{"$schema":"https://json.schemastore.org/web-types","name":"@aceshooting/lyra-ui","version":"18.4.0","description-markup":"markdown","contributions":{"html":{"elements":[{"name":"lr-accordion","description":"`<lr-accordion>` — coordinates accessible, vertically stacked expandable sections.\n\n`mode=\"multiple\"` allows any number of items to expand. `single` permits at most one and keeps\nthe active item open when it is activated again. `single-collapsible` also permits at most one,\nbut allows all items to be collapsed.\n\nOnly direct `<lr-accordion-item>` children are coordinated. Direct `<lr-details>` panels were\naccepted before 9.0.0 and no longer are: migrate `summary` to `label`, `open` to `expanded`, and\n`show()`/`hide()` to `expand()`/`collapse()`. A `<lr-details>` slotted into an accordion today is\nordinary content that owns its own disclosure lifecycle -- the group does not apply its\npresentation, single-panel invariant, roving keyboard model, or lifecycle to it.\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) | Direct `<lr-accordion-item>` elements. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The accordion wrapper. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-accordion-filled-bg` (default: `var(--lr-color-surface-raised)`) — Filled group background.\n- `--lr-accordion-filled-border-color` (default: `transparent`) — Filled border color.\n- `--lr-accordion-filled-outlined-bg` (default: `var(--lr-color-surface-raised)`) — Filled-outlined group background.\n- `--lr-accordion-filled-outlined-border-color` (default: `var(--lr-color-border)`) — Filled-outlined border color.\n- `--lr-accordion-outlined-bg` (default: `var(--lr-color-surface)`) — Outlined group background.\n- `--lr-accordion-outlined-border-color` (default: `var(--lr-color-border)`) — Outlined border color.","attributes":[{"name":"appearance","description":"Visual treatment applied to the group and its direct items.\n\nType: `LyraAccordionAppearance`  \nDefault: `'outlined'`","value":{"type":["'filled'","'outlined'","'filled-outlined'","'plain'"]}},{"name":"heading-level","description":"Heading level applied to direct items. Values other than 1–6 and `none` use h3.\n\nType: `LyraAccordionHeadingLevel`  \nDefault: `'3'`","value":{"type":["LyraAccordionHeadingLevel"]}},{"name":"icon-placement","description":"Icon position applied to direct accordion items.\n\nType: `LyraAccordionIconPlacement`  \nDefault: `'end'`","value":{"type":["'start'","'end'"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"mode","description":"Controls whether one or multiple items can be expanded.\n\nType: `LyraAccordionMode`  \nDefault: `'multiple'`","value":{"type":["'single'","'single-collapsible'","'multiple'"]}}],"slots":[{"name":"","description":"Direct `<lr-accordion-item>` elements."}],"js":{"properties":[{"name":"appearance","description":"Visual treatment applied to the group and its direct items.\n\nAttribute: `appearance`  \nReflected to its attribute.","type":"LyraAccordionAppearance","default":"'outlined'"},{"name":"headingLevel","description":"Heading level applied to direct items. Values other than 1–6 and `none` use h3.\n\nAttribute: `heading-level`  \nReflected to its attribute.","type":"LyraAccordionHeadingLevel","default":"'3'"},{"name":"iconPlacement","description":"Icon position applied to direct accordion items.\n\nAttribute: `icon-placement`  \nReflected to its attribute.","type":"LyraAccordionIconPlacement","default":"'end'"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"mode","description":"Controls whether one or multiple items can be expanded.\n\nAttribute: `mode`  \nReflected to its attribute.","type":"LyraAccordionMode","default":"'multiple'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-after-collapse","description":"Emitted after a direct item finishes collapsing. `detail: { item }`. Nested groups emit the same name, with a `detail.item` of their own; handle it as this group's event only when `event.target === event.currentTarget` (see `lr-toggle-request`).","type":"CustomEvent<LyraEventDetailSnapshot<LyraAccordionEventDetail>>"},{"name":"lr-after-expand","description":"Emitted after a direct item finishes expanding. `detail: { item }`. Nested groups emit the same name, with a `detail.item` of their own; handle it as this group's event only when `event.target === event.currentTarget` (see `lr-toggle-request`).","type":"CustomEvent<LyraEventDetailSnapshot<LyraAccordionEventDetail>>"},{"name":"lr-collapse","description":"Emitted before a direct item collapses. `detail: { item }`. Cancelable. Nested groups emit the same name, with a `detail.item` of their own; handle it as this group's event only when `event.target === event.currentTarget` (see `lr-toggle-request`).","type":"CustomEvent<LyraEventDetailSnapshot<LyraAccordionEventDetail>>"},{"name":"lr-expand","description":"Emitted before a direct item expands. `detail: { item }`. Cancelable. Nested groups emit the same name, with a `detail.item` of their own; handle it as this group's event only when `event.target === event.currentTarget` (see `lr-toggle-request`).","type":"CustomEvent<LyraEventDetailSnapshot<LyraAccordionEventDetail>>"},{"name":"lr-toggle-request","description":"Emitted alongside `lr-expand`/`lr-collapse` for the same proposed transition, with the direction in the detail instead of the event name -- the same `{ collapsed }` shape `<lr-code-block>` and `<lr-chat-message>` use for their own `lr-toggle-request`, plus `item` to identify which child is proposed to change. `detail: { collapsed, item }`. Cancelable; a listener calling `preventDefault()` on either `lr-toggle-request` or the matching `lr-expand`/`lr-collapse` vetoes the transition, and both always fire so a listener on one name never misses a transition the other name already vetoed. **A nested group's events are not scoped to it, so filter by target.** Every accordion event bubbles and is composed, so an inner `<lr-accordion>` slotted inside an outer item sends its own `lr-expand`, `lr-collapse`, `lr-toggle-request`, `lr-after-expand` and `lr-after-collapse` straight through the outer group. A listener bound directly on the outer `<lr-accordion>` therefore also receives the inner group's — and their `detail.item` is an item of the inner group, so an outer handler that looks that item up among its own children finds nothing, or acts on a panel it does not own. Coordination itself is already scoped: an outer group never applies its single-panel invariant, roving keyboard model, or lifecycle to an inner group's items. It is only the listener that needs the guard, the same one `<lr-details>` and `<lr-dialog>` document for their own events: ```html <lr-accordion id=\"outer\"> <lr-accordion-item label=\"Outer\"> <lr-accordion> <lr-accordion-item label=\"Inner\">Inner content.</lr-accordion-item> </lr-accordion> </lr-accordion-item> </lr-accordion> <script type=\"module\"> const outer = document.querySelector('#outer'); outer.addEventListener('lr-expand', (event) => { if (event.target !== event.currentTarget) return; // a nested group expanded, not this one // ... }); </script> ```","type":"CustomEvent<\n    LyraEventDetailSnapshot<{ readonly collapsed: boolean; readonly item: LyraAccordionItem }>\n  >"}]}},{"name":"lr-accordion-item","description":"`<lr-accordion-item>` — an accessible expandable section for `<lr-accordion>`.\n\nThe item deliberately owns only Web Awesome's accordion-item vocabulary. Use `expanded`,\n`label`, and `expand()`/`collapse()`/`toggle()` here; the independent `open`, `summary`, and\n`show()`/`hide()` disclosure vocabulary belongs to `<lr-details>`.\n\nA present host `aria-label`, including an explicitly empty value, names the trigger button.\nWhen absent, the trigger retains its native name-from-content behavior.\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 part `base`: Deprecated since `8.2.3`. Use part `::part(accordion-item)`. Removal is not permitted before `10.0.0`. The accordion-item part names the outer wrapper explicitly; base remains on that same node during the compatibility window. That version is a policy floor, not a plan: Web Awesome still publishes its own deprecated `base` part on `wa-accordion-item`, and a mirrored tag owes its whole upstream surface, so this alias is removed only when upstream's is.\n\n---\n\n**Slots**\n\n| Name | Description |\n| --- | --- |\n| (default) | Panel content. |\n| `icon` | Optional decorative expand/collapse icon. Its flattened subtree remains visible but is inert and hidden from assistive technology; the trigger button is the sole action. |\n| `label` | Visible header label; takes priority over the `label` property. Its flattened subtree is inert and hidden from assistive technology, while its accessibility-visible text names the sole trigger button. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `accordion-item` | The outer wrapper. It is the same node as `base`. |\n| `base` | Deprecated compatibility name for the outer wrapper; use `accordion-item`. |\n| `button` | The trigger button. |\n| `content` | Content container inside the panel. |\n| `heading` | Heading around the trigger; omitted for `heading-level=\"none\"`. |\n| `icon` | Expand/collapse icon container. |\n| `label` | Label container. |\n| `panel` | Expandable panel. |\n\n---\n\n**CSS Custom Properties**\n\n- `--easing` — Upstream-compatible alias for `--lr-accordion-item-easing`.\n- `--hide-duration` — Upstream-compatible alias for `--lr-accordion-item-hide-duration`.\n- `--lr-accordion-item-button-active-bg` (default: `color-mix(...)`) — Trigger pressed background.\n- `--lr-accordion-item-button-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Trigger hover background.\n- `--lr-accordion-item-easing` (default: `var(--lr-easing-standard)`) — Expand/collapse easing.\n- `--lr-accordion-item-filled-bg` (default: `var(--lr-color-surface-raised)`) — Filled item background.\n- `--lr-accordion-item-filled-outlined-bg` (default: `var(--lr-color-surface-raised)`) — Filled-outlined item background.\n- `--lr-accordion-item-hide-duration` (default: `var(--lr-duration-base)`) — Collapse transition duration.\n- `--lr-accordion-item-outlined-bg` (default: `var(--lr-color-surface)`) — Outlined item background.\n- `--lr-accordion-item-show-duration` (default: `var(--lr-duration-base)`) — Expand transition duration.\n- `--lr-accordion-item-spacing` (default: `var(--lr-form-control-padding-inline)`) — Header/content spacing.\n- `--show-duration` — Upstream-compatible alias for `--lr-accordion-item-show-duration`.\n- `--spacing` — Upstream-compatible alias for `--lr-accordion-item-spacing`.","attributes":[{"name":"appearance","description":"Visual treatment inherited non-destructively from the owning accordion.\n\nType: `LyraAccordionAppearance`  \nDefault: `'outlined'`","value":{"type":["'filled'","'outlined'","'filled-outlined'","'plain'"]}},{"name":"disabled","description":"Disables the item so it cannot be toggled.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"expanded","description":"Whether the panel is expanded. Assigning it uses the owning accordion's cancelable lifecycle.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"heading-level","description":"Heading level from 1–6, or `none`; every other value uses h3.\n\nType: `LyraAccordionHeadingLevel`  \nDefault: `'3'`","value":{"type":["LyraAccordionHeadingLevel"]}},{"name":"icon-placement","description":"Whether the icon appears before or after the label.\n\nType: `LyraAccordionIconPlacement`  \nDefault: `'end'`","value":{"type":["'start'","'end'"]}},{"name":"label","description":"Text shown in the trigger. Rich content belongs in the `label` slot.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"slots":[{"name":"","description":"Panel content."},{"name":"icon","description":"Optional decorative expand/collapse icon. Its flattened subtree remains visible but is inert and hidden from assistive technology; the trigger button is the sole action."},{"name":"label","description":"Visible header label; takes priority over the `label` property. Its flattened subtree is inert and hidden from assistive technology, while its accessibility-visible text names the sole trigger button."}],"js":{"properties":[{"name":"appearance","description":"Visual treatment inherited non-destructively from the owning accordion.\n\nAttribute: `appearance`  \nReflected to its attribute.","type":"LyraAccordionAppearance","default":"'outlined'"},{"name":"disabled","description":"Disables the item so it cannot be toggled.\n\nAttribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"expanded","description":"Whether the panel is expanded. Assigning it uses the owning accordion's cancelable lifecycle.\n\nAttribute: `expanded`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"headingLevel","description":"Heading level from 1–6, or `none`; every other value uses h3.\n\nAttribute: `heading-level`  \nReflected to its attribute.","type":"LyraAccordionHeadingLevel","default":"'3'"},{"name":"iconPlacement","description":"Whether the icon appears before or after the label.\n\nAttribute: `icon-placement`  \nReflected to its attribute.","type":"LyraAccordionIconPlacement","default":"'end'"},{"name":"label","description":"Text shown in the trigger. Rich content belongs in the `label` slot.\n\nAttribute: `label`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}]}},{"name":"lr-activity-feed","description":"`<lr-activity-feed>` — an append-only streaming log of granular agent actions (\"Searching the\nweb…\", \"Read src/index.ts\"), collapsing to a localized \"Completed N steps\" summary once the run\nis over. Entries never change state once added (a step whose status mutates in place belongs to\n`<lr-task-list>` instead). Implements the shared follow (stick-to-bottom) contract: `follow`\nis a component-managed, host-assignable property, released on user scroll-up and re-engaged at\nthe bottom. `lr-follow-change` reports user-driven transitions only; direct host assignments are\ncontrolled input and never echo an event. At/above\n`virtualizeAt` entries, the body renders through an internal `<lr-virtual-list>`\ninstead of a plain keyed list — same list semantics either way, keyed by `id`. Empty/blank ids\nare omitted and duplicates normalize before counts, follow calculations, and rendering; the\nfirst occurrence wins.\n\nEach entry's `text` renders as plain text by default; a host needing richer per-entry content\n(rendered markdown, a trailing tool-call chip list, etc.) sets `renderText` to replace the\ndefault text inside the stable `entry-text` styling wrapper, identically whether or not the feed\nis currently virtualized. An entry's optional `data` is an opaque caller payload -- never read\nor rendered by this component -- carried through by reference (never deep-cloned) and handed\nback to `renderText`, so a host needing the original source record behind a rendered line does\nnot have to re-derive it by re-scanning its own source array on every render.\n\n`compact` tightens the header and entry-row padding for dense transcript rows. `frame=\"plain\"`\nremoves the outside card chrome when a containing message or panel already supplies it; the\nheader/body divider remains, so the disclosure keeps its internal structure -- the same two-knob\nconvention `<lr-thinking-panel>` and `<lr-confirm-bar>` already establish. The card's own paint\nis retunable without a `::part(base)` override through `--lr-activity-feed-background`,\n`--lr-activity-feed-border-color` and `--lr-activity-feed-radius`; each is an inline `var()`\nfallback at its point of use, so an unset feed renders exactly as before and any of the three can\nbe set on the feed or on an ancestor transcript.\n\nFocus is repaired, not merely dropped, when the currently focused control disappears from under\nit: collapsing (`expanded` becoming `false`) moves focus already inside the body to\n`[part=\"header\"]` before the body is hidden, and an `entries` update that removes the specific\nrow holding focus does the same once that update (and, while virtualized, the internal\n`<lr-virtual-list>`'s own follow-up render) has settled. Neither case fires when focus is\nelsewhere -- appending a live entry never steals focus from an unrelated, still-present control.\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**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The outer container. |\n| `body` | The scrollable region containing the entries (or the internal virtual-list). |\n| `entry` | One entry row; carries `data-variant`. |\n| `entry-icon` | The literal `icon` hint, or a variant dot when unset. |\n| `entry-text` | The entry's text styling wrapper. `renderText`, when set, supplies rich content inside this stable part instead of replacing the part itself. |\n| `entry-timestamp` | The formatted timestamp, only rendered while `showTimestamps` and a valid `timestamp` is set. |\n| `header` | The clickable header (`<button>`). |\n| `label` | The header's title text — `label`, or its localized default when `label` is omitted. |\n| `status-dot` | The decorative mode indicator dot; pulses while `mode=\"live\"`. |\n| `summary` | The header's one-line ticker (`live`) or completed-count summary (`post-hoc`). |\n| `toggle` | The chevron indicator inside the header. |\n| `variant-dot` | The variant dot rendered inside `entry-icon` when the entry sets no literal `icon`. Its own named part rather than an internal class, so it stays styleable in both the plain and virtualized rendering paths and reachable from a consumer's `::part()`. Also carries a variant-specific name, since `::part()` cannot be qualified by `[data-variant]`. |\n| `variant-dot-brand` | A `brand`-variant entry's dot (also carries `variant-dot`). |\n| `variant-dot-danger` | A `danger`-variant entry's dot (also carries `variant-dot`). |\n| `variant-dot-neutral` | An entry with no `variant`'s dot (also carries `variant-dot`). |\n| `variant-dot-success` | A `success`-variant entry's dot (also carries `variant-dot`). |\n| `variant-dot-warning` | A `warning`-variant entry's dot (also carries `variant-dot`). |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-activity-feed-background` (default: `var(--lr-color-surface)`) — Fill of the outer card (`[part=\"base\"]`) while `frame=\"card\"`. `frame=\"plain\"` still removes the fill entirely.\n- `--lr-activity-feed-border-color` (default: `var(--lr-color-border)`) — Colour of the outer card's border and of the header/body divider, which `frame=\"plain\"` keeps.\n- `--lr-activity-feed-compact-entry-padding` (default: `var(--lr-space-2xs) var(--lr-space-s)`) — `[part=\"entry\"]` padding while `compact`.\n- `--lr-activity-feed-compact-header-gap` (default: `var(--lr-space-2xs)`) — Gap between the header toggle, status dot, label, and summary while `compact`.\n- `--lr-activity-feed-compact-header-padding` (default: `var(--lr-space-2xs) var(--lr-space-s)`) — `[part=\"header\"]` padding while `compact`.\n- `--lr-activity-feed-live-status-color` (default: `var(--lr-color-brand)`) — Background color of `status-dot` while `mode=\"live\"`.\n- `--lr-activity-feed-max-height` (default: `16rem`) — Cap on how tall the expanded body grows before it scrolls internally (non-virtualized mode); also sizes the internal virtual-list.\n- `--lr-activity-feed-radius` (default: `var(--lr-radius)`) — Corner radius of the outer card. `frame=\"plain\"` still squares the corners.","attributes":[{"name":"compact","description":"Tighter header and entry-row padding for dense transcript contexts. Defaults to `false`,\npreserving the regular-density treatment. This changes density only; the outer border and\nsurface remain, so use `frame=\"plain\"` to remove card chrome.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"expanded","description":"Body visibility. Never self-mutated on `mode` changes — a host wanting the finished feed\ncollapsed sets `mode=\"post-hoc\"` and `expanded=false` together.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"follow","description":"Component-managed, host-assignable stick-to-bottom flag — released on user scroll-up,\nre-engaged at the bottom. Only drives scrolling in `'live'` mode.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"frame","description":"Visual chrome, in the library's shared container-frame vocabulary. `'card'` (the default)\nkeeps the bordered, filled outer container. `'plain'` removes that outer border, background,\nand corner radius so a feed nested inside existing message chrome does not double it. Plain\npreserves the header/body divider and whichever regular or compact padding applies.\n\nType: `LyraFrame`  \nDefault: `'card'`","value":{"type":["'card'","'plain'"]}},{"name":"label","description":"Optional header-text override. Omission localizes `activityFeedLabel`; any supplied string,\nincluding `'Activity'` or `''`, is rendered verbatim. The semantic list uses an authored host\n`aria-label` when present (including an explicit empty value), otherwise its localized\n`activityFeedLabel` fallback, while this remains the visible header text.\n\nType: `string | undefined`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"mode","description":"Type: `ActivityFeedMode`","value":{"type":["'live'","'post-hoc'"]}},{"name":"show-timestamps","description":"Trailing `<time datetime>` per entry, default `hour:minute` in `effectiveLocale`.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"virtualize-at","description":"At/above this entry count, the body renders through an internal `<lr-virtual-list>`.\n\nType: `number`  \nDefault: `199`","value":{"type":["number"]}}],"js":{"properties":[{"name":"compact","description":"Tighter header and entry-row padding for dense transcript contexts. Defaults to `false`,\npreserving the regular-density treatment. This changes density only; the outer border and\nsurface remain, so use `frame=\"plain\"` to remove card chrome.\n\nAttribute: `compact`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"entries","description":"Append-only: stable ids, new entries at the end. Entries never change state once added.\nEmpty/blank ids are omitted and duplicates normalize first-wins before summary,\nvirtualization, and rendering.","type":"readonly ActivityEntry[]","default":"[]"},{"name":"expanded","description":"Body visibility. Never self-mutated on `mode` changes — a host wanting the finished feed\ncollapsed sets `mode=\"post-hoc\"` and `expanded=false` together.\n\nAttribute: `expanded`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"follow","description":"Component-managed, host-assignable stick-to-bottom flag — released on user scroll-up,\nre-engaged at the bottom. Only drives scrolling in `'live'` mode.\n\nAttribute: `follow`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"formatTimestamp","description":"Overrides the default `hour:minute` rendering of every entry's `timestamp`.","type":"(date: Date) => string | undefined"},{"name":"frame","description":"Visual chrome, in the library's shared container-frame vocabulary. `'card'` (the default)\nkeeps the bordered, filled outer container. `'plain'` removes that outer border, background,\nand corner radius so a feed nested inside existing message chrome does not double it. Plain\npreserves the header/body divider and whichever regular or compact padding applies.\n\nAttribute: `frame`  \nReflected to its attribute.","type":"LyraFrame","default":"'card'"},{"name":"label","description":"Optional header-text override. Omission localizes `activityFeedLabel`; any supplied string,\nincluding `'Activity'` or `''`, is rendered verbatim. The semantic list uses an authored host\n`aria-label` when present (including an explicit empty value), otherwise its localized\n`activityFeedLabel` fallback, while this remains the visible header text.\n\nAttribute: `label`","type":"string | undefined"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"mode","description":"Attribute: `mode`  \nReflected to its attribute.","type":"ActivityFeedMode"},{"name":"renderText","description":"Overrides the default plain text inside every `[part=\"entry-text\"]` wrapper with an arbitrary\n`TemplateResult` (e.g. rendered markdown, or markdown plus a trailing list of\n`<lr-tool-call-chip>`s). The stable wrapper remains available for styling in both rendering\npaths, since both render every entry through the same internal template.","type":"(entry: ActivityEntry) => TemplateResult | undefined"},{"name":"showTimestamps","description":"Trailing `<time datetime>` per entry, default `hour:minute` in `effectiveLocale`.\n\nAttribute: `show-timestamps`","type":"boolean","default":"false"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"virtualizeAt","description":"At/above this entry count, the body renders through an internal `<lr-virtual-list>`.\n\nAttribute: `virtualize-at`","type":"number","default":"199"}],"events":[{"name":"lr-follow-change","description":"A user scroll released or re-engaged `follow`. `detail: { following }`. Direct property/attribute assignments never echo an event.","type":"CustomEvent<ActivityFeedFollowChangeDetail>"},{"name":"lr-toggle","description":"The header was activated, expanding or collapsing the body. `detail: { expanded }`.","type":"CustomEvent<ActivityFeedToggleDetail>"}]}},{"name":"lr-agent-eval-dashboard","description":"`<lr-agent-eval-dashboard>` — a controlled evaluation overview with metric cards, a trend chart,\nand run-status history. It never launches or scores evaluations. Duplicate metric or run ids\nnormalize before selection, charting, rendering, and activation; the first occurrence wins.\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: `6.2.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 root dashboard wrapper. |\n| `chart` | The trend chart. |\n| `empty` | The empty history message. |\n| `heading` | The visible heading. |\n| `metric` | One metric card. |\n| `metrics` | The metric-card grid. |\n| `run` | One run row. |\n| `run-label` | A run label. |\n| `run-meta` | Status and metric value. |\n| `run-status` | A run status badge. |\n| `run-status-message` | Optional caller-supplied detail for a run status. |\n| `runs` | The run history. |\n| `runs-heading` | The run history heading. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-agent-eval-dashboard-active-background` (default: `var(--lr-color-brand-quiet)`) — Active metric background.\n- `--lr-agent-eval-dashboard-active-border` (default: `var(--lr-color-brand)`) — Active metric border.","attributes":[{"name":"chart-height","description":"Type: `string`  \nDefault: `'220px'`","value":{"type":["string"]}},{"name":"currency","description":"ISO 4217 currency code used by metrics whose format is `currency`. Invalid codes use USD.\n\nType: `string`  \nDefault: `'USD'`","value":{"type":["string"]}},{"name":"label","description":"Accessible/visible heading override. Optional. Omitting it localizes the default\n`evaluationDashboardLabel` message; an explicit empty string renders no visible/accessible\nlabel.\n\nType: `string | undefined`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max-rendered-runs","description":"Maximum history entries rendered into both the run list and trend chart. Clamped to 1–500.\n\nType: `number`  \nDefault: `100`","value":{"type":["number"]}},{"name":"metric-id","description":"Controlled metric selection. `null` or an unmatched identity selects the first valid metric.\n\nType: `string | null`  \nDefault: `null`"},{"name":"show-chart","description":"Type: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}}],"js":{"properties":[{"name":"chartHeight","description":"Attribute: `chart-height`","type":"string","default":"'220px'"},{"name":"currency","description":"ISO 4217 currency code used by metrics whose format is `currency`. Invalid codes use USD.\n\nAttribute: `currency`","type":"string","default":"'USD'"},{"name":"label","description":"Accessible/visible heading override. Optional. Omitting it localizes the default\n`evaluationDashboardLabel` message; an explicit empty string renders no visible/accessible\nlabel.\n\nAttribute: `label`","type":"string | undefined"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"maxRenderedRuns","description":"Maximum history entries rendered into both the run list and trend chart. Clamped to 1–500.\n\nAttribute: `max-rendered-runs`","type":"number","default":"100"},{"name":"metricId","description":"Controlled metric selection. `null` or an unmatched identity selects the first valid metric.\n\nAttribute: `metric-id`","type":"string | null","default":"null"},{"name":"metrics","description":"Metric cards and selector choices. Empty ids are omitted; duplicates normalize first-wins.","type":"readonly AgentEvaluationMetric[]","default":"[]"},{"name":"runs","description":"Run history used by both the chart and list. Empty ids are omitted; duplicates normalize\nfirst-wins.","type":"readonly AgentEvaluationDashboardRun[]","default":"[]"},{"name":"showChart","description":"Attribute: `show-chart`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-metric-change","description":"A host-controlled metric selection changed. `detail: { metricId }`.","type":"CustomEvent<{ metricId: string }>"},{"name":"lr-run-activate","description":"A run row was activated. `detail: { runId, run }`.","type":"CustomEvent<LyraEventDetailSnapshot<AgentRunActivateDetail<AgentEvaluationDashboardRun>>>"}]}},{"name":"lr-agent-run","description":"`<lr-agent-run>` — the top-level shell for one `AgentRun`: lifecycle-status badge, elapsed\ntime, current step, model/cost summary, and built-in Cancel/Retry controls in a header, plus\nfour named composition slots (`tasks`/`tools`/`reasoning`/`output`) for the run's actual\ncontent. This is deliberately a SHELL, not a new step-rendering surface — every piece of\nper-step or per-invocation rendering routes through an existing primitive:\n\n- **Elapsed time**: composes `<lr-generation-metrics>` (`status`/`started-at`, its own built-in\n  Stop button hidden via `show-stop=\"false\"` since this component renders its own Cancel/Retry\n  pair instead) for the *live, ticking* readout while the run is genuinely in progress\n  (`running`/`collecting`/`waiting-input`/`waiting-approval`). `<lr-stream-status>` doesn't fit:\n  its `phase` vocabulary\n  (`idle`/`connecting`/`streaming`/`stalled`) models transport/connection health, not an agent\n  run's nine built-in lifecycle statuses (plus application-defined extensions), and it exposes no elapsed-time readout at all — exactly the\n  distinction `<lr-generation-metrics>`'s own class doc already draws between the two. Once the\n  run reaches a terminal state (`done`/`error`/`cancelled`) with both a `startedAt` and an\n  `endedAt`, this component instead renders a small locally-formatted static duration\n  (`endedAt - startedAt`): `<lr-generation-metrics>`'s `status=\"complete\"` semantics only\n  ever freeze at whatever it last computed *live*, so mounting it directly against a completed\n  run loaded from history (e.g. `startedAt` yesterday, `endedAt` five minutes later, loaded\n  today) would either show a stale zero or the wrong multi-hour span — it has no way to render a\n  fixed historical span on demand. That static fallback reuses the side-effect-free duration\n  value model shared by the run/tool surfaces while retaining this component's own localized\n  message interpolation.\n- **Model + cost summary**: composes `<lr-usage-badge>`, fed `run.costEstimate` (formatted via\n  `formatCost`, or a plain `Intl.NumberFormat` by default — this library never assumes a\n  currency, see `<lr-format-number>`'s own explicit `currency` prop) as its `cost-text`.\n  `run.model` (a plain string with no analogous `<lr-usage-badge>` property) renders alongside\n  as plain text.\n- **Current step**: a single-line summary of whichever `run.steps` entry currently has\n  `status.kind === 'running'` (the last such entry, if more than one) — a plain text line, not a\n  list, so it doesn't duplicate `<lr-task-list>`'s own per-item rendering.\n- **Tasks slot default content**: when the host doesn't slot anything into `tasks` and\n  `run.steps` is non-empty, this component's own `<slot>` fallback renders a `<lr-task-list>`\n  populated by mapping every `AgentStep` to a `TaskItem` (see `toTaskItem()`) — a plain data\n  adapter between the two existing shapes, not new rendering.\n- **Status badge**: composes `<lr-badge>`. **Empty state**: composes `<lr-empty>` when `run` is\n  `null`.\n\n`tools`/`reasoning`/`output` are plain named slots with no default content — entirely the\nhost's own composition (typically `<lr-tool-call-chip>`/`<lr-tool-result-view>` rows,\nreasoning/streaming text, and final output respectively). An `actions` slot adds extra header\ncontrols alongside the built-in Cancel/Retry pair. The `header` and `summary` slots replace the\nbuilt-in lifecycle header and model/usage/metrics summary respectively. `statusLabels` and\n`statusVariants` make application-defined lifecycle kinds first-class, while `metrics` renders\narbitrary labeled values such as prompt and completion token counts.\n\nThe built-in Cancel button renders while `showCancel` is true and the run's status is one of\n`TICKING_KINDS` (still genuinely in progress); Retry renders while `showRetry` is true and the\nstatus is `error` or `cancelled`. Clicking either fires `lr-cancel`/`lr-run-retry` with\n`CancelEventDetail`/`RetryEventDetail` from `src/ai/types.ts` — this component never cancels or\nretries anything itself, it only requests. `RetryEventDetail.attempt` is a 1-based counter\nlocal to this component, incremented on every `lr-run-retry` click and reset to `0` whenever\n`run.id` changes (a genuinely new run replacing the old one, as opposed to the same run's status\nmerely updating in place).\n\nLifecycle transitions into an attention-needing or terminal state (`waiting-input`,\n`waiting-approval`, `done`, `error`, `cancelled`) are announced through an internal\n`<lr-live-region>`, mirroring `<lr-stream-status>`'s own stall/recover announcements —\n`running`/`idle` transitions are frequent and not independently actionable, so they stay\nsilent, and whatever status a freshly-assigned `run` (a new `run.id`) happens to already carry\nis never itself treated as an eventful transition, only a later in-place change is.\n\nPublic collection and status-map properties take bounded, clone-owned readonly snapshots.\nCreate and reassign a new array or record after changes; mutating the assigned value does not\nupdate the view.\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**Slots**\n\n| Name | Description |\n| --- | --- |\n| `actions` | Extra header actions alongside the built-in Cancel/Retry buttons. |\n| `header` | Replaces the built-in lifecycle header and its built-in actions. |\n| `output` | The run's final output content. No default content. |\n| `reasoning` | Reasoning/thinking content. No default content. |\n| `summary` | Replaces the built-in model, usage, and metrics summary. |\n| `tasks` | Task/plan content. Falls back to a `<lr-task-list>` built from `run.steps` when nothing is slotted and `run.steps` is non-empty. |\n| `tools` | Tool-call content (e.g. `<lr-tool-call-chip>`/`<lr-tool-result-view>` rows). No default content. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `actions` | Wrapper around the `actions` slot and the built-in Cancel/Retry buttons. |\n| `base` | The root container. |\n| `body` | Wrapper around the four composition slots. |\n| `cancel-button` | The built-in Cancel button. Only rendered while cancelable (see the class doc). |\n| `current-step` | Wrapper around the current-step icon and label. Only rendered while a step has `status.kind === 'running'`. |\n| `current-step-icon` | The spinning current-step icon. |\n| `current-step-label` | The current step's `label` text. |\n| `elapsed` | The composed `<lr-generation-metrics>`, only rendered while the run is actively ticking (see the class doc). |\n| `elapsed-static` | The static formatted duration for a terminal run with both `startedAt` and `endedAt`. |\n| `empty` | The `<lr-empty>` shown when `run` is `null`. |\n| `header` | The header row wrapping status, elapsed time, current step, summary, and actions. |\n| `metric` | One arbitrary metric in the built-in summary. |\n| `metric-label` | The metric's label. |\n| `metric-value` | The metric's value. |\n| `model` | `run.model`, when set. |\n| `output` | The `output` slot. |\n| `reasoning` | The `reasoning` slot. |\n| `retry-button` | The built-in Retry button. Only rendered while retryable. |\n| `status` | Wrapper around the status badge and optional status message. |\n| `status-badge` | The resolved `<lr-badge>` lifecycle-status pill. |\n| `status-message` | `run.status.message`, when set. |\n| `summary` | Wrapper around the model text and the composed `<lr-usage-badge>`. Only rendered while `run.model` or a valid `run.costEstimate` is present. |\n| `tasks` | The `tasks` slot. |\n| `tools` | The `tools` slot. |\n| `usage` | The composed `<lr-usage-badge>`. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-agent-run-background` (default: `var(--lr-color-surface)`) — Fill of the outer card (`[part=\"base\"]`) while `frame=\"card\"`. `frame=\"plain\"` still removes the fill entirely.\n- `--lr-agent-run-border-color` (default: `var(--lr-color-border)`) — Colour of the outer card's border.\n- `--lr-agent-run-compact-gap` (default: `var(--lr-space-s)`) — Gap between `[part=\"base\"]`'s header and body while `compact`.\n- `--lr-agent-run-compact-padding` (default: `var(--lr-space-s)`) — `[part=\"base\"]` padding while `compact`.\n- `--lr-agent-run-metric-brand-color` (default: `var(--lr-color-brand)`) — Brand metric value.\n- `--lr-agent-run-metric-danger-color` (default: `var(--lr-color-danger)`) — Danger metric value.\n- `--lr-agent-run-metric-success-color` (default: `var(--lr-color-success)`) — Success metric value.\n- `--lr-agent-run-metric-warning-color` (default: `var(--lr-color-warning)`) — Warning metric value.\n- `--lr-agent-run-radius` (default: `var(--lr-radius)`) — Corner radius of the outer card. `frame=\"plain\"` still squares the corners.\n- `--lr-agent-run-spin` (default: `var(--lr-transition-ambient)`) — Current-step icon spin animation.","attributes":[{"name":"compact","description":"Tighter root padding and header/body gap for dense contexts (a run rendered as a row in a\nlist, a side panel) -- same convention as `lr-empty`'s `compact`. Defaults to `false`, i.e.\nthe full card padding. Purely a density knob: the border and background stay, so use\n`frame=\"plain\"` instead to drop the chrome entirely.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"frame","description":"Visual chrome, in the library's shared container-frame vocabulary. `'card'` (the default)\nkeeps the bordered, filled, padded box. `'plain'` removes the border, background, padding and\ncorner radius, so a run nested inside a host container that already draws a border doesn't\ndouble it. `plain` wins over `compact` when both are set (nothing left to tighten). The\nbuilt-in Cancel/Retry buttons draw their own border/background and stay visibly interactive\neither way.\n\nType: `LyraFrame`  \nDefault: `'card'`","value":{"type":["'card'","'plain'"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"show-cancel","description":"Whether the built-in Cancel button can render at all -- still gated by the run's own status\nbeing cancelable (`running`/`collecting`/`waiting-input`/`waiting-approval`). Set `false` for a read-only\nviewer.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"show-retry","description":"Whether the built-in Retry button can render at all -- still gated by the run's own status\nbeing retryable (`error`/`cancelled`).\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}}],"slots":[{"name":"actions","description":"Extra header actions alongside the built-in Cancel/Retry buttons."},{"name":"header","description":"Replaces the built-in lifecycle header and its built-in actions."},{"name":"output","description":"The run's final output content. No default content."},{"name":"reasoning","description":"Reasoning/thinking content. No default content."},{"name":"summary","description":"Replaces the built-in model, usage, and metrics summary."},{"name":"tasks","description":"Task/plan content. Falls back to a `<lr-task-list>` built from `run.steps` when nothing is slotted and `run.steps` is non-empty."},{"name":"tools","description":"Tool-call content (e.g. `<lr-tool-call-chip>`/`<lr-tool-result-view>` rows). No default content."}],"js":{"properties":[{"name":"compact","description":"Tighter root padding and header/body gap for dense contexts (a run rendered as a row in a\nlist, a side panel) -- same convention as `lr-empty`'s `compact`. Defaults to `false`, i.e.\nthe full card padding. Purely a density knob: the border and background stay, so use\n`frame=\"plain\"` instead to drop the chrome entirely.\n\nAttribute: `compact`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"formatCost","description":"Overrides the default plain `Intl.NumberFormat` rendering of `run.costEstimate` fed to the\ncomposed `<lr-usage-badge>`'s `cost-text` -- e.g. to add a currency symbol/code, which this\nlibrary never assumes on a host's behalf.","type":"(cost: number) => string | undefined"},{"name":"frame","description":"Visual chrome, in the library's shared container-frame vocabulary. `'card'` (the default)\nkeeps the bordered, filled, padded box. `'plain'` removes the border, background, padding and\ncorner radius, so a run nested inside a host container that already draws a border doesn't\ndouble it. `plain` wins over `compact` when both are set (nothing left to tighten). The\nbuilt-in Cancel/Retry buttons draw their own border/background and stay visibly interactive\neither way.\n\nAttribute: `frame`  \nReflected to its attribute.","type":"LyraFrame","default":"'card'"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"metrics","description":"Additional run metrics such as prompt/completion token counts. Empty/blank ids are omitted\nand duplicates normalize first-wins before summary visibility and rendering.","type":"readonly AgentRunMetric[]","default":"[]"},{"name":"run","description":"The run to display. Controlled and never mutated by this component -- pass a new object to\nupdate it. `null` renders the shared `<lr-empty>` `noData` state. A runtime summary record\nwithout `steps` renders an empty task slot, and a step without a status renders as pending.","type":"AgentRun | null","default":"null"},{"name":"showCancel","description":"Whether the built-in Cancel button can render at all -- still gated by the run's own status\nbeing cancelable (`running`/`collecting`/`waiting-input`/`waiting-approval`). Set `false` for a read-only\nviewer.\n\nAttribute: `show-cancel`","type":"boolean","default":"true"},{"name":"showRetry","description":"Whether the built-in Retry button can render at all -- still gated by the run's own status\nbeing retryable (`error`/`cancelled`).\n\nAttribute: `show-retry`","type":"boolean","default":"true"},{"name":"statusLabels","description":"Clone-owned labels for application-defined lifecycle kinds. Built-in kinds remain localized\nby Lyra. Reassign a new record after changes.","type":"Readonly<Record<string, string>>","default":"{}"},{"name":"statusVariants","description":"Clone-owned badge variants for application-defined lifecycle kinds. Unknown kinds default to\n`neutral`. Reassign a new record after changes.","type":"Readonly<Record<string, BadgeVariant>>","default":"{}"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-cancel","description":"The built-in Cancel button was activated. `detail: CancelEventDetail` (`{ reason }`, always `undefined` from the built-in button itself).","type":"CustomEvent<CancelEventDetail>"},{"name":"lr-run-retry","description":"The built-in Retry button was activated. `detail: RetryEventDetail` (`{ attempt }`, a 1-based counter reset per `run.id`).","type":"CustomEvent<RetryEventDetail>"}]}},{"name":"lr-agent-trace","description":"`<lr-agent-trace>` — a provider-neutral agent/LLM trace view: a span-kind filter row, a\nhandoff quick-jump list, and the full trace hierarchy, all driven by one shared `LyraSpan[]`\narray (the same shape `<lr-trace-tree>` and `<lr-span-waterfall>` already consume).\n\nThe actual trace rendering -- hierarchy, expand/collapse, roving-tabindex keyboard navigation,\nduration bars, the empty state -- is entirely `<lr-trace-tree>`'s own: this component only ever\npasses it a (possibly filtered) `spans` array plus a handful of pass-through properties, never\nbuilding its own row markup. `<lr-trace-tree>` was chosen over `<lr-span-waterfall>` because a\ntrace is fundamentally the hierarchy relationship between spans (which agent called which tool,\nwhich handed off to which sub-agent) -- exactly what `parentId`-derived `aria-level` nesting\nconveys and a flat, `startMs`-ordered timeline does not.\n\nThis component's own contribution is the multi-domain filter layer on top of that: a filter\nrow composing `<lr-graph-legend>` -- the same abstract type/visibility-toggle legend pattern\nthat component already establishes for `<lr-graph>`'s node types, reused here (it neither\nreads nor writes an actual graph) for `LyraSpan.kind` visibility instead -- and a handoff\nquick-jump list composing `<lr-handoff-divider>` for each visible `'agent'`-kind span (an\nagent invocation is, in trace terms, a handoff of control to that agent). Hidden kinds are\nsimply excluded from the array handed to `<lr-trace-tree>`; a span whose parent got filtered\nout is promoted to a root by `<lr-trace-tree>`'s own existing orphan handling, never dropped.\n\nSelection is controlled end-to-end for deep-linking: `activeSpanId` flows down into\n`<lr-trace-tree>` verbatim, and both activation paths -- a row click inside the tree, or a\nhandoff quick-jump entry -- update it and fire the identical `lr-span-select` `{ spanId }`\nshape, so\na host can encode the current span id in a URL and feed it straight back in.\n\nPublic collection properties take bounded readonly snapshots. `spans` keeps its admitted item\nidentities only long enough for the shared descriptor-safe projection to copy its fields; later\nrendering never re-reads an admitted source row. Create a new collection and reassign it after\nchanges; mutating the assigned array does not update the view.\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| `base` | The root wrapper. |\n| `filter` | The composed `<lr-graph-legend>` filter row, only rendered while `spans` has at least one span. |\n| `handoff` | One handoff quick-jump entry (a `<button>` wrapping an `<lr-handoff-divider>`); carries `data-active`. |\n| `handoffs` | The handoff quick-jump list wrapper, only rendered while at least one visible span has `kind: 'agent'`. |\n| `tree` | The composed `<lr-trace-tree>`. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-agent-trace-handoff-active-bg` (default: `var(--lr-color-brand-quiet)`) — Background of the active (`activeSpanId`) handoff quick-jump entry. Shadow Parts forbids an attribute selector after `::part()`, so the active entry could otherwise only be restyled by hijacking the library-wide `--lr-color-brand-quiet` token.","attributes":[{"name":"active-span-id","description":"Controlled selection, forwarded verbatim into the composed `<lr-trace-tree>`. Updated\nlocally (and re-emitted as `lr-span-select`) whenever a span is activated from either the\ntree or the handoff quick-jump list, so a host can also treat it as a two-way binding.\n\nType: `string | null`  \nDefault: `null`"},{"name":"label","description":"Optional accessible-name override forwarded to the composed `<lr-trace-tree>`. Omission\nleaves the composed tree's own `label` unset, so it localizes its own default; any supplied\nstring, including `''`, is forwarded verbatim. See `<lr-trace-tree>`'s own `label` property.\n\nType: `string | undefined`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"show-bars","description":"Shows the inline duration bar on the composed `<lr-trace-tree>`, matching the\npositive-polarity `showTokens`/`showCost` convention on this same element. Defaults to\n`true`; set `show-bars=\"false\"` to suppress the bar for dense/narrow embeddings.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"show-cost","description":"Forwarded verbatim to the composed `<lr-trace-tree>`.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"show-tokens","description":"Forwarded verbatim to the composed `<lr-trace-tree>`.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"js":{"properties":[{"name":"activeSpanId","description":"Controlled selection, forwarded verbatim into the composed `<lr-trace-tree>`. Updated\nlocally (and re-emitted as `lr-span-select`) whenever a span is activated from either the\ntree or the handoff quick-jump list, so a host can also treat it as a two-way binding.\n\nAttribute: `active-span-id`","type":"string | null","default":"null"},{"name":"hiddenKinds","description":"Span kinds currently hidden from the tree. Empty (the default) shows every kind. Controlled\n-- a host may pre-set this (e.g. to hide `retriever`/`embedding` spans by default) or read it\nback after `lr-span-visibility-change`.","type":"readonly LyraSpan['kind'][]","default":"[]"},{"name":"label","description":"Optional accessible-name override forwarded to the composed `<lr-trace-tree>`. Omission\nleaves the composed tree's own `label` unset, so it localizes its own default; any supplied\nstring, including `''`, is forwarded verbatim. See `<lr-trace-tree>`'s own `label` property.\n\nAttribute: `label`","type":"string | undefined"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"showBars","description":"Shows the inline duration bar on the composed `<lr-trace-tree>`, matching the\npositive-polarity `showTokens`/`showCost` convention on this same element. Defaults to\n`true`; set `show-bars=\"false\"` to suppress the bar for dense/narrow embeddings.\n\nAttribute: `show-bars`","type":"boolean","default":"true"},{"name":"showCost","description":"Forwarded verbatim to the composed `<lr-trace-tree>`.\n\nAttribute: `show-cost`","type":"boolean","default":"false"},{"name":"showTokens","description":"Forwarded verbatim to the composed `<lr-trace-tree>`.\n\nAttribute: `show-tokens`","type":"boolean","default":"false"},{"name":"spans","description":"The full, unfiltered span array -- identical contract to `<lr-trace-tree>.spans`. Controlled\nand never mutated by this component; `activeSpanId` and its ancestor path reserve positions\ninside the shared 500-row projection before kind filtering.","type":"readonly LyraSpan[]","default":"[]"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-span-select","description":"`detail: { spanId }` — a span was activated, from the tree or the handoff list.","type":"CustomEvent<{ spanId: string }>"},{"name":"lr-span-toggle","description":"`detail: { spanId, expanded }` — a tree row was expanded or collapsed.","type":"CustomEvent<{ spanId: string; expanded: boolean }>"},{"name":"lr-span-visibility-change","description":"`detail: { hiddenKinds }` — the span-kind filter changed.","type":"CustomEvent<LyraEventDetailSnapshot<{ hiddenKinds: LyraSpan['kind'][] }>>"}]}},{"name":"lr-agent-workspace","description":"`<lr-agent-workspace>` — a responsive, controlled shell for an AI conversation and its\nsupporting agent state. It renders the transcript and composer in the main pane, and composes\nexisting run, tool, retrieval, grounding, and context primitives in an optional details pane.\n\nThe component performs no network requests, model calls, retrieval, or persistence. Assign new\ndata to the public properties as the host application receives updates. The `messages` fallback\nrenders ordered `message.parts` through `<lr-message-parts>` when supplied, otherwise sanitized\nMarkdown from the legacy `message.text`; applications can replace the entire region with the\n`messages` slot. The `details` slot similarly replaces the built-in details pane while keeping\nthe responsive shell. Empty and duplicate message ids normalize first-wins before the bounded\nwindow is chosen; at most the latest 500 valid messages are materialized. Applications needing\na larger retained transcript can supply a virtualized `messages` slot.\nComposer value, follow state, and retrieval selection are request-only:\nchild events are forwarded, but the workspace never writes those public\nproperties. The host applies accepted state back to the component.\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**The transcript is the only region that scrolls.** `[part='base']` is a three-row grid —\nheader, conversation, composer — where only the middle row can shrink, so the composed\n`<lr-chat-viewport>` owns the scrolling and the chrome rows stay put. Header and composer\ncontent are therefore sized by their own content: give the workspace less block-size than they\nneed and the conversation row collapses to zero first, after which the chrome is clipped with no\nscrollbar. That only happens with unusually large slotted chrome — a very tall `header-actions`\ntoolbar, or a `composer` replacement much taller than the built-in one — and the fix belongs to\nwhoever supplied it, through the public parts:\n`lr-agent-workspace::part(header) { max-block-size: 4rem; overflow: auto; }` (the same applies\nto `::part(composer)`). No component-owned custom property duplicates that, because a\n`::part()` rule from the consumer's tree already wins over the shadow stylesheet regardless of\nspecificity and can set the cap and the overflow together.\n\n---\n\n**Component metadata**\n\n- Status: `stable`\n- Since: `4.2.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| `composer` | Replaces the built-in plain-frame `<lr-chat-composer>`; a supplied composer keeps its own frame. |\n| `details` | Replaces the built-in run/tool/retrieval/grounding/context details pane. |\n| `header-actions` | Header actions such as model selection, settings, or export controls. |\n| `messages` | Replaces the data-driven transcript message list. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The root workspace wrapper. |\n| `body` | The main conversation/details layout. |\n| `composer` | The composer region. |\n| `composer-input` | The built-in `<lr-chat-composer>`. |\n| `conversation` | The main transcript pane. |\n| `details` | The responsive details pane. |\n| `details-content` | The built-in details content wrapper. |\n| `header` | The workspace heading and header-actions slot. |\n| `header-actions` | The header-actions slot wrapper. |\n| `heading` | The visible workspace heading. |\n| `message` | Each data-driven transcript message. |\n| `messages` | Each data-driven transcript message (also exposed as `message`). |\n| `messages-empty` | The empty transcript state. |\n| `section` | A built-in run, tools, retrieval, grounding, or context section. |\n| `section-heading` | A built-in details section heading. |\n| `viewport` | The composed `<lr-chat-viewport>`. |","attributes":[{"name":"aria-label","description":"Host-level accessible-name override for the internal `role=\"region\"` root.\n\nType: `string | null`  \nDefault: `null`"},{"name":"composer-max-rows","description":"Type: `number`  \nDefault: `8`","value":{"type":["number"]}},{"name":"composer-min-rows","description":"Minimum and maximum rows for the built-in composer.\n\nType: `number`  \nDefault: `1`","value":{"type":["number"]}},{"name":"composer-placeholder","description":"Placeholder for the built-in composer.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"composer-status","description":"Type: `ChatComposerStatus`","value":{"type":["'idle'","'sending'","'streaming'"]}},{"name":"composer-value","description":"Controlled value of the built-in composer.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"context-total","description":"Overall context-window token total.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"follow","description":"Whether the transcript follows the latest message.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"label","description":"Accessible name and visible heading for the workspace.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"retrieval-error-text","description":"Caller-supplied retrieval error text.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"retrieval-has-more","description":"Whether more retrieval results can be requested.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"retrieval-loading","description":"Loading state for the built-in retrieval result list.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"show-composer","description":"Whether the built-in plain-frame composer is available when no `composer` slot is supplied.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"show-details","description":"Whether the built-in details pane is available when data is present.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"unread-start-index","description":"First unread message index, forwarded to the transcript viewport.\n\nType: `number | null`  \nDefault: `null`"}],"slots":[{"name":"composer","description":"Replaces the built-in plain-frame `<lr-chat-composer>`; a supplied composer keeps its own frame."},{"name":"details","description":"Replaces the built-in run/tool/retrieval/grounding/context details pane."},{"name":"header-actions","description":"Header actions such as model selection, settings, or export controls."},{"name":"messages","description":"Replaces the data-driven transcript message list."}],"js":{"properties":[{"name":"accessibleLabel","description":"Host-level accessible-name override for the internal `role=\"region\"` root.\n\nAttribute: `aria-label`","type":"string | null","default":"null"},{"name":"citations","description":"Citations displayed with the grounding summary, first-valid/first-wins by nonblank id.","type":"readonly Citation[]","default":"[]"},{"name":"composerMaxRows","description":"Attribute: `composer-max-rows`","type":"number","default":"8"},{"name":"composerMinRows","description":"Minimum and maximum rows for the built-in composer.\n\nAttribute: `composer-min-rows`","type":"number","default":"1"},{"name":"composerPlaceholder","description":"Placeholder for the built-in composer.\n\nAttribute: `composer-placeholder`","type":"string","default":"''"},{"name":"composerStatus","description":"Attribute: `composer-status`","type":"ChatComposerStatus"},{"name":"composerValue","description":"Controlled value of the built-in composer.\n\nAttribute: `composer-value`","type":"string","default":"''"},{"name":"contextSegments","description":"Final model-call context segments, first-valid/first-wins by nonblank id.","type":"readonly ContextInspectorSegment[]","default":"[]"},{"name":"contextTotal","description":"Overall context-window token total.\n\nAttribute: `context-total`","type":"number","default":"0"},{"name":"follow","description":"Whether the transcript follows the latest message.\n\nAttribute: `follow`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"groundingAssessment","description":"Grounding assessment for the current assistant answer.","type":"Readonly<GroundingAssessment> | null","default":"null"},{"name":"label","description":"Accessible name and visible heading for the workspace.\n\nAttribute: `label`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"messages","description":"Conversation messages. The host owns ordering, updates, and persistence. Ids are unique,\nnonempty occurrence identities; malformed rows and later duplicates are ignored before the\nbounded render window is chosen, with the first occurrence winning.","type":"readonly ChatMessage[]","default":"[]"},{"name":"metrics","description":"Additional metrics forwarded to `<lr-agent-run>`, such as token counts or latency.","type":"readonly AgentRunMetric[]","default":"[]"},{"name":"retrievalChunks","description":"Retrieval chunks for the current answer or query, first-valid/first-wins by nonblank id.","type":"readonly RetrievalChunk[]","default":"[]"},{"name":"retrievalErrorText","description":"Caller-supplied retrieval error text.\n\nAttribute: `retrieval-error-text`","type":"string","default":"''"},{"name":"retrievalHasMore","description":"Whether more retrieval results can be requested.\n\nAttribute: `retrieval-has-more`","type":"boolean","default":"false"},{"name":"retrievalLoading","description":"Loading state for the built-in retrieval result list.\n\nAttribute: `retrieval-loading`","type":"boolean","default":"false"},{"name":"run","description":"Current agent run, rendered in the details pane when set.","type":"Readonly<AgentRun> | null","default":"null"},{"name":"selectedRetrievalChunkIds","description":"Controlled retrieval selection, forwarded to `<lr-retrieval-results>`.","type":"readonly string[]","default":"[]"},{"name":"showComposer","description":"Whether the built-in plain-frame composer is available when no `composer` slot is supplied.\n\nAttribute: `show-composer`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"showDetails","description":"Whether the built-in details pane is available when data is present.\n\nAttribute: `show-details`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"tools","description":"Tool calls for the current run. Malformed/blank/later duplicate composite identities are\nignored before section gating and forwarding to `<lr-tool-timeline>`.","type":"readonly ToolTimelineEntry[]","default":"[]"},{"name":"unreadStartIndex","description":"First unread message index, forwarded to the transcript viewport.\n\nAttribute: `unread-start-index`","type":"number | null","default":"null"}],"events":[{"name":"lr-cancel","description":"Forwarded from the built-in agent run.","type":"CustomEvent<CancelEventDetail>"},{"name":"lr-citation-select","description":"Forwarded from the built-in grounding summary. `detail: { citation }`.","type":"CustomEvent<LyraEventDetailSnapshot<CitationSelectEventDetail>>"},{"name":"lr-follow-change","description":"Forwarded from the transcript viewport. `detail: { following }`.","type":"CustomEvent<{ following: boolean }>"},{"name":"lr-input","description":"Forwarded from the built-in composer. `detail: { value }`.","type":"CustomEvent<{ value: string }>"},{"name":"lr-message-retry","description":"A data-driven message's retry action was activated. `detail: { messageId }`.","type":"CustomEvent<{ messageId: string }>"},{"name":"lr-retrieval-select","description":"Forwarded from the built-in retrieval results. `detail: { chunkIds, chunks }`.","type":"CustomEvent<LyraEventDetailSnapshot<RetrievalResultsSelectDetail>>"},{"name":"lr-run-retry","description":"Forwarded from the built-in agent run.","type":"CustomEvent<RetryEventDetail>"},{"name":"lr-stop","description":"Forwarded from the built-in composer.","type":"CustomEvent<null>"},{"name":"lr-submit","description":"Forwarded from the built-in composer. `detail: { value }`.","type":"CustomEvent<{ value: string }>"},{"name":"lr-tool-approval-decide","description":"Forwarded from the built-in tool timeline.","type":"CustomEvent<ToolTimelineApprovalDetail>"}]}},{"name":"lr-alert","description":"`<lr-alert>` — a closed-by-default inline alert that can also move into the shared toast stack.\nIt mirrors the public `<sl-alert>` contract under the `lr-` prefix. `lr-show`/`lr-hide` are\ncancelable veto points, matching every other Lyra component that emits them; the settled\n`lr-after-*` notifications are not. Initial `open` markup establishes state without emitting a\ntransition event, so it is never vetoable. The light-DOM host owns `role=\"alert\"`; its slotted\nmessage is therefore the one assertive semantic surface for both static and later-open alerts,\nwithout a duplicate shadow or shared live region. The optional icon wrapper remains visible as\ndecorative chrome while its flattened subtree is inert and hidden from the accessibility tree.\nAccepted transitions resume after reconnect and emit at most one matching terminal event;\nmethod promises still settle if a disconnect proves lasting.\n\n---\n\n**Component metadata**\n\n- Status: `stable`\n- Since: `8.0.0`\n- Rationale: This tag entered Lyra as a stable public API with documented behavior, accessibility, and cross-browser support.\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 alert's main content. |\n| `icon` | Optional decorative leading icon. Its flattened subtree remains visible but is inert and hidden from assistive technology. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The component's base wrapper. |\n| `close-button` | The close button. |\n| `close-button__base` | Compatibility alias for the close button's base part; it is on the same native button as `close-button`. |\n| `icon` | The optional inert, aria-hidden icon wrapper. |\n| `message` | The alert's main-content wrapper. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-alert-close-active-bg` (default: `color-mix(in oklab,transparent,var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — The close button's pressed background, independently scoped from `--lr-alert-close-hover-bg`.\n- `--lr-alert-close-hover-bg` (default: `color-mix(in oklab,transparent,var(--lr-color-mix-partner) var(--lr-color-mix-hover))`) — The close button's hover background, scoped so a consumer can retint just this control without touching the shared `--lr-color-mix-partner`/`--lr-color-mix-hover` tokens every other interactive surface in the library also reads.","attributes":[{"name":"closable","description":"Enables the localized close action.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"countdown","description":"Type: `AlertCountdown`","value":{"type":["'rtl'","'ltr'"]}},{"name":"duration","description":"Milliseconds before automatic dismissal; `Infinity` disables automatic dismissal.\n\nType: `number`  \nDefault: `Infinity`","value":{"type":["number"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"open","description":"Whether the alert is visible. The attribute reflects method and property changes.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"role","description":"Light-DOM semantic role for the projected message. Reflected so server renderers can\nserialize the default before browser connection; an authored role continues to win.\n\nType: `string | null`  \nDefault: `'alert'`"},{"name":"size","description":"Density tier on the library's one size ladder, in either spelling — `2xs`/`xs`/`s`/`m`/`l`/\n`xl`, or Web Awesome's and Shoelace's `small`/`medium`/`large`. A Lyra addition on top of the\npinned Shoelace surface, and opt-in for that reason: with no size the panel keeps the exact\npadding and inherited text size it shipped with, so migrated markup renders unchanged. A tier\nscales the panel's padding and text together and takes `<lr-callout>`'s tier values for both,\nkeeping the same constant gap, so a tiered alert and a tiered callout of the same size line\nup in one column. Their UNSET states are NOT interchangeable, deliberately: with no tier this\npanel keeps a fixed gutter and inherits the ambient text size — its exact pre-ladder\nrendering — while an untiered `<lr-callout>` reads the ambient form-control slots and falls\nback to `--lr-space-m` / `--lr-font-size-m`. Pinning a default tier here would resize every\nalert that shipped before the ladder reached this component. Unsupported values normalize to\nthe omitted state and remove the attribute.\n\nType: `LyraSize | undefined`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}},{"name":"variant","description":"Type: `AlertVariant`  \nDefault: `'primary'`","value":{"type":["'neutral'","'success'","'warning'","'danger'","'primary'"]}}],"slots":[{"name":"","description":"The alert's main content."},{"name":"icon","description":"Optional decorative leading icon. Its flattened subtree remains visible but is inert and hidden from assistive technology."}],"js":{"properties":[{"name":"closable","description":"Enables the localized close action.\n\nAttribute: `closable`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"countdown","description":"Attribute: `countdown`  \nReflected to its attribute.","type":"AlertCountdown"},{"name":"duration","description":"Milliseconds before automatic dismissal; `Infinity` disables automatic dismissal.\n\nAttribute: `duration`","type":"number","default":"Infinity"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"open","description":"Whether the alert is visible. The attribute reflects method and property changes.\n\nAttribute: `open`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"role","description":"Light-DOM semantic role for the projected message. Reflected so server renderers can\nserialize the default before browser connection; an authored role continues to win.\n\nAttribute: `role`  \nReflected to its attribute.","type":"string | null","default":"'alert'"},{"name":"size","description":"Density tier on the library's one size ladder, in either spelling — `2xs`/`xs`/`s`/`m`/`l`/\n`xl`, or Web Awesome's and Shoelace's `small`/`medium`/`large`. A Lyra addition on top of the\npinned Shoelace surface, and opt-in for that reason: with no size the panel keeps the exact\npadding and inherited text size it shipped with, so migrated markup renders unchanged. A tier\nscales the panel's padding and text together and takes `<lr-callout>`'s tier values for both,\nkeeping the same constant gap, so a tiered alert and a tiered callout of the same size line\nup in one column. Their UNSET states are NOT interchangeable, deliberately: with no tier this\npanel keeps a fixed gutter and inherits the ambient text size — its exact pre-ladder\nrendering — while an untiered `<lr-callout>` reads the ambient form-control slots and falls\nback to `--lr-space-m` / `--lr-font-size-m`. Pinning a default tier here would resize every\nalert that shipped before the ladder reached this component. Unsupported values normalize to\nthe omitted state and remove the attribute.\n\nAttribute: `size`  \nReflected to its attribute.","type":"LyraSize | undefined"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"variant","description":"Attribute: `variant`  \nReflected to its attribute.","type":"AlertVariant","default":"'primary'"}],"events":[{"name":"lr-after-hide","description":"Emitted after the alert's hide motion completes. Noncancelable.","type":"CustomEvent<null>"},{"name":"lr-after-show","description":"Emitted after the alert's show motion completes. Noncancelable.","type":"CustomEvent<null>"},{"name":"lr-hide","description":"The alert is about to close, including an auto-hide expiry. Cancelable on the same terms as `lr-show`.","type":"CustomEvent<null>"},{"name":"lr-show","description":"The alert is about to open. Cancelable — `preventDefault()` leaves it closed and the reflected attribute untouched.","type":"CustomEvent<null>"}]}},{"name":"lr-animated-image","description":"`<lr-animated-image>` -- displays an animated GIF/APNG/WebP with a\nplay/pause control, defaulting to a frozen first frame both at rest and\nautomatically under `prefers-reduced-motion: reduce` (unless the page\nauthor explicitly opts back in via `respect-reduced-motion=\"false\"`), so\nmotion is never forced on a user who asked for less of it.\n\n**Freeze-frame mechanism.** The live `<img>`'s `load` event handler\nsynchronously draws the just-loaded image to `[part=\"canvas\"]` (a\nDPR-aware `drawImage()`, the same pattern `<lr-heatmap>` uses for its own\ncanvas sizing) before any animation frames have had a chance to advance.\nThat captured frame is what pausing always reverts to -- it is not\nre-captured on every pause, only once per successful `src` load. Both\n`[part=\"image\"]` and `[part=\"canvas\"]` stay mounted at all times (never\n`display: none`/removed) so the browser's native decode loop keeps running\neven while visually covered by the frozen canvas; only opacity and\n`aria-hidden` swap between them, driven by the effective `playing` state.\n\n**`play` vs. `playing`.** `play` is the caller's intent (settable and\nreflected). `playing` is the read-only, reflected effect\nafter reduced-motion arbitration: `play && !(respectReducedMotion &&\n<OS prefers-reduced-motion: reduce>)`. A page can set `.play = true` while\nreduced motion still keeps the visual frozen -- `lr-play`/`lr-pause`\nonly fire on a real transition of the resolved `playing` value, never on a\n`play` assignment that reduced motion blocks from taking visible effect.\n\n**Safety.** `src` is re-validated through `safeMediaSrc()` (the same\nallowlist `<lr-media-card>` uses) before it is ever assigned to the real\n`<img src>`. An empty `src` renders no `src` attribute and is not an\nerror; a non-empty `src` that fails the check is treated exactly like a\nnative image decode failure -- `lr-error` fires and no request is ever\nattempted.\n\n**Alternative text follows native image presence semantics.** An absent or explicitly empty\n`alt` keeps the image and frozen canvas decorative, matching the mirrored components. A\nnonempty value names whichever of those two mutually-exclusive visual owners is exposed. The\nplay/pause button remains independently named with localized action text.\n\nLyra deliberately adds a reduced-motion safety policy and a bounded `--lr-animated-image-max-height`\ndefault beyond the mirrored components. Set `respect-reduced-motion=\"false\"` when preserving\nupstream playback under a reduced-motion preference is required, and override the max-height\nhook with `none` when the upstream unconstrained block-size is required.\n\nDeliberately no label/hint/error chrome -- this is not a form-associated\ncontrol (nothing resembling a value the user submits).\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| `pause-icon` | Decorative custom pause glyph shown while playing. Rendered through the same inert sibling layer. |\n| `play-icon` | Decorative custom play glyph shown while frozen/paused. Rendered in an inert, aria-hidden, pointer-transparent sibling layer over the play/pause button. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | Root wrapper; positioning context for `control-box`. |\n| `canvas` | The frozen-frame `<canvas>`, shown in place of `image` while not playing. |\n| `control-box` | The container that surrounds and backgrounds the play/pause button. Only rendered once loaded and error-free. |\n| `image` | The live `<img>`. |\n| `play-button` | The `<button type=\"button\">` inside `control-box` that toggles `play`. |\n\n---\n\n**CSS Custom Properties**\n\n- `--control-box-size` — Upstream-compatible alias for `--lr-animated-image-control-box-size`.\n- `--icon-size` — Upstream-compatible alias for `--lr-animated-image-icon-size`.\n- `--lr-animated-image-control-box-size` — The size of `control-box`. Defaults to `var(--lr-icon-button-size)`.\n- `--lr-animated-image-icon-size` — The size of the play/pause icons. Defaults to `calc(var(--lr-icon-button-size) * 0.35)`.\n- `--lr-animated-image-max-height` — Caps the rendered media's block-size. Defaults to `var(--lr-size-20rem)`.","attributes":[{"name":"alt","description":"A description of the image used by assistive devices. Absent/empty means decorative.\n\nType: `string | undefined`"},{"name":"aria-label","description":"Accessible-name override for `[part=\"play-button\"]`. Maps to the\nhost's `aria-label` attribute and, once set, wins verbatim over the\ncomputed per-state Play/Pause label in both play and pause states --\nit does not itself vary by state. Never touches `[part=\"image\"]`'s\n`alt` / `[part=\"canvas\"]`'s `aria-label`, which stay independently\nsourced from `alt`. A consumer wanting state-sensitive custom wording\nwithout losing the Play/Pause distinction should override the\n`playWithContext`/`pauseWithContext`/`animatedImageDefaultAlt` strings\ninstead.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"play","description":"Requests animated playback. Distinct from the read-only `playing`\neffect -- see the class doc's \"`play` vs. `playing`\" section.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"respect-reduced-motion","description":"When `true` (default) and the platform reports\n`prefers-reduced-motion: reduce`, playback stays frozen and\n`[part=\"play-button\"]` is disabled regardless of `play`. Set to `false`\nto let `play` take effect even under a reduced-motion preference -- a\ndeliberate, page-author-level override.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"src","description":"The path to the image to load. Always re-validated against a\nsafe-scheme allowlist before use -- see the class doc.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"slots":[{"name":"pause-icon","description":"Decorative custom pause glyph shown while playing. Rendered through the same inert sibling layer."},{"name":"play-icon","description":"Decorative custom play glyph shown while frozen/paused. Rendered in an inert, aria-hidden, pointer-transparent sibling layer over the play/pause button."}],"js":{"properties":[{"name":"accessibleLabel","description":"Accessible-name override for `[part=\"play-button\"]`. Maps to the\nhost's `aria-label` attribute and, once set, wins verbatim over the\ncomputed per-state Play/Pause label in both play and pause states --\nit does not itself vary by state. Never touches `[part=\"image\"]`'s\n`alt` / `[part=\"canvas\"]`'s `aria-label`, which stay independently\nsourced from `alt`. A consumer wanting state-sensitive custom wording\nwithout losing the Play/Pause distinction should override the\n`playWithContext`/`pauseWithContext`/`animatedImageDefaultAlt` strings\ninstead.\n\nAttribute: `aria-label`","type":"string","default":"''"},{"name":"alt","description":"A description of the image used by assistive devices. Absent/empty means decorative.\n\nAttribute: `alt`","type":"string | undefined"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"play","description":"Requests animated playback. Distinct from the read-only `playing`\neffect -- see the class doc's \"`play` vs. `playing`\" section.\n\nAttribute: `play`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"playing","description":"The effective playing state after reduced-motion arbitration -- also\nreflected as a `playing` host attribute. Read-only; control playback\nvia `play`.","type":"boolean","read-only":true},{"name":"respectReducedMotion","description":"When `true` (default) and the platform reports\n`prefers-reduced-motion: reduce`, playback stays frozen and\n`[part=\"play-button\"]` is disabled regardless of `play`. Set to `false`\nto let `play` take effect even under a reduced-motion preference -- a\ndeliberate, page-author-level override.\n\nAttribute: `respect-reduced-motion`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"src","description":"The path to the image to load. Always re-validated against a\nsafe-scheme allowlist before use -- see the class doc.\n\nAttribute: `src`","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"blur","description":"Relayed once from the internal play/pause button as a bubbling, composed native event.","type":"FocusEvent"},{"name":"focus","description":"Relayed once from the internal play/pause button as a bubbling, composed native event.","type":"FocusEvent"},{"name":"lr-error","description":"The live `<img>` failed to load, or `src` was non-empty but failed the safe-URL check. Never fires for an empty `src`.","type":"CustomEvent<null>"},{"name":"lr-load","description":"The live `<img>` finished loading. Fires again on every successful subsequent `src` change.","type":"CustomEvent<null>"},{"name":"lr-pause","description":"The effective `playing` state transitioned `true` -> `false` (including a reduced-motion change forcing a freeze while `play` stays `true`).","type":"CustomEvent<null>"},{"name":"lr-play","description":"The effective `playing` state transitioned `false` -> `true`.","type":"CustomEvent<null>"}]}},{"name":"lr-animation","description":"`<lr-animation>` declaratively animates its single slotted child through the\nnative Web Animations API: a small curated preset catalog (`name`) or fully\ncustom `keyframes`, explicit WAAPI timing controls, an optional\n`playOnVisible` trigger, and a `lr-start`/`lr-finish`/`lr-cancel` event\ncontract. An initial playing mount creates one animation and emits one start; later target or\ntiming changes still rebuild, and replay keeps its normal lifecycle.\n\n`keyframes`, when set, always wins over `name`. The `iterations` default is\n`Infinity` (mirrors the upstream Web Awesome/Shoelace animation contract\nverbatim) -- a named preset plays forever unless the consumer sets\n`iterations=\"1\"`.\n\n`direction` is the Web Animations API's `PlaybackDirection`\n(`'normal' | 'reverse' | 'alternate' | 'alternate-reverse'`) and is entirely\nunrelated to text direction. Only the `slide-in-start`/`slide-in-end`/\n`slide-out-start`/`slide-out-end` presets read the inherited text direction\n(`effectiveDirection`) to resolve which physical edge \"start\"/\"end\" means,\nand they do so fresh every time the animation is (re)built -- an animation\nalready mid-flight is not retroactively re-mirrored if an ancestor `dir`\nflips while it plays; the next rebuild picks up the change.\n\n`respectReducedMotion` (default `true`) caps playback to one iteration and\ncalls `finish()` immediately instead of playing, whenever the OS/browser\nreports `prefers-reduced-motion: reduce` -- the target snaps straight to\nits resolved end state, and `lr-start`/`lr-finish` still fire in order\nso a consumer sequencing further UI off those events keeps working even\nthough nothing visibly interpolated. Set `respectReducedMotion=\"false\"`\nonly for genuine user-triggered feedback (e.g. a drag-confirm snap-back)\nwhere a silent jump would be more confusing than a fast real animation --\nambient/decorative animation should always leave this at its default.\n\n`timingPreset` (default `'custom'`) optionally derives `duration`/`easing`\nfrom the shared `--lr-transition-fast`/`-base`/`-ambient` tokens instead\nof the raw `duration`/`easing` property values, so an app's global motion\nretiming reaches this component's animations too.\n\nNamed presets resolve through the public animation registry as `animation.<name>`. Per-element\noverrides win over page defaults; `rtlKeyframes` follows the live inherited text direction and\na `null` override disables interpolation without skipping `lr-start`/`lr-finish`.\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 element to animate. A second slotted element is accepted without error but ignored. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-animation-bounce-height` (default: `25%`) — Peak lift height of the bounce preset.\n- `--lr-animation-shake-distance` (default: `4%`) — Horizontal travel of the shake preset.\n- `--lr-animation-slide-distance` (default: `100%`) — Travel distance for the slide-in/slide-out/slide-in-up/slide-in-down presets.\n- `--lr-animation-zoom-scale` (default: `0.5`) — Starting/ending scale factor for the zoom-in/zoom-out presets.","attributes":[{"name":"delay","description":"Type: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"direction","description":"Type: `PlaybackDirection`  \nDefault: `'normal'`","value":{"type":["'alternate'","'alternate-reverse'","'normal'","'reverse'"]}},{"name":"duration","description":"Type: `number`  \nDefault: `1000`","value":{"type":["number"]}},{"name":"easing","description":"Type: `string`  \nDefault: `'linear'`","value":{"type":["string"]}},{"name":"end-delay","description":"Type: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"fill","description":"Type: `FillMode`  \nDefault: `'auto'`","value":{"type":["'auto'","'backwards'","'both'","'forwards'","'none'"]}},{"name":"iteration-start","description":"Type: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"iterations","description":"Type: `number`  \nDefault: `Infinity`","value":{"type":["number"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"name","description":"Built-in preset or consumer-registered `animation.<name>` key.\n\nType: `string`  \nDefault: `'none'`","value":{"type":["string"]}},{"name":"play","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"play-on-visible","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"play-on-visible-repeat","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"playback-rate","description":"Type: `number`  \nDefault: `1`","value":{"type":["number"]}},{"name":"respect-reduced-motion","description":"Type: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"root-margin","description":"Type: `string`  \nDefault: `'0px'`","value":{"type":["string"]}},{"name":"timing-preset","description":"Type: `LyraAnimationTimingPreset`  \nDefault: `'custom'`","value":{"type":["'custom'","'fast'","'base'","'ambient'"]}}],"slots":[{"name":"","description":"The element to animate. A second slotted element is accepted without error but ignored."}],"js":{"properties":[{"name":"currentTime","type":"CSSNumberish"},{"name":"delay","description":"Attribute: `delay`","type":"number","default":"0"},{"name":"direction","description":"Attribute: `direction`","type":"PlaybackDirection","default":"'normal'"},{"name":"duration","description":"Attribute: `duration`","type":"number","default":"1000"},{"name":"easing","description":"Attribute: `easing`","type":"string","default":"'linear'"},{"name":"endDelay","description":"Attribute: `end-delay`","type":"number","default":"0"},{"name":"fill","description":"Attribute: `fill`","type":"FillMode","default":"'auto'"},{"name":"iterationStart","description":"Attribute: `iteration-start`","type":"number","default":"0"},{"name":"iterations","description":"Attribute: `iterations`","type":"number","default":"Infinity"},{"name":"keyframes","type":"Keyframe[] | undefined","default":"undefined"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"name","description":"Built-in preset or consumer-registered `animation.<name>` key.\n\nAttribute: `name`","type":"string","default":"'none'"},{"name":"play","description":"Attribute: `play`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"playOnVisible","description":"Attribute: `play-on-visible`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"playOnVisibleRepeat","description":"Attribute: `play-on-visible-repeat`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"playbackRate","description":"Attribute: `playback-rate`","type":"number","default":"1"},{"name":"respectReducedMotion","description":"Attribute: `respect-reduced-motion`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"root","type":"Element | null","default":"null"},{"name":"rootMargin","description":"Attribute: `root-margin`","type":"string","default":"'0px'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"threshold","description":"Intersection thresholds for `playOnVisible`; arrays are bounded, filtered, and frozen.","type":"number | readonly number[]"},{"name":"timingPreset","description":"Attribute: `timing-preset`  \nReflected to its attribute.","type":"LyraAnimationTimingPreset","default":"'custom'"}],"events":[{"name":"lr-cancel","description":"The animation was canceled via the public `cancel()` method or external cancellation.","type":"CustomEvent<null>"},{"name":"lr-finish","description":"The animation reached its natural end, including the reduced-motion instant-finish path.","type":"CustomEvent<null>"},{"name":"lr-start","description":"A new animation was created and playback began or restarted.","type":"CustomEvent<null>"}]}},{"name":"lr-app-rail","description":"`<lr-app-rail>` — a responsive navigation rail that adapts across three\npresentations as the *viewport* narrows (not this element's own inline\nsize — see the `mode` getter doc for why): `'full'` (nav items show\nicon + label, inline), `'icon-only'` (a narrower inline rail, icons only),\nand `'mobile'` (hidden behind a toggle button; opening it shows a\nfocus-trapped floating overlay over the page).\n\nBreakpoints are viewport-width `matchMedia()` queries against\n`icon-only-breakpoint`/`mobile-breakpoint`, not a `ResizeObserver` on this\nelement — a nav rail's presentation should track the actual device/window\nwidth the way a native OS shell's navigation does, not however much\nhorizontal space a particular layout happens to give it.\n\nThe `'mobile'` state participates in the library's shared overlay stack,\nwhich supplies focus trapping, Escape/backdrop dismissal, inerting, and\nfocus restoration without nesting a `<lr-dialog>` in this component's\nshadow template. `[part=\"base\"]` (the inline\n`'full'`/`'icon-only'` presentation) and `[part=\"panel\"]` (the mobile\noverlay) are the *same* element promoted in place across modes (mirrors\n`<lr-widget>`'s fullscreen mode) — never both at once, and never two\nseparate copies of the slotted content, which slot projection can't\nproduce anyway (a light-DOM node is only ever assigned to one `<slot>`).\nIt's a plain `<div>` with an explicit `role=\"navigation\"` rather than a\nliteral `<nav>` tag: a `<nav>`'s implicit role can't be overridden to\n`role=\"dialog\"` while the overlay is modal without an `aria-allowed-role`\nviolation (verified against axe), whereas an explicit `role=\"navigation\"`\non a generic element can be swapped for `role=\"dialog\"` freely.\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) | Nav items. Use `<lr-app-rail-item>` for the explicit icon/label contract that automatically hides labels in `'icon-only'` mode, and `<lr-app-rail-group>` to title and optionally collapse a section of them -- a slotted group is marked `icon-only` exactly like a slotted item, and forwards that state to the items it owns. Generic links and buttons remain supported, but their compact presentation is the consumer's responsibility. While the mobile overlay is open, clicking anywhere inside this slot closes it. |\n| `footer` | A trailing user/settings trigger, shown below the nav items. |\n| `header` | Logo/brand content, shown above the nav items in every mode. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `backdrop` | The mobile overlay's scrim. Only rendered while open. |\n| `base` | The rail root while inline (`'full'`/`'icon-only'` modes). |\n| `collapse-icon` | The wrapper around `[part=\"collapse-toggle\"]`'s chevron. The glyph is direction-aware through this wrapper's own `transform` (never a second, mirrored icon), so it always points toward the edge the rail is about to move to, under both `dir` values. |\n| `collapse-toggle` | The opt-in desktop collapse control, rendered inside `[part=\"header\"]` only while `collapsible` is set and `mode` is not `'mobile'`. Carries the localized expand/collapse accessible name and renders `aria-expanded` in both states, so a screen reader announces the rail's current presentation rather than only its label. `aria-expanded` is deliberate even though collapsing removes nothing from the accessibility tree: `'icon-only'` only clips each item's `[part=\"label\"]`/`[part=\"meta\"]` visually, so a screen-reader user reads the same nav either way, and the attribute is what tells a magnifier or braille user which of the two presentations they are currently in. Its `aria-controls` names `[part=\"nav\"]` — the item list whose presentation actually changes — never the `[part=\"base\"]`/`[part=\"panel\"]` element, which CONTAINS this button and would make the control claim to expand its own ancestor. |\n| `footer` | The wrapper around the `footer` slot. |\n| `header` | The wrapper around the `header` slot. |\n| `nav` | The wrapper around the default (nav items) slot. |\n| `panel` | The mobile overlay's floating panel — see the class doc for why it's the same element as `base`, never both at once. |\n| `resizer` | The `resizable` opt-in's drag handle -- its interactive hit target, sized to the shared minimum tappable size (`--lr-icon-button-size`), independent of the slimmer visible line rendered by its `resizer-track` child. Its numeric ARIA range remains in CSS pixels while `aria-valuetext` reports the current width through the effective locale. Only rendered while `resizable` and `mode` is `'full'`. |\n| `resizer-track` | The resizer's slim visible drag line, centered inside `[part=\"resizer\"]`'s larger hit target (mirrors `<lr-swatch-picker>`'s `[part=\"swatch\"]`/`[part=\"swatch-fill\"]` split). Colors on hover/focus the same way the whole handle previously did. |\n| `toggle` | The mobile hamburger/close toggle button. Hidden via CSS outside `'mobile'` mode, or -- while it is not also serving as the panel's only in-panel dismiss control (see below) -- entirely via `hideToggle`; it inherits the rail's typography and its glyph scales at 1em. Reparented to be the first child of `[part=\"panel\"]` for exactly as long as the mobile overlay is open, so the shared focus trap (scoped to the panel alone) can reach it and Tab cycles through it like `<lr-dialog>`'s in-panel close button; moved back to its resting position, a sibling ahead of `[part=\"panel\"]`, once closed. Reparenting reuses the same element throughout (never destroyed/recreated), so a reference captured before opening remains valid after closing. Rendered as its own reserved row ahead of the `header` slot while inside the panel, never absolutely overlaid on top of it, so a wide/slotted header is never obscured. `hideToggle` only suppresses it in its OUTSIDE/closed position (the \"open\" trigger, redundant once a consumer wires an external `trigger`/`for`); it stays visible once reparented inside the open panel, since it is then the only in-panel dismiss control. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-app-rail-background` (default: `var(--lr-color-surface)`) — `[part=\"base\"]`'s background (the docked, non-overlay presentation).\n- `--lr-app-rail-collapse-toggle-active-bg` — Collapse-control pressed background; defaults to the same brand-quiet active mix `[part=\"toggle\"]` uses.\n- `--lr-app-rail-collapse-toggle-active-color` (default: `var(--lr-color-brand)`) — Collapse-control pressed foreground.\n- `--lr-app-rail-collapse-toggle-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Collapse-control hover background.\n- `--lr-app-rail-collapse-toggle-hover-color` (default: `var(--lr-color-brand)`) — Collapse-control hover foreground.\n- `--lr-app-rail-footer-padding` (default: `var(--lr-space-m)`) — `[part=\"footer\"]`'s padding.\n- `--lr-app-rail-header-min-block-size` (default: `auto`) — `[part=\"header\"]`'s minimum block size. `auto` (the default) is the property's own initial value, so unset reproduces today's exact height; set it to reserve room for header content that mounts or resizes asynchronously.\n- `--lr-app-rail-header-padding` (default: `var(--lr-space-m)`) — `[part=\"header\"]`'s padding.\n- `--lr-app-rail-icon-width` (default: `var(--lr-size-4rem)`) — The inline rail's width in `'icon-only'` mode, and the maximum width of each slotted `<lr-app-rail-item>` in that mode.\n- `--lr-app-rail-mobile-width` (default: `var(--lr-size-18rem)`) — The mobile overlay panel's width, capped at `85vw`.\n- `--lr-app-rail-nav-gap` (default: `var(--lr-space-xs)`) — Gap between slotted items inside `[part=\"nav\"]`, unset reproducing the value this rule hard-coded before the token existed.\n- `--lr-app-rail-nav-padding` (default: `var(--lr-space-s)`) — `[part=\"nav\"]`'s padding, unset reproducing the value this rule hard-coded before the token existed.\n- `--lr-app-rail-overlay-color` (default: `var(--lr-color-overlay)`) — The mobile overlay scrim's background.\n- `--lr-app-rail-panel-background` (default: `var(--lr-color-surface-overlay)`) — `[part=\"panel\"]`'s background (the mobile overlay presentation) -- kept separate from `--lr-app-rail-background`/`--lr-app-rail-overlay-color` (the backdrop scrim) since the panel is deliberately themed as a modal surface, not the docked rail chrome.\n- `--lr-app-rail-panel-inset-block-start` (default: `0`) — Block-start (top) inset shared by `[part=\"panel\"]` and `[part=\"backdrop\"]` -- raise it to leave room for a fixed app bar/status area above the drawer instead of the panel/scrim starting flush with the viewport top.\n- `--lr-app-rail-panel-overflow-block` (default: `auto`) — `[part=\"panel\"]`'s logical `overflow-block`, paired with `--lr-app-rail-panel-overflow-inline` below.\n- `--lr-app-rail-panel-overflow-inline` (default: `clip`) — `[part=\"panel\"]`'s logical `overflow-inline`. `clip` (the default) prevents a spurious horizontal scrollbar from wide slotted header/footer content, but also clips a `position: fixed` popup opened by a slotted/nav-item control (e.g. a slotted `<lr-select>`/`<lr-menu>`) whenever that popup's rendered box extends past the panel's own inline bounds -- a `position: fixed` box is clipped by an ancestor's non-`visible` overflow regardless of its own containing block. Setting only this one to `visible` is not enough to escape that: per the CSS overflow spec, a lone `visible` axis paired with a non-`visible` other axis computes as `auto` instead, which still clips -- set `--lr-app-rail-panel-overflow-block` to `visible` too to actually stop the clipping, accepting that wide header/footer content can then scroll/bleed both ways instead.\n- `--lr-app-rail-panel-radius` (default: `0`) — Uniform corner radius of `[part=\"panel\"]`. `0` (the default) reproduces today's flush-edged drawer; pairs naturally with a nonzero `--lr-app-rail-panel-inset-block-start`, which exposes the panel's top corners. Each per-corner token below defaults to this one, so setting only this token still rounds all four corners uniformly, exactly as before the per-corner tokens existed.\n- `--lr-app-rail-panel-radius-end-end` (default: `var(--lr-app-rail-panel-radius)`) — Logical `border-end-end-radius` of `[part=\"panel\"]` -- the corner away from the flush inline-start edge, block-end side. The other corner a flush-against-one-edge drawer typically rounds. All four per-corner tokens are logical, so which physical corner each one paints swaps under `dir=\"rtl\"` with no second consumer rule -- the panel's own flush edge stays its logical inline-start regardless of direction.\n- `--lr-app-rail-panel-radius-end-start` (default: `var(--lr-app-rail-panel-radius)`) — Logical `border-end-start-radius` of `[part=\"panel\"]` -- the corner at the drawer's own flush inline-start edge, block-end side.\n- `--lr-app-rail-panel-radius-start-end` (default: `var(--lr-app-rail-panel-radius)`) — Logical `border-start-end-radius` of `[part=\"panel\"]` -- the corner away from the flush inline-start edge, block-start side. One of the two corners a flush-against-one-edge drawer typically rounds.\n- `--lr-app-rail-panel-radius-start-start` (default: `var(--lr-app-rail-panel-radius)`) — Logical `border-start-start-radius` of `[part=\"panel\"]` -- the corner at the drawer's own flush inline-start edge, block-start side.\n- `--lr-app-rail-resizer-active-bg` — Resizer-track pressed background; defaults to the former brand active mix.\n- `--lr-app-rail-resizer-hover-bg` (default: `var(--lr-color-brand)`) — Resizer-track hover background.\n- `--lr-app-rail-toggle-active-bg` — Toggle pressed background; defaults to the former brand-quiet active mix.\n- `--lr-app-rail-toggle-active-color` (default: `var(--lr-color-brand)`) — Toggle pressed foreground.\n- `--lr-app-rail-toggle-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Toggle hover background.\n- `--lr-app-rail-toggle-hover-color` (default: `var(--lr-color-brand)`) — Toggle hover foreground.\n- `--lr-app-rail-width` (default: `var(--lr-size-15rem)`) — The inline rail's width in `'full'` mode. Overridden by an inline width while a `resizable` rail has an explicit `railWidthPx`.","attributes":[{"name":"aria-label","description":"Accessible name overriding `label` (and its localized default) for the nav landmark / dialog\nrole, mirroring `<lr-date-input>`'s `accessibleLabel` pattern. Reads the host's own\n`aria-label` attribute -- unset (the default, `null`) reproduces today's exact\n`label`/localized-default output.\n\nType: `string | null`  \nDefault: `null`"},{"name":"collapsible","description":"Opts in the desktop collapse control: a `[part=\"collapse-toggle\"]` button rendered inside\n`[part=\"header\"]` that flips the rail between its `'full'` and `'icon-only'` presentations,\nthe same flip `toggleCollapse()` performs. It writes `preferredMode`, so the collapse survives\na reload whenever `storage-key` is set and `persist` includes `preferred-mode`, and it still\nyields to a viewport too narrow for any inline rail (see `preferredMode`'s own doc).\n\nNot rendered at all while `mode` is `'mobile'` -- there is no inline rail to collapse there,\nand rendering it would add a second, meaningless control to the focus-trapped overlay next to\nthe `[part=\"toggle\"]` dismiss button. `false` (the default) reproduces today's exact output:\nno extra element, and `[part=\"header\"]`'s own block layout unchanged.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"for","description":"Id of an external element that opens this rail's mobile overlay, the label/`htmlFor`-style\nalternative to assigning `trigger` directly -- mirrors `<lr-page-rail>`'s `for`. Resolved\nagainst this element's own root (shadow root or document) when the overlay opens. Ignored\nonce `trigger` is itself set.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"force-mode","description":"Pins the rail's effective `mode` to `'full'` or `'icon-only'`, bypassing the live\n`icon-only-breakpoint`/`mobile-breakpoint` match entirely. The sentinel `'auto'` (and the\nunset default, `undefined`) release the pin and resume automatic breakpoint tracking --\nwhether the rail is currently pinned or auto-tracking is itself observable this way:\n`forceMode === 'auto'` (or unset) means auto-tracking, any other value means pinned.\n`'mobile'` cannot be pinned here -- the mobile breakpoint is always tracked automatically\nregardless, mirroring `preferredMode`'s own scope. An unrecognized value is ignored, leaving\nthe current pinned/auto-tracking state unchanged. Applies synchronously -- mirrors the\npre-9.0 `mode` setter this replaced, including for code (a resize gesture's own pointermove\nhandler, e.g.) that reads `mode`-derived state immediately after assigning this property,\nwith no intervening render. `mode` itself is a read-only resolved accessor; assign\n`forceMode` to change what it reports.\n\nType: `LyraAppRailPreferredMode | 'auto' | undefined`","value":{"type":["'full'","'icon-only'","'auto'"]}},{"name":"hide-toggle","description":"Suppresses the built-in mobile `[part='toggle']` hamburger/OPEN button -- for a consumer that\nalready owns an external mobile-menu trigger wired to this rail's own `open` property (see\n`trigger`/`for`). `false` (the default) reproduces today's exact output; note `open` still\nhas no built-in external trigger of its own once this is set, since `lr-toggle` only fires\nfrom the toggle button being removed. This does NOT remove the button once the overlay is\nopen: at that point it has been reparented inside the trapped `[part=\"panel\"]` (see the\n`toggle` csspart doc) as the panel's only in-panel dismiss control, and hiding it there too\nwould leave the open panel with no in-panel way to close it at all -- only Escape/backdrop.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"icon-only-breakpoint","description":"Below this viewport width, the rail switches from `'full'` to\n`'icon-only'`. Any valid CSS length, used directly in a `max-width`\nmedia query.\n\nType: `string`  \nDefault: `'960px'`","value":{"type":["string"]}},{"name":"label","description":"Optional accessible name for the rail's navigation landmark and mobile dialog. Every\nnonempty supplied string is literal; only absence/empty uses the localized fallback. A\nhost-level `aria-label` attribute takes precedence, including an explicit empty value.\n\nType: `string | undefined`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max-rail-width-px","description":"Maximum `railWidthPx` a drag/keyboard resize can reach.\n\nType: `number`  \nDefault: `440`","value":{"type":["number"]}},{"name":"min-rail-width-px","description":"Minimum `railWidthPx` a drag/keyboard resize can reach.\n\nType: `number`  \nDefault: `190`","value":{"type":["number"]}},{"name":"mobile-breakpoint","description":"Below this viewport width, the rail switches from `'icon-only'` to\n`'mobile'`. Should be smaller than `iconOnlyBreakpoint` to produce all\nthree states as the viewport narrows.\n\nType: `string`  \nDefault: `'600px'`","value":{"type":["string"]}},{"name":"open","description":"Whether the mobile floating overlay is shown. Only meaningful while\n`mode` is `'mobile'`; leaving mobile mode closes it so a later mobile\ntransition never restores a stale modal. Set this directly, or use the built-in toggle button\n— there is no separate `show()`/`hide()` pair.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"persist","description":"Whitespace-separated persistence allowlist. `open width` is the backward-compatible default;\nuse `width preferred-mode` to retain layout preference without restoring the transient mobile\noverlay. Valid tokens are `open`, `width`, and `preferred-mode`.\n\nType: `string`  \nDefault: `'open width'`","value":{"type":["string"]}},{"name":"preferred-mode","description":"Manually prefers `'full'` or `'icon-only'` for the non-mobile breakpoint axis, while the\n`mobile-breakpoint` continues to be tracked automatically regardless — e.g. a user's manual\ncollapse toggle that should still yield to a genuinely too-narrow-for-any-inline-rail\nviewport. Only consulted while `mode` isn't pinned via `forceMode` — that continues to take\nfull priority, unchanged. Unset (the default, `null`) reproduces today's exact\nbreakpoint-only behavior.\n\nType: `LyraAppRailPreferredMode | null | undefined`","value":{"type":["'full'","'icon-only'"]}},{"name":"rail-width-px","description":"The rail's current width in px while `resizable` — settable/gettable. Unset defers to the\n`--lr-app-rail-width` CSS token's own resolved width.\n\nType: `number | undefined`"},{"name":"resizable","description":"Opts a continuously draggable width in for the `'full'` state — exposes a `[part=\"resizer\"]`\nhandle (pointer-drag and `ArrowLeft`/`ArrowRight` keyboard stepping, RTL-aware) clamped to\n`[minRailWidthPx, maxRailWidthPx]`. Set `storageKey` to persist the fields selected by\n`persist`; otherwise listen for `lr-rail-resize` and persist its committed `widthPx` yourself.\nCall `preventDefault()` on `lr-rail-resize-request` to keep the current width. A request\nlistener that disables resizing, leaves full mode, or disconnects the rail also cancels the\npending proposal without overwriting listener state. `false` (the\ndefault) renders no resizer and leaves the fixed-width `--lr-app-rail-width` CSS token exactly\nas before this property existed.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"storage-key","description":"When set, persists the fields selected by `persist` to `localStorage` under\n`lr-app-rail:${storageKey}`, restoring them on the next mount — mirrors `lr-multi-split`'s\n`storage-key`. Effective `mode` is breakpoint-derived and is never persisted, and a stored\n`open` is restored only onto a mount whose breakpoint-derived mode is already `'mobile'` —\n`open` means nothing at a wider breakpoint (see its own doc), so a stored one is dropped\nthere rather than left primed to throw the overlay open the moment the viewport narrows.\nUnset (the default) means no persistence, exactly as before.\n\nType: `string | undefined`"}],"slots":[{"name":"","description":"Nav items. Use `<lr-app-rail-item>` for the explicit icon/label contract that automatically hides labels in `'icon-only'` mode, and `<lr-app-rail-group>` to title and optionally collapse a section of them -- a slotted group is marked `icon-only` exactly like a slotted item, and forwards that state to the items it owns. Generic links and buttons remain supported, but their compact presentation is the consumer's responsibility. While the mobile overlay is open, clicking anywhere inside this slot closes it."},{"name":"footer","description":"A trailing user/settings trigger, shown below the nav items."},{"name":"header","description":"Logo/brand content, shown above the nav items in every mode."}],"js":{"properties":[{"name":"collapsible","description":"Opts in the desktop collapse control: a `[part=\"collapse-toggle\"]` button rendered inside\n`[part=\"header\"]` that flips the rail between its `'full'` and `'icon-only'` presentations,\nthe same flip `toggleCollapse()` performs. It writes `preferredMode`, so the collapse survives\na reload whenever `storage-key` is set and `persist` includes `preferred-mode`, and it still\nyields to a viewport too narrow for any inline rail (see `preferredMode`'s own doc).\n\nNot rendered at all while `mode` is `'mobile'` -- there is no inline rail to collapse there,\nand rendering it would add a second, meaningless control to the focus-trapped overlay next to\nthe `[part=\"toggle\"]` dismiss button. `false` (the default) reproduces today's exact output:\nno extra element, and `[part=\"header\"]`'s own block layout unchanged.\n\nAttribute: `collapsible`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"dragging","description":"`true` for the duration of an active pointer-driven resize drag (not a keyboard step) --\nreflected so a consumer (or this component's own styles) can suppress `[part='base']`'s\n`transition: inline-size` during the drag, which otherwise visibly \"chases\" the pointer\ninstead of tracking it 1:1. Read-only -- this component owns the transitions entirely; there\nis no public setter.","type":"boolean","read-only":true},{"name":"for","description":"Id of an external element that opens this rail's mobile overlay, the label/`htmlFor`-style\nalternative to assigning `trigger` directly -- mirrors `<lr-page-rail>`'s `for`. Resolved\nagainst this element's own root (shadow root or document) when the overlay opens. Ignored\nonce `trigger` is itself set.\n\nAttribute: `for`","type":"string","default":"''"},{"name":"forceMode","description":"Pins the rail's effective `mode` to `'full'` or `'icon-only'`, bypassing the live\n`icon-only-breakpoint`/`mobile-breakpoint` match entirely. The sentinel `'auto'` (and the\nunset default, `undefined`) release the pin and resume automatic breakpoint tracking --\nwhether the rail is currently pinned or auto-tracking is itself observable this way:\n`forceMode === 'auto'` (or unset) means auto-tracking, any other value means pinned.\n`'mobile'` cannot be pinned here -- the mobile breakpoint is always tracked automatically\nregardless, mirroring `preferredMode`'s own scope. An unrecognized value is ignored, leaving\nthe current pinned/auto-tracking state unchanged. Applies synchronously -- mirrors the\npre-9.0 `mode` setter this replaced, including for code (a resize gesture's own pointermove\nhandler, e.g.) that reads `mode`-derived state immediately after assigning this property,\nwith no intervening render. `mode` itself is a read-only resolved accessor; assign\n`forceMode` to change what it reports.\n\nAttribute: `force-mode`","type":"LyraAppRailPreferredMode | 'auto' | undefined"},{"name":"hideToggle","description":"Suppresses the built-in mobile `[part='toggle']` hamburger/OPEN button -- for a consumer that\nalready owns an external mobile-menu trigger wired to this rail's own `open` property (see\n`trigger`/`for`). `false` (the default) reproduces today's exact output; note `open` still\nhas no built-in external trigger of its own once this is set, since `lr-toggle` only fires\nfrom the toggle button being removed. This does NOT remove the button once the overlay is\nopen: at that point it has been reparented inside the trapped `[part=\"panel\"]` (see the\n`toggle` csspart doc) as the panel's only in-panel dismiss control, and hiding it there too\nwould leave the open panel with no in-panel way to close it at all -- only Escape/backdrop.\n\nAttribute: `hide-toggle`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"iconOnlyBreakpoint","description":"Below this viewport width, the rail switches from `'full'` to\n`'icon-only'`. Any valid CSS length, used directly in a `max-width`\nmedia query.\n\nAttribute: `icon-only-breakpoint`","type":"string","default":"'960px'"},{"name":"label","description":"Optional accessible name for the rail's navigation landmark and mobile dialog. Every\nnonempty supplied string is literal; only absence/empty uses the localized fallback. A\nhost-level `aria-label` attribute takes precedence, including an explicit empty value.\n\nAttribute: `label`","type":"string | undefined"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"maxRailWidthPx","description":"Maximum `railWidthPx` a drag/keyboard resize can reach.\n\nAttribute: `max-rail-width-px`","type":"number","default":"440"},{"name":"minRailWidthPx","description":"Minimum `railWidthPx` a drag/keyboard resize can reach.\n\nAttribute: `min-rail-width-px`","type":"number","default":"190"},{"name":"mobileBreakpoint","description":"Below this viewport width, the rail switches from `'icon-only'` to\n`'mobile'`. Should be smaller than `iconOnlyBreakpoint` to produce all\nthree states as the viewport narrows.\n\nAttribute: `mobile-breakpoint`","type":"string","default":"'600px'"},{"name":"mode","description":"The rail's current effective presentation. Always one of the three real\nmodes — never `'auto'` — reflecting either the live breakpoint match or,\nonce pinned via `forceMode`, whatever mode is currently pinned.\n\nRead-only: this getter never accepts an assignment. Set `forceMode` to\npin `'full'`/`'icon-only'`, or to `'auto'`/unset to release the pin and\nresume automatic breakpoint tracking -- unlike the pre-9.0 `mode`\nsetter this replaced, whether the rail is currently pinned is itself\nobservable via `forceMode === 'auto'` (or unset).\n\nReflected to the `mode` attribute for `:host([mode=\"...\"])` styling --\nmanually, via `updated()`, since this property has no Lit-managed\naccessor to reflect through (see `setEffectiveMode()`).","type":"LyraAppRailMode","read-only":true},{"name":"open","description":"Whether the mobile floating overlay is shown. Only meaningful while\n`mode` is `'mobile'`; leaving mobile mode closes it so a later mobile\ntransition never restores a stale modal. Set this directly, or use the built-in toggle button\n— there is no separate `show()`/`hide()` pair.\n\nAttribute: `open`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"persist","description":"Whitespace-separated persistence allowlist. `open width` is the backward-compatible default;\nuse `width preferred-mode` to retain layout preference without restoring the transient mobile\noverlay. Valid tokens are `open`, `width`, and `preferred-mode`.\n\nAttribute: `persist`","type":"string","default":"'open width'"},{"name":"preferredMode","description":"Manually prefers `'full'` or `'icon-only'` for the non-mobile breakpoint axis, while the\n`mobile-breakpoint` continues to be tracked automatically regardless — e.g. a user's manual\ncollapse toggle that should still yield to a genuinely too-narrow-for-any-inline-rail\nviewport. Only consulted while `mode` isn't pinned via `forceMode` — that continues to take\nfull priority, unchanged. Unset (the default, `null`) reproduces today's exact\nbreakpoint-only behavior.\n\nAttribute: `preferred-mode`","type":"LyraAppRailPreferredMode | null | undefined"},{"name":"railWidthPx","description":"The rail's current width in px while `resizable` — settable/gettable. Unset defers to the\n`--lr-app-rail-width` CSS token's own resolved width.\n\nAttribute: `rail-width-px`","type":"number | undefined"},{"name":"resizable","description":"Opts a continuously draggable width in for the `'full'` state — exposes a `[part=\"resizer\"]`\nhandle (pointer-drag and `ArrowLeft`/`ArrowRight` keyboard stepping, RTL-aware) clamped to\n`[minRailWidthPx, maxRailWidthPx]`. Set `storageKey` to persist the fields selected by\n`persist`; otherwise listen for `lr-rail-resize` and persist its committed `widthPx` yourself.\nCall `preventDefault()` on `lr-rail-resize-request` to keep the current width. A request\nlistener that disables resizing, leaves full mode, or disconnects the rail also cancels the\npending proposal without overwriting listener state. `false` (the\ndefault) renders no resizer and leaves the fixed-width `--lr-app-rail-width` CSS token exactly\nas before this property existed.\n\nAttribute: `resizable`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"storageKey","description":"When set, persists the fields selected by `persist` to `localStorage` under\n`lr-app-rail:${storageKey}`, restoring them on the next mount — mirrors `lr-multi-split`'s\n`storage-key`. Effective `mode` is breakpoint-derived and is never persisted, and a stored\n`open` is restored only onto a mount whose breakpoint-derived mode is already `'mobile'` —\n`open` means nothing at a wider breakpoint (see its own doc), so a stored one is dropped\nthere rather than left primed to throw the overlay open the moment the viewport narrows.\nUnset (the default) means no persistence, exactly as before.\n\nAttribute: `storage-key`","type":"string | undefined"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"trigger","description":"Direct reference to an external element that opens this rail's mobile overlay -- e.g. a\nhamburger button living in application chrome rather than this component's own built-in\n`[part=\"toggle\"]` (typically paired with `hideToggle`). When set (or resolved through\n`for`), closing the overlay by ANY path -- Escape, backdrop click, a nav-item click, or the\nbuilt-in toggle itself -- returns focus to it, the same guarantee the built-in toggle's own\nclick already gets. An external trigger needs this explicit association instead of relying\non whatever last held focus: a consumer's own JS-driven `open = true` (rather than a real\nclick) never focuses anything, and even a real click does not reliably focus its target in\nevery browser. Resolved once when the overlay opens; reassign after that point to change the\nreturn target for the overlay's remaining lifetime. Read alongside `for`; this direct\nreference wins when both resolve to different elements. Unset (the default, `null`)\nreproduces today's exact behavior: only the built-in toggle's own click supplies a return\ntarget, for that interaction alone.","type":"HTMLElement | null","default":"null"}],"events":[{"name":"lr-mode-change","description":"The effective mode changed. A LIVE breakpoint crossing (after mount) or an explicit `forceMode` assignment fires immediately, synchronously with the change. The mode this component settles on for its very FIRST mount -- whether that is simply the initial breakpoint match, or a persisted `preferred-mode` restored from storage (`storage-key` + `persist=\"preferred-mode\"`) overriding it -- instead fires once, from that same mount's first `updated()`, so a listener always observes the single, settled mode once the initial render and attribute reflection have both already landed, never an intermediate pre-restore value the restore was always going to overwrite. Not fired for a redundant reassignment to the mode already in effect, nor when the first mount's settled mode never left the constructor default (the ordinary default-mode mount stays silent). `detail: LyraAppRailModeChangeDetail`.","type":"CustomEvent<LyraAppRailModeChangeDetail>"},{"name":"lr-rail-resize","description":"The `resizable` rail's width was committed: immediately after a genuine keyboard step, or once on pointerup after a genuine drag. Non-cancelable; no event is emitted for clamped no-ops, canceled/lost gestures, or direct `railWidthPx` writes. `detail: LyraAppRailResizeDetail`.","type":"CustomEvent<LyraAppRailResizeDetail>"},{"name":"lr-rail-resize-request","description":"A cancelable request to change the `resizable` rail's width via drag or keyboard stepping. Call `preventDefault()` to keep `railWidthPx` unchanged. Not fired when a consumer sets `railWidthPx` directly. `detail: LyraAppRailResizeDetail`.","type":"CustomEvent<LyraAppRailResizeDetail>"},{"name":"lr-toggle","description":"The mobile overlay is opening or closing — via the built-in toggle button, Escape, a backdrop click, a nav-item click while open, or a breakpoint/forced mode change leaving `'mobile'` while open. Not fired when a consumer sets `open` directly (mirrors `<lr-dialog>`'s `open`/`close()` split). `detail: LyraAppRailToggleDetail`. Conditionally cancelable: every interactive trigger can be vetoed, but the forced mode-change close always applies (vetoing it would leave `open` stuck `true` in a mode where it's meaningless) -- call `preventDefault()` to keep the overlay as it is.","type":"CustomEvent<LyraAppRailToggleDetail>"}]}},{"name":"lr-app-rail-group","description":"`<lr-app-rail-group>` — a titled section of navigation items inside `<lr-app-rail>`.\n\nGrouping is by COMPOSITION: a group holds whatever it is given (`<lr-app-rail-item>`s, nested\ngroups, anything else a consumer slots), and has no items array, no renderer callback and no\nmodel of its own. Nothing about its contents is described twice, so a group can never disagree\nwith what is actually rendered inside it.\n\nThe group names itself with a real heading landmark (`role=\"heading\"` plus a settable\n`aria-level`, not a hard-wired `<h3>` whose level would be wrong in half the pages that embed a\nrail), and labels its own `role=\"group\"` container from that same heading — so a screen-reader\nuser reaches \"Workspaces, group\" instead of an unnamed run of links.\n\n`collapsible` opts in the standard disclosure shape: the heading's own text becomes a button\ncarrying `aria-expanded` and `aria-controls`, exactly as the accordion pattern prescribes,\nrather than a separate unlabeled chevron next to an inert title. Collapsing goes through the\nlibrary's request/commit pair, so a consumer can veto it (`preventDefault()`) or resolve it\nitself by assigning `open` from the request listener.\n\nThe owning rail marks a slotted group `icon-only` the same way it marks a slotted item, and the\ngroup forwards that to the items and nested groups it DIRECTLY owns — including ones appended\nlater — so composition survives the rail's icon-only presentation without the rail having to\nreach through it. A nested group re-forwards in turn, so exactly one element ever writes\n`icon-only` onto any given node and a nested group clips its own heading too.\n\n---\n\n**Component metadata**\n\n- Status: `experimental`\n- Since: `16.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**Slots**\n\n| Name | Description |\n| --- | --- |\n| (default) | The group's navigation items. `<lr-app-rail-item>` and nested `<lr-app-rail-group>` children mirror the group's `icon-only` state automatically; anything else is rendered as given. |\n| `header-actions` | Controls rendered beside the heading — an \"add\" button, an overflow menu. A SIBLING of the heading (and so of the collapse control inside it), matching `<lr-details>`'s header-actions shape, so activating one never toggles the group. |\n| `heading` | Rich heading content, replacing the `heading` property. Becomes the collapse control's own accessible name while `collapsible` is set. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The `role=\"group\"` container. |\n| `content` | The collapsible region holding the default slot. |\n| `header` | The row holding the heading and any header actions. |\n| `header-actions` | The wrapper around the `header-actions` slot. Hidden while empty. |\n| `heading` | The heading landmark. Carries `role=\"heading\"` and `aria-level`. |\n| `heading-text` | The wrapper around the heading text/slot; visually clipped while `icon-only`, keeping the group's accessible name intact. |\n| `toggle` | The collapse control, only rendered while `collapsible` is set. Renders `aria-expanded` in both states and takes its accessible name from the heading text. Resolves to a square hit target (matching the icon-button footprint used elsewhere in this library) while `icon-only`, instead of stretching across the header row. |\n| `toggle-icon` | The wrapper around the collapse chevron. Direction-aware through this wrapper's own `transform`, never a second mirrored glyph. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-app-rail-group-active-bg` — Collapse-control pressed background; defaults to the same brand-quiet active mix the rest of the rail uses.\n- `--lr-app-rail-group-active-color` (default: `var(--lr-color-brand)`) — Collapse-control pressed foreground.\n- `--lr-app-rail-group-gap` (default: `var(--lr-space-xs)`) — Gap between the group's own items.\n- `--lr-app-rail-group-heading-color` (default: `var(--lr-color-text-quiet)`) — Heading text color.\n- `--lr-app-rail-group-heading-font-size` (default: `var(--lr-font-size-sm)`) — Heading font size.\n- `--lr-app-rail-group-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Collapse-control hover background.\n- `--lr-app-rail-group-hover-color` (default: `var(--lr-color-brand)`) — Collapse-control hover foreground.\n- `--lr-app-rail-group-padding-block` (default: `var(--lr-space-xs)`) — Block padding around `[part=\"base\"]`.","attributes":[{"name":"collapsible","description":"Opts in the built-in collapse control. `false` (the default) renders the heading as inert\ntext, exactly as a plain section title. `open` still governs whether the content renders, so\na consumer can drive collapse entirely from its own chrome without opting in here.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"heading","description":"The group's heading text. The `heading` slot replaces it when populated.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"heading-level","description":"The `aria-level` the heading landmark reports. A rail sits at a different depth in every\npage that embeds it, so the level is settable rather than baked into a fixed `<h3>`.\nClamped to the 1-6 range a heading can actually carry, and rounded; a non-finite value falls\nback to the default.\n\nType: `number`  \nDefault: `3`","value":{"type":["number"]}},{"name":"icon-only","description":"Type: `boolean`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"open","description":"Whether the group's content is shown. `true` by default — a nav section that hid itself on\nfirst paint would be the surprising default — which is why it carries\n`trueDefaultBooleanConverter`: Lit's presence-based boolean converter cannot parse\n`open=\"false\"`, so without it the property would be unsettable from markup.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}}],"slots":[{"name":"","description":"The group's navigation items. `<lr-app-rail-item>` and nested `<lr-app-rail-group>` children mirror the group's `icon-only` state automatically; anything else is rendered as given."},{"name":"header-actions","description":"Controls rendered beside the heading — an \"add\" button, an overflow menu. A SIBLING of the heading (and so of the collapse control inside it), matching `<lr-details>`'s header-actions shape, so activating one never toggles the group."},{"name":"heading","description":"Rich heading content, replacing the `heading` property. Becomes the collapse control's own accessible name while `collapsible` is set."}],"js":{"properties":[{"name":"collapsible","description":"Opts in the built-in collapse control. `false` (the default) renders the heading as inert\ntext, exactly as a plain section title. `open` still governs whether the content renders, so\na consumer can drive collapse entirely from its own chrome without opting in here.\n\nAttribute: `collapsible`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"heading","description":"The group's heading text. The `heading` slot replaces it when populated.\n\nAttribute: `heading`","type":"string","default":"''"},{"name":"headingLevel","description":"The `aria-level` the heading landmark reports. A rail sits at a different depth in every\npage that embeds it, so the level is settable rather than baked into a fixed `<h3>`.\nClamped to the 1-6 range a heading can actually carry, and rounded; a non-finite value falls\nback to the default.\n\nAttribute: `heading-level`","type":"number","default":"3"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"open","description":"Whether the group's content is shown. `true` by default — a nav section that hid itself on\nfirst paint would be the surprising default — which is why it carries\n`trueDefaultBooleanConverter`: Lit's presence-based boolean converter cannot parse\n`open=\"false\"`, so without it the property would be unsettable from markup.\n\nAttribute: `open`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-toggle","description":"The group finished opening or closing. Non-cancelable, emitted after `open` is written, and never emitted for a vetoed or listener-resolved request. `detail: LyraAppRailGroupToggleDetail`.","type":"CustomEvent<LyraAppRailGroupToggleDetail>"},{"name":"lr-toggle-request","description":"Cancelable proposal emitted before `open` changes from the built-in collapse control. Call `preventDefault()` to keep the current state, or assign `open` from the listener to resolve it yourself — a write during the dispatch suppresses the default commit even when it assigns the value the property already held. Not emitted for a direct `open` write. `detail: LyraAppRailGroupToggleDetail`.","type":"CustomEvent<LyraAppRailGroupToggleDetail>"}]}},{"name":"lr-app-rail-item","description":"`<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. `[part=\"base\"]` resolves to a square hit target\n(matching the icon-button footprint used elsewhere in this library) while\n`icon-only`, instead of stretching across the rail's icon column.\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\nAn item may own its own expandable child list -- the treeitem-with-link pattern used by\nrepository trees, Notion-style page trees and IDE explorers, where the row itself is a\ndestination and a SEPARATE disclosure expands that one item's own nested rows beneath it.\n`<lr-app-rail-group>` cannot express this: its collapsible heading IS the toggle, so nesting a\nnavigable link inside it would put an interactive element inside a button. Slotting one or more\n`<lr-app-rail-item>`s into `children` instead renders a built-in disclosure -- a SIBLING of\n`[part=\"base\"]`, never nested inside it, so the link keeps navigating on its own and the\ndisclosure keeps toggling on its own; clicking one never triggers the other. The disclosure\ncarries `aria-expanded`/`aria-controls` and a localized accessible name interpolating this\nitem's own label, mirroring `<lr-app-rail-group>`'s collapsible contract for event name, detail\nshape and cancelable request/commit semantics exactly (see `lr-toggle-request`/`lr-toggle`\nbelow). An item with nothing slotted into `children` renders no disclosure and no extra\nwrapper -- byte-identical to an item with no children slot at all.\n\n`icon-only` forwards onto every `<lr-app-rail-item>` this item DIRECTLY owns through `children`,\nexactly how `<lr-app-rail-group>` forwards onto the items and nested groups it owns -- so a\nnested item's own icon/label presentation tracks the rail's presentation without the rail\nreaching through two hosts. The disclosure itself never changes shape between presentations: it\nis always a fixed icon-button-sized square beside `[part=\"base\"]`, the same footprint `end` and\nicon-only `[part=\"base\"]` already use, so it needs no icon-only-specific styling of its own.\nThere is no ancestor-current treatment: `<lr-app-rail-group>` has no equivalent concept for a\ngroup containing the current item, so none is invented here either -- a current descendant\nstays perceivable only through its own `current` property, exactly as an unnested item would.\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| `children` | Nested `<lr-app-rail-item>`s disclosed beneath this item. Rendering anything into this slot grows a built-in disclosure button (`[part=\"toggle\"]`) as a sibling of `[part=\"base\"]`; leaving it empty renders neither the disclosure nor `[part=\"children\"]`. |\n| `end` | Trailing controls or adornments -- an overflow menu trigger, a status badge. Also a sibling of the internal link/button (the same shape `<lr-details>` uses for its `header-actions`), so a slotted control keeps its own click, keyboard activation and focus order instead of being swallowed by the item's own activation target. Unlike `meta` it stays visible in `icon-only` mode, where it shares the narrow rail's width with the icon. |\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| `meta` | Secondary trailing text -- an unread count, a keyboard shortcut. Rendered as a SIBLING of the internal link/button, never inside it, so it is not part of the item's accessible name and a pointer landing on it does not activate the item. Visually clipped in `icon-only` mode exactly as `[part=\"label\"]` is, staying available to assistive technology. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The link or button receiving focus and activation. |\n| `children` | The wrapper around the `children` slot. Rendered only while something is slotted into `children`; hidden (but present, so `aria-controls` keeps resolving) while `expanded` is `false`. |\n| `current-indicator` | A decorative inline indicator rendered only while the item is `current`/`aria-current=\"page\"`, mirroring `<lr-conversation-item>`'s shipped `active-indicator` part. |\n| `end` | The wrapper around the `end` slot, following `[part=\"meta\"]`. Hidden while empty for the same reason. |\n| `icon` | The icon wrapper. |\n| `label` | The label wrapper; visually clipped in icon-only mode. |\n| `meta` | The wrapper around the `meta` slot. Hidden while nothing is slotted into it, so an item without secondary text renders exactly as before the slot existed. |\n| `toggle` | The disclosure control, rendered only while something is slotted into `children`. A sibling of `[part=\"base\"]`, never nested inside it, so activating one never triggers the other. Carries `aria-expanded` in both states and `aria-controls` pointing at `[part=\"children\"]`'s id; its accessible name is a localized `this.localize()` template interpolating this item's own label, with no literal fallback. |\n| `toggle-icon` | The wrapper around the disclosure chevron. Direction-aware through this wrapper's own `transform`, never a second mirrored glyph -- mirrors `<lr-app-rail-group>`'s `[part=\"toggle-icon\"]`. |\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-current-font-weight` (default: `var(--lr-font-weight-semibold)`) — Font weight of the `current`/`aria-current=\"page\"` item, decoupled from the shared `--lr-font-weight-semibold` token so retheming it does not repaint every other semibold element on the page. Mirrors `<lr-stepper>`'s `--lr-stepper-current-font-weight` and `<lr-segmented>`'s `--lr-segmented-selected-font-weight`.\n- `--lr-app-rail-item-current-indicator-color` (default: `var(--lr-color-brand)`) — Color of the decorative `[part=\"current-indicator\"]` while current.\n- `--lr-app-rail-item-current-indicator-display` — `[part=\"current-indicator\"]`'s `display` while `icon-only`. Unset (the default), the indicator is suppressed there -- a full-height edge bar on the square icon-only tile reads as a rendering glitch. Set to `block` (or any non-`none` display) to restore it. Full presentation is unaffected either way; its own `[part=\"current-indicator\"]` rule declares no `display` at all.\n- `--lr-app-rail-item-current-indicator-inset-inline` (default: `0 auto`) — Logical inline-start and inline-end insets for `[part=\"current-indicator\"]`; set `auto 0` to place it at inline-end.\n- `--lr-app-rail-item-current-indicator-width` (default: `var(--lr-size-2px)`) — Inline size of `[part=\"current-indicator\"]` while current.\n- `--lr-app-rail-item-current-ring` — `box-shadow` on `[part=\"base\"]` while `current`/`aria-current=\"page\"`. Unset, icon-only gets an inset ring by default -- the non-color-only signal that replaces the indicator bar suppressed there (WCAG 1.4.1); full presentation, which already conveys current state through the indicator bar and `--lr-app-rail-item-current-font-weight`, stays ring-free (`none`) by default. Setting this token explicitly applies the same value in both presentations.\n- `--lr-app-rail-item-font-size` (default: `inherit`) — `[part=\"base\"]`'s font size, set after the `font` shorthand so it alone can be retuned while family/weight/line-height stay inherited.\n- `--lr-app-rail-item-gap` (default: `var(--lr-space-s)`) — Gap between `[part=\"icon\"]` and `[part=\"label\"]`, and between the item's own control and its `[part=\"meta\"]`/`[part=\"end\"]` adornments.\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.\n- `--lr-app-rail-item-icon-only-size` — When set, sizes `[part=\"base\"]`'s icon-only square (`inline-size` and `block-size` alike) directly, independent of the row's own `--lr-app-rail-item-min-block-size`. Unset (the default), the square is still derived via `aspect-ratio: 1` against the row's block size, exactly as before. Still floor-clamped to `--lr-icon-button-size` by `[part=\"base\"]`'s shared `min-block-size` rule.\n- `--lr-app-rail-item-icon-size` (default: `var(--lr-icon-button-size)`) — `[part=\"icon\"]`'s inline size. Not floor-clamped -- the icon is decorative, not itself a pointer target.\n- `--lr-app-rail-item-indent` (default: `var(--lr-space-l)`) — `[part=\"children\"]`'s `padding-inline-start`. Applied once per nesting level -- a doubly-nested `children` list compounds two insets automatically, since each level's own `[part=\"children\"]` applies the token again. Logical, so it mirrors under `dir=\"rtl\"` with no separate rule.\n- `--lr-app-rail-item-meta-color` (default: `var(--lr-color-text-quiet)`) — `[part=\"meta\"]`'s text color; quiet by default so a count reads as secondary to the label beside it.\n- `--lr-app-rail-item-meta-font-size` (default: `var(--lr-font-size-sm)`) — `[part=\"meta\"]`'s font size.\n- `--lr-app-rail-item-min-block-size` (default: `var(--lr-icon-button-size)`) — `[part=\"base\"]`'s row height. Floor-clamped to `--lr-icon-button-size` regardless of the override, preserving the WCAG 2.5.8 hit-area minimum.\n- `--lr-app-rail-item-padding` (default: `var(--lr-space-s)`) — `[part=\"base\"]`'s padding.\n- `--lr-positioning-strategy` — Cascading `absolute`/`fixed` override for the icon-only flyout tooltip's `fixed` default, read from computed style when it is (re)positioned. Set it once on `:root`, a theme, or one clipping ancestor to change every unset rail item beneath it; an unrecognized value falls back to `fixed`.","attributes":[{"name":"current","description":"Marks this as the destination for the current page/view. Reflects\n`aria-current=\"page\"` on `[part=\"base\"]` and drives the active visual\ntreatment -- the rail has no built-in routing, so the consumer sets\nthis per item (e.g. by comparing `href` against the current location).\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"disabled","description":"Prevents activation while retaining the item in the rail.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"expanded","description":"Whether this item's `children` are shown. `false` by default -- a nested list expanding\nitself on first paint would be a surprising default, and it reproduces exactly what an item\nwith no `expanded` property rendered before this feature existed. Mirrors\n`<lr-app-rail-group>`'s `open` accessor: every write, including one that assigns the value\nalready held, marks the veto guard so a synchronous `lr-toggle-request` listener resolving\nthis itself is observed correctly (see VetoWriteGuard).\n\nType: `boolean`","value":{"type":["boolean"]}},{"name":"href","description":"Optional destination. Without `href`, the item renders as a button.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"icon-only","description":"Type: `boolean`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"target","description":"Optional link target.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"tooltip","description":"Opt-in hover/focus flyout showing this item's label text while `icon-only` (set externally by\nthe parent `<lr-app-rail>` as the viewport narrows) hides it from view -- an explicit,\ndocumented property instead of an unverified cross-browser `::part()` + `::after` + `attr()`\ncomposition. No effect outside icon-only mode, since the label is already visible there.\n`false` (the default) reproduces today's exact output.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"","description":"The visible navigation label."},{"name":"children","description":"Nested `<lr-app-rail-item>`s disclosed beneath this item. Rendering anything into this slot grows a built-in disclosure button (`[part=\"toggle\"]`) as a sibling of `[part=\"base\"]`; leaving it empty renders neither the disclosure nor `[part=\"children\"]`."},{"name":"end","description":"Trailing controls or adornments -- an overflow menu trigger, a status badge. Also a sibling of the internal link/button (the same shape `<lr-details>` uses for its `header-actions`), so a slotted control keeps its own click, keyboard activation and focus order instead of being swallowed by the item's own activation target. Unlike `meta` it stays visible in `icon-only` mode, where it shares the narrow rail's width with the icon."},{"name":"icon","description":"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."},{"name":"meta","description":"Secondary trailing text -- an unread count, a keyboard shortcut. Rendered as a SIBLING of the internal link/button, never inside it, so it is not part of the item's accessible name and a pointer landing on it does not activate the item. Visually clipped in `icon-only` mode exactly as `[part=\"label\"]` is, staying available to assistive technology."}],"js":{"properties":[{"name":"current","description":"Marks this as the destination for the current page/view. Reflects\n`aria-current=\"page\"` on `[part=\"base\"]` and drives the active visual\ntreatment -- the rail has no built-in routing, so the consumer sets\nthis per item (e.g. by comparing `href` against the current location).\n\nAttribute: `current`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"disabled","description":"Prevents activation while retaining the item in the rail.\n\nAttribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"expanded","description":"Whether this item's `children` are shown. `false` by default -- a nested list expanding\nitself on first paint would be a surprising default, and it reproduces exactly what an item\nwith no `expanded` property rendered before this feature existed. Mirrors\n`<lr-app-rail-group>`'s `open` accessor: every write, including one that assigns the value\nalready held, marks the veto guard so a synchronous `lr-toggle-request` listener resolving\nthis itself is observed correctly (see VetoWriteGuard).\n\nAttribute: `expanded`  \nReflected to its attribute.","type":"boolean"},{"name":"href","description":"Optional destination. Without `href`, the item renders as a button.\n\nAttribute: `href`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"target","description":"Optional link target.\n\nAttribute: `target`","type":"string","default":"''"},{"name":"tooltip","description":"Opt-in hover/focus flyout showing this item's label text while `icon-only` (set externally by\nthe parent `<lr-app-rail>` as the viewport narrows) hides it from view -- an explicit,\ndocumented property instead of an unverified cross-browser `::part()` + `::after` + `attr()`\ncomposition. No effect outside icon-only mode, since the label is already visible there.\n`false` (the default) reproduces today's exact output.\n\nAttribute: `tooltip`  \nReflected to its attribute.","type":"boolean","default":"false"}],"events":[{"name":"lr-toggle","description":"The item finished expanding or collapsing its `children`. Non-cancelable, emitted after `expanded` is written, and never emitted for a vetoed or listener-resolved request. `detail: LyraAppRailItemToggleDetail`.","type":"CustomEvent<LyraAppRailItemToggleDetail>"},{"name":"lr-toggle-request","description":"Cancelable proposal emitted before `expanded` changes from the built-in disclosure. Call `preventDefault()` to keep the current state, or assign `expanded` from the listener to resolve it yourself -- a write during the dispatch suppresses the default commit even when it assigns the value the property already held. Not emitted for a direct `expanded` write. `detail: LyraAppRailItemToggleDetail` (`{ open: boolean }` -- the field is named `open`, matching `<lr-app-rail-group>`'s identical event name and detail shape exactly, so a listener bound to both components' `lr-toggle-request` need not branch on which fired).","type":"CustomEvent<LyraAppRailItemToggleDetail>"}]}},{"name":"lr-approval-queue","description":"`<lr-approval-queue>` — a controlled queue of tool calls that need human approval, with a\nkeyboard-accessible request list and a single reused `<lr-tool-approval-dialog>`. It never\nexecutes tools, applies permissions, or persists decisions; the host owns those operations.\nEmpty request ids are omitted and duplicate ids normalize before counts, selection, rendering,\nand events; the first valid occurrence wins.\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: `6.2.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 root queue wrapper. |\n| `count` | The pending-count text. |\n| `empty` | The empty state. |\n| `heading` | The visible queue heading. |\n| `heading-row` | The heading and pending-count row. |\n| `list` | The request list. |\n| `request` | One selectable request row. |\n| `request-id` | The stable request id. |\n| `request-info` | Request name and id wrapper. |\n| `status` | The request status badge. |\n| `tool-name` | The proposed tool name. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-approval-queue-selected-border` (default: `var(--lr-color-brand)`) — Selected request border.","attributes":[{"name":"editable","description":"Allows argument editing in the nested approval dialog.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"label","description":"Accessible name and visible heading. Optional. Omitting it localizes the default\n`approvalQueueLabel` message; an explicit empty string renders no visible/accessible label.\n\nType: `string | undefined`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"open","description":"Whether the decision dialog is open.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"selected-invocation-id","description":"Stable invocation identity of the request currently shown in the dialog, or `null` when none\nis selected.\n\nType: `string | null`  \nDefault: `null`"}],"js":{"properties":[{"name":"editable","description":"Allows argument editing in the nested approval dialog.\n\nAttribute: `editable`","type":"boolean","default":"true"},{"name":"label","description":"Accessible name and visible heading. Optional. Omitting it localizes the default\n`approvalQueueLabel` message; an explicit empty string renders no visible/accessible label.\n\nAttribute: `label`","type":"string | undefined"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"open","description":"Whether the decision dialog is open.\n\nAttribute: `open`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"requests","description":"Requests in display order. Controlled and never mutated by this component. Empty ids are\nomitted and duplicate ids normalize first-wins before counts, selection, dialog lookup, and\nevents.","type":"readonly ToolApprovalRequest[]","default":"[]"},{"name":"selectedInvocationId","description":"Stable invocation identity of the request currently shown in the dialog, or `null` when none\nis selected.\n\nAttribute: `selected-invocation-id`","type":"string | null","default":"null"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-approval-close","description":"The nested decision dialog closed, or controlled requests invalidated its formerly pending selection. `detail: { invocationId, reason }`; invalidation uses `reason: 'request-invalidated'` after selection and open state are cleared. Non-cancelable.","type":"CustomEvent<{ invocationId: string; reason: ToolApprovalDialogCloseReason }>"},{"name":"lr-approval-decision","description":"A request was approved or denied. `detail: { invocationId, approved, args? }`. Cancelable; preventing it keeps the nested dialog pending.","type":"CustomEvent<ToolApprovalEventDetail & { args?: unknown }>"},{"name":"lr-approval-select","description":"A request was selected. `detail: { invocationId }`.","type":"CustomEvent<{ invocationId: string }>"}]}},{"name":"lr-archive-viewer","description":"Lists names and declared uncompressed sizes in a ZIP archive without rendering entry contents\nor loading an archive parser. One owned central-directory parser is the listing and validation\nauthority: it enforces the 10,000-entry and 100 MB declared-expansion ceilings, validates local\nheader bounds and supported compression methods, and never inflates entry bodies.\nFragment anchors use the exact ZIP entry path as their `id`; rendered rows do not expose that\npath as a DOM `id`, so the viewer resolves entry metadata before mounting and scrolling the\nmatching virtual row. Text-quote anchors resolve against each complete entry path. Text\nselections and painted highlights are likewise scoped to entry paths in the nested virtual list.\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| `anchor-live-region` | The aria-hidden, non-live shadow mirror of the latest anchor-jump message. |\n| `base` | The root container with explicit `aria-busy` loading state. |\n| `body` | The archive listing body. |\n| `entry` | An archive entry row. |\n| `entry-icon` | The decorative folder or file icon. |\n| `entry-name` | The entry path. |\n| `entry-name-dir` | The entry path of a directory row (also carries `entry-name`). |\n| `entry-size` | The human-readable file size. |\n| `error` | The error region. |\n| `highlight` | A painted entry-path highlight (`<mark>` fallback path only). |\n| `spinner` | The visible tokenized loading treatment and ordinary text label. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-archive-viewer-max-height` (default: `none`) — Maximum block size of the scrollable body. Also settable via the `max-height` property.\n- `--lr-archive-viewer-highlight-accent-background` — Accent highlight background.\n- `--lr-archive-viewer-highlight-success-background` — Success highlight background.\n- `--lr-archive-viewer-highlight-warning-background` — Warning highlight background.\n- `--lr-archive-viewer-highlight-danger-background` — Danger highlight background.\n- `--lr-archive-viewer-highlight-neutral-background` — Neutral highlight background.\n- `--lr-archive-viewer-highlight-active-background` — Active highlight background.\n- `--lr-archive-viewer-highlight-active-outline` — Active fallback-highlight outline.","attributes":[{"name":"active-highlight-id","description":"Id of the currently active highlight, or null when none is active.\n\nType: `string | null`  \nDefault: `null`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max-height","description":"A CSS `max-height` for the scrollable archive body; invalid values are ignored.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"name","description":"Display name used on the shadow listing owner when host `aria-label` is absent. A non-empty\nhost label remains on the host; an explicitly empty one is preserved on the shadow owner.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"src","description":"URL to fetch and parse as a ZIP archive.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"js":{"properties":[{"name":"activeHighlightId","description":"Id of the currently active highlight, or null when none is active.\n\nAttribute: `active-highlight-id`","type":"string | null","default":"null"},{"name":"anchor","description":"Anchor or highlight id to resolve and scroll into view.","type":"LyraAnchor | string | null","default":"null"},{"name":"anchorKinds","description":"Anchor kinds supported by this viewer instance.","type":"readonly LyraAnchorKind[]","default":"[]","read-only":true},{"name":"highlights","description":"Highlights rendered by the document target. Reassign after mutation.","type":"LyraHighlight[]","default":"[]"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"maxHeight","description":"A CSS `max-height` for the scrollable archive body; invalid values are ignored.\n\nAttribute: `max-height`","type":"string","default":"''"},{"name":"name","description":"Display name used on the shadow listing owner when host `aria-label` is absent. A non-empty\nhost label remains on the host; an explicitly empty one is preserved on the shadow owner.\n\nAttribute: `name`","type":"string","default":"''"},{"name":"src","description":"URL to fetch and parse as a ZIP archive.\n\nAttribute: `src`","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-anchor-result","description":"Fired after an `anchor` assignment or `scrollToAnchor()` call is applied. `detail: { found }`.","type":"CustomEvent<AnchorResultDetail>"},{"name":"lr-render-error","description":"Fired when fetching or parsing the archive fails.","type":"CustomEvent<{ error: unknown }>"},{"name":"lr-search-change","description":"Fired when archive-path search state or its active match changes, including source-reset and effective-locale re-evaluation. Search accepts at most 4,096 query code units and scans at most 4,000,000 path code units; `detail.matchCountExact=false` identifies a ceiling-truncated lower bound.","type":"CustomEvent<LyraSearchChangeDetail>"},{"name":"lr-text-select","description":"Fired after a selection within one entry path. `detail: { text, anchor, rects }`; `anchor` is an entry-scoped text quote, or `null` when it cannot be anchored.","type":"CustomEvent<TextSelectDetail>"}]}},{"name":"lr-artifact-panel","description":"`<lr-artifact-panel>` — shell around one agent-generated artifact: a\ntitle/kind header, a preview<->code toggle, version navigation with\nrestore, a streaming indicator, and built-in copy/download actions.\nRenders none of the artifact itself — content is slotted. Version ids are stable identities;\nempty/blank ids are omitted and duplicates normalize before navigation, labels, restore actions,\nand counts, first-wins.\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| (default) | Preview-view content. |\n| `actions` | Extra header controls, rendered between the version navigation and the built-in copy/download buttons. |\n| `code` | Code-view content (typically a `<lr-code-block>`). The preview/code toggle only renders once this slot has assigned content. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `actions` | The `actions` slot wrapper. |\n| `base` | The root wrapper. |\n| `body` | The content body wrapper. |\n| `copy-button` | The copy button, rendered only while `copyText` is non-empty. |\n| `download-button` | The download button, rendered only while `downloadSrc` is non-empty. |\n| `header` | The header row. |\n| `kind` | The kind badge. |\n| `label` | The artifact title. |\n| `restore-button` | The restore-this-version button, rendered only while the active version isn't the latest one. |\n| `streaming-indicator` | The streaming state indicator, rendered only while `streaming`. |\n| `version-label` | The active `ArtifactVersion.label`, when supplied. |\n| `version-nav` | The version navigation group (rendered only once `versions` is non-empty). |\n| `version-next` | The next-version button. |\n| `version-next-glyph` | The chevron glyph inside `version-next`, mirrored under RTL. |\n| `version-position` | The \"Version N of M\" text. |\n| `version-previous` | The previous-version button. |\n| `version-previous-glyph` | The chevron glyph inside `version-previous`, mirrored under RTL. |\n| `view-button` | One toggle button; carries `data-view=\"preview\"` or `data-view=\"code\"`. |\n| `view-toggle` | The preview/code toggle group (rendered only once the `code` slot has content). |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-artifact-panel-view-active-bg` (default: `var(--lr-color-brand-quiet)`) — Background of the pressed (active) preview/code toggle button.\n- `--lr-artifact-panel-view-active-color` (default: `var(--lr-color-brand)`) — Text color of the pressed (active) preview/code toggle button. Restyling the pressed state otherwise requires overriding the library-wide brand tokens, since `::part(view-button)[aria-pressed]` is invalid CSS.","attributes":[{"name":"active-version-id","description":"The currently viewed version's id, or `null` to mean \"the latest version\".\n\nType: `string | null`  \nDefault: `null`"},{"name":"copy-text","description":"The text copied to the clipboard by the copy button. Empty hides the button.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"download-name","description":"The suggested filename reported in the `lr-download` event detail.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"download-src","description":"The download URL, sanitized through `safeDownloadHref()` before use. Empty hides the button.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"kind","description":"A short kind label (e.g. `document`, `code`), shown as a badge next to `label`.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"label","description":"The artifact's title, shown in the header. Optional. Omitting it localizes the default\n`artifactPanelLabel` message for the view-toggle group's accessible name (and shows no\nvisible title); an explicit empty string also renders no visible/accessible label.\n\nType: `string | undefined`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"streaming","description":"Whether the artifact is still being generated. Sets `aria-busy` on the body and shows a\ntext indicator instead of an animated one, so it stays legible under reduced motion.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"view","description":"Which slot is currently visible.\n\nType: `ArtifactPanelView`  \nDefault: `'preview'`","value":{"type":["'preview'","'code'"]}}],"slots":[{"name":"","description":"Preview-view content."},{"name":"actions","description":"Extra header controls, rendered between the version navigation and the built-in copy/download buttons."},{"name":"code","description":"Code-view content (typically a `<lr-code-block>`). The preview/code toggle only renders once this slot has assigned content."}],"js":{"properties":[{"name":"activeVersionId","description":"The currently viewed version's id, or `null` to mean \"the latest version\".\n\nAttribute: `active-version-id`","type":"string | null","default":"null"},{"name":"copyText","description":"The text copied to the clipboard by the copy button. Empty hides the button.\n\nAttribute: `copy-text`","type":"string","default":"''"},{"name":"downloadName","description":"The suggested filename reported in the `lr-download` event detail.\n\nAttribute: `download-name`","type":"string","default":"''"},{"name":"downloadSrc","description":"The download URL, sanitized through `safeDownloadHref()` before use. Empty hides the button.\n\nAttribute: `download-src`","type":"string","default":"''"},{"name":"kind","description":"A short kind label (e.g. `document`, `code`), shown as a badge next to `label`.\n\nAttribute: `kind`","type":"string","default":"''"},{"name":"label","description":"The artifact's title, shown in the header. Optional. Omitting it localizes the default\n`artifactPanelLabel` message for the view-toggle group's accessible name (and shows no\nvisible title); an explicit empty string also renders no visible/accessible label.\n\nAttribute: `label`","type":"string | undefined"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"streaming","description":"Whether the artifact is still being generated. Sets `aria-busy` on the body and shows a\ntext indicator instead of an animated one, so it stays legible under reduced motion.\n\nAttribute: `streaming`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"versions","description":"The artifact's version history, oldest first. The last entry is the latest version. Empty/blank\nids are omitted and duplicates normalize first-wins before navigation, counts, and events.","type":"readonly ArtifactVersion[]","default":"[]"},{"name":"view","description":"Which slot is currently visible.\n\nAttribute: `view`  \nReflected to its attribute.","type":"ArtifactPanelView","default":"'preview'"}],"events":[{"name":"lr-copy","description":"`detail: { ok: true, text }`. Fired after the clipboard write fulfills.","type":"CustomEvent<LyraClipboardWriteSuccess>"},{"name":"lr-copy-error","description":"`detail: { ok: false, text, reason, error }` — typed clipboard failure.","type":"CustomEvent<LyraClipboardWriteFailure>"},{"name":"lr-download","description":"`detail: { filename, src }`. Fired with the sanitized download URL.","type":"CustomEvent<{ filename: string; src: string }>"},{"name":"lr-error","description":"The clipboard write failed; generic no-detail notification.","type":"CustomEvent<null>"},{"name":"lr-restore","description":"`detail: { versionId }`. Fired by the restore-this-version button; mutates nothing itself — `versions` and the resulting content stay host-owned state.","type":"CustomEvent<{ versionId: string }>"},{"name":"lr-version-change","description":"`detail: { versionId }`. Fired when the previous/next navigation moves to a different version.","type":"CustomEvent<{ versionId: string }>"},{"name":"lr-view-change","description":"`detail: { view }`. Fired when the preview/code toggle changes.","type":"CustomEvent<{ view: ArtifactPanelView }>"}]}},{"name":"lr-attachment-chip","description":"`<lr-attachment-chip>` — a compact chip representing one file queued for\n(or already part of) a chat message: a composer's pre-send attachment\ntray, or a sent message's `attachments` slot (see `<lr-chat-message>`).\n\nTwo independent ways to populate it, matching the two points in a message's\nlifecycle this is used at:\n - Set `file` to a real `File` (fresh from a picker/drop) — `name`, `bytes`,\n   `mime-type` and the image thumbnail are all auto-derived from it.\n - Set the plain `name`/`bytes`/`mime-type`/`thumbnail-src` props instead,\n   for reconstructing a chip from server-persisted attachment metadata\n   (e.g. after a page reload, when no real `File` object exists any more).\n\n`file` always wins when both are present — see each accessor's own doc.\nThe image thumbnail for a real `File` is a cached `URL.createObjectURL()`\nblob URL, created in the update lifecycle immediately before the thumbnail\nrenders and revoked automatically once `file`\nchanges away from the object it was created for, and on disconnect — this\ncomponent never leaks a blob URL.\n\nIdentifying *which* attachment a `lr-remove`/`lr-retry`/`lr-preview-request` event is about:\nset `attachment-id=\"...\"` when you have a stable server-side attachment identity. The platform\n`id` remains available exclusively for DOM identity and idrefs. When `attachmentId` is unset and\n`file` is set, a stable attachment identity is\nderived from `` `${file.name}:${file.size}:${file.lastModified}` `` — stable\nacross re-renders of the *same* `File` object without requiring the\nconsumer to invent one. When neither is available, a generated internal id\nis used as a last resort so the event always has *some* id.\n\ni18n/locale: complete contextual messages (including filename/percentage\nplacement and punctuation) route through the shared localization registry.\n`removeLabel`/`retryLabel`/`uploadingLabel`/`uploadFailedLabel` remain as\nsimple per-instance copy overrides; use the component's `.strings` map or a\nregistered locale when a translation needs to reorder the interpolated\nvalues. These are plain properties, not slots — this component still\nexposes no slots.\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 chip's root container. |\n| `meta` | Wrapper around the filename and the formatted file size. |\n| `name` | The filename (ellipsis-truncated via CSS; the untruncated name is always available via the native `title` tooltip). |\n| `preview-button` | The preview affordance, rendered when a file or `preview-src` is available. |\n| `progress` | The numeric upload progress bar (`role=\"progressbar\"`), shown only while `status=\"uploading\"` and `progress` is a meaningful (>0) number. |\n| `progress-fill` | The filled portion of `progress`. |\n| `remove-button` | The remove (×) affordance, only rendered while `removable`. |\n| `retry-button` | The retry affordance, only rendered while `status=\"error\"`. |\n| `size` | The human-readable formatted file size, from `bytes` (or the `file`'s own byte count). Hidden when no size is known. |\n| `spinner` | Decorative (`aria-hidden`) indeterminate upload spinner, shown instead of `progress` while `status=\"uploading\"` and `progress` is unset/0; the adjacent status text carries the visible wording, and upload ticks never enter a live region. |\n| `status-text` | The visible text twin of the status accent color — carries uploading/error state in text. Empty/hidden for `pending`/`success`; forced-colors mode retains distinct border patterns for every state. Plain visible text, so it reads normally once a user reaches the chip; the interrupting announcement that a transition *into* `status=\"error\"` makes goes through the shared light-DOM assertive region. |\n| `thumbnail` | The leading image thumbnail / generic file glyph. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-attachment-chip-accent` (default: `var(--lr-color-text-quiet)`) — Accent color used for the status text, spinner, and progress fill. Its private default changes per `status` (`uploading`/`error`/`success`); the public value remains authoritative.\n- `--lr-attachment-chip-bg` (default: `var(--lr-color-surface)`) — Chip background. Its private default changes per `status` to that status's `-quiet` tint; the public value still wins.\n- `--lr-attachment-chip-border` (default: `var(--lr-color-border)`) — Chip border color. Every non-`pending` `status` changes its private default to `transparent`.\n- `--lr-attachment-chip-compact-font-size` (default: `var(--lr-font-size-xs)`) — Font size of `[part=\"base\"]` while `compact`.\n- `--lr-attachment-chip-compact-gap` (default: `var(--lr-size-0-25rem)`) — Gap between the chip's parts while `compact`.\n- `--lr-attachment-chip-compact-padding` (default: `var(--lr-size-0-125rem) var(--lr-space-xs)`) — Padding of `[part=\"base\"]` while `compact`.\n- `--lr-attachment-chip-compact-thumbnail-only-padding` (default: `var(--lr-size-0-125rem)`) — Padding of `[part=\"base\"]` while `compact` and `thumbnail-only` together actually hide `[part=\"meta\"]` (an image-mime attachment only — see `thumbnailOnly`). Reduced from `--lr-attachment-chip-compact-padding` since the lone thumbnail no longer needs inline padding sized for a text row.\n- `--lr-attachment-chip-compact-thumbnail-size` (default: `var(--lr-size-1-75rem)`) — Thumbnail size while `compact`, rethemeable independently of `--lr-icon-button-size`. Retry, preview, and remove actions retain that shared token's minimum hit-area floor.\n- `--lr-attachment-chip-padding` (default: `var(--lr-space-xs) var(--lr-space-s)`) — Padding of `[part=\"base\"]` while `compact` is unset.\n- `--lr-attachment-chip-spinner-duration` (default: `var(--lr-transition-ambient)`) — Duration and easing of one indeterminate upload-spinner rotation. The ambient loop stops under reduced motion.","attributes":[{"name":"attachment-id","description":"Stable action identity. Empty or whitespace-only values use the documented fallback.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"bytes","description":"Type: `number | undefined`"},{"name":"compact","description":"Renders a smaller, borderless pill presentation instead of the default bordered/chrome-heavy\nchip -- for a consumer that wants an icon-only-adjacent, compact attachment affordance (e.g.\na composer's pending-attachment tray) without hand-tuning several `::part()` custom\nproperties individually. `false` (the default) is visually identical to today.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"mime-type","description":"MIME type, used only while `file` is unset.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"name","description":"Filename, used only while `file` is unset.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"preview-src","description":"URL used to preview or download the attachment when `file` is unset.\nA real `File` takes precedence and is previewed through a temporary blob URL.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"previewable","description":"Shows the preview action when a `file` or `preview-src` is available.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"progress","description":"Upload completion, 0-100. Only meaningful while `status=\"uploading\"`;\na value of 0 (the default), `NaN`, or negative falls back to the indeterminate spinner\n(see `hasNumericProgress`); an oversized value clamps to 100 (see `clampedProgress`).\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"removable","description":"Shows the remove (×) button.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"remove-label","description":"Verb used in the remove button's accessible name. For complete control over translated\nword order and punctuation, override the `removeWithContext` message instead.\n\nType: `string | undefined`"},{"name":"retry-label","description":"Verb used in the retry button's accessible name. For complete control over translated word\norder and punctuation, override the `attachmentRetryWithContext` message instead.\n\nType: `string | undefined`"},{"name":"status","description":"Lifecycle state — drives the accent tint and which of `progress`/`spinner`/`retry-button` renders.\nFailures already present on reconnect render silently; new connected failures announce once.\n\nType: `LyraAttachmentUploadStatus`  \nDefault: `'pending'`","value":{"type":["'pending'","'uploading'","'error'","'success'"]}},{"name":"thumbnail-only","description":"When both this and `compact` are set, hides `[part=meta]` (the filename/size text) entirely\nfor an image-mime attachment, leaving only the thumbnail -- for a consumer wanting a\nthumbnail-only density purely through props, with no consumer-side CSS. Has no effect for a\nnon-image chip (there is no thumbnail to fall back to showing on its own) or when `compact` is\nunset. `false` (the default) reproduces today's exact output.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"thumbnail-src","description":"Thumbnail image URL, used only while `file` is unset (a real `File`'s\nthumbnail always comes from a generated object URL instead — see the\nclass doc). Unlike the other independent props this one has no\n`file`-derived equivalent to defer to for a non-image file; it's simply\nrendered whenever present.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"untitled-label","description":"Override for the empty-name fallback shown (and used as the `title` tooltip) when neither\n`file` nor `name` supply a filename -- for i18n/locale. Defaults to `'Untitled file'`,\nreproducing today's exact hardcoded text byte-for-byte.\n\nType: `string | undefined`"},{"name":"upload-failed-label","description":"Visible status text shown for `status=\"error\"`. Override for\ni18n/locale. Defaults to `'Upload failed'`, reproducing today's exact\ntext byte-for-byte.\n\nType: `string | undefined`"},{"name":"uploading-label","description":"Verb used in uploading messages. For complete control over translated word order and\npunctuation, override the `attachmentUploadingWithContext`,\n`attachmentUploadingProgress`, and `attachmentUploadingIndeterminate` messages instead.\n\nType: `string | undefined`"}],"js":{"properties":[{"name":"attachmentId","description":"Stable action identity. Empty or whitespace-only values use the documented fallback.\n\nAttribute: `attachment-id`","type":"string","default":"''"},{"name":"bytes","description":"Attribute: `bytes`","type":"number | undefined"},{"name":"compact","description":"Renders a smaller, borderless pill presentation instead of the default bordered/chrome-heavy\nchip -- for a consumer that wants an icon-only-adjacent, compact attachment affordance (e.g.\na composer's pending-attachment tray) without hand-tuning several `::part()` custom\nproperties individually. `false` (the default) is visually identical to today.\n\nAttribute: `compact`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"file","description":"A real `File`, e.g. fresh from `<lr-file-input>`'s `lr-files` event.\nWhen set, `name`/`bytes`/`mime-type`/the image thumbnail are all derived\nfrom it, taking precedence over the independent props below.","type":"File | undefined"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"mimeType","description":"MIME type, used only while `file` is unset.\n\nAttribute: `mime-type`","type":"string","default":"''"},{"name":"name","description":"Filename, used only while `file` is unset.\n\nAttribute: `name`","type":"string","default":"''"},{"name":"previewSrc","description":"URL used to preview or download the attachment when `file` is unset.\nA real `File` takes precedence and is previewed through a temporary blob URL.\n\nAttribute: `preview-src`","type":"string","default":"''"},{"name":"previewable","description":"Shows the preview action when a `file` or `preview-src` is available.\n\nAttribute: `previewable`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"progress","description":"Upload completion, 0-100. Only meaningful while `status=\"uploading\"`;\na value of 0 (the default), `NaN`, or negative falls back to the indeterminate spinner\n(see `hasNumericProgress`); an oversized value clamps to 100 (see `clampedProgress`).\n\nAttribute: `progress`","type":"number","default":"0"},{"name":"removable","description":"Shows the remove (×) button.\n\nAttribute: `removable`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"removeLabel","description":"Verb used in the remove button's accessible name. For complete control over translated\nword order and punctuation, override the `removeWithContext` message instead.\n\nAttribute: `remove-label`","type":"string | undefined"},{"name":"retryLabel","description":"Verb used in the retry button's accessible name. For complete control over translated word\norder and punctuation, override the `attachmentRetryWithContext` message instead.\n\nAttribute: `retry-label`","type":"string | undefined"},{"name":"status","description":"Lifecycle state — drives the accent tint and which of `progress`/`spinner`/`retry-button` renders.\nFailures already present on reconnect render silently; new connected failures announce once.\n\nAttribute: `status`  \nReflected to its attribute.","type":"LyraAttachmentUploadStatus","default":"'pending'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"thumbnailOnly","description":"When both this and `compact` are set, hides `[part=meta]` (the filename/size text) entirely\nfor an image-mime attachment, leaving only the thumbnail -- for a consumer wanting a\nthumbnail-only density purely through props, with no consumer-side CSS. Has no effect for a\nnon-image chip (there is no thumbnail to fall back to showing on its own) or when `compact` is\nunset. `false` (the default) reproduces today's exact output.\n\nAttribute: `thumbnail-only`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"thumbnailSrc","description":"Thumbnail image URL, used only while `file` is unset (a real `File`'s\nthumbnail always comes from a generated object URL instead — see the\nclass doc). Unlike the other independent props this one has no\n`file`-derived equivalent to defer to for a non-image file; it's simply\nrendered whenever present.\n\nAttribute: `thumbnail-src`","type":"string","default":"''"},{"name":"untitledLabel","description":"Override for the empty-name fallback shown (and used as the `title` tooltip) when neither\n`file` nor `name` supply a filename -- for i18n/locale. Defaults to `'Untitled file'`,\nreproducing today's exact hardcoded text byte-for-byte.\n\nAttribute: `untitled-label`","type":"string | undefined"},{"name":"uploadFailedLabel","description":"Visible status text shown for `status=\"error\"`. Override for\ni18n/locale. Defaults to `'Upload failed'`, reproducing today's exact\ntext byte-for-byte.\n\nAttribute: `upload-failed-label`","type":"string | undefined"},{"name":"uploadingLabel","description":"Verb used in uploading messages. For complete control over translated word order and\npunctuation, override the `attachmentUploadingWithContext`,\n`attachmentUploadingProgress`, and `attachmentUploadingIndeterminate` messages instead.\n\nAttribute: `uploading-label`","type":"string | undefined"}],"events":[{"name":"lr-preview-request","description":"Notification that the preview action was activated. `detail: { attachmentId, name, mimeType, src }`. Not cancelable: the chip never registers or owns a viewer/overlay, so there is nothing local to gate behind `.preventDefault()`; consumers compose the desired preview surface entirely on their own.","type":"CustomEvent<LyraAttachmentPreviewRequestDetail>"},{"name":"lr-remove","description":"The user activated the remove (×) button. `detail: { attachmentId }`. Only rendered while `removable`.","type":"CustomEvent<LyraAttachmentIdDetail>"},{"name":"lr-retry","description":"The user activated the retry button. `detail: { attachmentId }`. Only rendered while `status=\"error\"`.","type":"CustomEvent<LyraAttachmentIdDetail>"}]}},{"name":"lr-attachment-trigger","description":"`<lr-attachment-trigger>` — a compact attach affordance designed for a\nchat composer's start slot (see `<lr-chat-composer>`'s own `start`\nslot, which this drops straight into, though this component has no code\ndependency on it). Its shape adapts to how many attachment `capabilities`\nare configured:\n - Exactly one capability: a single plain icon button ([part='trigger']).\n   Activating it performs that capability's action directly.\n - More than one: a small anchored menu ([part='menu'], composed from\n   `<lr-dropdown>`/`<lr-menu>`/`<lr-menu-item>`) listing each capability as a row.\n\nTwo of the four capabilities (`files`, `image`) are file-picker-backed:\nactivating them opens a hidden native `<input type=\"file\">` via a\nsynthetic `.click()`, and the resulting selection is re-emitted as\n`lr-files`. `accept` is shared across both — `image` defaults it to\n`'image/*'` unless the `accept` prop overrides it, `files` always uses\n`accept` as-is (empty means \"any file type\", matching a bare native\n`<input type=\"file\">` with no `accept` attribute).\n\n**`camera`/`audio` are scope-limited by design.** This component does not\nimplement any camera or microphone capture UI itself — no `getUserMedia`,\nno `<input capture>` — because that's entirely a host/browser concern with\nno single right answer (a desktop web app, a mobile PWA, and a native\nwrapper all want different things here). Activating `camera` fires\n`lr-camera-request`; activating `audio` fires `lr-audio-request`. The\nhost owns everything from that point on — typically opening\n`<lr-push-to-talk>` in a `<lr-overlay>`/popover for `audio`, then\nhanding the resulting blob to something like `<lr-attachment-chip>`.\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| `expand-icon` | The disclosure chevron inside the multi-capability trigger button. Only rendered when `capabilities.length > 1`. |\n| `hidden-input` | The internal native `<input type=\"file\">` that actually opens the OS file picker. Hidden (`display: none`) by default; exposed as a part only so a consumer can override that with `::part(hidden-input)` in the unlikely case their integration needs to. `accessibleLabel` supplies an accessible-name override for either trigger shape. A host `aria-label`, including an explicit empty value, wins over it. |\n| `menu` | The `<lr-dropdown>` shell. Only rendered when `capabilities.length > 1`. |\n| `menu-trigger` | The multi-capability button slotted into `<lr-dropdown>`'s `trigger` slot. Only rendered when `capabilities.length > 1`. |\n| `menu-trigger__control` | The multi-capability action's own native `<button>`, forwarded for the same reason. |\n| `trigger` | The single-capability action, a composed `<lr-icon-button>` as of 16.0.0. Only rendered when `capabilities.length === 1`. It still owns the accessible name, the activation and the `title`; its background, radius, hover/press mixes, focus ring and hit-area floor now come from `--lr-icon-button-*`, retuned by `appearance`/`size`. |\n| `trigger__control` | The single-capability action's own native `<button>`, forwarded because the painted surface sits one shadow boundary deeper than `trigger`. |","attributes":[{"name":"accept","description":"Native-file-input-style accept string (e.g. `'image/*'` or\n`'.pdf,.docx'`), forwarded to the hidden file input for the\n`files`/`image` capabilities — see the class doc for how each uses it.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"accessible-label","description":"Accessible-name override for the semantic trigger button.\n\nType: `string | undefined`"},{"name":"appearance","description":"How the trigger fills itself, from the library's one shared `appearance` vocabulary. The\ndefault `'plain'` is exactly the treatment this component shipped before it had the property:\nno fill, no border, quiet glyph. `'filled'`/`'filled-outlined'` tint it, `'outlined'` bounds\nit, `'accent'` makes it the loud primary affordance in a composer's start slot. Painted\nthrough the composed `<lr-icon-button>`'s own `--lr-icon-button-*` contract, so an ancestor\ntheme wrapper still wins over every tier.\n\nType: `LyraAppearance`  \nDefault: `'plain'`","value":{"type":["'accent'","'filled'","'outlined'","'filled-outlined'","'plain'"]}},{"name":"disabled","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"multiple","description":"Forwarded to the hidden file input's own `multiple` attribute.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"size","description":"Size on the library's shared six-step ladder, accepting the Web Awesome/Shoelace spellings\n(`small`/`medium`/`large`) too so a migration stays a tag rename. The tier scales the GLYPH,\nnever the tappable box: `--lr-icon-button-size` is an accessibility floor, and the ladder's\ntightest tiers resolve below WCAG 2.5.8's minimum, so wiring the target to it would let\n`size=\"2xs\"` ship an untappable control. Override `--lr-icon-button-size` to make that\ntrade-off explicitly, exactly as on a standalone `<lr-icon-button>`.\n\nType: `LyraSize`  \nDefault: `'m'`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}},{"name":"trigger-title","description":"Forwards to the internal trigger button(s)' native `title` attribute — a sighted mouse\nuser's hover tooltip, distinct from `accessibleLabel`'s accessible-name (`aria-label`) role.\nApplies to both the single-capability `[part=trigger]` button and the multi-capability\n`[part=menu-trigger]` button. Unset (the default): no `title` attribute, unchanged from\nbefore this property existed.\n\nType: `string | undefined`"}],"js":{"properties":[{"name":"accept","description":"Native-file-input-style accept string (e.g. `'image/*'` or\n`'.pdf,.docx'`), forwarded to the hidden file input for the\n`files`/`image` capabilities — see the class doc for how each uses it.\n\nAttribute: `accept`","type":"string","default":"''"},{"name":"accessibleLabel","description":"Accessible-name override for the semantic trigger button.\n\nAttribute: `accessible-label`","type":"string | undefined"},{"name":"appearance","description":"How the trigger fills itself, from the library's one shared `appearance` vocabulary. The\ndefault `'plain'` is exactly the treatment this component shipped before it had the property:\nno fill, no border, quiet glyph. `'filled'`/`'filled-outlined'` tint it, `'outlined'` bounds\nit, `'accent'` makes it the loud primary affordance in a composer's start slot. Painted\nthrough the composed `<lr-icon-button>`'s own `--lr-icon-button-*` contract, so an ancestor\ntheme wrapper still wins over every tier.\n\nAttribute: `appearance`  \nReflected to its attribute.","type":"LyraAppearance","default":"'plain'"},{"name":"capabilities","description":"Which attachment capabilities to offer, in display order. Normalization scans at most 64\ncandidates and retains the first four unique recognized values, so duplicates and unknown\nentries do not consume the four-capability output budget. A single retained entry renders a\nplain button; more than one renders a menu.","type":"readonly LyraAttachmentCapability[]","default":"DEFAULT_CAPABILITIES"},{"name":"disabled","description":"Attribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"multiple","description":"Forwarded to the hidden file input's own `multiple` attribute.\n\nAttribute: `multiple`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"size","description":"Size on the library's shared six-step ladder, accepting the Web Awesome/Shoelace spellings\n(`small`/`medium`/`large`) too so a migration stays a tag rename. The tier scales the GLYPH,\nnever the tappable box: `--lr-icon-button-size` is an accessibility floor, and the ladder's\ntightest tiers resolve below WCAG 2.5.8's minimum, so wiring the target to it would let\n`size=\"2xs\"` ship an untappable control. Override `--lr-icon-button-size` to make that\ntrade-off explicitly, exactly as on a standalone `<lr-icon-button>`.\n\nAttribute: `size`  \nReflected to its attribute.","type":"LyraSize","default":"'m'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"triggerTitle","description":"Forwards to the internal trigger button(s)' native `title` attribute — a sighted mouse\nuser's hover tooltip, distinct from `accessibleLabel`'s accessible-name (`aria-label`) role.\nApplies to both the single-capability `[part=trigger]` button and the multi-capability\n`[part=menu-trigger]` button. Unset (the default): no `title` attribute, unchanged from\nbefore this property existed.\n\nAttribute: `trigger-title`","type":"string | undefined"}],"events":[{"name":"blur","description":"Relayed once from the active trigger button as a bubbling, composed native event.","type":"FocusEvent"},{"name":"focus","description":"Relayed once from the active trigger button as a bubbling, composed native event.","type":"FocusEvent"},{"name":"lr-audio-request","description":"The `audio` capability was activated. No detail payload — same request-only scope as `lr-camera-request`; the host implements the actual recording flow (typically `<lr-push-to-talk>`).","type":"CustomEvent<null>"},{"name":"lr-camera-request","description":"The `camera` capability was activated. No detail payload — see the class doc's scope note; the host implements the actual capture flow.","type":"CustomEvent<null>"},{"name":"lr-files","description":"A file-backed capability's hidden file input produced a real selection. `detail: { capability: 'files' | 'image', files }`; `files` is a fresh readonly owner-realm `File[]` snapshot rather than the native input's live `FileList`.","type":"CustomEvent<LyraEventDetailSnapshot<LyraAttachmentFilesDetail>>"}]}},{"name":"lr-audio-visualizer","description":"`<lr-audio-visualizer>` — a presentational, canvas-drawn voice-activity visualization. Its\n`mode` is `\"bars\"` (default) or `\"waveform\"`. Driven by a `MediaStream`\n(lazily wired to a WebAudio `AnalyserNode`), a numeric `level` for hosts that already compute\nlevels (e.g. `lr-push-to-talk`'s `lr-level`), or `state` alone for an ambient animation when no\nreal signal exists. A real signal (`stream` or `level`) always drives amplitude regardless of\n`prefers-reduced-motion` — that is live, user-controlled feedback, not decorative motion; only the\nsignal-less ambient animation is throttled and simplified under reduced motion.\n\nAnimation frames are only scheduled while the drawn output is actually time-varying (live analyser\ndata, or a non-reduced ambient pulse/sweep). Static output — a constant `level`, idle bars, or the\nflattened reduced-motion ambient patterns — draws once and stops; any change that could alter the\nnext frame (properties, stream/`AudioContext` state, size, theme, motion preference) re-enters the\nloop via `scheduleDraw()`. The loop is also paused while the host is scrolled off-screen (an\n`IntersectionObserver`-gated `visible` flag, mirroring `<lr-chart>`'s own `draw()` gating), so a\nlive-signal visualizer buried behind later transcript messages doesn't keep repainting for nobody.\nCanvas-bound theme colors are materialized through a live DOM color probe before drawing, so\n`currentColor`, inherited expressions, and invalid values cannot silently paint as stale black.\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 root wrapper. |\n| `canvas` | The drawing surface (`aria-hidden`; the host itself carries `role=\"img\"` and the accessible name). |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-audio-visualizer-ambient-duration` (default: `var(--lr-duration-ambient)`) — Time-only duration of one signal-less ambient pulse or sweep cycle.\n- `--lr-audio-visualizer-color` (default: `var(--lr-color-brand)`) — Active bar/waveform color.\n- `--lr-audio-visualizer-height` (default: `var(--lr-size-3rem)`) — The host's block size, which the canvas fills at 100%.\n- `--lr-audio-visualizer-quiet-color` (default: `var(--lr-color-brand-border-normal)`) — Inactive/idle color. Chosen over `--lr-color-brand-quiet` for its WCAG 1.4.11 non-text contrast against `--lr-color-surface` (the idle bars have no other distinguishing shape or border).","attributes":[{"name":"bar-count","description":"Type: `number`  \nDefault: `5`","value":{"type":["number"]}},{"name":"gain","description":"Amplitude multiplier applied in `draw()`. NaN/non-finite falls back to `1` via `effectiveGain`.\n\nType: `number`  \nDefault: `1`","value":{"type":["number"]}},{"name":"label","description":"Accessible-name override. Unset (the default) auto-generates \"Voice activity: {state}\".\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"level","description":"Externally-computed amplitude, `[0, 1]`, for a host that already derives its own level\n(e.g. `lr-push-to-talk`'s `lr-level`). `null` (the default) means \"no external signal\" --\nsee `effectiveLevel` for how a non-null value is clamped/NaN-guarded before it feeds `draw()`.\n\nType: `number | null`  \nDefault: `null`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"mode","description":"Drawing vocabulary: discrete `bars` or a continuous `waveform`.\n\nType: `AudioVisualizerMode`","value":{"type":["'bars'","'waveform'"]}},{"name":"state","description":"Type: `AudioVisualizerState`","value":{"type":["'idle'","'listening'","'thinking'","'speaking'"]}}],"js":{"properties":[{"name":"barCount","description":"Attribute: `bar-count`","type":"number","default":"5"},{"name":"gain","description":"Amplitude multiplier applied in `draw()`. NaN/non-finite falls back to `1` via `effectiveGain`.\n\nAttribute: `gain`","type":"number","default":"1"},{"name":"label","description":"Accessible-name override. Unset (the default) auto-generates \"Voice activity: {state}\".\n\nAttribute: `label`","type":"string","default":"''"},{"name":"level","description":"Externally-computed amplitude, `[0, 1]`, for a host that already derives its own level\n(e.g. `lr-push-to-talk`'s `lr-level`). `null` (the default) means \"no external signal\" --\nsee `effectiveLevel` for how a non-null value is clamped/NaN-guarded before it feeds `draw()`.\n\nAttribute: `level`","type":"number | null","default":"null"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"mode","description":"Drawing vocabulary: discrete `bars` or a continuous `waveform`.\n\nAttribute: `mode`  \nReflected to its attribute.","type":"AudioVisualizerMode"},{"name":"state","description":"Attribute: `state`  \nReflected to its attribute.","type":"AudioVisualizerState"},{"name":"stream","type":"MediaStream | null","default":"null"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}]}},{"name":"lr-av-player","description":"`<lr-av-player>` — audio/video player built on a native `<audio>`/`<video>` element, plus a cue\ntranscript synced to `currentTime`, `time-range` anchor/highlight support, an optional\ndependency-free waveform (peaks in, no in-component decoding), and playback-rate control. Owns\nrecorded-media transcript sync; distinct from `<lr-transcript-feed>` (live captions for an\nin-progress voice session) and `<lr-sequence-playback>` (an index stepper over\n`[0, itemCount)` for\ntime-series dashboards — no media involved in either).\n\nAdopts `DocumentAnchorTarget` with `anchorKinds: ['time-range']` only. No text selection is bound:\ntranscript rows render inside `<lr-virtual-list>`'s own nested shadow root, one boundary deeper\nthan the mixin's default selection lookup resolves.\n\nThe transcript virtualizes through `<lr-virtual-list>` the same way `pdf-viewer.class.ts`\nvirtualizes pages: `items`/`renderItem`/`keyFunction`/`activeItemId` props. Playback follows its\nactive cue through `activeItemId`; search navigation reveals its active match through the list's\n`scrollToIndex()` API without seeking the media.\nAn authored host `aria-label` remains the aggregate name on the host. Otherwise a nonempty\n`name` labels `[part=\"base\"]` as a region. The native media element keeps the distinct localized\nplayer-purpose label, avoiding duplicate semantic owners; a bare loaded player uses the native\nmedia element as its sole named owner.\n\n**RTL behavior:** surrounding controls stay logical, but `[part=\"timeline\"]` is a physical\nelapsed-time axis and remains left-to-right under `dir=\"rtl\"`. ArrowLeft rewinds and ArrowRight\nadvances in both text directions.\n\nWaveform canvas painting is visibility-gated: peak, theme, and resize changes while the player\nis off-screen stay dirty and coalesce into one paint on re-entry. Environments without\n`IntersectionObserver` retain eager painting.\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| `anchor-live-region` | The aria-hidden, non-live shadow mirror of the latest anchor-jump message. |\n| `base` | The root wrapper. |\n| `cue` | One transcript row (`aria-current`, `data-match`, `data-active-match`). |\n| `cue-active-match` | Added alongside `cue`/`cue-match` on the row holding the current search match. |\n| `cue-current` | Added alongside `cue` on the row the playhead is inside. A second part name rather than an attribute selector, because Shadow Parts forbids an attribute selector after `::part()`. |\n| `cue-match` | Added alongside `cue` on every row matching the current search query. |\n| `cue-speaker` | A cue's speaker label. |\n| `cue-text` | A cue's text. |\n| `cue-time` | A cue's timestamp label. |\n| `error` | Ordinary visible failure text. Fresh post-mount media/source failures append the localized message to the shared light-DOM assertive announcement sink; an already-unsafe initial `src` renders visibly without interrupting on mount. |\n| `media` | The native `<audio>`/`<video>` element. |\n| `rate-select` | The playback-rate `<select>`. |\n| `timeline` | The waveform canvas or plain seek rail; click-to-seek and arrow-key seeking. It is disabled and removed from sequential focus until duration is positive. |\n| `timeline-marker` | One clickable marker per `time-range` highlight (`data-tone`, `data-active`). |\n| `toolbar` | The playback-rate control row. |\n| `transcript` | The virtualized cue list (`<lr-virtual-list>` itself). |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-av-player-transcript-height` (default: `var(--lr-size-16rem)`) — Block size of the virtualized transcript list.\n- `--lr-av-player-marker-active-color` (default: `var(--lr-color-brand)`) — Outline color of the `[part=\"timeline-marker\"]` matching `activeHighlightId`.\n- `--lr-av-player-marker-bg` (default: `color-mix(in srgb, var(--lr-color-brand) 35%, transparent)`) — Background of a `[part=\"timeline-marker\"]` with no (or an unrecognized) `data-tone`.\n- `--lr-av-player-marker-success-bg` (default: `color-mix(in srgb, var(--lr-color-success) 35%, transparent)`) — Background of a `[part=\"timeline-marker\"][data-tone=\"success\"]`.\n- `--lr-av-player-marker-warning-bg` (default: `color-mix(in srgb, var(--lr-color-warning) 35%, transparent)`) — Background of a `[part=\"timeline-marker\"][data-tone=\"warning\"]`.\n- `--lr-av-player-marker-danger-bg` (default: `color-mix(in srgb, var(--lr-color-danger) 35%, transparent)`) — Background of a `[part=\"timeline-marker\"][data-tone=\"danger\"]`.\n- `--lr-av-player-marker-neutral-bg` (default: `color-mix(in srgb, var(--lr-color-text) 25%, transparent)`) — Background of a `[part=\"timeline-marker\"][data-tone=\"neutral\"]`.\n- `--lr-av-player-marker-fill` — The resting fill a `[part=\"timeline-marker\"]` actually renders, resolved per tone from the `--lr-av-player-marker-*-bg` knobs above. Its hover and pressed states are colour mixes taken from this value, so setting it directly retints all three at once for one marker; retint a whole tone through the `-bg` knob instead.\n- `--lr-av-player-cue-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Background of a hovered `[part=\"cue\"]`. The pressed state mixes further from this same value rather than a separate knob, so retuning it keeps its pressed step too.\n- `--lr-av-player-cue-current-bg` (default: `var(--lr-color-brand-quiet)`) — Background of the `[part=\"cue\"]` the playhead is currently inside.\n- `--lr-av-player-cue-active-match-color` (default: `var(--lr-color-warning)`) — Outline color of the `[part=\"cue\"]` holding the current search match, leaving the other matches' dashed outline on the shared warning token.","attributes":[{"name":"active-highlight-id","description":"Id of the currently active highlight, or null when none is active.\n\nType: `string | null`  \nDefault: `null`"},{"name":"kind","description":"Forces exact `audio`/`video` rendering, overriding the `mime-type`-based auto-detection.\nUnrecognized runtime or attribute values continue MIME auto-detection.\n\nType: `LyraAvKind | undefined`","value":{"type":["'audio'","'video'"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"loop","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"mime-type","description":"Drives auto-detection: an `audio/*` mime type renders `<audio>`; anything else renders\n`<video>`. Ignored once `kind` is set explicitly. Attribute removal is consumed as an absent hint.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"muted","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"name","description":"Accessible name of the stable `[part=\"base\"]` region and of the native `[part=\"media\"]`\nelement (the actual keyboard tab stop, which would otherwise be nameless); a host\n`aria-label` wins, then the localized `avPlayerLabel` fallback.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"playback-rate","description":"Playback-rate multiplier, reflected to the native media element. Clamped to\n`[MIN_PLAYBACK_RATE, MAX_PLAYBACK_RATE]` -- a non-finite or wildly out-of-range assignment\n(e.g. a bad computed value) self-heals rather than reaching `HTMLMediaElement.playbackRate`\nunsanitized.\n\nType: `number`","value":{"type":["number"]}},{"name":"poster","description":"Poster image for `<video>`; validated with `safeMediaSrc` and omitted when unsafe. Ignored for\n`<audio>`.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"preload","description":"Type: `LyraAvPreload`  \nDefault: `'metadata'`","value":{"type":["'none'","'metadata'","'auto'"]}},{"name":"src","description":"Media URL; validated with `safeMediaSrc` before it ever reaches the `<audio>`/`<video>` `src`.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"volume","description":"Native volume on the canonical `0..1` scale. Native `volumechange` updates this property, and\ndirect property writes update the current media generation without feedback duplicates.\n\nType: `number`","value":{"type":["number"]}}],"js":{"properties":[{"name":"activeHighlightId","description":"Id of the currently active highlight, or null when none is active.\n\nAttribute: `active-highlight-id`","type":"string | null","default":"null"},{"name":"anchor","description":"Anchor or highlight id to resolve and scroll into view.","type":"LyraAnchor | string | null","default":"null"},{"name":"anchorKinds","description":"From `DocumentAnchorTarget` — only `time-range` anchors resolve here.","type":"readonly LyraAnchorKind[]","default":"['time-range']","read-only":true},{"name":"cues","description":"Transcript entries, rendered as a virtualized, `currentTime`-synced list. Valid nonempty\n`cueId` values are unique; the first occurrence wins. Inputs are bounded, cloned, and frozen.\nOmitted ends use indexed next chronological starts; seeks reconcile in linear work.","type":"readonly LyraAvCue[]"},{"name":"currentTime","description":"Live playback position: the media element's own `currentTime` once mounted, else the last\nlocally-tracked value (e.g. a `seek()` issued before metadata loaded).","type":"number"},{"name":"highlights","description":"Highlights rendered by the document target. Reassign after mutation.","type":"LyraHighlight[]","default":"[]"},{"name":"kind","description":"Forces exact `audio`/`video` rendering, overriding the `mime-type`-based auto-detection.\nUnrecognized runtime or attribute values continue MIME auto-detection.\n\nAttribute: `kind`","type":"LyraAvKind | undefined"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"loop","description":"Attribute: `loop`","type":"boolean","default":"false"},{"name":"mimeType","description":"Drives auto-detection: an `audio/*` mime type renders `<audio>`; anything else renders\n`<video>`. Ignored once `kind` is set explicitly. Attribute removal is consumed as an absent hint.\n\nAttribute: `mime-type`","type":"string","default":"''"},{"name":"muted","description":"Attribute: `muted`","type":"boolean","default":"false"},{"name":"name","description":"Accessible name of the stable `[part=\"base\"]` region and of the native `[part=\"media\"]`\nelement (the actual keyboard tab stop, which would otherwise be nameless); a host\n`aria-label` wins, then the localized `avPlayerLabel` fallback.\n\nAttribute: `name`","type":"string","default":"''"},{"name":"peaks","description":"Normalized `0..1` waveform amplitude samples. Empty renders a plain seek rail instead of a\ncanvas -- this component never decodes audio itself.","type":"readonly number[]"},{"name":"playbackRate","description":"Playback-rate multiplier, reflected to the native media element. Clamped to\n`[MIN_PLAYBACK_RATE, MAX_PLAYBACK_RATE]` -- a non-finite or wildly out-of-range assignment\n(e.g. a bad computed value) self-heals rather than reaching `HTMLMediaElement.playbackRate`\nunsanitized.\n\nAttribute: `playback-rate`  \nReflected to its attribute.","type":"number"},{"name":"poster","description":"Poster image for `<video>`; validated with `safeMediaSrc` and omitted when unsafe. Ignored for\n`<audio>`.\n\nAttribute: `poster`","type":"string","default":"''"},{"name":"preload","description":"Attribute: `preload`","type":"LyraAvPreload","default":"'metadata'"},{"name":"rates","description":"Selectable rates offered by `[part=\"rate-select\"]`; snapshotted, deduplicated, bounded to 32.","type":"readonly number[]"},{"name":"src","description":"Media URL; validated with `safeMediaSrc` before it ever reaches the `<audio>`/`<video>` `src`.\n\nAttribute: `src`","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"tracks","description":"Native `<track>` sources (subtitles/captions/descriptions), bounded and snapshotted.","type":"readonly LyraAvTrack[]"},{"name":"volume","description":"Native volume on the canonical `0..1` scale. Native `volumechange` updates this property, and\ndirect property writes update the current media generation without feedback duplicates.\n\nAttribute: `volume`  \nReflected to its attribute.","type":"number"}],"events":[{"name":"blur","description":"Relayed once from the native media element as a bubbling, composed native event.","type":"FocusEvent"},{"name":"ended","description":"Relayed native media event; non-bubbling and non-composed.","type":"Event"},{"name":"error","description":"Relayed native media event; non-bubbling and non-composed. The localized `lr-render-error` notification additionally carries the underlying failure detail.","type":"Event"},{"name":"focus","description":"Relayed once from the native media element as a bubbling, composed native event.","type":"FocusEvent"},{"name":"loadedmetadata","description":"Relayed native media event; non-bubbling and non-composed.","type":"Event"},{"name":"lr-anchor-result","description":"Fired after `anchor` (or a `scrollToAnchor()` call) is applied. `detail: { found }`.","type":"CustomEvent<AnchorResultDetail>"},{"name":"lr-cue-change","description":"The active transcript cue changed. `detail: { cueId, index }` (`cueId:null,index:-1` when none is active).","type":"CustomEvent<LyraAvCueChangeDetail>"},{"name":"lr-highlight-activate","description":"A `time-range` highlight marker was activated. `detail: { highlightId }`.","type":"CustomEvent<HighlightActivateDetail>"},{"name":"lr-load","description":"Media metadata finished loading. `detail: { duration, kind }`.","type":"CustomEvent<{ duration: number; kind: LyraAvKind }>"},{"name":"lr-pause","description":"Playback paused.","type":"CustomEvent<null>"},{"name":"lr-play","description":"Playback started.","type":"CustomEvent<null>"},{"name":"lr-rate-change","description":"`detail: { rate }`.","type":"CustomEvent<{ rate: number }>"},{"name":"lr-render-error","description":"Native media failure, unsafe-source rejection, or an internal playback rejection. `detail: { error }`; native `MediaError` identity is preserved.","type":"CustomEvent<{ error: unknown }>"},{"name":"lr-search-change","description":"Fired from `search()`/`searchNext()`/`searchPrevious()`/ `clearSearch()`. `detail: { query, matchCount, matchCountExact, activeIndex }`. `matchCountExact` is always `true`: `search()` matches over the already-loaded `cues` array with no additional ceiling.","type":"CustomEvent<LyraSearchChangeDetail>"},{"name":"lr-time-change","description":"`detail: { currentTime }`, throttled to at most 4/s while playing, plus one extra emission per `seek()` regardless of the throttle window.","type":"CustomEvent<{ currentTime: number }>"},{"name":"pause","description":"Relayed native media event; non-bubbling and non-composed.","type":"Event"},{"name":"play","description":"Relayed native media event; non-bubbling and non-composed.","type":"Event"},{"name":"timeupdate","description":"Relayed native media event; non-bubbling and non-composed.","type":"Event"},{"name":"volumechange","description":"Relayed native media event; non-bubbling and non-composed.","type":"Event"}]}},{"name":"lr-avatar","description":"`<lr-avatar>` — a small, fixed-size identity marker: an image, an `icon`-slotted fallback\nglyph, or an initials fallback, in that priority order. Mirrors `wa-avatar`'s public surface\n(`image`/`initials`/`loading`/`shape`, the `icon` slot, the image-load error event) and adds\nthis library's own `size`/`variant` vocabulary. Purely presentational, no built-in interactivity;\na consumer wraps it in their own `<button>`/`<lr-menu>` trigger for a user-menu affordance.\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| `icon` | A fallback glyph shown only when there is no loadable `image` — the same role `wa-avatar`'s `icon` slot fills, i.e. a stand-in for the `initials` text rather than an override of the photo. Also decorative (`aria-hidden`), so set `label` alongside it. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The outer circle/rounded/square container. |\n| `icon` | Wrapper around the named icon fallback while it has assigned content and no image is currently usable. |\n| `image` | The `<img>`, only rendered while `image` is set and has not failed to load (and is safe for a media source). |\n| `initials` | The initials text, only rendered once the image and icon fallbacks ahead of it in the priority order have been ruled out. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-avatar-bg` (default: `var(--lr-color-border)`) — Container background. Each non-neutral `variant` changes its private default to that variant's `-quiet` tint.\n- `--lr-avatar-color` (default: `var(--lr-color-text)`) — Initials/glyph color. Each non-neutral `variant` changes its private default to that variant's loud color.\n- `--lr-avatar-font-size` (default: `var(--lr-font-size-m)`) — Font size of the initials fallback (and of any `em`-sized slotted glyph). `size` steps its private default alongside the diameter, so the initials track the circle instead of staying at one fixed size across every tier.\n- `--lr-avatar-size` (default: `var(--lr-size-3rem)`) — Inline and block size of the container. `size` steps its private default across the shared six-step ladder, from `var(--lr-size-1-5rem)` (`2xs`) to `var(--lr-size-5rem)` (`xl`); an inherited or direct public value still wins.\n- `--size` (default: `var(--lr-avatar-size)`) — Upstream-compatible avatar diameter.","attributes":[{"name":"image","description":"Image URL. Takes priority over the `icon` slot and `initials` when set and loads successfully\nand falls back to them on a load error. Named\n`image` to match `wa-avatar`; it used to be `src`, which a mechanical rename left unset —\nsilently falling back to initials.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"initials","description":"Fallback text (typically 1-2 characters) shown when no glyph and no image is set, or the\nimage fails to load and no `icon` slot content is provided.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"label","description":"Accessible description matching the upstream avatar contract. A host `aria-label` wins.\nAttribute removal is consumed as an absent label without changing its null readback.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"loading","description":"Native `<img loading>` passthrough. `'lazy'` defers the request until the avatar approaches\nthe viewport — worth setting for avatars far down a long list, never for one above the fold.\n\nType: `LyraAvatarLoading`  \nDefault: `'eager'`","value":{"type":["'eager'","'lazy'"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"shape","description":"`'circle'` (the default), `'rounded'` (the shared medium corner radius), or `'square'` (no\ncorner radius at all).\n\nType: `LyraAvatarShape`  \nDefault: `'circle'`","value":{"type":["'circle'","'rounded'","'square'"]}},{"name":"size","description":"Visual size, on the shared six-step ladder. `'large'`/`'l'` matches `--lr-icon-button-size`\n(4rem); `'medium'`/`'m'` (the default) is the mirrored 3rem diameter.\n\nType: `LyraSize`  \nDefault: `'medium'`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}},{"name":"variant","description":"Recolors the initials-fallback background/text, on the library's shared `variant` vocabulary.\n`'neutral'` (the default) reads as a plain, unaccented circle.\n\nType: `LyraVariant`  \nDefault: `'neutral'`","value":{"type":["'neutral'","'brand'","'success'","'warning'","'danger'"]}}],"slots":[{"name":"icon","description":"A fallback glyph shown only when there is no loadable `image` — the same role `wa-avatar`'s `icon` slot fills, i.e. a stand-in for the `initials` text rather than an override of the photo. Also decorative (`aria-hidden`), so set `label` alongside it."}],"js":{"properties":[{"name":"image","description":"Image URL. Takes priority over the `icon` slot and `initials` when set and loads successfully\nand falls back to them on a load error. Named\n`image` to match `wa-avatar`; it used to be `src`, which a mechanical rename left unset —\nsilently falling back to initials.\n\nAttribute: `image`","type":"string","default":"''"},{"name":"initials","description":"Fallback text (typically 1-2 characters) shown when no glyph and no image is set, or the\nimage fails to load and no `icon` slot content is provided.\n\nAttribute: `initials`","type":"string","default":"''"},{"name":"label","description":"Accessible description matching the upstream avatar contract. A host `aria-label` wins.\nAttribute removal is consumed as an absent label without changing its null readback.\n\nAttribute: `label`","type":"string","default":"''"},{"name":"loading","description":"Native `<img loading>` passthrough. `'lazy'` defers the request until the avatar approaches\nthe viewport — worth setting for avatars far down a long list, never for one above the fold.\n\nAttribute: `loading`","type":"LyraAvatarLoading","default":"'eager'"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"shape","description":"`'circle'` (the default), `'rounded'` (the shared medium corner radius), or `'square'` (no\ncorner radius at all).\n\nAttribute: `shape`  \nReflected to its attribute.","type":"LyraAvatarShape","default":"'circle'"},{"name":"size","description":"Visual size, on the shared six-step ladder. `'large'`/`'l'` matches `--lr-icon-button-size`\n(4rem); `'medium'`/`'m'` (the default) is the mirrored 3rem diameter.\n\nAttribute: `size`  \nReflected to its attribute.","type":"LyraSize","default":"'medium'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"variant","description":"Recolors the initials-fallback background/text, on the library's shared `variant` vocabulary.\n`'neutral'` (the default) reads as a plain, unaccented circle.\n\nAttribute: `variant`  \nReflected to its attribute.","type":"LyraVariant","default":"'neutral'"}],"events":[{"name":"lr-error","description":"The image failed to load. `detail: { image }` carries the URL that failed, so a consumer can retry or report it; the avatar itself has already fallen back to the `icon` slot or the initials by the time this fires. Never fires when no `image` is set.","type":"CustomEvent<LyraAvatarErrorDetail>"}]}},{"name":"lr-avatar-group","description":"`<lr-avatar-group>` — stacks a set of slotted `<lr-avatar>` children into a single\noverlapping row (negative-margin overlap, ring border so each circle reads as distinct) and,\npast a configurable `max` count, collapses the excess into a \"+N\" overflow badge. First-party\ninvention (no Web Awesome equivalent), composed over `<lr-avatar>` rather than reimplementing\nit — plain light-DOM slotted content is the group's items, the same shape `<lr-multi-split>`'s\npanels / `<lr-source-list>`'s cards / `<lr-chip-group>`'s chips already use, not a\n`.items` array prop.\n\n`size`/`shape`/`variant` provide defaults to assigned avatars that omit the corresponding\nattribute. Explicit child attributes always win; group-owned defaults are removed on disconnect\nor removal without overwriting later author writes.\n\n**Deliberate divergence from `<lr-chip-group>`'s overflow pattern.** Chip-group's overflow\nindicator is a disclosure toggle that reveals the excess children in place (`aria-expanded`,\na \"Show less\" relabel). This component's overflow badge does not do that — unstacking N more\ncircles back into the row would defeat the entire point of a compact identity stack. Instead,\n`lr-overflow-click` is a pure notification hook: the component keeps rendering the same\ncollapsed stack + badge regardless of whether anyone listens, and a consumer typically wires\nthe event to open their own popover/dialog/tooltip listing the hidden members (out of scope for\nthis component — no popover dependency is introduced here). There is no `expanded` state, no\n`aria-expanded`, and the badge never changes its own text/label on click.\n\n**No roving-tabindex / arrow-key composite-widget behavior applies here, and this is\nintentional, not an oversight.** Avatars are non-interactive per `<lr-avatar>`'s own\nestablished contract (purely presentational, no built-in interactivity), so this is not a\nlistbox/toolbar/grid needing `ArrowLeft`/`ArrowRight` roving focus — the overflow badge is the\nonly interactive element, and as a native `<button>` it's automatically part of the normal Tab\nsequence with no custom keyboard handling required.\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) | Direct or forwarded `<lr-avatar>` elements. Other assigned elements are ignored and remain untouched. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The outer inline-flex container (holds the slot and the overflow badge). |\n| `overflow-badge` | The \"+N\" button. Only rendered while `max` is actively causing an overflow. |\n| `overflow-badge-visual` | The avatar-sized painted disc inside the 40px action surface. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-avatar-group-avatar-size` (default: `var(--lr-size-3rem)`) — Sizes the overflow badge to match the slotted avatars, tier for tier with `<lr-avatar>`'s own `--lr-avatar-size`.\n- `--lr-avatar-group-badge-bg` (default: `var(--lr-color-border)`) — Overflow badge background. Its private default follows `variant`; the public value remains authoritative.\n- `--lr-avatar-group-badge-color` (default: `var(--lr-color-text)`) — Overflow badge text color. Its private default follows `variant`; the public value remains authoritative.\n- `--lr-avatar-group-badge-font-size` (default: `var(--lr-font-size-m)`) — Font size of the \"+N\" badge label. `size` steps its private default across the same six-step ladder as `<lr-avatar>`'s own `--lr-avatar-font-size`, so the badge and the avatars it caps read at the same optical weight.\n- `--lr-avatar-group-overlap` (default: `var(--lr-size-neg-6px)`) — Horizontal overlap between consecutive avatars (a logical `margin-inline-start`, so it auto-mirrors under `dir=\"rtl\"`). Setting this to `0` or a positive length is a supported escape hatch that turns the stack into normal, non-overlapping spacing.\n- `--lr-avatar-group-ring-color` (default: `var(--lr-color-surface)`) — The cutout-style ring drawn around every avatar and the overflow badge.\n- `--lr-avatar-group-ring-width` (default: `var(--lr-border-width-medium)`) — Ring thickness.","attributes":[{"name":"label","description":"The group's own accessible name (`role=\"group\"`'s `aria-label`). A host-level `aria-label`\nwins if both are set. Unset (the default) renders no `aria-label` at all — a screen reader\nannounces \"group\" with no name, then reads each avatar's own accessible name in turn.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max","description":"Maximum number of assigned children shown before the rest collapse behind a \"+N\" badge.\nFlattened slot-forwarded children count the same as direct light-DOM children. Unset (the\ndefault) means no limit — every child is always shown. Any explicitly assigned value is\nsanitized to a finite, non-negative integer via `finiteCount` — this feeds the\n`hasOverflow`/`syncChildVisibility`/`onOverflowClick` index math below directly, so a\nNaN/negative value must never reach it.\n\nType: `number | undefined`"},{"name":"shape","description":"`'circle'` (the default), `'rounded'`, or `'square'`. Also provides the default to assigned\navatars that omit their own `shape`.\n\nType: `LyraAvatarShape`  \nDefault: `'circle'`","value":{"type":["'circle'","'rounded'","'square'"]}},{"name":"size","description":"Shared size default for the badge and avatars that omit their own `size`.\n\nType: `LyraSize`  \nDefault: `'medium'`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}},{"name":"variant","description":"Recolors the overflow badge and defaults avatars that omit their own `variant`.\n`'neutral'` (the default) reads as a plain, unaccented badge.\n\nType: `LyraVariant`  \nDefault: `'neutral'`","value":{"type":["'neutral'","'brand'","'success'","'warning'","'danger'"]}}],"slots":[{"name":"","description":"Direct or forwarded `<lr-avatar>` elements. Other assigned elements are ignored and remain untouched."}],"js":{"properties":[{"name":"label","description":"The group's own accessible name (`role=\"group\"`'s `aria-label`). A host-level `aria-label`\nwins if both are set. Unset (the default) renders no `aria-label` at all — a screen reader\nannounces \"group\" with no name, then reads each avatar's own accessible name in turn.\n\nAttribute: `label`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"max","description":"Maximum number of assigned children shown before the rest collapse behind a \"+N\" badge.\nFlattened slot-forwarded children count the same as direct light-DOM children. Unset (the\ndefault) means no limit — every child is always shown. Any explicitly assigned value is\nsanitized to a finite, non-negative integer via `finiteCount` — this feeds the\n`hasOverflow`/`syncChildVisibility`/`onOverflowClick` index math below directly, so a\nNaN/negative value must never reach it.\n\nAttribute: `max`","type":"number | undefined"},{"name":"shape","description":"`'circle'` (the default), `'rounded'`, or `'square'`. Also provides the default to assigned\navatars that omit their own `shape`.\n\nAttribute: `shape`  \nReflected to its attribute.","type":"LyraAvatarShape","default":"'circle'"},{"name":"size","description":"Shared size default for the badge and avatars that omit their own `size`.\n\nAttribute: `size`  \nReflected to its attribute.","type":"LyraSize","default":"'medium'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"variant","description":"Recolors the overflow badge and defaults avatars that omit their own `variant`.\n`'neutral'` (the default) reads as a plain, unaccented badge.\n\nAttribute: `variant`  \nReflected to its attribute.","type":"LyraVariant","default":"'neutral'"}],"events":[{"name":"lr-overflow-click","description":"The overflow badge was activated (click, or Enter/Space while focused — native `<button>` behavior). `detail: { hiddenCount, hiddenAvatars }` where `hiddenAvatars` is a fresh readonly snapshot of eligible avatars hidden past `max`. Non-cancelable — informational hook, no default action to veto.","type":"CustomEvent<LyraAvatarGroupOverflowDetail>"}]}},{"name":"lr-badge","description":"`<lr-badge>` — a compact status label.\n\nTwo independent visual axes: `variant` picks the semantic palette (neutral through danger, read\nfrom the library's shared semantic grid), and `appearance` decides how much of that palette\nlands on the fill, the border, and the text. `variant=\"neutral\"` deliberately opts out of the\ngrid's own neutral row and keeps the ambient surface/border/text treatment, so a badge with no\nstatus to signal reads as plain rather than grey-tinted.\n`pill` switches the rounded rectangle for fully-rounded ends, and `attention` adds an opt-in,\nreduced-motion-aware animation for a badge that has to be noticed.\nBadge content is static by default, matching both mirrored upstreams. Authors whose badge holds\ngenuinely changing status text can opt into live-region semantics with `role=\"status\"`; any\nauthored role is preserved. `<lr-tag>` inherits the same visual and author-owned semantic\ncontract.\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) | Badge content. |\n| `end` | Content placed after the label, typically an icon. The wrapper collapses entirely (no stray gap) while empty. Mark purely decorative content `aria-hidden`. |\n| `start` | Content placed before the label, typically an icon. The wrapper collapses entirely (no stray gap) while empty. Mark purely decorative content `aria-hidden`. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `badge` | The badge surface. It is the same node as `base`. |\n| `base` | Compatibility name for the badge surface; use `badge`. |\n| `content` | Wrapper around the default slot; the part that truncates with an ellipsis. |\n| `end` | Wrapper around the `end` slot. Hidden entirely while empty. |\n| `start` | Wrapper around the `start` slot. Hidden entirely while empty. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-badge-attention-duration` (default: `var(--lr-duration-ambient)`) — One cycle of the `attention` animation.\n- `--lr-badge-attention-easing` (default: `var(--lr-easing-emphasized)`) — Timing function of the `attention` animation.\n- `--lr-badge-background` (default: `var(--lr-badge-fill)`) — Explicit override for the badge's background, winning over whatever `variant` and `appearance` resolved. Left unset (the default) so it still inherits from a consumer's own ancestor rule.\n- `--lr-badge-border` (default: `var(--lr-badge-stroke)`) — Explicit override for the badge's border color, on the same terms as `--lr-badge-background`.\n- `--lr-badge-bounce-distance` (default: `var(--lr-size-0-1875rem)`) — Peak travel of the `attention=\"bounce\"` hop.\n- `--lr-badge-color` (default: `var(--lr-badge-text)`) — Explicit override for the badge's text color, on the same terms as `--lr-badge-background`.\n- `--lr-badge-edge` (default: `var(--lr-color-border)`) — Palette slot: the variant's border color. Its private default follows each non-neutral `variant`'s loud fill; an inherited or direct public value remains authoritative.\n- `--lr-badge-fill` (default: `var(--lr-badge-tint)`) — Surface slot: which palette entry `appearance` routed onto the background. Set it to retune a single appearance without touching the palette.\n- `--lr-badge-font-size` (default: `var(--lr-font-size-sm)`) — The badge's label font size. Each `size` sets it to that step's font size.\n- `--lr-badge-gap` (default: `var(--lr-space-2xs)`) — Space between the `start` slot, the label, and the `end` slot.\n- `--lr-badge-ink` (default: `var(--lr-color-text)`) — Palette slot: the variant's text color. Its private default follows each non-neutral `variant`'s loud fill; an inherited or direct public value remains authoritative.\n- `--lr-badge-min-height` (default: `var(--lr-size-1-25rem)`) — The badge's minimum block size. Each `size` sets it to that step's minimum block size.\n- `--lr-badge-on-solid` (default: `var(--lr-color-on-loud)`) — Palette slot: the text color that stays legible on `--lr-badge-solid`.\n- `--lr-badge-padding-inline` (default: `var(--lr-space-s)`) — The badge's inline padding. Each `size` sets it to that step's inline padding.\n- `--lr-badge-pulse-color` (default: `color-mix(in srgb, currentColor 40%, transparent)`) — Color of the expanding ring drawn by `attention=\"pulse\"`.\n- `--lr-badge-pulse-spread` (default: `var(--lr-size-0-25rem)`) — How far the `attention=\"pulse\"` ring expands.\n- `--lr-badge-radius` (default: `var(--lr-radius)`) — Corner radius of the badge surface. `pill` raises it to `var(--lr-radius-pill)`. Does not vary by `size` tier.\n- `--lr-badge-solid` (default: `var(--lr-color-fill-loud)`) — Palette slot: the variant's loud fill, used by `appearance=\"accent\"`.\n- `--lr-badge-stroke` (default: `var(--lr-badge-edge)`) — Surface slot: which palette entry `appearance` routed onto the border color.\n- `--lr-badge-text` (default: `var(--lr-badge-ink)`) — Surface slot: which palette entry `appearance` routed onto the label color.\n- `--lr-badge-tint` (default: `var(--lr-color-surface)`) — Palette slot: the variant's quiet fill. Its private default follows each non-neutral `variant`'s quiet fill from the shared semantic grid; an inherited or direct public value remains authoritative.\n- `--pulse-color` (default: `var(--lr-badge-pulse-color)`) — Upstream-compatible pulse-ring color.","attributes":[{"name":"appearance","description":"How much of the `variant` palette is spent on fill, border, and text. The default\n(`filled-outlined`: quiet tint, loud border, loud text) reproduces the badge's original\ntreatment.\n\nType: `BadgeAppearance`  \nDefault: `'filled-outlined'`","value":{"type":["'accent'","'filled'","'outlined'","'filled-outlined'","'plain'"]}},{"name":"attention","description":"Opt-in attention-seeking animation. An explicit `'none'` suppresses the `pulse` shorthand.\nStops entirely under `prefers-reduced-motion: reduce`.\n\nType: `BadgeAttention`  \nDefault: `'none'`","value":{"type":["'none'","'pulse'","'bounce'"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"pill","description":"Draws fully-rounded ends instead of the default rounded rectangle.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"pulse","description":"Upstream-compatible pulse shorthand. Equivalent to `attention=\"pulse\"` only while the\n`attention` attribute is omitted; every explicit attention value takes precedence.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"size","description":"Visual density, matching `<lr-chip>`'s `3xs`–`xl` size scale. `m` preserves the original\nbadge dimensions. Valid `small`/`medium`/`large` values round-trip exactly.\n\nType: `BadgeSize`  \nDefault: `'m'`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}},{"name":"variant","description":"Semantic palette. Every valid upstream spelling remains observable verbatim; rendering uses\nthe private canonical value instead of rewriting the public property or reflected attribute.\n\nType: `BadgeVariant`  \nDefault: `'neutral'`","value":{"type":["'neutral'","'brand'","'success'","'warning'","'danger'","'primary'"]}}],"slots":[{"name":"","description":"Badge content."},{"name":"end","description":"Content placed after the label, typically an icon. The wrapper collapses entirely (no stray gap) while empty. Mark purely decorative content `aria-hidden`."},{"name":"start","description":"Content placed before the label, typically an icon. The wrapper collapses entirely (no stray gap) while empty. Mark purely decorative content `aria-hidden`."}],"js":{"properties":[{"name":"appearance","description":"How much of the `variant` palette is spent on fill, border, and text. The default\n(`filled-outlined`: quiet tint, loud border, loud text) reproduces the badge's original\ntreatment.\n\nAttribute: `appearance`  \nReflected to its attribute.","type":"BadgeAppearance","default":"'filled-outlined'"},{"name":"attention","description":"Opt-in attention-seeking animation. An explicit `'none'` suppresses the `pulse` shorthand.\nStops entirely under `prefers-reduced-motion: reduce`.\n\nAttribute: `attention`  \nReflected to its attribute.","type":"BadgeAttention","default":"'none'"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"pill","description":"Draws fully-rounded ends instead of the default rounded rectangle.\n\nAttribute: `pill`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"pulse","description":"Upstream-compatible pulse shorthand. Equivalent to `attention=\"pulse\"` only while the\n`attention` attribute is omitted; every explicit attention value takes precedence.\n\nAttribute: `pulse`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"size","description":"Visual density, matching `<lr-chip>`'s `3xs`–`xl` size scale. `m` preserves the original\nbadge dimensions. Valid `small`/`medium`/`large` values round-trip exactly.\n\nAttribute: `size`  \nReflected to its attribute.","type":"BadgeSize","default":"'m'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"variant","description":"Semantic palette. Every valid upstream spelling remains observable verbatim; rendering uses\nthe private canonical value instead of rewriting the public property or reflected attribute.\n\nAttribute: `variant`  \nReflected to its attribute.","type":"BadgeVariant","default":"'neutral'"}]}},{"name":"lr-bar-chart","description":"`<lr-bar-chart>` — `<lr-chart>` with a `\"bar\"` default. Like the mirrored Web Awesome tag,\nits writable `type` still accepts the complete chart-type vocabulary.\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) | An optional `<script type=\"application/json\">` containing a Chart.js configuration. |\n| `center` | Optional overlay content positioned at the chart area's center. Useful for doughnut and pie totals. |\n| `data-table` | An optional consumer-provided accessible table alternative. Use this escape hatch for a complete paginated or virtualized alternative when the generated 1,000-record sample is insufficient. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The chart wrapper. |\n| `canvas` | The Chart.js canvas. |\n| `center` | The chart-area-centered overlay wrapper for the `center` slot. |\n| `data-table` | The optional generated or slotted data table. |\n| `data-table-toggle` | The disclosure button rendered by `dataTableToggle`. |\n| `data-truncation` | Explanation shown when the generated accessible alternative samples a data set larger than its 1,000-record ceiling. |\n| `description` | The accessible chart summary. |\n| `error` | Static visible error shown instead of `canvas` when the optional `chart.js` peer dependency is not installed; its transition is announced through a shared light-DOM alert. |\n| `feature-warning` | Static nonfatal warning when a requested optional feature peer is unavailable while the core chart remains usable. |\n| `legend` | The wrapping DOM legend, rendered unless `withoutLegend` is set. |\n| `legend-item` | A keyboard-operable dataset or category visibility toggle. |\n| `legend-item-hidden` | Added while the legend item's dataset or category is hidden. |\n| `legend-swatch` | The resolved dataset/category color swatch in a legend item. |\n| `notices` | Wrapper for nonfatal feature warnings and generated-data truncation notices. |\n| `plot` | The fixed-height canvas/overlay region. |\n| `reset-zoom-button` | The reset-zoom control when zoom is active. |\n\n---\n\n**CSS Custom Properties**\n\n- `--border-color-1` (default: `var(--lr-color-chart-1)`) — First dataset border color.\n- `--border-color-2` (default: `var(--lr-color-chart-2)`) — Second dataset border color.\n- `--border-color-3` (default: `var(--lr-color-chart-3)`) — Third dataset border color.\n- `--border-color-4` (default: `var(--lr-color-chart-4)`) — Fourth dataset border color.\n- `--border-color-5` (default: `var(--lr-color-chart-5)`) — Fifth dataset border color.\n- `--border-color-6` (default: `var(--lr-color-chart-6)`) — Sixth dataset border color.\n- `--border-radius` (default: `var(--lr-radius)`) — Dataset element corner radius.\n- `--border-width` (default: `var(--lr-border-width-thin)`) — Dataset element border width.\n- `--fill-color-1` (default: `var(--lr-color-chart-1)`) — First dataset fill color.\n- `--fill-color-2` (default: `var(--lr-color-chart-2)`) — Second dataset fill color.\n- `--fill-color-3` (default: `var(--lr-color-chart-3)`) — Third dataset fill color.\n- `--fill-color-4` (default: `var(--lr-color-chart-4)`) — Fourth dataset fill color.\n- `--fill-color-5` (default: `var(--lr-color-chart-5)`) — Fifth dataset fill color.\n- `--fill-color-6` (default: `var(--lr-color-chart-6)`) — Sixth dataset fill color.\n- `--grid-border-width` (default: `var(--lr-border-width-thin)`) — Axis and grid line width.\n- `--grid-color` (default: `var(--lr-chart-grid-color)`) — Grid line color.\n- `--line-border-width` (default: `var(--lr-border-width-medium)`) — Line dataset stroke width.\n- `--lr-chart-canvas-hover-outline-color` (default: `var(--lr-chart-grid-color)`) — Color of the `[part='canvas']` hover-state outline.\n- `--lr-chart-canvas-hover-outline-width` (default: `var(--lr-border-width-thin)`) — Width of the `[part='canvas']` hover-state outline.\n- `--lr-chart-data-table-button-active-bg` — Pressed background of an actionable generated- table value; defaults to the standard active mix of `--lr-color-brand-quiet`.\n- `--lr-chart-data-table-button-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background of an actionable generated-table value.\n- `--lr-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-chart-data-table-toggle-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background of the `dataTableToggle` disclosure button.\n- `--lr-chart-grid-color` (default: `var(--lr-color-border)`) — Grid-line color. Resolved via `getComputedStyle` on every draw (Chart.js paints to canvas and cannot consume `var()`).\n- `--lr-chart-height` (default: `var(--lr-size-280px)`) — The plot region's `block-size` and the host's minimum block size. A visible data table or wrapping DOM legend grows the host in normal flow instead of overlapping following content. `height` supplies a private fallback; this public token always wins when a consumer sets it.\n- `--lr-chart-legend-color` (default: `var(--lr-color-text)`) — Legend label color. Resolved via `getComputedStyle` on every draw.\n- `--lr-chart-legend-item-active-bg` — Pressed background of a legend visibility button; defaults to the standard active mix of `--lr-color-brand-quiet`.\n- `--lr-chart-legend-item-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background of a legend visibility button.\n- `--lr-chart-legend-side-max` (default: `var(--lr-size-15rem)`) — Maximum inline size reserved for a side-positioned DOM legend; the track is also capped at one third of the chart allocation.\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 every series collapses to one system color and the stripe/crosshatch pattern 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.\n- `--lr-chart-reset-zoom-button-active-bg` — Pressed background of the reset-zoom button; defaults to the standard active mix of `--lr-color-brand-quiet`.\n- `--lr-chart-reset-zoom-button-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background of the reset-zoom button.\n- `--lr-chart-tick-color` (default: `var(--lr-color-text-quiet)`) — Axis tick-label color; also used for the `xLabel`/`yLabel`/`y2Label` axis-title text (there is no separate title-color token). Resolved via `getComputedStyle` on every draw.\n- `--lr-chart-tick-font-size` (default: `var(--lr-font-size-xs)`) — Axis tick-label font size, in any CSS length unit. Defaults to `--lr-font-size-xs` (12px at the standard root) because that matches Chart.js's OWN built-in tick font size, which is what every canvas chart rendered before this token existed -- leaving it unset must stay byte-identical to that, not shrink to `<lr-lite-chart>`'s SVG default. Also sizes the radar/polarArea `r`-scale `pointLabels` (the spoke labels), but ONLY once set: those default separately to Chart.js's OWN distinct `RadialLinearScale` `pointLabels` default (10px, not this token's 12px), and only adopt this token's size once the consumer explicitly sets it, at which point ticks and point labels match. Resolved via `getComputedStyle` on every draw, same constraint as every other `--lr-chart-*` token here (Chart.js paints to canvas and cannot consume `var()`).\n- `--lr-chart-tooltip-bg` (default: `var(--lr-color-surface)`) — Tooltip background color. Resolved via `getComputedStyle` on every draw.\n- `--lr-chart-tooltip-text` (default: `var(--lr-color-text)`) — Tooltip text color. Resolved via `getComputedStyle` on every draw.\n- `--point-radius` (default: `var(--lr-space-2xs)`) — Line/scatter point radius.","attributes":[{"name":"area","description":"Chart-wide default fill-under-line setting for line-type series; a series's own `LyraChartSeries.fill` overrides it.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"axes","description":"Complete cartesian axis visibility, independent of grid. `y` also controls the y2 axis.\nRadial charts ignore this setting. Explicit config scale options retain precedence.\n\nType: `LyraChartAxes`  \nDefault: `'both'`","value":{"type":["'x'","'y'","'both'","'none'"]}},{"name":"begin-at-zero","description":"Type: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"compact","description":"Compact cartesian plot: hide axes and remove automatic layout padding. Set height and\nwithoutLegend for a small histogram/sparkline. Preserves data tables, tooltips and keyboard\nactions; radial charts ignore this setting. Explicit config options retain precedence.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"data-labels","description":"Draws each data point's value on the chart via the optional\n`chartjs-plugin-datalabels` peer. Unset (the default) leaves labels off for\nthis chart; the peer is attached only to instances that opt in, and\n`buildConfig()` keeps its per-chart options disabled until this is set. The\nscreen-reader equivalent is the always-present data table (see\n`show-data-table`); labels are a purely visual, canvas-only addition.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"data-table-toggle","description":"Render a disclosure button above the accessible data table so a sighted reader can reveal the\nnumbers behind the chart on demand. `showDataTable` alone is all-or-nothing -- the table is\neither permanently screen-reader-only or permanently visible -- which left a consumer wrapping\na duplicated table in their own `<details>`.\n\nWith this set, `showDataTable` becomes the disclosure's *initial* state rather than its whole\nbehavior. The table stays in the DOM in both states, so assistive technology never loses it.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"description","description":"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`"},{"name":"grid","description":"Controls which cartesian grid axes are drawn.\n\nType: `LyraChartGrid`  \nDefault: `'both'`","value":{"type":["'x'","'y'","'both'","'none'"]}},{"name":"height","description":"Type: `string`  \nDefault: `'280px'`","value":{"type":["string"]}},{"name":"index-axis","description":"Chart.js index axis. `'y'` is Chart.js's own mechanism for horizontal bars (it also flips\nline/area types onto a horizontal category axis).\n\nType: `LyraChartIndexAxis`  \nDefault: `'x'`","value":{"type":["'x'","'y'"]}},{"name":"label","description":"Accessible chart label. A host `aria-label` still has highest precedence.\n\nType: `string | null`  \nDefault: `null`"},{"name":"legend-display","description":"`auto` retains optional legend formatting; `label` omits values even with a formatter; `value`\nappends a formatted value. `percentage` uses locale percentages of the absolute represented\nlegend values, including hidden items (zero totals yield 0%). `value-percentage` appends both,\nas `label: value (percentage)`. Dataset values are sampled sums; category values come from the\nfirst dataset. The `formatter`/`valueFormatter` callback backing `value` and `value-percentage`\nadditionally receives that same `percentage` in its `surface: 'legend'` context, so a custom\nformatter can build its own combined text without recomputing the share. Tooltip and axis\nformatting are unchanged.\n\nType: `LyraChartLegendDisplay`  \nDefault: `'auto'`","value":{"type":["'auto'","'label'","'value'","'percentage'","'value-percentage'"]}},{"name":"legend-mode","description":"`datum` renders category toggles for pie/doughnut/polar-area charts. Categories use the first\ndataset's colors and values; a toggle affects that category in every ring. Other chart types\nretain dataset legends. `auto` (the default) resolves to `datum` on pie/doughnut/polar-area\ncharts -- where a single-dataset legend would otherwise enumerate one entry for the whole\ndataset instead of one per visible slice -- and to `dataset` everywhere else. `dataset` always\nforces the dataset legend, even on a slice chart. Both non-`auto` modes use the generated\naccessible-data sampling budget.\n\nType: `LyraChartLegendMode`  \nDefault: `'auto'`","value":{"type":["'auto'","'dataset'","'datum'"]}},{"name":"legend-position","description":"Legend placement. `auto` uses a right legend above 480px and a bottom legend below it.\n\nType: `LyraChartLegendPosition`  \nDefault: `'top'`","value":{"type":["'left'","'top'","'right'","'bottom'","'center'","'chartArea'","'start'","'end'","'auto'"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max","description":"Maximum value-axis bound. Non-finite values are ignored.\n\nType: `number | null`  \nDefault: `null`"},{"name":"min","description":"Minimum value-axis bound. Non-finite values are ignored.\n\nType: `number | null`  \nDefault: `null`"},{"name":"plugins","description":"Chart.js plugins attached to this chart instance. Valid plugins retain their opaque identity.\n\nType: `readonly LyraChartPlugin[]`  \nDefault: `[]`"},{"name":"scale-type","description":"Scale type for the **value** axis (the categorical axis is unaffected). `'logarithmic'` plots\na dataset spanning several orders of magnitude honestly, where a linear axis collapses\neverything below the maximum into the baseline. Inherited by `lr-line-chart`,\n`lr-scatter-chart` and `lr-bar-chart`.\n\nA logarithmic axis cannot represent zero or negative values (`log(0)` is `-Infinity`), so\n`beginAtZero` is not forwarded in that mode -- Chart.js would otherwise be handed a bound it\ncannot place. Non-positive data points are dropped by Chart.js's own log scale.\n\nType: `LyraChartScaleType`  \nDefault: `'linear'`","value":{"type":["'linear'","'logarithmic'"]}},{"name":"show-data-table","description":"Makes the generated data table visible; it remains screen-reader available when false.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"stack-totals","description":"When the chart is `stacked` (bar/line only), draws the per-category stack\ntotal above each stack, via the same optional `chartjs-plugin-datalabels`\npeer as `data-labels`. Null/undefined points are skipped; a category whose\nevery value is null shows no total. The generated accessible data table\nreceives the same formatted total column (one per value axis). Unset (the\ndefault) draws and adds nothing.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"stacked","description":"Stacks the `x`/`y`(/`y2`) scale entries `buildScales()` returns; only meaningful for `bar` and `line` types.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"type","description":"Type: `LyraChartType`  \nDefault: `'bar'`","value":{"type":["'line'","'bar'","'scatter'","'pie'","'doughnut'","'radar'","'polarArea'","'bubble'"]}},{"name":"without-animation","description":"Disables Chart.js animation.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"without-legend","description":"Hides the legend.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"without-tooltip","description":"Hides Chart.js tooltips.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"x-label","description":"Type: `string | null`  \nDefault: `null`"},{"name":"y-label","description":"Type: `string | null`  \nDefault: `null`"},{"name":"y2-label","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"zoom","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"","description":"An optional `<script type=\"application/json\">` containing a Chart.js configuration."},{"name":"center","description":"Optional overlay content positioned at the chart area's center. Useful for doughnut and pie totals."},{"name":"data-table","description":"An optional consumer-provided accessible table alternative. Use this escape hatch for a complete paginated or virtualized alternative when the generated 1,000-record sample is insufficient."}],"js":{"properties":[{"name":"annotations","description":"Declarative reference lines and shaded bands — a threshold, an event year, a regime change, a\nhighlighted period. Each entry marks either a single `value` or a `from`/`to` range on `axis`\n(default `'y'`), with an optional `label` and semantic `tone`.\n\nNeeds the optional `chartjs-plugin-annotation` peer, loaded on first actual demand so a page\nwith no annotated charts never downloads it. The plugin is registered globally, like\n`chartjs-plugin-zoom` and unlike `chartjs-plugin-datalabels`: it draws nothing unless a chart\nsupplies annotation options, so the registration is unobservable to charts that set none, and\nregistration is also what installs the plugin's own element defaults. Without the peer\ninstalled the chart still renders; a console warning plus a localized visible warning and\nlight-DOM announcement explain the no-op — the same fail-closed contract `data-labels` uses.\n\nEntries are included in the generated accessible description, mirroring `lr-heatmap`.","type":"readonly LyraChartAnnotation[]","default":"[]"},{"name":"area","description":"Chart-wide default fill-under-line setting for line-type series; a series's own `LyraChartSeries.fill` overrides it.\n\nAttribute: `area`","type":"boolean","default":"false"},{"name":"axes","description":"Complete cartesian axis visibility, independent of grid. `y` also controls the y2 axis.\nRadial charts ignore this setting. Explicit config scale options retain precedence.\n\nAttribute: `axes`","type":"LyraChartAxes","default":"'both'"},{"name":"beginAtZero","description":"Attribute: `begin-at-zero`","type":"boolean","default":"true"},{"name":"chart","description":"The current Chart.js instance. Read it only while the element is connected and loaded.","type":"LyraChartInstance | undefined"},{"name":"chartArea","description":"The current Chart.js chart-area geometry in canvas-local coordinates. Read-only -- derived\nfrom the live Chart.js instance's own layout pass, never assignable. The setter is a\ndocumented no-op (matching `lr-histogram`'s `labels`/`datasets` pattern) so an accidental\n`.chartArea=${x}` Lit template binding degrades silently instead of throwing from inside\nlit-html's property-commit.","type":"LyraChartArea | undefined"},{"name":"compact","description":"Compact cartesian plot: hide axes and remove automatic layout padding. Set height and\nwithoutLegend for a small histogram/sparkline. Preserves data tables, tooltips and keyboard\nactions; radial charts ignore this setting. Explicit config options retain precedence.\n\nAttribute: `compact`","type":"boolean","default":"false"},{"name":"config","type":"LyraChartConfiguration | undefined"},{"name":"dataLabels","description":"Draws each data point's value on the chart via the optional\n`chartjs-plugin-datalabels` peer. Unset (the default) leaves labels off for\nthis chart; the peer is attached only to instances that opt in, and\n`buildConfig()` keeps its per-chart options disabled until this is set. The\nscreen-reader equivalent is the always-present data table (see\n`show-data-table`); labels are a purely visual, canvas-only addition.\n\nAttribute: `data-labels`","type":"boolean","default":"false"},{"name":"dataTableToggle","description":"Render a disclosure button above the accessible data table so a sighted reader can reveal the\nnumbers behind the chart on demand. `showDataTable` alone is all-or-nothing -- the table is\neither permanently screen-reader-only or permanently visible -- which left a consumer wrapping\na duplicated table in their own `<details>`.\n\nWith this set, `showDataTable` becomes the disclosure's *initial* state rather than its whole\nbehavior. The table stays in the DOM in both states, so assistive technology never loses it.\n\nAttribute: `data-table-toggle`","type":"boolean","default":"false"},{"name":"datasets","description":"Simplified chart series. Non-record entries are dropped while valid sibling series remain.","type":"readonly LyraChartSeries[]"},{"name":"description","description":"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\nAttribute: `description`","type":"string | null","default":"null"},{"name":"formatter","description":"Unified context-object formatter for visual, tooltip, table/export, and spoken values.","type":"LyraChartFormatter | undefined"},{"name":"grid","description":"Controls which cartesian grid axes are drawn.\n\nAttribute: `grid`","type":"LyraChartGrid","default":"'both'"},{"name":"height","description":"Attribute: `height`","type":"string","default":"'280px'"},{"name":"hiddenDatasets","description":"Complete controlled visibility state for DOM legend toggles. `undefined` (the default) honors\neach effective dataset's `hidden` configuration; a defined array wins over those defaults, and\nan empty array deliberately makes every dataset visible. Invalid, duplicate, and out-of-range\nindexes are ignored when state is applied or emitted.","type":"readonly number[] | undefined"},{"name":"hiddenDatums","description":"Controlled hidden source category indexes for pie/doughnut/polar-area charts, shared by all\ndatasets/rings. Clone-owned; invalid, duplicate and out-of-range indexes are ignored when\napplied or emitted. Empty restores all categories. Does not alter dataset visibility or exports.","type":"readonly number[]","default":"[]"},{"name":"indexAxis","description":"Chart.js index axis. `'y'` is Chart.js's own mechanism for horizontal bars (it also flips\nline/area types onto a horizontal category axis).\n\nAttribute: `index-axis`","type":"LyraChartIndexAxis","default":"'x'"},{"name":"label","description":"Accessible chart label. A host `aria-label` still has highest precedence.\n\nAttribute: `label`","type":"string | null","default":"null"},{"name":"labels","type":"string[]","default":"[]"},{"name":"legendDisplay","description":"`auto` retains optional legend formatting; `label` omits values even with a formatter; `value`\nappends a formatted value. `percentage` uses locale percentages of the absolute represented\nlegend values, including hidden items (zero totals yield 0%). `value-percentage` appends both,\nas `label: value (percentage)`. Dataset values are sampled sums; category values come from the\nfirst dataset. The `formatter`/`valueFormatter` callback backing `value` and `value-percentage`\nadditionally receives that same `percentage` in its `surface: 'legend'` context, so a custom\nformatter can build its own combined text without recomputing the share. Tooltip and axis\nformatting are unchanged.\n\nAttribute: `legend-display`","type":"LyraChartLegendDisplay","default":"'auto'"},{"name":"legendMode","description":"`datum` renders category toggles for pie/doughnut/polar-area charts. Categories use the first\ndataset's colors and values; a toggle affects that category in every ring. Other chart types\nretain dataset legends. `auto` (the default) resolves to `datum` on pie/doughnut/polar-area\ncharts -- where a single-dataset legend would otherwise enumerate one entry for the whole\ndataset instead of one per visible slice -- and to `dataset` everywhere else. `dataset` always\nforces the dataset legend, even on a slice chart. Both non-`auto` modes use the generated\naccessible-data sampling budget.\n\nAttribute: `legend-mode`","type":"LyraChartLegendMode","default":"'auto'"},{"name":"legendPosition","description":"Legend placement. `auto` uses a right legend above 480px and a bottom legend below it.\n\nAttribute: `legend-position`","type":"LyraChartLegendPosition","default":"'top'"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"max","description":"Maximum value-axis bound. Non-finite values are ignored.\n\nAttribute: `max`","type":"number | null","default":"null"},{"name":"min","description":"Minimum value-axis bound. Non-finite values are ignored.\n\nAttribute: `min`","type":"number | null","default":"null"},{"name":"plugins","description":"Chart.js plugins attached to this chart instance. Valid plugins retain their opaque identity.\n\nAttribute: `plugins`","type":"readonly LyraChartPlugin[]","default":"[]"},{"name":"scaleType","description":"Scale type for the **value** axis (the categorical axis is unaffected). `'logarithmic'` plots\na dataset spanning several orders of magnitude honestly, where a linear axis collapses\neverything below the maximum into the baseline. Inherited by `lr-line-chart`,\n`lr-scatter-chart` and `lr-bar-chart`.\n\nA logarithmic axis cannot represent zero or negative values (`log(0)` is `-Infinity`), so\n`beginAtZero` is not forwarded in that mode -- Chart.js would otherwise be handed a bound it\ncannot place. Non-positive data points are dropped by Chart.js's own log scale.\n\nAttribute: `scale-type`","type":"LyraChartScaleType","default":"'linear'"},{"name":"showDataTable","description":"Makes the generated data table visible; it remains screen-reader available when false.\n\nAttribute: `show-data-table`","type":"boolean","default":"false"},{"name":"stackTotals","description":"When the chart is `stacked` (bar/line only), draws the per-category stack\ntotal above each stack, via the same optional `chartjs-plugin-datalabels`\npeer as `data-labels`. Null/undefined points are skipped; a category whose\nevery value is null shows no total. The generated accessible data table\nreceives the same formatted total column (one per value axis). Unset (the\ndefault) draws and adds nothing.\n\nAttribute: `stack-totals`","type":"boolean","default":"false"},{"name":"stacked","description":"Stacks the `x`/`y`(/`y2`) scale entries `buildScales()` returns; only meaningful for `bar` and `line` types.\n\nAttribute: `stacked`","type":"boolean","default":"false"},{"name":"stackedAxes","description":"Per-value-axis override of `stacked`, keyed by `'y'`/`'y2'`. An axis absent from this record\n-- including every axis when the whole property is unset -- falls back to the chart-wide\n`stacked` value, which is what keeps a chart that never sets this byte-identical to before.\nLets a `stacked` bar series on the primary axis sit next to an unstacked overlay series on\n`y2` (via `LyraChartSeries.axis: 'y2'`): set `stackedAxes` to `{ y2: false }` alongside\n`stacked`, or spell out both axes explicitly. The shared categorical axis (`x` for a vertical\nbar/line, or `y` when `indexAxis` is `'y'`) has no independent entry of its own -- it always\nmirrors the resolved `'y'` value, matching Chart.js's own paired index/value-scale stacking\ncontract. Only meaningful for `bar`/`line` types, matching `stacked` itself.","type":"Partial<Record<'y' | 'y2', boolean>> | undefined"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"tooltipFooterFormatter","description":"Tooltip footer formatter -- e.g. a category's stack total under the items. Receives every\nitem the hovered tooltip covers, in the same shape as `tooltipTitleFormatter`. Unset (the\ndefault) leaves Chart.js's own default (no footer).","type":"LyraChartTooltipGroupFormatter | undefined"},{"name":"tooltipTitleFormatter","description":"Tooltip title formatter -- e.g. a scatter point's own name. Receives every item the hovered\ntooltip covers, each in `formatter`'s `'tooltip'`-surface context shape. Unset (the default)\nleaves Chart.js's own default title (the shared category label) in place.","type":"LyraChartTooltipGroupFormatter | undefined"},{"name":"type","description":"Attribute: `type`","type":"LyraChartType","default":"'bar'"},{"name":"valueFormatter","description":"Formats numeric (value-axis) ticks, tooltip values, legend values, and generated accessible\ntable cells from one callback.\nHorizontal scalar tooltips use parsed x, including a raw config indexAxis override;\nstructured points retain their y-value contract. The context-object formatter shares this rule.\nNever runs against the categorical x-axis's own labels (line/bar's `labels` strings) —\nChart.js's category scale passes the tick index to `ticks.callback`, not the label text,\nso formatting it would corrupt the axis.","type":"LyraChartValueFormatter | undefined"},{"name":"withoutAnimation","description":"Disables Chart.js animation.\n\nAttribute: `without-animation`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"withoutLegend","description":"Hides the legend.\n\nAttribute: `without-legend`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"withoutTooltip","description":"Hides Chart.js tooltips.\n\nAttribute: `without-tooltip`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"xLabel","description":"Attribute: `x-label`","type":"string | null","default":"null"},{"name":"y2Label","description":"Attribute: `y2-label`","type":"string","default":"''"},{"name":"yLabel","description":"Attribute: `y-label`","type":"string | null","default":"null"},{"name":"zoom","description":"Attribute: `zoom`","type":"boolean","default":"false"}],"events":[{"name":"lr-before-datum-visibility-change","description":"Cancelable category visibility proposal in datum legend mode. `detail: { index: number, visible: boolean, hiddenDatums: readonly number[] }`. Source category indexes apply to every dataset/ring. The complete detail is frozen.","type":"CustomEvent<LyraChartDatumVisibilityChangeDetail>"},{"name":"lr-before-legend-visibility-change","description":"Cancelable proposal emitted before a DOM legend toggle changes state. `detail` contains the target `datasetIndex`, its proposed `visible` value, and the complete canonical proposed `hiddenDatasets` snapshot.","type":"CustomEvent<LyraChartLegendVisibilityChangeDetail>"},{"name":"lr-datum-activate","description":"Family-normalized activation event. Its detail adds `kind` (`bar`, `point`, `segment`, or `slice`) to the `lr-point-click` detail.","type":"CustomEvent<\n    LyraChartDatumActivateDetail<LyraCoreChartDatumKind>\n  >"},{"name":"lr-datum-visibility-change","description":"Emitted after an accepted category toggle commits the same frozen detail. Programmatic `hiddenDatums` assignments are silent.","type":"CustomEvent<LyraChartDatumVisibilityChangeDetail>"},{"name":"lr-legend-visibility-change","description":"Emitted after an accepted DOM legend toggle commits the same detail. Programmatic `hiddenDatasets` changes reconcile without either event.","type":"CustomEvent<LyraChartLegendVisibilityChangeDetail>"},{"name":"lr-point-click","description":"Fired when pointer input lands on a data point/segment, when a generated data-table value is activated, or when Enter/Space activates the keyboard-current canvas datum. `detail: { datasetIndex: number, index: number, label: string | undefined, value: unknown }`. For scatter/bubble data, `label` prefers the per-point label and `value` is the complete typed `LyraChartPoint` (`x`, `y`, optional `r`, optional `label`).","type":"CustomEvent<{\n    datasetIndex: number;\n    index: number;\n    label: string | undefined;\n    value: unknown;\n  }>"},{"name":"lr-zoom","description":"`detail: { zoomed }`.","type":"CustomEvent<{ zoomed: boolean }>"}]}},{"name":"lr-box-plot","description":"`<lr-box-plot>` — a box-and-whisker chart from precomputed five-number\nsummaries (no raw sample data is shipped to the browser). Beyond Web\nAwesome's chart set — useful for summarizing distributions.\nWith IntersectionObserver available, canvas construction waits for the first delivered\nvisibility decision; without it, drawing starts as soon as the peers and canvas are ready.\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 table alternative. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The chart wrapper. |\n| `canvas` | The box-plot canvas. A keyboard-navigable surface: Arrow keys/Home/End walk the individual boxes and Enter/Space activates the current one, mirroring `<lr-chart>`. |\n| `data-table` | The optional generated or slotted data table. |\n| `data-table-toggle` | The disclosure button rendered by `dataTableToggle`. |\n| `data-truncation` | Explanation shown when the generated accessible alternative samples more than 1,000 records. |\n| `description` | The accessible box-plot summary. |\n| `error` | Static visible error shown instead of the canvas when the optional box-plot peer fails to load; its transition is announced through a shared light-DOM alert. |\n| `legend` | The wrapping DOM legend rendered when `legend` is set. |\n| `legend-item` | A keyboard-operable series visibility toggle. |\n| `legend-item-hidden` | Added to a `legend-item` while its box series is hidden. |\n| `legend-swatch` | The resolved series-color swatch in a legend item. |\n| `plot` | The fixed-height canvas region. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-box-plot-border-color-1` (default: `var(--lr-color-chart-1)`) — First series box-outline color.\n- `--lr-box-plot-border-color-2` (default: `var(--lr-color-chart-2)`) — Second series box-outline color.\n- `--lr-box-plot-border-color-3` (default: `var(--lr-color-chart-3)`) — Third series box-outline color.\n- `--lr-box-plot-border-color-4` (default: `var(--lr-color-chart-4)`) — Fourth series box-outline color.\n- `--lr-box-plot-border-color-5` (default: `var(--lr-color-chart-5)`) — Fifth series box-outline color.\n- `--lr-box-plot-border-color-6` (default: `var(--lr-color-chart-6)`) — Sixth series box-outline color.\n- `--lr-box-plot-border-color-7` (default: `var(--lr-color-chart-7)`) — Seventh series box-outline color.\n- `--lr-box-plot-border-color-8` (default: `var(--lr-color-chart-8)`) — Eighth series box-outline color.\n- `--lr-box-plot-border-width` (default: `var(--lr-border-width-thin)`) — Canvas box-outline stroke width, in pixels. Same override mechanism as `<lr-chart>`'s `--border-width`.\n- `--lr-box-plot-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-box-plot-data-table-toggle-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background of the `dataTableToggle` disclosure button.\n- `--lr-box-plot-fill-color-1` (default: `var(--lr-color-chart-1)`) — First series box-fill and legend-swatch color.\n- `--lr-box-plot-fill-color-2` (default: `var(--lr-color-chart-2)`) — Second series box-fill and legend-swatch color.\n- `--lr-box-plot-fill-color-3` (default: `var(--lr-color-chart-3)`) — Third series box-fill and legend-swatch color.\n- `--lr-box-plot-fill-color-4` (default: `var(--lr-color-chart-4)`) — Fourth series box-fill and legend-swatch color.\n- `--lr-box-plot-fill-color-5` (default: `var(--lr-color-chart-5)`) — Fifth series box-fill and legend-swatch color.\n- `--lr-box-plot-fill-color-6` (default: `var(--lr-color-chart-6)`) — Sixth series box-fill and legend-swatch color.\n- `--lr-box-plot-fill-color-7` (default: `var(--lr-color-chart-7)`) — Seventh series box-fill and legend-swatch color.\n- `--lr-box-plot-fill-color-8` (default: `var(--lr-color-chart-8)`) — Eighth series box-fill and legend-swatch color.\n- `--lr-box-plot-item-radius` (default: `0`) — Radius, in pixels, of the individual raw-sample dots drawn alongside each box; `0` (the default) disables them.\n- `--lr-chart-canvas-hover-outline-color` (default: `var(--lr-chart-grid-color)`) — Color of the `[part='canvas']` hover-state outline. Same token and default as `<lr-chart>`.\n- `--lr-chart-canvas-hover-outline-width` (default: `var(--lr-border-width-thin)`) — Width of the `[part='canvas']` hover-state outline.\n- `--lr-chart-grid-color` (default: `var(--lr-color-border)`) — Canvas 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)`) — DOM legend label color.\n- `--lr-chart-legend-item-active-bg` — Legend-item pressed background.\n- `--lr-chart-legend-item-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Legend-item hover background.\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 stripe/crosshatch pattern 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-lite-chart>`.\n- `--lr-chart-tick-color` (default: `var(--lr-color-text-quiet)`) — Canvas tick and axis-title color.\n- `--lr-chart-tick-font-size` (default: `var(--lr-font-size-xs)`) — Canvas axis tick-label font size. Same token name and default as `lr-chart`'s equivalent, so theming either retunes both; `--lr-font-size-xs` (12px at the standard root) matches Chart.js's OWN built-in tick font size, which is what box-plot rendered before this token existed.\n- `--lr-chart-tooltip-bg` (default: `var(--lr-color-surface)`) — Canvas tooltip background.\n- `--lr-chart-tooltip-text` (default: `var(--lr-color-text)`) — Canvas tooltip text color.","attributes":[{"name":"begin-at-zero","description":"Type: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"data-table-toggle","description":"Render a disclosure button above the accessible data table so a sighted reader can reveal the\nnumbers behind the plot on demand. `showDataTable` alone is all-or-nothing -- the table is\neither permanently screen-reader-only or permanently visible -- which left a consumer wrapping\na duplicated table in their own `<details>`.\n\nWith this set, `showDataTable` becomes the disclosure's *initial* state rather than its whole\nbehavior. The table stays in the DOM in both states, so assistive technology never loses it.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"description","description":"Accessible chart description. A generated five-number summary is used when unset.\n\nType: `string | null`  \nDefault: `null`"},{"name":"height","description":"Type: `string`  \nDefault: `'280px'`","value":{"type":["string"]}},{"name":"label","description":"Accessible chart name. A host `aria-label` wins.\n\nType: `string | null`  \nDefault: `null`"},{"name":"legend","description":"Deliberately opt-in (default `false`), unlike `lr-chart`'s negative-polarity\n`withoutLegend` (legend shown by default): a box plot's single/few-series comparison usage is\nmore often legend-redundant (category labels already identify each box) than `lr-chart`'s\ntypical multi-dataset case.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"legend-position","description":"Logical placement for the optional DOM legend. Deliberately `'bottom'`, unlike `lr-chart`'s\n`'top'` default -- shared with `lr-lite-chart` via `chart-chrome.ts`'s\n`normalizeChartChromeLegendPosition()` default.\n\nType: `LyraChartChromeLegendPosition`  \nDefault: `'bottom'`","value":{"type":["'top'","'bottom'","'start'","'end'"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"show-data-table","description":"Makes the generated data table visible; it remains screen-reader available when false.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"y-label","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}}],"slots":[{"name":"data-table","description":"An optional consumer-provided complete/paginated accessible table alternative."}],"js":{"properties":[{"name":"beginAtZero","description":"Attribute: `begin-at-zero`","type":"boolean","default":"true"},{"name":"dataTableToggle","description":"Render a disclosure button above the accessible data table so a sighted reader can reveal the\nnumbers behind the plot on demand. `showDataTable` alone is all-or-nothing -- the table is\neither permanently screen-reader-only or permanently visible -- which left a consumer wrapping\na duplicated table in their own `<details>`.\n\nWith this set, `showDataTable` becomes the disclosure's *initial* state rather than its whole\nbehavior. The table stays in the DOM in both states, so assistive technology never loses it.\n\nAttribute: `data-table-toggle`","type":"boolean","default":"false"},{"name":"datasets","description":"Series with an array `data` payload. Malformed entries are dropped without hiding siblings.","type":"readonly LyraBoxPlotSeries[]"},{"name":"description","description":"Accessible chart description. A generated five-number summary is used when unset.\n\nAttribute: `description`","type":"string | null","default":"null"},{"name":"formatter","description":"Unified context-object formatter shared with the other chart surfaces.","type":"LyraChartFormatter | undefined"},{"name":"height","description":"Attribute: `height`","type":"string","default":"'280px'"},{"name":"hiddenDatasets","description":"Complete controlled legend visibility state. `undefined` keeps the default all-visible state.","type":"readonly number[] | undefined"},{"name":"label","description":"Accessible chart name. A host `aria-label` wins.\n\nAttribute: `label`","type":"string | null","default":"null"},{"name":"labels","type":"readonly string[]","default":"[]"},{"name":"legend","description":"Deliberately opt-in (default `false`), unlike `lr-chart`'s negative-polarity\n`withoutLegend` (legend shown by default): a box plot's single/few-series comparison usage is\nmore often legend-redundant (category labels already identify each box) than `lr-chart`'s\ntypical multi-dataset case.\n\nAttribute: `legend`","type":"boolean","default":"false"},{"name":"legendPosition","description":"Logical placement for the optional DOM legend. Deliberately `'bottom'`, unlike `lr-chart`'s\n`'top'` default -- shared with `lr-lite-chart` via `chart-chrome.ts`'s\n`normalizeChartChromeLegendPosition()` default.\n\nAttribute: `legend-position`","type":"LyraChartChromeLegendPosition","default":"'bottom'"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"showDataTable","description":"Makes the generated data table visible; it remains screen-reader available when false.\n\nAttribute: `show-data-table`","type":"boolean","default":"false"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"valueFormatter","description":"Formats numeric axes, tooltips, generated table cells, summaries, and CSV export.","type":"LyraChartValueFormatter | undefined"},{"name":"yLabel","description":"Attribute: `y-label`","type":"string","default":"''"}],"events":[{"name":"lr-before-legend-visibility-change","description":"Cancelable proposed DOM legend visibility change.","type":"CustomEvent<LyraEventDetailSnapshot<LyraChartLegendVisibilityChangeDetail>>"},{"name":"lr-datum-activate","description":"Family-normalized box activation; the legacy detail plus `kind: 'box'`.","type":"CustomEvent<\n    LyraChartDatumActivateDetail<'box', LyraBoxPlotSummary | null>\n  >"},{"name":"lr-legend-visibility-change","description":"Committed DOM legend visibility change.","type":"CustomEvent<LyraEventDetailSnapshot<LyraChartLegendVisibilityChangeDetail>>"},{"name":"lr-point-click","description":"Fired when pointer input lands on a box, or when Enter/Space activates the keyboard-current box. `detail: { datasetIndex: number, index: number, label: string | undefined, value: LyraBoxPlotSummary | null }`, where `value` is that box's complete five-number summary. Mirrors `<lr-chart>`/`<lr-lite-chart>`'s event of the same name.","type":"CustomEvent<LyraBoxPlotPointDetail>"}]}},{"name":"lr-branch-picker","description":"`<lr-branch-picker>` — the \"‹ 2 / 5 ›\" navigator across regenerated/edited variants of one\nmessage. Pure controlled: it never mutates its own `index` — the same contract `<lr-pagination>`\nalready establishes for `page`. The host listens for `lr-branch-change`, swaps the displayed\nbranch content, and applies the new `index` back.\n\nRenders nothing at all while `count < 2`, so a host can bind it unconditionally on every message\nregardless of whether that message actually has multiple branches yet.\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 group wrapper (`role=\"group\"`). |\n| `next-button` | The next-branch chevron button. |\n| `next-glyph` | The chevron glyph wrapper inside `next-button`. |\n| `position` | The visible \"2 / 5\" text. |\n| `previous-button` | The previous-branch chevron button. |\n| `previous-glyph` | The chevron glyph wrapper inside `previous-button`. |","attributes":[{"name":"count","description":"Total number of branches. While `count < 2` the component renders nothing at all.\n\nType: `number`  \nDefault: `1`","value":{"type":["number"]}},{"name":"index","description":"0-based current branch, rendered 1-based (\"2 / 5\"). Controlled -- this component never writes\nto it itself.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"label","description":"Accessible name for the group. Defaults to the localized `branchPickerLabel`.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"js":{"properties":[{"name":"count","description":"Total number of branches. While `count < 2` the component renders nothing at all.\n\nAttribute: `count`  \nReflected to its attribute.","type":"number","default":"1"},{"name":"index","description":"0-based current branch, rendered 1-based (\"2 / 5\"). Controlled -- this component never writes\nto it itself.\n\nAttribute: `index`  \nReflected to its attribute.","type":"number","default":"0"},{"name":"label","description":"Accessible name for the group. Defaults to the localized `branchPickerLabel`.\n\nAttribute: `label`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-branch-change","description":"A branch navigation was requested. `detail: { index }` — always a valid target (never past either bound); the consumer applies `index` after switching the displayed branch content.","type":"CustomEvent<{ index: number }>"},{"name":"lr-toolbar-actions-change","description":"No-detail coordination event emitted when the logical toolbar actions exposed by this provider change availability or order.","type":"Event"}]}},{"name":"lr-breadcrumb","description":"`<lr-breadcrumb>` — a responsive navigation trail.\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-breadcrumb-item>` children. |\n| `separator` | Decorative visual separator copied into each item that does not provide its own separator. Generated copies are inert and aria-hidden, with identifiers, ID references, form associations, and submission attributes removed. Source mutations patch identity-compatible copies in place; do not use this slot for interactive content or form controls. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | Compatibility name for the navigation wrapper; use `breadcrumb`. |\n| `breadcrumb` | The navigation wrapper. It is the same node as `base`. |\n| `list` | The `role=\"list\"` flex row wrapping the slotted items. |","attributes":[{"name":"aria-label","description":"Accessible-name override for the trail, mapped to the host's `aria-label` attribute the same\nway every other Lyra component spells this member. The `<nav>` landmark that owns the role\nlives in the shadow root and never inherits a host attribute automatically, so the value is\ncopied onto it. Both spellings work: an `aria-label` attribute on `<lr-breadcrumb>` (which the\nattribute mapping also surfaces here) and a plain property assignment\n(`el.accessibleLabel = 'Docs trail'`). Wins over `label` and over the localized default\n(\"Breadcrumb\"); an explicitly empty `aria-label` attribute or an explicitly empty\n`accessibleLabel`/`label` property assignment stays empty rather than falling through.\n\nType: `string | undefined`"},{"name":"label","description":"Accessible name matching both pinned upstream breadcrumb contracts. A host `aria-label`\nremains the highest-priority override. An explicitly empty string stays empty rather than\nfalling back to the localized default.\n\nType: `string | undefined`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"slots":[{"name":"","description":"`<lr-breadcrumb-item>` children."},{"name":"separator","description":"Decorative visual separator copied into each item that does not provide its own separator. Generated copies are inert and aria-hidden, with identifiers, ID references, form associations, and submission attributes removed. Source mutations patch identity-compatible copies in place; do not use this slot for interactive content or form controls."}],"js":{"properties":[{"name":"accessibleLabel","description":"Accessible-name override for the trail, mapped to the host's `aria-label` attribute the same\nway every other Lyra component spells this member. The `<nav>` landmark that owns the role\nlives in the shadow root and never inherits a host attribute automatically, so the value is\ncopied onto it. Both spellings work: an `aria-label` attribute on `<lr-breadcrumb>` (which the\nattribute mapping also surfaces here) and a plain property assignment\n(`el.accessibleLabel = 'Docs trail'`). Wins over `label` and over the localized default\n(\"Breadcrumb\"); an explicitly empty `aria-label` attribute or an explicitly empty\n`accessibleLabel`/`label` property assignment stays empty rather than falling through.\n\nAttribute: `aria-label`","type":"string | undefined"},{"name":"label","description":"Accessible name matching both pinned upstream breadcrumb contracts. A host `aria-label`\nremains the highest-priority override. An explicitly empty string stays empty rather than\nfalling back to the localized default.\n\nAttribute: `label`","type":"string | undefined"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}]}},{"name":"lr-breadcrumb-item","description":"`<lr-breadcrumb-item>` — one link, button, or current-page label in a breadcrumb.\nA host `aria-label` is forwarded by attribute presence to the non-current\nnative link or button, including an explicitly empty value.\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) | Item label. |\n| `end` | Content after the label. |\n| `prefix` | Shoelace-compatible alias for `start`. |\n| `separator` | Decorative visual separator shown before non-first items; defaults to `/`. Content is always inert and aria-hidden, so it must not supply interactive behavior, a focus target, or form state. |\n| `start` | Content before the label. |\n| `suffix` | Shoelace-compatible alias for `end`. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The link, button, or current-page label. |\n| `end` | Wrapper around the `end` and `suffix` slots. |\n| `label` | Wrapper around the default label slot. |\n| `prefix` | Shoelace-compatible alias for `start`. |\n| `separator` | Decorative separator shown before non-first items. |\n| `start` | Wrapper around the `start` and `prefix` slots. |\n| `suffix` | Shoelace-compatible alias for `end`. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-breadcrumb-current-color` (default: `var(--lr-color-text-quiet)`) — Text color of the current-page item (`current`/`aria-current=\"page\"`). 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-text-quiet` token.\n- `--lr-breadcrumb-item-active-bg` — Link/button pressed background; defaults to the former transparent active mix.","attributes":[{"name":"current","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"href","description":"Optional URL. A safe URL renders a native anchor; an unset URL renders a native button for\nnon-current items. Assigning the upstream `undefined` spelling clears back to the canonical\nempty-string read value.\n\nType: `string | undefined`  \nDefault: `''`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"rel","description":"Author-settable link relationship, merged with a non-negotiable security floor: `opener` is\nalways stripped, and `noopener noreferrer` is force-added whenever `target` is set.\n\nDefaults to `'noreferrer noopener'`, which is what BOTH `wa-breadcrumb-item` and\n`sl-breadcrumb-item` declare — unlike `lr-button`, where the two upstreams disagree and Lyra\ntherefore keeps no default.\n\nType: `string`  \nDefault: `'noreferrer noopener'`","value":{"type":["string"]}},{"name":"target","description":"Native link target. When present, the rendered anchor always contributes\n`noopener noreferrer` to `rel` — author tokens are merged, not ignored (see `rel`).\n\nType: `LyraBreadcrumbItemTarget | undefined`","value":{"type":["'_blank'","'_parent'","'_self'","'_top'"]}}],"slots":[{"name":"","description":"Item label."},{"name":"end","description":"Content after the label."},{"name":"prefix","description":"Shoelace-compatible alias for `start`."},{"name":"separator","description":"Decorative visual separator shown before non-first items; defaults to `/`. Content is always inert and aria-hidden, so it must not supply interactive behavior, a focus target, or form state."},{"name":"start","description":"Content before the label."},{"name":"suffix","description":"Shoelace-compatible alias for `end`."}],"js":{"properties":[{"name":"current","description":"Attribute: `current`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"href","description":"Optional URL. A safe URL renders a native anchor; an unset URL renders a native button for\nnon-current items. Assigning the upstream `undefined` spelling clears back to the canonical\nempty-string read value.\n\nAttribute: `href`","type":"string | undefined","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"rel","description":"Author-settable link relationship, merged with a non-negotiable security floor: `opener` is\nalways stripped, and `noopener noreferrer` is force-added whenever `target` is set.\n\nDefaults to `'noreferrer noopener'`, which is what BOTH `wa-breadcrumb-item` and\n`sl-breadcrumb-item` declare — unlike `lr-button`, where the two upstreams disagree and Lyra\ntherefore keeps no default.\n\nAttribute: `rel`","type":"string","default":"'noreferrer noopener'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"target","description":"Native link target. When present, the rendered anchor always contributes\n`noopener noreferrer` to `rel` — author tokens are merged, not ignored (see `rel`).\n\nAttribute: `target`","type":"LyraBreadcrumbItemTarget | undefined"}]}},{"name":"lr-browser-frame","description":"`<lr-browser-frame>` — presentational \"agent computer\" viewport: a screenshot/frame stream (or\nslotted live media), read-only URL display, action-ping overlays, and take-over/stop affordances.\nNo automation transport, no input relay — take-over is an event; the host swaps in its own\ninteractive element.\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| (default) | Host-owned live element (e.g. `<video>` or an interactive `<iframe>`), replacing the `frame-src` image. |\n| `actions` | Extra toolbar controls. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `actions` | The `actions` slot wrapper. |\n| `base` | The root wrapper (`role=\"group\"`). |\n| `controller-badge` | The current controller indicator. |\n| `frame` | The `frame-src` `<img>` (absent once the default slot is populated). |\n| `ping` | One action-ping marker; carries `data-kind`. |\n| `status` | The visible, non-live status text. |\n| `stop-button` | The stop button. |\n| `take-over-button` | The take-over/hand-back button. |\n| `toolbar` | The header row. |\n| `url` | The read-only address text. |\n| `viewport` | The frame/media container. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-browser-frame-aspect-ratio` (default: `16 / 9`) — The viewport's aspect ratio.\n- `--lr-browser-frame-controller-background` (default: `var(--lr-color-brand-quiet)`) — Controller badge background.\n- `--lr-browser-frame-controller-color` (default: `var(--lr-color-brand)`) — Controller badge text color.\n- `--lr-browser-frame-ping-click-color` (default: `var(--lr-color-brand)`) — Click-ping border color.\n- `--lr-browser-frame-ping-move-color` (default: `var(--lr-color-text-quiet)`) — Move-ping border color.\n- `--lr-browser-frame-ping-scroll-color` (default: `var(--lr-color-warning)`) — Scroll-ping border color.\n- `--lr-browser-frame-ping-type-color` (default: `var(--lr-color-success)`) — Type-ping border color.","attributes":[{"name":"controller","description":"Type: `BrowserFrameController`  \nDefault: `'agent'`","value":{"type":["'agent'","'user'"]}},{"name":"controls","description":"Type: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"frame-src","description":"Type: `string`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"phase","description":"Type: `LyraStreamPhase`","value":{"type":["'idle'","'connecting'","'streaming'","'stalled'"]}},{"name":"url","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}}],"slots":[{"name":"","description":"Host-owned live element (e.g. `<video>` or an interactive `<iframe>`), replacing the `frame-src` image."},{"name":"actions","description":"Extra toolbar controls."}],"js":{"properties":[{"name":"controller","description":"Attribute: `controller`  \nReflected to its attribute.","type":"BrowserFrameController","default":"'agent'"},{"name":"controls","description":"Attribute: `controls`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"frameSrc","description":"Attribute: `frame-src`","type":"string"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"phase","description":"Attribute: `phase`  \nReflected to its attribute.","type":"LyraStreamPhase"},{"name":"pings","description":"Pointer markers keyed by stable id. Empty/blank ids are omitted and duplicates normalize\nfirst-wins before rendering.","type":"readonly BrowserPing[]","default":"[]"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"url","description":"Attribute: `url`","type":"string","default":"''"}],"events":[{"name":"lr-stop","description":"Stop the agent's browser session.","type":"CustomEvent<null>"},{"name":"lr-take-over","description":"`detail: { controller }` — the *requested* controller.","type":"CustomEvent<{ controller: BrowserFrameController }>"}]}},{"name":"lr-bubble-chart","description":"`<lr-bubble-chart>` — `<lr-chart>` with a `\"bubble\"` default and the mirrored writable type. Feed\npoints via `LyraChartSeries.points`, whose exported `LyraChartPoint` type carries\n`x`/`y`, optional bubble `r` (radius), and an optional per-point `label`.\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) | An optional `<script type=\"application/json\">` containing a Chart.js configuration. |\n| `center` | Optional overlay content positioned at the chart area's center. Useful for doughnut and pie totals. |\n| `data-table` | An optional consumer-provided accessible table alternative. Use this escape hatch for a complete paginated or virtualized alternative when the generated 1,000-record sample is insufficient. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The chart wrapper. |\n| `canvas` | The Chart.js canvas. |\n| `center` | The chart-area-centered overlay wrapper for the `center` slot. |\n| `data-table` | The optional generated or slotted data table. |\n| `data-table-toggle` | The disclosure button rendered by `dataTableToggle`. |\n| `data-truncation` | Explanation shown when the generated accessible alternative samples a data set larger than its 1,000-record ceiling. |\n| `description` | The accessible chart summary. |\n| `error` | Static visible error shown instead of `canvas` when the optional `chart.js` peer dependency is not installed; its transition is announced through a shared light-DOM alert. |\n| `feature-warning` | Static nonfatal warning when a requested optional feature peer is unavailable while the core chart remains usable. |\n| `legend` | The wrapping DOM legend, rendered unless `withoutLegend` is set. |\n| `legend-item` | A keyboard-operable dataset or category visibility toggle. |\n| `legend-item-hidden` | Added while the legend item's dataset or category is hidden. |\n| `legend-swatch` | The resolved dataset/category color swatch in a legend item. |\n| `notices` | Wrapper for nonfatal feature warnings and generated-data truncation notices. |\n| `plot` | The fixed-height canvas/overlay region. |\n| `reset-zoom-button` | The reset-zoom control when zoom is active. |\n\n---\n\n**CSS Custom Properties**\n\n- `--border-color-1` (default: `var(--lr-color-chart-1)`) — First dataset border color.\n- `--border-color-2` (default: `var(--lr-color-chart-2)`) — Second dataset border color.\n- `--border-color-3` (default: `var(--lr-color-chart-3)`) — Third dataset border color.\n- `--border-color-4` (default: `var(--lr-color-chart-4)`) — Fourth dataset border color.\n- `--border-color-5` (default: `var(--lr-color-chart-5)`) — Fifth dataset border color.\n- `--border-color-6` (default: `var(--lr-color-chart-6)`) — Sixth dataset border color.\n- `--border-radius` (default: `var(--lr-radius)`) — Dataset element corner radius.\n- `--border-width` (default: `var(--lr-border-width-thin)`) — Dataset element border width.\n- `--fill-color-1` (default: `var(--lr-color-chart-1)`) — First dataset fill color.\n- `--fill-color-2` (default: `var(--lr-color-chart-2)`) — Second dataset fill color.\n- `--fill-color-3` (default: `var(--lr-color-chart-3)`) — Third dataset fill color.\n- `--fill-color-4` (default: `var(--lr-color-chart-4)`) — Fourth dataset fill color.\n- `--fill-color-5` (default: `var(--lr-color-chart-5)`) — Fifth dataset fill color.\n- `--fill-color-6` (default: `var(--lr-color-chart-6)`) — Sixth dataset fill color.\n- `--grid-border-width` (default: `var(--lr-border-width-thin)`) — Axis and grid line width.\n- `--grid-color` (default: `var(--lr-chart-grid-color)`) — Grid line color.\n- `--line-border-width` (default: `var(--lr-border-width-medium)`) — Line dataset stroke width.\n- `--lr-chart-canvas-hover-outline-color` (default: `var(--lr-chart-grid-color)`) — Color of the `[part='canvas']` hover-state outline.\n- `--lr-chart-canvas-hover-outline-width` (default: `var(--lr-border-width-thin)`) — Width of the `[part='canvas']` hover-state outline.\n- `--lr-chart-data-table-button-active-bg` — Pressed background of an actionable generated- table value; defaults to the standard active mix of `--lr-color-brand-quiet`.\n- `--lr-chart-data-table-button-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background of an actionable generated-table value.\n- `--lr-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-chart-data-table-toggle-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background of the `dataTableToggle` disclosure button.\n- `--lr-chart-grid-color` (default: `var(--lr-color-border)`) — Grid-line color. Resolved via `getComputedStyle` on every draw (Chart.js paints to canvas and cannot consume `var()`).\n- `--lr-chart-height` (default: `var(--lr-size-280px)`) — The plot region's `block-size` and the host's minimum block size. A visible data table or wrapping DOM legend grows the host in normal flow instead of overlapping following content. `height` supplies a private fallback; this public token always wins when a consumer sets it.\n- `--lr-chart-legend-color` (default: `var(--lr-color-text)`) — Legend label color. Resolved via `getComputedStyle` on every draw.\n- `--lr-chart-legend-item-active-bg` — Pressed background of a legend visibility button; defaults to the standard active mix of `--lr-color-brand-quiet`.\n- `--lr-chart-legend-item-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background of a legend visibility button.\n- `--lr-chart-legend-side-max` (default: `var(--lr-size-15rem)`) — Maximum inline size reserved for a side-positioned DOM legend; the track is also capped at one third of the chart allocation.\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 every series collapses to one system color and the stripe/crosshatch pattern 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.\n- `--lr-chart-reset-zoom-button-active-bg` — Pressed background of the reset-zoom button; defaults to the standard active mix of `--lr-color-brand-quiet`.\n- `--lr-chart-reset-zoom-button-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background of the reset-zoom button.\n- `--lr-chart-tick-color` (default: `var(--lr-color-text-quiet)`) — Axis tick-label color; also used for the `xLabel`/`yLabel`/`y2Label` axis-title text (there is no separate title-color token). Resolved via `getComputedStyle` on every draw.\n- `--lr-chart-tick-font-size` (default: `var(--lr-font-size-xs)`) — Axis tick-label font size, in any CSS length unit. Defaults to `--lr-font-size-xs` (12px at the standard root) because that matches Chart.js's OWN built-in tick font size, which is what every canvas chart rendered before this token existed -- leaving it unset must stay byte-identical to that, not shrink to `<lr-lite-chart>`'s SVG default. Also sizes the radar/polarArea `r`-scale `pointLabels` (the spoke labels), but ONLY once set: those default separately to Chart.js's OWN distinct `RadialLinearScale` `pointLabels` default (10px, not this token's 12px), and only adopt this token's size once the consumer explicitly sets it, at which point ticks and point labels match. Resolved via `getComputedStyle` on every draw, same constraint as every other `--lr-chart-*` token here (Chart.js paints to canvas and cannot consume `var()`).\n- `--lr-chart-tooltip-bg` (default: `var(--lr-color-surface)`) — Tooltip background color. Resolved via `getComputedStyle` on every draw.\n- `--lr-chart-tooltip-text` (default: `var(--lr-color-text)`) — Tooltip text color. Resolved via `getComputedStyle` on every draw.\n- `--point-radius` (default: `var(--lr-space-2xs)`) — Line/scatter point radius.","attributes":[{"name":"area","description":"Chart-wide default fill-under-line setting for line-type series; a series's own `LyraChartSeries.fill` overrides it.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"axes","description":"Complete cartesian axis visibility, independent of grid. `y` also controls the y2 axis.\nRadial charts ignore this setting. Explicit config scale options retain precedence.\n\nType: `LyraChartAxes`  \nDefault: `'both'`","value":{"type":["'x'","'y'","'both'","'none'"]}},{"name":"begin-at-zero","description":"Type: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"compact","description":"Compact cartesian plot: hide axes and remove automatic layout padding. Set height and\nwithoutLegend for a small histogram/sparkline. Preserves data tables, tooltips and keyboard\nactions; radial charts ignore this setting. Explicit config options retain precedence.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"data-labels","description":"Draws each data point's value on the chart via the optional\n`chartjs-plugin-datalabels` peer. Unset (the default) leaves labels off for\nthis chart; the peer is attached only to instances that opt in, and\n`buildConfig()` keeps its per-chart options disabled until this is set. The\nscreen-reader equivalent is the always-present data table (see\n`show-data-table`); labels are a purely visual, canvas-only addition.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"data-table-toggle","description":"Render a disclosure button above the accessible data table so a sighted reader can reveal the\nnumbers behind the chart on demand. `showDataTable` alone is all-or-nothing -- the table is\neither permanently screen-reader-only or permanently visible -- which left a consumer wrapping\na duplicated table in their own `<details>`.\n\nWith this set, `showDataTable` becomes the disclosure's *initial* state rather than its whole\nbehavior. The table stays in the DOM in both states, so assistive technology never loses it.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"description","description":"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`"},{"name":"grid","description":"Controls which cartesian grid axes are drawn.\n\nType: `LyraChartGrid`  \nDefault: `'both'`","value":{"type":["'x'","'y'","'both'","'none'"]}},{"name":"height","description":"Type: `string`  \nDefault: `'280px'`","value":{"type":["string"]}},{"name":"index-axis","description":"Chart.js index axis. `'y'` is Chart.js's own mechanism for horizontal bars (it also flips\nline/area types onto a horizontal category axis).\n\nType: `LyraChartIndexAxis`  \nDefault: `'x'`","value":{"type":["'x'","'y'"]}},{"name":"label","description":"Accessible chart label. A host `aria-label` still has highest precedence.\n\nType: `string | null`  \nDefault: `null`"},{"name":"legend-display","description":"`auto` retains optional legend formatting; `label` omits values even with a formatter; `value`\nappends a formatted value. `percentage` uses locale percentages of the absolute represented\nlegend values, including hidden items (zero totals yield 0%). `value-percentage` appends both,\nas `label: value (percentage)`. Dataset values are sampled sums; category values come from the\nfirst dataset. The `formatter`/`valueFormatter` callback backing `value` and `value-percentage`\nadditionally receives that same `percentage` in its `surface: 'legend'` context, so a custom\nformatter can build its own combined text without recomputing the share. Tooltip and axis\nformatting are unchanged.\n\nType: `LyraChartLegendDisplay`  \nDefault: `'auto'`","value":{"type":["'auto'","'label'","'value'","'percentage'","'value-percentage'"]}},{"name":"legend-mode","description":"`datum` renders category toggles for pie/doughnut/polar-area charts. Categories use the first\ndataset's colors and values; a toggle affects that category in every ring. Other chart types\nretain dataset legends. `auto` (the default) resolves to `datum` on pie/doughnut/polar-area\ncharts -- where a single-dataset legend would otherwise enumerate one entry for the whole\ndataset instead of one per visible slice -- and to `dataset` everywhere else. `dataset` always\nforces the dataset legend, even on a slice chart. Both non-`auto` modes use the generated\naccessible-data sampling budget.\n\nType: `LyraChartLegendMode`  \nDefault: `'auto'`","value":{"type":["'auto'","'dataset'","'datum'"]}},{"name":"legend-position","description":"Legend placement. `auto` uses a right legend above 480px and a bottom legend below it.\n\nType: `LyraChartLegendPosition`  \nDefault: `'top'`","value":{"type":["'left'","'top'","'right'","'bottom'","'center'","'chartArea'","'start'","'end'","'auto'"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max","description":"Maximum value-axis bound. Non-finite values are ignored.\n\nType: `number | null`  \nDefault: `null`"},{"name":"min","description":"Minimum value-axis bound. Non-finite values are ignored.\n\nType: `number | null`  \nDefault: `null`"},{"name":"plugins","description":"Chart.js plugins attached to this chart instance. Valid plugins retain their opaque identity.\n\nType: `readonly LyraChartPlugin[]`  \nDefault: `[]`"},{"name":"scale-type","description":"Scale type for the **value** axis (the categorical axis is unaffected). `'logarithmic'` plots\na dataset spanning several orders of magnitude honestly, where a linear axis collapses\neverything below the maximum into the baseline. Inherited by `lr-line-chart`,\n`lr-scatter-chart` and `lr-bar-chart`.\n\nA logarithmic axis cannot represent zero or negative values (`log(0)` is `-Infinity`), so\n`beginAtZero` is not forwarded in that mode -- Chart.js would otherwise be handed a bound it\ncannot place. Non-positive data points are dropped by Chart.js's own log scale.\n\nType: `LyraChartScaleType`  \nDefault: `'linear'`","value":{"type":["'linear'","'logarithmic'"]}},{"name":"show-data-table","description":"Makes the generated data table visible; it remains screen-reader available when false.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"stack-totals","description":"When the chart is `stacked` (bar/line only), draws the per-category stack\ntotal above each stack, via the same optional `chartjs-plugin-datalabels`\npeer as `data-labels`. Null/undefined points are skipped; a category whose\nevery value is null shows no total. The generated accessible data table\nreceives the same formatted total column (one per value axis). Unset (the\ndefault) draws and adds nothing.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"stacked","description":"Stacks the `x`/`y`(/`y2`) scale entries `buildScales()` returns; only meaningful for `bar` and `line` types.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"type","description":"Type: `LyraChartType`  \nDefault: `'bubble'`","value":{"type":["'line'","'bar'","'scatter'","'pie'","'doughnut'","'radar'","'polarArea'","'bubble'"]}},{"name":"without-animation","description":"Disables Chart.js animation.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"without-legend","description":"Hides the legend.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"without-tooltip","description":"Hides Chart.js tooltips.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"x-label","description":"Type: `string | null`  \nDefault: `null`"},{"name":"y-label","description":"Type: `string | null`  \nDefault: `null`"},{"name":"y2-label","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"zoom","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"","description":"An optional `<script type=\"application/json\">` containing a Chart.js configuration."},{"name":"center","description":"Optional overlay content positioned at the chart area's center. Useful for doughnut and pie totals."},{"name":"data-table","description":"An optional consumer-provided accessible table alternative. Use this escape hatch for a complete paginated or virtualized alternative when the generated 1,000-record sample is insufficient."}],"js":{"properties":[{"name":"annotations","description":"Declarative reference lines and shaded bands — a threshold, an event year, a regime change, a\nhighlighted period. Each entry marks either a single `value` or a `from`/`to` range on `axis`\n(default `'y'`), with an optional `label` and semantic `tone`.\n\nNeeds the optional `chartjs-plugin-annotation` peer, loaded on first actual demand so a page\nwith no annotated charts never downloads it. The plugin is registered globally, like\n`chartjs-plugin-zoom` and unlike `chartjs-plugin-datalabels`: it draws nothing unless a chart\nsupplies annotation options, so the registration is unobservable to charts that set none, and\nregistration is also what installs the plugin's own element defaults. Without the peer\ninstalled the chart still renders; a console warning plus a localized visible warning and\nlight-DOM announcement explain the no-op — the same fail-closed contract `data-labels` uses.\n\nEntries are included in the generated accessible description, mirroring `lr-heatmap`.","type":"readonly LyraChartAnnotation[]","default":"[]"},{"name":"area","description":"Chart-wide default fill-under-line setting for line-type series; a series's own `LyraChartSeries.fill` overrides it.\n\nAttribute: `area`","type":"boolean","default":"false"},{"name":"axes","description":"Complete cartesian axis visibility, independent of grid. `y` also controls the y2 axis.\nRadial charts ignore this setting. Explicit config scale options retain precedence.\n\nAttribute: `axes`","type":"LyraChartAxes","default":"'both'"},{"name":"beginAtZero","description":"Attribute: `begin-at-zero`","type":"boolean","default":"true"},{"name":"chart","description":"The current Chart.js instance. Read it only while the element is connected and loaded.","type":"LyraChartInstance | undefined"},{"name":"chartArea","description":"The current Chart.js chart-area geometry in canvas-local coordinates. Read-only -- derived\nfrom the live Chart.js instance's own layout pass, never assignable. The setter is a\ndocumented no-op (matching `lr-histogram`'s `labels`/`datasets` pattern) so an accidental\n`.chartArea=${x}` Lit template binding degrades silently instead of throwing from inside\nlit-html's property-commit.","type":"LyraChartArea | undefined"},{"name":"compact","description":"Compact cartesian plot: hide axes and remove automatic layout padding. Set height and\nwithoutLegend for a small histogram/sparkline. Preserves data tables, tooltips and keyboard\nactions; radial charts ignore this setting. Explicit config options retain precedence.\n\nAttribute: `compact`","type":"boolean","default":"false"},{"name":"config","type":"LyraChartConfiguration | undefined"},{"name":"dataLabels","description":"Draws each data point's value on the chart via the optional\n`chartjs-plugin-datalabels` peer. Unset (the default) leaves labels off for\nthis chart; the peer is attached only to instances that opt in, and\n`buildConfig()` keeps its per-chart options disabled until this is set. The\nscreen-reader equivalent is the always-present data table (see\n`show-data-table`); labels are a purely visual, canvas-only addition.\n\nAttribute: `data-labels`","type":"boolean","default":"false"},{"name":"dataTableToggle","description":"Render a disclosure button above the accessible data table so a sighted reader can reveal the\nnumbers behind the chart on demand. `showDataTable` alone is all-or-nothing -- the table is\neither permanently screen-reader-only or permanently visible -- which left a consumer wrapping\na duplicated table in their own `<details>`.\n\nWith this set, `showDataTable` becomes the disclosure's *initial* state rather than its whole\nbehavior. The table stays in the DOM in both states, so assistive technology never loses it.\n\nAttribute: `data-table-toggle`","type":"boolean","default":"false"},{"name":"datasets","description":"Simplified chart series. Non-record entries are dropped while valid sibling series remain.","type":"readonly LyraChartSeries[]"},{"name":"description","description":"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\nAttribute: `description`","type":"string | null","default":"null"},{"name":"formatter","description":"Unified context-object formatter for visual, tooltip, table/export, and spoken values.","type":"LyraChartFormatter | undefined"},{"name":"grid","description":"Controls which cartesian grid axes are drawn.\n\nAttribute: `grid`","type":"LyraChartGrid","default":"'both'"},{"name":"height","description":"Attribute: `height`","type":"string","default":"'280px'"},{"name":"hiddenDatasets","description":"Complete controlled visibility state for DOM legend toggles. `undefined` (the default) honors\neach effective dataset's `hidden` configuration; a defined array wins over those defaults, and\nan empty array deliberately makes every dataset visible. Invalid, duplicate, and out-of-range\nindexes are ignored when state is applied or emitted.","type":"readonly number[] | undefined"},{"name":"hiddenDatums","description":"Controlled hidden source category indexes for pie/doughnut/polar-area charts, shared by all\ndatasets/rings. Clone-owned; invalid, duplicate and out-of-range indexes are ignored when\napplied or emitted. Empty restores all categories. Does not alter dataset visibility or exports.","type":"readonly number[]","default":"[]"},{"name":"indexAxis","description":"Chart.js index axis. `'y'` is Chart.js's own mechanism for horizontal bars (it also flips\nline/area types onto a horizontal category axis).\n\nAttribute: `index-axis`","type":"LyraChartIndexAxis","default":"'x'"},{"name":"label","description":"Accessible chart label. A host `aria-label` still has highest precedence.\n\nAttribute: `label`","type":"string | null","default":"null"},{"name":"labels","type":"string[]","default":"[]"},{"name":"legendDisplay","description":"`auto` retains optional legend formatting; `label` omits values even with a formatter; `value`\nappends a formatted value. `percentage` uses locale percentages of the absolute represented\nlegend values, including hidden items (zero totals yield 0%). `value-percentage` appends both,\nas `label: value (percentage)`. Dataset values are sampled sums; category values come from the\nfirst dataset. The `formatter`/`valueFormatter` callback backing `value` and `value-percentage`\nadditionally receives that same `percentage` in its `surface: 'legend'` context, so a custom\nformatter can build its own combined text without recomputing the share. Tooltip and axis\nformatting are unchanged.\n\nAttribute: `legend-display`","type":"LyraChartLegendDisplay","default":"'auto'"},{"name":"legendMode","description":"`datum` renders category toggles for pie/doughnut/polar-area charts. Categories use the first\ndataset's colors and values; a toggle affects that category in every ring. Other chart types\nretain dataset legends. `auto` (the default) resolves to `datum` on pie/doughnut/polar-area\ncharts -- where a single-dataset legend would otherwise enumerate one entry for the whole\ndataset instead of one per visible slice -- and to `dataset` everywhere else. `dataset` always\nforces the dataset legend, even on a slice chart. Both non-`auto` modes use the generated\naccessible-data sampling budget.\n\nAttribute: `legend-mode`","type":"LyraChartLegendMode","default":"'auto'"},{"name":"legendPosition","description":"Legend placement. `auto` uses a right legend above 480px and a bottom legend below it.\n\nAttribute: `legend-position`","type":"LyraChartLegendPosition","default":"'top'"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"max","description":"Maximum value-axis bound. Non-finite values are ignored.\n\nAttribute: `max`","type":"number | null","default":"null"},{"name":"min","description":"Minimum value-axis bound. Non-finite values are ignored.\n\nAttribute: `min`","type":"number | null","default":"null"},{"name":"plugins","description":"Chart.js plugins attached to this chart instance. Valid plugins retain their opaque identity.\n\nAttribute: `plugins`","type":"readonly LyraChartPlugin[]","default":"[]"},{"name":"scaleType","description":"Scale type for the **value** axis (the categorical axis is unaffected). `'logarithmic'` plots\na dataset spanning several orders of magnitude honestly, where a linear axis collapses\neverything below the maximum into the baseline. Inherited by `lr-line-chart`,\n`lr-scatter-chart` and `lr-bar-chart`.\n\nA logarithmic axis cannot represent zero or negative values (`log(0)` is `-Infinity`), so\n`beginAtZero` is not forwarded in that mode -- Chart.js would otherwise be handed a bound it\ncannot place. Non-positive data points are dropped by Chart.js's own log scale.\n\nAttribute: `scale-type`","type":"LyraChartScaleType","default":"'linear'"},{"name":"showDataTable","description":"Makes the generated data table visible; it remains screen-reader available when false.\n\nAttribute: `show-data-table`","type":"boolean","default":"false"},{"name":"stackTotals","description":"When the chart is `stacked` (bar/line only), draws the per-category stack\ntotal above each stack, via the same optional `chartjs-plugin-datalabels`\npeer as `data-labels`. Null/undefined points are skipped; a category whose\nevery value is null shows no total. The generated accessible data table\nreceives the same formatted total column (one per value axis). Unset (the\ndefault) draws and adds nothing.\n\nAttribute: `stack-totals`","type":"boolean","default":"false"},{"name":"stacked","description":"Stacks the `x`/`y`(/`y2`) scale entries `buildScales()` returns; only meaningful for `bar` and `line` types.\n\nAttribute: `stacked`","type":"boolean","default":"false"},{"name":"stackedAxes","description":"Per-value-axis override of `stacked`, keyed by `'y'`/`'y2'`. An axis absent from this record\n-- including every axis when the whole property is unset -- falls back to the chart-wide\n`stacked` value, which is what keeps a chart that never sets this byte-identical to before.\nLets a `stacked` bar series on the primary axis sit next to an unstacked overlay series on\n`y2` (via `LyraChartSeries.axis: 'y2'`): set `stackedAxes` to `{ y2: false }` alongside\n`stacked`, or spell out both axes explicitly. The shared categorical axis (`x` for a vertical\nbar/line, or `y` when `indexAxis` is `'y'`) has no independent entry of its own -- it always\nmirrors the resolved `'y'` value, matching Chart.js's own paired index/value-scale stacking\ncontract. Only meaningful for `bar`/`line` types, matching `stacked` itself.","type":"Partial<Record<'y' | 'y2', boolean>> | undefined"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"tooltipFooterFormatter","description":"Tooltip footer formatter -- e.g. a category's stack total under the items. Receives every\nitem the hovered tooltip covers, in the same shape as `tooltipTitleFormatter`. Unset (the\ndefault) leaves Chart.js's own default (no footer).","type":"LyraChartTooltipGroupFormatter | undefined"},{"name":"tooltipTitleFormatter","description":"Tooltip title formatter -- e.g. a scatter point's own name. Receives every item the hovered\ntooltip covers, each in `formatter`'s `'tooltip'`-surface context shape. Unset (the default)\nleaves Chart.js's own default title (the shared category label) in place.","type":"LyraChartTooltipGroupFormatter | undefined"},{"name":"type","description":"Attribute: `type`","type":"LyraChartType","default":"'bubble'"},{"name":"valueFormatter","description":"Formats numeric (value-axis) ticks, tooltip values, legend values, and generated accessible\ntable cells from one callback.\nHorizontal scalar tooltips use parsed x, including a raw config indexAxis override;\nstructured points retain their y-value contract. The context-object formatter shares this rule.\nNever runs against the categorical x-axis's own labels (line/bar's `labels` strings) —\nChart.js's category scale passes the tick index to `ticks.callback`, not the label text,\nso formatting it would corrupt the axis.","type":"LyraChartValueFormatter | undefined"},{"name":"withoutAnimation","description":"Disables Chart.js animation.\n\nAttribute: `without-animation`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"withoutLegend","description":"Hides the legend.\n\nAttribute: `without-legend`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"withoutTooltip","description":"Hides Chart.js tooltips.\n\nAttribute: `without-tooltip`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"xLabel","description":"Attribute: `x-label`","type":"string | null","default":"null"},{"name":"y2Label","description":"Attribute: `y2-label`","type":"string","default":"''"},{"name":"yLabel","description":"Attribute: `y-label`","type":"string | null","default":"null"},{"name":"zoom","description":"Attribute: `zoom`","type":"boolean","default":"false"}],"events":[{"name":"lr-before-datum-visibility-change","description":"Cancelable category visibility proposal in datum legend mode. `detail: { index: number, visible: boolean, hiddenDatums: readonly number[] }`. Source category indexes apply to every dataset/ring. The complete detail is frozen.","type":"CustomEvent<LyraChartDatumVisibilityChangeDetail>"},{"name":"lr-before-legend-visibility-change","description":"Cancelable proposal emitted before a DOM legend toggle changes state. `detail` contains the target `datasetIndex`, its proposed `visible` value, and the complete canonical proposed `hiddenDatasets` snapshot.","type":"CustomEvent<LyraChartLegendVisibilityChangeDetail>"},{"name":"lr-datum-activate","description":"Family-normalized activation event. Its detail adds `kind` (`bar`, `point`, `segment`, or `slice`) to the `lr-point-click` detail.","type":"CustomEvent<\n    LyraChartDatumActivateDetail<LyraCoreChartDatumKind>\n  >"},{"name":"lr-datum-visibility-change","description":"Emitted after an accepted category toggle commits the same frozen detail. Programmatic `hiddenDatums` assignments are silent.","type":"CustomEvent<LyraChartDatumVisibilityChangeDetail>"},{"name":"lr-legend-visibility-change","description":"Emitted after an accepted DOM legend toggle commits the same detail. Programmatic `hiddenDatasets` changes reconcile without either event.","type":"CustomEvent<LyraChartLegendVisibilityChangeDetail>"},{"name":"lr-point-click","description":"Fired when pointer input lands on a data point/segment, when a generated data-table value is activated, or when Enter/Space activates the keyboard-current canvas datum. `detail: { datasetIndex: number, index: number, label: string | undefined, value: unknown }`. For scatter/bubble data, `label` prefers the per-point label and `value` is the complete typed `LyraChartPoint` (`x`, `y`, optional `r`, optional `label`).","type":"CustomEvent<{\n    datasetIndex: number;\n    index: number;\n    label: string | undefined;\n    value: unknown;\n  }>"},{"name":"lr-zoom","description":"`detail: { zoomed }`.","type":"CustomEvent<{ zoomed: boolean }>"}]}},{"name":"lr-button","description":"`<lr-button>` — a generic action-button primitive. Renders an internal native\n`<button part=\"base\">`. `type=\"submit\"`/`type=\"reset\"`\nare handled by this component itself via the host's associated form — a shadow-internal\nnative `<button type=\"submit\">` does not participate in an ancestor light-DOM form's submission\non its own, since form-submitter semantics don't cross the shadow boundary.\nSubmit and reset remain default actions of the composed native `click`: any listener on that\nclick path can call `preventDefault()` to veto them, while stopping propagation alone does not.\nForm-level `submit`/`reset` cancellation remains a separate, later veto point.\n\nA submit button that carries `name`/`value` or any of the `form*` submission overrides\n(`formaction`/`formenctype`/`formmethod`/`formnovalidate`/`formtarget`) submits through a\ntransient native `<button type=\"submit\">` inserted directly after the host, used as\n`requestSubmit()`'s submitter and removed again in the same synchronous step. That is what makes\nthe name/value pair reach the submitted `FormData` and the overrides reach the real submission:\n`requestSubmit()` can only take a submitter the form actually owns, and a custom element is never\none. While that submitter exists it *is* the form's submitter, so `SubmitEvent.submitter` is the\ntransient native button rather than this host. With none of those properties set, submission\nstays a plain `requestSubmit()` with a `null` submitter.\n\nWhen `href` is set to a safe link URL (`http:`/`https:`/`blob:`/`mailto:`/relative — see\n`safeLinkHref`, or `safeDownloadHref` which drops `mailto:` when `download` is set) the root\nrenders as a real `<a part=\"base\" href=…>` instead — for a link styled\nas a button (e.g. a CTA). Native navigation is then the anchor's own activation, so the\nsubmit/reset click handler and `type` (submit/reset) have no effect in that mode. When the\nbutton is disabled (its own `disabled` or an ancestor `<fieldset disabled>`) the anchor renders\nwith `aria-disabled=\"true\"` and **no `href`** — an href-less anchor is not focusable or\nnavigable, so a disabled link button genuinely cannot be activated (unlike a bare\n`aria-disabled` on a still-navigable link). It also dims to `--lr-opacity-disabled` with a\n`not-allowed` cursor and drops its hover/press feedback, exactly as the native `<button>` path\ndoes — an `<a>` can never match the `:disabled` pseudo-class, so that arm of the disabled\nstyling is keyed off `aria-disabled` instead. An unsafe/unparseable `href` falls back to the\nnative `<button>`.\n\n`accessibleLabel` (attribute `aria-label`) is forwarded reactively to the internal button/anchor\nas a literal string (for an icon-only button with no visible label). Host `aria-describedby`\nIDREFs are resolved through `ariaDescribedByElements`; external `aria-labelledby` is not copied\nacross the shadow boundary.\nDescription targets follow same-ID replacement, removal, reinsertion, reconnection and document\nadoption, including transitions between the native button and anchor.\nHost `aria-haspopup` and `aria-expanded` values are likewise forwarded to the internal semantic\ncontrol. `aria-pressed` (`true`, `false`, `mixed`) supports button toggles; `aria-current`\n(`page`, `step`, `location`, `date`, `time`, `true`, `false`) supports current navigation.\nThese states follow attribute changes, removal and button/link replacement without changing\nthe native role. Empty or unsupported state tokens are omitted from the internal control.\nWhen host `aria-controls` names elements in the host's own root, the controls\nrelationship is resolved onto the internal control through the reflected element-reference API\nso it remains valid across this component's shadow boundary. Assigning that relationship\nintentionally clears the serialized `aria-controls` value; read `ariaControlsElements` in a\nsupporting browser. Browsers without that API retain the forwarded string attribute as a\nbest-effort fallback.\nCircle and automatically detected icon-only buttons keep the shared\n`--lr-icon-button-size` minimum target in every `size` tier; the tier still scales their glyph\nand chrome, but cannot collapse the clickable box below that floor.\nIn a constrained row the default-slot label ellipsizes (set `wrap` for a multi-line label\ninstead), while each `start`/`end` adornment is capped at 40% of the control so unbroken\nconsumer content cannot force the button wider.\nThe label does **not** grow to fill a stretched button: icon and label centre together under\n`--lr-button-justify`. A `with-caret` button, and one with an `end`/`suffix` adornment, keep the\nold growing label so that trailing affordance stays pinned to the trailing content edge;\n`--lr-button-label-grow` overrides both directions.\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) | Default slot: the button's label content. |\n| `end` | Trailing icon/content, rendered after the label. |\n| `prefix` | Shoelace alias for `start`, rendered through the same wrapper. |\n| `start` | Leading icon/content, rendered before the label. |\n| `suffix` | Shoelace alias for `end`, rendered through the same wrapper. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | Compatibility name for the internal control; use `button`. |\n| `button` | The internal native `<button>` (or an `<a>` for a safe link). It is the same node as `base`. Circle and icon-only states retain the shared minimum icon-button target. |\n| `caret` | The decorative dropdown chevron, present only while `withCaret` is `true`. |\n| `end` | The `end` slot wrapper. |\n| `label` | The default-slot label wrapper. |\n| `prefix` | Shoelace alias for `start`; both names are on the same wrapper. |\n| `spinner` | The loading spinner, present only while `loading` is `true`. |\n| `start` | The `start` slot wrapper. |\n| `suffix` | Shoelace alias for `end`; both names are on the same wrapper. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-button-accent` (default: `var(--lr-color-fill-loud)`) — Text/glyph color for the chrome-less appearances (`outlined`, `plain`, `link`), i.e. the active `variant`'s loud fill used as a foreground. `variant=\"neutral\"` is the one exception: its loud fill is a mid grey picked to carry light text, so borrowing it as text on the page surface would wash out every plain and link button — neutral keeps `--lr-color-text`.\n- `--lr-button-accent-fill` (default: `var(--lr-color-fill-loud)`) — Background of `appearance=\"accent\"` (and its border color): the active `variant`'s loud fill, the one primary action in a view.\n- `--lr-button-accent-on-fill` (default: `var(--lr-color-on-loud)`) — Text color on top of `--lr-button-accent-fill`, the grid's guaranteed-legible foreground for that fill.\n- `--lr-button-active-background` (default: `color-mix(in oklab, var(--lr-button-hover-base), var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Background while a non-disabled button is pressed — the same mix at the stronger `--lr-color-mix-active` share, so the pressed state reads as more than the hover. `appearance=\"link\"` moves its text colour by these two shares instead of taking a background.\n- `--lr-button-active-scale` (default: `0.9875`) — `transform: scale()` factor applied while a non-disabled button is pressed.\n- `--lr-button-border` (default: `var(--lr-color-border-normal)`) — Border color of the internal button, from the active `variant`'s row of the shared semantic grid.\n- `--lr-button-caret-size` (default: `var(--lr-size-0-75em)`) — Font size of the `with-caret` chevron, i.e. its rendered glyph box. Relative to the button's own font size, so it follows every `size` tier without a per-tier rule.\n- `--lr-button-fill` (default: `var(--lr-color-fill-quiet)`) — Background of `appearance=\"filled\"`: the active `variant`'s quiet tint, i.e. a secondary-action fill that is visibly a fill rather than the page surface. Follows `variant` through the shared semantic grid.\n- `--lr-button-font-size` (default: `var(--lr-form-control-font-size)`) — Font size of the internal button, from the active `size` tier. `appearance=\"link\"` ignores it and inherits the ambient font instead.\n- `--lr-button-gap` (default: `var(--lr-form-control-gap)`) — Gap between the icon/label and any slotted content in the internal button. Constant across the ladder's tiers. Override it to retune without a `::part(base)` rule.\n- `--lr-button-height` — Exact height of the internal button. **Undeclared by default** — so the button keeps the active tier's `min-block-size` floor and an `auto` height, exactly as before. Set it (e.g. to pin the button to a fixed toolbar row) to both floor *and* cap the height. Never declare it as `auto`: a declared value wins over the `var()` fallback arm and would make every tier's floor dead code. `appearance=\"link\"` ignores it.\n- `--lr-button-hover-background` (default: `color-mix(in oklab, var(--lr-button-hover-base), var(--lr-color-mix-partner) var(--lr-color-mix-hover))`) — Background of a non-disabled button while hovered. Replaced the pre-8.0.0 `--lr-button-hover-brightness` multiplier: a `filter` multiplies every channel, so it moved a mid-toned fill but did nothing at all to a pure white or pure black one, and it dimmed the label and icons along with the box.\n- `--lr-button-hover-base` (default: `var(--lr-color-surface)`) — The colour the hover and press mixes move away from. Each painted appearance re-points it at its own fill (`--lr-button-fill` for `filled`/`filled-outlined`, `--lr-button-accent-fill` for `accent`); the chrome-less tiers (`outlined`, `plain`, `quiet`, `link`) paint nothing, so they mix from the page surface. Set it alongside `--lr-button-outlined-fill` when you tint an outlined button.\n- `--lr-button-hover-border` — Border color of a non-disabled button while hovered. **Undeclared by default**, so it falls back to whatever border colour the active `appearance` already paints at rest — every appearance's current hover border is unchanged until this is set. `appearance=\"link\"` renders with no border (`border: 0`) at every state, so this has no visible effect there.\n- `--lr-button-hover-color` — Text color of a non-disabled button while hovered. **Undeclared by default**, so it falls back to whatever colour the active `appearance` already paints at rest — every appearance's current hover text colour is unchanged until this is set. `appearance=\"link\"` ignores it: its own hover rule sets a higher-specificity colour mix instead.\n- `--lr-button-justify` (default: `center`) — `justify-content` of the internal button's row. With the label no longer growing by default, this is what positions the whole icon+label pair inside a stretched control: `flex-start` packs it against the leading edge, `space-between` pushes the adornments apart.\n- `--lr-button-label-grow` (default: `0`) — `flex-grow` of `[part=\"label\"]`. `0` (the default) lets the label shrink-wrap its text so `--lr-button-justify` positions the real content; `1` restores the pre-16.0.0 behaviour where the label absorbed every spare pixel of a stretched button. It also overrides the automatic grow a `with-caret`/`end`-adornment button applies, so `0` opts those rows out of pinning their trailing affordance.\n- `--lr-button-min-height` (default: `var(--lr-form-control-height)`) — The active tier's `min-block-size` floor, resolved through that tier's own `--lr-button-size-*` token, and used as the fallback when `--lr-button-height` is unset.\n- `--lr-button-on-fill` (default: `var(--lr-color-on-quiet)`) — Text color on top of `--lr-button-fill`, the grid's guaranteed-legible foreground for that tint.\n- `--lr-button-outlined-border` (default: `var(--lr-color-border-strong)`) — Border color of `appearance=\"outlined\"` and `appearance=\"filled-outlined\"`, which overrides `--lr-button-border`.\n- `--lr-button-outlined-fill` (default: `transparent`) — Background of `appearance=\"outlined\"`. Transparent by default; set it to tint the button (e.g. a faint surface wash behind the outline) without a `::part(base)` rule. Like `--lr-button-quiet-*`, it is deliberately *not* swapped per `variant`. The hover and press mixes read `--lr-button-hover-base`, which this tier leaves on the page surface, so set both together when you tint an outlined button.\n- `--lr-button-padding-block` (default: `var(--lr-form-control-padding-block)`) — Block padding of the internal button, taken from the active `size` tier of the shared ladder. Override it to retune a tier without a `::part(base)` rule; `appearance=\"link\"` ignores it (it renders with zero padding).\n- `--lr-button-padding-inline` (default: `var(--lr-form-control-padding-inline)`) — Inline padding of the internal button, from the active `size` tier. `appearance=\"link\"` ignores it.\n- `--lr-button-quiet-border` (default: `var(--lr-color-border)`) — Border color of `appearance=\"quiet\"`.\n- `--lr-button-quiet-text` (default: `var(--lr-color-text-quiet)`) — Text color of `appearance=\"quiet\"`.\n- `--lr-button-radius` (default: `var(--lr-form-control-radius)`) — Corner radius of the internal button, from the active `size` tier of the shared ladder (the two tightest tiers take a smaller radius, since a 6px corner on a 20px-tall control reads as a lozenge). `appearance=\"link\"` ignores it (it renders with zero radius). `pill` changes the private default to `--lr-radius-pill`; an inherited or direct `--lr-button-radius` still wins.\n- `--lr-button-shadow` — Box shadow of the internal button. **Undeclared by default**, so `box-shadow` falls back to `none` — byte-identical to before this property existed. Set it (e.g. an elevated/floating action button) without a `::part(base)` rule. `appearance=\"link\"` always renders with no shadow regardless of this token — a zero-chrome inline link has no box to elevate.\n- `--lr-button-size-2xs` (default: `var(--lr-form-control-height-2xs)`) — `min-block-size` at `size=\"2xs\"`. Since 8.0.0 the whole scale comes from the shared form-control ladder (`internal/sizes.styles.ts`), so ordinary single-row controls share the same minimum-height floor. A composed control can still grow to preserve an action's hit target or fit its content.\n- `--lr-button-size-l` (default: `var(--lr-form-control-height-l)`) — `min-block-size` at `size=\"l\"` (and at `size=\"large\"`).\n- `--lr-button-size-m` (default: `var(--lr-form-control-height-m)`) — `min-block-size` at `size=\"m\"` (and at `size=\"medium\"`), the default tier.\n- `--lr-button-size-s` (default: `var(--lr-form-control-height-s)`) — `min-block-size` at `size=\"s\"` (and at the `size=\"small\"` spelling).\n- `--lr-button-size-xl` (default: `var(--lr-form-control-height-xl)`) — `min-block-size` at `size=\"xl\"`.\n- `--lr-button-size-xs` (default: `var(--lr-form-control-height-xs)`) — `min-block-size` at `size=\"xs\"`.\n- `--lr-button-spinner-duration` (default: `var(--lr-transition-ambient)`) — Timing of the `loading` spinner.\n- `--lr-button-width` (default: `100%`) — Inline size of the internal button. The host defaults it to `100%` so the native button follows the host's own width; override to `auto` (or any other value) for a compact inline composition.","attributes":[{"name":"appearance","description":"`'accent'` (the default, matching the upstream default) is the loud tier: the active\n`variant`'s solid fill with its guaranteed-legible foreground, for the one primary action in a\nview. `'filled'` is the same tone one emphasis step down — a quiet tint, for a secondary\naction; it is deliberately a real fill rather than the page surface, so the two tiers never\npaint the same button. `'outlined'` is a border with no fill, `'plain'` neither.\n`'filled-outlined'` is `'filled'` plus `'outlined'`'s border color, for a filled button that\nstill has to read against a same-toned surface.\n`'link'` is zero-chrome inline text — no padding, border, or\nmin-height, underlined, colored from `--lr-button-accent` (the same token `'plain'` uses)\nand inheriting the surrounding font — for a text link that flows inline in a sentence rather\nthan a button-shaped control. `'quiet'` is a bordered, transparent-until-hover tier for a\ntoolbar-style icon+label action — its border/text read fixed `--lr-color-border`/`--lr-color-text-quiet`\ntokens regardless of `variant`, unlike `'outlined'`'s variant-tinted text, so it stays\nvisually muted at rest.\n\nType: `ButtonAppearance`  \nDefault: `'accent'`","value":{"type":["'accent'","'filled'","'outlined'","'filled-outlined'","'plain'","'link'","'quiet'"]}},{"name":"aria-controls","description":"Type: `| string\n    | null`  \nDefault: `null`"},{"name":"aria-current","description":"Current-item state forwarded reactively to the internal control: page, step, location, date, time, true or false.\n\nType: `string | null`  \nDefault: `null`"},{"name":"aria-describedby","description":"Type: `| string\n    | null`  \nDefault: `null`"},{"name":"aria-expanded","description":"Type: `| string\n    | null`  \nDefault: `null`"},{"name":"aria-haspopup","description":"Type: `| string\n    | null`  \nDefault: `null`"},{"name":"aria-label","description":"Accessible name forwarded to the internal native button or anchor. Bound to the host's\n`aria-label` content attribute so changing or removing that attribute after mount keeps the\nactual focused control synchronized.\n\nType: `string | null`  \nDefault: `null`"},{"name":"aria-pressed","description":"Toggle state forwarded reactively to the internal control: true, false or mixed.\n\nType: `string | null`  \nDefault: `null`"},{"name":"caret","description":"Reflected Shoelace alias for `withCaret`; both attributes reach the same rendered chevron.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"circle","description":"Shoelace-compatible circular icon-button treatment. It does not replace `pill`: `circle`\nadditionally makes the control square and removes label-oriented inline padding.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"custom-error","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nType: `string | null`  \nDefault: `null`"},{"name":"disabled","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"download","description":"Native anchor `download` attribute, used only while `href` resolves to a link. Ignored in\n`<button>` mode.\n\nType: `string | undefined`"},{"name":"form","description":"Browser-resolved form owner; assigning an ID, form element, or `null` updates `form`.\n\nType: `HTMLFormElement | string | null`  \nDefault: `null`"},{"name":"formaction","description":"Overrides the form owner's `action` for the submission this button triggers. Unset by\ndefault, leaving the form's own `action` in place.\n\nType: `string | undefined`"},{"name":"formenctype","description":"Overrides the form owner's `enctype` for the submission this button triggers.\n\nType: `ButtonFormEnctype | undefined`","value":{"type":["'application/x-www-form-urlencoded'","'multipart/form-data'","'text/plain'"]}},{"name":"formmethod","description":"Overrides the form owner's `method` for the submission this button triggers.\n\nType: `ButtonFormMethod | undefined`","value":{"type":["'get'","'post'","'dialog'"]}},{"name":"formnovalidate","description":"Skips the form owner's constraint validation for the submission this button triggers —\nthe native `formnovalidate` semantics. Without it an invalid form is reported and not\nsubmitted, exactly as a native submit button behaves.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"formtarget","description":"Overrides the form owner's `target` for the submission this button triggers. Distinct from\n`target`, which is the anchor target used in link mode.\n\nType: `string | undefined`"},{"name":"href","description":"When set to a safe link URL, the button's root renders as a real `<a href=…>` instead of a\n`<button>` — for a link styled as a button (e.g. a CTA). Unset (the default) renders a plain\n`<button>`, byte-for-byte as before. Only `http:`/`https:`/`blob:`/`mailto:`/relative URLs are\nhonored (see `safeLinkHref`); an unsafe/unparseable value falls back to the native `<button>`.\nSetting `download` narrows the allowlist to `safeDownloadHref`'s, which drops `mailto:` — a\nmail handoff names no retrievable bytes, so it cannot be a download target.\n`type` (submit/reset) has no effect while the anchor renders — an anchor has no submit/reset\nconcept, and native navigation is its own activation. While the button is disabled the anchor\nrenders with no `href` (see the class doc comment), so a disabled link button cannot navigate.\n\nType: `string | undefined`  \nDefault: `undefined`"},{"name":"loading","description":"Shows an internal spinner in place of interaction affordance and disables the button, without\nclearing `disabled` — a consumer's own `disabled` state and a transient `loading` state are\nindependent (mirrors `<lr-export-button>`'s own `loading`/`disabled` pair).\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"name","description":"Submitted as a `name`/`value` pair with the form data, but only while this button is the\nsubmitter (`type=\"submit\"`, in `<button>` mode). Unnamed (the default), the button contributes\nnothing — exactly like a native `<button>` with no `name`. See the class doc comment for how\nthe pair reaches the submitted `FormData`.\n\nReflected synchronously on assignment (rather than on Lit's async update cycle) because a\nrename must be visible to a `form.requestSubmit()` in the same tick — including this\ncomponent's own, when a consumer renames the button from the click handler that submits.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"outline","description":"Shoelace-compatible outlined treatment. The canonical `appearance` property remains\nuntouched so removing `outline` restores the exact Lyra appearance the author selected.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"pill","description":"Fully rounded ends, for a pill-shaped control. Changes the private radius default to\n`--lr-radius-pill` rather than declaring a radius on `[part~=\"base\"]`, so an inherited or\ndirect `--lr-button-radius` stays authoritative. `appearance=\"link\"` still renders with zero\nchrome, pill or not.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"rel","description":"Author-settable link relationship, merged with a non-negotiable security floor.\n\nMirrors `wa-button`/`sl-button`'s `rel`, so values the platform defines and upstream consumers\nactually use -- `nofollow`, `me`, `license`, `external`, `tag` -- survive a `wa-`/`sl-` -> `lr-`\nrename instead of being silently dropped. Two rules are enforced regardless of what an author\nwrites, which is what keeps this safe to expose:\n\n1. `opener` is always stripped. It is the one token that re-opens the reverse-tabnabbing vector.\n2. Whenever `target` is set, `noopener noreferrer` is force-added. A named/new browsing context\n   always gets the guard, author input or not.\n\nWith no `target` there is no new browsing context to protect, so a same-tab link renders exactly\nthe author's tokens. Deliberately left with NO default: `wa-button` declares none, and defaulting\nit (as `sl-button` does) would start suppressing the `Referer` header on every same-tab Lyra\nlink -- a real behavior change well beyond parity.\n\nType: `string | undefined`"},{"name":"required","description":"Whether a non-empty submitter value is required. This adds the Web Awesome form-control\ncontract without making an ordinary optional action button contribute persistent form data.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"size","description":"Visual size on the library's one control ladder. Accepts both the canonical `'2xs'`–`'xl'`\nsteps and Web Awesome's/Shoelace's `'small'`/`'medium'`/`'large'` spellings of `s`/`m`/`l`, so\na migration is a tag rename with no attribute rewrite; the two spellings render identically.\n`'2xs'` is the tightest tier — a sub-`xs` size for dense, toolbar-embedded controls (e.g.\nbeside a native `<input type=\"search\">` in a compact dialog header). `'m'` (the default) is\nthe standard size.\n\nType: `LyraSize`  \nDefault: `'m'`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}},{"name":"target","description":"Native anchor `target`, used only while `href` resolves to a link. Setting this to `'_blank'`\n(or any other target) always contributes `noopener noreferrer` to the rendered anchor's `rel`\n— matching `lr-card`'s/`lr-stat`'s identical pattern. Author `rel` tokens are merged rather\nthan ignored (see `rel`), but the guard is not removable and `opener` is always stripped.\nIgnored in `<button>` mode.\n\nType: `string | undefined`"},{"name":"type","description":"Forwarded to this component's own submit/reset handling — see the class doc comment above\nfor why this component (not the shadow-internal `<button>`) owns that behavior.\n\nType: `ButtonType`  \nDefault: `'button'`","value":{"type":["'button'","'submit'","'reset'"]}},{"name":"value","description":"The value submitted alongside `name`. Meaningful only together with a `name`, matching a\nnative submit button.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"variant","description":"Semantic tone, from the library's one `variant` vocabulary — the same five values every other\n`variant` in the library takes. Selects which row of the semantic colour grid every fill,\nborder and foreground token below resolves against. Shoelace's `default`/`primary` spellings\nnormalize to `neutral`/`brand`; its `text` spelling normalizes to neutral `appearance=\"plain\"`.\nReads always return the canonical Lyra vocabulary.\n\nType: `ButtonVariant`  \nDefault: `'neutral'`","value":{"type":["'neutral'","'brand'","'success'","'warning'","'danger'","'default'","'primary'","'text'"]}},{"name":"with-caret","description":"Renders a decorative trailing chevron (`[part=\"caret\"]`, `aria-hidden`) marking the button as\na dropdown/menu trigger. It carries no accessible name of its own — the button's label already\nnames the action, and the popup relationship is expressed by a host `aria-haspopup`/\n`aria-expanded`, which are forwarded to the internal control.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"with-end","description":"SSR presence hint for the `end` adornment wrapper.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"with-start","description":"SSR presence hint for the `start` adornment wrapper. Assigned slot content is still detected\nautomatically, so this is optional in client-rendered markup.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"wrap","description":"Wraps a long label onto multiple lines instead of ellipsis-truncating it to one, matching\n`<lr-chip>`'s identical opt-in. `false` (the default) reproduces the exact single-line,\nellipsis-truncated `[part=\"label\"]`.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"","description":"Default slot: the button's label content."},{"name":"end","description":"Trailing icon/content, rendered after the label."},{"name":"prefix","description":"Shoelace alias for `start`, rendered through the same wrapper."},{"name":"start","description":"Leading icon/content, rendered before the label."},{"name":"suffix","description":"Shoelace alias for `end`, rendered through the same wrapper."}],"js":{"properties":[{"name":"accessibleLabel","description":"Accessible name forwarded to the internal native button or anchor. Bound to the host's\n`aria-label` content attribute so changing or removing that attribute after mount keeps the\nactual focused control synchronized.\n\nAttribute: `aria-label`","type":"string | null","default":"null"},{"name":"appearance","description":"`'accent'` (the default, matching the upstream default) is the loud tier: the active\n`variant`'s solid fill with its guaranteed-legible foreground, for the one primary action in a\nview. `'filled'` is the same tone one emphasis step down — a quiet tint, for a secondary\naction; it is deliberately a real fill rather than the page surface, so the two tiers never\npaint the same button. `'outlined'` is a border with no fill, `'plain'` neither.\n`'filled-outlined'` is `'filled'` plus `'outlined'`'s border color, for a filled button that\nstill has to read against a same-toned surface.\n`'link'` is zero-chrome inline text — no padding, border, or\nmin-height, underlined, colored from `--lr-button-accent` (the same token `'plain'` uses)\nand inheriting the surrounding font — for a text link that flows inline in a sentence rather\nthan a button-shaped control. `'quiet'` is a bordered, transparent-until-hover tier for a\ntoolbar-style icon+label action — its border/text read fixed `--lr-color-border`/`--lr-color-text-quiet`\ntokens regardless of `variant`, unlike `'outlined'`'s variant-tinted text, so it stays\nvisually muted at rest.\n\nAttribute: `appearance`  \nReflected to its attribute.","type":"ButtonAppearance","default":"'accent'"},{"name":"caret","description":"Reflected Shoelace alias for `withCaret`; both attributes reach the same rendered chevron.\n\nAttribute: `caret`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"circle","description":"Shoelace-compatible circular icon-button treatment. It does not replace `pill`: `circle`\nadditionally makes the control square and removes label-oriented inline padding.\n\nAttribute: `circle`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"customError","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nAttribute: `custom-error`  \nReflected to its attribute.","type":"string | null","default":"null"},{"name":"disabled","description":"Attribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"download","description":"Native anchor `download` attribute, used only while `href` resolves to a link. Ignored in\n`<button>` mode.\n\nAttribute: `download`","type":"string | undefined"},{"name":"effectiveDisabled","description":"Whether the button is disabled explicitly or by an ancestor fieldset.","type":"boolean","read-only":true},{"name":"form","description":"Browser-resolved form owner; assigning an ID, form element, or `null` updates `form`.\n\nAttribute: `form`  \nReflected to its attribute.","type":"HTMLFormElement | string | null","default":"null"},{"name":"formAction","description":"Overrides the form owner's `action` for the submission this button triggers. Unset by\ndefault, leaving the form's own `action` in place.\n\nAttribute: `formaction`","type":"string | undefined"},{"name":"formEnctype","description":"Overrides the form owner's `enctype` for the submission this button triggers.\n\nAttribute: `formenctype`","type":"ButtonFormEnctype | undefined"},{"name":"formMethod","description":"Overrides the form owner's `method` for the submission this button triggers.\n\nAttribute: `formmethod`","type":"ButtonFormMethod | undefined"},{"name":"formNoValidate","description":"Skips the form owner's constraint validation for the submission this button triggers —\nthe native `formnovalidate` semantics. Without it an invalid form is reported and not\nsubmitted, exactly as a native submit button behaves.\n\nAttribute: `formnovalidate`","type":"boolean","default":"false"},{"name":"formTarget","description":"Overrides the form owner's `target` for the submission this button triggers. Distinct from\n`target`, which is the anchor target used in link mode.\n\nAttribute: `formtarget`","type":"string | undefined"},{"name":"href","description":"When set to a safe link URL, the button's root renders as a real `<a href=…>` instead of a\n`<button>` — for a link styled as a button (e.g. a CTA). Unset (the default) renders a plain\n`<button>`, byte-for-byte as before. Only `http:`/`https:`/`blob:`/`mailto:`/relative URLs are\nhonored (see `safeLinkHref`); an unsafe/unparseable value falls back to the native `<button>`.\nSetting `download` narrows the allowlist to `safeDownloadHref`'s, which drops `mailto:` — a\nmail handoff names no retrievable bytes, so it cannot be a download target.\n`type` (submit/reset) has no effect while the anchor renders — an anchor has no submit/reset\nconcept, and native navigation is its own activation. While the button is disabled the anchor\nrenders with no `href` (see the class doc comment), so a disabled link button cannot navigate.\n\nAttribute: `href`  \nReflected to its attribute.","type":"string | undefined","default":"undefined"},{"name":"labels","type":"NodeList","read-only":true},{"name":"loading","description":"Shows an internal spinner in place of interaction affordance and disables the button, without\nclearing `disabled` — a consumer's own `disabled` state and a transient `loading` state are\nindependent (mirrors `<lr-export-button>`'s own `loading`/`disabled` pair).\n\nAttribute: `loading`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"name","description":"Submitted as a `name`/`value` pair with the form data, but only while this button is the\nsubmitter (`type=\"submit\"`, in `<button>` mode). Unnamed (the default), the button contributes\nnothing — exactly like a native `<button>` with no `name`. See the class doc comment for how\nthe pair reaches the submitted `FormData`.\n\nReflected synchronously on assignment (rather than on Lit's async update cycle) because a\nrename must be visible to a `form.requestSubmit()` in the same tick — including this\ncomponent's own, when a consumer renames the button from the click handler that submits.\n\nAttribute: `name`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"outline","description":"Shoelace-compatible outlined treatment. The canonical `appearance` property remains\nuntouched so removing `outline` restores the exact Lyra appearance the author selected.\n\nAttribute: `outline`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"pill","description":"Fully rounded ends, for a pill-shaped control. Changes the private radius default to\n`--lr-radius-pill` rather than declaring a radius on `[part~=\"base\"]`, so an inherited or\ndirect `--lr-button-radius` stays authoritative. `appearance=\"link\"` still renders with zero\nchrome, pill or not.\n\nAttribute: `pill`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"rel","description":"Author-settable link relationship, merged with a non-negotiable security floor.\n\nMirrors `wa-button`/`sl-button`'s `rel`, so values the platform defines and upstream consumers\nactually use -- `nofollow`, `me`, `license`, `external`, `tag` -- survive a `wa-`/`sl-` -> `lr-`\nrename instead of being silently dropped. Two rules are enforced regardless of what an author\nwrites, which is what keeps this safe to expose:\n\n1. `opener` is always stripped. It is the one token that re-opens the reverse-tabnabbing vector.\n2. Whenever `target` is set, `noopener noreferrer` is force-added. A named/new browsing context\n   always gets the guard, author input or not.\n\nWith no `target` there is no new browsing context to protect, so a same-tab link renders exactly\nthe author's tokens. Deliberately left with NO default: `wa-button` declares none, and defaulting\nit (as `sl-button` does) would start suppressing the `Referer` header on every same-tab Lyra\nlink -- a real behavior change well beyond parity.\n\nAttribute: `rel`","type":"string | undefined"},{"name":"required","description":"Whether a non-empty submitter value is required. This adds the Web Awesome form-control\ncontract without making an ordinary optional action button contribute persistent form data.\n\nAttribute: `required`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"size","description":"Visual size on the library's one control ladder. Accepts both the canonical `'2xs'`–`'xl'`\nsteps and Web Awesome's/Shoelace's `'small'`/`'medium'`/`'large'` spellings of `s`/`m`/`l`, so\na migration is a tag rename with no attribute rewrite; the two spellings render identically.\n`'2xs'` is the tightest tier — a sub-`xs` size for dense, toolbar-embedded controls (e.g.\nbeside a native `<input type=\"search\">` in a compact dialog header). `'m'` (the default) is\nthe standard size.\n\nAttribute: `size`  \nReflected to its attribute.","type":"LyraSize","default":"'m'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"target","description":"Native anchor `target`, used only while `href` resolves to a link. Setting this to `'_blank'`\n(or any other target) always contributes `noopener noreferrer` to the rendered anchor's `rel`\n— matching `lr-card`'s/`lr-stat`'s identical pattern. Author `rel` tokens are merged rather\nthan ignored (see `rel`), but the guard is not removable and `opener` is always stripped.\nIgnored in `<button>` mode.\n\nAttribute: `target`","type":"string | undefined"},{"name":"type","description":"Forwarded to this component's own submit/reset handling — see the class doc comment above\nfor why this component (not the shadow-internal `<button>`) owns that behavior.\n\nAttribute: `type`","type":"ButtonType","default":"'button'"},{"name":"validationMessage","type":"string","read-only":true},{"name":"validity","type":"ValidityState","read-only":true},{"name":"value","description":"The value submitted alongside `name`. Meaningful only together with a `name`, matching a\nnative submit button.\n\nAttribute: `value`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"variant","description":"Semantic tone, from the library's one `variant` vocabulary — the same five values every other\n`variant` in the library takes. Selects which row of the semantic colour grid every fill,\nborder and foreground token below resolves against. Shoelace's `default`/`primary` spellings\nnormalize to `neutral`/`brand`; its `text` spelling normalizes to neutral `appearance=\"plain\"`.\nReads always return the canonical Lyra vocabulary.\n\nAttribute: `variant`  \nReflected to its attribute.","type":"ButtonVariant","default":"'neutral'"},{"name":"willValidate","type":"boolean","read-only":true},{"name":"withCaret","description":"Renders a decorative trailing chevron (`[part=\"caret\"]`, `aria-hidden`) marking the button as\na dropdown/menu trigger. It carries no accessible name of its own — the button's label already\nnames the action, and the popup relationship is expressed by a host `aria-haspopup`/\n`aria-expanded`, which are forwarded to the internal control.\n\nAttribute: `with-caret`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"withEnd","description":"SSR presence hint for the `end` adornment wrapper.\n\nAttribute: `with-end`","type":"boolean","default":"false"},{"name":"withStart","description":"SSR presence hint for the `start` adornment wrapper. Assigned slot content is still detected\nautomatically, so this is optional in client-rendered markup.\n\nAttribute: `with-start`","type":"boolean","default":"false"},{"name":"wrap","description":"Wraps a long label onto multiple lines instead of ellipsis-truncating it to one, matching\n`<lr-chip>`'s identical opt-in. `false` (the default) reproduces the exact single-line,\nellipsis-truncated `[part=\"label\"]`.\n\nAttribute: `wrap`  \nReflected to its attribute.","type":"boolean","default":"false"}],"events":[{"name":"blur","description":"Native blur relayed once from the internal button or anchor.","type":"FocusEvent"},{"name":"focus","description":"Native focus relayed once from the internal button or anchor.","type":"FocusEvent"},{"name":"lr-invalid","description":"The button failed a validity check. Cancelable; preventing it also prevents the native `invalid` event's default validation UI.","type":"CustomEvent<null>"}]}},{"name":"lr-button-group","description":"`<lr-button-group>` — a responsive grouping primitive for related actions.\nIt preserves the consumer's button elements and exposes the group semantics\non the element that owns the label. A host `aria-label` wins by attribute\npresence, including an explicitly empty value.\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) | Buttons or other action controls. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The group wrapper. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-button-group-gap` (default: `var(--lr-space-2xs)`) — Gap between grouped controls.","attributes":[{"name":"label","description":"Accessible group-name fallback when the host `aria-label` is absent.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"orientation","description":"Logical control axis, using the shared `LyraOrientation` vocabulary.\n\nType: `LyraOrientation`  \nDefault: `'horizontal'`","value":{"type":["'horizontal'","'vertical'"]}}],"slots":[{"name":"","description":"Buttons or other action controls."}],"js":{"properties":[{"name":"label","description":"Accessible group-name fallback when the host `aria-label` is absent.\n\nAttribute: `label`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"orientation","description":"Logical control axis, using the shared `LyraOrientation` vocabulary.\n\nAttribute: `orientation`  \nReflected to its attribute.","type":"LyraOrientation","default":"'horizontal'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}]}},{"name":"lr-calendar","description":"`<lr-calendar>` — responsive month calendar with event markers and agenda mode.\n\nMonth-view event markers are real buttons inside each focusable gridcell, so\nkeyboard users can activate individual events without switching views.\nAgenda view renders the same events as full-width buttons. Early ISO dates retain their\nauthored local year in month rendering and navigation. Colored agenda actions keep their\nforeground/background pairing during hover and press; callers remain responsible for choosing\naccessible custom event colors.\n\nPublic collection properties take bounded, detached readonly sequences. Calendar-only fields\nare projected from own data descriptors once per assignment; `lr-event-select` retains the\ncaller's original event identity. Create a new collection and reassign it after changes;\nmutating the assigned array does not update the view.\n\n`firstDayOfWeek` defaults to `'auto'`, deriving the week start from `effectiveLocale` (via the\nshared `resolveFirstDayOfWeek()` contract also used by `lr-date-picker`/`lr-date-input`), and\nalso accepts one of the shared weekday-name tokens (`'sun'` through `'sat'`) for an explicit,\nlocale-independent week start.\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| `agenda` | Agenda list. |\n| `agenda-event` | One focusable event button in agenda view (`view=\"agenda\"` only). |\n| `date` | The day-of-month number inside a day cell. |\n| `day` | Day cell. |\n| `event` | Event marker. |\n| `grid` | Month grid. |\n| `header` | Calendar header. |\n| `nav` | Either month-navigation button. |\n| `nav-glyph` | The previous/next chevron glyph, mirrored under RTL. |\n| `navigation` | Wrapper around both month-navigation controls and the title. |\n| `next-button` | Next-month button. |\n| `previous-button` | Previous-month button. |\n| `title` | The header's month/year title. |\n| `week` | One week row within the month grid. |\n| `weekday` | One weekday header cell. |\n| `weekdays` | Weekday header row. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-calendar-agenda-event-active-bg` (default: `color-mix(in oklab, var(--lr-calendar-agenda-event-hover-bg, var(--lr-color-brand-quiet)), var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Agenda-event pressed background override; without one, colored events retain their event fill.\n- `--lr-calendar-agenda-event-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Agenda-event hover background override; without one, colored events retain their event fill.\n- `--lr-calendar-day-active-bg` (default: `color-mix(in oklab, var(--lr-calendar-day-hover-bg, var(--lr-color-brand-quiet)), var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Day pressed background.\n- `--lr-calendar-day-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Day hover background.\n- `--lr-calendar-day-min-block-size` (default: `var(--lr-size-6rem)`) — Minimum block size of a day cell.\n- `--lr-calendar-day-min-block-size-narrow` (default: `var(--lr-size-4rem)`) — Minimum block size of a day cell once the host is narrower than 28rem.\n- `--lr-calendar-day-outside-bg` (default: `var(--lr-color-surface)`) — Background of an adjacent-month day cell.\n- `--lr-calendar-day-outside-color` (default: `var(--lr-color-text-quiet)`) — Text color of an adjacent-month day cell.\n- `--lr-calendar-day-selected-bg` (default: `var(--lr-color-brand-quiet)`) — Background of a selected day cell, decoupled from the shared token also driving the nav-button/agenda-event hover background.\n- `--lr-calendar-day-today-outline-color` (default: `var(--lr-color-brand)`) — Outline color of today's day cell.\n- `--lr-calendar-nav-active-bg` (default: `color-mix(in oklab, var(--lr-calendar-nav-hover-bg, var(--lr-color-brand-quiet)), var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Month-navigation pressed background.\n- `--lr-calendar-nav-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Month-navigation hover background.","attributes":[{"name":"aria-label","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"first-day-of-week","description":"Type: `LyraCalendarFirstDayOfWeek`  \nDefault: `'auto'`","value":{"type":["'auto'","'sun'","'mon'","'tue'","'wed'","'thu'","'fri'","'sat'"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"value","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"view","description":"Type: `CalendarView`","value":{"type":["'month'","'agenda'"]}},{"name":"view-date","description":"Type: `string`","value":{"type":["string"]}}],"js":{"properties":[{"name":"accessibleLabel","description":"Attribute: `aria-label`","type":"string","default":"''"},{"name":"events","type":"readonly CalendarEvent[]","default":"[]"},{"name":"firstDayOfWeek","description":"Attribute: `first-day-of-week`","type":"LyraCalendarFirstDayOfWeek","default":"'auto'"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"value","description":"Attribute: `value`","type":"string","default":"''"},{"name":"view","description":"Attribute: `view`  \nReflected to its attribute.","type":"CalendarView"},{"name":"viewDate","description":"Attribute: `view-date`","type":"string"}],"events":[{"name":"lr-date-select","description":"A calendar date was selected.","type":"CustomEvent<{ date: string }>"},{"name":"lr-event-select","description":"An event was selected.","type":"CustomEvent<{ event: CalendarEvent }>"},{"name":"lr-view-change","description":"The visible month changed.","type":"CustomEvent<{ viewDate: string }>"}]}},{"name":"lr-calendar-viewer","description":"Parses `.ics` calendars with the optional `ical.js` peer and renders each\nVEVENT as plain text, preserving summaries, DATE/DATE-TIME semantics, locations, and details.\nEarly all-day years retain UTC calendar semantics and the exclusive DTEND display boundary.\nAt most 250 events and 2 MiB of rendered event text are retained so search, selection and\ntext-quote anchors continue to cover the complete accepted document without eager 10k-row DOM.\nThe inherited fragment path performs an exact DOM `id` lookup, but generated event markup has\nno fragment ids; such a jump reports `found: false`. Use a text-quote anchor for event content.\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| `anchor-live-region` | The aria-hidden, non-live shadow mirror of the latest anchor-jump message. |\n| `base` | The root container with explicit `aria-busy` loading state. |\n| `body` | The scrollable calendar body. |\n| `error` | The error region. |\n| `event` | One calendar event. |\n| `event-description` | The event description. |\n| `event-list` | The event list. |\n| `event-location` | The event location. |\n| `event-summary` | The event title. |\n| `event-time` | The formatted event time. |\n| `spinner` | The visible tokenized loading treatment and ordinary text label. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-calendar-viewer-max-height` (default: `none`) — Maximum block size of `[part=\"body\"]` before it scrolls internally. The `maxHeight` property sets this token inline on `[part=\"base\"]`.","attributes":[{"name":"active-highlight-id","description":"Id of the currently active highlight, or null when none is active.\n\nType: `string | null`  \nDefault: `null`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max-height","description":"A CSS `max-height`; invalid values are ignored.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"name","description":"Display name associated with the calendar. It names `[part='base']` when host `aria-label` is\nabsent, before the localized fallback. A non-empty host label remains on the host; an\nexplicitly empty one is preserved on the shadow owner.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"src","description":"URL to fetch and parse as an iCalendar document.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"js":{"properties":[{"name":"activeHighlightId","description":"Id of the currently active highlight, or null when none is active.\n\nAttribute: `active-highlight-id`","type":"string | null","default":"null"},{"name":"anchor","description":"Anchor or highlight id to resolve and scroll into view.","type":"LyraAnchor | string | null","default":"null"},{"name":"anchorKinds","description":"Anchor kinds supported by this viewer instance.","type":"readonly LyraAnchorKind[]","default":"[]","read-only":true},{"name":"highlights","description":"Highlights rendered by the document target. Reassign after mutation.","type":"LyraHighlight[]","default":"[]"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"maxHeight","description":"A CSS `max-height`; invalid values are ignored.\n\nAttribute: `max-height`","type":"string","default":"''"},{"name":"name","description":"Display name associated with the calendar. It names `[part='base']` when host `aria-label` is\nabsent, before the localized fallback. A non-empty host label remains on the host; an\nexplicitly empty one is preserved on the shadow owner.\n\nAttribute: `name`","type":"string","default":"''"},{"name":"src","description":"URL to fetch and parse as an iCalendar document.\n\nAttribute: `src`","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-anchor-result","description":"Fired after an `anchor` assignment or `scrollToAnchor()` call is applied. `detail: { found: boolean }`. Bubbling, composed, and non-cancelable.","type":"CustomEvent<AnchorResultDetail>"},{"name":"lr-render-error","description":"Fired when fetching or parsing the calendar fails.","type":"CustomEvent<{ error: unknown }>"},{"name":"lr-search-change","description":"Fired whenever search state changes. `matchCountExact=false` makes the retained count a lower bound. Bubbling, composed, and non-cancelable.","type":"CustomEvent<LyraSearchChangeDetail>"},{"name":"lr-text-select","description":"Fired after a selection ends inside the rendered calendar. `detail: { text: string; anchor: LyraAnchor | null; rects: DOMRect[] }`. Bubbling, composed, and non-cancelable.","type":"CustomEvent<TextSelectDetail>"}]}},{"name":"lr-callout","description":"`<lr-callout>` — an inline message surface for status, warning, and error content.\nSet `inline` for lightweight reactive status/error text: it removes the panel chrome while\npreserving the accessible content, optional leading icon, and close action.\nInitial content is not announced as a new live update unless `announce` opts in; with it set,\nthe content present when the callout first mounts is announced once, at the same urgency the\nlater-update path derives from `variant`, and reconnection or adoption stages that content\nagain instead of replaying the announcement. A host `role=\"status\"`/`role=\"alert\"` hand-added as\na workaround before `announce` existed should be removed once `announce` is set: leaving both in\nplace announces the same initial text twice, once through the native role and once through the\nshared sink. Once the first render and slot\ndistribution settle, later content updates are appended to a shared light-DOM polite sink, or\nan assertive one for `variant=\"danger\"`. Announcements normalize accessible heading/message\ntext, excluding icon and close chrome plus subtree-pruned descendants. A visibility-hidden\nwrapper omits its own text but may contain a descendant that restores visibility; updates while\nthe host or a composed ancestor is hidden stay silent. A nested forwarding slot contributes its\nflattened assigned text rather than fallback content, and later assignment or assigned-content\nmutations are observed. A nonempty host/property accessible label prefixes the visible update as\ncontext instead of replacing it; the complete order and punctuation come from the localized\n`calloutAnnouncementWithContext` message. An explicitly empty host label still leaves visible\ntext live. Property and rich-slot headings default to semantic level 3; set `heading-level`\nfrom `1`–`6` to fit the surrounding outline, or `none` for visual-only heading text.\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) | Message content. |\n| `heading` | Optional rich heading content; its wrapper owns the configured heading level. |\n| `icon` | Optional icon. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The visible grid wrapper inside the host-owned callout surface. |\n| `close-button` | The close button, sized to the shared minimum tappable size (`--lr-icon-button-size`) in both the default panel and the compact `inline` variant. As of 16.0.0 this is a composed `<lr-icon-button>` host, not a native `<button>`: it still owns the grid placement, but the painted surface moved one shadow boundary deeper -- style it through `close-button__control` or the `--lr-icon-button-*` tokens. |\n| `close-button__control` | The composed `<lr-icon-button>`'s own native control, forwarded because the painted surface (background, radius, hover/press fill, focus ring and hit-area floor) now sits one shadow boundary deeper than `close-button`. |\n| `close-icon` | The close button's visible \"×\" glyph, independent of the control's hit target size -- shrinks in the `inline` variant while the hit target stays full-size. |\n| `content` | The message content. |\n| `heading` | The heading wrapper (`role=\"heading\"` at the configured level unless opted out). |\n| `icon` | The icon wrapper. |\n| `message` | The message content wrapper. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-callout-background` (default: `var(--lr-color-fill-quiet,var(--lr-color-brand-fill-quiet))`) — The host surface's background: an inherited semantic quiet fill, with brand as the standalone fallback.\n- `--lr-callout-border` (default: `var(--lr-color-fill-loud,var(--lr-color-brand-fill-loud))`) — The host surface's border color.\n- `--lr-callout-close-hover-bg` (default: `var(--lr-color-brand-quiet)`) — The close button's hover background, decoupled from `--lr-callout-background` so a consumer can retint one without affecting the other (e.g. keeping the hover fill visibly distinct from a `variant=\"brand\"` panel, which shares the same default token).\n- `--lr-callout-color` (default: `var(--lr-color-fill-loud,var(--lr-color-brand-fill-loud))`) — The host surface's text color.\n- `--lr-callout-font-size` (default: `var(--lr-form-control-font-size,var(--lr-font-size-m))`) — The callout's text size. Its private default follows the library's shared size ladder; an inherited or direct public value remains authoritative.\n- `--lr-callout-gap` (default: `var(--lr-space-s)`) — Space between the icon, the content, and the close action. Deliberately does not vary by `size`: it separates three adjacent boxes rather than setting the panel's density, and shrinking it at the small tiers only crowds them.\n- `--lr-callout-padding` (default: `var(--lr-form-control-padding-inline,var(--lr-space-m))`) — Padding of the panel, on both axes. Its private default follows the shared ladder's inline-padding knob: a panel's block rhythm is generous like a control's inline padding, not tight like its block padding (which exists to fit text inside a fixed control height). This hook applies to the panel treatment; `inline` intentionally forces host padding to zero.","attributes":[{"name":"accessible-label","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"announce","description":"Opts this callout into announcing the content it already carries when it first mounts,\nthrough the same shared light-DOM sink and the same `variant`-derived urgency the\nlater-update path uses. Leave unset for a callout that is part of the page a user is\narriving on: its text is read in document order and repeating it is noise. This is read once,\nwhen the callout first mounts -- a later reconnection or adoption stages the existing content\nagain rather than replaying it, and later content updates are announced either way. Remove\nany host `role=\"status\"`/`role=\"alert\"` hand-added before this property existed once it is\nset -- otherwise the initial text is announced twice, through the native role and again\nthrough the shared sink.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"appearance","description":"Type: `CalloutAppearance`","value":{"type":["'accent'","'filled'","'outlined'","'filled-outlined'","'plain'"]}},{"name":"closable","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"heading","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"heading-level","description":"Type: `LyraHeadingLevel`","value":{"type":["'1'","'2'","'3'","'4'","'5'","'6'","'none'"]}},{"name":"inline","description":"Uses the lightweight inline treatment without border, background, or panel padding.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"open","description":"Type: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"size","description":"Type: `CalloutSize`  \nDefault: `'m'`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}},{"name":"variant","description":"Type: `CalloutVariant`  \nDefault: `'brand'`","value":{"type":["'neutral'","'brand'","'success'","'warning'","'danger'"]}}],"slots":[{"name":"","description":"Message content."},{"name":"heading","description":"Optional rich heading content; its wrapper owns the configured heading level."},{"name":"icon","description":"Optional icon."}],"js":{"properties":[{"name":"accessibleLabel","description":"Attribute: `accessible-label`","type":"string","default":"''"},{"name":"announce","description":"Opts this callout into announcing the content it already carries when it first mounts,\nthrough the same shared light-DOM sink and the same `variant`-derived urgency the\nlater-update path uses. Leave unset for a callout that is part of the page a user is\narriving on: its text is read in document order and repeating it is noise. This is read once,\nwhen the callout first mounts -- a later reconnection or adoption stages the existing content\nagain rather than replaying it, and later content updates are announced either way. Remove\nany host `role=\"status\"`/`role=\"alert\"` hand-added before this property existed once it is\nset -- otherwise the initial text is announced twice, through the native role and again\nthrough the shared sink.\n\nAttribute: `announce`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"appearance","description":"Attribute: `appearance`  \nReflected to its attribute.","type":"CalloutAppearance"},{"name":"closable","description":"Attribute: `closable`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"heading","description":"Attribute: `heading`","type":"string","default":"''"},{"name":"headingLevel","description":"Attribute: `heading-level`  \nReflected to its attribute.","type":"LyraHeadingLevel"},{"name":"inline","description":"Attribute: `inline`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"open","description":"Attribute: `open`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"size","description":"Attribute: `size`  \nReflected to its attribute.","type":"CalloutSize","default":"'m'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"variant","description":"Attribute: `variant`  \nReflected to its attribute.","type":"CalloutVariant","default":"'brand'"}],"events":[{"name":"lr-close","description":"The close action was accepted. Cancelable before the callout hides.","type":"CustomEvent<null>"}]}},{"name":"lr-card","description":"`<lr-card>` — a generic, styled bordered content container: the \"small bordered surface with\npadding\" idiom common to hero highlights, clickable grid tiles, and management-list items. A\ndirect `<lr-*>` counterpart to `<wa-card>`'s contract, staying slot-compatible with\n`lr-result-card` where they overlap.\n\nThe header is allocation-responsive: long or translated header content can shrink and wrap,\nand the actions group moves onto another line when both no longer fit side by side.\n\n**Overflow is clipped, deliberately, and the card never picks a scroll owner for you.**\n`[part='base']` stretches to the host's allocated block-size and clips its overflow — that clip\nis what keeps a full-bleed `media`/`image` child inside the rounded border. So a card given a\n*definite* allocation (a fixed grid row, an explicit `block-size`) clips body content taller\nthan that allocation rather than growing or scrolling; in an auto-sized row it simply grows and\nnothing is clipped. Neither upstream card exposes an overflow, block-size, or scroll hook, and\nthis one deliberately adds none either: the public `body` part already carries the whole\ndecision, and a `::part()` rule from the consumer's tree wins over the shadow stylesheet\nregardless of specificity. A fixed-height tile whose body must hold more content therefore says\nso itself — `lr-card::part(body) { overflow: auto; }` — which also leaves `max-block-size`,\n`scrollbar-gutter`, and `overscroll-behavior` in the consumer's hands.\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 card body. |\n| `actions` | Horizontal-card actions; retained as the legacy header-actions alias vertically. |\n| `footer` | Footer content, rendered below the body. |\n| `footer-actions` | Controls rendered alongside the vertical footer. |\n| `header` | Header row content, rendered above the body. |\n| `header-actions` | Controls rendered alongside the vertical header. |\n| `image` | Shoelace-compatible alias for `media`. |\n| `media` | Media content, rendered above the header or at logical start when horizontal. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `actions` | Wrapper around the `actions` and `header-actions` slots. Hidden entirely when both are empty. |\n| `activation-button` | The native whole-card action, rendered while `actionable` without `href`. It is a sibling of slotted controls, so actionable descendants are never nested inside another actionable role. |\n| `base` | The outer container (a `<div>`, or a stretched `<a>` behind the consumer slots when `href` is set). |\n| `body` | Wrapper around the default slot. |\n| `footer` | Wrapper around the `footer` and `footer-actions` slots. Hidden entirely when both are empty. |\n| `header` | Wrapper around the `header` slot and `actions`. Hidden entirely when both are empty. |\n| `image` | Shoelace-compatible alias on the same wrapper as `media`. |\n| `media` | Wrapper around the `media` and `image` slots. Hidden entirely when empty. |\n\n---\n\n**CSS Custom Properties**\n\n- `--border-color` (default: `var(--lr-color-border)`) — Shoelace-compatible border color.\n- `--border-radius` (default: `var(--lr-radius)`) — Shoelace-compatible corner radius.\n- `--border-width` (default: `var(--lr-border-width-thin)`) — Shoelace-compatible border width.\n- `--lr-card-accent-border-color` (default: `var(--lr-color-brand)`) — Accent stripe color.\n- `--lr-card-filled-bg` (default: `var(--lr-color-brand-quiet)`) — Filled appearance background.\n- `--lr-card-filled-outlined-bg` (default: `var(--lr-color-brand-quiet)`) — Filled-outlined background.\n- `--lr-card-interactive-active-border-color` (default: `var(--lr-color-brand)`) — Interactive pressed border.\n- `--lr-card-interactive-active-overlay` — Interactive pressed overlay; defaults to the former transparent active mix.\n- `--lr-card-interactive-hover-border-color` (default: `var(--lr-color-brand)`) — Interactive hover border.\n- `--lr-card-interactive-hover-shadow` (default: `var(--lr-card-shadow, none)`) — Box shadow of an `actionable`/linked card's base while hovered. Falls back to `--lr-card-shadow` itself, so a card given only a resting shadow keeps that exact shadow on hover; set this independently to lift an actionable card a further step on hover.\n- `--lr-card-outlined-bg` (default: `var(--lr-color-surface)`) — Background of the DEFAULT (`outlined`) appearance, and of `accent`, which adds a stripe without restating a surface. The filled tiers below already had their own hook; this one closes the gap for the tier most cards actually render, so retinting one themed card no longer needs a `::part(base)` rule or an app-wide `--lr-color-surface` change. Mirrors `<lr-details>`'s `--lr-details-outlined-bg`.\n- `--lr-card-shadow` — Box shadow of the card surface. **Undeclared by default**, so `box-shadow` falls back to `none` -- byte-identical to before this property existed. Set it (e.g. a raised card in a flat layout) without a `::part(base)` rule.\n- `--padding` (default: `var(--spacing,var(--lr-space-m))`) — Shoelace-compatible section padding.\n- `--spacing` (default: `var(--lr-space-m)`) — Space around and between card sections.","attributes":[{"name":"actionable","description":"Opt-in no-link whole-card action behavior: the hover/focus-visible treatment (border-color shift,\n`cursor: pointer`) plus, when `href` is **not** also set, real activation semantics --\n`[part='activation-button']` becomes the focusable native button, responds to Enter/Space,\nand emits `lr-card-activate`. With `href` set the stretched native `<a>` owns navigation and\n`lr-card-activate` is never fired. `false` (the default) reproduces today's exact static\noutput: no button, no listeners, no events.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"appearance","description":"Visual treatment, mirroring `wa-card`'s `appearance` vocabulary. `'outlined'` (the default)\nis a bordered surface -- the common \"small bordered surface with padding\" idiom.\n\nType: `LyraAppearance`  \nDefault: `'outlined'`","value":{"type":["'accent'","'filled'","'outlined'","'filled-outlined'","'plain'"]}},{"name":"aria-current","description":"Current-item state forwarded reactively onto whichever control the card renders, the activation button OR the stretched link (`aria-current` is global, and a current-page link is its commonest use): `page`, `step`, `location`, `date`, `time`, `true` or `false`.\n\nType: `string | null`  \nDefault: `null`"},{"name":"aria-label","description":"Accessible name forwarded to the native activation owner. The `aria-label` attribute/property\napplies by presence to the interactive button or linked anchor, including an explicitly empty\nvalue.\n\nType: `string | null`  \nDefault: `null`"},{"name":"aria-pressed","description":"Toggle state forwarded reactively onto the native `activation-button`: `true`, `false` or `mixed`. Anything else is ignored rather than passed through, so a typo never reaches the accessibility tree. A LINKED card does not receive it -- `link` has no pressed state, and asserting one there is an ARIA conformance failure, not a nicety.\n\nType: `string | null`  \nDefault: `null`"},{"name":"disabled","description":"Turns the card's OWN activation off: the native `activation-button` renders `disabled`, a\nlinked card's stretched `<a>` loses its `href` (so it genuinely cannot navigate rather than\nmerely claiming `aria-disabled` on a live link, matching `<lr-button>`/`<lr-icon-button>`)\nand leaves the tab order, `lr-card-activate` stops firing from every path including\n`click()`, and the card paints at `--lr-opacity-disabled` with a `not-allowed` cursor.\n\nScoped to the card's own action: a passive card (no `actionable`, no `href`) has nothing to\nturn off, so `disabled` leaves it byte-identical rather than dimming inert content into a\nclaim the card cannot back with behavior. Slotted controls stay the consumer's own to\ndisable -- a card is a container, and silently disabling somebody else's buttons is not a\nstate this component can honestly own.\n\nLike `<lr-icon-button>`, a card is deliberately NOT form-associated (it is a layout\ncontainer, not a form control, and enrolling every card in `form.elements` would be a far\nlarger change than the state it buys), so an ancestor `<fieldset disabled>` does not cascade\nhere -- disable each card explicitly.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"href","description":"When set, a real stretched `<a href=...>` renders behind the card's consumer slots for a\nwhole-card link (e.g. a wide CTA tile). Slotted controls remain independent actions; clicks\nin noninteractive card content still follow the link. Unset (the default) renders a plain\n`<div>`.\n\nType: `string | undefined`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"orientation","description":"Section flow, using the shared `LyraOrientation` vocabulary. Horizontal cards arrange\nmedia, body, and `actions` side by side.\n\nType: `LyraOrientation`  \nDefault: `'vertical'`","value":{"type":["'horizontal'","'vertical'"]}},{"name":"rel","description":"Author-settable relationship tokens. `opener` is always stripped; whenever `target` is set,\nthe rendered link force-adds `noopener noreferrer` without discarding other tokens.\n\nType: `string | undefined`"},{"name":"target","description":"Native anchor target, used only while `href` resolves to a link. Any target forces the\n`noopener noreferrer` security floor while preserving safe author `rel` tokens.\n\nType: `string | undefined`"},{"name":"with-footer","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"with-footer-actions","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"with-header","description":"SSR presence hints. Hydrated cards also detect populated slots automatically.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"with-header-actions","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"with-media","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"","description":"The card body."},{"name":"actions","description":"Horizontal-card actions; retained as the legacy header-actions alias vertically."},{"name":"footer","description":"Footer content, rendered below the body."},{"name":"footer-actions","description":"Controls rendered alongside the vertical footer."},{"name":"header","description":"Header row content, rendered above the body."},{"name":"header-actions","description":"Controls rendered alongside the vertical header."},{"name":"image","description":"Shoelace-compatible alias for `media`."},{"name":"media","description":"Media content, rendered above the header or at logical start when horizontal."}],"js":{"properties":[{"name":"accessibleLabel","description":"Accessible name forwarded to the native activation owner. The `aria-label` attribute/property\napplies by presence to the interactive button or linked anchor, including an explicitly empty\nvalue.\n\nAttribute: `aria-label`","type":"string | null","default":"null"},{"name":"actionable","description":"Opt-in no-link whole-card action behavior: the hover/focus-visible treatment (border-color shift,\n`cursor: pointer`) plus, when `href` is **not** also set, real activation semantics --\n`[part='activation-button']` becomes the focusable native button, responds to Enter/Space,\nand emits `lr-card-activate`. With `href` set the stretched native `<a>` owns navigation and\n`lr-card-activate` is never fired. `false` (the default) reproduces today's exact static\noutput: no button, no listeners, no events.\n\nAttribute: `actionable`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"appearance","description":"Visual treatment, mirroring `wa-card`'s `appearance` vocabulary. `'outlined'` (the default)\nis a bordered surface -- the common \"small bordered surface with padding\" idiom.\n\nAttribute: `appearance`  \nReflected to its attribute.","type":"LyraAppearance","default":"'outlined'"},{"name":"disabled","description":"Turns the card's OWN activation off: the native `activation-button` renders `disabled`, a\nlinked card's stretched `<a>` loses its `href` (so it genuinely cannot navigate rather than\nmerely claiming `aria-disabled` on a live link, matching `<lr-button>`/`<lr-icon-button>`)\nand leaves the tab order, `lr-card-activate` stops firing from every path including\n`click()`, and the card paints at `--lr-opacity-disabled` with a `not-allowed` cursor.\n\nScoped to the card's own action: a passive card (no `actionable`, no `href`) has nothing to\nturn off, so `disabled` leaves it byte-identical rather than dimming inert content into a\nclaim the card cannot back with behavior. Slotted controls stay the consumer's own to\ndisable -- a card is a container, and silently disabling somebody else's buttons is not a\nstate this component can honestly own.\n\nLike `<lr-icon-button>`, a card is deliberately NOT form-associated (it is a layout\ncontainer, not a form control, and enrolling every card in `form.elements` would be a far\nlarger change than the state it buys), so an ancestor `<fieldset disabled>` does not cascade\nhere -- disable each card explicitly.\n\nAttribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"href","description":"When set, a real stretched `<a href=...>` renders behind the card's consumer slots for a\nwhole-card link (e.g. a wide CTA tile). Slotted controls remain independent actions; clicks\nin noninteractive card content still follow the link. Unset (the default) renders a plain\n`<div>`.\n\nAttribute: `href`","type":"string | undefined"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"orientation","description":"Section flow, using the shared `LyraOrientation` vocabulary. Horizontal cards arrange\nmedia, body, and `actions` side by side.\n\nAttribute: `orientation`  \nReflected to its attribute.","type":"LyraOrientation","default":"'vertical'"},{"name":"rel","description":"Author-settable relationship tokens. `opener` is always stripped; whenever `target` is set,\nthe rendered link force-adds `noopener noreferrer` without discarding other tokens.\n\nAttribute: `rel`","type":"string | undefined"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"target","description":"Native anchor target, used only while `href` resolves to a link. Any target forces the\n`noopener noreferrer` security floor while preserving safe author `rel` tokens.\n\nAttribute: `target`","type":"string | undefined"},{"name":"withFooter","description":"Attribute: `with-footer`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"withFooterActions","description":"Attribute: `with-footer-actions`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"withHeader","description":"SSR presence hints. Hydrated cards also detect populated slots automatically.\n\nAttribute: `with-header`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"withHeaderActions","description":"Attribute: `with-header-actions`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"withMedia","description":"Attribute: `with-media`  \nReflected to its attribute.","type":"boolean","default":"false"}],"events":[{"name":"lr-card-activate","description":"The whole card was activated (click, or Enter/Space on the native `activation-button`). No detail. Only fired while `actionable` is set **without** `href` -- with `href` the stretched native `<a>` is the activation. Never fired for an interaction that originated in a slotted control (a button, link, input, or anything else focusable), so a card can keep its own action buttons.","type":"CustomEvent<null>"}]}},{"name":"lr-carousel","description":"`<lr-carousel>` — a scroll-snap carousel for arbitrary slotted content. Its Web Awesome and\nShoelace-compatible surface supports optional navigation and pagination, multiple slides per\npage, horizontal or vertical movement, autoplay, looping, and opt-in mouse dragging.\nManual active-page changes are announced through a pre-mounted light-DOM live region even while\nautoplay is enabled. Only timer-driven advances stay silent, and neither initial connection nor\nreconnection replays the current page. Changes made while the carousel or a composed ancestor is\naccessibility-hidden stay silent. Subtree-pruned slide content is omitted; a visibility-hidden\nwrapper may still expose a descendant that explicitly restores visibility. Forwarding slots\ncontribute their flattened assigned content; their fallback contributes only when the slot has\nno direct assignment, even when an assignment is itself accessibility-hidden. The localized\n`carouselSlideAnnouncement` and `carouselSlideAnnouncementSeparator` messages control the order,\npunctuation, and separation of spoken position/content summaries.\nAssigned slide semantics remain author-owned after connection: later `role`, `aria-label`,\n`aria-roledescription`, `hidden`, `inert`, and `aria-hidden` changes persist through carousel\nupdates. Off-page slides are temporarily inert and aria-hidden, then regain their retained\nauthor state when visible, unassigned, or disconnected.\nLoop endcaps snapshot only side-effect-free plain HTML and stay synchronized with light-DOM\nmutations. Slides containing custom elements, media/resources, form state, scripts, styles, or\nnon-HTML descendants use their original element for wrap alignment instead, so loop mode never\nduplicates component lifecycles, network/playback owners, or stateful controls.\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) | Slide elements. Each assigned element becomes one slide. |\n| `next-icon` | Optional decorative next-navigation icon. Its flattened subtree remains visible but is inert and hidden from assistive technology; the native button is the action. |\n| `previous-icon` | Optional decorative previous-navigation icon, with the same inert visual content contract as `next-icon`. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | Compatibility name for the carousel landmark; use `carousel`. |\n| `carousel` | The carousel landmark. It is the same node as `base`. |\n| `controls` | Lyra extension wrapping enabled navigation and pagination. |\n| `indicator-dot` | Compact visible dot inside a pagination button. |\n| `navigation` | The previous/next navigation wrapper. |\n| `navigation-button` | Shared navigation button part. |\n| `navigation-button--next` | Shoelace name for the next navigation button. |\n| `navigation-button--previous` | Shoelace name for the previous navigation button. |\n| `navigation-button-next` | Next navigation button. |\n| `navigation-button-previous` | Previous navigation button. |\n| `next-glyph` | Wrapper around the next-icon slot. |\n| `pagination` | The pagination wrapper. |\n| `pagination-item` | A pagination button. |\n| `pagination-item--active` | Shoelace name for the active pagination button. |\n| `pagination-item-active` | The active pagination button. |\n| `previous-glyph` | Wrapper around the previous-icon slot. |\n| `scroll-container` | The keyboard-focusable scroll-snap viewport. Arrow/Home/End navigation leaves descendant editors and interactive controls in charge of their own keys. |\n| `track` | Lyra extension wrapping the slotted slides and eligible inert loop snapshots. |\n\n---\n\n**CSS Custom Properties**\n\n- `--aspect-ratio` (default: `16/9`) — Aspect ratio inherited by each slide.\n- `--lr-carousel-indicator-current-bg` (default: `var(--lr-color-brand-quiet)`) — Active dot fill.\n- `--lr-carousel-indicator-current-border-color` (default: `var(--lr-color-brand)`) — Active dot border.\n- `--lr-carousel-navigation-active-bg` — Navigation pressed background; defaults to the former brand-quiet active mix.\n- `--lr-carousel-navigation-active-border-color` (default: `var(--lr-color-brand)`) — Navigation pressed border.\n- `--lr-carousel-navigation-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Navigation hover background.\n- `--lr-carousel-navigation-hover-border-color` (default: `var(--lr-color-brand)`) — Navigation hover border.\n- `--lr-carousel-pagination-active-bg` — Pagination-dot pressed background; defaults to the former brand-quiet active mix.\n- `--lr-carousel-pagination-active-border-color` (default: `var(--lr-color-brand)`) — Pagination-dot pressed border.\n- `--lr-carousel-pagination-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Pagination-dot hover background.\n- `--lr-carousel-pagination-hover-border-color` (default: `var(--lr-color-brand)`) — Pagination-dot hover border.\n- `--lr-carousel-scroll-container-hover-outline-color` (default: `var(--lr-color-border-strong)`) — Outline color of the mouse-hover preview on `[part=\"scroll-container\"]`. Set to `transparent` to opt out of the hover treatment entirely.\n- `--lr-carousel-scroll-container-hover-outline-offset` (default: `var(--lr-focus-ring-offset)`) — Offset of the mouse-hover preview on `[part=\"scroll-container\"]`.\n- `--lr-carousel-scroll-container-hover-outline-style` (default: `solid`) — Outline style of the mouse-hover preview on `[part=\"scroll-container\"]`.\n- `--lr-carousel-scroll-container-hover-outline-width` (default: `var(--lr-border-width-thin)`) — Outline width of the mouse-hover preview on `[part=\"scroll-container\"]`.\n- `--lr-carousel-slide-basis` — Compatibility override for the computed per-page basis.\n- `--scroll-hint` — Logical padding that reveals the nearest adjacent slides.\n- `--slide-gap` (default: `var(--lr-space-m)`) — Gap between slides.","attributes":[{"name":"accessible-label","description":"Accessible name used when the host has no `aria-label`; omitted falls back to the localized\n`carouselLabel` default. An explicitly empty `accessible-label` is used as-is.\n\nType: `string | undefined`"},{"name":"aria-label","description":"Type: `| string\n    | null`  \nDefault: `null`"},{"name":"autoplay","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"autoplay-interval","description":"Type: `number`  \nDefault: `3000`","value":{"type":["number"]}},{"name":"current-slide","description":"Zero-based start of the active slide page.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"currentSlide","description":"Web Awesome compatibility alias for `current-slide`; HTML normalizes it to `currentslide` at runtime. When both are present initially, `current-slide` wins.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"loop","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"mouse-dragging","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"navigation","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"orientation","description":"Type: `LyraCarouselOrientation`  \nDefault: `'horizontal'`","value":{"type":["'horizontal'","'vertical'"]}},{"name":"pagination","description":"Whether page indicators are rendered.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"slides-per-move","description":"Type: `number`  \nDefault: `1`","value":{"type":["number"]}},{"name":"slides-per-page","description":"Type: `number`  \nDefault: `1`","value":{"type":["number"]}}],"slots":[{"name":"","description":"Slide elements. Each assigned element becomes one slide."},{"name":"next-icon","description":"Optional decorative next-navigation icon. Its flattened subtree remains visible but is inert and hidden from assistive technology; the native button is the action."},{"name":"previous-icon","description":"Optional decorative previous-navigation icon, with the same inert visual content contract as `next-icon`."}],"js":{"properties":[{"name":"accessibleLabel","description":"Accessible name used when the host has no `aria-label`; omitted falls back to the localized\n`carouselLabel` default. An explicitly empty `accessible-label` is used as-is.\n\nAttribute: `accessible-label`","type":"string | undefined"},{"name":"autoplay","description":"Attribute: `autoplay`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"autoplayInterval","description":"Attribute: `autoplay-interval`","type":"number","default":"3000"},{"name":"currentSlide","description":"Zero-based start of the active slide page.\n\nAttribute: `current-slide`  \nReflected to its attribute.","type":"number","default":"0"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"loop","description":"Attribute: `loop`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"mouseDragging","description":"Attribute: `mouse-dragging`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"navigation","description":"Attribute: `navigation`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"orientation","description":"Attribute: `orientation`","type":"LyraCarouselOrientation","default":"'horizontal'"},{"name":"pagination","description":"Whether page indicators are rendered.\n\nAttribute: `pagination`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"slides","description":"Live count of assigned slides.","type":"number","default":"0","read-only":true},{"name":"slidesPerMove","description":"Attribute: `slides-per-move`","type":"number","default":"1"},{"name":"slidesPerPage","description":"Attribute: `slides-per-page`","type":"number","default":"1"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-slide-change","description":"Active slide changed. `detail: { index, slide }`.","type":"CustomEvent<{ index: number; slide: HTMLElement }>"}]}},{"name":"lr-carousel-item","description":"`<lr-carousel-item>` — an optional semantic wrapper for one child of\n`<lr-carousel>`. A carousel also accepts arbitrary slotted elements, so\nthis element is convenience syntax for migrations and for consistent item styling.\nIts author-supplied slide semantics remain in effect when changed after connection; an owning\ncarousel only temporarily applies inertness and aria-hidden state while the item is off page.\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) | Slide content. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The slide wrapper. |\n\n---\n\n**CSS Custom Properties**\n\n- `--aspect-ratio` — The slide aspect ratio, inherited from an owning carousel by default.","attributes":[{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"slots":[{"name":"","description":"Slide content."}],"js":{"properties":[{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}]}},{"name":"lr-chart","description":"`<lr-chart>` — the core Chart.js wrapper used directly and by the typed\nChart.js tags plus `<lr-histogram>`. `<lr-lite-chart>` and `<lr-box-plot>`\nare independent implementations. Requires the optional peer dep `chart.js`; `chartjs-plugin-zoom`\n(for `zoom`) and `chartjs-plugin-datalabels` (for `data-labels`/`stack-totals`)\nare further optional peers loaded only on demand.\nWith IntersectionObserver available, canvas construction waits for the first delivered\nvisibility decision; without it, drawing starts as soon as the peer and canvas are ready.\nSimplified pie/doughnut datasets with magnitudes above Number.MAX_SAFE_INTEGER are uniformly\nscaled for finite peer arc geometry. Legends, tooltips, data labels and semantic exports retain\noriginal values; direct peer callbacks see scaled values. Explicit config.data is passed through.\n\n**API mirror note:** the real `wa-chart` docs page\n(https://webawesome.com/docs/components/chart/) documents a `config:\nChartJS['config']` property alongside its simplified attributes — \"a\nflexible wrapper around Chart.js\" supporting *both* simplified attributes\nand full Chart.js configuration passthrough, not a `data`/`options` prop\npair. `lr-chart` mirrors that dual surface: the `LyraChartSeries`-based\n`datasets`/`labels`/`type`/`withoutLegend`/`xLabel`/`yLabel`/`zoom` attributes\nbelow are the simplified surface (compatible with WA's `type`, `xLabel`,\n`yLabel`, `withoutLegend`, etc.), and the additional\n`config` property is the raw-passthrough escape hatch — a\n`LyraChartConfiguration` deep-merged over the generated config in\n`buildConfig()`, mirroring WA's `config` property without discarding the\n`LyraChartSeries` shape the rest of this component family (subclasses, box-plot,\nhistogram) is built on.\n\n`datasets`, `annotations`, and `hiddenDatasets` take bounded, clone-owned readonly snapshots.\nCreate a new collection and reassign it after changes; mutating the assigned array does not\nupdate the view. `labels` does not yet share this contract.\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) | An optional `<script type=\"application/json\">` containing a Chart.js configuration. |\n| `center` | Optional overlay content positioned at the chart area's center. Useful for doughnut and pie totals. |\n| `data-table` | An optional consumer-provided accessible table alternative. Use this escape hatch for a complete paginated or virtualized alternative when the generated 1,000-record sample is insufficient. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The chart wrapper. |\n| `canvas` | The Chart.js canvas. |\n| `center` | The chart-area-centered overlay wrapper for the `center` slot. |\n| `data-table` | The optional generated or slotted data table. |\n| `data-table-toggle` | The disclosure button rendered by `dataTableToggle`. |\n| `data-truncation` | Explanation shown when the generated accessible alternative samples a data set larger than its 1,000-record ceiling. |\n| `description` | The accessible chart summary. |\n| `error` | Static visible error shown instead of `canvas` when the optional `chart.js` peer dependency is not installed; its transition is announced through a shared light-DOM alert. |\n| `feature-warning` | Static nonfatal warning when a requested optional feature peer is unavailable while the core chart remains usable. |\n| `legend` | The wrapping DOM legend, rendered unless `withoutLegend` is set. |\n| `legend-item` | A keyboard-operable dataset or category visibility toggle. |\n| `legend-item-hidden` | Added while the legend item's dataset or category is hidden. |\n| `legend-swatch` | The resolved dataset/category color swatch in a legend item. |\n| `notices` | Wrapper for nonfatal feature warnings and generated-data truncation notices. |\n| `plot` | The fixed-height canvas/overlay region. |\n| `reset-zoom-button` | The reset-zoom control when zoom is active. |\n\n---\n\n**CSS Custom Properties**\n\n- `--border-color-1` (default: `var(--lr-color-chart-1)`) — First dataset border color.\n- `--border-color-2` (default: `var(--lr-color-chart-2)`) — Second dataset border color.\n- `--border-color-3` (default: `var(--lr-color-chart-3)`) — Third dataset border color.\n- `--border-color-4` (default: `var(--lr-color-chart-4)`) — Fourth dataset border color.\n- `--border-color-5` (default: `var(--lr-color-chart-5)`) — Fifth dataset border color.\n- `--border-color-6` (default: `var(--lr-color-chart-6)`) — Sixth dataset border color.\n- `--border-radius` (default: `var(--lr-radius)`) — Dataset element corner radius.\n- `--border-width` (default: `var(--lr-border-width-thin)`) — Dataset element border width.\n- `--fill-color-1` (default: `var(--lr-color-chart-1)`) — First dataset fill color.\n- `--fill-color-2` (default: `var(--lr-color-chart-2)`) — Second dataset fill color.\n- `--fill-color-3` (default: `var(--lr-color-chart-3)`) — Third dataset fill color.\n- `--fill-color-4` (default: `var(--lr-color-chart-4)`) — Fourth dataset fill color.\n- `--fill-color-5` (default: `var(--lr-color-chart-5)`) — Fifth dataset fill color.\n- `--fill-color-6` (default: `var(--lr-color-chart-6)`) — Sixth dataset fill color.\n- `--grid-border-width` (default: `var(--lr-border-width-thin)`) — Axis and grid line width.\n- `--grid-color` (default: `var(--lr-chart-grid-color)`) — Grid line color.\n- `--line-border-width` (default: `var(--lr-border-width-medium)`) — Line dataset stroke width.\n- `--lr-chart-canvas-hover-outline-color` (default: `var(--lr-chart-grid-color)`) — Color of the `[part='canvas']` hover-state outline.\n- `--lr-chart-canvas-hover-outline-width` (default: `var(--lr-border-width-thin)`) — Width of the `[part='canvas']` hover-state outline.\n- `--lr-chart-data-table-button-active-bg` — Pressed background of an actionable generated- table value; defaults to the standard active mix of `--lr-color-brand-quiet`.\n- `--lr-chart-data-table-button-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background of an actionable generated-table value.\n- `--lr-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-chart-data-table-toggle-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background of the `dataTableToggle` disclosure button.\n- `--lr-chart-grid-color` (default: `var(--lr-color-border)`) — Grid-line color. Resolved via `getComputedStyle` on every draw (Chart.js paints to canvas and cannot consume `var()`).\n- `--lr-chart-height` (default: `var(--lr-size-280px)`) — The plot region's `block-size` and the host's minimum block size. A visible data table or wrapping DOM legend grows the host in normal flow instead of overlapping following content. `height` supplies a private fallback; this public token always wins when a consumer sets it.\n- `--lr-chart-legend-color` (default: `var(--lr-color-text)`) — Legend label color. Resolved via `getComputedStyle` on every draw.\n- `--lr-chart-legend-item-active-bg` — Pressed background of a legend visibility button; defaults to the standard active mix of `--lr-color-brand-quiet`.\n- `--lr-chart-legend-item-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background of a legend visibility button.\n- `--lr-chart-legend-side-max` (default: `var(--lr-size-15rem)`) — Maximum inline size reserved for a side-positioned DOM legend; the track is also capped at one third of the chart allocation.\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 every series collapses to one system color and the stripe/crosshatch pattern 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.\n- `--lr-chart-reset-zoom-button-active-bg` — Pressed background of the reset-zoom button; defaults to the standard active mix of `--lr-color-brand-quiet`.\n- `--lr-chart-reset-zoom-button-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background of the reset-zoom button.\n- `--lr-chart-tick-color` (default: `var(--lr-color-text-quiet)`) — Axis tick-label color; also used for the `xLabel`/`yLabel`/`y2Label` axis-title text (there is no separate title-color token). Resolved via `getComputedStyle` on every draw.\n- `--lr-chart-tick-font-size` (default: `var(--lr-font-size-xs)`) — Axis tick-label font size, in any CSS length unit. Defaults to `--lr-font-size-xs` (12px at the standard root) because that matches Chart.js's OWN built-in tick font size, which is what every canvas chart rendered before this token existed -- leaving it unset must stay byte-identical to that, not shrink to `<lr-lite-chart>`'s SVG default. Also sizes the radar/polarArea `r`-scale `pointLabels` (the spoke labels), but ONLY once set: those default separately to Chart.js's OWN distinct `RadialLinearScale` `pointLabels` default (10px, not this token's 12px), and only adopt this token's size once the consumer explicitly sets it, at which point ticks and point labels match. Resolved via `getComputedStyle` on every draw, same constraint as every other `--lr-chart-*` token here (Chart.js paints to canvas and cannot consume `var()`).\n- `--lr-chart-tooltip-bg` (default: `var(--lr-color-surface)`) — Tooltip background color. Resolved via `getComputedStyle` on every draw.\n- `--lr-chart-tooltip-text` (default: `var(--lr-color-text)`) — Tooltip text color. Resolved via `getComputedStyle` on every draw.\n- `--point-radius` (default: `var(--lr-space-2xs)`) — Line/scatter point radius.","attributes":[{"name":"area","description":"Chart-wide default fill-under-line setting for line-type series; a series's own `LyraChartSeries.fill` overrides it.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"axes","description":"Complete cartesian axis visibility, independent of grid. `y` also controls the y2 axis.\nRadial charts ignore this setting. Explicit config scale options retain precedence.\n\nType: `LyraChartAxes`  \nDefault: `'both'`","value":{"type":["'x'","'y'","'both'","'none'"]}},{"name":"begin-at-zero","description":"Type: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"compact","description":"Compact cartesian plot: hide axes and remove automatic layout padding. Set height and\nwithoutLegend for a small histogram/sparkline. Preserves data tables, tooltips and keyboard\nactions; radial charts ignore this setting. Explicit config options retain precedence.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"data-labels","description":"Draws each data point's value on the chart via the optional\n`chartjs-plugin-datalabels` peer. Unset (the default) leaves labels off for\nthis chart; the peer is attached only to instances that opt in, and\n`buildConfig()` keeps its per-chart options disabled until this is set. The\nscreen-reader equivalent is the always-present data table (see\n`show-data-table`); labels are a purely visual, canvas-only addition.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"data-table-toggle","description":"Render a disclosure button above the accessible data table so a sighted reader can reveal the\nnumbers behind the chart on demand. `showDataTable` alone is all-or-nothing -- the table is\neither permanently screen-reader-only or permanently visible -- which left a consumer wrapping\na duplicated table in their own `<details>`.\n\nWith this set, `showDataTable` becomes the disclosure's *initial* state rather than its whole\nbehavior. The table stays in the DOM in both states, so assistive technology never loses it.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"description","description":"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`"},{"name":"grid","description":"Controls which cartesian grid axes are drawn.\n\nType: `LyraChartGrid`  \nDefault: `'both'`","value":{"type":["'x'","'y'","'both'","'none'"]}},{"name":"height","description":"Type: `string`  \nDefault: `'280px'`","value":{"type":["string"]}},{"name":"index-axis","description":"Chart.js index axis. `'y'` is Chart.js's own mechanism for horizontal bars (it also flips\nline/area types onto a horizontal category axis).\n\nType: `LyraChartIndexAxis`  \nDefault: `'x'`","value":{"type":["'x'","'y'"]}},{"name":"label","description":"Accessible chart label. A host `aria-label` still has highest precedence.\n\nType: `string | null`  \nDefault: `null`"},{"name":"legend-display","description":"`auto` retains optional legend formatting; `label` omits values even with a formatter; `value`\nappends a formatted value. `percentage` uses locale percentages of the absolute represented\nlegend values, including hidden items (zero totals yield 0%). `value-percentage` appends both,\nas `label: value (percentage)`. Dataset values are sampled sums; category values come from the\nfirst dataset. The `formatter`/`valueFormatter` callback backing `value` and `value-percentage`\nadditionally receives that same `percentage` in its `surface: 'legend'` context, so a custom\nformatter can build its own combined text without recomputing the share. Tooltip and axis\nformatting are unchanged.\n\nType: `LyraChartLegendDisplay`  \nDefault: `'auto'`","value":{"type":["'auto'","'label'","'value'","'percentage'","'value-percentage'"]}},{"name":"legend-mode","description":"`datum` renders category toggles for pie/doughnut/polar-area charts. Categories use the first\ndataset's colors and values; a toggle affects that category in every ring. Other chart types\nretain dataset legends. `auto` (the default) resolves to `datum` on pie/doughnut/polar-area\ncharts -- where a single-dataset legend would otherwise enumerate one entry for the whole\ndataset instead of one per visible slice -- and to `dataset` everywhere else. `dataset` always\nforces the dataset legend, even on a slice chart. Both non-`auto` modes use the generated\naccessible-data sampling budget.\n\nType: `LyraChartLegendMode`  \nDefault: `'auto'`","value":{"type":["'auto'","'dataset'","'datum'"]}},{"name":"legend-position","description":"Legend placement. `auto` uses a right legend above 480px and a bottom legend below it.\n\nType: `LyraChartLegendPosition`  \nDefault: `'top'`","value":{"type":["'left'","'top'","'right'","'bottom'","'center'","'chartArea'","'start'","'end'","'auto'"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max","description":"Maximum value-axis bound. Non-finite values are ignored.\n\nType: `number | null`  \nDefault: `null`"},{"name":"min","description":"Minimum value-axis bound. Non-finite values are ignored.\n\nType: `number | null`  \nDefault: `null`"},{"name":"plugins","description":"Chart.js plugins attached to this chart instance. Valid plugins retain their opaque identity.\n\nType: `readonly LyraChartPlugin[]`  \nDefault: `[]`"},{"name":"scale-type","description":"Scale type for the **value** axis (the categorical axis is unaffected). `'logarithmic'` plots\na dataset spanning several orders of magnitude honestly, where a linear axis collapses\neverything below the maximum into the baseline. Inherited by `lr-line-chart`,\n`lr-scatter-chart` and `lr-bar-chart`.\n\nA logarithmic axis cannot represent zero or negative values (`log(0)` is `-Infinity`), so\n`beginAtZero` is not forwarded in that mode -- Chart.js would otherwise be handed a bound it\ncannot place. Non-positive data points are dropped by Chart.js's own log scale.\n\nType: `LyraChartScaleType`  \nDefault: `'linear'`","value":{"type":["'linear'","'logarithmic'"]}},{"name":"show-data-table","description":"Makes the generated data table visible; it remains screen-reader available when false.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"stack-totals","description":"When the chart is `stacked` (bar/line only), draws the per-category stack\ntotal above each stack, via the same optional `chartjs-plugin-datalabels`\npeer as `data-labels`. Null/undefined points are skipped; a category whose\nevery value is null shows no total. The generated accessible data table\nreceives the same formatted total column (one per value axis). Unset (the\ndefault) draws and adds nothing.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"stacked","description":"Stacks the `x`/`y`(/`y2`) scale entries `buildScales()` returns; only meaningful for `bar` and `line` types.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"type","description":"Type: `LyraChartType`  \nDefault: `'bar'`","value":{"type":["'line'","'bar'","'scatter'","'pie'","'doughnut'","'radar'","'polarArea'","'bubble'"]}},{"name":"without-animation","description":"Disables Chart.js animation.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"without-legend","description":"Hides the legend.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"without-tooltip","description":"Hides Chart.js tooltips.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"x-label","description":"Type: `string | null`  \nDefault: `null`"},{"name":"y-label","description":"Type: `string | null`  \nDefault: `null`"},{"name":"y2-label","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"zoom","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"","description":"An optional `<script type=\"application/json\">` containing a Chart.js configuration."},{"name":"center","description":"Optional overlay content positioned at the chart area's center. Useful for doughnut and pie totals."},{"name":"data-table","description":"An optional consumer-provided accessible table alternative. Use this escape hatch for a complete paginated or virtualized alternative when the generated 1,000-record sample is insufficient."}],"js":{"properties":[{"name":"annotations","description":"Declarative reference lines and shaded bands — a threshold, an event year, a regime change, a\nhighlighted period. Each entry marks either a single `value` or a `from`/`to` range on `axis`\n(default `'y'`), with an optional `label` and semantic `tone`.\n\nNeeds the optional `chartjs-plugin-annotation` peer, loaded on first actual demand so a page\nwith no annotated charts never downloads it. The plugin is registered globally, like\n`chartjs-plugin-zoom` and unlike `chartjs-plugin-datalabels`: it draws nothing unless a chart\nsupplies annotation options, so the registration is unobservable to charts that set none, and\nregistration is also what installs the plugin's own element defaults. Without the peer\ninstalled the chart still renders; a console warning plus a localized visible warning and\nlight-DOM announcement explain the no-op — the same fail-closed contract `data-labels` uses.\n\nEntries are included in the generated accessible description, mirroring `lr-heatmap`.","type":"readonly LyraChartAnnotation[]","default":"[]"},{"name":"area","description":"Chart-wide default fill-under-line setting for line-type series; a series's own `LyraChartSeries.fill` overrides it.\n\nAttribute: `area`","type":"boolean","default":"false"},{"name":"axes","description":"Complete cartesian axis visibility, independent of grid. `y` also controls the y2 axis.\nRadial charts ignore this setting. Explicit config scale options retain precedence.\n\nAttribute: `axes`","type":"LyraChartAxes","default":"'both'"},{"name":"beginAtZero","description":"Attribute: `begin-at-zero`","type":"boolean","default":"true"},{"name":"chart","description":"The current Chart.js instance. Read it only while the element is connected and loaded.","type":"LyraChartInstance | undefined"},{"name":"chartArea","description":"The current Chart.js chart-area geometry in canvas-local coordinates. Read-only -- derived\nfrom the live Chart.js instance's own layout pass, never assignable. The setter is a\ndocumented no-op (matching `lr-histogram`'s `labels`/`datasets` pattern) so an accidental\n`.chartArea=${x}` Lit template binding degrades silently instead of throwing from inside\nlit-html's property-commit.","type":"LyraChartArea | undefined"},{"name":"compact","description":"Compact cartesian plot: hide axes and remove automatic layout padding. Set height and\nwithoutLegend for a small histogram/sparkline. Preserves data tables, tooltips and keyboard\nactions; radial charts ignore this setting. Explicit config options retain precedence.\n\nAttribute: `compact`","type":"boolean","default":"false"},{"name":"config","type":"LyraChartConfiguration | undefined"},{"name":"dataLabels","description":"Draws each data point's value on the chart via the optional\n`chartjs-plugin-datalabels` peer. Unset (the default) leaves labels off for\nthis chart; the peer is attached only to instances that opt in, and\n`buildConfig()` keeps its per-chart options disabled until this is set. The\nscreen-reader equivalent is the always-present data table (see\n`show-data-table`); labels are a purely visual, canvas-only addition.\n\nAttribute: `data-labels`","type":"boolean","default":"false"},{"name":"dataTableToggle","description":"Render a disclosure button above the accessible data table so a sighted reader can reveal the\nnumbers behind the chart on demand. `showDataTable` alone is all-or-nothing -- the table is\neither permanently screen-reader-only or permanently visible -- which left a consumer wrapping\na duplicated table in their own `<details>`.\n\nWith this set, `showDataTable` becomes the disclosure's *initial* state rather than its whole\nbehavior. The table stays in the DOM in both states, so assistive technology never loses it.\n\nAttribute: `data-table-toggle`","type":"boolean","default":"false"},{"name":"datasets","description":"Simplified chart series. Non-record entries are dropped while valid sibling series remain.","type":"readonly LyraChartSeries[]"},{"name":"description","description":"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\nAttribute: `description`","type":"string | null","default":"null"},{"name":"formatter","description":"Unified context-object formatter for visual, tooltip, table/export, and spoken values.","type":"LyraChartFormatter | undefined"},{"name":"grid","description":"Controls which cartesian grid axes are drawn.\n\nAttribute: `grid`","type":"LyraChartGrid","default":"'both'"},{"name":"height","description":"Attribute: `height`","type":"string","default":"'280px'"},{"name":"hiddenDatasets","description":"Complete controlled visibility state for DOM legend toggles. `undefined` (the default) honors\neach effective dataset's `hidden` configuration; a defined array wins over those defaults, and\nan empty array deliberately makes every dataset visible. Invalid, duplicate, and out-of-range\nindexes are ignored when state is applied or emitted.","type":"readonly number[] | undefined"},{"name":"hiddenDatums","description":"Controlled hidden source category indexes for pie/doughnut/polar-area charts, shared by all\ndatasets/rings. Clone-owned; invalid, duplicate and out-of-range indexes are ignored when\napplied or emitted. Empty restores all categories. Does not alter dataset visibility or exports.","type":"readonly number[]","default":"[]"},{"name":"indexAxis","description":"Chart.js index axis. `'y'` is Chart.js's own mechanism for horizontal bars (it also flips\nline/area types onto a horizontal category axis).\n\nAttribute: `index-axis`","type":"LyraChartIndexAxis","default":"'x'"},{"name":"label","description":"Accessible chart label. A host `aria-label` still has highest precedence.\n\nAttribute: `label`","type":"string | null","default":"null"},{"name":"labels","type":"string[]","default":"[]"},{"name":"legendDisplay","description":"`auto` retains optional legend formatting; `label` omits values even with a formatter; `value`\nappends a formatted value. `percentage` uses locale percentages of the absolute represented\nlegend values, including hidden items (zero totals yield 0%). `value-percentage` appends both,\nas `label: value (percentage)`. Dataset values are sampled sums; category values come from the\nfirst dataset. The `formatter`/`valueFormatter` callback backing `value` and `value-percentage`\nadditionally receives that same `percentage` in its `surface: 'legend'` context, so a custom\nformatter can build its own combined text without recomputing the share. Tooltip and axis\nformatting are unchanged.\n\nAttribute: `legend-display`","type":"LyraChartLegendDisplay","default":"'auto'"},{"name":"legendMode","description":"`datum` renders category toggles for pie/doughnut/polar-area charts. Categories use the first\ndataset's colors and values; a toggle affects that category in every ring. Other chart types\nretain dataset legends. `auto` (the default) resolves to `datum` on pie/doughnut/polar-area\ncharts -- where a single-dataset legend would otherwise enumerate one entry for the whole\ndataset instead of one per visible slice -- and to `dataset` everywhere else. `dataset` always\nforces the dataset legend, even on a slice chart. Both non-`auto` modes use the generated\naccessible-data sampling budget.\n\nAttribute: `legend-mode`","type":"LyraChartLegendMode","default":"'auto'"},{"name":"legendPosition","description":"Legend placement. `auto` uses a right legend above 480px and a bottom legend below it.\n\nAttribute: `legend-position`","type":"LyraChartLegendPosition","default":"'top'"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"max","description":"Maximum value-axis bound. Non-finite values are ignored.\n\nAttribute: `max`","type":"number | null","default":"null"},{"name":"min","description":"Minimum value-axis bound. Non-finite values are ignored.\n\nAttribute: `min`","type":"number | null","default":"null"},{"name":"plugins","description":"Chart.js plugins attached to this chart instance. Valid plugins retain their opaque identity.\n\nAttribute: `plugins`","type":"readonly LyraChartPlugin[]","default":"[]"},{"name":"scaleType","description":"Scale type for the **value** axis (the categorical axis is unaffected). `'logarithmic'` plots\na dataset spanning several orders of magnitude honestly, where a linear axis collapses\neverything below the maximum into the baseline. Inherited by `lr-line-chart`,\n`lr-scatter-chart` and `lr-bar-chart`.\n\nA logarithmic axis cannot represent zero or negative values (`log(0)` is `-Infinity`), so\n`beginAtZero` is not forwarded in that mode -- Chart.js would otherwise be handed a bound it\ncannot place. Non-positive data points are dropped by Chart.js's own log scale.\n\nAttribute: `scale-type`","type":"LyraChartScaleType","default":"'linear'"},{"name":"showDataTable","description":"Makes the generated data table visible; it remains screen-reader available when false.\n\nAttribute: `show-data-table`","type":"boolean","default":"false"},{"name":"stackTotals","description":"When the chart is `stacked` (bar/line only), draws the per-category stack\ntotal above each stack, via the same optional `chartjs-plugin-datalabels`\npeer as `data-labels`. Null/undefined points are skipped; a category whose\nevery value is null shows no total. The generated accessible data table\nreceives the same formatted total column (one per value axis). Unset (the\ndefault) draws and adds nothing.\n\nAttribute: `stack-totals`","type":"boolean","default":"false"},{"name":"stacked","description":"Stacks the `x`/`y`(/`y2`) scale entries `buildScales()` returns; only meaningful for `bar` and `line` types.\n\nAttribute: `stacked`","type":"boolean","default":"false"},{"name":"stackedAxes","description":"Per-value-axis override of `stacked`, keyed by `'y'`/`'y2'`. An axis absent from this record\n-- including every axis when the whole property is unset -- falls back to the chart-wide\n`stacked` value, which is what keeps a chart that never sets this byte-identical to before.\nLets a `stacked` bar series on the primary axis sit next to an unstacked overlay series on\n`y2` (via `LyraChartSeries.axis: 'y2'`): set `stackedAxes` to `{ y2: false }` alongside\n`stacked`, or spell out both axes explicitly. The shared categorical axis (`x` for a vertical\nbar/line, or `y` when `indexAxis` is `'y'`) has no independent entry of its own -- it always\nmirrors the resolved `'y'` value, matching Chart.js's own paired index/value-scale stacking\ncontract. Only meaningful for `bar`/`line` types, matching `stacked` itself.","type":"Partial<Record<'y' | 'y2', boolean>> | undefined"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"tooltipFooterFormatter","description":"Tooltip footer formatter -- e.g. a category's stack total under the items. Receives every\nitem the hovered tooltip covers, in the same shape as `tooltipTitleFormatter`. Unset (the\ndefault) leaves Chart.js's own default (no footer).","type":"LyraChartTooltipGroupFormatter | undefined"},{"name":"tooltipTitleFormatter","description":"Tooltip title formatter -- e.g. a scatter point's own name. Receives every item the hovered\ntooltip covers, each in `formatter`'s `'tooltip'`-surface context shape. Unset (the default)\nleaves Chart.js's own default title (the shared category label) in place.","type":"LyraChartTooltipGroupFormatter | undefined"},{"name":"type","description":"Attribute: `type`","type":"LyraChartType","default":"'bar'"},{"name":"valueFormatter","description":"Formats numeric (value-axis) ticks, tooltip values, legend values, and generated accessible\ntable cells from one callback.\nHorizontal scalar tooltips use parsed x, including a raw config indexAxis override;\nstructured points retain their y-value contract. The context-object formatter shares this rule.\nNever runs against the categorical x-axis's own labels (line/bar's `labels` strings) —\nChart.js's category scale passes the tick index to `ticks.callback`, not the label text,\nso formatting it would corrupt the axis.","type":"LyraChartValueFormatter | undefined"},{"name":"withoutAnimation","description":"Disables Chart.js animation.\n\nAttribute: `without-animation`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"withoutLegend","description":"Hides the legend.\n\nAttribute: `without-legend`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"withoutTooltip","description":"Hides Chart.js tooltips.\n\nAttribute: `without-tooltip`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"xLabel","description":"Attribute: `x-label`","type":"string | null","default":"null"},{"name":"y2Label","description":"Attribute: `y2-label`","type":"string","default":"''"},{"name":"yLabel","description":"Attribute: `y-label`","type":"string | null","default":"null"},{"name":"zoom","description":"Attribute: `zoom`","type":"boolean","default":"false"}],"events":[{"name":"lr-before-datum-visibility-change","description":"Cancelable category visibility proposal in datum legend mode. `detail: { index: number, visible: boolean, hiddenDatums: readonly number[] }`. Source category indexes apply to every dataset/ring. The complete detail is frozen.","type":"CustomEvent<LyraChartDatumVisibilityChangeDetail>"},{"name":"lr-before-legend-visibility-change","description":"Cancelable proposal emitted before a DOM legend toggle changes state. `detail` contains the target `datasetIndex`, its proposed `visible` value, and the complete canonical proposed `hiddenDatasets` snapshot.","type":"CustomEvent<LyraChartLegendVisibilityChangeDetail>"},{"name":"lr-datum-activate","description":"Family-normalized activation event. Its detail adds `kind` (`bar`, `point`, `segment`, or `slice`) to the `lr-point-click` detail.","type":"CustomEvent<\n    LyraChartDatumActivateDetail<LyraCoreChartDatumKind>\n  >"},{"name":"lr-datum-visibility-change","description":"Emitted after an accepted category toggle commits the same frozen detail. Programmatic `hiddenDatums` assignments are silent.","type":"CustomEvent<LyraChartDatumVisibilityChangeDetail>"},{"name":"lr-legend-visibility-change","description":"Emitted after an accepted DOM legend toggle commits the same detail. Programmatic `hiddenDatasets` changes reconcile without either event.","type":"CustomEvent<LyraChartLegendVisibilityChangeDetail>"},{"name":"lr-point-click","description":"Fired when pointer input lands on a data point/segment, when a generated data-table value is activated, or when Enter/Space activates the keyboard-current canvas datum. `detail: { datasetIndex: number, index: number, label: string | undefined, value: unknown }`. For scatter/bubble data, `label` prefers the per-point label and `value` is the complete typed `LyraChartPoint` (`x`, `y`, optional `r`, optional `label`).","type":"CustomEvent<{\n    datasetIndex: number;\n    index: number;\n    label: string | undefined;\n    value: unknown;\n  }>"},{"name":"lr-zoom","description":"`detail: { zoomed }`.","type":"CustomEvent<{ zoomed: boolean }>"}]}},{"name":"lr-chat-composer","description":"`<lr-chat-composer>` — the message input for a chat/agent conversation\nsurface: an auto-resizing textarea plus a send/stop button. Form-\nassociated via the `FormAssociated` mixin (see `<lr-date-input>` for the\nsame shape), so it participates in native `<form>` submission/validation/\nreset like any other text control — `name`/`value`/`disabled`/`required`/\n`checkValidity()`/`reportValidity()` all come from that mixin.\n\nAuto-resize reads the textarea's own *computed* line-height/padding/\nborder at runtime (`resizeTextarea()`) rather than assuming a fixed\npx-per-row constant, so it stays correct under a consumer's own font-size/\nline-height overrides. It grows between `min-rows` and `max-rows`, then\nswitches to internal scrolling. A `ResizeObserver` on the textarea itself\nre-runs the same fit whenever its *width* changes (a responsive\nbreakpoint, a sidebar toggling, a window resize, an orientation change)\neven though `value`/`min-rows`/`max-rows` never did -- a narrower box\nwraps the same text across more lines, so the previously-fitted height\nwould otherwise go stale and clip content with no scrollbar to reveal it.\n\nEnter-to-send (only active while `submit-on-enter` is true, the default):\nplain Enter submits and is prevented from inserting a newline; Shift+Enter\nalways inserts a newline no matter what; an IME composition step (checked\nvia `isComposing`, with `keyCode === 229` as a defense-in-depth fallback\nfor browsers that report `isComposing` inconsistently on the\ncompositionend-adjacent keydown) is never treated as a submit trigger;\nand while `status` isn't `\"idle\"` Enter is left alone to insert a newline\ntoo, rather than trying to submit again -- there is nothing meaningful to\nsubmit while a previous message is still sending/streaming, and the\ntextarea deliberately stays interactive (see `disabled` below) so a user\ncan keep composing their next message in the meantime.\n\nDeliberately no label/hint/error chrome -- a composite chat-input control, not a labeled form\nfield; wrap it in your own layout for that context. A host `aria-label` is forwarded to the\ninternal textarea and takes precedence over the placeholder-derived name.\n\n`lr-submit`'s `detail.value` is always the exact, untrimmed current\nvalue (`detail.value === value` at the moment it fires) -- trimming is\nleft to the consumer so it never silently diverges from what `value`\nitself reports. Submitting does not clear `value`; the consumer clears it\nonce the submission has actually been accepted (so e.g. a failed send can\nleave the text in place for retry).\n`submitDisabled` lets the consumer apply its own validation policy without\ndisabling the textarea or the busy-state Stop action.\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| `chips` | An attachment tray rendered above the input row (e.g. files queued for this message). |\n| `end` | Overrides the built-in send/stop button entirely when it has assigned content. |\n| `start` | Content rendered before the textarea (e.g. an attach-file trigger button). |\n| `toolbar` | Auxiliary controls (e.g. a model or provider picker) rendered inside the frame, above the chips tray and input row, sharing `[part=\"base\"]`'s `:focus-within` affordance. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `action-button` | The built-in send/stop button. Absent whenever `end` has assigned content. Style its busy treatment via `:host([status='sending'])`/`:host([status='streaming'])`, or the dedicated `--lr-chat-composer-busy-bg` cssprop below. |\n| `base` | The bordered root container. Drops its card chrome (border, background, padding, radius) under `frame=\"plain\"`, where the focus affordance becomes an underline on this same part instead of the border-color shift. |\n| `chips` | The wrapper around the `chips` slot. Hidden entirely when the slot is empty. |\n| `end` | The wrapper around the `end` slot and the built-in `action-button`. |\n| `row` | The row holding the start slot, textarea, and end slot/button. |\n| `send-glyph` | Directional send glyph wrapper; mirrored automatically in RTL. |\n| `start` | The wrapper around the `start` slot. Hidden entirely when empty. |\n| `stop-glyph` | Symmetric stop glyph wrapper. |\n| `textarea` | The auto-resizing `<textarea>` itself. |\n| `toolbar` | The wrapper around the `toolbar` slot. Hidden entirely when empty, matching `start`/`chips`. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-chat-composer-busy-bg` (default: `var(--lr-color-text-quiet)`) — `action-button` background while `status` is `\"sending\"` or `\"streaming\"`. Scoped separately from the shared `--lr-color-text-quiet` token, which the `textarea` part's placeholder also reads -- overriding this recolors only the busy button, not the placeholder text too.\n- `--lr-chat-composer-background` (default: `var(--lr-color-surface)`) — Fill of the card (`[part=\"base\"]`) while `frame=\"card\"`. `frame=\"plain\"` still removes the fill entirely.\n- `--lr-chat-composer-border-color` (default: `var(--lr-color-border)`) — Resting colour of the card's border. The `:focus-within` border stays on the brand token -- it is state paint, not chrome.\n- `--lr-chat-composer-radius` (default: `var(--lr-radius)`) — Corner radius of the card. `frame=\"plain\"` still squares the corners.\n- `--lr-chat-composer-padding` (default: `var(--lr-space-s)`) — Padding of the card (`[part=\"base\"]`). `frame=\"plain\"` still zeroes it, same as the background/border-color/radius hooks above.\n- `--lr-chat-composer-gap` (default: `var(--lr-space-xs)`) — Row gap between the `toolbar`, `chips` and `row` sections stacked inside `[part=\"base\"]`.\n- `--lr-chat-composer-focus-shadow` (default: `inset 0 calc(-1 * var(--lr-focus-ring-width)) 0 0 var(--lr-focus-ring-color)`) — The `frame=\"plain\"` focus affordance painted on `[part=\"base\"]:focus-within`, replacing the card's border-color shift with an underline since there is no border left to recolor under `plain`. Override to reshape it (a different width/color) or set to `none` to cede focus chrome entirely to a consumer-drawn wrapper -- chosen over a third `frame` value, since every other piece of this card's paint (background/border-color/radius above) is already a cssprop hook rather than a `frame` variant, and `none` already reads naturally as \"I'll draw my own\".","attributes":[{"name":"actions-layout","description":"Arrangement of the `start`/`end` action slots relative to the textarea, on the shared\nliteral-set pattern (`literalSetConverter`, matching `<lr-model-settings-panel>`'s `layout`).\n`'inline'` (the default) keeps today's single flex row. `'stacked'` arranges `start` above\n`end` as a compact rail in one column, beside a `textarea` that spans both rows -- for a\nmulti-row composer where the action buttons would otherwise stretch to the row's full\ncross-axis height. Layout only; slot content, empty-slot hiding and the built-in button are\nunchanged. Invalid direct or attribute values normalize and reflect as `'inline'`.\n\nType: `ChatComposerActionsLayout`","value":{"type":["'inline'","'stacked'"]}},{"name":"aria-label","description":"Accessible name for the internal textarea. Takes precedence over the placeholder-derived name.\n\nType: `string | null`  \nDefault: `null`"},{"name":"autocapitalize","description":"Forwarded to the internal `<textarea>`'s own `autocapitalize`. Empty string omits the\nattribute (browser default).\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"autocomplete","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"autocorrect","description":"Native autocorrect state. Reads are boolean; writes accept boolean or the legacy\n`'off'`/`'false'` string vocabulary and reflect canonical `on`/`off`.\n\nType: `boolean`","value":{"type":["boolean"]}},{"name":"custom-error","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nType: `string | null`  \nDefault: `null`"},{"name":"disabled","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"enterkeyhint","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"form","description":"Type: `HTMLFormElement | string | null`  \nDefault: `null`"},{"name":"frame","description":"Visual chrome, on the library-wide `frame` vocabulary. `'card'` (the default) keeps the\nbordered, filled, padded box. `'plain'` removes the border, background, padding and corner\nradius, so a composer docked inside a chat panel, dialog footer or toolbar that already draws\nits own border doesn't double the frame. Focus stays visible either way: `plain` swaps the\nborder-color shift for an underline across the input row, since there is no border left to\nrecolor.\n\nType: `ChatComposerFrame`  \nDefault: `'card'`","value":{"type":["'card'","'plain'"]}},{"name":"inputmode","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max-rows","description":"Type: `number`  \nDefault: `8`","value":{"type":["number"]}},{"name":"maxlength","description":"Native maximum text length. Unset or invalid values impose no upper bound.\n\nType: `number | undefined`"},{"name":"min-rows","description":"Type: `number`  \nDefault: `1`","value":{"type":["number"]}},{"name":"minlength","description":"Native minimum text length. Unset or invalid values impose no lower bound.\n\nType: `number | undefined`"},{"name":"name","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"placeholder","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"readonly","description":"Native read-only state. The textarea remains focusable/submittable but cannot be user-edited,\nand intrinsic constraints are barred just like a native read-only textarea.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"required","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"spellcheck","description":"Type: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"status","description":"Sending state. Invalid direct or attribute writes normalize and reflect as `idle`.\n\nType: `ChatComposerStatus`","value":{"type":["'idle'","'sending'","'streaming'"]}},{"name":"stoppable","description":"Type: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"submit-disabled","description":"Consumer-controlled validation gate for submission. While idle, disables the built-in Send\nbutton and suppresses Enter/click submission without disabling the textarea. Busy Stop behavior\nremains governed by `status` and `stoppable`.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"submit-on-enter","description":"Type: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"value","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"wrap","description":"Native editing-assistance attributes forwarded to the internal textarea.\n\nType: `ChatComposerWrap`  \nDefault: `'soft'`","value":{"type":["'hard'","'soft'","'off'"]}}],"slots":[{"name":"chips","description":"An attachment tray rendered above the input row (e.g. files queued for this message)."},{"name":"end","description":"Overrides the built-in send/stop button entirely when it has assigned content."},{"name":"start","description":"Content rendered before the textarea (e.g. an attach-file trigger button)."},{"name":"toolbar","description":"Auxiliary controls (e.g. a model or provider picker) rendered inside the frame, above the chips tray and input row, sharing `[part=\"base\"]`'s `:focus-within` affordance."}],"js":{"properties":[{"name":"accessibleLabel","description":"Accessible name for the internal textarea. Takes precedence over the placeholder-derived name.\n\nAttribute: `aria-label`","type":"string | null","default":"null"},{"name":"actionsLayout","description":"Arrangement of the `start`/`end` action slots relative to the textarea, on the shared\nliteral-set pattern (`literalSetConverter`, matching `<lr-model-settings-panel>`'s `layout`).\n`'inline'` (the default) keeps today's single flex row. `'stacked'` arranges `start` above\n`end` as a compact rail in one column, beside a `textarea` that spans both rows -- for a\nmulti-row composer where the action buttons would otherwise stretch to the row's full\ncross-axis height. Layout only; slot content, empty-slot hiding and the built-in button are\nunchanged. Invalid direct or attribute values normalize and reflect as `'inline'`.\n\nAttribute: `actions-layout`  \nReflected to its attribute.","type":"ChatComposerActionsLayout"},{"name":"autocapitalize","description":"Forwarded to the internal `<textarea>`'s own `autocapitalize`. Empty string omits the\nattribute (browser default).\n\nAttribute: `autocapitalize`","type":"string","default":"''"},{"name":"autocomplete","description":"Attribute: `autocomplete`","type":"string","default":"''"},{"name":"autocorrect","description":"Native autocorrect state. Reads are boolean; writes accept boolean or the legacy\n`'off'`/`'false'` string vocabulary and reflect canonical `on`/`off`.\n\nAttribute: `autocorrect`","type":"boolean"},{"name":"customError","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nAttribute: `custom-error`  \nReflected to its attribute.","type":"string | null","default":"null"},{"name":"defaultValue","description":"Attribute: `value`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"disabled","description":"Attribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"enterKeyHint","description":"Attribute: `enterkeyhint`","type":"string","default":"''"},{"name":"form","description":"Attribute: `form`  \nReflected to its attribute.","type":"HTMLFormElement | string | null","default":"null"},{"name":"frame","description":"Visual chrome, on the library-wide `frame` vocabulary. `'card'` (the default) keeps the\nbordered, filled, padded box. `'plain'` removes the border, background, padding and corner\nradius, so a composer docked inside a chat panel, dialog footer or toolbar that already draws\nits own border doesn't double the frame. Focus stays visible either way: `plain` swaps the\nborder-color shift for an underline across the input row, since there is no border left to\nrecolor.\n\nAttribute: `frame`  \nReflected to its attribute.","type":"ChatComposerFrame","default":"'card'"},{"name":"input","description":"The internal native textarea for integrations that require direct DOM access.","type":"HTMLTextAreaElement | null","read-only":true},{"name":"inputMode","description":"Attribute: `inputmode`","type":"string","default":"''"},{"name":"labels","type":"NodeList","read-only":true},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"maxLength","description":"Native maximum text length. Unset or invalid values impose no upper bound.\n\nAttribute: `maxlength`","type":"number | undefined"},{"name":"maxRows","description":"Attribute: `max-rows`","type":"number","default":"8"},{"name":"minLength","description":"Native minimum text length. Unset or invalid values impose no lower bound.\n\nAttribute: `minlength`","type":"number | undefined"},{"name":"minRows","description":"Attribute: `min-rows`","type":"number","default":"1"},{"name":"name","description":"Attribute: `name`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"placeholder","description":"Attribute: `placeholder`","type":"string","default":"''"},{"name":"readOnly","description":"Native read-only state. The textarea remains focusable/submittable but cannot be user-edited,\nand intrinsic constraints are barred just like a native read-only textarea.\n\nAttribute: `readonly`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"required","description":"Attribute: `required`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"selectionDirection","type":"ChatComposerSelectionDirection | null"},{"name":"selectionEnd","type":"number | null"},{"name":"selectionStart","type":"number | null"},{"name":"spellcheck","description":"Attribute: `spellcheck`","type":"boolean","default":"true"},{"name":"status","description":"Sending state. Invalid direct or attribute writes normalize and reflect as `idle`.\n\nAttribute: `status`  \nReflected to its attribute.","type":"ChatComposerStatus"},{"name":"stoppable","description":"Attribute: `stoppable`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"submitDisabled","description":"Consumer-controlled validation gate for submission. While idle, disables the built-in Send\nbutton and suppresses Enter/click submission without disabling the textarea. Busy Stop behavior\nremains governed by `status` and `stoppable`.\n\nAttribute: `submit-disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"submitOnEnter","description":"Attribute: `submit-on-enter`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"validationMessage","type":"string","read-only":true},{"name":"validity","type":"ValidityState","read-only":true},{"name":"value","type":"string"},{"name":"willValidate","type":"boolean","read-only":true},{"name":"wrap","description":"Native editing-assistance attributes forwarded to the internal textarea.\n\nAttribute: `wrap`","type":"ChatComposerWrap","default":"'soft'"}],"events":[{"name":"blur","description":"One realm-correct native `FocusEvent` relayed from the textarea, preserving `relatedTarget`.","type":"FocusEvent"},{"name":"change","description":"One native `Event` relayed from the textarea when its edit is committed.","type":"Event"},{"name":"focus","description":"One realm-correct native `FocusEvent` relayed from the textarea, preserving `relatedTarget`.","type":"FocusEvent"},{"name":"input","description":"One realm-correct native `InputEvent` relayed from the textarea for each user edit.","type":"InputEvent"},{"name":"lr-change","description":"Fired with `detail: { value }` beside the native `change` event.","type":"CustomEvent<{ value: string }>"},{"name":"lr-input","description":"Fired on every user-driven edit of the textarea (not a programmatic `.value` assignment). `detail: { value }`.","type":"CustomEvent<{ value: string }>"},{"name":"lr-invalid","description":"The composer failed a validity check. Cancelable — preventing this alias also prevents the native `invalid` event that produced it.","type":"CustomEvent<null>"},{"name":"lr-stop","description":"Fired by the built-in button while `status` is `\"sending\"` or `\"streaming\"` and `stoppable` is `true` (the default). No detail.","type":"CustomEvent<null>"},{"name":"lr-submit","description":"Fired by Enter (per `submit-on-enter`) or the built-in button while `status=\"idle\"` and `submitDisabled` is false. `detail: { value }`.","type":"CustomEvent<{ value: string }>"}]}},{"name":"lr-chat-message","description":"`<lr-chat-message>` — a role-based message bubble *shell* for a chat/\nagent conversation surface. It renders none of the message content itself:\nthe default slot carries whatever a consumer wants to display (plain\ntext, a `<lr-markdown>`, a custom template, anything at all) and this\ncomponent only supplies the surrounding chrome — alignment/coloring by\n`role`, an avatar/badges header row, an optional collapse toggle, an\nattachments strip, and a status-aware footer (a live-updating status dot +\ntext, the formatted `timestamp`, a built-in retry affordance for\n`status=\"failed\"`, and an `actions` slot for everything else).\n\nNo built-in copy button is rendered. Deciding what \"the copyable text\" of\nan arbitrary slotted message even means (plain text? the rendered\nmarkdown source? something else?) is exactly the kind of content\ninterpretation this shell deliberately stays out of — slot a copy control\ninto `actions` instead. Compose `<lr-copy-button>` with the intended source\ntext, or emit `lr-copy` from a custom control only after its clipboard write\nfulfills, with frozen `detail: { ok: true, text }`. This matches the success\ncontract used by copy controls across the conversation surface.\n\nAccessibility of `status`: the current status is always available as\nplain visible text (`[part=\"status-text\"]`), never color alone. A\ntransition *to* `\"failed\"`, or *from* `\"streaming\"` to `\"sent\"` (a stream\nfinishing), is additionally announced through an internal\n`<lr-live-region>` (see that component's header for the throttled-\nannouncement wiring this composes) so a screen-reader user who isn't\ncurrently focused on this message still learns about it — *unless* the\n`failure` slot has content, in which case this internal announcement is\nskipped: the host's own `role=\"alert\"` failure content is expected to\nannounce itself, and firing both would double-announce the same failure\nwith two different (and differently specific) messages. This differs\nfrom `<lr-typing-indicator>`'s deliberately simpler `role=\"status\"`\napproach — that component only ever has one thing to announce (its own\nmount); this one has a `status` that can flip between several values\nacross a single element's lifetime, which is exactly the coalescing job\n`<lr-live-region>` exists for.\n\n`messageRole` identifies the author (`user`/`assistant`/`system`, matching\nthe vocabulary of chat/completion APIs). The platform `role` property remains available for\nhost semantics; the localized author identity directly names the internal article through its\n`aria-label`, and a host `aria-label` overrides that fallback by attribute presence.\n\n`actionsPosition=\"outside\"` renders the `actions` slot as a sibling immediately after the\nmessage bubble instead of nested inside the footer.\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 message body. |\n| `actions` | Action controls (e.g. copy, retry), rendered at the end of the footer. |\n| `attachments` | File/image attachment chips, rendered below the message body by default; see `attachments-position`. |\n| `avatar` | An avatar/icon for the message author. |\n| `badges` | Small status/metric chips (e.g. token count, latency, model name) — entirely app-supplied; this component computes none of that itself. |\n| `failure` | Only ever rendered while `status=\"failed\"`. Empty (the default), the footer keeps its built-in `[part=\"status-text\"]`/`[part=\"retry-button\"]` exactly as before. The moment this slot has assigned content, that built-in status text and retry button are suppressed — the host is now fully responsible for presenting its own failure UI, and the built-in `chatFailedAnnounce` live-region announcement is suppressed too (see `@event lr-message-retry` below for the effect on that event, and the \"Accessibility of `status`\" paragraph above for the built-in announcement this replaces). Content assigned here should carry `role=\"alert\"` itself when it represents an actionable send failure — this component does not add that role on the host's behalf, since it has no way to know what markup the host puts in this slot. This mirrors `lr-flow-node`'s `header` slot, which replaces that component's own built-in heading row the same way. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `actions` | The wrapper around the `actions` slot. Rendered inside the footer by default; a sibling immediately after `bubble` when `actionsPosition=\"outside\"`. |\n| `attachments` | The wrapper around the `attachments` slot. |\n| `avatar` | The wrapper around the `avatar` slot. |\n| `badges` | The wrapper around the `badges` slot. |\n| `body` | The wrapper around the default slot (the message content). Hidden while `collapsed`. |\n| `bubble` | The message article and bubble root. Programmatically focusable (`tabindex=\"-1\"`) so focus has a stable place to land when the built-in retry button is removed. Its fill, text, and geometry derive from the documented theme hooks. |\n| `collapse-button` | The built-in collapse/expand toggle (only rendered when `collapsible`). |\n| `failure` | The `failure` slot itself (`display: contents` — it contributes no box of its own, so the host's own content lays out exactly as if it were a direct child of `bubble`, with no `::part(failure)` override needed to get there). Only present in the DOM while `status=\"failed\"`. |\n| `footer` | The row below the message body — status, timestamp, retry, and actions. Hidden entirely when none of those have anything to show. |\n| `header` | The row above the message body — avatar, badges, and the collapse toggle. Hidden entirely when none of those have anything to show. |\n| `retry-button` | The built-in retry button (only rendered when `status=\"failed\"`). |\n| `status-indicator` | A small decorative (`aria-hidden`) dot reflecting `status`; absent while `status=\"sent\"`. |\n| `status-text` | The visible text twin of `status-indicator` — carries the state in text, not just color. |\n| `timestamp` | The formatted `timestamp`, rendered in a `<time>` element. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-chat-message-bubble-bg` (default: `var(--lr-color-surface)`) — Bubble fill for every role except `user`.\n- `--lr-chat-message-bubble-color` (default: `var(--lr-color-text)`) — Bubble text color for every role except `user`.\n- `--lr-chat-message-bubble-padding` (default: `var(--lr-space-m)`) — Bubble padding.\n- `--lr-chat-message-bubble-radius` (default: `var(--lr-radius)`) — Bubble corner radius. Bubble-only by design — `collapse-button` and `retry-button` keep reading the shared `--lr-radius`, so a rounder bubble never desyncs the controls from the rest of the library.\n- `--lr-chat-message-failed-bg` (default: `var(--lr-color-danger-quiet)`) — Failed bubble fill.\n- `--lr-chat-message-failed-border-color` (default: `var(--lr-color-danger)`) — Failed bubble border.\n- `--lr-chat-message-failed-footer-color` (default: `var(--lr-color-danger)`) — Failed-message footer text.\n- `--lr-chat-message-failed-indicator-color` (default: `var(--lr-color-danger)`) — Failed indicator.\n- `--lr-chat-message-failed-status-color` (default: `var(--lr-color-danger)`) — Failed status text.\n- `--lr-chat-message-footer-color` (default: `var(--lr-color-text-quiet)`) — Default footer text.\n- `--lr-chat-message-indicator-color` (default: `var(--lr-color-text-quiet)`) — Default status indicator.\n- `--lr-chat-message-max-width` (default: `80%`) — Maximum inline size of the message bubble.\n- `--lr-chat-message-streaming-border-color` (default: `var(--lr-color-brand)`) — Streaming bubble border.\n- `--lr-chat-message-streaming-indicator-color` (default: `var(--lr-color-brand)`) — Streaming indicator.\n- `--lr-chat-message-system-color` (default: `var(--lr-color-text-quiet)`) — System-message text color.\n- `--lr-chat-message-user-bubble-bg` (default: `var(--lr-color-brand-quiet)`) — Bubble fill for `message-role=\"user\"`.\n- `--lr-chat-message-user-bubble-color` (default: `var(--lr-color-text)`) — Bubble text color for `message-role=\"user\"`.\n- `--lr-chat-message-user-footer-color` (default: `var(--lr-color-text)`) — User-message footer text.\n- `--lr-transition-ambient` (default: `1.8s ease-in-out`) — Streaming-indicator animation duration and timing function.","attributes":[{"name":"actions-position","description":"Where the actions row renders relative to the bubble.\n\nType: `ChatMessageActionsPosition`  \nDefault: `'inside'`","value":{"type":["'inside'","'outside'"]}},{"name":"attachments-position","description":"Where the `attachments` slot renders relative to the message body.\n`'after'` (the default) reproduces today's exact DOM order. `'before'`\nrenders attachments immediately above the body -- both DOM and visual\norder move together (no CSS `order` trick), so reading/focus order\nalways matches what's on screen.\n\nType: `'before' | 'after'`  \nDefault: `'after'`","value":{"type":["'before'","'after'"]}},{"name":"collapsed","description":"Whether the message body is currently hidden. Effective whenever set,\nindependent of `collapsible` — `collapsible` only controls whether the\nbuilt-in toggle button is rendered, mirroring `lr-widget`'s identical\n`collapsible`/`collapsed` pair.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"collapsible","description":"Shows the built-in collapse/expand toggle in the header.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"message-id","description":"Optional stable application-defined identifier for this message. Included in `lr-message-retry`\ndetail when set.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"message-role","description":"Who authored the message. Its localized identity directly names the internal article.\n\nType: `ChatMessageRole`  \nDefault: `'assistant'`","value":{"type":["'user'","'assistant'","'system'"]}},{"name":"status","description":"Delivery/generation state. Drives the footer's status dot/text and,\nfor `\"failed\"`, the bubble's danger treatment and the built-in retry\nbutton. Declared via `static properties` above with a hand-written\naccessor (see `previousStatus`).\n\nType: `ChatMessageStatus`","value":{"type":["'sending'","'sent'","'failed'","'streaming'"]}}],"slots":[{"name":"","description":"The message body."},{"name":"actions","description":"Action controls (e.g. copy, retry), rendered at the end of the footer."},{"name":"attachments","description":"File/image attachment chips, rendered below the message body by default; see `attachments-position`."},{"name":"avatar","description":"An avatar/icon for the message author."},{"name":"badges","description":"Small status/metric chips (e.g. token count, latency, model name) — entirely app-supplied; this component computes none of that itself."},{"name":"failure","description":"Only ever rendered while `status=\"failed\"`. Empty (the default), the footer keeps its built-in `[part=\"status-text\"]`/`[part=\"retry-button\"]` exactly as before. The moment this slot has assigned content, that built-in status text and retry button are suppressed — the host is now fully responsible for presenting its own failure UI, and the built-in `chatFailedAnnounce` live-region announcement is suppressed too (see `@event lr-message-retry` below for the effect on that event, and the \"Accessibility of `status`\" paragraph above for the built-in announcement this replaces). Content assigned here should carry `role=\"alert\"` itself when it represents an actionable send failure — this component does not add that role on the host's behalf, since it has no way to know what markup the host puts in this slot. This mirrors `lr-flow-node`'s `header` slot, which replaces that component's own built-in heading row the same way."}],"js":{"properties":[{"name":"actionsPosition","description":"Where the actions row renders relative to the bubble.\n\nAttribute: `actions-position`  \nReflected to its attribute.","type":"ChatMessageActionsPosition","default":"'inside'"},{"name":"attachmentsPosition","description":"Where the `attachments` slot renders relative to the message body.\n`'after'` (the default) reproduces today's exact DOM order. `'before'`\nrenders attachments immediately above the body -- both DOM and visual\norder move together (no CSS `order` trick), so reading/focus order\nalways matches what's on screen.\n\nAttribute: `attachments-position`","type":"'before' | 'after'","default":"'after'"},{"name":"collapsed","description":"Whether the message body is currently hidden. Effective whenever set,\nindependent of `collapsible` — `collapsible` only controls whether the\nbuilt-in toggle button is rendered, mirroring `lr-widget`'s identical\n`collapsible`/`collapsed` pair.\n\nAttribute: `collapsed`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"collapsible","description":"Shows the built-in collapse/expand toggle in the header.\n\nAttribute: `collapsible`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"formatTimestamp","description":"Overrides the localized default `hour:minute` rendering of `timestamp` for applications\nthat need a domain-specific date/time contract.","type":"(date: Date) => string | undefined"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"messageId","description":"Optional stable application-defined identifier for this message. Included in `lr-message-retry`\ndetail when set.\n\nAttribute: `message-id`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"messageRole","description":"Who authored the message. Its localized identity directly names the internal article.\n\nAttribute: `message-role`  \nReflected to its attribute.","type":"ChatMessageRole","default":"'assistant'"},{"name":"status","description":"Delivery/generation state. Drives the footer's status dot/text and,\nfor `\"failed\"`, the bubble's danger treatment and the built-in retry\nbutton. Declared via `static properties` above with a hand-written\naccessor (see `previousStatus`).\n\nAttribute: `status`  \nReflected to its attribute.","type":"ChatMessageStatus"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"timestamp","description":"When the message was sent/received. Accepts a `Date` or anything\n`new Date()` can parse (e.g. an ISO 8601 string); invalid input is\ntreated the same as unset (no timestamp rendered).","type":"LyraTimestamp | undefined"}],"events":[{"name":"lr-message-retry","description":"Fired by the built-in retry button, only rendered when `status=\"failed\"` and the `failure` slot is empty. `detail: { messageId?: string }` includes this element's stable `messageId` when supplied, so a conversation surface can identify the message without a closure around each row. A host using the `failure` slot owns its own retry control and is not required to use this event at all — but nothing stops that control from dispatching its own `new CustomEvent('lr-message-retry', { bubbles: true, composed: true })` to stay consistent with the same event contract a listener further up a conversation surface already relies on for every other message.","type":"CustomEvent<{ messageId?: string }>"},{"name":"lr-toggle","description":"Collapse state committed. `detail: { collapsed }`.","type":"CustomEvent<ChatMessageToggleDetail>"},{"name":"lr-toggle-request","description":"Cancelable request to change collapse state. `detail: { collapsed }`.","type":"CustomEvent<ChatMessageToggleDetail>"}]}},{"name":"lr-chat-viewport","description":"`<lr-chat-viewport>` — the transcript scroll container: owns stick-to-bottom behavior while an\nanswer streams, the \"jump to latest\" pill, and the unread divider.\n\n**Two supported content shapes, auto-detected:** ordinary element children (typically\n`<lr-chat-message>`s -- *slotted mode*), or exactly one `<lr-virtual-list>` (*virtual mode*,\ndetected via `instanceof` against the imported class so custom prefixes keep working). In virtual\nmode this component defers all scrolling to the slotted list's own `scrollToIndex()`, and sizes\nthat list to its own height -- without which the list would scroll inside `lr-virtual-list`'s\n24rem `--lr-virtual-list-height` default no matter how tall this viewport is. That sizing is a\npercentage, so virtual mode needs a height-bounded parent, the same requirement slotted mode's\nown scroll container already has; a consumer's own rule or inline style setting\n`--lr-virtual-list-height` on the list still wins.\n\n**Follow/release state machine.** While `follow` is engaged, content growth re-scrolls to the end.\nRelease happens only on a *user-intent* gesture (wheel, touchmove, scrollbar-drag, or\nPageUp/ArrowUp/Home while the log region has focus) that leaves the view more than\n`bottomThreshold` from the end -- a scroll caused by this component's own programmatic scrolling,\nor by a layout shift, never releases it. Reaching the bottom again by any means re-engages `follow`.\nThe internal log defaults to `live=\"off\"`, which avoids announcing every streaming token. Consumers\nthat append complete messages at an announcement-safe cadence can opt into `polite` or `assertive`;\neach newly appended direct child's accessibility-exposed text is then announced through the\ndocument's shared light-DOM sink. Hidden, inert, `aria-hidden`, and CSS-hidden content is omitted.\nExisting declarative children stay silent on mount, and appending the same text again creates a\nnew announcement. The shadow log itself always remains `aria-live=\"off\"`.\n\n**`scrollToUnread()` in virtual mode.** The target row is scrolled with `align: 'start'` so the\ndivider boundary lands at the top of the view with the unread content visible below it -- the\nonly alignment that matches what \"scroll to the divider\" means here. The underlying virtual list\nonly issues a corrective re-scroll for an initially-unmeasured target when that target's *own*\nheight is what was uncertain (`align: 'end'`/a downward `align: 'auto'`); a `'start'`-aligned\ntarget's position is a function of the rows *before* it, so it has no such self-correction. In\npractice the rows leading up to an unread boundary are usually ones the reader already scrolled\npast (and so already measured), which keeps this accurate in the common case; a still-unmeasured\nlong-distance jump can land approximately rather than pixel-exact. Fixing that fully would mean\nchanging how the underlying list resolves offsets, which is out of scope here -- `align: 'end'`\nwas considered and rejected because it changes the visible outcome (it would put the *bottom* of\nthe boundary row at the viewport's bottom edge, hiding the unread content the jump is meant to\nreveal, not just changing how precisely it lands).\n\nRenders no messages and computes no unread state itself -- the host supplies `unreadStartIndex`;\nno virtualization of its own (`<lr-virtual-list>`); not a generic overflow surface\n(`<lr-scroller>`); no message semantics (`<lr-chat-message>`).\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 transcript: ordinary element children, or exactly one `<lr-virtual-list>`. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The positioning root. |\n| `content` | The slotted-content wrapper the growth observers watch. |\n| `jump-pill` | The built-in jump-to-latest button, absent while `follow` is engaged. |\n| `scroll` | The scroll container (`role=\"log\"` and, in slotted mode, `tabindex=\"0\"`). In virtual mode it stops scrolling itself and drops its tab stop because the slotted list owns both scrolling and keyboard focus. |\n| `unread-divider` | The \"New messages\" separator (slotted mode only). |","attributes":[{"name":"aria-label","description":"Host `aria-label`, forwarded to the internal `role=\"log\"` element -- an `aria-label` left\non the custom-element host itself names nothing, because the log role lives inside the\nshadow root. Wins over `label` and the localized default.\n\nType: `string | null`  \nDefault: `null`"},{"name":"bottom-threshold","description":"Px distance from the end still counted as \"at bottom.\"\n\nType: `number`  \nDefault: `24`","value":{"type":["number"]}},{"name":"follow","description":"Type: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"label","description":"Accessible name for the log region. Defaults to the localized `chatViewportLabel`;\na host `aria-label` (see `accessibleLabel`) wins over both.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"live","description":"Live-region policy for newly appended direct children. Keep `off` for token-by-token\nstreaming; use `polite` or `assertive` only when messages are appended at an announcement-safe\ncadence. Only accessibility-exposed text is copied. The shadow `role=\"log\"` remains non-live;\nannouncements use a shared light-DOM sink.\n\nType: `ChatViewportLive`  \nDefault: `'off'`","value":{"type":["'off'","'polite'","'assertive'"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"unread-start-index","description":"Index of the first unread item -- element-child index in slotted mode, `items` index in virtual\nmode. Host-owned unread bookkeeping in, divider/pill count out. `null` disables both.\n\nType: `number | null`  \nDefault: `null`"}],"slots":[{"name":"","description":"The transcript: ordinary element children, or exactly one `<lr-virtual-list>`."}],"js":{"properties":[{"name":"accessibleLabel","description":"Host `aria-label`, forwarded to the internal `role=\"log\"` element -- an `aria-label` left\non the custom-element host itself names nothing, because the log role lives inside the\nshadow root. Wins over `label` and the localized default.\n\nAttribute: `aria-label`","type":"string | null","default":"null"},{"name":"bottomThreshold","description":"Px distance from the end still counted as \"at bottom.\"\n\nAttribute: `bottom-threshold`","type":"number","default":"24"},{"name":"follow","description":"Attribute: `follow`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"label","description":"Accessible name for the log region. Defaults to the localized `chatViewportLabel`;\na host `aria-label` (see `accessibleLabel`) wins over both.\n\nAttribute: `label`","type":"string","default":"''"},{"name":"live","description":"Live-region policy for newly appended direct children. Keep `off` for token-by-token\nstreaming; use `polite` or `assertive` only when messages are appended at an announcement-safe\ncadence. Only accessibility-exposed text is copied. The shadow `role=\"log\"` remains non-live;\nannouncements use a shared light-DOM sink.\n\nAttribute: `live`  \nReflected to its attribute.","type":"ChatViewportLive","default":"'off'"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"unreadStartIndex","description":"Index of the first unread item -- element-child index in slotted mode, `items` index in virtual\nmode. Host-owned unread bookkeeping in, divider/pill count out. `null` disables both.\n\nAttribute: `unread-start-index`","type":"number | null","default":"null"}],"events":[{"name":"lr-follow-change","description":"`detail: { following }` -- fired whenever `follow` flips (user scroll-up release, or reaching the bottom again). Never fired for the initial mount state.","type":"CustomEvent<{ following: boolean }>"}]}},{"name":"lr-checkbox","description":"`<lr-checkbox>` — a boolean form control. Structurally the same idea as\n`<lr-switch>` (form-associated via `ElementInternals`, click and\nSpace both toggle) but with checkbox semantics: `role=\"checkbox\"` +\nan `aria-checked` that can also be `\"mixed\"`, and a visual box/checkmark\ninstead of a track/thumb.\n\n`checked` is not a plain string, so this attaches `ElementInternals`\ndirectly and implements its own `updateValidity()` rather than using the\n`FormAssociated` mixin — see `<lr-combobox>` for the same\ndirect-`ElementInternals` shape with a non-string value.\n\nSupporting text is optional through either Web Awesome's `hint` spelling or Shoelace's\n`help-text` spelling. `errorText` and the `error` slot provide the matching owned error surface;\nall rendered messages share an additive described-by relationship with external host ids.\nDeliberately no separate top-of-field label property/slot/part: the default slot already is the\nvisible, clickable checkbox label, matching `lr-switch`'s form-control shape.\nDefault-slot presence follows flattened rendered assignment and updates when forwarded content\nchanges. Visual elements, including decorative `aria-hidden` icons, keep the label wrapper;\naccessible naming remains the browser's slot semantics unless a host `aria-label` is present.\nThe public label and supporting/error text wrap at arbitrary boundaries in constrained rows;\nthe fixed checkbox square and shared interactive target never shrink to make that fit.\nThe internal checkbox role exposes explicit stateful `aria-invalid`: visible error chrome wins\nimmediately, while intrinsic/custom invalidity is exposed only after user interaction.\n\nRemoving `error-text` safely omits the message while preserving native null property readback.\nExplicit empty text stays empty; later supplied text renders normally.\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) | Label text, rendered next to the box. Clicking it toggles the checkbox, the same as clicking a native checkbox's associated `<label>`. If left empty, set `aria-label` on the host so the control still has an accessible name. Host `aria-label` is forwarded by presence, including an explicitly empty value. Interactive label content remains a separate focus stop outside the checkbox role; activating that content does not also toggle the checkbox. |\n| `error` | Custom error content on the owned error surface. A host `aria-describedby` attribute is resolved onto the internal `role=\"checkbox\"` through `ariaDescribedByElements` so externally-owned descriptions remain valid across the shadow boundary. |\n| `help-text` | Shoelace-compatible supporting text; the same surface as `hint`. |\n| `hint` | Web Awesome-compatible supporting text. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | Compatibility name for the interactive control; use `checkbox`. |\n| `box` | The small square that shows the checkmark/indeterminate dash. |\n| `checkbox` | The interactive `role=\"checkbox\"` owner around the box. It is the same node as `base`, retains the shared `--lr-icon-button-size` minimum target at every size tier, and keeps the rich default label as a sibling so nested actions remain valid focus stops. |\n| `checked-icon` | WA/Shoelace name for the checked glyph. |\n| `checkmark` | Lyra name for the visible glyph inside the box. |\n| `control` | WA/Shoelace name for `box`. |\n| `control--checked` | Shoelace state alias on the control while checked. |\n| `control--indeterminate` | Shoelace state alias on the control while indeterminate. |\n| `error` | The error message. |\n| `form-control` | The outer wrapper around the checkbox, error, and hint. |\n| `form-control-help-text` | Shoelace name for the same supporting-text wrapper. |\n| `hint` | Web Awesome name for the supporting-text wrapper. |\n| `indeterminate-icon` | WA/Shoelace name for the indeterminate glyph. |\n| `label` | The wrapper around the default slot. |\n| `row` | The row wrapping the checkbox owner and the label as siblings. This is the node to size or align when laying out a column of checkboxes; `base`/`checkbox` is only the control box inside it, so its inline size tracks the box, not the row. |\n\n---\n\n**CSS Custom Properties**\n\n- `--checked-icon-color` (default: `currentColor`) — WA-compatible color of the checked or indeterminate glyph.\n- `--checked-icon-scale` (default: `1`) — WA-compatible scale of the checked or indeterminate glyph.\n- `--lr-checkbox-active-border` (default: `var(--lr-color-brand)`) — Box border while pressed.\n- `--lr-checkbox-active-ring` (default: `var(--lr-color-brand-quiet)`) — Outer box ring while pressed.\n- `--lr-checkbox-box-size` (default: `min(var(--lr-icon-button-size), calc(var(--lr-form-control-height) * 0.7))`) — Edge length of `[part='box']`. Derived from the `size` tier's shared control height, so the box lines up with an `<lr-input>`/`<lr-select>`/`<lr-button>` of the same `size`; set it to pin the box independently of the tier.\n- `--lr-checkbox-checked-bg` (default: `var(--lr-color-brand)`) — Background of `[part='box']` while `checked` or `indeterminate`. Retint just this control's checked fill without touching the shared `--lr-color-brand` token every other component also reads.\n- `--lr-checkbox-checked-border` (default: `var(--lr-color-brand)`) — Border color of `[part='box']` while `checked` or `indeterminate`.\n- `--lr-checkbox-hover-border` (default: `var(--lr-color-brand)`) — Box border while the enabled interactive control is hovered.\n- `--lr-checkbox-invalid-border` (default: `var(--lr-color-danger)`) — Box border while invalid chrome is visible.\n- `--lr-checkbox-label-indent` (default: `calc(var(--lr-checkbox-box-size) + var(--lr-space-s))`) — The inline distance from the control's start edge to the start of the label text, i.e. the box's own floor plus the gap next to it — so it tracks `size` along with the box. Published so a consumer composing per-option hint text under the label can align it without re-deriving that formula from the shadow styles, and used as the source of the real gap so the two cannot drift. Setting it on the element (or on `lr-checkbox` in your own stylesheet) moves the label; because custom properties inherit down and not sideways, it is *not* readable from a sibling node in your tree — align a sibling by computing the same formula from `--lr-theme-icon-button-size`, `--lr-theme-form-control-height-*` and `--lr-theme-space-s`, which you control.","attributes":[{"name":"checked","description":"Reflected current reset default; changing it never overwrites dirty live `checked` state.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"custom-error","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nType: `string | null`  \nDefault: `null`"},{"name":"disabled","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"error-text","description":"Error text associated with the inner checkbox; custom markup can use the `error` slot.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"form","description":"Type: `HTMLFormElement | string | null`  \nDefault: `null`"},{"name":"help-text","description":"Shoelace alias for hint.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"hint","description":"Web Awesome supporting text. It wins when both mapped spellings are supplied.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"indeterminate","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"name","description":"The form submission key, reflected synchronously for native form APIs.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"required","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"size","description":"Control size, on the library's shared ladder. Accepts both spellings of every tier —\n`2xs`/`xs`/`s`/`m`/`l`/`xl` and Web Awesome's `small`/`medium`/`large` — so migrating either way\nis a tag rename. Scales the box and its checkmark off the same `--lr-form-control-*` values\n`<lr-input>`/`<lr-select>`/`<lr-button>` use, so controls of one `size` line up in a row. The\nslotted label keeps the library's standard control-label type size at every tier; restyle it\nthrough `::part(label)` if you want it to track the control.\n\nType: `LyraSize`  \nDefault: `'m'`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}},{"name":"value","description":"Type: `string`","value":{"type":["string"]}}],"slots":[{"name":"","description":"Label text, rendered next to the box. Clicking it toggles the checkbox, the same as clicking a native checkbox's associated `<label>`. If left empty, set `aria-label` on the host so the control still has an accessible name. Host `aria-label` is forwarded by presence, including an explicitly empty value. Interactive label content remains a separate focus stop outside the checkbox role; activating that content does not also toggle the checkbox."},{"name":"error","description":"Custom error content on the owned error surface. A host `aria-describedby` attribute is resolved onto the internal `role=\"checkbox\"` through `ariaDescribedByElements` so externally-owned descriptions remain valid across the shadow boundary."},{"name":"help-text","description":"Shoelace-compatible supporting text; the same surface as `hint`."},{"name":"hint","description":"Web Awesome-compatible supporting text."}],"js":{"properties":[{"name":"checked","description":"Attribute: `checked`","type":"boolean","default":"false"},{"name":"customError","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nAttribute: `custom-error`  \nReflected to its attribute.","type":"string | null","default":"null"},{"name":"defaultChecked","description":"Reflected current reset default; changing it never overwrites dirty live `checked` state.\n\nAttribute: `checked`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"disabled","description":"Attribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"effectiveDisabled","description":"Whether the control is disabled explicitly, by an ancestor fieldset, or by an owning `<lr-checkbox-group>`.","type":"boolean","read-only":true},{"name":"errorText","description":"Error text associated with the inner checkbox; custom markup can use the `error` slot.\n\nAttribute: `error-text`","type":"string","default":"''"},{"name":"form","description":"Attribute: `form`  \nReflected to its attribute.","type":"HTMLFormElement | string | null","default":"null"},{"name":"helpText","description":"Shoelace alias for hint.\n\nAttribute: `help-text`","type":"string","default":"''"},{"name":"hint","description":"Web Awesome supporting text. It wins when both mapped spellings are supplied.\n\nAttribute: `hint`","type":"string","default":"''"},{"name":"indeterminate","description":"Attribute: `indeterminate`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"labels","type":"NodeList","read-only":true},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"name","description":"The form submission key, reflected synchronously for native form APIs.\n\nAttribute: `name`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"required","description":"Attribute: `required`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"size","description":"Control size, on the library's shared ladder. Accepts both spellings of every tier —\n`2xs`/`xs`/`s`/`m`/`l`/`xl` and Web Awesome's `small`/`medium`/`large` — so migrating either way\nis a tag rename. Scales the box and its checkmark off the same `--lr-form-control-*` values\n`<lr-input>`/`<lr-select>`/`<lr-button>` use, so controls of one `size` line up in a row. The\nslotted label keeps the library's standard control-label type size at every tier; restyle it\nthrough `::part(label)` if you want it to track the control.\n\nAttribute: `size`  \nReflected to its attribute.","type":"LyraSize","default":"'m'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"validationMessage","type":"string","read-only":true},{"name":"validity","type":"ValidityState","read-only":true},{"name":"value","description":"Attribute: `value`  \nReflected to its attribute.","type":"string"},{"name":"willValidate","type":"boolean","read-only":true}],"events":[{"name":"blur","description":"Re-dispatched from the internal control as a bubbling, composed event.","type":"FocusEvent"},{"name":"change","description":"Fired immediately after `input` for the same user toggle.","type":"Event"},{"name":"focus","description":"Re-dispatched from the internal control as a bubbling, composed event.","type":"FocusEvent"},{"name":"input","description":"The user toggled the checkbox; bubbling and composed like a native form event.","type":"Event"},{"name":"lr-change","description":"Compatibility alias fired after `input` and `change` (click or Space). `detail: { checked }`. Not fired for a programmatic `.checked` assignment, nor for a user toggle a listener refused through `lr-checkbox-toggle-request`.","type":"CustomEvent<{ checked: boolean }>"},{"name":"lr-checkbox-toggle-request","description":"A user toggle (click or Space) is about to change `checked`; `detail: { checked }` carries the state the control *would* take, and `checked` itself still holds the old value while this dispatches. Cancelable: calling `preventDefault()` keeps the current state, so the control never flips at all rather than flipping and snapping back, and none of `input`/`lr-input`/`change`/`lr-change` fire. A listener may instead resolve the request by assigning `checked` itself during the dispatch, which suppresses the built-in write the same way. Not fired for a programmatic `.checked` assignment, nor while the control is disabled. An `<lr-checkbox-group>` owner consumes this event and republishes it as its own `lr-checkbox-group-toggle-request`, the same way it already translates `input`/`change`.","type":"CustomEvent<{ checked: boolean }>"},{"name":"lr-input","description":"Prefixed compatibility alias for `input`; `detail: { checked }`.","type":"CustomEvent<{ checked: boolean }>"},{"name":"lr-invalid","description":"The checkbox failed a validity check. Cancelable: calling `preventDefault()` also cancels the native `invalid` event behind it, suppressing the browser's own validation bubble so an app can present the failure its own way.","type":"CustomEvent<null>"}]}},{"name":"lr-checkbox-group","description":"`<lr-checkbox-group>` — a form-associated group of `<lr-checkbox>` elements.\nLong label/hint/error content and horizontal option labels remain contained in a 320px LTR or\nRTL allocation; options wrap without shrinking their checkbox targets.\nIts fieldset owns aggregate `aria-invalid` state and, while required, a localized hidden\nrequiredness description that composes with existing hint/error relationships without marking\nevery child checkbox required. A host `aria-describedby` is resolved onto that fieldset before\nits own hint/error/required descriptions, preserving external guidance across the shadow\nboundary. Host `aria-labelledby` is deliberately not projected: the native legend supplies the\ngroup's visible label relationship.\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-checkbox>` children. |\n| `error` | Custom validation message. |\n| `hint` | Supporting text. |\n| `label` | Visible group label. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `error` | Validation message. |\n| `form-control` | Group wrapper. |\n| `form-control-input` | WA name for the same checkbox collection. |\n| `form-control-label` | Label. |\n| `hint` | Supporting text. |\n| `options` | Checkbox collection. |\n\n---\n\n**CSS Custom Properties**\n\n- `--gap` (default: `var(--lr-checkbox-group-option-gap)`) — WA-compatible option gap.\n- `--lr-checkbox-group-invalid-border` (default: `var(--lr-color-danger)`) — Border around the option collection while invalid chrome is visible.\n- `--lr-checkbox-group-option-gap` (default: `calc(var(--lr-form-control-height) * 0.2)`) — Gap between adjacent options, scaled by `size`.\n- `--lr-checkbox-group-row-gap` (default: `calc(var(--lr-form-control-height) * 0.1)`) — Vertical gap between the group's label, options and messages, scaled by `size`.\n- `--lr-form-control-required-color` (default: `var(--lr-color-danger)`) — Required-marker color, themeable independently of error text and invalid borders.\n- `--lr-form-control-required-content` (default: `' *'`) — The required marker appended to `form-control-label` while `required` is set. Set it to `''` to suppress the marker, or to any other quoted string (`' (required)'`, a localized word) to replace it.\n- `--lr-form-control-required-offset` (default: `0`) — Inline space between the label text and the required marker.","attributes":[{"name":"aria-label","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"custom-error","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nType: `string | null`"},{"name":"disabled","description":"Type: `boolean`","value":{"type":["boolean"]}},{"name":"error-text","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"form","description":"Type: `HTMLFormElement | string | null`  \nDefault: `null`"},{"name":"hint","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"label","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"name","description":"The form submission key each checked child checkbox's value is grouped under in the group's\nown `FormData` entry (see `sync()`). Reflected synchronously for native form APIs; renaming\nrebuilds that `FormData` in the same tick -- mirrors `<lr-token-input>`'s identical `name` setter.\n\nType: `string`","value":{"type":["string"]}},{"name":"orientation","description":"Option flow and the matching WA public attribute.\n\nType: `CheckboxGroupOrientation`  \nDefault: `'vertical'`","value":{"type":["'horizontal'","'vertical'"]}},{"name":"required","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"size","description":"Size of the group's own chrome, on the library's shared ladder. Accepts both spellings of every\ntier — `2xs`/`xs`/`s`/`m`/`l`/`xl` and Web Awesome's `small`/`medium`/`large` — so migrating\neither way is a tag rename. Scales the group's label type size and the gaps around and between\nits options off the same `--lr-form-control-*` values the controls themselves use, and\npropagates the selected tier to every owned checkbox so the aggregate control stays coherent.\n\nWhen omitted, each checkbox keeps its authored size, matching the mirrored upstream default.\nAn explicit group size temporarily overrides every owned checkbox; removal/reparenting restores\nthe latest author value rather than leaving owner state behind.\n\nType: `LyraSize | undefined`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}},{"name":"with-hint","description":"SSR slot-presence hint for hint content unavailable before hydration.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"with-label","description":"SSR slot-presence hint for label content unavailable before hydration.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"","description":"`<lr-checkbox>` children."},{"name":"error","description":"Custom validation message."},{"name":"hint","description":"Supporting text."},{"name":"label","description":"Visible group label."}],"js":{"properties":[{"name":"accessibleLabel","description":"Attribute: `aria-label`","type":"string","default":"''"},{"name":"customError","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nAttribute: `custom-error`  \nReflected to its attribute.","type":"string | null"},{"name":"disabled","description":"Attribute: `disabled`  \nReflected to its attribute.","type":"boolean"},{"name":"effectiveDisabled","description":"Whether the group is disabled explicitly or by an ancestor fieldset.","type":"boolean","read-only":true},{"name":"errorText","description":"Attribute: `error-text`","type":"string","default":"''"},{"name":"form","description":"Attribute: `form`  \nReflected to its attribute.","type":"HTMLFormElement | string | null","default":"null"},{"name":"hint","description":"Attribute: `hint`","type":"string","default":"''"},{"name":"label","description":"Attribute: `label`","type":"string","default":"''"},{"name":"labels","type":"NodeList","read-only":true},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"name","description":"The form submission key each checked child checkbox's value is grouped under in the group's\nown `FormData` entry (see `sync()`). Reflected synchronously for native form APIs; renaming\nrebuilds that `FormData` in the same tick -- mirrors `<lr-token-input>`'s identical `name` setter.\n\nAttribute: `name`  \nReflected to its attribute.","type":"string"},{"name":"orientation","description":"Option flow and the matching WA public attribute.\n\nAttribute: `orientation`  \nReflected to its attribute.","type":"CheckboxGroupOrientation","default":"'vertical'"},{"name":"required","description":"Attribute: `required`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"size","description":"Size of the group's own chrome, on the library's shared ladder. Accepts both spellings of every\ntier — `2xs`/`xs`/`s`/`m`/`l`/`xl` and Web Awesome's `small`/`medium`/`large` — so migrating\neither way is a tag rename. Scales the group's label type size and the gaps around and between\nits options off the same `--lr-form-control-*` values the controls themselves use, and\npropagates the selected tier to every owned checkbox so the aggregate control stays coherent.\n\nWhen omitted, each checkbox keeps its authored size, matching the mirrored upstream default.\nAn explicit group size temporarily overrides every owned checkbox; removal/reparenting restores\nthe latest author value rather than leaving owner state behind.\n\nAttribute: `size`  \nReflected to its attribute.","type":"LyraSize | undefined"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"validationMessage","type":"string","read-only":true},{"name":"validity","type":"ValidityState","read-only":true},{"name":"value","description":"Checked child values, in DOM order. Reading returns a frozen defensive snapshot, so mutating\nthe returned array never changes the group -- assign a new array instead.\n\nAssigning mirrors the array onto the owned checkboxes: a child whose `value` (defaulting to\n`'on'`) appears in the array becomes checked, every other child becomes unchecked, and\nduplicate entries check that many same-valued children. Assignment is controlled input, so it\nemits no `lr-change`; only user interaction does. Values naming no child are ignored.\n\nThis used to be a getter with no setter. Reading it was fine, but `.value=${...}` -- the\nbinding every other form control in this library accepts -- compiles to a plain property\nassignment that `readonly` cannot catch at the binding site, so it threw\n\"Cannot set property value ... which has only a getter\" from inside lit-html during a *later*\nrender, pointing at framework internals rather than the offending line.","type":"readonly string[]"},{"name":"willValidate","type":"boolean","read-only":true},{"name":"withHint","description":"SSR slot-presence hint for hint content unavailable before hydration.\n\nAttribute: `with-hint`","type":"boolean","default":"false"},{"name":"withLabel","description":"SSR slot-presence hint for label content unavailable before hydration.\n\nAttribute: `with-label`","type":"boolean","default":"false"}],"events":[{"name":"change","description":"User selection changed.","type":"CustomEvent<Readonly<{ value: readonly string[] }>>"},{"name":"input","description":"User selection changed.","type":"CustomEvent<Readonly<{ value: readonly string[] }>>"},{"name":"lr-change","description":"User selection changed; detail is `{ value: string[] }`. Not fired for a toggle a listener refused through `lr-checkbox-group-toggle-request`.","type":"CustomEvent<Readonly<{ value: readonly string[] }>>"},{"name":"lr-checkbox-group-toggle-request","description":"One owned checkbox is about to toggle; `detail: { value, previousValue, option }` carries the group value that *would* result, the value as it stands right now, and the checkbox the user acted on. Cancelable: calling `preventDefault()` keeps the current state, so the option never flips at all rather than flipping and snapping back -- which is what lets a host refuse \"uncheck the last remaining option\" (`detail.value.length === 0`) with no flicker -- and no `input`/`change`/`lr-change` follows. A listener may instead resolve the request by assigning the group's `value` itself during the dispatch, which suppresses the option's own write the same way. The owned checkbox's `lr-checkbox-toggle-request` is consumed and republished as this event, exactly as the group already translates a child's `input`/`change`/`lr-change` into its own.","type":"CustomEvent<\n    LyraEventDetailSnapshot<LyraCheckboxGroupToggleRequestDetail>\n  >"},{"name":"lr-invalid","description":"The aggregate checkbox group failed a validity check. Cancelable: calling `preventDefault()` also cancels the native `invalid` event behind it, suppressing the browser's own validation bubble so an app can present the failure its own way.","type":"CustomEvent<null>"}]}},{"name":"lr-checkpoint","description":"`<lr-checkpoint>` — an inline conversation restore point: a labeled marker between messages\nwhose Restore affordance confirms inline, then hands the host a `lr-restore` event. This\ncomponent persists and restores nothing itself — host state in, events out.\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) | Optional supplemental content under the marker row (e.g. what changed since this point). |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The marker root (`role=\"group\"`). |\n| `cancel-button` | Cancels, reverting to `restore-button`. |\n| `confirm-button` | Confirms the restore, firing `lr-restore`. |\n| `confirm-group` | The inline confirm prompt, swapped in for `restore-button` while confirming. |\n| `confirm-prompt` | The confirm prompt text. |\n| `icon` | The bookmark glyph. |\n| `label` | The computed label text. |\n| `line` | Each of the two flanking rules. |\n| `restore-button` | The Restore button. Only rendered while `restorable`. |\n| `timestamp` | The formatted `timestamp`, when set. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-checkpoint-spin-duration` (default: `var(--lr-transition-ambient)`) — Restoring-spinner timing, inheriting the shared ambient-motion token by default (stopped under reduced motion).","attributes":[{"name":"checkpoint-id","description":"Opaque id echoed in the `lr-restore` event detail.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"confirm-restore","description":"Gates the `lr-restore` event behind the inline confirm step.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"label","description":"Checkpoint name. The generic `'Checkpoint'` fallback renders while empty.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"restorable","description":"When `false`, renders a plain marker with no button — for read-only views, or the currently-\nrestored checkpoint.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"restoring","description":"Host-set busy state: the Restore button becomes `aria-disabled=\"true\"` with a spinner beside\nthe localized \"Restoring…\" text.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"","description":"Optional supplemental content under the marker row (e.g. what changed since this point)."}],"js":{"properties":[{"name":"checkpointId","description":"Opaque id echoed in the `lr-restore` event detail.\n\nAttribute: `checkpoint-id`","type":"string","default":"''"},{"name":"confirmRestore","description":"Gates the `lr-restore` event behind the inline confirm step.\n\nAttribute: `confirm-restore`","type":"boolean","default":"true"},{"name":"formatTimestamp","description":"Overrides the default `hour:minute` rendering of `timestamp`.","type":"(date: Date) => string | undefined"},{"name":"label","description":"Checkpoint name. The generic `'Checkpoint'` fallback renders while empty.\n\nAttribute: `label`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"restorable","description":"When `false`, renders a plain marker with no button — for read-only views, or the currently-\nrestored checkpoint.\n\nAttribute: `restorable`","type":"boolean","default":"true"},{"name":"restoring","description":"Host-set busy state: the Restore button becomes `aria-disabled=\"true\"` with a spinner beside\nthe localized \"Restoring…\" text.\n\nAttribute: `restoring`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"timestamp","description":"Optional creation time, rendered as `<time datetime>`, default `hour:minute` in\n`effectiveLocale`. Invalid strings are treated as unset.","type":"LyraTimestamp | undefined"}],"events":[{"name":"lr-restore","description":"Restore was activated (after the inline confirm step, when `confirmRestore` is on). `detail: { checkpointId, label }`. Not cancelable — a request; this component performs no default action and stores nothing.","type":"CustomEvent<CheckpointRestoreDetail>"}]}},{"name":"lr-chip","description":"`<lr-chip>` — a small, content-agnostic pill for a short label: a tag, an\nactive-filter/scope indicator, etc. Distinct from `<lr-attachment-chip>`\n(specifically file-shaped, with a thumbnail/size/upload-progress) — this\none carries no domain assumptions at all, just a label and an optional\nleading adornment.\n\n`variant` tints the whole pill using the same loud-color-on-quiet-tint\nconvention `<lr-tool-call-chip>`/`<lr-citation-badge>` already\nestablish for status coloring: background is the variant's quiet fill,\ntext/icon is its loud fill, both read from the shared semantic grid.\n`neutral` (the default) deliberately opts out of that grid's own neutral\nrow and falls back to a plain bordered-surface look — the same \"no signal\"\ntreatment `<lr-citation-badge>`'s `default` status and\n`<lr-tool-call-chip>`'s `pending` status already use.\n\nThis property was called `tone` before 8.0.0. It is `variant` now, with no\nalias: the library spells one concept one way, and `<lr-badge>`,\n`<lr-callout>` and `<lr-toast-item>` all already spelled it `variant`.\n\nThis is a controlled component: clicking the remove (×) button only fires\n`lr-remove` — the chip never removes itself from the DOM on its own\ninteraction, the same contract `<lr-attachment-chip>`/\n`<lr-conversation-item>` already follow. A consumer owns the underlying\nlist and decides whether/how the click actually removes anything.\n`disabled` disables whichever native action control is active and suppresses\nselection/removal requests without changing the controlled state.\nIf an interactive chip has a host `aria-label`, the host becomes the single aggregate\n`role=\"group\"` owner. The native toggle/remove action keeps a purpose-specific name derived from\nvisible label text (or its localized fallback), avoiding two owners with the same copied name.\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 chip's label content. Visible accessible text and forwarding-slot reassignment stay synchronized with toggle/remove action names. In toggle mode its flattened subtree is inert and hidden from assistive technology while the separate native toggle owns the action and name. |\n| `end` | Optional trailing content, typically an icon, placed after the label and before the toggle/remove button. Nothing is reserved for it (no extra gap) when left empty, mirroring `<lr-badge>`'s identical `end` slot. It remains ordinary consumer content in passive/removable mode; toggle mode makes its flattened subtree inert and hidden from assistive technology beneath the full-surface native toggle. |\n| `start` | Optional decorative leading adornment, such as an icon or status dot. Its flattened subtree remains visible but is inert and hidden from assistive technology. Nothing is reserved for it (no extra gap) when left empty. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The pill's root container. |\n| `end` | Wrapper around the `end` slot. Hidden entirely while empty, and inert plus aria-hidden in toggle mode. |\n| `label` | Wrapper around the default slot; inert and aria-hidden in toggle mode. |\n| `remove-button` | The remove (×) affordance, only rendered while `removable`. |\n| `start` | Inert, aria-hidden wrapper around the decorative `start` slot. Hidden entirely while empty. |\n| `toggle-button` | The real toggle control, rendered over the non-interactive label when toggle mode is active. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-chip-accent` (default: `var(--lr-color-text)`) — Text/icon color of the pill. Each non-neutral `variant` changes its private default to that variant's loud fill.\n- `--lr-chip-bg` (default: `var(--lr-color-surface)`) — Background of the pill. Each non-neutral `variant` changes its private default to that variant's quiet fill.\n- `--lr-chip-border` (default: `var(--lr-color-border)`) — Border color of the pill. Every non-neutral `variant` changes its private default to `transparent`.\n- `--lr-chip-font-size` (default: `var(--lr-font-size-sm)`) — Label font size. Each `size` changes its private default to that step's font size; an inherited or direct public value still wins.\n- `--lr-chip-gap` (default: `var(--lr-space-xs)`) — Gap between the icon, label, and remove button. Each `size` changes its private default to that step's gap.\n- `--lr-chip-height` — Exact block size of the chip. Undeclared by default, so the chip grows to fit its content (floored by `--lr-chip-min-height` when interactive). Set it to pin a fixed height. A value below the shared interactive target is for non-interactive chips only.\n- `--lr-chip-icon-size` (default: `var(--lr-font-size-sm)`) — Font size of the `start` slot wrapper. Its private default follows each `size` step's icon size; an inherited or direct public value remains authoritative.\n- `--lr-chip-min-height` (default: `var(--lr-size-1-5rem)`) — Component density floor for an interactive chip. The real toggle/remove controls also enforce the shared `--lr-icon-button-size` target floor.\n- `--lr-chip-padding-block` (default: `var(--lr-size-0-25rem)`) — Block padding of the pill. Each `size` changes its private default to that step's block padding; an inherited or direct public value remains authoritative.\n- `--lr-chip-padding-inline` (default: `var(--lr-space-s)`) — Inline padding of the pill. Each `size` changes its private default to that step's inline padding; an inherited or direct public value remains authoritative.\n- `--lr-chip-pressed-bg` (default: `var(--lr-chip-bg)`) — Background while a toggleable chip is selected, independently themeable from its resting background.\n- `--lr-chip-pressed-border` (default: `var(--lr-chip-accent)`) — Border color while a toggleable chip is selected, independently themeable from the label/icon color.\n- `--lr-chip-radius` (default: `var(--lr-radius)`) — Corner radius of the pill and of the remove button, kept in sync so retuning one retunes both. `pill` changes its private default to `var(--lr-radius-pill)`. Does not vary by `size` tier.","attributes":[{"name":"disabled","description":"Disables the active toggle/remove control and suppresses its request event.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"pill","description":"Draws fully-rounded ends instead of the default rounded rectangle, matching\n`<lr-badge>`/`<lr-tag>`'s identical property.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"removable","description":"Shows the remove (×) button.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"selected","description":"Current pressed state. This does not make the chip interactive by itself; set `toggleable`\nto opt into the native toggle action. Keeping state and mode independent makes declarative\nSSR and property-update order deterministic. Has no visual or interactive effect while\n`toggleable` is unset or while `removable` owns the chip's action.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"size","description":"Type: `ChipSize`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'3xs'","'small'","'medium'","'large'"]}},{"name":"toggleable","description":"Sole opt-in for the chip's toggle/pressed interactive mode. Set `selected` independently for\nthe current pressed state. The default is a passive label pill. Has no effect while\n`removable` owns the chip's action.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"value","description":"Opaque consumer bookkeeping value — never read, validated, or rendered\nby this component itself, only ever echoed back verbatim (including\n`undefined` if never set) in `lr-remove`'s detail.\n\nType: `string | undefined`"},{"name":"variant","description":"Type: `ChipVariant`","value":{"type":["'neutral'","'brand'","'success'","'warning'","'danger'"]}},{"name":"wrap","description":"Wraps a long label onto multiple lines instead of ellipsis-truncating it to one, matching\n`<lr-suggestion-chips>`'s identical opt-in. `false` (the default) reproduces today's exact\nsingle-line, ellipsis-truncated `[part=\"label\"]`.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"","description":"The chip's label content. Visible accessible text and forwarding-slot reassignment stay synchronized with toggle/remove action names. In toggle mode its flattened subtree is inert and hidden from assistive technology while the separate native toggle owns the action and name."},{"name":"end","description":"Optional trailing content, typically an icon, placed after the label and before the toggle/remove button. Nothing is reserved for it (no extra gap) when left empty, mirroring `<lr-badge>`'s identical `end` slot. It remains ordinary consumer content in passive/removable mode; toggle mode makes its flattened subtree inert and hidden from assistive technology beneath the full-surface native toggle."},{"name":"start","description":"Optional decorative leading adornment, such as an icon or status dot. Its flattened subtree remains visible but is inert and hidden from assistive technology. Nothing is reserved for it (no extra gap) when left empty."}],"js":{"properties":[{"name":"disabled","description":"Disables the active toggle/remove control and suppresses its request event.\n\nAttribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"pill","description":"Draws fully-rounded ends instead of the default rounded rectangle, matching\n`<lr-badge>`/`<lr-tag>`'s identical property.\n\nAttribute: `pill`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"removable","description":"Shows the remove (×) button.\n\nAttribute: `removable`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"selected","description":"Current pressed state. This does not make the chip interactive by itself; set `toggleable`\nto opt into the native toggle action. Keeping state and mode independent makes declarative\nSSR and property-update order deterministic. Has no visual or interactive effect while\n`toggleable` is unset or while `removable` owns the chip's action.\n\nAttribute: `selected`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"size","description":"Attribute: `size`  \nReflected to its attribute.","type":"ChipSize"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"toggleable","description":"Sole opt-in for the chip's toggle/pressed interactive mode. Set `selected` independently for\nthe current pressed state. The default is a passive label pill. Has no effect while\n`removable` owns the chip's action.\n\nAttribute: `toggleable`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"value","description":"Opaque consumer bookkeeping value — never read, validated, or rendered\nby this component itself, only ever echoed back verbatim (including\n`undefined` if never set) in `lr-remove`'s detail.\n\nAttribute: `value`","type":"string | undefined"},{"name":"variant","description":"Attribute: `variant`  \nReflected to its attribute.","type":"ChipVariant"},{"name":"wrap","description":"Wraps a long label onto multiple lines instead of ellipsis-truncating it to one, matching\n`<lr-suggestion-chips>`'s identical opt-in. `false` (the default) reproduces today's exact\nsingle-line, ellipsis-truncated `[part=\"label\"]`.\n\nAttribute: `wrap`  \nReflected to its attribute.","type":"boolean","default":"false"}],"events":[{"name":"lr-chip-select","description":"Fired on click, or Enter/Space while focused, once the chip has opted into toggle mode via `toggleable` and `removable` is not set. `detail: { value, selected }` contains the proposed next state. Cancelable; preventing it keeps the current `selected` state unchanged.","type":"CustomEvent<ChipSelectDetail>"},{"name":"lr-remove","description":"The remove (×) button was activated (click, or Enter/Space while focused — native `<button>` behavior). `detail: { value }` — `value` is `undefined` when the `value` prop was never set. Only rendered while `removable`.","type":"CustomEvent<ChipRemoveDetail>"}]}},{"name":"lr-chip-group","description":"`<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\nCollapsed groups reapply max-visible when assigned children are replaced or reordered at the same count, preserving authored hidden/inert state and releasing departed visibility leases.\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-gap` (default: `var(--lr-space-xs)`) — Gap between `[part=\"base\"]`'s wrapped children, chips and the overflow indicator alike.\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.","attributes":[{"name":"aria-label","description":"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: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max-visible","description":"Maximum number of assigned children shown before the rest collapse behind a \"+N\"\nindicator. Flattened slot-forwarded children count the same as direct light-DOM children.\nUnset (the default) means no limit — every child is always shown. Any explicitly assigned\nvalue is sanitized to a finite, non-negative integer via `finiteCount` — this feeds the\n`hasOverflow`/`syncChildVisibility` index comparisons below directly, so a NaN/negative value\nmust never reach them.\n\nType: `number | undefined`"}],"slots":[{"name":"","description":"`<lr-chip>` elements (or any content, though the chip pairing is the intended usage)."}],"js":{"properties":[{"name":"accessibleLabel","description":"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\nAttribute: `aria-label`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"maxVisible","description":"Maximum number of assigned children shown before the rest collapse behind a \"+N\"\nindicator. Flattened slot-forwarded children count the same as direct light-DOM children.\nUnset (the default) means no limit — every child is always shown. Any explicitly assigned\nvalue is sanitized to a finite, non-negative integer via `finiteCount` — this feeds the\n`hasOverflow`/`syncChildVisibility` index comparisons below directly, so a NaN/negative value\nmust never reach them.\n\nAttribute: `max-visible`","type":"number | undefined"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-overflow-toggle","description":"The overflow indicator was activated, revealing or re-collapsing the excess children. `detail: { expanded }`.","type":"CustomEvent<ChipGroupOverflowToggleDetail>"}]}},{"name":"lr-chunk-inspector","description":"`<lr-chunk-inspector>` — a ranked retrieved-chunks list: relevance score bars with tier tones,\nexpandable chunk text, and the deep-link event that lands a chunk in `lr-document-viewer`.\nNever fetches or ranks and never opens documents itself. Blank chunk identities and later\nduplicates are omitted first-wins before sorting, rendering, state, or events.\n\nEvery row-level part is reachable through `::part()` in both rendering paths: above\n`virtualize-at` a row lives in the internal `<lr-virtual-list>`'s shadow root, and its parts are\nre-exported from there under the same names. Row *state* is exposed as an additional part name\n(`chunk-current`, `score-current`, `score-fill-<tone>`, `text-clamped`) rather than as an\nattribute on the part, because Shadow Parts forbids an attribute selector after `::part()` --\n`::part(chunk)[aria-current='true']` is invalid CSS. The equivalent attributes are still present\non the elements. A state part is a second token in the same `part` attribute, so a `[part~=\"...\"]`\n(not `[part=\"...\"]`) selector is the one that matches inside a tree.\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**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The result wrapper. It owns `role=\"group\"` and the fallback name unless a non-empty host `aria-label` makes the host the sole overall owner. |\n| `chunk` | One chunk row. Carries `role=\"listitem\"` only in the non-virtualized path; while virtualized the surrounding `<lr-virtual-list>` row supplies that role instead. |\n| `chunk-current` | Additional part on the `chunk` row matching `activeChunkId`. |\n| `empty` | The empty-state message, shown when `chunks` is empty. |\n| `open-button` | The chunk's title/open `<button>`. |\n| `score` | The visible percent-score text. |\n| `score-bar` | The `aria-hidden` score bar track. |\n| `score-current` | Additional part on the current row's `score` line. |\n| `score-fill` | The score bar's tone-mapped fill. |\n| `score-fill-danger` | Additional part on a `score-fill` in the low-score tier. |\n| `score-fill-success` | Additional part on a `score-fill` in the high-score tier. |\n| `score-fill-warning` | Additional part on a `score-fill` in the medium-score tier. |\n| `text` | The chunk's text preview. Omitted when `compact`. |\n| `text-clamped` | Additional part on a `text` preview that is still collapsed (line-clamped); dropped once that chunk is expanded. |\n| `title` | The `<span>` inside `open-button` carrying the visible title text. Split from `open-button` (rather than a dual part name on one element) because an exact-match `[part=\"...\"]` CSS attribute selector -- as used by this component's own tests -- cannot match a multi-token `part` attribute value. |\n| `toggle` | The \"Show more\"/\"Show less\" button. Omitted when `compact`. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-chunk-inspector-current-bg` (default: `var(--lr-color-brand-quiet)`) — Background of the chunk matching `activeChunkId`. **Contrast-sensitive:** paired with `--lr-chunk-inspector-current-color`, which has to keep a 4.5:1 ratio against it.\n- `--lr-chunk-inspector-current-color` (default: `var(--lr-color-text)`) — Text color of the current chunk's `[part=\"score\"]` line. **Contrast-sensitive:** the quiet token it replaces only reaches ~4.24:1 against the current background, so override this together with `--lr-chunk-inspector-current-bg`, never alone.","attributes":[{"name":"active-chunk-id","description":"Marks the chunk currently open in the viewer.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"compact","description":"Compact rows render title + score bar + open button only.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"label","description":"Fallback name for the populated chunk group. A non-empty host `aria-label` makes the host the\nsole overall owner; an explicitly empty host label stays empty on the group.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"sort","description":"Ordering applied before rendering the supplied chunks.\n\nType: `ChunkInspectorSort`  \nDefault: `'score'`","value":{"type":["'score'","'none'"]}},{"name":"virtualize-at","description":"Row count at which rendering switches to the internal virtual list.\n\nType: `number`  \nDefault: `50`","value":{"type":["number"]}}],"js":{"properties":[{"name":"activeChunkId","description":"Marks the chunk currently open in the viewer.\n\nAttribute: `active-chunk-id`","type":"string","default":"''"},{"name":"chunks","description":"Retrieved chunks to inspect. The input order is preserved when `sort=\"none\"`.","type":"readonly LyraChunk[]","default":"[]"},{"name":"compact","description":"Compact rows render title + score bar + open button only.\n\nAttribute: `compact`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"label","description":"Fallback name for the populated chunk group. A non-empty host `aria-label` makes the host the\nsole overall owner; an explicitly empty host label stays empty on the group.\n\nAttribute: `label`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"sort","description":"Ordering applied before rendering the supplied chunks.\n\nAttribute: `sort`","type":"ChunkInspectorSort","default":"'score'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"thresholds","description":"Score boundaries used to classify each chunk as high, medium, or low relevance.","type":"LyraScoreThresholds","default":"{ high: 0.75, medium: 0.5, }"},{"name":"virtualizeAt","description":"Row count at which rendering switches to the internal virtual list.\n\nAttribute: `virtualize-at`","type":"number","default":"50"}],"events":[{"name":"lr-chunk-open","description":"A chunk's title/open button was activated -- the event a host routes into `lr-document-viewer` (set `src` from `sourceId`, set `anchor`). `detail: { chunkId, sourceId, anchor? }`.","type":"CustomEvent<LyraEventDetailSnapshot<{\n    chunkId: string;\n    sourceId: string;\n    anchor?: LyraChunkAnchor;\n  }>>"},{"name":"lr-expand","description":"A chunk's text toggle was activated. `detail: { chunkId, expanded }`.","type":"CustomEvent<{ chunkId: string; expanded: boolean }>"}]}},{"name":"lr-citation-badge","description":"`<lr-citation-badge>` — an inline `[n]` citation marker with a hover/\nfocus preview popover and confidence/verification-status coloring. Used\nfor an agent response's inline citations, each carrying a `source-id`\nthat matches a corresponding `<lr-source-card>` shown elsewhere on the\npage (a sibling component in this same family — this component doesn't\nimport or know anything about it, only carries the id through its\nevents).\n\nThe default slot is *not* the badge's visible content — the badge always\nrenders `[index]` — it's reserved for optional rich preview content (e.g.\na filename + short excerpt) shown in a floating popover on hover/focus,\npositioned with `internal/positioner.js`'s `place()` the same way\n`<lr-tool-call-chip>` positions its own detail tooltip. No popover shows\nat all when the slot carries no content, and the popover never traps\nfocus — it's supplementary preview content, not a modal, so Tab continues\npast the badge normally even while it happens to be visible from a mouse\nhover. When preview content exists, the button keeps a stable\n`aria-describedby` relationship to the `role=\"tooltip\"` panel while it is\nboth hidden and visible, so assistive technology can resolve the preview\nas soon as focus causes it to open.\n\nAn authored host `aria-label` deliberately names only the custom-element boundary; it is not\ncopied onto the internal button. Host naming does not cross the shadow boundary, so the button\nretains its localized citation/index/status name as the interactive control's own name.\n\nTwo distinct signals fire from the same badge: `lr-citation-activate`\n(click, or Enter while focused — native `<button>` behavior, no listener\nneeded for the Enter case) is the lightweight \"jump to this source\"\nsignal a host wires to scrolling/highlighting the matching\n`<lr-source-card>`. `lr-citation-open` (dblclick, or Space while\nfocused) is a distinct \"full preview\" signal — `href` in its detail is\n`undefined` when the `href` prop isn't set; the consumer decides what\n\"open\" means (a new tab, a dialog, etc). A double-click still fires two\n`lr-citation-activate` events (one per constituent click — standard\nbrowser `dblclick` behavior) in addition to the one `lr-citation-open`;\na consumer that only cares about the richer signal on a double-click\nshould ignore the paired activate events in that case.\n\nStatus coloring: `verified`/`high` use the success tones (a claim that's\nbeen checked out, or the model is confident in). `medium`/`low` use\nwarning (progressively less certain, but still a real citation).\n`unverified` uses danger — deliberately distinct from `low`: \"hasn't been\nchecked at all\" is a different (arguably riskier) claim than \"checked but\nuncertain\". `default` renders as plain neutral text with no background\ntint, for citations that carry no confidence/verification signal at all.\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) | Rich preview/tooltip content (e.g. a filename + excerpt), shown in a floating popover on hover/focus. Nothing renders (no hover affordance at all) when this slot is empty. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The clickable badge (`<button>`). |\n| `bracket` | Each of the two literal `[`/`]` glyphs. |\n| `index` | The citation number. |\n| `popover` | The floating preview panel (only meaningful while open). |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-citation-badge-accent` (default: `var(--lr-color-text-quiet)`) — Text color of `base`, and its hover border color. Its private default follows the reflected `status`: success for `high`/`verified`, warning for `medium`/`low`, and danger for `unverified`; a public value wins.\n- `--lr-citation-badge-bg` (default: `transparent`) — Background of `base`. Its private default follows `status` to the matching `-quiet` tone (`success`/`warning`/`danger`); a public value wins.\n- `--lr-citation-badge-border` (default: `transparent`) — Resting border color of `base`; no `status` changes it, so it stays transparent unless a host overrides it.\n- `--lr-overlay-border` (default: `var(--lr-color-border)`) — Shared floating-surface edge colour, on the anchored source-preview popover.\n- `--lr-overlay-radius` (default: `var(--lr-radius)`) — Shared floating-surface corner radius, on the anchored source-preview popover.\n- `--lr-overlay-shadow-anchored` (default: `var(--lr-shadow-m)`) — Elevation of the anchored surface.\n- `--lr-overlay-surface` (default: `var(--lr-color-surface-overlay)`) — Shared floating-surface fill, on the anchored source-preview popover.\n- `--lr-positioning-strategy` — Cascading `absolute`/`fixed` override for the preview popover's `fixed` default, read from computed style when it is (re)positioned. Set it once on `:root`, a theme, or one clipping ancestor to change every unset citation badge beneath it; an unrecognized value falls back to `fixed`.","attributes":[{"name":"href","description":"Optional direct link target for the citation's source. Carried into\n`lr-citation-open`'s detail as-is; this component never navigates.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"index","description":"The citation number shown, e.g. `3` renders as `[3]`. Renders directly as visible text (and\nfeeds `lr-citation-activate`/`lr-citation-open`'s `detail.index`), so a NaN/non-integer\nvalue would be a real user-facing rendering bug — clamped to a finite, 1-indexed integer\n(citation numbers are conventionally 1-indexed, matching this property's own default).\n\nType: `number`","value":{"type":["number"]}},{"name":"label","description":"Adds source context to the accessible name while retaining the visible citation index\n(`\"Citation {index}, {label}\"`).\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"source-id","description":"Id of a corresponding `<lr-source-card>` elsewhere on the page —\nechoed back verbatim in both events, never read or validated here.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"status","description":"Confidence/verification state — drives the badge's color and (unless\n`label` is set) part of its accessible name.\n\nType: `CitationBadgeStatus`  \nDefault: `'default'`","value":{"type":["'default'","'high'","'medium'","'low'","'verified'","'unverified'"]}}],"slots":[{"name":"","description":"Rich preview/tooltip content (e.g. a filename + excerpt), shown in a floating popover on hover/focus. Nothing renders (no hover affordance at all) when this slot is empty."}],"js":{"properties":[{"name":"href","description":"Optional direct link target for the citation's source. Carried into\n`lr-citation-open`'s detail as-is; this component never navigates.\n\nAttribute: `href`","type":"string","default":"''"},{"name":"index","description":"The citation number shown, e.g. `3` renders as `[3]`. Renders directly as visible text (and\nfeeds `lr-citation-activate`/`lr-citation-open`'s `detail.index`), so a NaN/non-integer\nvalue would be a real user-facing rendering bug — clamped to a finite, 1-indexed integer\n(citation numbers are conventionally 1-indexed, matching this property's own default).\n\nAttribute: `index`","type":"number"},{"name":"label","description":"Adds source context to the accessible name while retaining the visible citation index\n(`\"Citation {index}, {label}\"`).\n\nAttribute: `label`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"sourceId","description":"Id of a corresponding `<lr-source-card>` elsewhere on the page —\nechoed back verbatim in both events, never read or validated here.\n\nAttribute: `source-id`","type":"string","default":"''"},{"name":"status","description":"Confidence/verification state — drives the badge's color and (unless\n`label` is set) part of its accessible name.\n\nAttribute: `status`  \nReflected to its attribute.","type":"CitationBadgeStatus","default":"'default'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-citation-activate","description":"The badge was activated (click, or Enter while focused). `detail: { sourceId, index }`.","type":"CustomEvent<CitationActivateDetail>"},{"name":"lr-citation-open","description":"The badge's \"full preview\" affordance was triggered (dblclick, or Space while focused). `detail: { sourceId, index, href }`.","type":"CustomEvent<CitationOpenDetail>"}]}},{"name":"lr-claim-evidence","description":"`<lr-claim-evidence>` — a controlled claim-by-claim grounding audit. It relates generated\nclaims to complete citation records, exposes assessment status/confidence, and tolerates\nmissing citation ids without fabricating evidence.\n\nPublic collection sequences are bounded, frozen snapshots. Admitted claim and citation source\nidentities remain opaque while descriptor-safe projections copy the fields used for display and\nlookup once; later rendering and events never reread a source record. Create a new collection\nand reassign it after changes; mutating the assigned array does not update the view. Blank\nclaim/citation ids and later duplicates are ignored before lookup, rendering, counts, or\nactivation. The first record for an id wins.\nA nested badge's `lr-citation-activate` is contained and translated to `lr-citation-select` with\nthe complete citation record. Its distinct `lr-citation-open` signal intentionally remains a\ncomposed child event and crosses this host unchanged, preserving its `{ sourceId, index, href }`\ndetail for consumers that want the badge's richer open action.\n\n---\n\n**Component metadata**\n\n- Status: `stable`\n- Since: `7.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 named claim-evidence region. |\n| `claim` | One claim. |\n| `claim-selected` | The selected claim. |\n| `claim-text` | The claim text. |\n| `claim-trigger` | A claim's selection button. |\n| `confidence` | The optional localized confidence. |\n| `empty` | The empty state. |\n| `evidence` | Resolved evidence citations for one claim. |\n| `explanation` | Caller-supplied assessment explanation. |\n| `list` | The claim list. |\n| `status` | The support-status badge. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-claim-evidence-compact-gap` (default: `var(--lr-space-xs)`) — Gap between `[part=\"claim-trigger\"]`'s columns while `compact`.\n- `--lr-claim-evidence-compact-padding` (default: `var(--lr-space-xs)`) — `[part=\"claim-trigger\"]` padding while `compact`.","attributes":[{"name":"compact","description":"Tighter claim-trigger padding and column gap, for dense evidence lists -- same convention as\n`lr-source-card`'s/`lr-entity-card`'s `compact`. Defaults to `false`, i.e. the full\nclaim-trigger padding. Purely a density knob: each claim's border and background stay, so use\n`frame=\"plain\"` to drop the chrome entirely.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"frame","description":"Container treatment, in the shared `LyraFrame` vocabulary. `'card'` (the default) keeps each\nclaim's bordered, filled box. `'plain'` removes the border, background, and corner radius from\nevery `[part~=\"claim\"]` row, so claims nested inside an already-bordered container (e.g. a\nwider audit panel) don't double the frame. `plain` wins over `compact` when both are set\n(nothing left to tighten).\n\nType: `LyraFrame`  \nDefault: `'card'`","value":{"type":["'card'","'plain'"]}},{"name":"label","description":"Fallback name for the claim-and-evidence region. A non-empty host `aria-label` makes the host\nthe sole overall owner; an explicitly empty host label stays empty on the region.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"selected-claim-id","description":"Controlled id of the claim whose evidence is expanded.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"js":{"properties":[{"name":"citations","description":"Citation records resolved by each claim's citation indexes.","type":"readonly Citation[]","default":"[]"},{"name":"claims","description":"Grounded claims rendered as the selectable evidence index.","type":"readonly GroundedClaim[]","default":"[]"},{"name":"compact","description":"Tighter claim-trigger padding and column gap, for dense evidence lists -- same convention as\n`lr-source-card`'s/`lr-entity-card`'s `compact`. Defaults to `false`, i.e. the full\nclaim-trigger padding. Purely a density knob: each claim's border and background stay, so use\n`frame=\"plain\"` to drop the chrome entirely.\n\nAttribute: `compact`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"frame","description":"Container treatment, in the shared `LyraFrame` vocabulary. `'card'` (the default) keeps each\nclaim's bordered, filled box. `'plain'` removes the border, background, and corner radius from\nevery `[part~=\"claim\"]` row, so claims nested inside an already-bordered container (e.g. a\nwider audit panel) don't double the frame. `plain` wins over `compact` when both are set\n(nothing left to tighten).\n\nAttribute: `frame`  \nReflected to its attribute.","type":"LyraFrame","default":"'card'"},{"name":"label","description":"Fallback name for the claim-and-evidence region. A non-empty host `aria-label` makes the host\nthe sole overall owner; an explicitly empty host label stays empty on the region.\n\nAttribute: `label`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"selectedClaimId","description":"Controlled id of the claim whose evidence is expanded.\n\nAttribute: `selected-claim-id`","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-citation-select","description":"Evidence was activated. `detail: { citation }`.","type":"CustomEvent<\n    LyraEventDetailSnapshot<CitationSelectEventDetail>\n  >"},{"name":"lr-claim-select","description":"A claim was activated. `detail: { claim }`.","type":"CustomEvent<\n    LyraEventDetailSnapshot<{ claim: GroundedClaim }>\n  >"}]}},{"name":"lr-code-block","description":"`<lr-code-block>` — fenced code display with optional lazy syntax\nhighlighting and a copy button. No highlighting grammar ships in this\ncomponent itself: it lazy-loads the optional peer dependency `shiki` (see\n`code-loader.ts`) for the actual tokenizing, and degrades to a plain\n`<pre><code>` when that peer isn't installed or `language` is unset/\nunrecognized — the exact same optional-peer shape `<lr-markdown>` and\n`<lr-chart>` already establish. That fallback is the *default* rendering\npath, not a degraded one: unhighlighted code is perfectly usable, and it's\nwhat every instance renders at zero extra bytes until shiki resolves.\n\nA `<lr-skeleton>` placeholder stands in only while shiki itself is\nloading for the very first time on the page (cached — see\n`loadShikiHighlighter()`) and `language` is set. It's deliberately *not*\nshown again for a subsequent per-language grammar load (e.g. a second\n`<lr-code-block>` requesting a language no earlier instance has used\nyet) — that grammar fetch is typically fast, and the plain-text fallback\nis already a perfectly readable placeholder for it, so a second\nloading-chrome state would add complexity for little practical benefit.\n\nSet a host `aria-label` (or the matching `accessibleLabel` property) to\noverride the filename/language-derived name on the internal focusable code\nregion. The name is forwarded to the element that owns `role=\"group\"`, not\nleft only on the custom-element host across the shadow boundary.\n\n`languages` is an additive, opt-in escape hatch from that default path for\na consumer whose language set is fixed and known ahead of time: a map of\nlanguage id to an already-imported shiki grammar module (e.g. `import bash\nfrom 'shiki/langs/bash.mjs'`). When `language` matches a key in `languages`,\nthis component seeds a fine-grained `createHighlighterCore()` highlighter\nwith *only* the pre-supplied grammars (see `code-loader.ts`'s\n`loadShikiHighlighterCore()`) instead of waiting on `loadShikiHighlighter()`\nand its dynamic per-language `loadLanguage()` import. The payoff isn't\nruntime cost — the default dynamic-import path is already well-optimized\nfor that — it's *build output*: shiki's main entry point bundles a dynamic\n`import()` per bundled language (~200 of them) because a bundler can't\nstatically narrow which of those a `loadLanguage(lang: string)` call might\nrequest at runtime, so it conservatively emits a build-output chunk for\nevery one of them. `shiki/core`'s fine-grained API has no such table — a\nbundler only ever sees the exact grammar modules `languages` itself\n`import`s, so a consumer who pins its full language set this way trades a\nhand-maintained list for a build output scoped to just those languages\ninstead of shiki's entire bundled set. A language requested but absent\nfrom `languages` still falls back to the ordinary dynamic-import path\nunchanged, so this is a partial opt-in, not a replacement for it.\n\nAdopts the `line-range` slice of this library's shared anchor-target contract:\n`highlights`/`activeHighlightId` paint (and `highlight-lines` additionally marks) per-line\nemphasis in both the shiki and plain-text-fallback rendering paths identically, and\n`scrollToAnchor()` resolves a `line-range` anchor. `activatable-lines` is a separate, purely\nlocal affordance that turns the (`line-numbers`-gated) gutter into a keyboard-navigable,\nclickable roving-tabindex group emitting `lr-line-activate` — it doesn't require `highlights` to\nbe set. If controlled `code` shrinks while a line owns focus, focus follows the clamped\nsurviving line through both plain and highlighted DOM replacement; an explicit move to another\ncontrol during the update is never overridden.\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| `header-actions` | Extra controls for the header row, rendered after the copy control. Their presence alone is enough to render the header. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The outer container. |\n| `body` | The scrollable region wrapping the code (or the loading skeleton); respects `max-height`, `hidden` while `collapsible` and `collapsed`. |\n| `code` | The rendered `<code>`, same split as `pre` above. |\n| `copy-button` | The copy-to-clipboard control, when `copyable`. A composed `<lr-icon-button>` as of 16.0.0: it still owns the accessible name, the activation and the part names, while its background, radius, hover/press mixes, focus ring and hit-area floor now come from `--lr-icon-button-*`. Also carries `copy-button-text` or `copy-button-icon` for the active `copyAppearance`, since a state cannot be selected with `::part(copy-button)[attr]`. |\n| `copy-button-icon` | The copy control while `copyAppearance` is `'icon'`. |\n| `copy-button-text` | The copy control while `copyAppearance` is `'text'`. |\n| `copy-button__control` | The copy control's own native `<button>`, forwarded because the painted surface sits one shadow boundary deeper than `copy-button`. |\n| `filename` | The `filename` text, when set. |\n| `header` | The row above the code (filename/language/copy/toggle), present whenever there's anything to put in it. |\n| `header-actions` | The wrapper around the `header-actions` slot, at the trailing end of the header row. |\n| `language` | The `language` badge, when set, so the language is exposed to assistive tech as visible text rather than only a `language` attribute a screen reader would never announce. |\n| `line-button` | A gutter line-number button, only rendered while `activatable-lines` and `line-numbers` are both set. |\n| `line-highlight` | A line marked by `highlight-lines` or a `line-range` entry in `highlights`. |\n| `pre` | The rendered `<pre>` — shiki's own in the highlighted path, this component's own plain one in the fallback path. |\n| `toggle` | The collapse/expand chevron button, when `collapsible`. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-code-block-active-line-outline-color` (default: `var(--lr-color-brand)`) — Outline color of the line marked active by `active-highlight-id`. Retints just that outline, leaving every other `--lr-color-brand` surface in the component (header pill, hover states, focus ring) alone. Inherits, so it can also be set on an ancestor or at the theme level.\n- `--lr-code-block-font` (default: `var(--lr-font-mono)`) — Monospace family for the rendered `pre` and `code`.\n- `--lr-code-block-highlighted-line-bg` (default: `var(--lr-color-warning-quiet)`) — Background color of a line marked by `highlight-lines` or a `line-range` entry in `highlights`, in both the light and dark-theme (shiki) rendering paths. Retints just that background, leaving every other `--lr-color-warning-quiet` surface alone. Inherits, so it can also be set on an ancestor or at the theme level.\n- `--lr-code-block-language-bg` (default: `var(--lr-color-brand-quiet)`) — Background of the `language` badge in `[part=\"header\"]`.\n- `--lr-code-block-language-color` (default: `var(--lr-color-brand)`) — Text color of the `language` badge. Same default as `--lr-code-editor-tab-size`, so the editable and read-only code surfaces agree; `lr-markdown`/`lr-markdown-core` declare the same token for their own `code-block` part (they are sibling elements, so they cannot inherit this one). Read as a token and never written inline, so a host override survives shiki's own inline `style` on the highlighted `pre`. The default is a `var()` fallback at the point of use rather than a `:host` declaration, so it inherits: set it on the element, a container, or `:root` and it reaches every code surface below. The markdown surface wraps (`white-space: pre-wrap`) while this one does not, so the same value can look different on a wrapped line, where tab stops restart.\n- `--lr-code-block-max-height` (default: `none`) — Scroll cap applied to `body`. The `max-height` attribute, when set, writes this same property inline on `body` and therefore wins.\n- `--lr-code-block-tab-size` (default: `2`) — Tab width for the rendered code, applied to `pre`.\n- `--lr-theme-scrollbar-gutter` (default: `auto`) — Opt-in theme-level scrollbar gutter honored by `body`; see `--lr-theme-scrollbar-width`.\n- `--lr-theme-scrollbar-width` (default: `auto`) — Opt-in theme-level scrollbar width honored by `body`; unset, renders identically to before. Set on `:root` or any ancestor to retune every internal scroll container in the library at once. Shared with `lr-code-block-core` (which reuses this stylesheet).","attributes":[{"name":"activatable-lines","description":"Makes the (`line-numbers`-gated) gutter a roving group of activation buttons.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"active-highlight-id","description":"The `highlights` entry, if any, currently treated as active (`data-active` on its lines).\n\nType: `| string\n    | null`  \nDefault: `null`"},{"name":"aria-label","description":"Accessible-name override for the internal focusable code region. Maps\nto the host's `aria-label` attribute and wins over `filename` and\n`language`-derived defaults.\n\nType: `string | null`  \nDefault: `null`"},{"name":"code","description":"The raw source text. Removing the attribute renders an empty code block.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"collapsed","description":"Whether the code region is currently hidden. Only has a visible effect\nwhile `collapsible` is also true.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"collapsible","description":"Whether the code region can be collapsed via a header toggle.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"copy-appearance","description":"How the header's copy control presents itself. `'text'` (the default) is the labelled button\nthis component has always rendered -- unset, nothing about the header changes. `'icon'` swaps\nthe visible label for a compact glyph and promotes the same localized Copy/Copied/failure\nstring to the control's accessible name, for a dense header that already carries a filename,\na language chip and slotted `header-actions`.\n\nType: `LyraCodeBlockCopyAppearance`  \nDefault: `'text'`","value":{"type":["'text'","'icon'"]}},{"name":"copyable","description":"Shows a copy-to-clipboard button in the header.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"filename","description":"Shown in the header above the code, when set.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"highlight-lines","description":"Comma-separated 1-based inclusive line ranges (e.g. `\"3-5,7\"`) to visually emphasize.\nRemoving the attribute clears these ranges. Declarative sugar over `highlights` — merges with, and renders identically to, any\n`line-range` entries in `highlights`.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"language","description":"A shiki-recognized language id or alias (e.g. `\"javascript\"`,\n`\"python\"`, `\"json\"`). When unset, or when shiki doesn't recognize it,\nthe code renders as plain unhighlighted text regardless of whether\nshiki itself is available.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"line-numbers","description":"Whether to display one-based line numbers beside the code. Highlighted gutters\nfollow live locale and line-label string changes.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max-height","description":"A CSS length (e.g. `\"20rem\"`); once set, the code scrolls internally\npast this height instead of growing the page.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"slots":[{"name":"header-actions","description":"Extra controls for the header row, rendered after the copy control. Their presence alone is enough to render the header."}],"js":{"properties":[{"name":"accessibleLabel","description":"Accessible-name override for the internal focusable code region. Maps\nto the host's `aria-label` attribute and wins over `filename` and\n`language`-derived defaults.\n\nAttribute: `aria-label`","type":"string | null","default":"null"},{"name":"activatableLines","description":"Makes the (`line-numbers`-gated) gutter a roving group of activation buttons.\n\nAttribute: `activatable-lines`","type":"boolean","default":"false"},{"name":"activeHighlightId","description":"The `highlights` entry, if any, currently treated as active (`data-active` on its lines).\n\nAttribute: `active-highlight-id`","type":"| string\n    | null","default":"null"},{"name":"anchorKinds","description":"Anchor kinds this component resolves via `scrollToAnchor()`.","type":"readonly LyraAnchor['kind'][]","default":"['line-range']","read-only":true},{"name":"code","description":"The raw source text. Removing the attribute renders an empty code block.\n\nAttribute: `code`","type":"string","default":"''"},{"name":"collapsed","description":"Whether the code region is currently hidden. Only has a visible effect\nwhile `collapsible` is also true.\n\nAttribute: `collapsed`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"collapsible","description":"Whether the code region can be collapsed via a header toggle.\n\nAttribute: `collapsible`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"copyAppearance","description":"How the header's copy control presents itself. `'text'` (the default) is the labelled button\nthis component has always rendered -- unset, nothing about the header changes. `'icon'` swaps\nthe visible label for a compact glyph and promotes the same localized Copy/Copied/failure\nstring to the control's accessible name, for a dense header that already carries a filename,\na language chip and slotted `header-actions`.\n\nAttribute: `copy-appearance`  \nReflected to its attribute.","type":"LyraCodeBlockCopyAppearance","default":"'text'"},{"name":"copyable","description":"Shows a copy-to-clipboard button in the header.\n\nAttribute: `copyable`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"filename","description":"Shown in the header above the code, when set.\n\nAttribute: `filename`","type":"string","default":"''"},{"name":"highlightLines","description":"Comma-separated 1-based inclusive line ranges (e.g. `\"3-5,7\"`) to visually emphasize.\nRemoving the attribute clears these ranges. Declarative sugar over `highlights` — merges with, and renders identically to, any\n`line-range` entries in `highlights`.\n\nAttribute: `highlight-lines`","type":"string","default":"''"},{"name":"highlights","description":"Host-supplied highlights to paint over the code. Only `line-range` anchors are meaningful\nhere — every other `LyraAnchor` kind, and a highlight with a missing, malformed, or\nnon-discriminated anchor, is ignored (`snapshotLyraHighlights`).","type":"readonly LyraHighlight[]","default":"[]"},{"name":"language","description":"A shiki-recognized language id or alias (e.g. `\"javascript\"`,\n`\"python\"`, `\"json\"`). When unset, or when shiki doesn't recognize it,\nthe code renders as plain unhighlighted text regardless of whether\nshiki itself is available.\n\nAttribute: `language`","type":"string","default":"''"},{"name":"languages","description":"A map of language id to an already-imported shiki grammar module's\ndefault export (e.g. `{ bash: bashGrammar }` where `bashGrammar` came\nfrom a module-scope `import bash from 'shiki/langs/bash.mjs'`). When\n`language` matches a key here, highlighting for it is seeded from\nexactly this pre-supplied grammar via a fine-grained\n`createHighlighterCore()` highlighter, bypassing the default\n`loadShikiHighlighter()` singleton and its dynamic per-language\n`loadLanguage()` import entirely for that language — see the class doc\nabove for the build-output rationale. A `language` value absent from\nthis map (or left unset, or when `languages` itself is unset) falls\nback to that default dynamic-import path unchanged. For a TypeScript\nannotation, use `import type { ShikiLanguageInput } from\n'@aceshooting/lyra-ui/components/conversation/code-block/code-block.js'`;\nthis granular type-only import emits no registration side effect.","type":"Readonly<Record<\n    string,\n    ShikiLanguageInput\n  >> | undefined"},{"name":"lineNumbers","description":"Whether to display one-based line numbers beside the code. Highlighted gutters\nfollow live locale and line-label string changes.\n\nAttribute: `line-numbers`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"maxHeight","description":"A CSS length (e.g. `\"20rem\"`); once set, the code scrolls internally\npast this height instead of growing the page.\n\nAttribute: `max-height`","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-copy","description":"The raw `code` was written to the clipboard. Frozen detail: `{ ok: true, text }`.","type":"CustomEvent<LyraClipboardWriteSuccess>"},{"name":"lr-copy-error","description":"Clipboard writing failed. Frozen detail: `{ ok: false, text, reason, error }`, where `reason` is `'unsupported' | 'denied' | 'failed'`.","type":"CustomEvent<LyraClipboardWriteFailure>"},{"name":"lr-error","description":"Clipboard writing failed; generic no-detail notification.","type":"CustomEvent<null>"},{"name":"lr-line-activate","description":"A gutter line number was activated (click, or Enter/Space while focused) while `activatable-lines` is set. `detail: { line }`.","type":"CustomEvent<{ line: number }>"},{"name":"lr-text-select","description":"Fired when a text selection inside the code body ends. `detail: { text, anchor, rects }`; `anchor` is a `line-range` anchor covering the selected lines.","type":"CustomEvent<{\n    readonly text: string;\n    readonly anchor: LyraAnchor;\n    readonly rects: readonly TextSelectRect[];\n  }>"},{"name":"lr-toggle","description":"The collapse/expand header button was activated. `detail: { collapsed }` — same event name and shape convention as `<lr-thinking-panel>`'s own `lr-toggle`.","type":"CustomEvent<{ collapsed: boolean }>"},{"name":"lr-toggle-request","description":"Cancelable request emitted before collapse state changes. `detail: { collapsed }` is the proposed next state.","type":"CustomEvent<{ collapsed: boolean }>"}]}},{"name":"lr-code-block-core","description":"`<lr-code-block-core>` — a build-lean variant of `<lr-code-block>` for\na consumer whose `languages` map already covers every language it will\never render. It only ever calls `loadShikiHighlighterCore()` (from the peer-neutral Shiki\ncapability leaf) with `languages`' already-resolved entries — never `loadShikiHighlighter()`, the\ndefault ~200-language dynamic-import table loader `<lr-code-block>` calls. This component's own\nmodule never textually contains a call to (or import of) `loadShikiHighlighter` at all, so a\nconsumer importing this entry point instead of `code-block.js` gets a\ngenuinely shiki-full-table-free build.\n\nA `languages` entry may also be a lazy loader (`() => import('@shikijs/langs/<name>')`) instead\nof an already-resolved grammar — resolved and registered into the highlighter (via\n`HighlighterCore.loadLanguage()`) the first time a fence actually requests that key, memoized per\nkey so it is never re-imported. See the `languages` property doc for the exact shape.\n\nA `language` value absent from `languages` always renders the plain\n`<pre><code>` fallback — there is no default/full-table highlighter here\nto fall back to, unlike `<lr-code-block>`'s dynamic-import path for an\nunmapped language, and neither does a `languages` entry whose lazy loader rejects. That fallback\nis the *default* rendering path, not a degraded one, same as `<lr-code-block>`'s own plain-text\nfallback.\n\nEverything else — `code`/`language`/`filename`/`copyable`/`collapsible`/\n`collapsed`/`maxHeight`, the copy button, the collapse header toggle, the\nloading-skeleton behavior while the fine-grained highlighter itself\nresolves — matches `<lr-code-block>` exactly. A host `aria-label` (or\nthe matching `accessibleLabel` property) is forwarded to the internal\nfocusable element that owns the named `group` role.\n\nAdopts the `line-range` slice of this library's shared anchor-target contract, identical to\n`<lr-code-block>`: `highlights`/`activeHighlightId` paint (and `highlight-lines` additionally\nmarks) per-line emphasis in both the shiki and plain-text-fallback rendering paths identically,\nand `scrollToAnchor()` resolves a `line-range` anchor. `activatable-lines` is a separate, purely\nlocal affordance that turns the (`line-numbers`-gated) gutter into a keyboard-navigable,\nclickable roving-tabindex group emitting `lr-line-activate` — it doesn't require `highlights` to\nbe set. If controlled `code` shrinks while a line owns focus, focus follows the clamped\nsurviving line through both plain and highlighted DOM replacement; an explicit move to another\ncontrol during the update is never overridden.\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| `header-actions` | Extra controls for the header row, rendered after the copy control. Their presence alone is enough to render the header. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The outer container. |\n| `body` | The scrollable region wrapping the code (or the loading skeleton); respects `max-height`, `hidden` while `collapsible` and `collapsed`. |\n| `code` | The rendered `<code>`, same split as `pre` above. |\n| `copy-button` | The copy-to-clipboard control, when `copyable`. A composed `<lr-icon-button>` as of 16.0.0: it still owns the accessible name, the activation and the part names, while its background, radius, hover/press mixes, focus ring and hit-area floor now come from `--lr-icon-button-*`. Also carries `copy-button-text` or `copy-button-icon` for the active `copyAppearance`, since a state cannot be selected with `::part(copy-button)[attr]`. |\n| `copy-button-icon` | The copy control while `copyAppearance` is `'icon'`. |\n| `copy-button-text` | The copy control while `copyAppearance` is `'text'`. |\n| `copy-button__control` | The copy control's own native `<button>`, forwarded because the painted surface sits one shadow boundary deeper than `copy-button`. |\n| `filename` | The `filename` text, when set. |\n| `header` | The row above the code (filename/language/copy/toggle), present whenever there's anything to put in it. |\n| `header-actions` | The wrapper around the `header-actions` slot, at the trailing end of the header row. |\n| `language` | The `language` badge, when set, so the language is exposed to assistive tech as visible text rather than only a `language` attribute a screen reader would never announce. |\n| `line-button` | A gutter line-number button, only rendered while `activatable-lines` and `line-numbers` are both set. |\n| `line-highlight` | A line marked by `highlight-lines` or a `line-range` entry in `highlights`. |\n| `pre` | The rendered `<pre>` — shiki's own in the highlighted path, this component's own plain one in the fallback path. |\n| `toggle` | The collapse/expand chevron button, when `collapsible`. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-code-block-active-line-outline-color` (default: `var(--lr-color-brand)`) — Outline color of the line marked active by `active-highlight-id`, leaving every other `--lr-color-brand` surface in the component alone.\n- `--lr-code-block-font` (default: `var(--lr-font-mono)`) — Monospace family for the rendered `pre` and `code`.\n- `--lr-code-block-highlighted-line-bg` (default: `var(--lr-color-warning-quiet)`) — Background color of a line marked by `highlight-lines` or a `line-range` entry in `highlights`. Shared with `lr-code-block` (this component reuses its stylesheet), leaving every other `--lr-color-warning-quiet` surface alone.\n- `--lr-code-block-language-bg` (default: `var(--lr-color-brand-quiet)`) — Background of the `language` badge in `[part=\"header\"]`. Shared with `lr-code-block` (this component reuses its stylesheet).\n- `--lr-code-block-language-color` (default: `var(--lr-color-brand)`) — Text color of the `language` badge.\n- `--lr-code-block-max-height` (default: `none`) — Scroll cap applied to `body`. The `max-height` attribute, when set, writes this same property inline on `body` and therefore wins.\n- `--lr-code-block-tab-size` (default: `2`) — Tab width for the rendered code, applied to `pre`. Shared with `lr-code-block` (this component reuses its stylesheet), `lr-code-editor`, and the markdown viewers' own `code-block` part, so every code surface agrees on a tab's width.\n- `--lr-theme-scrollbar-gutter` (default: `auto`) — Opt-in theme-level scrollbar gutter honored by `body`; see `--lr-theme-scrollbar-width`.\n- `--lr-theme-scrollbar-width` (default: `auto`) — Opt-in theme-level scrollbar width honored by `body`; unset, renders identically to before. Set on `:root` or any ancestor to retune every internal scroll container in the library at once. Shared with `lr-code-block` (this component reuses its stylesheet).","attributes":[{"name":"activatable-lines","description":"Turns the (`line-numbers`-gated) gutter into a roving-tabindex group of buttons emitting\n`lr-line-activate`. Has no effect while `line-numbers` is unset.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"active-highlight-id","description":"The `highlights` entry, if any, currently treated as active (`data-active` on its lines).\n\nType: `| string\n    | null`  \nDefault: `null`"},{"name":"aria-label","description":"Accessible-name override for the internal focusable code region. Maps\nto the host's `aria-label` attribute and wins over `filename` and\n`language`-derived defaults.\n\nType: `string | null`  \nDefault: `null`"},{"name":"code","description":"The raw source text. Removing the attribute renders an empty code block.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"collapsed","description":"Whether the code region is currently hidden. Only has a visible effect\nwhile `collapsible` is also true.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"collapsible","description":"Whether the code region can be collapsed via a header toggle.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"copy-appearance","description":"How the header's copy control presents itself. `'text'` (the default) is the labelled button\nthis component has always rendered -- unset, nothing about the header changes. `'icon'` swaps\nthe visible label for a compact glyph and promotes the same localized Copy/Copied/failure\nstring to the control's accessible name, for a dense header that already carries a filename,\na language chip and slotted `header-actions`.\n\nType: `LyraCodeBlockCopyAppearance`  \nDefault: `'text'`","value":{"type":["'text'","'icon'"]}},{"name":"copyable","description":"Shows a copy-to-clipboard button in the header.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"filename","description":"Shown in the header above the code, when set.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"highlight-lines","description":"Comma-separated 1-based inclusive line ranges (e.g. `\"3-5,7\"`) to visually emphasize.\nRemoving the attribute clears these ranges. Declarative sugar over `highlights` — merges with, and renders identically to, any\n`line-range` entries in `highlights`.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"language","description":"A shiki-recognized language id or alias (e.g. `\"javascript\"`,\n`\"python\"`, `\"json\"`). When unset, or when it isn't a key in\n`languages`, the code renders as plain unhighlighted text — this\ncomponent has no default/full-table highlighter to fall back to.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"line-numbers","description":"Whether to display one-based line numbers beside the code. Highlighted gutters\nfollow live locale and line-label string changes.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max-height","description":"A CSS length (e.g. `\"20rem\"`); once set, the code scrolls internally\npast this height instead of growing the page.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"slots":[{"name":"header-actions","description":"Extra controls for the header row, rendered after the copy control. Their presence alone is enough to render the header."}],"js":{"properties":[{"name":"accessibleLabel","description":"Accessible-name override for the internal focusable code region. Maps\nto the host's `aria-label` attribute and wins over `filename` and\n`language`-derived defaults.\n\nAttribute: `aria-label`","type":"string | null","default":"null"},{"name":"activatableLines","description":"Turns the (`line-numbers`-gated) gutter into a roving-tabindex group of buttons emitting\n`lr-line-activate`. Has no effect while `line-numbers` is unset.\n\nAttribute: `activatable-lines`","type":"boolean","default":"false"},{"name":"activeHighlightId","description":"The `highlights` entry, if any, currently treated as active (`data-active` on its lines).\n\nAttribute: `active-highlight-id`","type":"| string\n    | null","default":"null"},{"name":"anchorKinds","description":"Anchor kinds this component resolves via `scrollToAnchor()`.","type":"readonly LyraAnchor['kind'][]","default":"['line-range']","read-only":true},{"name":"code","description":"The raw source text. Removing the attribute renders an empty code block.\n\nAttribute: `code`","type":"string","default":"''"},{"name":"collapsed","description":"Whether the code region is currently hidden. Only has a visible effect\nwhile `collapsible` is also true.\n\nAttribute: `collapsed`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"collapsible","description":"Whether the code region can be collapsed via a header toggle.\n\nAttribute: `collapsible`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"copyAppearance","description":"How the header's copy control presents itself. `'text'` (the default) is the labelled button\nthis component has always rendered -- unset, nothing about the header changes. `'icon'` swaps\nthe visible label for a compact glyph and promotes the same localized Copy/Copied/failure\nstring to the control's accessible name, for a dense header that already carries a filename,\na language chip and slotted `header-actions`.\n\nAttribute: `copy-appearance`  \nReflected to its attribute.","type":"LyraCodeBlockCopyAppearance","default":"'text'"},{"name":"copyable","description":"Shows a copy-to-clipboard button in the header.\n\nAttribute: `copyable`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"filename","description":"Shown in the header above the code, when set.\n\nAttribute: `filename`","type":"string","default":"''"},{"name":"highlightLines","description":"Comma-separated 1-based inclusive line ranges (e.g. `\"3-5,7\"`) to visually emphasize.\nRemoving the attribute clears these ranges. Declarative sugar over `highlights` — merges with, and renders identically to, any\n`line-range` entries in `highlights`.\n\nAttribute: `highlight-lines`","type":"string","default":"''"},{"name":"highlights","description":"Host-supplied highlights to paint over the code. Only `line-range` anchors are meaningful\nhere — every other `LyraAnchor` kind, and a highlight with a missing, malformed, or\nnon-discriminated anchor, is ignored (`snapshotLyraHighlights`).","type":"readonly LyraHighlight[]","default":"[]"},{"name":"language","description":"A shiki-recognized language id or alias (e.g. `\"javascript\"`,\n`\"python\"`, `\"json\"`). When unset, or when it isn't a key in\n`languages`, the code renders as plain unhighlighted text — this\ncomponent has no default/full-table highlighter to fall back to.\n\nAttribute: `language`","type":"string","default":"''"},{"name":"languages","description":"Grammar definitions this instance can highlight, e.g. `{ json: jsonGrammar }` (import from\n`shiki/langs/<name>.mjs`), or a lazy loader per key, e.g.\n`{ bash: () => import('@shikijs/langs/bash') }` -- called (at most once per key, memoized)\nthe first time a fenced block actually requests that language, instead of requiring every\ngrammar to already be imported before the map can be bound at all. This component has no\ndefault/full-table fallback highlighter -- a `language` absent from this map always renders\nthe plain-text fallback, and so does a key whose loader rejects. Empty (the\ndefault) never highlights at all. Replacing the map starts a new loading generation; an\nolder map that settles later cannot clear the current map's loading state or replace its\nhighlighted output. For a TypeScript annotation, use `import type { ShikiLanguageSource } from\n'@aceshooting/lyra-ui/components/conversation/code-block/code-block-core.js'`; this granular\ntype-only import emits no registration side effect.","type":"Readonly<Record<\n    string,\n    ShikiLanguageSource\n  >>","default":"{}"},{"name":"lineNumbers","description":"Whether to display one-based line numbers beside the code. Highlighted gutters\nfollow live locale and line-label string changes.\n\nAttribute: `line-numbers`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"maxHeight","description":"A CSS length (e.g. `\"20rem\"`); once set, the code scrolls internally\npast this height instead of growing the page.\n\nAttribute: `max-height`","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-copy","description":"The raw `code` was written to the clipboard. Frozen detail: `{ ok: true, text }`.","type":"CustomEvent<LyraClipboardWriteSuccess>"},{"name":"lr-copy-error","description":"Clipboard writing failed. Frozen detail: `{ ok: false, text, reason, error }`, where `reason` is `'unsupported' | 'denied' | 'failed'`.","type":"CustomEvent<LyraClipboardWriteFailure>"},{"name":"lr-error","description":"Clipboard writing failed; generic no-detail notification.","type":"CustomEvent<null>"},{"name":"lr-line-activate","description":"A gutter line number was activated (click, or Enter/Space while focused) while `activatable-lines` is set. `detail: { line }`.","type":"CustomEvent<{ line: number }>"},{"name":"lr-text-select","description":"Fired when a text selection inside the code body ends. `detail: { text, anchor, rects }`; `anchor` is a `line-range` anchor covering the selected lines.","type":"CustomEvent<{\n    readonly text: string;\n    readonly anchor: LyraAnchor;\n    readonly rects: readonly TextSelectRect[];\n  }>"},{"name":"lr-toggle","description":"The collapse/expand header button was activated. `detail: { collapsed }` — same event name and shape convention as `<lr-thinking-panel>`'s own `lr-toggle`.","type":"CustomEvent<{ collapsed: boolean }>"},{"name":"lr-toggle-request","description":"Cancelable request emitted before collapse state changes. `detail: { collapsed }` is the proposed next state.","type":"CustomEvent<{ collapsed: boolean }>"}]}},{"name":"lr-code-editor","description":"`<lr-code-editor>` — dependency-free multiline code editing surface with optional line numbers.\n\nKeyboard contract (no keyboard trap, WCAG 2.1.2): Tab inserts one indent unit of spaces at the\ncaret. Shift+Tab is never captured, so it always performs native reverse focus traversal.\nPressing Escape releases the next Tab for native forward traversal instead of indenting; typing\nany other key, or focus leaving the editor, re-arms Tab indentation.\nIn narrow allocations label/hint/error chrome wraps at the host boundary, while unbroken source\nremains reachable through the editor's one internal scroll surface instead of widening the page.\nWhen a containing block gives the host a definite block size, the host, form-control, editor,\nand textarea chain fills that allocation; without one, the editor remains content-sized above\nits active `--lr-code-editor-min-block-size` floor.\nThe native textarea receives `required` and explicit stateful `aria-invalid`: visible error\nchrome wins immediately, while intrinsic/custom invalidity is exposed only after interaction.\nForm reset restores the default and pristine interaction feedback while required and custom\nvalidity constraints remain. Removed label/hint/error attributes render as absent chrome.\nHost `aria-describedby` references resolve onto the native textarea before local error/hint\nguidance and remain current across target replacement, reconnect, and adoption.\n\nTab-width precedence, highest first: an explicitly assigned `tabSize` (property or `tab-size`\nattribute) wins over everything; otherwise a host-level `--lr-code-editor-tab-size` override\nwins; otherwise the stylesheet's `:host` default of `2` applies. The property therefore stays the\nprimary knob, but it no longer silently shadows the token while it sits at its default -- see\n`indentWidth` for how the same order drives the Tab key, not just the rendered tab stops.\nNative text and its private measurement use the same tab width. Soft/hard wrapping fits the\neditor allocation; unwrapped text and wrapped lines share the editor frame's scroll surface.\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| `error` | Validation message. |\n| `hint` | Supporting text. |\n| `label` | Visible label content. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `editor` | Editor frame and the component's only scrollport. |\n| `error` | Validation message. |\n| `form-control` | Outer wrapper. |\n| `form-control-label` | Label. Also carries the `label` part token for compatibility. |\n| `gutter` | Line-number gutter. |\n| `hint` | Supporting text. |\n| `label` | Alias of `form-control-label`. |\n| `textarea` | Native textarea. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-code-editor-min-block-size` (default: `var(--lr-size-8rem)`) — Minimum block size of the editor frame and its textarea. Comes from the active `size` tier by default; assign it directly to override that tier's value.\n- `--lr-code-editor-padding` (default: `var(--lr-space-s)`) — Padding of the gutter (block side only) and the textarea (all sides), from the active `size` tier.\n- `--lr-code-editor-font-size` (default: `var(--lr-font-size-m)`) — Font size of the gutter's line numbers and the textarea, from the active `size` tier.\n- `--lr-code-editor-line-height` (default: `1.5`) — Line height shared by the gutter and the textarea, so line numbers stay aligned with their lines.\n- `--lr-code-editor-tab-size` (default: `2`) — The textarea's `tab-size`. The single channel for tab width — the class writes this token rather than setting `tab-size` directly.\n- `--lr-code-editor-border` (default: `var(--lr-color-border)`) — Resting editor-frame border color, independent of the hover and invalid colors below.\n- `--lr-code-editor-fill` (default: `var(--lr-color-surface)`) — Resting editor-frame background.\n- `--lr-code-editor-hover-border` (default: `var(--lr-color-brand)`) — Editor-frame border while the enabled surface is hovered.\n- `--lr-code-editor-invalid-border` (default: `var(--lr-color-danger)`) — Editor-frame border while invalid chrome is visible.\n- `--lr-form-control-required-content` (default: `' *'`) — The required-field marker rendered after the label. Set it to `''` to suppress the marker, or to any other quoted string (`' (required)'`, a localized word) to replace it. Caller-supplied content, so it is never localized here.\n- `--lr-form-control-required-color` (default: `var(--lr-color-danger)`) — Color of that marker, retunable without touching any other danger-coloured surface.\n- `--lr-form-control-required-offset` (default: `0`) — Inline space between the label text and the marker.\n- `--lr-theme-scrollbar-width` (default: `auto`) — Opt-in theme-level scrollbar width honored by the `editor` scroll frame; unset, renders identically to before. Set on `:root` or any ancestor to retune every internal scroll container in the library at once.\n- `--lr-theme-scrollbar-gutter` (default: `auto`) — Opt-in theme-level scrollbar gutter honored by the `editor` scroll frame; see `--lr-theme-scrollbar-width`.","attributes":[{"name":"aria-label","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"autocapitalize","description":"Type: `string`  \nDefault: `'off'`","value":{"type":["string"]}},{"name":"autocomplete","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"autocorrect","description":"Type: `boolean`","value":{"type":["boolean"]}},{"name":"autofocus","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"cols","description":"Visible native column count. It also supplies the platform's hard-wrap submission width.\n\nType: `number`  \nDefault: `20`","value":{"type":["number"]}},{"name":"custom-error","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nType: `string | null`  \nDefault: `null`"},{"name":"disabled","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"enterkeyhint","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"error-text","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"form","description":"Type: `HTMLFormElement | string | null`  \nDefault: `null`"},{"name":"hint","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"inputmode","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"label","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"language","description":"Language identifier exposed as a reflected host styling hook.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"line-numbers","description":"Type: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"maxlength","description":"Type: `number | undefined`"},{"name":"minlength","description":"Type: `number | undefined`"},{"name":"name","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"placeholder","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"readonly","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"required","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"resize","description":"Native CSS `resize` behavior. `auto` grows to content and scrolls at a consumer-supplied\n`max-block-size`; leaving `auto` clears that mode's inline size/overflow state. An invalid\nruntime value falls back to `'both'`.\n\nType: `LyraCodeEditorResize`  \nDefault: `'both'`","value":{"type":["'none'","'both'","'horizontal'","'vertical'","'auto'"]}},{"name":"rows","description":"Type: `number`","value":{"type":["number"]}},{"name":"size","description":"Visual size on the library's one control ladder, shared with `<lr-textarea>`/`<lr-input>`/\n`<lr-select>`. Accepts both the canonical `'2xs'`–`'xl'` steps and Web Awesome's/Shoelace's\n`'small'`/`'medium'`/`'large'` spellings of `s`/`m`/`l`; the two render identically. Governs\nthe gutter's and textarea's padding and font size, plus the editor frame's minimum block\nsize.\n\nType: `LyraSize`  \nDefault: `'m'`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}},{"name":"spellcheck","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"tab-size","description":"Spaces inserted per Tab keypress, and the rendered `tab-size`. Assigning it (or setting the\n`tab-size` attribute) pins both, overriding any `--lr-code-editor-tab-size` the host set;\nleaving it alone lets that token drive them instead. Confirmed-crash history: this used to\nfeed `' '.repeat(Math.max(1, this.tabSize))` directly in `onKeyDown` below --\n`String.prototype.repeat()` throws a `RangeError` for a count of `+Infinity` specifically\n(e.g. a literal `tab-size=\"Infinity\"` attribute, which `Number(\"Infinity\")` happily converts\nto), and `Math.max(1, NaN)` is itself `NaN`, silently producing an empty, non-indenting insert\nfor a NaN `tabSize`. Sanitized to a finite integer in `[1, 16]` at assignment time instead, so\nboth the `repeat()` call and the emitted tab-width style always see a safe value.\n\nType: `number`","value":{"type":["number"]}},{"name":"title","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"value","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"wrap","description":"Type: `LyraCodeEditorWrap`","value":{"type":["'hard'","'soft'","'off'"]}}],"slots":[{"name":"error","description":"Validation message."},{"name":"hint","description":"Supporting text."},{"name":"label","description":"Visible label content."}],"js":{"properties":[{"name":"accessibleLabel","description":"Attribute: `aria-label`","type":"string","default":"''"},{"name":"autocapitalize","description":"Attribute: `autocapitalize`","type":"string","default":"'off'"},{"name":"autocomplete","description":"Attribute: `autocomplete`","type":"string","default":"''"},{"name":"autocorrect","description":"Attribute: `autocorrect`","type":"boolean"},{"name":"autofocus","description":"Attribute: `autofocus`","type":"boolean","default":"false"},{"name":"cols","description":"Visible native column count. It also supplies the platform's hard-wrap submission width.\n\nAttribute: `cols`","type":"number","default":"20"},{"name":"customError","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nAttribute: `custom-error`  \nReflected to its attribute.","type":"string | null","default":"null"},{"name":"defaultValue","description":"Attribute: `value`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"disabled","description":"Attribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"enterKeyHint","description":"Attribute: `enterkeyhint`","type":"string","default":"''"},{"name":"enterkeyhint","type":"string"},{"name":"errorText","description":"Attribute: `error-text`","type":"string","default":"''"},{"name":"form","description":"Attribute: `form`  \nReflected to its attribute.","type":"HTMLFormElement | string | null","default":"null"},{"name":"hint","description":"Attribute: `hint`","type":"string","default":"''"},{"name":"input","description":"Direct access to the owned native textarea.","type":"HTMLTextAreaElement | null","read-only":true},{"name":"inputMode","description":"Attribute: `inputmode`","type":"string","default":"''"},{"name":"inputmode","type":"string"},{"name":"label","description":"Attribute: `label`","type":"string","default":"''"},{"name":"labels","type":"NodeList","read-only":true},{"name":"language","description":"Language identifier exposed as a reflected host styling hook.\n\nAttribute: `language`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"lineNumbers","description":"Attribute: `line-numbers`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"maxlength","description":"Attribute: `maxlength`","type":"number | undefined"},{"name":"minlength","description":"Attribute: `minlength`","type":"number | undefined"},{"name":"name","description":"Attribute: `name`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"placeholder","description":"Attribute: `placeholder`","type":"string","default":"''"},{"name":"readonly","description":"Attribute: `readonly`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"required","description":"Attribute: `required`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"resize","description":"Native CSS `resize` behavior. `auto` grows to content and scrolls at a consumer-supplied\n`max-block-size`; leaving `auto` clears that mode's inline size/overflow state. An invalid\nruntime value falls back to `'both'`.\n\nAttribute: `resize`  \nReflected to its attribute.","type":"LyraCodeEditorResize","default":"'both'"},{"name":"rows","description":"Attribute: `rows`","type":"number"},{"name":"selectionDirection","type":"'forward' | 'backward' | 'none' | null"},{"name":"selectionEnd","type":"number | null"},{"name":"selectionStart","type":"number | null"},{"name":"size","description":"Visual size on the library's one control ladder, shared with `<lr-textarea>`/`<lr-input>`/\n`<lr-select>`. Accepts both the canonical `'2xs'`–`'xl'` steps and Web Awesome's/Shoelace's\n`'small'`/`'medium'`/`'large'` spellings of `s`/`m`/`l`; the two render identically. Governs\nthe gutter's and textarea's padding and font size, plus the editor frame's minimum block\nsize.\n\nAttribute: `size`  \nReflected to its attribute.","type":"LyraSize","default":"'m'"},{"name":"spellcheck","description":"Attribute: `spellcheck`","type":"boolean","default":"false"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"tabSize","description":"Spaces inserted per Tab keypress, and the rendered `tab-size`. Assigning it (or setting the\n`tab-size` attribute) pins both, overriding any `--lr-code-editor-tab-size` the host set;\nleaving it alone lets that token drive them instead. Confirmed-crash history: this used to\nfeed `' '.repeat(Math.max(1, this.tabSize))` directly in `onKeyDown` below --\n`String.prototype.repeat()` throws a `RangeError` for a count of `+Infinity` specifically\n(e.g. a literal `tab-size=\"Infinity\"` attribute, which `Number(\"Infinity\")` happily converts\nto), and `Math.max(1, NaN)` is itself `NaN`, silently producing an empty, non-indenting insert\nfor a NaN `tabSize`. Sanitized to a finite integer in `[1, 16]` at assignment time instead, so\nboth the `repeat()` call and the emitted tab-width style always see a safe value.\n\nAttribute: `tab-size`","type":"number"},{"name":"title","description":"Attribute: `title`","type":"string","default":"''"},{"name":"validationMessage","type":"string","read-only":true},{"name":"validity","type":"ValidityState","read-only":true},{"name":"value","description":"The normalized live value. Native textarea line endings are always LF; the host, form state,\ngutter and selection APIs use that same representation.","type":"string"},{"name":"willValidate","type":"boolean","read-only":true},{"name":"wrap","description":"Attribute: `wrap`","type":"LyraCodeEditorWrap"}],"events":[{"name":"blur","description":"Realm-correct native `FocusEvent` relayed from the textarea with `relatedTarget`.","type":"FocusEvent"},{"name":"change","description":"Realm-correct native commit `Event`, relayed once.","type":"Event"},{"name":"focus","description":"Realm-correct native `FocusEvent` relayed from the textarea with `relatedTarget`.","type":"FocusEvent"},{"name":"input","description":"Realm-correct native `InputEvent` relayed once when the user edits the code.","type":"InputEvent"},{"name":"lr-change","description":"Lyra commit alias; detail is `{ value }`.","type":"CustomEvent<{ value: string }>"},{"name":"lr-input","description":"Lyra value alias; detail is `{ value }`.","type":"CustomEvent<{ value: string }>"},{"name":"lr-invalid","description":"The editor failed a validity check. Cancelable: `preventDefault()` forwards to the native `invalid` event, suppressing the browser's own validation bubble and the focus/scroll `reportValidity()` would otherwise perform.","type":"CustomEvent<null>"}]}},{"name":"lr-color-picker","description":"`<lr-color-picker>` — a form-associated colour picker: a compact swatch trigger that opens a\npopover with a saturation/brightness grid, a hue slider, an optional alpha slider, a text field\naccepting any parseable CSS colour, an optional predefined palette, and — where the browser\nsupports it — a screen eyedropper.\n\n`value` is always serialized in the active `format` (`hex` by default), so reading it back after\nany interaction gives a canonical string in exactly one syntax; switching `format`, `opacity`, or\n`uppercase` re-serializes the same colour rather than reinterpreting it. Input is far more\npermissive than output: hex (3/4/6/8 digit), `rgb()`/`rgba()`, `hsl()`/`hsla()`,\n`hsv()`/`hsva()`, CSS colour names, and any other colour syntax the browser itself parses are all\naccepted. A value that is not a colour at all is kept verbatim rather than being silently\nreplaced, so a consumer's own sentinel survives a round trip.\n\nColour is never the only channel carrying state: the trigger is described by the current value in\ntext, the panel shows it in an editable field, and the selected palette swatch is marked with\n`aria-pressed` plus a check mark rather than a tint alone.\nPointer drags are reversible previews: a release commits the latest colour, while cancellation,\nlost capture, disablement, disconnection, or document adoption silently restores the colour and\nsubmitted form value that existed before the gesture.\nOwn or fieldset disablement discards an unfinished text draft without committing it and blocks\npalette/format actions immediately. An enabled text-field blur still commits a valid draft;\nchanging format remains silent. Host-root external descriptions precede local trigger guidance\nand follow source replacement, removal, reinsertion, reconnection and document adoption.\nThe popup participates in the shared nonmodal overlay stack, so Escape and an outside pointer\ndismiss it only while it is topmost; closing a newer overlay hands focus back through the\nmanager instead of collapsing every open popup under the same event.\n\nA `swatches` entry may also set `disabled`, marking that one palette swatch non-actionable\nindependent of the whole control's own `disabled`: it renders a genuinely disabled `<button>`\n(no tab stop, no hover/press affordance) and clicking it commits nothing. Omitted or `false`\nrenders the swatch exactly as before this field existed.\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| `error` | Custom validation-error content. |\n| `hint` | Supporting text. |\n| `label` | Custom label content. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | Permanent compatibility name on the same field wrapper as `color-picker`. |\n| `color-picker` | The field wrapper. It is the same node as `base` and `form-control`. |\n| `error` | The validation message. |\n| `eye-dropper-button` | Shoelace alias for `eyedropper-button`. |\n| `eye-dropper-button__base` | Shoelace alias for the eyedropper button's base. |\n| `eye-dropper-button__caret` | Shoelace alias for `eyedropper-button__caret`. |\n| `eye-dropper-button__label` | Shoelace alias for `eyedropper-button__label`. |\n| `eye-dropper-button__prefix` | Shoelace alias for `eyedropper-button__start`. |\n| `eye-dropper-button__suffix` | Shoelace alias for `eyedropper-button__end`. |\n| `eyedropper-button` | The screen-eyedropper button, rendered only where the EyeDropper API exists. |\n| `eyedropper-button__base` | Web Awesome alias for the eyedropper button's base. |\n| `eyedropper-button__caret` | Reserved caret container. |\n| `eyedropper-button__end` | Web Awesome end-adornment container. |\n| `eyedropper-button__label` | The localized, visually hidden button label. |\n| `eyedropper-button__start` | Web Awesome start-adornment container. |\n| `form-control` | The field wrapper. It is the same node as `base` and `color-picker`. |\n| `form-control-label` | The label. It also carries the `label` compatibility name. |\n| `format-button` | The format-cycling button. |\n| `format-button__base` | Alias for the format button's interactive base. |\n| `format-button__caret` | Reserved caret container. |\n| `format-button__end` | Web Awesome end-adornment container. |\n| `format-button__label` | The visible format abbreviation. |\n| `format-button__prefix` | Shoelace alias for `format-button__start`. |\n| `format-button__start` | Web Awesome start-adornment container. |\n| `format-button__suffix` | Shoelace alias for `format-button__end`. |\n| `grid` | The saturation/brightness grid. |\n| `grid-handle` | The grid's draggable, keyboard-operable handle. |\n| `hint` | Supporting text. |\n| `hue-slider` | The hue slider. Also carries the `slider` token. |\n| `hue-slider-handle` | The hue slider's handle. Also carries the `slider-handle` token. |\n| `input` | The text field holding the serialized value. |\n| `label` | Permanent compatibility name on the same label as `form-control-label`. |\n| `opacity-slider` | The opacity slider, rendered only when `opacity` is set. Also carries the `slider` token. |\n| `opacity-slider-handle` | The opacity slider's handle. Also carries the `slider-handle` token. |\n| `panel` | The positioned popover surface. |\n| `preview` | The current-colour preview beside the sliders. |\n| `slider` | Both the hue and opacity sliders. |\n| `slider-handle` | Both slider handles. |\n| `swatch` | A single palette swatch. The active one is `[part~='swatch-selected']`. Renders a genuine `disabled` `<button>` while that swatch's own entry sets `disabled`. |\n| `swatch-selected` | Token added to the swatch matching the current value. |\n| `swatches` | The predefined-palette container, rendered only when `swatches` is non-empty. |\n| `trigger` | The swatch button that opens the panel. |\n| `trigger-container` | The row wrapping the trigger. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-color-picker-swatch-size` (default: `var(--lr-form-control-height,var(--lr-size-2-5rem))`) — The centered visible swatch's inline and block size. The interactive trigger stays at least `--lr-icon-button-size`; larger swatch tiers expand it. The value reads the shared form-control height ladder, so the visible swatch follows neighbouring field density.\n- `--lr-color-picker-gap` (default: `var(--lr-space-xs)`) — Gap between field chrome and panel rows.\n- `--lr-color-picker-radius` (default: `var(--lr-radius)`) — Trigger, grid, and panel corner radius.\n- `--lr-color-picker-border-color` (default: `var(--lr-color-border)`) — Resting trigger border color.\n- `--lr-color-picker-hover-border-color` (default: `var(--lr-color-brand)`) — Hover border color.\n- `--lr-color-picker-selected-border` (default: `var(--lr-color-brand)`) — Border of the selected palette swatch.\n- `--lr-color-picker-selected-check-color` (default: `var(--lr-color-surface)`) — Checkmark color on the selected palette swatch.\n- `--lr-color-picker-grid-inline-size` (default: `var(--lr-size-15rem)`) — Saturation/brightness grid width.\n- `--lr-color-picker-grid-block-size` (default: `var(--lr-size-8rem)`) — Saturation/brightness grid height.\n- `--lr-color-picker-grid-handle-size` (default: `var(--lr-size-1rem)`) — Diameter of the grid handle.\n- `--lr-color-picker-slider-block-size` (default: `var(--lr-size-0-75rem)`) — Thickness of the visible hue/opacity ramp. The slider's own pointer target stays floored at 24px regardless.\n- `--lr-color-picker-slider-handle-size` (default: `var(--lr-size-1-25rem)`) — Diameter of a slider handle.\n- `--lr-color-picker-palette-swatch-size` (default: `var(--lr-size-1-5rem)`) — Size of a palette swatch.\n- `--lr-color-picker-swatch-disabled-opacity` (default: `0.5`) — Opacity of a palette swatch whose own entry sets `disabled`.\n- `--grid-width` — Upstream alias for `--lr-color-picker-grid-inline-size`.\n- `--grid-height` — Upstream alias for `--lr-color-picker-grid-block-size`.\n- `--grid-handle-size` — Upstream alias for `--lr-color-picker-grid-handle-size`.\n- `--slider-height` — Upstream alias for `--lr-color-picker-slider-block-size`.\n- `--slider-handle-size` — Upstream alias for `--lr-color-picker-slider-handle-size`.\n- `--swatch-size` — Shoelace alias for `--lr-color-picker-palette-swatch-size`.\n- `--lr-color-picker-checker-color` (default: `var(--lr-color-border)`) — Tint of the alpha checkerboard.\n- `--lr-color-picker-checker-size` (default: `var(--lr-size-0-5rem)`) — Cell size of the alpha checkerboard.\n- `--lr-color-picker-hue-stops` — The hue ramp's own gradient stops, shared by the hue slider in both text directions. Defaults to the six-stop sRGB hue wheel.\n- `--lr-color-picker-swatch-color` — The live colour painted on the trigger, preview, slider handles, and palette swatches. Rewritten on every render, so it reports state rather than accepting configuration.\n- `--lr-color-picker-grid-hue` — The saturation/brightness grid's fully-saturated base hue. Rewritten on every render, like `--lr-color-picker-swatch-color`.\n- `--lr-color-picker-opacity-gradient` — The opacity slider's transparent-to-opaque ramp, built from the current colour and text direction. Rewritten on every render.\n- `--lr-form-control-required-content` (default: `' *'`) — The required-field marker rendered after the label. Set it to `''` to suppress the marker, or to any other quoted string (`' (required)'`, a localized word) to replace it. Caller-supplied content, so it is never localized here.\n- `--lr-form-control-required-color` (default: `var(--lr-color-danger)`) — Color of that marker, retunable without touching any other danger-coloured surface.\n- `--lr-form-control-required-offset` (default: `0`) — Inline space between the label text and the marker.\n- `--lr-overlay-surface` (default: `var(--lr-color-surface-overlay)`) — Shared floating-surface fill, on the picker panel.\n- `--lr-overlay-border` (default: `var(--lr-color-border)`) — Shared floating-surface edge colour, on the picker panel.\n- `--lr-overlay-radius` (default: `var(--lr-radius)`) — Shared floating-surface corner radius, read by the picker panel only as the middle arm of `--lr-color-picker-radius`, which still wins when set.\n- `--lr-overlay-shadow-anchored` (default: `var(--lr-shadow-m)`) — Elevation of the anchored surface.\n- `--lr-positioning-strategy` — Cascading `absolute`/`fixed` override for {@link positioningStrategy}/`hoist`, read from computed style when the panel is (re)positioned. Set it once on `:root`, a theme, or one clipping ancestor to change every unset color picker beneath it instead of authoring `positioning-strategy`/`hoist` on each instance; an explicit value on the instance always wins over it.","attributes":[{"name":"aria-label","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"custom-error","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nType: `string | null`  \nDefault: `null`"},{"name":"disabled","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"error-text","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"form","description":"Type: `HTMLFormElement | string | null`  \nDefault: `null`"},{"name":"format","description":"Output format for `value`. Input is always parsed permissively regardless of this.\n\nType: `LyraColorPickerFormat`  \nDefault: `'hex'`","value":{"type":["'hex'","'rgb'","'hsl'","'hsv'"]}},{"name":"hint","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"hoist","description":"Retained boolean alias of positioningStrategy: `hoist` is exactly\n`positioningStrategy === 'fixed'`, and writing either spelling updates the other so the two\nattributes can never disagree in the DOM. It is this control's established name (and\nShoelace's own spelling on `sl-color-picker`), so it keeps working indefinitely; prefer\n`positioning-strategy` in new code, which reads the same on every anchored surface.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"inline","description":"Renders the full picker panel in normal flow instead of behind a popup trigger.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"label","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"name","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"no-format-toggle","description":"Shoelace spelling for `withoutFormatToggle`; either property removes the same button.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"opacity","description":"Enables the alpha channel: an opacity slider, and an alpha-carrying serialized value.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"open","description":"Whether the popup panel is open. The panel remains visible in `inline` mode.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"placement","description":"Preferred panel placement; the resolved side still flips to stay in the viewport.\n\nType: `Placement`  \nDefault: `'bottom-start'`","value":{"type":["'top'","'top-start'","'top-end'","'right'","'right-start'","'right-end'","'bottom'","'bottom-start'","'bottom-end'","'left'","'left-start'","'left-end'"]}},{"name":"positioning-strategy","description":"CSS positioning scheme the popup panel is laid out with -- the same property, spelled the same\nway, as on `<lr-popover>`, `<lr-dropdown>` and `<lr-select>`. `absolute` (this control's\nmirrored default) keeps the panel in the component's local scrolling context; `fixed` escapes\nmost clipping ancestors. An unsupported value resolves back to the default. Changes apply live\nwhile open.\nThis property reports only the instance's own authored value (or the mirrored default); the\npanel is actually placed with the `--lr-positioning-strategy` cascading custom property\nhonored ahead of that default when the instance itself sets nothing -- see that `@cssprop`.\n\nType: `PlaceStrategy`  \nDefault: `'absolute'`","value":{"type":["'absolute'","'fixed'"]}},{"name":"required","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"size","description":"Visible-swatch size — the library-wide `2xs`–`xl` ladder shared with `lr-input`/`lr-select`.\nThe interactive trigger retains the shared `--lr-icon-button-size` minimum target even when\nthe visible swatch is denser. The Web Awesome / Shoelace spellings `small`/`medium`/`large`\nare accepted for `s`/`m`/`l`, so a migration is a tag rename with no attribute rewrite.\n\nType: `LyraSize`  \nDefault: `'m'`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}},{"name":"swatches","description":"Predefined palette. A `;`-separated string, an array of colour strings, or an array of\n`{ color, label }` objects. Every colour the picker can parse is accepted. A blank object\nlabel is treated as absent so the localized raw-colour accessible-name fallback remains.\n\nType: `string | string[] | LyraColorPickerSwatch[]`  \nDefault: `''`"},{"name":"uppercase","description":"Serializes `value` in upper case (`#FF0000` rather than `#ff0000`).\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"value","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"with-hint","description":"Server-rendering hint that the `hint` slot is populated before client slot observation.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"with-label","description":"Server-rendering hint that the `label` slot is populated before client slot observation.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"without-format-toggle","description":"Removes the button that cycles between formats.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"error","description":"Custom validation-error content."},{"name":"hint","description":"Supporting text."},{"name":"label","description":"Custom label content."}],"js":{"properties":[{"name":"accessibleLabel","description":"Attribute: `aria-label`","type":"string","default":"''"},{"name":"customError","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nAttribute: `custom-error`  \nReflected to its attribute.","type":"string | null","default":"null"},{"name":"defaultValue","description":"Attribute: `value`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"disabled","description":"Attribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"errorText","description":"Attribute: `error-text`","type":"string","default":"''"},{"name":"form","description":"Attribute: `form`  \nReflected to its attribute.","type":"HTMLFormElement | string | null","default":"null"},{"name":"format","description":"Output format for `value`. Input is always parsed permissively regardless of this.\n\nAttribute: `format`","type":"LyraColorPickerFormat","default":"'hex'"},{"name":"hint","description":"Attribute: `hint`","type":"string","default":"''"},{"name":"hoist","description":"Retained boolean alias of positioningStrategy: `hoist` is exactly\n`positioningStrategy === 'fixed'`, and writing either spelling updates the other so the two\nattributes can never disagree in the DOM. It is this control's established name (and\nShoelace's own spelling on `sl-color-picker`), so it keeps working indefinitely; prefer\n`positioning-strategy` in new code, which reads the same on every anchored surface.\n\nAttribute: `hoist`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"inline","description":"Renders the full picker panel in normal flow instead of behind a popup trigger.\n\nAttribute: `inline`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"label","description":"Attribute: `label`","type":"string","default":"''"},{"name":"labels","type":"NodeList","read-only":true},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"name","description":"Attribute: `name`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"noFormatToggle","description":"Shoelace spelling for `withoutFormatToggle`; either property removes the same button.\n\nAttribute: `no-format-toggle`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"opacity","description":"Enables the alpha channel: an opacity slider, and an alpha-carrying serialized value.\n\nAttribute: `opacity`","type":"boolean","default":"false"},{"name":"open","description":"Whether the popup panel is open. The panel remains visible in `inline` mode.\n\nAttribute: `open`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"placement","description":"Preferred panel placement; the resolved side still flips to stay in the viewport.\n\nAttribute: `placement`  \nReflected to its attribute.","type":"Placement","default":"'bottom-start'"},{"name":"positioningStrategy","description":"CSS positioning scheme the popup panel is laid out with -- the same property, spelled the same\nway, as on `<lr-popover>`, `<lr-dropdown>` and `<lr-select>`. `absolute` (this control's\nmirrored default) keeps the panel in the component's local scrolling context; `fixed` escapes\nmost clipping ancestors. An unsupported value resolves back to the default. Changes apply live\nwhile open.\nThis property reports only the instance's own authored value (or the mirrored default); the\npanel is actually placed with the `--lr-positioning-strategy` cascading custom property\nhonored ahead of that default when the instance itself sets nothing -- see that `@cssprop`.\n\nAttribute: `positioning-strategy`  \nReflected to its attribute.","type":"PlaceStrategy","default":"'absolute'"},{"name":"required","description":"Attribute: `required`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"size","description":"Visible-swatch size — the library-wide `2xs`–`xl` ladder shared with `lr-input`/`lr-select`.\nThe interactive trigger retains the shared `--lr-icon-button-size` minimum target even when\nthe visible swatch is denser. The Web Awesome / Shoelace spellings `small`/`medium`/`large`\nare accepted for `s`/`m`/`l`, so a migration is a tag rename with no attribute rewrite.\n\nAttribute: `size`  \nReflected to its attribute.","type":"LyraSize","default":"'m'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"swatches","description":"Predefined palette. A `;`-separated string, an array of colour strings, or an array of\n`{ color, label }` objects. Every colour the picker can parse is accepted. A blank object\nlabel is treated as absent so the localized raw-colour accessible-name fallback remains.\n\nAttribute: `swatches`","type":"string | string[] | LyraColorPickerSwatch[]","default":"''"},{"name":"uppercase","description":"Serializes `value` in upper case (`#FF0000` rather than `#ff0000`).\n\nAttribute: `uppercase`","type":"boolean","default":"false"},{"name":"validationMessage","type":"string","read-only":true},{"name":"validity","type":"ValidityState","read-only":true},{"name":"value","type":"string"},{"name":"willValidate","type":"boolean","read-only":true},{"name":"withHint","description":"Server-rendering hint that the `hint` slot is populated before client slot observation.\n\nAttribute: `with-hint`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"withLabel","description":"Server-rendering hint that the `label` slot is populated before client slot observation.\n\nAttribute: `with-label`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"withoutFormatToggle","description":"Removes the button that cycles between formats.\n\nAttribute: `without-format-toggle`","type":"boolean","default":"false"}],"events":[{"name":"blur","description":"Native-constructor relay when focus leaves the internal controls.","type":"FocusEvent"},{"name":"change","description":"Native-style composed event, fired once an interaction commits (pointer release, key release, swatch click, text entry, eyedropper result).","type":"Event"},{"name":"focus","description":"Native-constructor relay when focus enters an internal control; bubbling and composed across the shadow boundary.","type":"FocusEvent"},{"name":"input","description":"Native-style composed event, fired for every colour preview during an interaction. Canceling a pointer gesture silently restores its pre-gesture value without another event.","type":"InputEvent"},{"name":"lr-after-hide","description":"The colour panel finished closing; follows `lr-hide` in the same update.","type":"CustomEvent<null>"},{"name":"lr-after-show","description":"The colour panel finished opening. There is no animated delay, so it follows `lr-show` in the same completed update.","type":"CustomEvent<null>"},{"name":"lr-change","description":"Shoelace-compatible commit alias carrying the newly serialized value; emitted alongside the native `change` event.","type":"CustomEvent<{ value: string }>"},{"name":"lr-hide","description":"The colour panel is about to close. Cancelable on the same terms as `lr-show`.","type":"CustomEvent<null>"},{"name":"lr-input","description":"Shoelace-compatible edit alias, emitted alongside each native `input` event.","type":"CustomEvent<null>"},{"name":"lr-invalid","description":"The color picker failed a validity check; cancelable. Calling `preventDefault()` also cancels the native `invalid` event it aliases, suppressing the browser's own validation bubble and `reportValidity()`'s focus/scroll.","type":"CustomEvent<null>"},{"name":"lr-show","description":"The colour panel is about to open, however `open` became true. Cancelable — `preventDefault()` leaves it closed. Initial markup, disconnect cleanup, and a close forced by disablement apply without emitting this request event.","type":"CustomEvent<null>"}]}},{"name":"lr-combobox","description":"`<lr-combobox>` — a filterable single/multi select that combines a text\ninput with a listbox. Mirrors the core `<wa-combobox>` API under `lr-`.\n\nOptions are `<lr-option value>` children. Emits native-style `change`/`input`\n(like Web Awesome) plus `lr-show`/`lr-hide`/`lr-clear`.\nEnter commits the highlighted option while the listbox has one; with nothing highlighted it\nperforms the implicit form submission a native text field would (see\n`internal/submit-on-enter.ts` — the internal input is in a shadow root and has no form owner, so\nthe platform can never do it here).\nStandard size tiers share their outer control height with sibling Lyra controls; the decorative\nexpand icon scales inside that allocation without creating an independent action target.\nIf local options or async rows change while a row is keyboard-active, the active descendant\nclamps to the nearest enabled survivor and clears when none remain.\nAn async `source` failure renders as a disabled listbox row, not a shadow-root live region; each\ncurrent post-mount rejection appends the localized `comboboxLoadError` message to the shared\nlight-DOM assertive announcement sink. Raw caught error text is never exposed to users.\nThe floating listbox is a nonmodal shared-overlay-manager entry. Visual stack order, Escape,\noutside-pointer dismissal, and focus handoff are therefore owned by only the newest Lyra\noverlay, including when another popup such as `lr-color-picker` remains open underneath it.\nThe editable combobox input exposes explicit stateful `aria-invalid`: visible error chrome wins\nimmediately, while intrinsic/custom invalidity is exposed only after interaction.\n\nHost `aria-describedby` targets supplement internal hint/error guidance on the semantic\ncontrol, including live target replacement and document adoption. Removing label, hint, or\nerror attributes safely omits their content while retaining native null property readback.\nMounted option `selected` writes immediately update the live value and submission silently;\nreset defaults stay independent, and later default changes preserve a dirty selection.\n\nComposing keys stay with text editing. Inert source options and their inert ancestors are\nunavailable through popup rows; named option adornment mutations refresh their presentation.\nSingle mode exposes one selected occurrence while retaining backing multiple-selection history.\n\nAssigning `undefined`/`null` to `value` clears the selection; every string, including `''`, is\ninstead a candidate value resolved against the current local options/async rows -- an\n`<lr-option value=\"\">` (or a matching row) is legitimate and now round-trips like any other. A\ncommitted value matching no current option/row (a stale value, or a programmatic assignment with\na typo) still commits rather than being dropped, but renders with a dashed/italic\n`[part='unknown-value']` badge instead of silently passing the raw string off as an ordinary\nlabel -- see `isUnknownValue()`. Suppressed while an async `source` fetch has never yet resolved\nfor this element, and never shown for an `allowCustomValue` commit, which is a sanctioned\nunmatched value, not a stale one. Over that same unresolved window the raw value itself is\nwithheld too -- the trigger (and any `multiple`-mode tag for the same value) shows the\n`loadingText` placeholder instead of the raw string, since it is not yet knowable whether the\nvalue is even unmatched.\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-option>` elements. |\n| `clear-icon` | Replaces the clear button's built-in icon. |\n| `end` | Adornment after the filter input and the built-in clear action, and before the expand icon — so consumer content never sits outboard of the dropdown chevron. |\n| `error` | Custom error content. |\n| `expand-icon` | Replaces the dropdown indicator's built-in icon. |\n| `hint` | Custom hint content. |\n| `label` | Custom label content. |\n| `source-error` | Replaces the built-in failed-`source` state, retry control included. Named apart from the form-control `error` slot deliberately: they are different failures and a control has to be able to show both. |\n| `start` | Adornment at the inline-start of the trigger row, before the selected-value tags and the filter input. Slotted content is decorative chrome, not an option: `collectOptions()` only ever collects `<lr-option>` elements from the default slot. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `clear-button` | The clear button. |\n| `combobox` | The input container (positioning anchor). |\n| `combobox-input` | The text input. |\n| `end` | Wrapper around the `end` adornment slot; `hidden` while nothing is slotted. |\n| `error` | Ordinary form-validation text referenced by the internal input; it is not a live region, avoiding a second announcement alongside native validation/focus feedback. |\n| `expand-icon` | The dropdown indicator. |\n| `form-control` | The outer wrapper around label, combobox, listbox, error and hint. |\n| `form-control-input` | Compatibility wrapper around the editable control. |\n| `form-control-label` | The `<label>` element. |\n| `group-label` | The heading of an option group (rows sharing a `group`), named as on `lr-select` and `lr-emoji-picker` so one rule can style every grouped list. |\n| `hint` | The hint message. |\n| `label` | Compatibility wrapper around the visible label content. |\n| `listbox` | The managed nonmodal options popover; its stack depth comes from `--lr-overlay-stack-index` with `--lr-layer-dropdown` as the standalone fallback. |\n| `option` | An option row. |\n| `option-badge` | An async option row's optional trailing metadata badge, and the localized \"not in catalog\" badge on a synthetic unmatched-value row (`show-unknown-option`). |\n| `option-dot` | An option row's leading status dot (when `dot-color` is set). |\n| `option-end` | An option row's trailing adornment, cloned from the source `<lr-option>`'s `end`/`suffix` slot (or an async row's `end`). Inert and aria-hidden. |\n| `option-icon` | An async option row's optional decorative leading visual. Its rendered subtree remains visible but is inert and hidden from assistive technology. |\n| `option-label` | An option row's label/sub wrapper. |\n| `option-overflow` | The \"+N more\" indicator shown when rows are capped by `maxRender`. |\n| `option-start` | An option row's leading adornment, cloned from the source `<lr-option>`'s `start`/`prefix` slot (or an async row's `start`). Inert and aria-hidden. |\n| `option-sub` | An option row's secondary line (when `sub` is set). |\n| `retry-button` | The retry control inside the failed-load state. |\n| `source-error` | The shared failed-load state itself, with `source-error-base`, `source-error-icon`, `source-error-heading`, `source-error-description` and `source-error-actions` forwarded from the composed `<lr-empty>`. |\n| `source-error-row` | The listbox row holding the failed-`source` state. |\n| `start` | Wrapper around the `start` adornment slot; `hidden` while nothing is slotted. |\n| `tag` | An individual selected tag. |\n| `tag-label` | The wrapping/ellipsis-safe selected-tag label. |\n| `tag__content` | Compatibility wrapper around a selected tag's visible content. |\n| `tag__remove-button` | A tag's remove button. |\n| `tag__remove-button__base` | Compatibility name on a tag's remove button. |\n| `tags` | The multi-select tag container. |\n| `unknown-value` | Badge shown next to the closed single-select input, or a `multiple`-mode tag, when the committed value matches no current option/row (see `isUnknownValue()`). |\n\n---\n\n**CSS Custom Properties**\n\n- `--hide-duration` (default: `var(--lr-transition-fast)`) — Listbox exit-transition duration.\n- `--lr-combobox-border-color` (default: `var(--lr-color-border)`) — Resting border color of the trigger row, `transparent` by default on the `filled` treatment.\n- `--lr-combobox-expand-size` — Decorative expand-icon box size, scaled by `size`.\n- `--lr-combobox-fill` (default: `var(--lr-color-surface)`) — Resting background of the trigger row. The `filled`/`filled-outlined` treatments default it to `--lr-color-surface-raised`; a value set here wins over every treatment.\n- `--lr-combobox-font-size` (default: `var(--lr-form-control-font-size)`) — Input text size, from the shared form-control size ladder.\n- `--lr-combobox-gap` (default: `var(--lr-space-xs)`) — Gap between the start/end adornments, tags, and filter input inside the trigger row. Unlike the size knobs above it does not vary by `size` tier. Override it to retune without a `::part(combobox)` rule.\n- `--lr-combobox-open-border-color` (default: `var(--lr-color-brand)`) — Border color of the trigger row while it holds focus — the state the listbox opens in. Bound to `:focus-within` rather than to `open`, so it paints on a focused row whose listbox is closed too; the name is symmetric with `lr-select`'s `--lr-select-open-border-color`, which is gated on `open` itself.\n- `--lr-combobox-option-active-bg` (default: `var(--lr-color-brand-quiet)`) — Background of a hovered or keyboard-active option row.\n- `--lr-combobox-option-badge-bg` (default: `var(--lr-color-brand-quiet)`) — Background of the `[part='option-badge']` trailing metadata badge, and the \"not in catalog\" badge on a synthetic unmatched-value row (`show-unknown-option`).\n- `--lr-combobox-option-selected-bg` (default: `transparent`) — Background of the currently-selected option row. Not declared on `:host`; retheme without hijacking `--lr-color-brand`.\n- `--lr-combobox-option-selected-border` (default: `var(--lr-color-brand)`) — Border color of the selected option row.\n- `--lr-combobox-option-selected-color` (default: `var(--lr-color-brand)`) — Text color of the selected option row.\n- `--lr-combobox-option-selected-font-weight` (default: `var(--lr-font-weight-semibold)`) — Font weight of the selected option row.\n- `--lr-combobox-radius` (default: `var(--lr-radius)`) — Corner radius of the trigger row (`[part='combobox']`). Does not vary by `size` tier; the `pill` attribute swaps it for `--lr-radius-pill`.\n- `--lr-combobox-tag-font-size` — Selected-tag text size.\n- `--lr-combobox-tag-padding` — Selected-tag padding.\n- `--lr-combobox-trigger-height` — Exact input-container height. Unset by default, which leaves `--lr-combobox-trigger-min-height` as a floor only; set it to a length to both floor and cap the row (e.g. to pixel-match `<lr-input>`/`<lr-select>` in the same toolbar). Because it is never declared by the component itself, it can be set from an ancestor or an outer-tree rule as well as inline on the element. Intended for a single-row combobox: in `multiple` mode a tag row long enough to wrap overflows the pinned box visibly (nothing is clipped or made unreachable), so leave it unset there.\n- `--lr-combobox-trigger-min-height` (default: `var(--lr-form-control-height)`) — Minimum input-container block size. Reads the shared form-control height ladder, so retuning `--lr-theme-form-control-height-*` moves this control and every sibling field together.\n- `--lr-combobox-trigger-padding` — Padding inside the input container.\n- `--lr-combobox-unknown-value-border-color` (default: `var(--lr-color-border)`) — Border color of the same unknown-value tag.\n- `--lr-combobox-unknown-value-border-style` (default: `dashed`) — Border style of a `multiple`-mode tag whose committed value matches no current option/row.\n- `--lr-form-control-focus-shadow` (default: `none`) — The shared field focus halo, painted as a `box-shadow` while this control is focused. One name for every field-shaped control in the library, so a halo is configured once rather than per component. Additive: the focus outline and border cue are the accessibility answer to focus and are never replaced by it.\n- `--lr-form-control-required-color` (default: `var(--lr-color-danger)`) — Required-marker color, themeable independently of error text and invalid borders.\n- `--lr-form-control-required-content` (default: `' *'`) — The required marker appended to `form-control-label` while `required` is set. Set it to `''` to suppress the marker, or to any other quoted string (`' (required)'`, a localized word) to replace it.\n- `--lr-form-control-required-offset` (default: `0`) — Inline space between the label text and the required marker.\n- `--lr-overlay-border` (default: `var(--lr-color-border)`) — Shared floating-surface edge colour, on the listbox popup.\n- `--lr-overlay-radius` (default: `var(--lr-radius)`) — Shared floating-surface corner radius, on the listbox popup.\n- `--lr-overlay-shadow-anchored` (default: `var(--lr-shadow-m)`) — Elevation of the anchored listbox popup.\n- `--lr-overlay-surface` (default: `var(--lr-color-surface-overlay)`) — Shared floating-surface fill, on the listbox popup. This is the public arm the popup never had: retinting it no longer means retinting the page surface every card and input reads.\n- `--lr-positioning-strategy` — Cascading `absolute`/`fixed` override for {@link positioningStrategy}, read from computed style when the listbox is positioned. Set it once on `:root`, a theme, or one clipping ancestor to change every unset combobox beneath it instead of authoring `positioning-strategy` on each instance; an explicit value on the instance always wins over it.\n- `--show-duration` (default: `var(--lr-transition-fast)`) — Listbox enter-transition duration.\n- `--tag-max-size` (default: `var(--lr-size-5rem)`) — Maximum inline size of a built-in selected tag.","attributes":[{"name":"allow-create","description":"Allows a nonmatching query to be created as a new option through the cancelable `lr-create`\nveto point. The default action appends and selects an `<lr-option>`.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"allow-custom-value","description":"Lets a single-select combobox commit arbitrary text without adding an option.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"appearance","description":"Visual treatment shared with other Lyra form controls.\n\nType: `'filled' | 'outlined' | 'filled-outlined'`  \nDefault: `'outlined'`","value":{"type":["'filled'","'outlined'","'filled-outlined'"]}},{"name":"autocapitalize","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"autocomplete","description":"Native editing-assistance attributes forwarded to the wrapped input.\n\nType: `string`  \nDefault: `'off'`","value":{"type":["string"]}},{"name":"autocorrect","description":"Web Awesome's boolean `autocorrect` IDL; its HTML attribute uses `on`/`off`.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"clearable","description":"Show a clear button while the combobox has something to clear on either axis: a committed\nselection, or visible filter text (the open listbox in single-select, any time in `multiple`\nmode — a closed single-select shows the selected label, not the query, so a stale query alone\nnever surfaces the button). Clearing a selection emits `input`/`change`/`lr-clear`; clearing\nfilter text emits `lr-filter` with an empty `value`; each fires only for the axis that\nactually changed. Named after Shoelace's `clearable`; Web Awesome spells the same idea\n`with-clear`, which is accepted as an alias so either migration keeps working.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"custom-error","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nType: `string | null`"},{"name":"disabled","description":"Disables every interactive sub-control.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"empty-text","description":"Optional no-match copy override. Omission localizes `noMatches`; a supplied string, including\n`\"No matches\"` or `\"\"`, renders verbatim.\n\nType: `string | undefined`"},{"name":"enterkeyhint","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"error-text","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"form","description":"Type: `HTMLFormElement | string | null`  \nDefault: `null`"},{"name":"hint","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"inputmode","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"label","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"loading-text","description":"Optional loading-copy override. Omission localizes `loading`; a supplied string, including\n`\"Loading…\"` or `\"\"`, renders verbatim. Shown both in the listbox's own loading row and, for a\ncommitted value a `source` fetch has never resolved (see `labelFor()`), in place of the raw\nvalue on the trigger/tags -- the same key covers both spots.\n\nType: `string | undefined`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max-options-visible","description":"Maximum number of selected-value **tags** shown before the rest collapse behind a \"+N\" tag\n(multi-select only). Sanitized to a finite, non-negative integer.\n\nNot to be confused with the two caps on the suggestion list: `visibleOptions` bounds how many\nsuggestion rows are visible at once, and `maxRender` bounds how many are rendered at all.\nThis one only ever concerns the tags for values already chosen.\n\nType: `number`  \nDefault: `3`","value":{"type":["number"]}},{"name":"max-render","description":"Maximum number of suggestion rows **rendered into the DOM at all** before the rest collapse\nbehind the overflow indicator (the current selection is always kept visible regardless). This\nis a performance ceiling, not a visible-height affordance: rows past it do not exist and\ncannot be scrolled to. Use `visibleOptions` to bound the popup's height while keeping every\nrow reachable, and `maxOptionsVisible` for the selected-tag cap. Sanitized to a finite,\nnon-negative integer capped at 1,000.\n\nRows render in full rather than as a recycled scroll window, because the filter input's\n`aria-activedescendant` is an IDREF and can only resolve within its own tree scope — rows\nhosted inside a nested windowing element would sit one shadow root deeper than the input\nthat must point at them. Raising this to cover a few-hundred-entry list (countries,\ncurrencies, time zones) is the intended use; past roughly a thousand rows, `source` narrows\nthe set before it becomes DOM and is the better tool.\n\nType: `number`","value":{"type":["number"]}},{"name":"multiple","description":"Enables multiple selection.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"name","description":"Submitted field name.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"open","description":"Whether the listbox is open. Effectively disabled controls reject direct reopen attempts,\nincluding a synchronous fieldset cascade.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"overflow-text","description":"Optional capped-list copy override. Omission localizes `comboboxOverflow`; a supplied string,\nincluding the built-in English template or `\"\"`, wins verbatim after `{n}` interpolation.\n\nType: `string | undefined`"},{"name":"pill","description":"Rounds the trigger row's corners to a full pill, mirroring `lr-input`'s own `pill`. It is a\nsingle override of `--lr-combobox-radius`, so a consumer setting that property directly still\nwins for a bespoke shape.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"placeholder","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"placement","description":"Preferred vertical side for the floating listbox.\n\nType: `LyraComboboxPlacement`  \nDefault: `'bottom'`","value":{"type":["'top'","'bottom'"]}},{"name":"positioning-strategy","description":"CSS positioning scheme the listbox is laid out with -- the property `<lr-select>`,\n`<lr-popover>`, `<lr-dropdown>`, `<lr-tooltip>` and `<lr-color-picker>` all spell the same way.\n`fixed` (this control's default, and what it has always rendered) positions against the\nviewport and escapes most clipping ancestors, which is why it suits a typeahead list that\nusually lives inside a scrollable region; `absolute` positions against the nearest containing\nblock and scrolls with it. An unsupported value resolves back to the default. Like\n`placement`, a change takes effect the next time the listbox opens.\n\nThis reports only the instance's own authored value (or the default). When the instance sets\nnothing, the listbox is placed with the `--lr-positioning-strategy` cascading custom property\nhonoured ahead of that default -- see that `@cssprop`.\n\nNo `hoist` alias, deliberately, unlike `<lr-select>`. There it is Shoelace's established\nspelling; here it would be a boolean whose default is `true`, so the attribute could only ever\nexpress the value the control already has. Use `positioning-strategy=\"absolute\"` to opt out.\n\nType: `PlaceStrategy`  \nDefault: `'fixed'`","value":{"type":["'absolute'","'fixed'"]}},{"name":"required","description":"Requires at least one committed selection.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"show-unknown-option","description":"Appends every committed value that no option or async row claims to the end of the listbox as\na synthetic, re-selectable row badged with the localized `notInCatalog` text -- the policy\n`<lr-model-select>` already ships.\n\nOff by default, because it adds a row to a listbox that has always rendered only real options.\nTurn it on wherever a stored value can outlive its catalog entry: without it, the out-of-list\nvalue is visible on the trigger but absent from the listbox, so a user who opens the listbox\nhas no way back to the value they arrived with.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"size","description":"Visual size — the library-wide `2xs`–`xl` ladder shared with `lr-input`/`lr-select`. The\nWeb Awesome / Shoelace spellings `small`/`medium`/`large` are accepted for `s`/`m`/`l`, so a\nmigration is a tag rename with no attribute rewrite.\n\nType: `LyraSize`  \nDefault: `'m'`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}},{"name":"source-delay","description":"Debounce (ms) between the last keystroke and the `source` call. Sanitized to a finite\nduration clamped to `[0, browser-timer-ceiling]`; `0` fires on every keystroke, a\nnon-finite value falls back to the `200` default.\n\nType: `number`","value":{"type":["number"]}},{"name":"spellcheck","description":"Native spellchecking forwarded to the filter input. Attribute removal restores this\ncomponent's declared `false` default instead of the converter's native-HTML `true` fallback.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"sync","description":"Copies the trigger's width, height, or both onto the listbox -- the same property\n`<lr-dropdown>`/`<lr-popup>` spell. Unset (the default), the listbox sizes to its own content,\nclamped between `--lr-size-12rem` and `--lr-size-28rem`, exactly as before. Set `sync=\"width\"`\nso a full-width trigger with short option labels gets a listbox that aligns to its own edges\ninstead of floating narrower in the middle -- the width clamp described above no longer\napplies while this is set, since the anchor's own width is now the intentional bound.\n\nType: `PlaceSync | undefined`  \nDefault: `undefined`","value":{"type":["'width'","'height'","'both'"]}},{"name":"value","description":"The selected value(s): a string in single mode, a string[] in `multiple` mode.\n\nAssigning `undefined` or `null` clears the selection -- the documented \"unset\" contract.\nEvery string, including `''`, is instead a candidate value: `<lr-option value=\"\">` (or a\nmatching async row) is a legitimate row, and assigning `''` selects it when present,\nmirroring what picking that row already did. A `''`/string assignment that matches nothing\nstill commits, exactly like any other unmatched string -- see `isUnknownValue()`.\n\n`LyraPickerValue<Multiple>` narrows to `string` on a `LyraCombobox<false>` and `string[]` on a\n`LyraCombobox<true>`; the unnarrowed default resolves to the published union below, which is\nwhy the manifest type is pinned here rather than left to the inferred alias name.\n\nType: `string | string[]`"},{"name":"visible-options","description":"Bounds the popup to roughly this many option rows, leaving the rest reachable by scrolling.\n\nThis is the third and last of three similarly-named caps, which is exactly the confusion this\nproperty exists to end -- each does something different:\n- `visibleOptions` (this one) caps how many suggestion rows are **visible** at once. Purely\n  presentational: every row is still rendered and still reachable by scrolling.\n- `maxOptionsVisible` caps how many **selected tags** are shown in multi-select before the\n  \"+N\" summary. Nothing to do with the suggestion list.\n- `maxRender` caps how many suggestion rows are **rendered into the DOM at all**, as a\n  performance ceiling; rows past it do not exist and are summarized by `option-overflow`.\n\nUnset imposes no bound of its own, leaving the listbox's existing max-height behavior exactly\nas it was. Zero, negative, and non-finite values normalize to unset rather than collapsing the\npopup.\n\nType: `number | undefined`"},{"name":"with-clear","description":"Web Awesome's spelling of clearable, accepted so a mechanical `wa-` → `lr-` rename\ndoes not silently drop the clear button. Prefer `clearable` in new code.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"with-hint","description":"SSR slot-presence hint for hint content.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"with-label","description":"SSR slot-presence hint for label content.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"","description":"`<lr-option>` elements."},{"name":"clear-icon","description":"Replaces the clear button's built-in icon."},{"name":"end","description":"Adornment after the filter input and the built-in clear action, and before the expand icon — so consumer content never sits outboard of the dropdown chevron."},{"name":"error","description":"Custom error content."},{"name":"expand-icon","description":"Replaces the dropdown indicator's built-in icon."},{"name":"hint","description":"Custom hint content."},{"name":"label","description":"Custom label content."},{"name":"source-error","description":"Replaces the built-in failed-`source` state, retry control included. Named apart from the form-control `error` slot deliberately: they are different failures and a control has to be able to show both."},{"name":"start","description":"Adornment at the inline-start of the trigger row, before the selected-value tags and the filter input. Slotted content is decorative chrome, not an option: `collectOptions()` only ever collects `<lr-option>` elements from the default slot."}],"js":{"properties":[{"name":"allowCreate","description":"Allows a nonmatching query to be created as a new option through the cancelable `lr-create`\nveto point. The default action appends and selects an `<lr-option>`.\n\nAttribute: `allow-create`","type":"boolean","default":"false"},{"name":"allowCustomValue","description":"Lets a single-select combobox commit arbitrary text without adding an option.\n\nAttribute: `allow-custom-value`","type":"boolean","default":"false"},{"name":"appearance","description":"Visual treatment shared with other Lyra form controls.\n\nAttribute: `appearance`  \nReflected to its attribute.","type":"'filled' | 'outlined' | 'filled-outlined'","default":"'outlined'"},{"name":"autocapitalize","description":"Attribute: `autocapitalize`","type":"string","default":"''"},{"name":"autocomplete","description":"Native editing-assistance attributes forwarded to the wrapped input.\n\nAttribute: `autocomplete`","type":"string","default":"'off'"},{"name":"autocorrect","description":"Web Awesome's boolean `autocorrect` IDL; its HTML attribute uses `on`/`off`.\n\nAttribute: `autocorrect`","type":"boolean","default":"true"},{"name":"clearable","description":"Show a clear button while the combobox has something to clear on either axis: a committed\nselection, or visible filter text (the open listbox in single-select, any time in `multiple`\nmode — a closed single-select shows the selected label, not the query, so a stale query alone\nnever surfaces the button). Clearing a selection emits `input`/`change`/`lr-clear`; clearing\nfilter text emits `lr-filter` with an empty `value`; each fires only for the axis that\nactually changed. Named after Shoelace's `clearable`; Web Awesome spells the same idea\n`with-clear`, which is accepted as an alias so either migration keeps working.\n\nAttribute: `clearable`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"customError","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nAttribute: `custom-error`  \nReflected to its attribute.","type":"string | null"},{"name":"disabled","description":"Disables every interactive sub-control.\n\nAttribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"effectiveDisabled","description":"Effective disabled state: this element's own `disabled` OR an ancestor\n`<fieldset disabled>`'s inherited state -- mirrors native `<input>`, whose\nown `disabled` IDL property/attribute is never mutated by a fieldset.","type":"boolean","read-only":true},{"name":"emptyText","description":"Optional no-match copy override. Omission localizes `noMatches`; a supplied string, including\n`\"No matches\"` or `\"\"`, renders verbatim.\n\nAttribute: `empty-text`","type":"string | undefined"},{"name":"enterKeyHint","description":"Attribute: `enterkeyhint`","type":"string","default":"''"},{"name":"enterkeyhint","type":"string"},{"name":"errorText","description":"Attribute: `error-text`","type":"string","default":"''"},{"name":"filter","type":"OptionFilter | null","default":"null"},{"name":"form","description":"Attribute: `form`  \nReflected to its attribute.","type":"HTMLFormElement | string | null","default":"null"},{"name":"getTag","description":"Custom selected-tag renderer in multiple mode. Returned strings stay text, never markup.","type":"LyraComboboxTagRenderer | undefined"},{"name":"getUnknownLabel","description":"Renders the label for a committed value that matches no option or row.\n\nThe existing tag/option renderers cannot serve this case: they are handed a matched option,\nwhich by definition does not exist here, so the raw value string was the only thing left to\nrender. This hook applies everywhere that value's label appears -- the trigger, a `multiple`\ntag, and the synthetic listbox row -- and is used only while the value is genuinely unmatched,\nso it can never override a real option's own label. A blank return falls back to the raw\nvalue, exactly as no hook at all would. Caller-supplied text: it is not localized here. Not\nconsulted while an async `source` fetch has never yet resolved for this element -- the value\nis not yet known to be unmatched at all, so `loadingText` renders instead (see `isUnknownValue()`).","type":"(value: string) => string | undefined"},{"name":"hint","description":"Attribute: `hint`","type":"string","default":"''"},{"name":"input","description":"The internal native filter input, for direct DOM access when needed.","type":"HTMLInputElement | null","read-only":true},{"name":"inputMode","description":"Attribute: `inputmode`","type":"string","default":"''"},{"name":"inputValue","description":"Live text in the native filter input. Programmatic writes are event-silent.","type":"string","default":"''"},{"name":"inputmode","description":"Lowercase mapped IDL aliases for the remaining camel-case native spellings.","type":"string"},{"name":"label","description":"Attribute: `label`","type":"string","default":"''"},{"name":"labels","type":"NodeList","read-only":true},{"name":"loadingText","description":"Optional loading-copy override. Omission localizes `loading`; a supplied string, including\n`\"Loading…\"` or `\"\"`, renders verbatim. Shown both in the listbox's own loading row and, for a\ncommitted value a `source` fetch has never resolved (see `labelFor()`), in place of the raw\nvalue on the trigger/tags -- the same key covers both spots.\n\nAttribute: `loading-text`","type":"string | undefined"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"maxOptionsVisible","description":"Maximum number of selected-value **tags** shown before the rest collapse behind a \"+N\" tag\n(multi-select only). Sanitized to a finite, non-negative integer.\n\nNot to be confused with the two caps on the suggestion list: `visibleOptions` bounds how many\nsuggestion rows are visible at once, and `maxRender` bounds how many are rendered at all.\nThis one only ever concerns the tags for values already chosen.\n\nAttribute: `max-options-visible`","type":"number","default":"3"},{"name":"maxRender","description":"Maximum number of suggestion rows **rendered into the DOM at all** before the rest collapse\nbehind the overflow indicator (the current selection is always kept visible regardless). This\nis a performance ceiling, not a visible-height affordance: rows past it do not exist and\ncannot be scrolled to. Use `visibleOptions` to bound the popup's height while keeping every\nrow reachable, and `maxOptionsVisible` for the selected-tag cap. Sanitized to a finite,\nnon-negative integer capped at 1,000.\n\nRows render in full rather than as a recycled scroll window, because the filter input's\n`aria-activedescendant` is an IDREF and can only resolve within its own tree scope — rows\nhosted inside a nested windowing element would sit one shadow root deeper than the input\nthat must point at them. Raising this to cover a few-hundred-entry list (countries,\ncurrencies, time zones) is the intended use; past roughly a thousand rows, `source` narrows\nthe set before it becomes DOM and is the better tool.\n\nAttribute: `max-render`","type":"number"},{"name":"multiple","description":"Enables multiple selection.\n\nAttribute: `multiple`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"name","description":"Submitted field name.\n\nAttribute: `name`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"open","description":"Whether the listbox is open. Effectively disabled controls reject direct reopen attempts,\nincluding a synchronous fieldset cascade.\n\nAttribute: `open`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"overflowText","description":"Optional capped-list copy override. Omission localizes `comboboxOverflow`; a supplied string,\nincluding the built-in English template or `\"\"`, wins verbatim after `{n}` interpolation.\n\nAttribute: `overflow-text`","type":"string | undefined"},{"name":"pill","description":"Rounds the trigger row's corners to a full pill, mirroring `lr-input`'s own `pill`. It is a\nsingle override of `--lr-combobox-radius`, so a consumer setting that property directly still\nwins for a bespoke shape.\n\nAttribute: `pill`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"placeholder","description":"Attribute: `placeholder`","type":"string","default":"''"},{"name":"placement","description":"Preferred vertical side for the floating listbox.\n\nAttribute: `placement`  \nReflected to its attribute.","type":"LyraComboboxPlacement","default":"'bottom'"},{"name":"positioningStrategy","description":"CSS positioning scheme the listbox is laid out with -- the property `<lr-select>`,\n`<lr-popover>`, `<lr-dropdown>`, `<lr-tooltip>` and `<lr-color-picker>` all spell the same way.\n`fixed` (this control's default, and what it has always rendered) positions against the\nviewport and escapes most clipping ancestors, which is why it suits a typeahead list that\nusually lives inside a scrollable region; `absolute` positions against the nearest containing\nblock and scrolls with it. An unsupported value resolves back to the default. Like\n`placement`, a change takes effect the next time the listbox opens.\n\nThis reports only the instance's own authored value (or the default). When the instance sets\nnothing, the listbox is placed with the `--lr-positioning-strategy` cascading custom property\nhonoured ahead of that default -- see that `@cssprop`.\n\nNo `hoist` alias, deliberately, unlike `<lr-select>`. There it is Shoelace's established\nspelling; here it would be a boolean whose default is `true`, so the attribute could only ever\nexpress the value the control already has. Use `positioning-strategy=\"absolute\"` to opt out.\n\nAttribute: `positioning-strategy`  \nReflected to its attribute.","type":"PlaceStrategy","default":"'fixed'"},{"name":"required","description":"Requires at least one committed selection.\n\nAttribute: `required`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"selectedRows","description":"Structured rows corresponding to the current selection, including opaque async-row data.\nAssigning rows from the current local or async source maps their stable `value` fields back to\ncontrolled selection. Detached values are ignored, duplicates collapse, single mode keeps the\nfirst row, and the write is silent like `value`. A property binding that arrives before local\noptions or async rows is deferred until that source resolves. Read rows remain detached\nsnapshots.","type":"ComboboxSourceRow[]"},{"name":"selectionDirection","type":"LyraComboboxSelectionDirection | null"},{"name":"selectionEnd","type":"number | null"},{"name":"selectionStart","type":"number | null"},{"name":"showUnknownOption","description":"Appends every committed value that no option or async row claims to the end of the listbox as\na synthetic, re-selectable row badged with the localized `notInCatalog` text -- the policy\n`<lr-model-select>` already ships.\n\nOff by default, because it adds a row to a listbox that has always rendered only real options.\nTurn it on wherever a stored value can outlive its catalog entry: without it, the out-of-list\nvalue is visible on the trigger but absent from the listbox, so a user who opens the listbox\nhas no way back to the value they arrived with.\n\nAttribute: `show-unknown-option`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"size","description":"Visual size — the library-wide `2xs`–`xl` ladder shared with `lr-input`/`lr-select`. The\nWeb Awesome / Shoelace spellings `small`/`medium`/`large` are accepted for `s`/`m`/`l`, so a\nmigration is a tag rename with no attribute rewrite.\n\nAttribute: `size`  \nReflected to its attribute.","type":"LyraSize","default":"'m'"},{"name":"source","description":"Optional bounded async row source. Receives `{ signal, limit: 2000 }`; may return a legacy\nreadonly row array or `{ rows, total? }`. Results are clone-normalized under row/text ceilings.","type":"ComboboxSource | null","default":"null"},{"name":"sourceDelay","description":"Debounce (ms) between the last keystroke and the `source` call. Sanitized to a finite\nduration clamped to `[0, browser-timer-ceiling]`; `0` fires on every keystroke, a\nnon-finite value falls back to the `200` default.\n\nAttribute: `source-delay`","type":"number"},{"name":"sourceTotal","description":"Provider-side match count for the latest accepted source response, before component caps.","type":"number","read-only":true},{"name":"sourceTruncated","description":"Whether the latest response contained or reported more rows than the bounded retained set.","type":"boolean","read-only":true},{"name":"spellcheck","description":"Native spellchecking forwarded to the filter input. Attribute removal restores this\ncomponent's declared `false` default instead of the converter's native-HTML `true` fallback.\n\nAttribute: `spellcheck`","type":"boolean","default":"false"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"sync","description":"Copies the trigger's width, height, or both onto the listbox -- the same property\n`<lr-dropdown>`/`<lr-popup>` spell. Unset (the default), the listbox sizes to its own content,\nclamped between `--lr-size-12rem` and `--lr-size-28rem`, exactly as before. Set `sync=\"width\"`\nso a full-width trigger with short option labels gets a listbox that aligns to its own edges\ninstead of floating narrower in the middle -- the width clamp described above no longer\napplies while this is set, since the anchor's own width is now the intentional bound.\n\nAttribute: `sync`  \nReflected to its attribute.","type":"PlaceSync | undefined","default":"undefined"},{"name":"validationMessage","type":"string","read-only":true},{"name":"validationTarget","description":"Native element used as the constraint-validation focus anchor.","type":"HTMLElement | undefined"},{"name":"validators","description":"Additional JavaScript validators run after the intrinsic `required` constraint — the same\ncontract `lr-date-input` implements. Accepts a function, an object with\n`validate(value, input)`, or the mapped object-validator shape with `checkValidity(input)` and\n`{ isValid, message, invalidKeys }` results. Object validators can list host\n`observedAttributes` that should trigger live revalidation.","type":"LyraComboboxValidator[]","default":"[]"},{"name":"validity","type":"ValidityState","read-only":true},{"name":"value","description":"The selected value(s): a string in single mode, a string[] in `multiple` mode.\n\nAssigning `undefined` or `null` clears the selection -- the documented \"unset\" contract.\nEvery string, including `''`, is instead a candidate value: `<lr-option value=\"\">` (or a\nmatching async row) is a legitimate row, and assigning `''` selects it when present,\nmirroring what picking that row already did. A `''`/string assignment that matches nothing\nstill commits, exactly like any other unmatched string -- see `isUnknownValue()`.\n\n`LyraPickerValue<Multiple>` narrows to `string` on a `LyraCombobox<false>` and `string[]` on a\n`LyraCombobox<true>`; the unnarrowed default resolves to the published union below, which is\nwhy the manifest type is pinned here rather than left to the inferred alias name.\n\nAttribute: `value`","type":"string | string[]"},{"name":"visibleOptions","description":"Bounds the popup to roughly this many option rows, leaving the rest reachable by scrolling.\n\nThis is the third and last of three similarly-named caps, which is exactly the confusion this\nproperty exists to end -- each does something different:\n- `visibleOptions` (this one) caps how many suggestion rows are **visible** at once. Purely\n  presentational: every row is still rendered and still reachable by scrolling.\n- `maxOptionsVisible` caps how many **selected tags** are shown in multi-select before the\n  \"+N\" summary. Nothing to do with the suggestion list.\n- `maxRender` caps how many suggestion rows are **rendered into the DOM at all**, as a\n  performance ceiling; rows past it do not exist and are summarized by `option-overflow`.\n\nUnset imposes no bound of its own, leaving the listbox's existing max-height behavior exactly\nas it was. Zero, negative, and non-finite values normalize to unset rather than collapsing the\npopup.\n\nAttribute: `visible-options`","type":"number | undefined"},{"name":"willValidate","type":"boolean","read-only":true},{"name":"withClear","description":"Web Awesome's spelling of clearable, accepted so a mechanical `wa-` → `lr-` rename\ndoes not silently drop the clear button. Prefer `clearable` in new code.\n\nAttribute: `with-clear`","type":"boolean","default":"false"},{"name":"withHint","description":"SSR slot-presence hint for hint content.\n\nAttribute: `with-hint`","type":"boolean","default":"false"},{"name":"withLabel","description":"SSR slot-presence hint for label content.\n\nAttribute: `with-label`","type":"boolean","default":"false"}],"events":[{"name":"blur","description":"Re-dispatched from the internal native input as a bubbling, composed, non-cancelable event.","type":"FocusEvent"},{"name":"change","description":"The selection changed through user interaction. A bubbling, composed, non-cancelable event carrying `detail: { value, data }` (the new committed selection: a string in single mode, a string[] in `multiple` mode; `data` is index-aligned with `value` -- `data[i]` is the opaque `data` payload of the row/option behind `value[i]`, by reference and never deep-cloned, or `undefined` for a value that resolves to no live row/option -- see `isUnknownValue()`).","type":"CustomEvent<\n    LyraEventDetailSnapshot<{\n      readonly value: LyraPickerDetailValue<Multiple>;\n      readonly data: readonly unknown[];\n    }>\n  >"},{"name":"focus","description":"Re-dispatched from the internal native input as a bubbling, composed, non-cancelable event.","type":"FocusEvent"},{"name":"input","description":"The user typed in the filter or changed the selection. Text edits expose the original InputEvent (no `value` detail); selection changes emit a bubbling, composed, non-cancelable event carrying `detail: { value, data }`.","type":"InputEvent | CustomEvent<\n    LyraEventDetailSnapshot<{\n      readonly value: LyraPickerDetailValue<Multiple>;\n      readonly data: readonly unknown[];\n    }>\n  >"},{"name":"lr-activate","description":"Fired on every activation of an available listbox row -- a click, or Enter on the active row -- whether or not the selection actually moved. `detail: { value }` carries the activated option's own value, always a single string even in `multiple` mode. Bubbling and composed, so a host outside the shadow tree receives it. Not cancelable: it is a notification that the user picked a row, not a veto point, and nothing in this component branches on it. In single-select mode, re-picking the already-selected row is the case `change`/`lr-change` deliberately stay silent for -- \"re-run that filter\" is a real intent -- and it is otherwise unobservable, because the rows live in this shadow root, so a retargeted `click` names no option and a keyboard commit produces no click at all. When an activation does move the selection, `input`/`change`/`lr-change` are emitted first. Not fired for typing, for a committed custom value that matches no row, for the clear button, or for a programmatic `value` assignment.","type":"CustomEvent<{ value: string }>"},{"name":"lr-after-hide","description":"The listbox finished closing and its transition settled.","type":"CustomEvent<null>"},{"name":"lr-after-show","description":"The listbox finished opening and its transition settled.","type":"CustomEvent<null>"},{"name":"lr-change","description":"Prefixed compatibility alias fired after `input` and `change` on the same selection change, mirroring `<lr-checkbox>`'s `lr-change`. `detail: { value, data }`. Not fired for typing or a programmatic `value` assignment.","type":"CustomEvent<\n    LyraEventDetailSnapshot<{\n      readonly value: LyraPickerDetailValue<Multiple>;\n      readonly data: readonly unknown[];\n    }>\n  >"},{"name":"lr-clear","description":"The value was cleared.","type":"CustomEvent<null>"},{"name":"lr-create","description":"Cancelable request to create a nonmatching input value. Prevent the event to supply a normalized option/value yourself.","type":"CustomEvent<{ inputValue: string }>"},{"name":"lr-filter","description":"The in-progress filter text changed through user input. `detail.value` is the live filter string, which is not the same thing as the host's `value` (the committed selection). User-input only: typing and the clear button announce it. Programmatic edits, including `setRangeText()`, are silent. `setRangeText()` preserves the replaced filter text and synchronizes its query/options without changing selected value. Picking a row, resetting the form, and dismissing the listbox also update the filter silently.","type":"CustomEvent<ComboboxFilterDetail>"},{"name":"lr-hide","description":"The listbox is about to close, however `open` became false. Conditionally cancelable: connected transitions can be vetoed on the same terms as `lr-show`; an already-removed element closing on disconnect cannot honour a veto. A connected veto also preserves the live filter query, active option, and async rows exactly.","type":"CustomEvent<null>"},{"name":"lr-invalid","description":"The combobox failed a validity check. Cancelable: calling `preventDefault()` also cancels the native `invalid` event behind it, suppressing the browser's own validation bubble so an app can present the failure its own way.","type":"CustomEvent<null>"},{"name":"lr-retry","description":"The failed-load state's `[part='retry-button']` was activated. Cancelable — the built-in action calls `refresh()`, and `preventDefault()` leaves the failure on screen for a host that owns its own retry timing.","type":"CustomEvent<null>"},{"name":"lr-show","description":"The listbox is about to open, however `open` became true. Cancelable — `preventDefault()` leaves it closed and the reflected attribute untouched.","type":"CustomEvent<null>"},{"name":"lr-source-error","description":"An async `source` call rejected. `detail: { error, query }` carries the raw rejection, so a host can log or report it (the rendered copy stays localized and never shows it), plus the exact query string that call was made with -- the rejected call's own query, not necessarily `this.query`/`inputValue`, which may have moved on (or been cleared by closing the listbox) by the time the rejection settles. Not cancelable — the failure has already happened and the error row is already what rendered, so there is nothing to veto.","type":"CustomEvent<{ error: unknown; query: string }>"}]}},{"name":"lr-command-palette","description":"`<lr-command-palette>` — searchable application command menu with keyboard navigation.\nShared overlay infrastructure (the same one `<lr-dialog>` uses) coordinates focus-trapping\nTab, Escape dismissal, and document scroll-locking for as long as the palette is open.\nThe public command sequence is copied, bounded, and frozen while each command object's identity\nis retained for its imperative `onSelect` contract. Create and reassign a new command array after\nsequence or row 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**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `backdrop` | Modal backdrop. |\n| `clear-button` | The button that clears the search field, replacing the native search-cancel glyph suppressed by this field's own reset; rendered only while it has a value. |\n| `command` | A command button. |\n| `command-group` | A labeled ARIA group containing visible command options. |\n| `description` | A command's secondary description text. Rendered for every command; empty when the command has no `description`. |\n| `dialog` | Palette dialog. |\n| `empty` | The \"no results\" message. Only rendered when the filter matches no command. |\n| `group` | A group heading, rendered before the first command of each `group`. |\n| `icon` | A command's leading icon glyph. Only rendered when the command has an `icon`. |\n| `input` | Search input. |\n| `label` | A command's visible label. |\n| `list` | Command list. |\n| `list-spacer` | Virtual result extent inside the scrolling list. |\n| `search` | The search row wrapping the leading icon and the `input`. |\n| `shortcut` | A command's trailing shortcut hint. Only rendered when the command has a `shortcut`. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-command-palette-active-bg` (default: `var(--lr-color-brand-quiet)`) — Background of the active (keyboard-highlighted, `data-active=\"true\"`) command row. Declared as an inline `var()` fallback (never on `:host`), so setting it on the element or an ancestor recolors only the active row without hijacking the library-wide `--lr-color-brand-quiet` token.\n- `--lr-command-palette-group-height` (default: `var(--lr-size-2rem)`) — Virtual group-heading height; live changes rebuild heading/row transforms and the result extent.\n- `--lr-command-palette-list-max-block-size` (default: `50vh`) — Maximum height of the scrolling command list.\n- `--lr-command-palette-max-block-size` (default: `70vh`) — Maximum dialog height.\n- `--lr-command-palette-max-inline-size` (default: `var(--lr-size-48rem)`) — Maximum dialog width.\n- `--lr-command-palette-offset-block-start` (default: `12vh`) — Gap between the viewport top and the dialog.\n- `--lr-command-palette-row-height` (default: `var(--lr-size-3rem)`) — Virtual command-row height; live changes rebuild row transforms, scrolling coordinates, and the result extent.\n- `--lr-command-palette-search-font-size` (default: `inherit`) — Text size of the query field.\n- `--lr-command-palette-search-gap` (default: `var(--lr-space-s)`) — Gap between the leading glyph and the query field.\n- `--lr-command-palette-search-min-height` (default: `auto`) — Minimum row height of the query field, for matching it to a themed search field of a chosen density tier. Point it at `--lr-form-control-height-s` (or any tier of that ladder) to line the palette's own field up with the rest of an application's controls.\n- `--lr-command-palette-search-padding` (default: `var(--lr-space-m)`) — Gutter around the query row.\n- `--lr-command-palette-z-index` (default: `var(--lr-overlay-stack-index, var(--lr-layer-modal))`) — Stacking index of the backdrop.","attributes":[{"name":"aria-label","description":"Accessible name for the dialog. Omitted falls back to the localized `commandPaletteLabel`\ndefault. An explicitly empty `aria-label` is used as-is.\n\nType: `string | undefined`"},{"name":"hotkey","description":"Exact global activation chord. `mod` resolves to Command on macOS and Control elsewhere,\nusing Client Hints with legacy platform and reduced user-agent fallbacks.\n\nType: `string`  \nDefault: `'mod+k'`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"open","description":"Whether the palette is open. Post-mount IDL and attribute writes use the same synchronous,\ncancelable lifecycle as `openPalette()` and `close()`; initial markup stays silent.\n\nType: `boolean`","value":{"type":["boolean"]}}],"js":{"properties":[{"name":"accessibleLabel","description":"Accessible name for the dialog. Omitted falls back to the localized `commandPaletteLabel`\ndefault. An explicitly empty `aria-label` is used as-is.\n\nAttribute: `aria-label`","type":"string | undefined"},{"name":"commands","description":"Commands to search and activate. The sequence is copied, bounded, and frozen while command\nidentity is retained. `commandId` must be unique and nonempty; malformed rows and later\nduplicates from untyped boundaries are omitted deterministically.","type":"readonly LyraCommand[]","default":"[]"},{"name":"hotkey","description":"Exact global activation chord. `mod` resolves to Command on macOS and Control elsewhere,\nusing Client Hints with legacy platform and reduced user-agent fallbacks.\n\nAttribute: `hotkey`","type":"string","default":"'mod+k'"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"open","description":"Whether the palette is open. Post-mount IDL and attribute writes use the same synchronous,\ncancelable lifecycle as `openPalette()` and `close()`; initial markup stays silent.\n\nAttribute: `open`  \nReflected to its attribute.","type":"boolean"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"blur","description":"Re-dispatched when the search input loses focus.","type":"CustomEvent<null>"},{"name":"focus","description":"Re-dispatched when the search input receives focus. Native `focus` neither bubbles nor crosses the shadow boundary, so a host listener on `<lr-command-palette>` itself never sees it otherwise.","type":"CustomEvent<null>"},{"name":"lr-close","description":"Emitted before the palette closes. Cancelable: `preventDefault()` keeps it open.","type":"CustomEvent<null>"},{"name":"lr-open","description":"Emitted before the palette opens. Cancelable: `preventDefault()` keeps it closed.","type":"CustomEvent<null>"},{"name":"lr-select","description":"A command was chosen; detail is `{ command }`.","type":"CustomEvent<Readonly<{ command: LyraCommand }>>"}]}},{"name":"lr-commit-card","description":"`<lr-commit-card>` — compact commit summary (subject, author/time, diffstat, per-file changes)\nthat links file rows out to a diff view. Set `compact` (tighter padding) and/or\n`frame=\"plain\"` (no border/padding at all) when embedding one as a row in a commit list or\nPR timeline, so the built-in card chrome doesn't double up against the list's own — same\nconvention as `<lr-agent-run>`'s own `compact`/`frame`.\nDuplicate file paths normalize before totals, counts, rendering, and selection events; the\nfirst occurrence wins. File addition/deletion counts are normalized to finite non-negative integers before totals,\nlocalized display, and accessible summaries are derived.\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| `actions` | Trailing header controls (e.g. an \"open PR\" button). |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `actions` | The `actions` slot wrapper. |\n| `additions` | The additions count. |\n| `author` | The author text. |\n| `base` | The root wrapper. |\n| `body` | The commit message's remaining lines. |\n| `copy-button` | The hash copy button. |\n| `deletions` | The deletions count. |\n| `diffstat` | The aggregate `+N -M` summary. |\n| `file` | A file row; carries `data-status`. |\n| `file-additions` | A file row's additions count. |\n| `file-deletions` | A file row's deletions count. |\n| `file-path` | A file row's path text. |\n| `file-status` | The one-letter git-status badge inside `[part=\"file-path\"]`, present only when that file has a `status`. Carries the localized expansion (`Modified`, `Added`, ...) as its accessible name, so the bare letter never reaches assistive tech on its own. |\n| `files-toggle` | The file-list fold toggle. |\n| `hash` | The abbreviated hash text. |\n| `meta` | The author/time/diffstat row. |\n| `subject` | The commit message's first line. |\n| `time` | The `<time>` wrapper. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-commit-card-background` (default: `transparent`) — Fill of the outer card (`[part=\"base\"]`) while `frame=\"card\"`, unset by default so the card takes the surface it sits on. `frame=\"plain\"` still removes the fill entirely.\n- `--lr-commit-card-border-color` (default: `var(--lr-color-border)`) — Colour of the outer card's border.\n- `--lr-commit-card-compact-padding` (default: `var(--lr-space-s)`) — `[part=\"base\"]` padding while `compact`.\n- `--lr-commit-card-radius` (default: `var(--lr-radius)`) — Corner radius of the outer card. `frame=\"plain\"` still squares the corners.","attributes":[{"name":"author","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"compact","description":"Tighter root padding for dense contexts (a commit rendered as a row in a list or PR\ntimeline) -- same convention as `<lr-agent-run>`'s own `compact`. Defaults to `false`, i.e.\nthe full card padding. Purely a density knob: the border stays, so use `frame=\"plain\"`\ninstead to drop the chrome entirely.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"copyable","description":"Type: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"files-expanded","description":"Whether the per-file list is shown. Defaults to `false` (collapsed), matching the\npositive-polarity `expanded` convention every sibling component uses.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"frame","description":"Visual chrome, in the library's shared container-frame vocabulary (the same `frame` property\n`<lr-agent-run>` carries). `'card'` (the default) keeps the bordered, padded box. `'plain'`\nremoves the border, padding and corner radius, so a commit nested inside a host list that\nalready draws its own row chrome doesn't double it. `plain` wins over `compact` when both are\nset (nothing left to tighten).\n\nType: `LyraFrame`  \nDefault: `'card'`","value":{"type":["'card'","'plain'"]}},{"name":"hash","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"message","description":"Commit subject and optional body. Removing the attribute clears both displayed sections.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"slots":[{"name":"actions","description":"Trailing header controls (e.g. an \"open PR\" button)."}],"js":{"properties":[{"name":"author","description":"Attribute: `author`","type":"string","default":"''"},{"name":"compact","description":"Tighter root padding for dense contexts (a commit rendered as a row in a list or PR\ntimeline) -- same convention as `<lr-agent-run>`'s own `compact`. Defaults to `false`, i.e.\nthe full card padding. Purely a density knob: the border stays, so use `frame=\"plain\"`\ninstead to drop the chrome entirely.\n\nAttribute: `compact`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"copyable","description":"Attribute: `copyable`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"files","description":"File changes keyed by path. Empty/blank paths are omitted and duplicates normalize\nfirst-wins before diffstat and events.","type":"readonly CommitFileChange[]","default":"[]"},{"name":"filesExpanded","description":"Whether the per-file list is shown. Defaults to `false` (collapsed), matching the\npositive-polarity `expanded` convention every sibling component uses.\n\nAttribute: `files-expanded`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"frame","description":"Visual chrome, in the library's shared container-frame vocabulary (the same `frame` property\n`<lr-agent-run>` carries). `'card'` (the default) keeps the bordered, padded box. `'plain'`\nremoves the border, padding and corner radius, so a commit nested inside a host list that\nalready draws its own row chrome doesn't double it. `plain` wins over `compact` when both are\nset (nothing left to tighten).\n\nAttribute: `frame`  \nReflected to its attribute.","type":"LyraFrame","default":"'card'"},{"name":"hash","description":"Attribute: `hash`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"message","description":"Commit subject and optional body. Removing the attribute clears both displayed sections.\n\nAttribute: `message`","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"timestamp","type":"number | undefined"}],"events":[{"name":"lr-copy","description":"`detail: { ok: true, text }` — the full-hash clipboard write completed.","type":"CustomEvent<LyraClipboardWriteSuccess>"},{"name":"lr-copy-error","description":"`detail: { ok: false, text, reason, error }` — typed clipboard failure.","type":"CustomEvent<LyraClipboardWriteFailure>"},{"name":"lr-error","description":"The clipboard write failed; generic no-detail notification.","type":"CustomEvent<null>"},{"name":"lr-file-select","description":"`detail: { filePath }` — a file row was activated.","type":"CustomEvent<{ filePath: string }>"},{"name":"lr-toggle","description":"`detail: { collapsed }` — the file-list fold changed.","type":"CustomEvent<{ collapsed: boolean }>"}]}},{"name":"lr-community-card","description":"`<lr-community-card>` — a cluster/community summary card (GraphRAG community report): label,\nLLM summary excerpt, member count, member chips with overflow, and a drill-in action. Doesn't\nown community rendering on the graph or membership fetching -- `lr-drill` asks the host to\nload members/subgraph.\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| `actions` | Extra header actions alongside the built-in drill button. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `actions` | The wrapper around the `actions` slot and the drill button. |\n| `base` | The outer bordered container. |\n| `drill-button` | The built-in \"Explore community\" button. |\n| `empty` | The empty state shown when `community` is `null`. |\n| `header` | The header row. |\n| `member` | One member chip button. |\n| `member-count` | The `\"{count} members\"` text. |\n| `members` | The wrapper around member chips, omitted in `compact` mode. |\n| `overflow` | The \"+N\" overflow chip button. |\n| `summary` | The LLM summary excerpt, omitted in `compact` mode. |\n| `title` | The community label, `role=\"heading\" aria-level=\"3\"` wrapping a `<button>`. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-community-card-bg` (default: `var(--lr-color-surface)`) — Resting background of `[part=\"base\"]`. `frame=\"plain\"` still paints transparent.","attributes":[{"name":"compact","description":"Single-row layout (title + member count + drill button, no summary/chips).\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"frame","description":"Container treatment, in the shared `LyraFrame` vocabulary — the same property this\ncomponent's sibling `lr-entity-card` carries. `'card'` (the default) keeps the bordered,\nfilled, padded box. `'plain'` removes the border, background, and padding, so a card nested\ninside a container that already draws a border doesn't double it.\n\nType: `LyraFrame`  \nDefault: `'card'`","value":{"type":["'card'","'plain'"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max-members","description":"Visible member chips before the \"+N\" overflow chip.\n\nType: `number`  \nDefault: `8`","value":{"type":["number"]}}],"slots":[{"name":"actions","description":"Extra header actions alongside the built-in drill button."}],"js":{"properties":[{"name":"community","description":"`null` renders the `noData` empty state.","type":"LyraCommunity | null","default":"null"},{"name":"compact","description":"Single-row layout (title + member count + drill button, no summary/chips).\n\nAttribute: `compact`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"frame","description":"Container treatment, in the shared `LyraFrame` vocabulary — the same property this\ncomponent's sibling `lr-entity-card` carries. `'card'` (the default) keeps the bordered,\nfilled, padded box. `'plain'` removes the border, background, and padding, so a card nested\ninside a container that already draws a border doesn't double it.\n\nAttribute: `frame`  \nReflected to its attribute.","type":"LyraFrame","default":"'card'"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"maxMembers","description":"Visible member chips before the \"+N\" overflow chip.\n\nAttribute: `max-members`","type":"number","default":"8"},{"name":"members","description":"Rendered as chips.","type":"readonly LyraEntity[]","default":"[]"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-drill","description":"`detail: { communityId }`.","type":"CustomEvent<{ communityId: string }>"},{"name":"lr-entity-activate","description":"A member chip was activated. `detail: { entityId }`.","type":"CustomEvent<{ entityId: string }>"}]}},{"name":"lr-compare-panel","description":"`<lr-compare-panel>` — side-by-side A/B output comparison with a winner\nvote (LMSYS-arena / LangSmith-pairwise style): two slotted panes, a vote\nbar, synchronized reading.\nA host may commit `itemId` and its controlled `vote` in either assignment order. Changing only\n`itemId` clears the prior vote; an explicit vote in the same update is preserved.\n`allowedVotes` is a clone-owned, bounded readonly snapshot; create and reassign a new array\nafter changing the permitted choices.\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| `a` | The first output (any content — a chat message, markdown, a viewer). |\n| `b` | The second output. |\n| `prompt` | Optional shared-input header above both panes. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The outer wrapper. |\n| `live-region` | The internal vote-announcement live region. |\n| `pane-a` | The first pane's labeled scroll region. |\n| `pane-b` | The second pane's labeled scroll region. |\n| `pane-header` | A pane's visible heading. |\n| `panes` | The row (or, under 640px, column) wrapping both panes. Stacked panes size to their content up to the configured maximum height. |\n| `prompt` | The optional prompt header, hidden when the `prompt` slot is empty. |\n| `vote-bar` | The `role=\"group\"` row of vote buttons. |\n| `vote-button` | One vote button. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-compare-panel-max-height` (default: `var(--lr-size-24rem)`) — Cap on how tall each pane's scroll region grows before it scrolls internally.\n- `--lr-compare-panel-selected-background` (default: `var(--lr-color-brand-quiet)`) — Selected vote button background.\n- `--lr-compare-panel-selected-border-color` (default: `var(--lr-color-brand)`) — Selected vote button border color.\n- `--lr-compare-panel-selected-color` (default: `var(--lr-color-brand)`) — Selected vote button text color.\n- `--lr-compare-panel-selected-font-weight` (default: `var(--lr-font-weight-semibold)`) — Selected vote button font weight.","attributes":[{"name":"disabled","description":"Type: `boolean`","value":{"type":["boolean"]}},{"name":"item-id","description":"Type: `string`","value":{"type":["string"]}},{"name":"label-a","description":"Type: `string`","value":{"type":["string"]}},{"name":"label-b","description":"Type: `string`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"sync-scroll","description":"Type: `boolean`","value":{"type":["boolean"]}},{"name":"vote","description":"Type: `CompareVote | null`","value":{"type":["'a'","'b'","'tie'","'both-bad'"]}}],"slots":[{"name":"a","description":"The first output (any content — a chat message, markdown, a viewer)."},{"name":"b","description":"The second output."},{"name":"prompt","description":"Optional shared-input header above both panes."}],"js":{"properties":[{"name":"allowedVotes","description":"Clone-owned vote choices shown in the canonical `a`, `b`, `tie`, `both-bad` order.\nJS-only so the positive choice list stays typed instead of relying on a\nlossy comma-separated attribute representation. Reassign a new array after changes.","type":"readonly CompareVote[]","default":"['a', 'b', 'tie', 'both-bad']"},{"name":"disabled","description":"Attribute: `disabled`  \nReflected to its attribute.","type":"boolean"},{"name":"itemId","description":"Attribute: `item-id`","type":"string"},{"name":"labelA","description":"Attribute: `label-a`","type":"string"},{"name":"labelB","description":"Attribute: `label-b`","type":"string"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"syncScroll","description":"Attribute: `sync-scroll`","type":"boolean"},{"name":"vote","description":"Attribute: `vote`  \nReflected to its attribute.","type":"CompareVote | null"}],"events":[{"name":"lr-vote","description":"`detail: { choice, itemId }`. Cancelable; preventing it preserves the prior vote.","type":"CustomEvent<{ choice: CompareVote; itemId: string }>"}]}},{"name":"lr-condition-builder","description":"`<lr-condition-builder>` — a composable structured-condition builder for tabular/dashboard data: a\nflat list of field/operator/value condition rows combined with one AND/OR combinator.\n\nDistinct from this package's `<lr-graph-query-builder>`: that component builds typed\nrelationship/path queries over a knowledge graph, a genuinely different data model from this\none's flat tabular field/operator/value conditions — they never share a file or a value type.\n\nA host supplies `fields` (the available columns, each with a `ConditionBuilderFieldType` that\ndetermines its offered operators and value control) and `value` (a plain\n`{ combinator, conditions }` object whose valid snapshots can be persisted or sent to a backend,\nusing the same shape convention as this package's `<lr-rubric-form>`/`<lr-filter-bar>`).\nThis component never mutates `fields`/`value` in place — inputs are clone-owned — and never calls\nout to storage/network itself. It does advance its own copy of `value` on each edit and *then*\nemits `lr-input` with the complete next state: the same \"update, then emit; reassign to control\"\nround-trip `<lr-source-picker>`'s `selectedSourceIds` and `<lr-retrieval-search>`'s `filters`\nestablish. `lr-input` is not cancelable, so a host validating an edit reassigns `value` in its\nhandler rather than vetoing the change before it renders. Controlled condition payloads are\npreserved when field metadata is absent, changes, or disagrees with an operator/value shape —\npersisted data is never silently repaired. `validationIssues`, `invalidConditionIds`,\n`checkValidity()`, and `reportValidity()` expose those disagreements instead. User-entered\nnumeric text is still parsed at the control boundary, where a non-finite result becomes unset.\nInputs are clone-owned, bounded readonly snapshots; blank field names, option values, and\ncondition ids are omitted, duplicates use their first valid record, unknown closed-vocabulary\nvalues normalize to a safe fallback, and all event details are frozen.\n\n**9.0 migration:** this original component was renamed from `<lr-query-builder>` /\n`LyraQueryBuilder` / `QueryBuilder*` to the condition-specific names above. No legacy tag, class,\ntype, or granular-path alias remains.\n\nEach row composes `<lr-select>` for the field and operator pickers, and a value control chosen\nfrom the selected field's `type`: `<lr-input type=\"text\">` (`string`), `<lr-input\ntype=\"number\">` (`number`), `<lr-select>` with `True`/`False` options (`boolean`),\n`<lr-date-input>` (`date`), `<lr-select>` (`enum`, `eq`/`neq`) or a multi-select\n`<lr-combobox>` (`enum`, `in`/`notIn`). Date fields forward bounded `min`/`max` strings to\n`<lr-date-input>`; number fields forward finite `min`/`max` and positive finite `step` values to\n`<lr-input>`. A unary operator (`isEmpty`/`isNotEmpty`) renders no value control.\nField/operator selections emit one complete-model `lr-input`; their native value events,\nprefixed value aliases and listbox lifecycle events stay within the picker.\n`<lr-icon-button icon=\"trash\">` removes a row; `<lr-button>` appends one.\n\nThis is a composite query-definition control, not a single submittable form field — it\ndeliberately ships no `label`/`hint`/`errorText` chrome or native form association (the\n`label`/`hint`/`error` triad those controls share doesn't fit a multi-row, multi-field\ncomposite the way it fits one value). A host names the whole control via a plain `aria-label`\nattribute, applied to the element that owns `role=\"group\"`. The group and each condition expose\nexplicit `aria-invalid=\"true\"|\"false\"` from the live validation result.\n\n---\n\n**Component metadata**\n\n- Status: `stable`\n- Since: `9.0.0`\n- Rationale: This tag entered Lyra as a stable public API with documented behavior, accessibility, and cross-browser support.\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| `add-button` | The \"Add condition\" `lr-button`. |\n| `base` | The outer wrapper. |\n| `combinator` | The AND/OR combinator `lr-select`, rendered only when there are 2+ conditions. |\n| `condition` | One field/operator/value row. |\n| `conditions` | The wrapper around the condition rows. |\n| `empty` | The message shown when there are no fields, or no conditions yet. |\n| `field-select` | A row's field `lr-select`. |\n| `operator-select` | A row's operator `lr-select`. |\n| `remove-button` | A row's remove `lr-icon-button`. |\n| `value` | A row's value control (whichever of `lr-input`/`lr-select`/`lr-date-input`/ `lr-combobox` applies, or an empty placeholder for a unary operator or an incomplete row). |","attributes":[{"name":"disabled","description":"Type: `boolean`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"js":{"properties":[{"name":"disabled","description":"Attribute: `disabled`  \nReflected to its attribute.","type":"boolean"},{"name":"fields","description":"Frozen snapshot of at most 200 fields, 500 options/operators per field, bounded strings, and\nfinite type-specific number constraints. Reassign after changing it.","type":"readonly ConditionBuilderField[]"},{"name":"invalidConditionIds","description":"Condition ids currently represented in `validationIssues`, in model order.","type":"readonly string[]","read-only":true},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"validationIssues","description":"Live, frozen validation results for controlled conditions that disagree with the current\nfield/operator/arity/type vocabulary. Reading this never mutates `value`.","type":"readonly ConditionBuilderValidationIssue[]","read-only":true},{"name":"value","description":"The current query: one combinator plus a flat list of conditions. Controlled — assigning\nthis directly never emits `lr-input` (that only fires for a user-driven change); see the\nclass doc's form-association note for why this stays a plain property, not a form value.\nAssignment preserves retained operator/value payloads even when they disagree with the current\nfield metadata; inspect `validationIssues` rather than expecting silent repair. It freezes at\nmost 200 conditions and 500 entries in each array-valued condition; reassign to update.","type":"ConditionBuilderValue"}],"events":[{"name":"lr-add-condition","description":"Frozen `detail: { condition }` — a row seeded with the first field was appended.","type":"CustomEvent<LyraEventDetailSnapshot<{ readonly condition: ConditionBuilderCondition }>>"},{"name":"lr-input","description":"`detail: { value }` — the full current value, after any user-driven change.","type":"CustomEvent<LyraEventDetailSnapshot<{ readonly value: ConditionBuilderValue }>>"},{"name":"lr-remove-condition","description":"`detail: { conditionId }` — a row was removed.","type":"CustomEvent<{ readonly conditionId: string }>"}]}},{"name":"lr-confirm-bar","description":"`<lr-confirm-bar>` — an inline, non-modal approve/deny block for one proposed action: the\nin-flow sibling of `<lr-tool-approval-dialog>` for confirmations that should sit in the\ntranscript instead of hijacking focus. Same `lr-approve`/`lr-deny` event shapes as the dialog,\nand the same `toolApprovalHeading`/`toolApprovalArgsLabel`/`deny`/`approve` localization keys, so\nthe two always translate in lockstep.\n\nNon-modal by contract: no focus trap, no scroll lock, no Escape/backdrop semantics, and it never\nsteals focus when it appears in the transcript. DOM and tab order put Deny before Approve (the\ndialog's safe-action-first rationale). On activation, focus moves synchronously to the first\navailable of `returnFocusTo` and `[part=\"status\"]` (an always-rendered, `tabindex=\"-1\"` element)\n*before* the Deny/Approve buttons unmount, so focus never has a gap where it would otherwise fall\nback to `<body>`. `returnFocusTo` is the opt-in half: unset, the handoff lands on `[part=\"status\"]`\nexactly as it always has, which keeps the decided status reachable but is a dead end for a host\nthat is about to unmount the bar. Set it to the control the bar replaced (or a thunk resolving to\nit) and the same handoff returns focus there instead, falling back to `[part=\"status\"]` whenever\nthe named element is missing, detached, `inert` or otherwise refuses focus -- an `inert` element\nrefuses `focus()` silently, so an unchecked handoff would strand the user on `<body>` at exactly\nthe moment a decision was announced. When `returnFocusTo` is a thunk and that immediate call\nfails, the same handoff quietly retries once more after the host has had a real chance to react\n(see `ConfirmBarReturnFocusTarget`'s doc comment) -- the case a thunk exists for in the first\nplace is a host that has not re-created its control yet at the instant the decision lands, and\nevery supported host framework re-renders asynchronously relative to this synchronous handoff.\n\n\"Never steals focus\" and \"no Escape semantics\" describe the bar's behavior when `autofocus` and\n`escape-denies` are both left unset (the default). A host that swaps a focused control out for\nthis bar -- the case those two properties exist for -- can opt into either or both instead of\nhand-rolling them: `autofocus` moves focus into the bar after its own first render (the Deny\ncontrol when it's present and enabled, matching the safe-action-first DOM order above, else the\nalways-present `[part=\"status\"]`), and `escape-denies` maps Escape on `[part=\"base\"]` to the same\noutcome as clicking Deny. `<lr-memory-panel>` predates both and still implements this focus/Escape\nhandoff itself (`focusPendingConfirmation`/`onConfirmKeyDown`) rather than depending on them.\n`escape-denies` is scoped to this element's own `[part=\"base\"]`, never `document`: this bar is\ninline and non-modal, not a member of the shared `activateOverlay()` Escape/stacking contract\n(`src/internal/overlay-manager.ts`) that real overlays use, so it must not swallow Escape intended\nfor an unrelated enclosing dialog or popover. Neither property traps focus or locks scrolling.\n\nNo argument editing (escalate to `<lr-tool-approval-dialog>`'s `editable` when edit-before-approve\nmatters); no blocking/modality guarantee (a user can scroll past); no decision persistence or\n\"remember choice\" logic (the `footer` slot + host own that).\n\nDensity and chrome are two knobs, not one: `compact` tightens the bar into a single dense inline\nrow and `frame=\"plain\"` removes the card border/radius/background/padding, exactly as they do on\n`<lr-agent-run>`, `<lr-commit-card>`, `<lr-result-card>`, `<lr-task-list>`, `<lr-terminal>` and\n`<lr-thinking-panel>`. Before 9.0.0 `compact` alone did both; a bar that relied on that now\nwants `compact frame=\"plain\"`.\n\nDeny/Approve are `<lr-button>`s. Deny is `variant=\"neutral\" appearance=\"outlined\"` and Approve is\n`variant=\"brand\"` (`\"danger\"` under `variant=\"danger\"`) at lr-button's default `appearance=\"accent\"`,\nso the destructive-or-primary action is the loud one and the safe action recedes. Both appearances\nare stated rather than inherited: a bar whose look depends on another component's default changes\nsilently when that default does. Both are composed children rendered by this component, each\nre-exporting `lr-button`'s own `base`/`label`/`start`/`end`/`spinner` parts under\n`{deny,approve}-button-{base,label,start,end,spinner}` so `--lr-button-*` theming and a consumer's\nexisting `lr-button` style fragments reach them like every other button in an app.\n\nAsync decisions have two entry points, and the declarative one is preferred. `lr-approve`/\n`lr-deny`'s detail carries `waitUntil(promise)`, ExtendableEvent-style: calling it during the\ndispatch puts the bar into `pending` (showing `loading` on the activated button and `disabled` on\nthe other) and the promise's settlement finalizes the decision or bounces it back for a retry, so\nthe component owns the whole state machine and no listener has to cast its `currentTarget`, write\n`pending`, and remember to await `updateComplete` before unmounting. Several `waitUntil()` calls\nfrom several listeners are awaited together. The imperative path it replaces still works and is\nunchanged: `preventDefault()` alone sets `pending` to the action being persisted until the host\nfinalizes by setting `.decision` or bounces back by clearing `.pending` to `null`. A listener that\ninstead resolves the decision itself synchronously (setting `.decision` or `.pending` directly\nduring the dispatch) wins outright over both -- `decide()` only applies its own `pending`\nbookkeeping, `waitUntil()`'s included, when the listener left both untouched, because `emit()` is\nsynchronous and a write that lands during it would otherwise be silently clobbered.\n\n`lr-decision-settled` fires after the decided status has rendered and been announced, on every\npath that reaches a decision -- the bar's own, a `waitUntil()` settlement, and a host writing\n`.decision` directly. It exists so a host can unmount the bar on that signal instead of guessing\nwhether the announcement has already happened.\n\nThe host-writable `disabled` independently blocks both Deny and Approve and makes `decide()` a\nno-op, without discarding any in-flight `decision`/`pending` 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) | Supplementary body content between the heading and the actions (e.g. a `lr-diff-view` of the proposed change). |\n| `footer` | Extra content at the start of the action row (e.g. a \"remember this choice\" checkbox), mirroring `lr-tool-approval-dialog`'s own `footer` slot. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `approve-button` | The built-in Approve `<lr-button>`. Named identically to the dialog's part. |\n| `approve-button-base` | Forwarded from the internal Approve `<lr-button>`'s same-node `base` and `button` wrapper aliases. |\n| `approve-button-end` | Forwarded from the internal Approve `<lr-button>`'s own `end` part. |\n| `approve-button-label` | Forwarded from the internal Approve `<lr-button>`'s own `label` part. |\n| `approve-button-spinner` | Forwarded from the internal Approve `<lr-button>`'s own `spinner` part, present only while `pending` is `'approve'`. |\n| `approve-button-start` | Forwarded from the internal Approve `<lr-button>`'s own `start` part. |\n| `args` | The `lr-details` + `lr-json-viewer` wrapper. Only rendered when `args` is defined. |\n| `base` | The root (`role=\"group\"`). |\n| `body` | The default-slot wrapper. |\n| `deny-button` | The built-in Deny `<lr-button>`. Named identically to the dialog's part. |\n| `deny-button-base` | Forwarded from the internal Deny `<lr-button>`'s same-node `base` and `button` wrapper aliases. |\n| `deny-button-end` | Forwarded from the internal Deny `<lr-button>`'s own `end` part. |\n| `deny-button-label` | Forwarded from the internal Deny `<lr-button>`'s own `label` part. |\n| `deny-button-spinner` | Forwarded from the internal Deny `<lr-button>`'s own `spinner` part, present only while `pending` is `'deny'`. |\n| `deny-button-start` | Forwarded from the internal Deny `<lr-button>`'s own `start` part. |\n| `footer` | The action row. |\n| `heading` | The heading. |\n| `status` | The decided-state text. Always present in the DOM (`tabindex=\"-1\"`) so focus has a stable, synchronous landing spot on activation. |\n| `tool-name` | The tool-name span within the heading. Only rendered when `heading` is unset. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-confirm-bar-approved-color` (default: `var(--lr-color-success)`) — `[part='status']` text/icon color once `decision` is `'approved'`.\n- `--lr-confirm-bar-bg` (default: `var(--lr-color-surface)`) — Resting background of `[part='base']`. `frame=\"plain\"` still paints transparent.\n- `--lr-confirm-bar-compact-gap` (default: `var(--lr-space-s)`) — Gap between the row's items while `compact`.\n- `--lr-confirm-bar-compact-padding` (default: `var(--lr-space-s)`) — Padding of `[part='base']` while `compact`. Accepts any padding shorthand. Overridden entirely by `frame=\"plain\"`.\n- `--lr-confirm-bar-denied-color` (default: `var(--lr-color-danger)`) — `[part='status']` text/icon color once `decision` is `'denied'`.","attributes":[{"name":"autofocus","description":"Opt-in focus-on-mount: moves focus into the bar after its own first render, once this\nelement and (when present) the Deny `<lr-button>` have both completed it. Named after the\nnative global attribute it stands in for -- the platform's own `autofocus` algorithm only\nfires for an element already in the document when it finishes parsing, never for one a host\nswaps in afterward (this bar's primary use, per the class doc), so this implements the same\nintent explicitly instead. Defaults to `false`: nothing here steals focus from a host that\ndoesn't ask for it.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"compact","description":"Collapses the bar from a stacked `display: block` card to a single tightly-padded inline row,\nfor a confirmation that has to live inside an existing container -- a table cell, a card's\naction row, a toolbar. The host becomes `inline-flex`, and the narrow-allocation `@container`\ntreatment is switched off (a compact bar is *expected* to be narrow, so stretching the buttons\nto fill would be exactly wrong). Purely a density/layout knob -- same convention as\n`<lr-agent-run>`'s `compact`: the border, corner radius and background stay, so use\n`frame=\"plain\"` to drop the chrome. Retune the density through\n`--lr-confirm-bar-compact-padding`/`-gap`. Everything else -- the event shapes, the\nfocus-to-`[part='status']`-before-unmount contract, `role=\"group\"` and its heading label --\nis unchanged.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"decision","description":"Decided state. Set by the component on activation *and* host-writable (an externally-resolved\ndecision -- timeout, another reviewer -- renders identically and emits no `lr-approve`/`lr-deny`\nof its own; the settled notification still fires, because the status really did render).\n\nType: `ConfirmBarDecision`","value":{"type":["'approved'","'denied'"]}},{"name":"disabled","description":"Disables both Deny and Approve and makes `decide()` a no-op, without discarding any\nin-flight `decision`/`pending` state. Distinct from `pending`: `pending` marks one specific\naction as awaiting the host while the other stays interactive, while `disabled` blocks both\nregardless of `pending`. Reflects as an attribute.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"escape-denies","description":"Opt-in: maps Escape on `[part=\"base\"]` to the same outcome as clicking Deny. See the class\ndoc for why this is scoped to this element's own base rather than `document`. A no-op while\n`disabled`, already decided, or `pending`, exactly like clicking Deny itself. Defaults to\n`false` -- an unlabelled Escape denying a proposal is a real behavior change a host must\nchoose explicitly.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"frame","description":"Visual chrome, in the library's shared container-frame vocabulary. `'card'` (the default)\nkeeps the bordered, filled, padded box. `'plain'` removes the border, background, padding and\ncorner radius, so a bar nested inside a host container that already draws a border (a table\ncell, an `<lr-result-card>` action row) doesn't double it. `plain` wins over `compact` when\nboth are set -- there is no padding left to tighten. The Deny/Approve `<lr-button>`s keep\ntheir own border/background either way, so a chrome-less bar still has a visible interactive\naffordance.\n\nType: `LyraFrame`  \nDefault: `'card'`","value":{"type":["'card'","'plain'"]}},{"name":"heading","description":"Free-form heading override for non-tool proposals. Wins over `toolName` when set.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"pending","description":"Which action is awaiting host resolution, while an lr-approve/lr-deny listener has called\npreventDefault(). Host-writable: set back to null to bounce back to the undecided state (e.g.\non failure, so the user can retry), or set `decision` to finalize.\n\nType: `ApprovalAction | null`","value":{"type":["'approve'","'deny'"]}},{"name":"tool-name","description":"Drives the default heading through the existing dialog keys.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"variant","description":"Token-mapped emphasis for destructive proposals.\n\nType: `ConfirmBarVariant`  \nDefault: `'neutral'`","value":{"type":["'neutral'","'danger'"]}}],"slots":[{"name":"","description":"Supplementary body content between the heading and the actions (e.g. a `lr-diff-view` of the proposed change)."},{"name":"footer","description":"Extra content at the start of the action row (e.g. a \"remember this choice\" checkbox), mirroring `lr-tool-approval-dialog`'s own `footer` slot."}],"js":{"properties":[{"name":"args","description":"Shown read-only inside a collapsed `lr-details` + `lr-json-viewer` when defined.","type":"unknown","default":"undefined"},{"name":"autofocus","description":"Opt-in focus-on-mount: moves focus into the bar after its own first render, once this\nelement and (when present) the Deny `<lr-button>` have both completed it. Named after the\nnative global attribute it stands in for -- the platform's own `autofocus` algorithm only\nfires for an element already in the document when it finishes parsing, never for one a host\nswaps in afterward (this bar's primary use, per the class doc), so this implements the same\nintent explicitly instead. Defaults to `false`: nothing here steals focus from a host that\ndoesn't ask for it.\n\nAttribute: `autofocus`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"compact","description":"Collapses the bar from a stacked `display: block` card to a single tightly-padded inline row,\nfor a confirmation that has to live inside an existing container -- a table cell, a card's\naction row, a toolbar. The host becomes `inline-flex`, and the narrow-allocation `@container`\ntreatment is switched off (a compact bar is *expected* to be narrow, so stretching the buttons\nto fill would be exactly wrong). Purely a density/layout knob -- same convention as\n`<lr-agent-run>`'s `compact`: the border, corner radius and background stay, so use\n`frame=\"plain\"` to drop the chrome. Retune the density through\n`--lr-confirm-bar-compact-padding`/`-gap`. Everything else -- the event shapes, the\nfocus-to-`[part='status']`-before-unmount contract, `role=\"group\"` and its heading label --\nis unchanged.\n\nAttribute: `compact`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"decision","description":"Decided state. Set by the component on activation *and* host-writable (an externally-resolved\ndecision -- timeout, another reviewer -- renders identically and emits no `lr-approve`/`lr-deny`\nof its own; the settled notification still fires, because the status really did render).\n\nAttribute: `decision`  \nReflected to its attribute.","type":"ConfirmBarDecision"},{"name":"disabled","description":"Disables both Deny and Approve and makes `decide()` a no-op, without discarding any\nin-flight `decision`/`pending` state. Distinct from `pending`: `pending` marks one specific\naction as awaiting the host while the other stays interactive, while `disabled` blocks both\nregardless of `pending`. Reflects as an attribute.\n\nAttribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"escapeDenies","description":"Opt-in: maps Escape on `[part=\"base\"]` to the same outcome as clicking Deny. See the class\ndoc for why this is scoped to this element's own base rather than `document`. A no-op while\n`disabled`, already decided, or `pending`, exactly like clicking Deny itself. Defaults to\n`false` -- an unlabelled Escape denying a proposal is a real behavior change a host must\nchoose explicitly.\n\nAttribute: `escape-denies`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"frame","description":"Visual chrome, in the library's shared container-frame vocabulary. `'card'` (the default)\nkeeps the bordered, filled, padded box. `'plain'` removes the border, background, padding and\ncorner radius, so a bar nested inside a host container that already draws a border (a table\ncell, an `<lr-result-card>` action row) doesn't double it. `plain` wins over `compact` when\nboth are set -- there is no padding left to tighten. The Deny/Approve `<lr-button>`s keep\ntheir own border/background either way, so a chrome-less bar still has a visible interactive\naffordance.\n\nAttribute: `frame`  \nReflected to its attribute.","type":"LyraFrame","default":"'card'"},{"name":"heading","description":"Free-form heading override for non-tool proposals. Wins over `toolName` when set.\n\nAttribute: `heading`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"pending","description":"Which action is awaiting host resolution, while an lr-approve/lr-deny listener has called\npreventDefault(). Host-writable: set back to null to bounce back to the undecided state (e.g.\non failure, so the user can retry), or set `decision` to finalize.\n\nAttribute: `pending`  \nReflected to its attribute.","type":"ApprovalAction | null"},{"name":"returnFocusTo","description":"Where focus goes once a decision lands, instead of parking on `[part=\"status\"]`. Property-only\n(an element reference has no attribute form), and a thunk is accepted so the lookup happens at\nhandoff time rather than at assignment time -- and, if that first lookup does not yet name a\nlive control, is repeated once more after the host has had a chance to react (see\n`ConfirmBarReturnFocusTarget`). The motivating case is the one the class doc opens with: a\nhost swaps a focused control out for this bar, and once the decision is made focus belongs\nback on that control (or on whatever replaced it), not on a status line the host is about to\nunmount -- and that replacement control is typically re-created asynchronously, after the\ndecision has already landed. Unset (`null`) keeps the shipped behavior exactly. A named\ntarget that is missing, detached, `inert` or otherwise refuses focus falls back to\n`[part=\"status\"]` rather than to `<body>`.","type":"ConfirmBarReturnFocusTarget","default":"null"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"toolName","description":"Drives the default heading through the existing dialog keys.\n\nAttribute: `tool-name`","type":"string","default":"''"},{"name":"variant","description":"Token-mapped emphasis for destructive proposals.\n\nAttribute: `variant`  \nReflected to its attribute.","type":"ConfirmBarVariant","default":"'neutral'"}],"events":[{"name":"lr-approve","description":"`detail: { args, waitUntil }` — `args` is the `args` prop as-is (no editing in the bar), matching `lr-tool-approval-dialog`'s own `args` detail. Cancelable: a listener calling `preventDefault()` sets `pending` to `'approve'` instead of finalizing synchronously; set `.decision` (or clear `.pending` back to `null`) once your async work settles. `waitUntil(promise)` does the same thing declaratively and needs no `preventDefault()`: the bar stays pending until the promise settles, then finalizes on resolution or bounces back on rejection.","type":"CustomEvent<{ args: unknown; waitUntil: ConfirmBarWaitUntil }>"},{"name":"lr-decision-settled","description":"`detail: { decision }`. Emitted after the decided `[part=\"status\"]` has rendered and its live-region announcement has been made, on every path that reaches a decision, including a host writing `.decision` directly. Non-cancelable: the decision is already final. A host that replaces the bar with its own result UI can do it on this event without awaiting `updateComplete` itself.","type":"CustomEvent<{ decision: ApprovalDecision }>"},{"name":"lr-deny","description":"`detail: { waitUntil }`, the same resolver `lr-approve` carries and no other data, matching the dialog's detail-free `lr-deny`. Cancelable, same `pending` mechanism as `lr-approve`.","type":"CustomEvent<{ waitUntil: ConfirmBarWaitUntil }>"}]}},{"name":"lr-contact-viewer","description":"Fetches a vCard document and renders one accessible card per contact. Contact names retain\nlevel-three heading semantics by default; set `heading-level` from `1`–`6` to fit the surrounding\noutline, or `none` for visual-only names. At most 250 contacts and 2 MiB of rendered contact text\nare accepted so eager DOM remains bounded while search, selection and text-quote anchors cover\nevery accepted contact. The inherited fragment path performs an exact DOM `id` lookup, but\ngenerated contact cards have no fragment ids; such a jump reports `found: false`.\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| `anchor-live-region` | The aria-hidden, non-live shadow mirror of the latest anchor-jump message. |\n| `base` | The root container with explicit `aria-busy` loading state. |\n| `body` | The wrapper around the fetched-state content. |\n| `contact` | One rendered contact card. |\n| `contact-adr` | A contact's address list, when present. |\n| `contact-email` | A contact's email list, when present. |\n| `contact-name` | A contact's name heading at the configured semantic level. |\n| `contact-org` | A contact's organization line, when present. |\n| `contact-tel` | A contact's phone number list, when present. |\n| `error` | The error region. |\n| `spinner` | The visible tokenized loading treatment and ordinary text label. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-contact-viewer-max-height` (default: `none`) — Maximum block size of the scrollable body before it scrolls internally. Also settable via the `max-height` property.","attributes":[{"name":"active-highlight-id","description":"Id of the currently active highlight, or null when none is active.\n\nType: `string | null`  \nDefault: `null`"},{"name":"heading-level","description":"Semantic level of each rendered contact name. Use `none` for visual-only names; invalid\nuntyped values use level 3.\n\nType: `LyraHeadingLevel`  \nDefault: `'3'`","value":{"type":["'1'","'2'","'3'","'4'","'5'","'6'","'none'"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max-height","description":"A CSS `max-height`; invalid values are ignored.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"name","description":"Optional display name for the source document. It names `[part='base']` when host\n`aria-label` is absent, before the localized fallback. A non-empty host label remains on the\nhost; an explicitly empty one is preserved on the shadow owner.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"src","description":"URL to fetch and parse as vCard text.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"js":{"properties":[{"name":"activeHighlightId","description":"Id of the currently active highlight, or null when none is active.\n\nAttribute: `active-highlight-id`","type":"string | null","default":"null"},{"name":"anchor","description":"Anchor or highlight id to resolve and scroll into view.","type":"LyraAnchor | string | null","default":"null"},{"name":"anchorKinds","description":"Anchor kinds supported by this viewer instance.","type":"readonly LyraAnchorKind[]","default":"[]","read-only":true},{"name":"headingLevel","description":"Semantic level of each rendered contact name. Use `none` for visual-only names; invalid\nuntyped values use level 3.\n\nAttribute: `heading-level`  \nReflected to its attribute.","type":"LyraHeadingLevel","default":"'3'"},{"name":"highlights","description":"Highlights rendered by the document target. Reassign after mutation.","type":"LyraHighlight[]","default":"[]"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"maxHeight","description":"A CSS `max-height`; invalid values are ignored.\n\nAttribute: `max-height`","type":"string","default":"''"},{"name":"name","description":"Optional display name for the source document. It names `[part='base']` when host\n`aria-label` is absent, before the localized fallback. A non-empty host label remains on the\nhost; an explicitly empty one is preserved on the shadow owner.\n\nAttribute: `name`","type":"string","default":"''"},{"name":"src","description":"URL to fetch and parse as vCard text.\n\nAttribute: `src`","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-anchor-result","description":"Fired after an `anchor` assignment or `scrollToAnchor()` call is applied. `detail: { found: boolean }`. Bubbling, composed, and non-cancelable.","type":"CustomEvent<AnchorResultDetail>"},{"name":"lr-render-error","description":"Fired when fetching or parsing the document fails.","type":"CustomEvent<{ error: unknown }>"},{"name":"lr-search-change","description":"Fired whenever search state changes. `matchCountExact=false` makes the retained count a lower bound. Bubbling, composed, and non-cancelable.","type":"CustomEvent<LyraSearchChangeDetail>"},{"name":"lr-text-select","description":"Fired after a selection ends inside the rendered contacts. `detail: { text: string; anchor: LyraAnchor | null; rects: DOMRect[] }`. Bubbling, composed, and non-cancelable.","type":"CustomEvent<TextSelectDetail>"}]}},{"name":"lr-context-inspector","description":"`<lr-context-inspector>` — an inspection view of the exact context assembled for a model call:\nper-segment token estimates via `<lr-context-meter>`, source attribution via\n`<lr-citation-badge>`, and copy/export affordances via `<lr-copy-button>`/`<lr-export-button>`.\nTruncation-boundary and redaction-marker rendering are this component's own minimal\npresentational logic (see `ContextInspectorSegment`'s `truncated`/`omittedTokens`/`redactions`\nfields) — no existing primitive covers \"show where this got cut off / redacted\", so this stays a\nsmall, purpose-built rendering step rather than a general text-annotation system.\n\nPure projection: never fetches, estimates tokens, or performs redaction itself — `segments` is\nexpected to already carry each field's final, already-processed value (e.g. `text` already has\nany redaction placeholders substituted in; this component never sees or renders the original\nunredacted content). Duplicate segment ids normalize before totals, exports, rendering, and\ncitation events; the first occurrence wins.\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.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| `base` | The `role=\"group\"` wrapper. |\n| `citation` | A segment's embedded `lr-citation-badge`, rendered only when it carries a `citation`. |\n| `copy-button` | The embedded `lr-copy-button`. |\n| `empty` | The empty state, shown when `segments` is empty. |\n| `export-button` | The embedded `lr-export-button`. |\n| `meter` | The embedded `lr-context-meter`. Omitted (replaced by `empty`) when `segments` is empty. |\n| `redaction` | One redacted range within a segment's text (a `<mark>`). |\n| `segment` | One segment's wrapper (`role=\"listitem\"`). |\n| `segment-header` | A segment's label/token-count/citation row. |\n| `segment-label` | A segment's visible label text. |\n| `segment-text` | A segment's text body, carrying any `redaction` marks and its own trailing `truncation-boundary` marker. |\n| `segment-tokens` | A segment's visible token-estimate text. |\n| `segments` | The `role=\"list\"` wrapper around all segments. Omitted (replaced by `empty`) when `segments` is empty. |\n| `toolbar` | The wrapper around the copy/export affordances. Omitted when `segments` is empty. |\n| `truncation-boundary` | The marker appended after a `truncated` segment's text. |","attributes":[{"name":"export-filename","description":"Download filename (no extension) passed through to `<lr-export-button>`.\n\nType: `string`  \nDefault: `'context'`","value":{"type":["string"]}},{"name":"label","description":"Accessible group name, and the embedded `<lr-context-meter>`'s own visible caption, e.g. \"128K context window\".\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"total","description":"The full token budget `segments` are measured against — passed straight through to `<lr-context-meter>`'s own `total`.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}}],"js":{"properties":[{"name":"exportFilename","description":"Download filename (no extension) passed through to `<lr-export-button>`.\n\nAttribute: `export-filename`","type":"string","default":"'context'"},{"name":"exportFormats","description":"Export format(s) offered by the embedded `<lr-export-button>` — a single id renders a plain button, more than one a format-choice menu.","type":"readonly LyraExportFormatOption[]","default":"['json']"},{"name":"label","description":"Accessible group name, and the embedded `<lr-context-meter>`'s own visible caption, e.g. \"128K context window\".\n\nAttribute: `label`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"segments","description":"The assembled context, one entry per piece (system prompt, retrieved chunk, history turn,\n...). Empty/blank ids are omitted and duplicates normalize first-wins before metering,\nrendering, export, and events. A valid-id streaming row whose text has not arrived yet is\nretained with an empty text body.","type":"readonly ContextInspectorSegment[]","default":"[]"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"total","description":"The full token budget `segments` are measured against — passed straight through to `<lr-context-meter>`'s own `total`.\n\nAttribute: `total`","type":"number","default":"0"}],"events":[{"name":"lr-citation-activate","description":"`detail: { sourceId, index }`, surfaced by a segment's embedded `lr-citation-badge` — the \"jump to this source\" signal a host wires to scrolling/highlighting the matching `lr-source-card`.","type":"CustomEvent<CitationActivateDetail>"},{"name":"lr-citation-open","description":"`detail: { sourceId, index, href }`, this component's \"full preview\" signal, surfaced the same way.","type":"CustomEvent<CitationOpenDetail>"},{"name":"lr-copy","description":"`detail: { ok: true, text }`, surfaced by the embedded `lr-copy-button` copying the assembled context text (every segment's `label` + `text`, in order). Bubbles + composed already; not re-emitted, so exactly one event reaches a host listener.","type":"CustomEvent<LyraClipboardWriteSuccess>"},{"name":"lr-copy-error","description":"The embedded copy control's compatibility error event for the same clipboard failure.","type":"CustomEvent<LyraClipboardWriteFailure>"},{"name":"lr-error","description":"A clipboard write failed in the embedded copy control.","type":"CustomEvent<null>"},{"name":"lr-export","description":"`detail: { format }`, surfaced by the embedded `lr-export-button`, one row per segment. Cancelable — see that component's own contract for substituting a server-generated export.","type":"CustomEvent<{ readonly format: string }>"},{"name":"lr-export-complete","description":"`detail: { format }`, fired after a non-cancelled export completes.","type":"CustomEvent<{ readonly format: LyraExportFormat }>"},{"name":"lr-export-error","description":"The embedded export control could not complete the requested export.","type":"CustomEvent<{ readonly format: LyraExportFormat; readonly error: unknown }>"},{"name":"lr-hide","description":"The embedded export format menu closed.","type":"CustomEvent<null>"},{"name":"lr-show","description":"The embedded export format menu opened.","type":"CustomEvent<null>"},{"name":"lr-toolbar-actions-change","description":"No-detail coordination event surfaced unchanged from the embedded copy button when its logical toolbar action changes availability or backing trigger.","type":"Event"}]}},{"name":"lr-context-meter","description":"`<lr-context-meter>` — a segmented occupancy meter (bar or ring) for\nshowing how a fixed capacity (a model's context window, a token budget,\nany consumable quota) is divided across labeled categories. First-party\ninvention; no equivalent exists in Web Awesome.\n\nPure data visualization: it renders `segments`/`total` as given and never\ncomputes token counts, costs, or any other domain-specific estimate\nitself — the one exception is the plain arithmetic sum of the segment\nvalues used to build the accessible \"X of Y used\" summary below.\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**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The component's root wrapper (a `<div>` for `bar`, an `<svg>` for `ring`). |\n| `label` | The visible caption, when `label` is set. |\n| `legend` | The visible category key rendered below the meter when `showLegend` is set. `aria-hidden` in the default presentational mode, because `segment-list` already exposes the same names to assistive technology; reachable while `interactive` is set, where its rows are the filter controls themselves. |\n| `legend-item` | One swatch + label pair in the legend, one per `segments` entry. A `<button>` carrying `aria-pressed` while `interactive` is set, a plain `<span>` otherwise. |\n| `legend-item-disabled` | The legend row of a band whose entry sets `disabled`. |\n| `legend-item-empty` | The legend row of a band whose `value` is 0. Derived; no built-in treatment, exactly like `segment-empty`. |\n| `legend-label` | The text of a legend item (the segment's `label`). |\n| `legend-percent` | One legend row's share of `total`, rendered by `legendDisplay`'s `label-percent`/`label-value-percent` settings. Always the ratio the bar/ring actually paints. |\n| `legend-swatch` | The color chip of a legend item, painted from that segment's resolved `color`/`tone` — the same ladder and the same inline custom-property escape `segment` uses. |\n| `legend-value` | One legend row's absolute count, rendered by `legendDisplay`'s `label-value`/`label-value-percent` settings. |\n| `segment` | One occupied segment. Carries `data-tone` for styling and `--lr-context-meter-segment-color` when `color` is set. While `interactive` is set it is a `<button>` (bar) or a `role=\"button\"` arc (ring) carrying `aria-pressed`, and a second `segment-selected` part token while its index is in `selectedIndices`. |\n| `segment-disabled` | A band whose `segments` entry sets `disabled`. The control is genuinely disabled: no tab stop, no hover/press affordance, and activating it emits nothing. |\n| `segment-empty` | A band whose `value` is 0. Derived, not declared, and carries no built-in treatment: it is the hook for a consumer's own \"nothing in this bucket\" styling. A zero band stays actionable unless its entry also sets `disabled`. |\n| `segment-item` | One visually-hidden segment label/count pair. |\n| `segment-list` | The visually-hidden list exposing the segment breakdown. |\n| `semantic` | The visually-hidden meter/group carrying aggregate range semantics. |\n| `track` | The unfilled/empty capacity track. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-context-meter-disabled-opacity` (default: `var(--lr-opacity-disabled)`) — Opacity of a band or legend row whose `segments` entry sets `disabled`. The band keeps its own colour -- it is still the datum it always was -- and loses only the affordances that promise activation.\n- `--lr-context-meter-legend-swatch-size` (default: `var(--lr-size-0-625rem)`) — Inline and block size of a legend swatch.\n- `--lr-context-meter-segment-color` — Per-segment color. Set inline on `[part=\"segment\"]` by the component itself whenever that segment supplies a `color`; unset (and the token unread) otherwise, leaving the `data-tone` palette in charge. The matching `[part=\"legend-swatch\"]` reads the same property, so a swatch can never disagree with the band it stands for.\n- `--lr-context-meter-segment-seam-color` (default: `var(--lr-color-surface)`) — Color of the hairline seam painted between adjacent `bar`-shape segments.\n- `--lr-context-meter-selected-arc-stroke` (default: `16`) — Stroke width, in this component's `0 0 100 100` viewBox units, of a selected `ring`-shape arc. Arcs share one bounding box, so a selected arc reports itself by thickening in place rather than by an outline that would trace the whole ring.\n- `--lr-context-meter-selected-ring-color` (default: `var(--lr-color-text)`) — Colour of the inset ring marking a `bar`-shape band or a legend row whose index is in `selectedIndices`. Painted inside the shadow root because the state lives in the part name, and as a ring rather than an outline so it composes with the hover/press/focus outlines instead of being replaced by them.\n- `--lr-context-meter-selected-ring-width` (default: `var(--lr-border-width-thick)`) — Width of that selected ring.\n- `--lr-context-meter-track-bg` (default: `color-mix(in srgb, var(--lr-color-border) 30%, transparent)`) — Background of the unfilled remainder of the `bar`-shape track.\n- `--lr-context-meter-track-radius` (default: `calc(var(--lr-radius) * 0.5)`) — Corner radius of the `bar`-shape track.\n- `--lr-context-meter-track-size` (default: `var(--lr-size-0-5rem)`) — Block size (thickness) of the `bar`-shape track, and therefore of its filled segments.","attributes":[{"name":"interactive","description":"Opt-in filter mode: every band, and every legend row, becomes a real button that emits the\ncancelable `lr-segment-activate`.\n\nOff by default, and off is unchanged from before this property existed -- a pure part-to-whole\nvisualization whose visible parts are all `aria-hidden`. On, the bands are `<button>`s (the\nring's arcs carry `role=\"button\"`, since an SVG shape cannot be a native one), the legend\nleaves the accessibility tree's shadow and its rows become buttons too, and both carry explicit\n`aria-pressed` from `selectedIndices`. The visually-hidden `[part=\"segment-list\"]` steps aside\nin this mode: the buttons already expose the same label/count pairs, with the pressed state\nattached, so repeating them statically would announce every category twice.\n\nA pressed state rather than an event alone: a filter toggle that cannot be reported as on or\noff is unusable through assistive technology, whatever it looks like.\n\nA band's width IS its share, so a small band is a small pointer target. Pair `interactive` with\n`showLegend` where that matters -- the legend row is the same action at full row height.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"label","description":"Overall accessible label/caption, e.g. `\"128K context window\"`.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"legend-display","description":"What each legend row shows beside its swatch. `label` (the default) is exactly the output this\ncomponent has always produced. The other three add the segment's own count, its share of\n`total`, or both, as `[part=\"legend-value\"]`/`[part=\"legend-percent\"]` spans.\n\nThe share is the SAME clamped ratio the bar/ring paints, so a key can never disagree with the\nband it stands for, and it is formatted through `effectiveLocale`. Has no effect while\n`showLegend` is unset. Folding the number into `segment.label` instead would push it into the\nhover title and the visually-hidden breakdown too, where a screen reader would hear the count\ntwice.\n\nType: `ContextMeterLegendDisplay`  \nDefault: `'label'`","value":{"type":["'label'","'label-value'","'label-percent'","'label-value-percent'"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"shape","description":"Meter geometry. Foreign attribute values normalize to the default bar shape.\n\nType: `ContextMeterShape`","value":{"type":["'ring'","'bar'"]}},{"name":"show-legend","description":"Renders a static `[part=\"legend\"]` key below the meter — one swatch/label pair per `segments`\nentry, each swatch painted with that segment's resolved `color`/`tone`. Off by default.\n\nWithout it, the only place a segment's own label is exposed is a hover `title` (desktop-only,\nundiscoverable) and the visually-hidden breakdown list — so a meter split across more than two\nor three categories is legible to a screen-reader user but not to a sighted one, who has to\nhand-roll swatch+label markup outside the component. Non-interactive: it toggles nothing and\nemits nothing, mirroring `<lr-sequence-strip>`'s `showLegend` rather than the interactive\n`<lr-graph-legend>`.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"total","description":"The full capacity segments are measured against (e.g. a model's context window size).\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}}],"js":{"properties":[{"name":"interactive","description":"Opt-in filter mode: every band, and every legend row, becomes a real button that emits the\ncancelable `lr-segment-activate`.\n\nOff by default, and off is unchanged from before this property existed -- a pure part-to-whole\nvisualization whose visible parts are all `aria-hidden`. On, the bands are `<button>`s (the\nring's arcs carry `role=\"button\"`, since an SVG shape cannot be a native one), the legend\nleaves the accessibility tree's shadow and its rows become buttons too, and both carry explicit\n`aria-pressed` from `selectedIndices`. The visually-hidden `[part=\"segment-list\"]` steps aside\nin this mode: the buttons already expose the same label/count pairs, with the pressed state\nattached, so repeating them statically would announce every category twice.\n\nA pressed state rather than an event alone: a filter toggle that cannot be reported as on or\noff is unusable through assistive technology, whatever it looks like.\n\nA band's width IS its share, so a small band is a small pointer target. Pair `interactive` with\n`showLegend` where that matters -- the legend row is the same action at full row height.\n\nAttribute: `interactive`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"label","description":"Overall accessible label/caption, e.g. `\"128K context window\"`.\n\nAttribute: `label`","type":"string","default":"''"},{"name":"legendDisplay","description":"What each legend row shows beside its swatch. `label` (the default) is exactly the output this\ncomponent has always produced. The other three add the segment's own count, its share of\n`total`, or both, as `[part=\"legend-value\"]`/`[part=\"legend-percent\"]` spans.\n\nThe share is the SAME clamped ratio the bar/ring paints, so a key can never disagree with the\nband it stands for, and it is formatted through `effectiveLocale`. Has no effect while\n`showLegend` is unset. Folding the number into `segment.label` instead would push it into the\nhover title and the visually-hidden breakdown too, where a screen reader would hear the count\ntwice.\n\nAttribute: `legend-display`","type":"ContextMeterLegendDisplay","default":"'label'"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"segments","description":"Occupied segments, each an absolute quantity against `total` — never a percentage.","type":"readonly ContextMeterSegment[]","default":"[]"},{"name":"selectedIndices","description":"Indexes of the currently selected segments, rendered as `aria-pressed=\"true\"` plus a second\npart token -- `segment-selected` on the band, `legend-item-selected` on its legend row.\nMeaningful only while `interactive` is set.\n\nUncontrolled by default: an activation this component emits and nobody vetoes toggles the\nindex here itself. `preventDefault()` on `lr-segment-activate` suppresses that write, which is\nhow a consumer that owns the selection takes control -- the library's standard request/commit\nshape. Assigning the property directly always wins either way. A non-integer or out-of-range\nentry selects nothing rather than throwing.","type":"readonly number[]","default":"[]"},{"name":"shape","description":"Meter geometry. Foreign attribute values normalize to the default bar shape.\n\nAttribute: `shape`  \nReflected to its attribute.","type":"ContextMeterShape"},{"name":"showLegend","description":"Renders a static `[part=\"legend\"]` key below the meter — one swatch/label pair per `segments`\nentry, each swatch painted with that segment's resolved `color`/`tone`. Off by default.\n\nWithout it, the only place a segment's own label is exposed is a hover `title` (desktop-only,\nundiscoverable) and the visually-hidden breakdown list — so a meter split across more than two\nor three categories is legible to a screen-reader user but not to a sighted one, who has to\nhand-roll swatch+label markup outside the component. Non-interactive: it toggles nothing and\nemits nothing, mirroring `<lr-sequence-strip>`'s `showLegend` rather than the interactive\n`<lr-graph-legend>`.\n\nAttribute: `show-legend`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"total","description":"The full capacity segments are measured against (e.g. a model's context window size).\n\nAttribute: `total`","type":"number","default":"0"}],"events":[{"name":"lr-segment-activate","description":"A band or its legend row was activated while `interactive` is set. `detail: { index, label, value }`. Cancelable: the default action is this component toggling `index` in its own `selectedIndices`, so `preventDefault()` hands that state entirely to the consumer. Never emitted in the default presentational mode.","type":"CustomEvent<LyraContextMeterSegmentActivateDetail>"}]}},{"name":"lr-control-group","description":"`<lr-control-group>` — a responsive layout primitive for a row of mixed form\ncontrols and action buttons (e.g. a segmented metric switcher beside a compact\nselect and an export button in a dashboard toolbar). Unlike `<lr-button-group>`\n(a uniform-height row of `<lr-button>`s that stretches every child to the row's\nfull height), this centers children of differing intrinsic heights and does not\nassume any particular child type.\n\nThe group fills a host that has been given a definite inline size, unconditionally. A percentage\ninline size resolves as `auto` against a shrink-to-fit containing block, so that is a no-op for\nthe ordinary toolbar-in-a-flex-row case and only takes effect once an ancestor sizes the host --\nthe same unconditional-chain pattern `<lr-file-input>` uses.\n\n`container-type: inline-size` stays opt-in via `responsive`, because unconditionally applying it\nmade the group collapse to 0 inline size whenever it sat as an ordinary `flex-basis: auto` child\nof a shrink-to-fit flex row -- exactly this component's own toolbar-row use case. Setting it makes\nthe host a size-query container that the consumer's own `@container` rules can target from their\nslotted content; the component itself declares no breakpoint of its own.\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) | Form controls, buttons, or any other action content. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The group wrapper (`role=\"group\"`). |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-control-group-gap` (default: `var(--lr-space-xs)`) — Gap between grouped controls.","attributes":[{"name":"label","description":"Accessible-name fallback for the internal `role=\"group\"` element when the host has no\n`aria-label`; a present host attribute wins, including an explicitly empty value.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"responsive","description":"Makes the host a CSS size-query container, so a consumer's own `@container` rules can react to\nthis group's allocated width from their slotted content. The component declares no breakpoint\nof its own, and its fill behaviour does not depend on this.\n\nLeft unset (the default), the host uses `container-type: normal`, because\n`container-type: inline-size` forces this element's own auto/content-based inline size to be\ncomputed as if it had no content, which silently collapses it to 0 width whenever it sits as\nan ordinary (`flex-basis: auto`) child of a shrink-to-fit flex row — exactly this component's\nown stated primary use case (a toolbar row of mixed controls). Set `responsive` only when the\ngroup's own size instead comes from somewhere else (a percentage width, a grid track, a\nblock-level parent), where that failure mode does not apply.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"","description":"Form controls, buttons, or any other action content."}],"js":{"properties":[{"name":"label","description":"Accessible-name fallback for the internal `role=\"group\"` element when the host has no\n`aria-label`; a present host attribute wins, including an explicitly empty value.\n\nAttribute: `label`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"responsive","description":"Makes the host a CSS size-query container, so a consumer's own `@container` rules can react to\nthis group's allocated width from their slotted content. The component declares no breakpoint\nof its own, and its fill behaviour does not depend on this.\n\nLeft unset (the default), the host uses `container-type: normal`, because\n`container-type: inline-size` forces this element's own auto/content-based inline size to be\ncomputed as if it had no content, which silently collapses it to 0 width whenever it sits as\nan ordinary (`flex-basis: auto`) child of a shrink-to-fit flex row — exactly this component's\nown stated primary use case (a toolbar row of mixed controls). Set `responsive` only when the\ngroup's own size instead comes from somewhere else (a percentage width, a grid track, a\nblock-level parent), where that failure mode does not apply.\n\nAttribute: `responsive`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}]}},{"name":"lr-conversation-item","description":"`<lr-conversation-item>` — a selectable row representing one chat\nsession in a history sidebar list. Usable standalone or as the\n`renderItem()` payload of a sibling virtualized-list component; this\nmodule has no dependency on that (or any) other component.\n\nTakes `label`/`excerpt`/`timestamp` as individual primitive props rather\nthan one opaque bound object, deliberately consistent with how\n`<lr-chat-message>` takes individual props instead of a single\n`.message` blob -- every other component in this family follows that\nshape, so this one does too even though a single bound `.session` object\nwould also have been a reasonable design.\n\n`conversationId` is the stable domain identity carried by both selection and rename events;\nnative `id` remains available for document identity and CSS/ARIA references.\n\n`role=\"button\"` on `[part=\"select-button\"]` so the item has valid semantics both\nstandalone and when placed in a larger history-list layout. A conversation\nrow activates one current session; it is not itself a listbox option and\ntherefore does not require a particular owner role.\n\n`role=\"button\"` forbids focusable\ndescendants -- verified against axe-core's `nested-interactive` rule,\nwhich flags it. That's why the rename button and the `actions` slot are\nrendered as DOM *siblings* of `[part=\"select-button\"]` (both inside\n`[part=\"base\"]`) rather than nested inside it: `[part=\"select-button\"]` only ever\ncontains plain text/`<time>` content. The in-place rename `<input>` is the\nsame problem one level deeper -- it replaces the label *inside*\n`[part=\"select-button\"]` while renaming -- so `[part=\"select-button\"]` sheds its\n`role`/`tabindex`/`aria-current`/`aria-label` entirely for the duration\nof an edit. A row mid-edit is a text field, so suspending the button\nsemantics is also the more accurate\ndescription of what's on screen.\n\nInline rename is a dedicated pencil/edit icon button (not a double-click\non the label) -- double-click has no keyboard/screen-reader equivalent\nand would silently swallow the row's own single-click `lr-select`,\nwhereas a button is independently focusable, has its own accessible name,\nand composes cleanly with click-to-select.\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| `actions` | Overflow/icon-button controls (for example a pin/delete button or a `lr-menu` trigger) rendered at the trailing edge of the row. |\n| `content` | Replaces the built-in label, excerpt, and meta content area with host-supplied row content. Only non-focusable content should be slotted here because the selectable region owns `role=\"button\"`. |\n| `excerpt` | Full override of the excerpt presentation (e.g. a search-hit snippet with `<mark>` highlighting). Wins over the `excerpt` property whenever it has assigned content, even if `excerpt` is also set. Only non-focusable content should be slotted here — see the `excerpt` property's own doc for why. |\n| `meta` | Small, non-focusable structured fields for the row (e.g. a day label, cost, request count) rendered below the label/excerpt. Entirely app-supplied; this component computes none of it. Only non-focusable content should be slotted here, for the same `nested-interactive` reason as `excerpt`. |\n| `start` | Content such as an avatar, purpose icon, or status indicator, rendered inside the selectable region before the label/excerpt content. Only non-focusable content should be slotted here because the selectable region owns `role=\"button\"`. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `actions` | The wrapper around the `actions` slot. |\n| `active-indicator` | A decorative inline indicator rendered only while the row is active. |\n| `base` | The outer row wrapper (plain, no ARIA role) laying out `[part=\"select-button\"]`, the rename button, and `actions`. |\n| `content` | Wrapper around the label and excerpt. |\n| `excerpt` | The last-message preview snippet. Only rendered when `excerpt` is non-empty. |\n| `label` | The visible label, shown while not renaming. |\n| `label-input` | The in-place rename `<input>`, shown only while renaming. |\n| `meta` | The wrapper around the `meta` slot. Only rendered in the built-in content path (not when the `content` slot is used), and `hidden` while the `meta` slot is empty. |\n| `rename-button` | The pencil/edit affordance that starts a rename (only rendered while `renamable` and not already renaming). |\n| `select-button` | The selectable region (`role=\"button\"`, removed while renaming -- see the class doc). Wraps `content` and `timestamp`. |\n| `start` | The wrapper around the `start` slot, inside `select-button`. Always rendered, but `hidden` while the slot is empty. |\n| `timestamp` | The formatted `timestamp`, rendered in a `<time>` element. Only rendered when `timestamp` is set and valid. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-conversation-item-active-bg` (default: `var(--lr-color-brand-quiet)`) — Background of the row while `active`. **Contrast-sensitive:** it is one half of a documented WCAG-AA pair — the active row's text is sized/toned for this background, so an override has to keep at least a 4.5:1 ratio against `--lr-conversation-item-active-color` (excerpt/timestamp) and against `--lr-color-text` (the label, which is not restyled by the pair).\n- `--lr-conversation-item-active-color` (default: `var(--lr-color-text)`) — Text color of `[part=\"excerpt\"]` and `[part=\"timestamp\"]` while `active`. **Contrast-sensitive:** it exists precisely because `--lr-color-text-quiet` only reaches ~4.25:1 against the active background; override it together with `--lr-conversation-item-active-bg`, never alone.\n- `--lr-conversation-item-active-indicator-color` (default: `var(--lr-color-brand)`) — Color of the decorative `[part=\"active-indicator\"]` while `active`.\n- `--lr-conversation-item-active-indicator-inset-inline` (default: `0 auto`) — Logical inline-start and inline-end insets for `[part=\"active-indicator\"]`; set `auto 0` to place it at inline-end.\n- `--lr-conversation-item-active-indicator-width` (default: `var(--lr-size-2px)`) — Inline size of `[part=\"active-indicator\"]` while `active`.\n- `--lr-conversation-item-align` (default: `flex-start`) — Cross-axis alignment of `[part=\"base\"]` and `[part=\"select-button\"]`. `flex-start` (the default) suits the common multi-line row (a title plus an `excerpt`); `center` reads better for a reliably single-line row with a taller trailing action (e.g. `actions`), but is not the default because it would misalign every existing multi-line row's title against its own baseline.\n- `--lr-conversation-item-compact-gap` (default: `var(--lr-space-2xs)`) — Gap between `[part=\"base\"]`'s columns while `compact`.\n- `--lr-conversation-item-compact-padding` (default: `var(--lr-space-xs) var(--lr-space-s)`) — `[part=\"base\"]` padding while `compact`.","attributes":[{"name":"active","description":"Whether this is the currently-selected/open session. Drives the\nbrand-quiet background treatment.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"autocapitalize","description":"Forwarded to the in-place rename `<input>`'s own `autocapitalize`. Empty string omits the\nattribute (browser default).\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"autocorrect","description":"Native editing-assistance state forwarded as canonical `autocorrect=\"on\"|\"off\"`. String\nwrites are normalized for framework and plain-DOM interoperability; reads are boolean.\n\nType: `boolean`","value":{"type":["boolean"]}},{"name":"compact","description":"Tighter row padding and gaps, for the dense history sidebars these rows usually render in --\nsame convention as `lr-empty`'s `compact`. Defaults to `false`, i.e. the full row padding.\nPurely a density knob: it tightens `[part=\"base\"]`'s padding and gap and collapses\n`[part=\"content\"]`'s inter-line gap, and changes nothing else. In particular it does **not**\nshrink `[part=\"rename-button\"]` below the shared `--lr-icon-button-size` target floor, hide the\nexcerpt (bind `excerpt`/the `excerpt` slot per row for that), or reduce the excerpt/timestamp\nfont sizes -- so a row with a rename button or slotted `actions` still floors at roughly that\nicon size plus the compact padding.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"conversation-id","description":"Stable domain identity included in selection and rename request details.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"excerpt","description":"A short preview snippet of the last message. Omit for no excerpt line. Ignored entirely when the\n`excerpt` slot has assigned content — see that slot's own description. Only non-focusable\ncontent should be slotted there: `role=\"button\"` on `[part=\"select-button\"]` forbids focusable\ndescendants (axe's `nested-interactive` rule); an interactive control belongs in the `actions`\nslot instead.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"label","description":"The session's visible label. The inherited native `title` remains available for host tooltip\nsemantics and is not used as conversation content.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"renamable","description":"Whether inline-rename is available at all. When `false`, the rename\nbutton never renders and the row can never enter its editing state. If\nflipped to `false` while a rename is already open, the in-progress edit\nis cancelled (discarded, like Escape) rather than left committable.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"spellcheck","description":"Forwarded to the in-place rename `<input>`'s own `spellcheck`. Defaults to `true`, matching\nthe native element's own default. `spellcheck=\"false\"` is parsed as false.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}}],"slots":[{"name":"actions","description":"Overflow/icon-button controls (for example a pin/delete button or a `lr-menu` trigger) rendered at the trailing edge of the row."},{"name":"content","description":"Replaces the built-in label, excerpt, and meta content area with host-supplied row content. Only non-focusable content should be slotted here because the selectable region owns `role=\"button\"`."},{"name":"excerpt","description":"Full override of the excerpt presentation (e.g. a search-hit snippet with `<mark>` highlighting). Wins over the `excerpt` property whenever it has assigned content, even if `excerpt` is also set. Only non-focusable content should be slotted here — see the `excerpt` property's own doc for why."},{"name":"meta","description":"Small, non-focusable structured fields for the row (e.g. a day label, cost, request count) rendered below the label/excerpt. Entirely app-supplied; this component computes none of it. Only non-focusable content should be slotted here, for the same `nested-interactive` reason as `excerpt`."},{"name":"start","description":"Content such as an avatar, purpose icon, or status indicator, rendered inside the selectable region before the label/excerpt content. Only non-focusable content should be slotted here because the selectable region owns `role=\"button\"`."}],"js":{"properties":[{"name":"active","description":"Whether this is the currently-selected/open session. Drives the\nbrand-quiet background treatment.\n\nAttribute: `active`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"autocapitalize","description":"Forwarded to the in-place rename `<input>`'s own `autocapitalize`. Empty string omits the\nattribute (browser default).\n\nAttribute: `autocapitalize`","type":"string","default":"''"},{"name":"autocorrect","description":"Native editing-assistance state forwarded as canonical `autocorrect=\"on\"|\"off\"`. String\nwrites are normalized for framework and plain-DOM interoperability; reads are boolean.\n\nAttribute: `autocorrect`","type":"boolean"},{"name":"compact","description":"Tighter row padding and gaps, for the dense history sidebars these rows usually render in --\nsame convention as `lr-empty`'s `compact`. Defaults to `false`, i.e. the full row padding.\nPurely a density knob: it tightens `[part=\"base\"]`'s padding and gap and collapses\n`[part=\"content\"]`'s inter-line gap, and changes nothing else. In particular it does **not**\nshrink `[part=\"rename-button\"]` below the shared `--lr-icon-button-size` target floor, hide the\nexcerpt (bind `excerpt`/the `excerpt` slot per row for that), or reduce the excerpt/timestamp\nfont sizes -- so a row with a rename button or slotted `actions` still floors at roughly that\nicon size plus the compact padding.\n\nAttribute: `compact`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"conversationId","description":"Stable domain identity included in selection and rename request details.\n\nAttribute: `conversation-id`","type":"string","default":"''"},{"name":"excerpt","description":"A short preview snippet of the last message. Omit for no excerpt line. Ignored entirely when the\n`excerpt` slot has assigned content — see that slot's own description. Only non-focusable\ncontent should be slotted there: `role=\"button\"` on `[part=\"select-button\"]` forbids focusable\ndescendants (axe's `nested-interactive` rule); an interactive control belongs in the `actions`\nslot instead.\n\nAttribute: `excerpt`","type":"string","default":"''"},{"name":"formatTimestamp","description":"Overrides the default absolute-time rendering of `timestamp` when an application\nneeds a different timestamp style (mirrors `<lr-chat-message>`'s identical hook).","type":"(date: Date) => string | undefined"},{"name":"label","description":"The session's visible label. The inherited native `title` remains available for host tooltip\nsemantics and is not used as conversation content.\n\nAttribute: `label`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"renamable","description":"Whether inline-rename is available at all. When `false`, the rename\nbutton never renders and the row can never enter its editing state. If\nflipped to `false` while a rename is already open, the in-progress edit\nis cancelled (discarded, like Escape) rather than left committable.\n\nAttribute: `renamable`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"spellcheck","description":"Forwarded to the in-place rename `<input>`'s own `spellcheck`. Defaults to `true`, matching\nthe native element's own default. `spellcheck=\"false\"` is parsed as false.\n\nAttribute: `spellcheck`","type":"boolean","default":"true"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"timestamp","description":"When the session was last active. Accepts a `Date` or anything\n`new Date()` can parse (e.g. an ISO 8601 string); invalid input is\ntreated the same as unset (no timestamp rendered) -- mirrors\n`<lr-chat-message>`'s identical `timestamp` prop.","type":"LyraTimestamp | undefined"}],"events":[{"name":"blur","description":"Re-dispatched from the in-place rename input as a bubbling, composed event.","type":"CustomEvent<null>"},{"name":"focus","description":"Re-dispatched from the in-place rename input as a bubbling, composed event.","type":"CustomEvent<null>"},{"name":"lr-rename","description":"An in-place rename was committed (Enter, or blur while editing). `detail: { conversationId, label }`. Does not mutate `label` itself -- this is a controlled component, the same convention `<lr-chat-message>` follows by not clearing its own state on retry; the consumer applies the new label once it's actually persisted. Not fired when the trimmed draft is empty or unchanged from the original `label` (that's treated as an implicit cancel).","type":"CustomEvent<ConversationItemRenameDetail>"},{"name":"lr-select","description":"The row was activated: a click on `[part=\"select-button\"]` (i.e. outside the rename button and the `actions` slot), or Enter/Space while it's focused -- in both cases only while not currently renaming. `detail: { conversationId }`.","type":"CustomEvent<ConversationItemSelectDetail>"}]}},{"name":"lr-copy-button","description":"`<lr-copy-button>` — a standalone icon-only copy-to-clipboard affordance for a plain\nsingle/multi-line text value in a layout the consumer controls (e.g. absolutely positioned in\nthe corner of an `lr-textarea` or a read-only output field). Unlike `lr-code-block`'s or\n`lr-json-viewer`'s own built-in copy buttons, this takes no positioning opinion of its own and\nhas no code/JSON content model to adopt just to reuse the copy affordance.\n\nWhen `from` is set it takes precedence over `value`: an element id copies `textContent`,\n`id[attribute]` copies an attribute, and `id.property` copies a property. An empty value, a\nmissing source, or a rejected Clipboard API call enters the error state. Native `dir` and\n`lang` remain inherited global attributes. Renderer bookkeeping and manifest-inferred form\nmetadata are deliberately not component properties; this control is not form-associated.\n\nThe confirmation state is only entered once the clipboard write actually resolves; a rejected\nwrite (denied permission, insecure context, unfocused document) renders a distinct failure\nglyph, announces itself through the live region, and emits both `lr-error` and the retained,\ndetailed `lr-copy-error` alias.\n\nThis trigger has no `size` property of its own: it composes `<lr-icon-button>`, so the built-in\ntrigger's hit area is that component's shared `--lr-icon-button-size` floor (2.5rem/40px), same\nas everywhere else in the library. For a dense action row (e.g. several copy buttons packed into\na toolbar) where 40px is more than the layout can afford, lower `--lr-icon-button-size-scope`\n(the subtree-scoped input) or `--lr-theme-icon-button-size` (the application-wide one) -- NOT\n`--lr-icon-button-size` itself, which every `LyraElement` re-declares on its own `:host` and so\nnever reaches a composed child (`internal/tokens.test.ts` proves this) -- on this element or\nany ancestor of it; `::part(base__control)` also reaches the same composed native control\ndirectly for a one-off override. Either way the shrink is local to the elements it targets, not\na library-wide floor change. A coarse-pointer/no-hover safety net (`internal/tokens.styles.ts`'s\n`baseTokens`) then floors the rendered hit area back at 2.75rem/44px regardless of how far the\ndense-row override lowered it, so an intentionally cramped desktop toolbar is still comfortably\ntappable the moment the pointer reaching it is a finger rather than a mouse.\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) | A custom trigger. When present, it replaces the built-in icon button. |\n| `copy-icon` | Resting copy icon for the built-in button. |\n| `error-icon` | Failure icon for the built-in button. |\n| `success-icon` | Confirmation icon for the built-in button. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The built-in trigger, which is a composed `<lr-icon-button>` rather than this component's own `<button>` as of 16.0.0. It still owns the accessible name, the activation and every part token below; its paint (background, radius, hover/press mixes, focus ring, hit-area floor) now comes from `<lr-icon-button>`'s own `--lr-icon-button-*` contract, so a rule that set `background`/`border`/`padding` through `::part(base)` must move to `base__control` or to the token. |\n| `base-error` | The trigger while the failure state is showing. |\n| `base-success` | The trigger while the copied confirmation is showing. |\n| `base__control` | The composed `<lr-icon-button>`'s own native control, forwarded so the painted surface stays reachable across the extra shadow boundary. |\n| `button` | Mapped alias for `base` on the same composed trigger. |\n| `copy-icon` | The resting copy glyph. |\n| `error-icon` | The failure glyph. |\n| `feedback` | Visually hidden, `aria-hidden` mirror of the outcome text. The announcement uses the shared light-DOM polite region because live regions inside shadow roots are not reliable; style the composed tooltip through its `tooltip__*` parts. |\n| `success-icon` | The confirmation glyph. |\n| `tooltip__base` | The nested tooltip's base wrapper. |\n| `tooltip__base__arrow` | The nested tooltip's arrow. |\n| `tooltip__base__popup` | The nested tooltip's popup wrapper. |\n| `tooltip__body` | The nested tooltip's content wrapper. |\n\n---\n\n**CSS Custom Properties**\n\n- `--error-color` (default: `var(--lr-color-danger)`) — Error-state icon color.\n- `--success-color` (default: `var(--lr-color-success)`) — Success-state icon color.","attributes":[{"name":"aria-label","description":"Accessible name forwarded from the host to the internal button. When unset or blank, the\nlocalized Copy/Copied/failure state provides the name so the icon-only trigger never becomes\nunnamed.\n\nType: `string | null`  \nDefault: `null`"},{"name":"copy-label","description":"Accessible name and resting tooltip text. Empty uses the localized Copy string.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"disabled","description":"Prevent activation and remove the internal button from the tab order.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"error-label","description":"Failure accessible name and tooltip text. Empty uses the localized failure string.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"feedback-duration","description":"How long, in milliseconds, the copied confirmation or failure state remains visible.\n\nType: `number`  \nDefault: `1000`","value":{"type":["number"]}},{"name":"from","description":"Id-based source expression. Takes precedence over `value`; supports `id`, `id[attr]`, and\n`id.property`.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"hoist","description":"Use fixed positioning for the tooltip so it can escape clipped containers.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"success-label","description":"Confirmation accessible name and tooltip text. Empty uses the localized Copied string.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"tooltip","description":"Tooltip behavior: normal hover/focus plus feedback, feedback only, or disabled.\n\nType: `LyraCopyButtonTooltip`  \nDefault: `'full'`","value":{"type":["'full'","'copy'","'none'"]}},{"name":"tooltip-placement","description":"Side on which the tooltip appears.\n\nType: `LyraCopyButtonTooltipPlacement`  \nDefault: `'top'`","value":{"type":["'top'","'right'","'bottom'","'left'"]}},{"name":"value","description":"The plain text to copy.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"slots":[{"name":"","description":"A custom trigger. When present, it replaces the built-in icon button."},{"name":"copy-icon","description":"Resting copy icon for the built-in button."},{"name":"error-icon","description":"Failure icon for the built-in button."},{"name":"success-icon","description":"Confirmation icon for the built-in button."}],"js":{"properties":[{"name":"accessibleLabel","description":"Accessible name forwarded from the host to the internal button. When unset or blank, the\nlocalized Copy/Copied/failure state provides the name so the icon-only trigger never becomes\nunnamed.\n\nAttribute: `aria-label`","type":"string | null","default":"null"},{"name":"copyLabel","description":"Accessible name and resting tooltip text. Empty uses the localized Copy string.\n\nAttribute: `copy-label`","type":"string","default":"''"},{"name":"disabled","description":"Prevent activation and remove the internal button from the tab order.\n\nAttribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"errorLabel","description":"Failure accessible name and tooltip text. Empty uses the localized failure string.\n\nAttribute: `error-label`","type":"string","default":"''"},{"name":"feedbackDuration","description":"How long, in milliseconds, the copied confirmation or failure state remains visible.\n\nAttribute: `feedback-duration`","type":"number","default":"1000"},{"name":"from","description":"Id-based source expression. Takes precedence over `value`; supports `id`, `id[attr]`, and\n`id.property`.\n\nAttribute: `from`","type":"string","default":"''"},{"name":"hoist","description":"Use fixed positioning for the tooltip so it can escape clipped containers.\n\nAttribute: `hoist`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"role","type":"string","default":"'group'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"successLabel","description":"Confirmation accessible name and tooltip text. Empty uses the localized Copied string.\n\nAttribute: `success-label`","type":"string","default":"''"},{"name":"tooltip","description":"Tooltip behavior: normal hover/focus plus feedback, feedback only, or disabled.\n\nAttribute: `tooltip`  \nReflected to its attribute.","type":"LyraCopyButtonTooltip","default":"'full'"},{"name":"tooltipPlacement","description":"Side on which the tooltip appears.\n\nAttribute: `tooltip-placement`  \nReflected to its attribute.","type":"LyraCopyButtonTooltipPlacement","default":"'top'"},{"name":"value","description":"The plain text to copy.\n\nAttribute: `value`","type":"string","default":"''"}],"events":[{"name":"lr-copy","description":"Clipboard writing fulfilled. The frozen shared outcome detail is `{ ok: true, text }`. Failed writes emit `lr-copy-error` instead.","type":"CustomEvent<LyraClipboardWriteSuccess>"},{"name":"lr-copy-error","description":"Source resolution or clipboard writing failed. The frozen detail is `{ ok: false, text, reason, error }`, where `reason` is `'unsupported' | 'denied' | 'failed'` and `error` is the platform error (a `DOMException` for a real rejection) or a component-created source error. Retained as a richer Lyra compatibility alias for `lr-error`.","type":"CustomEvent<LyraClipboardWriteFailure>"},{"name":"lr-error","description":"The source could not be resolved or clipboard writing failed. A bubbling, composed, non-cancelable `CustomEvent` with no detail, matching the mapped notification.","type":"CustomEvent<null>"},{"name":"lr-toolbar-actions-change","description":"The logical action exposed to a parent toolbar changed its disabled state or backing trigger. Bubbling, composed, and non-cancelable.","type":"Event"}]}},{"name":"lr-csv-viewer","description":"Fetches CSV text, parses quoted fields with PapaParse, and virtualizes its rows.\n\nAdopts `DocumentAnchorTarget`: a `cell-range` anchor addresses the raw file grid, 1-based, with\nthe header row included whenever `has-header-row` is set (matching how a spreadsheet app itself\nlabels `A1`) -- `scrollToAnchor()` scrolls the addressed row into view via the virtualized list's\n`active-item-id`, then scrolls the first addressed column horizontally into view. A `sheet`-qualified\nanchor never resolves here -- this viewer has no sheets. `highlights` paint as a\n`part=\"cell-highlight\"` structural cell wrapping a native `part=\"cell-highlight-action\"` button\non membership, recomputed per row inside `renderRow()` so a row scrolled out and back in\nreconstructs its highlight for free, with no persistent DOM to keep in sync.\n`search()` is a locale-aware case-insensitive substring match over the same stringified cell\nvalues `cell()` already renders, ordered row then column.\n\nA quote-aware structural scan enforces the 10,000-raw-row, 1,000-column, 1,000,000-cell, and\n100-diagnostic ceilings before PapaParse can materialize an amplified result. The peer then runs\nwith streaming row callbacks and the same limits as a second boundary.\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| `anchor-live-region` | The aria-hidden, non-live shadow mirror of the latest anchor-jump message. |\n| `base` | The root wrapper with explicit `aria-busy` loading state. |\n| `body` | The wrapper around the fetched-state content, capped by `max-height`; the nested virtual-list remains the data-row scrollport within that allocation. |\n| `cell` | One rendered cell. |\n| `cell-highlight` | A structural cell covered by a `highlights` entry. |\n| `cell-highlight-action` | The native button filling a highlighted cell; emits `lr-highlight-activate` when activated. Its accessible name localizes the complete cell-value and annotation message through separate `{value}` and `{label}` placeholders. |\n| `data-row` | One virtualized data row. |\n| `error` | The error message region. |\n| `header-row` | The persistent header above the virtualized row scrollport, rendered while `has-header-row` is set. |\n| `rows` | The virtualized row list. |\n| `sheet` | The named `role=\"table\"` wrapper around the header row and virtualized body. |\n| `spinner` | The visible tokenized loading treatment and ordinary text label. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-csv-viewer-highlight-color` (default: `var(--lr-color-brand)`) — Outline color of a highlighted cell. The active highlight changes a private warning-color default; an inherited or direct public value remains authoritative.\n- `--lr-csv-viewer-max-height` (default: `none`) — Maximum block size allocated to `[part=\"body\"]`; the nested virtual-list scrolls data rows within the remainder below the persistent header. The `maxHeight` property sets this token inline on `[part=\"base\"]`.","attributes":[{"name":"active-highlight-id","description":"Id of the currently active highlight, or null when none is active.\n\nType: `string | null`  \nDefault: `null`"},{"name":"has-header-row","description":"Whether the first parsed row is rendered as a sticky header.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max-height","description":"A CSS `max-height`; invalid values are ignored.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"name","description":"Source filename or display name used on the shadow viewer owner when host `aria-label` is\nabsent. A non-empty host label remains on the host; an explicitly empty one is preserved on\nthe shadow owner.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"src","description":"URL to fetch and parse.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"js":{"properties":[{"name":"activeHighlightId","description":"Id of the currently active highlight, or null when none is active.\n\nAttribute: `active-highlight-id`","type":"string | null","default":"null"},{"name":"anchor","description":"Anchor or highlight id to resolve and scroll into view.","type":"LyraAnchor | string | null","default":"null"},{"name":"anchorKinds","description":"Anchor kinds this viewer resolves via `scrollToAnchor()`.","type":"readonly LyraAnchorKind[]","default":"['cell-range']","read-only":true},{"name":"hasHeaderRow","description":"Whether the first parsed row is rendered as a sticky header.\n\nAttribute: `has-header-row`","type":"boolean","default":"true"},{"name":"highlights","description":"Highlights rendered by the document target. Reassign after mutation.","type":"LyraHighlight[]","default":"[]"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"maxHeight","description":"A CSS `max-height`; invalid values are ignored.\n\nAttribute: `max-height`","type":"string","default":"''"},{"name":"name","description":"Source filename or display name used on the shadow viewer owner when host `aria-label` is\nabsent. A non-empty host label remains on the host; an explicitly empty one is preserved on\nthe shadow owner.\n\nAttribute: `name`","type":"string","default":"''"},{"name":"src","description":"URL to fetch and parse.\n\nAttribute: `src`","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-anchor-result","description":"Fired after an `anchor` property assignment or a `scrollToAnchor()` call is applied. `detail: { found }`.","type":"CustomEvent<AnchorResultDetail>"},{"name":"lr-highlight-activate","description":"A `highlights` cell was clicked, or activated via Enter/Space while focused. `detail: { highlightId }`.","type":"CustomEvent<HighlightActivateDetail>"},{"name":"lr-render-error","description":"Fired when fetching or parsing fails, a parser is unavailable, the bounded parse exceeds a resource ceiling, or PapaParse returns recoverable diagnostics.","type":"CustomEvent<{ error: unknown }>"},{"name":"lr-search-change","description":"Fired whenever the search query, match count, or active match index changes, including source-reset and effective-locale re-evaluation. `detail: { query, matchCount, matchCountExact, activeIndex }`. Search accepts at most 4,096 query code units, scans at most 4,000,000 cell code units, and retains at most 1,000 matches; `matchCountExact=false` identifies a ceiling-truncated lower bound.","type":"CustomEvent<LyraSearchChangeDetail>"}]}},{"name":"lr-dashboard-grid","description":"`<lr-dashboard-grid>` — a responsive, keyboard-accessible widget grid: positions `layout`\nentries (`LyraDashboardCell`: `x`/`y`/`w`/`h` grid units + a widget descriptor) on a CSS Grid,\ncomposing `<lr-widget>` + `<lr-widget-renderer>` for each cell's default content, and owns all\ndrag/resize/collision interaction as controlled events -- it never mutates `layout` itself, nor\never touches `localStorage`/network; the host applies (or ignores) every emitted event and owns\npersistence entirely, mirroring `lr-flow-canvas`/`lr-table`'s own controlled-component\nconvention. Readonly (viewer) by default; opt into editor gestures individually via\n`cells-draggable`/`cells-resizable`, or lock the whole grid via `locked`.\n\nCell content: a `layout` entry with no matching light-DOM child (matched by `cell-id`) gets a\ndefault `<lr-widget label=\"...\">` wrapping a version-two `<lr-widget-renderer>` document\nauto-created and adopted into `slot=\"cell-{cellId}\"` -- this component's own job is the grid\nlayout/drag/resize/collision/persistence-event mechanics *around* that content, not widget\nrendering itself (see `lr-widget-renderer`'s own doc for its declarative-tree contract). A\nconsumer wanting full control over one cell's markup can instead author\n`<div cell-id=\"...\">...</div>` as a direct child; it is adopted in place of the default cell.\n\nKeyboard: cells share one roving tabindex in row-major spatial order. Arrow\nkeys/Home/End move the roving focus (RTL-aware: physical Left/Right always match what the\ncursor visually does, matching `lr-flow-canvas`'s own convention). While a cell has focus,\nCtrl/Cmd+Arrow moves it by one grid unit and Ctrl/Cmd+Shift+Arrow resizes it by one grid unit\n(Right/Down grow, Left/Up shrink) -- the full keyboard-operable equivalent of the pointer\ndrag/resize gestures below, per this library's accessibility bar (no pointer-only interaction).\n\nCollision: every move/resize request -- pointer or keyboard -- is resolved through `collision`\n(`'reject'` the default, `'push'`, or `'overlap'`; see `resolveLyraDashboardPlacement()` for\nthe exact rule). A rejected request leaves `layout` untouched and announces immediately. An\naccepted request emits `lr-cell-move`/`lr-cell-resize` plus a `lr-layout-change` snapshot of the full\nproposed layout (including any `'push'` cascade) -- the host's one persistence hook: listen for\nit and persist `event.detail.layout` however it likes (`localStorage`, a network call, neither).\nSuccess is announced only after a controlled `layout` assignment applies the requested target\ngeometry; a host that ignores a request produces no false move/resize confirmation.\nPointer movement snaps to the rendered track-plus-gutter pitch, including public CSS column,\nrow-height, and gap overrides in either text direction.\n\nResponsive: below a ~40rem container allocation (`@container`, not the viewport -- a dashboard\ngrid is commonly embedded in a panel of varying width), cells stack into a single flowing\ncolumn in the same row-major order the grid itself renders them in, instead of overflowing or\nshrinking columns unreadably. A cell that currently owns a resize handle retains the shared\ninteractive-action block-size floor, so the absolute handle cannot overlap the preceding cell\nor gap when consumer-authored content is shorter than the handle. Host, grid, cell, and slotted\ncustom-content boundaries all permit intrinsic shrinkage and inherit `overflow-wrap: anywhere`,\nso an unbroken direct text run cannot widen the stack; a consumer-owned scrollport can still\nopt into `overflow: auto`/`white-space: nowrap` and contains its own extent.\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**Slots**\n\n| Name | Description |\n| --- | --- |\n| `cell-{cellId}` | A `layout` entry's cell content; auto-populated by a default composed `<lr-widget>`/`<lr-widget-renderer>` pair unless a light-DOM `[cell-id=\"{cellId}\"]` child is authored instead. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The grid root. |\n| `cell` | A single cell's positioned wrapper. |\n| `empty` | The `lr-empty` shown when `layout` is empty. |\n| `live-region` | The `aria-hidden` mirror of the current move/resize/collision announcement. Rejections announce immediately; accepted moves/resizes announce after the host applies matching controlled `layout`. Spoken copy reaches the shared light-DOM polite sink only while the grid and all composed ancestors remain exposed to the accessibility tree. |\n| `resize-handle` | The pointer resize grip in a cell's trailing/bottom corner (only rendered while `cells-resizable`); the Ctrl/Cmd+Shift+Arrow keyboard path is the resize handle's full accessible equivalent, so the handle itself is `aria-hidden`. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-dashboard-grid-cell-hover-outline-color` (default: `var(--lr-color-border-strong)`) — Outline color of a cell's mouse-hover preview of its own `:focus-visible` ring (shown because every cell is a real focusable, draggable/resizable target). Set to `transparent` to opt out.\n- `--lr-dashboard-grid-collision-outline-color` (default: `var(--lr-color-danger)`) — Outline color of a cell whose current drag/resize preview collides with another cell.\n- `--lr-dashboard-grid-columns` (default: `12`) — Author override for the column count; otherwise the normalized `columns` property supplies the computed value.\n- `--lr-dashboard-grid-gap` (default: `8px`) — Author override for the gap between cells; otherwise the normalized `gap` property supplies a pixel value.\n- `--lr-dashboard-grid-interaction-shadow` (default: `var(--lr-shadow-m)`) — Box shadow applied to a cell for the duration of its pointer drag or resize interaction.\n- `--lr-dashboard-grid-row-height` (default: `80px`) — Author override for row track height; otherwise the normalized `rowHeight` property supplies a pixel value.","attributes":[{"name":"aria-label","description":"Overrides the grid region's accessible name; falls back to a generic localized label. Fed\nonly by a host `aria-label`, matching `lr-flow-canvas`'s own host-override pattern.\n\nType: `string | null`  \nDefault: `null`"},{"name":"cells-draggable","description":"Opts into pointer-drag + Ctrl/Cmd+Arrow keyboard move for unlocked cells.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"cells-resizable","description":"Opts into the pointer resize handle + Ctrl/Cmd+Shift+Arrow keyboard resize for unlocked cells.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"collision","description":"How a move/resize that would overlap another cell is resolved. Foreign runtime values\nnormalize to the safe `reject` policy.\n\nType: `LyraDashboardCollisionPolicy`","value":{"type":["'reject'","'push'","'overlap'"]}},{"name":"columns","description":"Column count of the underlying CSS Grid.\n\nType: `number`  \nDefault: `12`","value":{"type":["number"]}},{"name":"gap","description":"Gap between cells, in px, on both axes.\n\nType: `number`  \nDefault: `8`","value":{"type":["number"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locked","description":"Disables every drag/resize gesture grid-wide, regardless of `cells-draggable`/\n`cells-resizable` or a cell's own `locked`.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"row-height","description":"Row track height, in px (also the pointer-resize/drag row snap pitch, together with `gap`).\n\nType: `number`  \nDefault: `80`","value":{"type":["number"]}}],"slots":[{"name":"cell-{cellId}","description":"A `layout` entry's cell content; auto-populated by a default composed `<lr-widget>`/`<lr-widget-renderer>` pair unless a light-DOM `[cell-id=\"{cellId}\"]` child is authored instead."}],"js":{"properties":[{"name":"accessibleLabel","description":"Overrides the grid region's accessible name; falls back to a generic localized label. Fed\nonly by a host `aria-label`, matching `lr-flow-canvas`'s own host-override pattern.\n\nAttribute: `aria-label`","type":"string | null","default":"null"},{"name":"cellsDraggable","description":"Opts into pointer-drag + Ctrl/Cmd+Arrow keyboard move for unlocked cells.\n\nAttribute: `cells-draggable`","type":"boolean","default":"false"},{"name":"cellsResizable","description":"Opts into the pointer resize handle + Ctrl/Cmd+Shift+Arrow keyboard resize for unlocked cells.\n\nAttribute: `cells-resizable`","type":"boolean","default":"false"},{"name":"collision","description":"How a move/resize that would overlap another cell is resolved. Foreign runtime values\nnormalize to the safe `reject` policy.\n\nAttribute: `collision`","type":"LyraDashboardCollisionPolicy"},{"name":"columns","description":"Column count of the underlying CSS Grid.\n\nAttribute: `columns`","type":"number","default":"12"},{"name":"gap","description":"Gap between cells, in px, on both axes.\n\nAttribute: `gap`","type":"number","default":"8"},{"name":"layout","description":"The grid's immutable, bounded cell snapshot. Assign a new readonly collection to update it;\nevery move/resize remains a request event that the host applies or ignores, and success is\nannounced only when this controlled round trip contains the requested target geometry.\nInvalid records are skipped and duplicate ids use the first valid occurrence.","type":"readonly LyraDashboardCell[]"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"locked","description":"Disables every drag/resize gesture grid-wide, regardless of `cells-draggable`/\n`cells-resizable` or a cell's own `locked`.\n\nAttribute: `locked`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"rowHeight","description":"Row track height, in px (also the pointer-resize/drag row snap pitch, together with `gap`).\n\nAttribute: `row-height`","type":"number","default":"80"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-cell-move","description":"`detail: { cellId, position, previous }` — an accepted move request.","type":"CustomEvent<LyraDashboardCellMoveDetail>"},{"name":"lr-cell-resize","description":"`detail: { cellId, size, previous }` — an accepted resize request.","type":"CustomEvent<LyraDashboardCellResizeDetail>"},{"name":"lr-collision","description":"`detail: { cellId, collidedCellIds, policy, accepted }` — a move/resize request overlapped at least one other cell, regardless of whether `policy` ultimately accepted it.","type":"CustomEvent<LyraDashboardCollisionDetail>"},{"name":"lr-layout-change","description":"`detail: { layout }` — the full proposed layout after any accepted move/resize (including a `'push'` cascade); the host's persistence hook.","type":"CustomEvent<LyraDashboardLayoutChangeDetail>"}]}},{"name":"lr-data-grid","description":"`<lr-data-grid>` — a virtualized data grid for client or server data, with sorting, filtering,\ngrouping, trees, paging, pinning, resizing, reordering, selection, copying, and CSV export.\nMirrors the public `<wa-data-grid>` surface under the `lr-` prefix.\n\nArrays are shallow-reactive: reassign `data`, `columns`, and controlled state arrays after\nchanging them. Set `label` or a host `aria-label` to name the internal grid. Initial declarative\nloading stays silent; each later transition into loading appends the localized loading text to\nthe document's shared light-DOM polite sink while the visible overlay remains non-live. Public\ncollections are clone-owned readonly snapshots. Nested rows are projected iteratively with a\n10,000-node/64-descendant-level budget and a localized limit notice. Column identities use a\nnonblank `id`, then a nonblank `field`, then stable definition-object occurrence; blank and\nlater-duplicate identities are omitted first-wins. With `rowKey`, malformed, blank, and later\nduplicate row identities are omitted first-wins; without it, row object occurrence is stable\nacross reorder. `selectedRowKeys`/`expandedRowKeys` are the canonical controlled fields, while\nmirrored `selectedKeys`/`expandedKeys` remain compatibility aliases.\nThe filter, all-columns, and per-column disclosures are mutually exclusive and register with\nthe shared topmost overlay router; Escape closes the active disclosure and returns focus to its\ntrigger.\nPagination uses one page-local ARIA row model in client and server modes: the header occupies\nrow one, current-page display and expanded-detail rows start at row two, and `aria-rowcount`\ncovers that current page plus the header. A server `total` drives `pageCount` and the pager but\ndoes not inflate `aria-rowcount` without corresponding dataset-global `aria-rowindex` values.\n\nA separate `error` state reports a failed load: while `error` is set, the body's single row\nbecomes the built-in failed-load `<lr-empty>` (the same `error`-prefixed exported parts and\n`[part='retry-button']` as `<lr-table>`), behind its own `error` slot -- `<thead>`/toolbar/pager\nstay mounted around it. `loading` beats `error` beats every empty/no-columns/no-results branch,\nmatching `<lr-table>`'s own precedence. `error` is host-controlled, exactly like `<lr-table>`'s:\nthe internal `dataSource` request cycle's own `lr-data-error` does NOT set it, since that event's\nown contract keeps prior rows rendered on a rejection -- a consumer that wants this specific\nfailure to replace the row content instead sets `error = true` from its own `lr-data-error`\nlistener.\n\n---\n\n**Component metadata**\n\n- Status: `experimental`\n- Since: `4.0.0`\n- Rationale: This implementation reinstates an earlier Lyra tag with the experimental Web Awesome 3.11 public surface and remains experimental while production usage is gathered.\n- Graduation: Eligible for stable status once the mapped public surface, populated accessibility states, cross-browser behavior, and virtualization edge cases demonstrate sustained reliability.\n\n---\n\n**Slots**\n\n| Name | Description |\n| --- | --- |\n| `empty` | Content rendered when the source has no rows. |\n| `error` | Replaces the built-in failed-load state, including its retry button, while `error` is set. |\n| `loading` | Content rendered over the grid while data is loading. |\n| `no-results` | Content rendered when active search or filters match no rows. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `body` | The sole vertical and horizontal scroll viewport; header and footer columns mirror its logical inline position. |\n| `cell` | A data cell. |\n| `column-menu` | A per-column menu. |\n| `column-menu-button` | A per-column menu trigger. |\n| `columns-menu` | The all-columns visibility menu: the composed `<lr-dropdown>` itself, whose trigger and `role=\"menuitemcheckbox\"` rows are its own children. It replaced a hand-rolled toggle button plus an inline `role=\"group\"` checkbox panel, so a rule written against that former structure (`::part(columns-menu) > button`, a descendant `input[type=checkbox]`) no longer matches. |\n| `data-grid` | The outer data-grid container. |\n| `drag-ghost` | Preview shown while a column is dragged. |\n| `ellipsis` | Omitted-page indicator in the pager. |\n| `empty` | Empty-data state. |\n| `error` | The built-in `<lr-empty>` host rendered while `error` is set. |\n| `error-actions` | Exported from the built-in error `<lr-empty>`'s `actions` part. |\n| `error-base` | Exported from the built-in error `<lr-empty>`'s own `base` part. |\n| `error-cell` | The cell inside `error-row` that holds the failed-load content. |\n| `error-description` | Exported from the built-in error `<lr-empty>`'s `description` part. |\n| `error-heading` | Exported from the built-in error `<lr-empty>`'s `heading` part. |\n| `error-icon` | Exported from the built-in error `<lr-empty>`'s `icon` part. |\n| `error-row` | The single full-width row that replaces the body content while `error` is set. |\n| `expand-button` | A tree/detail/group expand control. |\n| `filter-button` | A column filter trigger. |\n| `filter-panel` | The active column filter editor. |\n| `filter-panel-clear` | The button that clears the active column filter editor's value, replacing the native search-cancel glyph suppressed by its own reset; rendered only while it has a value. |\n| `first-button` | First-page button. |\n| `first-icon` | The first-page directional icon. |\n| `footer` | Footer container. |\n| `footer-cell` | A footer cell. |\n| `footer-row` | Footer row. |\n| `group-count` | Number of rows in a group. |\n| `group-row` | A grouped row. |\n| `group-value` | Group value and disclosure control. |\n| `header` | Header row. |\n| `header-cell` | A column header cell. |\n| `last-button` | Last-page button. |\n| `last-icon` | The last-page directional icon. |\n| `live-region` | The visually-hidden, `aria-hidden` mirror of the last polite announcement. The announcement itself lands in the shared light-DOM polite region (`acquireAnnouncementSink()` in `internal/announcer.ts`), because a live region inside a shadow root is not reliably announced; this part is a styling/inspection surface only. |\n| `loading-overlay` | Visible, non-live loading-state overlay. The grid carries `aria-busy`; post-mount loading announcements use the shared light-DOM polite sink. |\n| `next-button` | Next-page button. |\n| `next-icon` | The next-page directional icon. |\n| `no-results` | No-filter-results state. |\n| `page` | A numbered page button. |\n| `page-current` | The current numbered page button. |\n| `page-size` | Page-size selector. |\n| `pager` | Pagination controls. |\n| `pager-button` | Shared part for every pager button. |\n| `pin-indicator` | Pinned-column edge marker. |\n| `previous-button` | Previous-page button. |\n| `previous-icon` | The previous-page directional icon. |\n| `resize-handle` | Pointer and keyboard column resize handle. |\n| `retry-button` | The built-in retry control rendered into the error state's `actions`. |\n| `row` | A data row. |\n| `row-detail` | Expanded detail content. |\n| `search` | Global row-search input. |\n| `search-clear` | The button that clears the global row-search input, replacing the native search-cancel glyph suppressed by its own reset; rendered only while it has a value. |\n| `search-wrapper` | The row wrapper around `search` and `search-clear`. |\n| `select-all-checkbox` | Current-page select-all checkbox. |\n| `sort-indicator` | Current sort-direction indicator. |\n| `sort-number` | Multi-sort priority number. |\n| `table` | Grid table wrapper. |\n| `toolbar` | Search and column controls. |\n| `tree-limit` | Localized notice rendered when nested input exceeds the 10,000-node or 64-descendant-level projection budget. |\n\n---\n\n**CSS Custom Properties**\n\n- `--accent-color` (default: `var(--lr-color-brand)`) — Accent used by focus and active states.\n- `--background-color` (default: `var(--lr-color-surface)`) — Grid background.\n- `--border-color` (default: `var(--lr-color-border)`) — Grid and cell border color.\n- `--border-radius` (default: `var(--lr-radius)`) — Outer and control corner radius.\n- `--border-width` (default: `var(--lr-border-width-thin)`) — Grid and cell border width.\n- `--cell-padding` (default: `var(--lr-space-m)`) — Header, cell, and footer padding.\n- `--focus-ring` (default: `var(--lr-focus-ring-width) solid var(--lr-focus-ring-color)`) — Focus ring.\n- `--header-background` (default: `var(--lr-color-surface-raised)`) — Header background.\n- `--header-row-height` (default: `var(--lr-size-3-5rem)`) — Header-row minimum height.\n- `--header-text-color` (default: `var(--lr-color-text)`) — Header foreground.\n- `--indent-size` (default: `var(--lr-size-1-25rem)`) — Tree-level indentation.\n- `--lr-data-grid-cell-color` (default: `inherit`) — Text colour of body cells.\n- `--lr-data-grid-cell-link-color` (default: `var(--lr-color-brand)`) — Colour of anchors returned by a column formatter or row detail renderer. These render inside the grid's shadow root, beyond the reach of page CSS. Set `revert` to restore the user-agent default.\n- `--lr-data-grid-cell-link-hover-color` (default: `var(--lr-data-grid-cell-link-color,var(--lr-color-brand))`) — Colour of those anchors on hover, focus-visible, and active interaction.\n- `--lr-data-grid-control-active-background` — Pressed background for grid controls.\n- `--lr-data-grid-control-hover-background` — Hovered background for grid controls.\n- `--lr-data-grid-page-size-active-background` — Pressed page-size selector background.\n- `--lr-data-grid-row-active-background` — Pressed data-row background.\n- `--lr-data-grid-sortable-header-active-background` — Pressed sortable-header background.\n- `--lr-data-grid-sortable-header-hover-background` — Hovered sortable-header background.\n- `--max-height` (default: `var(--lr-size-30rem)`) — Scroll viewport maximum height; `none` renders all.\n- `--row-height` (default: `var(--lr-size-3-5rem)`) — Estimated and minimum row height.\n- `--row-hover-background` — Hovered-row background.\n- `--selected-background` (default: `var(--lr-color-brand-quiet)`) — Selected-row background.\n- `--stripe-background` (default: `var(--lr-color-surface-raised)`) — Alternating-row background.\n- `--text-color` (default: `var(--lr-color-text)`) — Grid foreground.\n- `--transition-duration` (default: `var(--lr-duration-fast)`) — Interaction transition duration.","attributes":[{"name":"appearance","description":"Bordered or borderless container treatment.\n\nType: `DataGridAppearance`  \nDefault: `'outlined'`","value":{"type":["'outlined'","'plain'"]}},{"name":"child-rows","description":"Dot path or callback returning nested child rows.\n\nType: `| string\n    | ((row: Row) => readonly Row[] | undefined)\n    | null`  \nDefault: `null`"},{"name":"error","description":"Reports a failed load: the body renders the built-in failed-load state (matching\n`<lr-table>`'s own `error` contract) instead of the row/empty content, behind an `error`\nslot. `loading` beats `error` beats the empty/no-columns/no-results branches, so a loading\ngrid never flashes a stale failure and a failed grid never falls through to \"no results\"\ncopy that hides the retry affordance. The internal `dataSource` request cycle sets this\nautomatically alongside `lr-data-error`; a grid driven externally (`data`/`total` assigned by\nthe host, no `dataSource`) is set and cleared by the host like every other sibling.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"error-description","description":"Failed-load supporting copy.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"error-heading","description":"Failed-load heading override. Omitted localizes `<lr-table>`'s own `tableLoadFailed`\ndefault.\n\nType: `string | undefined`"},{"name":"filter-debounce","description":"Delay before server search/filter requests.\n\nType: `number`  \nDefault: `250`","value":{"type":["number"]}},{"name":"filter-from-leaf-rows","description":"Keeps matching descendants and their ancestors during tree filtering.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"group-by","description":"One or more field/column identifiers used to group client rows.\n\nType: `string | readonly string[] | null`  \nDefault: `null`"},{"name":"label","description":"Accessible name used when host `aria-label` is absent.\n\nType: `string | null`  \nDefault: `null`"},{"name":"loading","description":"Shows the loading overlay.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max-multi-sort","description":"Maximum simultaneous sorts; zero is unlimited.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"page","description":"Zero-based page index.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"page-size","description":"Rows per page.\n\nType: `number`  \nDefault: `20`","value":{"type":["number"]}},{"name":"paginate","description":"Enables client slicing and pager controls.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"pinnable","description":"Enables pinning unless a column overrides it.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"reorderable","description":"Enables column movement unless a column overrides it.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"resizable","description":"Enables column resizing unless a column overrides it.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"row-key","description":"Dot path used as the stable row identity.\n\nType: `string | null`  \nDefault: `null`"},{"name":"selectable","description":"Row-selection behavior. A bare attribute means `multiple`.\n\nType: `DataGridSelectable`  \nDefault: `'none'`","value":{"type":["''","'single'","'multiple'","'none'"]}},{"name":"selection-mode","description":"Alias of selectable using `<lr-table>`'s `selectionMode`/`selection-mode` spelling,\nso a consumer migrating between the two grid components doesn't need to remember that they\nchose different property names for the same row-selection concept. `selectable` remains the\ncanonical spelling (mirrored from `<wa-data-grid>`, so it is never renamed); reading and\nwriting `selectionMode` reads and writes `selectable` directly through the same underlying\nstate -- there is no separate value to fall out of sync. The bare `''` attribute shorthand\nfor `'multiple'` (`selectable`'s own convenience form) normalizes to `'multiple'` when read\nback through this alias.\n\nType: `'none' | 'single' | 'multiple'`","value":{"type":["'none'","'single'","'multiple'"]}},{"name":"server","description":"Uses server/event-driven loading and skips client processing.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"size","description":"Density on the shared Lyra size ladder.\n\nType: `DataGridSize`  \nDefault: `'m'`","value":{"type":["'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}},{"name":"sort-desc-first","description":"Starts new sort cycles descending.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"striped","description":"Alternates client row backgrounds.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"total","description":"Total server rows; `-1` derives the count from loaded data.\n\nType: `number`  \nDefault: `-1`","value":{"type":["number"]}},{"name":"with-column-menu","description":"Shows a menu on each column.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"with-columns-menu","description":"Shows the all-columns visibility menu -- the library's own checkbox menu (`<lr-dropdown>`\nplus a `role=\"menuitemcheckbox\"` row per column), which stays open across successive toggles\nso several columns can be shown or hidden in one visit.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"with-search","description":"Shows the global search field.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"without-sort-removal","description":"Keeps a sorted column in ascending/descending states instead of removing its sort.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"empty","description":"Content rendered when the source has no rows."},{"name":"error","description":"Replaces the built-in failed-load state, including its retry button, while `error` is set."},{"name":"loading","description":"Content rendered over the grid while data is loading."},{"name":"no-results","description":"Content rendered when active search or filters match no rows."}],"js":{"properties":[{"name":"appearance","description":"Bordered or borderless container treatment.\n\nAttribute: `appearance`  \nReflected to its attribute.","type":"DataGridAppearance","default":"'outlined'"},{"name":"childRows","description":"Dot path or callback returning nested child rows.\n\nAttribute: `child-rows`","type":"| string\n    | ((row: Row) => readonly Row[] | undefined)\n    | null","default":"null"},{"name":"columnOrder","description":"Clone-owned controlled column order; an empty array uses declaration order.","type":"readonly string[]"},{"name":"columns","description":"Clone-owned readonly column-definition sequence. Reassign to update.","type":"readonly DataGridColumn<Row>[]","default":"[]"},{"name":"data","description":"Clone-owned readonly client rows or current server page. Row identities are preserved.","type":"readonly Row[]","default":"[]"},{"name":"dataSource","description":"Async server loader. Providing one enables server behavior.","type":"| ((request: DataGridRequest) => Promise<DataGridResponse<Row>>)\n    | null","default":"null"},{"name":"error","description":"Reports a failed load: the body renders the built-in failed-load state (matching\n`<lr-table>`'s own `error` contract) instead of the row/empty content, behind an `error`\nslot. `loading` beats `error` beats the empty/no-columns/no-results branches, so a loading\ngrid never flashes a stale failure and a failed grid never falls through to \"no results\"\ncopy that hides the retry affordance. The internal `dataSource` request cycle sets this\nautomatically alongside `lr-data-error`; a grid driven externally (`data`/`total` assigned by\nthe host, no `dataSource`) is set and cleared by the host like every other sibling.\n\nAttribute: `error`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"errorDescription","description":"Failed-load supporting copy.\n\nAttribute: `error-description`","type":"string","default":"''"},{"name":"errorHeading","description":"Failed-load heading override. Omitted localizes `<lr-table>`'s own `tableLoadFailed`\ndefault.\n\nAttribute: `error-heading`","type":"string | undefined"},{"name":"expandedKeys","description":"Mirrored compatibility alias for `expandedRowKeys`.","type":"readonly DataGridKey[]"},{"name":"expandedRowKeys","description":"Clone-owned controlled expanded tree/detail/group row keys.","type":"readonly DataGridKey[]"},{"name":"filterDebounce","description":"Delay before server search/filter requests.\n\nAttribute: `filter-debounce`","type":"number","default":"250"},{"name":"filterFromLeafRows","description":"Keeps matching descendants and their ancestors during tree filtering.\n\nAttribute: `filter-from-leaf-rows`","type":"boolean","default":"false"},{"name":"filteredCount","description":"Number of rows after client search and filters, before paging.","type":"number","read-only":true},{"name":"filters","description":"Clone-owned controlled per-column filters. Re-binding an equal value is not a change: the\nheld value and its reference survive, nothing re-renders, and no server request is\nrescheduled, so a host that re-binds on every render cannot postpone the request forever.","type":"readonly DataGridFilter[]"},{"name":"groupBy","description":"One or more field/column identifiers used to group client rows.\n\nAttribute: `group-by`","type":"string | readonly string[] | null","default":"null"},{"name":"label","description":"Accessible name used when host `aria-label` is absent.\n\nAttribute: `label`","type":"string | null","default":"null"},{"name":"loading","description":"Shows the loading overlay.\n\nAttribute: `loading`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"maxMultiSort","description":"Maximum simultaneous sorts; zero is unlimited.\n\nAttribute: `max-multi-sort`","type":"number","default":"0"},{"name":"page","description":"Zero-based page index.\n\nAttribute: `page`  \nReflected to its attribute.","type":"number","default":"0"},{"name":"pageCount","description":"Number of available pages.","type":"number","read-only":true},{"name":"pageSize","description":"Rows per page.\n\nAttribute: `page-size`","type":"number","default":"20"},{"name":"pageSizeOptions","description":"Clone-owned choices rendered by the page-size selector.","type":"readonly number[]","default":"[10, 20, 50, 100]"},{"name":"paginate","description":"Enables client slicing and pager controls.\n\nAttribute: `paginate`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"pinnable","description":"Enables pinning unless a column overrides it.\n\nAttribute: `pinnable`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"reorderable","description":"Enables column movement unless a column overrides it.\n\nAttribute: `reorderable`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"resizable","description":"Enables column resizing unless a column overrides it.\n\nAttribute: `resizable`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"rowClass","description":"Callback assigning a class to each row.","type":"| ((row: Row) => string | null | undefined)\n    | null","default":"null"},{"name":"rowDetail","description":"Callback rendering expandable detail content.","type":"| ((row: Row) => string | TemplateResult | Node)\n    | null","default":"null"},{"name":"rowKey","description":"Dot path used as the stable row identity.\n\nAttribute: `row-key`","type":"string | null","default":"null"},{"name":"searchFn","description":"Optional global-search matcher.","type":"| ((value: unknown, term: string, row: Row) => boolean)\n    | null","default":"null"},{"name":"searchTerm","description":"Controlled global search term.","type":"string","default":"''"},{"name":"selectable","description":"Row-selection behavior. A bare attribute means `multiple`.\n\nAttribute: `selectable`  \nReflected to its attribute.","type":"DataGridSelectable","default":"'none'"},{"name":"selectableRows","description":"Callback disabling selection for individual rows.","type":"| ((row: Row) => boolean)\n    | null","default":"null"},{"name":"selectedKeys","description":"Mirrored compatibility alias for `selectedRowKeys`.","type":"readonly DataGridKey[]"},{"name":"selectedRowKeys","description":"Clone-owned controlled selected row keys.","type":"readonly DataGridKey[]"},{"name":"selectedRows","description":"Selected rows, derived from `selectedRowKeys`. Assigning current source rows updates those keys.","type":"readonly Row[]"},{"name":"selectionMode","description":"Alias of selectable using `<lr-table>`'s `selectionMode`/`selection-mode` spelling,\nso a consumer migrating between the two grid components doesn't need to remember that they\nchose different property names for the same row-selection concept. `selectable` remains the\ncanonical spelling (mirrored from `<wa-data-grid>`, so it is never renamed); reading and\nwriting `selectionMode` reads and writes `selectable` directly through the same underlying\nstate -- there is no separate value to fall out of sync. The bare `''` attribute shorthand\nfor `'multiple'` (`selectable`'s own convenience form) normalizes to `'multiple'` when read\nback through this alias.\n\nAttribute: `selection-mode`","type":"'none' | 'single' | 'multiple'"},{"name":"server","description":"Uses server/event-driven loading and skips client processing.\n\nAttribute: `server`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"size","description":"Density on the shared Lyra size ladder.\n\nAttribute: `size`  \nReflected to its attribute.","type":"DataGridSize","default":"'m'"},{"name":"sort","description":"Clone-owned controlled multi-column sorting state. Like `filters`, re-binding an equal value\nis not a change and reschedules nothing.","type":"SortingState"},{"name":"sortDescFirst","description":"Starts new sort cycles descending.\n\nAttribute: `sort-desc-first`","type":"boolean","default":"false"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"striped","description":"Alternates client row backgrounds.\n\nAttribute: `striped`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"total","description":"Total server rows; `-1` derives the count from loaded data.\n\nAttribute: `total`","type":"number","default":"-1"},{"name":"withColumnMenu","description":"Shows a menu on each column.\n\nAttribute: `with-column-menu`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"withColumnsMenu","description":"Shows the all-columns visibility menu -- the library's own checkbox menu (`<lr-dropdown>`\nplus a `role=\"menuitemcheckbox\"` row per column), which stays open across successive toggles\nso several columns can be shown or hidden in one visit.\n\nAttribute: `with-columns-menu`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"withSearch","description":"Shows the global search field.\n\nAttribute: `with-search`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"withoutSortRemoval","description":"Keeps a sorted column in ascending/descending states instead of removing its sort.\n\nAttribute: `without-sort-removal`  \nReflected to its attribute.","type":"boolean","default":"false"}],"events":[{"name":"blur","description":"Native blur relayed once from the toolbar search or active column-filter input.","type":"FocusEvent"},{"name":"focus","description":"Native focus relayed once from the toolbar search or active column-filter input.","type":"FocusEvent"},{"name":"lr-cell-click","description":"Fired when a data cell is activated with canonical `rowKey` and `columnId` identity. Clicking a supported interactive descendant, including its inner open-shadow native control, runs that control without also emitting lr-cell-click; passive cell content retains activation.","type":"CustomEvent<DataGridCellDetail<Row>>"},{"name":"lr-cell-contextmenu","description":"Fired before a native cell context menu. Cancelable; preventing default suppresses the native menu. Detail includes canonical `rowKey` and `columnId`.","type":"CustomEvent<DataGridCellContextMenuDetail<Row>>"},{"name":"lr-column-move","description":"Fired while and after a user column move; `detail.finished` marks commit.","type":"CustomEvent<LyraEventDetailSnapshot<DataGridColumnMoveDetail>>"},{"name":"lr-column-pin","description":"Fired after a user pins or unpins a column.","type":"CustomEvent<DataGridColumnPinDetail>"},{"name":"lr-column-resize","description":"Fired while and after a user resize; `detail.finished` marks commit. Pointer cancellation or lost capture restores the pre-gesture width, reports that rollback as `finished: false` when a live resize occurred, and never emits a commit.","type":"CustomEvent<DataGridColumnResizeDetail>"},{"name":"lr-column-visibility-change","description":"Fired after a user changes column visibility.","type":"CustomEvent<DataGridColumnVisibilityDetail>"},{"name":"lr-copy","description":"A clipboard write fulfilled. Frozen detail: `{ ok: true, text }`.","type":"CustomEvent<LyraClipboardWriteSuccess>"},{"name":"lr-copy-error","description":"A clipboard write failed. Frozen detail: `{ ok: false, text, reason, error }`.","type":"CustomEvent<LyraClipboardWriteFailure>"},{"name":"lr-data-error","description":"Fired when a server request rejects; prior rows remain rendered. Does NOT set `error` itself -- `error` is a separate, host-controlled property (see `@slot error`), so a consumer that wants this rejection to replace the row content with the built-in failed-load state sets `error = true` from its own listener.","type":"CustomEvent<LyraEventDetailSnapshot<DataGridDataErrorDetail>>"},{"name":"lr-error","description":"A clipboard write failed; compatibility notification without raw error text.","type":"CustomEvent<null>"},{"name":"lr-filter-change","description":"Fired after a user changes a column filter.","type":"CustomEvent<Readonly<{ filters: readonly DataGridFilter[] }>>"},{"name":"lr-group-collapse","description":"Fired after a user collapses a client-side group. Frozen detail: `{ key, columnId, value, rows }`.","type":"CustomEvent<Readonly<DataGridGroupDetail<Row>>>"},{"name":"lr-group-expand","description":"Fired after a user expands a client-side group. Frozen detail: `{ key, columnId, value, rows }`.","type":"CustomEvent<Readonly<DataGridGroupDetail<Row>>>"},{"name":"lr-page-change","description":"Fired after a user changes the zero-based page or page size.","type":"CustomEvent<DataGridPageDetail>"},{"name":"lr-retry","description":"The built-in `[part='retry-button']` was activated, only rendered while `error` is set. Cancelable: the default action clears `error`; `preventDefault()` leaves it set instead.","type":"CustomEvent<null>"},{"name":"lr-row-collapse","description":"Fired after a user collapses a tree row or row detail with canonical `rowKey` plus the mirrored `key` compatibility alias.","type":"CustomEvent<DataGridRowDetail<Row>>"},{"name":"lr-row-expand","description":"Fired after a user expands a tree row or row detail with canonical `rowKey` plus the mirrored `key` compatibility alias.","type":"CustomEvent<DataGridRowDetail<Row>>"},{"name":"lr-row-select","description":"Fired after a user changes selection with canonical `selectedRowKeys` plus the mirrored `selectedKeys` compatibility alias.","type":"CustomEvent<Readonly<DataGridSelectionDetail<Row>>>"},{"name":"lr-sort-change","description":"Fired after a user changes sorting, unless a preceding `lr-sort-request` was vetoed.","type":"CustomEvent<Readonly<{ sort: DataGridSortingState }>>"},{"name":"lr-sort-request","description":"Cancelable sort proposal, fired before `sort` commits. Frozen readonly `detail: { sort }`. Vetoing it leaves `sort` unchanged and suppresses `lr-sort-change`. Mirrors `<lr-table>`'s identical `lr-sort-request`/`lr-sort` veto-then-commit contract.","type":"CustomEvent<Readonly<{ sort: DataGridSortingState }>>"},{"name":"request","description":"Fired when server data is requested. `detail` contains sort, filter, search, page, page-size, and abort-signal state.","type":"CustomEvent<LyraEventDetailSnapshot<DataGridRequest>>"}]}},{"name":"lr-dataset-viewer","description":"Fetches delimited text and renders a virtualized, accessible data table: a `role=\"table\"`\ncontainer with a sticky `role=\"row\"` header, composed with `<lr-virtual-list item-role=\"row\">`\nfor the body so files far larger than a real synchronous `<table>` can render without locking the\nmain thread.\n\nAdopts `DocumentAnchorTarget`: a `cell-range` anchor addresses the raw file grid, 1-based, with\nthe header row always occupying row 1 (this component always parses with PapaParse's `header:\ntrue`, so the first row is never part of the virtualized body) -- `scrollToAnchor()` scrolls the\naddressed row into view via the virtualized list's `active-item-id`. A `sheet`-qualified anchor never\nresolves here -- this viewer has no sheets. `highlights` paint as a `part=\"cell-highlight\"` cell\nwrapping a focusable `part=\"cell-highlight-action\"` native button (keeping the ARIA table tree\nintact) on membership, recomputed per row inside `renderRow()` so a row scrolled out and back\nin reconstructs its highlight for free, with no persistent DOM to keep in sync. `search()` is a\nlocale-aware case-insensitive substring match over the header followed by every body cell's raw\nstring value, ordered row then column.\n\nA quote-aware structural scan enforces the 10,000-data-row, 1,000-field, 1,000,000-cell, and\n100-diagnostic ceilings before PapaParse can materialize an amplified result. The peer then runs\nwith streaming record callbacks and the same limits as a second boundary.\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| `anchor-live-region` | The aria-hidden, non-live shadow mirror of the latest anchor-jump message. |\n| `base` | The stable root wrapper with explicit `aria-busy` across every fetch state. `name` supplies its shadow region name; a non-empty host `aria-label` instead leaves ownership on the host, while an explicitly empty label remains explicit on this shadow owner. With neither source it stays a plain wrapper rather than an unnamed region. |\n| `body` | The scrollable body wrapper. |\n| `cell` | One rendered cell (`role=\"cell\"`). |\n| `cell-highlight` | A cell (`role=\"cell\"`) covered by a `highlights` entry; wraps the `cell-highlight-action` button. |\n| `cell-highlight-action` | The native button filling a highlighted cell -- focusable, emits `lr-highlight-activate` on click or Enter/Space. Its accessible name localizes the complete cell-value and annotation message through separate `{value}` and `{label}` placeholders. |\n| `data-row` | One virtualized data row. |\n| `error` | The error message region. |\n| `header-cell` | A header cell (`role=\"columnheader\"`). |\n| `header-row` | The sticky header row (`role=\"row\"`). |\n| `spinner` | The visible tokenized loading treatment and ordinary text label. |\n| `table` | The `role=\"table\"` container, named by the display name plus localized row count or by the localized row count alone; it never copies the host's overall name. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-dataset-viewer-max-height` (default: `none`) — Maximum block size of `[part=\"body\"]` before it scrolls internally. The `maxHeight` property sets this token inline on `[part=\"base\"]`. `scrollMode='page'` deliberately ignores the cap and hands both axes to page flow so the sticky header can use the page scrollport.\n- `--lr-dataset-viewer-highlight-color` (default: `var(--lr-color-brand)`) — Outline color of a highlighted cell. The active highlight changes a private warning-color default; an inherited or direct public value remains authoritative.\n- `--lr-dataset-viewer-header-row-bg` (default: `var(--lr-color-brand-quiet)`) — Background of `[part=\"header-row\"]`, independent of the highlight outline above.","attributes":[{"name":"active-highlight-id","description":"Id of the currently active highlight, or null when none is active.\n\nType: `string | null`  \nDefault: `null`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max-height","description":"A CSS `max-height`; invalid values are ignored.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"name","description":"Display name used for the table's row-count caption and for `[part=\"base\"]` when host\n`aria-label` is absent. A non-empty host label remains on the host; an explicitly empty one\nstays explicit on the shadow owner.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"scroll-mode","description":"Which element scrolls when the table overflows. `'self'` preserves contained horizontal\nscrolling and applies `maxHeight`. `'page'` removes intervening scroll containers while\nretaining rounded header corners, making the page the sticky header's scrollport; a\nwide dataset can consequently overflow its host.\n\nType: `DatasetViewerScrollMode`","value":{"type":["'self'","'page'"]}},{"name":"src","description":"URL to fetch and parse as delimited text.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"js":{"properties":[{"name":"activeHighlightId","description":"Id of the currently active highlight, or null when none is active.\n\nAttribute: `active-highlight-id`","type":"string | null","default":"null"},{"name":"anchor","description":"Anchor or highlight id to resolve and scroll into view.","type":"LyraAnchor | string | null","default":"null"},{"name":"anchorKinds","description":"Anchor kinds this viewer resolves via `scrollToAnchor()`.","type":"readonly LyraAnchorKind[]","default":"['cell-range']","read-only":true},{"name":"highlights","description":"Highlights rendered by the document target. Reassign after mutation.","type":"LyraHighlight[]","default":"[]"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"maxHeight","description":"A CSS `max-height`; invalid values are ignored.\n\nAttribute: `max-height`","type":"string","default":"''"},{"name":"name","description":"Display name used for the table's row-count caption and for `[part=\"base\"]` when host\n`aria-label` is absent. A non-empty host label remains on the host; an explicitly empty one\nstays explicit on the shadow owner.\n\nAttribute: `name`","type":"string","default":"''"},{"name":"scrollMode","description":"Which element scrolls when the table overflows. `'self'` preserves contained horizontal\nscrolling and applies `maxHeight`. `'page'` removes intervening scroll containers while\nretaining rounded header corners, making the page the sticky header's scrollport; a\nwide dataset can consequently overflow its host.\n\nAttribute: `scroll-mode`  \nReflected to its attribute.","type":"DatasetViewerScrollMode"},{"name":"src","description":"URL to fetch and parse as delimited text.\n\nAttribute: `src`","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-anchor-result","description":"Fired after an `anchor` property assignment or a `scrollToAnchor()` call is applied. `detail: { found }`.","type":"CustomEvent<AnchorResultDetail>"},{"name":"lr-highlight-activate","description":"A `highlights` cell was clicked, or activated via Enter/Space while focused. `detail: { highlightId }`.","type":"CustomEvent<HighlightActivateDetail>"},{"name":"lr-render-error","description":"Fired when fetching or parsing fails, the resource guard rejects the table, or PapaParse returns up to the bounded diagnostic ceiling alongside a recoverable partial table.","type":"CustomEvent<{ error: unknown }>"},{"name":"lr-search-change","description":"Fired whenever the search query, match count, or active match index changes, including source-reset and effective-locale re-evaluation. `detail: { query, matchCount, matchCountExact, activeIndex }`. Search accepts at most 4,096 query code units, scans at most 4,000,000 cell code units, and retains at most 1,000 matches; `matchCountExact=false` identifies a ceiling-truncated lower bound.","type":"CustomEvent<LyraSearchChangeDetail>"}]}},{"name":"lr-date-input","description":"`<lr-date-input>` — a date field with an attached calendar popover.\nMirrors the core `<wa-date-input>` API under `lr-`. Value is ISO 8601\n(`YYYY-MM-DD`, or `YYYY-MM-DD/YYYY-MM-DD` in range mode). Form-associated.\nThe ISO model is explicitly proleptic Gregorian for every locale. Display uses locale digits\nand `Intl.DateTimeFormat.formatRange()`; parsing normalizes those digits and bidi marks so the\ncomponent's own Arabic/Persian presentation always round-trips to the same ISO value.\n\nThis component uses a single text field; typing accepts ISO or a\nlocale-parseable date. Enter commits the typed text and then performs the implicit form\nsubmission a native `<input>` would (see `internal/submit-on-enter.ts` — the internal input is\nin a shadow root and has no form owner, so the platform can never do it here); the commit runs\nfirst so the submitted value is the date the field visibly shows.\nThat text field is also the popup-opening `role=\"combobox\"` owner, with explicit\n`aria-haspopup`, `aria-controls`, and `aria-expanded`; the adjacent button remains an equivalent\npointer/keyboard toggle rather than carrying the only popup relationship.\n\n`size` uses the same `2xs`–`xl` scale as `lr-input`/`lr-select`/`lr-combobox`'s own `size`,\ndefault `m`. The calendar-toggle and clear buttons fit within the selected control height\nwhile retaining a 24px target. The smallest tiers can grow to accommodate that minimum.\nIn a constrained row the editable input shrinks first, while each public `start`/`end`\nadornment is capped at 40% so unbroken consumer content cannot widen the field.\n\nHost aria-describedby targets in the host root resolve onto the native combobox input before\nits local error and hint guidance, and follow target replacement, reconnect, and adoption.\n\n---\n\n**Component metadata**\n\n- Status: `experimental`\n- Since: `4.0.0`\n- Rationale: This exact tag already appears in published Lyra versions and remains experimental under full semver protection while its public API and usage patterns mature.\n- Graduation: Eligible for stable status once its documented API, populated accessibility states, cross-browser behavior, and compatibility contract demonstrate sustained reliability.\n\n---\n\n**Slots**\n\n| Name | Description |\n| --- | --- |\n| `clear-icon` | Replaces the clear icon. |\n| `day-YYYY-MM-DD` | Content for an individual ISO calendar day. |\n| `end` | Adornment after the text field and the built-in clear action, and before the calendar toggle — so consumer content never sits outboard of the calendar button. |\n| `error` | Lyra extension for custom validation markup. |\n| `expand-icon` | Replaces the calendar icon. |\n| `footer` | Calendar footer content. |\n| `hint` | Custom hint content. |\n| `label` | Custom label content. |\n| `next-icon` | Replaces the next-month icon in the calendar. |\n| `previous-icon` | Replaces the previous-month icon in the calendar. |\n| `start` | Adornment at the inline-start of the input row, before the text field. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | Permanent compatibility name for the nested base wrapper. |\n| `clear-button` | The clear control. |\n| `date-input` | The date-input wrapper. |\n| `date-picker` | The nested date picker. |\n| `end` | Wrapper around the `end` adornment slot; `hidden` while nothing is slotted. |\n| `error` | The validation message. |\n| `expand-button` | The calendar popup toggle. |\n| `expand-icon` | The calendar icon. |\n| `form-control` | The outer form-control wrapper. |\n| `form-control-input` | The editable date surface. |\n| `form-control-label` | The outer label wrapper. |\n| `hint` | The hint message. |\n| `input` | The text input. |\n| `input-wrapper` | The input and button wrapper. |\n| `label` | Permanent compatibility name for the inner label-content wrapper. |\n| `popup` | The positioned calendar popup. |\n| `preset-button` | One quick-range button, forwarded from `<lr-date-picker>`. |\n| `presets` | The nested picker's quick-range row, forwarded from `<lr-date-picker>`. |\n| `range-separator` | The range separator. |\n| `segment` | The editable date segment wrapper. |\n| `segment-literal` | A literal inside the editable date surface. |\n| `start` | Wrapper around the `start` adornment slot; `hidden` while nothing is slotted. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-date-input-padding-block` (default: `var(--lr-form-control-padding-block)`) — Text input block padding, scaled by `size`.\n- `--lr-date-input-padding-inline` (default: `var(--lr-form-control-padding-inline)`) — Inline padding of the input row, scaled by `size`.\n- `--lr-date-input-font-size` (default: `var(--lr-form-control-font-size)`) — Font size of the text input, scaled by `size`.\n- `--lr-date-input-placeholder-color` (default: `var(--lr-color-text-quiet)`) — Placeholder text color.\n- `--lr-date-input-gap` (default: `var(--lr-space-xs)`) — Gap between input-row children.\n- `--lr-date-input-radius` (default: `var(--lr-radius)`) — Input-row corner radius. `pill` changes its private default to `--lr-radius-pill`; an inherited or direct public value still wins.\n- `--lr-date-input-focus-border-color` (default: `var(--lr-color-brand)`) — Focused row border color.\n- `--lr-date-input-action-hover-color` (default: `var(--lr-color-text)`) — Clear/calendar action color on hover.\n- `--lr-date-input-action-hover-bg` (default: `transparent`) — Clear/calendar action background on hover.\n- `--lr-date-input-action-hover-radius` (default: `var(--lr-date-input-radius)`) — Clear/calendar action corner radius on hover.\n- `--lr-date-input-action-active-color` (default: `var(--lr-date-input-action-hover-color,var(--lr-color-text))`) — Clear/calendar action color while pressed.\n- `--lr-date-input-action-active-bg` (default: `color-mix(...)`) — Clear/calendar action background while pressed.\n- `--lr-date-input-action-active-radius` (default: `var(--lr-date-input-radius)`) — Clear/calendar action corner radius while pressed.\n- `--lr-date-input-control-min-height` (default: `var(--lr-form-control-height)`) — Minimum block size of the input row, read from the shared form-control height ladder so retuning `--lr-theme-form-control-height-*` moves this control and every sibling field together. The smallest tiers can grow to fit the action buttons' 24px minimum and row borders.\n- `--lr-date-input-control-height` — Exact block size of the input row. Undeclared by default, so the row grows to fit its content (floored by `--lr-date-input-control-min-height`). Set it to pin a fixed height; the calendar toggle keeps its own 24x24 touch target even when this pins a shorter row.\n- `--show-duration` (default: `var(--lr-transition-fast)`) — Popup enter-transition duration.\n- `--hide-duration` (default: `var(--lr-transition-fast)`) — Popup exit-transition duration.\n- `--lr-date-input-fill` (default: `var(--lr-color-surface)`) — Resting background of the input row. The `filled`/`filled-outlined` treatments default it to `--lr-color-surface-raised`; a value set here wins over every treatment.\n- `--lr-date-input-border-color` (default: `var(--lr-color-border)`) — Resting border color of the input row, `transparent` by default on the `filled` treatment.\n- `--lr-form-control-focus-shadow` (default: `none`) — The shared field focus halo, painted as a `box-shadow` while this control is focused. One name for every field-shaped control in the library, so a halo is configured once rather than per component. Additive: the focus outline and border cue are the accessibility answer to focus and are never replaced by it.\n- `--lr-form-control-required-content` (default: `' *'`) — The required-field marker rendered after the label. Set it to `''` to suppress the marker, or to any other quoted string (`' (required)'`, a localized word) to replace it. Caller-supplied content, so it is never localized here.\n- `--lr-form-control-required-color` (default: `var(--lr-color-danger)`) — Color of that marker, retunable without touching any other danger-coloured surface.\n- `--lr-form-control-required-offset` (default: `0`) — Inline space between the label text and the marker.\n- `--lr-positioning-strategy` — Cascading `absolute`/`fixed` override for the calendar popup's `fixed` default, read from computed style when it is (re)positioned. Set it once on `:root`, a theme, or one clipping ancestor to change every unset date input beneath it; an unrecognized value falls back to `fixed`.","attributes":[{"name":"appearance","description":"Type: `Extract<LyraAppearance, 'filled' | 'outlined' | 'filled-outlined'>`  \nDefault: `'outlined'`","value":{"type":["'filled'","'outlined'","'filled-outlined'"]}},{"name":"aria-label","description":"Overrides the internal `<input>`'s computed accessible name. Wins over\n`label`/`placeholder`/the localized `date` fallback in that order --\nsee the `aria-label` binding in `render()`. Attribute-reflects from a\nhost-level `aria-label` so a plain-markup consumer gets ARIA-name\nforwarding without setting a JS property.\n\nType: `string | null`  \nDefault: `null`"},{"name":"autocapitalize","description":"Forwarded to the internal `<input>`'s own `autocapitalize`. Empty string omits the\nattribute (browser default).\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"autocomplete","description":"Forwarded to the internal date text input. Empty strings preserve the browser default.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"autocorrect","description":"Forwarded to the internal `<input>`'s own `autocorrect` (Safari/WebKit-specific). Empty\nstring omits the attribute (browser default).\nNamed `autoCorrect` (capital `C`), not `autocorrect`, purely to dodge a TS `lib.dom.d.ts`\ncollision: newer DOM typings declare a `boolean`-typed `HTMLElement.autocorrect` IDL member,\nwhich conflicts with this component's `string`-typed property of the same name. The explicit\nattribute mapping preserves the standard lowercase `autocorrect` wire name in both Lit and\ngenerated component metadata.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"clear-label","description":"Accessible label for the clear button. Omitted copy localizes; explicit text,\nincluding the built-in English label or an empty string, wins verbatim.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"custom-error","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nType: `string | null`  \nDefault: `null`"},{"name":"dialog-label","description":"Accessible label for the calendar popover dialog. Omitted copy localizes; explicit text,\nincluding the built-in English label or an empty string, wins verbatim.\n\nType: `string`  \nDefault: `'Choose date'`","value":{"type":["string"]}},{"name":"disable-future","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"disable-past","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"disabled","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"disabled-dates","description":"Type: `LyraDatePickerDisabledDates`  \nDefault: `''`","value":{"type":["LyraDatePickerDisabledDates"]}},{"name":"disabled-days-of-week","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"distance","description":"Type: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"enterkeyhint","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"error-text","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"first-day-of-week","description":"Type: `LyraDateInputFirstDayOfWeek`  \nDefault: `'auto'`","value":{"type":["'auto'","'sun'","'mon'","'tue'","'wed'","'thu'","'fri'","'sat'"]}},{"name":"form","description":"Type: `HTMLFormElement | string | null`  \nDefault: `null`"},{"name":"hint","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"inputmode","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"label","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max-range","description":"Type: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"min","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"min-range","description":"Type: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"mode","description":"Type: `'single' | 'range'`  \nDefault: `'single'`","value":{"type":["'single'","'range'"]}},{"name":"months","description":"Type: `1 | 2`  \nDefault: `1`","value":{"type":["1","2"]}},{"name":"name","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"open","description":"Whether the calendar popup is open. Disabled or readonly controls reject direct reopen\nattempts, including the synchronous fieldset cascade before its callback runs.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"open-label","description":"Accessible label for the calendar-toggle button. Omitted copy localizes; explicit text,\nincluding the built-in English label or an empty string, wins verbatim.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"page-by","description":"Type: `LyraDatePickerPageBy`  \nDefault: `'months'`","value":{"type":["'months'","'single'"]}},{"name":"pill","description":"Rounds the input row's corners to a full pill, mirroring `lr-input`'s own `pill`. It is a\nsingle override of `--lr-date-input-radius`, so a consumer setting that property directly\nstill wins for a bespoke shape.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"placeholder","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"placement","description":"Type: `LyraDateInputPlacement`  \nDefault: `'bottom-start'`","value":{"type":["'top'","'top-start'","'top-end'","'right'","'right-start'","'right-end'","'bottom'","'bottom-start'","'bottom-end'","'left'","'left-start'","'left-end'"]}},{"name":"readonly","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"required","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"size","description":"Visual size — the library-wide `2xs`–`xl` ladder shared with\n`lr-input`/`lr-select`/`lr-combobox`. `'2xs'` is the tightest tier, for dense\ntoolbar-embedded fields. The Web Awesome / Shoelace spellings `small`/`medium`/`large` are\naccepted for `s`/`m`/`l`, so a migration is a tag rename with no attribute rewrite.\n\nType: `LyraSize`  \nDefault: `'m'`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}},{"name":"spellcheck","description":"Forwarded to the internal `<input>`'s own `spellcheck`. Defaults to `true`, matching the\nnative element's own default. Uses spellcheckConverter rather than Lit's default\npresence-based `type: Boolean` converter -- see that converter's doc comment. A bare\n`.spellcheck` property binding can still turn this off with `spellcheck=\"false\"`; a Lit\ntemplate can do the same with either that attribute string or a `.spellcheck=${false}`\nbinding.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"today","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"value","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"weekday-format","description":"Type: `WeekdayFormat`  \nDefault: `'short'`","value":{"type":["'narrow'","'short'","'long'"]}},{"name":"with-clear","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"with-hint","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"with-label","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"with-outside-days","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"with-week-numbers","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"clear-icon","description":"Replaces the clear icon."},{"name":"day-YYYY-MM-DD","description":"Content for an individual ISO calendar day."},{"name":"end","description":"Adornment after the text field and the built-in clear action, and before the calendar toggle — so consumer content never sits outboard of the calendar button."},{"name":"error","description":"Lyra extension for custom validation markup."},{"name":"expand-icon","description":"Replaces the calendar icon."},{"name":"footer","description":"Calendar footer content."},{"name":"hint","description":"Custom hint content."},{"name":"label","description":"Custom label content."},{"name":"next-icon","description":"Replaces the next-month icon in the calendar."},{"name":"previous-icon","description":"Replaces the previous-month icon in the calendar."},{"name":"start","description":"Adornment at the inline-start of the input row, before the text field."}],"js":{"properties":[{"name":"accessibleLabel","description":"Overrides the internal `<input>`'s computed accessible name. Wins over\n`label`/`placeholder`/the localized `date` fallback in that order --\nsee the `aria-label` binding in `render()`. Attribute-reflects from a\nhost-level `aria-label` so a plain-markup consumer gets ARIA-name\nforwarding without setting a JS property.\n\nAttribute: `aria-label`","type":"string | null","default":"null"},{"name":"appearance","description":"Attribute: `appearance`  \nReflected to its attribute.","type":"Extract<LyraAppearance, 'filled' | 'outlined' | 'filled-outlined'>","default":"'outlined'"},{"name":"appliedPreset","description":"The preset whose button produced the current `value`, or `undefined` when the value was picked\non the calendar, typed into the field, cleared, or reset. Read it inside your own\n`change`/`input` handler.\n\nMirrors the nested `<lr-date-picker>`'s own `appliedPreset` across this shadow boundary,\nbecause the readback is what the compact popover shape needs most: a dashboard filter has to\npersist WHICH preset is active rather than the pair it froze to -- \"Last 7 days\" must still\nmean the last 7 days after tomorrow's reload. That fact is not recoverable from `value`:\nre-deriving it by string-matching is the mapping table `presets` exists to delete, and it is\nambiguous anyway (Today and This month coincide on the 1st of a month, and a hand-picked range\ncan equal a preset's pair by construction). The picker instance itself is unreachable from\noutside -- a CSS part cannot yield it -- so a consumer cannot read it there.\n\nA property rather than an event detail, for the same reason it is one on the picker:\n`input`/`change` here are NATIVE events, deliberately indistinguishable from a manual\nselection so existing handlers need no special case, and a native Event cannot carry a detail\nwithout changing its type. The mirror is updated before those events are relayed, so a handler\nreading it observes the preset that caused the very commit it is handling; it is `undefined`\nwhile the popover has never been opened, since no preset button has run.","type":"LyraDateRangePreset | undefined","read-only":true},{"name":"assumeInteractionOn","description":"Event names that mark the control as user-interacted for `:state(user-*)` styling.","type":"string[]","default":"['input']"},{"name":"autoCorrect","description":"Forwarded to the internal `<input>`'s own `autocorrect` (Safari/WebKit-specific). Empty\nstring omits the attribute (browser default).\nNamed `autoCorrect` (capital `C`), not `autocorrect`, purely to dodge a TS `lib.dom.d.ts`\ncollision: newer DOM typings declare a `boolean`-typed `HTMLElement.autocorrect` IDL member,\nwhich conflicts with this component's `string`-typed property of the same name. The explicit\nattribute mapping preserves the standard lowercase `autocorrect` wire name in both Lit and\ngenerated component metadata.\n\nAttribute: `autocorrect`","type":"string","default":"''"},{"name":"autocapitalize","description":"Forwarded to the internal `<input>`'s own `autocapitalize`. Empty string omits the\nattribute (browser default).\n\nAttribute: `autocapitalize`","type":"string","default":"''"},{"name":"autocomplete","description":"Forwarded to the internal date text input. Empty strings preserve the browser default.\n\nAttribute: `autocomplete`","type":"string","default":"''"},{"name":"clearLabel","description":"Accessible label for the clear button. Omitted copy localizes; explicit text,\nincluding the built-in English label or an empty string, wins verbatim.\n\nAttribute: `clear-label`","type":"string","default":"''"},{"name":"customError","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nAttribute: `custom-error`  \nReflected to its attribute.","type":"string | null","default":"null"},{"name":"dayContent","description":"Optional JavaScript renderer for individual calendar-day content.","type":"LyraDatePickerDayContent | undefined"},{"name":"defaultValue","description":"Attribute: `value`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"dialogLabel","description":"Accessible label for the calendar popover dialog. Omitted copy localizes; explicit text,\nincluding the built-in English label or an empty string, wins verbatim.\n\nAttribute: `dialog-label`","type":"string","default":"'Choose date'"},{"name":"disableFuture","description":"Attribute: `disable-future`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"disablePast","description":"Attribute: `disable-past`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"disabled","description":"Attribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"disabledDates","description":"Attribute: `disabled-dates`","type":"LyraDatePickerDisabledDates","default":"''"},{"name":"disabledDaysOfWeek","description":"Attribute: `disabled-days-of-week`","type":"string","default":"''"},{"name":"distance","description":"Attribute: `distance`  \nReflected to its attribute.","type":"number","default":"0"},{"name":"enterKeyHint","description":"Attribute: `enterkeyhint`","type":"string","default":"''"},{"name":"errorText","description":"Attribute: `error-text`","type":"string","default":"''"},{"name":"firstDayOfWeek","description":"Attribute: `first-day-of-week`  \nReflected to its attribute.","type":"LyraDateInputFirstDayOfWeek","default":"'auto'"},{"name":"form","description":"Attribute: `form`  \nReflected to its attribute.","type":"HTMLFormElement | string | null","default":"null"},{"name":"hint","description":"Attribute: `hint`","type":"string","default":"''"},{"name":"input","description":"The underlying date text input for platform-specific integrations.","type":"HTMLInputElement | undefined","read-only":true},{"name":"inputMode","description":"Attribute: `inputmode`","type":"string","default":"''"},{"name":"isDateDisabled","description":"Optional JavaScript predicate that disables matching calendar dates.","type":"(date: Date) => boolean | undefined"},{"name":"label","description":"Attribute: `label`","type":"string","default":"''"},{"name":"labels","type":"NodeList","read-only":true},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"max","description":"Attribute: `max`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"maxRange","description":"Attribute: `max-range`  \nReflected to its attribute.","type":"number","default":"0"},{"name":"min","description":"Attribute: `min`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"minRange","description":"Attribute: `min-range`  \nReflected to its attribute.","type":"number","default":"0"},{"name":"mode","description":"Attribute: `mode`  \nReflected to its attribute.","type":"'single' | 'range'","default":"'single'"},{"name":"months","description":"Attribute: `months`  \nReflected to its attribute.","type":"1 | 2","default":"1"},{"name":"name","description":"Attribute: `name`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"open","description":"Whether the calendar popup is open. Disabled or readonly controls reject direct reopen\nattempts, including the synchronous fieldset cascade before its callback runs.\n\nAttribute: `open`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"openLabel","description":"Accessible label for the calendar-toggle button. Omitted copy localizes; explicit text,\nincluding the built-in English label or an empty string, wins verbatim.\n\nAttribute: `open-label`","type":"string","default":"''"},{"name":"pageBy","description":"Attribute: `page-by`  \nReflected to its attribute.","type":"LyraDatePickerPageBy","default":"'months'"},{"name":"pill","description":"Rounds the input row's corners to a full pill, mirroring `lr-input`'s own `pill`. It is a\nsingle override of `--lr-date-input-radius`, so a consumer setting that property directly\nstill wins for a bespoke shape.\n\nAttribute: `pill`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"placeholder","description":"Attribute: `placeholder`","type":"string","default":"''"},{"name":"placement","description":"Attribute: `placement`  \nReflected to its attribute.","type":"LyraDateInputPlacement","default":"'bottom-start'"},{"name":"presets","description":"Quick-range options forwarded verbatim to the nested `<lr-date-picker>`; see that component's\nown `presets` doc for the semantics. Range mode only, and unset renders nothing.\n\nForwarded rather than reimplemented: the picker lives in this component's shadow root, so a\nconsumer has no route to it -- a CSS part cannot set a JS property -- and this compact\ntext-field-plus-popover shape is the one a dashboard time filter actually uses.","type":"readonly LyraDateRangePreset[]"},{"name":"readonly","description":"Attribute: `readonly`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"required","description":"Attribute: `required`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"selectionDirection","type":"LyraDateInputSelectionDirection | null"},{"name":"selectionEnd","type":"number | null"},{"name":"selectionStart","type":"number | null"},{"name":"size","description":"Visual size — the library-wide `2xs`–`xl` ladder shared with\n`lr-input`/`lr-select`/`lr-combobox`. `'2xs'` is the tightest tier, for dense\ntoolbar-embedded fields. The Web Awesome / Shoelace spellings `small`/`medium`/`large` are\naccepted for `s`/`m`/`l`, so a migration is a tag rename with no attribute rewrite.\n\nAttribute: `size`  \nReflected to its attribute.","type":"LyraSize","default":"'m'"},{"name":"spellcheck","description":"Forwarded to the internal `<input>`'s own `spellcheck`. Defaults to `true`, matching the\nnative element's own default. Uses spellcheckConverter rather than Lit's default\npresence-based `type: Boolean` converter -- see that converter's doc comment. A bare\n`.spellcheck` property binding can still turn this off with `spellcheck=\"false\"`; a Lit\ntemplate can do the same with either that attribute string or a `.spellcheck=${false}`\nbinding.\n\nAttribute: `spellcheck`","type":"boolean","default":"true"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"today","description":"Attribute: `today`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"validationMessage","type":"string","read-only":true},{"name":"validationTarget","description":"Native input used as the browser validation bubble's focus anchor.","type":"HTMLElement | undefined"},{"name":"validators","description":"Additional JavaScript validators run after the intrinsic date constraints. Accepts a\nfunction, an object with `validate(value, input)`, or the mapped object-validator shape with\n`checkValidity(input)` and `{ isValid, message, invalidKeys }` results. Object validators can\nlist host `observedAttributes` that should trigger live revalidation.","type":"LyraDateInputValidator[]","default":"[]"},{"name":"validity","type":"ValidityState","read-only":true},{"name":"value","type":"string"},{"name":"valueAsDate","type":"Date | null"},{"name":"valueAsRange","description":"Date-range projection of `value`; writes normalize reversed endpoints and remain event-silent.","type":"DateRange"},{"name":"weekdayFormat","description":"Attribute: `weekday-format`  \nReflected to its attribute.","type":"WeekdayFormat","default":"'short'"},{"name":"willValidate","type":"boolean","read-only":true},{"name":"withClear","description":"Attribute: `with-clear`","type":"boolean","default":"false"},{"name":"withHint","description":"Attribute: `with-hint`","type":"boolean","default":"false"},{"name":"withLabel","description":"Attribute: `with-label`","type":"boolean","default":"false"},{"name":"withOutsideDays","description":"Attribute: `with-outside-days`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"withWeekNumbers","description":"Attribute: `with-week-numbers`  \nReflected to its attribute.","type":"boolean","default":"false"}],"events":[{"name":"blur","description":"Re-dispatched from the internal `<input>`'s own `blur` as a bubbling, composed, non-cancelable event, unlike the native event.","type":"FocusEvent"},{"name":"change","description":"Fired on committed date transitions as a bubbling, composed, non-cancelable native event.","type":"Event"},{"name":"focus","description":"Re-dispatched from the internal `<input>`'s own `focus` as a bubbling, composed, non-cancelable event, unlike the native event.","type":"FocusEvent"},{"name":"input","description":"Fired on edits as a bubbling, composed, non-cancelable native event.","type":"InputEvent"},{"name":"lr-after-hide","description":"The calendar popover finished closing.","type":"CustomEvent<null>"},{"name":"lr-after-show","description":"The calendar popover finished opening.","type":"CustomEvent<null>"},{"name":"lr-clear","description":"The clear button was used.","type":"CustomEvent<null>"},{"name":"lr-hide","description":"Fired before the calendar popover closes; cancelable.","type":"CustomEvent<null>"},{"name":"lr-invalid","description":"The date input failed a validity check; cancelable. Calling `preventDefault()` also cancels the native `invalid` event it aliases, suppressing the browser's own validation bubble and `reportValidity()`'s focus/scroll.","type":"CustomEvent<null>"},{"name":"lr-show","description":"Fired before the calendar popover opens; cancelable.","type":"CustomEvent<null>"}]}},{"name":"lr-date-picker","description":"`<lr-date-picker>` — an inline month-grid calendar for picking a single date\nor a date range. Mirrors the core `<wa-date-picker>` API under `lr-`.\n\nValue is ISO 8601: `YYYY-MM-DD` (single) or `YYYY-MM-DD/YYYY-MM-DD` (range).\nCalendar arithmetic and formatting are explicitly proleptic Gregorian, including ISO years\n0000–0099; visible day/week digits still follow the effective locale's numbering system.\n\nDeliberately does **not** perform implicit form submission on Enter (unlike its `<lr-date-input>`\nwrapper, which routes through `internal/submit-on-enter.ts`): Enter selects the focused day in\nthe calendar grid — the grid's own commit key, the same carve-out `<lr-textarea>` has for a\nnewline. This element is also not form-associated; the wrapping `<lr-date-input>` is what\nparticipates in a `<form>`.\n\nMonth, year, and decade selection views retain one enabled roving Tab stop. Arrow keys follow\ntheir visual four-column grid (mirroring horizontally under RTL), Home and End move to the\nfirst and last enabled periods, and Enter or Space drills into the focused period.\nA period is enabled only when it contains a date selectable under the current bounds,\npast/future, date-list, weekday, predicate, and pending-range constraints.\n\nAn authored host aria-label names an enclosing group while each grid retains its own period\nname. Live constraints repair roving state without moving unrelated focus. Day and period\nnavigation stay within the supported ISO years 0000–9999.\n\n---\n\n**Component metadata**\n\n- Status: `experimental`\n- Since: `4.0.0`\n- Rationale: This exact tag already appears in published Lyra versions and remains experimental under full semver protection while its public API and usage patterns mature.\n- Graduation: Eligible for stable status once its documented API, populated accessibility states, cross-browser behavior, and compatibility contract demonstrate sustained reliability.\n\n---\n\n**Slots**\n\n| Name | Description |\n| --- | --- |\n| `day-YYYY-MM-DD` | Lyra extension for replacing an individual ISO calendar day's content. |\n| `footer` | Content below the calendar grids. |\n| `header` | Replaces the built-in navigation header. |\n| `next-icon` | Replaces the next-page icon. |\n| `previous-icon` | Replaces the previous-page icon. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | Permanent compatibility name on the same visible shell as `date-picker`. |\n| `date-picker` | The visible date-picker shell. |\n| `day` | A calendar day button. |\n| `day-disabled` | A disabled day. |\n| `day-label` | The visible day label. |\n| `day-outside` | A day outside the active month. |\n| `day-placeholder` | A non-day grid placeholder. |\n| `day-range-end` | The end of a selected range. |\n| `day-range-inner` | An interior day in a selected range. |\n| `day-range-preview` | A day in the pending range preview. |\n| `day-range-start` | The start of a selected range. |\n| `day-selected` | A selected day. |\n| `day-today` | A day representing today. |\n| `day-weekend` | A Saturday or Sunday. |\n| `footer` | The footer region. |\n| `grid` | A month date grid. |\n| `header` | The month header. |\n| `month` | A visible month wrapper. |\n| `month-label` | The interactive month label. |\n| `months` | The visible-month collection. |\n| `nav` | The navigation controls. |\n| `next` | The next-month button. |\n| `preset-button` | One quick-range button; carries `data-active` while its range is the current value. |\n| `presets` | The quick-range button row, rendered only in range mode with `presets` set. |\n| `previous` | The previous-month button. |\n| `title` | The month title. |\n| `view-cell` | A cell in a selection grid. |\n| `view-grid` | A month/year/decade selection grid. |\n| `view-item` | A month/year/decade selection button. |\n| `view-item-disabled` | A disabled selection item. |\n| `view-item-selected` | The item containing the selected date. |\n| `view-item-today` | The item containing today. |\n| `view-row` | A row in a selection grid. |\n| `week` | A calendar week row. |\n| `weekday` | A weekday label. |\n| `weekdays` | The weekday header row. |\n| `weeknumber` | One week number. |\n| `weeknumbers` | The week-number column. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-cell-size` (default: `var(--lr-size-2-25rem)`) — Inline and block size of each day cell and the matching calendar grid track.\n- `--lr-date-picker-day-active-bg` (default: `color-mix(in oklab, var(--lr-date-picker-day-hover-bg, var(--lr-color-brand-quiet)), var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Day pressed background.\n- `--lr-date-picker-day-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Day hover background.\n- `--lr-date-picker-day-outside-color` (default: `var(--lr-color-text-quiet)`) — Adjacent-month day color.\n- `--lr-date-picker-disabled-color` (default: `var(--lr-color-text-quiet)`) — Disabled day text color.\n- `--lr-date-picker-disabled-opacity` (default: `var(--lr-opacity-disabled)`) — Disabled day opacity.\n- `--lr-date-picker-header-gap` (default: `var(--lr-space-s)`) — Month-header child gap.\n- `--lr-date-picker-month-gap` (default: `var(--lr-space-l)`) — Gap between visible months.\n- `--lr-date-picker-nav-active-bg` (default: `color-mix(in oklab, var(--lr-date-picker-nav-hover-bg, var(--lr-color-brand-quiet)), var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Pressed month-navigation background.\n- `--lr-date-picker-nav-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background of the `[part=\"previous\"]`/`[part=\"next\"]` month-navigation buttons.\n- `--lr-date-picker-preset-active-bg` — Pressed background of a quick-range button; defaults to a mix of the hover background with the shared active mix partner.\n- `--lr-date-picker-preset-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background of a quick-range button.\n- `--lr-date-picker-preset-selected-bg` (default: `var(--lr-color-brand)`) — Background of the quick-range button whose range is currently selected.\n- `--lr-date-picker-preset-selected-border` (default: `var(--lr-color-brand)`) — Border color of the selected quick-range button.\n- `--lr-date-picker-preset-selected-color` (default: `var(--lr-color-on-brand)`) — Foreground color of the selected quick-range button.\n- `--lr-date-picker-radius` (default: `var(--lr-radius)`) — Calendar and control corner radius.\n- `--lr-date-picker-range-bg` (default: `var(--lr-color-brand-quiet)`) — Selected-range interior background.\n- `--lr-date-picker-range-color` (default: `var(--lr-color-text)`) — Adjacent-month range text color.\n- `--lr-date-picker-range-preview-bg` (default: `var(--lr-date-picker-range-bg, var(--lr-color-brand-quiet))`) — Pending-range preview background.\n- `--lr-date-picker-selected-bg` (default: `var(--lr-color-brand)`) — Selected day/range-endpoint background.\n- `--lr-date-picker-selected-color` (default: `var(--lr-color-on-brand)`) — Selected day/range-endpoint text color.\n- `--lr-date-picker-title-active-bg` (default: `var(--lr-color-brand-quiet)`) — Pressed title background.\n- `--lr-date-picker-title-active-color` (default: `var(--lr-color-brand)`) — Pressed title color.\n- `--lr-date-picker-title-active-radius` (default: `var(--lr-date-picker-radius)`) — Pressed title corner radius.\n- `--lr-date-picker-title-hover-color` (default: `var(--lr-color-brand)`) — Hovered title color.\n- `--lr-date-picker-today-outline` (default: `var(--lr-color-brand)`) — Today outline color.\n- `--lr-date-picker-view-active-bg` (default: `color-mix(in oklab, var(--lr-date-picker-view-hover-bg, var(--lr-color-brand-quiet)), var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Selection-view item pressed background.\n- `--lr-date-picker-view-disabled-opacity` (default: `var(--lr-opacity-disabled)`) — Disabled selection-view item opacity.\n- `--lr-date-picker-view-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Selection-view item hover background.\n- `--lr-date-picker-view-selected-bg` (default: `var(--lr-color-brand)`) — Selected selection-view item background.\n- `--lr-date-picker-view-selected-color` (default: `var(--lr-color-on-brand)`) — Selected selection-view item text color.\n- `--lr-date-picker-view-today-outline` (default: `var(--lr-color-brand)`) — Current-period selection-view outline.","attributes":[{"name":"disable-future","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"disable-past","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"disabled","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"disabled-dates","description":"Type: `LyraDatePickerDisabledDates`  \nDefault: `''`","value":{"type":["LyraDatePickerDisabledDates"]}},{"name":"disabled-days-of-week","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"first-day-of-week","description":"Type: `LyraDatePickerFirstDayOfWeek`  \nDefault: `'auto'`","value":{"type":["'auto'","'sun'","'mon'","'tue'","'wed'","'thu'","'fri'","'sat'"]}},{"name":"focused-date","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max-range","description":"Type: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"min","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"min-range","description":"Type: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"mode","description":"Type: `CalendarMode`  \nDefault: `'single'`","value":{"type":["'single'","'range'"]}},{"name":"months","description":"Type: `1 | 2`  \nDefault: `1`","value":{"type":["1","2"]}},{"name":"next-label","description":"Accessible label for the next-month button. Omitted copy localizes; explicit text,\nincluding the built-in English label or an empty string, wins verbatim.\n\nType: `string`  \nDefault: `'Next month'`","value":{"type":["string"]}},{"name":"page-by","description":"Type: `LyraDatePickerPageBy`  \nDefault: `'months'`","value":{"type":["'months'","'single'"]}},{"name":"previous-label","description":"Accessible label for the previous-month button. Omitted copy localizes; explicit text,\nincluding the built-in English label or an empty string, wins verbatim.\n\nType: `string`  \nDefault: `'Previous month'`","value":{"type":["string"]}},{"name":"readonly","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"size","description":"Visual size — scales the private default behind `--lr-cell-size` proportionally; not pixel-matched to\n`lr-input`'s row-height scale (a calendar cell isn't a text row). The Web Awesome / Shoelace spellings\n`small`/`medium`/`large` are accepted for `s`/`m`/`l`, so a migration is a tag rename with no\nattribute rewrite.\n\nType: `LyraSize`  \nDefault: `'m'`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}},{"name":"today","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"value","description":"ISO value: `YYYY-MM-DD` or `YYYY-MM-DD/YYYY-MM-DD`.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"view","description":"Type: `LyraDatePickerView`  \nDefault: `'days'`","value":{"type":["'days'","'months'","'years'","'decades'"]}},{"name":"weekday-format","description":"Type: `WeekdayFormat`  \nDefault: `'short'`","value":{"type":["'narrow'","'short'","'long'"]}},{"name":"with-outside-days","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"with-week-numbers","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"day-YYYY-MM-DD","description":"Lyra extension for replacing an individual ISO calendar day's content."},{"name":"footer","description":"Content below the calendar grids."},{"name":"header","description":"Replaces the built-in navigation header."},{"name":"next-icon","description":"Replaces the next-page icon."},{"name":"previous-icon","description":"Replaces the previous-page icon."}],"js":{"properties":[{"name":"appliedPreset","description":"The preset whose button produced the current `value`, or `undefined` when the range was picked\nby hand, cleared, or changed externally. Clearing removes identity before value events;\nexternal changes clear it silently. Read it inside your own `change`/`input` handler.\n\nExists because a dashboard filter has to persist WHICH preset is active, not the pair it froze\nto: \"Last 7 days\" must still mean the last 7 days after tomorrow's reload. That fact is not\nrecoverable from `value` -- re-deriving it by string-matching is the mapping table `presets`\nexists to delete, and it is ambiguous anyway (Today and This month coincide on the 1st of a\nmonth, and a hand-picked range can equal a preset's pair by construction).\n\nA property rather than an event detail: `input`/`change` are NATIVE events here, deliberately\nindistinguishable from a manual selection so existing handlers need no special case, and a\nnative Event cannot carry a detail without changing its type.","type":"LyraDateRangePreset | undefined","read-only":true},{"name":"dayContent","description":"Optional JavaScript renderer for individual calendar-day content.","type":"LyraDatePickerDayContent | undefined"},{"name":"disableFuture","description":"Attribute: `disable-future`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"disablePast","description":"Attribute: `disable-past`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"disabled","description":"Attribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"disabledDates","description":"Attribute: `disabled-dates`","type":"LyraDatePickerDisabledDates","default":"''"},{"name":"disabledDaysOfWeek","description":"Attribute: `disabled-days-of-week`","type":"string","default":"''"},{"name":"firstDayOfWeek","description":"Attribute: `first-day-of-week`  \nReflected to its attribute.","type":"LyraDatePickerFirstDayOfWeek","default":"'auto'"},{"name":"focusedDate","description":"Attribute: `focused-date`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"isDateDisabled","description":"Optional JavaScript predicate that disables matching calendar dates.","type":"(date: Date) => boolean | undefined"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"max","description":"Attribute: `max`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"maxRange","description":"Attribute: `max-range`  \nReflected to its attribute.","type":"number","default":"0"},{"name":"min","description":"Attribute: `min`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"minRange","description":"Attribute: `min-range`  \nReflected to its attribute.","type":"number","default":"0"},{"name":"mode","description":"Attribute: `mode`  \nReflected to its attribute.","type":"CalendarMode","default":"'single'"},{"name":"months","description":"Attribute: `months`  \nReflected to its attribute.","type":"1 | 2","default":"1"},{"name":"nextLabel","description":"Accessible label for the next-month button. Omitted copy localizes; explicit text,\nincluding the built-in English label or an empty string, wins verbatim.\n\nAttribute: `next-label`","type":"string","default":"'Next month'"},{"name":"pageBy","description":"Attribute: `page-by`  \nReflected to its attribute.","type":"LyraDatePickerPageBy","default":"'months'"},{"name":"presets","type":"readonly LyraDateRangePreset[]"},{"name":"previousLabel","description":"Accessible label for the previous-month button. Omitted copy localizes; explicit text,\nincluding the built-in English label or an empty string, wins verbatim.\n\nAttribute: `previous-label`","type":"string","default":"'Previous month'"},{"name":"readonly","description":"Attribute: `readonly`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"selection","description":"Parsed range view of `value`. Writes share `valueAsRange` normalization and stay silent.","type":"DateRange"},{"name":"size","description":"Visual size — scales the private default behind `--lr-cell-size` proportionally; not pixel-matched to\n`lr-input`'s row-height scale (a calendar cell isn't a text row). The Web Awesome / Shoelace spellings\n`small`/`medium`/`large` are accepted for `s`/`m`/`l`, so a migration is a tag rename with no\nattribute rewrite.\n\nAttribute: `size`  \nReflected to its attribute.","type":"LyraSize","default":"'m'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"today","description":"Attribute: `today`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"value","description":"ISO value: `YYYY-MM-DD` or `YYYY-MM-DD/YYYY-MM-DD`.\n\nAttribute: `value`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"valueAsDate","description":"Date view of a single-mode value. Writes serialize to local ISO and are silent.","type":"Date | null"},{"name":"valueAsRange","description":"Date-range view of a range-mode value. Reversed endpoints are normalized.","type":"DateRange"},{"name":"view","description":"Attribute: `view`  \nReflected to its attribute.","type":"LyraDatePickerView","default":"'days'"},{"name":"weekdayFormat","description":"Attribute: `weekday-format`  \nReflected to its attribute.","type":"WeekdayFormat","default":"'short'"},{"name":"withOutsideDays","description":"Attribute: `with-outside-days`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"withWeekNumbers","description":"Attribute: `with-week-numbers`  \nReflected to its attribute.","type":"boolean","default":"false"}],"events":[{"name":"change","description":"The user committed a value. Bubbling, composed, and non-cancelable.","type":"Event"},{"name":"input","description":"The value changed during interaction (range: after the first click). Bubbling, composed, and non-cancelable.","type":"InputEvent"},{"name":"lr-focus-day","description":"Keyboard or pointer focus moved to a day; detail is `{ date }`.","type":"CustomEvent<{ date: Date }>"},{"name":"lr-view-change","description":"The user changed the calendar view; detail is `{ view, date }`.","type":"CustomEvent<{ view: LyraDatePickerView; date: Date }>"}]}},{"name":"lr-details","description":"`<lr-details>` — an accessible disclosure panel.\n\nLifecycle: opening emits `lr-show` (cancelable), then `lr-toggle`, then `lr-after-show`;\nclosing emits `lr-hide` (cancelable), then `lr-toggle`, then `lr-after-hide`. `show()`,\n`hide()` and assigning `open` all run the same sequence, as does clicking (or activating with\nthe keyboard) the summary — the native `<details>` toggle is intercepted so a vetoed `lr-show`\ncannot leave the panel visually expanded. Markup that renders open from the start emits\nnothing.\n\nA present host `aria-label`, including an explicitly empty value, names the native summary\ntrigger. When absent, the summary retains its native name-from-content behavior.\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) | Panel content. |\n| `collapse-icon` | Icon shown while the panel is open. |\n| `expand-icon` | Icon shown while the panel is closed. |\n| `header-actions` | Extra controls rendered as a sibling of the native summary in the complete header row (e.g. a trailing \"add\" button). They remain enabled and do not toggle the panel, including while the disclosure itself is disabled. |\n| `summary` | Summary content. Takes priority over `summary` when any light-DOM child carries `slot=\"summary\"` — the fallback localized \"Details\" text only appears when neither is set. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | Compatibility name for the outer disclosure container; use `details`. |\n| `content` | The panel content inside a private findable closed-state gate. |\n| `details` | The outer disclosure container. It is the same node as `base`. |\n| `header` | The complete row containing the native summary and any header actions. |\n| `header-actions` | The wrapper around the `header-actions` slot, following the private native details element in `header`. |\n| `icon` | The expand/collapse icon wrapper. |\n| `summary` | The summary control. |\n| `summary-icon` | Shoelace-compatible alias for `icon`; both names are on the same node. |\n\n---\n\n**CSS Custom Properties**\n\n- `--hide-duration` (default: `var(--lr-duration-base)`) — Collapse-icon transition duration.\n- `--lr-details-content-padding-block-end` (default: `var(--lr-details-spacing)`) — Panel content's trailing block padding, independently tunable from the summary's own padding. Same fallback chain as `--lr-details-summary-padding-block`.\n- `--lr-details-content-padding-inline` (default: `var(--lr-details-spacing)`) — Panel content's inline padding, independently tunable from the summary's own padding. Same fallback chain as `--lr-details-summary-padding-block`.\n- `--lr-details-filled-bg` (default: `var(--lr-color-brand-quiet)`) — Filled surface background.\n- `--lr-details-filled-border-color` (default: `transparent`) — Filled border color.\n- `--lr-details-filled-outlined-bg` (default: `var(--lr-color-brand-quiet)`) — Filled-outlined surface background.\n- `--lr-details-filled-outlined-border-color` (default: `var(--lr-color-border)`) — Filled-outlined border color.\n- `--lr-details-font-size` (default: `var(--lr-form-control-font-size)`) — Text size of the summary and the panel. Its private default follows the library's shared size ladder; an inherited or direct public value remains authoritative.\n- `--lr-details-gap` (default: `var(--lr-space-s)`) — Gap between summary content and its icon.\n- `--lr-details-outlined-bg` (default: `var(--lr-color-surface)`) — Outlined surface background.\n- `--lr-details-outlined-border-color` (default: `var(--lr-color-border)`) — Outlined border color.\n- `--lr-details-radius` (default: `var(--lr-radius)`) — Disclosure surface corner radius.\n- `--lr-details-spacing` (default: `var(--lr-form-control-padding-inline)`) — Block rhythm: the summary's block padding and the panel's trailing padding, kept equal so a stack of disclosures reads evenly. Its private default follows the shared ladder's inline-padding knob, whose values suit a stacked panel; the ladder's own block padding exists to fit text inside a fixed control height and would collapse the summary row. An inherited or direct public value remains authoritative.\n- `--lr-details-summary-active-bg` (default: `color-mix(...)`) — Summary pressed background.\n- `--lr-details-summary-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Summary hover background.\n- `--lr-details-summary-padding-block` (default: `var(--lr-details-spacing)`) — Summary block padding (top/bottom), independently tunable from the panel content's own padding. Falls through to `--lr-details-spacing` (and its private ladder default) when unset, so an un-set disclosure renders unchanged, mirroring how `--lr-details-gap`/`--lr-details-radius` are already independent of each other.\n- `--lr-details-summary-padding-inline` (default: `var(--lr-details-spacing)`) — Summary inline padding (start/end), independently tunable from the panel content's own padding. Same fallback chain as `--lr-details-summary-padding-block`.\n- `--show-duration` (default: `var(--lr-duration-base)`) — Expand-icon transition duration.\n- `--spacing` — Upstream-compatible spacing override for the summary and content.","attributes":[{"name":"appearance","description":"Visual surface treatment.\n\nType: `LyraDetailsAppearance`  \nDefault: `'outlined'`","value":{"type":["'filled'","'outlined'","'filled-outlined'","'plain'"]}},{"name":"disabled","description":"Disables activation and removes the native summary from sequential keyboard navigation,\nmatching the disabled trigger behavior of `lr-accordion-item`. Programmatic focus remains a\nnative `<summary>` capability.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"icon-placement","description":"Logical side of the expand/collapse icon.\n\nType: `LyraDetailsIconPlacement`  \nDefault: `'end'`","value":{"type":["'start'","'end'"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"name","description":"Groups disclosures in the same document or shadow root. Opening one closes its open peers.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"open","description":"Whether the panel is expanded. Assigning it runs the full `lr-show`/`lr-hide` lifecycle and\ncan be vetoed the same way, so the property, the reflected attribute and `show()`/`hide()`\ncan never disagree.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"size","description":"Visual density, on the library's shared ladder. Both spellings of every tier are accepted\n(`s`/`small`, `m`/`medium`, `l`/`large`), so markup migrated from Web Awesome or Shoelace\nneeds no attribute rewrite. `m` reproduces the disclosure this component had before `size`\nexisted.\n\nType: `LyraDetailsSize`  \nDefault: `'m'`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}},{"name":"summary","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}}],"slots":[{"name":"","description":"Panel content."},{"name":"collapse-icon","description":"Icon shown while the panel is open."},{"name":"expand-icon","description":"Icon shown while the panel is closed."},{"name":"header-actions","description":"Extra controls rendered as a sibling of the native summary in the complete header row (e.g. a trailing \"add\" button). They remain enabled and do not toggle the panel, including while the disclosure itself is disabled."},{"name":"summary","description":"Summary content. Takes priority over `summary` when any light-DOM child carries `slot=\"summary\"` — the fallback localized \"Details\" text only appears when neither is set."}],"js":{"properties":[{"name":"appearance","description":"Visual surface treatment.\n\nAttribute: `appearance`  \nReflected to its attribute.","type":"LyraDetailsAppearance","default":"'outlined'"},{"name":"disabled","description":"Disables activation and removes the native summary from sequential keyboard navigation,\nmatching the disabled trigger behavior of `lr-accordion-item`. Programmatic focus remains a\nnative `<summary>` capability.\n\nAttribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"iconPlacement","description":"Logical side of the expand/collapse icon.\n\nAttribute: `icon-placement`  \nReflected to its attribute.","type":"LyraDetailsIconPlacement","default":"'end'"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"name","description":"Groups disclosures in the same document or shadow root. Opening one closes its open peers.\n\nAttribute: `name`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"open","description":"Whether the panel is expanded. Assigning it runs the full `lr-show`/`lr-hide` lifecycle and\ncan be vetoed the same way, so the property, the reflected attribute and `show()`/`hide()`\ncan never disagree.\n\nAttribute: `open`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"size","description":"Visual density, on the library's shared ladder. Both spellings of every tier are accepted\n(`s`/`small`, `m`/`medium`, `l`/`large`), so markup migrated from Web Awesome or Shoelace\nneeds no attribute rewrite. `m` reproduces the disclosure this component had before `size`\nexisted.\n\nAttribute: `size`  \nReflected to its attribute.","type":"LyraDetailsSize","default":"'m'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"summary","description":"Attribute: `summary`","type":"string","default":"''"}],"events":[{"name":"lr-after-hide","description":"The panel is closed and its marker transition has finished. Nested disclosures emit the same name; handle it as this panel's event only when `event.target === event.currentTarget` (see `lr-toggle`).","type":"CustomEvent<null>"},{"name":"lr-after-show","description":"The panel is open and its marker transition has finished. Nested disclosures emit the same name; handle it as this panel's event only when `event.target === event.currentTarget` (see `lr-toggle`).","type":"CustomEvent<null>"},{"name":"lr-hide","description":"The panel is about to close. Cancelable. Nested disclosures emit the same name; handle it as this panel's event only when `event.target === event.currentTarget` (see `lr-toggle`).","type":"CustomEvent<null>"},{"name":"lr-show","description":"The panel is about to open. Cancelable. Nested disclosures emit the same name; handle it as this panel's event only when `event.target === event.currentTarget` (see `lr-toggle`).","type":"CustomEvent<null>"},{"name":"lr-toggle","description":"The disclosure state changed. `detail: { open, source }`, where `source` is `user` for summary activation, `programmatic` for `show()`/`hide()`/`open`, or `peer` when a named disclosure closes this panel. Reports the direction and source of an accepted state change. `<lr-accordion>` coordinates its direct `<lr-accordion-item>` children; Details disclosures manage their own state and optional named-peer grouping. **A nested disclosure's events are not scoped to it, so filter by target.** Every Details event bubbles and is composed, with no exception for this component. A `<lr-details>` nested inside another one — as ordinary slotted content, in the default panel or in `header-actions` — sends its own `lr-show`, `lr-hide`, `lr-toggle`, `lr-after-show` and `lr-after-hide` straight through the outer panel, so a listener bound directly on the outer `<lr-details>` also receives the inner one's, and an inner disclosure opening or closing looks identical to the outer one doing the same. It is the failure mode `<lr-dialog>`'s `lr-close` carries and documents too. This is deliberate rather than a bug to fix: non-bubbling disclosure events would be a breaking change, and `event.target`/`event.currentTarget` already give every listener what it needs to tell the two apart. Guard on the target: ```html <lr-details id=\"outer\" summary=\"Outer\"> Some outer content. <lr-details id=\"inner\" summary=\"Inner\">Inner content.</lr-details> </lr-details> <script type=\"module\"> const outer = document.querySelector('#outer'); outer.addEventListener('lr-toggle', (event) => { if (event.target !== event.currentTarget) return; // the inner details toggled, not this one // ... }); </script> ```","type":"CustomEvent<LyraDetailsToggleDetail>"}]}},{"name":"lr-dialog","description":"`<lr-dialog>` — a general-purpose modal/overlay. `role=\"dialog\"`,\nfocus-trapped while open, dismissible via Escape or (opt-in) a backdrop click, and\nscroll-locks the document for as long as it's open. While open it is promoted into the\nbrowser top layer, so no consumer stacking context can render on top of it. The mapped\n`label` property renders as a visible title and the close affordance is present by default;\n`closable=\"false\"` plus either header-suppression spelling support custom chrome. `no-header` is\nShoelace's name for it and `without-header` is Web Awesome's; both are current upstream\nspellings, neither is deprecated, and both are read.\n\nLifecycle: `show()` emits `lr-show` (cancelable) and then, once the enter animation has\nfinished, `lr-after-show`. `hide()`/`close()` emit `lr-hide` (cancelable), then\n`lr-close` (cancelable, carrying the dismissal reason), then — once the exit animation\nhas finished — `lr-after-hide`. Assigning `open` runs the same lifecycle, so the property, the\nreflected attribute, and the two method calls can never disagree. Markup that renders open\nfrom the start emits nothing, matching `<lr-menu>`.\nThe panel resolves `dialog.show`/`dialog.hide` through the public animation registry; the\nbackdrop resolves `dialog.overlay.show`/`dialog.overlay.hide`. A per-element registration wins\nover a page default, while keyframes-only overrides retain the dialog's token-derived timing.\n\nAccessible naming and visible-title precedence are independent. A host `aria-label` wins by\nattribute presence, including an explicitly empty value, followed by `accessible-label`, then\nthe text of a direct light-DOM heading. Otherwise the visible title wrapper names the panel.\nWithin that wrapper the rich `label` slot wins over the `label` property, which wins over the\nlegacy `heading` property. Explicit accessible-only naming never suppresses that visible title.\n\nThe slotted-heading case deliberately uses `aria-label` (a copied string)\nrather than `aria-labelledby` pointing at the heading's `id`: the heading is\n*light-DOM* content while `[part=\"panel\"]` lives in this element's\n*shadow* tree, and an ID-reference attribute can't resolve across that\nboundary (verified against axe's `aria-dialog-name` rule) — unlike the\nmapped-title cases above, where the target element is rendered\ninside the same shadow root it labels, so `aria-labelledby` there is safe.\nThe `label` *slot* is safe for the same reason: `aria-labelledby` targets the shadow-owned\n`part=\"heading\"` wrapper, and the accessible-name computation flattens the slot inside it.\nThat generated visible title is a level-three heading by default; set `heading-level` from\n`1`–`6` to fit the surrounding outline, or `none` for visual-only title text. A direct\nlight-DOM heading retains its own level instead.\n\n`closable` defaults to true and renders a close (X) button in the header row (creating one, with\nno heading text, if neither `heading` nor the `label` slot is set) that closes the dialog via\nthe same `close()` path as Escape/backdrop-dismiss, with reason `'close-button'`.\n\nThe `body` part is the element that scrolls, so it carries `tabindex=\"-1\"`: a dialog holding\nonly prose, a table, or a rendered document would otherwise have no keyboard stop at all and\nits content would be readable by mouse alone. It joins the Tab order only while it actually\noverflows, sorts behind any control inside it for initial focus, and shows the standard focus\nring on `::part(body)` when it takes focus.\n\nStacking: opening one `<lr-dialog>` while another is already open (e.g. a\n`confirm()` launched from within an already-open dialog) is supported --\nEscape and the Tab focus trap only ever act on the topmost open dialog, so\ndialogs beneath it stay open and untouched until the one on top closes.\n\nRemoving label safely omits its fallback title. Open dialog and drawer names follow supported name and exclusion attribute changes on direct unslotted headings, while host naming retains precedence; nested and slot-empty headings remain outside automatic discovery.\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 dialog body. |\n| `footer` | Action buttons, rendered in a bottom row. |\n| `header-actions` | Extra controls rendered in the header row, before the built-in close button. |\n| `label` | Rich header content, rendered in the header row and used as the panel's accessible name. Wins over the plain-string `label` and legacy `heading` properties. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `backdrop` | The full-viewport scrim behind the panel; also carries `overlay`. |\n| `base` | Shoelace wrapper alias. |\n| `body` | The wrapper around the default slot. |\n| `close-button` | The built-in close button, rendered inside `header` only when `closable` is `true`. |\n| `close-button__base` | Exported mapped alias on the close button, on the same node. |\n| `close-button__control` | The composed `<lr-icon-button>`'s own native control, forwarded because the painted surface now sits one shadow boundary deeper than `close-button`. As of 16.0.0 the close button IS an `<lr-icon-button>`, so its background, radius, hover/press mixes, focus ring and hit-area floor come from `--lr-icon-button-*`; a rule that painted through `::part(close-button)` moves here or onto the token. |\n| `dialog` | Web Awesome alias on the panel. |\n| `footer` | The wrapper around the `footer` slot. |\n| `header` | The header row, rendered when the `label` slot is filled, `label`/`heading` is set (and no heading is slotted into the default slot), `header-actions` is filled, and/or `closable` is `true` — and never when `noHeader` or `withoutHeader` is set. |\n| `header-actions` | The wrapper around the `header-actions` slot. |\n| `heading` | The visible title inside `header`; also carries `title` and `label`, and owns the configured heading semantics unless opted out. |\n| `label` | Mapped alias on the visible title. |\n| `overlay` | Shoelace alias on the backdrop. |\n| `panel` | The dialog panel itself (`role=\"dialog\"` while open); also carries `dialog`. Shrink-wraps to its content by default, capped at `--lr-dialog-max-width` (default `32rem` at the `size=\"m\"` tier — see the `size` property); set `--lr-dialog-width` for an assertive width instead of only a cap. `--lr-dialog-height` is the same idea on the block axis: left unset the panel stays content-sized (capped at the viewport), and set it gives `body` a definite size to fill and scroll within while `header`/ `footer` keep their natural size. |\n| `title` | Mapped alias on the visible title. |\n\n---\n\n**CSS Custom Properties**\n\n- `--backdrop-filter` (default: `var(--lr-dialog-backdrop-filter,none)`) — Mapped backdrop-filter alias.\n- `--body-spacing` — Shoelace body padding override.\n- `--footer-spacing` — Shoelace footer padding override.\n- `--header-spacing` — Mapped header padding override.\n- `--hide-duration` — Mapped closing animation duration.\n- `--lr-dialog-backdrop-duration` (default: `var(--lr-duration-fast)`) — Duration of the backdrop's fade.\n- `--lr-dialog-backdrop-filter` (default: `none`) — `backdrop-filter` applied to the scrim, for a frosted-glass treatment over the page behind it.\n- `--lr-dialog-height` (default: `auto`) — Assertive block size for the panel, mirroring `--lr-dialog-width` on the other axis. Left at `auto` the panel shrink-wraps to its content, unchanged from before this property existed; always capped at `100%` (the viewport) like every other panel dimension. With it set, `body`'s own `flex: 1 1 auto` is what actually gives slotted content a definite, fillable block size -- `header` and `footer` keep their natural size and only `body` grows or shrinks into the remaining space.\n- `--lr-dialog-max-width` (default: `var(--lr-dialog-width, var(--_lr-dialog-max-width))`) — Cap on the panel's inline size. Falls back to `--lr-dialog-width` when that is set, so an assertive width is not clipped by the tier default; the viewport (`100%`) is always a hard limit on top. The innermost fallback steps with `size` across the shared six-step ladder (`20rem` at `2xs` up to `48rem` at `xl`, `32rem` unchanged at the `m` default) -- an inherited or direct value here still wins outright over every tier.\n- `--lr-dialog-overlay-color` (default: `var(--lr-color-overlay)`) — Backdrop scrim color.\n- `--lr-dialog-panel-duration` (default: `var(--lr-duration-base)`) — Duration of the panel's enter/exit animation.\n- `--lr-dialog-spacing` (default: `var(--lr-space-l)`) — Padding inside the body, and the inline padding of the header and footer rows.\n- `--lr-dialog-spacing-block` (default: `var(--lr-space-m)`) — Block padding of the header and footer rows, which are tighter than the body by default.\n- `--lr-dialog-width` (default: `auto`) — Assertive inline size for the panel. Left at `auto` the panel shrink-wraps to its content.\n- `--lr-overlay-border` (default: `var(--lr-color-border)`) — Shared floating-surface edge colour, on the panel and on the header's and footer's dividing rules.\n- `--lr-overlay-radius` (default: `var(--lr-radius)`) — Shared floating-surface corner radius, on the panel and on the close button.\n- `--lr-overlay-shadow-modal` (default: `var(--lr-shadow-xl)`) — Elevation of a modal panel. A separate tier from `--lr-overlay-shadow-anchored`, so raising popups never raises dialogs.\n- `--lr-overlay-surface` (default: `var(--lr-color-surface-overlay)`) — Shared floating-surface fill, on the panel. The same family every anchored popup now reads, so one declaration retints the dialog and the popups opened from it together.\n- `--show-duration` — Mapped opening animation duration.\n- `--spacing` (default: `var(--lr-dialog-spacing,var(--lr-space-l))`) — Mapped shared region spacing.\n- `--width` (default: `var(--lr-dialog-width,auto)`) — Mapped panel width alias.","attributes":[{"name":"accessible-label","description":"Explicit accessible-only panel name. Unlike `label`, it never renders visible text.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"aria-label","description":"Host-level `aria-label` override for the panel's accessible name — wins by attribute\npresence, including an explicitly empty value, over every other naming source (a slotted\nheading, the `label` slot, `heading`, the `label` property) without suppressing visible\nheading chrome, matching `<lr-date-input>`'s `accessibleLabel` pattern. See the class doc for\nthe full precedence order. Set as a plain `aria-label` attribute on `<lr-dialog>` itself, not\na public JS property.\n\nType: `string | null`  \nDefault: `null`"},{"name":"closable","description":"Renders a built-in close (X) button in the header row (creating one,\nwith no heading text, if `label` and `heading` are unset), wired to the same\n`close()` path Escape/backdrop-dismiss already use, with reason\n`'close-button'`.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"heading","description":"Legacy visible title fallback. The richer `label` slot and mapped `label` property win. Has\nno effect when a direct light-DOM heading already supplies custom title chrome.\n\nType: `string | undefined`"},{"name":"heading-level","description":"Semantic level of the generated visible title. Use `none` for visual-only text. A direct\nlight-DOM heading retains its own native/ARIA level; invalid untyped values use level 3.\n\nType: `LyraHeadingLevel`  \nDefault: `'3'`","value":{"type":["'1'","'2'","'3'","'4'","'5'","'6'","'none'"]}},{"name":"label","description":"Visible mapped title. The richer `label` slot wins when both are supplied.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"light-dismiss","description":"Dismisses the dialog on a backdrop click. Opt-in and `false` by default, matching\n`wa-dialog`. This was previously spelled `no-light-dismiss` — an opt-*out* whose default left\nbackdrop dismissal on, so a mechanical `wa-dialog` → `lr-dialog` rename silently flipped the\nbehaviour of every migrated dialog. A rename that changes what the markup does with nothing\nto warn on is worse than no rename at all, so the polarity now matches upstream exactly.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"no-header","description":"Shoelace's spelling (`sl-dialog`'s `no-header`) for suppressing the header row, read alongside\nWeb Awesome's `withoutHeader` above so a consumer arriving from either upstream finds their\nown attribute working. Neither is deprecated.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"open","description":"Whether the dialog is open. Assigning it runs the full `lr-show`/`lr-hide` lifecycle, so it\nstays in sync with `show()`/`hide()`/`close()` and can be vetoed the same way. Markup that\nrenders open from the start emits nothing.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"size","description":"Visual width tier for the panel, on the library's shared six-step size ladder. `'m'` (the\ndefault) is this component's pre-existing behaviour, unchanged: an unset panel still caps at\n`--lr-dialog-max-width`'s literal `32rem` default. Every other tier scales that same cap, from\na compact `20rem` at `2xs` up to a roomy `48rem` at `xl`; an explicit `--lr-dialog-width` or\n`--lr-dialog-max-width` override still wins over any tier.\n\nType: `LyraSize`  \nDefault: `'m'`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}},{"name":"with-footer","description":"SSR hint that keeps the footer wrapper rendered before slot assignment is observable.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"without-header","description":"Suppresses the header row entirely, whatever `heading`, `closable`, the `label` slot or the\n`header-actions` slot would otherwise render. For a dialog that owns its own chrome. This is\nWeb Awesome's spelling (`wa-dialog`'s `without-header`); `noHeader` below is Shoelace's. Both\nare current upstream names, both are read, and neither is deprecated.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"","description":"The dialog body."},{"name":"footer","description":"Action buttons, rendered in a bottom row."},{"name":"header-actions","description":"Extra controls rendered in the header row, before the built-in close button."},{"name":"label","description":"Rich header content, rendered in the header row and used as the panel's accessible name. Wins over the plain-string `label` and legacy `heading` properties."}],"js":{"properties":[{"name":"accessibleLabel","description":"Explicit accessible-only panel name. Unlike `label`, it never renders visible text.\n\nAttribute: `accessible-label`","type":"string","default":"''"},{"name":"closable","description":"Renders a built-in close (X) button in the header row (creating one,\nwith no heading text, if `label` and `heading` are unset), wired to the same\n`close()` path Escape/backdrop-dismiss already use, with reason\n`'close-button'`.\n\nAttribute: `closable`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"heading","description":"Legacy visible title fallback. The richer `label` slot and mapped `label` property win. Has\nno effect when a direct light-DOM heading already supplies custom title chrome.\n\nAttribute: `heading`","type":"string | undefined"},{"name":"headingLevel","description":"Semantic level of the generated visible title. Use `none` for visual-only text. A direct\nlight-DOM heading retains its own native/ARIA level; invalid untyped values use level 3.\n\nAttribute: `heading-level`  \nReflected to its attribute.","type":"LyraHeadingLevel","default":"'3'"},{"name":"label","description":"Visible mapped title. The richer `label` slot wins when both are supplied.\n\nAttribute: `label`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"lightDismiss","description":"Dismisses the dialog on a backdrop click. Opt-in and `false` by default, matching\n`wa-dialog`. This was previously spelled `no-light-dismiss` — an opt-*out* whose default left\nbackdrop dismissal on, so a mechanical `wa-dialog` → `lr-dialog` rename silently flipped the\nbehaviour of every migrated dialog. A rename that changes what the markup does with nothing\nto warn on is worse than no rename at all, so the polarity now matches upstream exactly.\n\nAttribute: `light-dismiss`","type":"boolean","default":"false"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"modal","description":"Shoelace-compatible modal controller. External activation suspends this dialog's focus/Escape\nownership without changing its logical `open` state; deactivation restores it.","type":"LyraDialogModalController","default":"{ activateExternal: () => { this.externalModalDepth++; if (this.externalModalDepth === 1) this.overlay?.suspend(); }, deactivateExternal: () => { if (this.externalModalDepth === 0) return; this.externalModalDepth--; if (this.externalModalDepth === 0 && this.open && this.modalSurface) { this.overlay?.resume(); queueMicrotask(() => this.focusInitial()); } }, }"},{"name":"noHeader","description":"Shoelace's spelling (`sl-dialog`'s `no-header`) for suppressing the header row, read alongside\nWeb Awesome's `withoutHeader` above so a consumer arriving from either upstream finds their\nown attribute working. Neither is deprecated.\n\nAttribute: `no-header`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"open","description":"Whether the dialog is open. Assigning it runs the full `lr-show`/`lr-hide` lifecycle, so it\nstays in sync with `show()`/`hide()`/`close()` and can be vetoed the same way. Markup that\nrenders open from the start emits nothing.\n\nAttribute: `open`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"size","description":"Visual width tier for the panel, on the library's shared six-step size ladder. `'m'` (the\ndefault) is this component's pre-existing behaviour, unchanged: an unset panel still caps at\n`--lr-dialog-max-width`'s literal `32rem` default. Every other tier scales that same cap, from\na compact `20rem` at `2xs` up to a roomy `48rem` at `xl`; an explicit `--lr-dialog-width` or\n`--lr-dialog-max-width` override still wins over any tier.\n\nAttribute: `size`  \nReflected to its attribute.","type":"LyraSize","default":"'m'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"withFooter","description":"SSR hint that keeps the footer wrapper rendered before slot assignment is observable.\n\nAttribute: `with-footer`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"withoutHeader","description":"Suppresses the header row entirely, whatever `heading`, `closable`, the `label` slot or the\n`header-actions` slot would otherwise render. For a dialog that owns its own chrome. This is\nWeb Awesome's spelling (`wa-dialog`'s `without-header`); `noHeader` below is Shoelace's. Both\nare current upstream names, both are read, and neither is deprecated.\n\nAttribute: `without-header`  \nReflected to its attribute.","type":"boolean","default":"false"}],"events":[{"name":"lr-after-hide","description":"The dialog is closed and its exit animation has finished. Descendants emit the same name; handle it as this dialog's event only when `event.target === event.currentTarget`.","type":"CustomEvent<null>"},{"name":"lr-after-show","description":"The dialog is open and its enter animation has finished. Descendants emit the same name; handle it as this dialog's event only when `event.target === event.currentTarget`.","type":"CustomEvent<null>"},{"name":"lr-close","description":"`detail: DialogCloseReason`. Cancelable — a listener calling `preventDefault()` stops the dialog from closing, for every dismissal path (Escape, backdrop, the built-in close button, `hide()`, `open = false`, or a consumer's own `close()` call). Fires after `lr-hide` and carries the one thing `lr-hide` does not: which affordance asked for the close. The plain `lr-close` spelling matches `<lr-tool-select-dialog>`, `<lr-tool-result-dialog>`, and `<lr-tool-approval-dialog>`, whose own docs already describe their close-reason detail as mirroring this shape. Also fired (with reason `'unmount'`, non-cancelable there since the element is already being removed) when the dialog is removed from the DOM while still open. **The name is not dialog-scoped, so filter by target.** `lr-close` is emitted by nine components in this library, several of which are commonly nested *inside* a dialog: `<lr-callout>` (an inline notice above a form), `<lr-tab>`/`<lr-tab-group>`, `<lr-command-palette>`, `<lr-document-viewer>`, `<lr-responsive-panel>`, and the three tool dialogs. Library events bubble and are composed, so a listener bound directly on `<lr-dialog>` also receives a descendant's close — and a closable callout inside a dialog would otherwise dismiss the whole dialog. Their details differ too (`<lr-callout>` and `<lr-tab>` carry none, where this event carries a `DialogCloseReason`), so a handler reading `event.detail.reason` would throw on a foreign one. This is latent rather than broken-on-arrival, because a callout or tab only emits once given a close affordance — which is what makes it a bad failure mode: it appears later and presents as the dialog dismissing itself. Guard on the target, the way `<lr-document-viewer>` already does internally: ```js dialog.addEventListener('lr-close', (event) => { if (event.target !== event.currentTarget) return; // a descendant's close, not this dialog's // ... }); ```","type":"CustomEvent<DialogCloseReason>"},{"name":"lr-hide","description":"The dialog is about to close, for every dismissal path. Cancelable — `preventDefault()` keeps it open and stops `lr-close` from firing at all. Detail is `{ source: Element }`, the affordance or host that requested the transition. The single exception is an open dialog being removed from the document: the close has already happened and cannot be undone, so that one is announced non-cancelable. Descendants emit the same name; handle it as this dialog's event only when `event.target === event.currentTarget`.","type":"CustomEvent<LyraDialogHideDetail>"},{"name":"lr-initial-focus","description":"Emitted immediately before the first automatic focus movement for an open activation. Cancelable; vetoing it leaves focus where the caller put it. CSS-hidden dialogs defer it until rendered, and reconnecting the same open dialog does not repeat it.","type":"CustomEvent<null>"},{"name":"lr-request-close","description":"A built-in affordance requested dismissal. Cancelable; detail is `{ source: 'close-button' | 'keyboard' | 'overlay' }`.","type":"CustomEvent<LyraDialogRequestCloseDetail>"},{"name":"lr-show","description":"The dialog is about to open. Cancelable — `preventDefault()` keeps it closed. Descendants emit the same name; handle it as this dialog's event only when `event.target === event.currentTarget`.","type":"CustomEvent<null>"}]}},{"name":"lr-diff-view","description":"`<lr-diff-view>` — a real two-string line diff (Hirschberg LCS alignment), rendered as\ninterleaved unified-diff output -- not diff-flavored syntax highlighting over an\nalready-formatted string (`lr-code-block`'s `language=\"diff\"` only lexically colors a string\nthe consumer already unified-diffed; it has no two-string-compare entry point). First-party\ninvention (no Web Awesome equivalent).\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 root wrapper. |\n| `copy-button` | The copy affordance, only rendered while `copyable`. |\n| `limit` | The localized fallback rendered when either input exceeds `maxLines`. |\n| `line` | A single line. Carries `data-type=\"equal\"\\|\"add\"\\|\"remove\"\\|\"empty\"\\|\"fold\"` (`\"empty\"` is an unbalanced-replace placeholder cell in `layout=\"split\"` and never carries a `+`/`-` prefix; `\"fold\"` is the collapsed-unchanged-lines marker `contextLines` produces). |\n| `side` | One column in `layout=\"split\"` (`data-side=\"old\"\\|\"new\"`). |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-diff-view-add-background` (default: `var(--lr-color-success-quiet)`) — Added-line background.\n- `--lr-diff-view-add-color` (default: `var(--lr-color-success)`) — Added-line text color.\n- `--lr-diff-view-fold-background` (default: `var(--lr-color-surface-raised)`) — Fold-marker background.\n- `--lr-diff-view-fold-color` (default: `var(--lr-color-text-quiet)`) — Fold-marker text color.\n- `--lr-diff-view-font` (default: `var(--lr-font-mono)`) — Font family used for the diff lines.\n- `--lr-diff-view-max-height` (default: `none`) — Cap on `[part=\"base\"]`'s block size, past which the view scrolls internally. The `maxHeight` property sets this token inline on `[part=\"base\"]`.\n- `--lr-diff-view-remove-background` (default: `var(--lr-color-danger-quiet)`) — Removed-line background.\n- `--lr-diff-view-remove-color` (default: `var(--lr-color-danger)`) — Removed-line text color.","attributes":[{"name":"context-lines","description":"How many unchanged lines to keep visible immediately before/after each change. Default\n`undefined` renders every line unconditionally, exactly like before this property existed. Set\nto a finite number `>= 0` to collapse a longer run of unchanged lines behind a single fold\nmarker reporting how many lines it hides -- the same context-window convention unified diffs\nand `git diff`'s `-U<n>` use. A negative or non-finite value is treated as unset (no folding).\n\nType: `number | undefined`"},{"name":"copyable","description":"Shows a copy-to-clipboard button for the full unified-diff text. `false` (the default)\nrenders no button.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"language","description":"A shiki-recognized language id. Highlighting activates only when this has a matching entry in\n`languages` -- there is deliberately no default full-table `lr-code-block`-style fallback, so\nthis component never reaches shiki's ~200-language dynamic-import table.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"layout","description":"Type: `LyraDiffViewLayout`","value":{"type":["'unified'","'split'"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max-height","description":"A CSS length (e.g. `\"20rem\"`); once set, the view scrolls internally past this height\ninstead of growing the page. Invalid values are ignored.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max-lines","description":"Maximum lines accepted on either input side before rendering a bounded fallback. Defaults\nto `5000`. `Infinity` relaxes this line-count limit; aggregate text and comparison work\nremain bounded.\n\nType: `number`  \nDefault: `5000`","value":{"type":["number"]}}],"js":{"properties":[{"name":"contextLines","description":"How many unchanged lines to keep visible immediately before/after each change. Default\n`undefined` renders every line unconditionally, exactly like before this property existed. Set\nto a finite number `>= 0` to collapse a longer run of unchanged lines behind a single fold\nmarker reporting how many lines it hides -- the same context-window convention unified diffs\nand `git diff`'s `-U<n>` use. A negative or non-finite value is treated as unset (no folding).\n\nAttribute: `context-lines`","type":"number | undefined"},{"name":"copyable","description":"Shows a copy-to-clipboard button for the full unified-diff text. `false` (the default)\nrenders no button.\n\nAttribute: `copyable`","type":"boolean","default":"false"},{"name":"language","description":"A shiki-recognized language id. Highlighting activates only when this has a matching entry in\n`languages` -- there is deliberately no default full-table `lr-code-block`-style fallback, so\nthis component never reaches shiki's ~200-language dynamic-import table.\n\nAttribute: `language`","type":"string","default":"''"},{"name":"languages","description":"Grammar definitions this instance can highlight, same shape as `lr-code-block-core`'s own\n`languages`.","type":"Readonly<\n    Record<string, ShikiLanguageInput>\n  > | undefined"},{"name":"layout","description":"Attribute: `layout`  \nReflected to its attribute.","type":"LyraDiffViewLayout"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"maxHeight","description":"A CSS length (e.g. `\"20rem\"`); once set, the view scrolls internally past this height\ninstead of growing the page. Invalid values are ignored.\n\nAttribute: `max-height`","type":"string","default":"''"},{"name":"maxLines","description":"Maximum lines accepted on either input side before rendering a bounded fallback. Defaults\nto `5000`. `Infinity` relaxes this line-count limit; aggregate text and comparison work\nremain bounded.\n\nAttribute: `max-lines`","type":"number","default":"5000"},{"name":"newText","description":"The \"after\" text. Default `''` renders an all-removals diff of `oldText`.","type":"string","default":"''"},{"name":"oldText","description":"The \"before\" text. Default `''` renders an all-additions diff of `newText`.","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-copy","description":"Fired after clipboard writing fulfills. The frozen shared outcome detail is `{ ok: true, text }`, where `text` is the full unified diff.","type":"CustomEvent<LyraClipboardWriteSuccess>"},{"name":"lr-copy-error","description":"The clipboard write failed. The frozen shared outcome detail is `{ ok: false, text, reason, error }`, where `reason` is `'unsupported' | 'denied' | 'failed'`.","type":"CustomEvent<LyraClipboardWriteFailure>"},{"name":"lr-error","description":"The clipboard write failed. A bubbling, composed, non-cancelable event with no detail.","type":"CustomEvent<null>"}]}},{"name":"lr-divider","description":"`<lr-divider>` — a themeable semantic separator.\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 separator element. |\n\n---\n\n**CSS Custom Properties**\n\n- `--color` (default: `var(--lr-color-border)`) — Separator color.\n- `--spacing` (default: `0`) — Space on both block sides (inline sides when vertical).\n- `--width` (default: `var(--lr-border-width-thin)`) — Separator thickness.","attributes":[{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"orientation","description":"Type: `LyraDividerOrientation`  \nDefault: `'horizontal'`","value":{"type":["'horizontal'","'vertical'"]}},{"name":"vertical","description":"Shoelace-compatible vertical-orientation shorthand.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"js":{"properties":[{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"orientation","description":"Attribute: `orientation`  \nReflected to its attribute.","type":"LyraDividerOrientation","default":"'horizontal'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"vertical","description":"Shoelace-compatible vertical-orientation shorthand.\n\nAttribute: `vertical`  \nReflected to its attribute.","type":"boolean","default":"false"}]}},{"name":"lr-dock-panel","description":"`<lr-dock-panel>` — a single panel docked to one edge of whatever\ncontains it, resizable by dragging its inner edge. Unlike `<lr-multi-split>`\n(which owns and lays out N sibling panels, and requires restructuring a\nlayout so every panel becomes its direct child), this is one self-\ncontained element you drop next to your existing content -- typically as\nan absolutely-positioned child of a `position: relative` parent, or as a\nflex item alongside a main-content sibling. It deliberately imposes no\n`position`/`inset` of its own (see the styles module): it only manages its\nown size along the resize axis (`inline-size` for `start`/`end`,\n`block-size` for `top`/`bottom`) and fills 100% of the cross axis, leaving\nwhere it sits in the page entirely up to the consumer's own layout. Live\ncontainer changes and direct property writes are reconciled without resize\ninteraction events so the rendered extent and separator range remain\nbounded atomically.\n\n`lr-multi-split` stays the right primitive for the multi-sibling-panel case;\nthis is the primitive for the single-edge-docked case, kept as a separate\ncomponent rather than a second mode bolted onto `lr-multi-split`'s API.\n\nPointer-drag-resize mirrors `lr-multi-split`'s pointer-capture technique\n(an admitted primary-button pointerdown captures the pointer on the handle,\npointermove computes a new size, and pointerup/pointercancel/\nlostpointercapture all release it) but\nfor a single draggable edge instead of N-1 dividers between N panels, and\nreasons in raw pixels throughout rather than percent -- `extent` is a CSS\nlength, and pointer movement is naturally pixels, so there's no percent\ndomain to convert through here. Every resize (drag step, drag release, or\nkeyboard step) always commits `extent` as a `px` string regardless of what\nunit `extent`/`min-extent`/`max-extent` were originally expressed in -- a drag\ninherently produces a pixel-precise result, so re-expressing it in the\ncaller's original unit (e.g. back into `rem`) would just be lossy\nre-derivation for no benefit.\n\nCollapsing hides the slotted content but keeps the panel itself at a\nsmall persistent \"rail\" width/height (`--lr-dock-panel-collapsed-size`,\ndefault `var(--lr-icon-button-size)`) rather than collapsing to zero --\na zero-size collapsed panel would have nowhere left to host the toggle\nbutton that re-expands it. `extent` itself is left untouched while\ncollapsed, so re-expanding restores what it was unless the live container\nbounds now require a smaller or larger valid extent.\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's own content. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The panel root. |\n| `collapse-toggle` | The collapse/expand toggle button. Only rendered when `collapsible`. |\n| `content` | The wrapper around the default slot; hidden while `collapsed`. |\n| `handle` | The draggable resize handle on the panel's inner edge. Its numeric ARIA range remains in CSS pixels while `aria-valuetext` reports the current extent through the effective locale. Only rendered when `resizable` and not `collapsed`. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-dock-panel-collapse-toggle-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Background of `collapse-toggle` on hover; also feeds its pressed background via `color-mix()`.\n- `--lr-dock-panel-collapse-toggle-hover-color` (default: `var(--lr-color-brand)`) — Text/icon color of `collapse-toggle` on hover, reused verbatim for its pressed color too.\n- `--lr-dock-panel-collapsed-size` (default: `var(--lr-icon-button-size)`) — The extent the panel keeps along its resize axis while `collapsed` -- enough to still host the toggle button that re-expands it.\n- `--lr-dock-panel-handle-active-color` (default: `color-mix(in oklab, var(--lr-dock-panel-handle-hover-color, var(--lr-color-brand)), var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Background of `handle` while actively dragged/pressed.\n- `--lr-dock-panel-handle-hover-color` (default: `var(--lr-color-brand)`) — Background of `handle` on hover and keyboard focus -- scoped separately from `collapse-toggle`'s own hover tokens above even though both default to the same brand token, since the two serve unrelated purposes (drag affordance vs. button feedback).","attributes":[{"name":"collapsed","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"collapsible","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"edge","description":"Type: `LyraDockPanelEdge`  \nDefault: `'end'`","value":{"type":["'start'","'end'","'top'","'bottom'"]}},{"name":"extent","description":"The current docked extent along the resize axis, as a CSS length (e.g. `\"320px\"`).\n\nSpelled `extent`, not `size`: everywhere else in the library `size` names a tier on the\nshared six-step ladder (`internal/variants.ts`'s `LyraSize`), and this is an arbitrary CSS\nlength instead. A clean rename with no alias -- `size`/`min-size`/`max-size` on\n`<lr-dock-panel>` are simply unknown attributes now.\n\nType: `string`  \nDefault: `'280px'`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max-extent","description":"Maximum resize bound, as a CSS length. Empty means \"no explicit cap\" -- the live extent of\nthe containing element is used instead, so the panel still can't be dragged wider/taller than\nits container.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"min-extent","description":"Minimum resize bound, as a CSS length.\n\nType: `string`  \nDefault: `'160px'`","value":{"type":["string"]}},{"name":"resizable","description":"When `false`, no drag handle renders at all and the panel is a fixed size.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}}],"slots":[{"name":"","description":"The panel's own content."}],"js":{"properties":[{"name":"collapsed","description":"Attribute: `collapsed`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"collapsible","description":"Attribute: `collapsible`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"edge","description":"Attribute: `edge`  \nReflected to its attribute.","type":"LyraDockPanelEdge","default":"'end'"},{"name":"extent","description":"The current docked extent along the resize axis, as a CSS length (e.g. `\"320px\"`).\n\nSpelled `extent`, not `size`: everywhere else in the library `size` names a tier on the\nshared six-step ladder (`internal/variants.ts`'s `LyraSize`), and this is an arbitrary CSS\nlength instead. A clean rename with no alias -- `size`/`min-size`/`max-size` on\n`<lr-dock-panel>` are simply unknown attributes now.\n\nAttribute: `extent`","type":"string","default":"'280px'"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"maxExtent","description":"Maximum resize bound, as a CSS length. Empty means \"no explicit cap\" -- the live extent of\nthe containing element is used instead, so the panel still can't be dragged wider/taller than\nits container.\n\nAttribute: `max-extent`","type":"string","default":"''"},{"name":"minExtent","description":"Minimum resize bound, as a CSS length.\n\nAttribute: `min-extent`","type":"string","default":"'160px'"},{"name":"resizable","description":"When `false`, no drag handle renders at all and the panel is a fixed size.\n\nAttribute: `resizable`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-collapse-change","description":"Non-cancelable post-commit notification from the built-in collapse toggle. Not fired when a consumer sets `collapsed` directly. `detail: { collapsed }` (the new `collapsed` state).","type":"CustomEvent<LyraDockPanelCollapseChangeDetail>"},{"name":"lr-collapse-request","description":"A cancelable proposed `collapsed` state from the built-in collapse toggle. Call `preventDefault()` to keep `collapsed` unchanged. Not fired when a consumer sets `collapsed` directly. `detail: { collapsed }`.","type":"CustomEvent<LyraDockPanelCollapseChangeDetail>"},{"name":"lr-resize-change","description":"Frozen `detail: { extent }`, fired once on genuine pointerup after at least one value transition and the drag's `lr-resize-request` was not prevented, and after each genuine keyboard step whose own `lr-resize-request` was not prevented. Pointer cancellation, lost capture, policy/geometry mutation, no-op attempts, and a prevented `lr-resize-request` all emit nothing.","type":"CustomEvent<LyraDockPanelResizeDetail>"},{"name":"lr-resize-input","description":"Frozen `detail: { extent }` (a `px` CSS length string), fired for every genuine pointer or keyboard value transition. Fully clamped/no-op attempts emit nothing.","type":"CustomEvent<LyraDockPanelResizeDetail>"},{"name":"lr-resize-request","description":"A cancelable proposed `extent` (a `px` CSS length string), `detail: { extent }`, fired before a discrete keyboard step commits and before a pointer drag's final settle commits. Call `preventDefault()` to reject it: a keyboard step simply does not apply, and a drag's final settle snaps the panel back to the size it had before that drag gesture began. Not fired for a continuous pointer drag's own intermediate ticks -- checking a cancelable event on every pointermove would make a live drag visibly stutter -- only its final settle on release.","type":"CustomEvent<LyraDockPanelResizeDetail>"}]}},{"name":"lr-document-compare","description":"`<lr-document-compare>` — side-by-side or inline comparison of two document versions, composed\nentirely from two existing primitives rather than reimplementing either: `<lr-diff-view>` is the\nreal two-string line diff (`view=\"diff\"`, the default), and `<lr-document-preview>` renders each\nversion's own actual content in `view=\"side-by-side\"`.\n\n**Synchronized anchors.** `<lr-diff-view>`'s own `layout=\"split\"` needs no scroll-sync of its\nown -- both columns already live inside one shared scrolling container, so they move together\nfor free. `view=\"side-by-side\"` is different: it renders two *independent*\n`<lr-document-preview>` panes, each with its own scrollbar, so nothing keeps them aligned on its\nown. This component adds exactly two minimal, purpose-built coordination mechanisms for that\ncase (mirroring `<lr-compare-panel>`'s own proven proportional-scroll algorithm rather than\ninventing a new one):\n- **Continuous scroll sync** (`syncScroll`, default `true`): scrolling either pane\n  proportionally scrolls the other to the same *fraction* of its own scrollable range, not the\n  same pixel offset -- the two versions can have very different lengths. A re-entrancy guard\n  stops the mirrored write from bouncing back.\n- **Highlight-anchor sync**: activating a region highlight in one pane (`lr-highlight-activate`)\n  that shares its normalized `id` with a highlight in the *other* preview scrolls that pane to\n  its own matching highlight via `<lr-document-preview>`'s own `scrollToAnchor()`. Both lookup\n  and activation use the preview's trimmed, nonempty, first-wins highlight projection. The\n  `lr-highlight-activate` event itself still bubbles through unchanged (`detail: {\n  highlightId }`, no\n  side discriminator) so an existing listener contract stays exactly what\n  `<lr-document-preview>` already documents.\n- A shared `anchor` property (same declarative shape as `<lr-document-viewer>`'s own `anchor`)\n  drives both panes to the same target at once via their own `scrollToAnchor()`.\n- Replacing a pane with a different source identity resets that pane to the top (both panes while\n  `syncScroll` is true). Re-rendering the same identity preserves reading position, and an active\n  shared `anchor` always wins over the reset.\n\nA nonempty host `aria-label` makes the host the sole named semantic owner. An explicitly empty\nhost label remains on the shadow group, and absence restores its localized comparison label.\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| `base` | The root wrapper. |\n| `diff` | The internal `<lr-diff-view>`, rendered while `view=\"diff\"`. |\n| `pane-empty` | The placeholder shown in a pane whose version is unset. |\n| `pane-header` | A pane's visible label. |\n| `pane-new` | The second (new/after) version's labeled, independently-scrollable pane. |\n| `pane-old` | The first (old/before) version's labeled, independently-scrollable pane. |\n| `panes` | The row (or, under 640px, column) wrapping both panes, rendered while `view=\"side-by-side\"`. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-document-compare-pane-max-height` (default: `var(--lr-size-24rem)`) — Maximum block size of a side-by-side pane before it scrolls internally.","attributes":[{"name":"copyable","description":"Forwarded to the internal `<lr-diff-view>`'s own `copyable` property while `view=\"diff\"`.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"diff-layout","description":"Type: `LyraDiffViewLayout`","value":{"type":["'unified'","'split'"]}},{"name":"language","description":"Forwarded to the internal `<lr-diff-view>`'s own `language` property while `view=\"diff\"`.\nRuntime values outside the documented string contract fall back to no highlighting.\n\nType: `string`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max-height","description":"A CSS length (e.g. `\"30rem\"`); once set, overrides `--lr-document-compare-pane-max-height` --\nthe max block size of each `view=\"side-by-side\"` pane -- declaratively, the same `max-height`\nattribute every other content-viewer sibling exposes, rather than requiring a consumer to set\nthe differently-named CSS custom property inline. Invalid values are ignored.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"sync-scroll","description":"Whether scrolling one `view=\"side-by-side\"` pane proportionally scrolls the other. See the\nclass doc's \"Synchronized anchors\" section.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"view","description":"Type: `LyraDocumentCompareView`","value":{"type":["'diff'","'side-by-side'"]}}],"js":{"properties":[{"name":"anchor","description":"A shared scroll-to-anchor target forwarded to both `view=\"side-by-side\"` panes'\n`scrollToAnchor()`. `hasChanged: () => true` so re-assigning the same value (e.g. re-clicking\nthe same source reference) still re-fires, mirroring `<lr-document-viewer>`'s identical\nproperty.","type":"LyraAnchor | string | null","default":"null"},{"name":"copyable","description":"Forwarded to the internal `<lr-diff-view>`'s own `copyable` property while `view=\"diff\"`.\n\nAttribute: `copyable`","type":"boolean","default":"false"},{"name":"diffLayout","description":"Attribute: `diff-layout`  \nReflected to its attribute.","type":"LyraDiffViewLayout"},{"name":"language","description":"Forwarded to the internal `<lr-diff-view>`'s own `language` property while `view=\"diff\"`.\nRuntime values outside the documented string contract fall back to no highlighting.\n\nAttribute: `language`","type":"string"},{"name":"languages","description":"Forwarded to the internal `<lr-diff-view>`'s own `languages` property while `view=\"diff\"`.","type":"Readonly<\n    Record<string, ShikiLanguageInput>\n  > | undefined"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"maxHeight","description":"A CSS length (e.g. `\"30rem\"`); once set, overrides `--lr-document-compare-pane-max-height` --\nthe max block size of each `view=\"side-by-side\"` pane -- declaratively, the same `max-height`\nattribute every other content-viewer sibling exposes, rather than requiring a consumer to set\nthe differently-named CSS custom property inline. Invalid values are ignored.\n\nAttribute: `max-height`","type":"string","default":"''"},{"name":"newVersion","description":"The \"after\" version. Display fields are copied through own data descriptors at assignment,\nwhile invalid records render as an unset pane.","type":"DocumentCompareVersion | undefined"},{"name":"oldVersion","description":"The \"before\" version. Display fields are copied through own data descriptors at assignment,\nwhile invalid records render as an unset pane.","type":"DocumentCompareVersion | undefined"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"syncScroll","description":"Whether scrolling one `view=\"side-by-side\"` pane proportionally scrolls the other. See the\nclass doc's \"Synchronized anchors\" section.\n\nAttribute: `sync-scroll`","type":"boolean","default":"true"},{"name":"view","description":"Attribute: `view`  \nReflected to its attribute.","type":"LyraDocumentCompareView"}],"events":[{"name":"lr-copy","description":"See `LyraDocumentCompareEventMap`.","type":"CustomEvent<LyraClipboardWriteSuccess>"},{"name":"lr-copy-error","description":"See `LyraDocumentCompareEventMap`.","type":"CustomEvent<LyraClipboardWriteFailure>"},{"name":"lr-download","description":"See `LyraDocumentCompareEventMap`.","type":"CustomEvent<{ src: string; filename: string }>"},{"name":"lr-error","description":"See `LyraDocumentCompareEventMap`.","type":"CustomEvent<null>"},{"name":"lr-highlight-activate","description":"See `LyraDocumentCompareEventMap`.","type":"CustomEvent<HighlightActivateDetail>"},{"name":"lr-render-error","description":"See `LyraDocumentCompareEventMap`.","type":"CustomEvent<{ error: unknown }>"}]}},{"name":"lr-document-library","description":"`<lr-document-library>` — a searchable, filterable inventory of documents with versions, tags,\nowners, freshness, and bulk selection. A controlled data view: it performs no upload, sync, or\nmutation of its own, only presents `documents` and emits request/notification events, mirroring\nthis package's other orchestration-level list surfaces (`<lr-thread-list>`'s\n`lr-thread-pin`/`-archive`/`-delete` convention).\n\nComposes `<lr-table>` for the inventory grid itself, since bulk selection, tags, and per-row\ntype icons all need arbitrary cell content rather than a stringified value.\n`<lr-table>` supports arbitrary `cell()`/`headerCell()` content and `priority`-driven responsive\ncolumn hiding, which this component relies on for its 320px-allocation behavior. Search\n(`<lr-input type=\"search\">`) and the tag facet (`<lr-combobox multiple>`) are both self-managed\n(client-side filtering against `documents`, like `<lr-thread-list>`'s own `searchable` field) —\noverride matching entirely via `filter`. Row selection uses `<lr-checkbox>` per cell. The\ncomposed table stays in multiple-selection semantics so `selectedDocumentIds` reaches row\n`aria-selected`, but its click-anywhere selection event is contained and rolled back because row\nactivation opens the document; checkbox controls remain the sole selection interaction.\n`<lr-table>` is set to `sort-mode=\"server\"` because this component owns ordering:\n`visibleDocuments` already sorts against real values (timestamps for `updatedAt`, a rank for\n`freshness`). Client mode would order the rows a second time from `String(cell(row))`, and these\n`cell()`s render formatted dates and templates — which made the Updated column come out\nalphabetical by month name rather than chronological. `sortKey`/`sortDir` are still passed\ndown: they drive the header's sort affordance, not the order.\nPost-mount selection-count changes announce through the document's shared light-DOM polite\nsink, including zero and repeated equal counts; initial declarative selection stays silent. The\nvisible selection bar remains ordinary, non-live content.\nDocument identity is a unique nonempty `id`: malformed records (including a missing/non-string\n`name` or non-string `tags` entry), blank ids, and later duplicate records are omitted at\nassignment, so the first valid occurrence owns filtering, counts, selection, rows, and events.\nInternal search, tag-filter, and checkbox native/prefixed value-event aliases, the tag\ncombobox's show/hide lifecycle, plus table selection/pagination events, are consumed at their\ntranslation boundary; hosts receive only the documented library-level events.\n\nA separate `error` state reports a failed load without discarding the toolbar/selection-bar\ncontext around it: while `error` is set, the nested `<lr-table>` shows its own built-in\nfailed-load state (the same `error`-prefixed exported parts and `[part='retry-button']` as\n`<lr-table>` itself) in place of the document rows, behind this component's own `error` slot.\n`error` beats the empty state, matching `<lr-table>`'s own precedence. This component forwards\n`error`/`errorHeading`/`errorDescription` to the nested table but owns the retry commit itself,\nthe same intercept-and-re-propose shape `onTableSortRequest` already uses for sort.\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**Slots**\n\n| Name | Description |\n| --- | --- |\n| `error` | Replaces the nested table's built-in failed-load state, including its retry button, while `error` is set. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The root region. |\n| `cell` | Exported from `<lr-table>`'s own `cell` part. |\n| `clear-selection` | The \"Clear selection\" button inside `selection-bar`. |\n| `document-name` | Each row's clickable document-name button. |\n| `error` | The nested table's built-in `<lr-empty>` host rendered while `error` is set. |\n| `error-actions` | Exported from the built-in error `<lr-empty>`'s `actions` part. |\n| `error-base` | Exported from the built-in error `<lr-empty>`'s own `base` part. |\n| `error-cell` | The cell inside `error-row` that holds the failed-load content. |\n| `error-description` | Exported from the built-in error `<lr-empty>`'s `description` part. |\n| `error-heading` | Exported from the built-in error `<lr-empty>`'s `heading` part. |\n| `error-icon` | Exported from the built-in error `<lr-empty>`'s `icon` part. |\n| `error-row` | The nested table's single full-width row that replaces the document rows while `error` is set. |\n| `header-cell` | Exported from `<lr-table>`'s own `header-cell` part. |\n| `retry-button` | The built-in retry control rendered into the error state's `actions`. |\n| `row` | Exported from `<lr-table>`'s own `row` part. |\n| `search` | The `<lr-input>` search field. |\n| `selection-bar` | The ordinary, non-live \"N selected\" / \"Clear selection\" bar. Only rendered while `selectedDocumentIds` is non-empty; selection announcements use the shared light-DOM polite sink. |\n| `selection-count` | The selected-count text inside `selection-bar`. |\n| `table` | The `<lr-table>` inventory grid. |\n| `tag-filter` | The `<lr-combobox>` tag facet filter. Only rendered while at least one document declares a `tags` entry. |\n| `toolbar` | Wraps the search field and tag filter. |","attributes":[{"name":"error","description":"Reports a failed document-list load. Forwarded to the nested `<lr-table>`, whose own\nbuilt-in failed-load state renders in place of the document rows; `<lr-table>`'s own\nprecedence applies (`error` beats the empty state). Reflected so `[error]` is selectable\nfrom outside.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"error-description","description":"Failed-load supporting copy, forwarded to the nested table.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"error-heading","description":"Failed-load heading override, forwarded to the nested table. Omitted localizes the table's\nown `tableLoadFailed` default.\n\nType: `string | undefined`"},{"name":"label","description":"Accessible name for the region and the inner grid. Defaults to the localized\n`documentLibraryLabel` when unset. An explicitly empty string renders as an empty label\nrather than falling back.\n\nType: `string | undefined`"},{"name":"loading","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"search-term","description":"Controlled search query applied to document names, owners, and tags. Removing the\nattribute clears filtering while retaining the native null property readback.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"size","description":"Density tier for the toolbar's own search field and tag filter, on the library's one size\nladder, in either spelling -- `2xs`/`xs`/`s`/`m`/`l`/`xl`, or Web Awesome's and Shoelace's\n`small`/`medium`/`large`. Forwarded verbatim to the composed `<lr-input>` and `<lr-combobox>`,\nwhich is the only way to reach them: each resolves its tier inside its own shadow root, so no\ncustom property this component could publish would get there. Opt-in: with no size both keep\ntheir own `m` default, exactly what they rendered before, and the two stay on the same tier as\neach other at every setting so the toolbar row never goes ragged. Forwarded as a property\nrather than an attribute, because removing an already-written `size` attribute again would\nleave each child's own `size` at `null` instead of back at its own default. Unsupported\nvalues normalize to the omitted state and remove the attribute.\n\nType: `LyraSize | undefined`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}},{"name":"sort-dir","description":"Controlled canonical sort direction shared with `<lr-table>`.\n\nType: `TableSortDirection`  \nDefault: `'asc'`","value":{"type":["'asc'","'desc'"]}},{"name":"sort-key","description":"Controlled sortable column key.\n\nType: `LibraryDocumentSortKey`  \nDefault: `'name'`","value":{"type":["'name'","'version'","'owner'","'freshness'","'updatedAt'"]}}],"slots":[{"name":"error","description":"Replaces the nested table's built-in failed-load state, including its retry button, while `error` is set."}],"js":{"properties":[{"name":"documents","description":"Clone-owned readonly inventory, bounded to the first 10,000 source documents and 10,000 tags\nper document. Document records, nested tag arrays, and dates are snapshotted at assignment\ntime; records without a string name or with non-string tag entries, blank ids, and later\nduplicate ids are omitted first-wins before filters, counts, selection, rows, and events. Reads\nreturn detached snapshots so even `Date` mutators cannot reach retained state. Reassign the\ncollection to update.","type":"readonly LibraryDocument[]"},{"name":"error","description":"Reports a failed document-list load. Forwarded to the nested `<lr-table>`, whose own\nbuilt-in failed-load state renders in place of the document rows; `<lr-table>`'s own\nprecedence applies (`error` beats the empty state). Reflected so `[error]` is selectable\nfrom outside.\n\nAttribute: `error`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"errorDescription","description":"Failed-load supporting copy, forwarded to the nested table.\n\nAttribute: `error-description`","type":"string","default":"''"},{"name":"errorHeading","description":"Failed-load heading override, forwarded to the nested table. Omitted localizes the table's\nown `tableLoadFailed` default.\n\nAttribute: `error-heading`","type":"string | undefined"},{"name":"filter","description":"Overrides the default case-insensitive name/owner/tag substring match. Receives the already\ntrimmed, lowercased search text, mirroring `<lr-thread-list>`'s identical `filter` contract.","type":"(\n    document: LibraryDocument,\n    query: string\n  ) => boolean | undefined"},{"name":"label","description":"Accessible name for the region and the inner grid. Defaults to the localized\n`documentLibraryLabel` when unset. An explicitly empty string renders as an empty label\nrather than falling back.\n\nAttribute: `label`","type":"string | undefined"},{"name":"loading","description":"Attribute: `loading`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"searchTerm","description":"Controlled search query applied to document names, owners, and tags. Removing the\nattribute clears filtering while retaining the native null property readback.\n\nAttribute: `search-term`","type":"string","default":"''"},{"name":"selectedDocumentIds","type":"readonly string[]"},{"name":"size","description":"Density tier for the toolbar's own search field and tag filter, on the library's one size\nladder, in either spelling -- `2xs`/`xs`/`s`/`m`/`l`/`xl`, or Web Awesome's and Shoelace's\n`small`/`medium`/`large`. Forwarded verbatim to the composed `<lr-input>` and `<lr-combobox>`,\nwhich is the only way to reach them: each resolves its tier inside its own shadow root, so no\ncustom property this component could publish would get there. Opt-in: with no size both keep\ntheir own `m` default, exactly what they rendered before, and the two stay on the same tier as\neach other at every setting so the toolbar row never goes ragged. Forwarded as a property\nrather than an attribute, because removing an already-written `size` attribute again would\nleave each child's own `size` at `null` instead of back at its own default. Unsupported\nvalues normalize to the omitted state and remove the attribute.\n\nAttribute: `size`  \nReflected to its attribute.","type":"LyraSize | undefined"},{"name":"sortDir","description":"Controlled canonical sort direction shared with `<lr-table>`.\n\nAttribute: `sort-dir`","type":"TableSortDirection","default":"'asc'"},{"name":"sortKey","description":"Controlled sortable column key.\n\nAttribute: `sort-key`","type":"LibraryDocumentSortKey","default":"'name'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"tagFilter","type":"readonly string[]"}],"events":[{"name":"lr-filter-change","description":"The search term or tag facet changed. Frozen readonly `detail: { searchTerm, tags, matchCount }`. The translated child `lr-input`/`change` event does not escape the library.","type":"CustomEvent<LyraEventDetailSnapshot<DocumentLibraryFilterChangeDetail>>"},{"name":"lr-open","description":"A document was activated (its name, or Enter/Space/click elsewhere on its row). Frozen readonly `detail: { documentId }`.","type":"CustomEvent<DocumentLibraryOpenDetail>"},{"name":"lr-retry","description":"The nested table's built-in `[part='retry-button']` was activated, only rendered while `error` is set. Cancelable: the default action clears `error`; `preventDefault()` leaves it set instead.","type":"CustomEvent<null>"},{"name":"lr-selection-change","description":"The bulk selection changed (a row checkbox, the header select-all checkbox, or \"Clear selection\"). Frozen readonly `detail: { documentIds: readonly string[] }`. Translated checkbox `lr-change` events do not escape the library.","type":"CustomEvent<LyraEventDetailSnapshot<DocumentLibrarySelectionChangeDetail>>"},{"name":"lr-sort","description":"Accepted sort transaction. Frozen readonly `detail: { phase: 'commit', sortKey, sortDir }`.","type":"CustomEvent<DocumentLibrarySortCommitDetail>"},{"name":"lr-sort-request","description":"Cancelable sort proposal translated from the composed table. Frozen readonly `detail: { phase: 'request', sortKey, sortDir }`.","type":"CustomEvent<DocumentLibrarySortRequestDetail>"}]}},{"name":"lr-document-preview","description":"`<lr-document-preview>` — a format-dispatching viewer for one document/\nattachment, plus the visual state machine for an async server-side\nconversion a host app runs in front of it.\n\nFormat dispatch is intentionally minimal (see this family's scope\nguidance): only `text/*`/`application/json` (plain, scrollable `<pre>` —\nno syntax highlighting; compose `<lr-code-block>` yourself via the\n`unsupported` slot for that) and `image/*` (a contained `<img>`) render\ninline. Everything else — PDF, office documents, video, audio, or any\nunrecognized MIME type — falls back to a generic \"can't preview this\"\nstate: a file glyph, a short message, and (when `src` is set) a native\n`<a download>` link. This is a deliberate ceiling, not a gap: this\ncomponent ships a dispatch *shell*, not a format registry. The\n`unsupported` slot is the escape hatch for every format left out of the\nbuilt-in three — plug in a PDF.js viewer, an office-doc renderer, a\n`<lr-code-block>`, or anything else keyed off `mime-type` yourself.\n\n`status=\"converting\"` is a second, independent axis from format dispatch.\nThis component does not know your backend's conversion API shape and\ntherefore owns none of the actual polling/fetch — a host that's converting\na non-natively-previewable format server-side (e.g. .docx → .pdf) polls\nits own backend and updates `status`/`progress`/`src` here as that\nproceeds. This component only *visualizes* that state: an indeterminate\nspinner, or a determinate one once `progress` is supplied. Once the host\nflips `status` to `\"ready\"` (typically alongside a new `src`/`mime-type`\npointing at the converted artifact), normal format dispatch resumes.\n\nThe one piece of async work this component *does* own is fetching a\n`text/*`/`application/json` `src` itself (there's no other way to get a\n`<pre>`'s text content from a URL) — gated behind the same generation-\ncounter guard `<lr-tool-result-view>`'s `resolve()` uses, plus an\n`AbortController`, so a `src` reassigned mid-fetch cancels the obsolete\nrequest and can't have a stale response clobber a newer one. A\nfailure here (network error, non-2xx response) renders inline via\n`[part=\"error\"]` and fires `lr-render-error`, independently of the\nhost-owned `status` prop — mirrors `<lr-markdown>`'s identical stance\nthat a *rendering* failure and a host's own state machine are different\nconcerns.\n\nEvery `src` is validated for the DOM/API sink that consumes it. Text\nfetches and image sources allow relative URLs plus `http:`, `https:`,\n`blob:`, and `data:`. Download links deliberately exclude `data:` because\nfollowing a `data:text/html` URL can create an active document. Unsafe or\nmalformed URLs never reach `fetch()`, an image `src`, or an anchor `href`;\nthey render a non-interactive fallback/error instead.\n\nAccessibility: entering an indeterminate converting/loading state is announced through the\npre-mounted shared document-level polite region, while its visible `[part=\"spinner\"]` remains\nordinary shadow content. Once real `progress` is available, the spinner becomes a standard\n`role=\"progressbar\"`, self-describing via `aria-valuenow`. Error transitions use the shared\nassertive region; `[part=\"error\"]` remains visible ordinary text so it is still encountered in\nreading order without relying on a shadow-root live region.\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| `unsupported` | Escape hatch: when populated, its content renders *instead of* the generic download fallback for any `mime-type` this component doesn't natively support (i.e. whenever format dispatch would otherwise fall through to \"generic\"). Ignored while `mime-type` resolves to `text`/`image` dispatch, or while `status` is `\"converting\"`/`\"error\"`. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The root container. |\n| `body` | The wrapper around whichever content is currently showing (text/image preview, the generic fallback, the spinner, or the error message). |\n| `download-link` | The `<a download>` affordance in the generic fallback. Only rendered when `src` is set and safe for link navigation. |\n| `error` | The visible ordinary-text error region, used both for `status=\"error\"` and for a failed text fetch; transitions announce through the shared assertive sink. |\n| `filename` | The filename text. |\n| `frame-content` | Forwarded from the internal `<lr-pan-zoom>` when `zoomable` (image format only). |\n| `frame-controls` | Forwarded from the internal `<lr-pan-zoom>` when `zoomable` (image format only). |\n| `frame-reset` | Forwarded from the internal `<lr-pan-zoom>` when `zoomable` (image format only). |\n| `frame-viewport` | Forwarded from the internal `<lr-pan-zoom>` when `zoomable` (image format only). |\n| `frame-zoom-in` | Forwarded from the internal `<lr-pan-zoom>` when `zoomable` (image format only). |\n| `frame-zoom-out` | Forwarded from the internal `<lr-pan-zoom>` when `zoomable` (image format only). |\n| `header` | The row above the body, holding `filename`. Hidden entirely when `filename` is unset. |\n| `highlight-actions` | Non-overlapping actions used when multiple region highlights would otherwise create overlapping minimum hit areas (image format only). |\n| `highlight-layer` | The wrapper around every rendered region highlight (image format only). |\n| `region-highlight` | One region highlight (`data-tone`, `data-active`) (image format only). |\n| `region-highlight-action` | One action in the non-overlapping highlight action list. ArrowDown/ArrowUp (or ArrowLeft/ArrowRight under RTL) plus Home/End move focus across this list, matching `<lr-highlight-layer>`'s roving shortcut; every action keeps its own native tabindex, so Tab still steps through each one individually. |\n| `region-highlight-target` | Transparent activation geometry around a region highlight, with a minimum pointer/focus area independent of the visual rectangle (image format only). |\n| `spinner` | The converting/loading indicator — ordinary content while indeterminate or, once numeric progress is known, a determinate `role=\"progressbar\"`. Used both for `status=\"converting\"` and for this component's own in-flight text fetch. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-document-preview-active-border` (default: `var(--lr-color-warning, var(--lr-color-brand))`) — Border color of the `[part=\"region-highlight\"]` matching `activeHighlightId` (image format only). Distinct from the resting highlight border.\n- `--lr-document-preview-download-link-active-bg` (default: `color-mix(in oklab, var(--lr-color-brand), var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Pressed background of the generic download link.\n- `--lr-document-preview-download-link-hover-bg` (default: `color-mix(in oklab, var(--lr-color-brand), var(--lr-color-mix-partner) var(--lr-color-mix-hover))`) — Hover background of the generic download link.\n- `--lr-document-preview-font` (default: `var(--lr-font-mono)`) — Font used for plain-text previews.\n- `--lr-document-preview-highlight-accent-color` (default: `var(--lr-color-brand)`) — Accent highlight border and hover tint.\n- `--lr-document-preview-highlight-danger-color` (default: `var(--lr-color-danger)`) — Danger highlight border and hover tint.\n- `--lr-document-preview-highlight-neutral-color` (default: `var(--lr-color-neutral)`) — Neutral highlight border and hover tint.\n- `--lr-document-preview-highlight-success-color` (default: `var(--lr-color-success)`) — Success highlight border and hover tint.\n- `--lr-document-preview-highlight-warning-color` (default: `var(--lr-color-warning)`) — Warning highlight border and hover tint.\n- `--lr-document-preview-max-height` (default: `none`) — Maximum body block size before the preview scrolls internally.\n- `--lr-document-preview-progress` (default: `0`) — Unitless 0-100 completion of the determinate loading ring (multiplied by `1%` in its conic gradient). Written inline by the component from the clamped `progress` value, so it is a read-out rather than a consumer knob.\n- `--lr-document-preview-spin-duration` (default: `var(--lr-transition-ambient)`) — Timing of one indeterminate loading-indicator rotation.","attributes":[{"name":"active-highlight-id","description":"Type: `string | null`  \nDefault: `null`"},{"name":"alt","description":"Alternative text for an image preview. When omitted, `filename` (or a\nlocalized generic fallback) is used. Set this explicitly to an empty\nstring when the preview image is decorative.\n\nType: `string | undefined`"},{"name":"error-text","description":"Shown (via `[part=\"error\"]`) while `status=\"error\"`. Caller-supplied text, not routed through\n`localize()` -- app/network data, not library copy.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"filename","description":"Shown in the header and used as the download link's suggested filename.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max-height","description":"A CSS length (e.g. `\"24rem\"`); once set, `[part=\"body\"]` scrolls\ninternally past this height instead of growing the page — same\ncontract as `<lr-json-viewer>`'s identically-named prop. Fitting images stay centered;\noversized images start inside the reachable scroll range. Invalid values are ignored.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"mime-type","description":"Drives format dispatch using the case-insensitive MIME essence before parameters.\nRemoving the attribute is treated as an absent format at render time.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"progress","description":"0-100. Only consulted while `status=\"converting\"`. Unset (the default)\nrenders the indeterminate spinner instead of a determinate progress bar.\n\nType: `number | undefined`"},{"name":"src","description":"URL to fetch (for `text`/`application/json`) or display (`image`, or as\nthe generic fallback's download `href`). The value is validated against\na sink-specific scheme allowlist before use. Optional — gracefully\nabsent while, e.g., a conversion is still in progress.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"status","description":"Host-owned lifecycle state. `\"converting\"` shows the spinner regardless\nof `mime-type`/`src`; `\"error\"` shows `errorText` regardless of\neither. `\"idle\"`/`\"ready\"` both resume normal format dispatch — this\ncomponent doesn't require a host that has no conversion step to ever\nset `\"ready\"` explicitly.\n\nType: `DocumentPreviewStatus`  \nDefault: `'idle'`","value":{"type":["'idle'","'converting'","'ready'","'error'"]}},{"name":"zoomable","description":"Wraps the rendered image (image format only) in an internal `<lr-pan-zoom>`. `false`\n(the default) preserves today's exact DOM -- an inline thumbnail (e.g. in a chat stream) must\nnot unexpectedly grow a focusable zoom-chrome viewport; an inspection surface opts in.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"unsupported","description":"Escape hatch: when populated, its content renders *instead of* the generic download fallback for any `mime-type` this component doesn't natively support (i.e. whenever format dispatch would otherwise fall through to \"generic\"). Ignored while `mime-type` resolves to `text`/`image` dispatch, or while `status` is `\"converting\"`/`\"error\"`."}],"js":{"properties":[{"name":"activeHighlightId","description":"Attribute: `active-highlight-id`","type":"string | null","default":"null"},{"name":"alt","description":"Alternative text for an image preview. When omitted, `filename` (or a\nlocalized generic fallback) is used. Set this explicitly to an empty\nstring when the preview image is decorative.\n\nAttribute: `alt`","type":"string | undefined"},{"name":"anchorKinds","type":"LyraAnchor['kind'][]","default":"['region']","read-only":true},{"name":"errorText","description":"Shown (via `[part=\"error\"]`) while `status=\"error\"`. Caller-supplied text, not routed through\n`localize()` -- app/network data, not library copy.\n\nAttribute: `error-text`","type":"string","default":"''"},{"name":"filename","description":"Shown in the header and used as the download link's suggested filename.\n\nAttribute: `filename`","type":"string","default":"''"},{"name":"highlights","description":"Display-only region highlights over the image-format preview (see the class doc's format-\ndispatch scope -- text/generic formats never render these). IDs are trimmed and must be\nnonempty; the first record for an ID is retained and blank or later duplicates are ignored.","type":"readonly LyraHighlight[]"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"maxHeight","description":"A CSS length (e.g. `\"24rem\"`); once set, `[part=\"body\"]` scrolls\ninternally past this height instead of growing the page — same\ncontract as `<lr-json-viewer>`'s identically-named prop. Fitting images stay centered;\noversized images start inside the reachable scroll range. Invalid values are ignored.\n\nAttribute: `max-height`","type":"string","default":"''"},{"name":"mimeType","description":"Drives format dispatch using the case-insensitive MIME essence before parameters.\nRemoving the attribute is treated as an absent format at render time.\n\nAttribute: `mime-type`","type":"string","default":"''"},{"name":"progress","description":"0-100. Only consulted while `status=\"converting\"`. Unset (the default)\nrenders the indeterminate spinner instead of a determinate progress bar.\n\nAttribute: `progress`","type":"number | undefined"},{"name":"src","description":"URL to fetch (for `text`/`application/json`) or display (`image`, or as\nthe generic fallback's download `href`). The value is validated against\na sink-specific scheme allowlist before use. Optional — gracefully\nabsent while, e.g., a conversion is still in progress.\n\nAttribute: `src`","type":"string","default":"''"},{"name":"status","description":"Host-owned lifecycle state. `\"converting\"` shows the spinner regardless\nof `mime-type`/`src`; `\"error\"` shows `errorText` regardless of\neither. `\"idle\"`/`\"ready\"` both resume normal format dispatch — this\ncomponent doesn't require a host that has no conversion step to ever\nset `\"ready\"` explicitly.\n\nAttribute: `status`  \nReflected to its attribute.","type":"DocumentPreviewStatus","default":"'idle'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"suppressDownload","description":"Omits the generic fallback's download action when a composing shell owns that action.\nProperty-only: this is a composition control rather than author-facing markup state.","type":"boolean","default":"false"},{"name":"zoomable","description":"Wraps the rendered image (image format only) in an internal `<lr-pan-zoom>`. `false`\n(the default) preserves today's exact DOM -- an inline thumbnail (e.g. in a chat stream) must\nnot unexpectedly grow a focusable zoom-chrome viewport; an inspection surface opts in.\n\nAttribute: `zoomable`  \nReflected to its attribute.","type":"boolean","default":"false"}],"events":[{"name":"lr-download","description":"`detail: { src, filename }` — fired when the safe generic-download fallback link is activated. The browser download itself needs no JS (a plain `<a download>` handles it); this is purely for a host that wants to observe/log the download.","type":"CustomEvent<{ src: string; filename: string }>"},{"name":"lr-highlight-activate","description":"A region highlight was activated (image format only). `detail: { highlightId }`.","type":"CustomEvent<HighlightActivateDetail>"},{"name":"lr-render-error","description":"`detail: { error }` — fired when this component rejects an unsafe text/JSON URL or when its own `text/*`/`application/json` `fetch(src)` fails. Distinct from `status=\"error\"`, which is entirely host-driven (see the class doc).","type":"CustomEvent<{ error: unknown }>"}]}},{"name":"lr-document-viewer","description":"A dialog-hosted document viewer with a pluggable MIME-type renderer registry.\nA registered renderer receives the current file; files without a matching\nrenderer use `<lr-document-preview>` as a safe built-in fallback. Each instance snapshots the\nregistered built-ins at construction; an explicit readonly `registry` provides deterministic\noverrides, and MIME dispatch ignores casing and parameters. An opt-in immutable `payload`\nbecomes authoritative for the file when set; scalar file properties remain the compatible\ndefault when it is unset.\nA host `aria-label` names the nested dialog by attribute presence, including an explicitly\nempty value; `name` remains the visible dialog heading.\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**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `body` | Wrapper around the active renderer or fallback preview. It exposes explicit `aria-busy`; visible loading/error text is ordinary content and transitions announce through the shared document-level polite/assertive sinks. |\n| `download-link` | The native download action shown when `src` is safe. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-document-viewer-download-link-active-bg` (default: `color-mix(in oklab, var(--lr-color-brand), var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Pressed background of the download link.\n- `--lr-document-viewer-download-link-hover-bg` (default: `color-mix(in oklab, var(--lr-color-brand), var(--lr-color-mix-partner) var(--lr-color-mix-hover))`) — Hover background of the download link.\n- `--lr-document-viewer-max-height` (default: `70vh`) — Maximum block size of the dialog body before it scrolls internally.\n- `--lr-document-viewer-min-height` (default: `var(--lr-size-12rem)`) — Minimum block size of the dialog body before it grows to fit content.\n- `--lr-document-viewer-width` (default: `auto`) — Assertive inline size for the nested dialog panel, forwarded to `<lr-dialog>`'s own `--lr-dialog-width`. Left at `auto` the panel shrink-wraps to content, capped by the dialog's own `--lr-dialog-max-width` tier -- set this instead of reaching through to `--lr-dialog-width` directly, which remains an internal implementation detail of the nested dialog.","attributes":[{"name":"alt","description":"Media alt text forwarded to the resolved renderer, for image-like renderers. Unset lets the\nrenderer derive a fallback name; an explicit empty string marks decorative media.\n\nType: `string | undefined`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"mime-type","description":"MIME type used for renderer dispatch.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"name","description":"Display name passed to the renderer and shown as the dialog heading. A host `aria-label`\nindependently overrides the nested dialog's accessible name by attribute presence.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"open","description":"Whether the viewer is open.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"src","description":"Source URL passed to the renderer or fallback preview.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"js":{"properties":[{"name":"alt","description":"Media alt text forwarded to the resolved renderer, for image-like renderers. Unset lets the\nrenderer derive a fallback name; an explicit empty string marks decorative media.\n\nAttribute: `alt`","type":"string | undefined"},{"name":"anchor","description":"Declarative scroll-to-anchor target, forwarded to the resolved renderer. A string is a\nhighlight id in `highlights`. `hasChanged: () => true` so re-assigning the same value (e.g.\nre-clicking the same citation badge) still re-fires, mirroring the anchor-target mixin's\nidentical property.","type":"LyraAnchor | string | null","default":"null"},{"name":"highlights","description":"Highlights forwarded to the resolved renderer. IDs are trimmed, nonempty, and first-wins.","type":"readonly LyraHighlight[]"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"mimeType","description":"MIME type used for renderer dispatch.\n\nAttribute: `mime-type`","type":"string","default":"''"},{"name":"name","description":"Display name passed to the renderer and shown as the dialog heading. A host `aria-label`\nindependently overrides the nested dialog's accessible name by attribute presence.\n\nAttribute: `name`","type":"string","default":"''"},{"name":"open","description":"Whether the viewer is open.\n\nAttribute: `open`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"payload","description":"Optional renderer-specific file payload. Assignment clones, bounds, and freezes the complete\nsnapshot immediately. While set, `payload.file` is authoritative for dispatch, heading,\nrenderer/fallback input, and download; `name`, `mimeType`, `src`, `anchor`, `highlights`, and\n`alt` resume their legacy authority when this is reset to `undefined`.","type":"LyraDocumentRendererPayload | undefined"},{"name":"registry","description":"Optional per-instance immutable/read-only registry override. Native maps and definition\nrecords are synchronously cloned and frozen while callback identities are retained; later\nsource-map mutation is not observed. Factory-created immutable registries use the same bounded\nsnapshot boundary. When unset, this instance owns a snapshot of the built-ins\nthat existed when it was constructed; later registrations cannot mutate it. A consumer matcher\nor renderer that throws is contained as the localized error state, and a pending anchor\ncompletes once with `{ found: false }`.","type":"DocumentRendererRegistry | undefined"},{"name":"src","description":"Source URL passed to the renderer or fallback preview.\n\nAttribute: `src`","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-anchor-result","description":"Fired once per applied `anchor`. An incapable resolved renderer produces `{ found: false }`; the `<lr-document-preview>` fallback reports its actual anchor result. An anchor-capable renderer reports its own jump result through its embedded `DocumentAnchorTarget` mixin, which composes up through this element unchanged.","type":"CustomEvent<AnchorResultDetail>"},{"name":"lr-close","description":"Fired when the viewer's shell dialog dismisses the viewer. The detail is the dialog close reason. A registered renderer's own descendant dialog keeps its independent `lr-close` path (guarded by `event.target !== event.currentTarget`) and does not close this viewer.","type":"CustomEvent<DocumentViewerCloseReason>"},{"name":"lr-download","description":"Fired when the viewer's safe download action is activated. The browser download itself is handled by the native link.","type":"CustomEvent<{ src: string; filename: string }>"},{"name":"lr-render-error","description":"Fired by the fallback preview or an embedded renderer when fetching, parsing, sanitizing, or rendering fails. `detail: { error }` composes through this shell unchanged.","type":"CustomEvent<{ error: unknown }>"}]}},{"name":"lr-docx-viewer","description":"Renders a DOCX document as sanitized semantic HTML using the optional\n`mammoth` converter and `dompurify` sanitizer peers. DOCX content is always\nsanitized; there is no unsanitized rendering mode for uploaded documents.\nConverted markup then passes through the passive-document profile: anchors, form controls, and\ncustom elements are unwrapped to ordinary text/children where safe, remote navigation/resource\nattributes are removed, and an `<a>` itself never remains. Images render only inline base64 GIF,\nJPEG, PNG, or WebP data; same-document SVG fragment references may remain.\n\nEvery rendered heading's slug (computed via the shared GitHub-slugger-style `Slugger` -- the same\nalgorithm and shared class `<lr-markdown>` uses, so identical heading text slugs identically\nacross both viewers) is stamped as its `id` and cached into `getHeadingTree()`'s document-ordered\noutline -- unconditional, unlike `<lr-markdown>`'s opt-in `heading-anchors`, since this\ncomponent's rendered HTML is always internal (mammoth's own conversion output), never a raw string\na consumer might serialize verbatim. Adopts `DocumentAnchorTarget`: `fragment` anchors resolve\nagainst that outline, `text-quote` anchors via `internal/text-quote.ts`'s shared scope/resolve\nhelpers; `highlights` re-resolve by quote after every render (never by node identity), so a\nhighlight painted before its quote is in the rendered markup yet simply paints once a later load\ncontains it. At most 100 quotes are painted per pass from a 1,000-entry candidate window;\n`activeHighlightId` is retained from anywhere in the bounded host snapshot and resolved first.\nKeyboard-accessible\nhighlight actions are rendered only for quotes that resolved\nagainst the currently loaded document, so an action never presents an enabled no-op. Highlight\npainting uses `internal/text-highlights.ts`'s `acquireHighlightHandle()` --\nthe CSS Custom Highlight API where the browser supports it (no DOM mutation at all), a `<mark>`-wrap\nfallback otherwise. `search()`/`searchNext()`/`searchPrevious()`/`clearSearch()` do a\ncase-insensitive substring search over the rendered content's text and paint every match as a\n`<mark part=\"search-match\">` (the active one also carrying `search-match-active`) -- a separate,\nalways-real-DOM-element mechanism from the tone-based highlight painting above, since search needs\nmany simultaneously-visible matches rather than one set of themed spans.\nA nonempty host `aria-label` makes the host the sole named semantic owner; otherwise the loaded\nshadow document owns the explicit-empty, `name`, or localized fallback label.\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| `anchor-live-region` | The aria-hidden, non-live shadow mirror of the latest anchor-jump message. |\n| `base` | The root container with explicit `aria-busy` loading state. |\n| `body` | The scrollable document body. |\n| `content` | The semantic document content. |\n| `error` | The error message region. |\n| `highlight` | A painted `text-quote` highlight (`<mark>`, `<mark>`-wrap fallback path only). |\n| `highlight-action` | One native highlight activation button. |\n| `highlight-actions` | Keyboard-accessible actions for the resolved text highlights. |\n| `search-match` | A painted in-document search match. |\n| `search-match-active` | The currently active search match (also carries `search-match`). |\n| `spinner` | The visible tokenized loading treatment and ordinary text label. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-docx-viewer-max-height` (default: `none`) — Maximum block size of the scrollable document body before it scrolls internally. Also settable via the `max-height` property.\n- `--lr-docx-viewer-table-header-background` (default: `var(--lr-color-brand-quiet)`) — Background of a rendered document table's header row (`th`), independent of the highlight backgrounds below.\n- `--lr-docx-viewer-highlight-accent-background` — Accent highlight background.\n- `--lr-docx-viewer-highlight-success-background` — Success highlight background.\n- `--lr-docx-viewer-highlight-warning-background` — Warning highlight background.\n- `--lr-docx-viewer-highlight-danger-background` — Danger highlight background.\n- `--lr-docx-viewer-highlight-neutral-background` — Neutral highlight background.\n- `--lr-docx-viewer-highlight-active-background` — Active highlight background.\n- `--lr-docx-viewer-highlight-active-outline` — Active fallback-highlight outline.\n- `--lr-docx-viewer-search-match-background` — Search-match background.\n- `--lr-docx-viewer-search-match-active-background` — Active search-match background.\n- `--lr-docx-viewer-search-match-active-foreground` — Active search-match foreground.","attributes":[{"name":"active-highlight-id","description":"Id of the currently active highlight, or null when none is active.\n\nType: `string | null`  \nDefault: `null`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max-height","description":"A CSS `max-height` that caps the scrollable document body; invalid values are ignored.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"name","description":"Accessible name for the rendered document when the host has no `aria-label`. Host\n`aria-label` wins by attribute presence, including an empty value.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"src","description":"URL to fetch and convert as a DOCX document.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"js":{"properties":[{"name":"activeHighlightId","description":"Id of the currently active highlight, or null when none is active.\n\nAttribute: `active-highlight-id`","type":"string | null","default":"null"},{"name":"anchor","description":"Anchor or highlight id to resolve and scroll into view.","type":"LyraAnchor | string | null","default":"null"},{"name":"anchorKinds","description":"Anchor kinds this viewer resolves via `scrollToAnchor()`. Readonly.","type":"['fragment', 'text-quote']","default":"['fragment', 'text-quote']","read-only":true},{"name":"highlights","description":"Highlights rendered by the document target. Reassign after mutation.","type":"LyraHighlight[]","default":"[]"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"maxHeight","description":"A CSS `max-height` that caps the scrollable document body; invalid values are ignored.\n\nAttribute: `max-height`","type":"string","default":"''"},{"name":"name","description":"Accessible name for the rendered document when the host has no `aria-label`. Host\n`aria-label` wins by attribute presence, including an empty value.\n\nAttribute: `name`","type":"string","default":"''"},{"name":"src","description":"URL to fetch and convert as a DOCX document.\n\nAttribute: `src`","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-anchor-result","description":"Fired after an `anchor` property assignment or a `scrollToAnchor()` call is applied. `detail: { found }`.","type":"CustomEvent<AnchorResultDetail>"},{"name":"lr-highlight-activate","description":"A painted `text-quote` highlight was clicked or its resolved keyboard action was activated. `detail: { highlightId }`.","type":"CustomEvent<HighlightActivateDetail>"},{"name":"lr-render-error","description":"Fired only when loading, conversion, or sanitization fails terminally.","type":"CustomEvent<{ error: unknown }>"},{"name":"lr-search-change","description":"Fired whenever the search query, match count, or active match index changes, including source-reset and effective-locale re-evaluation. `detail: { query, matchCount, matchCountExact, activeIndex }`. Search accepts at most 4,096 query code units, scans at most 4,000,000 code units, and retains at most 1,000 matches; a false `matchCountExact` makes `matchCount` a lower bound after any ceiling is reached.","type":"CustomEvent<LyraSearchChangeDetail>"},{"name":"lr-text-select","description":"Fired on selection end inside the rendered content. `detail: { text, anchor, rects }`; `anchor` is a `text-quote` `LyraAnchor` scoped to the rendered content, or `null` if the selection couldn't be anchored.","type":"CustomEvent<TextSelectDetail>"},{"name":"lr-viewer-diagnostic","description":"Structured non-fatal converter diagnostics. `detail.diagnostic` has code `docx-conversion-message`, severity, source, and the original peer value as `cause`.","type":"CustomEvent<LyraViewerDiagnosticEventDetail>"}]}},{"name":"lr-doughnut-chart","description":"`<lr-doughnut-chart>` — `<lr-chart>` with a `\"doughnut\"` default and the mirrored writable type.\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) | An optional `<script type=\"application/json\">` containing a Chart.js configuration. |\n| `center` | Optional overlay content positioned at the chart area's center. Useful for doughnut and pie totals. |\n| `data-table` | An optional consumer-provided accessible table alternative. Use this escape hatch for a complete paginated or virtualized alternative when the generated 1,000-record sample is insufficient. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The chart wrapper. |\n| `canvas` | The Chart.js canvas. |\n| `center` | The chart-area-centered overlay wrapper for the `center` slot. |\n| `data-table` | The optional generated or slotted data table. |\n| `data-table-toggle` | The disclosure button rendered by `dataTableToggle`. |\n| `data-truncation` | Explanation shown when the generated accessible alternative samples a data set larger than its 1,000-record ceiling. |\n| `description` | The accessible chart summary. |\n| `error` | Static visible error shown instead of `canvas` when the optional `chart.js` peer dependency is not installed; its transition is announced through a shared light-DOM alert. |\n| `feature-warning` | Static nonfatal warning when a requested optional feature peer is unavailable while the core chart remains usable. |\n| `legend` | The wrapping DOM legend, rendered unless `withoutLegend` is set. |\n| `legend-item` | A keyboard-operable dataset or category visibility toggle. |\n| `legend-item-hidden` | Added while the legend item's dataset or category is hidden. |\n| `legend-swatch` | The resolved dataset/category color swatch in a legend item. |\n| `notices` | Wrapper for nonfatal feature warnings and generated-data truncation notices. |\n| `plot` | The fixed-height canvas/overlay region. |\n| `reset-zoom-button` | The reset-zoom control when zoom is active. |\n\n---\n\n**CSS Custom Properties**\n\n- `--border-color-1` (default: `var(--lr-color-chart-1)`) — First dataset border color.\n- `--border-color-2` (default: `var(--lr-color-chart-2)`) — Second dataset border color.\n- `--border-color-3` (default: `var(--lr-color-chart-3)`) — Third dataset border color.\n- `--border-color-4` (default: `var(--lr-color-chart-4)`) — Fourth dataset border color.\n- `--border-color-5` (default: `var(--lr-color-chart-5)`) — Fifth dataset border color.\n- `--border-color-6` (default: `var(--lr-color-chart-6)`) — Sixth dataset border color.\n- `--border-radius` (default: `var(--lr-radius)`) — Dataset element corner radius.\n- `--border-width` (default: `var(--lr-border-width-thin)`) — Dataset element border width.\n- `--fill-color-1` (default: `var(--lr-color-chart-1)`) — First dataset fill color.\n- `--fill-color-2` (default: `var(--lr-color-chart-2)`) — Second dataset fill color.\n- `--fill-color-3` (default: `var(--lr-color-chart-3)`) — Third dataset fill color.\n- `--fill-color-4` (default: `var(--lr-color-chart-4)`) — Fourth dataset fill color.\n- `--fill-color-5` (default: `var(--lr-color-chart-5)`) — Fifth dataset fill color.\n- `--fill-color-6` (default: `var(--lr-color-chart-6)`) — Sixth dataset fill color.\n- `--grid-border-width` (default: `var(--lr-border-width-thin)`) — Axis and grid line width.\n- `--grid-color` (default: `var(--lr-chart-grid-color)`) — Grid line color.\n- `--line-border-width` (default: `var(--lr-border-width-medium)`) — Line dataset stroke width.\n- `--lr-chart-canvas-hover-outline-color` (default: `var(--lr-chart-grid-color)`) — Color of the `[part='canvas']` hover-state outline.\n- `--lr-chart-canvas-hover-outline-width` (default: `var(--lr-border-width-thin)`) — Width of the `[part='canvas']` hover-state outline.\n- `--lr-chart-data-table-button-active-bg` — Pressed background of an actionable generated- table value; defaults to the standard active mix of `--lr-color-brand-quiet`.\n- `--lr-chart-data-table-button-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background of an actionable generated-table value.\n- `--lr-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-chart-data-table-toggle-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background of the `dataTableToggle` disclosure button.\n- `--lr-chart-grid-color` (default: `var(--lr-color-border)`) — Grid-line color. Resolved via `getComputedStyle` on every draw (Chart.js paints to canvas and cannot consume `var()`).\n- `--lr-chart-height` (default: `var(--lr-size-280px)`) — The plot region's `block-size` and the host's minimum block size. A visible data table or wrapping DOM legend grows the host in normal flow instead of overlapping following content. `height` supplies a private fallback; this public token always wins when a consumer sets it.\n- `--lr-chart-legend-color` (default: `var(--lr-color-text)`) — Legend label color. Resolved via `getComputedStyle` on every draw.\n- `--lr-chart-legend-item-active-bg` — Pressed background of a legend visibility button; defaults to the standard active mix of `--lr-color-brand-quiet`.\n- `--lr-chart-legend-item-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background of a legend visibility button.\n- `--lr-chart-legend-side-max` (default: `var(--lr-size-15rem)`) — Maximum inline size reserved for a side-positioned DOM legend; the track is also capped at one third of the chart allocation.\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 every series collapses to one system color and the stripe/crosshatch pattern 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.\n- `--lr-chart-reset-zoom-button-active-bg` — Pressed background of the reset-zoom button; defaults to the standard active mix of `--lr-color-brand-quiet`.\n- `--lr-chart-reset-zoom-button-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background of the reset-zoom button.\n- `--lr-chart-tick-color` (default: `var(--lr-color-text-quiet)`) — Axis tick-label color; also used for the `xLabel`/`yLabel`/`y2Label` axis-title text (there is no separate title-color token). Resolved via `getComputedStyle` on every draw.\n- `--lr-chart-tick-font-size` (default: `var(--lr-font-size-xs)`) — Axis tick-label font size, in any CSS length unit. Defaults to `--lr-font-size-xs` (12px at the standard root) because that matches Chart.js's OWN built-in tick font size, which is what every canvas chart rendered before this token existed -- leaving it unset must stay byte-identical to that, not shrink to `<lr-lite-chart>`'s SVG default. Also sizes the radar/polarArea `r`-scale `pointLabels` (the spoke labels), but ONLY once set: those default separately to Chart.js's OWN distinct `RadialLinearScale` `pointLabels` default (10px, not this token's 12px), and only adopt this token's size once the consumer explicitly sets it, at which point ticks and point labels match. Resolved via `getComputedStyle` on every draw, same constraint as every other `--lr-chart-*` token here (Chart.js paints to canvas and cannot consume `var()`).\n- `--lr-chart-tooltip-bg` (default: `var(--lr-color-surface)`) — Tooltip background color. Resolved via `getComputedStyle` on every draw.\n- `--lr-chart-tooltip-text` (default: `var(--lr-color-text)`) — Tooltip text color. Resolved via `getComputedStyle` on every draw.\n- `--point-radius` (default: `var(--lr-space-2xs)`) — Line/scatter point radius.","attributes":[{"name":"area","description":"Chart-wide default fill-under-line setting for line-type series; a series's own `LyraChartSeries.fill` overrides it.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"axes","description":"Complete cartesian axis visibility, independent of grid. `y` also controls the y2 axis.\nRadial charts ignore this setting. Explicit config scale options retain precedence.\n\nType: `LyraChartAxes`  \nDefault: `'both'`","value":{"type":["'x'","'y'","'both'","'none'"]}},{"name":"begin-at-zero","description":"Type: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"compact","description":"Compact cartesian plot: hide axes and remove automatic layout padding. Set height and\nwithoutLegend for a small histogram/sparkline. Preserves data tables, tooltips and keyboard\nactions; radial charts ignore this setting. Explicit config options retain precedence.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"data-labels","description":"Draws each data point's value on the chart via the optional\n`chartjs-plugin-datalabels` peer. Unset (the default) leaves labels off for\nthis chart; the peer is attached only to instances that opt in, and\n`buildConfig()` keeps its per-chart options disabled until this is set. The\nscreen-reader equivalent is the always-present data table (see\n`show-data-table`); labels are a purely visual, canvas-only addition.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"data-table-toggle","description":"Render a disclosure button above the accessible data table so a sighted reader can reveal the\nnumbers behind the chart on demand. `showDataTable` alone is all-or-nothing -- the table is\neither permanently screen-reader-only or permanently visible -- which left a consumer wrapping\na duplicated table in their own `<details>`.\n\nWith this set, `showDataTable` becomes the disclosure's *initial* state rather than its whole\nbehavior. The table stays in the DOM in both states, so assistive technology never loses it.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"description","description":"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`"},{"name":"grid","description":"Controls which cartesian grid axes are drawn.\n\nType: `LyraChartGrid`  \nDefault: `'both'`","value":{"type":["'x'","'y'","'both'","'none'"]}},{"name":"height","description":"Type: `string`  \nDefault: `'280px'`","value":{"type":["string"]}},{"name":"index-axis","description":"Chart.js index axis. `'y'` is Chart.js's own mechanism for horizontal bars (it also flips\nline/area types onto a horizontal category axis).\n\nType: `LyraChartIndexAxis`  \nDefault: `'x'`","value":{"type":["'x'","'y'"]}},{"name":"label","description":"Accessible chart label. A host `aria-label` still has highest precedence.\n\nType: `string | null`  \nDefault: `null`"},{"name":"legend-display","description":"`auto` retains optional legend formatting; `label` omits values even with a formatter; `value`\nappends a formatted value. `percentage` uses locale percentages of the absolute represented\nlegend values, including hidden items (zero totals yield 0%). `value-percentage` appends both,\nas `label: value (percentage)`. Dataset values are sampled sums; category values come from the\nfirst dataset. The `formatter`/`valueFormatter` callback backing `value` and `value-percentage`\nadditionally receives that same `percentage` in its `surface: 'legend'` context, so a custom\nformatter can build its own combined text without recomputing the share. Tooltip and axis\nformatting are unchanged.\n\nType: `LyraChartLegendDisplay`  \nDefault: `'auto'`","value":{"type":["'auto'","'label'","'value'","'percentage'","'value-percentage'"]}},{"name":"legend-mode","description":"`datum` renders category toggles for pie/doughnut/polar-area charts. Categories use the first\ndataset's colors and values; a toggle affects that category in every ring. Other chart types\nretain dataset legends. `auto` (the default) resolves to `datum` on pie/doughnut/polar-area\ncharts -- where a single-dataset legend would otherwise enumerate one entry for the whole\ndataset instead of one per visible slice -- and to `dataset` everywhere else. `dataset` always\nforces the dataset legend, even on a slice chart. Both non-`auto` modes use the generated\naccessible-data sampling budget.\n\nType: `LyraChartLegendMode`  \nDefault: `'auto'`","value":{"type":["'auto'","'dataset'","'datum'"]}},{"name":"legend-position","description":"Legend placement. `auto` uses a right legend above 480px and a bottom legend below it.\n\nType: `LyraChartLegendPosition`  \nDefault: `'top'`","value":{"type":["'left'","'top'","'right'","'bottom'","'center'","'chartArea'","'start'","'end'","'auto'"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max","description":"Maximum value-axis bound. Non-finite values are ignored.\n\nType: `number | null`  \nDefault: `null`"},{"name":"min","description":"Minimum value-axis bound. Non-finite values are ignored.\n\nType: `number | null`  \nDefault: `null`"},{"name":"plugins","description":"Chart.js plugins attached to this chart instance. Valid plugins retain their opaque identity.\n\nType: `readonly LyraChartPlugin[]`  \nDefault: `[]`"},{"name":"scale-type","description":"Scale type for the **value** axis (the categorical axis is unaffected). `'logarithmic'` plots\na dataset spanning several orders of magnitude honestly, where a linear axis collapses\neverything below the maximum into the baseline. Inherited by `lr-line-chart`,\n`lr-scatter-chart` and `lr-bar-chart`.\n\nA logarithmic axis cannot represent zero or negative values (`log(0)` is `-Infinity`), so\n`beginAtZero` is not forwarded in that mode -- Chart.js would otherwise be handed a bound it\ncannot place. Non-positive data points are dropped by Chart.js's own log scale.\n\nType: `LyraChartScaleType`  \nDefault: `'linear'`","value":{"type":["'linear'","'logarithmic'"]}},{"name":"show-data-table","description":"Makes the generated data table visible; it remains screen-reader available when false.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"stack-totals","description":"When the chart is `stacked` (bar/line only), draws the per-category stack\ntotal above each stack, via the same optional `chartjs-plugin-datalabels`\npeer as `data-labels`. Null/undefined points are skipped; a category whose\nevery value is null shows no total. The generated accessible data table\nreceives the same formatted total column (one per value axis). Unset (the\ndefault) draws and adds nothing.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"stacked","description":"Stacks the `x`/`y`(/`y2`) scale entries `buildScales()` returns; only meaningful for `bar` and `line` types.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"type","description":"Type: `LyraChartType`  \nDefault: `'doughnut'`","value":{"type":["'line'","'bar'","'scatter'","'pie'","'doughnut'","'radar'","'polarArea'","'bubble'"]}},{"name":"without-animation","description":"Disables Chart.js animation.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"without-legend","description":"Hides the legend.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"without-tooltip","description":"Hides Chart.js tooltips.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"x-label","description":"Type: `string | null`  \nDefault: `null`"},{"name":"y-label","description":"Type: `string | null`  \nDefault: `null`"},{"name":"y2-label","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"zoom","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"","description":"An optional `<script type=\"application/json\">` containing a Chart.js configuration."},{"name":"center","description":"Optional overlay content positioned at the chart area's center. Useful for doughnut and pie totals."},{"name":"data-table","description":"An optional consumer-provided accessible table alternative. Use this escape hatch for a complete paginated or virtualized alternative when the generated 1,000-record sample is insufficient."}],"js":{"properties":[{"name":"annotations","description":"Declarative reference lines and shaded bands — a threshold, an event year, a regime change, a\nhighlighted period. Each entry marks either a single `value` or a `from`/`to` range on `axis`\n(default `'y'`), with an optional `label` and semantic `tone`.\n\nNeeds the optional `chartjs-plugin-annotation` peer, loaded on first actual demand so a page\nwith no annotated charts never downloads it. The plugin is registered globally, like\n`chartjs-plugin-zoom` and unlike `chartjs-plugin-datalabels`: it draws nothing unless a chart\nsupplies annotation options, so the registration is unobservable to charts that set none, and\nregistration is also what installs the plugin's own element defaults. Without the peer\ninstalled the chart still renders; a console warning plus a localized visible warning and\nlight-DOM announcement explain the no-op — the same fail-closed contract `data-labels` uses.\n\nEntries are included in the generated accessible description, mirroring `lr-heatmap`.","type":"readonly LyraChartAnnotation[]","default":"[]"},{"name":"area","description":"Chart-wide default fill-under-line setting for line-type series; a series's own `LyraChartSeries.fill` overrides it.\n\nAttribute: `area`","type":"boolean","default":"false"},{"name":"axes","description":"Complete cartesian axis visibility, independent of grid. `y` also controls the y2 axis.\nRadial charts ignore this setting. Explicit config scale options retain precedence.\n\nAttribute: `axes`","type":"LyraChartAxes","default":"'both'"},{"name":"beginAtZero","description":"Attribute: `begin-at-zero`","type":"boolean","default":"true"},{"name":"chart","description":"The current Chart.js instance. Read it only while the element is connected and loaded.","type":"LyraChartInstance | undefined"},{"name":"chartArea","description":"The current Chart.js chart-area geometry in canvas-local coordinates. Read-only -- derived\nfrom the live Chart.js instance's own layout pass, never assignable. The setter is a\ndocumented no-op (matching `lr-histogram`'s `labels`/`datasets` pattern) so an accidental\n`.chartArea=${x}` Lit template binding degrades silently instead of throwing from inside\nlit-html's property-commit.","type":"LyraChartArea | undefined"},{"name":"compact","description":"Compact cartesian plot: hide axes and remove automatic layout padding. Set height and\nwithoutLegend for a small histogram/sparkline. Preserves data tables, tooltips and keyboard\nactions; radial charts ignore this setting. Explicit config options retain precedence.\n\nAttribute: `compact`","type":"boolean","default":"false"},{"name":"config","type":"LyraChartConfiguration | undefined"},{"name":"dataLabels","description":"Draws each data point's value on the chart via the optional\n`chartjs-plugin-datalabels` peer. Unset (the default) leaves labels off for\nthis chart; the peer is attached only to instances that opt in, and\n`buildConfig()` keeps its per-chart options disabled until this is set. The\nscreen-reader equivalent is the always-present data table (see\n`show-data-table`); labels are a purely visual, canvas-only addition.\n\nAttribute: `data-labels`","type":"boolean","default":"false"},{"name":"dataTableToggle","description":"Render a disclosure button above the accessible data table so a sighted reader can reveal the\nnumbers behind the chart on demand. `showDataTable` alone is all-or-nothing -- the table is\neither permanently screen-reader-only or permanently visible -- which left a consumer wrapping\na duplicated table in their own `<details>`.\n\nWith this set, `showDataTable` becomes the disclosure's *initial* state rather than its whole\nbehavior. The table stays in the DOM in both states, so assistive technology never loses it.\n\nAttribute: `data-table-toggle`","type":"boolean","default":"false"},{"name":"datasets","description":"Simplified chart series. Non-record entries are dropped while valid sibling series remain.","type":"readonly LyraChartSeries[]"},{"name":"description","description":"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\nAttribute: `description`","type":"string | null","default":"null"},{"name":"formatter","description":"Unified context-object formatter for visual, tooltip, table/export, and spoken values.","type":"LyraChartFormatter | undefined"},{"name":"grid","description":"Controls which cartesian grid axes are drawn.\n\nAttribute: `grid`","type":"LyraChartGrid","default":"'both'"},{"name":"height","description":"Attribute: `height`","type":"string","default":"'280px'"},{"name":"hiddenDatasets","description":"Complete controlled visibility state for DOM legend toggles. `undefined` (the default) honors\neach effective dataset's `hidden` configuration; a defined array wins over those defaults, and\nan empty array deliberately makes every dataset visible. Invalid, duplicate, and out-of-range\nindexes are ignored when state is applied or emitted.","type":"readonly number[] | undefined"},{"name":"hiddenDatums","description":"Controlled hidden source category indexes for pie/doughnut/polar-area charts, shared by all\ndatasets/rings. Clone-owned; invalid, duplicate and out-of-range indexes are ignored when\napplied or emitted. Empty restores all categories. Does not alter dataset visibility or exports.","type":"readonly number[]","default":"[]"},{"name":"indexAxis","description":"Chart.js index axis. `'y'` is Chart.js's own mechanism for horizontal bars (it also flips\nline/area types onto a horizontal category axis).\n\nAttribute: `index-axis`","type":"LyraChartIndexAxis","default":"'x'"},{"name":"label","description":"Accessible chart label. A host `aria-label` still has highest precedence.\n\nAttribute: `label`","type":"string | null","default":"null"},{"name":"labels","type":"string[]","default":"[]"},{"name":"legendDisplay","description":"`auto` retains optional legend formatting; `label` omits values even with a formatter; `value`\nappends a formatted value. `percentage` uses locale percentages of the absolute represented\nlegend values, including hidden items (zero totals yield 0%). `value-percentage` appends both,\nas `label: value (percentage)`. Dataset values are sampled sums; category values come from the\nfirst dataset. The `formatter`/`valueFormatter` callback backing `value` and `value-percentage`\nadditionally receives that same `percentage` in its `surface: 'legend'` context, so a custom\nformatter can build its own combined text without recomputing the share. Tooltip and axis\nformatting are unchanged.\n\nAttribute: `legend-display`","type":"LyraChartLegendDisplay","default":"'auto'"},{"name":"legendMode","description":"`datum` renders category toggles for pie/doughnut/polar-area charts. Categories use the first\ndataset's colors and values; a toggle affects that category in every ring. Other chart types\nretain dataset legends. `auto` (the default) resolves to `datum` on pie/doughnut/polar-area\ncharts -- where a single-dataset legend would otherwise enumerate one entry for the whole\ndataset instead of one per visible slice -- and to `dataset` everywhere else. `dataset` always\nforces the dataset legend, even on a slice chart. Both non-`auto` modes use the generated\naccessible-data sampling budget.\n\nAttribute: `legend-mode`","type":"LyraChartLegendMode","default":"'auto'"},{"name":"legendPosition","description":"Legend placement. `auto` uses a right legend above 480px and a bottom legend below it.\n\nAttribute: `legend-position`","type":"LyraChartLegendPosition","default":"'top'"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"max","description":"Maximum value-axis bound. Non-finite values are ignored.\n\nAttribute: `max`","type":"number | null","default":"null"},{"name":"min","description":"Minimum value-axis bound. Non-finite values are ignored.\n\nAttribute: `min`","type":"number | null","default":"null"},{"name":"plugins","description":"Chart.js plugins attached to this chart instance. Valid plugins retain their opaque identity.\n\nAttribute: `plugins`","type":"readonly LyraChartPlugin[]","default":"[]"},{"name":"scaleType","description":"Scale type for the **value** axis (the categorical axis is unaffected). `'logarithmic'` plots\na dataset spanning several orders of magnitude honestly, where a linear axis collapses\neverything below the maximum into the baseline. Inherited by `lr-line-chart`,\n`lr-scatter-chart` and `lr-bar-chart`.\n\nA logarithmic axis cannot represent zero or negative values (`log(0)` is `-Infinity`), so\n`beginAtZero` is not forwarded in that mode -- Chart.js would otherwise be handed a bound it\ncannot place. Non-positive data points are dropped by Chart.js's own log scale.\n\nAttribute: `scale-type`","type":"LyraChartScaleType","default":"'linear'"},{"name":"showDataTable","description":"Makes the generated data table visible; it remains screen-reader available when false.\n\nAttribute: `show-data-table`","type":"boolean","default":"false"},{"name":"stackTotals","description":"When the chart is `stacked` (bar/line only), draws the per-category stack\ntotal above each stack, via the same optional `chartjs-plugin-datalabels`\npeer as `data-labels`. Null/undefined points are skipped; a category whose\nevery value is null shows no total. The generated accessible data table\nreceives the same formatted total column (one per value axis). Unset (the\ndefault) draws and adds nothing.\n\nAttribute: `stack-totals`","type":"boolean","default":"false"},{"name":"stacked","description":"Stacks the `x`/`y`(/`y2`) scale entries `buildScales()` returns; only meaningful for `bar` and `line` types.\n\nAttribute: `stacked`","type":"boolean","default":"false"},{"name":"stackedAxes","description":"Per-value-axis override of `stacked`, keyed by `'y'`/`'y2'`. An axis absent from this record\n-- including every axis when the whole property is unset -- falls back to the chart-wide\n`stacked` value, which is what keeps a chart that never sets this byte-identical to before.\nLets a `stacked` bar series on the primary axis sit next to an unstacked overlay series on\n`y2` (via `LyraChartSeries.axis: 'y2'`): set `stackedAxes` to `{ y2: false }` alongside\n`stacked`, or spell out both axes explicitly. The shared categorical axis (`x` for a vertical\nbar/line, or `y` when `indexAxis` is `'y'`) has no independent entry of its own -- it always\nmirrors the resolved `'y'` value, matching Chart.js's own paired index/value-scale stacking\ncontract. Only meaningful for `bar`/`line` types, matching `stacked` itself.","type":"Partial<Record<'y' | 'y2', boolean>> | undefined"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"tooltipFooterFormatter","description":"Tooltip footer formatter -- e.g. a category's stack total under the items. Receives every\nitem the hovered tooltip covers, in the same shape as `tooltipTitleFormatter`. Unset (the\ndefault) leaves Chart.js's own default (no footer).","type":"LyraChartTooltipGroupFormatter | undefined"},{"name":"tooltipTitleFormatter","description":"Tooltip title formatter -- e.g. a scatter point's own name. Receives every item the hovered\ntooltip covers, each in `formatter`'s `'tooltip'`-surface context shape. Unset (the default)\nleaves Chart.js's own default title (the shared category label) in place.","type":"LyraChartTooltipGroupFormatter | undefined"},{"name":"type","description":"Attribute: `type`","type":"LyraChartType","default":"'doughnut'"},{"name":"valueFormatter","description":"Formats numeric (value-axis) ticks, tooltip values, legend values, and generated accessible\ntable cells from one callback.\nHorizontal scalar tooltips use parsed x, including a raw config indexAxis override;\nstructured points retain their y-value contract. The context-object formatter shares this rule.\nNever runs against the categorical x-axis's own labels (line/bar's `labels` strings) —\nChart.js's category scale passes the tick index to `ticks.callback`, not the label text,\nso formatting it would corrupt the axis.","type":"LyraChartValueFormatter | undefined"},{"name":"withoutAnimation","description":"Disables Chart.js animation.\n\nAttribute: `without-animation`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"withoutLegend","description":"Hides the legend.\n\nAttribute: `without-legend`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"withoutTooltip","description":"Hides Chart.js tooltips.\n\nAttribute: `without-tooltip`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"xLabel","description":"Attribute: `x-label`","type":"string | null","default":"null"},{"name":"y2Label","description":"Attribute: `y2-label`","type":"string","default":"''"},{"name":"yLabel","description":"Attribute: `y-label`","type":"string | null","default":"null"},{"name":"zoom","description":"Attribute: `zoom`","type":"boolean","default":"false"}],"events":[{"name":"lr-before-datum-visibility-change","description":"Cancelable category visibility proposal in datum legend mode. `detail: { index: number, visible: boolean, hiddenDatums: readonly number[] }`. Source category indexes apply to every dataset/ring. The complete detail is frozen.","type":"CustomEvent<LyraChartDatumVisibilityChangeDetail>"},{"name":"lr-before-legend-visibility-change","description":"Cancelable proposal emitted before a DOM legend toggle changes state. `detail` contains the target `datasetIndex`, its proposed `visible` value, and the complete canonical proposed `hiddenDatasets` snapshot.","type":"CustomEvent<LyraChartLegendVisibilityChangeDetail>"},{"name":"lr-datum-activate","description":"Family-normalized activation event. Its detail adds `kind` (`bar`, `point`, `segment`, or `slice`) to the `lr-point-click` detail.","type":"CustomEvent<\n    LyraChartDatumActivateDetail<LyraCoreChartDatumKind>\n  >"},{"name":"lr-datum-visibility-change","description":"Emitted after an accepted category toggle commits the same frozen detail. Programmatic `hiddenDatums` assignments are silent.","type":"CustomEvent<LyraChartDatumVisibilityChangeDetail>"},{"name":"lr-legend-visibility-change","description":"Emitted after an accepted DOM legend toggle commits the same detail. Programmatic `hiddenDatasets` changes reconcile without either event.","type":"CustomEvent<LyraChartLegendVisibilityChangeDetail>"},{"name":"lr-point-click","description":"Fired when pointer input lands on a data point/segment, when a generated data-table value is activated, or when Enter/Space activates the keyboard-current canvas datum. `detail: { datasetIndex: number, index: number, label: string | undefined, value: unknown }`. For scatter/bubble data, `label` prefers the per-point label and `value` is the complete typed `LyraChartPoint` (`x`, `y`, optional `r`, optional `label`).","type":"CustomEvent<{\n    datasetIndex: number;\n    index: number;\n    label: string | undefined;\n    value: unknown;\n  }>"},{"name":"lr-zoom","description":"`detail: { zoomed }`.","type":"CustomEvent<{ zoomed: boolean }>"}]}},{"name":"lr-drawer","description":"`<lr-drawer>` — a modal panel anchored to one logical edge of the\nviewport. It shares Lyra's dialog focus trap, Escape/backdrop dismissal,\nscroll lock, top-layer promotion, stacking, accessible naming,\n`show()`/`hide()`/`close()` surface, and the whole\n`lr-show`/`lr-after-show`/`lr-hide`/`lr-after-hide`/`lr-close` lifecycle — see\n`<lr-dialog>` for all of it. `contained` instead positions within the nearest containing block\nas a nonmodal panel: no backdrop, inerting, focus trap, scroll lock, top layer, or global Escape.\nOnly that mode, the slide animation, `placement`, and the `--size` alias are drawer-specific.\nThe panel registry names are `drawer.showTop`/`hideTop`, `showEnd`/`hideEnd`,\n`showBottom`/`hideBottom`, and `showStart`/`hideStart`; the scrim uses\n`drawer.overlay.show`/`drawer.overlay.hide`.\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 drawer body. |\n| `footer` | Action buttons rendered in the footer row. |\n| `header-actions` | Extra header controls, inherited from `<lr-dialog>`. |\n| `label` | Rich header content, inherited from `<lr-dialog>`. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `backdrop` | The full-viewport scrim behind the panel; also carries `overlay`. |\n| `base` | Shoelace wrapper alias. |\n| `body` | The wrapper around the default slot. |\n| `close-button` | The built-in close button, rendered inside `header` only when `closable` is `true`. |\n| `close-button__base` | Exported mapped alias on the close button, on the same node. |\n| `close-button__control` | The composed `<lr-icon-button>`'s own native control, forwarded because the painted surface now sits one shadow boundary deeper than `close-button`. As of 16.0.0 the close button IS an `<lr-icon-button>`, so its background, radius, hover/press mixes, focus ring and hit-area floor come from `--lr-icon-button-*`; a rule that painted through `::part(close-button)` moves here or onto the token. |\n| `dialog` | Web Awesome alias on the panel. |\n| `footer` | The wrapper around the `footer` slot. |\n| `header` | The header row, rendered when the `label` slot is filled, `label`/`heading` is set (and no heading is slotted into the default slot), `header-actions` is filled, and/or `closable` is `true` — and never when `noHeader` or `withoutHeader` is set. |\n| `header-actions` | The wrapper around the `header-actions` slot. |\n| `heading` | The visible title inside `header`; also carries `title` and `label`, and owns the configured heading semantics unless opted out. |\n| `label` | Mapped alias on the visible title. |\n| `overlay` | Shoelace alias on the backdrop. |\n| `panel` | The dialog panel itself (`role=\"dialog\"` while open); also carries `dialog`. Shrink-wraps to its content by default, capped at `--lr-dialog-max-width` (default `32rem` at the `size=\"m\"` tier — see the `size` property); set `--lr-dialog-width` for an assertive width instead of only a cap. `--lr-dialog-height` is the same idea on the block axis: left unset the panel stays content-sized (capped at the viewport), and set it gives `body` a definite size to fill and scroll within while `header`/ `footer` keep their natural size. |\n| `title` | Mapped alias on the visible title. |\n\n---\n\n**CSS Custom Properties**\n\n- `--backdrop-filter` (default: `var(--lr-dialog-backdrop-filter,none)`) — Mapped backdrop-filter alias.\n- `--body-spacing` — Shoelace body padding.\n- `--footer-spacing` — Shoelace footer padding.\n- `--header-spacing` — Shoelace header padding.\n- `--hide-duration` — Closing slide duration.\n- `--lr-dialog-backdrop-duration` (default: `var(--lr-duration-fast)`) — Duration of the backdrop's fade.\n- `--lr-dialog-backdrop-filter` (default: `none`) — `backdrop-filter` applied to the scrim, for a frosted-glass treatment over the page behind it.\n- `--lr-dialog-height` (default: `auto`) — Assertive block size for the panel, mirroring `--lr-dialog-width` on the other axis. Left at `auto` the panel shrink-wraps to its content, unchanged from before this property existed; always capped at `100%` (the viewport) like every other panel dimension. With it set, `body`'s own `flex: 1 1 auto` is what actually gives slotted content a definite, fillable block size -- `header` and `footer` keep their natural size and only `body` grows or shrinks into the remaining space.\n- `--lr-dialog-max-width` (default: `var(--lr-dialog-width, var(--_lr-dialog-max-width))`) — Cap on the panel's inline size. Falls back to `--lr-dialog-width` when that is set, so an assertive width is not clipped by the tier default; the viewport (`100%`) is always a hard limit on top. The innermost fallback steps with `size` across the shared six-step ladder (`20rem` at `2xs` up to `48rem` at `xl`, `32rem` unchanged at the `m` default) -- an inherited or direct value here still wins outright over every tier.\n- `--lr-dialog-overlay-color` (default: `var(--lr-color-overlay)`) — Backdrop scrim color.\n- `--lr-dialog-panel-duration` (default: `var(--lr-duration-base)`) — Duration of the panel's enter/exit animation.\n- `--lr-dialog-spacing` (default: `var(--lr-space-l)`) — Padding inside the body, and the inline padding of the header and footer rows.\n- `--lr-dialog-spacing-block` (default: `var(--lr-space-m)`) — Block padding of the header and footer rows, which are tighter than the body by default.\n- `--lr-dialog-width` (default: `auto`) — Assertive inline size for the panel. Left at `auto` the panel shrink-wraps to its content.\n- `--lr-drawer-enter-x` (default: `calc(-1 * var(--lr-size-1rem))`) — Horizontal offset the panel slides in from, and back out to, for start/end drawers. Its private default changes per placement (and flips under RTL); an inherited or direct public value remains authoritative.\n- `--lr-drawer-enter-y` (default: `calc(-1 * var(--lr-size-1rem))`) — Vertical offset the panel slides in from, and back out to, for top/bottom drawers. Its private default becomes `var(--lr-size-1rem)` for `bottom`; an inherited or direct public value remains authoritative.\n- `--lr-drawer-height` — Block size for top/bottom drawers.\n- `--lr-drawer-width` — Inline size for start/end drawers.\n- `--lr-overlay-border` (default: `var(--lr-color-border)`) — Shared floating-surface edge colour, on the panel and on the header's and footer's dividing rules.\n- `--lr-overlay-radius` (default: `var(--lr-radius)`) — Shared floating-surface corner radius, on the panel and on the close button.\n- `--lr-overlay-shadow-modal` (default: `var(--lr-shadow-xl)`) — Elevation of a modal panel. A separate tier from `--lr-overlay-shadow-anchored`, so raising popups never raises dialogs.\n- `--lr-overlay-surface` (default: `var(--lr-color-surface-overlay)`) — Shared floating-surface fill, on the panel. The same family every anchored popup now reads, so one declaration retints the dialog and the popups opened from it together.\n- `--show-duration` — Opening slide duration.\n- `--size` — Mapped drawer size for the active axis.\n- `--spacing` (default: `var(--lr-dialog-spacing,var(--lr-space-l))`) — Web Awesome shared region spacing.\n- `--width` (default: `var(--lr-dialog-width,auto)`) — Mapped panel width alias.","attributes":[{"name":"accessible-label","description":"Explicit accessible-only panel name. Unlike `label`, it never renders visible text.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"aria-label","description":"Host-level `aria-label` override for the panel's accessible name — wins by attribute\npresence, including an explicitly empty value, over every other naming source (a slotted\nheading, the `label` slot, `heading`, the `label` property) without suppressing visible\nheading chrome, matching `<lr-date-input>`'s `accessibleLabel` pattern. See the class doc for\nthe full precedence order. Set as a plain `aria-label` attribute on `<lr-dialog>` itself, not\na public JS property.\n\nType: `string | null`  \nDefault: `null`"},{"name":"closable","description":"Renders a built-in close (X) button in the header row (creating one,\nwith no heading text, if `label` and `heading` are unset), wired to the same\n`close()` path Escape/backdrop-dismiss already use, with reason\n`'close-button'`.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"contained","description":"Positions inside the nearest containing block without modal inerting, focus trapping,\nscroll locking, top-layer promotion, backdrop, or Escape dismissal.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"heading","description":"Legacy visible title fallback. The richer `label` slot and mapped `label` property win. Has\nno effect when a direct light-DOM heading already supplies custom title chrome.\n\nType: `string | undefined`"},{"name":"heading-level","description":"Semantic level of the generated visible title. Use `none` for visual-only text. A direct\nlight-DOM heading retains its own native/ARIA level; invalid untyped values use level 3.\n\nType: `LyraHeadingLevel`  \nDefault: `'3'`","value":{"type":["'1'","'2'","'3'","'4'","'5'","'6'","'none'"]}},{"name":"label","description":"Visible mapped title. The richer `label` slot wins when both are supplied.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"light-dismiss","description":"Dismisses the dialog on a backdrop click. Opt-in and `false` by default, matching\n`wa-dialog`. This was previously spelled `no-light-dismiss` — an opt-*out* whose default left\nbackdrop dismissal on, so a mechanical `wa-dialog` → `lr-dialog` rename silently flipped the\nbehaviour of every migrated dialog. A rename that changes what the markup does with nothing\nto warn on is worse than no rename at all, so the polarity now matches upstream exactly.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"no-header","description":"Shoelace's spelling (`sl-dialog`'s `no-header`) for suppressing the header row, read alongside\nWeb Awesome's `withoutHeader` above so a consumer arriving from either upstream finds their\nown attribute working. Neither is deprecated.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"open","description":"Whether the dialog is open. Assigning it runs the full `lr-show`/`lr-hide` lifecycle, so it\nstays in sync with `show()`/`hide()`/`close()` and can be vetoed the same way. Markup that\nrenders open from the start emits nothing.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"placement","description":"Which edge the drawer slides in from. `end` by default, matching `wa-drawer`; it used to be\n`start`, so a mechanical rename silently moved every migrated drawer to the other side.\n\nType: `LyraDrawerPlacement`  \nDefault: `'end'`","value":{"type":["'start'","'end'","'top'","'bottom'"]}},{"name":"size","description":"Visual width tier for the panel, on the library's shared six-step size ladder. `'m'` (the\ndefault) is this component's pre-existing behaviour, unchanged: an unset panel still caps at\n`--lr-dialog-max-width`'s literal `32rem` default. Every other tier scales that same cap, from\na compact `20rem` at `2xs` up to a roomy `48rem` at `xl`; an explicit `--lr-dialog-width` or\n`--lr-dialog-max-width` override still wins over any tier.\n\nType: `LyraSize`  \nDefault: `'m'`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}},{"name":"with-footer","description":"SSR hint that keeps the footer wrapper rendered before slot assignment is observable.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"without-header","description":"Suppresses the header row entirely, whatever `heading`, `closable`, the `label` slot or the\n`header-actions` slot would otherwise render. For a dialog that owns its own chrome. This is\nWeb Awesome's spelling (`wa-dialog`'s `without-header`); `noHeader` below is Shoelace's. Both\nare current upstream names, both are read, and neither is deprecated.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"","description":"The drawer body."},{"name":"footer","description":"Action buttons rendered in the footer row."},{"name":"header-actions","description":"Extra header controls, inherited from `<lr-dialog>`."},{"name":"label","description":"Rich header content, inherited from `<lr-dialog>`."}],"js":{"properties":[{"name":"accessibleLabel","description":"Explicit accessible-only panel name. Unlike `label`, it never renders visible text.\n\nAttribute: `accessible-label`","type":"string","default":"''"},{"name":"closable","description":"Renders a built-in close (X) button in the header row (creating one,\nwith no heading text, if `label` and `heading` are unset), wired to the same\n`close()` path Escape/backdrop-dismiss already use, with reason\n`'close-button'`.\n\nAttribute: `closable`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"contained","description":"Positions inside the nearest containing block without modal inerting, focus trapping,\nscroll locking, top-layer promotion, backdrop, or Escape dismissal.\n\nAttribute: `contained`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"heading","description":"Legacy visible title fallback. The richer `label` slot and mapped `label` property win. Has\nno effect when a direct light-DOM heading already supplies custom title chrome.\n\nAttribute: `heading`","type":"string | undefined"},{"name":"headingLevel","description":"Semantic level of the generated visible title. Use `none` for visual-only text. A direct\nlight-DOM heading retains its own native/ARIA level; invalid untyped values use level 3.\n\nAttribute: `heading-level`  \nReflected to its attribute.","type":"LyraHeadingLevel","default":"'3'"},{"name":"label","description":"Visible mapped title. The richer `label` slot wins when both are supplied.\n\nAttribute: `label`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"lightDismiss","description":"Dismisses the dialog on a backdrop click. Opt-in and `false` by default, matching\n`wa-dialog`. This was previously spelled `no-light-dismiss` — an opt-*out* whose default left\nbackdrop dismissal on, so a mechanical `wa-dialog` → `lr-dialog` rename silently flipped the\nbehaviour of every migrated dialog. A rename that changes what the markup does with nothing\nto warn on is worse than no rename at all, so the polarity now matches upstream exactly.\n\nAttribute: `light-dismiss`","type":"boolean","default":"false"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"modal","description":"Shoelace-compatible modal controller. External activation suspends this dialog's focus/Escape\nownership without changing its logical `open` state; deactivation restores it.","type":"LyraDialogModalController","default":"{ activateExternal: () => { this.externalModalDepth++; if (this.externalModalDepth === 1) this.overlay?.suspend(); }, deactivateExternal: () => { if (this.externalModalDepth === 0) return; this.externalModalDepth--; if (this.externalModalDepth === 0 && this.open && this.modalSurface) { this.overlay?.resume(); queueMicrotask(() => this.focusInitial()); } }, }"},{"name":"noHeader","description":"Shoelace's spelling (`sl-dialog`'s `no-header`) for suppressing the header row, read alongside\nWeb Awesome's `withoutHeader` above so a consumer arriving from either upstream finds their\nown attribute working. Neither is deprecated.\n\nAttribute: `no-header`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"open","description":"Whether the dialog is open. Assigning it runs the full `lr-show`/`lr-hide` lifecycle, so it\nstays in sync with `show()`/`hide()`/`close()` and can be vetoed the same way. Markup that\nrenders open from the start emits nothing.\n\nAttribute: `open`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"placement","description":"Which edge the drawer slides in from. `end` by default, matching `wa-drawer`; it used to be\n`start`, so a mechanical rename silently moved every migrated drawer to the other side.\n\nAttribute: `placement`  \nReflected to its attribute.","type":"LyraDrawerPlacement","default":"'end'"},{"name":"size","description":"Visual width tier for the panel, on the library's shared six-step size ladder. `'m'` (the\ndefault) is this component's pre-existing behaviour, unchanged: an unset panel still caps at\n`--lr-dialog-max-width`'s literal `32rem` default. Every other tier scales that same cap, from\na compact `20rem` at `2xs` up to a roomy `48rem` at `xl`; an explicit `--lr-dialog-width` or\n`--lr-dialog-max-width` override still wins over any tier.\n\nAttribute: `size`  \nReflected to its attribute.","type":"LyraSize","default":"'m'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"withFooter","description":"SSR hint that keeps the footer wrapper rendered before slot assignment is observable.\n\nAttribute: `with-footer`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"withoutHeader","description":"Suppresses the header row entirely, whatever `heading`, `closable`, the `label` slot or the\n`header-actions` slot would otherwise render. For a dialog that owns its own chrome. This is\nWeb Awesome's spelling (`wa-dialog`'s `without-header`); `noHeader` below is Shoelace's. Both\nare current upstream names, both are read, and neither is deprecated.\n\nAttribute: `without-header`  \nReflected to its attribute.","type":"boolean","default":"false"}],"events":[{"name":"lr-after-hide","description":"The drawer is closed and has finished sliding out.","type":"CustomEvent<null>"},{"name":"lr-after-show","description":"The drawer is open and has finished sliding in.","type":"CustomEvent<null>"},{"name":"lr-close","description":"Inherited conditionally cancelable close event; detail is the dismissal reason. Ordinary dismissal can be vetoed; an `'unmount'` notification after external removal cannot be. **The name is not drawer-scoped, so filter by target.** `lr-close` is also emitted by several components commonly nested inside a drawer body (`<lr-callout>`, `<lr-tab>`/ `<lr-tab-group>`, `<lr-command-palette>`, `<lr-document-viewer>`), and library events bubble and are composed, so a listener bound directly on `<lr-drawer>` also receives a descendant's close. Guard on the target exactly as documented on `<lr-dialog>`'s own `lr-close`: `if (event.target !== event.currentTarget) return;`. It inherits every `<lr-dialog>` CSS part unchanged, with one deliberate layout exception: `<lr-dialog>`'s `[part=\"body\"]` grows to fill the panel once a consumer sets `--lr-dialog-height`, because that panel is otherwise content-sized. A drawer's panel is unconditionally a definite size for every `placement`, so this component opts back out of that growth — `body` keeps its natural content size and `footer` follows immediately after it, exactly as before `--lr-dialog-height` existed, instead of always being pushed to the panel's far edge. The `size` property, inherited unchanged from `<lr-dialog>`, caps the panel's `max-inline-size` for `start`/`end` placements on the same six-step ladder documented there (`'m'`'s 32rem cap exceeds the panel's own 24rem default inline size, so it stays a no-op at the default tier); `top`/`bottom` placements are unaffected, since those axes are already unconditionally 100%. Not to be confused with the drawer-specific `--size` CSS custom property below, which maps to this same panel's own `inline-size`/`block-size` for the active axis.","type":"CustomEvent<DialogCloseReason>"},{"name":"lr-hide","description":"The drawer is about to close. Cancelable.","type":"CustomEvent<LyraDialogHideDetail>"},{"name":"lr-initial-focus","description":"Inherited cancelable event before automatic modal focus movement.","type":"CustomEvent<null>"},{"name":"lr-request-close","description":"Inherited cancelable built-in dismissal request with a source detail.","type":"CustomEvent<LyraDialogRequestCloseDetail>"},{"name":"lr-show","description":"The drawer is about to open. Cancelable.","type":"CustomEvent<null>"}]}},{"name":"lr-drilldown-panel","description":"`<lr-drilldown-panel>` — a controlled navigation and category shell for related evidence,\ndocuments, entities, and host-rendered agent runs.\n\n`path` is normalized into a bounded, clone-owned, deeply frozen snapshot. Nodes use `nodeId`,\nevidence uses `evidenceId`, documents use `documentId`, and entities use `entityId`; invalid or\nlater duplicate identities are ignored. Activating a non-current breadcrumb emits a frozen\n`lr-drilldown-navigate` request and never mutates `path`.\n\n`activeCategory` is controlled too. The first available category is the fallback while the\nproperty is empty or unavailable. A tab interaction emits `lr-drilldown-category-change`, then\nrestores the authored category unless the host accepts the request by assigning the property.\nOnly the effective category's children are mounted. Its records are paged eight at a time, so a\ndocument category owns at most eight simultaneous `lr-document-preview` resource lifecycles;\nreplacement, paging, category changes, and disconnect remove obsolete previews and let each\npreview abort its owner-realm fetch. A localized range reports every bounded page and any input\nomitted by the schema ceiling.\n\nEvents from composed source cards, document previews, entity cards, and tabs do not leak raw.\nEach supported child event is either contained or translated to a drilldown event carrying the\ncurrent `nodeId` plus its domain item identity. Events from consumer-owned `runs` slot content\nremain consumer-owned and continue bubbling normally.\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**Slots**\n\n| Name | Description |\n| --- | --- |\n| `runs` | Host-rendered agent-run content for the current node's Agent runs category. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The root wrapper. |\n| `breadcrumb` | The nested breadcrumb trail. |\n| `breadcrumb-button` | A non-current breadcrumb's clickable label. |\n| `breadcrumb-item` | One nested breadcrumb item. |\n| `category` | The mounted active category wrapper. |\n| `content` | The current category content or empty state. |\n| `document-item` | One nested document preview. |\n| `empty` | The empty state. |\n| `entity-item` | One nested entity card. |\n| `evidence-item` | One nested source card. |\n| `limit` | A localized range reporting schema-truncated input. |\n| `next-button` | The next-page button. |\n| `pagination` | Controls and range summary for a bounded category page. |\n| `pagination-summary` | The localized visible range. |\n| `previous-button` | The previous-page button. |\n| `tabs` | The nested tab group when multiple categories are available. |","attributes":[{"name":"active-category","description":"Host-owned active category. Empty or unavailable values resolve to the first populated\ncategory without changing the authored value. User interaction emits a request only.\n\nType: `LyraDrilldownCategory | ''`","value":{"type":["'evidence'","'documents'","'entities'","'runs'","''"]}},{"name":"aria-label","description":"Accessible name forwarded to the current category owner. `null` leaves a tab strip unnamed\nand uses the category label for a sole region; an explicit empty string is preserved.\n\nType: `string | null`  \nDefault: `null`"},{"name":"community-label","description":"Forwarded to every nested entity card.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"show-focus-button","description":"Forwarded to every nested entity card.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}}],"slots":[{"name":"runs","description":"Host-rendered agent-run content for the current node's Agent runs category."}],"js":{"properties":[{"name":"accessibleLabel","description":"Accessible name forwarded to the current category owner. `null` leaves a tab strip unnamed\nand uses the category label for a sole region; an explicit empty string is preserved.\n\nAttribute: `aria-label`","type":"string | null","default":"null"},{"name":"activeCategory","description":"Host-owned active category. Empty or unavailable values resolve to the first populated\ncategory without changing the authored value. User interaction emits a request only.\n\nAttribute: `active-category`  \nReflected to its attribute.","type":"LyraDrilldownCategory | ''"},{"name":"communityLabel","description":"Forwarded to every nested entity card.\n\nAttribute: `community-label`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"path","description":"Full host-owned breadcrumb trail. Assigning snapshots valid records into bounded immutable\nstorage; invalid records and later duplicate `nodeId` values are ignored.","type":"readonly LyraDrilldownNode[]"},{"name":"showFocusButton","description":"Forwarded to every nested entity card.\n\nAttribute: `show-focus-button`","type":"boolean","default":"true"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"types","description":"Immutable node-type styling forwarded to entity cards. Invalid and duplicate entries are\nignored. This is structurally identical to the graph/entity node-style vocabulary.","type":"readonly LyraNodeTypeStyle[]"}],"events":[{"name":"lr-drilldown-category-change","description":"Frozen controlled request detail `{ nodeId, category, previousCategory }`.","type":"CustomEvent<LyraDrilldownCategoryChangeDetail>"},{"name":"lr-drilldown-document-download","description":"Correlated document download detail.","type":"CustomEvent<LyraDrilldownDocumentDownloadDetail>"},{"name":"lr-drilldown-document-highlight-activate","description":"Correlated document highlight detail.","type":"CustomEvent<LyraDrilldownDocumentHighlightActivateDetail>"},{"name":"lr-drilldown-document-render-error","description":"Correlated document render failure detail.","type":"CustomEvent<LyraDrilldownDocumentRenderErrorDetail>"},{"name":"lr-drilldown-entity-activate","description":"Correlated entity activation detail.","type":"CustomEvent<LyraDrilldownEntityActivateDetail>"},{"name":"lr-drilldown-evidence-expand","description":"Correlated evidence expansion detail.","type":"CustomEvent<LyraDrilldownEvidenceExpandDetail>"},{"name":"lr-drilldown-evidence-open","description":"Correlated evidence activation detail.","type":"CustomEvent<LyraDrilldownEvidenceOpenDetail>"},{"name":"lr-drilldown-navigate","description":"Frozen breadcrumb request detail `{ nodeId, index }`.","type":"CustomEvent<LyraDrilldownNavigateDetail>"}]}},{"name":"lr-drop-zone","description":"`<lr-drop-zone>` -- a drag-and-drop region wrapper with no file input of its own. Wrap it around\nan arbitrary region (a chat composer, a whole conversation viewport, a panel far larger than any\nsingle control) to make that entire region a file-drop target: it owns the drag-session state,\nrenders a themeable drag-over overlay, applies `accept`/size/count limits, and emits the same\n`lr-files` event shape `lr-file-input` does -- `detail: { files, rejected }` -- so the two are\ninterchangeable from a listener's point of view. It never renders a native file picker, a\nselected-file list, or any focusable control of its own; wrap `lr-file-input` itself (or any\nother focusable content) inside it when the region also needs a click-to-browse affordance.\n\nThe drag-session mechanics (nested-depth tracking, accept/reject preview, legacy File System API\nfolder traversal) are the exact ones `lr-file-input` uses, shared through\n`internal/drop-session-controller.ts` rather than reimplemented here.\n\n---\n\n**Component metadata**\n\n- Status: `experimental`\n- Since: `16.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**Slots**\n\n| Name | Description |\n| --- | --- |\n| (default) | The wrapped region. Rendered as ordinary light DOM content; this element adds only the drag listeners and the overlay layered on top. |\n| `overlay` | Custom drag-over overlay content, overriding the localized accept/reject text. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The wrapping element wrapping the default slot and the overlay. |\n| `overlay` | The drag-over overlay, layered above the slotted content. Hidden outside an active drag session. |\n| `overlay-icon` | The default decorative overlay icon. |\n| `overlay-text` | Wrapper around the overlay slot/text content. |\n| `rejection` | The visible region listing each currently-rejected file alongside its reason, rendered in addition to the sr-only `status` summary. |\n| `status` | The visually-hidden, `aria-hidden` mirror of the drag accept/reject state and accepted/rejected counts. The announcement itself lands in the shared light-DOM polite region (`acquireAnnouncementSink()` in `internal/announcer.ts`); this part is a styling/inspection surface only. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-drop-zone-accept-bg` (default: `color-mix(in srgb, var(--lr-color-success) 12%, transparent)`) — Background of `[part=\"overlay\"][data-drag-state=\"accept\"]`.\n- `--lr-drop-zone-accept-border-color` (default: `var(--lr-color-success)`) — Border color of `[part=\"overlay\"][data-drag-state=\"accept\"]`.\n- `--lr-drop-zone-overlay-bg` (default: `color-mix(in srgb, var(--lr-color-brand) 8%, transparent)`) — Fill of `[part=\"overlay\"]` in that same neutral drag state.\n- `--lr-drop-zone-overlay-border-color` (default: `var(--lr-color-brand)`) — Dashed border color of `[part=\"overlay\"]` in its neutral drag state, before an accept or reject verdict.\n- `--lr-drop-zone-overlay-font-size` (default: `var(--lr-font-size-md-sm)`) — Overlay instructional text size.\n- `--lr-drop-zone-overlay-gap` (default: `var(--lr-space-xs)`) — Gap between the overlay icon and text.\n- `--lr-drop-zone-overlay-icon-size` (default: `var(--lr-font-size-xl)`) — `[part=\"overlay-icon\"]` glyph size.\n- `--lr-drop-zone-radius` (default: `var(--lr-radius)`) — Corner radius of `[part=\"overlay\"]`.\n- `--lr-drop-zone-reject-bg` (default: `color-mix(in srgb, var(--lr-color-danger) 12%, transparent)`) — Background of `[part=\"overlay\"][data-drag-state=\"reject\"]`.\n- `--lr-drop-zone-reject-border-color` (default: `var(--lr-color-danger)`) — Border color of `[part=\"overlay\"][data-drag-state=\"reject\"]`.","attributes":[{"name":"accept","description":"Native-`accept`-style allowlist (`\".csv,.xlsx\"`, `\"image/*\"`, comma-separated mixes) --\nidentical parsing to `lr-file-input`'s `accept`, via the same `matchesAccept()`.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"disabled","description":"Disables drag/drop handling entirely; the wrapped content keeps its own interactivity.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"held-file-count","description":"Externally held file count added to the running count `maxFiles` evaluates against --\nidentical contract to `lr-file-input`'s `heldFileCount`, letting a cumulative, server-backed\ncap span separate drops onto this region. `0` (the default) means \"nothing held\" and\nreproduces prior behavior exactly. A negative, `NaN`, or `Infinity` value is normalized to\n`0` via `finiteCount`.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"held-total-size","description":"Externally held byte total added to the running size `maxTotalSize` evaluates against --\nidentical contract to `lr-file-input`'s `heldTotalSize`.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max-file-size","description":"Largest accepted file size in bytes. `0` (the default) disables the check -- identical\ncontract to `lr-file-input`'s `maxFileSize`, including its invalid-override fallback.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"max-files","description":"Largest number of files accepted per drop, counting `heldFileCount` plus the current drop's\nfiles. `0` (the default) disables the check -- identical contract to `lr-file-input`'s\n`maxFiles`. Since this component retains nothing of its own between drops, the count would\notherwise always cover only the current drop -- `heldFileCount` is what lets a cumulative cap\nspan separate drops.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"max-total-size","description":"Largest combined byte size accepted per drop, summing `heldTotalSize` plus the current\ndrop's files. `0` (the default) disables the check -- identical contract to\n`lr-file-input`'s `maxTotalSize`.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"multiple","description":"Accepts more than one file per drop, and enables recursive folder-drop traversal -- same\ncontract as `lr-file-input`'s `multiple`. Unlike `lr-file-input`, this defaults to `true`:\na region wrapper's typical use (dropping several files onto a chat surface) expects more than\none file, and there is no native single-file picker here to keep in sync.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}}],"slots":[{"name":"","description":"The wrapped region. Rendered as ordinary light DOM content; this element adds only the drag listeners and the overlay layered on top."},{"name":"overlay","description":"Custom drag-over overlay content, overriding the localized accept/reject text."}],"js":{"properties":[{"name":"accept","description":"Native-`accept`-style allowlist (`\".csv,.xlsx\"`, `\"image/*\"`, comma-separated mixes) --\nidentical parsing to `lr-file-input`'s `accept`, via the same `matchesAccept()`.\n\nAttribute: `accept`","type":"string","default":"''"},{"name":"disabled","description":"Disables drag/drop handling entirely; the wrapped content keeps its own interactivity.\n\nAttribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"dragging","description":"Readonly state derived from the current drag session.","type":"boolean","default":"false","read-only":true},{"name":"heldFileCount","description":"Externally held file count added to the running count `maxFiles` evaluates against --\nidentical contract to `lr-file-input`'s `heldFileCount`, letting a cumulative, server-backed\ncap span separate drops onto this region. `0` (the default) means \"nothing held\" and\nreproduces prior behavior exactly. A negative, `NaN`, or `Infinity` value is normalized to\n`0` via `finiteCount`.\n\nAttribute: `held-file-count`","type":"number","default":"0"},{"name":"heldTotalSize","description":"Externally held byte total added to the running size `maxTotalSize` evaluates against --\nidentical contract to `lr-file-input`'s `heldTotalSize`.\n\nAttribute: `held-total-size`","type":"number","default":"0"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"maxFileSize","description":"Largest accepted file size in bytes. `0` (the default) disables the check -- identical\ncontract to `lr-file-input`'s `maxFileSize`, including its invalid-override fallback.\n\nAttribute: `max-file-size`","type":"number","default":"0"},{"name":"maxFiles","description":"Largest number of files accepted per drop, counting `heldFileCount` plus the current drop's\nfiles. `0` (the default) disables the check -- identical contract to `lr-file-input`'s\n`maxFiles`. Since this component retains nothing of its own between drops, the count would\notherwise always cover only the current drop -- `heldFileCount` is what lets a cumulative cap\nspan separate drops.\n\nAttribute: `max-files`","type":"number","default":"0"},{"name":"maxTotalSize","description":"Largest combined byte size accepted per drop, summing `heldTotalSize` plus the current\ndrop's files. `0` (the default) disables the check -- identical contract to\n`lr-file-input`'s `maxTotalSize`.\n\nAttribute: `max-total-size`","type":"number","default":"0"},{"name":"multiple","description":"Accepts more than one file per drop, and enables recursive folder-drop traversal -- same\ncontract as `lr-file-input`'s `multiple`. Unlike `lr-file-input`, this defaults to `true`:\na region wrapper's typical use (dropping several files onto a chat surface) expects more than\none file, and there is no native single-file picker here to keep in sync.\n\nAttribute: `multiple`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-files","description":"Frozen `detail: { files, rejected, remainingFiles, remainingTotalSize }` with detached readonly sequences and rejected-file records, fired on drop. `remainingFiles`/`remainingTotalSize` report the allowance still left under `maxFiles`/ `maxTotalSize` after this drop (`null` while that limit is unset). Immutable `File` items retain identity. Typed as {@linkcode LyraDropZoneFilesEvent}, so `event.target`/`event.currentTarget` are `LyraDropZone` without a cast.","type":"LyraDropZoneFilesEvent"}]}},{"name":"lr-dropdown","description":"`<lr-dropdown>` — a trigger-owned action menu. The public host remains the Popover-style\ntrigger/positioning shell, but that shell is semantic-neutral: a contained `<lr-menu>` is the\nsole role/name owner and supplies roving focus, type-ahead, nested submenu intent, selection,\nand focus return for mapped dropdown items. A consumer-supplied `<lr-menu>` in the default slot\nbecomes that contained engine instead of being wrapped in a second menu, preserving its own\nheader/list/footer regions and naming precedence. The menu list scrolls within the popup's\nheight limit while the positioning shell lets nested submenus receive pointer input outside it.\nMotion resolves through\n`dropdown.show`/`dropdown.hide` in the public animation registry without changing the inherited\nPopover lifecycle. ArrowDown and ArrowUp open the menu and focus its first or last enabled item\nwhether the trigger is slotted or resolved through `for`.\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-dropdown-item>`/`<lr-menu-item>` rows, or one consumer-supplied `<lr-menu>`. |\n| `trigger` | The interactive element that toggles the dropdown. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `arrow` | The arrow element, rendered only when `arrow` is set. Its part name also carries the resolved side (`arrow-top`, `arrow-bottom`, `arrow-left`, `arrow-right`), so `::part(arrow arrow-top)` can style one side — state after `::part()` never matches. |\n| `base` | Web Awesome compatibility name on the positioned popup. |\n| `base__popup` | Shoelace compatibility name on the positioned popup. |\n| `body` | Mapped alias on the content wrapper. |\n| `content` | The content wrapper; also carries the `body` alias. |\n| `dialog` | Mapped alias on the positioned popup. |\n| `hover-bridge` | The invisible quad bridging the trigger and the popup, rendered only while a `hover` popover with `hover-bridge` set is open. |\n| `menu` | The contained menu engine. |\n| `panel` | Shoelace compatibility name on the positioned popup. |\n| `popup` | The positioned popup; also carries `dialog` and `popup__popup` aliases. |\n| `popup__arrow` | Exported mapped alias on the arrow. |\n| `popup__popup` | Exported popup alias on the positioned popup. |\n| `trigger` | The trigger wrapper. |\n\n---\n\n**CSS Custom Properties**\n\n- `--arrow-size` (default: `var(--lr-overlay-arrow-size,var(--lr-size-0-375rem))`) — Arrow half-width inherited from the popover surface.\n- `--hide-duration` (default: `var(--lr-transition-fast)`) — Closing transition duration.\n- `--lr-overlay-arrow-size` — Retained Lyra arrow-size fallback.\n- `--lr-overlay-border` (default: `var(--lr-color-border)`) — Shared floating-surface edge colour, inherited from the popover surface.\n- `--lr-overlay-max-inline-size` — Maximum inline size of the popup.\n- `--lr-overlay-radius` (default: `var(--lr-radius)`) — Shared floating-surface corner radius, inherited from the popover surface.\n- `--lr-overlay-shadow-anchored` (default: `var(--lr-shadow-m)`) — Elevation of an anchored, positioner-placed overlay, inherited from the popover surface.\n- `--lr-overlay-surface` (default: `var(--lr-color-surface-overlay)`) — Shared floating-surface fill, inherited from the popover surface.\n- `--lr-positioning-strategy` — Cascading `absolute`/`fixed` override for {@link positioningStrategy}/`hoist`, inherited from the popover surface. An explicit `positioning-strategy`/`hoist` on the instance always wins over it.\n- `--max-width` (default: `var(--lr-overlay-max-inline-size,var(--lr-size-20rem))`) — Maximum inline size inherited from the popover surface.\n- `--show-duration` (default: `var(--lr-transition-fast)`) — Opening transition duration.","attributes":[{"name":"aria-label","description":"Accessible name for the semantic popup. An authored host `aria-label` wins by presence,\nincluding an explicitly empty value, before this property or the localized role fallback.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"arrow","description":"Render an arrow that points at the anchor. Defaults on for the mapped surface.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"arrow-padding","description":"Keeps the arrow this far from the popup's corners, in pixels.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"arrow-placement","description":"Where the arrow sits along the popup's edge. `anchor` tracks the anchor's centre.\n\nType: `LyraArrowPlacement`  \nDefault: `'anchor'`","value":{"type":["'anchor'","'start'","'end'","'center'"]}},{"name":"disabled","description":"Prevents opening the popover -- pointer, keyboard, and programmatic `show()`/`open = true`\nare all refused while set. Becoming disabled also closes an already-open popover; initial\n`disabled` plus `open` markup/property state normalizes closed in either order. Mirrors\n`<lr-tooltip>`'s and `<lr-dropdown>`'s own `disabled`.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"distance","description":"Anchor-offset distance (px) passed to Floating UI's `offset()` middleware. Can legitimately\nbe negative (overlaps the popup with the trigger); NaN/non-finite falls back to the default.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"for","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"hide-delay","description":"Delay (ms) between the interaction ending and the popover closing again -- the grace period\nthat lets a pointer cross the gap to the popup. Normalized like showDelay.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"hoist","description":"Retained boolean alias of positioningStrategy: `hoist` is exactly\n`positioningStrategy === 'fixed'`, and writing either spelling updates the other so the two\nattributes can never disagree in the DOM. It is the established name here (and Shoelace's own\nspelling on `sl-dropdown`), so it keeps working indefinitely; prefer `positioning-strategy` in\nnew code, which reads the same on every anchored surface in the library.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"hover-bridge","description":"Renders an invisible `[part='hover-bridge']` quad spanning the `distance` gap between the\ntrigger and the popup while a `hover` popover is open, so a pointer travelling between them\nnever leaves both at once and the popover does not close underneath it. Off by default: it is\nonly meaningful for `trigger=\"hover\"`, and a page that keeps `distance` at `0` does not need\nit.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"open","description":"Whether the popover is open. Assigning it runs the full `lr-show`/`lr-hide` lifecycle.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"placement","description":"Type: `Placement`  \nDefault: `'bottom-start'`","value":{"type":["'top'","'top-start'","'top-end'","'right'","'right-start'","'right-end'","'bottom'","'bottom-start'","'bottom-end'","'left'","'left-start'","'left-end'"]}},{"name":"popup-role","description":"Dropdown semantics are invariant: the trigger announces a menu and the contained menu owns\nthat role/name. The inherited Popover write surface is narrowed to `menu`; any other runtime\nor authored value normalizes back to `menu` instead of changing the outer positioning shell.\n\nType: `LyraPopupRole`  \nDefault: `'menu'`","value":{"type":["'dialog'","'menu'","'none'"]}},{"name":"positioning-strategy","description":"CSS positioning scheme the popup is laid out with -- the one property `<lr-popover>`,\n`<lr-dropdown>` and `<lr-select>` all spell the same way. `fixed` normally positions against\nthe viewport, so it escapes most clipping ancestors; `absolute` positions against the popup's\ncontaining block and scrolls with it. Each component keeps its own mirrored default, so\nsetting nothing on the instance and on every ancestor never changes what it already rendered;\nan unsupported authored value resolves to that same default. Changes apply live while open.\nThis property reports only the instance's own authored value (or the mirrored default); the\npopup is actually placed with the `--lr-positioning-strategy` cascading custom property\nhonored ahead of that default when the instance itself sets nothing -- see that `@cssprop`.\n\nType: `PlaceStrategy`  \nDefault: `'fixed'`","value":{"type":["'absolute'","'fixed'"]}},{"name":"show-delay","description":"Delay (ms) between a `hover`/`focus` interaction and the popover opening. NaN, negative and\noversized values all normalize through `finiteDuration`.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"size","description":"Density propagated to directly owned mapped items.\n\nType: `LyraSize`  \nDefault: `'m'`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}},{"name":"skidding","description":"Offset along the anchor's edge, in pixels — Floating UI's cross-axis offset.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"stay-open-on-select","description":"Keeps the menu open after a selection unless the selected branch closes independently.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"sync","description":"Copies the trigger's width, height, or both onto the popup.\n\nType: `PlaceSync | undefined`  \nDefault: `undefined`","value":{"type":["'width'","'height'","'both'"]}},{"name":"trigger","description":"Space-separated list of the interactions that open the popover -- see\nLyraPopoverTrigger for the keywords, which are exactly `<lr-tooltip>`'s. Unrecognized\ntokens are dropped and a list left with none resolves back to `'click'`, so the property always\nreads back as a canonical list.\n\nType: `string`  \nDefault: `'click'`","value":{"type":["string"]}},{"name":"without-arrow","description":"Positive mapped spelling for suppressing the default arrow.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"","description":"`<lr-dropdown-item>`/`<lr-menu-item>` rows, or one consumer-supplied `<lr-menu>`."},{"name":"trigger","description":"The interactive element that toggles the dropdown."}],"js":{"properties":[{"name":"accessibleLabel","description":"Accessible name for the semantic popup. An authored host `aria-label` wins by presence,\nincluding an explicitly empty value, before this property or the localized role fallback.\n\nAttribute: `aria-label`","type":"string","default":"''"},{"name":"anchor","description":"Positioning-only element anchor. Takes precedence over `for` and the interaction owner, but\nnever receives click listeners or generated ARIA.","type":"Element | null","default":"null"},{"name":"arrow","description":"Dropdowns do not render a pointer unless a consumer explicitly enables it.\n\nAttribute: `arrow`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"arrowPadding","description":"Keeps the arrow this far from the popup's corners, in pixels.\n\nAttribute: `arrow-padding`","type":"number","default":"0"},{"name":"arrowPlacement","description":"Where the arrow sits along the popup's edge. `anchor` tracks the anchor's centre.\n\nAttribute: `arrow-placement`","type":"LyraArrowPlacement","default":"'anchor'"},{"name":"containingElement","description":"Optional element that counts as inside for light-dismiss handling. Property-only.","type":"HTMLElement | undefined"},{"name":"disabled","description":"Prevents opening the popover -- pointer, keyboard, and programmatic `show()`/`open = true`\nare all refused while set. Becoming disabled also closes an already-open popover; initial\n`disabled` plus `open` markup/property state normalizes closed in either order. Mirrors\n`<lr-tooltip>`'s and `<lr-dropdown>`'s own `disabled`.\n\nAttribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"distance","description":"Dropdowns sit flush against their trigger by default; generic popovers retain eight pixels.\n\nAttribute: `distance`","type":"number","default":"0"},{"name":"for","description":"Attribute: `for`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"hideDelay","description":"Delay (ms) between the interaction ending and the popover closing again -- the grace period\nthat lets a pointer cross the gap to the popup. Normalized like showDelay.\n\nAttribute: `hide-delay`","type":"number","default":"0"},{"name":"hoist","description":"Retained boolean alias of positioningStrategy: `hoist` is exactly\n`positioningStrategy === 'fixed'`, and writing either spelling updates the other so the two\nattributes can never disagree in the DOM. It is the established name here (and Shoelace's own\nspelling on `sl-dropdown`), so it keeps working indefinitely; prefer `positioning-strategy` in\nnew code, which reads the same on every anchored surface in the library.\n\nAttribute: `hoist`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"hoverBridge","description":"Renders an invisible `[part='hover-bridge']` quad spanning the `distance` gap between the\ntrigger and the popup while a `hover` popover is open, so a pointer travelling between them\nnever leaves both at once and the popover does not close underneath it. Off by default: it is\nonly meaningful for `trigger=\"hover\"`, and a page that keeps `distance` at `0` does not need\nit.\n\nAttribute: `hover-bridge`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"open","description":"Whether the popover is open. Assigning it runs the full `lr-show`/`lr-hide` lifecycle.\n\nAttribute: `open`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"placement","description":"Action menus retain their mapped below-trigger placement.\n\nAttribute: `placement`  \nReflected to its attribute.","type":"Placement","default":"'bottom-start'"},{"name":"popupRole","description":"Dropdown semantics are invariant: the trigger announces a menu and the contained menu owns\nthat role/name. The inherited Popover write surface is narrowed to `menu`; any other runtime\nor authored value normalizes back to `menu` instead of changing the outer positioning shell.\n\nAttribute: `popup-role`","type":"LyraPopupRole","default":"'menu'"},{"name":"positioningStrategy","description":"CSS positioning scheme the popup is laid out with -- the one property `<lr-popover>`,\n`<lr-dropdown>` and `<lr-select>` all spell the same way. `fixed` normally positions against\nthe viewport, so it escapes most clipping ancestors; `absolute` positions against the popup's\ncontaining block and scrolls with it. Each component keeps its own mirrored default, so\nsetting nothing on the instance and on every ancestor never changes what it already rendered;\nan unsupported authored value resolves to that same default. Changes apply live while open.\nThis property reports only the instance's own authored value (or the mirrored default); the\npopup is actually placed with the `--lr-positioning-strategy` cascading custom property\nhonored ahead of that default when the instance itself sets nothing -- see that `@cssprop`.\n\nAttribute: `positioning-strategy`  \nReflected to its attribute.","type":"PlaceStrategy","default":"'fixed'"},{"name":"showDelay","description":"Delay (ms) between a `hover`/`focus` interaction and the popover opening. NaN, negative and\noversized values all normalize through `finiteDuration`.\n\nAttribute: `show-delay`","type":"number","default":"0"},{"name":"size","description":"Density propagated to directly owned mapped items.\n\nAttribute: `size`  \nReflected to its attribute.","type":"LyraSize","default":"'m'"},{"name":"skidding","description":"Offset along the anchor's edge, in pixels — Floating UI's cross-axis offset.\n\nAttribute: `skidding`","type":"number","default":"0"},{"name":"stayOpenOnSelect","description":"Keeps the menu open after a selection unless the selected branch closes independently.\n\nAttribute: `stay-open-on-select`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"sync","description":"Copies the trigger's width, height, or both onto the popup.\n\nAttribute: `sync`  \nReflected to its attribute.","type":"PlaceSync | undefined","default":"undefined"},{"name":"trigger","description":"Space-separated list of the interactions that open the popover -- see\nLyraPopoverTrigger for the keywords, which are exactly `<lr-tooltip>`'s. Unrecognized\ntokens are dropped and a list left with none resolves back to `'click'`, so the property always\nreads back as a canonical list.\n\nAttribute: `trigger`","type":"string","default":"'click'"},{"name":"withoutArrow","description":"Positive mapped spelling for suppressing the default arrow.\n\nAttribute: `without-arrow`  \nReflected to its attribute.","type":"boolean","default":"false"}],"events":[{"name":"lr-after-hide","description":"The dropdown is closed and its transition has finished.","type":"CustomEvent<null>"},{"name":"lr-after-show","description":"The dropdown is open and its transition has finished.","type":"CustomEvent<null>"},{"name":"lr-hide","description":"The dropdown is about to close. Cancelable.","type":"CustomEvent<null>"},{"name":"lr-select","description":"A menu item was activated. `detail: { item }`. Cancelable; preventing the event keeps the dropdown and any selected submenu open.","type":"CustomEvent<MenuItemSelectDetail>"},{"name":"lr-show","description":"The dropdown is about to open. Cancelable.","type":"CustomEvent<null>"}]}},{"name":"lr-dropdown-item","description":"`<lr-dropdown-item>` — the Web Awesome-compatible name for a menu item.\nIt is intentionally a subclass of `<lr-menu-item>`, so it participates in\nthe same roving focus, checkbox, radio, selection, and menu event contracts — and\nin the same `size` ladder, including the `small`/`medium`/`large` spellings.\nIt also inherits `<lr-menu-item>`'s `href`/`target`/`rel`/`download` link-item support, mirroring\n`wa-dropdown-item`'s identical navigation surface — see that class's doc.\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 visual label content. Its flattened subtree is inert and hidden from assistive technology; its accessible text names the host menu item. |\n| `details` | Decorative WA-compatible secondary detail text. Its flattened subtree is inert and hidden from assistive technology. |\n| `icon` | Optional decorative leading icon. Its flattened subtree is inert and hidden from assistive technology. |\n| `prefix` | Shoelace-compatible decorative alias for leading content. Its flattened subtree is inert and hidden from assistive technology. |\n| `submenu` | A nested `<lr-menu>` or direct mapped dropdown items that open beside this row. |\n| `suffix` | Shoelace-compatible decorative trailing content. Its flattened subtree is inert and hidden from assistive technology. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The visual item row. |\n| `checked-icon` | Shoelace-compatible checkbox-glyph wrapper. |\n| `checkmark` | WA-compatible checkbox glyph. |\n| `details` | WA-compatible detail wrapper. |\n| `icon` | Leading icon wrapper. |\n| `label` | Label wrapper. |\n| `prefix` | Shoelace-compatible leading-content wrapper. |\n| `spinner` | Loading spinner. |\n| `spinner__base` | Shoelace-compatible spinner alias. |\n| `submenu` | Submenu panel/wrapper. |\n| `submenu-icon` | Submenu chevron wrapper. |\n| `suffix` | Shoelace-compatible trailing-content wrapper. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-menu-item-active-bg` (default: `color-mix(in oklab,var(--lr-menu-item-hover-bg,var(--lr-color-brand-quiet)),var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Background of an enabled row while pressed, matching `--lr-option-active-bg`'s equivalent hook. Left unset, the pressed fill keeps mixing from `--lr-menu-item-hover-bg` as before this hook existed.\n- `--lr-menu-item-checked-bg` (default: `transparent`) — Background of a checked (`type=\"checkbox\" checked` or `type=\"radio\" checked`) row.\n- `--lr-menu-item-checked-color` (default: `inherit`) — Foreground of a checked row.\n- `--lr-menu-item-checked-font-weight` (default: `inherit`) — Font weight of a checked row.\n- `--lr-menu-item-danger-active-bg` (default: `color-mix(in oklab, var(--lr-color-danger-quiet), var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Background of an enabled danger row while pressed. Checked-state hooks are also inline fallbacks, matching `<lr-option>`/`<lr-select>`/ `<lr-combobox>`/`<lr-tree-item>`'s equivalent row-chrome hooks; all three default to no visual change, so a `type=\"checkbox\"`/`type=\"radio\"` item's checked row paints identically to before these existed unless a consumer sets one.\n- `--lr-menu-item-danger-color` (default: `var(--lr-color-danger)`) — Foreground of a `variant=\"danger\"` row.\n- `--lr-menu-item-danger-hover-bg` (default: `var(--lr-color-danger-quiet)`) — Background of an enabled danger row while hovered.\n- `--lr-menu-item-gap` (default: `var(--lr-space-xs)`) — Gap between the visual parts of `[part=\"base\"]`, including its leading content, label, trailing details, and state glyphs. Declared as an inline `var()` fallback (never on `:host`), so an item or any ancestor can retune it without a `::part(base)` rule. It is constant across the shared size ladder.\n- `--lr-menu-item-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Background of an enabled row under the pointer. The pressed state mixes from this same value, so a retuned hover fill keeps its pressed step instead of snapping back to the brand default.\n- `--lr-menu-item-icon-color` (default: `inherit`) — Foreground of the leading icon wrapper. Unset it inherits the row's colour, including the danger variant's.\n- `--lr-menu-item-min-height` (default: `max(var(--lr-form-control-height),var(--lr-size-24px))`) — Minimum block size of the visual row. Unset it is the shared form-control ladder floored at the WCAG 2.2 SC 2.5.8 minimum, exactly as before this hook existed.\n- `--lr-menu-item-radius` (default: `var(--lr-form-control-radius)`) — Corner radius of the visual row and focusable host. Its fallback follows the active shared size tier. Declared as an inline `var()` fallback (never on `:host`), so an item or any ancestor can retune it without a `::part(base)` rule. Danger-state hooks are also inline fallbacks, so a menu can retheme only its dangerous rows without replacing the shared danger palette elsewhere.\n- `--lr-overlay-border` — Shared floating-surface edge colour, with the same deliberate exclusion as `--lr-overlay-surface` above.\n- `--lr-overlay-radius` — Shared floating-surface corner radius, with the same deliberate exclusion. The row's own corners come from `--lr-menu-item-radius`.\n- `--lr-overlay-surface` — Shared floating-surface fill. Advertised here because this tag shares a stylesheet directory with `lr-menu`, whose surface reads it; a dropdown item is a row inside that surface and paints no surface of its own, so setting it here changes nothing.\n- `--submenu-offset` (default: `-2px`) — Final signed distance between a submenu and its parent row. Negative values overlap the parent menu; positive values add separation. Mirrors under RTL.","attributes":[{"name":"checked","description":"Whether a `type=\"checkbox\"`/`type=\"radio\"` item is checked. Meaningless (ignored) for\n`type=\"normal\"`.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"disabled","description":"Disables selection and excludes this item from `<lr-menu>`'s roving-tabindex nav entirely.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"download","description":"Native anchor `download` attribute, used only while `href` resolves to a link. Narrows the\nsafe-URL allowlist to `safeDownloadHref`'s, which drops `mailto:` — a mail handoff names no\nretrievable bytes, so it cannot be a download target.\n\nType: `string | undefined`"},{"name":"group","description":"Narrows a `type=\"radio\"` item's exclusive-choice scope to only the other radio items sharing\nthis same string. Unset (the default), the scope is every `type=\"radio\"` item the same\nowning `<lr-menu>` owns directly — a nested submenu's radio items already belong to that\nsubmenu's own `<lr-menu>` instead, so they're never in scope regardless of `group`. Meaningless\n(ignored) for `type=\"normal\"`/`\"checkbox\"`.\n\nType: `string | undefined`"},{"name":"href","description":"When set to a safe link URL (`http:`/`https:`/`blob:`/`mailto:`/relative — see\n`safeLinkHref`, or `safeDownloadHref` which drops `mailto:` when `download` is set),\n`[part=\"base\"]` renders as a real `<a href=…>` instead of a `<span>`, and activation (click,\nor the parent's Enter/Space handling, which forwards through `click()` for a link item so the\nanchor's own native default action runs) navigates there in addition to firing the usual\n`select()`/`lr-select` contract. An unsafe/unparseable `href` falls back to the plain `<span>`,\nmatching `lr-button`'s identical fallback. Mirrors `wa-dropdown-item`'s link-item support.\n\nType: `string | undefined`"},{"name":"loading","description":"Shows progress and makes the row interaction-disabled while an action is pending.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"rel","description":"Independently settable author relationship tokens for the rendered link (no default).\n`opener` is always stripped, and any `target` force-adds the non-removable\n`noopener noreferrer` guard — see `target`.\n\nType: `string | undefined`"},{"name":"size","description":"Row density, on the library's shared six-step ladder — `'m'` by default. Scales the row's\nheight, inline/block padding, font size and corner radius together; `'small'`/`'medium'`/\n`'large'` are accepted as synonyms of `'s'`/`'m'`/`'l'`. Every tier still resolves to at\nleast the 24px pointer-target floor, so even `'2xs'` stays tappable. Each item carries its\nown size rather than inheriting one from `<lr-menu>`, so a single compact row inside an\notherwise default menu needs no wrapper.\n\nType: `LyraSize`  \nDefault: `'m'`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}},{"name":"submenu-open","description":"Whether the submenu is currently open. Assigning it, or changing the reflected\n`submenu-open` attribute, drives the same panel as `openSubmenu()` / `closeSubmenu()` without\nmoving focus. The normalized upstream `submenuopen` attribute is a permanent, bidirectionally\nsynchronized compatibility alias: changing either spelling controls the state, while every\ninternal dismissal clears both so a stale alias cannot reopen the panel. Like those methods, an\nauthored open request waits until submenu content is connected.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"submenuopen","description":"Normalized Web Awesome compatibility alias for `submenu-open`; both spellings reflect the live submenu state and changing either spelling controls it.\n\nType: `boolean`","value":{"type":["boolean"]}},{"name":"target","description":"Native anchor `target`, used only while `href` resolves to a link. Setting this to `'_blank'`\n(or any other target) always contributes `noopener noreferrer` to the rendered anchor's `rel`\n— matching `lr-button`'s identical pattern.\n\nType: `string | undefined`"},{"name":"type","description":"`'checkbox'` renders `role=\"menuitemcheckbox\"` with a toggleable `checked` state and a\ncheckmark glyph, mirroring `wa-dropdown-item`'s identical `type` option. `'radio'` renders\n`role=\"menuitemradio\"` with exclusive-choice group semantics — see the class doc for both.\n\nType: `MenuItemType`  \nDefault: `'normal'`","value":{"type":["'normal'","'checkbox'","'radio'"]}},{"name":"value","description":"An id/value available on the item carried by the parent `<lr-menu>`'s `lr-select` detail.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"variant","description":"Semantic treatment. `default` is the WA spelling of a normal action and `danger` is its\nmapped dangerous-action treatment.\n\nType: `MenuItemVariant`  \nDefault: `'default'`","value":{"type":["'default'","'danger'"]}}],"slots":[{"name":"","description":"The item's visual label content. Its flattened subtree is inert and hidden from assistive technology; its accessible text names the host menu item."},{"name":"details","description":"Decorative WA-compatible secondary detail text. Its flattened subtree is inert and hidden from assistive technology."},{"name":"icon","description":"Optional decorative leading icon. Its flattened subtree is inert and hidden from assistive technology."},{"name":"prefix","description":"Shoelace-compatible decorative alias for leading content. Its flattened subtree is inert and hidden from assistive technology."},{"name":"submenu","description":"A nested `<lr-menu>` or direct mapped dropdown items that open beside this row."},{"name":"suffix","description":"Shoelace-compatible decorative trailing content. Its flattened subtree is inert and hidden from assistive technology."}],"js":{"properties":[{"name":"checked","description":"Whether a `type=\"checkbox\"`/`type=\"radio\"` item is checked. Meaningless (ignored) for\n`type=\"normal\"`.\n\nAttribute: `checked`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"disabled","description":"Disables selection and excludes this item from `<lr-menu>`'s roving-tabindex nav entirely.\n\nAttribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"download","description":"Native anchor `download` attribute, used only while `href` resolves to a link. Narrows the\nsafe-URL allowlist to `safeDownloadHref`'s, which drops `mailto:` — a mail handoff names no\nretrievable bytes, so it cannot be a download target.\n\nAttribute: `download`","type":"string | undefined"},{"name":"group","description":"Narrows a `type=\"radio\"` item's exclusive-choice scope to only the other radio items sharing\nthis same string. Unset (the default), the scope is every `type=\"radio\"` item the same\nowning `<lr-menu>` owns directly — a nested submenu's radio items already belong to that\nsubmenu's own `<lr-menu>` instead, so they're never in scope regardless of `group`. Meaningless\n(ignored) for `type=\"normal\"`/`\"checkbox\"`.\n\nAttribute: `group`","type":"string | undefined"},{"name":"hasSubmenu","description":"Whether a nested `<lr-menu>` or direct mapped items are assigned to this item's `submenu`\nslot, making it a submenu parent.","type":"boolean","read-only":true},{"name":"href","description":"When set to a safe link URL (`http:`/`https:`/`blob:`/`mailto:`/relative — see\n`safeLinkHref`, or `safeDownloadHref` which drops `mailto:` when `download` is set),\n`[part=\"base\"]` renders as a real `<a href=…>` instead of a `<span>`, and activation (click,\nor the parent's Enter/Space handling, which forwards through `click()` for a link item so the\nanchor's own native default action runs) navigates there in addition to firing the usual\n`select()`/`lr-select` contract. An unsafe/unparseable `href` falls back to the plain `<span>`,\nmatching `lr-button`'s identical fallback. Mirrors `wa-dropdown-item`'s link-item support.\n\nAttribute: `href`  \nReflected to its attribute.","type":"string | undefined"},{"name":"loading","description":"Shows progress and makes the row interaction-disabled while an action is pending.\n\nAttribute: `loading`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"rel","description":"Independently settable author relationship tokens for the rendered link (no default).\n`opener` is always stripped, and any `target` force-adds the non-removable\n`noopener noreferrer` guard — see `target`.\n\nAttribute: `rel`","type":"string | undefined"},{"name":"size","description":"Row density, on the library's shared six-step ladder — `'m'` by default. Scales the row's\nheight, inline/block padding, font size and corner radius together; `'small'`/`'medium'`/\n`'large'` are accepted as synonyms of `'s'`/`'m'`/`'l'`. Every tier still resolves to at\nleast the 24px pointer-target floor, so even `'2xs'` stays tappable. Each item carries its\nown size rather than inheriting one from `<lr-menu>`, so a single compact row inside an\notherwise default menu needs no wrapper.\n\nAttribute: `size`  \nReflected to its attribute.","type":"LyraSize","default":"'m'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"submenuOpen","description":"Whether the submenu is currently open. Assigning it, or changing the reflected\n`submenu-open` attribute, drives the same panel as `openSubmenu()` / `closeSubmenu()` without\nmoving focus. The normalized upstream `submenuopen` attribute is a permanent, bidirectionally\nsynchronized compatibility alias: changing either spelling controls the state, while every\ninternal dismissal clears both so a stale alias cannot reopen the panel. Like those methods, an\nauthored open request waits until submenu content is connected.\n\nAttribute: `submenu-open`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"target","description":"Native anchor `target`, used only while `href` resolves to a link. Setting this to `'_blank'`\n(or any other target) always contributes `noopener noreferrer` to the rendered anchor's `rel`\n— matching `lr-button`'s identical pattern.\n\nAttribute: `target`","type":"string | undefined"},{"name":"type","description":"`'checkbox'` renders `role=\"menuitemcheckbox\"` with a toggleable `checked` state and a\ncheckmark glyph, mirroring `wa-dropdown-item`'s identical `type` option. `'radio'` renders\n`role=\"menuitemradio\"` with exclusive-choice group semantics — see the class doc for both.\n\nAttribute: `type`  \nReflected to its attribute.","type":"MenuItemType","default":"'normal'"},{"name":"value","description":"An id/value available on the item carried by the parent `<lr-menu>`'s `lr-select` detail.\n\nAttribute: `value`","type":"string","default":"''"},{"name":"variant","description":"Semantic treatment. `default` is the WA spelling of a normal action and `danger` is its\nmapped dangerous-action treatment.\n\nAttribute: `variant`  \nReflected to its attribute.","type":"MenuItemVariant","default":"'default'"}],"events":[{"name":"blur","description":"Native, non-bubbling, composed, non-cancelable `FocusEvent` emitted by the focusable host when it loses focus.","type":"FocusEvent"},{"name":"focus","description":"Native, non-bubbling, composed, non-cancelable `FocusEvent` emitted by the focusable host when it gains focus.","type":"FocusEvent"},{"name":"lr-menu-item-change","description":"A `type=\"checkbox\"` item was activated, or a `type=\"radio\"` item was activated while unchecked (an already-checked radio never fires this). `detail: { value, checked }` contains the item's own `value` and the proposed next `checked` value, before the property mutates. Cancelable: prevent it to retain the current `checked` value. The usual the parent menu's `lr-select` still follows, so selection and close behavior are unchanged. Never fired for `type=\"normal\"`. Unchecking a radio's group siblings once this event commits fires no event of its own.","type":"CustomEvent<MenuItemChangeDetail>"},{"name":"lr-menu-item-state-change","description":"Something that decides whether this item is navigable changed: `disabled`, `loading`, `hidden`, `inert`, or `aria-hidden`. `detail: { disabled, hidden, inert }`, where `disabled` is the effective `disabled || loading`. `<lr-menu>` consumes this to repair its roving-tabindex state immediately. The last three are plain native attributes rather than reactive properties, so they are watched with the item's own `MutationObserver`; `aria-hidden` fires the event without appearing in the detail, which carries only the item's own state flags.","type":"CustomEvent<MenuItemStateChangeDetail>"}]}},{"name":"lr-ebook-viewer","description":"Renders an EPUB with the optional `epubjs` peer. The mount element is kept\nstable because epub.js imperatively owns it and renders chapters in iframes.\n\nAdopts `DocumentAnchorTarget`: a `cfi` anchor displays directly via epub.js's own\n`rendition.display()`; a `text-quote` anchor resolves by scanning the book's spine sections\nwith epub.js's own `item.find()`, since chapter content lives inside epub.js-owned iframes\nrather than this component's own shadow DOM (a native `Range`/`Selection` inside one of those\niframes is invisible to this component's own document, so selection handling below is bridged\nthrough epub.js's own `selected` event instead of the mixin's default DOM-selection binding).\n`highlights` (kind `cfi`) paint via `rendition.annotations.highlight()`, resolving each `tone`\nto a concrete `fill` color (its `styles` 5th arg) so highlights actually differentiate by tone,\nand are re-applied whenever the rendition is recreated (a `src` change, or a reconnect remount)\n-- epub.js doesn't persist annotations across a fresh `renderTo()`. `getToc()` reads the EPUB's\nown navigation document into a flat, document-ordered outline once `book.ready` resolves.\n`location` (a CFI or\nspine href) is recorded before the book is ready and applied once loading finishes, or applied\nimmediately once it already has; epub.js's own `relocated` event keeps it in sync with user\nnavigation without re-triggering a `display()` call for a change that originated from that same\nevent. `search()`/`searchNext()`/`searchPrevious()`/`clearSearch()` scan the spine sequentially\nvia epub.js's own `item.find()`, aborting a superseded scan when a newer search or a `src`\nchange supersedes it.\n\nGenuine native selections from a chapter iframe use platform Selection accessors; arbitrary\npeer accessors remain uninvoked. Selected text and rectangles retain the shared bounded limits.\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| `anchor-live-region` | The aria-hidden, non-live shadow mirror of the latest anchor-jump message. |\n| `base` | The viewer container. |\n| `error` | Visible ordinary error text; transitions announce through the shared document-level assertive region. Search announcements are appended to the shared document-level polite region, which lives in the host's light DOM and has no part here. |\n| `mount` | The stable element epub.js renders into. |\n| `next-button` | The next chapter button. |\n| `next-icon` | The next button icon. |\n| `previous-button` | The previous chapter button. |\n| `previous-icon` | The previous button icon. |\n| `toolbar` | Previous and next chapter controls. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-ebook-viewer-max-height` (default: `none`) — Maximum block size of the mount area epub.js renders into, before it scrolls internally. Also settable via the `max-height` property.","attributes":[{"name":"active-highlight-id","description":"Id of the currently active highlight, or null when none is active.\n\nType: `string | null`  \nDefault: `null`"},{"name":"aria-label","description":"Host-level `aria-label` override for the internal reading region -- wins by attribute\npresence, including an explicitly empty value, over `name` and the localized fallback. Set as\na plain `aria-label` attribute on `<lr-ebook-viewer>` itself, not a public JS property: the\ndeclaration exists only so Lit observes the attribute (the same private attribute-observer\n`<lr-dialog>`, `<lr-page>`, `<lr-app-rail>` and `<lr-tour>` use).\n\nType: `string | null`  \nDefault: `null`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"location","description":"A CFI or spine href identifying the current reading position. Set before the book has\nfinished loading, it's recorded and applied via `rendition.display()` once loading\nfinishes; set after, it applies immediately. Kept in sync with epub.js's own `relocated`\nevent (fired on any user navigation) without re-triggering a `display()` call for a change\nthat originated from that same event. Not reflected as an attribute -- CFIs are long.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max-height","description":"A CSS `max-height` that caps the mount area epub.js renders into; invalid values are\nignored.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"name","description":"Display name used as the reading region's accessible-name fallback.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"src","description":"URL fetched as an ArrayBuffer and rendered as an EPUB.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"js":{"properties":[{"name":"activeHighlightId","description":"Id of the currently active highlight, or null when none is active.\n\nAttribute: `active-highlight-id`","type":"string | null","default":"null"},{"name":"anchor","description":"Anchor or highlight id to resolve and scroll into view.","type":"LyraAnchor | string | null","default":"null"},{"name":"anchorKinds","description":"Anchor kinds this viewer resolves: `cfi` displays directly via `rendition.display()`;\n`text-quote` resolves by scanning the book's spine with epub.js's own `item.find()`.","type":"['cfi', 'text-quote']","default":"['cfi', 'text-quote']","read-only":true},{"name":"highlights","description":"Highlights rendered by the document target. Reassign after mutation.","type":"LyraHighlight[]","default":"[]"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"location","description":"A CFI or spine href identifying the current reading position. Set before the book has\nfinished loading, it's recorded and applied via `rendition.display()` once loading\nfinishes; set after, it applies immediately. Kept in sync with epub.js's own `relocated`\nevent (fired on any user navigation) without re-triggering a `display()` call for a change\nthat originated from that same event. Not reflected as an attribute -- CFIs are long.\n\nAttribute: `location`","type":"string","default":"''"},{"name":"maxHeight","description":"A CSS `max-height` that caps the mount area epub.js renders into; invalid values are\nignored.\n\nAttribute: `max-height`","type":"string","default":"''"},{"name":"name","description":"Display name used as the reading region's accessible-name fallback.\n\nAttribute: `name`","type":"string","default":"''"},{"name":"src","description":"URL fetched as an ArrayBuffer and rendered as an EPUB.\n\nAttribute: `src`","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-anchor-result","description":"Fired after an `anchor` property assignment or a `scrollToAnchor()` call is applied. `detail: { found }`.","type":"CustomEvent<AnchorResultDetail>"},{"name":"lr-highlight-activate","description":"A painted `cfi` highlight was clicked. `detail: { highlightId }`.","type":"CustomEvent<HighlightActivateDetail>"},{"name":"lr-location-change","description":"The reading location changed (from `rendition`'s own `relocated` event). `detail: { cfi, href }`.","type":"CustomEvent<{ cfi: string; href: string }>"},{"name":"lr-render-error","description":"Fired when fetching, opening, or rendering fails.","type":"CustomEvent<{ error: unknown }>"},{"name":"lr-search-change","description":"Fired whenever the search query, match count, or active match index changes, including source-reset and effective-locale re-evaluation. `detail: { query, matchCount, matchCountExact, activeIndex }`. Search accepts at most 4,096 query code units, inspects at most 1,000 spine items and 4,000,000 result code units, and retains at most 10,000 matches; a false `matchCountExact` makes `matchCount` a lower bound (including when a spine item cannot load or any ceiling is reached).","type":"CustomEvent<LyraSearchChangeDetail>"},{"name":"lr-text-select","description":"Fired on selection end inside a chapter iframe (mirrors epub.js's own `selected` event). `detail: { text, anchor, rects }`; `text` is capped at 4,096 code units, `rects` at 1,000, and `anchor` is a `cfi` `LyraAnchor`.","type":"CustomEvent<TextSelectDetail>"}]}},{"name":"lr-email-viewer","description":"Parses `.eml` messages with the optional `postal-mime` peer and renders\ntheir HTML body only after DOMPurify sanitization and inside a paint-contained surface.\nSanitized HTML uses the passive-document profile: anchors, form controls, and custom elements\nare unwrapped to ordinary text/children where safe, remote navigation/resource attributes are\nremoved, and an `<a>` itself never remains. Images render only inline base64 GIF, JPEG, PNG, or\nWebP data; same-document SVG fragment references may remain.\nPlain-text messages remain useful without DOMPurify. Attachment rows are real buttons that emit\n`lr-attachment-open` with an immutable Blob snapshot of the decoded bytes -- this component\nnever opens, downloads, or object-URLs the content; a host routes the Blob into e.g.\n`URL.createObjectURL(content)` -> `lr-document-viewer` ->\nrevoke on `lr-close`. `fold-quotes` collapses trailing quoted-reply text/HTML behind a\nlocalized toggle. A missing attachment filename uses the localized\n`emailViewerUnnamedAttachment` fallback in both visible and accessible names, resolved while\nrendering so a later locale or `strings` change updates an already-parsed message.\nA nonempty host `aria-label` makes the host the sole named semantic owner; otherwise the shadow\nregion owns the explicit-empty, `name`, or localized fallback label.\nFragment anchors perform an exact DOM `id` lookup. Lyra generates no fragment ids for message\nheaders or plain-text bodies; an HTML message can resolve only an id retained from its sanitized\nbody. Text-quote anchors remain available across all rendered message text.\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| `anchor-live-region` | The aria-hidden, non-live shadow mirror of the latest anchor-jump message. |\n| `attachment-button` | An attachment's open button. |\n| `attachment-item` | An attachment metadata item. |\n| `attachment-list` | The attachment list. |\n| `attachment-name` | An attachment's filename, inside `attachment-button`. |\n| `attachment-size` | An attachment's formatted file size, inside `attachment-button`. |\n| `attachments` | The attachment region. |\n| `attachments-label` | The localized attachment heading. |\n| `base` | The root container with explicit `aria-busy` loading state. |\n| `body` | The scrollable message body. |\n| `body-html` | The sanitized HTML body. |\n| `body-text` | The plain-text body. |\n| `date` | The message date. |\n| `date-label` | The localized date label. |\n| `error` | The error region. |\n| `from` | The sender address. |\n| `from-label` | The localized sender label. |\n| `headers` | Message metadata. |\n| `quote-toggle` | The show/hide-quoted-text toggle button. |\n| `quoted` | A folded quoted-text block (hidden until expanded). |\n| `spinner` | The visible tokenized loading treatment and ordinary text label. |\n| `subject` | The message subject. |\n| `subject-label` | The localized subject label. |\n| `to` | The recipient addresses. |\n| `to-label` | The localized recipient label. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-email-viewer-max-height` (default: `none`) — Maximum block size of `[part=\"body\"]` before it scrolls internally. The `maxHeight` property sets this token inline on `[part=\"base\"]`.","attributes":[{"name":"active-highlight-id","description":"Id of the currently active highlight, or null when none is active.\n\nType: `string | null`  \nDefault: `null`"},{"name":"fold-quotes","description":"Collapses trailing quoted-reply text/HTML behind a localized toggle. `false` (the default)\npreserves today's exact body rendering.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max-height","description":"A CSS `max-height`; invalid values are ignored.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"name","description":"Display name associated with the message. Used as the accessible name\nof `[part='base']` when the host has no `aria-label`, and before the\nlocalized `emailViewerLabel` default, matching the `csvViewerLabel`-\nstyle sibling document viewers. Host `aria-label` wins by attribute\npresence, including an empty value.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"src","description":"URL to fetch and parse as an RFC 822 message.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"js":{"properties":[{"name":"activeHighlightId","description":"Id of the currently active highlight, or null when none is active.\n\nAttribute: `active-highlight-id`","type":"string | null","default":"null"},{"name":"anchor","description":"Anchor or highlight id to resolve and scroll into view.","type":"LyraAnchor | string | null","default":"null"},{"name":"anchorKinds","description":"Anchor kinds supported by this viewer instance.","type":"readonly LyraAnchorKind[]","default":"[]","read-only":true},{"name":"foldQuotes","description":"Collapses trailing quoted-reply text/HTML behind a localized toggle. `false` (the default)\npreserves today's exact body rendering.\n\nAttribute: `fold-quotes`","type":"boolean","default":"false"},{"name":"highlights","description":"Highlights rendered by the document target. Reassign after mutation.","type":"LyraHighlight[]","default":"[]"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"maxHeight","description":"A CSS `max-height`; invalid values are ignored.\n\nAttribute: `max-height`","type":"string","default":"''"},{"name":"name","description":"Display name associated with the message. Used as the accessible name\nof `[part='base']` when the host has no `aria-label`, and before the\nlocalized `emailViewerLabel` default, matching the `csvViewerLabel`-\nstyle sibling document viewers. Host `aria-label` wins by attribute\npresence, including an empty value.\n\nAttribute: `name`","type":"string","default":"''"},{"name":"src","description":"URL to fetch and parse as an RFC 822 message.\n\nAttribute: `src`","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-anchor-result","description":"Fired after an `anchor` assignment or `scrollToAnchor()` call is applied. `detail: { found: boolean }`. Bubbling, composed, and non-cancelable.","type":"CustomEvent<AnchorResultDetail>"},{"name":"lr-attachment-open","description":"An attachment button was activated. Recursively frozen `detail: { attachment: { filename, mimeType, content?: Blob } }`; read bytes with `arrayBuffer()`.","type":"CustomEvent<LyraEventDetailSnapshot<LyraEmailAttachmentOpenDetail>>"},{"name":"lr-render-error","description":"Fired when fetching or parsing the message fails.","type":"CustomEvent<{ error: unknown }>"},{"name":"lr-search-change","description":"Fired whenever search state changes. `matchCountExact=false` makes the retained count a lower bound. Bubbling, composed, and non-cancelable.","type":"CustomEvent<LyraSearchChangeDetail>"},{"name":"lr-text-select","description":"Fired after a selection ends inside the rendered message. `detail: { text: string; anchor: LyraAnchor | null; rects: DOMRect[] }`. Bubbling, composed, and non-cancelable.","type":"CustomEvent<TextSelectDetail>"}]}},{"name":"lr-embedding-explorer","description":"`<lr-embedding-explorer>` — a dependency-free, accessible 2D embedding projection viewer. It\nnormalizes host-provided coordinates into an SVG plot, colors optional clusters, and exposes\nclick/keyboard selection. Pointer, script, and assistive-technology focus all synchronize the\nsingle roving tab stop. It does not run PCA/UMAP/t-SNE, fetch chunks, or mutate points.\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.\nPoints with non-finite coordinates or blank ids and later valid duplicates are ignored before\nfocus, selection, rendering, or activation. The first valid point for an id wins.\nOptional cluster membership is exposed both through the plot options' descriptions and a\nvisible text legend, so cluster meaning never depends on color alone.\n\n---\n\n**Component metadata**\n\n- Status: `stable`\n- Since: `6.2.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 root wrapper. |\n| `empty` | The empty state. |\n| `legend` | The visible cluster-name list. |\n| `legend-item` | One cluster's legend entry. |\n| `legend-label` | One cluster's visible name. |\n| `legend-swatch` | One cluster's decorative color swatch. |\n| `plot` | The SVG projection plot. |\n| `point` | One focusable embedding point. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-color-chart-1` (default: `var(--lr-theme-color-chart-1,#0e006e)`) — First cluster color.\n- `--lr-color-chart-2` (default: `var(--lr-theme-color-chart-2,#4d011a)`) — Second cluster color.\n- `--lr-color-chart-3` (default: `var(--lr-theme-color-chart-3,#862002)`) — Third cluster color.\n- `--lr-color-chart-4` (default: `var(--lr-theme-color-chart-4,#503983)`) — Fourth cluster color.\n- `--lr-color-chart-5` (default: `var(--lr-theme-color-chart-5,#315fdd)`) — Fifth cluster color.\n- `--lr-color-chart-6` (default: `var(--lr-theme-color-chart-6,#935e7c)`) — Sixth cluster color.\n- `--lr-color-chart-7` (default: `var(--lr-theme-color-chart-7,#de6906)`) — Seventh cluster color.\n- `--lr-color-chart-8` (default: `var(--lr-theme-color-chart-8,#8f81d3)`) — Eighth cluster color; later clusters wrap through the same ordered palette.\n- `--lr-embedding-explorer-height` (default: `360px`) — The plot's `block-size`. Set on the host from the `height` property, whose default supplies the `360px`; a value the browser cannot parse as a `block-size` is dropped, leaving the `viewBox`-derived aspect-ratio size. A consumer's own `::part(plot) { block-size: ... }` rule still overrides it, and the narrow-allocation `min-block-size` floor still raises it.\n- `--lr-embedding-explorer-selected-stroke` (default: `var(--lr-color-brand)`) — Stroke color of the selected point.","attributes":[{"name":"aria-label","description":"JS-only accessible name for the plot while no host `aria-label` is authored. An authored host\nlabel governs the plot's name too (including an explicitly empty value), avoiding a competing\ngeneric plot label while still naming the shadow-internal `listbox` itself.\n\nType: `string | null`  \nDefault: `null`"},{"name":"height","description":"The plot's block size, as any CSS length the browser accepts for `block-size` — including\n`auto`, which restores the aspect-ratio-preserved size derived from the `viewBox`. It is\napplied through `--lr-embedding-explorer-height`; an unparseable value leaves that property\nunset, so the plot falls back to `auto` rather than collapsing.\n\nType: `string`  \nDefault: `'360px'`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"selected-point-id","description":"The selected point id. Controlled by the host.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"js":{"properties":[{"name":"accessibleLabel","description":"JS-only accessible name for the plot while no host `aria-label` is authored. An authored host\nlabel governs the plot's name too (including an explicitly empty value), avoiding a competing\ngeneric plot label while still naming the shadow-internal `listbox` itself.\n\nAttribute: `aria-label`","type":"string | null","default":"null"},{"name":"height","description":"The plot's block size, as any CSS length the browser accepts for `block-size` — including\n`auto`, which restores the aspect-ratio-preserved size derived from the `viewBox`. It is\napplied through `--lr-embedding-explorer-height`; an unparseable value leaves that property\nunset, so the plot falls back to `auto` rather than collapsing.\n\nAttribute: `height`","type":"string","default":"'360px'"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"points","description":"Projected points in host order. Non-finite coordinates are omitted.","type":"readonly EmbeddingPoint[]","default":"[]"},{"name":"selectedPointId","description":"The selected point id. Controlled by the host.\n\nAttribute: `selected-point-id`","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-point-select","description":"A point was activated. `detail: { point }`.","type":"CustomEvent<{ point: EmbeddingPoint }>"}]}},{"name":"lr-emoji-picker","description":"`<lr-emoji-picker>` — a searchable, keyboard-navigable, form-associated emoji picker. In the\nsame \"zero/optional-peer dependency\" spirit as `<lr-lite-chart>`/`<lr-heatmap>`: `groups` is\nfully consumer-suppliable (this component ships no emoji data of its own), with an *optional*\nconvenience auto-loader for a default set — see `emoji-data-loader.ts` and the class doc there for\nexactly what that covers.\n\nThe auto-loader fails *closed and visibly*: when the optional `emoji-picker-element-data` peer\ncannot be loaded, the grid renders a distinct localized `[part=\"load-error\"]` surface in place of\nthe ordinary `[part=\"empty\"]` message, so a skipped install is distinguishable at a glance from a\ngenuine zero-match search or a deliberate `groups = []` opt-out, and announces the same message\nonce through the document's shared assertive live region. Assigning `groups` afterwards clears\nit.\n\nKeyboard model: the grid is a roving-tabindex listbox (a single Tab stop — only the active emoji\nis tabbable). Arrow keys move the active option (Left/Right follow reading direction and swap\nunder RTL; Up/Down move by one visual row, measured from the live wrap layout), Home/End jump to\nthe first/last option, and Enter/Space picks. The search input doubles as a `role=\"combobox\"`\nover the same listbox: the arrow keys and Enter also work there while focus stays in the input,\nwith `aria-activedescendant` tracking the active option. Composing keyboard events remain with\ntext editing and do not navigate or pick an emoji. Large data sets automatically window\ntheir visible rows so scrolling does not create one button per supplied emoji in the DOM.\nReplacing `groups` while an emoji option owns focus preserves that item when its object remains\npresent, otherwise focus moves to the nearest surviving option; search or external focus is\nnever pulled into the grid by a controlled collection update. Roving navigation to an\noff-window option materializes its virtual row before transferring focus. Each explicit groups\nassignment snapshots current item content, including reused source objects; earlier snapshots\nremain frozen. Built-in headings follow live localization through filtering and windowed rows,\nwhile caller-authored headings remain literal.\n\nShips the same opt-in `label`/`hint`/`errorText` form-control chrome as `<lr-select>`/\n`<lr-color-picker>` (props + matching named slots + `form-control`/`form-control-label`/`hint`/\n`error` parts) — left unset, the chrome stays hidden. When `label` (or the `label` slot) is set\nand `aria-label`/`accessibleLabel` is not, the grid's accessible name switches from the\nlocalized default to `aria-labelledby` pointing at the visible label, mirroring\n`<lr-checkbox-group>`'s identical `accessibleLabel`-wins-over-`aria-labelledby` precedence.\nRemoving a chrome text attribute hides its empty chrome without changing property readback.\nHost `aria-describedby` references describe the value-owning listbox before local error/hint\nguidance; search retains its separate description ownership. Form reset clears interaction\nstate and restores the default value while required and custom validity constraints remain.\n\n`disabled` (from the `FormAssociated` mixin) gates every self-rendered interactive\nsub-control — the search input and every emoji button — not just one of them.\n\nComponent-scoped theme inputs remain undeclared on the host, so values inherited from an\nancestor theme wrapper override the active size tier. A value set directly on the picker still\nwins through normal custom-property inheritance.\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| `error` | Custom error content. |\n| `hint` | Custom hint content. |\n| `label` | Custom label content. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The wrapper around the search input and grid. |\n| `emoji` | Each emoji's own `<button>`; its box and glyph both scale with the `size` property (`--lr-emoji-picker-item-size`/`-glyph-size`), while its interactive box remains floored at the shared `--lr-icon-button-size`. |\n| `empty` | The empty-state message, shown when the search matches nothing or a consumer deliberately opted out with `groups = []`. |\n| `error` | The error message. |\n| `form-control` | The outer wrapper around label, base, error and hint. |\n| `form-control-label` | The visible label. |\n| `grid` | The keyboard-navigable emoji grid. It scrolls only in the block axis and clips inline overflow, avoiding a second scrollbar when the allocation is narrower than one option. |\n| `group-label` | Each group's heading, rendered above its emojis. |\n| `hint` | The hint message. |\n| `load-error` | The peer-load failure surface, shown in place of `empty` when the optional `emoji-picker-element-data` peer was consulted and did not resolve. It never appears for a zero-match search or a deliberate `groups = []`, and a later `groups` assignment clears it. The same message is announced once through the shared light-DOM assertive sink rather than through a shadow-root `role=\"alert\"`, which announces unreliably. |\n| `search` | The search/filter `<input>` (`role=\"combobox\"` over the grid). |\n| `search-clear` | The button that clears the search field, replacing the native search-cancel glyph suppressed by this field's own reset; rendered only while it has a value. |\n| `search-wrapper` | The row wrapper around `search` and `search-clear`. |\n| `virtual-items` | The flex row holding one windowed row's emoji buttons. |\n| `virtual-label` | The `aria-hidden` placeholder that reserves a row's group-label band when that row has no label, keeping every row the same height. Rendered on the windowed path only. |\n| `virtual-row` | One windowed row, absolutely positioned at the `--lr-emoji-picker-row-height` pitch. Rendered on the windowed path only. |\n| `virtual-spacer` | The full-height scroll spacer that gives the grid its scrollbar while only the visible rows exist in the DOM. Rendered on the windowed path only. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-emoji-picker-item-size` (default: `var(--lr-icon-button-size)`) — Each emoji button's box. Floored at the shared `--lr-icon-button-size`; small size tiers scale the glyph without shrinking the interactive target.\n- `--lr-emoji-picker-glyph-size` (default: `var(--lr-font-size-lg)`) — Font size of the emoji glyph, scaled by the `size` property to keep the glyph proportional to the item box.\n- `--lr-emoji-picker-gap` (default: `var(--lr-space-2xs)`) — Gap between emoji within a windowed row.\n- `--lr-emoji-picker-control-gap` (default: `var(--lr-space-xs)`) — Gap between field sections.\n- `--lr-emoji-picker-search-clear-gap` (default: `var(--lr-space-xs)`) — Gap between the search field and the clear button inside `search-wrapper`.\n- `--lr-emoji-picker-radius` (default: `var(--lr-radius)`) — Outer picker corner radius.\n- `--lr-emoji-picker-item-radius` (default: `var(--lr-radius-xs)`) — Search and emoji corner radius.\n- `--lr-emoji-picker-search-border-color` (default: `var(--lr-color-border)`) — Resting search border color, independent of the hover color below.\n- `--lr-emoji-picker-search-fill` (default: `var(--lr-color-surface)`) — Resting search background.\n- `--lr-emoji-picker-search-hover-border-color` (default: `var(--lr-color-brand)`) — Search hover border.\n- `--lr-emoji-picker-search-min-height` (default: `auto`) — Minimum row height of the filter field, for matching it to a themed search field of a chosen density tier. Point it at `--lr-form-control-height-s` (or any tier of that ladder) to line the picker's own field up with the rest of an application's controls. `size` does not drive it: on this component `size` scales the emoji glyph and item box, not the form-control ladder.\n- `--lr-emoji-picker-search-font-size` (default: `inherit`) — Text size of the filter field.\n- `--lr-emoji-picker-search-padding-inline` (default: `var(--lr-space-s)`) — Inline gutter of the filter field.\n- `--lr-emoji-picker-search-padding-block` (default: `var(--lr-space-xs)`) — Block gutter of the filter field.\n- `--lr-emoji-picker-row-height` (default: `calc(var(--lr-emoji-picker-item-size) + var(--lr-space-l))`) — One windowed row's height. Must stay at or above the item size plus the group-label band, or consecutive absolutely-positioned rows overlap.\n- `--lr-emoji-picker-hover-bg` (default: `var(--lr-emoji-picker-active-bg,var(--lr-color-brand-quiet))`) — Pointer-hover background. The legacy `--lr-emoji-picker-active-bg` remains its fallback.\n- `--lr-emoji-picker-keyboard-active-bg` (default: `var(--lr-emoji-picker-active-bg,var(--lr-color-brand-quiet))`) — Roving keyboard/pointer-active background.\n- `--lr-emoji-picker-selected-bg` (default: `var(--lr-color-brand-quiet)`) — Committed-value background.\n- `--lr-emoji-picker-selected-color` (default: `var(--lr-color-text)`) — Committed-value foreground.\n- `--lr-emoji-picker-selected-outline-color` (default: `var(--lr-color-brand)`) — Outline color for the committed selection.\n- `--lr-emoji-picker-pressed-bg` (default: `color-mix(...)`) — Pointer-pressed background.\n- `--lr-emoji-picker-pressed-outline-color` (default: `var(--lr-color-brand)`) — Outline color while an emoji button is being pointer-pressed.\n- `--lr-emoji-picker-keyboard-active-outline-color` (default: `var(--lr-color-brand)`) — Outline color for the roving keyboard-active emoji.\n- `--lr-emoji-picker-active-bg` (default: `var(--lr-color-brand-quiet)`) — Compatibility fallback background for hover and roving-active states.\n- `--lr-form-control-required-content` (default: `' *'`) — The required marker appended to `form-control-label` while `required` is set. Set it to `''` to suppress the marker, or to any other quoted string (`' (required)'`, a localized word) to replace it.\n- `--lr-form-control-required-color` (default: `var(--lr-color-danger)`) — Required-marker color, themeable independently of error text and invalid borders.\n- `--lr-form-control-required-offset` (default: `0`) — Inline space between the label text and the required marker.","attributes":[{"name":"aria-label","description":"Accessible name forwarded from the host to the internal emoji listbox. Omission falls back\nto the visible label or localized default; an explicitly empty host attribute stays empty.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"custom-error","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nType: `string | null`  \nDefault: `null`"},{"name":"disabled","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"error-text","description":"Validation-error text rendered below the hint.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"form","description":"Type: `HTMLFormElement | string | null`  \nDefault: `null`"},{"name":"hint","description":"Supporting text rendered below the search/grid.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"label","description":"Visible label content, rendered above the search/grid. Empty (the default) renders no label\nchrome at all -- see the class doc above for the full label/hint/error contract.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"name","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"required","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"size","description":"Visual size — scales the emoji glyph and preferred item box while keeping the interactive\ntarget floored at `--lr-icon-button-size`; not pixel-matched to `lr-input`'s row-height scale. The Web Awesome / Shoelace spellings\n`small`/`medium`/`large` are accepted for `s`/`m`/`l`, so a migration is a tag rename with no\nattribute rewrite.\n\nType: `LyraSize`  \nDefault: `'m'`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}},{"name":"value","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}}],"slots":[{"name":"error","description":"Custom error content."},{"name":"hint","description":"Custom hint content."},{"name":"label","description":"Custom label content."}],"js":{"properties":[{"name":"accessibleLabel","description":"Accessible name forwarded from the host to the internal emoji listbox. Omission falls back\nto the visible label or localized default; an explicitly empty host attribute stays empty.\n\nAttribute: `aria-label`","type":"string","default":"''"},{"name":"customError","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nAttribute: `custom-error`  \nReflected to its attribute.","type":"string | null","default":"null"},{"name":"defaultValue","description":"Attribute: `value`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"disabled","description":"Attribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"errorText","description":"Validation-error text rendered below the hint.\n\nAttribute: `error-text`","type":"string","default":"''"},{"name":"form","description":"Attribute: `form`  \nReflected to its attribute.","type":"HTMLFormElement | string | null","default":"null"},{"name":"groups","description":"The full, ungrouped data set to search/render. Consumer-supplied — this component ships no\nemoji data of its own. Leaving the property unset allows the optional convenience loader to\nprovide defaults; explicitly assigning `[]` opts out and renders only the search input and\nempty state. See `emoji-data-loader.ts` for the loader contract.","type":"readonly EmojiPickerGroup[]"},{"name":"hint","description":"Supporting text rendered below the search/grid.\n\nAttribute: `hint`","type":"string","default":"''"},{"name":"label","description":"Visible label content, rendered above the search/grid. Empty (the default) renders no label\nchrome at all -- see the class doc above for the full label/hint/error contract.\n\nAttribute: `label`","type":"string","default":"''"},{"name":"labels","type":"NodeList","read-only":true},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"name","description":"Attribute: `name`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"required","description":"Attribute: `required`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"size","description":"Visual size — scales the emoji glyph and preferred item box while keeping the interactive\ntarget floored at `--lr-icon-button-size`; not pixel-matched to `lr-input`'s row-height scale. The Web Awesome / Shoelace spellings\n`small`/`medium`/`large` are accepted for `s`/`m`/`l`, so a migration is a tag rename with no\nattribute rewrite.\n\nAttribute: `size`  \nReflected to its attribute.","type":"LyraSize","default":"'m'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"validationMessage","type":"string","read-only":true},{"name":"validity","type":"ValidityState","read-only":true},{"name":"value","type":"string"},{"name":"willValidate","type":"boolean","read-only":true}],"events":[{"name":"blur","description":"Native owner-realm `FocusEvent` relayed from the internal search input.","type":"FocusEvent"},{"name":"change","description":"Native commit `Event` emitted in the host's current owner realm with `input`.","type":"Event"},{"name":"focus","description":"Native owner-realm `FocusEvent` relayed from the internal search input.","type":"FocusEvent"},{"name":"input","description":"Native `InputEvent` emitted in the host's current owner realm after a user pick.","type":"InputEvent"},{"name":"lr-change","description":"An emoji pick was committed. `detail: { value }`.","type":"CustomEvent<{ value: string }>"},{"name":"lr-input","description":"An emoji was picked. `detail: { value }`.","type":"CustomEvent<{ value: string }>"},{"name":"lr-invalid","description":"The emoji picker failed a validity check. Cancelable — preventing this alias also prevents the native `invalid` event that produced it.","type":"CustomEvent<null>"}]}},{"name":"lr-empty","description":"`<lr-empty>` — a generic empty/no-data state. First-party invention (no\nWeb Awesome equivalent); fills a gap common to dashboard-style apps.\nInitial and reconnect content are not announced as new live updates unless `announce` opts in;\nwith it set, the heading/description present when the empty state first mounts is announced once\nthrough the same polite sink, while reconnection and adoption still stage the existing content\ninstead of replaying it. Later meaningful heading\nor description changes are appended to Lyra's shared light-DOM polite announcement sink;\ndecorative icon and action slots, hidden/inert content, and unchanged accessible text are not.\nA visibility-hidden wrapper omits its own text but can contain a visible override descendant.\nNested forwarding slots contribute flattened assigned heading/description text rather than\nfallback content; later assignment and assigned-content mutations are observed without making\ninitial distribution live. Updates while the host or a composed ancestor is not\nrendered/accessibility-visible stay silent. A host `aria-label` names the host only and does not\nreplace visible heading/description text in the announcement sink. Property and rich-slot\nheadings default to semantic level 3; set `heading-level` from `1`–`6` to fit the surrounding\noutline, or `none` for visual-only heading text.\n\nRemoving heading or description safely omits that text; explicit empty values remain empty and later values restore the corresponding content.\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) | Custom icon or illustration (defaults to none). |\n| `actions` | Buttons/links shown below the description. |\n| `description` | Rich description content (overrides the `description` attribute). |\n| `heading` | Rich heading content (overrides the `heading` attribute) inside the configured semantic heading wrapper. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `actions` | The wrapper around the `actions`-slotted content. |\n| `base` | The outer container. |\n| `description` | The description paragraph. |\n| `heading` | The heading paragraph (`role=\"heading\"` at the configured level unless opted out). |\n| `icon` | The wrapper around the default-slotted icon/illustration. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-empty-compact-align` — Cross-axis and text alignment used in compact mode; set to `center` for dense but centered empty states.\n- `--lr-empty-compact-font-size` — Heading font size used in compact mode. Unset by default (no fallback), so the heading keeps its ordinary inherited font size until a consumer opts in.\n- `--lr-empty-compact-gap` (default: `var(--lr-space-2xs)`) — Gap between the icon, title, and description in compact mode.\n- `--lr-empty-compact-padding` (default: `var(--lr-space-xs)`) — Padding used in compact mode; accepts any padding shorthand (e.g. `8px 2px`).","attributes":[{"name":"announce","description":"Opts this empty state into announcing the heading/description it already carries when it\nfirst mounts, through the same shared light-DOM polite sink later changes use. Leave unset\nfor an empty state that is part of the page a user is arriving on: its text is read in\ndocument order and repeating it is noise. Set it where the empty state replaces a result set\nthe user just asked for. This is read once, when the component first mounts -- a later\nreconnection or adoption stages the existing content again rather than replaying it, and\nlater heading/description changes are announced either way. Remove any host\n`role=\"status\"`/`role=\"alert\"` hand-added before this property existed once it is set --\notherwise the initial text is announced twice, through the native role and again through the\nshared sink.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"compact","description":"Compact rendering for use inside a constrained space (e.g. a widget body\nor table cell) rather than as a full-page state: left-aligned, tighter\npadding, and a lighter heading weight instead of the centered/spacious\ndefault.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"description","description":"Supporting copy, e.g. \"Try a different search.\"\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"heading","description":"Short heading, e.g. \"No results\".\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"heading-level","description":"Semantic level of the visible property/slotted heading. Use `none` for visual-only text;\ninvalid untyped values use level 3.\n\nType: `LyraHeadingLevel`  \nDefault: `'3'`","value":{"type":["'1'","'2'","'3'","'4'","'5'","'6'","'none'"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"slots":[{"name":"","description":"Custom icon or illustration (defaults to none)."},{"name":"actions","description":"Buttons/links shown below the description."},{"name":"description","description":"Rich description content (overrides the `description` attribute)."},{"name":"heading","description":"Rich heading content (overrides the `heading` attribute) inside the configured semantic heading wrapper."}],"js":{"properties":[{"name":"announce","description":"Opts this empty state into announcing the heading/description it already carries when it\nfirst mounts, through the same shared light-DOM polite sink later changes use. Leave unset\nfor an empty state that is part of the page a user is arriving on: its text is read in\ndocument order and repeating it is noise. Set it where the empty state replaces a result set\nthe user just asked for. This is read once, when the component first mounts -- a later\nreconnection or adoption stages the existing content again rather than replaying it, and\nlater heading/description changes are announced either way. Remove any host\n`role=\"status\"`/`role=\"alert\"` hand-added before this property existed once it is set --\notherwise the initial text is announced twice, through the native role and again through the\nshared sink.\n\nAttribute: `announce`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"compact","description":"Compact rendering for use inside a constrained space (e.g. a widget body\nor table cell) rather than as a full-page state: left-aligned, tighter\npadding, and a lighter heading weight instead of the centered/spacious\ndefault.\n\nAttribute: `compact`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"description","description":"Supporting copy, e.g. \"Try a different search.\"\n\nAttribute: `description`","type":"string","default":"''"},{"name":"heading","description":"Short heading, e.g. \"No results\".\n\nAttribute: `heading`","type":"string","default":"''"},{"name":"headingLevel","description":"Semantic level of the visible property/slotted heading. Use `none` for visual-only text;\ninvalid untyped values use level 3.\n\nAttribute: `heading-level`  \nReflected to its attribute.","type":"LyraHeadingLevel","default":"'3'"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}]}},{"name":"lr-entity-card","description":"`<lr-entity-card>` — a dossier card for one `LyraEntity`: type badge, description, key/value\nproperty rows, degree, community chip, plus a built-in \"focus in graph\" action. Never fetches or\nfocuses a graph itself — `lr-entity-select` is a request a host routes into `lr-graph`'s\n`focusNode(id, { zoom? })`.\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| (default) | Extra body content below the property rows (e.g. a `lr-neighbor-list`). |\n| `actions` | Extra header actions alongside the built-in focus button. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `actions` | The wrapper around the `actions` slot and the built-in focus button. |\n| `base` | The outer bordered container. |\n| `community` | The community-chip row. |\n| `degree` | The relationship-count row. |\n| `description` | The entity's description text. |\n| `empty` | The empty state shown when `entity` is `null`. |\n| `focus-button` | The built-in \"Focus in graph\" button. |\n| `header` | The header row wrapping the type badge, title, and actions. |\n| `properties` | The wrapper around every property/degree/community row. |\n| `property` | One key/value dossier row. |\n| `title` | The entity's label, `role=\"heading\" aria-level=\"3\"` by default. The host's existing `aria-level` override updates live; removing it restores level 3. |\n| `type-badge` | The resolved entity-type badge. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-entity-card-bg` (default: `var(--lr-color-surface)`) — Resting background of `[part=\"base\"]`. `frame=\"plain\"` still paints transparent.\n- `--lr-entity-card-compact-gap` (default: `var(--lr-space-xs)`) — Gap between `[part=\"base\"]`'s rows while `compact`.\n- `--lr-entity-card-compact-padding` (default: `var(--lr-space-s)`) — `[part=\"base\"]` padding while `compact`.","attributes":[{"name":"aria-level","description":"Heading level forwarded to the title. An absent or empty value uses level 3.\n\nType: `string | number | null`"},{"name":"community-label","description":"Display label for `entity.communityId`'s chip; falls back to the raw id.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"compact","description":"Tighter root padding and row gap for dense contexts (a dossier rendered in a sidebar or a\nresult list) -- same convention as `lr-empty`'s `compact`, and as this component's sibling\n`lr-community-card`. Defaults to `false`, i.e. the full card padding. Purely a density knob:\nthe border and background stay, so use `frame=\"plain\"` to drop the chrome entirely.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"frame","description":"Container treatment, in the shared `LyraFrame` vocabulary. `'card'` (the default) keeps the\nbordered, filled, padded box. `'plain'` removes the border, background, padding and corner\nradius, so a card nested inside a container that already draws a border doesn't double it.\n`plain` wins over `compact` when both are set (nothing left to tighten).\n\nType: `LyraFrame`  \nDefault: `'card'`","value":{"type":["'card'","'plain'"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"show-focus-button","description":"Hides the built-in focus action on pages with no graph.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}}],"slots":[{"name":"","description":"Extra body content below the property rows (e.g. a `lr-neighbor-list`)."},{"name":"actions","description":"Extra header actions alongside the built-in focus button."}],"js":{"properties":[{"name":"communityLabel","description":"Display label for `entity.communityId`'s chip; falls back to the raw id.\n\nAttribute: `community-label`","type":"string","default":"''"},{"name":"compact","description":"Tighter root padding and row gap for dense contexts (a dossier rendered in a sidebar or a\nresult list) -- same convention as `lr-empty`'s `compact`, and as this component's sibling\n`lr-community-card`. Defaults to `false`, i.e. the full card padding. Purely a density knob:\nthe border and background stay, so use `frame=\"plain\"` to drop the chrome entirely.\n\nAttribute: `compact`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"entity","description":"`null` renders the shared `lr-empty` `noData` state.","type":"Readonly<LyraEntity> | null","default":"null"},{"name":"frame","description":"Container treatment, in the shared `LyraFrame` vocabulary. `'card'` (the default) keeps the\nbordered, filled, padded box. `'plain'` removes the border, background, padding and corner\nradius, so a card nested inside a container that already draws a border doesn't double it.\n`plain` wins over `compact` when both are set (nothing left to tighten).\n\nAttribute: `frame`  \nReflected to its attribute.","type":"LyraFrame","default":"'card'"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"showFocusButton","description":"Hides the built-in focus action on pages with no graph.\n\nAttribute: `show-focus-button`","type":"boolean","default":"true"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"types","description":"`lr-graph` `nodeTypes` pass-through used to resolve the type badge's label and swatch\ncolor; an unresolvable `entity.type` renders as its raw id in a neutral badge.","type":"readonly LyraNodeTypeStyle[]","default":"[]"}],"events":[{"name":"lr-entity-select","description":"The built-in focus button was activated. `detail: { entityId }`.","type":"CustomEvent<{ entityId: string }>"}]}},{"name":"lr-entity-chip","description":"`<lr-entity-chip>` — an inline `@entity` mention for agent prose: flow content,\nkeyboard-focusable, with a hover/focus preview popover. The knowledge-graph sibling of\n`lr-citation-badge`, reusing its interaction contract wholesale. Carries ids through events\nonly -- no entity data resolution, no navigation.\n\nAn authored host `aria-label` names the custom-element boundary intentionally; it is not copied\nonto the internal button. Because host naming does not cross the shadow boundary, the button\nkeeps its localized text/type name (and its localized untitled fallback) as its own name.\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) | Rich preview content (typically a compact `lr-entity-card`), shown in a floating popover on hover/focus. No content -> no popover and no hover affordance at all. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The clickable chip (`<button>`). |\n| `label` | The chip's visible `text`. |\n| `popover` | The floating preview panel. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-entity-chip-bg` (default: `var(--lr-color-brand-quiet)`) — Background color.\n- `--lr-entity-chip-border` (default: `transparent`) — Border color of the chip.\n- `--lr-entity-chip-color` (default: `var(--lr-color-brand)`) — Text/accent color. Reflected `type` lets a host theme per type from CSS, e.g. `lr-entity-chip[type='person'] { --lr-entity-chip-color: ... }`.\n- `--lr-overlay-border` (default: `var(--lr-color-border)`) — Shared floating-surface edge colour, on the anchored detail popover.\n- `--lr-overlay-radius` (default: `var(--lr-radius)`) — Shared floating-surface corner radius, on the anchored detail popover.\n- `--lr-overlay-shadow-anchored` (default: `var(--lr-shadow-m)`) — Elevation of the anchored surface.\n- `--lr-overlay-surface` (default: `var(--lr-color-surface-overlay)`) — Shared floating-surface fill, on the anchored detail popover.\n- `--lr-positioning-strategy` — Cascading `absolute`/`fixed` override for the preview popover's `fixed` default, read from computed style when it is (re)positioned. Set it once on `:root`, a theme, or one clipping ancestor to change every unset entity chip beneath it; an unrecognized value falls back to `fixed`.","attributes":[{"name":"entity-id","description":"Echoed verbatim in both events. Blank identities disable activation.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"text","description":"The visible chip text (unlike citation-badge, the chip renders its own text, not `[n]`).\nRemoving the attribute leaves null readback and uses the localized untitled accessible name.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"type","description":"The entity's `lr-graph` `nodeTypes` id; reflected so hosts theme per type from CSS.\nA removed attribute is treated as an absent type without rewriting null readback.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"type-label","description":"Resolved display label for `type`; when set, the accessible name speaks it instead of the raw\ntype id.\n\nType: `string | undefined`"}],"slots":[{"name":"","description":"Rich preview content (typically a compact `lr-entity-card`), shown in a floating popover on hover/focus. No content -> no popover and no hover affordance at all."}],"js":{"properties":[{"name":"entityId","description":"Echoed verbatim in both events. Blank identities disable activation.\n\nAttribute: `entity-id`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"text","description":"The visible chip text (unlike citation-badge, the chip renders its own text, not `[n]`).\nRemoving the attribute leaves null readback and uses the localized untitled accessible name.\n\nAttribute: `text`","type":"string","default":"''"},{"name":"type","description":"The entity's `lr-graph` `nodeTypes` id; reflected so hosts theme per type from CSS.\nA removed attribute is treated as an absent type without rewriting null readback.\n\nAttribute: `type`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"typeLabel","description":"Resolved display label for `type`; when set, the accessible name speaks it instead of the raw\ntype id.\n\nAttribute: `type-label`","type":"string | undefined"}],"events":[{"name":"lr-entity-open","description":"Dblclick, or Space while focused. `detail: { entityId }`.","type":"CustomEvent<{ entityId: string }>"},{"name":"lr-entity-select","description":"Click, or Enter while focused. `detail: { entityId }`.","type":"CustomEvent<{ entityId: string }>"}]}},{"name":"lr-entity-dossier","description":"`<lr-entity-dossier>` — a full entity detail surface: a persistent header (`lr-entity-card` plus\nan optional confidence `lr-stat`) above a `lr-tab-group` strip for Relationships (`lr-neighbor-list`),\nSupporting chunks (`lr-chunk-inspector`), and Provenance (`lr-provenance-panel`). Pure layout —\nit never fetches, ranks, or mutates graph/document state, and never re-renders what any of those\nfive composed components already render themselves; every one of their own events (`\nlr-entity-select`, `lr-entity-activate`, `lr-node-expand`, `lr-chunk-open`, `lr-expand`,\n`lr-toggle`, `lr-tab-show`, plus the provenance panel's own conduit set — `lr-entity-open`, `lr-drill`,\n`lr-relation-activate`) bubbles through unmodified (`composed: true` crosses this component's own\nshadow boundary with no re-dispatch needed).\n\n`chunks`/`thresholds` (the \"supporting chunks\" tab) and `provenance` (the \"Provenance\" tab) are\ndeliberately separate inputs even though `lr-provenance-panel` can itself also show a chunks\nsection: the \"Supporting chunks\" tab is the evidence for *this entity's own* summary/properties,\nwhile `provenance` is the broader grounding chain (which may span other entities, relationships,\nand communities, and may or may not reuse the same chunk set) — a host is free to pass the same\narray to both when the two concepts genuinely coincide.\n\nTab labels reuse the exact `localize()` keys the composed child already uses for its own\naccessible name (`neighborListLabel`, `chunkInspectorLabel`, `provenancePanelLabel`) rather than\nnew dossier-specific keys, so a translated locale only has to cover each string once and the tab\nstrip and the panel underneath it always agree.\n\nThis component emits no events of its own. Its EventMap and `@event` documentation name the\ncomposed events that bubble through so host listeners remain typed and discoverable;\n`lr-tab-show` carries `detail: { tabId: LyraEntityDossierTab }`. This is the same \"pure\nprojection + event conduit\" convention `lr-provenance-panel` and `lr-spreadsheet-viewer`'s\ninternal `lr-tab-group` already establish.\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.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| `base` | The root wrapper, or the empty state's wrapper when `entity` is `null`. |\n| `chunk-inspector` | The nested `lr-chunk-inspector`, inside the Supporting chunks tab. |\n| `confidence` | The nested confidence `lr-stat`, only rendered when `confidence` is set. |\n| `empty` | The empty state shown when `entity` is `null`. |\n| `entity-card` | The nested `lr-entity-card`. |\n| `header` | The wrapper around the entity summary and the confidence stat. |\n| `neighbor-list` | The nested `lr-neighbor-list`, inside the Relationships tab. |\n| `provenance-panel` | The nested `lr-provenance-panel`, inside the Provenance tab. |\n| `tabs` | The nested `lr-tab-group` strip. |","attributes":[{"name":"aria-label","description":"JS-only accessible name for the internal `lr-tab-group` strip while no host `aria-label` is\nauthored. A host label independently names the dossier and is not cloned onto the strip.\n\nType: `string | null`  \nDefault: `null`"},{"name":"community-label","description":"Forwarded to `lr-entity-card`'s own `communityLabel`.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"expandable","description":"Forwarded to `lr-neighbor-list`'s own `expandable`.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"group-by-relation","description":"Forwarded to `lr-neighbor-list`'s own `groupByRelation`.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"show-focus-button","description":"Forwarded to `lr-entity-card`'s own `showFocusButton`.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}}],"js":{"properties":[{"name":"accessibleLabel","description":"JS-only accessible name for the internal `lr-tab-group` strip while no host `aria-label` is\nauthored. A host label independently names the dossier and is not cloned onto the strip.\n\nAttribute: `aria-label`","type":"string | null","default":"null"},{"name":"chunks","description":"Forwarded to `lr-chunk-inspector`'s own `chunks` -- the evidence for this entity's own\nsummary, distinct from `provenance` (see the class doc above).","type":"readonly LyraChunk[]","default":"[]"},{"name":"communityLabel","description":"Forwarded to `lr-entity-card`'s own `communityLabel`.\n\nAttribute: `community-label`","type":"string","default":"''"},{"name":"confidence","description":"Headline confidence KPI, rendered as an `lr-stat` next to the entity summary. Omitted\nentirely (no placeholder, no empty stat) when `null`.","type":"Readonly<LyraEntityDossierConfidence> | null","default":"null"},{"name":"entity","description":"`null` renders the shared `lr-empty` `noData` state in place of the whole dossier.","type":"Readonly<LyraEntity> | null","default":"null"},{"name":"expandable","description":"Forwarded to `lr-neighbor-list`'s own `expandable`.\n\nAttribute: `expandable`","type":"boolean","default":"false"},{"name":"groupByRelation","description":"Forwarded to `lr-neighbor-list`'s own `groupByRelation`.\n\nAttribute: `group-by-relation`","type":"boolean","default":"false"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"neighbors","description":"Forwarded to `lr-neighbor-list`'s own `rows`.","type":"readonly LyraNeighborRow[]","default":"[]"},{"name":"provenance","description":"Forwarded to `lr-provenance-panel`'s own `provenance`.","type":"Readonly<LyraProvenance> | null","default":"null"},{"name":"showFocusButton","description":"Forwarded to `lr-entity-card`'s own `showFocusButton`.\n\nAttribute: `show-focus-button`","type":"boolean","default":"true"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"thresholds","description":"Forwarded to both `lr-chunk-inspector`'s and `lr-provenance-panel`'s own `thresholds`, so\nthe score tiers agree everywhere a score renders in this dossier.","type":"LyraScoreThresholds","default":"{ high: 0.75, medium: 0.5, }"},{"name":"types","description":"`lr-graph` `nodeTypes` pass-through, forwarded to both `lr-entity-card` and\n`lr-provenance-panel` so the entity type badge and any provenance entity chips resolve\nidentically.","type":"readonly LyraNodeTypeStyle[]","default":"[]"}],"events":[{"name":"lr-chunk-open","description":"Surfaced unchanged from the embedded chunk inspector. `detail: { chunkId, sourceId, anchor? }`.","type":"CustomEvent<LyraEventDetailSnapshot<{\n    chunkId: string;\n    sourceId: string;\n    anchor?: LyraChunkAnchor;\n  }>>"},{"name":"lr-drill","description":"Surfaced unchanged from a community card inside the embedded provenance panel. `detail: { communityId }`.","type":"CustomEvent<{ communityId: string }>"},{"name":"lr-entity-activate","description":"Surfaced unchanged from the embedded provenance panel's own community card or relationship path strip. `detail: { entityId, occurrenceIndex? }`.","type":"CustomEvent<{\n    entityId: string;\n    occurrenceIndex?: number;\n  }>"},{"name":"lr-entity-open","description":"Surfaced unchanged from an entity chip inside the embedded provenance panel. `detail: { entityId }`.","type":"CustomEvent<{ entityId: string }>"},{"name":"lr-entity-select","description":"Surfaced unchanged from the embedded entity card or neighbor list. `detail: { entityId }`.","type":"CustomEvent<{ entityId: string }>"},{"name":"lr-expand","description":"Surfaced unchanged from the embedded chunk inspector. `detail: { chunkId, expanded }`.","type":"CustomEvent<{ chunkId: string; expanded: boolean }>"},{"name":"lr-node-expand","description":"Surfaced unchanged from the embedded neighbor list. `detail: { nodeId }`.","type":"CustomEvent<{ nodeId: string }>"},{"name":"lr-relation-activate","description":"Surfaced unchanged from a relationship path strip inside the embedded provenance panel. `detail: { relation, sourceNodeId?, targetNodeId?, occurrenceIndex }`.","type":"CustomEvent<{\n    relation: string;\n    sourceNodeId?: string;\n    targetNodeId?: string;\n    occurrenceIndex: number;\n  }>"},{"name":"lr-tab-show","description":"Surfaced unchanged from the embedded tabs. `detail: { tabId }`.","type":"CustomEvent<{ tabId: LyraEntityDossierTab }>"},{"name":"lr-toggle","description":"Surfaced unchanged from the embedded provenance panel. `detail: { section, expanded }`.","type":"CustomEvent<{ section: Section; expanded: boolean }>"}]}},{"name":"lr-env-list","description":"`<lr-env-list>` — masked key/value list for environment variables and secrets, with per-row\nreveal and copy. Masking is presentational, not a security boundary: the real value sits in a DOM\nproperty regardless of mask state. Entry identity is a unique nonempty `name`; malformed,\nblank-name, and later duplicate records are omitted first-wins before render, reveal state,\ncopy actions, and reveal events.\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 `<dl>` root. |\n| `copy-button` | The per-row copy button. |\n| `name` | The `<dt>` name text. |\n| `reveal-button` | The per-row reveal/hide toggle. |\n| `value` | The value text itself; carries `data-masked`. |\n| `value-cell` | The `<dd>` wrapping one entry's value text and its buttons; buttons live here (not as siblings of `<dt>`/`<dd>`) so the `<dl>` keeps a valid dt/dd content model. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-env-list-reveal-active-bg` (default: `var(--lr-color-brand-quiet)`) — Background of a pressed (revealed) reveal toggle.\n- `--lr-env-list-reveal-active-border` (default: `var(--lr-color-brand)`) — Border color of a pressed (revealed) reveal toggle. Restyling the pressed state otherwise requires overriding the library-wide brand tokens, since `::part(reveal-button)[aria-pressed]` is invalid CSS.","attributes":[{"name":"copyable","description":"Whether each entry gets a copy-to-clipboard button.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"label","description":"Accessible name for the list; falls back to a localized default when unset. An explicitly\nempty string renders as an empty label rather than falling back.\n\nType: `string | undefined`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"revealable","description":"Whether each secret entry gets a reveal/hide toggle.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}}],"js":{"properties":[{"name":"copyable","description":"Whether each entry gets a copy-to-clipboard button.\n\nAttribute: `copyable`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"entries","description":"Clone-owned readonly name/value entries to render, in order, bounded to the first 10,000\nsource entries. Malformed records, blank names, and later duplicate names are skipped; the\nfirst valid occurrence owns render, reveal, copy, and event identity. Reassign to update.","type":"readonly EnvEntry[]"},{"name":"label","description":"Accessible name for the list; falls back to a localized default when unset. An explicitly\nempty string renders as an empty label rather than falling back.\n\nAttribute: `label`","type":"string | undefined"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"revealable","description":"Whether each secret entry gets a reveal/hide toggle.\n\nAttribute: `revealable`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-copy","description":"A clipboard write fulfilled. Frozen detail: `{ ok: true, text }`, where text is the real (unmasked) value.","type":"CustomEvent<LyraClipboardWriteSuccess>"},{"name":"lr-copy-error","description":"A clipboard write failed. Frozen detail: `{ ok: false, text, reason, error }`.","type":"CustomEvent<LyraClipboardWriteFailure>"},{"name":"lr-error","description":"A clipboard write failed; compatibility notification without raw error text.","type":"CustomEvent<null>"},{"name":"lr-reveal-change","description":"`detail: { envName, revealed }`.","type":"CustomEvent<Readonly<{ envName: string; revealed: boolean }>>"}]}},{"name":"lr-eval-dataset","description":"`<lr-eval-dataset>` — dataset management for an evaluation suite: a filterable/taggable list of\n`EvalExample` rows, plus add/remove/import/export affordances.\n\nFully controlled, matching this library's established convention for every other\norchestration-level component in this family (e.g. `<lr-thread-list>`'s\n`lr-thread-pin`/`-archive`/`-delete`): `examples` is the host's own data, and this component\nnever mutates it or performs any I/O itself. Every action a user takes -- adding a row,\nremoving the selected row, importing files, exporting to a format -- fires a `*-request` event\ncarrying just enough information to act on. Duplicate example ids normalize before filtering,\nselection, row keys, exports, and actions; the first occurrence wins. The host decides how (a local mutation, a network\nround-trip, opening its own creation dialog, parsing an imported file's actual contents, writing\nan exported file to disk or a server) and passes an updated `examples` array back in.\n\nComposes `<lr-table>` for the row list (columns for `input`/`expectedOutput`/joined\n`tags`), `<lr-chip>`/`<lr-chip-group>` as a tag-based browse filter (one toggleable chip per\ndistinct tag currently present across `examples`; multiple active tags OR together, matching\nthe common \"browse by any of these tags\" idiom rather than requiring every tag to match),\n`<lr-file-input>` for the import affordance, and `<lr-export-button>` for the export affordance\n-- its own built-in client-side CSV/JSON download is deliberately suppressed\n(`event.preventDefault()` on its `lr-export`) since `<lr-export-button>`'s flat `rows`/`columns`\nCSV/JSON builder can't preserve an `EvalExample`'s own `tags`/`metadata` shape faithfully, and\nproducing the actual exported file/API-call either way is the host's job per this component's\nown controlled contract; this keeps `lr-export-request` the single source of truth for every\nconfigured format rather than one format silently downloading locally while every other format\ndoes nothing.\n\nRow sorting is *not* re-implemented here: all three built-in text columns opt into\n`<lr-table>` sorting, and its own `lr-sort` bubbles through (composed events cross a shadow\nboundary automatically) for a host that wants to reorder `examples` and hand back a resorted\narray -- the same \"the host owns the actual data\" contract as every other mutation this\ncomponent surfaces.\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.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| `add-button` | The \"Add example\" button. |\n| `base` | The root. |\n| `export` | The internal `<lr-export-button>`. |\n| `grid` | The internal `<lr-table>`. |\n| `import` | The internal `<lr-file-input>`. |\n| `remove-button` | The \"Remove\" button, disabled while nothing is selected. |\n| `search` | The search field's wrapper. Only rendered while `searchable`. |\n| `search-clear` | The clear-search button, replacing the native search-cancel glyph the component resets. Only rendered while the field has text. |\n| `search-input` | The `<input type=\"search\">`. Only rendered while `searchable`. |\n| `tag-filter` | The tag-filter chip group's wrapper. Only rendered while `examples` carries at least one tag. |\n| `toolbar` | The row of add/remove/import/export controls. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-eval-dataset-search-font-size` (default: `inherit`) — Text size of the search field.\n- `--lr-eval-dataset-search-min-height` (default: `auto`) — Minimum row height of the search field, for matching it to a themed search field of a chosen density tier. Point it at `--lr-form-control-height-s` (or any tier of that ladder) to line this field up with the rest of an application's controls.\n- `--lr-eval-dataset-search-padding-block` (default: `var(--lr-space-xs)`) — Block gutter of the search field.\n- `--lr-eval-dataset-search-padding-inline` (default: `var(--lr-space-s)`) — Leading gutter of the search field. The trailing gutter is reserved for the overlaid clear button.\n- `--lr-eval-dataset-search-radius` (default: `var(--lr-radius)`) — Corner radius of the search field.","attributes":[{"name":"accept","description":"Forwarded to the internal `<lr-file-input>`'s own `accept` (native-file-input-style pattern,\ne.g. `'.json,.csv'`). Empty (the default) accepts any file type.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"autocapitalize","description":"Native capitalization hint forwarded to the built-in search input while `searchable`.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"autocomplete","description":"Native autocomplete hint forwarded to the built-in search input while `searchable`. An empty\nstring (the default) leaves the browser default in effect.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"autocorrect","description":"Native autocorrection hint forwarded to the built-in search input while `searchable`.\n`autoCorrect` maps to the standard lowercase `autocorrect` attribute without colliding with\nthe incompatible inherited `HTMLElement.autocorrect` type.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"disabled","description":"Disables every add/remove/import/export affordance -- e.g. while a host-side mutation from a\nprevious request is still in flight.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"enterkeyhint","description":"Native virtual-keyboard enter-key hint forwarded to the built-in search input while\n`searchable`.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"inputmode","description":"Native virtual-keyboard input-mode hint forwarded to the built-in search input while\n`searchable`.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"label","description":"Accessible name for the nested example grid. This wins over the localized\n`evalDatasetLabel` default; a host `aria-label` names the host itself and is not cloned onto\nthe independently interactive grid.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"searchable","description":"Shows the built-in free-text search field, filtering by a case-insensitive substring match\nagainst `input`, `expectedOutput`, and `tags`.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"spellcheck","description":"Whether the browser spellchecks the built-in search input. Defaults to `true`; the literal\n`spellcheck=\"false\"` attribute is deliberately parsed as false instead of as a presence-based\nboolean.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}}],"js":{"properties":[{"name":"accept","description":"Forwarded to the internal `<lr-file-input>`'s own `accept` (native-file-input-style pattern,\ne.g. `'.json,.csv'`). Empty (the default) accepts any file type.\n\nAttribute: `accept`","type":"string","default":"''"},{"name":"autoCorrect","description":"Native autocorrection hint forwarded to the built-in search input while `searchable`.\n`autoCorrect` maps to the standard lowercase `autocorrect` attribute without colliding with\nthe incompatible inherited `HTMLElement.autocorrect` type.\n\nAttribute: `autocorrect`","type":"string","default":"''"},{"name":"autocapitalize","description":"Native capitalization hint forwarded to the built-in search input while `searchable`.\n\nAttribute: `autocapitalize`","type":"string","default":"''"},{"name":"autocomplete","description":"Native autocomplete hint forwarded to the built-in search input while `searchable`. An empty\nstring (the default) leaves the browser default in effect.\n\nAttribute: `autocomplete`","type":"string","default":"''"},{"name":"disabled","description":"Disables every add/remove/import/export affordance -- e.g. while a host-side mutation from a\nprevious request is still in flight.\n\nAttribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"enterKeyHint","description":"Native virtual-keyboard enter-key hint forwarded to the built-in search input while\n`searchable`.\n\nAttribute: `enterkeyhint`","type":"string","default":"''"},{"name":"examples","description":"Controlled dataset: every example currently known to the host. This component never\nmutates its own copy of it -- add/remove/import/export are all *requests*; the host performs\nthe actual mutation (and any persistence/API call) and passes the updated array back in.\nShrinking this out from under an in-progress selection or active tag filter is handled\ngracefully: a `selectedId` that no longer matches any row or falls outside the filtered\nresult set resets to `null` (so Remove cannot act on a hidden row), and an active tag filter\nthat no longer matches any row's `tags` is dropped rather than silently matching zero rows\nforever. Empty/blank ids are omitted and duplicates normalize first-wins before filtering,\nselection, the nested grid, and mutation events.","type":"readonly EvalExample[]","default":"[]"},{"name":"exportFormats","description":"Forwarded to the internal `<lr-export-button>`'s own `formats`.","type":"readonly LyraExportFormatOption[]","default":"['csv', 'json']"},{"name":"inputMode","description":"Native virtual-keyboard input-mode hint forwarded to the built-in search input while\n`searchable`.\n\nAttribute: `inputmode`","type":"string","default":"''"},{"name":"label","description":"Accessible name for the nested example grid. This wins over the localized\n`evalDatasetLabel` default; a host `aria-label` names the host itself and is not cloned onto\nthe independently interactive grid.\n\nAttribute: `label`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"searchable","description":"Shows the built-in free-text search field, filtering by a case-insensitive substring match\nagainst `input`, `expectedOutput`, and `tags`.\n\nAttribute: `searchable`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"spellcheck","description":"Whether the browser spellchecks the built-in search input. Defaults to `true`; the literal\n`spellcheck=\"false\"` attribute is deliberately parsed as false instead of as a presence-based\nboolean.\n\nAttribute: `spellcheck`","type":"boolean","default":"true"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"blur","description":"Re-dispatched when the internal search field loses focus.","type":"CustomEvent<null>"},{"name":"focus","description":"Re-dispatched when the internal search field (only rendered while `searchable`) receives focus, since native focus neither bubbles nor crosses the shadow boundary.","type":"CustomEvent<null>"},{"name":"lr-example-add-request","description":"The \"Add example\" control was activated. No detail payload -- this component has no opinion on what a new example's fields should be; the host implements its own creation flow (a dialog, a generated draft, etc.) and appends the result to `examples`.","type":"CustomEvent<null>"},{"name":"lr-example-remove-request","description":"The \"Remove\" control was activated for the selected row. `detail: { exampleId }`.","type":"CustomEvent<{ exampleId: string }>"},{"name":"lr-example-select","description":"A row was activated. `detail: { exampleId }` -- `exampleId` is `null` once the previously-selected row no longer exists in `examples` or falls outside the active filters (see `examples`' own doc).","type":"CustomEvent<{ exampleId: string | null }>"},{"name":"lr-export-request","description":"An export format was chosen. `detail: { format }`.","type":"CustomEvent<{ format: string }>"},{"name":"lr-import-request","description":"Files were selected/dropped on the internal `<lr-file-input>` and at least one was accepted by its own type/size rules. `detail: { files }` — raw `File[]`; parsing (CSV/JSON/etc. into `EvalExample` rows) is left to the host, mirroring `<lr-file-input>`'s own \"parsing is a host concern\" scope.","type":"CustomEvent<LyraEventDetailSnapshot<{ files: File[] }>>"},{"name":"lr-sort","description":"Deliberate pass-through from the internal table. `detail: { phase: 'commit', sortKey, sortDir }`.","type":"LyraTableEventMap<EvalExample>['lr-sort']"}]}},{"name":"lr-eval-result","description":"`<lr-eval-result>` — rubric scoring, human review, and comparison across a single evaluation\nexample's runs (one per model or prompt version), LangSmith/Arize-eval-result style. Duplicate\nrun ids normalize before fallback selection, lookup, table row keys, review events, and\ncomparison; the first occurrence wins.\n\nComposes three existing primitives directly rather than re-deriving any of their behavior:\n`<lr-table>` renders the `runs` comparison table (`columns` is a plain pass-through to its\nown `TableColumn[]` shape, the same way `rubricKeys` is a pass-through to\n`<lr-rubric-form>`'s own `keys` -- neither is re-derived here); `<lr-rubric-form>` is the\nhuman-review scoring surface for whichever run is currently selected, reading/writing that\nrun's own `review` value and re-emitting its `lr-input`/`lr-validity-change`/`lr-submit`/\n`lr-skip` events with the run id attached; `<lr-diff-view>` compares the selected run's output\nagainst `baselineRunId`'s output -- `layout=\"split\"` once they resolve to two distinct runs,\n`layout=\"unified\"` (an all-equal diff, i.e. a plain read of the one run's output) once they\nresolve to the same run or no baseline resolves at all -- so there is no separate un-diffed\n\"just show the output\" code path to keep in sync with the comparison one.\n\n`selectedRunId`/`baselineRunId` are both fully controlled: this component never mutates either\nproperty itself. Each one falls back to `runs[0]?.id` purely for *rendering* whenever the\nproperty is unset, so the component renders something useful with zero configuration beyond\n`runs` -- but moving the selection for real requires the host to set `selectedRunId` in\nresponse to `lr-run-activate`, the same shape `<lr-rubric-form>`'s own `itemId` already uses. A\n`selectedRunId`/`baselineRunId` that doesn't match any entry in `runs` degrades gracefully: the\ncomparison grid still renders, and the review/diff sections simply don't (no error, no crash).\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.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| `base` | The outer wrapper. |\n| `diff` | The wrapper around the diff caption and `<lr-diff-view>`. |\n| `diff-label-new` | The selected run's caption. |\n| `diff-label-old` | The baseline run's caption. |\n| `diff-labels` | The caption row naming the two compared runs (only rendered while comparing two distinct runs). |\n| `diff-view` | The `<lr-diff-view>` comparing the baseline and selected runs' output. |\n| `empty` | The message shown when `runs` has no entries. |\n| `grid` | The `<lr-table>` comparison table. |\n| `review` | The `<lr-rubric-form>` scoring the selected run. |","attributes":[{"name":"baseline-run-id","description":"The run compared against, and the diff's \"old\" side. `null` falls back to the first valid run;\nan unmatched identity selects no baseline.\n\nType: `string | null`  \nDefault: `null`"},{"name":"disabled","description":"Disables the review form's controls. The comparison grid stays interactive (selecting a run to inspect is not a mutation).\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"label","description":"Accessible name for the independently interactive comparison grid. Falls back to the\nlocalized evaluation-runs label when unset.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"review-skippable","description":"Shows a Skip control on the review form (forwarded to `<lr-rubric-form>`'s own `skippable`).\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"selected-run-id","description":"The run currently open for review, and the diff's \"new\" side. `null` falls back to the first\nvalid run; an unmatched identity selects no run.\n\nType: `string | null`  \nDefault: `null`"}],"js":{"properties":[{"name":"baselineRunId","description":"The run compared against, and the diff's \"old\" side. `null` falls back to the first valid run;\nan unmatched identity selects no baseline.\n\nAttribute: `baseline-run-id`","type":"string | null","default":"null"},{"name":"columns","description":"Column definitions for the comparison grid -- forwarded to `<lr-table>` after malformed and\nempty keys are omitted and duplicate keys normalize first-wins.\nEach column now needs a `cell(row)` accessor (`<lr-table>`'s `TableColumn` shape), not the old\n`<lr-data-grid>` `DataGridColumn`'s optional `value(row)`.","type":"readonly TableColumn<EvalRunResult>[]","default":"[]"},{"name":"disabled","description":"Disables the review form's controls. The comparison grid stays interactive (selecting a run to inspect is not a mutation).\n\nAttribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"label","description":"Accessible name for the independently interactive comparison grid. Falls back to the\nlocalized evaluation-runs label when unset.\n\nAttribute: `label`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"reviewSkippable","description":"Shows a Skip control on the review form (forwarded to `<lr-rubric-form>`'s own `skippable`).\n\nAttribute: `review-skippable`","type":"boolean","default":"false"},{"name":"rubricKeys","description":"Rubric field definitions for the review form. Empty keys are omitted and duplicate keys\nnormalize first-wins before the review form receives them.","type":"readonly RubricKey[]","default":"[]"},{"name":"runs","description":"The runs (one per model or prompt version) being compared for this evaluation example. Empty\nids are omitted and duplicates normalize first-wins before selection, diff, grid, and review\nevents.","type":"readonly EvalRunResult[]","default":"[]"},{"name":"selectedRunId","description":"The run currently open for review, and the diff's \"new\" side. `null` falls back to the first\nvalid run; an unmatched identity selects no run.\n\nAttribute: `selected-run-id`","type":"string | null","default":"null"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-review-input","description":"The selected run's rubric value changed. `detail: { runId, value }`.","type":"CustomEvent<LyraEventDetailSnapshot<{ runId: string; value: RubricValue }>>"},{"name":"lr-review-skip","description":"The selected run's rubric form was skipped (`reviewSkippable` only). `detail: { runId }`.","type":"CustomEvent<LyraEventDetailSnapshot<{ runId: string }>>"},{"name":"lr-review-submit","description":"The selected run's rubric form was submitted. `detail: { runId, value }`.","type":"CustomEvent<LyraEventDetailSnapshot<{ runId: string; value: RubricValue }>>"},{"name":"lr-review-validity-change","description":"The selected run's rubric validity changed. `detail: { runId, valid, errors }`.","type":"CustomEvent<LyraEventDetailSnapshot<{\n    runId: string;\n    valid: boolean;\n    errors: Record<string, string>;\n  }>>"},{"name":"lr-run-activate","description":"A comparison-grid row was activated. `detail: { runId, run }`.","type":"CustomEvent<LyraEventDetailSnapshot<AgentRunActivateDetail<EvalRunResult>>>"}]}},{"name":"lr-eval-run","description":"`<lr-eval-run>` — an evaluation batch's live progress: an overall `<lr-progress-bar>`\ncounting terminal (done/error/cancelled) examples against the batch total, plus one\n`<lr-details>` disclosure per example showing its input/output (`<lr-markdown>` or\n`<lr-code-block>`, per each payload's `format`), a `<lr-grounding-summary>` when the\nexample carries a `GroundingAssessment`, and a `<lr-tool-timeline>` when it carries\n`toolTrace` entries. Controlled: `examples` mirrors this package's other data-driven\ncomponents' own convention (a plain prop the host replaces wholesale to update, never mutated\nin place).\n\nNested-component events that need per-example correlation are intercepted and re-emitted under\nthis component's own name with the originating example's `id` folded into `detail` (matching\n`<lr-tool-timeline>`'s own precedent of extending a shared `*EventDetail` type from\n`src/ai/types.ts` rather than inventing a divergent shape) -- a host listening at this\ncomponent's boundary never needs to walk the DOM to find out which example a nested selection\nor approval decision came from.\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: `9.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 root wrapper. |\n| `count` | One count badge; carries `data-kind=\"running\"\\|\"error\"`. |\n| `counts` | Wrapper around the running/failed count badges. |\n| `empty` | The empty-state message shown when `examples` is empty. |\n| `example` | One example's `<lr-details>` row; carries `data-status` (the example's `status.kind`). |\n| `example-label` | An example's label text. |\n| `example-status` | An example's status badge. |\n| `example-status-message` | Optional caller-supplied detail for an example status. |\n| `example-summary` | The wrapper around an example's label and status badge, in the `<lr-details>` `summary` slot. |\n| `examples` | Wrapper around the per-example `<lr-details>` rows. |\n| `grounding-section` | Wrapper around an example's `<lr-grounding-summary>`, only rendered when the example carries a `grounding` assessment. |\n| `grounding-summary` | The nested `<lr-grounding-summary>` for an example's grounding assessment. |\n| `header` | The batch-progress header row. |\n| `header-label` | The run's label, defaulting to a localized \"Evaluation run\". |\n| `input` | The rendered `<lr-markdown>`/`<lr-code-block>` for an example's input. |\n| `input-section` | Wrapper around an example's input heading + rendered content. |\n| `live-region` | The internal status-announcement live region. |\n| `output` | The rendered `<lr-markdown>`/`<lr-code-block>` for an example's output. |\n| `output-section` | Wrapper around an example's output heading + rendered content. |\n| `progress` | The batch `<lr-progress-bar>`. |\n| `section-heading` | The heading text inside any of the four sections above. |\n| `summary` | The \"N of M examples complete\" text. |\n| `tool-trace` | The nested `<lr-tool-timeline>` for an example's tool calls. |\n| `tool-trace-section` | Wrapper around an example's `<lr-tool-timeline>`, only rendered when the example carries non-empty `toolTrace` entries. |","attributes":[{"name":"label","description":"Header label and accessible-name source. Falls back to a localized \"Evaluation run\" when\nunset.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"total","description":"The batch's expected total example count. `null` (the default) derives it from\n`examples.length` instead -- the common case once every result has already arrived; set this\nexplicitly while a batch is still streaming in and the eventual total is already known ahead\nof every example actually completing. An explicit value below the current observed count is\nraised to `examples.length`, so progress never reports an impossible total.\n\nType: `number | null`  \nDefault: `null`"}],"js":{"properties":[{"name":"examples","description":"The batch's examples so far. Controlled -- never mutated by this component; pass a new array\nto update it (e.g. as each example finishes, or as the whole batch streams in). Empty/blank ids\nare omitted and duplicates normalize first-wins before expansion, counts, announcements,\nrendering, and events. A valid-id partial streaming row keeps rendering with idle status and\nempty Markdown content until its status/input/output payloads arrive.","type":"readonly EvalExampleResult[]","default":"[]"},{"name":"label","description":"Header label and accessible-name source. Falls back to a localized \"Evaluation run\" when\nunset.\n\nAttribute: `label`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"total","description":"The batch's expected total example count. `null` (the default) derives it from\n`examples.length` instead -- the common case once every result has already arrived; set this\nexplicitly while a batch is still streaming in and the eventual total is already known ahead\nof every example actually completing. An explicit value below the current observed count is\nraised to `examples.length`, so progress never reports an impossible total.\n\nAttribute: `total`","type":"number | null","default":"null"}],"events":[{"name":"lr-example-citation-select","description":"An evidence citation in a nested `<lr-grounding-summary>` was activated. `detail: { exampleId, citation }`.","type":"CustomEvent<LyraEventDetailSnapshot<EvalCitationSelectDetail>>"},{"name":"lr-example-claim-select","description":"A grounded claim was activated. `detail: { exampleId, claim }`.","type":"CustomEvent<LyraEventDetailSnapshot<EvalClaimSelectDetail>>"},{"name":"lr-example-toggle","description":"An example's disclosure was expanded or collapsed. `detail: { exampleId, expanded }`.","type":"CustomEvent<EvalExampleToggleDetail>"},{"name":"lr-example-tool-activate","description":"A nested tool entry was activated. `detail: { exampleId, invocationId, sourceKey? }`.","type":"CustomEvent<EvalToolActivateDetail>"},{"name":"lr-example-tool-approval-decide","description":"A pending tool call in a nested `<lr-tool-timeline>` was approved or denied. `detail: { exampleId, invocationId, approved, args? }`. Cancelable: preventing this correlated event vetoes the nested decision and preserves its pending dialog.","type":"CustomEvent<EvalToolApprovalDetail>"},{"name":"lr-example-tool-render-error","description":"A nested tool renderer failed. `detail: { exampleId, invocationId, sourceKey?, toolName, error }`.","type":"CustomEvent<EvalToolRenderErrorDetail>"}]}},{"name":"lr-export-button","description":"`<lr-export-button>` — a CSV/JSON download button, single-format or a\nformat-choice menu. First-party invention; consolidates the ad-hoc\n\"export CSV\" button pattern common across dashboard UIs.\nFormat ids are unique, nonempty occurrence identities. Malformed options and later duplicate\nids are omitted before menu state, focus reconciliation, or export events; the first wins.\n\nData reaches a built-in CSV/JSON download two ways, both resolved at download time rather than\nat assignment time: the eager `rows` property (read after the cancelable `lr-export` event, so a\nlistener may assign it from inside its own handler) and the lazy `getRows` callback, which\nreplaces `rows` for that download and lets a consumer export a collection it already holds --\nan `<lr-table>`'s `viewRows`, for instance -- without materializing a second copy here.\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| `format-description` | A custom format option's optional secondary text. |\n| `format-label` | A format option's primary label. |\n| `menu` | The format-choice menu, shown when more than one format is configured. |\n| `menu-item` | A single format option inside the menu. |\n| `trigger` | The button that triggers the export (or opens the format menu). |\n| `trigger-error` | Present alongside `trigger` after a built-in CSV/JSON export fails, until the next export attempt. Style with `::part(trigger-error)`. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-export-button-active-background` — Trigger fill while pressed.\n- `--lr-export-button-active-border` — Trigger edge colour while pressed.\n- `--lr-export-button-active-color` — Trigger label and icon colour while pressed.\n- `--lr-export-button-background` — Trigger fill at rest. Overrides whatever the current `appearance` resolves to, leaving every other paint untouched.\n- `--lr-export-button-border` — Trigger edge colour at rest.\n- `--lr-export-button-color` — Trigger label and icon colour at rest. The escape hatch for `appearance=\"outlined\"`, which paints the label `--lr-color-brand` and has no `variant` of its own to return it to neutral text.\n- `--lr-export-button-hover-background` — Trigger fill on hover.\n- `--lr-export-button-hover-border` — Trigger edge colour on hover.\n- `--lr-export-button-hover-color` — Trigger label and icon colour on hover.\n- `--lr-overlay-border` (default: `var(--lr-color-border)`) — Shared floating-surface edge colour, on the menu popup.\n- `--lr-overlay-radius` (default: `var(--lr-radius)`) — Shared floating-surface corner radius, on the menu popup.\n- `--lr-overlay-shadow-anchored` (default: `var(--lr-shadow-m)`) — Elevation of the anchored surface.\n- `--lr-overlay-surface` (default: `var(--lr-color-surface-overlay)`) — Shared floating-surface fill, on the menu popup.\n- `--lr-positioning-strategy` — Cascading `absolute`/`fixed` override for the format menu's `fixed` default, read from computed style when it is (re)positioned. Set it once on `:root`, a theme, or one clipping ancestor to change every unset export button beneath it; an unrecognized value falls back to `fixed`.","attributes":[{"name":"appearance","description":"Optional `outlined` or `quiet` trigger treatment. Unset preserves the established surface, border, and text colors.\n\nType: `LyraExportButtonAppearance | undefined`","value":{"type":["'outlined'","'quiet'"]}},{"name":"aria-label","description":"Accessible name forwarded from the host to the native trigger button.\nWhen unset, a nonempty visible `label` provides the name; an empty visible label uses the\nlocalized default. An explicit empty `aria-label` remains authoritative by presence.\n\nType: `string | null`  \nDefault: `null`"},{"name":"bom","description":"Prepends a UTF-8 byte-order mark (U+FEFF) to the built-in CSV download only. Excel on\nWindows ignores a downloaded file's MIME charset and decodes a BOM-less CSV with the\nsystem ANSI code page, so accented, Arabic, CJK, and typographic characters render as\nmojibake; the BOM makes Excel detect UTF-8 and decode correctly. Google Sheets,\nLibreOffice, and Numbers already sniff UTF-8 correctly with or without it. Never applies to\nthe built-in JSON download -- RFC 8259 forbids a BOM there.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"disabled","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"filename","description":"Type: `string`  \nDefault: `'export'`","value":{"type":["string"]}},{"name":"label","description":"Visible trigger button text. It also feeds the format menu's `aria-label` when no host\n`aria-label` supplies a more specific name. `undefined` uses the localized default; every\nsupplied string, including `''` and `'Export'`, is caller-owned visible copy. An empty or\nwhitespace-only visible label retains the localized default as the trigger's accessible name.\n\nType: `string | undefined`"},{"name":"loading","description":"Controlled busy state for async/server-generated exports.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"open","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"size","description":"Optional density on the shared `2xs` through `xl` ladder, including the `small`/`medium`/`large` aliases. It changes the trigger and menu-row typography and padding; the 40px default hit-area floor remains in place. Unset preserves the established geometry.\n\nType: `LyraSize | undefined`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}}],"js":{"properties":[{"name":"accessibleLabel","description":"Accessible name forwarded from the host to the native trigger button.\nWhen unset, a nonempty visible `label` provides the name; an empty visible label uses the\nlocalized default. An explicit empty `aria-label` remains authoritative by presence.\n\nAttribute: `aria-label`","type":"string | null","default":"null"},{"name":"appearance","description":"Optional `outlined` or `quiet` trigger treatment. Unset preserves the established surface, border, and text colors.\n\nAttribute: `appearance`  \nReflected to its attribute.","type":"LyraExportButtonAppearance | undefined"},{"name":"bom","description":"Prepends a UTF-8 byte-order mark (U+FEFF) to the built-in CSV download only. Excel on\nWindows ignores a downloaded file's MIME charset and decodes a BOM-less CSV with the\nsystem ANSI code page, so accented, Arabic, CJK, and typographic characters render as\nmojibake; the BOM makes Excel detect UTF-8 and decode correctly. Google Sheets,\nLibreOffice, and Numbers already sniff UTF-8 correctly with or without it. Never applies to\nthe built-in JSON download -- RFC 8259 forbids a BOM there.\n\nAttribute: `bom`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"columns","type":"readonly Readonly<LyraCsvColumn>[]"},{"name":"disabled","description":"Attribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"filename","description":"Attribute: `filename`","type":"string","default":"'export'"},{"name":"formats","description":"Format choices keyed by unique, nonempty `formatId`; the first duplicate wins. An empty or\nfully rejected list disables the trigger because there is no export action to perform.","type":"readonly LyraExportFormatOption[]"},{"name":"getRows","description":"Lazy row source, consulted only when a built-in CSV/JSON download is actually about to be\nbuilt -- after the cancelable `lr-export` event was not prevented, and never for a custom\nformat this component does not serialize itself. When set, it fully replaces rows\nfor that download (the eager property is not merged into or read alongside it), so a\nconsumer holding a large or derived collection elsewhere -- an `<lr-table>`'s `viewRows`,\nsay -- can export exactly what is on screen without copying it into this element first and\nkeeping it live there:\n\n```ts\nexportButton.getRows = () => table.viewRows as readonly Record<string, unknown>[];\n```\n\nA non-array return is treated as no rows, matching how `rows` normalizes one. A callback\nthat throws is reported through `lr-export-error` and the shared failure announcement, the\nsame as any other export that could not be produced -- an export whose data could not be\ncollected has failed, and silently downloading an empty file would hide that.","type":"() => readonly Record<string, unknown>[] | undefined"},{"name":"label","description":"Visible trigger button text. It also feeds the format menu's `aria-label` when no host\n`aria-label` supplies a more specific name. `undefined` uses the localized default; every\nsupplied string, including `''` and `'Export'`, is caller-owned visible copy. An empty or\nwhitespace-only visible label retains the localized default as the trigger's accessible name.\n\nAttribute: `label`","type":"string | undefined"},{"name":"loading","description":"Controlled busy state for async/server-generated exports.\n\nAttribute: `loading`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"open","description":"Attribute: `open`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"rows","description":"Shallow frozen row snapshots. Nested cell values remain caller-owned opaque data.\n\nRead late, not early: the built-in download serializes whatever this holds *after* the\ncancelable `lr-export` event has been dispatched, so a listener may assign `.rows`\nsynchronously inside its own handler and that assignment is the data that gets downloaded.\nA consumer that would rather not keep an eagerly-materialized copy in the element at all\nsets getRows instead, which is consulted at the same point.","type":"readonly Readonly<Record<string, unknown>>[]"},{"name":"size","description":"Optional density on the shared `2xs` through `xl` ladder, including the `small`/`medium`/`large` aliases. It changes the trigger and menu-row typography and padding; the 40px default hit-area floor remains in place. Unset preserves the established geometry.\n\nAttribute: `size`  \nReflected to its attribute.","type":"LyraSize | undefined"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-export","description":"`detail: { format }`, cancelable — call `preventDefault()` to substitute the built-in client-side download with a server-generated one. A listener that lets the built-in download proceed may still supply its data from inside the handler: the rows are read *after* this dispatch, so assigning `.rows` here is honoured, and a `getRows` callback is consulted at the same point.","type":"CustomEvent<{ readonly format: string }>"},{"name":"lr-export-complete","description":"Fired after a non-cancelled download completes.","type":"CustomEvent<{ readonly format: LyraExportFormat }>"},{"name":"lr-export-error","description":"Fired when a built-in CSV/JSON export cannot be serialized or downloaded. `detail: { format, error }`. The same failure is also announced through the shared light-DOM live region and marks the trigger with the `trigger-error` part token, so a screen-reader user and a sighted user both learn the export failed without needing to listen for this event.","type":"CustomEvent<{ readonly format: LyraExportFormat; readonly error: unknown }>"},{"name":"lr-hide","description":"The format menu is about to close. Cancelable on the same terms as `lr-show`. A close this component imposes on itself (disablement, `loading`, or a format list collapsing to one entry) emits no lifecycle event and therefore offers no veto point.","type":"CustomEvent<null>"},{"name":"lr-show","description":"The format menu is about to open, however `open` became true. Cancelable — `preventDefault()` leaves it closed. Not fired for markup that renders open from the start.","type":"CustomEvent<null>"}]}},{"name":"lr-file-icon","description":"Displays a localized, tokenized file-type badge from a MIME type.\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 outer presentation wrapper. |\n| `description` | Consumer-authored metadata description in `mode=\"label\"` mode. |\n| `icon` | The format badge. |\n| `label` | The localized or consumer-authored format label in `mode=\"label\"` mode. |\n| `size` | The formatted `bytes` count, shown alongside `label` in `mode=\"label\"` mode when `bytes` is non-zero. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-file-icon-bg` (default: `var(--lr-color-brand-quiet)`) — Background of the `icon` part. Every file category renders the same fill; retint it without hijacking `--lr-color-brand-quiet` library-wide.\n- `--lr-file-icon-color` (default: `var(--lr-color-brand)`) — Text/glyph color of the `icon` part.\n- `--lr-file-icon-size` (default: `var(--lr-size-2rem)`) — Inline/block size of the format badge.","attributes":[{"name":"bytes","description":"File size **in bytes**, shown alongside the label in `mode=\"label\"` mode. `0` (the default)\nrenders no size. Named `bytes`, not `size`: everywhere else in this library `size` names a tier\non the shared size ladder, and a numeric byte count answering to the same property name is the\nkind of collision a consumer only discovers at runtime.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"decorative","description":"Whether the badge is decorative and hidden from assistive technology.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"label","description":"Optional visible/accessibility label override. Explicit empty text is preserved for the\nvisible `mode=\"label\"` text, but never leaves a non-decorative `role=\"img\"` unnamed -- the\ncomputed accessible name falls back to the resolved file-type metadata label instead.\n\nType: `string | undefined`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"mime-type","description":"MIME type used to resolve metadata. Also exposed as a `title` tooltip on the badge.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"mode","description":"Type: `LyraFileIconMode`","value":{"type":["'icon'","'label'"]}},{"name":"name","description":"Optional filename used for fallback detection with an empty or generic MIME type.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"js":{"properties":[{"name":"bytes","description":"File size **in bytes**, shown alongside the label in `mode=\"label\"` mode. `0` (the default)\nrenders no size. Named `bytes`, not `size`: everywhere else in this library `size` names a tier\non the shared size ladder, and a numeric byte count answering to the same property name is the\nkind of collision a consumer only discovers at runtime.\n\nAttribute: `bytes`","type":"number","default":"0"},{"name":"decorative","description":"Whether the badge is decorative and hidden from assistive technology.\n\nAttribute: `decorative`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"label","description":"Optional visible/accessibility label override. Explicit empty text is preserved for the\nvisible `mode=\"label\"` text, but never leaves a non-decorative `role=\"img\"` unnamed -- the\ncomputed accessible name falls back to the resolved file-type metadata label instead.\n\nAttribute: `label`","type":"string | undefined"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"mimeType","description":"MIME type used to resolve metadata. Also exposed as a `title` tooltip on the badge.\n\nAttribute: `mime-type`","type":"string","default":"''"},{"name":"mode","description":"Attribute: `mode`  \nReflected to its attribute.","type":"LyraFileIconMode"},{"name":"name","description":"Optional filename used for fallback detection with an empty or generic MIME type.\n\nAttribute: `name`","type":"string","default":"''"},{"name":"registry","description":"Immutable metadata authority for this instance.","type":"LyraFileTypeMetadataRegistry","default":"defaultFileTypeMetadataRegistry"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}]}},{"name":"lr-file-input","description":"`<lr-file-input>` — a drag-drop + click-to-browse file dropzone. Emits\nraw `File[]`; parsing (CSV/XLSX/etc.) is left to the host, since that's\nwhere files ultimately get uploaded and processed anyway.\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 part `base`: Deprecated since `8.2.3`. Use part `::part(file-input)`. Removal is not permitted before `10.0.0`. The file-input part names the interactive picker surface; base remains on that same node during the compatibility window. That version is a policy floor, not a plan: `wa-file-input` still publishes its own deprecated `base` part, so this alias is removed only when upstream's is.\n- Deprecated part `label`: Deprecated since `8.2.3`. Use part `::part(form-control-label)`. Removal is not permitted before `10.0.0`. The form-control-label part follows the shared form-control vocabulary; label remains on that same node during the compatibility window. That version is a policy floor, not a plan: `wa-file-input` still publishes its own deprecated `label` part, so this alias is removed only when upstream's is.\n\n---\n\n**Slots**\n\n| Name | Description |\n| --- | --- |\n| (default) | Custom drop-zone content, overrides the visible `label` text. The accessible name comes from a host `aria-label` when present, then falls back to `label`, so icon-only slot content remains announced correctly. |\n| `dropzone` | Named equivalent of the default dropzone-content slot. |\n| `error` | Custom validation error content. Use `with-error` when this slot is populated in server-rendered declarative shadow DOM before light-DOM slot assignment is observable. |\n| `hint` | Custom form-control hint content. |\n| `label` | Custom form-control label content. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | Deprecated in 8.2.3; compatibility name for `file-input`; both names are on the native dropzone button, visually backing the slotted content while remaining its sibling in the accessibility tree so arbitrary slotted controls are never nested in it. |\n| `dropzone` | The drag/drop and paste target around the semantic button. |\n| `dropzone-icon` | The default decorative file icon. |\n| `dropzone-text` | Wrapper around dropzone slot/text content. |\n| `error` | The visible validation message or authored error content. |\n| `file` | One selected-file row. |\n| `file-details` | Filename and formatted-size wrapper. |\n| `file-icon` | Generic icon for a non-image file. |\n| `file-image` | Image preview for an image file. |\n| `file-input` | The interactive picker surface. |\n| `file-list` | The current selected-file list. |\n| `file-name` | Selected filename. |\n| `file-size` | Localized selected-file size. |\n| `file-thumbnail` | One selected file's thumbnail/icon wrapper. |\n| `form-control` | The complete label, dropzone, selected-file, error, and hint frame. |\n| `form-control-label` | The form-control label. |\n| `hint` | The form-control hint. |\n| `input` | The visually-hidden native `<input type=\"file\">`. |\n| `label` | Deprecated in 8.2.3; compatibility name for `form-control-label`; both names are on the same node. |\n| `rejection` | The visible region listing each currently-rejected file alongside its reason, rendered in addition to (never in place of) the sr-only `status` summary. Its text stays in the accessibility tree as ordinary visible content; the interrupting announcement it used to make as a shadow `role=\"alert\"` now goes through the shared light-DOM assertive region instead. |\n| `remove-button` | Removes one selected file. |\n| `status` | The visually-hidden, `aria-hidden` mirror of the drag accept/reject state and accepted/rejected selection counts. The announcement itself lands in the shared light-DOM polite region (`acquireAnnouncementSink()` in `internal/announcer.ts`) — a live region inside a shadow root is not reliably announced — so this part is a styling/inspection surface only. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-file-input-accept-bg` (default: `color-mix(in srgb, var(--lr-color-success) 8%, transparent)`) — Background of `[part~=\"base\"][data-drag-state=\"accept\"]`.\n- `--lr-file-input-accept-border-color` (default: `var(--lr-color-success)`) — Border color of `[part~=\"base\"][data-drag-state=\"accept\"]`.\n- `--lr-file-input-compact-font-size` (default: `var(--lr-font-size-sm)`) — Label font size while `compact`.\n- `--lr-file-input-compact-gap` (default: `var(--lr-space-2xs)`) — Gap between the dropzone's slotted children while `compact`.\n- `--lr-file-input-compact-padding` (default: `var(--lr-space-s)`) — `[part~=\"base\"]` padding while `compact`.\n- `--lr-file-input-detail-font-size` (default: `var(--lr-font-size-sm)`) — Size of the secondary text: the hint, the validation error, and each selected file's formatted size. Retuned per `size` tier.\n- `--lr-file-input-dropzone-border-color` (default: `var(--lr-color-border)`) — Resting dropzone border color. The dashed border style is unchanged.\n- `--lr-file-input-dropzone-fill` (default: `var(--lr-color-surface)`) — Resting dropzone background, the state it spends most of its life in. The drag accept/reject tints have had their own hooks since 12.0.0; this one completes the set.\n- `--lr-file-input-dropzone-font-size` (default: `var(--lr-font-size-md-sm)`) — Instructional text size inside the dropzone. Retuned per `size` tier; the documented default is the `m`/`medium` tier.\n- `--lr-file-input-dropzone-hover-border-color` (default: `var(--lr-color-brand)`) — Dropzone border color while the pointer is over it, whether over the button or over the content stacked on it.\n- `--lr-file-input-dropzone-icon-size` (default: `var(--lr-font-size-xl)`) — `[part=\"dropzone-icon\"]` glyph size. Retuned per `size` tier.\n- `--lr-file-input-dropzone-padding` (default: `var(--lr-space-l)`) — Padding inside `[part~=\"base\"]` and the stacked dropzone content. Retuned per `size` tier; `compact` overrides it.\n- `--lr-file-input-font-size` (default: `var(--lr-form-control-font-size)`) — Label and selected-filename text size; tracks the shared `size` ladder.\n- `--lr-file-input-gap` (default: `var(--lr-space-xs)`) — Gap between the dropzone's slotted children. While `compact`, this is the fallback when `--lr-file-input-compact-gap` is unset.\n- `--lr-file-input-radius` (default: `var(--lr-radius)`) — Corner radius of `[part~=\"base\"]`.\n- `--lr-file-input-reject-bg` (default: `color-mix(in srgb, var(--lr-color-danger) 8%, transparent)`) — Background of `[part~=\"base\"][data-drag-state=\"reject\"]`.\n- `--lr-file-input-reject-border-color` (default: `var(--lr-color-danger)`) — Border color of `[part~=\"base\"][data-drag-state=\"reject\"]`.\n- `--lr-form-control-focus-shadow` (default: `none`) — The shared field focus halo, painted as a `box-shadow` while this control is focused. One name for every field-shaped control in the library, so a halo is configured once rather than per component. Additive: the focus outline and border cue are the accessibility answer to focus and are never replaced by it.\n- `--lr-form-control-required-color` (default: `var(--lr-color-danger)`) — Required-marker color, themeable independently of error text and invalid borders.\n- `--lr-form-control-required-content` (default: `' *'`) — The required marker appended to `form-control-label` while `required` is set. Set it to `''` to suppress the marker, or to any other quoted string (`' (required)'`, a localized word) to replace it.\n- `--lr-form-control-required-offset` (default: `0`) — Inline space between the label text and the required marker.","attributes":[{"name":"accept","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"accepted-message","description":"Message announced after an accepted selection; `{count}` is replaced by the number of\naccepted files. `undefined` uses the localized singular/plural default; every supplied\nstring, including `''` and the former English default, is caller-owned.\n\nType: `string | undefined`"},{"name":"accessible-label","description":"Accessible name forwarded to the semantic dropzone and native file input.\nWhen unset, the effective `label` text is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"capture","description":"Mobile capture hint forwarded to the native file picker.\n\nType: `LyraFileInputCapture`  \nDefault: `''`","value":{"type":["''","'user'","'environment'"]}},{"name":"compact","description":"Tighter dropzone padding, gap and label font for constrained spaces (a toolbar, a table cell)\n-- same convention as `lr-empty`'s `compact`. Defaults to `false`, i.e. the full `--lr-space-l`\ndropzone. The dashed border stays; only the internal spacing shrinks.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"custom-error","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nType: `string | null`"},{"name":"directory","description":"Enables directory selection through the browser's native picker.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"disabled","description":"Disables every interactive sub-control.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"error-text","description":"Plain-text validation error. A custom-validity message is shown when this is empty.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"form","description":"Type: `HTMLFormElement | string | null`  \nDefault: `null`"},{"name":"held-file-count","description":"Externally held file count added to the running count `maxFiles` evaluates against, in both\nretaining and `nonRetaining` modes -- the numeric counterpart of `valuePresent`, for a\ncumulative cap that spans separate picker sessions (e.g. a server-backed upload limit) rather\nthan resetting to what this control alone can see. `0` (the default) means \"nothing held\" and\nreproduces prior behavior exactly. A negative, `NaN`, or `Infinity` value is normalized to `0`\nvia `finiteCount` -- an invalid baseline degrades to \"nothing held\" rather than corrupting\nevery later comparison or permanently blocking every future file.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"held-total-size","description":"Externally held byte total added to the running size `maxTotalSize` evaluates against, in\nboth retaining and `nonRetaining` modes. Same contract, default, and invalid-input\nnormalization as `heldFileCount`.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"hint","description":"Optional hint copy. Removing the attribute removes its text and description association.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"label","description":"Form-control label. Empty or removed leaves the localized dropzone instruction as the visible fallback.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max-file-size","description":"Largest accepted file size in bytes. `0` (the default) disables the size check entirely --\nsee `effectiveMaxFileSize` for how an invalid override is handled.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"max-files","description":"Largest total number of files accepted, counting retained files (unless `nonRetaining`) plus\n`heldFileCount` plus the current batch. `0` (the default) disables the check. Same\nrejection-UI shape as `maxFileSize`: an excess file in the batch is rejected with reason\n`'maxFiles'` and appears in `[part=\"rejection\"]` alongside any other rejection, rather than\nfailing the whole selection. An invalid override (negative, `NaN`) falls back to a sane cap\nrather than silently accepting an unlimited count -- see `effectiveMaxFiles`.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"max-total-size","description":"Largest combined byte size accepted, summing retained files (unless `nonRetaining`) plus\n`heldTotalSize` plus the current batch. `0` (the default) disables the check. Same\nrejection-UI shape and invalid-override fallback as `maxFileSize` -- see\n`effectiveMaxTotalSize`.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"multiple","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"name","description":"Submitted field name.\n\nType: `string | null`  \nDefault: `null`"},{"name":"non-retaining","description":"Opt-in mode where an accepted selection still fires `lr-files`/`input`/`change` but is never\nwritten to `files` or rendered as a built-in `[part=\"file\"]` row -- for a host that persists\nfiles elsewhere and renders its own list, so assigning `files` (even to reset it) never fights\nthat host-owned rendering. `required` validity and the `blank` state read `valuePresent`\ninstead of `files.length` while this is set. Does not affect `formStateRestoreCallback()` or a\ndirect `files` assignment, both of which still retain.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"paste","description":"Enables files pasted from the clipboard into the dropzone. `true`-defaulting, so a plain\n`paste=\"false\"` attribute (not just a `.paste=${false}` property binding) actually disables it.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"rejected-message","description":"Message announced after rejected files; `{count}` is replaced by the number of rejected\nfiles. `undefined` uses the localized singular/plural default; every supplied string,\nincluding `''` and the former English default, is caller-owned.\n\nType: `string | undefined`"},{"name":"required","description":"Requires at least one selected file.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"size","description":"Type: `LyraSize`  \nDefault: `'m'`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}},{"name":"value-present","description":"External \"a value is present\" signal for a `nonRetaining` host to set once it has taken\nownership of the selected files, so `required` validity and the `blank` state reflect\nexternally-held files instead of the always-empty internal list. Ignored while `nonRetaining`\nis `false`.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"with-error","description":"SSR slot-presence hint for rich error content.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"with-hint","description":"SSR slot-presence hint for hint content.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"with-label","description":"SSR slot-presence hint for label content.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"","description":"Custom drop-zone content, overrides the visible `label` text. The accessible name comes from a host `aria-label` when present, then falls back to `label`, so icon-only slot content remains announced correctly."},{"name":"dropzone","description":"Named equivalent of the default dropzone-content slot."},{"name":"error","description":"Custom validation error content. Use `with-error` when this slot is populated in server-rendered declarative shadow DOM before light-DOM slot assignment is observable."},{"name":"hint","description":"Custom form-control hint content."},{"name":"label","description":"Custom form-control label content."}],"js":{"properties":[{"name":"accept","description":"Attribute: `accept`","type":"string","default":"''"},{"name":"acceptedMessage","description":"Message announced after an accepted selection; `{count}` is replaced by the number of\naccepted files. `undefined` uses the localized singular/plural default; every supplied\nstring, including `''` and the former English default, is caller-owned.\n\nAttribute: `accepted-message`","type":"string | undefined"},{"name":"accessibleLabel","description":"Accessible name forwarded to the semantic dropzone and native file input.\nWhen unset, the effective `label` text is used.\n\nAttribute: `accessible-label`","type":"string","default":"''"},{"name":"allowedMimeTypes","description":"Exact MIME allowlist. Assignment takes a bounded immutable snapshot.","type":"readonly string[]"},{"name":"capture","description":"Mobile capture hint forwarded to the native file picker.\n\nAttribute: `capture`","type":"LyraFileInputCapture","default":"''"},{"name":"compact","description":"Tighter dropzone padding, gap and label font for constrained spaces (a toolbar, a table cell)\n-- same convention as `lr-empty`'s `compact`. Defaults to `false`, i.e. the full `--lr-space-l`\ndropzone. The dashed border stays; only the internal spacing shrinks.\n\nAttribute: `compact`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"customError","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nAttribute: `custom-error`  \nReflected to its attribute.","type":"string | null"},{"name":"directory","description":"Enables directory selection through the browser's native picker.\n\nAttribute: `directory`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"disabled","description":"Disables every interactive sub-control.\n\nAttribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"dragging","description":"Readonly state derived from the current drag session.","type":"boolean","default":"false","read-only":true},{"name":"effectiveDisabled","type":"boolean","read-only":true},{"name":"errorText","description":"Plain-text validation error. A custom-validity message is shown when this is empty.\n\nAttribute: `error-text`","type":"string","default":"''"},{"name":"fileCount","description":"Readonly selected-file count derived from `files`.","type":"number","default":"0","read-only":true},{"name":"files","description":"Selected files. Programmatic writes are silent but immediately synchronize rendering/forms.","type":"File[]","default":"[]"},{"name":"forbiddenMimeTypes","description":"Exact MIME denylist, evaluated before `allowedMimeTypes`. Assignment takes a bounded\nimmutable snapshot.","type":"readonly string[]"},{"name":"form","description":"Attribute: `form`  \nReflected to its attribute.","type":"HTMLFormElement | string | null","default":"null"},{"name":"heldFileCount","description":"Externally held file count added to the running count `maxFiles` evaluates against, in both\nretaining and `nonRetaining` modes -- the numeric counterpart of `valuePresent`, for a\ncumulative cap that spans separate picker sessions (e.g. a server-backed upload limit) rather\nthan resetting to what this control alone can see. `0` (the default) means \"nothing held\" and\nreproduces prior behavior exactly. A negative, `NaN`, or `Infinity` value is normalized to `0`\nvia `finiteCount` -- an invalid baseline degrades to \"nothing held\" rather than corrupting\nevery later comparison or permanently blocking every future file.\n\nAttribute: `held-file-count`","type":"number","default":"0"},{"name":"heldTotalSize","description":"Externally held byte total added to the running size `maxTotalSize` evaluates against, in\nboth retaining and `nonRetaining` modes. Same contract, default, and invalid-input\nnormalization as `heldFileCount`.\n\nAttribute: `held-total-size`","type":"number","default":"0"},{"name":"hint","description":"Optional hint copy. Removing the attribute removes its text and description association.\n\nAttribute: `hint`","type":"string","default":"''"},{"name":"label","description":"Form-control label. Empty or removed leaves the localized dropzone instruction as the visible fallback.\n\nAttribute: `label`","type":"string","default":"''"},{"name":"labels","type":"NodeList","read-only":true},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"maxFileSize","description":"Largest accepted file size in bytes. `0` (the default) disables the size check entirely --\nsee `effectiveMaxFileSize` for how an invalid override is handled.\n\nAttribute: `max-file-size`","type":"number","default":"0"},{"name":"maxFiles","description":"Largest total number of files accepted, counting retained files (unless `nonRetaining`) plus\n`heldFileCount` plus the current batch. `0` (the default) disables the check. Same\nrejection-UI shape as `maxFileSize`: an excess file in the batch is rejected with reason\n`'maxFiles'` and appears in `[part=\"rejection\"]` alongside any other rejection, rather than\nfailing the whole selection. An invalid override (negative, `NaN`) falls back to a sane cap\nrather than silently accepting an unlimited count -- see `effectiveMaxFiles`.\n\nAttribute: `max-files`","type":"number","default":"0"},{"name":"maxTotalSize","description":"Largest combined byte size accepted, summing retained files (unless `nonRetaining`) plus\n`heldTotalSize` plus the current batch. `0` (the default) disables the check. Same\nrejection-UI shape and invalid-override fallback as `maxFileSize` -- see\n`effectiveMaxTotalSize`.\n\nAttribute: `max-total-size`","type":"number","default":"0"},{"name":"multiple","description":"Attribute: `multiple`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"name","description":"Submitted field name.\n\nAttribute: `name`  \nReflected to its attribute.","type":"string | null","default":"null"},{"name":"nonRetaining","description":"Opt-in mode where an accepted selection still fires `lr-files`/`input`/`change` but is never\nwritten to `files` or rendered as a built-in `[part=\"file\"]` row -- for a host that persists\nfiles elsewhere and renders its own list, so assigning `files` (even to reset it) never fights\nthat host-owned rendering. `required` validity and the `blank` state read `valuePresent`\ninstead of `files.length` while this is set. Does not affect `formStateRestoreCallback()` or a\ndirect `files` assignment, both of which still retain.\n\nAttribute: `non-retaining`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"paste","description":"Enables files pasted from the clipboard into the dropzone. `true`-defaulting, so a plain\n`paste=\"false\"` attribute (not just a `.paste=${false}` property binding) actually disables it.\n\nAttribute: `paste`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"rejectedMessage","description":"Message announced after rejected files; `{count}` is replaced by the number of rejected\nfiles. `undefined` uses the localized singular/plural default; every supplied string,\nincluding `''` and the former English default, is caller-owned.\n\nAttribute: `rejected-message`","type":"string | undefined"},{"name":"required","description":"Requires at least one selected file.\n\nAttribute: `required`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"size","description":"Attribute: `size`  \nReflected to its attribute.","type":"LyraSize","default":"'m'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"validationMessage","type":"string","read-only":true},{"name":"validationTarget","description":"Constraint-validation popup anchor. The focusable base of the dropzone control is the\ndefault after first render; assign another shadow descendant to override the anchor, or\n`undefined` to restore the default.","type":"HTMLElement | undefined"},{"name":"validators","description":"Additional JavaScript validators run after the intrinsic `required` constraint — the same\ncontract `lr-date-input` and `lr-combobox` implement. Accepts a function, an object with\n`validate(value, input)`, or the mapped object-validator shape with `checkValidity(input)` and\n`{ isValid, message, invalidKeys }` results. The value handed to a function/`validate()`\nvalidator is the current `files` array. Object validators can list host `observedAttributes`\nthat should trigger live revalidation. A validator that throws fails closed with the generic\nlocalized message. Barred (own or fieldset-cascaded `disabled`) exactly like the intrinsic\nconstraint.","type":"LyraFileInputValidator[]","default":"[]"},{"name":"validity","type":"ValidityState","read-only":true},{"name":"valuePresent","description":"External \"a value is present\" signal for a `nonRetaining` host to set once it has taken\nownership of the selected files, so `required` validity and the `blank` state reflect\nexternally-held files instead of the always-empty internal list. Ignored while `nonRetaining`\nis `false`.\n\nAttribute: `value-present`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"willValidate","type":"boolean","read-only":true},{"name":"withError","description":"SSR slot-presence hint for rich error content.\n\nAttribute: `with-error`","type":"boolean","default":"false"},{"name":"withHint","description":"SSR slot-presence hint for hint content.\n\nAttribute: `with-hint`","type":"boolean","default":"false"},{"name":"withLabel","description":"SSR slot-presence hint for label content.\n\nAttribute: `with-label`","type":"boolean","default":"false"}],"events":[{"name":"blur","description":"Fired when the semantic dropzone loses focus; bubbling, composed, and non-cancelable.","type":"FocusEvent"},{"name":"change","description":"Native event fired after `input` when user interaction changes `files`; bubbling, composed, and non-cancelable.","type":"Event"},{"name":"focus","description":"Fired when the semantic dropzone receives focus; bubbling, composed, and non-cancelable.","type":"FocusEvent"},{"name":"input","description":"Native event fired before `change` when user interaction changes `files`; bubbling, composed, and non-cancelable.","type":"Event"},{"name":"lr-files","description":"Frozen `detail: { files, rejected, remainingFiles, remainingTotalSize }` with detached readonly sequences and rejected-file records, fired on drop and manual selection. `remainingFiles`/`remainingTotalSize` report the allowance still left under `maxFiles`/ `maxTotalSize` after this batch (`null` while that limit is unset). Immutable `File` items retain identity. Typed as {@linkcode LyraFileInputFilesEvent}, so `event.target`/`event.currentTarget` are `LyraFileInput` without a cast. Still fires while `nonRetaining` is set, even though `files` itself is never written in that mode.","type":"LyraFileInputFilesEvent"},{"name":"lr-invalid","description":"The file input failed a validity check. Cancelable: calling `preventDefault()` also cancels the native `invalid` event behind it, suppressing the browser's own validation bubble so an app can present the failure its own way.","type":"CustomEvent<null>"}]}},{"name":"lr-file-tree","description":"`<lr-file-tree>` — a file-explorer preset over `<lr-tree>` + `<lr-file-icon>`: path-keyed\nnodes with git-status/diff-count badges, lazy directory loading, and select/open events.\n\n**The composed `<lr-tree>`'s `reorderable`/`lr-reorder` capability is deliberately not\nforwarded.** The tree it renders is not a model this component owns: `treeItems` is derived\nfrom `nodes` on every render and keyed by filesystem path, so sibling order is whatever the\nhost's own listing produced (name, type, git status), not an authored sequence a user can\nrearrange. `<lr-tree>`'s reorder is also strictly sibling-scoped — it never crosses a subtree\nboundary, precisely so a reorder can never become a reparent — which is the one file operation\n(\"move this file into that directory\") that would change a path and therefore mean something\nhere. Forwarding it would have to invent a second, path-shaped event alongside\n`lr-file-select`/`lr-file-open`/`lr-load-children`, permanently, for a gesture whose result the\nhost would have to discard. A consumer that genuinely needs orderable rows composes `<lr-tree>`\ndirectly, where the capability already lives.\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 root wrapper. |","attributes":[{"name":"label","description":"Accessible-name override for the internal `<lr-tree>`; falls back to the localized default\nwhen unset. An explicitly empty string renders as an empty label rather than falling back.\n\nType: `string | undefined`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"selected-path","description":"Type: `string | null`  \nDefault: `null`"}],"js":{"properties":[{"name":"label","description":"Accessible-name override for the internal `<lr-tree>`; falls back to the localized default\nwhen unset. An explicitly empty string renders as an empty label rather than falling back.\n\nAttribute: `label`","type":"string | undefined"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"nodes","description":"Clone-owned, cycle-safe readonly node snapshot. Empty/blank paths are omitted and duplicate\npaths use the first valid node; projection inspects at most 10,000 source positions across 64\ndescendant levels. An unreadable optional field rejects only its node, without reserving the\npath against a later valid occurrence. Reassign after changes.","type":"readonly FileTreeNode[]"},{"name":"selectedPath","description":"Attribute: `selected-path`","type":"string | null","default":"null"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-file-open","description":"`detail: { filePath, node }` — Enter/click on an already-selected file row (keyboard-open parity: a second activation of the same file opens it).","type":"CustomEvent<Readonly<{ filePath: string; node: FileTreeNode }>>"},{"name":"lr-file-select","description":"`detail: { filePath, node }` — a row was activated.","type":"CustomEvent<Readonly<{ filePath: string; node: FileTreeNode }>>"},{"name":"lr-load-children","description":"`detail: { filePath }` — a lazy (hasChildren, unloaded) directory expanded.","type":"CustomEvent<Readonly<{ filePath: string }>>"}]}},{"name":"lr-filter-bar","description":"`<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 (which filters that row admits is\n`activeFiltersDisplay`'s own contract; removing a chip always clears that filter, regardless of\nwhich chips the row is currently showing), an `<lr-button>` that resets every filter, and (while\n`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. A `'combobox'` filter may declare the same `debounce`, coalescing a burst\nof rapid picks into one delayed commit; unlike `'text'` its `.value=` binding stays fully\ncontrolled, rendering the pending selection in place of the last-committed `value` for as long\nas the commit is delayed. A `'custom'` definition may declare the same `debounce` too, applied to\nwhatever its adapter's `valueFromEvent` reads off `context.onValueChange`/`onInput`/`onChange`,\nwith identical flush-on-`context.onFocusout` and cancel-on-`reset()`/chip-removal/disconnect\nsemantics -- so a custom free-text filter no longer has to hand-roll that timer itself just to\nmatch what `'text'` already does. Every built-in (non-`'custom'`) type also accepts optional\n`size`/`icon`/`labelVisibility`, and every one whose composed control ships a clear action also\naccepts `clearable` -- forwarded verbatim to that control's own same-named property (`icon` into\nits `start` slot exactly like `LyraFilterBarOption.icon`; `clearable` reaching\n`<lr-date-input>` under its `with-clear` spelling). `'text'` adds `inputType`, `'combobox'` adds\n`emptyText`, and an option may carry `searchText` -- which only `<lr-combobox>` reads, since\n`<lr-select>`'s type-ahead matches on the option label alone. `labelVisibility: 'hidden'` routes `label` to\nthe composed control's own `aria-label` and, with no declared `placeholder`, to its placeholder,\nso a compact toolbar row still names every field. Every one of these is optional and defaults to\nthat composed control's own default, so an existing filter definition renders unchanged.\n\nA `'checkbox-menu'` filter is the one built-in type whose composed control is not a field:\n`<lr-dropdown>` plus one `<lr-dropdown-item type=\"checkbox\">` per option, behind a single\ntoolbar trigger that carries the label as its own text (no stacked label above it) and a menu\nthat stays open across toggles. Its value is a `string[]`, identical to a `'combobox'` with\n`multiple`, so the two are interchangeable everywhere the bar's own bookkeeping is concerned --\nchoose between them on interaction, not on data shape. Because its trigger is a button rather\nthan a field, it deliberately renders no required marker and sets no `aria-invalid`: the\nlibrary's shared `formControlRequiredMarker` has no selector that matches a button trigger's\nlabel, and `<lr-button>` does not forward a host `aria-invalid` onto the element that owns the\nbutton role, so writing one would be silently inert. A revealed `required` error still reaches\nassistive technology, as a screen-reader-only run inside the trigger's accessible name.\n\nA `'chip'` filter is the one type that composes no control at all. Its value is owned by a widget\nelsewhere on the page -- a calendar heatmap cell, a map selection, a chart brush -- so the bar\nrenders no field for it and it claims no toolbar cell (no `field` wrapper, and therefore no blank\ncolumn where an empty one's validation spacer would otherwise reserve a row of height). It is a\nfilter in every other sense: it lives in `value` under its own `filterId`, rides every\n`lr-input`/`lr-reset` detail, counts toward `hasActiveFilters` (so it enables the reset button,\nwhich is exactly the \"clear all\" action an all-chip bar needs) and `invalidFilterIds`, renders a\nremovable active-filter chip subject to `activeFiltersDisplay`, and is cleared by a chip removal\nand by `reset()` alongside every other filter. Its chip text comes from an optional\n`formatValue(value, locale)` receiving `effectiveLocale` -- the same locale every built-in type's\nown chip formatting and a custom adapter's `formatValue` already receive; omitted, a string array\nformats as a localized conjunction list and anything else renders `String(value)` verbatim, never\nthrough the date branch that would reformat an ISO day or mangle a value containing a slash.\n`clearValue` (default `''`) is what a chip removal writes; a domain sentinel must be paired with\n`isEmpty`, exactly as a custom adapter's own `clearValue`/`isEmpty` are. Its inherited\n`placeholder` is inert (there is no field to place it in), as it already is for `'custom'`, and\nits inherited `required` is honoured in bookkeeping only: a required-but-empty chip filter joins\n`invalidFilterIds`/`checkValidity()`/`lr-validity-change` but renders no inline error, since this\ncomponent renders no element of its own on which one could appear.\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**Slots**\n\n| Name | Description |\n| --- | --- |\n| `end` | Extra host-supplied controls rendered inside `controls`, next to the reset button (for example, a \"Save search\" or \"Export\" action) -- this component renders no default content into it. |\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 `activeFiltersDisplay` admits at least one currently-active filter (never, for `'hidden'`). |\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 `end` slot, the reset button, and the loading status. |\n| `end` | Wrapper around the `end` slot; hidden while nothing is slotted. |\n| `field` | The wrapper around one filter's composed control and its validation spacer; its flex-basis is `--lr-filter-bar-field-basis`. Also carries a second, per-filter token, `field-<filterId>` (for example `part=\"field field-status\"`), so a consumer can target one field's own wrapper -- `lr-filter-bar::part(field-status) { flex: 2 1 20rem; }` -- and set any layout property, not just width, without affecting `::part(field)` rules that still match every field. The `field-<filterId>` token is omitted (the wrapper renders `part=\"field\"` alone) when `filterId` is not a plain CSS ident (ASCII letters/digits/`-`/`_`, starting with a letter) -- `part` is a space-separated token list like `class`, so an id containing whitespace would otherwise silently fabricate an unrelated second token (including, in the worst case, one colliding with a real part name like `active-filters`). A `'chip'` filter renders no `field` wrapper at all, so neither `::part(field)` nor `::part(field-<filterId>)` ever matches one -- its only rendered surface is its active-filter `chip`. |\n| `filter-control` | One filter's composed built-in control, or the wrapper around a custom renderer's control (and around a `'checkbox-menu'`'s dropdown plus its error line). |\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. A `'checkbox-menu'` renders this one itself (its composed dropdown has no error chrome), `aria-hidden` because the same text also joins the trigger's accessible name -- an idref cannot cross into that button's own shadow root. |\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, or a `'checkbox-menu'` trigger's own `with-caret` disclosure chevron. |\n| `filter-control-field` | A built-in control's field frame: select trigger, combobox container, text/date input wrapper, or a `'checkbox-menu'` trigger button's own frame (the element inside `<lr-button>` that draws the border, background and radius -- not the chrome-less button host). |\n| `filter-control-hint` | A built-in control's hint message. |\n| `filter-control-input` | A built-in control's display or editable input, or a `'checkbox-menu'` trigger's selection summary. |\n| `filter-control-label` | A built-in control's label element. On a `'checkbox-menu'` this is the trigger button's own label text rather than a stacked label above the control, and it is visually hidden (never removed) under `labelVisibility: 'hidden'` -- except in the one case where the trigger's selection summary already IS the label (hidden routing, no declared `placeholder`, nothing selected), where it is omitted rather than naming the button twice. Under `labelVisibility: 'auto'` this component clips the same element itself once the bar's own allocation drops below `30rem`, and leaves it untouched above that -- so a consumer rule targeting this part sees a visible element at a wide allocation and a hairline, still-named one at a narrow one. |\n| `filter-control-label-group` | A `'checkbox-menu'` trigger's composed `<lr-button>`'s own label wrapper: the flex row laying out `filter-control-label` and `filter-control-input` beside each other and, with `with-caret`, growing to fill the stretched trigger so its content starts at the leading edge instead of centring. No other filter type renders this part -- every other type's label and input are two independent elements with no shared wrapper of their own. |\n| `filter-control-listbox` | A select or combobox options popover, or a `'checkbox-menu'`'s popup surface. |\n| `filter-control-option` | A select or combobox option row, or a `'checkbox-menu'`'s `role=\"menuitemcheckbox\"` row. |\n| `filter-control-popup` | A date input's positioned calendar popup. |\n| `filter-control-start` | A built-in control's start adornment wrapper, including a `'checkbox-menu'` trigger button's own. |\n| `filter-control-tag` | A combobox's individual selected tag. |\n| `filter-control-tag-label` | A combobox tag's wrapping/ellipsis-safe label; capped by that control's own `--tag-max-size`. |\n| `filter-control-tag-remove-button` | A combobox tag's own remove button. |\n| `filter-control-tag-remove-button-base` | Compatibility name for the icon wrapper inside a combobox tag's remove button; the same reach a standalone `lr-combobox`/`lr-select` consumer already has. |\n| `filter-control-tags` | A combobox's multi-select tag container. |\n| `reset-button` | The reset `<lr-button>`. |\n| `status` | The loading `<lr-spinner>`, only rendered while `loading`. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-filter-bar-field-basis` (default: `var(--lr-size-12rem)`) — Flex-basis of each filter's `field` wrapper, controlling how many fields fit per row before the row wraps.\n- `--lr-filter-bar-gap` (default: `var(--lr-space-s)`) — Gap between filter fields, the `end` slot, the reset button, and the loading status in the `controls` row.","attributes":[{"name":"active-filters-display","description":"Which currently-active filters render as removable chips in the row below the fields.\n`'all'` (default, and the only behaviour this component had before this property existed)\nshows one chip per filter that is not empty -- including a filter sitting at its own\n`defaultValue`, since a declared default is itself a value the filter currently holds.\n`'changed'` shows a chip only for a filter whose current value differs from its own\n`defaultValue` (see `filterValueEqualsDefault`) -- so a bar whose defaults narrow the view on\nload does not claim the user narrowed it, while a filter with no declared `defaultValue`\ncounts as changed the moment it has any value at all, since there is nothing for it to still\nequal. `'hidden'` never renders the row, regardless of any filter's state. Every value other\nthan `'changed'`/`'hidden'` (including a foreign attribute value) behaves like `'all'`,\nmatching `labelVisibility`'s own foreign-value handling. Removing a chip always clears that\nfilter, exactly as it always has -- this property only changes which already-active filters\nget a chip in the row, never what removing one does.\n\n`'changed'` additionally gates the reset button on `hasChangedFilters` rather than\n`hasActiveFilters`, so an untouched defaults-only bar -- which renders no chip in this mode --\nno longer offers an enabled reset that would change nothing. `hasActiveFilters` itself is\nunaffected by this property in every mode, and so is reset enablement under `'all'`/`'hidden'`.\n\nType: `LyraFilterBarActiveFiltersDisplay`  \nDefault: `'all'`","value":{"type":["'all'","'changed'","'hidden'"]}},{"name":"disabled","description":"Disables every composed filter control and the reset button. Plain property -- see the\nclass doc for why this component isn't form-associated / fieldset-cascaded.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"label","description":"Accessible-name fallback for the root `role=\"group\"` wrapper when the host has no\n`aria-label`, matching `<lr-control-group>`. Attribute presence wins, including an\nexplicitly empty `aria-label`.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"loading","description":"Shows the `status` spinner. Purely presentational -- filters stay editable while `loading`,\nsince a host typically wants a user to keep refining filters while a previous query is\nstill in flight; only the reset button (which would otherwise race a fresh, unrequeried\nreset against an in-flight fetch for the *previous* value) is disabled by it.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"slots":[{"name":"end","description":"Extra host-supplied controls rendered inside `controls`, next to the reset button (for example, a \"Save search\" or \"Export\" action) -- this component renders no default content into it."}],"js":{"properties":[{"name":"activeFiltersDisplay","description":"Which currently-active filters render as removable chips in the row below the fields.\n`'all'` (default, and the only behaviour this component had before this property existed)\nshows one chip per filter that is not empty -- including a filter sitting at its own\n`defaultValue`, since a declared default is itself a value the filter currently holds.\n`'changed'` shows a chip only for a filter whose current value differs from its own\n`defaultValue` (see `filterValueEqualsDefault`) -- so a bar whose defaults narrow the view on\nload does not claim the user narrowed it, while a filter with no declared `defaultValue`\ncounts as changed the moment it has any value at all, since there is nothing for it to still\nequal. `'hidden'` never renders the row, regardless of any filter's state. Every value other\nthan `'changed'`/`'hidden'` (including a foreign attribute value) behaves like `'all'`,\nmatching `labelVisibility`'s own foreign-value handling. Removing a chip always clears that\nfilter, exactly as it always has -- this property only changes which already-active filters\nget a chip in the row, never what removing one does.\n\n`'changed'` additionally gates the reset button on `hasChangedFilters` rather than\n`hasActiveFilters`, so an untouched defaults-only bar -- which renders no chip in this mode --\nno longer offers an enabled reset that would change nothing. `hasActiveFilters` itself is\nunaffected by this property in every mode, and so is reset enablement under `'all'`/`'hidden'`.\n\nAttribute: `active-filters-display`  \nReflected to its attribute.","type":"LyraFilterBarActiveFiltersDisplay","default":"'all'"},{"name":"disabled","description":"Disables every composed filter control and the reset button. Plain property -- see the\nclass doc for why this component isn't form-associated / fieldset-cascaded.\n\nAttribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"filters","description":"Host-declared filter definitions, rendered in array order. The first 10,000 definitions and\nnested collection entries are deeply snapshotted and frozen; reassign after changing them.\n`null`/`undefined` is treated as an empty array rather than throwing. Choice options require\nstring value/label data fields; malformed entries are omitted independently. Custom definitions\nrequire a callable renderer and adapter. Exceptions thrown by admitted renderers propagate.\n\n`Defs` narrows this element's `value` to a keyed record typed per `filterId` -- see\n`LyraFilterBarValueFor`; the unnarrowed default resolves to the published `readonly\nLyraFilterBarFilterDefinition[]` below, which is why the manifest type is pinned here rather\nthan left to the class's own type parameter.","type":"readonly LyraFilterBarFilterDefinition[] | null | undefined"},{"name":"hasActiveFilters","description":"Whether any filter currently has a value -- including one sitting at its own declared\n`defaultValue`, which is a value the filter holds like any other. Also what gates whether the\n`active-filters` chip row renders at all, and the reset button's own disabled state in every\n`activeFiltersDisplay` mode except `'changed'`, where `hasChangedFilters` gates it instead.\nThis getter itself is unaffected by `activeFiltersDisplay`.","type":"boolean","read-only":true},{"name":"hasChangedFilters","description":"Whether any filter's value differs from its own declared `defaultValue`. Always live, never\ncached, exactly like `invalidFilterIds`.\n\nThis is the counterpart to `hasActiveFilters`, not a synonym: a bar whose every filter sits\nat a non-empty declared default reads `hasActiveFilters === true` (those defaults are real\nvalues, and each one still renders its own chip under `activeFiltersDisplay: 'all'`) and\n`hasChangedFilters === false` -- a bar whose defaults narrow the view on load does not claim\nthe user narrowed it. A filter with no declared `defaultValue` counts as changed the moment it\nholds any value at all, since there is nothing for it to still equal; conversely, clearing a\nfilter that *does* declare one counts as changed too, because `reset()` would restore it.\n\nIt differs from the `'changed'` chip row in exactly that last case: the row only ever\nconsiders filters that currently hold a value, so a cleared-but-defaulted filter shows no\nchip while still reading as changed here.","type":"boolean","read-only":true},{"name":"invalidFilterIds","description":"Filter ids currently failing their own `required` check -- a filter is invalid only when\n`required` is set and its value is unset (see `isSet`). Always live, never cached.","type":"readonly string[]","read-only":true},{"name":"label","description":"Accessible-name fallback for the root `role=\"group\"` wrapper when the host has no\n`aria-label`, matching `<lr-control-group>`. Attribute presence wins, including an\nexplicitly empty `aria-label`.\n\nAttribute: `label`","type":"string","default":"''"},{"name":"loading","description":"Shows the `status` spinner. Purely presentational -- filters stay editable while `loading`,\nsince a host typically wants a user to keep refining filters while a previous query is\nstill in flight; only the reset button (which would otherwise race a fresh, unrequeried\nreset against an in-flight fetch for the *previous* value) is disabled by it.\n\nAttribute: `loading`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"value","description":"The current value of every filter -- see the class doc's serialization contract. Reads and\nwrites clone and freeze the record and each string-array field, bounded to 10,000 keys and\n10,000 array entries, so mutations never affect this component's state or a subsequent\n`lr-input` detail. Reassign after changes. `null`/`undefined` writes clear to the canonical\nempty record while reads stay non-null.\n\n`LyraFilterBarValueFor<Defs>` narrows each key to the value type the matching entry in\n`filters` implies (see `LyraFilterBarDefinitionValue`) when this element is typed with a\nliteral `Defs`; the unnarrowed default resolves to the published record below, which is why\nthe manifest type is pinned here rather than left to the inferred alias name.","type":"LyraFilterBarValue | null | undefined"}],"events":[{"name":"lr-input","description":"A filter's value changed (including a chip removal or `reset()`). `detail: { value, filterId, appliedPreset }` -- `value` is always the complete object; `filterId` is the one filter that changed, or `undefined` for a `reset()`; `appliedPreset` is the `'date-range'` quick-range entry that produced this commit, and `undefined` everywhere else (another filter type, or a range picked/typed by hand).","type":"CustomEvent<LyraFilterBarInputDetail<Defs>>"},{"name":"lr-reset","description":"`reset()` ran (via the reset button or a direct call). `detail: { value }`.","type":"CustomEvent<LyraFilterBarResetDetail<Defs>>"},{"name":"lr-validity-change","description":"The computed `{ valid, invalidFilterIds }` changed.","type":"CustomEvent<LyraEventDetailSnapshot<LyraFilterBarValidityDetail>>"}]}},{"name":"lr-flag","description":"`<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. It uses the same frame sizing, object fit, and shape clipping as `image`. |\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.","attributes":[{"name":"country","description":"ISO 3166-1 alpha-2 country code (e.g. `fr`, `us`). Takes precedence over `language`.\n\nType: `string | undefined`"},{"name":"fallback","description":"Placeholder image URL rendered in place of a flag when the code cannot resolve — a historical\nor defunct state in a longitudinal dataset, say. Unset renders the `fallback` slot's content\ninstead, or nothing at all, so the element still occupies its normal footprint in a table or\ncard grid rather than showing error wording.\n\nType: `string | undefined`"},{"name":"fidelity","description":"Type: `LyraFlagFidelity`","value":{"type":["'compact'","'standard'","'detailed'"]}},{"name":"label","description":"Accessible label / `alt` text used when `aria-label` is unset. Defaults to a localized, human-readable\nregion name derived from the *resolved country code* via\n`Intl.DisplayNames` (e.g. `\"United Kingdom\"`) — for a `language`-only\nelement (e.g. `language=\"en\"`) that's the mapped country's display name,\nnot the language tag itself. Falls back to the bare uppercase code if\n`Intl.DisplayNames` can't resolve it. Has no default when only `src` is\ngiven (no country/language to derive one from).\n\nType: `string | undefined`"},{"name":"language","description":"BCP-47-ish language tag (e.g. `en`, `en-US`) resolved to a country flag.\n\nType: `string | undefined`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"shape","description":"Flag crop geometry. Invalid runtime values normalize to `rect`.\n\nType: `LyraFlagShape`","value":{"type":["'rect'","'circle'"]}},{"name":"src","description":"A pre-resolved flag image URL — takes precedence over `country`/`language`\nand skips the `@aceshooting/lyra-flags` peer-package lookup (and its\nloading-skeleton round trip) entirely. See the class doc: mainly useful to\navoid even the small per-flag async hop when you already have the URL at\nbuild time. `label` is effectively required alongside `src` — there's no\n`country`/`language` to derive a fallback `alt` from.\n\nType: `string | undefined`"}],"slots":[{"name":"fallback","description":"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."}],"js":{"properties":[{"name":"country","description":"ISO 3166-1 alpha-2 country code (e.g. `fr`, `us`). Takes precedence over `language`.\n\nAttribute: `country`","type":"string | undefined"},{"name":"fallback","description":"Placeholder image URL rendered in place of a flag when the code cannot resolve — a historical\nor defunct state in a longitudinal dataset, say. Unset renders the `fallback` slot's content\ninstead, or nothing at all, so the element still occupies its normal footprint in a table or\ncard grid rather than showing error wording.\n\nAttribute: `fallback`","type":"string | undefined"},{"name":"fidelity","description":"Attribute: `fidelity`  \nReflected to its attribute.","type":"LyraFlagFidelity"},{"name":"label","description":"Accessible label / `alt` text used when `aria-label` is unset. Defaults to a localized, human-readable\nregion name derived from the *resolved country code* via\n`Intl.DisplayNames` (e.g. `\"United Kingdom\"`) — for a `language`-only\nelement (e.g. `language=\"en\"`) that's the mapped country's display name,\nnot the language tag itself. Falls back to the bare uppercase code if\n`Intl.DisplayNames` can't resolve it. Has no default when only `src` is\ngiven (no country/language to derive one from).\n\nAttribute: `label`","type":"string | undefined"},{"name":"language","description":"BCP-47-ish language tag (e.g. `en`, `en-US`) resolved to a country flag.\n\nAttribute: `language`","type":"string | undefined"},{"name":"loading","description":"True while the effective source is resolving or its native image is loading.","type":"boolean","read-only":true},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"shape","description":"Flag crop geometry. Invalid runtime values normalize to `rect`.\n\nAttribute: `shape`  \nReflected to its attribute.","type":"LyraFlagShape"},{"name":"src","description":"A pre-resolved flag image URL — takes precedence over `country`/`language`\nand skips the `@aceshooting/lyra-flags` peer-package lookup (and its\nloading-skeleton round trip) entirely. See the class doc: mainly useful to\navoid even the small per-flag async hop when you already have the URL at\nbuild time. `label` is effectively required alongside `src` — there's no\n`country`/`language` to derive a fallback `alt` from.\n\nAttribute: `src`","type":"string | undefined"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}]}},{"name":"lr-flow-canvas","description":"`<lr-flow-canvas>` — a pannable/zoomable DAG workflow canvas: positions HTML node cards, draws\nSVG edges between their handles, runs a shared layered auto-layout for unpositioned nodes, and owns\nall selection/drag/connect interaction. Readonly (viewer) by default; opt into editor gestures\nindividually via `nodes-draggable`, `connectable`, `droppable`. `nodes` and `edges` remain\ncontrolled and are never mutated internally. Selection is an internally applied interaction\nstate: `selectedNodeIds`/`selectedEdgeIds` can seed or replace it, and node/edge activation\nupdates those arrays before emitting `lr-selection-change`. Interaction announcements are\nflushed to the document's shared light-DOM polite sink; mount is silent and repeated identical\nmessages remain separate announcements. `[part=\"live-region\"]` is only an aria-hidden mirror.\nTurning on `locked` is a live safety boundary: active pan, node-drag, connect, and palette-drop\npreviews are canceled and their window listeners are retired before later pointer events can\ncommit. Viewport-mutating imperative methods, including `focusNode()`, are inert while locked.\nReplacing the controlled `nodes` model similarly retires node-drag and connect gestures before\ntheir captured ids can outlive that model; background pan remains independent. Node and edge\ncollections reject blank ids and later duplicates at assignment, so the first valid occurrence\nowns layout, focus, selection, gestures, companion snapshots, and emitted identity.\n\nA `FlowNode` may also set `disabled`, marking it non-actionable: it keeps its position and card\ncontent but cannot be selected or activated by click or keyboard, roving-tabindex navigation\n(arrow keys, Home/End) steps past it instead of landing on it, it cannot be dragged even while\n`nodes-draggable`, and it is excluded from starting or receiving a new connection while\n`connectable` -- an edge that already touches a since-disabled node is left alone. Omitted or\n`false` renders the node exactly as before this field existed.\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) | Consumer-authored node cards matched by `node-id`. Each matching card is assigned to the generated `node-{id}` slot; a declarative `lr-flow-node` fallback remains in shadow DOM and no light-DOM nodes are created or removed. Non-matching children are ignored with a warning. |\n| `bottom-end` | Floating end-side content in the wrapping bottom overlay rail (e.g. `lr-flow-minimap`). |\n| `bottom-start` | Floating start-side content in the wrapping bottom overlay rail (e.g. `lr-flow-controls`). |\n| `top-end` | Floating end-side content in the wrapping top overlay rail. |\n| `top-start` | Floating start-side content in the wrapping top overlay rail (e.g. `lr-flow-run-status`). |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `arrowhead` | A tone-matched directed-edge arrowhead marker. |\n| `background` | The dotted background grid. |\n| `base` | The root wrapper. |\n| `connection-line` | The in-progress connect-gesture path. |\n| `edge` | A single edge path. |\n| `edge-hit-area` | The transparent wide pointer target behind an edge. |\n| `edge-label` | An edge's drawn label. |\n| `edge-list` | A visually hidden list of dangling or otherwise unrenderable edges. |\n| `edges` | The edges SVG. |\n| `empty` | The `lr-empty` shown when `nodes` is empty. |\n| `layout-limit` | A visible localized notice shown when layered layout reaches its bounded edge-ordering work limit. Its announcement is sent through the shared light-DOM polite sink. |\n| `live-region` | An aria-hidden shadow mirror of the current item/gesture announcement; the actual announcement uses the shared light-DOM polite sink. |\n| `node` | A node's positioned wrapper. Carries `data-selected` while selected, and `aria-disabled=\"true\"` while its `FlowNode.disabled` is set. |\n| `node-card` | The declarative fallback card. |\n| `node-card-base` | The fallback `lr-flow-node` handle/card row. |\n| `node-card-body` | The fallback card's body. |\n| `node-card-handle` | Every fallback card handle. |\n| `node-card-handle-input` | A fallback card input handle. |\n| `node-card-handle-output` | A fallback card output handle. Fallback cards additionally expose a normalized `node-type-<type>` part derived from `FlowNode.type`; wildcard part names are described here rather than published as literal CEM members. |\n| `node-card-header` | The fallback card's header row. |\n| `node-card-heading` | The fallback card's heading. |\n| `node-card-progress` | The fallback card's determinate progress bar. |\n| `node-card-status` | The fallback card's visible status. |\n| `node-card-surface` | The fallback card's bordered surface. |\n| `node-card-toolbar` | The fallback card's toolbar. |\n| `node-control` | The visually hidden, roving selection button for a node. Renders a genuine `disabled` `<button>` while `FlowNode.disabled` is set. |\n| `overlay-rail` | A top or bottom wrapping rail that prevents opposite-corner companions from overlapping in narrow allocations. |\n| `stub` | A dangling-edge stub line. |\n| `viewport` | The focusable pan/zoom surface. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-canvas-reserved-height` (default: `var(--lr-size-24rem)`) — Default host block size, shared with the pre-upgrade reservation stylesheet. An explicit outer `block-size` still wins.\n- `--lr-flow-canvas-connection-line-color` (default: `var(--lr-color-brand)`) — Stroke color of `[part=\"connection-line\"]`, the in-progress connect-gesture path drawn while dragging a new connection, independent of a finished edge's own `--lr-flow-canvas-edge-*-color`.\n- `--lr-flow-canvas-drop-active-outline-color` (default: `var(--lr-color-brand)`) — Outline color of the viewport while a palette item is dragged over it (`droppable`).\n- `--lr-flow-canvas-edge-brand-color` (default: `var(--lr-color-brand)`) — Brand edge and arrowhead color.\n- `--lr-flow-canvas-edge-danger-color` (default: `var(--lr-color-danger)`) — Danger edge and arrowhead color.\n- `--lr-flow-canvas-edge-neutral-color` (default: `var(--lr-color-border)`) — Neutral edge and arrowhead color.\n- `--lr-flow-canvas-edge-success-color` (default: `var(--lr-color-success)`) — Success edge and arrowhead color.\n- `--lr-flow-canvas-edge-warning-color` (default: `var(--lr-color-warning)`) — Warning edge and arrowhead color.\n- `--lr-flow-canvas-grid-size` (default: `var(--lr-size-0-5rem)`) — Dotted background spacing. The `grid` property supplies the fallback when this hook is unset; an element or ancestor hook takes precedence.\n- `--lr-flow-canvas-march-duration` (default: `var(--lr-duration-ambient)`) — Running-edge march animation duration.\n- `--lr-flow-canvas-node-connect-invalid-outline-color` (default: `var(--lr-color-danger)`) — Outline color of a node that is an invalid connect-gesture drop target. Same `::part()` attribute-selector restriction as `--lr-flow-canvas-node-selected-outline-color` above.\n- `--lr-flow-canvas-node-connect-target-outline-color` (default: `var(--lr-color-brand)`) — Outline color of a node that is a valid connect-gesture drop target.\n- `--lr-flow-canvas-node-disabled-opacity` (default: `var(--lr-opacity-disabled)`) — Opacity of a node whose `FlowNode` entry sets `disabled`.\n- `--lr-flow-canvas-node-hover-outline-color` (default: `var(--lr-color-border-strong)`) — Outline color of a node's mouse-hover preview of its own `:focus-visible` ring. Unlike the four state-scoped colors above this one is `:hover`-gated rather than attribute-gated, so a `::part(node):hover` override would lose to this rule's own higher internal specificity rather than to the `::part()[attr]` restriction those four work around. Set to `transparent` to opt out.\n- `--lr-flow-canvas-node-selected-outline-color` (default: `var(--lr-color-brand)`) — Outline color of a selected node.","attributes":[{"name":"aria-label","description":"Type: `string | null`  \nDefault: `null`"},{"name":"connectable","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"droppable","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"grid","description":"Snap step, in content px, for drags/nudges/drop positions; `0` disables snapping. Also the\ndotted background's base spacing.\n\nType: `number`  \nDefault: `8`","value":{"type":["number"]}},{"name":"layer-gap","description":"Type: `number`  \nDefault: `64`","value":{"type":["number"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locked","description":"Freezes pan/zoom/edit gestures and viewport-mutating methods. Enabling it live cancels and\nrolls back every active gesture before retiring its global listeners.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"max-zoom","description":"Type: `number`  \nDefault: `2`","value":{"type":["number"]}},{"name":"min-zoom","description":"Type: `number`  \nDefault: `0.25`","value":{"type":["number"]}},{"name":"node-gap","description":"Type: `number`  \nDefault: `24`","value":{"type":["number"]}},{"name":"nodes-draggable","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"orientation","description":"Downstream layout and handle axis. Horizontal RTL reflects model coordinates while authored,\ngenerated and portable fallback cards retain readable content. Invalid runtime/attribute\nvalues normalize to horizontal.\n\nType: `LyraOrientation`","value":{"type":["'horizontal'","'vertical'"]}}],"slots":[{"name":"","description":"Consumer-authored node cards matched by `node-id`. Each matching card is assigned to the generated `node-{id}` slot; a declarative `lr-flow-node` fallback remains in shadow DOM and no light-DOM nodes are created or removed. Non-matching children are ignored with a warning."},{"name":"bottom-end","description":"Floating end-side content in the wrapping bottom overlay rail (e.g. `lr-flow-minimap`)."},{"name":"bottom-start","description":"Floating start-side content in the wrapping bottom overlay rail (e.g. `lr-flow-controls`)."},{"name":"top-end","description":"Floating end-side content in the wrapping top overlay rail."},{"name":"top-start","description":"Floating start-side content in the wrapping top overlay rail (e.g. `lr-flow-run-status`)."}],"js":{"properties":[{"name":"accessibleLabel","description":"Attribute: `aria-label`","type":"string | null","default":"null"},{"name":"connectable","description":"Attribute: `connectable`","type":"boolean","default":"false"},{"name":"decorations","description":"Deeply snapshotted, frozen run decorations, bounded to 10,000 keys and a finite nested-data\nbudget. Invalid statuses and records with unreadable nested fields are omitted independently,\nretaining valid neighbors. Reassign the record to update.","type":"FlowRunDecorations | null"},{"name":"droppable","description":"Attribute: `droppable`","type":"boolean","default":"false"},{"name":"edges","description":"Controlled edge model, deeply snapshotted and frozen at assignment, bounded to the first\n10,000 source edges and a finite nested-data budget. Blank ids and later duplicates are omitted\nfirst-wins before every render, action, focus, selection, snapshot, and event path. Reassign\nthe collection to update.","type":"readonly FlowEdge[]"},{"name":"grid","description":"Snap step, in content px, for drags/nudges/drop positions; `0` disables snapping. Also the\ndotted background's base spacing.\n\nAttribute: `grid`","type":"number","default":"8"},{"name":"layerGap","description":"Attribute: `layer-gap`","type":"number","default":"64"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"locked","description":"Freezes pan/zoom/edit gestures and viewport-mutating methods. Enabling it live cancels and\nrolls back every active gesture before retiring its global listeners.\n\nAttribute: `locked`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"maxZoom","description":"Attribute: `max-zoom`","type":"number","default":"2"},{"name":"minZoom","description":"Attribute: `min-zoom`","type":"number","default":"0.25"},{"name":"nodeGap","description":"Attribute: `node-gap`","type":"number","default":"24"},{"name":"nodes","description":"Controlled node model, deeply snapshotted and frozen at assignment, bounded to the first\n10,000 source nodes and a finite nested-data budget. Blank ids and later duplicates are omitted\nfirst-wins. Reassign to update; replacing it cancels active node-drag and pointer/keyboard\nconnect gestures and prunes selected ids that no longer exist.","type":"readonly FlowNode[]"},{"name":"nodesDraggable","description":"Attribute: `nodes-draggable`","type":"boolean","default":"false"},{"name":"orientation","description":"Downstream layout and handle axis. Horizontal RTL reflects model coordinates while authored,\ngenerated and portable fallback cards retain readable content. Invalid runtime/attribute\nvalues normalize to horizontal.\n\nAttribute: `orientation`  \nReflected to its attribute.","type":"LyraOrientation"},{"name":"selectedEdgeIds","description":"Frozen, unique snapshot of at most the first 10,000 valid nonblank edge ids.","type":"readonly string[]"},{"name":"selectedNodeIds","description":"Frozen, unique snapshot of at most the first 10,000 valid nonblank node ids.","type":"readonly string[]"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"viewport","description":"Read-only, derived from the live layout — setViewport is the mutator. The setter\nexists and is a documented no-op because this getter's return shape is exactly\n`setViewport()`'s input shape, which invites `.viewport=${next}` in a Lit template. A\ngetter-only accessor makes that binding throw from inside lit-html's property commit on a\n*later* render, blaming framework internals rather than the offending line; degrading to a\nsilent ignore is the kinder failure. Mirrors `LyraChart`'s `chartArea`.","type":"Readonly<{ x: number; y: number; zoom: number }>"}],"events":[{"name":"lr-connect","description":"`detail: { source, target, sourceHandle, targetHandle }`.","type":"CustomEvent<Readonly<{\n    source: string;\n    target: string;\n    sourceHandle: string;\n    targetHandle: string;\n  }>>"},{"name":"lr-edge-activate","description":"`detail: { edgeId, source, target }`.","type":"CustomEvent<Readonly<{ edgeId: string; source: string; target: string }>>"},{"name":"lr-layout-change","description":"`detail: { positions, truncated }`.","type":"CustomEvent<FlowLayoutChangeDetail>"},{"name":"lr-node-activate","description":"`detail: { nodeId }`.","type":"CustomEvent<Readonly<{ nodeId: string }>>"},{"name":"lr-node-add","description":"`detail: { type, position }`.","type":"CustomEvent<Readonly<{\n    type: string;\n    position: Readonly<{ x: number; y: number }>;\n  }>>"},{"name":"lr-node-move","description":"`detail: { nodeId, position, previous }`.","type":"CustomEvent<Readonly<{\n    readonly nodeId: string;\n    readonly position: Readonly<{ x: number; y: number }>;\n    readonly previous: Readonly<{ x: number; y: number }>;\n  }>>"},{"name":"lr-selection-change","description":"`detail: { nodeIds, edgeIds }`.","type":"CustomEvent<\n    Readonly<{ nodeIds: readonly string[]; edgeIds: readonly string[] }>\n  >"},{"name":"lr-selection-delete","description":"`detail: { nodeIds, edgeIds }`.","type":"CustomEvent<\n    Readonly<{ nodeIds: readonly string[]; edgeIds: readonly string[] }>\n  >"},{"name":"lr-viewport-change","description":"`detail: { x, y, zoom }`.","type":"CustomEvent<Readonly<{ x: number; y: number; zoom: number }>>"}]}},{"name":"lr-flow-controls","description":"`<lr-flow-controls>` — the canvas's button cluster: zoom in/out, fit, and interaction lock, so\nevery flow surface ships the same affordances without hosts rebuilding them. Manipulates only\nview state, never `nodes`/`edges` — no editing commands live here. Zoom-button availability comes\nfrom the canvas companion snapshot's finite, sorted effective bounds, never its raw public bound\ninputs.\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) | Extra host buttons appended to the cluster. A slotted `<button>` picks up the same treatment as the built-in controls through a `::slotted(button)` rule — the shared `--lr-icon-button-size` hit-area floor, the chrome-less transparent box, and the same hover/press/disabled/focus-visible affordances. Only the slotted element itself is styled, not the consumer's markup inside it. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The `role=\"group\"` wrapper. Drops its floating-surface chrome (border, background, shadow, padding, radius) under `frame=\"plain\"`. |\n| `fit` | Zoom-to-fit button. |\n| `lock` | Lock/unlock toggle button (omitted when `hideLock`). |\n| `zoom-in` | Zoom-in button. |\n| `zoom-out` | Zoom-out button. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-flow-controls-lock-active-color` (default: `var(--lr-color-brand)`) — Pressed lock-button foreground.","attributes":[{"name":"for","description":"Id of the `lr-flow-canvas` this cluster drives. Empty (the default) resolves to the nearest\nancestor canvas -- the slotted-into-a-corner-slot case. Changing it at runtime re-resolves and\nre-subscribes; a target that mounts later is picked up too.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"frame","description":"Container treatment, in the shared `LyraFrame` vocabulary. `'card'` (the default) keeps the\nbordered, filled, shadowed floating cluster. `'plain'` removes the border, background, shadow,\npadding and corner radius, so a cluster placed in a host toolbar or panel that already draws\nits own surface doesn't double the frame. The buttons keep their shared minimum hit area and\ntheir own hover/focus affordances either way.\n\nType: `LyraFrame`  \nDefault: `'card'`","value":{"type":["'card'","'plain'"]}},{"name":"hide-lock","description":"Omits the lock/unlock toggle button entirely, for canvases that never expose an interaction\nlock.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"orientation","description":"Type: `LyraOrientation`","value":{"type":["'horizontal'","'vertical'"]}}],"slots":[{"name":"","description":"Extra host buttons appended to the cluster. A slotted `<button>` picks up the same treatment as the built-in controls through a `::slotted(button)` rule — the shared `--lr-icon-button-size` hit-area floor, the chrome-less transparent box, and the same hover/press/disabled/focus-visible affordances. Only the slotted element itself is styled, not the consumer's markup inside it."}],"js":{"properties":[{"name":"for","description":"Id of the `lr-flow-canvas` this cluster drives. Empty (the default) resolves to the nearest\nancestor canvas -- the slotted-into-a-corner-slot case. Changing it at runtime re-resolves and\nre-subscribes; a target that mounts later is picked up too.\n\nAttribute: `for`","type":"string","default":"''"},{"name":"frame","description":"Container treatment, in the shared `LyraFrame` vocabulary. `'card'` (the default) keeps the\nbordered, filled, shadowed floating cluster. `'plain'` removes the border, background, shadow,\npadding and corner radius, so a cluster placed in a host toolbar or panel that already draws\nits own surface doesn't double the frame. The buttons keep their shared minimum hit area and\ntheir own hover/focus affordances either way.\n\nAttribute: `frame`  \nReflected to its attribute.","type":"LyraFrame","default":"'card'"},{"name":"hideLock","description":"Omits the lock/unlock toggle button entirely, for canvases that never expose an interaction\nlock.\n\nAttribute: `hide-lock`","type":"boolean","default":"false"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"orientation","description":"Attribute: `orientation`  \nReflected to its attribute.","type":"LyraOrientation"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}]}},{"name":"lr-flow-minimap","description":"`<lr-flow-minimap>` — a corner overview map of a `lr-flow-canvas`: scaled node rectangles plus\na draggable viewport rectangle, for orientation and fast navigation on canvases larger than the\nscreen. Draws no edges (nodes only, matching the React Flow/n8n minimap convention) and never\nreads `nodes` itself — geometry always comes from the canvas's `registerCompanion()` snapshots, so\nthe two can never disagree. The initial companion snapshot is silent; keyboard, map-click, and\nwheel viewport changes append their next rAF-coalesced snapshot to the document's shared\nlight-DOM polite sink, while a completed viewport drag appends its final position once.\nIdentical repeats remain distinct additions and `[part=\"live-region\"]` stays an aria-hidden\nmirror. A completed viewport drag consumes the browser-synthesized click that follows its\n`pointerup`; canceled or lost-capture drags stay silent and leave the next genuine map click\navailable for click-to-center navigation.\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 root wrapper. Drops its floating-surface chrome (border, background, radius) under `frame=\"plain\"`. |\n| `instructions` | Visually hidden keyboard instructions for the viewport. |\n| `live-region` | An aria-hidden shadow mirror of viewport-change announcements; the actual announcements use the shared light-DOM polite sink. |\n| `map` | The scaled SVG. |\n| `node` | One rect per node. |\n| `viewport` | The exact visible canvas-view rectangle. |\n| `viewport-hit-area` | The transparent, draggable/focusable interaction rectangle, floored to the shared hit-area size without changing the visible viewport geometry. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-flow-minimap-block-size` (default: `var(--lr-size-8rem)`) — Map block size.\n- `--lr-flow-minimap-inline-size` (default: `var(--lr-size-12rem)`) — Map inline size.\n- `--lr-flow-minimap-viewport-color` (default: `var(--lr-color-brand)`) — Fill (mixed 15% into transparent) and stroke of `[part=\"viewport\"]`, the rectangle showing the canvas's visible area, independent of the per-status node fills above.\n- `--lr-flow-minimap-viewport-min-size` (default: `var(--lr-icon-button-size)`) — Smallest rendered size, in physical pixels, of the transparent `viewport-hit-area` along either axis. On a canvas whose node bounds dwarf the visible viewport the raw rectangle collapses to a few pixels, which leaves the only pointer-drag handle for panning effectively unclickable; the floor grows it symmetrically about its own centre so it still points at what the viewport shows. The visible `viewport` stays exact. Defaults to Lyra's 40px interaction floor; set `0` to opt out.\n- `--lr-flow-status-color` (default: `var(--lr-color-border-strong)`) — Fill of nodes without an execution status.\n- `--lr-flow-status-denied-color` (default: `var(--lr-color-warning)`) — Denied-node fill.\n- `--lr-flow-status-error-color` (default: `var(--lr-color-danger)`) — Failed-node fill.\n- `--lr-flow-status-pending-color` (default: `var(--lr-color-border-strong)`) — Pending-node fill.\n- `--lr-flow-status-running-color` (default: `var(--lr-color-brand)`) — Running-node fill.\n- `--lr-flow-status-success-color` (default: `var(--lr-color-success)`) — Successful-node fill.","attributes":[{"name":"for","description":"Id of the target `lr-flow-canvas`. When empty, the nearest ancestor is used (the\nslotted-into-a-corner-slot case, the primary wiring).\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"frame","description":"Container treatment, in the shared `LyraFrame` vocabulary. `'card'` (the default) keeps the\nbordered, filled corner surface. `'plain'` removes the border, background and corner radius,\nfor a minimap placed in a host panel or toolbar that already draws its own surface, so the\nframe isn't doubled. The map's own hover/click affordances and the viewport rect stay either\nway -- only the outer `[part=\"base\"]` decoration goes. Mirrors `lr-flow-controls`'/\n`lr-flow-run-status`'s identical `frame`.\n\nType: `LyraFrame`  \nDefault: `'card'`","value":{"type":["'card'","'plain'"]}},{"name":"label","description":"Accessible name for the map region; falls back to a host `aria-label`, then `flowMinimapLabel`.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"js":{"properties":[{"name":"for","description":"Id of the target `lr-flow-canvas`. When empty, the nearest ancestor is used (the\nslotted-into-a-corner-slot case, the primary wiring).\n\nAttribute: `for`","type":"string","default":"''"},{"name":"frame","description":"Container treatment, in the shared `LyraFrame` vocabulary. `'card'` (the default) keeps the\nbordered, filled corner surface. `'plain'` removes the border, background and corner radius,\nfor a minimap placed in a host panel or toolbar that already draws its own surface, so the\nframe isn't doubled. The map's own hover/click affordances and the viewport rect stay either\nway -- only the outer `[part=\"base\"]` decoration goes. Mirrors `lr-flow-controls`'/\n`lr-flow-run-status`'s identical `frame`.\n\nAttribute: `frame`  \nReflected to its attribute.","type":"LyraFrame","default":"'card'"},{"name":"label","description":"Accessible name for the map region; falls back to a host `aria-label`, then `flowMinimapLabel`.\n\nAttribute: `label`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}]}},{"name":"lr-flow-node","description":"`<lr-flow-node>` — the card a workflow node renders as: header/body/toolbar chrome,\ntool-lifecycle status tones, and the named connection-handle elements edges anchor to. Used as\n`lr-flow-canvas`'s default card and as a slotted override; also renders standalone (palette\npreviews, docs). Purely presentational — activation, selection, movement, and connection are all\n`lr-flow-canvas` events; this component owns none of that.\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) | Body content. |\n| `header` | Replaces the built-in heading row entirely. |\n| `icon` | Leading header glyph. |\n| `toolbar` | Action row at the block-end edge. Always visible on coarse-pointer/no-hover devices; pointer-hover and focus-within reveal it elsewhere. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The row wrapping the input handles, the card, and the output handles. Carries no card chrome of its own — style the card itself through the `card` part. |\n| `body` | The default-slot body wrapper. |\n| `card` | The bordered, filled node card. |\n| `handle` | Every handle dot (input or output). |\n| `handle-input` | An input handle dot (also carries the shared `handle` part). |\n| `handle-output` | An output handle dot (also carries the shared `handle` part). |\n| `header` | The built-in header row (omitted when the `header` slot has content). |\n| `heading` | The heading text. |\n| `icon` | The wrapper around the `icon` slot. |\n| `progress` | The determinate progress bar. |\n| `status` | The visible status chip (status is never color-only). |\n| `toolbar` | The toolbar row wrapper. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-flow-node-compact-gap` (default: `var(--lr-space-2xs)`) — Gap between `[part=\"card\"]`'s rows while `compact`.\n- `--lr-flow-node-compact-padding` (default: `var(--lr-space-xs)`) — `[part=\"card\"]` padding while `compact`.\n- `--lr-flow-node-min-inline-size` (default: `calc(var(--lr-size-10rem) + var(--lr-size-1rem))`) — Minimum card inline size.\n- `--lr-flow-node-progress-fill-color` (default: `var(--lr-color-brand)`) — Determinate progress fill color, independent from the track and other brand-colored states.\n- `--lr-flow-node-progress-track-color` (default: `var(--lr-color-border)`) — Determinate progress track color.\n- `--lr-flow-node-running-border` (default: `var(--lr-color-brand)`) — Border color of the card while `status=\"running\"`. Independent from `--lr-flow-node-selected-outline-color` so a consumer can retint just one of the two states without the other following along.\n- `--lr-flow-node-running-glow` (default: `var(--lr-color-brand-quiet)`) — Box-shadow color of the running-state ring around the card, and the pulse keyframes' peak color.\n- `--lr-flow-node-selected-outline-color` (default: `var(--lr-color-brand)`) — Outline color of the card while `selected`. The outline stays independent from execution-state border and glow.\n- `--lr-flow-status-color` (default: `var(--lr-color-border-strong)`) — Status-dot color when no execution status is set.\n- `--lr-flow-status-denied-color` (default: `var(--lr-color-warning)`) — Denied status-dot color.\n- `--lr-flow-status-error-color` (default: `var(--lr-color-danger)`) — Error status-dot color.\n- `--lr-flow-status-pending-color` (default: `var(--lr-color-border-strong)`) — Pending status-dot color.\n- `--lr-flow-status-running-color` (default: `var(--lr-color-brand)`) — Running status-dot color.\n- `--lr-flow-status-success-color` (default: `var(--lr-color-success)`) — Success status-dot color.","attributes":[{"name":"compact","description":"Tighter card padding and row gap, for the dense canvases and palette previews these cards\nusually render in -- same convention as `lr-source-card`'s `compact`. Defaults to `false`,\ni.e. the full card padding. Purely a density knob: the border, background and shadow stay, as\ndo the `selected` and `status=\"running\"` treatments.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"data-node-type","description":"Consumer taxonomy forwarded by `lr-flow-canvas` as the reachable `data-node-type` attribute.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"duration-ms","description":"Type: `number | null`  \nDefault: `null`"},{"name":"heading","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"node-id","description":"This card's identity inside `lr-flow-canvas`, matched against a `nodes` entry's `id`. It\nreflects because the canvas adopts light-DOM children by reading the `node-id` *attribute*: a\nproperty-only `card.nodeId = 'fetch'` used to leave the card unslotted, rendering nowhere and\nwarning that it matched no node. The empty default stays absent from the DOM rather than\nserializing as `node-id=\"\"`, which the canvas would have to skip anyway.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"orientation","description":"Type: `LyraOrientation`","value":{"type":["'horizontal'","'vertical'"]}},{"name":"progress","description":"Type: `number | null`  \nDefault: `null`"},{"name":"selected","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"status","description":"Canonical tool lifecycle status. Invalid runtime/attribute values normalize to null.\n\nType: `LyraToolStatus | null`","value":{"type":["'pending'","'running'","'success'","'error'","'denied'"]}},{"name":"status-detail","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}}],"slots":[{"name":"","description":"Body content."},{"name":"header","description":"Replaces the built-in heading row entirely."},{"name":"icon","description":"Leading header glyph."},{"name":"toolbar","description":"Action row at the block-end edge. Always visible on coarse-pointer/no-hover devices; pointer-hover and focus-within reveal it elsewhere."}],"js":{"properties":[{"name":"compact","description":"Tighter card padding and row gap, for the dense canvases and palette previews these cards\nusually render in -- same convention as `lr-source-card`'s `compact`. Defaults to `false`,\ni.e. the full card padding. Purely a density knob: the border, background and shadow stay, as\ndo the `selected` and `status=\"running\"` treatments.\n\nAttribute: `compact`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"durationMs","description":"Attribute: `duration-ms`","type":"number | null","default":"null"},{"name":"flowType","description":"Consumer taxonomy forwarded by `lr-flow-canvas` as the reachable `data-node-type` attribute.\n\nAttribute: `data-node-type`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"heading","description":"Attribute: `heading`","type":"string","default":"''"},{"name":"inputs","description":"Frozen snapshot of at most the first 10,000 input handles. Reassign to update.","type":"readonly FlowHandle[]"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"nodeId","description":"This card's identity inside `lr-flow-canvas`, matched against a `nodes` entry's `id`. It\nreflects because the canvas adopts light-DOM children by reading the `node-id` *attribute*: a\nproperty-only `card.nodeId = 'fetch'` used to leave the card unslotted, rendering nowhere and\nwarning that it matched no node. The empty default stays absent from the DOM rather than\nserializing as `node-id=\"\"`, which the canvas would have to skip anyway.\n\nAttribute: `node-id`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"orientation","description":"Attribute: `orientation`  \nReflected to its attribute.","type":"LyraOrientation"},{"name":"outputs","description":"Frozen snapshot of at most the first 10,000 output handles. Reassign to update.","type":"readonly FlowHandle[]"},{"name":"progress","description":"Attribute: `progress`","type":"number | null","default":"null"},{"name":"selected","description":"Attribute: `selected`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"status","description":"Canonical tool lifecycle status. Invalid runtime/attribute values normalize to null.\n\nAttribute: `status`  \nReflected to its attribute.","type":"LyraToolStatus | null"},{"name":"statusDetail","description":"Attribute: `status-detail`","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}]}},{"name":"lr-flow-run-status","description":"`<lr-flow-run-status>` — execution-state presentation for a `lr-flow-canvas`: pushes a\n`FlowRunDecorations` map into the resolved canvas (the canvas itself renders the node/edge paint)\nand renders a compact run-summary strip. Does not execute, poll, or time anything — pure pushed\nstate; `durationMs` is host-computed.\n\n---\n\n**Component metadata**\n\n- Status: `stable`\n- Since: `9.0.0`\n- Rationale: This tag entered Lyra as a stable public API with documented behavior, accessibility, and cross-browser support.\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) | Extra host chrome appended to the strip (e.g. a cancel button or a usage badge). |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The root wrapper. Drops its floating-surface chrome under `frame=\"plain\"`. |\n| `count` | One per status present (text + tone dot, never color-only). |\n| `live-region` | The visually-hidden, `aria-hidden` mirror of the last step-transition announcement. The announcement itself lands in the shared light-DOM polite region (`acquireAnnouncementSink()` in `internal/announcer.ts`), because a live region inside a shadow root is not reliably announced; this part is a styling/inspection surface only. |\n| `summary` | The \"{done} of {total} steps complete\" line. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-flow-status-color` (default: `var(--lr-color-border-strong)`) — Count-dot color when no execution status is set.\n- `--lr-flow-status-denied-color` (default: `var(--lr-color-warning)`) — Denied count-dot color.\n- `--lr-flow-status-error-color` (default: `var(--lr-color-danger)`) — Error count-dot color.\n- `--lr-flow-status-pending-color` (default: `var(--lr-color-border-strong)`) — Pending count-dot color.\n- `--lr-flow-status-running-color` (default: `var(--lr-color-brand)`) — Running count-dot color.\n- `--lr-flow-status-success-color` (default: `var(--lr-color-success)`) — Success count-dot color.","attributes":[{"name":"for","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"frame","description":"Container treatment, in the shared `LyraFrame` vocabulary. `'card'` (the default) keeps the\nbordered, filled, shadowed floating strip. `'plain'` removes the border, background, shadow,\npadding and corner radius, so a summary strip dropped directly into a host toolbar that\nalready draws its own frame doesn't double it.\n\nType: `LyraFrame`  \nDefault: `'card'`","value":{"type":["'card'","'plain'"]}},{"name":"hide-summary","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"label","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"slots":[{"name":"","description":"Extra host chrome appended to the strip (e.g. a cancel button or a usage badge)."}],"js":{"properties":[{"name":"decorations","description":"Detached, deeply frozen decoration snapshot, bounded to 10,000 keys and a finite nested-data\nbudget. Invalid status entries are omitted; reassign the record to update.","type":"FlowRunDecorations"},{"name":"for","description":"Attribute: `for`","type":"string","default":"''"},{"name":"frame","description":"Container treatment, in the shared `LyraFrame` vocabulary. `'card'` (the default) keeps the\nbordered, filled, shadowed floating strip. `'plain'` removes the border, background, shadow,\npadding and corner radius, so a summary strip dropped directly into a host toolbar that\nalready draws its own frame doesn't double it.\n\nAttribute: `frame`  \nReflected to its attribute.","type":"LyraFrame","default":"'card'"},{"name":"hideSummary","description":"Attribute: `hide-summary`","type":"boolean","default":"false"},{"name":"label","description":"Attribute: `label`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}]}},{"name":"lr-format-bytes","description":"`<lr-format-bytes>` — locale-aware byte-size formatting.\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) | Fallback content when the value is not finite. |","attributes":[{"name":"decimals","description":"Type: `number`  \nDefault: `1`","value":{"type":["number"]}},{"name":"display","description":"Type: `LyraFormatDisplay`  \nDefault: `'short'`","value":{"type":["'long'","'short'","'narrow'"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"unit","description":"Type: `LyraFormatBytesUnit`  \nDefault: `'byte'`","value":{"type":["'byte'","'bit'"]}},{"name":"unit-step","description":"Type: `number`  \nDefault: `1000`","value":{"type":["number"]}},{"name":"value","description":"Type: `number`  \nDefault: `0`","value":{"type":["number"]}}],"slots":[{"name":"","description":"Fallback content when the value is not finite."}],"js":{"properties":[{"name":"decimals","description":"Attribute: `decimals`","type":"number","default":"1"},{"name":"display","description":"Attribute: `display`","type":"LyraFormatDisplay","default":"'short'"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"unit","description":"Attribute: `unit`","type":"LyraFormatBytesUnit","default":"'byte'"},{"name":"unitStep","description":"Attribute: `unit-step`","type":"number","default":"1000"},{"name":"value","description":"Attribute: `value`","type":"number","default":"0"}]}},{"name":"lr-format-date","description":"`<lr-format-date>` — locale-aware `Intl.DateTimeFormat` output. Numeric `date` attributes are\nepoch milliseconds, matching numeric property assignment; nonnumeric attributes remain date\nstrings.\n`timeZone` is forwarded to both granular and style-based formatting. An invalid zone falls back\nto the browser's local time zone instead of making the component fail to render.\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) | Fallback content for an invalid date. |","attributes":[{"name":"date","description":"Type: `string | number | Date`  \nDefault: `new Date()`"},{"name":"date-style","description":"Type: `LyraFormatDateStyle | undefined`","value":{"type":["'full'","'long'","'medium'","'short'"]}},{"name":"day","description":"Type: `LyraFormatDateNumeric | undefined`","value":{"type":["'numeric'","'2-digit'"]}},{"name":"era","description":"Type: `LyraFormatDateText | undefined`","value":{"type":["'narrow'","'short'","'long'"]}},{"name":"hour","description":"Type: `LyraFormatDateNumeric | undefined`","value":{"type":["'numeric'","'2-digit'"]}},{"name":"hour-format","description":"Type: `LyraFormatDateHour`  \nDefault: `'auto'`","value":{"type":["'auto'","'12'","'24'"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"minute","description":"Type: `LyraFormatDateNumeric | undefined`","value":{"type":["'numeric'","'2-digit'"]}},{"name":"month","description":"Type: `LyraFormatDateMonth | undefined`","value":{"type":["'numeric'","'2-digit'","'narrow'","'short'","'long'"]}},{"name":"second","description":"Type: `LyraFormatDateNumeric | undefined`","value":{"type":["'numeric'","'2-digit'"]}},{"name":"time-style","description":"Type: `LyraFormatDateStyle | undefined`","value":{"type":["'full'","'long'","'medium'","'short'"]}},{"name":"time-zone","description":"IANA time-zone name forwarded to `Intl.DateTimeFormat` (attribute `time-zone`).\n\nType: `Intl.DateTimeFormatOptions['timeZone'] | undefined`"},{"name":"time-zone-name","description":"Type: `LyraFormatDateTimeZoneName | undefined`","value":{"type":["'short'","'long'"]}},{"name":"weekday","description":"Type: `LyraFormatDateText | undefined`","value":{"type":["'narrow'","'short'","'long'"]}},{"name":"year","description":"Type: `LyraFormatDateNumeric | undefined`","value":{"type":["'numeric'","'2-digit'"]}}],"slots":[{"name":"","description":"Fallback content for an invalid date."}],"js":{"properties":[{"name":"date","description":"Attribute: `date`","type":"string | number | Date","default":"new Date()"},{"name":"dateStyle","description":"Attribute: `date-style`","type":"LyraFormatDateStyle | undefined"},{"name":"day","description":"Attribute: `day`","type":"LyraFormatDateNumeric | undefined"},{"name":"era","description":"Attribute: `era`","type":"LyraFormatDateText | undefined"},{"name":"hour","description":"Attribute: `hour`","type":"LyraFormatDateNumeric | undefined"},{"name":"hourFormat","description":"Attribute: `hour-format`","type":"LyraFormatDateHour","default":"'auto'"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"minute","description":"Attribute: `minute`","type":"LyraFormatDateNumeric | undefined"},{"name":"month","description":"Attribute: `month`","type":"LyraFormatDateMonth | undefined"},{"name":"second","description":"Attribute: `second`","type":"LyraFormatDateNumeric | undefined"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"timeStyle","description":"Attribute: `time-style`","type":"LyraFormatDateStyle | undefined"},{"name":"timeZone","description":"IANA time-zone name forwarded to `Intl.DateTimeFormat` (attribute `time-zone`).\n\nAttribute: `time-zone`","type":"Intl.DateTimeFormatOptions['timeZone'] | undefined"},{"name":"timeZoneName","description":"Attribute: `time-zone-name`","type":"LyraFormatDateTimeZoneName | undefined"},{"name":"weekday","description":"Attribute: `weekday`","type":"LyraFormatDateText | undefined"},{"name":"year","description":"Attribute: `year`","type":"LyraFormatDateNumeric | undefined"}]}},{"name":"lr-format-number","description":"`<lr-format-number>` — locale-aware `Intl.NumberFormat` output.\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) | Fallback content when the value is not finite. |","attributes":[{"name":"currency","description":"ISO currency code. Removed or blank attributes format with the existing USD fallback.\n\nType: `string`  \nDefault: `'USD'`","value":{"type":["string"]}},{"name":"currency-display","description":"Type: `LyraFormatCurrencyDisplay`  \nDefault: `'symbol'`","value":{"type":["'symbol'","'narrowSymbol'","'code'","'name'"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"maximum-fraction-digits","description":"Type: `number | undefined`"},{"name":"maximum-significant-digits","description":"Type: `number | undefined`"},{"name":"minimum-fraction-digits","description":"Type: `number | undefined`"},{"name":"minimum-integer-digits","description":"Type: `number | undefined`"},{"name":"minimum-significant-digits","description":"Type: `number | undefined`"},{"name":"no-grouping","description":"Shoelace grouping alias; equivalent to `withoutGrouping`.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"notation","description":"Type: `LyraFormatNumberNotation`  \nDefault: `'standard'`","value":{"type":["'standard'","'compact'","'scientific'","'engineering'"]}},{"name":"type","description":"Type: `LyraFormatNumberType`  \nDefault: `'decimal'`","value":{"type":["'currency'","'decimal'","'percent'"]}},{"name":"value","description":"Type: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"without-grouping","description":"Web Awesome grouping alias. When both grouping aliases are false, `Intl` keeps the locale's\ndefault grouping policy rather than being forced on.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"","description":"Fallback content when the value is not finite."}],"js":{"properties":[{"name":"currency","description":"ISO currency code. Removed or blank attributes format with the existing USD fallback.\n\nAttribute: `currency`","type":"string","default":"'USD'"},{"name":"currencyDisplay","description":"Attribute: `currency-display`","type":"LyraFormatCurrencyDisplay","default":"'symbol'"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"maximumFractionDigits","description":"Attribute: `maximum-fraction-digits`","type":"number | undefined"},{"name":"maximumSignificantDigits","description":"Attribute: `maximum-significant-digits`","type":"number | undefined"},{"name":"minimumFractionDigits","description":"Attribute: `minimum-fraction-digits`","type":"number | undefined"},{"name":"minimumIntegerDigits","description":"Attribute: `minimum-integer-digits`","type":"number | undefined"},{"name":"minimumSignificantDigits","description":"Attribute: `minimum-significant-digits`","type":"number | undefined"},{"name":"noGrouping","description":"Shoelace grouping alias; equivalent to `withoutGrouping`.\n\nAttribute: `no-grouping`","type":"boolean","default":"false"},{"name":"notation","description":"Attribute: `notation`","type":"LyraFormatNumberNotation","default":"'standard'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"type","description":"Attribute: `type`","type":"LyraFormatNumberType","default":"'decimal'"},{"name":"value","description":"Attribute: `value`","type":"number","default":"0"},{"name":"withoutGrouping","description":"Web Awesome grouping alias. When both grouping aliases are false, `Intl` keeps the locale's\ndefault grouping policy rather than being forced on.\n\nAttribute: `without-grouping`","type":"boolean","default":"false"}]}},{"name":"lr-funnel","description":"`<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  Finite values whose positive ratio overflows also fill the main or comparison track.\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- Malformed/non-record entries and records without a string `label` are omitted while later\n  valid neighbors remain in either series; caller-owned arrays are never rewritten.\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.","attributes":[{"name":"comparison-label","description":"Name for the comparison series. Falls back to a localized generic label.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"dropoff","description":"Whether the change from the previous stage is rendered above each later stage.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"label","description":"Accessible name for the stage list. A host `aria-label` wins over it.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"share-precision","description":"Fraction digits used for every share and drop-off percentage.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}}],"js":{"properties":[{"name":"comparison","description":"An optional baseline/peer cohort drawn behind each bar as an outline. It is normalized to its\nOWN first stage, so a funnel's shape stays comparable against a baseline whose absolute\nvolumes are not comparable at all.","type":"readonly LyraFunnelStage[]","default":"[]"},{"name":"comparisonLabel","description":"Name for the comparison series. Falls back to a localized generic label.\n\nAttribute: `comparison-label`","type":"string","default":"''"},{"name":"dropoff","description":"Whether the change from the previous stage is rendered above each later stage.\n\nAttribute: `dropoff`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"label","description":"Accessible name for the stage list. A host `aria-label` wins over it.\n\nAttribute: `label`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"sharePrecision","description":"Fraction digits used for every share and drop-off percentage.\n\nAttribute: `share-precision`","type":"number","default":"0"},{"name":"stages","description":"The ordered stages, first to last. Every share is measured against the first entry.","type":"readonly LyraFunnelStage[]","default":"[]"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}]}},{"name":"lr-gauge","description":"`<lr-gauge>` — a radial, full-circle ring, or linear meter. First-party invention; no\ngeneric gauge widget exists in Web Awesome.\nThe host defaults to `role=\"meter\"` (or `img` when no finite range can be announced), while an\nauthor-supplied role remains authoritative. Visually abbreviated SVG captions retain their full\ncaller-owned text in a nested `<title>` tooltip.\n`variant` picks the fill's semantic palette directly; `thresholds` instead derives it from the\ncurrent `value`, falling back to `variant` while empty or while `value` matches no entry.\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 root `<svg>`. |\n| `fill` | The animated fill arc/line. |\n| `label` | The label text. Rendered only while `label` is non-empty. |\n| `track` | The background track arc/line. |\n| `value` | The value text. Rendered only while `showValue` is true. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-gauge-fill` (default: `var(--lr-color-brand)`) — Fill stroke for radial, ring, and linear gauges. The token default follows the effective variant -- `variant`, or the matching `thresholds` entry -- rather than always `brand`.","attributes":[{"name":"label","description":"Optional visible label. Attribute removal omits the SVG label and restores the localized\ngauge name unless an author supplied aria-label; the property retains null readback.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max","description":"Type: `number`  \nDefault: `100`","value":{"type":["number"]}},{"name":"min","description":"Type: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"shape","description":"Visual geometry. Named `shape` because this Lyra-original component is not a native input.\n\nType: `GaugeShape`  \nDefault: `'radial'`","value":{"type":["'radial'","'ring'","'linear'"]}},{"name":"show-value","description":"Whether the decorative `part=\"value\"` caption renders at all. The accessible value --\n`aria-valuenow`/`aria-valuetext` and the host's computed accessible name -- comes from\n`value`/`valueText` directly and stays correct either way, since the caption itself is\nalways `aria-hidden`. Mirrors `<lr-progress-bar>`'s and `<lr-progress-ring>`'s own\n`showValue` name and meaning; the default differs (`true` here, `false` there) because\nunlike a progress indicator, a gauge's whole purpose is showing the reading it announces, so\nhiding the caption is the opt-out rather than the opt-in -- leaving it unset renders exactly\nas before this property existed. Uses the shared parse-only `trueDefaultBooleanConverter`\nrather than Lit's default presence-based `type: Boolean` handling, so a plain-HTML consumer\nwith no way to write a `.showValue` property binding can still turn this off with\n`show-value=\"false\"`. Deliberately not reflected: nothing styles or queries\n`[show-value]`.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"size","description":"Density tier on the library's one size ladder, in either spelling — `2xs`/`xs`/`s`/`m`/`l`/\n`xl`, or Web Awesome's and Shoelace's `small`/`medium`/`large`. Opt-in: with no size the\ngauge keeps the ambient text size it inherits and the em-based frame it has always drawn, so\nexisting markup renders unchanged. A tier scales the frame, stroke geometry and both captions\ntogether, because the whole box is expressed in em and the tier sets the host font size.\nUnsupported values normalize to the omitted state and remove the attribute.\n\nType: `LyraSize | undefined`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}},{"name":"value","description":"Type: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"value-text","description":"Displayed/announced value text, e.g. `'72°F'` for a raw `value` of `72`.\nAn empty string is treated the same as unset and falls back to the numeric `value`.\n\nType: `string | undefined`"},{"name":"variant","description":"Semantic palette for the fill, read from the library's shared semantic-tone vocabulary\n(the same one `<lr-progress-bar>` uses). This is the fallback color: whenever `thresholds`\nis non-empty and `value` matches at least one entry, the matching entry's variant wins\ninstead.\n\nType: `LyraProgressVariant`  \nDefault: `'brand'`","value":{"type":["'neutral'","'brand'","'success'","'warning'","'danger'"]}}],"js":{"properties":[{"name":"label","description":"Optional visible label. Attribute removal omits the SVG label and restores the localized\ngauge name unless an author supplied aria-label; the property retains null readback.\n\nAttribute: `label`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"max","description":"Attribute: `max`","type":"number","default":"100"},{"name":"min","description":"Attribute: `min`","type":"number","default":"0"},{"name":"shape","description":"Visual geometry. Named `shape` because this Lyra-original component is not a native input.\n\nAttribute: `shape`  \nReflected to its attribute.","type":"GaugeShape","default":"'radial'"},{"name":"showValue","description":"Whether the decorative `part=\"value\"` caption renders at all. The accessible value --\n`aria-valuenow`/`aria-valuetext` and the host's computed accessible name -- comes from\n`value`/`valueText` directly and stays correct either way, since the caption itself is\nalways `aria-hidden`. Mirrors `<lr-progress-bar>`'s and `<lr-progress-ring>`'s own\n`showValue` name and meaning; the default differs (`true` here, `false` there) because\nunlike a progress indicator, a gauge's whole purpose is showing the reading it announces, so\nhiding the caption is the opt-out rather than the opt-in -- leaving it unset renders exactly\nas before this property existed. Uses the shared parse-only `trueDefaultBooleanConverter`\nrather than Lit's default presence-based `type: Boolean` handling, so a plain-HTML consumer\nwith no way to write a `.showValue` property binding can still turn this off with\n`show-value=\"false\"`. Deliberately not reflected: nothing styles or queries\n`[show-value]`.\n\nAttribute: `show-value`","type":"boolean","default":"true"},{"name":"size","description":"Density tier on the library's one size ladder, in either spelling — `2xs`/`xs`/`s`/`m`/`l`/\n`xl`, or Web Awesome's and Shoelace's `small`/`medium`/`large`. Opt-in: with no size the\ngauge keeps the ambient text size it inherits and the em-based frame it has always drawn, so\nexisting markup renders unchanged. A tier scales the frame, stroke geometry and both captions\ntogether, because the whole box is expressed in em and the tier sets the host font size.\nUnsupported values normalize to the omitted state and remove the attribute.\n\nAttribute: `size`  \nReflected to its attribute.","type":"LyraSize | undefined"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"thresholds","description":"Value-to-variant color mapping. The LAST entry (after sorting by `at`, regardless of\nauthored order) whose `at` is `<=` the current `value` wins; an entry whose `at` is not a\nfinite number never matches. Leaving this at its default empty array, or leaving `value`\nbelow every entry's `at`, renders with `variant` instead. See LyraGaugeThreshold\nfor the higher-is-worse/higher-is-better example pair this single rule supports.","type":"readonly LyraGaugeThreshold[]","default":"[]"},{"name":"value","description":"Attribute: `value`","type":"number","default":"0"},{"name":"valueText","description":"Displayed/announced value text, e.g. `'72°F'` for a raw `value` of `72`.\nAn empty string is treated the same as unset and falls back to the numeric `value`.\n\nAttribute: `value-text`","type":"string | undefined"},{"name":"variant","description":"Semantic palette for the fill, read from the library's shared semantic-tone vocabulary\n(the same one `<lr-progress-bar>` uses). This is the fallback color: whenever `thresholds`\nis non-empty and `value` matches at least one entry, the matching entry's variant wins\ninstead.\n\nAttribute: `variant`  \nReflected to its attribute.","type":"LyraProgressVariant","default":"'brand'"}]}},{"name":"lr-generation-metrics","description":"`<lr-generation-metrics>` — a compact, ticking status readout shown\nalongside an in-progress AI response: elapsed time, token count, and\ntoken-throughput, plus a built-in Stop button. Renders as e.g.\n`12.3s · 340 tokens · 27 tok/s [Stop]`.\n\nThis is deliberately a *different* concern than the already-landed\n`<lr-stream-status>`: that component is about transport/connection\nhealth (idle/connecting/streaming/stalled, heartbeat-aware stall\ndetection), while this one is a user-facing metrics readout for a\ngeneration that both components' hosts typically already know is\nhealthily in progress. Neither imports or depends on the other, and a\nconsumer building a full generation UI is expected to compose both side by\nside rather than pick one.\n\n`status=\"running\"` drives an internal ~1s `setInterval` ticker that recomputes the\nelapsed-time display (a plain interval is sufficient here -- unlike\n`<lr-stream-status>`'s stall timer, this never needs to be armed with a\nprecise deadline, only to refresh a display roughly once a second). The\nelapsed clock's start instant is `started-at` when set (an epoch-ms\ntimestamp -- lets a host that already knows exactly when generation began,\ne.g. from its own request-dispatch timestamp, feed that in directly and\nsurvive this component being created slightly later than that instant);\nwhen `started-at` is unset, this component captures `Date.now()` when\n`status` enters `running`. Entering `complete` clears the ticker and freezes\nthe elapsed summary; entering `idle` clears it and resets the readout to\nzero. This keeps never-started and completed generations distinct.\n\n`tokens-per-second`, when the host supplies a finite value directly (e.g. from its own\nsmoothed/windowed rate calculation), is clamped to zero or above and used. Non-finite values\nare treated as omitted. When omitted,\nthis component derives a live figure itself from `token-count` divided by\nelapsed seconds -- but only once at least one full second of elapsed time\nhas accumulated, since dividing by a sub-second elapsed window can produce\nwildly-swinging, misleading early readings (e.g. 3 tokens in 40ms reading\nas \"75 tok/s\"). A host that wants a stable figure from the very first tick\nshould supply `tokens-per-second` itself. The tokens segment and the\nthroughput segment are independently optional: either, both, or neither\nmay render depending on what's available, per each property's own doc.\n\nAccessibility: this readout ticks roughly once per second while running,\nwhich is exactly the kind of high-frequency update\n`<lr-live-region>`/`Announcer` (`../../internal/announcer.js`) exists to\n*prevent* from being read aloud verbatim -- routing a per-second numeric\ntick through even a throttled announcer would still narrate a new number\nto a screen-reader user roughly once every throttle window for as long as\ngeneration runs, which is noise, not information. This component\ntherefore carries no `role=\"status\"`/`aria-live` of its own and never\nannounces anything; a host that wants generation-start/-end announced\nshould pair this with something that announces state *transitions* (e.g.\n`<lr-typing-indicator>`'s mount-time announcement), not this ticking\nreadout. The one genuinely actionable, infrequent control here -- the Stop\nbutton -- gets a normal, always-present `aria-label`, no different from\nany other icon-only button in this library.\n\n---\n\n**Component metadata**\n\n- Status: `stable`\n- Since: `9.0.0`\n- Rationale: This tag entered Lyra as a stable public API with documented behavior, accessibility, and cross-browser support.\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 root inline layout container. |\n| `elapsed` | The elapsed-time segment, e.g. `\"12.3s\"`. Always rendered (reads `\"0.0s\"` while idle). |\n| `stop-button` | The built-in Stop button. Only rendered while `status=\"running\"` and `show-stop` is true. |\n| `throughput` | The throughput segment, e.g. `\"27 tok/s\"`. Only rendered when a value is available (host-supplied or derived; see the class doc). |\n| `tokens` | The token-count segment, e.g. `\"340 tokens\"`. Only rendered when `token-count` is set. |","attributes":[{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"show-stop","description":"Whether the built-in Stop button renders at all. Defaults to `true`.\nUses showStopConverter rather than Lit's default presence-based\n`type: Boolean` handling, so a plain-HTML consumer with no way to write\na `.showStop` property binding can still turn this off with\n`show-stop=\"false\"`; a Lit template can do the same with either that\nattribute string or a `.showStop=${false}` property binding.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"started-at","description":"Epoch-ms timestamp of when generation began. Optional -- when unset (or\nwhen set to a value that fails to parse as a finite number, e.g. an\nISO-8601 date string) while `status` is `running`, this component captures\nthe current time itself the moment `status` becomes `running` and counts\nfrom there instead (see the class doc).\n\nType: `number | undefined`"},{"name":"status","description":"Generation lifecycle. `idle` is never-started/reset, `running` ticks and permits Stop, and\n`complete` freezes the final metrics. Invalid attribute or JavaScript writes fail closed to\n`idle`.\n\nType: `GenerationMetricsStatus`","value":{"type":["'idle'","'running'","'complete'"]}},{"name":"token-count","description":"Running token count so far. Finite values are rounded to a non-negative integer; unset or\nnon-finite values omit the `tokens` segment entirely.\n\nType: `number | undefined`"},{"name":"tokens-per-second","description":"Host-computed tokens/sec figure. Finite values are clamped to zero or above; unset and\nnon-finite values fall back to a derived `token-count / elapsed-seconds` rate once at least\none second has elapsed.\n\nType: `number | undefined`"}],"js":{"properties":[{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"showStop","description":"Whether the built-in Stop button renders at all. Defaults to `true`.\nUses showStopConverter rather than Lit's default presence-based\n`type: Boolean` handling, so a plain-HTML consumer with no way to write\na `.showStop` property binding can still turn this off with\n`show-stop=\"false\"`; a Lit template can do the same with either that\nattribute string or a `.showStop=${false}` property binding.\n\nAttribute: `show-stop`","type":"boolean","default":"true"},{"name":"startedAt","description":"Epoch-ms timestamp of when generation began. Optional -- when unset (or\nwhen set to a value that fails to parse as a finite number, e.g. an\nISO-8601 date string) while `status` is `running`, this component captures\nthe current time itself the moment `status` becomes `running` and counts\nfrom there instead (see the class doc).\n\nAttribute: `started-at`","type":"number | undefined"},{"name":"status","description":"Generation lifecycle. `idle` is never-started/reset, `running` ticks and permits Stop, and\n`complete` freezes the final metrics. Invalid attribute or JavaScript writes fail closed to\n`idle`.\n\nAttribute: `status`  \nReflected to its attribute.","type":"GenerationMetricsStatus"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"tokenCount","description":"Running token count so far. Finite values are rounded to a non-negative integer; unset or\nnon-finite values omit the `tokens` segment entirely.\n\nAttribute: `token-count`","type":"number | undefined"},{"name":"tokensPerSecond","description":"Host-computed tokens/sec figure. Finite values are clamped to zero or above; unset and\nnon-finite values fall back to a derived `token-count / elapsed-seconds` rate once at least\none second has elapsed.\n\nAttribute: `tokens-per-second`","type":"number | undefined"}],"events":[{"name":"lr-stop","description":"The built-in Stop button was clicked. No detail payload.","type":"CustomEvent<null>"}]}},{"name":"lr-geojson-view","description":"Permanent compatibility class for the pre-v9 `lr-geojson-view` tag.\n\nUse `LyraGeoJsonViewer` and `lr-geojson-viewer` for new code. This distinct subclass preserves\n`instanceof LyraGeoJsonViewer` while allowing both tag names in one custom-elements registry.\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| `anchor-live-region` | The aria-hidden, non-live shadow mirror of the latest anchor-jump message. |\n| `base` | The root container with explicit `aria-busy`. It owns the named region in non-map states, the missing-peer fallback, and while a lazy map initializes; the loaded map canvas then owns that landmark. |\n| `error` | Visible ordinary error text; transitions announce through the shared document-level assertive region. |\n| `metadata` | Searchable, selectable serialized GeoJSON metadata; scrolls inline rather than widening a narrow allocation. |\n| `missing-library` | The missing-maplibre-gl callout shown alongside the json-viewer fallback. |\n| `spinner` | The decorative loading placeholder and its ordinary visually-hidden label; transitions announce through the shared document-level polite region. |\n| `status` | The ordinary feature-count line; a successful transition announces through the shared document-level polite region. |","attributes":[{"name":"active-highlight-id","description":"Id of the currently active highlight, or null when none is active.\n\nType: `string | null`  \nDefault: `null`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"name","description":"Accessible-name fallback for the current region owner: the root in non-map states, or the\nloaded map canvas when the optional peer is available.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"src","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}}],"js":{"properties":[{"name":"activeHighlightId","description":"Id of the currently active highlight, or null when none is active.\n\nAttribute: `active-highlight-id`","type":"string | null","default":"null"},{"name":"anchor","description":"Anchor or highlight id to resolve and scroll into view.","type":"LyraAnchor | string | null","default":"null"},{"name":"anchorKinds","description":"Anchor kinds supported by this viewer instance.","type":"readonly LyraAnchorKind[]","default":"[]","read-only":true},{"name":"highlights","description":"Highlights rendered by the document target. Reassign after mutation.","type":"LyraHighlight[]","default":"[]"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"name","description":"Accessible-name fallback for the current region owner: the root in non-map states, or the\nloaded map canvas when the optional peer is available.\n\nAttribute: `name`","type":"string","default":"''"},{"name":"src","description":"Attribute: `src`","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-anchor-result","description":"Fired after an `anchor` assignment or `scrollToAnchor()` call is applied. `detail: { found: boolean }`. Bubbling, composed, and non-cancelable.","type":"CustomEvent<AnchorResultDetail>"},{"name":"lr-render-error","description":"Fetch, parse, shape-validation, or missing-map-capability failure. `detail: { error }`. A missing optional MapLibre peer leaves the serialized metadata fallback visible while reporting the degraded map capability.","type":"CustomEvent<{ error: unknown }>"},{"name":"lr-search-change","description":"Fired whenever searchable metadata state changes. `matchCountExact=false` makes the retained count a lower bound. Bubbling, composed, and non-cancelable.","type":"CustomEvent<LyraSearchChangeDetail>"},{"name":"lr-text-select","description":"Fired after a selection ends inside the searchable metadata. `detail: { text: string; anchor: LyraAnchor | null; rects: DOMRect[] }`. Bubbling, composed, and non-cancelable.","type":"CustomEvent<TextSelectDetail>"}]}},{"name":"lr-geojson-viewer","description":"`<lr-geojson-viewer>` — document-registry bridge rendering a fetched GeoJSON file through\n`<lr-map>`'s `dataLayers`. The separately exported `<lr-geojson-view>` compatibility class\npreserves the earlier tag without sharing a custom-elements constructor.\nThe inherited fragment path performs an exact DOM `id` lookup, but the generated metadata,\nstatus, and map output define no fragment ids; such a jump reports `found: false`. Use a\ntext-quote anchor for the serialized metadata.\n\n---\n\n**Component metadata**\n\n- Status: `stable`\n- Since: `9.0.0`\n- Rationale: This tag entered Lyra as a stable public API with documented behavior, accessibility, and cross-browser support.\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| `anchor-live-region` | The aria-hidden, non-live shadow mirror of the latest anchor-jump message. |\n| `base` | The root container with explicit `aria-busy`. It owns the named region in non-map states, the missing-peer fallback, and while a lazy map initializes; the loaded map canvas then owns that landmark. |\n| `error` | Visible ordinary error text; transitions announce through the shared document-level assertive region. |\n| `metadata` | Searchable, selectable serialized GeoJSON metadata; scrolls inline rather than widening a narrow allocation. |\n| `missing-library` | The missing-maplibre-gl callout shown alongside the json-viewer fallback. |\n| `spinner` | The decorative loading placeholder and its ordinary visually-hidden label; transitions announce through the shared document-level polite region. |\n| `status` | The ordinary feature-count line; a successful transition announces through the shared document-level polite region. |","attributes":[{"name":"active-highlight-id","description":"Id of the currently active highlight, or null when none is active.\n\nType: `string | null`  \nDefault: `null`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"name","description":"Accessible-name fallback for the current region owner: the root in non-map states, or the\nloaded map canvas when the optional peer is available.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"src","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}}],"js":{"properties":[{"name":"activeHighlightId","description":"Id of the currently active highlight, or null when none is active.\n\nAttribute: `active-highlight-id`","type":"string | null","default":"null"},{"name":"anchor","description":"Anchor or highlight id to resolve and scroll into view.","type":"LyraAnchor | string | null","default":"null"},{"name":"anchorKinds","description":"Anchor kinds supported by this viewer instance.","type":"readonly LyraAnchorKind[]","default":"[]","read-only":true},{"name":"highlights","description":"Highlights rendered by the document target. Reassign after mutation.","type":"LyraHighlight[]","default":"[]"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"name","description":"Accessible-name fallback for the current region owner: the root in non-map states, or the\nloaded map canvas when the optional peer is available.\n\nAttribute: `name`","type":"string","default":"''"},{"name":"src","description":"Attribute: `src`","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-anchor-result","description":"Fired after an `anchor` assignment or `scrollToAnchor()` call is applied. `detail: { found: boolean }`. Bubbling, composed, and non-cancelable.","type":"CustomEvent<AnchorResultDetail>"},{"name":"lr-render-error","description":"Fetch, parse, shape-validation, or missing-map-capability failure. `detail: { error }`. A missing optional MapLibre peer leaves the serialized metadata fallback visible while reporting the degraded map capability.","type":"CustomEvent<{ error: unknown }>"},{"name":"lr-search-change","description":"Fired whenever searchable metadata state changes. `matchCountExact=false` makes the retained count a lower bound. Bubbling, composed, and non-cancelable.","type":"CustomEvent<LyraSearchChangeDetail>"},{"name":"lr-text-select","description":"Fired after a selection ends inside the searchable metadata. `detail: { text: string; anchor: LyraAnchor | null; rects: DOMRect[] }`. Bubbling, composed, and non-cancelable.","type":"CustomEvent<TextSelectDetail>"}]}},{"name":"lr-graph","description":"`<lr-graph>` — a force-directed node-link diagram with pan/zoom/drag.\nRequires the optional peer deps `d3-force`/`d3-drag`/`d3-zoom`/`d3-selection`\n(lazy-loaded; a consumer who never uses this component pays zero d3 cost).\n\nSet `seed` for a deterministic layout: node initial positions become\nreproducible (keyed by node id) and the settle happens synchronously\ninstead of animating, like `prefers-reduced-motion`. `seed` only takes\neffect on the update that first populates `nodes`/`links` (or a later\nupdate that adds genuinely new node ids) — willUpdate() only reads it from\ninside rebuildSimulation(), which itself only ever assigns x/y to nodes\nthat don't already have a settled position, so changing `seed` on an\nalready-rendered graph is a no-op; nothing re-derives already-positioned\nnodes' x/y from the new value.\n\n`hiddenTypes` filters nodes/links by `LyraGraphNode.type` without discarding position state --\n`lastPositionById` remembers every node's last settled x/y across a hide/show round-trip, so\ntoggling a type off and back on restores each node where it was instead of re-randomizing it.\n\n`communities` draws one translucent convex-hull blob per entry, behind links/nodes -- a hull's\nmembership is the union of its own `memberIds` and every node whose `communityId` matches its\n`id`. A community with no currently-visible members (all its nodes hidden by `hiddenTypes`, or\nsimply empty) renders no hull.\n\n`layout=\"layered\"` swaps the d3-force simulation for a deterministic layered layout (see\n`src/internal/layered-layout.ts`) -- node drag is disabled in that mode, and `chargeStrength` is\na documented no-op.\n\n`renderer=\"canvas\"` swaps the per-node/per-link SVG DOM for a single DPR-aware `<canvas>` --\nevery event/method/property behaves identically to `renderer=\"svg\"` (the default), with hit-\ntesting resolved via an offscreen color-picking canvas instead of DOM event targets. The\ndocumented trade-offs: no `::part(node)`/`::part(link)` styling (pixels, not elements -- theme\nvia cssprops instead), no native SVG `<title>` tooltip (replaced by `part=\"tooltip\"`), and a\ndrawn focus ring instead of a CSS one. Keyboard roving/announcements are preserved through an\noffscreen `part=\"cursor-item\"` button per node/link/hull, driving the identical roving-tabindex\nlogic as `renderer=\"svg\"`. Both renderers skip nonoperable links when moving real keyboard\nfocus. Zero-width links retain topology but paint neither a stroke nor an arrowhead.\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**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `arrowhead` | The marker used by directed graph links. |\n| `base` | The graph wrapper. |\n| `canvas` | The single canvas surface (`renderer=\"canvas\"` only). |\n| `community-label` | A hull's label text. |\n| `cursor-item` | An offscreen keyboard-roving item (`renderer=\"canvas\"`'s a11y virtual cursor). |\n| `cursor-items` | The container of offscreen keyboard-roving items (`renderer=\"canvas\"` only). |\n| `data-list` | A visually hidden list alternative for graph data. |\n| `empty` | The empty-state message, shown when `nodes` is empty. |\n| `error` | Static visible error shown instead of the graph when the optional `d3` peer dependency is not installed; its transition is announced through a shared light-DOM alert. |\n| `expand-indicator` | The \"+\" badge rendered on a node with `expandable: true`. |\n| `focus-halo` | The persistent ring tracking `focusNodeId`'s node. |\n| `hull` | A community hull (behind links/nodes; role=\"button\"). |\n| `label` | A node label (`renderer=\"svg\"` only; not rendered at all when `nodeLabels` is `'none'`). |\n| `link` | A graph link. |\n| `link-label` | A drawn edge label (only rendered when `showEdgeLabels` is set). |\n| `live-region` | The aria-hidden shadow mirror of the current graph item announcement; assistive-technology announcements use a shared light-DOM sink. |\n| `node` | A graph node. |\n| `svg` | The graph SVG. |\n| `tooltip` | The hover tooltip (`renderer=\"canvas\"` only; the SVG `<title>` replacement). |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-canvas-reserved-height` (default: `var(--lr-size-24rem)`) — Default host block size, shared with the pre-upgrade reservation stylesheet. Below this in the fallback chain, the normalized `height` property sizes the host too (a private custom property, not itself settable) -- setting this always overrides `height`, and an explicit outer `block-size` still wins over both.\n- `--lr-graph-cat-1` (default: `var(--lr-theme-graph-cat-1,#8250df)`) — First categorical fallback color for typed nodes.\n- `--lr-graph-cat-2` (default: `var(--lr-theme-graph-cat-2,#bf3989)`) — Second categorical fallback color for typed nodes.\n- `--lr-graph-cat-3` (default: `var(--lr-theme-graph-cat-3,#0a7d91)`) — Third categorical fallback color for typed nodes.\n- `--lr-graph-cat-4` (default: `var(--lr-theme-graph-cat-4,#57606a)`) — Fourth categorical fallback color for typed nodes.\n- `--lr-graph-cat-5` (default: `var(--lr-theme-graph-cat-5,#b083f5)`) — Fifth categorical fallback color for typed nodes.\n- `--lr-graph-cat-6` (default: `var(--lr-theme-graph-cat-6,#f470b8)`) — Sixth categorical fallback color for typed nodes.\n- `--lr-graph-cat-7` (default: `var(--lr-theme-graph-cat-7,#52d6e8)`) — Seventh categorical fallback color for typed nodes.\n- `--lr-graph-cat-8` (default: `var(--lr-theme-graph-cat-8,#c9d1d9)`) — Eighth categorical fallback color for typed nodes; the palette wraps for later `nodeTypes` entries.\n- `--lr-graph-dimmed-opacity` (default: `0.35`) — Opacity applied to a node/link when `dimmedNodeIds`/`dimmedLinkIds` includes its id (both SVG and canvas renderers). Visible by default -- a consumer controlling `dimmedNodeIds`/`dimmedLinkIds` (e.g. `lr-knowledge-graph-explorer`) sees the dimming take effect with no extra host styling.\n- `--lr-graph-edge-label-halo` (default: `var(--lr-color-surface)`) — Legibility halo (`stroke`) behind a drawn edge label, painted under the fill via `paint-order: stroke`.\n- `--lr-graph-focus-halo-color` (default: `var(--lr-color-brand)`) — `focus-halo` stroke color.\n- `--lr-graph-hull-fill` (default: `var(--lr-color-brand)`) — Hull fill/stroke color.\n- `--lr-graph-hull-opacity` (default: `0.12`) — Hull element opacity (composites fill+stroke as one group, avoiding a double-opacity seam at the fill/stroke boundary). Applies to both SVG and canvas renderers.\n- `--lr-graph-selected-color` (default: `var(--lr-color-success)`) — Selected node/link stroke.\n- `--lr-link-color` (default: `var(--lr-color-border)`) — Default link stroke, overridden per-link by a link's own `color`.\n- `--lr-node-fill` (default: `var(--lr-color-brand)`) — Default node fill, overridden per-node by `LyraGraphNode.color`.","attributes":[{"name":"aria-label","description":"Accessible name for the graph. A present host `aria-label`, including an explicitly empty\none, makes this host the sole graph owner; otherwise the SVG/canvas owns the localized name.\n\nType: `string | null`  \nDefault: `null`"},{"name":"charge-strength","description":"Many-body force strength used by the force layout. Negative values repel nodes.\n\nType: `number`  \nDefault: `-300`","value":{"type":["number"]}},{"name":"edge-label-min-zoom","description":"Below this zoom scale, every drawn edge label is hidden (a `data-edge-labels-hidden`\nattribute toggled on the zoomed `<g>`, no Lit re-render). Ignored when `showEdgeLabels` is\nfalse.\n\nType: `number`  \nDefault: `0.6`","value":{"type":["number"]}},{"name":"fit-to","description":"Where the drawing space comes from. `'none'` (the default) uses the numeric `width`/`height`\nbelow, unchanged. `'container'` measures the host's own content box -- through the same\n`ResizeObserver` the canvas renderer already owns -- and feeds that measurement to the SVG\n`viewBox`, the layout's centering force, `focusNode()`/`fit()`'s camera math and the loading\nskeleton, so the drawing always matches the box it is rendered into and no host-side observer\nis needed. A resize re-centers the running layout in place (`forceCenter` plus a low-alpha\nrestart); it never rebuilds the simulation, so settled positions survive. While\n`'container'` is in effect the measured box wins over `width`/`height`, which stay the\nexplicit override path under the `'none'` default. This does not change how the host itself\nis sized -- an outer `block-size`, `--lr-canvas-reserved-height` and `height` still do that,\nand `'container'` simply follows whichever of them won. Falls back to `width`/`height` when\nthe box is unmeasurable (detached, `display: none`, or a realm with no `ResizeObserver`).\n\nType: `LyraGraphFit`  \nDefault: `'none'`","value":{"type":["'none'","'container'"]}},{"name":"focus-node-id","description":"Declaratively centers the camera on this node id once, the first time it resolves (on mount\nor when the id first appears in `nodes`) -- does not re-center on later mutations, so it\ncan't fight a user's panning on a streaming graph. Renders a persistent halo\n(`part=\"focus-halo\"`) around the node while set. See `focusNode()` for the imperative twin.\n\nType: `string | null`  \nDefault: `null`"},{"name":"height","description":"Requested graph viewport height in CSS pixels. Also sizes the rendered host itself (see\n`--lr-canvas-reserved-height`'s doc) whenever neither that nor an explicit outer `block-size`\noverrides it. Only the drawing space is ignored while `fitTo === 'container'`; the host\nsizing above still applies.\n\nType: `number`  \nDefault: `600`","value":{"type":["number"]}},{"name":"layout","description":"`'force'` (default) runs the existing d3-force simulation, untouched. `'layered'` computes a\ndeterministic Sugiyama-lite layout (`src/internal/layered-layout.ts`, a shared,\ndependency-free util suitable for any future layered-diagram consumer) instead -- no settle\nanimation, node drag disabled (dragging would fight a computed layout), `chargeStrength` a\ndocumented no-op, `linkDistance` retunes the layer gap. Switching at runtime repositions\nwithout a tween.\n\nType: `LyraGraphLayout`","value":{"type":["'force'","'layered'"]}},{"name":"link-distance","description":"Preferred link length for force layout and layer separation for layered layout.\n\nType: `number`  \nDefault: `100`","value":{"type":["number"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max-zoom","description":"Maximum camera scale accepted by zoom interactions; updates live in both renderers.\n\nType: `number`  \nDefault: `8`","value":{"type":["number"]}},{"name":"min-zoom","description":"Minimum camera scale accepted by zoom interactions; updates live in both renderers.\n\nType: `number`  \nDefault: `0.1`","value":{"type":["number"]}},{"name":"node-labels","description":"Node-label visibility. `'always'` draws every node's label unconditionally; `'zoom'` hides\nthem below `NODE_LABEL_MIN_ZOOM` (a `data-node-labels-hidden` attribute toggled on the zoomed\n`<g>`, mirroring `showEdgeLabels`/`edgeLabelMinZoom`'s own zoom-gate mechanism, no Lit\nre-render); `'none'` never renders them. Unset (the default) preserves each renderer's\npre-existing behavior exactly -- `'always'` for `renderer=\"svg\"`, `'zoom'` for\n`renderer=\"canvas\"` -- so this stays a purely additive opt-in.\n\nType: `LyraGraphNodeLabelsMode | undefined`","value":{"type":["'always'","'zoom'","'none'"]}},{"name":"renderer","description":"`'svg'` (default, unchanged) renders the existing per-node/per-link DOM. `'canvas'` swaps to\na single `<canvas part=\"canvas\">` -- the scale path (an honest ceiling for `'svg'`: dozens to\nlow hundreds of nodes; `'canvas'` targets roughly 5,000 nodes / 10,000 links). Feature-reduced\nby design: no `::part(node)`/`::part(link)` styling (pixels, not elements -- theme via\ncssprops), no SVG `<title>`, a drawn focus ring instead of a CSS one. All events/methods/\nprops otherwise behave identically across renderers. Runtime changes tear down and rebuild\nthe surface; positions survive via `prevById`/`lastPositionById`.\n\nType: `LyraGraphRenderer`  \nDefault: `'svg'`","value":{"type":["'svg'","'canvas'"]}},{"name":"seed","description":"When set, seeds each node's initial x/y deterministically (keyed by\nnode id, not array index) instead of forceSimulation()'s own random\nstart, and settles the simulation synchronously — see rebuildSimulation().\nOnly takes effect on the update that first assigns a given node id an\nx/y (i.e. supplied at/before `nodes`/`links` first populate, or when a\nlater update introduces new node ids) — changing `seed` afterwards does\nnot retroactively reposition already-settled nodes; there is currently\nno way to make an already-rendered graph reproducible after the fact.\n\nType: `number | undefined`"},{"name":"selection-mode","description":"`'none'` (default) preserves today's behavior exactly -- no `aria-pressed`/`data-selected`,\nno `lr-selection-change`. Controlled, mirroring `lr-heatmap.selectedCell`: the component\nnever mutates `selectedNodeIds`/`selectedLinkIds` itself, only emits intent; the host assigns\nthem back.\n\nType: `LyraGraphSelectionMode`  \nDefault: `'none'`","value":{"type":["'none'","'single'","'multiple'"]}},{"name":"show-edge-labels","description":"Draws each resolved (non-dangling) link's `label` as visible SVG text at the segment\nmidpoint. Off by default — `LyraGraphLink.label` stays spoken/tooltip-only, matching today's\nbehavior, unless this is set.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"width","description":"Requested graph viewport width in CSS pixels. Ignored while `fitTo === 'container'`.\n\nType: `number`  \nDefault: `800`","value":{"type":["number"]}}],"js":{"properties":[{"name":"accessibleLabel","description":"Accessible name for the graph. A present host `aria-label`, including an explicitly empty\none, makes this host the sole graph owner; otherwise the SVG/canvas owns the localized name.\n\nAttribute: `aria-label`","type":"string | null","default":"null"},{"name":"chargeStrength","description":"Many-body force strength used by the force layout. Negative values repel nodes.\n\nAttribute: `charge-strength`","type":"number","default":"-300"},{"name":"communities","description":"Renders one translucent hull per entry, behind links/nodes. Membership is the union of\n`memberIds` and every node whose `communityId` matches this entry's `id`.","type":"readonly LyraGraphCommunity[]","default":"[]"},{"name":"dimmedLinkIds","description":"Same contract as `dimmedNodeIds`, for links. A link's dimming key is the same `linkKey()`\nvalue (`LyraGraphLink.id`, else `` `${source}->${target}` ``) `selectedLinkIds` already uses.","type":"readonly string[]","default":"[]"},{"name":"dimmedNodeIds","description":"Node ids to render dimmed (`data-dimmed` on the matching `[part=\"node\"]`, themeable via\n`--lr-graph-dimmed-opacity`). Controlled, mirroring `selectedNodeIds`/`selectedLinkIds`: the\ncomponent never assigns this itself, only renders it -- a host typically computes it from a\n`lr-node-enter`/`lr-link-enter` hover (the complement of the hovered id's neighbor set,\ncomputed from the host's own `links` array) and assigns the result back. Empty (the default)\nrenders every node at full opacity, unchanged from today.","type":"readonly string[]","default":"[]"},{"name":"edgeLabelMinZoom","description":"Below this zoom scale, every drawn edge label is hidden (a `data-edge-labels-hidden`\nattribute toggled on the zoomed `<g>`, no Lit re-render). Ignored when `showEdgeLabels` is\nfalse.\n\nAttribute: `edge-label-min-zoom`","type":"number","default":"0.6"},{"name":"fitTo","description":"Where the drawing space comes from. `'none'` (the default) uses the numeric `width`/`height`\nbelow, unchanged. `'container'` measures the host's own content box -- through the same\n`ResizeObserver` the canvas renderer already owns -- and feeds that measurement to the SVG\n`viewBox`, the layout's centering force, `focusNode()`/`fit()`'s camera math and the loading\nskeleton, so the drawing always matches the box it is rendered into and no host-side observer\nis needed. A resize re-centers the running layout in place (`forceCenter` plus a low-alpha\nrestart); it never rebuilds the simulation, so settled positions survive. While\n`'container'` is in effect the measured box wins over `width`/`height`, which stay the\nexplicit override path under the `'none'` default. This does not change how the host itself\nis sized -- an outer `block-size`, `--lr-canvas-reserved-height` and `height` still do that,\nand `'container'` simply follows whichever of them won. Falls back to `width`/`height` when\nthe box is unmeasurable (detached, `display: none`, or a realm with no `ResizeObserver`).\n\nAttribute: `fit-to`","type":"LyraGraphFit","default":"'none'"},{"name":"focusNodeId","description":"Declaratively centers the camera on this node id once, the first time it resolves (on mount\nor when the id first appears in `nodes`) -- does not re-center on later mutations, so it\ncan't fight a user's panning on a streaming graph. Renders a persistent halo\n(`part=\"focus-halo\"`) around the node while set. See `focusNode()` for the imperative twin.\n\nAttribute: `focus-node-id`","type":"string | null","default":"null"},{"name":"height","description":"Requested graph viewport height in CSS pixels. Also sizes the rendered host itself (see\n`--lr-canvas-reserved-height`'s doc) whenever neither that nor an explicit outer `block-size`\noverrides it. Only the drawing space is ignored while `fitTo === 'container'`; the host\nsizing above still applies.\n\nAttribute: `height`","type":"number","default":"600"},{"name":"hiddenTypes","description":"Hides every node whose raw `type` value is listed here (no matching `nodeTypes` entry\nrequired), plus every link incident to a hidden node -- removed from the render, the\nsimulation input, the keyboard roving ring, the sr-only data list, and the accessible\ndiagram counts, as if absent. Positions round-trip via `lastPositionById`: toggling a type\noff and back on restores each node where it was.","type":"readonly string[]","default":"[]"},{"name":"layout","description":"`'force'` (default) runs the existing d3-force simulation, untouched. `'layered'` computes a\ndeterministic Sugiyama-lite layout (`src/internal/layered-layout.ts`, a shared,\ndependency-free util suitable for any future layered-diagram consumer) instead -- no settle\nanimation, node drag disabled (dragging would fight a computed layout), `chargeStrength` a\ndocumented no-op, `linkDistance` retunes the layer gap. Switching at runtime repositions\nwithout a tween.\n\nAttribute: `layout`","type":"LyraGraphLayout"},{"name":"linkDistance","description":"Preferred link length for force layout and layer separation for layered layout.\n\nAttribute: `link-distance`","type":"number","default":"100"},{"name":"links","description":"Directed or undirected connections between node ids in `nodes`.","type":"readonly LyraGraphLink[]","default":"[]"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"maxZoom","description":"Maximum camera scale accepted by zoom interactions; updates live in both renderers.\n\nAttribute: `max-zoom`","type":"number","default":"8"},{"name":"minZoom","description":"Minimum camera scale accepted by zoom interactions; updates live in both renderers.\n\nAttribute: `min-zoom`","type":"number","default":"0.1"},{"name":"nodeLabels","description":"Node-label visibility. `'always'` draws every node's label unconditionally; `'zoom'` hides\nthem below `NODE_LABEL_MIN_ZOOM` (a `data-node-labels-hidden` attribute toggled on the zoomed\n`<g>`, mirroring `showEdgeLabels`/`edgeLabelMinZoom`'s own zoom-gate mechanism, no Lit\nre-render); `'none'` never renders them. Unset (the default) preserves each renderer's\npre-existing behavior exactly -- `'always'` for `renderer=\"svg\"`, `'zoom'` for\n`renderer=\"canvas\"` -- so this stays a purely additive opt-in.\n\nAttribute: `node-labels`","type":"LyraGraphNodeLabelsMode | undefined"},{"name":"nodeTypes","description":"Declares each `LyraGraphNode.type` value's legend label, fill color, and shape. A typed node with\nno matching entry here renders as untyped (default circle, token fill) but still participates\nin `hiddenTypes` filtering by its raw `type` string.","type":"readonly LyraNodeTypeStyle[]","default":"[]"},{"name":"nodes","description":"Readonly nodes in the controlled graph model. Node ids provide stable render and interaction identity.","type":"readonly LyraGraphNode[]","default":"[]"},{"name":"renderer","description":"`'svg'` (default, unchanged) renders the existing per-node/per-link DOM. `'canvas'` swaps to\na single `<canvas part=\"canvas\">` -- the scale path (an honest ceiling for `'svg'`: dozens to\nlow hundreds of nodes; `'canvas'` targets roughly 5,000 nodes / 10,000 links). Feature-reduced\nby design: no `::part(node)`/`::part(link)` styling (pixels, not elements -- theme via\ncssprops), no SVG `<title>`, a drawn focus ring instead of a CSS one. All events/methods/\nprops otherwise behave identically across renderers. Runtime changes tear down and rebuild\nthe surface; positions survive via `prevById`/`lastPositionById`.\n\nAttribute: `renderer`","type":"LyraGraphRenderer","default":"'svg'"},{"name":"seed","description":"When set, seeds each node's initial x/y deterministically (keyed by\nnode id, not array index) instead of forceSimulation()'s own random\nstart, and settles the simulation synchronously — see rebuildSimulation().\nOnly takes effect on the update that first assigns a given node id an\nx/y (i.e. supplied at/before `nodes`/`links` first populate, or when a\nlater update introduces new node ids) — changing `seed` afterwards does\nnot retroactively reposition already-settled nodes; there is currently\nno way to make an already-rendered graph reproducible after the fact.\n\nAttribute: `seed`","type":"number | undefined"},{"name":"selectedLinkIds","description":"Controlled ids of selected links, using each link's stable effective key.","type":"readonly string[]","default":"[]"},{"name":"selectedNodeIds","description":"Controlled ids of selected nodes. Selection gestures emit intent without mutating this array.","type":"readonly string[]","default":"[]"},{"name":"selectionMode","description":"`'none'` (default) preserves today's behavior exactly -- no `aria-pressed`/`data-selected`,\nno `lr-selection-change`. Controlled, mirroring `lr-heatmap.selectedCell`: the component\nnever mutates `selectedNodeIds`/`selectedLinkIds` itself, only emits intent; the host assigns\nthem back.\n\nAttribute: `selection-mode`","type":"LyraGraphSelectionMode","default":"'none'"},{"name":"showEdgeLabels","description":"Draws each resolved (non-dangling) link's `label` as visible SVG text at the segment\nmidpoint. Off by default — `LyraGraphLink.label` stays spoken/tooltip-only, matching today's\nbehavior, unless this is set.\n\nAttribute: `show-edge-labels`","type":"boolean","default":"false"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"width","description":"Requested graph viewport width in CSS pixels. Ignored while `fitTo === 'container'`.\n\nAttribute: `width`","type":"number","default":"800"}],"events":[{"name":"lr-community-click","description":"A hull was activated. `detail: { communityId }`.","type":"CustomEvent<{ communityId: string }>"},{"name":"lr-link-click","description":"`detail: { sourceNodeId, targetNodeId, linkId? }`.","type":"CustomEvent<{\n    sourceNodeId: string;\n    targetNodeId: string;\n    linkId?: string;\n  }>"},{"name":"lr-link-enter","description":"A link was hovered. `detail: { sourceNodeId, targetNodeId, linkId? }`. Same suppression/`data-hovered` behavior as `lr-node-enter`.","type":"CustomEvent<{\n    sourceNodeId: string;\n    targetNodeId: string;\n    linkId?: string;\n  }>"},{"name":"lr-link-leave","description":"The hover from `lr-link-enter` ended. `detail: { sourceNodeId, targetNodeId, linkId? }`.","type":"CustomEvent<{\n    sourceNodeId: string;\n    targetNodeId: string;\n    linkId?: string;\n  }>"},{"name":"lr-node-click","description":"`detail: { nodeId, x, y }`, where `x` and `y` are the node's current coordinates in the graph's local drawing space.","type":"CustomEvent<{ nodeId: string; x: number; y: number }>"},{"name":"lr-node-enter","description":"A node was hovered. `detail: { nodeId }`. Suppressed while dragging or panning. Canvas enter/leave events fire once per hit-identity transition or exit. In SVG, also toggles a `data-hovered` attribute on that node's `[part=\"node\"]` element for pure-CSS theming (not a substitute for this event — a consumer computing its own adjacency-based highlight needs the id, which only the event carries).","type":"CustomEvent<{ nodeId: string }>"},{"name":"lr-node-expand","description":"A node was double-activated (native `dblclick`, or two Enter/Space activations of the same focused node within 500ms). `detail: { nodeId }`. Fires for any node regardless of `LyraGraphNode.expandable` -- that flag only controls the visual \"+\" affordance and spoken \"expandable\" suffix.","type":"CustomEvent<{ nodeId: string }>"},{"name":"lr-node-leave","description":"The hover from `lr-node-enter` ended. `detail: { nodeId }`.","type":"CustomEvent<{ nodeId: string }>"},{"name":"lr-selection-change","description":"`detail: { nodeIds, linkIds }`. Fires when `selectionMode` is not `'none'` and the user activates/clears a node or link. The component never assigns `selectedNodeIds`/`selectedLinkIds` itself -- controlled, mirroring `lr-heatmap.selectedCell`.","type":"CustomEvent<\n    LyraEventDetailSnapshot<{ nodeIds: string[]; linkIds: string[] }>\n  >"},{"name":"lr-viewport-change","description":"`detail: { k, x, y }`, the live d3-zoom camera transform. Fires at most once per animation frame regardless of how many pan/zoom/simulation-tick updates land within it, coalescing every source that can move a rendered node's screen position -- a user pan/zoom gesture, `focusNode()`/`fit()`'s camera tween, and every d3-force simulation tick (dragging a node, or the initial settle). A consumer anchoring its own UI (e.g. a details popover) to a node's `getBoundingClientRect()` can re-read it from this event instead of polling on a `requestAnimationFrame` loop of its own.","type":"CustomEvent<{ k: number; x: number; y: number }>"}]}},{"name":"lr-graph-legend","description":"`<lr-graph-legend>` — a node-type legend for a paired `lr-graph`: one swatch + label + count\nrow per `lr-graph` node type, doubling as visibility filters. Never reads or writes a graph directly —\nthe host forwards `types` in from `graph.nodeTypes` and `hiddenTypes` back out to\n`graph.hiddenTypes` on `lr-visibility-change`, the same event-decoupled contract every sibling\nin this family follows.\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.\nRows without a nonblank string `id` and `label`, plus later duplicate ids, are omitted so an\nuntyped payload cannot create an unnamed interactive filter.\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 legend wrapper. It owns `role=\"group\"` and the fallback name unless a non-empty host `aria-label` makes the host the sole overall owner. |\n| `count` | The optional per-type count. |\n| `item` | One row per type — a `<button>` when `interactive`, a plain `<div>` otherwise. |\n| `label` | The type's label text. |\n| `live-region` | The visually hidden filter-toggle announcement. |\n| `swatch` | The type's shape glyph. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-graph-legend-hidden-color` (default: `var(--lr-color-text-quiet)`) — Text color for a filtered-out (hidden) legend row's label/count, independent of the shared quiet-text token.\n- `--lr-graph-legend-hidden-swatch-opacity` (default: `0.5`) — Opacity of a filtered-out row's decorative swatch.","attributes":[{"name":"interactive","description":"`false` renders a read-only legend (no buttons, no toggling).\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"label","description":"Fallback name for the group; defaults to localized `graphLegendLabel`. A non-empty host\n`aria-label` makes the host the sole overall owner; an explicitly empty host label stays\nempty on the group.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"js":{"properties":[{"name":"counts","description":"Optional per-type node counts keyed by type id; a type with no entry renders no count.","type":"Readonly<Record<string, number>> | undefined"},{"name":"hiddenTypes","description":"Currently-hidden type ids. The legend toggles its own copy on activation *then* emits; a host\nmay also treat this as controlled by reassigning it after each event.","type":"readonly string[]","default":"[]"},{"name":"interactive","description":"`false` renders a read-only legend (no buttons, no toggling).\n\nAttribute: `interactive`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"label","description":"Fallback name for the group; defaults to localized `graphLegendLabel`. A non-empty host\n`aria-label` makes the host the sole overall owner; an explicitly empty host label stays\nempty on the group.\n\nAttribute: `label`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"types","description":"The `lr-graph.nodeTypes` array, passed through verbatim.","type":"readonly LyraNodeTypeStyle[]","default":"[]"}],"events":[{"name":"lr-before-visibility-change","description":"Cancelable proposed visibility change. `detail: { hiddenTypes }` is a frozen complete next array; canceling leaves state, announcements, and the post event unchanged.","type":"CustomEvent<\n    LyraEventDetailSnapshot<LyraGraphLegendVisibilityDetail>\n  >"},{"name":"lr-visibility-change","description":"`detail: { hiddenTypes }` — the complete updated array, fired after an accepted toggle has assigned and announced it.","type":"CustomEvent<\n    LyraEventDetailSnapshot<LyraGraphLegendVisibilityDetail>\n  >"}]}},{"name":"lr-graph-query-builder","description":"`<lr-graph-query-builder>` — an editor for a single typed relationship/path filter\n(`GraphQuery`) over a knowledge graph: start/end entity anchors, relationship-type and\nnode-type pickers with a removable active-filter chip display, a traversal direction, a\nmin/max hop range, validation, and a host-persisted saved-query list -- a serializable query\nmodel for GraphRAG workflows (feed the `value`/`lr-query-run` payload straight to a retrieval\nor traversal backend).\n\nComposes `<lr-select>` for every closed-choice picker (relationship type, node type,\ndirection, hop counts) and `<lr-input>` for the free-text entity ids -- the relationship/\nnode-type pickers are \"add\" selects: choosing an option appends it to the corresponding\narray and the picker itself resets to its placeholder, so the *current* selection is shown\nseparately as a row of removable `<lr-chip>`s inside an `<lr-chip-group>` (click a chip's\nremove button to drop that one type). A type value present in `value` but missing from\n`relationshipTypeOptions`/`nodeTypeOptions` (e.g. a saved query referencing a type that was\nsince renamed/removed from the picker's own option list) still renders as a chip, labeled with\nits raw value, rather than being silently dropped.\nRemoving a focused filter chip moves focus to its adjacent survivor or the matching add picker.\nWhen the host applies a focused saved-query deletion, focus follows the adjacent delete action\nor the stable save-name input; unrelated controlled updates never steal external focus.\n\n**Query model placement:** `GraphQuery` is kept local to this component rather than promoted\nto the shared `src/ai/types.ts` surface. Unlike that module's types (`ChatMessage`,\n`Citation`, `RetrievalQuery`, etc.), which each mirror a shape multiple existing primitives\nalready consume, `GraphQuery` is specific to this component's own editable-filter-set shape\n(its `minHops`/`maxHops` selects, its \"add picker + chip list\" editing idiom) -- no other\ncomponent reads or produces this exact shape today. This mirrors `<lr-rubric-form>`'s\n`RubricValue`/`RubricKey` and `<lr-tool-param-form>`'s `ToolParamFormSchema`, both also kept\nlocal to their own component for the identical reason.\n\n**Form association:** every other \"structured, non-string value\" editor in this package that\nlooks like this one -- `<lr-rubric-form>`, `<lr-tool-param-form>`, `<lr-time-range>` -- attaches\n`ElementInternals` directly (the `FormAssociated` mixin only fits a plain string value) and\ntreats native `<form>` participation as a nice-to-have layered on top of its primary\n`value`/`lr-input`/`lr-validity-change` integration contract, not a requirement. This component\nfollows that same established convention: `value` round-trips through `JSON.stringify()` as the\nsubmitted form value, and a consumer that never places this inside a `<form>` loses nothing.\nThe normalized initial `value` is captured as the reset default; `form.reset()` restores that\nmodel, clears interaction/touched state and the save-name draft, and preserves a caller-set\ncustom validity message like a native control.\nThe start-entity input carries native `required`, matching the aggregate builder's\n`valueMissing` rule. Host `focus()`/`click()` reach the first rendered field, and `blur()`\nreleases whichever nested field owns deep focus.\nAn unavailable DOM focus getter skips restoration without preventing chip removal or saved-query\nupdates. Ordinary focused removal still follows the adjacent control and leaves outside focus alone.\n\nRun, save, load, and delete use the same two-phase action contract: a cancelable\n`lr-before-query-*` request precedes any local effect, followed by a non-cancelable\n`lr-query-*` accepted notification. Vetoing a request suppresses its accepted notification;\nfor save it also preserves the draft name, and for load it preserves the current `value`.\n\n**Accessible name:** a host-level `aria-label` wins. Otherwise the region (`role=\"group\"`) is\nlabelled by the same visible label element that renders the `label` slot/property/localized\ndefault, so visible and announced names cannot diverge. The same region carries explicit\n`aria-invalid=\"true\"|\"false\"` from the complete builder's effective intrinsic/custom validity.\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**Slots**\n\n| Name | Description |\n| --- | --- |\n| `actions` | Extra host controls rendered in the footer beside the Run button. |\n| `error` | Error text for the complete form control. |\n| `hint` | Supporting text for the complete form control. |\n| `label` | Visible label for the complete form control. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The outer wrapper around every section. |\n| `direction` | The traversal-direction `<lr-select>`. |\n| `end-input` | The end-entity `<lr-input>`. |\n| `error` | Error text for the complete form control. |\n| `filter-group` | One type-filter section (relationship or node type); rendered twice. |\n| `footer` | The row containing the actions slot and the Run button. |\n| `hint` | Supporting text for the complete form control. |\n| `label` | Visible label for the complete form control. |\n| `max-hops` | The maximum-hops `<lr-select>`. |\n| `min-hops` | The minimum-hops `<lr-select>`. |\n| `node-type-chips` | The `<lr-chip-group>` listing currently active node types. |\n| `node-type-picker` | The \"add a node type\" `<lr-select>`. |\n| `path-fields` | The row wrapping the start/end entity inputs and hop-count selects. |\n| `relationship-chips` | The `<lr-chip-group>` listing currently active relationship types. |\n| `relationship-picker` | The \"add a relationship type\" `<lr-select>`. |\n| `run-button` | The Run button. |\n| `save-button` | The Save button. |\n| `save-name-input` | The new-saved-query name `<lr-input>`. |\n| `save-row` | The row containing the save-name input and Save button. |\n| `saved-delete-button` | A saved query row's delete button. |\n| `saved-empty` | The message shown when `savedQueries` has no entries. |\n| `saved-item` | One saved query's row. |\n| `saved-list` | The list of saved queries. |\n| `saved-load-button` | A saved query row's Load button. |\n| `saved-queries` | The wrapper around the save row and the saved-query list. |\n| `saved-queries-label` | The saved-queries section heading. |\n| `start-input` | The start-entity `<lr-input>`. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-graph-query-builder-run-active-bg` — Run button pressed background; defaults to the current brand active mix.\n- `--lr-graph-query-builder-run-bg` (default: `var(--lr-color-brand)`) — Run button resting background.\n- `--lr-graph-query-builder-run-border-color` (default: `var(--lr-color-brand)`) — Run button resting border color.\n- `--lr-graph-query-builder-run-color` (default: `var(--lr-color-on-brand)`) — Run button resting foreground.\n- `--lr-graph-query-builder-run-hover-bg` — Run button hover background; defaults to the current brand hover mix.\n- `--lr-graph-query-builder-save-active-bg` — Save button pressed background; defaults to the current quiet-brand active mix.\n- `--lr-graph-query-builder-save-bg` (default: `var(--lr-color-surface)`) — Save button resting background.\n- `--lr-graph-query-builder-save-border-color` (default: `var(--lr-color-border)`) — Save button resting border color.\n- `--lr-graph-query-builder-save-color` (default: `var(--lr-color-text)`) — Save button resting foreground.\n- `--lr-graph-query-builder-save-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Save button hover background.\n- `--lr-graph-query-builder-saved-delete-active-bg` (default: `var(--lr-color-danger-quiet)`) — Saved-query delete pressed background.\n- `--lr-graph-query-builder-saved-delete-active-color` — Saved-query delete pressed foreground; defaults to the current danger active mix.\n- `--lr-graph-query-builder-saved-delete-color` (default: `var(--lr-color-text-quiet)`) — Saved-query delete foreground.\n- `--lr-graph-query-builder-saved-delete-hover-color` (default: `var(--lr-color-danger)`) — Saved-query delete hover foreground.\n- `--lr-graph-query-builder-saved-load-active-bg` — Saved-query Load button pressed background; defaults to the current surface active mix.\n- `--lr-graph-query-builder-saved-load-color` (default: `var(--lr-color-text)`) — Saved-query Load button foreground.","attributes":[{"name":"custom-error","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nType: `string | null`"},{"name":"disabled","description":"Type: `boolean`","value":{"type":["boolean"]}},{"name":"error-text","description":"Caller-supplied outer error text. Field-level validation remains on the affected controls.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"form","description":"Type: `HTMLFormElement | string | null`  \nDefault: `null`"},{"name":"hint","description":"Supporting text rendered below the outer label.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"hop-limit","description":"Upper bound (inclusive) offered by the minimum/maximum hop selects. Sanitized to a finite\ninteger in `[1, 20]`, falling back to `6`.\n\nType: `number`  \nDefault: `6`","value":{"type":["number"]}},{"name":"label","description":"Accessible name for the whole component; falls back to the localized `graphQueryBuilderLabel`.\nA host-level `aria-label` attribute wins over both this property and the localized default --\nsee the class doc's \"Accessible name\" note.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"name","description":"Type: `string`","value":{"type":["string"]}}],"slots":[{"name":"actions","description":"Extra host controls rendered in the footer beside the Run button."},{"name":"error","description":"Error text for the complete form control."},{"name":"hint","description":"Supporting text for the complete form control."},{"name":"label","description":"Visible label for the complete form control."}],"js":{"properties":[{"name":"customError","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nAttribute: `custom-error`  \nReflected to its attribute.","type":"string | null"},{"name":"disabled","description":"Attribute: `disabled`  \nReflected to its attribute.","type":"boolean"},{"name":"effectiveDisabled","description":"Effective disabled state: this element's own `disabled` OR an ancestor\n`<fieldset disabled>`'s inherited state.","type":"boolean","read-only":true},{"name":"errorText","description":"Caller-supplied outer error text. Field-level validation remains on the affected controls.\n\nAttribute: `error-text`","type":"string","default":"''"},{"name":"errors","description":"The current effective validation errors. Intrinsic errors are keyed by their field part;\na caller-supplied custom validity message is keyed by the whole-control `base` part.","type":"Readonly<Record<string, string>>","read-only":true},{"name":"form","description":"Attribute: `form`  \nReflected to its attribute.","type":"HTMLFormElement | string | null","default":"null"},{"name":"hint","description":"Supporting text rendered below the outer label.\n\nAttribute: `hint`","type":"string","default":"''"},{"name":"hopLimit","description":"Upper bound (inclusive) offered by the minimum/maximum hop selects. Sanitized to a finite\ninteger in `[1, 20]`, falling back to `6`.\n\nAttribute: `hop-limit`","type":"number","default":"6"},{"name":"label","description":"Accessible name for the whole component; falls back to the localized `graphQueryBuilderLabel`.\nA host-level `aria-label` attribute wins over both this property and the localized default --\nsee the class doc's \"Accessible name\" note.\n\nAttribute: `label`","type":"string","default":"''"},{"name":"labels","type":"NodeList","read-only":true},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"name","description":"Attribute: `name`  \nReflected to its attribute.","type":"string"},{"name":"nodeTypeOptions","type":"readonly GraphQueryTypeOption[]"},{"name":"relationshipTypeOptions","type":"readonly GraphQueryTypeOption[]"},{"name":"savedQueries","type":"readonly GraphQuerySavedItem[]"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"validationMessage","type":"string","read-only":true},{"name":"validity","type":"ValidityState","read-only":true},{"name":"value","description":"The complete controlled query model, detached and deeply frozen with at most 500 relationship\nand node type entries. Reassign a new model after changes. Its normalized value at the first\nupdate is the form reset default; later property writes and user edits change only the live\nvalue.","type":"GraphQuery"},{"name":"willValidate","type":"boolean","read-only":true}],"events":[{"name":"lr-before-query-delete","description":"Cancelable delete request with frozen `detail: { queryId }`. Vetoing it suppresses `lr-query-delete`.","type":"CustomEvent<GraphQueryDeleteDetail>"},{"name":"lr-before-query-load","description":"Cancelable load request with frozen `detail: { queryId, query }`, emitted before `value` changes. Vetoing it preserves the current query.","type":"CustomEvent<LyraEventDetailSnapshot<GraphQueryLoadDetail>>"},{"name":"lr-before-query-run","description":"Cancelable request emitted after `reportValidity()` passes, before accepting Run. Frozen `detail: { query }`; vetoing it suppresses `lr-query-run`.","type":"CustomEvent<LyraEventDetailSnapshot<GraphQueryRunDetail>>"},{"name":"lr-before-query-save","description":"Cancelable save request with frozen `detail: { name, query }`. Vetoing it preserves the draft name and suppresses `lr-query-save`.","type":"CustomEvent<LyraEventDetailSnapshot<GraphQuerySaveDetail>>"},{"name":"lr-input","description":"`detail: { value }` — any field changed; the full current query. Hop select choices emit it once; child native/prefixed value and listbox lifecycle aliases are contained.","type":"CustomEvent<LyraEventDetailSnapshot<{ readonly value: GraphQuery }>>"},{"name":"lr-invalid","description":"Cancelable alias when the complete builder fails native validity; vetoing it also suppresses the native invalid default.","type":"CustomEvent<null>"},{"name":"lr-query-delete","description":"Non-cancelable accepted Delete notification. Frozen `detail: { queryId }`; the host removes the matching entry from `savedQueries`.","type":"CustomEvent<GraphQueryDeleteDetail>"},{"name":"lr-query-load","description":"Non-cancelable accepted Load notification emitted after `value` changes. Frozen `detail: { queryId, query }` contains the accepted query.","type":"CustomEvent<LyraEventDetailSnapshot<GraphQueryLoadDetail>>"},{"name":"lr-query-run","description":"Non-cancelable accepted Run notification. Frozen `detail: { query }`.","type":"CustomEvent<LyraEventDetailSnapshot<GraphQueryRunDetail>>"},{"name":"lr-query-save","description":"Non-cancelable accepted Save notification. Frozen `detail: { name, query }`; the host assigns an id and appends to `savedQueries`.","type":"CustomEvent<LyraEventDetailSnapshot<GraphQuerySaveDetail>>"},{"name":"lr-validity-change","description":"Frozen `detail: { valid, errors }` from effective native validity, including custom errors and validation barring; fired only on an actual change.","type":"CustomEvent<{\n    readonly valid: boolean;\n    readonly errors: Readonly<Record<string, string>>;\n  }>"}]}},{"name":"lr-grounding-summary","description":"`<lr-grounding-summary>` -- the claim-level scorecard for one generated answer: supported/\nunsupported claim counts, citation coverage, an optional confidence score, any warnings, and\n(when `citations` is supplied) a list of evidence citations linking back to their exact spans.\nConsumes `GroundingAssessment` from `src/ai/types.ts` directly as its primary input. Pure\nprojection + event conduit: never fetches or computes an assessment itself.\n\nComposes `<lr-stat>` for every numeric display (claim counts, coverage, confidence) and\n`<lr-citation-badge>` for each evidence entry -- this component defines no numeric-badge or\ncitation-link markup of its own.\n\nThis component contains `<lr-citation-badge>`'s raw `lr-citation-activate` event and emits the richer\n`lr-citation-select` (`detail: { citation }`, `CitationSelectEventDetail` from `src/ai/types.ts`)\ncarrying the full `Citation` -- including its `span` -- since a bare `sourceId`/`index` pair\ncan't by itself tell a host which exact evidence span to jump to.\n\nPublic collection sequences are bounded, frozen snapshots. The assessment and admitted\nclaim/citation source identities remain opaque while descriptor-safe projections copy fields\nused for display, lookup, and composition once; later rendering and events never reread a\nsource record. Create a new collection and reassign it after changes; mutating the assigned\narray does not update the view. Blank claim/citation ids and later duplicates are ignored before\ncounts, lookup, rendering, or activation. The first record for an id wins.\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| `base` | The root wrapper. It owns `role=\"group\"` and the fallback name unless a non-empty host `aria-label` makes the host the sole overall owner. |\n| `claims` | Claim-level evidence, when present and enabled. |\n| `empty` | The empty-state message, shown when `assessment` is `null`. |\n| `evidence` | Wrapper for the evidence section. Omitted when `citations` is empty. |\n| `evidence-count` | The evidence count. |\n| `evidence-heading` | The \"Evidence\" heading text. |\n| `evidence-item` | One citation's row (badge + always-visible label/span text). |\n| `evidence-label` | A citation's `label`, shown next to its badge (omitted when unset). |\n| `evidence-list` | The semantic list containing the evidence citations. |\n| `evidence-span` | A citation's formatted `span` range, shown next to its badge (omitted when `span` is unset). |\n| `stats` | Container for the claim-count/coverage/confidence `<lr-stat>` row. |\n| `warning` | One warning `<li>`. |\n| `warnings` | Wrapper for the warnings section. Omitted when there are no warnings. |\n| `warnings-count` | The warnings count. |\n| `warnings-heading` | The \"Warnings\" heading text. |\n| `warnings-list` | The `<ul>` of warning messages. |","attributes":[{"name":"heading-level","description":"Semantic level of the warnings and evidence section headings. Use `none` to keep the visual\nheading text without exposing it to heading navigation. Invalid untyped values use level 3.\n\nType: `LyraHeadingLevel`  \nDefault: `'3'`","value":{"type":["'1'","'2'","'3'","'4'","'5'","'6'","'none'"]}},{"name":"label","description":"Accessible name used by the stable group when the host has no `aria-label`; falls back to the\nlocalized `groundingSummaryLabel` default. An explicitly empty host label stays empty, and so\ndoes an explicitly empty `label`.\n\nType: `string | undefined`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"show-claims","description":"Renders `assessment.claims` through `<lr-claim-evidence>` when available.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}}],"js":{"properties":[{"name":"assessment","description":"The assessment to summarize. `null` (the default) renders the empty state.","type":"Readonly<GroundingAssessment> | null","default":"null"},{"name":"citations","description":"Evidence citations backing the assessment, each rendered as an `<lr-citation-badge>` linking\nback to its exact `span`. Independent of `assessment` -- the evidence section is simply\nomitted when this is empty, same as the warnings section is omitted when `assessment.warnings`\nis empty/unset.","type":"readonly Citation[]","default":"[]"},{"name":"headingLevel","description":"Semantic level of the warnings and evidence section headings. Use `none` to keep the visual\nheading text without exposing it to heading navigation. Invalid untyped values use level 3.\n\nAttribute: `heading-level`","type":"LyraHeadingLevel","default":"'3'"},{"name":"label","description":"Accessible name used by the stable group when the host has no `aria-label`; falls back to the\nlocalized `groundingSummaryLabel` default. An explicitly empty host label stays empty, and so\ndoes an explicitly empty `label`.\n\nAttribute: `label`","type":"string | undefined"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"showClaims","description":"Renders `assessment.claims` through `<lr-claim-evidence>` when available.\n\nAttribute: `show-claims`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"thresholds","description":"Tone thresholds applied to both `coverage` and `confidence` (both 0-1 fractions): at or above\n`high` renders `success`, at or above `medium` renders `warning`, below `medium` renders\n`danger`.","type":"LyraScoreThresholds","default":"{ high: 0.8, medium: 0.5, }"}],"events":[{"name":"lr-citation-select","description":"An evidence citation badge was activated. `detail: { citation }`.","type":"CustomEvent<LyraEventDetailSnapshot<CitationSelectEventDetail>>"},{"name":"lr-claim-select","description":"A composed claim-evidence row was activated. `detail: { claim }`.","type":"CustomEvent<LyraEventDetailSnapshot<{ claim: GroundedClaim }>>"}]}},{"name":"lr-handoff-divider","description":"`<lr-handoff-divider>` — a labeled semantic separator marking control transfer between agents\nin a transcript (\"Transferred to Research Agent\"), with an optional agent avatar. Purely\npresentational: no events, no interactivity, no restore semantics.\n\nThe computed label is announced once, on first connect, through an internal\n`<lr-live-region>` — a single mount-time announcement is enough since a handoff lands\nmid-stream and there is only ever one thing to say. Later property changes re-render the\nvisible/accessible label but never re-announce.\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| `avatar` | The incoming agent's `<lr-avatar>` (or icon), at the start of the chip. Hidden entirely while empty. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `avatar` | Wrapper around the `avatar` slot. Only shown while the slot has content. |\n| `base` | The separator root (`role=\"separator\"`). |\n| `chip` | The visual (`aria-hidden`) chip wrapping the avatar and label. |\n| `label` | The computed label text. |\n| `line` | Each of the two flanking rules. |","attributes":[{"name":"from-agent","description":"Optional source agent. With both `fromAgent` and `toAgent` set, renders `'Transferred from\n{from} to {to}'` — worded, not an arrow, so RTL needs no mirroring.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"label","description":"Full override, rendered as-is. With nothing set at all, the generic `'Agent handoff'`\nfallback renders.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"to-agent","description":"The destination agent now in control. With nothing else set, renders\n`'Transferred to {agent}'`.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"slots":[{"name":"avatar","description":"The incoming agent's `<lr-avatar>` (or icon), at the start of the chip. Hidden entirely while empty."}],"js":{"properties":[{"name":"fromAgent","description":"Optional source agent. With both `fromAgent` and `toAgent` set, renders `'Transferred from\n{from} to {to}'` — worded, not an arrow, so RTL needs no mirroring.\n\nAttribute: `from-agent`","type":"string","default":"''"},{"name":"label","description":"Full override, rendered as-is. With nothing set at all, the generic `'Agent handoff'`\nfallback renders.\n\nAttribute: `label`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"toAgent","description":"The destination agent now in control. With nothing else set, renders\n`'Transferred to {agent}'`.\n\nAttribute: `to-agent`","type":"string","default":"''"}]}},{"name":"lr-heatmap","description":"`<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). Invalid authored colors keep the\ndefault ramp endpoint and issue a deduplicated diagnostic only in development.\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\"]`. Focus-only updates restore\nintersected neighboring fills and overlays without redrawing the entire canvas.\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`data.weekdayLabelWidth` controls that mode's weekday-axis gutter independently of the matrix\n`rowLabelWidth`: a CSS-pixel number pins it, while `'auto'` measures localized or overridden\nweekday labels. Labels that still exceed the resolved gutter are ellipsized rather than clipped.\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**Slots**\n\n| Name | Description |\n| --- | --- |\n| `legend` | Custom legend content rendered inside the built-in legend row. Nothing is rendered, and the slot itself is absent, while `withoutLegend` is set. |\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. The whole row, its slot included, is absent from the DOM while `withoutLegend` is set. |\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 the legend is rendered, and removed again when either stops being true -- `withoutLegend` takes the whole legend row out of the DOM, and the legend bar is this property's only reader; 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.","attributes":[{"name":"accessible-cells","description":"Renders an opt-in DOM overlay of native buttons over the canvas. Each\nbutton has a localized accessible name, explicit `aria-selected=\"true\"` or\n`\"false\"` from `selectedCell`, and participates in a roving tabindex so a\ndense calendar does not create hundreds of tab stops. The selection is\ncontrolled: clicking a cell still emits `lr-cell-click`, and the\nconsumer updates `selectedCell` when it wants `aria-selected` to change.\nControlled grid refreshes preserve owned focus by matrix coordinate or calendar date, then\nclamp to the nearest surviving interactive cell (or the heatmap base when none remain).\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"bucket-count","description":"Type: `number`","value":{"type":["number"]}},{"name":"cell-gap-x","description":"Matrix-only trailing horizontal separator in CSS pixels, subtracted from the square cell\npitch. Clamped between zero and cellSize minus one; non-finite values use the default.\n\nType: `number`  \nDefault: `1`","value":{"type":["number"]}},{"name":"cell-gap-y","description":"Matrix-only trailing vertical separator in CSS pixels, with the same bounds as cellGapX.\n\nType: `number`  \nDefault: `1`","value":{"type":["number"]}},{"name":"cell-radius","description":"Matrix-only painted corner radius in CSS pixels, clamped to half the smaller painted side.\nDoes not change cellSize, the matrix pitch, data labels, or calendar geometry.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"cell-size","description":"Effective per-cell size (CSS px). Originally matrix-mode only; now also\ngoverns calendar mode's cell size (replacing the previously hardcoded\n11px constant there) once explicitly set. Left unset, each mode keeps\nits own original default — `DEFAULT_MATRIX_CELL_SIZE` (22) in matrix\nmode, `CAL_CELL` (11) in calendar mode — so an existing consumer who\nnever touches `cellSize` sees no change in either mode. Set explicitly\n(attribute or property), the same value governs both modes alike.\n\nType: `number`","value":{"type":["number"]}},{"name":"col-label-height","description":"Height, in CSS px, of the matrix column-label band, or `\"auto\"` to measure the labels and size\nthe band to fit them (never below the built-in 20px, and bounded above by a sanity ceiling so a\npathological label cannot produce an absurd canvas). Under a non-zero\n`colLabelRotation` the measurement projects each label's width through the rotation, which is\nwhat makes a rotated axis usable without hand-tuning a magic number.\n\nUnset keeps the built-in 20px, for the same reason `rowLabelWidth` does: auto-sizing every\nexisting heatmap would silently reflow charts whose labels already fit.\n\nType: `number | 'auto' | undefined`"},{"name":"col-label-interval","description":"Paint every Nth matrix column label, starting at column zero. Truncated to an integer of at\nleast one; non-finite values use one. Tooltips, keyboard labels, and data retain every label.\n\nType: `number`  \nDefault: `1`","value":{"type":["number"]}},{"name":"col-label-rotation","description":"Rotation, in degrees, applied to matrix column labels. Unset (or `0`) paints them horizontally\nexactly as before. In a dense matrix the per-column width is far narrower than a typical label,\nso horizontal labels collide with their neighbours; `45` or `90` is the standard remedy.\n\nEach label is rotated about an anchor at its own column's centre, with the label's *end* at the\nanchor, so it leans up and back over the columns to its left and the last column's label cannot\noverflow the canvas. Values outside `[0, 90]` clamp into it and non-finite values normalize to\n`0`; a rotation is not a coordinate a caller can usefully be surprised by.\n\nPair with `colLabelHeight=\"auto\"` to have the band size itself to the rotated extent.\n\nNot mirrored under `dir=\"rtl\"`: both grid modes deliberately retain physical LTR geometry (see\nthe class doc), and leaning one axis' labels the other way while the grid itself stays physical\nwould be incoherent.\n\nType: `number | undefined`"},{"name":"fit-to-width","description":"When set, `cellSize` is derived from the host's measured `clientWidth`\non every draw (including ResizeObserver-triggered redraws) instead of\nthe fixed `cell-size` attribute, so the grid actually fills the\navailable width. Without this, canvas dimensions are computed purely\nfrom `matrixPadLeft + cols * cellSize` (matrix mode) or\n`calendarPadLeft + weekCount * cellSize` (calendar mode), so a\nresize-triggered redraw is a geometric no-op. Originally matrix-mode\nonly; now applies to calendar mode too.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max-cell-size","description":"Ceiling (CSS px) on the cell size `fitToWidth` derives from the host width, in **both** modes.\nIgnored entirely while `fitToWidth` is unset — an explicit `cellSize` is never clamped, since\nit is already an exact request.\n\nExists because `fitToWidth` divides the whole host width across the grid: a 5-week calendar or\na 3-column matrix in a wide pane produces enormous cells. Capping them keeps the cell a cell.\nThe canvas is sized *from the clamped cell size*, so a capped grid deliberately leaves the\nremaining host width unfilled (the canvas simply ends early) rather than stretching to fill it\n— position it with normal CSS on the host if you want it centered or end-aligned.\n\nUnset (the default) reproduces today's exact fit-to-width behavior. Clamped to at least the\nbuilt-in `4`px floor; a non-finite value (or an empty attribute) means unset rather than `0`.\nWhen both clamps are set and `maxCellSize < minCellSize`, the ceiling wins — the same\nprecedence `finiteRange()` itself applies.\n\nType: `number | undefined`"},{"name":"midpoint","description":"Anchors a diverging ramp's neutral color on this value rather than at the middle of the\ndomain, scaling the two halves independently (`lo`->0, `midpoint`->0.5, `hi`->1). Unset (the\ndefault) leaves the plain min-max normalization untouched. Like `domain`, setting it opts into\nsigned data. A midpoint outside the resolved domain degrades to plain normalization rather\nthan distorting the ramp.\n\nType: `number | undefined`"},{"name":"min-cell-size","description":"Floor (CSS px) under the cell size `fitToWidth` derives from the host width, in **both** modes\n— the mirror of `maxCellSize`, and likewise ignored while `fitToWidth` is unset. Raises the\nbuilt-in `FIT_MIN_CELL` (4px) floor so a year-long calendar in a narrow pane keeps legible,\nhit-testable cells and overflows its host instead of collapsing to hairlines.\n\nCan only raise that floor, never lower it: a value below `4` normalizes to `4`. Unset (the\ndefault) reproduces today's exact fit-to-width behavior, and a non-finite value (or an empty\nattribute) means unset.\n\nType: `number | undefined`"},{"name":"multiple","description":"Enables controlled multiple selection through selectedCells instead of selectedCell.\nClick or Enter/Space toggles a cell. Drag paints/erases; Shift+arrows extends a rectangular\nrange. The default false preserves the existing single-cell event and selection contract.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"row-label-width","description":"Width, in CSS px, of the matrix row-label gutter, or `'auto'` to measure the widest label and\nsize the gutter to fit (never below the built-in 60px, never above 40% of the host's width, so\none long label cannot squeeze out the cells it exists to describe).\n\nUnset keeps the built-in 60px. That default is deliberate: auto-sizing every existing heatmap\nwould silently reflow charts whose labels already fit, which is a bigger change than the\nclipping it fixes. Opt in per chart, or pin an exact figure.\n\nIndependently of this, a row label too wide for the resolved gutter is now truncated with an\nellipsis instead of being clipped mid-glyph by whatever is painted beside it -- clipping read\nas a rendering fault, truncation reads as \"there is more here\". `cellText` still carries the\nfull label to the tooltip and the keyboard announcement either way.\n\nCalendar mode is unaffected; use `data.weekdayLabelWidth` for its weekday gutter.\n\nType: `number | 'auto' | undefined`"},{"name":"scale","description":"`\"linear\"` (default) maps values linearly to the color ramp in matrix\nmode, and buckets calendar-mode values via `quartileBucket()` — both\nunchanged from before this property governed calendar mode too.\n`\"sqrt\"` compresses via `sqrtStep()`'s square-root magnitude compression\ninstead, in *both* modes, so one heavy cell/day doesn't wash out the\nrest of a skewed dataset.\n\nType: `HeatmapScale`  \nDefault: `'linear'`","value":{"type":["'linear'","'sqrt'"]}},{"name":"sticky-labels","description":"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 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`","value":{"type":["'none'","'rows'","'cols'","'both'"]}},{"name":"value-label","description":"Legend caption. Unset uses the localized default; every supplied string is literal.\n\nType: `string | undefined`"},{"name":"without-legend","description":"Hides the legend. Same name and same polarity as `<lr-chart>`'s `withoutLegend`, so the two\nchart-adjacent surfaces a dashboard puts side by side are turned off the same way rather than\nthrough a third spelling.\n\nThe row is removed from the DOM outright -- swatches, endpoint labels, the `valueLabel`\ncaption, the annotation entries and the `legend` slot all go with it -- rather than being\nvisually hidden, so it contributes no layout box and assigns no slotted content. The legend's\nown preparation stops too: the `--lr-heatmap-color-steps-gradient` custom property this\ncomponent writes onto the host for the legend bar (and for nothing else) is not written while\nthe legend is hidden, and is removed again if it had been.\n\nCells, tooltips, keyboard interaction and the generated accessible summary are unaffected: the\nsummary already names the value label independently of the legend.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"legend","description":"Custom legend content rendered inside the built-in legend row. Nothing is rendered, and the slot itself is absent, while `withoutLegend` is set."}],"js":{"properties":[{"name":"accessibleCells","description":"Renders an opt-in DOM overlay of native buttons over the canvas. Each\nbutton has a localized accessible name, explicit `aria-selected=\"true\"` or\n`\"false\"` from `selectedCell`, and participates in a roving tabindex so a\ndense calendar does not create hundreds of tab stops. The selection is\ncontrolled: clicking a cell still emits `lr-cell-click`, and the\nconsumer updates `selectedCell` when it wants `aria-selected` to change.\nControlled grid refreshes preserve owned focus by matrix coordinate or calendar date, then\nclamp to the nearest surviving interactive cell (or the heatmap base when none remain).\n\nAttribute: `accessible-cells`","type":"boolean","default":"false"},{"name":"annotations","description":"Cells to ring-highlight — `row`/`col` in matrix mode, `date` in calendar mode. See `HeatmapAnnotation`.","type":"readonly HeatmapAnnotation[]","default":"[]"},{"name":"bucketCount","description":"Attribute: `bucket-count`","type":"number"},{"name":"cellColor","description":"Overrides a cell's computed ramp/no-data color entirely for an exact value -- receives the\ncell position (`MatrixCellPos` in matrix mode, `CalendarCellPos` — carrying the resolved ISO\n`date` — in calendar mode) and its\nvalue, return a CSS color string to force that cell to it, or `undefined` to fall back to the\nnormal `colorSteps`/ramp math unchanged. Lets a consumer designate a value as categorically\noutside the ramp (e.g. a real zero-count day rendered as a neutral hairline, distinct from\nboth \"no data\" and the ramp's own lightest step) without a prepended synthetic ramp color,\nwhich can't safely reserve an exact value on a skewed dataset (the bucket selectors round by\ncontinuous ratio, with no equality-based reservation). Unset (the default) reproduces today's\nexact ramp/no-data behavior for every cell. A returned value containing a CSS custom property\n(e.g. `var(--x)`) or other browser-resolvable color syntax (e.g. `color-mix(...)`) is\nautomatically resolved before being used as a canvas fill color.","type":"(\n    pos: MatrixCellPos | CalendarCellPos,\n    value: number\n  ) => string | undefined | undefined"},{"name":"cellGapX","description":"Matrix-only trailing horizontal separator in CSS pixels, subtracted from the square cell\npitch. Clamped between zero and cellSize minus one; non-finite values use the default.\n\nAttribute: `cell-gap-x`","type":"number","default":"1"},{"name":"cellGapY","description":"Matrix-only trailing vertical separator in CSS pixels, with the same bounds as cellGapX.\n\nAttribute: `cell-gap-y`","type":"number","default":"1"},{"name":"cellInteractive","description":"Opts individual cells out of the interaction model — receives the cell position and its\nvalue, return `false` to make that cell present-but-non-interactive (no hover tooltip,\nclick, or keyboard roving-focus stop), without losing the layout/color-ramp machinery. Lets\na consumer omit a future/out-of-range date from interaction, or mark a zero-value cell as\nnon-interactive, without ~300+ meaningless keyboard tab stops on a dense grid. In calendar\nmode the position carries its resolved ISO `date`, so \"everything after today\" is a direct\nstring comparison. Unset (the default) keeps every cell interactive, unchanged from before\nthis property existed.","type":"(\n    pos: MatrixCellPos | CalendarCellPos,\n    value: number\n  ) => boolean | undefined"},{"name":"cellRadius","description":"Matrix-only painted corner radius in CSS pixels, clamped to half the smaller painted side.\nDoes not change cellSize, the matrix pitch, data labels, or calendar geometry.\n\nAttribute: `cell-radius`","type":"number","default":"0"},{"name":"cellSize","description":"Effective per-cell size (CSS px). Originally matrix-mode only; now also\ngoverns calendar mode's cell size (replacing the previously hardcoded\n11px constant there) once explicitly set. Left unset, each mode keeps\nits own original default — `DEFAULT_MATRIX_CELL_SIZE` (22) in matrix\nmode, `CAL_CELL` (11) in calendar mode — so an existing consumer who\nnever touches `cellSize` sees no change in either mode. Set explicitly\n(attribute or property), the same value governs both modes alike.\n\nAttribute: `cell-size`","type":"number"},{"name":"cellText","description":"Formats the per-cell tooltip and keyboard announcement text — receives the cell position\n(`MatrixCellPos` in matrix mode, `CalendarCellPos` — which carries the resolved ISO\n`yyyy-mm-dd` `date`, gap positions included — in calendar mode) and its value. Falls back to\nlocalized matrix row/column/value or calendar date/value templates when unset; the default\nEnglish catalog renders \"Row X, Col Y: value\" / \"Mon DD: value\". Use this callback for\napplication-specific wording rather than ordinary translation.","type":"(\n    pos: MatrixCellPos | CalendarCellPos,\n    value: number\n  ) => string | undefined"},{"name":"colLabelHeight","description":"Height, in CSS px, of the matrix column-label band, or `\"auto\"` to measure the labels and size\nthe band to fit them (never below the built-in 20px, and bounded above by a sanity ceiling so a\npathological label cannot produce an absurd canvas). Under a non-zero\n`colLabelRotation` the measurement projects each label's width through the rotation, which is\nwhat makes a rotated axis usable without hand-tuning a magic number.\n\nUnset keeps the built-in 20px, for the same reason `rowLabelWidth` does: auto-sizing every\nexisting heatmap would silently reflow charts whose labels already fit.\n\nAttribute: `col-label-height`","type":"number | 'auto' | undefined"},{"name":"colLabelInterval","description":"Paint every Nth matrix column label, starting at column zero. Truncated to an integer of at\nleast one; non-finite values use one. Tooltips, keyboard labels, and data retain every label.\n\nAttribute: `col-label-interval`","type":"number","default":"1"},{"name":"colLabelRotation","description":"Rotation, in degrees, applied to matrix column labels. Unset (or `0`) paints them horizontally\nexactly as before. In a dense matrix the per-column width is far narrower than a typical label,\nso horizontal labels collide with their neighbours; `45` or `90` is the standard remedy.\n\nEach label is rotated about an anchor at its own column's centre, with the label's *end* at the\nanchor, so it leans up and back over the columns to its left and the last column's label cannot\noverflow the canvas. Values outside `[0, 90]` clamp into it and non-finite values normalize to\n`0`; a rotation is not a coordinate a caller can usefully be surprised by.\n\nPair with `colLabelHeight=\"auto\"` to have the band size itself to the rotated extent.\n\nNot mirrored under `dir=\"rtl\"`: both grid modes deliberately retain physical LTR geometry (see\nthe class doc), and leaning one axis' labels the other way while the grid itself stays physical\nwould be incoherent.\n\nAttribute: `col-label-rotation`","type":"number | undefined"},{"name":"colorSteps","description":"A discrete array (≥2) of CSS colors used as exact ramp steps instead of linearly\ninterpolating between the two `--lr-heatmap-scale-lo`/`-hi` endpoints — lets a consumer\nbring a validated, non-linear (or simply non-2-endpoint) sequential palette. Governs both\n`mode`s and both `scale` values, discretizing whichever scale would otherwise interpolate\ncontinuously into `colorSteps.length` buckets instead. Unset (the default, or fewer than 2\nentries) keeps today's 2-endpoint interpolation exactly. Invalid entries use the canvas\nfallback color and prevent the custom legend gradient from being assigned.","type":"readonly string[] | undefined"},{"name":"data","description":"All mode-specific input. Reassign this property after changing caller-owned collections.","type":"HeatmapData","default":"DEFAULT_MATRIX_DATA"},{"name":"domain","description":"Pins the color ramp's input domain to `[min, max]` instead of deriving it from the data's own\nextremes. Unset (the default) keeps today's behavior exactly: the ramp spans the data's own\nmin-max, so two heatmaps of comparable data each normalize to their own extremes and cannot be\nread against each other. Setting it also opts the component into **signed data** (see\n`signedDomain`), because declaring a domain is what disambiguates a negative value from the\nno-data sentinel. A reversed or degenerate pair falls back to the derived range.","type":"[number, number] | undefined"},{"name":"fitToWidth","description":"When set, `cellSize` is derived from the host's measured `clientWidth`\non every draw (including ResizeObserver-triggered redraws) instead of\nthe fixed `cell-size` attribute, so the grid actually fills the\navailable width. Without this, canvas dimensions are computed purely\nfrom `matrixPadLeft + cols * cellSize` (matrix mode) or\n`calendarPadLeft + weekCount * cellSize` (calendar mode), so a\nresize-triggered redraw is a geometric no-op. Originally matrix-mode\nonly; now applies to calendar mode too.\n\nAttribute: `fit-to-width`","type":"boolean","default":"false"},{"name":"legendStops","description":"A discrete legend key rendered *instead of* the `--lr-heatmap-scale-lo`/`-hi` gradient bar\nand its `[part=\"legend-lo\"]`/`[part=\"legend-hi\"]` endpoint labels — one\n`[part=\"legend-stop\"]` per entry, in array order, each a `[part=\"legend-swatch\"]` in that\nentry's `color` plus a `[part=\"legend-stop-label\"]`. Labels default to this component's own\nlocale-aware numeric formatting of `value`, so a stop only needs an explicit `label` when\nthe number isn't the right caption (\"none\", \"≥ 90%\").\n\nA stop's `color` is optional: omit it (or pass `''`) for a **caption-only** entry, which\nrenders its label with no `[part=\"legend-swatch\"]` element in the DOM at all — the shape a\n\"less ▢▢▢▢ more\" style key needs for its two end captions, without an empty swatch box\nsitting at either end of the row.\n\nExists for the consumer who supplies `cellColor`: because that callback overrides a cell's\ncolor entirely, the built-in two-endpoint bar can describe a ramp the grid no longer uses.\nSupplying the same colors here keeps the legend honest without hiding `[part=\"legend\"]` and\nre-implementing swatches, labels and the annotation entries by hand.\n\nStrictly presentation: the stops are never consulted by the color ramp, the bucket math, the\ntooltip, or the accessible name — supplying them changes nothing a cell renders. Any\n`annotations` with a `label` still render their `[part=\"legend-annotation\"]` entries after\nthe stops. Reassigning stops whose supported fields are unchanged does not schedule a redraw;\nevery assignment is still clone-owned, so mutating and reassigning the caller's array is\ndetected without exposing that mutation in place. Unset (the default) or an empty array\nreproduces today's exact gradient legend.","type":"readonly HeatmapLegendStop[] | undefined"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"matrixGeometry","description":"The gutter/cell geometry the last matrix-mode draw actually painted with --\n`{ padLeft, padTop, cellSize }`, all in CSS pixels. Custom gaps/radius additionally report\n`cellWidth`, `cellHeight`, and `cellRadius`; default cells omit these fields. This lets a light-DOM consumer\n(e.g. a sticky header mirror) line up with the canvas without hardcoding the same numbers `row-label-width`\nor `col-label-height`'s `\"auto\"` resolution would otherwise keep private. `undefined` in\ncalendar mode, and before the first matrix draw.\n\nThis returns the frozen object `drawMatrix()` stored (and `lr-matrix-geometry-change` carried)\non the last draw -- not a fresh computation. That distinction is the whole contract. Computing\nit on read from the same internal getters `drawMatrix()` uses looks equivalent and is not:\nthose getters read CURRENT layout, so any interval where layout has moved but no draw has\nhappened yet makes the getter describe a canvas that does not exist. Full redraws pause while\nthe host is outside the viewport (documented behaviour of this component), so that interval\ncan be long-lived and lands hardest on the tall, partly-scrolled matrix this getter exists to\nserve.\nReturning the stored object also makes the getter and the event the same value by\nconstruction rather than by coincidence.","type":"Readonly<LyraHeatmapMatrixGeometryChangeDetail> | undefined","read-only":true},{"name":"maxCellSize","description":"Ceiling (CSS px) on the cell size `fitToWidth` derives from the host width, in **both** modes.\nIgnored entirely while `fitToWidth` is unset — an explicit `cellSize` is never clamped, since\nit is already an exact request.\n\nExists because `fitToWidth` divides the whole host width across the grid: a 5-week calendar or\na 3-column matrix in a wide pane produces enormous cells. Capping them keeps the cell a cell.\nThe canvas is sized *from the clamped cell size*, so a capped grid deliberately leaves the\nremaining host width unfilled (the canvas simply ends early) rather than stretching to fill it\n— position it with normal CSS on the host if you want it centered or end-aligned.\n\nUnset (the default) reproduces today's exact fit-to-width behavior. Clamped to at least the\nbuilt-in `4`px floor; a non-finite value (or an empty attribute) means unset rather than `0`.\nWhen both clamps are set and `maxCellSize < minCellSize`, the ceiling wins — the same\nprecedence `finiteRange()` itself applies.\n\nAttribute: `max-cell-size`","type":"number | undefined"},{"name":"midpoint","description":"Anchors a diverging ramp's neutral color on this value rather than at the middle of the\ndomain, scaling the two halves independently (`lo`->0, `midpoint`->0.5, `hi`->1). Unset (the\ndefault) leaves the plain min-max normalization untouched. Like `domain`, setting it opts into\nsigned data. A midpoint outside the resolved domain degrades to plain normalization rather\nthan distorting the ramp.\n\nAttribute: `midpoint`","type":"number | undefined"},{"name":"minCellSize","description":"Floor (CSS px) under the cell size `fitToWidth` derives from the host width, in **both** modes\n— the mirror of `maxCellSize`, and likewise ignored while `fitToWidth` is unset. Raises the\nbuilt-in `FIT_MIN_CELL` (4px) floor so a year-long calendar in a narrow pane keeps legible,\nhit-testable cells and overflows its host instead of collapsing to hairlines.\n\nCan only raise that floor, never lower it: a value below `4` normalizes to `4`. Unset (the\ndefault) reproduces today's exact fit-to-width behavior, and a non-finite value (or an empty\nattribute) means unset.\n\nAttribute: `min-cell-size`","type":"number | undefined"},{"name":"multiple","description":"Enables controlled multiple selection through selectedCells instead of selectedCell.\nClick or Enter/Space toggles a cell. Drag paints/erases; Shift+arrows extends a rectangular\nrange. The default false preserves the existing single-cell event and selection contract.\n\nAttribute: `multiple`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"rowLabelWidth","description":"Width, in CSS px, of the matrix row-label gutter, or `'auto'` to measure the widest label and\nsize the gutter to fit (never below the built-in 60px, never above 40% of the host's width, so\none long label cannot squeeze out the cells it exists to describe).\n\nUnset keeps the built-in 60px. That default is deliberate: auto-sizing every existing heatmap\nwould silently reflow charts whose labels already fit, which is a bigger change than the\nclipping it fixes. Opt in per chart, or pin an exact figure.\n\nIndependently of this, a row label too wide for the resolved gutter is now truncated with an\nellipsis instead of being clipped mid-glyph by whatever is painted beside it -- clipping read\nas a rendering fault, truncation reads as \"there is more here\". `cellText` still carries the\nfull label to the tooltip and the keyboard announcement either way.\n\nCalendar mode is unaffected; use `data.weekdayLabelWidth` for its weekday gutter.\n\nAttribute: `row-label-width`  \nReflected to its attribute.","type":"number | 'auto' | undefined"},{"name":"scale","description":"`\"linear\"` (default) maps values linearly to the color ramp in matrix\nmode, and buckets calendar-mode values via `quartileBucket()` — both\nunchanged from before this property governed calendar mode too.\n`\"sqrt\"` compresses via `sqrtStep()`'s square-root magnitude compression\ninstead, in *both* modes, so one heavy cell/day doesn't wash out the\nrest of a skewed dataset.\n\nAttribute: `scale`","type":"HeatmapScale","default":"'linear'"},{"name":"selectedCell","description":"The single cell to mark as persistently selected -- `row`/`col` in matrix mode, `date` in\ncalendar mode. Purely a controlled, consumer-owned visual/accessibility marker, mirroring\n`<lr-lite-chart>`'s `selectedIndices` -- this component never mutates it itself; a consumer\nwires it up from `lr-cell-click` (or any other source) to build a toggle-select\ninteraction. Unset (the default, `null`) draws no selection ring, adds no selected-cell text\nto the host's `aria-label`, and adds no selected suffix to the keyboard announcement,\nreproducing today's exact output.","type":"HeatmapSelectedCell | null","default":"null"},{"name":"selectedCells","description":"Controlled selection in multiple mode. First MAX_HEATMAP_CELLS entries are clone-owned;\nduplicates, invalid/out-of-grid coordinates and non-interactive cells are ignored. Matrix\nentries use integer row/col; calendar entries use ISO dates (interactive gaps included).\nUser actions propose a new array through lr-selection-change, never mutate this property.","type":"readonly HeatmapSelectedCell[]","default":"[]"},{"name":"stickyLabels","description":"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 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\nAttribute: `sticky-labels`  \nReflected to its attribute.","type":"LyraHeatmapStickyLabels"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"valueLabel","description":"Legend caption. Unset uses the localized default; every supplied string is literal.\n\nAttribute: `value-label`","type":"string | undefined"},{"name":"withoutLegend","description":"Hides the legend. Same name and same polarity as `<lr-chart>`'s `withoutLegend`, so the two\nchart-adjacent surfaces a dashboard puts side by side are turned off the same way rather than\nthrough a third spelling.\n\nThe row is removed from the DOM outright -- swatches, endpoint labels, the `valueLabel`\ncaption, the annotation entries and the `legend` slot all go with it -- rather than being\nvisually hidden, so it contributes no layout box and assigns no slotted content. The legend's\nown preparation stops too: the `--lr-heatmap-color-steps-gradient` custom property this\ncomponent writes onto the host for the legend bar (and for nothing else) is not written while\nthe legend is hidden, and is removed again if it had been.\n\nCells, tooltips, keyboard interaction and the generated accessible summary are unaffected: the\nsummary already names the value label independently of the legend.\n\nAttribute: `without-legend`  \nReflected to its attribute.","type":"boolean","default":"false"}],"events":[{"name":"lr-cell-click","description":"Fired on click, or Enter/Space on the focused/hovered cell. `detail: { row, col, value }` in matrix mode, `detail: { date, value }` in calendar mode. `cellText` overrides the localized matrix row/column/value or calendar date/value template used for both the hover tooltip and the keyboard live-region announcement. Use the callback for application-specific wording that is not represented by the locale catalog. `cellColor` overrides a cell's ramp-computed color entirely for an exact value.","type":"CustomEvent<LyraHeatmapCellClickDetail>"},{"name":"lr-matrix-geometry-change","description":"Fired after a matrix-mode draw pass whose resolved `matrixGeometry` (`padLeft`/`padTop`/`cellSize`) differs from the previous draw -- e.g. after `row-label-width=\"auto\"`/`col-label-height=\"auto\"` resolves against new label content or a resize. `detail` is the same object `matrixGeometry` returns. Never fired in calendar mode.","type":"CustomEvent<LyraHeatmapMatrixGeometryChangeDetail>"},{"name":"lr-selection-change","description":"Non-cancelable controlled multiple-selection proposal with frozen `HeatmapSelectionChangeDetail { selectedCells, source }`. Click/Enter/Space toggles, Shift+arrows extends a rectangle, Shift+Space toggles a row and Ctrl/Meta+Space toggles a column. Pointer drag paints or erases with a transient preview and emits once on release; cancellation discards it. Assign the proposed array to `selectedCells` to accept. Programmatic assignments are silent.","type":"CustomEvent<HeatmapSelectionChangeDetail>"}]}},{"name":"lr-highlight-layer","description":"`<lr-highlight-layer>` — a presentational overlay that paints highlight rectangles\n(percent-of-box coordinates) over positioned content and owns their activation, active/flash\nstyling, and keyboard access. `items` order is the caller's own reading order; the layer does not\nre-sort geometrically. Fills its nearest positioned ancestor. With `interactive=false`, the\noverlay remains pure paint (`aria-hidden`, no group owner or controls). If no item has a valid\nrectangle, the component renders no subtree at all.\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 absolutely-positioned overlay (inset 0). |\n| `highlight-action` | One action in the non-overlapping highlight action list. |\n| `highlight-actions` | Non-overlapping actions used when more than one logical highlight would otherwise create ambiguous minimum hit areas. |\n| `rect` | One highlight rectangle (`data-tone`/`data-active`/`data-flash` state attributes). |\n| `rect-target` | Transparent activation geometry around a rectangle, with a minimum pointer/focus area independent of the caller-supplied visual coordinates. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-highlight-layer-accent-background` — Accent highlight background.\n- `--lr-highlight-layer-accent-outline` — Accent highlight outline.\n- `--lr-highlight-layer-danger-background` — Danger highlight background.\n- `--lr-highlight-layer-danger-outline` — Danger highlight outline.\n- `--lr-highlight-layer-flash-background` — Flash-state background.\n- `--lr-highlight-layer-neutral-background` — Neutral highlight background.\n- `--lr-highlight-layer-neutral-outline` — Neutral highlight outline.\n- `--lr-highlight-layer-success-background` — Success highlight background.\n- `--lr-highlight-layer-success-outline` — Success highlight outline.\n- `--lr-highlight-layer-warning-background` — Warning highlight background.\n- `--lr-highlight-layer-warning-outline` — Warning highlight outline.","attributes":[{"name":"active-highlight-id","description":"Domain identity of the currently active highlight.\n\nType: `string | null`  \nDefault: `null`"},{"name":"interactive","description":"`false` = pure paint: `pointer-events: none`, no tab stop, no role. Default-true, matching\nmarkdown's `sanitize` stance.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"js":{"properties":[{"name":"activeHighlightId","description":"Domain identity of the currently active highlight.\n\nAttribute: `active-highlight-id`","type":"string | null","default":"null"},{"name":"interactive","description":"`false` = pure paint: `pointer-events: none`, no tab stop, no role. Default-true, matching\nmarkdown's `sanitize` stance.\n\nAttribute: `interactive`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"items","description":"Highlight records in caller reading order. IDs are trimmed and must be nonempty; the first\nrecord for an ID is retained and blank or later duplicate records are ignored.","type":"readonly HighlightLayerItem[]"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-highlight-activate","description":"A rect was activated (click, or Enter/Space while focused). `detail: { highlightId }`.","type":"CustomEvent<HighlightActivateDetail>"}]}},{"name":"lr-histogram","description":"`<lr-histogram>` — bins `values` into `bins` equal-width buckets and\nrenders them as a bar chart. Chart.js has no built-in histogram\ncontroller; this composes `binValues()` with the plain `bar` type.\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| (default) | An optional `<script type=\"application/json\">` containing a Chart.js configuration. |\n| `center` | Optional overlay content positioned at the chart area's center. Useful for doughnut and pie totals. |\n| `data-table` | An optional consumer-provided accessible table alternative. Use this escape hatch for a complete paginated or virtualized alternative when the generated 1,000-record sample is insufficient. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The chart wrapper. |\n| `canvas` | The Chart.js canvas. |\n| `center` | The chart-area-centered overlay wrapper for the `center` slot. |\n| `data-table` | The optional generated or slotted data table. |\n| `data-table-toggle` | The disclosure button rendered by `dataTableToggle`. |\n| `data-truncation` | Explanation shown when the generated accessible alternative samples a data set larger than its 1,000-record ceiling. |\n| `description` | The accessible chart summary. |\n| `error` | Static visible error shown instead of `canvas` when the optional `chart.js` peer dependency is not installed; its transition is announced through a shared light-DOM alert. |\n| `feature-warning` | Static nonfatal warning when a requested optional feature peer is unavailable while the core chart remains usable. |\n| `legend` | The wrapping DOM legend, rendered unless `withoutLegend` is set. |\n| `legend-item` | A keyboard-operable dataset or category visibility toggle. |\n| `legend-item-hidden` | Added while the legend item's dataset or category is hidden. |\n| `legend-swatch` | The resolved dataset/category color swatch in a legend item. |\n| `notices` | Wrapper for nonfatal feature warnings and generated-data truncation notices. |\n| `plot` | The fixed-height canvas/overlay region. |\n| `reset-zoom-button` | The reset-zoom control when zoom is active. |\n\n---\n\n**CSS Custom Properties**\n\n- `--border-color-1` (default: `var(--lr-color-chart-1)`) — First dataset border color.\n- `--border-color-2` (default: `var(--lr-color-chart-2)`) — Second dataset border color.\n- `--border-color-3` (default: `var(--lr-color-chart-3)`) — Third dataset border color.\n- `--border-color-4` (default: `var(--lr-color-chart-4)`) — Fourth dataset border color.\n- `--border-color-5` (default: `var(--lr-color-chart-5)`) — Fifth dataset border color.\n- `--border-color-6` (default: `var(--lr-color-chart-6)`) — Sixth dataset border color.\n- `--border-radius` (default: `var(--lr-radius)`) — Dataset element corner radius.\n- `--border-width` (default: `var(--lr-border-width-thin)`) — Dataset element border width.\n- `--fill-color-1` (default: `var(--lr-color-chart-1)`) — First dataset fill color.\n- `--fill-color-2` (default: `var(--lr-color-chart-2)`) — Second dataset fill color.\n- `--fill-color-3` (default: `var(--lr-color-chart-3)`) — Third dataset fill color.\n- `--fill-color-4` (default: `var(--lr-color-chart-4)`) — Fourth dataset fill color.\n- `--fill-color-5` (default: `var(--lr-color-chart-5)`) — Fifth dataset fill color.\n- `--fill-color-6` (default: `var(--lr-color-chart-6)`) — Sixth dataset fill color.\n- `--grid-border-width` (default: `var(--lr-border-width-thin)`) — Axis and grid line width.\n- `--grid-color` (default: `var(--lr-chart-grid-color)`) — Grid line color.\n- `--line-border-width` (default: `var(--lr-border-width-medium)`) — Line dataset stroke width.\n- `--lr-chart-canvas-hover-outline-color` (default: `var(--lr-chart-grid-color)`) — Color of the `[part='canvas']` hover-state outline.\n- `--lr-chart-canvas-hover-outline-width` (default: `var(--lr-border-width-thin)`) — Width of the `[part='canvas']` hover-state outline.\n- `--lr-chart-data-table-button-active-bg` — Pressed background of an actionable generated- table value; defaults to the standard active mix of `--lr-color-brand-quiet`.\n- `--lr-chart-data-table-button-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background of an actionable generated-table value.\n- `--lr-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-chart-data-table-toggle-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background of the `dataTableToggle` disclosure button.\n- `--lr-chart-grid-color` (default: `var(--lr-color-border)`) — Grid-line color. Resolved via `getComputedStyle` on every draw (Chart.js paints to canvas and cannot consume `var()`).\n- `--lr-chart-height` (default: `var(--lr-size-280px)`) — The plot region's `block-size` and the host's minimum block size. A visible data table or wrapping DOM legend grows the host in normal flow instead of overlapping following content. `height` supplies a private fallback; this public token always wins when a consumer sets it.\n- `--lr-chart-legend-color` (default: `var(--lr-color-text)`) — Legend label color. Resolved via `getComputedStyle` on every draw.\n- `--lr-chart-legend-item-active-bg` — Pressed background of a legend visibility button; defaults to the standard active mix of `--lr-color-brand-quiet`.\n- `--lr-chart-legend-item-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background of a legend visibility button.\n- `--lr-chart-legend-side-max` (default: `var(--lr-size-15rem)`) — Maximum inline size reserved for a side-positioned DOM legend; the track is also capped at one third of the chart allocation.\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 every series collapses to one system color and the stripe/crosshatch pattern 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.\n- `--lr-chart-reset-zoom-button-active-bg` — Pressed background of the reset-zoom button; defaults to the standard active mix of `--lr-color-brand-quiet`.\n- `--lr-chart-reset-zoom-button-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background of the reset-zoom button.\n- `--lr-chart-tick-color` (default: `var(--lr-color-text-quiet)`) — Axis tick-label color; also used for the `xLabel`/`yLabel`/`y2Label` axis-title text (there is no separate title-color token). Resolved via `getComputedStyle` on every draw.\n- `--lr-chart-tick-font-size` (default: `var(--lr-font-size-xs)`) — Axis tick-label font size, in any CSS length unit. Defaults to `--lr-font-size-xs` (12px at the standard root) because that matches Chart.js's OWN built-in tick font size, which is what every canvas chart rendered before this token existed -- leaving it unset must stay byte-identical to that, not shrink to `<lr-lite-chart>`'s SVG default. Also sizes the radar/polarArea `r`-scale `pointLabels` (the spoke labels), but ONLY once set: those default separately to Chart.js's OWN distinct `RadialLinearScale` `pointLabels` default (10px, not this token's 12px), and only adopt this token's size once the consumer explicitly sets it, at which point ticks and point labels match. Resolved via `getComputedStyle` on every draw, same constraint as every other `--lr-chart-*` token here (Chart.js paints to canvas and cannot consume `var()`).\n- `--lr-chart-tooltip-bg` (default: `var(--lr-color-surface)`) — Tooltip background color. Resolved via `getComputedStyle` on every draw.\n- `--lr-chart-tooltip-text` (default: `var(--lr-color-text)`) — Tooltip text color. Resolved via `getComputedStyle` on every draw.\n- `--point-radius` (default: `var(--lr-space-2xs)`) — Line/scatter point radius.","attributes":[{"name":"area","description":"Chart-wide default fill-under-line setting for line-type series; a series's own `LyraChartSeries.fill` overrides it.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"axes","description":"Complete cartesian axis visibility, independent of grid. `y` also controls the y2 axis.\nRadial charts ignore this setting. Explicit config scale options retain precedence.\n\nType: `LyraChartAxes`  \nDefault: `'both'`","value":{"type":["'x'","'y'","'both'","'none'"]}},{"name":"begin-at-zero","description":"Type: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"bins","description":"Type: `number`  \nDefault: `10`","value":{"type":["number"]}},{"name":"compact","description":"Compact cartesian plot: hide axes and remove automatic layout padding. Set height and\nwithoutLegend for a small histogram/sparkline. Preserves data tables, tooltips and keyboard\nactions; radial charts ignore this setting. Explicit config options retain precedence.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"data-labels","description":"Draws each data point's value on the chart via the optional\n`chartjs-plugin-datalabels` peer. Unset (the default) leaves labels off for\nthis chart; the peer is attached only to instances that opt in, and\n`buildConfig()` keeps its per-chart options disabled until this is set. The\nscreen-reader equivalent is the always-present data table (see\n`show-data-table`); labels are a purely visual, canvas-only addition.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"data-table-toggle","description":"Render a disclosure button above the accessible data table so a sighted reader can reveal the\nnumbers behind the chart on demand. `showDataTable` alone is all-or-nothing -- the table is\neither permanently screen-reader-only or permanently visible -- which left a consumer wrapping\na duplicated table in their own `<details>`.\n\nWith this set, `showDataTable` becomes the disclosure's *initial* state rather than its whole\nbehavior. The table stays in the DOM in both states, so assistive technology never loses it.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"description","description":"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`"},{"name":"grid","description":"Controls which cartesian grid axes are drawn.\n\nType: `LyraChartGrid`  \nDefault: `'both'`","value":{"type":["'x'","'y'","'both'","'none'"]}},{"name":"height","description":"Type: `string`  \nDefault: `'280px'`","value":{"type":["string"]}},{"name":"index-axis","description":"Chart.js index axis. `'y'` is Chart.js's own mechanism for horizontal bars (it also flips\nline/area types onto a horizontal category axis).\n\nType: `LyraChartIndexAxis`  \nDefault: `'x'`","value":{"type":["'x'","'y'"]}},{"name":"label","description":"Accessible chart label. A host `aria-label` still has highest precedence.\n\nType: `string | null`  \nDefault: `null`"},{"name":"legend-display","description":"`auto` retains optional legend formatting; `label` omits values even with a formatter; `value`\nappends a formatted value. `percentage` uses locale percentages of the absolute represented\nlegend values, including hidden items (zero totals yield 0%). `value-percentage` appends both,\nas `label: value (percentage)`. Dataset values are sampled sums; category values come from the\nfirst dataset. The `formatter`/`valueFormatter` callback backing `value` and `value-percentage`\nadditionally receives that same `percentage` in its `surface: 'legend'` context, so a custom\nformatter can build its own combined text without recomputing the share. Tooltip and axis\nformatting are unchanged.\n\nType: `LyraChartLegendDisplay`  \nDefault: `'auto'`","value":{"type":["'auto'","'label'","'value'","'percentage'","'value-percentage'"]}},{"name":"legend-mode","description":"`datum` renders category toggles for pie/doughnut/polar-area charts. Categories use the first\ndataset's colors and values; a toggle affects that category in every ring. Other chart types\nretain dataset legends. `auto` (the default) resolves to `datum` on pie/doughnut/polar-area\ncharts -- where a single-dataset legend would otherwise enumerate one entry for the whole\ndataset instead of one per visible slice -- and to `dataset` everywhere else. `dataset` always\nforces the dataset legend, even on a slice chart. Both non-`auto` modes use the generated\naccessible-data sampling budget.\n\nType: `LyraChartLegendMode`  \nDefault: `'auto'`","value":{"type":["'auto'","'dataset'","'datum'"]}},{"name":"legend-position","description":"Legend placement. `auto` uses a right legend above 480px and a bottom legend below it.\n\nType: `LyraChartLegendPosition`  \nDefault: `'top'`","value":{"type":["'left'","'top'","'right'","'bottom'","'center'","'chartArea'","'start'","'end'","'auto'"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max","description":"Maximum value-axis bound. Non-finite values are ignored.\n\nType: `number | null`  \nDefault: `null`"},{"name":"min","description":"Minimum value-axis bound. Non-finite values are ignored.\n\nType: `number | null`  \nDefault: `null`"},{"name":"plugins","description":"Chart.js plugins attached to this chart instance. Valid plugins retain their opaque identity.\n\nType: `readonly LyraChartPlugin[]`  \nDefault: `[]`"},{"name":"scale-type","description":"Scale type for the **value** axis (the categorical axis is unaffected). `'logarithmic'` plots\na dataset spanning several orders of magnitude honestly, where a linear axis collapses\neverything below the maximum into the baseline. Inherited by `lr-line-chart`,\n`lr-scatter-chart` and `lr-bar-chart`.\n\nA logarithmic axis cannot represent zero or negative values (`log(0)` is `-Infinity`), so\n`beginAtZero` is not forwarded in that mode -- Chart.js would otherwise be handed a bound it\ncannot place. Non-positive data points are dropped by Chart.js's own log scale.\n\nType: `LyraChartScaleType`  \nDefault: `'linear'`","value":{"type":["'linear'","'logarithmic'"]}},{"name":"series-label","description":"Dataset label used for the legend, tooltip, table, and summary.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"show-data-table","description":"Makes the generated data table visible; it remains screen-reader available when false.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"stack-totals","description":"When the chart is `stacked` (bar/line only), draws the per-category stack\ntotal above each stack, via the same optional `chartjs-plugin-datalabels`\npeer as `data-labels`. Null/undefined points are skipped; a category whose\nevery value is null shows no total. The generated accessible data table\nreceives the same formatted total column (one per value axis). Unset (the\ndefault) draws and adds nothing.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"stacked","description":"Stacks the `x`/`y`(/`y2`) scale entries `buildScales()` returns; only meaningful for `bar` and `line` types.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"type","description":"Type: `'bar'`  \nDefault: `'bar'`","value":{"type":["'bar'"]}},{"name":"without-animation","description":"Disables Chart.js animation.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"without-legend","description":"Hides the legend.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"without-tooltip","description":"Hides Chart.js tooltips.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"x-label","description":"Type: `string | null`  \nDefault: `null`"},{"name":"y-label","description":"Type: `string | null`  \nDefault: `null`"},{"name":"y2-label","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"zoom","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"","description":"An optional `<script type=\"application/json\">` containing a Chart.js configuration."},{"name":"center","description":"Optional overlay content positioned at the chart area's center. Useful for doughnut and pie totals."},{"name":"data-table","description":"An optional consumer-provided accessible table alternative. Use this escape hatch for a complete paginated or virtualized alternative when the generated 1,000-record sample is insufficient."}],"js":{"properties":[{"name":"annotations","description":"Declarative reference lines and shaded bands — a threshold, an event year, a regime change, a\nhighlighted period. Each entry marks either a single `value` or a `from`/`to` range on `axis`\n(default `'y'`), with an optional `label` and semantic `tone`.\n\nNeeds the optional `chartjs-plugin-annotation` peer, loaded on first actual demand so a page\nwith no annotated charts never downloads it. The plugin is registered globally, like\n`chartjs-plugin-zoom` and unlike `chartjs-plugin-datalabels`: it draws nothing unless a chart\nsupplies annotation options, so the registration is unobservable to charts that set none, and\nregistration is also what installs the plugin's own element defaults. Without the peer\ninstalled the chart still renders; a console warning plus a localized visible warning and\nlight-DOM announcement explain the no-op — the same fail-closed contract `data-labels` uses.\n\nEntries are included in the generated accessible description, mirroring `lr-heatmap`.","type":"readonly LyraChartAnnotation[]","default":"[]"},{"name":"area","description":"Chart-wide default fill-under-line setting for line-type series; a series's own `LyraChartSeries.fill` overrides it.\n\nAttribute: `area`","type":"boolean","default":"false"},{"name":"axes","description":"Complete cartesian axis visibility, independent of grid. `y` also controls the y2 axis.\nRadial charts ignore this setting. Explicit config scale options retain precedence.\n\nAttribute: `axes`","type":"LyraChartAxes","default":"'both'"},{"name":"beginAtZero","description":"Attribute: `begin-at-zero`","type":"boolean","default":"true"},{"name":"bins","description":"Attribute: `bins`","type":"number","default":"10"},{"name":"chart","description":"The current Chart.js instance. Read it only while the element is connected and loaded.","type":"LyraChartInstance | undefined"},{"name":"chartArea","description":"The current Chart.js chart-area geometry in canvas-local coordinates. Read-only -- derived\nfrom the live Chart.js instance's own layout pass, never assignable. The setter is a\ndocumented no-op (matching `lr-histogram`'s `labels`/`datasets` pattern) so an accidental\n`.chartArea=${x}` Lit template binding degrades silently instead of throwing from inside\nlit-html's property-commit.","type":"LyraChartArea | undefined"},{"name":"compact","description":"Compact cartesian plot: hide axes and remove automatic layout padding. Set height and\nwithoutLegend for a small histogram/sparkline. Preserves data tables, tooltips and keyboard\nactions; radial charts ignore this setting. Explicit config options retain precedence.\n\nAttribute: `compact`","type":"boolean","default":"false"},{"name":"config","type":"LyraChartConfiguration | undefined"},{"name":"dataLabels","description":"Draws each data point's value on the chart via the optional\n`chartjs-plugin-datalabels` peer. Unset (the default) leaves labels off for\nthis chart; the peer is attached only to instances that opt in, and\n`buildConfig()` keeps its per-chart options disabled until this is set. The\nscreen-reader equivalent is the always-present data table (see\n`show-data-table`); labels are a purely visual, canvas-only addition.\n\nAttribute: `data-labels`","type":"boolean","default":"false"},{"name":"dataTableToggle","description":"Render a disclosure button above the accessible data table so a sighted reader can reveal the\nnumbers behind the chart on demand. `showDataTable` alone is all-or-nothing -- the table is\neither permanently screen-reader-only or permanently visible -- which left a consumer wrapping\na duplicated table in their own `<details>`.\n\nWith this set, `showDataTable` becomes the disclosure's *initial* state rather than its whole\nbehavior. The table stays in the DOM in both states, so assistive technology never loses it.\n\nAttribute: `data-table-toggle`","type":"boolean","default":"false"},{"name":"datasets","description":"Simplified chart series. Non-record entries are dropped while valid sibling series remain. Derived from `values`/`bins` on `<lr-histogram>`; assignment is accepted and silently ignored.","type":"readonly LyraChartSeries[]","read-only":true},{"name":"description","description":"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\nAttribute: `description`","type":"string | null","default":"null"},{"name":"formatter","description":"Unified context-object formatter for visual, tooltip, table/export, and spoken values.","type":"LyraChartFormatter | undefined"},{"name":"grid","description":"Controls which cartesian grid axes are drawn.\n\nAttribute: `grid`","type":"LyraChartGrid","default":"'both'"},{"name":"height","description":"Attribute: `height`","type":"string","default":"'280px'"},{"name":"hiddenDatasets","description":"Complete controlled visibility state for DOM legend toggles. `undefined` (the default) honors\neach effective dataset's `hidden` configuration; a defined array wins over those defaults, and\nan empty array deliberately makes every dataset visible. Invalid, duplicate, and out-of-range\nindexes are ignored when state is applied or emitted.","type":"readonly number[] | undefined"},{"name":"hiddenDatums","description":"Controlled hidden source category indexes for pie/doughnut/polar-area charts, shared by all\ndatasets/rings. Clone-owned; invalid, duplicate and out-of-range indexes are ignored when\napplied or emitted. Empty restores all categories. Does not alter dataset visibility or exports.","type":"readonly number[]","default":"[]"},{"name":"indexAxis","description":"Chart.js index axis. `'y'` is Chart.js's own mechanism for horizontal bars (it also flips\nline/area types onto a horizontal category axis).\n\nAttribute: `index-axis`","type":"LyraChartIndexAxis","default":"'x'"},{"name":"label","description":"Accessible chart label. A host `aria-label` still has highest precedence.\n\nAttribute: `label`","type":"string | null","default":"null"},{"name":"labels","description":"Derived from `values`/`bins` on `<lr-histogram>`; assignment is accepted and silently ignored.","type":"readonly string[]","default":"[]","read-only":true},{"name":"legendDisplay","description":"`auto` retains optional legend formatting; `label` omits values even with a formatter; `value`\nappends a formatted value. `percentage` uses locale percentages of the absolute represented\nlegend values, including hidden items (zero totals yield 0%). `value-percentage` appends both,\nas `label: value (percentage)`. Dataset values are sampled sums; category values come from the\nfirst dataset. The `formatter`/`valueFormatter` callback backing `value` and `value-percentage`\nadditionally receives that same `percentage` in its `surface: 'legend'` context, so a custom\nformatter can build its own combined text without recomputing the share. Tooltip and axis\nformatting are unchanged.\n\nAttribute: `legend-display`","type":"LyraChartLegendDisplay","default":"'auto'"},{"name":"legendMode","description":"`datum` renders category toggles for pie/doughnut/polar-area charts. Categories use the first\ndataset's colors and values; a toggle affects that category in every ring. Other chart types\nretain dataset legends. `auto` (the default) resolves to `datum` on pie/doughnut/polar-area\ncharts -- where a single-dataset legend would otherwise enumerate one entry for the whole\ndataset instead of one per visible slice -- and to `dataset` everywhere else. `dataset` always\nforces the dataset legend, even on a slice chart. Both non-`auto` modes use the generated\naccessible-data sampling budget.\n\nAttribute: `legend-mode`","type":"LyraChartLegendMode","default":"'auto'"},{"name":"legendPosition","description":"Legend placement. `auto` uses a right legend above 480px and a bottom legend below it.\n\nAttribute: `legend-position`","type":"LyraChartLegendPosition","default":"'top'"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"max","description":"Maximum value-axis bound. Non-finite values are ignored.\n\nAttribute: `max`","type":"number | null","default":"null"},{"name":"min","description":"Minimum value-axis bound. Non-finite values are ignored.\n\nAttribute: `min`","type":"number | null","default":"null"},{"name":"plugins","description":"Chart.js plugins attached to this chart instance. Valid plugins retain their opaque identity.\n\nAttribute: `plugins`","type":"readonly LyraChartPlugin[]","default":"[]"},{"name":"scaleType","description":"Scale type for the **value** axis (the categorical axis is unaffected). `'logarithmic'` plots\na dataset spanning several orders of magnitude honestly, where a linear axis collapses\neverything below the maximum into the baseline. Inherited by `lr-line-chart`,\n`lr-scatter-chart` and `lr-bar-chart`.\n\nA logarithmic axis cannot represent zero or negative values (`log(0)` is `-Infinity`), so\n`beginAtZero` is not forwarded in that mode -- Chart.js would otherwise be handed a bound it\ncannot place. Non-positive data points are dropped by Chart.js's own log scale.\n\nAttribute: `scale-type`","type":"LyraChartScaleType","default":"'linear'"},{"name":"seriesLabel","description":"Dataset label used for the legend, tooltip, table, and summary.\n\nAttribute: `series-label`","type":"string","default":"''"},{"name":"showDataTable","description":"Makes the generated data table visible; it remains screen-reader available when false.\n\nAttribute: `show-data-table`","type":"boolean","default":"false"},{"name":"stackTotals","description":"When the chart is `stacked` (bar/line only), draws the per-category stack\ntotal above each stack, via the same optional `chartjs-plugin-datalabels`\npeer as `data-labels`. Null/undefined points are skipped; a category whose\nevery value is null shows no total. The generated accessible data table\nreceives the same formatted total column (one per value axis). Unset (the\ndefault) draws and adds nothing.\n\nAttribute: `stack-totals`","type":"boolean","default":"false"},{"name":"stacked","description":"Stacks the `x`/`y`(/`y2`) scale entries `buildScales()` returns; only meaningful for `bar` and `line` types.\n\nAttribute: `stacked`","type":"boolean","default":"false"},{"name":"stackedAxes","description":"Per-value-axis override of `stacked`, keyed by `'y'`/`'y2'`. An axis absent from this record\n-- including every axis when the whole property is unset -- falls back to the chart-wide\n`stacked` value, which is what keeps a chart that never sets this byte-identical to before.\nLets a `stacked` bar series on the primary axis sit next to an unstacked overlay series on\n`y2` (via `LyraChartSeries.axis: 'y2'`): set `stackedAxes` to `{ y2: false }` alongside\n`stacked`, or spell out both axes explicitly. The shared categorical axis (`x` for a vertical\nbar/line, or `y` when `indexAxis` is `'y'`) has no independent entry of its own -- it always\nmirrors the resolved `'y'` value, matching Chart.js's own paired index/value-scale stacking\ncontract. Only meaningful for `bar`/`line` types, matching `stacked` itself.","type":"Partial<Record<'y' | 'y2', boolean>> | undefined"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"tooltipFooterFormatter","description":"Tooltip footer formatter -- e.g. a category's stack total under the items. Receives every\nitem the hovered tooltip covers, in the same shape as `tooltipTitleFormatter`. Unset (the\ndefault) leaves Chart.js's own default (no footer).","type":"LyraChartTooltipGroupFormatter | undefined"},{"name":"tooltipTitleFormatter","description":"Tooltip title formatter -- e.g. a scatter point's own name. Receives every item the hovered\ntooltip covers, each in `formatter`'s `'tooltip'`-surface context shape. Unset (the default)\nleaves Chart.js's own default title (the shared category label) in place.","type":"LyraChartTooltipGroupFormatter | undefined"},{"name":"type","description":"Attribute: `type`","type":"'bar'","default":"'bar'"},{"name":"valueFormatter","description":"Formats numeric (value-axis) ticks, tooltip values, legend values, and generated accessible\ntable cells from one callback.\nHorizontal scalar tooltips use parsed x, including a raw config indexAxis override;\nstructured points retain their y-value contract. The context-object formatter shares this rule.\nNever runs against the categorical x-axis's own labels (line/bar's `labels` strings) —\nChart.js's category scale passes the tick index to `ticks.callback`, not the label text,\nso formatting it would corrupt the axis.","type":"LyraChartValueFormatter | undefined"},{"name":"values","type":"readonly number[]","default":"[]"},{"name":"withoutAnimation","description":"Disables Chart.js animation.\n\nAttribute: `without-animation`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"withoutLegend","description":"Hides the legend.\n\nAttribute: `without-legend`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"withoutTooltip","description":"Hides Chart.js tooltips.\n\nAttribute: `without-tooltip`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"xLabel","description":"Attribute: `x-label`","type":"string | null","default":"null"},{"name":"y2Label","description":"Attribute: `y2-label`","type":"string","default":"''"},{"name":"yLabel","description":"Attribute: `y-label`","type":"string | null","default":"null"},{"name":"zoom","description":"Attribute: `zoom`","type":"boolean","default":"false"}],"events":[{"name":"lr-before-datum-visibility-change","description":"Cancelable category visibility proposal in datum legend mode. `detail: { index: number, visible: boolean, hiddenDatums: readonly number[] }`. Source category indexes apply to every dataset/ring. The complete detail is frozen.","type":"CustomEvent<LyraChartDatumVisibilityChangeDetail>"},{"name":"lr-before-legend-visibility-change","description":"Cancelable proposal emitted before a DOM legend toggle changes state. `detail` contains the target `datasetIndex`, its proposed `visible` value, and the complete canonical proposed `hiddenDatasets` snapshot.","type":"CustomEvent<LyraChartLegendVisibilityChangeDetail>"},{"name":"lr-datum-activate","description":"Family-normalized activation event. Its detail adds `kind` (`bar`, `point`, `segment`, or `slice`) to the `lr-point-click` detail.","type":"CustomEvent<\n    LyraChartDatumActivateDetail<LyraCoreChartDatumKind>\n  >"},{"name":"lr-datum-visibility-change","description":"Emitted after an accepted category toggle commits the same frozen detail. Programmatic `hiddenDatums` assignments are silent.","type":"CustomEvent<LyraChartDatumVisibilityChangeDetail>"},{"name":"lr-legend-visibility-change","description":"Emitted after an accepted DOM legend toggle commits the same detail. Programmatic `hiddenDatasets` changes reconcile without either event.","type":"CustomEvent<LyraChartLegendVisibilityChangeDetail>"},{"name":"lr-point-click","description":"Fired when pointer input lands on a data point/segment, when a generated data-table value is activated, or when Enter/Space activates the keyboard-current canvas datum. `detail: { datasetIndex: number, index: number, label: string | undefined, value: unknown }`. For scatter/bubble data, `label` prefers the per-point label and `value` is the complete typed `LyraChartPoint` (`x`, `y`, optional `r`, optional `label`).","type":"CustomEvent<{\n    datasetIndex: number;\n    index: number;\n    label: string | undefined;\n    value: unknown;\n  }>"},{"name":"lr-zoom","description":"`detail: { zoomed }`.","type":"CustomEvent<{ zoomed: boolean }>"}]}},{"name":"lr-html-viewer","description":"Fetches and safely renders an inline HTML document. The sanitized surface establishes paint\ncontainment so retained author styles cannot position content over the surrounding application.\nA nonempty host `aria-label` makes the host the sole named semantic owner; otherwise the loaded\nshadow document owns the explicit-empty, `name`, or localized fallback label.\nIts passive-document profile is network-silent and non-interactive: links, form controls, and\ncustom elements are unwrapped to their ordinary text/children where safe; remote navigation and\nresource attributes are removed. Images load only inline base64 GIF, JPEG, PNG, or WebP data,\nwhile same-document SVG fragment references may remain; an `<a>` itself never remains in the\nrendered preview.\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| `anchor-live-region` | The aria-hidden, non-live shadow mirror of the latest anchor-jump message. |\n| `base` | The root container with explicit `aria-busy` loading state. |\n| `body` | The wrapper around the fetched-state content. |\n| `error` | The error region. |\n| `html` | The sanitized HTML document, once loaded. |\n| `spinner` | The visible tokenized loading treatment and ordinary text label. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-html-viewer-max-height` (default: `none`) — Maximum block size of `[part=\"body\"]` before it scrolls internally. The `maxHeight` property sets this token inline on `[part=\"base\"]`.","attributes":[{"name":"active-highlight-id","description":"Id of the currently active highlight, or null when none is active.\n\nType: `string | null`  \nDefault: `null`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max-height","description":"A CSS `max-height`; invalid values are ignored.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"name","description":"Accessible name for the rendered HTML document.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"src","description":"URL to fetch and render as sanitized inline HTML.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"js":{"properties":[{"name":"activeHighlightId","description":"Id of the currently active highlight, or null when none is active.\n\nAttribute: `active-highlight-id`","type":"string | null","default":"null"},{"name":"anchor","description":"Anchor or highlight id to resolve and scroll into view.","type":"LyraAnchor | string | null","default":"null"},{"name":"anchorKinds","description":"Anchor kinds supported by this viewer instance.","type":"readonly LyraAnchorKind[]","default":"[]","read-only":true},{"name":"highlights","description":"Highlights rendered by the document target. Reassign after mutation.","type":"LyraHighlight[]","default":"[]"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"maxHeight","description":"A CSS `max-height`; invalid values are ignored.\n\nAttribute: `max-height`","type":"string","default":"''"},{"name":"name","description":"Accessible name for the rendered HTML document.\n\nAttribute: `name`","type":"string","default":"''"},{"name":"src","description":"URL to fetch and render as sanitized inline HTML.\n\nAttribute: `src`","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-anchor-result","description":"Fired after an `anchor` assignment or `scrollToAnchor()` call is applied. `detail: { found: boolean }`. Bubbling, composed, and non-cancelable.","type":"CustomEvent<AnchorResultDetail>"},{"name":"lr-render-error","description":"Fired when fetching or sanitizing the document fails.","type":"CustomEvent<{ error: unknown }>"},{"name":"lr-search-change","description":"Fired whenever search state changes. `matchCountExact=false` makes the retained count a lower bound. Bubbling, composed, and non-cancelable.","type":"CustomEvent<LyraSearchChangeDetail>"},{"name":"lr-text-select","description":"Fired after a selection ends inside the rendered document. `detail: { text: string; anchor: LyraAnchor | null; rects: DOMRect[] }`. Bubbling, composed, and non-cancelable.","type":"CustomEvent<TextSelectDetail>"}]}},{"name":"lr-icon","description":"`<lr-icon>` — an SVG icon primitive. Renders a built-in named path with no network access at\nall, or resolves a name through a registered icon library, or fetches one SVG document from\n`src`. Remote markup is byte-capped, sanitized with DOMPurify, and rendered only if the whole\npipeline succeeds; anything else fails closed with a localized alert and no partial markup.\nMatching loads share a bounded cache of canonical sanitized SVGs. Each instance deep-clones the\ncanonical node before its trusted library mutator runs, so cached state is never mutated.\nThe mirrored upstreams' icon-name vocabularies are not bundled. The default library contains\nonly `add`, `check`, `close`, `search`, `menu`, `chevron-left`, `chevron-right`, `chevron-down`,\n`calendar`, `command`, and `trash`; any other name renders no glyph unless a matching library is\nregistered, including through `registerIconLibrary('default', { resolver })`.\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 `autoWidth` / `auto-width`: Deprecated since `8.0.0`. Use property `canvas=\"auto\"`. Removal is not permitted before `10.0.0`. autoWidth is a boolean compatibility spelling that cannot express fixed canvas sizes; canvas covers both automatic and explicit sizing. That version is a policy floor, not a plan: `wa-icon` still publishes its own deprecated `auto-width` attribute, so this alias is removed only when upstream's is.\n\n---\n\n**Slots**\n\n| Name | Description |\n| --- | --- |\n| (default) | Optional custom SVG/path content when no `name`, `path`, `library`, or `src` resolves. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `empty` | Marker rendered when a remote icon resolved to an empty but valid document. |\n| `error` | The visually hidden, `aria-hidden` mirror shown when a remote icon fails. The spoken error is appended to Lyra's shared assertive light-DOM announcement sink while the icon and its composed ancestors are exposed to the accessibility tree. |\n| `svg` | The rendered SVG, whether built-in or fetched. |\n| `use` | Every `<use>` element in the rendered SVG. |\n\n---\n\n**CSS Custom Properties**\n\n- `--animation-delay` (default: `0s`) — Delay before an icon animation starts.\n- `--animation-direction` (default: `normal`) — Playback direction for icon animations.\n- `--animation-duration` (default: `var(--lr-duration-icon)`) — Duration of one animation cycle.\n- `--animation-iteration-count` (default: `infinite`) — Number of animation cycles.\n- `--animation-timing` (default: `var(--lr-easing-emphasized)`) — Animation timing function.\n- `--beat-fade-opacity` (default: `0.4`) — Lowest opacity during `beat-fade`.\n- `--beat-fade-scale` (default: `1.25`) — Peak scale during `beat-fade`.\n- `--beat-scale` (default: `1.25`) — Scale multiplier for `beat` and `spin-pulse`.\n- `--bounce-anticipation` (default: `0`) — Downward offset before a bounce.\n- `--bounce-height` (default: `calc(var(--lr-size-0-5em)*-1)`) — Peak bounce height.\n- `--bounce-jump-scale-x` (default: `0.95`) — Horizontal scale at the top of a bounce.\n- `--bounce-jump-scale-y` (default: `1.05`) — Vertical scale at the top of a bounce.\n- `--bounce-land-scale-x` (default: `1.08`) — Horizontal scale while landing.\n- `--bounce-land-scale-y` (default: `0.92`) — Vertical scale while landing.\n- `--bounce-rebound` (default: `calc(var(--lr-size-1em)*-0.1)`) — Landing rebound distance.\n- `--bounce-start-scale-x` (default: `1`) — Initial horizontal bounce scale.\n- `--bounce-start-scale-y` (default: `1`) — Initial vertical bounce scale.\n- `--buzz-distance` (default: `calc(var(--lr-size-1em)*0.12)`) — Horizontal buzz travel.\n- `--fade-opacity` (default: `0.4`) — Lowest opacity during `fade` and `spin-pulse`.\n- `--flip-angle` (default: `180deg`) — Rotation angle for flip treatments.\n- `--flip-anticipation-scale` (default: `0.9`) — Wind-up scale before a flip.\n- `--flip-overshoot` (default: `0deg`) — Extra angle before a flip settles.\n- `--flip-x` (default: `0`) — X coordinate of the flip rotation axis.\n- `--flip-y` (default: `1`) — Y coordinate of the flip rotation axis.\n- `--flip-z` (default: `0`) — Z coordinate of the flip rotation axis.\n- `--float-drift` (default: `0`) — Horizontal float drift.\n- `--float-height` (default: `calc(var(--lr-size-0-5em)*-1)`) — Float rise height.\n- `--float-squash-x` (default: `1.04`) — Resting horizontal float scale.\n- `--float-squash-y` (default: `0.96`) — Resting vertical float scale.\n- `--float-stretch-x` (default: `0.96`) — Peak horizontal float scale.\n- `--float-stretch-y` (default: `1.04`) — Peak vertical float scale.\n- `--float-tilt` (default: `4deg`) — Rotation at the float peak.\n- `--jello-scale-x` (default: `1.18`) — Horizontal jello stretch.\n- `--jello-scale-y` (default: `0.82`) — Vertical jello stretch.\n- `--lr-icon-fixed-width` (default: `var(--lr-size-1-5em)`) — Inline size of the box while `fixed-width` is set; the glyph keeps `--lr-icon-size` and centers inside it.\n- `--lr-icon-flip-x` (default: `1`) — Horizontal scale factor, set to `-1` by `flip`.\n- `--lr-icon-flip-y` (default: `1`) — Vertical scale factor, set to `-1` by `flip`.\n- `--lr-icon-rotate` (default: `0deg`) — Rotation applied to the box. Written inline from the `rotate` property, so set that rather than this property.\n- `--lr-icon-size` — Optional inline and block size override for every canvas.\n- `--primary-color` (default: `currentColor`) — Primary duotone layer color.\n- `--primary-opacity` (default: `1`) — Primary duotone layer opacity.\n- `--secondary-color` (default: `currentColor`) — Secondary duotone layer color.\n- `--secondary-opacity` (default: `0.4`) — Secondary duotone layer opacity.\n- `--swing-angle` (default: `15deg`) — Peak swing angle.\n- `--wag-angle` (default: `12deg`) — Peak wag angle.","attributes":[{"name":"animation","description":"Optional built-in motion treatment; all variants honor `prefers-reduced-motion`.\n\nType: `LyraIconAnimation | undefined`","value":{"type":["'beat'","'fade'","'beat-fade'","'bounce'","'flip'","'flip-360'","'shake'","'spin'","'spin-pulse'","'spin-reverse'","'spin-snap'","'spin-snap-4'","'spin-snap-8'","'buzz'","'wag'","'float'","'swing'","'jello'"]}},{"name":"auto-width","description":"Compatibility alias for `canvas=\"auto\"`. Purely a CSS-level alias — it never reads or\nwrites `canvas` — so an explicit `canvas` attribute/property always wins and this becomes a\nno-op while one is set.\n\nDeprecated since `8.0.0`. Use property `canvas=\"auto\"`. Removal is not permitted before `10.0.0`. autoWidth is a boolean compatibility spelling that cannot express fixed canvas sizes; canvas covers both automatic and explicit sizing. That version is a policy floor, not a plan: `wa-icon` still publishes its own deprecated `auto-width` attribute, so this alias is removed only when upstream's is.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"canvas","description":"Layout canvas. Unset/`fixed` is 1.25em × 1em; `auto` follows intrinsic width at 1em high;\n`square` is 1.25em × 1.25em; `roomy` is 1.5em × 1.5em.\n\nType: `LyraIconCanvas | undefined`","value":{"type":["'fixed'","'auto'","'square'","'roomy'"]}},{"name":"family","description":"Family forwarded to a registered library resolver. Its vocabulary belongs to the library.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"fixed-width","description":"Widens the icon box to `--lr-icon-fixed-width` so a column of icons aligns its labels.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"flip","description":"Mirrors the icon about the vertical (`x`/`horizontal`), horizontal (`y`/`vertical`), or both axes.\n\nType: `LyraIconFlip | undefined`","value":{"type":["'x'","'y'","'both'","'horizontal'","'vertical'"]}},{"name":"label","description":"Accessible name. Empty (the default) leaves the icon `aria-hidden`.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"library","description":"Name of a registered icon library. `default` means the built-in glyph set; an\nunregistered name also falls back to it, so registration can happen after first render.\n\nType: `string`  \nDefault: `'default'`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"name","description":"A built-in glyph name, or the name handed to the resolver of a registered `library`.\nAssigning `undefined`, as permitted by both pinned upstreams, clears the name.\n\nType: `string | undefined`  \nDefault: `''`"},{"name":"path","description":"Raw SVG path data, taking precedence over a built-in `name`.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"rotate","description":"Rotation in degrees, clockwise in both text directions. The zero default does not reflect and\nproduces no `transform`, so an ordinary icon never becomes a containing block.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"src","description":"URL of a single SVG document to fetch, used when no registered library resolves `name`.\nAssigning the upstream `undefined` spelling aborts/clears the pending source on update.\n\nType: `string | undefined`  \nDefault: `''`"},{"name":"swap-opacity","description":"Swaps the primary and secondary opacity hooks used by duotone SVGs.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"variant","description":"Variant forwarded to a registered library resolver. Its vocabulary belongs to the library.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"slots":[{"name":"","description":"Optional custom SVG/path content when no `name`, `path`, `library`, or `src` resolves."}],"js":{"properties":[{"name":"animation","description":"Optional built-in motion treatment; all variants honor `prefers-reduced-motion`.\n\nAttribute: `animation`  \nReflected to its attribute.","type":"LyraIconAnimation | undefined"},{"name":"autoWidth","description":"Compatibility alias for `canvas=\"auto\"`. Purely a CSS-level alias — it never reads or\nwrites `canvas` — so an explicit `canvas` attribute/property always wins and this becomes a\nno-op while one is set.\n\nDeprecated since `8.0.0`. Use property `canvas=\"auto\"`. Removal is not permitted before `10.0.0`. autoWidth is a boolean compatibility spelling that cannot express fixed canvas sizes; canvas covers both automatic and explicit sizing. That version is a policy floor, not a plan: `wa-icon` still publishes its own deprecated `auto-width` attribute, so this alias is removed only when upstream's is.\n\nAttribute: `auto-width`  \nReflected to its attribute.","type":"boolean","default":"false","deprecated":"Use `canvas=\"auto\"` instead."},{"name":"canvas","description":"Layout canvas. Unset/`fixed` is 1.25em × 1em; `auto` follows intrinsic width at 1em high;\n`square` is 1.25em × 1.25em; `roomy` is 1.5em × 1.5em.\n\nAttribute: `canvas`  \nReflected to its attribute.","type":"LyraIconCanvas | undefined"},{"name":"family","description":"Family forwarded to a registered library resolver. Its vocabulary belongs to the library.\n\nAttribute: `family`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"fixedWidth","description":"Widens the icon box to `--lr-icon-fixed-width` so a column of icons aligns its labels.\n\nAttribute: `fixed-width`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"flip","description":"Mirrors the icon about the vertical (`x`/`horizontal`), horizontal (`y`/`vertical`), or both axes.\n\nAttribute: `flip`  \nReflected to its attribute.","type":"LyraIconFlip | undefined"},{"name":"label","description":"Accessible name. Empty (the default) leaves the icon `aria-hidden`.\n\nAttribute: `label`","type":"string","default":"''"},{"name":"library","description":"Name of a registered icon library. `default` means the built-in glyph set; an\nunregistered name also falls back to it, so registration can happen after first render.\n\nAttribute: `library`  \nReflected to its attribute.","type":"string","default":"'default'"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"name","description":"A built-in glyph name, or the name handed to the resolver of a registered `library`.\nAssigning `undefined`, as permitted by both pinned upstreams, clears the name.\n\nAttribute: `name`  \nReflected to its attribute.","type":"string | undefined","default":"''"},{"name":"path","description":"Raw SVG path data, taking precedence over a built-in `name`.\n\nAttribute: `path`","type":"string","default":"''"},{"name":"rotate","description":"Rotation in degrees, clockwise in both text directions. The zero default does not reflect and\nproduces no `transform`, so an ordinary icon never becomes a containing block.\n\nAttribute: `rotate`  \nReflected to its attribute.","type":"number","default":"0"},{"name":"src","description":"URL of a single SVG document to fetch, used when no registered library resolves `name`.\nAssigning the upstream `undefined` spelling aborts/clears the pending source on update.\n\nAttribute: `src`","type":"string | undefined","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"swapOpacity","description":"Swaps the primary and secondary opacity hooks used by duotone SVGs.\n\nAttribute: `swap-opacity`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"variant","description":"Variant forwarded to a registered library resolver. Its vocabulary belongs to the library.\n\nAttribute: `variant`  \nReflected to its attribute.","type":"string","default":"''"}],"events":[{"name":"lr-error","description":"A remote icon could not be resolved, fetched, or sanitized. `detail: { src, error }`.","type":"CustomEvent<{ src: string; error: unknown }>"},{"name":"lr-load","description":"A remote icon finished loading and is in the DOM. `detail: { src }`.","type":"CustomEvent<{ src: string }>"}]}},{"name":"lr-icon-button","description":"`<lr-icon-button>` — an accessible icon-only action button.\n\nSet `icon` for one of `<lr-icon>`'s named glyphs, or slot your own content instead. Slotted\ncontent is a **sibling** of the built-in glyph rather than being piped through `<lr-icon>`, so\nany complete element — an `<svg>`, an `<img>`, an `<lr-flag>` — renders at its own natural\naspect ratio instead of being forced into a 1:1 box. Bare SVG geometry (`<path>`, `<circle>`,\nand a handful of other raw primitives) with no enclosing `<svg>` of its own is detected and\ncloned into a real, internal SVG-namespaced element so it still paints — the same fallback\n`<lr-icon>`'s own custom-content slot uses, but narrowly scoped so a custom element (e.g. a\nslotted `<lr-flag>`) is never run through it.\n\nHost `aria-haspopup` and `aria-expanded` values are forwarded reactively to the shadow-internal\nnative button. `aria-pressed` (`true`, `false`, `mixed`) supports icon-only toggle actions (mute,\nfavorite, pin); `aria-current` (`page`, `step`, `location`, `date`, `time`, `true`, `false`)\nsupports current-item icon buttons. Both follow attribute changes, removal and button/link\nreplacement without changing the native role; empty or unsupported tokens are omitted. Host\n`aria-describedby` and `aria-labelledby` IDREFs are resolved through\n`ariaDescribedByElements`/`ariaLabelledByElements`.\nRelationship targets follow same-ID replacement, removal, reinsertion, reconnection and document\nadoption, including transitions between the native button and anchor.\n\n`getToolbarActions()` contributes this control as one logical action to an enclosing composite\ntoolbar (`<lr-message-actions>`), so a roving-tabindex owner leases the internal control's own\n`tabindex` rather than the host's -- setting `tabindex` on a custom-element host neither adds nor\nremoves its shadow-internal button's tab stop.\nWhen host `aria-controls` names elements in the host's own root, the controls relationship is\nresolved onto that focused control through the reflected element-reference API so it remains\nvalid across this component's shadow boundary. Assigning that relationship intentionally clears\nthe serialized `aria-controls` value; read `ariaControlsElements` in a supporting browser.\nBrowsers without that API retain the forwarded string attribute as a best-effort fallback.\n\nThis icon-only primitive is intentionally an action/link, not a form submitter. Use\n`<lr-button circle type=\"submit|reset\">` with an icon-only default slot when a form action is\nrequired; that component owns the complete native submitter contract. Because this tag is not\nform-associated, ancestor `<fieldset disabled>` state does not reach it and it is absent from\n`form.elements`; disable each icon button explicitly.\n\nThe mirrored upstream's icon-name vocabulary is not bundled. The nested `<lr-icon>` default\nlibrary contains only `add`, `check`, `close`, `search`, `menu`, `chevron-left`,\n`chevron-right`, `chevron-down`, `calendar`, `command`, and `trash`; any other `icon`/`name`\nrenders no glyph unless a matching library is registered, including through\n`registerIconLibrary('default', { resolver })`.\n\nA safe `href` switches the interactive root to a native anchor. `rel` is independently\nsettable (no default); `opener` is always stripped and any `target` force-adds the\nnon-removable `noopener noreferrer` guard. `download` narrows URL validation to downloadable\nschemes. A disabled link keeps the anchor anatomy but removes `href`, so it cannot navigate.\n\nComponent-scoped theme inputs remain undeclared on the host, so values inherited from an\nancestor theme wrapper override the built-in fallback. A value set directly on the icon button\nstill wins through normal custom-property inheritance. `--lr-icon-button-size` is the one\nexception among this component's own cssprops: see its own `@cssprop` entry below.\n\n**No `size` attribute, deliberately.** This control is the one component in the library that\ndoes NOT key off the shared six-step size ladder, and the reason is that its dimension is an\naccessibility floor rather than a density dial. `--lr-icon-button-size` states the minimum\ntappable target the whole library sizes its icon controls against, and `check:hit-area` blocks a\nrelease that drops below it. The ladder's own small tiers sit at or under WCAG 2.5.8's 24px\nminimum — `2xs` resolves to 20px and `xs` to 24px — so wiring the target to the ladder would let\n`size=\"2xs\"` ship an untappable control, and would do it silently because the ladder is the\nmechanism every neighbouring control uses correctly. A smaller icon button therefore stays an\nexplicit, single-purpose decision: override `--lr-icon-button-size`, which reads as the\naccessibility trade-off it is. Scaling the glyph inside that floor is a separate concern and\nalready has its own inherited input, `--lr-icon-size`.\n\nLowering the size for a dense action row below the ordinary 2.5rem/40px floor is safe ONLY\nthrough an ancestor lever -- `--lr-theme-icon-button-size` (application-wide) or\n`--lr-icon-button-size-scope` (one subtree). The coarse-pointer/no-hover media rule in\n`internal/tokens.styles.ts`'s `baseTokens` reads both, and floors the RENDERED hit area back at\n2.75rem/44px however far the override lowered it, so the control stays comfortably tappable the\nmoment the pointer reaching it is a finger rather than a mouse.\n\nSetting `--lr-icon-button-size` DIRECTLY on this element does NOT get that floor, and the\nreference said for several releases that it did. A declaration on the host comes from the outer\ntree and outranks the shadow tree's own `:host` rule, so the media rule never wins and the\nrendered hit area is exactly the value set: `--lr-icon-button-size: 1rem` really does render a\n16px target under a coarse pointer. Below 24px that fails WCAG 2.2 SC 2.5.8, so the\nelement-scoped lever is the explicit accessibility trade-off it reads as -- prefer a subtree\noverride when the intent is merely a denser row. See `internal/tokens.test.ts`.\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) | Optional custom icon content, rendered beside (not inside) the `icon` glyph. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | Shoelace compatibility name for the interactive native control; use `button`. |\n| `button` | Native button, or the native anchor in safe link mode. The same node also carries `base`. |\n| `fallback` | The internal SVG-namespaced clone target for slotted bare geometry. Carries the same `fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.75\" stroke-linecap=\"round\" stroke-linejoin=\"round\"` defaults `<lr-icon>`'s own wrapper svg does, so bare stroke-style geometry (no fill/stroke of its own) renders outlined instead of as a solid shape; an explicit `fill`/`stroke`/etc. already present on the slotted node still wins for that node. Only present in the DOM while at least one top-level slotted element needs it; a complete `<svg>`, `<img>`, or custom element never mounts it. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-icon-button-background` (default: `transparent`) — Background fill of the native button.\n- `--lr-icon-button-background-active` (default: `color-mix(in oklab, var(--lr-color-surface), var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Background fill while pressed: the same mix at the stronger `--lr-color-mix-active` share, so the pressed state is visibly more than the hover.\n- `--lr-icon-button-background-hover` (default: `color-mix(in oklab, var(--lr-color-surface), var(--lr-color-mix-partner) var(--lr-color-mix-hover))`) — Background fill on hover. Before 8.0.0 this fell back to `var(--lr-color-surface)` — the page background — so on a default page a hovered icon button painted itself the colour it was already sitting on and showed no hover at all.\n- `--lr-icon-button-border` (default: `0`) — Complete border shorthand of the native button.\n- `--lr-icon-button-border-active` (default: `var(--lr-icon-button-border-hover, var(--lr-icon-button-border, 0))`) — Complete border shorthand while pressed; falls through to the hover border when only that is set.\n- `--lr-icon-button-border-hover` (default: `var(--lr-icon-button-border, 0)`) — Complete border shorthand on hover.\n- `--lr-icon-button-color` (default: `inherit`) — Icon/text color of the native button.\n- `--lr-icon-button-color-active` (default: `var(--lr-icon-button-color-hover, var(--lr-icon-button-color, inherit))`) — Icon/text color while pressed; falls through to the hover colour when only that is set.\n- `--lr-icon-button-color-hover` (default: `var(--lr-icon-button-color, inherit)`) — Icon/text color on hover.\n- `--lr-icon-button-radius` (default: `var(--lr-radius)`) — Corner radius of the native button.\n- `--lr-icon-button-size` (default: `2.5rem`) — Minimum tappable inline and block size of the native button — a **floor**, not a fixed size: content larger than it grows the button and keeps its own aspect ratio, while a small glyph pads out to it. A library-wide token (declared on every `lr-*` host by `tokens.styles.ts`, and the shared minimum tappable size several other components size their icon controls against), so overriding it globally resizes all of them together. **Element-scoped, unlike the `--lr-icon-button-*` cssprops below:** every `lr-*` host re-declares `--lr-icon-button-size` from `--lr-theme-icon-button-size` in the shared token layer, so an ancestor rule that sets `--lr-icon-button-size` directly is reset the moment it crosses into any intervening `lr-*` component's shadow root and never reaches this element. Set it directly on this element, set `--lr-icon-button-size-scope` on any ancestor to resize one subtree, or set `--lr-theme-icon-button-size` to resize every icon button in the application at once. Only the two ancestor levers keep the coarse-pointer hit-area floor; see `llms/shared.md`.","attributes":[{"name":"aria-controls","description":"Type: `string | null`  \nDefault: `null`"},{"name":"aria-current","description":"Current-item state forwarded reactively to the internal control: page, step, location, date, time, true or false.\n\nType: `string | null`  \nDefault: `null`"},{"name":"aria-describedby","description":"Type: `string | null`  \nDefault: `null`"},{"name":"aria-expanded","description":"Type: `string | null`  \nDefault: `null`"},{"name":"aria-haspopup","description":"Type: `string | null`  \nDefault: `null`"},{"name":"aria-label","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"aria-labelledby","description":"Host IDREFs resolved onto the internal control through `ariaLabelledByElements`, so a composing component can name this button from elements in its own shadow root. An IDREF string alone cannot cross that boundary; the reflected element reference can. Per ARIA it wins over `aria-label`/`label` and the localized fallback name.\n\nType: `string | null`"},{"name":"aria-pressed","description":"Toggle state forwarded reactively to the internal control: true, false or mixed.\n\nType: `string | null`  \nDefault: `null`"},{"name":"disabled","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"download","description":"Native anchor download filename; also selects the stricter download URL allowlist.\n\nType: `string | undefined`"},{"name":"href","description":"Safe link URL. When valid, the native root is an anchor rather than a button.\n\nType: `string | undefined`"},{"name":"icon","description":"Canonical Lyra glyph name. Shoelace's `name` alias delegates to the same state.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"label","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"library","description":"Icon-library name forwarded to the nested `<lr-icon>`.\n\nType: `string | undefined`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"name","description":"Shoelace alias for `icon`. Reads and writes remain synchronized in both directions; an\nupstream `undefined` write clears both to the canonical empty-string read value.\n\nType: `string | undefined`  \nDefault: `''`"},{"name":"rel","description":"Author relationship tokens for the rendered anchor, e.g. `nofollow me license` -- mirrors\n`wa-icon-button`/`sl-icon-button`'s own `rel`, so values a migrating consumer already relies\non survive a `wa-`/`sl-` -> `lr-` rename instead of being silently dropped. Two rules are\nenforced regardless of what an author writes: `opener` is always stripped (the one token that\nre-opens the reverse-tabnabbing vector), and `noopener noreferrer` is force-added whenever\n`target` is set. With no `target` there is no new browsing context to protect, so a same-tab\nlink renders exactly the author's tokens. Deliberately left with no default, matching\n`<lr-button>`'s own `rel`.\n\nType: `string | undefined`"},{"name":"src","description":"Remote SVG URL forwarded to the nested `<lr-icon>` and handled by its guarded loader.\n\nType: `string | undefined`"},{"name":"target","description":"Native anchor target. A non-empty target always derives a safe `rel`.\n\nType: `string | undefined`"}],"slots":[{"name":"","description":"Optional custom icon content, rendered beside (not inside) the `icon` glyph."}],"js":{"properties":[{"name":"accessibleLabel","description":"Attribute: `aria-label`","type":"string","default":"''"},{"name":"control","description":"The internal native `<button>` (or `<a>` in link mode) that owns the role -- the element a\ncomposing component must project a host IDREF relationship onto, since an idref cannot cross\nthis shadow boundary and assigning the relationship to THIS host would leave the real control\nunnamed. `null` before the first render. Mirrors `<lr-virtual-list>`'s `scrollContainer`, which\nexists for exactly the same reason.","type":"HTMLButtonElement | HTMLAnchorElement | null","read-only":true},{"name":"disabled","description":"Attribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"download","description":"Native anchor download filename; also selects the stricter download URL allowlist.\n\nAttribute: `download`","type":"string | undefined"},{"name":"effectiveDisabled","description":"Whether the action is disabled.","type":"boolean","read-only":true},{"name":"href","description":"Safe link URL. When valid, the native root is an anchor rather than a button.\n\nAttribute: `href`","type":"string | undefined"},{"name":"icon","description":"Canonical Lyra glyph name. Shoelace's `name` alias delegates to the same state.\n\nAttribute: `icon`","type":"string","default":"''"},{"name":"label","description":"Attribute: `label`","type":"string","default":"''"},{"name":"library","description":"Icon-library name forwarded to the nested `<lr-icon>`.\n\nAttribute: `library`","type":"string | undefined"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"name","description":"Shoelace alias for `icon`. Reads and writes remain synchronized in both directions; an\nupstream `undefined` write clears both to the canonical empty-string read value.\n\nAttribute: `name`","type":"string | undefined","default":"''"},{"name":"rel","description":"Author relationship tokens for the rendered anchor, e.g. `nofollow me license` -- mirrors\n`wa-icon-button`/`sl-icon-button`'s own `rel`, so values a migrating consumer already relies\non survive a `wa-`/`sl-` -> `lr-` rename instead of being silently dropped. Two rules are\nenforced regardless of what an author writes: `opener` is always stripped (the one token that\nre-opens the reverse-tabnabbing vector), and `noopener noreferrer` is force-added whenever\n`target` is set. With no `target` there is no new browsing context to protect, so a same-tab\nlink renders exactly the author's tokens. Deliberately left with no default, matching\n`<lr-button>`'s own `rel`.\n\nAttribute: `rel`","type":"string | undefined"},{"name":"src","description":"Remote SVG URL forwarded to the nested `<lr-icon>` and handled by its guarded loader.\n\nAttribute: `src`","type":"string | undefined"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"target","description":"Native anchor target. A non-empty target always derives a safe `rel`.\n\nAttribute: `target`","type":"string | undefined"}],"events":[{"name":"blur","description":"Native blur relayed once from the internal button.","type":"FocusEvent"},{"name":"focus","description":"Native focus relayed once from the internal button.","type":"FocusEvent"}]}},{"name":"lr-image-comparer","description":"`<lr-image-comparer>` — compares two slotted surfaces with a keyboard-\naccessible range divider.\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| `after` | The after-state image or content. |\n| `before` | The before-state image or content. |\n| `handle` | Custom decorative content inside the draggable handle. The flattened slot subtree is inert and hidden from assistive technology; the native range remains the only interaction target. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `after` | The after-state layer. |\n| `base` | Compatibility name for the comparison viewport; use `comparison`. |\n| `before` | The clipped before-state layer. |\n| `comparison` | The comparison viewport. It is the same node as `base`. |\n| `divider` | The visible divider line. |\n| `handle` | Wrapper around the native range interaction surface and visible handle. |\n| `input` | The transparent native range input. |\n\n---\n\n**CSS Custom Properties**\n\n- `--divider-width` (default: `var(--lr-size-1px)`) — Retained Shoelace-compat source for `--lr-image-comparer-divider-width`.\n- `--handle-size` (default: `var(--lr-icon-button-size)`) — Retained Shoelace-compat source for `--lr-image-comparer-handle-size`.\n- `--lr-image-comparer-divider-width` (default: `var(--divider-width, var(--lr-size-1px))`) — Width of the dividing line. The canonical, namespaced override; prefer it over the bare compat name, which inherits and so retunes every element in the subtree reading that generic name.\n- `--lr-image-comparer-handle-size` (default: `var(--handle-size, var(--lr-icon-button-size))`) — Inline and block size of the visible compare handle. Canonical, namespaced override.","attributes":[{"name":"after-label","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"aria-label","description":"Type: `string | null`  \nDefault: `null`"},{"name":"before-label","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"orientation","description":"Type: `LyraImageComparerOrientation`","value":{"type":["'horizontal'","'vertical'"]}},{"name":"position","description":"Type: `number`  \nDefault: `50`","value":{"type":["number"]}}],"slots":[{"name":"after","description":"The after-state image or content."},{"name":"before","description":"The before-state image or content."},{"name":"handle","description":"Custom decorative content inside the draggable handle. The flattened slot subtree is inert and hidden from assistive technology; the native range remains the only interaction target."}],"js":{"properties":[{"name":"accessibleLabel","description":"Attribute: `aria-label`","type":"string | null","default":"null"},{"name":"afterLabel","description":"Attribute: `after-label`","type":"string","default":"''"},{"name":"beforeLabel","description":"Attribute: `before-label`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"orientation","description":"Attribute: `orientation`  \nReflected to its attribute.","type":"LyraImageComparerOrientation"},{"name":"position","description":"Attribute: `position`  \nReflected to its attribute.","type":"number","default":"50"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"blur","description":"Relayed once from the native range handle as a bubbling, composed native event.","type":"FocusEvent"},{"name":"change","description":"Bubbling, composed native change event emitted when the range gesture commits a new position.","type":"Event"},{"name":"focus","description":"Relayed once from the native range handle as a bubbling, composed native event.","type":"FocusEvent"},{"name":"input","description":"Bubbling, composed native input event emitted after the divider's live position has been committed.","type":"Event"}]}},{"name":"lr-image-viewer","description":"`<lr-image-viewer>` — full pan/zoom raster-image viewer with labeled region highlights and\nopt-in region annotation, the landing surface for `region`-anchored citations. Distinct from\n`<lr-svg-viewer>` (rendered SVG documents) and `<lr-image-comparer>` (before/after slotted\nsurfaces) — this component owns raster grounding/citation display, not comparison or vector\nrendering.\n\nAdopts `DocumentAnchorTarget` with `anchorKinds: ['region']` only — no text selection is bound\n(a raster image has no selectable text), so `lr-text-select` is never emitted by this viewer.\n\nRegion rectangles are canonical finite, positive percentages wholly inside the 0–100 image\nspace; empty/blank IDs are omitted and duplicates use first-wins uniqueness. At most\n`IMAGE_VIEWER_HIGHLIGHT_LIMIT` buttons are\nprojected at once with one roving tab stop. An active tail item remains reachable by replacing\nthe final item in the leading window. Anchor success means the canonical rendered target was\nscrolled into and visibly intersects the embedded viewport.\n\nFit, rotation, and annotation controls become operable only after the current image loads. At\n90°/270° the `rotation-frame` owns an axis-swapped layout footprint so transformed media stays\nreachable in every fit mode rather than painting outside the pan/zoom scroll geometry.\n\n**RTL behavior:** the raster and annotation geometry use physical image coordinates. In\nannotation mode, ArrowLeft/ArrowRight decrease/increase a draft's x coordinate and their Shift\nvariants decrease/increase its width in both text directions; the surrounding toolbar remains\nlogical.\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| `anchor-live-region` | The aria-hidden, non-live shadow mirror of the latest anchor-jump message. |\n| `annotate-toggle` | The annotation-mode toggle button. |\n| `annotation-box` | The in-progress draft rectangle. |\n| `base` | The root wrapper. |\n| `error` | Ordinary visible failure text. Fresh post-mount image/source failures append the localized message to the shared light-DOM assertive announcement sink; an already-unsafe initial `src` renders visibly without interrupting on mount. |\n| `fit-control` | The fit-mode select. |\n| `frame` | The embedded `lr-pan-zoom`. |\n| `frame-content` | The embedded pan-zoom's transformed content wrapper. |\n| `frame-controls` | The embedded pan-zoom's zoom controls. |\n| `frame-viewport` | The embedded pan-zoom's scrollable viewport. |\n| `highlight` | One highlight box (`data-tone`, `data-active`). |\n| `highlight-label` | A highlight's visible label. |\n| `highlight-layer` | The overlay hosting highlight boxes. |\n| `image` | The `<img>` element. |\n| `image-wrapper` | The rotated wrapper around the image and its overlays. |\n| `rotate-button` | The rotate-90-clockwise button. |\n| `rotation-frame` | Layout footprint that axis-swaps at 90/270 degrees. |\n| `toolbar` | The fit/rotate/annotate controls row. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-image-viewer-annotate-active-bg` (default: `var(--lr-color-brand-quiet)`) — Background of `[part=\"annotate-toggle\"]` while annotation mode is on. The toggle carries its own glyph in `--lr-color-text`, so keep a 4.5:1 ratio against it.\n- `--lr-image-viewer-annotate-active-border` (default: `var(--lr-color-brand)`) — Border color of `[part=\"annotate-toggle\"]` while annotation mode is on.\n- `--lr-image-viewer-highlight-active-color` (default: `var(--lr-color-brand)`) — Outline color of the `[part=\"highlight\"]` matching `activeHighlightId`, independent of the per-tone border colors.\n- `--lr-image-viewer-highlight-active-border-width` (default: `var(--lr-border-width-thick)`) — Border width of the `[part=\"highlight\"]` matching `activeHighlightId`.\n- `--lr-image-viewer-highlight-active-outline-width` (default: `var(--lr-focus-ring-width)`) — Outline width of the `[part=\"highlight\"]` matching `activeHighlightId`.\n- `--lr-image-viewer-highlight-active-outline-offset` (default: `var(--lr-focus-ring-offset)`) — Outline offset of the `[part=\"highlight\"]` matching `activeHighlightId`.\n- `--lr-image-viewer-annotation-box-border` (default: `var(--lr-color-brand)`) — Border color of `[part=\"annotation-box\"]`, the in-progress draft rectangle drawn while annotating, independent of the saved `[part=\"highlight\"]` boxes' own tone colors.\n- `--lr-image-viewer-annotation-box-bg` (default: `color-mix(in srgb, var(--lr-color-brand) 15%, transparent)`) — Fill of `[part=\"annotation-box\"]`.\n- `--lr-image-viewer-highlight-border` (default: `var(--lr-color-brand)`) — Default highlight border.\n- `--lr-image-viewer-highlight-bg` (default: `color-mix(in srgb, var(--lr-color-brand) 20%, transparent)`) — Default highlight fill.\n- `--lr-image-viewer-highlight-success-border` — Success-tone highlight border.\n- `--lr-image-viewer-highlight-success-bg` — Success-tone highlight fill.\n- `--lr-image-viewer-highlight-warning-border` — Warning-tone highlight border.\n- `--lr-image-viewer-highlight-warning-bg` — Warning-tone highlight fill.\n- `--lr-image-viewer-highlight-danger-border` — Danger-tone highlight border.\n- `--lr-image-viewer-highlight-danger-bg` — Danger-tone highlight fill.\n- `--lr-image-viewer-highlight-neutral-border` — Neutral-tone highlight border.\n- `--lr-image-viewer-highlight-neutral-bg` — Neutral-tone highlight fill.\n- `--lr-image-viewer-highlight-fill` — The resting fill a `[part=\"highlight\"]` actually renders, resolved per tone from the `--lr-image-viewer-highlight-*-bg` knobs above. Its hover and pressed states are colour mixes taken from this value, so setting it directly retints all three at once for one highlight; retint a whole tone through the `-bg` knob instead.","attributes":[{"name":"active-highlight-id","description":"Id of the currently active highlight, or null when none is active.\n\nType: `string | null`  \nDefault: `null`"},{"name":"alt","description":"Image alt text. Unset falls back to `name`; explicitly `\"\"` marks the image decorative.\n\nType: `string | undefined`"},{"name":"annotatable","description":"Enables region drawing via pointer or keyboard. The focused image wrapper owns drawing\ncommands and shows the shared focus ring inside its clipped viewport; descendant highlights retain activation.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"fit","description":"Type: `LyraImageFit`","value":{"type":["'contain'","'width'","'actual'"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max-zoom","description":"Passed through to the embedded `<lr-pan-zoom>` as `.maxZoom`. Mirrors\n`<lr-lightbox>`'s own `maxZoom`.\n\nType: `number`  \nDefault: `4`","value":{"type":["number"]}},{"name":"min-zoom","description":"Passed through to the embedded `<lr-pan-zoom>` as `.minZoom`. Same default as\n`<lr-pan-zoom>` itself. Mirrors `<lr-lightbox>`'s own `minZoom` (name, default,\npass-through shape) -- both wrap the exact same `<lr-pan-zoom>` surface.\n\nType: `number`  \nDefault: `0.5`","value":{"type":["number"]}},{"name":"name","description":"Accessible name of `[part=\"base\"]`; a host `aria-label` wins, then the localized\n`imageViewerLabel` fallback.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"rotation","description":"Type: `LyraImageRotation`","value":{"type":["0","90","180","270"]}},{"name":"src","description":"Image URL; validated with `safeMediaSrc` before it ever reaches the `<img>`.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"zoom","description":"Multiplier over the fit-derived base scale, delegated to the embedded pan-zoom surface.\n\nType: `number`  \nDefault: `1`","value":{"type":["number"]}},{"name":"zoom-step","description":"Passed through to the embedded `<lr-pan-zoom>` as `.zoomStep`. Mirrors\n`<lr-lightbox>`'s own `zoomStep`.\n\nType: `number`  \nDefault: `0.25`","value":{"type":["number"]}}],"js":{"properties":[{"name":"activeHighlightId","description":"Id of the currently active highlight, or null when none is active.\n\nAttribute: `active-highlight-id`","type":"string | null","default":"null"},{"name":"alt","description":"Image alt text. Unset falls back to `name`; explicitly `\"\"` marks the image decorative.\n\nAttribute: `alt`","type":"string | undefined"},{"name":"anchor","description":"Anchor or highlight id to resolve and scroll into view.","type":"LyraAnchor | string | null","default":"null"},{"name":"anchorKinds","description":"From `DocumentAnchorTarget` — only `region` anchors resolve here.","type":"readonly LyraAnchorKind[]","default":"['region']","read-only":true},{"name":"annotatable","description":"Enables region drawing via pointer or keyboard. The focused image wrapper owns drawing\ncommands and shows the shared focus ring inside its clipped viewport; descendant highlights retain activation.\n\nAttribute: `annotatable`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"fit","description":"Attribute: `fit`  \nReflected to its attribute.","type":"LyraImageFit"},{"name":"highlights","description":"Highlights rendered by the document target. Reassign after mutation.","type":"LyraHighlight[]","default":"[]"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"maxZoom","description":"Passed through to the embedded `<lr-pan-zoom>` as `.maxZoom`. Mirrors\n`<lr-lightbox>`'s own `maxZoom`.\n\nAttribute: `max-zoom`","type":"number","default":"4"},{"name":"minZoom","description":"Passed through to the embedded `<lr-pan-zoom>` as `.minZoom`. Same default as\n`<lr-pan-zoom>` itself. Mirrors `<lr-lightbox>`'s own `minZoom` (name, default,\npass-through shape) -- both wrap the exact same `<lr-pan-zoom>` surface.\n\nAttribute: `min-zoom`","type":"number","default":"0.5"},{"name":"name","description":"Accessible name of `[part=\"base\"]`; a host `aria-label` wins, then the localized\n`imageViewerLabel` fallback.\n\nAttribute: `name`","type":"string","default":"''"},{"name":"resetZoom","description":"Restores the embedded pan/zoom scale and translation.","type":"() => void"},{"name":"rotation","description":"Attribute: `rotation`  \nReflected to its attribute.","type":"LyraImageRotation"},{"name":"src","description":"Image URL; validated with `safeMediaSrc` before it ever reaches the `<img>`.\n\nAttribute: `src`","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"zoom","description":"Multiplier over the fit-derived base scale, delegated to the embedded pan-zoom surface.\n\nAttribute: `zoom`  \nReflected to its attribute.","type":"number","default":"1"},{"name":"zoomIn","description":"Increases the embedded pan/zoom scale by one configured step.","type":"() => void"},{"name":"zoomOut","description":"Decreases the embedded pan/zoom scale by one configured step.","type":"() => void"},{"name":"zoomStep","description":"Passed through to the embedded `<lr-pan-zoom>` as `.zoomStep`. Mirrors\n`<lr-lightbox>`'s own `zoomStep`.\n\nAttribute: `zoom-step`","type":"number","default":"0.25"}],"events":[{"name":"lr-anchor-result","description":"Fired after `anchor` (or a `scrollToAnchor()` call) is applied. `detail: { found }`.","type":"CustomEvent<AnchorResultDetail>"},{"name":"lr-annotation-create","description":"A drawn/keyed region was committed. `detail: { anchor }` (kind `'region'`). Never stored by the component — the host appends a `LyraHighlight`.","type":"CustomEvent<LyraEventDetailSnapshot<{ anchor: LyraAnchor }>>"},{"name":"lr-fit-change","description":"`detail: { fit }`.","type":"CustomEvent<{ fit: LyraImageFit }>"},{"name":"lr-highlight-activate","description":"A highlight box was clicked/keyboard-activated. `detail: { highlightId }`.","type":"CustomEvent<HighlightActivateDetail>"},{"name":"lr-load","description":"Image finished loading. `detail: { naturalWidth, naturalHeight }`.","type":"CustomEvent<{ naturalWidth: number; naturalHeight: number }>"},{"name":"lr-render-error","description":"The image failed to load. `detail: { error }`.","type":"CustomEvent<{ error: unknown }>"},{"name":"lr-rotation-change","description":"`detail: { rotation }`.","type":"CustomEvent<{ rotation: LyraImageRotation }>"},{"name":"lr-zoom-change","description":"`detail: { zoom }`, bubbles from the embedded pan-zoom surface.","type":"CustomEvent<{ zoom: number }>"}]}},{"name":"lr-include","description":"`<lr-include>` loads an HTML fragment from `src` and transcludes it into\nthe page as sanitized light-DOM content, so the fragment participates in\nthe surrounding page's CSS cascade exactly like a native server-side\ninclude — unlike `<lr-html-viewer>`, which renders a foreign document\ninside an isolated preview card.\n\nLoaded markup always passes through the shared DOMPurify-backed\nsanitizer (`loadHtmlSanitizer()`, the same loader `<lr-html-viewer>`\nuses) before it ever touches `innerHTML` — there is no `allow-scripts`\nescape hatch here, unlike the Web Awesome/Shoelace components this element\notherwise mirrors: their raw, unsanitized injection (with an opt-in to\nactually re-execute embedded `<script>` tags) is incompatible with this\nlibrary's sanitize-always contract, so that option is simply omitted\nrather than shipped as a documented no-op.\nThe post-sanitization transclusion profile is network-silent and non-interactive: anchors are\nretained, but only resolvable same-document `#fragment` links survive and those ids are rebased\nper include instance. Other navigation and resource attributes such as `href`, `src`, `srcset`,\n`action`, `ping`, and `poster` are removed, so images never load. Form controls and custom\nelements cannot remain interactive; their wrappers are unwrapped when their ordinary children\nare safe, while elements such as inputs that have no passive content are removed.\nA `src` beginning with `#` clones the matching same-page element's children\nwithout fetching. A remote URL may carry the same kind of fragment; the\nfragmentless response is byte-capped and sanitized before the target is\nselected. The passive profile covers nested template contents before cache retention as well\nas live insertion; template text and supported fragment selection remain available.\nCloned ids are rebased per instance so repeated includes do not\nintroduce duplicate document ids.\n\n`mode` deliberately defaults to `'same-origin'` rather than the `'cors'`\ndefault those upstream components document — a same-origin-only fetch\nfails closed unless a consumer explicitly opts in to cross-origin fetching\nwith `mode=\"cors\"` (and the remote server cooperates via CORS headers).\n`'no-cors'` is accepted for enum completeness but is rarely useful: it\nalways yields an opaque response (`status` `0`, unreadable body), a Fetch\nAPI platform limitation rather than a bug here.\n\nA failure is announced twice under two names that always carry the same\ndetail object and always fire together: `lr-include-error` (Web Awesome\nspells it `wa-include-error`) and `lr-error` (Shoelace spells it\n`sl-error`, and it is the name every other Lyra component uses for a load\nfailure). The two upstreams disagree, so both spellings are supported and\nneither is deprecated — listen to whichever one your migration produced.\n\nThis is a deliberately bare transclusion primitive with no label/hint/\nerror chrome — its interaction idiom (silently swapping light-DOM content)\nis incompatible with a generic label/hint/error frame. Listen for\n`lr-include-error` to build your own error UI, and author meaningful\nfallback content inside `<lr-include>` for when the source never\nsucceeds; that fallback (and any previously successful include) is left\nuntouched on failure. No live region wraps the slot either: the\nfragment can contain its own landmarks and nested content, and forcing the\nwhole host into a live region would re-announce all of it on every load.\n\nNo implicit ARIA role and no computed accessible name are applied around\nthe transcluded content — the fragment's own semantics (headings,\nlandmarks, its own `role`/`aria-*` attributes) surface directly and\nunmodified, exactly as they would in a native include. The host carries an\nexplicit `aria-busy` state: `\"true\"` while a source is being loaded and\nsanitized, and\n`\"false\"` otherwise.\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) | Fallback content shown until (or unless) a fetch succeeds; overwritten with the sanitized fragment once one does. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `anchor-live-region` | The aria-hidden, non-live shadow mirror of the latest anchor-jump message. |\n| `base` | The non-layout (`display: contents`) wrapper around the default slot. |","attributes":[{"name":"active-highlight-id","description":"Id of the currently active highlight, or null when none is active.\n\nType: `string | null`  \nDefault: `null`"},{"name":"cache","description":"Shares bounded, sanitized remote resources with matching Include requests. Set to false to\nopt out of both retained values and in-flight deduplication.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"mode","description":"Type: `LyraIncludeMode`  \nDefault: `'same-origin'`","value":{"type":["'cors'","'no-cors'","'same-origin'"]}},{"name":"src","description":"HTML fragment source. Remote URLs are validated through the shared\n`safeFetchUrl()` allowlist (`http:`, `https:`, `blob:`, `data:`). Use\n`#id` to clone a same-page source's children or `/partial.html#id` to\nselect children from a sanitized remote document.\nAn empty/falsy value is a no-op: no fetch, no events, existing content\nuntouched.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"slots":[{"name":"","description":"Fallback content shown until (or unless) a fetch succeeds; overwritten with the sanitized fragment once one does."}],"js":{"properties":[{"name":"activeHighlightId","description":"Id of the currently active highlight, or null when none is active.\n\nAttribute: `active-highlight-id`","type":"string | null","default":"null"},{"name":"anchor","description":"Anchor or highlight id to resolve and scroll into view.","type":"LyraAnchor | string | null","default":"null"},{"name":"anchorKinds","description":"Anchor kinds supported by this viewer instance.","type":"readonly LyraAnchorKind[]","default":"[]","read-only":true},{"name":"cache","description":"Shares bounded, sanitized remote resources with matching Include requests. Set to false to\nopt out of both retained values and in-flight deduplication.\n\nAttribute: `cache`","type":"boolean","default":"true"},{"name":"highlights","description":"Highlights rendered by the document target. Reassign after mutation.","type":"LyraHighlight[]","default":"[]"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"mode","description":"Attribute: `mode`  \nReflected to its attribute.","type":"LyraIncludeMode","default":"'same-origin'"},{"name":"src","description":"HTML fragment source. Remote URLs are validated through the shared\n`safeFetchUrl()` allowlist (`http:`, `https:`, `blob:`, `data:`). Use\n`#id` to clone a same-page source's children or `/partial.html#id` to\nselect children from a sanitized remote document.\nAn empty/falsy value is a no-op: no fetch, no events, existing content\nuntouched.\n\nAttribute: `src`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-anchor-result","description":"Fired after an `anchor` assignment or `scrollToAnchor()` call is applied. `detail: { found: boolean }`. Bubbling, composed, and non-cancelable.","type":"CustomEvent<AnchorResultDetail>"},{"name":"lr-error","description":"The same failure under the spelling Shoelace's `sl-error` migrates to; it always fires alongside `lr-include-error` with the identical detail object. Neither spelling is deprecated.","type":"CustomEvent<LyraIncludeErrorDetail>"},{"name":"lr-include-error","description":"Loading, selecting, or sanitizing the fragment failed; see `LyraIncludeErrorReason` for `detail.reason`. Mirrors Web Awesome's `wa-include-error`.","type":"CustomEvent<LyraIncludeErrorDetail>"},{"name":"lr-load","description":"The source fragment was sanitized and written into the light DOM.","type":"CustomEvent<{ src: string }>"},{"name":"lr-search-change","description":"Fired whenever included-content search state changes. `matchCountExact=false` makes the retained count a lower bound. Bubbling, composed, and non-cancelable.","type":"CustomEvent<LyraSearchChangeDetail>"},{"name":"lr-text-select","description":"Fired after a selection ends inside the included content. `detail: { text: string; anchor: LyraAnchor | null; rects: DOMRect[] }`. Bubbling, composed, and non-cancelable.","type":"CustomEvent<TextSelectDetail>"}]}},{"name":"lr-ingestion-queue","description":"`<lr-ingestion-queue>` — a controlled list of documents moving through an ingestion pipeline\n(upload → text extraction → chunking → embedding → indexing), each row showing its stage,\nprogress, chunk/embedding counts, and a retry or cancel affordance. Presentation only: this\ncomponent runs no ingestion itself, persists nothing, and never mutates `items` -- retrying or\ncancelling a row fires a controlled `lr-retry`/`lr-cancel` request event and waits for the host\nto supply an updated `items` array, the same request/response convention `<lr-thread-list>`'s\n`lr-thread-pin`/`-archive`/`-delete` events already establish.\n\nAbove `virtualizeAt` items, the list renders through an internal `<lr-virtual-list>` instead of a\nplain keyed list (same precedent as `<lr-thread-list>`'s data mode, and the same exclusive `>`\nbound `<lr-chunk-inspector>`/`<lr-retrieval-results>`/`<lr-neighbor-list>` apply to their own\n`virtualize-at`) -- identical row markup and behavior either way, keyed by `id`.\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.\nBlank item ids and later duplicates are ignored before failure state, counts, virtualization,\nrendering, or actions. The first item for an id wins. Missing and unrecognized runtime `stage`\nvalues render as a localized, neutral, inert unknown state so a newer backend stage never\nbecomes a blank or misleadingly actionable row.\nNonstring failure details use the localized failed-stage label before rendering and fresh\nfailure announcements. Omitted details stay omitted; historical failures remain silent on mount.\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| `base` | The one stable root shell across empty, populated, and virtualized states. It is the named region unless a non-empty host `aria-label` makes the host the sole overall owner. |\n| `cancel-button` | Fires `lr-cancel`. Only rendered for non-terminal rows. |\n| `empty` | The `<lr-empty>` zero-items state. |\n| `failure-live` | The visually hidden, `aria-hidden` mirror of the last announced batch of fresh failures — those that transition or are added after mount; historical failed rows remain visible but are not re-announced. The announcement itself lands in the shared light-DOM assertive region (`acquireAnnouncementSink()` in `internal/announcer.ts`), because a live region inside a shadow root is not reliably announced; this part is a styling/inspection surface only. |\n| `item` | One queue item row; carries `data-stage`. When virtualized, reached from this component's own stylesheet via `lr-virtual-list::part(item)` (renders inside the internal `<lr-virtual-list>`'s own shadow root, not this component's). |\n| `item-actions` | Wrapper around the retry/cancel buttons. |\n| `item-attempts` | The attempt count, only rendered once `attempts` is greater than 0. |\n| `item-chunk-count` | The chunk count, only rendered once `chunkCount` is set. |\n| `item-embedding-status` | The \"N of M chunks embedded\" text, only rendered once both `chunkCount` and `embeddedChunkCount` are set. |\n| `item-error` | The failure message, only rendered for `stage=\"failed\"` with `error` set. |\n| `item-header` | The row's name/stage-badge line. |\n| `item-meta` | Wrapper around the chunk-count/embedding-status/attempt-count text. |\n| `item-name` | The document's `name`. |\n| `item-progress` | The row's `<lr-progress-bar>`, only rendered for an active (uploading through indexing) stage. |\n| `item-stage` | The row's `<lr-badge>` showing the localized stage label; its `variant` tracks `stage`. |\n| `list` | The unnamed row container (`role=\"list\"`), including the composed `<lr-virtual-list>` host in virtualized mode. Its surrounding `base` region owns the queue name. |\n| `retry-button` | Fires `lr-retry`. Only rendered for `stage=\"failed\"` rows. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-ingestion-queue-max-height` (default: `none`) — Non-virtualized mode only: caps how tall the list grows before it scrolls internally. Has no effect once virtualized -- the internal `<lr-virtual-list>`'s own viewport keeps its independent, fixed default height (retheme it directly via `<lr-ingestion-queue>`'s own `lr-virtual-list { --lr-virtual-list-height: ... }` if needed).","attributes":[{"name":"announce","description":"Opts this queue into announcing the failures it already carries when it first mounts, through\nthe same shared assertive region, the same list formatting and the same caller-supplied\n`item.error` text a later failure uses. Leave unset for a queue that is part of the page a\nuser is arriving on: those rows render in document order and repeating them is noise. Set it\nwhen the queue is created in response to a user action — a retried ingestion run that mounts\na fresh queue already holding `stage: 'failed'` rows would otherwise never speak them. Read\nonce per element lifetime: a later reconnection or adoption stages the same rows again rather\nthan replaying the announcement, and later failures announce either way. Remove any host\n`role=\"status\"`/`role=\"alert\"` hand-added before this property existed once it is set --\notherwise the initial failures are announced twice, through the native role and again\nthrough the shared sink.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"label","description":"Accessible name for the stable region when the host has no `aria-label`; defaults to\nlocalized `ingestionQueueLabel`. An explicitly empty host label stays empty, and so does an\nexplicitly empty `label`.\n\nType: `string | undefined`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"virtualize-at","description":"Above this item count, the list renders through an internal `<lr-virtual-list>`. Exclusive,\nlike every other `virtualize-at` in this family: exactly this many items still render as a\nplain list.\n\nType: `number`  \nDefault: `100`","value":{"type":["number"]}}],"js":{"properties":[{"name":"announce","description":"Opts this queue into announcing the failures it already carries when it first mounts, through\nthe same shared assertive region, the same list formatting and the same caller-supplied\n`item.error` text a later failure uses. Leave unset for a queue that is part of the page a\nuser is arriving on: those rows render in document order and repeating them is noise. Set it\nwhen the queue is created in response to a user action — a retried ingestion run that mounts\na fresh queue already holding `stage: 'failed'` rows would otherwise never speak them. Read\nonce per element lifetime: a later reconnection or adoption stages the same rows again rather\nthan replaying the announcement, and later failures announce either way. Remove any host\n`role=\"status\"`/`role=\"alert\"` hand-added before this property existed once it is set --\notherwise the initial failures are announced twice, through the native role and again\nthrough the shared sink.\n\nAttribute: `announce`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"items","description":"The queue to render, in display order. Controlled and never mutated by this component --\npass a new array (e.g. as ingestion progresses) to update it.","type":"readonly IngestionQueueItem[]","default":"[]"},{"name":"label","description":"Accessible name for the stable region when the host has no `aria-label`; defaults to\nlocalized `ingestionQueueLabel`. An explicitly empty host label stays empty, and so does an\nexplicitly empty `label`.\n\nAttribute: `label`","type":"string | undefined"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"virtualizeAt","description":"Above this item count, the list renders through an internal `<lr-virtual-list>`. Exclusive,\nlike every other `virtualize-at` in this family: exactly this many items still render as a\nplain list.\n\nAttribute: `virtualize-at`","type":"number","default":"100"}],"events":[{"name":"lr-cancel","description":"A row's cancel affordance was activated (rendered for every non-terminal row). `detail: { itemId, reason }` -- `reason` is always `undefined` from this component.","type":"CustomEvent<IngestionCancelEventDetail>"},{"name":"lr-retry","description":"A row's retry affordance was activated (only rendered for `stage=\"failed\"` rows). `detail: { itemId, attempt }` -- `attempt` is the attempt number about to be made.","type":"CustomEvent<IngestionRetryEventDetail>"}]}},{"name":"lr-input","description":"`<lr-input>` — a single-line plain-text input primitive, the `lr-*` equivalent of a plain\n`wa-input`, form-associated via the `FormAssociated` mixin (same shape as `<lr-textarea>`).\n\nShips the same opt-in `label`/`hint`/`errorText` form-control chrome as `<lr-textarea>`/\n`<lr-select>` (props + matching named slots + `form-control`/`form-control-label`/`hint`/`error`\nparts) — left unset, the chrome stays hidden. `size` uses the same `xs`–`xl` scale as\n`<lr-select>`/`<lr-combobox>`, and `appearance` the shared fill/border vocabulary.\n`type=\"password\"` renders a `password-toggle` eye-icon button — opt-in via the\n`password-toggle` attribute — that flips the internal native input between\n`type=\"password\"`/`type=\"text\"` and tracks `passwordVisible`. `type=\"email\"`/`type=\"number\"`\n(with `min`/`max`/`step`) delegate constraint validation to the internal native `<input>`'s own\nbrowser-computed `validity`, bridged into this element's `ElementInternals` by `updateValidity()`\n— as do `minlength`/`maxlength`/`pattern`, which constrain the text-bearing types.\n`type=\"date\"`/`type=\"datetime-local\"`/`type=\"search\"`/`type=\"tel\"`/`type=\"time\"`/`type=\"url\"`\nforward straight through to the matching native input behavior, the same as `type=\"text\"`.\n\nA host `aria-label` is forwarded to the internal textbox via the typed `accessibleLabel` property.\nA host `aria-describedby` is resolved onto that native input, ahead of its own hint/error/\nrequired descriptions, so externally-owned guidance remains valid across the shadow boundary.\nHost `aria-labelledby` is deliberately not projected: the native `<label>` already owns this\ncontrol's visible label relationship.\n\nForwards the full native selection/editing surface (`selectionStart`/`selectionEnd`,\n`setSelectionRange()`, `setRangeText()`), the same as `<lr-textarea>`, in addition to\n`focus()`/`blur()`/`select()`, `showPicker()`, and `stepUp()`/`stepDown()`.\n\nThe declarative `match` property pairs this field with a sibling one (by id, resolved in this\nelement's own root, or by direct element reference) and fails validity — a localized\n`customError` — whenever the two values disagree, once every other constraint already reports\nvalid; see its own doc comment for the full contract. There is no dedicated password-purpose\npreset, by deliberate decision rather than an oversight: the one platform detail a preset would\nactually save — `autocomplete` — has no single correct value for \"a password field\" (`new-password`\non a set/change/reset flow, `current-password` on a login one, never derivable from the other), so\na `purpose`/`preset` property would still take a second parameter carrying that same distinction,\ntrading the existing attributes for an invented vocabulary that a migrating `wa-`/`sl-`/native\n`<input type=\"password\">` author would have to learn instead of carrying over unchanged. Compose\n`type=\"password\"`, `password-toggle`, `autocomplete=\"new-password\"`, and `match` directly for a\nset/change/reset confirmation pair; a login field needs only `type=\"password\"` and\n`autocomplete=\"current-password\"`.\n\nPressing Enter submits the ancestor `<form>`, the implicit submission a native `<input>`\nperforms — the internal input is inside a shadow root and has no form owner of its own, so the\nplatform can never do it here. The form's first enabled submit control becomes\n`SubmitEvent.submitter` (an `<lr-button type=\"submit\">` included, via its own `click()`), a\nmodifier-held or IME-composition Enter is ignored, and a form with no submit button submits only\nfrom a single field — all of it the platform's own rules, shared with every other lyra text\ncontrol through `internal/submit-on-enter.ts`.\n\nComponent-scoped theme inputs remain undeclared on the host, so values inherited from an\nancestor theme wrapper override size, appearance, and pill fallbacks. A value set directly on\nthe input still wins. The same inheritance contract applies to subclasses that reuse this\nstylesheet, including `<lr-number-input>` and `<lr-native-time-input>`.\n\nWhen a clear or password action is rendered, compact tiers grow only enough to contain its\nshared `--lr-icon-button-size` hit target. The `l` and `xl` tiers retain their larger shared\ncontrol heights.\n\nRemoving label, hint, help-text, or error-text safely omits the content while retaining\nnative null property readback. Explicit empty strings remain empty.\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| `clear-icon` | Replaces the built-in clear glyph. |\n| `end` | Adornment after the native input and built-in actions. |\n| `error` | Custom error content. |\n| `help-text` | Shoelace alias for `hint`. |\n| `hide-password-icon` | Replaces the glyph shown while the password is visible. |\n| `hint` | Custom hint content. |\n| `label` | Custom label content. |\n| `prefix` | Shoelace alias for `start`. |\n| `show-password-icon` | Replaces the glyph shown while the password is hidden. |\n| `start` | Adornment before the native input. |\n| `suffix` | Shoelace alias for `end`. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | Compatibility name for the control row; use `input-wrapper`. |\n| `clear-button` | The clear action, rendered for non-empty clearable text/search inputs. |\n| `end` | Wrapper around the `end` adornment slot, with the same containment behavior. |\n| `error` | The error message. |\n| `form-control` | The outer wrapper around label, input, error and hint. |\n| `form-control-help-text` | Shoelace compatibility name for the hint message. |\n| `form-control-input` | Compatibility name for the control row. |\n| `form-control-label` | The `<label>` element. |\n| `hint` | The hint message. |\n| `input` | The native `<input>` element. |\n| `input-wrapper` | The row wrapping the native input and built-in actions. It is the same node as `base`. |\n| `label` | Wrapper around the visible label content. |\n| `password-toggle` | The show/hide-password button, rendered only for `type=\"password\"` with `password-toggle` set. |\n| `password-toggle-button` | Wrapper around the password-toggle icon. |\n| `prefix` | Shoelace compatibility part on the `prefix` slot. |\n| `start` | Wrapper around the `start` adornment slot. Long content shrinks and ellipsizes rather than widening the control allocation. |\n| `suffix` | Shoelace compatibility part on the `suffix` slot. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-input-control-min-height` (default: `var(--lr-form-control-height)`) — Outer control height floor, taken from the active `size` tier of the shared form-control ladder (`internal/sizes.styles.ts`), so an input is exactly as tall as an `<lr-button>`/`<lr-select>` of the same tier.\n- `--lr-input-control-height` — Exact outer control height. Unset by default, which leaves `--lr-input-control-min-height` as a floor only; set it to a length to both floor and cap the control row (e.g. to pixel-match `<lr-select>`/`<lr-combobox>` in the same toolbar). Because it is never declared by the component itself, it can be set from an ancestor or an outer-tree rule as well as inline on the element.\n- `--lr-input-padding-block` (default: `var(--lr-form-control-padding-block)`) — Block padding of the native input, from the active `size` tier of the shared ladder.\n- `--lr-input-padding-inline` (default: `var(--lr-form-control-padding-inline)`) — Inline padding of the control row, from the active `size` tier.\n- `--lr-input-font-size` (default: `var(--lr-form-control-font-size)`) — Font size of the native input, from the active `size` tier.\n- `--lr-input-gap` (default: `var(--lr-space-xs)`) — Gap between the start/end adornments and the native input in the control row. Unlike the size knobs above it does not vary by `size` tier. Override it to retune without a `::part(input-wrapper)` rule.\n- `--lr-input-radius` (default: `var(--lr-form-control-radius)`) — Corner radius of the control row, from the active `size` tier of the shared ladder (the two tightest tiers take a smaller radius). `pill` swaps it to `--lr-radius-pill`.\n- `--lr-input-fill` (default: `transparent`) — Background of the control row. Its private default changes per `appearance`; the public value remains authoritative in every appearance.\n- `--lr-input-border-color` (default: `var(--lr-color-border)`) — Border color of the control row, with a private default that changes per `appearance` in the same way as `--lr-input-fill`.\n- `--lr-input-focus-border-color` (default: `var(--lr-color-brand)`) — Control-row border color while focus is within the field.\n- `--lr-input-action-color` (default: `var(--lr-color-text-quiet)`) — Resting clear/password/number- stepper action color.\n- `--lr-input-action-hover-color` (default: `var(--lr-color-text)`) — Hovered action color.\n- `--lr-input-action-active-color` (default: `var(--lr-input-action-hover-color,var(--lr-color-text))`) — Pressed action color.\n- `--lr-input-action-active-bg` (default: `color-mix(in oklab,var(--lr-color-surface),var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Pressed action background. The same hooks apply to `lr-number-input`'s stepper pair.\n- `--lr-input-time-picker-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background for the browser-native time-picker indicator when `type=\"time\"`.\n- `--lr-input-time-picker-active-bg` (default: `var(--lr-color-brand)`) — Pressed background for the browser-native time-picker indicator when `type=\"time\"`.\n- `--lr-input-time-picker-focus-bg` (default: `var(--lr-color-brand-quiet)`) — Focus-visible background for the native time-picker indicator.\n- `--lr-input-time-picker-focus-ring` (default: `var(--lr-focus-ring-color)`) — Focus-visible outline color for the native time-picker indicator.\n- `--lr-form-control-focus-shadow` (default: `none`) — The shared field focus halo, painted as a `box-shadow` while this control is focused. One name for every field-shaped control in the library, so a halo is configured once rather than per component. Additive: the focus outline and border cue are the accessibility answer to focus and are never replaced by it.\n- `--lr-form-control-required-content` (default: `' *'`) — The required-field marker rendered after the label. Set it to `''` to suppress the marker, or to any other quoted string (`' (required)'`, a localized word) to replace it. Caller-supplied content, so it is never localized here.\n- `--lr-form-control-required-color` (default: `var(--lr-color-danger)`) — Color of that marker, retunable without touching any other danger-coloured surface.\n- `--lr-form-control-required-offset` (default: `0`) — Inline space between the label text and the marker.","attributes":[{"name":"appearance","description":"Visual treatment of the control row, from the library's shared field vocabulary.\n`'outlined'` (the mapped default) draws a border without a fill; `'filled-outlined'` draws\nthe fill, `'filled'` drops the border, `'plain'` drops both, and `'accent'` tints both with\nthe brand color. Each value only swaps `--lr-input-fill`/`--lr-input-border-color`, so a\nconsumer can retune any of them without a `::part(input-wrapper)` rule.\n\nType: `LyraAppearance`  \nDefault: `'outlined'`","value":{"type":["'accent'","'filled'","'outlined'","'filled-outlined'","'plain'"]}},{"name":"aria-label","description":"Accessible name overriding the label/placeholder-derived default. Takes precedence over both\n`label` and `placeholder` when set, matching `<lr-textarea>`'s `accessibleLabel`.\n\nType: `string | null`  \nDefault: `null`"},{"name":"autocapitalize","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"autocomplete","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"autocorrect","description":"Native editing-assistance state forwarded as canonical `autocorrect=\"on\"|\"off\"`. Reads are\nboolean. Writes accept Web Awesome's boolean IDL and Shoelace's `'on'`/`'off'` vocabulary.\n\nType: `boolean | 'off' | 'on'`  \nDefault: `true`"},{"name":"autofocus","description":"Forwarded to the internal native `<input>`, so the browser's own autofocus algorithm targets\nthe real text control rather than the (non-focusable) custom-element host.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"clearable","description":"Shows a built-in clear action for non-empty `text` and `search` inputs.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"custom-error","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nType: `string | null`  \nDefault: `null`"},{"name":"debounce","description":"How long (ms) to wait after the last keystroke before emitting one `lr-input-settled`,\ncoalescing a burst of rapid edits into a single downstream commit -- the same predicate and\n`DebounceController` primitive `<lr-filter-bar>`'s own per-filter `debounce` uses. Omitted,\n`0`, or a non-finite value means no debounce at all: `input`/`lr-input` keep firing per\nkeystroke exactly as before, and `lr-input-settled` never fires. A pending debounce is\nflushed immediately by `change`/Enter/blur (so a blur never drops the last keystroke) and\ncancelled with no stray settle by disconnection, the built-in clear button, and a\nprogrammatic `value` write that changes the value -- a same-value write does not disturb it.\n\nType: `number | undefined`"},{"name":"default-value","description":"Compatibility attribute alias for the supported `defaultValue` reset value.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"disabled","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"enterkeyhint","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"error-text","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"filled","description":"Shoelace's boolean spelling for the filled treatment. It does not overwrite an explicit\n`appearance`; the style alias simply paints the same fill while present.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"form","description":"Type: `HTMLFormElement | string | null`  \nDefault: `null`"},{"name":"help-text","description":"Shoelace alias for hint. `hint` wins when both are supplied.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"hint","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"inputmode","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"label","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"match","description":"Declarative cross-field confirmation constraint: a sibling field to compare this one's\n`value` against, referenced either by id (resolved in this element's own root — an idref\nnever crosses a shadow boundary, matching every other idref this library resolves) or by a\ndirect element reference (works across shadow trees, since no lookup is needed). While set\nand resolvable, this field additionally fails validity — `customError`, with a localized\nmismatch message — whenever its value differs from the referenced element's own `.value`.\nRe-validates automatically whenever either field changes: this field's own edits through the\nusual `value` write, and the referenced field's edits through a listener on its `input`/\n`change` events. A `match` that does not resolve to a live element (a dangling id, most\ncommonly) is inert rather than a permanent block on submission — exactly like the platform's\nown tolerance of an unresolvable `aria-describedby` idref. Pairs with a plain confirmation\nfield (`type=\"password\"` or otherwise); the referenced element only needs a string `.value`,\nso a native `<input>`/`<textarea>` works the same as another `lr-input`.\n\nType: `LyraMatchTarget`  \nDefault: `null`","value":{"type":["LyraMatchTarget"]}},{"name":"max","description":"Upper counterpart of `min`, with the same parsing and the same default of `undefined`.\n\nType: `number | string | undefined`"},{"name":"maxlength","description":"Upper counterpart of `minlength` (native `maxlength`/`tooLong`), with the same parsing and the\nsame default of `undefined`. Note that native `maxlength` also *prevents* typing beyond the\nlimit; it reports `tooLong` for values that arrive some other way (paste of a longer value,\na programmatic assignment).\n\nType: `number | undefined`"},{"name":"min","description":"`type=\"number\"` only — forwarded to the internal native `<input>`'s own `min`/`max`/`step`\nand consulted by that same native input's constraint validation (see `updateValidity()`).\nDefaults to `undefined` (no lower bound). The `min` attribute is parsed as a number here; the\ndeclared type also admits a string so a subclass bound to a non-numeric native input type can\nnarrow the attribute parsing to that type's own literal form (`<lr-native-time-input>`'s `09:00`)\nwithout redeclaring the whole property surface.\n\nType: `number | string | undefined`"},{"name":"minlength","description":"Minimum text length, forwarded to the internal native `<input>`'s own `minlength` and\nconsulted by that same native input's constraint validation (`tooShort`, see\n`updateValidity()`). Defaults to `undefined` (no lower bound). Like native `minlength`, an\nempty value never violates it — pair it with `required` to also reject empty. Ignored by the\nnative input for `type=\"number\"`/`type=\"time\"`, exactly as the platform specifies.\n\nType: `number | undefined`"},{"name":"name","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"no-spin-buttons","description":"Shoelace alias for withoutSpinButtons.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"password-toggle","description":"`type=\"password\"` only — renders the built-in show/hide-password button. Opt-in: a bare\n`type=\"password\"` field ships no toggle at all, so a consumer whose threat model or visual\ndesign excludes one is not forced to hide it with CSS.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"password-visible","description":"`type=\"password\"` only — whether the field currently reveals its raw text. Toggled by the\nbuilt-in `password-toggle` button; also settable by a consumer up front, with or without\nthat button being rendered.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"pattern","description":"A regular expression the value must match in full, forwarded to the internal native\n`<input>`'s own `pattern` and validated by it (`patternMismatch`). Defaults to `undefined`\n(no pattern). Compiled by the browser with the `v` flag and anchored to the whole value, so\nno `^`/`$` is needed; an empty value never violates it.\n\nType: `string | undefined`"},{"name":"pill","description":"Rounds the control row to a full pill by swapping `--lr-input-radius` to\n`--lr-radius-pill`.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"placeholder","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"readonly","description":"Forwards native read-only behavior to the internal input and disables the clear action.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"required","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"size","description":"Visual size on the library's one control ladder — shared with `lr-button`/`lr-select`/\n`lr-combobox`, so same-tier controls line up in a toolbar row. Accepts both the canonical\n`'2xs'`–`'xl'` steps and Web Awesome's/Shoelace's `'small'`/`'medium'`/`'large'` spellings of\n`s`/`m`/`l`; the two render identically. `'2xs'` is the tightest tier, for dense\ntoolbar-embedded controls.\n\nType: `LyraSize`  \nDefault: `'m'`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}},{"name":"spellcheck","description":"Type: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"step","description":"Accepts `'any'` (the native way to disable step validation) in addition to a numeric step.\n\nType: `number | 'any' | undefined`"},{"name":"title","description":"Forwarded to the internal native control.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"type","description":"Native input type. Unsupported runtime strings normalize to `text` at the public boundary so\nnative validity, type-dependent chrome, and the reflected host state cannot diverge.\n\nType: `LyraInputType`  \nDefault: `'text'`","value":{"type":["'text'","'password'","'email'","'number'","'time'","'search'","'date'","'datetime-local'","'tel'","'url'"]}},{"name":"value","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"with-clear","description":"Web Awesome's spelling of clearable, accepted so a mechanical `wa-` → `lr-` rename\ndoes not silently drop the clear action. Prefer `clearable` in new code.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"with-hint","description":"SSR slot-presence hint for hint/help-text content that cannot be inspected before hydration.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"with-label","description":"SSR slot-presence hint for label content that cannot be inspected before hydration.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"without-spin-buttons","description":"`type=\"number\"` only — suppresses the browser's own increment/decrement spin buttons. Left\nunset, the platform's spinners render exactly as they do on a bare `<input type=\"number\">`.\n`<lr-number-input>` defaults it the other way, since it draws its own stepper pair.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"clear-icon","description":"Replaces the built-in clear glyph."},{"name":"end","description":"Adornment after the native input and built-in actions."},{"name":"error","description":"Custom error content."},{"name":"help-text","description":"Shoelace alias for `hint`."},{"name":"hide-password-icon","description":"Replaces the glyph shown while the password is visible."},{"name":"hint","description":"Custom hint content."},{"name":"label","description":"Custom label content."},{"name":"prefix","description":"Shoelace alias for `start`."},{"name":"show-password-icon","description":"Replaces the glyph shown while the password is hidden."},{"name":"start","description":"Adornment before the native input."},{"name":"suffix","description":"Shoelace alias for `end`."}],"js":{"properties":[{"name":"accessibleLabel","description":"Accessible name overriding the label/placeholder-derived default. Takes precedence over both\n`label` and `placeholder` when set, matching `<lr-textarea>`'s `accessibleLabel`.\n\nAttribute: `aria-label`","type":"string | null","default":"null"},{"name":"appearance","description":"Visual treatment of the control row, from the library's shared field vocabulary.\n`'outlined'` (the mapped default) draws a border without a fill; `'filled-outlined'` draws\nthe fill, `'filled'` drops the border, `'plain'` drops both, and `'accent'` tints both with\nthe brand color. Each value only swaps `--lr-input-fill`/`--lr-input-border-color`, so a\nconsumer can retune any of them without a `::part(input-wrapper)` rule.\n\nAttribute: `appearance`  \nReflected to its attribute.","type":"LyraAppearance","default":"'outlined'"},{"name":"autocapitalize","description":"Attribute: `autocapitalize`","type":"string","default":"''"},{"name":"autocomplete","description":"Attribute: `autocomplete`","type":"string","default":"''"},{"name":"autocorrect","description":"Native editing-assistance state forwarded as canonical `autocorrect=\"on\"|\"off\"`. Reads are\nboolean. Writes accept Web Awesome's boolean IDL and Shoelace's `'on'`/`'off'` vocabulary.\n\nAttribute: `autocorrect`","type":"boolean | 'off' | 'on'","default":"true"},{"name":"autofocus","description":"Forwarded to the internal native `<input>`, so the browser's own autofocus algorithm targets\nthe real text control rather than the (non-focusable) custom-element host.\n\nAttribute: `autofocus`","type":"boolean","default":"false"},{"name":"clearable","description":"Shows a built-in clear action for non-empty `text` and `search` inputs.\n\nAttribute: `clearable`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"customError","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nAttribute: `custom-error`  \nReflected to its attribute.","type":"string | null","default":"null"},{"name":"debounce","description":"How long (ms) to wait after the last keystroke before emitting one `lr-input-settled`,\ncoalescing a burst of rapid edits into a single downstream commit -- the same predicate and\n`DebounceController` primitive `<lr-filter-bar>`'s own per-filter `debounce` uses. Omitted,\n`0`, or a non-finite value means no debounce at all: `input`/`lr-input` keep firing per\nkeystroke exactly as before, and `lr-input-settled` never fires. A pending debounce is\nflushed immediately by `change`/Enter/blur (so a blur never drops the last keystroke) and\ncancelled with no stray settle by disconnection, the built-in clear button, and a\nprogrammatic `value` write that changes the value -- a same-value write does not disturb it.\n\nAttribute: `debounce`","type":"number | undefined"},{"name":"defaultValue","description":"Attribute: `value`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"disabled","description":"Attribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"enterKeyHint","description":"Attribute: `enterkeyhint`","type":"string","default":"''"},{"name":"enterkeyhint","type":"string"},{"name":"errorText","description":"Attribute: `error-text`","type":"string","default":"''"},{"name":"filled","description":"Shoelace's boolean spelling for the filled treatment. It does not overwrite an explicit\n`appearance`; the style alias simply paints the same fill while present.\n\nAttribute: `filled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"form","description":"Attribute: `form`  \nReflected to its attribute.","type":"HTMLFormElement | string | null","default":"null"},{"name":"helpText","description":"Shoelace alias for hint. `hint` wins when both are supplied.\n\nAttribute: `help-text`","type":"string","default":"''"},{"name":"hint","description":"Attribute: `hint`","type":"string","default":"''"},{"name":"input","description":"The internal native `<input>` element, for direct DOM access — mirrors `<lr-textarea>`'s own `input` getter.","type":"HTMLInputElement | null","read-only":true},{"name":"inputMode","description":"Attribute: `inputmode`","type":"string","default":"''"},{"name":"inputmode","type":"string"},{"name":"label","description":"Attribute: `label`","type":"string","default":"''"},{"name":"labels","type":"NodeList","read-only":true},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"match","description":"Declarative cross-field confirmation constraint: a sibling field to compare this one's\n`value` against, referenced either by id (resolved in this element's own root — an idref\nnever crosses a shadow boundary, matching every other idref this library resolves) or by a\ndirect element reference (works across shadow trees, since no lookup is needed). While set\nand resolvable, this field additionally fails validity — `customError`, with a localized\nmismatch message — whenever its value differs from the referenced element's own `.value`.\nRe-validates automatically whenever either field changes: this field's own edits through the\nusual `value` write, and the referenced field's edits through a listener on its `input`/\n`change` events. A `match` that does not resolve to a live element (a dangling id, most\ncommonly) is inert rather than a permanent block on submission — exactly like the platform's\nown tolerance of an unresolvable `aria-describedby` idref. Pairs with a plain confirmation\nfield (`type=\"password\"` or otherwise); the referenced element only needs a string `.value`,\nso a native `<input>`/`<textarea>` works the same as another `lr-input`.\n\nAttribute: `match`","type":"LyraMatchTarget","default":"null"},{"name":"max","description":"Upper counterpart of `min`, with the same parsing and the same default of `undefined`.\n\nAttribute: `max`","type":"number | string | undefined"},{"name":"maxlength","description":"Upper counterpart of `minlength` (native `maxlength`/`tooLong`), with the same parsing and the\nsame default of `undefined`. Note that native `maxlength` also *prevents* typing beyond the\nlimit; it reports `tooLong` for values that arrive some other way (paste of a longer value,\na programmatic assignment).\n\nAttribute: `maxlength`","type":"number | undefined"},{"name":"min","description":"`type=\"number\"` only — forwarded to the internal native `<input>`'s own `min`/`max`/`step`\nand consulted by that same native input's constraint validation (see `updateValidity()`).\nDefaults to `undefined` (no lower bound). The `min` attribute is parsed as a number here; the\ndeclared type also admits a string so a subclass bound to a non-numeric native input type can\nnarrow the attribute parsing to that type's own literal form (`<lr-native-time-input>`'s `09:00`)\nwithout redeclaring the whole property surface.\n\nAttribute: `min`","type":"number | string | undefined"},{"name":"minlength","description":"Minimum text length, forwarded to the internal native `<input>`'s own `minlength` and\nconsulted by that same native input's constraint validation (`tooShort`, see\n`updateValidity()`). Defaults to `undefined` (no lower bound). Like native `minlength`, an\nempty value never violates it — pair it with `required` to also reject empty. Ignored by the\nnative input for `type=\"number\"`/`type=\"time\"`, exactly as the platform specifies.\n\nAttribute: `minlength`","type":"number | undefined"},{"name":"name","description":"Attribute: `name`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"noSpinButtons","description":"Shoelace alias for withoutSpinButtons.\n\nAttribute: `no-spin-buttons`","type":"boolean","default":"false"},{"name":"passwordToggle","description":"`type=\"password\"` only — renders the built-in show/hide-password button. Opt-in: a bare\n`type=\"password\"` field ships no toggle at all, so a consumer whose threat model or visual\ndesign excludes one is not forced to hide it with CSS.\n\nAttribute: `password-toggle`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"passwordVisible","description":"`type=\"password\"` only — whether the field currently reveals its raw text. Toggled by the\nbuilt-in `password-toggle` button; also settable by a consumer up front, with or without\nthat button being rendered.\n\nAttribute: `password-visible`","type":"boolean","default":"false"},{"name":"pattern","description":"A regular expression the value must match in full, forwarded to the internal native\n`<input>`'s own `pattern` and validated by it (`patternMismatch`). Defaults to `undefined`\n(no pattern). Compiled by the browser with the `v` flag and anchored to the whole value, so\nno `^`/`$` is needed; an empty value never violates it.\n\nAttribute: `pattern`","type":"string | undefined"},{"name":"pill","description":"Rounds the control row to a full pill by swapping `--lr-input-radius` to\n`--lr-radius-pill`.\n\nAttribute: `pill`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"placeholder","description":"Attribute: `placeholder`","type":"string","default":"''"},{"name":"readonly","description":"Forwards native read-only behavior to the internal input and disables the clear action.\n\nAttribute: `readonly`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"required","description":"Attribute: `required`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"selectionEnd","type":"number | null"},{"name":"selectionStart","description":"Cursor/selection extent, mirroring `<lr-textarea>`'s identical passthrough. `null` both when\nthe internal input hasn't rendered yet and whenever the current `type` doesn't support\nselection at all (matching the native `<input>`'s own contract — only `text`/`search` among\nthis component's types do; `password` also supports it natively but isn't exercised here).","type":"number | null"},{"name":"size","description":"Visual size on the library's one control ladder — shared with `lr-button`/`lr-select`/\n`lr-combobox`, so same-tier controls line up in a toolbar row. Accepts both the canonical\n`'2xs'`–`'xl'` steps and Web Awesome's/Shoelace's `'small'`/`'medium'`/`'large'` spellings of\n`s`/`m`/`l`; the two render identically. `'2xs'` is the tightest tier, for dense\ntoolbar-embedded controls.\n\nAttribute: `size`  \nReflected to its attribute.","type":"LyraSize","default":"'m'"},{"name":"spellcheck","description":"Attribute: `spellcheck`","type":"boolean","default":"true"},{"name":"step","description":"Accepts `'any'` (the native way to disable step validation) in addition to a numeric step.\n\nAttribute: `step`","type":"number | 'any' | undefined"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"title","description":"Forwarded to the internal native control.\n\nAttribute: `title`","type":"string","default":"''"},{"name":"type","description":"Native input type. Unsupported runtime strings normalize to `text` at the public boundary so\nnative validity, type-dependent chrome, and the reflected host state cannot diverge.\n\nAttribute: `type`  \nReflected to its attribute.","type":"LyraInputType","default":"'text'"},{"name":"validationMessage","type":"string","read-only":true},{"name":"validity","type":"ValidityState","read-only":true},{"name":"value","description":"Live string value. A Web Awesome-compatible null write clears it without widening reads.","type":"string"},{"name":"valueAsDate","description":"Native date/time value view. Unsupported input types mirror the native getter and return\n`null`; assignment follows the native input's own conversion and remains event-silent.","type":"Date | null"},{"name":"valueAsNumber","description":"Native numeric view (milliseconds for date/time inputs, numeric value for number inputs).\nAssignment is silent, matching `HTMLInputElement.valueAsNumber`.","type":"number"},{"name":"willValidate","type":"boolean","read-only":true},{"name":"withClear","description":"Web Awesome's spelling of clearable, accepted so a mechanical `wa-` → `lr-` rename\ndoes not silently drop the clear action. Prefer `clearable` in new code.\n\nAttribute: `with-clear`","type":"boolean","default":"false"},{"name":"withHint","description":"SSR slot-presence hint for hint/help-text content that cannot be inspected before hydration.\n\nAttribute: `with-hint`","type":"boolean","default":"false"},{"name":"withLabel","description":"SSR slot-presence hint for label content that cannot be inspected before hydration.\n\nAttribute: `with-label`","type":"boolean","default":"false"},{"name":"withoutSpinButtons","description":"`type=\"number\"` only — suppresses the browser's own increment/decrement spin buttons. Left\nunset, the platform's spinners render exactly as they do on a bare `<input type=\"number\">`.\n`<lr-number-input>` defaults it the other way, since it draws its own stepper pair.\n\nAttribute: `without-spin-buttons`  \nReflected to its attribute.","type":"boolean","default":"false"}],"events":[{"name":"blur","description":"Re-dispatched from the internal native `<input>`'s own `blur` — bubbling and composed (unlike the native event, which is neither).","type":"FocusEvent"},{"name":"change","description":"Native-style composed event fired at the native `change` timing.","type":"Event"},{"name":"focus","description":"Re-dispatched from the internal native `<input>`'s own `focus`, for the same reason as `blur`.","type":"FocusEvent"},{"name":"input","description":"Native-style composed event fired on every user-driven edit.","type":"InputEvent"},{"name":"lr-change","description":"Compatibility alias for `change`; `detail: { value }`.","type":"CustomEvent<{ value: string }>"},{"name":"lr-clear","description":"The built-in clear button cleared a text/search value, after the input/change events.","type":"CustomEvent<null>"},{"name":"lr-input","description":"Compatibility alias for `input`; `detail: { value }`.","type":"CustomEvent<{ value: string }>"},{"name":"lr-input-settled","description":"Fires once, `debounce` ms after the last keystroke, alongside the per-keystroke `input`/`lr-input` pair (which keep firing on every edit). `detail: { value }`, non-cancelable. A pending debounce is flushed immediately on `change`/Enter/blur, and cancelled with no stray settle on disconnect, the built-in clear button, and a programmatic `value` write that actually changes the value -- a same-value write (e.g. the controlled-input pattern of a framework re-binding `value` from the state its own handler just set) leaves the pending debounce armed instead of silently defeating it. Never fires while `debounce` is unset, `0`, or non-finite.","type":"CustomEvent<{ value: string }>"},{"name":"lr-invalid","description":"The input failed a validity check. Cancelable: `preventDefault()` forwards to the native `invalid` event, suppressing the browser's own validation bubble and the focus/scroll `reportValidity()` would otherwise perform.","type":"CustomEvent<null>"}]}},{"name":"lr-intersection-observer","description":"`<lr-intersection-observer>` — observes slotted targets entering or\nleaving a viewport and emits the native intersection entries without adding\nlayout or requiring consumers to manage observer lifecycle.\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) | Elements to observe. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The non-layout wrapper around the observed slot. |","attributes":[{"name":"disabled","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"intersect-class","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"once","description":"Stops observing each target after its first intersection. Consumed targets stay consumed\nacross option-driven observer rebuilds and reconnects; setting `once` to false resets them.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"root","description":"Element root or mapped element-ID string.\n\nType: `Element | string | null`  \nDefault: `null`"},{"name":"root-margin","description":"Type: `string`  \nDefault: `'0px'`","value":{"type":["string"]}},{"name":"threshold","description":"Type: `number | number[] | string`  \nDefault: `'0'`"}],"slots":[{"name":"","description":"Elements to observe."}],"js":{"properties":[{"name":"disabled","description":"Attribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"intersectClass","description":"Attribute: `intersect-class`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"once","description":"Stops observing each target after its first intersection. Consumed targets stay consumed\nacross option-driven observer rebuilds and reconnects; setting `once` to false resets them.\n\nAttribute: `once`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"root","description":"Element root or mapped element-ID string.\n\nAttribute: `root`","type":"Element | string | null","default":"null"},{"name":"rootMargin","description":"Attribute: `root-margin`","type":"string","default":"'0px'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"threshold","description":"Attribute: `threshold`","type":"number | number[] | string","default":"'0'"}],"events":[{"name":"lr-intersect","description":"Emitted once per native entry with `detail: { entry }`.","type":"CustomEvent<{ entry: IntersectionObserverEntry }>"},{"name":"lr-intersection","description":"Compatibility batch event emitted once per callback with frozen `detail: { entries: readonly IntersectionObserverEntry[] }`; the detached bounded sequence retains native entry identities.","type":"CustomEvent<\n    Readonly<{ entries: readonly IntersectionObserverEntry[] }>\n  >"}]}},{"name":"lr-json-schema-viewer","description":"`<lr-json-schema-viewer>` — a recursive, selectable JSON Schema inspector with required-state,\nconstraints, composition branches, `$ref` display, validation issues, cycle protection, and a\nconfigurable depth ceiling. It does not resolve remote references or validate values.\n\nPublic schema records and issue collections take bounded, clone-owned readonly snapshots.\nSchema records recursively copy supported own data fields without invoking accessors; unsupported\nor unsafe branches are omitted while valid siblings remain. Create and reassign a new record or\narray after changes; mutating the assigned value does not update the view.\n\n---\n\n**Component metadata**\n\n- Status: `stable`\n- Since: `9.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 named schema region. |\n| `constraints` | Recognized schema constraints. |\n| `description` | Caller-supplied schema description. |\n| `empty` | The empty state. |\n| `issue` | One caller-supplied validation issue. |\n| `issue-limit` | Resource-ceiling status shown when additional validation issues are omitted. |\n| `limit` | Resource-ceiling status shown when additional nodes are omitted. |\n| `name` | Property/branch name. |\n| `node` | One schema node. |\n| `node-selected` | The selected schema node. |\n| `node-trigger` | A schema-node activation button. |\n| `required` | Required badge. |\n| `tree` | The recursive schema tree. |\n| `type` | Schema type badge. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-schema-viewer-error-bg` (default: `var(--lr-color-danger-quiet)`) — Error issue background.\n- `--lr-schema-viewer-error-border` (default: `var(--lr-color-danger)`) — Error issue border.\n- `--lr-schema-viewer-info-bg` (default: `var(--lr-color-brand-quiet)`) — Info issue background.\n- `--lr-schema-viewer-info-border` (default: `var(--lr-color-brand)`) — Info issue border.\n- `--lr-schema-viewer-max-indent` (default: `var(--lr-size-12rem)`) — Maximum visual indentation; complete JSON Pointer paths and selection semantics remain unchanged at deeper levels.\n- `--lr-schema-viewer-selected-border` (default: `var(--lr-color-brand)`) — Selected node branch.\n- `--lr-schema-viewer-warning-bg` (default: `var(--lr-color-warning-quiet)`) — Warning issue background.\n- `--lr-schema-viewer-warning-border` (default: `var(--lr-color-warning)`) — Warning issue border.","attributes":[{"name":"label","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max-depth","description":"Requested nesting depth, clamped to 100 to keep recursive template construction stack-safe.\n\nType: `number`  \nDefault: `20`","value":{"type":["number"]}},{"name":"selected-path","description":"Controlled JSON Pointer selection. `null` means no selection; the empty\nstring is the valid JSON Pointer for the schema root.\n\nType: `string | null`  \nDefault: `null`"}],"js":{"properties":[{"name":"issues","type":"readonly SchemaValidationIssue[]","default":"[]"},{"name":"label","description":"Attribute: `label`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"maxDepth","description":"Requested nesting depth, clamped to 100 to keep recursive template construction stack-safe.\n\nAttribute: `max-depth`","type":"number","default":"20"},{"name":"schema","description":"Clone-owned recursive schema snapshot. Reassign a new record after changing any branch.\nBounded and depth-clamped by snapshotSchemaNode; a malformed branch is omitted\nwithout discarding admitted siblings. A runtime non-array `required` keyword is absent.","type":"JsonSchemaNode | null"},{"name":"selectedPath","description":"Controlled JSON Pointer selection. `null` means no selection; the empty\nstring is the valid JSON Pointer for the schema root.\n\nAttribute: `selected-path`","type":"string | null","default":"null"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-schema-select","description":"A schema node was activated. `detail: { schemaPath, schema }`.","type":"CustomEvent<\n    LyraEventDetailSnapshot<{ schemaPath: string; schema: JsonSchemaNode }>\n  >"}]}},{"name":"lr-json-viewer","description":"`<lr-json-viewer>` — a collapsible, copyable tree view for an arbitrary\nJSON-serializable value (object/array/string/number/boolean/null/\nundefined). Serves as the fallback renderer wherever a raw payload (tool\ncall arguments, a tool result, an API response) needs inspecting without a\nbespoke view.\n\nExpand/collapse state is keyed by structural path (not by object identity),\nso it survives a `data` reassignment that keeps the same shape -- e.g. a\nstreaming tool result being patched in place.\nImperative search-cursor changes are appended to the shared light-DOM polite announcement sink;\ninitial/reconnect state and changes while the host is accessibility-hidden are silent, and the\nshadow tree retains only an `aria-hidden` text mirror.\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 root scroll container; respects `max-height`. |\n| `bracket` | A `{`, `}`, `[`, or `]` delimiter. |\n| `copy-button` | A copy-to-clipboard button -- the top-level one (in `toolbar`, labelled \"Copy JSON to clipboard\") or a per-node one (only rendered when `copyable`; labelled with its own key/type, e.g. \"Copy age\", so assistive tech can tell rows apart). |\n| `key` | An object property key or array index label. |\n| `limit` | Localized notice shown when the depth/node traversal budget truncates rendering or search. |\n| `row` | A single structural JSON row (opening/value rows and closing-delimiter rows). |\n| `toggle` | A container node's expand/collapse button (hidden, but present for row alignment, on leaf/empty nodes). |\n| `toolbar` | The wrapper around the top-level copy button (only rendered when `copyable`). |\n| `tree` | The wrapper around the rendered node tree. |\n| `value` | A primitive value's text -- carries `data-type` (`string`/`number`/`boolean`/`null`/`undefined`, or `circular` for a self-reference marker in place of a re-visited container's subtree) for per-type coloring, `data-match` while it matches `search`, and `data-active` while it is the current `searchNext()`/`searchPrevious()` cursor position. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-json-viewer-active-outline` (default: `var(--lr-focus-ring-color)`) — Outline color for the current imperative search match.\n- `--lr-json-viewer-boolean-color` (default: `var(--lr-color-warning)`) — Boolean value color.\n- `--lr-json-viewer-font` (default: `var(--lr-font-mono)`) — Font family used for the rendered tree.\n- `--lr-json-viewer-match-bg` (default: `var(--lr-color-warning-quiet)`) — Background (and surrounding box-shadow) of a key/value that currently matches `search`.\n- `--lr-json-viewer-max-height` (default: `none`) — Cap on `[part=\"base\"]`'s block size, past which the viewer scrolls internally. The `maxHeight` property sets this token inline on `[part=\"base\"]`.\n- `--lr-json-viewer-null-color` (default: `var(--lr-color-text-quiet)`) — Null, undefined, and circular-reference marker color.\n- `--lr-json-viewer-number-color` (default: `var(--lr-color-brand)`) — Number value color.\n- `--lr-json-viewer-row-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background for a structural row.\n- `--lr-json-viewer-string-color` (default: `var(--lr-color-success)`) — String value color.","attributes":[{"name":"collapsed-depth","description":"Nodes at or beyond this nesting depth (root = 0) start collapsed. Omit/undefined: nothing auto-collapses.\n\nType: `number | undefined`"},{"name":"copyable","description":"Shows copy-to-clipboard affordances: one for the whole value, plus one per node.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max-height","description":"A CSS length (e.g. `\"20rem\"`); once set, the viewer scrolls internally past this height\ninstead of growing the page. Invalid values are ignored.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"search","description":"Removing the attribute clears search without changing its null readback. Case-insensitive substring match against keys/values; matches are highlighted and their ancestors auto-expanded. See also `runSearch()`/`searchNext()`/`searchPrevious()`/`clearSearch()` for imperative, cursor-navigable search built on top of this property.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"js":{"properties":[{"name":"collapsedDepth","description":"Nodes at or beyond this nesting depth (root = 0) start collapsed. Omit/undefined: nothing auto-collapses.\n\nAttribute: `collapsed-depth`","type":"number | undefined"},{"name":"copyable","description":"Shows copy-to-clipboard affordances: one for the whole value, plus one per node.\n\nAttribute: `copyable`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"data","description":"The value to render. Any JSON-serializable value, plus `undefined`.","type":"unknown"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"maxHeight","description":"A CSS length (e.g. `\"20rem\"`); once set, the viewer scrolls internally past this height\ninstead of growing the page. Invalid values are ignored.\n\nAttribute: `max-height`","type":"string","default":"''"},{"name":"search","description":"Removing the attribute clears search without changing its null readback. Case-insensitive substring match against keys/values; matches are highlighted and their ancestors auto-expanded. See also `runSearch()`/`searchNext()`/`searchPrevious()`/`clearSearch()` for imperative, cursor-navigable search built on top of this property.\n\nAttribute: `search`","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-copy","description":"Clipboard writing from the top-level or per-node action fulfilled. The frozen shared outcome detail is `{ ok: true, text }`.","type":"CustomEvent<LyraClipboardWriteSuccess>"},{"name":"lr-copy-error","description":"Clipboard writing failed. The frozen shared outcome detail is `{ ok: false, text, reason, error }`.","type":"CustomEvent<LyraClipboardWriteFailure>"},{"name":"lr-error","description":"Clipboard writing failed. Bubbling, composed, and carries no detail.","type":"CustomEvent<null>"},{"name":"lr-search-change","description":"Fired whenever the search query, match count, or active-match cursor changes -- from `runSearch()`/`searchNext()`/`searchPrevious()`/`clearSearch()`, or a direct `search`/`data` property write. `detail: { query, matchCount, matchCountExact, activeIndex }`; `matchCountExact=false` means the bounded count is a known lower bound.","type":"CustomEvent<{\n    query: string;\n    matchCount: number;\n    matchCountExact: boolean;\n    activeIndex: number;\n  }>"}]}},{"name":"lr-kbd","description":"`<lr-kbd>` — a small chip representing a keyboard shortcut, rendering\nthe platform-appropriate glyph for cross-platform modifier keys (⌘ on\nmacOS, \"Ctrl\" elsewhere) from a single platform-neutral `keys` string.\n\n`keys` is a `+`-separated sequence of tokens, e.g. `\"mod+k\"` or\n`\"mod+shift+p\"`. Recognized modifier tokens: `mod` (the platform-neutral\nprimary modifier — ⌘ on macOS, \"Ctrl\" elsewhere), `alt` (⌥ / \"Alt\"),\n`shift` (⇧ on every platform), and `ctrl` (always the literal Control\nkey, distinct from `mod`, for a shortcut that's specifically Ctrl even on\nmacOS). Any other token renders as typed, except a bare single\nletter/digit which is upper-cased, with a small built-in map of friendly\nlabels for common named keys (`enter` → `↵`, `esc` → \"Esc\", the four\narrow keys → arrow glyphs, plus `tab`/`space`/`backspace`/`delete`/`home`/\n`end`/`pageup`/`pagedown`/`plus`/`minus`). `enter` renders as its `↵`\nglyph (not the word \"Enter\") to match the other single-glyph modifier/\narrow keys visually — its spelled-out word form still appears in the\ncomputed `aria-label`.\n\nEach token renders as its own key cap (`part=\"key\"`); consecutive caps\nare joined by a small \"+\" separator between them, matching how most\ncross-platform shortcut documentation (including on macOS, despite the\nOS's own native shortcut hints usually running the glyphs together with\nno separator) reads unambiguously regardless of how many/which glyphs are\ninvolved.\n\nThe default slot is not used for the normal glyph rendering above — it's\nan escape hatch for fully custom content (e.g. an icon instead of a text\nglyph) that, when non-empty, replaces the `keys`-driven rendering.\nA host `aria-label` names that custom shortcut as one `role=\"img\"` unit;\nwithout one, the slotted content continues to own its own semantics.\n\nRemoving keys safely clears the shortcut. Unknown tokens, including constructor and __proto__, render and name themselves verbatim; recognized modifiers keep their localized labels.\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) | Optional override for fully custom key-cap content, replacing the `keys`-driven rendering. Leave empty to use `keys`. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The chip's root element. |\n| `key` | Each rendered key cap (one per token in `keys`). |","attributes":[{"name":"keys","description":"A `+`-separated shortcut, e.g. `'mod+k'`. See the class doc for the\nfull token grammar.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"platform","description":"Platform used for the platform-neutral `mod` and `alt` tokens. `auto` performs browser\ndetection; an explicit value is deterministic across browsers, SSR, screenshots, and tests.\n\nType: `KbdPlatform`  \nDefault: `'auto'`","value":{"type":["'auto'","'mac'","'windows'","'linux'"]}}],"slots":[{"name":"","description":"Optional override for fully custom key-cap content, replacing the `keys`-driven rendering. Leave empty to use `keys`."}],"js":{"properties":[{"name":"effectivePlatform","description":"The concrete, serializable platform currently used to render the shortcut.","type":"EffectiveKbdPlatform","read-only":true},{"name":"keys","description":"A `+`-separated shortcut, e.g. `'mod+k'`. See the class doc for the\nfull token grammar.\n\nAttribute: `keys`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"platform","description":"Platform used for the platform-neutral `mod` and `alt` tokens. `auto` performs browser\ndetection; an explicit value is deterministic across browsers, SSR, screenshots, and tests.\n\nAttribute: `platform`  \nReflected to its attribute.","type":"KbdPlatform","default":"'auto'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}]}},{"name":"lr-knowledge-base","description":"`<lr-knowledge-base>` — a source list for a retrieval knowledge base: sync status, indexing\nhealth, permissions, and per-row create/sync/pause/delete affordances. A controlled data view,\nlike every other Lyra data component: it never syncs or indexes anything itself, only presents\n`sources` and emits request-only events (`lr-source-create`/`-sync`/`-pause`/`-delete`) for the\nhost to act on and reflect back into a new `sources` value -- mirrors `lr-thread-list`'s\n`lr-thread-pin`/`-archive`/`-delete` convention exactly.\n\n`permission` is rendered informationally only (a badge in the permission column); this component\ndoes not gate the per-row action menu by it -- authorization enforcement is the host's own\nconcern, consistent with the controlled/presentational-only contract above. A `'syncing'` row's\n\"Sync now\" action is disabled (a sync is already running); every other row's is enabled,\nincluding `'error'`, so re-running a failed sync is one click. \"Pause sync\" is enabled only while\n`'syncing'`.\n\nComposes `<lr-table>` for the source list (its own click/keydown delegation already treats any\ncustom-element or `role=\"menuitem\"` cell content as interactive, so the per-row `<lr-dropdown>` never\nmisfires the table's row-click handling), `<lr-badge>` for the sync-status/indexing-health/\npermission indicators, `<lr-stat>` for the aggregate summary row above the table, and\n`<lr-dropdown>` + `<lr-menu>` for the per-row action affordances. The table's own\n`lr-row-click` is intentionally stopped from\npropagating further (this component doesn't expose row-click/selection semantics -- only the\nper-row action menu is interactive).\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.\nBlank source ids and later duplicates are ignored before summary counts, rendering, or actions.\nThe first source for an id wins.\n\nA separate `error` state reports a failed source-list load without discarding the toolbar and\nsummary context around it: while `error` is set, the nested `<lr-table>` shows its own built-in\nfailed-load state (the same `error`-prefixed exported parts and `[part='retry-button']` as\n`<lr-table>` itself) in place of the source rows, behind this component's own `error` slot.\nPrecedence matches `<lr-table>`'s: `error` beats the empty state, so a failed load never falls\nthrough to \"no sources\" copy that would hide the retry affordance. This component forwards\n`error`/`errorHeading`/`errorDescription` to the nested table but owns the retry commit itself\n(it intercepts the table's own `lr-retry`, re-proposes its own cancelable one, and only then\nclears `error`) so the outer property never drifts out of sync with the table's internal state.\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**Slots**\n\n| Name | Description |\n| --- | --- |\n| `error` | Replaces the nested table's built-in failed-load state, including its retry button, while `error` is set. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `actions-menu` | A row's `<lr-dropdown>` shell. |\n| `actions-trigger` | The kebab `<button>` opening a row's action menu. |\n| `base` | The root. |\n| `create-button` | The \"Add source\" `<lr-button>`, omitted while `hideCreate` is set. |\n| `document-count` | The formatted `documentCount` text, omitted when unset. |\n| `error` | The nested table's built-in `<lr-empty>` host rendered while `error` is set. |\n| `error-actions` | Exported from the built-in error `<lr-empty>`'s `actions` part. |\n| `error-base` | Exported from the built-in error `<lr-empty>`'s own `base` part. |\n| `error-cell` | The cell inside `error-row` that holds the failed-load content. |\n| `error-description` | Exported from the built-in error `<lr-empty>`'s `description` part. |\n| `error-heading` | Exported from the built-in error `<lr-empty>`'s `heading` part. |\n| `error-icon` | Exported from the built-in error `<lr-empty>`'s `icon` part. |\n| `error-row` | The nested table's single full-width row that replaces the source rows while `error` is set. |\n| `heading` | The heading text. |\n| `health-badge` | The indexing-health `<lr-badge>`. |\n| `health-cell` | A row's indexing-health cell wrapper. |\n| `name-cell` | A row's source-name cell wrapper. |\n| `permission-badge` | The permission `<lr-badge>`, omitted when `permission` is unset. |\n| `retry-button` | The built-in retry control rendered into the error state's `actions`. |\n| `source-name` | The source's name text. |\n| `source-type` | The source's `type` text, omitted when unset. |\n| `summary` | The aggregate-stats row, omitted while `hideSummary` is set or `sources` is empty. |\n| `summary-stat` | One `<lr-stat>` inside `summary`. |\n| `sync-badge` | The sync-status `<lr-badge>`. |\n| `sync-cell` | A row's sync-status cell wrapper. |\n| `sync-error` | The `errorMessage` text, shown only while `syncStatus` is `'error'` and it's set. |\n| `sync-timestamp` | The formatted `lastSyncedAt` text (or a \"never synced\" fallback). |\n| `table` | The `<lr-table>` listing every source. |\n| `toolbar` | The heading + \"Add source\" row. |","attributes":[{"name":"error","description":"Reports a failed source-list load. Forwarded to the nested `<lr-table>`, whose own built-in\nfailed-load state renders in place of the source rows; `<lr-table>`'s own precedence applies\n(`error` beats the empty state). Reflected so `[error]` is selectable from outside.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"error-description","description":"Failed-load supporting copy, forwarded to the nested table.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"error-heading","description":"Failed-load heading override, forwarded to the nested table. Omitted localizes the table's\nown `tableLoadFailed` default.\n\nType: `string | undefined`"},{"name":"hide-create","description":"Hides the toolbar's \"Add source\" affordance, e.g. for a read-only or permission-gated view.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"hide-summary","description":"Hides the aggregate summary row (total/synced/syncing/needs-attention).\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"label","description":"Heading text and the nested table's accessible name. A host `aria-label` independently\nnames the complete component. Omitted falls back to a localized default. An explicitly\nempty `label` keeps the visible heading empty, but the nested table still receives the\nlocalized default as its accessible name so the grid is never left unnamed.\n\nType: `string | undefined`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"slots":[{"name":"error","description":"Replaces the nested table's built-in failed-load state, including its retry button, while `error` is set."}],"js":{"properties":[{"name":"error","description":"Reports a failed source-list load. Forwarded to the nested `<lr-table>`, whose own built-in\nfailed-load state renders in place of the source rows; `<lr-table>`'s own precedence applies\n(`error` beats the empty state). Reflected so `[error]` is selectable from outside.\n\nAttribute: `error`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"errorDescription","description":"Failed-load supporting copy, forwarded to the nested table.\n\nAttribute: `error-description`","type":"string","default":"''"},{"name":"errorHeading","description":"Failed-load heading override, forwarded to the nested table. Omitted localizes the table's\nown `tableLoadFailed` default.\n\nAttribute: `error-heading`","type":"string | undefined"},{"name":"hideCreate","description":"Hides the toolbar's \"Add source\" affordance, e.g. for a read-only or permission-gated view.\n\nAttribute: `hide-create`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"hideSummary","description":"Hides the aggregate summary row (total/synced/syncing/needs-attention).\n\nAttribute: `hide-summary`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"label","description":"Heading text and the nested table's accessible name. A host `aria-label` independently\nnames the complete component. Omitted falls back to a localized default. An explicitly\nempty `label` keeps the visible heading empty, but the nested table still receives the\nlocalized default as its accessible name so the grid is never left unnamed.\n\nAttribute: `label`","type":"string | undefined"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"sources","description":"The sources to list, in display order.","type":"readonly KnowledgeSource[]","default":"[]"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-retry","description":"The nested table's built-in `[part='retry-button']` was activated, only rendered while `error` is set. Cancelable: the default action clears `error`; `preventDefault()` leaves it set instead.","type":"CustomEvent<null>"},{"name":"lr-source-create","description":"The toolbar \"Add source\" affordance was activated. No detail.","type":"CustomEvent<null>"},{"name":"lr-source-delete","description":"A row's \"Delete source\" action was activated. `detail: { sourceId }`.","type":"CustomEvent<{ sourceId: string }>"},{"name":"lr-source-pause","description":"A row's \"Pause sync\" action was activated. `detail: { sourceId }`.","type":"CustomEvent<{ sourceId: string }>"},{"name":"lr-source-sync","description":"A row's \"Sync now\" action was activated. `detail: { sourceId }`.","type":"CustomEvent<{ sourceId: string }>"}]}},{"name":"lr-knowledge-base-admin","description":"`<lr-knowledge-base-admin>` — a responsive operations shell composing the existing controlled\nsource inventory and ingestion queue into one tabbed knowledge-base view. It forwards every\nsource/ingestion action under a namespaced event and never creates connectors, uploads files, or\nchanges indexing configuration itself. Put configuration controls in the `settings` slot.\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: `6.2.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| `settings` | Optional host-owned ingestion, chunking, embedding, or permissions controls. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The root admin wrapper. |\n| `heading` | The visible heading. |\n| `panel` | The active panel. |\n| `settings` | The settings slot wrapper. |\n| `tab` | One tab button. |\n| `tabs` | The tablist. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-knowledge-base-admin-tab-selected-border` (default: `var(--lr-color-brand)`) — Bottom border color of the selected `[part=\"tab\"]`.\n- `--lr-knowledge-base-admin-tab-selected-color` (default: `var(--lr-color-text)`) — Text color of the selected `[part=\"tab\"]`. `::part(tab)[aria-selected='true']` is invalid CSS, so this pair is the only way to restyle the active tab without re-pointing the shared brand/text tokens.","attributes":[{"name":"active-tab","description":"Active tab. Controlled by the host after `lr-tab-change` if desired. An invalid value, or an\ningestion tab that becomes unavailable, normalizes to `'sources'` through the same event\ncontract.\n\nType: `KnowledgeBaseAdminTab`  \nDefault: `'sources'`","value":{"type":["'sources'","'ingestion'"]}},{"name":"hide-ingestion","description":"Hides the ingestion tab and queue. An active/focused ingestion tab moves to Sources.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"label","description":"Accessible name and visible heading. Omitted falls back to a localized default; an\nexplicitly empty `label` is used as-is.\n\nType: `string | undefined`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"slots":[{"name":"settings","description":"Optional host-owned ingestion, chunking, embedding, or permissions controls."}],"js":{"properties":[{"name":"activeTab","description":"Active tab. Controlled by the host after `lr-tab-change` if desired. An invalid value, or an\ningestion tab that becomes unavailable, normalizes to `'sources'` through the same event\ncontract.\n\nAttribute: `active-tab`  \nReflected to its attribute.","type":"KnowledgeBaseAdminTab","default":"'sources'"},{"name":"hideIngestion","description":"Hides the ingestion tab and queue. An active/focused ingestion tab moves to Sources.\n\nAttribute: `hide-ingestion`","type":"boolean","default":"false"},{"name":"ingestionItems","description":"Documents currently moving through ingestion.","type":"readonly IngestionQueueItem[]","default":"[]"},{"name":"label","description":"Accessible name and visible heading. Omitted falls back to a localized default; an\nexplicitly empty `label` is used as-is.\n\nAttribute: `label`","type":"string | undefined"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"sources","description":"Knowledge-base source connectors.","type":"readonly KnowledgeSource[]","default":"[]"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-activate","description":"Fired on every user activation of an available tab -- a click, or an Arrow/Home/End key -- whether or not `activeTab` actually moved. `detail: { value }` carries the activated tab, the same identity `lr-tab-change` reports. Bubbling and composed, so a host outside the shadow tree receives it. Not cancelable: it is a notification that the user picked a tab, not a veto point, and nothing in this component branches on it. Re-picking the active tab is the case `lr-tab-change` deliberately stays silent for -- \"refresh that queue\" is a real intent -- and from the keyboard it is otherwise unobservable, because Home on an already-first active tab (or End on an already-last one) activates a tab and produces no click at all. When an activation does move the tab, `lr-tab-change` is emitted first. The normalization that moves an invalid or newly-hidden tab back to Sources is not a user activation and fires only `lr-tab-change`.","type":"CustomEvent<{ value: KnowledgeBaseAdminTab }>"},{"name":"lr-ingestion-cancel","description":"Forwarded ingestion cancel request.","type":"CustomEvent<CancelEventDetail & { itemId: string }>"},{"name":"lr-ingestion-retry","description":"Forwarded ingestion retry request.","type":"CustomEvent<RetryEventDetail & { itemId: string }>"},{"name":"lr-source-create","description":"Forwarded source creation request.","type":"CustomEvent<null>"},{"name":"lr-source-delete","description":"Forwarded source deletion request. `detail: { sourceId }`.","type":"CustomEvent<{ sourceId: string }>"},{"name":"lr-source-pause","description":"Forwarded source pause request. `detail: { sourceId }`.","type":"CustomEvent<{ sourceId: string }>"},{"name":"lr-source-sync","description":"Forwarded source sync request. `detail: { sourceId }`.","type":"CustomEvent<{ sourceId: string }>"},{"name":"lr-tab-change","description":"The active operations tab changed. `detail: { tab }`.","type":"CustomEvent<{ tab: KnowledgeBaseAdminTab }>"}]}},{"name":"lr-knowledge-graph-explorer","description":"`<lr-knowledge-graph-explorer>` — an orchestration-level surface for exploring a knowledge\ngraph: the `lr-graph` canvas plus entity search, type filters, neighborhood expansion, pinned\nnodes, path finding between pins, node selection, and a details overlay. Composes existing\nprimitives rather than re-implementing graph rendering: `lr-graph` (canvas/pan-zoom/selection),\n`lr-graph-legend` (type filters), `lr-entity-card` (the details popover's default content),\n`lr-neighbor-list` (the selected entity's relationships), `lr-path-strip` (a found path), and\n`lr-popover.showAt()` (the details overlay itself).\n\n**How the details popover finds its viewport position.** `lr-graph.getNodePosition()` and the\n`lr-node-click` event's `{ x, y }` are in the graph's own *local drawing space* (pre pan/zoom),\nnever viewport pixels -- passing them straight to `showAt()` would anchor the popover at the\nwrong place as soon as the graph has panned or zoomed even once. A direct node click resolves\nthe correct viewport rect the way this library's own documented `lr-graph` + `lr-popover.showAt()`\ncomposition does: for `renderer=\"svg\"` (the default), `event.composedPath()` (the native `click`\nthat bubbles out of `lr-graph`'s shadow root) locates the actual clicked `[part=\"node\"]` element,\nwhose `getBoundingClientRect()` is already viewport-relative; for `renderer=\"canvas\"` (no\nper-node DOM element to find), the click event's own `clientX`/`clientY` are used directly, since\ncanvas hit-testing already treats those as viewport coordinates internally. While the popover\nstays open after an `renderer=\"svg\"` click, this component re-reads that same resolved node\nelement's `getBoundingClientRect()` and re-calls `showAt()` every time the composed `lr-graph`\nemits its own `lr-viewport-change` (a frame-coalesced pan/zoom/simulation-tick signal) --\nschedules no continuous popover-polling loop of its own, unlike an idle popover polling the DOM\nevery frame regardless of whether anything actually moved. Selecting a node any other\nway -- a search result, a neighbor row, a path-strip element, keyboard Enter/Space on a graph\nnode (which never dispatches a native `click`) -- has no click event to read a rect from, so it\ninstead calls the public `lr-graph.focusNode(id)` (which centers that node in the viewport) and\nthen anchors the popover at the graph element's own `getBoundingClientRect()` center once that\nsettles; no continuous tracking applies to that path.\n\n**Controlled vs. self-managed state.** `nodes`/`links`/`nodeTypes`/`communities`/`entityDetails`/\n`path` are purely host-supplied data, rendered as given. `hiddenTypes`/`selectedNodeId`/\n`searchQuery`/`pinnedNodeIds` are this component's own genuinely new contribution: it wires them\ninto `lr-graph`'s existing controlled props (`hiddenTypes`, `selectedNodeIds`, `dimmedNodeIds`,\n`dimmedLinkIds`) itself, toggling its own copy on interaction (the same self-toggle-then-emit\ncontract `lr-graph-legend` already uses) so every feature works with zero host wiring, while\nstill being presettable/observable properties and emitting events (`lr-selection-change`,\n`lr-pin-change`, `lr-path-request`, plus every composed primitive's own event bubbling straight through\nunmodified) for a host that wants to persist or react to them.\nHidden node types are excluded from both search matches and selected-entity neighbor rows, and\nactivation requests for a hidden node are ignored before selection changes.\n\n`highlight` controls what drives that dimming, on top of the always-active search-match\ndimming: `'selection'` (the default) dims by the selected node's immediate neighborhood;\n`'hover'` also dims by whichever node is currently pointer-hovered (falling back to the selected\nnode's neighborhood while nothing is hovered); `'none'` turns this component's own dimming off\nentirely, forwarding empty `dimmedNodeIds`/`dimmedLinkIds` regardless of search/selection state\n-- for a host that wants to drive `lr-graph`'s dimming through a different composition instead.\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.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**Slots**\n\n| Name | Description |\n| --- | --- |\n| `detail-actions` | Additive content appended into the default `lr-entity-card`'s `actions` slot, beside its built-in pin toggle. No effect while `details` is overridden. |\n| `detail-body` | Additive content appended inside the default `lr-entity-card`'s body, alongside its `lr-neighbor-list`. No effect while `details` is overridden. |\n| `details` | Overrides the details popover's default content (an `lr-entity-card` with a nested `lr-neighbor-list` and a pin toggle). Receives no data -- a consumer overriding this slot reads the selected entity from `selectedNodeId`/`nodes` itself. Replaces the default card entirely, including `detail-body`/`detail-actions` below. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The root wrapper. It owns `role=\"group\"` and the fallback name unless a non-empty host `aria-label` makes the host the sole overall owner. |\n| `detail-card` | The default-content `lr-entity-card`, only present while `selectedNodeId` resolves to a node. |\n| `detail-popover` | The composed `lr-popover` hosting the details overlay. |\n| `graph` | The composed `lr-graph`. |\n| `legend` | The composed `lr-graph-legend`. |\n| `path` | The composed `lr-path-strip`, only rendered while `path` is non-empty. |\n| `pinned` | The pinned-nodes row, only rendered while `pinnedNodeIds` is non-empty. |\n| `pinned-heading` | The pinned-nodes row's leading label. |\n| `search` | The composed `lr-entity-card` search `lr-input`. |\n| `search-empty` | The \"no matches\" message, shown when `searchQuery` is non-empty but no node matches. |\n| `search-result` | One search-match row (`role=\"listitem\"`, wrapping a `<button>`). |\n| `search-results` | The search-match list, only rendered while `searchQuery` is non-empty. |\n| `toolbar` | The row wrapping the search input and the type-filter legend. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-canvas-reserved-height` (default: `var(--lr-size-24rem)`) — Default block size of both this host and the composed `lr-graph`, shared with the pre-upgrade reservation stylesheet. Below this in the fallback chain, the composed `lr-graph`'s own normalized `height` (forwarded from this component's own `height`) sizes it instead; an explicit outer `block-size` still wins over both.","attributes":[{"name":"fit-to","description":"Forwarded to `lr-graph.fitTo`. `'container'` makes the composed graph draw at exactly the\npane this component's own layout gave it -- the reservation minus whatever the toolbar,\nsearch results, pinned row and path strip take, which is not derivable from `height` -- and\nfollow it live as the explorer is resized. `'none'` (the default) keeps forwarding the\nnumeric `width`/`height` below unchanged.\n\nType: `LyraGraphFit`  \nDefault: `'none'`","value":{"type":["'none'","'container'"]}},{"name":"height","description":"Requested height of the composed graph viewport in CSS pixels. Also sizes the rendered\n`[part=\"graph\"]`/host (see `--lr-canvas-reserved-height`'s doc) whenever neither that nor an\nexplicit outer `block-size` overrides it.\n\nType: `number`  \nDefault: `600`","value":{"type":["number"]}},{"name":"highlight","description":"What drives this component's own `dimmedNodeIds`/`dimmedLinkIds` forwarding, on top of the\nalways-active search-match dimming -- see the class doc's dedicated paragraph.\n\nType: `KnowledgeGraphHighlight`  \nDefault: `'selection'`","value":{"type":["'selection'","'hover'","'none'"]}},{"name":"label","description":"Fallback name for the root group; defaults to localized `graphExplorerLabel`. A non-empty\nhost `aria-label` makes the host the sole overall owner; an explicitly empty host label stays\nempty on the group, and so does an explicitly empty `label`.\n\nType: `string | undefined`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"node-labels","description":"Forwarded to `lr-graph.nodeLabels`. Unset (the default) leaves the composed `lr-graph` to\napply its own per-renderer default -- see that property's own doc.\n\nType: `LyraGraphNodeLabelsMode | undefined`","value":{"type":["'always'","'zoom'","'none'"]}},{"name":"renderer","description":"Forwarded to `lr-graph.renderer`. `renderer=\"canvas\"` has no per-node DOM element, which\nnarrows how the node-detail popover anchors and disables its pan/zoom tracking -- see the\nclass doc's anchoring note.\n\nType: `LyraGraphRenderer`  \nDefault: `'svg'`","value":{"type":["'svg'","'canvas'"]}},{"name":"search-query","description":"The search filter applied to the visible node set. A node matches when the query appears in\nany name it can be known by -- its `id`, its `label` or its `accessibleLabel` -- each folded\nwith the active locale, so a node named only through `accessibleLabel` is findable by the\nvery name the results, chips and popover display for it. Presettable (e.g. to restore a query\nfrom a URL on load) as well as self-managed on every keystroke in the toolbar's search box.\n`''` (the default) renders no search-result list at all and applies no search dimming.\nRemoving the attribute uses this empty-filter behavior while retaining null property\nreadback.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"selected-node-id","description":"The currently-selected node id, driving both the details popover and `lr-graph`'s\n`selectedNodeIds` visual state. Presettable (e.g. to deep-link to a specific entity) as well\nas self-managed on every selection interaction. `null` (the default) shows no selection and\nkeeps the details popover closed.\n\nType: `string | null`  \nDefault: `null`"},{"name":"width","description":"Requested width of the composed graph viewport in CSS pixels. Ignored by the composed graph\nwhile `fitTo === 'container'`.\n\nType: `number`  \nDefault: `800`","value":{"type":["number"]}}],"slots":[{"name":"detail-actions","description":"Additive content appended into the default `lr-entity-card`'s `actions` slot, beside its built-in pin toggle. No effect while `details` is overridden."},{"name":"detail-body","description":"Additive content appended inside the default `lr-entity-card`'s body, alongside its `lr-neighbor-list`. No effect while `details` is overridden."},{"name":"details","description":"Overrides the details popover's default content (an `lr-entity-card` with a nested `lr-neighbor-list` and a pin toggle). Receives no data -- a consumer overriding this slot reads the selected entity from `selectedNodeId`/`nodes` itself. Replaces the default card entirely, including `detail-body`/`detail-actions` below."}],"js":{"properties":[{"name":"communities","description":"Community hull definitions forwarded to the graph.","type":"readonly LyraGraphCommunity[]","default":"[]"},{"name":"entityDetails","description":"Extra dossier fields, keyed by node id -- see `LyraKnowledgeGraphEntityDetails`.","type":"Readonly<\n    Record<string, Readonly<LyraKnowledgeGraphEntityDetails>>\n  >","default":"{}"},{"name":"fitTo","description":"Forwarded to `lr-graph.fitTo`. `'container'` makes the composed graph draw at exactly the\npane this component's own layout gave it -- the reservation minus whatever the toolbar,\nsearch results, pinned row and path strip take, which is not derivable from `height` -- and\nfollow it live as the explorer is resized. `'none'` (the default) keeps forwarding the\nnumeric `width`/`height` below unchanged.\n\nAttribute: `fit-to`","type":"LyraGraphFit","default":"'none'"},{"name":"height","description":"Requested height of the composed graph viewport in CSS pixels. Also sizes the rendered\n`[part=\"graph\"]`/host (see `--lr-canvas-reserved-height`'s doc) whenever neither that nor an\nexplicit outer `block-size` overrides it.\n\nAttribute: `height`","type":"number","default":"600"},{"name":"hiddenTypes","description":"Currently-hidden `LyraGraphNode.type` values, forwarded to both `lr-graph.hiddenTypes` and\n`lr-graph-legend.hiddenTypes`. Self-toggled by the composed legend; still presettable.","type":"readonly string[]","default":"[]"},{"name":"highlight","description":"What drives this component's own `dimmedNodeIds`/`dimmedLinkIds` forwarding, on top of the\nalways-active search-match dimming -- see the class doc's dedicated paragraph.\n\nAttribute: `highlight`","type":"KnowledgeGraphHighlight","default":"'selection'"},{"name":"label","description":"Fallback name for the root group; defaults to localized `graphExplorerLabel`. A non-empty\nhost `aria-label` makes the host the sole overall owner; an explicitly empty host label stays\nempty on the group, and so does an explicitly empty `label`.\n\nAttribute: `label`","type":"string | undefined"},{"name":"links","description":"Links forwarded to the composed graph and path interactions.","type":"readonly LyraGraphLink[]","default":"[]"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"nodeLabels","description":"Forwarded to `lr-graph.nodeLabels`. Unset (the default) leaves the composed `lr-graph` to\napply its own per-renderer default -- see that property's own doc.\n\nAttribute: `node-labels`","type":"LyraGraphNodeLabelsMode | undefined"},{"name":"nodeTypes","description":"Labels, colors, and shapes for the graph's node-type vocabulary.","type":"readonly LyraNodeTypeStyle[]","default":"[]"},{"name":"nodes","description":"Nodes forwarded to the composed graph and search experience.","type":"readonly LyraGraphNode[]","default":"[]"},{"name":"path","description":"Host-supplied path-finding result, rendered via `lr-path-strip`. Empty (the default) renders\nno path strip. See `lr-path-request`.","type":"readonly LyraPathElement[]","default":"[]"},{"name":"pinnedNodeIds","description":"Currently-pinned node ids. Self-toggled by the pin action in the details popover and by a\npinned chip's remove button (see the class doc's \"controlled vs. self-managed\" note); still\npresettable/overridable like any other property. Exactly two pinned nodes reveals the \"Find\npath\" action.","type":"readonly string[]","default":"[]"},{"name":"renderer","description":"Forwarded to `lr-graph.renderer`. `renderer=\"canvas\"` has no per-node DOM element, which\nnarrows how the node-detail popover anchors and disables its pan/zoom tracking -- see the\nclass doc's anchoring note.\n\nAttribute: `renderer`","type":"LyraGraphRenderer","default":"'svg'"},{"name":"searchQuery","description":"The search filter applied to the visible node set. A node matches when the query appears in\nany name it can be known by -- its `id`, its `label` or its `accessibleLabel` -- each folded\nwith the active locale, so a node named only through `accessibleLabel` is findable by the\nvery name the results, chips and popover display for it. Presettable (e.g. to restore a query\nfrom a URL on load) as well as self-managed on every keystroke in the toolbar's search box.\n`''` (the default) renders no search-result list at all and applies no search dimming.\nRemoving the attribute uses this empty-filter behavior while retaining null property\nreadback.\n\nAttribute: `search-query`","type":"string","default":"''"},{"name":"selectedNodeId","description":"The currently-selected node id, driving both the details popover and `lr-graph`'s\n`selectedNodeIds` visual state. Presettable (e.g. to deep-link to a specific entity) as well\nas self-managed on every selection interaction. `null` (the default) shows no selection and\nkeeps the details popover closed.\n\nAttribute: `selected-node-id`","type":"string | null","default":"null"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"width","description":"Requested width of the composed graph viewport in CSS pixels. Ignored by the composed graph\nwhile `fitTo === 'container'`.\n\nAttribute: `width`","type":"number","default":"800"}],"events":[{"name":"lr-community-click","description":"Bubbles straight through from the composed `lr-graph`, unmodified.","type":"CustomEvent<{ communityId: string }>"},{"name":"lr-hidden-types-change","description":"A node type's visibility changed via the composed legend. `detail: { hiddenTypes }`. See the class doc above. Direct host assignments do not emit.","type":"CustomEvent<\n    LyraEventDetailSnapshot<{ hiddenTypes: string[] }>\n  >"},{"name":"lr-link-click","description":"Bubbles straight through from the composed `lr-graph`, unmodified.","type":"CustomEvent<{\n    sourceNodeId: string;\n    targetNodeId: string;\n    linkId?: string;\n  }>"},{"name":"lr-node-click","description":"Bubbles straight through from the composed `lr-graph`, unmodified.","type":"CustomEvent<{ nodeId: string; x: number; y: number }>"},{"name":"lr-node-expand","description":"Bubbles straight through from `lr-graph` and/or `lr-neighbor-list` (the same event name/detail shape from either source) -- this component never appends neighbors itself, only forwards the request; a host fetches/generates the expansion and assigns updated `nodes`/`links` back.","type":"CustomEvent<{ nodeId: string }>"},{"name":"lr-path-request","description":"`detail: { sourceNodeId, targetNodeId }`. See the class doc above.","type":"CustomEvent<{\n    sourceNodeId: string;\n    targetNodeId: string;\n  }>"},{"name":"lr-pin-change","description":"`detail: { pinnedNodeIds }`. See the class doc above.","type":"CustomEvent<\n    LyraEventDetailSnapshot<{ pinnedNodeIds: string[] }>\n  >"},{"name":"lr-relation-activate","description":"Bubbles straight through from the composed `lr-path-strip`, unmodified.","type":"CustomEvent<{\n    relation: string;\n    sourceNodeId?: string;\n    targetNodeId?: string;\n    occurrenceIndex: number;\n  }>"},{"name":"lr-search-change","description":"The user typed in the toolbar's search box. `detail: { query, matchCount, matchCountExact }`. `query` is the canonical `LyraSearchChangeDetail` name; `matchCountExact` is always `true` since this component's node filter has no truncating ceiling. No `activeIndex` -- this is a live node filter, not a cursor-based search. Direct host assignments do not emit.","type":"CustomEvent<{\n    query: string;\n    matchCount: number;\n    matchCountExact: boolean;\n  }>"},{"name":"lr-selection-change","description":"The explorer changed its self-managed selection. `detail: { selectedNodeId: string | null }`. Direct host assignments do not emit.","type":"CustomEvent<{ selectedNodeId: string | null }>"}]}},{"name":"lr-known-date","description":"`<lr-known-date>` — a date a user already knows (a birthdate, a passport\nissue/expiry date) collected as three plain, labeled day/month/year number\nfields in the locale's natural field order, rather than a calendar popup.\nForm-associated; the submitted form value is always canonical ISO 8601\n(`YYYY-MM-DD`), or `''` while any field is blank or the combination isn't a\nreal calendar date. Mirrors Web Awesome's `wa-known-date` API surface under\n`lr-`. `appearance` and `pill` mirror its field treatments, while `size` uses this library's\nshared `2xs`–`xl` ladder and also accepts the upstream `small`/`medium`/`large` spellings — the\nsame ladder every other Lyra form control sits on. The shared `FormAssociated` surface supplies\nthe upstream `form` owner contract.\n\nA field's own `<input>` shows exactly what was typed (never reformatted or\nreverted) -- only the composite `value` is zero-padded. Auto-advance\n(typing a field's last digit moves focus to the next field) and\nbackspace-to-previous-field-when-empty are this library's own additions on\ntop of Web Awesome's bare typing model, which documents no auto-advance;\ndon't remove them to \"restore\" WA parity. Arrow-key field-to-field\nnavigation at a field's text boundary is RTL-aware: the *physical* key that\nmeans \"toward the next field\" flips under an inherited `dir=\"rtl\"`, while\nthe field order itself (locale-derived) does not. Locale digits such as\nArabic-Indic and Persian numerals are accepted and normalized to the\ncanonical ASCII digits used by the ISO form value.\n\nPressing Enter in any of the three fields performs the implicit form submission a native\n`<input>` would (see `internal/submit-on-enter.ts` — the fields live in a shadow root and have no\nform owner, so the platform can never do it here), flushing any pending `change` first.\n\nNo resizable text-editing surface exists (three fixed-width digit fields),\nso resize forwarding doesn't apply, and `spellcheck`/`autocapitalize`/\n`autocorrect`/`wrap` don't meaningfully apply to 2–4-digit numeric fields\neither -- the same carve-out `lr-input[type=\"number\"]` already documents.\nVisible validation-message changes are appended to a pre-mounted light-DOM assertive live\nregion. Hidden, inert, CSS-hidden, and `aria-hidden` slotted error content is excluded from the\nannouncement text, and no error is announced while the control or a composed ancestor is\nhidden. Initial and reconnected validation state remains silent.\n\nHost `aria-describedby` resolves external guidance onto the aggregate date fieldset;\neach native field retains its local hint/error guidance. Removed label/hint attributes\nrender as absent. Disabled native fields retain their resting border on hover or press.\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 part `label`: Deprecated since `8.0.0`. Use part `::part(form-control-label)`. Removal is not permitted before `10.0.0`. The form-control-label part matches the shared form-control vocabulary; label remains on that same node during the compatibility window. That version is a policy floor, not a plan: `wa-known-date` still publishes its own deprecated `label` part, so this alias is removed only when upstream's is.\n\n---\n\n**Slots**\n\n| Name | Description |\n| --- | --- |\n| `error` | Custom error content, alongside the `errorText` attribute. |\n| `hint` | Custom hint content, alongside the `hint` attribute. |\n| `label` | Custom label/legend content, alongside the `label` attribute. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | Compatibility name for the outer wrapper; use `known-date`. |\n| `error` | The validation message. |\n| `field` | Each field block (label + input), repeated three times; distinguished by `data-field=\"day\"\\|\"month\"\\|\"year\"`. |\n| `field-day` | Added to the day field block. |\n| `field-input` | The native per-field `<input type=\"text\" inputmode=\"numeric\">`, repeated three times; distinguished by `data-field=\"day\"\\|\"month\"\\|\"year\"`. |\n| `field-label` | The small visible per-field text label (\"Day\"/\"Month\"/\"Year\"). |\n| `field-month` | Added to the month field block. |\n| `field-year` | Added to the year field block. |\n| `fields` | The row wrapping the three field blocks. |\n| `fieldset` | The `<fieldset>` grouping the three fields. |\n| `form-control` | The outer wrapper. It is the same node as `base` and `known-date`. |\n| `form-control-input` | Alias on the fields row matching other form controls. |\n| `form-control-label` | The visible label wrapper inside the legend. |\n| `hint` | The hint message. |\n| `known-date` | The outer wrapper around legend, fieldset, hint, and error. It is the same node as `base` and `form-control`. |\n| `label` | Deprecated in 8.0.0; compatibility alias for `form-control-label`. Web Awesome still publishes its own deprecated `label` part on `<wa-known-date>`, so this alias stays on the same node until upstream drops it. |\n| `legend` | The `<legend>` element. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-known-date-field-padding-block` (default: `var(--lr-form-control-padding-block)`) — Block padding of each `field-input`; its private default follows `size` through the shared ladder.\n- `--lr-known-date-field-padding-inline` (default: `var(--lr-form-control-padding-inline)`) — Inline padding of each `field-input`; its private default follows `size` through the shared ladder.\n- `--lr-known-date-field-font-size` (default: `var(--lr-form-control-font-size)`) — Font size of each `field-input`; its private default follows `size` through the shared ladder.\n- `--lr-known-date-field-min-height` (default: `max(var(--lr-form-control-height),var(--lr-size-24px))`) — Minimum block size of each `field-input`; its private default follows `size` (`2xs`/`xs`→`24px`, `s`→`1.875rem`, `m`→`2.5rem`, `l`→`3rem`, `xl`→`3.5rem`) -- the same shared control-height ladder `lr-input`/`lr-date-input` sit on, so a birthdate field in a form row beside those controls renders at the same height. The `max()` floors the two smallest tiers at WCAG 2.2 SC 2.5.8's 24px pointer-target minimum. At the small tiers the floor exceeds the field's own content height and actively pins the rendered box; at `l`/`xl` the content height stays under it, so those two tiers are unaffected. An inherited or direct public value wins in every tier.\n- `--lr-known-date-field-height` — Exact block size of each `field-input`. Undeclared by default, so the field grows to fit its content, floored by `--lr-known-date-field-min-height`. Set it to pin a fixed height.\n- `--lr-known-date-field-gap` (default: `var(--lr-space-s)`) — Gap between the three field blocks.\n- `--lr-known-date-day-field-width` (default: `var(--lr-size-3-5em)`) — Inline size of the day field.\n- `--lr-known-date-month-field-width` (default: `var(--lr-size-3-5em)`) — Inline size of the month field.\n- `--lr-known-date-year-field-width` (default: `var(--lr-size-5em)`) — Inline size of the year field.\n- `--lr-known-date-invalid-border-color` (default: `var(--lr-color-danger)`) — Border color of each `field-input` while `:host([data-invalid])` is set.\n- `--lr-form-control-required-content` (default: `' *'`) — The required-field marker, rendered after the `legend` box. Set it to `''` to suppress the marker, or to any other quoted string (`' (required)'`, a localized word) to replace it. Caller-supplied content, so it is never localized here.\n- `--lr-form-control-required-color` (default: `var(--lr-color-danger)`) — Color of that marker, retunable without touching any other danger-coloured surface.\n- `--lr-form-control-required-offset` (default: `0`) — Inline space between the label text and the marker.","attributes":[{"name":"appearance","description":"The field fill treatment.\n\nType: `LyraKnownDateAppearance`  \nDefault: `'outlined'`","value":{"type":["'filled'","'outlined'","'filled-outlined'"]}},{"name":"aria-label","description":"Overrides the fieldset's computed accessible name (normally the `<legend>`'s content). Applied\nas `aria-label` on the `part=\"fieldset\"` element, which owns the role -- not just the host.\n\nType: `string | null`  \nDefault: `null`"},{"name":"autocomplete","description":"Browser autofill family. `'bday'` expands into the three field-specific birthday tokens;\n`'on'`/`'off'` apply to every field, and any other non-empty token is forwarded only to the\nyear field, matching the mirrored control.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"custom-error","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nType: `string | null`  \nDefault: `null`"},{"name":"day-label","description":"Visible + accessible day label. Omission or attribute removal localizes the default; supplied empty text stays empty.\n\nType: `string | undefined`"},{"name":"disabled","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"error-text","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"form","description":"Type: `HTMLFormElement | string | null`  \nDefault: `null`"},{"name":"hint","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"label","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"BCP-47 override for field order and field-label localization sampling. Empty string falls\nback to `this.effectiveLocale` (inherited `lang`/ancestor), exactly like `lr-date-input`'s\n`locale`. Redeclared (non-reflecting) over `LyraElement`'s own reflecting `locale` for the\nsame reason `lr-date-input` does.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"min","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"month-label","description":"Visible + accessible month label. Omission or attribute removal localizes the default; supplied empty text stays empty.\n\nType: `string | undefined`"},{"name":"name","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"pill","description":"Draws each field with fully rounded corners.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"readonly","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"required","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"size","description":"Control density, on the library's shared six-step ladder — `'m'` by default. Scales each\nfield's height floor, padding, font size and corner radius together, so a birthdate field\nlines up with the `lr-input`/`lr-date-input` beside it at the same declared size.\n`'small'`/`'medium'`/`'large'` are accepted as synonyms of `'s'`/`'m'`/`'l'`. Every tier\nresolves to at least the 24px pointer-target floor, so even `'2xs'` stays usable.\n\nType: `LyraSize`  \nDefault: `'m'`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}},{"name":"value","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"with-hint","description":"SSR slot-presence hint for slotted hint content. Runtime slot detection remains automatic.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"with-label","description":"SSR slot-presence hint for a slotted label. Runtime slot detection remains automatic.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"year-label","description":"Visible + accessible year label. Omission or attribute removal localizes the default; supplied empty text stays empty.\n\nType: `string | undefined`"}],"slots":[{"name":"error","description":"Custom error content, alongside the `errorText` attribute."},{"name":"hint","description":"Custom hint content, alongside the `hint` attribute."},{"name":"label","description":"Custom label/legend content, alongside the `label` attribute."}],"js":{"properties":[{"name":"accessibleLabel","description":"Overrides the fieldset's computed accessible name (normally the `<legend>`'s content). Applied\nas `aria-label` on the `part=\"fieldset\"` element, which owns the role -- not just the host.\n\nAttribute: `aria-label`","type":"string | null","default":"null"},{"name":"appearance","description":"The field fill treatment.\n\nAttribute: `appearance`  \nReflected to its attribute.","type":"LyraKnownDateAppearance","default":"'outlined'"},{"name":"autocomplete","description":"Browser autofill family. `'bday'` expands into the three field-specific birthday tokens;\n`'on'`/`'off'` apply to every field, and any other non-empty token is forwarded only to the\nyear field, matching the mirrored control.\n\nAttribute: `autocomplete`","type":"string","default":"''"},{"name":"customError","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nAttribute: `custom-error`  \nReflected to its attribute.","type":"string | null","default":"null"},{"name":"dayLabel","description":"Visible + accessible day label. Omission or attribute removal localizes the default; supplied empty text stays empty.\n\nAttribute: `day-label`","type":"string | undefined"},{"name":"defaultValue","description":"Attribute: `value`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"disabled","description":"Attribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"errorText","description":"Attribute: `error-text`","type":"string","default":"''"},{"name":"form","description":"Attribute: `form`  \nReflected to its attribute.","type":"HTMLFormElement | string | null","default":"null"},{"name":"hint","description":"Attribute: `hint`","type":"string","default":"''"},{"name":"label","description":"Attribute: `label`","type":"string","default":"''"},{"name":"labels","type":"NodeList","read-only":true},{"name":"locale","description":"BCP-47 override for field order and field-label localization sampling. Empty string falls\nback to `this.effectiveLocale` (inherited `lang`/ancestor), exactly like `lr-date-input`'s\n`locale`. Redeclared (non-reflecting) over `LyraElement`'s own reflecting `locale` for the\nsame reason `lr-date-input` does.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"max","description":"Attribute: `max`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"min","description":"Attribute: `min`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"monthLabel","description":"Visible + accessible month label. Omission or attribute removal localizes the default; supplied empty text stays empty.\n\nAttribute: `month-label`","type":"string | undefined"},{"name":"name","description":"Attribute: `name`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"parts","description":"The three raw day/month/year field strings. Assigning a complete valid set updates `value`.","type":"LyraKnownDateParts","default":"{ ...EMPTY_PARTS }"},{"name":"pill","description":"Draws each field with fully rounded corners.\n\nAttribute: `pill`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"readonly","description":"Attribute: `readonly`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"required","description":"Attribute: `required`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"size","description":"Control density, on the library's shared six-step ladder — `'m'` by default. Scales each\nfield's height floor, padding, font size and corner radius together, so a birthdate field\nlines up with the `lr-input`/`lr-date-input` beside it at the same declared size.\n`'small'`/`'medium'`/`'large'` are accepted as synonyms of `'s'`/`'m'`/`'l'`. Every tier\nresolves to at least the 24px pointer-target floor, so even `'2xs'` stays usable.\n\nAttribute: `size`  \nReflected to its attribute.","type":"LyraSize","default":"'m'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"validationMessage","type":"string","read-only":true},{"name":"validationTarget","description":"The browser validation bubble's focus anchor -- the first visible day/month/year field in\nlocale order by default, never the hidden native `type=\"date\"` mirror (`valueInput`), which\nsits first in DOM order but must never receive focus or a validation popup.","type":"HTMLElement | undefined"},{"name":"validity","type":"ValidityState","read-only":true},{"name":"value","description":"Normalizes an assignment to the canonical ISO date or `''`, and repopulates the three raw\nfield texts to match -- a declarative `value=\"2007-3-27\"` (non-padded) or a calendar-invalid\nliteral (`\"2007-02-30\"`) sanitizes to `''`, same strict-ISO gate as `lr-date-input`'s\n`parseStrictISO()`. Programmatic assignment stays silent (no `input`/`change`), matching every\n`FormAssociated` sibling's documented contract.","type":"string"},{"name":"valueAsDate","description":"The composite value as a local-midnight `Date`, or `null` while incomplete/invalid.","type":"Date | null"},{"name":"valueInput","description":"Hidden native date mirror used by integrations that inspect native constraints directly.\nStays a writable `@query` field rather than a readonly `get`: `wa-known-date` declares it\nwritable, and check-pinned-upstream-manifests treats a readonly-vs-writable difference on a\nmirrored member as an `unsupported` surface drift -- a release blocker.","type":"HTMLInputElement"},{"name":"willValidate","type":"boolean","read-only":true},{"name":"withHint","description":"SSR slot-presence hint for slotted hint content. Runtime slot detection remains automatic.\n\nAttribute: `with-hint`","type":"boolean","default":"false"},{"name":"withLabel","description":"SSR slot-presence hint for a slotted label. Runtime slot detection remains automatic.\n\nAttribute: `with-label`","type":"boolean","default":"false"},{"name":"yearLabel","description":"Visible + accessible year label. Omission or attribute removal localizes the default; supplied empty text stays empty.\n\nAttribute: `year-label`","type":"string | undefined"}],"events":[{"name":"blur","description":"Re-dispatched, bubbling and composed, once when focus leaves all three internal fields for something outside the control -- not once per internal field-to-field Tab.","type":"CustomEvent<null>"},{"name":"change","description":"A bubbling, composed native change event fired when a field loses focus (including a Tab/auto-advance move away from it) and the composite value has newly transitioned to a different complete date, or from complete back to incomplete/blank. Programmatic `value`/`valueAsDate` assignment stays silent.","type":"Event & { readonly detail: LyraKnownDateEventDetail }"},{"name":"focus","description":"Re-dispatched, bubbling and composed, when any of the three internal fields receives focus (native `focus` doesn't bubble or cross a shadow boundary).","type":"CustomEvent<null>"},{"name":"input","description":"A bubbling, composed native input event fired on every keystroke in any field, retaining the originating edit's `inputType`. Its compatibility `detail.value` is the canonical ISO date only once all three fields resolve to a real calendar date, otherwise `''`; `detail.day`/ `month`/`year` always carry the live raw typed text.","type":"InputEvent & { readonly detail: LyraKnownDateEventDetail }"},{"name":"lr-invalid","description":"The composite date failed a validity check; cancelable. Calling `preventDefault()` also cancels the native `invalid` event it aliases, suppressing the browser's own validation bubble and `reportValidity()`'s focus/scroll.","type":"CustomEvent<null>"}]}},{"name":"lr-lightbox","description":"`<lr-lightbox>` — a full-screen, modal, click-to-enlarge image viewer with prev/next\nnavigation across an ordered set of images. It has no Web Awesome/Shoelace counterpart, so\nits API follows this library's own conventions.\n\n**Not a form-associated control** -- no `label`/`hint`/`errorText` chrome; its\n`accessibleLabel` only overrides the dialog's own accessible name. The native-wrapper/\nediting-assistance-passthrough guarantees don't apply either (no internal `<input>`/\n`<textarea>`).\n\nThis renders its own dialog panel rather than nesting a `<lr-dialog>` in its shadow\ntemplate -- shared overlay infrastructure (`src/internal/overlay-manager.ts`) coordinates\nstacking, focus trapping, Escape/backdrop dismissal, scroll lock, and focus return with every\nother overlay in the same document, the same way `<lr-dialog>`/`<lr-command-palette>`/\n`<lr-widget>` (fullscreen mode)/`<lr-app-rail>` (mobile mode)/`<lr-responsive-panel>`\nalready do. Per-image pan/zoom is delegated to one stable embedded `<lr-pan-zoom>`\ninstance (its `src`/`alt` swapped per navigation) rather than reimplementing pan/zoom --\ncomposing a small sibling leaf component directly in the render template, the same way\n`<lr-tool-select-dialog>` composes `<lr-checkbox>`/`<lr-switch>`.\n\nZoom/pan reset on navigation is imperative (`LyraPanZoom.resetView()`, called from\n`updated()`) rather than a Lit property binding -- a binding whose value never changes across\nrenders (e.g. `.zoom=${1}`) would only apply once, silently failing to reset on the *second*\nnavigation once the user has interactively zoomed. Recreating the frame element on every\nnavigation (e.g. via Lit's `keyed()` directive) was considered and rejected: it would also\nreset zoom/pan, but destroying/recreating the element would steal focus from a keyboard user\nwho had Tabbed into the frame's viewport mid-navigation.\n\nLifecycle: `show()` emits cancelable `lr-show` before committing `open=true`, followed by\n`lr-after-show` after the open panel renders. `hide()`/`close()` and post-render writes to\n`open=false` emit cancelable `lr-hide`, then cancelable `lr-lightbox-close`, followed by\n`lr-after-hide` after the closed state renders. A veto leaves the property and reflected\nattribute synchronized. Initial `open` markup is state rather than a transition and emits no\nlifecycle events.\n\n**Scope for v1 (deliberate, not oversights):** no default slot / no arbitrary slotted content\nper image (data-driven via `images` only); no dot-style indicators (a textual counter scales\nbetter to photo-set sizes); no visual open/close animation (`show()`/`hide()` still expose the\nshared before/after lifecycle contract); no\nclick-on-image-to-navigate (the image is already meaningfully interactive -- it focuses the\nzoomable frame's viewport and drives its native scroll-to-pan); no touch-swipe-to-navigate.\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| `actions` | Optional extra toolbar buttons (e.g. download/share/delete), rendered in `part=\"toolbar\"` between the counter and the close button. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `actions` | Wrapper around the `actions` slot; `hidden` when nothing is slotted. |\n| `backdrop` | The full-viewport scrim, positioned behind `panel`. |\n| `caption` | The current image's caption text. Only rendered when the current image's `caption` is non-empty. Its `id` is the `aria-describedby` target on `panel`. |\n| `close-button` | The close button. Always rendered -- unlike `<lr-dialog>`'s opt-in `closable`, a full-screen lightbox has no other built-in chrome, so this is not optional. |\n| `counter` | Visible, localized \"Image N of Total\" text. Omitted entirely when `showCounter` is `false`. |\n| `frame` | The embedded `<lr-pan-zoom>` element itself. |\n| `frame-content` | The embedded pan-zoom's transformed content wrapper. |\n| `frame-controls` | The embedded pan-zoom's zoom controls. |\n| `frame-viewport` | The embedded pan-zoom's scrollable viewport. |\n| `live-region` | Visually-hidden, `aria-hidden` mirror of the current position. On every `index` change while open, the spoken copy is appended to the shared light-DOM polite sink, regardless of trigger (button, keyboard, or a consumer setting `index`/`images` directly), unless the lightbox or a composed ancestor is excluded from the accessibility tree. The mirror is decoupled from the visible `counter` so an unrelated re-render never causes a spurious re-announcement. |\n| `next-button` | Symmetric to `previous-button`. |\n| `next-glyph` | Symmetric to `previous-glyph`. |\n| `panel` | `role=\"dialog\"` while open, `aria-modal=\"true\"`, `tabindex=\"-1\"`. Fills the padded safe area -- unlike `<lr-dialog>`, it does not shrink-wrap to content, since maximizing image real estate is the point. |\n| `previous-button` | Floating, absolutely positioned inside `stage`. Rendered only when `images.length > 1`. |\n| `previous-glyph` | The `chevronIcon()` inside `previous-button`, mirrored under RTL. |\n| `stage` | Houses the embedded `<lr-pan-zoom>` plus the floating `previous-button`/`next-button`. |\n| `toolbar` | Top row: `counter` (start), the `actions` slot wrapper, `close-button` (end). |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-lightbox-control-bg` — Background for every floating/toolbar icon button.\n- `--lr-lightbox-control-color` — Icon/text color paired with `--lr-lightbox-control-bg`.\n- `--lr-lightbox-overlay-color` — The backdrop scrim color.","attributes":[{"name":"aria-label","description":"Host-level `aria-label` override for the panel's accessible name -- wins over the\nlocalized `lightboxLabel` default. Exactly `<lr-pan-zoom>`'s own `accessibleLabel`\npattern (no other label source to arbitrate against here).\n\nType: `string | null`  \nDefault: `null`"},{"name":"fit","description":"Base image sizing policy, using the same vocabulary as `<lr-image-viewer>`. `actual`\npreserves the current natural-size behavior; `contain` fits the complete image inside the\navailable stage and `width` fills its inline size. Fit recalculates from layout when the\nstage allocation changes. Explicit user zoom remains in effect until navigation or a reset.\n\nType: `LyraImageFit`","value":{"type":["'contain'","'width'","'actual'"]}},{"name":"index","description":"The currently displayed image. Clamped defensively for rendering (out-of-range/negative/\nnon-integer never throws) and silently re-synced onto this property (no event) when\n`images` shrinks -- mirrors `<lr-carousel>`'s `normalizedIndex()`/`syncSlides()` split.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"light-dismiss","description":"Dismisses the lightbox on a backdrop click. Opt-in and `false` by default -- mirrors\n`<lr-dialog>`'s `lightDismiss` exactly (name, default, no reflect), which in turn matches\n`wa-dialog`.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"loop","description":"Wraps prev/next past the ends. Mirrors `<lr-carousel>`'s `loop` 1:1.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"max-zoom","description":"Passed through to the embedded `<lr-pan-zoom>` as `.maxZoom`.\n\nType: `number`  \nDefault: `4`","value":{"type":["number"]}},{"name":"min-zoom","description":"Passed through to the embedded `<lr-pan-zoom>` as `.minZoom`. Same default as\n`<lr-pan-zoom>` itself.\n\nType: `number`  \nDefault: `0.5`","value":{"type":["number"]}},{"name":"open","description":"Whether the lightbox is open. Post-render writes run the same cancelable lifecycle as\n`show()`/`hide()`/`close()`; initial markup is state and emits nothing.\n\nType: `boolean`","value":{"type":["boolean"]}},{"name":"show-counter","description":"Shows/hides only the visible `part=\"counter\"`. The accessibility `part=\"live-region\"`\nannouncement remains active so navigation is still conveyed when visual chrome is hidden.\nMirrors `<lr-carousel>`'s `showIndicators` (name shape, no reflect). Uses the shared\nparse-only `trueDefaultBooleanConverter` rather than Lit's default presence-based\n`type: Boolean` handling, so a plain-HTML consumer with no way to write a `.showCounter`\nproperty binding can still turn this off with `show-counter=\"false\"`. Deliberately not\nreflected: nothing styles or queries `[show-counter]`, so the serializing half of a\nreflecting converter would be dead code on a modal that already churns attributes.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"zoom-step","description":"Passed through to the embedded `<lr-pan-zoom>` as `.zoomStep`.\n\nType: `number`  \nDefault: `0.25`","value":{"type":["number"]}}],"slots":[{"name":"actions","description":"Optional extra toolbar buttons (e.g. download/share/delete), rendered in `part=\"toolbar\"` between the counter and the close button."}],"js":{"properties":[{"name":"accessibleLabel","description":"Host-level `aria-label` override for the panel's accessible name -- wins over the\nlocalized `lightboxLabel` default. Exactly `<lr-pan-zoom>`'s own `accessibleLabel`\npattern (no other label source to arbitrate against here).\n\nAttribute: `aria-label`","type":"string | null","default":"null"},{"name":"fit","description":"Base image sizing policy, using the same vocabulary as `<lr-image-viewer>`. `actual`\npreserves the current natural-size behavior; `contain` fits the complete image inside the\navailable stage and `width` fills its inline size. Fit recalculates from layout when the\nstage allocation changes. Explicit user zoom remains in effect until navigation or a reset.\n\nAttribute: `fit`  \nReflected to its attribute.","type":"LyraImageFit"},{"name":"goTo","description":"Jumps to a finite image index. Fractional values are truncated toward zero before\nclamping or loop wrapping, so `lr-index-change.detail.index` is always the rendered\ninteger index. Non-finite values are no-ops.","type":"(index: number) => void"},{"name":"images","description":"The ordered, bounded, immutable set of images being browsed. Assign a new collection to\nupdate it; malformed records are omitted and at most 10,000 candidates are inspected.","type":"readonly LyraLightboxImage[]"},{"name":"index","description":"The currently displayed image. Clamped defensively for rendering (out-of-range/negative/\nnon-integer never throws) and silently re-synced onto this property (no event) when\n`images` shrinks -- mirrors `<lr-carousel>`'s `normalizedIndex()`/`syncSlides()` split.\n\nAttribute: `index`  \nReflected to its attribute.","type":"number","default":"0"},{"name":"lightDismiss","description":"Dismisses the lightbox on a backdrop click. Opt-in and `false` by default -- mirrors\n`<lr-dialog>`'s `lightDismiss` exactly (name, default, no reflect), which in turn matches\n`wa-dialog`.\n\nAttribute: `light-dismiss`","type":"boolean","default":"false"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"loop","description":"Wraps prev/next past the ends. Mirrors `<lr-carousel>`'s `loop` 1:1.\n\nAttribute: `loop`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"maxZoom","description":"Passed through to the embedded `<lr-pan-zoom>` as `.maxZoom`.\n\nAttribute: `max-zoom`","type":"number","default":"4"},{"name":"minZoom","description":"Passed through to the embedded `<lr-pan-zoom>` as `.minZoom`. Same default as\n`<lr-pan-zoom>` itself.\n\nAttribute: `min-zoom`","type":"number","default":"0.5"},{"name":"next","description":"Advances to the next image, respecting `loop`.","type":"() => void"},{"name":"open","description":"Whether the lightbox is open. Post-render writes run the same cancelable lifecycle as\n`show()`/`hide()`/`close()`; initial markup is state and emits nothing.\n\nAttribute: `open`  \nReflected to its attribute.","type":"boolean"},{"name":"previous","description":"Moves to the previous image, respecting `loop`.","type":"() => void"},{"name":"showCounter","description":"Shows/hides only the visible `part=\"counter\"`. The accessibility `part=\"live-region\"`\nannouncement remains active so navigation is still conveyed when visual chrome is hidden.\nMirrors `<lr-carousel>`'s `showIndicators` (name shape, no reflect). Uses the shared\nparse-only `trueDefaultBooleanConverter` rather than Lit's default presence-based\n`type: Boolean` handling, so a plain-HTML consumer with no way to write a `.showCounter`\nproperty binding can still turn this off with `show-counter=\"false\"`. Deliberately not\nreflected: nothing styles or queries `[show-counter]`, so the serializing half of a\nreflecting converter would be dead code on a modal that already churns attributes.\n\nAttribute: `show-counter`","type":"boolean","default":"true"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"zoomStep","description":"Passed through to the embedded `<lr-pan-zoom>` as `.zoomStep`.\n\nAttribute: `zoom-step`","type":"number","default":"0.25"}],"events":[{"name":"lr-after-hide","description":"Fired after a successful `hide()`/`close()` has rendered closed.","type":"CustomEvent<null>"},{"name":"lr-after-show","description":"Fired after a successful `show()` has rendered the open panel.","type":"CustomEvent<null>"},{"name":"lr-hide","description":"Cancelable request fired before `lr-lightbox-close`; `detail: { source }`, where `source` is the close button, backdrop, panel (for Escape), or host (for API writes). On removal while already disconnected, the settled notification is non-cancelable because there is no connected state left for a listener to retain.","type":"CustomEvent<LyraLightboxHideDetail>"},{"name":"lr-index-change","description":"Fired for `next()`/`previous()`/`goTo()` navigation, including the built-in button and keyboard paths. Not fired when a consumer sets `index`/`images` directly. `detail: { index }` is always the rendered integer index.","type":"CustomEvent<{ index: number }>"},{"name":"lr-lightbox-close","description":"`detail: LyraLightboxCloseReason`. Cancelable -- a listener calling `preventDefault()` stops the lightbox from closing, for every dismissal path (Escape, backdrop, the built-in close button, or a consumer's own `close()` call). Fired whenever the lightbox is dismissed via Escape, a backdrop click, the built-in close button, a `close()` call, or (with reason `'unmount'`, not cancelable in practice since the element is already being removed) removal from the DOM by anything else while still open.","type":"CustomEvent<LyraLightboxCloseReason>"},{"name":"lr-show","description":"Cancelable request fired by `show()` before `open` changes.","type":"CustomEvent<null>"},{"name":"lr-zoom-change","description":"Not emitted by `LyraLightbox` itself -- see the interface doc above. `detail: { zoom }`.","type":"CustomEvent<{ zoom: number }>"}]}},{"name":"lr-line-chart","description":"`<lr-line-chart>` — `<lr-chart>` with a `\"line\"` default and the mirrored writable type.\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) | An optional `<script type=\"application/json\">` containing a Chart.js configuration. |\n| `center` | Optional overlay content positioned at the chart area's center. Useful for doughnut and pie totals. |\n| `data-table` | An optional consumer-provided accessible table alternative. Use this escape hatch for a complete paginated or virtualized alternative when the generated 1,000-record sample is insufficient. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The chart wrapper. |\n| `canvas` | The Chart.js canvas. |\n| `center` | The chart-area-centered overlay wrapper for the `center` slot. |\n| `data-table` | The optional generated or slotted data table. |\n| `data-table-toggle` | The disclosure button rendered by `dataTableToggle`. |\n| `data-truncation` | Explanation shown when the generated accessible alternative samples a data set larger than its 1,000-record ceiling. |\n| `description` | The accessible chart summary. |\n| `error` | Static visible error shown instead of `canvas` when the optional `chart.js` peer dependency is not installed; its transition is announced through a shared light-DOM alert. |\n| `feature-warning` | Static nonfatal warning when a requested optional feature peer is unavailable while the core chart remains usable. |\n| `legend` | The wrapping DOM legend, rendered unless `withoutLegend` is set. |\n| `legend-item` | A keyboard-operable dataset or category visibility toggle. |\n| `legend-item-hidden` | Added while the legend item's dataset or category is hidden. |\n| `legend-swatch` | The resolved dataset/category color swatch in a legend item. |\n| `notices` | Wrapper for nonfatal feature warnings and generated-data truncation notices. |\n| `plot` | The fixed-height canvas/overlay region. |\n| `reset-zoom-button` | The reset-zoom control when zoom is active. |\n\n---\n\n**CSS Custom Properties**\n\n- `--border-color-1` (default: `var(--lr-color-chart-1)`) — First dataset border color.\n- `--border-color-2` (default: `var(--lr-color-chart-2)`) — Second dataset border color.\n- `--border-color-3` (default: `var(--lr-color-chart-3)`) — Third dataset border color.\n- `--border-color-4` (default: `var(--lr-color-chart-4)`) — Fourth dataset border color.\n- `--border-color-5` (default: `var(--lr-color-chart-5)`) — Fifth dataset border color.\n- `--border-color-6` (default: `var(--lr-color-chart-6)`) — Sixth dataset border color.\n- `--border-radius` (default: `var(--lr-radius)`) — Dataset element corner radius.\n- `--border-width` (default: `var(--lr-border-width-thin)`) — Dataset element border width.\n- `--fill-color-1` (default: `var(--lr-color-chart-1)`) — First dataset fill color.\n- `--fill-color-2` (default: `var(--lr-color-chart-2)`) — Second dataset fill color.\n- `--fill-color-3` (default: `var(--lr-color-chart-3)`) — Third dataset fill color.\n- `--fill-color-4` (default: `var(--lr-color-chart-4)`) — Fourth dataset fill color.\n- `--fill-color-5` (default: `var(--lr-color-chart-5)`) — Fifth dataset fill color.\n- `--fill-color-6` (default: `var(--lr-color-chart-6)`) — Sixth dataset fill color.\n- `--grid-border-width` (default: `var(--lr-border-width-thin)`) — Axis and grid line width.\n- `--grid-color` (default: `var(--lr-chart-grid-color)`) — Grid line color.\n- `--line-border-width` (default: `var(--lr-border-width-medium)`) — Line dataset stroke width.\n- `--lr-chart-canvas-hover-outline-color` (default: `var(--lr-chart-grid-color)`) — Color of the `[part='canvas']` hover-state outline.\n- `--lr-chart-canvas-hover-outline-width` (default: `var(--lr-border-width-thin)`) — Width of the `[part='canvas']` hover-state outline.\n- `--lr-chart-data-table-button-active-bg` — Pressed background of an actionable generated- table value; defaults to the standard active mix of `--lr-color-brand-quiet`.\n- `--lr-chart-data-table-button-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background of an actionable generated-table value.\n- `--lr-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-chart-data-table-toggle-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background of the `dataTableToggle` disclosure button.\n- `--lr-chart-grid-color` (default: `var(--lr-color-border)`) — Grid-line color. Resolved via `getComputedStyle` on every draw (Chart.js paints to canvas and cannot consume `var()`).\n- `--lr-chart-height` (default: `var(--lr-size-280px)`) — The plot region's `block-size` and the host's minimum block size. A visible data table or wrapping DOM legend grows the host in normal flow instead of overlapping following content. `height` supplies a private fallback; this public token always wins when a consumer sets it.\n- `--lr-chart-legend-color` (default: `var(--lr-color-text)`) — Legend label color. Resolved via `getComputedStyle` on every draw.\n- `--lr-chart-legend-item-active-bg` — Pressed background of a legend visibility button; defaults to the standard active mix of `--lr-color-brand-quiet`.\n- `--lr-chart-legend-item-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background of a legend visibility button.\n- `--lr-chart-legend-side-max` (default: `var(--lr-size-15rem)`) — Maximum inline size reserved for a side-positioned DOM legend; the track is also capped at one third of the chart allocation.\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 every series collapses to one system color and the stripe/crosshatch pattern 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.\n- `--lr-chart-reset-zoom-button-active-bg` — Pressed background of the reset-zoom button; defaults to the standard active mix of `--lr-color-brand-quiet`.\n- `--lr-chart-reset-zoom-button-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background of the reset-zoom button.\n- `--lr-chart-tick-color` (default: `var(--lr-color-text-quiet)`) — Axis tick-label color; also used for the `xLabel`/`yLabel`/`y2Label` axis-title text (there is no separate title-color token). Resolved via `getComputedStyle` on every draw.\n- `--lr-chart-tick-font-size` (default: `var(--lr-font-size-xs)`) — Axis tick-label font size, in any CSS length unit. Defaults to `--lr-font-size-xs` (12px at the standard root) because that matches Chart.js's OWN built-in tick font size, which is what every canvas chart rendered before this token existed -- leaving it unset must stay byte-identical to that, not shrink to `<lr-lite-chart>`'s SVG default. Also sizes the radar/polarArea `r`-scale `pointLabels` (the spoke labels), but ONLY once set: those default separately to Chart.js's OWN distinct `RadialLinearScale` `pointLabels` default (10px, not this token's 12px), and only adopt this token's size once the consumer explicitly sets it, at which point ticks and point labels match. Resolved via `getComputedStyle` on every draw, same constraint as every other `--lr-chart-*` token here (Chart.js paints to canvas and cannot consume `var()`).\n- `--lr-chart-tooltip-bg` (default: `var(--lr-color-surface)`) — Tooltip background color. Resolved via `getComputedStyle` on every draw.\n- `--lr-chart-tooltip-text` (default: `var(--lr-color-text)`) — Tooltip text color. Resolved via `getComputedStyle` on every draw.\n- `--point-radius` (default: `var(--lr-space-2xs)`) — Line/scatter point radius.","attributes":[{"name":"area","description":"Chart-wide default fill-under-line setting for line-type series; a series's own `LyraChartSeries.fill` overrides it.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"axes","description":"Complete cartesian axis visibility, independent of grid. `y` also controls the y2 axis.\nRadial charts ignore this setting. Explicit config scale options retain precedence.\n\nType: `LyraChartAxes`  \nDefault: `'both'`","value":{"type":["'x'","'y'","'both'","'none'"]}},{"name":"begin-at-zero","description":"Type: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"compact","description":"Compact cartesian plot: hide axes and remove automatic layout padding. Set height and\nwithoutLegend for a small histogram/sparkline. Preserves data tables, tooltips and keyboard\nactions; radial charts ignore this setting. Explicit config options retain precedence.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"data-labels","description":"Draws each data point's value on the chart via the optional\n`chartjs-plugin-datalabels` peer. Unset (the default) leaves labels off for\nthis chart; the peer is attached only to instances that opt in, and\n`buildConfig()` keeps its per-chart options disabled until this is set. The\nscreen-reader equivalent is the always-present data table (see\n`show-data-table`); labels are a purely visual, canvas-only addition.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"data-table-toggle","description":"Render a disclosure button above the accessible data table so a sighted reader can reveal the\nnumbers behind the chart on demand. `showDataTable` alone is all-or-nothing -- the table is\neither permanently screen-reader-only or permanently visible -- which left a consumer wrapping\na duplicated table in their own `<details>`.\n\nWith this set, `showDataTable` becomes the disclosure's *initial* state rather than its whole\nbehavior. The table stays in the DOM in both states, so assistive technology never loses it.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"description","description":"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`"},{"name":"grid","description":"Controls which cartesian grid axes are drawn.\n\nType: `LyraChartGrid`  \nDefault: `'both'`","value":{"type":["'x'","'y'","'both'","'none'"]}},{"name":"height","description":"Type: `string`  \nDefault: `'280px'`","value":{"type":["string"]}},{"name":"index-axis","description":"Chart.js index axis. `'y'` is Chart.js's own mechanism for horizontal bars (it also flips\nline/area types onto a horizontal category axis).\n\nType: `LyraChartIndexAxis`  \nDefault: `'x'`","value":{"type":["'x'","'y'"]}},{"name":"label","description":"Accessible chart label. A host `aria-label` still has highest precedence.\n\nType: `string | null`  \nDefault: `null`"},{"name":"legend-display","description":"`auto` retains optional legend formatting; `label` omits values even with a formatter; `value`\nappends a formatted value. `percentage` uses locale percentages of the absolute represented\nlegend values, including hidden items (zero totals yield 0%). `value-percentage` appends both,\nas `label: value (percentage)`. Dataset values are sampled sums; category values come from the\nfirst dataset. The `formatter`/`valueFormatter` callback backing `value` and `value-percentage`\nadditionally receives that same `percentage` in its `surface: 'legend'` context, so a custom\nformatter can build its own combined text without recomputing the share. Tooltip and axis\nformatting are unchanged.\n\nType: `LyraChartLegendDisplay`  \nDefault: `'auto'`","value":{"type":["'auto'","'label'","'value'","'percentage'","'value-percentage'"]}},{"name":"legend-mode","description":"`datum` renders category toggles for pie/doughnut/polar-area charts. Categories use the first\ndataset's colors and values; a toggle affects that category in every ring. Other chart types\nretain dataset legends. `auto` (the default) resolves to `datum` on pie/doughnut/polar-area\ncharts -- where a single-dataset legend would otherwise enumerate one entry for the whole\ndataset instead of one per visible slice -- and to `dataset` everywhere else. `dataset` always\nforces the dataset legend, even on a slice chart. Both non-`auto` modes use the generated\naccessible-data sampling budget.\n\nType: `LyraChartLegendMode`  \nDefault: `'auto'`","value":{"type":["'auto'","'dataset'","'datum'"]}},{"name":"legend-position","description":"Legend placement. `auto` uses a right legend above 480px and a bottom legend below it.\n\nType: `LyraChartLegendPosition`  \nDefault: `'top'`","value":{"type":["'left'","'top'","'right'","'bottom'","'center'","'chartArea'","'start'","'end'","'auto'"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max","description":"Maximum value-axis bound. Non-finite values are ignored.\n\nType: `number | null`  \nDefault: `null`"},{"name":"min","description":"Minimum value-axis bound. Non-finite values are ignored.\n\nType: `number | null`  \nDefault: `null`"},{"name":"plugins","description":"Chart.js plugins attached to this chart instance. Valid plugins retain their opaque identity.\n\nType: `readonly LyraChartPlugin[]`  \nDefault: `[]`"},{"name":"scale-type","description":"Scale type for the **value** axis (the categorical axis is unaffected). `'logarithmic'` plots\na dataset spanning several orders of magnitude honestly, where a linear axis collapses\neverything below the maximum into the baseline. Inherited by `lr-line-chart`,\n`lr-scatter-chart` and `lr-bar-chart`.\n\nA logarithmic axis cannot represent zero or negative values (`log(0)` is `-Infinity`), so\n`beginAtZero` is not forwarded in that mode -- Chart.js would otherwise be handed a bound it\ncannot place. Non-positive data points are dropped by Chart.js's own log scale.\n\nType: `LyraChartScaleType`  \nDefault: `'linear'`","value":{"type":["'linear'","'logarithmic'"]}},{"name":"show-data-table","description":"Makes the generated data table visible; it remains screen-reader available when false.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"stack-totals","description":"When the chart is `stacked` (bar/line only), draws the per-category stack\ntotal above each stack, via the same optional `chartjs-plugin-datalabels`\npeer as `data-labels`. Null/undefined points are skipped; a category whose\nevery value is null shows no total. The generated accessible data table\nreceives the same formatted total column (one per value axis). Unset (the\ndefault) draws and adds nothing.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"stacked","description":"Stacks the `x`/`y`(/`y2`) scale entries `buildScales()` returns; only meaningful for `bar` and `line` types.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"type","description":"Type: `LyraChartType`  \nDefault: `'line'`","value":{"type":["'line'","'bar'","'scatter'","'pie'","'doughnut'","'radar'","'polarArea'","'bubble'"]}},{"name":"without-animation","description":"Disables Chart.js animation.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"without-legend","description":"Hides the legend.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"without-tooltip","description":"Hides Chart.js tooltips.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"x-label","description":"Type: `string | null`  \nDefault: `null`"},{"name":"y-label","description":"Type: `string | null`  \nDefault: `null`"},{"name":"y2-label","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"zoom","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"","description":"An optional `<script type=\"application/json\">` containing a Chart.js configuration."},{"name":"center","description":"Optional overlay content positioned at the chart area's center. Useful for doughnut and pie totals."},{"name":"data-table","description":"An optional consumer-provided accessible table alternative. Use this escape hatch for a complete paginated or virtualized alternative when the generated 1,000-record sample is insufficient."}],"js":{"properties":[{"name":"annotations","description":"Declarative reference lines and shaded bands — a threshold, an event year, a regime change, a\nhighlighted period. Each entry marks either a single `value` or a `from`/`to` range on `axis`\n(default `'y'`), with an optional `label` and semantic `tone`.\n\nNeeds the optional `chartjs-plugin-annotation` peer, loaded on first actual demand so a page\nwith no annotated charts never downloads it. The plugin is registered globally, like\n`chartjs-plugin-zoom` and unlike `chartjs-plugin-datalabels`: it draws nothing unless a chart\nsupplies annotation options, so the registration is unobservable to charts that set none, and\nregistration is also what installs the plugin's own element defaults. Without the peer\ninstalled the chart still renders; a console warning plus a localized visible warning and\nlight-DOM announcement explain the no-op — the same fail-closed contract `data-labels` uses.\n\nEntries are included in the generated accessible description, mirroring `lr-heatmap`.","type":"readonly LyraChartAnnotation[]","default":"[]"},{"name":"area","description":"Chart-wide default fill-under-line setting for line-type series; a series's own `LyraChartSeries.fill` overrides it.\n\nAttribute: `area`","type":"boolean","default":"false"},{"name":"axes","description":"Complete cartesian axis visibility, independent of grid. `y` also controls the y2 axis.\nRadial charts ignore this setting. Explicit config scale options retain precedence.\n\nAttribute: `axes`","type":"LyraChartAxes","default":"'both'"},{"name":"beginAtZero","description":"Attribute: `begin-at-zero`","type":"boolean","default":"true"},{"name":"chart","description":"The current Chart.js instance. Read it only while the element is connected and loaded.","type":"LyraChartInstance | undefined"},{"name":"chartArea","description":"The current Chart.js chart-area geometry in canvas-local coordinates. Read-only -- derived\nfrom the live Chart.js instance's own layout pass, never assignable. The setter is a\ndocumented no-op (matching `lr-histogram`'s `labels`/`datasets` pattern) so an accidental\n`.chartArea=${x}` Lit template binding degrades silently instead of throwing from inside\nlit-html's property-commit.","type":"LyraChartArea | undefined"},{"name":"compact","description":"Compact cartesian plot: hide axes and remove automatic layout padding. Set height and\nwithoutLegend for a small histogram/sparkline. Preserves data tables, tooltips and keyboard\nactions; radial charts ignore this setting. Explicit config options retain precedence.\n\nAttribute: `compact`","type":"boolean","default":"false"},{"name":"config","type":"LyraChartConfiguration | undefined"},{"name":"dataLabels","description":"Draws each data point's value on the chart via the optional\n`chartjs-plugin-datalabels` peer. Unset (the default) leaves labels off for\nthis chart; the peer is attached only to instances that opt in, and\n`buildConfig()` keeps its per-chart options disabled until this is set. The\nscreen-reader equivalent is the always-present data table (see\n`show-data-table`); labels are a purely visual, canvas-only addition.\n\nAttribute: `data-labels`","type":"boolean","default":"false"},{"name":"dataTableToggle","description":"Render a disclosure button above the accessible data table so a sighted reader can reveal the\nnumbers behind the chart on demand. `showDataTable` alone is all-or-nothing -- the table is\neither permanently screen-reader-only or permanently visible -- which left a consumer wrapping\na duplicated table in their own `<details>`.\n\nWith this set, `showDataTable` becomes the disclosure's *initial* state rather than its whole\nbehavior. The table stays in the DOM in both states, so assistive technology never loses it.\n\nAttribute: `data-table-toggle`","type":"boolean","default":"false"},{"name":"datasets","description":"Simplified chart series. Non-record entries are dropped while valid sibling series remain.","type":"readonly LyraChartSeries[]"},{"name":"description","description":"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\nAttribute: `description`","type":"string | null","default":"null"},{"name":"formatter","description":"Unified context-object formatter for visual, tooltip, table/export, and spoken values.","type":"LyraChartFormatter | undefined"},{"name":"grid","description":"Controls which cartesian grid axes are drawn.\n\nAttribute: `grid`","type":"LyraChartGrid","default":"'both'"},{"name":"height","description":"Attribute: `height`","type":"string","default":"'280px'"},{"name":"hiddenDatasets","description":"Complete controlled visibility state for DOM legend toggles. `undefined` (the default) honors\neach effective dataset's `hidden` configuration; a defined array wins over those defaults, and\nan empty array deliberately makes every dataset visible. Invalid, duplicate, and out-of-range\nindexes are ignored when state is applied or emitted.","type":"readonly number[] | undefined"},{"name":"hiddenDatums","description":"Controlled hidden source category indexes for pie/doughnut/polar-area charts, shared by all\ndatasets/rings. Clone-owned; invalid, duplicate and out-of-range indexes are ignored when\napplied or emitted. Empty restores all categories. Does not alter dataset visibility or exports.","type":"readonly number[]","default":"[]"},{"name":"indexAxis","description":"Chart.js index axis. `'y'` is Chart.js's own mechanism for horizontal bars (it also flips\nline/area types onto a horizontal category axis).\n\nAttribute: `index-axis`","type":"LyraChartIndexAxis","default":"'x'"},{"name":"label","description":"Accessible chart label. A host `aria-label` still has highest precedence.\n\nAttribute: `label`","type":"string | null","default":"null"},{"name":"labels","type":"string[]","default":"[]"},{"name":"legendDisplay","description":"`auto` retains optional legend formatting; `label` omits values even with a formatter; `value`\nappends a formatted value. `percentage` uses locale percentages of the absolute represented\nlegend values, including hidden items (zero totals yield 0%). `value-percentage` appends both,\nas `label: value (percentage)`. Dataset values are sampled sums; category values come from the\nfirst dataset. The `formatter`/`valueFormatter` callback backing `value` and `value-percentage`\nadditionally receives that same `percentage` in its `surface: 'legend'` context, so a custom\nformatter can build its own combined text without recomputing the share. Tooltip and axis\nformatting are unchanged.\n\nAttribute: `legend-display`","type":"LyraChartLegendDisplay","default":"'auto'"},{"name":"legendMode","description":"`datum` renders category toggles for pie/doughnut/polar-area charts. Categories use the first\ndataset's colors and values; a toggle affects that category in every ring. Other chart types\nretain dataset legends. `auto` (the default) resolves to `datum` on pie/doughnut/polar-area\ncharts -- where a single-dataset legend would otherwise enumerate one entry for the whole\ndataset instead of one per visible slice -- and to `dataset` everywhere else. `dataset` always\nforces the dataset legend, even on a slice chart. Both non-`auto` modes use the generated\naccessible-data sampling budget.\n\nAttribute: `legend-mode`","type":"LyraChartLegendMode","default":"'auto'"},{"name":"legendPosition","description":"Legend placement. `auto` uses a right legend above 480px and a bottom legend below it.\n\nAttribute: `legend-position`","type":"LyraChartLegendPosition","default":"'top'"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"max","description":"Maximum value-axis bound. Non-finite values are ignored.\n\nAttribute: `max`","type":"number | null","default":"null"},{"name":"min","description":"Minimum value-axis bound. Non-finite values are ignored.\n\nAttribute: `min`","type":"number | null","default":"null"},{"name":"plugins","description":"Chart.js plugins attached to this chart instance. Valid plugins retain their opaque identity.\n\nAttribute: `plugins`","type":"readonly LyraChartPlugin[]","default":"[]"},{"name":"scaleType","description":"Scale type for the **value** axis (the categorical axis is unaffected). `'logarithmic'` plots\na dataset spanning several orders of magnitude honestly, where a linear axis collapses\neverything below the maximum into the baseline. Inherited by `lr-line-chart`,\n`lr-scatter-chart` and `lr-bar-chart`.\n\nA logarithmic axis cannot represent zero or negative values (`log(0)` is `-Infinity`), so\n`beginAtZero` is not forwarded in that mode -- Chart.js would otherwise be handed a bound it\ncannot place. Non-positive data points are dropped by Chart.js's own log scale.\n\nAttribute: `scale-type`","type":"LyraChartScaleType","default":"'linear'"},{"name":"showDataTable","description":"Makes the generated data table visible; it remains screen-reader available when false.\n\nAttribute: `show-data-table`","type":"boolean","default":"false"},{"name":"stackTotals","description":"When the chart is `stacked` (bar/line only), draws the per-category stack\ntotal above each stack, via the same optional `chartjs-plugin-datalabels`\npeer as `data-labels`. Null/undefined points are skipped; a category whose\nevery value is null shows no total. The generated accessible data table\nreceives the same formatted total column (one per value axis). Unset (the\ndefault) draws and adds nothing.\n\nAttribute: `stack-totals`","type":"boolean","default":"false"},{"name":"stacked","description":"Stacks the `x`/`y`(/`y2`) scale entries `buildScales()` returns; only meaningful for `bar` and `line` types.\n\nAttribute: `stacked`","type":"boolean","default":"false"},{"name":"stackedAxes","description":"Per-value-axis override of `stacked`, keyed by `'y'`/`'y2'`. An axis absent from this record\n-- including every axis when the whole property is unset -- falls back to the chart-wide\n`stacked` value, which is what keeps a chart that never sets this byte-identical to before.\nLets a `stacked` bar series on the primary axis sit next to an unstacked overlay series on\n`y2` (via `LyraChartSeries.axis: 'y2'`): set `stackedAxes` to `{ y2: false }` alongside\n`stacked`, or spell out both axes explicitly. The shared categorical axis (`x` for a vertical\nbar/line, or `y` when `indexAxis` is `'y'`) has no independent entry of its own -- it always\nmirrors the resolved `'y'` value, matching Chart.js's own paired index/value-scale stacking\ncontract. Only meaningful for `bar`/`line` types, matching `stacked` itself.","type":"Partial<Record<'y' | 'y2', boolean>> | undefined"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"tooltipFooterFormatter","description":"Tooltip footer formatter -- e.g. a category's stack total under the items. Receives every\nitem the hovered tooltip covers, in the same shape as `tooltipTitleFormatter`. Unset (the\ndefault) leaves Chart.js's own default (no footer).","type":"LyraChartTooltipGroupFormatter | undefined"},{"name":"tooltipTitleFormatter","description":"Tooltip title formatter -- e.g. a scatter point's own name. Receives every item the hovered\ntooltip covers, each in `formatter`'s `'tooltip'`-surface context shape. Unset (the default)\nleaves Chart.js's own default title (the shared category label) in place.","type":"LyraChartTooltipGroupFormatter | undefined"},{"name":"type","description":"Attribute: `type`","type":"LyraChartType","default":"'line'"},{"name":"valueFormatter","description":"Formats numeric (value-axis) ticks, tooltip values, legend values, and generated accessible\ntable cells from one callback.\nHorizontal scalar tooltips use parsed x, including a raw config indexAxis override;\nstructured points retain their y-value contract. The context-object formatter shares this rule.\nNever runs against the categorical x-axis's own labels (line/bar's `labels` strings) —\nChart.js's category scale passes the tick index to `ticks.callback`, not the label text,\nso formatting it would corrupt the axis.","type":"LyraChartValueFormatter | undefined"},{"name":"withoutAnimation","description":"Disables Chart.js animation.\n\nAttribute: `without-animation`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"withoutLegend","description":"Hides the legend.\n\nAttribute: `without-legend`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"withoutTooltip","description":"Hides Chart.js tooltips.\n\nAttribute: `without-tooltip`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"xLabel","description":"Attribute: `x-label`","type":"string | null","default":"null"},{"name":"y2Label","description":"Attribute: `y2-label`","type":"string","default":"''"},{"name":"yLabel","description":"Attribute: `y-label`","type":"string | null","default":"null"},{"name":"zoom","description":"Attribute: `zoom`","type":"boolean","default":"false"}],"events":[{"name":"lr-before-datum-visibility-change","description":"Cancelable category visibility proposal in datum legend mode. `detail: { index: number, visible: boolean, hiddenDatums: readonly number[] }`. Source category indexes apply to every dataset/ring. The complete detail is frozen.","type":"CustomEvent<LyraChartDatumVisibilityChangeDetail>"},{"name":"lr-before-legend-visibility-change","description":"Cancelable proposal emitted before a DOM legend toggle changes state. `detail` contains the target `datasetIndex`, its proposed `visible` value, and the complete canonical proposed `hiddenDatasets` snapshot.","type":"CustomEvent<LyraChartLegendVisibilityChangeDetail>"},{"name":"lr-datum-activate","description":"Family-normalized activation event. Its detail adds `kind` (`bar`, `point`, `segment`, or `slice`) to the `lr-point-click` detail.","type":"CustomEvent<\n    LyraChartDatumActivateDetail<LyraCoreChartDatumKind>\n  >"},{"name":"lr-datum-visibility-change","description":"Emitted after an accepted category toggle commits the same frozen detail. Programmatic `hiddenDatums` assignments are silent.","type":"CustomEvent<LyraChartDatumVisibilityChangeDetail>"},{"name":"lr-legend-visibility-change","description":"Emitted after an accepted DOM legend toggle commits the same detail. Programmatic `hiddenDatasets` changes reconcile without either event.","type":"CustomEvent<LyraChartLegendVisibilityChangeDetail>"},{"name":"lr-point-click","description":"Fired when pointer input lands on a data point/segment, when a generated data-table value is activated, or when Enter/Space activates the keyboard-current canvas datum. `detail: { datasetIndex: number, index: number, label: string | undefined, value: unknown }`. For scatter/bubble data, `label` prefers the per-point label and `value` is the complete typed `LyraChartPoint` (`x`, `y`, optional `r`, optional `label`).","type":"CustomEvent<{\n    datasetIndex: number;\n    index: number;\n    label: string | undefined;\n    value: unknown;\n  }>"},{"name":"lr-zoom","description":"`detail: { zoomed }`.","type":"CustomEvent<{ zoomed: boolean }>"}]}},{"name":"lr-lite-chart","description":"`<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\nTwo `lr-chart` surfaces have no counterpart here, deliberately: a per-series `stack` group id\nand a per-axis `stackedAxes` override. This chart has exactly one value scale (no `y2`), so \"an\nunstacked overlay on a second axis\" has no equivalent shape, and `stacked` already sums the\nwhole category into one segmented bar; a per-series stack-group id would need the bar-geometry\npass below to track independent running offsets per group instead of one per category. Tooltip\ntitle/footer formatters are likewise absent: the hover tooltip here is a native SVG `<title>`\nper mark (`pointText`), not a multi-item tooltip with separate regions for several datasets\nsharing a hovered category.\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-chart-tick-font-size` (default: `var(--lr-font-size-2xs)`) — Axis tick-label font size. Same token name as `lr-chart`'s canvas equivalent, so theming either retunes both.\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`.","attributes":[{"name":"accessible-label","description":"Overrides the `<svg>`'s auto-derived `aria-label` (`datasets.map(d => d.label).join(', ') ||\n'Chart'`) — for a consumer with a real, localized chart description. A host `aria-label`\ntakes precedence. Unset (the default) keeps today's auto-derived (English-fallback) label\nexactly. `lr-lite-chart` keeps this override under its original `accessible-label` name; it\nis unrelated to (and was not renamed alongside) the deprecated `accessible-label` alias that\n`lr-chart`/`lr-box-plot` dropped in favor of their mirrored `label` property.\n\nType: `string | undefined`"},{"name":"bar-gap-ratio","description":"Overrides the internal `BAR_GROUP_GAP` (0.2) fraction of a category slot left as a gap between\ncategories. Grouped bars share the remaining width with bounded internal gaps; ratios below\n1 retain positive bar widths. Unset (the default) keeps the 0.2 category gap.\n\nType: `number | undefined`"},{"name":"bar-width","description":"Fixed per-category bar width in px, used only when `layout=\"scroll\"`. Ignored (as before this\nproperty existed) in `layout=\"fit\"`, the default. Scroll content is capped at 1,000,000px,\nso an excessive requested width is reduced as needed to keep SVG and CSS geometry finite.\n\nType: `number`  \nDefault: `32`","value":{"type":["number"]}},{"name":"begin-at-zero","description":"Type: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"data-table-toggle","description":"Render a disclosure button above the accessible data table so a sighted reader can reveal the\nnumbers on demand, turning `showDataTable` into the disclosure's INITIAL state rather than its\nwhole behavior. The table stays in the DOM in both states, so assistive technology never loses\nit.\n\nMatters more here than on `<lr-chart>`: this component exists to avoid the Chart.js peers, so\nwithout it an app that chose it for that reason had to either hand-roll a `<details>` around a\nduplicated table or adopt `<lr-chart>` and pull in Chart.js for a button — the cheap component\nstuck with the expensive workaround.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"description","description":"Optional accessible chart description.\n\nType: `string | null`  \nDefault: `null`"},{"name":"height","description":"A CSS `height`; invalid values leave the default height token in control. The public\n`--lr-chart-height` token always takes precedence over this private fallback.\n\nType: `string`  \nDefault: `'280px'`","value":{"type":["string"]}},{"name":"label","description":"Accessible chart name. A host `aria-label` wins.\n\nType: `string | null`  \nDefault: `null`"},{"name":"layout","description":"Type: `LyraLiteChartLayout`","value":{"type":["'fit'","'scroll'"]}},{"name":"legend","description":"Deliberately opt-in (default `false`), unlike `lr-chart`'s negative-polarity `withoutLegend`\n(legend shown by default): `lr-lite-chart`'s typical single-series sparkline-adjacent usage is\nmore often legend-redundant than `lr-chart`'s typical multi-dataset case.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"legend-position","description":"Logical placement for the optional DOM legend. Deliberately `'bottom'`, unlike `lr-chart`'s\n`'top'` default -- shared with `lr-box-plot` via `chart-chrome.ts`'s\n`normalizeChartChromeLegendPosition()` default.\n\nType: `LyraChartChromeLegendPosition`  \nDefault: `'bottom'`","value":{"type":["'top'","'bottom'","'start'","'end'"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max-labels","description":"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`"},{"name":"min-bar-height","description":"A pixel floor for a bar/stacked-segment's rendered height, for a nonzero value that would\notherwise round to sub-pixel and become visually indistinguishable from absent (while still\nbeing focusable/tab-stoppable/announced) — a real accessibility/visibility gap for\nheterogeneous-magnitude stacked data. `type=\"bar\"` only; a value of exactly `0` is unaffected\n(that's `skipZero`'s job, not this one's). Finite values are capped at 1,000,000px to keep\nderived SVG geometry practical. Unset (the default) reproduces today's `Math.max(0, y2 - y1)`\nexactly, with no floor. Authored floors can exceed the available plot height. Linear and\nlogarithmic stacks push subsequent segments along their signed pixel cursor.\n\nType: `number | undefined`"},{"name":"rounded-bars","description":"`type=\"bar\"` only: draws each bar as a rounded-top-corner shape instead of the default\nsquare-cornered rect. Default `false` renders exactly today's plain `<rect>`.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"scale","description":"`'linear'` (default) maps values through the standard domain fraction. `'sqrt'` compresses\nbar magnitudes while keeping line points and gridlines linear; stacked bars compress each\nsigned total once and split it proportionally. `'logarithmic'` maps bars, line points and\ngridlines onto the same log axis with positive, bounded logarithmic ticks. Logarithmic stacks\nmap the finite positive total once and\nsplit its extent by raw positive shares; nonpositive segments have zero natural log height.\nWith minBarHeight unset, the natural logarithmic stack remains within the plot.\n\nType: `LyraLiteChartScale`  \nDefault: `'linear'`","value":{"type":["'linear'","'sqrt'","'logarithmic'"]}},{"name":"show-data-table","description":"Makes the generated data table visible; it stays screen-reader available when false. Same\nmeaning as `<lr-chart>`'s property of the same name.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"skip-zero","description":"`type=\"bar\"` only: omits a bar entirely (no mark, no `tabindex`, no tooltip) for a value that\nis exactly `0` — `null`/non-finite values are always skipped regardless of this flag. Default\n`false` preserves today's behavior of a zero-height but focusable/titled bar.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"stacked","description":"Stacks each category's bars into one segmented bar. Ignored for `type=\"line\"`.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"table-totals","description":"Adds a localized total column to the built-in multi-series accessible table for a stacked\nbar chart. Ignored for grouped bars and line charts.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"type","description":"Type: `LyraLiteChartType`  \nDefault: `'bar'`","value":{"type":["'bar'","'line'"]}},{"name":"value-axis-gutter","description":"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`"},{"name":"without-value-axis","description":"Suppresses `renderGrid()` entirely — no gridlines, no y-axis tick labels. x-axis category\nlabels (rendered separately) are unaffected. Default `false` preserves today's behavior.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"x-label","description":"Horizontal axis title. Long titles ellipsize to fit while retaining their full accessible name.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"y-label","description":"Vertical axis title. Long titles ellipsize to fit while retaining their full accessible name.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"slots":[{"name":"data-table","description":"An optional consumer-provided complete/paginated accessible data alternative."}],"js":{"properties":[{"name":"accessibleLabel","description":"Overrides the `<svg>`'s auto-derived `aria-label` (`datasets.map(d => d.label).join(', ') ||\n'Chart'`) — for a consumer with a real, localized chart description. A host `aria-label`\ntakes precedence. Unset (the default) keeps today's auto-derived (English-fallback) label\nexactly. `lr-lite-chart` keeps this override under its original `accessible-label` name; it\nis unrelated to (and was not renamed alongside) the deprecated `accessible-label` alias that\n`lr-chart`/`lr-box-plot` dropped in favor of their mirrored `label` property.\n\nAttribute: `accessible-label`","type":"string | undefined"},{"name":"axisLabelText","description":"Visual-only override for one category-axis tick's text — receives that category's own `labels`\nentry and its index, and returns the string to draw, or `null` to draw no tick there at all.\n\nDisplay, not data: `labels` stays the single authoritative source for the generated accessible\ntable's row headers, the per-mark `<title>`/accessible name, the live announcement and CSV\nexport, so blanking a tick here never blanks the same category anywhere a reader or a\nspreadsheet needs it. That separation is the whole point — folding the same intent into\n`labels` (passing `''` for the categories that should carry no tick) empties the table row\nheader too, which is what made boundary-aligned ticks impossible before this hook existed.\n\nComplements `maxLabels` rather than replacing it: `maxLabels` decimates evenly to prevent\nlabel collision and is applied FIRST, so a category it already dropped never reaches this\ncallback. Use this one for ticks that must line up with an external grouping boundary (a\nmonth, a release, a shift change) instead of an even stride, and leave `maxLabels` unset there.\n\nThe returned string is ellipsized to the tick's own slot exactly like a source label, with the\nfull text kept as the tick's accessible name; a return value that is neither a string nor\n`null` falls back to the source label rather than reaching the DOM.","type":"(\n    label: string,\n    index: number,\n  ) => string | null | undefined"},{"name":"barGapRatio","description":"Overrides the internal `BAR_GROUP_GAP` (0.2) fraction of a category slot left as a gap between\ncategories. Grouped bars share the remaining width with bounded internal gaps; ratios below\n1 retain positive bar widths. Unset (the default) keeps the 0.2 category gap.\n\nAttribute: `bar-gap-ratio`","type":"number | undefined"},{"name":"barWidth","description":"Fixed per-category bar width in px, used only when `layout=\"scroll\"`. Ignored (as before this\nproperty existed) in `layout=\"fit\"`, the default. Scroll content is capped at 1,000,000px,\nso an excessive requested width is reduced as needed to keep SVG and CSS geometry finite.\n\nAttribute: `bar-width`","type":"number","default":"32"},{"name":"barX","description":"Overrides the x-origin `renderBars()`/the category labels would otherwise compute internally\nfor a given category index, for `type=\"bar\"` only (bars and their axis labels stay\nconsistent with each other either way). Lets a consumer pixel-align this chart's bars with,\ne.g., a sibling `lr-heatmap`'s calendar columns by handing both components the same\ncoordinate function. Unset (the default) uses the existing internal per-category slot math,\nunchanged from before this property existed. The callback resolves once per rendered category\nper render and its finite result is shared by bars and labels; a non-finite result falls back\nto normal slot placement.","type":"(index: number) => number | undefined"},{"name":"beginAtZero","description":"Attribute: `begin-at-zero`","type":"boolean","default":"true"},{"name":"dataTableToggle","description":"Render a disclosure button above the accessible data table so a sighted reader can reveal the\nnumbers on demand, turning `showDataTable` into the disclosure's INITIAL state rather than its\nwhole behavior. The table stays in the DOM in both states, so assistive technology never loses\nit.\n\nMatters more here than on `<lr-chart>`: this component exists to avoid the Chart.js peers, so\nwithout it an app that chose it for that reason had to either hand-roll a `<details>` around a\nduplicated table or adopt `<lr-chart>` and pull in Chart.js for a button — the cheap component\nstuck with the expensive workaround.\n\nAttribute: `data-table-toggle`","type":"boolean","default":"false"},{"name":"datasets","description":"Series with an array `data` payload. Malformed entries are dropped without hiding siblings.","type":"readonly LyraLiteChartSeries[]"},{"name":"description","description":"Optional accessible chart description.\n\nAttribute: `description`","type":"string | null","default":"null"},{"name":"formatter","description":"Unified context-object formatter shared with the Chart.js-backed chart surfaces.","type":"LyraChartFormatter | undefined"},{"name":"height","description":"A CSS `height`; invalid values leave the default height token in control. The public\n`--lr-chart-height` token always takes precedence over this private fallback.\n\nAttribute: `height`","type":"string","default":"'280px'"},{"name":"label","description":"Accessible chart name. A host `aria-label` wins.\n\nAttribute: `label`","type":"string | null","default":"null"},{"name":"labels","type":"readonly string[]","default":"[]"},{"name":"layout","description":"Attribute: `layout`  \nReflected to its attribute.","type":"LyraLiteChartLayout"},{"name":"legend","description":"Deliberately opt-in (default `false`), unlike `lr-chart`'s negative-polarity `withoutLegend`\n(legend shown by default): `lr-lite-chart`'s typical single-series sparkline-adjacent usage is\nmore often legend-redundant than `lr-chart`'s typical multi-dataset case.\n\nAttribute: `legend`","type":"boolean","default":"false"},{"name":"legendPosition","description":"Logical placement for the optional DOM legend. Deliberately `'bottom'`, unlike `lr-chart`'s\n`'top'` default -- shared with `lr-box-plot` via `chart-chrome.ts`'s\n`normalizeChartChromeLegendPosition()` default.\n\nAttribute: `legend-position`","type":"LyraChartChromeLegendPosition","default":"'bottom'"},{"name":"legendText","description":"Formats extra per-item text appended after a series' label in the built-in legend row (e.g. a\nvalue or percentage share) — receives the series label and its dataset index. Falls back to\nrendering the label alone when unset (today's exact legend output), mirroring `pointText`'s and\n`tickFormat`'s existing opt-in-hook convention. Has no effect while `legend` is `false`.","type":"(label: string, datasetIndex: number) => string | undefined"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"maxLabels","description":"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\nAttribute: `max-labels`","type":"number | 'auto' | undefined"},{"name":"minBarHeight","description":"A pixel floor for a bar/stacked-segment's rendered height, for a nonzero value that would\notherwise round to sub-pixel and become visually indistinguishable from absent (while still\nbeing focusable/tab-stoppable/announced) — a real accessibility/visibility gap for\nheterogeneous-magnitude stacked data. `type=\"bar\"` only; a value of exactly `0` is unaffected\n(that's `skipZero`'s job, not this one's). Finite values are capped at 1,000,000px to keep\nderived SVG geometry practical. Unset (the default) reproduces today's `Math.max(0, y2 - y1)`\nexactly, with no floor. Authored floors can exceed the available plot height. Linear and\nlogarithmic stacks push subsequent segments along their signed pixel cursor.\n\nAttribute: `min-bar-height`","type":"number | undefined"},{"name":"pointText","description":"Formats the per-bar/per-point `<title>` tooltip and accessible-name text — receives the category\nlabel, the raw value, and the dataset index. Falls back to the built-in raw-value template\nwhen unset (mirrors `lr-heatmap`'s `cellText` hook).","type":"(label: string, value: number, datasetIndex: number) => string | undefined"},{"name":"roundedBars","description":"`type=\"bar\"` only: draws each bar as a rounded-top-corner shape instead of the default\nsquare-cornered rect. Default `false` renders exactly today's plain `<rect>`.\n\nAttribute: `rounded-bars`","type":"boolean","default":"false"},{"name":"scale","description":"`'linear'` (default) maps values through the standard domain fraction. `'sqrt'` compresses\nbar magnitudes while keeping line points and gridlines linear; stacked bars compress each\nsigned total once and split it proportionally. `'logarithmic'` maps bars, line points and\ngridlines onto the same log axis with positive, bounded logarithmic ticks. Logarithmic stacks\nmap the finite positive total once and\nsplit its extent by raw positive shares; nonpositive segments have zero natural log height.\nWith minBarHeight unset, the natural logarithmic stack remains within the plot.\n\nAttribute: `scale`","type":"LyraLiteChartScale","default":"'linear'"},{"name":"selectedIndices","description":"Category indexes to mark `data-selected` and `aria-pressed=\"true\"` on every bar/point at\nthat index, across every\ndataset -- e.g. to highlight a whole selected week's column in a stacked chart. Empty (the\ndefault) reproduces today's exact output: no mark carries `data-selected`. Style the highlight\nvia the `--lr-lite-chart-selected-outline-color` and\n`--lr-lite-chart-selected-outline-width` custom properties -- selectors such as\n`::part(bar)[data-selected]` and `::part(point)[data-selected]` are invalid CSS (Shadow Parts\nforbids an attribute selector after `::part()`), so the outline is\npainted inside the shadow root and exposed through that token. This component takes no opinion\non what the highlight looks like, only which marks it applies to.","type":"readonly number[]","default":"[]"},{"name":"showDataTable","description":"Makes the generated data table visible; it stays screen-reader available when false. Same\nmeaning as `<lr-chart>`'s property of the same name.\n\nAttribute: `show-data-table`","type":"boolean","default":"false"},{"name":"skipZero","description":"`type=\"bar\"` only: omits a bar entirely (no mark, no `tabindex`, no tooltip) for a value that\nis exactly `0` — `null`/non-finite values are always skipped regardless of this flag. Default\n`false` preserves today's behavior of a zero-height but focusable/titled bar.\n\nAttribute: `skip-zero`","type":"boolean","default":"false"},{"name":"stacked","description":"Stacks each category's bars into one segmented bar. Ignored for `type=\"line\"`.\n\nAttribute: `stacked`","type":"boolean","default":"false"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"tableCellFormatter","description":"Formats finite numeric cells in the built-in multi-series accessible table, including its\nopt-in total cells. Unset preserves locale-aware number formatting.","type":"LyraLiteChartTableCellFormatter | undefined"},{"name":"tableTotals","description":"Adds a localized total column to the built-in multi-series accessible table for a stacked\nbar chart. Ignored for grouped bars and line charts.\n\nAttribute: `table-totals`","type":"boolean","default":"false"},{"name":"tickFormat","description":"Formats a y-axis tick value for display (e.g. `(v) => \\`$${v.toFixed(2)}\\``). Falls back to the\nbuilt-in nice-number formatter when unset.","type":"(value: number) => string | undefined"},{"name":"type","description":"Attribute: `type`","type":"LyraLiteChartType","default":"'bar'"},{"name":"valueAxisGutter","description":"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\nAttribute: `value-axis-gutter`","type":"number | 'auto' | undefined"},{"name":"withoutValueAxis","description":"Suppresses `renderGrid()` entirely — no gridlines, no y-axis tick labels. x-axis category\nlabels (rendered separately) are unaffected. Default `false` preserves today's behavior.\n\nAttribute: `without-value-axis`","type":"boolean","default":"false"},{"name":"xLabel","description":"Horizontal axis title. Long titles ellipsize to fit while retaining their full accessible name.\n\nAttribute: `x-label`","type":"string","default":"''"},{"name":"yLabel","description":"Vertical axis title. Long titles ellipsize to fit while retaining their full accessible name.\n\nAttribute: `y-label`","type":"string","default":"''"}],"events":[{"name":"lr-datum-activate","description":"Fired when a bar/point is activated. The normalized detail includes `kind`, `datasetIndex`, `index`, `label`, and `value` across the chart family.","type":"CustomEvent<\n    LyraChartDatumActivateDetail<'bar' | 'point', number | null>\n  >"},{"name":"lr-point-click","description":"Fired when a bar/point is activated (click, or Enter/Space while focused). `detail: { datasetIndex: number, index: number, label: string | undefined, value: number | null }` — same shape as `lr-chart`'s `lr-point-click`.","type":"CustomEvent<{\n    datasetIndex: number;\n    index: number;\n    label: string | undefined;\n    value: number | null;\n  }>"}]}},{"name":"lr-live-region","description":"`<lr-live-region>` — a visually-hidden ARIA live region that throttles\nand coalesces announcements instead of relaying every call verbatim.\n\nThe announced copy does **not** live in this element's shadow root: a live\nregion inside a shadow root is not reliably announced (JAWS with Firefox\nignores one outright), so `announce()` appends to a shared, ref-counted,\nvisually-hidden region in the host document — see\n`acquireAnnouncementSink()` in `../../../internal/announcer.js`. Every\n`<lr-live-region>` of the same `mode` in a document shares one such region,\nand it is unmounted when the last one disconnects. The shadow\n`part=\"region\"` element remains as an `aria-hidden` mirror of the latest\ntext — a styling/inspection surface, never a second announcement.\n\nNaive live regions plus token-by-token streaming text (a chat response, a\nprogress readout, ...) equals screen-reader spam: every incremental chunk\ngets announced. This component wraps `Announcer`\n(`../../internal/announcer.js`) so callers can fire `announce()` as often\nas they like — only the latest text within each `throttle-ms` window\nactually reaches assistive tech, and a `{ force: true }` call (e.g. once a\nstream ends) always lands immediately regardless of any window in\nprogress.\n\nA consumer typically mounts one `<lr-live-region>` per page/surface\n(much like `<lr-toast>` is one region per placement — see\n`../toast/toaster.ts`) and keeps a reference to call `announce()` from\napplication code or a parent component:\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| `region` | The visually-hidden, `aria-hidden` mirror of the latest announced text. The announcement itself lands in the shared light-DOM region, not here. |","attributes":[{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"mode","description":"Type: `LyraLiveRegionMode`","value":{"type":["'polite'","'assertive'"]}},{"name":"throttle-ms","description":"Throttle window in ms — see `Announcer` in `internal/announcer.ts`.\n\nType: `number`  \nDefault: `500`","value":{"type":["number"]}}],"js":{"properties":[{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"mode","description":"Attribute: `mode`  \nReflected to its attribute.","type":"LyraLiveRegionMode"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"throttleMs","description":"Throttle window in ms — see `Announcer` in `internal/announcer.ts`.\n\nAttribute: `throttle-ms`","type":"number","default":"500"}]}},{"name":"lr-locale-picker","description":"`<lr-locale-picker>` — a closed-list locale switcher over the library's own locale registry.\n\nWith `locales` left unset (the default), the offered rows are exactly\n`getRegisteredLyraLocales()` — every locale with strings registered via `registerLyraLocale()`,\nplus `'en'` (always available through the library's built-in English fallback) — kept live via\n`subscribeLyraLocaleRegistry()` so a locale registered after mount (e.g. a lazily-loaded\ntranslation pack) appears without a manual refresh. Passing an explicit `locales` array\noverrides the auto-discovered list entirely: a curated subset, a custom order, custom labels,\nor a locale the host wants to offer before its strings are registered.\n\n`value` is the *committed* selection (form-submitted, drives `lr-change`) and starts `''`.\nWhile unset, the trigger displays `effectiveLocale` (the same ancestor-`lang`/registry\nresolution every other component already uses) as a live preview — but that preview is never a\ncommitment: `checkValidity()`/`required` are governed by the real `value`, which stays `''`\nuntil the host sets it or the user actually picks a row. This mirrors a native `<select>`\nrendering its first option's text without that being a committed selection.\n\nWhen a required picker is still empty, its library-owned validation message follows its current\n`.strings` and effective locale. A caller-provided `setCustomValidity()` message remains the\nhigher-precedence validation layer until the caller clears it.\n\nBuilt directly on the shared trigger-button/`aria-activedescendant` listbox technique\n`<lr-select>` uses (not composed from it) — a plain closed list, no filter/free-text mode; a\nlocale catalog is realistically dozens of rows, not thousands, so `<lr-combobox>`'s filterable\nmodel would be more surface than the job needs.\n\nSelecting a row sets `value` and emits a cancelable `lr-change` — if a listener doesn't call\n`event.preventDefault()`, the component applies the pick itself via `setLyraLocale()`. A host\nthat wants to intercept the pick (e.g. persist it to a profile first) calls\n`event.preventDefault()`; `value` still updates so the trigger reflects the pick, but the\npage-level locale is untouched until the host calls `setLyraLocale()` itself.\n\nDoes not touch `document.documentElement.lang`/`dir` — applying a picked locale's writing\ndirection to the page is left to the host, which already has everything it needs from\n`lr-change` to do that itself: the detail carries the resolved `direction` alongside `value`,\nso `document.documentElement.dir = event.detail.direction` is the whole of it.\n\nComponent-scoped theme inputs remain undeclared on the host, so values inherited from an\nancestor theme wrapper override the active size tier. A value set directly on the locale picker\nstill wins through normal custom-property inheritance.\n\nHost aria-describedby targets supplement local error/hint guidance on the trigger. The\nrelationships track target replacement, missing IDs, removal/reinsertion, reconnect, and adoption.\nRemoved label/hint/error-text content is safely omitted without changing null property readback.\n\n---\n\n**Component metadata**\n\n- Status: `stable`\n- Since: `6.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| `error` | Custom error content. |\n| `hint` | Custom hint content. |\n| `label` | Custom label content. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `error` | The error message. |\n| `expand-icon` | The dropdown indicator. |\n| `form-control` | The outer wrapper around label, trigger, listbox, error and hint. |\n| `form-control-label` | The `<label>` element (only rendered — and only contributes to the accessible name — once `label` is non-empty). |\n| `hint` | The hint message. |\n| `listbox` | The options popover. |\n| `option` | An option row. |\n| `option-flag` | The row's leading `<lr-flag>` (present only while `showFlags` is on). |\n| `option-label` | An option row's label wrapper (native name + tag). |\n| `option-tag` | An option row's secondary line — the raw BCP-47 tag. Rendered only while `optionDisplay` is `label-tag` (the default); `optionDisplay=\"label\"` omits the element outright, so this part matches nothing at all rather than matching a hidden node. |\n| `trigger` | The trigger button (positioning anchor). |\n| `trigger-flag` | The trigger's leading `<lr-flag>` for the current value (present only while `showFlags` is on and `triggerDisplay` is not `label`). |\n| `trigger-label` | The current locale's label. Visually hidden in flag-only mode but retained as the trigger's accessible current-value description. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-form-control-focus-shadow` (default: `none`) — The shared field focus halo, painted as a `box-shadow` while this control is focused. One name for every field-shaped control in the library, so a halo is configured once rather than per component. Additive: the focus outline and border cue are the accessibility answer to focus and are never replaced by it.\n- `--lr-form-control-required-color` (default: `var(--lr-color-danger)`) — Color of that marker, retunable without touching any other danger-coloured surface.\n- `--lr-form-control-required-content` (default: `' *'`) — The required-field marker rendered after the label. Set it to `''` to suppress the marker, or to any other quoted string (`' (required)'`, a localized word) to replace it. Caller-supplied content, so it is never localized here.\n- `--lr-form-control-required-offset` (default: `0`) — Inline space between the label text and the marker.\n- `--lr-locale-picker-expand-size` — Decorative expand-icon box size, scaled by `size`.\n- `--lr-locale-picker-font-size` (default: `var(--lr-form-control-font-size)`) — Trigger font size, from the shared form-control size ladder.\n- `--lr-locale-picker-gap` (default: `var(--lr-space-xs)`) — Trigger and option child gap.\n- `--lr-locale-picker-open-border-color` (default: `var(--lr-color-brand)`) — Open trigger border color.\n- `--lr-locale-picker-option-active-bg` (default: `var(--lr-color-brand-quiet)`) — Background of a hovered or keyboard-active option row.\n- `--lr-locale-picker-option-selected-border-color` (default: `var(--lr-color-brand)`) — Selected option border.\n- `--lr-locale-picker-option-selected-color` (default: `var(--lr-color-brand)`) — Selected option text.\n- `--lr-locale-picker-option-selected-font-weight` (default: `var(--lr-font-weight-semibold)`) — Selected option font weight.\n- `--lr-locale-picker-radius` (default: `var(--lr-radius)`) — Trigger/listbox/option corner radius.\n- `--lr-locale-picker-trigger-border-color` (default: `var(--lr-color-border)`) — Resting trigger border color.\n- `--lr-locale-picker-trigger-fill` (default: `var(--lr-color-surface)`) — Resting trigger background.\n- `--lr-locale-picker-trigger-height` — Exact trigger height. Unset by default (a floor only via `-trigger-min-height`); set a length to both floor and cap the trigger, e.g. to pixel-match a sibling field in the same toolbar row.\n- `--lr-locale-picker-trigger-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Trigger hover background.\n- `--lr-locale-picker-trigger-hover-border-color` (default: `var(--lr-locale-picker-trigger-border-color)`) — Trigger border color while the pointer is over it. Unset, the border stays exactly where the resting state left it.\n- `--lr-locale-picker-trigger-min-height` (default: `var(--lr-form-control-height)`) — Trigger block-size floor. Reads the shared form-control height ladder, so retuning `--lr-theme-form-control-height-*` moves this control and every sibling field together.\n- `--lr-locale-picker-trigger-padding` — Trigger padding shorthand, scaled by `size`.\n- `--lr-overlay-border` (default: `var(--lr-color-border)`) — Shared floating-surface edge colour, on the listbox.\n- `--lr-overlay-radius` (default: `var(--lr-radius)`) — Shared floating-surface corner radius, read by the listbox only as the middle arm of `--lr-locale-picker-radius`, which still wins when set.\n- `--lr-overlay-shadow-anchored` (default: `var(--lr-shadow-m)`) — Elevation of the anchored listbox.\n- `--lr-overlay-surface` (default: `var(--lr-color-surface-overlay)`) — Shared floating-surface fill, on the listbox.\n- `--lr-positioning-strategy` — Cascading `absolute`/`fixed` override for the listbox's `fixed` default, read from computed style when it is (re)positioned. Set it once on `:root`, a theme, or one clipping ancestor to change every unset locale picker beneath it; an unrecognized value falls back to `fixed`.","attributes":[{"name":"custom-error","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nType: `string | null`"},{"name":"disabled","description":"Type: `boolean`","value":{"type":["boolean"]}},{"name":"error-text","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"form","description":"Type: `HTMLFormElement | string | null`  \nDefault: `null`"},{"name":"hint","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"label","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"name","description":"Type: `string`","value":{"type":["string"]}},{"name":"open","description":"Whether the option popup is open. Disabled controls reject direct reopen attempts, including\nthe synchronous fieldset cascade before `formDisabledCallback()` runs.\n\nType: `boolean`","value":{"type":["boolean"]}},{"name":"option-display","description":"Option-row content. The default `label-tag` keeps today's two-line row: the locale's label\nabove its raw BCP-47 tag. `label` renders the label alone and OMITS the `option-tag` part\nrather than hiding it -- a visually hidden tag still joins the row's accessible name and still\nmatches a consumer's own `::part(option-tag)` rule, so hiding is not omitting. The trigger,\nthe row flags and selection behaviour are identical either way.\n\nType: `LyraLocaleOptionDisplay`  \nDefault: `'label-tag'`","value":{"type":["'label'","'label-tag'"]}},{"name":"required","description":"Type: `boolean`","value":{"type":["boolean"]}},{"name":"show-flags","description":"Each row's leading `<lr-flag>`. The composition recipe this component supersedes\n(`lr-popover` + `lr-flag`) already pairs a locale switcher with flags by convention --\ndefaulting to `true` keeps that continuity; set `false` for text-only rows.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"size","description":"Visual size — the library-wide `2xs`–`xl` ladder shared with `lr-select`. The Web Awesome /\nShoelace spellings `small`/`medium`/`large` are accepted for `s`/`m`/`l`, so a migration is a\ntag rename with no attribute rewrite.\n\nType: `LyraSize`  \nDefault: `'m'`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}},{"name":"trigger-display","description":"Trigger content. The default flag-label preserves the label, optional flag and chevron.\nFlag mode centers the flag in a square based on the trigger height, with a 24px minimum,\nand keeps the current language accessible while hiding the visible label and chevron.\nLabel mode omits only the trigger flag. showFlags=false always keeps the visible label.\nOption labels/endonyms and selection behavior are unchanged.\n\nType: `LyraLocaleTriggerDisplay`  \nDefault: `'flag-label'`","value":{"type":["'flag'","'label'","'flag-label'"]}},{"name":"value","description":"Reflected current reset default; changing it never overwrites a dirty live `value`.\n\nType: `string`","value":{"type":["string"]}}],"slots":[{"name":"error","description":"Custom error content."},{"name":"hint","description":"Custom hint content."},{"name":"label","description":"Custom label content."}],"js":{"properties":[{"name":"customError","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nAttribute: `custom-error`  \nReflected to its attribute.","type":"string | null"},{"name":"defaultValue","description":"Reflected current reset default; changing it never overwrites a dirty live `value`.\n\nAttribute: `value`  \nReflected to its attribute.","type":"string"},{"name":"disabled","description":"Attribute: `disabled`  \nReflected to its attribute.","type":"boolean"},{"name":"effectiveDisabled","description":"Whether the control is disabled explicitly or by an ancestor fieldset.","type":"boolean","read-only":true},{"name":"errorText","description":"Attribute: `error-text`","type":"string","default":"''"},{"name":"form","description":"Attribute: `form`  \nReflected to its attribute.","type":"HTMLFormElement | string | null","default":"null"},{"name":"hint","description":"Attribute: `hint`","type":"string","default":"''"},{"name":"label","description":"Attribute: `label`","type":"string","default":"''"},{"name":"labels","type":"NodeList","read-only":true},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"locales","type":"LyraLocaleCatalog | undefined"},{"name":"name","description":"Attribute: `name`  \nReflected to its attribute.","type":"string"},{"name":"open","description":"Whether the option popup is open. Disabled controls reject direct reopen attempts, including\nthe synchronous fieldset cascade before `formDisabledCallback()` runs.\n\nAttribute: `open`  \nReflected to its attribute.","type":"boolean"},{"name":"optionDisplay","description":"Option-row content. The default `label-tag` keeps today's two-line row: the locale's label\nabove its raw BCP-47 tag. `label` renders the label alone and OMITS the `option-tag` part\nrather than hiding it -- a visually hidden tag still joins the row's accessible name and still\nmatches a consumer's own `::part(option-tag)` rule, so hiding is not omitting. The trigger,\nthe row flags and selection behaviour are identical either way.\n\nAttribute: `option-display`","type":"LyraLocaleOptionDisplay","default":"'label-tag'"},{"name":"required","description":"Attribute: `required`  \nReflected to its attribute.","type":"boolean"},{"name":"showFlags","description":"Each row's leading `<lr-flag>`. The composition recipe this component supersedes\n(`lr-popover` + `lr-flag`) already pairs a locale switcher with flags by convention --\ndefaulting to `true` keeps that continuity; set `false` for text-only rows.\n\nAttribute: `show-flags`","type":"boolean","default":"true"},{"name":"size","description":"Visual size — the library-wide `2xs`–`xl` ladder shared with `lr-select`. The Web Awesome /\nShoelace spellings `small`/`medium`/`large` are accepted for `s`/`m`/`l`, so a migration is a\ntag rename with no attribute rewrite.\n\nAttribute: `size`  \nReflected to its attribute.","type":"LyraSize","default":"'m'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"triggerDisplay","description":"Trigger content. The default flag-label preserves the label, optional flag and chevron.\nFlag mode centers the flag in a square based on the trigger height, with a 24px minimum,\nand keeps the current language accessible while hiding the visible label and chevron.\nLabel mode omits only the trigger flag. showFlags=false always keeps the visible label.\nOption labels/endonyms and selection behavior are unchanged.\n\nAttribute: `trigger-display`","type":"LyraLocaleTriggerDisplay","default":"'flag-label'"},{"name":"validationMessage","type":"string","read-only":true},{"name":"validity","type":"ValidityState","read-only":true},{"name":"value","description":"The current locale tag (empty string when nothing is committed).","type":"string"},{"name":"willValidate","type":"boolean","read-only":true}],"events":[{"name":"blur","description":"Native `FocusEvent` relayed from the internal trigger button.","type":"FocusEvent"},{"name":"focus","description":"Native `FocusEvent` relayed from the internal trigger button.","type":"FocusEvent"},{"name":"lr-change","description":"The selection changed. `detail: { value, previousValue, direction }`, where `direction` is the picked locale's `'ltr'`/`'rtl'` writing direction. Cancelable — `event.preventDefault()` stops the automatic `setLyraLocale()` call without reverting `value`.","type":"CustomEvent<LyraLocaleChangeDetail>"},{"name":"lr-invalid","description":"The locale picker failed a validity check; cancelable. Calling `preventDefault()` also cancels the native `invalid` event it aliases, suppressing the browser's own validation bubble and `reportValidity()`'s focus/scroll.","type":"CustomEvent<null>"}]}},{"name":"lr-map","description":"`<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 control data is admitted through bounded, descriptor-safe projections whose\nretained configuration is frozen. Opaque `choropleth.geojson`, `dataLayers[].geojson`, and\nmarker `unsafeHtml` values retain their original identity only at the MapLibre/Popup and\nimmutable `lr-map-marker-activate` detail boundaries; the component does not inspect them\nagain after admission. Reassign control input when its configuration changes rather than\nrelying on mutation of its admitted projection.\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. Slotted content is never made interactive by `legendInteractive`, which only reaches rows projected from `legend`. |\n| `legend-start` | The same extension point at the TOP of the legend panel: it renders ahead of the gradient bar and every projected row, where `legend` renders after them. A panel header -- a title, a source note, a host-built control -- could previously only ever be a footer, because `legend` was the only slot. Content here alone opens the panel, exactly as `legend` content alone does, and it is never made interactive by `legendInteractive`. |\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 with a decorative information glyph. |\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| `compass` | Peer compass/reset-north button; its glyph retains the peer's bearing rotation. |\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-disclosure` | The `button` that collapses and expands the whole legend panel. Rendered only when `legendCollapsible` is set, so an unset map's legend markup is unchanged. It carries the localized panel name as its visible, accessible label plus `aria-expanded` rendered as the literal `\"true\"`/`\"false\"`, and it grows to the shared `--lr-icon-button-size` hit-area floor. |\n| `legend-disclosure-icon` | The decorative chevron inside `legend-disclosure`. It is the wrapping part that rotates (per the shared icon set's contract), including under RTL. |\n| `legend-gradient` | The continuous ramp bar rendered from `legendGradient`. |\n| `legend-group` | The `role=\"group\"` wrapping one consecutive run of legend rows that share a `group`. Absent entirely when no admitted entry carries one, so an ungrouped legend's markup is unchanged. |\n| `legend-group-heading` | The visible heading naming a `legend-group`. It renders the caller-supplied `group` string verbatim and names the group through `aria-labelledby`. |\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, or the entry's glyph when it carries an `icon` — in which case the swatch drops its color block and pattern overlay, keeps the `pattern` border framing the glyph as its non-color cue, carries `data-icon=\"true\"`, and paints the glyph itself in the entry color. It nests inside `legend-toggle` on an interactive row and stays `aria-hidden`/`inert` there, so it never contributes to the button's accessible name. |\n| `legend-toggle` | The `button` an interactive legend row renders around its swatch and label when `legendInteractive` is set and the row carries a `value`. Absent entirely when either is missing, so an unset map's legend markup is unchanged. |\n| `legend-toggle-hidden` | Second token carried alongside `legend-toggle` while that row's category is in `hiddenCategories`. State lives in the part name rather than a separate attribute, so `::part(legend-toggle-hidden)` is a reachable styling hook. |\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| `navigation` | Standard peer NavigationControl group, when added through the map getter. |\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| `scale` | Standard peer ScaleControl bar. Units and updates remain owned by MapLibre. |\n| `zoom-in` | Peer zoom-in button with a localized accessible name and tokenized target. |\n| `zoom-out` | Peer zoom-out button. |\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-height` (default: `var(--lr-size-24rem)`) — Default host block size, shared with the pre-upgrade reservation stylesheet. An explicit outer `block-size` still wins.\n- `--lr-map-hidden-category-opacity` (default: `0.15`) — Opacity a hidden category's points, point strokes and point icons are muted to in the rendered MapLibre paint. Read from the resolved cascade on every paint, because MapLibre draws to a WebGL canvas the CSS cascade never reaches.\n- `--lr-map-legend-hidden-swatch-opacity` (default: `0.5`) — Opacity of a hidden interactive legend row's decorative swatch. Only the `aria-hidden` swatch dims; the label re-colors through the quiet text token instead, so it keeps AA contrast.\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`. The legend is read-only unless `legendInteractive` is set, which is opt-in for a reason: an unset map renders exactly the key it rendered before, with no button, no extra attribute and no extra MapLibre paint key. Only a row that carries its own `value` becomes a toggle -- the key is never derived from an `icon` record's `value`, which would silently make a row operable the author never marked. Each toggle is a native `button`, so it is one independent tab stop per row (a 100-row legend contributes 100, exactly as a 100-series `lr-chart` legend does) and it grows to the shared `--lr-icon-button-size` hit-area floor. Activation emits the cancelable `lr-map-legend-toggle`; there is deliberately no confirmation event, because the committed state is `hiddenCategories` and the host already observes it. A hidden category mutes its points, point strokes and point icons through `--lr-map-hidden-category-opacity`; a `kind: 'heatmap'` entry is deliberately out of scope, having no per-category field to mute. 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`.","attributes":[{"name":"center","description":"Initial and controlled map center as `[longitude, latitude]`.\n\nType: `readonly [number, number]`  \nDefault: `[0, 0]`"},{"name":"label","description":"Accessible name for MapLibre's focusable canvas. A nonempty host `aria-label` remains the\noverall component name and is not cloned onto the nested focus owner; the canvas uses this\npurpose-specific label or the localized `map` message. An explicit empty host name is\npreserved on the canvas for deliberately decorative embeddings.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"legend-collapsible","description":"Renders a disclosure button inside the legend panel that collapses the key down to its header.\nDefault `false`, and an unset map renders exactly the panel it rendered before this property\nexisted -- no button, no `id` minted on the row list, and no `hidden` attribute anywhere.\n\nA collapsed panel hides the gradient bar, the rows, the `legend-limit` summary and the\ntrailing `legend` slot; the `legend-start` slot and the disclosure itself stay visible, so a\nslotted header survives the collapse and the control that would restore the key is never the\nthing the collapse hides.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"legend-control-role","description":"How each keyed `legendInteractive` row's toggle control presents itself to assistive tech.\nInert while `legendInteractive` is unset, exactly like the toggle itself.\n\n- `'button'` (default) -- `<button aria-pressed>`, byte-identical to every 18.1.0 interactive\n  legend. Leaving this property unset changes nothing.\n- `'checkbox'` -- the SAME `<button>` element `renderLegendRow()` already renders, with its\n  implicit role overridden to `role=\"checkbox\"` and `aria-checked` in place of `aria-pressed`.\n  A native `<input type=\"checkbox\">` was considered and rejected: it would need its own\n  swatch/label markup and its own click/keyboard wiring duplicated from the button branch,\n  splitting `renderLegendRowContent()` in two. `<button role=\"checkbox\">` keeps the swatch,\n  the label, the click handler and the platform's own Enter/Space activation exactly as they\n  are for the button branch -- only the two ARIA attributes differ, so the CSS in\n  `map.styles.ts` (which targets `button[part~='legend-toggle']`, never a role or an ARIA\n  state) needs no `'checkbox'`-specific rule.\n\n`aria-checked` tracks the same `visible` flag `aria-pressed` does, inverted from\n`hiddenCategories`: a hidden category renders `aria-checked=\"false\"`. Both states always\nrender explicitly (`\"true\"`/`\"false\"`), never a Lit `?aria-*` presence directive, which cannot\nexpress the false state at all.\n\nType: `LyraMapLegendControlRole`","value":{"type":["'button'","'checkbox'"]}},{"name":"legend-gradient-hi-label","description":"Overrides the high endpoint's caption; defaults to the highest stop value, locale-formatted.\n\nType: `string | null`  \nDefault: `null`"},{"name":"legend-gradient-lo-label","description":"Overrides the low endpoint's caption; defaults to the lowest stop value, locale-formatted.\n\nType: `string | null`  \nDefault: `null`"},{"name":"legend-interactive","description":"Turns every legend row that carries a `value` into a keyboard-operable visibility toggle;\nrows without one stay inert. Default `false`, and an unset map renders exactly the read-only\nkey it rendered before this property existed -- no button, no extra attribute, and no extra\nMapLibre paint key.\n\nEach toggle is an independently tabbable native `button`, so Enter and Space are the\nplatform's own activation and no roving tabindex is involved. The consequence is stated\nrather than hidden: a 100-row interactive legend contributes 100 tab stops, exactly as a\n100-series `lr-chart` legend does. Each row also grows to the `--lr-icon-button-size` hit-area\nfloor; the legend panel's own `max-block-size`/`overflow: auto` contains the taller list.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"legend-open","description":"Whether a `legendCollapsible` panel is expanded. Defaults **open**, so adding only\n`legendCollapsible` never hides an existing key; it does nothing at all while\n`legendCollapsible` is unset.\n\nIt is a `true`-defaulting boolean, so it uses `trueDefaultBooleanConverter` rather than Lit's\npresence-based boolean converter, which cannot express `legend-open=\"false\"` at all. The\nreflection follows the same converter: open (the default) reflects as an ABSENT attribute and\ncollapsed reflects as `legend-open=\"false\"`.\n\nControlled public state, so -- exactly like `hiddenCategories` -- it deliberately survives a\ndisconnect and reconnect: the \"reset transient open-state in `disconnectedCallback()`\" rule\ncovers dropdown/preview/tooltip `@state`, not a documented property a host owns and re-reads.\nA programmatic assignment reconciles the rendered panel without emitting\n`lr-map-legend-panel-toggle`, so a controlled host cannot loop.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"zoom","description":"Initial and controlled map zoom level.\n\nType: `number`  \nDefault: `2`","value":{"type":["number"]}}],"slots":[{"name":"legend","description":"Custom legend content, rendered inside the legend panel's own layout so it stays positioned with the map instead of floating beside it. Slotted content is never made interactive by `legendInteractive`, which only reaches rows projected from `legend`."},{"name":"legend-start","description":"The same extension point at the TOP of the legend panel: it renders ahead of the gradient bar and every projected row, where `legend` renders after them. A panel header -- a title, a source note, a host-built control -- could previously only ever be a footer, because `legend` was the only slot. Content here alone opens the panel, exactly as `legend` content alone does, and it is never made interactive by `legendInteractive`."}],"js":{"properties":[{"name":"center","description":"Initial and controlled map center as `[longitude, latitude]`.\n\nAttribute: `center`","type":"readonly [number, number]","default":"[0, 0]"},{"name":"choropleth","description":"Optional GeoJSON choropleth layer and value-to-color configuration.","type":"Readonly<LyraMapChoroplethLayer> | undefined"},{"name":"dataLayers","description":"Additive GeoJSON layers rendered alongside the choropleth/markers -- each entry becomes a\nsource plus fill/line/circle layers. `sourceId` values are trimmed, must be nonempty, and retain\nonly their first occurrence. Defaults empty (zero behavior change).\n\nAn entry opts into either of two other renderings, both strictly additive: `cluster` turns its\nsource into a natively clustered one (aggregate circle, count label, unclustered points), which\nis what thousands of points need and what `markers` -- one real DOM element per entry -- cannot\nbe; `kind: 'heatmap'` replaces the geometry split with MapLibre's own `heatmap` layer. Neither\nchanges an entry that sets neither. `point` adds categorical circle paint and bounded SVG path\nicons to ordinary or clustered points on the same source; `line` adds numeric route paint.","type":"readonly LyraMapGeoJsonDataLayer[]","default":"[]"},{"name":"hiddenCategories","description":"Complete controlled set of muted category keys, mirroring `lr-chart`'s `hiddenDatasets`.\nClone-owned and frozen; non-string, empty, whitespace-only and duplicate entries are dropped,\nand at most 100 keys are retained. Honoured on the first render and the first MapLibre paint,\nnot only after a user toggle. An empty array deliberately means every category is visible.\n\nControlled public state, so it deliberately survives a disconnect and reconnect: the\n\"reset transient open-state in `disconnectedCallback()`\" rule covers dropdown/preview/tooltip\n`@state`, not a documented property a host owns and re-reads.","type":"readonly string[]"},{"name":"label","description":"Accessible name for MapLibre's focusable canvas. A nonempty host `aria-label` remains the\noverall component name and is not cloned onto the nested focus owner; the canvas uses this\npurpose-specific label or the localized `map` message. An explicit empty host name is\npreserved on the canvas for deliberately decorative embeddings.\n\nAttribute: `label`","type":"string","default":"''"},{"name":"legend","description":"Immutable, bounded entries rendered in the optional map legend. A required pattern keeps\ncategory identity available when authored colors collapse or are unavailable.","type":"readonly LyraMapLegendEntry[]"},{"name":"legendCollapsible","description":"Renders a disclosure button inside the legend panel that collapses the key down to its header.\nDefault `false`, and an unset map renders exactly the panel it rendered before this property\nexisted -- no button, no `id` minted on the row list, and no `hidden` attribute anywhere.\n\nA collapsed panel hides the gradient bar, the rows, the `legend-limit` summary and the\ntrailing `legend` slot; the `legend-start` slot and the disclosure itself stay visible, so a\nslotted header survives the collapse and the control that would restore the key is never the\nthing the collapse hides.\n\nAttribute: `legend-collapsible`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"legendControlRole","description":"How each keyed `legendInteractive` row's toggle control presents itself to assistive tech.\nInert while `legendInteractive` is unset, exactly like the toggle itself.\n\n- `'button'` (default) -- `<button aria-pressed>`, byte-identical to every 18.1.0 interactive\n  legend. Leaving this property unset changes nothing.\n- `'checkbox'` -- the SAME `<button>` element `renderLegendRow()` already renders, with its\n  implicit role overridden to `role=\"checkbox\"` and `aria-checked` in place of `aria-pressed`.\n  A native `<input type=\"checkbox\">` was considered and rejected: it would need its own\n  swatch/label markup and its own click/keyboard wiring duplicated from the button branch,\n  splitting `renderLegendRowContent()` in two. `<button role=\"checkbox\">` keeps the swatch,\n  the label, the click handler and the platform's own Enter/Space activation exactly as they\n  are for the button branch -- only the two ARIA attributes differ, so the CSS in\n  `map.styles.ts` (which targets `button[part~='legend-toggle']`, never a role or an ARIA\n  state) needs no `'checkbox'`-specific rule.\n\n`aria-checked` tracks the same `visible` flag `aria-pressed` does, inverted from\n`hiddenCategories`: a hidden category renders `aria-checked=\"false\"`. Both states always\nrender explicitly (`\"true\"`/`\"false\"`), never a Lit `?aria-*` presence directive, which cannot\nexpress the false state at all.\n\nAttribute: `legend-control-role`  \nReflected to its attribute.","type":"LyraMapLegendControlRole"},{"name":"legendGradient","description":"Renders the legend as a **continuous** gradient bar with endpoint labels instead of (or\nalongside) the discrete `legend` swatches — the standard key for a choropleth, whose\n`interpolate` fill is itself a continuous ramp that discrete rows cannot honestly describe.\n\nTakes the same `[value, color]` stop shape as `choropleth.stops`, so the usual assignment is\n`legendGradient = myChoropleth.stops`. A dev-mode diagnostic reports an independently authored\ncopy that drifts from the layer. Stops are sorted ascending, bounded, and filtered to finite\nvalues carrying a CSS-parsable color; fewer than two usable stops render no bar at all, since a\none-stop \"gradient\" is a flat block that describes nothing. A logarithmic choropleth samples\nthe same exponential interpolation in its visible key; unset (the default) renders exactly\ntoday's markup.\n\nEndpoint labels default to this component's locale-aware formatting of the lowest and highest\nstop values; `legendGradientLoLabel`/`legendGradientHiLabel` override them.","type":"readonly (readonly [number, string])[]"},{"name":"legendGradientHiLabel","description":"Overrides the high endpoint's caption; defaults to the highest stop value, locale-formatted.\n\nAttribute: `legend-gradient-hi-label`","type":"string | null","default":"null"},{"name":"legendGradientLoLabel","description":"Overrides the low endpoint's caption; defaults to the lowest stop value, locale-formatted.\n\nAttribute: `legend-gradient-lo-label`","type":"string | null","default":"null"},{"name":"legendInteractive","description":"Turns every legend row that carries a `value` into a keyboard-operable visibility toggle;\nrows without one stay inert. Default `false`, and an unset map renders exactly the read-only\nkey it rendered before this property existed -- no button, no extra attribute, and no extra\nMapLibre paint key.\n\nEach toggle is an independently tabbable native `button`, so Enter and Space are the\nplatform's own activation and no roving tabindex is involved. The consequence is stated\nrather than hidden: a 100-row interactive legend contributes 100 tab stops, exactly as a\n100-series `lr-chart` legend does. Each row also grows to the `--lr-icon-button-size` hit-area\nfloor; the legend panel's own `max-block-size`/`overflow: auto` contains the taller list.\n\nAttribute: `legend-interactive`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"legendOpen","description":"Whether a `legendCollapsible` panel is expanded. Defaults **open**, so adding only\n`legendCollapsible` never hides an existing key; it does nothing at all while\n`legendCollapsible` is unset.\n\nIt is a `true`-defaulting boolean, so it uses `trueDefaultBooleanConverter` rather than Lit's\npresence-based boolean converter, which cannot express `legend-open=\"false\"` at all. The\nreflection follows the same converter: open (the default) reflects as an ABSENT attribute and\ncollapsed reflects as `legend-open=\"false\"`.\n\nControlled public state, so -- exactly like `hiddenCategories` -- it deliberately survives a\ndisconnect and reconnect: the \"reset transient open-state in `disconnectedCallback()`\" rule\ncovers dropdown/preview/tooltip `@state`, not a documented property a host owns and re-reads.\nA programmatic assignment reconciles the rendered panel without emitting\n`lr-map-legend-panel-toggle`, so a controlled host cannot loop.\n\nAttribute: `legend-open`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"legendProjection","description":"Counts from the latest bounded legend normalization. `truncated` covers omitted rows or\nshortened labels; the returned record is frozen and never aliases caller input.","type":"LyraMapLegendProjection","read-only":true},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"map","description":"The underlying runtime `maplibregl.Map`, declared through Lyra's peer-neutral common-method\nsubset so consumers do not acquire a mandatory `maplibre-gl` type dependency. Consumers that\ninstall the optional peer may explicitly narrow this value to its full `Map` type.","type":"LyraMapInstance | undefined","read-only":true},{"name":"mapStyle","description":"Required MapLibre style URL or peer-neutral style specification. No provider is contacted\nunless a consumer assigns this property.","type":"Readonly<LyraMapStyleSpecification> | string | undefined"},{"name":"markers","description":"Point markers rendered over the map. Explicit IDs are unique-nonempty first-wins. An idless\nmarker is instead identified by its coordinate occurrence, so colocated idless markers remain\nseparate.","type":"readonly LyraMapMarker[]","default":"[]"},{"name":"maxBounds","description":"Box the map may not pan outside, `[[west, south], [east, north]]`, or `null` for unconstrained.\n\nExists because reaching for `map.setMaxBounds()` through the `.map` escape hatch can wedge\nmaplibre-gl: at a sub-1 fractional zoom in a wide container, constraining to the full world box\nhas been observed to leave `getZoom()` returning `null` permanently, after which every frame\nthrows from inside the peer's own matrix math and the canvas never paints again -- a blank map,\nwith nothing thrown at the call site to attribute it to. Going through this property applies\nthe same call, then checks the camera survived it and reverts if it did not, so the worst case\nis an unconstrained map plus a dev-mode warning rather than a blank one.","type":"LyraMapBounds | null","default":"null"},{"name":"renderWorldCopies","description":"Whether the constructed peer repeats the world horizontally. `undefined` leaves MapLibre's\nown default in force. Construction-only; set before the map is created.","type":"boolean | undefined"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"zoom","description":"Initial and controlled map zoom level.\n\nAttribute: `zoom`","type":"number","default":"2"}],"events":[{"name":"lr-map-click","description":"`detail: { lngLat, feature?, origin?, sourceId? }`. `feature` resolves against the choropleth fill *and* every applied `dataLayers` fill/line/circle/cluster layer, topmost first; `origin`/`sourceId` name where it came from. A hit on a clustered entry's aggregate circle reports `origin: 'cluster'` and carries MapLibre's `point_count`/`cluster_id` properties; a `kind: 'heatmap'` layer is never hit-tested, because MapLibre returns no features for a density surface.","type":"CustomEvent<{\n    readonly lngLat: readonly [number, number];\n    readonly feature: Feature | undefined;\n    /** Which layer `feature` was hit on, so a click is attributable when both a choropleth and\n     *  `dataLayers` are painted. `'cluster'` marks a hit on a clustered entry's aggregate circle,\n     *  whose `point_count`/`cluster_id` properties describe the group rather than one feature.\n     *  `undefined` whenever `feature` is. */\n    readonly origin: 'choropleth' | 'data-layer' | 'cluster' | undefined;\n    /** The authored `dataLayers[].sourceId` the hit belongs to; `undefined` for a choropleth hit\n     *  (which has only one possible source) and when nothing was hit. */\n    readonly sourceId: string | undefined;\n  }>"},{"name":"lr-map-legend-panel-toggle","description":"**Cancelable.** Fired once when the `legendCollapsible` disclosure is activated by pointer or by Enter/Space, carrying the immutable `detail: { open }` -- the proposed `legendOpen` value. It is the *panel's* disclosure, not a *category's* visibility, so it deliberately does not reuse `lr-map-legend-toggle`. `preventDefault()` is a real veto: `legendOpen` is not written, the rendered rows and the disclosure's `aria-expanded` do not change, which is what lets a host own the open state and write it itself. A programmatic `legendOpen` assignment reconciles without emitting anything, so a controlled host cannot loop.","type":"CustomEvent<LyraMapLegendPanelToggleDetail>"},{"name":"lr-map-legend-toggle","description":"**Cancelable.** Fired once when an interactive legend row is activated by pointer or by Enter/Space, carrying the immutable `detail: { value, visible, hiddenCategories }` -- the activated category key, its proposed visibility, and the complete proposed hidden set in the order it would be committed. `preventDefault()` is a real veto: `hiddenCategories` is not written, the row's `aria-pressed` does not change, the MapLibre paint is untouched, and nothing is announced, which is what lets a host own the set and write it itself. There is deliberately no second confirmation event: the committed state is `hiddenCategories`, which the host already observes, so a paired before/after vocabulary would be permanent public surface nobody asked for. A programmatic `hiddenCategories` assignment reconciles without emitting anything -- this event is a DOM-interaction proposal only.","type":"CustomEvent<LyraMapLegendToggleDetail>"},{"name":"lr-map-load","description":"Fired once the underlying maplibregl.Map loads.","type":"CustomEvent<null>"},{"name":"lr-map-marker-activate","description":"Fired once when an accepted declarative marker is activated by pointer/click or by Enter/Space. The immutable detail carries its normalized `id`, validated `lngLat`, accepted marker snapshot, and activation `source`.","type":"CustomEvent<LyraMapMarkerActivationDetail>"}]}},{"name":"lr-markdown","description":"`<lr-markdown>` — sanitized Markdown-to-HTML rendering (GFM tables,\nfenced code blocks, links, blockquotes) built on the optional peer\ndependencies `marked` (parsing) and `dompurify` (sanitizing), both\nlazy-loaded via `markdown-loader.ts` on first connect.\n\nRendering never ships unsanitized or broken markup silently:\n- If `marked` fails to load, or throws while parsing malformed input, the\n  component falls back to plain text (`white-space: pre-wrap`, no HTML\n  parsing at all) and fires `lr-render-error`.\n- If `htmlMode` is `sanitize` (the default) and `dompurify` fails to load, the\n  component *also* falls back to plain text + `lr-render-error` — it\n  never renders marked's raw HTML output when sanitization was requested\n  (or defaulted to) but is unavailable, even though `marked` itself loaded\n  fine.\n- If `htmlMode` is explicitly `trusted`, marked's raw output renders as-is\n  regardless of whether `dompurify` is installed — the consumer opted out\n  of sanitization, so `dompurify`'s absence is irrelevant to that path.\n\nThat same plain-text fallback rendering (`data-fallback` on the `content`\npart) is also, unconditionally and by default, a brief *transient* state on\nevery connect, not just a failure path: `connectedCallback()`'s dynamic\n`import()` of `marked`/`dompurify` (see `markdown-loader.ts`) is\nasynchronous, so the very first paint of any `<lr-markdown>` on a page\nshows plain text for at least one microtask — even when both peers are\nalready installed and load without error — until that import resolves and\na second render replaces it with the real Markdown output. Call `preloadMarkdown()` before\nmounting the first instance to avoid that window; later instances always adopt its settled\nshared dependency cache synchronously.\nDisconnecting and reconnecting while the shared load is pending invalidates the earlier\nconnection's settlement callback, so the current connection parses only once.\n\n`heading`/`code`/`blockquote`/`table`/`link`/`image` tokens are rendered\nthrough a `marked` renderer override that injects `part=\"...\"` attributes\ndirectly into the produced HTML — a single pass, not a second DOM walk\nafter insertion.\n\nFenced code blocks are syntax-highlighted via the same optional `shiki` peer `<lr-code-block>`\nuses (`highlightCode`, default `true` — a pure upgrade gated by whether `shiki` is installed at\nall, not a separate opt-in). `languages` supplies explicit grammars while the full loader\nremains the fallback. The very first render of any content is always plain\n(identical to today's output); highlighting arrives as an asynchronous upgrade one render later,\nonce shiki resolves. No highlighting is attempted while `streaming` is `true` — it applies once a\nstream settles, so there is no added per-chunk cost while content is still arriving.\n\nHighlighted blocks follow the page's resolved theme. Shiki emits both palettes at once, so\n`[part=\"content\"]` carries `data-dark-theme=\"true\"` whenever the component's own resolved\n`--lr-color-text` is lighter than its `--lr-color-surface`, and the stylesheet then paints each\ntoken from `--shiki-dark`/`--shiki-dark-bg` instead of the light inline color. It keys off the\nresolved tokens rather than `prefers-color-scheme`, so a consumer theming with\n`--lr-theme-color-*` independently of the OS setting gets the dark palette too -- the same\nmechanism `<lr-code-block>` uses for its own `[part=\"body\"]`.\n\nWhen `heading-anchors` is set, every rendered heading's slug (computed via the shared\nGitHub-slugger-style `Slugger`) is stamped as its `id`; `getHeadingTree()` computes that same\noutline on every parse regardless of `heading-anchors`, so a host can build a table of contents\neven while ids aren't in the DOM yet. `scrollToAnchor()` (from the adopted `DocumentAnchorTarget`\nmixin) resolves `fragment` anchors against that outline and `text-quote` anchors via\n`internal/text-quote.ts`'s shared scope/resolve helpers; `highlights` re-resolve by quote after\nevery render (never by node identity), so a highlight painted before a `streaming` update\nfinishes still finds its quote once the matching text arrives. Highlight painting uses\n`internal/text-highlights.ts`'s `acquireHighlightHandle()` -- the CSS Custom Highlight API where\nthe browser supports it (no DOM mutation at all), a `<mark>`-wrap fallback otherwise. Quote\nresolution indexes at most 1,000,000 code units/20,000 text nodes per content generation, bounds\neach quote/context field to 4,096 code units and each pass to 4,000,000 scanned code units, and\npaints at most 100 host highlights from a 1,000-entry candidate window while preserving the\nactive entry from the bounded host snapshot.\n\n`math` renders `$...$`/`$$...$$` TeX as MathML via the optional `katex` peer's\n`renderToString(tex, { output: 'mathml' })` -- MathML Core renders natively and accessibly in\nevergreen browsers with no extra stylesheet or webfont needing to cross the shadow boundary. A\nmissing `katex` peer renders the literal, unparsed TeX source (delimiters included) and fires one\n`lr-render-error`.\n\nMigrating a `<wa-markdown><script type=\"text/markdown\">...</script></wa-markdown>` usage: on\nconnect, a direct `<script type=\"text/markdown\">` child's text is read once and adopted as\n`content` (leading/trailing whitespace trimmed) -- but only while `content` has never been\nauthored (no `content` attribute/property set, including an explicitly empty one). Setting\n`content` -- then or later -- always wins; the script child is not re-read after connect, so\nmutating its text in place has no effect. Prefer the reactive `content` property directly for\nanything that updates after first connect.\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| `anchor-live-region` | The aria-hidden, non-live shadow mirror of the latest anchor-jump message. |\n| `blockquote` | Every rendered `<blockquote>`. |\n| `code-block` | Every rendered fenced/indented `<pre>`. |\n| `content` | The wrapper around the rendered (or plain-text fallback) output; respects `max-height`. |\n| `heading` | Every rendered `<h1>`–`<h6>` (shifted by `heading-offset`). |\n| `img` | Every rendered `<img>`. |\n| `inline-code` | Every rendered inline `<code>` span (backtick spans, not fenced blocks). |\n| `link` | Every rendered `<a>`. |\n| `list` | Every rendered `<ul>`/`<ol>`. |\n| `math` | A rendered inline or block math span (`data-display=\"inline\"\\|\"block\"`). |\n| `paragraph` | Every rendered `<p>`. |\n| `table` | Every rendered `<table>`. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-code-block-tab-size` (default: `2`) — Tab width for a rendered fenced/indented `code-block`. Deliberately the same token (and default) `lr-code-block` and `lr-code-editor` use, so a consumer sets one tab width for every code surface — it is declared here rather than inherited because `lr-code-block` is a sibling element, not an ancestor. A markdown code block wraps (`white-space: pre-wrap`) while `lr-code-block` does not, so the same value can render differently on a wrapped line, where tab stops restart.\n- `--lr-markdown-code-bg` (default: `var(--lr-color-brand-quiet)`) — Background shared by every inline `code` span and the fenced `code-block` surface.\n- `--lr-markdown-code-block-padding` (default: `var(--lr-space-s) var(--lr-space-m)`) — Padding of the fenced `code-block` surface.\n- `--lr-markdown-code-block-radius` (default: `var(--lr-radius)`) — Border radius of the fenced `code-block` surface.\n- `--lr-markdown-code-padding` (default: `var(--lr-size-0-125rem) var(--lr-size-0-3125rem)`) — Padding of an inline `code` span.\n- `--lr-markdown-code-radius` (default: `calc(var(--lr-radius) * 0.5)`) — Border radius of an inline `code` span.\n- `--lr-markdown-font-mono` (default: `var(--lr-font-mono)`) — Monospace family for rendered `<code>` inside `content`.\n- `--lr-markdown-highlight-accent-bg` (default: `var(--lr-color-brand-quiet)`) — Accent highlight fill.\n- `--lr-markdown-highlight-active-bg` (default: `var(--lr-color-brand-quiet)`) — Active highlight fill.\n- `--lr-markdown-highlight-active-outline-color` (default: `var(--lr-color-brand)`) — Active highlight outline.\n- `--lr-markdown-highlight-danger-bg` (default: `var(--lr-color-danger-quiet)`) — Danger highlight fill.\n- `--lr-markdown-highlight-neutral-bg` (default: `var(--lr-color-surface)`) — Neutral highlight fill.\n- `--lr-markdown-highlight-success-bg` (default: `var(--lr-color-success-quiet)`) — Success highlight fill.\n- `--lr-markdown-highlight-warning-bg` (default: `var(--lr-color-warning-quiet)`) — Warning highlight fill.\n- `--lr-markdown-max-height` (default: `none`) — Cap on `[part=\"content\"]`'s block size, past which the document scrolls internally. The `maxHeight` property sets this token inline on `[part=\"content\"]`.\n- `--lr-markdown-table-header-bg` (default: `var(--lr-color-brand-quiet)`) — Background of every rendered `[part=\"table\"]` header cell (`<th>`).","attributes":[{"name":"active-highlight-id","description":"Id of the currently active highlight, or null when none is active.\n\nType: `string | null`  \nDefault: `null`"},{"name":"content","description":"The Markdown source to render. Removing the attribute clears the document and its tab stop.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"gfm","description":"Enable GitHub-flavored Markdown (tables, strikethrough, autolinks, task lists).\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"heading-anchors","description":"Stamps a computed slug as `id` on every rendered heading. `getHeadingTree()` computes the\nsame slugs regardless of this property -- it only controls whether the `id` attribute is\nemitted into the rendered DOM. `false` (the default) preserves today's exact output.\n\nWhen `htmlMode` is `sanitize` (the default), a slug whose *value* collides with a real\n`document` property name (e.g. a heading literally titled \"Title\", \"Location\", or \"Forms\"\nslugs to `title`/`location`/`forms`) has its `id` silently stripped by DOMPurify's DOM-\nclobbering protection (`SANITIZE_DOM`) -- `getHeadingTree()` still reports that heading's slug\neither way, but `scrollToAnchor({ kind: 'fragment', id })` still resolves it correctly even\nwithout a DOM `id` present, via its own position-based fallback lookup.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"heading-offset","description":"Added to every rendered heading's source `token.depth` before emitting\n`<h${depth}>` — e.g. `heading-offset=\"2\"` renders a source `#` as\n`<h3>` and a source `##` as `<h4>`. The result is clamped to `[1, 6]`\n(a source `######` with a positive offset stays at `<h6>` rather than\noverflowing past the HTML heading levels; the floor at `1` is\ndefensive, since this property is meant to be additive-only). `0`\n(the default) preserves today's exact `<h${token.depth}>` output.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"highlight-code","description":"Syntax-highlights fenced code blocks via the same optional `shiki` peer `<lr-code-block>`\nuses. `true` (the default) upgrades every fenced block from plain `<pre><code>` once the peer\nis available -- a pure upgrade, not a behavior change gated on opt-in, since it's itself gated\ntransparently by whether `shiki` is installed at all (an app that never installs it sees\nbyte-identical output to today). Set `false` to keep plain output even when `shiki` is\ninstalled. No effect while `streaming` is `true` -- see that property's own doc.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"html-mode","description":"How authored raw HTML is handled: sanitized through DOMPurify (default), escaped as visible\ntext, or deliberately trusted. Independently of this, every markdown-native link/image\n`href`/`src` is always scheme-validated (`http:`/`https:`/`blob:`/`mailto:`, plus `data:` for\nimages) unless `htmlMode` is `trusted` -- a rejected scheme drops the anchor/image, rendering\nonly its text/alt content.\n\nType: `MarkdownHtmlMode`  \nDefault: `'sanitize'`","value":{"type":["'sanitize'","'escape'","'trusted'"]}},{"name":"internal-link-prefix","description":"When set, a rendered link whose `href` starts with this prefix is\ntreated as internal — its click is intercepted and reported via\n`lr-link-click` instead of navigating. Empty (the default) means\nevery link is treated as external.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"link-target","description":"`target` applied to every rendered `<a>`, with `rel=\"noopener\nnoreferrer\"` always added alongside it whenever a `target` is emitted.\n`'_blank'` (the default) preserves today's exact output. Set to `null`\n(or the empty string, e.g. via the `link-target=\"\"` attribute) to omit\n`target`/`rel` entirely, so rendered links open in the same tab.\n\nType: `string | null`  \nDefault: `'_blank'`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"math","description":"Renders `$...$`/`$$...$$` TeX via the optional `katex` peer, as MathML. `false` (the\ndefault) renders `$...$` literally, unparsed -- today's exact output.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"max-height","description":"A CSS length (e.g. `\"20rem\"`); once set, the rendered document scrolls internally past this\nheight instead of growing the page. Invalid values are ignored.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"streaming","description":"Signals that `content` is still arriving incrementally. While true, content renders as\nbounded-cost plain text and Markdown parsing resumes only for the final false transition;\nthe host remains `aria-busy=\"true\"` so assistive technology knows the rendered document is\nnot final.\nReflects so a consumer can also target `lr-markdown[streaming]`.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"tab-size","description":"Tab-stop width used when converting tabs in leading indentation to spaces before parsing.\nDefaults to `4`; non-finite values fall back to that default and finite values are truncated\nand clamped to `[1, 32]` before use. This does not change tabs inside ordinary text or the\nseparate `--lr-code-block-tab-size` used to display rendered code.\n\nType: `number`  \nDefault: `4`","value":{"type":["number"]}}],"js":{"properties":[{"name":"activeHighlightId","description":"Id of the currently active highlight, or null when none is active.\n\nAttribute: `active-highlight-id`","type":"string | null","default":"null"},{"name":"anchor","description":"Anchor or highlight id to resolve and scroll into view.","type":"LyraAnchor | string | null","default":"null"},{"name":"anchorKinds","description":"Anchor kinds resolved by both concrete Markdown tags.","type":"readonly LyraAnchorKind[]","default":"[ 'fragment', 'text-quote', ]","read-only":true},{"name":"content","description":"The Markdown source to render. Removing the attribute clears the document and its tab stop.\n\nAttribute: `content`","type":"string","default":"''"},{"name":"gfm","description":"Enable GitHub-flavored Markdown (tables, strikethrough, autolinks, task lists).\n\nAttribute: `gfm`","type":"boolean","default":"true"},{"name":"headingAnchors","description":"Stamps a computed slug as `id` on every rendered heading. `getHeadingTree()` computes the\nsame slugs regardless of this property -- it only controls whether the `id` attribute is\nemitted into the rendered DOM. `false` (the default) preserves today's exact output.\n\nWhen `htmlMode` is `sanitize` (the default), a slug whose *value* collides with a real\n`document` property name (e.g. a heading literally titled \"Title\", \"Location\", or \"Forms\"\nslugs to `title`/`location`/`forms`) has its `id` silently stripped by DOMPurify's DOM-\nclobbering protection (`SANITIZE_DOM`) -- `getHeadingTree()` still reports that heading's slug\neither way, but `scrollToAnchor({ kind: 'fragment', id })` still resolves it correctly even\nwithout a DOM `id` present, via its own position-based fallback lookup.\n\nAttribute: `heading-anchors`","type":"boolean","default":"false"},{"name":"headingOffset","description":"Added to every rendered heading's source `token.depth` before emitting\n`<h${depth}>` — e.g. `heading-offset=\"2\"` renders a source `#` as\n`<h3>` and a source `##` as `<h4>`. The result is clamped to `[1, 6]`\n(a source `######` with a positive offset stays at `<h6>` rather than\noverflowing past the HTML heading levels; the floor at `1` is\ndefensive, since this property is meant to be additive-only). `0`\n(the default) preserves today's exact `<h${token.depth}>` output.\n\nAttribute: `heading-offset`","type":"number","default":"0"},{"name":"highlightCode","description":"Syntax-highlights fenced code blocks via the same optional `shiki` peer `<lr-code-block>`\nuses. `true` (the default) upgrades every fenced block from plain `<pre><code>` once the peer\nis available -- a pure upgrade, not a behavior change gated on opt-in, since it's itself gated\ntransparently by whether `shiki` is installed at all (an app that never installs it sees\nbyte-identical output to today). Set `false` to keep plain output even when `shiki` is\ninstalled. No effect while `streaming` is `true` -- see that property's own doc.\n\nAttribute: `highlight-code`","type":"boolean","default":"true"},{"name":"highlights","description":"Highlights rendered by the document target. Reassign after mutation.","type":"LyraHighlight[]","default":"[]"},{"name":"htmlMode","description":"How authored raw HTML is handled: sanitized through DOMPurify (default), escaped as visible\ntext, or deliberately trusted. Independently of this, every markdown-native link/image\n`href`/`src` is always scheme-validated (`http:`/`https:`/`blob:`/`mailto:`, plus `data:` for\nimages) unless `htmlMode` is `trusted` -- a rejected scheme drops the anchor/image, rendering\nonly its text/alt content.\n\nAttribute: `html-mode`","type":"MarkdownHtmlMode","default":"'sanitize'"},{"name":"internalLinkPrefix","description":"When set, a rendered link whose `href` starts with this prefix is\ntreated as internal — its click is intercepted and reported via\n`lr-link-click` instead of navigating. Empty (the default) means\nevery link is treated as external.\n\nAttribute: `internal-link-prefix`","type":"string","default":"''"},{"name":"languages","description":"Same shape and purpose as `<lr-code-block>`'s own `languages` -- a fine-grained, explicit\nlanguage-grammar bundle scoping shiki's build output to just those grammars instead of its\nfull ~200-language bundle. Forwarded verbatim to `loadShikiHighlighterCore()`. Unset uses the\ndefault full-bundle loader, unchanged from how `<lr-code-block>` itself defaults.","type":"Readonly<Record<string, ShikiLanguageSource>> | undefined"},{"name":"linkTarget","description":"`target` applied to every rendered `<a>`, with `rel=\"noopener\nnoreferrer\"` always added alongside it whenever a `target` is emitted.\n`'_blank'` (the default) preserves today's exact output. Set to `null`\n(or the empty string, e.g. via the `link-target=\"\"` attribute) to omit\n`target`/`rel` entirely, so rendered links open in the same tab.\n\nAttribute: `link-target`","type":"string | null","default":"'_blank'"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"marked","description":"This instance's configurable parser, once the optional parser peer is available.","type":"LyraMarkedParser | undefined","read-only":true},{"name":"math","description":"Renders `$...$`/`$$...$$` TeX via the optional `katex` peer, as MathML. `false` (the\ndefault) renders `$...$` literally, unparsed -- today's exact output.\n\nAttribute: `math`","type":"boolean","default":"false"},{"name":"maxHeight","description":"A CSS length (e.g. `\"20rem\"`); once set, the rendered document scrolls internally past this\nheight instead of growing the page. Invalid values are ignored.\n\nAttribute: `max-height`","type":"string","default":"''"},{"name":"streaming","description":"Signals that `content` is still arriving incrementally. While true, content renders as\nbounded-cost plain text and Markdown parsing resumes only for the final false transition;\nthe host remains `aria-busy=\"true\"` so assistive technology knows the rendered document is\nnot final.\nReflects so a consumer can also target `lr-markdown[streaming]`.\n\nAttribute: `streaming`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"tabSize","description":"Tab-stop width used when converting tabs in leading indentation to spaces before parsing.\nDefaults to `4`; non-finite values fall back to that default and finite values are truncated\nand clamped to `[1, 32]` before use. This does not change tabs inside ordinary text or the\nseparate `--lr-code-block-tab-size` used to display rendered code.\n\nAttribute: `tab-size`","type":"number","default":"4"}],"events":[{"name":"lr-anchor-result","description":"Fired after an `anchor` property assignment or a `scrollToAnchor()` call is applied. `detail: { found }`.","type":"CustomEvent<AnchorResultDetail>"},{"name":"lr-content-settled","description":"Fired whenever newly-rendered content actually reaches `[part=\"content\"]` -- including a transient plain-text fallback frame and a later async syntax-highlight upgrade, not only a final parsed render. `detail: null`. Composed and bubbling, so a host composing this element inside a free-form container (e.g. `<lr-thinking-panel>`'s default slot) can listen for it to drive auto-scroll; see that component's own docs.","type":"CustomEvent<null>"},{"name":"lr-highlight-activate","description":"A painted `text-quote` highlight was clicked. `detail: { highlightId }`.","type":"CustomEvent<HighlightActivateDetail>"},{"name":"lr-link-click","description":"Fired (and the click prevented) when a rendered link's `href` starts with `internal-link-prefix`. `detail: { href: string }`. Ordinary external links navigate normally (in `link-target`) and never fire this event.","type":"CustomEvent<{ href: string }>"},{"name":"lr-render-error","description":"Fired whenever rendering falls back to plain text, or `math` is set but the `katex` peer isn't installed. `detail: { error: unknown }`.","type":"CustomEvent<{ error: unknown }>"},{"name":"lr-text-select","description":"Fired on selection end inside the rendered content. `detail: { text, anchor, rects }`; `anchor` is a `text-quote` `LyraAnchor` scoped to the rendered content, or `null` if the selection couldn't be anchored.","type":"CustomEvent<TextSelectDetail>"}]}},{"name":"lr-markdown-core","description":"`<lr-markdown-core>` — a build-lean variant of `<lr-markdown>` for a consumer whose\n`languages` map already covers every language it will ever render. Every other capability (GFM\ntables, fenced code blocks, links, blockquotes, heading anchors, text-quote highlights, math) is\nidentical to `<lr-markdown>` -- only fenced-code-block highlighting differs: this component's\nown module never textually contains a call to (or import of) `loadShikiHighlighter` (the\n~200-language default dynamic-import table `<lr-markdown>` can call). A consumer\nimporting this entry point instead of `markdown.js` gets a genuinely shiki-full-table-free\nbuild. A fenced block whose language isn't a key in `languages` always renders the plain-text\nfallback -- there is no default/full-table highlighter here to fall back to, mirroring\n`<lr-code-block-core>`'s identical contract for the sibling component.\n\nBuilt on the optional peer dependencies `marked` (parsing) and `dompurify` (sanitizing), both\nlazy-loaded via `markdown-loader.ts` on first connect.\n\nRendering never ships unsanitized or broken markup silently:\n- If `marked` fails to load, or throws while parsing malformed input, the\n  component falls back to plain text (`white-space: pre-wrap`, no HTML\n  parsing at all) and fires `lr-render-error`.\n- If `htmlMode` is `sanitize` (the default) and `dompurify` fails to load, the\n  component *also* falls back to plain text + `lr-render-error` — it\n  never renders marked's raw HTML output when sanitization was requested\n  (or defaulted to) but is unavailable, even though `marked` itself loaded\n  fine.\n- If `htmlMode` is explicitly `trusted`, marked's raw output renders as-is\n  regardless of whether `dompurify` is installed — the consumer opted out\n  of sanitization, so `dompurify`'s absence is irrelevant to that path.\n\nThat same plain-text fallback rendering (`data-fallback` on the `content`\npart) is also, unconditionally and by default, a brief *transient* state on\nevery connect, not just a failure path: `connectedCallback()`'s dynamic\n`import()` of `marked`/`dompurify` (see `markdown-loader.ts`) is\nasynchronous, so the very first paint of any `<lr-markdown>` on a page\nshows plain text for at least one microtask — even when both peers are\nalready installed and load without error — until that import resolves and\na second render replaces it with the real Markdown output. Call `preloadMarkdown()` before\nmounting the first instance to avoid that window; later instances always adopt its settled\nshared dependency cache synchronously.\nDisconnecting and reconnecting while the shared load is pending invalidates the earlier\nconnection's settlement callback, so the current connection parses only once.\n\n`heading`/`code`/`blockquote`/`table`/`link`/`image` tokens are rendered\nthrough a `marked` renderer override that injects `part=\"...\"` attributes\ndirectly into the produced HTML — a single pass, not a second DOM walk\nafter insertion.\n\nFenced code blocks are syntax-highlighted via the same fine-grained `shiki/core` recipe\n`<lr-code-block-core>` uses (`highlightCode`, default `true` — gated by whether a fenced\nblock's language is a key in `languages`, since there is no default highlighter here to gate on\n\"is shiki installed at all\"). The very first render of any content is always plain (identical to\n`<lr-markdown>`'s own output); highlighting arrives as an asynchronous upgrade one render\nlater, once the fine-grained highlighter resolves. No highlighting is attempted while\n`streaming` is `true` — it applies once a stream settles, so there is no added per-chunk cost\nwhile content is still arriving.\n\nHighlighted blocks follow the page's resolved theme. Shiki emits both palettes at once, so\n`[part=\"content\"]` carries `data-dark-theme=\"true\"` whenever the component's own resolved\n`--lr-color-text` is lighter than its `--lr-color-surface`, and the stylesheet then paints each\ntoken from `--shiki-dark`/`--shiki-dark-bg` instead of the light inline color. It keys off the\nresolved tokens rather than `prefers-color-scheme`, so a consumer theming with\n`--lr-theme-color-*` independently of the OS setting gets the dark palette too -- the same\nmechanism `<lr-code-block>` uses for its own `[part=\"body\"]`.\n\nWhen `heading-anchors` is set, every rendered heading's slug (computed via the shared\nGitHub-slugger-style `Slugger`) is stamped as its `id`; `getHeadingTree()` computes that same\noutline on every parse regardless of `heading-anchors`, so a host can build a table of contents\neven while ids aren't in the DOM yet. `scrollToAnchor()` (from the adopted `DocumentAnchorTarget`\nmixin) resolves `fragment` anchors against that outline and `text-quote` anchors via\n`internal/text-quote.ts`'s shared scope/resolve helpers; `highlights` re-resolve by quote after\nevery render (never by node identity), so a highlight painted before a `streaming` update\nfinishes still finds its quote once the matching text arrives. Highlight painting uses\n`internal/text-highlights.ts`'s `acquireHighlightHandle()` -- the CSS Custom Highlight API where\nthe browser supports it (no DOM mutation at all), a `<mark>`-wrap fallback otherwise. Quote\nresolution indexes at most 1,000,000 code units/20,000 text nodes per content generation, bounds\neach quote/context field to 4,096 code units and each pass to 4,000,000 scanned code units, and\npaints at most 100 host highlights from a 1,000-entry candidate window while preserving the\nactive entry from the bounded host snapshot.\n\n`math` renders `$...$`/`$$...$$` TeX as MathML via the optional `katex` peer's\n`renderToString(tex, { output: 'mathml' })` -- MathML Core renders natively and accessibly in\nevergreen browsers with no extra stylesheet or webfont needing to cross the shadow boundary. A\nmissing `katex` peer renders the literal, unparsed TeX source (delimiters included) and fires one\n`lr-render-error`.\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| `anchor-live-region` | The aria-hidden, non-live shadow mirror of the latest anchor-jump message. |\n| `blockquote` | Every rendered `<blockquote>`. |\n| `code-block` | Every rendered fenced/indented `<pre>`. |\n| `content` | The wrapper around the rendered (or plain-text fallback) output; respects `max-height`. |\n| `heading` | Every rendered `<h1>`–`<h6>` (shifted by `heading-offset`). |\n| `img` | Every rendered `<img>`. |\n| `inline-code` | Every rendered inline `<code>` span (backtick spans, not fenced blocks). |\n| `link` | Every rendered `<a>`. |\n| `list` | Every rendered `<ul>`/`<ol>`. |\n| `math` | A rendered inline or block math span (`data-display=\"inline\"\\|\"block\"`). |\n| `paragraph` | Every rendered `<p>`. |\n| `table` | Every rendered `<table>`. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-code-block-tab-size` (default: `2`) — Tab width for a rendered fenced/indented `code-block`. Deliberately the same token (and default) `lr-code-block` and `lr-code-editor` use, so a consumer sets one tab width for every code surface — it is declared here rather than inherited because `lr-code-block` is a sibling element, not an ancestor. A markdown code block wraps (`white-space: pre-wrap`) while `lr-code-block` does not, so the same value can render differently on a wrapped line, where tab stops restart.\n- `--lr-markdown-code-bg` (default: `var(--lr-color-brand-quiet)`) — Background shared by every inline `code` span and the fenced `code-block` surface.\n- `--lr-markdown-code-block-padding` (default: `var(--lr-space-s) var(--lr-space-m)`) — Padding of the fenced `code-block` surface.\n- `--lr-markdown-code-block-radius` (default: `var(--lr-radius)`) — Border radius of the fenced `code-block` surface.\n- `--lr-markdown-code-padding` (default: `var(--lr-size-0-125rem) var(--lr-size-0-3125rem)`) — Padding of an inline `code` span.\n- `--lr-markdown-code-radius` (default: `calc(var(--lr-radius) * 0.5)`) — Border radius of an inline `code` span.\n- `--lr-markdown-font-mono` (default: `var(--lr-font-mono)`) — Monospace family for rendered `<code>` inside `content`.\n- `--lr-markdown-highlight-accent-bg` (default: `var(--lr-color-brand-quiet)`) — Accent highlight fill.\n- `--lr-markdown-highlight-active-bg` (default: `var(--lr-color-brand-quiet)`) — Active highlight fill.\n- `--lr-markdown-highlight-active-outline-color` (default: `var(--lr-color-brand)`) — Active highlight outline.\n- `--lr-markdown-highlight-danger-bg` (default: `var(--lr-color-danger-quiet)`) — Danger highlight fill.\n- `--lr-markdown-highlight-neutral-bg` (default: `var(--lr-color-surface)`) — Neutral highlight fill.\n- `--lr-markdown-highlight-success-bg` (default: `var(--lr-color-success-quiet)`) — Success highlight fill.\n- `--lr-markdown-highlight-warning-bg` (default: `var(--lr-color-warning-quiet)`) — Warning highlight fill.\n- `--lr-markdown-max-height` (default: `none`) — Cap on `[part=\"content\"]`'s block size, past which the document scrolls internally. The `maxHeight` property sets this token inline on `[part=\"content\"]`.\n- `--lr-markdown-table-header-bg` (default: `var(--lr-color-brand-quiet)`) — Background of every rendered `[part=\"table\"]` header cell (`<th>`).","attributes":[{"name":"active-highlight-id","description":"Id of the currently active highlight, or null when none is active.\n\nType: `string | null`  \nDefault: `null`"},{"name":"content","description":"The Markdown source to render. Removing the attribute clears the document and its tab stop.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"gfm","description":"Enable GitHub-flavored Markdown (tables, strikethrough, autolinks, task lists).\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"heading-anchors","description":"Stamps a computed slug as `id` on every rendered heading. `getHeadingTree()` computes the\nsame slugs regardless of this property -- it only controls whether the `id` attribute is\nemitted into the rendered DOM. `false` (the default) preserves today's exact output.\n\nWhen `htmlMode` is `sanitize` (the default), a slug whose *value* collides with a real\n`document` property name (e.g. a heading literally titled \"Title\", \"Location\", or \"Forms\"\nslugs to `title`/`location`/`forms`) has its `id` silently stripped by DOMPurify's DOM-\nclobbering protection (`SANITIZE_DOM`) -- `getHeadingTree()` still reports that heading's slug\neither way, but `scrollToAnchor({ kind: 'fragment', id })` still resolves it correctly even\nwithout a DOM `id` present, via its own position-based fallback lookup.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"heading-offset","description":"Added to every rendered heading's source `token.depth` before emitting\n`<h${depth}>` — e.g. `heading-offset=\"2\"` renders a source `#` as\n`<h3>` and a source `##` as `<h4>`. The result is clamped to `[1, 6]`\n(a source `######` with a positive offset stays at `<h6>` rather than\noverflowing past the HTML heading levels; the floor at `1` is\ndefensive, since this property is meant to be additive-only). `0`\n(the default) preserves today's exact `<h${token.depth}>` output.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"highlight-code","description":"Syntax-highlights fenced code blocks through the fine-grained Shiki core loader when\n`languages` supplies the matching grammar. The empty default language map means no fenced\nblock is highlighted; set `false` to keep plain output even when grammars are supplied. No\neffect while `streaming` is `true` -- see that property's own doc.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"html-mode","description":"How authored raw HTML is handled: sanitized through DOMPurify (default), escaped as visible\ntext, or deliberately trusted. Independently of this, every markdown-native link/image\n`href`/`src` is always scheme-validated (`http:`/`https:`/`blob:`/`mailto:`, plus `data:` for\nimages) unless `htmlMode` is `trusted` -- a rejected scheme drops the anchor/image, rendering\nonly its text/alt content.\n\nType: `MarkdownHtmlMode`  \nDefault: `'sanitize'`","value":{"type":["'sanitize'","'escape'","'trusted'"]}},{"name":"internal-link-prefix","description":"When set, a rendered link whose `href` starts with this prefix is\ntreated as internal — its click is intercepted and reported via\n`lr-link-click` instead of navigating. Empty (the default) means\nevery link is treated as external.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"link-target","description":"`target` applied to every rendered `<a>`, with `rel=\"noopener\nnoreferrer\"` always added alongside it whenever a `target` is emitted.\n`'_blank'` (the default) preserves today's exact output. Set to `null`\n(or the empty string, e.g. via the `link-target=\"\"` attribute) to omit\n`target`/`rel` entirely, so rendered links open in the same tab.\n\nType: `string | null`  \nDefault: `'_blank'`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"math","description":"Renders `$...$`/`$$...$$` TeX via the optional `katex` peer, as MathML. `false` (the\ndefault) renders `$...$` literally, unparsed -- today's exact output.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"max-height","description":"A CSS length (e.g. `\"20rem\"`); once set, the rendered document scrolls internally past this\nheight instead of growing the page. Invalid values are ignored.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"streaming","description":"Signals that `content` is still arriving incrementally. While true, content renders as\nbounded-cost plain text and Markdown parsing resumes only for the final false transition;\nthe host remains `aria-busy=\"true\"` so assistive technology knows the rendered document is\nnot final.\nReflects so a consumer can also target `lr-markdown-core[streaming]`.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"tab-size","description":"Tab-stop width used to expand tabs in leading indentation before parsing. Finite values are\ntruncated and clamped to `[1, 32]`; non-finite values fall back to `4`. This is separate from\n`--lr-code-block-tab-size`, which controls the visual width of tabs in rendered code.\n\nType: `number`  \nDefault: `4`","value":{"type":["number"]}}],"js":{"properties":[{"name":"activeHighlightId","description":"Id of the currently active highlight, or null when none is active.\n\nAttribute: `active-highlight-id`","type":"string | null","default":"null"},{"name":"anchor","description":"Anchor or highlight id to resolve and scroll into view.","type":"LyraAnchor | string | null","default":"null"},{"name":"anchorKinds","description":"Anchor kinds resolved by both concrete Markdown tags.","type":"readonly LyraAnchorKind[]","default":"[ 'fragment', 'text-quote', ]","read-only":true},{"name":"content","description":"The Markdown source to render. Removing the attribute clears the document and its tab stop.\n\nAttribute: `content`","type":"string","default":"''"},{"name":"gfm","description":"Enable GitHub-flavored Markdown (tables, strikethrough, autolinks, task lists).\n\nAttribute: `gfm`","type":"boolean","default":"true"},{"name":"headingAnchors","description":"Stamps a computed slug as `id` on every rendered heading. `getHeadingTree()` computes the\nsame slugs regardless of this property -- it only controls whether the `id` attribute is\nemitted into the rendered DOM. `false` (the default) preserves today's exact output.\n\nWhen `htmlMode` is `sanitize` (the default), a slug whose *value* collides with a real\n`document` property name (e.g. a heading literally titled \"Title\", \"Location\", or \"Forms\"\nslugs to `title`/`location`/`forms`) has its `id` silently stripped by DOMPurify's DOM-\nclobbering protection (`SANITIZE_DOM`) -- `getHeadingTree()` still reports that heading's slug\neither way, but `scrollToAnchor({ kind: 'fragment', id })` still resolves it correctly even\nwithout a DOM `id` present, via its own position-based fallback lookup.\n\nAttribute: `heading-anchors`","type":"boolean","default":"false"},{"name":"headingOffset","description":"Added to every rendered heading's source `token.depth` before emitting\n`<h${depth}>` — e.g. `heading-offset=\"2\"` renders a source `#` as\n`<h3>` and a source `##` as `<h4>`. The result is clamped to `[1, 6]`\n(a source `######` with a positive offset stays at `<h6>` rather than\noverflowing past the HTML heading levels; the floor at `1` is\ndefensive, since this property is meant to be additive-only). `0`\n(the default) preserves today's exact `<h${token.depth}>` output.\n\nAttribute: `heading-offset`","type":"number","default":"0"},{"name":"highlightCode","description":"Syntax-highlights fenced code blocks through the fine-grained Shiki core loader when\n`languages` supplies the matching grammar. The empty default language map means no fenced\nblock is highlighted; set `false` to keep plain output even when grammars are supplied. No\neffect while `streaming` is `true` -- see that property's own doc.\n\nAttribute: `highlight-code`","type":"boolean","default":"true"},{"name":"highlights","description":"Highlights rendered by the document target. Reassign after mutation.","type":"LyraHighlight[]","default":"[]"},{"name":"htmlMode","description":"How authored raw HTML is handled: sanitized through DOMPurify (default), escaped as visible\ntext, or deliberately trusted. Independently of this, every markdown-native link/image\n`href`/`src` is always scheme-validated (`http:`/`https:`/`blob:`/`mailto:`, plus `data:` for\nimages) unless `htmlMode` is `trusted` -- a rejected scheme drops the anchor/image, rendering\nonly its text/alt content.\n\nAttribute: `html-mode`","type":"MarkdownHtmlMode","default":"'sanitize'"},{"name":"internalLinkPrefix","description":"When set, a rendered link whose `href` starts with this prefix is\ntreated as internal — its click is intercepted and reported via\n`lr-link-click` instead of navigating. Empty (the default) means\nevery link is treated as external.\n\nAttribute: `internal-link-prefix`","type":"string","default":"''"},{"name":"languages","description":"Grammar definitions this instance can highlight, e.g. `{ json: jsonGrammar }` (import from\n`shiki/langs/<name>.mjs`), or a lazy loader per key, e.g.\n`{ bash: () => import('@shikijs/langs/bash') }` -- called (at most once per key, memoized)\nthe first time a fenced block actually requests that language -- same shape as\n`<lr-code-block-core>`'s own `languages`. This component has no default/full-table\nhighlighter to fall back to -- a fenced block whose language isn't a key here always renders\nthe plain-text fallback, and so does a key whose lazy loader rejects. Empty (the default)\nnever highlights anything.","type":"Readonly<Record<string, ShikiLanguageSource>> | undefined","default":"{}"},{"name":"linkTarget","description":"`target` applied to every rendered `<a>`, with `rel=\"noopener\nnoreferrer\"` always added alongside it whenever a `target` is emitted.\n`'_blank'` (the default) preserves today's exact output. Set to `null`\n(or the empty string, e.g. via the `link-target=\"\"` attribute) to omit\n`target`/`rel` entirely, so rendered links open in the same tab.\n\nAttribute: `link-target`","type":"string | null","default":"'_blank'"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"marked","description":"This instance's configurable parser, once the optional parser peer is available.","type":"LyraMarkedParser | undefined","read-only":true},{"name":"math","description":"Renders `$...$`/`$$...$$` TeX via the optional `katex` peer, as MathML. `false` (the\ndefault) renders `$...$` literally, unparsed -- today's exact output.\n\nAttribute: `math`","type":"boolean","default":"false"},{"name":"maxHeight","description":"A CSS length (e.g. `\"20rem\"`); once set, the rendered document scrolls internally past this\nheight instead of growing the page. Invalid values are ignored.\n\nAttribute: `max-height`","type":"string","default":"''"},{"name":"streaming","description":"Signals that `content` is still arriving incrementally. While true, content renders as\nbounded-cost plain text and Markdown parsing resumes only for the final false transition;\nthe host remains `aria-busy=\"true\"` so assistive technology knows the rendered document is\nnot final.\nReflects so a consumer can also target `lr-markdown-core[streaming]`.\n\nAttribute: `streaming`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"tabSize","description":"Tab-stop width used to expand tabs in leading indentation before parsing. Finite values are\ntruncated and clamped to `[1, 32]`; non-finite values fall back to `4`. This is separate from\n`--lr-code-block-tab-size`, which controls the visual width of tabs in rendered code.\n\nAttribute: `tab-size`","type":"number","default":"4"}],"events":[{"name":"lr-anchor-result","description":"Fired after an `anchor` property assignment or a `scrollToAnchor()` call is applied. `detail: { found }`.","type":"CustomEvent<AnchorResultDetail>"},{"name":"lr-content-settled","description":"Fired whenever newly-rendered content actually reaches `[part=\"content\"]` -- including a transient plain-text fallback frame and a later async syntax-highlight upgrade, not only a final parsed render. `detail: null`. Composed and bubbling, so a host composing this element inside a free-form container (e.g. `<lr-thinking-panel>`'s default slot) can listen for it to drive auto-scroll; see that component's own docs.","type":"CustomEvent<null>"},{"name":"lr-highlight-activate","description":"A painted `text-quote` highlight was clicked. `detail: { highlightId }`.","type":"CustomEvent<HighlightActivateDetail>"},{"name":"lr-link-click","description":"Fired (and the click prevented) when a rendered link's `href` starts with `internal-link-prefix`. `detail: { href: string }`. Ordinary external links navigate normally (in `link-target`) and never fire this event.","type":"CustomEvent<{ href: string }>"},{"name":"lr-render-error","description":"Fired whenever rendering falls back to plain text, or `math` is set but the `katex` peer isn't installed. `detail: { error: unknown }`.","type":"CustomEvent<{ error: unknown }>"},{"name":"lr-text-select","description":"Fired on selection end inside the rendered content. `detail: { text, anchor, rects }`; `anchor` is a `text-quote` `LyraAnchor` scoped to the rendered content, or `null` if the selection couldn't be anchored.","type":"CustomEvent<TextSelectDetail>"}]}},{"name":"lr-mcp-app","description":"`<lr-mcp-app>` — hosts an MCP App-style executable UI resource in a uniquely-origin sandbox.\nInline resources receive a trusted leading CSP meta before any caller-controlled HTML token, so\ncomments or script strings cannot redirect policy insertion away from the parsed document head.\nRemote resources accept only relative and HTTP(S) document URLs and never send a referrer.\nThe frame can request tools, messages, links, logs, and resizing only through typed events;\nthe component never performs those external actions itself.\nResource records and nested CSP/metadata collections are bounded clone-owned readonly\nsnapshots. Create and reassign a new resource record after changes.\n\n---\n\n**Component metadata**\n\n- Status: `stable`\n- Since: `7.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 sandbox frame wrapper. |\n| `error` | The invalid-resource error. |\n| `frame` | The sandboxed iframe. |\n| `loading` | The pre-load status. |","attributes":[{"name":"aria-label","description":"Programmatic iframe title when no authored host `aria-label` attribute is present. An empty\nvalue cannot leave the executable frame unnamed.\n\nType: `string | null`  \nDefault: `null`"},{"name":"height","description":"Type: `number`  \nDefault: `320`","value":{"type":["number"]}},{"name":"label","description":"Purpose-specific iframe title used ahead of the resource title and localized fallback.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max-height","description":"Type: `number`  \nDefault: `800`","value":{"type":["number"]}}],"js":{"properties":[{"name":"accessibleLabel","description":"Programmatic iframe title when no authored host `aria-label` attribute is present. An empty\nvalue cannot leave the executable frame unnamed.\n\nAttribute: `aria-label`","type":"string | null","default":"null"},{"name":"height","description":"Attribute: `height`","type":"number","default":"320"},{"name":"label","description":"Purpose-specific iframe title used ahead of the resource title and localized fallback.\n\nAttribute: `label`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"maxHeight","description":"Attribute: `max-height`","type":"number","default":"800"},{"name":"resource","description":"Clone-owned resource snapshot. Reassign a new record after changing its CSP collections.","type":"McpAppResource | null","default":"null"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-mcp-log","description":"The frame sent a diagnostic value.","type":"CustomEvent<{ level: string; value: unknown }>"},{"name":"lr-mcp-open-link","description":"The frame requested navigation; the host decides whether to honor it.","type":"CustomEvent<{ href: string }>"},{"name":"lr-mcp-ready","description":"The frame loaded. `detail: { uri }`.","type":"CustomEvent<{ uri: string }>"},{"name":"lr-mcp-resize","description":"The frame requested a clamped height.","type":"CustomEvent<{ height: number }>"},{"name":"lr-mcp-send-message","description":"The frame requested a conversation message.","type":"CustomEvent<{ message: unknown }>"},{"name":"lr-mcp-tool-call","description":"The frame requested a tool. `detail: { requestId?, name, args, frameGeneration }`. `frameGeneration` is an opaque id for the frame that raised the request; hand it back in `postToolResult()`'s options so an asynchronous reply arriving after the frame changes is dropped rather than delivered into the unrelated app now mounted.","type":"CustomEvent<McpAppToolCallDetail>"}]}},{"name":"lr-media-card","description":"`<lr-media-card>` — a lightweight inline preview for one already-sent,\nalready-available attachment inside a rendered chat message body (e.g.\nplugged into `<lr-chat-message>`'s `attachments` slot, or embedded\ndirectly by a markdown/message renderer). Distinct from two other,\nsimilarly-named components in this family: `<lr-document-preview>` is a\nfuller viewer with header chrome and an async server-side-conversion\nstate machine (`status=\"converting\"`), and `<lr-attachment-chip>` is a\npre-send queued-file chip with upload progress. This component has\nneither concern — it only ever shows a `src` that's already final.\n\n**Format dispatch.** `kind` selects `'image'` (a plain `<img>`), `'video'`\n(a plain `<video controls>`), or `'file'` (an icon + filename chip with a\ndownload/open affordance). Leave `kind` unset to auto-detect from\n`mime-type` (`image/*` / `video/*` / anything else -> `'file'`);\nexplicitly setting `kind` always wins over detection.\n\n**Safe-URL checking.** `src` is validated before it's ever assigned to an\n`<img>`/`<video>` `src` or an `<a href>` — only `http:`/`https:`/`blob:`\n(plus `data:` for a *media* `src` only) or a scheme-relative/relative URL\nwith no scheme at all pass; anything else (`javascript:`, `vbscript:`,\nand similarly suspicious schemes) is rejected. Internal sink-specific\nvalidators explain why `data:` gets two different answers depending on\nwhere it is used. An `image`/`video` `kind` whose `src` fails the\nmedia-src check falls back to the generic file-chip rendering — this is\nthe \"plain preview unavailable state\" a dangerous URL degrades to, rather\nthan ever reaching a real media/anchor sink. That fallback also re-checks\n`src` against the stricter href allowlist for its own download affordance,\nbut since the href allowlist is a strict subset of the media-src allowlist,\nthat re-check can only ever change the outcome for a direct/auto-detected\n`kind=\"file\"` `src` — an `image`/`video` `src` that already failed the\nwider media-src check necessarily fails the narrower href check too, so\nthe fallback for those two kinds is always the plain, unclickable `span`.\n\n**The `video` case renders its open affordance separately from `base`.**\n`image`/`file` wrap their *entire* card in one native `<button>`/`<a>` —\nsafe because an `<img>` and a plain icon+text chip have no interactive\ncontent of their own to conflict with. A `<video controls>` element is\nitself interactive content (its own play/seek/volume controls), and HTML\nforbids nesting interactive content inside a `<button>`/`<a>` — doing so\nanyway would also make every click on the video's own controls bubble up\nand spuriously fire `lr-media-open`. So for `kind=\"video\"`, `base` is a plain,\nnon-interactive wrapper around `[part=\"media\"]`, and a small separate\n`[part=\"open-button\"]` (not one of this component's originally-scoped\nparts, added as the \"explicit view/open affordance\" the class is free to\nprovide) is the thing that actually fires `lr-media-open`.\n\n**Navigation.** This component never navigates on its own for `image`/\n`video` — activating the card only fires noncancelable `lr-media-open`; a host decides what\n\"open\" means (a lightbox, a new tab, whatever). The `file`-chip case is\nthe one exception: when `src` passes the (stricter) href safety check, the\nchip is a real `<a href download>` so a bare drop-in still does something\nuseful — but `lr-before-media-download` fires first and is `cancelable`; a host that\ncalls `preventDefault()` on it suppresses that default download/open so it\ncan substitute its own handling instead.\n\n**Pressed-state theme controls.** `--lr-media-card-active-border-color`\nand `--lr-media-card-active-bg` retint only an image/file card while it is\npressed. They are resolved in the state rule, rather than declared on the\nhost, so a conversation or attachment-list ancestor can theme every card\nwithout muting its own values.\n\n**Accessible action name.** A declarative host `aria-label` remains on the\nhost as the component's overall name; it is not cloned onto a second\nsemantic owner. The actionable button or link keeps a localized,\npurpose-specific name derived from filename/alt/kind. A property-only\n`accessibleLabel` assignment can name that internal action when no host\nlabel is present. Neither path replaces image alt text or the video\ncontrol's own purpose label, and an explicitly empty host name does not\nleave the still-interactive nested action unnamed.\n\n**Decorative images.** `alt` is optional rather than empty-by-default, so\n`alt=\"\"` -- the HTML idiom for a purely decorative image -- reaches the\nrendered `<img>` verbatim instead of collapsing into the unset case and\npicking up a generated description. Leaving `alt` off keeps the\n`filename`-then-generic fallback. The `<video>` label is deliberately\noutside that carve-out: an empty accessible name would leave an\ninteractive player unnamed rather than mark it decorative.\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 root interactive/container element. A `<button>` for `kind=\"image\"`, a plain wrapper `<div>` for `kind=\"video\"`, and either an `<a>` (when `src` passes the href safety check) or a plain `<span>` (otherwise) for the `file`-chip fallback. |\n| `file-icon` | The generic file glyph, shown only in the file-chip fallback. |\n| `filename` | The filename text, shown only in the file-chip fallback. |\n| `media` | The `<img>` or `<video>` element. |\n| `open-button` | The explicit \"open\" affordance rendered next to `[part=\"media\"]` for `kind=\"video\"` only — see the class doc. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-media-card-active-bg` (default: `color-mix(in oklab, var(--lr-color-surface), var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Pressed background color for image/file card actions. **Chrome escape hatch.** `frame=\"plain\"` drops `[part=\"base\"]`'s border, background, padding, and corner radius — for a dense list/feed of cards (this component's own documented primary use case) where the surrounding container already provides its own separation, so cards don't double up on chrome. `frame` is the library-wide name for this container treatment.\n- `--lr-media-card-active-border-color` (default: `color-mix(in oklab, var(--lr-color-brand), var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Pressed border color for image/file card actions.\n- `--lr-media-card-bg` (default: `var(--lr-color-surface)`) — Background of the RESTING `frame=\"card\"` chrome, the companion to the pressed state's `--lr-media-card-active-bg`. `frame=\"plain\"` still drops the fill entirely.\n- `--lr-media-card-max-height` (default: `var(--lr-size-20rem)`) — Cap on the block size of the `<img>`/`<video>` in `[part=\"media\"]`.","attributes":[{"name":"alt","description":"Alt text for the image case (and reused as a video label fallback). Unset falls back to\n`filename`, then a generic per-kind description; explicitly `\"\"` marks the image decorative,\nmatching `<lr-image-viewer>`/`<lr-document-preview>`. The `<video>` label is deliberately\noutside that carve-out: an empty accessible name would leave an interactive player unnamed\nrather than mark it decorative, so an empty `alt` still falls through there.\n\nType: `string | undefined`"},{"name":"aria-current","description":"Current-item state forwarded reactively onto whichever control this card renders, anchor included (`aria-current` is global): `page`, `step`, `location`, `date`, `time`, `true` or `false`.\n\nType: `string | null`  \nDefault: `null`"},{"name":"aria-label","description":"Accessible-name input. A declarative `aria-label` names the host; a property-only assignment\nnames the internal action when no host label is present. Nested actions otherwise keep a\nlocalized purpose name derived from `filename`, `alt`, or the resolved media kind. An\nexplicit empty string is equivalent to the unset `null` default -- both fall through to the\ngenerated purpose-specific name.\n\nType: `string | null`  \nDefault: `null`"},{"name":"aria-pressed","description":"Toggle state forwarded reactively onto this card's action when that action is a BUTTON (`kind=\"image\"`'s `base`, or `kind=\"video\"`'s `open-button`): `true`, `false` or `mixed`. Anything else is ignored rather than passed through. The file chip's anchor does not receive it -- `link` has no pressed state, and asserting one there is an ARIA conformance failure, not a nicety.\n\nType: `string | null`  \nDefault: `null`"},{"name":"disabled","description":"Turns off this card's OWN action: the image button and the video `open-button` render\n`disabled`, a safe file chip's anchor loses its `href` and `download` (so it genuinely cannot\nfetch rather than merely claiming `aria-disabled` on a live link) and leaves the tab order,\n`lr-media-open`/`lr-before-media-download` stop firing from every path including `click()`,\nand the affordance paints at `--lr-opacity-disabled` with a `not-allowed` cursor.\n\nDeliberately does NOT reach into the `kind=\"video\"` player: `<video controls>` is media\ncontent with its own native transport, not this card's action, and silencing playback is not\nwhat \"the open affordance is unavailable\" means. An unsafe-`src` file chip has no action at\nall, so `disabled` leaves it byte-identical.\n\nLike `<lr-icon-button>`, this component is not form-associated, so an ancestor\n`<fieldset disabled>` does not cascade here -- disable each card explicitly.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"filename","description":"Shown in the file-chip fallback, used as the download link's suggested\nfilename, and folded into the accessible name of the whole card.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"frame","description":"Visual chrome, on the library-wide `frame` vocabulary. `'card'` (the default) keeps the\nbordered, filled box. `'plain'` removes the border, background, padding and corner radius, so\na card inside a dense chat transcript (or any container already drawing its own separation\nbetween attachments) doesn't double the frame.\n\nType: `LyraFrame`  \nDefault: `'card'`","value":{"type":["'card'","'plain'"]}},{"name":"kind","description":"Explicit format dispatch. Leave unset to auto-detect from `mime-type`.\n\nType: `LyraMediaCardKind | undefined`","value":{"type":["'image'","'video'","'file'"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max-height","description":"A CSS length (e.g. `\"16rem\"`); once set, overrides the\n`--lr-media-card-max-height` custom property for this instance only —\nsame contract as `<lr-document-preview>`'s identically-named prop. Invalid values are\nignored.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"mime-type","description":"Drives auto-detection when `kind` is unset. Attribute removal is consumed as an absent hint.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"src","description":"The media URL. Always re-validated against a safe-scheme allowlist\nbefore use — see the class doc.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"js":{"properties":[{"name":"accessibleLabel","description":"Accessible-name input. A declarative `aria-label` names the host; a property-only assignment\nnames the internal action when no host label is present. Nested actions otherwise keep a\nlocalized purpose name derived from `filename`, `alt`, or the resolved media kind. An\nexplicit empty string is equivalent to the unset `null` default -- both fall through to the\ngenerated purpose-specific name.\n\nAttribute: `aria-label`","type":"string | null","default":"null"},{"name":"alt","description":"Alt text for the image case (and reused as a video label fallback). Unset falls back to\n`filename`, then a generic per-kind description; explicitly `\"\"` marks the image decorative,\nmatching `<lr-image-viewer>`/`<lr-document-preview>`. The `<video>` label is deliberately\noutside that carve-out: an empty accessible name would leave an interactive player unnamed\nrather than mark it decorative, so an empty `alt` still falls through there.\n\nAttribute: `alt`","type":"string | undefined"},{"name":"disabled","description":"Turns off this card's OWN action: the image button and the video `open-button` render\n`disabled`, a safe file chip's anchor loses its `href` and `download` (so it genuinely cannot\nfetch rather than merely claiming `aria-disabled` on a live link) and leaves the tab order,\n`lr-media-open`/`lr-before-media-download` stop firing from every path including `click()`,\nand the affordance paints at `--lr-opacity-disabled` with a `not-allowed` cursor.\n\nDeliberately does NOT reach into the `kind=\"video\"` player: `<video controls>` is media\ncontent with its own native transport, not this card's action, and silencing playback is not\nwhat \"the open affordance is unavailable\" means. An unsafe-`src` file chip has no action at\nall, so `disabled` leaves it byte-identical.\n\nLike `<lr-icon-button>`, this component is not form-associated, so an ancestor\n`<fieldset disabled>` does not cascade here -- disable each card explicitly.\n\nAttribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"filename","description":"Shown in the file-chip fallback, used as the download link's suggested\nfilename, and folded into the accessible name of the whole card.\n\nAttribute: `filename`","type":"string","default":"''"},{"name":"frame","description":"Visual chrome, on the library-wide `frame` vocabulary. `'card'` (the default) keeps the\nbordered, filled box. `'plain'` removes the border, background, padding and corner radius, so\na card inside a dense chat transcript (or any container already drawing its own separation\nbetween attachments) doesn't double the frame.\n\nAttribute: `frame`  \nReflected to its attribute.","type":"LyraFrame","default":"'card'"},{"name":"kind","description":"Explicit format dispatch. Leave unset to auto-detect from `mime-type`.\n\nAttribute: `kind`  \nReflected to its attribute.","type":"LyraMediaCardKind | undefined"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"maxHeight","description":"A CSS length (e.g. `\"16rem\"`); once set, overrides the\n`--lr-media-card-max-height` custom property for this instance only —\nsame contract as `<lr-document-preview>`'s identically-named prop. Invalid values are\nignored.\n\nAttribute: `max-height`","type":"string","default":"''"},{"name":"mimeType","description":"Drives auto-detection when `kind` is unset. Attribute removal is consumed as an absent hint.\n\nAttribute: `mime-type`","type":"string","default":"''"},{"name":"src","description":"The media URL. Always re-validated against a safe-scheme allowlist\nbefore use — see the class doc.\n\nAttribute: `src`","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"blur","description":"Relayed once from the primary action as a bubbling, composed native event.","type":"FocusEvent"},{"name":"focus","description":"Relayed once from the primary action as a bubbling, composed native event.","type":"FocusEvent"},{"name":"lr-before-media-download","description":"A safe file anchor is about to perform its native default. `detail: { src, filename }`; cancelable, and prevention suppresses the native download/open.","type":"CustomEvent<LyraMediaCardOpenDetail>"},{"name":"lr-media-open","description":"An image card or video `open-button` requested consumer-owned viewing. `detail: { src, filename }`; noncancelable notification.","type":"CustomEvent<LyraMediaCardOpenDetail>"}]}},{"name":"lr-memory-panel","description":"`<lr-memory-panel>` — an agent's working memory surface: short-term context and long-term\nmemories, each item's confidence and (optional) grounding provenance, and add/remove/forget\nactions gated behind an explicit confirmation step before anything is reported as decided.\n\nComposes `lr-provenance-panel` for a per-item's provenance breakdown (revealed behind a\ndisclosure toggle, only rendered when `item.provenance` is set) and `lr-confirm-bar` for every\nadd/remove/forget confirmation -- this component never re-implements a new inline-confirmation\npattern of its own. A memory item's confidence reuses `lr-citation-badge`'s own confidence\nvocabulary (`citationHighConfidence`/`citationMediumConfidence`/`citationLowConfidence`), tiered\nagainst `thresholds` the same way `lr-chunk-inspector` tiers a chunk's relevance score.\n\n`shortTerm`/`longTerm` are controlled and never mutated by this component -- approving a pending\naction only fires the matching event; the host applies the resulting state change (adding to\n`longTerm`, removing an item, clearing `longTerm`) and passes new arrays back down. At most one\nconfirmation is ever pending at a time: starting a new action (on the same item or a different\none) silently cancels whichever confirmation was already open, the same way only one row can be\nmid-edit in a list at once.\nIf a controlled collection replacement removes the row containing focus, focus moves to the\nclosest surviving memory row, or to the stable root when no row survives.\n\nFocus follows the confirmation rather than being dropped: activating an action replaces the\nbutton that had focus, so focus moves into the freshly rendered `lr-confirm-bar` (its Deny\ncontrol -- the safe action -- or the bar's own status element) instead of falling back to\n`<body>`. Resolving or cancelling hands focus back: to the row for a per-item decision, to the\n\"Forget all\" control for the bulk one. Escape while the confirmation holds focus cancels it\nexactly like Deny -- no event, same focus return -- and does not propagate, so an enclosing\ndialog or popover still sees its own Escape when no confirmation is open.\n\nThree distinct, non-overlapping actions: `add` promotes a short-term item into long-term memory\n(only offered on short-term items -- long-term items are already there); `remove` deletes one\nspecific item from whichever list it's in (offered on every item); `forget` is deliberately\nscoped to the whole long-term list at once (a single \"Forget all\" control in that section's\nheader, only rendered while `longTerm` is non-empty) -- a bulk, more consequential action kept\ndistinct from the per-item `remove`.\n\nPublic collection sequences are bounded, frozen snapshots. Admitted memory source identities\nand provenance remain opaque while descriptor-safe projections copy display and action fields\nonce; later rendering, event emission, and controlled-focus recovery never reread a source row.\nCreate a new collection and reassign it after changes; mutating the assigned array does not\nupdate the view. Blank memory ids and later duplicates within each scope are ignored before\nrendering, counts, focus recovery, confirmation state, or actions. The first item for an id\nwins in that scope.\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| `add-button` | The \"Add to long-term memory\" action. Only rendered on short-term items. |\n| `base` | The root wrapper. |\n| `confidence` | The item's confidence tier text, carrying `data-tone`. Omitted when `confidence` is unset. |\n| `empty` | The all-empty `lr-empty` state, shown when both lists are empty. |\n| `expand-toggle` | The provenance disclosure toggle. Omitted when `provenance` is unset. |\n| `forget-all-button` | The long-term section's bulk \"Forget all\" action. Only rendered while `longTerm` is non-empty. |\n| `forget-all-confirm` | The `<lr-confirm-bar>` shown in place of the \"Forget all\" action while that bulk confirmation is pending. |\n| `heading` | A section's visible heading text. |\n| `item` | One memory item row (`role=\"listitem\"`); carries `data-id`/`data-scope` and a stable `tabindex=\"-1\"` so focus has somewhere to land after a pending confirmation on this row resolves. |\n| `item-actions` | The wrapper around an item's action row (or its pending `lr-confirm-bar`). |\n| `item-body` | The disclosed `lr-provenance-panel` wrapper, `hidden` while collapsed. Omitted when `provenance` is unset. |\n| `item-row` | The wrapper around an item's text and confidence indicator. |\n| `item-text` | The item's `text`. |\n| `list` | A section's `role=\"list\"` wrapper, omitted while that section is empty. |\n| `remove-button` | The \"Remove\" action. Rendered on every item. |\n| `section` | One of the two (short-term/long-term) sections; carries `data-scope`. |\n| `section-empty` | A section's \"no items\" text, shown when that section's own list is empty. |\n| `section-header` | A section's heading + (long-term only) \"Forget all\" control row. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-memory-panel-confidence-danger-color` (default: `var(--lr-color-danger)`) — Text color for a low-confidence item's confidence indicator.\n- `--lr-memory-panel-confidence-success-color` (default: `var(--lr-color-success)`) — Text color for a high-confidence item's confidence indicator.\n- `--lr-memory-panel-confidence-warning-color` (default: `var(--lr-color-warning)`) — Text color for a medium-confidence item's confidence indicator.","attributes":[{"name":"label","description":"Fallback overall group name. A non-empty host `aria-label` makes the host the sole owner; an\nexplicitly empty host label stays empty on the group, and so does an explicitly empty\n`label`.\n\nType: `string | undefined`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"js":{"properties":[{"name":"label","description":"Fallback overall group name. A non-empty host `aria-label` makes the host the sole owner; an\nexplicitly empty host label stays empty on the group, and so does an explicitly empty\n`label`.\n\nAttribute: `label`","type":"string | undefined"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"longTerm","description":"Persisted memories. Controlled and never mutated by this component.","type":"readonly LyraMemoryItem[]","default":"[]"},{"name":"shortTerm","description":"Ephemeral, working-context items. Controlled and never mutated by this component.","type":"readonly LyraMemoryItem[]","default":"[]"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"thresholds","description":"Confidence-tier and (forwarded) provenance relevance-tier boundaries.","type":"LyraScoreThresholds","default":"{ high: 0.75, medium: 0.5, }"},{"name":"types","description":"`lr-provenance-panel` `types` pass-through, forwarded verbatim to every expanded item's panel.","type":"readonly LyraNodeTypeStyle[]","default":"[]"}],"events":[{"name":"lr-add","description":"A pending \"add to long-term memory\" action was approved. `detail: { memory }` -- the short-term item as-is; the host decides how/whether to persist it.","type":"CustomEvent<LyraEventDetailSnapshot<LyraMemoryAddDetail>>"},{"name":"lr-expand","description":"A memory item's provenance disclosure was toggled. `detail: { memoryId, scope, expanded }`.","type":"CustomEvent<LyraMemoryExpandDetail>"},{"name":"lr-forget","description":"The pending \"forget all long-term memories\" action was approved. No detail.","type":"CustomEvent<null>"},{"name":"lr-remove","description":"A pending \"remove\" action was approved. `detail: { memoryId, scope }`.","type":"CustomEvent<LyraMemoryRemoveDetail>"}]}},{"name":"lr-mention-popover","description":"`<lr-mention-popover>` — a caret-anchored, keyboard-navigable popover for\n`@`-mention and `/`-slash-command autocomplete inside a plain-text\n`<textarea>`/`<input>` the host owns (e.g. `<lr-chat-composer>`'s own\ntextarea, though this component has no dependency on that or any other\nspecific input). A textarea session keeps the native textarea's implicit\ntextbox semantics: it snapshots and temporarily clears any authored role,\nexpanded state, controls/active-descendant IDREF, or ARIA element reflection\nacross shadow roots, leaving only autocomplete/haspopup while open. Its\nfirst consumed arrow key moves real focus to the active option,\nso the focus owner and option share this component's shadow tree.\n\nIntegration contract (entirely the host's responsibility — this component\nnever inspects the text control's value or listens to it directly):\n1. Detect a mention/command trigger (e.g. `@`/`/` at the start of a word)\n   in the host's own `input` handling.\n2. Set `anchor` (the `<textarea>`/`<input>` itself, or any element for\n   plain whole-element anchoring — see \"Positioning\" below), `items`, and\n   `query` (the text typed since the trigger character), then flip\n   `open = true`.\n3. Forward every `keydown` the input receives, while `open`, through\n   `handleKeyDown()` — it returns `true` when it consumed the key (so the\n   host's own handler should stop, e.g. skip submitting the message on an\n   Enter that actually picked a mention) and `false` otherwise.\n4. Set `open = false` whenever the query stops looking like an active\n   mention context (a space typed, the trigger character deleted, or focus\n   leaving both the input and this popover) — `lr-mention-close` fires\n   automatically from that (see below), there is no separate \"tell it to\n   close\" call needed.\n5. For a textarea anchor, the component temporarily sets only\n   `aria-autocomplete=\"list\"` and `aria-haspopup=\"listbox\"`, restoring all authored ARIA/AOM\n   values it changes on close, anchor replacement, disconnect, or adoption. Call\n   `focusActiveOption()` after the first consumed navigation key. Pass an `ownsFocus` predicate\n   if the host tracks a suggestion generation or disabled/focus-exit state; it must remain true\n   while either the anchor or this popover owns that live session. A host blur handler must\n   therefore keep the popover open when `relatedTarget` is this component.\n\nPositioning: when `anchor` is a plain `<textarea>` or single-line text\n`<input>`, this component measures exactly where the caret currently\npaints (`caretClientRect()`, the standard hidden-mirror-element technique\n— see that function's own doc) and positions against that single point\nwith `internal/positioner.js`'s `place()`, so the popup tracks the caret\nrather than sitting under the whole textarea. Any other `anchor` element\n(or a text control this component fails to measure, e.g. one with\n`display: none`) falls back to `place(anchor, popup)` against the whole\nelement — the same whole-element anchoring `<lr-combobox>`/\n`<lr-select>` use for their own popups. Re-measures on every `anchor`/\n`query` change while open (a keystroke moves the caret, so a fresh `query`\nis the proxy for \"the caret may have moved\"); a caret that moves for a\nreason other than typing (e.g. a mouse click elsewhere in the text while\nthe popover happens to still be open) is not separately tracked — the\nhost can force a re-measure by toggling `open` or reassigning `anchor`.\n\nFiltering happens internally against `items` (mirroring `<lr-combobox>`'s\nfilter-predicate convention via `filter`, rather than requiring the host to\npre-filter): candidate rows without a string `label` are omitted before any\npredicate runs, and the default predicate is a case-insensitive substring\nmatch against `label`/`description`, overridable via `filter`.\n\nThere is no persisted \"selection\" the way a real listbox has one — a\nmention is either committed (closing the popover) or the popover is\ndismissed with nothing chosen — so `aria-selected=\"true\"` marks whichever\nrow is currently *active* (what Enter/Tab would commit right now), per the\nWAI-ARIA combobox-with-list-autocomplete pattern, rather than tracking a\nseparate persisted value the way `<lr-combobox>`'s own `aria-selected`\ndoes.\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| `empty` | The \"no matches\" message, shown when `items`/`query` produce zero rows. |\n| `listbox` | The popover's root element (`role=\"listbox\"`). |\n| `option` | A candidate row (`role=\"option\"`). Carries `aria-disabled=\"true\"` while that row's `disabled` is set. |\n| `option-description` | A row's optional secondary line, when `description` is set. |\n| `option-icon` | A row's leading icon glyph, when `icon` is set. |\n| `option-label` | Wrapper around a row's label/description. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-mention-popover-option-active-bg` (default: `var(--lr-color-brand-quiet)`) — Background of the hovered or `[data-active]` (keyboard-highlighted) suggestion row.\n- `--lr-mention-popover-option-disabled-opacity` (default: `0.5`) — Opacity of a row whose `items` entry sets `disabled`.\n- `--lr-overlay-border` (default: `var(--lr-color-border)`) — Shared floating-surface edge colour, on the listbox.\n- `--lr-overlay-radius` (default: `var(--lr-radius)`) — Shared floating-surface corner radius, on the listbox.\n- `--lr-overlay-shadow-anchored` (default: `var(--lr-shadow-m)`) — Elevation of the anchored surface.\n- `--lr-overlay-surface` (default: `var(--lr-color-surface-overlay)`) — Shared floating-surface fill, on the listbox.\n- `--lr-positioning-strategy` — Cascading `absolute`/`fixed` override for the listbox's `fixed` default, read from computed style when it is (re)positioned. Set it once on `:root`, a theme, or one clipping ancestor to change every unset mention popover beneath it; an unrecognized value falls back to `fixed`.","attributes":[{"name":"empty-text","description":"Message shown when `items` (post-`query`-filtering) is empty. `undefined` uses the localized\ndefault; every supplied string, including `''` and `'No matches'`, is caller-owned.\n\nType: `string | undefined`"},{"name":"label","description":"Accessible name for the `role=\"listbox\"` popup. `undefined` uses the localized default;\nevery supplied string, including `''` and `'Suggestions'`, is caller-owned. Also settable as\na plain `aria-label` attribute on `<lr-mention-popover>` itself, which takes precedence over\nthis property when present -- matches `<lr-combobox>`'s/`<lr-table>`'s identical host\n`aria-label` fallback.\n\nType: `string | undefined`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"open","description":"Whether the popover is shown.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"query","description":"The text typed since the trigger character (`@`/`/`/…) — drives the\nbuilt-in internal filtering (see `filter` to override it). Removing the attribute\nuses the unfiltered empty-query behavior without changing null readback.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"js":{"properties":[{"name":"activeDescendantElement","description":"The currently highlighted shadow option.","type":"HTMLElement | null","read-only":true},{"name":"activeDescendantId","description":"The internal id of the currently highlighted row, for same-tree consumers only.","type":"string | null","read-only":true},{"name":"anchor","description":"The element to position the popup relative to. When this is a plain\n`<textarea>`/single-line text `<input>`, positioning is caret-precise\n(see the class doc); any other element anchors the whole popup under\nthat element's own box, the same as `<lr-combobox>`'s trigger.","type":"HTMLElement | undefined"},{"name":"emptyText","description":"Message shown when `items` (post-`query`-filtering) is empty. `undefined` uses the localized\ndefault; every supplied string, including `''` and `'No matches'`, is caller-owned.\n\nAttribute: `empty-text`","type":"string | undefined"},{"name":"filter","description":"Overrides the built-in case-insensitive label/description substring match.","type":"LyraMentionFilter | null","default":"null"},{"name":"filteredItems","description":"The current candidate set: runtime rows without a non-blank string `label` are omitted (a\nblank/whitespace-only label would otherwise render a focusable `role=\"option\"` with no\naccessible name), then the remaining `items` are filtered by `query` via `filter` (or the\nbuilt-in default).","type":"readonly Readonly<LyraMentionItem>[]","read-only":true},{"name":"items","description":"The full candidate set, pre-`query`-filtering. Assignment takes a shallow frozen snapshot;\nmalformed rows without a string `label` remain in that snapshot but are omitted from every\nfiltered/rendered projection.","type":"readonly Readonly<LyraMentionItem>[]"},{"name":"label","description":"Accessible name for the `role=\"listbox\"` popup. `undefined` uses the localized default;\nevery supplied string, including `''` and `'Suggestions'`, is caller-owned. Also settable as\na plain `aria-label` attribute on `<lr-mention-popover>` itself, which takes precedence over\nthis property when present -- matches `<lr-combobox>`'s/`<lr-table>`'s identical host\n`aria-label` fallback.\n\nAttribute: `label`","type":"string | undefined"},{"name":"listboxId","description":"The internal `id` of the `role=\"listbox\"` popup. Like\n`activeDescendantId`, it cannot form a cross-shadow string IDREF from a\nhost-owned input.","type":"string","read-only":true},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"open","description":"Whether the popover is shown.\n\nAttribute: `open`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"query","description":"The text typed since the trigger character (`@`/`/`/…) — drives the\nbuilt-in internal filtering (see `filter` to override it). Removing the attribute\nuses the unfiltered empty-query behavior without changing null readback.\n\nAttribute: `query`","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-mention-close","description":"The popover was dismissed with no selection — Escape, or `open` transitioning to `false` by any other means (a direct host assignment included). Never fires for a close that followed a `lr-mention-select` commit.","type":"CustomEvent<null>"},{"name":"lr-mention-select","description":"An item was committed (Enter/Tab/click). `detail: { suggestionId, index, label }`; `index` disambiguates repeated business ids.","type":"CustomEvent<LyraMentionSelectDetail>"}]}},{"name":"lr-menu","description":"`<lr-menu>` — the inline semantic controller mapped from `<sl-menu>`. It owns the\n`role=\"menu\"` list, real roving focus, wrapping Arrow/Home/End navigation, typeahead, and the\nsingle canonical `lr-select` event. Wrap it in `<lr-dropdown>` when a trigger, positioned popup,\nopen state, lifecycle events, or imperative overlay methods are required; those concerns belong\nto the dropdown shell rather than being duplicated on the menu.\nBackground item removal or disablement repairs the roving stop without taking focus from\noutside controls or the header/footer. Displacing the focused item rehomes actual focus.\n\nAn `<lr-menu-item>` with `<lr-menu slot=\"submenu\">` uses a private, symbol-keyed presentation\ncontroller. ArrowRight steps into the submenu and ArrowLeft returns (mirrored under RTL),\nEnter/Space open the branch, Escape and outside pointer dismissal close only the innermost\nbranch, hover uses an intent delay, and at most one submenu per level stays open. This internal\nshell does not add root-menu attributes, methods, parts, or lifecycle events.\n\nSelection is always one cancelable `lr-select` carrying the complete item. A nested selection\nbubbles through every ancestor without translation or re-emission; preventing it anywhere keeps\nthe current branch open. Item-to-menu activation uses private owner plumbing, so neither\n`lr-menu-item-select` nor `lr-menu-select` is part of the public contract.\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-menu-item>` elements, plus optionally plain `<hr>` dividers between groups (native `<hr>` already carries an implicit `separator` role, matching what `role=\"menu\"` expects between item groups). Arbitrary non-item content still renders here for backward compatibility, but the `header`/`footer` slots below are the supported place for it. |\n| `footer` | Same as `header`, rendered below the items — an \"Apply\"/\"Done\" button, a link to a fuller settings page, a count. |\n| `header` | Composed content rendered above the items and *outside* the `role=\"menu\"` list — a filter/search field, a section title, a summary row. Keeps its own full default keyboard behavior, is reachable with Tab from the items, and is ARIA-valid (arbitrary content inside `role=\"menu\"` is not). Collapses to no box at all while unfilled. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `footer` | The wrapper around the `footer` slot, below the list and outside `role=\"menu\"`. `display: none` while the slot is unfilled. |\n| `header` | The wrapper around the `header` slot, above the list and outside `role=\"menu\"`. `display: none` while the slot is unfilled. |\n| `list` | The `role=\"menu\"` container wrapping the default slot. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-menu-max-inline-size` (default: `var(--lr-size-20rem)`) — Width ceiling of the standalone menu surface and of a submenu's own surface. Takes a length or a percentage; `100%` and `none` both uncap it to the container, and any other value outside `<length-percentage>` is treated as `none` rather than silently dropping the cap's safety terms. The viewport clamp and the container allocation are applied outside this name, so no value can make a menu overflow either. A contained menu (inside `lr-dropdown`) sizes from its dropdown and is unaffected.\n- `--lr-menu-min-inline-size` (default: `var(--lr-size-10rem)`) — Width floor of the same two surfaces. Lower it alongside `--lr-menu-max-inline-size` to make a menu narrower than 10rem; the floor wins over the ceiling, so capping alone cannot go below it.\n- `--lr-overlay-border` (default: `var(--lr-color-border)`) — Shared floating-surface edge colour, on the same two surfaces. The header/footer dividing rules and a slotted `hr` are deliberately excluded: they separate content, they do not draw the surface's own edge.\n- `--lr-overlay-radius` (default: `var(--lr-radius)`) — Shared floating-surface corner radius, on the same two surfaces.\n- `--lr-overlay-shadow-anchored` (default: `var(--lr-shadow-m)`) — Elevation of the anchored submenu surface.\n- `--lr-overlay-surface` (default: `var(--lr-color-surface-overlay)`) — Shared floating-surface fill, on the standalone menu surface and on a submenu's own surface. A contained menu (inside `lr-dropdown`) paints no surface of its own, so it is unaffected.\n- `--lr-positioning-strategy` — Cascading `absolute`/`fixed` override for the private submenu surface's `fixed` default, read from computed style when a submenu is (re)positioned. Set it once on `:root`, a theme, or one clipping ancestor to change every unset submenu beneath it; an unrecognized value falls back to `fixed`.","attributes":[{"name":"label","description":"Accessible name for the `role=\"menu\"` list — override with something\nspecific (e.g. \"Row actions\") when a page has more than one menu.\nLocalized (`menuLabel`) when omitted. Any supplied string, including\n`\"Menu\"` or an empty string, remains literal. A host-level\n`aria-label` attribute takes precedence over both this prop and the\nlocalized default — including an explicit empty `aria-label=\"\"` —\nmatching `lr-select`/`lr-model-select`'s established\n`this.getAttribute('aria-label') ?? <computed default>` precedence\n(see `effectiveLabel`).\n\nType: `string | undefined`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"slots":[{"name":"","description":"`<lr-menu-item>` elements, plus optionally plain `<hr>` dividers between groups (native `<hr>` already carries an implicit `separator` role, matching what `role=\"menu\"` expects between item groups). Arbitrary non-item content still renders here for backward compatibility, but the `header`/`footer` slots below are the supported place for it."},{"name":"footer","description":"Same as `header`, rendered below the items — an \"Apply\"/\"Done\" button, a link to a fuller settings page, a count."},{"name":"header","description":"Composed content rendered above the items and *outside* the `role=\"menu\"` list — a filter/search field, a section title, a summary row. Keeps its own full default keyboard behavior, is reachable with Tab from the items, and is ARIA-valid (arbitrary content inside `role=\"menu\"` is not). Collapses to no box at all while unfilled."}],"js":{"properties":[{"name":"dropdownOpen","type":"boolean"},{"name":"label","description":"Accessible name for the `role=\"menu\"` list — override with something\nspecific (e.g. \"Row actions\") when a page has more than one menu.\nLocalized (`menuLabel`) when omitted. Any supplied string, including\n`\"Menu\"` or an empty string, remains literal. A host-level\n`aria-label` attribute takes precedence over both this prop and the\nlocalized default — including an explicit empty `aria-label=\"\"` —\nmatching `lr-select`/`lr-model-select`'s established\n`this.getAttribute('aria-label') ?? <computed default>` precedence\n(see `effectiveLabel`).\n\nAttribute: `label`","type":"string | undefined"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-select","description":"WA-compatible selection event carrying `detail: { item }`. Cancelable; preventing it keeps the current menu/submenu chain open. Emitted once by the menu that owns the activated item and allowed to bubble through ancestors without translation/re-emission.","type":"CustomEvent<LyraEventDetailSnapshot<MenuItemSelectDetail>>"}]}},{"name":"lr-menu-item","description":"`<lr-menu-item>` — a single action row inside `<lr-menu>`'s default\nslot. Not meaningful on its own (there is no standalone \"click a menu item\"\nuse case) — it exists purely as `<lr-menu>`'s light-DOM child, the same\nrelationship `<lr-option>` has to `<lr-combobox>`/`<lr-select>`.\n\n`role=\"menuitem\"` and the roving `tabindex` both live on *this host\nelement*, not an internal shadow-DOM button — mirroring `<lr-tree-item>`'s\nidentical choice (see that class's doc). `<lr-menu>` is the sole owner of\nthis element's `tabIndex`: it flips exactly one navigable item's `tabIndex`\nto `0` (the rest sit at `-1`) as its roving-tabindex highlight moves, and\ncalls `.focus()` directly on this host to move real DOM focus there.\n`[part=\"base\"]` is purely a visual box with no interactive semantics of its\nown — see the class doc on `<lr-menu>` for why real DOM focus (rather\nthan `aria-activedescendant`) was chosen for this pair.\n\nEnter/Space activation is handled by `<lr-menu>`'s own delegated\n`keydown` listener calling `select()` on whichever item is currently\nroving-focused (mirrors `<lr-tree>` calling `current.select()` from its\nown keydown handler). The visual row wires the pointer `click` listener,\nand the host's `click()` forwards to that same row, so `select()` fires\nidentically whether the item was reached by mouse, keyboard, or a\nprogrammatic host click.\n\nA `<lr-menu>` or one or more direct mapped items assigned to the `submenu` slot turns this row\ninto a submenu parent: the host gains `aria-haspopup=\"menu\"` plus an `aria-expanded` that\nrenders `\"true\"` *and* `\"false\"` (never omitted — the attribute is part of\nthe role's state, so a Lit `?aria-expanded=` directive would be wrong), a\nchevron renders in `[part=\"submenu-icon\"]`, and activation opens the\nsubmenu instead of selecting. The parent `<lr-menu>` owns the interaction\npolicy — the arrow keys (mirrored under RTL), pointer intent, and the\none-submenu-per-level rule — and drives it through `openSubmenu()` /\n`closeSubmenu()`; this element owns the ARIA, the naming, and the panel\nwiring. Because a submenu parent is a disclosure rather than an action, it\nnever activates the menu, and neither `type=\"checkbox\"` nor `type=\"radio\"` has any effect on\none. A submenu selection is\nthe same single `lr-select` event bubbling through the outer menu — there is no separate nested\nselection event or public child-to-menu event.\n\nThe default label slot's flattened subtree is visual-only: it is inert and\nhidden from assistive technology so the focusable host remains the row's\nsole action. Its accessible text names both this item and its submenu's\n`role=\"menu\"`, without allowing an open submenu to leak into the item's\nname. Direct and flattened, forwarded default-slot labels are observed live\nso in-place text edits, reassignments, and relevant visibility changes\nupdate type-ahead and both computed names. Accessibility-hidden branches are\nomitted; a real forwarding-slot assignment remains authoritative even when\nhidden, while fallback contributes once no assignment remains. A host-level\n`aria-label` or `aria-labelledby` remains authoritative; a `label`/\n`aria-label` on the submenu itself does too. An explicitly empty\n`aria-label` and a value supplied after the initial computed name both win.\n\n`type=\"checkbox\"` (mirroring `wa-dropdown-item`'s identical `type` option)\nrenders `role=\"menuitemcheckbox\"` in place of `role=\"menuitem\"`, with\n`aria-checked` reflecting `checked` and a checkmark glyph shown once\n`checked` is `true`. Activating a `checkbox`-type item (click, or the\nparent's Enter/Space handling via `select()`) first fires a cancelable\n`lr-menu-item-change` with the proposed next `checked` value, then mutates\n`checked` unless a listener prevents that event. It fires\nthe owning menu's canonical `lr-select` afterwards either way. `type=\"normal\"` (the default) renders and\nbehaves exactly as before this option existed — no role, rendering, or\nevent differences.\n\n`type=\"radio\"` renders `role=\"menuitemradio\"` instead, reusing the same\n`aria-checked` reflection and checkmark glyph as `checkbox`, but with\nexclusive-choice group semantics layered on top: activating an already-\n`checked` radio is a no-op on `checked` itself — no `lr-menu-item-change`\nproposal, no state change, matching native `<input type=\"radio\">`\nsemantics — though it still falls through to the owning menu's usual\nselection, exactly like re-activating any other item. Activating an\n*unchecked* radio fires the same cancelable `lr-menu-item-change` with\n`checked: true`; once that is not prevented, this item becomes `checked`\nand every other `type=\"radio\"` item the *same owning `<lr-menu>`* owns\ndirectly (never one owned by a nested submenu, which has its own owning\nmenu) whose `group` matches this item's `group` is unchecked directly —\nwithout an `lr-menu-item-change` of its own. `group` defaults to `undefined`,\nso every ungrouped radio row beneath one menu shares a single exclusive\nscope unless narrowed by giving each subset its own `group` string.\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 visual label content. Its flattened subtree is inert and hidden from assistive technology; its accessible text names the host menu item. |\n| `details` | Decorative secondary WA-compatible detail text rendered after the label. Its flattened subtree is inert and hidden from assistive technology. |\n| `icon` | Optional decorative leading icon. Its flattened subtree is inert and hidden from assistive technology. |\n| `prefix` | Shoelace-compatible decorative alias for leading content. Its flattened subtree is inert and hidden from assistive technology. |\n| `submenu` | A nested `<lr-menu>` or direct mapped menu items that open beside this row. |\n| `suffix` | Shoelace-compatible decorative trailing content. Its flattened subtree is inert and hidden from assistive technology. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The row (`role` lives on the host — see the class doc). |\n| `checked-icon` | Shoelace-compatible wrapper around the checked glyph. |\n| `checkmark` | The checkmark glyph shown when a `type=\"checkbox\"`/`type=\"radio\"` item is `checked`. Not rendered at all for `type=\"normal\"`. |\n| `details` | Wrapper around the `details` slot. |\n| `icon` | Wrapper around the `icon` slot. Not rendered at all when the slot is empty. |\n| `label` | Wrapper around the default slot. |\n| `prefix` | Wrapper around the `prefix` slot. |\n| `spinner` | Loading spinner. |\n| `spinner__base` | Shoelace-compatible alias on the loading spinner. |\n| `submenu` | The submenu panel/wrapper. |\n| `submenu-icon` | Wrapper around the chevron shown on a submenu parent. Not rendered at all without a `submenu` slot. Mirrors under RTL through this wrapper, never by swapping the glyph. |\n| `suffix` | Wrapper around the `suffix` slot. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-menu-item-active-bg` (default: `color-mix(in oklab,var(--lr-menu-item-hover-bg,var(--lr-color-brand-quiet)),var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Background of an enabled row while pressed, matching `--lr-option-active-bg`'s equivalent hook. Left unset, the pressed fill keeps mixing from `--lr-menu-item-hover-bg` as before this hook existed.\n- `--lr-menu-item-checked-bg` (default: `transparent`) — Background of a checked (`type=\"checkbox\" checked` or `type=\"radio\" checked`) row.\n- `--lr-menu-item-checked-color` (default: `inherit`) — Foreground of a checked row.\n- `--lr-menu-item-checked-font-weight` (default: `inherit`) — Font weight of a checked row.\n- `--lr-menu-item-danger-active-bg` (default: `color-mix(in oklab, var(--lr-color-danger-quiet), var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Background of an enabled danger row while pressed. Checked-state hooks are also inline fallbacks, matching `<lr-option>`/`<lr-select>`/ `<lr-combobox>`/`<lr-tree-item>`'s equivalent row-chrome hooks; all three default to no visual change, so a `type=\"checkbox\"`/`type=\"radio\"` item's checked row paints identically to before these existed unless a consumer sets one.\n- `--lr-menu-item-danger-color` (default: `var(--lr-color-danger)`) — Foreground of a `variant=\"danger\"` row.\n- `--lr-menu-item-danger-hover-bg` (default: `var(--lr-color-danger-quiet)`) — Background of an enabled danger row while hovered.\n- `--lr-menu-item-gap` (default: `var(--lr-space-xs)`) — Gap between the visual parts of `[part=\"base\"]`, including its leading content, label, trailing details, and state glyphs. Declared as an inline `var()` fallback (never on `:host`), so an item or any ancestor can retune it without a `::part(base)` rule. It is constant across the shared size ladder.\n- `--lr-menu-item-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Background of an enabled row under the pointer. The pressed state mixes from this same value, so a retuned hover fill keeps its pressed step instead of snapping back to the brand default.\n- `--lr-menu-item-icon-color` (default: `inherit`) — Foreground of the leading icon wrapper. Unset it inherits the row's colour, including the danger variant's.\n- `--lr-menu-item-min-height` (default: `max(var(--lr-form-control-height),var(--lr-size-24px))`) — Minimum block size of the visual row. Unset it is the shared form-control ladder floored at the WCAG 2.2 SC 2.5.8 minimum, exactly as before this hook existed.\n- `--lr-menu-item-radius` (default: `var(--lr-form-control-radius)`) — Corner radius of the visual row and focusable host. Its fallback follows the active shared size tier. Declared as an inline `var()` fallback (never on `:host`), so an item or any ancestor can retune it without a `::part(base)` rule. Danger-state hooks are also inline fallbacks, so a menu can retheme only its dangerous rows without replacing the shared danger palette elsewhere.\n- `--submenu-offset` (default: `-2px`) — Final signed distance between a submenu and its parent row. Negative values overlap the parent menu; positive values add separation. Mirrors under RTL.","attributes":[{"name":"checked","description":"Whether a `type=\"checkbox\"`/`type=\"radio\"` item is checked. Meaningless (ignored) for\n`type=\"normal\"`.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"disabled","description":"Disables selection and excludes this item from `<lr-menu>`'s roving-tabindex nav entirely.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"download","description":"Native anchor `download` attribute, used only while `href` resolves to a link. Narrows the\nsafe-URL allowlist to `safeDownloadHref`'s, which drops `mailto:` — a mail handoff names no\nretrievable bytes, so it cannot be a download target.\n\nType: `string | undefined`"},{"name":"group","description":"Narrows a `type=\"radio\"` item's exclusive-choice scope to only the other radio items sharing\nthis same string. Unset (the default), the scope is every `type=\"radio\"` item the same\nowning `<lr-menu>` owns directly — a nested submenu's radio items already belong to that\nsubmenu's own `<lr-menu>` instead, so they're never in scope regardless of `group`. Meaningless\n(ignored) for `type=\"normal\"`/`\"checkbox\"`.\n\nType: `string | undefined`"},{"name":"href","description":"When set to a safe link URL (`http:`/`https:`/`blob:`/`mailto:`/relative — see\n`safeLinkHref`, or `safeDownloadHref` which drops `mailto:` when `download` is set),\n`[part=\"base\"]` renders as a real `<a href=…>` instead of a `<span>`, and activation (click,\nor the parent's Enter/Space handling, which forwards through `click()` for a link item so the\nanchor's own native default action runs) navigates there in addition to firing the usual\n`select()`/`lr-select` contract. An unsafe/unparseable `href` falls back to the plain `<span>`,\nmatching `lr-button`'s identical fallback. Mirrors `wa-dropdown-item`'s link-item support.\n\nType: `string | undefined`"},{"name":"loading","description":"Shows progress and makes the row interaction-disabled while an action is pending.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"rel","description":"Independently settable author relationship tokens for the rendered link (no default).\n`opener` is always stripped, and any `target` force-adds the non-removable\n`noopener noreferrer` guard — see `target`.\n\nType: `string | undefined`"},{"name":"size","description":"Row density, on the library's shared six-step ladder — `'m'` by default. Scales the row's\nheight, inline/block padding, font size and corner radius together; `'small'`/`'medium'`/\n`'large'` are accepted as synonyms of `'s'`/`'m'`/`'l'`. Every tier still resolves to at\nleast the 24px pointer-target floor, so even `'2xs'` stays tappable. Each item carries its\nown size rather than inheriting one from `<lr-menu>`, so a single compact row inside an\notherwise default menu needs no wrapper.\n\nType: `LyraSize`  \nDefault: `'m'`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}},{"name":"target","description":"Native anchor `target`, used only while `href` resolves to a link. Setting this to `'_blank'`\n(or any other target) always contributes `noopener noreferrer` to the rendered anchor's `rel`\n— matching `lr-button`'s identical pattern.\n\nType: `string | undefined`"},{"name":"type","description":"`'checkbox'` renders `role=\"menuitemcheckbox\"` with a toggleable `checked` state and a\ncheckmark glyph, mirroring `wa-dropdown-item`'s identical `type` option. `'radio'` renders\n`role=\"menuitemradio\"` with exclusive-choice group semantics — see the class doc for both.\n\nType: `MenuItemType`  \nDefault: `'normal'`","value":{"type":["'normal'","'checkbox'","'radio'"]}},{"name":"value","description":"An id/value available on the item carried by the parent `<lr-menu>`'s `lr-select` detail.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"variant","description":"Semantic treatment. `default` is the WA spelling of a normal action and `danger` is its\nmapped dangerous-action treatment.\n\nType: `MenuItemVariant`  \nDefault: `'default'`","value":{"type":["'default'","'danger'"]}}],"slots":[{"name":"","description":"The item's visual label content. Its flattened subtree is inert and hidden from assistive technology; its accessible text names the host menu item."},{"name":"details","description":"Decorative secondary WA-compatible detail text rendered after the label. Its flattened subtree is inert and hidden from assistive technology."},{"name":"icon","description":"Optional decorative leading icon. Its flattened subtree is inert and hidden from assistive technology."},{"name":"prefix","description":"Shoelace-compatible decorative alias for leading content. Its flattened subtree is inert and hidden from assistive technology."},{"name":"submenu","description":"A nested `<lr-menu>` or direct mapped menu items that open beside this row."},{"name":"suffix","description":"Shoelace-compatible decorative trailing content. Its flattened subtree is inert and hidden from assistive technology."}],"js":{"properties":[{"name":"checked","description":"Whether a `type=\"checkbox\"`/`type=\"radio\"` item is checked. Meaningless (ignored) for\n`type=\"normal\"`.\n\nAttribute: `checked`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"disabled","description":"Disables selection and excludes this item from `<lr-menu>`'s roving-tabindex nav entirely.\n\nAttribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"download","description":"Native anchor `download` attribute, used only while `href` resolves to a link. Narrows the\nsafe-URL allowlist to `safeDownloadHref`'s, which drops `mailto:` — a mail handoff names no\nretrievable bytes, so it cannot be a download target.\n\nAttribute: `download`","type":"string | undefined"},{"name":"group","description":"Narrows a `type=\"radio\"` item's exclusive-choice scope to only the other radio items sharing\nthis same string. Unset (the default), the scope is every `type=\"radio\"` item the same\nowning `<lr-menu>` owns directly — a nested submenu's radio items already belong to that\nsubmenu's own `<lr-menu>` instead, so they're never in scope regardless of `group`. Meaningless\n(ignored) for `type=\"normal\"`/`\"checkbox\"`.\n\nAttribute: `group`","type":"string | undefined"},{"name":"hasSubmenu","description":"Whether a nested `<lr-menu>` or direct mapped items are assigned to this item's `submenu`\nslot, making it a submenu parent.","type":"boolean","read-only":true},{"name":"href","description":"When set to a safe link URL (`http:`/`https:`/`blob:`/`mailto:`/relative — see\n`safeLinkHref`, or `safeDownloadHref` which drops `mailto:` when `download` is set),\n`[part=\"base\"]` renders as a real `<a href=…>` instead of a `<span>`, and activation (click,\nor the parent's Enter/Space handling, which forwards through `click()` for a link item so the\nanchor's own native default action runs) navigates there in addition to firing the usual\n`select()`/`lr-select` contract. An unsafe/unparseable `href` falls back to the plain `<span>`,\nmatching `lr-button`'s identical fallback. Mirrors `wa-dropdown-item`'s link-item support.\n\nAttribute: `href`  \nReflected to its attribute.","type":"string | undefined"},{"name":"loading","description":"Shows progress and makes the row interaction-disabled while an action is pending.\n\nAttribute: `loading`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"rel","description":"Independently settable author relationship tokens for the rendered link (no default).\n`opener` is always stripped, and any `target` force-adds the non-removable\n`noopener noreferrer` guard — see `target`.\n\nAttribute: `rel`","type":"string | undefined"},{"name":"size","description":"Row density, on the library's shared six-step ladder — `'m'` by default. Scales the row's\nheight, inline/block padding, font size and corner radius together; `'small'`/`'medium'`/\n`'large'` are accepted as synonyms of `'s'`/`'m'`/`'l'`. Every tier still resolves to at\nleast the 24px pointer-target floor, so even `'2xs'` stays tappable. Each item carries its\nown size rather than inheriting one from `<lr-menu>`, so a single compact row inside an\notherwise default menu needs no wrapper.\n\nAttribute: `size`  \nReflected to its attribute.","type":"LyraSize","default":"'m'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"submenuOpen","description":"Whether this item's submenu is currently open. Tracks the panel's own state, however it\nchanged — the parent menu's keyboard/pointer handling, a dismissal, or a direct write.","type":"boolean"},{"name":"target","description":"Native anchor `target`, used only while `href` resolves to a link. Setting this to `'_blank'`\n(or any other target) always contributes `noopener noreferrer` to the rendered anchor's `rel`\n— matching `lr-button`'s identical pattern.\n\nAttribute: `target`","type":"string | undefined"},{"name":"type","description":"`'checkbox'` renders `role=\"menuitemcheckbox\"` with a toggleable `checked` state and a\ncheckmark glyph, mirroring `wa-dropdown-item`'s identical `type` option. `'radio'` renders\n`role=\"menuitemradio\"` with exclusive-choice group semantics — see the class doc for both.\n\nAttribute: `type`  \nReflected to its attribute.","type":"MenuItemType","default":"'normal'"},{"name":"value","description":"An id/value available on the item carried by the parent `<lr-menu>`'s `lr-select` detail.\n\nAttribute: `value`","type":"string","default":"''"},{"name":"variant","description":"Semantic treatment. `default` is the WA spelling of a normal action and `danger` is its\nmapped dangerous-action treatment.\n\nAttribute: `variant`  \nReflected to its attribute.","type":"MenuItemVariant","default":"'default'"}],"events":[{"name":"lr-menu-item-change","description":"A `type=\"checkbox\"` item was activated, or a `type=\"radio\"` item was activated while unchecked (an already-checked radio never fires this). `detail: { value, checked }` contains the item's own `value` and the proposed next `checked` value, before the property mutates. Cancelable: prevent it to retain the current `checked` value. The usual the parent menu's `lr-select` still follows, so selection and close behavior are unchanged. Never fired for `type=\"normal\"`. Unchecking a radio's group siblings once this event commits fires no event of its own.","type":"CustomEvent<MenuItemChangeDetail>"},{"name":"lr-menu-item-state-change","description":"Something that decides whether this item is navigable changed: `disabled`, `loading`, `hidden`, `inert`, or `aria-hidden`. `detail: { disabled, hidden, inert }`, where `disabled` is the effective `disabled || loading`. `<lr-menu>` consumes this to repair its roving-tabindex state immediately. The last three are plain native attributes rather than reactive properties, so they are watched with the item's own `MutationObserver`; `aria-hidden` fires the event without appearing in the detail, which carries only the item's own state flags.","type":"CustomEvent<MenuItemStateChangeDetail>"}]}},{"name":"lr-menu-label","description":"`<lr-menu-label>` — a non-interactive section heading inside `<lr-menu>`'s default slot.\n\n`role=\"presentation\"` on the host: a `role=\"menu\"` may only contain menu-item roles, so a\nheading that kept a generic role would make the menu's own children invalid. The visible text\nstill reads normally in reading order, and `<lr-menu>`'s roving tabindex skips this element\nbecause it is not a `LyraMenuItem` — a label is never a focus stop.\n\nKeep selectable items directly assigned or forwarded into the menu's default slot, with this\nlabel as a sibling visual caption. Arbitrary group wrappers do not enroll their nested items\nin the menu's keyboard navigation or selection handling.\n\n---\n\n**Component metadata**\n\n- Status: `stable`\n- Since: `8.0.0`\n- Rationale: This tag entered Lyra as a stable public API with documented behavior, accessibility, and cross-browser support.\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 heading text. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The heading row. |","attributes":[{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"role","description":"Light-DOM semantic role. Reflected so the default is available to server renderers before\nbrowser connection; authored values remain authoritative.\n\nType: `string | null`  \nDefault: `'presentation'`"}],"slots":[{"name":"","description":"The heading text."}],"js":{"properties":[{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"role","description":"Light-DOM semantic role. Reflected so the default is available to server renderers before\nbrowser connection; authored values remain authoritative.\n\nAttribute: `role`  \nReflected to its attribute.","type":"string | null","default":"'presentation'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}]}},{"name":"lr-message-actions","description":"`<lr-message-actions>` — the per-message action toolbar for `<lr-chat-message>`'s `actions`\nslot: opt-in built-ins (copy / regenerate / edit / feedback) that emit intent events, plus a\ndefault slot for custom controls (e.g. a slotted `<lr-branch-picker>`). It performs nothing\nitself except the copy.\n\n`[part=\"base\"]` is `role=\"toolbar\"` with the WAI-ARIA APG roving-tabindex pattern applied to the\nplain `<button>` elements this component renders itself (`regenerate`/`edit`); ArrowLeft/ArrowRight\n(swapped under `effectiveDirection === 'rtl'`) plus Home/End move focus across every logical\naction. Plain light-DOM actions are flattened directly. Composite controls opt into the exported\n`LyraToolbarActionProvider` protocol, which keeps implementation nodes private while exposing\nordered focus/tab-stop operations and stable action IDs. Both feedback thumbs and both branch\ncontrols therefore remain independent arrow-key stops without parent shadow-root inspection.\nWhen a managed action leaves the toolbar, its optional `releaseTabIndex()` restores an untouched\nauthored tab stop; a consumer change made after toolbar management always remains authoritative.\nProviders notify availability/order changes with `lr-toolbar-actions-change`; plain authored\nactions are observed in light DOM. A former stop is cleared, and if it held focus, focus moves to\nthe nearest survivor or the stable toolbar without overriding a newer external focus move.\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.\nBuilt-in control names normalize first-wins before rendering, focus navigation, or intent\nevents, so each built-in can occur at most once. Provider action ids must be nonblank and unique\nwithin that provider; invalid actions and later duplicates are omitted.\n\nArrowLeft/ArrowRight/Home/End from a slotted feedback comment editor remain native editing keys. Roving navigation still operates on the actual toolbar and thumb actions.\n\nThe toolbar has no `size`/`compact` property of its own: every built-in action composes\n`<lr-icon-button>` (the embedded `lr-copy-button` does the same one level deeper), so each one's\nhit area is that component's shared `--lr-icon-button-size` floor (2.5rem/40px), same as\neverywhere else in the library. For a dense action row where 40px per action is more than the\nlayout can afford, lower `--lr-icon-button-size-scope` (the subtree-scoped input) or\n`--lr-theme-icon-button-size` (the application-wide one) -- NOT `--lr-icon-button-size` itself,\nwhich every `LyraElement` re-declares on its own `:host` and so never reaches a composed child\n(`internal/tokens.test.ts` proves this) -- on this element or any ancestor of it;\n`::part(regenerate-button__control)`/`::part(edit-button__control)` also reach the built-ins'\ncomposed native controls directly for a one-off override. Either way the shrink is local to the\nelements it targets, not a library-wide floor change. A coarse-pointer/no-hover safety net\n(`internal/tokens.styles.ts`'s `baseTokens`) then floors the rendered hit area back at\n2.75rem/44px regardless of how far the dense-row override lowered it, so an intentionally\ncramped desktop toolbar is still comfortably tappable the moment the pointer reaching it is a\nfinger rather than a mouse.\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) | Additional controls (e.g. `lr-copy-button`, `lr-icon-button`, `lr-branch-picker`) appended after the built-ins; they participate in the toolbar's arrow-key navigation. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The toolbar (`role=\"toolbar\"`). |\n| `copy-button` | The embedded `lr-copy-button`. |\n| `edit-button` | The built-in edit action, likewise a composed `<lr-icon-button>`. |\n| `edit-button__control` | The edit action's own native `<button>`. |\n| `feedback` | The embedded `lr-message-feedback`. |\n| `regenerate-button` | The built-in regenerate action, a composed `<lr-icon-button>` as of 16.0.0. It still owns the accessible name, the activation and the toolbar tab stop; its background, radius, hover/press mixes, focus ring and hit-area floor now come from `--lr-icon-button-*`. |\n| `regenerate-button__control` | The regenerate action's own native `<button>`, forwarded because the painted surface sits one shadow boundary deeper than `regenerate-button`. |","attributes":[{"name":"aria-label","description":"Overrides the toolbar's computed accessible name. Wins over `label` and the localized\ndefault. Attribute-reflects from a host-level `aria-label` so a plain-markup consumer gets\nARIA-name forwarding without setting a JS property.\n\nType: `string | null`  \nDefault: `null`"},{"name":"copy-text","description":"What the `copy` built-in copies. Required for it to render at all -- this component never\ninterprets the slotted message body itself.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"feedback-rating","description":"Forwarded to the embedded thumbs-only `lr-message-feedback` when enabled.\n\nType: `MessageFeedbackValue`  \nDefault: `null`","value":{"type":["'up'","'down'"]}},{"name":"label","description":"Accessible name for the toolbar. Defaults to the localized `messageActionsLabel`.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"reveal-on-interaction","description":"Visually hides the bar until the enclosing message is hovered or any control inside has focus.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"","description":"Additional controls (e.g. `lr-copy-button`, `lr-icon-button`, `lr-branch-picker`) appended after the built-ins; they participate in the toolbar's arrow-key navigation."}],"js":{"properties":[{"name":"accessibleLabel","description":"Overrides the toolbar's computed accessible name. Wins over `label` and the localized\ndefault. Attribute-reflects from a host-level `aria-label` so a plain-markup consumer gets\nARIA-name forwarding without setting a JS property.\n\nAttribute: `aria-label`","type":"string | null","default":"null"},{"name":"controls","description":"Which built-ins render, in display order. Duplicate names normalize first-wins.","type":"readonly MessageActionControl[]","default":"[]"},{"name":"copyText","description":"What the `copy` built-in copies. Required for it to render at all -- this component never\ninterprets the slotted message body itself.\n\nAttribute: `copy-text`","type":"string","default":"''"},{"name":"feedbackPending","description":"Whether this component's current built-in feedback child is awaiting a persistence settle.\nThis is a nonreflecting read-through; no `feedback-pending` attribute or change event exists.","type":"boolean","read-only":true},{"name":"feedbackRating","description":"Forwarded to the embedded thumbs-only `lr-message-feedback` when enabled.\n\nAttribute: `feedback-rating`","type":"MessageFeedbackValue","default":"null"},{"name":"label","description":"Accessible name for the toolbar. Defaults to the localized `messageActionsLabel`.\n\nAttribute: `label`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"revealOnInteraction","description":"Visually hides the bar until the enclosing message is hovered or any control inside has focus.\n\nAttribute: `reveal-on-interaction`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-copy","description":"Clipboard writing fulfilled. Frozen `detail: { ok: true, text }`, surfaced by the embedded `lr-copy-button` (bubbles + composed already; not re-emitted, so exactly one event reaches a host listener).","type":"CustomEvent<LyraClipboardWriteSuccess>"},{"name":"lr-copy-error","description":"Clipboard writing failed. Frozen `detail: { ok: false, text, reason, error }` from the embedded copy button.","type":"CustomEvent<LyraClipboardWriteFailure>"},{"name":"lr-edit","description":"The edit built-in was activated: a *request* to edit; the host swaps the message body for its own editor.","type":"CustomEvent<null>"},{"name":"lr-error","description":"Clipboard writing failed; generic `detail: null` signal from the embedded copy button.","type":"CustomEvent<null>"},{"name":"lr-feedback-change","description":"Bubbles unchanged from the embedded, thumbs-only `lr-message-feedback`. `detail: { rating }`. A colliding event from a slotted custom child is contained at the slot boundary and remains observable directly on that child.","type":"CustomEvent<{ rating: MessageFeedbackValue }>"},{"name":"lr-feedback-submit","description":"The built-in feedback control's terminal cancelable persistence request, including thumbs-only choices. Its frozen detail includes a nonblank `submissionId`; when prevented, pass that exact ID to `finalizePendingSubmit()` or `revertPendingSubmit()` on this wrapper. Slotted collisions are contained at the slot boundary.","type":"CustomEvent<LyraEventDetailSnapshot<MessageFeedbackSubmitDetail>>"},{"name":"lr-regenerate","description":"The regenerate built-in was activated. No detail.","type":"CustomEvent<null>"}]}},{"name":"lr-message-feedback","description":"`<lr-message-feedback>` — thumbs up/down for one assistant message, with an optional inline\ndetail step (categorical reason chips + a free-text comment) that opens as a disclosure directly\nbelow the thumbs. `rating` is the current presentation state; every terminal persistence request\nuses the same cancelable `lr-feedback-submit` transaction.\n\nActivating the pressed thumb while its detail panel is open toggles it off to `null` (mirrors\n`<lr-rating>`'s re-activate-to-clear contract). If that applicable panel was closed without\nchanging the rating (for example with Escape), activating the still-pressed thumb reopens it with\nthe surviving draft. A thumbs-only configuration (no `detail`, e.g.\n`<lr-message-actions>`'s embedded built-in) never has a panel to reopen, so its thumbs always\nbehave as a plain toggle.\nThe detail record and its reasons are a bounded clone-owned readonly snapshot. Create and\nreassign a new detail record after changes. When the detail record enables a comment textarea,\nits native `spellcheck`, `autocapitalize`, `autocorrect`, and `wrap` properties forward from\nthis element; no textarea exists, and those values have no rendered target, otherwise.\n\nAsynchronous finalization or reversion preserves focus on an outside control. Settlement retains the existing thumb/submit fallback when focus remains within the feedback or was lost as its pending controls became disabled.\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 root. |\n| `comment` | The comment `<textarea>`. Only rendered when `detail.commentable` is true. |\n| `down-button` | The thumbs-down toggle button. |\n| `panel` | The inline detail disclosure. Only rendered for a non-empty `detail`. |\n| `reasons` | The reason-chip group. Only rendered when `detail.reasons` is non-empty. |\n| `submit-button` | The panel's submit button. |\n| `thumbs` | The wrapper around both thumb buttons. |\n| `up-button` | The thumbs-up toggle button. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-message-feedback-down-active-bg` (default: `var(--lr-color-danger-quiet)`) — Background of the pressed thumbs-down button.\n- `--lr-message-feedback-down-active-border` (default: `var(--lr-color-danger)`) — Border color of the pressed thumbs-down button.\n- `--lr-message-feedback-down-active-color` (default: `var(--lr-color-danger)`) — Glyph color of the pressed thumbs-down button.\n- `--lr-message-feedback-up-active-bg` (default: `var(--lr-color-success-quiet)`) — Background of the pressed thumbs-up button.\n- `--lr-message-feedback-up-active-border` (default: `var(--lr-color-success)`) — Border color of the pressed thumbs-up button.\n- `--lr-message-feedback-up-active-color` (default: `var(--lr-color-success)`) — Glyph color of the pressed thumbs-up button. Not declared on `:host`, so it can be set on the element or any ancestor; scoped to the pressed state, unlike overriding the shared `--lr-color-success`.","attributes":[{"name":"autocapitalize","description":"Native autocapitalization hint for the optional comment textarea. Empty preserves its default.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"autocorrect","description":"Native autocorrect state for the optional comment textarea. Reads are boolean; writes also\naccept the legacy `'off'` and `'false'` string forms.\n\nType: `boolean`","value":{"type":["boolean"]}},{"name":"detail-for","description":"Which rating opens the configured detail panel. `'none'` explicitly makes even a populated\nconfiguration thumbs-only; `'up'`, `'down'` (default), and `'both'` select ownership.\n\nType: `MessageFeedbackDetailFor`  \nDefault: `'down'`","value":{"type":["'none'","'up'","'down'","'both'"]}},{"name":"disabled","description":"Read-only display of a recorded rating -- both thumbs become inert.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"pending","description":"A canceled `lr-feedback-submit` is awaiting host persistence. While true, every feedback control is\ndisabled and the open panel is busy. Resolve through `finalizePendingSubmit()` or\n`revertPendingSubmit()`; the component sets this state automatically.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"rating","description":"Current provisional or persisted rating. Host-writable for controlled restoration.\n\nType: `MessageFeedbackValue`  \nDefault: `null`","value":{"type":["'up'","'down'"]}},{"name":"spellcheck","description":"Native spellcheck state for the optional comment textarea. `spellcheck=\"false\"` parses false.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"wrap","description":"Native wrapping mode for the optional comment textarea. Removing `wrap` restores `'soft'`.\n\nType: `MessageFeedbackWrap`  \nDefault: `'soft'`","value":{"type":["'hard'","'soft'","'off'"]}}],"js":{"properties":[{"name":"autocapitalize","description":"Native autocapitalization hint for the optional comment textarea. Empty preserves its default.\n\nAttribute: `autocapitalize`","type":"string","default":"''"},{"name":"autocorrect","description":"Native autocorrect state for the optional comment textarea. Reads are boolean; writes also\naccept the legacy `'off'` and `'false'` string forms.\n\nAttribute: `autocorrect`","type":"boolean"},{"name":"detail","description":"One clone-owned explicit detail configuration. Omit it for a thumbs-only control; reassign a\nnew record after changing its reasons.","type":"MessageFeedbackDetailConfiguration | undefined"},{"name":"detailFor","description":"Which rating opens the configured detail panel. `'none'` explicitly makes even a populated\nconfiguration thumbs-only; `'up'`, `'down'` (default), and `'both'` select ownership.\n\nAttribute: `detail-for`","type":"MessageFeedbackDetailFor","default":"'down'"},{"name":"disabled","description":"Read-only display of a recorded rating -- both thumbs become inert.\n\nAttribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"pending","description":"A canceled `lr-feedback-submit` is awaiting host persistence. While true, every feedback control is\ndisabled and the open panel is busy. Resolve through `finalizePendingSubmit()` or\n`revertPendingSubmit()`; the component sets this state automatically.\n\nAttribute: `pending`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"rating","description":"Current provisional or persisted rating. Host-writable for controlled restoration.\n\nAttribute: `rating`  \nReflected to its attribute.","type":"MessageFeedbackValue","default":"null"},{"name":"spellcheck","description":"Native spellcheck state for the optional comment textarea. `spellcheck=\"false\"` parses false.\n\nAttribute: `spellcheck`","type":"boolean","default":"true"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"wrap","description":"Native wrapping mode for the optional comment textarea. Removing `wrap` restores `'soft'`.\n\nAttribute: `wrap`","type":"MessageFeedbackWrap","default":"'soft'"}],"events":[{"name":"blur","description":"Re-dispatched from the comment `<textarea>`'s own native `blur` -- bubbling and composed (unlike the native event, which is neither), so a listener above the shadow boundary can observe it. Mirrors `<lr-model-select>`'s identical re-dispatch for its own free-text `<input>`.","type":"CustomEvent<null>"},{"name":"focus","description":"Re-dispatched from the comment `<textarea>`'s own native `focus`, for the same reason as `blur`.","type":"CustomEvent<null>"},{"name":"lr-feedback-change","description":"`detail: { rating }`. Fires whenever thumb interaction changes the provisional rating, including clearing it to `null`.","type":"CustomEvent<{ rating: MessageFeedbackValue }>"},{"name":"lr-feedback-submit","description":"Frozen `detail: { rating, reasonIds, comment, submissionId }`, fired immediately for a thumbs-only terminal choice or by the detail panel's submit button. `submissionId` is a nonblank, never-reused transaction identity. Cancelable: `preventDefault()` holds the panel in its reflected `pending` state until the host calls `finalizePendingSubmit(submissionId)` after persistence succeeds or `revertPendingSubmit(submissionId)` after it fails. The legacy no-argument settle form works only for this instance's first never-invalidated transaction; later calls fail closed. An uncanceled submit retains the synchronous close/announce/focus behavior.","type":"CustomEvent<LyraEventDetailSnapshot<MessageFeedbackSubmitDetail>>"},{"name":"lr-toolbar-actions-change","description":"No-detail coordination event emitted when the logical toolbar actions exposed by this provider change availability or order.","type":"Event"}]}},{"name":"lr-message-parts","description":"`<lr-message-parts>` — renders ordered, interleavable provider-neutral AI message parts. It\ncomposes Lyra's existing Markdown, reasoning, tool, citation, attachment, widget, JSON, and\nmedia primitives while keeping streaming order stable by part id.\nPart ids are unique, nonempty occurrence identities. Empty ids are omitted; when malformed\ninput repeats an id, the first occurrence wins and later duplicates are ignored. Rendering,\ncitation ranks, retry payloads, and error announcements all consume that same projection.\nStreaming text and reasoning parts forward that state into their nested Markdown renderer, so\nparsing/highlighting coalesces until the same-id part becomes complete.\nStreaming text and reasoning show accumulated plain text; Markdown parsing and syntax\nhighlighting wait until that part completes.\n\nCitation ranks are derived in one linear render prepass, including for mixed streaming arrays.\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: `7.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| `attachment` | An attachment part. |\n| `audio` | An audio part. |\n| `audio-control` | The native audio playback control. |\n| `audio-transcript` | An audio part's transcript. |\n| `base` | The ordered message-part list. |\n| `citation` | A citation part. |\n| `data` | A data or widget part. |\n| `error` | An error part. |\n| `part` | Every rendered part wrapper. |\n| `part-streaming` | Additional part name on a streaming part. |\n| `reasoning` | A reasoning part. |\n| `retry` | A retryable error part's action. |\n| `text` | A text part. |\n| `tool-call` | A tool-call part. |\n| `tool-result` | A tool-result part. |\n| `tool-result-error` | Error copy for a failed tool-result part. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-message-parts-audio-transcript-color` (default: `var(--lr-color-text-quiet)`) — Text color of an audio transcript.\n- `--lr-message-parts-error-background` (default: `var(--lr-color-danger-quiet)`) — Background color of an error part.\n- `--lr-message-parts-error-border-color` (default: `var(--lr-color-danger)`) — Border color of an error part.\n- `--lr-message-parts-error-color` (default: `var(--lr-color-danger)`) — Text color of an error part.\n- `--lr-message-parts-streaming-color` (default: `var(--lr-color-text-quiet)`) — Text color of a streaming part wrapper.","attributes":[{"name":"aria-label","description":"Accessible name override for the internal message-part group.\n\nType: `string | null`  \nDefault: `null`"},{"name":"content-mode","description":"Text/reasoning rendering mode. Unsupported direct or attribute values normalize and reflect\nas `markdown`, including when the current value is already `markdown`.\n\nType: `MessagePartsContentMode`","value":{"type":["'plain'","'markdown'"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max-rendered-parts","description":"`0` (the default) renders every part -- unbounded, matching every prior release. A positive\nvalue windows rendering to the newest N parts (host `parts` data is untouched); citation\nranks are still computed against the full sequence first, so a badge's number stays stable\neven once an earlier citation rolls out of the rendered window. Opt in for a message that can\ngrow an unusually large number of parts (e.g. a long agentic run with many interleaved\ntool-call/tool-result parts), where unbounded live DOM can visibly stall the main thread.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"show-reasoning","description":"Include reasoning parts.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}}],"js":{"properties":[{"name":"accessibleLabel","description":"Accessible name override for the internal message-part group.\n\nAttribute: `aria-label`","type":"string | null","default":"null"},{"name":"contentMode","description":"Text/reasoning rendering mode. Unsupported direct or attribute values normalize and reflect\nas `markdown`, including when the current value is already `markdown`.\n\nAttribute: `content-mode`  \nReflected to its attribute.","type":"MessagePartsContentMode"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"maxRenderedParts","description":"`0` (the default) renders every part -- unbounded, matching every prior release. A positive\nvalue windows rendering to the newest N parts (host `parts` data is untouched); citation\nranks are still computed against the full sequence first, so a badge's number stays stable\neven once an earlier citation rolls out of the rendered window. Opt in for a message that can\ngrow an unusually large number of parts (e.g. a long agentic run with many interleaved\ntool-call/tool-result parts), where unbounded live DOM can visibly stall the main thread.\n\nAttribute: `max-rendered-parts`","type":"number","default":"0"},{"name":"parts","description":"Ordered message content.","type":"readonly MessagePart[]","default":"[]"},{"name":"renderPart","description":"Optional host renderer. Returning `undefined` delegates to the built-in renderer.","type":"MessagePartRenderer | undefined"},{"name":"showReasoning","description":"Include reasoning parts.\n\nAttribute: `show-reasoning`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-anchor-result","description":"Passthrough from rendered Markdown.","type":"CustomEvent<AnchorResultDetail>"},{"name":"lr-citation-open","description":"Passthrough from a rendered citation's full-preview action.","type":"CustomEvent<CitationOpenDetail>"},{"name":"lr-citation-select","description":"A citation part was activated. `detail: { citation }`.","type":"CustomEvent<LyraEventDetailSnapshot<CitationSelectEventDetail>>"},{"name":"lr-copy","description":"Passthrough from rendered JSON content.","type":"CustomEvent<LyraClipboardWriteSuccess>"},{"name":"lr-highlight-activate","description":"Passthrough from rendered Markdown.","type":"CustomEvent<HighlightActivateDetail>"},{"name":"lr-link-click","description":"Passthrough from rendered Markdown.","type":"CustomEvent<{ href: string }>"},{"name":"lr-part-retry","description":"Retry was requested for a retryable error part. `detail: { part }`.","type":"CustomEvent<LyraEventDetailSnapshot<{ part: MessagePart }>>"},{"name":"lr-preview-request","description":"Passthrough from a rendered attachment. Not cancelable since 10.0.0.","type":"CustomEvent<LyraAttachmentPreviewRequestDetail>"},{"name":"lr-remove","description":"Passthrough from a rendered attachment.","type":"CustomEvent<LyraAttachmentIdDetail>"},{"name":"lr-render-error","description":"Passthrough from rendered Markdown, tool-result, or widget content.","type":"CustomEvent<{ error: unknown } | { toolName: string; error: unknown }>"},{"name":"lr-retry","description":"Passthrough from a rendered attachment.","type":"CustomEvent<LyraAttachmentIdDetail>"},{"name":"lr-search-change","description":"Passthrough from rendered JSON content.","type":"CustomEvent<{\n    query: string;\n    matchCount: number;\n    matchCountExact: boolean;\n    activeIndex: number;\n  }>"},{"name":"lr-text-select","description":"Passthrough from rendered Markdown.","type":"CustomEvent<TextSelectDetail>"},{"name":"lr-toggle","description":"Passthrough from a rendered reasoning panel.","type":"CustomEvent<ThinkingPanelToggleDetail>"},{"name":"lr-tool-call-chip-select","description":"Passthrough from a rendered tool-call chip. The `lr-tool-chip-select` alias it replaced was removed in 9.0.0.","type":"CustomEvent<ToolChipSelectDetail>"},{"name":"lr-widget-action","description":"Passthrough from a rendered declarative widget.","type":"CustomEvent<{\n    actionId: string;\n    payload: unknown;\n    nodeId: string;\n    nodeKey: string;\n    nodePath: string;\n  }>"},{"name":"lr-widget-state-change","description":"Passthrough from a rendered controlled widget.","type":"CustomEvent<{\n    path: string;\n    value: unknown;\n    nodeId: string;\n    nodeKey: string;\n    nodePath: string;\n    prop: string;\n  }>"}]}},{"name":"lr-mind-map","description":"`<lr-mind-map>` — a radial expandable topic tree (NotebookLM Mind Maps): a spatial overview of\na topic hierarchy where activating a topic drills in or hands the topic to the chat. Hierarchy,\nnot network — no cross-links, no force simulation, no communities, no edge labels (that's\n`lr-graph`). Zero-dependency SVG; the radial layout is closed-form arithmetic, in its own\n`mind-map-layout.ts` module, mirroring `lr-word-cloud`'s dependency-free precedent.\n\nNode-position transitions use `--lr-transition-base`, which already collapses to near-zero\nunder `prefers-reduced-motion: reduce` globally (`tokens.styles.ts`), so expansion snaps rather\nthan tweening for a reduced-motion user with no extra branching in this component.\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**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The wrapper. |\n| `empty` | The empty-state message, shown when `topics` is empty. |\n| `focus-ring` | The keyboard focus ring, drawn from the moment the svg takes focus (the first placed topic is seeded as the keyboard cursor) rather than only after the first arrow key. |\n| `link` | A parent-child connector. |\n| `live-region` | The visually hidden announcement region. |\n| `node` | A topic node group. |\n| `node-label` | A topic's label text. |\n| `svg` | The single-tab-stop SVG focus target. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-mind-map-node-hover-halo` (default: `var(--lr-color-brand-quiet)`) — Stroke color of the hover halo drawn around a topic node's dot, giving mouse users the same \"this is clickable\" feedback keyboard users get from the drawn focus ring.\n- `--lr-mind-map-ring-gap` (default: `6rem`) — Radius step per depth ring.","attributes":[{"name":"expand-depth","description":"Initial expansion depth (root + first ring). Expansion state is component-managed\nafterward, keyed by topic id, and survives `topics` reassignment.\n\nType: `number`  \nDefault: `1`","value":{"type":["number"]}},{"name":"label","description":"Accessible name for the SVG group *and* the implicit hub's text; falls back to the localized\n`mindMapLabel` when omitted. An explicitly empty override stays empty.\n\nType: `string | undefined`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"js":{"properties":[{"name":"expandDepth","description":"Initial expansion depth (root + first ring). Expansion state is component-managed\nafterward, keyed by topic id, and survives `topics` reassignment.\n\nAttribute: `expand-depth`","type":"number","default":"1"},{"name":"label","description":"Accessible name for the SVG group *and* the implicit hub's text; falls back to the localized\n`mindMapLabel` when omitted. An explicitly empty override stays empty.\n\nAttribute: `label`","type":"string | undefined"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"topics","description":"A single root sits at the center; multiple roots hang off an implicit center hub whose\nvisible text is `label`.","type":"readonly LyraTopic[]","default":"[]"}],"events":[{"name":"lr-topic-select","description":"A *leaf* topic was activated. `detail: { topicId }`.","type":"CustomEvent<{ topicId: string }>"},{"name":"lr-topic-toggle","description":"A parent topic was activated (or auto-expanded by keyboard descent). `detail: { topicId, expanded }`.","type":"CustomEvent<{ topicId: string; expanded: boolean }>"}]}},{"name":"lr-model-select","description":"`<lr-model-select>` — a provider/model picker that renders as a closed\ndropdown when a fixed `catalog` is available, or as a filterable free-text\ncombobox when it isn't (or when `allow-custom` explicitly permits typing\nsomething outside the catalog). Built directly on the shared\ntrigger-button/aria-activedescendant listbox technique `<lr-select>` uses\nand the filter-as-you-type suggestion-popup technique `<lr-combobox>`\nuses — not by composing either element, since the mode switch and the\nstale-value handling below are specific to this control.\n\nA `value` that isn't present in `catalog` (e.g. a model id saved from a\nprovider whose live catalog has since changed) is never silently dropped:\n`effectiveEntries` appends it to the rendered option list as a synthetic,\nvisually-distinct row (dashed border, italic label, \"not in catalog\"\nbadge — see `model-select.styles.ts`) computed fresh from `catalog` +\n`value` on every render, without ever mutating the `catalog` property\nitself.\n\nObject-shaped catalog rows can include a literal `icon`, rendered decoratively as the leading\n`option-icon` part in either listbox mode. It is presentation only: the row's accessible name\nremains its `label`.\n\nA catalog row may also set `disabled`, marking it non-actionable: `aria-disabled=\"true\"`\nreplaces its selected/active affordances, activating it (click or keyboard) commits nothing and\nchanges no state, and arrow-key/Home/End active-descendant navigation steps past it instead of\nlanding on it. Omitted or `false` renders the row exactly as before this field existed.\n\n\nShips the standard label/hint/error form-control chrome: properties, matching named slots, and\nthe complete `form-control` frame. Each surface is opt-in; left unset, it renders no chrome.\nA focused trigger/input follows a rendering-mode replacement. If that new owner is disabled or\ninert, focus returns to the available element that led into the picker, or to the stable\n`form-control` owner when there is no return target; a newer external focus move always wins.\nArray-valued catalogs are clone-owned, bounded readonly snapshots. Create and reassign a new\ncatalog array after changing its rows.\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| `error` | Custom error content. |\n| `hint` | Custom hint content. |\n| `label` | Custom visible label content. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `combobox` | The text-input container (free-text mode's positioning anchor). |\n| `combobox-input` | The free-text mode's text input. |\n| `empty` | The empty-listbox message, shown when no rows match. |\n| `error` | The error message. |\n| `expand-icon` | The dropdown indicator. |\n| `form-control` | The complete label, control, hint, error, and listbox frame. |\n| `form-control-label` | The `<label>` element containing the `label` property and slot. |\n| `hint` | The hint message. |\n| `listbox` | The options popover (shared by both modes). |\n| `option` | An option row. |\n| `option-badge` | The \"not in catalog\" badge on a synthetic stale-value row. |\n| `option-icon` | An option row's optional decorative leading icon. |\n| `option-label` | An option row's label. |\n| `provider-badge` | The optional leading `provider` label. |\n| `trigger` | The trigger button (closed-dropdown mode's positioning anchor). |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-form-control-required-color` (default: `var(--lr-color-danger)`) — Required-marker color, themeable independently of error text and invalid borders.\n- `--lr-form-control-required-content` (default: `' *'`) — The required marker appended to `form-control-label` while `required` is set. Set it to `''` to suppress the marker, or to any other quoted string (`' (required)'`, a localized word) to replace it.\n- `--lr-form-control-required-offset` (default: `0`) — Inline space between the label text and the required marker.\n- `--lr-model-select-expand-size` (default: `var(--lr-size-1-75rem)`) — Decorative expand-icon box size, scaled by `size`.\n- `--lr-model-select-font-size` (default: `var(--lr-form-control-font-size)`) — Trigger/combobox font size, scaled by `size` off the shared control ladder.\n- `--lr-model-select-gap` (default: `var(--lr-space-xs)`) — Trigger, combobox, and option child gap.\n- `--lr-model-select-max-inline-size` (default: `var(--lr-size-24rem)`) — The host's own width ceiling. Set a length to retune it, or `none` to let the control fill its container the way `<lr-select>` does.\n- `--lr-model-select-open-border-color` (default: `var(--lr-color-brand)`) — Open trigger border color.\n- `--lr-model-select-option-active-bg` (default: `var(--lr-color-brand-quiet)`) — Background of a hovered or keyboard-active option row.\n- `--lr-model-select-option-disabled-opacity` (default: `0.5`) — Opacity of an option row whose catalog entry sets `disabled`.\n- `--lr-model-select-option-selected-bg` (default: `transparent`) — Background of the currently-selected option row. Not declared on `:host`; retheme without hijacking `--lr-color-brand`.\n- `--lr-model-select-option-selected-border` (default: `var(--lr-color-brand)`) — Border color of the selected option row.\n- `--lr-model-select-option-selected-color` (default: `var(--lr-color-brand)`) — Text color of the selected option row.\n- `--lr-model-select-option-selected-font-weight` (default: `var(--lr-font-weight-semibold)`) — Font weight of the selected option row.\n- `--lr-model-select-option-synthetic-border-color` (default: `var(--lr-color-border)`) — Border color of a synthetic stale-value option row.\n- `--lr-model-select-option-synthetic-border-style` (default: `dashed`) — Border style of a synthetic stale-value option row.\n- `--lr-model-select-radius` (default: `var(--lr-radius)`) — Trigger, combobox, listbox, and option corner radius.\n- `--lr-model-select-trigger-border-color` (default: `var(--lr-color-border)`) — Resting trigger/combobox border color, independent of the open-state color below.\n- `--lr-model-select-trigger-fill` (default: `var(--lr-color-surface)`) — Resting trigger/combobox background.\n- `--lr-model-select-trigger-height` — Exact trigger/combobox height. Unset by default (a floor only, via `-trigger-min-height`); set a length to both floor and cap the control, e.g. to pixel-match a sibling field in the same toolbar row. Takes precedence over `-trigger-min-height`.\n- `--lr-model-select-trigger-min-height` (default: `var(--lr-form-control-height)`) — Trigger/combobox block-size floor, scaled by `size` off the shared control ladder.\n- `--lr-model-select-trigger-padding` (default: `var(--lr-form-control-padding-block) var(--lr-form-control-padding-inline)`) — Trigger/combobox padding shorthand, scaled by `size` off the shared control ladder.\n- `--lr-overlay-border` (default: `var(--lr-color-border)`) — Shared floating-surface edge colour, on the listbox.\n- `--lr-overlay-radius` (default: `var(--lr-radius)`) — Shared floating-surface corner radius, read by the listbox only as the middle arm of `--lr-model-select-radius`, which still wins when set.\n- `--lr-overlay-shadow-anchored` (default: `var(--lr-shadow-m)`) — Elevation of the anchored surface.\n- `--lr-overlay-surface` (default: `var(--lr-color-surface-overlay)`) — Shared floating-surface fill, on the listbox.","attributes":[{"name":"allow-custom","description":"Let the user type/commit a value that isn't in `catalog`, even when `catalog` is non-empty.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"autocapitalize","description":"Forwarded to the free-text mode's native `<input>`'s own `autocapitalize`. Empty string omits\nthe attribute (browser default).\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"autocomplete","description":"Native editing and virtual-keyboard hints forwarded to free-text mode's input.\n\nType: `string`  \nDefault: `'off'`","value":{"type":["string"]}},{"name":"autocorrect","description":"Forwarded to the free-text mode's native `<input>`'s own `autocorrect` (Safari/WebKit-specific).\nEmpty string omits the attribute (browser default). Named `autoCorrect` (capital `C`), not\n`autocorrect`, purely to dodge a TS `lib.dom.d.ts` collision: newer DOM typings declare a\n`boolean`-typed `HTMLElement.autocorrect` IDL member, which conflicts with this string-typed\nproperty of the same name -- same rename fix as `<lr-date-input>` (`<lr-textarea>` instead\nkeeps the native `autocorrect` name and overrides it as a boolean accessor). The explicit\nattribute mapping preserves the lowercase wire name in generated component metadata.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"custom-error","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nType: `string | null`"},{"name":"disabled","description":"Type: `boolean`","value":{"type":["boolean"]}},{"name":"enterkeyhint","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"error-text","description":"Error text below the field (overridden by slotted `error` content). Unset (the default): no\nerror chrome renders.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"form","description":"Type: `HTMLFormElement | string | null`  \nDefault: `null`"},{"name":"hint","description":"Hint text below the field. Unset (the default): no hint chrome renders.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"inputmode","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"label","description":"Optional visible title above the control, rendered alongside the `label` slot in a\n`part=\"form-control-label\"` `<label>` paired with the active control's id. A host `aria-label`\nremains authoritative by presence; otherwise either visible-label source supplies the native\nassociated name. Leaving both empty keeps the `aria-label || placeholder || 'Model'` chain.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"name","description":"The form submission key, reflected synchronously for native form APIs.\n\nType: `string`","value":{"type":["string"]}},{"name":"open","description":"Whether the model list is open. Effectively disabled controls reject direct reopen attempts,\nincluding a synchronous fieldset cascade.\n\nType: `boolean`","value":{"type":["boolean"]}},{"name":"placeholder","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"provider","description":"Informational only — e.g. `'ollama'`. Rendered as a small leading badge for display grouping.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"readonly","description":"Keeps user edits and catalog commits from changing `value` while retaining focus, popup\nnavigation, selection/copy, form submission, reset, and programmatic writes.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"required","description":"Type: `boolean`","value":{"type":["boolean"]}},{"name":"size","description":"Visual size, on the library-wide six-step ladder (`2xs`–`xl`). `small`/`medium`/`large` are\naccepted spellings of `s`/`m`/`l` and render identically, so markup migrated from Web Awesome\nor Shoelace needs no attribute rewrite.\n\nType: `LyraSize`  \nDefault: `'m'`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}},{"name":"spellcheck","description":"Forwarded to the free-text mode's native `<input>`'s own `spellcheck`. Defaults to `true`,\nmatching the native element's own default. No effect in closed-dropdown mode (no native text\ninput there). `spellcheck=\"false\"` is parsed as `false` (see `spellcheckConverter` above).\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"value","description":"Reflected current reset default; changing it never overwrites a dirty live `value`.\n\nType: `string`","value":{"type":["string"]}}],"slots":[{"name":"error","description":"Custom error content."},{"name":"hint","description":"Custom hint content."},{"name":"label","description":"Custom visible label content."}],"js":{"properties":[{"name":"allowCustom","description":"Let the user type/commit a value that isn't in `catalog`, even when `catalog` is non-empty.\n\nAttribute: `allow-custom`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"autoCorrect","description":"Forwarded to the free-text mode's native `<input>`'s own `autocorrect` (Safari/WebKit-specific).\nEmpty string omits the attribute (browser default). Named `autoCorrect` (capital `C`), not\n`autocorrect`, purely to dodge a TS `lib.dom.d.ts` collision: newer DOM typings declare a\n`boolean`-typed `HTMLElement.autocorrect` IDL member, which conflicts with this string-typed\nproperty of the same name -- same rename fix as `<lr-date-input>` (`<lr-textarea>` instead\nkeeps the native `autocorrect` name and overrides it as a boolean accessor). The explicit\nattribute mapping preserves the lowercase wire name in generated component metadata.\n\nAttribute: `autocorrect`","type":"string","default":"''"},{"name":"autocapitalize","description":"Forwarded to the free-text mode's native `<input>`'s own `autocapitalize`. Empty string omits\nthe attribute (browser default).\n\nAttribute: `autocapitalize`","type":"string","default":"''"},{"name":"autocomplete","description":"Native editing and virtual-keyboard hints forwarded to free-text mode's input.\n\nAttribute: `autocomplete`","type":"string","default":"'off'"},{"name":"catalog","description":"The clone-owned full model list. Omit (or leave empty) to fall back to plain free-text entry.\nCatalog ids must be nonempty and unique; malformed rows and later duplicates are omitted,\nfirst wins. Reassign a new array after changes.","type":"LyraCatalog<LyraModelCatalogEntry> | undefined"},{"name":"customError","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nAttribute: `custom-error`  \nReflected to its attribute.","type":"string | null"},{"name":"defaultValue","description":"Reflected current reset default; changing it never overwrites a dirty live `value`.\n\nAttribute: `value`  \nReflected to its attribute.","type":"string"},{"name":"disabled","description":"Attribute: `disabled`  \nReflected to its attribute.","type":"boolean"},{"name":"effectiveDisabled","description":"Whether the control is disabled explicitly or by an ancestor fieldset.","type":"boolean","read-only":true},{"name":"enterKeyHint","description":"Attribute: `enterkeyhint`","type":"string","default":"''"},{"name":"errorText","description":"Error text below the field (overridden by slotted `error` content). Unset (the default): no\nerror chrome renders.\n\nAttribute: `error-text`","type":"string","default":"''"},{"name":"form","description":"Attribute: `form`  \nReflected to its attribute.","type":"HTMLFormElement | string | null","default":"null"},{"name":"hint","description":"Hint text below the field. Unset (the default): no hint chrome renders.\n\nAttribute: `hint`","type":"string","default":"''"},{"name":"input","description":"The native editable input in free-text mode, or `null` in closed-dropdown mode and before render.","type":"HTMLInputElement | null","read-only":true},{"name":"inputMode","description":"Attribute: `inputmode`","type":"string","default":"''"},{"name":"label","description":"Optional visible title above the control, rendered alongside the `label` slot in a\n`part=\"form-control-label\"` `<label>` paired with the active control's id. A host `aria-label`\nremains authoritative by presence; otherwise either visible-label source supplies the native\nassociated name. Leaving both empty keeps the `aria-label || placeholder || 'Model'` chain.\n\nAttribute: `label`","type":"string","default":"''"},{"name":"labels","type":"NodeList","read-only":true},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"name","description":"The form submission key, reflected synchronously for native form APIs.\n\nAttribute: `name`  \nReflected to its attribute.","type":"string"},{"name":"open","description":"Whether the model list is open. Effectively disabled controls reject direct reopen attempts,\nincluding a synchronous fieldset cascade.\n\nAttribute: `open`  \nReflected to its attribute.","type":"boolean"},{"name":"placeholder","description":"Attribute: `placeholder`","type":"string","default":"''"},{"name":"provider","description":"Informational only — e.g. `'ollama'`. Rendered as a small leading badge for display grouping.\n\nAttribute: `provider`","type":"string","default":"''"},{"name":"readonly","description":"Keeps user edits and catalog commits from changing `value` while retaining focus, popup\nnavigation, selection/copy, form submission, reset, and programmatic writes.\n\nAttribute: `readonly`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"required","description":"Attribute: `required`  \nReflected to its attribute.","type":"boolean"},{"name":"selectionDirection","type":"LyraModelSelectSelectionDirection | null"},{"name":"selectionEnd","type":"number | null"},{"name":"selectionStart","type":"number | null"},{"name":"size","description":"Visual size, on the library-wide six-step ladder (`2xs`–`xl`). `small`/`medium`/`large` are\naccepted spellings of `s`/`m`/`l` and render identically, so markup migrated from Web Awesome\nor Shoelace needs no attribute rewrite.\n\nAttribute: `size`  \nReflected to its attribute.","type":"LyraSize","default":"'m'"},{"name":"spellcheck","description":"Forwarded to the free-text mode's native `<input>`'s own `spellcheck`. Defaults to `true`,\nmatching the native element's own default. No effect in closed-dropdown mode (no native text\ninput there). `spellcheck=\"false\"` is parsed as `false` (see `spellcheckConverter` above).\n\nAttribute: `spellcheck`","type":"boolean","default":"true"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"validationMessage","type":"string","read-only":true},{"name":"validity","type":"ValidityState","read-only":true},{"name":"value","description":"The current model id (empty string when nothing is selected).","type":"string"},{"name":"willValidate","type":"boolean","read-only":true}],"events":[{"name":"blur","description":"Owner-realm native blur relayed once from the active control in either rendering mode, retaining `relatedTarget`.","type":"FocusEvent"},{"name":"change","description":"Owner-realm native event fired alongside `lr-change`, mirroring `<lr-select>`/`<lr-combobox>`'s value-change pair so native form bindings/framework `v-model` handlers behave consistently across the picker family.","type":"Event"},{"name":"focus","description":"Owner-realm native focus relayed once from the active control in either rendering mode, retaining `relatedTarget`.","type":"FocusEvent"},{"name":"input","description":"A payload-preserving owner-realm `InputEvent` on each free-text edit, and a plain native `Event` alongside `change` when either rendering mode commits a value.","type":"Event"},{"name":"lr-change","description":"The selected/typed value changed. `detail: { value: string; inCatalog: boolean }`.","type":"CustomEvent<{ value: string; inCatalog: boolean }>"},{"name":"lr-invalid","description":"The picker failed a validity check. Cancelable: calling `preventDefault()` also cancels the native `invalid` event behind it, suppressing the browser's own validation bubble so an app can present the failure its own way.","type":"CustomEvent<null>"}]}},{"name":"lr-model-settings-panel","description":"`<lr-model-settings-panel>` — a fixed composition of `<lr-model-select>`\nand `<lr-slider>` into one agent-configuration card: pick a provider's\nmodel, then tune its sampling temperature. Not a generic layout shell (no\nslots) — it exists so a consumer doesn't have to re-wire the same two\nchild `lr-change` events into one combined settings object by hand every\ntime this pairing comes up.\n\nEvery prop here is a plain pass-through to (or mirror of) the matching\nchild control's own prop of the same/similar name; see the child\ncomponents themselves for the exact semantics of `catalog`/`allowCustom`\nand `temperatureMin`/`temperatureMax`/`temperatureStep`.\nArray-valued catalogs are clone-owned, bounded readonly snapshots. Create and reassign a new\ncatalog array after changing its rows.\n\nThe panel's own `temperature` readout mirrors the slider's *live* value —\nupdated on every `lr-input` (drag/key-repeat), not just the committed\n`lr-change` — and is re-clamped into `[temperatureMin, temperatureMax]`\n(snapped to `temperatureStep`) whenever those three properties change, so\nit can never drift from what the nested `lr-slider` itself shows.\nThe visible temperature readout uses the effective locale and switches to bounded scientific\nnotation when a full decimal expansion would disturb the layout. The slider retains the exact\nfinite value through `aria-valuenow`.\nNative `focus` and `blur` relayed by the nested model selector or slider remain local to that\nchild; this panel exposes only its declared consolidated `lr-change` event.\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 outermost wrapping container. |\n| `model-label` | The model selector's visible label. |\n| `model-row` | The row wrapping the internal `lr-model-select`. |\n| `model-select` | The internal model selector. |\n| `temperature-label` | The visible \"Temperature\" caption. |\n| `temperature-row` | The row wrapping the temperature label/slider/value. |\n| `temperature-value` | The visible current temperature readout. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-model-settings-panel-max-inline-size` (default: `var(--lr-size-28rem)`) — The card's own width ceiling. Set a length to retune it or `none` for a full-width card. `layout=\"compact\"` uncaps the card by default, and reads the same name, so a length still narrows a compact card.","attributes":[{"name":"allow-custom","description":"Let the model control accept a value outside `catalog`; passed straight through.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"disabled","description":"Disables the panel as a unit by forwarding to both the internal\n`lr-model-select` and `lr-slider` — a wrapping `<fieldset disabled>`\nalone would not reach either, since a form-associated control's own\n`disabled` IDL property/attribute is never mutated by fieldset cascading.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"layout","description":"Type: `ModelSettingsPanelLayout`","value":{"type":["'vertical'","'compact'"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"model","description":"The current model id.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"provider","description":"Informational provider badge, passed straight through to the internal `lr-model-select`.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"temperature","description":"The current sampling temperature.\n\nType: `number`  \nDefault: `1`","value":{"type":["number"]}},{"name":"temperature-max","description":"Type: `number`  \nDefault: `2`","value":{"type":["number"]}},{"name":"temperature-min","description":"Type: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"temperature-step","description":"Type: `number`  \nDefault: `0.1`","value":{"type":["number"]}}],"js":{"properties":[{"name":"allowCustom","description":"Let the model control accept a value outside `catalog`; passed straight through.\n\nAttribute: `allow-custom`","type":"boolean","default":"false"},{"name":"catalog","description":"The clone-owned model list, normalized to unique nonempty first-wins ids by the internal\n`lr-model-select` and by this panel's `inCatalog` event computation. Reassign a new array\nafter changes.","type":"LyraCatalog<LyraModelCatalogEntry> | undefined"},{"name":"disabled","description":"Disables the panel as a unit by forwarding to both the internal\n`lr-model-select` and `lr-slider` — a wrapping `<fieldset disabled>`\nalone would not reach either, since a form-associated control's own\n`disabled` IDL property/attribute is never mutated by fieldset cascading.\n\nAttribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"layout","description":"Attribute: `layout`  \nReflected to its attribute.","type":"ModelSettingsPanelLayout"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"model","description":"The current model id.\n\nAttribute: `model`","type":"string","default":"''"},{"name":"provider","description":"Informational provider badge, passed straight through to the internal `lr-model-select`.\n\nAttribute: `provider`","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"temperature","description":"The current sampling temperature.\n\nAttribute: `temperature`","type":"number","default":"1"},{"name":"temperatureMax","description":"Attribute: `temperature-max`","type":"number","default":"2"},{"name":"temperatureMin","description":"Attribute: `temperature-min`","type":"number","default":"0"},{"name":"temperatureStep","description":"Attribute: `temperature-step`","type":"number","default":"0.1"}],"events":[{"name":"lr-change","description":"Either child control changed. `detail: { model: string; inCatalog: boolean; temperature: number }` — always the full current settings, not just whatever changed.","type":"CustomEvent<ModelSettingsChangeDetail>"}]}},{"name":"lr-multi-split","description":"`<lr-multi-split>` — resizable panels for dashboard layouts. Direct light-DOM\nchildren are the panels; a divider is auto-inserted between each pair. Give every panel a\nunique, nonempty, whitespace-stable `panel-id` when using `storageKey`: persistence records `panelId`/size pairs,\nso reordered or replaced panels recover the size belonging to their business identity instead\nof whichever panel happens to occupy the old array index. Missing or duplicate identities fail\npersistence closed while leaving the live, non-persisted split usable.\nIn a fixed block allocation, each direct panel is a scroll container\n(`min-block-size: 0; overflow: auto`) so long content stays within the\nsplit instead of escaping into following content. Set an individual\npanel's own `overflow` when it needs a different scrolling surface.\n\nOptionally, one pane can opt in to responsive collapse via `collapse`\n(`\"start\"`/`\"end\"`, default `\"none\"` — no behavior change when unset): as\nthe split's own container narrows past `railBreakpoint` that pane clamps\nto a fixed `railWidth`, and past the narrower `floatBreakpoint` it instead\nbecomes an absolutely-positioned overlay \"floating card\" above the other\npane. Both breakpoints accept a bare pixel number or a CSS length\n(`px`/`rem`/`em`), and `collapseBreakpointBasis=\"viewport\"` measures them\nagainst the viewport via `matchMedia` instead of this component's own\nallocation. This component only handles the width-collapse mechanics and\nsignals the current state — via the `collapseState`-derived\n`data-collapse-state` attribute (set on both the host and the collapsing\npanel itself) and the `lr-multi-split-collapse-change` event — it renders no\nicon-only/collapsed UI of its own; slotted content is expected to adapt to\nits own clamped width (e.g. via its own container query).\n\n`collapseState` is a public accessor with force/auto semantics mirroring\n`<lr-app-rail>`'s `mode`: it's normally derived automatically from the\nmeasured container width (via a `ResizeObserver` on `[part=\"base\"]`)\nwhenever it crosses `railBreakpoint`/`floatBreakpoint`, but assigning it a\nconcrete `'wide'`/`'rail'`/`'floating'` value pins it there and stops that\nautomatic tracking — useful for a consumer-driven toggle (e.g. a button\nthat forces `'floating'` regardless of width). Assigning the write-only\n`'auto'` sentinel releases the pin and immediately re-derives the state\nfrom the current measured width, resuming automatic tracking. `'auto'` is\nnever a value this getter returns. `expandPane()`/`collapsePane()`/`togglePane()` drive the\nsame two mechanisms semantically -- each picks the drawer or the pin according to the pane's\ncurrent band, so a consumer-built trigger no longer has to branch on `collapseState`\nitself -- and `releasePinOnBreakpoint` opts a pin in to releasing itself when the band or\nthe effective orientation moves on, instead of leaking into the next layout.\nWhile `collapse=\"none\"` or fewer than two direct panels exist, the public\nand reflected effective state is always `'wide'`: a forced rail/floating\nintent is retained privately for a later eligible pane but cannot emit,\nrender a backdrop, acquire focus/scroll-lock ownership, or project panel\nmarkers. Enabling/disabling an eligible pane is itself an effective state\ntransition; disabling closes `open` and releases overlay/focus ownership.\n\nThe `'floating'` state is a hidden-by-default drawer, gated by `open`\n(mirrors `<lr-app-rail>`'s mobile overlay): while `collapseState` is\n`'floating'` and `open` is `false` (the default), the collapsing panel\nrenders nothing — `hidden`, out of the accessibility tree, not just\nvisually hidden — instead of the always-visible overlay card this state\nrendered before `open` existed. Setting `open = true` reveals it as a\nfocus-trapped floating panel with a `[part=\"backdrop\"]` scrim; Escape or a\nbackdrop click proposes a cancelable close before changing `open`. Every sibling pane behind the drawer is inert for the\nsame interval, while the floating pane is the shared overlay manager's modal root. `open` is preserved (not reset)\nwhile `collapseState` isn't `'floating'`, but no drawer chrome renders\nuntil it is again — except that leaving `'floating'` while `open` is\n`true` (a breakpoint crossing back to `'wide'`/`'rail'`, or a forced\nreassignment) also closes it, the same way `<lr-app-rail>` closes its\nmobile overlay when leaving `'mobile'` while open.\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: `9.0.0`\n- Rationale: This tag entered Lyra as a stable public API with documented behavior, accessibility, and cross-browser support.\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) | Panels to arrange side by side (or stacked, when `orientation=\"vertical\"`); each direct child becomes one resizable panel. Set a unique nonempty, whitespace-stable `panel-id` on every panel when using persistence. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `backdrop` | The `'floating'` drawer's scrim. Only rendered while `collapseState === 'floating'` and `open`. |\n| `base` | The flex layout wrapper (`position: relative`, so the `'floating'` collapse state can anchor to it). |\n| `divider` | Each `role=\"separator\"` between two panels. `aria-valuenow` is the leading panel's percentage; `aria-valuemin`/`aria-valuemax` are that divider's currently achievable range, bounded by both adjacent panels' effective constraints and their current combined share (not whole-track bounds). Home/End move directly to those achievable extremes. Carries `aria-disabled=\"true\"` and is drag/keyboard-inert while its adjacent panel is collapsed (`'rail'`/`'floating'`). |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-multi-split-divider-active-color` (default: `color-mix(in oklab,var(--lr-color-brand),var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — The divider hairline's color while a resize gesture is pressed (pointer capture holds this through the whole drag).\n- `--lr-multi-split-divider-color` (default: `var(--lr-color-border)`) — The divider hairline's resting color.\n- `--lr-multi-split-divider-hover-color` (default: `var(--lr-color-brand)`) — The divider hairline's color on hover.\n- `--lr-multi-split-divider-target-size` (default: `max(var(--lr-icon-button-size),var(--lr-size-3px))`) — The real layout gutter reserved for each divider along the resize axis. The narrow visual rule is centered inside this owned track, so the target never overlaps either adjacent panel.\n- `--lr-multi-split-divider-thickness` (default: `var(--lr-size-3px)`) — The painted hairline's own thickness, independent of `--lr-multi-split-divider-target-size` above -- retuning either one never changes the other, so the WCAG 2.5.8 pointer target can never be shrunk by a thinner or thicker visual line.\n- `--lr-multi-split-floating-panel-inline-size` — Overrides the `'floating'` collapse state's overlay card `inline-size`, which otherwise mirrors its own live `sizes[i]` percent (i.e. what it renders at in the `'wide'` state). Unset, geometry is identical to today's behavior; set, it wins over that percent without needing `!important` against the live-synced inline style.\n- `--lr-multi-split-floating-panel-inset` (default: `0`) — The `'floating'` drawer's distance from `[part=\"base\"]`'s edges, applied to both block insets and to whichever logical inline edge `collapse` anchors the drawer to. Unset, the drawer stays flush with the container exactly as before; set once, it insets on all three anchored edges (the free inline edge stays governed by the panel's own width).\n- `--lr-multi-split-overlay-color` (default: `var(--lr-color-overlay)`) — The `'floating'` drawer scrim's color, applied to `[part=\"backdrop\"]`.","attributes":[{"name":"collapse","description":"Opts a pane in to responsive collapse: `'start'` is the first light-DOM\npanel (index 0), `'end'` is the last. Both are LOGICAL positions, same\nas CSS `inset-inline-start`/`-end` — see the `collapsingIndex` getter\nfor why that already resolves to the same physical index under RTL for\nthis component (panels are never re-`order`ed for RTL, only the drag\ndelta sign mirrors). Default `'none'`: none of the collapse behavior\nbelow applies, and rendering/behavior is identical to before this\nproperty existed.\n\nType: `LyraMultiSplitCollapseMode`  \nDefault: `'none'`","value":{"type":["'start'","'end'","'none'"]}},{"name":"collapse-breakpoint-basis","description":"Which box `railBreakpoint`/`floatBreakpoint` measure. `'container'` (the default) observes\nthis component's own `[part=\"base\"]` inline size via `ResizeObserver`, comparing strictly `<`.\n`'viewport'` instead evaluates `matchMedia('(max-width: <breakpoint>)')` for each of the two\nthresholds, which is inclusive (`<=`) — native `max-width` semantics, deliberately, so the\ncrossing point matches a CSS `@media` rule authored with the same length exactly. Switching\nbasis therefore shifts each crossing point by 1px (the same trade-off\n`orientationBreakpointBasis` already makes).\n\nUse `'viewport'` to collapse in step with a page-level responsive layout — e.g. a shell whose\nown `@media` rules restack at the same width — rather than with this split's own allocation.\n`'viewport'` also lets the browser resolve a `rem` breakpoint with real `@media` semantics\n(against the *initial* font size, ignoring an `html { font-size }` override), keeping it in\nstep with such a rule.\n\nBoth bands are classified from both queries together on every change, so a fast resize that\ncrosses both thresholds at once still lands on one correct state and fires\n`lr-multi-split-collapse-change` once. Under `'viewport'` basis the first paint is already correct —\nno `ResizeObserver` round-trip — and the initial state is not announced as a transition.\n\nDefault: `'container'`.\n\nType: `BreakpointBasis`  \nDefault: `'container'`","value":{"type":["'container'","'viewport'"]}},{"name":"collapse-state","description":"The collapsing pane's effective responsive state. Always one of the three\nreal states — never `'auto'` — and always `'wide'` while collapse is\ndisabled or fewer than two panels exist. Otherwise it reflects either the\nlive measured width or, once forced, whatever was last assigned. See the\nclass doc for the full force/auto contract.\n\nType: `LyraMultiSplitCollapseState`","value":{"type":["'wide'","'rail'","'floating'"]}},{"name":"float-breakpoint","description":"Width below which the collapsing pane instead becomes an absolutely-positioned overlay above\nthe other pane (`'floating'` state). Same accepted forms, basis, and sanitization as\n`railBreakpoint`; an unparseable value falls back to the `400` default.\n\nDefault: `400`.\n\nType: `| number\n    | string`  \nDefault: `400`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"min","description":"Type: `number`  \nDefault: `10`","value":{"type":["number"]}},{"name":"narrow-orientation","description":"Layout/resize axis used below `orientationBreakpoint`.\n\nType: `LyraOrientation`  \nDefault: `'vertical'`","value":{"type":["'horizontal'","'vertical'"]}},{"name":"open","description":"Whether the `'floating'` collapse state's drawer is shown. Only\nmeaningful while `collapseState` is `'floating'` — the value is\npreserved (not reset) while another state is active, but no drawer\nchrome renders until `collapseState` is `'floating'` again. Defaults to\n`false`: the collapsing pane renders nothing while floating until a\nconsumer opts in by setting this (or it's forced open programmatically)\n— see the class doc.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"orientation","description":"Type: `LyraOrientation`  \nDefault: `'horizontal'`","value":{"type":["'horizontal'","'vertical'"]}},{"name":"orientation-breakpoint","description":"Opt-in inline-size breakpoint for this component's *own* measured allocation. Below it,\n`narrowOrientation` becomes effective. Unset by default — the whole responsive-orientation\nfeature (and its `ResizeObserver`) is off, and `effectiveOrientation` just tracks\n`orientation`.\n\nAccepts a bare pixel number (`900`, `orientation-breakpoint=\"900\"` — the original form) or a\nCSS length string: `'900px'`, `'56.25rem'`, `'3em'`. Under the default\n`orientationBreakpointBasis=\"container\"`, `rem` resolves against the *document root*'s\ncomputed font size — the rule a `@container` query follows, not a `@media` query's — and `em`\nagainst this element's own computed font size. The length is re-resolved on every measurement,\nnever cached at first render, so a root font-size change moves the crossing width with no\ninvalidation step. To stay in step with a sibling `@media (max-width: 56.25rem)` rule, use\n`orientationBreakpointBasis=\"viewport\"`, which hands the length to the browser instead; see\nthat property for why the two resolve `rem` differently.\n\nAnything else — `''`, `'auto'`, garbage, a non-finite number, and deliberately `%`/`vw`/`vh`/\n`calc()` (which would mix reference boxes against an element-relative measurement) — behaves\nexactly as unset. Set `orientationBreakpointBasis=\"viewport\"` for a viewport-relative\nbreakpoint instead.\n\nType: `| number\n    | string | undefined`"},{"name":"orientation-breakpoint-basis","description":"Which box `orientationBreakpoint` measures. `'container'` (the default) observes this\ncomponent's own `[part=\"base\"]` inline size via `ResizeObserver`, comparing strictly `<`.\n`'viewport'` instead evaluates `matchMedia('(max-width: <breakpoint>)')`, which is inclusive\n(`<=`) — native `max-width` semantics, deliberately, so the crossing point matches a CSS\n`@media` rule authored with the same length exactly.\n\nUse `'viewport'` when two siblings in one row must flip together at a shared breakpoint: a row\nthat stacks via a pure-CSS `@media` rule makes each sibling's own width non-monotonic across\nthe transition, so no self-measured threshold can express it. `'viewport'` also lets the\nbrowser resolve a `rem` breakpoint with real `@media` semantics, keeping it in step with such\na rule across browser zoom and user font-size preferences.\n\nType: `BreakpointBasis`  \nDefault: `'container'`","value":{"type":["'container'","'viewport'"]}},{"name":"rail-breakpoint","description":"Width below which the collapsing pane switches from its normal percent width to the fixed\n`railWidth` (`'rail'` state). Must stay above `floatBreakpoint` — an inverted pair is\nsanitized by raising this one to match, which collapses the `'rail'` band away rather than\nleaving a wide container reported as collapsed.\n\nAccepts a bare pixel number (`640`, `rail-breakpoint=\"640\"` — the original form) or a CSS\nlength string: `'640px'`, `'68.75rem'`, `'3em'`. Under the default\n`collapseBreakpointBasis=\"container\"` this is compared against this component's own measured\n`[part=\"base\"]` inline size, strictly `<`, and `rem` resolves against the *document root*'s\ncomputed font size (a `@container` query's rule, not a `@media` query's) while `em` resolves\nagainst this element's own. The length is re-resolved on every measurement, never cached, so\na root font-size change moves the crossing width with no invalidation step.\n\nAnything the grammar rejects — `''`, `'auto'`, garbage, a non-finite number, and deliberately\n`%`/`vw`/`vh`/`calc()`/`var()` — falls back to the `640` default rather than switching the\nfeature off (unlike `orientationBreakpoint`, this breakpoint has a documented default to fall\nback to). A negative length is floored at `0`, i.e. never crossed.\n\nDefault: `640`.\n\nType: `| number\n    | string`  \nDefault: `640`"},{"name":"rail-width","description":"Fixed CSS length the collapsing pane clamps to in the `'rail'` state.\n\nType: `string`  \nDefault: `'3.5rem'`","value":{"type":["string"]}},{"name":"release-pin-on-breakpoint","description":"Opts a pinned `collapseState` (see that accessor's force/auto contract) in to releasing\nitself when the layout it was made for is gone: either the measured collapse band changes to\na different one than the pin was created in, or `effectiveOrientation` crosses\n`orientationBreakpoint`. The pin is dropped exactly as if `'auto'` had been assigned, and the\nstate re-derives from the current measurement, firing `lr-multi-split-collapse-change` if that\nis an actual transition.\n\nDefault `false`, which is the pre-existing behavior: a pin survives every band and orientation\nchange until a consumer assigns `'auto'`. Opt in when a pin is meant for one layout only --\ne.g. a rail pinned for a wide dashboard that must not leak into the narrow, drawer-based\nlayout, which otherwise has to be undone by hand from an `lr-multi-split-collapse-change` or\n`lr-multi-split-orientation-change` listener. Re-measuring the SAME band never releases a\npin, so an ordinary resize inside one band leaves it alone.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"storage-key","description":"When set, this instance's panel sizes are persisted to `localStorage`, keyed by this value\nplus each panel's identity (`panel-id`, falling back to DOM order), and restored on the next\nmount. Initialization-time precedence, highest first: an already-valid `sizes` binding (an\nexplicit authored layout for THIS mount always wins and is never silently replaced), then a\nvalid persisted layout, then `defaultSizes`, then equal distribution. Restoring persisted\nstate never fires an event -- read `sizes` after the component's first update to observe it.\n\nType: `string | undefined`"}],"slots":[{"name":"","description":"Panels to arrange side by side (or stacked, when `orientation=\"vertical\"`); each direct child becomes one resizable panel. Set a unique nonempty, whitespace-stable `panel-id` on every panel when using persistence."}],"js":{"properties":[{"name":"collapse","description":"Opts a pane in to responsive collapse: `'start'` is the first light-DOM\npanel (index 0), `'end'` is the last. Both are LOGICAL positions, same\nas CSS `inset-inline-start`/`-end` — see the `collapsingIndex` getter\nfor why that already resolves to the same physical index under RTL for\nthis component (panels are never re-`order`ed for RTL, only the drag\ndelta sign mirrors). Default `'none'`: none of the collapse behavior\nbelow applies, and rendering/behavior is identical to before this\nproperty existed.\n\nAttribute: `collapse`  \nReflected to its attribute.","type":"LyraMultiSplitCollapseMode","default":"'none'"},{"name":"collapseBreakpointBasis","description":"Which box `railBreakpoint`/`floatBreakpoint` measure. `'container'` (the default) observes\nthis component's own `[part=\"base\"]` inline size via `ResizeObserver`, comparing strictly `<`.\n`'viewport'` instead evaluates `matchMedia('(max-width: <breakpoint>)')` for each of the two\nthresholds, which is inclusive (`<=`) — native `max-width` semantics, deliberately, so the\ncrossing point matches a CSS `@media` rule authored with the same length exactly. Switching\nbasis therefore shifts each crossing point by 1px (the same trade-off\n`orientationBreakpointBasis` already makes).\n\nUse `'viewport'` to collapse in step with a page-level responsive layout — e.g. a shell whose\nown `@media` rules restack at the same width — rather than with this split's own allocation.\n`'viewport'` also lets the browser resolve a `rem` breakpoint with real `@media` semantics\n(against the *initial* font size, ignoring an `html { font-size }` override), keeping it in\nstep with such a rule.\n\nBoth bands are classified from both queries together on every change, so a fast resize that\ncrosses both thresholds at once still lands on one correct state and fires\n`lr-multi-split-collapse-change` once. Under `'viewport'` basis the first paint is already correct —\nno `ResizeObserver` round-trip — and the initial state is not announced as a transition.\n\nDefault: `'container'`.\n\nAttribute: `collapse-breakpoint-basis`  \nReflected to its attribute.","type":"BreakpointBasis","default":"'container'"},{"name":"collapseState","description":"The collapsing pane's effective responsive state. Always one of the three\nreal states — never `'auto'` — and always `'wide'` while collapse is\ndisabled or fewer than two panels exist. Otherwise it reflects either the\nlive measured width or, once forced, whatever was last assigned. See the\nclass doc for the full force/auto contract.\n\nAttribute: `collapse-state`  \nReflected to its attribute.","type":"LyraMultiSplitCollapseState"},{"name":"defaultSizes","description":"Initialization-only size fallback, below valid persistence and above equal distribution. Later\nassignments never overwrite live resize state. Each entry is either a plain number (percent of\nthe container, matching today's exact strict behavior) or a CSS length string (`'200px'`,\n`'20%'`, `'3rem'`) resolved against the measured container before percent-space validation --\nsee `resolveDefaultSizes()`. Initialization runs on the first update (not synchronously on\nconnection), so same-turn framework property bindings and `storageKey` persistence participate\nbefore the layout becomes live. A pure-number array is validated unchanged (an array that does\nnot sum to ~100 is still rejected).","type":"readonly (number | string)[]","default":"[]"},{"name":"dividerLabel","description":"Overrides the auto-inserted divider's `aria-label` — receives the divider's 0-based index\nand the total panel count (`lr-multi-split` supports N panels, so a single fixed string can't\nexpress every divider's label; a function can). Unset (the default) keeps today's exact\nlocalized `Resize divider between panel {a} and panel {b}` template (see `this.localize()`).","type":"(\n    index: number,\n    panelCount: number\n  ) => string | undefined"},{"name":"effectiveOrientation","description":"The live layout and resize axis after applying `orientationBreakpoint` — identical to\n`orientation` whenever `orientationBreakpoint` is unset (or set to something that doesn't\nresolve to a length). Also reflected as the `data-effective-orientation` host attribute (only\npresent while `orientationBreakpoint` resolves, mirroring `data-collapse-state`'s\nonly-present-while-active contract) so CSS can\ntarget the live axis directly instead of every consumer duplicating this fallback.","type":"LyraOrientation","read-only":true},{"name":"floatBreakpoint","description":"Width below which the collapsing pane instead becomes an absolutely-positioned overlay above\nthe other pane (`'floating'` state). Same accepted forms, basis, and sanitization as\n`railBreakpoint`; an unparseable value falls back to the `400` default.\n\nDefault: `400`.\n\nAttribute: `float-breakpoint`","type":"| number\n    | string","default":"400"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"min","description":"Attribute: `min`","type":"number","default":"10"},{"name":"narrowOrientation","description":"Layout/resize axis used below `orientationBreakpoint`.\n\nAttribute: `narrow-orientation`  \nReflected to its attribute.","type":"LyraOrientation","default":"'vertical'"},{"name":"open","description":"Whether the `'floating'` collapse state's drawer is shown. Only\nmeaningful while `collapseState` is `'floating'` — the value is\npreserved (not reset) while another state is active, but no drawer\nchrome renders until `collapseState` is `'floating'` again. Defaults to\n`false`: the collapsing pane renders nothing while floating until a\nconsumer opts in by setting this (or it's forced open programmatically)\n— see the class doc.\n\nAttribute: `open`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"orientation","description":"Attribute: `orientation`  \nReflected to its attribute.","type":"LyraOrientation","default":"'horizontal'"},{"name":"orientationBreakpoint","description":"Opt-in inline-size breakpoint for this component's *own* measured allocation. Below it,\n`narrowOrientation` becomes effective. Unset by default — the whole responsive-orientation\nfeature (and its `ResizeObserver`) is off, and `effectiveOrientation` just tracks\n`orientation`.\n\nAccepts a bare pixel number (`900`, `orientation-breakpoint=\"900\"` — the original form) or a\nCSS length string: `'900px'`, `'56.25rem'`, `'3em'`. Under the default\n`orientationBreakpointBasis=\"container\"`, `rem` resolves against the *document root*'s\ncomputed font size — the rule a `@container` query follows, not a `@media` query's — and `em`\nagainst this element's own computed font size. The length is re-resolved on every measurement,\nnever cached at first render, so a root font-size change moves the crossing width with no\ninvalidation step. To stay in step with a sibling `@media (max-width: 56.25rem)` rule, use\n`orientationBreakpointBasis=\"viewport\"`, which hands the length to the browser instead; see\nthat property for why the two resolve `rem` differently.\n\nAnything else — `''`, `'auto'`, garbage, a non-finite number, and deliberately `%`/`vw`/`vh`/\n`calc()` (which would mix reference boxes against an element-relative measurement) — behaves\nexactly as unset. Set `orientationBreakpointBasis=\"viewport\"` for a viewport-relative\nbreakpoint instead.\n\nAttribute: `orientation-breakpoint`","type":"| number\n    | string | undefined"},{"name":"orientationBreakpointBasis","description":"Which box `orientationBreakpoint` measures. `'container'` (the default) observes this\ncomponent's own `[part=\"base\"]` inline size via `ResizeObserver`, comparing strictly `<`.\n`'viewport'` instead evaluates `matchMedia('(max-width: <breakpoint>)')`, which is inclusive\n(`<=`) — native `max-width` semantics, deliberately, so the crossing point matches a CSS\n`@media` rule authored with the same length exactly.\n\nUse `'viewport'` when two siblings in one row must flip together at a shared breakpoint: a row\nthat stacks via a pure-CSS `@media` rule makes each sibling's own width non-monotonic across\nthe transition, so no self-measured threshold can express it. `'viewport'` also lets the\nbrowser resolve a `rem` breakpoint with real `@media` semantics, keeping it in step with such\na rule across browser zoom and user font-size preferences.\n\nAttribute: `orientation-breakpoint-basis`  \nReflected to its attribute.","type":"BreakpointBasis","default":"'container'"},{"name":"panelConstraints","description":"Optional px and/or percent min/max per panel, index-aligned with `sizes`. A\n`null`/missing entry leaves that panel purely percent-based (the\nexisting `min`-only behavior). `sizes`, the `lr-resize` payload, and\nlocalStorage persistence stay percent-based regardless — only the\neffective clamp bounds change for a constrained panel. Feasible pixel minimums survive flex\nshrink after divider gutters. When those floors cannot fit, panels share the remaining space\nproportionally instead of overflowing; percentage state remains unchanged. Gutter geometry\nfollows the actual divider, including live font-unit and token changes.","type":"readonly (LyraMultiSplitPanelConstraint | null)[]","default":"[]"},{"name":"railBreakpoint","description":"Width below which the collapsing pane switches from its normal percent width to the fixed\n`railWidth` (`'rail'` state). Must stay above `floatBreakpoint` — an inverted pair is\nsanitized by raising this one to match, which collapses the `'rail'` band away rather than\nleaving a wide container reported as collapsed.\n\nAccepts a bare pixel number (`640`, `rail-breakpoint=\"640\"` — the original form) or a CSS\nlength string: `'640px'`, `'68.75rem'`, `'3em'`. Under the default\n`collapseBreakpointBasis=\"container\"` this is compared against this component's own measured\n`[part=\"base\"]` inline size, strictly `<`, and `rem` resolves against the *document root*'s\ncomputed font size (a `@container` query's rule, not a `@media` query's) while `em` resolves\nagainst this element's own. The length is re-resolved on every measurement, never cached, so\na root font-size change moves the crossing width with no invalidation step.\n\nAnything the grammar rejects — `''`, `'auto'`, garbage, a non-finite number, and deliberately\n`%`/`vw`/`vh`/`calc()`/`var()` — falls back to the `640` default rather than switching the\nfeature off (unlike `orientationBreakpoint`, this breakpoint has a documented default to fall\nback to). A negative length is floored at `0`, i.e. never crossed.\n\nDefault: `640`.\n\nAttribute: `rail-breakpoint`","type":"| number\n    | string","default":"640"},{"name":"railWidth","description":"Fixed CSS length the collapsing pane clamps to in the `'rail'` state.\n\nAttribute: `rail-width`","type":"string","default":"'3.5rem'"},{"name":"releasePinOnBreakpoint","description":"Opts a pinned `collapseState` (see that accessor's force/auto contract) in to releasing\nitself when the layout it was made for is gone: either the measured collapse band changes to\na different one than the pin was created in, or `effectiveOrientation` crosses\n`orientationBreakpoint`. The pin is dropped exactly as if `'auto'` had been assigned, and the\nstate re-derives from the current measurement, firing `lr-multi-split-collapse-change` if that\nis an actual transition.\n\nDefault `false`, which is the pre-existing behavior: a pin survives every band and orientation\nchange until a consumer assigns `'auto'`. Opt in when a pin is meant for one layout only --\ne.g. a rail pinned for a wide dashboard that must not leak into the narrow, drawer-based\nlayout, which otherwise has to be undone by hand from an `lr-multi-split-collapse-change` or\n`lr-multi-split-orientation-change` listener. Re-measuring the SAME band never releases a\npin, so an ordinary resize inside one band leaves it alone.\n\nAttribute: `release-pin-on-breakpoint`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"sizes","type":"readonly number[]","default":"[]"},{"name":"storageKey","description":"When set, this instance's panel sizes are persisted to `localStorage`, keyed by this value\nplus each panel's identity (`panel-id`, falling back to DOM order), and restored on the next\nmount. Initialization-time precedence, highest first: an already-valid `sizes` binding (an\nexplicit authored layout for THIS mount always wins and is never silently replaced), then a\nvalid persisted layout, then `defaultSizes`, then equal distribution. Restoring persisted\nstate never fires an event -- read `sizes` after the component's first update to observe it.\n\nAttribute: `storage-key`","type":"string | undefined"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-multi-split-collapse-change","description":"`detail: { state }` (`LyraMultiSplitCollapseChangeDetail`), fired whenever the responsive `collapseState` actually transitions between `'wide'`/`'rail'`/`'floating'` — whether from a breakpoint crossing or an explicit `collapseState` assignment or collapse feature enable/disable. Fired AFTER the collapsing panel is decorated for the new state: its `data-collapse-state` marker, the `hidden` flag of the closed drawer and its owned inline sizing are all applied first, so a listener can read the panel synchronously inside its own handler instead of deferring past `updateComplete`. Focus is also moved out of a pane the new state hides or clamps before the event fires. Forced writes while no eligible collapsing pane exists are inert and do not fire. Not fired for a redundant reassignment to the state already in effect.","type":"CustomEvent<LyraMultiSplitCollapseChangeDetail>"},{"name":"lr-multi-split-constraints-invalid","description":"`detail: LyraMultiSplitConstraintIssueDetail`, fired once when the configured panel minimums/maximums cannot describe a layout that fits the track. The splitter rejects that infeasible set for interaction and falls back to a normalized percent minimum.","type":"CustomEvent<LyraMultiSplitConstraintIssueDetail>"},{"name":"lr-multi-split-orientation-change","description":"`detail: { orientation }`, fired when an enabled `orientationBreakpoint` changes the effective resize/layout axis.","type":"CustomEvent<LyraMultiSplitOrientationChangeDetail>"},{"name":"lr-resize","description":"`detail: { sizes }`, fired on every drag movement that changes sizes and every keyboard step after `sizes` is assigned. Non-cancelable; not fired when a consumer sets `sizes` directly. Pointer release persists the settled sizes but emits no additional event.","type":"CustomEvent<LyraEventDetailSnapshot<LyraMultiSplitResizeDetail>>"},{"name":"lr-resize-request","description":"A cancelable proposed `sizes` change from a divider drag or keyboard step. Call `preventDefault()` to keep `sizes` and persistence unchanged. Not fired when a consumer sets `sizes` directly. `detail: { sizes }` (`LyraMultiSplitResizeDetail`).","type":"CustomEvent<LyraEventDetailSnapshot<LyraMultiSplitResizeDetail>>"},{"name":"lr-toggle","description":"An Escape/backdrop request to close the floating drawer, or the forced close when an effective collapse transition leaves `'floating'` while open. `detail: LyraMultiSplitToggleDetail`. Escape/backdrop proposals are cancelable and fire before `open` changes; the forced responsive close is non-cancelable and fires after `open` is false. Direct `open` writes and no-op dismissals do not emit this event.","type":"CustomEvent<LyraMultiSplitToggleDetail>"}]}},{"name":"lr-mutation-observer","description":"`<lr-mutation-observer>` — observes element children in the default slot\nand forwards native mutation records as a composed event. It is useful for\nintegrating third-party renderers while keeping observer cleanup declarative.\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) | Elements to observe. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The non-layout wrapper around the observed slot. |","attributes":[{"name":"attr","description":"Mapped attribute selector: `*` observes all attributes; otherwise use space-separated names.\n\nType: `string | null`  \nDefault: `null`"},{"name":"attr-old-value","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"attributes","description":"Lyra compatibility alias for `attr` (its unfiltered boolean form, equivalent to `attr: '*'`\n-- observes every attribute with no name filtering). Reflects like every other mapped\nobserver attribute on this element so DOM introspection (`outerHTML`, attribute selectors,\nSSR re-serialization) stays consistent with a property assignment, not just a declarative one.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"char-data","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"char-data-old-value","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"character-data","description":"Lyra compatibility alias for `charData`. Reflects like every other mapped observer attribute\non this element so DOM introspection stays consistent with a property assignment, not just a\ndeclarative one.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"child-list","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"disabled","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"subtree","description":"Type: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}}],"slots":[{"name":"","description":"Elements to observe."}],"js":{"properties":[{"name":"attr","description":"Mapped attribute selector: `*` observes all attributes; otherwise use space-separated names.\n\nAttribute: `attr`  \nReflected to its attribute.","type":"string | null","default":"null"},{"name":"attrOldValue","description":"Attribute: `attr-old-value`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"attributeFilter","type":"string[]","default":"[]"},{"name":"charData","description":"Attribute: `char-data`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"charDataOldValue","description":"Attribute: `char-data-old-value`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"characterData","description":"Lyra compatibility alias for `charData`. Reflects like every other mapped observer attribute\non this element so DOM introspection stays consistent with a property assignment, not just a\ndeclarative one.\n\nAttribute: `character-data`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"childList","description":"Attribute: `child-list`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"disabled","description":"Attribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"observeAttributes","description":"Lyra compatibility alias for `attr` (its unfiltered boolean form, equivalent to `attr: '*'`\n-- observes every attribute with no name filtering). Reflects like every other mapped\nobserver attribute on this element so DOM introspection (`outerHTML`, attribute selectors,\nSSR re-serialization) stays consistent with a property assignment, not just a declarative one.\n\nAttribute: `attributes`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"subtree","description":"Attribute: `subtree`","type":"boolean","default":"true"}],"events":[{"name":"lr-mutation","description":"Observed DOM mutations; `detail.records` and `detail.mutationList` reference the same frozen readonly batch, whose native records retain identity.","type":"CustomEvent<\n    Readonly<{\n      records: readonly MutationRecord[];\n      mutationList: readonly MutationRecord[];\n    }>\n  >"}]}},{"name":"lr-native-time-input","description":"`<lr-native-time-input>` — the browser-native time field preserved from Lyra 7.\n\nUse this control when the platform's own `input[type=time]` UI is preferred. The segmented,\nlocale-aware Web Awesome-compatible field is `<lr-time-input>`.\n\nInherited stepUp/stepDown use pending value, step, min, and max properties synchronously\nand remain event-silent. Removed label/hint/help-text/error-text content is safely omitted.\n\n---\n\n**Component metadata**\n\n- Status: `stable`\n- Since: `8.0.0`\n- Rationale: This tag preserves the previously shipped native time-control contract while the primary lr-time-input name provides the segmented control.\n- Graduation: This compatibility surface remains stable while it preserves the Lyra 7 native behavior and has not entered a separately announced deprecation period.\n\n---\n\n**Slots**\n\n| Name | Description |\n| --- | --- |\n| `clear-icon` | Replaces the built-in clear glyph. |\n| `end` | Adornment after the native input and built-in actions. |\n| `error` | Custom error content. |\n| `help-text` | Shoelace alias for `hint`. |\n| `hide-password-icon` | Replaces the glyph shown while the password is visible. |\n| `hint` | Custom hint content. |\n| `label` | Custom label content. |\n| `prefix` | Shoelace alias for `start`. |\n| `show-password-icon` | Replaces the glyph shown while the password is hidden. |\n| `start` | Adornment before the native input. |\n| `suffix` | Shoelace alias for `end`. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | Compatibility name for the control row; use `time-input`. |\n| `clear-button` | The clear action, rendered for non-empty clearable text/search inputs. |\n| `end` | Wrapper around the `end` adornment slot, with the same containment behavior. |\n| `error` | The error message. |\n| `form-control` | The outer wrapper around label, input, error and hint. |\n| `form-control-help-text` | Shoelace compatibility name for the hint message. |\n| `form-control-input` | Compatibility name for the control row. |\n| `form-control-label` | The `<label>` element. |\n| `hint` | The hint message. |\n| `input` | The native `<input>` element. |\n| `input-wrapper` | The row wrapping the native input and built-in actions. It is the same node as `base`. |\n| `label` | Wrapper around the visible label content. |\n| `password-toggle` | The show/hide-password button, rendered only for `type=\"password\"` with `password-toggle` set. |\n| `password-toggle-button` | Wrapper around the password-toggle icon. |\n| `prefix` | Shoelace compatibility part on the `prefix` slot. |\n| `start` | Wrapper around the `start` adornment slot. Long content shrinks and ellipsizes rather than widening the control allocation. |\n| `suffix` | Shoelace compatibility part on the `suffix` slot. |\n| `time-input` | The native time control row. It is the same node as `base` and the inherited `input-wrapper` part. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-form-control-focus-shadow` (default: `none`) — The shared field focus halo, painted as a `box-shadow` while this control is focused. One name for every field-shaped control in the library, so a halo is configured once rather than per component. Additive: the focus outline and border cue are the accessibility answer to focus and are never replaced by it.\n- `--lr-form-control-required-color` (default: `var(--lr-color-danger)`) — Color of that marker, retunable without touching any other danger-coloured surface.\n- `--lr-form-control-required-content` (default: `' *'`) — The required-field marker rendered after the label. Set it to `''` to suppress the marker, or to any other quoted string (`' (required)'`, a localized word) to replace it. Caller-supplied content, so it is never localized here.\n- `--lr-form-control-required-offset` (default: `0`) — Inline space between the label text and the marker.\n- `--lr-input-action-active-bg` (default: `color-mix(in oklab,var(--lr-color-surface),var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Pressed action background. The same hooks apply to `lr-number-input`'s stepper pair.\n- `--lr-input-action-active-color` (default: `var(--lr-input-action-hover-color,var(--lr-color-text))`) — Pressed action color.\n- `--lr-input-action-color` (default: `var(--lr-color-text-quiet)`) — Resting clear/password/number- stepper action color.\n- `--lr-input-action-hover-color` (default: `var(--lr-color-text)`) — Hovered action color.\n- `--lr-input-border-color` (default: `var(--lr-color-border)`) — Border color of the control row, with a private default that changes per `appearance` in the same way as `--lr-input-fill`.\n- `--lr-input-control-height` — Exact outer control height. Unset by default, which leaves `--lr-input-control-min-height` as a floor only; set it to a length to both floor and cap the control row (e.g. to pixel-match `<lr-select>`/`<lr-combobox>` in the same toolbar). Because it is never declared by the component itself, it can be set from an ancestor or an outer-tree rule as well as inline on the element.\n- `--lr-input-control-min-height` (default: `var(--lr-form-control-height)`) — Outer control height floor, taken from the active `size` tier of the shared form-control ladder (`internal/sizes.styles.ts`), so an input is exactly as tall as an `<lr-button>`/`<lr-select>` of the same tier.\n- `--lr-input-fill` (default: `transparent`) — Background of the control row. Its private default changes per `appearance`; the public value remains authoritative in every appearance.\n- `--lr-input-focus-border-color` (default: `var(--lr-color-brand)`) — Control-row border color while focus is within the field.\n- `--lr-input-font-size` (default: `var(--lr-form-control-font-size)`) — Font size of the native input, from the active `size` tier.\n- `--lr-input-gap` (default: `var(--lr-space-xs)`) — Gap between the start/end adornments and the native input in the control row. Unlike the size knobs above it does not vary by `size` tier. Override it to retune without a `::part(input-wrapper)` rule.\n- `--lr-input-padding-block` (default: `var(--lr-form-control-padding-block)`) — Block padding of the native input, from the active `size` tier of the shared ladder.\n- `--lr-input-padding-inline` (default: `var(--lr-form-control-padding-inline)`) — Inline padding of the control row, from the active `size` tier.\n- `--lr-input-radius` (default: `var(--lr-form-control-radius)`) — Corner radius of the control row, from the active `size` tier of the shared ladder (the two tightest tiers take a smaller radius). `pill` swaps it to `--lr-radius-pill`.\n- `--lr-input-time-picker-active-bg` (default: `var(--lr-color-brand)`) — Pressed background for the browser-native time-picker indicator when `type=\"time\"`.\n- `--lr-input-time-picker-focus-bg` (default: `var(--lr-color-brand-quiet)`) — Focus-visible background for the native time-picker indicator.\n- `--lr-input-time-picker-focus-ring` (default: `var(--lr-focus-ring-color)`) — Focus-visible outline color for the native time-picker indicator.\n- `--lr-input-time-picker-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background for the browser-native time-picker indicator when `type=\"time\"`.","attributes":[{"name":"appearance","description":"Lyra 7 visual default retained intentionally while the mapped `lr-input` default moves to\noutlined in v8.\n\nType: `LyraAppearance`  \nDefault: `'filled-outlined'`","value":{"type":["'accent'","'filled'","'outlined'","'filled-outlined'","'plain'"]}},{"name":"aria-label","description":"Accessible name overriding the label/placeholder-derived default. Takes precedence over both\n`label` and `placeholder` when set, matching `<lr-textarea>`'s `accessibleLabel`.\n\nType: `string | null`  \nDefault: `null`"},{"name":"autocapitalize","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"autocomplete","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"autocorrect","description":"Native editing-assistance state forwarded as canonical `autocorrect=\"on\"|\"off\"`. Reads are\nboolean. Writes accept Web Awesome's boolean IDL and Shoelace's `'on'`/`'off'` vocabulary.\n\nType: `boolean`","value":{"type":["boolean"]}},{"name":"autofocus","description":"Forwarded to the internal native `<input>`, so the browser's own autofocus algorithm targets\nthe real text control rather than the (non-focusable) custom-element host.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"clearable","description":"Shows a built-in clear action for non-empty `text` and `search` inputs.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"custom-error","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nType: `string | null`  \nDefault: `null`"},{"name":"debounce","description":"How long (ms) to wait after the last keystroke before emitting one `lr-input-settled`,\ncoalescing a burst of rapid edits into a single downstream commit -- the same predicate and\n`DebounceController` primitive `<lr-filter-bar>`'s own per-filter `debounce` uses. Omitted,\n`0`, or a non-finite value means no debounce at all: `input`/`lr-input` keep firing per\nkeystroke exactly as before, and `lr-input-settled` never fires. A pending debounce is\nflushed immediately by `change`/Enter/blur (so a blur never drops the last keystroke) and\ncancelled with no stray settle by disconnection, the built-in clear button, and a\nprogrammatic `value` write that changes the value -- a same-value write does not disturb it.\n\nType: `number | undefined`"},{"name":"default-value","description":"Compatibility attribute alias for the supported `defaultValue` reset value.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"disabled","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"enterkeyhint","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"error-text","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"filled","description":"Shoelace's boolean spelling for the filled treatment. It does not overwrite an explicit\n`appearance`; the style alias simply paints the same fill while present.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"form","description":"Type: `HTMLFormElement | string | null`  \nDefault: `null`"},{"name":"help-text","description":"Shoelace alias for hint. `hint` wins when both are supplied.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"hint","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"inputmode","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"label","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"match","description":"Declarative cross-field confirmation constraint: a sibling field to compare this one's\n`value` against, referenced either by id (resolved in this element's own root — an idref\nnever crosses a shadow boundary, matching every other idref this library resolves) or by a\ndirect element reference (works across shadow trees, since no lookup is needed). While set\nand resolvable, this field additionally fails validity — `customError`, with a localized\nmismatch message — whenever its value differs from the referenced element's own `.value`.\nRe-validates automatically whenever either field changes: this field's own edits through the\nusual `value` write, and the referenced field's edits through a listener on its `input`/\n`change` events. A `match` that does not resolve to a live element (a dangling id, most\ncommonly) is inert rather than a permanent block on submission — exactly like the platform's\nown tolerance of an unresolvable `aria-describedby` idref. Pairs with a plain confirmation\nfield (`type=\"password\"` or otherwise); the referenced element only needs a string `.value`,\nso a native `<input>`/`<textarea>` works the same as another `lr-input`.\n\nType: `LyraMatchTarget`  \nDefault: `null`","value":{"type":["LyraMatchTarget"]}},{"name":"max","description":"Latest selectable native time.\n\nType: `number | string | undefined`"},{"name":"maxlength","description":"Upper counterpart of `minlength` (native `maxlength`/`tooLong`), with the same parsing and the\nsame default of `undefined`. Note that native `maxlength` also *prevents* typing beyond the\nlimit; it reports `tooLong` for values that arrive some other way (paste of a longer value,\na programmatic assignment).\n\nType: `number | undefined`"},{"name":"min","description":"Earliest selectable native time.\n\nType: `number | string | undefined`"},{"name":"minlength","description":"Minimum text length, forwarded to the internal native `<input>`'s own `minlength` and\nconsulted by that same native input's constraint validation (`tooShort`, see\n`updateValidity()`). Defaults to `undefined` (no lower bound). Like native `minlength`, an\nempty value never violates it — pair it with `required` to also reject empty. Ignored by the\nnative input for `type=\"number\"`/`type=\"time\"`, exactly as the platform specifies.\n\nType: `number | undefined`"},{"name":"name","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"no-spin-buttons","description":"Shoelace alias for withoutSpinButtons.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"password-toggle","description":"`type=\"password\"` only — renders the built-in show/hide-password button. Opt-in: a bare\n`type=\"password\"` field ships no toggle at all, so a consumer whose threat model or visual\ndesign excludes one is not forced to hide it with CSS.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"password-visible","description":"`type=\"password\"` only — whether the field currently reveals its raw text. Toggled by the\nbuilt-in `password-toggle` button; also settable by a consumer up front, with or without\nthat button being rendered.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"pattern","description":"A regular expression the value must match in full, forwarded to the internal native\n`<input>`'s own `pattern` and validated by it (`patternMismatch`). Defaults to `undefined`\n(no pattern). Compiled by the browser with the `v` flag and anchored to the whole value, so\nno `^`/`$` is needed; an empty value never violates it.\n\nType: `string | undefined`"},{"name":"pill","description":"Rounds the control row to a full pill by swapping `--lr-input-radius` to\n`--lr-radius-pill`.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"placeholder","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"readonly","description":"Forwards native read-only behavior to the internal input and disables the clear action.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"required","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"size","description":"Visual size on the library's one control ladder — shared with `lr-button`/`lr-select`/\n`lr-combobox`, so same-tier controls line up in a toolbar row. Accepts both the canonical\n`'2xs'`–`'xl'` steps and Web Awesome's/Shoelace's `'small'`/`'medium'`/`'large'` spellings of\n`s`/`m`/`l`; the two render identically. `'2xs'` is the tightest tier, for dense\ntoolbar-embedded controls.\n\nType: `LyraSize`  \nDefault: `'m'`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}},{"name":"spellcheck","description":"Type: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"step","description":"Accepts `'any'` (the native way to disable step validation) in addition to a numeric step.\n\nType: `number | 'any' | undefined`"},{"name":"title","description":"Forwarded to the internal native control.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"type","description":"Native input type. Unsupported runtime strings normalize to `text` at the public boundary so\nnative validity, type-dependent chrome, and the reflected host state cannot diverge.\n\nType: `LyraInputType`  \nDefault: `'time'`","value":{"type":["'text'","'password'","'email'","'number'","'time'","'search'","'date'","'datetime-local'","'tel'","'url'"]}},{"name":"value","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"with-clear","description":"Web Awesome's spelling of clearable, accepted so a mechanical `wa-` → `lr-` rename\ndoes not silently drop the clear action. Prefer `clearable` in new code.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"with-hint","description":"SSR slot-presence hint for hint/help-text content that cannot be inspected before hydration.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"with-label","description":"SSR slot-presence hint for label content that cannot be inspected before hydration.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"without-spin-buttons","description":"`type=\"number\"` only — suppresses the browser's own increment/decrement spin buttons. Left\nunset, the platform's spinners render exactly as they do on a bare `<input type=\"number\">`.\n`<lr-number-input>` defaults it the other way, since it draws its own stepper pair.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"clear-icon","description":"Replaces the built-in clear glyph."},{"name":"end","description":"Adornment after the native input and built-in actions."},{"name":"error","description":"Custom error content."},{"name":"help-text","description":"Shoelace alias for `hint`."},{"name":"hide-password-icon","description":"Replaces the glyph shown while the password is visible."},{"name":"hint","description":"Custom hint content."},{"name":"label","description":"Custom label content."},{"name":"prefix","description":"Shoelace alias for `start`."},{"name":"show-password-icon","description":"Replaces the glyph shown while the password is hidden."},{"name":"start","description":"Adornment before the native input."},{"name":"suffix","description":"Shoelace alias for `end`."}],"js":{"properties":[{"name":"accessibleLabel","description":"Accessible name overriding the label/placeholder-derived default. Takes precedence over both\n`label` and `placeholder` when set, matching `<lr-textarea>`'s `accessibleLabel`.\n\nAttribute: `aria-label`","type":"string | null","default":"null"},{"name":"appearance","description":"Lyra 7 visual default retained intentionally while the mapped `lr-input` default moves to\noutlined in v8.\n\nAttribute: `appearance`  \nReflected to its attribute.","type":"LyraAppearance","default":"'filled-outlined'"},{"name":"autocapitalize","description":"Attribute: `autocapitalize`","type":"string","default":"''"},{"name":"autocomplete","description":"Attribute: `autocomplete`","type":"string","default":"''"},{"name":"autocorrect","description":"Native editing-assistance state forwarded as canonical `autocorrect=\"on\"|\"off\"`. Reads are\nboolean. Writes accept Web Awesome's boolean IDL and Shoelace's `'on'`/`'off'` vocabulary.\n\nAttribute: `autocorrect`","type":"boolean"},{"name":"autofocus","description":"Forwarded to the internal native `<input>`, so the browser's own autofocus algorithm targets\nthe real text control rather than the (non-focusable) custom-element host.\n\nAttribute: `autofocus`","type":"boolean","default":"false"},{"name":"clearable","description":"Shows a built-in clear action for non-empty `text` and `search` inputs.\n\nAttribute: `clearable`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"customError","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nAttribute: `custom-error`  \nReflected to its attribute.","type":"string | null","default":"null"},{"name":"debounce","description":"How long (ms) to wait after the last keystroke before emitting one `lr-input-settled`,\ncoalescing a burst of rapid edits into a single downstream commit -- the same predicate and\n`DebounceController` primitive `<lr-filter-bar>`'s own per-filter `debounce` uses. Omitted,\n`0`, or a non-finite value means no debounce at all: `input`/`lr-input` keep firing per\nkeystroke exactly as before, and `lr-input-settled` never fires. A pending debounce is\nflushed immediately by `change`/Enter/blur (so a blur never drops the last keystroke) and\ncancelled with no stray settle by disconnection, the built-in clear button, and a\nprogrammatic `value` write that changes the value -- a same-value write does not disturb it.\n\nAttribute: `debounce`","type":"number | undefined"},{"name":"defaultValue","description":"Attribute: `value`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"disabled","description":"Attribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"enterKeyHint","description":"Attribute: `enterkeyhint`","type":"string","default":"''"},{"name":"enterkeyhint","type":"string"},{"name":"errorText","description":"Attribute: `error-text`","type":"string","default":"''"},{"name":"filled","description":"Shoelace's boolean spelling for the filled treatment. It does not overwrite an explicit\n`appearance`; the style alias simply paints the same fill while present.\n\nAttribute: `filled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"form","description":"Attribute: `form`  \nReflected to its attribute.","type":"HTMLFormElement | string | null","default":"null"},{"name":"helpText","description":"Shoelace alias for hint. `hint` wins when both are supplied.\n\nAttribute: `help-text`","type":"string","default":"''"},{"name":"hint","description":"Attribute: `hint`","type":"string","default":"''"},{"name":"input","description":"The internal native `<input>` element, for direct DOM access — mirrors `<lr-textarea>`'s own `input` getter.","type":"HTMLInputElement | null","read-only":true},{"name":"inputMode","description":"Attribute: `inputmode`","type":"string","default":"''"},{"name":"inputmode","type":"string"},{"name":"label","description":"Attribute: `label`","type":"string","default":"''"},{"name":"labels","type":"NodeList","read-only":true},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"match","description":"Declarative cross-field confirmation constraint: a sibling field to compare this one's\n`value` against, referenced either by id (resolved in this element's own root — an idref\nnever crosses a shadow boundary, matching every other idref this library resolves) or by a\ndirect element reference (works across shadow trees, since no lookup is needed). While set\nand resolvable, this field additionally fails validity — `customError`, with a localized\nmismatch message — whenever its value differs from the referenced element's own `.value`.\nRe-validates automatically whenever either field changes: this field's own edits through the\nusual `value` write, and the referenced field's edits through a listener on its `input`/\n`change` events. A `match` that does not resolve to a live element (a dangling id, most\ncommonly) is inert rather than a permanent block on submission — exactly like the platform's\nown tolerance of an unresolvable `aria-describedby` idref. Pairs with a plain confirmation\nfield (`type=\"password\"` or otherwise); the referenced element only needs a string `.value`,\nso a native `<input>`/`<textarea>` works the same as another `lr-input`.\n\nAttribute: `match`","type":"LyraMatchTarget","default":"null"},{"name":"max","description":"Latest selectable native time.\n\nAttribute: `max`","type":"number | string | undefined"},{"name":"maxlength","description":"Upper counterpart of `minlength` (native `maxlength`/`tooLong`), with the same parsing and the\nsame default of `undefined`. Note that native `maxlength` also *prevents* typing beyond the\nlimit; it reports `tooLong` for values that arrive some other way (paste of a longer value,\na programmatic assignment).\n\nAttribute: `maxlength`","type":"number | undefined"},{"name":"min","description":"Earliest selectable native time.\n\nAttribute: `min`","type":"number | string | undefined"},{"name":"minlength","description":"Minimum text length, forwarded to the internal native `<input>`'s own `minlength` and\nconsulted by that same native input's constraint validation (`tooShort`, see\n`updateValidity()`). Defaults to `undefined` (no lower bound). Like native `minlength`, an\nempty value never violates it — pair it with `required` to also reject empty. Ignored by the\nnative input for `type=\"number\"`/`type=\"time\"`, exactly as the platform specifies.\n\nAttribute: `minlength`","type":"number | undefined"},{"name":"name","description":"Attribute: `name`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"noSpinButtons","description":"Shoelace alias for withoutSpinButtons.\n\nAttribute: `no-spin-buttons`","type":"boolean","default":"false"},{"name":"passwordToggle","description":"`type=\"password\"` only — renders the built-in show/hide-password button. Opt-in: a bare\n`type=\"password\"` field ships no toggle at all, so a consumer whose threat model or visual\ndesign excludes one is not forced to hide it with CSS.\n\nAttribute: `password-toggle`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"passwordVisible","description":"`type=\"password\"` only — whether the field currently reveals its raw text. Toggled by the\nbuilt-in `password-toggle` button; also settable by a consumer up front, with or without\nthat button being rendered.\n\nAttribute: `password-visible`","type":"boolean","default":"false"},{"name":"pattern","description":"A regular expression the value must match in full, forwarded to the internal native\n`<input>`'s own `pattern` and validated by it (`patternMismatch`). Defaults to `undefined`\n(no pattern). Compiled by the browser with the `v` flag and anchored to the whole value, so\nno `^`/`$` is needed; an empty value never violates it.\n\nAttribute: `pattern`","type":"string | undefined"},{"name":"pill","description":"Rounds the control row to a full pill by swapping `--lr-input-radius` to\n`--lr-radius-pill`.\n\nAttribute: `pill`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"placeholder","description":"Attribute: `placeholder`","type":"string","default":"''"},{"name":"readonly","description":"Forwards native read-only behavior to the internal input and disables the clear action.\n\nAttribute: `readonly`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"required","description":"Attribute: `required`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"selectionEnd","type":"number | null"},{"name":"selectionStart","description":"Cursor/selection extent, mirroring `<lr-textarea>`'s identical passthrough. `null` both when\nthe internal input hasn't rendered yet and whenever the current `type` doesn't support\nselection at all (matching the native `<input>`'s own contract — only `text`/`search` among\nthis component's types do; `password` also supports it natively but isn't exercised here).","type":"number | null"},{"name":"size","description":"Visual size on the library's one control ladder — shared with `lr-button`/`lr-select`/\n`lr-combobox`, so same-tier controls line up in a toolbar row. Accepts both the canonical\n`'2xs'`–`'xl'` steps and Web Awesome's/Shoelace's `'small'`/`'medium'`/`'large'` spellings of\n`s`/`m`/`l`; the two render identically. `'2xs'` is the tightest tier, for dense\ntoolbar-embedded controls.\n\nAttribute: `size`  \nReflected to its attribute.","type":"LyraSize","default":"'m'"},{"name":"spellcheck","description":"Attribute: `spellcheck`","type":"boolean","default":"true"},{"name":"step","description":"Accepts `'any'` (the native way to disable step validation) in addition to a numeric step.\n\nAttribute: `step`","type":"number | 'any' | undefined"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"title","description":"Forwarded to the internal native control.\n\nAttribute: `title`","type":"string","default":"''"},{"name":"type","description":"Native input type. Unsupported runtime strings normalize to `text` at the public boundary so\nnative validity, type-dependent chrome, and the reflected host state cannot diverge.\n\nAttribute: `type`  \nReflected to its attribute.","type":"LyraInputType","default":"'time'"},{"name":"validationMessage","type":"string","read-only":true},{"name":"validity","type":"ValidityState","read-only":true},{"name":"value","description":"Live string value. A Web Awesome-compatible null write clears it without widening reads.","type":"string"},{"name":"valueAsDate","description":"Native date/time value view. Unsupported input types mirror the native getter and return\n`null`; assignment follows the native input's own conversion and remains event-silent.","type":"Date | null"},{"name":"valueAsNumber","description":"Native numeric view (milliseconds for date/time inputs, numeric value for number inputs).\nAssignment is silent, matching `HTMLInputElement.valueAsNumber`.","type":"number"},{"name":"willValidate","type":"boolean","read-only":true},{"name":"withClear","description":"Web Awesome's spelling of clearable, accepted so a mechanical `wa-` → `lr-` rename\ndoes not silently drop the clear action. Prefer `clearable` in new code.\n\nAttribute: `with-clear`","type":"boolean","default":"false"},{"name":"withHint","description":"SSR slot-presence hint for hint/help-text content that cannot be inspected before hydration.\n\nAttribute: `with-hint`","type":"boolean","default":"false"},{"name":"withLabel","description":"SSR slot-presence hint for label content that cannot be inspected before hydration.\n\nAttribute: `with-label`","type":"boolean","default":"false"},{"name":"withoutSpinButtons","description":"`type=\"number\"` only — suppresses the browser's own increment/decrement spin buttons. Left\nunset, the platform's spinners render exactly as they do on a bare `<input type=\"number\">`.\n`<lr-number-input>` defaults it the other way, since it draws its own stepper pair.\n\nAttribute: `without-spin-buttons`  \nReflected to its attribute.","type":"boolean","default":"false"}],"events":[{"name":"blur","description":"Re-dispatched from the internal native `<input>`'s own `blur` — bubbling and composed (unlike the native event, which is neither).","type":"FocusEvent"},{"name":"change","description":"Native-style composed event fired at the native `change` timing.","type":"Event"},{"name":"focus","description":"Re-dispatched from the internal native `<input>`'s own `focus`, for the same reason as `blur`.","type":"FocusEvent"},{"name":"input","description":"Native-style composed event fired on every user-driven edit.","type":"InputEvent"},{"name":"lr-change","description":"Compatibility alias for `change`; `detail: { value }`.","type":"CustomEvent<{ value: string }>"},{"name":"lr-clear","description":"The built-in clear button cleared a text/search value, after the input/change events.","type":"CustomEvent<null>"},{"name":"lr-input","description":"Compatibility alias for `input`; `detail: { value }`.","type":"CustomEvent<{ value: string }>"},{"name":"lr-input-settled","description":"Fires once, `debounce` ms after the last keystroke, alongside the per-keystroke `input`/`lr-input` pair (which keep firing on every edit). `detail: { value }`, non-cancelable. A pending debounce is flushed immediately on `change`/Enter/blur, and cancelled with no stray settle on disconnect, the built-in clear button, and a programmatic `value` write that actually changes the value -- a same-value write (e.g. the controlled-input pattern of a framework re-binding `value` from the state its own handler just set) leaves the pending debounce armed instead of silently defeating it. Never fires while `debounce` is unset, `0`, or non-finite.","type":"CustomEvent<{ value: string }>"},{"name":"lr-invalid","description":"The input failed a validity check. Cancelable: `preventDefault()` forwards to the native `invalid` event, suppressing the browser's own validation bubble and the focus/scroll `reportValidity()` would otherwise perform.","type":"CustomEvent<null>"}]}},{"name":"lr-neighbor-list","description":"`<lr-neighbor-list>` — one entity's relationship rows: relation, direction, neighbor, with\nper-row navigate and expand-in-graph affordances. Never computes neighbors itself (the host\nderives rows from its own graph data) and never mutates a graph.\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**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The stable root wrapper across empty, populated and virtualized states. It owns `role=\"group\"` and the fallback name unless a non-empty host `aria-label` owns the component; a nested list owns the row semantics in non-virtualized mode. |\n| `direction` | The `aria-hidden` direction glyph. |\n| `empty` | The empty-state message, shown when `rows` is empty. |\n| `expand-button` | The per-row expand-in-graph icon button, only rendered when `expandable`. |\n| `group-header` | A relation group header, only rendered when `groupByRelation`. Above `virtualizeAt` this is the internal virtual-list's own group label, re-exported under the same name so both paths present identically. |\n| `node-label` | The row's node `<button>`. |\n| `node-meta` | Secondary node text (type/degree), when present. |\n| `relation` | The relation text. |\n| `row` | One relationship row (`role=\"listitem\"`). Above `virtualizeAt` this is the internal virtual-list's own row wrapper, re-exported under the same name. |","attributes":[{"name":"expandable","description":"Shows a per-row expand icon-button emitting `lr-node-expand`.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"group-by-relation","description":"Stable-sorts rows by relation and renders one group header per relation with a count.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"label","description":"Accessible name for the stable group when the host has no `aria-label`; falls back to the\nlocalized `neighborListLabel` default when omitted. An explicitly empty host label stays\nempty, and so does an explicitly empty `label`.\n\nType: `string | undefined`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"virtualize-at","description":"Above this row count the list renders through an internal `lr-virtual-list`.\n\nType: `number`  \nDefault: `100`","value":{"type":["number"]}}],"js":{"properties":[{"name":"expandable","description":"Shows a per-row expand icon-button emitting `lr-node-expand`.\n\nAttribute: `expandable`","type":"boolean","default":"false"},{"name":"groupByRelation","description":"Stable-sorts rows by relation and renders one group header per relation with a count.\n\nAttribute: `group-by-relation`","type":"boolean","default":"false"},{"name":"label","description":"Accessible name for the stable group when the host has no `aria-label`; falls back to the\nlocalized `neighborListLabel` default when omitted. An explicitly empty host label stays\nempty, and so does an explicitly empty `label`.\n\nAttribute: `label`","type":"string | undefined"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"rows","description":"Neighbor relationships to render, including direction, relation, and target node data.","type":"readonly LyraNeighborRow[]","default":"[]"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"virtualizeAt","description":"Above this row count the list renders through an internal `lr-virtual-list`.\n\nAttribute: `virtualize-at`","type":"number","default":"100"}],"events":[{"name":"lr-entity-select","description":"A row's node button was activated. `detail: { entityId }`.","type":"CustomEvent<{ entityId: string }>"},{"name":"lr-node-expand","description":"A row's expand button was activated (only rendered when `expandable`). `detail: { nodeId }`.","type":"CustomEvent<{ nodeId: string }>"}]}},{"name":"lr-node-palette","description":"`<lr-node-palette>` — the searchable, categorized node library for workflow editors: drag an\nitem onto a canvas, or place it by keyboard. Never creates nodes or touches a canvas's data\nitself — the drop/place handshake ends at `lr-node-add`/`lr-palette-place`; the host mutates\n`nodes`. Fully decoupled from `lr-flow-canvas` (no `for` resolution, unlike\n`lr-flow-minimap`/`lr-flow-controls`/`lr-flow-run-status`) — it only needs to agree with a\n`droppable` canvas on the `FLOW_PALETTE_MIME_TYPE` drag payload shape.\n\nSet `reorderable` to opt into keyboard reordering of the catalog itself: Ctrl/Cmd+ArrowUp/\nArrowDown on the focused item emits `lr-reorder` — a *request*, exactly like every other event\nhere. `items` stays host-owned; nothing moves until the host applies the reported indices and\nreassigns it. The move is scoped to the item's own category group, matching the group-first\nrendering order, and mirrors `<lr-tree>`'s already-shipped `reorderable`/`lr-reorder` contract.\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.\nEach rendered item is projected once from its own data descriptors. Accessor-backed or malformed\nrows are omitted, while an admitted source object's identity remains available only for focus,\nreorder, and `lr-select` contracts.\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| `footer` | Content below the list. |\n| `header` | Content above the search field (e.g. a heading or tabs). |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The root wrapper. |\n| `empty` | The no-results message. |\n| `group-header` | A category heading (`role=\"presentation\"`). |\n| `item` | A single option row. |\n| `item-description` | An item's description text. |\n| `item-icon` | An item's icon wrapper. |\n| `item-label` | An item's label text. |\n| `list` | The listbox. |\n| `live-region` | The result-count announcement. |\n| `search` | The search input. |\n| `search-clear` | The button that clears the search field, rendered only while it has a value -- the native `type=\"search\"` cancel button is suppressed (its unthemed glyph does not match the field's own border/background), so this replaces it rather than merely hiding it. |\n| `search-field` | The wrapper around the search input and its clear button. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-node-palette-search-font-size` (default: `inherit`) — Text size of the search field.\n- `--lr-node-palette-search-min-height` (default: `var(--lr-icon-button-size)`) — Minimum row height of the search field, for matching it to a themed search field of a chosen density tier. Point it at `--lr-form-control-height-l` (or any tier of that ladder) to line this field up with the rest of an application's controls. It can only raise the height: the shared tappable-target minimum stays underneath it, so no tier can shrink the field past the WCAG floor.\n- `--lr-node-palette-search-padding-block` (default: `var(--lr-space-xs)`) — Block gutter of the search field.\n- `--lr-node-palette-search-padding-inline` (default: `var(--lr-space-s)`) — Leading gutter of the search field. The trailing gutter is reserved for the overlaid clear button.\n- `--lr-node-palette-search-radius` (default: `var(--lr-radius)`) — Corner radius of the search field.","attributes":[{"name":"aria-label","description":"JS-only accessible-name override for the listbox. Setting this property does not reflect a\nhost `aria-label`; an authored host attribute, including `aria-label=\"\"`, names only the\ncomponent and leaves the listbox to `label` or its localized fallback.\n\nType: `string | null`  \nDefault: `null`"},{"name":"label","description":"Accessible name for the actual listbox; omitted, empty, or whitespace-only values use the\nlocalized default while the public property's raw readback remains unchanged.\n\nType: `string | undefined`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"reorderable","description":"Opts into Ctrl/Cmd+ArrowUp/ArrowDown keyboard reordering (see the class doc). Defaults to\n`false`: unset, no `lr-reorder` is ever emitted and Ctrl/Cmd+Arrow keeps behaving exactly like\na plain Arrow press.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"footer","description":"Content below the list."},{"name":"header","description":"Content above the search field (e.g. a heading or tabs)."}],"js":{"properties":[{"name":"accessibleLabel","description":"JS-only accessible-name override for the listbox. Setting this property does not reflect a\nhost `aria-label`; an authored host attribute, including `aria-label=\"\"`, names only the\ncomponent and leaves the listbox to `label` or its localized fallback.\n\nAttribute: `aria-label`","type":"string | null","default":"null"},{"name":"items","description":"Node templates available for filtering, activation, dragging, and optional reordering.\nAccessor-backed or malformed rows are omitted; accepted fields are read once from own data\ndescriptors while the original item object stays available for documented identity contracts.","type":"readonly LyraPaletteItem[]","default":"[]"},{"name":"label","description":"Accessible name for the actual listbox; omitted, empty, or whitespace-only values use the\nlocalized default while the public property's raw readback remains unchanged.\n\nAttribute: `label`","type":"string | undefined"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"reorderable","description":"Opts into Ctrl/Cmd+ArrowUp/ArrowDown keyboard reordering (see the class doc). Defaults to\n`false`: unset, no `lr-reorder` is ever emitted and Ctrl/Cmd+Arrow keeps behaving exactly like\na plain Arrow press.\n\nAttribute: `reorderable`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"blur","description":"A realm-correct native `FocusEvent`, relayed exactly once when the internal search field loses focus; preserves `relatedTarget` and crosses the shadow boundary.","type":"FocusEvent"},{"name":"focus","description":"A realm-correct native `FocusEvent`, relayed exactly once when the internal search field gains focus; preserves `relatedTarget` and crosses the shadow boundary.","type":"FocusEvent"},{"name":"lr-palette-place","description":"An item was placed (pointer click or Enter/Space — the click/keyboard alternative to dragging). `detail: { type }`.","type":"CustomEvent<{ type: string }>"},{"name":"lr-reorder","description":"`detail: { type, category, fromIndex, toIndex }` — Ctrl/Cmd+ArrowUp/ArrowDown on the focused item requests moving it past its neighbour **inside its own category group**, so a reorder can never turn into a recategorization. `fromIndex`/`toIndex` index into `items` itself, so the host applies the move with a plain splice. Only fired while `reorderable`, never at a group boundary, and never cancelable — this component does not mutate `items`. Success is announced only once the re-rendered group order confirms the host applied it.","type":"CustomEvent<{\n    type: string;\n    category: string | null;\n    fromIndex: number;\n    toIndex: number;\n  }>"},{"name":"lr-select","description":"Emitted alongside `lr-palette-place` on both gestures, carrying the original admitted item object. `detail: { item }`.","type":"CustomEvent<Readonly<{ item: LyraPaletteItem }>>"}]}},{"name":"lr-notebook-viewer","description":"`<lr-notebook-viewer>` — read-only Jupyter notebook (nbformat 4.x) renderer, composing existing\ncomponents per cell. Execution is a hard non-goal.\n\nMarkdown cells render through `<lr-markdown>`, code cells through `<lr-code-block>` (using the\nnotebook's kernel language for syntax highlighting), and raw cells as plain preformatted text. A\ncode cell's `execute_result`/`display_data` outputs prefer, in order, `image/png`, `image/jpeg`,\n`image/svg+xml` (sanitized), `text/html` (sanitized), `application/json` (via `<lr-json-viewer>`),\nthen `text/plain`. Stream/error outputs (tinted `danger` for stderr/tracebacks) interpret embedded\nANSI SGR color/style escapes via the shared `internal/ansi.ts` parser, same as `<lr-terminal>`.\nSanitizing raw HTML/SVG\noutput markup lazy-loads the optional peer dependency `dompurify` via `dompurify-loader.ts`; when\nthat peer isn't installed, the output renders a localized notice instead of raw markup.\nSanitized `text/html` output uses the passive-document profile: anchors, form controls, and\ncustom elements are unwrapped to ordinary text/children where safe, remote navigation/resource\nattributes are removed, and only inline base64 raster image sources render. Sanitized\n`image/svg+xml` output is likewise network-silent and non-interactive: animation is removed and\nonly same-document fragment references or inline base64 raster image references survive.\n\nCells are virtualized through `<lr-virtual-list>` so a notebook with many cells stays cheap to\nscroll. `node-path` anchors resolve `path[0]` as a cell index; `fragment` anchors resolve a cell's\nown `id`.\n\nIdentified virtual cells use the same key for active paint and navigation. Repeating an anchor\nreturns to that cell after manual scrolling; max-height also bounds the virtual scroll viewport.\nAdopts `DocumentAnchorTarget`: `scrollToAnchor()`/the declarative `anchor` property resolve\nthrough the cell-granularity model above, and `highlights`/`activeHighlightId` resolve through\nthat exact same model (`resolveAnchorCellIndex()`), not a pixel-precise text range within a\ncell's own rendered markdown/code/output -- this viewer's addressable unit is the cell, matching\nits `anchorKinds`. A `highlights` entry whose anchor resolves paints its matched cell with a\n`cell-highlighted` part plus a tone-specific `cell-highlighted-<tone>` part (`accent` default,\n`success`, `warning`, `danger`, `neutral`); the entry whose `id` equals `activeHighlightId`\nadditionally carries `cell-highlight-active`. Unlike docx-viewer/ebook-viewer there is no raw\nmarkup to imperatively wrap or annotate -- cells are already declaratively re-rendered by Lit on\nevery `highlights`/`activeHighlightId`/load-state change, so `repaintHighlights()` just recomputes\nthat per-cell mapping ahead of the next render pass. `lr-highlight-activate` and `lr-text-select`\nare present on this component's event map only because it's inherited, structurally, from the\nshared `LyraAnchorTargetEventMap` every `DocumentAnchorTarget` adopter carries -- neither is\nactually emitted by this viewer: there is no keyboard-accessible highlight-activation surface\n(docx-viewer's/ebook-viewer's own click-to-activate needs a raw content DOM to hit-test or an\nannotation-click callback, neither of which this cell-level model has), and the mixin's default\n`bindTextSelection()` would anchor a selection as a `text-quote`, a kind outside this viewer's own\n`anchorKinds`/highlight-resolution model, so wiring it would offer a selection event whose own\nanchor could never be fed back in as a highlight.\n\n`search()`/`searchNext()`/`searchPrevious()`/`clearSearch()` follow the shared viewer search\ncontract (`internal/text-viewer-target.ts`'s `LyraTextViewerTarget`): `search()` resolves the\nmatch count and the two navigation methods resolve `true` once the active match moved, `false`\nwhen there is nothing to move to. A find-in-page host can therefore drive this viewer through the\nsame typed surface as every other one.\n\nParsed `notebook` assignments are synchronously clone-owned and recursively frozen. Mutate a\ncopy and reassign it to update the viewer; later changes to the source object 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**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `anchor-live-region` | The aria-hidden, non-live shadow mirror of the latest anchor-jump message. |\n| `base` | The root scroll container. |\n| `cell` | One cell row (`data-cell-type`, `data-active`, `data-highlighted`). |\n| `cell-active` | Added alongside `cell` on the cell currently targeted by an anchor or the active search match. A second part name rather than an attribute selector, because Shadow Parts forbids an attribute selector after `::part()`. |\n| `cell-gutter` | The `In [n]`/`Out [n]` label column. |\n| `cell-highlight-active` | Added alongside `cell-highlighted`/`cell-highlighted-<tone>` when the matched highlight's `id` equals `activeHighlightId`. |\n| `cell-highlighted` | Added alongside `cell` on a cell matched by a `highlights` entry. Always paired with a tone-specific `cell-highlighted-<tone>` part below (a second part name rather than an attribute selector, for the same Shadow Parts reason as `cell-active`). |\n| `cell-highlighted-accent` | Tone-specific highlight styling hook (the default tone). |\n| `cell-highlighted-danger` | Tone-specific highlight styling hook. |\n| `cell-highlighted-neutral` | Tone-specific highlight styling hook. |\n| `cell-highlighted-success` | Tone-specific highlight styling hook. |\n| `cell-highlighted-warning` | Tone-specific highlight styling hook. |\n| `cell-source` | A cell's source content. |\n| `error` | The error region. |\n| `error-output-label` | The label introducing an error output's traceback. |\n| `output` | One output (`data-output-type`, `data-stream`). |\n| `output-error` | Added alongside `output` on a stderr stream or an error output. |\n| `output-toggle` | Expands/collapses a long text output. |\n| `outputs` | The wrapper around a code cell's outputs. |\n| `raw-source` | A horizontally scrollable raw-cell source surface. |\n| `spinner` | Visible ordinary loading content with a motion-safe progress indicator. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-notebook-viewer-max-height` (default: `none`) — Maximum block size of the scrollable body before it scrolls internally. Also settable via the `max-height` property.\n- `--lr-notebook-viewer-active-bg` (default: `var(--lr-color-brand-quiet)`) — Background of the `[part=\"cell\"]` currently targeted by an anchor or the active search match.\n- `--lr-notebook-viewer-highlight-accent-background` (default: `var(--lr-color-brand-quiet)`) — Background of an `accent`-tone (the default) highlighted cell.\n- `--lr-notebook-viewer-highlight-success-background` (default: `var(--lr-color-success-quiet)`) — Background of a `success`-tone highlighted cell.\n- `--lr-notebook-viewer-highlight-warning-background` (default: `var(--lr-color-warning-quiet)`) — Background of a `warning`-tone highlighted cell.\n- `--lr-notebook-viewer-highlight-danger-background` (default: `var(--lr-color-danger-quiet)`) — Background of a `danger`-tone highlighted cell.\n- `--lr-notebook-viewer-highlight-neutral-background` (default: `var(--lr-color-surface-raised)`) — Background of a `neutral`-tone highlighted cell.\n- `--lr-notebook-viewer-highlight-active-outline` (default: `var(--lr-focus-ring-color)`) — Outline of the highlighted cell whose highlight `id` equals `activeHighlightId`.","attributes":[{"name":"active-highlight-id","description":"Id of the currently active highlight, or null when none is active.\n\nType: `string | null`  \nDefault: `null`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max-height","description":"A CSS `max-height`; invalid values are ignored.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"name","description":"Display name used as the viewer's accessible label, and matched against a `fragment` anchor's\ncell id.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"output-collapse-lines","description":"A plain-text output longer than this many lines renders collapsed behind a toggle. `0`\ndisables collapsing.\n\nType: `number`  \nDefault: `40`","value":{"type":["number"]}},{"name":"src","description":"URL to fetch and parse as a notebook. Ignored while `notebook` is present.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"js":{"properties":[{"name":"activeHighlightId","description":"Id of the currently active highlight, or null when none is active.\n\nAttribute: `active-highlight-id`","type":"string | null","default":"null"},{"name":"anchor","description":"Anchor or highlight id to resolve and scroll into view.","type":"LyraAnchor | string | null","default":"null"},{"name":"anchorKinds","description":"Anchor kinds this component resolves via `scrollToAnchor()`.","type":"readonly LyraAnchorKind[]","default":"['node-path', 'fragment']","read-only":true},{"name":"highlights","description":"Highlights rendered by the document target. Reassign after mutation.","type":"LyraHighlight[]","default":"[]"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"maxHeight","description":"A CSS `max-height`; invalid values are ignored.\n\nAttribute: `max-height`","type":"string","default":"''"},{"name":"name","description":"Display name used as the viewer's accessible label, and matched against a `fragment` anchor's\ncell id.\n\nAttribute: `name`","type":"string","default":"''"},{"name":"notebook","description":"A parsed notebook document, or its raw JSON text. Presence wins over `src` (including `''`)\nand is parsed synchronously. Assigning `undefined` clears inline authority, invalidates its\nrendering/sanitization work, and immediately resumes the already configured `src`.","type":"NotebookDoc | string | undefined"},{"name":"outputCollapseLines","description":"A plain-text output longer than this many lines renders collapsed behind a toggle. `0`\ndisables collapsing.\n\nAttribute: `output-collapse-lines`","type":"number","default":"40"},{"name":"source","description":"Intentionally inert -- `source` is always derived live from `src`/`notebook`. A getter with\nno setter throws (in strict-mode module code, which every consumer runs) the moment\nanything assigns to it, including a stray `.source=${x}` template binding; this no-op keeps\nthat assignment harmless instead of throwing from inside framework internals.","type":"LyraNotebookViewerSource"},{"name":"src","description":"URL to fetch and parse as a notebook. Ignored while `notebook` is present.\n\nAttribute: `src`","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-anchor-result","description":"Fired after an `anchor` property assignment or a `scrollToAnchor()` call is applied. Non-cancelable. `detail: { found }`.","type":"CustomEvent<AnchorResultDetail>"},{"name":"lr-load","description":"Fired once a notebook has been parsed and validated. `detail: { cellCount, language }`.","type":"CustomEvent<{ cellCount: number; language: string }>"},{"name":"lr-render-error","description":"Fired when fetching, parsing, or validating the notebook fails. `detail: { error }`.","type":"CustomEvent<{ error: unknown }>"},{"name":"lr-search-change","description":"Fired whenever the search query, match count, or active match index changes, including source-reset and effective-locale re-evaluation. `detail: { query, matchCount, matchCountExact, activeIndex }`. Notebook validation caps the corpus at 2,000 cells and search retains at most one match per cell. Search accepts at most 4,096 query code units and scans at most 4,000,000 source/output code units; a false `matchCountExact` makes the returned count a lower bound after either ceiling is reached.","type":"CustomEvent<LyraSearchChangeDetail>"}]}},{"name":"lr-number-input","description":"`<lr-number-input>` — a numeric field with the complete `lr-input` form, validation, and native\nediting contract, plus its own increment/decrement stepper pair.\n\nThe steppers replace the browser's built-in spin buttons rather than sitting beside them:\n`withoutSpinButtons` therefore defaults to `true` here (it defaults to `false` on `<lr-input>`),\nand both properties are independently settable, so `steppers=\"false\"\nwithout-spin-buttons=\"false\"` returns the field to a plain native `<input type=\"number\">`.\n\nEach stepper drives the inherited `stepUp()`/`stepDown()`, so `min`/`max` clamping and decimal\nhandling are the platform's. Unlike those silent methods, a stepper *click* is a user edit and\nemits the same `input`/`lr-input`/`change`/`lr-change` sequence typing would — but only when the\nvalue actually moved, so clicking at a bound is inert rather than emitting a no-op edit.\n\nThe steppers are deliberately outside the tab order (`tabindex=\"-1\"`), like the native spin\nbuttons they stand in for: a keyboard user steps the value with ArrowUp/ArrowDown on the field\nitself, which the native `<input type=\"number\">` already handles, so making them tab stops would\nadd two stops per field for no new capability. A click returns focus to the field.\n\nThe component retains the complete shared size sheet inherited conceptually from `lr-input`:\ncompact tiers grow only enough for the stepper hit targets, while `l` and `xl` retain their\nlarger control heights. The mirrored `small`, `medium`, and `large` spellings render exactly as\ncanonical `s`, `m`, and `l`, including row height, padding, and native-input font size.\n\nInherited stepUp/stepDown use pending value, step, min, and max properties synchronously\nand remain event-silent. Removed label/hint/help-text/error-text content is safely omitted.\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| `clear-icon` | Replaces the built-in clear glyph. |\n| `decrement-icon` | Replaces the decrement stepper's built-in chevron. |\n| `end` | Adornment after the native input and built-in actions. |\n| `error` | Custom error content. |\n| `help-text` | Shoelace alias for `hint`. |\n| `hide-password-icon` | Replaces the glyph shown while the password is visible. |\n| `hint` | Custom hint content. |\n| `increment-icon` | Replaces the increment stepper's built-in chevron. |\n| `label` | Custom label content. |\n| `prefix` | Shoelace alias for `start`. |\n| `show-password-icon` | Replaces the glyph shown while the password is hidden. |\n| `start` | Adornment before the native input. |\n| `suffix` | Shoelace alias for `end`. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | Compatibility name for the control row; use `number-input`. |\n| `clear-button` | The clear action, rendered for non-empty clearable text/search inputs. |\n| `end` | Wrapper around the `end` adornment slot, with the same containment behavior. |\n| `error` | The error message. |\n| `form-control` | The outer wrapper around label, input, error and hint. |\n| `form-control-help-text` | Shoelace compatibility name for the hint message. |\n| `form-control-input` | Compatibility name for the control row. |\n| `form-control-label` | The `<label>` element. |\n| `hint` | The hint message. |\n| `input` | The native `<input>` element. |\n| `input-wrapper` | The row wrapping the native input and built-in actions. It is the same node as `base`. |\n| `label` | Wrapper around the visible label content. |\n| `number-input` | The numeric control row. It is the same node as `base` and the inherited `input-wrapper` part. |\n| `password-toggle` | The show/hide-password button, rendered only for `type=\"password\"` with `password-toggle` set. |\n| `password-toggle-button` | Wrapper around the password-toggle icon. |\n| `prefix` | Shoelace compatibility part on the `prefix` slot. |\n| `start` | Wrapper around the `start` adornment slot. Long content shrinks and ellipsizes rather than widening the control allocation. |\n| `stepper` | Shared part on both stepper buttons. |\n| `stepper-decrement` | The decrement button. |\n| `stepper-down` | Lyra compatibility name on `stepper-decrement`. |\n| `stepper-increment` | The increment button. |\n| `stepper-up` | Lyra compatibility name on `stepper-increment`. |\n| `suffix` | Shoelace compatibility part on the `suffix` slot. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-form-control-focus-shadow` (default: `none`) — The shared field focus halo, painted as a `box-shadow` while this control is focused. One name for every field-shaped control in the library, so a halo is configured once rather than per component. Additive: the focus outline and border cue are the accessibility answer to focus and are never replaced by it.\n- `--lr-form-control-required-color` (default: `var(--lr-color-danger)`) — Color of that marker, retunable without touching any other danger-coloured surface.\n- `--lr-form-control-required-content` (default: `' *'`) — The required-field marker rendered after the label. Set it to `''` to suppress the marker, or to any other quoted string (`' (required)'`, a localized word) to replace it. Caller-supplied content, so it is never localized here.\n- `--lr-form-control-required-offset` (default: `0`) — Inline space between the label text and the marker.\n- `--lr-input-action-active-bg` (default: `color-mix(in oklab,var(--lr-color-surface),var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Pressed action background. The same hooks apply to `lr-number-input`'s stepper pair.\n- `--lr-input-action-active-color` (default: `var(--lr-input-action-hover-color,var(--lr-color-text))`) — Pressed action color.\n- `--lr-input-action-color` (default: `var(--lr-color-text-quiet)`) — Resting clear/password/number- stepper action color.\n- `--lr-input-action-hover-color` (default: `var(--lr-color-text)`) — Hovered action color.\n- `--lr-input-border-color` (default: `var(--lr-color-border)`) — Border color of the control row, with a private default that changes per `appearance` in the same way as `--lr-input-fill`.\n- `--lr-input-control-height` — Exact outer control height. Unset by default, which leaves `--lr-input-control-min-height` as a floor only; set it to a length to both floor and cap the control row (e.g. to pixel-match `<lr-select>`/`<lr-combobox>` in the same toolbar). Because it is never declared by the component itself, it can be set from an ancestor or an outer-tree rule as well as inline on the element.\n- `--lr-input-control-min-height` (default: `var(--lr-form-control-height)`) — Outer control height floor, taken from the active `size` tier of the shared form-control ladder (`internal/sizes.styles.ts`), so an input is exactly as tall as an `<lr-button>`/`<lr-select>` of the same tier.\n- `--lr-input-fill` (default: `transparent`) — Background of the control row. Its private default changes per `appearance`; the public value remains authoritative in every appearance.\n- `--lr-input-focus-border-color` (default: `var(--lr-color-brand)`) — Control-row border color while focus is within the field.\n- `--lr-input-font-size` (default: `var(--lr-form-control-font-size)`) — Font size of the native input, from the active `size` tier.\n- `--lr-input-gap` (default: `var(--lr-space-xs)`) — Gap between the start/end adornments and the native input in the control row. Unlike the size knobs above it does not vary by `size` tier. Override it to retune without a `::part(input-wrapper)` rule.\n- `--lr-input-padding-block` (default: `var(--lr-form-control-padding-block)`) — Block padding of the native input, from the active `size` tier of the shared ladder.\n- `--lr-input-padding-inline` (default: `var(--lr-form-control-padding-inline)`) — Inline padding of the control row, from the active `size` tier.\n- `--lr-input-radius` (default: `var(--lr-form-control-radius)`) — Corner radius of the control row, from the active `size` tier of the shared ladder (the two tightest tiers take a smaller radius). `pill` swaps it to `--lr-radius-pill`.\n- `--lr-input-time-picker-active-bg` (default: `var(--lr-color-brand)`) — Pressed background for the browser-native time-picker indicator when `type=\"time\"`.\n- `--lr-input-time-picker-focus-bg` (default: `var(--lr-color-brand-quiet)`) — Focus-visible background for the native time-picker indicator.\n- `--lr-input-time-picker-focus-ring` (default: `var(--lr-focus-ring-color)`) — Focus-visible outline color for the native time-picker indicator.\n- `--lr-input-time-picker-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background for the browser-native time-picker indicator when `type=\"time\"`.","attributes":[{"name":"appearance","description":"Numeric inputs use the outlined field treatment by default.\n\nType: `LyraAppearance`  \nDefault: `'outlined'`","value":{"type":["'accent'","'filled'","'outlined'","'filled-outlined'","'plain'"]}},{"name":"aria-label","description":"Accessible name overriding the label/placeholder-derived default. Takes precedence over both\n`label` and `placeholder` when set, matching `<lr-textarea>`'s `accessibleLabel`.\n\nType: `string | null`  \nDefault: `null`"},{"name":"autocapitalize","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"autocomplete","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"autocorrect","description":"Native editing-assistance state forwarded as canonical `autocorrect=\"on\"|\"off\"`. Reads are\nboolean. Writes accept Web Awesome's boolean IDL and Shoelace's `'on'`/`'off'` vocabulary.\n\nType: `boolean`","value":{"type":["boolean"]}},{"name":"autofocus","description":"Forwarded to the internal native `<input>`, so the browser's own autofocus algorithm targets\nthe real text control rather than the (non-focusable) custom-element host.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"clearable","description":"Shows a built-in clear action for non-empty `text` and `search` inputs.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"custom-error","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nType: `string | null`  \nDefault: `null`"},{"name":"debounce","description":"How long (ms) to wait after the last keystroke before emitting one `lr-input-settled`,\ncoalescing a burst of rapid edits into a single downstream commit -- the same predicate and\n`DebounceController` primitive `<lr-filter-bar>`'s own per-filter `debounce` uses. Omitted,\n`0`, or a non-finite value means no debounce at all: `input`/`lr-input` keep firing per\nkeystroke exactly as before, and `lr-input-settled` never fires. A pending debounce is\nflushed immediately by `change`/Enter/blur (so a blur never drops the last keystroke) and\ncancelled with no stray settle by disconnection, the built-in clear button, and a\nprogrammatic `value` write that changes the value -- a same-value write does not disturb it.\n\nType: `number | undefined`"},{"name":"default-value","description":"Compatibility attribute alias for the supported `defaultValue` reset value.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"disabled","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"enterkeyhint","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"error-text","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"filled","description":"Shoelace's boolean spelling for the filled treatment. It does not overwrite an explicit\n`appearance`; the style alias simply paints the same fill while present.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"form","description":"Type: `HTMLFormElement | string | null`  \nDefault: `null`"},{"name":"help-text","description":"Shoelace alias for hint. `hint` wins when both are supplied.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"hint","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"inputmode","description":"Requests a numeric virtual keyboard unless the consumer chooses `decimal`.\n\nType: `string`  \nDefault: `'numeric'`","value":{"type":["string"]}},{"name":"label","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"match","description":"Declarative cross-field confirmation constraint: a sibling field to compare this one's\n`value` against, referenced either by id (resolved in this element's own root — an idref\nnever crosses a shadow boundary, matching every other idref this library resolves) or by a\ndirect element reference (works across shadow trees, since no lookup is needed). While set\nand resolvable, this field additionally fails validity — `customError`, with a localized\nmismatch message — whenever its value differs from the referenced element's own `.value`.\nRe-validates automatically whenever either field changes: this field's own edits through the\nusual `value` write, and the referenced field's edits through a listener on its `input`/\n`change` events. A `match` that does not resolve to a live element (a dangling id, most\ncommonly) is inert rather than a permanent block on submission — exactly like the platform's\nown tolerance of an unresolvable `aria-describedby` idref. Pairs with a plain confirmation\nfield (`type=\"password\"` or otherwise); the referenced element only needs a string `.value`,\nso a native `<input>`/`<textarea>` works the same as another `lr-input`.\n\nType: `LyraMatchTarget`  \nDefault: `null`","value":{"type":["LyraMatchTarget"]}},{"name":"max","description":"Upper counterpart of `min`, with the same parsing and the same default of `undefined`.\n\nType: `number | string | undefined`"},{"name":"maxlength","description":"Upper counterpart of `minlength` (native `maxlength`/`tooLong`), with the same parsing and the\nsame default of `undefined`. Note that native `maxlength` also *prevents* typing beyond the\nlimit; it reports `tooLong` for values that arrive some other way (paste of a longer value,\na programmatic assignment).\n\nType: `number | undefined`"},{"name":"min","description":"`type=\"number\"` only — forwarded to the internal native `<input>`'s own `min`/`max`/`step`\nand consulted by that same native input's constraint validation (see `updateValidity()`).\nDefaults to `undefined` (no lower bound). The `min` attribute is parsed as a number here; the\ndeclared type also admits a string so a subclass bound to a non-numeric native input type can\nnarrow the attribute parsing to that type's own literal form (`<lr-native-time-input>`'s `09:00`)\nwithout redeclaring the whole property surface.\n\nType: `number | string | undefined`"},{"name":"minlength","description":"Minimum text length, forwarded to the internal native `<input>`'s own `minlength` and\nconsulted by that same native input's constraint validation (`tooShort`, see\n`updateValidity()`). Defaults to `undefined` (no lower bound). Like native `minlength`, an\nempty value never violates it — pair it with `required` to also reject empty. Ignored by the\nnative input for `type=\"number\"`/`type=\"time\"`, exactly as the platform specifies.\n\nType: `number | undefined`"},{"name":"name","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"no-spin-buttons","description":"Shoelace alias for withoutSpinButtons.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"password-toggle","description":"`type=\"password\"` only — renders the built-in show/hide-password button. Opt-in: a bare\n`type=\"password\"` field ships no toggle at all, so a consumer whose threat model or visual\ndesign excludes one is not forced to hide it with CSS.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"password-visible","description":"`type=\"password\"` only — whether the field currently reveals its raw text. Toggled by the\nbuilt-in `password-toggle` button; also settable by a consumer up front, with or without\nthat button being rendered.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"pattern","description":"A regular expression the value must match in full, forwarded to the internal native\n`<input>`'s own `pattern` and validated by it (`patternMismatch`). Defaults to `undefined`\n(no pattern). Compiled by the browser with the `v` flag and anchored to the whole value, so\nno `^`/`$` is needed; an empty value never violates it.\n\nType: `string | undefined`"},{"name":"pill","description":"Rounds the control row to a full pill by swapping `--lr-input-radius` to\n`--lr-radius-pill`.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"placeholder","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"readonly","description":"Forwards native read-only behavior to the internal input and disables the clear action.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"required","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"size","description":"Visual size on the library's one control ladder — shared with `lr-button`/`lr-select`/\n`lr-combobox`, so same-tier controls line up in a toolbar row. Accepts both the canonical\n`'2xs'`–`'xl'` steps and Web Awesome's/Shoelace's `'small'`/`'medium'`/`'large'` spellings of\n`s`/`m`/`l`; the two render identically. `'2xs'` is the tightest tier, for dense\ntoolbar-embedded controls.\n\nType: `LyraSize`  \nDefault: `'m'`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}},{"name":"spellcheck","description":"Type: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"step","description":"Native step-grid default.\n\nType: `number | 'any' | undefined`  \nDefault: `1`"},{"name":"steppers","description":"Renders the increment/decrement pair inside the control row. Set `steppers=\"false\"` for a\nbare numeric field.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"title","description":"Forwarded to the internal native control.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"type","description":"Native input type. Unsupported runtime strings normalize to `text` at the public boundary so\nnative validity, type-dependent chrome, and the reflected host state cannot diverge.\n\nType: `LyraInputType`  \nDefault: `'number'`","value":{"type":["'text'","'password'","'email'","'number'","'time'","'search'","'date'","'datetime-local'","'tel'","'url'"]}},{"name":"value","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"with-clear","description":"Web Awesome's spelling of clearable, accepted so a mechanical `wa-` → `lr-` rename\ndoes not silently drop the clear action. Prefer `clearable` in new code.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"with-hint","description":"SSR slot-presence hint for hint/help-text content that cannot be inspected before hydration.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"with-label","description":"SSR slot-presence hint for label content that cannot be inspected before hydration.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"without-spin-buttons","description":"Defaults to `true` here (unlike `<lr-input>`) so the component's own steppers are not shown\nalongside the browser's built-in spin buttons. `without-spin-buttons=\"false\"` brings the\nnative pair back.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"without-steppers","description":"Positive upstream spelling for hiding the stepper pair. The established `steppers` switch\nremains supported; either `without-steppers` or `steppers=\"false\"` hides the same controls.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"clear-icon","description":"Replaces the built-in clear glyph."},{"name":"decrement-icon","description":"Replaces the decrement stepper's built-in chevron."},{"name":"end","description":"Adornment after the native input and built-in actions."},{"name":"error","description":"Custom error content."},{"name":"help-text","description":"Shoelace alias for `hint`."},{"name":"hide-password-icon","description":"Replaces the glyph shown while the password is visible."},{"name":"hint","description":"Custom hint content."},{"name":"increment-icon","description":"Replaces the increment stepper's built-in chevron."},{"name":"label","description":"Custom label content."},{"name":"prefix","description":"Shoelace alias for `start`."},{"name":"show-password-icon","description":"Replaces the glyph shown while the password is hidden."},{"name":"start","description":"Adornment before the native input."},{"name":"suffix","description":"Shoelace alias for `end`."}],"js":{"properties":[{"name":"accessibleLabel","description":"Accessible name overriding the label/placeholder-derived default. Takes precedence over both\n`label` and `placeholder` when set, matching `<lr-textarea>`'s `accessibleLabel`.\n\nAttribute: `aria-label`","type":"string | null","default":"null"},{"name":"appearance","description":"Numeric inputs use the outlined field treatment by default.\n\nAttribute: `appearance`  \nReflected to its attribute.","type":"LyraAppearance","default":"'outlined'"},{"name":"autocapitalize","description":"Attribute: `autocapitalize`","type":"string","default":"''"},{"name":"autocomplete","description":"Attribute: `autocomplete`","type":"string","default":"''"},{"name":"autocorrect","description":"Native editing-assistance state forwarded as canonical `autocorrect=\"on\"|\"off\"`. Reads are\nboolean. Writes accept Web Awesome's boolean IDL and Shoelace's `'on'`/`'off'` vocabulary.\n\nAttribute: `autocorrect`","type":"boolean"},{"name":"autofocus","description":"Forwarded to the internal native `<input>`, so the browser's own autofocus algorithm targets\nthe real text control rather than the (non-focusable) custom-element host.\n\nAttribute: `autofocus`","type":"boolean","default":"false"},{"name":"clearable","description":"Shows a built-in clear action for non-empty `text` and `search` inputs.\n\nAttribute: `clearable`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"customError","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nAttribute: `custom-error`  \nReflected to its attribute.","type":"string | null","default":"null"},{"name":"debounce","description":"How long (ms) to wait after the last keystroke before emitting one `lr-input-settled`,\ncoalescing a burst of rapid edits into a single downstream commit -- the same predicate and\n`DebounceController` primitive `<lr-filter-bar>`'s own per-filter `debounce` uses. Omitted,\n`0`, or a non-finite value means no debounce at all: `input`/`lr-input` keep firing per\nkeystroke exactly as before, and `lr-input-settled` never fires. A pending debounce is\nflushed immediately by `change`/Enter/blur (so a blur never drops the last keystroke) and\ncancelled with no stray settle by disconnection, the built-in clear button, and a\nprogrammatic `value` write that changes the value -- a same-value write does not disturb it.\n\nAttribute: `debounce`","type":"number | undefined"},{"name":"defaultValue","description":"Attribute: `value`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"disabled","description":"Attribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"enterKeyHint","description":"Attribute: `enterkeyhint`","type":"string","default":"''"},{"name":"enterkeyhint","type":"string"},{"name":"errorText","description":"Attribute: `error-text`","type":"string","default":"''"},{"name":"filled","description":"Shoelace's boolean spelling for the filled treatment. It does not overwrite an explicit\n`appearance`; the style alias simply paints the same fill while present.\n\nAttribute: `filled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"form","description":"Attribute: `form`  \nReflected to its attribute.","type":"HTMLFormElement | string | null","default":"null"},{"name":"helpText","description":"Shoelace alias for hint. `hint` wins when both are supplied.\n\nAttribute: `help-text`","type":"string","default":"''"},{"name":"hint","description":"Attribute: `hint`","type":"string","default":"''"},{"name":"input","description":"The internal native `<input>` element, for direct DOM access — mirrors `<lr-textarea>`'s own `input` getter.","type":"HTMLInputElement | null","read-only":true},{"name":"inputMode","description":"Requests a numeric virtual keyboard unless the consumer chooses `decimal`.\n\nAttribute: `inputmode`","type":"string","default":"'numeric'"},{"name":"inputmode","type":"string"},{"name":"label","description":"Attribute: `label`","type":"string","default":"''"},{"name":"labels","type":"NodeList","read-only":true},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"match","description":"Declarative cross-field confirmation constraint: a sibling field to compare this one's\n`value` against, referenced either by id (resolved in this element's own root — an idref\nnever crosses a shadow boundary, matching every other idref this library resolves) or by a\ndirect element reference (works across shadow trees, since no lookup is needed). While set\nand resolvable, this field additionally fails validity — `customError`, with a localized\nmismatch message — whenever its value differs from the referenced element's own `.value`.\nRe-validates automatically whenever either field changes: this field's own edits through the\nusual `value` write, and the referenced field's edits through a listener on its `input`/\n`change` events. A `match` that does not resolve to a live element (a dangling id, most\ncommonly) is inert rather than a permanent block on submission — exactly like the platform's\nown tolerance of an unresolvable `aria-describedby` idref. Pairs with a plain confirmation\nfield (`type=\"password\"` or otherwise); the referenced element only needs a string `.value`,\nso a native `<input>`/`<textarea>` works the same as another `lr-input`.\n\nAttribute: `match`","type":"LyraMatchTarget","default":"null"},{"name":"max","description":"Upper counterpart of `min`, with the same parsing and the same default of `undefined`.\n\nAttribute: `max`","type":"number | string | undefined"},{"name":"maxlength","description":"Upper counterpart of `minlength` (native `maxlength`/`tooLong`), with the same parsing and the\nsame default of `undefined`. Note that native `maxlength` also *prevents* typing beyond the\nlimit; it reports `tooLong` for values that arrive some other way (paste of a longer value,\na programmatic assignment).\n\nAttribute: `maxlength`","type":"number | undefined"},{"name":"min","description":"`type=\"number\"` only — forwarded to the internal native `<input>`'s own `min`/`max`/`step`\nand consulted by that same native input's constraint validation (see `updateValidity()`).\nDefaults to `undefined` (no lower bound). The `min` attribute is parsed as a number here; the\ndeclared type also admits a string so a subclass bound to a non-numeric native input type can\nnarrow the attribute parsing to that type's own literal form (`<lr-native-time-input>`'s `09:00`)\nwithout redeclaring the whole property surface.\n\nAttribute: `min`","type":"number | string | undefined"},{"name":"minlength","description":"Minimum text length, forwarded to the internal native `<input>`'s own `minlength` and\nconsulted by that same native input's constraint validation (`tooShort`, see\n`updateValidity()`). Defaults to `undefined` (no lower bound). Like native `minlength`, an\nempty value never violates it — pair it with `required` to also reject empty. Ignored by the\nnative input for `type=\"number\"`/`type=\"time\"`, exactly as the platform specifies.\n\nAttribute: `minlength`","type":"number | undefined"},{"name":"name","description":"Attribute: `name`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"noSpinButtons","description":"Shoelace alias for withoutSpinButtons.\n\nAttribute: `no-spin-buttons`","type":"boolean","default":"false"},{"name":"passwordToggle","description":"`type=\"password\"` only — renders the built-in show/hide-password button. Opt-in: a bare\n`type=\"password\"` field ships no toggle at all, so a consumer whose threat model or visual\ndesign excludes one is not forced to hide it with CSS.\n\nAttribute: `password-toggle`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"passwordVisible","description":"`type=\"password\"` only — whether the field currently reveals its raw text. Toggled by the\nbuilt-in `password-toggle` button; also settable by a consumer up front, with or without\nthat button being rendered.\n\nAttribute: `password-visible`","type":"boolean","default":"false"},{"name":"pattern","description":"A regular expression the value must match in full, forwarded to the internal native\n`<input>`'s own `pattern` and validated by it (`patternMismatch`). Defaults to `undefined`\n(no pattern). Compiled by the browser with the `v` flag and anchored to the whole value, so\nno `^`/`$` is needed; an empty value never violates it.\n\nAttribute: `pattern`","type":"string | undefined"},{"name":"pill","description":"Rounds the control row to a full pill by swapping `--lr-input-radius` to\n`--lr-radius-pill`.\n\nAttribute: `pill`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"placeholder","description":"Attribute: `placeholder`","type":"string","default":"''"},{"name":"readonly","description":"Forwards native read-only behavior to the internal input and disables the clear action.\n\nAttribute: `readonly`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"required","description":"Attribute: `required`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"selectionEnd","type":"number | null"},{"name":"selectionStart","description":"Cursor/selection extent, mirroring `<lr-textarea>`'s identical passthrough. `null` both when\nthe internal input hasn't rendered yet and whenever the current `type` doesn't support\nselection at all (matching the native `<input>`'s own contract — only `text`/`search` among\nthis component's types do; `password` also supports it natively but isn't exercised here).","type":"number | null"},{"name":"size","description":"Visual size on the library's one control ladder — shared with `lr-button`/`lr-select`/\n`lr-combobox`, so same-tier controls line up in a toolbar row. Accepts both the canonical\n`'2xs'`–`'xl'` steps and Web Awesome's/Shoelace's `'small'`/`'medium'`/`'large'` spellings of\n`s`/`m`/`l`; the two render identically. `'2xs'` is the tightest tier, for dense\ntoolbar-embedded controls.\n\nAttribute: `size`  \nReflected to its attribute.","type":"LyraSize","default":"'m'"},{"name":"spellcheck","description":"Attribute: `spellcheck`","type":"boolean","default":"true"},{"name":"step","description":"Native step-grid default.\n\nAttribute: `step`","type":"number | 'any' | undefined","default":"1"},{"name":"steppers","description":"Renders the increment/decrement pair inside the control row. Set `steppers=\"false\"` for a\nbare numeric field.\n\nAttribute: `steppers`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"title","description":"Forwarded to the internal native control.\n\nAttribute: `title`","type":"string","default":"''"},{"name":"type","description":"Native input type. Unsupported runtime strings normalize to `text` at the public boundary so\nnative validity, type-dependent chrome, and the reflected host state cannot diverge.\n\nAttribute: `type`  \nReflected to its attribute.","type":"LyraInputType","default":"'number'"},{"name":"validationMessage","type":"string","read-only":true},{"name":"validity","type":"ValidityState","read-only":true},{"name":"value","description":"Live string value. A Web Awesome-compatible null write clears it without widening reads.","type":"string"},{"name":"valueAsDate","description":"Native date/time value view. Unsupported input types mirror the native getter and return\n`null`; assignment follows the native input's own conversion and remains event-silent.","type":"Date | null"},{"name":"valueAsNumber","description":"Native numeric view (milliseconds for date/time inputs, numeric value for number inputs).\nAssignment is silent, matching `HTMLInputElement.valueAsNumber`.","type":"number"},{"name":"willValidate","type":"boolean","read-only":true},{"name":"withClear","description":"Web Awesome's spelling of clearable, accepted so a mechanical `wa-` → `lr-` rename\ndoes not silently drop the clear action. Prefer `clearable` in new code.\n\nAttribute: `with-clear`","type":"boolean","default":"false"},{"name":"withHint","description":"SSR slot-presence hint for hint/help-text content that cannot be inspected before hydration.\n\nAttribute: `with-hint`","type":"boolean","default":"false"},{"name":"withLabel","description":"SSR slot-presence hint for label content that cannot be inspected before hydration.\n\nAttribute: `with-label`","type":"boolean","default":"false"},{"name":"withoutSpinButtons","description":"Defaults to `true` here (unlike `<lr-input>`) so the component's own steppers are not shown\nalongside the browser's built-in spin buttons. `without-spin-buttons=\"false\"` brings the\nnative pair back.\n\nAttribute: `without-spin-buttons`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"withoutSteppers","description":"Positive upstream spelling for hiding the stepper pair. The established `steppers` switch\nremains supported; either `without-steppers` or `steppers=\"false\"` hides the same controls.\n\nAttribute: `without-steppers`","type":"boolean","default":"false"}],"events":[{"name":"beforeinput","description":"The internal native input's cancelable `InputEvent`, which bubbles and composes through the host. Calling `preventDefault()` on the host vetoes the edit.","type":"InputEvent"},{"name":"blur","description":"Re-dispatched from the internal native `<input>`'s own `blur` — bubbling and composed (unlike the native event, which is neither).","type":"FocusEvent"},{"name":"change","description":"Native-style composed event fired at the native `change` timing.","type":"Event"},{"name":"focus","description":"Re-dispatched from the internal native `<input>`'s own `focus`, for the same reason as `blur`.","type":"FocusEvent"},{"name":"input","description":"Native-style composed event fired on every user-driven edit.","type":"InputEvent"},{"name":"lr-change","description":"Compatibility alias for `change`; `detail: { value }`.","type":"CustomEvent<{ value: string }>"},{"name":"lr-clear","description":"The built-in clear button cleared a text/search value, after the input/change events.","type":"CustomEvent<null>"},{"name":"lr-input","description":"Compatibility alias for `input`; `detail: { value }`.","type":"CustomEvent<{ value: string }>"},{"name":"lr-input-settled","description":"Fires once, `debounce` ms after the last keystroke, alongside the per-keystroke `input`/`lr-input` pair (which keep firing on every edit). `detail: { value }`, non-cancelable. A pending debounce is flushed immediately on `change`/Enter/blur, and cancelled with no stray settle on disconnect, the built-in clear button, and a programmatic `value` write that actually changes the value -- a same-value write (e.g. the controlled-input pattern of a framework re-binding `value` from the state its own handler just set) leaves the pending debounce armed instead of silently defeating it. Never fires while `debounce` is unset, `0`, or non-finite.","type":"CustomEvent<{ value: string }>"},{"name":"lr-invalid","description":"The input failed a validity check. Cancelable: `preventDefault()` forwards to the native `invalid` event, suppressing the browser's own validation bubble and the focus/scroll `reportValidity()` would otherwise perform.","type":"CustomEvent<null>"}]}},{"name":"lr-option","description":"`<lr-option>` — a selectable option for `<lr-combobox>` and `<lr-select>`.\nMirrors `<wa-option>` and `<sl-option>`. It acts as the data source for Lyra's\nbuilt-in pickers, which render their interactive rows in their own shadow roots.\n\nThe effective `label` is an explicit non-empty `label` property/attribute when supplied,\notherwise `defaultLabel`, the normalized accessible text of the flattened default slot. Hidden\nsubtrees are excluded, visible nested `aria-label` values replace their descendants, and named\nadornment slots never leak into either `defaultLabel` or Shoelace's `getTextLabel()` method.\nNamed adornment text, attributes, insertion/removal, and slot reassignment refresh the owning\ncombobox presentation, including decorative content that does not change the accessible label.\n\nSelection follows the native live/default split. The `selected` attribute initializes\n`defaultSelected`, which parent controls use as their `form.reset()` baseline; property writes\nto `defaultSelected` intentionally do not reflect. `selected` is independent property-only live\nstate, so a user pick never rewrites the declarative default. A later default change updates a\npristine live option, but never clobbers a live selection that has already become dirty.\nAssigning a mounted option's `selected` property immediately updates its owning picker and\nsubmitted value silently, including deselection and equal-value writes.\nIn a constrained option row the default label ellipsizes, while each `start`/`end` adornment is\ncapped at 40% of the row so unbroken consumer content cannot widen the owning listbox.\n\n`data` carries an opaque application payload (e.g. the backend record this option represents),\nmirroring an async combobox source row's own `data` field. It is never read or rendered by this\ncomponent; it is retained by reference (never deep-cloned) through the owning `lr-combobox`'s\n`selectedRows` and the owning `lr-select`'s `selectedData`, and in both controls' `lr-input`/\n`lr-change`/`input`/`change` event details.\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 option's visible label. |\n| `end` | WA-compatible trailing adornment. |\n| `prefix` | Shoelace-compatible alias for `start`. |\n| `start` | WA-compatible leading adornment. |\n| `suffix` | Shoelace-compatible alias for `end`. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The option's outer visual wrapper. |\n| `checked-icon` | The decorative checkmark shown while selected. |\n| `end` | The WA-compatible trailing-adornment wrapper; the same node as `suffix`. |\n| `label` | The default-slot label wrapper. |\n| `prefix` | The Shoelace-compatible leading-adornment wrapper; the same node as `start`. |\n| `start` | The WA-compatible leading-adornment wrapper; the same node as `prefix`. |\n| `suffix` | The Shoelace-compatible trailing-adornment wrapper; the same node as `end`. |\n\n---\n\n**CSS Custom Properties**\n\n- `--current-text-color` (default: `var(--lr-color-text)`) — Text color while the option is `current`.\n- `--lr-option-active-bg` (default: `color-mix(in oklab, var(--lr-option-hover-bg, var(--lr-color-brand-quiet)), var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Pressed background.\n- `--lr-option-checked-icon-color` (default: `var(--lr-color-brand)`) — Selected checkmark color.\n- `--lr-option-current-bg` (default: `var(--lr-color-brand-quiet)`) — Keyboard-current background.\n- `--lr-option-current-color` (default: `var(--current-text-color, var(--lr-color-text))`) — Keyboard-current text color; the upstream `--current-text-color` remains its fallback.\n- `--lr-option-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background.\n- `--lr-option-selected-font-weight` (default: `var(--lr-font-weight-semibold)`) — Selected label weight.","attributes":[{"name":"disabled","description":"Disable selecting this option.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"dot-color","description":"Optional color for a small leading status dot (any valid CSS color).\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"group","description":"Optional section header this option belongs under.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"label","description":"The option's effective plain-text label. An explicit non-empty property/attribute wins;\notherwise this resolves to defaultLabel. Property writes intentionally do not reflect.\n\nType: `string`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"search-text","description":"Extra text the filter should match beyond the label.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"selected","description":"Declarative/reset selection default supplied by the `selected` attribute. Property writes\nintentionally do not reflect. A write updates the live state only until `selected` has been\nwritten independently, and notifies the parent to update its `form.reset()` baseline.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"sub","description":"Optional secondary line rendered under the label (e.g. a status/date summary).\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"value","description":"The selection key submitted with the form.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"slots":[{"name":"","description":"The option's visible label."},{"name":"end","description":"WA-compatible trailing adornment."},{"name":"prefix","description":"Shoelace-compatible alias for `start`."},{"name":"start","description":"WA-compatible leading adornment."},{"name":"suffix","description":"Shoelace-compatible alias for `end`."}],"js":{"properties":[{"name":"data","description":"Opaque application payload, e.g. the backend record this option represents. Never read or\nrendered by `<lr-option>` itself. The light-DOM counterpart to an async `source` row's own\n`data` field: retained by reference (never deep-cloned) through the owning `lr-combobox`'s\n`selectedRows` and the owning `lr-select`'s `selectedData`.","type":"unknown | undefined"},{"name":"defaultLabel","description":"Accessible text generated from flattened default-slot content, excluding named adornments.","type":"string","read-only":true},{"name":"defaultSelected","description":"Declarative/reset selection default supplied by the `selected` attribute. Property writes\nintentionally do not reflect. A write updates the live state only until `selected` has been\nwritten independently, and notifies the parent to update its `form.reset()` baseline.\n\nAttribute: `selected`","type":"boolean","default":"false"},{"name":"disabled","description":"Disable selecting this option.\n\nAttribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"dotColor","description":"Optional color for a small leading status dot (any valid CSS color).\n\nAttribute: `dot-color`","type":"string","default":"''"},{"name":"group","description":"Optional section header this option belongs under.\n\nAttribute: `group`","type":"string","default":"''"},{"name":"label","description":"The option's effective plain-text label. An explicit non-empty property/attribute wins;\notherwise this resolves to defaultLabel. Property writes intentionally do not reflect.\n\nAttribute: `label`","type":"string"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"searchText","description":"Extra text the filter should match beyond the label.\n\nAttribute: `search-text`","type":"string","default":"''"},{"name":"selected","description":"Whether this option is currently selected. Parent controls write this live, property-only\nstate without changing `defaultSelected` or the declarative reset attribute.","type":"boolean","default":"false"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"sub","description":"Optional secondary line rendered under the label (e.g. a status/date summary).\n\nAttribute: `sub`","type":"string","default":"''"},{"name":"value","description":"The selection key submitted with the form.\n\nAttribute: `value`  \nReflected to its attribute.","type":"string","default":"''"}],"events":[{"name":"lr-option-change","description":"The option's label or selectable data changed. The parent combobox or select consumes this bubbling event to refresh its normalized option rows.","type":"CustomEvent<null>"}]}},{"name":"lr-otp-input","description":"`<lr-otp-input>` — a form-associated one-time-code field: several character segments that\ntogether hold one value.\n\nThe segments are presentational. A single real `<input>` sits transparently across them and owns\nfocus, selection and the value. It remains the native integration point for SMS autofill\n(`autocomplete` defaults to `one-time-code`), IME composition and mobile keyboards, and keeps the\ncontrol to one tab stop rather than one per character. Fixed-cell keyboard and paste handlers map\nnative editing intents into the visual cells without exposing one input per character.\n\nProgrammatic `value` writes, default propagation, form resets, and browser state restoration all\npass through the same sanitizer as typing and remain event-silent. `resetValidity()` clears a\nconsumer-supplied custom error while restoring the current intrinsic constraints.\n\nKeyboard editing uses fixed cells: physical Left/Right move to the visually adjacent segment\n(with the index delta mirrored under RTL), Backspace clears the current cell and moves back,\nDelete clears it in place, and neither deletion shifts trailing characters. A bare Enter flushes\na pending `change` and requests one submission from the owning form through the shared\nEnter-to-submit gate, so a modifier-held Enter, an Enter that commits an IME candidate, and an\nEnter a listener above has already vetoed all leave the form alone, and the form's default button\nreaches the submission as `SubmitEvent.submitter`. A full paste into an empty field fills accepted characters from\nthe first cell in one input operation. The public/submitted string concatenates occupied cells;\nmiddle empty cells are a visual editing state and are not encoded in that string. A nonempty\nnative selection maps its compact offsets back to occupied cells for replacement or deletion.\nThe host forwards the native selection getters, setters, and range-editing methods against that\nsame compact string. Range edits pass through the sanitizer, synchronize form value and\nvalidity, and remain event-silent like a programmatic `value` write.\n\nComponent-scoped theme inputs remain undeclared on the host, so values inherited from an\nancestor theme wrapper override appearance fallbacks. A value set directly on the OTP input\nstill wins through normal custom-property inheritance.\n\nHost aria-describedby targets supplement local error/hint guidance on the native control\ninput. Relationships track missing IDs, target replacement, removal/reinsertion, reconnect,\nand document adoption.\n\n---\n\n**Component metadata**\n\n- Status: `stable`\n- Since: `8.0.0`\n- Rationale: This tag entered Lyra as a stable public API with documented behavior, accessibility, and cross-browser support.\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| `error` | Rich validation text, replacing the `errorText` attribute. |\n| `hint` | Rich supporting text used while the `hint` attribute is empty. |\n| `label` | Rich label content used while the `label` attribute is empty. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The outer wrapper; retained alias for `form-control`. |\n| `control` | The real, visually transparent input. |\n| `error` | Validation text. |\n| `field` | Retained Lyra alias for the row of segments. |\n| `form-control` | The outer wrapper; shared form-control alias for `base`. |\n| `form-control-label` | The field label; shared form-control alias for `label`. |\n| `hint` | Supporting text. |\n| `label` | The field label; retained alias for `form-control-label`. |\n| `segment` | One character segment. Carries `active`, `masked`, `placeholder-mask` and `invalid` in the part name so a consumer can target any of those states through `::part()`. |\n| `segment-literal` | A literal separator emitted by `format`. |\n| `segments` | The allocation-bounded, horizontally scrollable row of fixed-size segments; it carries the shared minimum target floor. |\n| `separator` | Retained Lyra alias for a literal separator emitted by `format`. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-otp-input-mask-char` (default: `'•'`) — The glyph shown for a masked character, and for every empty segment while `with-mask` is set. Must be a quoted string, because it is used as CSS `content`.\n- `--mask-char` (default: `'•'`) — Mapped alias for `--lr-otp-input-mask-char`.\n- `--segment-border-radius` (default: `var(--lr-form-control-radius,var(--lr-radius))`) — Corner radius of a segment.\n- `--segment-gap` (default: `var(--lr-space-xs)`) — Gap between segments; ignored by `contained`.\n- `--segment-size` (default: `2.5em`) — Exact inline and block size of each non-shrinking segment at the default size tier.\n- `--lr-otp-input-segment-size` (default: `var(--lr-theme-otp-input-segment-size,2.5em)`) — Internal role token supplying the standalone segment size when `--segment-size` is unset. Element-scoped: every `lr-*` host re-declares this token from `--lr-theme-otp-input-segment-size` in the shared token layer, so an ancestor rule that sets `--lr-otp-input-segment-size` directly is reset at the first intervening `lr-*` component and never reaches this element. Set it directly on this element, or set `--lr-theme-otp-input-segment-size` on an ancestor to resize every OTP input in the subtree at once.\n- `--lr-otp-input-segment-border-color` (default: `var(--lr-color-border)`) — Border color of each segment.\n- `--lr-otp-input-segment-fill` (default: `transparent`) — Background fill of each segment.\n- `--lr-otp-input-segment-radius` (default: `var(--lr-form-control-radius,var(--lr-radius))`) — Corner radius of each segment.\n- `--lr-otp-input-active-border-color` (default: `var(--lr-focus-ring-color)`) — Active segment border.\n- `--lr-otp-input-active-ring-color` (default: `var(--lr-focus-ring-color)`) — Active segment outer ring.\n- `--lr-otp-input-invalid-border-color` (default: `var(--lr-color-danger)`) — Invalid segment border.\n- `--lr-form-control-required-content` (default: `' *'`) — The required-field marker rendered after the label. Set it to `''` to suppress the marker, or to any other quoted string (`' (required)'`, a localized word) to replace it. Caller-supplied content, so it is never localized here.\n- `--lr-form-control-required-color` (default: `var(--lr-color-danger)`) — Color of that marker, retunable without touching any other danger-coloured surface.\n- `--lr-form-control-required-offset` (default: `0`) — Inline space between the label text and the marker.","attributes":[{"name":"appearance","description":"Visual fill treatment for each segment, or a single joined `contained` field.\n\nType: `OtpInputAppearance`  \nDefault: `'outlined'`","value":{"type":["'filled'","'outlined'","'filled-outlined'","'contained'"]}},{"name":"autocomplete","description":"Native autofill hint. Defaults to the SMS one-time-code value.\n\nType: `string`  \nDefault: `'one-time-code'`","value":{"type":["string"]}},{"name":"autofocus","description":"Automatically focus the real input after the first client render.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"autosubmit","description":"Submit the owning form after an un-canceled `lr-complete`, one task later so an asynchronous\nlistener can still veto it. Replacing or restoring the code before that task runs cancels\nthe stale submission. The form's default button is resolved as the submitter.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"case","description":"Case transform applied as characters are entered.\n\nType: `OtpInputCase`  \nDefault: `'preserve'`","value":{"type":["'preserve'","'upper'","'lower'"]}},{"name":"custom-error","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nType: `string | null`  \nDefault: `null`"},{"name":"disabled","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"error-text","description":"Validation text shown immediately below the field. It sets the internal input's ARIA invalid\nstate; rich `error`-slot content takes precedence when supplied.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"form","description":"Type: `HTMLFormElement | string | null`  \nDefault: `null`"},{"name":"format","description":"Segment layout with literal separators — `#` marks a segment, any other character becomes a\nseparator. `format=\"###-###\"` renders two groups of three joined by a dash. Overrides `length`\nwhen its bounded parsed prefix contains at least one `#`; a literal-only parsed prefix falls\nback to `length`. Only the first 4,096 UTF-16 code units are parsed, and no more than 32\nsegments are retained.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"hint","description":"Supporting text below the field. When nonempty, it takes precedence over the `hint` slot.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"label","description":"Visible label. When nonempty, it takes precedence over rich `label`-slot content.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"length","description":"Number of character segments. Ignored when `format` is set.\n\nType: `number`  \nDefault: `6`","value":{"type":["number"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"mask","description":"Show entered characters as the mask glyph instead of their real value. Display-only.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"name","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"readonly","description":"Display the value without allowing edits. Unlike `disabled`, it still submits and focuses;\nintrinsic required/completeness validity is suspended until editing is enabled again.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"required","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"size","description":"Segment size on the shared form-control ladder. An unset size inherits its containing context;\nstandalone rendering falls back to `m`.\n\nType: `LyraSize`  \nDefault: `'m'`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}},{"name":"type","description":"Which characters are accepted; also drives the mobile keyboard through `inputmode`.\n\nType: `OtpInputType`  \nDefault: `'numeric'`","value":{"type":["'numeric'","'alpha'","'alphanumeric'"]}},{"name":"value","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"with-mask","description":"Show the mask glyph in empty segments, so the field reads as a fixed-length code before any\nentry. Independent of `mask`: entered characters stay visible unless `mask` is also set.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"error","description":"Rich validation text, replacing the `errorText` attribute."},{"name":"hint","description":"Rich supporting text used while the `hint` attribute is empty."},{"name":"label","description":"Rich label content used while the `label` attribute is empty."}],"js":{"properties":[{"name":"appearance","description":"Visual fill treatment for each segment, or a single joined `contained` field.\n\nAttribute: `appearance`  \nReflected to its attribute.","type":"OtpInputAppearance","default":"'outlined'"},{"name":"autocomplete","description":"Native autofill hint. Defaults to the SMS one-time-code value.\n\nAttribute: `autocomplete`  \nReflected to its attribute.","type":"string","default":"'one-time-code'"},{"name":"autofocus","description":"Automatically focus the real input after the first client render.\n\nAttribute: `autofocus`","type":"boolean","default":"false"},{"name":"autosubmit","description":"Submit the owning form after an un-canceled `lr-complete`, one task later so an asynchronous\nlistener can still veto it. Replacing or restoring the code before that task runs cancels\nthe stale submission. The form's default button is resolved as the submitter.\n\nAttribute: `autosubmit`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"case","description":"Case transform applied as characters are entered.\n\nAttribute: `case`  \nReflected to its attribute.","type":"OtpInputCase","default":"'preserve'"},{"name":"customError","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nAttribute: `custom-error`  \nReflected to its attribute.","type":"string | null","default":"null"},{"name":"defaultValue","description":"The reset default uses the same sanitizer when it becomes live; changing it also retires a\nqueued autosubmission, even while a dirty live value prevents immediate propagation.\n\nAttribute: `value`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"disabled","description":"Attribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"effectiveLength","description":"Mapped read-only name for the number of segments derived from `format` or `length`.","type":"number","read-only":true},{"name":"errorText","description":"Validation text shown immediately below the field. It sets the internal input's ARIA invalid\nstate; rich `error`-slot content takes precedence when supplied.\n\nAttribute: `error-text`","type":"string","default":"''"},{"name":"form","description":"Attribute: `form`  \nReflected to its attribute.","type":"HTMLFormElement | string | null","default":"null"},{"name":"format","description":"Segment layout with literal separators — `#` marks a segment, any other character becomes a\nseparator. `format=\"###-###\"` renders two groups of three joined by a dash. Overrides `length`\nwhen its bounded parsed prefix contains at least one `#`; a literal-only parsed prefix falls\nback to `length`. Only the first 4,096 UTF-16 code units are parsed, and no more than 32\nsegments are retained.\n\nAttribute: `format`","type":"string","default":"''"},{"name":"hint","description":"Supporting text below the field. When nonempty, it takes precedence over the `hint` slot.\n\nAttribute: `hint`","type":"string","default":"''"},{"name":"input","description":"The real native input used for focus, selection, autofill, and IME.","type":"HTMLInputElement | null","read-only":true},{"name":"label","description":"Visible label. When nonempty, it takes precedence over rich `label`-slot content.\n\nAttribute: `label`","type":"string","default":"''"},{"name":"labels","type":"NodeList","read-only":true},{"name":"length","description":"Number of character segments. Ignored when `format` is set.\n\nAttribute: `length`  \nReflected to its attribute.","type":"number","default":"6"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"mask","description":"Show entered characters as the mask glyph instead of their real value. Display-only.\n\nAttribute: `mask`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"name","description":"Attribute: `name`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"readonly","description":"Display the value without allowing edits. Unlike `disabled`, it still submits and focuses;\nintrinsic required/completeness validity is suspended until editing is enabled again.\n\nAttribute: `readonly`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"required","description":"Attribute: `required`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"selectionDirection","description":"Direction of the native compact-string selection, or `null` before first render.","type":"OtpInputSelectionDirection | null"},{"name":"selectionEnd","description":"End offset of the native compact-string selection, or `null` before first render.","type":"number | null"},{"name":"selectionStart","description":"Start offset of the native compact-string selection, or `null` before first render.","type":"number | null"},{"name":"size","description":"Segment size on the shared form-control ladder. An unset size inherits its containing context;\nstandalone rendering falls back to `m`.\n\nAttribute: `size`  \nReflected to its attribute.","type":"LyraSize","default":"'m'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"type","description":"Which characters are accepted; also drives the mobile keyboard through `inputmode`.\n\nAttribute: `type`  \nReflected to its attribute.","type":"OtpInputType","default":"'numeric'"},{"name":"validationMessage","type":"string","read-only":true},{"name":"validationTarget","description":"Native control passed to constraint-validation UI as its visual anchor.","type":"HTMLInputElement | null","read-only":true},{"name":"validity","type":"ValidityState","read-only":true},{"name":"value","description":"Live value normalized through the same character/length contract as native editing. At most\nthe first 4,096 UTF-16 code units are inspected, stopping earlier once every segment is full.","type":"string"},{"name":"willValidate","type":"boolean","read-only":true},{"name":"withMask","description":"Show the mask glyph in empty segments, so the field reads as a fixed-length code before any\nentry. Independent of `mask`: entered characters stay visible unless `mask` is also set.\n\nAttribute: `with-mask`  \nReflected to its attribute.","type":"boolean","default":"false"}],"events":[{"name":"blur","description":"Native blur relayed once from the real input.","type":"FocusEvent"},{"name":"change","description":"The value changed and the field settled on blur or Enter; relayed as one native `Event`.","type":"Event"},{"name":"focus","description":"Native focus relayed once from the real input.","type":"FocusEvent"},{"name":"input","description":"The real input changed; relayed as one native `InputEvent` with its editing payload intact. Intermediate IME composition waits for the final non-composing event.","type":"InputEvent"},{"name":"lr-clear","description":"The value was cleared. Bubbling, composed, and non-cancelable.","type":"CustomEvent<null>"},{"name":"lr-complete","description":"The field transitions from incomplete to every segment filled. `detail: { value }`. Cancelable; preventing it suppresses `autosubmit` for that completion. The autosubmission is deferred one task, so a listener may call `preventDefault()` after an `await`.","type":"CustomEvent<{ value: string }>"},{"name":"lr-invalid","description":"The one-time-code input failed a validity check. Cancelable: `preventDefault()` forwards to the native `invalid` event, suppressing the browser's own validation bubble and the focus/scroll `reportValidity()` would otherwise perform.","type":"CustomEvent<null>"}]}},{"name":"lr-page","description":"`<lr-page>` — a semantic application/page shell that derives its mobile or desktop presentation\nfrom its own allocated inline size. A single static navigation subtree participates in the\ndesktop grid and is promoted in place to a modal mobile drawer, so assigned nodes, component\ninstances, focus, form state, and scroll state are never cloned or replaced at a breakpoint.\n\nEach instance owns unique main/drawer/navigation IDs. Its skip link therefore targets its own\nmain landmark even when several Pages coexist. The default skip and navigation controls are\nlocalized, and a host `aria-label` overrides the navigation landmark's localized name.\nReplacement skip text and navigation-toggle glyph content remain visual only: their assigned\nsubtrees are inert and hidden from assistive technology, while skip text still names the outer\nlink.\n\n`disable-sticky` is a whitespace-token attribute accepting `banner`, `header`, `subheader`,\n`menu`, and `aside`. A token only disables that region; unrelated sticky regions keep working.\nSlotted controls carrying `data-toggle-nav` toggle the mobile drawer, matching the documented\nlight-DOM Page pattern without adding a stale `nav-state` property.\nEvery custom `navigation-toggle` and each composed descendant that actually receives focus\nreceive component-owned `aria-haspopup=\"dialog\"`, synchronized `aria-expanded`, a localized\nlabel when unnamed, and a relationship sourced from the real drawer. Current browsers expose\nthe Page host for that inward shadow relationship. Replacement, removal, and disconnect restore\nexact authored baselines, including writes made while ownership was active. Disabled,\n`aria-disabled`, hidden, or inert assigned controls do not toggle the drawer.\n\n---\n\n**Component metadata**\n\n- Status: `stable`\n- Since: `8.0.0`\n- Rationale: This tag entered Lyra as a stable public API with documented behavior, accessibility, and cross-browser support.\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) | Main content. |\n| `aside` | Complementary content beside the main region. |\n| `banner` | A page-wide notice above the header. |\n| `footer` | Page-wide footer content. |\n| `header` | Primary page header content. |\n| `main-footer` | Content after the main body but inside the main landmark. |\n| `main-header` | Content before the main body but inside the main landmark. |\n| `menu` | A compact menu beside the main region. |\n| `navigation` | Primary navigation content. |\n| `navigation-footer` | Content after the navigation links. |\n| `navigation-header` | Content before the navigation links. |\n| `navigation-toggle` | Custom controls that toggle mobile navigation and each receive the managed ARIA relationship described above. |\n| `navigation-toggle-icon` | Replaces the default toggle's menu glyph as inert, decorative visual content. |\n| `skip-to-content` | Replaces the localized skip-link text as inert visual content; its descriptive text names the outer skip link. |\n| `subheader` | A secondary header row. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `aside` | Wrapper for the `aside` slot and the complementary landmark. |\n| `banner` | Wrapper for the `banner` slot. |\n| `base` | Compatibility name for the root Page wrapper; use `page`. |\n| `body` | Desktop grid/mobile stack containing menu, navigation, main, and aside. |\n| `dialog-wrapper` | Mobile backdrop and drawer positioning layer; display-contents on desktop. |\n| `drawer` | Navigation's modal surface on mobile; display-contents on desktop. |\n| `footer` | Page-wide footer landmark. |\n| `header` | Primary page header landmark. |\n| `main` | The unique main landmark. |\n| `main-content` | Wrapper for the default slot. |\n| `main-footer` | Wrapper for the `main-footer` slot. |\n| `main-header` | Wrapper for the `main-header` slot. |\n| `menu` | Wrapper for the `menu` slot. |\n| `navigation` | The primary navigation landmark. |\n| `navigation-desktop` | Desktop compatibility name on the same node as `navigation`. |\n| `navigation-footer` | Wrapper for the `navigation-footer` slot. |\n| `navigation-header` | Wrapper for the `navigation-header` slot. |\n| `navigation-toggle` | The default mobile navigation button. |\n| `navigation-toggle-icon` | The default button's icon wrapper. |\n| `page` | Root Page wrapper; the same node as `base`. |\n| `skip-to-content` | The focus-revealed skip link. |\n| `subheader` | Wrapper for the `subheader` slot. |\n\n---\n\n**CSS Custom Properties**\n\n- `--aside-width` — Web Awesome alias for `--lr-page-aside-width`.\n- `--banner-height` — Web Awesome alias for `--lr-page-banner-height`.\n- `--header-height` — Web Awesome alias for `--lr-page-header-height`.\n- `--lr-page-aside-width` (default: `auto`) — Desktop aside column width.\n- `--lr-page-banner-height` (default: `0px`) — Minimum banner height and sticky offset.\n- `--lr-page-header-height` (default: `0px`) — Minimum header height and sticky offset.\n- `--lr-page-main-width` (default: `1fr`) — Desktop main column width.\n- `--lr-page-menu-width` (default: `auto`) — Desktop menu column width.\n- `--lr-page-navigation-backdrop-bg` (default: `var(--lr-color-overlay)`) — Background of the open mobile navigation backdrop.\n- `--lr-page-navigation-drawer-bg` (default: `var(--lr-color-surface-overlay)`) — Background of the mobile navigation drawer.\n- `--lr-page-navigation-drawer-shadow` (default: `var(--lr-shadow-l)`) — Shadow of the mobile navigation drawer.\n- `--lr-page-navigation-toggle-active-bg` (default: `color-mix(in oklab, var(--lr-color-brand-quiet), var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Background of a pressed default or slotted navigation toggle.\n- `--lr-page-navigation-toggle-active-color` (default: `var(--lr-color-brand)`) — Text color of a pressed default or slotted navigation toggle.\n- `--lr-page-navigation-toggle-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Background of a hovered default or slotted navigation toggle.\n- `--lr-page-navigation-toggle-hover-color` (default: `var(--lr-color-brand)`) — Text color of a hovered default or slotted navigation toggle.\n- `--lr-page-skip-to-content-active-bg` (default: `color-mix(in oklab, var(--lr-color-brand-quiet), var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Background of the pressed skip link.\n- `--lr-page-skip-to-content-active-color` (default: `var(--lr-color-brand)`) — Text color of the pressed skip link.\n- `--lr-page-skip-to-content-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Background of the hovered skip link.\n- `--lr-page-skip-to-content-hover-color` (default: `var(--lr-color-brand)`) — Text color of the hovered skip link.\n- `--lr-page-subheader-height` (default: `0px`) — Minimum subheader height and sticky offset. Interaction-state properties below are resolved as inline fallbacks, so setting one on the Page or any ancestor themes only its named target without replacing shared design tokens.\n- `--main-width` — Web Awesome alias for `--lr-page-main-width`.\n- `--menu-width` — Web Awesome alias for `--lr-page-menu-width`.\n- `--subheader-height` — Web Awesome alias for `--lr-page-subheader-height`.","attributes":[{"name":"aria-label","description":"Host-level accessible-name override forwarded to the internal navigation landmark.\n\nType: `| string\n    | null`  \nDefault: `null`"},{"name":"disable-navigation-toggle","description":"Hides the default mobile toggle. Slotted `data-toggle-nav` controls remain available.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"disable-sticky","description":"Whitespace-separated Page regions whose sticky positioning is disabled: `banner`, `header`, `subheader`, `menu`, and `aside`.\n\nType: `string`","value":{"type":["string"]}},{"name":"id","description":"SSR-reachable native fragment relationship; private so it does not invent another IDL API.\n\nType: `| string\n    | null`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"mobile-breakpoint","description":"Allocation breakpoint. Bare numbers/px, `rem`, and `em` use the shared CSS-length resolver;\ninvalid values fall back to `768px`.\n\nType: `string`  \nDefault: `'768px'`","value":{"type":["string"]}},{"name":"nav-open","description":"Whether mobile navigation is open. Desktop navigation remains visible independently.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"navigation-placement","description":"Logical edge occupied by desktop navigation and the mobile drawer.\n\nType: `PageNavigationPlacement`  \nDefault: `'start'`","value":{"type":["'start'","'end'"]}},{"name":"tabindex","description":"SSR-reachable native focusability for the fragment target.\n\nType: `| string\n    | null`"},{"name":"view","description":"Presentation derived from the Page's allocated inline size. It begins at `desktop` so server\noutput is deterministic, then reflects the first live allocation measurement.\n\nType: `PageView`  \nDefault: `'desktop'`","value":{"type":["'mobile'","'desktop'"]}}],"slots":[{"name":"","description":"Main content."},{"name":"aside","description":"Complementary content beside the main region."},{"name":"banner","description":"A page-wide notice above the header."},{"name":"footer","description":"Page-wide footer content."},{"name":"header","description":"Primary page header content."},{"name":"main-footer","description":"Content after the main body but inside the main landmark."},{"name":"main-header","description":"Content before the main body but inside the main landmark."},{"name":"menu","description":"A compact menu beside the main region."},{"name":"navigation","description":"Primary navigation content."},{"name":"navigation-footer","description":"Content after the navigation links."},{"name":"navigation-header","description":"Content before the navigation links."},{"name":"navigation-toggle","description":"Custom controls that toggle mobile navigation and each receive the managed ARIA relationship described above."},{"name":"navigation-toggle-icon","description":"Replaces the default toggle's menu glyph as inert, decorative visual content."},{"name":"skip-to-content","description":"Replaces the localized skip-link text as inert visual content; its descriptive text names the outer skip link."},{"name":"subheader","description":"A secondary header row."}],"js":{"properties":[{"name":"disableNavigationToggle","description":"Hides the default mobile toggle. Slotted `data-toggle-nav` controls remain available.\n\nAttribute: `disable-navigation-toggle`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"mobileBreakpoint","description":"Allocation breakpoint. Bare numbers/px, `rem`, and `em` use the shared CSS-length resolver;\ninvalid values fall back to `768px`.\n\nAttribute: `mobile-breakpoint`","type":"string","default":"'768px'"},{"name":"navOpen","description":"Whether mobile navigation is open. Desktop navigation remains visible independently.\n\nAttribute: `nav-open`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"navigationPlacement","description":"Logical edge occupied by desktop navigation and the mobile drawer.\n\nAttribute: `navigation-placement`  \nReflected to its attribute.","type":"PageNavigationPlacement","default":"'start'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"view","description":"Presentation derived from the Page's allocated inline size. It begins at `desktop` so server\noutput is deterministic, then reflects the first live allocation measurement.\n\nAttribute: `view`  \nReflected to its attribute.","type":"PageView","default":"'desktop'"}],"events":[{"name":"lr-nav-toggle","description":"A cancelable proposed `navOpen` state from `showNavigation()`, `hideNavigation()`, `toggleNavigation()`, or a built-in dismissal (backdrop click, Escape, the default navigation-toggle button). Call `preventDefault()` to leave `navOpen` unchanged. `detail: { open }`.","type":"CustomEvent<{ open: boolean }>"}]}},{"name":"lr-page-rail","description":"`<lr-page-rail>` — a virtualized vertical thumbnail rail for page-addressed documents, with\nper-page highlight heat markers. Two modes: **wired** (`viewer`/`for` supply a live\n`PageThumbnailSource`, e.g. `lr-pdf-viewer` -- thumbnails render lazily as rows materialize, and\nthe rail tracks page/count from the viewer's own events) and **mediated** (`page-count`/`page` are\nhost-bound directly, rows render a placeholder glyph -- still a fully functional pager). In wired\nmode the viewer's `page` is the single source of truth.\nUnmodified digit keys provide page-number type-ahead; Alt/Ctrl/Meta-modified digits remain\navailable to browser and application shortcuts and never alter the page.\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 rail. |\n| `heat` | The heat-marker cluster. |\n| `heat-dot` | One tone-colored heat marker (or the `+n` overflow marker). |\n| `heat-dot-accent` | An accent-tone heat marker (also carries `heat-dot`). |\n| `heat-dot-danger` | A danger-tone heat marker (also carries `heat-dot`). |\n| `heat-dot-neutral` | A neutral-tone heat marker (also carries `heat-dot`). |\n| `heat-dot-overflow` | The `+n` overflow marker (also carries `heat-dot`). |\n| `heat-dot-success` | A success-tone heat marker (also carries `heat-dot`). |\n| `heat-dot-warning` | A warning-tone heat marker (also carries `heat-dot`). |\n| `page` | One page button. |\n| `page-current` | The page button for the current `page` (also carries `page`). |\n| `page-number` | The visible page number. |\n| `pages` | The embedded `lr-virtual-list`. |\n| `thumbnail` | The thumbnail canvas/DOM-preview wrapper. |\n| `thumbnail-target` | The canvas or renderer-owned DOM-preview target. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-page-rail-current-bg` (default: `var(--lr-color-brand-quiet)`) — Background of the `[part=\"page-current\"]` button for the current `page`.\n- `--lr-page-rail-heat-accent-color` (default: `var(--lr-color-brand)`) — Background of an accent-tone (the default tone) `[part=\"heat-dot\"]` marker.\n- `--lr-page-rail-heat-danger-color` (default: `var(--lr-color-danger)`) — Background of a danger-tone `[part=\"heat-dot-danger\"]` marker.\n- `--lr-page-rail-heat-neutral-color` (default: `var(--lr-color-text-quiet)`) — Background of a neutral-tone `[part=\"heat-dot-neutral\"]` marker.\n- `--lr-page-rail-heat-success-color` (default: `var(--lr-color-success)`) — Background of a success-tone `[part=\"heat-dot-success\"]` marker.\n- `--lr-page-rail-heat-warning-color` (default: `var(--lr-color-warning)`) — Background of a warning-tone `[part=\"heat-dot-warning\"]` marker.\n- `--lr-page-rail-height` (default: `var(--lr-size-24rem)`) — Block size of the virtualized rail.","attributes":[{"name":"for","description":"Id of a `PageThumbnailSource` in the same root, the label/`htmlFor`-style alternative to\n`viewer`.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"label","description":"Overrides the computed accessible name.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"page","description":"Current page: auto-tracked in wired mode, host-bound in mediated mode.\n\nType: `number`  \nDefault: `1`","value":{"type":["number"]}},{"name":"page-count","description":"Mediated-mode page count. Ignored while a viewer is wired (`viewer` or a resolved `for`).\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"thumb-width","description":"Thumbnail CSS-px width, clamped to the container (320px-safe).\n\nType: `number`  \nDefault: `96`","value":{"type":["number"]}}],"js":{"properties":[{"name":"for","description":"Id of a `PageThumbnailSource` in the same root, the label/`htmlFor`-style alternative to\n`viewer`.\n\nAttribute: `for`","type":"string","default":"''"},{"name":"highlights","description":"Per-page heat-marker highlights. IDs are trimmed and must be nonempty; the first record for\nan ID is retained and blank or later duplicate records are ignored.","type":"readonly LyraHighlight[]"},{"name":"label","description":"Overrides the computed accessible name.\n\nAttribute: `label`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"page","description":"Current page: auto-tracked in wired mode, host-bound in mediated mode.\n\nAttribute: `page`  \nReflected to its attribute.","type":"number","default":"1"},{"name":"pageCount","description":"Mediated-mode page count. Ignored while a viewer is wired (`viewer` or a resolved `for`).\n\nAttribute: `page-count`","type":"number","default":"0"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"thumbWidth","description":"Thumbnail CSS-px width, clamped to the container (320px-safe).\n\nAttribute: `thumb-width`","type":"number","default":"96"},{"name":"viewer","type":"PageThumbnailSource | null","default":"null"}],"events":[{"name":"lr-page-select","description":"A page row was activated (click, or Enter/Space on a focused row). `detail: { page }`. In wired mode the rail also sets `viewer.page` itself.","type":"CustomEvent<{ page: number }>"}]}},{"name":"lr-pagination","description":"`<lr-pagination>` — controlled, server-friendly page navigation: a numbered\npage list with elided gaps, optional first/last controls, an optional\nitem-range summary, and a compact layout that swaps the list for an\neditable page jump.\n\nThe component never mutates `page`. Button and compact-field activation emits\n`lr-page-change`; link-mode anchors navigate without either page-change event. The consumer\napplies a button/field request after its own routing or data-fetch decision. Once the `page` property changes, a polite\nlive region announces the applied page and focus follows the newly current\npage control (or the compact page field).\nPublic `focus()`, `blur()`, and `click()` resolve the primary control for the active format:\nthe applied page control in standard format, or the page-jump input in compact format.\n\n`total=\"-1\"` enters indeterminate mode for a server API that never returns a total (limit/offset\nand cursor/keyset APIs typically don't) -- it renders previous/next plus a page-number field, no\nnumbered page list, no item-range summary, and no `page-count`. `format`, `with-summary`, and\n`with-edges` are ignored in this mode: there is no total to lay a page list or a \"last page\"\nbutton against. `hasNext` (default `true`) is the one extra signal the mode needs -- previous\navailability stays derivable from `page` alone, but forward availability generally is not for a\ncaller with no total. Any OTHER negative `total` (e.g. a computed `-50`) still renders the\nordinary empty state, exactly like today: only the exact `-1` sentinel opts in, so a garbage or\nmiscalculated negative value never silently reclassifies into a different rendering mode. Picked\nover a pair of `has-next`/`has-previous` booleans as the sole entry point because `total` is the\none property every consumer already sets, and it mirrors `<lr-table>`'s own established\nnegative-sentinel `total-items` precedent (see that property's own doc for why the two sentinels\nare kept numerically distinct). Event, focus-management, and announcement contracts are\nunchanged: `lr-before-page-change`/`lr-page-change`/`lr-activate` fire the same way, and the\napplied-page announcement/focus-follow both still run, just against a page-only message with no\ntotal-pages figure.\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| `first-icon` | Replacement for the first-page icon. |\n| `last-icon` | Replacement for the last-page icon. |\n| `next-icon` | Replacement for the next-page icon. |\n| `previous-icon` | Replacement for the previous-page icon. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | Compatibility name for the navigation wrapper; use `pagination`. |\n| `button` | Shared part on every page, ellipsis, and navigation control. |\n| `controls` | The previous/pages/next control group. |\n| `ellipsis` | An interactive control that jumps across a skipped run of pages. |\n| `first-button` | The first-page button, rendered with `with-edges`. |\n| `first-icon` | The first-page directional icon. |\n| `label` | Upstream alias on the same compact wrapper as `page-field`. |\n| `last-button` | The last-page button, rendered with `with-edges`. |\n| `last-icon` | The last-page directional icon. |\n| `live-region` | The visually hidden, `aria-hidden` mirror of the applied-page announcement. The announcement itself lands in the shared light-DOM polite region (`acquireAnnouncementSink()` in `internal/announcer.ts`), because a live region inside a shadow root is not reliably announced; this part is a styling/inspection surface only. |\n| `next-button` | The next-page button. |\n| `next-icon` | The next-page directional icon. |\n| `page` | One numbered page control; a `<button>`, or an `<a>` when `href-template` is set. |\n| `page-count` | The total page count shown after the input (`format=\"compact\"`). |\n| `page-current` | Also carried by the page control for the applied page, alongside `page`. |\n| `page-field` | The current-page input and page-count wrapper (`format=\"compact\"`). |\n| `page-input` | The validated numeric page-jump input (`format=\"compact\"`). |\n| `pages` | The `role=\"list\"` wrapper around the numbered page items. |\n| `pagination` | The navigation wrapper. It is the same node as `base`. |\n| `previous-button` | The previous-page button. |\n| `previous-icon` | The previous-page directional icon. |\n| `summary` | The item-range summary. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-pagination-active-bg` — Ordinary control pressed background; defaults to the current quiet-brand active mix.\n- `--lr-pagination-active-border-color` (default: `var(--lr-color-brand)`) — Ordinary control pressed border color.\n- `--lr-pagination-base-gap` (default: `var(--lr-space-m)`) — Gap between the summary and controls.\n- `--lr-pagination-control-bg` — Resting background of every control; defaults from the `appearance` variant.\n- `--lr-pagination-control-border-color` — Resting border color of every control; defaults from the `appearance` variant.\n- `--lr-pagination-control-color` (default: `var(--lr-color-text)`) — Resting control foreground.\n- `--lr-pagination-control-padding` (default: `var(--lr-space-xs)`) — Inner padding of the nav buttons and the page input. Uniform across every `size` (the control footprint is fixed by `--lr-pagination-control-size`, so this only adjusts the icon/digit inset).\n- `--lr-pagination-control-radius` (default: `var(--lr-radius)`) — Border radius of navigation buttons and the page input.\n- `--lr-pagination-control-size` — Control inline/block size; defaults from the `size` variant.\n- `--lr-pagination-controls-gap` (default: `var(--lr-space-xs)`) — Gap between the navigation controls and the numbered-page list or compact page field.\n- `--lr-pagination-current-active-bg` — Current-page pressed background; defaults to the current brand active mix.\n- `--lr-pagination-current-active-border-color` (default: `transparent`) — Current-page pressed border color.\n- `--lr-pagination-current-bg` (default: `var(--lr-color-brand)`) — Current-page background.\n- `--lr-pagination-current-border-color` (default: `transparent`) — Current-page border color.\n- `--lr-pagination-current-color` (default: `var(--lr-color-on-brand)`) — Current-page foreground.\n- `--lr-pagination-current-hover-bg` (default: `var(--lr-color-brand)`) — Current-page hover background.\n- `--lr-pagination-current-hover-border-color` (default: `transparent`) — Current-page hover border color.\n- `--lr-pagination-font-size` — Control font size; defaults from the `size` variant.\n- `--lr-pagination-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Ordinary control hover background.\n- `--lr-pagination-hover-border-color` (default: `var(--lr-color-brand)`) — Ordinary control hover border color.\n- `--lr-pagination-invalid-border` (default: `var(--lr-color-danger)`) — Border color of `[part=\"page-input\"]` while the typed page is out of range (`aria-invalid=\"true\"`).\n- `--lr-pagination-pages-gap` (default: `var(--lr-space-xs)`) — Gap between numbered page controls.","attributes":[{"name":"appearance","description":"Resting look of every control. The applied page stays a solid brand chip in all of them, so\nit is never the appearance that decides whether the current page is identifiable.\n\nType: `LyraAppearance`  \nDefault: `'outlined'`","value":{"type":["'accent'","'filled'","'outlined'","'filled-outlined'","'plain'"]}},{"name":"aria-label","description":"Accessible name forwarded from the host to the internal navigation landmark.\n\nType: `string | null`  \nDefault: `null`"},{"name":"boundary-count","description":"Pages always pinned at the start and at the end of the numbered list.\n\nType: `number`  \nDefault: `1`","value":{"type":["number"]}},{"name":"disabled","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"first-label","description":"Type: `string | undefined`"},{"name":"format","description":"`standard` renders the numbered page list; `compact` swaps it for the editable page jump,\nwhich fits a toolbar or a card footer where a full list would not. Unknown runtime values\nnormalize to `standard`.\n\nType: `LyraPaginationFormat`  \nDefault: `'standard'`","value":{"type":["'standard'","'compact'"]}},{"name":"has-next","description":"Whether at least one more page exists past the current one. Consulted only in indeterminate\nmode (`total=\"-1\"`, see the class doc) -- previous availability is always derivable from\n`page`, but forward availability generally is not for a caller with no total. Defaults to\n`true` so an indeterminate pager stays navigable until told otherwise.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"hide-single-page","description":"Renders nothing when zero or one page exists.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"href-template","description":"Renders each page as a link instead of a button, for SSR, crawlers, and no-JS navigation.\nA string uses `{page}` as the placeholder (`/products?page={page}`); a function receives the\npage number and returns the URL. A page whose resolved URL is not a safe navigation target\nfalls back to a button.\n\nType: `| string | ((page: number) => string)`  \nDefault: `''`"},{"name":"item-label","description":"Optional item noun used in the summary. Empty uses the localized `item`/`items` keys.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"label","description":"Accessible-name override for the internal navigation landmark, applied when no host\n`aria-label` is set. Optional. Omitting it localizes the default `paginationLabel` message;\nan explicit empty string renders no visible/accessible label.\n\nType: `string | undefined`"},{"name":"last-label","description":"Type: `string | undefined`"},{"name":"loading","description":"Disables navigation and exposes `aria-busy=\"true\"` while a page is loading.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"next-label","description":"Type: `string | undefined`"},{"name":"page","description":"The currently applied page. Controlled; this component never mutates it.\n\nType: `number`  \nDefault: `1`","value":{"type":["number"]}},{"name":"page-label","description":"Optional control-label overrides. Omission localizes the matching message key; supplied\nstrings, including the built-in English text or an empty string, render verbatim.\n\nType: `string | undefined`"},{"name":"page-size","description":"Number of items represented by one page. Non-positive values produce no pages.\n\nType: `number`  \nDefault: `10`","value":{"type":["number"]}},{"name":"previous-label","description":"Type: `string | undefined`"},{"name":"sibling-count","description":"Pages shown either side of the current page in the numbered list.\n\nType: `number`  \nDefault: `2`","value":{"type":["number"]}},{"name":"size","description":"Control footprint, on the library-wide six-step ladder. Web Awesome's and Shoelace's\n`small`/`medium`/`large` spellings are accepted as exact synonyms of `s`/`m`/`l`, so\nmigrating from either is a tag rename with no attribute rewrite.\n\nType: `LyraSize`  \nDefault: `'m'`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}},{"name":"total","description":"Total number of items across every page. Non-positive values render the empty state, with one\nexact exception: `-1` enters indeterminate mode instead (see the class doc) -- every other\nnegative value, including one arrived at by a miscalculation, still renders the ordinary empty\nstate. Named `total` to match `wa-pagination`; it used to be `total-items`, which a mechanical\nrename left unset — silently rendering the empty state.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"with-edges","description":"Renders buttons that jump straight to the first and last page.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"with-summary","description":"Renders the localized \"showing X–Y of Z\" summary row. Opt-in and `false` by default,\nmatching `wa-pagination`. It used to be `hide-summary`, an opt-*out* whose default showed the\nsummary, so a mechanical rename silently added a row to every migrated pager.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"without-nav","description":"Hides the previous and next controls while retaining pages and optional edge controls.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"first-icon","description":"Replacement for the first-page icon."},{"name":"last-icon","description":"Replacement for the last-page icon."},{"name":"next-icon","description":"Replacement for the next-page icon."},{"name":"previous-icon","description":"Replacement for the previous-page icon."}],"js":{"properties":[{"name":"accessibleLabel","description":"Accessible name forwarded from the host to the internal navigation landmark.\n\nAttribute: `aria-label`","type":"string | null","default":"null"},{"name":"appearance","description":"Resting look of every control. The applied page stays a solid brand chip in all of them, so\nit is never the appearance that decides whether the current page is identifiable.\n\nAttribute: `appearance`  \nReflected to its attribute.","type":"LyraAppearance","default":"'outlined'"},{"name":"boundaryCount","description":"Pages always pinned at the start and at the end of the numbered list.\n\nAttribute: `boundary-count`","type":"number","default":"1"},{"name":"disabled","description":"Attribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"firstLabel","description":"Attribute: `first-label`","type":"string | undefined"},{"name":"format","description":"`standard` renders the numbered page list; `compact` swaps it for the editable page jump,\nwhich fits a toolbar or a card footer where a full list would not. Unknown runtime values\nnormalize to `standard`.\n\nAttribute: `format`  \nReflected to its attribute.","type":"LyraPaginationFormat","default":"'standard'"},{"name":"hasNext","description":"Whether at least one more page exists past the current one. Consulted only in indeterminate\nmode (`total=\"-1\"`, see the class doc) -- previous availability is always derivable from\n`page`, but forward availability generally is not for a caller with no total. Defaults to\n`true` so an indeterminate pager stays navigable until told otherwise.\n\nAttribute: `has-next`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"hideSinglePage","description":"Renders nothing when zero or one page exists.\n\nAttribute: `hide-single-page`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"hrefTemplate","description":"Renders each page as a link instead of a button, for SSR, crawlers, and no-JS navigation.\nA string uses `{page}` as the placeholder (`/products?page={page}`); a function receives the\npage number and returns the URL. A page whose resolved URL is not a safe navigation target\nfalls back to a button.\n\nAttribute: `href-template`","type":"| string | ((page: number) => string)","default":"''"},{"name":"itemLabel","description":"Optional item noun used in the summary. Empty uses the localized `item`/`items` keys.\n\nAttribute: `item-label`","type":"string","default":"''"},{"name":"label","description":"Accessible-name override for the internal navigation landmark, applied when no host\n`aria-label` is set. Optional. Omitting it localizes the default `paginationLabel` message;\nan explicit empty string renders no visible/accessible label.\n\nAttribute: `label`","type":"string | undefined"},{"name":"lastLabel","description":"Attribute: `last-label`","type":"string | undefined"},{"name":"loading","description":"Disables navigation and exposes `aria-busy=\"true\"` while a page is loading.\n\nAttribute: `loading`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"nextLabel","description":"Attribute: `next-label`","type":"string | undefined"},{"name":"page","description":"The currently applied page. Controlled; this component never mutates it.\n\nAttribute: `page`  \nReflected to its attribute.","type":"number","default":"1"},{"name":"pageLabel","description":"Optional control-label overrides. Omission localizes the matching message key; supplied\nstrings, including the built-in English text or an empty string, render verbatim.\n\nAttribute: `page-label`","type":"string | undefined"},{"name":"pageSize","description":"Number of items represented by one page. Non-positive values produce no pages.\n\nAttribute: `page-size`","type":"number","default":"10"},{"name":"previousLabel","description":"Attribute: `previous-label`","type":"string | undefined"},{"name":"siblingCount","description":"Pages shown either side of the current page in the numbered list.\n\nAttribute: `sibling-count`","type":"number","default":"2"},{"name":"size","description":"Control footprint, on the library-wide six-step ladder. Web Awesome's and Shoelace's\n`small`/`medium`/`large` spellings are accepted as exact synonyms of `s`/`m`/`l`, so\nmigrating from either is a tag rename with no attribute rewrite.\n\nAttribute: `size`  \nReflected to its attribute.","type":"LyraSize","default":"'m'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"total","description":"Total number of items across every page. Non-positive values render the empty state, with one\nexact exception: `-1` enters indeterminate mode instead (see the class doc) -- every other\nnegative value, including one arrived at by a miscalculation, still renders the ordinary empty\nstate. Named `total` to match `wa-pagination`; it used to be `total-items`, which a mechanical\nrename left unset — silently rendering the empty state.\n\nAttribute: `total`","type":"number","default":"0"},{"name":"totalPages","description":"The total number of pages, derived from `total` and `pageSize`. Always `0` in indeterminate\nmode -- there is no total to derive a page count from.","type":"number","read-only":true},{"name":"withEdges","description":"Renders buttons that jump straight to the first and last page.\n\nAttribute: `with-edges`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"withSummary","description":"Renders the localized \"showing X–Y of Z\" summary row. Opt-in and `false` by default,\nmatching `wa-pagination`. It used to be `hide-summary`, an opt-*out* whose default showed the\nsummary, so a mechanical rename silently added a row to every migrated pager.\n\nAttribute: `with-summary`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"withoutNav","description":"Hides the previous and next controls while retaining pages and optional edge controls.\n\nAttribute: `without-nav`  \nReflected to its attribute.","type":"boolean","default":"false"}],"events":[{"name":"blur","description":"Re-dispatched from an internal pagination control as one bubbling, composed native `FocusEvent`, preserving its focus payload.","type":"FocusEvent"},{"name":"focus","description":"Re-dispatched from an internal pagination control as one bubbling, composed native `FocusEvent`, preserving its focus payload.","type":"FocusEvent"},{"name":"lr-activate","description":"Fired on every accepted page request, whether or not the page actually moved. `detail: { value }` carries the requested page number. Bubbling and composed, so a host outside the shadow tree receives it. Not cancelable: `lr-before-page-change` is this component's veto point, and a vetoed request emits no activation at all. Re-requesting the current page is the case `lr-page-change` deliberately stays silent for -- \"load that page again\" is a real intent, and it is otherwise unobservable, because the page buttons and the jump input live in this shadow root, so a retargeted `click` names no page and pressing Enter on the jump field produces no click. When a request does move the page, `lr-before-page-change` and `lr-page-change` are emitted first. Link-mode anchors navigate without emitting.","type":"CustomEvent<{ value: number }>"},{"name":"lr-before-page-change","description":"Fired before a valid button or compact-field page request. `detail: { page, pageSize }`. Cancelable; vetoing it suppresses `lr-page-change`. Link-mode anchors navigate without emitting.","type":"CustomEvent<LyraPaginationChangeDetail>"},{"name":"lr-page-change","description":"Fired when a button or compact field requests a valid page. `detail: { page, pageSize }`. The component remains controlled and never mutates `page` itself; link-mode anchors navigate without emitting.","type":"CustomEvent<LyraPaginationChangeDetail>"}]}},{"name":"lr-pan-zoom","description":"`<lr-pan-zoom>` — a scrollable frame for inspecting slotted or image content at a bounded zoom\nlevel. This is the intentionally renamed home of the original Lyra `lr-zoomable-frame`\npan-and-zoom API; `lr-zoomable-frame` now mirrors the iframe-based Web Awesome component.\n\n`resetZoom()` returns zoom to 1 while preserving the native scroll offset. `resetView()` also\nreturns the viewport to its origin for consumers that replace the inspected content.\n`fit` controls the base layout of an image supplied through `src`: `actual` preserves the\nexisting natural-size behavior, while `contain` and `width` size it against the viewport.\nThe three controls are independently tabbable native buttons in a labelled `group`; they do not\nclaim the arrow-key navigation contract of an ARIA toolbar.\n\n---\n\n**Component metadata**\n\n- Status: `stable`\n- Since: `8.0.0`\n- Rationale: This tag entered Lyra as a stable public API with documented behavior, accessibility, and cross-browser support.\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) | Content to inspect; when `src` is set, an image is rendered instead. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The frame wrapper. |\n| `content` | The transformed content wrapper. |\n| `controls` | Labelled group of independently tabbable zoom controls. |\n| `reset` | Reset-to-100-percent button. |\n| `viewport` | The scrollable viewport. |\n| `zoom-in` | Zoom-in button. |\n| `zoom-out` | Zoom-out button. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-pan-zoom-min-block-size` (default: `var(--lr-size-10rem)`) — Minimum viewport block size.\n- `--lr-pan-zoom-zoom` (default: `1`) — Read-only scale written from `zoom`; set the property instead.","attributes":[{"name":"alt","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"aria-label","description":"Overall host name when supplied as `aria-label`. A property-only value names the focusable\nviewport; when the host already owns a name, the viewport keeps its localized purpose name.\n\nType: `string | null`  \nDefault: `null`"},{"name":"fit","description":"Base image sizing policy. The default preserves the natural-size behavior of this frame.\n\nType: `LyraImageFit`","value":{"type":["'contain'","'width'","'actual'"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max-zoom","description":"Type: `number`  \nDefault: `4`","value":{"type":["number"]}},{"name":"min-zoom","description":"Type: `number`  \nDefault: `0.5`","value":{"type":["number"]}},{"name":"src","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"zoom","description":"Type: `number`  \nDefault: `1`","value":{"type":["number"]}},{"name":"zoom-step","description":"Type: `number`  \nDefault: `0.25`","value":{"type":["number"]}}],"slots":[{"name":"","description":"Content to inspect; when `src` is set, an image is rendered instead."}],"js":{"properties":[{"name":"accessibleLabel","description":"Overall host name when supplied as `aria-label`. A property-only value names the focusable\nviewport; when the host already owns a name, the viewport keeps its localized purpose name.\n\nAttribute: `aria-label`","type":"string | null","default":"null"},{"name":"alt","description":"Attribute: `alt`","type":"string","default":"''"},{"name":"fit","description":"Base image sizing policy. The default preserves the natural-size behavior of this frame.\n\nAttribute: `fit`  \nReflected to its attribute.","type":"LyraImageFit"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"maxZoom","description":"Attribute: `max-zoom`","type":"number","default":"4"},{"name":"minZoom","description":"Attribute: `min-zoom`","type":"number","default":"0.5"},{"name":"src","description":"Attribute: `src`","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"zoom","description":"Attribute: `zoom`  \nReflected to its attribute.","type":"number","default":"1"},{"name":"zoomStep","description":"Attribute: `zoom-step`","type":"number","default":"0.25"}],"events":[{"name":"blur","description":"Relayed once from the scrollable viewport as a bubbling, composed native event.","type":"FocusEvent"},{"name":"focus","description":"Relayed once from the scrollable viewport as a bubbling, composed native event.","type":"FocusEvent"},{"name":"lr-zoom-change","description":"Zoom changed. `detail: { zoom }`.","type":"CustomEvent<{ zoom: number }>"}]}},{"name":"lr-path-strip","description":"`<lr-path-strip>` — a linear node -> relation -> node chain rendering \"why A connects to B\"\n(GraphRAG local-search reasoning paths) as a compact, horizontally scrollable strip.\nOne-dimensional and presentational: no path finding, no branching, no per-element popovers.\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**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `arrow` | The `aria-hidden` directed-edge arrow glyph, logical (mirrors under RTL). |\n| `base` | The root wrapper, hosting the delegated roving-tabindex keydown handler. |\n| `empty` | The empty-state message, shown when `path` is empty. |\n| `node` | One `node`-kind element (a `<button>`). |\n| `relation` | One `edge`-kind element's relation label (a `<button>`). |","attributes":[{"name":"label","description":"Accessible name for the stable group when the host has no `aria-label`; falls back to\nlocalized `pathStripLabel` when omitted. An explicitly empty host label stays empty, and so\ndoes an explicitly empty `label`.\n\nType: `string | undefined`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"js":{"properties":[{"name":"label","description":"Accessible name for the stable group when the host has no `aria-label`; falls back to\nlocalized `pathStripLabel` when omitted. An explicitly empty host label stays empty, and so\ndoes an explicitly empty `label`.\n\nAttribute: `label`","type":"string | undefined"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"path","description":"Rendered in array order; alternation is the intended shape but not enforced.","type":"readonly LyraPathElement[]","default":"[]"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-entity-activate","description":"A node element activated. `detail: { entityId, occurrenceIndex }`.","type":"CustomEvent<{\n    entityId: string;\n    occurrenceIndex: number;\n  }>"},{"name":"lr-relation-activate","description":"An edge element activated. `detail: { relation, sourceNodeId?, targetNodeId?, occurrenceIndex }` — source/target resolved from the adjacent retained node elements, `undefined` when the path is malformed at that position. `occurrenceIndex` is the element's index in the supplied path, so deliberately repeated identities remain distinct.","type":"CustomEvent<{\n    relation: string;\n    sourceNodeId?: string;\n    targetNodeId?: string;\n    occurrenceIndex: number;\n  }>"}]}},{"name":"lr-pdf-viewer","description":"Fetches PDF bytes and renders their pages with the optional `pdfjs-dist` peer. Pages are composed\nthrough `lr-virtual-list`, while a PDF.js text layer keeps rendered text selectable and copyable.\nAdopts `DocumentAnchorTarget`: `page`, `text-quote`, and `region` anchors resolve; highlights paint\nvia one `<lr-highlight-layer>` per page, stacked beneath the text layer (canvas -> highlights ->\ntext layer) so starting a text selection over a cited passage keeps working. Pointer activation of\na highlight is hit-tested at the page-wrapper level (`onPageClick`) since the text layer sitting on\ntop intercepts most direct pointer events; keyboard activation reaches the highlight layer's own\nroving-tabindex rects directly, since z-stacking doesn't affect tab order. Accepted residual: a\nclick that ends a text-selection drag over a highlighted passage never activates it (the\nselection-in-progress check in `onPageClick` exists precisely to distinguish that case from a\ngenuine activation click).\nThe composed virtual-list lifecycle is an implementation detail: visible-range changes update\n`page`, while raw `lr-visible-range-change` and `lr-virtual-scroll` events stay contained.\nKnown capability boundaries: `search()`/text-quote anchors match exact (whitespace- and\nsoft-hyphen-normalized) text only -- there is no fuzzy/approximate mode (see `internal/\ntext-quote.ts`'s own doc comment for the exact normalization rules). Non-Latin cMap-encoded fonts\nget no special handling beyond whatever `pdfjs-dist` resolves on its own. A scanned or\nimage-only PDF has no text layer at all, so it has nothing to select or search.\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| `anchor-live-region` | The aria-hidden, non-live shadow mirror of the latest anchor-jump message. |\n| `base` | The named root viewer container with explicit `aria-busy`. |\n| `error` | Visible ordinary error text; transitions announce through the shared document-level assertive region. |\n| `next-button` | The next-page button. |\n| `page` | One rendered page wrapper. |\n| `page-canvas` | The canvas a page's content is painted onto. |\n| `page-error` | A visible, page-local fallback when one page fails without invalidating the rest of the document. |\n| `page-error-visible` | A currently visible page-local fallback (also carries `page-error`). |\n| `page-indicator` | The current page text. |\n| `pages` | The virtualized page list. |\n| `previous-button` | The previous-page button. |\n| `search-match` | A painted in-document search match. |\n| `search-match-active` | The currently active search match (also carries `search-match`). |\n| `spinner` | The decorative loading placeholder and its ordinary visually-hidden label; transitions announce through the shared document-level polite region. |\n| `text-layer` | Selectable text positioned over a page canvas. |\n| `text-span` | One generated text run inside a page's text layer. |\n| `toolbar` | Pagination and zoom controls. |\n| `zoom-in-button` | The zoom-in button. |\n| `zoom-indicator` | The current zoom percentage. |\n| `zoom-out-button` | The zoom-out button. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-pdf-viewer-height` (default: `var(--lr-size-24rem)`) — Block size of the virtualized page list.\n- `--lr-pdf-viewer-toolbar-bg` (default: `var(--lr-color-brand-quiet)`) — Background of the `toolbar` part, independent of the shared `--lr-color-brand-quiet` token.\n- `--lr-pdf-viewer-toolbar-button-hover-bg` (default: `var(--lr-color-surface)`) — Hover fill of the toolbar buttons. Defaults to the surface fill rather than the toolbar's own tint so the hover state is actually visible against it. Also settable via the `max-height` property.\n- `--lr-pdf-viewer-text-selection-bg` (default: `var(--lr-color-brand-quiet)`) — Background of a native text selection over a `text-span`, independent of the shared `--lr-color-brand-quiet` token.\n- `--lr-pdf-viewer-search-match-bg` (default: `var(--lr-color-warning-quiet)`) — Background of a painted, non-active search match.\n- `--lr-pdf-viewer-search-match-active-bg` (default: `var(--lr-color-warning)`) — Background of the currently active search match.","attributes":[{"name":"active-highlight-id","description":"Id of the currently active highlight, or null when none is active.\n\nType: `string | null`  \nDefault: `null`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max-height","description":"A CSS length (e.g. `\"30rem\"`); once set, overrides `--lr-pdf-viewer-height` -- the block size\nof the virtualized page list -- declaratively, the same `max-height` attribute\n`<lr-notebook-viewer>`/`<lr-svg-viewer>`/`<lr-xml-viewer>` expose, rather than requiring a\nconsumer to set the differently-named CSS custom property inline. Invalid values are\nignored.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"name","description":"Display name used as the document's accessible label fallback.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"page","description":"One-based current page, clamped to the loaded document's page count.\n\nType: `number`  \nDefault: `1`","value":{"type":["number"]}},{"name":"src","description":"URL to fetch and render as a PDF document.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"worker-src","description":"URL of the `pdfjs-dist` web worker chunk (`pdfjs-dist/build/pdf.worker.min.mjs`) as emitted by\nthe consuming application's own bundler. PDF.js rejects every `getDocument()` call with\n`No \"GlobalWorkerOptions.workerSrc\" specified.` until a worker is configured, and a bare package\nspecifier cannot be resolved from inside this library at runtime (there is no import map for it\nin a bundled app, and joining it to Lyra's own module URL points into Lyra's dist tree, where no\nworker exists), so a bundled application supplies the URL here. Document-relative values resolve\nagainst the document base; only `http:`, `https:`, `blob:` and `file:` URLs are accepted and\nanything else is ignored.\n\n`GlobalWorkerOptions` is PDF.js's process-wide singleton, so this is applied only while that\nsingleton is still unset: a worker the application configured itself is never overwritten, and\nwhen two viewers carry different values only the first one to load PDF.js takes effect for the\nwhole page. Assigning it after PDF.js has already loaded is not silently dropped -- it is\nre-applied on the next load -- but it still cannot displace a worker that is already configured.\nThe equivalent escape hatch, and the right choice for an application that wants one explicit\nworker for every viewer, is to import `pdfjs-dist` and set `GlobalWorkerOptions.workerSrc`\ndirectly during startup.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"zoom","description":"Page zoom multiplier, clamped to the range 0.25–4.\n\nType: `number`  \nDefault: `1`","value":{"type":["number"]}}],"js":{"properties":[{"name":"activeHighlightId","description":"Id of the currently active highlight, or null when none is active.\n\nAttribute: `active-highlight-id`","type":"string | null","default":"null"},{"name":"anchor","description":"Anchor or highlight id to resolve and scroll into view.","type":"LyraAnchor | string | null","default":"null"},{"name":"anchorKinds","description":"Anchor kinds this viewer resolves. `page` and page-addressed `region` anchors require an\ninteger within the loaded document's range; unlike the public `page` property, anchors are\nrejected rather than clamped.","type":"['page', 'text-quote', 'region']","default":"['page', 'text-quote', 'region']","read-only":true},{"name":"highlights","description":"Highlights rendered by the document target. Reassign after mutation.","type":"LyraHighlight[]","default":"[]"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"maxHeight","description":"A CSS length (e.g. `\"30rem\"`); once set, overrides `--lr-pdf-viewer-height` -- the block size\nof the virtualized page list -- declaratively, the same `max-height` attribute\n`<lr-notebook-viewer>`/`<lr-svg-viewer>`/`<lr-xml-viewer>` expose, rather than requiring a\nconsumer to set the differently-named CSS custom property inline. Invalid values are\nignored.\n\nAttribute: `max-height`","type":"string","default":"''"},{"name":"name","description":"Display name used as the document's accessible label fallback.\n\nAttribute: `name`","type":"string","default":"''"},{"name":"page","description":"One-based current page, clamped to the loaded document's page count.\n\nAttribute: `page`  \nReflected to its attribute.","type":"number","default":"1"},{"name":"pageViewerSnapshot","description":"Atomic readonly state for page-rail and other page-addressed integrations. Unlike the legacy\n`lr-load`/`lr-page-change` pair, a late subscriber can read this immediately, and `identity`\ndistinguishes same-count document replacements.","type":"LyraPageViewerSnapshot","read-only":true},{"name":"src","description":"URL to fetch and render as a PDF document.\n\nAttribute: `src`","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"workerSrc","description":"URL of the `pdfjs-dist` web worker chunk (`pdfjs-dist/build/pdf.worker.min.mjs`) as emitted by\nthe consuming application's own bundler. PDF.js rejects every `getDocument()` call with\n`No \"GlobalWorkerOptions.workerSrc\" specified.` until a worker is configured, and a bare package\nspecifier cannot be resolved from inside this library at runtime (there is no import map for it\nin a bundled app, and joining it to Lyra's own module URL points into Lyra's dist tree, where no\nworker exists), so a bundled application supplies the URL here. Document-relative values resolve\nagainst the document base; only `http:`, `https:`, `blob:` and `file:` URLs are accepted and\nanything else is ignored.\n\n`GlobalWorkerOptions` is PDF.js's process-wide singleton, so this is applied only while that\nsingleton is still unset: a worker the application configured itself is never overwritten, and\nwhen two viewers carry different values only the first one to load PDF.js takes effect for the\nwhole page. Assigning it after PDF.js has already loaded is not silently dropped -- it is\nre-applied on the next load -- but it still cannot displace a worker that is already configured.\nThe equivalent escape hatch, and the right choice for an application that wants one explicit\nworker for every viewer, is to import `pdfjs-dist` and set `GlobalWorkerOptions.workerSrc`\ndirectly during startup.\n\nAttribute: `worker-src`","type":"string","default":"''"},{"name":"zoom","description":"Page zoom multiplier, clamped to the range 0.25–4.\n\nAttribute: `zoom`  \nReflected to its attribute.","type":"number","default":"1"}],"events":[{"name":"lr-anchor-result","description":"Fired after an `anchor` (or `scrollToAnchor()` call) is applied. `detail: { found }`.","type":"CustomEvent<AnchorResultDetail>"},{"name":"lr-highlight-activate","description":"A highlight was activated. `detail: { highlightId }`.","type":"CustomEvent<HighlightActivateDetail>"},{"name":"lr-load","description":"Fired once the document reaches `ready`. `detail: { pageCount }`.","type":"CustomEvent<{ pageCount: number }>"},{"name":"lr-page-change","description":"Fired when the current page changes, but only once the document is ready -- a page set while the document is still loading is reflected in the viewer snapshot rather than announced, so a late subscriber reads it instead of missing it. This is a state broadcast, not a user-intent signal: unlike `<lr-pagination>` (which never mutates its own `page`, so its same-named event is a request the host applies) this viewer owns `page`, and scroll-driven crossings change it with no consumer action at all. Every accepted transition is therefore announced the same way -- scrolling, `nextPage()`/`previousPage()`/`goToPage()`, anchor resolution, a load resetting to page 1, and a plain `viewer.page = n` assignment included. A write that clamps or rounds back onto the page already showing changed nothing and is silent.","type":"CustomEvent<{ page: number; pageCount: number }>"},{"name":"lr-page-viewer-state-change","description":"Correlated page lifecycle state. `detail.snapshot` is the same readonly value exposed by `pageViewerSnapshot`; its `identity` changes for every load.","type":"CustomEvent<LyraPageViewerStateChangeDetail>"},{"name":"lr-render-error","description":"Fired when fetching, parsing, or rendering fails, including synchronous or rejected text-layer rendering. Text-layer failures are contained without an unhandled promise rejection.","type":"CustomEvent<{ error: unknown }>"},{"name":"lr-search-change","description":"Fired whenever the search query, match count, or active match index changes, including source-reset and effective-locale re-evaluation. `detail: { query, matchCount, matchCountExact, activeIndex }`. Search accepts at most 4,096 query code units, scans at most 1,000 pages/1,000,000 corpus code units/4,000,000 search code units, and retains at most 10,000 matches; a false `matchCountExact` makes `matchCount` a lower bound (including when a page could not be read or any ceiling is reached).","type":"CustomEvent<LyraSearchChangeDetail>"},{"name":"lr-text-select","description":"A text selection ended inside a page's text layer. `detail: { text, anchor, rects }`.","type":"CustomEvent<TextSelectDetail>"},{"name":"lr-zoom-change","description":"Fired when the zoom multiplier changes, on the same state-broadcast contract as `lr-page-change`: a programmatic `zoom` write announces exactly like a toolbar click. Not fired for the initial value, only for a transition away from it, and not for a write that clamps back onto the zoom already applied.","type":"CustomEvent<{ zoom: number }>"}]}},{"name":"lr-phone-input","description":"`<lr-phone-input>` — a country-aware telephone field whose form value is\ncanonical E.164. National formatting and numbering-plan validation are\nsupplied through `adapter`; without one, already-international E.164 input\nremains useful and national input stays editable with `incomplete` validity.\nAdapter results and country metadata are validated at the runtime boundary: only the exhaustive\nresult discriminator is accepted, `valid` requires E.164, malformed or hostile country rows are\nskipped, and malformed parser output fails closed to `invalid`.\n\nEach text edit emits native `input` then `lr-input`; a text commit emits native `change` then\n`lr-change`, and a country pick emits both pairs in that order. The aliases expose both the\ncanonical `value` and editable `inputValue`; programmatic property changes are silent.\nPhone-number text is deliberately LTR while\nthe form chrome and country selector follow the inherited direction. A host\n`aria-label` names the internal telephone input and wins over every derived\nor component-specific fallback; `phone-label`, `label` and `placeholder` follow in that order,\nand a field left with none of them still lands on a localized generic name rather than reaching\nthe accessibility tree unnamed. Pressing Enter performs the implicit form submission a native\n`<input type=\"tel\">` would (see `internal/submit-on-enter.ts` — the internal input is in a\nshadow root and has no form owner, so the platform can never do it here).\n\nThe country selector keeps the real, fully accessible native `<select>`\n(full country names in its popup, native mobile pickers, type-ahead) but\nrenders it invisibly over a compact visual trigger — selected alpha-2 code\nplus a design-system chevron — so long localized country names never clip\nthe closed control and the calling code isn't shown twice. With `flags`\nset, the trigger also shows the selected country's `<lr-flag>`; actual flag\nartwork still comes from the optional `@aceshooting/lyra-flags` peer,\nregistered by the consumer via `components/media/flag/flag-peer.js`\nexactly as for a standalone `<lr-flag>` (without that registration the\ntrigger simply omits the image). Native `<option>`s cannot contain\nelements, so the open popup remains text-only by platform design.\n\nComponent-scoped theme inputs remain undeclared on the host, so values inherited from an\nancestor theme wrapper override size and pill fallbacks. A value set directly on the phone\ninput still wins through normal custom-property inheritance.\nThe country selector retains the shared `--lr-icon-button-size` hit floor, and its row uses the\nsame action-bearing height ladder as input, number-input, and time-input.\n`readonly` locks both telephone and country mutation while retaining focus, selection, copying,\nform value, and submission. `autofocus` targets the real native telephone input.\n\nHost aria-describedby targets supplement local hint/error guidance on the telephone input,\nincluding live target changes, reconnect, and adoption. Removing default-country safely uses\nthe existing country fallback while retaining null property readback. Explicit countryLabel,\nincompleteText, and invalidText values win over locale strings; removing those copy attributes\nrestores their English property defaults and localized presentation. Empty validation copy\nretains a nonempty localized native error reason.\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| `country-prefix` | Optional visual displayed before the country selector, such as a flag. |\n| `error` | Custom error content. |\n| `hint` | Custom hint content. |\n| `label` | Custom label content. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `calling-code` | The selected country's calling code. |\n| `country` | The country selector region (invisible native select over the visual trigger). |\n| `country-code` | The selected alpha-2 code (or placeholder text) inside the trigger. |\n| `country-prefix` | Optional country adornment slot wrapper. |\n| `country-select` | The native country selector, stretched invisibly over the trigger. |\n| `country-trigger` | The visible, decorative closed-state trigger. |\n| `error` | Ordinary error/validation text referenced by the native telephone input through `aria-describedby`; it is not a live region, avoiding duplicate validation feedback. |\n| `expand-icon` | The dropdown indicator inside the trigger. |\n| `flag` | The selected country's `<lr-flag>` inside the trigger (only with `flags`). |\n| `form-control` | The outer form-control wrapper. |\n| `form-control-label` | The visible label. |\n| `hint` | The hint message. |\n| `input` | The native telephone input. |\n| `input-wrapper` | The country selector and telephone input wrapper. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-phone-input-padding-block` — Input block-padding, scaled by `size` through the shared form-control ladder.\n- `--lr-phone-input-font-size` — Input/flag/country-code/calling-code font size, scaled by `size`.\n- `--lr-phone-input-flag-size` — Selected flag size, scaled by `size`.\n- `--lr-phone-input-glyph-size` — Country selector glyph size, scaled by `size`.\n- `--lr-phone-input-gap` (default: `var(--lr-space-xs)`) — Country-trigger child gap.\n- `--lr-phone-input-radius` (default: `var(--lr-radius)`) — Input-wrapper corner radius, shared with the country trigger's leading corners. The `pill` attribute swaps it for `--lr-radius-pill`.\n- `--lr-phone-input-focus-border-color` (default: `var(--lr-color-brand)`) — Focused row border color.\n- `--lr-phone-input-invalid-border-color` (default: `var(--lr-color-danger)`) — Invalid row border color.\n- `--lr-phone-input-country-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Country trigger hover background.\n- `--lr-phone-input-control-min-height` (default: `var(--lr-form-control-height)`) — Input-wrapper block-size floor. Reads the shared form-control height ladder, so retuning `--lr-theme-form-control-height-*` moves this control and every sibling field together.\n- `--lr-phone-input-control-height` — Exact input-wrapper height. Unset by default, which leaves `--lr-phone-input-control-min-height` as a floor only; set it to a length to both floor and cap the row (e.g. to pixel-match a sibling field in the same toolbar row). Because it is never declared by the component itself, it can be set from an ancestor or an outer-tree rule as well as inline on the element.\n- `--lr-phone-input-fill` (default: `var(--lr-color-surface)`) — Resting background of the input row.\n- `--lr-phone-input-border-color` (default: `var(--lr-color-border)`) — Resting border color of the input row. The invalid and focused states keep their own hooks and still win over it.\n- `--lr-form-control-focus-shadow` (default: `none`) — The shared field focus halo, painted as a `box-shadow` while this control is focused. One name for every field-shaped control in the library, so a halo is configured once rather than per component. Additive: the focus outline and border cue are the accessibility answer to focus and are never replaced by it.\n- `--lr-form-control-required-content` (default: `' *'`) — The required-field marker rendered after the label. Set it to `''` to suppress the marker, or to any other quoted string (`' (required)'`, a localized word) to replace it. Caller-supplied content, so it is never localized here.\n- `--lr-form-control-required-color` (default: `var(--lr-color-danger)`) — Color of that marker, retunable without touching any other danger-coloured surface.\n- `--lr-form-control-required-offset` (default: `0`) — Inline space between the label text and the marker.","attributes":[{"name":"aria-label","description":"Accessible name for the telephone input. Takes precedence over `phoneLabel`, label, and placeholder.\n\nType: `string | null`  \nDefault: `null`"},{"name":"autocapitalize","description":"Forwarded to the internal `<input>`'s own `autocapitalize`. Empty string omits the attribute,\nleaving the browser's own default behavior.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"autocomplete","description":"Type: `string`  \nDefault: `'tel'`","value":{"type":["string"]}},{"name":"autocorrect","description":"Forwarded to the internal `<input>`'s own `autocorrect` (Safari/WebKit-specific). Empty\nstring omits the attribute. Named `autoCorrect` (capital `C`), not `autocorrect`, purely to\ndodge a TS `lib.dom.d.ts` collision: newer DOM typings declare a `boolean`-typed\n`HTMLElement.autocorrect` IDL member, which would conflict with this `string`-typed reactive\nproperty; the explicit `attribute: 'autocorrect'` mapping preserves the standard lowercase\n`autocorrect` wire name in both Lit and the rendered attribute.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"autofocus","description":"Forwards native autofocus to the real shadow input rather than the non-focusable host.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"country","description":"Currently selected ISO 3166-1 alpha-2 country code.\n\nType: `string`","value":{"type":["string"]}},{"name":"country-label","description":"Accessible name for the country selector. Explicit copy wins over locale strings; omission localizes.\n\nType: `string`  \nDefault: `'Select'`","value":{"type":["string"]}},{"name":"custom-error","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nType: `string | null`  \nDefault: `null`"},{"name":"default-country","description":"Country selected when no explicit `country` has been set.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"disabled","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"enterkeyhint","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"error-text","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"flags","description":"Show the selected country's flag in the country trigger. Rendering uses `<lr-flag\nfidelity=\"compact\">` (the icon-scale tier); the flag artwork itself still comes from the\noptional `@aceshooting/lyra-flags` peer package, which the consumer registers by importing\n`@aceshooting/lyra-ui/components/media/flag/flag-peer.js` — the same contract as a standalone\n`<lr-flag>`. Without that registration (or the peer package) the trigger simply renders no\nimage; nothing flag-related is bundled while this stays `false`. The native popup list stays\ntext-only — an `<option>` cannot contain elements.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"form","description":"Type: `HTMLFormElement | string | null`  \nDefault: `null`"},{"name":"hint","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"incomplete-text","description":"Validation message for a number that may still become valid with more digits. Explicit copy wins over locale strings; omission localizes.\n\nType: `string`  \nDefault: `'This phone number is incomplete.'`","value":{"type":["string"]}},{"name":"inputmode","description":"Type: `'tel' | 'numeric' | 'text'`  \nDefault: `'tel'`","value":{"type":["'tel'","'numeric'","'text'"]}},{"name":"invalid-text","description":"Validation message for a completed but invalid number. Explicit copy wins over locale strings; omission localizes.\n\nType: `string`  \nDefault: `'The value is invalid.'`","value":{"type":["string"]}},{"name":"label","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"name","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"phone-label","description":"Accessible-name override for the telephone input.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"pill","description":"Rounds the field's corners to a full pill, mirroring `lr-input`'s own `pill`. The country\ntrigger's leading corners follow, since both read `--lr-phone-input-radius`.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"placeholder","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"readonly","description":"Native readonly mode: keeps the telephone value focusable/copyable/submittable while\npreventing telephone and country edits and barring constraint validation.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"required","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"size","description":"Visual size — the library-wide `2xs`–`xl` ladder shared with `lr-input`. The Web Awesome /\nShoelace spellings `small`/`medium`/`large` are accepted for `s`/`m`/`l`, so a migration is a\ntag rename with no attribute rewrite.\n\nType: `LyraSize`  \nDefault: `'m'`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}},{"name":"spellcheck","description":"Forwarded to the internal `<input>`'s own `spellcheck`. Defaults to `true`, matching the\nnative element's own default. Uses spellcheckConverter rather than Lit's default\npresence-based boolean converter so an explicit `spellcheck=\"false\"` attribute is honored; a\n`.spellcheck=${false}` property binding can still turn this off directly.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"value","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}}],"slots":[{"name":"country-prefix","description":"Optional visual displayed before the country selector, such as a flag."},{"name":"error","description":"Custom error content."},{"name":"hint","description":"Custom hint content."},{"name":"label","description":"Custom label content."}],"js":{"properties":[{"name":"accessibleLabel","description":"Accessible name for the telephone input. Takes precedence over `phoneLabel`, label, and placeholder.\n\nAttribute: `aria-label`","type":"string | null","default":"null"},{"name":"adapter","type":"LyraPhoneNumberAdapter | undefined"},{"name":"autoCorrect","description":"Forwarded to the internal `<input>`'s own `autocorrect` (Safari/WebKit-specific). Empty\nstring omits the attribute. Named `autoCorrect` (capital `C`), not `autocorrect`, purely to\ndodge a TS `lib.dom.d.ts` collision: newer DOM typings declare a `boolean`-typed\n`HTMLElement.autocorrect` IDL member, which would conflict with this `string`-typed reactive\nproperty; the explicit `attribute: 'autocorrect'` mapping preserves the standard lowercase\n`autocorrect` wire name in both Lit and the rendered attribute.\n\nAttribute: `autocorrect`","type":"string","default":"''"},{"name":"autocapitalize","description":"Forwarded to the internal `<input>`'s own `autocapitalize`. Empty string omits the attribute,\nleaving the browser's own default behavior.\n\nAttribute: `autocapitalize`","type":"string","default":"''"},{"name":"autocomplete","description":"Attribute: `autocomplete`","type":"string","default":"'tel'"},{"name":"autofocus","description":"Forwards native autofocus to the real shadow input rather than the non-focusable host.\n\nAttribute: `autofocus`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"countries","type":"readonly LyraPhoneCountry[] | undefined"},{"name":"country","description":"Currently selected ISO 3166-1 alpha-2 country code.\n\nAttribute: `country`","type":"string"},{"name":"countryLabel","description":"Accessible name for the country selector. Explicit copy wins over locale strings; omission localizes.\n\nAttribute: `country-label`","type":"string","default":"'Select'"},{"name":"customError","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nAttribute: `custom-error`  \nReflected to its attribute.","type":"string | null","default":"null"},{"name":"defaultCountry","description":"Country selected when no explicit `country` has been set.\n\nAttribute: `default-country`","type":"string","default":"''"},{"name":"defaultValue","description":"Attribute: `value`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"disabled","description":"Attribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"enterkeyhint","description":"Attribute: `enterkeyhint`","type":"string","default":"''"},{"name":"errorText","description":"Attribute: `error-text`","type":"string","default":"''"},{"name":"flags","description":"Show the selected country's flag in the country trigger. Rendering uses `<lr-flag\nfidelity=\"compact\">` (the icon-scale tier); the flag artwork itself still comes from the\noptional `@aceshooting/lyra-flags` peer package, which the consumer registers by importing\n`@aceshooting/lyra-ui/components/media/flag/flag-peer.js` — the same contract as a standalone\n`<lr-flag>`. Without that registration (or the peer package) the trigger simply renders no\nimage; nothing flag-related is bundled while this stays `false`. The native popup list stays\ntext-only — an `<option>` cannot contain elements.\n\nAttribute: `flags`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"form","description":"Attribute: `form`  \nReflected to its attribute.","type":"HTMLFormElement | string | null","default":"null"},{"name":"hint","description":"Attribute: `hint`","type":"string","default":"''"},{"name":"incompleteText","description":"Validation message for a number that may still become valid with more digits. Explicit copy wins over locale strings; omission localizes.\n\nAttribute: `incomplete-text`","type":"string","default":"'This phone number is incomplete.'"},{"name":"input","description":"The underlying telephone input for platform-specific integrations.","type":"HTMLInputElement | undefined","read-only":true},{"name":"inputValue","description":"Editable display text, including a partial or invalid number.","type":"string","read-only":true},{"name":"inputmode","description":"Attribute: `inputmode`","type":"'tel' | 'numeric' | 'text'","default":"'tel'"},{"name":"invalidText","description":"Validation message for a completed but invalid number. Explicit copy wins over locale strings; omission localizes.\n\nAttribute: `invalid-text`","type":"string","default":"'The value is invalid.'"},{"name":"label","description":"Attribute: `label`","type":"string","default":"''"},{"name":"labels","type":"NodeList","read-only":true},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"name","description":"Attribute: `name`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"phoneLabel","description":"Accessible-name override for the telephone input.\n\nAttribute: `phone-label`","type":"string","default":"''"},{"name":"phoneStatus","description":"Current parse/validation state.","type":"LyraPhoneNumberStatus","read-only":true},{"name":"pill","description":"Rounds the field's corners to a full pill, mirroring `lr-input`'s own `pill`. The country\ntrigger's leading corners follow, since both read `--lr-phone-input-radius`.\n\nAttribute: `pill`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"placeholder","description":"Attribute: `placeholder`","type":"string","default":"''"},{"name":"readonly","description":"Native readonly mode: keeps the telephone value focusable/copyable/submittable while\npreventing telephone and country edits and barring constraint validation.\n\nAttribute: `readonly`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"required","description":"Attribute: `required`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"selectionDirection","type":"LyraPhoneInputSelectionDirection | null"},{"name":"selectionEnd","type":"number | null"},{"name":"selectionStart","type":"number | null"},{"name":"size","description":"Visual size — the library-wide `2xs`–`xl` ladder shared with `lr-input`. The Web Awesome /\nShoelace spellings `small`/`medium`/`large` are accepted for `s`/`m`/`l`, so a migration is a\ntag rename with no attribute rewrite.\n\nAttribute: `size`  \nReflected to its attribute.","type":"LyraSize","default":"'m'"},{"name":"spellcheck","description":"Forwarded to the internal `<input>`'s own `spellcheck`. Defaults to `true`, matching the\nnative element's own default. Uses spellcheckConverter rather than Lit's default\npresence-based boolean converter so an explicit `spellcheck=\"false\"` attribute is honored; a\n`.spellcheck=${false}` property binding can still turn this off directly.\n\nAttribute: `spellcheck`","type":"boolean","default":"true"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"validationMessage","type":"string","read-only":true},{"name":"validity","type":"ValidityState","read-only":true},{"name":"value","type":"string"},{"name":"willValidate","type":"boolean","read-only":true}],"events":[{"name":"blur","description":"Native `FocusEvent` relayed when the internal telephone input loses focus.","type":"FocusEvent"},{"name":"change","description":"Native `Event` fired when the telephone input commits or the country changes.","type":"Event"},{"name":"focus","description":"Native `FocusEvent` relayed when the internal telephone input receives focus.","type":"FocusEvent"},{"name":"input","description":"Native `InputEvent` fired for user edits and country changes.","type":"InputEvent"},{"name":"lr-change","description":"Lyra commit alias; detail contains the canonical and display values.","type":"CustomEvent<LyraPhoneInputEventDetail>"},{"name":"lr-input","description":"Lyra input alias; detail contains the canonical and display values.","type":"CustomEvent<LyraPhoneInputEventDetail>"},{"name":"lr-invalid","description":"The phone input failed a validity check. Cancelable: `preventDefault()` forwards to the native `invalid` event, suppressing the browser's own validation bubble and the focus/scroll `reportValidity()` would otherwise perform.","type":"CustomEvent<null>"}]}},{"name":"lr-pie-chart","description":"`<lr-pie-chart>` — `<lr-chart>` with a `\"pie\"` default and the mirrored writable type. Single-series:\none `LyraChartSeries` with `data: number[]` and `color: string[]` as the slice palette.\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) | An optional `<script type=\"application/json\">` containing a Chart.js configuration. |\n| `center` | Optional overlay content positioned at the chart area's center. Useful for doughnut and pie totals. |\n| `data-table` | An optional consumer-provided accessible table alternative. Use this escape hatch for a complete paginated or virtualized alternative when the generated 1,000-record sample is insufficient. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The chart wrapper. |\n| `canvas` | The Chart.js canvas. |\n| `center` | The chart-area-centered overlay wrapper for the `center` slot. |\n| `data-table` | The optional generated or slotted data table. |\n| `data-table-toggle` | The disclosure button rendered by `dataTableToggle`. |\n| `data-truncation` | Explanation shown when the generated accessible alternative samples a data set larger than its 1,000-record ceiling. |\n| `description` | The accessible chart summary. |\n| `error` | Static visible error shown instead of `canvas` when the optional `chart.js` peer dependency is not installed; its transition is announced through a shared light-DOM alert. |\n| `feature-warning` | Static nonfatal warning when a requested optional feature peer is unavailable while the core chart remains usable. |\n| `legend` | The wrapping DOM legend, rendered unless `withoutLegend` is set. |\n| `legend-item` | A keyboard-operable dataset or category visibility toggle. |\n| `legend-item-hidden` | Added while the legend item's dataset or category is hidden. |\n| `legend-swatch` | The resolved dataset/category color swatch in a legend item. |\n| `notices` | Wrapper for nonfatal feature warnings and generated-data truncation notices. |\n| `plot` | The fixed-height canvas/overlay region. |\n| `reset-zoom-button` | The reset-zoom control when zoom is active. |\n\n---\n\n**CSS Custom Properties**\n\n- `--border-color-1` (default: `var(--lr-color-chart-1)`) — First dataset border color.\n- `--border-color-2` (default: `var(--lr-color-chart-2)`) — Second dataset border color.\n- `--border-color-3` (default: `var(--lr-color-chart-3)`) — Third dataset border color.\n- `--border-color-4` (default: `var(--lr-color-chart-4)`) — Fourth dataset border color.\n- `--border-color-5` (default: `var(--lr-color-chart-5)`) — Fifth dataset border color.\n- `--border-color-6` (default: `var(--lr-color-chart-6)`) — Sixth dataset border color.\n- `--border-radius` (default: `var(--lr-radius)`) — Dataset element corner radius.\n- `--border-width` (default: `var(--lr-border-width-thin)`) — Dataset element border width.\n- `--fill-color-1` (default: `var(--lr-color-chart-1)`) — First dataset fill color.\n- `--fill-color-2` (default: `var(--lr-color-chart-2)`) — Second dataset fill color.\n- `--fill-color-3` (default: `var(--lr-color-chart-3)`) — Third dataset fill color.\n- `--fill-color-4` (default: `var(--lr-color-chart-4)`) — Fourth dataset fill color.\n- `--fill-color-5` (default: `var(--lr-color-chart-5)`) — Fifth dataset fill color.\n- `--fill-color-6` (default: `var(--lr-color-chart-6)`) — Sixth dataset fill color.\n- `--grid-border-width` (default: `var(--lr-border-width-thin)`) — Axis and grid line width.\n- `--grid-color` (default: `var(--lr-chart-grid-color)`) — Grid line color.\n- `--line-border-width` (default: `var(--lr-border-width-medium)`) — Line dataset stroke width.\n- `--lr-chart-canvas-hover-outline-color` (default: `var(--lr-chart-grid-color)`) — Color of the `[part='canvas']` hover-state outline.\n- `--lr-chart-canvas-hover-outline-width` (default: `var(--lr-border-width-thin)`) — Width of the `[part='canvas']` hover-state outline.\n- `--lr-chart-data-table-button-active-bg` — Pressed background of an actionable generated- table value; defaults to the standard active mix of `--lr-color-brand-quiet`.\n- `--lr-chart-data-table-button-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background of an actionable generated-table value.\n- `--lr-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-chart-data-table-toggle-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background of the `dataTableToggle` disclosure button.\n- `--lr-chart-grid-color` (default: `var(--lr-color-border)`) — Grid-line color. Resolved via `getComputedStyle` on every draw (Chart.js paints to canvas and cannot consume `var()`).\n- `--lr-chart-height` (default: `var(--lr-size-280px)`) — The plot region's `block-size` and the host's minimum block size. A visible data table or wrapping DOM legend grows the host in normal flow instead of overlapping following content. `height` supplies a private fallback; this public token always wins when a consumer sets it.\n- `--lr-chart-legend-color` (default: `var(--lr-color-text)`) — Legend label color. Resolved via `getComputedStyle` on every draw.\n- `--lr-chart-legend-item-active-bg` — Pressed background of a legend visibility button; defaults to the standard active mix of `--lr-color-brand-quiet`.\n- `--lr-chart-legend-item-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background of a legend visibility button.\n- `--lr-chart-legend-side-max` (default: `var(--lr-size-15rem)`) — Maximum inline size reserved for a side-positioned DOM legend; the track is also capped at one third of the chart allocation.\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 every series collapses to one system color and the stripe/crosshatch pattern 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.\n- `--lr-chart-reset-zoom-button-active-bg` — Pressed background of the reset-zoom button; defaults to the standard active mix of `--lr-color-brand-quiet`.\n- `--lr-chart-reset-zoom-button-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background of the reset-zoom button.\n- `--lr-chart-tick-color` (default: `var(--lr-color-text-quiet)`) — Axis tick-label color; also used for the `xLabel`/`yLabel`/`y2Label` axis-title text (there is no separate title-color token). Resolved via `getComputedStyle` on every draw.\n- `--lr-chart-tick-font-size` (default: `var(--lr-font-size-xs)`) — Axis tick-label font size, in any CSS length unit. Defaults to `--lr-font-size-xs` (12px at the standard root) because that matches Chart.js's OWN built-in tick font size, which is what every canvas chart rendered before this token existed -- leaving it unset must stay byte-identical to that, not shrink to `<lr-lite-chart>`'s SVG default. Also sizes the radar/polarArea `r`-scale `pointLabels` (the spoke labels), but ONLY once set: those default separately to Chart.js's OWN distinct `RadialLinearScale` `pointLabels` default (10px, not this token's 12px), and only adopt this token's size once the consumer explicitly sets it, at which point ticks and point labels match. Resolved via `getComputedStyle` on every draw, same constraint as every other `--lr-chart-*` token here (Chart.js paints to canvas and cannot consume `var()`).\n- `--lr-chart-tooltip-bg` (default: `var(--lr-color-surface)`) — Tooltip background color. Resolved via `getComputedStyle` on every draw.\n- `--lr-chart-tooltip-text` (default: `var(--lr-color-text)`) — Tooltip text color. Resolved via `getComputedStyle` on every draw.\n- `--point-radius` (default: `var(--lr-space-2xs)`) — Line/scatter point radius.","attributes":[{"name":"area","description":"Chart-wide default fill-under-line setting for line-type series; a series's own `LyraChartSeries.fill` overrides it.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"axes","description":"Complete cartesian axis visibility, independent of grid. `y` also controls the y2 axis.\nRadial charts ignore this setting. Explicit config scale options retain precedence.\n\nType: `LyraChartAxes`  \nDefault: `'both'`","value":{"type":["'x'","'y'","'both'","'none'"]}},{"name":"begin-at-zero","description":"Type: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"compact","description":"Compact cartesian plot: hide axes and remove automatic layout padding. Set height and\nwithoutLegend for a small histogram/sparkline. Preserves data tables, tooltips and keyboard\nactions; radial charts ignore this setting. Explicit config options retain precedence.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"data-labels","description":"Draws each data point's value on the chart via the optional\n`chartjs-plugin-datalabels` peer. Unset (the default) leaves labels off for\nthis chart; the peer is attached only to instances that opt in, and\n`buildConfig()` keeps its per-chart options disabled until this is set. The\nscreen-reader equivalent is the always-present data table (see\n`show-data-table`); labels are a purely visual, canvas-only addition.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"data-table-toggle","description":"Render a disclosure button above the accessible data table so a sighted reader can reveal the\nnumbers behind the chart on demand. `showDataTable` alone is all-or-nothing -- the table is\neither permanently screen-reader-only or permanently visible -- which left a consumer wrapping\na duplicated table in their own `<details>`.\n\nWith this set, `showDataTable` becomes the disclosure's *initial* state rather than its whole\nbehavior. The table stays in the DOM in both states, so assistive technology never loses it.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"description","description":"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`"},{"name":"grid","description":"Controls which cartesian grid axes are drawn.\n\nType: `LyraChartGrid`  \nDefault: `'both'`","value":{"type":["'x'","'y'","'both'","'none'"]}},{"name":"height","description":"Type: `string`  \nDefault: `'280px'`","value":{"type":["string"]}},{"name":"index-axis","description":"Chart.js index axis. `'y'` is Chart.js's own mechanism for horizontal bars (it also flips\nline/area types onto a horizontal category axis).\n\nType: `LyraChartIndexAxis`  \nDefault: `'x'`","value":{"type":["'x'","'y'"]}},{"name":"label","description":"Accessible chart label. A host `aria-label` still has highest precedence.\n\nType: `string | null`  \nDefault: `null`"},{"name":"legend-display","description":"`auto` retains optional legend formatting; `label` omits values even with a formatter; `value`\nappends a formatted value. `percentage` uses locale percentages of the absolute represented\nlegend values, including hidden items (zero totals yield 0%). `value-percentage` appends both,\nas `label: value (percentage)`. Dataset values are sampled sums; category values come from the\nfirst dataset. The `formatter`/`valueFormatter` callback backing `value` and `value-percentage`\nadditionally receives that same `percentage` in its `surface: 'legend'` context, so a custom\nformatter can build its own combined text without recomputing the share. Tooltip and axis\nformatting are unchanged.\n\nType: `LyraChartLegendDisplay`  \nDefault: `'auto'`","value":{"type":["'auto'","'label'","'value'","'percentage'","'value-percentage'"]}},{"name":"legend-mode","description":"`datum` renders category toggles for pie/doughnut/polar-area charts. Categories use the first\ndataset's colors and values; a toggle affects that category in every ring. Other chart types\nretain dataset legends. `auto` (the default) resolves to `datum` on pie/doughnut/polar-area\ncharts -- where a single-dataset legend would otherwise enumerate one entry for the whole\ndataset instead of one per visible slice -- and to `dataset` everywhere else. `dataset` always\nforces the dataset legend, even on a slice chart. Both non-`auto` modes use the generated\naccessible-data sampling budget.\n\nType: `LyraChartLegendMode`  \nDefault: `'auto'`","value":{"type":["'auto'","'dataset'","'datum'"]}},{"name":"legend-position","description":"Legend placement. `auto` uses a right legend above 480px and a bottom legend below it.\n\nType: `LyraChartLegendPosition`  \nDefault: `'top'`","value":{"type":["'left'","'top'","'right'","'bottom'","'center'","'chartArea'","'start'","'end'","'auto'"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max","description":"Maximum value-axis bound. Non-finite values are ignored.\n\nType: `number | null`  \nDefault: `null`"},{"name":"min","description":"Minimum value-axis bound. Non-finite values are ignored.\n\nType: `number | null`  \nDefault: `null`"},{"name":"plugins","description":"Chart.js plugins attached to this chart instance. Valid plugins retain their opaque identity.\n\nType: `readonly LyraChartPlugin[]`  \nDefault: `[]`"},{"name":"scale-type","description":"Scale type for the **value** axis (the categorical axis is unaffected). `'logarithmic'` plots\na dataset spanning several orders of magnitude honestly, where a linear axis collapses\neverything below the maximum into the baseline. Inherited by `lr-line-chart`,\n`lr-scatter-chart` and `lr-bar-chart`.\n\nA logarithmic axis cannot represent zero or negative values (`log(0)` is `-Infinity`), so\n`beginAtZero` is not forwarded in that mode -- Chart.js would otherwise be handed a bound it\ncannot place. Non-positive data points are dropped by Chart.js's own log scale.\n\nType: `LyraChartScaleType`  \nDefault: `'linear'`","value":{"type":["'linear'","'logarithmic'"]}},{"name":"show-data-table","description":"Makes the generated data table visible; it remains screen-reader available when false.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"stack-totals","description":"When the chart is `stacked` (bar/line only), draws the per-category stack\ntotal above each stack, via the same optional `chartjs-plugin-datalabels`\npeer as `data-labels`. Null/undefined points are skipped; a category whose\nevery value is null shows no total. The generated accessible data table\nreceives the same formatted total column (one per value axis). Unset (the\ndefault) draws and adds nothing.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"stacked","description":"Stacks the `x`/`y`(/`y2`) scale entries `buildScales()` returns; only meaningful for `bar` and `line` types.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"type","description":"Type: `LyraChartType`  \nDefault: `'pie'`","value":{"type":["'line'","'bar'","'scatter'","'pie'","'doughnut'","'radar'","'polarArea'","'bubble'"]}},{"name":"without-animation","description":"Disables Chart.js animation.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"without-legend","description":"Hides the legend.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"without-tooltip","description":"Hides Chart.js tooltips.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"x-label","description":"Type: `string | null`  \nDefault: `null`"},{"name":"y-label","description":"Type: `string | null`  \nDefault: `null`"},{"name":"y2-label","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"zoom","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"","description":"An optional `<script type=\"application/json\">` containing a Chart.js configuration."},{"name":"center","description":"Optional overlay content positioned at the chart area's center. Useful for doughnut and pie totals."},{"name":"data-table","description":"An optional consumer-provided accessible table alternative. Use this escape hatch for a complete paginated or virtualized alternative when the generated 1,000-record sample is insufficient."}],"js":{"properties":[{"name":"annotations","description":"Declarative reference lines and shaded bands — a threshold, an event year, a regime change, a\nhighlighted period. Each entry marks either a single `value` or a `from`/`to` range on `axis`\n(default `'y'`), with an optional `label` and semantic `tone`.\n\nNeeds the optional `chartjs-plugin-annotation` peer, loaded on first actual demand so a page\nwith no annotated charts never downloads it. The plugin is registered globally, like\n`chartjs-plugin-zoom` and unlike `chartjs-plugin-datalabels`: it draws nothing unless a chart\nsupplies annotation options, so the registration is unobservable to charts that set none, and\nregistration is also what installs the plugin's own element defaults. Without the peer\ninstalled the chart still renders; a console warning plus a localized visible warning and\nlight-DOM announcement explain the no-op — the same fail-closed contract `data-labels` uses.\n\nEntries are included in the generated accessible description, mirroring `lr-heatmap`.","type":"readonly LyraChartAnnotation[]","default":"[]"},{"name":"area","description":"Chart-wide default fill-under-line setting for line-type series; a series's own `LyraChartSeries.fill` overrides it.\n\nAttribute: `area`","type":"boolean","default":"false"},{"name":"axes","description":"Complete cartesian axis visibility, independent of grid. `y` also controls the y2 axis.\nRadial charts ignore this setting. Explicit config scale options retain precedence.\n\nAttribute: `axes`","type":"LyraChartAxes","default":"'both'"},{"name":"beginAtZero","description":"Attribute: `begin-at-zero`","type":"boolean","default":"true"},{"name":"chart","description":"The current Chart.js instance. Read it only while the element is connected and loaded.","type":"LyraChartInstance | undefined"},{"name":"chartArea","description":"The current Chart.js chart-area geometry in canvas-local coordinates. Read-only -- derived\nfrom the live Chart.js instance's own layout pass, never assignable. The setter is a\ndocumented no-op (matching `lr-histogram`'s `labels`/`datasets` pattern) so an accidental\n`.chartArea=${x}` Lit template binding degrades silently instead of throwing from inside\nlit-html's property-commit.","type":"LyraChartArea | undefined"},{"name":"compact","description":"Compact cartesian plot: hide axes and remove automatic layout padding. Set height and\nwithoutLegend for a small histogram/sparkline. Preserves data tables, tooltips and keyboard\nactions; radial charts ignore this setting. Explicit config options retain precedence.\n\nAttribute: `compact`","type":"boolean","default":"false"},{"name":"config","type":"LyraChartConfiguration | undefined"},{"name":"dataLabels","description":"Draws each data point's value on the chart via the optional\n`chartjs-plugin-datalabels` peer. Unset (the default) leaves labels off for\nthis chart; the peer is attached only to instances that opt in, and\n`buildConfig()` keeps its per-chart options disabled until this is set. The\nscreen-reader equivalent is the always-present data table (see\n`show-data-table`); labels are a purely visual, canvas-only addition.\n\nAttribute: `data-labels`","type":"boolean","default":"false"},{"name":"dataTableToggle","description":"Render a disclosure button above the accessible data table so a sighted reader can reveal the\nnumbers behind the chart on demand. `showDataTable` alone is all-or-nothing -- the table is\neither permanently screen-reader-only or permanently visible -- which left a consumer wrapping\na duplicated table in their own `<details>`.\n\nWith this set, `showDataTable` becomes the disclosure's *initial* state rather than its whole\nbehavior. The table stays in the DOM in both states, so assistive technology never loses it.\n\nAttribute: `data-table-toggle`","type":"boolean","default":"false"},{"name":"datasets","description":"Simplified chart series. Non-record entries are dropped while valid sibling series remain.","type":"readonly LyraChartSeries[]"},{"name":"description","description":"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\nAttribute: `description`","type":"string | null","default":"null"},{"name":"formatter","description":"Unified context-object formatter for visual, tooltip, table/export, and spoken values.","type":"LyraChartFormatter | undefined"},{"name":"grid","description":"Controls which cartesian grid axes are drawn.\n\nAttribute: `grid`","type":"LyraChartGrid","default":"'both'"},{"name":"height","description":"Attribute: `height`","type":"string","default":"'280px'"},{"name":"hiddenDatasets","description":"Complete controlled visibility state for DOM legend toggles. `undefined` (the default) honors\neach effective dataset's `hidden` configuration; a defined array wins over those defaults, and\nan empty array deliberately makes every dataset visible. Invalid, duplicate, and out-of-range\nindexes are ignored when state is applied or emitted.","type":"readonly number[] | undefined"},{"name":"hiddenDatums","description":"Controlled hidden source category indexes for pie/doughnut/polar-area charts, shared by all\ndatasets/rings. Clone-owned; invalid, duplicate and out-of-range indexes are ignored when\napplied or emitted. Empty restores all categories. Does not alter dataset visibility or exports.","type":"readonly number[]","default":"[]"},{"name":"indexAxis","description":"Chart.js index axis. `'y'` is Chart.js's own mechanism for horizontal bars (it also flips\nline/area types onto a horizontal category axis).\n\nAttribute: `index-axis`","type":"LyraChartIndexAxis","default":"'x'"},{"name":"label","description":"Accessible chart label. A host `aria-label` still has highest precedence.\n\nAttribute: `label`","type":"string | null","default":"null"},{"name":"labels","type":"string[]","default":"[]"},{"name":"legendDisplay","description":"`auto` retains optional legend formatting; `label` omits values even with a formatter; `value`\nappends a formatted value. `percentage` uses locale percentages of the absolute represented\nlegend values, including hidden items (zero totals yield 0%). `value-percentage` appends both,\nas `label: value (percentage)`. Dataset values are sampled sums; category values come from the\nfirst dataset. The `formatter`/`valueFormatter` callback backing `value` and `value-percentage`\nadditionally receives that same `percentage` in its `surface: 'legend'` context, so a custom\nformatter can build its own combined text without recomputing the share. Tooltip and axis\nformatting are unchanged.\n\nAttribute: `legend-display`","type":"LyraChartLegendDisplay","default":"'auto'"},{"name":"legendMode","description":"`datum` renders category toggles for pie/doughnut/polar-area charts. Categories use the first\ndataset's colors and values; a toggle affects that category in every ring. Other chart types\nretain dataset legends. `auto` (the default) resolves to `datum` on pie/doughnut/polar-area\ncharts -- where a single-dataset legend would otherwise enumerate one entry for the whole\ndataset instead of one per visible slice -- and to `dataset` everywhere else. `dataset` always\nforces the dataset legend, even on a slice chart. Both non-`auto` modes use the generated\naccessible-data sampling budget.\n\nAttribute: `legend-mode`","type":"LyraChartLegendMode","default":"'auto'"},{"name":"legendPosition","description":"Legend placement. `auto` uses a right legend above 480px and a bottom legend below it.\n\nAttribute: `legend-position`","type":"LyraChartLegendPosition","default":"'top'"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"max","description":"Maximum value-axis bound. Non-finite values are ignored.\n\nAttribute: `max`","type":"number | null","default":"null"},{"name":"min","description":"Minimum value-axis bound. Non-finite values are ignored.\n\nAttribute: `min`","type":"number | null","default":"null"},{"name":"plugins","description":"Chart.js plugins attached to this chart instance. Valid plugins retain their opaque identity.\n\nAttribute: `plugins`","type":"readonly LyraChartPlugin[]","default":"[]"},{"name":"scaleType","description":"Scale type for the **value** axis (the categorical axis is unaffected). `'logarithmic'` plots\na dataset spanning several orders of magnitude honestly, where a linear axis collapses\neverything below the maximum into the baseline. Inherited by `lr-line-chart`,\n`lr-scatter-chart` and `lr-bar-chart`.\n\nA logarithmic axis cannot represent zero or negative values (`log(0)` is `-Infinity`), so\n`beginAtZero` is not forwarded in that mode -- Chart.js would otherwise be handed a bound it\ncannot place. Non-positive data points are dropped by Chart.js's own log scale.\n\nAttribute: `scale-type`","type":"LyraChartScaleType","default":"'linear'"},{"name":"showDataTable","description":"Makes the generated data table visible; it remains screen-reader available when false.\n\nAttribute: `show-data-table`","type":"boolean","default":"false"},{"name":"stackTotals","description":"When the chart is `stacked` (bar/line only), draws the per-category stack\ntotal above each stack, via the same optional `chartjs-plugin-datalabels`\npeer as `data-labels`. Null/undefined points are skipped; a category whose\nevery value is null shows no total. The generated accessible data table\nreceives the same formatted total column (one per value axis). Unset (the\ndefault) draws and adds nothing.\n\nAttribute: `stack-totals`","type":"boolean","default":"false"},{"name":"stacked","description":"Stacks the `x`/`y`(/`y2`) scale entries `buildScales()` returns; only meaningful for `bar` and `line` types.\n\nAttribute: `stacked`","type":"boolean","default":"false"},{"name":"stackedAxes","description":"Per-value-axis override of `stacked`, keyed by `'y'`/`'y2'`. An axis absent from this record\n-- including every axis when the whole property is unset -- falls back to the chart-wide\n`stacked` value, which is what keeps a chart that never sets this byte-identical to before.\nLets a `stacked` bar series on the primary axis sit next to an unstacked overlay series on\n`y2` (via `LyraChartSeries.axis: 'y2'`): set `stackedAxes` to `{ y2: false }` alongside\n`stacked`, or spell out both axes explicitly. The shared categorical axis (`x` for a vertical\nbar/line, or `y` when `indexAxis` is `'y'`) has no independent entry of its own -- it always\nmirrors the resolved `'y'` value, matching Chart.js's own paired index/value-scale stacking\ncontract. Only meaningful for `bar`/`line` types, matching `stacked` itself.","type":"Partial<Record<'y' | 'y2', boolean>> | undefined"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"tooltipFooterFormatter","description":"Tooltip footer formatter -- e.g. a category's stack total under the items. Receives every\nitem the hovered tooltip covers, in the same shape as `tooltipTitleFormatter`. Unset (the\ndefault) leaves Chart.js's own default (no footer).","type":"LyraChartTooltipGroupFormatter | undefined"},{"name":"tooltipTitleFormatter","description":"Tooltip title formatter -- e.g. a scatter point's own name. Receives every item the hovered\ntooltip covers, each in `formatter`'s `'tooltip'`-surface context shape. Unset (the default)\nleaves Chart.js's own default title (the shared category label) in place.","type":"LyraChartTooltipGroupFormatter | undefined"},{"name":"type","description":"Attribute: `type`","type":"LyraChartType","default":"'pie'"},{"name":"valueFormatter","description":"Formats numeric (value-axis) ticks, tooltip values, legend values, and generated accessible\ntable cells from one callback.\nHorizontal scalar tooltips use parsed x, including a raw config indexAxis override;\nstructured points retain their y-value contract. The context-object formatter shares this rule.\nNever runs against the categorical x-axis's own labels (line/bar's `labels` strings) —\nChart.js's category scale passes the tick index to `ticks.callback`, not the label text,\nso formatting it would corrupt the axis.","type":"LyraChartValueFormatter | undefined"},{"name":"withoutAnimation","description":"Disables Chart.js animation.\n\nAttribute: `without-animation`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"withoutLegend","description":"Hides the legend.\n\nAttribute: `without-legend`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"withoutTooltip","description":"Hides Chart.js tooltips.\n\nAttribute: `without-tooltip`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"xLabel","description":"Attribute: `x-label`","type":"string | null","default":"null"},{"name":"y2Label","description":"Attribute: `y2-label`","type":"string","default":"''"},{"name":"yLabel","description":"Attribute: `y-label`","type":"string | null","default":"null"},{"name":"zoom","description":"Attribute: `zoom`","type":"boolean","default":"false"}],"events":[{"name":"lr-before-datum-visibility-change","description":"Cancelable category visibility proposal in datum legend mode. `detail: { index: number, visible: boolean, hiddenDatums: readonly number[] }`. Source category indexes apply to every dataset/ring. The complete detail is frozen.","type":"CustomEvent<LyraChartDatumVisibilityChangeDetail>"},{"name":"lr-before-legend-visibility-change","description":"Cancelable proposal emitted before a DOM legend toggle changes state. `detail` contains the target `datasetIndex`, its proposed `visible` value, and the complete canonical proposed `hiddenDatasets` snapshot.","type":"CustomEvent<LyraChartLegendVisibilityChangeDetail>"},{"name":"lr-datum-activate","description":"Family-normalized activation event. Its detail adds `kind` (`bar`, `point`, `segment`, or `slice`) to the `lr-point-click` detail.","type":"CustomEvent<\n    LyraChartDatumActivateDetail<LyraCoreChartDatumKind>\n  >"},{"name":"lr-datum-visibility-change","description":"Emitted after an accepted category toggle commits the same frozen detail. Programmatic `hiddenDatums` assignments are silent.","type":"CustomEvent<LyraChartDatumVisibilityChangeDetail>"},{"name":"lr-legend-visibility-change","description":"Emitted after an accepted DOM legend toggle commits the same detail. Programmatic `hiddenDatasets` changes reconcile without either event.","type":"CustomEvent<LyraChartLegendVisibilityChangeDetail>"},{"name":"lr-point-click","description":"Fired when pointer input lands on a data point/segment, when a generated data-table value is activated, or when Enter/Space activates the keyboard-current canvas datum. `detail: { datasetIndex: number, index: number, label: string | undefined, value: unknown }`. For scatter/bubble data, `label` prefers the per-point label and `value` is the complete typed `LyraChartPoint` (`x`, `y`, optional `r`, optional `label`).","type":"CustomEvent<{\n    datasetIndex: number;\n    index: number;\n    label: string | undefined;\n    value: unknown;\n  }>"},{"name":"lr-zoom","description":"`detail: { zoomed }`.","type":"CustomEvent<{ zoomed: boolean }>"}]}},{"name":"lr-polar-area-chart","description":"`<lr-polar-area-chart>` — `<lr-chart>` with a `\"polarArea\"` default and the mirrored writable type.\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) | An optional `<script type=\"application/json\">` containing a Chart.js configuration. |\n| `center` | Optional overlay content positioned at the chart area's center. Useful for doughnut and pie totals. |\n| `data-table` | An optional consumer-provided accessible table alternative. Use this escape hatch for a complete paginated or virtualized alternative when the generated 1,000-record sample is insufficient. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The chart wrapper. |\n| `canvas` | The Chart.js canvas. |\n| `center` | The chart-area-centered overlay wrapper for the `center` slot. |\n| `data-table` | The optional generated or slotted data table. |\n| `data-table-toggle` | The disclosure button rendered by `dataTableToggle`. |\n| `data-truncation` | Explanation shown when the generated accessible alternative samples a data set larger than its 1,000-record ceiling. |\n| `description` | The accessible chart summary. |\n| `error` | Static visible error shown instead of `canvas` when the optional `chart.js` peer dependency is not installed; its transition is announced through a shared light-DOM alert. |\n| `feature-warning` | Static nonfatal warning when a requested optional feature peer is unavailable while the core chart remains usable. |\n| `legend` | The wrapping DOM legend, rendered unless `withoutLegend` is set. |\n| `legend-item` | A keyboard-operable dataset or category visibility toggle. |\n| `legend-item-hidden` | Added while the legend item's dataset or category is hidden. |\n| `legend-swatch` | The resolved dataset/category color swatch in a legend item. |\n| `notices` | Wrapper for nonfatal feature warnings and generated-data truncation notices. |\n| `plot` | The fixed-height canvas/overlay region. |\n| `reset-zoom-button` | The reset-zoom control when zoom is active. |\n\n---\n\n**CSS Custom Properties**\n\n- `--border-color-1` (default: `var(--lr-color-chart-1)`) — First dataset border color.\n- `--border-color-2` (default: `var(--lr-color-chart-2)`) — Second dataset border color.\n- `--border-color-3` (default: `var(--lr-color-chart-3)`) — Third dataset border color.\n- `--border-color-4` (default: `var(--lr-color-chart-4)`) — Fourth dataset border color.\n- `--border-color-5` (default: `var(--lr-color-chart-5)`) — Fifth dataset border color.\n- `--border-color-6` (default: `var(--lr-color-chart-6)`) — Sixth dataset border color.\n- `--border-radius` (default: `var(--lr-radius)`) — Dataset element corner radius.\n- `--border-width` (default: `var(--lr-border-width-thin)`) — Dataset element border width.\n- `--fill-color-1` (default: `var(--lr-color-chart-1)`) — First dataset fill color.\n- `--fill-color-2` (default: `var(--lr-color-chart-2)`) — Second dataset fill color.\n- `--fill-color-3` (default: `var(--lr-color-chart-3)`) — Third dataset fill color.\n- `--fill-color-4` (default: `var(--lr-color-chart-4)`) — Fourth dataset fill color.\n- `--fill-color-5` (default: `var(--lr-color-chart-5)`) — Fifth dataset fill color.\n- `--fill-color-6` (default: `var(--lr-color-chart-6)`) — Sixth dataset fill color.\n- `--grid-border-width` (default: `var(--lr-border-width-thin)`) — Axis and grid line width.\n- `--grid-color` (default: `var(--lr-chart-grid-color)`) — Grid line color.\n- `--line-border-width` (default: `var(--lr-border-width-medium)`) — Line dataset stroke width.\n- `--lr-chart-canvas-hover-outline-color` (default: `var(--lr-chart-grid-color)`) — Color of the `[part='canvas']` hover-state outline.\n- `--lr-chart-canvas-hover-outline-width` (default: `var(--lr-border-width-thin)`) — Width of the `[part='canvas']` hover-state outline.\n- `--lr-chart-data-table-button-active-bg` — Pressed background of an actionable generated- table value; defaults to the standard active mix of `--lr-color-brand-quiet`.\n- `--lr-chart-data-table-button-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background of an actionable generated-table value.\n- `--lr-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-chart-data-table-toggle-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background of the `dataTableToggle` disclosure button.\n- `--lr-chart-grid-color` (default: `var(--lr-color-border)`) — Grid-line color. Resolved via `getComputedStyle` on every draw (Chart.js paints to canvas and cannot consume `var()`).\n- `--lr-chart-height` (default: `var(--lr-size-280px)`) — The plot region's `block-size` and the host's minimum block size. A visible data table or wrapping DOM legend grows the host in normal flow instead of overlapping following content. `height` supplies a private fallback; this public token always wins when a consumer sets it.\n- `--lr-chart-legend-color` (default: `var(--lr-color-text)`) — Legend label color. Resolved via `getComputedStyle` on every draw.\n- `--lr-chart-legend-item-active-bg` — Pressed background of a legend visibility button; defaults to the standard active mix of `--lr-color-brand-quiet`.\n- `--lr-chart-legend-item-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background of a legend visibility button.\n- `--lr-chart-legend-side-max` (default: `var(--lr-size-15rem)`) — Maximum inline size reserved for a side-positioned DOM legend; the track is also capped at one third of the chart allocation.\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 every series collapses to one system color and the stripe/crosshatch pattern 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.\n- `--lr-chart-reset-zoom-button-active-bg` — Pressed background of the reset-zoom button; defaults to the standard active mix of `--lr-color-brand-quiet`.\n- `--lr-chart-reset-zoom-button-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background of the reset-zoom button.\n- `--lr-chart-tick-color` (default: `var(--lr-color-text-quiet)`) — Axis tick-label color; also used for the `xLabel`/`yLabel`/`y2Label` axis-title text (there is no separate title-color token). Resolved via `getComputedStyle` on every draw.\n- `--lr-chart-tick-font-size` (default: `var(--lr-font-size-xs)`) — Axis tick-label font size, in any CSS length unit. Defaults to `--lr-font-size-xs` (12px at the standard root) because that matches Chart.js's OWN built-in tick font size, which is what every canvas chart rendered before this token existed -- leaving it unset must stay byte-identical to that, not shrink to `<lr-lite-chart>`'s SVG default. Also sizes the radar/polarArea `r`-scale `pointLabels` (the spoke labels), but ONLY once set: those default separately to Chart.js's OWN distinct `RadialLinearScale` `pointLabels` default (10px, not this token's 12px), and only adopt this token's size once the consumer explicitly sets it, at which point ticks and point labels match. Resolved via `getComputedStyle` on every draw, same constraint as every other `--lr-chart-*` token here (Chart.js paints to canvas and cannot consume `var()`).\n- `--lr-chart-tooltip-bg` (default: `var(--lr-color-surface)`) — Tooltip background color. Resolved via `getComputedStyle` on every draw.\n- `--lr-chart-tooltip-text` (default: `var(--lr-color-text)`) — Tooltip text color. Resolved via `getComputedStyle` on every draw.\n- `--point-radius` (default: `var(--lr-space-2xs)`) — Line/scatter point radius.","attributes":[{"name":"area","description":"Chart-wide default fill-under-line setting for line-type series; a series's own `LyraChartSeries.fill` overrides it.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"axes","description":"Complete cartesian axis visibility, independent of grid. `y` also controls the y2 axis.\nRadial charts ignore this setting. Explicit config scale options retain precedence.\n\nType: `LyraChartAxes`  \nDefault: `'both'`","value":{"type":["'x'","'y'","'both'","'none'"]}},{"name":"begin-at-zero","description":"Type: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"compact","description":"Compact cartesian plot: hide axes and remove automatic layout padding. Set height and\nwithoutLegend for a small histogram/sparkline. Preserves data tables, tooltips and keyboard\nactions; radial charts ignore this setting. Explicit config options retain precedence.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"data-labels","description":"Draws each data point's value on the chart via the optional\n`chartjs-plugin-datalabels` peer. Unset (the default) leaves labels off for\nthis chart; the peer is attached only to instances that opt in, and\n`buildConfig()` keeps its per-chart options disabled until this is set. The\nscreen-reader equivalent is the always-present data table (see\n`show-data-table`); labels are a purely visual, canvas-only addition.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"data-table-toggle","description":"Render a disclosure button above the accessible data table so a sighted reader can reveal the\nnumbers behind the chart on demand. `showDataTable` alone is all-or-nothing -- the table is\neither permanently screen-reader-only or permanently visible -- which left a consumer wrapping\na duplicated table in their own `<details>`.\n\nWith this set, `showDataTable` becomes the disclosure's *initial* state rather than its whole\nbehavior. The table stays in the DOM in both states, so assistive technology never loses it.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"description","description":"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`"},{"name":"grid","description":"Controls which cartesian grid axes are drawn.\n\nType: `LyraChartGrid`  \nDefault: `'both'`","value":{"type":["'x'","'y'","'both'","'none'"]}},{"name":"height","description":"Type: `string`  \nDefault: `'280px'`","value":{"type":["string"]}},{"name":"index-axis","description":"Chart.js index axis. `'y'` is Chart.js's own mechanism for horizontal bars (it also flips\nline/area types onto a horizontal category axis).\n\nType: `LyraChartIndexAxis`  \nDefault: `'x'`","value":{"type":["'x'","'y'"]}},{"name":"label","description":"Accessible chart label. A host `aria-label` still has highest precedence.\n\nType: `string | null`  \nDefault: `null`"},{"name":"legend-display","description":"`auto` retains optional legend formatting; `label` omits values even with a formatter; `value`\nappends a formatted value. `percentage` uses locale percentages of the absolute represented\nlegend values, including hidden items (zero totals yield 0%). `value-percentage` appends both,\nas `label: value (percentage)`. Dataset values are sampled sums; category values come from the\nfirst dataset. The `formatter`/`valueFormatter` callback backing `value` and `value-percentage`\nadditionally receives that same `percentage` in its `surface: 'legend'` context, so a custom\nformatter can build its own combined text without recomputing the share. Tooltip and axis\nformatting are unchanged.\n\nType: `LyraChartLegendDisplay`  \nDefault: `'auto'`","value":{"type":["'auto'","'label'","'value'","'percentage'","'value-percentage'"]}},{"name":"legend-mode","description":"`datum` renders category toggles for pie/doughnut/polar-area charts. Categories use the first\ndataset's colors and values; a toggle affects that category in every ring. Other chart types\nretain dataset legends. `auto` (the default) resolves to `datum` on pie/doughnut/polar-area\ncharts -- where a single-dataset legend would otherwise enumerate one entry for the whole\ndataset instead of one per visible slice -- and to `dataset` everywhere else. `dataset` always\nforces the dataset legend, even on a slice chart. Both non-`auto` modes use the generated\naccessible-data sampling budget.\n\nType: `LyraChartLegendMode`  \nDefault: `'auto'`","value":{"type":["'auto'","'dataset'","'datum'"]}},{"name":"legend-position","description":"Legend placement. `auto` uses a right legend above 480px and a bottom legend below it.\n\nType: `LyraChartLegendPosition`  \nDefault: `'top'`","value":{"type":["'left'","'top'","'right'","'bottom'","'center'","'chartArea'","'start'","'end'","'auto'"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max","description":"Maximum value-axis bound. Non-finite values are ignored.\n\nType: `number | null`  \nDefault: `null`"},{"name":"min","description":"Minimum value-axis bound. Non-finite values are ignored.\n\nType: `number | null`  \nDefault: `null`"},{"name":"plugins","description":"Chart.js plugins attached to this chart instance. Valid plugins retain their opaque identity.\n\nType: `readonly LyraChartPlugin[]`  \nDefault: `[]`"},{"name":"scale-type","description":"Scale type for the **value** axis (the categorical axis is unaffected). `'logarithmic'` plots\na dataset spanning several orders of magnitude honestly, where a linear axis collapses\neverything below the maximum into the baseline. Inherited by `lr-line-chart`,\n`lr-scatter-chart` and `lr-bar-chart`.\n\nA logarithmic axis cannot represent zero or negative values (`log(0)` is `-Infinity`), so\n`beginAtZero` is not forwarded in that mode -- Chart.js would otherwise be handed a bound it\ncannot place. Non-positive data points are dropped by Chart.js's own log scale.\n\nType: `LyraChartScaleType`  \nDefault: `'linear'`","value":{"type":["'linear'","'logarithmic'"]}},{"name":"show-data-table","description":"Makes the generated data table visible; it remains screen-reader available when false.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"stack-totals","description":"When the chart is `stacked` (bar/line only), draws the per-category stack\ntotal above each stack, via the same optional `chartjs-plugin-datalabels`\npeer as `data-labels`. Null/undefined points are skipped; a category whose\nevery value is null shows no total. The generated accessible data table\nreceives the same formatted total column (one per value axis). Unset (the\ndefault) draws and adds nothing.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"stacked","description":"Stacks the `x`/`y`(/`y2`) scale entries `buildScales()` returns; only meaningful for `bar` and `line` types.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"type","description":"Type: `LyraChartType`  \nDefault: `'polarArea'`","value":{"type":["'line'","'bar'","'scatter'","'pie'","'doughnut'","'radar'","'polarArea'","'bubble'"]}},{"name":"without-animation","description":"Disables Chart.js animation.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"without-legend","description":"Hides the legend.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"without-tooltip","description":"Hides Chart.js tooltips.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"x-label","description":"Type: `string | null`  \nDefault: `null`"},{"name":"y-label","description":"Type: `string | null`  \nDefault: `null`"},{"name":"y2-label","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"zoom","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"","description":"An optional `<script type=\"application/json\">` containing a Chart.js configuration."},{"name":"center","description":"Optional overlay content positioned at the chart area's center. Useful for doughnut and pie totals."},{"name":"data-table","description":"An optional consumer-provided accessible table alternative. Use this escape hatch for a complete paginated or virtualized alternative when the generated 1,000-record sample is insufficient."}],"js":{"properties":[{"name":"annotations","description":"Declarative reference lines and shaded bands — a threshold, an event year, a regime change, a\nhighlighted period. Each entry marks either a single `value` or a `from`/`to` range on `axis`\n(default `'y'`), with an optional `label` and semantic `tone`.\n\nNeeds the optional `chartjs-plugin-annotation` peer, loaded on first actual demand so a page\nwith no annotated charts never downloads it. The plugin is registered globally, like\n`chartjs-plugin-zoom` and unlike `chartjs-plugin-datalabels`: it draws nothing unless a chart\nsupplies annotation options, so the registration is unobservable to charts that set none, and\nregistration is also what installs the plugin's own element defaults. Without the peer\ninstalled the chart still renders; a console warning plus a localized visible warning and\nlight-DOM announcement explain the no-op — the same fail-closed contract `data-labels` uses.\n\nEntries are included in the generated accessible description, mirroring `lr-heatmap`.","type":"readonly LyraChartAnnotation[]","default":"[]"},{"name":"area","description":"Chart-wide default fill-under-line setting for line-type series; a series's own `LyraChartSeries.fill` overrides it.\n\nAttribute: `area`","type":"boolean","default":"false"},{"name":"axes","description":"Complete cartesian axis visibility, independent of grid. `y` also controls the y2 axis.\nRadial charts ignore this setting. Explicit config scale options retain precedence.\n\nAttribute: `axes`","type":"LyraChartAxes","default":"'both'"},{"name":"beginAtZero","description":"Attribute: `begin-at-zero`","type":"boolean","default":"true"},{"name":"chart","description":"The current Chart.js instance. Read it only while the element is connected and loaded.","type":"LyraChartInstance | undefined"},{"name":"chartArea","description":"The current Chart.js chart-area geometry in canvas-local coordinates. Read-only -- derived\nfrom the live Chart.js instance's own layout pass, never assignable. The setter is a\ndocumented no-op (matching `lr-histogram`'s `labels`/`datasets` pattern) so an accidental\n`.chartArea=${x}` Lit template binding degrades silently instead of throwing from inside\nlit-html's property-commit.","type":"LyraChartArea | undefined"},{"name":"compact","description":"Compact cartesian plot: hide axes and remove automatic layout padding. Set height and\nwithoutLegend for a small histogram/sparkline. Preserves data tables, tooltips and keyboard\nactions; radial charts ignore this setting. Explicit config options retain precedence.\n\nAttribute: `compact`","type":"boolean","default":"false"},{"name":"config","type":"LyraChartConfiguration | undefined"},{"name":"dataLabels","description":"Draws each data point's value on the chart via the optional\n`chartjs-plugin-datalabels` peer. Unset (the default) leaves labels off for\nthis chart; the peer is attached only to instances that opt in, and\n`buildConfig()` keeps its per-chart options disabled until this is set. The\nscreen-reader equivalent is the always-present data table (see\n`show-data-table`); labels are a purely visual, canvas-only addition.\n\nAttribute: `data-labels`","type":"boolean","default":"false"},{"name":"dataTableToggle","description":"Render a disclosure button above the accessible data table so a sighted reader can reveal the\nnumbers behind the chart on demand. `showDataTable` alone is all-or-nothing -- the table is\neither permanently screen-reader-only or permanently visible -- which left a consumer wrapping\na duplicated table in their own `<details>`.\n\nWith this set, `showDataTable` becomes the disclosure's *initial* state rather than its whole\nbehavior. The table stays in the DOM in both states, so assistive technology never loses it.\n\nAttribute: `data-table-toggle`","type":"boolean","default":"false"},{"name":"datasets","description":"Simplified chart series. Non-record entries are dropped while valid sibling series remain.","type":"readonly LyraChartSeries[]"},{"name":"description","description":"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\nAttribute: `description`","type":"string | null","default":"null"},{"name":"formatter","description":"Unified context-object formatter for visual, tooltip, table/export, and spoken values.","type":"LyraChartFormatter | undefined"},{"name":"grid","description":"Controls which cartesian grid axes are drawn.\n\nAttribute: `grid`","type":"LyraChartGrid","default":"'both'"},{"name":"height","description":"Attribute: `height`","type":"string","default":"'280px'"},{"name":"hiddenDatasets","description":"Complete controlled visibility state for DOM legend toggles. `undefined` (the default) honors\neach effective dataset's `hidden` configuration; a defined array wins over those defaults, and\nan empty array deliberately makes every dataset visible. Invalid, duplicate, and out-of-range\nindexes are ignored when state is applied or emitted.","type":"readonly number[] | undefined"},{"name":"hiddenDatums","description":"Controlled hidden source category indexes for pie/doughnut/polar-area charts, shared by all\ndatasets/rings. Clone-owned; invalid, duplicate and out-of-range indexes are ignored when\napplied or emitted. Empty restores all categories. Does not alter dataset visibility or exports.","type":"readonly number[]","default":"[]"},{"name":"indexAxis","description":"Chart.js index axis. `'y'` is Chart.js's own mechanism for horizontal bars (it also flips\nline/area types onto a horizontal category axis).\n\nAttribute: `index-axis`","type":"LyraChartIndexAxis","default":"'x'"},{"name":"label","description":"Accessible chart label. A host `aria-label` still has highest precedence.\n\nAttribute: `label`","type":"string | null","default":"null"},{"name":"labels","type":"string[]","default":"[]"},{"name":"legendDisplay","description":"`auto` retains optional legend formatting; `label` omits values even with a formatter; `value`\nappends a formatted value. `percentage` uses locale percentages of the absolute represented\nlegend values, including hidden items (zero totals yield 0%). `value-percentage` appends both,\nas `label: value (percentage)`. Dataset values are sampled sums; category values come from the\nfirst dataset. The `formatter`/`valueFormatter` callback backing `value` and `value-percentage`\nadditionally receives that same `percentage` in its `surface: 'legend'` context, so a custom\nformatter can build its own combined text without recomputing the share. Tooltip and axis\nformatting are unchanged.\n\nAttribute: `legend-display`","type":"LyraChartLegendDisplay","default":"'auto'"},{"name":"legendMode","description":"`datum` renders category toggles for pie/doughnut/polar-area charts. Categories use the first\ndataset's colors and values; a toggle affects that category in every ring. Other chart types\nretain dataset legends. `auto` (the default) resolves to `datum` on pie/doughnut/polar-area\ncharts -- where a single-dataset legend would otherwise enumerate one entry for the whole\ndataset instead of one per visible slice -- and to `dataset` everywhere else. `dataset` always\nforces the dataset legend, even on a slice chart. Both non-`auto` modes use the generated\naccessible-data sampling budget.\n\nAttribute: `legend-mode`","type":"LyraChartLegendMode","default":"'auto'"},{"name":"legendPosition","description":"Legend placement. `auto` uses a right legend above 480px and a bottom legend below it.\n\nAttribute: `legend-position`","type":"LyraChartLegendPosition","default":"'top'"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"max","description":"Maximum value-axis bound. Non-finite values are ignored.\n\nAttribute: `max`","type":"number | null","default":"null"},{"name":"min","description":"Minimum value-axis bound. Non-finite values are ignored.\n\nAttribute: `min`","type":"number | null","default":"null"},{"name":"plugins","description":"Chart.js plugins attached to this chart instance. Valid plugins retain their opaque identity.\n\nAttribute: `plugins`","type":"readonly LyraChartPlugin[]","default":"[]"},{"name":"scaleType","description":"Scale type for the **value** axis (the categorical axis is unaffected). `'logarithmic'` plots\na dataset spanning several orders of magnitude honestly, where a linear axis collapses\neverything below the maximum into the baseline. Inherited by `lr-line-chart`,\n`lr-scatter-chart` and `lr-bar-chart`.\n\nA logarithmic axis cannot represent zero or negative values (`log(0)` is `-Infinity`), so\n`beginAtZero` is not forwarded in that mode -- Chart.js would otherwise be handed a bound it\ncannot place. Non-positive data points are dropped by Chart.js's own log scale.\n\nAttribute: `scale-type`","type":"LyraChartScaleType","default":"'linear'"},{"name":"showDataTable","description":"Makes the generated data table visible; it remains screen-reader available when false.\n\nAttribute: `show-data-table`","type":"boolean","default":"false"},{"name":"stackTotals","description":"When the chart is `stacked` (bar/line only), draws the per-category stack\ntotal above each stack, via the same optional `chartjs-plugin-datalabels`\npeer as `data-labels`. Null/undefined points are skipped; a category whose\nevery value is null shows no total. The generated accessible data table\nreceives the same formatted total column (one per value axis). Unset (the\ndefault) draws and adds nothing.\n\nAttribute: `stack-totals`","type":"boolean","default":"false"},{"name":"stacked","description":"Stacks the `x`/`y`(/`y2`) scale entries `buildScales()` returns; only meaningful for `bar` and `line` types.\n\nAttribute: `stacked`","type":"boolean","default":"false"},{"name":"stackedAxes","description":"Per-value-axis override of `stacked`, keyed by `'y'`/`'y2'`. An axis absent from this record\n-- including every axis when the whole property is unset -- falls back to the chart-wide\n`stacked` value, which is what keeps a chart that never sets this byte-identical to before.\nLets a `stacked` bar series on the primary axis sit next to an unstacked overlay series on\n`y2` (via `LyraChartSeries.axis: 'y2'`): set `stackedAxes` to `{ y2: false }` alongside\n`stacked`, or spell out both axes explicitly. The shared categorical axis (`x` for a vertical\nbar/line, or `y` when `indexAxis` is `'y'`) has no independent entry of its own -- it always\nmirrors the resolved `'y'` value, matching Chart.js's own paired index/value-scale stacking\ncontract. Only meaningful for `bar`/`line` types, matching `stacked` itself.","type":"Partial<Record<'y' | 'y2', boolean>> | undefined"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"tooltipFooterFormatter","description":"Tooltip footer formatter -- e.g. a category's stack total under the items. Receives every\nitem the hovered tooltip covers, in the same shape as `tooltipTitleFormatter`. Unset (the\ndefault) leaves Chart.js's own default (no footer).","type":"LyraChartTooltipGroupFormatter | undefined"},{"name":"tooltipTitleFormatter","description":"Tooltip title formatter -- e.g. a scatter point's own name. Receives every item the hovered\ntooltip covers, each in `formatter`'s `'tooltip'`-surface context shape. Unset (the default)\nleaves Chart.js's own default title (the shared category label) in place.","type":"LyraChartTooltipGroupFormatter | undefined"},{"name":"type","description":"Attribute: `type`","type":"LyraChartType","default":"'polarArea'"},{"name":"valueFormatter","description":"Formats numeric (value-axis) ticks, tooltip values, legend values, and generated accessible\ntable cells from one callback.\nHorizontal scalar tooltips use parsed x, including a raw config indexAxis override;\nstructured points retain their y-value contract. The context-object formatter shares this rule.\nNever runs against the categorical x-axis's own labels (line/bar's `labels` strings) —\nChart.js's category scale passes the tick index to `ticks.callback`, not the label text,\nso formatting it would corrupt the axis.","type":"LyraChartValueFormatter | undefined"},{"name":"withoutAnimation","description":"Disables Chart.js animation.\n\nAttribute: `without-animation`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"withoutLegend","description":"Hides the legend.\n\nAttribute: `without-legend`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"withoutTooltip","description":"Hides Chart.js tooltips.\n\nAttribute: `without-tooltip`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"xLabel","description":"Attribute: `x-label`","type":"string | null","default":"null"},{"name":"y2Label","description":"Attribute: `y2-label`","type":"string","default":"''"},{"name":"yLabel","description":"Attribute: `y-label`","type":"string | null","default":"null"},{"name":"zoom","description":"Attribute: `zoom`","type":"boolean","default":"false"}],"events":[{"name":"lr-before-datum-visibility-change","description":"Cancelable category visibility proposal in datum legend mode. `detail: { index: number, visible: boolean, hiddenDatums: readonly number[] }`. Source category indexes apply to every dataset/ring. The complete detail is frozen.","type":"CustomEvent<LyraChartDatumVisibilityChangeDetail>"},{"name":"lr-before-legend-visibility-change","description":"Cancelable proposal emitted before a DOM legend toggle changes state. `detail` contains the target `datasetIndex`, its proposed `visible` value, and the complete canonical proposed `hiddenDatasets` snapshot.","type":"CustomEvent<LyraChartLegendVisibilityChangeDetail>"},{"name":"lr-datum-activate","description":"Family-normalized activation event. Its detail adds `kind` (`bar`, `point`, `segment`, or `slice`) to the `lr-point-click` detail.","type":"CustomEvent<\n    LyraChartDatumActivateDetail<LyraCoreChartDatumKind>\n  >"},{"name":"lr-datum-visibility-change","description":"Emitted after an accepted category toggle commits the same frozen detail. Programmatic `hiddenDatums` assignments are silent.","type":"CustomEvent<LyraChartDatumVisibilityChangeDetail>"},{"name":"lr-legend-visibility-change","description":"Emitted after an accepted DOM legend toggle commits the same detail. Programmatic `hiddenDatasets` changes reconcile without either event.","type":"CustomEvent<LyraChartLegendVisibilityChangeDetail>"},{"name":"lr-point-click","description":"Fired when pointer input lands on a data point/segment, when a generated data-table value is activated, or when Enter/Space activates the keyboard-current canvas datum. `detail: { datasetIndex: number, index: number, label: string | undefined, value: unknown }`. For scatter/bubble data, `label` prefers the per-point label and `value` is the complete typed `LyraChartPoint` (`x`, `y`, optional `r`, optional `label`).","type":"CustomEvent<{\n    datasetIndex: number;\n    index: number;\n    label: string | undefined;\n    value: unknown;\n  }>"},{"name":"lr-zoom","description":"`detail: { zoomed }`.","type":"CustomEvent<{ zoomed: boolean }>"}]}},{"name":"lr-policy-summary","description":"`<lr-policy-summary>` — a read-only list of guardrail, permission, privacy, and tool-policy\ndecisions, each carrying an `allow` / `deny` / `needs-review` state and an always-visible,\naccessible explanation of why that decision was made -- never conveyed by color alone.\n\nComposes `<lr-badge>` for the compact per-decision state indicator and renders the historical\nexplanation as ordinary text, so mounting an existing policy record does not announce it as a\nfresh alert or status change. `<lr-details>` renders a decision's optional richer `detail` (matched rule text,\npolicy id, cited evidence) behind progressive disclosure, collapsed by default, instead of\nalways showing it alongside the shorter `explanation`.\n\n`decisions` is controlled and never mutated by this component -- pass a new array (e.g. as a\nguardrail pipeline resolves) to update it. This is a summary surface, not an approval gate:\nthere is no per-decision action here, and a decision's `state` is fixed data, not something a\nviewer can change from this component.\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.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| `base` | The root wrapper, only rendered while `decisions` is non-empty. |\n| `category` | The decision's localized category text. |\n| `count` | One state's localized count text; carries `data-state`. |\n| `decision` | One decision row (`role=\"listitem\"`); carries `data-state` and `data-category`. |\n| `decision-header` | The row's category/label/state-badge line. |\n| `detail` | The `<lr-details>` progressive-disclosure panel for `detail`, only rendered when a decision defines one. |\n| `empty` | The `<lr-empty>` shown when `decisions` is empty. |\n| `explanation` | The always-visible historical `explanation` text. |\n| `label` | The decision's `label` text. |\n| `list` | The `role=\"list\"` wrapper around every decision row. Its purpose-specific name is the localized `policySummaryLabel`; a host `aria-label` names the host and is not cloned onto this nested semantic owner. |\n| `state-badge` | The resolved `<lr-badge>` state indicator. |\n| `summary` | The always-visible allow/deny/needs-review count row. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-policy-summary-count-allow-color` (default: `var(--lr-color-success)`) — Text color of the `allow` count.\n- `--lr-policy-summary-count-deny-color` (default: `var(--lr-color-danger)`) — Text color of the `deny` count.\n- `--lr-policy-summary-count-needs-review-color` (default: `var(--lr-color-warning)`) — Text color of the `needs-review` count. Restyling a state count otherwise requires overriding the library-wide status tokens, since `::part(count)[data-state]` is invalid CSS.","attributes":[{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"js":{"properties":[{"name":"decisions","description":"The decisions to render, in the given order. Controlled and never mutated by this component\n-- pass a new array to update it. Empty/blank ids are omitted, duplicates normalize\nfirst-wins before counts/rendering, and a decision with an out-of-union `category`/`state`\nis dropped rather than rendered.","type":"readonly PolicyDecision[]","default":"[]"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}]}},{"name":"lr-poll-status","description":"`<lr-poll-status>` — a \"next scheduled refresh\" countdown with a built-in pause control: a\nticking `M:SS` display counting down to the next scheduled action, a \"Refreshing…\" state at\nzero, a localized inactive state while `active` is false, a \"Paused\" state\nwhile `paused` (instead of freezing on a stale value), and a pause/resume\ntoggle. First-party invention (no Web Awesome equivalent); the\nclosest existing component, `lr-stream-status`, is scoped to transport/connection-health\nphases, a different concern from a scheduled-interval countdown -- this mirrors its internal\n`<lr-live-region>` composition for accessible phase-transition announcements.\n\nLong translated labels wrap within the allocated inline size while the pause/resume\naction retains its minimum target size.\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 root wrapper. |\n| `countdown` | The localized `M:SS` text, or the refreshing, paused, or inactive state. |\n| `indicator` | The pulsing status dot. |\n| `pause-button` | The built-in pause/resume toggle. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-poll-status-due-bg` (default: `var(--lr-color-success)`) — Background of `indicator` while `data-due` is set, without repainting every other component that reuses the shared success token.\n- `--lr-poll-status-pause-active-bg` — `pause-button` pressed background; defaults to the former brand-quiet active mix.\n- `--lr-poll-status-pause-active-color` (default: `var(--lr-color-brand)`) — `pause-button` pressed foreground.\n- `--lr-poll-status-pause-hover-bg` (default: `var(--lr-color-brand-quiet)`) — `pause-button` hover background.\n- `--lr-poll-status-pause-hover-color` (default: `var(--lr-color-brand)`) — `pause-button` hover foreground.","attributes":[{"name":"active","description":"Whether the poll cycle is running at all. While false, the component\nclears due/countdown semantics and disables its pause action.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"next-in-ms","description":"Milliseconds until the next scheduled action, as of whenever this was last set -- setting it\n(re)starts the countdown from \"now.\" Unset (the default) shows no countdown.\n\nType: `number | undefined`"},{"name":"paused","description":"User-toggled pause -- while `true`, the countdown display freezes and `lr-poll-due` never\nfires. `false` (the default).\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"js":{"properties":[{"name":"active","description":"Whether the poll cycle is running at all. While false, the component\nclears due/countdown semantics and disables its pause action.\n\nAttribute: `active`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"nextInMs","description":"Milliseconds until the next scheduled action, as of whenever this was last set -- setting it\n(re)starts the countdown from \"now.\" Unset (the default) shows no countdown.\n\nAttribute: `next-in-ms`","type":"number | undefined"},{"name":"paused","description":"User-toggled pause -- while `true`, the countdown display freezes and `lr-poll-due` never\nfires. `false` (the default).\n\nAttribute: `paused`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-pause-change","description":"Fired when `paused` changes via the built-in button. `detail: { paused: boolean }`.","type":"CustomEvent<{ readonly paused: boolean }>"},{"name":"lr-poll-due","description":"Fired once when the countdown reaches zero (not fired while `paused`).","type":"CustomEvent<null>"}]}},{"name":"lr-popover","description":"`<lr-popover>` — a light-dismiss floating surface, click-triggered by default.\n\n`trigger` selects which interaction opens it: `click` (the shipped default), `hover`, `focus`,\nor `manual`. The two transient modes open after `showDelay`, close after `hideDelay` once the\ninteraction ends, deliberately never move focus into the surface, and keep it open while focus\nrests anywhere inside it. A click on the trigger while a transient surface is open *pins* it --\nthe pointer may then leave without closing it -- and the next click releases the pin. Set\n`hover-bridge` to have the positioner clip an invisible quad across the `distance` gap so a\npointer travelling from the trigger to the popup never leaves both at once.\n\nInteraction/ARIA ownership is resolved separately from positioning. A slotted trigger wins and\nreceives the click listener plus `aria-haspopup`, `aria-expanded`, and `aria-controls`; without\none, a live HTML element resolved by `for` owns the same contract. A wrapper/custom trigger's\nreal composed focus target receives the same owned semantics and is the focus-return target. A\ndirect `.anchor` is positioning-only. `showAt()`'s virtual anchor wins positioning and\ndeliberately has no DOM interaction/ARIA owner while active.\nThe component supplies the real shadow popup to the shared relationship controller. Current\nbrowsers expose its nearest public shadow host to a light-DOM trigger, keeping the relationship\nresolvable without pretending a private idref crosses the boundary.\nLive `popupRole`, host-id, target-id, and target-identity changes keep those relationships\nsynchronized. Losing the sole live positioning anchor force-closes the surface; if a slotted or\n`for` fallback remains, the popover repositions to it and stays open. A deliberate `showAt()`\nvirtual anchor remains open independently of DOM-anchor removal.\n\nLifecycle: `show()` emits `lr-show` (cancelable) and then `lr-after-show` once the popup's\ntransition has finished; `hide()` emits `lr-hide` (cancelable) then `lr-after-hide`. Assigning\n`open` runs the same sequence, so the property, the reflected attribute and the two methods can\nnever disagree. Markup that renders open from the start emits nothing.\nMotion resolves through `popover.show`/`popover.hide` in the public animation registry.\n\nPositioning resolves `showAt()` virtual anchor, direct `.anchor`, `for`, then the interaction\nowner, in that order. Thus `anchor` can position against an element that never receives click or\nARIA state, while `for` owns both positioning and interaction only when no trigger is slotted.\nActivating an enabled, non-inert light-DOM descendant with `data-popover=\"close\"` requests this\nclosest owning popover to close. Nested popovers consume their own close actions.\n\nOpen popovers, dropdowns and tooltips reposition when their effective host or inherited text direction changes, preserving open state and lifecycle events.\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) | Popover content. An enabled, non-inert descendant with `data-popover=\"close\"` closes its nearest owning popover when activated. |\n| `trigger` | The highest-priority interaction/ARIA owner; toggles the popover even when positioning uses `anchor` or `for`. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `arrow` | The arrow element, rendered only when `arrow` is set. Its part name also carries the resolved side (`arrow-top`, `arrow-bottom`, `arrow-left`, `arrow-right`), so `::part(arrow arrow-top)` can style one side — state after `::part()` never matches. |\n| `body` | Mapped alias on the content wrapper. |\n| `content` | The content wrapper; also carries the `body` alias. |\n| `dialog` | Mapped alias on the positioned popup. |\n| `hover-bridge` | The invisible quad bridging the trigger and the popup, rendered only while a `hover` popover with `hover-bridge` set is open. |\n| `popup` | The positioned popup; also carries `dialog` and `popup__popup` aliases. |\n| `popup__arrow` | Exported mapped alias on the arrow. |\n| `popup__popup` | Exported popup alias on the positioned popup. |\n| `trigger` | The trigger wrapper. |\n\n---\n\n**CSS Custom Properties**\n\n- `--arrow-size` (default: `var(--lr-overlay-arrow-size,var(--lr-size-0-375rem))`) — Half-width of the arrow square.\n- `--hide-duration` (default: `var(--lr-duration-fast)`) — Closing transition duration.\n- `--lr-overlay-arrow-size` — Retained Lyra fallback for `--arrow-size`.\n- `--lr-overlay-border` (default: `var(--lr-color-border)`) — Shared floating-surface edge colour, on the popup and on the arrow's two outward-facing edges.\n- `--lr-overlay-max-inline-size` — Retained Lyra fallback for `--max-width`.\n- `--lr-overlay-radius` (default: `var(--lr-radius)`) — Shared floating-surface corner radius. The arrow is deliberately excluded: its corners are already cut by its clip path.\n- `--lr-overlay-shadow-anchored` (default: `var(--lr-shadow-m)`) — Elevation of an anchored, positioner-placed overlay. A separate tier from `--lr-overlay-shadow-modal`, so raising popups never raises dialogs.\n- `--lr-overlay-surface` (default: `var(--lr-color-surface-overlay)`) — Shared floating-surface fill, read by the popup and by its arrow. One declaration on any ancestor retints every overlay in that subtree without touching the page, card and control surfaces behind them.\n- `--lr-positioning-strategy` — Cascading `absolute`/`fixed` override for {@link positioningStrategy}, read from computed style when the popup is (re)positioned. Set it once on `:root`, a theme, or one clipping ancestor to change every unset overlay beneath it without authoring `positioning-strategy`/`hoist` on each instance; an explicit value on the instance always wins over it.\n- `--max-width` (default: `var(--lr-overlay-max-inline-size,var(--lr-size-20rem))`) — Maximum inline size of the popup.\n- `--show-duration` (default: `var(--lr-duration-fast)`) — Opening transition duration.","attributes":[{"name":"aria-label","description":"Accessible name for the semantic popup. An authored host `aria-label` wins by presence,\nincluding an explicitly empty value, before this property or the localized role fallback.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"arrow","description":"Render an arrow that points at the anchor. Defaults on for the mapped surface.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"arrow-padding","description":"Keeps the arrow this far from the popup's corners, in pixels.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"arrow-placement","description":"Where the arrow sits along the popup's edge. `anchor` tracks the anchor's centre.\n\nType: `LyraArrowPlacement`  \nDefault: `'anchor'`","value":{"type":["'anchor'","'start'","'end'","'center'"]}},{"name":"disabled","description":"Prevents opening the popover -- pointer, keyboard, and programmatic `show()`/`open = true`\nare all refused while set. Becoming disabled also closes an already-open popover; initial\n`disabled` plus `open` markup/property state normalizes closed in either order. Mirrors\n`<lr-tooltip>`'s and `<lr-dropdown>`'s own `disabled`.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"distance","description":"Anchor-offset distance (px) passed to Floating UI's `offset()` middleware. Can legitimately\nbe negative (overlaps the popup with the trigger); NaN/non-finite falls back to the default.\n\nType: `number`  \nDefault: `8`","value":{"type":["number"]}},{"name":"for","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"hide-delay","description":"Delay (ms) between the interaction ending and the popover closing again -- the grace period\nthat lets a pointer cross the gap to the popup. Normalized like showDelay.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"hover-bridge","description":"Renders an invisible `[part='hover-bridge']` quad spanning the `distance` gap between the\ntrigger and the popup while a `hover` popover is open, so a pointer travelling between them\nnever leaves both at once and the popover does not close underneath it. Off by default: it is\nonly meaningful for `trigger=\"hover\"`, and a page that keeps `distance` at `0` does not need\nit.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"open","description":"Whether the popover is open. Assigning it runs the full `lr-show`/`lr-hide` lifecycle.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"placement","description":"Type: `Placement`  \nDefault: `'top'`","value":{"type":["'top'","'top-start'","'top-end'","'right'","'right-start'","'right-end'","'bottom'","'bottom-start'","'bottom-end'","'left'","'left-start'","'left-end'"]}},{"name":"popup-role","description":"Semantic role used by the popup. `dialog` (default) for a contextual surface, `menu` for an\naction menu, or `none` to render no role and no generated name so the slotted content owns\nits own semantics -- see `LyraPopupRole` for why a navigation disclosure needs that.\nUnsupported attribute values and untyped property writes normalize to `dialog` before the\nrole or trigger ARIA is rendered.\n\nType: `LyraPopupRole`  \nDefault: `'dialog'`","value":{"type":["'dialog'","'menu'","'none'"]}},{"name":"positioning-strategy","description":"CSS positioning scheme the popup is laid out with -- the one property `<lr-popover>`,\n`<lr-dropdown>` and `<lr-select>` all spell the same way. `fixed` normally positions against\nthe viewport, so it escapes most clipping ancestors; `absolute` positions against the popup's\ncontaining block and scrolls with it. Each component keeps its own mirrored default, so\nsetting nothing on the instance and on every ancestor never changes what it already rendered;\nan unsupported authored value resolves to that same default. Changes apply live while open.\nThis property reports only the instance's own authored value (or the mirrored default); the\npopup is actually placed with the `--lr-positioning-strategy` cascading custom property\nhonored ahead of that default when the instance itself sets nothing -- see that `@cssprop`.\n\nType: `PlaceStrategy`  \nDefault: `'fixed'`","value":{"type":["'absolute'","'fixed'"]}},{"name":"show-delay","description":"Delay (ms) between a `hover`/`focus` interaction and the popover opening. NaN, negative and\noversized values all normalize through `finiteDuration`.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"skidding","description":"Offset along the anchor's edge, in pixels — Floating UI's cross-axis offset.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"trigger","description":"Space-separated list of the interactions that open the popover -- see\nLyraPopoverTrigger for the keywords, which are exactly `<lr-tooltip>`'s. Unrecognized\ntokens are dropped and a list left with none resolves back to `'click'`, so the property always\nreads back as a canonical list.\n\nType: `string`  \nDefault: `'click'`","value":{"type":["string"]}},{"name":"without-arrow","description":"Positive mapped spelling for suppressing the default arrow.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"","description":"Popover content. An enabled, non-inert descendant with `data-popover=\"close\"` closes its nearest owning popover when activated."},{"name":"trigger","description":"The highest-priority interaction/ARIA owner; toggles the popover even when positioning uses `anchor` or `for`."}],"js":{"properties":[{"name":"accessibleLabel","description":"Accessible name for the semantic popup. An authored host `aria-label` wins by presence,\nincluding an explicitly empty value, before this property or the localized role fallback.\n\nAttribute: `aria-label`","type":"string","default":"''"},{"name":"anchor","description":"Positioning-only element anchor. Takes precedence over `for` and the interaction owner, but\nnever receives click listeners or generated ARIA.","type":"Element | null","default":"null"},{"name":"arrow","description":"Render an arrow that points at the anchor. Defaults on for the mapped surface.\n\nAttribute: `arrow`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"arrowPadding","description":"Keeps the arrow this far from the popup's corners, in pixels.\n\nAttribute: `arrow-padding`","type":"number","default":"0"},{"name":"arrowPlacement","description":"Where the arrow sits along the popup's edge. `anchor` tracks the anchor's centre.\n\nAttribute: `arrow-placement`","type":"LyraArrowPlacement","default":"'anchor'"},{"name":"disabled","description":"Prevents opening the popover -- pointer, keyboard, and programmatic `show()`/`open = true`\nare all refused while set. Becoming disabled also closes an already-open popover; initial\n`disabled` plus `open` markup/property state normalizes closed in either order. Mirrors\n`<lr-tooltip>`'s and `<lr-dropdown>`'s own `disabled`.\n\nAttribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"distance","description":"Anchor-offset distance (px) passed to Floating UI's `offset()` middleware. Can legitimately\nbe negative (overlaps the popup with the trigger); NaN/non-finite falls back to the default.\n\nAttribute: `distance`","type":"number","default":"8"},{"name":"for","description":"Attribute: `for`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"hideDelay","description":"Delay (ms) between the interaction ending and the popover closing again -- the grace period\nthat lets a pointer cross the gap to the popup. Normalized like showDelay.\n\nAttribute: `hide-delay`","type":"number","default":"0"},{"name":"hoverBridge","description":"Renders an invisible `[part='hover-bridge']` quad spanning the `distance` gap between the\ntrigger and the popup while a `hover` popover is open, so a pointer travelling between them\nnever leaves both at once and the popover does not close underneath it. Off by default: it is\nonly meaningful for `trigger=\"hover\"`, and a page that keeps `distance` at `0` does not need\nit.\n\nAttribute: `hover-bridge`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"open","description":"Whether the popover is open. Assigning it runs the full `lr-show`/`lr-hide` lifecycle.\n\nAttribute: `open`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"placement","description":"Attribute: `placement`  \nReflected to its attribute.","type":"Placement","default":"'top'"},{"name":"popupRole","description":"Semantic role used by the popup. `dialog` (default) for a contextual surface, `menu` for an\naction menu, or `none` to render no role and no generated name so the slotted content owns\nits own semantics -- see `LyraPopupRole` for why a navigation disclosure needs that.\nUnsupported attribute values and untyped property writes normalize to `dialog` before the\nrole or trigger ARIA is rendered.\n\nAttribute: `popup-role`","type":"LyraPopupRole","default":"'dialog'"},{"name":"positioningStrategy","description":"CSS positioning scheme the popup is laid out with -- the one property `<lr-popover>`,\n`<lr-dropdown>` and `<lr-select>` all spell the same way. `fixed` normally positions against\nthe viewport, so it escapes most clipping ancestors; `absolute` positions against the popup's\ncontaining block and scrolls with it. Each component keeps its own mirrored default, so\nsetting nothing on the instance and on every ancestor never changes what it already rendered;\nan unsupported authored value resolves to that same default. Changes apply live while open.\nThis property reports only the instance's own authored value (or the mirrored default); the\npopup is actually placed with the `--lr-positioning-strategy` cascading custom property\nhonored ahead of that default when the instance itself sets nothing -- see that `@cssprop`.\n\nAttribute: `positioning-strategy`  \nReflected to its attribute.","type":"PlaceStrategy","default":"'fixed'"},{"name":"showDelay","description":"Delay (ms) between a `hover`/`focus` interaction and the popover opening. NaN, negative and\noversized values all normalize through `finiteDuration`.\n\nAttribute: `show-delay`","type":"number","default":"0"},{"name":"skidding","description":"Offset along the anchor's edge, in pixels — Floating UI's cross-axis offset.\n\nAttribute: `skidding`","type":"number","default":"0"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"trigger","description":"Space-separated list of the interactions that open the popover -- see\nLyraPopoverTrigger for the keywords, which are exactly `<lr-tooltip>`'s. Unrecognized\ntokens are dropped and a list left with none resolves back to `'click'`, so the property always\nreads back as a canonical list.\n\nAttribute: `trigger`","type":"string","default":"'click'"},{"name":"withoutArrow","description":"Positive mapped spelling for suppressing the default arrow.\n\nAttribute: `without-arrow`  \nReflected to its attribute.","type":"boolean","default":"false"}],"events":[{"name":"lr-after-hide","description":"The popover is closed and its transition has finished.","type":"CustomEvent<null>"},{"name":"lr-after-show","description":"The popover is open and its transition has finished.","type":"CustomEvent<null>"},{"name":"lr-hide","description":"The popover is about to close, for every dismissal path (Escape, light dismiss, `hide()`, `open = false`). Cancelable — `preventDefault()` keeps it open.","type":"CustomEvent<null>"},{"name":"lr-show","description":"The popover is about to open. Cancelable — `preventDefault()` keeps it closed.","type":"CustomEvent<null>"}]}},{"name":"lr-popup","description":"`<lr-popup>` — the low-level anchored-positioning primitive.\n\nIt positions its `popup` slot against an anchor and keeps the two aligned through scroll,\nresize and layout change. That is *all* it does: no dismiss behaviour, no focus management, no\nARIA relationship, no trigger semantics. Those are policy, and policy belongs to the component\nbuilt on top — `<lr-popover>`, `<lr-dropdown>` and `<lr-tooltip>` each layer their own.\n\nReach for it when you need a floating surface the library does not already ship: an anchored\ninline editor, a colour-picker panel, a custom autocomplete list. If you find yourself adding\nlight dismiss and focus return on top, use `<lr-popover>` instead.\n\nThe v8 defaults match the mapped primitive: `placement=\"top\"`, `strategy=\"absolute\"`, zero\ndistance/padding, and opt-in flip/shift. `auto-size` narrows an always-on measurement rather\nthan switching one on: this element publishes the available space as\n `--lr-positioner-available-inline-size`/`--lr-positioner-available-block-size` and caps the\npopup with them, so `auto-size` re-measures the named axes against `auto-size-boundary` and\n`auto-size-padding` instead of the shared `padding`.\n\n---\n\n**Component metadata**\n\n- Status: `stable`\n- Since: `8.0.0`\n- Rationale: This tag entered Lyra as a stable public API with documented behavior, accessibility, and cross-browser support.\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 floating content. |\n| `anchor` | The fallback element to position against when no higher-priority source resolves. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `anchor` | The anchor slot wrapper. |\n| `arrow` | The arrow element, rendered only when `arrow` is set. Its part name also carries the resolved side (`arrow-top`, `arrow-bottom`, `arrow-left`, `arrow-right`), matching `<lr-popover>` and `<lr-tooltip>`. |\n| `hover-bridge` | The invisible quad spanning the `distance` gap between anchor and popup, rendered only when `hover-bridge` is set. |\n| `popup` | The positioned floating surface. Carries the resolved side (`top`, `bottom`, `left`, `right`) in its part name, so `::part(popup bottom)` can style one side — state after `::part()` never matches. |\n\n---\n\n**CSS Custom Properties**\n\n- `--arrow-color` (default: `var(--lr-color-surface-raised)`) — Arrow fill.\n- `--arrow-size` (default: `var(--lr-popup-arrow-size,var(--lr-size-0-375rem))`) — Half-width of the arrow square. `--lr-popup-arrow-size` remains a compatibility alias.\n- `--auto-size-available-height` — Read-only available block size.\n- `--auto-size-available-width` — Read-only available inline size.\n- `--hide-duration` (default: `var(--lr-duration-fast)`) — Deactivation transition duration.\n- `--lr-popup-arrow-size` — Retained Lyra fallback for `--arrow-size`.\n- `--popup-border-width` (default: `var(--lr-border-width-thin)`) — Popup/arrow border width.\n- `--show-duration` (default: `var(--lr-duration-fast)`) — Activation transition duration.","attributes":[{"name":"active","description":"Requests positioning and paint. The surface remains hidden until a live anchor is placed.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"anchor","description":"Element, same-root id string, or Floating UI-compatible virtual element to position against.\nTakes precedence over `for` and the anchor slot; `virtualAnchor` remains the highest-priority\nLyra compatibility path. A disconnected element or dangling id falls through.\n\nType: `LyraPopupAnchor | null`  \nDefault: `null`"},{"name":"arrow","description":"Render an arrow that points at the anchor.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"arrow-padding","description":"Keeps the arrow this far from the popup's corners, in pixels.\n\nType: `number`  \nDefault: `10`","value":{"type":["number"]}},{"name":"arrow-placement","description":"Where the arrow sits along the popup's edge. `anchor` tracks the anchor's centre.\n\nType: `LyraArrowPlacement`  \nDefault: `'anchor'`","value":{"type":["'anchor'","'start'","'end'","'center'"]}},{"name":"auto-size","description":"Re-measures the available space on the named axes against `auto-size-boundary` and\n`auto-size-padding` rather than the shared `padding`. The popup is capped by that measurement\neither way — this narrows or widens the cap, it does not introduce one.\n\nType: `PlaceAutoSize | null`  \nDefault: `null`","value":{"type":["'horizontal'","'vertical'","'both'"]}},{"name":"auto-size-padding","description":"Padding kept clear inside the auto-size boundary, in pixels.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"boundary","description":"Shared clipping boundary. `viewport` ignores clipping ancestors; `scroll` uses them. The\nseparate flip/shift/auto-size boundaries below override this value one middleware at a time.\n\nType: `LyraPopupBoundary`  \nDefault: `'viewport'`","value":{"type":["'viewport'","'scroll'"]}},{"name":"distance","description":"Distance from the anchor along the placement axis, in pixels.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"flip","description":"Flip to the opposite side when the preferred one does not fit.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"flip-fallback-placements","description":"Space-delimited placements `flip` tries, in order, instead of just the opposite side —\n`flip-fallback-placements=\"right bottom\"`. Unrecognised entries are ignored.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"flip-fallback-strategy","description":"What `flip` settles on when none of the candidate placements fit: `best-fit` takes the\nleast-overflowing one, `initial` keeps `placement` as written. `initial-placement` remains a\ncompatibility alias.\n\nType: `LyraPopupFlipFallbackStrategy`  \nDefault: `'best-fit'`","value":{"type":["'best-fit'","'initial'","'initial-placement'"]}},{"name":"flip-padding","description":"Padding kept clear inside the flip boundary, in pixels.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"for","description":"Id of an element elsewhere in the same root to anchor against, instead of the `anchor` slot.\nResolved in this element's own root, so it works inside a shadow tree where an idref could not\ncross the boundary.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"hover-bridge","description":"Renders an invisible quad across the `distance` gap between anchor and popup, so a pointer\ntravelling between them never leaves both at once. Purely geometric — this element owns no\nhover policy of its own; the component built on top reads the hover.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"padding","description":"Viewport padding kept clear by `shift` and by the available-size measurement.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"placement","description":"Preferred placement. `flip`/`shift` may override it; the result is reported by `lr-reposition`.\n\nType: `Placement`  \nDefault: `'top'`","value":{"type":["'top'","'top-start'","'top-end'","'right'","'right-start'","'right-end'","'bottom'","'bottom-start'","'bottom-end'","'left'","'left-start'","'left-end'"]}},{"name":"shift","description":"Shift along the anchor's edge to stay within the viewport.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"shift-padding","description":"Padding kept clear inside the shift boundary, in pixels.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"skidding","description":"Offset along the anchor's edge, in pixels.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"strategy","description":"CSS positioning scheme. `fixed` escapes every ancestor's\ntransform/filter/containment context; `absolute` positions against the nearest positioned\nancestor, so the popup scrolls away with the content it belongs to. Defaults to `absolute`.\n\nType: `PlaceStrategy`  \nDefault: `'absolute'`","value":{"type":["'absolute'","'fixed'"]}},{"name":"sync","description":"Copies the anchor's inline size, block size, or both onto the popup.\n\nType: `PlaceSync | null`  \nDefault: `null`","value":{"type":["'width'","'height'","'both'"]}}],"slots":[{"name":"","description":"The floating content."},{"name":"anchor","description":"The fallback element to position against when no higher-priority source resolves."}],"js":{"properties":[{"name":"active","description":"Requests positioning and paint. The surface remains hidden until a live anchor is placed.\n\nAttribute: `active`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"anchor","description":"Element, same-root id string, or Floating UI-compatible virtual element to position against.\nTakes precedence over `for` and the anchor slot; `virtualAnchor` remains the highest-priority\nLyra compatibility path. A disconnected element or dangling id falls through.\n\nAttribute: `anchor`","type":"LyraPopupAnchor | null","default":"null"},{"name":"arrow","description":"Render an arrow that points at the anchor.\n\nAttribute: `arrow`","type":"boolean","default":"false"},{"name":"arrowPadding","description":"Keeps the arrow this far from the popup's corners, in pixels.\n\nAttribute: `arrow-padding`","type":"number","default":"10"},{"name":"arrowPlacement","description":"Where the arrow sits along the popup's edge. `anchor` tracks the anchor's centre.\n\nAttribute: `arrow-placement`","type":"LyraArrowPlacement","default":"'anchor'"},{"name":"autoSize","description":"Re-measures the available space on the named axes against `auto-size-boundary` and\n`auto-size-padding` rather than the shared `padding`. The popup is capped by that measurement\neither way — this narrows or widens the cap, it does not introduce one.\n\nAttribute: `auto-size`","type":"PlaceAutoSize | null","default":"null"},{"name":"autoSizeBoundary","description":"Element(s) the `auto-size` measurement uses, instead of the popup's clipping ancestors.","type":"PlaceBoundary | null","default":"null"},{"name":"autoSizePadding","description":"Padding kept clear inside the auto-size boundary, in pixels.\n\nAttribute: `auto-size-padding`","type":"number","default":"0"},{"name":"boundary","description":"Shared clipping boundary. `viewport` ignores clipping ancestors; `scroll` uses them. The\nseparate flip/shift/auto-size boundaries below override this value one middleware at a time.\n\nAttribute: `boundary`","type":"LyraPopupBoundary","default":"'viewport'"},{"name":"distance","description":"Distance from the anchor along the placement axis, in pixels.\n\nAttribute: `distance`","type":"number","default":"0"},{"name":"flip","description":"Flip to the opposite side when the preferred one does not fit.\n\nAttribute: `flip`","type":"boolean","default":"false"},{"name":"flipBoundary","description":"Element(s) `flip` measures overflow against, instead of the popup's clipping ancestors.","type":"PlaceBoundary | null","default":"null"},{"name":"flipFallbackPlacements","description":"Space-delimited placements `flip` tries, in order, instead of just the opposite side —\n`flip-fallback-placements=\"right bottom\"`. Unrecognised entries are ignored.\n\nAttribute: `flip-fallback-placements`","type":"string","default":"''"},{"name":"flipFallbackStrategy","description":"What `flip` settles on when none of the candidate placements fit: `best-fit` takes the\nleast-overflowing one, `initial` keeps `placement` as written. `initial-placement` remains a\ncompatibility alias.\n\nAttribute: `flip-fallback-strategy`","type":"LyraPopupFlipFallbackStrategy","default":"'best-fit'"},{"name":"flipPadding","description":"Padding kept clear inside the flip boundary, in pixels.\n\nAttribute: `flip-padding`","type":"number","default":"0"},{"name":"for","description":"Id of an element elsewhere in the same root to anchor against, instead of the `anchor` slot.\nResolved in this element's own root, so it works inside a shadow tree where an idref could not\ncross the boundary.\n\nAttribute: `for`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"hoverBridge","description":"Renders an invisible quad across the `distance` gap between anchor and popup, so a pointer\ntravelling between them never leaves both at once. Purely geometric — this element owns no\nhover policy of its own; the component built on top reads the hover.\n\nAttribute: `hover-bridge`","type":"boolean","default":"false"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"padding","description":"Viewport padding kept clear by `shift` and by the available-size measurement.\n\nAttribute: `padding`","type":"number","default":"0"},{"name":"placement","description":"Preferred placement. `flip`/`shift` may override it; the result is reported by `lr-reposition`.\n\nAttribute: `placement`  \nReflected to its attribute.","type":"Placement","default":"'top'"},{"name":"popup","description":"The positioned popup element, exposed for mapped popup integrations. Upstream public types\npermit assignment, so writes are accepted for source compatibility; the shadow-owned node\nremains authoritative because replacing it would detach positioning, parts, and animation.","type":"HTMLElement"},{"name":"shift","description":"Shift along the anchor's edge to stay within the viewport.\n\nAttribute: `shift`","type":"boolean","default":"false"},{"name":"shiftBoundary","description":"Element(s) `shift` measures overflow against, instead of the popup's clipping ancestors.","type":"PlaceBoundary | null","default":"null"},{"name":"shiftPadding","description":"Padding kept clear inside the shift boundary, in pixels.\n\nAttribute: `shift-padding`","type":"number","default":"0"},{"name":"skidding","description":"Offset along the anchor's edge, in pixels.\n\nAttribute: `skidding`","type":"number","default":"0"},{"name":"strategy","description":"CSS positioning scheme. `fixed` escapes every ancestor's\ntransform/filter/containment context; `absolute` positions against the nearest positioned\nancestor, so the popup scrolls away with the content it belongs to. Defaults to `absolute`.\n\nAttribute: `strategy`  \nReflected to its attribute.","type":"PlaceStrategy","default":"'absolute'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"sync","description":"Copies the anchor's inline size, block size, or both onto the popup.\n\nAttribute: `sync`","type":"PlaceSync | null","default":"null"},{"name":"virtualAnchor","description":"Highest-priority anchor. A plain rect defaults omitted dimensions to zero, clamps negative\ndimensions to zero, and ignores a rect containing any non-finite field.","type":"VirtualAnchor | { x: number; y: number; width?: number; height?: number } | null","default":"null"}],"events":[{"name":"lr-reposition","description":"Emitted after each recomputation. `detail: { placement }` carries the placement actually used, which `flip` may have changed.","type":"CustomEvent<{ placement: Placement }>"}]}},{"name":"lr-pptx-viewer","description":"Best-effort client-side PPTX viewer backed by `@aiden0z/pptx-renderer`.\nThe fidelity notice is intentionally always visible because animations,\nequations, embedded OLE objects, notes, and several advanced effects are\nnot represented by the renderer.\nRemote bytes and measured ZIP expansion are bounded before renderer-owned parsing begins; a\npeer that does not expose a complete, safely bounded ZIP-limits capability fails closed.\nLyra assigns no fragment ids to slides. A fragment anchor can resolve only an exact DOM `id`\nexposed in the optional renderer's currently mounted output; renderer-owned ids are not a\nstable Lyra navigation contract. Use `page`/`goToSlide()` or a text-quote anchor instead.\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| `anchor-live-region` | The aria-hidden, non-live shadow mirror of the latest anchor-jump message. |\n| `base` | The named viewer region with explicit `aria-busy`; its ordinary visually-hidden loading label is announced on later transitions through the shared document-level polite sink. |\n| `container` | The renderer-owned output container. |\n| `error` | Visible ordinary error text; transitions announce through the shared document-level assertive region. |\n| `header` | The optional presentation-name row. |\n| `name` | The presentation name. |\n| `nav` | Slide navigation controls. |\n| `next-button` | Next-slide button. |\n| `next-icon` | Next-slide icon; mirrors with effective RTL direction. |\n| `notice` | The persistent fidelity notice. |\n| `previous-button` | Previous-slide button. |\n| `previous-icon` | Previous-slide icon; mirrors with effective RTL direction. |\n| `slide-count` | Current slide indicator. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-pptx-viewer-max-height` (default: `none`) — Maximum block size of the scrollable renderer output container before it scrolls internally. Also settable via the `max-height` property.","attributes":[{"name":"active-highlight-id","description":"Id of the currently active highlight, or null when none is active.\n\nType: `string | null`  \nDefault: `null`"},{"name":"label","description":"Accessible-name override for the viewer region. Omitting it falls back to `name`, then a\nlocalized default; an explicit empty string clears it.\n\nType: `string | undefined`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max-height","description":"A CSS `max-height` that caps the scrollable renderer output container; invalid values are ignored.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"name","description":"Optional presentation name.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"page","description":"One-based current slide for page-addressed integrations; assignments navigate when ready.\n\nType: `number`  \nDefault: `1`","value":{"type":["number"]}},{"name":"src","description":"URL of the PPTX file.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"js":{"properties":[{"name":"activeHighlightId","description":"Id of the currently active highlight, or null when none is active.\n\nAttribute: `active-highlight-id`","type":"string | null","default":"null"},{"name":"anchor","description":"Anchor or highlight id to resolve and scroll into view.","type":"LyraAnchor | string | null","default":"null"},{"name":"anchorKinds","description":"Anchor kinds supported by this viewer instance.","type":"readonly LyraAnchorKind[]","default":"[]","read-only":true},{"name":"highlights","description":"Highlights rendered by the document target. Reassign after mutation.","type":"LyraHighlight[]","default":"[]"},{"name":"label","description":"Accessible-name override for the viewer region. Omitting it falls back to `name`, then a\nlocalized default; an explicit empty string clears it.\n\nAttribute: `label`","type":"string | undefined"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"maxHeight","description":"A CSS `max-height` that caps the scrollable renderer output container; invalid values are ignored.\n\nAttribute: `max-height`","type":"string","default":"''"},{"name":"name","description":"Optional presentation name.\n\nAttribute: `name`","type":"string","default":"''"},{"name":"page","description":"One-based current slide for page-addressed integrations; assignments navigate when ready.\n\nAttribute: `page`  \nReflected to its attribute.","type":"number","default":"1"},{"name":"pageViewerSnapshot","description":"Atomic readonly page/count/lifecycle state; `identity` changes for every load transaction.","type":"LyraPageViewerSnapshot","read-only":true},{"name":"src","description":"URL of the PPTX file.\n\nAttribute: `src`","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-anchor-result","description":"Fired after an `anchor` assignment or `scrollToAnchor()` call is applied. `detail: { found: boolean }`. Bubbling, composed, and non-cancelable.","type":"CustomEvent<AnchorResultDetail>"},{"name":"lr-load","description":"Fired after a presentation opens. `detail: { slideCount }`.","type":"CustomEvent<{ slideCount: number }>"},{"name":"lr-page-viewer-state-change","description":"Correlated page lifecycle state for `lr-page-rail` and other page-addressed integrations. `detail.snapshot` equals `pageViewerSnapshot`.","type":"CustomEvent<LyraPageViewerStateChangeDetail>"},{"name":"lr-render-error","description":"Fired for terminal fetch/open/render failures and rejected public slide navigation. Navigation rejection enters the localized error state. Recoverable post-load slide/node/search events use `lr-viewer-diagnostic` without also posing as terminal errors.","type":"CustomEvent<{ error: unknown }>"},{"name":"lr-search-change","description":"Fired whenever search state changes, including source-reset and effective-locale re-evaluation. Search accepts at most 4,096 query code units, validates at most 4,000,000 result code units, and retains at most 10,000 valid matches; `matchCountExact=false` identifies a ceiling-truncated lower bound. Bubbling, composed, and non-cancelable.","type":"CustomEvent<LyraSearchChangeDetail>"},{"name":"lr-slide-change","description":"Fired when the active slide changes.","type":"CustomEvent<{ index: number; count: number }>"},{"name":"lr-text-select","description":"Fired after a selection ends inside the rendered presentation. `detail: { text: string; anchor: LyraAnchor | null; rects: DOMRect[] }`. Bubbling, composed, and non-cancelable.","type":"CustomEvent<TextSelectDetail>"},{"name":"lr-viewer-diagnostic","description":"Structured renderer diagnostics for slide/node/search failures. `detail.diagnostic` includes a stable code, source, cause, `fatal`, and page/node when known.","type":"CustomEvent<LyraViewerDiagnosticEventDetail>"}]}},{"name":"lr-progress-bar","description":"`<lr-progress-bar>` — a determinate or indeterminate progress indicator. `variant` selects the\nindicator's semantic palette from the library's shared semantic grid (`neutral` through\n`danger`), defaulting to `brand`.\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) | Label content, visible independently of `show-value`; live visible accessible text stays synchronized through forwarding slots. |\n| `label` | Compatibility alias for the default label slot, with the same live-text behavior. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | Compatibility name for the progress wrapper; use `progress-bar`. |\n| `indicator` | The filled progress indicator. |\n| `label` | The label row. |\n| `progress-bar` | The progress wrapper. It is the same node as `base`. |\n| `track` | The track. |\n\n---\n\n**CSS Custom Properties**\n\n- `--height` (default: `var(--lr-progress-track-height)`) — Shoelace-compatible track height.\n- `--indicator-color` (default: `var(--lr-progress-indicator-color)`) — Upstream-compatible indicator color.\n- `--label-color` (default: `var(--lr-progress-label-color)`) — Shoelace-compatible label color.\n- `--lr-progress-duration` (default: `var(--lr-transition-ambient)`) — Indeterminate sweep timing.\n- `--lr-progress-indicator-color` (default: `var(--lr-progress-indicator-variant-color)`) — Indicator color, overriding the variant palette below.\n- `--lr-progress-indicator-variant-color` (default: `var(--lr-color-fill-loud,var(--lr-color-brand))`) — Palette slot: the active `variant`'s loud fill from the shared semantic grid. Feeds `--lr-progress-indicator-color` above unless that (or the upstream `--indicator-color` alias) is itself set.\n- `--lr-progress-label-color` (default: `var(--lr-color-text)`) — Label color.\n- `--lr-progress-track-color` (default: `var(--lr-color-brand-quiet)`) — Track color.\n- `--lr-progress-track-height` (default: `var(--lr-progress-height,var(--_lr-progress-track-height))`) — Block size of the progress track. The innermost fallback steps with `size` across the shared six-step ladder (`0.25rem` at `2xs` up to `1.5rem` at `xl`, `1rem` unchanged at the `m` default); an inherited or direct value here still wins outright over every tier.\n- `--track-color` (default: `var(--lr-progress-track-color)`) — Upstream-compatible track color.\n- `--track-height` (default: `var(--lr-progress-track-height)`) — Web Awesome-compatible track height.","attributes":[{"name":"accessible-label","description":"Explicit accessible name, on the library-wide `accessibleLabel`/`accessible-label` convention\nshared by every Lyra component that names a shadow-owned role. Not an alias kept for one\nupstream: `label` is the mapped upstream name and this is Lyra's own spelling; both are read,\nwith `label` first and a host `aria-label` above both.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"indeterminate","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"label","description":"Mapped accessible-label property.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max","description":"Type: `number`  \nDefault: `100`","value":{"type":["number"]}},{"name":"show-value","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"size","description":"Visual thickness of the track/indicator, on the library's shared six-step size ladder. `'m'`\n(the default) is this component's pre-existing behaviour, unchanged: an unset bar still\nrenders at `--lr-progress-track-height`'s literal `1rem` default. Every other tier scales that\nsame height, from a slender `0.25rem` at `2xs` up to a bold `1.5rem` at `xl`; an explicit\n`--lr-progress-track-height` (or the upstream `--track-height`/`--height` aliases) still wins\nover any tier.\n\nType: `LyraSize`  \nDefault: `'m'`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}},{"name":"value","description":"Type: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"variant","description":"Semantic palette, read from the library's shared semantic-tone vocabulary. Recolors the\nindicator via the variant's loud fill from the shared semantic grid.\n\nType: `LyraProgressVariant`  \nDefault: `'brand'`","value":{"type":["'neutral'","'brand'","'success'","'warning'","'danger'"]}}],"slots":[{"name":"","description":"Label content, visible independently of `show-value`; live visible accessible text stays synchronized through forwarding slots."},{"name":"label","description":"Compatibility alias for the default label slot, with the same live-text behavior."}],"js":{"properties":[{"name":"accessibleLabel","description":"Explicit accessible name, on the library-wide `accessibleLabel`/`accessible-label` convention\nshared by every Lyra component that names a shadow-owned role. Not an alias kept for one\nupstream: `label` is the mapped upstream name and this is Lyra's own spelling; both are read,\nwith `label` first and a host `aria-label` above both.\n\nAttribute: `accessible-label`","type":"string","default":"''"},{"name":"indeterminate","description":"Attribute: `indeterminate`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"label","description":"Mapped accessible-label property.\n\nAttribute: `label`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"max","description":"Attribute: `max`","type":"number","default":"100"},{"name":"showValue","description":"Attribute: `show-value`","type":"boolean","default":"false"},{"name":"size","description":"Visual thickness of the track/indicator, on the library's shared six-step size ladder. `'m'`\n(the default) is this component's pre-existing behaviour, unchanged: an unset bar still\nrenders at `--lr-progress-track-height`'s literal `1rem` default. Every other tier scales that\nsame height, from a slender `0.25rem` at `2xs` up to a bold `1.5rem` at `xl`; an explicit\n`--lr-progress-track-height` (or the upstream `--track-height`/`--height` aliases) still wins\nover any tier.\n\nAttribute: `size`  \nReflected to its attribute.","type":"LyraSize","default":"'m'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"value","description":"Attribute: `value`  \nReflected to its attribute.","type":"number","default":"0"},{"name":"variant","description":"Semantic palette, read from the library's shared semantic-tone vocabulary. Recolors the\nindicator via the variant's loud fill from the shared semantic grid.\n\nAttribute: `variant`  \nReflected to its attribute.","type":"LyraProgressVariant","default":"'brand'"}]}},{"name":"lr-progress-ring","description":"`<lr-progress-ring>` — a circular determinate or indeterminate progress indicator. `variant`\nselects the indicator's semantic palette from the library's shared semantic grid (`neutral`\nthrough `danger`), defaulting to `brand`, matching sibling `<lr-progress-bar>`.\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) | Optional center label whose visible accessible text names the progressbar unless an explicit accessible label overrides it; live mutations stay synchronized through forwarding slots. When nothing is slotted, the fallback content is the formatted percentage while determinate and `show-value` is set (`''` otherwise, and always `''` while `indeterminate`) -- the same value contract as `<lr-progress-bar>`'s `showValue`. |\n| `label` | Named alias for the optional center label, matching `<lr-progress-bar>`. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | Compatibility name for the progress wrapper; use `progress-ring`. |\n| `indicator` | The SVG indicator. |\n| `label` | The center label. |\n| `progress-ring` | The progress wrapper. It is the same node as `base`. |\n| `track` | The SVG track. |\n\n---\n\n**CSS Custom Properties**\n\n- `--indicator-color` (default: `var(--lr-progress-ring-indicator-color)`) — Upstream-compatible indicator color.\n- `--indicator-transition-duration` (default: `var(--lr-progress-ring-indicator-transition-duration)`) — Upstream-compatible transition duration.\n- `--indicator-width` (default: `var(--lr-progress-ring-indicator-width)`) — Upstream-compatible indicator width.\n- `--lr-progress-duration` (default: `var(--lr-transition-ambient)`) — Indeterminate rotation timing.\n- `--lr-progress-ring-indicator-color` (default: `var(--lr-progress-ring-indicator-variant-color)`) — Indicator stroke color, overriding the variant palette below.\n- `--lr-progress-ring-indicator-transition-duration` (default: `var(--lr-transition-base)`) — Determinate indicator transition.\n- `--lr-progress-ring-indicator-variant-color` (default: `var(--lr-color-fill-loud,var(--lr-color-brand))`) — Palette slot: the active `variant`'s loud fill from the shared semantic grid. Feeds `--lr-progress-ring-indicator-color` above unless that (or the upstream `--indicator-color` alias) is itself set.\n- `--lr-progress-ring-indicator-width` (default: `var(--lr-progress-ring-track-width)`) — Indicator stroke width.\n- `--lr-progress-ring-size` (default: `var(--size,var(--_lr-progress-ring-size))`) — Outer diameter of the ring. The private fallback steps with `size` across the shared six-step ladder (`1.25rem` at `2xs` up to `3.5rem` at `xl`, `2.5rem` unchanged at the `m` default); an inherited or direct value here (or the upstream `--size` alias) still wins outright over every tier.\n- `--lr-progress-ring-track-color` (default: `var(--lr-color-brand-quiet)`) — Track stroke color.\n- `--lr-progress-ring-track-width` (default: `var(--lr-theme-progress-ring-track-width,var(--lr-size-4px))`) — Track stroke width, `4px` by default. Bridges its own dedicated `--lr-theme-progress-ring-track-width` theme input rather than the widely-shared `--lr-theme-border-width-thick` (fed to the `--lr-border-width-thick` alias): `theme.css` declares that shared input at `3px` -- its correct default for the many surfaces that genuinely want it -- and bridging it directly here would have let importing `theme.css` alone silently repaint this ring's stroke to `3px` even with no consumer override. Set `--lr-theme-progress-ring-track-width` on `:root` or any ancestor to retune this ring specifically; it stays unset (and this default applies) whether or not `theme.css` is imported.\n- `--size` (default: `var(--lr-progress-ring-size)`) — Upstream-compatible outer diameter.\n- `--track-color` (default: `var(--lr-progress-ring-track-color)`) — Upstream-compatible track color.\n- `--track-width` (default: `var(--lr-progress-ring-track-width)`) — Upstream-compatible track width.","attributes":[{"name":"accessible-label","description":"Explicit accessible name, on the library-wide `accessibleLabel`/`accessible-label` convention\nshared by every Lyra component that names a shadow-owned role. Not an alias kept for one\nupstream: `label` is the mapped upstream name and this is Lyra's own spelling; both are read,\nwith `label` first and a host `aria-label` above both.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"indeterminate","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"label","description":"Mapped accessible-label property.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max","description":"Type: `number`  \nDefault: `100`","value":{"type":["number"]}},{"name":"show-value","description":"Shows the formatted percentage as the default slot's fallback content while determinate.\n`false` by default, matching sibling `<lr-progress-bar>`'s `showValue`/`show-value` exactly --\na determinate ring with no `show-value` renders no percentage text. Only the fallback is\ngated: a consumer who slots their own content always sees that content instead, with or\nwithout `show-value` (native `<slot>` projection semantics, unaffected by this property).\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"size","description":"Outer diameter of the ring, on the library's shared six-step size ladder. `'m'` (the default)\nis this component's pre-existing behaviour, unchanged: an unset ring still renders at\n`--lr-progress-ring-size`'s literal `2.5rem` default. Every other tier scales that same\ndiameter, from a compact `1.25rem` at `2xs` up to a roomy `3.5rem` at `xl`; an explicit\n`--lr-progress-ring-size` (or the upstream `--size` alias) still wins over any tier. Matching\nsibling `<lr-progress-bar>`'s own `size`, this scales exactly one dimension — the track/\nindicator stroke width and the center label's font size are unaffected by the tier.\n\nType: `LyraSize`  \nDefault: `'m'`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}},{"name":"value","description":"Type: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"variant","description":"Selects the indicator's semantic palette from the shared semantic grid, matching sibling\n`<lr-progress-bar>`'s `variant`.\n\nType: `LyraProgressVariant`  \nDefault: `'brand'`","value":{"type":["'neutral'","'brand'","'success'","'warning'","'danger'"]}}],"slots":[{"name":"","description":"Optional center label whose visible accessible text names the progressbar unless an explicit accessible label overrides it; live mutations stay synchronized through forwarding slots. When nothing is slotted, the fallback content is the formatted percentage while determinate and `show-value` is set (`''` otherwise, and always `''` while `indeterminate`) -- the same value contract as `<lr-progress-bar>`'s `showValue`."},{"name":"label","description":"Named alias for the optional center label, matching `<lr-progress-bar>`."}],"js":{"properties":[{"name":"accessibleLabel","description":"Explicit accessible name, on the library-wide `accessibleLabel`/`accessible-label` convention\nshared by every Lyra component that names a shadow-owned role. Not an alias kept for one\nupstream: `label` is the mapped upstream name and this is Lyra's own spelling; both are read,\nwith `label` first and a host `aria-label` above both.\n\nAttribute: `accessible-label`","type":"string","default":"''"},{"name":"indeterminate","description":"Attribute: `indeterminate`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"indicator","description":"Live SVG indicator circle, or `null` before the render root is populated.","type":"SVGCircleElement | null","read-only":true},{"name":"indicatorOffset","description":"Current normalized stroke offset used by the rendered indicator.","type":"number","read-only":true},{"name":"label","description":"Mapped accessible-label property.\n\nAttribute: `label`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"max","description":"Attribute: `max`","type":"number","default":"100"},{"name":"showValue","description":"Shows the formatted percentage as the default slot's fallback content while determinate.\n`false` by default, matching sibling `<lr-progress-bar>`'s `showValue`/`show-value` exactly --\na determinate ring with no `show-value` renders no percentage text. Only the fallback is\ngated: a consumer who slots their own content always sees that content instead, with or\nwithout `show-value` (native `<slot>` projection semantics, unaffected by this property).\n\nAttribute: `show-value`","type":"boolean","default":"false"},{"name":"size","description":"Outer diameter of the ring, on the library's shared six-step size ladder. `'m'` (the default)\nis this component's pre-existing behaviour, unchanged: an unset ring still renders at\n`--lr-progress-ring-size`'s literal `2.5rem` default. Every other tier scales that same\ndiameter, from a compact `1.25rem` at `2xs` up to a roomy `3.5rem` at `xl`; an explicit\n`--lr-progress-ring-size` (or the upstream `--size` alias) still wins over any tier. Matching\nsibling `<lr-progress-bar>`'s own `size`, this scales exactly one dimension — the track/\nindicator stroke width and the center label's font size are unaffected by the tier.\n\nAttribute: `size`  \nReflected to its attribute.","type":"LyraSize","default":"'m'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"value","description":"Attribute: `value`  \nReflected to its attribute.","type":"number","default":"0"},{"name":"variant","description":"Selects the indicator's semantic palette from the shared semantic grid, matching sibling\n`<lr-progress-bar>`'s `variant`.\n\nAttribute: `variant`  \nReflected to its attribute.","type":"LyraProgressVariant","default":"'brand'"}]}},{"name":"lr-prompt-input","description":"`<lr-prompt-input>` — a composed AI prompt surface combining the chat composer with attachments,\nmodel and voice selection, retrieval sources, mentions, slash commands, and a queued-turn list.\nIt performs no upload, model call, retrieval, or persistence.\n\nDeliberately not form-associated: this is a composite application interaction whose complete\nstate includes attachments, source scope, model, voice, and queued turns, not one successful\nstring form entry. Observe `lr-input` for controlled text and handle `lr-submit` as the\nsubmission request. `label` names the prompt section; it is not generic field chrome.\n\nThe composed text surface exposes the same native editing-assistance, selection, and range-edit\nAPIs as `<lr-chat-composer>`. Silent `setRangeText()` calls keep this outer `value` synchronized\nwithout emitting `lr-input`; selection APIs are no-ops before the nested textarea renders.\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.\nAttachment ids are unique, nonempty occurrence identities; malformed rows and later duplicate\nids are omitted before chip rendering or attachment events, with the first occurrence winning.\n\n---\n\n**Component metadata**\n\n- Status: `stable`\n- Since: `7.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| `chips` | Replaces the data-driven attachment chips. |\n| `controls` | Replaces the data-driven model, voice, and source controls. |\n| `end` | Custom send/stop action replacing the built-in composer action. |\n| `footer` | Content below the composer. |\n| `start` | Attachment-control content rendered before the textarea. Replaces the default attachment trigger. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The prompt surface. |\n| `chips` | The attachment-chip tray. |\n| `composer` | The composed chat composer. |\n| `controls` | Model, voice, and source controls. |\n| `footer` | The footer slot. |\n| `queue` | The composed prompt queue. |\n| `source-picker` | The composed source picker. |\n| `sources` | The collapsible source-picker region. |\n| `sources-summary` | The source-picker disclosure. |\n| `start` | The composer's `start` attachment control, or its default attachment trigger. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-prompt-input-control-width` (default: `--lr-size-12rem`) — Preferred width of each generated model, voice, and source control before wrapping.","attributes":[{"name":"aria-label","description":"Type: `string | null`  \nDefault: `null`"},{"name":"autocapitalize","description":"Forwarded to the composed native textarea's own `autocapitalize`. Empty string omits the\nattribute and preserves the browser default.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"autocomplete","description":"Native autocomplete hint forwarded to the composed textarea.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"autocorrect","description":"Native autocorrect state forwarded through the composer. Reads are boolean; writes accept\nboolean or the legacy `'off'`/`'false'` strings.\n\nType: `boolean`","value":{"type":["boolean"]}},{"name":"disabled","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"enterkeyhint","description":"Virtual-keyboard enter-action hint forwarded to the composed textarea.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"inputmode","description":"Virtual-keyboard input hint forwarded to the composed textarea.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"label","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"maxlength","description":"Type: `number | undefined`"},{"name":"minlength","description":"Type: `number | undefined`"},{"name":"model","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"placeholder","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"readonly","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"spellcheck","description":"Forwarded to the composed native textarea. `spellcheck=\"false\"` parses as `false`, matching\nthe textarea's true default while remaining usable from plain HTML.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"status","description":"Forwarded composer state. Invalid input reads as the safe idle state without rewriting this host's attribute.\n\nType: `ChatComposerStatus`","value":{"type":["'idle'","'sending'","'streaming'"]}},{"name":"submit-on-enter","description":"Type: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"value","description":"Type: `string`","value":{"type":["string"]}},{"name":"voice","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"wrap","description":"Native wrapping behavior forwarded to the composed textarea.\n\nType: `ChatComposerWrap`  \nDefault: `'soft'`","value":{"type":["'hard'","'soft'","'off'"]}}],"slots":[{"name":"chips","description":"Replaces the data-driven attachment chips."},{"name":"controls","description":"Replaces the data-driven model, voice, and source controls."},{"name":"end","description":"Custom send/stop action replacing the built-in composer action."},{"name":"footer","description":"Content below the composer."},{"name":"start","description":"Attachment-control content rendered before the textarea. Replaces the default attachment trigger."}],"js":{"properties":[{"name":"accessibleLabel","description":"Attribute: `aria-label`","type":"string | null","default":"null"},{"name":"attachmentCapabilities","type":"readonly LyraAttachmentCapability[]","default":"[ 'files', 'image', 'audio', ]"},{"name":"attachments","description":"Attachment chips keyed by unique, nonempty `attachmentId`; the first duplicate wins.","type":"readonly LyraPromptInputAttachment[]","default":"[]"},{"name":"autocapitalize","description":"Forwarded to the composed native textarea's own `autocapitalize`. Empty string omits the\nattribute and preserves the browser default.\n\nAttribute: `autocapitalize`","type":"string","default":"''"},{"name":"autocomplete","description":"Native autocomplete hint forwarded to the composed textarea.\n\nAttribute: `autocomplete`","type":"string","default":"''"},{"name":"autocorrect","description":"Native autocorrect state forwarded through the composer. Reads are boolean; writes accept\nboolean or the legacy `'off'`/`'false'` strings.\n\nAttribute: `autocorrect`","type":"boolean"},{"name":"commandItems","type":"readonly LyraPromptSuggestion[]","default":"[]"},{"name":"disabled","description":"Attribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"enterKeyHint","description":"Virtual-keyboard enter-action hint forwarded to the composed textarea.\n\nAttribute: `enterkeyhint`","type":"string","default":"''"},{"name":"input","description":"The composed native textarea, or `null` before it has rendered.","type":"HTMLTextAreaElement | null","read-only":true},{"name":"inputMode","description":"Virtual-keyboard input hint forwarded to the composed textarea.\n\nAttribute: `inputmode`","type":"string","default":"''"},{"name":"label","description":"Attribute: `label`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"maxLength","description":"Attribute: `maxlength`","type":"number | undefined"},{"name":"mentionItems","type":"readonly LyraPromptSuggestion[]","default":"[]"},{"name":"minLength","description":"Attribute: `minlength`","type":"number | undefined"},{"name":"model","description":"Attribute: `model`","type":"string","default":"''"},{"name":"modelCatalog","type":"LyraCatalog<LyraModelCatalogEntry> | undefined"},{"name":"placeholder","description":"Attribute: `placeholder`","type":"string","default":"''"},{"name":"queue","description":"Queued prompts keyed by unique nonblank `id`; malformed and later duplicate rows are omitted\nbefore section gating or forwarding.","type":"readonly PromptQueueItem[]","default":"[]"},{"name":"readOnly","description":"Attribute: `readonly`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"selectedSourceIds","description":"Controlled source identities, normalized to unique nonblank values before forwarding.","type":"readonly string[]","default":"[]"},{"name":"selectionDirection","type":"ChatComposerSelectionDirection | null"},{"name":"selectionEnd","type":"number | null"},{"name":"selectionStart","type":"number | null"},{"name":"sources","description":"Retrieval sources keyed by unique nonblank `id`; malformed and later duplicate roots are\nomitted before controls are rendered or forwarded.","type":"readonly LyraSourceEntry[]","default":"[]"},{"name":"spellcheck","description":"Forwarded to the composed native textarea. `spellcheck=\"false\"` parses as `false`, matching\nthe textarea's true default while remaining usable from plain HTML.\n\nAttribute: `spellcheck`","type":"boolean","default":"true"},{"name":"status","description":"Forwarded composer state. Invalid input reads as the safe idle state without rewriting this host's attribute.\n\nAttribute: `status`","type":"ChatComposerStatus"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"submitOnEnter","description":"Attribute: `submit-on-enter`","type":"boolean","default":"true"},{"name":"value","description":"Attribute: `value`","type":"string"},{"name":"voice","description":"Attribute: `voice`","type":"string","default":"''"},{"name":"voiceCatalog","type":"LyraCatalog<LyraVoiceCatalogEntry> | undefined"},{"name":"wrap","description":"Native wrapping behavior forwarded to the composed textarea.\n\nAttribute: `wrap`","type":"ChatComposerWrap","default":"'soft'"}],"events":[{"name":"blur","description":"One native `FocusEvent` relayed only from the primary prompt textarea, not from any composed control.","type":"FocusEvent"},{"name":"change","description":"One native `Event` when the primary prompt edit is committed.","type":"Event"},{"name":"focus","description":"One native `FocusEvent` relayed only from the primary prompt textarea, not from any composed control (model/voice picker, attachment trigger, prompt queue).","type":"FocusEvent"},{"name":"input","description":"One native `InputEvent` for a user edit of the primary prompt value.","type":"InputEvent"},{"name":"lr-attachment-preview-request","description":"Cancelable preview request. `detail: { attachmentId, name, mimeType, src }`.","type":"CustomEvent<LyraAttachmentPreviewRequestDetail>"},{"name":"lr-attachment-remove","description":"Attachment removal was requested. `detail: { attachmentId }`.","type":"CustomEvent<LyraAttachmentIdDetail>"},{"name":"lr-attachment-retry","description":"Retrying an attachment was requested. `detail: { attachmentId }`.","type":"CustomEvent<LyraAttachmentIdDetail>"},{"name":"lr-attachments-add","description":"Files were selected. `detail: { files, capability }`.","type":"CustomEvent<LyraEventDetailSnapshot<LyraAttachmentFilesDetail>>"},{"name":"lr-audio-request","description":"Audio capture was requested.","type":"CustomEvent<null>"},{"name":"lr-camera-request","description":"Camera capture was requested.","type":"CustomEvent<null>"},{"name":"lr-change","description":"Prompt text edit was committed. `detail: { value }`.","type":"CustomEvent<{ value: string }>"},{"name":"lr-input","description":"Prompt text changed. `detail: { value }`.","type":"CustomEvent<{ value: string }>"},{"name":"lr-mention-select","description":"A mention or slash command was inserted.","type":"CustomEvent<{\n    suggestionId: string;\n    index: number;\n    label: string;\n    trigger: '@' | '/';\n  }>"},{"name":"lr-model-change","description":"Model selection changed. `detail: { value, inCatalog }`.","type":"CustomEvent<{ value: string; inCatalog: boolean }>"},{"name":"lr-queue-change","description":"The queued prompts changed.","type":"CustomEvent<LyraEventDetailSnapshot<PromptQueueChangeDetail>>"},{"name":"lr-send-now","description":"Immediate submission of a queued prompt was requested. `detail: { item }`.","type":"CustomEvent<LyraEventDetailSnapshot<{ item: PromptQueueItem }>>"},{"name":"lr-sources-change","description":"Retrieval source selection changed. `detail: { selectedSourceIds }`.","type":"CustomEvent<LyraEventDetailSnapshot<{ selectedSourceIds: string[] }>>"},{"name":"lr-stop","description":"Stop generation was requested.","type":"CustomEvent<null>"},{"name":"lr-submit","description":"Prompt submission was requested. `detail: { value }`.","type":"CustomEvent<{ value: string }>"},{"name":"lr-voice-change","description":"Voice selection changed. `detail: { value, inCatalog }`.","type":"CustomEvent<{ value: string; inCatalog: boolean }>"}]}},{"name":"lr-prompt-queue","description":"`<lr-prompt-queue>` — a controlled queue of follow-up prompts that can be edited, reordered,\nremoved, or sent immediately while another agent turn is active.\nItem ids are unique occurrence identities. Empty ids and later duplicate occurrences are\nignored before rendering or proposing a mutation, so every `itemId` remains unambiguous.\nWhen the host accepts a removal while that row's action owns focus, the equivalent action on\nthe nearest surviving row receives focus; an emptied queue focuses its stable region instead.\nControlled updates never steal focus when the removed row did not own it.\n\nPublic item sequences are bounded, frozen snapshots. Admitted item identities remain opaque only\nwhile a descriptor-safe projection copies the queue's display and proposal fields once; later\nrendering and events never reread the source row or its opaque metadata. Create a new collection\nand reassign it after changes; mutating an assigned array does not update the view.\n\n---\n\n**Component metadata**\n\n- Status: `stable`\n- Since: `7.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| `action` | Every item action. |\n| `actions` | One item's action row. |\n| `attachment` | One attachment name. |\n| `attachments` | The visible attachment-name list for one prompt. |\n| `base` | The queue wrapper. |\n| `editor` | A queued prompt editor. |\n| `empty` | The empty state. |\n| `heading` | The queue heading. |\n| `item` | One queued prompt. |\n| `list` | The ordered queue list. |\n| `value` | Read-only prompt text when `editable` is false. |","attributes":[{"name":"aria-label","description":"Type: `string | null`  \nDefault: `null`"},{"name":"disabled","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"editable","description":"Type: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"label","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"js":{"properties":[{"name":"accessibleLabel","description":"Attribute: `aria-label`","type":"string | null","default":"null"},{"name":"disabled","description":"Attribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"editable","description":"Attribute: `editable`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"items","description":"Controlled queued prompts. Accessor-backed or malformed rows and attachments are omitted;\nduplicate nonblank item ids normalize first-wins after full row validation.","type":"readonly PromptQueueItem[]","default":"[]"},{"name":"label","description":"Attribute: `label`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-queue-change","description":"A proposed controlled queue update. `detail: { items, reason, itemId }`.","type":"CustomEvent<LyraEventDetailSnapshot<PromptQueueChangeDetail>>"},{"name":"lr-send-now","description":"Immediate send was requested. `detail: { item }`.","type":"CustomEvent<LyraEventDetailSnapshot<{ item: PromptQueueItem }>>"}]}},{"name":"lr-prompt-studio","description":"`<lr-prompt-studio>` — a provider-neutral prompt-development workbench for ordered role\nmessages, `{{variable}}` substitution, version selection, preview, save, and run intents.\nThe host owns persistence and model execution. Opting into message reordering exposes native,\nkeyboard-operable move controls; every proposed move is cancelable before the editor state changes.\nEmpty/blank message and version ids are omitted; duplicates use deterministic first-wins\nsemantics. Variable rows are\noccurrence-addressed because their names are editable and may temporarily be empty or repeated;\nduplicate names remain independently editable while placeholder resolution uses the first one.\nVariable values resolve recursively; undefined and cyclic placeholders remain intact within\npreview bounds. One preview projection allows at most 64 nested variable resolutions, 10,000\nplaceholder substitutions, and 1,048,576 UTF-16 code units each of aggregate preview output and\naggregate memoized intermediate text. A localized visible fallback replaces the preview when\na limit would be exceeded; raw editor state and save/run payloads are unchanged.\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: `7.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| `add-message` | The add-message action. |\n| `base` | The named studio region. |\n| `editor` | Messages and variables workspace. |\n| `message` | One prompt message. |\n| `message-actions` | Reorder and removal actions for one message, when reordering is enabled. |\n| `message-content` | A message textarea. It deliberately keeps native vertical resizing; configurable `resize` and auto-grow behavior are intentionally omitted. |\n| `message-role` | A message role selector. |\n| `messages` | Ordered prompt-message editor. |\n| `move-message-down` | A move-message-down action. |\n| `move-message-up` | A move-message-up action. |\n| `preview` | Resolved read-only preview. |\n| `remove-message` | A message removal action. |\n| `run` | The run action. |\n| `save` | The save action. |\n| `toolbar` | Save/run controls. |\n| `variable` | One variable row. |\n| `variables` | Variable editor. |\n| `version` | One saved version. |\n| `versions` | Saved-version controls. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-prompt-studio-field-hover-border` (default: `var(--lr-color-brand)`) — Enabled field hover border.\n- `--lr-prompt-studio-version-selected-bg` (default: `var(--lr-color-brand-quiet)`) — Selected version background.\n- `--lr-prompt-studio-version-selected-border` (default: `var(--lr-color-brand)`) — Selected version border.\n- `--lr-prompt-studio-version-selected-color` (default: `var(--lr-color-text)`) — Selected version foreground.\n- `--lr-prompt-studio-version-selected-hover-bg` (default: `color-mix(in oklab, var(--lr-color-brand-quiet), var(--lr-color-mix-partner) var(--lr-color-mix-hover))`) — Selected version hover background.","attributes":[{"name":"autocapitalize","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"autocorrect","description":"Named `autoCorrect` to avoid the boolean `HTMLElement.autocorrect` DOM typing collision while\npreserving the native lowercase `autocorrect` attribute.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"disabled","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"heading","description":"Visible toolbar heading. Falls back to the localized “Prompt studio” string.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"label","description":"Accessible name for the studio region. It is independent from the visible `heading`; when\nabsent, the heading text names the region. A host `aria-label` remains authoritative.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"reorderable","description":"Opts into native move-up/move-down buttons for each message. A move first emits the\ncancelable `lr-message-reorder` request, so a host that needs asynchronous persistence can\nprevent it and later assign its accepted message order.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"running","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"selected-version-id","description":"Type: `string | null`  \nDefault: `null`"},{"name":"spellcheck","description":"Native editing-assistance attributes forwarded to the message textarea and variable inputs.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"wrap","description":"Native `<textarea>` wrapping mode. Variable `<input>` controls do not support `wrap`.\n\nType: `PromptStudioWrap`  \nDefault: `'soft'`","value":{"type":["'hard'","'soft'","'off'"]}}],"js":{"properties":[{"name":"autoCorrect","description":"Named `autoCorrect` to avoid the boolean `HTMLElement.autocorrect` DOM typing collision while\npreserving the native lowercase `autocorrect` attribute.\n\nAttribute: `autocorrect`","type":"string","default":"''"},{"name":"autocapitalize","description":"Attribute: `autocapitalize`","type":"string","default":"''"},{"name":"disabled","description":"Attribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"heading","description":"Visible toolbar heading. Falls back to the localized “Prompt studio” string.\n\nAttribute: `heading`","type":"string","default":"''"},{"name":"label","description":"Accessible name for the studio region. It is independent from the visible `heading`; when\nabsent, the heading text names the region. A host `aria-label` remains authoritative.\n\nAttribute: `label`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"messages","description":"Host-controlled messages; a runtime non-array value renders as not-yet-loaded empty data.","type":"readonly PromptStudioMessage[]","default":"[]"},{"name":"reorderable","description":"Opts into native move-up/move-down buttons for each message. A move first emits the\ncancelable `lr-message-reorder` request, so a host that needs asynchronous persistence can\nprevent it and later assign its accepted message order.\n\nAttribute: `reorderable`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"running","description":"Attribute: `running`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"selectedVersionId","description":"Attribute: `selected-version-id`","type":"string | null","default":"null"},{"name":"spellcheck","description":"Native editing-assistance attributes forwarded to the message textarea and variable inputs.\n\nAttribute: `spellcheck`","type":"boolean","default":"true"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"variables","description":"Host-controlled variables; a runtime non-array value renders as not-yet-loaded empty data.","type":"readonly PromptStudioVariable[]","default":"[]"},{"name":"versions","description":"Host-controlled saved versions; a runtime non-array value renders as not-yet-loaded empty data.","type":"readonly PromptStudioVersion[]","default":"[]"},{"name":"wrap","description":"Native `<textarea>` wrapping mode. Variable `<input>` controls do not support `wrap`.\n\nAttribute: `wrap`","type":"PromptStudioWrap","default":"'soft'"}],"events":[{"name":"blur","description":"Re-dispatched when the message textarea or a variable input loses focus.","type":"CustomEvent<null>"},{"name":"focus","description":"Re-dispatched when the message role selector, textarea, or a variable input receives focus, since native focus neither bubbles nor crosses the shadow boundary.","type":"CustomEvent<null>"},{"name":"lr-change","description":"A cancelable proposal that messages or variables are about to change. Carries their complete next state. Prevent it to keep the current state unchanged, the same veto point `lr-message-reorder` already offers for reordering.","type":"CustomEvent<LyraEventDetailSnapshot<PromptStudioState>>"},{"name":"lr-message-reorder","description":"A cancelable request to reorder messages. Carries the proposed complete message order and the moved message's id and indexes. Prevent it to persist or reject the proposed order yourself, then assign `messages` when the host is ready to render it.","type":"CustomEvent<LyraEventDetailSnapshot<PromptStudioMessageReorderDetail>>"},{"name":"lr-run","description":"The current prompt was requested for execution.","type":"CustomEvent<LyraEventDetailSnapshot<PromptStudioState>>"},{"name":"lr-save","description":"The current prompt was requested for persistence.","type":"CustomEvent<LyraEventDetailSnapshot<PromptStudioState>>"},{"name":"lr-version-select","description":"A complete saved version was activated.","type":"CustomEvent<LyraEventDetailSnapshot<{ version: PromptStudioVersion }>>"}]}},{"name":"lr-provenance-panel","description":"`<lr-provenance-panel>` — the grounding breakdown for one answer: a sectioned disclosure\npanel (Entities / Relationships / Communities / Text chunks) composing this family's own pieces.\nThe chat <-> graph <-> document glue component. Pure projection + event conduit: no fetching, no\ngraph/viewer imports, no persistence.\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**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The root wrapper. |\n| `body` | A section's content wrapper, `hidden` while collapsed. |\n| `count` | A section's item-count badge. |\n| `empty` | The empty state, shown when every section is empty. |\n| `entity-row` | The wrapping row of entity chips inside the entities section. Style this to change how the chip lines pack (`justify-content`, `row-gap`). |\n| `header` | A section's disclosure `<button>`. |\n| `section` | One section's wrapper. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-provenance-panel-entity-justify` (default: `flex-start`) — Main-axis packing of the entity-chip row. `center` centers every line, the wrapped final one included.","attributes":[{"name":"label","description":"Fallback name for the provenance group, used when omitted; falls back to the localized\n`provenancePanelLabel`. A non-empty host `aria-label` makes the host the sole overall owner;\nan explicitly empty host label stays empty on the group, and so does an explicitly empty\n`label`.\n\nType: `string | undefined`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"js":{"properties":[{"name":"label","description":"Fallback name for the provenance group, used when omitted; falls back to the localized\n`provenancePanelLabel`. A non-empty host `aria-label` makes the host the sole overall owner;\nan explicitly empty host label stays empty on the group, and so does an explicitly empty\n`label`.\n\nAttribute: `label`","type":"string | undefined"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"provenance","description":"Provenance model whose entity, relationship, community, and chunk sections are rendered.","type":"Readonly<LyraProvenance> | null","default":"null"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"thresholds","description":"Score boundaries forwarded to the composed chunk inspector.","type":"LyraScoreThresholds","default":"{ high: 0.75, medium: 0.5, }"},{"name":"types","description":"`lr-graph` `nodeTypes` pass-through; resolves each `entity.type` for the entity chips' `typeLabel`.\nMalformed type rows are ignored so later valid matching records remain available.","type":"readonly LyraNodeTypeStyle[]","default":"[]"}],"events":[{"name":"lr-chunk-open","description":"Surfaced unchanged from an embedded chunk inspector. `detail: { chunkId, sourceId, anchor? }`.","type":"CustomEvent<LyraEventDetailSnapshot<{\n    chunkId: string;\n    sourceId: string;\n    anchor?: LyraChunkAnchor;\n  }>>"},{"name":"lr-drill","description":"Surfaced unchanged from an embedded community card's title, drill button, or overflow chip. `detail: { communityId }`.","type":"CustomEvent<{ communityId: string }>"},{"name":"lr-entity-activate","description":"Surfaced unchanged from an embedded community card or relationship path strip. `detail: { entityId, occurrenceIndex? }`.","type":"CustomEvent<{\n    entityId: string;\n    occurrenceIndex?: number;\n  }>"},{"name":"lr-entity-open","description":"Surfaced unchanged from an embedded entity chip (double-click, or Space while focused). `detail: { entityId }`.","type":"CustomEvent<{ entityId: string }>"},{"name":"lr-entity-select","description":"Surfaced unchanged from an embedded entity chip. `detail: { entityId }`.","type":"CustomEvent<{ entityId: string }>"},{"name":"lr-expand","description":"Surfaced unchanged from an embedded chunk inspector. `detail: { chunkId, expanded }`.","type":"CustomEvent<{ chunkId: string; expanded: boolean }>"},{"name":"lr-relation-activate","description":"Surfaced unchanged from an embedded relationship path strip's edge. `detail: { relation, sourceNodeId?, targetNodeId?, occurrenceIndex }`.","type":"CustomEvent<{\n    relation: string;\n    sourceNodeId?: string;\n    targetNodeId?: string;\n    occurrenceIndex: number;\n  }>"},{"name":"lr-toggle","description":"A section header was toggled. `detail: { section, expanded }`.","type":"CustomEvent<{ section: Section; expanded: boolean }>"}]}},{"name":"lr-push-to-talk","description":"`<lr-push-to-talk>` — a mic capture button owning the full `getUserMedia` + `MediaRecorder`\nlifecycle: permission request, recording, optional chunked streaming, teardown. The one place in\nthis library that touches the microphone — no SDK, no LiveKit/ElevenLabs import, native browser\nAPIs only.\n\n`mode=\"hold\"` (the default) is a press-and-hold gesture: pointerdown/Enter-or-Space-keydown starts,\npointerup/keyup/blur stops. `mode=\"toggle\"` is click-to-start/click-to-stop with `aria-pressed`.\nEscape cancels the in-progress take in either mode (discarding it — `lr-record-cancel`, never\n`lr-record-stop`). `state` is a read-only lifecycle reflected to the `data-state` attribute (not\n`state`, avoiding any ambiguity with a native form-control `state`): `'idle' | 'requesting' |\n'denied' | 'recording' | 'error'`. A host-level `aria-label` (set on `<lr-push-to-talk>` itself)\noverrides the computed trigger label by attribute presence, including an explicit empty value.\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| `microphone-icon` | Replaces the default mic glyph. Decorative: assigned content is inert and hidden from accessibility APIs because it is rendered inside the named trigger button. |\n| `recording-icon` | Replaces the default recording-state pulse glyph. Decorative and inert. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `icon` | Wrapper around the `microphone-icon` slot and default mic glyph. |\n| `pulse` | Wrapper around the `recording-icon` slot / default pulse glyph, rendered only while recording. |\n| `status` | Visible status text for the `requesting`/`denied`/`error`/unsupported states. |\n| `timer` | The localized `M:SS` elapsed-time readout, rendered only while recording and `show-timer`. |\n| `trigger` | The capture button. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-push-to-talk-pulse-recording-border-color` (default: `var(--lr-push-to-talk-recording-color, var(--lr-color-danger))`) — Recording pulse-ring border color.\n- `--lr-push-to-talk-recording-color` (default: `var(--lr-color-danger)`) — Established aggregate fallback for the recording trigger border, trigger foreground, and pulse border. The three more-specific recording properties below win independently when set.\n- `--lr-push-to-talk-size` (default: `var(--lr-size-3rem)`) — Preferred inline and block size of the circular `trigger` button; `--lr-icon-button-size` remains its minimum hit-area floor.\n- `--lr-push-to-talk-trigger-recording-border-color` (default: `var(--lr-push-to-talk-recording-color, var(--lr-color-danger))`) — Trigger border color while recording.\n- `--lr-push-to-talk-trigger-recording-color` (default: `var(--lr-push-to-talk-recording-color, var(--lr-color-danger))`) — Trigger foreground, including the default mic glyph, while recording.","attributes":[{"name":"device-id","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"disabled","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"level-events","description":"Enables `lr-level` sampling. Changes take effect immediately during an active recording.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max-duration-ms","description":"`> 0` auto-stops the take at this many milliseconds (a stuck-key guard); `0` (the default)\nnever auto-stops. Clamped to `[1, MAX_TIMEOUT_MS]` at the point it's handed to `setTimeout()`\n-- see `start()` -- the browser timer ceiling, matching\n`lr-sequence-playback`'s `interval-ms`\nhandling of its own duration-like property. Changes during recording reschedule the deadline\nrelative to the original recording start; setting `0` cancels it.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"mime-type","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"mode","description":"Type: `PushToTalkMode`","value":{"type":["'hold'","'toggle'"]}},{"name":"show-timer","description":"Shows and samples the elapsed timer. Changes take effect immediately while recording.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"timeslice-ms","description":"`> 0` requests periodic `lr-record-chunk` slices from `MediaRecorder` every this-many\nmilliseconds; `0` (the default) requests one slice at stop. Clamped to\n`[1, MAX_TIMEOUT_MS]` at the point it's handed to `MediaRecorder.start()` -- see `start()` --\nso a non-finite/oversized value can't reach that native API unsanitized.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}}],"slots":[{"name":"microphone-icon","description":"Replaces the default mic glyph. Decorative: assigned content is inert and hidden from accessibility APIs because it is rendered inside the named trigger button."},{"name":"recording-icon","description":"Replaces the default recording-state pulse glyph. Decorative and inert."}],"js":{"properties":[{"name":"audioConstraints","description":"Additional audio constraints (`echoCancellation`, …). `deviceId` has one authority: the\ntop-level `deviceId` property.","type":"PushToTalkAudioConstraints | undefined"},{"name":"deviceId","description":"Attribute: `device-id`","type":"string","default":"''"},{"name":"disabled","description":"Attribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"levelEvents","description":"Enables `lr-level` sampling. Changes take effect immediately during an active recording.\n\nAttribute: `level-events`","type":"boolean","default":"false"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"maxDurationMs","description":"`> 0` auto-stops the take at this many milliseconds (a stuck-key guard); `0` (the default)\nnever auto-stops. Clamped to `[1, MAX_TIMEOUT_MS]` at the point it's handed to `setTimeout()`\n-- see `start()` -- the browser timer ceiling, matching\n`lr-sequence-playback`'s `interval-ms`\nhandling of its own duration-like property. Changes during recording reschedule the deadline\nrelative to the original recording start; setting `0` cancels it.\n\nAttribute: `max-duration-ms`","type":"number","default":"0"},{"name":"mimeType","description":"Attribute: `mime-type`","type":"string","default":"''"},{"name":"mode","description":"Attribute: `mode`  \nReflected to its attribute.","type":"PushToTalkMode"},{"name":"showTimer","description":"Shows and samples the elapsed timer. Changes take effect immediately while recording.\n\nAttribute: `show-timer`","type":"boolean","default":"true"},{"name":"state","description":"Read-only recording lifecycle, reflected to the `data-state` attribute. Drive it via\n`start()`/`stop()`/`cancel()`, never by assignment.","type":"PushToTalkState","read-only":true},{"name":"stream","description":"The active `MediaStream` — the same object `lr-record-start` carries. `null` outside an\nactive take.","type":"MediaStream | null","read-only":true},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"timesliceMs","description":"`> 0` requests periodic `lr-record-chunk` slices from `MediaRecorder` every this-many\nmilliseconds; `0` (the default) requests one slice at stop. Clamped to\n`[1, MAX_TIMEOUT_MS]` at the point it's handed to `MediaRecorder.start()` -- see `start()` --\nso a non-finite/oversized value can't reach that native API unsanitized.\n\nAttribute: `timeslice-ms`","type":"number","default":"0"}],"events":[{"name":"lr-level","description":"`detail: { level: number }` (0-1 RMS amplitude), opt-in via `level-events`, rAF-throttled, only while `state === 'recording'`.","type":"CustomEvent<{ level: number }>"},{"name":"lr-record-cancel","description":"The take was discarded via `cancel()`/Escape — no detail, and `lr-record-stop` never fires for this take.","type":"CustomEvent<null>"},{"name":"lr-record-chunk","description":"A `timeslice-ms` slice was produced (only fires when `timeslice-ms > 0`, in order). `detail: { blob: Blob }` — a container fragment, decodable only once concatenated from the first chunk of the take.","type":"CustomEvent<{ blob: Blob }>"},{"name":"lr-record-error","description":"A permission request, recorder construction/start, or active recorder failed. `detail: { error: DOMException | Error }` — `NotAllowedError` transitions `state` to `'denied'`, anything else to `'error'`.","type":"CustomEvent<{ error: DOMException | Error }>"},{"name":"lr-record-start","description":"Capture began. `detail: { stream: MediaStream }` — the same object the `stream` getter then returns for the duration of the take.","type":"CustomEvent<{ stream: MediaStream }>"},{"name":"lr-record-state-change","description":"`detail: { state: PushToTalkState }` — fires on every recording lifecycle transition.","type":"CustomEvent<{ state: PushToTalkState }>"},{"name":"lr-record-stop","description":"The take finished normally. `detail: { blob: Blob; durationMs: number }` — `durationMs` excludes the `requesting` phase.","type":"CustomEvent<{ blob: Blob; durationMs: number }>"}]}},{"name":"lr-qr-code","description":"`<lr-qr-code>` -- encodes `value` as a QR symbol with the optional\n`qrcode` peer dependency (Reed-Solomon error correction and every other\nalgorithmic step of the QR spec is delegated to that library, never\nhand-rolled) and draws the resulting module matrix across the full canvas,\none square (optionally rounded) cell per module. Like the mirrored WA/SL\ncomponents, it does not inject a quiet zone; add host CSS `padding` when a\nscanner or physical output needs one.\n\nThe stable host is the single semantic owner while a value is loading or\nrendered. Its accessible name resolves, in order, from a host `aria-label`\nattribute, `label`, then `value`; the canvas is presentational. The same\nhost publishes `aria-busy=\"true\"` and `\"false\"`. An empty `value` renders\n`[part=\"empty\"]` without image semantics.\n\nStandard host `color` and `background-color` control foreground and\nbackground paint. `--lr-qr-code-fill` and `--lr-qr-code-background` are\noptional aliases for those host styles; otherwise inherited color and the\nhost's transparent background are preserved. The permanent upstream parity\nproperties `fill` and `background` take precedence over those CSS inputs.\nShoelace migration inserts its historical black/white defaults.\n\nThe mirrored renderers use a fixed two backing pixels per CSS pixel rather\nthan the live device pixel ratio. Lyra preserves that geometry for ordinary\nsizes and uniformly reduces only extreme allocations to a bounded pixel\nbudget; CSS size and aspect ratio do not change.\n\nDeliberately out of scope for this component, not oversights: a finder-pattern-corner accent\ncolor; auto-shrinking to fit a\nnarrow container (this component's `size` is a direct request for a\nspecific rendered pixel density, like `<img width height>` -- the consumer\npicks a size that fits their layout, this component never second-guesses\nit, though it still renders correctly at its default size inside a narrow\nallocation); form association (`value` is caller-supplied display data the\nuser doesn't edit through this component -- no `FormAssociated` mixin, no\nlabel/hint/error chrome, no form internals); and playback behavior. Keyboard\nfocus is intentionally absent -- the canvas is a static image\nstanding in for `value`, structurally like `<img>`, not an interactive\ngrid.\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 part `base`: Deprecated since `8.2.3`. Use part `::part(qr-code)`. Removal is not permitted before `10.0.0`. The qr-code part names the rendered code wrapper explicitly; base remains on that same node during the compatibility window. That version is a policy floor, not a plan: `wa-qr-code` still publishes `base` as a deprecated part and `sl-qr-code` still publishes it as its only, undeprecated part, so this alias stays for as long as either upstream ships it.\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | Deprecated in 8.2.3; compatibility name for the outer wrapper; use `qr-code`. |\n| `canvas` | The stable QR canvas. It remains hidden but reachable through `.canvas` while the component is empty, loading, or in an error state. |\n| `empty` | Shown when `value` is empty. |\n| `error` | Visible error shown when the peer is missing, or `value` failed to encode; the transition is announced through the shared light-DOM assertive region. |\n| `loading` | Shown while the optional `qrcode` peer is loading, the first time it's needed. |\n| `qr-code` | The outer wrapper, sized to `size`×`size` CSS px in every state. It is the same node as `base`. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-qr-code-background` — Optional alias for host `background-color`, used by the canvas background.\n- `--lr-qr-code-fill` — Optional alias for host `color`, used by foreground modules.","attributes":[{"name":"background","description":"Upstream-compatible canvas-background color. A non-empty value takes precedence over host\n`background-color` and `--lr-qr-code-background`.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"error-correction","description":"QR error-correction level. Normalized (upper-cased, validated against `L`/`M`/`Q`/`H`,\nfalling back to `H`) on every assignment, attribute or property, so it's never a transient\ngarbage value.\n\nType: `LyraQrCodeErrorCorrection`  \nDefault: `'H'`","value":{"type":["'L'","'M'","'Q'","'H'"]}},{"name":"fill","description":"Upstream-compatible foreground-module color. A non-empty value takes precedence over host\n`color` and `--lr-qr-code-fill`.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"image","description":"Safe media URL for an optional centered logo/image.\n\nType: `string | null`  \nDefault: `null`"},{"name":"image-background","description":"Optional CSS color painted behind the centered image and its padding.\n\nType: `string | null`  \nDefault: `null`"},{"name":"image-coverage","description":"Fraction of the QR canvas side available to the embedded image, clamped to `[0, 1]`.\n\nType: `number | null`  \nDefault: `null`"},{"name":"image-padding","description":"CSS-pixel padding inside the embedded image's coverage box, clamped to fit.\n\nType: `number | null`  \nDefault: `null`"},{"name":"label","description":"Accessible-name fallback when the host has no `aria-label`; otherwise falls back to `value`\n-- see the class doc\ncomment for the full precedence order. Caller-supplied data, not routed through `localize()`.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"radius","description":"Per-module corner radius, as a fraction of one module's side length -- `0` (default) for\nsquare modules, `0.5` for fully round/pill modules. Clamped to `[0, 0.5]`.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"size","description":"CSS-px side length of the square canvas, clamped to `[1, 2048]`.\n\nType: `number`  \nDefault: `128`","value":{"type":["number"]}},{"name":"value","description":"The data to encode. Empty renders `[part=\"empty\"]` -- no encode is attempted.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"js":{"properties":[{"name":"background","description":"Upstream-compatible canvas-background color. A non-empty value takes precedence over host\n`background-color` and `--lr-qr-code-background`.\n\nAttribute: `background`","type":"string","default":"''"},{"name":"canvas","description":"The stable canvas used for QR paint. The same node remains reachable across empty, loading,\nready, error, reconnect, and redraw transitions. Readonly: an explicit `get` (rather than\n`@query`) so the generated manifest marks it non-assignable.","type":"HTMLCanvasElement","read-only":true},{"name":"errorCorrection","description":"QR error-correction level. Normalized (upper-cased, validated against `L`/`M`/`Q`/`H`,\nfalling back to `H`) on every assignment, attribute or property, so it's never a transient\ngarbage value.\n\nAttribute: `error-correction`","type":"LyraQrCodeErrorCorrection","default":"'H'"},{"name":"fill","description":"Upstream-compatible foreground-module color. A non-empty value takes precedence over host\n`color` and `--lr-qr-code-fill`.\n\nAttribute: `fill`","type":"string","default":"''"},{"name":"image","description":"Safe media URL for an optional centered logo/image.\n\nAttribute: `image`","type":"string | null","default":"null"},{"name":"imageBackground","description":"Optional CSS color painted behind the centered image and its padding.\n\nAttribute: `image-background`","type":"string | null","default":"null"},{"name":"imageCoverage","description":"Fraction of the QR canvas side available to the embedded image, clamped to `[0, 1]`.\n\nAttribute: `image-coverage`","type":"number | null","default":"null"},{"name":"imagePadding","description":"CSS-pixel padding inside the embedded image's coverage box, clamped to fit.\n\nAttribute: `image-padding`","type":"number | null","default":"null"},{"name":"label","description":"Accessible-name fallback when the host has no `aria-label`; otherwise falls back to `value`\n-- see the class doc\ncomment for the full precedence order. Caller-supplied data, not routed through `localize()`.\n\nAttribute: `label`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"radius","description":"Per-module corner radius, as a fraction of one module's side length -- `0` (default) for\nsquare modules, `0.5` for fully round/pill modules. Clamped to `[0, 0.5]`.\n\nAttribute: `radius`","type":"number","default":"0"},{"name":"size","description":"CSS-px side length of the square canvas, clamped to `[1, 2048]`.\n\nAttribute: `size`","type":"number","default":"128"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"value","description":"The data to encode. Empty renders `[part=\"empty\"]` -- no encode is attempted.\n\nAttribute: `value`","type":"string","default":"''"}]}},{"name":"lr-radar-chart","description":"`<lr-radar-chart>` — `<lr-chart>` with a `\"radar\"` default and the mirrored writable type.\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) | An optional `<script type=\"application/json\">` containing a Chart.js configuration. |\n| `center` | Optional overlay content positioned at the chart area's center. Useful for doughnut and pie totals. |\n| `data-table` | An optional consumer-provided accessible table alternative. Use this escape hatch for a complete paginated or virtualized alternative when the generated 1,000-record sample is insufficient. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The chart wrapper. |\n| `canvas` | The Chart.js canvas. |\n| `center` | The chart-area-centered overlay wrapper for the `center` slot. |\n| `data-table` | The optional generated or slotted data table. |\n| `data-table-toggle` | The disclosure button rendered by `dataTableToggle`. |\n| `data-truncation` | Explanation shown when the generated accessible alternative samples a data set larger than its 1,000-record ceiling. |\n| `description` | The accessible chart summary. |\n| `error` | Static visible error shown instead of `canvas` when the optional `chart.js` peer dependency is not installed; its transition is announced through a shared light-DOM alert. |\n| `feature-warning` | Static nonfatal warning when a requested optional feature peer is unavailable while the core chart remains usable. |\n| `legend` | The wrapping DOM legend, rendered unless `withoutLegend` is set. |\n| `legend-item` | A keyboard-operable dataset or category visibility toggle. |\n| `legend-item-hidden` | Added while the legend item's dataset or category is hidden. |\n| `legend-swatch` | The resolved dataset/category color swatch in a legend item. |\n| `notices` | Wrapper for nonfatal feature warnings and generated-data truncation notices. |\n| `plot` | The fixed-height canvas/overlay region. |\n| `reset-zoom-button` | The reset-zoom control when zoom is active. |\n\n---\n\n**CSS Custom Properties**\n\n- `--border-color-1` (default: `var(--lr-color-chart-1)`) — First dataset border color.\n- `--border-color-2` (default: `var(--lr-color-chart-2)`) — Second dataset border color.\n- `--border-color-3` (default: `var(--lr-color-chart-3)`) — Third dataset border color.\n- `--border-color-4` (default: `var(--lr-color-chart-4)`) — Fourth dataset border color.\n- `--border-color-5` (default: `var(--lr-color-chart-5)`) — Fifth dataset border color.\n- `--border-color-6` (default: `var(--lr-color-chart-6)`) — Sixth dataset border color.\n- `--border-radius` (default: `var(--lr-radius)`) — Dataset element corner radius.\n- `--border-width` (default: `var(--lr-border-width-thin)`) — Dataset element border width.\n- `--fill-color-1` (default: `var(--lr-color-chart-1)`) — First dataset fill color.\n- `--fill-color-2` (default: `var(--lr-color-chart-2)`) — Second dataset fill color.\n- `--fill-color-3` (default: `var(--lr-color-chart-3)`) — Third dataset fill color.\n- `--fill-color-4` (default: `var(--lr-color-chart-4)`) — Fourth dataset fill color.\n- `--fill-color-5` (default: `var(--lr-color-chart-5)`) — Fifth dataset fill color.\n- `--fill-color-6` (default: `var(--lr-color-chart-6)`) — Sixth dataset fill color.\n- `--grid-border-width` (default: `var(--lr-border-width-thin)`) — Axis and grid line width.\n- `--grid-color` (default: `var(--lr-chart-grid-color)`) — Grid line color.\n- `--line-border-width` (default: `var(--lr-border-width-medium)`) — Line dataset stroke width.\n- `--lr-chart-canvas-hover-outline-color` (default: `var(--lr-chart-grid-color)`) — Color of the `[part='canvas']` hover-state outline.\n- `--lr-chart-canvas-hover-outline-width` (default: `var(--lr-border-width-thin)`) — Width of the `[part='canvas']` hover-state outline.\n- `--lr-chart-data-table-button-active-bg` — Pressed background of an actionable generated- table value; defaults to the standard active mix of `--lr-color-brand-quiet`.\n- `--lr-chart-data-table-button-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background of an actionable generated-table value.\n- `--lr-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-chart-data-table-toggle-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background of the `dataTableToggle` disclosure button.\n- `--lr-chart-grid-color` (default: `var(--lr-color-border)`) — Grid-line color. Resolved via `getComputedStyle` on every draw (Chart.js paints to canvas and cannot consume `var()`).\n- `--lr-chart-height` (default: `var(--lr-size-280px)`) — The plot region's `block-size` and the host's minimum block size. A visible data table or wrapping DOM legend grows the host in normal flow instead of overlapping following content. `height` supplies a private fallback; this public token always wins when a consumer sets it.\n- `--lr-chart-legend-color` (default: `var(--lr-color-text)`) — Legend label color. Resolved via `getComputedStyle` on every draw.\n- `--lr-chart-legend-item-active-bg` — Pressed background of a legend visibility button; defaults to the standard active mix of `--lr-color-brand-quiet`.\n- `--lr-chart-legend-item-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background of a legend visibility button.\n- `--lr-chart-legend-side-max` (default: `var(--lr-size-15rem)`) — Maximum inline size reserved for a side-positioned DOM legend; the track is also capped at one third of the chart allocation.\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 every series collapses to one system color and the stripe/crosshatch pattern 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.\n- `--lr-chart-reset-zoom-button-active-bg` — Pressed background of the reset-zoom button; defaults to the standard active mix of `--lr-color-brand-quiet`.\n- `--lr-chart-reset-zoom-button-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background of the reset-zoom button.\n- `--lr-chart-tick-color` (default: `var(--lr-color-text-quiet)`) — Axis tick-label color; also used for the `xLabel`/`yLabel`/`y2Label` axis-title text (there is no separate title-color token). Resolved via `getComputedStyle` on every draw.\n- `--lr-chart-tick-font-size` (default: `var(--lr-font-size-xs)`) — Axis tick-label font size, in any CSS length unit. Defaults to `--lr-font-size-xs` (12px at the standard root) because that matches Chart.js's OWN built-in tick font size, which is what every canvas chart rendered before this token existed -- leaving it unset must stay byte-identical to that, not shrink to `<lr-lite-chart>`'s SVG default. Also sizes the radar/polarArea `r`-scale `pointLabels` (the spoke labels), but ONLY once set: those default separately to Chart.js's OWN distinct `RadialLinearScale` `pointLabels` default (10px, not this token's 12px), and only adopt this token's size once the consumer explicitly sets it, at which point ticks and point labels match. Resolved via `getComputedStyle` on every draw, same constraint as every other `--lr-chart-*` token here (Chart.js paints to canvas and cannot consume `var()`).\n- `--lr-chart-tooltip-bg` (default: `var(--lr-color-surface)`) — Tooltip background color. Resolved via `getComputedStyle` on every draw.\n- `--lr-chart-tooltip-text` (default: `var(--lr-color-text)`) — Tooltip text color. Resolved via `getComputedStyle` on every draw.\n- `--point-radius` (default: `var(--lr-space-2xs)`) — Line/scatter point radius.","attributes":[{"name":"area","description":"Chart-wide default fill-under-line setting for line-type series; a series's own `LyraChartSeries.fill` overrides it.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"axes","description":"Complete cartesian axis visibility, independent of grid. `y` also controls the y2 axis.\nRadial charts ignore this setting. Explicit config scale options retain precedence.\n\nType: `LyraChartAxes`  \nDefault: `'both'`","value":{"type":["'x'","'y'","'both'","'none'"]}},{"name":"begin-at-zero","description":"Type: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"compact","description":"Compact cartesian plot: hide axes and remove automatic layout padding. Set height and\nwithoutLegend for a small histogram/sparkline. Preserves data tables, tooltips and keyboard\nactions; radial charts ignore this setting. Explicit config options retain precedence.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"data-labels","description":"Draws each data point's value on the chart via the optional\n`chartjs-plugin-datalabels` peer. Unset (the default) leaves labels off for\nthis chart; the peer is attached only to instances that opt in, and\n`buildConfig()` keeps its per-chart options disabled until this is set. The\nscreen-reader equivalent is the always-present data table (see\n`show-data-table`); labels are a purely visual, canvas-only addition.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"data-table-toggle","description":"Render a disclosure button above the accessible data table so a sighted reader can reveal the\nnumbers behind the chart on demand. `showDataTable` alone is all-or-nothing -- the table is\neither permanently screen-reader-only or permanently visible -- which left a consumer wrapping\na duplicated table in their own `<details>`.\n\nWith this set, `showDataTable` becomes the disclosure's *initial* state rather than its whole\nbehavior. The table stays in the DOM in both states, so assistive technology never loses it.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"description","description":"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`"},{"name":"grid","description":"Controls which cartesian grid axes are drawn.\n\nType: `LyraChartGrid`  \nDefault: `'both'`","value":{"type":["'x'","'y'","'both'","'none'"]}},{"name":"height","description":"Type: `string`  \nDefault: `'280px'`","value":{"type":["string"]}},{"name":"index-axis","description":"Chart.js index axis. `'y'` is Chart.js's own mechanism for horizontal bars (it also flips\nline/area types onto a horizontal category axis).\n\nType: `LyraChartIndexAxis`  \nDefault: `'x'`","value":{"type":["'x'","'y'"]}},{"name":"label","description":"Accessible chart label. A host `aria-label` still has highest precedence.\n\nType: `string | null`  \nDefault: `null`"},{"name":"legend-display","description":"`auto` retains optional legend formatting; `label` omits values even with a formatter; `value`\nappends a formatted value. `percentage` uses locale percentages of the absolute represented\nlegend values, including hidden items (zero totals yield 0%). `value-percentage` appends both,\nas `label: value (percentage)`. Dataset values are sampled sums; category values come from the\nfirst dataset. The `formatter`/`valueFormatter` callback backing `value` and `value-percentage`\nadditionally receives that same `percentage` in its `surface: 'legend'` context, so a custom\nformatter can build its own combined text without recomputing the share. Tooltip and axis\nformatting are unchanged.\n\nType: `LyraChartLegendDisplay`  \nDefault: `'auto'`","value":{"type":["'auto'","'label'","'value'","'percentage'","'value-percentage'"]}},{"name":"legend-mode","description":"`datum` renders category toggles for pie/doughnut/polar-area charts. Categories use the first\ndataset's colors and values; a toggle affects that category in every ring. Other chart types\nretain dataset legends. `auto` (the default) resolves to `datum` on pie/doughnut/polar-area\ncharts -- where a single-dataset legend would otherwise enumerate one entry for the whole\ndataset instead of one per visible slice -- and to `dataset` everywhere else. `dataset` always\nforces the dataset legend, even on a slice chart. Both non-`auto` modes use the generated\naccessible-data sampling budget.\n\nType: `LyraChartLegendMode`  \nDefault: `'auto'`","value":{"type":["'auto'","'dataset'","'datum'"]}},{"name":"legend-position","description":"Legend placement. `auto` uses a right legend above 480px and a bottom legend below it.\n\nType: `LyraChartLegendPosition`  \nDefault: `'top'`","value":{"type":["'left'","'top'","'right'","'bottom'","'center'","'chartArea'","'start'","'end'","'auto'"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max","description":"Maximum value-axis bound. Non-finite values are ignored.\n\nType: `number | null`  \nDefault: `null`"},{"name":"min","description":"Minimum value-axis bound. Non-finite values are ignored.\n\nType: `number | null`  \nDefault: `null`"},{"name":"plugins","description":"Chart.js plugins attached to this chart instance. Valid plugins retain their opaque identity.\n\nType: `readonly LyraChartPlugin[]`  \nDefault: `[]`"},{"name":"scale-type","description":"Scale type for the **value** axis (the categorical axis is unaffected). `'logarithmic'` plots\na dataset spanning several orders of magnitude honestly, where a linear axis collapses\neverything below the maximum into the baseline. Inherited by `lr-line-chart`,\n`lr-scatter-chart` and `lr-bar-chart`.\n\nA logarithmic axis cannot represent zero or negative values (`log(0)` is `-Infinity`), so\n`beginAtZero` is not forwarded in that mode -- Chart.js would otherwise be handed a bound it\ncannot place. Non-positive data points are dropped by Chart.js's own log scale.\n\nType: `LyraChartScaleType`  \nDefault: `'linear'`","value":{"type":["'linear'","'logarithmic'"]}},{"name":"show-data-table","description":"Makes the generated data table visible; it remains screen-reader available when false.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"stack-totals","description":"When the chart is `stacked` (bar/line only), draws the per-category stack\ntotal above each stack, via the same optional `chartjs-plugin-datalabels`\npeer as `data-labels`. Null/undefined points are skipped; a category whose\nevery value is null shows no total. The generated accessible data table\nreceives the same formatted total column (one per value axis). Unset (the\ndefault) draws and adds nothing.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"stacked","description":"Stacks the `x`/`y`(/`y2`) scale entries `buildScales()` returns; only meaningful for `bar` and `line` types.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"type","description":"Type: `LyraChartType`  \nDefault: `'radar'`","value":{"type":["'line'","'bar'","'scatter'","'pie'","'doughnut'","'radar'","'polarArea'","'bubble'"]}},{"name":"without-animation","description":"Disables Chart.js animation.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"without-legend","description":"Hides the legend.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"without-tooltip","description":"Hides Chart.js tooltips.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"x-label","description":"Type: `string | null`  \nDefault: `null`"},{"name":"y-label","description":"Type: `string | null`  \nDefault: `null`"},{"name":"y2-label","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"zoom","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"","description":"An optional `<script type=\"application/json\">` containing a Chart.js configuration."},{"name":"center","description":"Optional overlay content positioned at the chart area's center. Useful for doughnut and pie totals."},{"name":"data-table","description":"An optional consumer-provided accessible table alternative. Use this escape hatch for a complete paginated or virtualized alternative when the generated 1,000-record sample is insufficient."}],"js":{"properties":[{"name":"annotations","description":"Declarative reference lines and shaded bands — a threshold, an event year, a regime change, a\nhighlighted period. Each entry marks either a single `value` or a `from`/`to` range on `axis`\n(default `'y'`), with an optional `label` and semantic `tone`.\n\nNeeds the optional `chartjs-plugin-annotation` peer, loaded on first actual demand so a page\nwith no annotated charts never downloads it. The plugin is registered globally, like\n`chartjs-plugin-zoom` and unlike `chartjs-plugin-datalabels`: it draws nothing unless a chart\nsupplies annotation options, so the registration is unobservable to charts that set none, and\nregistration is also what installs the plugin's own element defaults. Without the peer\ninstalled the chart still renders; a console warning plus a localized visible warning and\nlight-DOM announcement explain the no-op — the same fail-closed contract `data-labels` uses.\n\nEntries are included in the generated accessible description, mirroring `lr-heatmap`.","type":"readonly LyraChartAnnotation[]","default":"[]"},{"name":"area","description":"Chart-wide default fill-under-line setting for line-type series; a series's own `LyraChartSeries.fill` overrides it.\n\nAttribute: `area`","type":"boolean","default":"false"},{"name":"axes","description":"Complete cartesian axis visibility, independent of grid. `y` also controls the y2 axis.\nRadial charts ignore this setting. Explicit config scale options retain precedence.\n\nAttribute: `axes`","type":"LyraChartAxes","default":"'both'"},{"name":"beginAtZero","description":"Attribute: `begin-at-zero`","type":"boolean","default":"true"},{"name":"chart","description":"The current Chart.js instance. Read it only while the element is connected and loaded.","type":"LyraChartInstance | undefined"},{"name":"chartArea","description":"The current Chart.js chart-area geometry in canvas-local coordinates. Read-only -- derived\nfrom the live Chart.js instance's own layout pass, never assignable. The setter is a\ndocumented no-op (matching `lr-histogram`'s `labels`/`datasets` pattern) so an accidental\n`.chartArea=${x}` Lit template binding degrades silently instead of throwing from inside\nlit-html's property-commit.","type":"LyraChartArea | undefined"},{"name":"compact","description":"Compact cartesian plot: hide axes and remove automatic layout padding. Set height and\nwithoutLegend for a small histogram/sparkline. Preserves data tables, tooltips and keyboard\nactions; radial charts ignore this setting. Explicit config options retain precedence.\n\nAttribute: `compact`","type":"boolean","default":"false"},{"name":"config","type":"LyraChartConfiguration | undefined"},{"name":"dataLabels","description":"Draws each data point's value on the chart via the optional\n`chartjs-plugin-datalabels` peer. Unset (the default) leaves labels off for\nthis chart; the peer is attached only to instances that opt in, and\n`buildConfig()` keeps its per-chart options disabled until this is set. The\nscreen-reader equivalent is the always-present data table (see\n`show-data-table`); labels are a purely visual, canvas-only addition.\n\nAttribute: `data-labels`","type":"boolean","default":"false"},{"name":"dataTableToggle","description":"Render a disclosure button above the accessible data table so a sighted reader can reveal the\nnumbers behind the chart on demand. `showDataTable` alone is all-or-nothing -- the table is\neither permanently screen-reader-only or permanently visible -- which left a consumer wrapping\na duplicated table in their own `<details>`.\n\nWith this set, `showDataTable` becomes the disclosure's *initial* state rather than its whole\nbehavior. The table stays in the DOM in both states, so assistive technology never loses it.\n\nAttribute: `data-table-toggle`","type":"boolean","default":"false"},{"name":"datasets","description":"Simplified chart series. Non-record entries are dropped while valid sibling series remain.","type":"readonly LyraChartSeries[]"},{"name":"description","description":"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\nAttribute: `description`","type":"string | null","default":"null"},{"name":"formatter","description":"Unified context-object formatter for visual, tooltip, table/export, and spoken values.","type":"LyraChartFormatter | undefined"},{"name":"grid","description":"Controls which cartesian grid axes are drawn.\n\nAttribute: `grid`","type":"LyraChartGrid","default":"'both'"},{"name":"height","description":"Attribute: `height`","type":"string","default":"'280px'"},{"name":"hiddenDatasets","description":"Complete controlled visibility state for DOM legend toggles. `undefined` (the default) honors\neach effective dataset's `hidden` configuration; a defined array wins over those defaults, and\nan empty array deliberately makes every dataset visible. Invalid, duplicate, and out-of-range\nindexes are ignored when state is applied or emitted.","type":"readonly number[] | undefined"},{"name":"hiddenDatums","description":"Controlled hidden source category indexes for pie/doughnut/polar-area charts, shared by all\ndatasets/rings. Clone-owned; invalid, duplicate and out-of-range indexes are ignored when\napplied or emitted. Empty restores all categories. Does not alter dataset visibility or exports.","type":"readonly number[]","default":"[]"},{"name":"indexAxis","description":"Chart.js index axis. `'y'` is Chart.js's own mechanism for horizontal bars (it also flips\nline/area types onto a horizontal category axis).\n\nAttribute: `index-axis`","type":"LyraChartIndexAxis","default":"'x'"},{"name":"label","description":"Accessible chart label. A host `aria-label` still has highest precedence.\n\nAttribute: `label`","type":"string | null","default":"null"},{"name":"labels","type":"string[]","default":"[]"},{"name":"legendDisplay","description":"`auto` retains optional legend formatting; `label` omits values even with a formatter; `value`\nappends a formatted value. `percentage` uses locale percentages of the absolute represented\nlegend values, including hidden items (zero totals yield 0%). `value-percentage` appends both,\nas `label: value (percentage)`. Dataset values are sampled sums; category values come from the\nfirst dataset. The `formatter`/`valueFormatter` callback backing `value` and `value-percentage`\nadditionally receives that same `percentage` in its `surface: 'legend'` context, so a custom\nformatter can build its own combined text without recomputing the share. Tooltip and axis\nformatting are unchanged.\n\nAttribute: `legend-display`","type":"LyraChartLegendDisplay","default":"'auto'"},{"name":"legendMode","description":"`datum` renders category toggles for pie/doughnut/polar-area charts. Categories use the first\ndataset's colors and values; a toggle affects that category in every ring. Other chart types\nretain dataset legends. `auto` (the default) resolves to `datum` on pie/doughnut/polar-area\ncharts -- where a single-dataset legend would otherwise enumerate one entry for the whole\ndataset instead of one per visible slice -- and to `dataset` everywhere else. `dataset` always\nforces the dataset legend, even on a slice chart. Both non-`auto` modes use the generated\naccessible-data sampling budget.\n\nAttribute: `legend-mode`","type":"LyraChartLegendMode","default":"'auto'"},{"name":"legendPosition","description":"Legend placement. `auto` uses a right legend above 480px and a bottom legend below it.\n\nAttribute: `legend-position`","type":"LyraChartLegendPosition","default":"'top'"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"max","description":"Maximum value-axis bound. Non-finite values are ignored.\n\nAttribute: `max`","type":"number | null","default":"null"},{"name":"min","description":"Minimum value-axis bound. Non-finite values are ignored.\n\nAttribute: `min`","type":"number | null","default":"null"},{"name":"plugins","description":"Chart.js plugins attached to this chart instance. Valid plugins retain their opaque identity.\n\nAttribute: `plugins`","type":"readonly LyraChartPlugin[]","default":"[]"},{"name":"scaleType","description":"Scale type for the **value** axis (the categorical axis is unaffected). `'logarithmic'` plots\na dataset spanning several orders of magnitude honestly, where a linear axis collapses\neverything below the maximum into the baseline. Inherited by `lr-line-chart`,\n`lr-scatter-chart` and `lr-bar-chart`.\n\nA logarithmic axis cannot represent zero or negative values (`log(0)` is `-Infinity`), so\n`beginAtZero` is not forwarded in that mode -- Chart.js would otherwise be handed a bound it\ncannot place. Non-positive data points are dropped by Chart.js's own log scale.\n\nAttribute: `scale-type`","type":"LyraChartScaleType","default":"'linear'"},{"name":"showDataTable","description":"Makes the generated data table visible; it remains screen-reader available when false.\n\nAttribute: `show-data-table`","type":"boolean","default":"false"},{"name":"stackTotals","description":"When the chart is `stacked` (bar/line only), draws the per-category stack\ntotal above each stack, via the same optional `chartjs-plugin-datalabels`\npeer as `data-labels`. Null/undefined points are skipped; a category whose\nevery value is null shows no total. The generated accessible data table\nreceives the same formatted total column (one per value axis). Unset (the\ndefault) draws and adds nothing.\n\nAttribute: `stack-totals`","type":"boolean","default":"false"},{"name":"stacked","description":"Stacks the `x`/`y`(/`y2`) scale entries `buildScales()` returns; only meaningful for `bar` and `line` types.\n\nAttribute: `stacked`","type":"boolean","default":"false"},{"name":"stackedAxes","description":"Per-value-axis override of `stacked`, keyed by `'y'`/`'y2'`. An axis absent from this record\n-- including every axis when the whole property is unset -- falls back to the chart-wide\n`stacked` value, which is what keeps a chart that never sets this byte-identical to before.\nLets a `stacked` bar series on the primary axis sit next to an unstacked overlay series on\n`y2` (via `LyraChartSeries.axis: 'y2'`): set `stackedAxes` to `{ y2: false }` alongside\n`stacked`, or spell out both axes explicitly. The shared categorical axis (`x` for a vertical\nbar/line, or `y` when `indexAxis` is `'y'`) has no independent entry of its own -- it always\nmirrors the resolved `'y'` value, matching Chart.js's own paired index/value-scale stacking\ncontract. Only meaningful for `bar`/`line` types, matching `stacked` itself.","type":"Partial<Record<'y' | 'y2', boolean>> | undefined"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"tooltipFooterFormatter","description":"Tooltip footer formatter -- e.g. a category's stack total under the items. Receives every\nitem the hovered tooltip covers, in the same shape as `tooltipTitleFormatter`. Unset (the\ndefault) leaves Chart.js's own default (no footer).","type":"LyraChartTooltipGroupFormatter | undefined"},{"name":"tooltipTitleFormatter","description":"Tooltip title formatter -- e.g. a scatter point's own name. Receives every item the hovered\ntooltip covers, each in `formatter`'s `'tooltip'`-surface context shape. Unset (the default)\nleaves Chart.js's own default title (the shared category label) in place.","type":"LyraChartTooltipGroupFormatter | undefined"},{"name":"type","description":"Attribute: `type`","type":"LyraChartType","default":"'radar'"},{"name":"valueFormatter","description":"Formats numeric (value-axis) ticks, tooltip values, legend values, and generated accessible\ntable cells from one callback.\nHorizontal scalar tooltips use parsed x, including a raw config indexAxis override;\nstructured points retain their y-value contract. The context-object formatter shares this rule.\nNever runs against the categorical x-axis's own labels (line/bar's `labels` strings) —\nChart.js's category scale passes the tick index to `ticks.callback`, not the label text,\nso formatting it would corrupt the axis.","type":"LyraChartValueFormatter | undefined"},{"name":"withoutAnimation","description":"Disables Chart.js animation.\n\nAttribute: `without-animation`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"withoutLegend","description":"Hides the legend.\n\nAttribute: `without-legend`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"withoutTooltip","description":"Hides Chart.js tooltips.\n\nAttribute: `without-tooltip`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"xLabel","description":"Attribute: `x-label`","type":"string | null","default":"null"},{"name":"y2Label","description":"Attribute: `y2-label`","type":"string","default":"''"},{"name":"yLabel","description":"Attribute: `y-label`","type":"string | null","default":"null"},{"name":"zoom","description":"Attribute: `zoom`","type":"boolean","default":"false"}],"events":[{"name":"lr-before-datum-visibility-change","description":"Cancelable category visibility proposal in datum legend mode. `detail: { index: number, visible: boolean, hiddenDatums: readonly number[] }`. Source category indexes apply to every dataset/ring. The complete detail is frozen.","type":"CustomEvent<LyraChartDatumVisibilityChangeDetail>"},{"name":"lr-before-legend-visibility-change","description":"Cancelable proposal emitted before a DOM legend toggle changes state. `detail` contains the target `datasetIndex`, its proposed `visible` value, and the complete canonical proposed `hiddenDatasets` snapshot.","type":"CustomEvent<LyraChartLegendVisibilityChangeDetail>"},{"name":"lr-datum-activate","description":"Family-normalized activation event. Its detail adds `kind` (`bar`, `point`, `segment`, or `slice`) to the `lr-point-click` detail.","type":"CustomEvent<\n    LyraChartDatumActivateDetail<LyraCoreChartDatumKind>\n  >"},{"name":"lr-datum-visibility-change","description":"Emitted after an accepted category toggle commits the same frozen detail. Programmatic `hiddenDatums` assignments are silent.","type":"CustomEvent<LyraChartDatumVisibilityChangeDetail>"},{"name":"lr-legend-visibility-change","description":"Emitted after an accepted DOM legend toggle commits the same detail. Programmatic `hiddenDatasets` changes reconcile without either event.","type":"CustomEvent<LyraChartLegendVisibilityChangeDetail>"},{"name":"lr-point-click","description":"Fired when pointer input lands on a data point/segment, when a generated data-table value is activated, or when Enter/Space activates the keyboard-current canvas datum. `detail: { datasetIndex: number, index: number, label: string | undefined, value: unknown }`. For scatter/bubble data, `label` prefers the per-point label and `value` is the complete typed `LyraChartPoint` (`x`, `y`, optional `r`, optional `label`).","type":"CustomEvent<{\n    datasetIndex: number;\n    index: number;\n    label: string | undefined;\n    value: unknown;\n  }>"},{"name":"lr-zoom","description":"`detail: { zoomed }`.","type":"CustomEvent<{ zoomed: boolean }>"}]}},{"name":"lr-radio","description":"`<lr-radio>` — a form-associated single-choice control. Radios can be used\nalone or inside `<lr-radio-group>`.\n\nDeliberately no hint/error chrome of its own -- the default slot already carries real, visible\nlabel text (see `@slot` below), so a labeled-field frame built around `label`/`hint`/`errorText`\nprops has nothing to add here. A consumer needing shared hint/error messaging for a set of\noptions composes it once on the owning `<lr-radio-group>` (which does carry `hint`/`errorText`),\nthe same way a native radio `<fieldset>`/`<legend>` pairs with one externally-owned error node\nshared across all its `<input type=\"radio\">` children rather than one per option.\nFlattened forwarding-slot changes keep the visual label wrapper synchronized; element-only and\ndecorative `aria-hidden` visuals still count as visual content. A host `aria-label` retains\naccessible-name precedence by presence, including an explicitly empty value.\nA standalone radio is bounded by its allocation: an unbroken default label wraps within the\navailable inline size in both LTR and RTL while the circular indicator remains fixed.\nIn `appearance=\"button\"`, the same `start`/`prefix` and `end`/`suffix` adornment aliases as\n`<lr-radio-button>` render around the label. Empty leading, label, and trailing wrappers stay\nhidden so only present content contributes the button's flex gaps.\n\nHost `aria-describedby` references resolve onto the internal radio, including button appearance,\nand track live target changes, reconnect and document adoption. Explicit `checked` assignments\nmark live state dirty even when unchanged; later default changes affect live state only after reset.\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) | Label content, including forwarded or element-only visuals. |\n| `end` | Trailing content in `appearance=\"button\"`. |\n| `prefix` | Shoelace-compatible alias for `start` in `appearance=\"button\"`. |\n| `start` | Leading content in `appearance=\"button\"`, typically an icon. |\n| `suffix` | Shoelace-compatible alias for `end` in `appearance=\"button\"`. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The interactive radio control. |\n| `button` | Shoelace button-chrome alias in `appearance=\"button\"` mode. |\n| `button--checked` | Shoelace selected-button state alias. |\n| `checked-icon` | WA/Shoelace name for the same selected indicator. |\n| `circle` | The circular radio indicator. |\n| `control` | WA/Shoelace name for the indicator, or the interactive button in `appearance=\"button\"`. |\n| `control--checked` | Shoelace state alias on the selected indicator. |\n| `dot` | The selected indicator. |\n| `end` | The `appearance=\"button\"` trailing-content wrapper; hidden while empty. |\n| `label` | The default slot wrapper; hidden while it has no real content. |\n| `prefix` | Shoelace-compatible alias on the same leading-content wrapper. |\n| `start` | The `appearance=\"button\"` leading-content wrapper; hidden while empty. |\n| `suffix` | Shoelace-compatible alias on the same trailing-content wrapper. |\n\n---\n\n**CSS Custom Properties**\n\n- `--checked-icon-color` (default: `var(--lr-radio-checked-dot-color)`) — WA-compatible selected-glyph color alias.\n- `--checked-icon-scale` (default: `1`) — WA-compatible selected-glyph scale alias.\n- `--lr-radio-active-border-color` (default: `var(--lr-radio-hover-border-color)`) — Indicator border while the interactive row is pressed.\n- `--lr-radio-active-ring-color` (default: `var(--lr-color-brand-quiet)`) — Indicator ring while the interactive row is pressed.\n- `--lr-radio-button-gap` (default: `var(--lr-space-xs)`) — Gap between the present start/prefix, label, and end/suffix wrappers in `appearance=\"button\"`.\n- `--lr-radio-checked-border-color` (default: `var(--lr-color-brand)`) — Border color of `[part='circle']` while `checked`. Retint just this control's checked ring without touching the shared `--lr-color-brand` token every other component also reads.\n- `--lr-radio-checked-dot-color` (default: `var(--lr-color-brand)`) — Background of `[part='dot']` while `checked`.\n- `--lr-radio-circle-size` (default: `min(var(--lr-icon-button-size), calc(var(--lr-form-control-height) * 0.7))`) — Edge length of `[part='circle']`. Derived from the `size` tier's shared control height so a radio lines up with an `<lr-input>`/`<lr-select>`/`<lr-button>` of the same `size`.\n- `--lr-radio-dot-size` (default: `min(calc(var(--lr-radio-circle-size) * 0.5), calc(var(--lr-form-control-height) * 0.3))`) — Edge length of `[part='dot']`, capped at half the circle so it can never outgrow its ring.\n- `--lr-radio-hover-border-color` (default: `var(--lr-color-brand)`) — Indicator border while the interactive row is hovered.\n- `--lr-radio-label-indent` (default: `calc(var(--lr-radio-circle-size) + var(--lr-space-s))`) — The inline distance from the control's start edge to the start of the label text, i.e. the circle's own floor plus the gap next to it — so it tracks `size` along with the circle. Published so a consumer composing per-option hint text under the label can align it without re-deriving that formula from the shadow styles, and used as the source of the real gap so the two cannot drift. Setting it on the element (or on `lr-radio` in your own stylesheet) moves the label; because custom properties inherit down and not sideways, it is *not* readable from a sibling node in your tree — align a sibling by computing the same formula from `--lr-theme-icon-button-size`, `--lr-theme-form-control-height-*` and `--lr-theme-space-s`, which you control.\n- `--lr-radio-radius` (default: `var(--lr-radius-pill)`) — Corner radius of the control's own chrome. A circular indicator is fully round at every setting; `<lr-radio-button>` re-points this knob at the shared control radius and swaps it for a pill when `pill` is set.","attributes":[{"name":"appearance","description":"WA-compatible visual mode. `button` keeps the same radio semantics and group ownership.\n\nType: `RadioAppearance`  \nDefault: `'default'`","value":{"type":["'default'","'button'"]}},{"name":"checked","description":"Reflected current reset default; changing it never overwrites dirty live `checked` state.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"custom-error","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nType: `string | null`  \nDefault: `null`"},{"name":"disabled","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"form","description":"Type: `HTMLFormElement | string | null`  \nDefault: `null`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"name","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"pill","description":"Rounds the control's own chrome into a pill instead of the shared control radius. A plain\n`<lr-radio>`'s indicator is a circle at every setting, so this is visible on\n`<lr-radio-button>`, which inherits this class and renders rectangular chrome; it is declared\nhere so both tags carry one property with one meaning.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"required","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"size","description":"Control size, on the library's shared ladder. Accepts both spellings of every tier —\n`2xs`/`xs`/`s`/`m`/`l`/`xl` and Web Awesome's `small`/`medium`/`large` — so migrating either way\nis a tag rename. Scales the indicator off the same `--lr-form-control-*` values\n`<lr-input>`/`<lr-select>`/`<lr-button>` use, so controls of one `size` line up in a row. The\nslotted label keeps the library's standard control-label type size at every tier; restyle it\nthrough `::part(label)` if you want it to track the control. An owning group exposes its\nprojected tier through `effectiveSize` without overwriting this authored property; likewise,\n`effectiveName` reports aggregate name authority without rewriting `name`.\n\nType: `LyraSize`  \nDefault: `'m'`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}},{"name":"value","description":"Type: `string`","value":{"type":["string"]}}],"slots":[{"name":"","description":"Label content, including forwarded or element-only visuals."},{"name":"end","description":"Trailing content in `appearance=\"button\"`."},{"name":"prefix","description":"Shoelace-compatible alias for `start` in `appearance=\"button\"`."},{"name":"start","description":"Leading content in `appearance=\"button\"`, typically an icon."},{"name":"suffix","description":"Shoelace-compatible alias for `end` in `appearance=\"button\"`."}],"js":{"properties":[{"name":"appearance","description":"WA-compatible visual mode. `button` keeps the same radio semantics and group ownership.\n\nAttribute: `appearance`  \nReflected to its attribute.","type":"RadioAppearance","default":"'default'"},{"name":"checked","description":"Attribute: `checked`","type":"boolean","default":"false"},{"name":"customError","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nAttribute: `custom-error`  \nReflected to its attribute.","type":"string | null","default":"null"},{"name":"defaultChecked","description":"Reflected current reset default; changing it never overwrites dirty live `checked` state.\n\nAttribute: `checked`  \nReflected to its attribute.","type":"boolean"},{"name":"disabled","description":"Attribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"effectiveDisabled","type":"boolean","read-only":true},{"name":"effectiveName","description":"Name used by the owning aggregate group without rewriting this option's authored `name`.","type":"string","read-only":true},{"name":"effectiveRequired","type":"boolean","read-only":true},{"name":"effectiveSize","description":"Size projected by the owning group without rewriting this option's authored `size`.","type":"LyraSize","read-only":true},{"name":"form","description":"Attribute: `form`  \nReflected to its attribute.","type":"HTMLFormElement | string | null","default":"null"},{"name":"labels","type":"NodeList","read-only":true},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"name","description":"Attribute: `name`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"pill","description":"Rounds the control's own chrome into a pill instead of the shared control radius. A plain\n`<lr-radio>`'s indicator is a circle at every setting, so this is visible on\n`<lr-radio-button>`, which inherits this class and renders rectangular chrome; it is declared\nhere so both tags carry one property with one meaning.\n\nAttribute: `pill`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"required","description":"Attribute: `required`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"size","description":"Control size, on the library's shared ladder. Accepts both spellings of every tier —\n`2xs`/`xs`/`s`/`m`/`l`/`xl` and Web Awesome's `small`/`medium`/`large` — so migrating either way\nis a tag rename. Scales the indicator off the same `--lr-form-control-*` values\n`<lr-input>`/`<lr-select>`/`<lr-button>` use, so controls of one `size` line up in a row. The\nslotted label keeps the library's standard control-label type size at every tier; restyle it\nthrough `::part(label)` if you want it to track the control. An owning group exposes its\nprojected tier through `effectiveSize` without overwriting this authored property; likewise,\n`effectiveName` reports aggregate name authority without rewriting `name`.\n\nAttribute: `size`  \nReflected to its attribute.","type":"LyraSize","default":"'m'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"validationMessage","type":"string","read-only":true},{"name":"validity","type":"ValidityState","read-only":true},{"name":"value","description":"Attribute: `value`  \nReflected to its attribute.","type":"string"},{"name":"willValidate","type":"boolean","read-only":true}],"events":[{"name":"blur","description":"The internal radio lost focus.","type":"FocusEvent"},{"name":"change","description":"A standalone radio was selected; native-style and composed.","type":"Event"},{"name":"focus","description":"The internal radio received focus.","type":"FocusEvent"},{"name":"input","description":"A standalone radio was selected; native-style and composed.","type":"Event"},{"name":"lr-change","description":"Standalone prefixed compatibility alias for `change`. `detail: { checked, value }`. An owning radio group emits its aggregate value-event sequence instead of any child value events.","type":"CustomEvent<{ checked: boolean; value: string }>"},{"name":"lr-input","description":"Standalone prefixed compatibility alias for `input`. `detail: { checked, value }`.","type":"CustomEvent<{ checked: boolean; value: string }>"},{"name":"lr-invalid","description":"The standalone radio failed a validity check. Aggregate groups emit their own alias instead. Cancelable: calling `preventDefault()` also cancels the native `invalid` event behind it, suppressing the browser's own validation bubble so an app can present the failure its own way.","type":"CustomEvent<null>"}]}},{"name":"lr-radio-button","description":"`<lr-radio-button>` — a single-choice control rendered as a button rather than a circle.\n\nThe same control as `<lr-radio>`, and deliberately a subclass of it: form association,\nvalidity, `form.reset()` restoration and the whole `<lr-radio-group>` ownership/roving-focus\ncontract are inherited rather than reimplemented, so the two can never drift apart. Only the\nchrome differs. A `<lr-radio-group>` accepts either tag, and the two can be mixed.\n\nAn owning horizontal group collapses borders only for button radios whose rendered boxes are\nactually adjacent on the same flex line. The group's ordinary gap, a plain-radio interruption,\nvertical layout, or wrapping starts a new fully rounded run; live layout and membership changes\nare reconciled after layout in both directions.\nA host `aria-label` is forwarded to the internal `role=\"radio\"` by attribute presence, so an\nexplicitly empty value remains authoritative rather than restoring a label-text fallback.\nStandalone button chrome is bounded by its allocation: unbroken labels wrap, while long\nstart/prefix and end/suffix adornments truncate inside their capped portions instead of widening\nthe page. The leading, label, and trailing wrappers are hidden independently while empty, so a\nmissing region never contributes a dead `--lr-radio-button-gap`.\n\nHost `aria-describedby` references resolve onto the internal radio and track target changes,\nreconnect and document adoption. Equal-value `checked` assignments retain the inherited dirty\nstate contract: later defaults cannot replace the live selection until reset.\n\n---\n\n**Component metadata**\n\n- Status: `stable`\n- Since: `8.0.0`\n- Rationale: This tag entered Lyra as a stable public API with documented behavior, accessibility, and cross-browser support.\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) | Label text. |\n| `end` | Content placed after the label. |\n| `prefix` | Shoelace-compatible alias for `start`, rendered through the same wrapper. |\n| `start` | Content placed before the label, typically an icon. |\n| `suffix` | Shoelace-compatible alias for `end`, rendered through the same wrapper. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The interactive button. Carries `checked` and `disabled` in the part name so a consumer can target either state through `::part()`. Every size tier retains a 24px minimum target in both axes, including an empty-label control. |\n| `button` | Shoelace name for the interactive button. |\n| `button--checked` | Shoelace state alias on the selected button. |\n| `checked-icon` | WA/Shoelace name for the same selected indicator. |\n| `circle` | The circular radio indicator. |\n| `control` | Compatibility alias for the interactive control. |\n| `control--checked` | Shoelace state alias on the selected indicator. |\n| `dot` | The selected indicator. |\n| `end` | The trailing-content wrapper; hidden while both trailing slots are empty. |\n| `label` | The default slot wrapper; hidden while it has no real content. |\n| `prefix` | Shoelace-compatible alias for `start`; both names are on the same wrapper. |\n| `start` | The leading-content wrapper; hidden while both leading slots are empty. |\n| `suffix` | Shoelace-compatible alias for `end`; both names are on the same wrapper. |\n\n---\n\n**CSS Custom Properties**\n\n- `--checked-icon-color` (default: `var(--lr-radio-checked-dot-color)`) — WA-compatible selected-glyph color alias.\n- `--checked-icon-scale` (default: `1`) — WA-compatible selected-glyph scale alias.\n- `--lr-radio-active-border-color` (default: `var(--lr-radio-hover-border-color)`) — Indicator border while the interactive row is pressed.\n- `--lr-radio-active-ring-color` (default: `var(--lr-color-brand-quiet)`) — Indicator ring while the interactive row is pressed.\n- `--lr-radio-button-active-bg` (default: `color-mix(...)`) — Unchecked button background while pressed.\n- `--lr-radio-button-active-border-color` (default: `var(--lr-radio-button-hover-border-color)`) — Unchecked button border while pressed.\n- `--lr-radio-button-checked-active-bg` (default: `color-mix(...)`) — Checked button background while pressed.\n- `--lr-radio-button-checked-active-border-color` (default: `var(--lr-radio-button-checked-hover-border-color)`) — Checked button border while pressed.\n- `--lr-radio-button-checked-bg` (default: `var(--lr-color-brand)`) — Checked button background.\n- `--lr-radio-button-checked-border-color` (default: `var(--lr-color-brand)`) — Checked button border.\n- `--lr-radio-button-checked-color` (default: `var(--lr-color-on-brand)`) — Checked button text color.\n- `--lr-radio-button-checked-hover-bg` (default: `color-mix(...)`) — Checked button background while hovered.\n- `--lr-radio-button-checked-hover-border-color` (default: `var(--lr-radio-button-checked-border-color)`) — Checked button border while hovered.\n- `--lr-radio-button-gap` (default: `var(--lr-space-xs)`) — Gap between the start/prefix wrapper, label, and end/suffix wrapper in both `<lr-radio-button>` and `<lr-radio appearance=\"button\">`.\n- `--lr-radio-button-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Unchecked button background while hovered.\n- `--lr-radio-button-hover-border-color` (default: `var(--lr-color-brand)`) — Unchecked button border while hovered.\n- `--lr-radio-checked-border-color` (default: `var(--lr-color-brand)`) — Border color of `[part='circle']` while `checked`. Retint just this control's checked ring without touching the shared `--lr-color-brand` token every other component also reads.\n- `--lr-radio-checked-dot-color` (default: `var(--lr-color-brand)`) — Background of `[part='dot']` while `checked`.\n- `--lr-radio-circle-size` (default: `min(var(--lr-icon-button-size), calc(var(--lr-form-control-height) * 0.7))`) — Edge length of `[part='circle']`. Derived from the `size` tier's shared control height so a radio lines up with an `<lr-input>`/`<lr-select>`/`<lr-button>` of the same `size`.\n- `--lr-radio-dot-size` (default: `min(calc(var(--lr-radio-circle-size) * 0.5), calc(var(--lr-form-control-height) * 0.3))`) — Edge length of `[part='dot']`, capped at half the circle so it can never outgrow its ring.\n- `--lr-radio-hover-border-color` (default: `var(--lr-color-brand)`) — Indicator border while the interactive row is hovered.\n- `--lr-radio-label-indent` (default: `calc(var(--lr-radio-circle-size) + var(--lr-space-s))`) — The inline distance from the control's start edge to the start of the label text, i.e. the circle's own floor plus the gap next to it — so it tracks `size` along with the circle. Published so a consumer composing per-option hint text under the label can align it without re-deriving that formula from the shadow styles, and used as the source of the real gap so the two cannot drift. Setting it on the element (or on `lr-radio` in your own stylesheet) moves the label; because custom properties inherit down and not sideways, it is *not* readable from a sibling node in your tree — align a sibling by computing the same formula from `--lr-theme-icon-button-size`, `--lr-theme-form-control-height-*` and `--lr-theme-space-s`, which you control.\n- `--lr-radio-radius` (default: `var(--lr-form-control-radius)`) — Corner radius of the outer edges of the button row. Its private default follows the shared control radius and changes to `--lr-radius-pill` for `pill`; an inherited or direct public value still wins.","attributes":[{"name":"appearance","description":"WA-compatible visual mode. `button` keeps the same radio semantics and group ownership.\n\nType: `RadioAppearance`  \nDefault: `'default'`","value":{"type":["'default'","'button'"]}},{"name":"checked","description":"Reflected current reset default; changing it never overwrites dirty live `checked` state.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"custom-error","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nType: `string | null`  \nDefault: `null`"},{"name":"disabled","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"form","description":"Type: `HTMLFormElement | string | null`  \nDefault: `null`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"name","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"pill","description":"Rounds the control's own chrome into a pill instead of the shared control radius. A plain\n`<lr-radio>`'s indicator is a circle at every setting, so this is visible on\n`<lr-radio-button>`, which inherits this class and renders rectangular chrome; it is declared\nhere so both tags carry one property with one meaning.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"required","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"size","description":"Control size, on the library's shared ladder. Accepts both spellings of every tier —\n`2xs`/`xs`/`s`/`m`/`l`/`xl` and Web Awesome's `small`/`medium`/`large` — so migrating either way\nis a tag rename. Scales the indicator off the same `--lr-form-control-*` values\n`<lr-input>`/`<lr-select>`/`<lr-button>` use, so controls of one `size` line up in a row. The\nslotted label keeps the library's standard control-label type size at every tier; restyle it\nthrough `::part(label)` if you want it to track the control. An owning group exposes its\nprojected tier through `effectiveSize` without overwriting this authored property; likewise,\n`effectiveName` reports aggregate name authority without rewriting `name`.\n\nType: `LyraSize`  \nDefault: `'m'`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}},{"name":"value","description":"Type: `string`","value":{"type":["string"]}}],"slots":[{"name":"","description":"Label text."},{"name":"end","description":"Content placed after the label."},{"name":"prefix","description":"Shoelace-compatible alias for `start`, rendered through the same wrapper."},{"name":"start","description":"Content placed before the label, typically an icon."},{"name":"suffix","description":"Shoelace-compatible alias for `end`, rendered through the same wrapper."}],"js":{"properties":[{"name":"appearance","description":"WA-compatible visual mode. `button` keeps the same radio semantics and group ownership.\n\nAttribute: `appearance`  \nReflected to its attribute.","type":"RadioAppearance","default":"'default'"},{"name":"checked","description":"Attribute: `checked`","type":"boolean","default":"false"},{"name":"customError","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nAttribute: `custom-error`  \nReflected to its attribute.","type":"string | null","default":"null"},{"name":"defaultChecked","description":"Reflected current reset default; changing it never overwrites dirty live `checked` state.\n\nAttribute: `checked`  \nReflected to its attribute.","type":"boolean"},{"name":"disabled","description":"Attribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"effectiveDisabled","type":"boolean","read-only":true},{"name":"effectiveName","description":"Name used by the owning aggregate group without rewriting this option's authored `name`.","type":"string","read-only":true},{"name":"effectiveRequired","type":"boolean","read-only":true},{"name":"effectiveSize","description":"Size projected by the owning group without rewriting this option's authored `size`.","type":"LyraSize","read-only":true},{"name":"form","description":"Attribute: `form`  \nReflected to its attribute.","type":"HTMLFormElement | string | null","default":"null"},{"name":"labels","type":"NodeList","read-only":true},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"name","description":"Attribute: `name`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"pill","description":"Rounds the control's own chrome into a pill instead of the shared control radius. A plain\n`<lr-radio>`'s indicator is a circle at every setting, so this is visible on\n`<lr-radio-button>`, which inherits this class and renders rectangular chrome; it is declared\nhere so both tags carry one property with one meaning.\n\nAttribute: `pill`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"required","description":"Attribute: `required`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"size","description":"Control size, on the library's shared ladder. Accepts both spellings of every tier —\n`2xs`/`xs`/`s`/`m`/`l`/`xl` and Web Awesome's `small`/`medium`/`large` — so migrating either way\nis a tag rename. Scales the indicator off the same `--lr-form-control-*` values\n`<lr-input>`/`<lr-select>`/`<lr-button>` use, so controls of one `size` line up in a row. The\nslotted label keeps the library's standard control-label type size at every tier; restyle it\nthrough `::part(label)` if you want it to track the control. An owning group exposes its\nprojected tier through `effectiveSize` without overwriting this authored property; likewise,\n`effectiveName` reports aggregate name authority without rewriting `name`.\n\nAttribute: `size`  \nReflected to its attribute.","type":"LyraSize","default":"'m'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"validationMessage","type":"string","read-only":true},{"name":"validity","type":"ValidityState","read-only":true},{"name":"value","description":"Attribute: `value`  \nReflected to its attribute.","type":"string"},{"name":"willValidate","type":"boolean","read-only":true}],"events":[{"name":"blur","description":"The internal control lost focus.","type":"FocusEvent"},{"name":"change","description":"The user selected this radio.","type":"Event"},{"name":"focus","description":"The internal control received focus.","type":"FocusEvent"},{"name":"input","description":"The user selected this radio.","type":"Event"},{"name":"lr-change","description":"A standalone radio button was selected. `detail: { checked, value }`. An owning radio group emits its aggregate event instead.","type":"CustomEvent<{ checked: boolean; value: string }>"},{"name":"lr-input","description":"Standalone prefixed compatibility alias for `input`. `detail: { checked, value }`.","type":"CustomEvent<{ checked: boolean; value: string }>"},{"name":"lr-invalid","description":"The standalone radio button failed a validity check. Aggregate groups emit their own alias instead. Cancelable: calling `preventDefault()` also cancels the native `invalid` event behind it, suppressing the browser's own validation bubble so an app can present the failure its own way.","type":"CustomEvent<null>"}]}},{"name":"lr-radio-group","description":"`<lr-radio-group>` — a labeled, keyboard-navigable group of radios.\nA required but pristine group exposes `aria-invalid=\"false\"`; intrinsic invalidity is projected\nto the radiogroup only after user interaction (selecting a radio, blurring the group) or\ninteractive validation (`reportValidity()`, or a submission attempt), while explicit error\nchrome remains immediate. `checkValidity()` alone is a silent query and never marks a pristine\ngroup interacted.\n\nHost `aria-describedby` references resolve onto the internal radiogroup before local hint/error\nguidance. References track target replacement/removal, reconnect and document adoption.\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) | Radio controls. |\n| `error` | Validation text. |\n| `help-text` | Shoelace alias for `hint`. |\n| `hint` | Supporting text. |\n| `label` | Visible group label. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The radiogroup wrapper. |\n| `button-group` | Shoelace segmented-option collection alias. |\n| `button-group__base` | Shoelace alias on the same collection. |\n| `error` | Validation text. |\n| `form-control` | Mapped form-control wrapper. |\n| `form-control-help-text` | Shoelace name on the same supporting text. |\n| `form-control-input` | Mapped name on the same option collection. |\n| `form-control-label` | Mapped name on the same group label. |\n| `hint` | Supporting text. |\n| `label` | The group label. |\n| `radios` | WA option collection. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-form-control-required-color` (default: `var(--lr-color-danger)`) — Required-marker color, themeable independently of error text and invalid borders.\n- `--lr-form-control-required-content` (default: `' *'`) — The required marker appended to `form-control-label` while `required` is set. Set it to `''` to suppress the marker, or to any other quoted string (`' (required)'`, a localized word) to replace it.\n- `--lr-form-control-required-offset` (default: `0`) — Inline space between the label text and the required marker.\n- `--lr-radio-group-row-gap` (default: `calc(var(--lr-form-control-height) * 0.2)`) — Vertical gap between the group's label, options and messages, scaled by `size`.","attributes":[{"name":"aria-label","description":"Accessible-name override forwarded to the internal radiogroup. Attribute presence wins,\nincluding an explicitly empty `aria-label`, which also suppresses visible-label linkage.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"custom-error","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nType: `string | null`  \nDefault: `null`"},{"name":"default-value","description":"Shoelace's separate spelling for the reset default.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"disabled","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"error-text","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"form","description":"Type: `HTMLFormElement | string | null`  \nDefault: `null`"},{"name":"help-text","description":"Shoelace alias for hint. `hint` wins when both are supplied.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"hint","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"label","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"name","description":"Submitted form-data key. Lyra defaults to empty, unlike `<sl-radio-group>`'s `\"option\"`;\nthe migration codemod inserts `name=\"option\"`, while a manual tag rename must set it\nexplicitly to preserve Shoelace's default.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"orientation","description":"Arrow-key axis and option layout. Left/right are mirrored under RTL in horizontal mode.\n\nType: `RadioGroupOrientation`  \nDefault: `'vertical'`","value":{"type":["'horizontal'","'vertical'"]}},{"name":"required","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"size","description":"Size of the group's own chrome, on the library's shared ladder. Accepts both spellings of every\ntier — `2xs`/`xs`/`s`/`m`/`l`/`xl` and Web Awesome's `small`/`medium`/`large` — so migrating\neither way is a tag rename. Scales the group's label type size and the gaps around and between\nits options off the same `--lr-form-control-*` values the controls themselves use, and\nprojects the effective tier to owned options without rewriting their authored `size` state.\n\nType: `LyraSize`  \nDefault: `'m'`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}},{"name":"value","description":"Reflected current reset default; changing it never overwrites a dirty live selection.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"with-hint","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"with-label","description":"SSR slot-presence hints used before light-DOM assignment can be inspected.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"","description":"Radio controls."},{"name":"error","description":"Validation text."},{"name":"help-text","description":"Shoelace alias for `hint`."},{"name":"hint","description":"Supporting text."},{"name":"label","description":"Visible group label."}],"js":{"properties":[{"name":"accessibleLabel","description":"Accessible-name override forwarded to the internal radiogroup. Attribute presence wins,\nincluding an explicitly empty `aria-label`, which also suppresses visible-label linkage.\n\nAttribute: `aria-label`","type":"string","default":"''"},{"name":"customError","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nAttribute: `custom-error`  \nReflected to its attribute.","type":"string | null","default":"null"},{"name":"defaultValue","description":"Reflected current reset default; changing it never overwrites a dirty live selection.\n\nAttribute: `value`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"disabled","description":"Attribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"effectiveDisabled","type":"boolean","read-only":true},{"name":"errorText","description":"Attribute: `error-text`","type":"string","default":"''"},{"name":"form","description":"Attribute: `form`  \nReflected to its attribute.","type":"HTMLFormElement | string | null","default":"null"},{"name":"helpText","description":"Shoelace alias for hint. `hint` wins when both are supplied.\n\nAttribute: `help-text`","type":"string","default":"''"},{"name":"hint","description":"Attribute: `hint`","type":"string","default":"''"},{"name":"label","description":"Attribute: `label`","type":"string","default":"''"},{"name":"labels","type":"NodeList","read-only":true},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"name","description":"Submitted form-data key. Lyra defaults to empty, unlike `<sl-radio-group>`'s `\"option\"`;\nthe migration codemod inserts `name=\"option\"`, while a manual tag rename must set it\nexplicitly to preserve Shoelace's default.\n\nAttribute: `name`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"orientation","description":"Arrow-key axis and option layout. Left/right are mirrored under RTL in horizontal mode.\n\nAttribute: `orientation`  \nReflected to its attribute.","type":"RadioGroupOrientation","default":"'vertical'"},{"name":"required","description":"Attribute: `required`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"size","description":"Size of the group's own chrome, on the library's shared ladder. Accepts both spellings of every\ntier — `2xs`/`xs`/`s`/`m`/`l`/`xl` and Web Awesome's `small`/`medium`/`large` — so migrating\neither way is a tag rename. Scales the group's label type size and the gaps around and between\nits options off the same `--lr-form-control-*` values the controls themselves use, and\nprojects the effective tier to owned options without rewriting their authored `size` state.\n\nAttribute: `size`  \nReflected to its attribute.","type":"LyraSize","default":"'m'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"validationMessage","type":"string","read-only":true},{"name":"validity","type":"ValidityState","read-only":true},{"name":"value","description":"Attribute: `value`","type":"string","default":"''"},{"name":"willValidate","type":"boolean","read-only":true},{"name":"withHint","description":"Attribute: `with-hint`","type":"boolean","default":"false"},{"name":"withLabel","description":"SSR slot-presence hints used before light-DOM assignment can be inspected.\n\nAttribute: `with-label`","type":"boolean","default":"false"}],"events":[{"name":"change","description":"Native event fired after `input` for the same group selection.","type":"Event"},{"name":"input","description":"Native event fired from the group when its selected value changes.","type":"InputEvent"},{"name":"lr-change","description":"A radio was selected. `detail: { value, radio }`.","type":"CustomEvent<{ value: string; radio: LyraRadio }>"},{"name":"lr-input","description":"Prefixed alias for `input`; `detail: { value, radio }`.","type":"CustomEvent<{ value: string; radio: LyraRadio }>"},{"name":"lr-invalid","description":"The group's owned validity control failed a validity check. Cancelable: calling `preventDefault()` also cancels the native `invalid` event behind it, suppressing the browser's own validation bubble so an app can present the failure its own way.","type":"CustomEvent<null>"}]}},{"name":"lr-rag-answer","description":"`<lr-rag-answer>` — a controlled grounded-answer surface combining sanitized Markdown, citation\nbadges, a grounding assessment, and source previews. It performs no model call, retrieval,\ncitation parsing, or source fetching.\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.\nBlank citation/source/claim ids and later duplicates are ignored before lookup, counts,\nrendering, or activation. The first record for an id wins.\nBoth child citation signals (`lr-citation-activate` and `lr-citation-open`) are contained and\ntranslated to this component's single `lr-citation-select` event, with `section` identifying\nwhether the answer citation row or grounding summary owned the badge.\n\n---\n\n**Component metadata**\n\n- Status: `stable`\n- Since: `6.2.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| `answer` | Replaces the data-driven Markdown answer body. |\n| `sources` | Replaces the data-driven source list. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `answer` | The answer content wrapper. |\n| `base` | The root answer wrapper. |\n| `citation-list` | The citation badge row. |\n| `citations` | The citation section. |\n| `error` | The neutral, visible caller-supplied error message. New non-empty errors are announced through a shared assertive light-DOM region; initial and reconnect content is not replayed unless `announce` is set, which reads the error present at first mount once. |\n| `grounding` | The grounding assessment. |\n| `loading` | The loading indicator. |\n| `retry` | The retry button. |\n| `section-heading` | A localized section heading. |\n| `source-list` | The data-driven source list. |\n| `sources` | The source section. |","attributes":[{"name":"announce","description":"Opts this answer into announcing the error it is already presenting the first time it\nmounts, through the same shared assertive light-DOM region and the same verbatim\ncaller-supplied text a later `errorText` change takes. Set it where the answer is rendered\nin response to a request the user just made and nothing else reports the failure; leave it\nunset for an answer that is part of the page a user is arriving on, whose error text is\nalready read in document order. Read once, when the answer first mounts: a later\nreconnection or adoption stages the existing error again rather than replaying it, and\nlater `errorText` changes are announced either way. An answer with no error announces\nnothing. Remove any host `role=\"status\"`/`role=\"alert\"` hand-added before this property\nexisted once it is set -- otherwise the initial error is announced twice, through the native\nrole and again through the shared sink.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"answer","description":"Markdown answer content rendered when the `answer` slot is empty.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"aria-label","description":"JS-only accessible-name override for the article while the host attribute is absent. A\nnon-empty markup `aria-label` makes the host the sole overall owner; an explicitly empty host\nlabel stays empty on the article.\n\nType: `string | null`  \nDefault: `null`"},{"name":"error-text","description":"Caller-supplied error text. The visible message is deliberately not a shadow live region;\nnew non-empty values are announced through a shared assertive light-DOM region. Content\npresent on the initial render or reconnect is not replayed unless `announce` is set.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"label","description":"Visible answer label and fallback article name, used when omitted; falls back to the\nlocalized `ragAnswerLabel`. An explicitly empty override stays empty.\n\nType: `string | undefined`"},{"name":"loading","description":"Marks answer generation as pending. Busy semantics and the loading cue remain present while\npartial property or slotted answer content streams; `errorText` takes state precedence if a\nhost supplies both flags during a transition.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"show-claims","description":"Whether claim-level details are forwarded to the grounding summary.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"show-sources","description":"Whether the source section is rendered when source data or slotted content exists.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}}],"slots":[{"name":"answer","description":"Replaces the data-driven Markdown answer body."},{"name":"sources","description":"Replaces the data-driven source list."}],"js":{"properties":[{"name":"accessibleLabel","description":"JS-only accessible-name override for the article while the host attribute is absent. A\nnon-empty markup `aria-label` makes the host the sole overall owner; an explicitly empty host\nlabel stays empty on the article.\n\nAttribute: `aria-label`","type":"string | null","default":"null"},{"name":"announce","description":"Opts this answer into announcing the error it is already presenting the first time it\nmounts, through the same shared assertive light-DOM region and the same verbatim\ncaller-supplied text a later `errorText` change takes. Set it where the answer is rendered\nin response to a request the user just made and nothing else reports the failure; leave it\nunset for an answer that is part of the page a user is arriving on, whose error text is\nalready read in document order. Read once, when the answer first mounts: a later\nreconnection or adoption stages the existing error again rather than replaying it, and\nlater `errorText` changes are announced either way. An answer with no error announces\nnothing. Remove any host `role=\"status\"`/`role=\"alert\"` hand-added before this property\nexisted once it is set -- otherwise the initial error is announced twice, through the native\nrole and again through the shared sink.\n\nAttribute: `announce`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"answer","description":"Markdown answer content rendered when the `answer` slot is empty.\n\nAttribute: `answer`","type":"string","default":"''"},{"name":"assessment","description":"Optional grounding assessment summarized above the citations.","type":"Readonly<GroundingAssessment> | null","default":"null"},{"name":"citations","description":"Citations referenced by the answer and grounding assessment.","type":"readonly Citation[]","default":"[]"},{"name":"errorText","description":"Caller-supplied error text. The visible message is deliberately not a shadow live region;\nnew non-empty values are announced through a shared assertive light-DOM region. Content\npresent on the initial render or reconnect is not replayed unless `announce` is set.\n\nAttribute: `error-text`","type":"string","default":"''"},{"name":"label","description":"Visible answer label and fallback article name, used when omitted; falls back to the\nlocalized `ragAnswerLabel`. An explicitly empty override stays empty.\n\nAttribute: `label`","type":"string | undefined"},{"name":"loading","description":"Marks answer generation as pending. Busy semantics and the loading cue remain present while\npartial property or slotted answer content streams; `errorText` takes state precedence if a\nhost supplies both flags during a transition.\n\nAttribute: `loading`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"showClaims","description":"Whether claim-level details are forwarded to the grounding summary.\n\nAttribute: `show-claims`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"showSources","description":"Whether the source section is rendered when source data or slotted content exists.\n\nAttribute: `show-sources`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"sources","description":"Source records rendered when the `sources` slot is empty.","type":"readonly DocumentRef[]","default":"[]"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-citation-select","description":"A citation badge was activated. `detail: { citation, section }`; `section` is the single presentation owner (`answer` or `grounding`).","type":"CustomEvent<LyraEventDetailSnapshot<LyraRagCitationSelectDetail>>"},{"name":"lr-claim-select","description":"A claim was activated. `detail: { claim }`.","type":"CustomEvent<LyraEventDetailSnapshot<{ claim: GroundedClaim }>>"},{"name":"lr-retry","description":"The retry button was activated after an error.","type":"CustomEvent<null>"}]}},{"name":"lr-rag-eval-dashboard","description":"`<lr-rag-eval-dashboard>` — a controlled RAG quality overview with current metric cards,\nper-metric trends, evaluation slices, and run history. It displays host-computed metrics and\nnever executes datasets, retrieval, judges, or model calls. A controlled `slice` absent from\nthe current runs is preserved and renders an explicit localized unavailable-filter state;\nthe component never silently switches it to All.\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.\nBlank metric/run ids and later duplicates are ignored before fallback selection, filters,\ncounts, rendering, or actions. The first record for an id wins.\n\n---\n\n**Component metadata**\n\n- Status: `stable`\n- Since: `7.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 named dashboard region. |\n| `chart` | The active metric trend. |\n| `empty` | The no-runs or unavailable-controlled-slice state. |\n| `heading` | The visible dashboard heading. |\n| `metric` | One metric control. |\n| `metric-category` | The metric's caller-supplied category label. |\n| `metric-selected` | The controlled active metric. |\n| `metrics` | Metric-card controls. |\n| `run` | One evaluation run. |\n| `runs` | Evaluation run history. |\n| `runs-heading` | Run-history heading. |\n| `slice` | One slice filter. |\n| `slice-selected` | The controlled active slice. |\n| `slices` | Slice filter controls. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-rag-eval-dashboard-selected-border-color` (default: `var(--lr-color-brand)`) — Border color shared by the controlled active slice and metric.","attributes":[{"name":"chart-height","description":"CSS block size forwarded to the composed trend chart.\n\nType: `string`  \nDefault: `'220px'`","value":{"type":["string"]}},{"name":"label","description":"Visible dashboard heading and fallback overall-region name. Omitting it falls back to a\nlocalized default; an explicit empty string clears both. A non-empty host `aria-label`\nmakes the host the sole overall owner; an explicitly empty host label stays empty.\n\nType: `string | undefined`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"metric-id","description":"Controlled id of the active metric; empty selects the first available metric. A non-empty\nvalue that matches no declared `metrics` entry selects no metric at all (no button renders\n`aria-pressed=\"true\"`, and no chart renders) rather than silently substituting the first\nmetric -- the host's own readback always agrees with what is rendered.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"show-chart","description":"Whether a trend chart is rendered when an active metric and matching runs exist.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"slice","description":"Controlled evaluation slice. An unavailable value is preserved and renders an explicit\nlocalized state until the host changes it or supplies a matching run.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"js":{"properties":[{"name":"chartHeight","description":"CSS block size forwarded to the composed trend chart.\n\nAttribute: `chart-height`","type":"string","default":"'220px'"},{"name":"label","description":"Visible dashboard heading and fallback overall-region name. Omitting it falls back to a\nlocalized default; an explicit empty string clears both. A non-empty host `aria-label`\nmakes the host the sole overall owner; an explicitly empty host label stays empty.\n\nAttribute: `label`","type":"string | undefined"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"metricId","description":"Controlled id of the active metric; empty selects the first available metric. A non-empty\nvalue that matches no declared `metrics` entry selects no metric at all (no button renders\n`aria-pressed=\"true\"`, and no chart renders) rather than silently substituting the first\nmetric -- the host's own readback always agrees with what is rendered.\n\nAttribute: `metric-id`","type":"string","default":"''"},{"name":"metrics","description":"Metric definitions shown as controls and used to format run values.","type":"readonly LyraRagEvaluationMetric[]","default":"[]"},{"name":"runs","description":"Evaluation runs displayed in the trend chart and run history.","type":"readonly LyraRagEvaluationRun[]","default":"[]"},{"name":"showChart","description":"Whether a trend chart is rendered when an active metric and matching runs exist.\n\nAttribute: `show-chart`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"slice","description":"Controlled evaluation slice. An unavailable value is preserved and renders an explicit\nlocalized state until the host changes it or supplies a matching run.\n\nAttribute: `slice`","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-metric-change","description":"A metric was activated. `detail: { metricId }`.","type":"CustomEvent<{ metricId: string }>"},{"name":"lr-run-change","description":"An evaluation run was activated. `detail: { run }`.","type":"CustomEvent<{ run: LyraRagEvaluationRun }>"},{"name":"lr-slice-change","description":"An evaluation slice was activated. `detail: { slice }`.","type":"CustomEvent<{ slice: string }>"}]}},{"name":"lr-random-content","description":"`<lr-random-content>` — displays a randomly (or sequentially) chosen\nsubset of its slotted children and hides the rest, for A/B copy testing,\ntestimonial/quote rotation, or varying marketing copy on each render or\ninterval without any custom JS beyond slotting the candidates.\n\nNot a form-associated control: it is a content-rotation primitive over\ncaller-supplied children, so the label/hint/error frame doesn't apply.\nIts only built-in action is the autoplay pause/resume control.\n\nThe host renders `display: block` by default, like the rest of this\nfamily. A consumer needing an inline text-fragment swap inside a sentence\ncan override `lr-random-content { display: inline; }` from outside —\nthat isn't baked in here, since `display: contents` on the host risks\naccessibility-tree inconsistencies across engines.\n\nSelection is driven by `autoplay`/`autoplayInterval` and the public\n`randomize()` method. When autoplay is enabled, a built-in localized\npause/resume action exposes the reflected `paused` state. Rotation also\nsuspends while focus is anywhere inside the component and never hides a\nsubtree that currently owns focus.\nSelection changes after mount are announced through a pre-mounted light-DOM live region,\nexcept for timer-driven autoplay ticks. In particular, an explicit `randomize()` call is\nannounced even while autoplay is enabled. Announcement text omits subtree-pruned content; a\nvisibility-hidden wrapper omits its own text but can contain a visible override descendant.\nA nested forwarding slot contributes flattened assigned text rather than fallback content;\nlater assigned-content and assignment changes are announced when they change the exposed\nselection, while initial distribution stays silent.\nChanges while the host or a composed ancestor is accessibility-hidden, as well as initial\nconnection and reconnection, stay silent.\nReactive selection changes written while detached and rendered during reconnection are part of\nthat silent baseline; a later explicit `randomize()` is still announced.\n\n**Before script runs, the first candidate is the one that shows.** Selection happens in\n`firstUpdated()`, which a server renderer never executes, and it works by setting\n`hidden`/`aria-hidden` on light-DOM siblings — something Lit's hydration diffing never inspects,\nso no amount of first-render seeding can make the server agree. The shadow stylesheet therefore\nhides every candidate after the first until a selection has actually been applied: a\nserver-rendered page (and a page whose script never runs at all) paints one candidate rather\nthan the entire pool, and hydration swaps that one for the chosen one instead of collapsing N\ndown to one. Randomness itself is genuinely unavailable server-side — there is no seed to share\n— so authors who need a *specific* pre-hydration candidate order the pool accordingly.\n\n`fade-left`/`fade-right` are physical-direction transforms (matching the\nupstream naming this component mirrors), not \"previous/next\" navigational\nsemantics like a carousel chevron, so they are deliberately **not**\nmirrored under `:host(:dir(rtl))`.\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 pool of candidate children. Direct element children are eligible; a direct forwarding slot is flattened to its projected element candidates. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The wrapping element around the default slot. |\n| `pause-button` | The autoplay pause/resume action. |\n\n---\n\n**CSS Custom Properties**\n\n- `--animation-duration` (default: `300ms`) — Web Awesome duration alias.\n- `--animation-easing` (default: `ease`) — Web Awesome easing alias.\n- `--animation-translate` (default: `var(--lr-size-0-5em)`) — Web Awesome travel-distance alias.\n- `--lr-animation-duration` (default: `300ms`) — Mapped duration of the entrance animation.\n- `--lr-animation-easing` (default: `ease`) — Mapped easing function for the entrance animation.\n- `--lr-animation-translate` (default: `var(--lr-size-0-5em)`) — Mapped travel distance for directional animations.\n- `--lr-random-content-animation-duration` (default: `300ms`) — Duration of the entrance animation.\n- `--lr-random-content-animation-easing` (default: `ease`) — Easing function for the entrance animation.\n- `--lr-random-content-animation-translate` (default: `var(--lr-size-0-5em)`) — Translation distance for directional animations.\n- `--lr-random-content-item-alignment` (default: `flex-start`) — Cross-axis alignment of selected items.\n- `--lr-random-content-item-gap` (default: `var(--lr-space-s)`) — Gap between simultaneously selected items.","attributes":[{"name":"animation","description":"Entrance effect applied to a child the instant it becomes shown.\n\nType: `LyraRandomContentAnimation`  \nDefault: `'none'`","value":{"type":["'none'","'fade'","'fade-up'","'fade-down'","'fade-left'","'fade-right'"]}},{"name":"autoplay","description":"Whether the displayed selection automatically re-rolls on an interval.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"autoplay-interval","description":"Milliseconds between autoplay ticks. Clamped to a 1000ms floor.\n\nType: `number`  \nDefault: `3000`","value":{"type":["number"]}},{"name":"items","description":"How many children are shown simultaneously -- a count, not the pool itself. NaN/negative/\nfractional/oversized all normalize through `finiteInteger`, clamped to at least 1 and at\nmost the pool size -- see `clampedCount()`.\n\nType: `number`  \nDefault: `1`","value":{"type":["number"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"mode","description":"Type: `LyraRandomContentMode`  \nDefault: `'unique'`","value":{"type":["'unique'","'random'","'sequence'"]}},{"name":"paused","description":"Whether autoplay is user-paused. Reflected for external state styling.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"","description":"The pool of candidate children. Direct element children are eligible; a direct forwarding slot is flattened to its projected element candidates."}],"js":{"properties":[{"name":"animation","description":"Entrance effect applied to a child the instant it becomes shown.\n\nAttribute: `animation`  \nReflected to its attribute.","type":"LyraRandomContentAnimation","default":"'none'"},{"name":"autoplay","description":"Whether the displayed selection automatically re-rolls on an interval.\n\nAttribute: `autoplay`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"autoplayInterval","description":"Milliseconds between autoplay ticks. Clamped to a 1000ms floor.\n\nAttribute: `autoplay-interval`","type":"number","default":"3000"},{"name":"items","description":"How many children are shown simultaneously -- a count, not the pool itself. NaN/negative/\nfractional/oversized all normalize through `finiteInteger`, clamped to at least 1 and at\nmost the pool size -- see `clampedCount()`.\n\nAttribute: `items`","type":"number","default":"1"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"mode","description":"Attribute: `mode`  \nReflected to its attribute.","type":"LyraRandomContentMode","default":"'unique'"},{"name":"paused","description":"Whether autoplay is user-paused. Reflected for external state styling.\n\nAttribute: `paused`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-content-change","description":"The displayed selection changed (first render, `randomize()`, a slot-change-triggered reselection, or an autoplay tick). `detail: { items }` is the exact frozen snapshot of the elements now shown, in display order. Not emitted when the eligible pool is empty.","type":"CustomEvent<{ readonly items: readonly Element[] }>"},{"name":"lr-pause-change","description":"Fired when `paused` changes via the built-in pause/resume button, so a host mirroring or persisting that state stays in sync. Never fired for a host's own `paused` write. `detail: { paused: boolean }` (the new `paused` value). Same name and shape as `<lr-poll-status>`'s identical affordance.","type":"CustomEvent<{ readonly paused: boolean }>"}]}},{"name":"lr-rating","description":"`<lr-rating>` — a keyboard-accessible star rating control. Pointer position within a symbol is\nmirrored under RTL and snapped to `precision`, matching keyboard/value fractional selection.\n\nForm-associated through `ElementInternals` directly rather than through the shared\n`FormAssociated` mixin: this control's `value` is a number, not the plain string that mixin's\ncontract assumes, so the mixin would force every consumer through string round-tripping for what\nis natively a numeric score. The submitted entry is the clamped value stringified (`\"0\"` while\nunrated), and `required` reports `valueMissing` until a rating above zero is set. As with a\nnative range-like controls and both mirrored rating elements, the `value` content attribute and\nIDL property control the live score. `defaultValue` / `default-value` independently own the form\nreset target, so changing `value` never silently rewrites what `form.reset()` restores.\n\nThe host is the single focusable `role=\"slider\"` owner and carries its value/name/state ARIA,\nincluding explicit `aria-invalid=\"true\"|\"false\"` from effective intrinsic/custom validity.\nThe shadow symbol row is presentational chrome, so host ARIA customization cannot create a\nsecond competing slider.\n\nDeliberately no label/hint/error chrome: `label` here is an accessible-name override, not visible\nlabel text. A rating is a row of symbols with no field frame of its own, so a consumer wanting a\nlabeled field wraps this element in their own layout, exactly as `<lr-slider>` does.\n\nReadonly transitions synchronize validity and aria-invalid in the same completed update. Form reset restores the independent default-value rather than the live value attribute.\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` | Compatibility name for the presentational symbol row; use `rating`. |\n| `rating` | The presentational symbol row. It is the same node as `base`. |\n| `star` | Each visual symbol. |\n| `star-fill` | The filled overlay inside each symbol, clipped to that symbol's filled fraction (0%, a partial percentage under a fractional `precision`, or 100%). |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-rating-active-color` (default: `color-mix(in oklab, var(--lr-rating-empty-color, var(--symbol-color, var(--lr-color-border-strong))), var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Pressed-symbol color. Set it independently of `--lr-rating-empty-color` to recolor the pressed state without changing resting or hover symbols.\n- `--lr-rating-empty-color` (default: `var(--lr-color-border)`) — Unfilled-symbol color, retained during hover preview.\n- `--lr-rating-fill` (default: `var(--lr-color-warning)`) — Filled-symbol color.\n- `--lr-rating-gap` (default: `var(--symbol-spacing,var(--lr-space-xs))`) — Gap between symbols. It takes precedence over the `--symbol-spacing` compatibility hook while preserving that hook and the shared spacing token as fallbacks.\n- `--lr-rating-size` (default: `var(--lr-font-size-xl)`) — Symbol size. Its private default follows each `size` step; an inherited or direct public value wins. The `m` default reproduces the treatment this component had before `size` existed.\n- `--symbol-color` (default: `var(--lr-rating-empty-color,var(--lr-color-border))`) — Compatibility alias for the inactive symbol color. `--lr-rating-empty-color` wins when both are set.\n- `--symbol-color-active` (default: `var(--lr-rating-fill,var(--lr-color-warning))`) — Compatibility alias for the active symbol color. `--lr-rating-fill` wins when both are set.\n- `--symbol-size` — Shoelace-compatible symbol size. It feeds the current `size` step when `--lr-rating-size` is unset; the Lyra-prefixed property wins when both are set.\n- `--symbol-spacing` (default: `var(--lr-space-xs)`) — Compatibility spacing around symbols.","attributes":[{"name":"custom-error","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nType: `string | null`  \nDefault: `null`"},{"name":"default-value","description":"Compatibility attribute alias for the supported `defaultValue` reset value.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"disabled","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"form","description":"Type: `HTMLFormElement | string | null`  \nDefault: `null`"},{"name":"label","description":"Accessible name for the whole control, used when the host carries no `aria-label`. Not\nrendered as visible text — a rating has no field frame of its own.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max","description":"The highest rating to show, i.e. the number of symbols rendered.\n\nType: `number`  \nDefault: `5`","value":{"type":["number"]}},{"name":"name","description":"Submitted as the name half of the form-data name/value pair.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"precision","description":"Type: `number`  \nDefault: `1`","value":{"type":["number"]}},{"name":"readonly","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"required","description":"Blocks form submission until a rating above zero is set.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"size","description":"Visual density; changes the private fallback behind `--lr-rating-size`. An inherited or\ndirect public value wins. Valid upstream long-form sizes remain observable verbatim rather\nthan being reflected back as a different token.\n\nType: `LyraRatingSize`  \nDefault: `'m'`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}},{"name":"value","description":"The current rating. Clamped to `[0, max]` wherever it is read; the raw assignment is kept so\na value set before `max` arrives from markup isn't silently truncated.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}}],"js":{"properties":[{"name":"accessibleLabel","description":"Accessible-name property override. A host `aria-label` attribute has higher priority, and an\nexplicitly empty host attribute is preserved instead of restoring a fallback name.","type":"string","default":"''"},{"name":"customError","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nAttribute: `custom-error`  \nReflected to its attribute.","type":"string | null","default":"null"},{"name":"defaultValue","description":"Current reset default; changing it never overwrites a dirty live rating. The independently\nreflected `default-value` compatibility attribute reaches this same property.","type":"number","default":"0"},{"name":"disabled","description":"Attribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"effectiveDisabled","description":"Whether the control is disabled explicitly or by an ancestor `<fieldset disabled>`.","type":"boolean","read-only":true},{"name":"form","description":"Attribute: `form`  \nReflected to its attribute.","type":"HTMLFormElement | string | null","default":"null"},{"name":"getSymbol","description":"Renders a consumer-supplied decorative symbol per position instead of the built-in star.\nIts output cannot become a second focus or pointer target; interact with the rating control\nitself to select a value.","type":"LyraRatingSymbolRenderer | undefined"},{"name":"label","description":"Accessible name for the whole control, used when the host carries no `aria-label`. Not\nrendered as visible text — a rating has no field frame of its own.\n\nAttribute: `label`","type":"string","default":"''"},{"name":"labels","type":"NodeList","read-only":true},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"max","description":"The highest rating to show, i.e. the number of symbols rendered.\n\nAttribute: `max`","type":"number","default":"5"},{"name":"name","description":"Submitted as the name half of the form-data name/value pair.\n\nAttribute: `name`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"precision","description":"Attribute: `precision`","type":"number","default":"1"},{"name":"rating","description":"Live presentational symbol row, or `null` before the render root is populated.","type":"HTMLElement | null","read-only":true},{"name":"readonly","description":"Attribute: `readonly`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"required","description":"Blocks form submission until a rating above zero is set.\n\nAttribute: `required`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"size","description":"Visual density; changes the private fallback behind `--lr-rating-size`. An inherited or\ndirect public value wins. Valid upstream long-form sizes remain observable verbatim rather\nthan being reflected back as a different token.\n\nAttribute: `size`  \nReflected to its attribute.","type":"LyraRatingSize","default":"'m'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"validationMessage","type":"string","read-only":true},{"name":"validity","type":"ValidityState","read-only":true},{"name":"value","description":"The current rating. Clamped to `[0, max]` wherever it is read; the raw assignment is kept so\na value set before `max` arrives from markup isn't silently truncated.\n\nAttribute: `value`","type":"number","default":"0"},{"name":"willValidate","type":"boolean","read-only":true}],"events":[{"name":"blur","description":"The native blur event from the host-owned slider.","type":"FocusEvent"},{"name":"change","description":"Bubbling, composed native `Event` emitted when a user commits a new value, immediately before `lr-change`. Programmatic writes and no-op gestures are silent.","type":"Event"},{"name":"focus","description":"The native focus event from the host-owned slider.","type":"FocusEvent"},{"name":"lr-activate","description":"Fired on every interactive commit of a rating -- a click on a symbol, or an Arrow/Home/End key -- whether or not the value actually moved. `detail: { value }` carries the committed rating. Bubbling and composed, so a host outside the shadow tree receives it. Not cancelable: it is a notification that the user committed a rating, not a veto point, and nothing in this component branches on it. Re-committing the current rating is the case `lr-change` deliberately stays silent for, and from the keyboard it is otherwise unobservable: End on an already-maximum rating, Home on an already-zero one, or an arrow key at either bound commits a rating and produces no click at all. When the commit does move the value, `change` and `lr-change` are emitted first, so a listener reading `value` from any of them sees the settled rating. A non-interactive (`readonly`/`disabled`) rating fires none of them.","type":"CustomEvent<{ value: number }>"},{"name":"lr-change","description":"The rating changed. `detail: { value }`.","type":"CustomEvent<{ value: number }>"},{"name":"lr-hover","description":"The pointer entered, moved across, or left the symbols while the rating is settable. `detail: { phase, value }`, where `value` is the rating that committing the current pointer position would produce — enough to render a live description of what is being hovered.","type":"CustomEvent<{ phase: LyraRatingHoverPhase; value: number }>"},{"name":"lr-invalid","description":"The rating failed a validity check. Cancelable: calling `preventDefault()` also cancels the native `invalid` event behind it, suppressing the browser's own validation bubble so an app can present the failure its own way.","type":"CustomEvent<null>"}]}},{"name":"lr-realtime-session","description":"`<lr-realtime-session>` — a provider-neutral voice-session shell composing connection status,\nlive activity, transcript, native capture, mute, interruption, and connect/disconnect intents.\nTransport, authentication, audio playback, and SDK ownership remain with the host.\nState transitions transfer focus from a disappearing session action to the replacement\nconnect/disconnect action. Hiding the public capture surface does the same only when capture\nowned focus; surviving or foreign focus is never moved.\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: `7.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| `controls` | Additional provider-specific controls. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `activity` | Voice activity visualization. |\n| `base` | The named session region. |\n| `capture` | Native push-to-talk capture. |\n| `connect` | Connect action. |\n| `controls` | Built-in and slotted controls. |\n| `disconnect` | Disconnect action. |\n| `error` | Localized connection error. |\n| `header` | Status and session controls. |\n| `interrupt` | Response interruption action. |\n| `mute` | Controlled mute action. |\n| `status` | Connection status badge. |\n| `transcript` | Live transcript. |","attributes":[{"name":"label","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"level","description":"Type: `number | null`  \nDefault: `null`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"muted","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"session-id","description":"Stable identity forwarded to the transcript feed. Changing it resets finalized-entry\nannouncement history so reused entry ids in a new session remain unambiguous.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"show-capture","description":"Shows native push-to-talk capture. Hiding a focused capture transfers focus to the current\nconnect/disconnect action; hiding it while another control owns focus leaves that focus alone.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"state","description":"Type: `RealtimeConnectionState`","value":{"type":["'disconnected'","'connecting'","'connected'","'reconnecting'","'error'"]}},{"name":"voice-state","description":"Type: `AudioVisualizerState`","value":{"type":["'idle'","'listening'","'thinking'","'speaking'"]}}],"slots":[{"name":"controls","description":"Additional provider-specific controls."}],"js":{"properties":[{"name":"entries","type":"readonly LyraTranscriptEntry[]","default":"[]"},{"name":"label","description":"Attribute: `label`","type":"string","default":"''"},{"name":"level","description":"Attribute: `level`","type":"number | null","default":"null"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"muted","description":"Attribute: `muted`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"sessionId","description":"Stable identity forwarded to the transcript feed. Changing it resets finalized-entry\nannouncement history so reused entry ids in a new session remain unambiguous.\n\nAttribute: `session-id`","type":"string","default":"''"},{"name":"showCapture","description":"Shows native push-to-talk capture. Hiding a focused capture transfers focus to the current\nconnect/disconnect action; hiding it while another control owns focus leaves that focus alone.\n\nAttribute: `show-capture`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"state","description":"Attribute: `state`  \nReflected to its attribute.","type":"RealtimeConnectionState"},{"name":"stream","type":"MediaStream | null","default":"null"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"voiceState","description":"Attribute: `voice-state`","type":"AudioVisualizerState"}],"events":[{"name":"lr-connect","description":"Connection was requested.","type":"CustomEvent<null>"},{"name":"lr-disconnect","description":"Disconnection was requested.","type":"CustomEvent<null>"},{"name":"lr-interrupt","description":"Interruption of the current response was requested.","type":"CustomEvent<null>"},{"name":"lr-level","description":"Passthrough from capture. `detail: { level: number }`.","type":"CustomEvent<{ level: number }>"},{"name":"lr-mute-change","description":"A controlled microphone mute change was requested.","type":"CustomEvent<{ muted: boolean }>"},{"name":"lr-record-cancel","description":"Passthrough from capture with no detail.","type":"CustomEvent<null>"},{"name":"lr-record-chunk","description":"Passthrough from capture. `detail: { blob: Blob }`.","type":"CustomEvent<{ blob: Blob }>"},{"name":"lr-record-error","description":"Passthrough from capture. `detail: { error: DOMException | Error }`.","type":"CustomEvent<{ error: DOMException | Error }>"},{"name":"lr-record-start","description":"Passthrough from capture. `detail: { stream: MediaStream }`.","type":"CustomEvent<{ stream: MediaStream }>"},{"name":"lr-record-state-change","description":"Passthrough from capture. `detail: { state: PushToTalkState }`.","type":"CustomEvent<{ state: PushToTalkState }>"},{"name":"lr-record-stop","description":"Passthrough from capture. `detail: { blob: Blob; durationMs: number }`.","type":"CustomEvent<{ blob: Blob; durationMs: number }>"}]}},{"name":"lr-relative-time","description":"`<lr-relative-time>` — locale-aware relative time that can refresh automatically. Numeric\n`date` attributes are epoch milliseconds, matching numeric property assignment; nonnumeric\nattributes remain date strings.\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.","attributes":[{"name":"date","description":"Type: `string | number | Date`  \nDefault: `new Date()`"},{"name":"format","description":"Type: `LyraFormatDisplay`  \nDefault: `'long'`","value":{"type":["'long'","'short'","'narrow'"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"numeric","description":"Type: `LyraRelativeTimeNumeric`  \nDefault: `'auto'`","value":{"type":["'always'","'auto'"]}},{"name":"sync","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"unit","description":"Type: `LyraRelativeTimeUnit | 'auto'`  \nDefault: `'auto'`","value":{"type":["'second'","'minute'","'hour'","'day'","'week'","'month'","'quarter'","'year'","'auto'"]}}],"js":{"properties":[{"name":"date","description":"Attribute: `date`","type":"string | number | Date","default":"new Date()"},{"name":"format","description":"Attribute: `format`","type":"LyraFormatDisplay","default":"'long'"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"numeric","description":"Attribute: `numeric`","type":"LyraRelativeTimeNumeric","default":"'auto'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"sync","description":"Attribute: `sync`","type":"boolean","default":"false"},{"name":"unit","description":"Attribute: `unit`","type":"LyraRelativeTimeUnit | 'auto'","default":"'auto'"}]}},{"name":"lr-reorder-item","description":"`<lr-reorder-item>` — one row inside `<lr-reorder-list>`. Renders arbitrary slotted content plus\nmove-up/move-down buttons. This item alone doesn't know whether it's first or last in the list,\nso its readonly boundary-disabled state (`atStart`/`atEnd`), list-level cascade\n(`listDisabled`), and held-move state (`pending`) are resolved by the owning\n`<lr-reorder-list>`. `focusMoveButton()` moves focus onto one of the two controls\nprogrammatically -- the owning list uses it for its own post-move focus restore, and a host\nrunning `<lr-reorder-list>` in its `controlled` mode can use it the same way once its own\nre-render settles, including onto a freshly recreated element instance.\n\n---\n\n**Component metadata**\n\n- Status: `stable`\n- Since: `6.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) | Arbitrary row content (a label, a mini-form, anything). |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The row's root wrapper. |\n| `content` | Wrapper around the default slot. |\n| `move-down-button` | The move-down control, likewise a composed `<lr-icon-button>`. |\n| `move-down-button__control` | The move-down control's own native `<button>`. |\n| `move-up-button` | The move-up control, a composed `<lr-icon-button>` as of 16.0.0. It still owns the accessible name, the activation and the rotation; its background, radius, hover/press mixes, focus ring and hit-area floor now come from `--lr-icon-button-*`. |\n| `move-up-button__control` | The move-up control's own native `<button>`, forwarded because the painted surface sits one shadow boundary deeper than `move-up-button`. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-reorder-item-gap` (default: `var(--lr-space-xs)`) — Gap between the move buttons and content. Move-button state properties are resolved as inline fallbacks, so setting one on an item or any ancestor themes only the requested hover or pressed state without replacing shared brand tokens.\n- `--lr-reorder-item-move-button-active-bg` (default: `color-mix(in oklab, var(--lr-color-brand-quiet), var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Background of a pressed move button.\n- `--lr-reorder-item-move-button-active-color` (default: `var(--lr-color-brand)`) — Text color of a pressed move button.\n- `--lr-reorder-item-move-button-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Background of a hovered move button.\n- `--lr-reorder-item-move-button-hover-color` (default: `var(--lr-color-brand)`) — Text color of a hovered move button.","attributes":[{"name":"accessible-label","description":"Explicit item identity used to correlate this row's repeated move actions. When absent, a\nbounded accessible-text projection of the row content is used.\n\nType: `string | undefined`"},{"name":"disabled","description":"Disables this row's own move-up/move-down buttons without removing it or its slotted content\nfrom the DOM. Does not gate the default slot's own content.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"value","description":"Required unique, nonempty stable identifier included in the parent list's emitted\n`lr-reorder` order array. An owning list excludes an item with a missing, whitespace-only, or\nduplicate value from movement until its identity becomes valid. Direct property or attribute\nedits refresh the owner's movement boundaries. Removed standalone values render as absent.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"slots":[{"name":"","description":"Arbitrary row content (a label, a mini-form, anything)."}],"js":{"properties":[{"name":"accessibleLabel","description":"Explicit item identity used to correlate this row's repeated move actions. When absent, a\nbounded accessible-text projection of the row content is used.\n\nAttribute: `accessible-label`","type":"string | undefined"},{"name":"atEnd","description":"Whether this is the last valid item in the owning list. Readonly.","type":"boolean","read-only":true},{"name":"atStart","description":"Whether this is the first valid item in the owning list. Readonly.","type":"boolean","read-only":true},{"name":"disabled","description":"Disables this row's own move-up/move-down buttons without removing it or its slotted content\nfrom the DOM. Does not gate the default slot's own content.\n\nAttribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"listDisabled","description":"Effective owning-list disabled state. Readonly; it never mutates this item's authored\n`disabled` property.","type":"boolean","read-only":true},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"pending","description":"Whether this item's proposed move is held pending host resolution. Readonly and exposed as\nthe `:state(pending)` custom state.","type":"boolean","read-only":true},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"value","description":"Required unique, nonempty stable identifier included in the parent list's emitted\n`lr-reorder` order array. An owning list excludes an item with a missing, whitespace-only, or\nduplicate value from movement until its identity becomes valid. Direct property or attribute\nedits refresh the owner's movement boundaries. Removed standalone values render as absent.\n\nAttribute: `value`","type":"string","default":"''"}],"events":[{"name":"lr-move-request","description":"`detail: { direction: 'up' | 'down' }` — a move button was activated while not disabled. Bubbles (composed) to the owning `<lr-reorder-list>`, which performs the actual move and boundary-state recomputation.","type":"CustomEvent<{ direction: 'up' | 'down' }>"}]}},{"name":"lr-reorder-list","description":"`<lr-reorder-list>` — a generic vertical list of `<lr-reorder-item>` rows, reorderable via\nper-row move-up/move-down buttons (always available) or Ctrl/Cmd+ArrowUp/ArrowDown from focus\nanywhere inside a row — the same modifier convention `<lr-tree>`'s `reorderable` and\n`<lr-dashboard-grid>`'s `cells-draggable` already establish.\n\nBy default this list physically moves its own slotted `<lr-reorder-item>` light-DOM nodes\nitself, unlike `<lr-tree>`'s `reorderable` mode (a *controlled* request — `data` is host-owned\nand nothing moves until the host reassigns it): this list has no `data` array prop, its\nchildren are plain author-authored slotted content with nothing to reconcile against, so DOM\norder genuinely is the source of truth (the same principle `<lr-tree>` relies on for its own\nchildren). Setting `controlled` opts into the `<lr-tree>`-style contract instead — see its own\ndoc comment. Every item must provide a unique, nonempty `value`; invalid or duplicate identities\nstay visible but cannot move. The `lr-reorder` event tells the host the resulting stable-id\norder, so it can persist it without hand-rolling its own splice/resort logic.\n\nAn `lr-reorder` listener can call `preventDefault()` to hold a move open while its own async\nwork (e.g. a network call persisting the new order) is in flight -- the same\ncancelable-event-plus-host-resolvable-pending-state pattern `<lr-confirm-bar>` and\n`<lr-tool-approval-dialog>` already establish for their own approve/deny decisions.\n\n---\n\n**Component metadata**\n\n- Status: `stable`\n- Since: `6.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-reorder-item>` elements. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The list's root wrapper (`role=\"list\"`). |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-reorder-list-gap` (default: `var(--lr-space-2xs)`) — Gap between rows.","attributes":[{"name":"controlled","description":"Opt-in controlled mode. Unset (the default), an uncanceled `lr-reorder` (or a\n`finalizePendingMove()` call) moves this list's own slotted `<lr-reorder-item>` light-DOM\nnodes itself, exactly as before this property existed. Set, this list stops moving anything\nitself -- the host is expected to reorder its OWN backing data and re-render the slotted\nitems in the new order, the same controlled request `<lr-tree>`'s `reorderable` already\nestablishes for its `data`-driven children. This list still has no `data` array prop (its\nchildren stay plain slotted content), so the reconciliation is keyed by each item's stable\n`value` rather than by element reference: once a later slot/attribute mutation settles into\nexactly the value order this list emitted as the triggering event's `order`, the move is\ncomplete -- boundary state, focus restore, and the `reorderItemMoved` announcement then fire\nagainst whichever element instance now holds that `value` (the host's re-render may have\nrecreated it). Every move action stays disabled and `:state(busy)`/`aria-busy=\"true\"` apply\nlist-wide for the whole wait, matching a `preventDefault()`-held move. A host re-render that\nnever reaches that exact order leaves the move pending indefinitely; one that drops the\nmoved `value` entirely (removes or renames that row) cancels it silently, with no\nannouncement -- the host already knows, since it made that edit itself.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"disabled","description":"Disables every item's move-up/move-down buttons and the Ctrl/Cmd+Arrow shortcut, without\nremoving any item from the DOM or mutating any item's own `disabled` attribute.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"label","description":"Accessible-name fallback for the internal `role=\"list\"` element when the host has no\n`aria-label`, matching `<lr-control-group>`. Native lists don't require an accessible name,\nso this has no forced fallback string when both are left unset.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"slots":[{"name":"","description":"`<lr-reorder-item>` elements."}],"js":{"properties":[{"name":"controlled","description":"Opt-in controlled mode. Unset (the default), an uncanceled `lr-reorder` (or a\n`finalizePendingMove()` call) moves this list's own slotted `<lr-reorder-item>` light-DOM\nnodes itself, exactly as before this property existed. Set, this list stops moving anything\nitself -- the host is expected to reorder its OWN backing data and re-render the slotted\nitems in the new order, the same controlled request `<lr-tree>`'s `reorderable` already\nestablishes for its `data`-driven children. This list still has no `data` array prop (its\nchildren stay plain slotted content), so the reconciliation is keyed by each item's stable\n`value` rather than by element reference: once a later slot/attribute mutation settles into\nexactly the value order this list emitted as the triggering event's `order`, the move is\ncomplete -- boundary state, focus restore, and the `reorderItemMoved` announcement then fire\nagainst whichever element instance now holds that `value` (the host's re-render may have\nrecreated it). Every move action stays disabled and `:state(busy)`/`aria-busy=\"true\"` apply\nlist-wide for the whole wait, matching a `preventDefault()`-held move. A host re-render that\nnever reaches that exact order leaves the move pending indefinitely; one that drops the\nmoved `value` entirely (removes or renames that row) cancels it silently, with no\nannouncement -- the host already knows, since it made that edit itself.\n\nAttribute: `controlled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"disabled","description":"Disables every item's move-up/move-down buttons and the Ctrl/Cmd+Arrow shortcut, without\nremoving any item from the DOM or mutating any item's own `disabled` attribute.\n\nAttribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"label","description":"Accessible-name fallback for the internal `role=\"list\"` element when the host has no\n`aria-label`, matching `<lr-control-group>`. Native lists don't require an accessible name,\nso this has no forced fallback string when both are left unset.\n\nAttribute: `label`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-reorder","description":"`detail: { order, fromIndex, toIndex }` — fired before a move is applied (button click or Ctrl/Cmd+Arrow). `order` is every valid item's stable `value` in the order the move WOULD produce; `fromIndex`/`toIndex` are the moved item's 0-based position before/after. Cancelable: a listener calling `preventDefault()` holds the move instead of applying it -- the affected `<lr-reorder-item>` exposes `:state(pending)`, every move action becomes disabled, and no other move can start anywhere in this list -- until the host calls `finalizePendingMove()` to apply it or `revertPendingMove()` to discard it and restore the prior order. Uncanceled (the default), the move applies synchronously in the same tick when `controlled` is unset, unchanged from every release before this option existed; while `controlled` is set it instead waits for a matching host re-render, per that property's own doc comment.","type":"CustomEvent<LyraEventDetailSnapshot<LyraReorderDetail>>"}]}},{"name":"lr-resize-observer","description":"`<lr-resize-observer>` — observes the first-party or consumer-owned\nelements in its default slot and emits typed resize entries. The wrapper has\nno visual layout of its own (`display: contents`).\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) | Elements to observe. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The non-layout wrapper around the observed slot. |","attributes":[{"name":"box","description":"Type: `ResizeObserverBox`  \nDefault: `'content-box'`","value":{"type":["'content-box'","'border-box'","'device-pixel-content-box'"]}},{"name":"disabled","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"slots":[{"name":"","description":"Elements to observe."}],"js":{"properties":[{"name":"box","description":"Attribute: `box`  \nReflected to its attribute.","type":"ResizeObserverBox","default":"'content-box'"},{"name":"disabled","description":"Attribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-resize","description":"Observed elements changed size; the detached bounded entry sequence and containing detail are frozen while native entry identities are retained.","type":"CustomEvent<\n    Readonly<{ entries: readonly ResizeObserverEntry[] }>\n  >"}]}},{"name":"lr-responsive-panel","description":"`<lr-responsive-panel>` — the same slotted content either docked inline\nin the page's normal layout flow (desktop) or presented as a full-screen/\nbottom-sheet overlay, depending on its allocated inline size. Typical uses:\na settings panel or a conversation-history sidebar that's a permanent\ndocked pane on a wide screen but a modal on a phone.\n\nBreakpoint detection observes this component and compares its allocation with\n`overlayBreakpoint`. Resizing a containing layout across the breakpoint while\n`mode=\"auto\"` (the default) updates the\neffective presentation without unmounting or re-creating the slotted\ncontent: inline and overlay presentation share the exact same shadow DOM\nstructure (only a css class, and the overlay-only `role`/`aria-modal`\nattributes and backdrop element, differ), so lit-html's diffing keeps\n`[part=\"body\"]` and its `<slot>` as the same DOM node across the\ntransition -- scroll position and focus inside the slotted content survive\nit for free. When an open inline panel becomes modal, focus already inside\nis preserved and outside focus moves to the first available target. Closing\nstill returns to the opener captured by the original inline open.\n\nThe overlay presentation uses the library's shared overlay coordinator for\nfocus trapping, Escape/backdrop dismissal, inerting, and stack ordering,\nwhile retaining this component's own responsive rendering and close event.\n\nAccessible name (overlay presentation only -- the inline presentation has\nno dialog semantics to name), in priority order: if the host element itself\nhas an `aria-label` attribute set, its value wins outright, overriding\nevery source below -- the standard ARIA convention for a consumer that\nwants full control over the announced name, matching lr-dialog's\n`accessibleLabel` pattern. Otherwise `label`, when set, is used verbatim.\nWhen both are empty, this falls back to the `header` slot's content -- a\nheading element (`h1`–`h6` or `[role=\"heading\"]`) among the slotted header\ncontent wins if present, otherwise the header slot's full text content is\nused, mirroring lr-dialog's `detectHeading()`/`headingText` fallback (see\ndialog.ts's module doc for why this uses `aria-label`, a copied string,\nrather than `aria-labelledby`: the header content is light DOM while\n`[part=\"panel\"]` lives in this element's shadow tree, and an ID-reference\nattribute can't resolve across that boundary). A panel opened without a\nhost `aria-label`, `label`, or header content receives the localized\n`responsivePanel` fallback, so every overlay dialog remains named.\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| `footer` | Optional footer content (e.g. action buttons), rendered below the body. |\n| `header` | Optional header content, rendered above the body. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `backdrop` | The full-viewport scrim behind the panel -- only rendered in the overlay presentation. |\n| `base` | The root wrapper; `display: none` while closed, positioned `fixed` while open and in the overlay presentation. |\n| `body` | The wrapper around the default slot. |\n| `footer` | The wrapper around the `footer` slot. Overlay state properties are resolved as inline fallbacks, so setting one on a panel or any ancestor themes the overlay without changing docked panel chrome or shared tokens. |\n| `header` | The wrapper around the `header` slot. |\n| `panel` | The panel surface itself (`role=\"dialog\"` while open and in the overlay presentation). |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-responsive-panel-overlay-color` (default: `var(--lr-color-overlay)`) — The overlay presentation's scrim color, applied to `[part=\"backdrop\"]`.\n- `--lr-responsive-panel-overlay-panel-bg` (default: `var(--lr-color-surface-overlay)`) — Background of `[part=\"panel\"]` in the overlay presentation.\n- `--lr-responsive-panel-overlay-panel-shadow` (default: `var(--lr-shadow-l)`) — Shadow of `[part=\"panel\"]` in the overlay presentation.\n- `--lr-responsive-panel-sheet-max-block-size` (default: `85dvh`) — Maximum height of the `shape=\"bottom-sheet\"` overlay panel (falls back to `85vh` where `dvh` is unsupported).\n- `--lr-responsive-panel-side-inline-size` (default: `var(--lr-size-20rem)`) — Width of the `shape=\"start\"`/`shape=\"end\"` overlay panel along the inline axis.","attributes":[{"name":"aria-label","description":"Host-level `aria-label` override for the overlay presentation's accessible name -- wins over\nevery other source (`label`, the header-slot fallback), matching `<lr-dialog>`'s\n`accessibleLabel` pattern. See the class doc for the full precedence order. Set as a plain\n`aria-label` attribute on `<lr-responsive-panel>` itself, not a public JS property.\n\nType: `| string\n    | null`  \nDefault: `null`"},{"name":"label","description":"Accessible name for the overlay presentation's `role=\"dialog\"`. Unused in the inline\npresentation, which has no dialog semantics to name. When empty, falls back to the `header`\nslot's content -- see the class doc for the full fallback order.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"mode","description":"Type: `LyraResponsivePanelMode`","value":{"type":["'inline'","'overlay'","'auto'"]}},{"name":"open","description":"Whether the panel is open. In the inline presentation this just means visible/mounted; in\nthe overlay presentation this is the actual modal open/closed state.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"overlay-breakpoint","description":"CSS length compared with this element's allocated inline size in `mode=\"auto\"`.\nAt or below the breakpoint, the effective presentation is `'overlay'`.\n\nType: `string`  \nDefault: `'768px'`","value":{"type":["string"]}},{"name":"shape","description":"Only affects the overlay presentation's visual treatment -- `'fullscreen'` (default) covers\nthe whole viewport; `'bottom-sheet'` anchors to the block-end edge and doesn't cover the full\nheight; `'start'`/`'end'` anchor to the matching *logical* inline edge instead, like a docked\nsidebar's slide-in-from-the-edge overlay counterpart -- the anchored edge, the panel's rounded\nfree edge, and the geometry all flip automatically under `dir=\"rtl\"` (logical\n`inset-inline-*`/border-radius properties, no `:dir()` selector involved). No entrance motion\nis implied by any shape value. This is a presentation-shape axis, not the library's shared\nsemantic-tone `variant` vocabulary (`lr-button`/`lr-badge`/etc.) -- it deliberately uses a\ndifferent property name to avoid colliding with that meaning.\n\nType: `LyraResponsivePanelShape`  \nDefault: `'fullscreen'`","value":{"type":["'fullscreen'","'bottom-sheet'","'start'","'end'"]}}],"slots":[{"name":"","description":"The panel body."},{"name":"footer","description":"Optional footer content (e.g. action buttons), rendered below the body."},{"name":"header","description":"Optional header content, rendered above the body."}],"js":{"properties":[{"name":"effectiveMode","description":"The currently resolved presentation. Composition/measurement is the sole write authority.","type":"LyraResponsivePanelEffectiveMode","read-only":true},{"name":"label","description":"Accessible name for the overlay presentation's `role=\"dialog\"`. Unused in the inline\npresentation, which has no dialog semantics to name. When empty, falls back to the `header`\nslot's content -- see the class doc for the full fallback order.\n\nAttribute: `label`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"mode","description":"Attribute: `mode`  \nReflected to its attribute.","type":"LyraResponsivePanelMode"},{"name":"open","description":"Whether the panel is open. In the inline presentation this just means visible/mounted; in\nthe overlay presentation this is the actual modal open/closed state.\n\nAttribute: `open`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"overlayBreakpoint","description":"CSS length compared with this element's allocated inline size in `mode=\"auto\"`.\nAt or below the breakpoint, the effective presentation is `'overlay'`.\n\nAttribute: `overlay-breakpoint`","type":"string","default":"'768px'"},{"name":"shape","description":"Only affects the overlay presentation's visual treatment -- `'fullscreen'` (default) covers\nthe whole viewport; `'bottom-sheet'` anchors to the block-end edge and doesn't cover the full\nheight; `'start'`/`'end'` anchor to the matching *logical* inline edge instead, like a docked\nsidebar's slide-in-from-the-edge overlay counterpart -- the anchored edge, the panel's rounded\nfree edge, and the geometry all flip automatically under `dir=\"rtl\"` (logical\n`inset-inline-*`/border-radius properties, no `:dir()` selector involved). No entrance motion\nis implied by any shape value. This is a presentation-shape axis, not the library's shared\nsemantic-tone `variant` vocabulary (`lr-button`/`lr-badge`/etc.) -- it deliberately uses a\ndifferent property name to avoid colliding with that meaning.\n\nAttribute: `shape`  \nReflected to its attribute.","type":"LyraResponsivePanelShape","default":"'fullscreen'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-close","description":"`detail: LyraResponsivePanelCloseReason`. Cancelable pre-close veto, fired by the overlay presentation's built-in dismiss triggers (Escape, backdrop click) and by any `close()` call, in either presentation. Calling `preventDefault()` keeps the panel open and leaves any active overlay chrome/focus trap intact. A plain `open = false` property write does not fire it (matching lr-dialog's own precedent: only going through `close()` counts as a dismissal), and this is deliberately the same event/semantics in both presentations, rather than only being meaningful for the overlay case, so a consumer only has to wire up one listener regardless of which presentation is currently active.","type":"CustomEvent<LyraResponsivePanelCloseReason>"},{"name":"lr-mode-change","description":"`detail: LyraResponsivePanelModeChangeDetail`. Fired whenever the *effective* mode (not the `mode` prop's literal value, which may be `'auto'`) changes between `'inline'` and `'overlay'` -- crossing the breakpoint while `mode=\"auto\"`, or the host reassigning `mode` to a value that changes the effective presentation. Never fired for the initial render, only for a live change thereafter.","type":"CustomEvent<LyraResponsivePanelModeChangeDetail>"}]}},{"name":"lr-result-card","description":"`<lr-result-card>` — a small bordered card shell for a custom tool-result\nrenderer's body (see `<lr-tool-result-view>`'s `registerToolRenderer()`\nin `../tool-result-view/registry.js`). Purely visual, with no state of its\nown beyond slot-presence tracking: it gives every custom renderer the same\n\"small card\" language (border, radius, optional heading + header actions)\nwithout each one hand-rolling its own box.\n\nPairs with `<lr-result-field>` for the label/value rows that typically\nmake up the body, though the default slot accepts any content — nothing\nhere requires a `<lr-result-field>` specifically.\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 card body — typically one or more `<lr-result-field>` rows. |\n| `actions` | Small header controls (e.g. a copy button), rendered alongside the heading. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `actions` | The wrapper around the `actions` slot. `hidden` whenever the slot has no assigned content. |\n| `base` | The outer bordered container. |\n| `body` | The wrapper around the default slot. |\n| `header` | The header row wrapping the heading and the `actions` slot. Present in the DOM at all times (so a later `slotchange` on `actions` is still observed) but `hidden` whenever there is no `heading` and no `actions` content — an untitled, action-less card has no visible header bar at all. |\n| `heading` | The heading text. Truncates with an ellipsis and carries its own native `title` attribute (the full string) so hovering the truncated text reveals it. The host's native `HTMLElement.title` remains independent and is never repurposed or removed. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-result-card-background` (default: `var(--lr-color-surface)`) — Fill of the outer card (`[part=\"base\"]`) while `frame=\"card\"`. `frame=\"plain\"` still removes the fill entirely.\n- `--lr-result-card-border-color` (default: `var(--lr-color-border)`) — Colour of the outer card's border and of the `[part=\"header\"]` divider.\n- `--lr-result-card-compact-body-gap` (default: `var(--lr-space-2xs)`) — Gap between `[part=\"body\"]`'s children while `compact`.\n- `--lr-result-card-compact-body-padding` (default: `var(--lr-space-xs)`) — `[part=\"body\"]` padding while `compact`.\n- `--lr-result-card-compact-header-gap` (default: `var(--lr-space-xs)`) — Gap between `[part=\"header\"]`'s heading and actions while `compact`.\n- `--lr-result-card-compact-header-padding` (default: `var(--lr-space-xs)`) — `[part=\"header\"]` block/inline padding while `compact`.\n- `--lr-result-card-radius` (default: `var(--lr-radius)`) — Corner radius of the outer card. `frame=\"plain\"` still squares the corners.","attributes":[{"name":"compact","description":"Tighter header/body padding for dense contexts (a card rendered as a row in a transcript or\nresult list) -- same convention as `lr-agent-run`'s `compact`. Defaults to `false`, i.e. the\nfull card padding. Purely a density knob: the border and background stay, so use\n`frame=\"plain\"` instead to drop the chrome entirely. `frame=\"plain\"` leaves compact padding\nand gaps intact when both are set.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"frame","description":"Visual chrome, in the library's shared container-frame vocabulary (the same `frame` property\n`<lr-agent-run>` carries). `'card'` (the default) keeps the bordered, filled box. `'plain'`\nremoves the border, background, and corner radius, so a card nested inside a host container\nthat already draws a border (e.g. `<lr-tool-result-view>`'s own chrome) doesn't double it.\n`plain` controls chrome only: compact padding and gaps still apply when both are set.\n\nType: `LyraFrame`  \nDefault: `'card'`","value":{"type":["'card'","'plain'"]}},{"name":"heading","description":"Small visible heading for the card. Leave unset for an untitled card.\nThis is deliberately separate from the host's native `title` tooltip. Removing the attribute clears its displayed text.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"with-actions","description":"Explicit SSR presence hint for an `actions` slot. Browser upgrades also detect assignment\nautomatically, so ordinary client-authored markup does not need it. Server renderers cannot\ninspect light DOM while rendering a custom element; set this when actions must be visible in\nthe no-JS response.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"","description":"The card body — typically one or more `<lr-result-field>` rows."},{"name":"actions","description":"Small header controls (e.g. a copy button), rendered alongside the heading."}],"js":{"properties":[{"name":"compact","description":"Tighter header/body padding for dense contexts (a card rendered as a row in a transcript or\nresult list) -- same convention as `lr-agent-run`'s `compact`. Defaults to `false`, i.e. the\nfull card padding. Purely a density knob: the border and background stay, so use\n`frame=\"plain\"` instead to drop the chrome entirely. `frame=\"plain\"` leaves compact padding\nand gaps intact when both are set.\n\nAttribute: `compact`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"frame","description":"Visual chrome, in the library's shared container-frame vocabulary (the same `frame` property\n`<lr-agent-run>` carries). `'card'` (the default) keeps the bordered, filled box. `'plain'`\nremoves the border, background, and corner radius, so a card nested inside a host container\nthat already draws a border (e.g. `<lr-tool-result-view>`'s own chrome) doesn't double it.\n`plain` controls chrome only: compact padding and gaps still apply when both are set.\n\nAttribute: `frame`  \nReflected to its attribute.","type":"LyraFrame","default":"'card'"},{"name":"heading","description":"Small visible heading for the card. Leave unset for an untitled card.\nThis is deliberately separate from the host's native `title` tooltip. Removing the attribute clears its displayed text.\n\nAttribute: `heading`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"withActions","description":"Explicit SSR presence hint for an `actions` slot. Browser upgrades also detect assignment\nautomatically, so ordinary client-authored markup does not need it. Server renderers cannot\ninspect light DOM while rendering a custom element; set this when actions must be visible in\nthe no-JS response.\n\nAttribute: `with-actions`  \nReflected to its attribute.","type":"boolean","default":"false"}]}},{"name":"lr-result-field","description":"`<lr-result-field>` — a single label/value row, meant for use inside a\n`<lr-result-card>` body (though it works standalone too). Renders as a\ndense \"label: value\" line by default — e.g. \"Status: 200 OK\" or\n\"Duration: 340ms\" — matching the compact, small-card presentation this\npair exists for.\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) | Rich value content (e.g. a `<lr-chip>` status badge, or a plain text override), taking precedence over the `value` prop whenever it has any assigned content. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The row container. |\n| `label` | The label text (including its trailing colon). |\n| `value` | The wrapper around the value — either the slotted content or the plain `value` prop text. |","attributes":[{"name":"label","description":"The field name, e.g. \"Status\". Leave unset or remove the attribute to render a value with no label.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"value","description":"Plain-text value, e.g. \"200 OK\". Ignored once the default slot carries\nreal content — see the `@slot` doc.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"slots":[{"name":"","description":"Rich value content (e.g. a `<lr-chip>` status badge, or a plain text override), taking precedence over the `value` prop whenever it has any assigned content."}],"js":{"properties":[{"name":"label","description":"The field name, e.g. \"Status\". Leave unset or remove the attribute to render a value with no label.\n\nAttribute: `label`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"value","description":"Plain-text value, e.g. \"200 OK\". Ignored once the default slot carries\nreal content — see the `@slot` doc.\n\nAttribute: `value`","type":"string","default":"''"}]}},{"name":"lr-retrieval-compare","description":"`<lr-retrieval-compare>` — a side-by-side retrieval/reranking workbench that makes rank,\noverlap, and dense/sparse/rerank/final score changes inspectable. It never performs retrieval.\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.\nBlank set ids and later duplicates are ignored before overlap, rendering, or activation. Within\neach retained set, blank chunk ids and later duplicates are likewise ignored. First records win.\n\n---\n\n**Component metadata**\n\n- Status: `stable`\n- Since: `7.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 named comparison region. |\n| `chunk` | A selectable chunk row. |\n| `chunk-rank` | The effective rank. |\n| `chunk-selected` | The selected chunk row. |\n| `chunk-text` | Retrieved text. |\n| `chunk-title` | The source title. |\n| `chunks` | One ranked list. |\n| `empty` | The empty state. |\n| `overlap` | The pairwise top-k Jaccard overlap summary. |\n| `score` | One named score. |\n| `scores` | Score-breakdown list. |\n| `set` | One result-set column. |\n| `set-heading` | A caller-supplied result-set label. |\n| `sets` | Horizontally scrollable set grid. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-retrieval-compare-selected-border` (default: `var(--lr-color-brand)`) — Border color marking a selected `[part~=\"chunk\"]` row.","attributes":[{"name":"label","description":"Fallback name for the comparison region. Omitting it falls back to a localized default; an\nexplicit empty string clears it. A non-empty host `aria-label` makes the host the sole\noverall owner; an explicitly empty host label stays empty on the region.\n\nType: `string | undefined`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"selected-chunk-id","description":"Controlled chunk id highlighted across every set that contains it.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"top-k","description":"Maximum ranked chunks shown from each set after stable score ordering.\n\nType: `number`  \nDefault: `10`","value":{"type":["number"]}}],"js":{"properties":[{"name":"label","description":"Fallback name for the comparison region. Omitting it falls back to a localized default; an\nexplicit empty string clears it. A non-empty host `aria-label` makes the host the sole\noverall owner; an explicitly empty host label stays empty on the region.\n\nAttribute: `label`","type":"string | undefined"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"selectedChunkId","description":"Controlled chunk id highlighted across every set that contains it.\n\nAttribute: `selected-chunk-id`","type":"string","default":"''"},{"name":"sets","description":"Named retrieval result sets rendered side by side.","type":"readonly RetrievalComparisonSet[]","default":"[]"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"topK","description":"Maximum ranked chunks shown from each set after stable score ordering.\n\nAttribute: `top-k`","type":"number","default":"10"}],"events":[{"name":"lr-chunk-select","description":"A result was activated. `detail: { setId, chunk }`.","type":"CustomEvent<LyraEventDetailSnapshot<{ setId: string; chunk: RetrievalChunk }>>"}]}},{"name":"lr-retrieval-results","description":"`<lr-retrieval-results>` — the orchestration-level ranked-chunk-list surface: takes raw\n`RetrievalChunk[]` (the shared retrieval-and-grounding type from `src/ai/types.ts`) and adds\neverything a single retrieval call's result set needs beyond what one chunk's own rendering\nprovides -- canonical identity handling, optional grouping by source, multi-selection,\npagination/infinite loading, and a compact/expanded presentation switch -- while composing\nexisting primitives for\nevery part that already has one, never re-implementing chunk/score/source rendering itself.\n\n**Composition, not reinvention.** Each rendered row wraps exactly one chunk in an internal\n`<lr-chunk-inspector>` (fed a single-element `chunks` array), reusing its score bar/tier\ncoloring, title+page rendering, expandable text, and `compact` mode verbatim -- this component\nnever hand-rolls chunk-card markup. `metadata` (arbitrary `Record<string, unknown>`, which no\nexisting primitive renders) is the one genuinely new bit of presentation here, shown as a plain\nkey/value list in `expanded` presentation only. Large result sets are windowed through an\ninternal `<lr-virtual-list>`, exactly like `<lr-thread-list>`'s own data-mode rendering -- each\nrow's rendered content therefore lives inside `<lr-virtual-list>`'s own shadow root, not this\ncomponent's, whenever virtualization is active (see that component's own doc for why).\n\n**Controlled component.** `chunks`/`selectedChunkIds`/`loading`/`errorText`/`hasMore` are all\nhost-owned;\nthis component never fetches, retries, or mutates its own copy of `chunks`. Selecting a row\nupdates `selectedChunkIds` locally *then* emits `lr-select` (the same \"update own copy, then\nemit; reassign to control\" convention `<lr-source-picker>` already uses) so a host can either\naccept the update as-is or override it before the next render.\n\n**Identity.** Blank chunk ids and later duplicates are always omitted first-wins before sorting,\ngrouping, selection, rendering, or events. The `dedupe` switch is retained for compatibility but\ncannot reintroduce ambiguous duplicate identities. **Grouping** (`grouping=\"source\"`) buckets the\ncanonical, score-sorted list by `source.id`, each bucket\nordered by its own best-scoring chunk first, and always renders through the internal\n`<lr-virtual-list>` (regardless of `virtualize-at`) so group headers have a single rendering path\n— `<lr-thread-list>`'s own date-bucket grouping takes the identical approach.\n\n**Pagination.** While virtualized, `has-more`/`loading` are forwarded straight to the internal\n`<lr-virtual-list>`, which fires `lr-load-more` itself on scroll-near-bottom (re-emitted here\nunchanged). Below the virtualization threshold (a short, non-grouped list), scrolling near the\nbottom isn't a meaningful gesture, so a `[part=\"load-more\"]` button takes its place instead,\nshowing a spinner in place of the button while `loading` is true.\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.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| `base` | The outer container and programmatic focus fallback when a controlled collection/state transition removes every focused result action. |\n| `chunk` | The per-row `<lr-chunk-inspector>`'s own `chunk` row. |\n| `chunk-current` | The row `<lr-chunk-inspector>`'s current-chunk state part. |\n| `chunk-open-button` | The row chunk's title/open `<button>`. |\n| `chunk-score` | The row chunk's percent-score line. |\n| `chunk-score-bar` | The row chunk's score bar track. |\n| `chunk-score-current` | The current row chunk's score line. |\n| `chunk-score-fill` | The row chunk's score bar fill. |\n| `chunk-score-fill-danger` | The row chunk's score fill in the low-score tier. |\n| `chunk-score-fill-success` | The row chunk's score fill in the high-score tier. |\n| `chunk-score-fill-warning` | The row chunk's score fill in the medium-score tier. |\n| `chunk-text` | The row chunk's text preview (`presentation=\"expanded\"` only). |\n| `chunk-text-clamped` | The row chunk's text preview while still collapsed. |\n| `chunk-title` | The row chunk's visible title text. |\n| `chunk-toggle` | The row chunk's \"Show more\"/\"Show less\" button. |\n| `empty` | The `<lr-empty>` wrapper, shown when `chunks` is empty and neither `errorText` nor `loading` is set. A later transition into this settled state is announced through a shared polite light-DOM region; initial and reconnect content is not replayed unless `announce` is set, which reads the state present at first mount once. |\n| `error` | The neutral, visible error message shown while `errorText` is non-empty. New non-empty errors are announced through a shared assertive light-DOM region; initial and reconnect content is not replayed unless `announce` is set, which reads the state present at first mount once. |\n| `group-header` | Exported from the internal `<lr-virtual-list>`'s `group` part — grouped/virtualized mode only. |\n| `load-more` | The \"Load more\" button itself (non-virtualized mode, `loading` false). |\n| `load-more-row` | The wrapper around the non-virtualized-mode pagination footer. |\n| `metadata` | The `<dl>` of a chunk's `metadata` entries — omitted entirely when a chunk has no `metadata`, or while `presentation=\"compact\"`. |\n| `metadata-entry` | One metadata key/value pair's wrapper. |\n| `metadata-term` | The `<dt>` carrying a metadata key. Named separately because `::part()` matches one element and cannot be followed into its subtree. |\n| `metadata-value` | The `<dd>` carrying a metadata value. |\n| `row` | One result row's wrapper. Below the virtualization threshold this is a plain, directly-styleable element in this component's own shadow root; while virtualized it is exported from the internal `<lr-virtual-list>`'s own `row` part instead (`::part(row)` still reaches it either way). |\n| `row-body` | The wrapper around a row's `<lr-chunk-inspector>` plus its optional metadata list; carries `data-selected` while that row is selected. |\n| `row-body-selected` | Additional part on a selected `row-body`. State is exposed as a second part name because Shadow Parts forbids an attribute selector after `::part()` — `::part(row-body)[data-selected]` is invalid CSS, and while virtualized `::part()` is the only way in. A state part is a second token in the same `part` attribute, so a `[part~=\"…\"]` (not `[part=\"…\"]`) selector is the one that matches inside a tree. |\n| `select` | The per-row `<lr-checkbox>`, omitted entirely when `selectable` is false. |\n| `spinner` | The initial-load `<lr-spinner>`, shown while `loading` is true and `chunks` is still empty. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-retrieval-results-selected-border` (default: `var(--lr-color-brand)`) — Inline-start border color marking a selected `[part=\"row-body\"]`. A border rather than a fill by design (see the styles file), so recoloring it carries no contrast risk for the row's own text.","attributes":[{"name":"active-chunk-id","description":"Marks the chunk currently open in a viewer -- forwarded to each per-row `<lr-chunk-inspector>`\nand to the internal `<lr-virtual-list>` (which scrolls the matching row into view).\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"announce","description":"Opts this panel into announcing the state it is already presenting the first time it mounts:\nthe verbatim `errorText` assertively, or, with no error and nothing loading, the localized\nempty-result message politely. Set it where the panel is rendered in response to a retrieval\nthe user just ran and nothing else reports the outcome; leave it unset for a panel that is\npart of the page a user is arriving on, whose visible error or empty state is already read\nin document order. Read once, when the panel first mounts: a later reconnection or adoption\nstages the existing state again rather than replaying it, and later transitions are\nannounced either way. A panel that already has chunks announces nothing -- rendered results\nare ordinary content. Remove any host `role=\"status\"`/`role=\"alert\"` hand-added before this\nproperty existed once it is set -- otherwise the initial state is announced twice, through\nthe native role and again through the shared sink.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"dedupe","description":"Retained for compatibility. Identity is always nonblank and first-wins even when false.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"error-text","description":"Non-empty replaces the entire result view with a neutral, visible error message -- caller-\nsupplied text, not routed through `localize()` (the same stance `<lr-document-preview>`'s own\n`error-text` takes for the same reason: this is app/network data, not library copy). New\nnon-empty values are announced through a shared assertive light-DOM region; initial and\nreconnect content is not replayed unless `announce` is set.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"grouping","description":"`'source'` buckets rows under a header per `source.id` (always rendered through the internal\n`<lr-virtual-list>`, regardless of `virtualize-at`); `'custom'` buckets them under whatever key\n`groupBy` returns; `'none'` (default) is a flat ranked list.\n\nType: `RetrievalResultsGrouping`  \nDefault: `'none'`","value":{"type":["'source'","'custom'","'none'"]}},{"name":"has-more","description":"While virtualized, forwarded to the internal `<lr-virtual-list>` so scrolling near the bottom\nfires `lr-load-more`; otherwise shows the built-in `[part=\"load-more\"]` footer.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"label","description":"Fallback name for the results region. Omitting it falls back to the localized\n`chunkInspectorLabel` (\"Retrieved chunks\") -- reused rather than a new key, since it already\nsays exactly what this region is. An explicit empty string clears the fallback. A non-empty\nhost `aria-label` makes the host the sole overall owner; an explicitly empty host label stays\nempty on the region.\n\nType: `string | undefined`"},{"name":"loading","description":"Marks retrieval as pending, selecting the initial spinner or load-more progress state.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"presentation","description":"`'expanded'` (default) shows each chunk's full `<lr-chunk-inspector>` row (score bar, text\npreview with its own expand toggle) plus any `metadata`; `'compact'` shows title + score bar\nonly, on both.\n\nType: `RetrievalResultsPresentation`  \nDefault: `'expanded'`","value":{"type":["'compact'","'expanded'"]}},{"name":"selectable","description":"Shows a per-row `<lr-checkbox>`.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"sort","description":"`'score'` (default) sorts the canonical list descending by `score`; `'none'` preserves\n`chunks`' own given order.\n\nType: `'score' | 'none'`  \nDefault: `'score'`","value":{"type":["'score'","'none'"]}},{"name":"virtualize-at","description":"Above this many rows (after identity canonicalization, before grouping), rendering switches\nfrom a plain list to the internal `<lr-virtual-list>`. Grouped mode always virtualizes\nregardless of this value.\n\nType: `number`  \nDefault: `50`","value":{"type":["number"]}}],"js":{"properties":[{"name":"activeChunkId","description":"Marks the chunk currently open in a viewer -- forwarded to each per-row `<lr-chunk-inspector>`\nand to the internal `<lr-virtual-list>` (which scrolls the matching row into view).\n\nAttribute: `active-chunk-id`","type":"string","default":"''"},{"name":"announce","description":"Opts this panel into announcing the state it is already presenting the first time it mounts:\nthe verbatim `errorText` assertively, or, with no error and nothing loading, the localized\nempty-result message politely. Set it where the panel is rendered in response to a retrieval\nthe user just ran and nothing else reports the outcome; leave it unset for a panel that is\npart of the page a user is arriving on, whose visible error or empty state is already read\nin document order. Read once, when the panel first mounts: a later reconnection or adoption\nstages the existing state again rather than replaying it, and later transitions are\nannounced either way. A panel that already has chunks announces nothing -- rendered results\nare ordinary content. Remove any host `role=\"status\"`/`role=\"alert\"` hand-added before this\nproperty existed once it is set -- otherwise the initial state is announced twice, through\nthe native role and again through the shared sink.\n\nAttribute: `announce`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"chunks","description":"The raw (not deduplicated/sorted/grouped) result set. Host-owned.","type":"readonly RetrievalChunk[]","default":"[]"},{"name":"dedupe","description":"Retained for compatibility. Identity is always nonblank and first-wins even when false.\n\nAttribute: `dedupe`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"errorText","description":"Non-empty replaces the entire result view with a neutral, visible error message -- caller-\nsupplied text, not routed through `localize()` (the same stance `<lr-document-preview>`'s own\n`error-text` takes for the same reason: this is app/network data, not library copy). New\nnon-empty values are announced through a shared assertive light-DOM region; initial and\nreconnect content is not replayed unless `announce` is set.\n\nAttribute: `error-text`","type":"string","default":"''"},{"name":"groupBy","description":"`grouping=\"custom\"`: derives an arbitrary group id for every visible chunk (a date bucket, a\nrelevance tier, a domain-specific bucket). Left unset, `'custom'` degrades to a flat list\nrather than inventing a key, so the built-in identity/sort/virtualization pipeline stays usable\neither way. Mirrors `<lr-thread-list>`'s identical escape hatch.","type":"(chunk: RetrievalChunk) => string | undefined"},{"name":"groupLabel","description":"`grouping=\"custom\"`: renders a group's header label from its id and the chunks in it. Left\nunset, the group id is shown verbatim.","type":"(\n    id: string,\n    chunks: RetrievalChunk[]\n  ) => string | undefined"},{"name":"groupOrder","description":"`grouping=\"custom\"`: explicit group-id order, or a comparator. Ids missing from an array\nfollow in their first-seen order.","type":"| readonly string[]\n    | ((a: string, b: string) => number) | undefined"},{"name":"grouping","description":"`'source'` buckets rows under a header per `source.id` (always rendered through the internal\n`<lr-virtual-list>`, regardless of `virtualize-at`); `'custom'` buckets them under whatever key\n`groupBy` returns; `'none'` (default) is a flat ranked list.\n\nAttribute: `grouping`","type":"RetrievalResultsGrouping","default":"'none'"},{"name":"hasMore","description":"While virtualized, forwarded to the internal `<lr-virtual-list>` so scrolling near the bottom\nfires `lr-load-more`; otherwise shows the built-in `[part=\"load-more\"]` footer.\n\nAttribute: `has-more`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"label","description":"Fallback name for the results region. Omitting it falls back to the localized\n`chunkInspectorLabel` (\"Retrieved chunks\") -- reused rather than a new key, since it already\nsays exactly what this region is. An explicit empty string clears the fallback. A non-empty\nhost `aria-label` makes the host the sole overall owner; an explicitly empty host label stays\nempty on the region.\n\nAttribute: `label`","type":"string | undefined"},{"name":"loading","description":"Marks retrieval as pending, selecting the initial spinner or load-more progress state.\n\nAttribute: `loading`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"presentation","description":"`'expanded'` (default) shows each chunk's full `<lr-chunk-inspector>` row (score bar, text\npreview with its own expand toggle) plus any `metadata`; `'compact'` shows title + score bar\nonly, on both.\n\nAttribute: `presentation`","type":"RetrievalResultsPresentation","default":"'expanded'"},{"name":"selectable","description":"Shows a per-row `<lr-checkbox>`.\n\nAttribute: `selectable`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"selectedChunkIds","description":"Controlled selection, by chunk `id`. The component updates its own copy on toggle *then*\nemits `lr-select`; reassign to control. An id with no matching chunk is harmless -- it simply\nnever renders a checked row.","type":"readonly string[]","default":"[]"},{"name":"sort","description":"`'score'` (default) sorts the canonical list descending by `score`; `'none'` preserves\n`chunks`' own given order.\n\nAttribute: `sort`","type":"'score' | 'none'","default":"'score'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"thresholds","description":"Forwarded verbatim to every per-row `<lr-chunk-inspector>`'s own `thresholds`.","type":"LyraScoreThresholds","default":"{ high: 0.75, medium: 0.5, }"},{"name":"virtualizeAt","description":"Above this many rows (after identity canonicalization, before grouping), rendering switches\nfrom a plain list to the internal `<lr-virtual-list>`. Grouped mode always virtualizes\nregardless of this value.\n\nAttribute: `virtualize-at`","type":"number","default":"50"}],"events":[{"name":"lr-chunk-open","description":"A row's title/open button was activated, forwarded verbatim from the per-row `<lr-chunk-inspector>`'s own `lr-chunk-open`. `detail: { chunkId, sourceId, anchor? }` — the event a host routes into `<lr-document-viewer>`.","type":"CustomEvent<\n    LyraEventDetailSnapshot<{\n      chunkId: string;\n      sourceId: string;\n      anchor?: DocumentLocator;\n    }>\n  >"},{"name":"lr-load-more","description":"More results were requested — via the internal `<lr-virtual-list>`'s own scroll-near-bottom detection while virtualized, or the built-in `[part=\"load-more\"]` button otherwise. Only ever fires while `has-more` is true and `loading` is false.","type":"CustomEvent<null>"},{"name":"lr-select","description":"The selected-chunk set changed. `detail: { chunkIds, chunks }` — `chunkIds` is the complete updated selection (not just the toggled id), `chunks` the matching canonical `RetrievalChunk` records.","type":"CustomEvent<\n    LyraEventDetailSnapshot<RetrievalResultsSelectDetail>\n  >"}]}},{"name":"lr-retrieval-search","description":"`<lr-retrieval-search>` -- the query bar for a retrieval/RAG surface: query text, an active-\nfilter/scope chip row, a vector/keyword/hybrid mode selector, and loading/error/empty status\nfeedback. Consumes `RetrievalQuery` (`src/ai/types.ts`) as the shape emitted on submit.\n\nFully controlled, like every other Lyra input: `query`/`mode`/`filters`/`scope` are host-owned\nproperties. This component never performs retrieval itself -- it only emits `lr-search`; the\nhost owns the actual fetch and toggles `loading` around it. Because this component has no way\nto know when a request resolves (only `loading`, set from outside), submitting again (Enter, or\nclicking the button) while `loading` is already `true` is treated as **superseding** the\nin-flight request: `lr-cancel` fires immediately before the new `lr-search`. The submit button\nitself doubles as an explicit Cancel affordance while `loading` -- clicking it only emits\n`lr-cancel`, without resubmitting, the same \"just stop\" action `<lr-chat-composer>`'s Stop\nbutton offers for its own `stoppable` busy state.\n\nComposes `<lr-input type=\"search\">` for the query field, `<lr-segmented>` for the mode\nselector (the same small-closed-set-choice-in-a-toolbar role it already fills, left at the shared\ndefault size so it resolves the same `--lr-form-control-height` as the query field and the submit\nbutton and the row reads as one flush line), `<lr-chip>`/`<lr-chip-group>` for removable active-filter/scope\nchips, `<lr-spinner>` for the loading state, and `<lr-empty>` (compact) for the empty state.\n`filters`/`scope` chip removal updates this component's own copy first, then emits\n`lr-filters-change` with the complete next state -- the same \"update, then emit; reassign to\ncontrol\" round-trip `<lr-source-picker>`'s `selectedSourceIds` already establishes. `empty` is a\nhost-driven flag (the last completed search returned zero results); this component holds no\nresults data of its own -- see `<lr-retrieval-results>` for rendering the actual chunk list.\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.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| `base` | The root search shell. It owns `role=\"search\"` and the fallback name unless a non-empty host `aria-label` makes the host the sole overall owner. |\n| `empty` | The compact `<lr-empty>`, shown only when `empty` is `true` and neither `loading` nor `errorText` is set. Later transitions into that settled state are announced through a shared polite light-DOM region; the state present at first mount is announced only when `announce` is set. |\n| `error` | The neutral, visible error message, shown only when `errorText` is non-empty and not `loading`. New non-empty errors are announced through a shared assertive light-DOM region; initial and reconnect content is not replayed unless `announce` is set, which reads the state present at first mount once. |\n| `filters` | The active-filter/scope `<lr-chip-group>`. Omitted entirely when both `filters` and `scope` are empty. |\n| `mode` | The vector/keyword/hybrid `<lr-segmented>`. |\n| `query` | The query `<lr-input type=\"search\">`. |\n| `row` | The row holding the query field, mode selector, and submit/cancel button. |\n| `spinner` | The busy `<lr-spinner>`, shown only while `loading`. |\n| `submit` | The submit/cancel `<button>`. Reads \"Search\" while idle, \"Cancel\" while `loading`. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-retrieval-search-submit-min-height` (default: `var(--lr-icon-button-size)`) — Minimum height of the submit button. A `size` tier raises it to that tier's shared form-control height; the shared tappable-target minimum always stays underneath, so no tier can shrink the button past the WCAG floor.","attributes":[{"name":"announce","description":"Opts this search into announcing the state it is already presenting the first time it\nmounts: the verbatim `errorText` assertively, or, with no error and nothing loading, the\nlocalized zero-result message politely. Set it where the search is rendered in response to a\nquery the user just ran and nothing else reports the outcome; leave it unset for a search\nthat is part of the page a user is arriving on, whose visible error or empty state is\nalready read in document order. Read once, when the search first mounts: a later\nreconnection or adoption stages the existing state again rather than replaying it, and later\ntransitions are announced either way. A search presenting neither state announces nothing.\nRemove any host `role=\"status\"`/`role=\"alert\"` hand-added before this property existed once\nit is set -- otherwise the initial state is announced twice, through the native role and\nagain through the shared sink.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"aria-label","description":"JS-only accessible-name override for the inner search landmark. A non-empty markup\n`aria-label` names the host as the sole overall owner instead.\n\nType: `string | null`  \nDefault: `null`"},{"name":"empty","description":"Host-driven flag: the last completed search returned zero results. Renders a compact\n`<lr-empty>` beneath the search row and politely announces later transitions into that\nsettled state. Never inferred by this component itself -- see the class doc; it holds no\nresults data of its own.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"error-text","description":"Host-supplied error message from the last failed search, shown verbatim (caller-owned text,\nnot localized) in a neutral visible region. New non-empty values are announced through a\nshared assertive light-DOM region; initial and reconnect content is not replayed unless\n`announce` is set. Empty string (the default) shows nothing.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"label","description":"Accessible name for the inner search landmark when the host has no `aria-label`. Omitting it\nfalls back to the localized default; an explicit empty string clears it.\n\nType: `string | undefined`"},{"name":"loading","description":"Host-driven busy flag. This component never performs retrieval itself and has no way to know\nwhen a request resolves, so the host toggles this explicitly around its own fetch -- see the\nclass doc for the resulting submit/cancel/supersede behavior.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"mode","description":"Retrieval mode. Defaults to `'hybrid'`, the common default for a search bar combining both\nvector and keyword retrieval.\n\nType: `LyraRetrievalMode`","value":{"type":["'vector'","'keyword'","'hybrid'"]}},{"name":"placeholder","description":"Placeholder for the query field. Empty string (the default) falls back to the localized\ngeneric \"Search\" placeholder, which also becomes that field's accessible name (mirroring\n`<lr-input>`'s own placeholder-as-label fallback).\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"query","description":"The current query text. Controlled -- the internal `lr-input` updates this optimistically as\nthe user types (mirroring every other Lyra input's controlled-value convention), and a host\nreassignment always wins.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"size","description":"Density tier for the whole query row, on the library's one size ladder, in either spelling --\n`2xs`/`xs`/`s`/`m`/`l`/`xl`, or Web Awesome's and Shoelace's `small`/`medium`/`large`. It is\none property for all three controls on purpose: the query field, the mode selector and the\nsubmit button share the row's baseline, and sizing any one of them alone is what makes the\nrow ragged. Forwarding is the only way to reach the first two, which resolve their tier\ninside their own shadow roots, and it is forwarded as a property rather than an attribute\nbecause removing an already-written `size` attribute again would leave each child's own\n`size` at `null` instead of back at its own default. Opt-in: with no size every control keeps\nits own `m` default, exactly what the row rendered before, and the submit button keeps the\nshared tappable-target floor at every tier. Unsupported values normalize to the omitted state\nand remove the attribute.\n\nType: `LyraSize | undefined`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}}],"js":{"properties":[{"name":"accessibleLabel","description":"JS-only accessible-name override for the inner search landmark. A non-empty markup\n`aria-label` names the host as the sole overall owner instead.\n\nAttribute: `aria-label`","type":"string | null","default":"null"},{"name":"announce","description":"Opts this search into announcing the state it is already presenting the first time it\nmounts: the verbatim `errorText` assertively, or, with no error and nothing loading, the\nlocalized zero-result message politely. Set it where the search is rendered in response to a\nquery the user just ran and nothing else reports the outcome; leave it unset for a search\nthat is part of the page a user is arriving on, whose visible error or empty state is\nalready read in document order. Read once, when the search first mounts: a later\nreconnection or adoption stages the existing state again rather than replaying it, and later\ntransitions are announced either way. A search presenting neither state announces nothing.\nRemove any host `role=\"status\"`/`role=\"alert\"` hand-added before this property existed once\nit is set -- otherwise the initial state is announced twice, through the native role and\nagain through the shared sink.\n\nAttribute: `announce`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"empty","description":"Host-driven flag: the last completed search returned zero results. Renders a compact\n`<lr-empty>` beneath the search row and politely announces later transitions into that\nsettled state. Never inferred by this component itself -- see the class doc; it holds no\nresults data of its own.\n\nAttribute: `empty`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"errorText","description":"Host-supplied error message from the last failed search, shown verbatim (caller-owned text,\nnot localized) in a neutral visible region. New non-empty values are announced through a\nshared assertive light-DOM region; initial and reconnect content is not replayed unless\n`announce` is set. Empty string (the default) shows nothing.\n\nAttribute: `error-text`","type":"string","default":"''"},{"name":"filters","description":"Arbitrary metadata filters, rendered as removable `\"{key}: {value}\"` chips. Controlled --\nreassign to change what's shown; see the class doc's \"update, then emit\" round-trip.","type":"Readonly<Record<string, unknown>>","default":"{}"},{"name":"label","description":"Accessible name for the inner search landmark when the host has no `aria-label`. Omitting it\nfalls back to the localized default; an explicit empty string clears it.\n\nAttribute: `label`","type":"string | undefined"},{"name":"loading","description":"Host-driven busy flag. This component never performs retrieval itself and has no way to know\nwhen a request resolves, so the host toggles this explicitly around its own fetch -- see the\nclass doc for the resulting submit/cancel/supersede behavior.\n\nAttribute: `loading`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"mode","description":"Retrieval mode. Defaults to `'hybrid'`, the common default for a search bar combining both\nvector and keyword retrieval.\n\nAttribute: `mode`","type":"LyraRetrievalMode"},{"name":"placeholder","description":"Placeholder for the query field. Empty string (the default) falls back to the localized\ngeneric \"Search\" placeholder, which also becomes that field's accessible name (mirroring\n`<lr-input>`'s own placeholder-as-label fallback).\n\nAttribute: `placeholder`","type":"string","default":"''"},{"name":"query","description":"The current query text. Controlled -- the internal `lr-input` updates this optimistically as\nthe user types (mirroring every other Lyra input's controlled-value convention), and a host\nreassignment always wins.\n\nAttribute: `query`","type":"string","default":"''"},{"name":"scope","description":"Source-scope ids/labels this query is restricted to, rendered as removable chips alongside\n`filters`. Same controlled round-trip as `filters`.","type":"readonly string[]","default":"[]"},{"name":"size","description":"Density tier for the whole query row, on the library's one size ladder, in either spelling --\n`2xs`/`xs`/`s`/`m`/`l`/`xl`, or Web Awesome's and Shoelace's `small`/`medium`/`large`. It is\none property for all three controls on purpose: the query field, the mode selector and the\nsubmit button share the row's baseline, and sizing any one of them alone is what makes the\nrow ragged. Forwarding is the only way to reach the first two, which resolve their tier\ninside their own shadow roots, and it is forwarded as a property rather than an attribute\nbecause removing an already-written `size` attribute again would leave each child's own\n`size` at `null` instead of back at its own default. Opt-in: with no size every control keeps\nits own `m` default, exactly what the row rendered before, and the submit button keeps the\nshared tappable-target floor at every tier. Unsupported values normalize to the omitted state\nand remove the attribute.\n\nAttribute: `size`  \nReflected to its attribute.","type":"LyraSize | undefined"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-cancel","description":"The in-flight request should be cancelled: either the user clicked the button while `loading` (`detail: {}`), or a new submission superseded the in-flight one before it resolved (`detail: { reason: 'superseded' }`, fired immediately before the new `lr-search`).","type":"CustomEvent<CancelEventDetail>"},{"name":"lr-filters-change","description":"A `filters`/`scope` chip's remove button was activated. `detail`: the complete updated `{ filters, scope }` state.","type":"CustomEvent<\n    LyraEventDetailSnapshot<RetrievalFiltersChangeDetail>\n  >"},{"name":"lr-search","description":"The query was submitted (Enter in the query field, or the submit button while not `loading`). `detail`: the full `RetrievalQuery` (`{ text, mode, filters, scope }`).","type":"CustomEvent<LyraEventDetailSnapshot<RetrievalQuery>>"}]}},{"name":"lr-retrieval-trace","description":"`<lr-retrieval-trace>` — a retrieval pipeline's stage timeline (query rewriting, embedding,\nretrieval, reranking, filtering), rendered through `<lr-span-waterfall>`'s existing\ntime-scaled bar rendering, plus a disclosure list below it exposing each stage's evidence:\nfree-form text, retrieved/reranked/filtered chunks via `<lr-chunk-inspector>`, and/or arbitrary\nstage metadata. Never fetches, ranks, or computes retrieval results itself.\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.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| `base` | The root wrapper. |\n| `chunk-inspector` | The stage-owned chunk inspector; its generic child actions are stopped and re-emitted as `lr-stage-chunk-action`. |\n| `evidence-body` | A stage's evidence content wrapper, hidden while collapsed. |\n| `evidence-list` | The wrapper around every stage's evidence disclosure row. Omitted when no stage has evidence. |\n| `evidence-metadata` | A stage's key/value metadata list (a `<dl>`). |\n| `evidence-metadata-key` | One metadata entry's key (a `<dt>`). |\n| `evidence-metadata-row` | One metadata entry's `<dt>`/`<dd>` pair wrapper, inside `evidence-metadata`. |\n| `evidence-metadata-value` | One metadata entry's value (a `<dd>`). |\n| `evidence-row` | One stage's evidence disclosure row. Omitted for a stage with no evidence. |\n| `evidence-text` | A stage's free-form text evidence. |\n| `evidence-toggle` | A stage's evidence disclosure `<button>`. |\n| `evidence-toggle-icon` | The disclosure button's chevron glyph. |\n| `timeline` | The internal `<lr-span-waterfall>` element. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-retrieval-trace-active-border` (default: `var(--lr-color-brand)`) — Border color of the `[part=\"evidence-row\"]` whose stage matches `activeStageId`.","attributes":[{"name":"active-stage-id","description":"Controlled selection, forwarded verbatim to the internal `<lr-span-waterfall>`'s `activeSpanId`.\n\nType: `string | null`  \nDefault: `null`"},{"name":"label","description":"Accessible name for the internal timeline. A host `aria-label` independently names the\ntrace as a whole; an empty value falls back to the timeline's localized default.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"js":{"properties":[{"name":"activeStageId","description":"Controlled selection, forwarded verbatim to the internal `<lr-span-waterfall>`'s `activeSpanId`.\n\nAttribute: `active-stage-id`","type":"string | null","default":"null"},{"name":"label","description":"Accessible name for the internal timeline. A host `aria-label` independently names the\ntrace as a whole; an empty value falls back to the timeline's localized default.\n\nAttribute: `label`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"stages","description":"The pipeline's stages, in any order -- the internal timeline sorts them by `startMs`.","type":"readonly RetrievalStage[]","default":"[]"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-stage-chunk-action","description":"A chunk inside a stage was opened or expanded. The discriminated detail always includes `stageId` and `action`, so consumers never infer ownership from DOM ancestry.","type":"CustomEvent<LyraEventDetailSnapshot<LyraRetrievalTraceChunkActionDetail>>"},{"name":"lr-stage-select","description":"A stage's bar was activated in the timeline (click, Enter, Space). `detail: { stageId }`.","type":"CustomEvent<{ stageId: string }>"},{"name":"lr-stage-toggle","description":"A stage's evidence panel was expanded or collapsed (via its own toggle, or implicitly by selecting that stage in the timeline for the first time). `detail: { stageId, expanded }`.","type":"CustomEvent<{ stageId: string; expanded: boolean }>"}]}},{"name":"lr-rubric-form","description":"`<lr-rubric-form>` — a configurable annotation rubric (LangSmith\nannotation-queue style): score, category, and freeform-comment keys with\na submit-and-next flow for working through an eval queue.\n\nEach `RubricKey.type` routes to an existing sibling control: `score`\nrenders `<lr-segmented>` when its `[min, max]`/`step` domain has 10 or\nfewer integer steps, or `<lr-slider>` otherwise; `category` renders\n`<lr-select>` (single) or `<lr-checkbox-group>` (`multiple`); `comment`\nrenders `<lr-textarea>`. Both score branches format visible numeric labels with the effective\nlocale; segmented item values and submitted rubric values remain stable raw numbers/strings.\nA key whose `type` is none of the three renders\na visible \"Unsupported field type\" note instead of silently dropping it,\nand marks the form invalid — the same defensive shape as\n`<lr-tool-param-form>`'s own unsupported-property fallback.\nThe exported key model is a readonly discriminated union. Live/default/restored values are\ncanonicalized once against that current schema before render, validity, events, or FormData:\nscores clamp/snap to their domain, categories retain only declared option occurrences,\ncomments require strings, and undeclared fields are discarded. A wide slider score without a\nsupplied default records its rendered, snapped midpoint in both the default and live value;\nsegmented scores remain unselected. `defaultValue` is the explicit reset baseline; reads return\ndefensive snapshots.\nReplacing the parent value reconciles live multiple-category checkbox state, even immediately\nafter a user edit, without changing child reset defaults or emitting user-edit events.\n\nOptional native `<form>` participation is implemented via `ElementInternals`\nattached directly (this component's value is a whole object, not a plain\nstring, so the `FormAssociated` string-value mixin doesn't fit) — the same\nshape `<lr-tool-param-form>` uses. This is a nice-to-have layered on top\nof the primary integration contract (`value` +\n`lr-input`/`lr-validity-change`/`lr-submit`/`lr-skip`), not a\nrequirement: a consumer that never puts this inside a `<form>` loses\nnothing.\nAggregate `label`, `hint`, and `errorText` properties have matching slots and\nsame-shadow ARIA links on the outer `base` role=\"group\". A host `aria-label` wins by attribute\npresence (including an explicitly empty value), while each rubric field keeps its own\nfield-level name. When `errorText` is empty, a consumer `setCustomValidity()` message is rendered\nin the aggregate error region so a blocking whole-form error is never silent.\nHost-root external descriptions precede the aggregate hint/error guidance and follow live source\nidentity changes, reconnection and adoption. They stay on the aggregate group; child fields keep\ntheir own guidance. Removing label or hint safely removes that copy while retaining native\nattribute-removal property readback.\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| `actions` | Extra host controls rendered in the footer beside Submit/Skip. |\n| `error` | Aggregate validation text; supplements `errorText` or the current custom error. |\n| `hint` | Aggregate supporting text rendered after all fields. |\n| `label` | Aggregate rubric label rendered before all fields. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `aggregate-error` | Aggregate error text; also carries `form-control-error`. |\n| `aggregate-hint` | Aggregate supporting text; also carries `form-control-help-text`. |\n| `aggregate-label` | Aggregate rubric label; separate from per-field `label` parts. |\n| `base` | The outer wrapper around all fields. |\n| `description` | A field's helper text. |\n| `empty` | The message shown when `keys` has no entries. |\n| `error` | Ordinary field-level validation text composed into its control's accessible name/description; it is not a live region, avoiding duplicate report-validity announcements. |\n| `field` | One key's wrapper (label + control + description + error). |\n| `fields` | Wrapper around every rubric field or the empty state. |\n| `footer` | The row containing the actions slot and Submit/Skip buttons. |\n| `form-control` | Aggregate form-control wrapper around label, fields, hint, and error. |\n| `form-control-error` | Shared form-control alias on the aggregate error. |\n| `form-control-help-text` | Shared form-control alias on the aggregate hint. |\n| `form-control-input` | Shared form-control alias on the fields wrapper. |\n| `form-control-label` | Shared form-control alias on the aggregate label. |\n| `label` | A field's label. |\n| `scale` | The rendered score/category/comment control's wrapper. |\n| `skip` | The Skip button (only rendered when `skippable`). |\n| `submit` | The Submit button. |\n| `unsupported` | The fallback note for a key whose `type` is outside the three supported ones. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-form-control-required-color` (default: `var(--lr-color-danger)`) — Color of that marker, independently retunable from field errors.\n- `--lr-form-control-required-content` (default: `' *'`) — Required-field marker after rubric-owned score and unsupported-field labels. Set it to `''` to suppress the marker, or to any other quoted string (`' (required)'`, a localized word) to replace it.\n- `--lr-form-control-required-offset` (default: `0`) — Inline space between the label text and marker.\n- `--lr-rubric-form-skip-active-bg` (default: `color-mix(...)`) — Skip background while pressed.\n- `--lr-rubric-form-skip-bg` (default: `var(--lr-color-surface)`) — Skip-button background.\n- `--lr-rubric-form-skip-border-color` (default: `var(--lr-color-border)`) — Skip-button border.\n- `--lr-rubric-form-skip-color` (default: `var(--lr-color-text)`) — Skip-button text color.\n- `--lr-rubric-form-skip-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Skip background while hovered.\n- `--lr-rubric-form-submit-active-bg` (default: `color-mix(...)`) — Submit background while pressed.\n- `--lr-rubric-form-submit-active-border-color` (default: `color-mix(...)`) — Submit border while pressed.\n- `--lr-rubric-form-submit-bg` (default: `var(--lr-color-brand)`) — Submit-button background.\n- `--lr-rubric-form-submit-border-color` (default: `var(--lr-color-brand)`) — Submit-button border.\n- `--lr-rubric-form-submit-color` (default: `var(--lr-color-on-brand)`) — Submit-button text color.\n- `--lr-rubric-form-submit-hover-bg` (default: `color-mix(...)`) — Submit background while hovered.\n- `--lr-rubric-form-submit-hover-border-color` (default: `color-mix(...)`) — Submit border while hovered.","attributes":[{"name":"custom-error","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nType: `string | null`"},{"name":"disabled","description":"Type: `boolean`","value":{"type":["boolean"]}},{"name":"error-text","description":"Aggregate visible error text. A consumer custom-validity message is shown when this is empty.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"form","description":"Type: `HTMLFormElement | string | null`  \nDefault: `null`"},{"name":"has-next","description":"Type: `boolean`","value":{"type":["boolean"]}},{"name":"hint","description":"Aggregate supporting text.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"item-id","description":"Type: `string`","value":{"type":["string"]}},{"name":"label","description":"Aggregate label for the complete rubric. Rich content can use the matching slot.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"name","description":"Type: `string`","value":{"type":["string"]}},{"name":"skippable","description":"Type: `boolean`","value":{"type":["boolean"]}},{"name":"with-hint","description":"SSR hint-presence hint; hydrated instances also discover populated hint/help-text slots.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"with-label","description":"SSR label-presence hint; hydrated instances also discover populated slots.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"actions","description":"Extra host controls rendered in the footer beside Submit/Skip."},{"name":"error","description":"Aggregate validation text; supplements `errorText` or the current custom error."},{"name":"hint","description":"Aggregate supporting text rendered after all fields."},{"name":"label","description":"Aggregate rubric label rendered before all fields."}],"js":{"properties":[{"name":"customError","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nAttribute: `custom-error`  \nReflected to its attribute.","type":"string | null"},{"name":"defaultValue","description":"Explicit native form-reset baseline. Changing it updates pristine live state only.","type":"RubricValue"},{"name":"disabled","description":"Attribute: `disabled`  \nReflected to its attribute.","type":"boolean"},{"name":"effectiveDisabled","description":"Whether the form is disabled explicitly or by an ancestor fieldset.","type":"boolean","read-only":true},{"name":"errorText","description":"Aggregate visible error text. A consumer custom-validity message is shown when this is empty.\n\nAttribute: `error-text`","type":"string","default":"''"},{"name":"errors","description":"The current effective validation errors. Intrinsic errors are keyed by their rubric key;\na caller-supplied custom validity message is keyed by the whole-control `base` part.","type":"Readonly<Record<string, string>>","read-only":true},{"name":"form","description":"Attribute: `form`  \nReflected to its attribute.","type":"HTMLFormElement | string | null","default":"null"},{"name":"hasNext","description":"Attribute: `has-next`","type":"boolean"},{"name":"hint","description":"Aggregate supporting text.\n\nAttribute: `hint`","type":"string","default":"''"},{"name":"itemId","description":"Attribute: `item-id`  \nReflected to its attribute.","type":"string"},{"name":"keys","type":"readonly RubricKey[]"},{"name":"label","description":"Aggregate label for the complete rubric. Rich content can use the matching slot.\n\nAttribute: `label`","type":"string","default":"''"},{"name":"labels","description":"Delegates straight to `ElementInternals.labels` -- no logic of its own.","type":"NodeList","read-only":true},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"name","description":"Attribute: `name`  \nReflected to its attribute.","type":"string"},{"name":"skippable","description":"Attribute: `skippable`","type":"boolean"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"validationMessage","type":"string","read-only":true},{"name":"validity","type":"ValidityState","read-only":true},{"name":"value","description":"Canonical live structured value. Reads are defensive snapshots; writes are normalized against\nthe current discriminated schema before rendering, validity, events, and form submission.","type":"RubricValue"},{"name":"willValidate","type":"boolean","read-only":true},{"name":"withHint","description":"SSR hint-presence hint; hydrated instances also discover populated hint/help-text slots.\n\nAttribute: `with-hint`","type":"boolean","default":"false"},{"name":"withLabel","description":"SSR label-presence hint; hydrated instances also discover populated slots.\n\nAttribute: `with-label`","type":"boolean","default":"false"}],"events":[{"name":"lr-input","description":"`detail: { value }` — any control changed; the full current value object.","type":"CustomEvent<Readonly<{ value: RubricValue }>>"},{"name":"lr-invalid","description":"The complete rubric form failed a validity check. Cancelable; preventing it also prevents the native `invalid` event's default validation UI.","type":"CustomEvent<null>"},{"name":"lr-skip","description":"`detail: { itemId }` — Skip activated (`skippable` only); no validation.","type":"CustomEvent<{ itemId: string }>"},{"name":"lr-submit","description":"`detail: { value, itemId }` — Submit clicked or Ctrl/Cmd+Enter, after validity passes.","type":"CustomEvent<Readonly<{ value: RubricValue; itemId: string }>>"},{"name":"lr-validity-change","description":"`detail: { valid, errors }` — fired only on an actual change.","type":"CustomEvent<{\n    readonly valid: boolean;\n    readonly errors: Readonly<Record<string, string>>;\n  }>"}]}},{"name":"lr-scatter-chart","description":"`<lr-scatter-chart>` — `<lr-chart>` with a `\"scatter\"` default and the mirrored writable type. Feed\npoints via `LyraChartSeries.points`.\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) | An optional `<script type=\"application/json\">` containing a Chart.js configuration. |\n| `center` | Optional overlay content positioned at the chart area's center. Useful for doughnut and pie totals. |\n| `data-table` | An optional consumer-provided accessible table alternative. Use this escape hatch for a complete paginated or virtualized alternative when the generated 1,000-record sample is insufficient. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The chart wrapper. |\n| `canvas` | The Chart.js canvas. |\n| `center` | The chart-area-centered overlay wrapper for the `center` slot. |\n| `data-table` | The optional generated or slotted data table. |\n| `data-table-toggle` | The disclosure button rendered by `dataTableToggle`. |\n| `data-truncation` | Explanation shown when the generated accessible alternative samples a data set larger than its 1,000-record ceiling. |\n| `description` | The accessible chart summary. |\n| `error` | Static visible error shown instead of `canvas` when the optional `chart.js` peer dependency is not installed; its transition is announced through a shared light-DOM alert. |\n| `feature-warning` | Static nonfatal warning when a requested optional feature peer is unavailable while the core chart remains usable. |\n| `legend` | The wrapping DOM legend, rendered unless `withoutLegend` is set. |\n| `legend-item` | A keyboard-operable dataset or category visibility toggle. |\n| `legend-item-hidden` | Added while the legend item's dataset or category is hidden. |\n| `legend-swatch` | The resolved dataset/category color swatch in a legend item. |\n| `notices` | Wrapper for nonfatal feature warnings and generated-data truncation notices. |\n| `plot` | The fixed-height canvas/overlay region. |\n| `reset-zoom-button` | The reset-zoom control when zoom is active. |\n\n---\n\n**CSS Custom Properties**\n\n- `--border-color-1` (default: `var(--lr-color-chart-1)`) — First dataset border color.\n- `--border-color-2` (default: `var(--lr-color-chart-2)`) — Second dataset border color.\n- `--border-color-3` (default: `var(--lr-color-chart-3)`) — Third dataset border color.\n- `--border-color-4` (default: `var(--lr-color-chart-4)`) — Fourth dataset border color.\n- `--border-color-5` (default: `var(--lr-color-chart-5)`) — Fifth dataset border color.\n- `--border-color-6` (default: `var(--lr-color-chart-6)`) — Sixth dataset border color.\n- `--border-radius` (default: `var(--lr-radius)`) — Dataset element corner radius.\n- `--border-width` (default: `var(--lr-border-width-thin)`) — Dataset element border width.\n- `--fill-color-1` (default: `var(--lr-color-chart-1)`) — First dataset fill color.\n- `--fill-color-2` (default: `var(--lr-color-chart-2)`) — Second dataset fill color.\n- `--fill-color-3` (default: `var(--lr-color-chart-3)`) — Third dataset fill color.\n- `--fill-color-4` (default: `var(--lr-color-chart-4)`) — Fourth dataset fill color.\n- `--fill-color-5` (default: `var(--lr-color-chart-5)`) — Fifth dataset fill color.\n- `--fill-color-6` (default: `var(--lr-color-chart-6)`) — Sixth dataset fill color.\n- `--grid-border-width` (default: `var(--lr-border-width-thin)`) — Axis and grid line width.\n- `--grid-color` (default: `var(--lr-chart-grid-color)`) — Grid line color.\n- `--line-border-width` (default: `var(--lr-border-width-medium)`) — Line dataset stroke width.\n- `--lr-chart-canvas-hover-outline-color` (default: `var(--lr-chart-grid-color)`) — Color of the `[part='canvas']` hover-state outline.\n- `--lr-chart-canvas-hover-outline-width` (default: `var(--lr-border-width-thin)`) — Width of the `[part='canvas']` hover-state outline.\n- `--lr-chart-data-table-button-active-bg` — Pressed background of an actionable generated- table value; defaults to the standard active mix of `--lr-color-brand-quiet`.\n- `--lr-chart-data-table-button-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background of an actionable generated-table value.\n- `--lr-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-chart-data-table-toggle-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background of the `dataTableToggle` disclosure button.\n- `--lr-chart-grid-color` (default: `var(--lr-color-border)`) — Grid-line color. Resolved via `getComputedStyle` on every draw (Chart.js paints to canvas and cannot consume `var()`).\n- `--lr-chart-height` (default: `var(--lr-size-280px)`) — The plot region's `block-size` and the host's minimum block size. A visible data table or wrapping DOM legend grows the host in normal flow instead of overlapping following content. `height` supplies a private fallback; this public token always wins when a consumer sets it.\n- `--lr-chart-legend-color` (default: `var(--lr-color-text)`) — Legend label color. Resolved via `getComputedStyle` on every draw.\n- `--lr-chart-legend-item-active-bg` — Pressed background of a legend visibility button; defaults to the standard active mix of `--lr-color-brand-quiet`.\n- `--lr-chart-legend-item-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background of a legend visibility button.\n- `--lr-chart-legend-side-max` (default: `var(--lr-size-15rem)`) — Maximum inline size reserved for a side-positioned DOM legend; the track is also capped at one third of the chart allocation.\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 every series collapses to one system color and the stripe/crosshatch pattern 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.\n- `--lr-chart-reset-zoom-button-active-bg` — Pressed background of the reset-zoom button; defaults to the standard active mix of `--lr-color-brand-quiet`.\n- `--lr-chart-reset-zoom-button-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background of the reset-zoom button.\n- `--lr-chart-tick-color` (default: `var(--lr-color-text-quiet)`) — Axis tick-label color; also used for the `xLabel`/`yLabel`/`y2Label` axis-title text (there is no separate title-color token). Resolved via `getComputedStyle` on every draw.\n- `--lr-chart-tick-font-size` (default: `var(--lr-font-size-xs)`) — Axis tick-label font size, in any CSS length unit. Defaults to `--lr-font-size-xs` (12px at the standard root) because that matches Chart.js's OWN built-in tick font size, which is what every canvas chart rendered before this token existed -- leaving it unset must stay byte-identical to that, not shrink to `<lr-lite-chart>`'s SVG default. Also sizes the radar/polarArea `r`-scale `pointLabels` (the spoke labels), but ONLY once set: those default separately to Chart.js's OWN distinct `RadialLinearScale` `pointLabels` default (10px, not this token's 12px), and only adopt this token's size once the consumer explicitly sets it, at which point ticks and point labels match. Resolved via `getComputedStyle` on every draw, same constraint as every other `--lr-chart-*` token here (Chart.js paints to canvas and cannot consume `var()`).\n- `--lr-chart-tooltip-bg` (default: `var(--lr-color-surface)`) — Tooltip background color. Resolved via `getComputedStyle` on every draw.\n- `--lr-chart-tooltip-text` (default: `var(--lr-color-text)`) — Tooltip text color. Resolved via `getComputedStyle` on every draw.\n- `--point-radius` (default: `var(--lr-space-2xs)`) — Line/scatter point radius.","attributes":[{"name":"area","description":"Chart-wide default fill-under-line setting for line-type series; a series's own `LyraChartSeries.fill` overrides it.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"axes","description":"Complete cartesian axis visibility, independent of grid. `y` also controls the y2 axis.\nRadial charts ignore this setting. Explicit config scale options retain precedence.\n\nType: `LyraChartAxes`  \nDefault: `'both'`","value":{"type":["'x'","'y'","'both'","'none'"]}},{"name":"begin-at-zero","description":"Type: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"compact","description":"Compact cartesian plot: hide axes and remove automatic layout padding. Set height and\nwithoutLegend for a small histogram/sparkline. Preserves data tables, tooltips and keyboard\nactions; radial charts ignore this setting. Explicit config options retain precedence.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"data-labels","description":"Draws each data point's value on the chart via the optional\n`chartjs-plugin-datalabels` peer. Unset (the default) leaves labels off for\nthis chart; the peer is attached only to instances that opt in, and\n`buildConfig()` keeps its per-chart options disabled until this is set. The\nscreen-reader equivalent is the always-present data table (see\n`show-data-table`); labels are a purely visual, canvas-only addition.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"data-table-toggle","description":"Render a disclosure button above the accessible data table so a sighted reader can reveal the\nnumbers behind the chart on demand. `showDataTable` alone is all-or-nothing -- the table is\neither permanently screen-reader-only or permanently visible -- which left a consumer wrapping\na duplicated table in their own `<details>`.\n\nWith this set, `showDataTable` becomes the disclosure's *initial* state rather than its whole\nbehavior. The table stays in the DOM in both states, so assistive technology never loses it.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"description","description":"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`"},{"name":"grid","description":"Controls which cartesian grid axes are drawn.\n\nType: `LyraChartGrid`  \nDefault: `'both'`","value":{"type":["'x'","'y'","'both'","'none'"]}},{"name":"height","description":"Type: `string`  \nDefault: `'280px'`","value":{"type":["string"]}},{"name":"index-axis","description":"Chart.js index axis. `'y'` is Chart.js's own mechanism for horizontal bars (it also flips\nline/area types onto a horizontal category axis).\n\nType: `LyraChartIndexAxis`  \nDefault: `'x'`","value":{"type":["'x'","'y'"]}},{"name":"label","description":"Accessible chart label. A host `aria-label` still has highest precedence.\n\nType: `string | null`  \nDefault: `null`"},{"name":"legend-display","description":"`auto` retains optional legend formatting; `label` omits values even with a formatter; `value`\nappends a formatted value. `percentage` uses locale percentages of the absolute represented\nlegend values, including hidden items (zero totals yield 0%). `value-percentage` appends both,\nas `label: value (percentage)`. Dataset values are sampled sums; category values come from the\nfirst dataset. The `formatter`/`valueFormatter` callback backing `value` and `value-percentage`\nadditionally receives that same `percentage` in its `surface: 'legend'` context, so a custom\nformatter can build its own combined text without recomputing the share. Tooltip and axis\nformatting are unchanged.\n\nType: `LyraChartLegendDisplay`  \nDefault: `'auto'`","value":{"type":["'auto'","'label'","'value'","'percentage'","'value-percentage'"]}},{"name":"legend-mode","description":"`datum` renders category toggles for pie/doughnut/polar-area charts. Categories use the first\ndataset's colors and values; a toggle affects that category in every ring. Other chart types\nretain dataset legends. `auto` (the default) resolves to `datum` on pie/doughnut/polar-area\ncharts -- where a single-dataset legend would otherwise enumerate one entry for the whole\ndataset instead of one per visible slice -- and to `dataset` everywhere else. `dataset` always\nforces the dataset legend, even on a slice chart. Both non-`auto` modes use the generated\naccessible-data sampling budget.\n\nType: `LyraChartLegendMode`  \nDefault: `'auto'`","value":{"type":["'auto'","'dataset'","'datum'"]}},{"name":"legend-position","description":"Legend placement. `auto` uses a right legend above 480px and a bottom legend below it.\n\nType: `LyraChartLegendPosition`  \nDefault: `'top'`","value":{"type":["'left'","'top'","'right'","'bottom'","'center'","'chartArea'","'start'","'end'","'auto'"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max","description":"Maximum value-axis bound. Non-finite values are ignored.\n\nType: `number | null`  \nDefault: `null`"},{"name":"min","description":"Minimum value-axis bound. Non-finite values are ignored.\n\nType: `number | null`  \nDefault: `null`"},{"name":"plugins","description":"Chart.js plugins attached to this chart instance. Valid plugins retain their opaque identity.\n\nType: `readonly LyraChartPlugin[]`  \nDefault: `[]`"},{"name":"scale-type","description":"Scale type for the **value** axis (the categorical axis is unaffected). `'logarithmic'` plots\na dataset spanning several orders of magnitude honestly, where a linear axis collapses\neverything below the maximum into the baseline. Inherited by `lr-line-chart`,\n`lr-scatter-chart` and `lr-bar-chart`.\n\nA logarithmic axis cannot represent zero or negative values (`log(0)` is `-Infinity`), so\n`beginAtZero` is not forwarded in that mode -- Chart.js would otherwise be handed a bound it\ncannot place. Non-positive data points are dropped by Chart.js's own log scale.\n\nType: `LyraChartScaleType`  \nDefault: `'linear'`","value":{"type":["'linear'","'logarithmic'"]}},{"name":"show-data-table","description":"Makes the generated data table visible; it remains screen-reader available when false.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"stack-totals","description":"When the chart is `stacked` (bar/line only), draws the per-category stack\ntotal above each stack, via the same optional `chartjs-plugin-datalabels`\npeer as `data-labels`. Null/undefined points are skipped; a category whose\nevery value is null shows no total. The generated accessible data table\nreceives the same formatted total column (one per value axis). Unset (the\ndefault) draws and adds nothing.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"stacked","description":"Stacks the `x`/`y`(/`y2`) scale entries `buildScales()` returns; only meaningful for `bar` and `line` types.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"type","description":"Type: `LyraChartType`  \nDefault: `'scatter'`","value":{"type":["'line'","'bar'","'scatter'","'pie'","'doughnut'","'radar'","'polarArea'","'bubble'"]}},{"name":"without-animation","description":"Disables Chart.js animation.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"without-legend","description":"Hides the legend.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"without-tooltip","description":"Hides Chart.js tooltips.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"x-label","description":"Type: `string | null`  \nDefault: `null`"},{"name":"y-label","description":"Type: `string | null`  \nDefault: `null`"},{"name":"y2-label","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"zoom","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"","description":"An optional `<script type=\"application/json\">` containing a Chart.js configuration."},{"name":"center","description":"Optional overlay content positioned at the chart area's center. Useful for doughnut and pie totals."},{"name":"data-table","description":"An optional consumer-provided accessible table alternative. Use this escape hatch for a complete paginated or virtualized alternative when the generated 1,000-record sample is insufficient."}],"js":{"properties":[{"name":"annotations","description":"Declarative reference lines and shaded bands — a threshold, an event year, a regime change, a\nhighlighted period. Each entry marks either a single `value` or a `from`/`to` range on `axis`\n(default `'y'`), with an optional `label` and semantic `tone`.\n\nNeeds the optional `chartjs-plugin-annotation` peer, loaded on first actual demand so a page\nwith no annotated charts never downloads it. The plugin is registered globally, like\n`chartjs-plugin-zoom` and unlike `chartjs-plugin-datalabels`: it draws nothing unless a chart\nsupplies annotation options, so the registration is unobservable to charts that set none, and\nregistration is also what installs the plugin's own element defaults. Without the peer\ninstalled the chart still renders; a console warning plus a localized visible warning and\nlight-DOM announcement explain the no-op — the same fail-closed contract `data-labels` uses.\n\nEntries are included in the generated accessible description, mirroring `lr-heatmap`.","type":"readonly LyraChartAnnotation[]","default":"[]"},{"name":"area","description":"Chart-wide default fill-under-line setting for line-type series; a series's own `LyraChartSeries.fill` overrides it.\n\nAttribute: `area`","type":"boolean","default":"false"},{"name":"axes","description":"Complete cartesian axis visibility, independent of grid. `y` also controls the y2 axis.\nRadial charts ignore this setting. Explicit config scale options retain precedence.\n\nAttribute: `axes`","type":"LyraChartAxes","default":"'both'"},{"name":"beginAtZero","description":"Attribute: `begin-at-zero`","type":"boolean","default":"true"},{"name":"chart","description":"The current Chart.js instance. Read it only while the element is connected and loaded.","type":"LyraChartInstance | undefined"},{"name":"chartArea","description":"The current Chart.js chart-area geometry in canvas-local coordinates. Read-only -- derived\nfrom the live Chart.js instance's own layout pass, never assignable. The setter is a\ndocumented no-op (matching `lr-histogram`'s `labels`/`datasets` pattern) so an accidental\n`.chartArea=${x}` Lit template binding degrades silently instead of throwing from inside\nlit-html's property-commit.","type":"LyraChartArea | undefined"},{"name":"compact","description":"Compact cartesian plot: hide axes and remove automatic layout padding. Set height and\nwithoutLegend for a small histogram/sparkline. Preserves data tables, tooltips and keyboard\nactions; radial charts ignore this setting. Explicit config options retain precedence.\n\nAttribute: `compact`","type":"boolean","default":"false"},{"name":"config","type":"LyraChartConfiguration | undefined"},{"name":"dataLabels","description":"Draws each data point's value on the chart via the optional\n`chartjs-plugin-datalabels` peer. Unset (the default) leaves labels off for\nthis chart; the peer is attached only to instances that opt in, and\n`buildConfig()` keeps its per-chart options disabled until this is set. The\nscreen-reader equivalent is the always-present data table (see\n`show-data-table`); labels are a purely visual, canvas-only addition.\n\nAttribute: `data-labels`","type":"boolean","default":"false"},{"name":"dataTableToggle","description":"Render a disclosure button above the accessible data table so a sighted reader can reveal the\nnumbers behind the chart on demand. `showDataTable` alone is all-or-nothing -- the table is\neither permanently screen-reader-only or permanently visible -- which left a consumer wrapping\na duplicated table in their own `<details>`.\n\nWith this set, `showDataTable` becomes the disclosure's *initial* state rather than its whole\nbehavior. The table stays in the DOM in both states, so assistive technology never loses it.\n\nAttribute: `data-table-toggle`","type":"boolean","default":"false"},{"name":"datasets","description":"Simplified chart series. Non-record entries are dropped while valid sibling series remain.","type":"readonly LyraChartSeries[]"},{"name":"description","description":"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\nAttribute: `description`","type":"string | null","default":"null"},{"name":"formatter","description":"Unified context-object formatter for visual, tooltip, table/export, and spoken values.","type":"LyraChartFormatter | undefined"},{"name":"grid","description":"Controls which cartesian grid axes are drawn.\n\nAttribute: `grid`","type":"LyraChartGrid","default":"'both'"},{"name":"height","description":"Attribute: `height`","type":"string","default":"'280px'"},{"name":"hiddenDatasets","description":"Complete controlled visibility state for DOM legend toggles. `undefined` (the default) honors\neach effective dataset's `hidden` configuration; a defined array wins over those defaults, and\nan empty array deliberately makes every dataset visible. Invalid, duplicate, and out-of-range\nindexes are ignored when state is applied or emitted.","type":"readonly number[] | undefined"},{"name":"hiddenDatums","description":"Controlled hidden source category indexes for pie/doughnut/polar-area charts, shared by all\ndatasets/rings. Clone-owned; invalid, duplicate and out-of-range indexes are ignored when\napplied or emitted. Empty restores all categories. Does not alter dataset visibility or exports.","type":"readonly number[]","default":"[]"},{"name":"indexAxis","description":"Chart.js index axis. `'y'` is Chart.js's own mechanism for horizontal bars (it also flips\nline/area types onto a horizontal category axis).\n\nAttribute: `index-axis`","type":"LyraChartIndexAxis","default":"'x'"},{"name":"label","description":"Accessible chart label. A host `aria-label` still has highest precedence.\n\nAttribute: `label`","type":"string | null","default":"null"},{"name":"labels","type":"string[]","default":"[]"},{"name":"legendDisplay","description":"`auto` retains optional legend formatting; `label` omits values even with a formatter; `value`\nappends a formatted value. `percentage` uses locale percentages of the absolute represented\nlegend values, including hidden items (zero totals yield 0%). `value-percentage` appends both,\nas `label: value (percentage)`. Dataset values are sampled sums; category values come from the\nfirst dataset. The `formatter`/`valueFormatter` callback backing `value` and `value-percentage`\nadditionally receives that same `percentage` in its `surface: 'legend'` context, so a custom\nformatter can build its own combined text without recomputing the share. Tooltip and axis\nformatting are unchanged.\n\nAttribute: `legend-display`","type":"LyraChartLegendDisplay","default":"'auto'"},{"name":"legendMode","description":"`datum` renders category toggles for pie/doughnut/polar-area charts. Categories use the first\ndataset's colors and values; a toggle affects that category in every ring. Other chart types\nretain dataset legends. `auto` (the default) resolves to `datum` on pie/doughnut/polar-area\ncharts -- where a single-dataset legend would otherwise enumerate one entry for the whole\ndataset instead of one per visible slice -- and to `dataset` everywhere else. `dataset` always\nforces the dataset legend, even on a slice chart. Both non-`auto` modes use the generated\naccessible-data sampling budget.\n\nAttribute: `legend-mode`","type":"LyraChartLegendMode","default":"'auto'"},{"name":"legendPosition","description":"Legend placement. `auto` uses a right legend above 480px and a bottom legend below it.\n\nAttribute: `legend-position`","type":"LyraChartLegendPosition","default":"'top'"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"max","description":"Maximum value-axis bound. Non-finite values are ignored.\n\nAttribute: `max`","type":"number | null","default":"null"},{"name":"min","description":"Minimum value-axis bound. Non-finite values are ignored.\n\nAttribute: `min`","type":"number | null","default":"null"},{"name":"plugins","description":"Chart.js plugins attached to this chart instance. Valid plugins retain their opaque identity.\n\nAttribute: `plugins`","type":"readonly LyraChartPlugin[]","default":"[]"},{"name":"scaleType","description":"Scale type for the **value** axis (the categorical axis is unaffected). `'logarithmic'` plots\na dataset spanning several orders of magnitude honestly, where a linear axis collapses\neverything below the maximum into the baseline. Inherited by `lr-line-chart`,\n`lr-scatter-chart` and `lr-bar-chart`.\n\nA logarithmic axis cannot represent zero or negative values (`log(0)` is `-Infinity`), so\n`beginAtZero` is not forwarded in that mode -- Chart.js would otherwise be handed a bound it\ncannot place. Non-positive data points are dropped by Chart.js's own log scale.\n\nAttribute: `scale-type`","type":"LyraChartScaleType","default":"'linear'"},{"name":"showDataTable","description":"Makes the generated data table visible; it remains screen-reader available when false.\n\nAttribute: `show-data-table`","type":"boolean","default":"false"},{"name":"stackTotals","description":"When the chart is `stacked` (bar/line only), draws the per-category stack\ntotal above each stack, via the same optional `chartjs-plugin-datalabels`\npeer as `data-labels`. Null/undefined points are skipped; a category whose\nevery value is null shows no total. The generated accessible data table\nreceives the same formatted total column (one per value axis). Unset (the\ndefault) draws and adds nothing.\n\nAttribute: `stack-totals`","type":"boolean","default":"false"},{"name":"stacked","description":"Stacks the `x`/`y`(/`y2`) scale entries `buildScales()` returns; only meaningful for `bar` and `line` types.\n\nAttribute: `stacked`","type":"boolean","default":"false"},{"name":"stackedAxes","description":"Per-value-axis override of `stacked`, keyed by `'y'`/`'y2'`. An axis absent from this record\n-- including every axis when the whole property is unset -- falls back to the chart-wide\n`stacked` value, which is what keeps a chart that never sets this byte-identical to before.\nLets a `stacked` bar series on the primary axis sit next to an unstacked overlay series on\n`y2` (via `LyraChartSeries.axis: 'y2'`): set `stackedAxes` to `{ y2: false }` alongside\n`stacked`, or spell out both axes explicitly. The shared categorical axis (`x` for a vertical\nbar/line, or `y` when `indexAxis` is `'y'`) has no independent entry of its own -- it always\nmirrors the resolved `'y'` value, matching Chart.js's own paired index/value-scale stacking\ncontract. Only meaningful for `bar`/`line` types, matching `stacked` itself.","type":"Partial<Record<'y' | 'y2', boolean>> | undefined"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"tooltipFooterFormatter","description":"Tooltip footer formatter -- e.g. a category's stack total under the items. Receives every\nitem the hovered tooltip covers, in the same shape as `tooltipTitleFormatter`. Unset (the\ndefault) leaves Chart.js's own default (no footer).","type":"LyraChartTooltipGroupFormatter | undefined"},{"name":"tooltipTitleFormatter","description":"Tooltip title formatter -- e.g. a scatter point's own name. Receives every item the hovered\ntooltip covers, each in `formatter`'s `'tooltip'`-surface context shape. Unset (the default)\nleaves Chart.js's own default title (the shared category label) in place.","type":"LyraChartTooltipGroupFormatter | undefined"},{"name":"type","description":"Attribute: `type`","type":"LyraChartType","default":"'scatter'"},{"name":"valueFormatter","description":"Formats numeric (value-axis) ticks, tooltip values, legend values, and generated accessible\ntable cells from one callback.\nHorizontal scalar tooltips use parsed x, including a raw config indexAxis override;\nstructured points retain their y-value contract. The context-object formatter shares this rule.\nNever runs against the categorical x-axis's own labels (line/bar's `labels` strings) —\nChart.js's category scale passes the tick index to `ticks.callback`, not the label text,\nso formatting it would corrupt the axis.","type":"LyraChartValueFormatter | undefined"},{"name":"withoutAnimation","description":"Disables Chart.js animation.\n\nAttribute: `without-animation`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"withoutLegend","description":"Hides the legend.\n\nAttribute: `without-legend`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"withoutTooltip","description":"Hides Chart.js tooltips.\n\nAttribute: `without-tooltip`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"xLabel","description":"Attribute: `x-label`","type":"string | null","default":"null"},{"name":"y2Label","description":"Attribute: `y2-label`","type":"string","default":"''"},{"name":"yLabel","description":"Attribute: `y-label`","type":"string | null","default":"null"},{"name":"zoom","description":"Attribute: `zoom`","type":"boolean","default":"false"}],"events":[{"name":"lr-before-datum-visibility-change","description":"Cancelable category visibility proposal in datum legend mode. `detail: { index: number, visible: boolean, hiddenDatums: readonly number[] }`. Source category indexes apply to every dataset/ring. The complete detail is frozen.","type":"CustomEvent<LyraChartDatumVisibilityChangeDetail>"},{"name":"lr-before-legend-visibility-change","description":"Cancelable proposal emitted before a DOM legend toggle changes state. `detail` contains the target `datasetIndex`, its proposed `visible` value, and the complete canonical proposed `hiddenDatasets` snapshot.","type":"CustomEvent<LyraChartLegendVisibilityChangeDetail>"},{"name":"lr-datum-activate","description":"Family-normalized activation event. Its detail adds `kind` (`bar`, `point`, `segment`, or `slice`) to the `lr-point-click` detail.","type":"CustomEvent<\n    LyraChartDatumActivateDetail<LyraCoreChartDatumKind>\n  >"},{"name":"lr-datum-visibility-change","description":"Emitted after an accepted category toggle commits the same frozen detail. Programmatic `hiddenDatums` assignments are silent.","type":"CustomEvent<LyraChartDatumVisibilityChangeDetail>"},{"name":"lr-legend-visibility-change","description":"Emitted after an accepted DOM legend toggle commits the same detail. Programmatic `hiddenDatasets` changes reconcile without either event.","type":"CustomEvent<LyraChartLegendVisibilityChangeDetail>"},{"name":"lr-point-click","description":"Fired when pointer input lands on a data point/segment, when a generated data-table value is activated, or when Enter/Space activates the keyboard-current canvas datum. `detail: { datasetIndex: number, index: number, label: string | undefined, value: unknown }`. For scatter/bubble data, `label` prefers the per-point label and `value` is the complete typed `LyraChartPoint` (`x`, `y`, optional `r`, optional `label`).","type":"CustomEvent<{\n    datasetIndex: number;\n    index: number;\n    label: string | undefined;\n    value: unknown;\n  }>"},{"name":"lr-zoom","description":"`detail: { zoomed }`.","type":"CustomEvent<{ zoomed: boolean }>"}]}},{"name":"lr-scroller","description":"`<lr-scroller>` — a responsive overflow surface with optional previous\nand next controls. Content remains in the default slot, so cards, tabs, and\nany consumer-owned interactive elements retain their own semantics.\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) | Scrollable content. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The overall scroller layout. |\n| `content` | The slotted content wrapper. |\n| `control` | Shared part on both `previous` and `next`. |\n| `end-shadow` | Logical-end overflow cue. |\n| `next` | The next/end control. |\n| `next-glyph` | The chevron glyph inside `next`, mirrored under RTL. |\n| `previous` | The previous/start control. |\n| `previous-glyph` | The chevron glyph inside `previous`, mirrored under RTL. |\n| `start-shadow` | Logical-start overflow cue. |\n| `viewport` | The native scroll container. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-scroller-control-size` (default: `var(--lr-size-2rem)`) — Control size.\n- `--lr-scroller-hover-outline-color` (default: `var(--lr-color-border)`) — Outline color of the mouse-hover preview on `[part=\"viewport\"]`. Set to `transparent` to opt out of the hover treatment entirely.\n- `--lr-scroller-hover-outline-offset` (default: `var(--lr-focus-ring-offset)`) — Offset of the mouse-hover preview on `[part=\"viewport\"]`.\n- `--lr-scroller-hover-outline-style` (default: `solid`) — Outline style of the mouse-hover preview on `[part=\"viewport\"]`.\n- `--lr-scroller-hover-outline-width` (default: `var(--lr-border-width-thin)`) — Outline width of the mouse-hover preview on `[part=\"viewport\"]`.\n- `--lr-scroller-min-block-size` (default: `var(--lr-size-10rem)`) — Minimum vertical scroller size.\n- `--lr-scroller-shadow-color` (default: `var(--shadow-color)`) — Lyra-prefixed shadow-color alias.\n- `--lr-scroller-shadow-size` (default: `var(--shadow-size)`) — Lyra-prefixed shadow-size alias.\n- `--shadow-color` (default: `var(--lr-color-surface)`) — Base color of each edge shadow.\n- `--shadow-size` (default: `var(--lr-size-2rem)`) — Inline/block extent of each edge shadow.","attributes":[{"name":"controls","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"label","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"orientation","description":"Type: `LyraOrientation`  \nDefault: `'horizontal'`","value":{"type":["'horizontal'","'vertical'"]}},{"name":"scroll-step","description":"Type: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"without-scrollbar","description":"Hides the native scrollbar while preserving scrolling.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"without-shadow","description":"Removes both visual edge cues while leaving native scrolling untouched.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"","description":"Scrollable content."}],"js":{"properties":[{"name":"controls","description":"Attribute: `controls`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"label","description":"Attribute: `label`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"orientation","description":"Attribute: `orientation`  \nReflected to its attribute.","type":"LyraOrientation","default":"'horizontal'"},{"name":"scrollStep","description":"Attribute: `scroll-step`","type":"number","default":"0"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"withoutScrollbar","description":"Hides the native scrollbar while preserving scrolling.\n\nAttribute: `without-scrollbar`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"withoutShadow","description":"Removes both visual edge cues while leaving native scrolling untouched.\n\nAttribute: `without-shadow`  \nReflected to its attribute.","type":"boolean","default":"false"}],"events":[{"name":"lr-scroll","description":"`detail: { scrollStart: boolean; scrollEnd: boolean; scrollLeft: number; scrollTop: number }` reports the scroll position and available edges. Scroll-driven emissions are coalesced through one `requestAnimationFrame` tick, so a fling that fires dozens of native `scroll` events produces at most one of these per frame.","type":"CustomEvent<{\n    scrollStart: boolean;\n    scrollEnd: boolean;\n    scrollLeft: number;\n    scrollTop: number;\n  }>"}]}},{"name":"lr-segmented","description":"`<lr-segmented>` — a single-select button row with the WAI-ARIA APG `radiogroup` contract\nbuilt in: `role=\"radiogroup\"`/`role=\"radio\"`, roving tabindex, automatic activation (click or\narrow-key move both select immediately, like a native radio group), cyclic Arrow/Home/End\nnavigation among non-disabled items. First-party invention --\n\"choose exactly one of N labeled options, rendered as a button row\" is ubiquitous\nsettings/filter-panel UI. Supports the library's shared `size` ladder, the same one\n`<lr-select>`/`<lr-combobox>`/`<lr-input>` use, so it can sit flush beside those controls in a\ntoolbar at a matching height.\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 `role=\"radiogroup\"` root. |\n| `segment` | A single `role=\"radio\"` button. |\n| `segment-icon` | Optional decorative leading visual supplied by the item's `icon` field. Content may have a natural aspect ratio and is not restricted to a square icon; it is inert and hidden from assistive technology, so it cannot provide an independent action or accessible name. |\n| `segment-label` | The segment's label text. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-scroll-fade-size` (default: `2rem`) — Width of the fade at each horizontal scroll edge. The fade is applied only while the track actually overflows, so a row that fits is never dimmed.\n- `--lr-segmented-active-bg` (default: `color-mix(in oklab, transparent, var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Background of a pressed segment that is neither checked nor disabled.\n- `--lr-segmented-active-color` (default: `var(--lr-segmented-hover-color, var(--lr-color-text))`) — Text color of a pressed segment that is neither checked nor disabled. Its default follows `--lr-segmented-hover-color` to preserve the established hover/pressed relationship; set this property to theme the pressed text independently.\n- `--lr-segmented-font-size` (default: `var(--lr-form-control-font-size)`) — Each segment's font size, taken from the `size` tier's shared control font size.\n- `--lr-segmented-hover-bg` (default: `transparent`) — Background of a hovered segment that is neither checked nor disabled. Undeclared by default, so it falls back to the segment's own resting transparent background — byte-identical to before this property existed.\n- `--lr-segmented-hover-color` (default: `var(--lr-color-text)`) — Text color of a hovered segment that is neither checked nor disabled. Independent of the selected-state props above — recoloring the checked pill leaves this untouched.\n- `--lr-segmented-hover-shadow` (default: `none`) — Box shadow of a hovered segment that is neither checked nor disabled. Undeclared by default, matching the segment's own resting absence of a shadow.\n- `--lr-segmented-segment-padding` (default: `var(--lr-form-control-padding-block) var(--lr-form-control-padding-inline)`) — Each segment's padding, taken from the `size` tier's shared control padding.\n- `--lr-segmented-selected-bg` (default: `var(--lr-color-surface)`) — Background of the checked segment. Scoped to `[aria-checked='true']` only, so it never repaints a hovered unselected segment (which is what hijacking `--lr-color-surface` library-wide used to do).\n- `--lr-segmented-selected-color` (default: `var(--lr-color-text)`) — Text color of the checked segment.\n- `--lr-segmented-selected-font-weight` (default: `var(--lr-font-weight-semibold)`) — Font weight of the checked segment.\n- `--lr-segmented-selected-shadow` (default: `var(--lr-shadow-xs)`) — Box shadow lifting the checked segment off the track.\n- `--lr-segmented-track-bg` (default: `transparent`) — Background of the `base` track. Undeclared by default, matching its own current absence of a background.\n- `--lr-segmented-track-border-color` (default: `var(--lr-color-border)`) — Border color of the `base` track, which previously read that token as a literal with no override hook.\n- `--lr-segmented-track-gap` (default: `var(--lr-size-0-125rem)`) — Gap between segments.\n- `--lr-segmented-track-height` — Exact height of the `base` track, pinning it at every `size` tier (sets both `block-size` and `min-block-size`) so the row can sit flush beside a hard-sized toolbar control. **Genuinely unset by default** — while unset each tier keeps its own `--lr-segmented-track-min-height` floor and the track grows with its content.\n- `--lr-segmented-track-min-height` (default: `var(--lr-form-control-height)`) — Minimum height of the `base` track, taken from the `size` tier's shared control height; the `2.5rem` (40px) default applies at the unset/`m` size, matching `<lr-input>`/`<lr-select>`/`<lr-combobox>`'s own shared default-tier floor. The private default follows `size`; a public value inherited from an ancestor or set directly on the element remains authoritative in every tier.\n- `--lr-segmented-track-padding` (default: `var(--lr-size-0-125rem)`) — Track inset padding.\n- `--lr-segmented-track-radius` (default: `var(--lr-radius)`) — Track corner radius.","attributes":[{"name":"label","description":"Accessible-name fallback for the radiogroup when the host has no `aria-label`, used when no\nvisible label context exists around it (e.g. no wrapping `<label>` or adjacent heading). A\nhost `aria-label` wins by attribute presence, including an explicitly empty value. The resolved\nname is set on the `role=\"radiogroup\"` element.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"size","description":"Visual size, on the library's shared ladder — the same `--lr-form-control-*` scale\n`<lr-input>`/`<lr-select>`/`<lr-combobox>`/`<lr-button>` use, so a row of mixed controls at one\n`size` lines up. Accepts both spellings of every tier: `2xs`/`xs`/`s`/`m`/`l`/`xl` and Web\nAwesome's `small`/`medium`/`large`, so migrating either way is a tag rename. Reflects as the\n`size` attribute.\n\nType: `LyraSize`  \nDefault: `'m'`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}},{"name":"value","description":"The currently selected item's `value`.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"js":{"properties":[{"name":"items","description":"The button row's immutable, bounded items. Later duplicate values are ignored.","type":"readonly LyraSegmentedItem[]"},{"name":"label","description":"Accessible-name fallback for the radiogroup when the host has no `aria-label`, used when no\nvisible label context exists around it (e.g. no wrapping `<label>` or adjacent heading). A\nhost `aria-label` wins by attribute presence, including an explicitly empty value. The resolved\nname is set on the `role=\"radiogroup\"` element.\n\nAttribute: `label`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"size","description":"Visual size, on the library's shared ladder — the same `--lr-form-control-*` scale\n`<lr-input>`/`<lr-select>`/`<lr-combobox>`/`<lr-button>` use, so a row of mixed controls at one\n`size` lines up. Accepts both spellings of every tier: `2xs`/`xs`/`s`/`m`/`l`/`xl` and Web\nAwesome's `small`/`medium`/`large`, so migrating either way is a tag rename. Reflects as the\n`size` attribute.\n\nAttribute: `size`  \nReflected to its attribute.","type":"LyraSize","default":"'m'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"value","description":"The currently selected item's `value`.\n\nAttribute: `value`","type":"string","default":"''"}],"events":[{"name":"lr-activate","description":"Fired on every activation of a non-disabled segment -- a click, or an Arrow/Home/End key that lands on one -- whether or not the selection actually moved. `detail: { value }` carries the activated segment's own value. Bubbling and composed, so a host outside the shadow tree receives it. Not cancelable: it is a notification that the user picked a segment, not a veto point, and nothing in this component branches on it. Re-picking the current value is the case `lr-change` deliberately stays silent for (a re-submit, a re-fetch, a panel the host wants to reopen), and it is otherwise unobservable for keyboard activation, which produces no click. When an activation does move the selection, `lr-change` is emitted first, so a listener reading `value` from either event always sees the settled selection.","type":"CustomEvent<{ value: string }>"},{"name":"lr-change","description":"Fired when the selected value changes via click or keyboard. `detail: { value }`.","type":"CustomEvent<{ value: string }>"}]}},{"name":"lr-select","description":"`<lr-select>` — a plain closed-list dropdown: a direct `<lr-*>`\ncounterpart to `<wa-select>`/`<wa-option>`. Trigger is a button (not a text\ninput) -- click/Enter/Space/ArrowDown opens it, there's no typing-to-filter.\nA printable keypress instead jumps (or, while closed, directly selects) the\nnext option whose label starts with what's been typed, like a native\n`<select>`'s type-ahead. Closed multiple mode skips selected option occurrences and keeps\nsearching for a later unselected match, including another occurrence of the same value.\n\nOptions are `<lr-option value>` children, the same element `<lr-combobox>`\nuses. Unlike `lr-combobox` there is no filter/source/empty-text/max-render\nsurface -- see `<lr-combobox>` for the filterable case.\n\n`multiple` turns the committed `value` into a `string[]` and renders one removable chip per\nselection. The chip row is a sibling overlaid on the real trigger button, never nested inside it,\nso every remove control is valid independently-focusable interactive content. The trigger keeps\none complete visually-hidden joined-value node for assistive technology while the painted\nbuilt-in chip labels are hidden from it, preventing both truncation and duplicate announcement.\nPicking a selected row again still toggles it off, Backspace/Delete on the trigger removes the\nlast selection, and `with-clear` removes all of them. `getTag` replaces a built-in chip entirely;\n`max-options-visible` caps how many render before the rest collapse behind a localized \"+N\" chip.\n\n`with-clear`'s button renders inside the trigger's inline-end padding,\noutboard of the expand icon, as a sibling of the trigger rather than a child\nof it -- for the same nesting reason.\nThe trigger and overlaid multi-select tag row accept constrained allocation: long selected\nlabels ellipsize and long chips wrap within a 320px LTR or RTL container instead of widening it.\n\nReuses `lr-combobox`'s popup positioning (`internal/positioner.js`) and\nclick-outside/Escape/Home/End/Arrow-key listbox navigation patterns,\nadapted to a trigger button that keeps DOM focus throughout (the listbox's\n\"active\" row is conveyed via `aria-activedescendant`, never actual focus),\nmatching the WAI-ARIA \"select-only combobox\" pattern.\n\nWhen `autoCommitSingleOption` is set and exactly one option is available\n(neither disabled nor inert, including through an inert ancestor), the popup never\nopens at all: a click, Enter, Space, ArrowDown, or ArrowUp on the trigger\ncommits that sole option directly, and the trigger renders as a plain\n`role=\"button\"` with no chevron/`aria-haspopup`/`aria-expanded` rather than\na combobox with a permanently inert popup state — opening a one-row list to\npick the only available choice is pure friction with no real decision\nbehind it. This never changes `value`/validity defaults on its own — an\nunselected single-option select stays unselected (and a `required` one\nstays invalid) exactly like the multi-option case, until the trigger is\nactually activated. `autoCommitSingleOption` defaults to `false`: by\ndefault a select always renders the normal combobox/listbox/chevron\ntrigger no matter how many options are enabled, matching pre-1.3.0\nbehavior — opt in explicitly if a narrowing-to-one option list should\nauto-commit.\n\nDeliberately does **not** perform implicit form submission on Enter (unlike `<lr-input>`/\n`<lr-combobox>`/`<lr-date-input>`, which route through `internal/submit-on-enter.ts`): the\ntrigger is a `role=\"combobox\"` button where Enter opens the listbox and, once open, commits the\nactive option — the ARIA combobox behavior its upstream counterpart follows. Submitting there\nwould shadow the only keyboard way to open the list.\n\nWhile the listbox is open, live option collection changes preserve the keyboard-active option\nby element identity across reorders. If that option is removed or becomes unavailable, the\nnearest available survivor takes over (preferring the following row on a tie); an empty\navailable collection clears `aria-activedescendant` instead of retaining an invalid index.\n\nHost `aria-describedby` targets supplement internal hint/error guidance on the semantic\ncontrol, including live target replacement and document adoption. Removing label, hint, or\nerror attributes safely omits their content while retaining native null property readback.\nMounted option `selected` writes immediately update the live value and submission silently;\nreset defaults stay independent, and later default changes preserve a dirty selection.\n\nAssigning `undefined`/`null` to `value`/`defaultValue` clears the selection; every string,\nincluding `''`, is instead a candidate value resolved against the current options -- an\n`<lr-option value=\"\">` is a legitimate row and now round-trips like any other. A committed value\nmatching no current option (a stale value, or a programmatic assignment with a typo) still\ncommits rather than being dropped, but renders with a dashed/italic `[part='unknown-value']`\nbadge instead of silently passing the raw string off as an ordinary label -- see\n`isUnknownValue()`. Set `loading` while that same value's catalog simply hasn't arrived yet (an\nasync fetch still in flight, say): a still-unmatched value then renders the localized `loading`\nplaceholder instead, with no `unknown-value` badge, since it is not yet known to be missing. The\nsame flag covers an empty selection too -- with nothing selected the trigger shows that same\nlocalized text in place of `placeholder`, so both halves of a pending state read the same words\nwithout a consumer re-localizing them.\n\nA slotted `<lr-option>`'s `start`/`end` (and the Shoelace `prefix`/`suffix` aliases) adornments\nare cloned into the corresponding `[part='option-start']`/`[part='option-end']` listbox row,\nmirroring `<lr-combobox>`.\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-option>` elements. |\n| `clear-icon` | Replaces the built-in clear glyph. |\n| `end` | Decorative adornment after the selected-value label and before the expand icon. Its wrapper has the same enforced inert/`aria-hidden` contract as `start`. |\n| `error` | Custom error content. |\n| `expand-icon` | Replaces the built-in expand glyph. |\n| `help-text` | Shoelace alias for `hint`. |\n| `hint` | Custom hint content. |\n| `label` | Custom label content. |\n| `prefix` | Shoelace alias for `start`. |\n| `start` | Decorative adornment at the inline-start of the trigger row, before the selected-value label. Its wrapper is always `aria-hidden` and inert because it lives inside the native trigger button; interactive content supplied here remains deliberately unavailable. |\n| `suffix` | Shoelace alias for `end`. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `clear-button` | The `with-clear` button. |\n| `combobox` | Compatibility name for the control wrapper. |\n| `display-input` | The selected-value/placeholder display inside the trigger. In populated multiple mode it is visually hidden but exposes every selected label to assistive technology. |\n| `end` | Inert, decorative wrapper around the `end` adornment slot; `hidden` while nothing is slotted. |\n| `error` | The error message. |\n| `expand-icon` | The dropdown indicator. |\n| `form-control` | The outer wrapper around label, trigger, listbox, error and hint. |\n| `form-control-help-text` | Shoelace compatibility name for the hint message. |\n| `form-control-input` | Compatibility name for the control wrapper. |\n| `form-control-label` | The `<label>` element. |\n| `group-label` | An option group's heading row, referenced by the enclosing `role=\"group\"`. |\n| `hint` | The hint message. |\n| `label` | Wrapper around the visible label content. |\n| `listbox` | The managed nonmodal options popover; its stack depth comes from `--lr-overlay-stack-index` with `--lr-layer-dropdown` as the standalone fallback. |\n| `option` | An option row. |\n| `option-badge` | The localized \"not in catalog\" badge on a synthetic unmatched-value row (`show-unknown-option` only). |\n| `option-dot` | An option row's leading status dot (when `dot-color` is set). |\n| `option-end` | An option row's trailing adornment, cloned from the source `<lr-option>`'s `end`/`suffix` slot. Inert and aria-hidden. |\n| `option-label` | An option row's label/sub wrapper. |\n| `option-start` | An option row's leading adornment, cloned from the source `<lr-option>`'s `start`/`prefix` slot. Inert and aria-hidden. |\n| `option-sub` | An option row's secondary line (when `sub` is set). |\n| `prefix` | Shoelace compatibility part on the `prefix` slot. |\n| `start` | Inert, decorative wrapper around the `start` adornment slot; `hidden` while nothing is slotted. |\n| `suffix` | Shoelace compatibility part on the `suffix` slot. |\n| `tag` | One selected-value chip. The \"+N\" overflow chip carries both `tag` and `tag-overflow`, so `::part(tag)` styles every chip and `::part(tag-overflow)` only that one -- state after `::part()` never matches, so it is encoded in the part name instead. |\n| `tag-label` | A chip's ellipsis-safe label. |\n| `tag-overflow` | The \"+N\" chip standing in for the selections past `max-options-visible`. |\n| `tag__base` | Compatibility name on a built-in selected-value chip. |\n| `tag__content` | Compatibility name around a built-in chip's visible label. |\n| `tag__remove-button` | A built-in chip's remove button. |\n| `tag__remove-button__base` | Compatibility name on the same remove button. |\n| `tags` | The `multiple`-mode chip row, rendered as a sibling overlaid on the trigger. |\n| `trigger` | The trigger button (positioning anchor). |\n| `unknown-value` | Badge shown next to the trigger label or a `multiple`-mode tag when the committed value matches no current `<lr-option>` (see `isUnknownValue()`). |\n\n---\n\n**CSS Custom Properties**\n\n- `--hide-duration` (default: `var(--lr-transition-fast)`) — Listbox exit-transition timing.\n- `--lr-form-control-focus-shadow` (default: `none`) — The shared field focus halo, painted as a `box-shadow` while this control is focused. One name for every field-shaped control in the library, so a halo is configured once rather than per component. Additive: the focus outline and border cue are the accessibility answer to focus and are never replaced by it.\n- `--lr-form-control-required-color` (default: `var(--lr-color-danger)`) — Required-marker color, themeable independently of error text and invalid borders.\n- `--lr-form-control-required-content` (default: `' *'`) — The required marker appended to `form-control-label` while `required` is set. Set it to `''` to suppress the marker, or to any other quoted string (`' (required)'`, a localized word) to replace it.\n- `--lr-form-control-required-offset` (default: `0`) — Inline space between the label text and the required marker.\n- `--lr-overlay-border` (default: `var(--lr-color-border)`) — Shared floating-surface edge colour, on the listbox.\n- `--lr-overlay-radius` (default: `var(--lr-radius)`) — Shared floating-surface corner radius, on the listbox.\n- `--lr-overlay-shadow-anchored` (default: `var(--lr-shadow-m)`) — Elevation of the anchored listbox.\n- `--lr-overlay-surface` (default: `var(--lr-color-surface-overlay)`) — Shared floating-surface fill, on the listbox. The listbox is a floating surface, so it retints with every other popup rather than with the trigger it drops from.\n- `--lr-positioning-strategy` — Cascading `absolute`/`fixed` override for {@link positioningStrategy}/`hoist`, read from computed style when the listbox is (re)positioned. Set it once on `:root`, a theme, or one clipping ancestor to change every unset select beneath it instead of authoring `positioning-strategy`/`hoist` on each instance; an explicit value on the instance always wins over it.\n- `--lr-select-expand-size` — Decorative expand-icon box size, scaled by `size`. The one piece of this component's geometry the shared ladder does not own: it sizes a glyph, not the control row.\n- `--lr-select-font-size` (default: `var(--lr-form-control-font-size)`) — Trigger font size, from the active `size` tier.\n- `--lr-select-gap` — Gap between the trigger's start adornment, label, end adornment, and expand icon. Doesn't vary by `size`.\n- `--lr-select-open-border-color` (default: `var(--lr-color-brand)`) — Trigger border while the listbox is open.\n- `--lr-select-option-active-bg` (default: `var(--lr-color-brand-quiet)`) — Background of the hovered/keyboard-active option row. Not declared on `:host`, so a value set on any ancestor is never shadowed -- retheme just this row state without hijacking the shared `--lr-color-brand-quiet` token used by every other component's own hover/active state.\n- `--lr-select-option-badge-bg` (default: `var(--lr-color-brand-quiet)`) — Background of the `[part='option-badge']` \"not in catalog\" badge.\n- `--lr-select-option-selected-bg` (default: `transparent`) — Background of the currently-selected option row. Not declared on `:host`; retheme just the selected row without hijacking `--lr-color-brand`.\n- `--lr-select-option-selected-border` (default: `var(--lr-color-brand)`) — Border color of the selected option row.\n- `--lr-select-option-selected-color` (default: `var(--lr-color-brand)`) — Text color of the selected option row.\n- `--lr-select-option-selected-font-weight` (default: `var(--lr-font-weight-semibold)`) — Font weight of the selected option row.\n- `--lr-select-radius` (default: `var(--lr-form-control-radius)`) — Trigger corner radius, from the active `size` tier of the shared form-control ladder (the two tightest tiers take a smaller radius).\n- `--lr-select-tag-font-size` — Chip text size. Doesn't vary by `size`.\n- `--lr-select-tag-padding` — Padding inside a `multiple`-mode chip. Doesn't vary by `size`.\n- `--lr-select-trigger-active-bg` (default: `color-mix(...)`) — Trigger background while pressed.\n- `--lr-select-trigger-border-color` (default: `var(--lr-color-border)`) — Resting trigger border color, `transparent` by default on the `filled`/`plain`/`accent` treatments.\n- `--lr-select-trigger-fill` (default: `var(--lr-color-surface)`) — Resting trigger background. Read by every appearance, each falling back to its own default (`--lr-color-surface-raised` for `filled`/`filled-outlined`, `transparent` for `plain`, `--lr-color-brand` for `accent`), so one value retints the trigger whichever treatment it is wearing.\n- `--lr-select-trigger-height` — Exact trigger height. Unset by default, which leaves `--lr-select-trigger-min-height` as a floor only; set it to a length to both floor and cap the trigger (e.g. to pixel-match a sibling field in the same toolbar row). Because it is never declared by the component itself, it can be set from an ancestor or an outer-tree rule as well as inline on the element.\n- `--lr-select-trigger-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Trigger background while hovered. Accent appearance keeps its louder mixed fallback when this hook is unset.\n- `--lr-select-trigger-hover-border-color` (default: `var(--lr-select-trigger-border-color)`) — Trigger border color while the pointer is over it. Unset, the border stays exactly where the resting state left it.\n- `--lr-select-trigger-min-height` (default: `var(--lr-form-control-height)`) — Trigger block-size floor, from the active `size` tier of the shared ladder, and live at every tier including the default `m` -- so a select is exactly as tall as an `<lr-button>`/`<lr-input>` of that tier.\n- `--lr-select-trigger-padding` — Trigger padding shorthand. Defaults to the active `size` tier's `var(--lr-form-control-padding-block) var(--lr-form-control-padding-inline)` from the shared ladder.\n- `--lr-select-unknown-value-border-color` (default: `var(--lr-color-border)`) — Border color of the same unknown-value chip.\n- `--lr-select-unknown-value-border-style` (default: `dashed`) — Border style of an `[part='unknown-value']` chip (a `multiple`-mode tag whose committed value matches no current option).\n- `--show-duration` (default: `var(--lr-transition-fast)`) — Listbox enter-transition timing.\n- `--tag-max-size` (default: `var(--lr-size-12rem)`) — Maximum inline size of one selected-value tag.","attributes":[{"name":"appearance","description":"Visual treatment of the trigger surface.\n\nType: `LyraAppearance`  \nDefault: `'outlined'`","value":{"type":["'accent'","'filled'","'outlined'","'filled-outlined'","'plain'"]}},{"name":"auto-commit-single-option","description":"Opt-in: when `true` and exactly one `<lr-option>` is enabled, the\ntrigger commits that option directly (click/Enter/Space/ArrowDown/\nArrowUp) instead of opening the listbox, and renders as a plain\n`role=\"button\"` with no chevron. Defaults to `false`, which always\nrenders the normal combobox/listbox/chevron trigger regardless of how\nmany options are enabled — the pre-1.3.0 behavior. See the class doc\nabove and `onlyOption` below for the full rationale.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"autofocus","description":"Forwarded to the internal trigger button.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"clearable","description":"Shoelace's spelling of withClear, accepted so a mechanical `sl-` → `lr-` rename does\nnot silently drop the clear button. Prefer `with-clear` in new code.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"custom-error","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nType: `string | null`  \nDefault: `null`"},{"name":"default-value","description":"Reset value, matching the mapped native-like select contract. The `default-value` attribute\nsupplies the single-mode string form; property writes may use a string array in `multiple`\nmode. Changing the default updates the live value only while it is still pristine.\n`undefined`/`null` clear the default; `''` is a candidate value like any other -- see the\n`value` setter's doc for the full contract.\n\nType: `string | string[]`  \nDefault: `''`"},{"name":"disabled","description":"Whether user interaction and form participation are disabled.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"error-text","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"filled","description":"Shoelace boolean alias for the filled appearance.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"form","description":"ID of an external form owner.\n\nType: `HTMLFormElement | string | null`  \nDefault: `null`"},{"name":"help-text","description":"Shoelace alias for hint. `hint` wins when both are present.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"hint","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"hoist","description":"Retained boolean alias of positioningStrategy: `hoist` is exactly\n`positioningStrategy === 'fixed'`, and writing either spelling updates the other so the two\nattributes can never disagree in the DOM. It is this control's established name (and\nShoelace's own spelling on `sl-select`), so it keeps working indefinitely; prefer\n`positioning-strategy` in new code, which reads the same on every anchored surface.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"label","description":"Visible label. A host `aria-label` wins on the internal trigger by attribute presence,\nincluding an explicitly empty value that suppresses this label's naming fallback.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"loading","description":"Whether a committed value's real label may still be pending -- e.g. the `<lr-option>` catalog\nbehind it is still being fetched/mounted asynchronously and simply hasn't arrived yet. While\n`true`, a committed value that currently matches no option (the same condition `isUnknownValue()`\ntests) renders the localized `loading` placeholder in the trigger label or the relevant\n`multiple` tag instead of the raw value, and is not flagged with the dashed/italic\n`notInCatalog`/`[part='unknown-value']` badge a genuinely unmatched value gets, nor added to the\nsynthetic `showUnknownOption` listbox row -- \"not yet resolved\" is a different state from \"known\nto be missing\". With nothing selected at all -- a create form whose catalog is still being\nfetched, or an edit form whose saved selection is legitimately empty -- the trigger shows that\nsame localized `loading` text in place of `placeholder`, so one property covers the whole\npending state rather than only its committed-value half and the two halves always read the\nsame words. The trigger's accessible name is unchanged by this: a host `aria-label` still\nwins, then `label`, then `placeholder`, then the localized `select` fallback.\nA value that already matches a live option is unaffected either way. Reflected\nso `:host([loading])` is available as a styling hook. Never mutates `value`/`selectedOptions`\nitself, and does not itself disable the trigger -- pair it with `disabled` when the control\nshould also be non-interactive while its catalog is pending.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max-options-visible","description":"Maximum number of selected-value chips shown before the rest collapse behind a localized\n\"+N\" chip (`multiple` only). `0` removes the cap. Sanitized to a finite, non-negative\ninteger, falling back to `3`.\n\nType: `number`  \nDefault: `3`","value":{"type":["number"]}},{"name":"multiple","description":"Whether several options can be selected at once. Flipping it re-shapes `value` (a string\nbecomes a `string[]`) and the submitted form entry, so it is normally set once declaratively.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"name","description":"Submission name.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"open","description":"Whether the listbox is open. Disabled controls synchronously normalize every opening write\nback to `false`, including reflected-attribute writes.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"pill","description":"Fully-rounded trigger corners. Changes the private radius default to `--lr-radius-pill`, so\nan inherited or direct `--lr-select-radius` remains authoritative.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"placeholder","description":"Text shown on the trigger while nothing is selected. It still names the trigger when neither\na host `aria-label` nor a `label` does. One exception to \"an empty selection always shows\nthis\": while `loading` is `true` the trigger shows the localized `loading` text instead, so a\nconsumer never has to re-localize that string in its own catalog to cover the empty half of a\npending state -- see loading. The trigger's accessible name is unaffected either way.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"placement","description":"Preferred listbox placement. `flip`/`shift` may still override it to keep the popup in view,\nand the `left`/`right` component is swapped under RTL. Changes reposition an already-open\nlistbox without closing it or changing overlay stack ownership.\n\nType: `Placement`  \nDefault: `'bottom'`","value":{"type":["'top'","'top-start'","'top-end'","'right'","'right-start'","'right-end'","'bottom'","'bottom-start'","'bottom-end'","'left'","'left-start'","'left-end'"]}},{"name":"positioning-strategy","description":"CSS positioning scheme the listbox is laid out with -- the one property `<lr-select>`,\n`<lr-dropdown>` and `<lr-popover>` all spell the same way. `absolute` (this control's mirrored\ndefault) positions against the nearest containing block and scrolls with it; `fixed` positions\nagainst the viewport and escapes most clipping ancestors. An unsupported value resolves back\nto the default. Changes apply live while open.\nThis property reports only the instance's own authored value (or the mirrored default); the\nlistbox is actually placed with the `--lr-positioning-strategy` cascading custom property\nhonored ahead of that default when the instance itself sets nothing -- see that `@cssprop`.\n\nType: `PlaceStrategy`  \nDefault: `'absolute'`","value":{"type":["'absolute'","'fixed'"]}},{"name":"required","description":"Whether at least one selected option is required for validity.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"show-unknown-option","description":"Appends every committed value that no `<lr-option>` claims to the end of the listbox as a\nsynthetic, re-selectable row badged with the localized `notInCatalog` text -- the policy\n`<lr-model-select>` already ships.\n\nOff by default, because it adds a row to a listbox that has always rendered only real options.\nTurn it on wherever a stored value can outlive its catalog entry: without it, the out-of-list\nvalue is visible on the trigger but absent from the listbox, so a user who opens the listbox\nhas no way back to the value they arrived with. No synthetic row appears for a value `loading`\nis currently suppressing -- see that property -- since it is not yet known to be unmatched.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"size","description":"Visual size on the library's one control ladder — shared with `lr-button`/`lr-input`/\n`lr-combobox`/`lr-locale-picker`, so same-tier controls line up in a toolbar row. Accepts both\nthe canonical `'2xs'`–`'xl'` steps and Web Awesome's/Shoelace's `'small'`/`'medium'`/`'large'`\nspellings of `s`/`m`/`l`; the two render identically.\n\nType: `LyraSize`  \nDefault: `'m'`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}},{"name":"sync","description":"Copies the trigger's width, height, or both onto the listbox -- the same property\n`<lr-popup>`/`<lr-popover>`/`<lr-dropdown>`/`<lr-combobox>` spell, with the same values. Unset\n(the default), the listbox sizes to its own content, clamped between `--lr-size-12rem` and\n`--lr-size-28rem`, exactly as before. Set `sync=\"width\"` so a full-width trigger with short\noption labels gets a listbox that aligns to its own edges instead of floating narrower in the\nmiddle -- the content clamp above no longer applies while this is set, since the trigger's own\nwidth is now the intentional bound. A synced listbox is still bounded by the space actually\nmeasured beside its anchor, so an over-wide trigger cannot push it off-screen. Changes\nreposition an already-open listbox without closing it.\n\nType: `PlaceSync | undefined`  \nDefault: `undefined`","value":{"type":["'width'","'height'","'both'"]}},{"name":"title","description":"Forwarded to the internal trigger button.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"value","description":"The selected value: a single string outside `multiple` mode (empty when nothing is\nselected), a `string[]` inside it.\n\nAssigning `undefined` or `null` clears the selection -- the documented \"unset\" contract.\nEvery string, including `''`, is instead a candidate value resolved against the current\n`<lr-option>`s: an option may legitimately declare `value=\"\"`, and assigning `''` selects it\nwhen present (mirroring what clicking that row already did). A `''`/non-array assignment that\nmatches no option still commits, exactly like any other unmatched string -- see\n`isUnknownValue()`.\n\n`LyraPickerValue<Multiple>` narrows to `string` on a `LyraSelect<false>` and `string[]` on a\n`LyraSelect<true>`; the unnarrowed default resolves to the published union below, which is\nwhy the manifest type is pinned here rather than left to the inferred alias name.\n\nType: `string | string[]`  \nDefault: `''`"},{"name":"with-clear","description":"Show a button that empties the selection while there is anything selected.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"with-hint","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"with-label","description":"SSR slot-presence hints for pre-hydration form chrome.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"","description":"`<lr-option>` elements."},{"name":"clear-icon","description":"Replaces the built-in clear glyph."},{"name":"end","description":"Decorative adornment after the selected-value label and before the expand icon. Its wrapper has the same enforced inert/`aria-hidden` contract as `start`."},{"name":"error","description":"Custom error content."},{"name":"expand-icon","description":"Replaces the built-in expand glyph."},{"name":"help-text","description":"Shoelace alias for `hint`."},{"name":"hint","description":"Custom hint content."},{"name":"label","description":"Custom label content."},{"name":"prefix","description":"Shoelace alias for `start`."},{"name":"start","description":"Decorative adornment at the inline-start of the trigger row, before the selected-value label. Its wrapper is always `aria-hidden` and inert because it lives inside the native trigger button; interactive content supplied here remains deliberately unavailable."},{"name":"suffix","description":"Shoelace alias for `end`."}],"js":{"properties":[{"name":"appearance","description":"Visual treatment of the trigger surface.\n\nAttribute: `appearance`  \nReflected to its attribute.","type":"LyraAppearance","default":"'outlined'"},{"name":"autoCommitSingleOption","description":"Opt-in: when `true` and exactly one `<lr-option>` is enabled, the\ntrigger commits that option directly (click/Enter/Space/ArrowDown/\nArrowUp) instead of opening the listbox, and renders as a plain\n`role=\"button\"` with no chevron. Defaults to `false`, which always\nrenders the normal combobox/listbox/chevron trigger regardless of how\nmany options are enabled — the pre-1.3.0 behavior. See the class doc\nabove and `onlyOption` below for the full rationale.\n\nAttribute: `auto-commit-single-option`","type":"boolean","default":"false"},{"name":"autofocus","description":"Forwarded to the internal trigger button.\n\nAttribute: `autofocus`","type":"boolean","default":"false"},{"name":"clearable","description":"Shoelace's spelling of withClear, accepted so a mechanical `sl-` → `lr-` rename does\nnot silently drop the clear button. Prefer `with-clear` in new code.\n\nAttribute: `clearable`","type":"boolean","default":"false"},{"name":"customError","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nAttribute: `custom-error`  \nReflected to its attribute.","type":"string | null","default":"null"},{"name":"defaultValue","description":"Reset value, matching the mapped native-like select contract. The `default-value` attribute\nsupplies the single-mode string form; property writes may use a string array in `multiple`\nmode. Changing the default updates the live value only while it is still pristine.\n`undefined`/`null` clear the default; `''` is a candidate value like any other -- see the\n`value` setter's doc for the full contract.\n\nAttribute: `default-value`","type":"string | string[]","default":"''"},{"name":"disabled","description":"Whether user interaction and form participation are disabled.\n\nAttribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"effectiveDisabled","description":"Effective disabled state: this element's own `disabled` OR an ancestor\n`<fieldset disabled>`'s inherited state -- mirrors native `<input>`, whose\nown `disabled` IDL property/attribute is never mutated by a fieldset.","type":"boolean","read-only":true},{"name":"errorText","description":"Attribute: `error-text`","type":"string","default":"''"},{"name":"filled","description":"Shoelace boolean alias for the filled appearance.\n\nAttribute: `filled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"form","description":"Browser-resolved form owner. Assigning a form id string or form element updates the `form`\ncontent attribute while reads remain element-valued.\n\nAttribute: `form`  \nReflected to its attribute.","type":"HTMLFormElement | string | null","default":"null"},{"name":"getTag","description":"Renders a selected option's chip in `multiple` mode; see `LyraSelectTagRenderer`.","type":"LyraSelectTagRenderer | undefined"},{"name":"getUnknownLabel","description":"Renders the label for a committed value that matches no option.\n\n`getTag` cannot serve this case: it is handed a matched option, which by definition does not\nexist here, so the raw value string was the only thing left to render. This hook applies\neverywhere that value's label appears -- the trigger, a `multiple` tag, and the synthetic\nlistbox row -- and is used only while the value is genuinely unmatched, so it can never\noverride a real option's own label. A blank return falls back to the raw value, exactly as no\nhook at all would. Caller-supplied text: it is not localized here. Not consulted while\n`loading` is `true` and the value is still unresolved -- see `loading` below -- because that\nvalue is not yet known to be unmatched at all.","type":"(value: string) => string | undefined"},{"name":"helpText","description":"Shoelace alias for hint. `hint` wins when both are present.\n\nAttribute: `help-text`","type":"string","default":"''"},{"name":"hint","description":"Attribute: `hint`","type":"string","default":"''"},{"name":"hoist","description":"Retained boolean alias of positioningStrategy: `hoist` is exactly\n`positioningStrategy === 'fixed'`, and writing either spelling updates the other so the two\nattributes can never disagree in the DOM. It is this control's established name (and\nShoelace's own spelling on `sl-select`), so it keeps working indefinitely; prefer\n`positioning-strategy` in new code, which reads the same on every anchored surface.\n\nAttribute: `hoist`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"label","description":"Visible label. A host `aria-label` wins on the internal trigger by attribute presence,\nincluding an explicitly empty value that suppresses this label's naming fallback.\n\nAttribute: `label`","type":"string","default":"''"},{"name":"labels","type":"NodeList","read-only":true},{"name":"loading","description":"Whether a committed value's real label may still be pending -- e.g. the `<lr-option>` catalog\nbehind it is still being fetched/mounted asynchronously and simply hasn't arrived yet. While\n`true`, a committed value that currently matches no option (the same condition `isUnknownValue()`\ntests) renders the localized `loading` placeholder in the trigger label or the relevant\n`multiple` tag instead of the raw value, and is not flagged with the dashed/italic\n`notInCatalog`/`[part='unknown-value']` badge a genuinely unmatched value gets, nor added to the\nsynthetic `showUnknownOption` listbox row -- \"not yet resolved\" is a different state from \"known\nto be missing\". With nothing selected at all -- a create form whose catalog is still being\nfetched, or an edit form whose saved selection is legitimately empty -- the trigger shows that\nsame localized `loading` text in place of `placeholder`, so one property covers the whole\npending state rather than only its committed-value half and the two halves always read the\nsame words. The trigger's accessible name is unchanged by this: a host `aria-label` still\nwins, then `label`, then `placeholder`, then the localized `select` fallback.\nA value that already matches a live option is unaffected either way. Reflected\nso `:host([loading])` is available as a styling hook. Never mutates `value`/`selectedOptions`\nitself, and does not itself disable the trigger -- pair it with `disabled` when the control\nshould also be non-interactive while its catalog is pending.\n\nAttribute: `loading`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"maxOptionsVisible","description":"Maximum number of selected-value chips shown before the rest collapse behind a localized\n\"+N\" chip (`multiple` only). `0` removes the cap. Sanitized to a finite, non-negative\ninteger, falling back to `3`.\n\nAttribute: `max-options-visible`","type":"number","default":"3"},{"name":"multiple","description":"Whether several options can be selected at once. Flipping it re-shapes `value` (a string\nbecomes a `string[]`) and the submitted form entry, so it is normally set once declaratively.\n\nAttribute: `multiple`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"name","description":"Submission name.\n\nAttribute: `name`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"open","description":"Whether the listbox is open. Disabled controls synchronously normalize every opening write\nback to `false`, including reflected-attribute writes.\n\nAttribute: `open`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"pill","description":"Fully-rounded trigger corners. Changes the private radius default to `--lr-radius-pill`, so\nan inherited or direct `--lr-select-radius` remains authoritative.\n\nAttribute: `pill`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"placeholder","description":"Text shown on the trigger while nothing is selected. It still names the trigger when neither\na host `aria-label` nor a `label` does. One exception to \"an empty selection always shows\nthis\": while `loading` is `true` the trigger shows the localized `loading` text instead, so a\nconsumer never has to re-localize that string in its own catalog to cover the empty half of a\npending state -- see loading. The trigger's accessible name is unaffected either way.\n\nAttribute: `placeholder`","type":"string","default":"''"},{"name":"placement","description":"Preferred listbox placement. `flip`/`shift` may still override it to keep the popup in view,\nand the `left`/`right` component is swapped under RTL. Changes reposition an already-open\nlistbox without closing it or changing overlay stack ownership.\n\nAttribute: `placement`  \nReflected to its attribute.","type":"Placement","default":"'bottom'"},{"name":"positioningStrategy","description":"CSS positioning scheme the listbox is laid out with -- the one property `<lr-select>`,\n`<lr-dropdown>` and `<lr-popover>` all spell the same way. `absolute` (this control's mirrored\ndefault) positions against the nearest containing block and scrolls with it; `fixed` positions\nagainst the viewport and escapes most clipping ancestors. An unsupported value resolves back\nto the default. Changes apply live while open.\nThis property reports only the instance's own authored value (or the mirrored default); the\nlistbox is actually placed with the `--lr-positioning-strategy` cascading custom property\nhonored ahead of that default when the instance itself sets nothing -- see that `@cssprop`.\n\nAttribute: `positioning-strategy`  \nReflected to its attribute.","type":"PlaceStrategy","default":"'absolute'"},{"name":"required","description":"Whether at least one selected option is required for validity.\n\nAttribute: `required`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"selectedData","description":"The opaque `data` payload of each committed value, index-aligned with `value` -- always an\narray the same length as `value`, in both single and `multiple` mode. A committed value with\nno currently live matching option -- see `isUnknownValue()` -- fills its own slot with\n`undefined` rather than shifting the entries after it, so `selectedData[i]` always describes\n`(this.multiple ? this.value[i] : this.value)`. Reached by reference, never deep-cloned: the\nlight-DOM counterpart to an async combobox source row's own `data` field, surfaced through\n`selectedRows`.","type":"readonly unknown[]","default":"[]","read-only":true},{"name":"selectedOptions","description":"Live selected option occurrences. Writes commit the referenced live options through the\nsame event-silent path as a `value` assignment; foreign/detached options are ignored and\nsingle mode keeps only the first occurrence. Reads return a fresh snapshot, so mutating the\nreturned array never mutates the control's identity bookkeeping.","type":"LyraOption[]","default":"[]"},{"name":"showUnknownOption","description":"Appends every committed value that no `<lr-option>` claims to the end of the listbox as a\nsynthetic, re-selectable row badged with the localized `notInCatalog` text -- the policy\n`<lr-model-select>` already ships.\n\nOff by default, because it adds a row to a listbox that has always rendered only real options.\nTurn it on wherever a stored value can outlive its catalog entry: without it, the out-of-list\nvalue is visible on the trigger but absent from the listbox, so a user who opens the listbox\nhas no way back to the value they arrived with. No synthetic row appears for a value `loading`\nis currently suppressing -- see that property -- since it is not yet known to be unmatched.\n\nAttribute: `show-unknown-option`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"size","description":"Visual size on the library's one control ladder — shared with `lr-button`/`lr-input`/\n`lr-combobox`/`lr-locale-picker`, so same-tier controls line up in a toolbar row. Accepts both\nthe canonical `'2xs'`–`'xl'` steps and Web Awesome's/Shoelace's `'small'`/`'medium'`/`'large'`\nspellings of `s`/`m`/`l`; the two render identically.\n\nAttribute: `size`  \nReflected to its attribute.","type":"LyraSize","default":"'m'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"sync","description":"Copies the trigger's width, height, or both onto the listbox -- the same property\n`<lr-popup>`/`<lr-popover>`/`<lr-dropdown>`/`<lr-combobox>` spell, with the same values. Unset\n(the default), the listbox sizes to its own content, clamped between `--lr-size-12rem` and\n`--lr-size-28rem`, exactly as before. Set `sync=\"width\"` so a full-width trigger with short\noption labels gets a listbox that aligns to its own edges instead of floating narrower in the\nmiddle -- the content clamp above no longer applies while this is set, since the trigger's own\nwidth is now the intentional bound. A synced listbox is still bounded by the space actually\nmeasured beside its anchor, so an over-wide trigger cannot push it off-screen. Changes\nreposition an already-open listbox without closing it.\n\nAttribute: `sync`  \nReflected to its attribute.","type":"PlaceSync | undefined","default":"undefined"},{"name":"title","description":"Forwarded to the internal trigger button.\n\nAttribute: `title`","type":"string","default":"''"},{"name":"validationMessage","type":"string","read-only":true},{"name":"validity","type":"ValidityState","read-only":true},{"name":"value","description":"The selected value: a single string outside `multiple` mode (empty when nothing is\nselected), a `string[]` inside it.\n\nAssigning `undefined` or `null` clears the selection -- the documented \"unset\" contract.\nEvery string, including `''`, is instead a candidate value resolved against the current\n`<lr-option>`s: an option may legitimately declare `value=\"\"`, and assigning `''` selects it\nwhen present (mirroring what clicking that row already did). A `''`/non-array assignment that\nmatches no option still commits, exactly like any other unmatched string -- see\n`isUnknownValue()`.\n\n`LyraPickerValue<Multiple>` narrows to `string` on a `LyraSelect<false>` and `string[]` on a\n`LyraSelect<true>`; the unnarrowed default resolves to the published union below, which is\nwhy the manifest type is pinned here rather than left to the inferred alias name.\n\nAttribute: `value`","type":"string | string[]","default":"''"},{"name":"willValidate","type":"boolean","read-only":true},{"name":"withClear","description":"Show a button that empties the selection while there is anything selected.\n\nAttribute: `with-clear`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"withHint","description":"Attribute: `with-hint`","type":"boolean","default":"false"},{"name":"withLabel","description":"SSR slot-presence hints for pre-hydration form chrome.\n\nAttribute: `with-label`","type":"boolean","default":"false"}],"events":[{"name":"blur","description":"Re-dispatched from the trigger as a bubbling, composed event.","type":"FocusEvent"},{"name":"change","description":"Fired when the selection changed, mirroring native `<select>`'s own event name. Read the new selection from `value`.","type":"Event"},{"name":"focus","description":"Re-dispatched from the trigger as a bubbling, composed event.","type":"FocusEvent"},{"name":"input","description":"Fired alongside `change` on every selection change (native `<select>` doesn't meaningfully distinguish the two either).","type":"InputEvent"},{"name":"lr-activate","description":"Fired on every activation of an available listbox row -- a click, or Enter/Space on the active row -- whether or not the selection actually moved. `detail: { value }` carries the activated option's own value, always a single string even in `multiple` mode. Bubbling and composed, so a host outside the shadow tree receives it. Not cancelable: it is a notification that the user picked a row, not a veto point, and nothing in this component branches on it. In single-select mode, re-picking the already-selected row is the case `change`/`lr-change` deliberately stay silent for (matching a native `<select>`) -- \"re-run that filter\" is a real intent -- and it is otherwise unobservable, because the rows live in this shadow root, so a retargeted `click` names no option and a keyboard commit produces no click at all. When an activation does move the selection, `input`/`lr-input`/`change`/`lr-change` are emitted first. Not fired for a programmatic `value` assignment, nor by the `with-clear` button.","type":"CustomEvent<{ value: string }>"},{"name":"lr-after-hide","description":"The listbox finished closing and its transition settled.","type":"CustomEvent<null>"},{"name":"lr-after-show","description":"The listbox finished opening and its transition settled.","type":"CustomEvent<null>"},{"name":"lr-change","description":"Prefixed compatibility alias fired after `input` and `change` on the same selection change, mirroring `<lr-checkbox>`'s `lr-change`. Not fired for a programmatic `value` assignment. `detail.data` mirrors `lr-input`.","type":"CustomEvent<\n    LyraEventDetailSnapshot<{\n      readonly value: LyraPickerDetailValue<Multiple>;\n      readonly data: readonly unknown[];\n    }>\n  >"},{"name":"lr-clear","description":"The `with-clear` button emptied the selection, fired after the `input`/`lr-input`/`change`/`lr-change` sequence. Never fired when there was nothing to clear.","type":"CustomEvent<null>"},{"name":"lr-hide","description":"The listbox is about to close, however `open` became false. Conditionally cancelable: connected transitions can be vetoed on the same terms as `lr-show`; an already-removed element closing on disconnect cannot honour a veto. Disabling the control, directly or through a fieldset, force-closes it without this vetoable lifecycle because a disabled control cannot retain an interactive popup.","type":"CustomEvent<null>"},{"name":"lr-input","description":"Prefixed compatibility alias for `input`; `detail: { value, data }`, where `data` is the opaque `data` payload of each newly committed occurrence (see `selectedData`), by reference, never deep-cloned.","type":"CustomEvent<\n    LyraEventDetailSnapshot<{\n      readonly value: LyraPickerDetailValue<Multiple>;\n      readonly data: readonly unknown[];\n    }>\n  >"},{"name":"lr-invalid","description":"The select failed a validity check. Cancelable: calling `preventDefault()` also cancels the native `invalid` event behind it, suppressing the browser's own validation bubble so an app can present the failure its own way.","type":"CustomEvent<null>"},{"name":"lr-show","description":"The listbox is about to open, however `open` became true. Cancelable — `preventDefault()` leaves it closed and the reflected attribute untouched.","type":"CustomEvent<null>"}]}},{"name":"lr-selection-toolbar","description":"`<lr-selection-toolbar>` — a nonmodal action toolbar positioned above selected text. It carries\nthe selected text and a format-neutral document anchor into ask, quote, cite, or copy actions.\nControlled action refreshes preserve a focused action by id, otherwise move to the nearest\nsurvivor, or focus the toolbar when no actions remain, without overriding newer focus moves.\n\nThe four built-in actions are the shipped set; `actions` reorders or subsets them. Anything\nbeyond them -- \"translate\", \"define\", \"search web\" -- goes in the `actions` slot, which renders\nafter the built-ins inside the same `role=\"toolbar\"` element and joins the same roving-tabindex\ngroup (Home/End/Arrow, RTL-mirrored), so a fifth action does not mean reimplementing the\npositioning, keyboard, and dismissal behavior from scratch. The toolbar traverses open shadow\nroots and slots to manage each real action rather than treating a custom-element or wrapper root\nas a focus target merely because it exposes `focus()`. A slotted action carries its own\naccessible name and click handling; this component only manages its tab stop. Availability,\nactionability, and `tabindex` changes are reconciled live; focused removals/unavailable actions\nmove to the nearest survivor or stable toolbar without overriding newer external focus.\nDuplicate built-in names normalize first-wins before rendering, roving focus, or action events.\n\nPublic anchor records and action collections take bounded, clone-owned readonly snapshots.\nCreate and reassign a new record or array after changes; mutating the assigned value does not\nupdate the view.\n\n---\n\n**Component metadata**\n\n- Status: `stable`\n- Since: `7.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| `actions` | Extra actions rendered after the built-in ask/quote/cite/copy buttons, inside the same `role=\"toolbar\"` element and roving-tabindex group. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `action` | Every action button. |\n| `action-ask` | The ask action. |\n| `action-cite` | The cite action. |\n| `action-copy` | The copy action. |\n| `action-quote` | The quote action. |\n| `toolbar` | The floating `role=\"toolbar\"` surface. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-overlay-border` (default: `var(--lr-color-border)`) — Shared floating-surface edge colour, on the toolbar.\n- `--lr-overlay-radius` (default: `var(--lr-radius)`) — Shared floating-surface corner radius, on the toolbar.\n- `--lr-overlay-shadow-anchored` (default: `var(--lr-shadow-m)`) — Elevation of the anchored surface.\n- `--lr-overlay-surface` (default: `var(--lr-color-surface-overlay)`) — Shared floating-surface fill, on the toolbar.\n- `--lr-selection-toolbar-placement-gap` (default: `var(--lr-space-s)`) — Non-negative distance between the selection and toolbar, and between the toolbar and viewport during collision avoidance. Unitless pixel values and `px`, `rem`, and `em` values are resolved live; invalid values fall back to the default and negative values clamp to `0`.","attributes":[{"name":"aria-label","description":"Type: `string | null`  \nDefault: `null`"},{"name":"label","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"open","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"text","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}}],"slots":[{"name":"actions","description":"Extra actions rendered after the built-in ask/quote/cite/copy buttons, inside the same `role=\"toolbar\"` element and roving-tabindex group."}],"js":{"properties":[{"name":"accessibleLabel","description":"Attribute: `aria-label`","type":"string | null","default":"null"},{"name":"actions","description":"Controlled action set. A focused action survives reordering by id; if it is removed, focus\nmoves to the nearest action or the stable toolbar when the set becomes empty. Duplicate names\nnormalize first-wins.","type":"readonly SelectionAction[]","default":"[ 'ask', 'quote', 'cite', 'copy', ]"},{"name":"anchor","description":"Clone-owned selection anchor. Reassign a new record after changing any path segment.","type":"DocumentLocator | null","default":"null"},{"name":"label","description":"Attribute: `label`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"open","description":"Attribute: `open`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"rect","type":"DOMRectReadOnly | null","default":"null"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"text","description":"Attribute: `text`","type":"string","default":"''"}],"events":[{"name":"lr-copy","description":"Clipboard writing fulfilled. Frozen `detail: { ok: true, text }`.","type":"CustomEvent<LyraClipboardWriteSuccess>"},{"name":"lr-copy-error","description":"Clipboard writing failed. Frozen `detail: { ok: false, text, reason, error }`.","type":"CustomEvent<LyraClipboardWriteFailure>"},{"name":"lr-dismiss","description":"The toolbar was dismissed with Escape.","type":"CustomEvent<null>"},{"name":"lr-error","description":"Clipboard writing failed; generic no-detail notification.","type":"CustomEvent<null>"},{"name":"lr-selection-action","description":"An action was chosen. `detail: { action, text, anchor }`.","type":"CustomEvent<LyraEventDetailSnapshot<SelectionActionDetail>>"}]}},{"name":"lr-sequence-playback","description":"`<lr-sequence-playback>` — steps a current index through `[0, itemCount)` on a fixed\ninterval (play/pause), the common building block behind ad-hoc\nplay-timers in time-series dashboards.\n\n---\n\n**Component metadata**\n\n- Status: `stable`\n- Since: `9.0.0`\n- Rationale: This tag entered Lyra as a stable public API with documented behavior, accessibility, and cross-browser support.\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 playback controls wrapper. |\n| `play-button` | The play/pause button; disabled resting paint is retained under hover and press. |\n| `slider` | The playback position slider. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-sequence-playback-icon-size` (default: `calc(var(--lr-icon-button-size) * 0.35)`) — Font size of the play/pause glyph, derived from the shared icon-button hit-target size.\n- `--lr-sequence-playback-play-button-active-bg` — Pressed play/pause button background. Defaults to the existing surface active mix; read as an inline fallback so an ancestor value inherits.\n- `--lr-sequence-playback-play-button-active-border-color` (default: `var(--lr-color-brand)`) — Pressed play/pause button border color; read as an inline fallback so an ancestor value inherits.","attributes":[{"name":"current-index","description":"The current sequence item, in `[0, itemCount)`.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"hidden","description":"Re-declared as a Lit reactive property (shadowing the inherited plain\n`HTMLElement.hidden` IDL property) so that setting `el.hidden = true` —\nor the `hidden` attribute — actually enters Lit's change-tracking system\nand the `willUpdate` auto-pause guard below can see it via `changed`.\n`reflect: true` preserves the native attribute-reflection behavior.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"interval-ms","description":"Delay between ticks, in milliseconds, while playing. Clamped to the timer-safe range in\n`scheduleTick()`.\n\nType: `number`  \nDefault: `900`","value":{"type":["number"]}},{"name":"item-count","description":"Total number of sequence items; the current-index range is `[0, itemCount)`.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"loop","description":"Type: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"playing","description":"Type: `boolean`","value":{"type":["boolean"]}}],"js":{"properties":[{"name":"currentIndex","description":"The current sequence item, in `[0, itemCount)`.\n\nAttribute: `current-index`","type":"number","default":"0"},{"name":"hidden","description":"Re-declared as a Lit reactive property (shadowing the inherited plain\n`HTMLElement.hidden` IDL property) so that setting `el.hidden = true` —\nor the `hidden` attribute — actually enters Lit's change-tracking system\nand the `willUpdate` auto-pause guard below can see it via `changed`.\n`reflect: true` preserves the native attribute-reflection behavior.\n\nAttribute: `hidden`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"intervalMs","description":"Delay between ticks, in milliseconds, while playing. Clamped to the timer-safe range in\n`scheduleTick()`.\n\nAttribute: `interval-ms`","type":"number","default":"900"},{"name":"itemCount","description":"Total number of sequence items; the current-index range is `[0, itemCount)`.\n\nAttribute: `item-count`","type":"number","default":"0"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"loop","description":"Attribute: `loop`","type":"boolean","default":"true"},{"name":"playing","description":"Attribute: `playing`  \nReflected to its attribute.","type":"boolean"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"blur","description":"Relayed once from an internal playback control as a bubbling, composed native event.","type":"FocusEvent"},{"name":"focus","description":"Relayed once from an internal playback control as a bubbling, composed native event.","type":"FocusEvent"},{"name":"lr-pause","description":"Fired when playback stops (including auto-pause).","type":"CustomEvent<null>"},{"name":"lr-play","description":"Fired when playback starts.","type":"CustomEvent<null>"},{"name":"lr-sequence-step","description":"`detail: { currentIndex }`, fired on every tick and manual step.","type":"CustomEvent<LyraSequencePlaybackStepDetail>"}]}},{"name":"lr-sequence-strip","description":"`<lr-sequence-strip>` — a compact, one-thin-cell-per-item strip visualizing a sequence of\ncategorical states, with an optional secondary per-cell marker. Pure CSS/flex, no chart.js/SVG/\ncanvas — sized/named consistently with the sparkline/heatmap family, but a glanceable aggregate\nvisualization. The strip is a labeled `role=\"list\"` and each cell is a named list item.\nExactly one cell is tabbable; Left/Right and Home/End rove through the cells and show the same\ndetail tooltip as pointer hover. Clicking a cell, or pressing Enter/Space on the roving cell,\nemits the controlled `lr-item-activate` event without moving selection. A host `aria-label`\nnames the host itself without being duplicated on the internal list; `accessible-label` names\nthat list, otherwise its category summary does.\nA category whose label is omitted or blank uses the localized unnamed-category label for\naffected list-item names and tooltips, its summary clause, and its legend row.\nControlled item refreshes preserve the focused\nitem by id, clamp to the nearest survivor, and focus the stable list when the strip becomes empty.\nA queued arrow/Home/End focus is generation- and identity-bound: replacing `items`, disconnecting,\nor reconnecting before that update settles cannot focus the same numeric index in a new model.\nAt most 200 cells are rendered. Past that cap the strip becomes a span-preserving OVERVIEW rather\nthan a window: the retained items are distributed over exactly 200 contiguous ranges, each cell\npainted by its range's dominant category and marked when any item in it is, so the strip still\nrepresents the whole sequence at full width. Roving focus, `aria-posinset`/`aria-setsize`,\n`aria-current` and activation all address those cells; activating a range emits its FIRST item.\nAssignment\nretains at most the first 10,000 items and categories as detached frozen snapshots; reassign a\ncollection after changing it.\n\nAn item may also set `disabled`, marking it non-actionable: `aria-disabled=\"true\"` replaces the\nselected/active affordances of the cell that represents it, activating it (click or Enter/Space)\nemits nothing, and roving Left/Right/Home/End navigation -- including the default resting tab\nstop -- steps past it instead of landing on it. Above the cell cap, a range cell's disabled state\nfollows its own activated item, the range's first (see `lr-item-activate` above). Omitted or\n`false` renders the item exactly as before this field existed.\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 root strip wrapper (`role=\"list\"`). |\n| `bucket-summary` | Visible item-total/range-count disclosure, rendered only while the strip is past its cell cap and therefore showing ranges rather than individual items. It replaces 15.x's `window-range`, which disclosed a projection window this component no longer has. |\n| `cell` | Each named, roving-focus cell, background-colored by its category — one item below the render cap, one dominant-coloured item range above it. Carries `aria-disabled=\"true\"` while the item it activates sets `disabled`. |\n| `legend` | The static category key rendered below the strip when `showLegend` is set (`aria-hidden` — it repeats the strip's own `aria-label` visually). |\n| `legend-item` | One swatch + label pair in the legend, one per `categories` entry (plus one trailing marker row when `markerLabel` is set). |\n| `legend-label` | The text of a legend item (the category's `label`, or the localized unnamed-category label). |\n| `legend-limit` | Visible rendered/total category count when the legend is bounded. |\n| `legend-marker-swatch` | The chip of the `markerLabel` legend row: a neutral chip carrying the same bottom bar a `marker: true` cell paints, in the same `--lr-sequence-strip-marker-color`. |\n| `legend-swatch` | The color chip of a legend item, matching that category's cell color. |\n| `marker` | The small bottom marker on a cell any of whose items sets `marker: true`. |\n| `tooltip` | The hover/focus tooltip showing the active cell's label, positioned from that active cell. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-sequence-strip-disabled-opacity` (default: `var(--lr-opacity-disabled)`) — Opacity of a cell whose activated item sets `disabled`.\n- `--lr-sequence-strip-height` (default: `var(--lr-size-1-5rem)`) — Block size of the strip.\n- `--lr-sequence-strip-legend-marker-bg` (default: `var(--lr-color-surface-raised)`) — Neutral chip background behind the marker legend row's bar; it stands in for \"any cell\", so it deliberately matches no category color.\n- `--lr-sequence-strip-legend-swatch-size` (default: `var(--lr-size-0-625rem)`) — Inline and block size of a legend swatch (category and marker rows alike).\n- `--lr-sequence-strip-marker-color` (default: `var(--lr-color-text)`) — Color of the bottom marker on a `marker: true` cell, and of the marker legend row's bar.","attributes":[{"name":"accessible-label","description":"Overrides the auto-generated `aria-label` (a per-category \"label: count\" summary). Unset\ncomputes the summary from `items`/`categories`; an explicitly empty string renders as an\nempty label rather than falling back to the auto-generated summary.\n\nType: `string | undefined`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"marker-label","description":"Names what a cell's `marker` means (e.g. `\"Subagent\"`). Set it to key the marker in the legend\n— with `showLegend` on it adds one trailing `[part=\"legend-item\"]` whose swatch reproduces the\ncell's own marker treatment — and to have the marker counted in the auto-generated summary,\nwhich is otherwise per-category only. Unset (the default) nothing changes: no extra legend row\nand no extra summary clause.\n\nType: `string | undefined`"},{"name":"selected-index","description":"Index of the currently selected item, or `-1` (the default) for none — the controlled selection\nthis strip's natural companion, `lr-sequence-playback`, scrubs through. Mirrors the shape\n`lr-lite-chart`'s `selectedIndices` and `lr-heatmap`'s `selectedCell` already establish.\n\nControlled, not self-managing: activating a cell emits `lr-item-activate` and does **not**\nmove the selection on its own, so the consumer stays the single source of truth and the\ncomponent cannot drift from a playback index it does not own. Before focus enters, a valid\nselection anchors the strip's sole keyboard entry stop; keyboard roving remains authoritative\nafter focus. Past the 200-cell cap it is the whole range containing the index that reads as\nselected, since that range is the only thing the strip draws for it. An out-of-range or\nnon-integer value selects nothing rather than throwing.\n\nType: `number`  \nDefault: `-1`","value":{"type":["number"]}},{"name":"show-legend","description":"Renders a static `[part=\"legend\"]` key of every `categories` entry below the strip, so the\ncolor-to-category mapping is readable without hovering each cell. Deliberately\nnon-interactive: unlike `<lr-graph-legend>` this toggles nothing and emits nothing — the\nstrip is a presentational aggregate, and the key describes the scheme, not the current data\n(a category with no matching item still gets a row).\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"js":{"properties":[{"name":"accessibleLabel","description":"Overrides the auto-generated `aria-label` (a per-category \"label: count\" summary). Unset\ncomputes the summary from `items`/`categories`; an explicitly empty string renders as an\nempty label rather than falling back to the auto-generated summary.\n\nAttribute: `accessible-label`","type":"string | undefined"},{"name":"categories","description":"Frozen snapshot of at most the first 10,000 categories. Empty/blank ids are omitted and\nduplicate ids use the first entry. Reassign to update.","type":"readonly SequenceStripCategory[]"},{"name":"items","description":"Frozen snapshot of at most the first 10,000 items. Empty/blank ids are omitted and duplicate\nids use the first entry. Reassign to update.","type":"readonly SequenceStripItem[]"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"markerLabel","description":"Names what a cell's `marker` means (e.g. `\"Subagent\"`). Set it to key the marker in the legend\n— with `showLegend` on it adds one trailing `[part=\"legend-item\"]` whose swatch reproduces the\ncell's own marker treatment — and to have the marker counted in the auto-generated summary,\nwhich is otherwise per-category only. Unset (the default) nothing changes: no extra legend row\nand no extra summary clause.\n\nAttribute: `marker-label`","type":"string | undefined"},{"name":"selectedIndex","description":"Index of the currently selected item, or `-1` (the default) for none — the controlled selection\nthis strip's natural companion, `lr-sequence-playback`, scrubs through. Mirrors the shape\n`lr-lite-chart`'s `selectedIndices` and `lr-heatmap`'s `selectedCell` already establish.\n\nControlled, not self-managing: activating a cell emits `lr-item-activate` and does **not**\nmove the selection on its own, so the consumer stays the single source of truth and the\ncomponent cannot drift from a playback index it does not own. Before focus enters, a valid\nselection anchors the strip's sole keyboard entry stop; keyboard roving remains authoritative\nafter focus. Past the 200-cell cap it is the whole range containing the index that reads as\nselected, since that range is the only thing the strip draws for it. An out-of-range or\nnon-integer value selects nothing rather than throwing.\n\nAttribute: `selected-index`","type":"number","default":"-1"},{"name":"showLegend","description":"Renders a static `[part=\"legend\"]` key of every `categories` entry below the strip, so the\ncolor-to-category mapping is readable without hovering each cell. Deliberately\nnon-interactive: unlike `<lr-graph-legend>` this toggles nothing and emits nothing — the\nstrip is a presentational aggregate, and the key describes the scheme, not the current data\n(a category with no matching item still gets a row).\n\nAttribute: `show-legend`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-item-activate","description":"Fired when a cell is clicked, or activated with Enter/Space on the roving-tabindex focus. `detail: { index, id, item }` identifies the picked item — the range's FIRST item once the strip is past its cell cap. Not cancelable, and it does not move `selectedIndex` on its own -- the selection is controlled, so the consumer stays the single source of truth for a playback index this strip does not own.","type":"CustomEvent<LyraSequenceStripActivateDetail>"}]}},{"name":"lr-skeleton","description":"`<lr-skeleton>` — a loading placeholder mirroring the public Web Awesome/Shoelace skeleton\nsurface under the `lr-` prefix. It is decorative by default like both upstreams; `announce`\nopts one placeholder into a localized status. An author-supplied host role remains authoritative;\nthe component adds/removes `role=\"status\"` only when it owns that opt-in role. Geometry is\nexposed as `shape`.\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` | Compatibility name for the placeholder shape. |\n| `indicator` | The placeholder shape and animation surface. It is the same node as `base`. |\n\n---\n\n**CSS Custom Properties**\n\n- `--border-radius` (default: `var(--lr-skeleton-border-radius)`) — Shoelace-compatible corner radius.\n- `--color` (default: `var(--lr-skeleton-color)`) — Upstream-compatible placeholder color.\n- `--lr-skeleton-border-radius` (default: `var(--lr-radius)`) — Text/rectangle corner radius.\n- `--lr-skeleton-color` (default: `var(--lr-color-border)`) — Placeholder color.\n- `--lr-skeleton-h` (default: `var(--lr-size-1em)`) — Block size of the placeholder.\n- `--lr-skeleton-sheen-color` (default: `var(--lr-color-surface)`) — Sheen highlight color.\n- `--lr-skeleton-w` (default: `100%`) — Inline size of the placeholder.\n- `--lr-transition-ambient` (default: `1.8s ease-in-out`) — Animation duration and timing function shared by the pulse and sheen effects.\n- `--sheen-color` (default: `var(--lr-skeleton-sheen-color)`) — Upstream-compatible sheen color.","attributes":[{"name":"announce","description":"Opts this placeholder into a localized status announcement. Leave unset for decorative\nskeletons, including repeated members of a group whose loading state is announced once.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"effect","description":"Type: `LyraSkeletonEffect`  \nDefault: `'none'`","value":{"type":["'pulse'","'sheen'","'none'"]}},{"name":"height","description":"Type: `string | undefined`"},{"name":"label","description":"Accessible name announced via `role=\"status\"`. Absence uses the localized loading string;\nevery supplied value, including the English fallback or an empty string, remains literal.\n\nType: `string | undefined`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"shape","description":"Placeholder geometry. This is named `shape` so it cannot be confused with semantic tone.\n\nType: `LyraSkeletonShape`  \nDefault: `'text'`","value":{"type":["'text'","'circle'","'rect'"]}},{"name":"width","description":"Type: `string | undefined`"}],"js":{"properties":[{"name":"announce","description":"Opts this placeholder into a localized status announcement. Leave unset for decorative\nskeletons, including repeated members of a group whose loading state is announced once.\n\nAttribute: `announce`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"effect","description":"Attribute: `effect`","type":"LyraSkeletonEffect","default":"'none'"},{"name":"height","description":"Attribute: `height`","type":"string | undefined"},{"name":"label","description":"Accessible name announced via `role=\"status\"`. Absence uses the localized loading string;\nevery supplied value, including the English fallback or an empty string, remains literal.\n\nAttribute: `label`","type":"string | undefined"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"shape","description":"Placeholder geometry. This is named `shape` so it cannot be confused with semantic tone.\n\nAttribute: `shape`  \nReflected to its attribute.","type":"LyraSkeletonShape","default":"'text'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"width","description":"Attribute: `width`","type":"string | undefined"}]}},{"name":"lr-slider","description":"`<lr-slider>` — a numeric range control (e.g. an LLM \"temperature\"\nsetting), form-associated. Its live `value` and reflected/reset `defaultValue` are numbers;\n`valueAsNumber` remains a numeric alias and `valueAsString` preserves the library's former\nstring round-trip explicitly. A bare slider starts at `0`, matching the mapped contract rather\nthan silently choosing the domain midpoint.\n\nA primary-button press anywhere on the track (not just the thumb) jumps the thumb\nto that point and continues the same gesture as a drag, matching native\n`<input type=range>` click-to-seek. In `range` mode the click moves\nwhichever handle is nearer the clicked position.\n\n`range` turns the control into a two-handle selection between `minValue` and `maxValue`, which\ndefault to `0` and `50`. When one handle crosses the other it pushes its sibling instead of\nstopping, so the active thumb always follows the user's pointer/key. A named range submits two\nsame-name `FormData` entries in lower/upper order; a single slider submits one numeric string.\n\n`label`/`hint`/`errorText` plus their slots render visible form context. `with-label`/`with-hint`\nare SSR presence hints only: hydrated instances also detect populated content automatically.\nEvery handle references visible error content before hint content through `aria-describedby`.\nIn single mode, host-root external descriptions precede that local guidance and follow live\nsource replacement, removal and reconnection. Removing label, hint, help-text or error-text\nsafely removes the corresponding copy while preserving native attribute-removal readback.\nThe `reference` slot supplies endpoint/unit context in the `references` part. All four text\nregions wrap unbroken content within the slider's allocation in LTR and RTL instead of widening\nit.\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| `error` | Rich error content, replacing the plain-text `errorText` property. |\n| `help-text` | Shoelace-compatible alias for the `hint` slot. |\n| `hint` | Rich hint content, replacing the plain-text `hint` attribute. |\n| `label` | Rich visible label content, appended after the plain `label` property. |\n| `reference` | Endpoint or unit references rendered beside the track. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | Compatibility name on the interactive track row; use `slider`. |\n| `control` | The row wrapping the track and the optional value readout. Carries `role=\"group\"` (named from `label`/`aria-label`) in `range` mode, so the two handles are announced as one control. |\n| `error` | The error region, hidden while neither `errorText` nor the `error` slot has content. |\n| `form-control` | Shoelace-compatible name on the same interactive row. |\n| `form-control-help-text` | Shoelace-compatible name on the hint region. |\n| `form-control-input` | Shoelace-compatible name on the interactive track row. |\n| `form-control-label` | Shoelace-compatible name on the visible label. |\n| `hint` | The hint region, hidden while neither `hint` nor the `hint` slot has content. |\n| `indicator` | The filled portion of the track: from `min` up to the current value, or between the two handles in `range` mode. |\n| `input` | Shoelace-compatible name on the interactive track row. |\n| `label` | Visible label content. |\n| `label-row` | Label and readout row, rendered with showValue and valuePlacement=\"label\". |\n| `marker` | One `step`-grid tick mark. |\n| `markers` | The tick-mark container rendered when `with-markers` is set. |\n| `references` | Wrapper for the `reference` slot. |\n| `slider` | Interactive track row. It is the same node as `base`. |\n| `thumb` | A draggable handle (`role=\"slider\"`). Present on every handle, including both range handles. |\n| `thumb-max` | The upper handle in `range` mode (also carries `thumb`). |\n| `thumb-min` | The lower handle in `range` mode (also carries `thumb`). |\n| `tooltip` | The live value bubble rendered per handle when `with-tooltip` is set. |\n| `tooltip-visible` | Added to `tooltip` while that handle is focused or being dragged. |\n| `tooltip__arrow` | Decorative tooltip arrow. |\n| `tooltip__content` | Tooltip text wrapper. |\n| `tooltip__tooltip` | Upstream alias on the tooltip bubble. |\n| `track` | The full-length background line. |\n| `value` | The visible readout, rendered when `show-value` is true. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-slider-gap` (default: `var(--lr-space-s)`) — Gap between the track row, value, label, references, and hint as they wrap.\n- `--lr-slider-track-length` (default: `var(--lr-size-10rem)`) — Length of the track in `orientation=\"vertical\"`; the horizontal track fills its container instead. Declared as an inline `var()` fallback (never on `:host`), so a consumer override at any ancestor wins.\n- `--lr-slider-row-size` (default: `calc(var(--lr-form-control-height) * 0.6)`) — Cross-axis extent of the control's interactive row: its block size when horizontal, its inline size when vertical. Scales off the shared form-control ladder, so a size tier moves it without a per-tier rule.\n- `--lr-slider-thumb-size` (default: `calc(var(--lr-form-control-height) * 0.4)`) — Diameter of each draggable handle, derived from the `size` tier's shared control height. The transparent drag area around it never drops below 1.75rem/28px, whatever this is set to.\n- `--lr-slider-track-thickness` (default: `calc(var(--lr-slider-thumb-size) * 0.25)`) — Thickness of the track, the filled indicator and (scaled from it) the `with-markers` ticks.\n- `--lr-slider-thumb-bg` (default: `var(--lr-color-brand)`) — Resting thumb background.\n- `--lr-slider-thumb-border-color` (default: `var(--lr-color-surface)`) — Resting thumb border.\n- `--lr-slider-thumb-hover-ring-color` (default: `var(--lr-color-brand-quiet)`) — Thumb ring while hovered.\n- `--lr-slider-thumb-active-ring-color` (default: `var(--lr-slider-thumb-hover-ring-color)`) — Thumb ring while pressed.\n- `--thumb-size` — Shoelace alias setting both thumb dimensions.\n- `--thumb-width` — Upstream thumb inline size.\n- `--thumb-height` — Upstream thumb block size.\n- `--track-height` — Shoelace alias for track thickness.\n- `--track-size` — Web Awesome alias for track thickness.\n- `--track-color-active` — Filled indicator color.\n- `--track-color-inactive` — Resting track color.\n- `--track-active-offset` — Additional indicator offset.\n- `--tooltip-offset` — Shoelace tooltip distance alias.\n- `--lr-slider-tooltip-distance` (default: `8`) — Numeric CSS-pixel distance written by the `tooltipDistance` property for the internal tooltip-placement calculation.\n- `--marker-width` — Marker inline size.\n- `--marker-height` — Marker block size.\n- `--lr-form-control-required-content` (default: `' *'`) — The required marker appended to `form-control-label` while `required` is set. Set it to `''` to suppress the marker, or to any other quoted string (`' (required)'`, a localized word) to replace it.\n- `--lr-form-control-required-color` (default: `var(--lr-color-danger)`) — Required-marker color, themeable independently of error text and invalid borders.\n- `--lr-form-control-required-offset` (default: `0`) — Inline space between the label text and the required marker.","attributes":[{"name":"autofocus","description":"Focuses the first thumb after the first client render.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"custom-error","description":"Caller-supplied constraint-validation message.\n\nType: `string | null`  \nDefault: `null`"},{"name":"disabled","description":"Prevents focus, user edits, and form submission.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"error-text","description":"Plain-text error associated with every handle; rich content can use the `error` slot.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"form","description":"Type: `HTMLFormElement | string | null`  \nDefault: `null`"},{"name":"help-text","description":"Shoelace-compatible spelling of `hint`; `hint` wins when both are supplied.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"hint","description":"Plain-text description of what the slider controls, rendered below the track and wired to\nevery handle through `aria-describedby`. Use the `hint` slot instead for rich content.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"indicator-offset","description":"Origin of the single-slider indicator. The fill spans between this value and `value`.\n\nType: `number | undefined`"},{"name":"label","description":"Accessible-name fallback for the slider when the host has no `aria-label`, used when no\nvisible label context exists around it (e.g. no wrapping `<label>` or adjacent heading).\nThe resolved name is set on the interactive `role=\"slider\"` element — or, in `range` mode,\non the `role=\"group\"` wrapping both handles, since each handle then owns its own\nstart/end name. A host attribute wins by presence, including an explicitly empty value that\nsuppresses visible/property/localized fallbacks and visible-label linkage. With neither a\nhost `aria-label` nor this property, the localized generic `sliderLabel` message applies so\nthe focusable thumb is never nameless (the same pattern as `<lr-input>`/`<lr-textarea>`'s\nbuilt-in generic labels).\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max","description":"Upper domain bound.\n\nType: `number`  \nDefault: `100`","value":{"type":["number"]}},{"name":"max-value","description":"The upper handle's value in `range` mode. Crossing pushes the lower handle.\n\nType: `number`  \nDefault: `50`","value":{"type":["number"]}},{"name":"min","description":"Lower domain bound.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"min-value","description":"The lower handle's value in `range` mode. Crossing pushes the upper handle.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"name","description":"Submitted form-data key. A null/empty name omits the control from submission.\n\nType: `string | null`  \nDefault: `null`"},{"name":"orientation","description":"Which axis carries the value. `'vertical'` also switches the primary keys to\nArrowUp/ArrowDown and exposes `aria-orientation=\"vertical\"`.\n\nType: `SliderOrientation`  \nDefault: `'horizontal'`","value":{"type":["'horizontal'","'vertical'"]}},{"name":"range","description":"Two-handle mode: the control selects the span between `minValue` and\n`maxValue` instead of a single number. See the class doc for what this\nmeans for form submission.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"readonly","description":"Whether the value is displayed but not changeable. Unlike `disabled`, a read-only slider\nstays focusable and fully legible, and still submits its value.\nBecoming readonly cancels unfinished gestures, preserving their live value.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"required","description":"Whether the control participates in the required form-state vocabulary. A slider always\nhas a numeric value, so this flag does not by itself make the control invalid.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"show-value","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"size","description":"Control size, on the library's shared ladder. Accepts both spellings of every tier —\n`2xs`/`xs`/`s`/`m`/`l`/`xl` and Web Awesome's `small`/`medium`/`large` — so migrating either way\nis a tag rename. Scales the track, the filled indicator, the tick marks and the handles off the\nsame `--lr-form-control-*` values `<lr-input>`/`<lr-select>`/`<lr-button>` use, so controls of\none `size` line up in a row. The handle's transparent drag area keeps its own 1.75rem/28px\nfloor at every tier, so a small slider is still a conformant pointer target.\n\nType: `LyraSize`  \nDefault: `'m'`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}},{"name":"step","description":"Step-grid interval; non-positive values select the unstepped mode.\n\nType: `number`  \nDefault: `1`","value":{"type":["number"]}},{"name":"tooltip","description":"Shoelace-compatible tooltip switch. `none` hides; top/bottom also set the placement. Lyra\ndefaults to `none`, unlike `<sl-range>`'s `top`; the migration codemod inserts `tooltip=\"top\"`,\nwhile a manual tag rename must set it explicitly to preserve Shoelace's default.\n\nType: `'top' | 'bottom' | 'none'`  \nDefault: `'none'`","value":{"type":["'top'","'bottom'","'none'"]}},{"name":"tooltip-distance","description":"Gap between a handle and its tooltip, measured in CSS pixels.\n\nType: `number`  \nDefault: `8`","value":{"type":["number"]}},{"name":"tooltip-placement","description":"Physical side of the handle on which the tooltip is placed.\n\nType: `SliderTooltipPlacement`  \nDefault: `'top'`","value":{"type":["'top'","'right'","'bottom'","'left'"]}},{"name":"value","description":"Reflected numeric reset default, sourced from the `value` content attribute.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"value-display","description":"Visible readout text. `formatted` reuses valueFormatter (then tooltipFormatter when absent)\nfor each handle, with localized numeric fallback for nullish results. The numeric default\npreserves the existing showValue contract. Does not change ARIA, tooltip or event behavior.\n\nType: `SliderValueDisplay`  \nDefault: `'numeric'`","value":{"type":["'numeric'","'formatted'"]}},{"name":"value-placement","description":"Position of the showValue readout. `label` places it at the inline end of a separate label\nrow without including its text in the control's accessible name.\n\nType: `SliderValuePlacement`  \nDefault: `'inline'`","value":{"type":["'inline'","'label'"]}},{"name":"with-hint","description":"SSR presence hint for hint chrome. Hydrated instances also inspect both hint slots.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"with-label","description":"SSR presence hint for visible label chrome. Hydrated instances also inspect slot content.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"with-markers","description":"Whether to draw a tick mark at every `step` position along the track.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"with-tooltip","description":"Whether to show a live value bubble beside each focused or dragged handle.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"error","description":"Rich error content, replacing the plain-text `errorText` property."},{"name":"help-text","description":"Shoelace-compatible alias for the `hint` slot."},{"name":"hint","description":"Rich hint content, replacing the plain-text `hint` attribute."},{"name":"label","description":"Rich visible label content, appended after the plain `label` property."},{"name":"reference","description":"Endpoint or unit references rendered beside the track."}],"js":{"properties":[{"name":"autofocus","description":"Focuses the first thumb after the first client render.\n\nAttribute: `autofocus`","type":"boolean","default":"false"},{"name":"customError","description":"Caller-supplied constraint-validation message.\n\nAttribute: `custom-error`  \nReflected to its attribute.","type":"string | null","default":"null"},{"name":"defaultValue","description":"Reflected numeric reset default, sourced from the `value` content attribute.\n\nAttribute: `value`  \nReflected to its attribute.","type":"number","default":"0"},{"name":"disabled","description":"Prevents focus, user edits, and form submission.\n\nAttribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"effectiveDisabled","type":"boolean","read-only":true},{"name":"errorText","description":"Plain-text error associated with every handle; rich content can use the `error` slot.\n\nAttribute: `error-text`","type":"string","default":"''"},{"name":"form","description":"Attribute: `form`  \nReflected to its attribute.","type":"HTMLFormElement | string | null","default":"null"},{"name":"helpText","description":"Shoelace-compatible spelling of `hint`; `hint` wins when both are supplied.\n\nAttribute: `help-text`","type":"string","default":"''"},{"name":"hint","description":"Plain-text description of what the slider controls, rendered below the track and wired to\nevery handle through `aria-describedby`. Use the `hint` slot instead for rich content.\n\nAttribute: `hint`","type":"string","default":"''"},{"name":"indicatorOffset","description":"Origin of the single-slider indicator. The fill spans between this value and `value`.\n\nAttribute: `indicator-offset`","type":"number | undefined"},{"name":"isRange","description":"Read-only upstream alias indicating whether two handles are active.","type":"boolean","default":"false","read-only":true},{"name":"label","description":"Accessible-name fallback for the slider when the host has no `aria-label`, used when no\nvisible label context exists around it (e.g. no wrapping `<label>` or adjacent heading).\nThe resolved name is set on the interactive `role=\"slider\"` element — or, in `range` mode,\non the `role=\"group\"` wrapping both handles, since each handle then owns its own\nstart/end name. A host attribute wins by presence, including an explicitly empty value that\nsuppresses visible/property/localized fallbacks and visible-label linkage. With neither a\nhost `aria-label` nor this property, the localized generic `sliderLabel` message applies so\nthe focusable thumb is never nameless (the same pattern as `<lr-input>`/`<lr-textarea>`'s\nbuilt-in generic labels).\n\nAttribute: `label`","type":"string","default":"''"},{"name":"labels","type":"NodeList","read-only":true},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"max","description":"Upper domain bound.\n\nAttribute: `max`","type":"number","default":"100"},{"name":"maxValue","description":"The upper handle's value in `range` mode. Crossing pushes the lower handle.\n\nAttribute: `max-value`","type":"number","default":"50"},{"name":"min","description":"Lower domain bound.\n\nAttribute: `min`","type":"number","default":"0"},{"name":"minValue","description":"The lower handle's value in `range` mode. Crossing pushes the upper handle.\n\nAttribute: `min-value`","type":"number","default":"0"},{"name":"name","description":"Submitted form-data key. A null/empty name omits the control from submission.\n\nAttribute: `name`  \nReflected to its attribute.","type":"string | null","default":"null"},{"name":"orientation","description":"Which axis carries the value. `'vertical'` also switches the primary keys to\nArrowUp/ArrowDown and exposes `aria-orientation=\"vertical\"`.\n\nAttribute: `orientation`  \nReflected to its attribute.","type":"SliderOrientation","default":"'horizontal'"},{"name":"range","description":"Two-handle mode: the control selects the span between `minValue` and\n`maxValue` instead of a single number. See the class doc for what this\nmeans for form submission.\n\nAttribute: `range`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"readonly","description":"Whether the value is displayed but not changeable. Unlike `disabled`, a read-only slider\nstays focusable and fully legible, and still submits its value.\nBecoming readonly cancels unfinished gestures, preserving their live value.\n\nAttribute: `readonly`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"required","description":"Whether the control participates in the required form-state vocabulary. A slider always\nhas a numeric value, so this flag does not by itself make the control invalid.\n\nAttribute: `required`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"showValue","description":"Attribute: `show-value`","type":"boolean","default":"false"},{"name":"size","description":"Control size, on the library's shared ladder. Accepts both spellings of every tier —\n`2xs`/`xs`/`s`/`m`/`l`/`xl` and Web Awesome's `small`/`medium`/`large` — so migrating either way\nis a tag rename. Scales the track, the filled indicator, the tick marks and the handles off the\nsame `--lr-form-control-*` values `<lr-input>`/`<lr-select>`/`<lr-button>` use, so controls of\none `size` line up in a row. The handle's transparent drag area keeps its own 1.75rem/28px\nfloor at every tier, so a small slider is still a conformant pointer target.\n\nAttribute: `size`  \nReflected to its attribute.","type":"LyraSize","default":"'m'"},{"name":"step","description":"Step-grid interval; non-positive values select the unstepped mode.\n\nAttribute: `step`","type":"number","default":"1"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"tooltip","description":"Shoelace-compatible tooltip switch. `none` hides; top/bottom also set the placement. Lyra\ndefaults to `none`, unlike `<sl-range>`'s `top`; the migration codemod inserts `tooltip=\"top\"`,\nwhile a manual tag rename must set it explicitly to preserve Shoelace's default.\n\nAttribute: `tooltip`","type":"'top' | 'bottom' | 'none'","default":"'none'"},{"name":"tooltipDistance","description":"Gap between a handle and its tooltip, measured in CSS pixels.\n\nAttribute: `tooltip-distance`","type":"number","default":"8"},{"name":"tooltipFormatter","description":"Shoelace-compatible single-argument tooltip formatter.","type":"(value: number) => string | undefined"},{"name":"tooltipPlacement","description":"Physical side of the handle on which the tooltip is placed.\n\nAttribute: `tooltip-placement`  \nReflected to its attribute.","type":"SliderTooltipPlacement","default":"'top'"},{"name":"validationMessage","type":"string","read-only":true},{"name":"validity","type":"ValidityState","read-only":true},{"name":"value","description":"Live numeric value. String writes remain accepted as a source-compatible input path, but\nreads are always finite numbers; use `valueAsString` when a string round-trip is desired.\nAssignments in one reactive batch settle against its final min/max/step at updateComplete,\nso value-first Lit bindings retain fractions. Immediate reads use the current domain.","type":"number","default":"0"},{"name":"valueAsNumber","description":"Numeric compatibility alias for `value`.","type":"number","default":"0"},{"name":"valueAsString","description":"Explicit string compatibility accessor retained for integrations that serialize eagerly.","type":"string","default":"'0'"},{"name":"valueDisplay","description":"Visible readout text. `formatted` reuses valueFormatter (then tooltipFormatter when absent)\nfor each handle, with localized numeric fallback for nullish results. The numeric default\npreserves the existing showValue contract. Does not change ARIA, tooltip or event behavior.\n\nAttribute: `value-display`","type":"SliderValueDisplay","default":"'numeric'"},{"name":"valueFormatter","description":"Optional human-readable formatter for a handle's `aria-valuetext` (and\nits `with-tooltip` bubble). It receives the same finite, clamped number\nexposed through `aria-valuenow` plus the handle it belongs to; leaving\nit unset preserves the existing numeric `aria-valuetext`. Return\n`null`/`undefined` to omit the attribute.","type":"SliderValueFormatter | undefined"},{"name":"valuePlacement","description":"Position of the showValue readout. `label` places it at the inline end of a separate label\nrow without including its text in the control's accessible name.\n\nAttribute: `value-placement`","type":"SliderValuePlacement","default":"'inline'"},{"name":"willValidate","type":"boolean","read-only":true},{"name":"withHint","description":"SSR presence hint for hint chrome. Hydrated instances also inspect both hint slots.\n\nAttribute: `with-hint`","type":"boolean","default":"false"},{"name":"withLabel","description":"SSR presence hint for visible label chrome. Hydrated instances also inspect slot content.\n\nAttribute: `with-label`","type":"boolean","default":"false"},{"name":"withMarkers","description":"Whether to draw a tick mark at every `step` position along the track.\n\nAttribute: `with-markers`","type":"boolean","default":"false"},{"name":"withTooltip","description":"Whether to show a live value bubble beside each focused or dragged handle.\n\nAttribute: `with-tooltip`","type":"boolean","default":"false"}],"events":[{"name":"blur","description":"Native blur relayed once from the thumb losing focus.","type":"FocusEvent"},{"name":"change","description":"Native event fired when a handle interaction commits.","type":"Event"},{"name":"focus","description":"Native focus relayed once from the focused thumb.","type":"FocusEvent"},{"name":"input","description":"Native event fired continuously while a user moves a handle.","type":"InputEvent"},{"name":"lr-change","description":"Fired once an interaction commits: on pointerup for a drag, or on keyup or ordinary blur for a keyboard step — so a single Arrow/Home/End/ PageUp/PageDown press fires both `lr-input` and `lr-change`, mirroring how native `<input type=range>` fires `change` on every committed step too. `detail: { value, minValue, maxValue, handle }`. Disablement or readonly cancels an unfinished gesture without reverting its live value.","type":"CustomEvent<LyraSliderChangeDetail>"},{"name":"lr-input","description":"Fired continuously during an active drag or a keyboard step (including OS key-repeat while a key is held), mirroring native `<input type=range>`'s own `input` event. `detail: { value, minValue, maxValue, handle }`.","type":"CustomEvent<LyraSliderChangeDetail>"},{"name":"lr-invalid","description":"The slider failed a validity check. Cancelable: calling `preventDefault()` also cancels the native `invalid` event behind it, suppressing the browser's own validation bubble so an app can present the failure its own way.","type":"CustomEvent<null>"}]}},{"name":"lr-source-card","description":"`<lr-source-card>` — one citation/source entry, meant to be a direct\nlight-DOM child of `<lr-source-list>` (though it renders and functions\nfine standalone). Shows a title/page heading, an always-visible `excerpt`\nslot, and an optional `full` slot revealed behind its own independent\n\"Show more\" toggle — unrelated to the parent `<lr-source-list>`'s own\nexpand/collapse, which only ever hides/shows the *set* of cards, never a\nsingle card's own content.\n\n`source-id` is this card's stable identity, meant to match a\n`<lr-citation-badge>` (a sibling component) elsewhere on the page. This\ncomponent doesn't implement any scroll-to/highlight behavior itself — that\nlives at the app level, wiring a citation badge's activation event to this\ncard's `id`/`source-id`. Let the browser's default scroll behavior apply,\nor add application motion that respects reduced-motion preferences. See the\n`@example` below.\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| `excerpt` | A short preview. When left empty, the `excerpt` part collapses away entirely rather than leaving an empty gap in the card. |\n| `full` | The complete source text/chunk, hidden behind the \"Show more\"/\"Show less\" toggle. When left empty, no toggle renders at all — a card with no `full` content simply has no expand affordance. Removing all `full`-slotted content while expanded automatically collapses it back, and announces that collapse through `lr-expand` like any other state change. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The outer container. |\n| `excerpt` | The wrapper around the `excerpt` slot, `hidden` when the slot has no assigned content. |\n| `full` | The wrapper around the `full` slot, `hidden` while collapsed. |\n| `title` | The clickable title/page heading (`<button>`). |\n| `toggle` | The \"Show more\"/\"Show less\" button. Only rendered when the `full` slot has content. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-source-card-bg` (default: `var(--lr-color-surface)`) — Background of the RESTING `frame=\"card\"` chrome, the companion to the `compact` tier's existing padding/gap levers. `frame=\"plain\"` still drops the fill entirely.\n- `--lr-source-card-compact-padding` (default: `var(--lr-space-xs)`) — `[part=\"base\"]` padding while `compact`.\n- `--lr-source-card-compact-gap` (default: `var(--lr-space-2xs)`) — Gap between `[part=\"base\"]`'s rows while `compact`.","attributes":[{"name":"aria-current","description":"Current-item state forwarded reactively onto the `title` button: `page`, `step`, `location`, `date`, `time`, `true` or `false`.\n\nType: `string | null`  \nDefault: `null`"},{"name":"aria-pressed","description":"Toggle state forwarded reactively onto the `title` button: `true`, `false` or `mixed`. Anything else is ignored rather than passed through, so a typo never reaches the accessibility tree. The `toggle` button never receives it -- it already owns `aria-expanded` for its own disclosure state, and two conflicting state claims on one control is worse than one.\n\nType: `string | null`  \nDefault: `null`"},{"name":"compact","description":"Tighter root padding and row gap, for the dense citation lists these cards usually render in\n-- same convention as `lr-empty`'s `compact`. Defaults to `false`, i.e. the full card\npadding. Purely a density knob: the border and background stay, so use `frame=\"plain\"`\nto drop the chrome entirely.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"disabled","description":"Turns off this card's OWN controls: the `title` button and the \"Show more\"/\"Show less\"\n`toggle` both render `disabled`, so neither one can emit `lr-open` or `lr-expand` and neither\nremains in the tab order, and the card paints at `--lr-opacity-disabled` with a\n`not-allowed` cursor on both. The one `lr-expand` a disabled card can still emit is the\nautomatic collapse when the `full` slot empties while expanded -- that reports a state change\nthe card genuinely made, exactly as it does when enabled, and swallowing it would desync a\nhost tracking expansion off the event stream.\n\nEvery self-rendered sub-control is gated, not just the primary one: a card whose title is\ninert but whose disclosure toggle still expands reads as half-broken rather than disabled.\nSlotted `excerpt`/`full` content stays the consumer's own -- a card is a container, and\nsilently disabling somebody else's controls is not a state this component can honestly own.\n\nLike `<lr-icon-button>`, this component is not form-associated, so an ancestor\n`<fieldset disabled>` does not cascade here -- disable each card explicitly.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"frame","description":"Container treatment, in the shared `LyraFrame` vocabulary. `'card'` (the default) keeps the\nbordered, filled, padded box. `'plain'` removes the border, background, padding and corner\nradius, so a card inside a `<lr-source-list>` (or any container already drawing its own\nborder/dividers) doesn't double the frame. `plain` wins over `compact` when both are set\n(nothing left to tighten); the title and toggle keep their brand color and hover underline,\nwhich never depended on the card chrome.\n\nType: `LyraFrame`  \nDefault: `'card'`","value":{"type":["'card'","'plain'"]}},{"name":"href","description":"Optional URL, echoed back (unopened) in `lr-open`'s detail.\n\nType: `string | undefined`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"page","description":"Optional page reference, e.g. `12` or `\"iv\"` — rendered as-is (never\nparsed/validated as a number), so a non-numeric page label works too.\n\nType: `string | number | undefined`"},{"name":"source-id","description":"Stable identifier matching a `<lr-citation-badge>` elsewhere on the page.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"title","description":"The source's display title, e.g. a filename. Rendered only as the\ntitle button's own text -- a bare host-level `title` attribute (the\nbrowser's global tooltip attribute) is actively stripped once Lit has\nsynced it into this property, so the card never grows an unsolicited\nnative tooltip repeating the same text. See `StripHostTitleAttribute`\n(`internal/strip-host-title.ts`).\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"slots":[{"name":"excerpt","description":"A short preview. When left empty, the `excerpt` part collapses away entirely rather than leaving an empty gap in the card."},{"name":"full","description":"The complete source text/chunk, hidden behind the \"Show more\"/\"Show less\" toggle. When left empty, no toggle renders at all — a card with no `full` content simply has no expand affordance. Removing all `full`-slotted content while expanded automatically collapses it back, and announces that collapse through `lr-expand` like any other state change."}],"js":{"properties":[{"name":"compact","description":"Tighter root padding and row gap, for the dense citation lists these cards usually render in\n-- same convention as `lr-empty`'s `compact`. Defaults to `false`, i.e. the full card\npadding. Purely a density knob: the border and background stay, so use `frame=\"plain\"`\nto drop the chrome entirely.\n\nAttribute: `compact`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"disabled","description":"Turns off this card's OWN controls: the `title` button and the \"Show more\"/\"Show less\"\n`toggle` both render `disabled`, so neither one can emit `lr-open` or `lr-expand` and neither\nremains in the tab order, and the card paints at `--lr-opacity-disabled` with a\n`not-allowed` cursor on both. The one `lr-expand` a disabled card can still emit is the\nautomatic collapse when the `full` slot empties while expanded -- that reports a state change\nthe card genuinely made, exactly as it does when enabled, and swallowing it would desync a\nhost tracking expansion off the event stream.\n\nEvery self-rendered sub-control is gated, not just the primary one: a card whose title is\ninert but whose disclosure toggle still expands reads as half-broken rather than disabled.\nSlotted `excerpt`/`full` content stays the consumer's own -- a card is a container, and\nsilently disabling somebody else's controls is not a state this component can honestly own.\n\nLike `<lr-icon-button>`, this component is not form-associated, so an ancestor\n`<fieldset disabled>` does not cascade here -- disable each card explicitly.\n\nAttribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"frame","description":"Container treatment, in the shared `LyraFrame` vocabulary. `'card'` (the default) keeps the\nbordered, filled, padded box. `'plain'` removes the border, background, padding and corner\nradius, so a card inside a `<lr-source-list>` (or any container already drawing its own\nborder/dividers) doesn't double the frame. `plain` wins over `compact` when both are set\n(nothing left to tighten); the title and toggle keep their brand color and hover underline,\nwhich never depended on the card chrome.\n\nAttribute: `frame`  \nReflected to its attribute.","type":"LyraFrame","default":"'card'"},{"name":"href","description":"Optional URL, echoed back (unopened) in `lr-open`'s detail.\n\nAttribute: `href`","type":"string | undefined"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"page","description":"Optional page reference, e.g. `12` or `\"iv\"` — rendered as-is (never\nparsed/validated as a number), so a non-numeric page label works too.\n\nAttribute: `page`","type":"string | number | undefined"},{"name":"sourceId","description":"Stable identifier matching a `<lr-citation-badge>` elsewhere on the page.\n\nAttribute: `source-id`","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"title","description":"The source's display title, e.g. a filename. Rendered only as the\ntitle button's own text -- a bare host-level `title` attribute (the\nbrowser's global tooltip attribute) is actively stripped once Lit has\nsynced it into this property, so the card never grows an unsolicited\nnative tooltip repeating the same text. See `StripHostTitleAttribute`\n(`internal/strip-host-title.ts`).\n\nAttribute: `title`","type":"string","default":"''"}],"events":[{"name":"lr-expand","description":"The card's expanded state changed — either the per-card \"Show more\"/\"Show less\" toggle was activated, or all `full`-slotted content was removed while expanded, collapsing the card automatically. `detail: { sourceId, expanded }`.","type":"CustomEvent<SourceCardExpandDetail>"},{"name":"lr-open","description":"The title was activated. `detail: { sourceId, href }` — `href` may be `undefined`. This component never navigates on its own (staying a controlled component, the same convention `<lr-tool-call-chip>`'s `lr-tool-call-chip-select` follows); a listener decides what \"open\" means (open `href` in a new tab, open an in-app viewer, etc).","type":"CustomEvent<SourceCardOpenDetail>"}]}},{"name":"lr-source-list","description":"`<lr-source-list>` — a collapsible \"Sources\" panel for one chat message,\ngrouping a set of `<lr-source-card>` children (its default-slot light-DOM\nchildren, plain composition — no `.items` array prop, the same shape\n`<lr-multi-split>`'s panels take) behind a single clickable header.\n\nThis library has no built-in pluralization (see `<lr-empty>`'s plain\n`description` prop for a similar stance), so anything beyond the final\nfallback is entirely consumer-supplied: `label-plural` (e.g. `\"3 sources\"`)\nwins when set, falling back to `label`, falling back to a localized\n`\"Sources\"` (via `this.localize()`) — see each property's own doc.\n`sourceCount` (a read-only, live-updated count of the currently-slotted\nchildren) is exposed for a consumer who wants to build that string\nreactively instead of hand-counting DOM children.\n\nThe card list is removed from the accessibility tree (not just visually\nhidden) while collapsed, via the native `hidden` attribute on\n`[part=\"list\"]` — a screen reader user tabbing past the header never lands\non off-screen source cards they can't currently see.\nWhen every assigned child is a source card, a neutral `<div>`/`<span>`\nwrapper, or already `role=\"listitem\"`, `[part=\"list\"]` supplies list/listitem\nsemantics. Native controls and other semantic children retain their\nsemantics; their presence leaves the wrapper unroled rather than imposing\nan invalid list context.\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-source-card>` elements, neutral `<div>`/`<span>` wrappers, or author-owned list items. Other semantic children remain as authored and disable the list semantics. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The outer container. |\n| `header` | The clickable header (`<button>`) toggling `expanded`. |\n| `list` | The wrapper around the default slot, `hidden` while collapsed. |\n| `toggle` | The chevron indicator inside the header. |","attributes":[{"name":"expanded","description":"Whether the card list is currently shown. Starts collapsed by default\nso a message's sources don't eat vertical space until asked for.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"label","description":"Header text used when `label-plural` isn't set, e.g. `\"Sources\"`. Omitting it falls back to\na localized default; an explicit empty string uses that localized accessible fallback so the\ndisclosure button always has a name (still overridden by `label-plural` when that's set).\n\nType: `string | undefined`"},{"name":"label-plural","description":"Fully consumer-built, already-pluralized header summary, e.g. `\"3 sources\"`\nor `\"1 source\"` — this component never counts or pluralizes on its own\n(see the class doc). Takes precedence over `label` when both are set.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"slots":[{"name":"","description":"`<lr-source-card>` elements, neutral `<div>`/`<span>` wrappers, or author-owned list items. Other semantic children remain as authored and disable the list semantics."}],"js":{"properties":[{"name":"expanded","description":"Whether the card list is currently shown. Starts collapsed by default\nso a message's sources don't eat vertical space until asked for.\n\nAttribute: `expanded`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"label","description":"Header text used when `label-plural` isn't set, e.g. `\"Sources\"`. Omitting it falls back to\na localized default; an explicit empty string uses that localized accessible fallback so the\ndisclosure button always has a name (still overridden by `label-plural` when that's set).\n\nAttribute: `label`","type":"string | undefined"},{"name":"labelPlural","description":"Fully consumer-built, already-pluralized header summary, e.g. `\"3 sources\"`\nor `\"1 source\"` — this component never counts or pluralizes on its own\n(see the class doc). Takes precedence over `label` when both are set.\n\nAttribute: `label-plural`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"sourceCount","description":"Intentionally inert -- `sourceCount` is always derived live from the actual slotted\nchildren. A getter with no setter throws (in strict-mode module code, which every consumer\nruns) the moment anything assigns to it, including a stray `.sourceCount=${x}` template\nbinding; this no-op keeps that assignment harmless instead of throwing from inside\nframework internals.","type":"number"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-toggle","description":"The header was activated, expanding or collapsing the list. `detail: { expanded }`.","type":"CustomEvent<SourceListToggleDetail>"}]}},{"name":"lr-source-picker","description":"`<lr-source-picker>` — a checkbox tree/list scoping which sources ground the next answer:\ntri-state folders, select-all, type icons, search. **Not `FormAssociated`, deliberately**: this\nis a scoping panel, not a form control — the selection is immediate app state consumed by the\nnext retrieval call, exactly the stance `lr-tool-select-dialog` already takes.\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**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The root wrapper. |\n| `checkbox` | The tri-state checkbox glyph. |\n| `disclosure` | A folder row's pointer-only expand/collapse indicator. Keyboard expansion remains owned by the surrounding treeitem. |\n| `empty` | The empty state (`noData` when `sources` is empty, `noMatches` when a filter empties the tree). |\n| `error` | A localized error shown when a nonempty source payload contains no valid rows. |\n| `icon` | The `lr-file-icon` type badge. |\n| `item` | One `role=\"treeitem\"` row. Its selection state is exposed only through tri-state `aria-checked`; `aria-selected` is intentionally absent because it would duplicate that same state. |\n| `label` | The entry's label text. |\n| `limit` | Localized fail-closed status when a cyclic, duplicate, over-depth or over-budget input was truncated by the bounded source-tree normalizer. |\n| `search` | The built-in filter `lr-input`, only rendered when `searchable`. |\n| `select-all` | The header select-all row, only rendered when `showSelectAll`. |\n| `select-all-control` | The shared `lr-checkbox` that owns select-all semantics. |\n| `summary` | The \"{selected} of {total} selected\" text. |\n| `tree` | The `role=\"tree\"` container. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-source-picker-checked-bg` — Background of a fully-checked selection control: the `select-all` pill (defaults to `var(--lr-color-brand-quiet)`) and a fully-selected entry's `[part=\"checkbox\"]` (defaults to `var(--lr-color-brand)`). The two keep their distinct resting defaults; setting this prop unifies both.\n- `--lr-source-picker-checked-border` (default: `var(--lr-color-brand)`) — Border color of every checked or mixed selection control.\n- `--lr-source-picker-depth` (default: `0`) — Internal indent plumbing, not a retheming knob: the row's own nesting depth, written inline onto `[part=\"item\"]` as a plain number and multiplied by `--lr-source-picker-indent-size` to produce the indent.\n- `--lr-source-picker-indent-size` (default: `var(--lr-size-1-25rem)`) — Indent step added to `[part=\"item\"]`'s `padding-inline-start` per nesting level. The total indent is capped at `--lr-size-8rem` so a deeply nested tree cannot push its labels out of view.\n- `--lr-source-picker-mixed-bg` (default: `color-mix(in srgb, var(--lr-color-brand) 50%, var(--lr-color-surface))`) — Background of a partially-selected entry's `[part=\"checkbox\"]`.","attributes":[{"name":"aria-label","description":"JS-only accessible-name override for the tree. A markup `aria-label` names the component\nas a whole, so it is not cloned onto the inner tree.\n\nType: `string | null`  \nDefault: `null`"},{"name":"label","description":"Visible/fallback accessible label for the source tree. Omitting it falls back to a\nlocalized default; an explicit empty string clears it.\n\nType: `string | undefined`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"searchable","description":"Whether the built-in source filter is rendered. Toggling retains the query and selection,\nwhile keeping a visible tree entry available whenever rows remain.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"show-select-all","description":"Whether the header exposes one control for selecting or clearing every visible leaf source.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"size","description":"Density tier for the built-in filter field, on the library's one size ladder, in either\nspelling -- `2xs`/`xs`/`s`/`m`/`l`/`xl`, or Web Awesome's and Shoelace's\n`small`/`medium`/`large`. Forwarded to the composed `<lr-input>`, which is the only way to\nreach it: that control resolves its tier inside its own shadow root, so no custom property\nthis component could publish would get there. Forwarded as a property rather than an\nattribute, because removing an already-written `size` attribute again would leave the child's\nown `size` at `null` instead of back at its own default. Opt-in: with no size the field keeps\nits own `m` default, exactly what it rendered before. Unsupported values normalize to the\nomitted state and remove the attribute.\n\nType: `LyraSize | undefined`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}}],"js":{"properties":[{"name":"accessibleLabel","description":"JS-only accessible-name override for the tree. A markup `aria-label` names the component\nas a whole, so it is not cloned onto the inner tree.\n\nAttribute: `aria-label`","type":"string | null","default":"null"},{"name":"label","description":"Visible/fallback accessible label for the source tree. Omitting it falls back to a\nlocalized default; an explicit empty string clears it.\n\nAttribute: `label`","type":"string | undefined"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"searchable","description":"Whether the built-in source filter is rendered. Toggling retains the query and selection,\nwhile keeping a visible tree entry available whenever rows remain.\n\nAttribute: `searchable`","type":"boolean","default":"true"},{"name":"selectedSourceIds","description":"Leaf ids only. Duplicates and ids absent from `sources` are discarded. The picker updates\nits own copy on toggle *then* emits; reassign to control.","type":"readonly string[]","default":"[]"},{"name":"showSelectAll","description":"Whether the header exposes one control for selecting or clearing every visible leaf source.\n\nAttribute: `show-select-all`","type":"boolean","default":"true"},{"name":"size","description":"Density tier for the built-in filter field, on the library's one size ladder, in either\nspelling -- `2xs`/`xs`/`s`/`m`/`l`/`xl`, or Web Awesome's and Shoelace's\n`small`/`medium`/`large`. Forwarded to the composed `<lr-input>`, which is the only way to\nreach it: that control resolves its tier inside its own shadow root, so no custom property\nthis component could publish would get there. Forwarded as a property rather than an\nattribute, because removing an already-written `size` attribute again would leave the child's\nown `size` at `null` instead of back at its own default. Opt-in: with no size the field keeps\nits own `m` default, exactly what it rendered before. Unsupported values normalize to the\nomitted state and remove the attribute.\n\nAttribute: `size`  \nReflected to its attribute.","type":"LyraSize | undefined"},{"name":"sources","description":"Flat (no `children`) or a tree.","type":"readonly LyraSourceEntry[]","default":"[]"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-sources-change","description":"`detail: { selectedSourceIds }` — the complete updated leaf-id array, fired after every toggle including select-all.","type":"CustomEvent<\n    LyraEventDetailSnapshot<{ selectedSourceIds: string[] }>\n  >"}]}},{"name":"lr-span-waterfall","description":"`<lr-span-waterfall>` — the horizontal-timeline projection of the same\n`LyraSpan[]` `<lr-trace-tree>` consumes: a time axis, one row per span\nin start order, status-toned bars (Langfuse timeline / Temporal\nevent-history style).\n\nPublic collection properties take bounded readonly snapshots. `spans` keeps admitted item\nidentities only long enough for the shared descriptor-safe projection to copy its closed\ndisplay schema; later rendering never re-reads an admitted source row. Create a new collection\nand reassign it after changes; mutating the assigned array does not update the view.\n\nThe time axis always scales to the whole trace, including spans the 500-row ceiling drops, so a\ntruncated tail never stretches the surviving bars across the track.\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| `axis` | The time-ruler row, hidden when `hideAxis`. |\n| `bar` | The interactive, focusable status-toned bar (`role` via `<button>`), with the shared `--lr-icon-button-size` minimum target in both axes even when its duration would paint more narrowly. |\n| `bar-track` | The bar's positioning track. |\n| `base` | The root wrapper. |\n| `duration` | The formatted duration text. |\n| `empty` | The empty-state message shown when `spans` is empty. |\n| `limit` | Localized notice shown when the shared 500-span projection ceiling is reached. |\n| `live-region` | The internal focus/status-announcement live region. |\n| `meta` | Secondary row info (status/duration), shown inline under 480px. |\n| `name` | The span's name (the row's name gutter). |\n| `row` | One span's row. |\n| `status-text` | The visible status label. |\n| `tick` | One axis tick mark. |\n| `tick-label` | An axis tick's formatted duration label. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-span-waterfall-denied-color` (default: `var(--lr-color-warning)`) — Denied bar fill.\n- `--lr-span-waterfall-error-color` (default: `var(--lr-color-danger)`) — Error bar fill.\n- `--lr-span-waterfall-name-width` (default: `8rem`) — Width of the name gutter column.\n- `--lr-span-waterfall-pending-border-color` (default: `var(--lr-color-border-strong)`) — Pending bar border.\n- `--lr-span-waterfall-row-active-bg` (default: `var(--lr-color-brand-quiet)`) — Background of the active (`activeSpanId`) row. Shadow Parts forbids an attribute selector after `::part()`, so the active row could otherwise only be restyled by hijacking the library-wide `--lr-color-brand-quiet` token.\n- `--lr-span-waterfall-running-color` (default: `var(--lr-color-brand)`) — Running stripe foreground.\n- `--lr-span-waterfall-running-stripe-color` (default: `var(--lr-color-brand-quiet)`) — Running stripe background.\n- `--lr-span-waterfall-stripe-speed` (default: `var(--lr-duration-ambient)`) — Animation duration for a `running` span's striped bar. The fallback is the bare-duration `--lr-duration-ambient`, not the `--lr-transition-ambient` duration+easing shorthand, which would be invalid in an `animation-duration` slot.\n- `--lr-span-waterfall-success-color` (default: `var(--lr-color-success)`) — Success bar fill.","attributes":[{"name":"active-span-id","description":"Type: `string | null`  \nDefault: `null`"},{"name":"hide-axis","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"label","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"view-end-ms","description":"Type: `number | null`  \nDefault: `null`"},{"name":"view-start-ms","description":"Visible time window in trace-relative ms (same non-negative, trace-relative vocabulary as\n`LyraSpan.startMs`/`endMs` -- never a wall-clock timestamp). Both `null` (the default) fits\nthe whole trace; a non-null NaN (e.g. an unparsable attribute) is normalized the same way as\n`null` by `viewWindow()` rather than poisoning the axis/bar math with NaN.\n\nType: `number | null`  \nDefault: `null`"}],"js":{"properties":[{"name":"activeSpanId","description":"Attribute: `active-span-id`","type":"string | null","default":"null"},{"name":"hideAxis","description":"Attribute: `hide-axis`","type":"boolean","default":"false"},{"name":"label","description":"Attribute: `label`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"spans","description":"Identical contract to `<lr-trace-tree>.spans`; rows sort by `startMs` (ties keep array order).\nThe controlled `activeSpanId` reserves a position inside the shared 500-row ceiling. Foreign\nruntime `kind`/`status` values normalize to `'other'`/`'pending'` before rendering.","type":"readonly LyraSpan[]","default":"[]"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"viewEndMs","description":"Attribute: `view-end-ms`","type":"number | null","default":"null"},{"name":"viewStartMs","description":"Visible time window in trace-relative ms (same non-negative, trace-relative vocabulary as\n`LyraSpan.startMs`/`endMs` -- never a wall-clock timestamp). Both `null` (the default) fits\nthe whole trace; a non-null NaN (e.g. an unparsable attribute) is normalized the same way as\n`null` by `viewWindow()` rather than poisoning the axis/bar math with NaN.\n\nAttribute: `view-start-ms`","type":"number | null","default":"null"}],"events":[{"name":"lr-span-select","description":"`detail: { spanId }` — a bar/row was activated (click, Enter, Space).","type":"CustomEvent<{ spanId: string }>"}]}},{"name":"lr-sparkline","description":"`<lr-sparkline>` — a zero-dependency inline SVG trend chart.\nMirrors the Web Awesome `<wa-sparkline>` API under the `lr-` prefix and retains the earlier\n`values`/`mark`/`min`/`max` Lyra surface as an additive programmatic extension.\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 part `base`: Deprecated since `8.0.0`. Use part `::part(sparkline)`. Removal is not permitted before `10.0.0`. The sparkline part names the rendered SVG wrapper unambiguously; base remains on that same node during the compatibility window. That version is a policy floor, not a plan: `wa-sparkline` still publishes its own deprecated `base` part, so this alias is removed only when upstream's is.\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `area` | Compatibility alias for `fill` on the same path. |\n| `bar` | Each rectangle rendered by the additive `mark=\"bar\"` mode. |\n| `base` | Deprecated alias for `sparkline` on the same SVG wrapper. |\n| `fill` | The filled area rendered by `appearance=\"solid\"` and `appearance=\"gradient\"`. |\n| `line` | The stroked trend path. |\n| `sparkline` | The outer SVG wrapper. |\n\n---\n\n**CSS Custom Properties**\n\n- `--fill-color` (default: `var(--lr-color-brand-quiet)`) — Area fill color. A `trend` supplies a semantic token default, while an authored value always wins.\n- `--line-color` (default: `var(--lr-color-brand)`) — Trend line color. A `trend` supplies a semantic token default, while an authored value always wins.\n- `--line-width` (default: `var(--lr-border-width-medium)`) — Trend line width.\n- `--lr-sparkline-stroke-width` (default: `var(--lr-border-width-medium)`) — Compatibility alias used as the fallback for `--line-width`.","attributes":[{"name":"appearance","description":"Fill treatment under the trend line.\n\nType: `LyraSparklineAppearance`  \nDefault: `'solid'`","value":{"type":["'gradient'","'line'","'solid'"]}},{"name":"aria-label","description":"Compatibility accessible-name property. An authored host `aria-label` wins; otherwise a\nnonempty `label` precedes a nonempty programmatic value here.\n\nType: `string | null`  \nDefault: `null`"},{"name":"curve","description":"Interpolation used to connect adjacent samples.\n\nType: `LyraSparklineCurve`  \nDefault: `'linear'`","value":{"type":["'linear'","'natural'","'step'"]}},{"name":"data","description":"Space-separated finite numeric samples. At least two are required. An empty or removed\ndata attribute uses values instead; removal retains null property readback.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"label","description":"Accessible label applied verbatim to the SVG.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"mark","description":"Geometry used to plot samples. Foreign tokens normalize to `line`.\n\nType: `LyraSparklineMark`","value":{"type":["'line'","'bar'"]}},{"name":"max","description":"Upper bound of the value scale (defaults to the data maximum).\n\nType: `number | undefined`"},{"name":"min","description":"Lower bound of the value scale (defaults to the data minimum).\n\nType: `number | undefined`"},{"name":"trend","description":"Semantic default color; public color custom properties take precedence.\n\nType: `LyraSparklineTrend | undefined`","value":{"type":["'positive'","'negative'","'neutral'"]}}],"js":{"properties":[{"name":"accessibleLabel","description":"Compatibility accessible-name property. An authored host `aria-label` wins; otherwise a\nnonempty `label` precedes a nonempty programmatic value here.\n\nAttribute: `aria-label`","type":"string | null","default":"null"},{"name":"appearance","description":"Fill treatment under the trend line.\n\nAttribute: `appearance`  \nReflected to its attribute.","type":"LyraSparklineAppearance","default":"'solid'"},{"name":"curve","description":"Interpolation used to connect adjacent samples.\n\nAttribute: `curve`  \nReflected to its attribute.","type":"LyraSparklineCurve","default":"'linear'"},{"name":"data","description":"Space-separated finite numeric samples. At least two are required. An empty or removed\ndata attribute uses values instead; removal retains null property readback.\n\nAttribute: `data`","type":"string","default":"''"},{"name":"label","description":"Accessible label applied verbatim to the SVG.\n\nAttribute: `label`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"mark","description":"Geometry used to plot samples. Foreign tokens normalize to `line`.\n\nAttribute: `mark`  \nReflected to its attribute.","type":"LyraSparklineMark"},{"name":"max","description":"Upper bound of the value scale (defaults to the data maximum).\n\nAttribute: `max`","type":"number | undefined"},{"name":"min","description":"Lower bound of the value scale (defaults to the data minimum).\n\nAttribute: `min`","type":"number | undefined"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"trend","description":"Semantic default color; public color custom properties take precedence.\n\nAttribute: `trend`  \nReflected to its attribute.","type":"LyraSparklineTrend | undefined"},{"name":"values","description":"Additive programmatic data source used when `data` is empty. Property-only.","type":"readonly number[]","default":"[]"}]}},{"name":"lr-spinner","description":"`<lr-spinner>` — an indeterminate busy indicator. It uses non-live `progressbar` semantics so\nmounting ordinary loading UI does not announce a false status update.\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) | Optional label. `label-placement=\"after\"` renders it and uses its live, visible accessible text as the progressbar name, including through forwarding slots; `none` hides it from both rendering and the accessibility tree. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | Compatibility name for the outer wrapper; use `spinner`. |\n| `label` | The accessible/visible label wrapper. |\n| `spinner` | The outer wrapper. It is the same node as `base`. |\n| `spinner-indicator` | The animated indicator inside the wrapper. |\n\n---\n\n**CSS Custom Properties**\n\n- `--indicator-color` (default: `var(--lr-color-brand)`) — Upstream-compatible indicator color.\n- `--lr-spinner-duration` (default: `var(--lr-transition-ambient)`) — Duration/easing of one rotation. Not read under `prefers-reduced-motion: reduce`, where the animation is disabled entirely.\n- `--lr-spinner-size` (default: `var(--lr-size-1-25rem)`) — Outer diameter of the indicator.\n- `--lr-spinner-track-width` (default: `var(--lr-border-width-medium)`) — Thickness of the ring track.\n- `--speed` (default: `var(--lr-spinner-duration)`) — Upstream-compatible rotation duration.\n- `--track-color` (default: `var(--lr-color-brand-quiet)`) — Upstream-compatible track color.\n- `--track-width` (default: `var(--lr-spinner-track-width)`) — Upstream-compatible track width.","attributes":[{"name":"aria-label","description":"Accessible name for the busy progress indicator, forwarded from a host `aria-label`. When unset, a\nvisible `label-placement=\"after\"` label names it, then the localized \"Loading…\" fallback.\n\nType: `string | null`  \nDefault: `null`"},{"name":"label-placement","description":"Type: `LyraSpinnerLabelPlacement`  \nDefault: `'none'`","value":{"type":["'none'","'after'"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"slots":[{"name":"","description":"Optional label. `label-placement=\"after\"` renders it and uses its live, visible accessible text as the progressbar name, including through forwarding slots; `none` hides it from both rendering and the accessibility tree."}],"js":{"properties":[{"name":"accessibleLabel","description":"Accessible name for the busy progress indicator, forwarded from a host `aria-label`. When unset, a\nvisible `label-placement=\"after\"` label names it, then the localized \"Loading…\" fallback.\n\nAttribute: `aria-label`","type":"string | null","default":"null"},{"name":"labelPlacement","description":"Attribute: `label-placement`  \nReflected to its attribute.","type":"LyraSpinnerLabelPlacement","default":"'none'"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}]}},{"name":"lr-split-panel","description":"`<lr-split-panel>` — an accessible, draggable two-pane layout.\n\n`position` and `positionInPixels` are measured from the selected `primary`\npanel's edge. Without a primary panel, `start` is the reference and its\npercentage is preserved when the component resizes. Selecting `start` or\n`end` instead preserves that panel's pixel size.\n\n---\n\n**Component metadata**\n\n- Status: `stable`\n- Since: `8.0.0`\n- Rationale: This tag entered Lyra as a stable public API with documented behavior, accessibility, and cross-browser support.\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| `divider` | Optional decorative content rendered inside the draggable divider. Assigned content is inert, so the separator remains the sole resize control. |\n| `end` | Content in the logical end pane. |\n| `start` | Content in the logical start pane. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The component's layout wrapper. |\n| `divider` | The draggable separator. Its numeric ARIA range remains percentages while `aria-valuetext` reports the measured current percentage through the effective locale. |\n| `end` | The logical end pane. |\n| `panel` | Shared part on both pane wrappers. |\n| `split-panel` | Compatibility alias on the layout wrapper. |\n| `start` | The logical start pane. |\n\n---\n\n**CSS Custom Properties**\n\n- `--divider-hit-area` (default: `12px`) — Requested divider hit area; Lyra's minimum hit-area token remains the floor.\n- `--divider-width` (default: `4px`) — Visible divider thickness.\n- `--lr-split-panel-divider-active-color` (default: `var(--lr-color-border-strong)`) — Background of `divider` while being dragged (or focused and pressed via the keyboard).\n- `--lr-split-panel-divider-hit-area` (default: `var(--divider-hit-area)`) — Lyra-prefixed hit-area alias.\n- `--lr-split-panel-divider-hover-color` (default: `var(--lr-color-brand)`) — Background of `divider` on hover/keyboard focus, independent of any other component's own hover token that happens to default to the same shared brand color.\n- `--lr-split-panel-divider-width` (default: `var(--divider-width)`) — Lyra-prefixed divider-width alias.\n- `--lr-split-panel-max` (default: `var(--max)`) — Lyra-prefixed maximum-size alias.\n- `--lr-split-panel-min` (default: `var(--min)`) — Lyra-prefixed minimum-size alias.\n- `--max` (default: `100%`) — Maximum size of the primary pane, or the start pane when `primary` is unset.\n- `--min` (default: `0`) — Minimum size of the primary pane, or the start pane when `primary` is unset.","attributes":[{"name":"disabled","description":"Prevents pointer and keyboard repositioning.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"orientation","description":"Layout axis. Horizontal places panes at logical start and end.\n\nType: `LyraSplitPanelOrientation`  \nDefault: `'horizontal'`","value":{"type":["'horizontal'","'vertical'"]}},{"name":"position","description":"Divider position as a percentage from the primary panel's edge.\n\nType: `number`  \nDefault: `50`","value":{"type":["number"]}},{"name":"position-in-pixels","description":"Divider position in pixels from the primary panel's edge.\n\nType: `number`","value":{"type":["number"]}},{"name":"primary","description":"Pane whose pixel size remains fixed while the host resizes.\n\nType: `LyraSplitPanelPrimary | undefined`","value":{"type":["'start'","'end'"]}},{"name":"snap","description":"Space-separated pixel/percent snap points, `repeat(...)`, or a snap callback. String\npreprocessing reads at most 16,384 UTF-16 code units and retains at most 256 finite valid\ntokens, caching their numeric value/unit projection until the source changes. Assigning the Web Awesome `undefined`\nspelling restores the inert empty-string read default.\n\nType: `string | LyraSplitPanelSnapFunction | undefined`  \nDefault: `''`"},{"name":"snap-threshold","description":"Maximum distance in pixels at which string snap points take effect.\n\nType: `number`  \nDefault: `12`","value":{"type":["number"]}},{"name":"vertical","description":"Boolean compatibility alias for `orientation=\"vertical\"`.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"divider","description":"Optional decorative content rendered inside the draggable divider. Assigned content is inert, so the separator remains the sole resize control."},{"name":"end","description":"Content in the logical end pane."},{"name":"start","description":"Content in the logical start pane."}],"js":{"properties":[{"name":"disabled","description":"Prevents pointer and keyboard repositioning.\n\nAttribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"orientation","description":"Layout axis. Horizontal places panes at logical start and end.\n\nAttribute: `orientation`  \nReflected to its attribute.","type":"LyraSplitPanelOrientation","default":"'horizontal'"},{"name":"position","description":"Divider position as a percentage from the primary panel's edge.\n\nAttribute: `position`  \nReflected to its attribute.","type":"number","default":"50"},{"name":"positionInPixels","description":"Divider position in pixels from the primary panel's edge.\n\nAttribute: `position-in-pixels`","type":"number"},{"name":"primary","description":"Pane whose pixel size remains fixed while the host resizes.\n\nAttribute: `primary`  \nReflected to its attribute.","type":"LyraSplitPanelPrimary | undefined"},{"name":"snap","description":"Space-separated pixel/percent snap points, `repeat(...)`, or a snap callback. String\npreprocessing reads at most 16,384 UTF-16 code units and retains at most 256 finite valid\ntokens, caching their numeric value/unit projection until the source changes. Assigning the Web Awesome `undefined`\nspelling restores the inert empty-string read default.\n\nAttribute: `snap`  \nReflected to its attribute.","type":"string | LyraSplitPanelSnapFunction | undefined","default":"''"},{"name":"snapThreshold","description":"Maximum distance in pixels at which string snap points take effect.\n\nAttribute: `snap-threshold`","type":"number","default":"12"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"vertical","description":"Boolean compatibility alias for `orientation=\"vertical\"`.\n\nAttribute: `vertical`  \nReflected to its attribute.","type":"boolean","default":"false"}],"events":[{"name":"lr-reposition","description":"Non-cancelable post-commit notification after a pointer or keyboard interaction moves the divider. Not fired when a consumer sets `position` or `positionInPixels` directly.","type":"CustomEvent<null>"},{"name":"lr-reposition-request","description":"A cancelable proposed divider position from a pointer drag or keyboard interaction. Both detail values measure from the selected primary edge and match accepted public readback. Call `preventDefault()` to keep `position` unchanged. Not fired when a consumer sets `position` or `positionInPixels` directly. `detail: LyraSplitPanelRepositionDetail`.","type":"CustomEvent<LyraSplitPanelRepositionDetail>"}]}},{"name":"lr-spreadsheet-viewer","description":"Fetches and renders `.xlsx` and legacy `.xls` workbooks with virtualized rows and sheet tabs.\n\nAdopts `DocumentAnchorTarget`: a `cell-range` anchor addresses one sheet's raw grid, 1-based, with\nits (always-present) header row included -- matching how a spreadsheet app itself labels `A1`.\nThe target sheet resolves from the anchor's own `sheet` field (falling back to a `Sheet!`-prefixed\n`range`, then the currently active sheet when neither is set); `scrollToAnchor()` switches\n`<lr-tab-group>`'s `active` tab first when the resolved sheet isn't already active, then scrolls the\naddressed row into view via the virtualized list's `active-item-id`, then scrolls the first addressed\ncolumn horizontally into view. `highlights` paint a structural `part=\"cell-highlight\"` cell\nwrapping a focusable native `part=\"cell-highlight-action\"` button, recomputed per row inside\n`renderRow()` so a row scrolled out and back in reconstructs its highlight for free, with no\npersistent DOM to keep in sync. `search()` is a case-insensitive\nsubstring match over every sheet's stringified cell values (the same stringification `cell()`\nalready renders), ordered sheet then row then column, switching tabs as navigation crosses sheets.\nEach sheet is independently limited to 10,000 rows and 1,000 columns; a workbook additionally\nretains at most 256 sheets and 1,000,000 aggregate expanded cells. Internal tab and virtual-list\nlifecycle events stay contained inside the viewer.\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| `anchor-live-region` | The aria-hidden, non-live shadow mirror of the latest anchor-jump message. |\n| `base` | The root wrapper. |\n| `body` | The scrollable wrapper around the fetched-state content, capped by `max-height`. |\n| `cell` | One rendered cell. |\n| `cell-highlight` | A structural cell covered by a `highlights` entry. |\n| `cell-highlight-action` | The native button filling a highlighted cell -- focusable, emits `lr-highlight-activate` on click or Enter/Space. Its accessible name localizes the complete cell-value and annotation message through separate `{value}` and `{label}` placeholders. |\n| `data-row` | One virtualized data row. |\n| `error` | The error message region. |\n| `header-row` | A sheet's header row. |\n| `rows` | The virtualized row list. |\n| `sheet` | The wrapper around one sheet's header row and virtualized body. |\n| `spinner` | Visible ordinary loading content with a motion-safe progress indicator. |\n| `tabs` | The sheet-switching `<lr-tab-group>`, rendered only for a multi-sheet workbook; its `lr-tab-show`/`lr-tab-hide` lifecycle events do not escape this viewer. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-spreadsheet-viewer-highlight-color` (default: `var(--lr-color-brand)`) — Outline color of a highlighted cell. The active highlight changes a private warning-color default; an inherited or direct public value remains authoritative.\n- `--lr-spreadsheet-viewer-highlight-outline-offset` (default: `calc(-1 * var(--lr-border-width-medium))`) — Outline offset of a highlighted cell.\n- `--lr-spreadsheet-viewer-max-height` (default: `none`) — Maximum block size of `[part=\"body\"]` before it scrolls internally. The `maxHeight` property sets this token inline on `[part=\"base\"]`.","attributes":[{"name":"active-highlight-id","description":"Id of the currently active highlight, or null when none is active.\n\nType: `string | null`  \nDefault: `null`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max-height","description":"A CSS `max-height`; invalid values are ignored.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"name","description":"Source filename or display name, used as the viewer's accessible name.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"src","description":"URL to fetch and parse.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"js":{"properties":[{"name":"activeHighlightId","description":"Id of the currently active highlight, or null when none is active.\n\nAttribute: `active-highlight-id`","type":"string | null","default":"null"},{"name":"anchor","description":"Anchor or highlight id to resolve and scroll into view.","type":"LyraAnchor | string | null","default":"null"},{"name":"anchorKinds","description":"Anchor kinds this viewer resolves via `scrollToAnchor()`.","type":"readonly LyraAnchorKind[]","default":"['cell-range']","read-only":true},{"name":"highlights","description":"Highlights rendered by the document target. Reassign after mutation.","type":"LyraHighlight[]","default":"[]"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"maxHeight","description":"A CSS `max-height`; invalid values are ignored.\n\nAttribute: `max-height`","type":"string","default":"''"},{"name":"name","description":"Source filename or display name, used as the viewer's accessible name.\n\nAttribute: `name`","type":"string","default":"''"},{"name":"src","description":"URL to fetch and parse.\n\nAttribute: `src`","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-anchor-result","description":"Fired after an `anchor` property assignment or a `scrollToAnchor()` call is applied. `detail: { found }`.","type":"CustomEvent<AnchorResultDetail>"},{"name":"lr-highlight-activate","description":"A `highlights` cell was clicked, or activated via Enter/Space while focused. `detail: { highlightId }`.","type":"CustomEvent<HighlightActivateDetail>"},{"name":"lr-render-error","description":"Fired when fetching or parsing fails.","type":"CustomEvent<{ error: unknown }>"},{"name":"lr-search-change","description":"Fired whenever the search query, match count, or active match index changes, including source-reset and effective-locale re-evaluation. `detail: { query, matchCount, matchCountExact, activeIndex }`. Search accepts at most 4,096 query code units, scans at most 4,000,000 cell code units, and retains at most 1,000 matches; `matchCountExact=false` identifies a ceiling-truncated lower bound.","type":"CustomEvent<LyraSearchChangeDetail>"}]}},{"name":"lr-stack-trace","description":"`<lr-stack-trace>` — parses common V8/JS-TS, Firefox/Safari, and Python stack traces into a\nleading message plus activatable frames, splitting chained/caused-by errors into separate\ngroups. Frames matching `internalPatterns` (`node_modules/`, `node:internal`,\n`site-packages/`, ... by default) fold behind a count-labeled toggle. Falls back to verbatim\nraw text when nothing parses. A malformed or unsafe numeric location remains visible as raw,\nnon-activatable trace text rather than becoming an invalid navigation target. Parsing and raw\nrendering are bounded by the exported `STACK_TRACE_LIMITS`; `[part=\"limit\"]` makes any omitted\ninput explicit. First-party invention (no Web Awesome equivalent).\n`internalPatterns` is a clone-owned, bounded readonly snapshot; create and reassign a new array\nafter changing the matcher sequence.\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 root wrapper; respects `max-height`. Tightens its padding under `compact` and drops its card chrome under `frame=\"plain\"`. |\n| `copy-button` | The copy-to-clipboard button, only rendered while `copyable`. |\n| `frame` | A selectable frame button (carrying `data-internal` for internal frames), or a non-activatable raw row when the source location is malformed or unsafe. |\n| `frame-function` | The frame's function name. |\n| `frame-location` | The frame's `file:line:col` text. |\n| `group` | One chained-error group of frames. |\n| `internal-toggle` | The collapse/expand toggle for a run of internal frames. |\n| `limit` | Localized notice rendered when a parser resource ceiling omitted input. |\n| `message` | The leading error message text for a group. |\n| `raw` | The verbatim `<pre>` fallback when zero structured frames parsed. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-stack-trace-background` (default: `var(--lr-color-surface)`) — Fill of the outer card (`[part=\"base\"]`) while `frame=\"card\"`. `frame=\"plain\"` still removes the fill entirely.\n- `--lr-stack-trace-border-color` (default: `var(--lr-color-border)`) — Colour of the outer card's border.\n- `--lr-stack-trace-compact-gap` (default: `var(--lr-space-2xs)`) — Space below `[part=\"message\"]` and between `[part=\"group\"]`s while `compact`.\n- `--lr-stack-trace-compact-padding` (default: `var(--lr-space-2xs)`) — `[part=\"base\"]` padding while `compact`. Overridden entirely by `frame=\"plain\"`.\n- `--lr-stack-trace-font` (default: `var(--lr-font-mono)`) — Font family for the parsed frames and the verbatim raw fallback.\n- `--lr-stack-trace-interactive-color` (default: `var(--lr-color-brand)`) — Interactive frame/toggle accent.\n- `--lr-stack-trace-internal-frame-color` (default: `var(--lr-color-text-quiet)`) — Internal frame foreground.\n- `--lr-stack-trace-max-height` (default: `none`) — Cap on how tall `[part=\"base\"]` grows before it scrolls internally. `none` lets the component grow with its content; the `max-height` attribute sets this token.\n- `--lr-stack-trace-radius` (default: `var(--lr-radius)`) — Corner radius of the outer card. `frame=\"plain\"` still squares the corners.","attributes":[{"name":"collapse-internal","description":"Folds runs of internal frames (matching `internalPatterns`) behind a toggle.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"compact","description":"Tighter root padding and between-group spacing for dense contexts (a trace rendered as a row\nin an error list, a side panel) -- same convention as `<lr-agent-run>`'s and\n`<lr-thinking-panel>`'s `compact`, and the counterpart `frame` already had. Defaults to\n`false`, i.e. the full card padding. Purely a density knob: the border, corner radius and\nbackground stay, so use `frame=\"plain\"` to drop the chrome entirely.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"copyable","description":"Shows a copy-to-clipboard button for the raw trace text.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"frame","description":"Visual chrome, in the library's shared container-frame vocabulary. `'card'` (the default)\nkeeps the bordered, filled, padded box. `'plain'` removes the border, background, padding and\ncorner radius so a trace nested inside an `lr-result-card`/`lr-agent-run` (which already draws\na border) doesn't double the box. `plain` wins over `compact` when both are set (nothing left\nto tighten). The `max-height` scroll cap and the copy/stack-frame affordances are unaffected.\n\nType: `LyraFrame`  \nDefault: `'card'`","value":{"type":["'card'","'plain'"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max-height","description":"Caps the rendered block size and enables an internal scrollbar once content exceeds it\n(any valid CSS length, e.g. `'20rem'`). Empty string (the default) grows with content.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"trace","description":"The raw stack trace text to parse and render. Removing the attribute clears its displayed text.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"js":{"properties":[{"name":"collapseInternal","description":"Folds runs of internal frames (matching `internalPatterns`) behind a toggle.\n\nAttribute: `collapse-internal`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"compact","description":"Tighter root padding and between-group spacing for dense contexts (a trace rendered as a row\nin an error list, a side panel) -- same convention as `<lr-agent-run>`'s and\n`<lr-thinking-panel>`'s `compact`, and the counterpart `frame` already had. Defaults to\n`false`, i.e. the full card padding. Purely a density knob: the border, corner radius and\nbackground stay, so use `frame=\"plain\"` to drop the chrome entirely.\n\nAttribute: `compact`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"copyable","description":"Shows a copy-to-clipboard button for the raw trace text.\n\nAttribute: `copyable`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"frame","description":"Visual chrome, in the library's shared container-frame vocabulary. `'card'` (the default)\nkeeps the bordered, filled, padded box. `'plain'` removes the border, background, padding and\ncorner radius so a trace nested inside an `lr-result-card`/`lr-agent-run` (which already draws\na border) doesn't double the box. `plain` wins over `compact` when both are set (nothing left\nto tighten). The `max-height` scroll cap and the copy/stack-frame affordances are unaffected.\n\nAttribute: `frame`  \nReflected to its attribute.","type":"LyraFrame","default":"'card'"},{"name":"internalPatterns","type":"readonly (string | RegExp)[]"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"maxHeight","description":"Caps the rendered block size and enables an internal scrollbar once content exceeds it\n(any valid CSS length, e.g. `'20rem'`). Empty string (the default) grows with content.\n\nAttribute: `max-height`","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"trace","description":"The raw stack trace text to parse and render. Removing the attribute clears its displayed text.\n\nAttribute: `trace`","type":"string","default":"''"}],"events":[{"name":"lr-copy","description":"`detail: { ok: true, text }` — the raw-trace clipboard write completed.","type":"CustomEvent<LyraClipboardWriteSuccess>"},{"name":"lr-copy-error","description":"`detail: { ok: false, text, reason, error }` — typed clipboard failure.","type":"CustomEvent<LyraClipboardWriteFailure>"},{"name":"lr-error","description":"The clipboard write failed; generic no-detail notification.","type":"CustomEvent<null>"},{"name":"lr-frame-select","description":"`detail: { file, line, column?, raw }` — a frame with a safe parsed location was activated (`column` is always undefined for Python frames, which carry no column information). Malformed or unsafe locations render as raw text and never emit this event.","type":"CustomEvent<{ file: string; line: number; column?: number; raw: string }>"}]}},{"name":"lr-stat","description":"`<lr-stat>` — a KPI/stat card. First-party invention consolidating the\n\"metric row\" / \"KPI card\" pattern common to dashboard UIs.\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) | Legacy leading-icon alias, retained as the fallback for `start`. |\n| `caption` | Rich caption content (overrides the `caption` attribute). |\n| `spark` | A sparkline (e.g. `<lr-sparkline>`) or other compact trend visual. `lr-stat` only reserves the slot; it doesn't render one itself. |\n| `start` | Leading icon. Takes precedence over the legacy default slot when both are filled. |\n| `sub` | Rich sub-line content (overrides the `sub` attribute). When linked, every consumer slot remains a sibling of the stretched anchor so an interactive slotted descendant is never nested inside the whole-card link. Passive slotted content forwards pointer modifiers; the platform primary modifier and Shift preserve new-context activation. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The component's root wrapper (`<div>`, or a stretched real `<a>` when `href` is safe). |\n| `caption` | Container for the caption attribute/slot. |\n| `icon` | Container for the leading icon slot. |\n| `label` | The label text. Hidden (and collapsed) whenever `label` is empty, so a label-less stat doesn't leave a blank line above the value. |\n| `row` | A single breakdown row (one per `rows` entry). |\n| `row-label` | The label text of a breakdown row. |\n| `row-value` | The value text of a breakdown row. Shows the row's `exactValue` (if any) as a hover/focus tooltip, same as the headline `value`, and is accessibly labelled by its `row-label` (via `aria-labelledby`) the same way the headline `value` is. |\n| `rows` | Container for the `rows` breakdown list. |\n| `spark` | Container for the `spark` slot. |\n| `sub` | Container for the `sub` attribute/slot. |\n| `trend` | The trend pill. |\n| `unit` | The unit text. |\n| `value` | The value text. Accessibly labelled by the `label` part (via `aria-labelledby`) whenever `label` is set, so tabbing directly to this (focusable when `exactValue` is set) control still announces which metric and visible unit it is. |\n| `value-row` | Wrapper around the value and unit. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-stat-bg` (default: `var(--lr-color-surface)`) — Resting background of the card. The pressed fill of a linked card mixes from this value too, so one override retints both. `frame=\"plain\"` still paints transparent.\n- `--lr-stat-emphasis-border-color` (default: `var(--lr-color-brand)`) — Accent-edge color when `emphasis` is set. Independent of the headline's emphasis tint and `brand` variant.\n- `--lr-stat-emphasis-value-color` (default: `var(--lr-color-brand)`) — Headline value color when `emphasis` is set on a neutral stat. Independent of the accent edge and `brand` variant.\n- `--lr-stat-gap` (default: `var(--lr-space-xs)`) — Gap between the card's stacked parts, read by both `[part=\"base\"]` and the linked-card content wrapper. The `compact` variant reads the same property with its own current default (`var(--lr-size-0-125rem)`) as its fallback.\n- `--lr-stat-link-active-bg` (default: `color-mix(...)`) — Linked-card background while pressed.\n- `--lr-stat-link-active-border-color` (default: `var(--lr-stat-link-hover-border-color,var(--lr-color-brand))`) — Linked-card border while pressed.\n- `--lr-stat-link-active-shadow` (default: `var(--lr-stat-link-hover-shadow,var(--lr-shadow-s))`) — Linked-card shadow while pressed.\n- `--lr-stat-link-hover-border-color` (default: `var(--lr-color-brand)`) — Linked-card border on hover.\n- `--lr-stat-link-hover-shadow` (default: `var(--lr-shadow-s)`) — Linked-card shadow on hover.\n- `--lr-stat-padding` (default: `var(--lr-space-m)`) — Padding of the card, read by both `[part=\"base\"]` and the linked-card content wrapper so a linked and unlinked stat never drift. The `compact` and `frame=\"plain\"` variants read the same property with their own current default as its fallback (`var(--lr-space-s)` and `0` respectively), so one override reaches every rendering path.\n- `--lr-stat-trend-bad-bg` (default: `color-mix(in srgb, var(--lr-color-danger) 8%, transparent)`) — Background of the trend pill when its polarity is \"bad\".\n- `--lr-stat-trend-bad-color` (default: `var(--lr-color-danger)`) — Text color of the trend pill when its polarity is \"bad\". Independent of the headline value's `variant=\"danger\"` tint, which reads the shared `--lr-color-danger` token directly.\n- `--lr-stat-trend-good-bg` (default: `color-mix(in srgb, var(--lr-color-success) 8%, transparent)`) — Background of the trend pill when its polarity is \"good\".\n- `--lr-stat-trend-good-color` (default: `var(--lr-color-success)`) — Text color of the trend pill when its polarity is \"good\". Independent of the headline value's `variant=\"success\"` tint, which reads the shared `--lr-color-success` token directly.\n- `--lr-stat-value-brand-color` (default: `var(--lr-color-brand)`) — Headline value color for the `brand` variant.\n- `--lr-stat-value-danger-color` (default: `var(--lr-color-danger)`) — Headline value color for the `danger` variant.\n- `--lr-stat-value-success-color` (default: `var(--lr-color-success)`) — Headline value color for the `success` variant.\n- `--lr-stat-value-warning-color` (default: `var(--lr-color-warning)`) — Headline value color for the `warning` variant.","attributes":[{"name":"aria-label","description":"Host accessible-name override forwarded to the linked anchor when `href` is safe.\n\nType: `string | null`  \nDefault: `null`"},{"name":"caption","description":"Caption fallback. Removing the attribute omits it without hiding assigned caption content.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"compact","description":"Tighter padding for constrained spaces — same convention as `lr-empty`'s `compact`.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"delta-percent","description":"Percentage delta for the trend pill. Null (the JSON-safe default) hides the pill;\nnon-finite input normalizes to null and finite numbers remain unclamped.\n\nType: `number | null`"},{"name":"emphasis","description":"Visual emphasis (e.g. for a \"headline\" stat in a group) — orthogonal to\nthe status `variant`; see the `[part='value']` selector below for how\nthe two combine.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"exact-value","description":"Exact value shown as a hover/focus tooltip on the headline `value` (e.g. `value=\"$1.2K\"\nexact-value=\"$1,204.37\"`). Also makes `[part='value']` keyboard-focusable so the tooltip is\nreachable without a pointer.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"frame","description":"Container treatment — the shared `frame` vocabulary, not a fill. `'card'` (the default) keeps\nthe bordered, filled, padded box that stretches to fill its parent; `'plain'` removes the\nborder, background, padding, corner radius and the `block-size: 100%` stretch so the stat can\nsit inline in prose, a toolbar or a table cell. `plain` wins over `compact` when both are set\n(nothing left to tighten), and it also drops `emphasis`'s accent edge — that edge is card\nchrome — while `emphasis`'s brand value tint still applies. A `plain` stat with a safe `href`\nswaps the card's border-color/lift hover affordance (invisible with no border) for an\nunderline on `[part='value']`; the `:focus-visible` ring is unchanged.\n\nThis was `appearance` before 8.0.0, where `appearance` meant two unrelated things across the\nlibrary; it now means \"how a control fills itself\" everywhere, and the container treatment it\nused to double as is `frame`. A clean rename with no alias: `appearance` on `<lr-stat>` is\nsimply an unknown attribute now.\n\nType: `LyraFrame`  \nDefault: `'card'`","value":{"type":["'card'","'plain'"]}},{"name":"good-direction","description":"Which trend direction counts as \"good\" — inverts arrow/color polarity for\ncost/latency/error-rate-style metrics where a decrease is the win.\n\nType: `StatGoodDirection`  \nDefault: `'up'`","value":{"type":["'up'","'down'"]}},{"name":"href","description":"When set to a safe URL, renders the whole stat as a real anchor instead of a static div.\n\nType: `string | undefined`"},{"name":"label","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"orientation","description":"Layout axis. `'vertical'` (the default) stacks label, value, trend, sub and caption.\n`'horizontal'` lays label, value+unit, trend, sub and caption out on a single wrapping\nbaseline row; `[part='spark']` and `[part='rows']` have no sensible place on a text baseline\nand stay stacked on their own full-width line beneath that row.\n\nType: `StatOrientation`  \nDefault: `'vertical'`","value":{"type":["'horizontal'","'vertical'"]}},{"name":"prose","description":"Renders `value` as smaller/lighter prose (e.g. a loading/status message) instead of the bold\nnumeric headline style, and hides `unit`.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"sub","description":"Sub-line fallback. Removing the attribute omits it without hiding assigned sub content.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"target","description":"Native anchor target, used only while `href` resolves to a link. Setting this to `'_blank'`\n(or any other target) automatically derives `rel=\"noopener noreferrer\"` on the rendered\nanchor -- there is no separately-settable `rel` property, so a consumer can't forget it and\nleave the opened page holding a `window.opener` back-reference (reverse-tabnabbing). Matches\n`app-rail-item.class.ts`'s pattern.\n\nType: `string | undefined`"},{"name":"unit","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"value","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"variant","description":"Type: `LyraVariant`  \nDefault: `'neutral'`","value":{"type":["'neutral'","'brand'","'success'","'warning'","'danger'"]}}],"slots":[{"name":"","description":"Legacy leading-icon alias, retained as the fallback for `start`."},{"name":"caption","description":"Rich caption content (overrides the `caption` attribute)."},{"name":"spark","description":"A sparkline (e.g. `<lr-sparkline>`) or other compact trend visual. `lr-stat` only reserves the slot; it doesn't render one itself."},{"name":"start","description":"Leading icon. Takes precedence over the legacy default slot when both are filled."},{"name":"sub","description":"Rich sub-line content (overrides the `sub` attribute). When linked, every consumer slot remains a sibling of the stretched anchor so an interactive slotted descendant is never nested inside the whole-card link. Passive slotted content forwards pointer modifiers; the platform primary modifier and Shift preserve new-context activation."}],"js":{"properties":[{"name":"accessibleLabel","description":"Host accessible-name override forwarded to the linked anchor when `href` is safe.\n\nAttribute: `aria-label`","type":"string | null","default":"null"},{"name":"caption","description":"Caption fallback. Removing the attribute omits it without hiding assigned caption content.\n\nAttribute: `caption`","type":"string","default":"''"},{"name":"compact","description":"Tighter padding for constrained spaces — same convention as `lr-empty`'s `compact`.\n\nAttribute: `compact`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"deltaPercent","description":"Percentage delta for the trend pill. Null (the JSON-safe default) hides the pill;\nnon-finite input normalizes to null and finite numbers remain unclamped.\n\nAttribute: `delta-percent`","type":"number | null"},{"name":"emphasis","description":"Visual emphasis (e.g. for a \"headline\" stat in a group) — orthogonal to\nthe status `variant`; see the `[part='value']` selector below for how\nthe two combine.\n\nAttribute: `emphasis`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"exactValue","description":"Exact value shown as a hover/focus tooltip on the headline `value` (e.g. `value=\"$1.2K\"\nexact-value=\"$1,204.37\"`). Also makes `[part='value']` keyboard-focusable so the tooltip is\nreachable without a pointer.\n\nAttribute: `exact-value`","type":"string","default":"''"},{"name":"frame","description":"Container treatment — the shared `frame` vocabulary, not a fill. `'card'` (the default) keeps\nthe bordered, filled, padded box that stretches to fill its parent; `'plain'` removes the\nborder, background, padding, corner radius and the `block-size: 100%` stretch so the stat can\nsit inline in prose, a toolbar or a table cell. `plain` wins over `compact` when both are set\n(nothing left to tighten), and it also drops `emphasis`'s accent edge — that edge is card\nchrome — while `emphasis`'s brand value tint still applies. A `plain` stat with a safe `href`\nswaps the card's border-color/lift hover affordance (invisible with no border) for an\nunderline on `[part='value']`; the `:focus-visible` ring is unchanged.\n\nThis was `appearance` before 8.0.0, where `appearance` meant two unrelated things across the\nlibrary; it now means \"how a control fills itself\" everywhere, and the container treatment it\nused to double as is `frame`. A clean rename with no alias: `appearance` on `<lr-stat>` is\nsimply an unknown attribute now.\n\nAttribute: `frame`  \nReflected to its attribute.","type":"LyraFrame","default":"'card'"},{"name":"goodDirection","description":"Which trend direction counts as \"good\" — inverts arrow/color polarity for\ncost/latency/error-rate-style metrics where a decrease is the win.\n\nAttribute: `good-direction`","type":"StatGoodDirection","default":"'up'"},{"name":"href","description":"When set to a safe URL, renders the whole stat as a real anchor instead of a static div.\n\nAttribute: `href`","type":"string | undefined"},{"name":"label","description":"Attribute: `label`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"orientation","description":"Layout axis. `'vertical'` (the default) stacks label, value, trend, sub and caption.\n`'horizontal'` lays label, value+unit, trend, sub and caption out on a single wrapping\nbaseline row; `[part='spark']` and `[part='rows']` have no sensible place on a text baseline\nand stay stacked on their own full-width line beneath that row.\n\nAttribute: `orientation`  \nReflected to its attribute.","type":"StatOrientation","default":"'vertical'"},{"name":"prose","description":"Renders `value` as smaller/lighter prose (e.g. a loading/status message) instead of the bold\nnumeric headline style, and hides `unit`.\n\nAttribute: `prose`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"rows","description":"Breakdown rows rendered as a simple label/value list beneath the caption. The first 10,000\nrows are snapshotted and frozen so caller mutation cannot bypass the reactive boundary;\nreassign the collection to update.","type":"readonly StatRow[]"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"sub","description":"Sub-line fallback. Removing the attribute omits it without hiding assigned sub content.\n\nAttribute: `sub`","type":"string","default":"''"},{"name":"target","description":"Native anchor target, used only while `href` resolves to a link. Setting this to `'_blank'`\n(or any other target) automatically derives `rel=\"noopener noreferrer\"` on the rendered\nanchor -- there is no separately-settable `rel` property, so a consumer can't forget it and\nleave the opened page holding a `window.opener` back-reference (reverse-tabnabbing). Matches\n`app-rail-item.class.ts`'s pattern.\n\nAttribute: `target`","type":"string | undefined"},{"name":"unit","description":"Attribute: `unit`","type":"string","default":"''"},{"name":"value","description":"Attribute: `value`","type":"string","default":"''"},{"name":"variant","description":"Attribute: `variant`  \nReflected to its attribute.","type":"LyraVariant","default":"'neutral'"}]}},{"name":"lr-stepper","description":"`<lr-stepper>` — ordered multi-step wizard/form navigation: label + index per step,\ncurrent/completed/locked/error state, click-to-jump. First-party invention (no Web Awesome\nequivalent). Fully data-driven and controlled, like `lr-table`'s `columns`/`rows` -- it never\nmutates `steps` itself; a click or Enter/Space on a non-disabled step fires a non-cancelable\n`lr-step-select`, and the host decides whether/how `steps` changes in response.\n\nAn opt-in `orientationBreakpoint` (unset by default -- no behavior change) makes the effective\nlayout/navigation axis respond to a measured inline size instead of only the authored\n`orientation`: below that width (a pixel number or a `px`/`rem`/`em` CSS length), `narrowOrientation`\nbecomes effective; at/above it, `orientation` does. This mirrors `<lr-multi-split>`'s identically-named\n`orientationBreakpoint`/`narrowOrientation`/`orientationBreakpointBasis` contract. Under the default\n`orientationBreakpointBasis=\"container\"` the breakpoint is measured on this stepper's own\n`[part=\"base\"]` inline size via `ResizeObserver`, so a stepper placed in a narrow split pane or\ndialog still responds correctly even in a wide window; `orientationBreakpointBasis=\"viewport\"`\ninstead evaluates `matchMedia('(max-width: <breakpoint>)')`, needed when the stepper has a fixed\nwidth in a row that stacks at a shared breakpoint. The effective axis is exposed via the\n`effectiveOrientation` getter, a `data-effective-orientation` host attribute (only present while\nthe breakpoint feature is active), and `lr-stepper-orientation-change`.\n\nAn opt-in `readonly` (false by default -- no behavior change) turns the same data into a passive\nprogress display: every step renders as a non-interactive item rather than a button, so no step\ntakes a tab stop and no `lr-step-select` is emitted. (A read-only horizontal strip that actually\noverflows moves the single tab stop onto its own scroll container instead, so its off-screen\nsteps stay keyboard-reachable.) It is deliberately *not* a disabled\ntreatment -- `disabled` says \"you may not do this\", read-only says \"there is nothing to do here\"\n-- so read-only steps keep normal opacity and every state glyph, current-step marker and\n`--lr-stepper-*` custom property.\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 root wrapper, and the horizontally scrolling track. Takes `tabindex=\"0\"` only while `readonly` and genuinely overflowing, so an otherwise keyboard-unreachable read-only strip can still be scrolled; style that state with `::part(base):focus-visible`. |\n| `step` | A single step button, or a non-interactive `<div>` carrying the same part while `readonly`. |\n| `step-check` | The completed-checkmark glyph, shown for `completed` steps instead of `step-index`. |\n| `step-icon` | Optional inert, aria-hidden leading topic glyph supplied by the item's `icon` field; content may have a natural aspect ratio and is not restricted to a square icon. Rendered additionally to, never instead of, `step-index`/`step-check`. |\n| `step-index` | The numbered index chip, shown for `pending`/`current`/`error` steps. |\n| `step-item` | The `role=\"listitem\"` wrapper for one step. |\n| `step-label` | The step's label text. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-scroll-fade-size` (default: `2rem`) — Width of each decorative horizontal overflow fade. Pointer-state hooks use inline `var()` fallbacks rather than a `:host` declaration, so they inherit from the stepper or any ancestor without retheming another state.\n- `--lr-stepper-active-bg` (default: `color-mix(in oklab, var(--lr-color-brand-quiet), var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Background of a pressed, non-disabled step.\n- `--lr-stepper-active-color` (default: `var(--lr-color-text)`) — Text color of a pressed, non-disabled step.\n- `--lr-stepper-current-color` (default: `var(--lr-color-text)`) — Text color of the `current` step. Declared as an inline `var()` fallback (never on `:host`), so setting it on the element or an ancestor recolors only the current step without hijacking the library-wide `--lr-color-text` token.\n- `--lr-stepper-current-font-weight` (default: `var(--lr-font-weight-semibold)`) — Font weight of the `current` step's label. `::part(step)[data-state='current']` is invalid CSS (an attribute selector cannot follow `::part`), so this is the only way to change just the current step's boldness without hijacking the library-wide `--lr-font-weight-semibold` token.\n- `--lr-stepper-current-index-bg` (default: `var(--lr-color-brand)`) — Background of the `current` step's numbered index chip (`step-index`).\n- `--lr-stepper-current-index-color` (default: `var(--lr-color-on-brand)`) — Text color of the `current` step's numbered index chip.\n- `--lr-stepper-error-color` (default: `var(--lr-color-danger)`) — Text color of an `error` step.\n- `--lr-stepper-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Background of a hovered, non-disabled step.\n- `--lr-stepper-hover-color` (default: `var(--lr-color-text)`) — Text color of a hovered, non-disabled step.","attributes":[{"name":"aria-label","description":"Accessible name for the `role=\"list\"` step strip. Attribute-reflects from a host-level\n`aria-label` so a plain-markup consumer gets ARIA-name forwarding without setting a JS\nproperty. Unset, the list renders without an `aria-label` (the role carries no localized\ndefault name).\n\nType: `string | null`  \nDefault: `null`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"narrow-orientation","description":"Layout/navigation axis used below `orientationBreakpoint`.\n\nType: `LyraOrientation`  \nDefault: `'vertical'`","value":{"type":["'horizontal'","'vertical'"]}},{"name":"orientation","description":"`'horizontal'` (the default) lays steps out in a row (Left/Right, RTL-aware, to navigate);\n`'vertical'` stacks them (Up/Down navigate instead, no RTL swap needed). The *authored* axis\nused at/above `orientationBreakpoint` (or always, when that's unset) -- see\n`effectiveOrientation` for the live axis actually in effect.\n\nType: `LyraOrientation`  \nDefault: `'horizontal'`","value":{"type":["'horizontal'","'vertical'"]}},{"name":"orientation-breakpoint","description":"Opt-in inline-size breakpoint, measured on `[part=\"base\"]`. Below it, `narrowOrientation`\nbecomes effective instead of `orientation`. Unset (the default): no behavior change, the\nauthored `orientation` always applies.\n\nAccepts a bare pixel number (`500`, `'500'`), an explicit `px` length (`'500px'`), a `rem`\nlength (`'31.25rem'`) or an `em` length (`'3em'`). Under the default\n`orientationBreakpointBasis=\"container\"`, `rem` resolves against the **document root**'s\ncomputed font size -- the rule a `@container` query follows, and *not* a `@media` query's --\nwhile `em` resolves against this element's own computed font size. The length is re-resolved\non every measurement, never cached, so browser zoom, a user font-size preference or an app\nbase-size token change are picked up with no invalidation step. To stay in step with a\nsibling `@media (max-width: …rem)` rule, use `orientationBreakpointBasis=\"viewport\"`, which\nhands the length to the browser instead; see that property for why the two differ.\n\nAny other value -- `%`, `vw`, `calc()`, `'auto'`, an unparseable string -- behaves exactly as\nunset (no responsive observation at all), rather than as an armed breakpoint that can never\nbe crossed. Set `orientationBreakpointBasis=\"viewport\"` for a viewport-relative breakpoint\ninstead.\n\nType: `| number\n    | string | undefined`"},{"name":"orientation-breakpoint-basis","description":"Which box `orientationBreakpoint` measures. `'container'` (the default) observes this\nstepper's own `[part=\"base\"]` inline size via `ResizeObserver`, comparing strictly `<`.\n`'viewport'` instead evaluates `matchMedia('(max-width: <breakpoint>)')`, which is inclusive\n(`<=`) -- native `max-width` semantics, deliberately, so the crossing point matches a CSS\n`@media` rule authored with the same length exactly.\n\nA stepper given a fixed width in a row layout cannot react to that row stacking by measuring\nitself -- its own width never changes. That case requires `'viewport'`, which also lets the\nbrowser resolve a `rem` breakpoint with real `@media` semantics.\n\nType: `BreakpointBasis`  \nDefault: `'container'`","value":{"type":["'container'","'viewport'"]}},{"name":"readonly","description":"Turns the strip into a passive progress display. Each step renders as a non-interactive\n`role=\"listitem\"` item instead of a button: no `tabindex`, no `aria-disabled`, no click or\nEnter/Space activation, and therefore no `lr-step-select` at all. Everything that describes\n*progress* is kept untouched -- the index chip, the completed checkmark, the optional topic\nicon, the per-step `title`, `aria-current=\"step\"` on the current step, and every\n`--lr-stepper-*` custom property.\n\nDeliberately not `disabled` styling: `disabled` says \"you may not do this\", read-only says\n\"there is nothing to do here\", so a read-only step keeps normal opacity and simply loses its\npointer cursor (the same bargain `lr-slider` and `lr-rating` strike for their own `readonly`).\nA per-step `disabled` flag is inert while read-only for the same reason -- there is no\nactivation left for it to gate, so it contributes no dimming either.\n\nNo *step* takes a tab stop: roving tabindex exists to give a composite *control* exactly one\nentry point, and a passive list is not a control. The one exception is the scroll container\nitself -- a read-only horizontal strip that genuinely overflows gives `[part=\"base\"]`\n`tabindex=\"0\"` so its hidden steps stay reachable by keyboard (see `syncScrollTabStop()`);\na strip that fits, or a vertical one, still takes no tab stop at all. Unset (the default) is\nbyte-for-byte the previous behavior.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"wrap-labels","description":"When true, allows step labels to wrap when the effective orientation is vertical. The\ndefault preserves the single-line labels used by the original stepper contract; horizontal\nlabels remain single-line even when this property is enabled.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"js":{"properties":[{"name":"accessibleLabel","description":"Accessible name for the `role=\"list\"` step strip. Attribute-reflects from a host-level\n`aria-label` so a plain-markup consumer gets ARIA-name forwarding without setting a JS\nproperty. Unset, the list renders without an `aria-label` (the role carries no localized\ndefault name).\n\nAttribute: `aria-label`","type":"string | null","default":"null"},{"name":"effectiveOrientation","description":"The live layout/navigation axis after applying `orientationBreakpoint` -- identical to\n`orientation` whenever that's unset. See the class doc.","type":"LyraOrientation","read-only":true},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"narrowOrientation","description":"Layout/navigation axis used below `orientationBreakpoint`.\n\nAttribute: `narrow-orientation`  \nReflected to its attribute.","type":"LyraOrientation","default":"'vertical'"},{"name":"orientation","description":"`'horizontal'` (the default) lays steps out in a row (Left/Right, RTL-aware, to navigate);\n`'vertical'` stacks them (Up/Down navigate instead, no RTL swap needed). The *authored* axis\nused at/above `orientationBreakpoint` (or always, when that's unset) -- see\n`effectiveOrientation` for the live axis actually in effect.\n\nAttribute: `orientation`  \nReflected to its attribute.","type":"LyraOrientation","default":"'horizontal'"},{"name":"orientationBreakpoint","description":"Opt-in inline-size breakpoint, measured on `[part=\"base\"]`. Below it, `narrowOrientation`\nbecomes effective instead of `orientation`. Unset (the default): no behavior change, the\nauthored `orientation` always applies.\n\nAccepts a bare pixel number (`500`, `'500'`), an explicit `px` length (`'500px'`), a `rem`\nlength (`'31.25rem'`) or an `em` length (`'3em'`). Under the default\n`orientationBreakpointBasis=\"container\"`, `rem` resolves against the **document root**'s\ncomputed font size -- the rule a `@container` query follows, and *not* a `@media` query's --\nwhile `em` resolves against this element's own computed font size. The length is re-resolved\non every measurement, never cached, so browser zoom, a user font-size preference or an app\nbase-size token change are picked up with no invalidation step. To stay in step with a\nsibling `@media (max-width: …rem)` rule, use `orientationBreakpointBasis=\"viewport\"`, which\nhands the length to the browser instead; see that property for why the two differ.\n\nAny other value -- `%`, `vw`, `calc()`, `'auto'`, an unparseable string -- behaves exactly as\nunset (no responsive observation at all), rather than as an armed breakpoint that can never\nbe crossed. Set `orientationBreakpointBasis=\"viewport\"` for a viewport-relative breakpoint\ninstead.\n\nAttribute: `orientation-breakpoint`","type":"| number\n    | string | undefined"},{"name":"orientationBreakpointBasis","description":"Which box `orientationBreakpoint` measures. `'container'` (the default) observes this\nstepper's own `[part=\"base\"]` inline size via `ResizeObserver`, comparing strictly `<`.\n`'viewport'` instead evaluates `matchMedia('(max-width: <breakpoint>)')`, which is inclusive\n(`<=`) -- native `max-width` semantics, deliberately, so the crossing point matches a CSS\n`@media` rule authored with the same length exactly.\n\nA stepper given a fixed width in a row layout cannot react to that row stacking by measuring\nitself -- its own width never changes. That case requires `'viewport'`, which also lets the\nbrowser resolve a `rem` breakpoint with real `@media` semantics.\n\nAttribute: `orientation-breakpoint-basis`  \nReflected to its attribute.","type":"BreakpointBasis","default":"'container'"},{"name":"readonly","description":"Turns the strip into a passive progress display. Each step renders as a non-interactive\n`role=\"listitem\"` item instead of a button: no `tabindex`, no `aria-disabled`, no click or\nEnter/Space activation, and therefore no `lr-step-select` at all. Everything that describes\n*progress* is kept untouched -- the index chip, the completed checkmark, the optional topic\nicon, the per-step `title`, `aria-current=\"step\"` on the current step, and every\n`--lr-stepper-*` custom property.\n\nDeliberately not `disabled` styling: `disabled` says \"you may not do this\", read-only says\n\"there is nothing to do here\", so a read-only step keeps normal opacity and simply loses its\npointer cursor (the same bargain `lr-slider` and `lr-rating` strike for their own `readonly`).\nA per-step `disabled` flag is inert while read-only for the same reason -- there is no\nactivation left for it to gate, so it contributes no dimming either.\n\nNo *step* takes a tab stop: roving tabindex exists to give a composite *control* exactly one\nentry point, and a passive list is not a control. The one exception is the scroll container\nitself -- a read-only horizontal strip that genuinely overflows gives `[part=\"base\"]`\n`tabindex=\"0\"` so its hidden steps stay reachable by keyboard (see `syncScrollTabStop()`);\na strip that fits, or a vertical one, still takes no tab stop at all. Unset (the default) is\nbyte-for-byte the previous behavior.\n\nAttribute: `readonly`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"steps","type":"readonly LyraStepItem[]"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"wrapLabels","description":"When true, allows step labels to wrap when the effective orientation is vertical. The\ndefault preserves the single-line labels used by the original stepper contract; horizontal\nlabels remain single-line even when this property is enabled.\n\nAttribute: `wrap-labels`  \nReflected to its attribute.","type":"boolean","default":"false"}],"events":[{"name":"lr-step-select","description":"Fired on click, or Enter/Space while focused, on a non-`disabled` step. Never fired while `readonly`. `detail: { stepId, index }`; the index disambiguates legitimate duplicate step IDs. Not cancelable: this component is fully controlled (mirrors `lr-table`'s `columns`/`rows` contract) and takes no default action of its own on selection (it never mutates `steps`), so there is no real veto point for `preventDefault()` to gate.","type":"CustomEvent<{ stepId: string; index: number }>"},{"name":"lr-stepper-orientation-change","description":"`detail: { orientation }`, fired when an enabled `orientationBreakpoint` changes the effective layout/navigation axis.","type":"CustomEvent<LyraStepperOrientationChangeDetail>"}]}},{"name":"lr-stream-status","description":"`<lr-stream-status>` — a compact status indicator for a single streaming\nconnection (SSE, WebSocket, long-poll, …), with built-in heartbeat-aware\nstall detection.\n\nThe host owns `connectionState` for `idle`/`connecting`/`streaming`, and\ncalls `recordActivity()` on every *semantic* frame received while\nstreaming — a real content chunk, never a transport-level keep-alive ping.\nThis component has no payload-inspection logic of its own: \"ignore\nheartbeats\" is entirely a call-site discipline — the host simply never\ncalls `recordActivity()` for a ping, so pings never reset the stall timer\nand a connection that's only sending keep-alives (no real content) for\nlonger than `stall-threshold-ms` correctly reads as stalled.\n\nInternally, an inactivity timer runs only while the effective readonly `phase` is `streaming`.\nIt's (re)armed whenever `connectionState` enters `streaming` or\n`recordActivity()` recovers from `stalled`, on every\nsubsequent `recordActivity()` call while already streaming, whenever\n`stall-threshold-ms` itself changes while already streaming (the new\nvalue takes effect immediately, the same way `<lr-toast-item>`'s\n`duration` re-applies mid-flight, rather than waiting for the next\n`recordActivity()`/phase change), and whenever this element (re)connects\nto the DOM while `phase` is still `'streaming'` (a disconnect always\ndisarms it, so moving the element elsewhere in the page — disconnect then\nreconnect with `phase` unchanged — must resume detection rather than\nsilently disabling it for the rest of the streaming session). It's\ndisarmed the instant `phase` becomes anything else, including a\nhost-driven `connectionState` reassignment away from `streaming` — so a stale timer can\nnever fire a stall transition after the host has already moved on. If it\never fires, `phase` becomes `'stalled'` and `lr-stall` is dispatched.\n\n`phase` is a readonly effective value: it mirrors `connectionState` unless inactivity has\nstalled a streaming connection. A host that detects a semantic stall through another signal\ncalls `markStalled()` instead of writing component-owned state. `recordActivity()` clears that\noverride and resumes the timer. `lr-stall`/`lr-recover` fire exactly once for actual effective\ntransitions into/out of `stalled`.\nLike `<lr-chat-message>`'s `status`, whatever phase this element happens\nto *mount* with is never itself treated as an eventful transition — only a\nlater change fires an event or an announcement.\n\nAccessibility: phase transitions into/out of `'stalled'` are announced\nthrough an internal `<lr-live-region>` (see that component for the\nthrottled/coalesced-announcement machinery this composes) rather than a\nhand-rolled `aria-live` region. `recordActivity()` itself never announces\nanything, no matter how often the host calls it — only the *transition*\nannounces, exactly once per transition, which is the entire point of\nrouting through the throttled announcer instead of writing to a live\nregion on every call. Entering `'stalled'` announces with `mode=\"assertive\"`\n(a stall can need the user's attention, e.g. before they give up and\nnavigate away); leaving `'stalled'` always announces with `mode=\"polite\"`\n(good news doesn't need to interrupt), but the *wording* depends on where\nit lands: `\"Connection restored.\"` only when the destination is\n`'streaming'` (a genuine recovery), or a neutral `\"No longer stalled.\"`\nwhen the destination is `'idle'`/`'connecting'` instead — that's the host\ngiving up on the stream, not the stream recovering, and a screen-reader\nuser must never be told the opposite of what a sighted user sees on\nscreen. The decorative indicator dot is `aria-hidden` — it's a\ncolor/motion cue only, never the sole carrier of state.\n\nVisual: `'stalled'` is styled as a warning, not a danger — a stall is\nusually recoverable (the stream may resume on its own, or the host's own\nretry logic may kick in), so treating it as an actionable warning rather\nthan a hard failure keeps the tone proportionate. A host that wants to\nescalate after N stalls can listen for `lr-stall` and show its own danger-styled error 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) | Custom copy shown only while `phase === 'stalled'` (e.g. \"Taking longer than usual…\"). A sensible built-in default is used when nothing is slotted. |\n| `actions` | A stop/retry button row. Always present in the template regardless of phase; visibility is driven by whether anything is slotted. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `actions` | Wrapper around the `actions` slot. |\n| `base` | The root layout container. |\n| `indicator` | The decorative (`aria-hidden`) status dot. |\n| `message` | Wrapper around the default slot; only rendered while readonly `phase` is `stalled`. |\n| `phase` | Persistent localized phase text. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-stream-status-dot-color` (default: `var(--lr-color-text-quiet)`) — `indicator` dot color. Its private default changes with reflected `connection-state` and the component-owned `data-stalled` state: `var(--lr-color-brand)` for `connecting`/`streaming`, `var(--lr-color-warning)` for `stalled`. Set it on the element or any ancestor; an element value wins.\n- `--lr-stream-status-dot-opacity` (default: `0.35`) — `indicator` dot opacity. Its private default changes with those same host states: `0.6` for `connecting`, `1` for `streaming` and `stalled`. Set it on the element or any ancestor; an element value wins.\n- `--lr-stream-status-message-color` (default: `var(--lr-color-warning)`) — `phase` and `message` text color while `data-stalled` is present. Decoupled from `--lr-stream-status-stalled-border-color` even though both fall back to the same shared token today.\n- `--lr-stream-status-stalled-bg` (default: `var(--lr-color-warning-quiet)`) — `base` row background while `data-stalled` is present.\n- `--lr-stream-status-stalled-border-color` (default: `var(--lr-color-warning)`) — `base` row border color while `data-stalled` is present.","attributes":[{"name":"connection-state","description":"Host-owned transport state. Invalid attribute and JavaScript writes normalize to `idle`.\n\nType: `StreamConnectionState`","value":{"type":["'idle'","'connecting'","'streaming'"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"stall-threshold-ms","description":"How long `phase` may stay `'streaming'` with no `recordActivity()` call\nbefore this component declares it stalled.\n\nType: `number`  \nDefault: `10000`","value":{"type":["number"]}}],"slots":[{"name":"","description":"Custom copy shown only while `phase === 'stalled'` (e.g. \"Taking longer than usual…\"). A sensible built-in default is used when nothing is slotted."},{"name":"actions","description":"A stop/retry button row. Always present in the template regardless of phase; visibility is driven by whether anything is slotted."}],"js":{"properties":[{"name":"connectionState","description":"Host-owned transport state. Invalid attribute and JavaScript writes normalize to `idle`.\n\nAttribute: `connection-state`  \nReflected to its attribute.","type":"StreamConnectionState"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"phase","description":"Readonly effective status, including the component-owned stalled override.","type":"LyraStreamPhase","read-only":true},{"name":"stallThresholdMs","description":"How long `phase` may stay `'streaming'` with no `recordActivity()` call\nbefore this component declares it stalled.\n\nAttribute: `stall-threshold-ms`","type":"number","default":"10000"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-recover","description":"Fired whenever the effective phase transitions out of `stalled`.","type":"CustomEvent<null>"},{"name":"lr-stall","description":"Fired whenever the effective phase transitions into `stalled`.","type":"CustomEvent<null>"}]}},{"name":"lr-streaming-text","description":"`<lr-streaming-text>` — a token-coalescing incremental text renderer for\nstreaming assistant output, with an optional blinking cursor and\nauto-detected Markdown rendering.\n\nThe host is expected to assign the *entire* current text on every update\nto `content`, not a delta -- this component does no accumulation or\nordering of its own. That matches how most streaming-UI state (SSE/\nWebSocket token accumulation into a growing string in application state)\nis already managed.\n\nToken-by-token streaming can update `content` far faster than a human can\nusefully perceive a re-render -- dozens of times a second for a fast\nmodel. Re-rendering on every single assignment thrashes layout for no\nvisible benefit, so updates funnel through `Announcer`\n(`../../internal/announcer.js`), reused here purely as the generic\n\"coalesce rapid calls, flush the latest\" timing primitive its own class\ndoc says other components should reuse -- with none of its usual\nDOM/ARIA plumbing (that's `<lr-live-region>`'s job, not this\ncomponent's). Within any `coalesce-ms` window, only the *last* `content`\nvalue assigned actually reaches the rendered DOM. Two cases always bypass\nthe throttle and flush immediately instead of waiting out the window: the\nvery first `content` assignment after mount (so an already-complete\nmessage never shows an artificial startup delay), and any transition of\n`streaming` between `true` and `false` in either direction (so the final\nchunk of a finished stream can never be left stranded mid-window, and a\nstream restarting on a reused element can never keep showing the\nprevious stream's stale final content for the length of the window).\n\n`contentMode=\"auto\"` (the default) auto-detects via a lightweight regex heuristic (see\n`looksLikeMarkdown`) run against whatever text is currently displayed --\ngood enough to route obviously-Markdown output through `<lr-markdown>`\nwithout the host needing to know or declare it up front, at the cost of\nan occasional one-time mode flip if Markdown syntax only appears partway\nthrough a stream. Explicit `\"plain\"` and `\"markdown\"` modes always win\nover the heuristic. Rendering itself is never reimplemented here:\nMarkdown mode composes `<lr-markdown>` (`../markdown/markdown.js`)\ndirectly, forwarding this component's own `streaming` through as that\ncomponent's own forward-compatible `streaming` hint prop, and this\ncomponent's own `languages` through verbatim; plain-text mode\nrenders into a `white-space: pre-wrap` span instead. The rest of\n`<lr-markdown>`'s configuration surface is forwarded verbatim too --\n`tabSize`, `htmlMode`, `gfm`, `linkTarget`, `internalLinkPrefix`,\n`headingOffset`, `highlightCode`, `headingAnchors`, `math`, and\n`maxHeight` -- each defaulting to exactly `<lr-markdown>`'s own default, so\nleaving all of them unset renders identically to before this wrapper\nforwarded them. The plain-text path\ndoes not load optional peers. Markdown mode uses `<lr-markdown>`'s lazy\n`marked` parser and default `dompurify` sanitizer; fenced-code highlighting\ncan additionally use `shiki`. The transitive Markdown graph also contains\nthe opt-in `katex` loader, requested only if this wrapper's own `math` is\nset (forwarded to the composed element, unset by default).\n\nA consumer with a bounded, known fence-language set who wants to avoid `<lr-markdown>`'s\n~200-language dynamic-import table entirely -- either by setting `languages` here, or to skip\nthe full table's build-output cost outright -- can import `streaming-text-core.js` instead,\nwhich composes `<lr-markdown-core>` under the tag `lr-streaming-text-core` and never references\nthe full table at all; see that variant's own class doc.\n\nThe blinking cursor (shown only while `streaming` is `true`) degrades to\na static, always-visible bar under `prefers-reduced-motion: reduce`\nrather than disabling the animation into an invisible frozen frame --\nthe same pattern `<lr-typing-indicator>`'s own `cursor` variant uses. In\nplain-text mode the cursor sits inline at the tail of the final\ncharacter, since the text is one continuous inline flow; in Markdown\nmode it renders as its own trailing block below the rendered content\ninstead of attempting to splice into whatever nested block Markdown\nhappens to end with (a paragraph, a table cell, a list item, a fenced\ncode block, …) -- genuinely interleaving into arbitrary rendered Markdown\nwithout reaching across `<lr-markdown>`'s own shadow boundary isn't a\ntractable general solution, so this component doesn't attempt it.\n\nDriven entirely by its properties -- it doesn't announce anything to assistive tech itself (a\nhost that needs streamed text announced already has `<lr-live-region>` for that, composed, for\nexample, inside `<lr-chat-message>`). It does fire one signal-only event: `lr-content-settled`,\ncomposed and bubbling, whenever newly-coalesced `displayedContent` actually reaches the\nrendered DOM. A consumer that composes this element inside a free-form container -- e.g.\n`<lr-thinking-panel>`'s default slot -- listens for that event to drive its own auto-scroll,\nsince this component renders into its own shadow root and a plain light-DOM\n`MutationObserver` on the container can never see that update happen. In `markdown` mode\n(forced or auto-detected) this element does not emit the event itself -- the composed\n`<lr-markdown>` it delegates rendering to already emits its own `lr-content-settled` at its own\nsettle point, and that event is composed, so it bubbles out through this element unmodified;\nemitting a second one here would double-fire every listener.\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 root container. |\n| `blockquote` | Forwarded from the composed `<lr-markdown>` in Markdown mode -- every rendered `<blockquote>`. |\n| `code-block` | Forwarded from the composed `<lr-markdown>` in Markdown mode -- every rendered fenced/indented `<pre>`. |\n| `content` | Forwarded from the composed `<lr-markdown>` in Markdown mode -- the wrapper around its rendered (or plain-text fallback) output; respects `max-height`. |\n| `cursor` | The blinking (or, under reduced motion, static) cursor bar. Only rendered while `streaming` is `true`. |\n| `heading` | Forwarded from the composed `<lr-markdown>` in Markdown mode -- every rendered `<h1>`–`<h6>` (shifted by `heading-offset`). |\n| `img` | Forwarded from the composed `<lr-markdown>` in Markdown mode -- every rendered `<img>`. |\n| `inline-code` | Forwarded from the composed `<lr-markdown>` in Markdown mode -- every rendered inline `<code>` span (backtick spans, not fenced blocks). |\n| `link` | Forwarded from the composed `<lr-markdown>` in Markdown mode -- every rendered `<a>`. |\n| `list` | Forwarded from the composed `<lr-markdown>` in Markdown mode -- every rendered `<ul>`/`<ol>`. |\n| `math` | Forwarded from the composed `<lr-markdown>` in Markdown mode -- a rendered inline or block math span (`data-display=\"inline\"\\|\"block\"`). |\n| `paragraph` | Forwarded from the composed `<lr-markdown>` in Markdown mode -- every rendered `<p>`. |\n| `table` | Forwarded from the composed `<lr-markdown>` in Markdown mode -- every rendered `<table>`. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-inline-cursor-height` (default: `var(--lr-size-1em)`) — Shared height of the inline cursor bar.\n- `--lr-inline-cursor-width` (default: `var(--lr-size-0-125rem)`) — Shared width of the inline cursor bar (also its border radius).","attributes":[{"name":"coalesce-ms","description":"Trailing-edge coalesce window, in ms, for `content` updates -- see the\nclass doc.\n\nType: `number`  \nDefault: `50`","value":{"type":["number"]}},{"name":"content","description":"The full current text so far -- always the complete string, never a\ndelta to append.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"content-mode","description":"Rendering mode. `auto` uses `looksLikeMarkdown`; the other values force\ntheir named mode regardless of content.\n\nType: `StreamingTextContentMode`  \nDefault: `'auto'`","value":{"type":["'auto'","'plain'","'markdown'"]}},{"name":"gfm","description":"Forwarded verbatim to the composed Markdown element's own `gfm` -- GitHub-flavored Markdown\n(tables, strikethrough, autolinks, task lists). `true` (the default) matches the composed\nelement's own default.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"heading-anchors","description":"Forwarded verbatim to the composed Markdown element's own `headingAnchors`. `false` (the\ndefault) matches the composed element's own default.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"heading-offset","description":"Forwarded verbatim to the composed Markdown element's own `headingOffset`. `0` (the\ndefault) matches the composed element's own default.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"highlight-code","description":"Forwarded verbatim to the composed Markdown element's own `highlightCode`. `true` (the\ndefault) matches the composed element's own default.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"html-mode","description":"Forwarded verbatim to the composed Markdown element's own `htmlMode` -- how authored raw\nHTML is handled (`'sanitize'`, `'escape'`, or `'trusted'`). `'sanitize'` (the default)\nmatches the composed element's own default.\n\nType: `MarkdownHtmlMode`  \nDefault: `'sanitize'`","value":{"type":["'sanitize'","'escape'","'trusted'"]}},{"name":"internal-link-prefix","description":"Forwarded verbatim to the composed Markdown element's own `internalLinkPrefix`. Empty (the\ndefault) matches the composed element's own default -- every link is treated as external.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"link-target","description":"Forwarded verbatim to the composed Markdown element's own `linkTarget` -- the `target`\napplied to every rendered `<a>`, with `rel=\"noopener noreferrer\"` always added by the\ncomposed element alongside it whenever a `target` is emitted. `'_blank'` (the default)\nmatches the composed element's own default; set to `null` (or the empty string, e.g. via the\n`link-target=\"\"` attribute) to omit `target`/`rel` entirely so rendered links open in the\nsame tab.\n\nType: `string | null`  \nDefault: `'_blank'`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"math","description":"Forwarded verbatim to the composed Markdown element's own `math`. `false` (the default)\nmatches the composed element's own default.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"max-height","description":"Forwarded verbatim to the composed Markdown element's own `maxHeight`. Empty (the default)\nmatches the composed element's own default -- the rendered document never scrolls\ninternally.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"streaming","description":"Shows the blinking cursor after the rendered text. Reflects, so a host\ncan also target `[streaming]` in CSS.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"tab-size","description":"Forwarded verbatim to the composed Markdown element's own `tabSize` -- the tab-stop width\nused to expand tabs in leading indentation before parsing. `4` (the default) matches the\ncomposed element's own default.\n\nType: `number`  \nDefault: `4`","value":{"type":["number"]}}],"js":{"properties":[{"name":"coalesceMs","description":"Trailing-edge coalesce window, in ms, for `content` updates -- see the\nclass doc.\n\nAttribute: `coalesce-ms`","type":"number","default":"50"},{"name":"content","description":"The full current text so far -- always the complete string, never a\ndelta to append.\n\nAttribute: `content`","type":"string","default":"''"},{"name":"contentMode","description":"Rendering mode. `auto` uses `looksLikeMarkdown`; the other values force\ntheir named mode regardless of content.\n\nAttribute: `content-mode`  \nReflected to its attribute.","type":"StreamingTextContentMode","default":"'auto'"},{"name":"gfm","description":"Forwarded verbatim to the composed Markdown element's own `gfm` -- GitHub-flavored Markdown\n(tables, strikethrough, autolinks, task lists). `true` (the default) matches the composed\nelement's own default.\n\nAttribute: `gfm`","type":"boolean","default":"true"},{"name":"headingAnchors","description":"Forwarded verbatim to the composed Markdown element's own `headingAnchors`. `false` (the\ndefault) matches the composed element's own default.\n\nAttribute: `heading-anchors`","type":"boolean","default":"false"},{"name":"headingOffset","description":"Forwarded verbatim to the composed Markdown element's own `headingOffset`. `0` (the\ndefault) matches the composed element's own default.\n\nAttribute: `heading-offset`","type":"number","default":"0"},{"name":"highlightCode","description":"Forwarded verbatim to the composed Markdown element's own `highlightCode`. `true` (the\ndefault) matches the composed element's own default.\n\nAttribute: `highlight-code`","type":"boolean","default":"true"},{"name":"htmlMode","description":"Forwarded verbatim to the composed Markdown element's own `htmlMode` -- how authored raw\nHTML is handled (`'sanitize'`, `'escape'`, or `'trusted'`). `'sanitize'` (the default)\nmatches the composed element's own default.\n\nAttribute: `html-mode`","type":"MarkdownHtmlMode","default":"'sanitize'"},{"name":"internalLinkPrefix","description":"Forwarded verbatim to the composed Markdown element's own `internalLinkPrefix`. Empty (the\ndefault) matches the composed element's own default -- every link is treated as external.\n\nAttribute: `internal-link-prefix`","type":"string","default":"''"},{"name":"languages","description":"Forwarded verbatim to the composed Markdown element's own `languages` -- a fine-grained,\nexplicit language-grammar bundle scoping shiki's build output to just those grammars. Unset\nleaves the composed element's own default untouched: the full variant falls back to its\n~200-language dynamic-import table, the core variant renders unmatched fences as plain text.","type":"Readonly<Record<string, ShikiLanguageInput>> | undefined"},{"name":"linkTarget","description":"Forwarded verbatim to the composed Markdown element's own `linkTarget` -- the `target`\napplied to every rendered `<a>`, with `rel=\"noopener noreferrer\"` always added by the\ncomposed element alongside it whenever a `target` is emitted. `'_blank'` (the default)\nmatches the composed element's own default; set to `null` (or the empty string, e.g. via the\n`link-target=\"\"` attribute) to omit `target`/`rel` entirely so rendered links open in the\nsame tab.\n\nAttribute: `link-target`","type":"string | null","default":"'_blank'"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"math","description":"Forwarded verbatim to the composed Markdown element's own `math`. `false` (the default)\nmatches the composed element's own default.\n\nAttribute: `math`","type":"boolean","default":"false"},{"name":"maxHeight","description":"Forwarded verbatim to the composed Markdown element's own `maxHeight`. Empty (the default)\nmatches the composed element's own default -- the rendered document never scrolls\ninternally.\n\nAttribute: `max-height`","type":"string","default":"''"},{"name":"streaming","description":"Shows the blinking cursor after the rendered text. Reflects, so a host\ncan also target `[streaming]` in CSS.\n\nAttribute: `streaming`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"tabSize","description":"Forwarded verbatim to the composed Markdown element's own `tabSize` -- the tab-stop width\nused to expand tabs in leading indentation before parsing. `4` (the default) matches the\ncomposed element's own default.\n\nAttribute: `tab-size`","type":"number","default":"4"}],"events":[{"name":"lr-content-settled","description":"Fired after newly-coalesced content actually reaches the rendered DOM (plain-text mode only -- see the class doc). `detail: null`.","type":"CustomEvent<null>"}]}},{"name":"lr-streaming-text-core","description":"`<lr-streaming-text-core>` — a build-lean `<lr-streaming-text>` variant for a consumer whose\n`languages` map already covers every fenced-code language it will ever stream, or who never\nrenders fenced code at all. Every capability is identical to `<lr-streaming-text>` -- token\ncoalescing, `contentMode` auto-detection, the blinking cursor, the `lr-content-settled` event,\nand the full forwarded Markdown configuration surface (`tabSize`, `htmlMode`, `gfm`,\n`linkTarget`, `internalLinkPrefix`, `headingOffset`, `highlightCode`, `headingAnchors`, `math`,\n`maxHeight`) -- only which Markdown element Markdown mode composes differs: this variant\nrenders `<lr-markdown-core>` (`../markdown/markdown-core.js`) instead of `<lr-markdown>`, so this\ncomponent's own module never textually contains a reference to `<lr-markdown>`'s ~200-language\ndynamic-import table. A fenced code block whose language isn't a key in `languages` always\nrenders the plain-text fallback here -- there is no default/full-table highlighter to fall back\nto, mirroring `<lr-markdown-core>`'s own contract.\n\n---\n\n**Component metadata**\n\n- Status: `experimental`\n- Since: `16.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| `base` | The root container. |\n| `blockquote` | Forwarded from the composed `<lr-markdown-core>` in Markdown mode -- every rendered `<blockquote>`. |\n| `code-block` | Forwarded from the composed `<lr-markdown-core>` in Markdown mode -- every rendered fenced/indented `<pre>`. |\n| `content` | Forwarded from the composed `<lr-markdown-core>` in Markdown mode -- the wrapper around its rendered (or plain-text fallback) output; respects `max-height`. |\n| `cursor` | The blinking (or, under reduced motion, static) cursor bar. Only rendered while `streaming` is `true`. |\n| `heading` | Forwarded from the composed `<lr-markdown-core>` in Markdown mode -- every rendered `<h1>`–`<h6>` (shifted by `heading-offset`). |\n| `img` | Forwarded from the composed `<lr-markdown-core>` in Markdown mode -- every rendered `<img>`. |\n| `inline-code` | Forwarded from the composed `<lr-markdown-core>` in Markdown mode -- every rendered inline `<code>` span (backtick spans, not fenced blocks). |\n| `link` | Forwarded from the composed `<lr-markdown-core>` in Markdown mode -- every rendered `<a>`. |\n| `list` | Forwarded from the composed `<lr-markdown-core>` in Markdown mode -- every rendered `<ul>`/`<ol>`. |\n| `math` | Forwarded from the composed `<lr-markdown-core>` in Markdown mode -- a rendered inline or block math span (`data-display=\"inline\"\\|\"block\"`). |\n| `paragraph` | Forwarded from the composed `<lr-markdown-core>` in Markdown mode -- every rendered `<p>`. |\n| `table` | Forwarded from the composed `<lr-markdown-core>` in Markdown mode -- every rendered `<table>`. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-inline-cursor-height` (default: `var(--lr-size-1em)`) — Shared height of the inline cursor bar.\n- `--lr-inline-cursor-width` (default: `var(--lr-size-0-125rem)`) — Shared width of the inline cursor bar (also its border radius).","attributes":[{"name":"coalesce-ms","description":"Trailing-edge coalesce window, in ms, for `content` updates -- see the\nclass doc.\n\nType: `number`  \nDefault: `50`","value":{"type":["number"]}},{"name":"content","description":"The full current text so far -- always the complete string, never a\ndelta to append.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"content-mode","description":"Rendering mode. `auto` uses `looksLikeMarkdown`; the other values force\ntheir named mode regardless of content.\n\nType: `StreamingTextContentMode`  \nDefault: `'auto'`","value":{"type":["'auto'","'plain'","'markdown'"]}},{"name":"gfm","description":"Forwarded verbatim to the composed Markdown element's own `gfm` -- GitHub-flavored Markdown\n(tables, strikethrough, autolinks, task lists). `true` (the default) matches the composed\nelement's own default.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"heading-anchors","description":"Forwarded verbatim to the composed Markdown element's own `headingAnchors`. `false` (the\ndefault) matches the composed element's own default.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"heading-offset","description":"Forwarded verbatim to the composed Markdown element's own `headingOffset`. `0` (the\ndefault) matches the composed element's own default.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"highlight-code","description":"Forwarded verbatim to the composed Markdown element's own `highlightCode`. `true` (the\ndefault) matches the composed element's own default.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"html-mode","description":"Forwarded verbatim to the composed Markdown element's own `htmlMode` -- how authored raw\nHTML is handled (`'sanitize'`, `'escape'`, or `'trusted'`). `'sanitize'` (the default)\nmatches the composed element's own default.\n\nType: `MarkdownHtmlMode`  \nDefault: `'sanitize'`","value":{"type":["'sanitize'","'escape'","'trusted'"]}},{"name":"internal-link-prefix","description":"Forwarded verbatim to the composed Markdown element's own `internalLinkPrefix`. Empty (the\ndefault) matches the composed element's own default -- every link is treated as external.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"link-target","description":"Forwarded verbatim to the composed Markdown element's own `linkTarget` -- the `target`\napplied to every rendered `<a>`, with `rel=\"noopener noreferrer\"` always added by the\ncomposed element alongside it whenever a `target` is emitted. `'_blank'` (the default)\nmatches the composed element's own default; set to `null` (or the empty string, e.g. via the\n`link-target=\"\"` attribute) to omit `target`/`rel` entirely so rendered links open in the\nsame tab.\n\nType: `string | null`  \nDefault: `'_blank'`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"math","description":"Forwarded verbatim to the composed Markdown element's own `math`. `false` (the default)\nmatches the composed element's own default.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"max-height","description":"Forwarded verbatim to the composed Markdown element's own `maxHeight`. Empty (the default)\nmatches the composed element's own default -- the rendered document never scrolls\ninternally.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"streaming","description":"Shows the blinking cursor after the rendered text. Reflects, so a host\ncan also target `[streaming]` in CSS.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"tab-size","description":"Forwarded verbatim to the composed Markdown element's own `tabSize` -- the tab-stop width\nused to expand tabs in leading indentation before parsing. `4` (the default) matches the\ncomposed element's own default.\n\nType: `number`  \nDefault: `4`","value":{"type":["number"]}}],"js":{"properties":[{"name":"coalesceMs","description":"Trailing-edge coalesce window, in ms, for `content` updates -- see the\nclass doc.\n\nAttribute: `coalesce-ms`","type":"number","default":"50"},{"name":"content","description":"The full current text so far -- always the complete string, never a\ndelta to append.\n\nAttribute: `content`","type":"string","default":"''"},{"name":"contentMode","description":"Rendering mode. `auto` uses `looksLikeMarkdown`; the other values force\ntheir named mode regardless of content.\n\nAttribute: `content-mode`  \nReflected to its attribute.","type":"StreamingTextContentMode","default":"'auto'"},{"name":"gfm","description":"Forwarded verbatim to the composed Markdown element's own `gfm` -- GitHub-flavored Markdown\n(tables, strikethrough, autolinks, task lists). `true` (the default) matches the composed\nelement's own default.\n\nAttribute: `gfm`","type":"boolean","default":"true"},{"name":"headingAnchors","description":"Forwarded verbatim to the composed Markdown element's own `headingAnchors`. `false` (the\ndefault) matches the composed element's own default.\n\nAttribute: `heading-anchors`","type":"boolean","default":"false"},{"name":"headingOffset","description":"Forwarded verbatim to the composed Markdown element's own `headingOffset`. `0` (the\ndefault) matches the composed element's own default.\n\nAttribute: `heading-offset`","type":"number","default":"0"},{"name":"highlightCode","description":"Forwarded verbatim to the composed Markdown element's own `highlightCode`. `true` (the\ndefault) matches the composed element's own default.\n\nAttribute: `highlight-code`","type":"boolean","default":"true"},{"name":"htmlMode","description":"Forwarded verbatim to the composed Markdown element's own `htmlMode` -- how authored raw\nHTML is handled (`'sanitize'`, `'escape'`, or `'trusted'`). `'sanitize'` (the default)\nmatches the composed element's own default.\n\nAttribute: `html-mode`","type":"MarkdownHtmlMode","default":"'sanitize'"},{"name":"internalLinkPrefix","description":"Forwarded verbatim to the composed Markdown element's own `internalLinkPrefix`. Empty (the\ndefault) matches the composed element's own default -- every link is treated as external.\n\nAttribute: `internal-link-prefix`","type":"string","default":"''"},{"name":"languages","description":"Forwarded verbatim to the composed Markdown element's own `languages` -- a fine-grained,\nexplicit language-grammar bundle scoping shiki's build output to just those grammars. Unset\nleaves the composed element's own default untouched: the full variant falls back to its\n~200-language dynamic-import table, the core variant renders unmatched fences as plain text.","type":"Readonly<Record<string, ShikiLanguageInput>> | undefined"},{"name":"linkTarget","description":"Forwarded verbatim to the composed Markdown element's own `linkTarget` -- the `target`\napplied to every rendered `<a>`, with `rel=\"noopener noreferrer\"` always added by the\ncomposed element alongside it whenever a `target` is emitted. `'_blank'` (the default)\nmatches the composed element's own default; set to `null` (or the empty string, e.g. via the\n`link-target=\"\"` attribute) to omit `target`/`rel` entirely so rendered links open in the\nsame tab.\n\nAttribute: `link-target`","type":"string | null","default":"'_blank'"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"math","description":"Forwarded verbatim to the composed Markdown element's own `math`. `false` (the default)\nmatches the composed element's own default.\n\nAttribute: `math`","type":"boolean","default":"false"},{"name":"maxHeight","description":"Forwarded verbatim to the composed Markdown element's own `maxHeight`. Empty (the default)\nmatches the composed element's own default -- the rendered document never scrolls\ninternally.\n\nAttribute: `max-height`","type":"string","default":"''"},{"name":"streaming","description":"Shows the blinking cursor after the rendered text. Reflects, so a host\ncan also target `[streaming]` in CSS.\n\nAttribute: `streaming`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"tabSize","description":"Forwarded verbatim to the composed Markdown element's own `tabSize` -- the tab-stop width\nused to expand tabs in leading indentation before parsing. `4` (the default) matches the\ncomposed element's own default.\n\nAttribute: `tab-size`","type":"number","default":"4"}],"events":[{"name":"lr-content-settled","description":"Fired after newly-coalesced content actually reaches the rendered DOM (plain-text mode only -- see `<lr-streaming-text>`'s class doc). `detail: null`.","type":"CustomEvent<null>"}]}},{"name":"lr-subagent-panel","description":"`<lr-subagent-panel>` — a controlled hierarchy of nested agent runs with lifecycle status,\ntask/model context, progress, selection, cancellation, and retry intents. Runs with empty ids\nare omitted and later duplicate ids are ignored before hierarchy, focus, counts, and events.\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: `7.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| `actions` | Run actions. |\n| `base` | The named subagent region. |\n| `cancel` | Cancellation action. |\n| `empty` | The empty state. |\n| `label` | Run label. |\n| `limit` | Resource-ceiling status shown when additional runs are omitted. |\n| `list` | Hierarchical run list. |\n| `model` | Caller-supplied model id. |\n| `progress` | Progress indicator. |\n| `retry` | Retry action. |\n| `run` | One run. |\n| `run-row` | Run content and actions. |\n| `run-selected` | The selected run. |\n| `run-trigger` | Run selection action. |\n| `status` | Lifecycle status badge. |\n| `task` | Caller-supplied task text. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-subagent-panel-background` (default: `var(--lr-color-surface)`) — Resting fill of each run row's trigger and action buttons. Hover and press follow `--lr-subagent-panel-hover-background`, so retune both together.\n- `--lr-subagent-panel-border-color` (default: `var(--lr-color-border)`) — Colour of each run row's border and of its action divider. A selected row still uses `--lr-subagent-panel-selected-border`.\n- `--lr-subagent-panel-compact-action-padding` (default: `var(--lr-space-2xs)`) — `[part=\"cancel\"]`/ `[part=\"retry\"]` padding while `compact`.\n- `--lr-subagent-panel-compact-font-size` (default: `var(--lr-font-size-2xs)`) — `[part=\"task\"]`/ `[part=\"model\"]` font size while `compact`.\n- `--lr-subagent-panel-compact-trigger-gap` (default: `var(--lr-space-2xs)`) — Gap between `[part=\"run-trigger\"]`'s label/status/task/model/progress while `compact`.\n- `--lr-subagent-panel-compact-trigger-padding` (default: `var(--lr-space-2xs) var(--lr-space-s)`) — `[part=\"run-trigger\"]` padding while `compact`.\n- `--lr-subagent-panel-hover-background` (default: `var(--lr-color-surface-raised)`) — Hovered fill of each run row's trigger and action buttons. The pressed fill is this value mixed a further `--lr-color-mix-active` toward `--lr-color-mix-partner`, so retuning hover carries the press with it.\n- `--lr-subagent-panel-progress-fill` (default: `var(--lr-color-brand)`) — Progress fill.\n- `--lr-subagent-panel-progress-track` (default: `var(--lr-color-border)`) — Progress track.\n- `--lr-subagent-panel-radius` (default: `var(--lr-radius)`) — Corner radius of each run row. `frame=\"plain\"` still squares the corners.\n- `--lr-subagent-panel-selected-border` (default: `var(--lr-color-brand)`) — Selected run border.","attributes":[{"name":"compact","description":"Tighter run-row padding/gaps and smaller task/model text -- same convention as\n`lr-task-list`/`lr-stack-trace`/`lr-thinking-panel`/`lr-terminal`'s `compact`. Defaults to\n`false`, i.e. full padding. Purely a density knob: each row's own border stays, so use\n`frame=\"plain\"` instead to drop the chrome entirely.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"frame","description":"Visual chrome for each run row, in the library's shared container-frame vocabulary. `'card'`\n(the default) keeps each row's own border/radius; `'plain'` drops it, for a transcript or\nmessage-bubble context that already draws its own border around a nested\n`<lr-subagent-panel>` and would otherwise double it.\n\nType: `LyraFrame`  \nDefault: `'card'`","value":{"type":["'card'","'plain'"]}},{"name":"label","description":"Optional accessible-name override for the `role=\"tree\"` element. Omission localizes the\ndefault; any supplied string, including `''`, is rendered verbatim.\n\nType: `string | undefined`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"selected-run-id","description":"Type: `string | null`  \nDefault: `null`"}],"js":{"properties":[{"name":"compact","description":"Tighter run-row padding/gaps and smaller task/model text -- same convention as\n`lr-task-list`/`lr-stack-trace`/`lr-thinking-panel`/`lr-terminal`'s `compact`. Defaults to\n`false`, i.e. full padding. Purely a density knob: each row's own border stays, so use\n`frame=\"plain\"` instead to drop the chrome entirely.\n\nAttribute: `compact`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"frame","description":"Visual chrome for each run row, in the library's shared container-frame vocabulary. `'card'`\n(the default) keeps each row's own border/radius; `'plain'` drops it, for a transcript or\nmessage-bubble context that already draws its own border around a nested\n`<lr-subagent-panel>` and would otherwise double it.\n\nAttribute: `frame`  \nReflected to its attribute.","type":"LyraFrame","default":"'card'"},{"name":"label","description":"Optional accessible-name override for the `role=\"tree\"` element. Omission localizes the\ndefault; any supplied string, including `''`, is rendered verbatim.\n\nAttribute: `label`","type":"string | undefined"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"runs","type":"readonly SubagentRun[]","default":"[]"},{"name":"selectedRunId","description":"Attribute: `selected-run-id`","type":"string | null","default":"null"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-cancel","description":"Cancellation was requested for an active run.","type":"CustomEvent<LyraEventDetailSnapshot<{ runId: string }>>"},{"name":"lr-run-activate","description":"A complete subagent run was activated. `detail: { runId, run }`.","type":"CustomEvent<LyraEventDetailSnapshot<AgentRunActivateDetail<SubagentRun>>>"},{"name":"lr-run-retry","description":"Retry was requested for an errored/cancelled run.","type":"CustomEvent<LyraEventDetailSnapshot<{ runId: string }>>"}]}},{"name":"lr-suggestion-chips","description":"`<lr-suggestion-chips>` — starter prompts (empty thread) and follow-up suggestions (after a\nresponse) as a horizontally scrollable chip row; activation hands the prompt to the host, which\ndecides whether to compose it into an input or send it directly. Never writes into a composer or\nsends anything itself.\n\nStreaming-friendly: chips render through a keyed `repeat()` on `suggestionId`, so replacing\nfollow-ups mid-conversation preserves focus on any chip whose identifier survives. Identifiers\nmust be nonempty and unique; invalid and later duplicate entries are omitted deterministically.\nSuggestions are a clone-owned, bounded readonly snapshot; create and reassign a new array after\nchanging the sequence or a row.\n\nA suggestion may also set `disabled`, marking it non-actionable: its chip renders a genuinely\ndisabled `<button>` (no roving tab stop, no hover/press affordance) and activating it -- by click\nor keyboard -- emits nothing and changes no state. Arrow-key/Home/End roving navigation steps\npast it instead of landing on it. Omitted or `false` renders the chip exactly as before this\nfield existed.\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 labeled group. |\n| `chip` | Each suggestion button. |\n| `chip-detail` | The secondary line (only rendered when `detail` is set). |\n| `chip-icon` | Optional decorative literal icon. |\n| `chip-label` | The primary text. |\n| `row` | The flex container holding the chips, in both the wrapping and the scrolling layout. Style this to change how chip lines pack (`justify-content`, `row-gap`). |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-suggestion-chips-disabled-opacity` (default: `0.5`) — Opacity of a chip whose suggestion sets `disabled`.\n- `--lr-suggestion-chips-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Background of a hovered chip.\n- `--lr-suggestion-chips-hover-border` (default: `var(--lr-color-brand)`) — Border color of a hovered chip.\n- `--lr-suggestion-chips-justify` (default: `flex-start`) — Main-axis packing of the chip row. `center` centers every line, the wrapped final one included — what `::part(base)` alone cannot do.","attributes":[{"name":"label","description":"Accessible name for the group. Optional. Omitting it localizes the default `suggestionsLabel`\nmessage; an explicit empty string renders no visible/accessible label.\n\nType: `string | undefined`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"wrap","description":"Wraps into multiple rows instead of a single horizontally scrollable line.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"js":{"properties":[{"name":"label","description":"Accessible name for the group. Optional. Omitting it localizes the default `suggestionsLabel`\nmessage; an explicit empty string renders no visible/accessible label.\n\nAttribute: `label`","type":"string | undefined"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"suggestions","description":"The clone-owned suggestions to render, in order. `suggestionId` must be unique and nonempty;\nthe first valid occurrence wins. Empty renders nothing at all. Reassign a new array after\nchanges.","type":"readonly LyraChatSuggestion[]","default":"[]"},{"name":"wrap","description":"Wraps into multiple rows instead of a single horizontally scrollable line.\n\nAttribute: `wrap`  \nReflected to its attribute.","type":"boolean","default":"false"}],"events":[{"name":"lr-suggestion-select","description":"`detail: { suggestionId, label }`.","type":"CustomEvent<{ suggestionId: string; label: string }>"}]}},{"name":"lr-svg-viewer","description":"Fetches and safely renders an inline SVG document. Author styles, SVG animation elements, and\nexternal resource/paint-server references are removed before insertion; local fragment paint\nservers and embedded raster data remain available without secondary network requests.\n\nAdopts `DocumentAnchorTarget`: a `region` anchor addresses one `highlights` entry by reference\nor structural equality of its `rect` (and optional `page`) -- `scrollToAnchor()`/a declarative\n`anchor` assignment scrolls the matching `[part=\"region-highlight\"]` into view and fires\n`lr-anchor-result`. No other anchor kind resolves here -- a sanitized SVG document has neither\npages nor extractable text to quote. At most 100 valid region highlights are painted from a\n1,000-entry candidate window; `activeHighlightId` is retained from anywhere in the bounded host\nsnapshot and placed first inside both paint ceilings.\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| `anchor-live-region` | The aria-hidden, non-live shadow mirror of the latest anchor-jump message. |\n| `base` | The root container. It owns `role=\"img\"` only for passive loaded SVG content; idle, loading, error, zoomable, and interactive-highlight states use `role=\"region\"` so their descendant state text and controls remain exposed to assistive technology. |\n| `body` | The wrapper around the fetched-state content. |\n| `error` | Visible ordinary error text; transitions announce through the shared document-level assertive region. |\n| `frame-content` | Forwarded from the internal `<lr-pan-zoom>` when `zoomable`. |\n| `frame-controls` | Forwarded from the internal `<lr-pan-zoom>` when `zoomable`. |\n| `frame-reset` | Forwarded from the internal `<lr-pan-zoom>` when `zoomable`. |\n| `frame-viewport` | Forwarded from the internal `<lr-pan-zoom>` when `zoomable`. |\n| `frame-zoom-in` | Forwarded from the internal `<lr-pan-zoom>` when `zoomable`. |\n| `frame-zoom-out` | Forwarded from the internal `<lr-pan-zoom>` when `zoomable`. |\n| `highlight-actions` | Non-overlapping actions used for multiple region highlights. |\n| `highlight-layer` | The wrapper around every rendered region highlight. |\n| `region-highlight` | One region highlight (`data-tone`, `data-active`). |\n| `region-highlight-action` | One non-overlapping highlight action. |\n| `region-highlight-target` | Transparent activation geometry around a region highlight, with a minimum pointer/focus area independent of the visual rectangle. |\n| `spinner` | Visible ordinary loading content with a motion-safe progress indicator; transitions announce through the shared document-level polite region. |\n| `svg` | The sanitized SVG document, once loaded. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-svg-viewer-max-height` (default: `none`) — Maximum block size of the scrollable body before it scrolls internally. Also settable via the `max-height` property.\n- `--lr-svg-viewer-active-border` (default: `var(--lr-color-warning, var(--lr-color-brand))`) — Border color of the `[part=\"region-highlight\"]` matching `activeHighlightId`. Distinct from the resting highlight border, so the active region can be recolored without touching the rest.\n- `--lr-svg-viewer-highlight-accent-color` (default: `var(--lr-color-brand)`) — Accent highlight border and hover tint.\n- `--lr-svg-viewer-highlight-success-color` (default: `var(--lr-color-success)`) — Success highlight border and hover tint.\n- `--lr-svg-viewer-highlight-warning-color` (default: `var(--lr-color-warning)`) — Warning highlight border and hover tint.\n- `--lr-svg-viewer-highlight-danger-color` (default: `var(--lr-color-danger)`) — Danger highlight border and hover tint.\n- `--lr-svg-viewer-highlight-neutral-color` (default: `var(--lr-color-neutral)`) — Neutral highlight border and hover tint.","attributes":[{"name":"active-highlight-id","description":"Id of the currently active highlight, or null when none is active.\n\nType: `string | null`  \nDefault: `null`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max-height","description":"CSS length that caps the scrollable body. Fitting content stays centered; overflowing\nSVG content starts inside the reachable scroll range. Invalid values are ignored.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"name","description":"Accessible name for the rendered SVG surface. The surface is an image while passive and a\nregion when zoom controls or highlight actions make it interactive.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"src","description":"URL to fetch and render as sanitized inline SVG.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"zoomable","description":"Wraps the rendered content in an internal `<lr-pan-zoom>`. `false` (the default)\npreserves today's exact DOM -- an inline thumbnail (e.g. in a chat stream) must not\nunexpectedly grow a focusable zoom-chrome viewport; an inspection surface opts in.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"js":{"properties":[{"name":"activeHighlightId","description":"Id of the currently active highlight, or null when none is active.\n\nAttribute: `active-highlight-id`","type":"string | null","default":"null"},{"name":"anchor","description":"Anchor or highlight id to resolve and scroll into view.","type":"LyraAnchor | string | null","default":"null"},{"name":"anchorKinds","description":"Anchor kinds this viewer resolves via `scrollToAnchor()`. `highlights`/`activeHighlightId`/\n`anchor` are inherited from `DocumentAnchorTarget` -- display-only, no creation UI here.","type":"readonly LyraAnchorKind[]","default":"['region']","read-only":true},{"name":"highlights","description":"Highlights rendered by the document target. Reassign after mutation.","type":"LyraHighlight[]","default":"[]"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"maxHeight","description":"CSS length that caps the scrollable body. Fitting content stays centered; overflowing\nSVG content starts inside the reachable scroll range. Invalid values are ignored.\n\nAttribute: `max-height`","type":"string","default":"''"},{"name":"name","description":"Accessible name for the rendered SVG surface. The surface is an image while passive and a\nregion when zoom controls or highlight actions make it interactive.\n\nAttribute: `name`","type":"string","default":"''"},{"name":"src","description":"URL to fetch and render as sanitized inline SVG.\n\nAttribute: `src`","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"zoomable","description":"Wraps the rendered content in an internal `<lr-pan-zoom>`. `false` (the default)\npreserves today's exact DOM -- an inline thumbnail (e.g. in a chat stream) must not\nunexpectedly grow a focusable zoom-chrome viewport; an inspection surface opts in.\n\nAttribute: `zoomable`  \nReflected to its attribute.","type":"boolean","default":"false"}],"events":[{"name":"lr-anchor-result","description":"Fired after an `anchor` property assignment or a `scrollToAnchor()` call is applied. `detail: { found }`.","type":"CustomEvent<AnchorResultDetail>"},{"name":"lr-highlight-activate","description":"A region highlight was activated. `detail: { highlightId }`.","type":"CustomEvent<HighlightActivateDetail>"},{"name":"lr-render-error","description":"Fired when fetching or sanitizing the document fails.","type":"CustomEvent<{ error: unknown }>"}]}},{"name":"lr-swatch-picker","description":"`<lr-swatch-picker>` -- a single-select picker over a small, fixed set of color swatches with\nthe WAI-ARIA APG `radiogroup` contract built in: `role=\"radiogroup\"`/`role=\"radio\"`, roving\ntabindex, automatic activation (click or arrow-key move both select immediately, like a native\nradio group), cyclic Arrow/Home/End navigation. Distinct from `<lr-color-picker>`'s freeform\nnative color input -- this picks exactly one of N designer-chosen named colors, the shape apps\notherwise hand-roll as a row of round accent-color buttons.\n\n`mode=\"gemstone\"` uses the shared faceted gemstone glyph for items carrying a `gemstone`\nkey and opts into the gemstone glow/shine defaults. The checked swatch's automatic glyph is\nthemed by the exact same `gemstoneSelectedGlyphStyles` stylesheet exported from\n`theme/gemstones.js`, included here in `static styles` and applied through the same\n`data-lr-gemstone-selected` attribute documented on that export -- so a glyph rendered anywhere\nelse on the page (for example a header trigger showing the current selection) can reach the\nidentical halo/shine by consuming that export directly, and the two can never drift apart. An\nexplicit `icon` override on a `mode=\"gemstone\"` item is a consumer-authored shape, not that\nshared glyph, so it keeps this picker's own generic selected-icon shine instead (see\n`--lr-swatch-picker-gemstone-selected-blur`/`-shine-duration` below). The `items` array controls\ndisplay order and `value` still controls the initial selection. Live option reorders preserve\nfocus by option identity; removing the focused option moves focus to the nearest surviving\nswatch without changing the controlled `value` or emitting `lr-change`.\n\n`disabled` locks the whole picker: every swatch renders as a real `disabled` `<button>` (out of\nthe tab sequence, inert to activation), keyboard navigation and `click()` become no-ops, and the\nswatches dim with a `not-allowed` cursor. It is the picker's own attribute only — this control is\ndeliberately not form-associated (it submits nothing, carries no `name`, validity or reset\nsemantics), so an ancestor `<fieldset disabled>` does not cascade into it.\n\nOwn `disabled` takes effect immediately for host activation and focus, including calls made in\nthe same task as the property change. Blocked activation leaves value and change events untouched;\nblocked focus keeps outside focus in place.\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 `role=\"radiogroup\"` root. |\n| `swatch` | A single `role=\"radio\"` color swatch's interactive hit target; sized via `--lr-swatch-picker-hit-size` (its private default follows `size` and is floored at 24px), independent of the smaller visible fill/icon rendered inside it. A public value wins. The selected one is `[part='swatch'][aria-checked='true']`. |\n| `swatch-fill` | The compact filled circle rendered when the option has no custom `icon`. |\n| `swatch-icon` | Optional decorative custom shape supplied by the option's `icon` field; its subtree is inert and hidden from assistive technology. When present it replaces `swatch-fill` and the swatch renders unfilled/unbordered behind it. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-swatch-picker-fill-size` (default: `var(--lr-theme-swatch-picker-fill-size, var(--lr-size-1-5rem))`) — Visible fill/icon diameter for the swatch. Its private default follows the active tier. Set `--lr-theme-swatch-picker-fill-size` on an ancestor to give every tier a shared default, or set this component hook on an ancestor/direct host to override every tier.\n- `--lr-swatch-picker-gap` (default: `var(--lr-space-xs)`) — Gap between swatches.\n- `--lr-swatch-picker-gemstone-selected-blur` (default: `var(--lr-gemstone-selected-blur, var(--lr-size-0-5rem))`) — Selected glow blur used by `mode=\"gemstone\"` when `--lr-swatch-picker-selected-blur` is not overridden. Applies to a plain color-fill swatch and to a consumer-supplied `icon` override; the automatic gemstone glyph itself is themed by `--lr-gemstone-selected-blur` directly (see `theme/gemstones.js`'s `gemstoneSelectedGlyphStyles`), which this hook's own default now aliases so the two cannot silently drift apart.\n- `--lr-swatch-picker-gemstone-shine-duration` (default: `var(--lr-gemstone-selected-shine-duration, var(--lr-transition-ambient))`) — Selected shine timing used by `mode=\"gemstone\"` when `--lr-swatch-picker-shine-duration` is not overridden. Same scope and aliasing as `--lr-swatch-picker-gemstone-selected-blur` above.\n- `--lr-swatch-picker-hit-size` (default: `var(--lr-size-2-5rem)`) — Hit-area size (both min-inline-size and min-block-size) for the swatch button. Its private default follows the active tier and is floored at 24px; an inherited or direct public value wins.\n- `--lr-swatch-picker-selected-blur` (default: `0`) — Blur radius of that same ring. 0 by default (a crisp ring); set a real length (e.g. 0.4rem) for a soft glow instead.\n- `--lr-swatch-picker-selected-color` (default: `var(--lr-color-brand)`) — Ring color drawn around the selected swatch, themeable independently of the focus ring and every other ring color.\n- `--lr-swatch-picker-shine-duration` (default: `0s`) — Duration of a rhythmic brighten-and-settle \"shine\" on the selected swatch. `0s` (the default) is a no-op -- today's static look for every existing consumer. Set a real duration (e.g. 1.6s) for a pulsing shine; disabled outright under `prefers-reduced-motion: reduce`. Independent of `--lr-swatch-picker-selected-blur` (a separate `filter: brightness()` animation, not `box-shadow`), so the two compose freely, and works identically for a plain color circle and an icon swatch alike.\n- `--lr-swatch-picker-wrap` (default: `wrap`) — `flex-wrap` on the swatch row. Reproduces today's hardcoded wrapping row by default; set `nowrap` to confine every swatch to a single row (e.g. inside a fixed-width popover panel whose height must not shift from a second row).","attributes":[{"name":"aria-label","description":"Accessible-name fallback for the radiogroup when the host has no `aria-label`, used when no\nvisible label context exists around it (e.g. no wrapping `<label>` or adjacent heading).\nThe resolved name is set on the `role=\"radiogroup\"` element.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"disabled","description":"Locks the whole picker: every rendered swatch becomes a genuinely `disabled` `<button>` (so\nit leaves the tab sequence and stops emitting activation), arrow/Home/End navigation and\n`click()` become no-ops, and the swatches dim to `--lr-opacity-disabled` with a `not-allowed`\ncursor. Use it for the usual \"locked while saving\" case.\n\nThis is the picker's OWN attribute only. `<lr-swatch-picker>` is deliberately not a\nform-associated element — it emits `lr-change` and is driven by `value`, but it submits\nnothing and has no name, validity or reset semantics — so, exactly like a native `<div>`,\nit takes no disablement from an ancestor `<fieldset disabled>`. Disable the picker itself\nalongside the fieldset when a form needs both.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"mode","description":"Type: `LyraSwatchPickerMode`","value":{"type":["'swatch'","'gemstone'"]}},{"name":"size","description":"Visual size — scales the swatch hit-area and fill diameter proportionally, hit-area\nfloored at 24px (WCAG 2.5.8); not pixel-matched to `lr-input`'s row-height scale. The Web Awesome / Shoelace spellings\n`small`/`medium`/`large` are accepted for `s`/`m`/`l`, so a migration is a tag rename with no\nattribute rewrite.\n\nType: `LyraSize`  \nDefault: `'m'`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}},{"name":"value","description":"The currently selected option's `value`, or `null` when nothing is selected.\n\nType: `string | null`  \nDefault: `null`"}],"js":{"properties":[{"name":"accessibleLabel","description":"Accessible-name fallback for the radiogroup when the host has no `aria-label`, used when no\nvisible label context exists around it (e.g. no wrapping `<label>` or adjacent heading).\nThe resolved name is set on the `role=\"radiogroup\"` element.\n\nAttribute: `aria-label`","type":"string","default":"''"},{"name":"disabled","description":"Locks the whole picker: every rendered swatch becomes a genuinely `disabled` `<button>` (so\nit leaves the tab sequence and stops emitting activation), arrow/Home/End navigation and\n`click()` become no-ops, and the swatches dim to `--lr-opacity-disabled` with a `not-allowed`\ncursor. Use it for the usual \"locked while saving\" case.\n\nThis is the picker's OWN attribute only. `<lr-swatch-picker>` is deliberately not a\nform-associated element — it emits `lr-change` and is driven by `value`, but it submits\nnothing and has no name, validity or reset semantics — so, exactly like a native `<div>`,\nit takes no disablement from an ancestor `<fieldset disabled>`. Disable the picker itself\nalongside the fieldset when a form needs both.\n\nAttribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"items","description":"The selectable color swatches, in display order.","type":"readonly SwatchPickerItem[]"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"mode","description":"Attribute: `mode`  \nReflected to its attribute.","type":"LyraSwatchPickerMode"},{"name":"size","description":"Visual size — scales the swatch hit-area and fill diameter proportionally, hit-area\nfloored at 24px (WCAG 2.5.8); not pixel-matched to `lr-input`'s row-height scale. The Web Awesome / Shoelace spellings\n`small`/`medium`/`large` are accepted for `s`/`m`/`l`, so a migration is a tag rename with no\nattribute rewrite.\n\nAttribute: `size`  \nReflected to its attribute.","type":"LyraSize","default":"'m'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"value","description":"The currently selected option's `value`, or `null` when nothing is selected.\n\nAttribute: `value`","type":"string | null","default":"null"}],"events":[{"name":"lr-activate","description":"Fired on every activation of a swatch -- a click, or an Arrow/Home/End key that lands on one -- whether or not the selection actually moved. `detail: { value }` carries the activated swatch's own value. Bubbling and composed, so a host outside the shadow tree receives it. Not cancelable: it is a notification that the user picked a swatch, not a veto point, and nothing in this component branches on it. Re-picking the current value is the case `lr-change` deliberately stays silent for, and it is otherwise unobservable -- the swatches live in this shadow root, so a retargeted `click` names no swatch, and keyboard activation (Home on an already-first selection, End on an already-last one, an arrow key in a one-item row) produces no click at all. When an activation does move the selection, `lr-change` is emitted first, so a listener reading `value` from either event sees the settled selection.","type":"CustomEvent<{ value: string }>"},{"name":"lr-change","description":"Fired when the selected value changes via click or keyboard. `detail: { value }`.","type":"CustomEvent<{ value: string }>"}]}},{"name":"lr-switch","description":"`<lr-switch>` — a boolean toggle-switch form control. Structurally the\nsame idea as a checkbox (form-associated via `ElementInternals`, click and\nSpace toggle) but with switch semantics: `role=\"switch\"` +\n`aria-checked` read to assistive tech as an on/off state rather than a\nchecked/unchecked one, and there is no indeterminate state.\n\n`checked` is not a plain string, so this attaches `ElementInternals`\ndirectly and implements its own `updateValidity()` rather than using the\n`FormAssociated` mixin (that mixin's `value` accessor assumes a string —\nsee `<lr-combobox>` for the same direct-`ElementInternals` shape with a\nnon-string value).\n\nShips an opt-in `hint`/`errorText` form-control chrome (props + matching named slots +\n`hint`/`error` CSS parts), mirroring `<lr-select>`'s pattern for those two pieces -- left\nunset, neither renders. Deliberately no separate top-of-field `label` prop/slot/part mirroring\n`<lr-select>`'s `form-control-label`: the default slot already *is* this control's visible,\nclickable label (same as `<lr-checkbox>`), so a second label surface would be redundant.\nIts wrapper follows flattened rendered assignment and updates through forwarding slots. Visual\nelements, including decorative `aria-hidden` icons, retain the wrapper independently of their\naccessibility-tree contribution.\n\nHost `aria-describedby` references resolve onto the internal switch before its local error/hint\nguidance, tracking target changes, reconnect and document adoption. Removing `hint`, `help-text`\nor `error-text` safely omits the content while preserving native null property readback.\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) | Label text, rendered next to the track. Clicking it toggles the switch, the same as clicking a checkbox's associated `<label>`. If left empty, set `aria-label` on the host so the control still has an accessible name. Host `aria-label` is forwarded by presence, including an explicitly empty value. |\n| `error` | Custom error content. |\n| `help-text` | Shoelace alias for `hint`. |\n| `hint` | Custom hint content. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | Compatibility name for the semantic switch owner; use `switch`. |\n| `control` | WA/Shoelace name for the same pill-shaped background. |\n| `error` | The error message. |\n| `form-control` | The outer wrapper around the switch, error and hint. |\n| `form-control-help-text` | Shoelace name for the same hint message. |\n| `hint` | The hint message. |\n| `label` | The wrapper around the default slot. |\n| `row` | The row wrapping the switch owner and the label as siblings. This is the node to size or align when laying out a column of switches; `base`/`switch` is only the track box inside it, so its inline size tracks the track, not the row. |\n| `switch` | The interactive `role=\"switch\"` owner around the track, with the rich default label as a sibling so nested actions remain valid focus stops. |\n| `thumb` | The circular knob that slides across the track. |\n| `track` | The pill-shaped background. |\n| `wrapper` | Compatibility name on the semantic switch owner. |\n\n---\n\n**CSS Custom Properties**\n\n- `--height` (default: `var(--lr-switch-track-block-size)`) — WA/Shoelace alias for the track's block size.\n- `--lr-switch-checked-label-color` (default: `var(--lr-switch-label-color)`) — Text color of `[part='label']` while checked, independently themeable from the unchecked color.\n- `--lr-switch-checked-thumb-fill` (default: `var(--lr-switch-thumb-fill)`) — Thumb fill while checked, independently themeable from the unchecked fill.\n- `--lr-switch-checked-track-border` (default: `var(--lr-switch-track-border)`) — Border of `[part='track']` while checked, independently themeable from the unchecked border, so a bordered track can differ by state without reaching for `::part(track)` plus the `checked` custom state. Takes a whole `border` shorthand value, like `--lr-switch-track-border`; give both states the same border *width* unless a size change between them is what you want, since the track is `box-sizing: content-box` and a border grows its outer footprint.\n- `--lr-switch-checked-track-fill` (default: `var(--lr-color-brand)`) — Track fill while checked.\n- `--lr-switch-gap` (default: `var(--lr-space-s)`) — Gap between the track and label.\n- `--lr-switch-label-color` (default: `var(--lr-color-text)`) — Text color of `[part='label']`, and the checked-state fallback when `--lr-switch-checked-label-color` is unset.\n- `--lr-switch-thumb-fill` (default: `var(--lr-color-surface)`) — Thumb fill while unchecked, and the checked-state fallback when `--lr-switch-checked-thumb-fill` is unset.\n- `--lr-switch-thumb-offset` (default: `var(--lr-size-2px)`) — Inset of the thumb from the track's edges.\n- `--lr-switch-track-active-fill` (default: `color-mix(...)`) — Track fill while pressed.\n- `--lr-switch-track-block-size` (default: `calc(var(--lr-form-control-height) * 0.5)`) — Block size of the track, half the `size` tier's shared control height; the thumb's diameter is derived from it minus twice `--lr-switch-thumb-offset`.\n- `--lr-switch-track-border` — Border of `[part='track']`, and the checked-state fallback when `--lr-switch-checked-track-border` is unset. Undeclared by default (no border renders at all), matching today's chrome.\n- `--lr-switch-track-fill` (default: `var(--lr-color-border)`) — Resting fill of `[part='track']`, used as the source for the hover and press fallbacks.\n- `--lr-switch-track-hover-fill` (default: `color-mix(...)`) — Track fill while hovered.\n- `--lr-switch-track-inline-size` (default: `calc(var(--lr-switch-track-block-size) * 1.8)`) — Inline size of the track, and (with the block size) the distance the thumb travels when checked. Derived from the block size, so re-sizing the track keeps its aspect ratio.\n- `--thumb-size` (default: `calc(var(--height, var(--lr-switch-track-block-size)) - (var(--lr-switch-thumb-offset) * 2))`) — WA/Shoelace thumb diameter alias.\n- `--width` (default: `var(--lr-switch-track-inline-size)`) — WA/Shoelace alias for the track's inline size.","attributes":[{"name":"checked","description":"Reflected current reset default; changing it never overwrites dirty live `checked` state.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"custom-error","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nType: `string | null`  \nDefault: `null`"},{"name":"disabled","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"error-text","description":"Error text below the switch (overridden by slotted `error` content). Unset: no error chrome\nrenders.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"form","description":"Type: `HTMLFormElement | string | null`  \nDefault: `null`"},{"name":"help-text","description":"Shoelace alias for hint. `hint` wins when both are supplied.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"hint","description":"Hint text below the switch. Unset: no hint chrome renders.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"name","description":"The form submission key, reflected synchronously for native form APIs.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"required","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"size","description":"Control size, on the library's shared ladder. Accepts both spellings of every tier —\n`2xs`/`xs`/`s`/`m`/`l`/`xl` and Web Awesome's `small`/`medium`/`large` — so migrating either way\nis a tag rename. Scales the track and thumb off the same `--lr-form-control-*` values\n`<lr-input>`/`<lr-select>`/`<lr-button>` use, so controls of one `size` line up in a row. The\nslotted label keeps the library's standard control-label type size at every tier; restyle it\nthrough `::part(label)` if you want it to track the control.\n\nType: `LyraSize`  \nDefault: `'m'`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}},{"name":"value","description":"Type: `string`","value":{"type":["string"]}},{"name":"with-hint","description":"WA SSR slot-presence hint used before light-DOM assignment can be inspected.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"","description":"Label text, rendered next to the track. Clicking it toggles the switch, the same as clicking a checkbox's associated `<label>`. If left empty, set `aria-label` on the host so the control still has an accessible name. Host `aria-label` is forwarded by presence, including an explicitly empty value."},{"name":"error","description":"Custom error content."},{"name":"help-text","description":"Shoelace alias for `hint`."},{"name":"hint","description":"Custom hint content."}],"js":{"properties":[{"name":"checked","description":"Attribute: `checked`","type":"boolean","default":"false"},{"name":"customError","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nAttribute: `custom-error`  \nReflected to its attribute.","type":"string | null","default":"null"},{"name":"defaultChecked","description":"Reflected current reset default; changing it never overwrites dirty live `checked` state.\n\nAttribute: `checked`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"disabled","description":"Attribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"effectiveDisabled","description":"Whether the control is disabled explicitly or by an ancestor fieldset.","type":"boolean","read-only":true},{"name":"errorText","description":"Error text below the switch (overridden by slotted `error` content). Unset: no error chrome\nrenders.\n\nAttribute: `error-text`","type":"string","default":"''"},{"name":"form","description":"Attribute: `form`  \nReflected to its attribute.","type":"HTMLFormElement | string | null","default":"null"},{"name":"helpText","description":"Shoelace alias for hint. `hint` wins when both are supplied.\n\nAttribute: `help-text`","type":"string","default":"''"},{"name":"hint","description":"Hint text below the switch. Unset: no hint chrome renders.\n\nAttribute: `hint`","type":"string","default":"''"},{"name":"labels","type":"NodeList","read-only":true},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"name","description":"The form submission key, reflected synchronously for native form APIs.\n\nAttribute: `name`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"required","description":"Attribute: `required`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"size","description":"Control size, on the library's shared ladder. Accepts both spellings of every tier —\n`2xs`/`xs`/`s`/`m`/`l`/`xl` and Web Awesome's `small`/`medium`/`large` — so migrating either way\nis a tag rename. Scales the track and thumb off the same `--lr-form-control-*` values\n`<lr-input>`/`<lr-select>`/`<lr-button>` use, so controls of one `size` line up in a row. The\nslotted label keeps the library's standard control-label type size at every tier; restyle it\nthrough `::part(label)` if you want it to track the control.\n\nAttribute: `size`  \nReflected to its attribute.","type":"LyraSize","default":"'m'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"validationMessage","type":"string","read-only":true},{"name":"validity","type":"ValidityState","read-only":true},{"name":"value","description":"Attribute: `value`  \nReflected to its attribute.","type":"string"},{"name":"willValidate","type":"boolean","read-only":true},{"name":"withHint","description":"WA SSR slot-presence hint used before light-DOM assignment can be inspected.\n\nAttribute: `with-hint`","type":"boolean","default":"false"}],"events":[{"name":"blur","description":"The internal switch control lost focus. Bridges the internal element's non-bubbling native `blur`, re-dispatched as bubbling and composed.","type":"FocusEvent"},{"name":"change","description":"Fired immediately after `input` for the same user toggle, matching the native checkbox/radio contract a form library expects from a boolean control.","type":"Event"},{"name":"focus","description":"The internal switch control received focus. Bridges the internal element's non-bubbling native `focus`, re-dispatched as bubbling and composed.","type":"FocusEvent"},{"name":"input","description":"The user toggled the switch; bubbling and composed like a native form event.","type":"InputEvent"},{"name":"lr-change","description":"Compatibility alias fired after `input` and `change` (click, Space, logical ArrowLeft/ArrowRight, or the programmatic `click()` activation path). `detail: { checked }`. Not fired for a plain `.checked` property assignment, `form.reset()`, session-state restoration, or a user toggle a listener refused through `lr-switch-toggle-request`.","type":"CustomEvent<{ checked: boolean }>"},{"name":"lr-input","description":"Prefixed compatibility alias for `input`; `detail: { checked }`.","type":"CustomEvent<{ checked: boolean }>"},{"name":"lr-invalid","description":"The switch failed a validity check. Cancelable: calling `preventDefault()` also cancels the native `invalid` event behind it, suppressing the browser's own validation bubble so an app can present the failure its own way.","type":"CustomEvent<null>"},{"name":"lr-switch-toggle-request","description":"A user toggle (click, Space, the logical arrow keys, or the programmatic `click()` activation path) is about to change `checked`; `detail: { checked }` carries the state the control *would* take, and `checked` itself still holds the old value while this dispatches. Cancelable: calling `preventDefault()` keeps the current state, so the switch never slides at all rather than sliding and snapping back, and none of `input`/`lr-input`/`change`/`lr-change` fire. A listener may instead resolve the request by assigning `checked` itself during the dispatch, which suppresses the built-in write the same way. Not fired for a programmatic `.checked` assignment, while the control is disabled, or for an arrow key that names the state the switch already holds.","type":"CustomEvent<{ checked: boolean }>"}]}},{"name":"lr-tab","description":"`<lr-tab>` — one tab in a `<lr-tab-group>`'s strip. Mirrors `wa-tab` / `sl-tab`.\n\nA declarative descriptor, not the interactive control: `<lr-tab-group>` renders the real\n`role=\"tab\"` button and projects this element's content into it, so the whole ARIA and\nroving-tabindex contract stays in one place. That means the content may be rich (an icon plus a\nlabel, a badge), but its direct element roots are inert while projected so the button remains the\nsole action. The group's real button gets only the default slot's accessibility-exposed flattened\ntext as its accessible name; author-hidden, inert, or CSS-hidden branches do not contribute.\n\nPair it with a `<lr-tab-panel>` whose `name` matches this element's `panel`.\n`closable` adds a localized visual close affordance. It shares the owning tab's single APG focus\nstop rather than nesting another interactive control inside the group's real tab button: click\nthe affordance, or press Delete while the real tab button is focused. Either path emits the\nnoncancelable `lr-close` notification without selecting or removing the tab; the owning\napplication decides whether and when to remove the matching tab and panel.\n\n---\n\n**Component metadata**\n\n- Status: `stable`\n- Since: `8.0.0`\n- Rationale: This tag entered Lyra as a stable public API with documented behavior, accessibility, and cross-browser support.\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 tab's visual label content. Its direct default-slot element roots are inert while the owning group projects them; their accessibility-exposed flattened text names the real tab button. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | Compatibility name for the tab content wrapper; use `tab`. |\n| `close-button` | The non-focusable visual close affordance shown when `closable` is true. |\n| `close-button__base` | Compatibility alias on the same close affordance as `close-button`. |\n| `tab` | The tab content wrapper. It is the same node as `base`. |","attributes":[{"name":"active","description":"Whether this tab is the active tab. The owning group keeps this synchronized for hydrated\nmarkup; setting it explicitly supplies the matching SSR hint.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"closable","description":"Shows a localized close affordance. Clicking it or pressing Delete on the focused owning tab\nemits `lr-close`; it never removes the tab. The visual affordance is non-focusable because the\ngroup projects it into the real tab button.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"disabled","description":"Removes the tab from keyboard navigation and prevents activation.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"panel","description":"The `name` of the `<lr-tab-panel>` this tab reveals.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"slots":[{"name":"","description":"The tab's visual label content. Its direct default-slot element roots are inert while the owning group projects them; their accessibility-exposed flattened text names the real tab button."}],"js":{"properties":[{"name":"active","description":"Whether this tab is the active tab. The owning group keeps this synchronized for hydrated\nmarkup; setting it explicitly supplies the matching SSR hint.\n\nAttribute: `active`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"closable","description":"Shows a localized close affordance. Clicking it or pressing Delete on the focused owning tab\nemits `lr-close`; it never removes the tab. The visual affordance is non-focusable because the\ngroup projects it into the real tab button.\n\nAttribute: `closable`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"disabled","description":"Removes the tab from keyboard navigation and prevents activation.\n\nAttribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"panel","description":"The `name` of the `<lr-tab-panel>` this tab reveals.\n\nAttribute: `panel`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-close","description":"Emitted when the close affordance is clicked or Delete is pressed on its focused owning tab. Bubbles, is composed, and is not cancelable; the component does not remove itself.","type":"CustomEvent<null>"}]}},{"name":"lr-tab-group","description":"`<lr-tab-group>` — a tab strip composed from direct `<lr-tab panel=\"x\">` and\n`<lr-tab-panel name=\"x\">` children. This is the one canonical child model shared with both\nmapped upstreams; the group assigns private projection slots itself so consumer markup remains\na mechanical tag rename.\n\nImplements the WAI-ARIA APG tabs pattern. With the default `activation=\"auto\"`, Left/Right\n(swapped under RTL, or Up/Down when `placement` is `start`/`end`) move focus *and* selection\ntogether; with `activation=\"manual\"` they move focus only and Enter/Space commits, which the APG\nrequires whenever revealing a panel is expensive. Removing a focused unselected tab silently\nrehomes focus to a survivor while retaining a valid selection and preserving outside focus.\nHome/End jump to the first/last enabled tab,\nand a roving `tabindex` follows the focused tab. An enabled closable `<lr-tab>` adds\n`aria-keyshortcuts=\"Delete\"` to that same real tab button; Delete routes the close request through\nthe descriptor so `lr-close` still targets `<lr-tab>`. The visual close affordance stays\nnon-focusable and accessibility-hidden, avoiding a nested interactive control. Rich `<lr-tab>`\ncontent is likewise inert while projected; only its accessibility-exposed, default-slot text\nnames the real tab button rather than leaving an interactive descendant inside it. Author\n`aria-hidden`, hidden, inert, and CSS-hidden branches never leak into that name, and visibility\nor text changes refresh it.\nA labeled direct tab without `panel` receives a stable synthetic panel key that cannot collide\nwith an authored tab or panel name. An unpaneled descriptor with no accessibility-exposed label\nis omitted instead of speaking that internal key; an explicitly paneled empty descriptor retains\nits authored panel name as the accessible fallback.\n\n**`inert` on a source child excludes its tab exactly as `disabled` does** — it never takes\nselection, never holds the roving `tabindex`, and arrow keys step past it — and the rendered tab\nbutton is itself marked `inert`, so a pointer cannot reach it either. Only the child's *own*\n`inert` counts: a whole group inerted by an open modal keeps its selection and panels intact.\n\n`defaultSlot` exposes the real unnamed shadow slot expected by mapped integrations. Lyra keeps\nit hidden because every accepted child is assigned to a deterministic named projection slot.\n\n**Overflow.** A horizontal tab row that does not fit stays natively scrollable and gains two\nscroll controls flanking the tablist inside `[part=\"nav\"]`, mirroring both upstreams. They are\nrendered only for a horizontal `placement` (a vertical strip scrolls in the block direction,\nwhich these controls do not address — the same restriction both upstreams apply) and are laid out\nonly while the tablist genuinely overflows, gated on the measurement the edge fade already uses,\nso a row that fits is never flanked by two dead buttons. `without-scroll-controls` (or Shoelace's\n`no-scroll-controls`) opts out, leaving the pre-8.0.0 behavior: native scrolling plus the fade.\nThe fade is deliberately kept alongside the controls — it says \"the row continues past this\nedge\", which the controls themselves cannot show, and both appear on exactly the same condition.\nBy default an inactive edge control is hidden once that direction has nothing left to scroll to.\nShoelace's `fixed-scroll-controls` keeps both controls present throughout an overflowing range;\nin that mode an exhausted control stays visible but remains a no-op. Edge state is measured in\nlogical coordinates, so controls and the one-sided fade remain truthful under RTL too.\nA vertical `start`/`end` nav stays shrinkable and is capped at\n`--lr-tab-group-vertical-nav-max-inline-size` (default `var(--lr-size-12rem)`), so long labels\nellipsize rather than consuming the panel's allocation.\n\n**The scroll controls are `aria-hidden=\"true\"` and `tabindex=\"-1\"`** — a pointer affordance only,\nmatching upstream. The tablist is already fully keyboard-scrollable without them: the roving\n`tabindex` puts every tab one arrow key away, and focusing a tab scrolls it into view. Adding two\ntab stops in the middle of the strip would therefore buy no capability and cost every keyboard\nuser two extra stops between the tabs and the panel. They still carry a localized `aria-label`,\nso the name is there for automation and for a consumer that chooses to expose them.\n\n---\n\n**Component metadata**\n\n- Status: `stable`\n- Since: `8.0.0`\n- Rationale: This tag entered Lyra as a stable public API with documented behavior, accessibility, and cross-browser support.\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) | Canonical `<lr-tab>`/`<lr-tab-panel>` pairs. |\n| `nav` | Upstream-compatible slot used by `<lr-tab>` descriptors. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `active-tab-indicator` | Indicator inside the active tab. |\n| `base` | Compatibility name for the root wrapper; use `tab-group`. |\n| `body` | Wrapper around all tab panels. |\n| `nav` | The row wrapping the tablist together with the two overflow scroll controls; mirrors the upstream part of the same name. |\n| `panel` | A single `role=\"tabpanel\"` wrapper (one per tab, hidden unless active). |\n| `scroll-button` | Shared part on both overflow scroll controls. |\n| `scroll-button--end` | Upstream modifier alias on `scroll-button-end`. |\n| `scroll-button--start` | Upstream modifier alias on `scroll-button-start`. |\n| `scroll-button-end` | The control that scrolls the tabs toward their inline end (\"next\" — the left-hand control under RTL). |\n| `scroll-button-glyph` | The chevron wrapper inside a scroll control. This is the element that mirrors under RTL; the icon itself never rotates. |\n| `scroll-button-start` | The control that scrolls the tabs toward their inline start (\"previous\" — the right-hand control under RTL). |\n| `scroll-button__base` | Export-compatible base name on both scroll controls. |\n| `tab` | A single tab button. |\n| `tab-group` | The root wrapper around the tablist and panels. It is the same node as `base`. |\n| `tablist` | The `role=\"tablist\"` row of tab buttons. |\n| `tabs` | Upstream name on the same scroll container as `tablist`. |\n\n---\n\n**CSS Custom Properties**\n\n- `--indicator-color` — Upstream alias for the active indicator color.\n- `--lr-scroll-fade-size` (default: `2rem`) — Width of the fade at each horizontal scroll edge. The fade is applied only while the tablist actually overflows, so a row that fits is never dimmed.\n- `--lr-tab-group-active-bg` (default: `color-mix(in oklab, transparent, var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Background of a pressed, non-disabled tab.\n- `--lr-tab-group-active-color` (default: `var(--lr-tab-group-hover-color, var(--lr-color-text))`) — Text color of a pressed, non-disabled tab.\n- `--lr-tab-group-hover-color` (default: `var(--lr-color-text)`) — Text color of a hovered, non-disabled tab. Independent of the selected-state props above. Pressed-tab and scroll-control hooks use inline `var()` fallbacks rather than a `:host` declaration, so they inherit from the group or any ancestor without retheming the other states.\n- `--lr-tab-group-indicator-color` (default: `var(--lr-color-brand)`) — Color of the selected tab's underline, themeable independently of its text color.\n- `--lr-tab-group-panel-hover-outline-color` (default: `var(--lr-color-border)`) — Outline color of the mouse-hover preview on `[part=\"panel\"]`. Set to `transparent` to opt out of the hover treatment entirely.\n- `--lr-tab-group-panel-hover-outline-offset` (default: `var(--lr-focus-ring-offset)`) — Offset of the mouse-hover preview on `[part=\"panel\"]`.\n- `--lr-tab-group-panel-hover-outline-style` (default: `solid`) — Outline style of the mouse-hover preview on `[part=\"panel\"]`.\n- `--lr-tab-group-panel-hover-outline-width` (default: `var(--lr-border-width-thin)`) — Outline width of the mouse-hover preview on `[part=\"panel\"]`.\n- `--lr-tab-group-scroll-button-active-bg` (default: `color-mix(in oklab, transparent, var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Background of a pressed overflow scroll control.\n- `--lr-tab-group-scroll-button-active-color` (default: `var(--lr-color-text)`) — Text color of a pressed overflow scroll control.\n- `--lr-tab-group-scroll-button-hover-color` (default: `var(--lr-color-text)`) — Text color of a hovered overflow scroll control.\n- `--lr-tab-group-selected-color` (default: `var(--lr-color-brand)`) — Text color of the selected tab. Scoped to `[aria-selected='true']` only, so it never repaints a hovered unselected tab (which is what hijacking `--lr-color-brand` library-wide used to do).\n- `--lr-tab-group-vertical-nav-max-inline-size` (default: `var(--lr-size-12rem)`) — Maximum logical inline size of a vertical `start`/`end` nav. Long labels ellipsize inside that bound so the panel remains usable at narrow allocations.\n- `--track-color` — Upstream track color.\n- `--track-width` — Upstream track width.","attributes":[{"name":"activation","description":"`auto` (the default) moves selection with focus. `manual` moves focus only and waits for\nEnter or Space — the APG requirement for panels that are expensive to reveal.\n\nType: `LyraTabGroupActivation`  \nDefault: `'auto'`","value":{"type":["'auto'","'manual'"]}},{"name":"active","description":"The active tab's panel name. Falls back to the first enabled tab whenever the current value doesn't resolve to one.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"aria-label","description":"Accessible name for the `role=\"tablist\"` strip. Attribute-reflects from a host-level\n`aria-label` so a plain-markup consumer gets ARIA-name forwarding without setting a JS\nproperty. `null` omits the attribute; an explicit empty string is forwarded (the role has no\nlocalized default name).\n\nType: `string | null`  \nDefault: `null`"},{"name":"fixed-scroll-controls","description":"Keeps both overflow controls visible while the row overflows, even when one logical edge is\nexhausted. Without it, each inactive edge control is hidden, matching Shoelace.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"no-scroll-controls","description":"Shoelace's spelling of `withoutScrollControls`, read alongside it so a consumer arriving from\neither upstream finds their own attribute working. Neither is deprecated.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"placement","description":"Which edge the tab strip sits on. `start`/`end` are logical and mirror under RTL; both make\nthe tablist vertical, which swaps the navigation keys to Up/Down per the APG.\n\nType: `LyraTabGroupPlacement`  \nDefault: `'top'`","value":{"type":["'top'","'bottom'","'start'","'end'"]}},{"name":"without-scroll-controls","description":"Suppresses the overflow scroll controls, leaving an overflowing tab row natively scrollable\nwith the edge fade as its only affordance. Web Awesome's spelling of the flag.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"","description":"Canonical `<lr-tab>`/`<lr-tab-panel>` pairs."},{"name":"nav","description":"Upstream-compatible slot used by `<lr-tab>` descriptors."}],"js":{"properties":[{"name":"accessibleLabel","description":"Accessible name for the `role=\"tablist\"` strip. Attribute-reflects from a host-level\n`aria-label` so a plain-markup consumer gets ARIA-name forwarding without setting a JS\nproperty. `null` omits the attribute; an explicit empty string is forwarded (the role has no\nlocalized default name).\n\nAttribute: `aria-label`","type":"string | null","default":"null"},{"name":"activation","description":"`auto` (the default) moves selection with focus. `manual` moves focus only and waits for\nEnter or Space — the APG requirement for panels that are expensive to reveal.\n\nAttribute: `activation`  \nReflected to its attribute.","type":"LyraTabGroupActivation","default":"'auto'"},{"name":"active","description":"The active tab's panel name. Falls back to the first enabled tab whenever the current value doesn't resolve to one.\n\nAttribute: `active`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"defaultSlot","description":"The group's real unnamed slot. It is kept hidden because Lyra assigns each tab and panel to\nits own deterministic named slot, but remains exposed for mapped slot observation. Stays a\nwritable `@query` field rather than a readonly `get`: `wa-tab-group` declares it writable, and\ncheck-pinned-upstream-manifests treats a readonly-vs-writable difference on a mirrored member\nas an `unsupported` surface drift -- a release blocker.","type":"HTMLSlotElement"},{"name":"fixedScrollControls","description":"Keeps both overflow controls visible while the row overflows, even when one logical edge is\nexhausted. Without it, each inactive edge control is hidden, matching Shoelace.\n\nAttribute: `fixed-scroll-controls`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"noScrollControls","description":"Shoelace's spelling of `withoutScrollControls`, read alongside it so a consumer arriving from\neither upstream finds their own attribute working. Neither is deprecated.\n\nAttribute: `no-scroll-controls`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"placement","description":"Which edge the tab strip sits on. `start`/`end` are logical and mirror under RTL; both make\nthe tablist vertical, which swaps the navigation keys to Up/Down per the APG.\n\nAttribute: `placement`  \nReflected to its attribute.","type":"LyraTabGroupPlacement","default":"'top'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"withoutScrollControls","description":"Suppresses the overflow scroll controls, leaving an overflowing tab row natively scrollable\nwith the edge fade as its only affordance. Web Awesome's spelling of the flag.\n\nAttribute: `without-scroll-controls`  \nReflected to its attribute.","type":"boolean","default":"false"}],"events":[{"name":"lr-activate","description":"Fired on every user activation of a navigable tab -- a click, or an Arrow/Home/End key under `activation=\"auto\"`, or Enter/Space under `activation=\"manual\"` -- whether or not the active tab actually moved. `detail: { value }` carries the activated tab's panel name, the same identity `lr-tab-show` reports. Bubbling and composed, so a host outside the shadow tree receives it. Not cancelable: it is a notification that the user picked a tab, not a veto point, and nothing in this component branches on it. Re-picking the active tab is the case `lr-tab-show` deliberately stays silent for -- \"reload that panel\" is a real intent -- and from the keyboard it is otherwise unobservable, because Home on an already-first active tab (or End on an already-last one) activates a tab and produces no click at all. When an activation does move the tab, `lr-tab-hide` and `lr-tab-show` are emitted first. The programmatic `show()` method is not a user activation and never fires it.","type":"CustomEvent<{ value: string }>"},{"name":"lr-tab-hide","description":"`detail: { name }`, fired for the outgoing tab immediately before `lr-tab-show`.","type":"CustomEvent<{ name: string }>"},{"name":"lr-tab-show","description":"`detail: { name }`, fired when a tab becomes active via click or keyboard.","type":"CustomEvent<{ name: string }>"}]}},{"name":"lr-tab-panel","description":"`<lr-tab-panel>` — the content revealed by the `<lr-tab>` whose `panel` matches this element's\n`name`. Mirrors `wa-tab-panel` / `sl-tab-panel`.\n\nDeliberately carries no `role=\"tabpanel\"` of its own: `<lr-tab-group>` renders the\n`role=\"tabpanel\"` wrapper this element is projected into, and a second nested tabpanel role\nwould leave the panel announced twice. Show/hide is the group's job too.\n\n---\n\n**Component metadata**\n\n- Status: `stable`\n- Since: `8.0.0`\n- Rationale: This tag entered Lyra as a stable public API with documented behavior, accessibility, and cross-browser support.\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's content. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The panel content wrapper. |\n\n---\n\n**CSS Custom Properties**\n\n- `--padding` (default: `0`) — Inner panel padding.","attributes":[{"name":"active","description":"Whether this panel is active. The owning group synchronizes it after hydration; setting it\nexplicitly supplies the SSR-visible panel.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"name","description":"Matches the `panel` of the `<lr-tab>` that reveals this panel.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"slots":[{"name":"","description":"The panel's content."}],"js":{"properties":[{"name":"active","description":"Whether this panel is active. The owning group synchronizes it after hydration; setting it\nexplicitly supplies the SSR-visible panel.\n\nAttribute: `active`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"name","description":"Matches the `panel` of the `<lr-tab>` that reveals this panel.\n\nAttribute: `name`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}]}},{"name":"lr-table","description":"`<lr-table>` — a sort/select-aware data table.\n\nA sortable-header activation first proposes a cancelable `lr-sort-request`. If accepted, client\nmode writes `sortKey`/`sortDir` and reorders the rendered rows before emitting `lr-sort`; server\nmode leaves those properties controlled and emits the same committed transaction so the caller\ncan fetch and supply the corresponding row order. Single/multiple selection is self-managed in\none `selectedRowKeys` store; row expansion follows the same opt-in shape through\n`expansionMode`/`expandedRowKeys` -- see that property's own doc block below for the\nrequest/commit detail. The\ndirection chosen the first time a column becomes the active `sortKey` comes from that column's\nown `columns[].defaultSortDir` when set, falling back to the element-level `defaultSortDir`\n(`'asc'` by default) otherwise -- letting one column in an otherwise-ascending table (e.g. a\n\"last updated\" column) start descending. Re-activating the column that is already `sortKey`\nstill only toggles between `'asc'` and `'desc'`.\n\nHeader/row activation is delegated: one `click` and one `keydown`\nlistener on `<table>` resolve the target via `closest('[data-col-key]'\n| '[data-row-key]')` and a key→object lookup map, instead of allocating\nfresh per-column/per-row closures on every render. Both listeners inspect\nthe delegated event's composed path for actual native, role, or tabindex\nsemantics (see `INTERACTIVE_SELECTOR`) so a button/link/input inside a cell\nowns its own activation instead of triggering `lr-row-click`. A passive\ncustom element remains part of the row activation surface; an opaque\nclosed-shadow control marks its host with `data-table-interactive`.\n\nKeyboard focus follows a roving-tabindex pattern (one `tabindex=\"0\"` stop\namong the header cells, one among the body rows — see `focusedColKey()` /\n`focusedRowKey()`), matching this repo's other `role=\"grid\"`/composite\nwidgets. Left/Right/Home/End move within the header row; Up/Down/Home/End\nmove within the body; Down from the header enters the body's roving stop,\nand Up from the body's first row returns to the header's roving stop.\nEnter/Space still only sort/activate (see `activateColumn()` /\n`activateRow()`). When controlled rows or columns replace the focused\nmember, focus follows the same stable key when it survives and otherwise\nclamps to the nearest surviving index; an update never reclaims focus once\nthe user has moved it outside the table. Effective locale changes use the same current\npage identity for activation, editing, and direct row-focus restoration.\n\nA column with `editTrigger: 'double-click'` additionally gives its own resting cell a\n`tabindex=\"-1\"` roving-focus stop — reachable, once the row itself has focus, with ArrowRight\n(ArrowLeft under RTL) to enter at the first editable cell in the row and step forward, ArrowLeft\n(ArrowRight under RTL) to step back and, from the first editable cell, return focus to the row —\nnever through Tab, so a table with one or more editable columns gains no new Tab stop, only a\nnew arrow-reachable one, and a table with none renders no `tabindex`/`part='cell'[data-editable]`\nat all. `F2` or `Enter` on that focused cell opens its editor (`startEditing()`); `editCell()` is\nthe same effect as a public method, for a consumer's own key binding, menu action, or other\ntrigger. `Enter` on the row itself (not a focused cell) still only activates the row, exactly as\nbefore — the two coexist because the table tells them apart from which of the two currently has\nfocus, not from the key alone. Escape and Enter inside the open editor keep cancelling/committing\nas already documented below; either one now also returns focus to the cell that opened it (the\neditor's own DOM node is what closes), matching a conventional grid's F2/Escape contract and\nclosing the WCAG 2.1.1 (Keyboard) gap a pointer-only `double-click` trigger otherwise leaves.\nPriority-hidden columns hide their header, body, and footer cells together; revealing\npriority columns restores all three bands.\nBlank and later-duplicate column keys are omitted first-wins at assignment. Rows retain their\ncaller-owned records, then one canonical `rowKey` projection omits blank and later-duplicate\nidentities before filtering, counts, pagination, focus, actions, and events.\n\nSet `aria-label` on the host to give the `role=\"grid\"` element an\naccessible name; it's forwarded into the shadow DOM's `<table>`.\n\n`columns[].priority` ('medium' | 'low') hides that column once measured overflow says\n`[part='base']` actually needs the room -- `'low'` first, `'medium'` next if the table would still\noverflow with just `'low'` gone -- never at a fixed container width; `[part='reveal-columns-button']`\nforces them all back into view. The public `hasHiddenPriorityColumns`\nproperty reports only whether a priority column is actually hidden right\nnow, measured via `ResizeObserver` on `[part='base']` plus a post-render DOM\ncheck. The toggle separately measures whether priority columns would hide\nat the current allocation, so it stays available while force-visible mode\nis active without making `hasHiddenPriorityColumns` contradict the rendered\nstate. `priorityColumnsVisible` defaults to `false` and toggles itself on\n`[part='reveal-columns-button']` activation with no external wiring\nrequired, but is also settable up front (property or the reflected\n`priority-columns-visible` attribute) to restore a previously-persisted\npreference, and readable back — directly or via the `lr-priority-columns-visibility-change`\nevent — to persist the current one. `columns[].sticky` pins a column's\nheader/cells to the inline-start (`'start'`) or inline-end (`'end'`)\nedge while the table scrolls horizontally. Every member of the priority-column family --\n`revealColumnsLabel`/`hideColumnsLabel` (which only ever reach the DOM on\n`[part='reveal-columns-button']`), `priorityColumnsVisible` (which only overrides a hide rule\nthere is none of) and `storageKey` (which persists nothing else) -- is inert unless at least one\ncolumn declares `priority`, so configuring any of them without one logs a one-time,\nproduction-silent, page-bounded development `console.warn` naming the members that will do\nnothing (the same dev-diagnostic shape as an unnamed grid's own warning). The read-only\n`priorityColumnsToggleAvailable` reports whether the reveal button is currently offered at all,\nwhich is the same measured state the button itself renders from.\n\n`expandedContent` (a table-level `(row: T) => unknown`, not a per-column\nhook, since the resulting panel spans every column via `colspan`) makes\nevery row render a leading chevron-toggle cell before its data columns.\n`canExpand` optionally gates which rows actually get an interactive\ntoggle — a row that fails it still gets a blank leading cell for column\nalignment. Which rows are currently open lives in `expandedRowKeys` (a set of row keys, per\n`rowKey`/`keyOf()`), and `expansionMode` decides who writes it — mirroring `selectionMode`\nmember for member. Under the default `'none'` the set is fully consumer-owned: the table only\nreads it and emits `lr-row-expand-toggle` on activation, exactly as it always has. Under\n`'single'` or `'multiple'` the table proposes each change with the cancelable\n`lr-row-expand-request` first and, unless a listener vetoes it, writes `expandedRowKeys` itself\nbefore announcing the applied change with `lr-row-expand-toggle`. `'single'` keeps at most one\nrow open; the row it closes to make room gets its own `lr-row-expand-toggle` (`expanded: false`)\njust before the accepted one, so the per-row event stays a complete account of what opened and\nclosed. Flipping `expansionMode` to `'single'` coerces an already-larger set down to its\nfirst key the same way `selectionMode` does for `selectedRowKeys`.\n\nNeither mode clears keys when the visible rows change: filtering, sorting and pagination leave\n`expandedRowKeys` alone, so a row scrolled, filtered or paged out of view returns expanded, and\na key matching no current row simply renders nothing until one exists again. That is\n`selectedRowKeys`' own convention — valid off-view keys stay controlled state so a\nserver-paginated table can keep them.\n\nSelection is opt-in through the `selectionMode` property. Use `single` or\n`multiple` to self-manage row selection; the default `none` remains\npresentational. `selectedRowKeys` contains the raw keys in every mode; single mode enforces one.\n\n`rowElement(rowKey)`, `cellElement(rowKey, columnKey)` and `expandedContentElement(rowKey)`\nresolve a rendered `<tr>`/`<td>` from the identity a consumer already has, for code that has to\nreach content its own `cell(row)` or `expandedContent(row)` callback rendered into this shadow\nroot (measuring it, scrolling it into view, or applying a style `::part()` cannot express, since\nonly pseudo-classes may follow a part selector). One method per callback, because the expansion\npanel is a *sibling* `<tr part='expanded-row'>` of the data row rather than a descendant of it:\n`rowElement`/`cellElement` reach `cell(row)` output only, and `expandedContentElement` returns\nthe `[part='expanded-cell']` holding `expandedContent(row)` output. All three read the current\nrender output, so `await table.updateComplete` first and treat `null` as \"not rendered right\nnow\". They resolve the `data-row-key`/`data-col-key`/`data-expanded-row-key` attributes those\nelements carry: `data-col-key` is the column's own `key`, while `data-row-key` and\n`data-expanded-row-key` are a type-tagged encoding of the row key (`string:a` vs `number:1`)\nthat keeps a numeric key distinct from the string that stringifies the same way. The panel\ndeliberately does not repeat `data-row-key`, so every `[data-row-key]` query still resolves\nexactly one element per row. All three attributes are stable public API; prefer the methods over\nbuilding a selector from them, since a consumer-supplied key is not safe to interpolate into CSS\nunescaped.\n\n`filterable` adds a compact search field above the grid. `filterText` is\ncontrolled and emits `lr-filter-change`; `filter` can provide a typed\npredicate, otherwise the row is matched against its JSON representation.\nThe internal filter and cell-editor native value events are contained at\ntheir translation boundaries; hosts receive `lr-filter-change` and\n`lr-cell-edit` instead.\n`pageSize` bounds pagination through the existing `<lr-pagination>` primitive (100 rows by\ndefault, normalized to 1..500). Client mode owns the accepted page and slices `rows`; server mode\nleaves `page` controlled, bounds the supplied page to `pageSize`, and uses `totalItems` for the\nnavigation summary. `unknownTotal` (server mode only) forwards `<lr-pagination>`'s own\nindeterminate mode for a caller with no total -- previous/next only, no numbered list, no\nitem-range summary -- with `hasNext` as the one extra signal that mode needs; see both\nproperties' own docs. `loading` keeps the table shell busy; `loadingAppearance`\nchooses how — the default `'spinner'` replaces the grid with an indeterminate\nspinner, while `'skeleton'` keeps the real `<colgroup>`/`<thead>` (and the\nfilter/pagination chrome) and fills the body with `skeletonRows` placeholder\nrows, so column geometry survives the load instead of collapsing and\nreflowing. Loading takes precedence over both empty branches. Because a skeleton needs a\ncolumn schema, a skeleton request received before `columns` arrives temporarily falls back to\nthe spinner rather than showing the no-columns empty state. Initial declarative loading stays\nsilent; every post-mount transition into either\nloading appearance appends to the shared light-DOM polite sink — including repeated cycles —\nwhile every placeholder opts out of `<lr-skeleton>`'s own announcement.\nColumns with `editTrigger: 'double-click'` open a native text/number/select editor on\ndouble-click, `F2`, or `Enter` on the cell's own roving focus stop (see the keyboard paragraph\nabove), and emit `lr-cell-edit`; row mutation remains consumer-owned. `editType: 'select'`\nrenders a native `<select>` populated from `editOptions` (`{ value, label }[]`) instead of an\n`<input>` -- a column with no `editOptions` renders an empty, valueless `<select>` rather than\nthrowing. `editTrigger: 'always'` instead renders that editor in every body cell of the\ncolumn from first paint — a settings/rate-style column meant to be typed\nstraight into. Persistent editors are plain tab stops (no `tabindex` of their\nown, exactly like the row-expand toggle) outside the header/row roving model,\nso arrow keys still navigate the grid from a row's own tab stop and act as\ncaret movement once focus is inside a field. Enter commits and keeps focus;\nEscape has nothing to cancel back to, so it is left uncancelled for an\nancestor dialog/popover. Their value binds as a content attribute, so once\nthe user has typed into one an out-of-band `rows` update to that same cell no\nlonger replaces the draft; an untouched editor still picks up a new value. A persistent\n`editType: 'select'` editor has no such native protection -- `<select>`/`<option>` carry no\ndirty-value flag, so an out-of-band `rows` update to that cell re-applies the selection even\nafter the user has picked a different option.\nEach editor's accessible name is `columns[].editLabel(row)` when the column defines it, or\notherwise the interpolated `tableEditCell` string (`Edit {column}`) -- the same name for every\nrow in that column, since the default carries no row context. Define `editLabel` for any\n`editTrigger: 'always'` column: its editors are permanent, individually focusable Tab stops, so\nleaving every one of them identically named (e.g. fifty \"Edit Status\" controls) fails WCAG 2.4.6\nand 1.3.1 for keyboard and screen-reader users.\nFocus is restored across a re-sort that moves the editor's node, and dropped\n(never re-aimed at an unrelated row) when its row leaves the rendered page.\n`spellcheck`/`autocapitalize`/`autoCorrect` forward to the filter input and, for a `'text'`\n(the default) `editType`, the inline cell editor -- no effect on a `'number'` or `'select'` cell\neditor.\n`groupBy` inserts non-focusable group header rows before each group; use\n`groupLabel` when the raw group key needs custom content. A client-mode\nsort applies *within* each group, so grouping survives sorting on a column\nunrelated to the group key.\n\n`columns[].heatValue` opts a column into heat-tint mode: its numeric return value is normalized\nagainst a shared scale spanning every `heatValue`-defining column across every currently-rendered\nrow (auto-derived, or overridden via `heatTintScale`) and painted as a `color-mix()` background via\nthe retheme-able `--lr-table-heat-tint-lo`/`-hi` custom properties (matching `lr-heatmap`'s own\nramp-token convention). The heat-tint and resize properties can be set on the table or a theme\nancestor; a value set directly on the table wins through the normal cascade. `rowTotal`/`grandTotal`\nadd a trailing column mirroring `expandedContent`'s\nleading one: `rowTotal(row)` renders per-row, `grandTotal(rows)` renders at its intersection with\nthe footer row (only when a column also defines `footer`) — both share `footer`'s own\n\"consumer computes/renders\" contract rather than assuming addition.\n\nThe public readonly `viewRows` (`rows` after filtering and client-mode sorting, ignoring\npagination) and `pageRows` (`viewRows` sliced to the page currently rendered in `<tbody>`) getters\nexpose the same rows `footer(rows)`/`grandTotal(rows)`/the heat-tint domain already see, so a\nconsumer that needs \"what the grid currently shows\" -- e.g. to export it -- reads one of these\ninstead of re-implementing filtering, sorting, and pagination itself. Both return a fresh, frozen\narray on every read; mutating the result cannot reach the table's own internal state.\n\nThe built-in empty state is addressable rather than fixed: every `<lr-empty>` the table renders\ncarries `part=\"empty\"` and re-exports its own inner parts as `empty-heading`/`empty-description`/\n`empty-icon`/`empty-actions`/`empty-base`, the two *data*-empty branches (no rows at all, and\nfiltered/paginated down to zero) render it as the fallback content of a named `empty` slot so a\nconsumer can replace it wholesale, and `emptyCompact` overrides each branch's built-in `compact`\ndefault. The no-columns branch is deliberately **not** slot-replaceable — it reports a\nconfiguration problem (`noColumnsHeading`), not \"this query returned nothing\", and a single slot\ncovering all three would collapse that distinction.\n\nA separate `error` state reports a failed load without discarding grid context: while `error` is\nset, `<tbody>`'s single row becomes a failed-load `<lr-empty>` (the same `error`-prefixed exported\nparts as the empty state, plus a built-in `[part='retry-button']`), behind its own `error` slot —\nbut `<thead>`, the filter field, and pagination all stay mounted around it, unlike either\ndata-empty branch above, which replace them too. Precedence when more than one state could apply\nat once: `loading` beats `error` beats every empty branch, so a `loading` table never flashes a\nstale `error`, and an `error` table never falls through to \"no rows\"/\"no columns\" copy\nunderneath it. The retry button's `lr-retry` is cancelable: the built-in action clears `error`,\nand `preventDefault()` leaves it set for a consumer that owns its own retry timing.\n\n`layout` sets a floor on the `<table>`'s `table-layout`: `'fixed'` forces it even with no column\nwidths, while the default `'auto'` still resolves to `fixed` whenever a column declares a `width`\nor a drag-resize is in flight (column resizing does not work under `table-layout: auto`).\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| `empty` | Replaces the built-in empty state on the two *data*-empty branches (no rows at all, and filtered/paginated down to zero). Left unfilled, the built-in `[part='empty']` `<lr-empty>` renders as this slot's fallback content. The no-columns branch renders its own `noColumnsHeading` state and is not slot-replaceable. |\n| `error` | Replaces the built-in failed-load state, including its retry button, while `error` is set. Left unfilled, the built-in `[part='error']` `<lr-empty>` renders as this slot's fallback content. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The root wrapper around the `<table>` and its footer controls. |\n| `caption` | The `<caption>` element, rendered only when `caption` is set. |\n| `cell` | Each body `<td>`. An `editTrigger: 'double-click'` column's resting (not currently editing) cell additionally carries `[data-editable]` and its own `tabindex=\"-1\"` roving-focus stop -- see the keyboard paragraph above. |\n| `cell-editor` | The native inline cell editor -- an `<input>` for `editType: 'text'`/ `'number'`, a `<select>` for `editType: 'select'`: shown after a double-click on an `editTrigger: 'double-click'` cell, and rendered persistently in every body cell of an `editTrigger: 'always'` column. |\n| `empty` | The built-in `<lr-empty>` host, in all three empty states (no columns configured, no rows at all, and filtered/paginated down to zero rows). The two data-empty states render it as the `empty` slot's fallback, so it disappears once that slot is filled. Note that the no-columns and no-rows states return the empty element as the shadow root's own root, with no `[part='base']` wrapper around it — `::part(base)` does not apply in those two states, only in the filtered-to-zero one. |\n| `empty-actions` | Exported from the built-in `<lr-empty>`'s `actions` part. |\n| `empty-base` | Exported from the built-in `<lr-empty>`'s own `base` part. |\n| `empty-description` | Exported from the built-in `<lr-empty>`'s `description` part. |\n| `empty-heading` | Exported from the built-in `<lr-empty>`'s `heading` part. |\n| `empty-icon` | Exported from the built-in `<lr-empty>`'s `icon` part. |\n| `error` | The built-in `<lr-empty>` host rendered in the row body while `error` is set. Unlike `[part='empty']`'s no-rows branches, its surrounding `<thead>`, filter, and pagination stay mounted rather than being replaced along with it. |\n| `error-actions` | Exported from the built-in error `<lr-empty>`'s `actions` part; wraps `retry-button`. |\n| `error-base` | Exported from the built-in error `<lr-empty>`'s own `base` part. |\n| `error-cell` | The `<td>` inside `[part='error-row']`, spanning every column, that holds the failed-load content. |\n| `error-description` | Exported from the built-in error `<lr-empty>`'s `description` part. |\n| `error-heading` | Exported from the built-in error `<lr-empty>`'s `heading` part. |\n| `error-icon` | Exported from the built-in error `<lr-empty>`'s `icon` part. |\n| `error-row` | The single full-width `<tr>` that replaces the row content while `error` is set. Present only in the in-grid branch: when `columns` is empty there is no grid to keep mounted, so the failed-load content renders standalone and neither this part nor `error-cell` exists. |\n| `expand-toggle-cell` | Each row's (and the header's) leading chevron-toggle cell, rendered only when `expandedContent` is set. |\n| `expanded-cell` | The single `colspan`-spanning `<td>` inside `expanded-row`, containing `expandedContent(row)`. Resolved from script by `expandedContentElement(rowKey)`. |\n| `expanded-row` | The full-width panel `<tr>` rendered beneath a row whose key is in `expandedRowKeys`. Carries `data-expanded-row-key`, not `data-row-key`: it is a sibling of the data row, so repeating that attribute would make every `[data-row-key]` query resolve two elements per open row. |\n| `filter` | The optional row-filter input. |\n| `filter-clear` | The button that clears the filter field, replacing the native search-cancel glyph suppressed by this field's own reset; rendered only while it has a value. |\n| `filter-label` | The `<label>` wrapping the filter input. |\n| `foot` | The `<tfoot>`, only rendered when at least one column defines `footer`. |\n| `footer-cell` | A single footer cell. |\n| `footer-row` | The single footer row. |\n| `group-cell` | The full-width group header cell. |\n| `group-row` | A non-focusable group header row. |\n| `head` | The `<thead>` element. |\n| `header-cell` | Each `<th>` header cell. |\n| `loading` | The loading-state wrapper. Under `loadingAppearance=\"spinner\"` (the default) it is the visible block holding the spinner; under `\"skeleton\"` it is the visually-hidden aria-hidden announcement mirror, since the placeholder rows are the visible affordance. It is never itself live; post-mount loading announcements use the shared light-DOM polite sink. |\n| `more-button` | The \"load more\" control, shown when `hasMore` is true. |\n| `pagination` | The optional pagination component. |\n| `resize-handle` | The focusable separator used to resize a `resizable` column. Its numeric ARIA range remains in CSS pixels while `aria-valuetext` reports the current value through the effective locale. |\n| `retry-button` | The built-in retry control rendered into the error state's `actions`. |\n| `reveal-columns-button` | The button that toggles `priority`-hidden columns back into view. |\n| `row` | Each body `<tr>`. |\n| `row-expand-icon` | The 1em chevron icon inside `row-expand-toggle`. |\n| `row-expand-toggle` | The `<button>` inside `expand-toggle-cell`, absent for a row that fails `canExpand`; it inherits the table's typography. |\n| `row-total-cell` | Each body row's trailing `<td>` holding `rowTotal(row)`, rendered only when `rowTotal` is set. The corresponding footer-row cell (holding `grandTotal`) is a `footer-cell` instead, matching every other footer cell. |\n| `skeleton` | Each `<lr-skeleton>` placeholder inside a `loadingAppearance=\"skeleton\"` body cell. Its rows and cells reuse the ordinary `row`/`cell`/`row-total-cell` parts (that is what keeps them geometrically identical to real rows), so this is the part to target for the placeholder's own look — e.g. `::part(skeleton) { --lr-skeleton-h: 2em; }`. |\n| `sort-icon` | The direction indicator in a sortable header cell. |\n| `sort-icon-active` | The active direction chevron; also carries sort-icon. |\n| `sort-icon-inactive` | The muted bidirectional indicator when sortIndicators is all; also carries sort-icon. |\n| `table` | The `<table role=\"grid\">` element. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-table-cell-color` (default: `inherit`) — Text colour of body cells; inherits the host's own colour by default.\n- `--lr-table-cell-link-color` (default: `var(--lr-color-brand)`) — Colour of an anchor returned from a column's `cell(row)`. Such an anchor renders inside this component's shadow root, so page CSS cannot reach it and `::part()` cannot select past the first compound selector to reach it either; without this hook it computes to the UA default link blue. Set `revert` for the UA default.\n- `--lr-table-cell-link-hover-color` (default: `var(--lr-table-cell-link-color,var(--lr-color-brand))`) — Colour of that anchor on hover and `:focus-visible`, which also thicken its underline.\n- `--lr-table-cell-padding` (default: `var(--lr-space-s)`) — Padding of a header cell, a body cell, and the row-total cell.\n- `--lr-table-cell-padding-compact` (default: `var(--lr-space-xs) var(--lr-space-s)`) — Padding of a group-header cell and a footer cell, which default to a tighter block/inline shorthand than `--lr-table-cell-padding` rather than sharing it outright.\n- `--lr-table-font-size` (default: `inherit`) — Font size of the `<table>` element and, through normal inheritance, every cell inside it. The rest of the font shorthand (family, weight, etc.) keeps inheriting from the host regardless of this override.\n- `--lr-table-header-sorted-bg` (default: `var(--lr-color-surface)`) — Background of the currently-sorted column's header cell (`[aria-sort]` other than `none`), including a `sticky` column's own header cell. Same rationale as `--lr-table-row-selected-bg`: `::part(header-cell)[aria-sort]` is invalid CSS, so this token is the supported way to recolor the sorted header without hijacking a library-wide token.\n- `--lr-table-header-sorted-color` (default: `inherit`) — Text color of the currently-sorted column's header cell.\n- `--lr-table-heat-t` — This cell's position on the heat-tint ramp, as a percentage string. Set inline by the component on each `[data-heat]` cell; not consumer-settable.\n- `--lr-table-heat-tint-hi` (default: `var(--lr-color-brand)`) — High endpoint of the heat-tint ramp used by `heatValue` columns. Inherits from theme ancestors.\n- `--lr-table-heat-tint-lo` (default: `var(--lr-color-brand-quiet)`) — Low endpoint of the heat-tint ramp used by `heatValue` columns. Inherits from theme ancestors.\n- `--lr-table-max-height` (default: `none`) — Cap on the scroll container's block size, past which the table body scrolls.\n- `--lr-table-resize-handle-active-bg` (default: `var(--lr-table-resize-handle-hover-bg,var(--lr-color-brand))`) — Resize-handle pressed background.\n- `--lr-table-resize-handle-active-opacity` (default: `calc(var(--lr-table-resize-handle-hover-opacity,var(--lr-table-resize-handle-opacity,0.12))*2)`) — Resize-handle pressed opacity.\n- `--lr-table-resize-handle-hover-bg` (default: `var(--lr-color-brand)`) — Resize-handle hover/focus background.\n- `--lr-table-resize-handle-hover-opacity` (default: `var(--lr-table-resize-handle-opacity,0.12)`) — Resize-handle hover/focus opacity.\n- `--lr-table-resize-handle-opacity` (default: `0.12`) — Hover/focus opacity of the resize handle. Legacy shared-state hook; inherits from theme ancestors.\n- `--lr-table-resize-min-width` (default: `var(--lr-size-3rem)`) — Default minimum width for a resizable column without an explicit pixel `minWidth`. Inherits from theme ancestors.\n- `--lr-table-row-selected-bg` (default: `var(--lr-color-brand-quiet)`) — Background of a row whose `aria-selected` is `true`, including that row's own `sticky` column cell -- a sticky cell otherwise paints its own opaque surface and would hide the selected fill. Shadow Parts forbids an attribute selector after `::part()`, so `::part(row)[aria-selected]` is invalid CSS and the selected row could otherwise only be restyled by hijacking the library-wide `--lr-color-brand-quiet` token.\n- `--lr-table-row-stripe-bg` (default: `transparent`) — Background of alternating body rows, including each row's own `sticky` column cell. The token is read only on rows carrying the internal stripe marker, so it can be set on the table or an ancestor without affecting group, expanded, hover, or selected rows.\n- `--lr-table-sticky-offset` (default: `0`) — Distance a `sticky` column pins from the inline edge. Measured and set inline per column by the component so multiple sticky columns stack instead of overlapping; falls back to `0` for the first one, or before the first measurement pass.\n- `--lr-theme-scrollbar-gutter` (default: `auto`) — Opt-in theme-level scrollbar gutter honored by the `base` scroll container; see `--lr-theme-scrollbar-width`.\n- `--lr-theme-scrollbar-width` (default: `auto`) — Opt-in theme-level scrollbar width honored by the `base` scroll container; unset, renders identically to before. Set on `:root` or any ancestor to retune every internal scroll container in the library at once.","attributes":[{"name":"accessible-label","description":"Accessible name for the `role=\"grid\"` — a typed alternative to setting `aria-label` on the\nhost. When set it becomes the grid's `aria-label`; a host `aria-label` is used as a fallback\nwhen this is unset. Consumer-supplied text, so it is NOT run through `this.localize()`. An\nexplicitly empty string is a real override (renders `aria-label=\"\"`) rather than falling\nback to the host `aria-label`.\n\nType: `string | undefined`"},{"name":"announce","description":"Opts this table into announcing a failed-load state it already carries when it first mounts,\nthrough the same shared assertive region and the same heading text the later `error`\ntransition announces, so the two paths cannot drift. Leave unset for a table that is part of\nthe page a user is arriving on: the built-in error state renders in document order and\nrepeating it is noise. Set it when the table is created in response to a user action — a\nreload that rejects mounts a fresh `error` table whose failure would otherwise never be\nspoken. Read once, on the first update: a later reconnection or adoption stages the same\nstate again rather than replaying the announcement, and later `error` transitions announce\neither way. Deliberately not forwarded to the composed `[part='error']` `<lr-empty>`, whose\nown `announce` stays unset so the failure is spoken once, not twice. Remove any host\n`role=\"status\"`/`role=\"alert\"` hand-added before this property existed once it is set --\notherwise the failure is announced a third time, through the native role as well.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"autocapitalize","description":"Forwarded to the same inputs' native `autocapitalize`. Empty string omits the attribute\n(browser default).\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"autocorrect","description":"Forwarded to the same inputs' native `autocorrect` (Safari/WebKit-specific). Empty string\nomits the attribute (browser default). Named `autoCorrect` (capital `C`), not `autocorrect`,\nto dodge a TS `lib.dom.d.ts` collision -- same fix as `<lr-textarea>`/`<lr-model-select>`.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"caption","description":"Optional visible caption rendered as the table's `<caption>`. Also names the grid (via\n`aria-labelledby`) when no `accessibleLabel`/host `aria-label` is set. Consumer-supplied\ntext, not localized.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"default-sort-dir","description":"The direction applied whenever header activation switches sorting to a *different* column —\nincluding the first column ever sorted — for any column that does not declare its own\n`columns[].defaultSortDir` (that column-level value wins first when set). Re-activating the\ncolumn that is already `sortKey` toggles between `'asc'` and `'desc'` instead, so this never\noverrides a direction the user just chose for the column they are still on. Defaults to\n`'asc'`; set `'desc'` for a most-recent-first or highest-first table.\n\nType: `TableSortDirection`  \nDefault: `'asc'`","value":{"type":["'asc'","'desc'"]}},{"name":"empty-compact","description":"Overrides the built-in `[part='empty']` state's `compact` rendering. Leave `undefined` (the\ndefault) to keep each branch's own built-in behavior: the whole-table states (no columns, no\nrows) render spacious, while the in-table filtered/paginated-to-zero state — which sits below\nthe filter field inside `[part='base']` — renders compact. `empty-compact=\"false\"` forces the\nspacious rendering everywhere. Has no effect once the `empty` slot is filled.\n\nType: `boolean | undefined`"},{"name":"empty-description","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"empty-heading","description":"Type: `string | undefined`"},{"name":"error","description":"Non-`false` replaces `<tbody>`'s row content with a built-in failed-load state, while the\nsurrounding `<thead>`, filter field, and pagination stay mounted — unlike either data-empty\nbranch below, which this state overrides and which replace that chrome too. Precedence when\nmore than one applies at once: `loading` beats `error` beats every empty branch, so a\n`loading` table never shows a stale `error`, and an `error` table never falls through to\n\"no rows\"/\"no columns\" copy underneath it. Reflected so `[error]` is selectable from\npage-level CSS the same way `[loading]` already is.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"error-description","description":"Optional failed-load description. Empty by default (no description line); a supplied string,\nincluding the built-in English value, renders verbatim — never localized, the same contract\nas `emptyDescription`. Has no effect once the `error` slot is filled.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"error-heading","description":"Optional failed-load heading override. Omission localizes `tableLoadFailed`; a supplied\nstring, including the built-in English text or an empty string, renders verbatim. Has no\neffect once the `error` slot is filled.\n\nType: `string | undefined`"},{"name":"expansion-mode","description":"Who owns `expandedRowKeys`, mirroring `selectionMode`'s three members. `'none'` (the default,\nand the behaviour this component shipped with) leaves the set entirely consumer-controlled:\nactivation only reports `lr-row-expand-toggle`. `'single'` and `'multiple'` self-manage the\nset behind the cancelable `lr-row-expand-request`, with `'single'` keeping at most one row\nopen and coercing an already-larger set down to its first key when this property becomes\n`'single'`. Closing a row to make room for another is an expansion change like any other, so\n`'single'` reports the displaced row with its own `lr-row-expand-toggle` (`expanded: false`)\nahead of the accepted one -- unless that row is filtered or paged out of view, which leaves\nit no `row` to describe. The property-driven coercion above reports through\n`expandedRowKeys` alone for the same reason. No mode ever clears keys because the visible\nrows changed -- see the class JSDoc's note on off-view keys, which follows\n`selectedRowKeys`' convention.\n\nType: `TableExpansionMode`  \nDefault: `'none'`","value":{"type":["'none'","'single'","'multiple'"]}},{"name":"filter-label","description":"Optional filter-copy overrides. Omission localizes the matching message key; supplied\nstrings, including the built-in English text or an empty string, render verbatim.\n\nType: `string | undefined`"},{"name":"filter-placeholder","description":"Type: `string | undefined`"},{"name":"filter-text","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"filterable","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"has-hidden-priority-columns","description":"Whether the current rendered allocation actually hides at least one `priority` column. This\nread-only state becomes false once `priorityColumnsVisible` reveals them; the toggle remains\navailable at narrow allocations through an internal capability measurement.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"has-more","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"has-next","description":"Whether at least one more page exists past the current one. Consulted only alongside\n`unknownTotal`; forwarded verbatim to the nested `<lr-pagination>`'s own `hasNext`. Defaults to\n`true` so an indeterminate server pager stays navigable until the caller's API reports\notherwise.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"hide-columns-label","description":"Type: `string | undefined`"},{"name":"layout","description":"Type: `'auto' | 'fixed'`","value":{"type":["'auto'","'fixed'"]}},{"name":"loading","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"loading-appearance","description":"How `loading` renders. `'spinner'` (the default, unchanged output) replaces the whole grid\nwith an indeterminate spinner. `'skeleton'` instead renders the real table — the same\n`<colgroup>` (declared *and* drag-resized widths included), the same `<thead>`, the filter\nfield and the pagination footer — and fills `<tbody>` with placeholder rows, so a cold load\nsketches the grid's shape rather than collapsing to a spinner and reflowing when the rows\nland. Kept separate from `loading` rather than widening it to a string union, so\n`?loading=${…}` bindings and `el.loading === true` checks keep working.\nWhen `columns` is empty, a skeleton request temporarily renders the spinner: loading still\ntakes precedence over the no-columns empty state, but there is no schema to sketch yet.\n\nColumn *widths* only stay pixel-identical across the load if the browser isn't sizing them\nfrom cell content: declare `columns[].width`, or set `layout=\"fixed\"`. Under the default\n`table-layout: auto`, placeholder cells have no intrinsic width, so the columns re-measure\nwhen real content arrives — exactly as they do between any two different data sets.\n\nType: `TableLoadingAppearance`  \nDefault: `'spinner'`","value":{"type":["'spinner'","'skeleton'"]}},{"name":"loading-label","description":"Optional loading-copy override. Omission localizes `tableLoading`; a supplied string renders verbatim.\n\nType: `string | undefined`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"more-label","description":"Optional copy overrides. Omission localizes the matching message key; supplied strings,\nincluding the built-in English text or an empty string, render verbatim.\n\nType: `string | undefined`"},{"name":"no-columns-description","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"no-columns-heading","description":"Type: `string | undefined`"},{"name":"page","description":"Current page. Client pagination updates it on accepted navigation; server pagination leaves it\ncontrolled and only emits `lr-page-change`.\n\nType: `number`  \nDefault: `1`","value":{"type":["number"]}},{"name":"page-size","description":"Maximum rows mounted per page. Defaults to 100 and normalizes into 1..500 so a bare table\nnever creates an unbounded row-by-column DOM projection.\n\nType: `number`  \nDefault: `100`","value":{"type":["number"]}},{"name":"pagination-mode","description":"Type: `'client' | 'server'`  \nDefault: `'client'`","value":{"type":["'client'","'server'"]}},{"name":"priority-columns-visible","description":"Forces `priority`-hidden columns back into view, overriding the\nmeasured-overflow hide rules in table.styles.ts. Toggles itself on\n`[part='reveal-columns-button']` activation by default — no external\nwiring is required for the button to work. Also settable from outside\n(property or the reflected `priority-columns-visible` attribute) to restore a\npreviously-persisted preference. The single\n`lr-priority-columns-visibility-change` event reports button-driven changes.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"reveal-columns-label","description":"Type: `string | undefined`"},{"name":"scroll-mode","description":"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'`","value":{"type":["'self'","'page'","'auto'"]}},{"name":"selection-mode","description":"Type: `TableSelectionMode`  \nDefault: `'none'`","value":{"type":["'none'","'single'","'multiple'"]}},{"name":"skeleton-rows","description":"Number of placeholder rows rendered by `loadingAppearance=\"skeleton\"`. `0` (the default)\nrenders 3 placeholders for the ordinary bounded default, or derives a non-default explicit\n`pageSize` (capped at 20). Positive explicit values are also capped at 20. Ignored entirely\nunder the default spinner appearance.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"sort-dir","description":"Type: `TableSortDirection`  \nDefault: `'asc'`","value":{"type":["'asc'","'desc'"]}},{"name":"sort-indicators","description":"`'active'` preserves the active-column chevron alone. `'all'` also reserves the same icon\nspace with a muted bidirectional indicator in inactive sortable headers, including on touch\nscreens. This presentation choice does not change sorting, focus or aria-sort semantics.\n\nType: `TableSortIndicators`  \nDefault: `'active'`","value":{"type":["'active'","'all'"]}},{"name":"sort-key","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"sort-mode","description":"`'client'` (the default) orders `rows` itself, in the browser, from `sortKey`/`sortDir` and\nthe active column's `sortValue`. `'server'` renders `rows` in exactly the order given,\nassuming the caller has already sorted them — mirroring `paginationMode`'s identical\nclient/server split. Header activation first emits cancelable `lr-sort-request`; an accepted\nactivation emits `lr-sort` either way, but only client mode mutates these properties.\n\nWith no `sortKey` set (the default) `'client'` is a no-op: the input order is preserved\nverbatim, so an existing consumer that only listens for `lr-sort` sees unchanged rendering\nuntil a header is actually activated.\n\nType: `TableSortMode`  \nDefault: `'client'`","value":{"type":["'client'","'server'"]}},{"name":"spellcheck","description":"Forwarded to the filter input's, and (when the active column's `editType` is `'text'`, the\ndefault) the inline cell-editor input's, native `spellcheck`. Defaults to `true`, matching\nthe native element's own default. `spellcheck=\"false\"` is parsed as `false` (see\n`spellcheckConverter` above). No effect on a `'number'` or `'select'` cell editor.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"storage-key","description":"Persists `priorityColumnsVisible` to `localStorage` across reloads when set. Namespaced as\n`lr-table:${storageKey}`. Restoration never overwrites a `priorityColumnsVisible` the consumer\ndeclared on the same mount (`priority-columns-visible` present, or a\n`.priorityColumnsVisible=${...}` binding) -- including a binding that pins it to `false`, its\nown default. The same \"explicit beats persisted\" guarantee as `lr-app-rail`'s and\n`lr-widget`'s `storage-key` restores, which share this one's write-tracking mechanism.\n\nType: `string | undefined`"},{"name":"total-items","description":"Total item count for server pagination; `-1` derives it from filtered rows.\n\nType: `number`  \nDefault: `-1`","value":{"type":["number"]}},{"name":"unknown-total","description":"Marks server pagination as indeterminate -- the caller has no total item count, only whether\none more page exists (`hasNext`). Forwarded to the nested `<lr-pagination>` as its own\nindeterminate mode (a `total=\"-1\"` sentinel; see that component's docs), which then renders\nprevious/next only, with no numbered page list and no item-range summary. A dedicated boolean\nrather than a second magic `totalItems` value: `totalItems=\"-1\"` already means \"derive from\nthe currently matching rows\", and stacking a different meaning onto another negative number\nwould be exactly the kind of easy-to-mistake sentinel this library avoids elsewhere. Ignored\noutside `paginationMode: 'server'` -- client mode always knows the exact row count it slices,\nso it never needs the indeterminate layout.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"empty","description":"Replaces the built-in empty state on the two *data*-empty branches (no rows at all, and filtered/paginated down to zero). Left unfilled, the built-in `[part='empty']` `<lr-empty>` renders as this slot's fallback content. The no-columns branch renders its own `noColumnsHeading` state and is not slot-replaceable."},{"name":"error","description":"Replaces the built-in failed-load state, including its retry button, while `error` is set. Left unfilled, the built-in `[part='error']` `<lr-empty>` renders as this slot's fallback content."}],"js":{"properties":[{"name":"accessibleLabel","description":"Accessible name for the `role=\"grid\"` — a typed alternative to setting `aria-label` on the\nhost. When set it becomes the grid's `aria-label`; a host `aria-label` is used as a fallback\nwhen this is unset. Consumer-supplied text, so it is NOT run through `this.localize()`. An\nexplicitly empty string is a real override (renders `aria-label=\"\"`) rather than falling\nback to the host `aria-label`.\n\nAttribute: `accessible-label`","type":"string | undefined"},{"name":"announce","description":"Opts this table into announcing a failed-load state it already carries when it first mounts,\nthrough the same shared assertive region and the same heading text the later `error`\ntransition announces, so the two paths cannot drift. Leave unset for a table that is part of\nthe page a user is arriving on: the built-in error state renders in document order and\nrepeating it is noise. Set it when the table is created in response to a user action — a\nreload that rejects mounts a fresh `error` table whose failure would otherwise never be\nspoken. Read once, on the first update: a later reconnection or adoption stages the same\nstate again rather than replaying the announcement, and later `error` transitions announce\neither way. Deliberately not forwarded to the composed `[part='error']` `<lr-empty>`, whose\nown `announce` stays unset so the failure is spoken once, not twice. Remove any host\n`role=\"status\"`/`role=\"alert\"` hand-added before this property existed once it is set --\notherwise the failure is announced a third time, through the native role as well.\n\nAttribute: `announce`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"autoCorrect","description":"Forwarded to the same inputs' native `autocorrect` (Safari/WebKit-specific). Empty string\nomits the attribute (browser default). Named `autoCorrect` (capital `C`), not `autocorrect`,\nto dodge a TS `lib.dom.d.ts` collision -- same fix as `<lr-textarea>`/`<lr-model-select>`.\n\nAttribute: `autocorrect`","type":"string","default":"''"},{"name":"autocapitalize","description":"Forwarded to the same inputs' native `autocapitalize`. Empty string omits the attribute\n(browser default).\n\nAttribute: `autocapitalize`","type":"string","default":"''"},{"name":"canExpand","description":"Gates whether a given row gets an interactive chevron/toggle at all,\nwhen `expandedContent` is set. Omit to make every row expandable. A\nrow that fails this check still gets a leading cell (for column\nalignment) but it renders empty — no button, no `aria-expanded`, no\nclick handler.","type":"(row: T) => boolean | undefined"},{"name":"caption","description":"Optional visible caption rendered as the table's `<caption>`. Also names the grid (via\n`aria-labelledby`) when no `accessibleLabel`/host `aria-label` is set. Consumer-supplied\ntext, not localized.\n\nAttribute: `caption`","type":"string","default":"''"},{"name":"columns","description":"Clone-owned readonly column-definition sequence, bounded to the first 10,000 source\npositions. Blank keys and later duplicate keys are omitted (first valid occurrence wins)\nbefore any header, cell, sort, focus, or event path. Column objects and callbacks retain their\nidentities; reassign the collection to update.","type":"readonly TableColumn<T>[]"},{"name":"defaultSortDir","description":"The direction applied whenever header activation switches sorting to a *different* column —\nincluding the first column ever sorted — for any column that does not declare its own\n`columns[].defaultSortDir` (that column-level value wins first when set). Re-activating the\ncolumn that is already `sortKey` toggles between `'asc'` and `'desc'` instead, so this never\noverrides a direction the user just chose for the column they are still on. Defaults to\n`'asc'`; set `'desc'` for a most-recent-first or highest-first table.\n\nAttribute: `default-sort-dir`","type":"TableSortDirection","default":"'asc'"},{"name":"emptyCompact","description":"Overrides the built-in `[part='empty']` state's `compact` rendering. Leave `undefined` (the\ndefault) to keep each branch's own built-in behavior: the whole-table states (no columns, no\nrows) render spacious, while the in-table filtered/paginated-to-zero state — which sits below\nthe filter field inside `[part='base']` — renders compact. `empty-compact=\"false\"` forces the\nspacious rendering everywhere. Has no effect once the `empty` slot is filled.\n\nAttribute: `empty-compact`","type":"boolean | undefined"},{"name":"emptyDescription","description":"Attribute: `empty-description`","type":"string","default":"''"},{"name":"emptyHeading","description":"Attribute: `empty-heading`","type":"string | undefined"},{"name":"error","description":"Non-`false` replaces `<tbody>`'s row content with a built-in failed-load state, while the\nsurrounding `<thead>`, filter field, and pagination stay mounted — unlike either data-empty\nbranch below, which this state overrides and which replace that chrome too. Precedence when\nmore than one applies at once: `loading` beats `error` beats every empty branch, so a\n`loading` table never shows a stale `error`, and an `error` table never falls through to\n\"no rows\"/\"no columns\" copy underneath it. Reflected so `[error]` is selectable from\npage-level CSS the same way `[loading]` already is.\n\nAttribute: `error`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"errorDescription","description":"Optional failed-load description. Empty by default (no description line); a supplied string,\nincluding the built-in English value, renders verbatim — never localized, the same contract\nas `emptyDescription`. Has no effect once the `error` slot is filled.\n\nAttribute: `error-description`","type":"string","default":"''"},{"name":"errorHeading","description":"Optional failed-load heading override. Omission localizes `tableLoadFailed`; a supplied\nstring, including the built-in English text or an empty string, renders verbatim. Has no\neffect once the `error` slot is filled.\n\nAttribute: `error-heading`","type":"string | undefined"},{"name":"expandedContent","description":"Renders a full-width panel beneath a row when that row's key is in\n`expandedRowKeys`. Table-level (not per-column) since the panel spans\nevery column via `colspan`. Setting this makes every row render a\nleading chevron-toggle cell before all data columns; omit for no\nleading cell at all (unchanged output). The returned content renders inside this\ncomponent's shadow root, behind the `expanded-cell` part -- page-level CSS selectors cannot\nreach it, and `::part(expanded-cell)` only reaches that wrapping `<td>`, not the descendants\nthis callback returns (`::part()` is a pseudo-element; only pseudo-classes may follow it, so\n`::part(expanded-cell) .child` never matches, the same limitation `cell(row)`'s returned\nanchors run into). Style such content by returning already-styled elements -- inline\n`style`, or elements that reference this table's own `--lr-*` design tokens, which inherit\nacross the shadow boundary like any custom property -- rather than depending on a\npage-level selector to find it. When script has to reach the rendered panel anyway (to\nmeasure it or scroll it into view), `expandedContentElement(rowKey)` resolves that `<td>`;\n`rowElement()` does not, since the panel is a sibling `<tr>` rather than part of the row.","type":"(row: T) => unknown | undefined"},{"name":"expandedRowKeys","type":"ReadonlySet<K>"},{"name":"expansionMode","description":"Who owns `expandedRowKeys`, mirroring `selectionMode`'s three members. `'none'` (the default,\nand the behaviour this component shipped with) leaves the set entirely consumer-controlled:\nactivation only reports `lr-row-expand-toggle`. `'single'` and `'multiple'` self-manage the\nset behind the cancelable `lr-row-expand-request`, with `'single'` keeping at most one row\nopen and coercing an already-larger set down to its first key when this property becomes\n`'single'`. Closing a row to make room for another is an expansion change like any other, so\n`'single'` reports the displaced row with its own `lr-row-expand-toggle` (`expanded: false`)\nahead of the accepted one -- unless that row is filtered or paged out of view, which leaves\nit no `row` to describe. The property-driven coercion above reports through\n`expandedRowKeys` alone for the same reason. No mode ever clears keys because the visible\nrows changed -- see the class JSDoc's note on off-view keys, which follows\n`selectedRowKeys`' convention.\n\nAttribute: `expansion-mode`  \nReflected to its attribute.","type":"TableExpansionMode","default":"'none'"},{"name":"filter","type":"(row: T, text: string) => boolean | undefined"},{"name":"filterLabel","description":"Optional filter-copy overrides. Omission localizes the matching message key; supplied\nstrings, including the built-in English text or an empty string, render verbatim.\n\nAttribute: `filter-label`","type":"string | undefined"},{"name":"filterPlaceholder","description":"Attribute: `filter-placeholder`","type":"string | undefined"},{"name":"filterText","description":"Attribute: `filter-text`","type":"string","default":"''"},{"name":"filterable","description":"Attribute: `filterable`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"grandTotal","description":"Renders the bottom-right cell (row-total column × footer row). Only rendered when both\n`rowTotal` is set **and** at least one column defines `footer` — otherwise there is no footer\nrow for it to occupy, and this renders nothing.","type":"(rows: readonly T[]) => unknown | undefined"},{"name":"groupBy","description":"Inserts a non-focusable group header row wherever this key changes between consecutive\nrendered rows. Supply `rows` with each group already contiguous — the table does not\nre-order them to make them so, and the group order it renders is their first-appearance\norder in `rows`. A client-mode sort (`sortMode: 'client'`) is applied *within* each group\nrather than across the whole set, so sorting a grouped table on a column unrelated to the\ngroup key reorders rows inside their groups and leaves the grouping itself intact. Sorting on\na column whose value is constant inside every group — the group column itself, most obviously\n— reorders the *groups* by that value instead, since there is nothing to reorder within\nthem.","type":"(row: T) => string | number | undefined"},{"name":"groupLabel","type":"(key: string | number, rows: readonly T[]) => unknown | undefined"},{"name":"hasHiddenPriorityColumns","description":"Whether the current rendered allocation actually hides at least one `priority` column. This\nread-only state becomes false once `priorityColumnsVisible` reveals them; the toggle remains\navailable at narrow allocations through an internal capability measurement.\n\nAttribute: `has-hidden-priority-columns`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"hasMore","description":"Attribute: `has-more`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"hasNext","description":"Whether at least one more page exists past the current one. Consulted only alongside\n`unknownTotal`; forwarded verbatim to the nested `<lr-pagination>`'s own `hasNext`. Defaults to\n`true` so an indeterminate server pager stays navigable until the caller's API reports\notherwise.\n\nAttribute: `has-next`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"heatTintScale","description":"Overrides the auto-derived heat-tint domain (min/max of every `heatValue` result across every\ncurrently-rendered row — post-sort, pre-pagination, the same rows `footer(rows)` already sees).\nUnset computes the domain automatically from the data, spanning every `heatValue`-defining\ncolumn together (a single shared scale across the whole grid, not one scale per column).","type":"{ min?: number; max?: number } | undefined"},{"name":"hideColumnsLabel","description":"Attribute: `hide-columns-label`","type":"string | undefined"},{"name":"layout","description":"Attribute: `layout`  \nReflected to its attribute.","type":"'auto' | 'fixed'"},{"name":"loading","description":"Attribute: `loading`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"loadingAppearance","description":"How `loading` renders. `'spinner'` (the default, unchanged output) replaces the whole grid\nwith an indeterminate spinner. `'skeleton'` instead renders the real table — the same\n`<colgroup>` (declared *and* drag-resized widths included), the same `<thead>`, the filter\nfield and the pagination footer — and fills `<tbody>` with placeholder rows, so a cold load\nsketches the grid's shape rather than collapsing to a spinner and reflowing when the rows\nland. Kept separate from `loading` rather than widening it to a string union, so\n`?loading=${…}` bindings and `el.loading === true` checks keep working.\nWhen `columns` is empty, a skeleton request temporarily renders the spinner: loading still\ntakes precedence over the no-columns empty state, but there is no schema to sketch yet.\n\nColumn *widths* only stay pixel-identical across the load if the browser isn't sizing them\nfrom cell content: declare `columns[].width`, or set `layout=\"fixed\"`. Under the default\n`table-layout: auto`, placeholder cells have no intrinsic width, so the columns re-measure\nwhen real content arrives — exactly as they do between any two different data sets.\n\nAttribute: `loading-appearance`  \nReflected to its attribute.","type":"TableLoadingAppearance","default":"'spinner'"},{"name":"loadingLabel","description":"Optional loading-copy override. Omission localizes `tableLoading`; a supplied string renders verbatim.\n\nAttribute: `loading-label`","type":"string | undefined"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"moreLabel","description":"Optional copy overrides. Omission localizes the matching message key; supplied strings,\nincluding the built-in English text or an empty string, render verbatim.\n\nAttribute: `more-label`","type":"string | undefined"},{"name":"noColumnsDescription","description":"Attribute: `no-columns-description`","type":"string","default":"''"},{"name":"noColumnsHeading","description":"Attribute: `no-columns-heading`","type":"string | undefined"},{"name":"page","description":"Current page. Client pagination updates it on accepted navigation; server pagination leaves it\ncontrolled and only emits `lr-page-change`.\n\nAttribute: `page`  \nReflected to its attribute.","type":"number","default":"1"},{"name":"pageRows","description":"`viewRows` sliced to the page currently rendered in `<tbody>` -- exactly the rows on screen\nright now. Same defensive-copy guarantee as `viewRows`.","type":"readonly T[]","read-only":true},{"name":"pageSize","description":"Maximum rows mounted per page. Defaults to 100 and normalizes into 1..500 so a bare table\nnever creates an unbounded row-by-column DOM projection.\n\nAttribute: `page-size`","type":"number","default":"100"},{"name":"paginationMode","description":"Attribute: `pagination-mode`  \nReflected to its attribute.","type":"'client' | 'server'","default":"'client'"},{"name":"priorityColumnsToggleAvailable","description":"Whether the reveal/hide control is currently offered at all -- the public, read-only\ncounterpart of the measurement `[part='reveal-columns-button']` itself renders from. True\nwhile at least one `priority` column is actually hidden at the current allocation, and it\nstays true once `priorityColumnsVisible` has revealed those columns (otherwise the control\nwould remove itself the moment it was used, stranding the columns visible). Always false with\nno `priority` column declared, which is the state the inert-configuration development\nwarning describes. Remeasured from the live DOM after every render and on every container\nresize, so read it after `await table.updateComplete`.","type":"boolean","read-only":true},{"name":"priorityColumnsVisible","description":"Forces `priority`-hidden columns back into view, overriding the\nmeasured-overflow hide rules in table.styles.ts. Toggles itself on\n`[part='reveal-columns-button']` activation by default — no external\nwiring is required for the button to work. Also settable from outside\n(property or the reflected `priority-columns-visible` attribute) to restore a\npreviously-persisted preference. The single\n`lr-priority-columns-visibility-change` event reports button-driven changes.\n\nAttribute: `priority-columns-visible`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"revealColumnsLabel","description":"Attribute: `reveal-columns-label`","type":"string | undefined"},{"name":"rowExpandLabel","description":"Accessible name for one row's expand/collapse chevron, read once per render for that row,\nexactly like a column's `editLabel`/`cellTitle`. Consumer-owned text: it is used verbatim and\nnever passed through the localization runtime.\n\nOmit it and every chevron in the table shares the same localized `expand`/`collapse` name,\nwhich carries no row context. That is fine for a handful of rows, but each chevron is its own\nTab stop, so a long table otherwise announces the same two names over and over with no way to\ntell the rows apart. There is no default row context to add here: this component has no\nrow-header notion to derive one from (`rowKey` is an opaque identity, not a label).","type":"(row: T, expanded: boolean) => string | undefined"},{"name":"rowKey","description":"Derives each row's stable identity for `repeat()`'s DOM-reconciliation\nkey and the delegated click/keydown row lookup (`rowsByKey`,\n`data-row-key`). When omitted, `keyOf()` falls back to the row's index\nin `rows`, which is only a safe identity while `rows` never reorders —\nprovide `rowKey` whenever `rows` can be sorted, filtered, or otherwise\nre-ordered across renders, or row identity (selection, focus, click\ntargets) can silently attach to the wrong row. Empty string identities and later duplicates\nare omitted before every rendered/count/focus/action/event path; the first valid occurrence\nwins.","type":"(row: T) => K | undefined"},{"name":"rowTotal","description":"Renders a trailing `<td>` on every body row holding this row's total. Same\n\"consumer computes/renders, table only positions\" contract as the existing per-column\n`footer(rows)` — does not assume addition, so a non-sum aggregate works identically. Omit for\nno trailing column at all (unchanged output).","type":"(row: T) => unknown | undefined"},{"name":"rows","description":"Clone-owned readonly row sequence, bounded to the first 10,000 rows. Row objects are retained\nhere; the rendered model applies `rowKey` as one unique nonempty first-wins identity\nprojection before filtering, counts, pagination, focus, actions, and events. Reassign the\ncollection to update.","type":"readonly T[]"},{"name":"scrollMode","description":"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\nAttribute: `scroll-mode`  \nReflected to its attribute.","type":"TableScrollMode","default":"'self'"},{"name":"selectedRowKeys","description":"Selected raw row keys in every selection mode, bounded to 10,000 keys. Single mode replaces\nthis set with exactly one key per row activation; multiple mode toggles membership. Reads\nreturn immutable detached `ReadonlySet` facades; malformed and whitespace-only string keys are\nomitted while valid off-page keys are retained for server pagination. Reassign a new set to\nupdate.","type":"ReadonlySet<K>"},{"name":"selectionMode","description":"Attribute: `selection-mode`  \nReflected to its attribute.","type":"TableSelectionMode","default":"'none'"},{"name":"skeletonRows","description":"Number of placeholder rows rendered by `loadingAppearance=\"skeleton\"`. `0` (the default)\nrenders 3 placeholders for the ordinary bounded default, or derives a non-default explicit\n`pageSize` (capped at 20). Positive explicit values are also capped at 20. Ignored entirely\nunder the default spinner appearance.\n\nAttribute: `skeleton-rows`","type":"number","default":"0"},{"name":"sortDir","description":"Attribute: `sort-dir`","type":"TableSortDirection","default":"'asc'"},{"name":"sortIndicators","description":"`'active'` preserves the active-column chevron alone. `'all'` also reserves the same icon\nspace with a muted bidirectional indicator in inactive sortable headers, including on touch\nscreens. This presentation choice does not change sorting, focus or aria-sort semantics.\n\nAttribute: `sort-indicators`","type":"TableSortIndicators","default":"'active'"},{"name":"sortKey","description":"Attribute: `sort-key`","type":"string","default":"''"},{"name":"sortMode","description":"`'client'` (the default) orders `rows` itself, in the browser, from `sortKey`/`sortDir` and\nthe active column's `sortValue`. `'server'` renders `rows` in exactly the order given,\nassuming the caller has already sorted them — mirroring `paginationMode`'s identical\nclient/server split. Header activation first emits cancelable `lr-sort-request`; an accepted\nactivation emits `lr-sort` either way, but only client mode mutates these properties.\n\nWith no `sortKey` set (the default) `'client'` is a no-op: the input order is preserved\nverbatim, so an existing consumer that only listens for `lr-sort` sees unchanged rendering\nuntil a header is actually activated.\n\nAttribute: `sort-mode`  \nReflected to its attribute.","type":"TableSortMode","default":"'client'"},{"name":"spellcheck","description":"Forwarded to the filter input's, and (when the active column's `editType` is `'text'`, the\ndefault) the inline cell-editor input's, native `spellcheck`. Defaults to `true`, matching\nthe native element's own default. `spellcheck=\"false\"` is parsed as `false` (see\n`spellcheckConverter` above). No effect on a `'number'` or `'select'` cell editor.\n\nAttribute: `spellcheck`","type":"boolean","default":"true"},{"name":"storageKey","description":"Persists `priorityColumnsVisible` to `localStorage` across reloads when set. Namespaced as\n`lr-table:${storageKey}`. Restoration never overwrites a `priorityColumnsVisible` the consumer\ndeclared on the same mount (`priority-columns-visible` present, or a\n`.priorityColumnsVisible=${...}` binding) -- including a binding that pins it to `false`, its\nown default. The same \"explicit beats persisted\" guarantee as `lr-app-rail`'s and\n`lr-widget`'s `storage-key` restores, which share this one's write-tracking mechanism.\n\nAttribute: `storage-key`","type":"string | undefined"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"totalItems","description":"Total item count for server pagination; `-1` derives it from filtered rows.\n\nAttribute: `total-items`","type":"number","default":"-1"},{"name":"unknownTotal","description":"Marks server pagination as indeterminate -- the caller has no total item count, only whether\none more page exists (`hasNext`). Forwarded to the nested `<lr-pagination>` as its own\nindeterminate mode (a `total=\"-1\"` sentinel; see that component's docs), which then renders\nprevious/next only, with no numbered page list and no item-range summary. A dedicated boolean\nrather than a second magic `totalItems` value: `totalItems=\"-1\"` already means \"derive from\nthe currently matching rows\", and stacking a different meaning onto another negative number\nwould be exactly the kind of easy-to-mistake sentinel this library avoids elsewhere. Ignored\noutside `paginationMode: 'server'` -- client mode always knows the exact row count it slices,\nso it never needs the indeterminate layout.\n\nAttribute: `unknown-total`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"viewRows","description":"`rows` after filtering and (client-mode) sorting, ignoring pagination -- the same set\n`columns[].footer(rows)`/`grandTotal(rows)` and the heat-tint domain already compute over.\nLets a consumer that needs \"what the grid currently shows\" (e.g. exporting the visible rows)\nread this instead of re-implementing filtering/sorting itself. Reads `sortedEntries()`'s\nexisting memoized cache, so an unrelated update (a roving-tabindex move, an inline-editor\nopen, ...) costs nothing extra here. Always a fresh, frozen array: mutating what this returns\ncannot reach or corrupt the table's own internal state.","type":"readonly T[]","read-only":true}],"events":[{"name":"blur","description":"Re-dispatched from the internal filter/cell-editor native inputs' own `blur`, for the same reason as `focus`.","type":"CustomEvent<null>"},{"name":"focus","description":"Re-dispatched from the internal filter/cell-editor native inputs' own `focus` — bubbling and composed (unlike the native event, which is neither).","type":"CustomEvent<null>"},{"name":"lr-cell-edit","description":"An inline editor committed a value. `detail: { row, columnKey, value }`.","type":"CustomEvent<Readonly<{ row: T; columnKey: string; value: string | number }>>"},{"name":"lr-column-resize","description":"A resizable column changed width by pointer or keyboard. `detail: { columnKey, width }`, where `width` is in CSS pixels. A pointer drag fires this once per pixel of movement as non-cancelable live feedback, then once more, **cancelable**, for the final width committed at drag-end; a keyboard step (Home/End/Arrow) is already a single discrete action and fires that one cancelable commit directly. `preventDefault()` on a cancelable emission reverts the column to its pre-gesture width -- unless the listener resolved the resize itself during that same synchronous dispatch, in which case the width it applied stands instead of being rolled back over.","type":"CustomEvent<Readonly<{ columnKey: string; width: number }>>"},{"name":"lr-filter-change","description":"The filter field changed. Frozen readonly `detail: { text }`.","type":"CustomEvent<Readonly<{ text: string }>>"},{"name":"lr-load-more","description":"The \"load more\" control was activated.","type":"CustomEvent<null>"},{"name":"lr-page-change","description":"A pagination control requested a page. Frozen readonly `detail: { page }`.","type":"CustomEvent<Readonly<{ page: number }>>"},{"name":"lr-priority-columns-visibility-change","description":"`priorityColumnsVisible` was toggled by `[part='reveal-columns-button']`. Frozen readonly `detail: { visible: boolean }`.","type":"CustomEvent<Readonly<{ visible: boolean }>>"},{"name":"lr-retry","description":"The built-in `[part='retry-button']` was activated, only rendered while `error` is set. Cancelable: the default action clears `error`; `preventDefault()` leaves it set instead.","type":"CustomEvent<null>"},{"name":"lr-row-click","description":"A row was activated. `detail: { row }`.","type":"CustomEvent<Readonly<{ row: T }>>"},{"name":"lr-row-expand-request","description":"Cancelable proposal before a self-managed expansion change. Frozen readonly `detail: { row, rowKey, expanded }`, where `expanded` is the state being proposed. Emitted only while `expansionMode` is `'single'` or `'multiple'`; vetoing it skips the built-in `expandedRowKeys` write and suppresses the following `lr-row-expand-toggle`, leaving the row's expansion fully controlled.","type":"CustomEvent<Readonly<{ row: T; rowKey: K; expanded: boolean }>>"},{"name":"lr-row-expand-toggle","description":"The row-expand chevron was activated. Frozen readonly `detail: { row, rowKey, expanded }`, where `expanded` is the state the activation resolves to. Fired only when `expandedContent` is set and the row passes `canExpand`. Under the default `expansionMode: 'none'` it does not itself mutate `expandedRowKeys` — the consumer updates it and passes the new value back in. Under a self-managed mode it follows an unvetoed `lr-row-expand-request` and the write has already landed, so a listener reading `expandedRowKeys` sees the new state. `'single'` additionally fires it once with `expanded: false` for the row it just closed to make room, immediately before the accepted one, so a host mirroring open rows from this event alone stays correct — with one boundary: a displaced row that is filtered or paged out of view has no `row` object to describe, so that case is reported only through `expandedRowKeys`. The `'single'` coercion that runs when `expansionMode` itself becomes `'single'` reports through `expandedRowKeys` alone for the same reason — a key that matches no rendered row cannot carry a `row`.","type":"CustomEvent<Readonly<{ row: T; rowKey: K; expanded: boolean }>>"},{"name":"lr-selection-change","description":"Opt-in row selection changed, from a row activation or from a `selectionMode` flip to `'single'` coercing an existing multi-row selection down to one key. Frozen readonly `detail: { rowKeys: readonly K[] }` — `readonly (string | number)[]` on an unparameterized table, the default `K`. Not cancelable in either case: it announces a selection that has already changed rather than proposing one.","type":"CustomEvent<Readonly<{ rowKeys: readonly K[] }>>"},{"name":"lr-sort","description":"Accepted sort transaction. Frozen readonly `detail: { phase: 'commit', sortKey, sortDir }`. Client mode also updates `sortKey`/`sortDir`; server mode leaves them controlled while reporting the accepted proposal.","type":"CustomEvent<TableSortCommitDetail>"},{"name":"lr-sort-request","description":"Cancelable sort proposal. Frozen readonly `detail: { phase: 'request', sortKey, sortDir }`. Vetoing it leaves sort state and rows unchanged and suppresses `lr-sort`.","type":"CustomEvent<TableSortRequestDetail>"}]}},{"name":"lr-tag","description":"`<lr-tag>` — the compact badge treatment with tag semantics: the same `variant`/`size`/\n`appearance`/`pill`/`attention` surface as `<lr-badge>`, plus an optional remove affordance for\na tag standing in for a dismissible selection, filter, or keyword.\n\nLike `<lr-chip>`, removal is controlled: activating the remove action emits one notification and\nleaves the tag connected. The consumer updates its own source state and removes the tag.\nA host `aria-label` names one aggregate `role=\"group\"`; the nested remove button retains a\npurpose-specific name derived from visible tag text or the localized remove fallback.\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) | Tag content. A removable tag keeps its action name synchronized with visible accessible label text through forwarding slots. |\n| `end` | Content placed after the label, typically an icon. |\n| `start` | Content placed before the label, typically an icon. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `badge` | The badge surface. It is the same node as `base`. |\n| `base` | The tag surface. |\n| `content` | Wrapper around the default slot; the part that truncates with an ellipsis. |\n| `end` | Wrapper around the `end` slot. Hidden entirely while empty. |\n| `remove-button` | The remove affordance, only rendered while `withRemove`. |\n| `remove-button__base` | Shoelace-compatible alias for `remove-button`; both names are on the same node. |\n| `start` | Wrapper around the `start` slot. Hidden entirely while empty. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-badge-attention-duration` (default: `var(--lr-duration-ambient)`) — One cycle of the `attention` animation.\n- `--lr-badge-attention-easing` (default: `var(--lr-easing-emphasized)`) — Timing function of the `attention` animation.\n- `--lr-badge-background` (default: `var(--lr-badge-fill)`) — Explicit override for the badge's background, winning over whatever `variant` and `appearance` resolved. Left unset (the default) so it still inherits from a consumer's own ancestor rule.\n- `--lr-badge-border` (default: `var(--lr-badge-stroke)`) — Explicit override for the badge's border color, on the same terms as `--lr-badge-background`.\n- `--lr-badge-bounce-distance` (default: `var(--lr-size-0-1875rem)`) — Peak travel of the `attention=\"bounce\"` hop.\n- `--lr-badge-color` (default: `var(--lr-badge-text)`) — Explicit override for the badge's text color, on the same terms as `--lr-badge-background`.\n- `--lr-badge-edge` (default: `var(--lr-color-border)`) — Palette slot: the variant's border color. Its private default follows each non-neutral `variant`'s loud fill; an inherited or direct public value remains authoritative.\n- `--lr-badge-fill` (default: `var(--lr-badge-tint)`) — Surface slot: which palette entry `appearance` routed onto the background. Set it to retune a single appearance without touching the palette.\n- `--lr-badge-font-size` (default: `var(--lr-font-size-sm)`) — The badge's label font size. Each `size` sets it to that step's font size.\n- `--lr-badge-gap` (default: `var(--lr-space-2xs)`) — Space between the `start` slot, the label, and the `end` slot.\n- `--lr-badge-ink` (default: `var(--lr-color-text)`) — Palette slot: the variant's text color. Its private default follows each non-neutral `variant`'s loud fill; an inherited or direct public value remains authoritative.\n- `--lr-badge-min-height` (default: `var(--lr-size-1-25rem)`) — The badge's minimum block size. Each `size` sets it to that step's minimum block size.\n- `--lr-badge-on-solid` (default: `var(--lr-color-on-loud)`) — Palette slot: the text color that stays legible on `--lr-badge-solid`.\n- `--lr-badge-padding-inline` (default: `var(--lr-space-s)`) — The badge's inline padding. Each `size` sets it to that step's inline padding.\n- `--lr-badge-pulse-color` (default: `color-mix(in srgb, currentColor 40%, transparent)`) — Color of the expanding ring drawn by `attention=\"pulse\"`.\n- `--lr-badge-pulse-spread` (default: `var(--lr-size-0-25rem)`) — How far the `attention=\"pulse\"` ring expands.\n- `--lr-badge-radius` (default: `var(--lr-radius)`) — Corner radius of the badge surface. `pill` raises it to `var(--lr-radius-pill)`. Does not vary by `size` tier.\n- `--lr-badge-solid` (default: `var(--lr-color-fill-loud)`) — Palette slot: the variant's loud fill, used by `appearance=\"accent\"`.\n- `--lr-badge-stroke` (default: `var(--lr-badge-edge)`) — Surface slot: which palette entry `appearance` routed onto the border color.\n- `--lr-badge-text` (default: `var(--lr-badge-ink)`) — Surface slot: which palette entry `appearance` routed onto the label color.\n- `--lr-badge-tint` (default: `var(--lr-color-surface)`) — Palette slot: the variant's quiet fill. Its private default follows each non-neutral `variant`'s quiet fill from the shared semantic grid; an inherited or direct public value remains authoritative.\n- `--lr-tag-remove-hover-background` (default: `color-mix(in srgb, currentColor 16%, transparent)`) — Background of the remove button on hover.\n- `--lr-tag-remove-radius` (default: `var(--lr-badge-radius)`) — Corner radius of the remove button, defaulting to the tag's own corner so retuning one retunes both.\n- `--pulse-color` (default: `var(--lr-badge-pulse-color)`) — Upstream-compatible pulse-ring color.","attributes":[{"name":"appearance","description":"How much of the `variant` palette is spent on fill, border, and text. The default\n(`filled-outlined`: quiet tint, loud border, loud text) reproduces the badge's original\ntreatment.\n\nType: `BadgeAppearance`  \nDefault: `'filled-outlined'`","value":{"type":["'accent'","'filled'","'outlined'","'filled-outlined'","'plain'"]}},{"name":"attention","description":"Opt-in attention-seeking animation. An explicit `'none'` suppresses the `pulse` shorthand.\nStops entirely under `prefers-reduced-motion: reduce`.\n\nType: `BadgeAttention`  \nDefault: `'none'`","value":{"type":["'none'","'pulse'","'bounce'"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"pill","description":"Draws fully-rounded ends instead of the default rounded rectangle.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"pulse","description":"Upstream-compatible pulse shorthand. Equivalent to `attention=\"pulse\"` only while the\n`attention` attribute is omitted; every explicit attention value takes precedence.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"removable","description":"Shoelace-compatible alias for `withRemove`, backed by the same authority.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"size","description":"Visual density, matching `<lr-chip>`'s `3xs`–`xl` size scale. `m` preserves the original\nbadge dimensions. Valid `small`/`medium`/`large` values round-trip exactly.\n\nType: `BadgeSize`  \nDefault: `'m'`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}},{"name":"variant","description":"Semantic palette. Every valid upstream spelling remains observable verbatim; rendering uses\nthe private canonical value instead of rewriting the public property or reflected attribute.\n\nType: `TagVariant`  \nDefault: `'neutral'`","value":{"type":["'neutral'","'brand'","'success'","'warning'","'danger'","'primary'","'text'"]}},{"name":"with-remove","description":"Renders the remove affordance. Either mirrored attribute enables the shared state; assigning\nfalse through either property clears both attributes so the write reads back truthfully.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"","description":"Tag content. A removable tag keeps its action name synchronized with visible accessible label text through forwarding slots."},{"name":"end","description":"Content placed after the label, typically an icon."},{"name":"start","description":"Content placed before the label, typically an icon."}],"js":{"properties":[{"name":"appearance","description":"How much of the `variant` palette is spent on fill, border, and text. The default\n(`filled-outlined`: quiet tint, loud border, loud text) reproduces the badge's original\ntreatment.\n\nAttribute: `appearance`  \nReflected to its attribute.","type":"BadgeAppearance","default":"'filled-outlined'"},{"name":"attention","description":"Opt-in attention-seeking animation. An explicit `'none'` suppresses the `pulse` shorthand.\nStops entirely under `prefers-reduced-motion: reduce`.\n\nAttribute: `attention`  \nReflected to its attribute.","type":"BadgeAttention","default":"'none'"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"pill","description":"Draws fully-rounded ends instead of the default rounded rectangle.\n\nAttribute: `pill`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"pulse","description":"Upstream-compatible pulse shorthand. Equivalent to `attention=\"pulse\"` only while the\n`attention` attribute is omitted; every explicit attention value takes precedence.\n\nAttribute: `pulse`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"removable","description":"Shoelace-compatible alias for `withRemove`, backed by the same authority.\n\nAttribute: `removable`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"size","description":"Visual density, matching `<lr-chip>`'s `3xs`–`xl` size scale. `m` preserves the original\nbadge dimensions. Valid `small`/`medium`/`large` values round-trip exactly.\n\nAttribute: `size`  \nReflected to its attribute.","type":"BadgeSize","default":"'m'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"variant","description":"Semantic palette. Every valid upstream spelling remains observable verbatim; rendering uses\nthe private canonical value instead of rewriting the public property or reflected attribute.\n\nAttribute: `variant`  \nReflected to its attribute.","type":"TagVariant","default":"'neutral'"},{"name":"withRemove","description":"Renders the remove affordance. Either mirrored attribute enables the shared state; assigning\nfalse through either property clears both attributes so the write reads back truthfully.\n\nAttribute: `with-remove`  \nReflected to its attribute.","type":"boolean","default":"false"}],"events":[{"name":"lr-remove","description":"Noncancelable notification that the remove button was activated (click, or Enter/Space while focused — native `<button>` behavior). The consumer owns the state update and DOM removal. Only rendered, and therefore only fired, while `withRemove` or its Shoelace-compatible `removable` alias is set. The event's `target` is the tag.","type":"CustomEvent<null>"}]}},{"name":"lr-task-list","description":"`<lr-task-list>` — a live, collapsible tracker for an agent's plan: ordered steps with\nper-step lifecycle status and one level of nested sub-steps, embedded in the transcript.\n`items` is controlled and never mutated by this component, mirroring `<lr-stepper>`'s `steps`\ncontract. Unlike stepper's single-`current` navigation control, task-list has no selection and\nseveral steps may be `running` at once. Set `reorderable` to request sibling-scoped keyboard\nmoves; the host applies the reordered `items` array. Non-record rows and rows without a nonempty\nstring id are omitted. Reordering additionally requires globally unique ids among every retained\ntop-level task and direct child; duplicate data stays visible but fails closed.\nThe visible header is a level-three heading by default; set `heading-level` from `1`–`6` to fit\nthe surrounding document outline, or `none` for a visual-only header.\nStatus changes and confirmed moves are announced through an internal `<lr-live-region>`.\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\nOnly the first 500 top-level items are mounted into the DOM (matching the render ceiling this\nfamily's other bounded lists use); the header's \"N of M completed\" summary still counts every\nitem in `items`, and reorder index math still reads full sibling order from `items` regardless\nof what is actually rendered.\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| `detail-<id>` | Dynamic, one per item id (e.g. `slot=\"detail-step-3\"`). Rich detail under that item's label, after its `detail` text -- typically a `<lr-tool-call-chip>` or file `<lr-chip>`. Plain-HTML friendly, no render props. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The outer container. |\n| `body` | The list of items, `hidden` while collapsed. |\n| `header` | The visible header content (a `<button>` when `collapsible`, a plain wrapper otherwise), inside the configurable semantic heading. |\n| `item` | One item row (`role=\"listitem\"`); carries `data-status`, `data-id`, `data-depth` (`\"0\"` for a top-level item, `\"1\"` for a child), and is keyboard-focusable only for valid `reorderable` data. |\n| `item-children` | The nested `role=\"list\"` wrapper around a top-level item's children. |\n| `item-detail` | The item's optional `detail` text. |\n| `item-label` | The item's `label` text. |\n| `label` | The `label` text. |\n| `status-icon` | The per-item status glyph. |\n| `summary` | The visible \"N of M completed\" summary, counting only top-level items. |\n| `toggle` | The chevron indicator inside the header. Only rendered when `collapsible`. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-task-list-background` (default: `var(--lr-color-surface)`) — Fill of the outer card (`[part=\"base\"]`) while `frame=\"card\"`. `frame=\"plain\"` still removes the fill entirely.\n- `--lr-task-list-border-color` (default: `var(--lr-color-border)`) — Colour of the outer card's border and of the header/body divider, which `frame=\"plain\"` keeps.\n- `--lr-task-list-compact-body-padding` (default: `var(--lr-space-2xs) var(--lr-space-s) var(--lr-space-s)`) — `[part=\"body\"]` padding while `compact`.\n- `--lr-task-list-compact-gap` (default: `var(--lr-space-2xs)`) — Gap between `[part=\"body\"]`'s item rows while `compact`.\n- `--lr-task-list-compact-header-font-size` (default: `var(--lr-font-size-sm)`) — `[part=\"header\"]` font size while `compact`.\n- `--lr-task-list-compact-header-gap` (default: `var(--lr-space-2xs)`) — Gap between `[part=\"header\"]`'s toggle/label/summary while `compact`.\n- `--lr-task-list-compact-header-padding` (default: `var(--lr-space-2xs) var(--lr-space-s)`) — `[part=\"header\"]` padding while `compact`.\n- `--lr-task-list-error-color` (default: `var(--lr-color-danger)`) — Error status icon color.\n- `--lr-task-list-pending-color` (default: `var(--lr-color-text-quiet)`) — Pending status icon color.\n- `--lr-task-list-radius` (default: `var(--lr-radius)`) — Corner radius of the outer card. `frame=\"plain\"` still squares the corners.\n- `--lr-task-list-running-color` (default: `var(--lr-color-brand)`) — Running status icon color.\n- `--lr-task-list-spin` (default: `var(--lr-transition-ambient)`) — Running-status icon spin animation duration/timing.\n- `--lr-task-list-success-color` (default: `var(--lr-color-success)`) — Success status icon color.","attributes":[{"name":"collapsible","description":"When `false`, the header renders as a static heading (no button, no toggle affordance) and\n`expanded` can still be set programmatically by the host, just not toggled via the UI.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"compact","description":"Tighter header/body padding and item gap for dense contexts (a plan tracker nested in an\nalready-padded transcript row) -- same convention as `lr-agent-run`/`lr-source-card`'s\n`compact`. Defaults to `false`, i.e. the full padding. Purely a density knob: the border and\nbackground stay, so use `frame=\"plain\"` instead to drop the chrome entirely.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"expanded","description":"Whether the body (item list) is currently shown. Defaults open -- this is a progress surface,\nnot a details disclosure a reader opts into.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"frame","description":"Visual chrome, in the library's shared container-frame vocabulary. `'card'` (the default)\nkeeps the bordered, filled box. `'plain'` removes `[part=\"base\"]`'s border, background, and\ncorner radius, so a list embedded in the transcript inside a container that already draws a\nborder (an agent-run panel, a message bubble) doesn't double it.\n\nType: `LyraFrame`  \nDefault: `'card'`","value":{"type":["'card'","'plain'"]}},{"name":"heading-level","description":"Semantic level of the visible header. Use `none` to keep the visual header without exposing\nit to heading navigation. Invalid untyped values use level 3.\n\nType: `LyraHeadingLevel`  \nDefault: `'3'`","value":{"type":["'1'","'2'","'3'","'4'","'5'","'6'","'none'"]}},{"name":"label","description":"Optional header-text override. Omission localizes `taskListLabel`; any supplied string,\nincluding `'Tasks'` or `''`, is rendered verbatim.\n\nType: `string | undefined`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"reorderable","description":"Opts into Ctrl/Cmd+ArrowUp/ArrowDown reorder requests. `items` remains host-owned: the\ncomponent never moves a task until the host reassigns a confirmed sibling order. All ids\nacross top-level tasks and direct children must be unique; otherwise the feature fails closed\nwith no row tab stops or `lr-reorder` requests.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"detail-<id>","description":"Dynamic, one per item id (e.g. `slot=\"detail-step-3\"`). Rich detail under that item's label, after its `detail` text -- typically a `<lr-tool-call-chip>` or file `<lr-chip>`. Plain-HTML friendly, no render props."}],"js":{"properties":[{"name":"collapsible","description":"When `false`, the header renders as a static heading (no button, no toggle affordance) and\n`expanded` can still be set programmatically by the host, just not toggled via the UI.\n\nAttribute: `collapsible`","type":"boolean","default":"true"},{"name":"compact","description":"Tighter header/body padding and item gap for dense contexts (a plan tracker nested in an\nalready-padded transcript row) -- same convention as `lr-agent-run`/`lr-source-card`'s\n`compact`. Defaults to `false`, i.e. the full padding. Purely a density knob: the border and\nbackground stay, so use `frame=\"plain\"` instead to drop the chrome entirely.\n\nAttribute: `compact`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"expanded","description":"Whether the body (item list) is currently shown. Defaults open -- this is a progress surface,\nnot a details disclosure a reader opts into.\n\nAttribute: `expanded`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"frame","description":"Visual chrome, in the library's shared container-frame vocabulary. `'card'` (the default)\nkeeps the bordered, filled box. `'plain'` removes `[part=\"base\"]`'s border, background, and\ncorner radius, so a list embedded in the transcript inside a container that already draws a\nborder (an agent-run panel, a message bubble) doesn't double it.\n\nAttribute: `frame`  \nReflected to its attribute.","type":"LyraFrame","default":"'card'"},{"name":"headingLevel","description":"Semantic level of the visible header. Use `none` to keep the visual header without exposing\nit to heading navigation. Invalid untyped values use level 3.\n\nAttribute: `heading-level`  \nReflected to its attribute.","type":"LyraHeadingLevel","default":"'3'"},{"name":"items","description":"The plan. Controlled and never mutated by this component -- pass a new array to update it.\nRuntime non-record rows and rows without a nonempty string id are omitted before rendering,\nsummaries, announcements, and reorder validation.","type":"readonly TaskItem[]","default":"[]"},{"name":"label","description":"Optional header-text override. Omission localizes `taskListLabel`; any supplied string,\nincluding `'Tasks'` or `''`, is rendered verbatim.\n\nAttribute: `label`","type":"string | undefined"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"reorderable","description":"Opts into Ctrl/Cmd+ArrowUp/ArrowDown reorder requests. `items` remains host-owned: the\ncomponent never moves a task until the host reassigns a confirmed sibling order. All ids\nacross top-level tasks and direct children must be unique; otherwise the feature fails closed\nwith no row tab stops or `lr-reorder` requests.\n\nAttribute: `reorderable`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-reorder","description":"`detail: { taskId, parentTaskId, fromIndex, toIndex }` — Ctrl/Cmd+ArrowUp/ArrowDown requests moving the focused task within its own sibling list (`parentTaskId` is `null` for a top-level task; indices are sibling-scoped). Only fired while `reorderable` with unique ids; a boundary key never reparents. A move is announced only after the rendered order confirms it.","type":"CustomEvent<{\n    taskId: string;\n    parentTaskId: string | null;\n    fromIndex: number;\n    toIndex: number;\n  }>"},{"name":"lr-toggle","description":"The header was activated, expanding or collapsing the panel. `detail: { expanded }`.","type":"CustomEvent<TaskListToggleDetail>"}]}},{"name":"lr-terminal","description":"`<lr-terminal>` — read-only ANSI console for streamed agent/tool output. Not a PTY: no\nstdin/keystroke handling, no cursor-addressed full-screen apps. Split ANSI sequences retain at\nmost 4,096 characters; an overlong unterminated control sequence is dropped so later chunks\nresume without an unbounded hidden carry.\n\n`compact` tightens the toolbar and line padding for dense transcript rows, and `frame=\"plain\"`\nremoves the outer card chrome when a surrounding container already supplies it — the same pair\n`lr-result-card`, `lr-stack-trace`, `lr-task-list`, and `lr-thinking-panel` expose.\n\nDeliberately no `maxHeight`/`--lr-terminal-max-height` pair (unlike `lr-json-viewer`,\n`lr-diff-view`, `lr-code-block`, `lr-stack-trace`, and `lr-markdown`): those default to `none`\nand grow with their content until a caller opts into a cap. This component's `[part=\"viewport\"]`\nis *always* a fixed-height virtualized scrollback region — `--lr-terminal-height` (default\n`20rem`) already is that cap, retunable the same way. A second, differently-shaped \"grows until\ncapped\" property would fight that always-scrolling model rather than complement it.\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| `announcer` | The visually-hidden, `aria-hidden` mirror of the text last announced while `announce-output` is set. The announcement itself lands in the shared light-DOM region (`acquireAnnouncementSink()` in `internal/announcer.ts`), because a live region inside a shadow root is not reliably announced; this part is a styling/inspection surface only. |\n| `base` | The outer container. |\n| `copy-button` | The copy-to-clipboard button. |\n| `download-button` | The download button. |\n| `jump-to-latest` | The pill shown while `follow` is disengaged and new output has arrived. |\n| `line` | One rendered line; carries `data-line-number`, `data-match`, `data-highlight-tone`. Rendered through `<lr-virtual-list>`'s `renderItem`, so it lives inside that element's own shadow root rather than this component's -- this component's own stylesheet reaches it via `lr-virtual-list::part(line)`, one hop of the standard CSS Shadow Parts selector. |\n| `line-active-match` | Alias on the active search-match line. |\n| `line-highlight-accent` | Alias on an accent-highlighted line. |\n| `line-highlight-danger` | Alias on a danger-highlighted line. |\n| `line-highlight-neutral` | Alias on a neutral-highlighted line. |\n| `line-highlight-success` | Alias on a success-highlighted line. |\n| `line-highlight-warning` | Alias on a warning-highlighted line. |\n| `line-interactive` | Alias on a line that owns an activatable highlight. |\n| `line-match` | Alias on a line containing a search match. |\n| `toolbar` | The header row, only rendered when copy/download are enabled. |\n| `viewport` | The `role=\"log\"` scrollable region wrapping the virtualized line list. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-terminal-border-color` (default: `var(--lr-color-border)`) — Colour of the outer card's border and of the toolbar/log divider, which `frame=\"plain\"` keeps.\n- `--lr-terminal-compact-line-padding-inline` (default: `var(--lr-space-xs)`) — Inline padding of each rendered `[part=\"line\"]` while `compact`.\n- `--lr-terminal-compact-toolbar-gap` (default: `var(--lr-space-2xs)`) — Gap between `[part=\"toolbar\"]`'s buttons while `compact`.\n- `--lr-terminal-compact-toolbar-padding` (default: `var(--lr-space-2xs) var(--lr-space-xs)`) — `[part=\"toolbar\"]` padding while `compact`.\n- `--lr-terminal-height` (default: `var(--lr-size-20rem)`) — Block size of `[part=\"viewport\"]`, the scrollable log region. Not declared on `:host`, so it is inherited — set it on the host or any ancestor.\n- `--lr-terminal-highlight-accent-bg` (default: `var(--lr-color-brand-quiet)`) — Background of an `accent`-tone highlighted line. Decoupled from the shared `--lr-color-brand-quiet` token also used by `[part=\"copy-button\"]`/`[part=\"download-button\"]`'s hover state, and from any `::part('line')` override (the background is applied inline, so a stylesheet rule can't beat it without `!important`).\n- `--lr-terminal-highlight-danger-bg` (default: `var(--lr-color-danger-quiet)`) — Background of a `danger`-tone highlighted line.\n- `--lr-terminal-highlight-neutral-bg` (default: `var(--lr-color-surface)`) — Background of a `neutral`-tone highlighted line.\n- `--lr-terminal-highlight-success-bg` (default: `var(--lr-color-success-quiet)`) — Background of a `success`-tone highlighted line.\n- `--lr-terminal-highlight-warning-bg` (default: `var(--lr-color-warning-quiet)`) — Background of a `warning`-tone highlighted line.\n- `--lr-terminal-line-active-bg` (default: `color-mix(in oklab, var(--lr-terminal-line-hover-bg, var(--lr-color-brand-quiet)), var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Pressed background of an ordinary rendered line.\n- `--lr-terminal-line-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background of an ordinary rendered `[part=\"line\"]`.\n- `--lr-terminal-radius` (default: `var(--lr-radius)`) — Corner radius of the outer card. `frame=\"plain\"` still squares the corners.\n- `--lr-terminal-search-active-outline-color` (default: `var(--lr-color-brand)`) — Outline color for the active search match's line.\n- `--lr-terminal-search-outline-color` (default: `var(--lr-color-warning)`) — Outline color for a line containing a non-active search match.\n- `--lr-terminal-surface-color` (default: `var(--lr-color-surface-raised)`) — Card-frame background and the fallback foreground for inverse ANSI segments without an explicit background. The `frame=\"plain\"` escape remains transparent.\n- `--lr-terminal-toolbar-button-active-bg` (default: `color-mix(in oklab, var(--lr-terminal-toolbar-button-hover-bg, var(--lr-color-brand-quiet)), var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Pressed background of the toolbar buttons.\n- `--lr-terminal-toolbar-button-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Hover background of `[part=\"copy-button\"]` and `[part=\"download-button\"]`.","attributes":[{"name":"announce-output","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"aria-label","description":"Accessible name for the nested `role=\"log\"`; a non-empty host `aria-label` is forwarded,\nwhile an empty value falls back to the localized terminal-purpose label.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"compact","description":"Tightens the toolbar's padding/gap and each rendered line's inline padding for a terminal\nembedded in an already-padded transcript row -- same convention as `lr-task-list`'s and\n`lr-thinking-panel`'s `compact`. Defaults to `false`, i.e. the full padding. Purely a density\nknob: the card border and background stay, so use `frame=\"plain\"` to drop the chrome.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"content","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"copyable","description":"Type: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"downloadable","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"filename","description":"Type: `string`  \nDefault: `'terminal.log'`","value":{"type":["string"]}},{"name":"follow","description":"Type: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"frame","description":"Visual chrome, in the library's shared container-frame vocabulary. `'card'` (the default)\nkeeps `[part=\"base\"]`'s border, corner radius, and raised surface; `'plain'` removes all\nthree so a terminal nested inside a container that already draws a border (an agent-run\npanel, a message bubble) doesn't double it. Plain keeps the toolbar/log divider and whichever\nregular or compact padding applies -- it controls outer chrome only.\n\nType: `LyraFrame`  \nDefault: `'card'`","value":{"type":["'card'","'plain'"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max-scrollback","description":"Line-count scrollback buffer limit. NaN/negative/oversized (e.g. `Infinity`) normalize to a\n1..10,000 range; total retained cells and cells per line have independent hard ceilings.\n\nType: `number`  \nDefault: `5000`","value":{"type":["number"]}},{"name":"wrap","description":"Type: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}}],"js":{"properties":[{"name":"accessibleLabel","description":"Accessible name for the nested `role=\"log\"`; a non-empty host `aria-label` is forwarded,\nwhile an empty value falls back to the localized terminal-purpose label.\n\nAttribute: `aria-label`","type":"string","default":"''"},{"name":"activeHighlightId","type":"string | null","default":"null"},{"name":"anchorKinds","description":"Feature-detectable capability mirror -- the same pattern `DocumentAnchorTarget`-adopting\nviewers use for their own `anchorKinds` field. This component isn't document-viewer-registry-\nrouted, so it has no registry `capabilities.anchors` entry to declare this on instead.","type":"readonly LyraAnchor['kind'][]","default":"['line-range']","read-only":true},{"name":"announceOutput","description":"Attribute: `announce-output`","type":"boolean","default":"false"},{"name":"compact","description":"Tightens the toolbar's padding/gap and each rendered line's inline padding for a terminal\nembedded in an already-padded transcript row -- same convention as `lr-task-list`'s and\n`lr-thinking-panel`'s `compact`. Defaults to `false`, i.e. the full padding. Purely a density\nknob: the card border and background stay, so use `frame=\"plain\"` to drop the chrome.\n\nAttribute: `compact`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"content","description":"Attribute: `content`","type":"string","default":"''"},{"name":"copyable","description":"Attribute: `copyable`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"downloadable","description":"Attribute: `downloadable`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"filename","description":"Attribute: `filename`","type":"string","default":"'terminal.log'"},{"name":"follow","description":"Attribute: `follow`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"frame","description":"Visual chrome, in the library's shared container-frame vocabulary. `'card'` (the default)\nkeeps `[part=\"base\"]`'s border, corner radius, and raised surface; `'plain'` removes all\nthree so a terminal nested inside a container that already draws a border (an agent-run\npanel, a message bubble) doesn't double it. Plain keeps the toolbar/log divider and whichever\nregular or compact padding applies -- it controls outer chrome only.\n\nAttribute: `frame`  \nReflected to its attribute.","type":"LyraFrame","default":"'card'"},{"name":"highlights","type":"readonly LyraHighlight[]"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"maxScrollback","description":"Line-count scrollback buffer limit. NaN/negative/oversized (e.g. `Infinity`) normalize to a\n1..10,000 range; total retained cells and cells per line have independent hard ceilings.\n\nAttribute: `max-scrollback`","type":"number","default":"5000"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"wrap","description":"Attribute: `wrap`  \nReflected to its attribute.","type":"boolean","default":"true"}],"events":[{"name":"lr-copy","description":"`detail: { ok: true, text }` — the plain-text clipboard write completed.","type":"CustomEvent<LyraClipboardWriteSuccess>"},{"name":"lr-copy-error","description":"`detail: { ok: false, text, reason, error }` — typed clipboard failure.","type":"CustomEvent<LyraClipboardWriteFailure>"},{"name":"lr-download","description":"`detail: { filename }` — the download button was activated. Cancelable: by default this component itself builds an in-memory Blob of the current plain-text log and triggers a browser download via a synthetic `<a download>` click; a host that calls `preventDefault()` on this event suppresses that built-in download entirely and can substitute its own handling (e.g. routing a large log through a server-side export instead), mirroring `<lr-media-card>`'s `lr-open` convention.","type":"CustomEvent<{ filename: string }>"},{"name":"lr-error","description":"The clipboard write failed; generic no-detail notification.","type":"CustomEvent<null>"},{"name":"lr-follow-change","description":"`detail: { following }` — a user viewport/jump action changed stick-to-bottom. Direct `follow` assignments and imperative navigation do not echo an event.","type":"CustomEvent<{ following: boolean }>"},{"name":"lr-highlight-activate","description":"`detail: { highlightId }` — a highlighted line was clicked/activated.","type":"CustomEvent<HighlightActivateDetail>"},{"name":"lr-search-change","description":"`detail: { query, matchCount, matchCountExact, activeIndex }`. `matchCountExact` is `false` once a search hits the 10,000-match retention ceiling, marking `matchCount` as a lower bound rather than an exact total.","type":"CustomEvent<LyraSearchChangeDetail>"},{"name":"lr-text-select","description":"`detail: { text, anchor, rects }` — fires on pointerup after a text selection ending inside the viewport. `anchor` is `null` when either selection endpoint isn't inside a currently-mounted (non-virtualized-out) line.","type":"CustomEvent<TextSelectDetail>"}]}},{"name":"lr-test-results","description":"`<lr-test-results>` — a pass/fail suite summary with per-status counts, status filter\ntoggles, and per-test rows whose failures auto-expand by default and can host rich slotted\ndetail (e.g. a diff or code block) alongside the plain failure message.\nEmpty/blank suite and test ids are omitted and duplicates use first-wins identity. At most 1,000\nuniquely identified suite/test rows are mounted. Manually expanded identities and\nfailures reserve positions before ordinary input-order rows, while the four summary counts cover\nthe complete normalized input. Foreign runtime statuses normalize once to the localized neutral\n`skipped` fallback. Completion announcements require an explicit same-`runId`\n`runState=\"running\"` -> `\"complete\"` transition; clearing data alone is not treated as a\ncompleted run.\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| `detail-{encodedSuiteId}:{encodedTestId}` | Collision-free suite-scoped rich detail for a test, and the only detail slot this component reads. Derive it with `testResultDetailSlotName(suiteId, testId)` rather than assembling it by hand. The legacy `detail-{suiteId}-{testId}` and `detail-{testId}` spellings were removed in 9.0.0; content assigned to either is simply never slotted. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The root wrapper; carries the localized \"Test results\" `role=\"group\"` semantics unless a non-empty host `aria-label` already makes the host the overall semantic owner. Explicit `aria-label=\"\"` remains empty instead of restoring the fallback. |\n| `count` | One status count; carries `data-status`. |\n| `empty` | Empty/no-match state, including a populated run hidden entirely by filters. |\n| `failure` | The failure-detail wrapper; hidden while collapsed. |\n| `failure-message` | The failure's plain message text. |\n| `filter` | The filter-toggle row. |\n| `filter-toggle` | One status filter toggle; carries `data-status` and `aria-pressed`. |\n| `limit` | Localized resource-ceiling notice. |\n| `suite` | One suite section. |\n| `suite-header` | The suite's name row. |\n| `summary` | The status-count strip. |\n| `test` | One test row; carries `data-status`. |\n| `test-duration` | The duration text. |\n| `test-expand-toggle` | The expand/collapse button for a row's failure detail. Its accessible name joins the suite and test name with the localized `accessibleLabelSeparator`. Rendered for any failed test, or any test with canonical suite-scoped detail content. |\n| `test-name` | The activatable test-name button. |\n| `test-status` | A language-neutral decorative status glyph and its localized visible status-word text; carries `data-status`. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-test-results-failed-color` (default: `var(--lr-color-danger)`) — Failed-state foreground.\n- `--lr-test-results-filter-active-bg` (default: `var(--lr-color-brand-quiet)`) — Background of a pressed (active) status filter toggle.\n- `--lr-test-results-filter-active-border` (default: `var(--lr-color-brand)`) — Border color of a pressed (active) status filter toggle.\n- `--lr-test-results-filter-active-color` (default: `var(--lr-color-brand)`) — Text color of a pressed (active) status filter toggle. Restyling the pressed state otherwise requires overriding the library-wide brand tokens, since `::part(filter-toggle)[aria-pressed]` is invalid CSS.\n- `--lr-test-results-passed-color` (default: `var(--lr-color-success)`) — Passed-state foreground.\n- `--lr-test-results-running-color` (default: `var(--lr-color-brand)`) — Running-state foreground.\n- `--lr-test-results-skipped-color` (default: `var(--lr-color-text-quiet)`) — Skipped-state foreground.\n- `--lr-test-results-spinner-size` (default: `var(--lr-size-1em)`) — Diameter of the composed spinner in a running test row.","attributes":[{"name":"auto-expand-failures","description":"Whether a failed test's detail auto-expands. A row the user has manually toggled always\nkeeps its own explicit state regardless of this flag.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"run-id","description":"Stable source-run identity used to correlate lifecycle announcements.\n\nType: `string | null`  \nDefault: `null`"},{"name":"run-state","description":"Explicit source-run lifecycle; only a same-id running -> complete transition announces.\n\nType: `TestRunState`  \nDefault: `'idle'`","value":{"type":["'idle'","'running'","'complete'"]}}],"slots":[{"name":"detail-{encodedSuiteId}:{encodedTestId}","description":"Collision-free suite-scoped rich detail for a test, and the only detail slot this component reads. Derive it with `testResultDetailSlotName(suiteId, testId)` rather than assembling it by hand. The legacy `detail-{suiteId}-{testId}` and `detail-{testId}` spellings were removed in 9.0.0; content assigned to either is simply never slotted."}],"js":{"properties":[{"name":"autoExpandFailures","description":"Whether a failed test's detail auto-expands. A row the user has manually toggled always\nkeeps its own explicit state regardless of this flag.\n\nAttribute: `auto-expand-failures`","type":"boolean","default":"true"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"runId","description":"Stable source-run identity used to correlate lifecycle announcements.\n\nAttribute: `run-id`","type":"string | null","default":"null"},{"name":"runState","description":"Explicit source-run lifecycle; only a same-id running -> complete transition announces.\n\nAttribute: `run-state`  \nReflected to its attribute.","type":"TestRunState","default":"'idle'"},{"name":"statusFilter","description":"When non-empty, only tests whose status is in this set are shown. Empty means \"show all\".","type":"readonly TestStatus[]","default":"[]"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"suites","description":"The suites to render, grouped in order. Controlled and never mutated by this component --\npass a new array (e.g. as a run streams in) to update it. Duplicate suite ids and per-suite\ntest ids use deterministic first-wins identity.","type":"readonly TestSuiteResult[]","default":"[]"}],"events":[{"name":"lr-filter-change","description":"`detail: { statuses }` — the status-set filter changed.","type":"CustomEvent<LyraEventDetailSnapshot<{ statuses: TestStatus[] }>>"},{"name":"lr-test-select","description":"`detail: { suiteId, testId }` — a test row's name was activated.","type":"CustomEvent<{ suiteId: string; testId: string }>"},{"name":"lr-toggle","description":"`detail: { suiteId, testId, expanded }` — a row's failure detail was expanded/collapsed. The identity shape is invariant even when `testId` is globally unique.","type":"CustomEvent<{ suiteId: string; testId: string; expanded: boolean }>"}]}},{"name":"lr-textarea","description":"`<lr-textarea>` — a multiline plain-text input primitive, form-associated via the\n`FormAssociated` mixin (see `<lr-chat-composer>`/`<lr-date-input>` for the same shape), so it\nparticipates in native `<form>` submission/validation/reset like any other text control --\n`name`/`value`/`disabled`/`required`/`checkValidity()`/`reportValidity()` all come from that mixin.\n\nShips an opt-in `label`/`hint`/`errorText` form-control chrome (props + matching named slots +\n`form-control-label`/`hint`/`error` parts), mirroring `<lr-select>`'s exact pattern -- left\nunset, the chrome remains hidden. A consumer preferring their own form-field layout can still\nignore these and wrap the element. A host `aria-label` is forwarded to the internal textbox via\nthe typed `accessibleLabel` property. A host `aria-describedby` is resolved onto that native\ntextarea, ahead of its own hint/error descriptions, so externally-owned guidance remains valid\nacross the shadow boundary. Host `aria-labelledby` is deliberately not projected: the native\n`<label>` already owns this control's visible label relationship.\n\n`minlength`/`maxlength` are forwarded to the internal native `<textarea>` and bridged into this\nelement's own `ElementInternals` as `tooShort`/`tooLong` by `updateValidity()`.\n`readonly` keeps the value focusable, selectable, copyable, and form-submittable while barring\nuser edits and constraint validation, matching the native textarea contract.\n\nRemoving `label`, `hint`, `help-text` or `error-text` safely omits that content while preserving\nnative null property readback. Explicit empty strings stay empty; later text renders normally.\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| `error` | Custom error content. |\n| `help-text` | Shoelace alias for `hint`. |\n| `hint` | Custom hint content. |\n| `label` | Custom label content. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | Compatibility name for the control wrapper; use `textarea-wrapper`. |\n| `count` | The character count, rendered only with `with-count`. |\n| `error` | The error message. |\n| `footer` | The row below the field carrying the character count. Hidden without `with-count`. |\n| `form-control` | The outer wrapper around label, textarea, error and hint. |\n| `form-control-help-text` | Shoelace compatibility name for the hint message. |\n| `form-control-input` | Compatibility name for the control wrapper. |\n| `form-control-label` | The `<label>` element. |\n| `hint` | The hint message. |\n| `label` | Wrapper around the visible label content. |\n| `textarea` | The native `<textarea>` element. |\n| `textarea-adjuster` | Compatibility name for the native-resize wrapper. |\n| `textarea-wrapper` | The wrapper around the native `<textarea>`. It is the same node as `base`. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-textarea-max-block-size` (default: `none`) — Maximum auto-grown block size before the textarea scrolls.\n- `--lr-textarea-padding` (default: `var(--lr-form-control-padding-inline)`) — Padding of the native textarea on all four sides, from the active `size` tier of the shared form-control ladder (`internal/sizes.styles.ts`). The ladder's *inline* gutter is used on every side deliberately: its block padding is `0` at the two tightest tiers because a control row's height floor supplies the space there, and a textarea has no such floor -- the first line of text would sit on the border.\n- `--lr-textarea-font-size` (default: `var(--lr-form-control-font-size)`) — Font size of the native textarea, from the active `size` tier of the shared ladder.\n- `--lr-textarea-radius` (default: `var(--lr-form-control-radius)`) — Corner radius of the field, from the active `size` tier of the shared ladder (the two tightest tiers take a smaller radius). `pill` changes the private default to `--lr-radius-pill`; a public value still wins.\n- `--lr-textarea-fill` (default: `transparent`) — Background of the field. Its private default follows `appearance`; the documented default is `appearance=\"outlined\"`'s value.\n- `--lr-textarea-border-color` (default: `var(--lr-color-border)`) — Border color of the field. Its private default follows `appearance` in the same way as `--lr-textarea-fill`.\n- `--lr-textarea-hover-border-color` (default: `var(--lr-color-brand)`) — Field border color while the native textarea is hovered.\n- `--lr-textarea-focus-border-color` (default: `var(--lr-textarea-border-color)`) — Field border color while the native textarea is focused. Unset, it resolves to this field's own resting border color, so a textarea with no override renders exactly as before this hook existed.\n- `--lr-form-control-focus-shadow` (default: `none`) — The shared field focus halo, painted as a `box-shadow` while this control is focused. One name for every field-shaped control in the library, so a halo is configured once rather than per component. Additive: the focus outline and border cue are the accessibility answer to focus and are never replaced by it.\n- `--lr-form-control-required-content` (default: `' *'`) — The required-field marker rendered after the label. Set it to `''` to suppress the marker, or to any other quoted string (`' (required)'`, a localized word) to replace it. Caller-supplied content, so it is never localized here.\n- `--lr-form-control-required-color` (default: `var(--lr-color-danger)`) — Color of that marker, retunable without touching any other danger-coloured surface.\n- `--lr-form-control-required-offset` (default: `0`) — Inline space between the label text and the marker.","attributes":[{"name":"appearance","description":"Visual treatment of the field, from the library's shared vocabulary and with the same\nmeanings as `<lr-input>`'s `appearance`. Each value only swaps\n`--lr-textarea-fill`/`--lr-textarea-border-color`.\n\nType: `LyraAppearance`  \nDefault: `'outlined'`","value":{"type":["'accent'","'filled'","'outlined'","'filled-outlined'","'plain'"]}},{"name":"aria-label","description":"Accessible name overriding the label/placeholder-derived default. Any non-`null` value takes\nprecedence by presence—including `''`—matching `<lr-date-input>`'s `accessibleLabel`.\n\nType: `string | null`  \nDefault: `null`"},{"name":"autocapitalize","description":"Forwarded to the native `<textarea>`'s own `autocapitalize`. Empty string omits the\nattribute (browser default).\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"autocomplete","description":"Native editing-assistance attributes forwarded to the wrapped textarea. Empty strings omit\nthe corresponding attribute and retain the browser default.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"autocorrect","description":"Native editing-assistance state forwarded as canonical `autocorrect=\"on\"|\"off\"`. Reads are\nboolean. Writes accept Web Awesome's boolean IDL and Shoelace's string vocabulary:\n`'off'`/`'false'` normalize to false and every other string normalizes to true.\n\nType: `boolean | string`  \nDefault: `true`"},{"name":"autofocus","description":"Forwarded to the internal native textarea.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"custom-error","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nType: `string | null`  \nDefault: `null`"},{"name":"debounce","description":"How long (ms) to wait after the last keystroke before emitting one `lr-input-settled`,\ncoalescing a burst of rapid edits into a single downstream commit -- the same predicate and\n`DebounceController` primitive `<lr-filter-bar>`'s own per-filter `debounce` uses, and shared\nwith `<lr-input>`'s identical property. Omitted, `0`, or a non-finite value means no debounce\nat all: `input`/`lr-input` keep firing per keystroke exactly as before, and `lr-input-settled`\nnever fires. A pending debounce is flushed immediately by `change`/Enter/blur (so a blur never\ndrops the last keystroke) and cancelled with no stray settle by disconnection and a\nprogrammatic `value` write that changes the value -- a same-value write does not disturb it.\n\nType: `number | undefined`"},{"name":"default-value","description":"Compatibility attribute alias for the supported `defaultValue` reset value.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"disabled","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"enterkeyhint","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"error-text","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"filled","description":"Shoelace boolean alias for the filled treatment.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"form","description":"Type: `HTMLFormElement | string | null`  \nDefault: `null`"},{"name":"help-text","description":"Shoelace alias for hint. `hint` wins when both are set.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"hint","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"inputmode","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"label","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"maxlength","description":"Upper counterpart of `minlength` (native `maxlength`/`tooLong`), with the same parsing and\nthe same default of `undefined`. Note that native `maxlength` also *prevents* typing beyond\nthe limit; it reports `tooLong` for values that arrive some other way (paste of a longer\nvalue, a programmatic assignment).\n\nType: `number | undefined`"},{"name":"minlength","description":"Minimum text length, forwarded to the native `<textarea>`'s own `minlength` and reported as\n`tooShort` by `updateValidity()`. Defaults to `undefined` (no lower bound). Like native\n`minlength`, an empty value never violates it — pair it with `required` to also reject\nempty.\n\nType: `number | undefined`"},{"name":"name","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"pill","description":"Fully rounded field corners, matching `<lr-input>`'s/`<lr-select>`'s own `pill` — Shoelace and\nWeb Awesome both ship it on their textarea, so a mechanical tag rename must not drop it.\nChanges the private radius default to `--lr-radius-pill` rather than declaring a radius on\n`[part=\"textarea\"]`, so an inherited or direct `--lr-textarea-radius` remains authoritative.\nMost useful on a one-or-two-row field; a tall multi-line surface with fully rounded ends wastes\nits first and last line's inline space, so this is opt-in rather than tied to `size`.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"placeholder","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"readonly","description":"Forwards native read-only behavior to the internal textarea. The value remains focusable,\nselectable, copyable, and form-submittable; constraint validation is suspended until the\nproperty is unset.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"required","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"resize","description":"Native CSS `resize` behavior for the textarea (`'none'`, `'vertical'`, `'horizontal'`,\n`'both'`), plus `'auto'`: a `ResizeObserver`-driven grow-to-content mode with no manual drag\nhandle (mirrors `wa-textarea`'s `resize=\"auto\"`). An invalid runtime value falls back to\n`'vertical'`.\n\nType: `TextareaResize`  \nDefault: `'vertical'`","value":{"type":["'none'","'vertical'","'horizontal'","'both'","'auto'"]}},{"name":"rows","description":"Visible text rows.\n\nType: `number`  \nDefault: `4`","value":{"type":["number"]}},{"name":"size","description":"Visual size on the library's one control ladder, shared with `<lr-input>`/`<lr-select>`.\nAccepts both the canonical `'2xs'`–`'xl'` steps and Web Awesome's/Shoelace's\n`'small'`/`'medium'`/`'large'` spellings of `s`/`m`/`l`; the two render identically. Governs\nthe field's padding and font size — a textarea's own height comes from `rows`/`resize`, not\nfrom the ladder's control-height floor.\n\nType: `LyraSize`  \nDefault: `'m'`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}},{"name":"spellcheck","description":"Forwarded to the native `<textarea>`'s own `spellcheck`. Defaults to `true`, matching the\nnative element's own default.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"title","description":"Forwarded to the internal native textarea.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"value","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"with-count","description":"Renders a character count below the field. With `maxlength` set it counts down the remaining\ncharacters instead of up from zero. The visible count and internal shadow mirror are\n`aria-hidden`; after user input pauses, the localized count is appended once to Lyra's shared\nlight-DOM polite announcement sink so it is not spoken over every keystroke. The sink stays\nsilent while this host or a composed ancestor is excluded from the accessibility tree.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"with-hint","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"with-label","description":"SSR slot-presence hints for declarative shadow DOM and hydration.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"wrap","description":"Forwarded to the native `<textarea>`'s own `wrap`.\n\nType: `TextareaWrap`  \nDefault: `'soft'`","value":{"type":["'hard'","'soft'","'off'"]}}],"slots":[{"name":"error","description":"Custom error content."},{"name":"help-text","description":"Shoelace alias for `hint`."},{"name":"hint","description":"Custom hint content."},{"name":"label","description":"Custom label content."}],"js":{"properties":[{"name":"accessibleLabel","description":"Accessible name overriding the label/placeholder-derived default. Any non-`null` value takes\nprecedence by presence—including `''`—matching `<lr-date-input>`'s `accessibleLabel`.\n\nAttribute: `aria-label`","type":"string | null","default":"null"},{"name":"appearance","description":"Visual treatment of the field, from the library's shared vocabulary and with the same\nmeanings as `<lr-input>`'s `appearance`. Each value only swaps\n`--lr-textarea-fill`/`--lr-textarea-border-color`.\n\nAttribute: `appearance`  \nReflected to its attribute.","type":"LyraAppearance","default":"'outlined'"},{"name":"autocapitalize","description":"Forwarded to the native `<textarea>`'s own `autocapitalize`. Empty string omits the\nattribute (browser default).\n\nAttribute: `autocapitalize`","type":"string","default":"''"},{"name":"autocomplete","description":"Native editing-assistance attributes forwarded to the wrapped textarea. Empty strings omit\nthe corresponding attribute and retain the browser default.\n\nAttribute: `autocomplete`","type":"string","default":"''"},{"name":"autocorrect","description":"Native editing-assistance state forwarded as canonical `autocorrect=\"on\"|\"off\"`. Reads are\nboolean. Writes accept Web Awesome's boolean IDL and Shoelace's string vocabulary:\n`'off'`/`'false'` normalize to false and every other string normalizes to true.\n\nAttribute: `autocorrect`","type":"boolean | string","default":"true"},{"name":"autofocus","description":"Forwarded to the internal native textarea.\n\nAttribute: `autofocus`","type":"boolean","default":"false"},{"name":"customError","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nAttribute: `custom-error`  \nReflected to its attribute.","type":"string | null","default":"null"},{"name":"debounce","description":"How long (ms) to wait after the last keystroke before emitting one `lr-input-settled`,\ncoalescing a burst of rapid edits into a single downstream commit -- the same predicate and\n`DebounceController` primitive `<lr-filter-bar>`'s own per-filter `debounce` uses, and shared\nwith `<lr-input>`'s identical property. Omitted, `0`, or a non-finite value means no debounce\nat all: `input`/`lr-input` keep firing per keystroke exactly as before, and `lr-input-settled`\nnever fires. A pending debounce is flushed immediately by `change`/Enter/blur (so a blur never\ndrops the last keystroke) and cancelled with no stray settle by disconnection and a\nprogrammatic `value` write that changes the value -- a same-value write does not disturb it.\n\nAttribute: `debounce`","type":"number | undefined"},{"name":"defaultValue","description":"Attribute: `value`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"disabled","description":"Attribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"enterKeyHint","description":"Attribute: `enterkeyhint`","type":"string","default":"''"},{"name":"enterkeyhint","type":"string"},{"name":"errorText","description":"Attribute: `error-text`","type":"string","default":"''"},{"name":"filled","description":"Shoelace boolean alias for the filled treatment.\n\nAttribute: `filled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"form","description":"Attribute: `form`  \nReflected to its attribute.","type":"HTMLFormElement | string | null","default":"null"},{"name":"helpText","description":"Shoelace alias for hint. `hint` wins when both are set.\n\nAttribute: `help-text`","type":"string","default":"''"},{"name":"hint","description":"Attribute: `hint`","type":"string","default":"''"},{"name":"input","description":"The internal native `<textarea>` element, for direct DOM access (caret position, selection,\n`setRangeText()`) that has no first-class `lr-*` equivalent -- mirrors `wa-textarea`'s own\n`input` getter.","type":"HTMLTextAreaElement | null","read-only":true},{"name":"inputMode","description":"Attribute: `inputmode`","type":"string","default":"''"},{"name":"inputmode","description":"Lowercase mapped IDLs that delegate to the existing reactive native spellings.","type":"string"},{"name":"label","description":"Attribute: `label`","type":"string","default":"''"},{"name":"labels","type":"NodeList","read-only":true},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"maxlength","description":"Upper counterpart of `minlength` (native `maxlength`/`tooLong`), with the same parsing and\nthe same default of `undefined`. Note that native `maxlength` also *prevents* typing beyond\nthe limit; it reports `tooLong` for values that arrive some other way (paste of a longer\nvalue, a programmatic assignment).\n\nAttribute: `maxlength`","type":"number | undefined"},{"name":"minlength","description":"Minimum text length, forwarded to the native `<textarea>`'s own `minlength` and reported as\n`tooShort` by `updateValidity()`. Defaults to `undefined` (no lower bound). Like native\n`minlength`, an empty value never violates it — pair it with `required` to also reject\nempty.\n\nAttribute: `minlength`","type":"number | undefined"},{"name":"name","description":"Attribute: `name`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"pill","description":"Fully rounded field corners, matching `<lr-input>`'s/`<lr-select>`'s own `pill` — Shoelace and\nWeb Awesome both ship it on their textarea, so a mechanical tag rename must not drop it.\nChanges the private radius default to `--lr-radius-pill` rather than declaring a radius on\n`[part=\"textarea\"]`, so an inherited or direct `--lr-textarea-radius` remains authoritative.\nMost useful on a one-or-two-row field; a tall multi-line surface with fully rounded ends wastes\nits first and last line's inline space, so this is opt-in rather than tied to `size`.\n\nAttribute: `pill`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"placeholder","description":"Attribute: `placeholder`","type":"string","default":"''"},{"name":"readonly","description":"Forwards native read-only behavior to the internal textarea. The value remains focusable,\nselectable, copyable, and form-submittable; constraint validation is suspended until the\nproperty is unset.\n\nAttribute: `readonly`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"required","description":"Attribute: `required`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"resize","description":"Native CSS `resize` behavior for the textarea (`'none'`, `'vertical'`, `'horizontal'`,\n`'both'`), plus `'auto'`: a `ResizeObserver`-driven grow-to-content mode with no manual drag\nhandle (mirrors `wa-textarea`'s `resize=\"auto\"`). An invalid runtime value falls back to\n`'vertical'`.\n\nAttribute: `resize`  \nReflected to its attribute.","type":"TextareaResize","default":"'vertical'"},{"name":"rows","description":"Visible text rows.\n\nAttribute: `rows`","type":"number","default":"4"},{"name":"selectionDirection","type":"TextareaSelectionDirection | null"},{"name":"selectionEnd","type":"number | null"},{"name":"selectionStart","type":"number | null"},{"name":"size","description":"Visual size on the library's one control ladder, shared with `<lr-input>`/`<lr-select>`.\nAccepts both the canonical `'2xs'`–`'xl'` steps and Web Awesome's/Shoelace's\n`'small'`/`'medium'`/`'large'` spellings of `s`/`m`/`l`; the two render identically. Governs\nthe field's padding and font size — a textarea's own height comes from `rows`/`resize`, not\nfrom the ladder's control-height floor.\n\nAttribute: `size`  \nReflected to its attribute.","type":"LyraSize","default":"'m'"},{"name":"spellcheck","description":"Forwarded to the native `<textarea>`'s own `spellcheck`. Defaults to `true`, matching the\nnative element's own default.\n\nAttribute: `spellcheck`","type":"boolean","default":"true"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"title","description":"Forwarded to the internal native textarea.\n\nAttribute: `title`","type":"string","default":"''"},{"name":"validationMessage","type":"string","read-only":true},{"name":"validity","type":"ValidityState","read-only":true},{"name":"value","type":"string"},{"name":"willValidate","type":"boolean","read-only":true},{"name":"withCount","description":"Renders a character count below the field. With `maxlength` set it counts down the remaining\ncharacters instead of up from zero. The visible count and internal shadow mirror are\n`aria-hidden`; after user input pauses, the localized count is appended once to Lyra's shared\nlight-DOM polite announcement sink so it is not spoken over every keystroke. The sink stays\nsilent while this host or a composed ancestor is excluded from the accessibility tree.\n\nAttribute: `with-count`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"withHint","description":"Attribute: `with-hint`","type":"boolean","default":"false"},{"name":"withLabel","description":"SSR slot-presence hints for declarative shadow DOM and hydration.\n\nAttribute: `with-label`","type":"boolean","default":"false"},{"name":"wrap","description":"Forwarded to the native `<textarea>`'s own `wrap`.\n\nAttribute: `wrap`","type":"TextareaWrap","default":"'soft'"}],"events":[{"name":"blur","description":"Re-dispatched from the internal native `<textarea>`'s own `blur` -- bubbling and composed (unlike the native event, which is neither), so a listener above the shadow boundary can observe it.","type":"FocusEvent"},{"name":"change","description":"Native-style composed event fired at the native `change` timing.","type":"Event"},{"name":"focus","description":"Re-dispatched from the internal native `<textarea>`'s own `focus`, for the same reason as `blur`.","type":"FocusEvent"},{"name":"input","description":"Native-style composed event fired on every user-driven edit.","type":"InputEvent"},{"name":"lr-change","description":"Compatibility alias for `change`; `detail: { value }`.","type":"CustomEvent<{ value: string }>"},{"name":"lr-input","description":"Compatibility alias for `input`; `detail: { value }`.","type":"CustomEvent<{ value: string }>"},{"name":"lr-input-settled","description":"Fires once, `debounce` ms after the last keystroke, alongside the per-keystroke `input`/`lr-input` pair (which keep firing on every edit). `detail: { value }`, non-cancelable. A pending debounce is flushed immediately on `change`/Enter/blur, and cancelled with no stray settle on disconnect and a programmatic `value` write that actually changes the value -- a same-value write (e.g. the controlled-input pattern of a framework re-binding `value` from the state its own handler just set) leaves the pending debounce armed instead of silently defeating it. Never fires while `debounce` is unset, `0`, or non-finite.","type":"CustomEvent<{ value: string }>"},{"name":"lr-invalid","description":"The textarea failed a validity check. Cancelable: `preventDefault()` forwards to the native `invalid` event, suppressing the browser's own validation bubble and the focus/scroll `reportValidity()` would otherwise perform.","type":"CustomEvent<null>"}]}},{"name":"lr-thinking-panel","description":"`<lr-thinking-panel>` — a collapsible panel for an AI agent's\nintermediate reasoning/\"thinking\" transcript, kept visually and\nsemantically distinct from its final response. Same collapsible\nheader-button-plus-region shape as `<lr-source-list>`; the default slot\nis entirely free-form (a consumer-composed `<lr-streaming-text>`,\n`<lr-markdown>`, or plain text) — this component has no dependency on\neither and imposes no structure on what's slotted.\n\n`compact` tightens the header and transcript-body padding for dense\ntranscript rows. `frame=\"plain\"` removes the outside card chrome when a\ncontaining message or panel already supplies it; the header/body divider\nand their layout remain, so the disclosure keeps its internal structure.\n\n`mode` (`'live'` while reasoning is actively streaming in, `'post-hoc'`\nonce it's complete and being reviewed after the fact) drives two concrete\nbehavior differences, not just a styling hook:\n- **Header hint.** While `duration-ms` is unset, `'live'` shows a pulsing\n  \"Thinking…\" placeholder in `[part=\"duration\"]`; `'post-hoc'` shows\n  nothing there instead (a finished review with no known duration has\n  nothing useful to say in that slot). Once `duration-ms` is set, both\n  modes show the same static `\"Thought for …\"` text — a `'post-hoc'`\n  consumer that captured a duration is free to supply it too.\n- **Auto-scroll.** Only `'live'` mode auto-follows new content appended to\n  the default slot while `expanded` (see below); `'post-hoc'` never\n  scrolls on its own, since reviewing finished reasoning is expected to\n  start from the top like reading any other completed document. This\n  library otherwise defaults to *not* editorializing about a host's data\n  (see `<lr-empty>`'s plain-`description` stance), but scroll position\n  is presentation, not data, so this one behavior difference earns its\n  keep rather than being left as a bare visual/semantic hint the host\n  would have to reimplement identically itself.\n\nLive-mode auto-scroll (\"stick to bottom\") is the classic chat-transcript\nconvention: while `mode=\"live\"` and `expanded`, new content keeps the\npanel scrolled to its latest line — *unless* the user has manually\nscrolled up to (re-)read earlier content, in which case their position is\nnever yanked away from them. This is tracked continuously via a `scroll`\nlistener on `[part=\"body\"]` (not recomputed from the mutation itself,\nwhich necessarily observes the DOM only *after* it has already changed):\nevery user-driven scroll updates the public `follow` state to record whether the body was left within\n`NEAR_BOTTOM_PX` of its own max scroll position, and only a mutation that\narrives while that's still true triggers a follow-up scroll-to-bottom.\nOpening an already-`'live'` panel (or one that later becomes `'live'`)\nalways resets this to \"anchored\" and jumps to the latest content, the same\nway a chat app's own transcript does when you re-open it.\n\nNew content is detected two ways, both feeding the same coalesced scroll-to-bottom (a mutation\nand a settle event landing in the same animation frame never double-scroll):\n- A `MutationObserver` on this element's own light DOM (`childList`+`subtree`+`characterData`)\n  rather than the default slot's `slotchange` event, because `slotchange` only fires when the\n  set of top-level assigned nodes changes — never for a text node mutating *inside* an\n  already-slotted element, which is the shape a consumer literally appending chunks to a plain\n  light-DOM node produces. This cannot see a mutation entirely inside a slotted custom\n  element's own shadow root (e.g. `<lr-markdown>` re-rendering its shadow tree after a\n  `content` property change) — Shadow DOM encapsulation blocks that by design.\n- A listener for `lr-content-settled`, a composed, bubbling, signal-only event\n  (`detail: null`) this library's own streaming renderers — `<lr-streaming-text>`,\n  `<lr-markdown>`, `<lr-markdown-core>` — emit at their own settle points. Being composed, it\n  crosses exactly the shadow boundary the `MutationObserver` above cannot, covering every\n  property- or attribute-driven producer that renders into its own shadow root instead of\n  mutating visible light-DOM text.\n\nA slotted element that is neither a plain light-DOM text producer nor one of this library's own\nstreaming renderers — a bespoke custom element that re-renders its own shadow tree from a\nproperty change — needs to append/mutate visible light-DOM text itself, emit its own\n`lr-content-settled`, or have the host call this panel's own `scrollToBottom()` directly.\n\n`aria-controls` linking the header to the body region uses `nextId()`\n(`../../internal/a11y.js`) for a collision-safe id, the same convention\n`<lr-source-list>` and `<lr-widget>` already establish for every\ntoggle-controls-region pairing in this library.\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 reasoning/thinking content. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The outer container. |\n| `body` | The wrapper around the default slot, `hidden` while collapsed. Independently keyboard-focusable (`tabindex=\"0\"`, `role=\"group\"` named from `label`) since it's its own capped-height scrollable region. |\n| `duration` | The formatted duration / \"Thinking…\" placeholder, when shown. |\n| `header` | The clickable header (`<button>`) toggling `expanded`. |\n| `label` | The `label` text. |\n| `toggle` | The chevron indicator inside the header. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-thinking-panel-background` (default: `var(--lr-color-surface)`) — Fill of the outer card (`[part=\"base\"]`) while `frame=\"card\"`. `frame=\"plain\"` still removes the fill entirely.\n- `--lr-thinking-panel-body-hover-outline-color` (default: `var(--lr-color-border)`) — Outline color of the mouse-hover preview on `[part=\"body\"]`. Set to `transparent` to opt out of the hover treatment entirely.\n- `--lr-thinking-panel-body-hover-outline-offset` (default: `calc(-1 * var(--lr-focus-ring-offset))`) — Inward offset of the mouse-hover preview on `[part=\"body\"]`, keeping the outline inside its own scrollport so it is not clipped at the edge.\n- `--lr-thinking-panel-body-hover-outline-style` (default: `solid`) — Outline style of the mouse-hover preview on `[part=\"body\"]`.\n- `--lr-thinking-panel-body-hover-outline-width` (default: `var(--lr-focus-ring-width)`) — Outline width of the mouse-hover preview on `[part=\"body\"]`.\n- `--lr-thinking-panel-border-color` (default: `var(--lr-color-border)`) — Colour of the outer card's border and of the header/body divider, which `frame=\"plain\"` keeps.\n- `--lr-thinking-panel-compact-body-padding` (default: `var(--lr-space-s)`) — `[part=\"body\"]` padding while `compact`.\n- `--lr-thinking-panel-compact-header-font-size` (default: `var(--lr-font-size-sm)`) — Font size of `[part=\"header\"]` while `compact`.\n- `--lr-thinking-panel-compact-header-gap` (default: `var(--lr-space-2xs)`) — Gap between the header toggle, label, and duration while `compact`.\n- `--lr-thinking-panel-compact-header-padding` (default: `var(--lr-space-2xs) var(--lr-space-s)`) — `[part=\"header\"]` padding while `compact`.\n- `--lr-thinking-panel-max-block-size` (default: `var(--lr-size-16rem)`) — Cap on how tall the expanded reasoning transcript grows before `[part=\"body\"]` scrolls internally.\n- `--lr-thinking-panel-pending-color` (default: `var(--lr-color-brand)`) — Live pending-state color.\n- `--lr-thinking-panel-radius` (default: `var(--lr-radius)`) — Corner radius of the outer card. `frame=\"plain\"` still squares the corners.","attributes":[{"name":"compact","description":"Tighter header/body padding and header gap for dense transcript contexts. Defaults to\n`false`, preserving the regular-density treatment. This changes density only; the outer\nborder and surface remain, so use `frame=\"plain\"` to remove card chrome.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"duration-ms","description":"How long the reasoning took, in milliseconds, once known. Omitted\nentirely (nothing rendered in `'post-hoc'`, a pulsing placeholder in\n`'live'`) while unset.\n\nType: `number | undefined`"},{"name":"expanded","description":"Whether the reasoning transcript is currently shown. Starts collapsed,\nmatching `<lr-source-list>`'s default -- a consumer running `'live'`\nreasoning sets this `true` itself to stream it in view as it arrives.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"follow","description":"Whether live, expanded content follows the transcript tail. User scrolling updates this\nproperty and emits `lr-follow-change`; direct assignments are controlled input and do not\necho an event. Opening a live panel or calling `scrollToBottom()` re-engages it silently.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"frame","description":"Visual chrome, in the library's shared container-frame vocabulary. `'card'` (the default)\nkeeps the bordered, filled outer container. `'plain'` removes that outer border, background,\nand corner radius so a thinking panel nested inside existing message chrome does not double\nit. Plain preserves the header/body divider and whichever regular or compact padding applies.\n\nType: `LyraFrame`  \nDefault: `'card'`","value":{"type":["'card'","'plain'"]}},{"name":"label","description":"Optional header-text override. Omission localizes `thinkingPanelLabel`; any supplied string,\nincluding `'Thinking'` or `''`, is rendered verbatim.\n\nType: `string | undefined`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"mode","description":"Type: `ThinkingPanelMode`","value":{"type":["'live'","'post-hoc'"]}}],"slots":[{"name":"","description":"The reasoning/thinking content."}],"js":{"properties":[{"name":"compact","description":"Tighter header/body padding and header gap for dense transcript contexts. Defaults to\n`false`, preserving the regular-density treatment. This changes density only; the outer\nborder and surface remain, so use `frame=\"plain\"` to remove card chrome.\n\nAttribute: `compact`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"durationMs","description":"How long the reasoning took, in milliseconds, once known. Omitted\nentirely (nothing rendered in `'post-hoc'`, a pulsing placeholder in\n`'live'`) while unset.\n\nAttribute: `duration-ms`","type":"number | undefined"},{"name":"expanded","description":"Whether the reasoning transcript is currently shown. Starts collapsed,\nmatching `<lr-source-list>`'s default -- a consumer running `'live'`\nreasoning sets this `true` itself to stream it in view as it arrives.\n\nAttribute: `expanded`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"follow","description":"Whether live, expanded content follows the transcript tail. User scrolling updates this\nproperty and emits `lr-follow-change`; direct assignments are controlled input and do not\necho an event. Opening a live panel or calling `scrollToBottom()` re-engages it silently.\n\nAttribute: `follow`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"frame","description":"Visual chrome, in the library's shared container-frame vocabulary. `'card'` (the default)\nkeeps the bordered, filled outer container. `'plain'` removes that outer border, background,\nand corner radius so a thinking panel nested inside existing message chrome does not double\nit. Plain preserves the header/body divider and whichever regular or compact padding applies.\n\nAttribute: `frame`  \nReflected to its attribute.","type":"LyraFrame","default":"'card'"},{"name":"label","description":"Optional header-text override. Omission localizes `thinkingPanelLabel`; any supplied string,\nincluding `'Thinking'` or `''`, is rendered verbatim.\n\nAttribute: `label`","type":"string | undefined"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"mode","description":"Attribute: `mode`  \nReflected to its attribute.","type":"ThinkingPanelMode"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-follow-change","description":"`detail: { following }`; emitted only when a user scroll releases or re-engages tail following. Direct `follow` assignment and `scrollToBottom()` do not echo it.","type":"CustomEvent<{ following: boolean }>"},{"name":"lr-toggle","description":"The accepted header request committed. `detail: { expanded }` carries the new state and is never emitted for a vetoed proposal.","type":"CustomEvent<ThinkingPanelToggleDetail>"},{"name":"lr-toggle-request","description":"Cancelable proposal emitted before a header activation changes `expanded`. `detail: { expanded }` carries the requested next state.","type":"CustomEvent<ThinkingPanelToggleDetail>"}]}},{"name":"lr-thread-list","description":"`<lr-thread-list>` — the conversation sidebar: a grouped, searchable list of chat sessions with\npin/archive/delete/rename affordances. *Data mode* (non-empty `threads`, or empty `threads` with\nnothing slotted) renders every row as a `<lr-conversation-item>` inside an internal\n`<lr-virtual-list>` — virtualized by construction, scroll position and per-row state survive a\n`threads` replacement; zero rows renders the built-in empty state. *Slotted mode* (empty `threads`\n*and* real slotted content) renders host-supplied `<lr-conversation-item>`s from the default slot\nas-is: no grouping, virtualization, or row actions in that mode — those are data-mode-only by design\n(shadow DOM cannot inject group headers between slotted children).\n\nNo thread CRUD or persistence: every mutation (`lr-thread-pin`/`-archive`/`-delete`/`-rename`) is\na controlled event carrying the *requested* new state — the host mutates `threads`.\nData-mode thread `id` values must be nonempty, nonblank, and unique. Untyped invalid rows and\nlater duplicates are omitted deterministically, so focus, virtualization, actions, and emitted\n`conversationId` values all resolve to the first valid occurrence.\nArrow/Home/End navigation skips unavailable rows, including a row placed below an `inert`\nancestor by `wrapRow`. Arrow navigation continues through the complete item model at a virtual\nwindow edge; Home/End always resolve the first/last complete-model thread even from a middle\nwindow, mounting candidates until an available row can receive focus.\n\nData mode: a host needing content with no home in `lr-conversation-item`'s own\n`label`/`excerpt`/`meta`/`actions` surface sets `wrapRow` to wrap the already-built row. For\ncommon row composition, `renderStart`, `renderExcerpt`, `renderMeta`, and `renderRowContent`\nprovide focused virtualized render hooks -- `renderExcerpt` renders into the row item's own\n`excerpt` slot (winning over the plain-string `excerpt` property) for rich per-row content such\nas a highlighted search snippet. A host needing a fully custom\n`actions` surface itself — beyond `rowActions`'s closed `pin | archive | delete` set, e.g. a\n`<lr-dropdown>` + `<lr-menu>` with Rename/Delete — sets `renderActions` instead; its content is appended after any\nbuilt-in `rowActions` output in the same slot, and `wrapRow` continues to compose around the result.\n\nPublic collection properties take bounded, detached readonly sequences. Thread display fields\nare projected from own data descriptors once per assignment; callbacks retain the caller's\nexact source thread identity. Create a new collection and reassign it after changes; mutating\nthe assigned array does not update the view.\n\nA separate `error` state reports a failed load: while `error` is set, the built-in `<lr-empty>`\nfailed-load state (the same `error`-prefixed exported parts and `[part='retry-button']` as\n`<lr-table>`) replaces the virtual list/empty state, behind its own `error` slot. `error` beats\nthe built-in empty state, matching `<lr-table>`'s own precedence.\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) | Slotted mode only: host-supplied `lr-conversation-item`s, rendered in order. Each top-level assigned element that doesn't already carry an explicit `role` is given `role=\"listitem\"`, since `[part=\"list\"]` is `role=\"list\"` in this mode and `lr-conversation-item` deliberately doesn't self-apply that role (see its own class doc). |\n| `empty` | Replaces the built-in empty state. |\n| `error` | Replaces the built-in failed-load state, including its retry button, while `error` is set. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The root. |\n| `clear-button` | Clears the search field. Rendered only while it has a value. |\n| `empty` | The empty/no-matches state. |\n| `error` | The built-in `<lr-empty>` host rendered while `error` is set. |\n| `error-actions` | Exported from the built-in error `<lr-empty>`'s `actions` part. |\n| `error-base` | Exported from the built-in error `<lr-empty>`'s own `base` part. |\n| `error-description` | Exported from the built-in error `<lr-empty>`'s `description` part. |\n| `error-heading` | Exported from the built-in error `<lr-empty>`'s `heading` part. |\n| `error-icon` | Exported from the built-in error `<lr-empty>`'s `icon` part. |\n| `group-adornment` | Optional rich `renderGroupAdornment` output beside the toggle. |\n| `group-header` | A date/custom group header in data mode. |\n| `group-icon` | The decorative expand/collapse glyph. |\n| `group-label` | The group label inside `group-toggle`. |\n| `group-sticky` | `sticky-groups` only: the pinned copy of the current group's header, exported from the internal `lr-virtual-list`'s sticky layer. It repeats the `group-header`, `group-label`, and `group-icon` visuals but is `aria-hidden`, inert, and pointer-transparent; the real row remains the sole `group-toggle`. Style this part for the pinned band itself, e.g. a shadow or a border under the band. |\n| `group-toggle` | The controlled group expand/collapse button. |\n| `list` | The list region. |\n| `pin-glyph` | The small pin indicator shown in a pinned row's `meta` slot (data mode). |\n| `retry-button` | The built-in retry control rendered into the error state's `actions`. |\n| `row` | Exported from the internal `lr-virtual-list`'s `row` part (data mode). |\n| `row-action` | A built-in pin/archive/delete icon button (data mode, when `rowActions` includes it). |\n| `row-actions` | The wrapper around built-in and `renderActions` output. |\n| `row-content` | The wrapper around `renderRowContent` output. |\n| `row-excerpt` | The wrapper around `renderExcerpt` output, slotted into the row item's own `excerpt` slot. |\n| `row-item-actions` | Data mode: the row item's `actions` wrapper. |\n| `row-item-active-indicator` | Data mode: the row item's decorative active indicator, exported from `lr-conversation-item`. |\n| `row-item-base` | Data mode: the row `<lr-conversation-item>`'s own `base` part — the box whose padding sets row height. `row-item-*` parts are the item's *internals*; the `row-*` parts above wrap this component's own callback output and are a different surface. Styling row density here replaces the older `::part(row) { --lr-theme-*: … }` workaround, which retheme'd the whole row subtree (`renderActions` popups included). |\n| `row-item-content` | Data mode: the row item's label/excerpt content column. |\n| `row-item-excerpt` | Data mode: the row item's excerpt line. |\n| `row-item-label` | Data mode: the row item's visible label. |\n| `row-item-label-input` | Data mode: the row item's in-place rename `<input>`. |\n| `row-item-meta` | Data mode: the row item's `meta` wrapper. |\n| `row-item-rename-button` | Data mode: the row item's pencil/rename affordance. |\n| `row-item-select-button` | Data mode: the row item's selectable button-like region. |\n| `row-item-start` | Data mode: the row item's `start` wrapper. |\n| `row-item-timestamp` | Data mode: the row item's `<time>` element. |\n| `row-meta` | A wrapper around built-in or `renderMeta` metadata. |\n| `row-start` | The wrapper around `renderStart` output. |\n| `row-wrapper` | The wrapper around `wrapRow` output (data mode, only when `wrapRow` is set). Row-only: group headers are never passed through `wrapRow`, so they never carry it. |\n| `search` | The search field wrapper. |\n| `search-input` | The `<input type=\"search\">`. |\n| `viewport` | The real scroll container, exported from the internal `lr-virtual-list`. It fills this component's height with no consumer CSS (and falls back to `lr-virtual-list`'s own 24rem `--lr-virtual-list-height` default when the container has no resolvable height). |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-thread-list-excerpt-highlight-background` (default: `var(--lr-color-warning-quiet)`) — Background of `<mark>` descendants returned by `renderExcerpt`.\n- `--lr-thread-list-excerpt-highlight-foreground` (default: `inherit`) — Foreground of `<mark>` descendants returned by `renderExcerpt`.\n- `--lr-thread-list-excerpt-highlight-padding` (default: `0`) — Padding of `<mark>` descendants returned by `renderExcerpt`.\n- `--lr-thread-list-excerpt-highlight-radius` (default: `var(--lr-radius-xs)`) — Corner radius of `<mark>` descendants returned by `renderExcerpt`.\n- `--lr-thread-list-group-toggle-active-bg` (default: `color-mix(in oklab, var(--lr-thread-list-group-toggle-hover-bg, var(--lr-color-surface-raised)), var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Group-toggle pressed background.\n- `--lr-thread-list-group-toggle-active-color` (default: `var(--lr-thread-list-group-toggle-hover-color, var(--lr-color-text))`) — Group-toggle pressed foreground.\n- `--lr-thread-list-group-toggle-hover-bg` (default: `var(--lr-color-surface-raised)`) — Group-toggle hover background.\n- `--lr-thread-list-group-toggle-hover-color` (default: `var(--lr-color-text)`) — Group-toggle hover foreground.\n- `--lr-thread-list-row-action-active-bg` (default: `color-mix(in oklab, var(--lr-thread-list-row-action-hover-bg, var(--lr-color-surface-raised)), var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Row-action pressed background.\n- `--lr-thread-list-row-action-active-color` (default: `var(--lr-thread-list-row-action-hover-color, var(--lr-color-text))`) — Row-action pressed foreground.\n- `--lr-thread-list-row-action-hover-bg` (default: `var(--lr-color-surface-raised)`) — Row-action hover background.\n- `--lr-thread-list-row-action-hover-color` (default: `var(--lr-color-text)`) — Row-action hover foreground.\n- `--lr-thread-list-search-clear-size` (default: `var(--lr-size-1-5rem)`) — Box size of the search field's clear button. Deliberately not tiered by `size`: it is a tap target floored at the shared minimum target size, not a text box.\n- `--lr-thread-list-search-font-size` — Text size of the search field. Unset while `size` is, so the field inherits the ambient text size; a `size` tier resolves it to that tier's shared form-control font size.\n- `--lr-thread-list-search-gap` (default: `var(--lr-space-xs)`) — Gap between the search field and its clear button.\n- `--lr-thread-list-search-min-height` — Minimum row height of the search field. Unset while `size` is, so the field is exactly as tall as its own text plus padding; a `size` tier resolves it to that tier's shared form-control height.\n- `--lr-thread-list-search-padding` (default: `var(--lr-space-s)`) — Gutter around the built-in search field. Deliberately not tiered by `size`, which sizes the field itself.\n- `--lr-thread-list-search-padding-block` (default: `var(--lr-space-xs)`) — Block gutter of the search field. A `size` tier replaces the default with that tier's shared form-control block gutter.\n- `--lr-thread-list-search-padding-inline` (default: `var(--lr-space-s)`) — Inline gutter of the search field. A `size` tier replaces the default with that tier's shared form-control inline gutter.\n- `--lr-thread-list-search-radius` (default: `var(--lr-radius)`) — Corner radius of the search field. A `size` tier replaces the default with that tier's shared form-control radius.","attributes":[{"name":"active-conversation-id","description":"Data mode: marks the matching raw thread id `active`/`aria-current` and scrolls it into view.\nInternal group and thread keys are separately namespaced, so ids such as `group:today` remain\nordinary thread ids rather than colliding with a group header.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"compact","description":"Data mode only: forwarded to every row `<lr-conversation-item>`'s own `compact`, tightening\neach row's padding and gaps in one place. Slotted mode is a deliberate no-op — this component\nrenders host-supplied items as-is, so the host sets `compact` on its own items there, the same\ndivision of responsibility slotted mode already has for every other row property.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"error","description":"Reports a failed thread-list load. While set, the built-in failed-load state (matching\n`<lr-table>`'s own `error` contract) replaces the virtual list/empty state; `error` beats the\nbuilt-in empty state. Reflected so `[error]` is selectable from outside.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"error-description","description":"Failed-load supporting copy.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"error-heading","description":"Failed-load heading override. Omitted localizes `<lr-table>`'s own `tableLoadFailed`\ndefault.\n\nType: `string | undefined`"},{"name":"grouping","description":"Data mode: bucket rows under localized date headers, use `groupBy` with `'custom'`, or use\n`'none'` for a flat list in host order.\n\nType: `ThreadListGrouping`  \nDefault: `'date'`","value":{"type":["'date'","'custom'","'none'"]}},{"name":"label","description":"Accessible name for the list region. Optional. Omitting it localizes the default\n`threadListLabel` message; an explicit empty string renders no visible/accessible label.\n\nType: `string | undefined`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"renamable","description":"Forwarded to each data-mode row's inline rename.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"searchable","description":"Shows the built-in search field.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"show-archived","description":"Data mode: include `archived` threads (in their own trailing group under `grouping=\"date\"`).\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"size","description":"Density tier for the built-in search field, on the library's one size ladder, in either\nspelling -- `2xs`/`xs`/`s`/`m`/`l`/`xl`, or Web Awesome's and Shoelace's\n`small`/`medium`/`large`. Opt-in: with no size the field keeps the exact gutters, corner\nradius and inherited text size it shipped with, so existing markup renders unchanged. A tier\ngives it the row height, text size, gutters and corner radius an `<lr-input>` of that tier\nhas, so this sidebar's own filter box lines up with an adjacent themed search field instead\nof sitting at one fixed size no consumer could reach. Only the field is tiered: the gutter\naround it and the clear affordance keep their own sizes, because the clear button is a tap\ntarget floored by the shared minimum target size rather than by the text scale -- both have\ntheir own custom properties for a consumer that wants to move them too. Unsupported values\nnormalize to the omitted state and remove the attribute.\n\nType: `LyraSize | undefined`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}},{"name":"sticky-groups","description":"Data mode only: pins the current date/custom group's header to the top of the scroll viewport\nwhile its rows are in view, pushing it off as the next group's header arrives. Group headers\nare ordinary virtualized rows, so this renders a `aria-hidden` copy of the header into\n`lr-virtual-list`'s sticky layer (`[part=\"group-sticky\"]`) — the real row keeps the\n`role=\"heading\"`, focus, and collapse-action ownership, while the copy is presentational,\ninert, and pointer-transparent. Default `false` leaves rendering exactly as it is without\nthis feature; `grouping=\"none\"` has no headers to pin, so it is a no-op there.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"","description":"Slotted mode only: host-supplied `lr-conversation-item`s, rendered in order. Each top-level assigned element that doesn't already carry an explicit `role` is given `role=\"listitem\"`, since `[part=\"list\"]` is `role=\"list\"` in this mode and `lr-conversation-item` deliberately doesn't self-apply that role (see its own class doc)."},{"name":"empty","description":"Replaces the built-in empty state."},{"name":"error","description":"Replaces the built-in failed-load state, including its retry button, while `error` is set."}],"js":{"properties":[{"name":"activeConversationId","description":"Data mode: marks the matching raw thread id `active`/`aria-current` and scrolls it into view.\nInternal group and thread keys are separately namespaced, so ids such as `group:today` remain\nordinary thread ids rather than colliding with a group header.\n\nAttribute: `active-conversation-id`","type":"string","default":"''"},{"name":"collapsedGroupIds","description":"Data mode: ids of date/custom groups whose rows are omitted from virtualization.\nSelf-managed by default -- activating the built-in group toggle updates this array directly.\nPrevent the default of the cancelable `lr-group-toggle-request` event to veto that write and\nkeep this property fully controlled instead, the only behavior it had before self-management\nexisted.","type":"readonly string[]","default":"[]"},{"name":"compact","description":"Data mode only: forwarded to every row `<lr-conversation-item>`'s own `compact`, tightening\neach row's padding and gaps in one place. Slotted mode is a deliberate no-op — this component\nrenders host-supplied items as-is, so the host sets `compact` on its own items there, the same\ndivision of responsibility slotted mode already has for every other row property.\n\nAttribute: `compact`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"error","description":"Reports a failed thread-list load. While set, the built-in failed-load state (matching\n`<lr-table>`'s own `error` contract) replaces the virtual list/empty state; `error` beats the\nbuilt-in empty state. Reflected so `[error]` is selectable from outside.\n\nAttribute: `error`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"errorDescription","description":"Failed-load supporting copy.\n\nAttribute: `error-description`","type":"string","default":"''"},{"name":"errorHeading","description":"Failed-load heading override. Omitted localizes `<lr-table>`'s own `tableLoadFailed`\ndefault.\n\nAttribute: `error-heading`","type":"string | undefined"},{"name":"filter","description":"Overrides the default case-insensitive `title` + `excerpt` substring match.","type":"(\n    thread: LyraChatThread,\n    query: string\n  ) => boolean | undefined"},{"name":"formatDate","description":"Overrides the default locale-aware formatting used for month group dates.","type":"(date: Date) => string | undefined"},{"name":"getGroupLabel","description":"Returns the semantic string label for any date or custom group.","type":"(\n    context: ThreadGroupContext\n  ) => string | undefined"},{"name":"groupBy","description":"`grouping=\"custom\"`: derives an arbitrary controlled nonblank group id for every visible\nthread. Rows whose callback fails or returns an invalid id are omitted from the grouped view.","type":"(thread: LyraChatThread) => string | undefined"},{"name":"groupOrder","description":"`grouping=\"custom\"`: explicit group-id order, or a comparator. Unlisted ids follow in their\nfirst-seen order when an array is supplied.","type":"| readonly string[]\n    | ((a: string, b: string) => number) | undefined"},{"name":"grouping","description":"Data mode: bucket rows under localized date headers, use `groupBy` with `'custom'`, or use\n`'none'` for a flat list in host order.\n\nAttribute: `grouping`","type":"ThreadListGrouping","default":"'date'"},{"name":"label","description":"Accessible name for the list region. Optional. Omitting it localizes the default\n`threadListLabel` message; an explicit empty string renders no visible/accessible label.\n\nAttribute: `label`","type":"string | undefined"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"renamable","description":"Forwarded to each data-mode row's inline rename.\n\nAttribute: `renamable`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"renderActions","description":"Data mode only: appended after any built-in `rowActions` buttons in the same row's `actions`\nslot -- the escape hatch for a fully custom per-row action surface (e.g. an `<lr-dropdown>`\ncontaining `<lr-menu>` with\nRename/Delete, mirroring an app's own richer row-action menu) that `rowActions`'s closed\n`pin | archive | delete` set can't express. Additive, not a replacement: both render together\nwhen `rowActions` is also non-empty, the same composition direction `wrapRow` already takes\nelsewhere on the row (it only ever adds content, never removes built-in output) -- set\n`rowActions` to `[]` (its default) to omit the built-in buttons and use only the callback's\ncontent. Receives the *current* thread on every render, re-invoked per row through the\nvirtualized `renderItem` path exactly like `wrapRow` -- never memoized or stale. Rendered as a\nDOM sibling of the row's own selectable region (`lr-conversation-item`'s `[part=\"select-button\"]`),\nthe same structural reason the built-in `rowActions` buttons don't also trigger `lr-select` --\nso ordinary Lyra controls returned here (`lr-dropdown`, `lr-icon-button`, etc.) fire their own\nevents normally without also selecting the row. A nested open `lr-dropdown` also keeps its\nvirtual row above later rows even if focus temporarily leaves the menu. Unset (the default)\nleaves `rowActions`' output byte-for-byte unchanged.","type":"(\n    thread: LyraChatThread\n  ) => TemplateResult | undefined"},{"name":"renderExcerpt","description":"Data mode only: renders the row's excerpt content into the row item's own `excerpt` slot,\nwhich wins over its plain-string `excerpt` property whenever it has assigned content -- see\n`<lr-conversation-item>`'s own `excerpt` slot doc. Use this for rich content the plain\n`LyraChatThread.excerpt` string can't carry, e.g. a server-highlighted search-match snippet.\nUnlike `renderRowContent`, this leaves the built-in label layout and inline-rename affordance\nuntouched -- only the excerpt line is replaced. Unset (the default) leaves the plain-string\n`excerpt` property rendering exactly as it does today.","type":"(\n    thread: LyraChatThread\n  ) => TemplateResult | undefined"},{"name":"renderGroupAdornment","description":"Renders optional rich content beside (never inside) a group toggle.","type":"(\n    context: ThreadGroupContext\n  ) => TemplateResult | undefined"},{"name":"renderMeta","description":"Data mode only: renders the row's meta content. Built-in pin metadata remains available when\npresent, and this result is appended in the same meta region.","type":"(\n    thread: LyraChatThread\n  ) => TemplateResult | undefined"},{"name":"renderRowContent","description":"Data mode only: replaces the conversation item's label/excerpt/meta content area with a\nhost-rendered row body. Use this for structured, non-interactive row content while keeping\nthe selectable row and timestamp semantics supplied by `<lr-conversation-item>`.","type":"(\n    thread: LyraChatThread\n  ) => TemplateResult | undefined"},{"name":"renderStart","description":"Data mode only: renders non-interactive content in the row's start slot, before its label\nand excerpt. The callback runs during the virtualized row render.","type":"(\n    thread: LyraChatThread\n  ) => TemplateResult | undefined"},{"name":"rowActions","description":"Data mode only: built-in icon buttons rendered into each row's `actions` slot, in display order.","type":"readonly ThreadRowAction[]","default":"[]"},{"name":"searchable","description":"Shows the built-in search field.\n\nAttribute: `searchable`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"showArchived","description":"Data mode: include `archived` threads (in their own trailing group under `grouping=\"date\"`).\n\nAttribute: `show-archived`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"size","description":"Density tier for the built-in search field, on the library's one size ladder, in either\nspelling -- `2xs`/`xs`/`s`/`m`/`l`/`xl`, or Web Awesome's and Shoelace's\n`small`/`medium`/`large`. Opt-in: with no size the field keeps the exact gutters, corner\nradius and inherited text size it shipped with, so existing markup renders unchanged. A tier\ngives it the row height, text size, gutters and corner radius an `<lr-input>` of that tier\nhas, so this sidebar's own filter box lines up with an adjacent themed search field instead\nof sitting at one fixed size no consumer could reach. Only the field is tiered: the gutter\naround it and the clear affordance keep their own sizes, because the clear button is a tap\ntarget floored by the shared minimum target size rather than by the text scale -- both have\ntheir own custom properties for a consumer that wants to move them too. Unsupported values\nnormalize to the omitted state and remove the attribute.\n\nAttribute: `size`  \nReflected to its attribute.","type":"LyraSize | undefined"},{"name":"stickyGroups","description":"Data mode only: pins the current date/custom group's header to the top of the scroll viewport\nwhile its rows are in view, pushing it off as the next group's header arrives. Group headers\nare ordinary virtualized rows, so this renders a `aria-hidden` copy of the header into\n`lr-virtual-list`'s sticky layer (`[part=\"group-sticky\"]`) — the real row keeps the\n`role=\"heading\"`, focus, and collapse-action ownership, while the copy is presentational,\ninert, and pointer-transparent. Default `false` leaves rendering exactly as it is without\nthis feature; `grouping=\"none\"` has no headers to pin, so it is a no-op there.\n\nAttribute: `sticky-groups`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"threads","description":"At least one valid thread ⇒ data mode (the default slot is ignored). No valid threads and no\nslotted content ⇒ data mode with zero rows (the built-in empty state). No valid threads with\nslotted content ⇒ slotted mode. Thread ids must be nonempty and unique; invalid/later\nduplicate rows are omitted, first wins.","type":"readonly LyraChatThread[]","default":"[]"},{"name":"wrapRow","description":"Data mode only: wraps each row's built-in `<lr-conversation-item>` with host-supplied\ncontent that has no home in the item's own `label`/`excerpt`/`meta`/`actions` surface — e.g. a\nstart-side purpose icon (`lr-conversation-item` has no default slot to receive one) or trailing\ntag chips. Receives the thread and the already-built row `TemplateResult`; returns the final\nrow content. Unset renders the built-in row unwrapped -- no extra element is added at all.\nWhen set, the returned content is placed inside a library-owned `part=\"row-wrapper\"` block\n`<div>`, so the whole wrapped row is styleable from outside as\n`lr-thread-list::part(row-wrapper)` (padding, border, background, `display: flex`, …) without\nthe host having to thread its own class through this callback. That wrapper is deliberately\nunstyled and block-level: the box `lr-virtual-list` measures for windowing is its own\n`[part=\"row\"]` one level up, and an unstyled block box contributes exactly its child's height\nto it, so adding it leaves every measured row height unchanged. Applies to rows only -- group\nheaders never pass through `wrapRow` and never carry `row-wrapper`.","type":"(\n    thread: LyraChatThread,\n    row: TemplateResult\n  ) => TemplateResult | undefined"}],"events":[{"name":"blur","description":"`searchable`: re-dispatched from the internal search `<input>`'s own `blur` -- bubbling and composed (unlike the native event, which is neither), so a listener above the shadow boundary can observe it.","type":"CustomEvent<null>"},{"name":"focus","description":"`searchable`: re-dispatched from the internal search `<input>`'s own `focus`, for the same reason as `blur`.","type":"CustomEvent<null>"},{"name":"lr-filter-change","description":"`detail: { text, matchCount }` -- data-mode query plus owned results.","type":"CustomEvent<{ text: string; matchCount: number }>"},{"name":"lr-group-toggle","description":"`detail: { groupId, collapsed }` -- a custom/date group's collapse-state change was accepted and, unless `lr-group-toggle-request` was prevented, already applied to `collapsedGroupIds`. A host that already listens here and reassigns `collapsedGroupIds` itself keeps working unchanged: this component's own write, when it happens, always precedes that listener in the same synchronous event dispatch, so the host's own assignment simply wins last.","type":"CustomEvent<ThreadGroupToggleDetail>"},{"name":"lr-group-toggle-request","description":"`detail: { groupId, collapsed }` -- cancelable proposal before a custom/date group's collapse state changes. Calling `preventDefault()` skips the built-in `collapsedGroupIds` write below and suppresses the following `lr-group-toggle`, leaving the group's collapse state fully controlled -- the host must then reassign `collapsedGroupIds` itself, mirroring `<lr-chat-message>`'s and `<lr-code-block>`'s own `lr-toggle-request`/`lr-toggle` pairs.","type":"CustomEvent<ThreadGroupToggleDetail>"},{"name":"lr-query-change","description":"`detail: { text }` -- slotted-mode query request; the host owns results.","type":"CustomEvent<{ text: string }>"},{"name":"lr-retry","description":"The built-in `[part='retry-button']` was activated, only rendered while `error` is set. Cancelable: the default action clears `error`; `preventDefault()` leaves it set instead.","type":"CustomEvent<null>"},{"name":"lr-select","description":"`detail: { conversationId }` -- a row was activated (data mode only).","type":"CustomEvent<{ conversationId: string }>"},{"name":"lr-thread-archive","description":"`detail: { conversationId, archived }` -- the requested new state.","type":"CustomEvent<{\n    conversationId: string;\n    archived: boolean;\n  }>"},{"name":"lr-thread-delete","description":"`detail: { conversationId }` -- no built-in confirmation.","type":"CustomEvent<{ conversationId: string }>"},{"name":"lr-thread-pin","description":"`detail: { conversationId, pinned }` -- the requested new state.","type":"CustomEvent<{ conversationId: string; pinned: boolean }>"},{"name":"lr-thread-rename","description":"`detail: { conversationId, label }`, re-emitted from the row's correlated `lr-rename` request (data mode only).","type":"CustomEvent<{ conversationId: string; label: string }>"}]}},{"name":"lr-time-input","description":"`<lr-time-input>` — a locale-aware segmented time field with an attached column picker.\n\nMirrors the public `<wa-time-input>` surface under the `lr-` prefix. The submitted value is a\ntimezone-free 24-hour string (`HH:mm`, or `HH:mm:ss` when seconds are shown); an incomplete\ndraft submits the empty string. Use `<lr-native-time-input>` for the Lyra 7 browser-native\n`input[type=time]` experience.\n\nThe outer row follows the shared control-height ladder without adding padding around its action\nhit targets: compact tiers grow only enough for the clear/expand buttons, while `l` and `xl`\nretain their larger shared heights.\nLocale digits and ASCII digits are accepted symmetrically. Constraint bounds are formatted\nthrough the same locale presentation, while the wire value remains ASCII. Numeric step\nvalidation and picker options use the native time step base (valid `min`, then the reset\ndefault, then midnight) and the picker projects only complete times on that grid.\nEach picker column is a one-stop listbox: ArrowUp/ArrowDown/Home/End rove its enabled options,\nand the native option button supplies Enter/Space activation.\nWhen a controlled locale, hour format, or step change removes the segment that currently owns\nfocus, focus moves to the first surviving segment after the new pattern renders. Changes never\nreclaim focus from another control.\nThe semantic group and every spinbutton expose explicit required/invalid states. Requiredness\nalso has one localized hidden group description that composes with the visible hint/error\nrelationship; visible error chrome wins `aria-invalid` immediately, while intrinsic/custom\ninvalidity is exposed only after interaction.\nA host `aria-describedby` is resolved onto the semantic group before its own hint, error, and\nrequired descriptions, so externally-owned guidance remains valid across the shadow boundary.\nHost `aria-labelledby` is deliberately not projected: the rendered visible label owns this\ngroup's label relationship.\n\nRemoving label or hint safely omits that content while retaining native null property\nreadback. Explicit empty strings remain empty.\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| `clear-icon` | Replaces the clear glyph. |\n| `end` | Adornment after the clear action and before the expand action. |\n| `error` | Custom error content. |\n| `expand-icon` | Replaces the picker expand glyph. |\n| `footer` | Replaces the default Now footer action. |\n| `hint` | Custom hint content. |\n| `label` | Custom label content. |\n| `start` | Adornment before the segments. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The segmented time row. |\n| `clear-button` | The clear action. |\n| `column` | One hour, minute, second, or day-period column. It scrolls only in the block axis and clips inline overflow when a consumer supplies an undersized `--column-width`. |\n| `column-item` | A picker column option. |\n| `column-item-selected` | A selected picker option; also carries `column-item`. |\n| `columns` | The picker column group. |\n| `end` | Shrinkable wrapper around the `end` slot; long content ellipsizes. |\n| `error` | Ordinary validation text referenced by the segmented input through `aria-describedby`; it is not a live region, avoiding duplicate native validation feedback. |\n| `expand-button` | The picker toggle. |\n| `expand-icon` | The picker-toggle glyph. |\n| `form-control` | The outer form-control wrapper. |\n| `form-control-input` | The row containing segments and actions. |\n| `form-control-label` | The wrap-safe label wrapper; unbroken localized text stays within the host allocation. |\n| `hint` | The hint message. |\n| `input` | The segmented editing surface. |\n| `input-wrapper` | The row containing segments and actions. |\n| `label` | Compatibility alias for `form-control-label` on the same node. |\n| `now-button` | The default Now footer action. |\n| `popup` | The positioned picker surface. |\n| `segment` | An editable time segment. |\n| `segment-literal` | A locale-derived separator. |\n| `start` | Shrinkable wrapper around the `start` slot; long content ellipsizes. |\n| `time-input` | Compatibility alias for `base` on the same node. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-time-input-control-min-height` (default: `var(--lr-form-control-height)`) — Outer row height floor, taken from the active `size` tier of the shared form-control ladder (`internal/sizes.styles.ts`), so a time field is exactly as tall as an `<lr-input>`/ `<lr-select>` of the same tier.\n- `--lr-time-input-control-height` — Exact outer row height. Unset by default, which leaves `--lr-time-input-control-min-height` as a floor only; set it to a length to both floor and cap the row (e.g. to pixel-match `<lr-date-input>` in the same toolbar). Because it is never declared by the component itself, it can be set from an ancestor or an outer-tree rule as well as inline on the element.\n- `--lr-time-input-gap` (default: `var(--lr-form-control-gap)`) — Gap between segments, adornments, and actions in the outer row. Undeclared on the host so ancestor theme wrappers can set it.\n- `--lr-time-input-radius` (default: `var(--lr-form-control-radius)`) — Outer row corner radius. `pill` supplies `--lr-radius-pill` only as the fallback, so a component-scoped value wins.\n- `--lr-time-input-border-color` (default: `var(--lr-color-border)`) — Outer row border color, with appearance-specific fallbacks.\n- `--lr-time-input-fill` (default: `transparent`) — Outer row background, with appearance-specific fallbacks.\n- `--lr-time-input-color` (default: `var(--lr-color-text)`) — Outer row text color, including the accent appearance fallback.\n- `--lr-time-input-focus-border-color` (default: `var(--lr-color-brand)`) — Open/focused row border.\n- `--lr-time-input-segment-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Segment hover fill.\n- `--lr-time-input-segment-active-bg` — Segment pressed fill; derived from hover when unset.\n- `--lr-time-input-segment-focus-bg` (default: `var(--lr-time-input-segment-hover-bg,var(--lr-color-brand-quiet))`) — Keyboard-focused segment fill.\n- `--lr-time-input-action-color` (default: `var(--lr-color-text-quiet)`) — Resting clear/expand color.\n- `--lr-time-input-action-hover-color` (default: `var(--lr-color-text)`) — Hovered clear/expand color.\n- `--lr-time-input-action-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Clear/expand/Now hover fill.\n- `--lr-time-input-action-active-bg` — Clear/expand/Now pressed fill; derived from hover when unset.\n- `--lr-time-input-column-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Picker-option hover fill.\n- `--lr-time-input-column-active-bg` — Picker-option pressed fill; derived from hover when unset.\n- `--lr-time-input-column-selected-bg` (default: `var(--lr-color-brand)`) — Selected option fill.\n- `--lr-time-input-column-selected-color` (default: `var(--lr-color-on-brand)`) — Selected option text.\n- `--lr-time-input-column-selected-font-weight` (default: `var(--lr-font-weight-semibold)`) — Selected option weight.\n- `--lr-time-input-column-selected-hover-bg` — Selected-option hover fill; derived when unset.\n- `--lr-time-input-column-selected-active-bg` — Selected-option pressed fill; derived when unset.\n- `--column-item-height` (default: `calc(var(--lr-size-1em)*2.25)`) — Picker row height.\n- `--column-width` (default: `calc(var(--lr-size-1em)*3)`) — Picker column width.\n- `--show-duration` (default: `var(--lr-duration-fast)`) — Picker opening duration.\n- `--hide-duration` (default: `var(--lr-duration-fast)`) — Picker closing duration.\n- `--lr-form-control-focus-shadow` (default: `none`) — The shared field focus halo, painted as a `box-shadow` while this control is focused. One name for every field-shaped control in the library, so a halo is configured once rather than per component. Additive: the focus outline and border cue are the accessibility answer to focus and are never replaced by it.\n- `--lr-form-control-required-content` (default: `' *'`) — The required-field marker rendered after the label. Set it to `''` to suppress the marker, or to any other quoted string (`' (required)'`, a localized word) to replace it. Caller-supplied content, so it is never localized here.\n- `--lr-form-control-required-color` (default: `var(--lr-color-danger)`) — Color of that marker, retunable without touching any other danger-coloured surface.\n- `--lr-form-control-required-offset` (default: `0`) — Inline space between the label text and the marker.\n- `--lr-overlay-surface` (default: `var(--lr-color-surface-raised)`) — Shared floating-surface fill, on the anchored picker panel. The family's own default is `var(--lr-color-surface-overlay)`; this panel deliberately keeps the raised tone as its unset value so it stays separated from the field it drops from, and it never read as a hole in dark mode.\n- `--lr-overlay-border` (default: `var(--lr-color-border)`) — Shared floating-surface edge colour, on the anchored picker panel.\n- `--lr-overlay-radius` (default: `var(--lr-radius)`) — Shared floating-surface corner radius, on the anchored picker panel.\n- `--lr-overlay-shadow-anchored` (default: `var(--lr-shadow-m)`) — Elevation of the anchored surface.\n- `--lr-positioning-strategy` — Cascading `absolute`/`fixed` override for the column picker's `fixed` default, read from computed style when it is (re)positioned. Set it once on `:root`, a theme, or one clipping ancestor to change every unset time input beneath it; an unrecognized value falls back to `fixed`.","attributes":[{"name":"appearance","description":"Type: `LyraAppearance`  \nDefault: `'outlined'`","value":{"type":["'accent'","'filled'","'outlined'","'filled-outlined'","'plain'"]}},{"name":"autocomplete","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"custom-error","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nType: `string | null`  \nDefault: `null`"},{"name":"disabled","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"distance","description":"Type: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"error-text","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"form","description":"Type: `HTMLFormElement | string | null`  \nDefault: `null`"},{"name":"hint","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"hour-format","description":"Type: `LyraTimeInputHourFormat`  \nDefault: `'auto'`","value":{"type":["'auto'","'12'","'24'"]}},{"name":"label","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"min","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"name","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"open","description":"Whether the column picker is open.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"pill","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"placement","description":"Type: `LyraTimeInputPlacement`  \nDefault: `'bottom-start'`","value":{"type":["'top'","'top-start'","'top-end'","'right'","'right-start'","'right-end'","'bottom'","'bottom-start'","'bottom-end'","'left'","'left-start'","'left-end'"]}},{"name":"readonly","description":"Whether the control remains focusable but blocks user edits.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"required","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"size","description":"Type: `LyraSize`  \nDefault: `'m'`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}},{"name":"step","description":"Allowed value step in seconds, or `any` to disable step validation. Numeric grids use valid\n`min`, then `defaultValue`, then midnight as their base; picker columns project that full grid.\n\nType: `LyraTimeInputStep`  \nDefault: `60`","value":{"type":["LyraTimeInputStep"]}},{"name":"value","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"with-clear","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"with-hint","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"with-label","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"with-now","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"clear-icon","description":"Replaces the clear glyph."},{"name":"end","description":"Adornment after the clear action and before the expand action."},{"name":"error","description":"Custom error content."},{"name":"expand-icon","description":"Replaces the picker expand glyph."},{"name":"footer","description":"Replaces the default Now footer action."},{"name":"hint","description":"Custom hint content."},{"name":"label","description":"Custom label content."},{"name":"start","description":"Adornment before the segments."}],"js":{"properties":[{"name":"appearance","description":"Attribute: `appearance`  \nReflected to its attribute.","type":"LyraAppearance","default":"'outlined'"},{"name":"autocomplete","description":"Attribute: `autocomplete`","type":"string","default":"''"},{"name":"customError","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nAttribute: `custom-error`  \nReflected to its attribute.","type":"string | null","default":"null"},{"name":"defaultValue","description":"Attribute: `value`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"disabled","description":"Attribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"distance","description":"Attribute: `distance`  \nReflected to its attribute.","type":"number","default":"0"},{"name":"errorText","description":"Attribute: `error-text`","type":"string","default":"''"},{"name":"form","description":"Attribute: `form`  \nReflected to its attribute.","type":"HTMLFormElement | string | null","default":"null"},{"name":"hint","description":"Attribute: `hint`","type":"string","default":"''"},{"name":"hourFormat","description":"Attribute: `hour-format`  \nReflected to its attribute.","type":"LyraTimeInputHourFormat","default":"'auto'"},{"name":"label","description":"Attribute: `label`","type":"string","default":"''"},{"name":"labels","type":"NodeList","read-only":true},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"max","description":"Attribute: `max`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"min","description":"Attribute: `min`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"name","description":"Attribute: `name`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"open","description":"Whether the column picker is open.\n\nAttribute: `open`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"pill","description":"Attribute: `pill`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"placement","description":"Attribute: `placement`  \nReflected to its attribute.","type":"LyraTimeInputPlacement","default":"'bottom-start'"},{"name":"readonly","description":"Whether the control remains focusable but blocks user edits.\n\nAttribute: `readonly`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"required","description":"Attribute: `required`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"size","description":"Attribute: `size`  \nReflected to its attribute.","type":"LyraSize","default":"'m'"},{"name":"step","description":"Allowed value step in seconds, or `any` to disable step validation. Numeric grids use valid\n`min`, then `defaultValue`, then midnight as their base; picker columns project that full grid.\n\nAttribute: `step`  \nReflected to its attribute.","type":"LyraTimeInputStep","default":"60"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"validationMessage","type":"string","read-only":true},{"name":"validity","type":"ValidityState","read-only":true},{"name":"value","type":"string"},{"name":"valueAsDate","description":"A Date carrying the selected local clock fields on today's local calendar date.\n\nAssigning reads the same local clock fields back off the given Date, so it round-trips with\nthe getter; `null` or an invalid Date clears the field. Assignment is silent.","type":"Date | null"},{"name":"valueAsNumber","description":"Milliseconds since local midnight, or `NaN` while blank/incomplete.\n\nAssigning sets `value` from the same scale. `NaN`, a negative number, or a full day or more\nclears the field rather than wrapping, matching how a native time input treats an\nout-of-range `valueAsNumber`. Assignment is silent, like the native property.","type":"number"},{"name":"willValidate","type":"boolean","read-only":true},{"name":"withClear","description":"Attribute: `with-clear`","type":"boolean","default":"false"},{"name":"withHint","description":"Attribute: `with-hint`","type":"boolean","default":"false"},{"name":"withLabel","description":"Attribute: `with-label`","type":"boolean","default":"false"},{"name":"withNow","description":"Attribute: `with-now`","type":"boolean","default":"false"}],"events":[{"name":"blur","description":"Re-dispatched when focus leaves the segmented editing surface.","type":"FocusEvent"},{"name":"change","description":"Native `Event` fired when a complete value is committed.","type":"Event"},{"name":"focus","description":"Re-dispatched when focus enters the segmented editing surface.","type":"FocusEvent"},{"name":"input","description":"Native `InputEvent` fired for user edits.","type":"InputEvent"},{"name":"lr-after-hide","description":"The closing transition finished.","type":"CustomEvent<null>"},{"name":"lr-after-show","description":"The opening transition finished.","type":"CustomEvent<null>"},{"name":"lr-change","description":"Prefixed compatibility alias for `change` with `detail.value`.","type":"CustomEvent<{ value: string }>"},{"name":"lr-clear","description":"The clear action removed the value.","type":"CustomEvent<null>"},{"name":"lr-hide","description":"Cancelable event fired before the picker closes.","type":"CustomEvent<null>"},{"name":"lr-input","description":"Prefixed compatibility alias for `input` with `detail.value`.","type":"CustomEvent<{ value: string }>"},{"name":"lr-invalid","description":"The control failed a validity check; cancelable. Calling `preventDefault()` also cancels the native `invalid` event it aliases, suppressing the browser's own validation bubble and `reportValidity()`'s focus/scroll.","type":"CustomEvent<null>"},{"name":"lr-show","description":"Cancelable event fired before the picker opens.","type":"CustomEvent<null>"}]}},{"name":"lr-time-range","description":"`<lr-time-range>` — a two-handle brush/scrubber over a numeric domain.\nCallers map their own time axis to `[min, max]`; no date logic lives here\n(matches the no-date-library constraint used elsewhere in this library).\n\nOptionally paired with a row of discrete presets (`presets`) — e.g. \"Last\n7 days\" / \"Last 30 days\" — rendered above the track; picking one is just a\nshortcut that sets both handles at once, the continuous brush underneath\nis unaffected and both interaction modes coexist. `appliedPreset` preserves which shortcut\nproduced the current range without guessing from numeric equality.\n\nForm-associated for the `<fieldset disabled>` cascade and for validation, not for a submitted\nvalue: it attaches `ElementInternals` (like `<lr-combobox>`'s minimal pattern, rather than the\nsingle-string-value `FormAssociated` mixin, which doesn't fit a two-handle range) so that an\nancestor `<fieldset disabled>` disables both handles and every preset button through\n`effectiveDisabled` the same way it would a native `<input>`, without touching the\nconsumer-facing `disabled` property/attribute itself. Unlike `<lr-combobox>`, it never calls\n`internals.setFormValue()` and has no `name` — the selected range is not included in the owning\nform's `FormData` on submit; read `start`/`end` directly (e.g. from `lr-change`) instead of\nrelying on native form submission. It still takes part in `form.reset()`, though — see\n`formResetCallback()`, which restores the declared `start`/`end` and puts the control back to\npristine so it cannot keep blocking a form the user just reset.\nDirect disablement, fieldset disablement, and form reset synchronously retire every active\nkeyboard/pointer gesture without a stale `change` commit on a later key or pointer release.\n\nIt has no constraints of its own — every reachable range is a legal one, so `checkValidity()`\npasses unless a consumer has set an error through `setCustomValidity()`. That method is the\nwhole point of the validity surface here: a range this component cannot know is wrong (an\noverlapping booking, a window the server rejects) still blocks submission of the form the\nelement sits in.\n\nClicking anywhere on the track — the vast majority of the control's clickable area — jumps\nwhichever handle is nearer the clicked position to that point and continues as the same drag\ngesture, then leaves that handle focused so arrow keys carry on from there. Mirrors\n`<lr-slider>`'s `range` mode exactly, including the RTL ratio mirroring and the tie-break toward\nthe handle that can actually travel toward the click. A pointerdown that starts on a handle stays\na plain handle drag.\n\nDeliberately no label/hint/error chrome -- `startLabel`/`endLabel` here are per-handle\naccessible-name overrides, not visible label text, the same carve-out `<lr-slider>` states for\nits own single-handle `label`; a labeled-field consumer wraps this element in their own layout.\nThe `base` around both handles is still an accessible `role=\"group\"`, named by a non-empty host\n`aria-label`; native external `<label for>` associations remain available through `labels` but do\nnot cross into the shadow-root group. The two handles retain their individual names.\n\nOnly the primary mouse button starts seeking or dragging. Right/middle presses leave values\nand input/change events untouched; touch and pen gestures retain their existing pointer behavior.\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 time-range wrapper. |\n| `handle-end` | The end handle. |\n| `handle-start` | The start handle. |\n| `preset-button` | A preset button. |\n| `presets` | The preset controls wrapper. |\n| `range` | The selected range. |\n| `track` | The complete range track. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-time-range-base-size` (default: `1.5rem*scale`) — Brush baseline block size.\n- `--lr-time-range-handle-bg` (default: `var(--lr-color-brand)`) — Resting handle background.\n- `--lr-time-range-handle-border-color` (default: `var(--lr-color-surface)`) — Resting handle border.\n- `--lr-time-range-handle-hover-bg` — Hovered handle background; defaults to a hover-state mix of `--lr-time-range-handle-bg`.\n- `--lr-time-range-handle-pressed-bg` — Pressed handle background; defaults to an active-state mix of `--lr-time-range-handle-bg`.\n- `--lr-time-range-handle-size` (default: `14px*scale`) — Visible handle diameter.\n- `--lr-time-range-hit-size` (default: `max(24px,28px*scale)`) — Actual drag hit-area diameter; endpoint handles are inset by half this distance so the hit geometry stays inside the host.\n- `--lr-time-range-preset-active-bg` (default: `var(--lr-color-brand)`) — Background of the active preset button (`[data-active]`, i.e. the preset whose button produced the current range). Declared as an inline `var()` fallback (never on `:host`), so setting it on the element or an ancestor recolors only the active preset without hijacking the library-wide `--lr-color-brand` token.\n- `--lr-time-range-preset-active-border-color` (default: `var(--lr-color-brand)`) — Border color of the active preset button.\n- `--lr-time-range-preset-active-color` (default: `var(--lr-color-on-brand)`) — Text color of the active preset button.\n- `--lr-time-range-preset-font-size` — Preset button font size, scaled by `size`.\n- `--lr-time-range-preset-gap` (default: `var(--lr-space-xs)`) — Gap between preset buttons.\n- `--lr-time-range-preset-hover-border-color` (default: `var(--lr-color-brand)`) — Border color of a hovered preset button.\n- `--lr-time-range-preset-padding` — Preset button padding, scaled by `size`.\n- `--lr-time-range-preset-pressed-bg` — Background of a pressed preset button; defaults to an active-state mix of `--lr-color-surface`.\n- `--lr-time-range-preset-pressed-border-color` — Border color of a pressed preset button; defaults to an active-state mix of `--lr-color-brand`.\n- `--lr-time-range-preset-radius` (default: `var(--lr-radius)`) — Preset button corner radius.\n- `--lr-time-range-size-scale` (default: `1`) — Unitless multiplier applied proportionally to the handle, track, and preset-button dimensions based on the current `size` tier; the drag hit-area is floored at 24px (WCAG 2.5.8).\n- `--lr-time-range-track-size` (default: `4px*scale`) — Track and selected-range thickness.","attributes":[{"name":"custom-error","description":"Reflected consumer validity message; only `setCustomValidity('')` clears it.\n\nType: `string | null`"},{"name":"disabled","description":"Type: `boolean`","value":{"type":["boolean"]}},{"name":"end","description":"Type: `number`  \nDefault: `100`","value":{"type":["number"]}},{"name":"end-label","description":"Accessible-name override for the end handle. `undefined` uses the localized default;\nevery supplied string, including empty and `\"Range end\"`, is caller-owned verbatim.\n\nType: `string | undefined`"},{"name":"form","description":"Type: `HTMLFormElement | string | null`  \nDefault: `null`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max","description":"Type: `number`  \nDefault: `100`","value":{"type":["number"]}},{"name":"min","description":"Type: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"size","description":"Visual size — proportionally scales the handle, track, and preset buttons via a single\nmultiplier; the drag hit-area never shrinks below 24px (WCAG 2.5.8). Not pixel-matched to\n`lr-input`'s row-height scale -- this component's own dimensions aren't on that ladder. The Web Awesome / Shoelace spellings\n`small`/`medium`/`large` are accepted for `s`/`m`/`l`, so a migration is a tag rename with no\nattribute rewrite.\n\nType: `LyraSize`  \nDefault: `'m'`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}},{"name":"start","description":"Type: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"start-label","description":"Accessible-name override for the start handle. `undefined` uses the localized default;\nevery supplied string, including empty and `\"Range start\"`, is caller-owned verbatim.\n\nType: `string | undefined`"},{"name":"step","description":"Type: `number`  \nDefault: `1`","value":{"type":["number"]}}],"js":{"properties":[{"name":"appliedPreset","description":"The preset whose button produced the current `start`/`end` pair, or `undefined` before a\npreset is selected and after a manual handle move, a controlled endpoint change away from\nthat preset, a preset-collection replacement, or a form reset. Read it inside an\n`input`/`change` or `lr-input`/`lr-change` handler; preset application updates this identity\nbefore dispatching the synchronous event pair. No-op endpoint and preset-snapshot writes\npreserve it.\n\nNumeric equality deliberately does not infer identity. Two presets can resolve to the same\nrange, and a manual drag can land on exactly the same values, while only a preset click means\nthe caller should persist that relative shortcut. The returned object is the frozen snapshot\nexposed through `presets`.","type":"TimeRangePreset | undefined","read-only":true},{"name":"customError","description":"Reflected consumer validity message; only `setCustomValidity('')` clears it.\n\nAttribute: `custom-error`  \nReflected to its attribute.","type":"string | null"},{"name":"disabled","description":"Attribute: `disabled`  \nReflected to its attribute.","type":"boolean"},{"name":"effectiveDisabled","description":"Effective disabled state: this element's own `disabled` OR an ancestor\n`<fieldset disabled>`'s inherited state -- mirrors native `<input>`,\nwhose own `disabled` IDL property/attribute is never mutated by a\nfieldset.","type":"boolean","read-only":true},{"name":"end","description":"Attribute: `end`","type":"number","default":"100"},{"name":"endLabel","description":"Accessible-name override for the end handle. `undefined` uses the localized default;\nevery supplied string, including empty and `\"Range end\"`, is caller-owned verbatim.\n\nAttribute: `end-label`","type":"string | undefined"},{"name":"form","description":"Attribute: `form`  \nReflected to its attribute.","type":"HTMLFormElement | string | null","default":"null"},{"name":"labels","type":"NodeList","read-only":true},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"max","description":"Attribute: `max`","type":"number","default":"100"},{"name":"min","description":"Attribute: `min`","type":"number","default":"0"},{"name":"presets","type":"readonly TimeRangePreset[]"},{"name":"size","description":"Visual size — proportionally scales the handle, track, and preset buttons via a single\nmultiplier; the drag hit-area never shrinks below 24px (WCAG 2.5.8). Not pixel-matched to\n`lr-input`'s row-height scale -- this component's own dimensions aren't on that ladder. The Web Awesome / Shoelace spellings\n`small`/`medium`/`large` are accepted for `s`/`m`/`l`, so a migration is a tag rename with no\nattribute rewrite.\n\nAttribute: `size`  \nReflected to its attribute.","type":"LyraSize","default":"'m'"},{"name":"start","description":"Attribute: `start`","type":"number","default":"0"},{"name":"startLabel","description":"Accessible-name override for the start handle. `undefined` uses the localized default;\nevery supplied string, including empty and `\"Range start\"`, is caller-owned verbatim.\n\nAttribute: `start-label`","type":"string | undefined"},{"name":"step","description":"Attribute: `step`","type":"number","default":"1"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"validationMessage","type":"string","read-only":true},{"name":"validity","type":"ValidityState","read-only":true},{"name":"valueFormatter","description":"Optional human-readable formatter for each handle's `aria-valuetext`. Receives the same\nfinite, clamped number exposed through `aria-valuenow` plus `'start'`/`'end'`; leaving it\nunset preserves the numeric-only slider contract. Return `null`/`undefined` to omit\n`aria-valuetext` for a handle.","type":"TimeRangeValueFormatter | undefined"},{"name":"willValidate","type":"boolean","read-only":true}],"events":[{"name":"blur","description":"Native blur relayed once from either handle.","type":"FocusEvent"},{"name":"change","description":"Native event fired when a handle interaction or preset commits.","type":"Event"},{"name":"focus","description":"Native focus relayed once from either handle.","type":"FocusEvent"},{"name":"input","description":"Native event fired continuously while a user moves either handle.","type":"Event"},{"name":"lr-change","description":"Fired on pointer release, keyboard keyup or handle-blur commit, or when a preset button is clicked. `detail: { start, end }`.","type":"CustomEvent<{ start: number; end: number }>"},{"name":"lr-input","description":"Fired continuously while dragging or on each arrow-key press. `detail: { start, end }`.","type":"CustomEvent<{ start: number; end: number }>"},{"name":"lr-invalid","description":"Cancelable prefixed alias fired when native validity checking fails.","type":"CustomEvent<null>"}]}},{"name":"lr-timeline","description":"`<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. The one tab stop the timeline\nitself owns is `[part='base']` while a `horizontal` strip genuinely overflows — passive items\nleave nothing tabbable inside a scroll container, so without it the events scrolled off the edge\nare pointer-only content. Not a form-associated control — no value to submit, no\nlabel/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. Its `tabindex` rises from `-1` to `0` while (and only while) that horizontal strip genuinely overflows: timeline items are passive, so nothing inside is tabbable and the off-screen events would otherwise be pointer-only content. Style that state with `::part(base):focus-visible`. |\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. Horizontal overlap and stack modes measure actual item/lane height independently and update it when content changes. Ignored in the default `scale=\"flow\"`.","attributes":[{"name":"aria-label","description":"Host-level `aria-label` override for the list's accessible name — wins over the localized\ndefault `\"Timeline\"`. Needed because the `role=\"list\"` element lives in the shadow root and\nnever inherits a host attribute automatically — same reasoning as `<lr-breadcrumb>`'s\nidentical property. Unset falls back to the localized default; an explicitly empty\n`aria-label` stays empty.\n\nType: `string | undefined`"},{"name":"collision","description":"Type: `LyraTimelineCollision`","value":{"type":["'overlap'","'stack'","'cluster'"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"orientation","description":"Type: `LyraOrientation`","value":{"type":["'horizontal'","'vertical'"]}},{"name":"scale","description":"Type: `LyraTimelineScale`","value":{"type":["'flow'","'time'"]}}],"slots":[{"name":"","description":"`<lr-timeline-item>` children, in display order."}],"js":{"properties":[{"name":"accessibleLabel","description":"Host-level `aria-label` override for the list's accessible name — wins over the localized\ndefault `\"Timeline\"`. Needed because the `role=\"list\"` element lives in the shadow root and\nnever inherits a host attribute automatically — same reasoning as `<lr-breadcrumb>`'s\nidentical property. Unset falls back to the localized default; an explicitly empty\n`aria-label` stays empty.\n\nAttribute: `aria-label`","type":"string | undefined"},{"name":"collision","description":"Attribute: `collision`  \nReflected to its attribute.","type":"LyraTimelineCollision"},{"name":"itemCount","description":"Read-only, live-updated count of default-slot `<lr-timeline-item>` assignments, including\nflattened forwarding slots — handy for building a `\"{count} events\"` header without\nhand-counting DOM children.","type":"number","read-only":true},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"orientation","description":"Attribute: `orientation`  \nReflected to its attribute.","type":"LyraOrientation"},{"name":"rangeEnd","description":"Pins the axis end instead of deriving it from the latest item. Ignored unless\n`scale=\"time\"`; a non-finite or reversed pair falls back to the derived range.","type":"Date | string | number | undefined"},{"name":"rangeStart","description":"Pins the axis start instead of deriving it from the earliest item. Ignored unless\n`scale=\"time\"`; a non-finite or reversed pair falls back to the derived range.","type":"Date | string | number | undefined"},{"name":"scale","description":"Attribute: `scale`  \nReflected to its attribute.","type":"LyraTimelineScale"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-cluster-activate","description":"A `collision=\"cluster\"` count marker was activated by pointer, Enter, or Space. `detail: { items }` contains a fresh frozen snapshot of the member `<lr-timeline-item>` elements in document order. Non-cancelable notification; the timeline has no built-in expansion or selection action to veto.","type":"CustomEvent<LyraTimelineClusterActivateDetail>"}]}},{"name":"lr-timeline-item","description":"`<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.","attributes":[{"name":"active","description":"Marks this as the current/in-progress item (e.g. \"the agent is executing this step right now\"),\nas opposed to a resolved past entry. Drives a pulsing marker (disabled under\n`prefers-reduced-motion: reduce`) and an explicit `aria-current` state on the host.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"sync","description":"Forwarded 1:1 onto the internally-rendered `<lr-relative-time>`'s own `sync` property, so a\nlive feed (e.g. streaming agent actions) can opt this item into auto-refreshing relative text\n(\"just now\" ticking to \"1 minute ago\"). Named to match `<lr-relative-time>`'s own `sync`\nproperty verbatim. Has no effect when the `timestamp` slot is populated -- there is no internal\n`<lr-relative-time>` to forward onto in that case.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"variant","description":"Type: `LyraVariant`","value":{"type":["'neutral'","'brand'","'success'","'warning'","'danger'"]}}],"slots":[{"name":"","description":"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."},{"name":"description","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."},{"name":"marker-icon","description":"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`."},{"name":"timestamp","description":"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."}],"js":{"properties":[{"name":"active","description":"Marks this as the current/in-progress item (e.g. \"the agent is executing this step right now\"),\nas opposed to a resolved past entry. Drives a pulsing marker (disabled under\n`prefers-reduced-motion: reduce`) and an explicit `aria-current` state on the host.\n\nAttribute: `active`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"sync","description":"Forwarded 1:1 onto the internally-rendered `<lr-relative-time>`'s own `sync` property, so a\nlive feed (e.g. streaming agent actions) can opt this item into auto-refreshing relative text\n(\"just now\" ticking to \"1 minute ago\"). Named to match `<lr-relative-time>`'s own `sync`\nproperty verbatim. Has no effect when the `timestamp` slot is populated -- there is no internal\n`<lr-relative-time>` to forward onto in that case.\n\nAttribute: `sync`","type":"boolean","default":"false"},{"name":"timestamp","description":"When this event happened. Accepts a `Date`, anything `new Date()` can parse (e.g. an ISO 8601\nstring), or epoch milliseconds. Invalid/unparseable input normalizes to \"unset\" -- no timestamp\nUI renders, identical to `timestamp` never having been set at all. `attribute: false` since\n`Date` instances aren't attribute-serializable -- set via a property binding\n(`.timestamp=${...}`) or imperatively, never a plain HTML attribute. Ignored entirely when the\n`timestamp` slot has assigned content -- see the class doc / that slot's own description.","type":"Date | string | number | undefined"},{"name":"variant","description":"Attribute: `variant`  \nReflected to its attribute.","type":"LyraVariant"}]}},{"name":"lr-toast","description":"`<lr-toast>` — one placement-specific stacking toast region. The `toast()` helper maintains one\nregion per owner document and placement. Each keeps at most three items active and twenty more\nin a hidden, inert FIFO queue. Further admissions discard the\noldest queued work and report the coalesced loss through an event and polite announcement.\nMembership is reconciled before every admission and reasserted after reconnect/reparent; a\nlasting region disconnect discards managed work instead of retaining nodes that could resurrect.\nMirrors the Web Awesome `<wa-toast>` API under the `lr-` prefix.\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-toast-item>` elements. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `stack` | The fl-column container holding the items. |\n\n---\n\n**CSS Custom Properties**\n\n- `--gap` — Mapped alias for `--lr-toast-gap`.\n- `--lr-toast-accent-color` (default: `var(--lr-color-border)`) — Accent bar / icon color of a slotted item. Its private default follows `variant`; an inherited or direct public value wins.\n- `--lr-toast-accent-width` (default: `var(--lr-size-4px)`) — Width of a slotted item's accent bar. Read by `<lr-toast-item>`'s own stylesheet, so set it on the item.\n- `--lr-toast-font-size` (default: `var(--lr-font-size-m)`) — Font size of a slotted item. Its private default follows `size`; an inherited or direct public value wins.\n- `--lr-toast-gap` (default: `var(--lr-space-s)`) — Gap between stacked items.\n- `--lr-toast-hide-duration` (default: `var(--lr-transition-base, 180ms ease-out)`) — Hide transition of a slotted item. Read by `<lr-toast-item>`, so set it on the item.\n- `--lr-toast-padding` (default: `var(--lr-space-m)`) — Padding of a slotted item. Its private default follows `size`; an inherited or direct public value wins.\n- `--lr-toast-show-duration` (default: `var(--lr-transition-base, 180ms ease-out)`) — Show transition of a slotted item. Read by `<lr-toast-item>`, so set it on the item.\n- `--lr-toast-width` (default: `var(--lr-size-28rem)`) — Inline size of the stack, capped by the usable logical safe-area rectangle.\n- `--width` — Mapped alias for `--lr-toast-width`.","attributes":[{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"placement","description":"Where the stack anchors on screen.\n\nType: `LyraToastPlacement`  \nDefault: `'top-end'`","value":{"type":["'top-start'","'top-center'","'top-end'","'bottom-start'","'bottom-center'","'bottom-end'"]}}],"slots":[{"name":"","description":"`<lr-toast-item>` elements."}],"js":{"properties":[{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"placement","description":"Where the stack anchors on screen.\n\nAttribute: `placement`  \nReflected to its attribute.","type":"LyraToastPlacement","default":"'top-end'"},{"name":"stack","description":"Live stack element, or `null` before the render root is populated.","type":"HTMLElement | null","read-only":true},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-toast-overflow","description":"Noncancelable notification that queued items were discarded to keep the stack bounded. Synchronous losses are coalesced into `detail: { count }`.","type":"CustomEvent<LyraToastOverflowDetail>"}]}},{"name":"lr-toast-item","description":"`<lr-toast-item>` — a single toast notification. Its normalized message is announced through a\nshared light-DOM sink, leaving the visible close and action controls outside the live subtree.\nContextual close names include rich non-interactive message markup and update with its text.\nReferenced labels and open shadow roots actually traversed for their text remain observed outside\nthe item. Bounded traversal appends an explicit truncation marker to a prefix, or uses a localized\nincomplete-content fallback when no prefix fits, instead of presenting partial content as whole.\nWhen a focused toast finishes hiding, focus moves to an adjacent toast or back to the pre-toast\ncontrol. An accepted show or hide interrupted by disconnect resumes to one terminal completion\nif the same item reconnects. Region-owned items beyond the active window stay hidden, inert, and\ntimer-paused until FIFO promotion, including an already-visible standalone item reparented into\na full region.\nMirrors the Web Awesome `<wa-toast-item>` API under the `lr-` prefix.\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 message content. Visible non-interactive text, including through forwarding slots, stays synchronized with the close button's contextual accessible name. |\n| `icon` | Optional icon shown at the start. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `accent` | The colored accent bar. |\n| `close-button` | The dismiss button. |\n| `close-icon` | The close glyph wrapper. |\n| `close-icon__svg` | The close glyph's SVG element. |\n| `content` | The message wrapper. |\n| `icon` | The icon wrapper. |\n| `progress-ring` | The auto-dismiss progress ring around the close glyph. |\n| `progress-ring__base` | The progress ring's SVG element. |\n| `progress-ring__indicator` | The elapsed-time indicator circle. |\n| `progress-ring__label` | The ring's centered close-glyph container. |\n| `progress-ring__track` | The progress ring's background circle. |\n| `toast-item` | The outer container. |\n\n---\n\n**CSS Custom Properties**\n\n- `--accent-width` — Mapped alias for `--lr-toast-accent-width`.\n- `--hide-duration` — Mapped alias for `--lr-toast-hide-duration`.\n- `--lr-toast-accent-color` (default: `var(--lr-color-border)`) — Color of the accent bar and the icon. Its private default follows each non-neutral `variant`'s loud fill from the shared semantic grid; `neutral` keeps the plain border color, so an informational toast reads as unaccented. An inherited or direct public value remains authoritative.\n- `--lr-toast-accent-width` (default: `var(--lr-size-4px)`) — Width of the accent bar, and the extra inline-start padding reserved for it.\n- `--lr-toast-close-button-active-bg` (default: `color-mix(in oklab, transparent, var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Background of the enabled close button while pressed.\n- `--lr-toast-close-button-active-color` (default: `var(--lr-color-text)`) — Foreground of the enabled close button while pressed.\n- `--lr-toast-close-button-hover-bg` (default: `transparent`) — Background of the enabled close button while hovered.\n- `--lr-toast-close-button-hover-color` (default: `var(--lr-color-text)`) — Foreground of the enabled close button while hovered.\n- `--lr-toast-font-size` (default: `var(--lr-font-size-m)`) — Font size of the item. Its private default follows `size` across the shared six-step ladder; an inherited or direct public value wins.\n- `--lr-toast-hide-duration` (default: `var(--lr-transition-base, 180ms ease-out)`) — Opacity/transform transition used while hiding.\n- `--lr-toast-item-gap` (default: `var(--lr-space-s)`) — Gap between the item icon, message, and close button. Unlike `--lr-toast-gap`, this does not affect spacing between stacked items.\n- `--lr-toast-item-radius` (default: `var(--lr-radius)`) — Corner radius of the item surface and its accent bar's inline-start corners. Pointer-state hooks are inline fallbacks, so they inherit from the item or an ancestor without recoloring the item surface or the stack.\n- `--lr-toast-padding` (default: `var(--lr-space-m)`) — Padding of the item. Its private default follows `size` across the shared six-step ladder; an inherited or direct public value wins.\n- `--lr-toast-show-duration` (default: `var(--lr-transition-base, 180ms ease-out)`) — Opacity/transform transition used while showing.\n- `--padding` — Mapped alias for `--lr-toast-padding`.\n- `--show-duration` — Mapped alias for `--lr-toast-show-duration`.","attributes":[{"name":"duration","description":"Auto-dismiss delay in ms. Set to `Infinity` (or <= 0) to disable.\n\nType: `number`  \nDefault: `5000`","value":{"type":["number"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"size","description":"Visual size. Valid upstream `small`/`medium`/`large` values round-trip verbatim while the CSS\nmaps both spellings onto the same rendered ladder.\n\nType: `LyraToastSize`  \nDefault: `'m'`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}},{"name":"variant","description":"Severity/variant.\n\nType: `LyraToastVariant`  \nDefault: `'neutral'`","value":{"type":["'neutral'","'brand'","'success'","'warning'","'danger'"]}},{"name":"with-icon","description":"Show the icon slot.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"","description":"The message content. Visible non-interactive text, including through forwarding slots, stays synchronized with the close button's contextual accessible name."},{"name":"icon","description":"Optional icon shown at the start."}],"js":{"properties":[{"name":"duration","description":"Auto-dismiss delay in ms. Set to `Infinity` (or <= 0) to disable.\n\nAttribute: `duration`","type":"number","default":"5000"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"size","description":"Visual size. Valid upstream `small`/`medium`/`large` values round-trip verbatim while the CSS\nmaps both spellings onto the same rendered ladder.\n\nAttribute: `size`  \nReflected to its attribute.","type":"LyraToastSize","default":"'m'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"toastItemElement","description":"Live visible toast surface, or `null` before the render root is populated.","type":"HTMLElement | null","read-only":true},{"name":"variant","description":"Severity/variant.\n\nAttribute: `variant`  \nReflected to its attribute.","type":"LyraToastVariant","default":"'neutral'"},{"name":"withIcon","description":"Show the icon slot.\n\nAttribute: `with-icon`","type":"boolean","default":"false"}],"events":[{"name":"lr-after-hide","description":"Fired after the hide animation completes (item then removes itself).","type":"CustomEvent<null>"},{"name":"lr-after-show","description":"Fired after the show animation completes.","type":"CustomEvent<null>"},{"name":"lr-hide","description":"The item is about to hide, including an auto-dismiss expiry. Cancelable — `preventDefault()` leaves it visible. A vetoed auto-dismiss restarts the full current normalized duration; a vetoed manual `hide()` leaves any active countdown untouched.","type":"CustomEvent<null>"},{"name":"lr-show","description":"The item is about to show. Cancelable — `preventDefault()` suppresses and releases the toast without starting its auto-dismiss timer.","type":"CustomEvent<null>"}]}},{"name":"lr-token-input","description":"`<lr-token-input>` — an editable, form-associated list of removable tokens.\n\nEnter commits the typed draft into a token while there is one; with the draft empty it performs\nthe implicit form submission a native text field would (see `internal/submit-on-enter.ts` — the\ninternal input is in a shadow root and has no form owner, so the platform can never do it here).\nA `delimiter` keystroke stays purely a commit key and never submits. Tab commits a nonempty\ndraft without preventing the key, so native focus traversal still advances.\nComposing keyboard events, including legacy key code 229, remain with the draft or inline\neditor without adding, removing, committing or closing tokens.\nHost-root external descriptions precede local hint/error guidance on the native draft input\nand follow live source replacement, removal, reconnection and document adoption.\nRemoving label, hint or error-text safely removes the copy without changing native\nattribute-removal property readback. Editable token labels keep their text vertically centered.\n`select()`, the selection getters/setters, `setSelectionRange()`, and `setRangeText()` expose the\nnative draft input's editing surface. Range edits synchronize the pending draft without\nemitting user events, so a later delimiter/Enter/Tab/blur commit consumes the edited text.\n`focus()` and `click()` are synchronous no-ops under own or fieldset-cascaded disablement,\nincluding the same task that begins the disabled transition before Lit updates the draft input.\nIf a focused token surface disappears through its own remove action or a controlled\n`value`/`defaultValue` shrink, focus moves to the nearest surviving equivalent surface, or to\nthe draft input when no token remains. A newer external focus destination always 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| `end` | Adornment at the inline-end of the token/input row, after the draft input. |\n| `error` | Validation message. |\n| `hint` | Supporting text. |\n| `label` | Visible label content. |\n| `start` | Adornment at the inline-start of the token/input row, before the tokens. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `end` | Wrapper around the `end` adornment slot; `hidden` while nothing is slotted. |\n| `error` | Validation message. |\n| `form-control` | Outer control wrapper. |\n| `form-control-label` | Label. |\n| `hint` | Supporting text. |\n| `input` | Native text input. |\n| `input-wrapper` | Token and input row. |\n| `remove` | Token remove button. |\n| `start` | Wrapper around the `start` adornment slot; `hidden` while nothing is slotted. |\n| `token` | Individual token. |\n| `token-editor` | The inline text field replacing a token's text while it is being edited. Rendered only while `editable` is set and that token is open for editing. |\n| `token-label` | The token's text, as the roving-focus edit trigger. Rendered only while `editable` is set. Effective disablement removes every token label's tabindex, exposes `aria-disabled=\"true\"`, and retires internal focus; re-enabling restores one roving stop. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-form-control-focus-shadow` (default: `none`) — The shared field focus halo, painted as a `box-shadow` while this control is focused. One name for every field-shaped control in the library, so a halo is configured once rather than per component. Additive: the focus outline and border cue are the accessibility answer to focus and are never replaced by it.\n- `--lr-form-control-required-color` (default: `var(--lr-color-danger)`) — Required-marker color, themeable independently of error text and invalid borders.\n- `--lr-form-control-required-content` (default: `' *'`) — The required marker appended to `form-control-label` while `required` is set. Set it to `''` to suppress the marker, or to any other quoted string (`' (required)'`, a localized word) to replace it.\n- `--lr-form-control-required-offset` (default: `0`) — Inline space between the label text and the required marker.\n- `--lr-token-input-action-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Edit/remove hover background.\n- `--lr-token-input-border-color` (default: `var(--lr-color-border)`) — Resting border color of the input row. The invalid and focused states keep their own hooks and still win over it.\n- `--lr-token-input-control-height` — Exact input-wrapper height. Unset by default, which leaves `--lr-token-input-control-min-height` as a floor only; set it to a length to both floor and cap the row (e.g. to pixel-match a sibling field in the same toolbar row). An uncapped row grows as tokens wrap; a capped row clips inline overflow and intentionally scrolls in the block axis so wrapped tokens and their hit-area-floored actions remain reachable. Because it is never declared by the component itself, it can be set from an ancestor or an outer-tree rule as well as inline on the element.\n- `--lr-token-input-control-min-height` (default: `var(--lr-form-control-height)`) — Input-wrapper block-size floor. Reads the shared form-control height ladder, so retuning `--lr-theme-form-control-height-*` moves this control and every sibling field together.\n- `--lr-token-input-edit-hover-bg` (default: `var(--lr-token-input-action-hover-bg)`) — Editable token label hover background, independently themeable from the remove action.\n- `--lr-token-input-edit-pressed-bg` — Editable token label pressed background; defaults to an active-state mix of `--lr-token-input-edit-hover-bg`.\n- `--lr-token-input-editor-inline-size` (default: `var(--lr-size-6rem)`) — Inline size of the inline token editor opened by `editable`.\n- `--lr-token-input-fill` (default: `var(--lr-color-surface)`) — Resting background of the input row.\n- `--lr-token-input-focus-border-color` (default: `var(--lr-color-brand)`) — Focused row border color.\n- `--lr-token-input-font-size` — Input-wrapper/token font size, scaled by `size`.\n- `--lr-token-input-gap` (default: `var(--lr-space-xs)`) — Gap between form/row children.\n- `--lr-token-input-input-inline-size` (default: `var(--lr-size-8rem)`) — `flex-basis` of the native text input within the token row.\n- `--lr-token-input-invalid-border-color` (default: `var(--lr-color-danger)`) — Invalid row border color.\n- `--lr-token-input-min-input-inline-size` (default: `var(--lr-size-4rem)`) — Inline-size floor of the native text input, so it stays usable once tokens wrap.\n- `--lr-token-input-padding` — Input-wrapper padding, scaled by `size`.\n- `--lr-token-input-radius` (default: `var(--lr-radius)`) — Row/token corner radius. `pill` changes its private default to `--lr-radius-pill`; an inherited or direct public value still wins.\n- `--lr-token-input-remove-hover-bg` (default: `var(--lr-token-input-action-hover-bg)`) — Remove action hover background, independently themeable from the editable label.\n- `--lr-token-input-remove-pressed-bg` — Remove action pressed background; defaults to an active-state mix of `--lr-token-input-remove-hover-bg`.\n- `--lr-token-input-token-bg` (default: `var(--lr-color-brand-quiet)`) — Token chip background.\n- `--lr-token-input-token-gap` (default: `var(--lr-space-2xs)`) — Gap inside token chips.\n- `--lr-token-input-token-padding` — Per-token chip padding, scaled by `size`.","attributes":[{"name":"allow-duplicates","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"aria-label","description":"Accessible-name override forwarded to the input wrapper and draft input. Attribute presence\nwins, including an explicitly empty `aria-label`, which suppresses visible-label linkage.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"autocapitalize","description":"Forwarded to both native text inputs. Empty preserves the browser default.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"autocorrect","description":"Native editing-assistance state forwarded to both text inputs. Reads are boolean; writes\naccept booleans and the native/Shoelace string vocabulary (`off`/`false` disable it).\n\nType: `boolean`","value":{"type":["boolean"]}},{"name":"custom-error","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nType: `string | null`"},{"name":"delimiter","description":"Character(s) that split a typed draft into several tokens, and (when a single character) the\nkeystroke that commits the draft. `null` — from the property, or from `delimiter=\"none\"` /\n`delimiter=\"\"` — disables both, so a token may contain the delimiter verbatim. Defaults to `,`.\n\nType: `string | null`  \nDefault: `','`"},{"name":"disabled","description":"Type: `boolean`","value":{"type":["boolean"]}},{"name":"editable","description":"Type: `boolean`","value":{"type":["boolean"]}},{"name":"error-text","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"form","description":"Type: `HTMLFormElement | string | null`  \nDefault: `null`"},{"name":"hint","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"label","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"name","description":"The form submission key, reflected synchronously for native form APIs.\nThis control keys its `FormData` entries directly off `name` (see\n`syncValidity()`), so a rename must rebuild that `FormData` in the same\ntick -- mirrors `<lr-combobox>`'s identical `name` setter.\n\nType: `string`","value":{"type":["string"]}},{"name":"pill","description":"Rounds the token row's corners to a full pill, mirroring `lr-input`'s own `pill`. It is a\nsingle override of `--lr-token-input-radius`, which the tokens share with the row, so the\nchips round with it.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"placeholder","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"required","description":"Type: `boolean`","value":{"type":["boolean"]}},{"name":"size","description":"Visual size — the library-wide `2xs`–`xl` ladder shared with `lr-input`. The Web Awesome /\nShoelace spellings `small`/`medium`/`large` are accepted for `s`/`m`/`l`, so a migration is a\ntag rename with no attribute rewrite.\n\nType: `LyraSize`  \nDefault: `'m'`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}},{"name":"spellcheck","description":"Forwarded to both native text inputs using the native explicit `\"true\"`/`\"false\"`\nattribute vocabulary.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"value","description":"Reflected JSON-array reset default; changing it never overwrites a dirty live token list.\n\nType: `readonly string[]`"}],"slots":[{"name":"end","description":"Adornment at the inline-end of the token/input row, after the draft input."},{"name":"error","description":"Validation message."},{"name":"hint","description":"Supporting text."},{"name":"label","description":"Visible label content."},{"name":"start","description":"Adornment at the inline-start of the token/input row, before the tokens."}],"js":{"properties":[{"name":"accessibleLabel","description":"Accessible-name override forwarded to the input wrapper and draft input. Attribute presence\nwins, including an explicitly empty `aria-label`, which suppresses visible-label linkage.\n\nAttribute: `aria-label`","type":"string","default":"''"},{"name":"allowDuplicates","description":"Attribute: `allow-duplicates`","type":"boolean","default":"false"},{"name":"autocapitalize","description":"Forwarded to both native text inputs. Empty preserves the browser default.\n\nAttribute: `autocapitalize`","type":"string","default":"''"},{"name":"autocorrect","description":"Native editing-assistance state forwarded to both text inputs. Reads are boolean; writes\naccept booleans and the native/Shoelace string vocabulary (`off`/`false` disable it).\n\nAttribute: `autocorrect`","type":"boolean"},{"name":"customError","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nAttribute: `custom-error`  \nReflected to its attribute.","type":"string | null"},{"name":"defaultValue","description":"Reflected JSON-array reset default; changing it never overwrites a dirty live token list.\n\nAttribute: `value`  \nReflected to its attribute.","type":"readonly string[]"},{"name":"delimiter","description":"Character(s) that split a typed draft into several tokens, and (when a single character) the\nkeystroke that commits the draft. `null` — from the property, or from `delimiter=\"none\"` /\n`delimiter=\"\"` — disables both, so a token may contain the delimiter verbatim. Defaults to `,`.\n\nAttribute: `delimiter`","type":"string | null","default":"','"},{"name":"disabled","description":"Attribute: `disabled`  \nReflected to its attribute.","type":"boolean"},{"name":"editable","description":"Attribute: `editable`  \nReflected to its attribute.","type":"boolean"},{"name":"effectiveDisabled","description":"Effective disabled state: this element's own `disabled` OR an ancestor\n`<fieldset disabled>`'s inherited state -- mirrors native `<input>`, whose\nown `disabled` IDL property/attribute is never mutated by a fieldset.","type":"boolean","read-only":true},{"name":"errorText","description":"Attribute: `error-text`","type":"string","default":"''"},{"name":"form","description":"Attribute: `form`  \nReflected to its attribute.","type":"HTMLFormElement | string | null","default":"null"},{"name":"hint","description":"Attribute: `hint`","type":"string","default":"''"},{"name":"label","description":"Attribute: `label`","type":"string","default":"''"},{"name":"labels","type":"NodeList","read-only":true},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"name","description":"The form submission key, reflected synchronously for native form APIs.\nThis control keys its `FormData` entries directly off `name` (see\n`syncValidity()`), so a rename must rebuild that `FormData` in the same\ntick -- mirrors `<lr-combobox>`'s identical `name` setter.\n\nAttribute: `name`  \nReflected to its attribute.","type":"string"},{"name":"pill","description":"Rounds the token row's corners to a full pill, mirroring `lr-input`'s own `pill`. It is a\nsingle override of `--lr-token-input-radius`, which the tokens share with the row, so the\nchips round with it.\n\nAttribute: `pill`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"placeholder","description":"Attribute: `placeholder`","type":"string","default":"''"},{"name":"required","description":"Attribute: `required`  \nReflected to its attribute.","type":"boolean"},{"name":"selectionDirection","description":"Native draft selection direction, or `null` before the internal input renders.","type":"HTMLInputElement['selectionDirection']"},{"name":"selectionEnd","description":"Native draft selection end, or `null` before the internal input renders.","type":"number | null"},{"name":"selectionStart","description":"Native draft selection start, or `null` before the internal input renders.","type":"number | null"},{"name":"size","description":"Visual size — the library-wide `2xs`–`xl` ladder shared with `lr-input`. The Web Awesome /\nShoelace spellings `small`/`medium`/`large` are accepted for `s`/`m`/`l`, so a migration is a\ntag rename with no attribute rewrite.\n\nAttribute: `size`  \nReflected to its attribute.","type":"LyraSize","default":"'m'"},{"name":"spellcheck","description":"Forwarded to both native text inputs using the native explicit `\"true\"`/`\"false\"`\nattribute vocabulary.\n\nAttribute: `spellcheck`","type":"boolean","default":"true"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"validationMessage","type":"string","read-only":true},{"name":"validity","type":"ValidityState","read-only":true},{"name":"value","type":"readonly string[]"},{"name":"willValidate","type":"boolean","read-only":true}],"events":[{"name":"blur","description":"Native `FocusEvent` relayed from the draft input or inline token editor.","type":"FocusEvent"},{"name":"change","description":"Native commit `Event` emitted with `input`.","type":"Event"},{"name":"focus","description":"Native `FocusEvent` relayed from the draft input or inline token editor.","type":"FocusEvent"},{"name":"input","description":"Native `InputEvent` emitted after a user changes the token list.","type":"InputEvent"},{"name":"lr-add","description":"One or more tokens are about to be added in a single commit. Detail is `{ value, values }`, where `value` is the final added token for compatibility and `values` is the complete ordered batch. Cancelable -- call `preventDefault()` to veto the add (e.g. a server-side validation check) and the tokens stay out of `value`; the typed draft text is left in the input unchanged so the user can correct it, rather than being silently cleared.","type":"CustomEvent<Readonly<{ value: string; values: readonly string[] }>>"},{"name":"lr-change","description":"Lyra commit alias; detail is `{ value }` with the current token list.","type":"CustomEvent<Readonly<{ value: readonly string[] }>>"},{"name":"lr-input","description":"Lyra input alias; detail is `{ value }` with the current token list.","type":"CustomEvent<Readonly<{ value: readonly string[] }>>"},{"name":"lr-invalid","description":"The token list failed a validity check. Cancelable: calling `preventDefault()` also cancels the native `invalid` event behind it, suppressing the browser's own validation bubble so an app can present the failure its own way.","type":"CustomEvent<null>"},{"name":"lr-remove","description":"A token is about to be removed; detail is `{ value, index }`. Cancelable -- call `preventDefault()` to veto the removal (e.g. pending an async confirmation or a protected-token check) and the token stays in `value` unchanged.","type":"CustomEvent<{ value: string; index: number }>"},{"name":"lr-token-edit","description":"An existing token is about to be edited in place; detail is `{ value, previousValue, index }`. Not emitted for a reverted, unchanged, emptied, or duplicate-colliding edit -- those close the editor with no event. Cancelable -- call `preventDefault()` to veto the edit and the token stays in `value` unchanged; the inline editor stays open with the user's edited text intact so they can correct it, rather than closing and discarding it.","type":"CustomEvent<{\n    value: string;\n    previousValue: string;\n    index: number;\n  }>"}]}},{"name":"lr-tool-approval-dialog","description":"`<lr-tool-approval-dialog>` — a human-in-the-loop gate: presents one\nproposed tool/function call (`toolName` + `args`) and blocks an agent from\nexecuting it until a person explicitly approves or denies it, with an\noptional inline \"edit the arguments before approving\" step.\n\nThis renders its own dialog panel rather than nesting a `<lr-dialog>` in\nits shadow template. Shared overlay infrastructure coordinates stacking,\nfocus trapping, Escape dismissal, optional backdrop dismissal, and focus\nreturn with every other overlay in the same document.\n\nApprove/Deny/Edit are built-in chrome (not a `footer` slot a consumer must\nassemble) — this component's interaction shape is fixed enough (there is\nexactly one correct set of actions for \"approve this call\") that requiring\nevery consumer to re-build it would just be boilerplate. A `footer` slot is\nstill offered for *supplementary* content a consumer wants alongside those\nbuttons (e.g. a \"remember this choice for this tool\" checkbox) — its\ncontent renders to the start of the action row, before Deny/Edit/Approve.\n\nEditing: while `editable`, an Edit button swaps the read-only\n`<lr-json-viewer>` for a plain `<textarea>` pre-filled with\n`JSON.stringify(args, null, 2)`. Every keystroke is re-validated with\n`JSON.parse` — the Approve button is `disabled` for as long as the current\ntextarea content fails to parse, so a malformed edit can never be silently\napproved as either the broken text or a stale copy of the original args.\nThe editor defaults to `spellcheck=\"false\"`, `autocapitalize=\"off\"`,\n`autocorrect=\"off\"`, and `autocomplete=\"off\"` because its content is raw\nJSON, never prose. The corresponding native editing properties remain\nconfigurable for integrations that need different browser behavior.\nThe raw-JSON editor deliberately fixes native `resize` to `vertical`: a\nuser can make a long draft taller without changing the dialog's constrained\ninline size. This focused approval flow exposes neither a generic `resize`\nsurface nor auto-grow behavior; consumers that need either compose a\ndedicated editor around their approval UI.\nThe same button relabels to \"Cancel\" while editing; clicking it discards\nthe draft entirely and returns to the read-only view of the *original*\n`args` — there is no separate \"save\" step independent of Approve itself.\nBoth `editing` and any in-progress draft reset back to the read-only view\nevery time the dialog transitions from closed to open or its open proposal (`proposalKey`,\n`toolName`, or `args`) changes, so a reused instance never leaks one proposal's half-finished\nedit into the next.\n`editable` flipping to `false` mid-edit does the same (see `willUpdate()`)\nand, if the textarea it unmounts still held focus, `updated()` refocuses\nDeny so the focus trap keeps engaging instead of silently letting focus\nfall through to the document.\n\nInitial focus deliberately does *not* land on Approve:\napproving a tool call is a consequential, potentially irreversible action,\nso a user who opens this dialog and reflexively presses Enter/Space before\nreading anything should deny, not approve. Deny gets the initial focus\ninstead — the same \"focus the safe action\" convention a native destructive-\nconfirmation dialog (delete, discard, etc.) typically follows for its own\nCancel button — rather than the inert dialog panel, which would need an\nextra Tab press before *any* action is reachable at all.\n\nDeny/Approve are `<lr-button>`s. Deny is `variant=\"neutral\" appearance=\"outlined\"`, Approve is\n`variant=\"brand\"` at lr-button's default `appearance=\"accent\"`, so the primary action is the loud\none and the safe action recedes. Both appearances are stated rather than inherited: a dialog whose\nlook depends on another component's default changes silently when that default does. Both are\ncomposed children rendered by this component (which offers no `variant` knob of its own, unlike\n`<lr-confirm-bar>`), each re-exporting `lr-button`'s own `base`/`label`/`start`/\n`end`/`spinner` parts under `{deny,approve}-button-{base,label,start,end,spinner}`. An\n`lr-approve`/`lr-deny` listener can call `preventDefault()` to keep the decision open while its\nown async work (e.g. a network call) is in flight: `pending` is set to `'approve'`/`'deny'`,\nshowing `loading` on that button and `disabled` on the other (and, for Approve, alongside the\nexisting invalid-JSON `disabled` gate), until the host finalizes by calling\n`close('approve'|'deny')` or bounces back by clearing `.pending` to `null`. A listener that\ninstead resolves the decision itself synchronously (calling `close('approve'|'deny')` or setting\n`.pending` directly before returning from the `preventDefault()`ed handler) wins outright:\n`onApprove`/`onDeny` only fall back to their own `pending` bookkeeping when the listener left both\n`pending` and `open` untouched. While `pending` is\nset, Escape and an enabled backdrop dismissal are suppressed -- a decision in flight should not\nbe abandonable out from under the host mid-request -- and `pending` itself resets to `null` every\ntime the dialog transitions from closed to open, mirroring `editing`'s own reset-on-reopen\ncontract.\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| `footer` | Optional supplementary content (e.g. a \"remember this choice\" checkbox), rendered before the built-in Deny/Edit/Approve buttons. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `approve-button` | The built-in Approve `<lr-button>` — `disabled` while an in-progress edit is invalid JSON (or while Deny is pending). |\n| `approve-button-base` | Forwarded from the internal Approve `<lr-button>`'s same-node `base` and `button` wrapper aliases. |\n| `approve-button-end` | Forwarded from the internal Approve `<lr-button>`'s own `end` part. |\n| `approve-button-label` | Forwarded from the internal Approve `<lr-button>`'s own `label` part. |\n| `approve-button-spinner` | Forwarded from the internal Approve `<lr-button>`'s own `spinner` part, present only while `pending` is `'approve'`. |\n| `approve-button-start` | Forwarded from the internal Approve `<lr-button>`'s own `start` part. |\n| `args-editor` | The raw-JSON `<textarea>` shown while editing. |\n| `args-view` | The read-only `<lr-json-viewer>` shown while not editing. |\n| `backdrop` | The full-viewport scrim behind the panel. |\n| `body` | The wrapper around the args view/editor. |\n| `deny-button` | The built-in Deny `<lr-button>`. |\n| `deny-button-base` | Forwarded from the internal Deny `<lr-button>`'s same-node `base` and `button` wrapper aliases. |\n| `deny-button-end` | Forwarded from the internal Deny `<lr-button>`'s own `end` part. |\n| `deny-button-label` | Forwarded from the internal Deny `<lr-button>`'s own `label` part. |\n| `deny-button-spinner` | Forwarded from the internal Deny `<lr-button>`'s own `spinner` part, present only while `pending` is `'deny'`. |\n| `deny-button-start` | Forwarded from the internal Deny `<lr-button>`'s own `start` part. |\n| `edit-button` | The built-in Edit/Cancel toggle button (only rendered while `editable`). |\n| `error` | The inline \"invalid JSON\" message, shown only while editing with unparseable content. |\n| `footer` | The action row wrapping the `footer` slot and the built-in buttons. |\n| `header` | The wrapper around the heading. |\n| `panel` | The dialog panel itself (`role=\"dialog\"` while open). |\n| `tool-name` | The `toolName` text within the heading. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-tool-approval-dialog-hover-border-color` (default: `var(--lr-color-brand)`) — Border color of a valid, editable raw-JSON args editor on hover. Invalid and pending states retain their semantic chrome.\n- `--lr-tool-approval-dialog-invalid-border-color` (default: `var(--lr-color-danger)`) — Border color of an invalid raw-JSON editor.\n- `--lr-tool-approval-dialog-mono-font` (default: `var(--lr-font-mono)`) — Font family for the tool name and the raw-JSON args editor.\n- `--lr-tool-approval-dialog-overlay-color` (default: `var(--lr-color-overlay)`) — Backdrop scrim color.","attributes":[{"name":"aria-label","description":"Accessible name for the component. When assigned directly as a property without a host\nattribute it names the dialog panel; a host `aria-label` remains on the host and the panel\nstays labelled by its visible heading to avoid cloning the same owner.\n\nType: `string | null`  \nDefault: `null`"},{"name":"autocapitalize","description":"Type: `string`  \nDefault: `'off'`","value":{"type":["string"]}},{"name":"autocomplete","description":"Type: `string`  \nDefault: `'off'`","value":{"type":["string"]}},{"name":"autocorrect","description":"Type: `string`  \nDefault: `'off'`","value":{"type":["string"]}},{"name":"editable","description":"Whether an \"Edit\" affordance is offered at all. When `false`, `args` is always shown read-only and can never be changed before approval.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"enterkeyhint","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"inputmode","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"light-dismiss","description":"Dismisses the dialog on a backdrop click. Opt-in and `false` by default, matching\n`<lr-dialog>`, `<lr-drawer>`, `<lr-lightbox>`, and the sibling tool dialogs.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"open","description":"Whether the dialog is open. Set this directly or use `show()`/`hide()`/`close()`.\n\nType: `boolean`","value":{"type":["boolean"]}},{"name":"pending","description":"Which decision is awaiting host resolution, while an lr-approve/lr-deny listener has called\npreventDefault(). Host-writable: set back to null to bounce back to the undecided state (e.g.\non failure, so the user can retry), or call `close('approve'|'deny')` to finalize. Also reset\nto `null` every time the dialog transitions from closed to open, mirroring\n`editing`/`draftText`/`draftError`'s own reset-on-reopen contract below, so a reused instance\nnever leaks one proposal's stuck pending state into the next. While non-null, Escape and an\nenabled backdrop dismissal are suppressed (see `activateOverlay()`).\n\nType: `ToolApprovalDialogPending`","value":{"type":["'approve'","'deny'"]}},{"name":"proposal-key","description":"Stable identity/generation for the proposal. Changing it while open resets draft and pending\nstate even when the replacement proposal happens to reuse the same visible name/arguments.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"spellcheck","description":"Native editing-assistance attributes forwarded to the raw-JSON textarea.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"tool-name","description":"The proposed tool/function's name, e.g. `web_search`. Drives the heading and the dialog's accessible name.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"wrap","description":"Type: `ToolApprovalDialogWrap`  \nDefault: `'soft'`","value":{"type":["'hard'","'soft'","'off'"]}}],"slots":[{"name":"footer","description":"Optional supplementary content (e.g. a \"remember this choice\" checkbox), rendered before the built-in Deny/Edit/Approve buttons."}],"js":{"properties":[{"name":"accessibleLabel","description":"Accessible name for the component. When assigned directly as a property without a host\nattribute it names the dialog panel; a host `aria-label` remains on the host and the panel\nstays labelled by its visible heading to avoid cloning the same owner.\n\nAttribute: `aria-label`","type":"string | null","default":"null"},{"name":"args","description":"The proposed call's arguments — any JSON-serializable value, rendered via `<lr-json-viewer>` (or, while editing, stringified into the textarea).","type":"unknown","default":"{}"},{"name":"autoCorrect","description":"Attribute: `autocorrect`","type":"string","default":"'off'"},{"name":"autocapitalize","description":"Attribute: `autocapitalize`","type":"string","default":"'off'"},{"name":"autocomplete","description":"Attribute: `autocomplete`","type":"string","default":"'off'"},{"name":"editable","description":"Whether an \"Edit\" affordance is offered at all. When `false`, `args` is always shown read-only and can never be changed before approval.\n\nAttribute: `editable`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"enterKeyHint","description":"Attribute: `enterkeyhint`","type":"string","default":"''"},{"name":"inputMode","description":"Attribute: `inputmode`","type":"string","default":"''"},{"name":"lightDismiss","description":"Dismisses the dialog on a backdrop click. Opt-in and `false` by default, matching\n`<lr-dialog>`, `<lr-drawer>`, `<lr-lightbox>`, and the sibling tool dialogs.\n\nAttribute: `light-dismiss`","type":"boolean","default":"false"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"open","description":"Whether the dialog is open. Set this directly or use `show()`/`hide()`/`close()`.\n\nAttribute: `open`  \nReflected to its attribute.","type":"boolean"},{"name":"pending","description":"Which decision is awaiting host resolution, while an lr-approve/lr-deny listener has called\npreventDefault(). Host-writable: set back to null to bounce back to the undecided state (e.g.\non failure, so the user can retry), or call `close('approve'|'deny')` to finalize. Also reset\nto `null` every time the dialog transitions from closed to open, mirroring\n`editing`/`draftText`/`draftError`'s own reset-on-reopen contract below, so a reused instance\nnever leaks one proposal's stuck pending state into the next. While non-null, Escape and an\nenabled backdrop dismissal are suppressed (see `activateOverlay()`).\n\nAttribute: `pending`  \nReflected to its attribute.","type":"ToolApprovalDialogPending"},{"name":"proposalKey","description":"Stable identity/generation for the proposal. Changing it while open resets draft and pending\nstate even when the replacement proposal happens to reuse the same visible name/arguments.\n\nAttribute: `proposal-key`","type":"string","default":"''"},{"name":"spellcheck","description":"Native editing-assistance attributes forwarded to the raw-JSON textarea.\n\nAttribute: `spellcheck`","type":"boolean","default":"false"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"toolName","description":"The proposed tool/function's name, e.g. `web_search`. Drives the heading and the dialog's accessible name.\n\nAttribute: `tool-name`","type":"string","default":"''"},{"name":"wrap","description":"Attribute: `wrap`","type":"ToolApprovalDialogWrap","default":"'soft'"}],"events":[{"name":"blur","description":"Re-dispatched when the raw-JSON editor loses focus.","type":"CustomEvent<null>"},{"name":"focus","description":"Re-dispatched when the raw-JSON editor receives focus.","type":"CustomEvent<null>"},{"name":"lr-approve","description":"The call was approved. `detail: { args }` — the current, already-parsed arguments object: the original `args` prop, or (if an edit was in progress) the user's edited-and-validated version. Cancelable: a listener calling `preventDefault()` sets `pending` to `'approve'` instead of closing. Otherwise always followed by `lr-close` with reason `'approve'`.","type":"CustomEvent<{ args: unknown }>"},{"name":"lr-close","description":"`detail: ToolApprovalDialogCloseReason`. Fired exactly once per dismissal — via Escape, an opted-in backdrop click, the Approve/Deny buttons, or a `close()` call — so there is one consistent \"this dialog is now closed\" signal regardless of which path triggered it.","type":"CustomEvent<ToolApprovalDialogCloseReason>"},{"name":"lr-deny","description":"The call was denied (no detail). Cancelable, same `pending` mechanism as `lr-approve` (`pending` is set to `'deny'`). Otherwise always followed by `lr-close` with reason `'deny'`.","type":"CustomEvent<null>"}]}},{"name":"lr-tool-call-chip","description":"`<lr-tool-call-chip>` — a compact inline pill representing one tool/\nfunction call an agent made mid-conversation, e.g.\n`web_search: Searching web…` with a `running` spinner. It owns no detail\nsurface of its own: clicking (or Enter/Space-activating) it only fires\n`lr-tool-call-chip-select` — a consumer wires that to opening a\n`<lr-tool-result-dialog>` (or anything else) at the call site. Keeping\nthe two decoupled means a chip can be reused wherever a compact call\nsummary is useful, with or without a detail surface behind it.\n\nThe default slot is *not* the chip's visible content — the chip's own\nlabel is always built from `name`/`summary`/`status`/`duration-ms`. It's\nreserved for optional read-only preview content (e.g. the tool's raw\narguments or a short formatted summary) shown in a floating tooltip on hover/focus, positioned\nwith `internal/positioner.js`'s `place()` the same way `<lr-combobox>`\npositions its listbox. No tooltip is shown at all when the slot carries no\ncontent — hovering an empty chip does nothing. Hover and keyboard focus are\ntracked as independent reasons to keep the tooltip open (mirrors\n`<lr-citation-badge>`'s popover), so releasing one modality while the\nother is still active doesn't close it, and the trigger button's\n`aria-describedby` points at the tooltip's id whenever it's open and has\ncontent, so the association reaches assistive tech too. The tooltip is an\nexplicitly noninteractive preview: its flattened subtree is inert, so a\nconsumer must put actions in the detail surface opened from\n`lr-tool-call-chip-select`, not links or controls in this description slot.\n\nThe `icon` slot overrides the built-in per-status glyph entirely via the\nplatform's own slot-fallback-content mechanism (`<slot\nname=\"icon\">${fallback}</slot>` — the same pattern `<lr-stat>`'s\n`caption` slot and `<lr-file-input>`'s default slot already use):\nwhatever is assigned to `slot=\"icon\"` wins; otherwise the `icon` prop is\nrendered as a literal hint (e.g. an emoji); otherwise the built-in glyph\nfor the current `status` is used.\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) | Noninteractive tooltip preview text or formatting, shown on hover/focus. Interactive descendants are inert; put actions in the detail surface opened from `lr-tool-call-chip-select`. Nothing renders when this slot is empty. |\n| `icon` | Overrides the built-in status glyph entirely. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The clickable pill (`<button>`). |\n| `category` | The optional grouping label. |\n| `duration` | The formatted `duration-ms`, when set. |\n| `icon` | Wrapper around the status glyph / `icon` slot. |\n| `label` | Wrapper around `category`, `name` and `summary`. |\n| `meta` | Wrapper around `status-text` and `duration`. |\n| `name` | The tool/function name. |\n| `status-text` | The visible text twin of the status glyph/color — carries the state in text, not just color. |\n| `summary` | The short status text. |\n| `tooltip` | The floating detail popup (only meaningful while open). |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-overlay-border` (default: `var(--lr-color-border)`) — Shared floating-surface edge colour, on the anchored detail tooltip.\n- `--lr-overlay-radius` (default: `var(--lr-radius)`) — Shared floating-surface corner radius, on the anchored detail tooltip.\n- `--lr-overlay-shadow-anchored` (default: `var(--lr-shadow-m)`) — Elevation of the anchored surface.\n- `--lr-overlay-surface` (default: `var(--lr-color-surface-overlay)`) — Shared floating-surface fill, on the anchored detail tooltip.\n- `--lr-positioning-strategy` — Cascading `absolute`/`fixed` override for the detail tooltip's `fixed` default, read from computed style when it is (re)positioned. Set it once on `:root`, a theme, or one clipping ancestor to change every unset tool call chip beneath it; an unrecognized value falls back to `fixed`.\n- `--lr-tool-call-chip-accent` (default: `var(--lr-color-text-quiet)`) — Accent color for the status glyph and text. Its private default follows `status` (`running` → brand, `success` → success, `error` → danger, `denied` → warning); an inherited or direct public override always wins.\n- `--lr-tool-call-chip-bg` (default: `var(--lr-color-surface)`) — Chip background. Its private default follows the same `status` rules using each status's `-quiet` tint; a public override wins.\n- `--lr-tool-call-chip-border` (default: `var(--lr-color-border)`) — Chip border color. Its private default becomes transparent for every non-`pending` status; a public override wins.\n- `--lr-tool-call-chip-spin` (default: `var(--lr-transition-ambient)`) — Running-icon animation duration and timing.\n- `--lr-transition-ambient` (default: `1.8s ease-in-out`) — Pending-icon pulse duration and timing.","attributes":[{"name":"call-id","description":"Unique identifier for this specific invocation — echoed back in `lr-tool-call-chip-select`'s\ndetail so a listener can correlate the click with the call it fired for.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"category","description":"Optional grouping label, e.g. `research`. Removing the attribute clears its displayed text.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"duration-ms","description":"How long the call took, in milliseconds. Omitted from the chip entirely when unset.\n\nType: `number | undefined`"},{"name":"icon","description":"Literal icon hint (e.g. an emoji) used when the `icon` slot is empty — see the class doc's\nicon-precedence note. Ignored once anything is assigned to `slot=\"icon\"`.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"name","description":"The tool/function name, e.g. `web_search`.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"status","description":"The call's current lifecycle state — drives the glyph, color, and\n`status-text`. Invalid runtime values use the pending presentation.\n\nType: `ToolCallStatus`  \nDefault: `'pending'`","value":{"type":["'pending'","'running'","'success'","'error'","'denied'"]}},{"name":"summary","description":"Short human-readable status text, e.g. `Searching web…`. Removing the attribute clears its displayed text.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"slots":[{"name":"","description":"Noninteractive tooltip preview text or formatting, shown on hover/focus. Interactive descendants are inert; put actions in the detail surface opened from `lr-tool-call-chip-select`. Nothing renders when this slot is empty."},{"name":"icon","description":"Overrides the built-in status glyph entirely."}],"js":{"properties":[{"name":"callId","description":"Unique identifier for this specific invocation — echoed back in `lr-tool-call-chip-select`'s\ndetail so a listener can correlate the click with the call it fired for.\n\nAttribute: `call-id`","type":"string","default":"''"},{"name":"category","description":"Optional grouping label, e.g. `research`. Removing the attribute clears its displayed text.\n\nAttribute: `category`","type":"string","default":"''"},{"name":"durationMs","description":"How long the call took, in milliseconds. Omitted from the chip entirely when unset.\n\nAttribute: `duration-ms`","type":"number | undefined"},{"name":"icon","description":"Literal icon hint (e.g. an emoji) used when the `icon` slot is empty — see the class doc's\nicon-precedence note. Ignored once anything is assigned to `slot=\"icon\"`.\n\nAttribute: `icon`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"name","description":"The tool/function name, e.g. `web_search`.\n\nAttribute: `name`","type":"string","default":"''"},{"name":"status","description":"The call's current lifecycle state — drives the glyph, color, and\n`status-text`. Invalid runtime values use the pending presentation.\n\nAttribute: `status`  \nReflected to its attribute.","type":"ToolCallStatus","default":"'pending'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"summary","description":"Short human-readable status text, e.g. `Searching web…`. Removing the attribute clears its displayed text.\n\nAttribute: `summary`","type":"string","default":"''"}],"events":[{"name":"lr-tool-call-chip-select","description":"The chip was activated (click or Enter/Space while focused). `detail: { name, callId }`. The `lr-tool-chip-select` alias this event replaced was removed in 9.0.0.","type":"CustomEvent<ToolChipSelectDetail>"}]}},{"name":"lr-tool-param-form","description":"`<lr-tool-param-form>` — renders one form control per top-level property\nof a JSON Schema object, for ad hoc tool invocation or approval-editing UIs\n(e.g. \"the agent wants to call `create_event(title, attendees, allDay)` —\nlet the user tweak the arguments before running it\").\n\n**Scope limitation (intentional, not accidental):** this renderer only\nunderstands a *flat* object schema — every `properties` entry must be\n`'string'`, `'number'`, `'integer'`, `'boolean'`, or a string `enum`;\nprimitive `const` is also enforced. Nested objects, arrays,\n`oneOf`/`anyOf`/`allOf`, `$ref`, constraints such as `minLength`/`minimum`,\nand schema-valued `additionalProperties` are not read. A full\nJSON-Schema-to-form renderer is\nout of scope for this component; a property whose `type` isn't one of the\nfour above renders a visible \"Unsupported field type\" note and marks the\nform invalid instead of silently dropping it or throwing.\nA schema is additionally bounded to 100 fields and 500 enum choices per field. Exceeding either\nceiling fails the form closed with a localized form-wide error while the bounded prefix remains\navailable for inspection; malformed null/array property definitions fail as schema errors rather\nthan being misreported as value-serialization failures.\n\nFields render in `Object.keys(schema.properties)` order (insertion order,\nwhich is reliable for a plain object's string keys). A field's label is\n`title ?? ` the property key; `description` renders as helper text below\nthe control; a key listed in `required` gets a visible `*`. The outer component owns validation\nbecause JSON Schema `required` means property presence, unlike HTML controls' nonempty/must-check\nsemantics. Boolean fields therefore expose explicit unset/true/false values instead of\nconflating an absent property with `false`.\n\nDeliberately no top-level `label`/`hint`/`errorText` chrome (unlike\n`<lr-checkbox-group>`'s own trio, despite both being compound, multi-item\nform controls): every field already carries its own per-field\n`label`/`description`/`error` parts above, and this whole control is\nmeant to be composed inside a consumer's own dialog/section (e.g. \"Approve\n`create_event` call?\") that already supplies the surrounding heading and\ncontext — a second, redundant outer label here would just repeat it. A\nform-wide validation summary is still available via the `error` part\n(`class=\"form-error\"`), driven by `reportValidity()`.\nThe `base` wrapper is always the accessible `role=\"group\"`, so a native external `<label for>`\npointing at this form-associated host can name it via the external-label bridge. A host\n`aria-label` wins by attribute presence (including an explicitly empty value), forwarded onto\nthat same `base` wrapper — matching `<lr-rubric-form>`'s identical pattern. Every generated field\nretains its own more specific name either way.\n\nThis component owns no Submit/Cancel/Approve chrome — a consumer composes\nit inside their own dialog (e.g. a tool-approval dialog) and reads\n`.value`/`.errors`/`checkValidity()` (or calls `reportValidity()` right\nbefore acting, which also reveals any inline errors that user interaction\nhasn't surfaced yet).\n\n`value` is exactly what the consumer last set it to — a field with no\nentry in `value` but a schema `default` displays (and is *emitted*, via\n`lr-input`) as that default, but the `value` *property* itself is left\nalone until the user actually edits that field. This mirrors an\nuncontrolled `<input placeholder>` not writing to `.value`, and means the\nvery first `lr-input` a consumer receives already carries every default\nresolved, so round-tripping `e.detail.value` back into `.value` converges\nafter one edit. JSON Schema defines `default` as an annotation; this form\nrenderer deliberately materializes it before validation and submission,\nso a valid default can satisfy `required` here.\n\nOptional native `<form>` participation is implemented via `ElementInternals`\nattached directly (this component's value is a whole object, not a plain\nstring, so the `FormAssociated` string-value mixin doesn't fit — same\nshape as `<lr-combobox>`'s array-valued case). This is a nice-to-have\nlayered on top of the primary integration contract (`value` +\n`lr-input`/`lr-validity-change`), not a requirement: a consumer that\nnever puts this inside a `<form>` loses nothing.\nThe value present on first connection is cloned as the native default.\n`form.reset()` restores a fresh clone of that default, clears touched and\ninteraction state, and preserves any consumer-set custom validity message,\nmatching native controls' separation between reset state and custom errors.\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 outer wrapper around all fields. |\n| `control` | The native `<input>` for a `'string'` (non-enum) field, or the composed `<lr-number-input>` for a `'number'`/`'integer'` field (its own increment/decrement steppers replace the field type's native spin buttons — see `<lr-number-input>`'s own docs for its further-forwarded parts). Not present on the `'boolean'`/enum (`<lr-select>`) or unsupported-type fallback branches. |\n| `description` | A field's helper text, from `schema.description`. |\n| `empty` | The message shown when `schema.properties` has no entries. |\n| `error` | A field-level or form-level validation message. |\n| `field` | One property's wrapper (label + control + description + error). |\n| `label` | A field's label. |\n| `unsupported` | The fallback note rendered in place of a control for a property whose `type` is outside this renderer's scope. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-form-control-required-color` (default: `var(--lr-color-danger)`) — Color of that marker, retunable without touching any other danger-coloured surface.\n- `--lr-form-control-required-content` (default: `' *'`) — The required-field marker rendered after the `label` part of every field whose key is listed in the schema's `required` array — per field here, not per host, because this control's value is a whole object. Set it to `''` to suppress the marker, or to any other quoted string (`' (required)'`, a localized word) to replace it. Caller-supplied content, so it is never localized here.\n- `--lr-form-control-required-offset` (default: `0`) — Inline space between the label text and the marker.\n- `--lr-tool-param-form-invalid-border-color` (default: `var(--lr-color-danger)`) — Border color of an invalid generated native text or number input.","attributes":[{"name":"custom-error","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nType: `string | null`"},{"name":"disabled","description":"Type: `boolean`","value":{"type":["boolean"]}},{"name":"form","description":"Type: `HTMLFormElement | string | null`  \nDefault: `null`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"name","description":"Submission key for the optional native `<form>` participation, reflected synchronously.\n\nType: `string`","value":{"type":["string"]}}],"js":{"properties":[{"name":"customError","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nAttribute: `custom-error`  \nReflected to its attribute.","type":"string | null"},{"name":"disabled","description":"Attribute: `disabled`  \nReflected to its attribute.","type":"boolean"},{"name":"effectiveDisabled","description":"Whether the form is disabled explicitly or by an ancestor fieldset.","type":"boolean","read-only":true},{"name":"effectiveValue","description":"`value`, with any property missing from it filled in from `schema`'s own `default` — see the class doc.","type":"ToolParamFormValue","read-only":true},{"name":"errors","description":"The current effective validation errors. Intrinsic errors are keyed by their property;\na whole-control or caller-supplied custom error is keyed by the `base` part.","type":"Readonly<Record<string, string>>","read-only":true},{"name":"form","description":"Attribute: `form`  \nReflected to its attribute.","type":"HTMLFormElement | string | null","default":"null"},{"name":"formError","description":"A schema-wide or JSON-serialization error that cannot be assigned to one field.","type":"string","read-only":true},{"name":"labels","type":"NodeList","read-only":true},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"name","description":"Submission key for the optional native `<form>` participation, reflected synchronously.\n\nAttribute: `name`  \nReflected to its attribute.","type":"string"},{"name":"schema","description":"Detached, deeply frozen schema snapshot. At most 100 fields, 100 required keys, and 500 enum\nchoices per field are retained. Oversized assignments remain invalid until replaced; reassign\nthe schema after changing it.","type":"FlatToolParamSchema"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"validationMessage","type":"string","read-only":true},{"name":"validity","type":"ValidityState","read-only":true},{"name":"value","description":"Detached, deeply frozen argument snapshot, bounded to 10,000 entries per array/plain record,\n50,000 total nodes, and 16 nested levels. Reassign after changing it.","type":"ToolParamFormValue"},{"name":"willValidate","type":"boolean","read-only":true}],"events":[{"name":"blur","description":"Re-dispatched when a generated native `'string'` text input loses focus.","type":"CustomEvent<null>"},{"name":"focus","description":"Re-dispatched when a generated native `'string'` text input receives focus. Composed controls (`<lr-select>`, `<lr-number-input>`) already expose their own bubbling, composed bridge.","type":"CustomEvent<null>"},{"name":"lr-input","description":"A field's value changed. `detail: { value }` — the full current value object (every property, defaults resolved), not just the field that changed.","type":"CustomEvent<LyraEventDetailSnapshot<{ readonly value: ToolParamFormValue }>>"},{"name":"lr-invalid","description":"The complete parameter form failed a validity check. Cancelable; preventing it also prevents the native `invalid` event's default validation UI.","type":"CustomEvent<null>"},{"name":"lr-validity-change","description":"Effective native validity or errors changed. The frozen `detail: { valid, errors }` includes custom errors and own/fieldset validation barring.","type":"CustomEvent<LyraEventDetailSnapshot<{\n    readonly valid: boolean;\n    readonly errors: Readonly<Record<string, string>>;\n  }>>"}]}},{"name":"lr-tool-result-dialog","description":"`<lr-tool-result-dialog>` — a full tool-call detail overlay: a status/\nduration header plus a `body` slot where a consumer typically places a\n`<lr-tab-group>` with Input/Preview/JSON/Raw panels. This component knows\nnothing about what's inside that slot — it only supplies the modal chrome\naround it.\n\nThis is its own standalone overlay implementation (`role=\"dialog\"`,\nfocus-trapped, Escape-dismissible, optionally backdrop-dismissible, scroll-locking) rather than\nnesting a `<lr-dialog>` in its shadow template — see `<lr-dialog>`'s\nown header comment for why a new overlay component in this library\nduplicates that pattern locally instead of composing the previous one:\nslot-forwarding into a nested `<lr-dialog>` would put a forwarding\n`<slot>` where a light-DOM-scanning descendant (e.g. a slotted\n`<lr-tab-group>`'s own `Array.from(this.children)` scan) expects real\nprojected content.\n\n`maximized` toggles between a constrained modal size and a near-fullscreen\nsize within the same open dialog and open/close lifecycle — unlike\n`<lr-widget>`'s fullscreen mode, there's no non-modal resting state to\nreturn to, so no separate scroll-lock/focus-trap bookkeeping is needed for\nthe transition itself.\n\nStacking: opening more than one of these dialogs at once is supported --\nEscape and the Tab focus trap only ever act on the topmost open instance,\nso instances beneath it stay open and untouched until the one on top closes.\nThe header also remains usable in narrow allocations: long localized status\nlabels wrap within their badge while the maximize and close actions move to\na reachable row instead of forcing the panel wider.\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| `body` | The dialog's main content — typically a `<lr-tab-group>` with Input/Preview/JSON/Raw panels, entirely consumer-assembled. |\n| `footer` | Optional action buttons, rendered in a bottom row. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `backdrop` | The full-viewport scrim behind the panel. |\n| `body` | The wrapper around the `body` slot. |\n| `close-button` | The built-in close button. |\n| `duration` | The formatted `duration-ms` text. |\n| `footer` | The wrapper around the `footer` slot. |\n| `header` | The row containing the tool name, status, duration, and toggle/close buttons. |\n| `header-actions` | The wrapper around the maximize and close buttons. |\n| `maximize-button` | The built-in maximize/restore toggle button. |\n| `panel` | The dialog panel itself (`role=\"dialog\"` while open). |\n| `status` | The status badge (icon + text). |\n| `title` | The wrapper around the tool name, status, and duration. |\n| `tool-name` | The `tool-name` text. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-tool-result-dialog-denied-bg` (default: `var(--lr-color-warning-quiet)`) — Denied status background.\n- `--lr-tool-result-dialog-denied-color` (default: `var(--lr-color-warning)`) — Denied status foreground.\n- `--lr-tool-result-dialog-error-bg` (default: `var(--lr-color-danger-quiet)`) — Error status background.\n- `--lr-tool-result-dialog-error-color` (default: `var(--lr-color-danger)`) — Error status foreground.\n- `--lr-tool-result-dialog-maximized-inset` — Insets for the maximized panel.\n- `--lr-tool-result-dialog-overlay-color` (default: `var(--lr-color-overlay)`) — Backdrop color.\n- `--lr-tool-result-dialog-pending-bg` (default: `transparent`) — Pending status background.\n- `--lr-tool-result-dialog-pending-color` (default: `var(--lr-color-text-quiet)`) — Pending status foreground.\n- `--lr-tool-result-dialog-running-bg` (default: `var(--lr-color-brand-quiet)`) — Running status background.\n- `--lr-tool-result-dialog-running-color` (default: `var(--lr-color-brand)`) — Running status foreground.\n- `--lr-tool-result-dialog-spin` (default: `var(--lr-transition-ambient)`) — Running-status animation duration and timing.\n- `--lr-tool-result-dialog-success-bg` (default: `var(--lr-color-success-quiet)`) — Success status background.\n- `--lr-tool-result-dialog-success-color` (default: `var(--lr-color-success)`) — Success status foreground.","attributes":[{"name":"aria-label","description":"Accessible name for the component. When assigned directly as a property without a host\nattribute it names the internal dialog; a host `aria-label` remains on the host and the\ninternal dialog stays labelled by its visible tool name to avoid cloning the same owner.\n\nType: `string | null`  \nDefault: `null`"},{"name":"duration-ms","description":"How long the call took, in milliseconds. Omitted from the header entirely when unset.\n\nType: `number | undefined`"},{"name":"light-dismiss","description":"Dismisses the dialog on a backdrop click. Opt-in and `false` by default, matching\n`<lr-dialog>`, `<lr-drawer>`, and `<lr-lightbox>`.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"maximized","description":"Near-fullscreen presentation of the same open dialog.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"open","description":"Whether the dialog is open. Set this directly or use `show()`/`hide()`/`close()`. Each path\nrestores focus to the trigger element identically; reasoned closing additionally fires\n`lr-close`, since a direct assignment carries no reason string\nto attach to that event.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"status","description":"The tool call's current lifecycle state — drives the header's status\nbadge. An out-of-union value (e.g. a stray `status` attribute, or a\ndirect property assignment from an untyped caller) is treated as\n`'pending'` rather than crashing render.\n\nType: `ToolResultStatus`  \nDefault: `'pending'`","value":{"type":["'pending'","'running'","'success'","'error'","'denied'"]}},{"name":"tool-name","description":"The tool's name, rendered prominently in the header.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"slots":[{"name":"body","description":"The dialog's main content — typically a `<lr-tab-group>` with Input/Preview/JSON/Raw panels, entirely consumer-assembled."},{"name":"footer","description":"Optional action buttons, rendered in a bottom row."}],"js":{"properties":[{"name":"accessibleLabel","description":"Accessible name for the component. When assigned directly as a property without a host\nattribute it names the internal dialog; a host `aria-label` remains on the host and the\ninternal dialog stays labelled by its visible tool name to avoid cloning the same owner.\n\nAttribute: `aria-label`","type":"string | null","default":"null"},{"name":"durationMs","description":"How long the call took, in milliseconds. Omitted from the header entirely when unset.\n\nAttribute: `duration-ms`","type":"number | undefined"},{"name":"lightDismiss","description":"Dismisses the dialog on a backdrop click. Opt-in and `false` by default, matching\n`<lr-dialog>`, `<lr-drawer>`, and `<lr-lightbox>`.\n\nAttribute: `light-dismiss`","type":"boolean","default":"false"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"maximized","description":"Near-fullscreen presentation of the same open dialog.\n\nAttribute: `maximized`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"open","description":"Whether the dialog is open. Set this directly or use `show()`/`hide()`/`close()`. Each path\nrestores focus to the trigger element identically; reasoned closing additionally fires\n`lr-close`, since a direct assignment carries no reason string\nto attach to that event.\n\nAttribute: `open`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"status","description":"The tool call's current lifecycle state — drives the header's status\nbadge. An out-of-union value (e.g. a stray `status` attribute, or a\ndirect property assignment from an untyped caller) is treated as\n`'pending'` rather than crashing render.\n\nAttribute: `status`  \nReflected to its attribute.","type":"ToolResultStatus","default":"'pending'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"toolName","description":"The tool's name, rendered prominently in the header.\n\nAttribute: `tool-name`","type":"string","default":"''"}],"events":[{"name":"lr-close","description":"`detail: ToolResultDialogCloseReason`. Fired exactly once per dismissal, via Escape, an opted-in backdrop click, the built-in close button, or a `close()` call.","type":"CustomEvent<ToolResultDialogCloseReason>"},{"name":"lr-maximize-change","description":"Cancelable. `detail: { maximized: boolean }` (the would-be new `maximized` state), fired when the header's maximize/restore toggle is clicked, *before* `maximized` itself changes. Calling `preventDefault()` vetoes the toggle and leaves `maximized` unchanged -- e.g. a host persisting a per-user \"prefers maximized\" layout preference can hold the transition until a save round-trip completes.","type":"CustomEvent<{ readonly maximized: boolean }>"}]}},{"name":"lr-tool-result-view","description":"`<lr-tool-result-view>` — renders a tool call's result via whichever\ncustom renderer a host app has registered for it (see `registerToolRenderer()`\nin `registry.ts`), falling back to `<lr-json-viewer>` whenever no\nrenderer matches, a candidate renderer's `matches()` predicate throws during\ndispatch, a renderer's optional `load()` rejects, or its `render()` throws.\nThis component owns none of the actual visual weight of a\npopulated tool result — that's entirely whatever the registered renderer\nreturns; this is just the dispatch + fallback + loading-state shell.\n\nDispatch runs against `registry` when set, otherwise against the\nmodule-level default registry `registerToolRenderer()` writes to — see\n`findToolRenderer()`'s two-step (exact name, then shape-based `matches()`)\nlookup order for the full rule.\n\n`fallback` implements two kinds: `\"json\"` (the default, an unconditional `<lr-json-viewer>`)\nand `\"text\"`, which renders a *string* `result` as preformatted text instead — falling back to\nthe `\"json\"` behavior when `result` isn't a string, so setting `fallback=\"text\"` defensively\nagainst an unpredictable result shape never renders broken output. `copyable` adds a\ncopy-to-clipboard affordance to either fallback kind (forwarded to `<lr-json-viewer>`'s own\n`copyable` for `\"json\"`; a `<lr-copy-button>` alongside the text for `\"text\"`).\n\nA matched renderer's `render()` is also handed a 3rd `context` argument\n(`{ reportStatus }`) it can use to signal a non-throwing outcome (e.g. an application-level\nfailure it still drew a real UI for) — see `ToolRenderContext` in `registry.ts`. This is purely\nadditive: a pre-existing 2-arg `render(result, args)` function stays assignable unchanged, and a\nrenderer that never calls `reportStatus` leaves `status` at its default, `'success'`.\n\nAssigning `registry` synchronously copies at most 10,000 entries into a frozen readonly facade.\nLater `set()`/`delete()` calls on the source map are not observed; create and assign a new map to\nupdate dispatch. Definition records are cloned and frozen; their callback identities are retained.\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 root wrapper around the resolved renderer's output (or the loading/fallback view). Exposes `aria-busy=\"true\"` while a lazy renderer loads and `\"false\"` otherwise. |\n| `fallback-copy` | The `<lr-copy-button>` shown when `copyable` is set alongside the `fallback=\"text\"` kind (only present when both are set). |\n| `fallback-text` | The `<pre>` element for the `fallback=\"text\"` kind's preformatted result text (only present in that mode). |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-tool-result-view-font` (default: `var(--lr-font-mono)`) — Font family for the `fallback=\"text\"` preformatted output.","attributes":[{"name":"copyable","description":"Shows a copy-to-clipboard affordance alongside the fallback view (both `\"json\"` and `\"text\"` kinds) — forwarded to `<lr-json-viewer>`'s own `copyable`, or renders a `<lr-copy-button>` next to the text fallback.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"fallback","description":"Fallback-kind selector — see the class doc's `fallback` paragraph for the full \"json\" vs \"text\" behavior.\n\nType: `ToolResultFallback`","value":{"type":["'json'","'text'"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"status","description":"The outcome of the currently-rendered result, as reported by the matched renderer's optional\n`context.reportStatus()` third `render()` argument (see `ToolRenderContext` in `registry.ts`).\nReset to `'success'` immediately before every `render()` call, so a renderer that never calls\n`reportStatus` — including every pre-existing 2-arg renderer — leaves it at that default, and a\nlater renderer that stays quiet doesn't inherit a stale outcome from a previous one. Reuses the\nsame vocabulary as `<lr-tool-result-dialog>`'s own `status` property.\n\nType: `ToolResultStatus`  \nDefault: `'success'`","value":{"type":["'pending'","'running'","'success'","'error'","'denied'"]}},{"name":"tool-name","description":"The tool's name — the primary dispatch key (see `findToolRenderer()`).\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"js":{"properties":[{"name":"args","description":"The tool call's original arguments, if available — handed to the matched renderer's `render()` alongside `result`.","type":"unknown"},{"name":"copyable","description":"Shows a copy-to-clipboard affordance alongside the fallback view (both `\"json\"` and `\"text\"` kinds) — forwarded to `<lr-json-viewer>`'s own `copyable`, or renders a `<lr-copy-button>` next to the text fallback.\n\nAttribute: `copyable`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"fallback","description":"Fallback-kind selector — see the class doc's `fallback` paragraph for the full \"json\" vs \"text\" behavior.\n\nAttribute: `fallback`  \nReflected to its attribute.","type":"ToolResultFallback"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"registry","description":"Custom registry to dispatch against instead of the module-level default one (see `registry.ts`).","type":"ToolRendererRegistry | undefined"},{"name":"result","description":"The tool call's result payload, handed to the matched renderer's `render()` (and to `matches()` for shape-based dispatch, and to the `<lr-json-viewer>` fallback).","type":"unknown"},{"name":"status","description":"The outcome of the currently-rendered result, as reported by the matched renderer's optional\n`context.reportStatus()` third `render()` argument (see `ToolRenderContext` in `registry.ts`).\nReset to `'success'` immediately before every `render()` call, so a renderer that never calls\n`reportStatus` — including every pre-existing 2-arg renderer — leaves it at that default, and a\nlater renderer that stays quiet doesn't inherit a stale outcome from a previous one. Reuses the\nsame vocabulary as `<lr-tool-result-dialog>`'s own `status` property.\n\nAttribute: `status`  \nReflected to its attribute.","type":"ToolResultStatus","default":"'success'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"toolName","description":"The tool's name — the primary dispatch key (see `findToolRenderer()`).\n\nAttribute: `tool-name`","type":"string","default":"''"}],"events":[{"name":"lr-render-error","description":"`detail: { toolName, error }` — fired immediately before falling back to `<lr-json-viewer>`, whether because no renderer matched, a candidate renderer's `matches()` predicate threw during dispatch, a renderer's `load()` rejected, or its `render()` threw.","type":"CustomEvent<{ toolName: string; error: unknown }>"}]}},{"name":"lr-tool-select-dialog","description":"`<lr-tool-select-dialog>` — a category-grouped, filterable, searchable\ntool-enablement dialog for picking which agent tools are available in a\nconversation.\n\nThis renders its own dialog panel rather than nesting a `<lr-dialog>` in\nits shadow template. Shared overlay infrastructure coordinates stacking,\nfocus trapping, Escape dismissal, optional backdrop dismissal, and focus\nreturn with every other overlay in the same document.\n\n`useDefaults` is a single top-level switch: while `true`, every per-tool\ncheckbox below renders disabled (still reflecting whatever `selectedToolIds`\nholds — a consumer should populate that with its own default tool set\nwhenever `useDefaults` is true) and a hint explains that turning the\nswitch off is how to customize. Turning it off is the \"customize\"\naffordance — it's the only thing that both flips `useDefaults` to `false`\n*and* unlocks the per-tool checkboxes for editing, so there's exactly one\ncontrol for that transition rather than a separate button duplicating it.\n\nThere is no built-in footer/close button — like `<lr-dialog>`, dismissal\nhappens via Escape, an opted-in `lightDismiss` backdrop click, or a\nconsumer's own `footer`-slotted action calling `close()`. This also means the search input is the very\nfirst focusable element in the panel with no special-casing needed, so\nit's what receives focus on open (see `updated()`).\n\nMatching tools mount in user-driven batches of 200. Matching selected identities reserve batch\npositions before ordinary input-order matches, so the checked rows behind the controlled\n`selectedToolIds` summary remain available without first loading every preceding tool. When more\nmatches remain, a localized limit notice and Load more button make the bounded projection\nexplicit and provide a keyboard-reachable continuation; search can independently narrow the\ncatalog. Both canonical projections inspect at most their first 10,000 input positions. Within\nthat prefix, a repeated tool id's first valid admitted occurrence wins; selected ids retain\ntheir first nonblank occurrence. Selected ids absent from `tools` remain in that canonical\nselection and in `lr-change` proposals, preserving independently managed selection state.\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.\nNative/prefixed input and change events from the composed checkbox and switch controls stop at\nthis dialog's boundary, as do their own `lr-checkbox-toggle-request`/`lr-switch-toggle-request`\nproposals; consumers receive only the aggregate `lr-change` proposal above.\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| `footer` | Optional action buttons (e.g. a \"Done\" button), rendered in a bottom row. Changes already apply live via `lr-change`, so this is optional. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `backdrop` | The full-viewport scrim behind the panel. |\n| `body` | The keyboard-focusable scrollable wrapper around the grouped tool list. |\n| `category` | A single category's wrapper (`role=\"group\"`). |\n| `category-count` | The terse, `aria-hidden` tool count next to a category heading (the heading's accessible name gets the full sentence from an sr-only sibling instead). |\n| `category-heading` | A category's heading. |\n| `category-list` | The `<ul>` of tool rows within a category. |\n| `defaults-hint` | The \"turn off to customize\" hint, shown only while `useDefaults` is true. |\n| `defaults-row` | The wrapper around the use-defaults switch and its hint. |\n| `defaults-toggle` | The built-in `<lr-switch>` bound to `useDefaults`. |\n| `empty` | The \"no tools\" / \"no matches\" message. |\n| `footer` | The wrapper around the `footer` slot. |\n| `header` | The wrapper around the title/subtitle. |\n| `limit` | Localized notice shown while additional matching tools remain unmounted. |\n| `load-more` | Button that mounts the next bounded batch of matching tools. |\n| `panel` | The dialog panel itself (`role=\"dialog\"` while open). |\n| `search-clear` | The clear-search button, replacing the native search-cancel glyph the component resets. Only rendered while the field has text. |\n| `search-input` | The filter text input. |\n| `search-row` | The wrapper around the search input. |\n| `subtitle` | The \"N of M tools enabled\" summary line. |\n| `title` | The dialog's heading. |\n| `tool-checkbox` | A row's `<lr-checkbox>`. |\n| `tool-description` | A row's optional description text. |\n| `tool-disabled-reason` | A disabled row's `disabledReason` text, slotted inside `tool-checkbox` (alongside `tool-name`/`tool-description`) so it contributes to the checkbox's accessible name/description instead of going unannounced. |\n| `tool-icon` | A row's leading icon glyph, when `icon` is set. |\n| `tool-name` | A row's name text (plus its `icon`, if set). |\n| `tool-row` | A single tool's `<li>` row. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-tool-select-dialog-body-hover-outline-color` (default: `var(--lr-color-border)`) — Outline color of the mouse-hover preview on `[part=\"body\"]`. Set to `transparent` to opt out of the hover treatment entirely.\n- `--lr-tool-select-dialog-body-hover-outline-offset` (default: `calc(-1 * var(--lr-border-width-thin))`) — Inward offset of the mouse-hover preview on `[part=\"body\"]`, keeping the outline inside its own scrollport so it is not clipped at the edge.\n- `--lr-tool-select-dialog-body-hover-outline-style` (default: `solid`) — Outline style of the mouse-hover preview on `[part=\"body\"]`.\n- `--lr-tool-select-dialog-body-hover-outline-width` (default: `var(--lr-border-width-thin)`) — Outline width of the mouse-hover preview on `[part=\"body\"]`.\n- `--lr-tool-select-dialog-overlay-color` (default: `var(--lr-color-overlay)`) — Backdrop scrim color.\n- `--lr-tool-select-dialog-search-font-size` (default: `inherit`) — Text size of the search field.\n- `--lr-tool-select-dialog-search-min-height` (default: `auto`) — Minimum row height of the search field, for matching it to a themed search field of a chosen density tier. Point it at `--lr-form-control-height-s` (or any tier of that ladder) to line this field up with the rest of an application's controls.\n- `--lr-tool-select-dialog-search-padding-block` (default: `var(--lr-space-s)`) — Block gutter of the search field.\n- `--lr-tool-select-dialog-search-padding-inline` (default: `var(--lr-space-m)`) — Leading gutter of the search field. The trailing gutter is reserved for the overlaid clear button.\n- `--lr-tool-select-dialog-search-radius` (default: `var(--lr-radius)`) — Corner radius of the search field.","attributes":[{"name":"aria-label","description":"Accessible name for the component. When assigned directly as a property without a host\nattribute it names the dialog panel; a host `aria-label` remains on the host and the panel\nstays labelled by its visible heading to avoid cloning the same owner.\n\nType: `string | null`  \nDefault: `null`"},{"name":"autocapitalize","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"autocomplete","description":"Native editing-assistance and virtual-keyboard hints forwarded to the search input.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"autocorrect","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"enterkeyhint","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"inputmode","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"label","description":"The dialog's visible heading and accessible name. Omission uses the localized default; any\nsupplied string, including `\"Select tools\"` or an empty string, remains literal.\n\nType: `string | undefined`"},{"name":"light-dismiss","description":"Dismisses the dialog on a backdrop click. Opt-in and `false` by default, matching\n`<lr-dialog>`, `<lr-drawer>`, and `<lr-lightbox>`.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"open","description":"Whether the dialog is open. Set this directly or use `show()`/`hide()`/`close()`.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"search-placeholder","description":"Search placeholder. Omission uses the localized default; supplied text remains literal even\nwhen it matches the former English default or is empty. An empty/whitespace-only placeholder\nleaves the field visually empty while its accessible name falls back to the localized default.\n\nType: `string | undefined`"},{"name":"spellcheck","description":"Type: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"use-defaults","description":"Whether the conversation is using the default tool set (`true`) or a custom selection (`false`) — see the class doc for the exact interaction with `selectedToolIds`/per-tool editing.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"footer","description":"Optional action buttons (e.g. a \"Done\" button), rendered in a bottom row. Changes already apply live via `lr-change`, so this is optional."}],"js":{"properties":[{"name":"accessibleLabel","description":"Accessible name for the component. When assigned directly as a property without a host\nattribute it names the dialog panel; a host `aria-label` remains on the host and the panel\nstays labelled by its visible heading to avoid cloning the same owner.\n\nAttribute: `aria-label`","type":"string | null","default":"null"},{"name":"autoCorrect","description":"Attribute: `autocorrect`","type":"string","default":"''"},{"name":"autocapitalize","description":"Attribute: `autocapitalize`","type":"string","default":"''"},{"name":"autocomplete","description":"Native editing-assistance and virtual-keyboard hints forwarded to the search input.\n\nAttribute: `autocomplete`","type":"string","default":"''"},{"name":"enterKeyHint","description":"Attribute: `enterkeyhint`","type":"string","default":"''"},{"name":"filter","description":"Overrides the built-in case-insensitive name/description substring match.","type":"ToolSelectFilter | null","default":"null"},{"name":"inputMode","description":"Attribute: `inputmode`","type":"string","default":"''"},{"name":"label","description":"The dialog's visible heading and accessible name. Omission uses the localized default; any\nsupplied string, including `\"Select tools\"` or an empty string, remains literal.\n\nAttribute: `label`","type":"string | undefined"},{"name":"lightDismiss","description":"Dismisses the dialog on a backdrop click. Opt-in and `false` by default, matching\n`<lr-dialog>`, `<lr-drawer>`, and `<lr-lightbox>`.\n\nAttribute: `light-dismiss`","type":"boolean","default":"false"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"open","description":"Whether the dialog is open. Set this directly or use `show()`/`hide()`/`close()`.\n\nAttribute: `open`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"searchPlaceholder","description":"Search placeholder. Omission uses the localized default; supplied text remains literal even\nwhen it matches the former English default or is empty. An empty/whitespace-only placeholder\nleaves the field visually empty while its accessible name falls back to the localized default.\n\nAttribute: `search-placeholder`","type":"string | undefined"},{"name":"selectedToolIds","description":"The currently-enabled tool ids. The first 10,000 input positions form the canonicalization\nprefix; empty ids are omitted and duplicates are treated as one selection. Ids absent from\n`tools` remain independently selected.","type":"readonly string[]","default":"[]"},{"name":"spellcheck","description":"Attribute: `spellcheck`","type":"boolean","default":"true"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"tools","description":"The full set of tools a consumer offers, across all categories. The first 10,000 input\npositions are inspected; empty ids are omitted and duplicate ids use a deterministic\nfirst-valid-admitted-occurrence projection.","type":"readonly ToolSelectDialogTool[]","default":"[]"},{"name":"useDefaults","description":"Whether the conversation is using the default tool set (`true`) or a custom selection (`false`) — see the class doc for the exact interaction with `selectedToolIds`/per-tool editing.\n\nAttribute: `use-defaults`  \nReflected to its attribute.","type":"boolean","default":"false"}],"events":[{"name":"blur","description":"Re-dispatched when the internal search input loses focus.","type":"CustomEvent<null>"},{"name":"focus","description":"Re-dispatched when the internal search input receives focus.","type":"CustomEvent<null>"},{"name":"lr-change","description":"A proposed enabled-tool selection or `useDefaults` toggle. `detail: { selectedToolIds: string[], useDefaults: boolean }`, with `selectedToolIds` from the canonical first-10,000-input-position selection. Cancelable; preventing it preserves both properties, and the built-in checkbox or switch never flips at all -- the proposal is raised from that control's own `lr-checkbox-toggle-request`/`lr-switch-toggle-request`, before it writes its `checked` state, so a refused change shows no flip-and-snap-back.","type":"CustomEvent<LyraEventDetailSnapshot<ToolSelectionChangeDetail>>"},{"name":"lr-close","description":"`detail: ToolSelectDialogCloseReason`. Fired exactly once per dismissal, via Escape, an opted-in backdrop click, or a `close()` call.","type":"CustomEvent<ToolSelectDialogCloseReason>"}]}},{"name":"lr-tool-timeline","description":"`<lr-tool-timeline>` — a chronological list of an agent run's tool/function calls, each\nrendered through `<lr-tool-call-chip>` (name/status/duration) and `<lr-tool-result-view>`\n(args/result), with per-entry retry counts, sensitive-field redaction, and a shared\n`<lr-tool-approval-dialog>` for entries gated behind a human approval decision. This component\nowns none of the actual per-call rendering -- that is entirely those three existing\nprimitives -- its own job is ordering `entries` chronologically, computing each entry's\nduration from `startedAt`/`endedAt`, masking `redactedFields` before handing `args`/`result` to\n`<lr-tool-result-view>`, and opening/closing the one shared approval dialog for whichever entry\nis currently pending a decision.\n\nOrdering: `entries` is sorted ascending by `startedAt`; an entry with no `startedAt` sorts after\nevery timed entry, keeping its position relative to any other untimed entries stable (input\norder is preserved among ties) — a still-pending call with no timestamp yet naturally lands at\nthe end without needing to be pre-sorted by the host.\nRendering is bounded to 500 unique source entries before sorting. Duplicate `(sourceKey,id)`\nidentities use a deterministic first-wins policy. Entries already open or under approval\nreview are reserved inside that budget when new history would otherwise push them past the\nceiling, and a localized notice exposes truncation instead of silently hiding it. Foreign\nruntime statuses normalize once to `pending` before both row and child presentation.\n\nRedaction work is deferred until a detail row opens and memoized while its payload/path inputs\nremain unchanged. It is bounded to 100 paths, 64 levels, and 10,000 visited nodes; exceeding a\nceiling masks the affected branch rather than exposing data or exhausting the page. Redaction\nonly ever affects the read-only detail view: the copy of `args` handed to the\napproval dialog is always the entry's real, unmasked value. Approving a masked-args call must\nlet the reviewer see (and, if `approvalEditable`, edit) what will actually be sent — handing the\ndialog a placeholder string in place of a real field would silently corrupt the decision.\n\nApproval: activating the chip (`lr-tool-call-chip-select`) of an entry with `needsApproval` and\nan undecided `approved` opens the shared dialog for that entry; approving or denying emits this\ncomponent's own `lr-tool-approval-decide` and closes the dialog. This component never mutates\n`entries` itself — a host applies the decision (and any resulting status change) and re-assigns\n`entries`; if the entry currently under review disappears or no longer qualifies as pending\n(its `approved` was resolved some other way) by the time `entries` changes, the dialog closes on\nits own rather than staying open over stale data. If a host cancels `lr-tool-approval-decide` to\npersist it asynchronously, `pendingApproval` identifies the held action. After success, update\nthe controlled entries and call `finalizePendingApproval()`; after failure, call\n`revertPendingApproval()` to restore the same open dialog and its draft for retry. A host that\ninstead resolves the decision synchronously by reassigning `entries` from within the same\n`preventDefault()`ed listener wins outright: the entry's live state is re-checked immediately\nafter dispatch, so the shared dialog's `pending` flag is never parked on an entry the host already\nfinalized. A chip\nbelonging to an entry that isn't pending approval emits the timeline-owned, correlated\n`lr-tool-activate`; raw child selection and disclosure lifecycle events are contained.\n\nPublic collection properties take bounded readonly snapshots. `entries` retains each source\nobject and its opaque `args`/`result` payloads by identity only while a closed descriptor-safe\nprojection copies the fields this component uses; later rendering never re-reads an admitted\nsource record. Create a new collection and reassign it after changes; mutating the assigned\narray does not update the view.\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| `approval-dialog` | The single shared `<lr-tool-approval-dialog>` instance. |\n| `base` | The root `<ol>`. |\n| `empty` | Localized empty state shown when no entries are available. |\n| `entry` | One entry's `<li>`; carries `data-status` (the entry's `status`) and `data-pending-approval` (`\"true\"`/`\"false\"`). |\n| `entry-approval-status` | The \"Approved\"/\"Denied\" badge, only rendered once `approved` is set; carries `data-decision` (`\"approved\"`/`\"denied\"`). |\n| `entry-body` | Wrapper around one entry's header and details. |\n| `entry-details` | The `<lr-details>` disclosure wrapping the entry's result view. |\n| `entry-error` | The entry's `error` text, only rendered when set. |\n| `entry-header` | Wrapper around the timestamp, chip, retry badge, and approval status. |\n| `entry-marker` | The decorative rail dot/connector for one entry. |\n| `entry-redacted-indicator` | A decorative marker shown when `redactedFields` is non-empty for that entry; the glyph is decorative and localized hidden-state text remains in the accessibility tree. |\n| `entry-result` | The entry's `<lr-tool-result-view>`. |\n| `entry-retries` | The retry-count badge, only rendered while `retryCount > 0`. |\n| `entry-retries-count` | The formatted retry count within the retry badge. |\n| `entry-retries-label` | The localized \"Retry\" text within the retry badge. |\n| `entry-timestamp` | The formatted `startedAt`, only rendered while it's set. |\n| `limit` | Localized resource-ceiling notice. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-tool-timeline-approved-bg` (default: `var(--lr-color-success-quiet)`) — Approved badge background.\n- `--lr-tool-timeline-approved-color` (default: `var(--lr-color-success)`) — Approved badge foreground.\n- `--lr-tool-timeline-denied-bg` (default: `var(--lr-color-danger-quiet)`) — Denied badge background.\n- `--lr-tool-timeline-denied-color` (default: `var(--lr-color-danger)`) — Denied badge foreground.\n- `--lr-tool-timeline-denied-marker-color` (default: `var(--lr-color-warning)`) — Rail-dot color for a `status=\"denied\"` entry, decoupled from the pending-approval border below so a consumer can retint either independently.\n- `--lr-tool-timeline-error-color` (default: `var(--lr-color-danger)`) — Expanded error text.\n- `--lr-tool-timeline-error-marker-color` (default: `var(--lr-color-danger)`) — Error rail dot.\n- `--lr-tool-timeline-gap` (default: `var(--lr-space-l)`) — Vertical gap between entries.\n- `--lr-tool-timeline-marker-size` (default: `var(--lr-size-0-625rem)`) — Diameter of an entry's rail dot; also the width of the marker gutter column.\n- `--lr-tool-timeline-pending-approval-border-color` (default: `var(--lr-color-warning)`) — Color of the entry body's leading border while `data-pending-approval=\"true\"`.\n- `--lr-tool-timeline-pending-marker-color` (default: `var(--lr-color-text-quiet)`) — Rail-dot color for a `status=\"pending\"` entry.\n- `--lr-tool-timeline-running-marker-color` (default: `var(--lr-color-brand)`) — Running rail dot.\n- `--lr-tool-timeline-success-marker-color` (default: `var(--lr-color-success)`) — Success rail dot.","attributes":[{"name":"approval-editable","description":"Forwarded to the shared approval dialog's own `editable` — whether a reviewer can edit an\nentry's arguments before approving it.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"js":{"properties":[{"name":"approvalEditable","description":"Forwarded to the shared approval dialog's own `editable` — whether a reviewer can edit an\nentry's arguments before approving it.\n\nAttribute: `approval-editable`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"entries","description":"The calls to render, in any order — see the class doc's ordering note. Entries with empty\ninvocation ids are omitted; duplicate `(sourceKey, id)` identities normalize first-wins.","type":"readonly ToolTimelineEntry[]","default":"[]"},{"name":"formatTimestamp","description":"Overrides the default `hour:minute` rendering of every entry's `startedAt`.","type":"(date: Date) => string | undefined"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"pendingApproval","description":"The approval/denial action held after a listener vetoes `lr-tool-approval-decide`, or `null`\notherwise. Read-only: call `finalizePendingApproval()` after persisting the controlled entry,\nor `revertPendingApproval()` to release the same dialog and draft for another attempt.","type":"ToolTimelineApprovalPending","read-only":true},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-tool-activate","description":"A non-approval entry was activated. `detail: { invocationId, sourceKey? }`.","type":"CustomEvent<ToolTimelineActivateDetail>"},{"name":"lr-tool-approval-decide","description":"A pending entry's approval dialog was resolved. `detail: { invocationId, approved, args? }` — `args` (the dialog's current, possibly host-edited arguments) is present only when `approved` is `true`. Cancelable; preventing it preserves the pending dialog and its current argument edits, sets `pendingApproval`, and requires `finalizePendingApproval()` or `revertPendingApproval()` to settle the held action.","type":"CustomEvent<ToolTimelineApprovalDetail>"},{"name":"lr-tool-render-error","description":"A nested result renderer failed. `detail: { invocationId, sourceKey?, toolName, error }`.","type":"CustomEvent<ToolTimelineRenderErrorDetail>"}]}},{"name":"lr-tooltip","description":"`<lr-tooltip>` — a localized tooltip for a consumer-owned trigger. It accepts both mapped\nlight-DOM shapes without ambiguity: a Web Awesome-style named `trigger` plus default content,\nor a Shoelace-style default trigger plus `content`/`slot=\"content\"` content.\nPlain content uses tooltip semantics. When the active content slot contains an actionable descendant\n(including native controls, authored sequential focus stops, explicit ARIA widgets, and controls\ninside a nested custom element's open shadow root), the popup promotes to a named\ndialog and remains open while pointer or focus is inside so its controls can be reached. Escape\nfrom popup content closes it and restores focus to the trigger. Prefer `<lr-popover>` when\nclick-to-open ownership is desired.\nForwarding slots are followed through their live composed assignments: reassignment, descendant\ntext/actionability changes, and restoration of a forwarding slot's fallback all update the\ndescription and popup role. Image alternatives and bounded, cycle-safe `aria-labelledby`\ntraversal participate too; referenced roots are observed for text and identity changes even\nwhen a target is external or not yet present. A host `aria-label` wins by attribute presence, so\nan explicit empty label suppresses both derived content text and the localized actionable-popup\nfallback.\n\nInteraction/ARIA ownership is independent of positioning. A slotted trigger wins; without one,\na live HTML element resolved by `for` receives the configured interaction listeners and\n`aria-describedby`. A direct `.anchor` is positioning-only. `showAt()`'s virtual anchor wins\npositioning and deliberately has no DOM interaction/ARIA owner while active. Losing the sole\nlive positioning anchor force-closes the tooltip, while a remaining slotted/`for` fallback is\nrebound and keeps the tooltip open.\n\n`trigger` is a space-separated list of `hover`, `focus`, `click` and `manual`, defaulting to\n`\"hover focus\"`. `manual` (in the list, or the standalone `manual` boolean) means only\n`show()`/`hide()`/`open` move it. `show-delay` and `hide-delay` are independent, so a tooltip\ncan linger after the pointer leaves without also being slow to appear.\nMotion resolves through `tooltip.show`/`tooltip.hide` in the public animation registry.\nContent/trigger observers and delayed transitions bind to the current owner window; disconnect\nand cross-document adoption cancel the old realm before reconnect creates replacements.\n\nWhile open, the trigger's `aria-describedby` targets a hidden text proxy in this component's\nlight DOM rather than the shadow-private popup. Native triggers can resolve that ID directly.\nA description is only announced on the node that actually holds focus, so a custom-element\ntrigger also has the proxy applied to its first focusable descendant (through slots and nested\nopen shadow roots) — reaching `<lr-select>`, `<lr-switch>`, `<lr-chip>` and consumer-authored\nwrappers, not only the components that forward their own host `aria-describedby`. Descendants\ninside a shadow root are linked through `ariaDescribedByElements`, where the serialized internal\nattribute is intentionally empty; descriptions the control already had are kept and restored.\nBubbling `focusin`/`focusout` observes those real composed targets, and moving focus within the\ntrigger or between interactive popup controls does not spuriously close the tooltip.\n\nOpen popovers, dropdowns and tooltips reposition when their effective host or inherited text direction changes, preserving open state and lifecycle events. Removing content safely omits tooltip fallback text.\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) | Web Awesome shape: tooltip content; Shoelace shape: the trigger when no named trigger is present. |\n| `content` | Shoelace shape: tooltip content when the default slot owns the trigger. |\n| `trigger` | Web Awesome shape: the highest-priority interaction/ARIA owner. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `arrow` | The arrow element, rendered only when `arrow` is set. Its part name also carries the resolved side (`arrow-top`, `arrow-bottom`, `arrow-left`, `arrow-right`). |\n| `base` | Compatibility name for the tooltip popup wrapper; it is the same node as `tooltip`. |\n| `base__arrow` | Shoelace exported alias on the arrow. |\n| `base__popup` | Shoelace exported popup alias on the same node. |\n| `body` | Tooltip content wrapper. |\n| `popup` | The tooltip popup. It is the same node as `base` and `tooltip`. |\n| `tooltip` | The tooltip popup wrapper. It is the same node as `base`. |\n| `trigger` | The trigger wrapper. |\n\n---\n\n**CSS Custom Properties**\n\n- `--arrow-size` (default: `var(--lr-tooltip-arrow-size,var(--lr-size-0-375rem))`) — Half-width of the arrow square.\n- `--hide-delay` (default: `0ms`) — Interaction hide delay when `hide-delay` is not explicit.\n- `--lr-overlay-border` — Shared floating-surface edge colour. Same deliberate exclusion as `--lr-overlay-surface` above: the bubble draws no border.\n- `--lr-overlay-radius` — Shared floating-surface corner radius. Same deliberate exclusion: the bubble keeps the tighter `--lr-radius-xs` a label-sized box reads best with.\n- `--lr-overlay-surface` — Shared floating-surface fill. Advertised here because this tag's rules live in the stylesheet module `lr-popover` also composes; a tooltip bubble is a high-contrast label, not a panel, so it paints from `--lr-tooltip-background` and is deliberately outside the overlay-surface family.\n- `--lr-positioning-strategy` — Cascading `absolute`/`fixed` override for {@link positioningStrategy}/`hoist`, read from computed style when the bubble is (re)positioned. Set it once on `:root`, a theme, or one clipping ancestor to change every unset tooltip beneath it instead of authoring `positioning-strategy`/`hoist` on each instance; an explicit value on the instance always wins over it.\n- `--lr-tooltip-arrow-size` — Retained Lyra fallback for `--arrow-size`.\n- `--lr-tooltip-background` — Tooltip background color (default `--lr-color-neutral`).\n- `--lr-tooltip-color` — Tooltip text color (default `--lr-color-on-neutral`).\n- `--lr-tooltip-max-inline-size` — Retained Lyra fallback for `--max-width`.\n- `--max-width` (default: `var(--lr-tooltip-max-inline-size,var(--lr-size-20rem))`) — Maximum inline size of the tooltip.\n- `--show-delay` (default: `150ms`) — Interaction show delay when `show-delay` is not explicit.","attributes":[{"name":"aria-label","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"arrow","description":"Render an arrow that points at the anchor. Defaults on for mapped tooltip markup.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"arrow-padding","description":"Keeps the arrow this far from the popup's corners, in pixels.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"arrow-placement","description":"Where the arrow sits along the popup's edge. `anchor` tracks the anchor's centre.\n\nType: `LyraArrowPlacement`  \nDefault: `'anchor'`","value":{"type":["'anchor'","'start'","'end'","'center'"]}},{"name":"content","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"disabled","description":"Prevents interaction/programmatic opening and closes an open tooltip.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"distance","description":"Anchor-offset distance (px) passed to Floating UI's `offset()` middleware -- identical\nsemantics to `<lr-popover>.distance` (can legitimately be negative for overlap).\n\nType: `number`  \nDefault: `8`","value":{"type":["number"]}},{"name":"for","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"hide-delay","description":"Delay (ms) before an interaction closes the tooltip again. `0` by default, so leaving the\ntrigger closes it at once.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"hoist","description":"Retained boolean alias of positioningStrategy: `hoist` is exactly\n`positioningStrategy === 'fixed'`, and writing either spelling updates the other so the two\nattributes can never disagree in the DOM. It is this component's established name (and\nShoelace's own spelling on `sl-tooltip`), so it keeps working indefinitely; prefer\n`positioning-strategy` in new code, which reads the same on every anchored surface.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"manual","description":"Equivalent to including `manual` in `trigger`; kept because it reads better as a boolean\nattribute on a tooltip that is only ever driven from script.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"open","description":"Whether the tooltip is open. Assigning it runs the full `lr-show`/`lr-hide` lifecycle;\nassigning `false` also cancels a delayed open that has not fired yet.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"placement","description":"Type: `Placement`  \nDefault: `'top'`","value":{"type":["'top'","'top-start'","'top-end'","'right'","'right-start'","'right-end'","'bottom'","'bottom-start'","'bottom-end'","'left'","'left-start'","'left-end'"]}},{"name":"positioning-strategy","description":"CSS positioning scheme the popup is laid out with -- the same property, spelled the same way,\nas on `<lr-popover>`, `<lr-dropdown>` and `<lr-select>`. `absolute` (this component's mirrored\ndefault) positions against the nearest containing block and scrolls with it; `fixed` positions\nagainst the viewport and escapes most clipping ancestors. An unsupported value resolves back\nto the default. Changes apply live while open.\nThis property reports only the instance's own authored value (or the mirrored default); the\npopup is actually placed with the `--lr-positioning-strategy` cascading custom property\nhonored ahead of that default when the instance itself sets nothing -- see that `@cssprop`.\n\nType: `PlaceStrategy`  \nDefault: `'absolute'`","value":{"type":["'absolute'","'fixed'"]}},{"name":"show-delay","description":"Delay (ms) before an interaction opens the tooltip. NaN/negative/oversized all normalize\nthrough `finiteDuration`.\n\nType: `number`  \nDefault: `150`","value":{"type":["number"]}},{"name":"skidding","description":"Offset along the anchor's edge, in pixels — Floating UI's cross-axis offset.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"trigger","description":"Space-separated interaction list: any of `hover`, `focus`, `click`, `manual`. `manual` (or an\nempty list) leaves the tooltip entirely under programmatic control.\n\nType: `string`  \nDefault: `'hover focus'`","value":{"type":["string"]}},{"name":"without-arrow","description":"Positive mapped spelling for suppressing the default arrow.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"","description":"Web Awesome shape: tooltip content; Shoelace shape: the trigger when no named trigger is present."},{"name":"content","description":"Shoelace shape: tooltip content when the default slot owns the trigger."},{"name":"trigger","description":"Web Awesome shape: the highest-priority interaction/ARIA owner."}],"js":{"properties":[{"name":"accessibleLabel","description":"Attribute: `aria-label`","type":"string","default":"''"},{"name":"anchor","description":"Positioning-only element anchor. Takes precedence over `for` and the interaction owner, but\nnever receives interaction listeners or generated ARIA.","type":"Element | null","default":"null"},{"name":"arrow","description":"Render an arrow that points at the anchor. Defaults on for mapped tooltip markup.\n\nAttribute: `arrow`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"arrowPadding","description":"Keeps the arrow this far from the popup's corners, in pixels.\n\nAttribute: `arrow-padding`","type":"number","default":"0"},{"name":"arrowPlacement","description":"Where the arrow sits along the popup's edge. `anchor` tracks the anchor's centre.\n\nAttribute: `arrow-placement`","type":"LyraArrowPlacement","default":"'anchor'"},{"name":"content","description":"Attribute: `content`","type":"string","default":"''"},{"name":"disabled","description":"Prevents interaction/programmatic opening and closes an open tooltip.\n\nAttribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"distance","description":"Anchor-offset distance (px) passed to Floating UI's `offset()` middleware -- identical\nsemantics to `<lr-popover>.distance` (can legitimately be negative for overlap).\n\nAttribute: `distance`","type":"number","default":"8"},{"name":"for","description":"Attribute: `for`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"hideDelay","description":"Delay (ms) before an interaction closes the tooltip again. `0` by default, so leaving the\ntrigger closes it at once.\n\nAttribute: `hide-delay`","type":"number","default":"0"},{"name":"hoist","description":"Retained boolean alias of positioningStrategy: `hoist` is exactly\n`positioningStrategy === 'fixed'`, and writing either spelling updates the other so the two\nattributes can never disagree in the DOM. It is this component's established name (and\nShoelace's own spelling on `sl-tooltip`), so it keeps working indefinitely; prefer\n`positioning-strategy` in new code, which reads the same on every anchored surface.\n\nAttribute: `hoist`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"manual","description":"Equivalent to including `manual` in `trigger`; kept because it reads better as a boolean\nattribute on a tooltip that is only ever driven from script.\n\nAttribute: `manual`","type":"boolean","default":"false"},{"name":"open","description":"Whether the tooltip is open. Assigning it runs the full `lr-show`/`lr-hide` lifecycle;\nassigning `false` also cancels a delayed open that has not fired yet.\n\nAttribute: `open`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"placement","description":"Attribute: `placement`  \nReflected to its attribute.","type":"Placement","default":"'top'"},{"name":"positioningStrategy","description":"CSS positioning scheme the popup is laid out with -- the same property, spelled the same way,\nas on `<lr-popover>`, `<lr-dropdown>` and `<lr-select>`. `absolute` (this component's mirrored\ndefault) positions against the nearest containing block and scrolls with it; `fixed` positions\nagainst the viewport and escapes most clipping ancestors. An unsupported value resolves back\nto the default. Changes apply live while open.\nThis property reports only the instance's own authored value (or the mirrored default); the\npopup is actually placed with the `--lr-positioning-strategy` cascading custom property\nhonored ahead of that default when the instance itself sets nothing -- see that `@cssprop`.\n\nAttribute: `positioning-strategy`  \nReflected to its attribute.","type":"PlaceStrategy","default":"'absolute'"},{"name":"showDelay","description":"Delay (ms) before an interaction opens the tooltip. NaN/negative/oversized all normalize\nthrough `finiteDuration`.\n\nAttribute: `show-delay`","type":"number","default":"150"},{"name":"skidding","description":"Offset along the anchor's edge, in pixels — Floating UI's cross-axis offset.\n\nAttribute: `skidding`","type":"number","default":"0"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"trigger","description":"Space-separated interaction list: any of `hover`, `focus`, `click`, `manual`. `manual` (or an\nempty list) leaves the tooltip entirely under programmatic control.\n\nAttribute: `trigger`","type":"string","default":"'hover focus'"},{"name":"withoutArrow","description":"Positive mapped spelling for suppressing the default arrow.\n\nAttribute: `without-arrow`  \nReflected to its attribute.","type":"boolean","default":"false"}],"events":[{"name":"lr-after-hide","description":"The tooltip is closed and its transition has finished.","type":"CustomEvent<null>"},{"name":"lr-after-show","description":"The tooltip is open and its transition has finished.","type":"CustomEvent<null>"},{"name":"lr-hide","description":"The tooltip is about to close. Cancelable — `preventDefault()` keeps it open.","type":"CustomEvent<null>"},{"name":"lr-show","description":"The tooltip is about to open. Cancelable — `preventDefault()` keeps it closed.","type":"CustomEvent<null>"}]}},{"name":"lr-tour","description":"`<lr-tour>` -- a spotlight-and-step guided walkthrough for first-run onboarding. A sequence\nof steps, each anchored to a target element elsewhere in the page via the shared Floating UI\npositioner, shown against a dimmed full-viewport backdrop with a cutout/ring highlighting the\ncurrent target, with Next/Previous/Skip controls and a step-progress indicator. First-party\ninvention (no Web Awesome equivalent) -- nearest precedent in shape is `lr-dialog` (overlay\nlifecycle/focus trap) + `lr-carousel` (index-based navigation) + `lr-stepper`\n(progress/RTL arrow-key nav).\n\n**Not a form-associated control.** A tour is a walkthrough, not a field -- it deliberately has\nno `label`/`hint`/`error` chrome and no `FormAssociated` mixin.\n\n**Controlled component.** `steps` is never mutated by this component (mirrors\n`lr-stepper`'s `steps`); only `activeIndex` and `open` are self-managed, mirroring\n`lr-carousel`'s `index`.\n\n**Target interactivity.** By default, the step's spotlighted target is non-interactive while\nits step is active: it stays visually revealed but is outside the modal interaction model\nand cannot be clicked -- every pointer event over the full\nviewport, including directly over the visually-revealed target, is captured by the backdrop\n(CSS `mask` does not affect hit-testing, only `clip-path` does) -- and cannot be reached by Tab\n(the shared overlay focus trap confines Tab to the popover panel). Set `step.interactiveTarget`\nto opt a step's target out of this: the backdrop additionally clips itself (via `clip-path`,\nwhich *does* affect hit-testing) around the same rect, so pointer/click events fall through to\nthe live target underneath. The panel also becomes nonmodal and an explicit Tab route connects\nits controls with the live target.\n\n**Focus management.** Default steps exclusively own interaction: the shared overlay manager\nmarks outside content inert, traps Tab, and the panel reports `aria-modal=\"true\"`.\n`interactiveTarget` steps instead use a nonmodal overlay, report `aria-modal=\"false\"`, and\ntreat the panel plus the external target's live composed focusables as one bounded Tab scope.\n\nEach step transition mounts a genuinely new popover DOM node (keyed on occurrence index plus\nthe step's `stepId`) so duplicate business ids cannot collapse distinct occurrences and focus\nreliably re-enters the panel every time, even though the Previous/Next button that triggered\nthe transition lives inside that same persistent-looking region. Every step-related event\nexposes the occurrence index; it is the authoritative collection identity.\n\nNo `Home`/`End` jump-to-first/last-step shortcut and no click-to-jump progress dots, unlike\n`lr-stepper` -- a tour's steps are tied to live DOM targets that may not exist until an\nearlier step's side effect (opening a menu, navigating a route) has run, so free jumping is\nunsafe by default. `goToStep()` remains available for a host that knows what it's doing (e.g.\na \"restart tour\" affordance elsewhere).\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) | Rich content overriding the currently active step's plain-text `content` for that step only. When real content is assigned, it's shown instead of `step.content`; when empty, `step.content` renders as plain text. Not scoped per step by this component itself -- a consumer that needs different rich content per step swaps the slotted children (or listens for `lr-tour-step-change` and re-renders them) itself, the same \"consumer owns slotted content\" pattern `lr-dialog`'s default slot already uses. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `backdrop` | The full-viewport dimmed scrim with the spotlight cutout, an inline `<svg>`. `aria-hidden=\"true\"`. |\n| `body` | Wrapper around the step's content (slotted or `step.content`). |\n| `footer` | Wrapper around the Previous/Skip/Next-or-Done control row. |\n| `heading` | The step's visible heading text element -- the `aria-labelledby` target. |\n| `next-button` | The Next/Done control (label switches on the last step). |\n| `popover` | The step panel itself. `role=\"dialog\"`. |\n| `previous-button` | The Previous control. |\n| `progress` | Wrapper around the built-in step-progress indicator (dots + text). |\n| `progress-dot` | An individual decorative dot within `progress`. `aria-hidden=\"true\"`. |\n| `progress-text` | The visible \"Step X of Y\" text -- one of the popover's `aria-describedby` targets. |\n| `skip-button` | The Skip control. |\n| `spotlight` | The decorative highlight ring drawn around the current target's (padded) rect. `pointer-events: none`, `aria-hidden=\"true\"`. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-positioning-strategy` — Cascading `absolute`/`fixed` override for the step popover's `fixed` default, read from computed style when a step is (re)positioned. Set it once on `:root`, a theme, or one clipping ancestor to change every unset tour beneath it; an unrecognized value falls back to `fixed`.\n- `--lr-tour-backdrop-color` — Backdrop scrim fill. Defaults to `--lr-color-overlay`.\n- `--lr-tour-popover-max-width` — Maximum popover inline size. Defaults to `--lr-size-22rem`.\n- `--lr-tour-progress-dot-current-bg` (default: `var(--lr-color-brand)`) — Background of `progress-dot` for the current step, without repainting every other component that reuses the shared brand token.\n- `--lr-tour-spotlight-radius` — Corner radius shared by the cutout and the ring. Defaults to `--lr-radius`.\n- `--lr-tour-spotlight-ring-color` — Spotlight ring color. Defaults to `--lr-color-brand`.\n- `--lr-tour-spotlight-ring-width` — Spotlight ring thickness. Defaults to `--lr-border-width-medium`.","attributes":[{"name":"active-index","description":"Index of the currently active step, clamped to `[0, steps.length - 1]` by `goToStep()` --\nand, for a direct property/attribute assignment that bypasses that method (e.g. two-way\nbinding an external store, or a bad `active-index` attribute), normalized the same way in\n`willUpdate()` below.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"aria-label","description":"Host-level `aria-label` override for every step popover's accessible name -- wins over each\nstep's own `heading`, matching `lr-dialog`'s `accessibleLabel` pattern. Most consumers\nwon't need this since each step already has a meaningful name via `heading`; setting it\nmakes the *same* string name every step's panel. Set as a plain `aria-label` attribute on\n`<lr-tour>` itself, not a public JS property. An explicitly empty `aria-label=\"\"` suppresses\nthe panel's accessible name outright rather than falling back to the heading or step count --\nagain as `lr-dialog` does.\n\nType: `string | null`  \nDefault: `null`"},{"name":"distance","description":"Distance (px) between the target and the popover, passed straight to Floating UI's\n`offset()` middleware -- a tour-level-only setting, mirroring `lr-popover`'s `distance`\nprop exactly (can legitimately be negative for overlap).\n\nType: `number`  \nDefault: `12`","value":{"type":["number"]}},{"name":"light-dismiss","description":"Whether a backdrop click dismisses the tour (`end('skip')`). Defaults to `false`, matching\n`lr-dialog`/`lr-lightbox`'s `lightDismiss`: a guided tour's backdrop click doing nothing by\ndefault avoids losing onboarding progress to a stray click. Set it to opt in.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"open","description":"Whether the tour is open. Set this (or call `start()`/`end()`) -- there is no separate\n`show()`/`hide()` pair.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"placement","description":"Tour-level default Floating UI placement, overridable per step via `LyraTourStep.placement`.\n\nType: `Placement`  \nDefault: `'bottom'`","value":{"type":["'top'","'top-start'","'top-end'","'right'","'right-start'","'right-end'","'bottom'","'bottom-start'","'bottom-end'","'left'","'left-start'","'left-end'"]}},{"name":"show-progress","description":"Whether the built-in \"Step X of Y\" progress indicator (dots + text) renders in the footer.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"spotlight-padding","description":"Tour-level default extra px between a target's own box and the spotlight cutout/ring,\noverridable per step via `LyraTourStep.spotlightPadding`. Non-negative.\n\nType: `number`  \nDefault: `4`","value":{"type":["number"]}}],"slots":[{"name":"","description":"Rich content overriding the currently active step's plain-text `content` for that step only. When real content is assigned, it's shown instead of `step.content`; when empty, `step.content` renders as plain text. Not scoped per step by this component itself -- a consumer that needs different rich content per step swaps the slotted children (or listens for `lr-tour-step-change` and re-renders them) itself, the same \"consumer owns slotted content\" pattern `lr-dialog`'s default slot already uses."}],"js":{"properties":[{"name":"activeIndex","description":"Index of the currently active step, clamped to `[0, steps.length - 1]` by `goToStep()` --\nand, for a direct property/attribute assignment that bypasses that method (e.g. two-way\nbinding an external store, or a bad `active-index` attribute), normalized the same way in\n`willUpdate()` below.\n\nAttribute: `active-index`  \nReflected to its attribute.","type":"number","default":"0"},{"name":"distance","description":"Distance (px) between the target and the popover, passed straight to Floating UI's\n`offset()` middleware -- a tour-level-only setting, mirroring `lr-popover`'s `distance`\nprop exactly (can legitimately be negative for overlap).\n\nAttribute: `distance`","type":"number","default":"12"},{"name":"lightDismiss","description":"Whether a backdrop click dismisses the tour (`end('skip')`). Defaults to `false`, matching\n`lr-dialog`/`lr-lightbox`'s `lightDismiss`: a guided tour's backdrop click doing nothing by\ndefault avoids losing onboarding progress to a stray click. Set it to opt in.\n\nAttribute: `light-dismiss`","type":"boolean","default":"false"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"open","description":"Whether the tour is open. Set this (or call `start()`/`end()`) -- there is no separate\n`show()`/`hide()` pair.\n\nAttribute: `open`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"placement","description":"Tour-level default Floating UI placement, overridable per step via `LyraTourStep.placement`.\n\nAttribute: `placement`  \nReflected to its attribute.","type":"Placement","default":"'bottom'"},{"name":"showProgress","description":"Whether the built-in \"Step X of Y\" progress indicator (dots + text) renders in the footer.\n\nAttribute: `show-progress`","type":"boolean","default":"true"},{"name":"spotlightPadding","description":"Tour-level default extra px between a target's own box and the spotlight cutout/ring,\noverridable per step via `LyraTourStep.spotlightPadding`. Non-negative.\n\nAttribute: `spotlight-padding`","type":"number","default":"4"},{"name":"steps","description":"Ordered step data. Assignment clone-normalizes at most 256 own-data records into a frozen\nsnapshot, omitting malformed/accessor rows and invalid optional fields, so later caller\nmutation cannot silently change rendering or an emitted event. Empty (the default) renders\nnothing.","type":"readonly Readonly<LyraTourStep>[]"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-tour-end","description":"Fired by `end()` (and by `next()` on the last step, with reason `'completed'`). `detail: LyraTourEndReason`. Conditionally cancelable: every ordinary end can be vetoed, while `'unmount'` cannot because the element is already being removed -- mirrors `lr-dialog`'s own `lr-close` exactly.","type":"CustomEvent<LyraTourEndReason>"},{"name":"lr-tour-start","description":"Fired by `start()`. `detail: { index }`. Not cancelable.","type":"CustomEvent<{ readonly index: number }>"},{"name":"lr-tour-step-change","description":"Fired by `next()`/`back()`/`goToStep()` before `activeIndex` changes. `detail: { index, previousIndex, step, via }`. Cancelable -- a listener calling `preventDefault()` leaves `activeIndex` unchanged, letting a tour gate advancement on a real action (e.g. an onboarding step demonstrating \"click this button\" shouldn't let Next silently skip past it). This is a deliberate departure from `lr-carousel`'s non-cancelable `lr-slide-change`.","type":"CustomEvent<{\n    readonly index: number;\n    readonly previousIndex: number;\n    readonly step: Readonly<LyraTourStep>;\n    readonly via: 'next' | 'back' | 'goto';\n  }>"},{"name":"lr-tour-target-missing","description":"The active step's `target` did not resolve to a connected element. `detail: { index, step }`. Not cancelable -- informational. The tour does not auto-end; it renders that step's popover unanchored (viewport-centered, no spotlight cutout) instead of throwing. A host can listen and decide to `skip()`/`goToStep()` in response.","type":"CustomEvent<{\n    readonly index: number;\n    readonly step: Readonly<LyraTourStep>;\n  }>"}]}},{"name":"lr-trace-tree","description":"`<lr-trace-tree>` — a collapsible span hierarchy for one agent/LLM trace\n(Langfuse/LangSmith run-tree style): kind icon, name, status, an inline\nduration bar on the shared trace time scale, and optional tokens/cost\ncolumns. Consumes the same `LyraSpan[]` as `<lr-span-waterfall>`.\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\nDuration bars always scale to the whole trace, including spans the 500-row ceiling drops, so a\ntruncated tail never stretches the surviving bars across their tracks.\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| `bar` | The duration bar's filled portion. |\n| `bar-track` | The duration bar's background track. |\n| `base` | The root wrapper (`role=\"tree\"`). |\n| `cost` | The cost column cell (when `showCost`). |\n| `detail` | The span's secondary text, from `LyraSpan.detail`. |\n| `duration` | The formatted duration text. |\n| `empty` | The empty-state message shown when `spans` is empty. |\n| `header` | The column-header row, rendered only when `showTokens`/`showCost` is on. |\n| `icon` | The span-kind icon. |\n| `limit` | Localized notice shown when the shared 500-span projection ceiling is reached. |\n| `live-region` | The internal status-announcement live region. |\n| `name` | The span's name. |\n| `row` | One span's row (`role=\"treeitem\"`). |\n| `status-text` | The visible status label. |\n| `toggle` | A row's expand/collapse button. |\n| `tokens-in` | The tokens-in column cell (when `showTokens`). |\n| `tokens-out` | The tokens-out column cell (when `showTokens`). |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-trace-tree-bar-track-bg` (default: `var(--lr-color-surface-raised)`) — Duration bar track.\n- `--lr-trace-tree-denied-color` (default: `var(--lr-color-warning)`) — Denied status text and bar.\n- `--lr-trace-tree-error-color` (default: `var(--lr-color-danger)`) — Error status text and bar.\n- `--lr-trace-tree-max-indent` (default: `var(--lr-size-12rem)`) — Maximum visual nesting indentation; semantic `aria-level` remains exact at deeper levels.\n- `--lr-trace-tree-pending-color` (default: `var(--lr-color-text-quiet)`) — Pending status text and bar.\n- `--lr-trace-tree-row-active-bg` (default: `var(--lr-color-brand-quiet)`) — Background of the active (`activeSpanId`) row. Shadow Parts forbids an attribute selector after `::part()`, so the active row could otherwise only be restyled by hijacking the library-wide `--lr-color-brand-quiet` token. Pairs with `--lr-trace-tree-row-active-color`: set both together, since the defaults assume the active background stays on the same side of the lightness midpoint as the ambient surface — a dark tint in light mode needs the matching text color set too, or the row's secondary text drops below the WCAG AA contrast floor.\n- `--lr-trace-tree-row-active-color` (default: `var(--lr-color-text)`) — Foreground reference for the active (`activeSpanId`) row. It sets the color of that row's secondary text (`detail`, `duration`, `tokens-in`, `tokens-out`, `cost`, and the `pending` status label), which is raised from the quiet token to full-strength text so it clears WCAG AA against the active row's tint. The semantic status labels keep their own hue but are mixed 25% toward this same value, so overriding it re-aims every foreground on the row at once rather than leaving the status colors stranded. See the pairing caveat on `--lr-trace-tree-row-active-bg`.\n- `--lr-trace-tree-running-color` (default: `var(--lr-color-brand)`) — Running status text and stripe.\n- `--lr-trace-tree-running-stripe-bg` (default: `var(--lr-color-brand-quiet)`) — Running stripe contrast.\n- `--lr-trace-tree-success-color` (default: `var(--lr-color-success)`) — Success status text and bar.\n- `--lr-trace-tree-toggle-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Toggle hover background.","attributes":[{"name":"active-span-id","description":"Controlled selection — the matching row carries `aria-current`/`data-active` and scrolls into view.\n\nType: `string | null`  \nDefault: `null`"},{"name":"hide-bars","description":"Suppresses the inline duration bar, for dense/narrow embeddings.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"label","description":"Optional accessible-name override for the `role=\"tree\"` element. Omission localizes the\ndefault; any supplied string, including `''`, is rendered verbatim. A host `aria-label`\nnames the host itself and is not cloned onto the independently interactive tree.\n\nType: `string | undefined`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"show-cost","description":"Adds a cost column, rendering `costText` verbatim.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"show-tokens","description":"Adds tokens-in/tokens-out columns.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"js":{"properties":[{"name":"activeSpanId","description":"Controlled selection — the matching row carries `aria-current`/`data-active` and scrolls into view.\n\nAttribute: `active-span-id`","type":"string | null","default":"null"},{"name":"hideBars","description":"Suppresses the inline duration bar, for dense/narrow embeddings.\n\nAttribute: `hide-bars`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"label","description":"Optional accessible-name override for the `role=\"tree\"` element. Omission localizes the\ndefault; any supplied string, including `''`, is rendered verbatim. A host `aria-label`\nnames the host itself and is not cloned onto the independently interactive tree.\n\nAttribute: `label`","type":"string | undefined"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"showCost","description":"Adds a cost column, rendering `costText` verbatim.\n\nAttribute: `show-cost`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"showTokens","description":"Adds tokens-in/tokens-out columns.\n\nAttribute: `show-tokens`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"spans","description":"Flat span array. Hierarchy is derived from `parentId`; siblings order by `startMs`.\nAt most 500 unique spans with finite timestamps are rendered. A resolved `activeSpanId` and\nits nearest ancestor path reserve positions before ordinary input-order rows, so a controlled\nselection remains current and revealable across the ceiling. Malformed parent cycles are\nbroken into roots so hostile trace data cannot recurse indefinitely. Foreign runtime\n`kind`/`status` values normalize to `'other'`/`'pending'` before rendering.","type":"readonly LyraSpan[]","default":"[]"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-span-select","description":"`detail: { spanId }` — a row was activated (click, Enter, Space).","type":"CustomEvent<{ spanId: string }>"},{"name":"lr-span-toggle","description":"`detail: { spanId, expanded }` — a row was expanded or collapsed.","type":"CustomEvent<{ spanId: string; expanded: boolean }>"}]}},{"name":"lr-transcript-feed","description":"`<lr-transcript-feed>` — live captions for an in-progress voice session: speaker-grouped\nentries, interim-vs-final styling with in-place upgrades keyed by `id`, and a stick-to-bottom\nauto-scroll with release, the same `follow`/`lr-follow-change` contract `lr-terminal` uses.\n\nRendering reconciles `entries` keyed by `id` via Lit's `repeat()`. Ids must be nonempty,\nnonblank, and unique within a session, and `text` must be a string; invalid and later duplicate\nrows are omitted with the first valid occurrence winning. A same-`id` entry with new `text`\nreplaces in place; a same-`id` entry whose\n`interim` flips from `true` to unset/`false`\nmoves from the interim area into the `role=\"log\"` region and announces exactly once. Interim\nentries render *after* the log container, visible but structurally outside it, so per-token\nmutations are never spoken by assistive tech.\n\nThat announcement does **not** come from the shadow `role=\"log\"` region, which is explicitly\n`aria-live=\"off\"`: a live region rendered inside a component's own shadow root is not reliably\nannounced (JAWS with Firefox ignores one outright). Each newly final entry's `text` is announced\nonce through the shared light-DOM `polite` sink instead (`internal/announcer.ts`), the same route\n`<lr-chat-viewport>` and `<lr-terminal>` take. The entries a feed is *mounted* with are existing\ntranscript rather than newly spoken captions, so the first render only records them; a caption is\nannounced when it becomes final on a later update, and never re-announced afterwards.\n\nLive captions only: recorded-media transcript sync — clickable cues, seek-on-select — is a\nseparate concern from this component.\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\nActivating the focused jump action resumes follow and transfers focus to the scroll base when the action disappears, unless a newer outside focus move takes precedence.\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| `empty` | Custom empty state. Default: the localized \"No transcript yet\". |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The scroll container. |\n| `empty` | The empty-state wrapper. |\n| `entry` | One entry row (final or interim). |\n| `interim` | Present (alongside `entry`) on an interim row. |\n| `interim-area` | The wrapper around the interim (not-yet-final) entries, rendered as a sibling of `log`. Only rendered while at least one interim entry exists. |\n| `jump-button` | The \"jump to latest\" affordance, shown only while `follow` is `false`. |\n| `log` | The `role=\"log\"` region wrapping final entries only. |\n| `speaker` | An entry's speaker label (omitted for a row that repeats the previous row's speaker). |\n| `text` | An entry's text (`dir=\"auto\"`, for mixed-language captions). |\n| `timestamp` | An entry's timestamp, shown only when `show-timestamps` is set. |","attributes":[{"name":"aria-label","description":"Overrides the log region's computed accessible name. Wins over `label` and the localized\ndefault. Attribute-reflects from a host-level `aria-label` so a plain-markup consumer gets\nARIA-name forwarding without setting a JS property.\n\nType: `string | null`  \nDefault: `null`"},{"name":"follow","description":"Type: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"label","description":"Accessible name for the `role=\"log\"` region. Optional. Omitting it localizes the default\n`transcriptFeedLabel` message; an explicit empty string renders no visible/accessible label,\nunless `accessibleLabel` is also set (it wins over both).\n\nType: `string | undefined`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max-rendered-entries","description":"`> 0` renders only the newest N rows (host `entries` data is untouched); `0` explicitly\nopts into rendering the full history.\n\nType: `number`  \nDefault: `500`","value":{"type":["number"]}},{"name":"session-id","description":"Session identity. Changing it resets final-announcement history and treats\nthe new session's current entries as a silent baseline.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"show-timestamps","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"empty","description":"Custom empty state. Default: the localized \"No transcript yet\"."}],"js":{"properties":[{"name":"accessibleLabel","description":"Overrides the log region's computed accessible name. Wins over `label` and the localized\ndefault. Attribute-reflects from a host-level `aria-label` so a plain-markup consumer gets\nARIA-name forwarding without setting a JS property.\n\nAttribute: `aria-label`","type":"string | null","default":"null"},{"name":"entries","type":"readonly LyraTranscriptEntry[]","default":"[]"},{"name":"follow","description":"Attribute: `follow`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"formatTimestamp","description":"Overrides the default `Intl.DateTimeFormat` short-time rendering.","type":"(date: Date) => string | undefined"},{"name":"label","description":"Accessible name for the `role=\"log\"` region. Optional. Omitting it localizes the default\n`transcriptFeedLabel` message; an explicit empty string renders no visible/accessible label,\nunless `accessibleLabel` is also set (it wins over both).\n\nAttribute: `label`","type":"string | undefined"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"maxRenderedEntries","description":"`> 0` renders only the newest N rows (host `entries` data is untouched); `0` explicitly\nopts into rendering the full history.\n\nAttribute: `max-rendered-entries`","type":"number","default":"500"},{"name":"sessionId","description":"Session identity. Changing it resets final-announcement history and treats\nthe new session's current entries as a silent baseline.\n\nAttribute: `session-id`","type":"string","default":"''"},{"name":"showTimestamps","description":"Attribute: `show-timestamps`","type":"boolean","default":"false"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-follow-change","description":"`detail: { following: boolean }` — a user scroll or jump-button click changed stick-to-bottom. Direct `follow` assignments and calling `scrollToBottom()` directly are controlled input and do not echo an event, matching `lr-terminal`'s identical contract.","type":"CustomEvent<{ following: boolean }>"}]}},{"name":"lr-tree","description":"`<lr-tree>` — an expand/collapse hierarchy for graph/document navigation.\n\n**Two child models are accepted.** Nested `<lr-tree-item>` elements written as light-DOM children\nmirror `wa-tree`/`sl-tree`, so that markup renames mechanically; each item carries its own\n`label`/`expanded`/`disabled`/`selected` (see `<lr-tree-item>`). Assigning `data` — a `LyraTreeNodeData[]`\nof plain objects, which additionally supports per-row icons, descriptions and badges — is this\nlibrary's own original shape and remains fully supported. A tree containing any author-written\n`<lr-tree-item>` child is read purely as the declarative model and `data` is ignored, so the two\nnever interleave ambiguously; the empty state renders only when neither model has any items.\nData-model `LyraTreeNodeData.id` values are nonblank global identities and must be unique across\nthe reachable hierarchy. Malformed rows and later duplicate ids are omitted before rendering,\nfocus, selection, expansion, or reorder requests; the first valid depth-first occurrence wins.\n\nImplements the WAI-ARIA treeitem keyboard pattern: a single roving\n`tabindex` (tracked here as `activeId`, pushed down to every\n`<lr-tree-item>` — including nested ones, recursively) and\nArrowUp/Down/Right/Left/Home/End/Enter/Space handled by one delegated\n`keydown` listener. Native `KeyboardEvent`s are `composed: true` and\nbubble across shadow-DOM boundaries, so a press inside a deeply-nested\n`<lr-tree-item>`'s own shadow root still reaches this listener.\n\n**`inert` excludes an item and its whole subtree from that navigation exactly as `disabled`\ndoes** — the roving `tabindex` and `role=\"treeitem\"` live on the `<lr-tree-item>` host itself, so\nan inert item refuses `focus()` outright. Marking the focused item inert therefore moves the\nroving target, and real focus with it, instead of stranding focus on `<body>`. Only `inert`\n*inside* the tree counts: a tree the page behind an open modal has inerted keeps its selection,\nits roving target, and its `activeId` untouched. Selection is deliberately unaffected either way\n— inert means \"not interactive right now\", never \"deselected\".\n\nSet `reorderable` to opt into keyboard reordering: Ctrl/Cmd+ArrowUp/ArrowDown on the focused\nnode emits `lr-reorder` — a *request*, exactly like every other event here. `data` is\nhost-owned and never mutated by this component, so nothing moves until the host reassigns a\nreordered `data`; focus then follows the moved node. The keybinding matches\n`<lr-dashboard-grid>`'s `cells-draggable` precedent (Alt+Arrow is browser back/forward on\nWindows/Linux). `<lr-file-tree>` deliberately **opts out**: its `LyraTreeNodeData[]` is derived from\n`nodes` on every render and keyed by filesystem path, an order it does not own.\nThe reorder live region announces success only after a rendered sibling-order change confirms\nthe host accepted the exact requested swap. Ignored, delayed, or rejected requests never claim\nthat a move already happened; unrelated updates keep an asynchronous request pending.\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) | Top-level `<lr-tree-item>` elements, each nesting its own children — the declarative child model. Leave it empty and assign `data` instead for the object model. |\n| `collapse-icon` | Default icon shown by collapsed items; an item-level slot takes precedence. |\n| `expand-icon` | Default icon shown by expanded items; an item-level slot takes precedence. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | Compatibility name for the root wrapper; `tree` is the component-specific alias. |\n| `empty` | The empty-state message shown when neither child model has any items. |\n| `tree` | The tree's root wrapper (`role=\"tree\"`). It is the same node as `base`. |\n\n---\n\n**CSS Custom Properties**\n\n- `--indent-guide-color` (default: `var(--lr-color-border)`) — Indentation guide color.\n- `--indent-guide-offset` (default: `0`) — Block-axis inset for indentation guides.\n- `--indent-guide-style` (default: `solid`) — Indentation guide border style.\n- `--indent-guide-width` (default: `0`) — Indentation guide width.\n- `--indent-size` (default: `var(--lr-space-l)`) — Indentation step for nested items.","attributes":[{"name":"label","description":"Accessible-name fallback for the internal `role=\"tree\"` element. A host `aria-label` wins by\nattribute presence, including when explicitly empty; `label` is used only when that attribute\nis absent. External `aria-labelledby` idrefs are not forwarded across the shadow boundary.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"reorderable","description":"Opts into Ctrl/Cmd+ArrowUp/ArrowDown keyboard reordering (see the class doc). Defaults to\n`false`: unset, no `lr-reorder` is ever emitted, Ctrl/Cmd+Arrow keeps behaving exactly like\na plain Arrow press, and the internal live region is not rendered at all.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"selection","description":"Selection behavior. Multiple modes cascade through enabled descendants and expose checkboxes.\n\nType: `TreeSelection`  \nDefault: `'single'`","value":{"type":["'single'","'multiple'","'leaf'","'leaf-multiple'"]}}],"slots":[{"name":"","description":"Top-level `<lr-tree-item>` elements, each nesting its own children — the declarative child model. Leave it empty and assign `data` instead for the object model."},{"name":"collapse-icon","description":"Default icon shown by collapsed items; an item-level slot takes precedence."},{"name":"expand-icon","description":"Default icon shown by expanded items; an item-level slot takes precedence."}],"js":{"properties":[{"name":"data","description":"Clone-owned/frozen object child model. Normalization retains at most 1,000 nodes over 64\ndescendant levels and inspects at most 10,000 root/child array positions in depth-first order.\nAn otherwise unnamed projected row uses its stable data ID as its semantic name, without\nchanging its visible label or the installed data.","type":"readonly LyraTreeNodeData[]","default":"[]"},{"name":"dataTruncated","description":"Whether normalization omitted malformed, over-depth, or over-budget data.","type":"boolean","read-only":true},{"name":"label","description":"Accessible-name fallback for the internal `role=\"tree\"` element. A host `aria-label` wins by\nattribute presence, including when explicitly empty; `label` is used only when that attribute\nis absent. External `aria-labelledby` idrefs are not forwarded across the shadow boundary.\n\nAttribute: `label`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"reorderable","description":"Opts into Ctrl/Cmd+ArrowUp/ArrowDown keyboard reordering (see the class doc). Defaults to\n`false`: unset, no `lr-reorder` is ever emitted, Ctrl/Cmd+Arrow keeps behaving exactly like\na plain Arrow press, and the internal live region is not rendered at all.\n\nAttribute: `reorderable`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"selectedItems","description":"The current selected item elements in document order.","type":"readonly LyraTreeItem[]","read-only":true},{"name":"selection","description":"Selection behavior. Multiple modes cascade through enabled descendants and expose checkboxes.\n\nAttribute: `selection`","type":"TreeSelection","default":"'single'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-after-collapse","description":"Bubbles after an item's collapse motion completes. `detail: { item }`.","type":"CustomEvent<LyraEventDetailSnapshot<{ readonly item: LyraTreeItem }>>"},{"name":"lr-after-expand","description":"Bubbles after an item's expansion motion completes. `detail: { item }`.","type":"CustomEvent<LyraEventDetailSnapshot<{ readonly item: LyraTreeItem }>>"},{"name":"lr-collapse","description":"Bubbles from the item whose collapse began. `detail: { item }`.","type":"CustomEvent<LyraEventDetailSnapshot<{ readonly item: LyraTreeItem }>>"},{"name":"lr-expand","description":"Bubbles from the item whose expansion began. `detail: { item }`.","type":"CustomEvent<LyraEventDetailSnapshot<{ readonly item: LyraTreeItem }>>"},{"name":"lr-lazy-change","description":"Bubbles when an item's pending lazy-loading state changes. `detail: { item, loading }`.","type":"CustomEvent<\n    LyraEventDetailSnapshot<{ readonly item: LyraTreeItem; readonly loading: boolean }>\n  >"},{"name":"lr-lazy-load","description":"Bubbles when a lazy item requests children. `detail: { item, generation }`.","type":"CustomEvent<\n    LyraEventDetailSnapshot<{ readonly item: LyraTreeItem; readonly generation: number }>\n  >"},{"name":"lr-node-select","description":"`detail: { nodeId }`, dispatched by a descendant `<lr-tree-item>` and observed here (bubbling, composed) to keep the roving-tabindex `activeId` in sync.","type":"CustomEvent<{ nodeId: string }>"},{"name":"lr-node-toggle","description":"`detail: { nodeId, expanded }`, dispatched by a descendant `<lr-tree-item>` and observed here (bubbling, composed) to keep the roving-tabindex `activeId` in sync.","type":"CustomEvent<{ nodeId: string; expanded: boolean }>"},{"name":"lr-reorder","description":"`detail: { nodeId, parentNodeId, fromIndex, toIndex }` — Ctrl/Cmd+ArrowUp/ArrowDown requests moving the focused node within its **own parent's** child list (`parentNodeId` is `null` for a top-level item; the indices are sibling-scoped, not flattened-visible-list positions). Only fired while `reorderable`. Never fires at a subtree boundary, so a reorder can never become a reparent. Success is announced only after the rendered sibling order confirms the request.","type":"CustomEvent<{ nodeId: string; parentNodeId: string | null; fromIndex: number; toIndex: number }>"},{"name":"lr-selection-change","description":"Selection changed. `detail: { selection }`, where `selection` is the current `selectedItems` array.","type":"CustomEvent<\n    LyraEventDetailSnapshot<{ readonly selection: readonly LyraTreeItem[] }>\n  >"}]}},{"name":"lr-tree-item","description":"`<lr-tree-item>` — one row of `<lr-tree>`, in either of two child models.\n\n**Declarative model** (mirrors `wa-tree-item`/`sl-tree-item`, so that markup renames\nmechanically): the row's label is the default slot's content — or the `label` attribute when the\nslot is empty — and the hierarchy is nested `<lr-tree-item>` elements written as light-DOM\nchildren. Those nested children are moved to the internal `children` slot by this component, so\nan author never writes `slot=` themselves, exactly as `<lr-tab-group>` assigns the slots for its\nown `<lr-tab>`/`<lr-tab-panel>` element model. `expanded`, `disabled` and `selected` are plain\nattributes on each element.\n\n**Data model**: `<lr-tree>` assigns an `item` (a `LyraTreeNodeData` object) and this element renders that\nobject's whole subtree — icon, description, badges and children — into its own shadow root. An\nassigned `item` always wins for label, disabled state, and children; its `selected`/`lazy`\nvalues seed the element whenever a refreshed object identity is assigned. The owning tree then\nmanages selection on the element without mutating the caller's object.\n\nBoth models share the owning tree's selection engine, lazy-loading lifecycle, disclosure-icon\nslots, and expansion lifecycle. Lyra's richer `lr-node-*` notifications remain available beside\nthe normalized `lr-expand`/`lr-collapse`/`lr-lazy-*` surface. Per-row icons, secondary\ndescriptions and badges remain additive data-model features.\nIn the declarative model, flattened real-content presence chooses between the visual slot and\n`label` fallback, so decorative or element-only visuals remain rendered. Spoken `nodeLabel`\ntext is resolved separately from accessibility-visible assigned content and updates through\nforwarding slots; a host `aria-label` keeps precedence by presence in both models. A data\nitem's `accessibleLabel` is reflected only while the component owns that attribute, so an\ninitial or later author override survives object refreshes. A data item with no usable spoken\nlabel, visible label, description or badge name uses its stable ID as a semantic fallback.\nThis leaves the visible content unchanged and does not apply to declarative items.\nEvery documented CSS part is forwarded under the same name through recursively rendered data-\nmodel children. A consumer selector on the outer item therefore reaches matching row, label,\nstate, checkbox, badge, and disclosure parts at every rendered depth. Declarative children stay\nin consumer light DOM and remain directly selectable as their own `<lr-tree-item>` hosts.\n\n`role=\"treeitem\"` (plus `aria-expanded`/`aria-level`/`aria-setsize`/\n`aria-posinset` and the roving `tabindex`, driven by `<lr-tree>`) live on\nthe *host* element, not the internal `[part=\"row\"]` div — that makes this\nnode's own nested children (rendered in *its own* shadow root, or projected from the light DOM,\nas further `role=\"group\"` content) genuine DOM descendants of the treeitem, which is\nwhat the WAI-ARIA treeitem pattern requires (previously a shadow-root\nsibling).\n\n---\n\n**Component metadata**\n\n- Status: `stable`\n- Since: `8.0.0`\n- Rationale: This tag entered Lyra as a stable public API with documented behavior, accessibility, and cross-browser support.\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 row's label content, in the declarative model. Nested `<lr-tree-item>` children written here are moved to the `children` slot automatically; the `label` attribute is used when no label content is slotted. |\n| `children` | Where nested `<lr-tree-item>` children are projected. Assigned by this component — authors write the children in the default slot. |\n| `collapse-icon` | The disclosure icon shown while collapsed. Falls back to the owning tree's slot, then the built-in chevron. |\n| `expand-icon` | The disclosure icon shown while expanded. Falls back to the owning tree's slot, then the built-in chevron. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `badge` | One optional chip per `item.badges` entry, tone-mapped via `data-tone`. |\n| `base` | Compatibility name for the outer wrapper; `tree-item` is the component-specific alias. |\n| `checkbox` | The checkbox shown by `multiple` and `leaf-multiple` selection. |\n| `checkbox__base` | The checkbox base. |\n| `checkbox__checked-icon` | The checked glyph. |\n| `checkbox__control` | The checkbox control. |\n| `checkbox__control--checked` | The checked checkbox control. |\n| `checkbox__control--indeterminate` | The indeterminate checkbox control. |\n| `checkbox__indeterminate-icon` | The indeterminate glyph. |\n| `checkbox__label` | The checkbox label wrapper. |\n| `children` | The nested-children container. |\n| `content` | The primary and secondary text wrapper. |\n| `description` | The optional secondary description. |\n| `expand-button` | The disclosure button and lazy spinner container. |\n| `group` | The wrapper around a node's expanded child items. |\n| `icon` | The optional decorative leading icon. |\n| `indentation` | The indentation and guide container. |\n| `item` | The painted row container, excluding nested children; state backgrounds and opacity applied through the mirrored item parts reach the visible row. |\n| `item--disabled` | The item container while disabled. |\n| `item--expanded` | The item container while expanded. |\n| `item--indeterminate` | The item container while partially selected. |\n| `item--selected` | The item container while selected. |\n| `label` | The node label. |\n| `row` | The tree row. |\n| `spinner` | The lazy-loading spinner. |\n| `spinner__base` | The spinner's base. |\n| `toggle` | The expand/collapse button, with pointer hover/pressed feedback while enabled. |\n| `tree-item` | The outer wrapper around the row and child group. It is the same node as `base`. |\n\n---\n\n**CSS Custom Properties**\n\n- `--hide-duration` (default: `var(--lr-duration-base)`) — Collapse motion duration.\n- `--indent-guide-color` (default: `var(--lr-color-border)`) — Indentation guide color.\n- `--indent-guide-offset` (default: `0`) — Block-axis inset at both ends of the indentation guide.\n- `--indent-guide-style` (default: `solid`) — Indentation guide border style.\n- `--indent-guide-width` (default: `0`) — Indentation guide width.\n- `--indent-size` (default: `var(--lr-space-l)`) — Indentation step applied once per nesting depth.\n- `--lr-tree-badge-brand-bg` (default: `var(--lr-color-brand-quiet)`) — Brand badge background.\n- `--lr-tree-badge-brand-color` (default: `var(--lr-color-brand)`) — Brand badge text color.\n- `--lr-tree-badge-danger-bg` (default: `var(--lr-color-danger-quiet)`) — Danger badge background.\n- `--lr-tree-badge-danger-color` (default: `var(--lr-color-danger)`) — Danger badge text color.\n- `--lr-tree-badge-neutral-bg` (default: `var(--lr-color-surface)`) — Neutral badge background.\n- `--lr-tree-badge-neutral-color` (default: `var(--lr-color-text-quiet)`) — Neutral badge text color.\n- `--lr-tree-badge-success-bg` (default: `var(--lr-color-success-quiet)`) — Success badge background.\n- `--lr-tree-badge-success-color` (default: `var(--lr-color-success)`) — Success badge text color.\n- `--lr-tree-badge-warning-bg` (default: `var(--lr-color-warning-quiet)`) — Warning badge background.\n- `--lr-tree-badge-warning-color` (default: `var(--lr-color-warning)`) — Warning badge text color.\n- `--lr-tree-checkbox-checked-bg` (default: `var(--lr-color-brand)`) — Checked control background.\n- `--lr-tree-checkbox-checked-border-color` (default: `var(--lr-color-brand)`) — Checked control border.\n- `--lr-tree-checkbox-checked-color` (default: `var(--lr-color-on-brand)`) — Checked glyph color.\n- `--lr-tree-checkbox-indeterminate-bg` (default: `var(--lr-color-brand)`) — Indeterminate control background.\n- `--lr-tree-checkbox-indeterminate-border-color` (default: `var(--lr-color-brand)`) — Indeterminate control border.\n- `--lr-tree-checkbox-indeterminate-color` (default: `var(--lr-color-on-brand)`) — Indeterminate glyph color.\n- `--lr-tree-depth` (default: `0`) — Internal indent plumbing, not a retheming knob: this node's `depth`, written inline onto `[part=\"row\"]` by the component and multiplied by `--indent-size` (capped at `--lr-size-8rem`) to produce the row's `padding-inline-start`.\n- `--lr-tree-selected-bg` (default: `var(--lr-color-brand-quiet)`) — Background of the selected row.\n- `--lr-tree-selected-color` (default: `var(--lr-color-brand)`) — Text color of the selected row.\n- `--show-duration` (default: `var(--lr-duration-base)`) — Expansion motion duration.","attributes":[{"name":"disabled","description":"Removes this item from roving focus and prevents select/toggle activation, in the declarative\nmodel. Ignored when an `item` is assigned (`item.disabled` decides then).\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"expanded","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"label","description":"The row's label in the declarative model, used when no label content is slotted. Ignored when\nan `item` object is assigned (`item.label` is the label then).\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"lazy","description":"Enables asynchronous child loading. Expanding emits `lr-lazy-load` and waits for children.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"selected","description":"Whether this item is the current selection. Declarative markup can seed it with the reflected\nattribute; data objects seed it on assignment; an owning tree then maintains it directly.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}}],"slots":[{"name":"","description":"The row's label content, in the declarative model. Nested `<lr-tree-item>` children written here are moved to the `children` slot automatically; the `label` attribute is used when no label content is slotted."},{"name":"children","description":"Where nested `<lr-tree-item>` children are projected. Assigned by this component — authors write the children in the default slot."},{"name":"collapse-icon","description":"The disclosure icon shown while collapsed. Falls back to the owning tree's slot, then the built-in chevron."},{"name":"expand-icon","description":"The disclosure icon shown while expanded. Falls back to the owning tree's slot, then the built-in chevron."}],"js":{"properties":[{"name":"disabled","description":"Removes this item from roving focus and prevents select/toggle activation, in the declarative\nmodel. Ignored when an `item` is assigned (`item.disabled` decides then).\n\nAttribute: `disabled`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"expanded","description":"Attribute: `expanded`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"hasChildren","type":"boolean","read-only":true},{"name":"indeterminate","description":"Whether only part of this branch is selected. Managed by the owning tree.","type":"boolean","read-only":true},{"name":"isDisabled","description":"Whether this item is disabled, in whichever child model is in use.","type":"boolean","read-only":true},{"name":"item","description":"The data model: the whole subtree as one object, assigned by `<lr-tree>` from its `data`. When\nset it wins over the declarative model for label, disabled state, and children. Its selected\nand lazy values seed the corresponding element state when a refreshed identity is assigned.","type":"LyraTreeNodeData | undefined"},{"name":"label","description":"The row's label in the declarative model, used when no label content is slotted. Ignored when\nan `item` object is assigned (`item.label` is the label then).\n\nAttribute: `label`","type":"string","default":"''"},{"name":"lazy","description":"Enables asynchronous child loading. Expanding emits `lr-lazy-load` and waits for children.\n\nAttribute: `lazy`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"loading","description":"Whether a lazy expansion is waiting for children.","type":"boolean","read-only":true},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"nodeId","description":"This item's identity, in whichever child model is in use: `item.id` in the data model, or a\ngenerated, per-element id in the declarative one (where the markup carries no id of its own).\n`<lr-tree>` tracks its roving tabindex by this value, and it is the `id` every `lr-node-toggle`\n/ `lr-node-select` / `lr-reorder` detail carries.","type":"string","read-only":true},{"name":"nodeLabel","description":"This item's spoken name, in whichever child model is in use — used for `<lr-tree>`'s reorder\nannouncements. Falls back through `item.accessibleLabel`/`item.label`, then a host\n`aria-label`, flattened accessible slotted label text (nested items excluded), and finally the\n`label` attribute fallback.","type":"string","read-only":true},{"name":"selected","description":"Whether this item is the current selection. Declarative markup can seed it with the reflected\nattribute; data objects seed it on assignment; an owning tree then maintains it directly.\n\nAttribute: `selected`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-after-collapse","description":"Fired after the collapse motion completes. `detail: { item }`.","type":"CustomEvent<LyraEventDetailSnapshot<{ readonly item: LyraTreeItem }>>"},{"name":"lr-after-expand","description":"Fired after the expansion motion completes. `detail: { item }`.","type":"CustomEvent<LyraEventDetailSnapshot<{ readonly item: LyraTreeItem }>>"},{"name":"lr-collapse","description":"Fired when collapse begins. `detail: { item }`.","type":"CustomEvent<LyraEventDetailSnapshot<{ readonly item: LyraTreeItem }>>"},{"name":"lr-expand","description":"Fired when expansion begins. `detail: { item }`.","type":"CustomEvent<LyraEventDetailSnapshot<{ readonly item: LyraTreeItem }>>"},{"name":"lr-lazy-change","description":"Fired when the pending lazy-loading state changes. `detail: { item, loading }`.","type":"CustomEvent<\n    LyraEventDetailSnapshot<{ readonly item: LyraTreeItem; readonly loading: boolean }>\n  >"},{"name":"lr-lazy-load","description":"Requests children for a lazy item. `detail: { item, generation }`; consumers can ignore stale generations.","type":"CustomEvent<\n    LyraEventDetailSnapshot<{ readonly item: LyraTreeItem; readonly generation: number }>\n  >"},{"name":"lr-node-select","description":"`detail: { nodeId }`, fired when this node's primary action is activated (via `select()`, clicking anywhere in its row, or Enter/Space).","type":"CustomEvent<{ nodeId: string }>"},{"name":"lr-node-toggle","description":"`detail: { nodeId, expanded }`, fired when this node is expanded or collapsed (via `expand()`/`collapse()`, the toggle button, or ArrowRight/ArrowLeft).","type":"CustomEvent<{ nodeId: string; expanded: boolean }>"}]}},{"name":"lr-typing-indicator","description":"`<lr-typing-indicator>` — a purely presentational \"assistant is\nresponding\" presence cue. No events, no interactivity: a consumer mounts\nit while a response is being generated and removes it (or hides it) once\nreal content has arrived.\n\nThree visual shapes share one component rather than three separate tags\nbecause callers pick between them along a single axis — how the\nsurrounding surface wants the cue to read — and nothing else about the\ncomponent differs:\n- `dots` (default) — three dots with a staggered bounce, the classic\n  \"typing…\" affordance for a standalone status line.\n- `pulse` — a single breathing dot, a quieter cue for a tighter space\n  (e.g. next to an avatar).\n- `cursor` — a blinking vertical bar, meant to sit inline at the tail end\n  of streamed text that is still being appended to.\n\nAccessibility: this indicator typically mounts and unmounts around a real\ngeneration lifecycle (appears when a response starts, disappears once one\narrives) rather than emitting a stream of updates of its own, so it does\n*not* route through `<lr-live-region>`/`Announcer`\n(`../../internal/announcer.js`) — that machinery exists to coalesce many\nrapidly-changing announcements into one, and there is only ever a single\nannouncement here: the mount itself. A plain `role=\"status\"` plus an\naccessible name derived from `label` is sufficient, set both as an\n`aria-label` on the host *and* as a visually-hidden text node in the\nshadow tree, so the name survives even if only one of the two is picked up\nby a given assistive-tech/browser pairing. An empty or whitespace-only\n`label` falls back to the localized \"Thinking…\" copy in\nboth places, rather than leaving the component with no accessible name at\nall. An `aria-label` set directly on the host element (the idiomatic way to\nname any custom element) wins over the `label`-derived default, in both\nplaces -- the host attribute is never silently clobbered on first render.\nThe animated dots/pulse/cursor\nshape is `aria-hidden=\"true\"` — it's decorative; `label` is the entire\naccessible content, so nothing narrates individual animation frames.\n\n`labelPlacement=\"after\"` additionally renders `label` (or its localized \"Thinking…\" fallback)\nvisibly next to the shape, in a `part=\"label\"` element, mirroring `<lr-spinner>`'s own\n`labelPlacement` vocabulary; the default `\"none\"` keeps today's screen-reader-only rendering,\na single sr-only text node with no visible twin. The visible `part=\"label\"` node is itself\n`aria-hidden=\"true\"`: the host's own `aria-label` (see `accessibleLabel`) already carries the\nidentical string as this element's accessible name, so the visible copy would otherwise be\nreachable as a second, redundant accessibility-tree node for the same text -- the same\nduplicate-source-of-truth problem `<lr-gauge>` already avoids by hiding its own `part=\"label\"`.\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 decorative (`aria-hidden`) wrapper around the animated shape. |\n| `cursor` | The blinking bar in the `cursor` shape. |\n| `dot` | Each of the three dots in the `dots` shape. |\n| `label` | The visible label (`aria-hidden`), rendered only while `label-placement=\"after\"`. |\n| `pulse` | The single pulsing dot in the `pulse` shape. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-inline-cursor-height` (default: `var(--lr-size-1em)`) — Shared inline-cursor height.\n- `--lr-inline-cursor-width` (default: `var(--lr-size-0-125rem)`) — Shared inline-cursor width. The `size` property supplies compact and roomy tier fallbacks.\n- `--lr-typing-dot-size` (default: `var(--lr-space-s)`) — Diameter of each dot in the `dots` and `pulse` variants. The `size` property supplies compact and roomy tier overrides.\n- `--lr-typing-dot-stagger-1` (default: `600ms`) — Delay for the second dot in the dots variant.\n- `--lr-typing-dot-stagger-2` (default: `1200ms`) — Delay for the third dot in the dots variant.\n- `--lr-typing-duration` (default: `var(--lr-transition-ambient)`) — Animation duration and timing function for the dot-bounce/pulse/cursor-blink loop, shared by all variants. Aliases the shared `--lr-transition-ambient` token (default `1.8s ease-in-out`) by default, so retiming just this component doesn't affect other ambient-looping components in the library.\n- `--lr-typing-gap` (default: `var(--lr-space-xs)`) — Gap between dots in the `dots` variant. The `size` property supplies compact and roomy tier overrides.","attributes":[{"name":"label","description":"Accessible name, exposed via `role=\"status\"`. Not re-announced on every\nanimation frame — only mount (and any later change to this property)\nproduces a new announcement. Removing the attribute restores the localized fallback; an\nexplicit host aria-label keeps precedence. An empty or whitespace-only value falls\nback to the localized \"Thinking…\" copy (see\n`accessibleLabel`) so the component never loses its accessible name.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"label-placement","description":"Where the accessible label renders. `'none'` (default) keeps it screen-reader-only, exactly\nas this component rendered before this property existed. `'after'` also renders it visibly\nnext to the animated shape -- the same `labelPlacement` vocabulary as `<lr-spinner>`.\n\nType: `TypingIndicatorLabelPlacement`  \nDefault: `'none'`","value":{"type":["'none'","'after'"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"shape","description":"Which decorative presentation to render.\n\nType: `TypingIndicatorShape`  \nDefault: `'dots'`","value":{"type":["'dots'","'pulse'","'cursor'"]}},{"name":"size","description":"Visual size on the shared ladder — drop to `s`/`small` (or below) for dense layouts, e.g.\ninline with a message bubble. `'m'` (the default) is the standalone status-line size.\n\nType: `TypingIndicatorSize`  \nDefault: `'m'`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}}],"js":{"properties":[{"name":"label","description":"Accessible name, exposed via `role=\"status\"`. Not re-announced on every\nanimation frame — only mount (and any later change to this property)\nproduces a new announcement. Removing the attribute restores the localized fallback; an\nexplicit host aria-label keeps precedence. An empty or whitespace-only value falls\nback to the localized \"Thinking…\" copy (see\n`accessibleLabel`) so the component never loses its accessible name.\n\nAttribute: `label`","type":"string","default":"''"},{"name":"labelPlacement","description":"Where the accessible label renders. `'none'` (default) keeps it screen-reader-only, exactly\nas this component rendered before this property existed. `'after'` also renders it visibly\nnext to the animated shape -- the same `labelPlacement` vocabulary as `<lr-spinner>`.\n\nAttribute: `label-placement`  \nReflected to its attribute.","type":"TypingIndicatorLabelPlacement","default":"'none'"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"shape","description":"Which decorative presentation to render.\n\nAttribute: `shape`  \nReflected to its attribute.","type":"TypingIndicatorShape","default":"'dots'"},{"name":"size","description":"Visual size on the shared ladder — drop to `s`/`small` (or below) for dense layouts, e.g.\ninline with a message bubble. `'m'` (the default) is the standalone status-line size.\n\nAttribute: `size`  \nReflected to its attribute.","type":"TypingIndicatorSize","default":"'m'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}]}},{"name":"lr-usage-badge","description":"`<lr-usage-badge>` — a compact, static resource strip for one message or run: tokens in/out,\ncost, latency, with a hover/focus tooltip breakdown. Purely formatting — this component computes\nno counts, rates, or prices; every segment is independently optional, and with nothing set,\nnothing renders at all (not even a focusable/interactive shell).\n\nThe tooltip reuses `<lr-tool-call-chip>`'s hover/focus/Escape/`aria-describedby` contract\nwholesale: hover and focus are tracked as independent \"keep it open\" reasons, so releasing one\nmodality while the other still holds doesn't close it.\n\nThe built-in latency formatting has no minutes/hours tier (`'{ms}ms'`, or one-decimal seconds\nabove 1000ms) — a host whose latencies commonly exceed a minute sets `formatLatency` to render\nits own scale instead, in both the visible strip and the tooltip row.\n\nAn `aria-label` set on the host element (the idiomatic way to name any custom element) wins\nover the localized default accessible name, same convention as `<lr-tool-call-chip>`'s own\n`aria-label` precedence.\n\nNumber abbreviation is `abbreviate`, not `compact`. This badge has no density mode; `compact`\n(removed in 9.0.0) selected `Intl.NumberFormat`'s `notation: 'compact'` here while meaning\nvisual density on every other component that spells it, so the name was moved to what it\nactually does. A stale `compact` attribute is inert.\n\nRemoving cost-text or summary safely omits that content; explicit empty values remain empty and later values restore it. An open tooltip participates in shared Escape ordering even while only hovered, and dismissal preserves focus elsewhere.\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| `details` | Extra rows appended below the built-in tooltip breakdown (e.g. cache-read tokens). Interactive descendants are intentionally inert because this is a tooltip, not a dialog; their accessible text is mirrored into the trigger's tooltip description. |\n| `summary` | Visible summary shown when no built-in segment is set. The `summary` property is its text fallback. A details-only badge without either form of summary remains non-focusable. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The root inline strip (a focusable non-button `role=\"group\"`, only while at least one segment, or a visible summary with details, has content). |\n| `cost` | The verbatim `costText`. Only rendered when set. |\n| `latency` | The formatted `latencyMs`. Only rendered when it's a finite number. |\n| `summary` | The visible fallback shown when no built-in segment is set. |\n| `tokens-in` | The `'{count} in'` segment. Only rendered when `tokensIn` is a finite number. |\n| `tokens-out` | The `'{count} out'` segment. Only rendered when `tokensOut` is a finite number. |\n| `tooltip` | The floating detail breakdown, only meaningful while open. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-overlay-border` (default: `var(--lr-color-border)`) — Shared floating-surface edge colour, on the anchored breakdown tooltip.\n- `--lr-overlay-radius` (default: `var(--lr-radius)`) — Shared floating-surface corner radius, on the anchored breakdown tooltip.\n- `--lr-overlay-shadow-anchored` (default: `var(--lr-shadow-m)`) — Elevation of the anchored surface.\n- `--lr-overlay-surface` (default: `var(--lr-color-surface-overlay)`) — Shared floating-surface fill, on the anchored breakdown tooltip.\n- `--lr-positioning-strategy` — Cascading `absolute`/`fixed` override for the breakdown tooltip's `fixed` default, read from computed style when it is (re)positioned. Set it once on `:root`, a theme, or one clipping ancestor to change every unset usage badge beneath it; an unrecognized value falls back to `fixed`.","attributes":[{"name":"abbreviate","description":"Token counts render via `Intl.NumberFormat` `notation: 'compact'` (e.g. `12345 -> \"12K\"`)\nwhen set; the tooltip always shows full grouped figures regardless. Named for the number\nformatting it selects, not for density: `compact` means visual density on twenty other\ncomponents in this library, and this one has no density mode at all.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"cost-text","description":"Pre-formatted cost (e.g. `\"$0.012\"`), rendered verbatim. Currency formatting is host domain.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"latency-ms","description":"Latency in milliseconds, formatted with the shared duration algorithm (or `formatLatency`,\nwhen set).\n\nType: `number | undefined`"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"summary","description":"Visible text used when there are no built-in token/cost/latency segments. Required to make a\ndetails-only badge into a discoverable tooltip trigger; the `summary` slot takes precedence.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"tokens-in","description":"Input tokens. Normalized to a non-negative integer, locale-formatted. Segment omitted\nentirely while unset or non-finite.\n\nType: `number | undefined`"},{"name":"tokens-out","description":"Output tokens. Same rules as `tokensIn`.\n\nType: `number | undefined`"}],"slots":[{"name":"details","description":"Extra rows appended below the built-in tooltip breakdown (e.g. cache-read tokens). Interactive descendants are intentionally inert because this is a tooltip, not a dialog; their accessible text is mirrored into the trigger's tooltip description."},{"name":"summary","description":"Visible summary shown when no built-in segment is set. The `summary` property is its text fallback. A details-only badge without either form of summary remains non-focusable."}],"js":{"properties":[{"name":"abbreviate","description":"Token counts render via `Intl.NumberFormat` `notation: 'compact'` (e.g. `12345 -> \"12K\"`)\nwhen set; the tooltip always shows full grouped figures regardless. Named for the number\nformatting it selects, not for density: `compact` means visual density on twenty other\ncomponents in this library, and this one has no density mode at all.\n\nAttribute: `abbreviate`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"costText","description":"Pre-formatted cost (e.g. `\"$0.012\"`), rendered verbatim. Currency formatting is host domain.\n\nAttribute: `cost-text`","type":"string","default":"''"},{"name":"formatLatency","description":"Overrides the shared short-duration rendering of `latencyMs` (`'{ms}ms'`, or one-decimal\nseconds above 1000ms — no minutes/hours tier) in both the visible strip and the tooltip row.\nMirrors `<lr-activity-feed>`'s `formatTimestamp` convention.","type":"(ms: number) => string | undefined"},{"name":"latencyMs","description":"Latency in milliseconds, formatted with the shared duration algorithm (or `formatLatency`,\nwhen set).\n\nAttribute: `latency-ms`","type":"number | undefined"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"summary","description":"Visible text used when there are no built-in token/cost/latency segments. Required to make a\ndetails-only badge into a discoverable tooltip trigger; the `summary` slot takes precedence.\n\nAttribute: `summary`","type":"string","default":"''"},{"name":"tokensIn","description":"Input tokens. Normalized to a non-negative integer, locale-formatted. Segment omitted\nentirely while unset or non-finite.\n\nAttribute: `tokens-in`","type":"number | undefined"},{"name":"tokensOut","description":"Output tokens. Same rules as `tokensIn`.\n\nAttribute: `tokens-out`","type":"number | undefined"}]}},{"name":"lr-video","description":"`<lr-video>` — a native, inline video player with three custom-control presets, selectable\ncaptions, fullscreen and picture-in-picture capability gates, and bounded WebVTT thumbnail\npreviews. Its elapsed-time timeline stays on a physical left-to-right axis in either text\ndirection, so native ArrowRight advances and ArrowLeft rewinds. Mirrors the public `<wa-video>`\nsurface under the `lr-` prefix.\nWhile a poster is visible, its poster-play button is the only exposed play action; the ordinary\ncontrol-bar play toggle stays hidden until playback begins. Decorative icon-slot subtrees remain\nprojected through inert, accessibility-hidden siblings rather than entering their native\nbuttons. A declarative host name stays on the host while the native video uses a purpose label;\nan explicitly empty host name is preserved exactly on the native semantic owner.\n\n---\n\n**Component metadata**\n\n- Status: `experimental`\n- Since: `8.0.0`\n- Rationale: This newly introduced Lyra tag mirrors an experimental Web Awesome 3.11 public surface and remains experimental while production compatibility evidence is gathered.\n- Graduation: Eligible for stable status once the mapped public surface, populated accessibility states, cross-browser media behavior, and lifecycle edge cases demonstrate sustained reliability.\n\n---\n\n**Slots**\n\n| Name | Description |\n| --- | --- |\n| (default) | Native `<source>` and `<track>` children. Consumer nodes remain in light DOM; safe allowlisted clones are inserted into the private native video. |\n| `controls-after-play` | Content immediately after the play/pause control. |\n| `controls-start` | Content at the start of the control bar. |\n| `exit-fullscreen-icon` | Decorative fullscreen-exit glyph override. Assigned content is rendered inert and accessibility-hidden beside, never inside, the named native button. |\n| `fullscreen-icon` | Decorative fullscreen-enter glyph override; rendered through the same inert sibling layer. |\n| `mute-icon` | Decorative muted-state glyph override; rendered through the same inert sibling layer. |\n| `pause-icon` | Decorative pause glyph override; rendered through the same inert sibling layer. |\n| `play-icon` | Decorative play glyph override; rendered through the same inert sibling layer. |\n| `poster-icon` | Decorative poster-play glyph override; rendered through the same inert sibling layer. |\n| `volume-icon` | Decorative audible-state glyph override; rendered through the same inert sibling layer. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | Alias on the same root node as `video-wrapper`. |\n| `caption` | Active native caption text. |\n| `caption-overlay` | Caption positioning layer. |\n| `controls` | Custom control bar. |\n| `controls-overlay` | Bottom controls positioning layer. |\n| `poster-overlay` | Poster positioning layer. |\n| `poster-play-button` | Poster play action. |\n| `progress` | Native range input used to scrub. When disabled, its timeline track retains resting paint. |\n| `thumbnail` | Active WebVTT thumbnail preview. |\n| `timeline` | Timeline wrapper. |\n| `timeline-indicator` | Played portion of the timeline. |\n| `timeline-thumb` | Current-time marker. |\n| `timeline-track` | Timeline rail. |\n| `video` | Native `<video>` element. |\n| `video-title-overlay` | Title positioning layer. |\n| `video-wrapper` | Alias on the same root node as `base`. |\n\n---\n\n**CSS Custom Properties**\n\n- `--controls-background` (default: `var(--lr-color-overlay-strong)`) — Controls, captions, and title overlay background.\n- `--controls-color` (default: `var(--lr-color-on-strong-overlay)`) — Custom-control foreground color. The poster play action defaults to `var(--lr-color-text)` against its surface background.\n- `--lr-video-poster-play-button-hover-background` (default: `color-mix(...)`) — Poster play-button hover background.\n- `--lr-video-poster-play-button-hover-border-color` (default: `var(--lr-color-brand)`) — Poster play-button hover border color.\n- `--poster-play-button-background` (default: `var(--lr-color-surface-overlay)`) — Poster play-button background.","attributes":[{"name":"autoplay","description":"Starts playback as soon as the browser's autoplay policy allows.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"autoplay-muted","description":"Starts muted autoplay without changing the authored `muted` property.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"autoplay-on-visible","description":"Pauses playing video outside the viewport and resumes only playback this behavior paused.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"controls","description":"Custom controls: none, standard, or standard plus rate and picture-in-picture.\n\nType: `LyraVideoControls`  \nDefault: `'standard'`","value":{"type":["'none'","'standard'","'full'"]}},{"name":"currentTime","description":"Current playback position in seconds. Assignments are finite and clamped to duration.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"duration","description":"Current finite media duration. Read-only in normal use.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"icon-library","description":"Icon library handed to every control fallback `<lr-icon>`.\n\nType: `string`  \nDefault: `'system'`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"loop","description":"Restarts playback when the video reaches its end.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"muted","description":"Current authored mute state; reflected for state styling.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"playing","description":"Current playing state. Read-only in normal use.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"poster","description":"Poster URL. Executable schemes fail closed.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"preload","description":"Native preload policy.\n\nType: `LyraVideoPreload`  \nDefault: `'metadata'`","value":{"type":["'auto'","'metadata'","'none'"]}},{"name":"src","description":"Direct video URL. Executable schemes fail closed.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"thumbnails","description":"URL of a WebVTT thumbnail file. Reads are byte- and cue-capped.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"title","description":"Video title and accessible-name context.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"volume","description":"Audio volume from zero to one.\n\nType: `number`  \nDefault: `1`","value":{"type":["number"]}}],"slots":[{"name":"","description":"Native `<source>` and `<track>` children. Consumer nodes remain in light DOM; safe allowlisted clones are inserted into the private native video."},{"name":"controls-after-play","description":"Content immediately after the play/pause control."},{"name":"controls-start","description":"Content at the start of the control bar."},{"name":"exit-fullscreen-icon","description":"Decorative fullscreen-exit glyph override. Assigned content is rendered inert and accessibility-hidden beside, never inside, the named native button."},{"name":"fullscreen-icon","description":"Decorative fullscreen-enter glyph override; rendered through the same inert sibling layer."},{"name":"mute-icon","description":"Decorative muted-state glyph override; rendered through the same inert sibling layer."},{"name":"pause-icon","description":"Decorative pause glyph override; rendered through the same inert sibling layer."},{"name":"play-icon","description":"Decorative play glyph override; rendered through the same inert sibling layer."},{"name":"poster-icon","description":"Decorative poster-play glyph override; rendered through the same inert sibling layer."},{"name":"volume-icon","description":"Decorative audible-state glyph override; rendered through the same inert sibling layer."}],"js":{"properties":[{"name":"autoplay","description":"Starts playback as soon as the browser's autoplay policy allows.\n\nAttribute: `autoplay`","type":"boolean","default":"false"},{"name":"autoplayMuted","description":"Starts muted autoplay without changing the authored `muted` property.\n\nAttribute: `autoplay-muted`","type":"boolean","default":"false"},{"name":"autoplayOnVisible","description":"Pauses playing video outside the viewport and resumes only playback this behavior paused.\n\nAttribute: `autoplay-on-visible`","type":"boolean","default":"false"},{"name":"controls","description":"Custom controls: none, standard, or standard plus rate and picture-in-picture.\n\nAttribute: `controls`  \nReflected to its attribute.","type":"LyraVideoControls","default":"'standard'"},{"name":"currentTime","description":"Current playback position in seconds. Assignments are finite and clamped to duration.\n\nAttribute: `currentTime`","type":"number","default":"0"},{"name":"duration","description":"Current finite media duration. Read-only in normal use.\n\nAttribute: `duration`","type":"number","default":"0"},{"name":"iconLibrary","description":"Icon library handed to every control fallback `<lr-icon>`.\n\nAttribute: `icon-library`","type":"string","default":"'system'"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"loop","description":"Restarts playback when the video reaches its end.\n\nAttribute: `loop`","type":"boolean","default":"false"},{"name":"muted","description":"Current authored mute state; reflected for state styling.\n\nAttribute: `muted`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"playing","description":"Current playing state. Read-only in normal use.\n\nAttribute: `playing`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"poster","description":"Poster URL. Executable schemes fail closed.\n\nAttribute: `poster`","type":"string","default":"''"},{"name":"preload","description":"Native preload policy.\n\nAttribute: `preload`","type":"LyraVideoPreload","default":"'metadata'"},{"name":"src","description":"Direct video URL. Executable schemes fail closed.\n\nAttribute: `src`","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"thumbnails","description":"URL of a WebVTT thumbnail file. Reads are byte- and cue-capped.\n\nAttribute: `thumbnails`","type":"string","default":"''"},{"name":"title","description":"Video title and accessible-name context.\n\nAttribute: `title`","type":"string","default":"''"},{"name":"volume","description":"Audio volume from zero to one.\n\nAttribute: `volume`","type":"number","default":"1"}],"events":[{"name":"blur","description":"Relayed once from the internal play/pause control as a bubbling, composed native event.","type":"FocusEvent"},{"name":"ended","description":"Relayed native video event; non-bubbling, non-composed, and non-cancelable.","type":"Event"},{"name":"error","description":"Relayed native video event; non-bubbling, non-composed, and non-cancelable.","type":"Event"},{"name":"focus","description":"Relayed once from the internal play/pause control as a bubbling, composed native event.","type":"FocusEvent"},{"name":"loadedmetadata","description":"Relayed native video event; non-bubbling, non-composed, and non-cancelable.","type":"Event"},{"name":"pause","description":"Relayed native video event; non-bubbling, non-composed, and non-cancelable.","type":"Event"},{"name":"play","description":"Relayed native video event; non-bubbling, non-composed, and non-cancelable.","type":"Event"},{"name":"timeupdate","description":"Relayed native video event; non-bubbling, non-composed, and non-cancelable. Scrubbing the custom timeline, or calling `seek()`, also dispatches this event immediately and exactly once -- the corresponding native follow-up event is not separately relayed.","type":"Event"},{"name":"volumechange","description":"Relayed native video event; non-bubbling, non-composed, and non-cancelable.","type":"Event"}]}},{"name":"lr-video-playlist","description":"`<lr-video-playlist>` — a direct-child `<lr-video>` playlist with a navigable current-item\nlist. It mirrors the public `<wa-video-playlist>` surface under the `lr-` prefix.\n\nLyra additionally exposes `autoAdvance` and `repeat`. `autoAdvance` defaults to `true` to\npreserve the mirrored ended behavior; `repeat=\"one\"` restarts the current video and\n`repeat=\"all\"` wraps the final video to the first.\n`items` can seed deterministic playlist-row metadata for server rendering. Seeded rows are\nvisible but disabled until the browser can adopt the indexed direct video children; live child\nmetadata is authoritative after that corrective update.\n\nA child marked `inert` is unavailable: it never becomes the active video,\n`next()`/`previous()`/auto-advance step past it, and its playlist row renders `disabled` so the\nrow cannot enter the sequential or arrow-key path. Only the child's *own* `inert` counts — a\nplaylist inerted wholesale by an open modal keeps playing. `<lr-video>` has no `disabled`\ncontract; use the native `inert` property to make a child unavailable.\nEvery enabled row is an ordinary sequentially reachable button (`tabindex=\"0\"`); arrow keys are\noptional shortcuts, not a required composite-widget navigation contract. Visible durations are\nassociated with their row through `aria-describedby`. Child presentation overrides are owned\nreversibly while the child belongs to this playlist and restored on removal/reparenting.\n\n---\n\n**Component metadata**\n\n- Status: `experimental`\n- Since: `8.0.0`\n- Rationale: This newly introduced Lyra tag mirrors an experimental Web Awesome 3.11 public surface and remains experimental while production compatibility evidence is gathered.\n- Graduation: Eligible for stable status once the mapped public surface, populated accessibility states, cross-browser media behavior, and lifecycle edge cases demonstrate sustained reliability.\n- Deprecated part `base`: Deprecated since `8.0.0`. Use part `::part(video-playlist)`. Removal is not permitted before `10.0.0`. The video-playlist part identifies the root component explicitly; base remains on the same root node for migration compatibility. That version is a policy floor, not a plan: `wa-video-playlist` still publishes its own deprecated `base` part, so this alias is removed only when upstream's is.\n\n---\n\n**Slots**\n\n| Name | Description |\n| --- | --- |\n| (default) | Direct `<lr-video>` children. Other elements are not playlist items. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | Deprecated alias on the same root node as `video-playlist`. |\n| `playlist` | Playlist sidebar container. |\n| `playlist-duration` | Duration text within a playlist item. |\n| `playlist-item` | An individual playlist item button. |\n| `playlist-thumbnail` | Thumbnail within a playlist item. |\n| `playlist-title` | Title text within a playlist item. |\n| `video-playlist` | Root video-and-playlist layout. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-video-playlist-item-current-background` (default: `var(--lr-color-brand-fill-quiet)`) — Current playlist-item background.\n- `--lr-video-playlist-item-current-border-color` (default: `var(--lr-color-brand)`) — Current playlist-item border color.","attributes":[{"name":"auto-advance","description":"Whether an ended current video advances automatically. Errors never change selection.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"controls","description":"Controls preset forwarded to every direct child video.\n\nType: `LyraVideoControls`  \nDefault: `'full'`","value":{"type":["'none'","'standard'","'full'"]}},{"name":"icon-library","description":"Icon library forwarded to every direct child video.\n\nType: `string`  \nDefault: `'system'`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"repeat","description":"Automatic completion behavior: stop, repeat one, or wrap the full playlist. Lyra extension.\n\nType: `LyraVideoPlaylistRepeat`  \nDefault: `'none'`","value":{"type":["'none'","'one'","'all'"]}}],"slots":[{"name":"","description":"Direct `<lr-video>` children. Other elements are not playlist items."}],"js":{"properties":[{"name":"autoAdvance","description":"Whether an ended current video advances automatically. Errors never change selection.\n\nAttribute: `auto-advance`","type":"boolean","default":"true"},{"name":"controls","description":"Controls preset forwarded to every direct child video.\n\nAttribute: `controls`  \nReflected to its attribute.","type":"LyraVideoControls","default":"'full'"},{"name":"iconLibrary","description":"Icon library forwarded to every direct child video.\n\nAttribute: `icon-library`","type":"string","default":"'system'"},{"name":"items","description":"Initial row metadata for deterministic server rendering, indexed to the direct video children.\nAssign the same value before the first server and browser render. Once live children can be\nobserved, their title/poster/duration/inert state replaces this seed.","type":"readonly LyraVideoPlaylistItem[]","default":"[]"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"repeat","description":"Automatic completion behavior: stop, repeat one, or wrap the full playlist. Lyra extension.\n\nAttribute: `repeat`","type":"LyraVideoPlaylistRepeat","default":"'none'"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"blur","description":"Relayed once from a playlist row as a bubbling, composed native event.","type":"FocusEvent"},{"name":"focus","description":"Relayed once from a playlist row as a bubbling, composed native event.","type":"FocusEvent"},{"name":"lr-video-change","description":"Emitted when `goTo()`, `next()`, `previous()`, or ended advancement selects a video. Detail is `{ previousIndex, currentIndex, video }`; `video` is a fresh, detached, recursively frozen `{ title, poster, sources, tracks }` data snapshot with no live DOM nodes.","type":"CustomEvent<LyraEventDetailSnapshot<LyraVideoPlaylistChangeDetail>>"}]}},{"name":"lr-virtual-list","description":"`<lr-virtual-list>` — a generic windowed/virtualized list host. Renders\nonly the items within the current viewport (plus `overscan` padding rows\non each side) as real DOM, regardless of how large its effective source is, so a\nmulti-thousand-row chat history sidebar or long message thread stays cheap\nto scroll.\n\nContent is entirely caller-supplied: `renderItem(item, index)` returns\nwhatever `lit-html` value should represent that row (typically a\n`TemplateResult`). That value is instantiated inside this component's shadow root, not in the\ncaller's light DOM; style callback output in its own template/custom element, through inherited\ncustom properties, or through an explicitly exported part. `keyFunction(item, index)` gives the\nrow a stable `repeat()` reconciliation key, so scroll position and any per-row state (e.g. an\n`<audio>` element's playback position) survive an array/source mutation instead of every row\nremounting from scratch.\n\n**Narrow allocations.** Row wrappers allow their content to shrink and use\n`overflow-wrap: anywhere` by default, so a normal long value wraps inside\nthe list rather than widening a narrow panel; its resulting height is what\n`row-height=\"auto\"` measures. A consumer that deliberately needs an\nunbroken value can set `white-space: nowrap` on its own rendered content:\nthe scroll container remains horizontally scrollable for that opt-out.\n\n**Windowing math.** Every row is positioned by a `transform: translateY(offset)`, rather than by\npage flow. Array sources use a cumulative offsets cache. Count/index sources stay sparse: fixed\nrow offsets are direct arithmetic and auto-height offsets add only mounted-row measurements to\nthe default estimate. This is what lets only a small DOM window exist while the scrollbar still\nreflects the full content height without synthesizing count-sized item/key/offset arrays:\n- **`row-height=\"auto\"` (default).** Each currently-rendered row is\n  watched by a `ResizeObserver`; its real height lands in a per-key\n  `Map`, and any row not yet measured contributes `DEFAULT_ROW_ESTIMATE_PX`\n  until it has been. This is *not* the same\n  thing as a page-count-based `padding-top`/`padding-bottom` spacer pair —\n  that approach reflows every unmeasured row's position on every new\n  measurement, which is exactly what per-row transform offsets avoid: only\n  the rows *after* a newly-measured one shift, and even that shift is a\n  cheap style recompute, not a layout-affecting padding change.\n- **Fixed numeric `row-height`.** No measurement needed — the offset is `i * rowHeightPx` for an\n  indexed source, while arrays retain the same cached cumulative path as auto-height arrays.\n\nAn array source's offsets cache is rebuilt only when `items`/`source`, `row-height`, or\n`keyFunction` change, or a row's measured height changes -- not on every\nupdate, so a pure scroll-position tick (potentially every rAF while\nscrolling) only re-runs the cheap range/visibility math in\n`computeRange()`, never the `O(n)` offsets rebuild (which, in\n`row-height=\"auto\"` mode, also means a `keyFunction` call per item). For\nindexed sources skip that count-sized rebuild entirely.\n\nBefore a viewport can be measured, including during server rendering, one bounded deterministic\nfirst window (the first row plus `overscan`) is emitted instead of a false empty list. Hydration\npreserves that server window on its first pass, then reconciles it with the measured viewport;\nan ordinary browser-only mount retains its empty-until-measured range-event behavior.\n\n**Accessibility.** The scroll container is `role=\"list\"` and each rendered\nrow is `role=\"listitem\"`, deliberately *not* `listbox`/`option` — this\ncomponent only provides windowing, not the roving-tabindex/\n`aria-activedescendant` keyboard-interaction contract ARIA requires\nalongside a real `listbox`. A consumer that wants full single-select\nlistbox semantics on top of this should compose that behavior itself (see\n`<lr-select>`'s pattern), the same way this component's `active-item-id`\nonly *scrolls* the matching row into view and marks it `aria-current` —\nit never claims to be a selection widget. `aria-setsize`/`aria-posinset`\nare computed from the row's real index in the full effective source (not its\nposition among the currently-rendered DOM window), so a screen reader\nstill announces e.g. \"item 12 of 340\" correctly. `[part=\"base\"]` itself\ncarries `tabindex=\"0\"` — `renderItem`'s content is caller-supplied and not\nguaranteed to contain a focusable element, and a scrollable region with no\nfocusable content of its own is otherwise unreachable by keyboard (native\narrow/Page Up/Page Down scrolling included).\n\n**Grouping.** When supplied, `groups` renders a labeled, measured virtual entry immediately\nbefore the corresponding `startIndex` row. Its live block size contributes to following offsets,\nso an opaque variable-height marker cannot cover that first row. Markers are windowed with the\nrows, while normalized metadata stays cached for sticky lookup; one-group-per-row catalogs remain\nbounded.\n\n**Sticky group headers.** `renderStickyGroup` adds a `[part=\"sticky-group\"]` overlay pinned to the\ntop of the scroll viewport, showing the `groups` entry the viewport is currently inside; as the\nnext group's header arrives it is pushed out by the overlap rather than swapped abruptly. Unset\n(the default) renders no overlay element at all, and the list renders exactly as it does without\nthis feature. Four properties of the overlay matter to a consumer:\n- It is a **strictly presentational visual copy** of content that already exists in the list, so\n  the copy itself is both `aria-hidden` and `inert`. The real row keeps sole ownership of heading\n  semantics, focus and activation without this component traversing or mutating caller-rendered\n  descendants (including arbitrary open shadow roots).\n- It is **pointer-transparent**. Put interactive group actions in the real row; the sticky copy\n  deliberately cannot be opted into a pointer-only interaction state.\n- It is **never measured as a row or real marker.** It contributes nothing to offsets, so the\n  presentational copy is not counted twice.\n- Its measured height becomes a `scroll-padding-block-start` on the scroll container, so both\n  `active-item-id`/`scrollToIndex` and native keyboard scrolling stop *below* the band instead of\n  parking the target row behind it. Scrolled above the first group the band shows nothing but\n  stays mounted, so that height is known before the first jump rather than after it. Under an\n  external `scrollElement` that inset is written on an element that no longer scrolls: the\n  programmatic paths still clear the band (they subtract it arithmetically), but the consumer\n  owns mirroring `scroll-padding-block-start` onto their own scroller for the native one.\nA host that renders its own group headers as ordinary rows supplies `groups` purely as position\nanchors, with `label: ''` so no duplicate `[part=\"group\"]` marker renders.\n\n**Position queries.** `offsetForIndex(index)` and `indexAtOffset(px)` expose the windowing math\nitself: they translate between an item index and the pixel offset that row renders at, in the same\ncoordinate space as the scroll container's `scrollTop`. A host doing its own scroll-linked layout\n(a pinned group header, a scrollbar minimap, a \"jump to here\" affordance) needs those numbers and\nwould otherwise have to duplicate the offsets array.\n\n**External scroll container.** `scrollElement` points the whole windowing loop at an ancestor\nelement (or the `Window`) that already owns a scrollbar, for a list embedded in a longer scrolling\npage rather than sized as its own panel. `[part=\"base\"]` then stops scrolling and grows to the\nlist's full virtual extent, so the page scrollbar spans the whole list, the visible band is the\nexternal scroller's height, and `[part=\"sticky-group\"]` sticks to that scrollport. Every\nlist-coordinate API (`offsetForIndex()`, `indexAtOffset()`, `scrollToIndex()`, `active-item-id`,\n`lr-virtual-scroll`) keeps answering in the list's own offsets; this component converts. There is\nno ancestor auto-detection, deliberately: a detected scroller would silently change this\ncomponent's behavior the day an unrelated `overflow` rule landed on a wrapper in between.\n\n**Programmatic scrolling.** `scrollToIndex()` is the public counterpart to `active-item-id`'s automatic\nscroll-into-view -- used by `<lr-chat-viewport>`'s virtual mode and any other host that needs to\nscroll to a specific row without also changing which row is \"active.\"\n\n**`item-role=\"row\"` mode.** Additive to the default `'listitem'` mapping above: `[part=\"base\"]`\nbecomes `role=\"rowgroup\"`, `[part=\"spacer\"]` becomes `role=\"presentation\"`, and each row becomes\n`role=\"row\"` with `aria-rowindex` (the row's 1-based index plus `row-index-offset`) instead of\n`aria-setsize`/`aria-posinset`. For a consumer composing its own `role=\"table\"` wrapper and header\nrow around this component (see `<lr-dataset-viewer>`), where `row-index-offset=\"1\"` accounts for\nthat external header row occupying `aria-rowindex=\"1\"`.\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**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `base` | The scrollable container (`role=\"list\"`), including the horizontal scrollport used when consumer-rendered row content explicitly opts out of wrapping. Under an external `scrollElement` it stops scrolling, drops its `tabindex` and hover outline, and sizes itself to the list's full virtual extent instead of `--lr-virtual-list-height`. |\n| `group` | A positioned group label. Not rendered for a `groups` entry whose `label` is the empty string (a position-anchor-only entry). |\n| `row` | One rendered row's absolutely-positioned wrapper (`role=\"listitem\"`); `renderItem`'s return value renders inside it. Normal content wraps within the row; consumer content can opt out with `white-space: nowrap`. |\n| `spacer` | The full-content-height inner element that gives the container its true scrollable extent. |\n| `sticky-group` | The pinned copy of the current group, rendered only while `renderStickyGroup` is set (and showing nothing while the viewport is above the first group, where there is no group to pin). Always `aria-hidden`, `inert`, and pointer-transparent; put interactive actions in the real group row. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-theme-scrollbar-gutter` (default: `auto`) — Opt-in theme-level scrollbar gutter honored by the `base` scroll viewport; see `--lr-theme-scrollbar-width`.\n- `--lr-theme-scrollbar-width` (default: `auto`) — Opt-in theme-level scrollbar width honored by the `base` scroll viewport; unset, renders identically to before. Set on `:root` or any ancestor to retune every internal scroll container in the library at once.\n- `--lr-virtual-list-height` (default: `var(--lr-size-24rem)`) — The scroll viewport's height. A virtualized list needs a bounded scroll extent, so this ships a default rather than collapsing to zero when a caller does not size the host. Ignored while `scrollElement` names an external scroller, whose own height is the visible band.\n- `--lr-virtual-list-hover-outline-color` (default: `var(--lr-color-border-strong)`) — Outline color of the mouse-hover preview on `[part=\"base\"]` (a subtler, always-focusable-target preview of its own `:focus-visible` ring). Set to `transparent` to opt out of the hover treatment entirely.\n- `--lr-virtual-list-hover-outline-offset` (default: `calc(-1 * var(--lr-border-width-thin))`) — Inward offset of the mouse-hover preview on `[part=\"base\"]`, keeping the outline inside its own scrollport so it is not clipped at the edge.\n- `--lr-virtual-list-hover-outline-style` (default: `solid`) — Outline style of the mouse-hover preview on `[part=\"base\"]`.\n- `--lr-virtual-list-hover-outline-width` (default: `var(--lr-border-width-thin)`) — Outline width of the mouse-hover preview on `[part=\"base\"]`.","attributes":[{"name":"active-item-id","description":"When set and it matches a row's typed `keyFunction` result, that row is\nsmoothly scrolled into view whenever this changes. Attribute values are\nstrings; assign the property for a numeric key.\n\nType: `VirtualListKey | ''`  \nDefault: `''`"},{"name":"has-more","description":"When true, scrolling near the bottom fires `lr-load-more`.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"item-role","description":"`'listitem'` (default) preserves today's `role=\"list\"`/`role=\"listitem\"` mapping with\n`aria-setsize`/`aria-posinset`. `'row'` maps to `role=\"rowgroup\"`/`role=\"row\"` with\n`aria-rowindex` instead -- for a consumer composing a virtualized `role=\"table\"` (see\n`<lr-dataset-viewer>`).\n\nType: `LyraVirtualListItemRole`  \nDefault: `'listitem'`","value":{"type":["'listitem'","'row'"]}},{"name":"loading","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"overscan","description":"Extra rows rendered beyond the visible viewport on each side, to reduce\nblank-frame risk during fast scrolling. Normalized to a whole number in\nthe inclusive range 0–`MAX_OVERSCAN_ROWS`; non-finite values use the\ndefault.\n\nType: `number`  \nDefault: `6`","value":{"type":["number"]}},{"name":"row-height","description":"`'auto'` (default) measures each row's real height via `ResizeObserver`;\na positive number fixes every row to that many pixels. Numeric markup attributes are parsed\ninto numbers; invalid markup safely canonicalizes to `'auto'`.\n\nType: `LyraVirtualListRowHeight`  \nDefault: `'auto'`","value":{"type":["LyraVirtualListRowHeight"]}},{"name":"row-index-offset","description":"Added to a row's 1-based index to compute `aria-rowindex` in `item-role=\"row\"` mode (e.g. `1`\nwhen a consumer renders its own header row occupying `aria-rowindex=\"1\"` outside this\ncomponent). No effect in `'listitem'` mode.\n\nType: `number`  \nDefault: `0`","value":{"type":["number"]}},{"name":"row-projection","description":"Type: `LyraVirtualListRowProjection`","value":{"type":["'shadow'","'light'"]}}],"js":{"properties":[{"name":"activeItemId","description":"When set and it matches a row's typed `keyFunction` result, that row is\nsmoothly scrolled into view whenever this changes. Attribute values are\nstrings; assign the property for a numeric key.\n\nAttribute: `active-item-id`","type":"VirtualListKey | ''","default":"''"},{"name":"groups","description":"Measured group markers inserted immediately before their first row's `startIndex`. Non-object\nentries, invalid indexes, and duplicate indexes are ignored during rendering. An entry whose `label` is\nthe empty string renders no `[part=\"group\"]` marker at all — it is a pure\nposition anchor, for a host that renders its own group header as an\nordinary row (and would otherwise get two stacked headers) but still needs\nthis component to know where each group starts, e.g. to drive\n`renderStickyGroup`. Omitting `label` entirely still falls back to `key`.","type":"readonly LyraVirtualListGroup[] | undefined"},{"name":"hasMore","description":"When true, scrolling near the bottom fires `lr-load-more`.\n\nAttribute: `has-more`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"itemRole","description":"`'listitem'` (default) preserves today's `role=\"list\"`/`role=\"listitem\"` mapping with\n`aria-setsize`/`aria-posinset`. `'row'` maps to `role=\"rowgroup\"`/`role=\"row\"` with\n`aria-rowindex` instead -- for a consumer composing a virtualized `role=\"table\"` (see\n`<lr-dataset-viewer>`).\n\nAttribute: `item-role`","type":"LyraVirtualListItemRole","default":"'listitem'"},{"name":"items","description":"The full (non-windowed) item collection. Preserved as the array-compatible source when\n`source` is unset.","type":"readonly unknown[]","default":"[]"},{"name":"keyFunction","description":"Derives a row's stable `repeat()` key. Falls back to the item's index\nin the effective source when omitted, which is only a safe identity while the collection\nnever reorders/inserts/removes — provide this whenever it can, or\nscroll position and any per-row DOM state can attach to the wrong row\nacross a mutation (same caveat as `<lr-table>`'s `rowKey`). Duplicate keys remain distinct\nby occurrence for rendering and measurement; `activeItemId` targets the first occurrence.","type":"(\n    item: unknown,\n    index: number\n  ) => string | number | undefined"},{"name":"loading","description":"Attribute: `loading`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"overscan","description":"Extra rows rendered beyond the visible viewport on each side, to reduce\nblank-frame risk during fast scrolling. Normalized to a whole number in\nthe inclusive range 0–`MAX_OVERSCAN_ROWS`; non-finite values use the\ndefault.\n\nAttribute: `overscan`","type":"number","default":"6"},{"name":"projectedRows","description":"The projected light-DOM row wrappers (`[data-lr-virtual-list-row]`) that currently exist as\ndirect children of this host, in item order — the `row-projection=\"light\"` counterpart of\nrenderedRows, and always empty in the default `'shadow'` mode.\n\nEach one pairs 1:1 with the `[part=\"row\"]` wrapper it is slotted into and mirrors that\nwrapper's `data-row-index`/`data-row-key`. Only direct children are considered, so a nested\n`<lr-virtual-list>` inside a projected row never contributes its own rows here. Treat the\nreturned elements as read-only: their lifetime belongs to the windowing math, and any of them\ncan be recycled or removed on the next update.","type":"HTMLElement[]","read-only":true},{"name":"renderItem","description":"Renders one row's content — typically a `lit-html` `TemplateResult` — inside this component's\nshadow root. The returned value is not light-DOM content: style it in its own template/custom\nelement, with inherited custom properties, or through a part this component exports.","type":"(\n    item: unknown,\n    index: number\n  ) => unknown"},{"name":"renderStickyGroup","description":"Renders the pinned copy of whichever `groups` entry the viewport is\ncurrently inside, into a `[part=\"sticky-group\"]` overlay layer that stays\nat the top of the scroll viewport. Unset (the default) renders no overlay\nelement whatsoever. See the class doc's \"Sticky group headers\" section for\nthe accessibility and interactivity contract.\n\nCalled on every scroll-driven update, so keep it cheap and side-effect\nfree — including while the viewport is above the first group, where it is\ncalled with the *first* group and the result rendered hidden, purely to\nkeep the band's height measurable for the scroll inset.","type":"(\n    group: LyraVirtualListGroup\n  ) => unknown | undefined"},{"name":"renderedRows","description":"The row wrappers (`[part=\"row\"]`) that currently exist as real DOM, in item order — the current\nwindow, not the whole `items` collection, and empty before the first render. Each one carries\nits own `data-row-index`, and `renderItem`'s output for that item is inside it.\n\nFor a host that has to *reach* a rendered row rather than style it: focus management across a\nwindowed list is the motivating case, since the row that a keyboard command needs to focus may\nnot have existed a frame earlier. `exportparts` cannot serve that — it forwards styling, not\nelement references. Treat the returned elements as read-only: their positioning, keys, and\nlifetime belong to the windowing math, and any of them can be recycled or removed on the next\nupdate.","type":"HTMLElement[]","read-only":true},{"name":"rowHeight","description":"`'auto'` (default) measures each row's real height via `ResizeObserver`;\na positive number fixes every row to that many pixels. Numeric markup attributes are parsed\ninto numbers; invalid markup safely canonicalizes to `'auto'`.\n\nAttribute: `row-height`","type":"LyraVirtualListRowHeight","default":"'auto'"},{"name":"rowIndexOffset","description":"Added to a row's 1-based index to compute `aria-rowindex` in `item-role=\"row\"` mode (e.g. `1`\nwhen a consumer renders its own header row occupying `aria-rowindex=\"1\"` outside this\ncomponent). No effect in `'listitem'` mode.\n\nAttribute: `row-index-offset`","type":"number","default":"0"},{"name":"rowProjection","description":"Attribute: `row-projection`","type":"LyraVirtualListRowProjection"},{"name":"scrollContainer","description":"The real scroll container — the `[part=\"base\"]` element, the box whose `scrollTop`/\n`clientHeight` this component's windowing math is expressed against. `undefined` until the\nfirst render (and for a never-connected element), since the element does not exist before then.\n\nWhile `scrollElement` is set this element still exists and still hosts every row, but it no\nlonger scrolls: the named external scroller does. Read and write the scroll position there, or\nkeep using `scrollToIndex()`, which targets whichever of the two is currently in charge.\n\nExposed so a host that needs the live scroll position, or needs to scroll the list itself, can\ndo it without reaching into this component's shadow root. Pair it with `lr-virtual-scroll` (change\nnotifications), `offsetForIndex()`/`indexAtOffset()` (coordinate conversion), and\n`scrollToIndex()` (which expresses \"show row N\" without any manual arithmetic at all, and is\nthe better choice whenever that is the actual intent).","type":"HTMLElement | undefined","read-only":true},{"name":"scrollElement","description":"An ancestor element — or the `Window` — that already owns the scrollbar, for a list that is\npart of a longer scrolling page rather than a self-contained panel. While set, this component's\nown `[part=\"base\"]` viewport stops scrolling (it grows to the list's full virtual extent) and\nthe windowing math tracks the named scroller's position instead, so one page scrollbar moves\nthe whole page *and* re-windows the list.\n\nThere is deliberately **no ancestor auto-detection**: the scroller is whichever element you\nname and nothing else. A detected ancestor would silently change this component's behavior the\nday an unrelated `overflow` rule lands on some wrapper between the two.\n\nEverything expressed in list coordinates keeps working unchanged — `offsetForIndex()`,\n`indexAtOffset()`, `scrollToIndex()`, `active-item-id`, and `lr-virtual-scroll`'s `scrollTop`\nare all still relative to the top of the list itself, not to the external scroller; the\ncomponent converts between the two. What changes hands is the scrollbar, the visible band's\nheight (the scroller's, not `--lr-virtual-list-height`'s), and `[part=\"sticky-group\"]`'s\nsticky container, which becomes the external scrollport.\n\nFour consequences worth knowing before reaching for this:\n- `[part=\"base\"]` drops its `tabindex` and its hover outline, because it is no longer a\n  scrollable region. Keyboard scrolling belongs to the external scroller, and a focus stop that\n  scrolls nothing is worse than none.\n- Horizontal scrolling of row content that opted out of wrapping (`white-space: nowrap`)\n  becomes the external scroller's responsibility: CSS cannot leave one axis visible while the\n  other scrolls.\n- The list's position inside the scroller is re-read on scroll, on the scroller's own resize,\n  when the list's own rendered extent resizes, and whenever this property *changes*. A layout\n  change *above* the list that shifts it without any of those happening is not observable. To\n  force a re-read, clear the property and set it again\n  (`el.scrollElement = undefined; el.scrollElement = scroller`) -- assigning the same value\n  twice does nothing, because an unchanged value is not a change as far as Lit is concerned.\n- While `renderStickyGroup` is set, mirror `scroll-padding-block-start` onto the external\n  scroller yourself. This component writes that inset on `[part=\"base\"]`, where it stops having\n  any effect once that element no longer scrolls, and it will not write style on an element it\n  does not own. Programmatic scrolling is unaffected -- `scrollToIndex()` and `active-item-id`\n  subtract the band's height arithmetically -- but native keyboard scrolling can otherwise park\n  the row it lands on underneath `[part=\"sticky-group\"]`.\n\nA value that is neither an `Element` nor a `Window` is ignored (the component keeps scrolling\nits own viewport) rather than throwing — a consumer wiring this from a ref commonly passes\n`null`/`undefined` on its first render.","type":"Element | Window | undefined"},{"name":"source","description":"A readonly array or count/index-backed collection. An array assignment is copied, bounded,\nand frozen while retaining each generic row's identity; reassign a new array after sequence\nchanges. Indexed-source objects pass through by identity. When set, this takes precedence over\n`items`; an indexed source lets synthetic or remote models expose a large row count without\nallocating an `Array(0…count)` merely to feed the virtualizer.","type":"LyraVirtualListSource | undefined"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-load-more","description":"Fired once per approach to the bottom of the list while `has-more` is true and `loading` is false. Deliberately does not refire on every scroll tick while still near the bottom (`loading` gates the in-flight case; scrolling back away from the bottom and returning, or the effective source growing enough to move the window away from the end, re-arms it) — a consumer wanting an automatic retry after a failed fetch should surface its own retry affordance rather than relying on this firing again unprompted.","type":"CustomEvent<null>"},{"name":"lr-virtual-scroll","description":"`detail: { scrollTop, viewportHeight }` (see `LyraVirtualListScroll`) — the scroll container moved. `scrollTop` is always in the list's own offset space (`offsetForIndex()`'s space), including under an external `scrollElement`, where it is how far the list has scrolled past the top of that scroller rather than the scroller's own position. Emitted from the same `requestAnimationFrame` tick that already coalesces native `scroll` events, so a fling that fires dozens of native events produces at most one of these per frame, and none at all when the position did not actually change. Unlike `lr-visible-range-change` this reports *sub-row* movement, which is what a scroll-linked layout (a pinned header, a minimap) needs. A host `aria-label` attribute on this element is forwarded onto the internal `role=\"list\"` container, since `aria-label` set on a custom-element host does not by itself name a role living on an internal shadow element. Used by `<lr-activity-feed>`'s virtualized mode.","type":"CustomEvent<LyraVirtualListScroll>"},{"name":"lr-visible-range-change","description":"`detail: { start, end }` (see `LyraVirtualListRange`) — the current visible (non-overscanned) item index range, fired only when it actually changes.","type":"CustomEvent<LyraVirtualListRange>"}]}},{"name":"lr-visually-hidden","description":"`<lr-visually-hidden>` — hides its content from sight while leaving it in the accessibility\ntree, so screen readers still announce it.\n\nContent becomes visible again while anything inside it holds focus, which is what makes the\nelement usable for skip links: the link is invisible until a keyboard user tabs to it.\n\n---\n\n**Component metadata**\n\n- Status: `stable`\n- Since: `8.0.0`\n- Rationale: This tag entered Lyra as a stable public API with documented behavior, accessibility, and cross-browser support.\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 content to hide visually. |","attributes":[{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"slots":[{"name":"","description":"The content to hide visually."}],"js":{"properties":[{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}]}},{"name":"lr-voice-picker","description":"`<lr-voice-picker>` — a TTS voice selector over a host-supplied `catalog`, mirroring\n`lr-model-select`'s closed-dropdown/free-text-combobox dual mode, stale-value handling, and\nform-association verbatim (see that class's own doc for the full mode-switching contract this one\nshares), extended with a TTS-agnostic preview affordance: a standalone, always-tab-reachable\n`[part=\"preview-button\"]` beside the trigger previews the active option while open, else the\ncommitted value; per-row `[part=\"option-preview\"]` icons are pointer-only duplicates\n(`tabindex=\"-1\"`, `aria-hidden=\"true\"`) since a listbox option must not contain a focusable\ndescendant.\n\nPreview requests are event-first relative to their new target: `lr-preview-request` is cancelable\nand fires before that target can start. Left un-prevented, a `previewUrl` plays through one\ninternal native `<audio>` (the URL passes `safeMediaSrc()` first); `preventDefault()` or no URL\nleaves playback entirely to the host's own TTS. Requesting the same voice while it is already\nplaying internally stops it instead of re-requesting; requesting a different voice retires the\nold resource (and publishes its terminal change) before the new request is dispatched.\n`lr-preview-change` reports internal playback start only after the current\n`audio.play()` promise fulfills, and reports `voiceId: null` on stop/end/error. A rejected pending\nplay publishes neither a false start nor a false stop. Committed-value, active-option, and catalog\nchanges likewise retire an internal preview before the visible preview control changes target;\nclosing or filtering also retires a row-owned preview once no rendered control represents it.\n\nIn free-text mode, `input` and the native selection/range-editing APIs expose the editable\ncombobox text. `setRangeText()` synchronizes `value`, form data, and validity without emitting\nuser-input events. These APIs are no-ops in closed-dropdown mode and before render.\n`readonly` keeps both combobox owners focusable and browseable while blocking user typing and\ncatalog commits; selection/copy, voice previews, form submission/reset, and programmatic writes\nremain available.\nCatalog assignments become bounded, clone-owned, frozen snapshots. Create and reassign a new\ncatalog array after changing its rows; mutating an assigned source does not update the picker.\n\nA catalog row may also set `disabled`, marking it non-actionable exactly like `lr-model-select`'s\nown catalog rows: `aria-disabled=\"true\"` replaces its selected/active affordances, activating it\n(click or keyboard) commits nothing and changes no state, and arrow-key/Home/End\nactive-descendant navigation steps past it instead of landing on it. It does not affect that\nrow's own `[part=\"option-preview\"]`, a separate affordance -- a disabled voice remains\npreviewable so a listener can hear why it is excluded. Omitted or `false` renders the row exactly\nas before this field existed.\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| `error` | Custom error content. |\n| `hint` | Custom hint content. |\n| `label` | Custom visible label content. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `combobox` | The text-input container (free-text mode). |\n| `combobox-input` | The free-text `<input>`. |\n| `empty` | The empty-listbox message. |\n| `error` | The error message. |\n| `expand-icon` | The dropdown indicator. |\n| `form-control` | The complete label, control, hint, error, and listbox frame. |\n| `form-control-label` | The `<label>` element containing the `label` property and slot. |\n| `hint` | The hint message. |\n| `listbox` | The options popover. |\n| `option` | An option row. |\n| `option-badge` | The \"not in catalog\" badge on a synthetic stale-value row. |\n| `option-label` | An option row's label/meta wrapper. |\n| `option-meta` | An option row's quiet `language · description` second line. |\n| `option-preview` | A pointer-only per-row preview icon (`tabindex=\"-1\"`, `aria-hidden`). |\n| `preview-button` | The standalone, keyboard-reachable preview toggle beside the trigger. |\n| `provider-badge` | The optional leading `provider` label. |\n| `trigger` | The trigger button (closed-dropdown mode). |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-form-control-required-color` (default: `var(--lr-color-danger)`) — Required-marker color, themeable independently of error text and invalid borders.\n- `--lr-form-control-required-content` (default: `' *'`) — The required marker appended to `form-control-label` while `required` is set. Set it to `''` to suppress the marker, or to any other quoted string (`' (required)'`, a localized word) to replace it.\n- `--lr-form-control-required-offset` (default: `0`) — Inline space between the label text and the required marker.\n- `--lr-overlay-border` (default: `var(--lr-color-border)`) — Shared floating-surface edge colour, on the listbox.\n- `--lr-overlay-radius` (default: `var(--lr-radius)`) — Shared floating-surface corner radius, read by the listbox only as the middle arm of `--lr-voice-picker-radius`, which still wins when set.\n- `--lr-overlay-shadow-anchored` (default: `var(--lr-shadow-m)`) — Elevation of the anchored surface.\n- `--lr-overlay-surface` (default: `var(--lr-color-surface-overlay)`) — Shared floating-surface fill, on the listbox.\n- `--lr-voice-picker-gap` (default: `var(--lr-space-xs)`) — Gap between the field and preview action, and between trigger, combobox, and option children.\n- `--lr-voice-picker-max-inline-size` (default: `var(--lr-size-24rem)`) — The host's own width ceiling. Set a length to retune it, or `none` to let the control fill its container the way `<lr-select>` does.\n- `--lr-voice-picker-open-border-color` (default: `var(--lr-color-brand)`) — Open trigger border color.\n- `--lr-voice-picker-option-active-bg` (default: `var(--lr-color-brand-quiet)`) — Active option fill.\n- `--lr-voice-picker-option-disabled-opacity` (default: `0.5`) — Opacity of an option row whose catalog entry sets `disabled`.\n- `--lr-voice-picker-option-selected-bg` (default: `transparent`) — Selected option fill.\n- `--lr-voice-picker-option-selected-border` (default: `var(--lr-color-brand)`) — Selected option border.\n- `--lr-voice-picker-option-selected-color` (default: `var(--lr-color-brand)`) — Selected option text.\n- `--lr-voice-picker-option-selected-font-weight` (default: `var(--lr-font-weight-semibold)`) — Selected option label weight.\n- `--lr-voice-picker-option-synthetic-border-color` (default: `var(--lr-color-border)`) — Border color of a synthetic stale-value option row.\n- `--lr-voice-picker-option-synthetic-border-style` (default: `dashed`) — Border style of a synthetic stale-value option row.\n- `--lr-voice-picker-option-synthetic-font-style` (default: `italic`) — Font style of a synthetic stale-value option label.\n- `--lr-voice-picker-preview-active-border` (default: `var(--lr-color-brand)`) — Active preview border.\n- `--lr-voice-picker-preview-active-color` (default: `var(--lr-color-brand)`) — Active preview icon.\n- `--lr-voice-picker-preview-hover-bg` (default: `var(--lr-color-brand-quiet)`) — Shared hover/press fill for the standalone and row preview actions.\n- `--lr-voice-picker-preview-hover-color` (default: `var(--lr-color-brand)`) — Shared hover/press icon color for the standalone and row preview actions.\n- `--lr-voice-picker-radius` (default: `var(--lr-form-control-radius)`) — Trigger, combobox, listbox, option, and preview-action corner radius.\n- `--lr-voice-picker-trigger-border-color` (default: `var(--lr-color-border)`) — Resting trigger/combobox border color, independent of the open-state color below.\n- `--lr-voice-picker-trigger-fill` (default: `var(--lr-color-surface)`) — Resting trigger/combobox background.\n- `--lr-voice-picker-trigger-height` — Exact trigger/combobox height. Unset by default (a floor only, via `-trigger-min-height`); set a length to both floor and cap the control, e.g. to pixel-match a sibling field in the same toolbar row. Takes precedence over `-trigger-min-height`, and the preview action follows whichever of the two is in play.\n- `--lr-voice-picker-trigger-min-height` (default: `var(--lr-form-control-height)`) — Trigger/combobox block-size floor. Reads the shared form-control height ladder, so retuning `--lr-theme-form-control-height-*` moves this control and every sibling field together. The preview action follows it, so raising the floor keeps the pair the same height; the action's own WCAG hit-area floor still wins below `--lr-icon-button-size`.","attributes":[{"name":"allow-custom","description":"Let the user type/commit a value that isn't in `catalog`, even when `catalog` is non-empty.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"autocapitalize","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"autocomplete","description":"Type: `string`  \nDefault: `'off'`","value":{"type":["string"]}},{"name":"autocorrect","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"custom-error","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nType: `string | null`"},{"name":"disabled","description":"Type: `boolean`","value":{"type":["boolean"]}},{"name":"enterkeyhint","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"error-text","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"form","description":"Type: `HTMLFormElement | string | null`  \nDefault: `null`"},{"name":"hint","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"inputmode","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"label","description":"Visible label text. The `label` slot appends custom label content to the same native label.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"name","description":"Type: `string`","value":{"type":["string"]}},{"name":"open","description":"Whether the catalog popup is open. Effectively disabled controls reject direct reopen\nattempts, including a synchronous fieldset cascade.\n\nType: `boolean`","value":{"type":["boolean"]}},{"name":"placeholder","description":"Type: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"preview","description":"Whether to render preview affordances at all.\n\nType: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"provider","description":"Informational only (e.g. `'elevenlabs'`); rendered as a small leading badge.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"readonly","description":"Keeps user edits and catalog commits from changing `value` while retaining focus, popup\nnavigation, selection/copy, previews, form submission, reset, and programmatic writes.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"required","description":"Type: `boolean`","value":{"type":["boolean"]}},{"name":"size","description":"Visual size on the shared six-tier control ladder. `small`/`medium`/`large` alias\n`s`/`m`/`l`; the preview action keeps the library-wide 40px minimum hit area.\n\nType: `LyraSize`  \nDefault: `'m'`","value":{"type":["'2xs'","'xs'","'s'","'m'","'l'","'xl'","'small'","'medium'","'large'"]}},{"name":"spellcheck","description":"Type: `boolean`  \nDefault: `true`","value":{"type":["boolean"]}},{"name":"value","description":"Reflected current reset default; changing it never overwrites a dirty live `value`.\n\nType: `string`","value":{"type":["string"]}}],"slots":[{"name":"error","description":"Custom error content."},{"name":"hint","description":"Custom hint content."},{"name":"label","description":"Custom visible label content."}],"js":{"properties":[{"name":"allowCustom","description":"Let the user type/commit a value that isn't in `catalog`, even when `catalog` is non-empty.\n\nAttribute: `allow-custom`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"autoCorrect","description":"Attribute: `autocorrect`","type":"string","default":"''"},{"name":"autocapitalize","description":"Attribute: `autocapitalize`","type":"string","default":"''"},{"name":"autocomplete","description":"Attribute: `autocomplete`","type":"string","default":"'off'"},{"name":"catalog","description":"The bounded, clone-owned, frozen full voice list. Omit (or leave empty) to fall back to plain\nfree-text entry. Catalog ids must be nonempty and unique; later duplicates are omitted\nentirely, first wins. A blank/whitespace-only id is never selectable, keyboard-reachable, or\npreviewable, but still renders as an inert trailing row rather than silently vanishing (see\n`malformedCatalogEntries`). Replacing the catalog retires any internal preview before the\nrendered candidate can change; reassign a new array after row changes.","type":"LyraCatalog<LyraVoiceCatalogEntry> | undefined"},{"name":"customError","description":"Consumer-supplied validation message reflected through `custom-error`.\n\nAttribute: `custom-error`  \nReflected to its attribute.","type":"string | null"},{"name":"defaultValue","description":"Reflected current reset default; changing it never overwrites a dirty live `value`.\n\nAttribute: `value`","type":"string"},{"name":"disabled","description":"Attribute: `disabled`  \nReflected to its attribute.","type":"boolean"},{"name":"effectiveDisabled","description":"Whether the control is disabled explicitly or by an ancestor fieldset.","type":"boolean","read-only":true},{"name":"enterKeyHint","description":"Attribute: `enterkeyhint`","type":"string","default":"''"},{"name":"errorText","description":"Attribute: `error-text`","type":"string","default":"''"},{"name":"form","description":"Attribute: `form`  \nReflected to its attribute.","type":"HTMLFormElement | string | null","default":"null"},{"name":"hint","description":"Attribute: `hint`","type":"string","default":"''"},{"name":"input","description":"The native editable input in free-text mode, or `null` in closed-dropdown mode and before render.","type":"HTMLInputElement | null","read-only":true},{"name":"inputMode","description":"Attribute: `inputmode`","type":"string","default":"''"},{"name":"label","description":"Visible label text. The `label` slot appends custom label content to the same native label.\n\nAttribute: `label`","type":"string","default":"''"},{"name":"labels","type":"NodeList","read-only":true},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"name","description":"Attribute: `name`  \nReflected to its attribute.","type":"string"},{"name":"open","description":"Whether the catalog popup is open. Effectively disabled controls reject direct reopen\nattempts, including a synchronous fieldset cascade.\n\nAttribute: `open`  \nReflected to its attribute.","type":"boolean"},{"name":"placeholder","description":"Attribute: `placeholder`","type":"string","default":"''"},{"name":"preview","description":"Whether to render preview affordances at all.\n\nAttribute: `preview`  \nReflected to its attribute.","type":"boolean","default":"true"},{"name":"provider","description":"Informational only (e.g. `'elevenlabs'`); rendered as a small leading badge.\n\nAttribute: `provider`","type":"string","default":"''"},{"name":"readonly","description":"Keeps user edits and catalog commits from changing `value` while retaining focus, popup\nnavigation, selection/copy, previews, form submission, reset, and programmatic writes.\n\nAttribute: `readonly`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"required","description":"Attribute: `required`  \nReflected to its attribute.","type":"boolean"},{"name":"selectionDirection","type":"LyraVoicePickerSelectionDirection | null"},{"name":"selectionEnd","type":"number | null"},{"name":"selectionStart","type":"number | null"},{"name":"size","description":"Visual size on the shared six-tier control ladder. `small`/`medium`/`large` alias\n`s`/`m`/`l`; the preview action keeps the library-wide 40px minimum hit area.\n\nAttribute: `size`  \nReflected to its attribute.","type":"LyraSize","default":"'m'"},{"name":"spellcheck","description":"Attribute: `spellcheck`","type":"boolean","default":"true"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"validationMessage","type":"string","read-only":true},{"name":"validity","type":"ValidityState","read-only":true},{"name":"value","description":"The current voice id (empty string when nothing is selected).","type":"string"},{"name":"willValidate","type":"boolean","read-only":true}],"events":[{"name":"blur","description":"Owner-realm native blur relayed when focus leaves the complete picker boundary, retaining `relatedTarget`. Moving between the trigger or input and the sibling preview control does not close/touch the picker or emit this event.","type":"FocusEvent"},{"name":"change","description":"Owner-realm native event fired alongside `lr-change`, mirroring `lr-model-select`'s native-style pair.","type":"Event"},{"name":"focus","description":"Owner-realm native focus relayed when focus enters that complete picker boundary, retaining `relatedTarget`.","type":"FocusEvent"},{"name":"input","description":"A payload-preserving owner-realm `InputEvent` on each free-text edit, and a plain native `Event` alongside `change` when either rendering mode commits a value.","type":"Event"},{"name":"lr-change","description":"`detail: { value: string; inCatalog: boolean }`.","type":"CustomEvent<{ value: string; inCatalog: boolean }>"},{"name":"lr-invalid","description":"The picker failed a validity check. Cancelable: calling `preventDefault()` also cancels the native `invalid` event behind it, suppressing the browser's own validation bubble so an app can present the failure its own way.","type":"CustomEvent<null>"},{"name":"lr-preview-change","description":"`detail: { voiceId: string | null }` — internal playback started (`voiceId`) or stopped (`null`).","type":"CustomEvent<{ voiceId: string | null }>"},{"name":"lr-preview-request","description":"`detail: { voiceId: string; previewUrl?: string }`. Cancelable.","type":"CustomEvent<{ voiceId: string; previewUrl?: string }>"}]}},{"name":"lr-widget","description":"`<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\"]`.","attributes":[{"name":"aria-label","description":"Overrides the fullscreen dialog's accessible name, taking precedence over both `label` and a\nslotted `label`. An explicitly empty value remains an explicit name; fallbacks apply only when\nthe value is absent. Fed only by a host `aria-label`, matching `lr-scroller`'s/`lr-carousel`'s\nown host-override pattern.\n\nType: `string | null`  \nDefault: `null`"},{"name":"backdrop-inset","description":"Overrides the fullscreen backdrop's viewport-filling inset independently of\n`fullscreenInset`. Invalid values retain the default `0`.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"collapsed","description":"Whether the body is collapsed. Reflects to the `collapsed` attribute. Also settable from\noutside (attribute or property) to restore a previously-persisted `storageKey` preference --\nsee `storageKey`'s own doc for the explicit-assignment-beats-persisted-value precedence.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"collapsible","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"compact","description":"Tighter header/body padding for constrained spaces.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"expandable","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"fullscreen","description":"Type: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"fullscreen-inset","description":"CSS `inset` shorthand applied to the fullscreen panel instead of its safe-area default.\nThe backdrop remains viewport-filling unless `backdropInset` is also set.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"label","description":"Header title. Removing the attribute omits the copy without changing null readback.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"storage-key","description":"Persists `collapsed` to `localStorage` across reloads when set. Namespaced as\n`lr-widget:${storageKey}`. Restoration never overwrites a `collapsed` the consumer already\nassigned on the same mount (`collapsed` attribute present, or a `.collapsed=${...}` binding)\n-- including a binding that pins it to `false`, its own default. The same \"explicit beats\npersisted\" guarantee as `lr-app-rail`'s and `lr-table`'s `storage-key` restores, which share\nthis one's write-tracking mechanism. Unset (the default) touches storage not at all.\n\nType: `string | undefined`"},{"name":"sublabel","description":"Secondary header copy. Removed or empty attributes render no fallback text.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"slots":[{"name":"","description":"The panel body."},{"name":"actions","description":"Header action controls, rendered before the collapse/expand buttons."},{"name":"collapse-icon","description":"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`."},{"name":"fullscreen-icon","description":"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`."},{"name":"icon","description":"Optional decorative leading icon in the title row. Its flattened subtree is inert and hidden from assistive technology."},{"name":"label","description":"Rich label content (overrides the `label` attribute)."},{"name":"sublabel","description":"Rich sublabel content (overrides the `sublabel` attribute)."},{"name":"view-{viewId}","description":"Content for the view whose `LyraWidgetView.viewId` matches `{viewId}`, rendered when `views` is non-empty."}],"js":{"properties":[{"name":"accessibleLabel","description":"Overrides the fullscreen dialog's accessible name, taking precedence over both `label` and a\nslotted `label`. An explicitly empty value remains an explicit name; fallbacks apply only when\nthe value is absent. Fed only by a host `aria-label`, matching `lr-scroller`'s/`lr-carousel`'s\nown host-override pattern.\n\nAttribute: `aria-label`","type":"string | null","default":"null"},{"name":"activeViewId","description":"The currently active view's `viewId` -- defaults to the first entry of `views` (or `''` when\n`views` is empty). Settable directly by a consumer wanting to control the active view\nexternally; also updated internally when a view toggle is clicked.","type":"string","default":"''"},{"name":"backdropInset","description":"Overrides the fullscreen backdrop's viewport-filling inset independently of\n`fullscreenInset`. Invalid values retain the default `0`.\n\nAttribute: `backdrop-inset`","type":"string","default":"''"},{"name":"collapsed","description":"Whether the body is collapsed. Reflects to the `collapsed` attribute. Also settable from\noutside (attribute or property) to restore a previously-persisted `storageKey` preference --\nsee `storageKey`'s own doc for the explicit-assignment-beats-persisted-value precedence.\n\nAttribute: `collapsed`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"collapsible","description":"Attribute: `collapsible`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"compact","description":"Tighter header/body padding for constrained spaces.\n\nAttribute: `compact`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"expandable","description":"Attribute: `expandable`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"fullscreen","description":"Attribute: `fullscreen`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"fullscreenInset","description":"CSS `inset` shorthand applied to the fullscreen panel instead of its safe-area default.\nThe backdrop remains viewport-filling unless `backdropInset` is also set.\n\nAttribute: `fullscreen-inset`","type":"string","default":"''"},{"name":"label","description":"Header title. Removing the attribute omits the copy without changing null readback.\n\nAttribute: `label`","type":"string","default":"''"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"storageKey","description":"Persists `collapsed` to `localStorage` across reloads when set. Namespaced as\n`lr-widget:${storageKey}`. Restoration never overwrites a `collapsed` the consumer already\nassigned on the same mount (`collapsed` attribute present, or a `.collapsed=${...}` binding)\n-- including a binding that pins it to `false`, its own default. The same \"explicit beats\npersisted\" guarantee as `lr-app-rail`'s and `lr-table`'s `storage-key` restores, which share\nthis one's write-tracking mechanism. Unset (the default) touches storage not at all.\n\nAttribute: `storage-key`","type":"string | undefined"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"sublabel","description":"Secondary header copy. Removed or empty attributes render no fallback text.\n\nAttribute: `sublabel`","type":"string","default":"''"},{"name":"views","description":"Named alternate views for the panel body. Assignment takes a bounded, recursively frozen\nsnapshot (except `icon`, preserved by reference -- see `snapshotWidgetViews`'s doc); mutate a\ncopy and reassign it to update. For example, a chart/table toggle inside the same card\nchrome. Each entry gets a header toggle button and a `<slot name=\"view-${viewId}\">`. Empty (the\ndefault) renders today's single unnamed default slot as the sole view, unchanged. An entry's\n`label` is optional -- see `LyraWidgetView`'s own doc for the icon-only (`ariaLabel`) case.","type":"readonly LyraWidgetView[]"}],"events":[{"name":"lr-activate","description":"Fired on every accepted header view-toggle activation, whether or not `activeViewId` actually moved. `detail: { value }` carries the activated view's `viewId`. Bubbling and composed, so a host outside the shadow tree receives it. Not cancelable: `lr-view-request` is this component's veto point, and a vetoed activation emits no activation at all. Re-picking the active view is the case `lr-view-change` deliberately stays silent for -- \"rebuild that view\" is a real intent -- and it is otherwise unobservable, because the toggles live in this shadow root, so a retargeted `click` names no view. When an activation does move the view, `lr-view-request` and `lr-view-change` are emitted first. Not fired when a consumer sets `activeViewId` directly.","type":"CustomEvent<{ value: string }>"},{"name":"lr-collapse-change","description":"Non-cancelable post-commit notification from the built-in collapse toggle. Not fired when a consumer sets `collapsed` directly. `detail: { collapsed }` (the new `collapsed` state).","type":"CustomEvent<{ collapsed: boolean }>"},{"name":"lr-collapse-request","description":"A cancelable proposed `collapsed` state from the built-in collapse toggle. Call `preventDefault()` to keep `collapsed` and persistence unchanged. Not fired when a consumer sets `collapsed` directly. `detail: { collapsed }`.","type":"CustomEvent<{ collapsed: boolean }>"},{"name":"lr-fullscreen-change","description":"Non-cancelable post-commit notification, fired after the fullscreen toggle, Escape, or a backdrop click accepts the change. Not fired when a consumer sets `fullscreen` directly. `detail: { fullscreen }` (the new `fullscreen` state).","type":"CustomEvent<{ fullscreen: boolean }>"},{"name":"lr-fullscreen-request","description":"A cancelable proposed `fullscreen` state from the fullscreen toggle, Escape, or a backdrop click. Call `preventDefault()` to leave `fullscreen` unchanged. Not fired when a consumer sets `fullscreen` directly. `detail: { fullscreen }`.","type":"CustomEvent<{ fullscreen: boolean }>"},{"name":"lr-view-change","description":"Non-cancelable post-commit notification, fired after a header view-toggle click accepts the change. Not fired when a consumer sets `activeViewId` directly. `detail: { viewId }`.","type":"CustomEvent<{ viewId: string }>"},{"name":"lr-view-request","description":"A cancelable proposed `activeViewId` from a header view-toggle click. Call `preventDefault()` to leave `activeViewId` unchanged. Not fired when a consumer sets `activeViewId` directly. `detail: { viewId }`.","type":"CustomEvent<{ viewId: string }>"}]}},{"name":"lr-widget-renderer","description":"`<lr-widget-renderer>` — renders an agent-streamed declarative JSON widget tree through an\nallowlisted `type -> lyra tag` registry (see `registry.ts`/`resolve.ts` for the allowlist\nenforcement itself; this class only turns an already-resolved tree into declarative templates).\nMapped custom-element tags and children are serializable during SSR and keyed identically during\nhydration. Primitive mapped props remain property-only by contract: the server emits the stable\nelement/child shell, then hydration assigns props without converting them into attributes. Lit's\nkeyed reconciliation reuses the mapped element so focus, scroll position, and internal state\nsurvive a streamed document update. Each unchanged resolved mapped node also reuses its template\nand ref callback, avoiding redundant property assignments and listener detach/attach cycles on\nunrelated renderer updates.\n\nThe version-two `document` is the sole tree source. An allowlisted prop value shaped as\n`{ $bind: '/json/pointer', fallback?: primitive }` reads from the explicit `bindingState`\nproperty; a registry `bindings` entry names the control event that requests a change.\nThe renderer reports that request through `lr-widget-state-change` and never mutates caller state.\nUnknown-type and disallowed-prop warnings deduplicate within the effective root/registry\ngeneration. Binding-state-only re-resolution remains quiet, while replacing the document root\nor registry releases its prior warning keys before resolving the new generation.\nA malformed root or nested node fails closed: the prior rendered tree is cleared and exactly one\n`lr-render-error` describes the rejected update.\nThe normal `widget-renderer.js` registration entry installs the eight mapped custom elements.\nEvery renderer owns an explicit immutable registry value, defaulting to the frozen built-in\nregistry. A lean consumer imports this side-effect-free class module, defines the renderer,\nimports only its mapped registrations, and assigns a registry made by\n`createWidgetTypeRegistry()`.\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 root wrapper (`display: contents` — adds no layout box of its own). |\n| `col` | A built-in `col` node. |\n| `row` | A built-in `row` node. |\n| `text` | A built-in `text` node. |","attributes":[{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"js":{"properties":[{"name":"bindingState","description":"Explicit controlled binding state. `null` is a real state value, never an absence sentinel.","type":"unknown | undefined"},{"name":"document","description":"Version-two declarative document. Assignment takes a bounded recursively frozen snapshot;\nmutate a copy and reassign it to update. `null` renders an empty base. A malformed root or\nnested node clears prior content and emits one `lr-render-error`.","type":"LyraWidgetDocument | null","default":"null"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"registry","description":"Immutable type registry owned by this renderer. Assign a snapshot returned by\n`createWidgetTypeRegistry()` to override the built-ins without affecting another instance.","type":"LyraWidgetTypeRegistry","default":"DEFAULT_WIDGET_TYPE_REGISTRY"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"}],"events":[{"name":"lr-render-error","description":"`detail: { error }` — the root or one of its nested nodes was structurally unusable.","type":"CustomEvent<{ error: Error }>"},{"name":"lr-widget-action","description":"`detail: { actionId, payload, nodeId, nodeKey, nodePath }` — the single bubbling action channel.","type":"CustomEvent<{\n    actionId: string;\n    payload: unknown;\n    nodeId: string;\n    nodeKey: string;\n    nodePath: string;\n  }>"},{"name":"lr-widget-state-change","description":"A bound control requested a controlled state update. `detail: { path, value, nodeId, nodeKey, nodePath, prop }`; the caller must apply the next `bindingState` value.","type":"CustomEvent<{\n    path: string;\n    value: unknown;\n    nodeId: string;\n    nodeKey: string;\n    nodePath: string;\n    prop: string;\n  }>"}]}},{"name":"lr-word-cloud","description":"`<lr-word-cloud>` — a zero-dependency SVG word/tag cloud. First-party\ninvention (no Web Awesome equivalent). Each word's rendered size is scaled\nfrom its `weight` and placed via an outward Archimedean-spiral search (the\nstandard word-cloud heuristic: heaviest words placed first, each one\nspiraling out from the center until it clears every word already placed).\n\nUnlike sibling `lr-sparkline`/`lr-heatmap` (one `role=\"img\"` glyph\nstanding in for an aggregate value), the individual words here are the\nmeaningful interactive content — but with up to `MAX_WORDS` of them, making\nevery single one its own tab stop would be a poor keyboard experience.\nInstead, like `lr-heatmap`'s cells, the whole `[part=\"svg\"]` is one tab\nstop with roving arrow-key focus (Home/End jump to the first/last word,\nEnter/Space activates the focused one), a drawn `[part=\"focus-ring\"]`, and\na shared light-DOM polite status announcement. The application role and\naggregate accessible name live on that same focusable SVG. An authored host\n`aria-label` is forwarded to that semantic owner and takes precedence over\nthe localized generated name; any authored host role remains on the host.\n`[part=\"live-region\"]` is an aria-hidden mirror of the most recent announcement. Mount is silent, and identical edge\nmovements append separate announcements.\n\nThe eight default palette custom properties inherit from theme ancestors; setting one directly\non the word cloud still wins through the normal cascade.\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 word-cloud wrapper. |\n| `empty` | The empty-state message. |\n| `focus-ring` | The keyboard focus ring. |\n| `legend` | The optional color key below the cloud. |\n| `legend-item` | One named color entry. |\n| `legend-label` | The visible legend label. |\n| `legend-limit` | Localized rendered/received legend-entry disclosure when the explicit legend is bounded. |\n| `legend-swatch` | The color swatch for a legend entry. |\n| `limit` | Numeric rendered/input disclosure when input normalization or layout omits data. |\n| `live-region` | An aria-hidden shadow mirror of the current announcement; the actual announcement uses the shared light-DOM polite sink. |\n| `svg` | The word-cloud SVG. |\n| `word` | A rendered word. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-word-cloud-color-1` (default: `var(--lr-color-brand)`) — First entry of the default categorical palette.\n- `--lr-word-cloud-color-2` (default: `var(--lr-color-success)`) — Second entry of the default categorical palette.\n- `--lr-word-cloud-color-3` (default: `var(--lr-color-warning)`) — Third entry of the default categorical palette.\n- `--lr-word-cloud-color-4` (default: `var(--lr-color-danger)`) — Fourth entry of the default categorical palette.\n- `--lr-word-cloud-color-5` (default: `var(--lr-color-chart-1)`) — Fifth entry of the default categorical palette.\n- `--lr-word-cloud-color-6` (default: `var(--lr-color-chart-2)`) — Sixth entry of the default categorical palette.\n- `--lr-word-cloud-color-7` (default: `var(--lr-color-chart-3)`) — Seventh entry of the default categorical palette.\n- `--lr-word-cloud-color-8` (default: `var(--lr-color-chart-4)`) — Eighth entry of the default categorical palette.","attributes":[{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max-font-size","description":"Font size, in px, for the highest-weight word.\n\nType: `number`  \nDefault: `48`","value":{"type":["number"]}},{"name":"min-font-size","description":"Font size, in px, for the lowest-weight word.\n\nType: `number`  \nDefault: `12`","value":{"type":["number"]}},{"name":"scale","description":"`sqrt` compresses the weight->font-size mapping so one heavy word doesn't dwarf the rest.\n\nType: `WordCloudScale`","value":{"type":["'linear'","'sqrt'"]}},{"name":"show-legend","description":"Renders the supplied or derived legend entries below the cloud. It is non-interactive and\ndoes not alter word activation or palette selection.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"word-rotation","description":"Type: `WordCloudRotation`","value":{"type":["'none'","'mixed'"]}}],"js":{"properties":[{"name":"domain","description":"Pins the weight-to-font-size input domain to `[min, max]`, so separate clouds can share one\nscale instead of each deriving it from its own lightest/heaviest word. Reversed endpoints are\nnormalized; a degenerate or non-finite pair falls back to the data-derived range. Scaling\nstays finite when opposite-sign finite endpoints would overflow on subtraction.","type":"[number, number] | undefined"},{"name":"legend","type":"readonly WordCloudLegendItem[]"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"maxFontSize","description":"Font size, in px, for the highest-weight word.\n\nAttribute: `max-font-size`","type":"number","default":"48"},{"name":"minFontSize","description":"Font size, in px, for the lowest-weight word.\n\nAttribute: `min-font-size`","type":"number","default":"12"},{"name":"palette","type":"readonly string[] | undefined"},{"name":"scale","description":"`sqrt` compresses the weight->font-size mapping so one heavy word doesn't dwarf the rest.\n\nAttribute: `scale`  \nReflected to its attribute.","type":"WordCloudScale"},{"name":"showLegend","description":"Renders the supplied or derived legend entries below the cloud. It is non-interactive and\ndoes not alter word activation or palette selection.\n\nAttribute: `show-legend`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"wordRotation","description":"Attribute: `word-rotation`  \nReflected to its attribute.","type":"WordCloudRotation"},{"name":"words","description":"Normalized frozen word snapshot. At most 10,000 source records and a bounded aggregate text\nbudget are scanned; invalid records are skipped, and every accepted weight is the finite\nnonnegative value used by layout/events/announcements. Reassign to update.","type":"readonly WordCloudWord[]"}],"events":[{"name":"lr-word-activate","description":"Fired from pointer activation, or Enter/Space on the focused word. `detail: { text, weight, group }`.","type":"CustomEvent<Readonly<{ text: string; weight: number; group?: string }>>"}]}},{"name":"lr-xml-viewer","description":"`<lr-xml-viewer>` — collapsible, copyable, `DOMParser`-based tree view for XML documents,\nmirroring `lr-json-viewer`'s UX (`collapsed-depth`, `copyable`, structural-path-keyed expand\nstate that survives a same-shape `xml` reassignment -- e.g. a streaming document being patched\nin place) adapted for XML's own node kinds: elements with attributes, text, comments, CDATA\nsections, and processing instructions, rendered in their original mixed-child source order.\n\nSearch is a purely imperative surface (`search()`/`searchNext()`/`searchPrevious()`/\n`clearSearch()`), the same uniform contract every anchor-target, search-capable viewer in this\nlibrary implements (`lr-pdf-viewer`, `lr-ebook-viewer`, `lr-notebook-viewer`) rather than\na settable property. Each of the three navigating methods resolves only once the newly active\nmatch's row has been scrolled into view, the same way `lr-docx-viewer` follows its own active\nmatch: marking `data-active-match` without scrolling leaves a find-in-page host stepping through\nmatches the reader never sees. `node-path` anchors address an element by child-index chain from\nthe document root, with an optional trailing `'@attrName'` segment addressing one of that\nelement's attributes. Resolving one paints `data-active` on the addressed `[part=\"node\"]` row and,\nfor an attribute-addressing path, on that one `[part=\"attribute\"]` pair -- so a citation pointing\nat a single attribute value of a multi-attribute element stays distinguishable in the rendered\nDOM.\n\nHost-supplied `highlights` are resolved the same way: every entry whose anchor is a `node-path`\nthis document can resolve tints its element row (`data-highlight`, carrying the entry's tone) and\ngains a focusable `[part=\"highlight-action\"]` button that emits `lr-highlight-activate`. Entries\nwhose anchor kind or path this viewer cannot resolve -- including a missing or non-array path --\nare ignored rather than partially painted, and a highlight inside a collapsed subtree paints\nonce that subtree is expanded.\n\nNamespace-literal: qualified names render exactly as authored, with no namespace-URI-aware\nmatching. Every document type declaration is rejected before `DOMParser`, preventing both\nexternal-entity access and browser-specific internal-entity expansion.\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| `anchor-live-region` | The aria-hidden, non-live shadow mirror of the latest anchor-jump message. |\n| `attribute` | One attribute's name/value pair wrapper (`data-active` while a `node-path` anchor's trailing `'@attrName'` segment addresses this specific attribute). |\n| `attribute-name` | An attribute's name. |\n| `attribute-value` | An attribute's value (`data-match`). |\n| `base` | The root scroll container. |\n| `cdata` | A CDATA section leaf. |\n| `comment` | A comment leaf. |\n| `copy-button` | A copy-to-clipboard button -- the whole-document one (in `toolbar`) or a per-node one (only when `copyable`). |\n| `error` | The error region. |\n| `highlight-action` | The focusable button a resolved `highlights` entry adds to its element row; emits `lr-highlight-activate`. |\n| `node` | One element row (`data-active` while it's the resolved anchor target, `data-match` while any part of it matches the current search, `data-active-match` while it's the currently active search match, `data-highlight` carrying the tone of a `highlights` entry resolved to it, and `data-active-highlight` while that entry is `activeHighlightId`). |\n| `pi` | A processing-instruction leaf. |\n| `spinner` | Visible ordinary loading content with a motion-safe progress indicator. |\n| `tag` | An element's tag name (`data-match`). |\n| `text` | A text leaf (`data-match`). |\n| `toggle` | An element's expand/collapse button (only on elements with renderable children). Its collapsed chevron mirrors with effective RTL direction; the expanded chevron points down in either direction. |\n| `toggle-placeholder` | A non-interactive alignment spacer in place of `toggle` on an empty element. It is accessibility-hidden and cannot be revealed into a phantom control by consumer CSS. |\n| `toolbar` | The whole-document copy button row (only when `copyable`). |\n| `tree` | The rendered node tree. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-xml-viewer-active-attribute-color` (default: `var(--lr-color-brand)`) — Outline color of the `[part=\"attribute\"]` an attribute-addressing `node-path` anchor resolved to.\n- `--lr-xml-viewer-tag-color` (default: `var(--lr-color-brand)`) — Text color of `[part=\"tag\"]`, an element's rendered tag name, independent of the active-attribute outline above.\n- `--lr-xml-viewer-highlight-accent-background` (default: `var(--lr-color-brand-quiet)`) — Row background of an accent-tone (the default tone) `highlights` entry.\n- `--lr-xml-viewer-highlight-success-background` (default: `var(--lr-color-success-quiet)`) — Row background of a success-tone `highlights` entry.\n- `--lr-xml-viewer-highlight-warning-background` (default: `var(--lr-color-warning-quiet)`) — Row background of a warning-tone `highlights` entry.\n- `--lr-xml-viewer-highlight-danger-background` (default: `var(--lr-color-danger-quiet)`) — Row background of a danger-tone `highlights` entry.\n- `--lr-xml-viewer-highlight-neutral-background` (default: `var(--lr-color-surface-raised)`) — Row background of a neutral-tone `highlights` entry. Deliberately not `--lr-color-surface`: the viewer's own ambient background would render a neutral highlight as unhighlighted.\n- `--lr-xml-viewer-highlight-active-outline` (default: `var(--lr-color-brand)`) — Outline color of the `highlights` entry currently named by `activeHighlightId`.\n- `--lr-xml-viewer-max-height` (default: `none`) — Maximum block size of the scrollable body before it scrolls internally. Also settable via the `max-height` property.\n- `--lr-xml-viewer-active-match-color` (default: `var(--lr-color-warning)`) — Outline color of the `[part=\"node\"]` holding the current search match. Scoped to the active match, so the dashed outline on the other matches keeps the shared warning token.\n- `--lr-xml-viewer-match-color` (default: `var(--lr-color-warning)`) — Outline color of a (non-active) `[part=\"node\"]` search match, and the tint source for a matching `[part=\"text\"]`'s background. Distinct from `--lr-xml-viewer-active-match-color`, so the non-active matches can be recolored without touching the active one.\n- `--lr-xml-viewer-match-bg` (default: `var(--lr-color-warning-quiet)`) — Background of a matching `[part=\"tag\"]`/`[part=\"attribute-value\"]`.","attributes":[{"name":"active-highlight-id","description":"Id of the currently active highlight, or null when none is active.\n\nType: `string | null`  \nDefault: `null`"},{"name":"collapsed-depth","description":"Elements at or beyond this nesting depth (root = 0) start collapsed. Omit/undefined:\nnothing auto-collapses.\n\nType: `number | undefined`"},{"name":"copyable","description":"Shows copy-to-clipboard affordances: one for the whole document, plus one per element.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"max-height","description":"A CSS `max-height`; invalid values are ignored.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"name","description":"Display name used as the viewer's accessible label.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"src","description":"URL to fetch and parse as XML. Ignored once `xml` is set.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}}],"js":{"properties":[{"name":"activeHighlightId","description":"Id of the currently active highlight, or null when none is active.\n\nAttribute: `active-highlight-id`","type":"string | null","default":"null"},{"name":"anchor","description":"Anchor or highlight id to resolve and scroll into view.","type":"LyraAnchor | string | null","default":"null"},{"name":"anchorKinds","description":"Anchor kinds this component resolves via `scrollToAnchor()`.","type":"readonly LyraAnchorKind[]","default":"['node-path']","read-only":true},{"name":"collapsedDepth","description":"Elements at or beyond this nesting depth (root = 0) start collapsed. Omit/undefined:\nnothing auto-collapses.\n\nAttribute: `collapsed-depth`","type":"number | undefined"},{"name":"copyable","description":"Shows copy-to-clipboard affordances: one for the whole document, plus one per element.\n\nAttribute: `copyable`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"highlights","description":"Highlights rendered by the document target. Reassign after mutation.","type":"LyraHighlight[]","default":"[]"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"maxHeight","description":"A CSS `max-height`; invalid values are ignored.\n\nAttribute: `max-height`","type":"string","default":"''"},{"name":"name","description":"Display name used as the viewer's accessible label.\n\nAttribute: `name`","type":"string","default":"''"},{"name":"source","description":"Readonly discriminated snapshot of the effective source authority.","type":"LyraXmlViewerSource","read-only":true},{"name":"src","description":"URL to fetch and parse as XML. Ignored once `xml` is set.\n\nAttribute: `src`","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"xml","description":"Raw XML text to parse and render, wins over `src`. Setting this parses synchronously.","type":"string | undefined"}],"events":[{"name":"lr-anchor-result","description":"Fired after an `anchor` property assignment or a `scrollToAnchor()` call is applied. Non-cancelable. `detail: { found }`.","type":"CustomEvent<AnchorResultDetail>"},{"name":"lr-copy","description":"The clipboard write fulfilled. `detail: { ok: true, text }`.","type":"CustomEvent<LyraClipboardWriteSuccess>"},{"name":"lr-copy-error","description":"A clipboard write failed. `detail: { ok: false, text, reason, error }`.","type":"CustomEvent<LyraClipboardWriteFailure>"},{"name":"lr-error","description":"A clipboard write failed; generic no-detail notification.","type":"CustomEvent<null>"},{"name":"lr-highlight-activate","description":"A `highlights` entry's `[part=\"highlight-action\"]` button was activated by click or Enter/Space. Non-cancelable. `detail: { highlightId }`.","type":"CustomEvent<HighlightActivateDetail>"},{"name":"lr-render-error","description":"Fired when fetching or parsing the document fails, including a parse error or exceeding the node cap. `detail: { error }`.","type":"CustomEvent<{ error: unknown }>"},{"name":"lr-search-change","description":"Fired whenever the search query, match count, or active match index changes, including source-reset and effective-locale re-evaluation. `detail: { query, matchCount, matchCountExact, activeIndex }`. Search accepts at most 4,096 query code units, scans at most 4,000,000 tag/attribute/text code units, and retains at most 10,000 matches; a false `matchCountExact` makes `matchCount` a lower bound after any ceiling.","type":"CustomEvent<LyraSearchChangeDetail>"}]}},{"name":"lr-zoomable-frame","description":"`<lr-zoomable-frame>` — a sandboxed iframe preview with discrete zoom controls. Its public\nsurface mirrors Web Awesome's `wa-zoomable-frame`; Lyra's former slotted/image inspection\nsurface now lives at `<lr-pan-zoom>`.\n\nSecurity defaults are deliberately restrictive: iframe navigation accepts only relative,\n`http:`, `https:`, `blob:`, and exact `about:blank` URLs; the iframe always carries a sandbox; and the default\n`allow-same-origin` token supports same-origin `contentDocument`/theme synchronization while\nscripts, forms, popups, downloads, and top navigation remain blocked. Consumer-provided sandbox\ntokens are allowlisted, and `allow-scripts` is never combined with `allow-same-origin`.\n\nThe scaled iframe is a physical pixel canvas, so its origin stays at physical top-left in both\ndirections. The zoom-control group remains logical interface chrome and therefore appears at\ninline-end (physical left in RTL). Its two native buttons remain independent Tab stops; the\ngroup does not claim the roving-arrow-key contract of an ARIA toolbar.\n`withoutInteraction` makes the browsing context genuinely unavailable: the iframe is native\n`inert`, leaves sequential focus, refuses pointer and programmatic activation, and carries no\nunsupported `aria-disabled` claim. Focus entry through Tab, pointer, or `focus()` is tracked on\nthe host as `data-frame-focused` so the shared focus ring remains visible across the browsing-\ncontext boundary. Zoom-control focus does not enter that browsing context; transitions between\na zoom control and the iframe retain one balanced native focus/blur relay pair.\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| `zoom-in-icon` | Override for the decorative zoom-in glyph. Its flattened subtree is inert and hidden from assistive technology; the native zoom-in button remains the sole action. |\n| `zoom-out-icon` | Override for the decorative zoom-out glyph. Its flattened subtree is inert and hidden from assistive technology; the native zoom-out button remains the sole action. |\n\n---\n\n**CSS Shadow Parts**\n\n| Name | Description |\n| --- | --- |\n| `controls` | The labelled zoom-control group. |\n| `iframe` | The internal `<iframe>` element. |\n| `zoom-in-button` | The zoom-in button. |\n| `zoom-out-button` | The zoom-out button. |\n\n---\n\n**CSS Custom Properties**\n\n- `--lr-zoomable-frame-control-hover-background` (default: `var(--lr-color-brand-quiet)`) — Zoom control hover background; its active background derives from the same value.\n- `--lr-zoomable-frame-zoom` (default: `1`) — Read-only resolved iframe scale written from `zoom`.","attributes":[{"name":"allowfullscreen","description":"Forwards the native fullscreen opt-in to the iframe.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"aria-label","description":"Accessible-name input. A declarative `aria-label` remains on the host while the iframe keeps\na localized purpose title; a property-only value names the iframe. An explicitly empty host\nname is preserved as an empty iframe title instead of being replaced through truthiness.\n\nType: `string | null`  \nDefault: `null`"},{"name":"loading","description":"Controls native iframe loading behavior. Invalid runtime values fall back to `eager`.\n\nType: `LyraZoomableFrameLoading`  \nDefault: `'eager'`","value":{"type":["'eager'","'lazy'"]}},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"referrerpolicy","description":"Native iframe referrer policy. Invalid non-empty values fail closed to `no-referrer`.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"sandbox","description":"Iframe sandbox tokens. The attribute is always rendered; the script/same-origin pair is\nnarrowed to scripts in a unique origin.\n\nType: `string`  \nDefault: `'allow-same-origin'`","value":{"type":["string"]}},{"name":"src","description":"The URL of the content to display. Active/non-embeddable schemes are rejected.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"srcdoc","description":"Inline HTML to display. A present `srcdoc` wins over `src`, including an empty attribute.\n\nType: `string`  \nDefault: `''`","value":{"type":["string"]}},{"name":"with-theme-sync","description":"Best-effort sync of Lyra theme classes, attributes, and `--lr-theme-*` values into a\nsame-origin iframe document. Turning it off restores only the iframe state this component\nchanged; cross-origin access remains untouched.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"without-controls","description":"Removes the zoom-control group.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"without-interaction","description":"Removes the iframe from sequential focus and disables pointer interaction.\n\nType: `boolean`  \nDefault: `false`","value":{"type":["boolean"]}},{"name":"zoom","description":"Current iframe scale. Programmatic values need not appear in `zoomLevels`.\n\nType: `number`  \nDefault: `1`","value":{"type":["number"]}},{"name":"zoom-levels","description":"Space-separated decimal and percentage stops used only by `zoomIn()`/`zoomOut()`. The\nnormalized projection reads at most 16,384 UTF-16 code units and 256 whitespace-delimited\ntokens, ignores a token cut by the source ceiling, and is cached until this string changes.\n\nType: `string`  \nDefault: `'25% 50% 75% 100% 125% 150% 175% 200%'`","value":{"type":["string"]}}],"slots":[{"name":"zoom-in-icon","description":"Override for the decorative zoom-in glyph. Its flattened subtree is inert and hidden from assistive technology; the native zoom-in button remains the sole action."},{"name":"zoom-out-icon","description":"Override for the decorative zoom-out glyph. Its flattened subtree is inert and hidden from assistive technology; the native zoom-out button remains the sole action."}],"js":{"properties":[{"name":"accessibleLabel","description":"Accessible-name input. A declarative `aria-label` remains on the host while the iframe keeps\na localized purpose title; a property-only value names the iframe. An explicitly empty host\nname is preserved as an empty iframe title instead of being replaced through truthiness.\n\nAttribute: `aria-label`","type":"string | null","default":"null"},{"name":"allowfullscreen","description":"Forwards the native fullscreen opt-in to the iframe.\n\nAttribute: `allowfullscreen`","type":"boolean","default":"false"},{"name":"contentDocument","description":"Returns the current same-origin iframe document, or `null` when detached/cross-origin.","type":"Document | null","read-only":true},{"name":"contentWindow","description":"Returns the current iframe window while connected. Cross-origin windows are still opaque.","type":"Window | null","read-only":true},{"name":"iframe","description":"The internal iframe; replaced whenever navigation policy changes. An explicit `get` (rather\nthan `@query`) so the generated manifest marks it readonly, not merely by convention.","type":"HTMLIFrameElement | undefined","read-only":true},{"name":"loading","description":"Controls native iframe loading behavior. Invalid runtime values fall back to `eager`.\n\nAttribute: `loading`","type":"LyraZoomableFrameLoading","default":"'eager'"},{"name":"locale","description":"Optional locale override. Otherwise the nearest `locale`/`lang` ancestor is used.\n\nAttribute: `locale`  \nReflected to its attribute.","type":"string","default":"''"},{"name":"referrerpolicy","description":"Native iframe referrer policy. Invalid non-empty values fail closed to `no-referrer`.\n\nAttribute: `referrerpolicy`","type":"string","default":"''"},{"name":"sandbox","description":"Iframe sandbox tokens. The attribute is always rendered; the script/same-origin pair is\nnarrowed to scripts in a unique origin.\n\nAttribute: `sandbox`","type":"string","default":"'allow-same-origin'"},{"name":"src","description":"The URL of the content to display. Active/non-embeddable schemes are rejected.\n\nAttribute: `src`","type":"string","default":"''"},{"name":"srcdoc","description":"Inline HTML to display. A present `srcdoc` wins over `src`, including an empty attribute.\n\nAttribute: `srcdoc`","type":"string","default":"''"},{"name":"strings","description":"Immutable, bounded per-instance message overrides, useful for application-specific wording.\nAssignment snapshots own data-string/plural entries; malformed/accessor entries are omitted\nand later caller mutation cannot alter rendered copy without a new assignment.","type":"LyraLocaleStrings"},{"name":"withThemeSync","description":"Best-effort sync of Lyra theme classes, attributes, and `--lr-theme-*` values into a\nsame-origin iframe document. Turning it off restores only the iframe state this component\nchanged; cross-origin access remains untouched.\n\nAttribute: `with-theme-sync`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"withoutControls","description":"Removes the zoom-control group.\n\nAttribute: `without-controls`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"withoutInteraction","description":"Removes the iframe from sequential focus and disables pointer interaction.\n\nAttribute: `without-interaction`  \nReflected to its attribute.","type":"boolean","default":"false"},{"name":"zoom","description":"Current iframe scale. Programmatic values need not appear in `zoomLevels`.\n\nAttribute: `zoom`  \nReflected to its attribute.","type":"number","default":"1"},{"name":"zoomLevels","description":"Space-separated decimal and percentage stops used only by `zoomIn()`/`zoomOut()`. The\nnormalized projection reads at most 16,384 UTF-16 code units and 256 whitespace-delimited\ntokens, ignores a token cut by the source ceiling, and is cached until this string changes.\n\nAttribute: `zoom-levels`","type":"string","default":"'25% 50% 75% 100% 125% 150% 175% 200%'"}],"events":[{"name":"blur","description":"Relayed once from the internal iframe as a bubbling, composed native event.","type":"FocusEvent"},{"name":"error","description":"Relayed native iframe error event; non-bubbling and non-composed.","type":"Event"},{"name":"focus","description":"Relayed once from the internal iframe as a bubbling, composed native event.","type":"FocusEvent"},{"name":"load","description":"Relayed native iframe load event; non-bubbling and non-composed.","type":"Event"}]}}]},"css":{"properties":[{"name":"--accent-color","description":"**`<lr-data-grid>`** (default: `var(--lr-color-brand)`) — Accent used by focus and active states."},{"name":"--accent-width","description":"**`<lr-toast-item>`** — Mapped alias for `--lr-toast-accent-width`."},{"name":"--animation-delay","description":"**`<lr-icon>`** (default: `0s`) — Delay before an icon animation starts."},{"name":"--animation-direction","description":"**`<lr-icon>`** (default: `normal`) — Playback direction for icon animations."},{"name":"--animation-duration","description":"**`<lr-icon>`** (default: `var(--lr-duration-icon)`) — Duration of one animation cycle.\n\n**`<lr-random-content>`** (default: `300ms`) — Web Awesome duration alias."},{"name":"--animation-easing","description":"**`<lr-random-content>`** (default: `ease`) — Web Awesome easing alias."},{"name":"--animation-iteration-count","description":"**`<lr-icon>`** (default: `infinite`) — Number of animation cycles."},{"name":"--animation-timing","description":"**`<lr-icon>`** (default: `var(--lr-easing-emphasized)`) — Animation timing function."},{"name":"--animation-translate","description":"**`<lr-random-content>`** (default: `var(--lr-size-0-5em)`) — Web Awesome travel-distance alias."},{"name":"--arrow-color","description":"**`<lr-popup>`** (default: `var(--lr-color-surface-raised)`) — Arrow fill."},{"name":"--arrow-size","description":"**`<lr-dropdown>`** (default: `var(--lr-overlay-arrow-size,var(--lr-size-0-375rem))`) — Arrow half-width inherited from the popover surface.\n\n**`<lr-popover>`** (default: `var(--lr-overlay-arrow-size,var(--lr-size-0-375rem))`) — Half-width of the arrow square.\n\n**`<lr-popup>`** (default: `var(--lr-popup-arrow-size,var(--lr-size-0-375rem))`) — Half-width of the arrow square. `--lr-popup-arrow-size` remains a compatibility alias.\n\n**`<lr-tooltip>`** (default: `var(--lr-tooltip-arrow-size,var(--lr-size-0-375rem))`) — Half-width of the arrow square."},{"name":"--aside-width","description":"**`<lr-page>`** — Web Awesome alias for `--lr-page-aside-width`."},{"name":"--aspect-ratio","description":"**`<lr-carousel>`** (default: `16/9`) — Aspect ratio inherited by each slide.\n\n**`<lr-carousel-item>`** — The slide aspect ratio, inherited from an owning carousel by default."},{"name":"--auto-size-available-height","description":"**`<lr-popup>`** — Read-only available block size."},{"name":"--auto-size-available-width","description":"**`<lr-popup>`** — Read-only available inline size."},{"name":"--backdrop-filter","description":"**`<lr-dialog>`, `<lr-drawer>`** (default: `var(--lr-dialog-backdrop-filter,none)`) — Mapped backdrop-filter alias."},{"name":"--background-color","description":"**`<lr-data-grid>`** (default: `var(--lr-color-surface)`) — Grid background."},{"name":"--banner-height","description":"**`<lr-page>`** — Web Awesome alias for `--lr-page-banner-height`."},{"name":"--beat-fade-opacity","description":"**`<lr-icon>`** (default: `0.4`) — Lowest opacity during `beat-fade`."},{"name":"--beat-fade-scale","description":"**`<lr-icon>`** (default: `1.25`) — Peak scale during `beat-fade`."},{"name":"--beat-scale","description":"**`<lr-icon>`** (default: `1.25`) — Scale multiplier for `beat` and `spin-pulse`."},{"name":"--body-spacing","description":"**`<lr-dialog>`** — Shoelace body padding override.\n\n**`<lr-drawer>`** — Shoelace body padding."},{"name":"--border-color","description":"**`<lr-card>`** (default: `var(--lr-color-border)`) — Shoelace-compatible border color.\n\n**`<lr-data-grid>`** (default: `var(--lr-color-border)`) — Grid and cell border color."},{"name":"--border-color-1","description":"**`<lr-bar-chart>`, `<lr-bubble-chart>`, `<lr-chart>`, `<lr-doughnut-chart>`, `<lr-histogram>`, `<lr-line-chart>`, `<lr-pie-chart>`, `<lr-polar-area-chart>`, `<lr-radar-chart>`, `<lr-scatter-chart>`** (default: `var(--lr-color-chart-1)`) — First dataset border color."},{"name":"--border-color-2","description":"**`<lr-bar-chart>`, `<lr-bubble-chart>`, `<lr-chart>`, `<lr-doughnut-chart>`, `<lr-histogram>`, `<lr-line-chart>`, `<lr-pie-chart>`, `<lr-polar-area-chart>`, `<lr-radar-chart>`, `<lr-scatter-chart>`** (default: `var(--lr-color-chart-2)`) — Second dataset border color."},{"name":"--border-color-3","description":"**`<lr-bar-chart>`, `<lr-bubble-chart>`, `<lr-chart>`, `<lr-doughnut-chart>`, `<lr-histogram>`, `<lr-line-chart>`, `<lr-pie-chart>`, `<lr-polar-area-chart>`, `<lr-radar-chart>`, `<lr-scatter-chart>`** (default: `var(--lr-color-chart-3)`) — Third dataset border color."},{"name":"--border-color-4","description":"**`<lr-bar-chart>`, `<lr-bubble-chart>`, `<lr-chart>`, `<lr-doughnut-chart>`, `<lr-histogram>`, `<lr-line-chart>`, `<lr-pie-chart>`, `<lr-polar-area-chart>`, `<lr-radar-chart>`, `<lr-scatter-chart>`** (default: `var(--lr-color-chart-4)`) — Fourth dataset border color."},{"name":"--border-color-5","description":"**`<lr-bar-chart>`, `<lr-bubble-chart>`, `<lr-chart>`, `<lr-doughnut-chart>`, `<lr-histogram>`, `<lr-line-chart>`, `<lr-pie-chart>`, `<lr-polar-area-chart>`, `<lr-radar-chart>`, `<lr-scatter-chart>`** (default: `var(--lr-color-chart-5)`) — Fifth dataset border color."},{"name":"--border-color-6","description":"**`<lr-bar-chart>`, `<lr-bubble-chart>`, `<lr-chart>`, `<lr-doughnut-chart>`, `<lr-histogram>`, `<lr-line-chart>`, `<lr-pie-chart>`, `<lr-polar-area-chart>`, `<lr-radar-chart>`, `<lr-scatter-chart>`** (default: `var(--lr-color-chart-6)`) — Sixth dataset border color."},{"name":"--border-radius","description":"**`<lr-bar-chart>`, `<lr-bubble-chart>`, `<lr-chart>`, `<lr-doughnut-chart>`, `<lr-histogram>`, `<lr-line-chart>`, `<lr-pie-chart>`, `<lr-polar-area-chart>`, `<lr-radar-chart>`, `<lr-scatter-chart>`** (default: `var(--lr-radius)`) — Dataset element corner radius.\n\n**`<lr-card>`** (default: `var(--lr-radius)`) — Shoelace-compatible corner radius.\n\n**`<lr-data-grid>`** (default: `var(--lr-radius)`) — Outer and control corner radius.\n\n**`<lr-skeleton>`** (default: `var(--lr-skeleton-border-radius)`) — Shoelace-compatible corner radius."},{"name":"--border-width","description":"**`<lr-bar-chart>`, `<lr-bubble-chart>`, `<lr-chart>`, `<lr-doughnut-chart>`, `<lr-histogram>`, `<lr-line-chart>`, `<lr-pie-chart>`, `<lr-polar-area-chart>`, `<lr-radar-chart>`, `<lr-scatter-chart>`** (default: `var(--lr-border-width-thin)`) — Dataset element border width.\n\n**`<lr-card>`** (default: `var(--lr-border-width-thin)`) — Shoelace-compatible border width.\n\n**`<lr-data-grid>`** (default: `var(--lr-border-width-thin)`) — Grid and cell border width."},{"name":"--bounce-anticipation","description":"**`<lr-icon>`** (default: `0`) — Downward offset before a bounce."},{"name":"--bounce-height","description":"**`<lr-icon>`** (default: `calc(var(--lr-size-0-5em)*-1)`) — Peak bounce height."},{"name":"--bounce-jump-scale-x","description":"**`<lr-icon>`** (default: `0.95`) — Horizontal scale at the top of a bounce."},{"name":"--bounce-jump-scale-y","description":"**`<lr-icon>`** (default: `1.05`) — Vertical scale at the top of a bounce."},{"name":"--bounce-land-scale-x","description":"**`<lr-icon>`** (default: `1.08`) — Horizontal scale while landing."},{"name":"--bounce-land-scale-y","description":"**`<lr-icon>`** (default: `0.92`) — Vertical scale while landing."},{"name":"--bounce-rebound","description":"**`<lr-icon>`** (default: `calc(var(--lr-size-1em)*-0.1)`) — Landing rebound distance."},{"name":"--bounce-start-scale-x","description":"**`<lr-icon>`** (default: `1`) — Initial horizontal bounce scale."},{"name":"--bounce-start-scale-y","description":"**`<lr-icon>`** (default: `1`) — Initial vertical bounce scale."},{"name":"--buzz-distance","description":"**`<lr-icon>`** (default: `calc(var(--lr-size-1em)*0.12)`) — Horizontal buzz travel."},{"name":"--cell-padding","description":"**`<lr-data-grid>`** (default: `var(--lr-space-m)`) — Header, cell, and footer padding."},{"name":"--checked-icon-color","description":"**`<lr-checkbox>`** (default: `currentColor`) — WA-compatible color of the checked or indeterminate glyph.\n\n**`<lr-radio>`, `<lr-radio-button>`** (default: `var(--lr-radio-checked-dot-color)`) — WA-compatible selected-glyph color alias."},{"name":"--checked-icon-scale","description":"**`<lr-checkbox>`** (default: `1`) — WA-compatible scale of the checked or indeterminate glyph.\n\n**`<lr-radio>`, `<lr-radio-button>`** (default: `1`) — WA-compatible selected-glyph scale alias."},{"name":"--color","description":"**`<lr-divider>`** (default: `var(--lr-color-border)`) — Separator color.\n\n**`<lr-skeleton>`** (default: `var(--lr-skeleton-color)`) — Upstream-compatible placeholder color."},{"name":"--column-item-height","description":"**`<lr-time-input>`** (default: `calc(var(--lr-size-1em)*2.25)`) — Picker row height."},{"name":"--column-width","description":"**`<lr-time-input>`** (default: `calc(var(--lr-size-1em)*3)`) — Picker column width."},{"name":"--control-box-size","description":"**`<lr-animated-image>`** — Upstream-compatible alias for `--lr-animated-image-control-box-size`."},{"name":"--controls-background","description":"**`<lr-video>`** (default: `var(--lr-color-overlay-strong)`) — Controls, captions, and title overlay background."},{"name":"--controls-color","description":"**`<lr-video>`** (default: `var(--lr-color-on-strong-overlay)`) — Custom-control foreground color. The poster play action defaults to `var(--lr-color-text)` against its surface background."},{"name":"--current-text-color","description":"**`<lr-option>`** (default: `var(--lr-color-text)`) — Text color while the option is `current`."},{"name":"--divider-hit-area","description":"**`<lr-split-panel>`** (default: `12px`) — Requested divider hit area; Lyra's minimum hit-area token remains the floor."},{"name":"--divider-width","description":"**`<lr-image-comparer>`** (default: `var(--lr-size-1px)`) — Retained Shoelace-compat source for `--lr-image-comparer-divider-width`.\n\n**`<lr-split-panel>`** (default: `4px`) — Visible divider thickness."},{"name":"--easing","description":"**`<lr-accordion-item>`** — Upstream-compatible alias for `--lr-accordion-item-easing`."},{"name":"--error-color","description":"**`<lr-copy-button>`** (default: `var(--lr-color-danger)`) — Error-state icon color."},{"name":"--fade-opacity","description":"**`<lr-icon>`** (default: `0.4`) — Lowest opacity during `fade` and `spin-pulse`."},{"name":"--fill-color","description":"**`<lr-sparkline>`** (default: `var(--lr-color-brand-quiet)`) — Area fill color. A `trend` supplies a semantic token default, while an authored value always wins."},{"name":"--fill-color-1","description":"**`<lr-bar-chart>`, `<lr-bubble-chart>`, `<lr-chart>`, `<lr-doughnut-chart>`, `<lr-histogram>`, `<lr-line-chart>`, `<lr-pie-chart>`, `<lr-polar-area-chart>`, `<lr-radar-chart>`, `<lr-scatter-chart>`** (default: `var(--lr-color-chart-1)`) — First dataset fill color."},{"name":"--fill-color-2","description":"**`<lr-bar-chart>`, `<lr-bubble-chart>`, `<lr-chart>`, `<lr-doughnut-chart>`, `<lr-histogram>`, `<lr-line-chart>`, `<lr-pie-chart>`, `<lr-polar-area-chart>`, `<lr-radar-chart>`, `<lr-scatter-chart>`** (default: `var(--lr-color-chart-2)`) — Second dataset fill color."},{"name":"--fill-color-3","description":"**`<lr-bar-chart>`, `<lr-bubble-chart>`, `<lr-chart>`, `<lr-doughnut-chart>`, `<lr-histogram>`, `<lr-line-chart>`, `<lr-pie-chart>`, `<lr-polar-area-chart>`, `<lr-radar-chart>`, `<lr-scatter-chart>`** (default: `var(--lr-color-chart-3)`) — Third dataset fill color."},{"name":"--fill-color-4","description":"**`<lr-bar-chart>`, `<lr-bubble-chart>`, `<lr-chart>`, `<lr-doughnut-chart>`, `<lr-histogram>`, `<lr-line-chart>`, `<lr-pie-chart>`, `<lr-polar-area-chart>`, `<lr-radar-chart>`, `<lr-scatter-chart>`** (default: `var(--lr-color-chart-4)`) — Fourth dataset fill color."},{"name":"--fill-color-5","description":"**`<lr-bar-chart>`, `<lr-bubble-chart>`, `<lr-chart>`, `<lr-doughnut-chart>`, `<lr-histogram>`, `<lr-line-chart>`, `<lr-pie-chart>`, `<lr-polar-area-chart>`, `<lr-radar-chart>`, `<lr-scatter-chart>`** (default: `var(--lr-color-chart-5)`) — Fifth dataset fill color."},{"name":"--fill-color-6","description":"**`<lr-bar-chart>`, `<lr-bubble-chart>`, `<lr-chart>`, `<lr-doughnut-chart>`, `<lr-histogram>`, `<lr-line-chart>`, `<lr-pie-chart>`, `<lr-polar-area-chart>`, `<lr-radar-chart>`, `<lr-scatter-chart>`** (default: `var(--lr-color-chart-6)`) — Sixth dataset fill color."},{"name":"--flip-angle","description":"**`<lr-icon>`** (default: `180deg`) — Rotation angle for flip treatments."},{"name":"--flip-anticipation-scale","description":"**`<lr-icon>`** (default: `0.9`) — Wind-up scale before a flip."},{"name":"--flip-overshoot","description":"**`<lr-icon>`** (default: `0deg`) — Extra angle before a flip settles."},{"name":"--flip-x","description":"**`<lr-icon>`** (default: `0`) — X coordinate of the flip rotation axis."},{"name":"--flip-y","description":"**`<lr-icon>`** (default: `1`) — Y coordinate of the flip rotation axis."},{"name":"--flip-z","description":"**`<lr-icon>`** (default: `0`) — Z coordinate of the flip rotation axis."},{"name":"--float-drift","description":"**`<lr-icon>`** (default: `0`) — Horizontal float drift."},{"name":"--float-height","description":"**`<lr-icon>`** (default: `calc(var(--lr-size-0-5em)*-1)`) — Float rise height."},{"name":"--float-squash-x","description":"**`<lr-icon>`** (default: `1.04`) — Resting horizontal float scale."},{"name":"--float-squash-y","description":"**`<lr-icon>`** (default: `0.96`) — Resting vertical float scale."},{"name":"--float-stretch-x","description":"**`<lr-icon>`** (default: `0.96`) — Peak horizontal float scale."},{"name":"--float-stretch-y","description":"**`<lr-icon>`** (default: `1.04`) — Peak vertical float scale."},{"name":"--float-tilt","description":"**`<lr-icon>`** (default: `4deg`) — Rotation at the float peak."},{"name":"--focus-ring","description":"**`<lr-data-grid>`** (default: `var(--lr-focus-ring-width) solid var(--lr-focus-ring-color)`) — Focus ring."},{"name":"--footer-spacing","description":"**`<lr-dialog>`** — Shoelace footer padding override.\n\n**`<lr-drawer>`** — Shoelace footer padding."},{"name":"--gap","description":"**`<lr-checkbox-group>`** (default: `var(--lr-checkbox-group-option-gap)`) — WA-compatible option gap.\n\n**`<lr-toast>`** — Mapped alias for `--lr-toast-gap`."},{"name":"--grid-border-width","description":"**`<lr-bar-chart>`, `<lr-bubble-chart>`, `<lr-chart>`, `<lr-doughnut-chart>`, `<lr-histogram>`, `<lr-line-chart>`, `<lr-pie-chart>`, `<lr-polar-area-chart>`, `<lr-radar-chart>`, `<lr-scatter-chart>`** (default: `var(--lr-border-width-thin)`) — Axis and grid line width."},{"name":"--grid-color","description":"**`<lr-bar-chart>`, `<lr-bubble-chart>`, `<lr-chart>`, `<lr-doughnut-chart>`, `<lr-histogram>`, `<lr-line-chart>`, `<lr-pie-chart>`, `<lr-polar-area-chart>`, `<lr-radar-chart>`, `<lr-scatter-chart>`** (default: `var(--lr-chart-grid-color)`) — Grid line color."},{"name":"--grid-handle-size","description":"**`<lr-color-picker>`** — Upstream alias for `--lr-color-picker-grid-handle-size`."},{"name":"--grid-height","description":"**`<lr-color-picker>`** — Upstream alias for `--lr-color-picker-grid-block-size`."},{"name":"--grid-width","description":"**`<lr-color-picker>`** — Upstream alias for `--lr-color-picker-grid-inline-size`."},{"name":"--handle-size","description":"**`<lr-image-comparer>`** (default: `var(--lr-icon-button-size)`) — Retained Shoelace-compat source for `--lr-image-comparer-handle-size`."},{"name":"--header-background","description":"**`<lr-data-grid>`** (default: `var(--lr-color-surface-raised)`) — Header background."},{"name":"--header-height","description":"**`<lr-page>`** — Web Awesome alias for `--lr-page-header-height`."},{"name":"--header-row-height","description":"**`<lr-data-grid>`** (default: `var(--lr-size-3-5rem)`) — Header-row minimum height."},{"name":"--header-spacing","description":"**`<lr-dialog>`** — Mapped header padding override.\n\n**`<lr-drawer>`** — Shoelace header padding."},{"name":"--header-text-color","description":"**`<lr-data-grid>`** (default: `var(--lr-color-text)`) — Header foreground."},{"name":"--height","description":"**`<lr-progress-bar>`** (default: `var(--lr-progress-track-height)`) — Shoelace-compatible track height.\n\n**`<lr-switch>`** (default: `var(--lr-switch-track-block-size)`) — WA/Shoelace alias for the track's block size."},{"name":"--hide-delay","description":"**`<lr-tooltip>`** (default: `0ms`) — Interaction hide delay when `hide-delay` is not explicit."},{"name":"--hide-duration","description":"**`<lr-accordion-item>`** — Upstream-compatible alias for `--lr-accordion-item-hide-duration`.\n\n**`<lr-combobox>`** (default: `var(--lr-transition-fast)`) — Listbox exit-transition duration.\n\n**`<lr-date-input>`** (default: `var(--lr-transition-fast)`) — Popup exit-transition duration.\n\n**`<lr-details>`** (default: `var(--lr-duration-base)`) — Collapse-icon transition duration.\n\n**`<lr-dialog>`** — Mapped closing animation duration.\n\n**`<lr-drawer>`** — Closing slide duration.\n\n**`<lr-dropdown>`** (default: `var(--lr-transition-fast)`) — Closing transition duration.\n\n**`<lr-popover>`** (default: `var(--lr-duration-fast)`) — Closing transition duration.\n\n**`<lr-popup>`** (default: `var(--lr-duration-fast)`) — Deactivation transition duration.\n\n**`<lr-select>`** (default: `var(--lr-transition-fast)`) — Listbox exit-transition timing.\n\n**`<lr-time-input>`** (default: `var(--lr-duration-fast)`) — Picker closing duration.\n\n**`<lr-toast-item>`** — Mapped alias for `--lr-toast-hide-duration`.\n\n**`<lr-tree-item>`** (default: `var(--lr-duration-base)`) — Collapse motion duration."},{"name":"--icon-size","description":"**`<lr-animated-image>`** — Upstream-compatible alias for `--lr-animated-image-icon-size`."},{"name":"--indent-guide-color","description":"**`<lr-tree>`, `<lr-tree-item>`** (default: `var(--lr-color-border)`) — Indentation guide color."},{"name":"--indent-guide-offset","description":"**`<lr-tree>`** (default: `0`) — Block-axis inset for indentation guides.\n\n**`<lr-tree-item>`** (default: `0`) — Block-axis inset at both ends of the indentation guide."},{"name":"--indent-guide-style","description":"**`<lr-tree>`, `<lr-tree-item>`** (default: `solid`) — Indentation guide border style."},{"name":"--indent-guide-width","description":"**`<lr-tree>`, `<lr-tree-item>`** (default: `0`) — Indentation guide width."},{"name":"--indent-size","description":"**`<lr-data-grid>`** (default: `var(--lr-size-1-25rem)`) — Tree-level indentation.\n\n**`<lr-tree>`** (default: `var(--lr-space-l)`) — Indentation step for nested items.\n\n**`<lr-tree-item>`** (default: `var(--lr-space-l)`) — Indentation step applied once per nesting depth."},{"name":"--indicator-color","description":"**`<lr-progress-bar>`** (default: `var(--lr-progress-indicator-color)`) — Upstream-compatible indicator color.\n\n**`<lr-progress-ring>`** (default: `var(--lr-progress-ring-indicator-color)`) — Upstream-compatible indicator color.\n\n**`<lr-spinner>`** (default: `var(--lr-color-brand)`) — Upstream-compatible indicator color.\n\n**`<lr-tab-group>`** — Upstream alias for the active indicator color."},{"name":"--indicator-transition-duration","description":"**`<lr-progress-ring>`** (default: `var(--lr-progress-ring-indicator-transition-duration)`) — Upstream-compatible transition duration."},{"name":"--indicator-width","description":"**`<lr-progress-ring>`** (default: `var(--lr-progress-ring-indicator-width)`) — Upstream-compatible indicator width."},{"name":"--jello-scale-x","description":"**`<lr-icon>`** (default: `1.18`) — Horizontal jello stretch."},{"name":"--jello-scale-y","description":"**`<lr-icon>`** (default: `0.82`) — Vertical jello stretch."},{"name":"--label-color","description":"**`<lr-progress-bar>`** (default: `var(--lr-progress-label-color)`) — Shoelace-compatible label color."},{"name":"--line-border-width","description":"**`<lr-bar-chart>`, `<lr-bubble-chart>`, `<lr-chart>`, `<lr-doughnut-chart>`, `<lr-histogram>`, `<lr-line-chart>`, `<lr-pie-chart>`, `<lr-polar-area-chart>`, `<lr-radar-chart>`, `<lr-scatter-chart>`** (default: `var(--lr-border-width-medium)`) — Line dataset stroke width."},{"name":"--line-color","description":"**`<lr-sparkline>`** (default: `var(--lr-color-brand)`) — Trend line color. A `trend` supplies a semantic token default, while an authored value always wins."},{"name":"--line-width","description":"**`<lr-sparkline>`** (default: `var(--lr-border-width-medium)`) — Trend line width."},{"name":"--lr-accordion-filled-bg","description":"**`<lr-accordion>`** (default: `var(--lr-color-surface-raised)`) — Filled group background."},{"name":"--lr-accordion-filled-border-color","description":"**`<lr-accordion>`** (default: `transparent`) — Filled border color."},{"name":"--lr-accordion-filled-outlined-bg","description":"**`<lr-accordion>`** (default: `var(--lr-color-surface-raised)`) — Filled-outlined group background."},{"name":"--lr-accordion-filled-outlined-border-color","description":"**`<lr-accordion>`** (default: `var(--lr-color-border)`) — Filled-outlined border color."},{"name":"--lr-accordion-item-button-active-bg","description":"**`<lr-accordion-item>`** (default: `color-mix(...)`) — Trigger pressed background."},{"name":"--lr-accordion-item-button-hover-bg","description":"**`<lr-accordion-item>`** (default: `var(--lr-color-brand-quiet)`) — Trigger hover background."},{"name":"--lr-accordion-item-easing","description":"**`<lr-accordion-item>`** (default: `var(--lr-easing-standard)`) — Expand/collapse easing."},{"name":"--lr-accordion-item-filled-bg","description":"**`<lr-accordion-item>`** (default: `var(--lr-color-surface-raised)`) — Filled item background."},{"name":"--lr-accordion-item-filled-outlined-bg","description":"**`<lr-accordion-item>`** (default: `var(--lr-color-surface-raised)`) — Filled-outlined item background."},{"name":"--lr-accordion-item-hide-duration","description":"**`<lr-accordion-item>`** (default: `var(--lr-duration-base)`) — Collapse transition duration."},{"name":"--lr-accordion-item-outlined-bg","description":"**`<lr-accordion-item>`** (default: `var(--lr-color-surface)`) — Outlined item background."},{"name":"--lr-accordion-item-show-duration","description":"**`<lr-accordion-item>`** (default: `var(--lr-duration-base)`) — Expand transition duration."},{"name":"--lr-accordion-item-spacing","description":"**`<lr-accordion-item>`** (default: `var(--lr-form-control-padding-inline)`) — Header/content spacing."},{"name":"--lr-accordion-outlined-bg","description":"**`<lr-accordion>`** (default: `var(--lr-color-surface)`) — Outlined group background."},{"name":"--lr-accordion-outlined-border-color","description":"**`<lr-accordion>`** (default: `var(--lr-color-border)`) — Outlined border color."},{"name":"--lr-activity-feed-background","description":"**`<lr-activity-feed>`** (default: `var(--lr-color-surface)`) — Fill of the outer card (`[part=\"base\"]`) while `frame=\"card\"`. `frame=\"plain\"` still removes the fill entirely."},{"name":"--lr-activity-feed-border-color","description":"**`<lr-activity-feed>`** (default: `var(--lr-color-border)`) — Colour of the outer card's border and of the header/body divider, which `frame=\"plain\"` keeps."},{"name":"--lr-activity-feed-compact-entry-padding","description":"**`<lr-activity-feed>`** (default: `var(--lr-space-2xs) var(--lr-space-s)`) — `[part=\"entry\"]` padding while `compact`."},{"name":"--lr-activity-feed-compact-header-gap","description":"**`<lr-activity-feed>`** (default: `var(--lr-space-2xs)`) — Gap between the header toggle, status dot, label, and summary while `compact`."},{"name":"--lr-activity-feed-compact-header-padding","description":"**`<lr-activity-feed>`** (default: `var(--lr-space-2xs) var(--lr-space-s)`) — `[part=\"header\"]` padding while `compact`."},{"name":"--lr-activity-feed-live-status-color","description":"**`<lr-activity-feed>`** (default: `var(--lr-color-brand)`) — Background color of `status-dot` while `mode=\"live\"`."},{"name":"--lr-activity-feed-max-height","description":"**`<lr-activity-feed>`** (default: `16rem`) — Cap on how tall the expanded body grows before it scrolls internally (non-virtualized mode); also sizes the internal virtual-list."},{"name":"--lr-activity-feed-radius","description":"**`<lr-activity-feed>`** (default: `var(--lr-radius)`) — Corner radius of the outer card. `frame=\"plain\"` still squares the corners."},{"name":"--lr-agent-eval-dashboard-active-background","description":"**`<lr-agent-eval-dashboard>`** (default: `var(--lr-color-brand-quiet)`) — Active metric background."},{"name":"--lr-agent-eval-dashboard-active-border","description":"**`<lr-agent-eval-dashboard>`** (default: `var(--lr-color-brand)`) — Active metric border."},{"name":"--lr-agent-run-background","description":"**`<lr-agent-run>`** (default: `var(--lr-color-surface)`) — Fill of the outer card (`[part=\"base\"]`) while `frame=\"card\"`. `frame=\"plain\"` still removes the fill entirely."},{"name":"--lr-agent-run-border-color","description":"**`<lr-agent-run>`** (default: `var(--lr-color-border)`) — Colour of the outer card's border."},{"name":"--lr-agent-run-compact-gap","description":"**`<lr-agent-run>`** (default: `var(--lr-space-s)`) — Gap between `[part=\"base\"]`'s header and body while `compact`."},{"name":"--lr-agent-run-compact-padding","description":"**`<lr-agent-run>`** (default: `var(--lr-space-s)`) — `[part=\"base\"]` padding while `compact`."},{"name":"--lr-agent-run-metric-brand-color","description":"**`<lr-agent-run>`** (default: `var(--lr-color-brand)`) — Brand metric value."},{"name":"--lr-agent-run-metric-danger-color","description":"**`<lr-agent-run>`** (default: `var(--lr-color-danger)`) — Danger metric value."},{"name":"--lr-agent-run-metric-success-color","description":"**`<lr-agent-run>`** (default: `var(--lr-color-success)`) — Success metric value."},{"name":"--lr-agent-run-metric-warning-color","description":"**`<lr-agent-run>`** (default: `var(--lr-color-warning)`) — Warning metric value."},{"name":"--lr-agent-run-radius","description":"**`<lr-agent-run>`** (default: `var(--lr-radius)`) — Corner radius of the outer card. `frame=\"plain\"` still squares the corners."},{"name":"--lr-agent-run-spin","description":"**`<lr-agent-run>`** (default: `var(--lr-transition-ambient)`) — Current-step icon spin animation."},{"name":"--lr-agent-trace-handoff-active-bg","description":"**`<lr-agent-trace>`** (default: `var(--lr-color-brand-quiet)`) — Background of the active (`activeSpanId`) handoff quick-jump entry. Shadow Parts forbids an attribute selector after `::part()`, so the active entry could otherwise only be restyled by hijacking the library-wide `--lr-color-brand-quiet` token."},{"name":"--lr-alert-close-active-bg","description":"**`<lr-alert>`** (default: `color-mix(in oklab,transparent,var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — The close button's pressed background, independently scoped from `--lr-alert-close-hover-bg`."},{"name":"--lr-alert-close-hover-bg","description":"**`<lr-alert>`** (default: `color-mix(in oklab,transparent,var(--lr-color-mix-partner) var(--lr-color-mix-hover))`) — The close button's hover background, scoped so a consumer can retint just this control without touching the shared `--lr-color-mix-partner`/`--lr-color-mix-hover` tokens every other interactive surface in the library also reads."},{"name":"--lr-animated-image-control-box-size","description":"**`<lr-animated-image>`** — The size of `control-box`. Defaults to `var(--lr-icon-button-size)`."},{"name":"--lr-animated-image-icon-size","description":"**`<lr-animated-image>`** — The size of the play/pause icons. Defaults to `calc(var(--lr-icon-button-size) * 0.35)`."},{"name":"--lr-animated-image-max-height","description":"**`<lr-animated-image>`** — Caps the rendered media's block-size. Defaults to `var(--lr-size-20rem)`."},{"name":"--lr-animation-bounce-height","description":"**`<lr-animation>`** (default: `25%`) — Peak lift height of the bounce preset."},{"name":"--lr-animation-duration","description":"**`<lr-random-content>`** (default: `300ms`) — Mapped duration of the entrance animation."},{"name":"--lr-animation-easing","description":"**`<lr-random-content>`** (default: `ease`) — Mapped easing function for the entrance animation."},{"name":"--lr-animation-shake-distance","description":"**`<lr-animation>`** (default: `4%`) — Horizontal travel of the shake preset."},{"name":"--lr-animation-slide-distance","description":"**`<lr-animation>`** (default: `100%`) — Travel distance for the slide-in/slide-out/slide-in-up/slide-in-down presets."},{"name":"--lr-animation-translate","description":"**`<lr-random-content>`** (default: `var(--lr-size-0-5em)`) — Mapped travel distance for directional animations."},{"name":"--lr-animation-zoom-scale","description":"**`<lr-animation>`** (default: `0.5`) — Starting/ending scale factor for the zoom-in/zoom-out presets."},{"name":"--lr-app-rail-background","description":"**`<lr-app-rail>`** (default: `var(--lr-color-surface)`) — `[part=\"base\"]`'s background (the docked, non-overlay presentation)."},{"name":"--lr-app-rail-collapse-toggle-active-bg","description":"**`<lr-app-rail>`** — Collapse-control pressed background; defaults to the same brand-quiet active mix `[part=\"toggle\"]` uses."},{"name":"--lr-app-rail-collapse-toggle-active-color","description":"**`<lr-app-rail>`** (default: `var(--lr-color-brand)`) — Collapse-control pressed foreground."},{"name":"--lr-app-rail-collapse-toggle-hover-bg","description":"**`<lr-app-rail>`** (default: `var(--lr-color-brand-quiet)`) — Collapse-control hover background."},{"name":"--lr-app-rail-collapse-toggle-hover-color","description":"**`<lr-app-rail>`** (default: `var(--lr-color-brand)`) — Collapse-control hover foreground."},{"name":"--lr-app-rail-footer-padding","description":"**`<lr-app-rail>`** (default: `var(--lr-space-m)`) — `[part=\"footer\"]`'s padding."},{"name":"--lr-app-rail-group-active-bg","description":"**`<lr-app-rail-group>`** — Collapse-control pressed background; defaults to the same brand-quiet active mix the rest of the rail uses."},{"name":"--lr-app-rail-group-active-color","description":"**`<lr-app-rail-group>`** (default: `var(--lr-color-brand)`) — Collapse-control pressed foreground."},{"name":"--lr-app-rail-group-gap","description":"**`<lr-app-rail-group>`** (default: `var(--lr-space-xs)`) — Gap between the group's own items."},{"name":"--lr-app-rail-group-heading-color","description":"**`<lr-app-rail-group>`** (default: `var(--lr-color-text-quiet)`) — Heading text color."},{"name":"--lr-app-rail-group-heading-font-size","description":"**`<lr-app-rail-group>`** (default: `var(--lr-font-size-sm)`) — Heading font size."},{"name":"--lr-app-rail-group-hover-bg","description":"**`<lr-app-rail-group>`** (default: `var(--lr-color-brand-quiet)`) — Collapse-control hover background."},{"name":"--lr-app-rail-group-hover-color","description":"**`<lr-app-rail-group>`** (default: `var(--lr-color-brand)`) — Collapse-control hover foreground."},{"name":"--lr-app-rail-group-padding-block","description":"**`<lr-app-rail-group>`** (default: `var(--lr-space-xs)`) — Block padding around `[part=\"base\"]`."},{"name":"--lr-app-rail-header-min-block-size","description":"**`<lr-app-rail>`** (default: `auto`) — `[part=\"header\"]`'s minimum block size. `auto` (the default) is the property's own initial value, so unset reproduces today's exact height; set it to reserve room for header content that mounts or resizes asynchronously."},{"name":"--lr-app-rail-header-padding","description":"**`<lr-app-rail>`** (default: `var(--lr-space-m)`) — `[part=\"header\"]`'s padding."},{"name":"--lr-app-rail-icon-width","description":"**`<lr-app-rail>`** (default: `var(--lr-size-4rem)`) — The inline rail's width in `'icon-only'` mode, and the maximum width of each slotted `<lr-app-rail-item>` in that mode."},{"name":"--lr-app-rail-item-active-bg","description":"**`<lr-app-rail-item>`** — Pressed background; defaults to the former brand-quiet active mix."},{"name":"--lr-app-rail-item-active-color","description":"**`<lr-app-rail-item>`** (default: `var(--lr-color-brand)`) — Pressed text/icon color."},{"name":"--lr-app-rail-item-current-bg","description":"**`<lr-app-rail-item>`** (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."},{"name":"--lr-app-rail-item-current-color","description":"**`<lr-app-rail-item>`** (default: `var(--lr-color-brand)`) — Text/icon color of the `current`/`aria-current=\"page\"` item."},{"name":"--lr-app-rail-item-current-font-weight","description":"**`<lr-app-rail-item>`** (default: `var(--lr-font-weight-semibold)`) — Font weight of the `current`/`aria-current=\"page\"` item, decoupled from the shared `--lr-font-weight-semibold` token so retheming it does not repaint every other semibold element on the page. Mirrors `<lr-stepper>`'s `--lr-stepper-current-font-weight` and `<lr-segmented>`'s `--lr-segmented-selected-font-weight`."},{"name":"--lr-app-rail-item-current-indicator-color","description":"**`<lr-app-rail-item>`** (default: `var(--lr-color-brand)`) — Color of the decorative `[part=\"current-indicator\"]` while current."},{"name":"--lr-app-rail-item-current-indicator-display","description":"**`<lr-app-rail-item>`** — `[part=\"current-indicator\"]`'s `display` while `icon-only`. Unset (the default), the indicator is suppressed there -- a full-height edge bar on the square icon-only tile reads as a rendering glitch. Set to `block` (or any non-`none` display) to restore it. Full presentation is unaffected either way; its own `[part=\"current-indicator\"]` rule declares no `display` at all."},{"name":"--lr-app-rail-item-current-indicator-inset-inline","description":"**`<lr-app-rail-item>`** (default: `0 auto`) — Logical inline-start and inline-end insets for `[part=\"current-indicator\"]`; set `auto 0` to place it at inline-end."},{"name":"--lr-app-rail-item-current-indicator-width","description":"**`<lr-app-rail-item>`** (default: `var(--lr-size-2px)`) — Inline size of `[part=\"current-indicator\"]` while current."},{"name":"--lr-app-rail-item-current-ring","description":"**`<lr-app-rail-item>`** — `box-shadow` on `[part=\"base\"]` while `current`/`aria-current=\"page\"`. Unset, icon-only gets an inset ring by default -- the non-color-only signal that replaces the indicator bar suppressed there (WCAG 1.4.1); full presentation, which already conveys current state through the indicator bar and `--lr-app-rail-item-current-font-weight`, stays ring-free (`none`) by default. Setting this token explicitly applies the same value in both presentations."},{"name":"--lr-app-rail-item-font-size","description":"**`<lr-app-rail-item>`** (default: `inherit`) — `[part=\"base\"]`'s font size, set after the `font` shorthand so it alone can be retuned while family/weight/line-height stay inherited."},{"name":"--lr-app-rail-item-gap","description":"**`<lr-app-rail-item>`** (default: `var(--lr-space-s)`) — Gap between `[part=\"icon\"]` and `[part=\"label\"]`, and between the item's own control and its `[part=\"meta\"]`/`[part=\"end\"]` adornments."},{"name":"--lr-app-rail-item-hover-bg","description":"**`<lr-app-rail-item>`** (default: `var(--lr-color-brand-quiet)`) — Hover background."},{"name":"--lr-app-rail-item-hover-color","description":"**`<lr-app-rail-item>`** (default: `var(--lr-color-brand)`) — Hover text/icon color."},{"name":"--lr-app-rail-item-icon-only-size","description":"**`<lr-app-rail-item>`** — When set, sizes `[part=\"base\"]`'s icon-only square (`inline-size` and `block-size` alike) directly, independent of the row's own `--lr-app-rail-item-min-block-size`. Unset (the default), the square is still derived via `aspect-ratio: 1` against the row's block size, exactly as before. Still floor-clamped to `--lr-icon-button-size` by `[part=\"base\"]`'s shared `min-block-size` rule."},{"name":"--lr-app-rail-item-icon-size","description":"**`<lr-app-rail-item>`** (default: `var(--lr-icon-button-size)`) — `[part=\"icon\"]`'s inline size. Not floor-clamped -- the icon is decorative, not itself a pointer target."},{"name":"--lr-app-rail-item-indent","description":"**`<lr-app-rail-item>`** (default: `var(--lr-space-l)`) — `[part=\"children\"]`'s `padding-inline-start`. Applied once per nesting level -- a doubly-nested `children` list compounds two insets automatically, since each level's own `[part=\"children\"]` applies the token again. Logical, so it mirrors under `dir=\"rtl\"` with no separate rule."},{"name":"--lr-app-rail-item-meta-color","description":"**`<lr-app-rail-item>`** (default: `var(--lr-color-text-quiet)`) — `[part=\"meta\"]`'s text color; quiet by default so a count reads as secondary to the label beside it."},{"name":"--lr-app-rail-item-meta-font-size","description":"**`<lr-app-rail-item>`** (default: `var(--lr-font-size-sm)`) — `[part=\"meta\"]`'s font size."},{"name":"--lr-app-rail-item-min-block-size","description":"**`<lr-app-rail-item>`** (default: `var(--lr-icon-button-size)`) — `[part=\"base\"]`'s row height. Floor-clamped to `--lr-icon-button-size` regardless of the override, preserving the WCAG 2.5.8 hit-area minimum."},{"name":"--lr-app-rail-item-padding","description":"**`<lr-app-rail-item>`** (default: `var(--lr-space-s)`) — `[part=\"base\"]`'s padding."},{"name":"--lr-app-rail-mobile-width","description":"**`<lr-app-rail>`** (default: `var(--lr-size-18rem)`) — The mobile overlay panel's width, capped at `85vw`."},{"name":"--lr-app-rail-nav-gap","description":"**`<lr-app-rail>`** (default: `var(--lr-space-xs)`) — Gap between slotted items inside `[part=\"nav\"]`, unset reproducing the value this rule hard-coded before the token existed."},{"name":"--lr-app-rail-nav-padding","description":"**`<lr-app-rail>`** (default: `var(--lr-space-s)`) — `[part=\"nav\"]`'s padding, unset reproducing the value this rule hard-coded before the token existed."},{"name":"--lr-app-rail-overlay-color","description":"**`<lr-app-rail>`** (default: `var(--lr-color-overlay)`) — The mobile overlay scrim's background."},{"name":"--lr-app-rail-panel-background","description":"**`<lr-app-rail>`** (default: `var(--lr-color-surface-overlay)`) — `[part=\"panel\"]`'s background (the mobile overlay presentation) -- kept separate from `--lr-app-rail-background`/`--lr-app-rail-overlay-color` (the backdrop scrim) since the panel is deliberately themed as a modal surface, not the docked rail chrome."},{"name":"--lr-app-rail-panel-inset-block-start","description":"**`<lr-app-rail>`** (default: `0`) — Block-start (top) inset shared by `[part=\"panel\"]` and `[part=\"backdrop\"]` -- raise it to leave room for a fixed app bar/status area above the drawer instead of the panel/scrim starting flush with the viewport top."},{"name":"--lr-app-rail-panel-overflow-block","description":"**`<lr-app-rail>`** (default: `auto`) — `[part=\"panel\"]`'s logical `overflow-block`, paired with `--lr-app-rail-panel-overflow-inline` below."},{"name":"--lr-app-rail-panel-overflow-inline","description":"**`<lr-app-rail>`** (default: `clip`) — `[part=\"panel\"]`'s logical `overflow-inline`. `clip` (the default) prevents a spurious horizontal scrollbar from wide slotted header/footer content, but also clips a `position: fixed` popup opened by a slotted/nav-item control (e.g. a slotted `<lr-select>`/`<lr-menu>`) whenever that popup's rendered box extends past the panel's own inline bounds -- a `position: fixed` box is clipped by an ancestor's non-`visible` overflow regardless of its own containing block. Setting only this one to `visible` is not enough to escape that: per the CSS overflow spec, a lone `visible` axis paired with a non-`visible` other axis computes as `auto` instead, which still clips -- set `--lr-app-rail-panel-overflow-block` to `visible` too to actually stop the clipping, accepting that wide header/footer content can then scroll/bleed both ways instead."},{"name":"--lr-app-rail-panel-radius","description":"**`<lr-app-rail>`** (default: `0`) — Uniform corner radius of `[part=\"panel\"]`. `0` (the default) reproduces today's flush-edged drawer; pairs naturally with a nonzero `--lr-app-rail-panel-inset-block-start`, which exposes the panel's top corners. Each per-corner token below defaults to this one, so setting only this token still rounds all four corners uniformly, exactly as before the per-corner tokens existed."},{"name":"--lr-app-rail-panel-radius-end-end","description":"**`<lr-app-rail>`** (default: `var(--lr-app-rail-panel-radius)`) — Logical `border-end-end-radius` of `[part=\"panel\"]` -- the corner away from the flush inline-start edge, block-end side. The other corner a flush-against-one-edge drawer typically rounds. All four per-corner tokens are logical, so which physical corner each one paints swaps under `dir=\"rtl\"` with no second consumer rule -- the panel's own flush edge stays its logical inline-start regardless of direction."},{"name":"--lr-app-rail-panel-radius-end-start","description":"**`<lr-app-rail>`** (default: `var(--lr-app-rail-panel-radius)`) — Logical `border-end-start-radius` of `[part=\"panel\"]` -- the corner at the drawer's own flush inline-start edge, block-end side."},{"name":"--lr-app-rail-panel-radius-start-end","description":"**`<lr-app-rail>`** (default: `var(--lr-app-rail-panel-radius)`) — Logical `border-start-end-radius` of `[part=\"panel\"]` -- the corner away from the flush inline-start edge, block-start side. One of the two corners a flush-against-one-edge drawer typically rounds."},{"name":"--lr-app-rail-panel-radius-start-start","description":"**`<lr-app-rail>`** (default: `var(--lr-app-rail-panel-radius)`) — Logical `border-start-start-radius` of `[part=\"panel\"]` -- the corner at the drawer's own flush inline-start edge, block-start side."},{"name":"--lr-app-rail-resizer-active-bg","description":"**`<lr-app-rail>`** — Resizer-track pressed background; defaults to the former brand active mix."},{"name":"--lr-app-rail-resizer-hover-bg","description":"**`<lr-app-rail>`** (default: `var(--lr-color-brand)`) — Resizer-track hover background."},{"name":"--lr-app-rail-toggle-active-bg","description":"**`<lr-app-rail>`** — Toggle pressed background; defaults to the former brand-quiet active mix."},{"name":"--lr-app-rail-toggle-active-color","description":"**`<lr-app-rail>`** (default: `var(--lr-color-brand)`) — Toggle pressed foreground."},{"name":"--lr-app-rail-toggle-hover-bg","description":"**`<lr-app-rail>`** (default: `var(--lr-color-brand-quiet)`) — Toggle hover background."},{"name":"--lr-app-rail-toggle-hover-color","description":"**`<lr-app-rail>`** (default: `var(--lr-color-brand)`) — Toggle hover foreground."},{"name":"--lr-app-rail-width","description":"**`<lr-app-rail>`** (default: `var(--lr-size-15rem)`) — The inline rail's width in `'full'` mode. Overridden by an inline width while a `resizable` rail has an explicit `railWidthPx`."},{"name":"--lr-approval-queue-selected-border","description":"**`<lr-approval-queue>`** (default: `var(--lr-color-brand)`) — Selected request border."},{"name":"--lr-archive-viewer-highlight-accent-background","description":"**`<lr-archive-viewer>`** — Accent highlight background."},{"name":"--lr-archive-viewer-highlight-active-background","description":"**`<lr-archive-viewer>`** — Active highlight background."},{"name":"--lr-archive-viewer-highlight-active-outline","description":"**`<lr-archive-viewer>`** — Active fallback-highlight outline."},{"name":"--lr-archive-viewer-highlight-danger-background","description":"**`<lr-archive-viewer>`** — Danger highlight background."},{"name":"--lr-archive-viewer-highlight-neutral-background","description":"**`<lr-archive-viewer>`** — Neutral highlight background."},{"name":"--lr-archive-viewer-highlight-success-background","description":"**`<lr-archive-viewer>`** — Success highlight background."},{"name":"--lr-archive-viewer-highlight-warning-background","description":"**`<lr-archive-viewer>`** — Warning highlight background."},{"name":"--lr-archive-viewer-max-height","description":"**`<lr-archive-viewer>`** (default: `none`) — Maximum block size of the scrollable body. Also settable via the `max-height` property."},{"name":"--lr-artifact-panel-view-active-bg","description":"**`<lr-artifact-panel>`** (default: `var(--lr-color-brand-quiet)`) — Background of the pressed (active) preview/code toggle button."},{"name":"--lr-artifact-panel-view-active-color","description":"**`<lr-artifact-panel>`** (default: `var(--lr-color-brand)`) — Text color of the pressed (active) preview/code toggle button. Restyling the pressed state otherwise requires overriding the library-wide brand tokens, since `::part(view-button)[aria-pressed]` is invalid CSS."},{"name":"--lr-attachment-chip-accent","description":"**`<lr-attachment-chip>`** (default: `var(--lr-color-text-quiet)`) — Accent color used for the status text, spinner, and progress fill. Its private default changes per `status` (`uploading`/`error`/`success`); the public value remains authoritative."},{"name":"--lr-attachment-chip-bg","description":"**`<lr-attachment-chip>`** (default: `var(--lr-color-surface)`) — Chip background. Its private default changes per `status` to that status's `-quiet` tint; the public value still wins."},{"name":"--lr-attachment-chip-border","description":"**`<lr-attachment-chip>`** (default: `var(--lr-color-border)`) — Chip border color. Every non-`pending` `status` changes its private default to `transparent`."},{"name":"--lr-attachment-chip-compact-font-size","description":"**`<lr-attachment-chip>`** (default: `var(--lr-font-size-xs)`) — Font size of `[part=\"base\"]` while `compact`."},{"name":"--lr-attachment-chip-compact-gap","description":"**`<lr-attachment-chip>`** (default: `var(--lr-size-0-25rem)`) — Gap between the chip's parts while `compact`."},{"name":"--lr-attachment-chip-compact-padding","description":"**`<lr-attachment-chip>`** (default: `var(--lr-size-0-125rem) var(--lr-space-xs)`) — Padding of `[part=\"base\"]` while `compact`."},{"name":"--lr-attachment-chip-compact-thumbnail-only-padding","description":"**`<lr-attachment-chip>`** (default: `var(--lr-size-0-125rem)`) — Padding of `[part=\"base\"]` while `compact` and `thumbnail-only` together actually hide `[part=\"meta\"]` (an image-mime attachment only — see `thumbnailOnly`). Reduced from `--lr-attachment-chip-compact-padding` since the lone thumbnail no longer needs inline padding sized for a text row."},{"name":"--lr-attachment-chip-compact-thumbnail-size","description":"**`<lr-attachment-chip>`** (default: `var(--lr-size-1-75rem)`) — Thumbnail size while `compact`, rethemeable independently of `--lr-icon-button-size`. Retry, preview, and remove actions retain that shared token's minimum hit-area floor."},{"name":"--lr-attachment-chip-padding","description":"**`<lr-attachment-chip>`** (default: `var(--lr-space-xs) var(--lr-space-s)`) — Padding of `[part=\"base\"]` while `compact` is unset."},{"name":"--lr-attachment-chip-spinner-duration","description":"**`<lr-attachment-chip>`** (default: `var(--lr-transition-ambient)`) — Duration and easing of one indeterminate upload-spinner rotation. The ambient loop stops under reduced motion."},{"name":"--lr-audio-visualizer-ambient-duration","description":"**`<lr-audio-visualizer>`** (default: `var(--lr-duration-ambient)`) — Time-only duration of one signal-less ambient pulse or sweep cycle."},{"name":"--lr-audio-visualizer-color","description":"**`<lr-audio-visualizer>`** (default: `var(--lr-color-brand)`) — Active bar/waveform color."},{"name":"--lr-audio-visualizer-height","description":"**`<lr-audio-visualizer>`** (default: `var(--lr-size-3rem)`) — The host's block size, which the canvas fills at 100%."},{"name":"--lr-audio-visualizer-quiet-color","description":"**`<lr-audio-visualizer>`** (default: `var(--lr-color-brand-border-normal)`) — Inactive/idle color. Chosen over `--lr-color-brand-quiet` for its WCAG 1.4.11 non-text contrast against `--lr-color-surface` (the idle bars have no other distinguishing shape or border)."},{"name":"--lr-av-player-cue-active-match-color","description":"**`<lr-av-player>`** (default: `var(--lr-color-warning)`) — Outline color of the `[part=\"cue\"]` holding the current search match, leaving the other matches' dashed outline on the shared warning token."},{"name":"--lr-av-player-cue-current-bg","description":"**`<lr-av-player>`** (default: `var(--lr-color-brand-quiet)`) — Background of the `[part=\"cue\"]` the playhead is currently inside."},{"name":"--lr-av-player-cue-hover-bg","description":"**`<lr-av-player>`** (default: `var(--lr-color-brand-quiet)`) — Background of a hovered `[part=\"cue\"]`. The pressed state mixes further from this same value rather than a separate knob, so retuning it keeps its pressed step too."},{"name":"--lr-av-player-marker-active-color","description":"**`<lr-av-player>`** (default: `var(--lr-color-brand)`) — Outline color of the `[part=\"timeline-marker\"]` matching `activeHighlightId`."},{"name":"--lr-av-player-marker-bg","description":"**`<lr-av-player>`** (default: `color-mix(in srgb, var(--lr-color-brand) 35%, transparent)`) — Background of a `[part=\"timeline-marker\"]` with no (or an unrecognized) `data-tone`."},{"name":"--lr-av-player-marker-danger-bg","description":"**`<lr-av-player>`** (default: `color-mix(in srgb, var(--lr-color-danger) 35%, transparent)`) — Background of a `[part=\"timeline-marker\"][data-tone=\"danger\"]`."},{"name":"--lr-av-player-marker-fill","description":"**`<lr-av-player>`** — The resting fill a `[part=\"timeline-marker\"]` actually renders, resolved per tone from the `--lr-av-player-marker-*-bg` knobs above. Its hover and pressed states are colour mixes taken from this value, so setting it directly retints all three at once for one marker; retint a whole tone through the `-bg` knob instead."},{"name":"--lr-av-player-marker-neutral-bg","description":"**`<lr-av-player>`** (default: `color-mix(in srgb, var(--lr-color-text) 25%, transparent)`) — Background of a `[part=\"timeline-marker\"][data-tone=\"neutral\"]`."},{"name":"--lr-av-player-marker-success-bg","description":"**`<lr-av-player>`** (default: `color-mix(in srgb, var(--lr-color-success) 35%, transparent)`) — Background of a `[part=\"timeline-marker\"][data-tone=\"success\"]`."},{"name":"--lr-av-player-marker-warning-bg","description":"**`<lr-av-player>`** (default: `color-mix(in srgb, var(--lr-color-warning) 35%, transparent)`) — Background of a `[part=\"timeline-marker\"][data-tone=\"warning\"]`."},{"name":"--lr-av-player-transcript-height","description":"**`<lr-av-player>`** (default: `var(--lr-size-16rem)`) — Block size of the virtualized transcript list."},{"name":"--lr-avatar-bg","description":"**`<lr-avatar>`** (default: `var(--lr-color-border)`) — Container background. Each non-neutral `variant` changes its private default to that variant's `-quiet` tint."},{"name":"--lr-avatar-color","description":"**`<lr-avatar>`** (default: `var(--lr-color-text)`) — Initials/glyph color. Each non-neutral `variant` changes its private default to that variant's loud color."},{"name":"--lr-avatar-font-size","description":"**`<lr-avatar>`** (default: `var(--lr-font-size-m)`) — Font size of the initials fallback (and of any `em`-sized slotted glyph). `size` steps its private default alongside the diameter, so the initials track the circle instead of staying at one fixed size across every tier."},{"name":"--lr-avatar-group-avatar-size","description":"**`<lr-avatar-group>`** (default: `var(--lr-size-3rem)`) — Sizes the overflow badge to match the slotted avatars, tier for tier with `<lr-avatar>`'s own `--lr-avatar-size`."},{"name":"--lr-avatar-group-badge-bg","description":"**`<lr-avatar-group>`** (default: `var(--lr-color-border)`) — Overflow badge background. Its private default follows `variant`; the public value remains authoritative."},{"name":"--lr-avatar-group-badge-color","description":"**`<lr-avatar-group>`** (default: `var(--lr-color-text)`) — Overflow badge text color. Its private default follows `variant`; the public value remains authoritative."},{"name":"--lr-avatar-group-badge-font-size","description":"**`<lr-avatar-group>`** (default: `var(--lr-font-size-m)`) — Font size of the \"+N\" badge label. `size` steps its private default across the same six-step ladder as `<lr-avatar>`'s own `--lr-avatar-font-size`, so the badge and the avatars it caps read at the same optical weight."},{"name":"--lr-avatar-group-overlap","description":"**`<lr-avatar-group>`** (default: `var(--lr-size-neg-6px)`) — Horizontal overlap between consecutive avatars (a logical `margin-inline-start`, so it auto-mirrors under `dir=\"rtl\"`). Setting this to `0` or a positive length is a supported escape hatch that turns the stack into normal, non-overlapping spacing."},{"name":"--lr-avatar-group-ring-color","description":"**`<lr-avatar-group>`** (default: `var(--lr-color-surface)`) — The cutout-style ring drawn around every avatar and the overflow badge."},{"name":"--lr-avatar-group-ring-width","description":"**`<lr-avatar-group>`** (default: `var(--lr-border-width-medium)`) — Ring thickness."},{"name":"--lr-avatar-size","description":"**`<lr-avatar>`** (default: `var(--lr-size-3rem)`) — Inline and block size of the container. `size` steps its private default across the shared six-step ladder, from `var(--lr-size-1-5rem)` (`2xs`) to `var(--lr-size-5rem)` (`xl`); an inherited or direct public value still wins."},{"name":"--lr-badge-attention-duration","description":"**`<lr-badge>`, `<lr-tag>`** (default: `var(--lr-duration-ambient)`) — One cycle of the `attention` animation."},{"name":"--lr-badge-attention-easing","description":"**`<lr-badge>`, `<lr-tag>`** (default: `var(--lr-easing-emphasized)`) — Timing function of the `attention` animation."},{"name":"--lr-badge-background","description":"**`<lr-badge>`, `<lr-tag>`** (default: `var(--lr-badge-fill)`) — Explicit override for the badge's background, winning over whatever `variant` and `appearance` resolved. Left unset (the default) so it still inherits from a consumer's own ancestor rule."},{"name":"--lr-badge-border","description":"**`<lr-badge>`, `<lr-tag>`** (default: `var(--lr-badge-stroke)`) — Explicit override for the badge's border color, on the same terms as `--lr-badge-background`."},{"name":"--lr-badge-bounce-distance","description":"**`<lr-badge>`, `<lr-tag>`** (default: `var(--lr-size-0-1875rem)`) — Peak travel of the `attention=\"bounce\"` hop."},{"name":"--lr-badge-color","description":"**`<lr-badge>`, `<lr-tag>`** (default: `var(--lr-badge-text)`) — Explicit override for the badge's text color, on the same terms as `--lr-badge-background`."},{"name":"--lr-badge-edge","description":"**`<lr-badge>`, `<lr-tag>`** (default: `var(--lr-color-border)`) — Palette slot: the variant's border color. Its private default follows each non-neutral `variant`'s loud fill; an inherited or direct public value remains authoritative."},{"name":"--lr-badge-fill","description":"**`<lr-badge>`, `<lr-tag>`** (default: `var(--lr-badge-tint)`) — Surface slot: which palette entry `appearance` routed onto the background. Set it to retune a single appearance without touching the palette."},{"name":"--lr-badge-font-size","description":"**`<lr-badge>`, `<lr-tag>`** (default: `var(--lr-font-size-sm)`) — The badge's label font size. Each `size` sets it to that step's font size."},{"name":"--lr-badge-gap","description":"**`<lr-badge>`, `<lr-tag>`** (default: `var(--lr-space-2xs)`) — Space between the `start` slot, the label, and the `end` slot."},{"name":"--lr-badge-ink","description":"**`<lr-badge>`, `<lr-tag>`** (default: `var(--lr-color-text)`) — Palette slot: the variant's text color. Its private default follows each non-neutral `variant`'s loud fill; an inherited or direct public value remains authoritative."},{"name":"--lr-badge-min-height","description":"**`<lr-badge>`, `<lr-tag>`** (default: `var(--lr-size-1-25rem)`) — The badge's minimum block size. Each `size` sets it to that step's minimum block size."},{"name":"--lr-badge-on-solid","description":"**`<lr-badge>`, `<lr-tag>`** (default: `var(--lr-color-on-loud)`) — Palette slot: the text color that stays legible on `--lr-badge-solid`."},{"name":"--lr-badge-padding-inline","description":"**`<lr-badge>`, `<lr-tag>`** (default: `var(--lr-space-s)`) — The badge's inline padding. Each `size` sets it to that step's inline padding."},{"name":"--lr-badge-pulse-color","description":"**`<lr-badge>`, `<lr-tag>`** (default: `color-mix(in srgb, currentColor 40%, transparent)`) — Color of the expanding ring drawn by `attention=\"pulse\"`."},{"name":"--lr-badge-pulse-spread","description":"**`<lr-badge>`, `<lr-tag>`** (default: `var(--lr-size-0-25rem)`) — How far the `attention=\"pulse\"` ring expands."},{"name":"--lr-badge-radius","description":"**`<lr-badge>`, `<lr-tag>`** (default: `var(--lr-radius)`) — Corner radius of the badge surface. `pill` raises it to `var(--lr-radius-pill)`. Does not vary by `size` tier."},{"name":"--lr-badge-solid","description":"**`<lr-badge>`, `<lr-tag>`** (default: `var(--lr-color-fill-loud)`) — Palette slot: the variant's loud fill, used by `appearance=\"accent\"`."},{"name":"--lr-badge-stroke","description":"**`<lr-badge>`, `<lr-tag>`** (default: `var(--lr-badge-edge)`) — Surface slot: which palette entry `appearance` routed onto the border color."},{"name":"--lr-badge-text","description":"**`<lr-badge>`, `<lr-tag>`** (default: `var(--lr-badge-ink)`) — Surface slot: which palette entry `appearance` routed onto the label color."},{"name":"--lr-badge-tint","description":"**`<lr-badge>`, `<lr-tag>`** (default: `var(--lr-color-surface)`) — Palette slot: the variant's quiet fill. Its private default follows each non-neutral `variant`'s quiet fill from the shared semantic grid; an inherited or direct public value remains authoritative."},{"name":"--lr-border-width-medium","description":"**Shared design token** — Canonical shared component token for border width medium. Reads `--lr-theme-border-width-medium`."},{"name":"--lr-border-width-thick","description":"**Shared design token** — Canonical shared component token for border width thick. Reads `--lr-theme-border-width-thick`."},{"name":"--lr-border-width-thin","description":"**Shared design token** — Canonical shared component token for border width thin. Reads `--lr-theme-border-width-thin`."},{"name":"--lr-box-plot-border-color-1","description":"**`<lr-box-plot>`** (default: `var(--lr-color-chart-1)`) — First series box-outline color."},{"name":"--lr-box-plot-border-color-2","description":"**`<lr-box-plot>`** (default: `var(--lr-color-chart-2)`) — Second series box-outline color."},{"name":"--lr-box-plot-border-color-3","description":"**`<lr-box-plot>`** (default: `var(--lr-color-chart-3)`) — Third series box-outline color."},{"name":"--lr-box-plot-border-color-4","description":"**`<lr-box-plot>`** (default: `var(--lr-color-chart-4)`) — Fourth series box-outline color."},{"name":"--lr-box-plot-border-color-5","description":"**`<lr-box-plot>`** (default: `var(--lr-color-chart-5)`) — Fifth series box-outline color."},{"name":"--lr-box-plot-border-color-6","description":"**`<lr-box-plot>`** (default: `var(--lr-color-chart-6)`) — Sixth series box-outline color."},{"name":"--lr-box-plot-border-color-7","description":"**`<lr-box-plot>`** (default: `var(--lr-color-chart-7)`) — Seventh series box-outline color."},{"name":"--lr-box-plot-border-color-8","description":"**`<lr-box-plot>`** (default: `var(--lr-color-chart-8)`) — Eighth series box-outline color."},{"name":"--lr-box-plot-border-width","description":"**`<lr-box-plot>`** (default: `var(--lr-border-width-thin)`) — Canvas box-outline stroke width, in pixels. Same override mechanism as `<lr-chart>`'s `--border-width`."},{"name":"--lr-box-plot-data-table-toggle-active-bg","description":"**`<lr-box-plot>`** — Pressed background of the `dataTableToggle` disclosure button; defaults to a mix of the hover background with the shared active mix partner."},{"name":"--lr-box-plot-data-table-toggle-hover-bg","description":"**`<lr-box-plot>`** (default: `var(--lr-color-brand-quiet)`) — Hover background of the `dataTableToggle` disclosure button."},{"name":"--lr-box-plot-fill-color-1","description":"**`<lr-box-plot>`** (default: `var(--lr-color-chart-1)`) — First series box-fill and legend-swatch color."},{"name":"--lr-box-plot-fill-color-2","description":"**`<lr-box-plot>`** (default: `var(--lr-color-chart-2)`) — Second series box-fill and legend-swatch color."},{"name":"--lr-box-plot-fill-color-3","description":"**`<lr-box-plot>`** (default: `var(--lr-color-chart-3)`) — Third series box-fill and legend-swatch color."},{"name":"--lr-box-plot-fill-color-4","description":"**`<lr-box-plot>`** (default: `var(--lr-color-chart-4)`) — Fourth series box-fill and legend-swatch color."},{"name":"--lr-box-plot-fill-color-5","description":"**`<lr-box-plot>`** (default: `var(--lr-color-chart-5)`) — Fifth series box-fill and legend-swatch color."},{"name":"--lr-box-plot-fill-color-6","description":"**`<lr-box-plot>`** (default: `var(--lr-color-chart-6)`) — Sixth series box-fill and legend-swatch color."},{"name":"--lr-box-plot-fill-color-7","description":"**`<lr-box-plot>`** (default: `var(--lr-color-chart-7)`) — Seventh series box-fill and legend-swatch color."},{"name":"--lr-box-plot-fill-color-8","description":"**`<lr-box-plot>`** (default: `var(--lr-color-chart-8)`) — Eighth series box-fill and legend-swatch color."},{"name":"--lr-box-plot-item-radius","description":"**`<lr-box-plot>`** (default: `0`) — Radius, in pixels, of the individual raw-sample dots drawn alongside each box; `0` (the default) disables them."},{"name":"--lr-breadcrumb-current-color","description":"**`<lr-breadcrumb-item>`** (default: `var(--lr-color-text-quiet)`) — Text color of the current-page item (`current`/`aria-current=\"page\"`). 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-text-quiet` token."},{"name":"--lr-breadcrumb-item-active-bg","description":"**`<lr-breadcrumb-item>`** — Link/button pressed background; defaults to the former transparent active mix."},{"name":"--lr-browser-frame-aspect-ratio","description":"**`<lr-browser-frame>`** (default: `16 / 9`) — The viewport's aspect ratio."},{"name":"--lr-browser-frame-controller-background","description":"**`<lr-browser-frame>`** (default: `var(--lr-color-brand-quiet)`) — Controller badge background."},{"name":"--lr-browser-frame-controller-color","description":"**`<lr-browser-frame>`** (default: `var(--lr-color-brand)`) — Controller badge text color."},{"name":"--lr-browser-frame-ping-click-color","description":"**`<lr-browser-frame>`** (default: `var(--lr-color-brand)`) — Click-ping border color."},{"name":"--lr-browser-frame-ping-move-color","description":"**`<lr-browser-frame>`** (default: `var(--lr-color-text-quiet)`) — Move-ping border color."},{"name":"--lr-browser-frame-ping-scroll-color","description":"**`<lr-browser-frame>`** (default: `var(--lr-color-warning)`) — Scroll-ping border color."},{"name":"--lr-browser-frame-ping-type-color","description":"**`<lr-browser-frame>`** (default: `var(--lr-color-success)`) — Type-ping border color."},{"name":"--lr-button-accent","description":"**`<lr-button>`** (default: `var(--lr-color-fill-loud)`) — Text/glyph color for the chrome-less appearances (`outlined`, `plain`, `link`), i.e. the active `variant`'s loud fill used as a foreground. `variant=\"neutral\"` is the one exception: its loud fill is a mid grey picked to carry light text, so borrowing it as text on the page surface would wash out every plain and link button — neutral keeps `--lr-color-text`."},{"name":"--lr-button-accent-fill","description":"**`<lr-button>`** (default: `var(--lr-color-fill-loud)`) — Background of `appearance=\"accent\"` (and its border color): the active `variant`'s loud fill, the one primary action in a view."},{"name":"--lr-button-accent-on-fill","description":"**`<lr-button>`** (default: `var(--lr-color-on-loud)`) — Text color on top of `--lr-button-accent-fill`, the grid's guaranteed-legible foreground for that fill."},{"name":"--lr-button-active-background","description":"**`<lr-button>`** (default: `color-mix(in oklab, var(--lr-button-hover-base), var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Background while a non-disabled button is pressed — the same mix at the stronger `--lr-color-mix-active` share, so the pressed state reads as more than the hover. `appearance=\"link\"` moves its text colour by these two shares instead of taking a background."},{"name":"--lr-button-active-scale","description":"**`<lr-button>`** (default: `0.9875`) — `transform: scale()` factor applied while a non-disabled button is pressed."},{"name":"--lr-button-border","description":"**`<lr-button>`** (default: `var(--lr-color-border-normal)`) — Border color of the internal button, from the active `variant`'s row of the shared semantic grid."},{"name":"--lr-button-caret-size","description":"**`<lr-button>`** (default: `var(--lr-size-0-75em)`) — Font size of the `with-caret` chevron, i.e. its rendered glyph box. Relative to the button's own font size, so it follows every `size` tier without a per-tier rule."},{"name":"--lr-button-fill","description":"**`<lr-button>`** (default: `var(--lr-color-fill-quiet)`) — Background of `appearance=\"filled\"`: the active `variant`'s quiet tint, i.e. a secondary-action fill that is visibly a fill rather than the page surface. Follows `variant` through the shared semantic grid."},{"name":"--lr-button-font-size","description":"**`<lr-button>`** (default: `var(--lr-form-control-font-size)`) — Font size of the internal button, from the active `size` tier. `appearance=\"link\"` ignores it and inherits the ambient font instead."},{"name":"--lr-button-gap","description":"**`<lr-button>`** (default: `var(--lr-form-control-gap)`) — Gap between the icon/label and any slotted content in the internal button. Constant across the ladder's tiers. Override it to retune without a `::part(base)` rule."},{"name":"--lr-button-group-gap","description":"**`<lr-button-group>`** (default: `var(--lr-space-2xs)`) — Gap between grouped controls."},{"name":"--lr-button-height","description":"**`<lr-button>`** — Exact height of the internal button. **Undeclared by default** — so the button keeps the active tier's `min-block-size` floor and an `auto` height, exactly as before. Set it (e.g. to pin the button to a fixed toolbar row) to both floor *and* cap the height. Never declare it as `auto`: a declared value wins over the `var()` fallback arm and would make every tier's floor dead code. `appearance=\"link\"` ignores it."},{"name":"--lr-button-hover-background","description":"**`<lr-button>`** (default: `color-mix(in oklab, var(--lr-button-hover-base), var(--lr-color-mix-partner) var(--lr-color-mix-hover))`) — Background of a non-disabled button while hovered. Replaced the pre-8.0.0 `--lr-button-hover-brightness` multiplier: a `filter` multiplies every channel, so it moved a mid-toned fill but did nothing at all to a pure white or pure black one, and it dimmed the label and icons along with the box."},{"name":"--lr-button-hover-base","description":"**`<lr-button>`** (default: `var(--lr-color-surface)`) — The colour the hover and press mixes move away from. Each painted appearance re-points it at its own fill (`--lr-button-fill` for `filled`/`filled-outlined`, `--lr-button-accent-fill` for `accent`); the chrome-less tiers (`outlined`, `plain`, `quiet`, `link`) paint nothing, so they mix from the page surface. Set it alongside `--lr-button-outlined-fill` when you tint an outlined button."},{"name":"--lr-button-hover-border","description":"**`<lr-button>`** — Border color of a non-disabled button while hovered. **Undeclared by default**, so it falls back to whatever border colour the active `appearance` already paints at rest — every appearance's current hover border is unchanged until this is set. `appearance=\"link\"` renders with no border (`border: 0`) at every state, so this has no visible effect there."},{"name":"--lr-button-hover-color","description":"**`<lr-button>`** — Text color of a non-disabled button while hovered. **Undeclared by default**, so it falls back to whatever colour the active `appearance` already paints at rest — every appearance's current hover text colour is unchanged until this is set. `appearance=\"link\"` ignores it: its own hover rule sets a higher-specificity colour mix instead."},{"name":"--lr-button-justify","description":"**`<lr-button>`** (default: `center`) — `justify-content` of the internal button's row. With the label no longer growing by default, this is what positions the whole icon+label pair inside a stretched control: `flex-start` packs it against the leading edge, `space-between` pushes the adornments apart."},{"name":"--lr-button-label-grow","description":"**`<lr-button>`** (default: `0`) — `flex-grow` of `[part=\"label\"]`. `0` (the default) lets the label shrink-wrap its text so `--lr-button-justify` positions the real content; `1` restores the pre-16.0.0 behaviour where the label absorbed every spare pixel of a stretched button. It also overrides the automatic grow a `with-caret`/`end`-adornment button applies, so `0` opts those rows out of pinning their trailing affordance."},{"name":"--lr-button-min-height","description":"**`<lr-button>`** (default: `var(--lr-form-control-height)`) — The active tier's `min-block-size` floor, resolved through that tier's own `--lr-button-size-*` token, and used as the fallback when `--lr-button-height` is unset."},{"name":"--lr-button-on-fill","description":"**`<lr-button>`** (default: `var(--lr-color-on-quiet)`) — Text color on top of `--lr-button-fill`, the grid's guaranteed-legible foreground for that tint."},{"name":"--lr-button-outlined-border","description":"**`<lr-button>`** (default: `var(--lr-color-border-strong)`) — Border color of `appearance=\"outlined\"` and `appearance=\"filled-outlined\"`, which overrides `--lr-button-border`."},{"name":"--lr-button-outlined-fill","description":"**`<lr-button>`** (default: `transparent`) — Background of `appearance=\"outlined\"`. Transparent by default; set it to tint the button (e.g. a faint surface wash behind the outline) without a `::part(base)` rule. Like `--lr-button-quiet-*`, it is deliberately *not* swapped per `variant`. The hover and press mixes read `--lr-button-hover-base`, which this tier leaves on the page surface, so set both together when you tint an outlined button."},{"name":"--lr-button-padding-block","description":"**`<lr-button>`** (default: `var(--lr-form-control-padding-block)`) — Block padding of the internal button, taken from the active `size` tier of the shared ladder. Override it to retune a tier without a `::part(base)` rule; `appearance=\"link\"` ignores it (it renders with zero padding)."},{"name":"--lr-button-padding-inline","description":"**`<lr-button>`** (default: `var(--lr-form-control-padding-inline)`) — Inline padding of the internal button, from the active `size` tier. `appearance=\"link\"` ignores it."},{"name":"--lr-button-quiet-border","description":"**`<lr-button>`** (default: `var(--lr-color-border)`) — Border color of `appearance=\"quiet\"`."},{"name":"--lr-button-quiet-text","description":"**`<lr-button>`** (default: `var(--lr-color-text-quiet)`) — Text color of `appearance=\"quiet\"`."},{"name":"--lr-button-radius","description":"**`<lr-button>`** (default: `var(--lr-form-control-radius)`) — Corner radius of the internal button, from the active `size` tier of the shared ladder (the two tightest tiers take a smaller radius, since a 6px corner on a 20px-tall control reads as a lozenge). `appearance=\"link\"` ignores it (it renders with zero radius). `pill` changes the private default to `--lr-radius-pill`; an inherited or direct `--lr-button-radius` still wins."},{"name":"--lr-button-shadow","description":"**`<lr-button>`** — Box shadow of the internal button. **Undeclared by default**, so `box-shadow` falls back to `none` — byte-identical to before this property existed. Set it (e.g. an elevated/floating action button) without a `::part(base)` rule. `appearance=\"link\"` always renders with no shadow regardless of this token — a zero-chrome inline link has no box to elevate."},{"name":"--lr-button-size-2xs","description":"**`<lr-button>`** (default: `var(--lr-form-control-height-2xs)`) — `min-block-size` at `size=\"2xs\"`. Since 8.0.0 the whole scale comes from the shared form-control ladder (`internal/sizes.styles.ts`), so ordinary single-row controls share the same minimum-height floor. A composed control can still grow to preserve an action's hit target or fit its content."},{"name":"--lr-button-size-l","description":"**`<lr-button>`** (default: `var(--lr-form-control-height-l)`) — `min-block-size` at `size=\"l\"` (and at `size=\"large\"`)."},{"name":"--lr-button-size-m","description":"**`<lr-button>`** (default: `var(--lr-form-control-height-m)`) — `min-block-size` at `size=\"m\"` (and at `size=\"medium\"`), the default tier."},{"name":"--lr-button-size-s","description":"**`<lr-button>`** (default: `var(--lr-form-control-height-s)`) — `min-block-size` at `size=\"s\"` (and at the `size=\"small\"` spelling)."},{"name":"--lr-button-size-xl","description":"**`<lr-button>`** (default: `var(--lr-form-control-height-xl)`) — `min-block-size` at `size=\"xl\"`."},{"name":"--lr-button-size-xs","description":"**`<lr-button>`** (default: `var(--lr-form-control-height-xs)`) — `min-block-size` at `size=\"xs\"`."},{"name":"--lr-button-spinner-duration","description":"**`<lr-button>`** (default: `var(--lr-transition-ambient)`) — Timing of the `loading` spinner."},{"name":"--lr-button-width","description":"**`<lr-button>`** (default: `100%`) — Inline size of the internal button. The host defaults it to `100%` so the native button follows the host's own width; override to `auto` (or any other value) for a compact inline composition."},{"name":"--lr-calendar-agenda-event-active-bg","description":"**`<lr-calendar>`** (default: `color-mix(in oklab, var(--lr-calendar-agenda-event-hover-bg, var(--lr-color-brand-quiet)), var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Agenda-event pressed background override; without one, colored events retain their event fill."},{"name":"--lr-calendar-agenda-event-hover-bg","description":"**`<lr-calendar>`** (default: `var(--lr-color-brand-quiet)`) — Agenda-event hover background override; without one, colored events retain their event fill."},{"name":"--lr-calendar-day-active-bg","description":"**`<lr-calendar>`** (default: `color-mix(in oklab, var(--lr-calendar-day-hover-bg, var(--lr-color-brand-quiet)), var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Day pressed background."},{"name":"--lr-calendar-day-hover-bg","description":"**`<lr-calendar>`** (default: `var(--lr-color-brand-quiet)`) — Day hover background."},{"name":"--lr-calendar-day-min-block-size","description":"**`<lr-calendar>`** (default: `var(--lr-size-6rem)`) — Minimum block size of a day cell."},{"name":"--lr-calendar-day-min-block-size-narrow","description":"**`<lr-calendar>`** (default: `var(--lr-size-4rem)`) — Minimum block size of a day cell once the host is narrower than 28rem."},{"name":"--lr-calendar-day-outside-bg","description":"**`<lr-calendar>`** (default: `var(--lr-color-surface)`) — Background of an adjacent-month day cell."},{"name":"--lr-calendar-day-outside-color","description":"**`<lr-calendar>`** (default: `var(--lr-color-text-quiet)`) — Text color of an adjacent-month day cell."},{"name":"--lr-calendar-day-selected-bg","description":"**`<lr-calendar>`** (default: `var(--lr-color-brand-quiet)`) — Background of a selected day cell, decoupled from the shared token also driving the nav-button/agenda-event hover background."},{"name":"--lr-calendar-day-today-outline-color","description":"**`<lr-calendar>`** (default: `var(--lr-color-brand)`) — Outline color of today's day cell."},{"name":"--lr-calendar-nav-active-bg","description":"**`<lr-calendar>`** (default: `color-mix(in oklab, var(--lr-calendar-nav-hover-bg, var(--lr-color-brand-quiet)), var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Month-navigation pressed background."},{"name":"--lr-calendar-nav-hover-bg","description":"**`<lr-calendar>`** (default: `var(--lr-color-brand-quiet)`) — Month-navigation hover background."},{"name":"--lr-calendar-viewer-max-height","description":"**`<lr-calendar-viewer>`** (default: `none`) — Maximum block size of `[part=\"body\"]` before it scrolls internally. The `maxHeight` property sets this token inline on `[part=\"base\"]`."},{"name":"--lr-callout-background","description":"**`<lr-callout>`** (default: `var(--lr-color-fill-quiet,var(--lr-color-brand-fill-quiet))`) — The host surface's background: an inherited semantic quiet fill, with brand as the standalone fallback."},{"name":"--lr-callout-border","description":"**`<lr-callout>`** (default: `var(--lr-color-fill-loud,var(--lr-color-brand-fill-loud))`) — The host surface's border color."},{"name":"--lr-callout-close-hover-bg","description":"**`<lr-callout>`** (default: `var(--lr-color-brand-quiet)`) — The close button's hover background, decoupled from `--lr-callout-background` so a consumer can retint one without affecting the other (e.g. keeping the hover fill visibly distinct from a `variant=\"brand\"` panel, which shares the same default token)."},{"name":"--lr-callout-color","description":"**`<lr-callout>`** (default: `var(--lr-color-fill-loud,var(--lr-color-brand-fill-loud))`) — The host surface's text color."},{"name":"--lr-callout-font-size","description":"**`<lr-callout>`** (default: `var(--lr-form-control-font-size,var(--lr-font-size-m))`) — The callout's text size. Its private default follows the library's shared size ladder; an inherited or direct public value remains authoritative."},{"name":"--lr-callout-gap","description":"**`<lr-callout>`** (default: `var(--lr-space-s)`) — Space between the icon, the content, and the close action. Deliberately does not vary by `size`: it separates three adjacent boxes rather than setting the panel's density, and shrinking it at the small tiers only crowds them."},{"name":"--lr-callout-padding","description":"**`<lr-callout>`** (default: `var(--lr-form-control-padding-inline,var(--lr-space-m))`) — Padding of the panel, on both axes. Its private default follows the shared ladder's inline-padding knob: a panel's block rhythm is generous like a control's inline padding, not tight like its block padding (which exists to fit text inside a fixed control height). This hook applies to the panel treatment; `inline` intentionally forces host padding to zero."},{"name":"--lr-canvas-reserved-height","description":"**`<lr-flow-canvas>`** (default: `var(--lr-size-24rem)`) — Default host block size, shared with the pre-upgrade reservation stylesheet. An explicit outer `block-size` still wins.\n\n**`<lr-graph>`** (default: `var(--lr-size-24rem)`) — Default host block size, shared with the pre-upgrade reservation stylesheet. Below this in the fallback chain, the normalized `height` property sizes the host too (a private custom property, not itself settable) -- setting this always overrides `height`, and an explicit outer `block-size` still wins over both.\n\n**`<lr-knowledge-graph-explorer>`** (default: `var(--lr-size-24rem)`) — Default block size of both this host and the composed `lr-graph`, shared with the pre-upgrade reservation stylesheet. Below this in the fallback chain, the composed `lr-graph`'s own normalized `height` (forwarded from this component's own `height`) sizes it instead; an explicit outer `block-size` still wins over both."},{"name":"--lr-card-accent-border-color","description":"**`<lr-card>`** (default: `var(--lr-color-brand)`) — Accent stripe color."},{"name":"--lr-card-filled-bg","description":"**`<lr-card>`** (default: `var(--lr-color-brand-quiet)`) — Filled appearance background."},{"name":"--lr-card-filled-outlined-bg","description":"**`<lr-card>`** (default: `var(--lr-color-brand-quiet)`) — Filled-outlined background."},{"name":"--lr-card-interactive-active-border-color","description":"**`<lr-card>`** (default: `var(--lr-color-brand)`) — Interactive pressed border."},{"name":"--lr-card-interactive-active-overlay","description":"**`<lr-card>`** — Interactive pressed overlay; defaults to the former transparent active mix."},{"name":"--lr-card-interactive-hover-border-color","description":"**`<lr-card>`** (default: `var(--lr-color-brand)`) — Interactive hover border."},{"name":"--lr-card-interactive-hover-shadow","description":"**`<lr-card>`** (default: `var(--lr-card-shadow, none)`) — Box shadow of an `actionable`/linked card's base while hovered. Falls back to `--lr-card-shadow` itself, so a card given only a resting shadow keeps that exact shadow on hover; set this independently to lift an actionable card a further step on hover."},{"name":"--lr-card-outlined-bg","description":"**`<lr-card>`** (default: `var(--lr-color-surface)`) — Background of the DEFAULT (`outlined`) appearance, and of `accent`, which adds a stripe without restating a surface. The filled tiers below already had their own hook; this one closes the gap for the tier most cards actually render, so retinting one themed card no longer needs a `::part(base)` rule or an app-wide `--lr-color-surface` change. Mirrors `<lr-details>`'s `--lr-details-outlined-bg`."},{"name":"--lr-card-shadow","description":"**`<lr-card>`** — Box shadow of the card surface. **Undeclared by default**, so `box-shadow` falls back to `none` -- byte-identical to before this property existed. Set it (e.g. a raised card in a flat layout) without a `::part(base)` rule."},{"name":"--lr-carousel-indicator-current-bg","description":"**`<lr-carousel>`** (default: `var(--lr-color-brand-quiet)`) — Active dot fill."},{"name":"--lr-carousel-indicator-current-border-color","description":"**`<lr-carousel>`** (default: `var(--lr-color-brand)`) — Active dot border."},{"name":"--lr-carousel-navigation-active-bg","description":"**`<lr-carousel>`** — Navigation pressed background; defaults to the former brand-quiet active mix."},{"name":"--lr-carousel-navigation-active-border-color","description":"**`<lr-carousel>`** (default: `var(--lr-color-brand)`) — Navigation pressed border."},{"name":"--lr-carousel-navigation-hover-bg","description":"**`<lr-carousel>`** (default: `var(--lr-color-brand-quiet)`) — Navigation hover background."},{"name":"--lr-carousel-navigation-hover-border-color","description":"**`<lr-carousel>`** (default: `var(--lr-color-brand)`) — Navigation hover border."},{"name":"--lr-carousel-pagination-active-bg","description":"**`<lr-carousel>`** — Pagination-dot pressed background; defaults to the former brand-quiet active mix."},{"name":"--lr-carousel-pagination-active-border-color","description":"**`<lr-carousel>`** (default: `var(--lr-color-brand)`) — Pagination-dot pressed border."},{"name":"--lr-carousel-pagination-hover-bg","description":"**`<lr-carousel>`** (default: `var(--lr-color-brand-quiet)`) — Pagination-dot hover background."},{"name":"--lr-carousel-pagination-hover-border-color","description":"**`<lr-carousel>`** (default: `var(--lr-color-brand)`) — Pagination-dot hover border."},{"name":"--lr-carousel-scroll-container-hover-outline-color","description":"**`<lr-carousel>`** (default: `var(--lr-color-border-strong)`) — Outline color of the mouse-hover preview on `[part=\"scroll-container\"]`. Set to `transparent` to opt out of the hover treatment entirely."},{"name":"--lr-carousel-scroll-container-hover-outline-offset","description":"**`<lr-carousel>`** (default: `var(--lr-focus-ring-offset)`) — Offset of the mouse-hover preview on `[part=\"scroll-container\"]`."},{"name":"--lr-carousel-scroll-container-hover-outline-style","description":"**`<lr-carousel>`** (default: `solid`) — Outline style of the mouse-hover preview on `[part=\"scroll-container\"]`."},{"name":"--lr-carousel-scroll-container-hover-outline-width","description":"**`<lr-carousel>`** (default: `var(--lr-border-width-thin)`) — Outline width of the mouse-hover preview on `[part=\"scroll-container\"]`."},{"name":"--lr-carousel-slide-basis","description":"**`<lr-carousel>`** — Compatibility override for the computed per-page basis."},{"name":"--lr-cell-size","description":"**`<lr-date-picker>`** (default: `var(--lr-size-2-25rem)`) — Inline and block size of each day cell and the matching calendar grid track."},{"name":"--lr-chart-canvas-hover-outline-color","description":"**`<lr-bar-chart>`, `<lr-bubble-chart>`, `<lr-chart>`, `<lr-doughnut-chart>`, `<lr-histogram>`, `<lr-line-chart>`, `<lr-pie-chart>`, `<lr-polar-area-chart>`, `<lr-radar-chart>`, `<lr-scatter-chart>`** (default: `var(--lr-chart-grid-color)`) — Color of the `[part='canvas']` hover-state outline.\n\n**`<lr-box-plot>`** (default: `var(--lr-chart-grid-color)`) — Color of the `[part='canvas']` hover-state outline. Same token and default as `<lr-chart>`."},{"name":"--lr-chart-canvas-hover-outline-width","description":"**`<lr-bar-chart>`, `<lr-box-plot>`, `<lr-bubble-chart>`, `<lr-chart>`, `<lr-doughnut-chart>`, `<lr-histogram>`, `<lr-line-chart>`, `<lr-pie-chart>`, `<lr-polar-area-chart>`, `<lr-radar-chart>`, `<lr-scatter-chart>`** (default: `var(--lr-border-width-thin)`) — Width of the `[part='canvas']` hover-state outline."},{"name":"--lr-chart-color-1","description":"**`<lr-lite-chart>`** (default: `var(--lr-color-chart-1)`) — First series color."},{"name":"--lr-chart-color-2","description":"**`<lr-lite-chart>`** (default: `var(--lr-color-chart-2)`) — Second series color."},{"name":"--lr-chart-color-3","description":"**`<lr-lite-chart>`** (default: `var(--lr-color-chart-3)`) — Third series color."},{"name":"--lr-chart-color-4","description":"**`<lr-lite-chart>`** (default: `var(--lr-color-chart-4)`) — Fourth series color."},{"name":"--lr-chart-color-5","description":"**`<lr-lite-chart>`** (default: `var(--lr-color-chart-5)`) — Fifth series color."},{"name":"--lr-chart-color-6","description":"**`<lr-lite-chart>`** (default: `var(--lr-color-chart-6)`) — Sixth series color."},{"name":"--lr-chart-color-7","description":"**`<lr-lite-chart>`** (default: `var(--lr-color-chart-7)`) — Seventh series color."},{"name":"--lr-chart-color-8","description":"**`<lr-lite-chart>`** (default: `var(--lr-color-chart-8)`) — Eighth series color."},{"name":"--lr-chart-data-table-button-active-bg","description":"**`<lr-bar-chart>`, `<lr-bubble-chart>`, `<lr-chart>`, `<lr-doughnut-chart>`, `<lr-histogram>`, `<lr-line-chart>`, `<lr-pie-chart>`, `<lr-polar-area-chart>`, `<lr-radar-chart>`, `<lr-scatter-chart>`** — Pressed background of an actionable generated- table value; defaults to the standard active mix of `--lr-color-brand-quiet`."},{"name":"--lr-chart-data-table-button-hover-bg","description":"**`<lr-bar-chart>`, `<lr-bubble-chart>`, `<lr-chart>`, `<lr-doughnut-chart>`, `<lr-histogram>`, `<lr-line-chart>`, `<lr-pie-chart>`, `<lr-polar-area-chart>`, `<lr-radar-chart>`, `<lr-scatter-chart>`** (default: `var(--lr-color-brand-quiet)`) — Hover background of an actionable generated-table value."},{"name":"--lr-chart-data-table-toggle-active-bg","description":"**`<lr-bar-chart>`, `<lr-bubble-chart>`, `<lr-chart>`, `<lr-doughnut-chart>`, `<lr-histogram>`, `<lr-line-chart>`, `<lr-pie-chart>`, `<lr-polar-area-chart>`, `<lr-radar-chart>`, `<lr-scatter-chart>`** — Pressed background of the `dataTableToggle` disclosure button; defaults to a mix of the hover background with the shared active mix partner."},{"name":"--lr-chart-data-table-toggle-hover-bg","description":"**`<lr-bar-chart>`, `<lr-bubble-chart>`, `<lr-chart>`, `<lr-doughnut-chart>`, `<lr-histogram>`, `<lr-line-chart>`, `<lr-pie-chart>`, `<lr-polar-area-chart>`, `<lr-radar-chart>`, `<lr-scatter-chart>`** (default: `var(--lr-color-brand-quiet)`) — Hover background of the `dataTableToggle` disclosure button."},{"name":"--lr-chart-grid-color","description":"**`<lr-bar-chart>`, `<lr-bubble-chart>`, `<lr-chart>`, `<lr-doughnut-chart>`, `<lr-histogram>`, `<lr-line-chart>`, `<lr-pie-chart>`, `<lr-polar-area-chart>`, `<lr-radar-chart>`, `<lr-scatter-chart>`** (default: `var(--lr-color-border)`) — Grid-line color. Resolved via `getComputedStyle` on every draw (Chart.js paints to canvas and cannot consume `var()`).\n\n**`<lr-box-plot>`** (default: `var(--lr-color-border)`) — Canvas grid-line color.\n\n**`<lr-lite-chart>`** (default: `var(--lr-color-border)`) — Grid-line color."},{"name":"--lr-chart-height","description":"**`<lr-bar-chart>`, `<lr-bubble-chart>`, `<lr-chart>`, `<lr-doughnut-chart>`, `<lr-histogram>`, `<lr-line-chart>`, `<lr-pie-chart>`, `<lr-polar-area-chart>`, `<lr-radar-chart>`, `<lr-scatter-chart>`** (default: `var(--lr-size-280px)`) — The plot region's `block-size` and the host's minimum block size. A visible data table or wrapping DOM legend grows the host in normal flow instead of overlapping following content. `height` supplies a private fallback; this public token always wins when a consumer sets it.\n\n**`<lr-box-plot>`, `<lr-lite-chart>`** (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."},{"name":"--lr-chart-legend-color","description":"**`<lr-bar-chart>`, `<lr-bubble-chart>`, `<lr-chart>`, `<lr-doughnut-chart>`, `<lr-histogram>`, `<lr-line-chart>`, `<lr-pie-chart>`, `<lr-polar-area-chart>`, `<lr-radar-chart>`, `<lr-scatter-chart>`** (default: `var(--lr-color-text)`) — Legend label color. Resolved via `getComputedStyle` on every draw.\n\n**`<lr-box-plot>`** (default: `var(--lr-color-text)`) — DOM legend label color.\n\n**`<lr-lite-chart>`** (default: `var(--lr-color-text)`) — Legend label color."},{"name":"--lr-chart-legend-item-active-bg","description":"**`<lr-bar-chart>`, `<lr-bubble-chart>`, `<lr-chart>`, `<lr-doughnut-chart>`, `<lr-histogram>`, `<lr-line-chart>`, `<lr-pie-chart>`, `<lr-polar-area-chart>`, `<lr-radar-chart>`, `<lr-scatter-chart>`** — Pressed background of a legend visibility button; defaults to the standard active mix of `--lr-color-brand-quiet`.\n\n**`<lr-box-plot>`** — Legend-item pressed background."},{"name":"--lr-chart-legend-item-hover-bg","description":"**`<lr-bar-chart>`, `<lr-bubble-chart>`, `<lr-chart>`, `<lr-doughnut-chart>`, `<lr-histogram>`, `<lr-line-chart>`, `<lr-pie-chart>`, `<lr-polar-area-chart>`, `<lr-radar-chart>`, `<lr-scatter-chart>`** (default: `var(--lr-color-brand-quiet)`) — Hover background of a legend visibility button.\n\n**`<lr-box-plot>`** (default: `var(--lr-color-brand-quiet)`) — Legend-item hover background."},{"name":"--lr-chart-legend-side-max","description":"**`<lr-bar-chart>`, `<lr-bubble-chart>`, `<lr-chart>`, `<lr-doughnut-chart>`, `<lr-histogram>`, `<lr-line-chart>`, `<lr-pie-chart>`, `<lr-polar-area-chart>`, `<lr-radar-chart>`, `<lr-scatter-chart>`** (default: `var(--lr-size-15rem)`) — Maximum inline size reserved for a side-positioned DOM legend; the track is also capped at one third of the chart allocation.\n\n**`<lr-box-plot>`, `<lr-lite-chart>`** (default: `var(--lr-size-15rem)`) — Maximum side-legend track size."},{"name":"--lr-chart-pattern-step","description":"**`<lr-bar-chart>`, `<lr-bubble-chart>`, `<lr-chart>`, `<lr-doughnut-chart>`, `<lr-histogram>`, `<lr-line-chart>`, `<lr-pie-chart>`, `<lr-polar-area-chart>`, `<lr-radar-chart>`, `<lr-scatter-chart>`** (default: `var(--lr-space-2xs)`) — Tile size of the texture painted on `[part='legend-swatch']` while `forced-colors: active` matches, where every series collapses to one system color and the stripe/crosshatch pattern 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.\n\n**`<lr-box-plot>`** (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 stripe/crosshatch pattern 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-lite-chart>`.\n\n**`<lr-lite-chart>`** (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>`."},{"name":"--lr-chart-reset-zoom-button-active-bg","description":"**`<lr-bar-chart>`, `<lr-bubble-chart>`, `<lr-chart>`, `<lr-doughnut-chart>`, `<lr-histogram>`, `<lr-line-chart>`, `<lr-pie-chart>`, `<lr-polar-area-chart>`, `<lr-radar-chart>`, `<lr-scatter-chart>`** — Pressed background of the reset-zoom button; defaults to the standard active mix of `--lr-color-brand-quiet`."},{"name":"--lr-chart-reset-zoom-button-hover-bg","description":"**`<lr-bar-chart>`, `<lr-bubble-chart>`, `<lr-chart>`, `<lr-doughnut-chart>`, `<lr-histogram>`, `<lr-line-chart>`, `<lr-pie-chart>`, `<lr-polar-area-chart>`, `<lr-radar-chart>`, `<lr-scatter-chart>`** (default: `var(--lr-color-brand-quiet)`) — Hover background of the reset-zoom button."},{"name":"--lr-chart-tick-color","description":"**`<lr-bar-chart>`, `<lr-bubble-chart>`, `<lr-chart>`, `<lr-doughnut-chart>`, `<lr-histogram>`, `<lr-line-chart>`, `<lr-pie-chart>`, `<lr-polar-area-chart>`, `<lr-radar-chart>`, `<lr-scatter-chart>`** (default: `var(--lr-color-text-quiet)`) — Axis tick-label color; also used for the `xLabel`/`yLabel`/`y2Label` axis-title text (there is no separate title-color token). Resolved via `getComputedStyle` on every draw.\n\n**`<lr-box-plot>`** (default: `var(--lr-color-text-quiet)`) — Canvas tick and axis-title color.\n\n**`<lr-lite-chart>`** (default: `var(--lr-color-text-quiet)`) — Axis and legend-detail color."},{"name":"--lr-chart-tick-font-size","description":"**`<lr-bar-chart>`, `<lr-bubble-chart>`, `<lr-chart>`, `<lr-doughnut-chart>`, `<lr-histogram>`, `<lr-line-chart>`, `<lr-pie-chart>`, `<lr-polar-area-chart>`, `<lr-radar-chart>`, `<lr-scatter-chart>`** (default: `var(--lr-font-size-xs)`) — Axis tick-label font size, in any CSS length unit. Defaults to `--lr-font-size-xs` (12px at the standard root) because that matches Chart.js's OWN built-in tick font size, which is what every canvas chart rendered before this token existed -- leaving it unset must stay byte-identical to that, not shrink to `<lr-lite-chart>`'s SVG default. Also sizes the radar/polarArea `r`-scale `pointLabels` (the spoke labels), but ONLY once set: those default separately to Chart.js's OWN distinct `RadialLinearScale` `pointLabels` default (10px, not this token's 12px), and only adopt this token's size once the consumer explicitly sets it, at which point ticks and point labels match. Resolved via `getComputedStyle` on every draw, same constraint as every other `--lr-chart-*` token here (Chart.js paints to canvas and cannot consume `var()`).\n\n**`<lr-box-plot>`** (default: `var(--lr-font-size-xs)`) — Canvas axis tick-label font size. Same token name and default as `lr-chart`'s equivalent, so theming either retunes both; `--lr-font-size-xs` (12px at the standard root) matches Chart.js's OWN built-in tick font size, which is what box-plot rendered before this token existed.\n\n**`<lr-lite-chart>`** (default: `var(--lr-font-size-2xs)`) — Axis tick-label font size. Same token name as `lr-chart`'s canvas equivalent, so theming either retunes both."},{"name":"--lr-chart-tooltip-bg","description":"**`<lr-bar-chart>`, `<lr-bubble-chart>`, `<lr-chart>`, `<lr-doughnut-chart>`, `<lr-histogram>`, `<lr-line-chart>`, `<lr-pie-chart>`, `<lr-polar-area-chart>`, `<lr-radar-chart>`, `<lr-scatter-chart>`** (default: `var(--lr-color-surface)`) — Tooltip background color. Resolved via `getComputedStyle` on every draw.\n\n**`<lr-box-plot>`** (default: `var(--lr-color-surface)`) — Canvas tooltip background."},{"name":"--lr-chart-tooltip-text","description":"**`<lr-bar-chart>`, `<lr-bubble-chart>`, `<lr-chart>`, `<lr-doughnut-chart>`, `<lr-histogram>`, `<lr-line-chart>`, `<lr-pie-chart>`, `<lr-polar-area-chart>`, `<lr-radar-chart>`, `<lr-scatter-chart>`** (default: `var(--lr-color-text)`) — Tooltip text color. Resolved via `getComputedStyle` on every draw.\n\n**`<lr-box-plot>`** (default: `var(--lr-color-text)`) — Canvas tooltip text color."},{"name":"--lr-chat-composer-background","description":"**`<lr-chat-composer>`** (default: `var(--lr-color-surface)`) — Fill of the card (`[part=\"base\"]`) while `frame=\"card\"`. `frame=\"plain\"` still removes the fill entirely."},{"name":"--lr-chat-composer-border-color","description":"**`<lr-chat-composer>`** (default: `var(--lr-color-border)`) — Resting colour of the card's border. The `:focus-within` border stays on the brand token -- it is state paint, not chrome."},{"name":"--lr-chat-composer-busy-bg","description":"**`<lr-chat-composer>`** (default: `var(--lr-color-text-quiet)`) — `action-button` background while `status` is `\"sending\"` or `\"streaming\"`. Scoped separately from the shared `--lr-color-text-quiet` token, which the `textarea` part's placeholder also reads -- overriding this recolors only the busy button, not the placeholder text too."},{"name":"--lr-chat-composer-focus-shadow","description":"**`<lr-chat-composer>`** (default: `inset 0 calc(-1 * var(--lr-focus-ring-width)) 0 0 var(--lr-focus-ring-color)`) — The `frame=\"plain\"` focus affordance painted on `[part=\"base\"]:focus-within`, replacing the card's border-color shift with an underline since there is no border left to recolor under `plain`. Override to reshape it (a different width/color) or set to `none` to cede focus chrome entirely to a consumer-drawn wrapper -- chosen over a third `frame` value, since every other piece of this card's paint (background/border-color/radius above) is already a cssprop hook rather than a `frame` variant, and `none` already reads naturally as \"I'll draw my own\"."},{"name":"--lr-chat-composer-gap","description":"**`<lr-chat-composer>`** (default: `var(--lr-space-xs)`) — Row gap between the `toolbar`, `chips` and `row` sections stacked inside `[part=\"base\"]`."},{"name":"--lr-chat-composer-padding","description":"**`<lr-chat-composer>`** (default: `var(--lr-space-s)`) — Padding of the card (`[part=\"base\"]`). `frame=\"plain\"` still zeroes it, same as the background/border-color/radius hooks above."},{"name":"--lr-chat-composer-radius","description":"**`<lr-chat-composer>`** (default: `var(--lr-radius)`) — Corner radius of the card. `frame=\"plain\"` still squares the corners."},{"name":"--lr-chat-message-bubble-bg","description":"**`<lr-chat-message>`** (default: `var(--lr-color-surface)`) — Bubble fill for every role except `user`."},{"name":"--lr-chat-message-bubble-color","description":"**`<lr-chat-message>`** (default: `var(--lr-color-text)`) — Bubble text color for every role except `user`."},{"name":"--lr-chat-message-bubble-padding","description":"**`<lr-chat-message>`** (default: `var(--lr-space-m)`) — Bubble padding."},{"name":"--lr-chat-message-bubble-radius","description":"**`<lr-chat-message>`** (default: `var(--lr-radius)`) — Bubble corner radius. Bubble-only by design — `collapse-button` and `retry-button` keep reading the shared `--lr-radius`, so a rounder bubble never desyncs the controls from the rest of the library."},{"name":"--lr-chat-message-failed-bg","description":"**`<lr-chat-message>`** (default: `var(--lr-color-danger-quiet)`) — Failed bubble fill."},{"name":"--lr-chat-message-failed-border-color","description":"**`<lr-chat-message>`** (default: `var(--lr-color-danger)`) — Failed bubble border."},{"name":"--lr-chat-message-failed-footer-color","description":"**`<lr-chat-message>`** (default: `var(--lr-color-danger)`) — Failed-message footer text."},{"name":"--lr-chat-message-failed-indicator-color","description":"**`<lr-chat-message>`** (default: `var(--lr-color-danger)`) — Failed indicator."},{"name":"--lr-chat-message-failed-status-color","description":"**`<lr-chat-message>`** (default: `var(--lr-color-danger)`) — Failed status text."},{"name":"--lr-chat-message-footer-color","description":"**`<lr-chat-message>`** (default: `var(--lr-color-text-quiet)`) — Default footer text."},{"name":"--lr-chat-message-indicator-color","description":"**`<lr-chat-message>`** (default: `var(--lr-color-text-quiet)`) — Default status indicator."},{"name":"--lr-chat-message-max-width","description":"**`<lr-chat-message>`** (default: `80%`) — Maximum inline size of the message bubble."},{"name":"--lr-chat-message-streaming-border-color","description":"**`<lr-chat-message>`** (default: `var(--lr-color-brand)`) — Streaming bubble border."},{"name":"--lr-chat-message-streaming-indicator-color","description":"**`<lr-chat-message>`** (default: `var(--lr-color-brand)`) — Streaming indicator."},{"name":"--lr-chat-message-system-color","description":"**`<lr-chat-message>`** (default: `var(--lr-color-text-quiet)`) — System-message text color."},{"name":"--lr-chat-message-user-bubble-bg","description":"**`<lr-chat-message>`** (default: `var(--lr-color-brand-quiet)`) — Bubble fill for `message-role=\"user\"`."},{"name":"--lr-chat-message-user-bubble-color","description":"**`<lr-chat-message>`** (default: `var(--lr-color-text)`) — Bubble text color for `message-role=\"user\"`."},{"name":"--lr-chat-message-user-footer-color","description":"**`<lr-chat-message>`** (default: `var(--lr-color-text)`) — User-message footer text."},{"name":"--lr-checkbox-active-border","description":"**`<lr-checkbox>`** (default: `var(--lr-color-brand)`) — Box border while pressed."},{"name":"--lr-checkbox-active-ring","description":"**`<lr-checkbox>`** (default: `var(--lr-color-brand-quiet)`) — Outer box ring while pressed."},{"name":"--lr-checkbox-box-size","description":"**`<lr-checkbox>`** (default: `min(var(--lr-icon-button-size), calc(var(--lr-form-control-height) * 0.7))`) — Edge length of `[part='box']`. Derived from the `size` tier's shared control height, so the box lines up with an `<lr-input>`/`<lr-select>`/`<lr-button>` of the same `size`; set it to pin the box independently of the tier."},{"name":"--lr-checkbox-checked-bg","description":"**`<lr-checkbox>`** (default: `var(--lr-color-brand)`) — Background of `[part='box']` while `checked` or `indeterminate`. Retint just this control's checked fill without touching the shared `--lr-color-brand` token every other component also reads."},{"name":"--lr-checkbox-checked-border","description":"**`<lr-checkbox>`** (default: `var(--lr-color-brand)`) — Border color of `[part='box']` while `checked` or `indeterminate`."},{"name":"--lr-checkbox-group-invalid-border","description":"**`<lr-checkbox-group>`** (default: `var(--lr-color-danger)`) — Border around the option collection while invalid chrome is visible."},{"name":"--lr-checkbox-group-option-gap","description":"**`<lr-checkbox-group>`** (default: `calc(var(--lr-form-control-height) * 0.2)`) — Gap between adjacent options, scaled by `size`."},{"name":"--lr-checkbox-group-row-gap","description":"**`<lr-checkbox-group>`** (default: `calc(var(--lr-form-control-height) * 0.1)`) — Vertical gap between the group's label, options and messages, scaled by `size`."},{"name":"--lr-checkbox-hover-border","description":"**`<lr-checkbox>`** (default: `var(--lr-color-brand)`) — Box border while the enabled interactive control is hovered."},{"name":"--lr-checkbox-invalid-border","description":"**`<lr-checkbox>`** (default: `var(--lr-color-danger)`) — Box border while invalid chrome is visible."},{"name":"--lr-checkbox-label-indent","description":"**`<lr-checkbox>`** (default: `calc(var(--lr-checkbox-box-size) + var(--lr-space-s))`) — The inline distance from the control's start edge to the start of the label text, i.e. the box's own floor plus the gap next to it — so it tracks `size` along with the box. Published so a consumer composing per-option hint text under the label can align it without re-deriving that formula from the shadow styles, and used as the source of the real gap so the two cannot drift. Setting it on the element (or on `lr-checkbox` in your own stylesheet) moves the label; because custom properties inherit down and not sideways, it is *not* readable from a sibling node in your tree — align a sibling by computing the same formula from `--lr-theme-icon-button-size`, `--lr-theme-form-control-height-*` and `--lr-theme-space-s`, which you control."},{"name":"--lr-checkpoint-spin-duration","description":"**`<lr-checkpoint>`** (default: `var(--lr-transition-ambient)`) — Restoring-spinner timing, inheriting the shared ambient-motion token by default (stopped under reduced motion)."},{"name":"--lr-chip-accent","description":"**`<lr-chip>`** (default: `var(--lr-color-text)`) — Text/icon color of the pill. Each non-neutral `variant` changes its private default to that variant's loud fill."},{"name":"--lr-chip-bg","description":"**`<lr-chip>`** (default: `var(--lr-color-surface)`) — Background of the pill. Each non-neutral `variant` changes its private default to that variant's quiet fill."},{"name":"--lr-chip-border","description":"**`<lr-chip>`** (default: `var(--lr-color-border)`) — Border color of the pill. Every non-neutral `variant` changes its private default to `transparent`."},{"name":"--lr-chip-font-size","description":"**`<lr-chip>`** (default: `var(--lr-font-size-sm)`) — Label font size. Each `size` changes its private default to that step's font size; an inherited or direct public value still wins."},{"name":"--lr-chip-gap","description":"**`<lr-chip>`** (default: `var(--lr-space-xs)`) — Gap between the icon, label, and remove button. Each `size` changes its private default to that step's gap."},{"name":"--lr-chip-group-gap","description":"**`<lr-chip-group>`** (default: `var(--lr-space-xs)`) — Gap between `[part=\"base\"]`'s wrapped children, chips and the overflow indicator alike."},{"name":"--lr-chip-group-overflow-expanded-border-style","description":"**`<lr-chip-group>`** (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."},{"name":"--lr-chip-group-overflow-expanded-color","description":"**`<lr-chip-group>`** (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."},{"name":"--lr-chip-height","description":"**`<lr-chip>`** — Exact block size of the chip. Undeclared by default, so the chip grows to fit its content (floored by `--lr-chip-min-height` when interactive). Set it to pin a fixed height. A value below the shared interactive target is for non-interactive chips only."},{"name":"--lr-chip-icon-size","description":"**`<lr-chip>`** (default: `var(--lr-font-size-sm)`) — Font size of the `start` slot wrapper. Its private default follows each `size` step's icon size; an inherited or direct public value remains authoritative."},{"name":"--lr-chip-min-height","description":"**`<lr-chip>`** (default: `var(--lr-size-1-5rem)`) — Component density floor for an interactive chip. The real toggle/remove controls also enforce the shared `--lr-icon-button-size` target floor."},{"name":"--lr-chip-padding-block","description":"**`<lr-chip>`** (default: `var(--lr-size-0-25rem)`) — Block padding of the pill. Each `size` changes its private default to that step's block padding; an inherited or direct public value remains authoritative."},{"name":"--lr-chip-padding-inline","description":"**`<lr-chip>`** (default: `var(--lr-space-s)`) — Inline padding of the pill. Each `size` changes its private default to that step's inline padding; an inherited or direct public value remains authoritative."},{"name":"--lr-chip-pressed-bg","description":"**`<lr-chip>`** (default: `var(--lr-chip-bg)`) — Background while a toggleable chip is selected, independently themeable from its resting background."},{"name":"--lr-chip-pressed-border","description":"**`<lr-chip>`** (default: `var(--lr-chip-accent)`) — Border color while a toggleable chip is selected, independently themeable from the label/icon color."},{"name":"--lr-chip-radius","description":"**`<lr-chip>`** (default: `var(--lr-radius)`) — Corner radius of the pill and of the remove button, kept in sync so retuning one retunes both. `pill` changes its private default to `var(--lr-radius-pill)`. Does not vary by `size` tier."},{"name":"--lr-chunk-inspector-current-bg","description":"**`<lr-chunk-inspector>`** (default: `var(--lr-color-brand-quiet)`) — Background of the chunk matching `activeChunkId`. **Contrast-sensitive:** paired with `--lr-chunk-inspector-current-color`, which has to keep a 4.5:1 ratio against it."},{"name":"--lr-chunk-inspector-current-color","description":"**`<lr-chunk-inspector>`** (default: `var(--lr-color-text)`) — Text color of the current chunk's `[part=\"score\"]` line. **Contrast-sensitive:** the quiet token it replaces only reaches ~4.24:1 against the current background, so override this together with `--lr-chunk-inspector-current-bg`, never alone."},{"name":"--lr-citation-badge-accent","description":"**`<lr-citation-badge>`** (default: `var(--lr-color-text-quiet)`) — Text color of `base`, and its hover border color. Its private default follows the reflected `status`: success for `high`/`verified`, warning for `medium`/`low`, and danger for `unverified`; a public value wins."},{"name":"--lr-citation-badge-bg","description":"**`<lr-citation-badge>`** (default: `transparent`) — Background of `base`. Its private default follows `status` to the matching `-quiet` tone (`success`/`warning`/`danger`); a public value wins."},{"name":"--lr-citation-badge-border","description":"**`<lr-citation-badge>`** (default: `transparent`) — Resting border color of `base`; no `status` changes it, so it stays transparent unless a host overrides it."},{"name":"--lr-claim-evidence-compact-gap","description":"**`<lr-claim-evidence>`** (default: `var(--lr-space-xs)`) — Gap between `[part=\"claim-trigger\"]`'s columns while `compact`."},{"name":"--lr-claim-evidence-compact-padding","description":"**`<lr-claim-evidence>`** (default: `var(--lr-space-xs)`) — `[part=\"claim-trigger\"]` padding while `compact`."},{"name":"--lr-code-block-active-line-outline-color","description":"**`<lr-code-block>`** (default: `var(--lr-color-brand)`) — Outline color of the line marked active by `active-highlight-id`. Retints just that outline, leaving every other `--lr-color-brand` surface in the component (header pill, hover states, focus ring) alone. Inherits, so it can also be set on an ancestor or at the theme level.\n\n**`<lr-code-block-core>`** (default: `var(--lr-color-brand)`) — Outline color of the line marked active by `active-highlight-id`, leaving every other `--lr-color-brand` surface in the component alone."},{"name":"--lr-code-block-font","description":"**`<lr-code-block>`, `<lr-code-block-core>`** (default: `var(--lr-font-mono)`) — Monospace family for the rendered `pre` and `code`."},{"name":"--lr-code-block-highlighted-line-bg","description":"**`<lr-code-block>`** (default: `var(--lr-color-warning-quiet)`) — Background color of a line marked by `highlight-lines` or a `line-range` entry in `highlights`, in both the light and dark-theme (shiki) rendering paths. Retints just that background, leaving every other `--lr-color-warning-quiet` surface alone. Inherits, so it can also be set on an ancestor or at the theme level.\n\n**`<lr-code-block-core>`** (default: `var(--lr-color-warning-quiet)`) — Background color of a line marked by `highlight-lines` or a `line-range` entry in `highlights`. Shared with `lr-code-block` (this component reuses its stylesheet), leaving every other `--lr-color-warning-quiet` surface alone."},{"name":"--lr-code-block-language-bg","description":"**`<lr-code-block>`** (default: `var(--lr-color-brand-quiet)`) — Background of the `language` badge in `[part=\"header\"]`.\n\n**`<lr-code-block-core>`** (default: `var(--lr-color-brand-quiet)`) — Background of the `language` badge in `[part=\"header\"]`. Shared with `lr-code-block` (this component reuses its stylesheet)."},{"name":"--lr-code-block-language-color","description":"**`<lr-code-block>`** (default: `var(--lr-color-brand)`) — Text color of the `language` badge. Same default as `--lr-code-editor-tab-size`, so the editable and read-only code surfaces agree; `lr-markdown`/`lr-markdown-core` declare the same token for their own `code-block` part (they are sibling elements, so they cannot inherit this one). Read as a token and never written inline, so a host override survives shiki's own inline `style` on the highlighted `pre`. The default is a `var()` fallback at the point of use rather than a `:host` declaration, so it inherits: set it on the element, a container, or `:root` and it reaches every code surface below. The markdown surface wraps (`white-space: pre-wrap`) while this one does not, so the same value can look different on a wrapped line, where tab stops restart.\n\n**`<lr-code-block-core>`** (default: `var(--lr-color-brand)`) — Text color of the `language` badge."},{"name":"--lr-code-block-max-height","description":"**`<lr-code-block>`, `<lr-code-block-core>`** (default: `none`) — Scroll cap applied to `body`. The `max-height` attribute, when set, writes this same property inline on `body` and therefore wins."},{"name":"--lr-code-block-tab-size","description":"**`<lr-code-block>`** (default: `2`) — Tab width for the rendered code, applied to `pre`.\n\n**`<lr-code-block-core>`** (default: `2`) — Tab width for the rendered code, applied to `pre`. Shared with `lr-code-block` (this component reuses its stylesheet), `lr-code-editor`, and the markdown viewers' own `code-block` part, so every code surface agrees on a tab's width.\n\n**`<lr-markdown>`, `<lr-markdown-core>`** (default: `2`) — Tab width for a rendered fenced/indented `code-block`. Deliberately the same token (and default) `lr-code-block` and `lr-code-editor` use, so a consumer sets one tab width for every code surface — it is declared here rather than inherited because `lr-code-block` is a sibling element, not an ancestor. A markdown code block wraps (`white-space: pre-wrap`) while `lr-code-block` does not, so the same value can render differently on a wrapped line, where tab stops restart."},{"name":"--lr-code-editor-border","description":"**`<lr-code-editor>`** (default: `var(--lr-color-border)`) — Resting editor-frame border color, independent of the hover and invalid colors below."},{"name":"--lr-code-editor-fill","description":"**`<lr-code-editor>`** (default: `var(--lr-color-surface)`) — Resting editor-frame background."},{"name":"--lr-code-editor-font-size","description":"**`<lr-code-editor>`** (default: `var(--lr-font-size-m)`) — Font size of the gutter's line numbers and the textarea, from the active `size` tier."},{"name":"--lr-code-editor-hover-border","description":"**`<lr-code-editor>`** (default: `var(--lr-color-brand)`) — Editor-frame border while the enabled surface is hovered."},{"name":"--lr-code-editor-invalid-border","description":"**`<lr-code-editor>`** (default: `var(--lr-color-danger)`) — Editor-frame border while invalid chrome is visible."},{"name":"--lr-code-editor-line-height","description":"**`<lr-code-editor>`** (default: `1.5`) — Line height shared by the gutter and the textarea, so line numbers stay aligned with their lines."},{"name":"--lr-code-editor-min-block-size","description":"**`<lr-code-editor>`** (default: `var(--lr-size-8rem)`) — Minimum block size of the editor frame and its textarea. Comes from the active `size` tier by default; assign it directly to override that tier's value."},{"name":"--lr-code-editor-padding","description":"**`<lr-code-editor>`** (default: `var(--lr-space-s)`) — Padding of the gutter (block side only) and the textarea (all sides), from the active `size` tier."},{"name":"--lr-code-editor-tab-size","description":"**`<lr-code-editor>`** (default: `2`) — The textarea's `tab-size`. The single channel for tab width — the class writes this token rather than setting `tab-size` directly."},{"name":"--lr-color-border","description":"**Shared design token** — Canonical shared component token for color border. Reads `--lr-theme-color-surface-border`."},{"name":"--lr-color-border-strong","description":"**Shared design token** — Canonical shared component token for color border strong. Reads `--lr-theme-color-border-strong`."},{"name":"--lr-color-brand","description":"**Shared design token** — Canonical shared component token for color brand."},{"name":"--lr-color-brand-border-loud","description":"**Shared design token** — Canonical shared component token for color brand border loud. Reads `--lr-theme-color-brand-border-loud`."},{"name":"--lr-color-brand-border-normal","description":"**Shared design token** — Canonical shared component token for color brand border normal. Reads `--lr-theme-color-brand-border-normal`."},{"name":"--lr-color-brand-border-quiet","description":"**Shared design token** — Canonical shared component token for color brand border quiet. Reads `--lr-theme-color-brand-border-quiet`."},{"name":"--lr-color-brand-fill-loud","description":"**Shared design token** — Canonical shared component token for color brand fill loud. Reads `--lr-theme-color-brand-fill-loud`."},{"name":"--lr-color-brand-fill-normal","description":"**Shared design token** — Canonical shared component token for color brand fill normal. Reads `--lr-theme-color-brand-fill-normal`."},{"name":"--lr-color-brand-fill-quiet","description":"**Shared design token** — Canonical shared component token for color brand fill quiet. Reads `--lr-theme-color-brand-fill-quiet`."},{"name":"--lr-color-brand-on-loud","description":"**Shared design token** — Canonical shared component token for color brand on loud. Reads `--lr-theme-color-brand-on-loud`."},{"name":"--lr-color-brand-on-normal","description":"**Shared design token** — Canonical shared component token for color brand on normal. Reads `--lr-theme-color-brand-on-normal`."},{"name":"--lr-color-brand-on-quiet","description":"**Shared design token** — Canonical shared component token for color brand on quiet. Reads `--lr-theme-color-brand-on-quiet`."},{"name":"--lr-color-brand-quiet","description":"**Shared design token** — Canonical shared component token for color brand quiet."},{"name":"--lr-color-chart-1","description":"**`<lr-embedding-explorer>`** (default: `var(--lr-theme-color-chart-1,#0e006e)`) — First cluster color.\n\n**Shared design token** — Canonical shared component token for color chart 1. Reads `--lr-theme-color-chart-1`."},{"name":"--lr-color-chart-2","description":"**`<lr-embedding-explorer>`** (default: `var(--lr-theme-color-chart-2,#4d011a)`) — Second cluster color.\n\n**Shared design token** — Canonical shared component token for color chart 2. Reads `--lr-theme-color-chart-2`."},{"name":"--lr-color-chart-3","description":"**`<lr-embedding-explorer>`** (default: `var(--lr-theme-color-chart-3,#862002)`) — Third cluster color.\n\n**Shared design token** — Canonical shared component token for color chart 3. Reads `--lr-theme-color-chart-3`."},{"name":"--lr-color-chart-4","description":"**`<lr-embedding-explorer>`** (default: `var(--lr-theme-color-chart-4,#503983)`) — Fourth cluster color.\n\n**Shared design token** — Canonical shared component token for color chart 4. Reads `--lr-theme-color-chart-4`."},{"name":"--lr-color-chart-5","description":"**`<lr-embedding-explorer>`** (default: `var(--lr-theme-color-chart-5,#315fdd)`) — Fifth cluster color.\n\n**Shared design token** — Canonical shared component token for color chart 5. Reads `--lr-theme-color-chart-5`."},{"name":"--lr-color-chart-6","description":"**`<lr-embedding-explorer>`** (default: `var(--lr-theme-color-chart-6,#935e7c)`) — Sixth cluster color.\n\n**Shared design token** — Canonical shared component token for color chart 6. Reads `--lr-theme-color-chart-6`."},{"name":"--lr-color-chart-7","description":"**`<lr-embedding-explorer>`** (default: `var(--lr-theme-color-chart-7,#de6906)`) — Seventh cluster color.\n\n**Shared design token** — Canonical shared component token for color chart 7. Reads `--lr-theme-color-chart-7`."},{"name":"--lr-color-chart-8","description":"**`<lr-embedding-explorer>`** (default: `var(--lr-theme-color-chart-8,#8f81d3)`) — Eighth cluster color; later clusters wrap through the same ordered palette.\n\n**Shared design token** — Canonical shared component token for color chart 8. Reads `--lr-theme-color-chart-8`."},{"name":"--lr-color-danger","description":"**Shared design token** — Canonical shared component token for color danger."},{"name":"--lr-color-danger-border-loud","description":"**Shared design token** — Canonical shared component token for color danger border loud. Reads `--lr-theme-color-danger-border-loud`."},{"name":"--lr-color-danger-border-normal","description":"**Shared design token** — Canonical shared component token for color danger border normal. Reads `--lr-theme-color-danger-border-normal`."},{"name":"--lr-color-danger-border-quiet","description":"**Shared design token** — Canonical shared component token for color danger border quiet. Reads `--lr-theme-color-danger-border-quiet`."},{"name":"--lr-color-danger-fill-loud","description":"**Shared design token** — Canonical shared component token for color danger fill loud. Reads `--lr-theme-color-danger-fill-loud`."},{"name":"--lr-color-danger-fill-normal","description":"**Shared design token** — Canonical shared component token for color danger fill normal. Reads `--lr-theme-color-danger-fill-normal`."},{"name":"--lr-color-danger-fill-quiet","description":"**Shared design token** — Canonical shared component token for color danger fill quiet. Reads `--lr-theme-color-danger-fill-quiet`."},{"name":"--lr-color-danger-on-loud","description":"**Shared design token** — Canonical shared component token for color danger on loud. Reads `--lr-theme-color-danger-on-loud`."},{"name":"--lr-color-danger-on-normal","description":"**Shared design token** — Canonical shared component token for color danger on normal. Reads `--lr-theme-color-danger-on-normal`."},{"name":"--lr-color-danger-on-quiet","description":"**Shared design token** — Canonical shared component token for color danger on quiet. Reads `--lr-theme-color-danger-on-quiet`."},{"name":"--lr-color-danger-quiet","description":"**Shared design token** — Canonical shared component token for color danger quiet."},{"name":"--lr-color-mix-active","description":"**Shared design token** — Canonical shared component token for color mix active. Reads `--lr-theme-color-mix-active`."},{"name":"--lr-color-mix-hover","description":"**Shared design token** — Canonical shared component token for color mix hover. Reads `--lr-theme-color-mix-hover`."},{"name":"--lr-color-mix-partner","description":"**Shared design token** — Canonical shared component token for color mix partner. Reads `--lr-theme-color-mix-partner`."},{"name":"--lr-color-neutral","description":"**Shared design token** — Canonical shared component token for color neutral."},{"name":"--lr-color-neutral-border-loud","description":"**Shared design token** — Canonical shared component token for color neutral border loud. Reads `--lr-theme-color-neutral-border-loud`."},{"name":"--lr-color-neutral-border-normal","description":"**Shared design token** — Canonical shared component token for color neutral border normal. Reads `--lr-theme-color-neutral-border-normal`."},{"name":"--lr-color-neutral-border-quiet","description":"**Shared design token** — Canonical shared component token for color neutral border quiet. Reads `--lr-theme-color-neutral-border-quiet`."},{"name":"--lr-color-neutral-fill-loud","description":"**Shared design token** — Canonical shared component token for color neutral fill loud. Reads `--lr-theme-color-neutral-fill-loud`."},{"name":"--lr-color-neutral-fill-normal","description":"**Shared design token** — Canonical shared component token for color neutral fill normal. Reads `--lr-theme-color-neutral-fill-normal`."},{"name":"--lr-color-neutral-fill-quiet","description":"**Shared design token** — Canonical shared component token for color neutral fill quiet. Reads `--lr-theme-color-neutral-fill-quiet`."},{"name":"--lr-color-neutral-on-loud","description":"**Shared design token** — Canonical shared component token for color neutral on loud. Reads `--lr-theme-color-neutral-on-loud`."},{"name":"--lr-color-neutral-on-normal","description":"**Shared design token** — Canonical shared component token for color neutral on normal. Reads `--lr-theme-color-neutral-on-normal`."},{"name":"--lr-color-neutral-on-quiet","description":"**Shared design token** — Canonical shared component token for color neutral on quiet. Reads `--lr-theme-color-neutral-on-quiet`."},{"name":"--lr-color-no-data","description":"**Shared design token** — Canonical shared component token for color no data. Reads `--lr-theme-color-no-data`."},{"name":"--lr-color-on-brand","description":"**Shared design token** — Canonical shared component token for color on brand."},{"name":"--lr-color-on-danger","description":"**Shared design token** — Canonical shared component token for color on danger."},{"name":"--lr-color-on-neutral","description":"**Shared design token** — Canonical shared component token for color on neutral."},{"name":"--lr-color-on-strong-overlay","description":"**Shared design token** — Canonical shared component token for color on strong overlay. Reads `--lr-theme-color-on-strong-overlay`."},{"name":"--lr-color-on-success","description":"**Shared design token** — Canonical shared component token for color on success."},{"name":"--lr-color-on-warning","description":"**Shared design token** — Canonical shared component token for color on warning."},{"name":"--lr-color-overlay","description":"**Shared design token** — Canonical shared component token for color overlay. Reads `--lr-theme-color-overlay`."},{"name":"--lr-color-overlay-strong","description":"**Shared design token** — Canonical shared component token for color overlay strong. Reads `--lr-theme-color-overlay-strong`."},{"name":"--lr-color-picker-border-color","description":"**`<lr-color-picker>`** (default: `var(--lr-color-border)`) — Resting trigger border color."},{"name":"--lr-color-picker-checker-color","description":"**`<lr-color-picker>`** (default: `var(--lr-color-border)`) — Tint of the alpha checkerboard."},{"name":"--lr-color-picker-checker-size","description":"**`<lr-color-picker>`** (default: `var(--lr-size-0-5rem)`) — Cell size of the alpha checkerboard."},{"name":"--lr-color-picker-gap","description":"**`<lr-color-picker>`** (default: `var(--lr-space-xs)`) — Gap between field chrome and panel rows."},{"name":"--lr-color-picker-grid-block-size","description":"**`<lr-color-picker>`** (default: `var(--lr-size-8rem)`) — Saturation/brightness grid height."},{"name":"--lr-color-picker-grid-handle-size","description":"**`<lr-color-picker>`** (default: `var(--lr-size-1rem)`) — Diameter of the grid handle."},{"name":"--lr-color-picker-grid-hue","description":"**`<lr-color-picker>`** — The saturation/brightness grid's fully-saturated base hue. Rewritten on every render, like `--lr-color-picker-swatch-color`."},{"name":"--lr-color-picker-grid-inline-size","description":"**`<lr-color-picker>`** (default: `var(--lr-size-15rem)`) — Saturation/brightness grid width."},{"name":"--lr-color-picker-hover-border-color","description":"**`<lr-color-picker>`** (default: `var(--lr-color-brand)`) — Hover border color."},{"name":"--lr-color-picker-hue-stops","description":"**`<lr-color-picker>`** — The hue ramp's own gradient stops, shared by the hue slider in both text directions. Defaults to the six-stop sRGB hue wheel."},{"name":"--lr-color-picker-opacity-gradient","description":"**`<lr-color-picker>`** — The opacity slider's transparent-to-opaque ramp, built from the current colour and text direction. Rewritten on every render."},{"name":"--lr-color-picker-palette-swatch-size","description":"**`<lr-color-picker>`** (default: `var(--lr-size-1-5rem)`) — Size of a palette swatch."},{"name":"--lr-color-picker-radius","description":"**`<lr-color-picker>`** (default: `var(--lr-radius)`) — Trigger, grid, and panel corner radius."},{"name":"--lr-color-picker-selected-border","description":"**`<lr-color-picker>`** (default: `var(--lr-color-brand)`) — Border of the selected palette swatch."},{"name":"--lr-color-picker-selected-check-color","description":"**`<lr-color-picker>`** (default: `var(--lr-color-surface)`) — Checkmark color on the selected palette swatch."},{"name":"--lr-color-picker-slider-block-size","description":"**`<lr-color-picker>`** (default: `var(--lr-size-0-75rem)`) — Thickness of the visible hue/opacity ramp. The slider's own pointer target stays floored at 24px regardless."},{"name":"--lr-color-picker-slider-handle-size","description":"**`<lr-color-picker>`** (default: `var(--lr-size-1-25rem)`) — Diameter of a slider handle."},{"name":"--lr-color-picker-swatch-color","description":"**`<lr-color-picker>`** — The live colour painted on the trigger, preview, slider handles, and palette swatches. Rewritten on every render, so it reports state rather than accepting configuration."},{"name":"--lr-color-picker-swatch-disabled-opacity","description":"**`<lr-color-picker>`** (default: `0.5`) — Opacity of a palette swatch whose own entry sets `disabled`."},{"name":"--lr-color-picker-swatch-size","description":"**`<lr-color-picker>`** (default: `var(--lr-form-control-height,var(--lr-size-2-5rem))`) — The centered visible swatch's inline and block size. The interactive trigger stays at least `--lr-icon-button-size`; larger swatch tiers expand it. The value reads the shared form-control height ladder, so the visible swatch follows neighbouring field density."},{"name":"--lr-color-shadow","description":"**Shared design token** — Canonical shared component token for color shadow. Reads `--lr-theme-color-shadow`."},{"name":"--lr-color-success","description":"**Shared design token** — Canonical shared component token for color success."},{"name":"--lr-color-success-border-loud","description":"**Shared design token** — Canonical shared component token for color success border loud. Reads `--lr-theme-color-success-border-loud`."},{"name":"--lr-color-success-border-normal","description":"**Shared design token** — Canonical shared component token for color success border normal. Reads `--lr-theme-color-success-border-normal`."},{"name":"--lr-color-success-border-quiet","description":"**Shared design token** — Canonical shared component token for color success border quiet. Reads `--lr-theme-color-success-border-quiet`."},{"name":"--lr-color-success-fill-loud","description":"**Shared design token** — Canonical shared component token for color success fill loud. Reads `--lr-theme-color-success-fill-loud`."},{"name":"--lr-color-success-fill-normal","description":"**Shared design token** — Canonical shared component token for color success fill normal. Reads `--lr-theme-color-success-fill-normal`."},{"name":"--lr-color-success-fill-quiet","description":"**Shared design token** — Canonical shared component token for color success fill quiet. Reads `--lr-theme-color-success-fill-quiet`."},{"name":"--lr-color-success-on-loud","description":"**Shared design token** — Canonical shared component token for color success on loud. Reads `--lr-theme-color-success-on-loud`."},{"name":"--lr-color-success-on-normal","description":"**Shared design token** — Canonical shared component token for color success on normal. Reads `--lr-theme-color-success-on-normal`."},{"name":"--lr-color-success-on-quiet","description":"**Shared design token** — Canonical shared component token for color success on quiet. Reads `--lr-theme-color-success-on-quiet`."},{"name":"--lr-color-success-quiet","description":"**Shared design token** — Canonical shared component token for color success quiet."},{"name":"--lr-color-surface","description":"**Shared design token** — Canonical shared component token for color surface. Reads `--lr-theme-color-surface-default`."},{"name":"--lr-color-surface-overlay","description":"**Shared design token** — Canonical shared component token for color surface overlay. Reads `--lr-theme-color-surface-overlay`."},{"name":"--lr-color-surface-raised","description":"**Shared design token** — Canonical shared component token for color surface raised. Reads `--lr-theme-color-surface-raised`."},{"name":"--lr-color-text","description":"**Shared design token** — Canonical shared component token for color text. Reads `--lr-theme-color-text-normal`."},{"name":"--lr-color-text-quiet","description":"**Shared design token** — Canonical shared component token for color text quiet. Reads `--lr-theme-color-text-quiet`."},{"name":"--lr-color-warning","description":"**Shared design token** — Canonical shared component token for color warning."},{"name":"--lr-color-warning-border-loud","description":"**Shared design token** — Canonical shared component token for color warning border loud. Reads `--lr-theme-color-warning-border-loud`."},{"name":"--lr-color-warning-border-normal","description":"**Shared design token** — Canonical shared component token for color warning border normal. Reads `--lr-theme-color-warning-border-normal`."},{"name":"--lr-color-warning-border-quiet","description":"**Shared design token** — Canonical shared component token for color warning border quiet. Reads `--lr-theme-color-warning-border-quiet`."},{"name":"--lr-color-warning-fill-loud","description":"**Shared design token** — Canonical shared component token for color warning fill loud. Reads `--lr-theme-color-warning-fill-loud`."},{"name":"--lr-color-warning-fill-normal","description":"**Shared design token** — Canonical shared component token for color warning fill normal. Reads `--lr-theme-color-warning-fill-normal`."},{"name":"--lr-color-warning-fill-quiet","description":"**Shared design token** — Canonical shared component token for color warning fill quiet. Reads `--lr-theme-color-warning-fill-quiet`."},{"name":"--lr-color-warning-on-loud","description":"**Shared design token** — Canonical shared component token for color warning on loud. Reads `--lr-theme-color-warning-on-loud`."},{"name":"--lr-color-warning-on-normal","description":"**Shared design token** — Canonical shared component token for color warning on normal. Reads `--lr-theme-color-warning-on-normal`."},{"name":"--lr-color-warning-on-quiet","description":"**Shared design token** — Canonical shared component token for color warning on quiet. Reads `--lr-theme-color-warning-on-quiet`."},{"name":"--lr-color-warning-quiet","description":"**Shared design token** — Canonical shared component token for color warning quiet."},{"name":"--lr-combobox-border-color","description":"**`<lr-combobox>`** (default: `var(--lr-color-border)`) — Resting border color of the trigger row, `transparent` by default on the `filled` treatment."},{"name":"--lr-combobox-expand-size","description":"**`<lr-combobox>`** — Decorative expand-icon box size, scaled by `size`."},{"name":"--lr-combobox-fill","description":"**`<lr-combobox>`** (default: `var(--lr-color-surface)`) — Resting background of the trigger row. The `filled`/`filled-outlined` treatments default it to `--lr-color-surface-raised`; a value set here wins over every treatment."},{"name":"--lr-combobox-font-size","description":"**`<lr-combobox>`** (default: `var(--lr-form-control-font-size)`) — Input text size, from the shared form-control size ladder."},{"name":"--lr-combobox-gap","description":"**`<lr-combobox>`** (default: `var(--lr-space-xs)`) — Gap between the start/end adornments, tags, and filter input inside the trigger row. Unlike the size knobs above it does not vary by `size` tier. Override it to retune without a `::part(combobox)` rule."},{"name":"--lr-combobox-open-border-color","description":"**`<lr-combobox>`** (default: `var(--lr-color-brand)`) — Border color of the trigger row while it holds focus — the state the listbox opens in. Bound to `:focus-within` rather than to `open`, so it paints on a focused row whose listbox is closed too; the name is symmetric with `lr-select`'s `--lr-select-open-border-color`, which is gated on `open` itself."},{"name":"--lr-combobox-option-active-bg","description":"**`<lr-combobox>`** (default: `var(--lr-color-brand-quiet)`) — Background of a hovered or keyboard-active option row."},{"name":"--lr-combobox-option-badge-bg","description":"**`<lr-combobox>`** (default: `var(--lr-color-brand-quiet)`) — Background of the `[part='option-badge']` trailing metadata badge, and the \"not in catalog\" badge on a synthetic unmatched-value row (`show-unknown-option`)."},{"name":"--lr-combobox-option-selected-bg","description":"**`<lr-combobox>`** (default: `transparent`) — Background of the currently-selected option row. Not declared on `:host`; retheme without hijacking `--lr-color-brand`."},{"name":"--lr-combobox-option-selected-border","description":"**`<lr-combobox>`** (default: `var(--lr-color-brand)`) — Border color of the selected option row."},{"name":"--lr-combobox-option-selected-color","description":"**`<lr-combobox>`** (default: `var(--lr-color-brand)`) — Text color of the selected option row."},{"name":"--lr-combobox-option-selected-font-weight","description":"**`<lr-combobox>`** (default: `var(--lr-font-weight-semibold)`) — Font weight of the selected option row."},{"name":"--lr-combobox-radius","description":"**`<lr-combobox>`** (default: `var(--lr-radius)`) — Corner radius of the trigger row (`[part='combobox']`). Does not vary by `size` tier; the `pill` attribute swaps it for `--lr-radius-pill`."},{"name":"--lr-combobox-tag-font-size","description":"**`<lr-combobox>`** — Selected-tag text size."},{"name":"--lr-combobox-tag-padding","description":"**`<lr-combobox>`** — Selected-tag padding."},{"name":"--lr-combobox-trigger-height","description":"**`<lr-combobox>`** — Exact input-container height. Unset by default, which leaves `--lr-combobox-trigger-min-height` as a floor only; set it to a length to both floor and cap the row (e.g. to pixel-match `<lr-input>`/`<lr-select>` in the same toolbar). Because it is never declared by the component itself, it can be set from an ancestor or an outer-tree rule as well as inline on the element. Intended for a single-row combobox: in `multiple` mode a tag row long enough to wrap overflows the pinned box visibly (nothing is clipped or made unreachable), so leave it unset there."},{"name":"--lr-combobox-trigger-min-height","description":"**`<lr-combobox>`** (default: `var(--lr-form-control-height)`) — Minimum input-container block size. Reads the shared form-control height ladder, so retuning `--lr-theme-form-control-height-*` moves this control and every sibling field together."},{"name":"--lr-combobox-trigger-padding","description":"**`<lr-combobox>`** — Padding inside the input container."},{"name":"--lr-combobox-unknown-value-border-color","description":"**`<lr-combobox>`** (default: `var(--lr-color-border)`) — Border color of the same unknown-value tag."},{"name":"--lr-combobox-unknown-value-border-style","description":"**`<lr-combobox>`** (default: `dashed`) — Border style of a `multiple`-mode tag whose committed value matches no current option/row."},{"name":"--lr-command-palette-active-bg","description":"**`<lr-command-palette>`** (default: `var(--lr-color-brand-quiet)`) — Background of the active (keyboard-highlighted, `data-active=\"true\"`) command row. Declared as an inline `var()` fallback (never on `:host`), so setting it on the element or an ancestor recolors only the active row without hijacking the library-wide `--lr-color-brand-quiet` token."},{"name":"--lr-command-palette-group-height","description":"**`<lr-command-palette>`** (default: `var(--lr-size-2rem)`) — Virtual group-heading height; live changes rebuild heading/row transforms and the result extent."},{"name":"--lr-command-palette-list-max-block-size","description":"**`<lr-command-palette>`** (default: `50vh`) — Maximum height of the scrolling command list."},{"name":"--lr-command-palette-max-block-size","description":"**`<lr-command-palette>`** (default: `70vh`) — Maximum dialog height."},{"name":"--lr-command-palette-max-inline-size","description":"**`<lr-command-palette>`** (default: `var(--lr-size-48rem)`) — Maximum dialog width."},{"name":"--lr-command-palette-offset-block-start","description":"**`<lr-command-palette>`** (default: `12vh`) — Gap between the viewport top and the dialog."},{"name":"--lr-command-palette-row-height","description":"**`<lr-command-palette>`** (default: `var(--lr-size-3rem)`) — Virtual command-row height; live changes rebuild row transforms, scrolling coordinates, and the result extent."},{"name":"--lr-command-palette-search-font-size","description":"**`<lr-command-palette>`** (default: `inherit`) — Text size of the query field."},{"name":"--lr-command-palette-search-gap","description":"**`<lr-command-palette>`** (default: `var(--lr-space-s)`) — Gap between the leading glyph and the query field."},{"name":"--lr-command-palette-search-min-height","description":"**`<lr-command-palette>`** (default: `auto`) — Minimum row height of the query field, for matching it to a themed search field of a chosen density tier. Point it at `--lr-form-control-height-s` (or any tier of that ladder) to line the palette's own field up with the rest of an application's controls."},{"name":"--lr-command-palette-search-padding","description":"**`<lr-command-palette>`** (default: `var(--lr-space-m)`) — Gutter around the query row."},{"name":"--lr-command-palette-z-index","description":"**`<lr-command-palette>`** (default: `var(--lr-overlay-stack-index, var(--lr-layer-modal))`) — Stacking index of the backdrop."},{"name":"--lr-commit-card-background","description":"**`<lr-commit-card>`** (default: `transparent`) — Fill of the outer card (`[part=\"base\"]`) while `frame=\"card\"`, unset by default so the card takes the surface it sits on. `frame=\"plain\"` still removes the fill entirely."},{"name":"--lr-commit-card-border-color","description":"**`<lr-commit-card>`** (default: `var(--lr-color-border)`) — Colour of the outer card's border."},{"name":"--lr-commit-card-compact-padding","description":"**`<lr-commit-card>`** (default: `var(--lr-space-s)`) — `[part=\"base\"]` padding while `compact`."},{"name":"--lr-commit-card-radius","description":"**`<lr-commit-card>`** (default: `var(--lr-radius)`) — Corner radius of the outer card. `frame=\"plain\"` still squares the corners."},{"name":"--lr-community-card-bg","description":"**`<lr-community-card>`** (default: `var(--lr-color-surface)`) — Resting background of `[part=\"base\"]`. `frame=\"plain\"` still paints transparent."},{"name":"--lr-compare-panel-max-height","description":"**`<lr-compare-panel>`** (default: `var(--lr-size-24rem)`) — Cap on how tall each pane's scroll region grows before it scrolls internally."},{"name":"--lr-compare-panel-selected-background","description":"**`<lr-compare-panel>`** (default: `var(--lr-color-brand-quiet)`) — Selected vote button background."},{"name":"--lr-compare-panel-selected-border-color","description":"**`<lr-compare-panel>`** (default: `var(--lr-color-brand)`) — Selected vote button border color."},{"name":"--lr-compare-panel-selected-color","description":"**`<lr-compare-panel>`** (default: `var(--lr-color-brand)`) — Selected vote button text color."},{"name":"--lr-compare-panel-selected-font-weight","description":"**`<lr-compare-panel>`** (default: `var(--lr-font-weight-semibold)`) — Selected vote button font weight."},{"name":"--lr-confirm-bar-approved-color","description":"**`<lr-confirm-bar>`** (default: `var(--lr-color-success)`) — `[part='status']` text/icon color once `decision` is `'approved'`."},{"name":"--lr-confirm-bar-bg","description":"**`<lr-confirm-bar>`** (default: `var(--lr-color-surface)`) — Resting background of `[part='base']`. `frame=\"plain\"` still paints transparent."},{"name":"--lr-confirm-bar-compact-gap","description":"**`<lr-confirm-bar>`** (default: `var(--lr-space-s)`) — Gap between the row's items while `compact`."},{"name":"--lr-confirm-bar-compact-padding","description":"**`<lr-confirm-bar>`** (default: `var(--lr-space-s)`) — Padding of `[part='base']` while `compact`. Accepts any padding shorthand. Overridden entirely by `frame=\"plain\"`."},{"name":"--lr-confirm-bar-denied-color","description":"**`<lr-confirm-bar>`** (default: `var(--lr-color-danger)`) — `[part='status']` text/icon color once `decision` is `'denied'`."},{"name":"--lr-contact-viewer-max-height","description":"**`<lr-contact-viewer>`** (default: `none`) — Maximum block size of the scrollable body before it scrolls internally. Also settable via the `max-height` property."},{"name":"--lr-context-meter-disabled-opacity","description":"**`<lr-context-meter>`** (default: `var(--lr-opacity-disabled)`) — Opacity of a band or legend row whose `segments` entry sets `disabled`. The band keeps its own colour -- it is still the datum it always was -- and loses only the affordances that promise activation."},{"name":"--lr-context-meter-legend-swatch-size","description":"**`<lr-context-meter>`** (default: `var(--lr-size-0-625rem)`) — Inline and block size of a legend swatch."},{"name":"--lr-context-meter-segment-color","description":"**`<lr-context-meter>`** — Per-segment color. Set inline on `[part=\"segment\"]` by the component itself whenever that segment supplies a `color`; unset (and the token unread) otherwise, leaving the `data-tone` palette in charge. The matching `[part=\"legend-swatch\"]` reads the same property, so a swatch can never disagree with the band it stands for."},{"name":"--lr-context-meter-segment-seam-color","description":"**`<lr-context-meter>`** (default: `var(--lr-color-surface)`) — Color of the hairline seam painted between adjacent `bar`-shape segments."},{"name":"--lr-context-meter-selected-arc-stroke","description":"**`<lr-context-meter>`** (default: `16`) — Stroke width, in this component's `0 0 100 100` viewBox units, of a selected `ring`-shape arc. Arcs share one bounding box, so a selected arc reports itself by thickening in place rather than by an outline that would trace the whole ring."},{"name":"--lr-context-meter-selected-ring-color","description":"**`<lr-context-meter>`** (default: `var(--lr-color-text)`) — Colour of the inset ring marking a `bar`-shape band or a legend row whose index is in `selectedIndices`. Painted inside the shadow root because the state lives in the part name, and as a ring rather than an outline so it composes with the hover/press/focus outlines instead of being replaced by them."},{"name":"--lr-context-meter-selected-ring-width","description":"**`<lr-context-meter>`** (default: `var(--lr-border-width-thick)`) — Width of that selected ring."},{"name":"--lr-context-meter-track-bg","description":"**`<lr-context-meter>`** (default: `color-mix(in srgb, var(--lr-color-border) 30%, transparent)`) — Background of the unfilled remainder of the `bar`-shape track."},{"name":"--lr-context-meter-track-radius","description":"**`<lr-context-meter>`** (default: `calc(var(--lr-radius) * 0.5)`) — Corner radius of the `bar`-shape track."},{"name":"--lr-context-meter-track-size","description":"**`<lr-context-meter>`** (default: `var(--lr-size-0-5rem)`) — Block size (thickness) of the `bar`-shape track, and therefore of its filled segments."},{"name":"--lr-control-group-gap","description":"**`<lr-control-group>`** (default: `var(--lr-space-xs)`) — Gap between grouped controls."},{"name":"--lr-conversation-item-active-bg","description":"**`<lr-conversation-item>`** (default: `var(--lr-color-brand-quiet)`) — Background of the row while `active`. **Contrast-sensitive:** it is one half of a documented WCAG-AA pair — the active row's text is sized/toned for this background, so an override has to keep at least a 4.5:1 ratio against `--lr-conversation-item-active-color` (excerpt/timestamp) and against `--lr-color-text` (the label, which is not restyled by the pair)."},{"name":"--lr-conversation-item-active-color","description":"**`<lr-conversation-item>`** (default: `var(--lr-color-text)`) — Text color of `[part=\"excerpt\"]` and `[part=\"timestamp\"]` while `active`. **Contrast-sensitive:** it exists precisely because `--lr-color-text-quiet` only reaches ~4.25:1 against the active background; override it together with `--lr-conversation-item-active-bg`, never alone."},{"name":"--lr-conversation-item-active-indicator-color","description":"**`<lr-conversation-item>`** (default: `var(--lr-color-brand)`) — Color of the decorative `[part=\"active-indicator\"]` while `active`."},{"name":"--lr-conversation-item-active-indicator-inset-inline","description":"**`<lr-conversation-item>`** (default: `0 auto`) — Logical inline-start and inline-end insets for `[part=\"active-indicator\"]`; set `auto 0` to place it at inline-end."},{"name":"--lr-conversation-item-active-indicator-width","description":"**`<lr-conversation-item>`** (default: `var(--lr-size-2px)`) — Inline size of `[part=\"active-indicator\"]` while `active`."},{"name":"--lr-conversation-item-align","description":"**`<lr-conversation-item>`** (default: `flex-start`) — Cross-axis alignment of `[part=\"base\"]` and `[part=\"select-button\"]`. `flex-start` (the default) suits the common multi-line row (a title plus an `excerpt`); `center` reads better for a reliably single-line row with a taller trailing action (e.g. `actions`), but is not the default because it would misalign every existing multi-line row's title against its own baseline."},{"name":"--lr-conversation-item-compact-gap","description":"**`<lr-conversation-item>`** (default: `var(--lr-space-2xs)`) — Gap between `[part=\"base\"]`'s columns while `compact`."},{"name":"--lr-conversation-item-compact-padding","description":"**`<lr-conversation-item>`** (default: `var(--lr-space-xs) var(--lr-space-s)`) — `[part=\"base\"]` padding while `compact`."},{"name":"--lr-csv-viewer-highlight-color","description":"**`<lr-csv-viewer>`** (default: `var(--lr-color-brand)`) — Outline color of a highlighted cell. The active highlight changes a private warning-color default; an inherited or direct public value remains authoritative."},{"name":"--lr-csv-viewer-max-height","description":"**`<lr-csv-viewer>`** (default: `none`) — Maximum block size allocated to `[part=\"body\"]`; the nested virtual-list scrolls data rows within the remainder below the persistent header. The `maxHeight` property sets this token inline on `[part=\"base\"]`."},{"name":"--lr-dashboard-grid-cell-hover-outline-color","description":"**`<lr-dashboard-grid>`** (default: `var(--lr-color-border-strong)`) — Outline color of a cell's mouse-hover preview of its own `:focus-visible` ring (shown because every cell is a real focusable, draggable/resizable target). Set to `transparent` to opt out."},{"name":"--lr-dashboard-grid-collision-outline-color","description":"**`<lr-dashboard-grid>`** (default: `var(--lr-color-danger)`) — Outline color of a cell whose current drag/resize preview collides with another cell."},{"name":"--lr-dashboard-grid-columns","description":"**`<lr-dashboard-grid>`** (default: `12`) — Author override for the column count; otherwise the normalized `columns` property supplies the computed value."},{"name":"--lr-dashboard-grid-gap","description":"**`<lr-dashboard-grid>`** (default: `8px`) — Author override for the gap between cells; otherwise the normalized `gap` property supplies a pixel value."},{"name":"--lr-dashboard-grid-interaction-shadow","description":"**`<lr-dashboard-grid>`** (default: `var(--lr-shadow-m)`) — Box shadow applied to a cell for the duration of its pointer drag or resize interaction."},{"name":"--lr-dashboard-grid-row-height","description":"**`<lr-dashboard-grid>`** (default: `80px`) — Author override for row track height; otherwise the normalized `rowHeight` property supplies a pixel value."},{"name":"--lr-data-grid-cell-color","description":"**`<lr-data-grid>`** (default: `inherit`) — Text colour of body cells."},{"name":"--lr-data-grid-cell-link-color","description":"**`<lr-data-grid>`** (default: `var(--lr-color-brand)`) — Colour of anchors returned by a column formatter or row detail renderer. These render inside the grid's shadow root, beyond the reach of page CSS. Set `revert` to restore the user-agent default."},{"name":"--lr-data-grid-cell-link-hover-color","description":"**`<lr-data-grid>`** (default: `var(--lr-data-grid-cell-link-color,var(--lr-color-brand))`) — Colour of those anchors on hover, focus-visible, and active interaction."},{"name":"--lr-data-grid-control-active-background","description":"**`<lr-data-grid>`** — Pressed background for grid controls."},{"name":"--lr-data-grid-control-hover-background","description":"**`<lr-data-grid>`** — Hovered background for grid controls."},{"name":"--lr-data-grid-page-size-active-background","description":"**`<lr-data-grid>`** — Pressed page-size selector background."},{"name":"--lr-data-grid-row-active-background","description":"**`<lr-data-grid>`** — Pressed data-row background."},{"name":"--lr-data-grid-sortable-header-active-background","description":"**`<lr-data-grid>`** — Pressed sortable-header background."},{"name":"--lr-data-grid-sortable-header-hover-background","description":"**`<lr-data-grid>`** — Hovered sortable-header background."},{"name":"--lr-dataset-viewer-header-row-bg","description":"**`<lr-dataset-viewer>`** (default: `var(--lr-color-brand-quiet)`) — Background of `[part=\"header-row\"]`, independent of the highlight outline above."},{"name":"--lr-dataset-viewer-highlight-color","description":"**`<lr-dataset-viewer>`** (default: `var(--lr-color-brand)`) — Outline color of a highlighted cell. The active highlight changes a private warning-color default; an inherited or direct public value remains authoritative."},{"name":"--lr-dataset-viewer-max-height","description":"**`<lr-dataset-viewer>`** (default: `none`) — Maximum block size of `[part=\"body\"]` before it scrolls internally. The `maxHeight` property sets this token inline on `[part=\"base\"]`. `scrollMode='page'` deliberately ignores the cap and hands both axes to page flow so the sticky header can use the page scrollport."},{"name":"--lr-date-input-action-active-bg","description":"**`<lr-date-input>`** (default: `color-mix(...)`) — Clear/calendar action background while pressed."},{"name":"--lr-date-input-action-active-color","description":"**`<lr-date-input>`** (default: `var(--lr-date-input-action-hover-color,var(--lr-color-text))`) — Clear/calendar action color while pressed."},{"name":"--lr-date-input-action-active-radius","description":"**`<lr-date-input>`** (default: `var(--lr-date-input-radius)`) — Clear/calendar action corner radius while pressed."},{"name":"--lr-date-input-action-hover-bg","description":"**`<lr-date-input>`** (default: `transparent`) — Clear/calendar action background on hover."},{"name":"--lr-date-input-action-hover-color","description":"**`<lr-date-input>`** (default: `var(--lr-color-text)`) — Clear/calendar action color on hover."},{"name":"--lr-date-input-action-hover-radius","description":"**`<lr-date-input>`** (default: `var(--lr-date-input-radius)`) — Clear/calendar action corner radius on hover."},{"name":"--lr-date-input-border-color","description":"**`<lr-date-input>`** (default: `var(--lr-color-border)`) — Resting border color of the input row, `transparent` by default on the `filled` treatment."},{"name":"--lr-date-input-control-height","description":"**`<lr-date-input>`** — Exact block size of the input row. Undeclared by default, so the row grows to fit its content (floored by `--lr-date-input-control-min-height`). Set it to pin a fixed height; the calendar toggle keeps its own 24x24 touch target even when this pins a shorter row."},{"name":"--lr-date-input-control-min-height","description":"**`<lr-date-input>`** (default: `var(--lr-form-control-height)`) — Minimum block size of the input row, read from the shared form-control height ladder so retuning `--lr-theme-form-control-height-*` moves this control and every sibling field together. The smallest tiers can grow to fit the action buttons' 24px minimum and row borders."},{"name":"--lr-date-input-fill","description":"**`<lr-date-input>`** (default: `var(--lr-color-surface)`) — Resting background of the input row. The `filled`/`filled-outlined` treatments default it to `--lr-color-surface-raised`; a value set here wins over every treatment."},{"name":"--lr-date-input-focus-border-color","description":"**`<lr-date-input>`** (default: `var(--lr-color-brand)`) — Focused row border color."},{"name":"--lr-date-input-font-size","description":"**`<lr-date-input>`** (default: `var(--lr-form-control-font-size)`) — Font size of the text input, scaled by `size`."},{"name":"--lr-date-input-gap","description":"**`<lr-date-input>`** (default: `var(--lr-space-xs)`) — Gap between input-row children."},{"name":"--lr-date-input-padding-block","description":"**`<lr-date-input>`** (default: `var(--lr-form-control-padding-block)`) — Text input block padding, scaled by `size`."},{"name":"--lr-date-input-padding-inline","description":"**`<lr-date-input>`** (default: `var(--lr-form-control-padding-inline)`) — Inline padding of the input row, scaled by `size`."},{"name":"--lr-date-input-placeholder-color","description":"**`<lr-date-input>`** (default: `var(--lr-color-text-quiet)`) — Placeholder text color."},{"name":"--lr-date-input-radius","description":"**`<lr-date-input>`** (default: `var(--lr-radius)`) — Input-row corner radius. `pill` changes its private default to `--lr-radius-pill`; an inherited or direct public value still wins."},{"name":"--lr-date-picker-day-active-bg","description":"**`<lr-date-picker>`** (default: `color-mix(in oklab, var(--lr-date-picker-day-hover-bg, var(--lr-color-brand-quiet)), var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Day pressed background."},{"name":"--lr-date-picker-day-hover-bg","description":"**`<lr-date-picker>`** (default: `var(--lr-color-brand-quiet)`) — Day hover background."},{"name":"--lr-date-picker-day-outside-color","description":"**`<lr-date-picker>`** (default: `var(--lr-color-text-quiet)`) — Adjacent-month day color."},{"name":"--lr-date-picker-disabled-color","description":"**`<lr-date-picker>`** (default: `var(--lr-color-text-quiet)`) — Disabled day text color."},{"name":"--lr-date-picker-disabled-opacity","description":"**`<lr-date-picker>`** (default: `var(--lr-opacity-disabled)`) — Disabled day opacity."},{"name":"--lr-date-picker-header-gap","description":"**`<lr-date-picker>`** (default: `var(--lr-space-s)`) — Month-header child gap."},{"name":"--lr-date-picker-month-gap","description":"**`<lr-date-picker>`** (default: `var(--lr-space-l)`) — Gap between visible months."},{"name":"--lr-date-picker-nav-active-bg","description":"**`<lr-date-picker>`** (default: `color-mix(in oklab, var(--lr-date-picker-nav-hover-bg, var(--lr-color-brand-quiet)), var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Pressed month-navigation background."},{"name":"--lr-date-picker-nav-hover-bg","description":"**`<lr-date-picker>`** (default: `var(--lr-color-brand-quiet)`) — Hover background of the `[part=\"previous\"]`/`[part=\"next\"]` month-navigation buttons."},{"name":"--lr-date-picker-preset-active-bg","description":"**`<lr-date-picker>`** — Pressed background of a quick-range button; defaults to a mix of the hover background with the shared active mix partner."},{"name":"--lr-date-picker-preset-hover-bg","description":"**`<lr-date-picker>`** (default: `var(--lr-color-brand-quiet)`) — Hover background of a quick-range button."},{"name":"--lr-date-picker-preset-selected-bg","description":"**`<lr-date-picker>`** (default: `var(--lr-color-brand)`) — Background of the quick-range button whose range is currently selected."},{"name":"--lr-date-picker-preset-selected-border","description":"**`<lr-date-picker>`** (default: `var(--lr-color-brand)`) — Border color of the selected quick-range button."},{"name":"--lr-date-picker-preset-selected-color","description":"**`<lr-date-picker>`** (default: `var(--lr-color-on-brand)`) — Foreground color of the selected quick-range button."},{"name":"--lr-date-picker-radius","description":"**`<lr-date-picker>`** (default: `var(--lr-radius)`) — Calendar and control corner radius."},{"name":"--lr-date-picker-range-bg","description":"**`<lr-date-picker>`** (default: `var(--lr-color-brand-quiet)`) — Selected-range interior background."},{"name":"--lr-date-picker-range-color","description":"**`<lr-date-picker>`** (default: `var(--lr-color-text)`) — Adjacent-month range text color."},{"name":"--lr-date-picker-range-preview-bg","description":"**`<lr-date-picker>`** (default: `var(--lr-date-picker-range-bg, var(--lr-color-brand-quiet))`) — Pending-range preview background."},{"name":"--lr-date-picker-selected-bg","description":"**`<lr-date-picker>`** (default: `var(--lr-color-brand)`) — Selected day/range-endpoint background."},{"name":"--lr-date-picker-selected-color","description":"**`<lr-date-picker>`** (default: `var(--lr-color-on-brand)`) — Selected day/range-endpoint text color."},{"name":"--lr-date-picker-title-active-bg","description":"**`<lr-date-picker>`** (default: `var(--lr-color-brand-quiet)`) — Pressed title background."},{"name":"--lr-date-picker-title-active-color","description":"**`<lr-date-picker>`** (default: `var(--lr-color-brand)`) — Pressed title color."},{"name":"--lr-date-picker-title-active-radius","description":"**`<lr-date-picker>`** (default: `var(--lr-date-picker-radius)`) — Pressed title corner radius."},{"name":"--lr-date-picker-title-hover-color","description":"**`<lr-date-picker>`** (default: `var(--lr-color-brand)`) — Hovered title color."},{"name":"--lr-date-picker-today-outline","description":"**`<lr-date-picker>`** (default: `var(--lr-color-brand)`) — Today outline color."},{"name":"--lr-date-picker-view-active-bg","description":"**`<lr-date-picker>`** (default: `color-mix(in oklab, var(--lr-date-picker-view-hover-bg, var(--lr-color-brand-quiet)), var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Selection-view item pressed background."},{"name":"--lr-date-picker-view-disabled-opacity","description":"**`<lr-date-picker>`** (default: `var(--lr-opacity-disabled)`) — Disabled selection-view item opacity."},{"name":"--lr-date-picker-view-hover-bg","description":"**`<lr-date-picker>`** (default: `var(--lr-color-brand-quiet)`) — Selection-view item hover background."},{"name":"--lr-date-picker-view-selected-bg","description":"**`<lr-date-picker>`** (default: `var(--lr-color-brand)`) — Selected selection-view item background."},{"name":"--lr-date-picker-view-selected-color","description":"**`<lr-date-picker>`** (default: `var(--lr-color-on-brand)`) — Selected selection-view item text color."},{"name":"--lr-date-picker-view-today-outline","description":"**`<lr-date-picker>`** (default: `var(--lr-color-brand)`) — Current-period selection-view outline."},{"name":"--lr-details-content-padding-block-end","description":"**`<lr-details>`** (default: `var(--lr-details-spacing)`) — Panel content's trailing block padding, independently tunable from the summary's own padding. Same fallback chain as `--lr-details-summary-padding-block`."},{"name":"--lr-details-content-padding-inline","description":"**`<lr-details>`** (default: `var(--lr-details-spacing)`) — Panel content's inline padding, independently tunable from the summary's own padding. Same fallback chain as `--lr-details-summary-padding-block`."},{"name":"--lr-details-filled-bg","description":"**`<lr-details>`** (default: `var(--lr-color-brand-quiet)`) — Filled surface background."},{"name":"--lr-details-filled-border-color","description":"**`<lr-details>`** (default: `transparent`) — Filled border color."},{"name":"--lr-details-filled-outlined-bg","description":"**`<lr-details>`** (default: `var(--lr-color-brand-quiet)`) — Filled-outlined surface background."},{"name":"--lr-details-filled-outlined-border-color","description":"**`<lr-details>`** (default: `var(--lr-color-border)`) — Filled-outlined border color."},{"name":"--lr-details-font-size","description":"**`<lr-details>`** (default: `var(--lr-form-control-font-size)`) — Text size of the summary and the panel. Its private default follows the library's shared size ladder; an inherited or direct public value remains authoritative."},{"name":"--lr-details-gap","description":"**`<lr-details>`** (default: `var(--lr-space-s)`) — Gap between summary content and its icon."},{"name":"--lr-details-outlined-bg","description":"**`<lr-details>`** (default: `var(--lr-color-surface)`) — Outlined surface background."},{"name":"--lr-details-outlined-border-color","description":"**`<lr-details>`** (default: `var(--lr-color-border)`) — Outlined border color."},{"name":"--lr-details-radius","description":"**`<lr-details>`** (default: `var(--lr-radius)`) — Disclosure surface corner radius."},{"name":"--lr-details-spacing","description":"**`<lr-details>`** (default: `var(--lr-form-control-padding-inline)`) — Block rhythm: the summary's block padding and the panel's trailing padding, kept equal so a stack of disclosures reads evenly. Its private default follows the shared ladder's inline-padding knob, whose values suit a stacked panel; the ladder's own block padding exists to fit text inside a fixed control height and would collapse the summary row. An inherited or direct public value remains authoritative."},{"name":"--lr-details-summary-active-bg","description":"**`<lr-details>`** (default: `color-mix(...)`) — Summary pressed background."},{"name":"--lr-details-summary-hover-bg","description":"**`<lr-details>`** (default: `var(--lr-color-brand-quiet)`) — Summary hover background."},{"name":"--lr-details-summary-padding-block","description":"**`<lr-details>`** (default: `var(--lr-details-spacing)`) — Summary block padding (top/bottom), independently tunable from the panel content's own padding. Falls through to `--lr-details-spacing` (and its private ladder default) when unset, so an un-set disclosure renders unchanged, mirroring how `--lr-details-gap`/`--lr-details-radius` are already independent of each other."},{"name":"--lr-details-summary-padding-inline","description":"**`<lr-details>`** (default: `var(--lr-details-spacing)`) — Summary inline padding (start/end), independently tunable from the panel content's own padding. Same fallback chain as `--lr-details-summary-padding-block`."},{"name":"--lr-dialog-backdrop-duration","description":"**`<lr-dialog>`, `<lr-drawer>`** (default: `var(--lr-duration-fast)`) — Duration of the backdrop's fade."},{"name":"--lr-dialog-backdrop-filter","description":"**`<lr-dialog>`, `<lr-drawer>`** (default: `none`) — `backdrop-filter` applied to the scrim, for a frosted-glass treatment over the page behind it."},{"name":"--lr-dialog-height","description":"**`<lr-dialog>`, `<lr-drawer>`** (default: `auto`) — Assertive block size for the panel, mirroring `--lr-dialog-width` on the other axis. Left at `auto` the panel shrink-wraps to its content, unchanged from before this property existed; always capped at `100%` (the viewport) like every other panel dimension. With it set, `body`'s own `flex: 1 1 auto` is what actually gives slotted content a definite, fillable block size -- `header` and `footer` keep their natural size and only `body` grows or shrinks into the remaining space."},{"name":"--lr-dialog-max-width","description":"**`<lr-dialog>`, `<lr-drawer>`** (default: `var(--lr-dialog-width, var(--_lr-dialog-max-width))`) — Cap on the panel's inline size. Falls back to `--lr-dialog-width` when that is set, so an assertive width is not clipped by the tier default; the viewport (`100%`) is always a hard limit on top. The innermost fallback steps with `size` across the shared six-step ladder (`20rem` at `2xs` up to `48rem` at `xl`, `32rem` unchanged at the `m` default) -- an inherited or direct value here still wins outright over every tier."},{"name":"--lr-dialog-overlay-color","description":"**`<lr-dialog>`, `<lr-drawer>`** (default: `var(--lr-color-overlay)`) — Backdrop scrim color."},{"name":"--lr-dialog-panel-duration","description":"**`<lr-dialog>`, `<lr-drawer>`** (default: `var(--lr-duration-base)`) — Duration of the panel's enter/exit animation."},{"name":"--lr-dialog-spacing","description":"**`<lr-dialog>`, `<lr-drawer>`** (default: `var(--lr-space-l)`) — Padding inside the body, and the inline padding of the header and footer rows."},{"name":"--lr-dialog-spacing-block","description":"**`<lr-dialog>`, `<lr-drawer>`** (default: `var(--lr-space-m)`) — Block padding of the header and footer rows, which are tighter than the body by default."},{"name":"--lr-dialog-width","description":"**`<lr-dialog>`, `<lr-drawer>`** (default: `auto`) — Assertive inline size for the panel. Left at `auto` the panel shrink-wraps to its content."},{"name":"--lr-diff-view-add-background","description":"**`<lr-diff-view>`** (default: `var(--lr-color-success-quiet)`) — Added-line background."},{"name":"--lr-diff-view-add-color","description":"**`<lr-diff-view>`** (default: `var(--lr-color-success)`) — Added-line text color."},{"name":"--lr-diff-view-fold-background","description":"**`<lr-diff-view>`** (default: `var(--lr-color-surface-raised)`) — Fold-marker background."},{"name":"--lr-diff-view-fold-color","description":"**`<lr-diff-view>`** (default: `var(--lr-color-text-quiet)`) — Fold-marker text color."},{"name":"--lr-diff-view-font","description":"**`<lr-diff-view>`** (default: `var(--lr-font-mono)`) — Font family used for the diff lines."},{"name":"--lr-diff-view-max-height","description":"**`<lr-diff-view>`** (default: `none`) — Cap on `[part=\"base\"]`'s block size, past which the view scrolls internally. The `maxHeight` property sets this token inline on `[part=\"base\"]`."},{"name":"--lr-diff-view-remove-background","description":"**`<lr-diff-view>`** (default: `var(--lr-color-danger-quiet)`) — Removed-line background."},{"name":"--lr-diff-view-remove-color","description":"**`<lr-diff-view>`** (default: `var(--lr-color-danger)`) — Removed-line text color."},{"name":"--lr-dock-panel-collapse-toggle-hover-bg","description":"**`<lr-dock-panel>`** (default: `var(--lr-color-brand-quiet)`) — Background of `collapse-toggle` on hover; also feeds its pressed background via `color-mix()`."},{"name":"--lr-dock-panel-collapse-toggle-hover-color","description":"**`<lr-dock-panel>`** (default: `var(--lr-color-brand)`) — Text/icon color of `collapse-toggle` on hover, reused verbatim for its pressed color too."},{"name":"--lr-dock-panel-collapsed-size","description":"**`<lr-dock-panel>`** (default: `var(--lr-icon-button-size)`) — The extent the panel keeps along its resize axis while `collapsed` -- enough to still host the toggle button that re-expands it."},{"name":"--lr-dock-panel-handle-active-color","description":"**`<lr-dock-panel>`** (default: `color-mix(in oklab, var(--lr-dock-panel-handle-hover-color, var(--lr-color-brand)), var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Background of `handle` while actively dragged/pressed."},{"name":"--lr-dock-panel-handle-hover-color","description":"**`<lr-dock-panel>`** (default: `var(--lr-color-brand)`) — Background of `handle` on hover and keyboard focus -- scoped separately from `collapse-toggle`'s own hover tokens above even though both default to the same brand token, since the two serve unrelated purposes (drag affordance vs. button feedback)."},{"name":"--lr-document-compare-pane-max-height","description":"**`<lr-document-compare>`** (default: `var(--lr-size-24rem)`) — Maximum block size of a side-by-side pane before it scrolls internally."},{"name":"--lr-document-preview-active-border","description":"**`<lr-document-preview>`** (default: `var(--lr-color-warning, var(--lr-color-brand))`) — Border color of the `[part=\"region-highlight\"]` matching `activeHighlightId` (image format only). Distinct from the resting highlight border."},{"name":"--lr-document-preview-download-link-active-bg","description":"**`<lr-document-preview>`** (default: `color-mix(in oklab, var(--lr-color-brand), var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Pressed background of the generic download link."},{"name":"--lr-document-preview-download-link-hover-bg","description":"**`<lr-document-preview>`** (default: `color-mix(in oklab, var(--lr-color-brand), var(--lr-color-mix-partner) var(--lr-color-mix-hover))`) — Hover background of the generic download link."},{"name":"--lr-document-preview-font","description":"**`<lr-document-preview>`** (default: `var(--lr-font-mono)`) — Font used for plain-text previews."},{"name":"--lr-document-preview-highlight-accent-color","description":"**`<lr-document-preview>`** (default: `var(--lr-color-brand)`) — Accent highlight border and hover tint."},{"name":"--lr-document-preview-highlight-danger-color","description":"**`<lr-document-preview>`** (default: `var(--lr-color-danger)`) — Danger highlight border and hover tint."},{"name":"--lr-document-preview-highlight-neutral-color","description":"**`<lr-document-preview>`** (default: `var(--lr-color-neutral)`) — Neutral highlight border and hover tint."},{"name":"--lr-document-preview-highlight-success-color","description":"**`<lr-document-preview>`** (default: `var(--lr-color-success)`) — Success highlight border and hover tint."},{"name":"--lr-document-preview-highlight-warning-color","description":"**`<lr-document-preview>`** (default: `var(--lr-color-warning)`) — Warning highlight border and hover tint."},{"name":"--lr-document-preview-max-height","description":"**`<lr-document-preview>`** (default: `none`) — Maximum body block size before the preview scrolls internally."},{"name":"--lr-document-preview-progress","description":"**`<lr-document-preview>`** (default: `0`) — Unitless 0-100 completion of the determinate loading ring (multiplied by `1%` in its conic gradient). Written inline by the component from the clamped `progress` value, so it is a read-out rather than a consumer knob."},{"name":"--lr-document-preview-spin-duration","description":"**`<lr-document-preview>`** (default: `var(--lr-transition-ambient)`) — Timing of one indeterminate loading-indicator rotation."},{"name":"--lr-document-viewer-download-link-active-bg","description":"**`<lr-document-viewer>`** (default: `color-mix(in oklab, var(--lr-color-brand), var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Pressed background of the download link."},{"name":"--lr-document-viewer-download-link-hover-bg","description":"**`<lr-document-viewer>`** (default: `color-mix(in oklab, var(--lr-color-brand), var(--lr-color-mix-partner) var(--lr-color-mix-hover))`) — Hover background of the download link."},{"name":"--lr-document-viewer-max-height","description":"**`<lr-document-viewer>`** (default: `70vh`) — Maximum block size of the dialog body before it scrolls internally."},{"name":"--lr-document-viewer-min-height","description":"**`<lr-document-viewer>`** (default: `var(--lr-size-12rem)`) — Minimum block size of the dialog body before it grows to fit content."},{"name":"--lr-document-viewer-width","description":"**`<lr-document-viewer>`** (default: `auto`) — Assertive inline size for the nested dialog panel, forwarded to `<lr-dialog>`'s own `--lr-dialog-width`. Left at `auto` the panel shrink-wraps to content, capped by the dialog's own `--lr-dialog-max-width` tier -- set this instead of reaching through to `--lr-dialog-width` directly, which remains an internal implementation detail of the nested dialog."},{"name":"--lr-docx-viewer-highlight-accent-background","description":"**`<lr-docx-viewer>`** — Accent highlight background."},{"name":"--lr-docx-viewer-highlight-active-background","description":"**`<lr-docx-viewer>`** — Active highlight background."},{"name":"--lr-docx-viewer-highlight-active-outline","description":"**`<lr-docx-viewer>`** — Active fallback-highlight outline."},{"name":"--lr-docx-viewer-highlight-danger-background","description":"**`<lr-docx-viewer>`** — Danger highlight background."},{"name":"--lr-docx-viewer-highlight-neutral-background","description":"**`<lr-docx-viewer>`** — Neutral highlight background."},{"name":"--lr-docx-viewer-highlight-success-background","description":"**`<lr-docx-viewer>`** — Success highlight background."},{"name":"--lr-docx-viewer-highlight-warning-background","description":"**`<lr-docx-viewer>`** — Warning highlight background."},{"name":"--lr-docx-viewer-max-height","description":"**`<lr-docx-viewer>`** (default: `none`) — Maximum block size of the scrollable document body before it scrolls internally. Also settable via the `max-height` property."},{"name":"--lr-docx-viewer-search-match-active-background","description":"**`<lr-docx-viewer>`** — Active search-match background."},{"name":"--lr-docx-viewer-search-match-active-foreground","description":"**`<lr-docx-viewer>`** — Active search-match foreground."},{"name":"--lr-docx-viewer-search-match-background","description":"**`<lr-docx-viewer>`** — Search-match background."},{"name":"--lr-docx-viewer-table-header-background","description":"**`<lr-docx-viewer>`** (default: `var(--lr-color-brand-quiet)`) — Background of a rendered document table's header row (`th`), independent of the highlight backgrounds below."},{"name":"--lr-drawer-enter-x","description":"**`<lr-drawer>`** (default: `calc(-1 * var(--lr-size-1rem))`) — Horizontal offset the panel slides in from, and back out to, for start/end drawers. Its private default changes per placement (and flips under RTL); an inherited or direct public value remains authoritative."},{"name":"--lr-drawer-enter-y","description":"**`<lr-drawer>`** (default: `calc(-1 * var(--lr-size-1rem))`) — Vertical offset the panel slides in from, and back out to, for top/bottom drawers. Its private default becomes `var(--lr-size-1rem)` for `bottom`; an inherited or direct public value remains authoritative."},{"name":"--lr-drawer-height","description":"**`<lr-drawer>`** — Block size for top/bottom drawers."},{"name":"--lr-drawer-width","description":"**`<lr-drawer>`** — Inline size for start/end drawers."},{"name":"--lr-drop-zone-accept-bg","description":"**`<lr-drop-zone>`** (default: `color-mix(in srgb, var(--lr-color-success) 12%, transparent)`) — Background of `[part=\"overlay\"][data-drag-state=\"accept\"]`."},{"name":"--lr-drop-zone-accept-border-color","description":"**`<lr-drop-zone>`** (default: `var(--lr-color-success)`) — Border color of `[part=\"overlay\"][data-drag-state=\"accept\"]`."},{"name":"--lr-drop-zone-overlay-bg","description":"**`<lr-drop-zone>`** (default: `color-mix(in srgb, var(--lr-color-brand) 8%, transparent)`) — Fill of `[part=\"overlay\"]` in that same neutral drag state."},{"name":"--lr-drop-zone-overlay-border-color","description":"**`<lr-drop-zone>`** (default: `var(--lr-color-brand)`) — Dashed border color of `[part=\"overlay\"]` in its neutral drag state, before an accept or reject verdict."},{"name":"--lr-drop-zone-overlay-font-size","description":"**`<lr-drop-zone>`** (default: `var(--lr-font-size-md-sm)`) — Overlay instructional text size."},{"name":"--lr-drop-zone-overlay-gap","description":"**`<lr-drop-zone>`** (default: `var(--lr-space-xs)`) — Gap between the overlay icon and text."},{"name":"--lr-drop-zone-overlay-icon-size","description":"**`<lr-drop-zone>`** (default: `var(--lr-font-size-xl)`) — `[part=\"overlay-icon\"]` glyph size."},{"name":"--lr-drop-zone-radius","description":"**`<lr-drop-zone>`** (default: `var(--lr-radius)`) — Corner radius of `[part=\"overlay\"]`."},{"name":"--lr-drop-zone-reject-bg","description":"**`<lr-drop-zone>`** (default: `color-mix(in srgb, var(--lr-color-danger) 12%, transparent)`) — Background of `[part=\"overlay\"][data-drag-state=\"reject\"]`."},{"name":"--lr-drop-zone-reject-border-color","description":"**`<lr-drop-zone>`** (default: `var(--lr-color-danger)`) — Border color of `[part=\"overlay\"][data-drag-state=\"reject\"]`."},{"name":"--lr-duration-ambient","description":"**Shared design token** — Canonical shared component token for duration ambient. Reads `--lr-theme-duration-slow`."},{"name":"--lr-duration-base","description":"**Shared design token** — Canonical shared component token for duration base. Reads `--lr-theme-duration-normal`."},{"name":"--lr-duration-fast","description":"**Shared design token** — Canonical shared component token for duration fast. Reads `--lr-theme-duration-fast`."},{"name":"--lr-duration-icon","description":"**Shared design token** — Canonical shared component token for duration icon. Reads `--lr-theme-duration-icon`."},{"name":"--lr-easing-emphasized","description":"**Shared design token** — Canonical shared component token for easing emphasized. Reads `--lr-theme-easing-emphasized`."},{"name":"--lr-easing-linear","description":"**Shared design token** — Canonical shared component token for easing linear. Reads `--lr-theme-easing-linear`."},{"name":"--lr-easing-standard","description":"**Shared design token** — Canonical shared component token for easing standard. Reads `--lr-theme-easing-standard`."},{"name":"--lr-ebook-viewer-max-height","description":"**`<lr-ebook-viewer>`** (default: `none`) — Maximum block size of the mount area epub.js renders into, before it scrolls internally. Also settable via the `max-height` property."},{"name":"--lr-email-viewer-max-height","description":"**`<lr-email-viewer>`** (default: `none`) — Maximum block size of `[part=\"body\"]` before it scrolls internally. The `maxHeight` property sets this token inline on `[part=\"base\"]`."},{"name":"--lr-embedding-explorer-height","description":"**`<lr-embedding-explorer>`** (default: `360px`) — The plot's `block-size`. Set on the host from the `height` property, whose default supplies the `360px`; a value the browser cannot parse as a `block-size` is dropped, leaving the `viewBox`-derived aspect-ratio size. A consumer's own `::part(plot) { block-size: ... }` rule still overrides it, and the narrow-allocation `min-block-size` floor still raises it."},{"name":"--lr-embedding-explorer-selected-stroke","description":"**`<lr-embedding-explorer>`** (default: `var(--lr-color-brand)`) — Stroke color of the selected point."},{"name":"--lr-emoji-picker-active-bg","description":"**`<lr-emoji-picker>`** (default: `var(--lr-color-brand-quiet)`) — Compatibility fallback background for hover and roving-active states."},{"name":"--lr-emoji-picker-control-gap","description":"**`<lr-emoji-picker>`** (default: `var(--lr-space-xs)`) — Gap between field sections."},{"name":"--lr-emoji-picker-gap","description":"**`<lr-emoji-picker>`** (default: `var(--lr-space-2xs)`) — Gap between emoji within a windowed row."},{"name":"--lr-emoji-picker-glyph-size","description":"**`<lr-emoji-picker>`** (default: `var(--lr-font-size-lg)`) — Font size of the emoji glyph, scaled by the `size` property to keep the glyph proportional to the item box."},{"name":"--lr-emoji-picker-hover-bg","description":"**`<lr-emoji-picker>`** (default: `var(--lr-emoji-picker-active-bg,var(--lr-color-brand-quiet))`) — Pointer-hover background. The legacy `--lr-emoji-picker-active-bg` remains its fallback."},{"name":"--lr-emoji-picker-item-radius","description":"**`<lr-emoji-picker>`** (default: `var(--lr-radius-xs)`) — Search and emoji corner radius."},{"name":"--lr-emoji-picker-item-size","description":"**`<lr-emoji-picker>`** (default: `var(--lr-icon-button-size)`) — Each emoji button's box. Floored at the shared `--lr-icon-button-size`; small size tiers scale the glyph without shrinking the interactive target."},{"name":"--lr-emoji-picker-keyboard-active-bg","description":"**`<lr-emoji-picker>`** (default: `var(--lr-emoji-picker-active-bg,var(--lr-color-brand-quiet))`) — Roving keyboard/pointer-active background."},{"name":"--lr-emoji-picker-keyboard-active-outline-color","description":"**`<lr-emoji-picker>`** (default: `var(--lr-color-brand)`) — Outline color for the roving keyboard-active emoji."},{"name":"--lr-emoji-picker-pressed-bg","description":"**`<lr-emoji-picker>`** (default: `color-mix(...)`) — Pointer-pressed background."},{"name":"--lr-emoji-picker-pressed-outline-color","description":"**`<lr-emoji-picker>`** (default: `var(--lr-color-brand)`) — Outline color while an emoji button is being pointer-pressed."},{"name":"--lr-emoji-picker-radius","description":"**`<lr-emoji-picker>`** (default: `var(--lr-radius)`) — Outer picker corner radius."},{"name":"--lr-emoji-picker-row-height","description":"**`<lr-emoji-picker>`** (default: `calc(var(--lr-emoji-picker-item-size) + var(--lr-space-l))`) — One windowed row's height. Must stay at or above the item size plus the group-label band, or consecutive absolutely-positioned rows overlap."},{"name":"--lr-emoji-picker-search-border-color","description":"**`<lr-emoji-picker>`** (default: `var(--lr-color-border)`) — Resting search border color, independent of the hover color below."},{"name":"--lr-emoji-picker-search-clear-gap","description":"**`<lr-emoji-picker>`** (default: `var(--lr-space-xs)`) — Gap between the search field and the clear button inside `search-wrapper`."},{"name":"--lr-emoji-picker-search-fill","description":"**`<lr-emoji-picker>`** (default: `var(--lr-color-surface)`) — Resting search background."},{"name":"--lr-emoji-picker-search-font-size","description":"**`<lr-emoji-picker>`** (default: `inherit`) — Text size of the filter field."},{"name":"--lr-emoji-picker-search-hover-border-color","description":"**`<lr-emoji-picker>`** (default: `var(--lr-color-brand)`) — Search hover border."},{"name":"--lr-emoji-picker-search-min-height","description":"**`<lr-emoji-picker>`** (default: `auto`) — Minimum row height of the filter field, for matching it to a themed search field of a chosen density tier. Point it at `--lr-form-control-height-s` (or any tier of that ladder) to line the picker's own field up with the rest of an application's controls. `size` does not drive it: on this component `size` scales the emoji glyph and item box, not the form-control ladder."},{"name":"--lr-emoji-picker-search-padding-block","description":"**`<lr-emoji-picker>`** (default: `var(--lr-space-xs)`) — Block gutter of the filter field."},{"name":"--lr-emoji-picker-search-padding-inline","description":"**`<lr-emoji-picker>`** (default: `var(--lr-space-s)`) — Inline gutter of the filter field."},{"name":"--lr-emoji-picker-selected-bg","description":"**`<lr-emoji-picker>`** (default: `var(--lr-color-brand-quiet)`) — Committed-value background."},{"name":"--lr-emoji-picker-selected-color","description":"**`<lr-emoji-picker>`** (default: `var(--lr-color-text)`) — Committed-value foreground."},{"name":"--lr-emoji-picker-selected-outline-color","description":"**`<lr-emoji-picker>`** (default: `var(--lr-color-brand)`) — Outline color for the committed selection."},{"name":"--lr-empty-compact-align","description":"**`<lr-empty>`** — Cross-axis and text alignment used in compact mode; set to `center` for dense but centered empty states."},{"name":"--lr-empty-compact-font-size","description":"**`<lr-empty>`** — Heading font size used in compact mode. Unset by default (no fallback), so the heading keeps its ordinary inherited font size until a consumer opts in."},{"name":"--lr-empty-compact-gap","description":"**`<lr-empty>`** (default: `var(--lr-space-2xs)`) — Gap between the icon, title, and description in compact mode."},{"name":"--lr-empty-compact-padding","description":"**`<lr-empty>`** (default: `var(--lr-space-xs)`) — Padding used in compact mode; accepts any padding shorthand (e.g. `8px 2px`)."},{"name":"--lr-entity-card-bg","description":"**`<lr-entity-card>`** (default: `var(--lr-color-surface)`) — Resting background of `[part=\"base\"]`. `frame=\"plain\"` still paints transparent."},{"name":"--lr-entity-card-compact-gap","description":"**`<lr-entity-card>`** (default: `var(--lr-space-xs)`) — Gap between `[part=\"base\"]`'s rows while `compact`."},{"name":"--lr-entity-card-compact-padding","description":"**`<lr-entity-card>`** (default: `var(--lr-space-s)`) — `[part=\"base\"]` padding while `compact`."},{"name":"--lr-entity-chip-bg","description":"**`<lr-entity-chip>`** (default: `var(--lr-color-brand-quiet)`) — Background color."},{"name":"--lr-entity-chip-border","description":"**`<lr-entity-chip>`** (default: `transparent`) — Border color of the chip."},{"name":"--lr-entity-chip-color","description":"**`<lr-entity-chip>`** (default: `var(--lr-color-brand)`) — Text/accent color. Reflected `type` lets a host theme per type from CSS, e.g. `lr-entity-chip[type='person'] { --lr-entity-chip-color: ... }`."},{"name":"--lr-env-list-reveal-active-bg","description":"**`<lr-env-list>`** (default: `var(--lr-color-brand-quiet)`) — Background of a pressed (revealed) reveal toggle."},{"name":"--lr-env-list-reveal-active-border","description":"**`<lr-env-list>`** (default: `var(--lr-color-brand)`) — Border color of a pressed (revealed) reveal toggle. Restyling the pressed state otherwise requires overriding the library-wide brand tokens, since `::part(reveal-button)[aria-pressed]` is invalid CSS."},{"name":"--lr-eval-dataset-search-font-size","description":"**`<lr-eval-dataset>`** (default: `inherit`) — Text size of the search field."},{"name":"--lr-eval-dataset-search-min-height","description":"**`<lr-eval-dataset>`** (default: `auto`) — Minimum row height of the search field, for matching it to a themed search field of a chosen density tier. Point it at `--lr-form-control-height-s` (or any tier of that ladder) to line this field up with the rest of an application's controls."},{"name":"--lr-eval-dataset-search-padding-block","description":"**`<lr-eval-dataset>`** (default: `var(--lr-space-xs)`) — Block gutter of the search field."},{"name":"--lr-eval-dataset-search-padding-inline","description":"**`<lr-eval-dataset>`** (default: `var(--lr-space-s)`) — Leading gutter of the search field. The trailing gutter is reserved for the overlaid clear button."},{"name":"--lr-eval-dataset-search-radius","description":"**`<lr-eval-dataset>`** (default: `var(--lr-radius)`) — Corner radius of the search field."},{"name":"--lr-export-button-active-background","description":"**`<lr-export-button>`** — Trigger fill while pressed."},{"name":"--lr-export-button-active-border","description":"**`<lr-export-button>`** — Trigger edge colour while pressed."},{"name":"--lr-export-button-active-color","description":"**`<lr-export-button>`** — Trigger label and icon colour while pressed."},{"name":"--lr-export-button-background","description":"**`<lr-export-button>`** — Trigger fill at rest. Overrides whatever the current `appearance` resolves to, leaving every other paint untouched."},{"name":"--lr-export-button-border","description":"**`<lr-export-button>`** — Trigger edge colour at rest."},{"name":"--lr-export-button-color","description":"**`<lr-export-button>`** — Trigger label and icon colour at rest. The escape hatch for `appearance=\"outlined\"`, which paints the label `--lr-color-brand` and has no `variant` of its own to return it to neutral text."},{"name":"--lr-export-button-hover-background","description":"**`<lr-export-button>`** — Trigger fill on hover."},{"name":"--lr-export-button-hover-border","description":"**`<lr-export-button>`** — Trigger edge colour on hover."},{"name":"--lr-export-button-hover-color","description":"**`<lr-export-button>`** — Trigger label and icon colour on hover."},{"name":"--lr-file-icon-bg","description":"**`<lr-file-icon>`** (default: `var(--lr-color-brand-quiet)`) — Background of the `icon` part. Every file category renders the same fill; retint it without hijacking `--lr-color-brand-quiet` library-wide."},{"name":"--lr-file-icon-color","description":"**`<lr-file-icon>`** (default: `var(--lr-color-brand)`) — Text/glyph color of the `icon` part."},{"name":"--lr-file-icon-size","description":"**`<lr-file-icon>`** (default: `var(--lr-size-2rem)`) — Inline/block size of the format badge."},{"name":"--lr-file-input-accept-bg","description":"**`<lr-file-input>`** (default: `color-mix(in srgb, var(--lr-color-success) 8%, transparent)`) — Background of `[part~=\"base\"][data-drag-state=\"accept\"]`."},{"name":"--lr-file-input-accept-border-color","description":"**`<lr-file-input>`** (default: `var(--lr-color-success)`) — Border color of `[part~=\"base\"][data-drag-state=\"accept\"]`."},{"name":"--lr-file-input-compact-font-size","description":"**`<lr-file-input>`** (default: `var(--lr-font-size-sm)`) — Label font size while `compact`."},{"name":"--lr-file-input-compact-gap","description":"**`<lr-file-input>`** (default: `var(--lr-space-2xs)`) — Gap between the dropzone's slotted children while `compact`."},{"name":"--lr-file-input-compact-padding","description":"**`<lr-file-input>`** (default: `var(--lr-space-s)`) — `[part~=\"base\"]` padding while `compact`."},{"name":"--lr-file-input-detail-font-size","description":"**`<lr-file-input>`** (default: `var(--lr-font-size-sm)`) — Size of the secondary text: the hint, the validation error, and each selected file's formatted size. Retuned per `size` tier."},{"name":"--lr-file-input-dropzone-border-color","description":"**`<lr-file-input>`** (default: `var(--lr-color-border)`) — Resting dropzone border color. The dashed border style is unchanged."},{"name":"--lr-file-input-dropzone-fill","description":"**`<lr-file-input>`** (default: `var(--lr-color-surface)`) — Resting dropzone background, the state it spends most of its life in. The drag accept/reject tints have had their own hooks since 12.0.0; this one completes the set."},{"name":"--lr-file-input-dropzone-font-size","description":"**`<lr-file-input>`** (default: `var(--lr-font-size-md-sm)`) — Instructional text size inside the dropzone. Retuned per `size` tier; the documented default is the `m`/`medium` tier."},{"name":"--lr-file-input-dropzone-hover-border-color","description":"**`<lr-file-input>`** (default: `var(--lr-color-brand)`) — Dropzone border color while the pointer is over it, whether over the button or over the content stacked on it."},{"name":"--lr-file-input-dropzone-icon-size","description":"**`<lr-file-input>`** (default: `var(--lr-font-size-xl)`) — `[part=\"dropzone-icon\"]` glyph size. Retuned per `size` tier."},{"name":"--lr-file-input-dropzone-padding","description":"**`<lr-file-input>`** (default: `var(--lr-space-l)`) — Padding inside `[part~=\"base\"]` and the stacked dropzone content. Retuned per `size` tier; `compact` overrides it."},{"name":"--lr-file-input-font-size","description":"**`<lr-file-input>`** (default: `var(--lr-form-control-font-size)`) — Label and selected-filename text size; tracks the shared `size` ladder."},{"name":"--lr-file-input-gap","description":"**`<lr-file-input>`** (default: `var(--lr-space-xs)`) — Gap between the dropzone's slotted children. While `compact`, this is the fallback when `--lr-file-input-compact-gap` is unset."},{"name":"--lr-file-input-radius","description":"**`<lr-file-input>`** (default: `var(--lr-radius)`) — Corner radius of `[part~=\"base\"]`."},{"name":"--lr-file-input-reject-bg","description":"**`<lr-file-input>`** (default: `color-mix(in srgb, var(--lr-color-danger) 8%, transparent)`) — Background of `[part~=\"base\"][data-drag-state=\"reject\"]`."},{"name":"--lr-file-input-reject-border-color","description":"**`<lr-file-input>`** (default: `var(--lr-color-danger)`) — Border color of `[part~=\"base\"][data-drag-state=\"reject\"]`."},{"name":"--lr-filter-bar-field-basis","description":"**`<lr-filter-bar>`** (default: `var(--lr-size-12rem)`) — Flex-basis of each filter's `field` wrapper, controlling how many fields fit per row before the row wraps."},{"name":"--lr-filter-bar-gap","description":"**`<lr-filter-bar>`** (default: `var(--lr-space-s)`) — Gap between filter fields, the `end` slot, the reset button, and the loading status in the `controls` row."},{"name":"--lr-flag-aspect-ratio","description":"**`<lr-flag>`** (default: `4 / 3`) — Rectangular flag aspect ratio."},{"name":"--lr-flag-object-fit","description":"**`<lr-flag>`** (default: `cover`) — How the image fits its flag frame."},{"name":"--lr-flag-radius","description":"**`<lr-flag>`** — Rectangular flag corner radius."},{"name":"--lr-flow-canvas-connection-line-color","description":"**`<lr-flow-canvas>`** (default: `var(--lr-color-brand)`) — Stroke color of `[part=\"connection-line\"]`, the in-progress connect-gesture path drawn while dragging a new connection, independent of a finished edge's own `--lr-flow-canvas-edge-*-color`."},{"name":"--lr-flow-canvas-drop-active-outline-color","description":"**`<lr-flow-canvas>`** (default: `var(--lr-color-brand)`) — Outline color of the viewport while a palette item is dragged over it (`droppable`)."},{"name":"--lr-flow-canvas-edge-brand-color","description":"**`<lr-flow-canvas>`** (default: `var(--lr-color-brand)`) — Brand edge and arrowhead color."},{"name":"--lr-flow-canvas-edge-danger-color","description":"**`<lr-flow-canvas>`** (default: `var(--lr-color-danger)`) — Danger edge and arrowhead color."},{"name":"--lr-flow-canvas-edge-neutral-color","description":"**`<lr-flow-canvas>`** (default: `var(--lr-color-border)`) — Neutral edge and arrowhead color."},{"name":"--lr-flow-canvas-edge-success-color","description":"**`<lr-flow-canvas>`** (default: `var(--lr-color-success)`) — Success edge and arrowhead color."},{"name":"--lr-flow-canvas-edge-warning-color","description":"**`<lr-flow-canvas>`** (default: `var(--lr-color-warning)`) — Warning edge and arrowhead color."},{"name":"--lr-flow-canvas-grid-size","description":"**`<lr-flow-canvas>`** (default: `var(--lr-size-0-5rem)`) — Dotted background spacing. The `grid` property supplies the fallback when this hook is unset; an element or ancestor hook takes precedence."},{"name":"--lr-flow-canvas-march-duration","description":"**`<lr-flow-canvas>`** (default: `var(--lr-duration-ambient)`) — Running-edge march animation duration."},{"name":"--lr-flow-canvas-node-connect-invalid-outline-color","description":"**`<lr-flow-canvas>`** (default: `var(--lr-color-danger)`) — Outline color of a node that is an invalid connect-gesture drop target. Same `::part()` attribute-selector restriction as `--lr-flow-canvas-node-selected-outline-color` above."},{"name":"--lr-flow-canvas-node-connect-target-outline-color","description":"**`<lr-flow-canvas>`** (default: `var(--lr-color-brand)`) — Outline color of a node that is a valid connect-gesture drop target."},{"name":"--lr-flow-canvas-node-disabled-opacity","description":"**`<lr-flow-canvas>`** (default: `var(--lr-opacity-disabled)`) — Opacity of a node whose `FlowNode` entry sets `disabled`."},{"name":"--lr-flow-canvas-node-hover-outline-color","description":"**`<lr-flow-canvas>`** (default: `var(--lr-color-border-strong)`) — Outline color of a node's mouse-hover preview of its own `:focus-visible` ring. Unlike the four state-scoped colors above this one is `:hover`-gated rather than attribute-gated, so a `::part(node):hover` override would lose to this rule's own higher internal specificity rather than to the `::part()[attr]` restriction those four work around. Set to `transparent` to opt out."},{"name":"--lr-flow-canvas-node-selected-outline-color","description":"**`<lr-flow-canvas>`** (default: `var(--lr-color-brand)`) — Outline color of a selected node."},{"name":"--lr-flow-controls-lock-active-color","description":"**`<lr-flow-controls>`** (default: `var(--lr-color-brand)`) — Pressed lock-button foreground."},{"name":"--lr-flow-minimap-block-size","description":"**`<lr-flow-minimap>`** (default: `var(--lr-size-8rem)`) — Map block size."},{"name":"--lr-flow-minimap-inline-size","description":"**`<lr-flow-minimap>`** (default: `var(--lr-size-12rem)`) — Map inline size."},{"name":"--lr-flow-minimap-viewport-color","description":"**`<lr-flow-minimap>`** (default: `var(--lr-color-brand)`) — Fill (mixed 15% into transparent) and stroke of `[part=\"viewport\"]`, the rectangle showing the canvas's visible area, independent of the per-status node fills above."},{"name":"--lr-flow-minimap-viewport-min-size","description":"**`<lr-flow-minimap>`** (default: `var(--lr-icon-button-size)`) — Smallest rendered size, in physical pixels, of the transparent `viewport-hit-area` along either axis. On a canvas whose node bounds dwarf the visible viewport the raw rectangle collapses to a few pixels, which leaves the only pointer-drag handle for panning effectively unclickable; the floor grows it symmetrically about its own centre so it still points at what the viewport shows. The visible `viewport` stays exact. Defaults to Lyra's 40px interaction floor; set `0` to opt out."},{"name":"--lr-flow-node-compact-gap","description":"**`<lr-flow-node>`** (default: `var(--lr-space-2xs)`) — Gap between `[part=\"card\"]`'s rows while `compact`."},{"name":"--lr-flow-node-compact-padding","description":"**`<lr-flow-node>`** (default: `var(--lr-space-xs)`) — `[part=\"card\"]` padding while `compact`."},{"name":"--lr-flow-node-min-inline-size","description":"**`<lr-flow-node>`** (default: `calc(var(--lr-size-10rem) + var(--lr-size-1rem))`) — Minimum card inline size."},{"name":"--lr-flow-node-progress-fill-color","description":"**`<lr-flow-node>`** (default: `var(--lr-color-brand)`) — Determinate progress fill color, independent from the track and other brand-colored states."},{"name":"--lr-flow-node-progress-track-color","description":"**`<lr-flow-node>`** (default: `var(--lr-color-border)`) — Determinate progress track color."},{"name":"--lr-flow-node-running-border","description":"**`<lr-flow-node>`** (default: `var(--lr-color-brand)`) — Border color of the card while `status=\"running\"`. Independent from `--lr-flow-node-selected-outline-color` so a consumer can retint just one of the two states without the other following along."},{"name":"--lr-flow-node-running-glow","description":"**`<lr-flow-node>`** (default: `var(--lr-color-brand-quiet)`) — Box-shadow color of the running-state ring around the card, and the pulse keyframes' peak color."},{"name":"--lr-flow-node-selected-outline-color","description":"**`<lr-flow-node>`** (default: `var(--lr-color-brand)`) — Outline color of the card while `selected`. The outline stays independent from execution-state border and glow."},{"name":"--lr-flow-status-color","description":"**`<lr-flow-minimap>`** (default: `var(--lr-color-border-strong)`) — Fill of nodes without an execution status.\n\n**`<lr-flow-node>`** (default: `var(--lr-color-border-strong)`) — Status-dot color when no execution status is set.\n\n**`<lr-flow-run-status>`** (default: `var(--lr-color-border-strong)`) — Count-dot color when no execution status is set."},{"name":"--lr-flow-status-denied-color","description":"**`<lr-flow-minimap>`** (default: `var(--lr-color-warning)`) — Denied-node fill.\n\n**`<lr-flow-node>`** (default: `var(--lr-color-warning)`) — Denied status-dot color.\n\n**`<lr-flow-run-status>`** (default: `var(--lr-color-warning)`) — Denied count-dot color."},{"name":"--lr-flow-status-error-color","description":"**`<lr-flow-minimap>`** (default: `var(--lr-color-danger)`) — Failed-node fill.\n\n**`<lr-flow-node>`** (default: `var(--lr-color-danger)`) — Error status-dot color.\n\n**`<lr-flow-run-status>`** (default: `var(--lr-color-danger)`) — Error count-dot color."},{"name":"--lr-flow-status-pending-color","description":"**`<lr-flow-minimap>`** (default: `var(--lr-color-border-strong)`) — Pending-node fill.\n\n**`<lr-flow-node>`** (default: `var(--lr-color-border-strong)`) — Pending status-dot color.\n\n**`<lr-flow-run-status>`** (default: `var(--lr-color-border-strong)`) — Pending count-dot color."},{"name":"--lr-flow-status-running-color","description":"**`<lr-flow-minimap>`** (default: `var(--lr-color-brand)`) — Running-node fill.\n\n**`<lr-flow-node>`** (default: `var(--lr-color-brand)`) — Running status-dot color.\n\n**`<lr-flow-run-status>`** (default: `var(--lr-color-brand)`) — Running count-dot color."},{"name":"--lr-flow-status-success-color","description":"**`<lr-flow-minimap>`** (default: `var(--lr-color-success)`) — Successful-node fill.\n\n**`<lr-flow-node>`** (default: `var(--lr-color-success)`) — Success status-dot color.\n\n**`<lr-flow-run-status>`** (default: `var(--lr-color-success)`) — Success count-dot color."},{"name":"--lr-focus-ring","description":"**Shared design token** — Composite focus-ring outline shorthand, derived from the width and color parts. Mirrors the ready-made outline value Web Awesome exposes as --wa-focus-ring so a migrating consumer has a one-to-one target instead of hand-expanding every site. Offset stays separate because outline-offset is its own property."},{"name":"--lr-focus-ring-color","description":"**Shared design token** — Canonical shared component token for focus ring color. Reads `--lr-theme-color-focus`."},{"name":"--lr-focus-ring-offset","description":"**Shared design token** — Canonical shared component token for focus ring offset. Reads `--lr-theme-focus-ring-offset`."},{"name":"--lr-focus-ring-width","description":"**Shared design token** — Canonical shared component token for focus ring width. Reads `--lr-theme-focus-ring-width`."},{"name":"--lr-font","description":"**Shared design token** — Canonical shared component token for font. Reads `--lr-theme-font-family-body`."},{"name":"--lr-font-mono","description":"**Shared design token** — Canonical shared component token for font mono. Reads `--lr-theme-font-family-mono`."},{"name":"--lr-font-size-2xl","description":"**Shared design token** — Canonical shared component token for font size 2xl. Reads `--lr-theme-font-size-2xl`."},{"name":"--lr-font-size-2xs","description":"**Shared design token** — Canonical shared component token for font size 2xs. Reads `--lr-theme-font-size-2xs`."},{"name":"--lr-font-size-3xl","description":"**Shared design token** — Canonical shared component token for font size 3xl. Reads `--lr-theme-font-size-3xl`."},{"name":"--lr-font-size-3xs","description":"**Shared design token** — Canonical shared component token for font size 3xs. Reads `--lr-theme-font-size-3xs`."},{"name":"--lr-font-size-lg","description":"**Shared design token** — Canonical shared component token for font size lg. Reads `--lr-theme-font-size-lg`."},{"name":"--lr-font-size-m","description":"**Shared design token** — Canonical shared component token for font size m. Reads `--lr-theme-font-size-m`."},{"name":"--lr-font-size-md-sm","description":"**Shared design token** — Canonical shared component token for font size md sm. Reads `--lr-theme-font-size-md-sm`."},{"name":"--lr-font-size-sm","description":"**Shared design token** — Canonical shared component token for font size sm. Reads `--lr-theme-font-size-sm`."},{"name":"--lr-font-size-xl","description":"**Shared design token** — Canonical shared component token for font size xl. Reads `--lr-theme-font-size-xl`."},{"name":"--lr-font-size-xs","description":"**Shared design token** — Canonical shared component token for font size xs. Reads `--lr-theme-font-size-xs`."},{"name":"--lr-font-weight-bold","description":"**Shared design token** — Canonical shared component token for font weight bold. Reads `--lr-theme-font-weight-bold`."},{"name":"--lr-font-weight-medium","description":"**Shared design token** — Canonical shared component token for font weight medium. Reads `--lr-theme-font-weight-medium`."},{"name":"--lr-font-weight-normal","description":"**Shared design token** — Canonical shared component token for font weight normal. Reads `--lr-theme-font-weight-normal`."},{"name":"--lr-font-weight-semibold","description":"**Shared design token** — Canonical shared component token for font weight semibold. Reads `--lr-theme-font-weight-semibold`."},{"name":"--lr-form-control-focus-shadow","description":"**`<lr-combobox>`, `<lr-date-input>`, `<lr-file-input>`, `<lr-input>`, `<lr-locale-picker>`, `<lr-native-time-input>`, `<lr-number-input>`, `<lr-phone-input>`, `<lr-select>`, `<lr-textarea>`, `<lr-time-input>`, `<lr-token-input>`** (default: `none`) — The shared field focus halo, painted as a `box-shadow` while this control is focused. One name for every field-shaped control in the library, so a halo is configured once rather than per component. Additive: the focus outline and border cue are the accessibility answer to focus and are never replaced by it."},{"name":"--lr-form-control-height-2xs","description":"**Shared design token** — Canonical shared component token for form control height 2xs. Reads `--lr-theme-form-control-height-2xs`."},{"name":"--lr-form-control-height-l","description":"**Shared design token** — Canonical shared component token for form control height l. Reads `--lr-theme-form-control-height-l`."},{"name":"--lr-form-control-height-m","description":"**Shared design token** — Canonical shared component token for form control height m. Reads `--lr-theme-form-control-height-m`."},{"name":"--lr-form-control-height-s","description":"**Shared design token** — Canonical shared component token for form control height s. Reads `--lr-theme-form-control-height-s`."},{"name":"--lr-form-control-height-xl","description":"**Shared design token** — Canonical shared component token for form control height xl. Reads `--lr-theme-form-control-height-xl`."},{"name":"--lr-form-control-height-xs","description":"**Shared design token** — Canonical shared component token for form control height xs. Reads `--lr-theme-form-control-height-xs`."},{"name":"--lr-form-control-radius","description":"**Shared design token** — Canonical shared component token for form control radius; falls back to the shared corner radius when no per-control-family override is set. Reads `--lr-theme-form-control-radius`."},{"name":"--lr-form-control-required-color","description":"**`<lr-checkbox-group>`, `<lr-combobox>`, `<lr-emoji-picker>`, `<lr-file-input>`, `<lr-model-select>`, `<lr-radio-group>`, `<lr-select>`, `<lr-slider>`, `<lr-token-input>`, `<lr-voice-picker>`** (default: `var(--lr-color-danger)`) — Required-marker color, themeable independently of error text and invalid borders.\n\n**`<lr-code-editor>`, `<lr-color-picker>`, `<lr-date-input>`, `<lr-input>`, `<lr-known-date>`, `<lr-locale-picker>`, `<lr-native-time-input>`, `<lr-number-input>`, `<lr-otp-input>`, `<lr-phone-input>`, `<lr-textarea>`, `<lr-time-input>`, `<lr-tool-param-form>`** (default: `var(--lr-color-danger)`) — Color of that marker, retunable without touching any other danger-coloured surface.\n\n**`<lr-rubric-form>`** (default: `var(--lr-color-danger)`) — Color of that marker, independently retunable from field errors."},{"name":"--lr-form-control-required-content","description":"**`<lr-checkbox-group>`, `<lr-combobox>`, `<lr-emoji-picker>`, `<lr-file-input>`, `<lr-model-select>`, `<lr-radio-group>`, `<lr-select>`, `<lr-slider>`, `<lr-token-input>`, `<lr-voice-picker>`** (default: `' *'`) — The required marker appended to `form-control-label` while `required` is set. Set it to `''` to suppress the marker, or to any other quoted string (`' (required)'`, a localized word) to replace it.\n\n**`<lr-code-editor>`, `<lr-color-picker>`, `<lr-date-input>`, `<lr-input>`, `<lr-locale-picker>`, `<lr-native-time-input>`, `<lr-number-input>`, `<lr-otp-input>`, `<lr-phone-input>`, `<lr-textarea>`, `<lr-time-input>`** (default: `' *'`) — The required-field marker rendered after the label. Set it to `''` to suppress the marker, or to any other quoted string (`' (required)'`, a localized word) to replace it. Caller-supplied content, so it is never localized here.\n\n**`<lr-known-date>`** (default: `' *'`) — The required-field marker, rendered after the `legend` box. Set it to `''` to suppress the marker, or to any other quoted string (`' (required)'`, a localized word) to replace it. Caller-supplied content, so it is never localized here.\n\n**`<lr-rubric-form>`** (default: `' *'`) — Required-field marker after rubric-owned score and unsupported-field labels. Set it to `''` to suppress the marker, or to any other quoted string (`' (required)'`, a localized word) to replace it.\n\n**`<lr-tool-param-form>`** (default: `' *'`) — The required-field marker rendered after the `label` part of every field whose key is listed in the schema's `required` array — per field here, not per host, because this control's value is a whole object. Set it to `''` to suppress the marker, or to any other quoted string (`' (required)'`, a localized word) to replace it. Caller-supplied content, so it is never localized here."},{"name":"--lr-form-control-required-offset","description":"**`<lr-checkbox-group>`, `<lr-combobox>`, `<lr-emoji-picker>`, `<lr-file-input>`, `<lr-model-select>`, `<lr-radio-group>`, `<lr-select>`, `<lr-slider>`, `<lr-token-input>`, `<lr-voice-picker>`** (default: `0`) — Inline space between the label text and the required marker.\n\n**`<lr-code-editor>`, `<lr-color-picker>`, `<lr-date-input>`, `<lr-input>`, `<lr-known-date>`, `<lr-locale-picker>`, `<lr-native-time-input>`, `<lr-number-input>`, `<lr-otp-input>`, `<lr-phone-input>`, `<lr-textarea>`, `<lr-time-input>`, `<lr-tool-param-form>`** (default: `0`) — Inline space between the label text and the marker.\n\n**`<lr-rubric-form>`** (default: `0`) — Inline space between the label text and marker."},{"name":"--lr-funnel-bar-color","description":"**`<lr-funnel>`** (default: `var(--lr-color-brand)`) — Fill of every stage bar that has no own color."},{"name":"--lr-funnel-bar-size","description":"**`<lr-funnel>`** (default: `var(--lr-size-1-5rem)`) — Thickness of a stage's track."},{"name":"--lr-funnel-comparison-color","description":"**`<lr-funnel>`** (default: `var(--lr-color-border-strong)`) — Outline of the comparison bars."},{"name":"--lr-funnel-track-color","description":"**`<lr-funnel>`** (default: `var(--lr-color-surface-raised)`) — Background of the bar track."},{"name":"--lr-gauge-fill","description":"**`<lr-gauge>`** (default: `var(--lr-color-brand)`) — Fill stroke for radial, ring, and linear gauges. The token default follows the effective variant -- `variant`, or the matching `thresholds` entry -- rather than always `brand`."},{"name":"--lr-graph-cat-1","description":"**`<lr-graph>`** (default: `var(--lr-theme-graph-cat-1,#8250df)`) — First categorical fallback color for typed nodes.\n\n**Shared design token** — Canonical shared component token for graph cat 1. Reads `--lr-theme-graph-cat-1`."},{"name":"--lr-graph-cat-2","description":"**`<lr-graph>`** (default: `var(--lr-theme-graph-cat-2,#bf3989)`) — Second categorical fallback color for typed nodes.\n\n**Shared design token** — Canonical shared component token for graph cat 2. Reads `--lr-theme-graph-cat-2`."},{"name":"--lr-graph-cat-3","description":"**`<lr-graph>`** (default: `var(--lr-theme-graph-cat-3,#0a7d91)`) — Third categorical fallback color for typed nodes.\n\n**Shared design token** — Canonical shared component token for graph cat 3. Reads `--lr-theme-graph-cat-3`."},{"name":"--lr-graph-cat-4","description":"**`<lr-graph>`** (default: `var(--lr-theme-graph-cat-4,#57606a)`) — Fourth categorical fallback color for typed nodes.\n\n**Shared design token** — Canonical shared component token for graph cat 4. Reads `--lr-theme-graph-cat-4`."},{"name":"--lr-graph-cat-5","description":"**`<lr-graph>`** (default: `var(--lr-theme-graph-cat-5,#b083f5)`) — Fifth categorical fallback color for typed nodes.\n\n**Shared design token** — Canonical shared component token for graph cat 5. Reads `--lr-theme-graph-cat-5`."},{"name":"--lr-graph-cat-6","description":"**`<lr-graph>`** (default: `var(--lr-theme-graph-cat-6,#f470b8)`) — Sixth categorical fallback color for typed nodes.\n\n**Shared design token** — Canonical shared component token for graph cat 6. Reads `--lr-theme-graph-cat-6`."},{"name":"--lr-graph-cat-7","description":"**`<lr-graph>`** (default: `var(--lr-theme-graph-cat-7,#52d6e8)`) — Seventh categorical fallback color for typed nodes.\n\n**Shared design token** — Canonical shared component token for graph cat 7. Reads `--lr-theme-graph-cat-7`."},{"name":"--lr-graph-cat-8","description":"**`<lr-graph>`** (default: `var(--lr-theme-graph-cat-8,#c9d1d9)`) — Eighth categorical fallback color for typed nodes; the palette wraps for later `nodeTypes` entries.\n\n**Shared design token** — Canonical shared component token for graph cat 8. Reads `--lr-theme-graph-cat-8`."},{"name":"--lr-graph-dimmed-opacity","description":"**`<lr-graph>`** (default: `0.35`) — Opacity applied to a node/link when `dimmedNodeIds`/`dimmedLinkIds` includes its id (both SVG and canvas renderers). Visible by default -- a consumer controlling `dimmedNodeIds`/`dimmedLinkIds` (e.g. `lr-knowledge-graph-explorer`) sees the dimming take effect with no extra host styling."},{"name":"--lr-graph-edge-label-halo","description":"**`<lr-graph>`** (default: `var(--lr-color-surface)`) — Legibility halo (`stroke`) behind a drawn edge label, painted under the fill via `paint-order: stroke`."},{"name":"--lr-graph-focus-halo-color","description":"**`<lr-graph>`** (default: `var(--lr-color-brand)`) — `focus-halo` stroke color."},{"name":"--lr-graph-hull-fill","description":"**`<lr-graph>`** (default: `var(--lr-color-brand)`) — Hull fill/stroke color."},{"name":"--lr-graph-hull-opacity","description":"**`<lr-graph>`** (default: `0.12`) — Hull element opacity (composites fill+stroke as one group, avoiding a double-opacity seam at the fill/stroke boundary). Applies to both SVG and canvas renderers."},{"name":"--lr-graph-legend-hidden-color","description":"**`<lr-graph-legend>`** (default: `var(--lr-color-text-quiet)`) — Text color for a filtered-out (hidden) legend row's label/count, independent of the shared quiet-text token."},{"name":"--lr-graph-legend-hidden-swatch-opacity","description":"**`<lr-graph-legend>`** (default: `0.5`) — Opacity of a filtered-out row's decorative swatch."},{"name":"--lr-graph-query-builder-run-active-bg","description":"**`<lr-graph-query-builder>`** — Run button pressed background; defaults to the current brand active mix."},{"name":"--lr-graph-query-builder-run-bg","description":"**`<lr-graph-query-builder>`** (default: `var(--lr-color-brand)`) — Run button resting background."},{"name":"--lr-graph-query-builder-run-border-color","description":"**`<lr-graph-query-builder>`** (default: `var(--lr-color-brand)`) — Run button resting border color."},{"name":"--lr-graph-query-builder-run-color","description":"**`<lr-graph-query-builder>`** (default: `var(--lr-color-on-brand)`) — Run button resting foreground."},{"name":"--lr-graph-query-builder-run-hover-bg","description":"**`<lr-graph-query-builder>`** — Run button hover background; defaults to the current brand hover mix."},{"name":"--lr-graph-query-builder-save-active-bg","description":"**`<lr-graph-query-builder>`** — Save button pressed background; defaults to the current quiet-brand active mix."},{"name":"--lr-graph-query-builder-save-bg","description":"**`<lr-graph-query-builder>`** (default: `var(--lr-color-surface)`) — Save button resting background."},{"name":"--lr-graph-query-builder-save-border-color","description":"**`<lr-graph-query-builder>`** (default: `var(--lr-color-border)`) — Save button resting border color."},{"name":"--lr-graph-query-builder-save-color","description":"**`<lr-graph-query-builder>`** (default: `var(--lr-color-text)`) — Save button resting foreground."},{"name":"--lr-graph-query-builder-save-hover-bg","description":"**`<lr-graph-query-builder>`** (default: `var(--lr-color-brand-quiet)`) — Save button hover background."},{"name":"--lr-graph-query-builder-saved-delete-active-bg","description":"**`<lr-graph-query-builder>`** (default: `var(--lr-color-danger-quiet)`) — Saved-query delete pressed background."},{"name":"--lr-graph-query-builder-saved-delete-active-color","description":"**`<lr-graph-query-builder>`** — Saved-query delete pressed foreground; defaults to the current danger active mix."},{"name":"--lr-graph-query-builder-saved-delete-color","description":"**`<lr-graph-query-builder>`** (default: `var(--lr-color-text-quiet)`) — Saved-query delete foreground."},{"name":"--lr-graph-query-builder-saved-delete-hover-color","description":"**`<lr-graph-query-builder>`** (default: `var(--lr-color-danger)`) — Saved-query delete hover foreground."},{"name":"--lr-graph-query-builder-saved-load-active-bg","description":"**`<lr-graph-query-builder>`** — Saved-query Load button pressed background; defaults to the current surface active mix."},{"name":"--lr-graph-query-builder-saved-load-color","description":"**`<lr-graph-query-builder>`** (default: `var(--lr-color-text)`) — Saved-query Load button foreground."},{"name":"--lr-graph-selected-color","description":"**`<lr-graph>`** (default: `var(--lr-color-success)`) — Selected node/link stroke."},{"name":"--lr-heatmap-annotation-color","description":"**`<lr-heatmap>`** (default: `var(--lr-color-danger)`) — Border color for an annotated cell."},{"name":"--lr-heatmap-color-steps-gradient","description":"**`<lr-heatmap>`** (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 the legend is rendered, and removed again when either stops being true -- `withoutLegend` takes the whole legend row out of the DOM, and the legend bar is this property's only reader; the fallback is the two-endpoint scale ramp."},{"name":"--lr-heatmap-focus-ring-color","description":"**`<lr-heatmap>`** (default: `var(--lr-focus-ring-color)`) — Focus ring around a focused cell."},{"name":"--lr-heatmap-grid-max-block-size","description":"**`<lr-heatmap>`** (default: `none`) — Block-size ceiling of the `stickyLabels` scrollport. A frozen column band only stays behind once the grid actually scrolls vertically."},{"name":"--lr-heatmap-label-font","description":"**`<lr-heatmap>`** — Font for axis/legend labels drawn on the canvas."},{"name":"--lr-heatmap-no-data-fill","description":"**`<lr-heatmap>`** (default: `var(--lr-color-no-data)`) — Fill for cells with no value."},{"name":"--lr-heatmap-scale-hi","description":"**`<lr-heatmap>`** (default: `var(--lr-color-brand)`) — High endpoint of the sequential color ramp."},{"name":"--lr-heatmap-scale-lo","description":"**`<lr-heatmap>`** (default: `var(--lr-color-brand-quiet)`) — Low endpoint of the sequential color ramp."},{"name":"--lr-heatmap-selected-color","description":"**`<lr-heatmap>`** (default: `var(--lr-color-success)`) — Border color for the selected cell."},{"name":"--lr-heatmap-sticky-label-bg","description":"**`<lr-heatmap>`** (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."},{"name":"--lr-heatmap-tooltip-bg","description":"**`<lr-heatmap>`** (default: `var(--lr-color-surface)`) — Hover tooltip background."},{"name":"--lr-heatmap-tooltip-text","description":"**`<lr-heatmap>`** (default: `var(--lr-color-text)`) — Hover tooltip text color."},{"name":"--lr-highlight-layer-accent-background","description":"**`<lr-highlight-layer>`** — Accent highlight background."},{"name":"--lr-highlight-layer-accent-outline","description":"**`<lr-highlight-layer>`** — Accent highlight outline."},{"name":"--lr-highlight-layer-danger-background","description":"**`<lr-highlight-layer>`** — Danger highlight background."},{"name":"--lr-highlight-layer-danger-outline","description":"**`<lr-highlight-layer>`** — Danger highlight outline."},{"name":"--lr-highlight-layer-flash-background","description":"**`<lr-highlight-layer>`** — Flash-state background."},{"name":"--lr-highlight-layer-neutral-background","description":"**`<lr-highlight-layer>`** — Neutral highlight background."},{"name":"--lr-highlight-layer-neutral-outline","description":"**`<lr-highlight-layer>`** — Neutral highlight outline."},{"name":"--lr-highlight-layer-success-background","description":"**`<lr-highlight-layer>`** — Success highlight background."},{"name":"--lr-highlight-layer-success-outline","description":"**`<lr-highlight-layer>`** — Success highlight outline."},{"name":"--lr-highlight-layer-warning-background","description":"**`<lr-highlight-layer>`** — Warning highlight background."},{"name":"--lr-highlight-layer-warning-outline","description":"**`<lr-highlight-layer>`** — Warning highlight outline."},{"name":"--lr-hover-brightness","description":"**Shared design token** — Canonical shared component token for hover brightness. Reads `--lr-theme-hover-brightness`."},{"name":"--lr-html-viewer-max-height","description":"**`<lr-html-viewer>`** (default: `none`) — Maximum block size of `[part=\"body\"]` before it scrolls internally. The `maxHeight` property sets this token inline on `[part=\"base\"]`."},{"name":"--lr-icon-button-background","description":"**`<lr-icon-button>`** (default: `transparent`) — Background fill of the native button."},{"name":"--lr-icon-button-background-active","description":"**`<lr-icon-button>`** (default: `color-mix(in oklab, var(--lr-color-surface), var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Background fill while pressed: the same mix at the stronger `--lr-color-mix-active` share, so the pressed state is visibly more than the hover."},{"name":"--lr-icon-button-background-hover","description":"**`<lr-icon-button>`** (default: `color-mix(in oklab, var(--lr-color-surface), var(--lr-color-mix-partner) var(--lr-color-mix-hover))`) — Background fill on hover. Before 8.0.0 this fell back to `var(--lr-color-surface)` — the page background — so on a default page a hovered icon button painted itself the colour it was already sitting on and showed no hover at all."},{"name":"--lr-icon-button-border","description":"**`<lr-icon-button>`** (default: `0`) — Complete border shorthand of the native button."},{"name":"--lr-icon-button-border-active","description":"**`<lr-icon-button>`** (default: `var(--lr-icon-button-border-hover, var(--lr-icon-button-border, 0))`) — Complete border shorthand while pressed; falls through to the hover border when only that is set."},{"name":"--lr-icon-button-border-hover","description":"**`<lr-icon-button>`** (default: `var(--lr-icon-button-border, 0)`) — Complete border shorthand on hover."},{"name":"--lr-icon-button-color","description":"**`<lr-icon-button>`** (default: `inherit`) — Icon/text color of the native button."},{"name":"--lr-icon-button-color-active","description":"**`<lr-icon-button>`** (default: `var(--lr-icon-button-color-hover, var(--lr-icon-button-color, inherit))`) — Icon/text color while pressed; falls through to the hover colour when only that is set."},{"name":"--lr-icon-button-color-hover","description":"**`<lr-icon-button>`** (default: `var(--lr-icon-button-color, inherit)`) — Icon/text color on hover."},{"name":"--lr-icon-button-radius","description":"**`<lr-icon-button>`** (default: `var(--lr-radius)`) — Corner radius of the native button."},{"name":"--lr-icon-button-size","description":"**`<lr-icon-button>`** (default: `2.5rem`) — Minimum tappable inline and block size of the native button — a **floor**, not a fixed size: content larger than it grows the button and keeps its own aspect ratio, while a small glyph pads out to it. A library-wide token (declared on every `lr-*` host by `tokens.styles.ts`, and the shared minimum tappable size several other components size their icon controls against), so overriding it globally resizes all of them together. **Element-scoped, unlike the `--lr-icon-button-*` cssprops below:** every `lr-*` host re-declares `--lr-icon-button-size` from `--lr-theme-icon-button-size` in the shared token layer, so an ancestor rule that sets `--lr-icon-button-size` directly is reset the moment it crosses into any intervening `lr-*` component's shadow root and never reaches this element. Set it directly on this element, set `--lr-icon-button-size-scope` on any ancestor to resize one subtree, or set `--lr-theme-icon-button-size` to resize every icon button in the application at once. Only the two ancestor levers keep the coarse-pointer hit-area floor; see `llms/shared.md`.\n\n**Shared design token** — Canonical shared component token for icon button size. Reads `--lr-theme-icon-button-size`."},{"name":"--lr-icon-fixed-width","description":"**`<lr-icon>`** (default: `var(--lr-size-1-5em)`) — Inline size of the box while `fixed-width` is set; the glyph keeps `--lr-icon-size` and centers inside it."},{"name":"--lr-icon-flip-x","description":"**`<lr-icon>`** (default: `1`) — Horizontal scale factor, set to `-1` by `flip`."},{"name":"--lr-icon-flip-y","description":"**`<lr-icon>`** (default: `1`) — Vertical scale factor, set to `-1` by `flip`."},{"name":"--lr-icon-rotate","description":"**`<lr-icon>`** (default: `0deg`) — Rotation applied to the box. Written inline from the `rotate` property, so set that rather than this property."},{"name":"--lr-icon-size","description":"**`<lr-icon>`** — Optional inline and block size override for every canvas."},{"name":"--lr-image-comparer-divider-width","description":"**`<lr-image-comparer>`** (default: `var(--divider-width, var(--lr-size-1px))`) — Width of the dividing line. The canonical, namespaced override; prefer it over the bare compat name, which inherits and so retunes every element in the subtree reading that generic name."},{"name":"--lr-image-comparer-handle-size","description":"**`<lr-image-comparer>`** (default: `var(--handle-size, var(--lr-icon-button-size))`) — Inline and block size of the visible compare handle. Canonical, namespaced override."},{"name":"--lr-image-viewer-annotate-active-bg","description":"**`<lr-image-viewer>`** (default: `var(--lr-color-brand-quiet)`) — Background of `[part=\"annotate-toggle\"]` while annotation mode is on. The toggle carries its own glyph in `--lr-color-text`, so keep a 4.5:1 ratio against it."},{"name":"--lr-image-viewer-annotate-active-border","description":"**`<lr-image-viewer>`** (default: `var(--lr-color-brand)`) — Border color of `[part=\"annotate-toggle\"]` while annotation mode is on."},{"name":"--lr-image-viewer-annotation-box-bg","description":"**`<lr-image-viewer>`** (default: `color-mix(in srgb, var(--lr-color-brand) 15%, transparent)`) — Fill of `[part=\"annotation-box\"]`."},{"name":"--lr-image-viewer-annotation-box-border","description":"**`<lr-image-viewer>`** (default: `var(--lr-color-brand)`) — Border color of `[part=\"annotation-box\"]`, the in-progress draft rectangle drawn while annotating, independent of the saved `[part=\"highlight\"]` boxes' own tone colors."},{"name":"--lr-image-viewer-highlight-active-border-width","description":"**`<lr-image-viewer>`** (default: `var(--lr-border-width-thick)`) — Border width of the `[part=\"highlight\"]` matching `activeHighlightId`."},{"name":"--lr-image-viewer-highlight-active-color","description":"**`<lr-image-viewer>`** (default: `var(--lr-color-brand)`) — Outline color of the `[part=\"highlight\"]` matching `activeHighlightId`, independent of the per-tone border colors."},{"name":"--lr-image-viewer-highlight-active-outline-offset","description":"**`<lr-image-viewer>`** (default: `var(--lr-focus-ring-offset)`) — Outline offset of the `[part=\"highlight\"]` matching `activeHighlightId`."},{"name":"--lr-image-viewer-highlight-active-outline-width","description":"**`<lr-image-viewer>`** (default: `var(--lr-focus-ring-width)`) — Outline width of the `[part=\"highlight\"]` matching `activeHighlightId`."},{"name":"--lr-image-viewer-highlight-bg","description":"**`<lr-image-viewer>`** (default: `color-mix(in srgb, var(--lr-color-brand) 20%, transparent)`) — Default highlight fill."},{"name":"--lr-image-viewer-highlight-border","description":"**`<lr-image-viewer>`** (default: `var(--lr-color-brand)`) — Default highlight border."},{"name":"--lr-image-viewer-highlight-danger-bg","description":"**`<lr-image-viewer>`** — Danger-tone highlight fill."},{"name":"--lr-image-viewer-highlight-danger-border","description":"**`<lr-image-viewer>`** — Danger-tone highlight border."},{"name":"--lr-image-viewer-highlight-fill","description":"**`<lr-image-viewer>`** — The resting fill a `[part=\"highlight\"]` actually renders, resolved per tone from the `--lr-image-viewer-highlight-*-bg` knobs above. Its hover and pressed states are colour mixes taken from this value, so setting it directly retints all three at once for one highlight; retint a whole tone through the `-bg` knob instead."},{"name":"--lr-image-viewer-highlight-neutral-bg","description":"**`<lr-image-viewer>`** — Neutral-tone highlight fill."},{"name":"--lr-image-viewer-highlight-neutral-border","description":"**`<lr-image-viewer>`** — Neutral-tone highlight border."},{"name":"--lr-image-viewer-highlight-success-bg","description":"**`<lr-image-viewer>`** — Success-tone highlight fill."},{"name":"--lr-image-viewer-highlight-success-border","description":"**`<lr-image-viewer>`** — Success-tone highlight border."},{"name":"--lr-image-viewer-highlight-warning-bg","description":"**`<lr-image-viewer>`** — Warning-tone highlight fill."},{"name":"--lr-image-viewer-highlight-warning-border","description":"**`<lr-image-viewer>`** — Warning-tone highlight border."},{"name":"--lr-ingestion-queue-max-height","description":"**`<lr-ingestion-queue>`** (default: `none`) — Non-virtualized mode only: caps how tall the list grows before it scrolls internally. Has no effect once virtualized -- the internal `<lr-virtual-list>`'s own viewport keeps its independent, fixed default height (retheme it directly via `<lr-ingestion-queue>`'s own `lr-virtual-list { --lr-virtual-list-height: ... }` if needed)."},{"name":"--lr-inline-cursor-height","description":"**`<lr-streaming-text>`, `<lr-streaming-text-core>`** (default: `var(--lr-size-1em)`) — Shared height of the inline cursor bar.\n\n**`<lr-typing-indicator>`** (default: `var(--lr-size-1em)`) — Shared inline-cursor height."},{"name":"--lr-inline-cursor-width","description":"**`<lr-streaming-text>`, `<lr-streaming-text-core>`** (default: `var(--lr-size-0-125rem)`) — Shared width of the inline cursor bar (also its border radius).\n\n**`<lr-typing-indicator>`** (default: `var(--lr-size-0-125rem)`) — Shared inline-cursor width. The `size` property supplies compact and roomy tier fallbacks."},{"name":"--lr-input-action-active-bg","description":"**`<lr-input>`, `<lr-native-time-input>`, `<lr-number-input>`** (default: `color-mix(in oklab,var(--lr-color-surface),var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Pressed action background. The same hooks apply to `lr-number-input`'s stepper pair."},{"name":"--lr-input-action-active-color","description":"**`<lr-input>`, `<lr-native-time-input>`, `<lr-number-input>`** (default: `var(--lr-input-action-hover-color,var(--lr-color-text))`) — Pressed action color."},{"name":"--lr-input-action-color","description":"**`<lr-input>`, `<lr-native-time-input>`, `<lr-number-input>`** (default: `var(--lr-color-text-quiet)`) — Resting clear/password/number- stepper action color."},{"name":"--lr-input-action-hover-color","description":"**`<lr-input>`, `<lr-native-time-input>`, `<lr-number-input>`** (default: `var(--lr-color-text)`) — Hovered action color."},{"name":"--lr-input-border-color","description":"**`<lr-input>`, `<lr-native-time-input>`, `<lr-number-input>`** (default: `var(--lr-color-border)`) — Border color of the control row, with a private default that changes per `appearance` in the same way as `--lr-input-fill`."},{"name":"--lr-input-control-height","description":"**`<lr-input>`, `<lr-native-time-input>`, `<lr-number-input>`** — Exact outer control height. Unset by default, which leaves `--lr-input-control-min-height` as a floor only; set it to a length to both floor and cap the control row (e.g. to pixel-match `<lr-select>`/`<lr-combobox>` in the same toolbar). Because it is never declared by the component itself, it can be set from an ancestor or an outer-tree rule as well as inline on the element."},{"name":"--lr-input-control-min-height","description":"**`<lr-input>`, `<lr-native-time-input>`, `<lr-number-input>`** (default: `var(--lr-form-control-height)`) — Outer control height floor, taken from the active `size` tier of the shared form-control ladder (`internal/sizes.styles.ts`), so an input is exactly as tall as an `<lr-button>`/`<lr-select>` of the same tier."},{"name":"--lr-input-fill","description":"**`<lr-input>`, `<lr-native-time-input>`, `<lr-number-input>`** (default: `transparent`) — Background of the control row. Its private default changes per `appearance`; the public value remains authoritative in every appearance."},{"name":"--lr-input-focus-border-color","description":"**`<lr-input>`, `<lr-native-time-input>`, `<lr-number-input>`** (default: `var(--lr-color-brand)`) — Control-row border color while focus is within the field."},{"name":"--lr-input-font-size","description":"**`<lr-input>`, `<lr-native-time-input>`, `<lr-number-input>`** (default: `var(--lr-form-control-font-size)`) — Font size of the native input, from the active `size` tier."},{"name":"--lr-input-gap","description":"**`<lr-input>`, `<lr-native-time-input>`, `<lr-number-input>`** (default: `var(--lr-space-xs)`) — Gap between the start/end adornments and the native input in the control row. Unlike the size knobs above it does not vary by `size` tier. Override it to retune without a `::part(input-wrapper)` rule."},{"name":"--lr-input-padding-block","description":"**`<lr-input>`, `<lr-native-time-input>`, `<lr-number-input>`** (default: `var(--lr-form-control-padding-block)`) — Block padding of the native input, from the active `size` tier of the shared ladder."},{"name":"--lr-input-padding-inline","description":"**`<lr-input>`, `<lr-native-time-input>`, `<lr-number-input>`** (default: `var(--lr-form-control-padding-inline)`) — Inline padding of the control row, from the active `size` tier."},{"name":"--lr-input-radius","description":"**`<lr-input>`, `<lr-native-time-input>`, `<lr-number-input>`** (default: `var(--lr-form-control-radius)`) — Corner radius of the control row, from the active `size` tier of the shared ladder (the two tightest tiers take a smaller radius). `pill` swaps it to `--lr-radius-pill`."},{"name":"--lr-input-time-picker-active-bg","description":"**`<lr-input>`, `<lr-native-time-input>`, `<lr-number-input>`** (default: `var(--lr-color-brand)`) — Pressed background for the browser-native time-picker indicator when `type=\"time\"`."},{"name":"--lr-input-time-picker-focus-bg","description":"**`<lr-input>`, `<lr-native-time-input>`, `<lr-number-input>`** (default: `var(--lr-color-brand-quiet)`) — Focus-visible background for the native time-picker indicator."},{"name":"--lr-input-time-picker-focus-ring","description":"**`<lr-input>`, `<lr-native-time-input>`, `<lr-number-input>`** (default: `var(--lr-focus-ring-color)`) — Focus-visible outline color for the native time-picker indicator."},{"name":"--lr-input-time-picker-hover-bg","description":"**`<lr-input>`, `<lr-native-time-input>`, `<lr-number-input>`** (default: `var(--lr-color-brand-quiet)`) — Hover background for the browser-native time-picker indicator when `type=\"time\"`."},{"name":"--lr-json-viewer-active-outline","description":"**`<lr-json-viewer>`** (default: `var(--lr-focus-ring-color)`) — Outline color for the current imperative search match."},{"name":"--lr-json-viewer-boolean-color","description":"**`<lr-json-viewer>`** (default: `var(--lr-color-warning)`) — Boolean value color."},{"name":"--lr-json-viewer-font","description":"**`<lr-json-viewer>`** (default: `var(--lr-font-mono)`) — Font family used for the rendered tree."},{"name":"--lr-json-viewer-match-bg","description":"**`<lr-json-viewer>`** (default: `var(--lr-color-warning-quiet)`) — Background (and surrounding box-shadow) of a key/value that currently matches `search`."},{"name":"--lr-json-viewer-max-height","description":"**`<lr-json-viewer>`** (default: `none`) — Cap on `[part=\"base\"]`'s block size, past which the viewer scrolls internally. The `maxHeight` property sets this token inline on `[part=\"base\"]`."},{"name":"--lr-json-viewer-null-color","description":"**`<lr-json-viewer>`** (default: `var(--lr-color-text-quiet)`) — Null, undefined, and circular-reference marker color."},{"name":"--lr-json-viewer-number-color","description":"**`<lr-json-viewer>`** (default: `var(--lr-color-brand)`) — Number value color."},{"name":"--lr-json-viewer-row-hover-bg","description":"**`<lr-json-viewer>`** (default: `var(--lr-color-brand-quiet)`) — Hover background for a structural row."},{"name":"--lr-json-viewer-string-color","description":"**`<lr-json-viewer>`** (default: `var(--lr-color-success)`) — String value color."},{"name":"--lr-knowledge-base-admin-tab-selected-border","description":"**`<lr-knowledge-base-admin>`** (default: `var(--lr-color-brand)`) — Bottom border color of the selected `[part=\"tab\"]`."},{"name":"--lr-knowledge-base-admin-tab-selected-color","description":"**`<lr-knowledge-base-admin>`** (default: `var(--lr-color-text)`) — Text color of the selected `[part=\"tab\"]`. `::part(tab)[aria-selected='true']` is invalid CSS, so this pair is the only way to restyle the active tab without re-pointing the shared brand/text tokens."},{"name":"--lr-known-date-day-field-width","description":"**`<lr-known-date>`** (default: `var(--lr-size-3-5em)`) — Inline size of the day field."},{"name":"--lr-known-date-field-font-size","description":"**`<lr-known-date>`** (default: `var(--lr-form-control-font-size)`) — Font size of each `field-input`; its private default follows `size` through the shared ladder."},{"name":"--lr-known-date-field-gap","description":"**`<lr-known-date>`** (default: `var(--lr-space-s)`) — Gap between the three field blocks."},{"name":"--lr-known-date-field-height","description":"**`<lr-known-date>`** — Exact block size of each `field-input`. Undeclared by default, so the field grows to fit its content, floored by `--lr-known-date-field-min-height`. Set it to pin a fixed height."},{"name":"--lr-known-date-field-min-height","description":"**`<lr-known-date>`** (default: `max(var(--lr-form-control-height),var(--lr-size-24px))`) — Minimum block size of each `field-input`; its private default follows `size` (`2xs`/`xs`→`24px`, `s`→`1.875rem`, `m`→`2.5rem`, `l`→`3rem`, `xl`→`3.5rem`) -- the same shared control-height ladder `lr-input`/`lr-date-input` sit on, so a birthdate field in a form row beside those controls renders at the same height. The `max()` floors the two smallest tiers at WCAG 2.2 SC 2.5.8's 24px pointer-target minimum. At the small tiers the floor exceeds the field's own content height and actively pins the rendered box; at `l`/`xl` the content height stays under it, so those two tiers are unaffected. An inherited or direct public value wins in every tier."},{"name":"--lr-known-date-field-padding-block","description":"**`<lr-known-date>`** (default: `var(--lr-form-control-padding-block)`) — Block padding of each `field-input`; its private default follows `size` through the shared ladder."},{"name":"--lr-known-date-field-padding-inline","description":"**`<lr-known-date>`** (default: `var(--lr-form-control-padding-inline)`) — Inline padding of each `field-input`; its private default follows `size` through the shared ladder."},{"name":"--lr-known-date-invalid-border-color","description":"**`<lr-known-date>`** (default: `var(--lr-color-danger)`) — Border color of each `field-input` while `:host([data-invalid])` is set."},{"name":"--lr-known-date-month-field-width","description":"**`<lr-known-date>`** (default: `var(--lr-size-3-5em)`) — Inline size of the month field."},{"name":"--lr-known-date-year-field-width","description":"**`<lr-known-date>`** (default: `var(--lr-size-5em)`) — Inline size of the year field."},{"name":"--lr-layer-base","description":"**Shared design token** — Canonical shared component token for layer base. Reads `--lr-theme-z-index-base`."},{"name":"--lr-layer-content","description":"**Shared design token** — Canonical shared component token for layer content. Reads `--lr-theme-z-index-content`."},{"name":"--lr-layer-dropdown","description":"**Shared design token** — Canonical shared component token for layer dropdown. Reads `--lr-theme-z-index-dropdown`."},{"name":"--lr-layer-modal","description":"**Shared design token** — Canonical shared component token for layer modal. Reads `--lr-theme-z-index-modal`."},{"name":"--lr-layer-popover","description":"**Shared design token** — Canonical shared component token for layer popover. Reads `--lr-theme-z-index-popover`."},{"name":"--lr-layer-toast","description":"**Shared design token** — Canonical shared component token for layer toast. Reads `--lr-theme-z-index-toast`."},{"name":"--lr-lightbox-control-bg","description":"**`<lr-lightbox>`** — Background for every floating/toolbar icon button."},{"name":"--lr-lightbox-control-color","description":"**`<lr-lightbox>`** — Icon/text color paired with `--lr-lightbox-control-bg`."},{"name":"--lr-lightbox-overlay-color","description":"**`<lr-lightbox>`** — The backdrop scrim color."},{"name":"--lr-line-height-1-4","description":"**Shared design token** — Canonical shared component token for line height 1 4. Reads `--lr-theme-line-height-1-4`."},{"name":"--lr-line-height-compact","description":"**Shared design token** — Canonical shared component token for line height compact. Reads `--lr-theme-line-height-compact`."},{"name":"--lr-line-height-loose","description":"**Shared design token** — Canonical shared component token for line height loose. Reads `--lr-theme-line-height-loose`."},{"name":"--lr-line-height-none","description":"**Shared design token** — Canonical shared component token for line height none. Reads `--lr-theme-line-height-none`."},{"name":"--lr-line-height-normal","description":"**Shared design token** — Canonical shared component token for line height normal. Reads `--lr-theme-line-height-normal`."},{"name":"--lr-line-height-snug","description":"**Shared design token** — Canonical shared component token for line height snug. Reads `--lr-theme-line-height-snug`."},{"name":"--lr-link-color","description":"**`<lr-graph>`** (default: `var(--lr-color-border)`) — Default link stroke, overridden per-link by a link's own `color`."},{"name":"--lr-lite-chart-data-table-toggle-active-bg","description":"**`<lr-lite-chart>`** — Pressed background of the `dataTableToggle` disclosure button; defaults to a mix of the hover background with the shared active mix partner."},{"name":"--lr-lite-chart-data-table-toggle-hover-bg","description":"**`<lr-lite-chart>`** (default: `var(--lr-color-brand-quiet)`) — Hover background of the `dataTableToggle` disclosure button."},{"name":"--lr-lite-chart-selected-outline-color","description":"**`<lr-lite-chart>`** (default: `var(--lr-color-brand)`) — Stroke for a bar/point whose category index is in `selectedIndices`."},{"name":"--lr-lite-chart-selected-outline-width","description":"**`<lr-lite-chart>`** (default: `var(--lr-size-2px)`) — Stroke width for a bar/point whose category index is in `selectedIndices`."},{"name":"--lr-locale-picker-expand-size","description":"**`<lr-locale-picker>`** — Decorative expand-icon box size, scaled by `size`."},{"name":"--lr-locale-picker-font-size","description":"**`<lr-locale-picker>`** (default: `var(--lr-form-control-font-size)`) — Trigger font size, from the shared form-control size ladder."},{"name":"--lr-locale-picker-gap","description":"**`<lr-locale-picker>`** (default: `var(--lr-space-xs)`) — Trigger and option child gap."},{"name":"--lr-locale-picker-open-border-color","description":"**`<lr-locale-picker>`** (default: `var(--lr-color-brand)`) — Open trigger border color."},{"name":"--lr-locale-picker-option-active-bg","description":"**`<lr-locale-picker>`** (default: `var(--lr-color-brand-quiet)`) — Background of a hovered or keyboard-active option row."},{"name":"--lr-locale-picker-option-selected-border-color","description":"**`<lr-locale-picker>`** (default: `var(--lr-color-brand)`) — Selected option border."},{"name":"--lr-locale-picker-option-selected-color","description":"**`<lr-locale-picker>`** (default: `var(--lr-color-brand)`) — Selected option text."},{"name":"--lr-locale-picker-option-selected-font-weight","description":"**`<lr-locale-picker>`** (default: `var(--lr-font-weight-semibold)`) — Selected option font weight."},{"name":"--lr-locale-picker-radius","description":"**`<lr-locale-picker>`** (default: `var(--lr-radius)`) — Trigger/listbox/option corner radius."},{"name":"--lr-locale-picker-trigger-border-color","description":"**`<lr-locale-picker>`** (default: `var(--lr-color-border)`) — Resting trigger border color."},{"name":"--lr-locale-picker-trigger-fill","description":"**`<lr-locale-picker>`** (default: `var(--lr-color-surface)`) — Resting trigger background."},{"name":"--lr-locale-picker-trigger-height","description":"**`<lr-locale-picker>`** — Exact trigger height. Unset by default (a floor only via `-trigger-min-height`); set a length to both floor and cap the trigger, e.g. to pixel-match a sibling field in the same toolbar row."},{"name":"--lr-locale-picker-trigger-hover-bg","description":"**`<lr-locale-picker>`** (default: `var(--lr-color-brand-quiet)`) — Trigger hover background."},{"name":"--lr-locale-picker-trigger-hover-border-color","description":"**`<lr-locale-picker>`** (default: `var(--lr-locale-picker-trigger-border-color)`) — Trigger border color while the pointer is over it. Unset, the border stays exactly where the resting state left it."},{"name":"--lr-locale-picker-trigger-min-height","description":"**`<lr-locale-picker>`** (default: `var(--lr-form-control-height)`) — Trigger block-size floor. Reads the shared form-control height ladder, so retuning `--lr-theme-form-control-height-*` moves this control and every sibling field together."},{"name":"--lr-locale-picker-trigger-padding","description":"**`<lr-locale-picker>`** — Trigger padding shorthand, scaled by `size`."},{"name":"--lr-map-choropleth-fill-opacity","description":"**`<lr-map>`** (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."},{"name":"--lr-map-height","description":"**`<lr-map>`** (default: `var(--lr-size-24rem)`) — Default host block size, shared with the pre-upgrade reservation stylesheet. An explicit outer `block-size` still wins."},{"name":"--lr-map-hidden-category-opacity","description":"**`<lr-map>`** (default: `0.15`) — Opacity a hidden category's points, point strokes and point icons are muted to in the rendered MapLibre paint. Read from the resolved cascade on every paint, because MapLibre draws to a WebGL canvas the CSS cascade never reaches."},{"name":"--lr-map-legend-hidden-swatch-opacity","description":"**`<lr-map>`** (default: `0.5`) — Opacity of a hidden interactive legend row's decorative swatch. Only the `aria-hidden` swatch dims; the label re-colors through the quiet text token instead, so it keeps AA contrast."},{"name":"--lr-map-popup-close-button-active-bg","description":"**`<lr-map>`** (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`."},{"name":"--lr-map-popup-close-button-active-color","description":"**`<lr-map>`** (default: `var(--lr-color-brand)`) — Pressed foreground of `popup-close-button`. The legend is read-only unless `legendInteractive` is set, which is opt-in for a reason: an unset map renders exactly the key it rendered before, with no button, no extra attribute and no extra MapLibre paint key. Only a row that carries its own `value` becomes a toggle -- the key is never derived from an `icon` record's `value`, which would silently make a row operable the author never marked. Each toggle is a native `button`, so it is one independent tab stop per row (a 100-row legend contributes 100, exactly as a 100-series `lr-chart` legend does) and it grows to the shared `--lr-icon-button-size` hit-area floor. Activation emits the cancelable `lr-map-legend-toggle`; there is deliberately no confirmation event, because the committed state is `hiddenCategories` and the host already observes it. A hidden category mutes its points, point strokes and point icons through `--lr-map-hidden-category-opacity`; a `kind: 'heatmap'` entry is deliberately out of scope, having no per-category field to mute. 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."},{"name":"--lr-map-popup-close-button-hover-bg","description":"**`<lr-map>`** (default: `var(--lr-color-brand-quiet)`) — Hover background of `popup-close-button`."},{"name":"--lr-map-popup-close-button-hover-color","description":"**`<lr-map>`** (default: `var(--lr-color-brand)`) — Hover foreground of `popup-close-button`."},{"name":"--lr-markdown-code-bg","description":"**`<lr-markdown>`, `<lr-markdown-core>`** (default: `var(--lr-color-brand-quiet)`) — Background shared by every inline `code` span and the fenced `code-block` surface."},{"name":"--lr-markdown-code-block-padding","description":"**`<lr-markdown>`, `<lr-markdown-core>`** (default: `var(--lr-space-s) var(--lr-space-m)`) — Padding of the fenced `code-block` surface."},{"name":"--lr-markdown-code-block-radius","description":"**`<lr-markdown>`, `<lr-markdown-core>`** (default: `var(--lr-radius)`) — Border radius of the fenced `code-block` surface."},{"name":"--lr-markdown-code-padding","description":"**`<lr-markdown>`, `<lr-markdown-core>`** (default: `var(--lr-size-0-125rem) var(--lr-size-0-3125rem)`) — Padding of an inline `code` span."},{"name":"--lr-markdown-code-radius","description":"**`<lr-markdown>`, `<lr-markdown-core>`** (default: `calc(var(--lr-radius) * 0.5)`) — Border radius of an inline `code` span."},{"name":"--lr-markdown-font-mono","description":"**`<lr-markdown>`, `<lr-markdown-core>`** (default: `var(--lr-font-mono)`) — Monospace family for rendered `<code>` inside `content`."},{"name":"--lr-markdown-highlight-accent-bg","description":"**`<lr-markdown>`, `<lr-markdown-core>`** (default: `var(--lr-color-brand-quiet)`) — Accent highlight fill."},{"name":"--lr-markdown-highlight-active-bg","description":"**`<lr-markdown>`, `<lr-markdown-core>`** (default: `var(--lr-color-brand-quiet)`) — Active highlight fill."},{"name":"--lr-markdown-highlight-active-outline-color","description":"**`<lr-markdown>`, `<lr-markdown-core>`** (default: `var(--lr-color-brand)`) — Active highlight outline."},{"name":"--lr-markdown-highlight-danger-bg","description":"**`<lr-markdown>`, `<lr-markdown-core>`** (default: `var(--lr-color-danger-quiet)`) — Danger highlight fill."},{"name":"--lr-markdown-highlight-neutral-bg","description":"**`<lr-markdown>`, `<lr-markdown-core>`** (default: `var(--lr-color-surface)`) — Neutral highlight fill."},{"name":"--lr-markdown-highlight-success-bg","description":"**`<lr-markdown>`, `<lr-markdown-core>`** (default: `var(--lr-color-success-quiet)`) — Success highlight fill."},{"name":"--lr-markdown-highlight-warning-bg","description":"**`<lr-markdown>`, `<lr-markdown-core>`** (default: `var(--lr-color-warning-quiet)`) — Warning highlight fill."},{"name":"--lr-markdown-max-height","description":"**`<lr-markdown>`, `<lr-markdown-core>`** (default: `none`) — Cap on `[part=\"content\"]`'s block size, past which the document scrolls internally. The `maxHeight` property sets this token inline on `[part=\"content\"]`."},{"name":"--lr-markdown-table-header-bg","description":"**`<lr-markdown>`, `<lr-markdown-core>`** (default: `var(--lr-color-brand-quiet)`) — Background of every rendered `[part=\"table\"]` header cell (`<th>`)."},{"name":"--lr-mask-opaque","description":"**Shared design token** — Canonical shared component token for mask opaque."},{"name":"--lr-media-card-active-bg","description":"**`<lr-media-card>`** (default: `color-mix(in oklab, var(--lr-color-surface), var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Pressed background color for image/file card actions. **Chrome escape hatch.** `frame=\"plain\"` drops `[part=\"base\"]`'s border, background, padding, and corner radius — for a dense list/feed of cards (this component's own documented primary use case) where the surrounding container already provides its own separation, so cards don't double up on chrome. `frame` is the library-wide name for this container treatment."},{"name":"--lr-media-card-active-border-color","description":"**`<lr-media-card>`** (default: `color-mix(in oklab, var(--lr-color-brand), var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Pressed border color for image/file card actions."},{"name":"--lr-media-card-bg","description":"**`<lr-media-card>`** (default: `var(--lr-color-surface)`) — Background of the RESTING `frame=\"card\"` chrome, the companion to the pressed state's `--lr-media-card-active-bg`. `frame=\"plain\"` still drops the fill entirely."},{"name":"--lr-media-card-max-height","description":"**`<lr-media-card>`** (default: `var(--lr-size-20rem)`) — Cap on the block size of the `<img>`/`<video>` in `[part=\"media\"]`."},{"name":"--lr-memory-panel-confidence-danger-color","description":"**`<lr-memory-panel>`** (default: `var(--lr-color-danger)`) — Text color for a low-confidence item's confidence indicator."},{"name":"--lr-memory-panel-confidence-success-color","description":"**`<lr-memory-panel>`** (default: `var(--lr-color-success)`) — Text color for a high-confidence item's confidence indicator."},{"name":"--lr-memory-panel-confidence-warning-color","description":"**`<lr-memory-panel>`** (default: `var(--lr-color-warning)`) — Text color for a medium-confidence item's confidence indicator."},{"name":"--lr-mention-popover-option-active-bg","description":"**`<lr-mention-popover>`** (default: `var(--lr-color-brand-quiet)`) — Background of the hovered or `[data-active]` (keyboard-highlighted) suggestion row."},{"name":"--lr-mention-popover-option-disabled-opacity","description":"**`<lr-mention-popover>`** (default: `0.5`) — Opacity of a row whose `items` entry sets `disabled`."},{"name":"--lr-menu-item-active-bg","description":"**`<lr-dropdown-item>`, `<lr-menu-item>`** (default: `color-mix(in oklab,var(--lr-menu-item-hover-bg,var(--lr-color-brand-quiet)),var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Background of an enabled row while pressed, matching `--lr-option-active-bg`'s equivalent hook. Left unset, the pressed fill keeps mixing from `--lr-menu-item-hover-bg` as before this hook existed."},{"name":"--lr-menu-item-checked-bg","description":"**`<lr-dropdown-item>`, `<lr-menu-item>`** (default: `transparent`) — Background of a checked (`type=\"checkbox\" checked` or `type=\"radio\" checked`) row."},{"name":"--lr-menu-item-checked-color","description":"**`<lr-dropdown-item>`, `<lr-menu-item>`** (default: `inherit`) — Foreground of a checked row."},{"name":"--lr-menu-item-checked-font-weight","description":"**`<lr-dropdown-item>`, `<lr-menu-item>`** (default: `inherit`) — Font weight of a checked row."},{"name":"--lr-menu-item-danger-active-bg","description":"**`<lr-dropdown-item>`, `<lr-menu-item>`** (default: `color-mix(in oklab, var(--lr-color-danger-quiet), var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Background of an enabled danger row while pressed. Checked-state hooks are also inline fallbacks, matching `<lr-option>`/`<lr-select>`/ `<lr-combobox>`/`<lr-tree-item>`'s equivalent row-chrome hooks; all three default to no visual change, so a `type=\"checkbox\"`/`type=\"radio\"` item's checked row paints identically to before these existed unless a consumer sets one."},{"name":"--lr-menu-item-danger-color","description":"**`<lr-dropdown-item>`, `<lr-menu-item>`** (default: `var(--lr-color-danger)`) — Foreground of a `variant=\"danger\"` row."},{"name":"--lr-menu-item-danger-hover-bg","description":"**`<lr-dropdown-item>`, `<lr-menu-item>`** (default: `var(--lr-color-danger-quiet)`) — Background of an enabled danger row while hovered."},{"name":"--lr-menu-item-gap","description":"**`<lr-dropdown-item>`, `<lr-menu-item>`** (default: `var(--lr-space-xs)`) — Gap between the visual parts of `[part=\"base\"]`, including its leading content, label, trailing details, and state glyphs. Declared as an inline `var()` fallback (never on `:host`), so an item or any ancestor can retune it without a `::part(base)` rule. It is constant across the shared size ladder."},{"name":"--lr-menu-item-hover-bg","description":"**`<lr-dropdown-item>`, `<lr-menu-item>`** (default: `var(--lr-color-brand-quiet)`) — Background of an enabled row under the pointer. The pressed state mixes from this same value, so a retuned hover fill keeps its pressed step instead of snapping back to the brand default."},{"name":"--lr-menu-item-icon-color","description":"**`<lr-dropdown-item>`, `<lr-menu-item>`** (default: `inherit`) — Foreground of the leading icon wrapper. Unset it inherits the row's colour, including the danger variant's."},{"name":"--lr-menu-item-min-height","description":"**`<lr-dropdown-item>`, `<lr-menu-item>`** (default: `max(var(--lr-form-control-height),var(--lr-size-24px))`) — Minimum block size of the visual row. Unset it is the shared form-control ladder floored at the WCAG 2.2 SC 2.5.8 minimum, exactly as before this hook existed."},{"name":"--lr-menu-item-radius","description":"**`<lr-dropdown-item>`, `<lr-menu-item>`** (default: `var(--lr-form-control-radius)`) — Corner radius of the visual row and focusable host. Its fallback follows the active shared size tier. Declared as an inline `var()` fallback (never on `:host`), so an item or any ancestor can retune it without a `::part(base)` rule. Danger-state hooks are also inline fallbacks, so a menu can retheme only its dangerous rows without replacing the shared danger palette elsewhere."},{"name":"--lr-menu-max-inline-size","description":"**`<lr-menu>`** (default: `var(--lr-size-20rem)`) — Width ceiling of the standalone menu surface and of a submenu's own surface. Takes a length or a percentage; `100%` and `none` both uncap it to the container, and any other value outside `<length-percentage>` is treated as `none` rather than silently dropping the cap's safety terms. The viewport clamp and the container allocation are applied outside this name, so no value can make a menu overflow either. A contained menu (inside `lr-dropdown`) sizes from its dropdown and is unaffected."},{"name":"--lr-menu-min-inline-size","description":"**`<lr-menu>`** (default: `var(--lr-size-10rem)`) — Width floor of the same two surfaces. Lower it alongside `--lr-menu-max-inline-size` to make a menu narrower than 10rem; the floor wins over the ceiling, so capping alone cannot go below it."},{"name":"--lr-message-feedback-down-active-bg","description":"**`<lr-message-feedback>`** (default: `var(--lr-color-danger-quiet)`) — Background of the pressed thumbs-down button."},{"name":"--lr-message-feedback-down-active-border","description":"**`<lr-message-feedback>`** (default: `var(--lr-color-danger)`) — Border color of the pressed thumbs-down button."},{"name":"--lr-message-feedback-down-active-color","description":"**`<lr-message-feedback>`** (default: `var(--lr-color-danger)`) — Glyph color of the pressed thumbs-down button."},{"name":"--lr-message-feedback-up-active-bg","description":"**`<lr-message-feedback>`** (default: `var(--lr-color-success-quiet)`) — Background of the pressed thumbs-up button."},{"name":"--lr-message-feedback-up-active-border","description":"**`<lr-message-feedback>`** (default: `var(--lr-color-success)`) — Border color of the pressed thumbs-up button."},{"name":"--lr-message-feedback-up-active-color","description":"**`<lr-message-feedback>`** (default: `var(--lr-color-success)`) — Glyph color of the pressed thumbs-up button. Not declared on `:host`, so it can be set on the element or any ancestor; scoped to the pressed state, unlike overriding the shared `--lr-color-success`."},{"name":"--lr-message-parts-audio-transcript-color","description":"**`<lr-message-parts>`** (default: `var(--lr-color-text-quiet)`) — Text color of an audio transcript."},{"name":"--lr-message-parts-error-background","description":"**`<lr-message-parts>`** (default: `var(--lr-color-danger-quiet)`) — Background color of an error part."},{"name":"--lr-message-parts-error-border-color","description":"**`<lr-message-parts>`** (default: `var(--lr-color-danger)`) — Border color of an error part."},{"name":"--lr-message-parts-error-color","description":"**`<lr-message-parts>`** (default: `var(--lr-color-danger)`) — Text color of an error part."},{"name":"--lr-message-parts-streaming-color","description":"**`<lr-message-parts>`** (default: `var(--lr-color-text-quiet)`) — Text color of a streaming part wrapper."},{"name":"--lr-mind-map-node-hover-halo","description":"**`<lr-mind-map>`** (default: `var(--lr-color-brand-quiet)`) — Stroke color of the hover halo drawn around a topic node's dot, giving mouse users the same \"this is clickable\" feedback keyboard users get from the drawn focus ring."},{"name":"--lr-mind-map-ring-gap","description":"**`<lr-mind-map>`** (default: `6rem`) — Radius step per depth ring."},{"name":"--lr-model-select-expand-size","description":"**`<lr-model-select>`** (default: `var(--lr-size-1-75rem)`) — Decorative expand-icon box size, scaled by `size`."},{"name":"--lr-model-select-font-size","description":"**`<lr-model-select>`** (default: `var(--lr-form-control-font-size)`) — Trigger/combobox font size, scaled by `size` off the shared control ladder."},{"name":"--lr-model-select-gap","description":"**`<lr-model-select>`** (default: `var(--lr-space-xs)`) — Trigger, combobox, and option child gap."},{"name":"--lr-model-select-max-inline-size","description":"**`<lr-model-select>`** (default: `var(--lr-size-24rem)`) — The host's own width ceiling. Set a length to retune it, or `none` to let the control fill its container the way `<lr-select>` does."},{"name":"--lr-model-select-open-border-color","description":"**`<lr-model-select>`** (default: `var(--lr-color-brand)`) — Open trigger border color."},{"name":"--lr-model-select-option-active-bg","description":"**`<lr-model-select>`** (default: `var(--lr-color-brand-quiet)`) — Background of a hovered or keyboard-active option row."},{"name":"--lr-model-select-option-disabled-opacity","description":"**`<lr-model-select>`** (default: `0.5`) — Opacity of an option row whose catalog entry sets `disabled`."},{"name":"--lr-model-select-option-selected-bg","description":"**`<lr-model-select>`** (default: `transparent`) — Background of the currently-selected option row. Not declared on `:host`; retheme without hijacking `--lr-color-brand`."},{"name":"--lr-model-select-option-selected-border","description":"**`<lr-model-select>`** (default: `var(--lr-color-brand)`) — Border color of the selected option row."},{"name":"--lr-model-select-option-selected-color","description":"**`<lr-model-select>`** (default: `var(--lr-color-brand)`) — Text color of the selected option row."},{"name":"--lr-model-select-option-selected-font-weight","description":"**`<lr-model-select>`** (default: `var(--lr-font-weight-semibold)`) — Font weight of the selected option row."},{"name":"--lr-model-select-option-synthetic-border-color","description":"**`<lr-model-select>`** (default: `var(--lr-color-border)`) — Border color of a synthetic stale-value option row."},{"name":"--lr-model-select-option-synthetic-border-style","description":"**`<lr-model-select>`** (default: `dashed`) — Border style of a synthetic stale-value option row."},{"name":"--lr-model-select-radius","description":"**`<lr-model-select>`** (default: `var(--lr-radius)`) — Trigger, combobox, listbox, and option corner radius."},{"name":"--lr-model-select-trigger-border-color","description":"**`<lr-model-select>`** (default: `var(--lr-color-border)`) — Resting trigger/combobox border color, independent of the open-state color below."},{"name":"--lr-model-select-trigger-fill","description":"**`<lr-model-select>`** (default: `var(--lr-color-surface)`) — Resting trigger/combobox background."},{"name":"--lr-model-select-trigger-height","description":"**`<lr-model-select>`** — Exact trigger/combobox height. Unset by default (a floor only, via `-trigger-min-height`); set a length to both floor and cap the control, e.g. to pixel-match a sibling field in the same toolbar row. Takes precedence over `-trigger-min-height`."},{"name":"--lr-model-select-trigger-min-height","description":"**`<lr-model-select>`** (default: `var(--lr-form-control-height)`) — Trigger/combobox block-size floor, scaled by `size` off the shared control ladder."},{"name":"--lr-model-select-trigger-padding","description":"**`<lr-model-select>`** (default: `var(--lr-form-control-padding-block) var(--lr-form-control-padding-inline)`) — Trigger/combobox padding shorthand, scaled by `size` off the shared control ladder."},{"name":"--lr-model-settings-panel-max-inline-size","description":"**`<lr-model-settings-panel>`** (default: `var(--lr-size-28rem)`) — The card's own width ceiling. Set a length to retune it or `none` for a full-width card. `layout=\"compact\"` uncaps the card by default, and reads the same name, so a length still narrows a compact card."},{"name":"--lr-multi-split-divider-active-color","description":"**`<lr-multi-split>`** (default: `color-mix(in oklab,var(--lr-color-brand),var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — The divider hairline's color while a resize gesture is pressed (pointer capture holds this through the whole drag)."},{"name":"--lr-multi-split-divider-color","description":"**`<lr-multi-split>`** (default: `var(--lr-color-border)`) — The divider hairline's resting color."},{"name":"--lr-multi-split-divider-hover-color","description":"**`<lr-multi-split>`** (default: `var(--lr-color-brand)`) — The divider hairline's color on hover."},{"name":"--lr-multi-split-divider-target-size","description":"**`<lr-multi-split>`** (default: `max(var(--lr-icon-button-size),var(--lr-size-3px))`) — The real layout gutter reserved for each divider along the resize axis. The narrow visual rule is centered inside this owned track, so the target never overlaps either adjacent panel."},{"name":"--lr-multi-split-divider-thickness","description":"**`<lr-multi-split>`** (default: `var(--lr-size-3px)`) — The painted hairline's own thickness, independent of `--lr-multi-split-divider-target-size` above -- retuning either one never changes the other, so the WCAG 2.5.8 pointer target can never be shrunk by a thinner or thicker visual line."},{"name":"--lr-multi-split-floating-panel-inline-size","description":"**`<lr-multi-split>`** — Overrides the `'floating'` collapse state's overlay card `inline-size`, which otherwise mirrors its own live `sizes[i]` percent (i.e. what it renders at in the `'wide'` state). Unset, geometry is identical to today's behavior; set, it wins over that percent without needing `!important` against the live-synced inline style."},{"name":"--lr-multi-split-floating-panel-inset","description":"**`<lr-multi-split>`** (default: `0`) — The `'floating'` drawer's distance from `[part=\"base\"]`'s edges, applied to both block insets and to whichever logical inline edge `collapse` anchors the drawer to. Unset, the drawer stays flush with the container exactly as before; set once, it insets on all three anchored edges (the free inline edge stays governed by the panel's own width)."},{"name":"--lr-multi-split-overlay-color","description":"**`<lr-multi-split>`** (default: `var(--lr-color-overlay)`) — The `'floating'` drawer scrim's color, applied to `[part=\"backdrop\"]`."},{"name":"--lr-node-fill","description":"**`<lr-graph>`** (default: `var(--lr-color-brand)`) — Default node fill, overridden per-node by `LyraGraphNode.color`."},{"name":"--lr-node-palette-search-font-size","description":"**`<lr-node-palette>`** (default: `inherit`) — Text size of the search field."},{"name":"--lr-node-palette-search-min-height","description":"**`<lr-node-palette>`** (default: `var(--lr-icon-button-size)`) — Minimum row height of the search field, for matching it to a themed search field of a chosen density tier. Point it at `--lr-form-control-height-l` (or any tier of that ladder) to line this field up with the rest of an application's controls. It can only raise the height: the shared tappable-target minimum stays underneath it, so no tier can shrink the field past the WCAG floor."},{"name":"--lr-node-palette-search-padding-block","description":"**`<lr-node-palette>`** (default: `var(--lr-space-xs)`) — Block gutter of the search field."},{"name":"--lr-node-palette-search-padding-inline","description":"**`<lr-node-palette>`** (default: `var(--lr-space-s)`) — Leading gutter of the search field. The trailing gutter is reserved for the overlaid clear button."},{"name":"--lr-node-palette-search-radius","description":"**`<lr-node-palette>`** (default: `var(--lr-radius)`) — Corner radius of the search field."},{"name":"--lr-notebook-viewer-active-bg","description":"**`<lr-notebook-viewer>`** (default: `var(--lr-color-brand-quiet)`) — Background of the `[part=\"cell\"]` currently targeted by an anchor or the active search match."},{"name":"--lr-notebook-viewer-highlight-accent-background","description":"**`<lr-notebook-viewer>`** (default: `var(--lr-color-brand-quiet)`) — Background of an `accent`-tone (the default) highlighted cell."},{"name":"--lr-notebook-viewer-highlight-active-outline","description":"**`<lr-notebook-viewer>`** (default: `var(--lr-focus-ring-color)`) — Outline of the highlighted cell whose highlight `id` equals `activeHighlightId`."},{"name":"--lr-notebook-viewer-highlight-danger-background","description":"**`<lr-notebook-viewer>`** (default: `var(--lr-color-danger-quiet)`) — Background of a `danger`-tone highlighted cell."},{"name":"--lr-notebook-viewer-highlight-neutral-background","description":"**`<lr-notebook-viewer>`** (default: `var(--lr-color-surface-raised)`) — Background of a `neutral`-tone highlighted cell."},{"name":"--lr-notebook-viewer-highlight-success-background","description":"**`<lr-notebook-viewer>`** (default: `var(--lr-color-success-quiet)`) — Background of a `success`-tone highlighted cell."},{"name":"--lr-notebook-viewer-highlight-warning-background","description":"**`<lr-notebook-viewer>`** (default: `var(--lr-color-warning-quiet)`) — Background of a `warning`-tone highlighted cell."},{"name":"--lr-notebook-viewer-max-height","description":"**`<lr-notebook-viewer>`** (default: `none`) — Maximum block size of the scrollable body before it scrolls internally. Also settable via the `max-height` property."},{"name":"--lr-opacity-disabled","description":"**Shared design token** — Canonical shared component token for opacity disabled. Reads `--lr-theme-opacity-disabled`."},{"name":"--lr-opacity-muted","description":"**Shared design token** — Canonical shared component token for opacity muted. Reads `--lr-theme-opacity-muted`."},{"name":"--lr-option-active-bg","description":"**`<lr-option>`** (default: `color-mix(in oklab, var(--lr-option-hover-bg, var(--lr-color-brand-quiet)), var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Pressed background."},{"name":"--lr-option-checked-icon-color","description":"**`<lr-option>`** (default: `var(--lr-color-brand)`) — Selected checkmark color."},{"name":"--lr-option-current-bg","description":"**`<lr-option>`** (default: `var(--lr-color-brand-quiet)`) — Keyboard-current background."},{"name":"--lr-option-current-color","description":"**`<lr-option>`** (default: `var(--current-text-color, var(--lr-color-text))`) — Keyboard-current text color; the upstream `--current-text-color` remains its fallback."},{"name":"--lr-option-hover-bg","description":"**`<lr-option>`** (default: `var(--lr-color-brand-quiet)`) — Hover background."},{"name":"--lr-option-selected-font-weight","description":"**`<lr-option>`** (default: `var(--lr-font-weight-semibold)`) — Selected label weight."},{"name":"--lr-otp-input-active-border-color","description":"**`<lr-otp-input>`** (default: `var(--lr-focus-ring-color)`) — Active segment border."},{"name":"--lr-otp-input-active-ring-color","description":"**`<lr-otp-input>`** (default: `var(--lr-focus-ring-color)`) — Active segment outer ring."},{"name":"--lr-otp-input-invalid-border-color","description":"**`<lr-otp-input>`** (default: `var(--lr-color-danger)`) — Invalid segment border."},{"name":"--lr-otp-input-mask-char","description":"**`<lr-otp-input>`** (default: `'•'`) — The glyph shown for a masked character, and for every empty segment while `with-mask` is set. Must be a quoted string, because it is used as CSS `content`."},{"name":"--lr-otp-input-segment-border-color","description":"**`<lr-otp-input>`** (default: `var(--lr-color-border)`) — Border color of each segment."},{"name":"--lr-otp-input-segment-fill","description":"**`<lr-otp-input>`** (default: `transparent`) — Background fill of each segment."},{"name":"--lr-otp-input-segment-radius","description":"**`<lr-otp-input>`** (default: `var(--lr-form-control-radius,var(--lr-radius))`) — Corner radius of each segment."},{"name":"--lr-otp-input-segment-size","description":"**`<lr-otp-input>`** (default: `var(--lr-theme-otp-input-segment-size,2.5em)`) — Internal role token supplying the standalone segment size when `--segment-size` is unset. Element-scoped: every `lr-*` host re-declares this token from `--lr-theme-otp-input-segment-size` in the shared token layer, so an ancestor rule that sets `--lr-otp-input-segment-size` directly is reset at the first intervening `lr-*` component and never reaches this element. Set it directly on this element, or set `--lr-theme-otp-input-segment-size` on an ancestor to resize every OTP input in the subtree at once.\n\n**Shared design token** — Canonical shared component token for otp input segment size. Reads `--lr-theme-otp-input-segment-size`."},{"name":"--lr-overlay-arrow-size","description":"**`<lr-dropdown>`** — Retained Lyra arrow-size fallback.\n\n**`<lr-popover>`** — Retained Lyra fallback for `--arrow-size`."},{"name":"--lr-overlay-border","description":"**`<lr-citation-badge>`** (default: `var(--lr-color-border)`) — Shared floating-surface edge colour, on the anchored source-preview popover.\n\n**`<lr-color-picker>`** (default: `var(--lr-color-border)`) — Shared floating-surface edge colour, on the picker panel.\n\n**`<lr-combobox>`** (default: `var(--lr-color-border)`) — Shared floating-surface edge colour, on the listbox popup.\n\n**`<lr-dialog>`, `<lr-drawer>`** (default: `var(--lr-color-border)`) — Shared floating-surface edge colour, on the panel and on the header's and footer's dividing rules.\n\n**`<lr-dropdown>`** (default: `var(--lr-color-border)`) — Shared floating-surface edge colour, inherited from the popover surface.\n\n**`<lr-dropdown-item>`** — Shared floating-surface edge colour, with the same deliberate exclusion as `--lr-overlay-surface` above.\n\n**`<lr-entity-chip>`** (default: `var(--lr-color-border)`) — Shared floating-surface edge colour, on the anchored detail popover.\n\n**`<lr-export-button>`** (default: `var(--lr-color-border)`) — Shared floating-surface edge colour, on the menu popup.\n\n**`<lr-locale-picker>`, `<lr-mention-popover>`, `<lr-model-select>`, `<lr-select>`, `<lr-voice-picker>`** (default: `var(--lr-color-border)`) — Shared floating-surface edge colour, on the listbox.\n\n**`<lr-menu>`** (default: `var(--lr-color-border)`) — Shared floating-surface edge colour, on the same two surfaces. The header/footer dividing rules and a slotted `hr` are deliberately excluded: they separate content, they do not draw the surface's own edge.\n\n**`<lr-popover>`** (default: `var(--lr-color-border)`) — Shared floating-surface edge colour, on the popup and on the arrow's two outward-facing edges.\n\n**`<lr-selection-toolbar>`** (default: `var(--lr-color-border)`) — Shared floating-surface edge colour, on the toolbar.\n\n**`<lr-time-input>`** (default: `var(--lr-color-border)`) — Shared floating-surface edge colour, on the anchored picker panel.\n\n**`<lr-tool-call-chip>`** (default: `var(--lr-color-border)`) — Shared floating-surface edge colour, on the anchored detail tooltip.\n\n**`<lr-tooltip>`** — Shared floating-surface edge colour. Same deliberate exclusion as `--lr-overlay-surface` above: the bubble draws no border.\n\n**`<lr-usage-badge>`** (default: `var(--lr-color-border)`) — Shared floating-surface edge colour, on the anchored breakdown tooltip."},{"name":"--lr-overlay-max-inline-size","description":"**`<lr-dropdown>`** — Maximum inline size of the popup.\n\n**`<lr-popover>`** — Retained Lyra fallback for `--max-width`."},{"name":"--lr-overlay-radius","description":"**`<lr-citation-badge>`** (default: `var(--lr-radius)`) — Shared floating-surface corner radius, on the anchored source-preview popover.\n\n**`<lr-color-picker>`** (default: `var(--lr-radius)`) — Shared floating-surface corner radius, read by the picker panel only as the middle arm of `--lr-color-picker-radius`, which still wins when set.\n\n**`<lr-combobox>`** (default: `var(--lr-radius)`) — Shared floating-surface corner radius, on the listbox popup.\n\n**`<lr-dialog>`, `<lr-drawer>`** (default: `var(--lr-radius)`) — Shared floating-surface corner radius, on the panel and on the close button.\n\n**`<lr-dropdown>`** (default: `var(--lr-radius)`) — Shared floating-surface corner radius, inherited from the popover surface.\n\n**`<lr-dropdown-item>`** — Shared floating-surface corner radius, with the same deliberate exclusion. The row's own corners come from `--lr-menu-item-radius`.\n\n**`<lr-entity-chip>`** (default: `var(--lr-radius)`) — Shared floating-surface corner radius, on the anchored detail popover.\n\n**`<lr-export-button>`** (default: `var(--lr-radius)`) — Shared floating-surface corner radius, on the menu popup.\n\n**`<lr-locale-picker>`** (default: `var(--lr-radius)`) — Shared floating-surface corner radius, read by the listbox only as the middle arm of `--lr-locale-picker-radius`, which still wins when set.\n\n**`<lr-mention-popover>`, `<lr-select>`** (default: `var(--lr-radius)`) — Shared floating-surface corner radius, on the listbox.\n\n**`<lr-menu>`** (default: `var(--lr-radius)`) — Shared floating-surface corner radius, on the same two surfaces.\n\n**`<lr-model-select>`** (default: `var(--lr-radius)`) — Shared floating-surface corner radius, read by the listbox only as the middle arm of `--lr-model-select-radius`, which still wins when set.\n\n**`<lr-popover>`** (default: `var(--lr-radius)`) — Shared floating-surface corner radius. The arrow is deliberately excluded: its corners are already cut by its clip path.\n\n**`<lr-selection-toolbar>`** (default: `var(--lr-radius)`) — Shared floating-surface corner radius, on the toolbar.\n\n**`<lr-time-input>`** (default: `var(--lr-radius)`) — Shared floating-surface corner radius, on the anchored picker panel.\n\n**`<lr-tool-call-chip>`** (default: `var(--lr-radius)`) — Shared floating-surface corner radius, on the anchored detail tooltip.\n\n**`<lr-tooltip>`** — Shared floating-surface corner radius. Same deliberate exclusion: the bubble keeps the tighter `--lr-radius-xs` a label-sized box reads best with.\n\n**`<lr-usage-badge>`** (default: `var(--lr-radius)`) — Shared floating-surface corner radius, on the anchored breakdown tooltip.\n\n**`<lr-voice-picker>`** (default: `var(--lr-radius)`) — Shared floating-surface corner radius, read by the listbox only as the middle arm of `--lr-voice-picker-radius`, which still wins when set."},{"name":"--lr-overlay-shadow-anchored","description":"**`<lr-citation-badge>`, `<lr-color-picker>`, `<lr-entity-chip>`, `<lr-export-button>`, `<lr-mention-popover>`, `<lr-model-select>`, `<lr-selection-toolbar>`, `<lr-time-input>`, `<lr-tool-call-chip>`, `<lr-usage-badge>`, `<lr-voice-picker>`** (default: `var(--lr-shadow-m)`) — Elevation of the anchored surface.\n\n**`<lr-combobox>`** (default: `var(--lr-shadow-m)`) — Elevation of the anchored listbox popup.\n\n**`<lr-dropdown>`** (default: `var(--lr-shadow-m)`) — Elevation of an anchored, positioner-placed overlay, inherited from the popover surface.\n\n**`<lr-locale-picker>`, `<lr-select>`** (default: `var(--lr-shadow-m)`) — Elevation of the anchored listbox.\n\n**`<lr-menu>`** (default: `var(--lr-shadow-m)`) — Elevation of the anchored submenu surface.\n\n**`<lr-popover>`** (default: `var(--lr-shadow-m)`) — Elevation of an anchored, positioner-placed overlay. A separate tier from `--lr-overlay-shadow-modal`, so raising popups never raises dialogs."},{"name":"--lr-overlay-shadow-modal","description":"**`<lr-dialog>`, `<lr-drawer>`** (default: `var(--lr-shadow-xl)`) — Elevation of a modal panel. A separate tier from `--lr-overlay-shadow-anchored`, so raising popups never raises dialogs."},{"name":"--lr-overlay-surface","description":"**`<lr-citation-badge>`** (default: `var(--lr-color-surface-overlay)`) — Shared floating-surface fill, on the anchored source-preview popover.\n\n**`<lr-color-picker>`** (default: `var(--lr-color-surface-overlay)`) — Shared floating-surface fill, on the picker panel.\n\n**`<lr-combobox>`** (default: `var(--lr-color-surface-overlay)`) — Shared floating-surface fill, on the listbox popup. This is the public arm the popup never had: retinting it no longer means retinting the page surface every card and input reads.\n\n**`<lr-dialog>`, `<lr-drawer>`** (default: `var(--lr-color-surface-overlay)`) — Shared floating-surface fill, on the panel. The same family every anchored popup now reads, so one declaration retints the dialog and the popups opened from it together.\n\n**`<lr-dropdown>`** (default: `var(--lr-color-surface-overlay)`) — Shared floating-surface fill, inherited from the popover surface.\n\n**`<lr-dropdown-item>`** — Shared floating-surface fill. Advertised here because this tag shares a stylesheet directory with `lr-menu`, whose surface reads it; a dropdown item is a row inside that surface and paints no surface of its own, so setting it here changes nothing.\n\n**`<lr-entity-chip>`** (default: `var(--lr-color-surface-overlay)`) — Shared floating-surface fill, on the anchored detail popover.\n\n**`<lr-export-button>`** (default: `var(--lr-color-surface-overlay)`) — Shared floating-surface fill, on the menu popup.\n\n**`<lr-locale-picker>`, `<lr-mention-popover>`, `<lr-model-select>`, `<lr-voice-picker>`** (default: `var(--lr-color-surface-overlay)`) — Shared floating-surface fill, on the listbox.\n\n**`<lr-menu>`** (default: `var(--lr-color-surface-overlay)`) — Shared floating-surface fill, on the standalone menu surface and on a submenu's own surface. A contained menu (inside `lr-dropdown`) paints no surface of its own, so it is unaffected.\n\n**`<lr-popover>`** (default: `var(--lr-color-surface-overlay)`) — Shared floating-surface fill, read by the popup and by its arrow. One declaration on any ancestor retints every overlay in that subtree without touching the page, card and control surfaces behind them.\n\n**`<lr-select>`** (default: `var(--lr-color-surface-overlay)`) — Shared floating-surface fill, on the listbox. The listbox is a floating surface, so it retints with every other popup rather than with the trigger it drops from.\n\n**`<lr-selection-toolbar>`** (default: `var(--lr-color-surface-overlay)`) — Shared floating-surface fill, on the toolbar.\n\n**`<lr-time-input>`** (default: `var(--lr-color-surface-raised)`) — Shared floating-surface fill, on the anchored picker panel. The family's own default is `var(--lr-color-surface-overlay)`; this panel deliberately keeps the raised tone as its unset value so it stays separated from the field it drops from, and it never read as a hole in dark mode.\n\n**`<lr-tool-call-chip>`** (default: `var(--lr-color-surface-overlay)`) — Shared floating-surface fill, on the anchored detail tooltip.\n\n**`<lr-tooltip>`** — Shared floating-surface fill. Advertised here because this tag's rules live in the stylesheet module `lr-popover` also composes; a tooltip bubble is a high-contrast label, not a panel, so it paints from `--lr-tooltip-background` and is deliberately outside the overlay-surface family.\n\n**`<lr-usage-badge>`** (default: `var(--lr-color-surface-overlay)`) — Shared floating-surface fill, on the anchored breakdown tooltip."},{"name":"--lr-page-aside-width","description":"**`<lr-page>`** (default: `auto`) — Desktop aside column width."},{"name":"--lr-page-banner-height","description":"**`<lr-page>`** (default: `0px`) — Minimum banner height and sticky offset."},{"name":"--lr-page-header-height","description":"**`<lr-page>`** (default: `0px`) — Minimum header height and sticky offset."},{"name":"--lr-page-main-width","description":"**`<lr-page>`** (default: `1fr`) — Desktop main column width."},{"name":"--lr-page-menu-width","description":"**`<lr-page>`** (default: `auto`) — Desktop menu column width."},{"name":"--lr-page-navigation-backdrop-bg","description":"**`<lr-page>`** (default: `var(--lr-color-overlay)`) — Background of the open mobile navigation backdrop."},{"name":"--lr-page-navigation-drawer-bg","description":"**`<lr-page>`** (default: `var(--lr-color-surface-overlay)`) — Background of the mobile navigation drawer."},{"name":"--lr-page-navigation-drawer-shadow","description":"**`<lr-page>`** (default: `var(--lr-shadow-l)`) — Shadow of the mobile navigation drawer."},{"name":"--lr-page-navigation-toggle-active-bg","description":"**`<lr-page>`** (default: `color-mix(in oklab, var(--lr-color-brand-quiet), var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Background of a pressed default or slotted navigation toggle."},{"name":"--lr-page-navigation-toggle-active-color","description":"**`<lr-page>`** (default: `var(--lr-color-brand)`) — Text color of a pressed default or slotted navigation toggle."},{"name":"--lr-page-navigation-toggle-hover-bg","description":"**`<lr-page>`** (default: `var(--lr-color-brand-quiet)`) — Background of a hovered default or slotted navigation toggle."},{"name":"--lr-page-navigation-toggle-hover-color","description":"**`<lr-page>`** (default: `var(--lr-color-brand)`) — Text color of a hovered default or slotted navigation toggle."},{"name":"--lr-page-rail-current-bg","description":"**`<lr-page-rail>`** (default: `var(--lr-color-brand-quiet)`) — Background of the `[part=\"page-current\"]` button for the current `page`."},{"name":"--lr-page-rail-heat-accent-color","description":"**`<lr-page-rail>`** (default: `var(--lr-color-brand)`) — Background of an accent-tone (the default tone) `[part=\"heat-dot\"]` marker."},{"name":"--lr-page-rail-heat-danger-color","description":"**`<lr-page-rail>`** (default: `var(--lr-color-danger)`) — Background of a danger-tone `[part=\"heat-dot-danger\"]` marker."},{"name":"--lr-page-rail-heat-neutral-color","description":"**`<lr-page-rail>`** (default: `var(--lr-color-text-quiet)`) — Background of a neutral-tone `[part=\"heat-dot-neutral\"]` marker."},{"name":"--lr-page-rail-heat-success-color","description":"**`<lr-page-rail>`** (default: `var(--lr-color-success)`) — Background of a success-tone `[part=\"heat-dot-success\"]` marker."},{"name":"--lr-page-rail-heat-warning-color","description":"**`<lr-page-rail>`** (default: `var(--lr-color-warning)`) — Background of a warning-tone `[part=\"heat-dot-warning\"]` marker."},{"name":"--lr-page-rail-height","description":"**`<lr-page-rail>`** (default: `var(--lr-size-24rem)`) — Block size of the virtualized rail."},{"name":"--lr-page-skip-to-content-active-bg","description":"**`<lr-page>`** (default: `color-mix(in oklab, var(--lr-color-brand-quiet), var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Background of the pressed skip link."},{"name":"--lr-page-skip-to-content-active-color","description":"**`<lr-page>`** (default: `var(--lr-color-brand)`) — Text color of the pressed skip link."},{"name":"--lr-page-skip-to-content-hover-bg","description":"**`<lr-page>`** (default: `var(--lr-color-brand-quiet)`) — Background of the hovered skip link."},{"name":"--lr-page-skip-to-content-hover-color","description":"**`<lr-page>`** (default: `var(--lr-color-brand)`) — Text color of the hovered skip link."},{"name":"--lr-page-subheader-height","description":"**`<lr-page>`** (default: `0px`) — Minimum subheader height and sticky offset. Interaction-state properties below are resolved as inline fallbacks, so setting one on the Page or any ancestor themes only its named target without replacing shared design tokens."},{"name":"--lr-pagination-active-bg","description":"**`<lr-pagination>`** — Ordinary control pressed background; defaults to the current quiet-brand active mix."},{"name":"--lr-pagination-active-border-color","description":"**`<lr-pagination>`** (default: `var(--lr-color-brand)`) — Ordinary control pressed border color."},{"name":"--lr-pagination-base-gap","description":"**`<lr-pagination>`** (default: `var(--lr-space-m)`) — Gap between the summary and controls."},{"name":"--lr-pagination-control-bg","description":"**`<lr-pagination>`** — Resting background of every control; defaults from the `appearance` variant."},{"name":"--lr-pagination-control-border-color","description":"**`<lr-pagination>`** — Resting border color of every control; defaults from the `appearance` variant."},{"name":"--lr-pagination-control-color","description":"**`<lr-pagination>`** (default: `var(--lr-color-text)`) — Resting control foreground."},{"name":"--lr-pagination-control-padding","description":"**`<lr-pagination>`** (default: `var(--lr-space-xs)`) — Inner padding of the nav buttons and the page input. Uniform across every `size` (the control footprint is fixed by `--lr-pagination-control-size`, so this only adjusts the icon/digit inset)."},{"name":"--lr-pagination-control-radius","description":"**`<lr-pagination>`** (default: `var(--lr-radius)`) — Border radius of navigation buttons and the page input."},{"name":"--lr-pagination-control-size","description":"**`<lr-pagination>`** — Control inline/block size; defaults from the `size` variant."},{"name":"--lr-pagination-controls-gap","description":"**`<lr-pagination>`** (default: `var(--lr-space-xs)`) — Gap between the navigation controls and the numbered-page list or compact page field."},{"name":"--lr-pagination-current-active-bg","description":"**`<lr-pagination>`** — Current-page pressed background; defaults to the current brand active mix."},{"name":"--lr-pagination-current-active-border-color","description":"**`<lr-pagination>`** (default: `transparent`) — Current-page pressed border color."},{"name":"--lr-pagination-current-bg","description":"**`<lr-pagination>`** (default: `var(--lr-color-brand)`) — Current-page background."},{"name":"--lr-pagination-current-border-color","description":"**`<lr-pagination>`** (default: `transparent`) — Current-page border color."},{"name":"--lr-pagination-current-color","description":"**`<lr-pagination>`** (default: `var(--lr-color-on-brand)`) — Current-page foreground."},{"name":"--lr-pagination-current-hover-bg","description":"**`<lr-pagination>`** (default: `var(--lr-color-brand)`) — Current-page hover background."},{"name":"--lr-pagination-current-hover-border-color","description":"**`<lr-pagination>`** (default: `transparent`) — Current-page hover border color."},{"name":"--lr-pagination-font-size","description":"**`<lr-pagination>`** — Control font size; defaults from the `size` variant."},{"name":"--lr-pagination-hover-bg","description":"**`<lr-pagination>`** (default: `var(--lr-color-brand-quiet)`) — Ordinary control hover background."},{"name":"--lr-pagination-hover-border-color","description":"**`<lr-pagination>`** (default: `var(--lr-color-brand)`) — Ordinary control hover border color."},{"name":"--lr-pagination-invalid-border","description":"**`<lr-pagination>`** (default: `var(--lr-color-danger)`) — Border color of `[part=\"page-input\"]` while the typed page is out of range (`aria-invalid=\"true\"`)."},{"name":"--lr-pagination-pages-gap","description":"**`<lr-pagination>`** (default: `var(--lr-space-xs)`) — Gap between numbered page controls."},{"name":"--lr-pan-zoom-min-block-size","description":"**`<lr-pan-zoom>`** (default: `var(--lr-size-10rem)`) — Minimum viewport block size."},{"name":"--lr-pan-zoom-zoom","description":"**`<lr-pan-zoom>`** (default: `1`) — Read-only scale written from `zoom`; set the property instead."},{"name":"--lr-pdf-viewer-height","description":"**`<lr-pdf-viewer>`** (default: `var(--lr-size-24rem)`) — Block size of the virtualized page list."},{"name":"--lr-pdf-viewer-search-match-active-bg","description":"**`<lr-pdf-viewer>`** (default: `var(--lr-color-warning)`) — Background of the currently active search match."},{"name":"--lr-pdf-viewer-search-match-bg","description":"**`<lr-pdf-viewer>`** (default: `var(--lr-color-warning-quiet)`) — Background of a painted, non-active search match."},{"name":"--lr-pdf-viewer-text-selection-bg","description":"**`<lr-pdf-viewer>`** (default: `var(--lr-color-brand-quiet)`) — Background of a native text selection over a `text-span`, independent of the shared `--lr-color-brand-quiet` token."},{"name":"--lr-pdf-viewer-toolbar-bg","description":"**`<lr-pdf-viewer>`** (default: `var(--lr-color-brand-quiet)`) — Background of the `toolbar` part, independent of the shared `--lr-color-brand-quiet` token."},{"name":"--lr-pdf-viewer-toolbar-button-hover-bg","description":"**`<lr-pdf-viewer>`** (default: `var(--lr-color-surface)`) — Hover fill of the toolbar buttons. Defaults to the surface fill rather than the toolbar's own tint so the hover state is actually visible against it. Also settable via the `max-height` property."},{"name":"--lr-phone-input-border-color","description":"**`<lr-phone-input>`** (default: `var(--lr-color-border)`) — Resting border color of the input row. The invalid and focused states keep their own hooks and still win over it."},{"name":"--lr-phone-input-control-height","description":"**`<lr-phone-input>`** — Exact input-wrapper height. Unset by default, which leaves `--lr-phone-input-control-min-height` as a floor only; set it to a length to both floor and cap the row (e.g. to pixel-match a sibling field in the same toolbar row). Because it is never declared by the component itself, it can be set from an ancestor or an outer-tree rule as well as inline on the element."},{"name":"--lr-phone-input-control-min-height","description":"**`<lr-phone-input>`** (default: `var(--lr-form-control-height)`) — Input-wrapper block-size floor. Reads the shared form-control height ladder, so retuning `--lr-theme-form-control-height-*` moves this control and every sibling field together."},{"name":"--lr-phone-input-country-hover-bg","description":"**`<lr-phone-input>`** (default: `var(--lr-color-brand-quiet)`) — Country trigger hover background."},{"name":"--lr-phone-input-fill","description":"**`<lr-phone-input>`** (default: `var(--lr-color-surface)`) — Resting background of the input row."},{"name":"--lr-phone-input-flag-size","description":"**`<lr-phone-input>`** — Selected flag size, scaled by `size`."},{"name":"--lr-phone-input-focus-border-color","description":"**`<lr-phone-input>`** (default: `var(--lr-color-brand)`) — Focused row border color."},{"name":"--lr-phone-input-font-size","description":"**`<lr-phone-input>`** — Input/flag/country-code/calling-code font size, scaled by `size`."},{"name":"--lr-phone-input-gap","description":"**`<lr-phone-input>`** (default: `var(--lr-space-xs)`) — Country-trigger child gap."},{"name":"--lr-phone-input-glyph-size","description":"**`<lr-phone-input>`** — Country selector glyph size, scaled by `size`."},{"name":"--lr-phone-input-invalid-border-color","description":"**`<lr-phone-input>`** (default: `var(--lr-color-danger)`) — Invalid row border color."},{"name":"--lr-phone-input-padding-block","description":"**`<lr-phone-input>`** — Input block-padding, scaled by `size` through the shared form-control ladder."},{"name":"--lr-phone-input-radius","description":"**`<lr-phone-input>`** (default: `var(--lr-radius)`) — Input-wrapper corner radius, shared with the country trigger's leading corners. The `pill` attribute swaps it for `--lr-radius-pill`."},{"name":"--lr-policy-summary-count-allow-color","description":"**`<lr-policy-summary>`** (default: `var(--lr-color-success)`) — Text color of the `allow` count."},{"name":"--lr-policy-summary-count-deny-color","description":"**`<lr-policy-summary>`** (default: `var(--lr-color-danger)`) — Text color of the `deny` count."},{"name":"--lr-policy-summary-count-needs-review-color","description":"**`<lr-policy-summary>`** (default: `var(--lr-color-warning)`) — Text color of the `needs-review` count. Restyling a state count otherwise requires overriding the library-wide status tokens, since `::part(count)[data-state]` is invalid CSS."},{"name":"--lr-poll-status-due-bg","description":"**`<lr-poll-status>`** (default: `var(--lr-color-success)`) — Background of `indicator` while `data-due` is set, without repainting every other component that reuses the shared success token."},{"name":"--lr-poll-status-pause-active-bg","description":"**`<lr-poll-status>`** — `pause-button` pressed background; defaults to the former brand-quiet active mix."},{"name":"--lr-poll-status-pause-active-color","description":"**`<lr-poll-status>`** (default: `var(--lr-color-brand)`) — `pause-button` pressed foreground."},{"name":"--lr-poll-status-pause-hover-bg","description":"**`<lr-poll-status>`** (default: `var(--lr-color-brand-quiet)`) — `pause-button` hover background."},{"name":"--lr-poll-status-pause-hover-color","description":"**`<lr-poll-status>`** (default: `var(--lr-color-brand)`) — `pause-button` hover foreground."},{"name":"--lr-popover-viewport-clamp","description":"**Shared design token** — Canonical shared component token for popover viewport clamp. Reads `--lr-theme-popover-viewport-clamp`."},{"name":"--lr-popup-arrow-size","description":"**`<lr-popup>`** — Retained Lyra fallback for `--arrow-size`."},{"name":"--lr-positioning-strategy","description":"**`<lr-app-rail-item>`** — Cascading `absolute`/`fixed` override for the icon-only flyout tooltip's `fixed` default, read from computed style when it is (re)positioned. Set it once on `:root`, a theme, or one clipping ancestor to change every unset rail item beneath it; an unrecognized value falls back to `fixed`.\n\n**`<lr-citation-badge>`** — Cascading `absolute`/`fixed` override for the preview popover's `fixed` default, read from computed style when it is (re)positioned. Set it once on `:root`, a theme, or one clipping ancestor to change every unset citation badge beneath it; an unrecognized value falls back to `fixed`.\n\n**`<lr-color-picker>`** — Cascading `absolute`/`fixed` override for {@link positioningStrategy}/`hoist`, read from computed style when the panel is (re)positioned. Set it once on `:root`, a theme, or one clipping ancestor to change every unset color picker beneath it instead of authoring `positioning-strategy`/`hoist` on each instance; an explicit value on the instance always wins over it.\n\n**`<lr-combobox>`** — Cascading `absolute`/`fixed` override for {@link positioningStrategy}, read from computed style when the listbox is positioned. Set it once on `:root`, a theme, or one clipping ancestor to change every unset combobox beneath it instead of authoring `positioning-strategy` on each instance; an explicit value on the instance always wins over it.\n\n**`<lr-date-input>`** — Cascading `absolute`/`fixed` override for the calendar popup's `fixed` default, read from computed style when it is (re)positioned. Set it once on `:root`, a theme, or one clipping ancestor to change every unset date input beneath it; an unrecognized value falls back to `fixed`.\n\n**`<lr-dropdown>`** — Cascading `absolute`/`fixed` override for {@link positioningStrategy}/`hoist`, inherited from the popover surface. An explicit `positioning-strategy`/`hoist` on the instance always wins over it.\n\n**`<lr-entity-chip>`** — Cascading `absolute`/`fixed` override for the preview popover's `fixed` default, read from computed style when it is (re)positioned. Set it once on `:root`, a theme, or one clipping ancestor to change every unset entity chip beneath it; an unrecognized value falls back to `fixed`.\n\n**`<lr-export-button>`** — Cascading `absolute`/`fixed` override for the format menu's `fixed` default, read from computed style when it is (re)positioned. Set it once on `:root`, a theme, or one clipping ancestor to change every unset export button beneath it; an unrecognized value falls back to `fixed`.\n\n**`<lr-locale-picker>`** — Cascading `absolute`/`fixed` override for the listbox's `fixed` default, read from computed style when it is (re)positioned. Set it once on `:root`, a theme, or one clipping ancestor to change every unset locale picker beneath it; an unrecognized value falls back to `fixed`.\n\n**`<lr-mention-popover>`** — Cascading `absolute`/`fixed` override for the listbox's `fixed` default, read from computed style when it is (re)positioned. Set it once on `:root`, a theme, or one clipping ancestor to change every unset mention popover beneath it; an unrecognized value falls back to `fixed`.\n\n**`<lr-menu>`** — Cascading `absolute`/`fixed` override for the private submenu surface's `fixed` default, read from computed style when a submenu is (re)positioned. Set it once on `:root`, a theme, or one clipping ancestor to change every unset submenu beneath it; an unrecognized value falls back to `fixed`.\n\n**`<lr-popover>`** — Cascading `absolute`/`fixed` override for {@link positioningStrategy}, read from computed style when the popup is (re)positioned. Set it once on `:root`, a theme, or one clipping ancestor to change every unset overlay beneath it without authoring `positioning-strategy`/`hoist` on each instance; an explicit value on the instance always wins over it.\n\n**`<lr-select>`** — Cascading `absolute`/`fixed` override for {@link positioningStrategy}/`hoist`, read from computed style when the listbox is (re)positioned. Set it once on `:root`, a theme, or one clipping ancestor to change every unset select beneath it instead of authoring `positioning-strategy`/`hoist` on each instance; an explicit value on the instance always wins over it.\n\n**`<lr-time-input>`** — Cascading `absolute`/`fixed` override for the column picker's `fixed` default, read from computed style when it is (re)positioned. Set it once on `:root`, a theme, or one clipping ancestor to change every unset time input beneath it; an unrecognized value falls back to `fixed`.\n\n**`<lr-tool-call-chip>`** — Cascading `absolute`/`fixed` override for the detail tooltip's `fixed` default, read from computed style when it is (re)positioned. Set it once on `:root`, a theme, or one clipping ancestor to change every unset tool call chip beneath it; an unrecognized value falls back to `fixed`.\n\n**`<lr-tooltip>`** — Cascading `absolute`/`fixed` override for {@link positioningStrategy}/`hoist`, read from computed style when the bubble is (re)positioned. Set it once on `:root`, a theme, or one clipping ancestor to change every unset tooltip beneath it instead of authoring `positioning-strategy`/`hoist` on each instance; an explicit value on the instance always wins over it.\n\n**`<lr-tour>`** — Cascading `absolute`/`fixed` override for the step popover's `fixed` default, read from computed style when a step is (re)positioned. Set it once on `:root`, a theme, or one clipping ancestor to change every unset tour beneath it; an unrecognized value falls back to `fixed`.\n\n**`<lr-usage-badge>`** — Cascading `absolute`/`fixed` override for the breakdown tooltip's `fixed` default, read from computed style when it is (re)positioned. Set it once on `:root`, a theme, or one clipping ancestor to change every unset usage badge beneath it; an unrecognized value falls back to `fixed`."},{"name":"--lr-pptx-viewer-max-height","description":"**`<lr-pptx-viewer>`** (default: `none`) — Maximum block size of the scrollable renderer output container before it scrolls internally. Also settable via the `max-height` property."},{"name":"--lr-progress-duration","description":"**`<lr-progress-bar>`** (default: `var(--lr-transition-ambient)`) — Indeterminate sweep timing.\n\n**`<lr-progress-ring>`** (default: `var(--lr-transition-ambient)`) — Indeterminate rotation timing."},{"name":"--lr-progress-indicator-color","description":"**`<lr-progress-bar>`** (default: `var(--lr-progress-indicator-variant-color)`) — Indicator color, overriding the variant palette below."},{"name":"--lr-progress-indicator-variant-color","description":"**`<lr-progress-bar>`** (default: `var(--lr-color-fill-loud,var(--lr-color-brand))`) — Palette slot: the active `variant`'s loud fill from the shared semantic grid. Feeds `--lr-progress-indicator-color` above unless that (or the upstream `--indicator-color` alias) is itself set."},{"name":"--lr-progress-label-color","description":"**`<lr-progress-bar>`** (default: `var(--lr-color-text)`) — Label color."},{"name":"--lr-progress-ring-indicator-color","description":"**`<lr-progress-ring>`** (default: `var(--lr-progress-ring-indicator-variant-color)`) — Indicator stroke color, overriding the variant palette below."},{"name":"--lr-progress-ring-indicator-transition-duration","description":"**`<lr-progress-ring>`** (default: `var(--lr-transition-base)`) — Determinate indicator transition."},{"name":"--lr-progress-ring-indicator-variant-color","description":"**`<lr-progress-ring>`** (default: `var(--lr-color-fill-loud,var(--lr-color-brand))`) — Palette slot: the active `variant`'s loud fill from the shared semantic grid. Feeds `--lr-progress-ring-indicator-color` above unless that (or the upstream `--indicator-color` alias) is itself set."},{"name":"--lr-progress-ring-indicator-width","description":"**`<lr-progress-ring>`** (default: `var(--lr-progress-ring-track-width)`) — Indicator stroke width."},{"name":"--lr-progress-ring-size","description":"**`<lr-progress-ring>`** (default: `var(--size,var(--_lr-progress-ring-size))`) — Outer diameter of the ring. The private fallback steps with `size` across the shared six-step ladder (`1.25rem` at `2xs` up to `3.5rem` at `xl`, `2.5rem` unchanged at the `m` default); an inherited or direct value here (or the upstream `--size` alias) still wins outright over every tier."},{"name":"--lr-progress-ring-track-color","description":"**`<lr-progress-ring>`** (default: `var(--lr-color-brand-quiet)`) — Track stroke color."},{"name":"--lr-progress-ring-track-width","description":"**`<lr-progress-ring>`** (default: `var(--lr-theme-progress-ring-track-width,var(--lr-size-4px))`) — Track stroke width, `4px` by default. Bridges its own dedicated `--lr-theme-progress-ring-track-width` theme input rather than the widely-shared `--lr-theme-border-width-thick` (fed to the `--lr-border-width-thick` alias): `theme.css` declares that shared input at `3px` -- its correct default for the many surfaces that genuinely want it -- and bridging it directly here would have let importing `theme.css` alone silently repaint this ring's stroke to `3px` even with no consumer override. Set `--lr-theme-progress-ring-track-width` on `:root` or any ancestor to retune this ring specifically; it stays unset (and this default applies) whether or not `theme.css` is imported."},{"name":"--lr-progress-track-color","description":"**`<lr-progress-bar>`** (default: `var(--lr-color-brand-quiet)`) — Track color."},{"name":"--lr-progress-track-height","description":"**`<lr-progress-bar>`** (default: `var(--lr-progress-height,var(--_lr-progress-track-height))`) — Block size of the progress track. The innermost fallback steps with `size` across the shared six-step ladder (`0.25rem` at `2xs` up to `1.5rem` at `xl`, `1rem` unchanged at the `m` default); an inherited or direct value here still wins outright over every tier."},{"name":"--lr-prompt-input-control-width","description":"**`<lr-prompt-input>`** (default: `--lr-size-12rem`) — Preferred width of each generated model, voice, and source control before wrapping."},{"name":"--lr-prompt-studio-field-hover-border","description":"**`<lr-prompt-studio>`** (default: `var(--lr-color-brand)`) — Enabled field hover border."},{"name":"--lr-prompt-studio-version-selected-bg","description":"**`<lr-prompt-studio>`** (default: `var(--lr-color-brand-quiet)`) — Selected version background."},{"name":"--lr-prompt-studio-version-selected-border","description":"**`<lr-prompt-studio>`** (default: `var(--lr-color-brand)`) — Selected version border."},{"name":"--lr-prompt-studio-version-selected-color","description":"**`<lr-prompt-studio>`** (default: `var(--lr-color-text)`) — Selected version foreground."},{"name":"--lr-prompt-studio-version-selected-hover-bg","description":"**`<lr-prompt-studio>`** (default: `color-mix(in oklab, var(--lr-color-brand-quiet), var(--lr-color-mix-partner) var(--lr-color-mix-hover))`) — Selected version hover background."},{"name":"--lr-provenance-panel-entity-justify","description":"**`<lr-provenance-panel>`** (default: `flex-start`) — Main-axis packing of the entity-chip row. `center` centers every line, the wrapped final one included."},{"name":"--lr-push-to-talk-pulse-recording-border-color","description":"**`<lr-push-to-talk>`** (default: `var(--lr-push-to-talk-recording-color, var(--lr-color-danger))`) — Recording pulse-ring border color."},{"name":"--lr-push-to-talk-recording-color","description":"**`<lr-push-to-talk>`** (default: `var(--lr-color-danger)`) — Established aggregate fallback for the recording trigger border, trigger foreground, and pulse border. The three more-specific recording properties below win independently when set."},{"name":"--lr-push-to-talk-size","description":"**`<lr-push-to-talk>`** (default: `var(--lr-size-3rem)`) — Preferred inline and block size of the circular `trigger` button; `--lr-icon-button-size` remains its minimum hit-area floor."},{"name":"--lr-push-to-talk-trigger-recording-border-color","description":"**`<lr-push-to-talk>`** (default: `var(--lr-push-to-talk-recording-color, var(--lr-color-danger))`) — Trigger border color while recording."},{"name":"--lr-push-to-talk-trigger-recording-color","description":"**`<lr-push-to-talk>`** (default: `var(--lr-push-to-talk-recording-color, var(--lr-color-danger))`) — Trigger foreground, including the default mic glyph, while recording."},{"name":"--lr-qr-code-background","description":"**`<lr-qr-code>`** — Optional alias for host `background-color`, used by the canvas background."},{"name":"--lr-qr-code-fill","description":"**`<lr-qr-code>`** — Optional alias for host `color`, used by foreground modules."},{"name":"--lr-radio-active-border-color","description":"**`<lr-radio>`, `<lr-radio-button>`** (default: `var(--lr-radio-hover-border-color)`) — Indicator border while the interactive row is pressed."},{"name":"--lr-radio-active-ring-color","description":"**`<lr-radio>`, `<lr-radio-button>`** (default: `var(--lr-color-brand-quiet)`) — Indicator ring while the interactive row is pressed."},{"name":"--lr-radio-button-active-bg","description":"**`<lr-radio-button>`** (default: `color-mix(...)`) — Unchecked button background while pressed."},{"name":"--lr-radio-button-active-border-color","description":"**`<lr-radio-button>`** (default: `var(--lr-radio-button-hover-border-color)`) — Unchecked button border while pressed."},{"name":"--lr-radio-button-checked-active-bg","description":"**`<lr-radio-button>`** (default: `color-mix(...)`) — Checked button background while pressed."},{"name":"--lr-radio-button-checked-active-border-color","description":"**`<lr-radio-button>`** (default: `var(--lr-radio-button-checked-hover-border-color)`) — Checked button border while pressed."},{"name":"--lr-radio-button-checked-bg","description":"**`<lr-radio-button>`** (default: `var(--lr-color-brand)`) — Checked button background."},{"name":"--lr-radio-button-checked-border-color","description":"**`<lr-radio-button>`** (default: `var(--lr-color-brand)`) — Checked button border."},{"name":"--lr-radio-button-checked-color","description":"**`<lr-radio-button>`** (default: `var(--lr-color-on-brand)`) — Checked button text color."},{"name":"--lr-radio-button-checked-hover-bg","description":"**`<lr-radio-button>`** (default: `color-mix(...)`) — Checked button background while hovered."},{"name":"--lr-radio-button-checked-hover-border-color","description":"**`<lr-radio-button>`** (default: `var(--lr-radio-button-checked-border-color)`) — Checked button border while hovered."},{"name":"--lr-radio-button-gap","description":"**`<lr-radio>`** (default: `var(--lr-space-xs)`) — Gap between the present start/prefix, label, and end/suffix wrappers in `appearance=\"button\"`.\n\n**`<lr-radio-button>`** (default: `var(--lr-space-xs)`) — Gap between the start/prefix wrapper, label, and end/suffix wrapper in both `<lr-radio-button>` and `<lr-radio appearance=\"button\">`."},{"name":"--lr-radio-button-hover-bg","description":"**`<lr-radio-button>`** (default: `var(--lr-color-brand-quiet)`) — Unchecked button background while hovered."},{"name":"--lr-radio-button-hover-border-color","description":"**`<lr-radio-button>`** (default: `var(--lr-color-brand)`) — Unchecked button border while hovered."},{"name":"--lr-radio-checked-border-color","description":"**`<lr-radio>`, `<lr-radio-button>`** (default: `var(--lr-color-brand)`) — Border color of `[part='circle']` while `checked`. Retint just this control's checked ring without touching the shared `--lr-color-brand` token every other component also reads."},{"name":"--lr-radio-checked-dot-color","description":"**`<lr-radio>`, `<lr-radio-button>`** (default: `var(--lr-color-brand)`) — Background of `[part='dot']` while `checked`."},{"name":"--lr-radio-circle-size","description":"**`<lr-radio>`, `<lr-radio-button>`** (default: `min(var(--lr-icon-button-size), calc(var(--lr-form-control-height) * 0.7))`) — Edge length of `[part='circle']`. Derived from the `size` tier's shared control height so a radio lines up with an `<lr-input>`/`<lr-select>`/`<lr-button>` of the same `size`."},{"name":"--lr-radio-dot-size","description":"**`<lr-radio>`, `<lr-radio-button>`** (default: `min(calc(var(--lr-radio-circle-size) * 0.5), calc(var(--lr-form-control-height) * 0.3))`) — Edge length of `[part='dot']`, capped at half the circle so it can never outgrow its ring."},{"name":"--lr-radio-group-row-gap","description":"**`<lr-radio-group>`** (default: `calc(var(--lr-form-control-height) * 0.2)`) — Vertical gap between the group's label, options and messages, scaled by `size`."},{"name":"--lr-radio-hover-border-color","description":"**`<lr-radio>`, `<lr-radio-button>`** (default: `var(--lr-color-brand)`) — Indicator border while the interactive row is hovered."},{"name":"--lr-radio-label-indent","description":"**`<lr-radio>`, `<lr-radio-button>`** (default: `calc(var(--lr-radio-circle-size) + var(--lr-space-s))`) — The inline distance from the control's start edge to the start of the label text, i.e. the circle's own floor plus the gap next to it — so it tracks `size` along with the circle. Published so a consumer composing per-option hint text under the label can align it without re-deriving that formula from the shadow styles, and used as the source of the real gap so the two cannot drift. Setting it on the element (or on `lr-radio` in your own stylesheet) moves the label; because custom properties inherit down and not sideways, it is *not* readable from a sibling node in your tree — align a sibling by computing the same formula from `--lr-theme-icon-button-size`, `--lr-theme-form-control-height-*` and `--lr-theme-space-s`, which you control."},{"name":"--lr-radio-radius","description":"**`<lr-radio>`** (default: `var(--lr-radius-pill)`) — Corner radius of the control's own chrome. A circular indicator is fully round at every setting; `<lr-radio-button>` re-points this knob at the shared control radius and swaps it for a pill when `pill` is set.\n\n**`<lr-radio-button>`** (default: `var(--lr-form-control-radius)`) — Corner radius of the outer edges of the button row. Its private default follows the shared control radius and changes to `--lr-radius-pill` for `pill`; an inherited or direct public value still wins."},{"name":"--lr-radius","description":"**Shared design token** — Canonical shared component token for radius. Reads `--lr-theme-border-radius-m`."},{"name":"--lr-radius-pill","description":"**Shared design token** — Canonical shared component token for radius pill. Reads `--lr-theme-border-radius-pill`."},{"name":"--lr-radius-xs","description":"**Shared design token** — Canonical shared component token for radius xs. Reads `--lr-theme-border-radius-xs`."},{"name":"--lr-rag-eval-dashboard-selected-border-color","description":"**`<lr-rag-eval-dashboard>`** (default: `var(--lr-color-brand)`) — Border color shared by the controlled active slice and metric."},{"name":"--lr-ramp-brand-05","description":"**Shared design token** — Canonical shared component token for ramp brand 05."},{"name":"--lr-ramp-brand-10","description":"**Shared design token** — Canonical shared component token for ramp brand 10."},{"name":"--lr-ramp-brand-20","description":"**Shared design token** — Canonical shared component token for ramp brand 20."},{"name":"--lr-ramp-brand-30","description":"**Shared design token** — Canonical shared component token for ramp brand 30."},{"name":"--lr-ramp-brand-40","description":"**Shared design token** — Canonical shared component token for ramp brand 40."},{"name":"--lr-ramp-brand-50","description":"**Shared design token** — Canonical shared component token for ramp brand 50."},{"name":"--lr-ramp-brand-60","description":"**Shared design token** — Canonical shared component token for ramp brand 60."},{"name":"--lr-ramp-brand-70","description":"**Shared design token** — Canonical shared component token for ramp brand 70."},{"name":"--lr-ramp-brand-80","description":"**Shared design token** — Canonical shared component token for ramp brand 80."},{"name":"--lr-ramp-brand-90","description":"**Shared design token** — Canonical shared component token for ramp brand 90."},{"name":"--lr-ramp-brand-95","description":"**Shared design token** — Canonical shared component token for ramp brand 95."},{"name":"--lr-ramp-danger-05","description":"**Shared design token** — Canonical shared component token for ramp danger 05."},{"name":"--lr-ramp-danger-10","description":"**Shared design token** — Canonical shared component token for ramp danger 10."},{"name":"--lr-ramp-danger-20","description":"**Shared design token** — Canonical shared component token for ramp danger 20."},{"name":"--lr-ramp-danger-30","description":"**Shared design token** — Canonical shared component token for ramp danger 30."},{"name":"--lr-ramp-danger-40","description":"**Shared design token** — Canonical shared component token for ramp danger 40."},{"name":"--lr-ramp-danger-50","description":"**Shared design token** — Canonical shared component token for ramp danger 50."},{"name":"--lr-ramp-danger-60","description":"**Shared design token** — Canonical shared component token for ramp danger 60."},{"name":"--lr-ramp-danger-70","description":"**Shared design token** — Canonical shared component token for ramp danger 70."},{"name":"--lr-ramp-danger-80","description":"**Shared design token** — Canonical shared component token for ramp danger 80."},{"name":"--lr-ramp-danger-90","description":"**Shared design token** — Canonical shared component token for ramp danger 90."},{"name":"--lr-ramp-danger-95","description":"**Shared design token** — Canonical shared component token for ramp danger 95."},{"name":"--lr-ramp-neutral-05","description":"**Shared design token** — Canonical shared component token for ramp neutral 05."},{"name":"--lr-ramp-neutral-10","description":"**Shared design token** — Canonical shared component token for ramp neutral 10."},{"name":"--lr-ramp-neutral-20","description":"**Shared design token** — Canonical shared component token for ramp neutral 20."},{"name":"--lr-ramp-neutral-30","description":"**Shared design token** — Canonical shared component token for ramp neutral 30."},{"name":"--lr-ramp-neutral-40","description":"**Shared design token** — Canonical shared component token for ramp neutral 40."},{"name":"--lr-ramp-neutral-50","description":"**Shared design token** — Canonical shared component token for ramp neutral 50."},{"name":"--lr-ramp-neutral-60","description":"**Shared design token** — Canonical shared component token for ramp neutral 60."},{"name":"--lr-ramp-neutral-70","description":"**Shared design token** — Canonical shared component token for ramp neutral 70."},{"name":"--lr-ramp-neutral-80","description":"**Shared design token** — Canonical shared component token for ramp neutral 80."},{"name":"--lr-ramp-neutral-90","description":"**Shared design token** — Canonical shared component token for ramp neutral 90."},{"name":"--lr-ramp-neutral-95","description":"**Shared design token** — Canonical shared component token for ramp neutral 95."},{"name":"--lr-ramp-success-05","description":"**Shared design token** — Canonical shared component token for ramp success 05."},{"name":"--lr-ramp-success-10","description":"**Shared design token** — Canonical shared component token for ramp success 10."},{"name":"--lr-ramp-success-20","description":"**Shared design token** — Canonical shared component token for ramp success 20."},{"name":"--lr-ramp-success-30","description":"**Shared design token** — Canonical shared component token for ramp success 30."},{"name":"--lr-ramp-success-40","description":"**Shared design token** — Canonical shared component token for ramp success 40."},{"name":"--lr-ramp-success-50","description":"**Shared design token** — Canonical shared component token for ramp success 50."},{"name":"--lr-ramp-success-60","description":"**Shared design token** — Canonical shared component token for ramp success 60."},{"name":"--lr-ramp-success-70","description":"**Shared design token** — Canonical shared component token for ramp success 70."},{"name":"--lr-ramp-success-80","description":"**Shared design token** — Canonical shared component token for ramp success 80."},{"name":"--lr-ramp-success-90","description":"**Shared design token** — Canonical shared component token for ramp success 90."},{"name":"--lr-ramp-success-95","description":"**Shared design token** — Canonical shared component token for ramp success 95."},{"name":"--lr-ramp-warning-05","description":"**Shared design token** — Canonical shared component token for ramp warning 05."},{"name":"--lr-ramp-warning-10","description":"**Shared design token** — Canonical shared component token for ramp warning 10."},{"name":"--lr-ramp-warning-20","description":"**Shared design token** — Canonical shared component token for ramp warning 20."},{"name":"--lr-ramp-warning-30","description":"**Shared design token** — Canonical shared component token for ramp warning 30."},{"name":"--lr-ramp-warning-40","description":"**Shared design token** — Canonical shared component token for ramp warning 40."},{"name":"--lr-ramp-warning-50","description":"**Shared design token** — Canonical shared component token for ramp warning 50."},{"name":"--lr-ramp-warning-60","description":"**Shared design token** — Canonical shared component token for ramp warning 60."},{"name":"--lr-ramp-warning-70","description":"**Shared design token** — Canonical shared component token for ramp warning 70."},{"name":"--lr-ramp-warning-80","description":"**Shared design token** — Canonical shared component token for ramp warning 80."},{"name":"--lr-ramp-warning-90","description":"**Shared design token** — Canonical shared component token for ramp warning 90."},{"name":"--lr-ramp-warning-95","description":"**Shared design token** — Canonical shared component token for ramp warning 95."},{"name":"--lr-random-content-animation-duration","description":"**`<lr-random-content>`** (default: `300ms`) — Duration of the entrance animation."},{"name":"--lr-random-content-animation-easing","description":"**`<lr-random-content>`** (default: `ease`) — Easing function for the entrance animation."},{"name":"--lr-random-content-animation-translate","description":"**`<lr-random-content>`** (default: `var(--lr-size-0-5em)`) — Translation distance for directional animations."},{"name":"--lr-random-content-item-alignment","description":"**`<lr-random-content>`** (default: `flex-start`) — Cross-axis alignment of selected items."},{"name":"--lr-random-content-item-gap","description":"**`<lr-random-content>`** (default: `var(--lr-space-s)`) — Gap between simultaneously selected items."},{"name":"--lr-rating-active-color","description":"**`<lr-rating>`** (default: `color-mix(in oklab, var(--lr-rating-empty-color, var(--symbol-color, var(--lr-color-border-strong))), var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Pressed-symbol color. Set it independently of `--lr-rating-empty-color` to recolor the pressed state without changing resting or hover symbols."},{"name":"--lr-rating-empty-color","description":"**`<lr-rating>`** (default: `var(--lr-color-border)`) — Unfilled-symbol color, retained during hover preview."},{"name":"--lr-rating-fill","description":"**`<lr-rating>`** (default: `var(--lr-color-warning)`) — Filled-symbol color."},{"name":"--lr-rating-gap","description":"**`<lr-rating>`** (default: `var(--symbol-spacing,var(--lr-space-xs))`) — Gap between symbols. It takes precedence over the `--symbol-spacing` compatibility hook while preserving that hook and the shared spacing token as fallbacks."},{"name":"--lr-rating-size","description":"**`<lr-rating>`** (default: `var(--lr-font-size-xl)`) — Symbol size. Its private default follows each `size` step; an inherited or direct public value wins. The `m` default reproduces the treatment this component had before `size` existed."},{"name":"--lr-reorder-item-gap","description":"**`<lr-reorder-item>`** (default: `var(--lr-space-xs)`) — Gap between the move buttons and content. Move-button state properties are resolved as inline fallbacks, so setting one on an item or any ancestor themes only the requested hover or pressed state without replacing shared brand tokens."},{"name":"--lr-reorder-item-move-button-active-bg","description":"**`<lr-reorder-item>`** (default: `color-mix(in oklab, var(--lr-color-brand-quiet), var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Background of a pressed move button."},{"name":"--lr-reorder-item-move-button-active-color","description":"**`<lr-reorder-item>`** (default: `var(--lr-color-brand)`) — Text color of a pressed move button."},{"name":"--lr-reorder-item-move-button-hover-bg","description":"**`<lr-reorder-item>`** (default: `var(--lr-color-brand-quiet)`) — Background of a hovered move button."},{"name":"--lr-reorder-item-move-button-hover-color","description":"**`<lr-reorder-item>`** (default: `var(--lr-color-brand)`) — Text color of a hovered move button."},{"name":"--lr-reorder-list-gap","description":"**`<lr-reorder-list>`** (default: `var(--lr-space-2xs)`) — Gap between rows."},{"name":"--lr-responsive-panel-overlay-color","description":"**`<lr-responsive-panel>`** (default: `var(--lr-color-overlay)`) — The overlay presentation's scrim color, applied to `[part=\"backdrop\"]`."},{"name":"--lr-responsive-panel-overlay-panel-bg","description":"**`<lr-responsive-panel>`** (default: `var(--lr-color-surface-overlay)`) — Background of `[part=\"panel\"]` in the overlay presentation."},{"name":"--lr-responsive-panel-overlay-panel-shadow","description":"**`<lr-responsive-panel>`** (default: `var(--lr-shadow-l)`) — Shadow of `[part=\"panel\"]` in the overlay presentation."},{"name":"--lr-responsive-panel-sheet-max-block-size","description":"**`<lr-responsive-panel>`** (default: `85dvh`) — Maximum height of the `shape=\"bottom-sheet\"` overlay panel (falls back to `85vh` where `dvh` is unsupported)."},{"name":"--lr-responsive-panel-side-inline-size","description":"**`<lr-responsive-panel>`** (default: `var(--lr-size-20rem)`) — Width of the `shape=\"start\"`/`shape=\"end\"` overlay panel along the inline axis."},{"name":"--lr-result-card-background","description":"**`<lr-result-card>`** (default: `var(--lr-color-surface)`) — Fill of the outer card (`[part=\"base\"]`) while `frame=\"card\"`. `frame=\"plain\"` still removes the fill entirely."},{"name":"--lr-result-card-border-color","description":"**`<lr-result-card>`** (default: `var(--lr-color-border)`) — Colour of the outer card's border and of the `[part=\"header\"]` divider."},{"name":"--lr-result-card-compact-body-gap","description":"**`<lr-result-card>`** (default: `var(--lr-space-2xs)`) — Gap between `[part=\"body\"]`'s children while `compact`."},{"name":"--lr-result-card-compact-body-padding","description":"**`<lr-result-card>`** (default: `var(--lr-space-xs)`) — `[part=\"body\"]` padding while `compact`."},{"name":"--lr-result-card-compact-header-gap","description":"**`<lr-result-card>`** (default: `var(--lr-space-xs)`) — Gap between `[part=\"header\"]`'s heading and actions while `compact`."},{"name":"--lr-result-card-compact-header-padding","description":"**`<lr-result-card>`** (default: `var(--lr-space-xs)`) — `[part=\"header\"]` block/inline padding while `compact`."},{"name":"--lr-result-card-radius","description":"**`<lr-result-card>`** (default: `var(--lr-radius)`) — Corner radius of the outer card. `frame=\"plain\"` still squares the corners."},{"name":"--lr-retrieval-compare-selected-border","description":"**`<lr-retrieval-compare>`** (default: `var(--lr-color-brand)`) — Border color marking a selected `[part~=\"chunk\"]` row."},{"name":"--lr-retrieval-results-selected-border","description":"**`<lr-retrieval-results>`** (default: `var(--lr-color-brand)`) — Inline-start border color marking a selected `[part=\"row-body\"]`. A border rather than a fill by design (see the styles file), so recoloring it carries no contrast risk for the row's own text."},{"name":"--lr-retrieval-search-submit-min-height","description":"**`<lr-retrieval-search>`** (default: `var(--lr-icon-button-size)`) — Minimum height of the submit button. A `size` tier raises it to that tier's shared form-control height; the shared tappable-target minimum always stays underneath, so no tier can shrink the button past the WCAG floor."},{"name":"--lr-retrieval-trace-active-border","description":"**`<lr-retrieval-trace>`** (default: `var(--lr-color-brand)`) — Border color of the `[part=\"evidence-row\"]` whose stage matches `activeStageId`."},{"name":"--lr-rubric-form-skip-active-bg","description":"**`<lr-rubric-form>`** (default: `color-mix(...)`) — Skip background while pressed."},{"name":"--lr-rubric-form-skip-bg","description":"**`<lr-rubric-form>`** (default: `var(--lr-color-surface)`) — Skip-button background."},{"name":"--lr-rubric-form-skip-border-color","description":"**`<lr-rubric-form>`** (default: `var(--lr-color-border)`) — Skip-button border."},{"name":"--lr-rubric-form-skip-color","description":"**`<lr-rubric-form>`** (default: `var(--lr-color-text)`) — Skip-button text color."},{"name":"--lr-rubric-form-skip-hover-bg","description":"**`<lr-rubric-form>`** (default: `var(--lr-color-brand-quiet)`) — Skip background while hovered."},{"name":"--lr-rubric-form-submit-active-bg","description":"**`<lr-rubric-form>`** (default: `color-mix(...)`) — Submit background while pressed."},{"name":"--lr-rubric-form-submit-active-border-color","description":"**`<lr-rubric-form>`** (default: `color-mix(...)`) — Submit border while pressed."},{"name":"--lr-rubric-form-submit-bg","description":"**`<lr-rubric-form>`** (default: `var(--lr-color-brand)`) — Submit-button background."},{"name":"--lr-rubric-form-submit-border-color","description":"**`<lr-rubric-form>`** (default: `var(--lr-color-brand)`) — Submit-button border."},{"name":"--lr-rubric-form-submit-color","description":"**`<lr-rubric-form>`** (default: `var(--lr-color-on-brand)`) — Submit-button text color."},{"name":"--lr-rubric-form-submit-hover-bg","description":"**`<lr-rubric-form>`** (default: `color-mix(...)`) — Submit background while hovered."},{"name":"--lr-rubric-form-submit-hover-border-color","description":"**`<lr-rubric-form>`** (default: `color-mix(...)`) — Submit border while hovered."},{"name":"--lr-safe-area-bottom","description":"**Shared design token** — Canonical shared component token for safe area bottom."},{"name":"--lr-safe-area-inline-end","description":"**Shared design token** — Canonical shared component token for safe area inline end."},{"name":"--lr-safe-area-inline-start","description":"**Shared design token** — Canonical shared component token for safe area inline start."},{"name":"--lr-safe-area-top","description":"**Shared design token** — Canonical shared component token for safe area top."},{"name":"--lr-schema-viewer-error-bg","description":"**`<lr-json-schema-viewer>`** (default: `var(--lr-color-danger-quiet)`) — Error issue background."},{"name":"--lr-schema-viewer-error-border","description":"**`<lr-json-schema-viewer>`** (default: `var(--lr-color-danger)`) — Error issue border."},{"name":"--lr-schema-viewer-info-bg","description":"**`<lr-json-schema-viewer>`** (default: `var(--lr-color-brand-quiet)`) — Info issue background."},{"name":"--lr-schema-viewer-info-border","description":"**`<lr-json-schema-viewer>`** (default: `var(--lr-color-brand)`) — Info issue border."},{"name":"--lr-schema-viewer-max-indent","description":"**`<lr-json-schema-viewer>`** (default: `var(--lr-size-12rem)`) — Maximum visual indentation; complete JSON Pointer paths and selection semantics remain unchanged at deeper levels."},{"name":"--lr-schema-viewer-selected-border","description":"**`<lr-json-schema-viewer>`** (default: `var(--lr-color-brand)`) — Selected node branch."},{"name":"--lr-schema-viewer-warning-bg","description":"**`<lr-json-schema-viewer>`** (default: `var(--lr-color-warning-quiet)`) — Warning issue background."},{"name":"--lr-schema-viewer-warning-border","description":"**`<lr-json-schema-viewer>`** (default: `var(--lr-color-warning)`) — Warning issue border."},{"name":"--lr-scroll-fade-size","description":"**`<lr-segmented>`** (default: `2rem`) — Width of the fade at each horizontal scroll edge. The fade is applied only while the track actually overflows, so a row that fits is never dimmed.\n\n**`<lr-stepper>`** (default: `2rem`) — Width of each decorative horizontal overflow fade. Pointer-state hooks use inline `var()` fallbacks rather than a `:host` declaration, so they inherit from the stepper or any ancestor without retheming another state.\n\n**`<lr-tab-group>`** (default: `2rem`) — Width of the fade at each horizontal scroll edge. The fade is applied only while the tablist actually overflows, so a row that fits is never dimmed.\n\n**`<lr-timeline>`** (default: `2rem`) — Inline size of each edge fade while a horizontal timeline overflows. Forced-colors mode disables the masks while retaining native scrolling.\n\n**`<lr-widget>`** (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\n**Shared design token** — Canonical shared component token for scroll fade size. Reads `--lr-theme-scroll-fade-size`."},{"name":"--lr-scroller-control-size","description":"**`<lr-scroller>`** (default: `var(--lr-size-2rem)`) — Control size."},{"name":"--lr-scroller-hover-outline-color","description":"**`<lr-scroller>`** (default: `var(--lr-color-border)`) — Outline color of the mouse-hover preview on `[part=\"viewport\"]`. Set to `transparent` to opt out of the hover treatment entirely."},{"name":"--lr-scroller-hover-outline-offset","description":"**`<lr-scroller>`** (default: `var(--lr-focus-ring-offset)`) — Offset of the mouse-hover preview on `[part=\"viewport\"]`."},{"name":"--lr-scroller-hover-outline-style","description":"**`<lr-scroller>`** (default: `solid`) — Outline style of the mouse-hover preview on `[part=\"viewport\"]`."},{"name":"--lr-scroller-hover-outline-width","description":"**`<lr-scroller>`** (default: `var(--lr-border-width-thin)`) — Outline width of the mouse-hover preview on `[part=\"viewport\"]`."},{"name":"--lr-scroller-min-block-size","description":"**`<lr-scroller>`** (default: `var(--lr-size-10rem)`) — Minimum vertical scroller size."},{"name":"--lr-scroller-shadow-color","description":"**`<lr-scroller>`** (default: `var(--shadow-color)`) — Lyra-prefixed shadow-color alias."},{"name":"--lr-scroller-shadow-size","description":"**`<lr-scroller>`** (default: `var(--shadow-size)`) — Lyra-prefixed shadow-size alias."},{"name":"--lr-segmented-active-bg","description":"**`<lr-segmented>`** (default: `color-mix(in oklab, transparent, var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Background of a pressed segment that is neither checked nor disabled."},{"name":"--lr-segmented-active-color","description":"**`<lr-segmented>`** (default: `var(--lr-segmented-hover-color, var(--lr-color-text))`) — Text color of a pressed segment that is neither checked nor disabled. Its default follows `--lr-segmented-hover-color` to preserve the established hover/pressed relationship; set this property to theme the pressed text independently."},{"name":"--lr-segmented-font-size","description":"**`<lr-segmented>`** (default: `var(--lr-form-control-font-size)`) — Each segment's font size, taken from the `size` tier's shared control font size."},{"name":"--lr-segmented-hover-bg","description":"**`<lr-segmented>`** (default: `transparent`) — Background of a hovered segment that is neither checked nor disabled. Undeclared by default, so it falls back to the segment's own resting transparent background — byte-identical to before this property existed."},{"name":"--lr-segmented-hover-color","description":"**`<lr-segmented>`** (default: `var(--lr-color-text)`) — Text color of a hovered segment that is neither checked nor disabled. Independent of the selected-state props above — recoloring the checked pill leaves this untouched."},{"name":"--lr-segmented-hover-shadow","description":"**`<lr-segmented>`** (default: `none`) — Box shadow of a hovered segment that is neither checked nor disabled. Undeclared by default, matching the segment's own resting absence of a shadow."},{"name":"--lr-segmented-segment-padding","description":"**`<lr-segmented>`** (default: `var(--lr-form-control-padding-block) var(--lr-form-control-padding-inline)`) — Each segment's padding, taken from the `size` tier's shared control padding."},{"name":"--lr-segmented-selected-bg","description":"**`<lr-segmented>`** (default: `var(--lr-color-surface)`) — Background of the checked segment. Scoped to `[aria-checked='true']` only, so it never repaints a hovered unselected segment (which is what hijacking `--lr-color-surface` library-wide used to do)."},{"name":"--lr-segmented-selected-color","description":"**`<lr-segmented>`** (default: `var(--lr-color-text)`) — Text color of the checked segment."},{"name":"--lr-segmented-selected-font-weight","description":"**`<lr-segmented>`** (default: `var(--lr-font-weight-semibold)`) — Font weight of the checked segment."},{"name":"--lr-segmented-selected-shadow","description":"**`<lr-segmented>`** (default: `var(--lr-shadow-xs)`) — Box shadow lifting the checked segment off the track."},{"name":"--lr-segmented-track-bg","description":"**`<lr-segmented>`** (default: `transparent`) — Background of the `base` track. Undeclared by default, matching its own current absence of a background."},{"name":"--lr-segmented-track-border-color","description":"**`<lr-segmented>`** (default: `var(--lr-color-border)`) — Border color of the `base` track, which previously read that token as a literal with no override hook."},{"name":"--lr-segmented-track-gap","description":"**`<lr-segmented>`** (default: `var(--lr-size-0-125rem)`) — Gap between segments."},{"name":"--lr-segmented-track-height","description":"**`<lr-segmented>`** — Exact height of the `base` track, pinning it at every `size` tier (sets both `block-size` and `min-block-size`) so the row can sit flush beside a hard-sized toolbar control. **Genuinely unset by default** — while unset each tier keeps its own `--lr-segmented-track-min-height` floor and the track grows with its content."},{"name":"--lr-segmented-track-min-height","description":"**`<lr-segmented>`** (default: `var(--lr-form-control-height)`) — Minimum height of the `base` track, taken from the `size` tier's shared control height; the `2.5rem` (40px) default applies at the unset/`m` size, matching `<lr-input>`/`<lr-select>`/`<lr-combobox>`'s own shared default-tier floor. The private default follows `size`; a public value inherited from an ancestor or set directly on the element remains authoritative in every tier."},{"name":"--lr-segmented-track-padding","description":"**`<lr-segmented>`** (default: `var(--lr-size-0-125rem)`) — Track inset padding."},{"name":"--lr-segmented-track-radius","description":"**`<lr-segmented>`** (default: `var(--lr-radius)`) — Track corner radius."},{"name":"--lr-select-expand-size","description":"**`<lr-select>`** — Decorative expand-icon box size, scaled by `size`. The one piece of this component's geometry the shared ladder does not own: it sizes a glyph, not the control row."},{"name":"--lr-select-font-size","description":"**`<lr-select>`** (default: `var(--lr-form-control-font-size)`) — Trigger font size, from the active `size` tier."},{"name":"--lr-select-gap","description":"**`<lr-select>`** — Gap between the trigger's start adornment, label, end adornment, and expand icon. Doesn't vary by `size`."},{"name":"--lr-select-open-border-color","description":"**`<lr-select>`** (default: `var(--lr-color-brand)`) — Trigger border while the listbox is open."},{"name":"--lr-select-option-active-bg","description":"**`<lr-select>`** (default: `var(--lr-color-brand-quiet)`) — Background of the hovered/keyboard-active option row. Not declared on `:host`, so a value set on any ancestor is never shadowed -- retheme just this row state without hijacking the shared `--lr-color-brand-quiet` token used by every other component's own hover/active state."},{"name":"--lr-select-option-badge-bg","description":"**`<lr-select>`** (default: `var(--lr-color-brand-quiet)`) — Background of the `[part='option-badge']` \"not in catalog\" badge."},{"name":"--lr-select-option-selected-bg","description":"**`<lr-select>`** (default: `transparent`) — Background of the currently-selected option row. Not declared on `:host`; retheme just the selected row without hijacking `--lr-color-brand`."},{"name":"--lr-select-option-selected-border","description":"**`<lr-select>`** (default: `var(--lr-color-brand)`) — Border color of the selected option row."},{"name":"--lr-select-option-selected-color","description":"**`<lr-select>`** (default: `var(--lr-color-brand)`) — Text color of the selected option row."},{"name":"--lr-select-option-selected-font-weight","description":"**`<lr-select>`** (default: `var(--lr-font-weight-semibold)`) — Font weight of the selected option row."},{"name":"--lr-select-radius","description":"**`<lr-select>`** (default: `var(--lr-form-control-radius)`) — Trigger corner radius, from the active `size` tier of the shared form-control ladder (the two tightest tiers take a smaller radius)."},{"name":"--lr-select-tag-font-size","description":"**`<lr-select>`** — Chip text size. Doesn't vary by `size`."},{"name":"--lr-select-tag-padding","description":"**`<lr-select>`** — Padding inside a `multiple`-mode chip. Doesn't vary by `size`."},{"name":"--lr-select-trigger-active-bg","description":"**`<lr-select>`** (default: `color-mix(...)`) — Trigger background while pressed."},{"name":"--lr-select-trigger-border-color","description":"**`<lr-select>`** (default: `var(--lr-color-border)`) — Resting trigger border color, `transparent` by default on the `filled`/`plain`/`accent` treatments."},{"name":"--lr-select-trigger-fill","description":"**`<lr-select>`** (default: `var(--lr-color-surface)`) — Resting trigger background. Read by every appearance, each falling back to its own default (`--lr-color-surface-raised` for `filled`/`filled-outlined`, `transparent` for `plain`, `--lr-color-brand` for `accent`), so one value retints the trigger whichever treatment it is wearing."},{"name":"--lr-select-trigger-height","description":"**`<lr-select>`** — Exact trigger height. Unset by default, which leaves `--lr-select-trigger-min-height` as a floor only; set it to a length to both floor and cap the trigger (e.g. to pixel-match a sibling field in the same toolbar row). Because it is never declared by the component itself, it can be set from an ancestor or an outer-tree rule as well as inline on the element."},{"name":"--lr-select-trigger-hover-bg","description":"**`<lr-select>`** (default: `var(--lr-color-brand-quiet)`) — Trigger background while hovered. Accent appearance keeps its louder mixed fallback when this hook is unset."},{"name":"--lr-select-trigger-hover-border-color","description":"**`<lr-select>`** (default: `var(--lr-select-trigger-border-color)`) — Trigger border color while the pointer is over it. Unset, the border stays exactly where the resting state left it."},{"name":"--lr-select-trigger-min-height","description":"**`<lr-select>`** (default: `var(--lr-form-control-height)`) — Trigger block-size floor, from the active `size` tier of the shared ladder, and live at every tier including the default `m` -- so a select is exactly as tall as an `<lr-button>`/`<lr-input>` of that tier."},{"name":"--lr-select-trigger-padding","description":"**`<lr-select>`** — Trigger padding shorthand. Defaults to the active `size` tier's `var(--lr-form-control-padding-block) var(--lr-form-control-padding-inline)` from the shared ladder."},{"name":"--lr-select-unknown-value-border-color","description":"**`<lr-select>`** (default: `var(--lr-color-border)`) — Border color of the same unknown-value chip."},{"name":"--lr-select-unknown-value-border-style","description":"**`<lr-select>`** (default: `dashed`) — Border style of an `[part='unknown-value']` chip (a `multiple`-mode tag whose committed value matches no current option)."},{"name":"--lr-selection-toolbar-placement-gap","description":"**`<lr-selection-toolbar>`** (default: `var(--lr-space-s)`) — Non-negative distance between the selection and toolbar, and between the toolbar and viewport during collision avoidance. Unitless pixel values and `px`, `rem`, and `em` values are resolved live; invalid values fall back to the default and negative values clamp to `0`."},{"name":"--lr-sequence-playback-icon-size","description":"**`<lr-sequence-playback>`** (default: `calc(var(--lr-icon-button-size) * 0.35)`) — Font size of the play/pause glyph, derived from the shared icon-button hit-target size."},{"name":"--lr-sequence-playback-play-button-active-bg","description":"**`<lr-sequence-playback>`** — Pressed play/pause button background. Defaults to the existing surface active mix; read as an inline fallback so an ancestor value inherits."},{"name":"--lr-sequence-playback-play-button-active-border-color","description":"**`<lr-sequence-playback>`** (default: `var(--lr-color-brand)`) — Pressed play/pause button border color; read as an inline fallback so an ancestor value inherits."},{"name":"--lr-sequence-strip-disabled-opacity","description":"**`<lr-sequence-strip>`** (default: `var(--lr-opacity-disabled)`) — Opacity of a cell whose activated item sets `disabled`."},{"name":"--lr-sequence-strip-height","description":"**`<lr-sequence-strip>`** (default: `var(--lr-size-1-5rem)`) — Block size of the strip."},{"name":"--lr-sequence-strip-legend-marker-bg","description":"**`<lr-sequence-strip>`** (default: `var(--lr-color-surface-raised)`) — Neutral chip background behind the marker legend row's bar; it stands in for \"any cell\", so it deliberately matches no category color."},{"name":"--lr-sequence-strip-legend-swatch-size","description":"**`<lr-sequence-strip>`** (default: `var(--lr-size-0-625rem)`) — Inline and block size of a legend swatch (category and marker rows alike)."},{"name":"--lr-sequence-strip-marker-color","description":"**`<lr-sequence-strip>`** (default: `var(--lr-color-text)`) — Color of the bottom marker on a `marker: true` cell, and of the marker legend row's bar."},{"name":"--lr-shadow","description":"**Shared design token** — Canonical shared component token for shadow."},{"name":"--lr-shadow-color","description":"**Shared design token** — Canonical shared component token for shadow color. Reads `--lr-theme-shadow-color`."},{"name":"--lr-shadow-l","description":"**Shared design token** — Canonical shared component token for shadow l. Reads `--lr-theme-shadow-l`."},{"name":"--lr-shadow-m","description":"**Shared design token** — Canonical shared component token for shadow m. Reads `--lr-theme-shadow-m`."},{"name":"--lr-shadow-s","description":"**Shared design token** — Canonical shared component token for shadow s. Reads `--lr-theme-shadow-s`."},{"name":"--lr-shadow-xl","description":"**Shared design token** — Canonical shared component token for shadow xl. Reads `--lr-theme-shadow-xl`."},{"name":"--lr-shadow-xs","description":"**Shared design token** — Canonical shared component token for shadow xs. Reads `--lr-theme-shadow-xs`."},{"name":"--lr-size-0-02em","description":"**Shared design token** — Canonical shared component token for size 0 02em. Reads `--lr-theme-size-0-02em`."},{"name":"--lr-size-0-03em","description":"**Shared design token** — Canonical shared component token for size 0 03em. Reads `--lr-theme-size-0-03em`."},{"name":"--lr-size-0-04em","description":"**Shared design token** — Canonical shared component token for size 0 04em. Reads `--lr-theme-size-0-04em`."},{"name":"--lr-size-0-05rem","description":"**Shared design token** — Canonical shared component token for size 0 05rem. Reads `--lr-theme-size-0-05rem`."},{"name":"--lr-size-0-0625rem","description":"**Shared design token** — Canonical shared component token for size 0 0625rem. Reads `--lr-theme-size-0-0625rem`."},{"name":"--lr-size-0-09375rem","description":"**Shared design token** — Canonical shared component token for size 0 09375rem. Reads `--lr-theme-size-0-09375rem`."},{"name":"--lr-size-0-125rem","description":"**Shared design token** — Canonical shared component token for size 0 125rem. Reads `--lr-theme-size-0-125rem`."},{"name":"--lr-size-0-15rem","description":"**Shared design token** — Canonical shared component token for size 0 15rem. Reads `--lr-theme-size-0-15rem`."},{"name":"--lr-size-0-1875rem","description":"**Shared design token** — Canonical shared component token for size 0 1875rem. Reads `--lr-theme-size-0-1875rem`."},{"name":"--lr-size-0-1rem","description":"**Shared design token** — Canonical shared component token for size 0 1rem. Reads `--lr-theme-size-0-1rem`."},{"name":"--lr-size-0-25rem","description":"**Shared design token** — Canonical shared component token for size 0 25rem. Reads `--lr-theme-size-0-25rem`."},{"name":"--lr-size-0-3125rem","description":"**Shared design token** — Canonical shared component token for size 0 3125rem. Reads `--lr-theme-size-0-3125rem`."},{"name":"--lr-size-0-35em","description":"**Shared design token** — Canonical shared component token for size 0 35em. Reads `--lr-theme-size-0-35em`."},{"name":"--lr-size-0-375rem","description":"**Shared design token** — Canonical shared component token for size 0 375rem. Reads `--lr-theme-size-0-375rem`."},{"name":"--lr-size-0-3em","description":"**Shared design token** — Canonical shared component token for size 0 3em. Reads `--lr-theme-size-0-3em`."},{"name":"--lr-size-0-4375rem","description":"**Shared design token** — Canonical shared component token for size 0 4375rem. Reads `--lr-theme-size-0-4375rem`."},{"name":"--lr-size-0-4em","description":"**Shared design token** — Canonical shared component token for size 0 4em. Reads `--lr-theme-size-0-4em`."},{"name":"--lr-size-0-4rem","description":"**Shared design token** — Canonical shared component token for size 0 4rem. Reads `--lr-theme-size-0-4rem`."},{"name":"--lr-size-0-5em","description":"**Shared design token** — Canonical shared component token for size 0 5em. Reads `--lr-theme-size-0-5em`."},{"name":"--lr-size-0-5rem","description":"**Shared design token** — Canonical shared component token for size 0 5rem. Reads `--lr-theme-size-0-5rem`."},{"name":"--lr-size-0-625rem","description":"**Shared design token** — Canonical shared component token for size 0 625rem. Reads `--lr-theme-size-0-625rem`."},{"name":"--lr-size-0-6875rem","description":"**Shared design token** — Canonical shared component token for size 0 6875rem. Reads `--lr-theme-size-0-6875rem`."},{"name":"--lr-size-0-6rem","description":"**Shared design token** — Canonical shared component token for size 0 6rem. Reads `--lr-theme-size-0-6rem`."},{"name":"--lr-size-0-75em","description":"**Shared design token** — Canonical shared component token for size 0 75em. Reads `--lr-theme-size-0-75em`."},{"name":"--lr-size-0-75rem","description":"**Shared design token** — Canonical shared component token for size 0 75rem. Reads `--lr-theme-size-0-75rem`."},{"name":"--lr-size-0-7em","description":"**Shared design token** — Canonical shared component token for size 0 7em. Reads `--lr-theme-size-0-7em`."},{"name":"--lr-size-0-875em","description":"**Shared design token** — Canonical shared component token for size 0 875em. Reads `--lr-theme-size-0-875em`."},{"name":"--lr-size-0-8rem","description":"**Shared design token** — Canonical shared component token for size 0 8rem. Reads `--lr-theme-size-0-8rem`."},{"name":"--lr-size-0-9375rem","description":"**Shared design token** — Canonical shared component token for size 0 9375rem. Reads `--lr-theme-size-0-9375rem`."},{"name":"--lr-size-1-0625rem","description":"**Shared design token** — Canonical shared component token for size 1 0625rem. Reads `--lr-theme-size-1-0625rem`."},{"name":"--lr-size-1-1rem","description":"**Shared design token** — Canonical shared component token for size 1 1rem. Reads `--lr-theme-size-1-1rem`."},{"name":"--lr-size-1-25rem","description":"**Shared design token** — Canonical shared component token for size 1 25rem. Reads `--lr-theme-size-1-25rem`."},{"name":"--lr-size-1-5em","description":"**Shared design token** — Canonical shared component token for size 1 5em. Reads `--lr-theme-size-1-5em`."},{"name":"--lr-size-1-5rem","description":"**Shared design token** — Canonical shared component token for size 1 5rem. Reads `--lr-theme-size-1-5rem`."},{"name":"--lr-size-1-75rem","description":"**Shared design token** — Canonical shared component token for size 1 75rem. Reads `--lr-theme-size-1-75rem`."},{"name":"--lr-size-1-875rem","description":"**Shared design token** — Canonical shared component token for size 1 875rem. Reads `--lr-theme-size-1-875rem`."},{"name":"--lr-size-10px","description":"**Shared design token** — Canonical shared component token for size 10px. Reads `--lr-theme-size-10px`."},{"name":"--lr-size-10rem","description":"**Shared design token** — Canonical shared component token for size 10rem. Reads `--lr-theme-size-10rem`."},{"name":"--lr-size-12em","description":"**Shared design token** — Canonical shared component token for size 12em. Reads `--lr-theme-size-12em`."},{"name":"--lr-size-12rem","description":"**Shared design token** — Canonical shared component token for size 12rem. Reads `--lr-theme-size-12rem`."},{"name":"--lr-size-14px","description":"**Shared design token** — Canonical shared component token for size 14px. Reads `--lr-theme-size-14px`."},{"name":"--lr-size-14rem","description":"**Shared design token** — Canonical shared component token for size 14rem. Reads `--lr-theme-size-14rem`."},{"name":"--lr-size-15rem","description":"**Shared design token** — Canonical shared component token for size 15rem. Reads `--lr-theme-size-15rem`."},{"name":"--lr-size-16px","description":"**Shared design token** — Canonical shared component token for size 16px. Reads `--lr-theme-size-16px`."},{"name":"--lr-size-16rem","description":"**Shared design token** — Canonical shared component token for size 16rem. Reads `--lr-theme-size-16rem`."},{"name":"--lr-size-18rem","description":"**Shared design token** — Canonical shared component token for size 18rem. Reads `--lr-theme-size-18rem`."},{"name":"--lr-size-1em","description":"**Shared design token** — Canonical shared component token for size 1em. Reads `--lr-theme-size-1em`."},{"name":"--lr-size-1px","description":"**Shared design token** — Canonical shared component token for size 1px. Reads `--lr-theme-size-1px`."},{"name":"--lr-size-1rem","description":"**Shared design token** — Canonical shared component token for size 1rem. Reads `--lr-theme-size-1rem`."},{"name":"--lr-size-2-25rem","description":"**Shared design token** — Canonical shared component token for size 2 25rem. Reads `--lr-theme-size-2-25rem`."},{"name":"--lr-size-2-5ch","description":"**Shared design token** — Canonical shared component token for size 2 5ch. Reads `--lr-theme-size-2-5ch`."},{"name":"--lr-size-2-5rem","description":"**Shared design token** — Canonical shared component token for size 2 5rem. Reads `--lr-theme-size-2-5rem`."},{"name":"--lr-size-20rem","description":"**Shared design token** — Canonical shared component token for size 20rem. Reads `--lr-theme-size-20rem`."},{"name":"--lr-size-22rem","description":"**Shared design token** — Canonical shared component token for size 22rem. Reads `--lr-theme-size-22rem`."},{"name":"--lr-size-24px","description":"**Shared design token** — Canonical shared component token for size 24px. Reads `--lr-theme-size-24px`."},{"name":"--lr-size-24rem","description":"**Shared design token** — Canonical shared component token for size 24rem. Reads `--lr-theme-size-24rem`."},{"name":"--lr-size-280px","description":"**Shared design token** — Canonical shared component token for size 280px. Reads `--lr-theme-size-280px`."},{"name":"--lr-size-28px","description":"**Shared design token** — Canonical shared component token for size 28px. Reads `--lr-theme-size-28px`."},{"name":"--lr-size-28rem","description":"**Shared design token** — Canonical shared component token for size 28rem. Reads `--lr-theme-size-28rem`."},{"name":"--lr-size-2px","description":"**Shared design token** — Canonical shared component token for size 2px. Reads `--lr-theme-size-2px`."},{"name":"--lr-size-2rem","description":"**Shared design token** — Canonical shared component token for size 2rem. Reads `--lr-theme-size-2rem`."},{"name":"--lr-size-3-5em","description":"**Shared design token** — Canonical shared component token for size 3 5em. Reads `--lr-theme-size-3-5em`."},{"name":"--lr-size-3-5rem","description":"**Shared design token** — Canonical shared component token for size 3 5rem. Reads `--lr-theme-size-3-5rem`."},{"name":"--lr-size-30rem","description":"**Shared design token** — Canonical shared component token for size 30rem. Reads `--lr-theme-size-30rem`."},{"name":"--lr-size-32rem","description":"**Shared design token** — Canonical shared component token for size 32rem. Reads `--lr-theme-size-32rem`."},{"name":"--lr-size-36rem","description":"**Shared design token** — Canonical shared component token for size 36rem. Reads `--lr-theme-size-36rem`."},{"name":"--lr-size-38rem","description":"**Shared design token** — Canonical shared component token for size 38rem. Reads `--lr-theme-size-38rem`."},{"name":"--lr-size-3ch","description":"**Shared design token** — Canonical shared component token for size 3ch. Reads `--lr-theme-size-3ch`."},{"name":"--lr-size-3px","description":"**Shared design token** — Canonical shared component token for size 3px. Reads `--lr-theme-size-3px`."},{"name":"--lr-size-3rem","description":"**Shared design token** — Canonical shared component token for size 3rem. Reads `--lr-theme-size-3rem`."},{"name":"--lr-size-48rem","description":"**Shared design token** — Canonical shared component token for size 48rem. Reads `--lr-theme-size-48rem`."},{"name":"--lr-size-4ch","description":"**Shared design token** — Canonical shared component token for size 4ch. Reads `--lr-theme-size-4ch`."},{"name":"--lr-size-4px","description":"**Shared design token** — Canonical shared component token for size 4px. Reads `--lr-theme-size-4px`."},{"name":"--lr-size-4rem","description":"**Shared design token** — Canonical shared component token for size 4rem. Reads `--lr-theme-size-4rem`."},{"name":"--lr-size-5em","description":"**Shared design token** — Canonical shared component token for size 5em. Reads `--lr-theme-size-5em`."},{"name":"--lr-size-5rem","description":"**Shared design token** — Canonical shared component token for size 5rem. Reads `--lr-theme-size-5rem`."},{"name":"--lr-size-6ch","description":"**Shared design token** — Canonical shared component token for size 6ch. Reads `--lr-theme-size-6ch`."},{"name":"--lr-size-6em","description":"**Shared design token** — Canonical shared component token for size 6em. Reads `--lr-theme-size-6em`."},{"name":"--lr-size-6px","description":"**Shared design token** — Canonical shared component token for size 6px. Reads `--lr-theme-size-6px`."},{"name":"--lr-size-6rem","description":"**Shared design token** — Canonical shared component token for size 6rem. Reads `--lr-theme-size-6rem`."},{"name":"--lr-size-7rem","description":"**Shared design token** — Canonical shared component token for size 7rem. Reads `--lr-theme-size-7rem`."},{"name":"--lr-size-8em","description":"**Shared design token** — Canonical shared component token for size 8em. Reads `--lr-theme-size-8em`."},{"name":"--lr-size-8rem","description":"**Shared design token** — Canonical shared component token for size 8rem. Reads `--lr-theme-size-8rem`."},{"name":"--lr-size-neg-0-15rem","description":"**Shared design token** — Canonical shared component token for size neg 0 15rem. Reads `--lr-theme-size-neg-0-15rem`."},{"name":"--lr-size-neg-0-25rem","description":"**Shared design token** — Canonical shared component token for size neg 0 25rem. Reads `--lr-theme-size-neg-0-25rem`."},{"name":"--lr-size-neg-1px","description":"**Shared design token** — Canonical shared component token for size neg 1px. Reads `--lr-theme-size-neg-1px`."},{"name":"--lr-size-neg-4px","description":"**Shared design token** — Canonical shared component token for size neg 4px. Reads `--lr-theme-size-neg-4px`."},{"name":"--lr-size-neg-6px","description":"**Shared design token** — Canonical shared component token for size neg 6px. Reads `--lr-theme-size-neg-6px`."},{"name":"--lr-size-neg-8px","description":"**Shared design token** — Canonical shared component token for size neg 8px. Reads `--lr-theme-size-neg-8px`."},{"name":"--lr-skeleton-border-radius","description":"**`<lr-skeleton>`** (default: `var(--lr-radius)`) — Text/rectangle corner radius."},{"name":"--lr-skeleton-color","description":"**`<lr-skeleton>`** (default: `var(--lr-color-border)`) — Placeholder color."},{"name":"--lr-skeleton-h","description":"**`<lr-skeleton>`** (default: `var(--lr-size-1em)`) — Block size of the placeholder."},{"name":"--lr-skeleton-sheen-color","description":"**`<lr-skeleton>`** (default: `var(--lr-color-surface)`) — Sheen highlight color."},{"name":"--lr-skeleton-w","description":"**`<lr-skeleton>`** (default: `100%`) — Inline size of the placeholder."},{"name":"--lr-slider-gap","description":"**`<lr-slider>`** (default: `var(--lr-space-s)`) — Gap between the track row, value, label, references, and hint as they wrap."},{"name":"--lr-slider-row-size","description":"**`<lr-slider>`** (default: `calc(var(--lr-form-control-height) * 0.6)`) — Cross-axis extent of the control's interactive row: its block size when horizontal, its inline size when vertical. Scales off the shared form-control ladder, so a size tier moves it without a per-tier rule."},{"name":"--lr-slider-thumb-active-ring-color","description":"**`<lr-slider>`** (default: `var(--lr-slider-thumb-hover-ring-color)`) — Thumb ring while pressed."},{"name":"--lr-slider-thumb-bg","description":"**`<lr-slider>`** (default: `var(--lr-color-brand)`) — Resting thumb background."},{"name":"--lr-slider-thumb-border-color","description":"**`<lr-slider>`** (default: `var(--lr-color-surface)`) — Resting thumb border."},{"name":"--lr-slider-thumb-hover-ring-color","description":"**`<lr-slider>`** (default: `var(--lr-color-brand-quiet)`) — Thumb ring while hovered."},{"name":"--lr-slider-thumb-size","description":"**`<lr-slider>`** (default: `calc(var(--lr-form-control-height) * 0.4)`) — Diameter of each draggable handle, derived from the `size` tier's shared control height. The transparent drag area around it never drops below 1.75rem/28px, whatever this is set to."},{"name":"--lr-slider-tooltip-distance","description":"**`<lr-slider>`** (default: `8`) — Numeric CSS-pixel distance written by the `tooltipDistance` property for the internal tooltip-placement calculation."},{"name":"--lr-slider-track-length","description":"**`<lr-slider>`** (default: `var(--lr-size-10rem)`) — Length of the track in `orientation=\"vertical\"`; the horizontal track fills its container instead. Declared as an inline `var()` fallback (never on `:host`), so a consumer override at any ancestor wins."},{"name":"--lr-slider-track-thickness","description":"**`<lr-slider>`** (default: `calc(var(--lr-slider-thumb-size) * 0.25)`) — Thickness of the track, the filled indicator and (scaled from it) the `with-markers` ticks."},{"name":"--lr-source-card-bg","description":"**`<lr-source-card>`** (default: `var(--lr-color-surface)`) — Background of the RESTING `frame=\"card\"` chrome, the companion to the `compact` tier's existing padding/gap levers. `frame=\"plain\"` still drops the fill entirely."},{"name":"--lr-source-card-compact-gap","description":"**`<lr-source-card>`** (default: `var(--lr-space-2xs)`) — Gap between `[part=\"base\"]`'s rows while `compact`."},{"name":"--lr-source-card-compact-padding","description":"**`<lr-source-card>`** (default: `var(--lr-space-xs)`) — `[part=\"base\"]` padding while `compact`."},{"name":"--lr-source-picker-checked-bg","description":"**`<lr-source-picker>`** — Background of a fully-checked selection control: the `select-all` pill (defaults to `var(--lr-color-brand-quiet)`) and a fully-selected entry's `[part=\"checkbox\"]` (defaults to `var(--lr-color-brand)`). The two keep their distinct resting defaults; setting this prop unifies both."},{"name":"--lr-source-picker-checked-border","description":"**`<lr-source-picker>`** (default: `var(--lr-color-brand)`) — Border color of every checked or mixed selection control."},{"name":"--lr-source-picker-depth","description":"**`<lr-source-picker>`** (default: `0`) — Internal indent plumbing, not a retheming knob: the row's own nesting depth, written inline onto `[part=\"item\"]` as a plain number and multiplied by `--lr-source-picker-indent-size` to produce the indent."},{"name":"--lr-source-picker-indent-size","description":"**`<lr-source-picker>`** (default: `var(--lr-size-1-25rem)`) — Indent step added to `[part=\"item\"]`'s `padding-inline-start` per nesting level. The total indent is capped at `--lr-size-8rem` so a deeply nested tree cannot push its labels out of view."},{"name":"--lr-source-picker-mixed-bg","description":"**`<lr-source-picker>`** (default: `color-mix(in srgb, var(--lr-color-brand) 50%, var(--lr-color-surface))`) — Background of a partially-selected entry's `[part=\"checkbox\"]`."},{"name":"--lr-space-2xl","description":"**Shared design token** — Canonical shared component token for space 2xl. Reads `--lr-theme-space-2xl`."},{"name":"--lr-space-2xs","description":"**Shared design token** — Canonical shared component token for space 2xs. Reads `--lr-theme-space-2xs`."},{"name":"--lr-space-l","description":"**Shared design token** — Canonical shared component token for space l. Reads `--lr-theme-space-l`."},{"name":"--lr-space-m","description":"**Shared design token** — Canonical shared component token for space m. Reads `--lr-theme-space-m`."},{"name":"--lr-space-s","description":"**Shared design token** — Canonical shared component token for space s. Reads `--lr-theme-space-s`."},{"name":"--lr-space-xs","description":"**Shared design token** — Canonical shared component token for space xs. Reads `--lr-theme-space-xs`."},{"name":"--lr-span-waterfall-denied-color","description":"**`<lr-span-waterfall>`** (default: `var(--lr-color-warning)`) — Denied bar fill."},{"name":"--lr-span-waterfall-error-color","description":"**`<lr-span-waterfall>`** (default: `var(--lr-color-danger)`) — Error bar fill."},{"name":"--lr-span-waterfall-name-width","description":"**`<lr-span-waterfall>`** (default: `8rem`) — Width of the name gutter column."},{"name":"--lr-span-waterfall-pending-border-color","description":"**`<lr-span-waterfall>`** (default: `var(--lr-color-border-strong)`) — Pending bar border."},{"name":"--lr-span-waterfall-row-active-bg","description":"**`<lr-span-waterfall>`** (default: `var(--lr-color-brand-quiet)`) — Background of the active (`activeSpanId`) row. Shadow Parts forbids an attribute selector after `::part()`, so the active row could otherwise only be restyled by hijacking the library-wide `--lr-color-brand-quiet` token."},{"name":"--lr-span-waterfall-running-color","description":"**`<lr-span-waterfall>`** (default: `var(--lr-color-brand)`) — Running stripe foreground."},{"name":"--lr-span-waterfall-running-stripe-color","description":"**`<lr-span-waterfall>`** (default: `var(--lr-color-brand-quiet)`) — Running stripe background."},{"name":"--lr-span-waterfall-stripe-speed","description":"**`<lr-span-waterfall>`** (default: `var(--lr-duration-ambient)`) — Animation duration for a `running` span's striped bar. The fallback is the bare-duration `--lr-duration-ambient`, not the `--lr-transition-ambient` duration+easing shorthand, which would be invalid in an `animation-duration` slot."},{"name":"--lr-span-waterfall-success-color","description":"**`<lr-span-waterfall>`** (default: `var(--lr-color-success)`) — Success bar fill."},{"name":"--lr-sparkline-stroke-width","description":"**`<lr-sparkline>`** (default: `var(--lr-border-width-medium)`) — Compatibility alias used as the fallback for `--line-width`."},{"name":"--lr-spinner-duration","description":"**`<lr-spinner>`** (default: `var(--lr-transition-ambient)`) — Duration/easing of one rotation. Not read under `prefers-reduced-motion: reduce`, where the animation is disabled entirely."},{"name":"--lr-spinner-size","description":"**`<lr-spinner>`** (default: `var(--lr-size-1-25rem)`) — Outer diameter of the indicator."},{"name":"--lr-spinner-track-width","description":"**`<lr-spinner>`** (default: `var(--lr-border-width-medium)`) — Thickness of the ring track."},{"name":"--lr-split-panel-divider-active-color","description":"**`<lr-split-panel>`** (default: `var(--lr-color-border-strong)`) — Background of `divider` while being dragged (or focused and pressed via the keyboard)."},{"name":"--lr-split-panel-divider-hit-area","description":"**`<lr-split-panel>`** (default: `var(--divider-hit-area)`) — Lyra-prefixed hit-area alias."},{"name":"--lr-split-panel-divider-hover-color","description":"**`<lr-split-panel>`** (default: `var(--lr-color-brand)`) — Background of `divider` on hover/keyboard focus, independent of any other component's own hover token that happens to default to the same shared brand color."},{"name":"--lr-split-panel-divider-width","description":"**`<lr-split-panel>`** (default: `var(--divider-width)`) — Lyra-prefixed divider-width alias."},{"name":"--lr-split-panel-max","description":"**`<lr-split-panel>`** (default: `var(--max)`) — Lyra-prefixed maximum-size alias."},{"name":"--lr-split-panel-min","description":"**`<lr-split-panel>`** (default: `var(--min)`) — Lyra-prefixed minimum-size alias."},{"name":"--lr-spreadsheet-viewer-highlight-color","description":"**`<lr-spreadsheet-viewer>`** (default: `var(--lr-color-brand)`) — Outline color of a highlighted cell. The active highlight changes a private warning-color default; an inherited or direct public value remains authoritative."},{"name":"--lr-spreadsheet-viewer-highlight-outline-offset","description":"**`<lr-spreadsheet-viewer>`** (default: `calc(-1 * var(--lr-border-width-medium))`) — Outline offset of a highlighted cell."},{"name":"--lr-spreadsheet-viewer-max-height","description":"**`<lr-spreadsheet-viewer>`** (default: `none`) — Maximum block size of `[part=\"body\"]` before it scrolls internally. The `maxHeight` property sets this token inline on `[part=\"base\"]`."},{"name":"--lr-stack-trace-background","description":"**`<lr-stack-trace>`** (default: `var(--lr-color-surface)`) — Fill of the outer card (`[part=\"base\"]`) while `frame=\"card\"`. `frame=\"plain\"` still removes the fill entirely."},{"name":"--lr-stack-trace-border-color","description":"**`<lr-stack-trace>`** (default: `var(--lr-color-border)`) — Colour of the outer card's border."},{"name":"--lr-stack-trace-compact-gap","description":"**`<lr-stack-trace>`** (default: `var(--lr-space-2xs)`) — Space below `[part=\"message\"]` and between `[part=\"group\"]`s while `compact`."},{"name":"--lr-stack-trace-compact-padding","description":"**`<lr-stack-trace>`** (default: `var(--lr-space-2xs)`) — `[part=\"base\"]` padding while `compact`. Overridden entirely by `frame=\"plain\"`."},{"name":"--lr-stack-trace-font","description":"**`<lr-stack-trace>`** (default: `var(--lr-font-mono)`) — Font family for the parsed frames and the verbatim raw fallback."},{"name":"--lr-stack-trace-interactive-color","description":"**`<lr-stack-trace>`** (default: `var(--lr-color-brand)`) — Interactive frame/toggle accent."},{"name":"--lr-stack-trace-internal-frame-color","description":"**`<lr-stack-trace>`** (default: `var(--lr-color-text-quiet)`) — Internal frame foreground."},{"name":"--lr-stack-trace-max-height","description":"**`<lr-stack-trace>`** (default: `none`) — Cap on how tall `[part=\"base\"]` grows before it scrolls internally. `none` lets the component grow with its content; the `max-height` attribute sets this token."},{"name":"--lr-stack-trace-radius","description":"**`<lr-stack-trace>`** (default: `var(--lr-radius)`) — Corner radius of the outer card. `frame=\"plain\"` still squares the corners."},{"name":"--lr-stat-bg","description":"**`<lr-stat>`** (default: `var(--lr-color-surface)`) — Resting background of the card. The pressed fill of a linked card mixes from this value too, so one override retints both. `frame=\"plain\"` still paints transparent."},{"name":"--lr-stat-emphasis-border-color","description":"**`<lr-stat>`** (default: `var(--lr-color-brand)`) — Accent-edge color when `emphasis` is set. Independent of the headline's emphasis tint and `brand` variant."},{"name":"--lr-stat-emphasis-value-color","description":"**`<lr-stat>`** (default: `var(--lr-color-brand)`) — Headline value color when `emphasis` is set on a neutral stat. Independent of the accent edge and `brand` variant."},{"name":"--lr-stat-gap","description":"**`<lr-stat>`** (default: `var(--lr-space-xs)`) — Gap between the card's stacked parts, read by both `[part=\"base\"]` and the linked-card content wrapper. The `compact` variant reads the same property with its own current default (`var(--lr-size-0-125rem)`) as its fallback."},{"name":"--lr-stat-link-active-bg","description":"**`<lr-stat>`** (default: `color-mix(...)`) — Linked-card background while pressed."},{"name":"--lr-stat-link-active-border-color","description":"**`<lr-stat>`** (default: `var(--lr-stat-link-hover-border-color,var(--lr-color-brand))`) — Linked-card border while pressed."},{"name":"--lr-stat-link-active-shadow","description":"**`<lr-stat>`** (default: `var(--lr-stat-link-hover-shadow,var(--lr-shadow-s))`) — Linked-card shadow while pressed."},{"name":"--lr-stat-link-hover-border-color","description":"**`<lr-stat>`** (default: `var(--lr-color-brand)`) — Linked-card border on hover."},{"name":"--lr-stat-link-hover-shadow","description":"**`<lr-stat>`** (default: `var(--lr-shadow-s)`) — Linked-card shadow on hover."},{"name":"--lr-stat-padding","description":"**`<lr-stat>`** (default: `var(--lr-space-m)`) — Padding of the card, read by both `[part=\"base\"]` and the linked-card content wrapper so a linked and unlinked stat never drift. The `compact` and `frame=\"plain\"` variants read the same property with their own current default as its fallback (`var(--lr-space-s)` and `0` respectively), so one override reaches every rendering path."},{"name":"--lr-stat-trend-bad-bg","description":"**`<lr-stat>`** (default: `color-mix(in srgb, var(--lr-color-danger) 8%, transparent)`) — Background of the trend pill when its polarity is \"bad\"."},{"name":"--lr-stat-trend-bad-color","description":"**`<lr-stat>`** (default: `var(--lr-color-danger)`) — Text color of the trend pill when its polarity is \"bad\". Independent of the headline value's `variant=\"danger\"` tint, which reads the shared `--lr-color-danger` token directly."},{"name":"--lr-stat-trend-good-bg","description":"**`<lr-stat>`** (default: `color-mix(in srgb, var(--lr-color-success) 8%, transparent)`) — Background of the trend pill when its polarity is \"good\"."},{"name":"--lr-stat-trend-good-color","description":"**`<lr-stat>`** (default: `var(--lr-color-success)`) — Text color of the trend pill when its polarity is \"good\". Independent of the headline value's `variant=\"success\"` tint, which reads the shared `--lr-color-success` token directly."},{"name":"--lr-stat-value-brand-color","description":"**`<lr-stat>`** (default: `var(--lr-color-brand)`) — Headline value color for the `brand` variant."},{"name":"--lr-stat-value-danger-color","description":"**`<lr-stat>`** (default: `var(--lr-color-danger)`) — Headline value color for the `danger` variant."},{"name":"--lr-stat-value-success-color","description":"**`<lr-stat>`** (default: `var(--lr-color-success)`) — Headline value color for the `success` variant."},{"name":"--lr-stat-value-warning-color","description":"**`<lr-stat>`** (default: `var(--lr-color-warning)`) — Headline value color for the `warning` variant."},{"name":"--lr-stepper-active-bg","description":"**`<lr-stepper>`** (default: `color-mix(in oklab, var(--lr-color-brand-quiet), var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Background of a pressed, non-disabled step."},{"name":"--lr-stepper-active-color","description":"**`<lr-stepper>`** (default: `var(--lr-color-text)`) — Text color of a pressed, non-disabled step."},{"name":"--lr-stepper-current-color","description":"**`<lr-stepper>`** (default: `var(--lr-color-text)`) — Text color of the `current` step. Declared as an inline `var()` fallback (never on `:host`), so setting it on the element or an ancestor recolors only the current step without hijacking the library-wide `--lr-color-text` token."},{"name":"--lr-stepper-current-font-weight","description":"**`<lr-stepper>`** (default: `var(--lr-font-weight-semibold)`) — Font weight of the `current` step's label. `::part(step)[data-state='current']` is invalid CSS (an attribute selector cannot follow `::part`), so this is the only way to change just the current step's boldness without hijacking the library-wide `--lr-font-weight-semibold` token."},{"name":"--lr-stepper-current-index-bg","description":"**`<lr-stepper>`** (default: `var(--lr-color-brand)`) — Background of the `current` step's numbered index chip (`step-index`)."},{"name":"--lr-stepper-current-index-color","description":"**`<lr-stepper>`** (default: `var(--lr-color-on-brand)`) — Text color of the `current` step's numbered index chip."},{"name":"--lr-stepper-error-color","description":"**`<lr-stepper>`** (default: `var(--lr-color-danger)`) — Text color of an `error` step."},{"name":"--lr-stepper-hover-bg","description":"**`<lr-stepper>`** (default: `var(--lr-color-brand-quiet)`) — Background of a hovered, non-disabled step."},{"name":"--lr-stepper-hover-color","description":"**`<lr-stepper>`** (default: `var(--lr-color-text)`) — Text color of a hovered, non-disabled step."},{"name":"--lr-stream-status-dot-color","description":"**`<lr-stream-status>`** (default: `var(--lr-color-text-quiet)`) — `indicator` dot color. Its private default changes with reflected `connection-state` and the component-owned `data-stalled` state: `var(--lr-color-brand)` for `connecting`/`streaming`, `var(--lr-color-warning)` for `stalled`. Set it on the element or any ancestor; an element value wins."},{"name":"--lr-stream-status-dot-opacity","description":"**`<lr-stream-status>`** (default: `0.35`) — `indicator` dot opacity. Its private default changes with those same host states: `0.6` for `connecting`, `1` for `streaming` and `stalled`. Set it on the element or any ancestor; an element value wins."},{"name":"--lr-stream-status-message-color","description":"**`<lr-stream-status>`** (default: `var(--lr-color-warning)`) — `phase` and `message` text color while `data-stalled` is present. Decoupled from `--lr-stream-status-stalled-border-color` even though both fall back to the same shared token today."},{"name":"--lr-stream-status-stalled-bg","description":"**`<lr-stream-status>`** (default: `var(--lr-color-warning-quiet)`) — `base` row background while `data-stalled` is present."},{"name":"--lr-stream-status-stalled-border-color","description":"**`<lr-stream-status>`** (default: `var(--lr-color-warning)`) — `base` row border color while `data-stalled` is present."},{"name":"--lr-subagent-panel-background","description":"**`<lr-subagent-panel>`** (default: `var(--lr-color-surface)`) — Resting fill of each run row's trigger and action buttons. Hover and press follow `--lr-subagent-panel-hover-background`, so retune both together."},{"name":"--lr-subagent-panel-border-color","description":"**`<lr-subagent-panel>`** (default: `var(--lr-color-border)`) — Colour of each run row's border and of its action divider. A selected row still uses `--lr-subagent-panel-selected-border`."},{"name":"--lr-subagent-panel-compact-action-padding","description":"**`<lr-subagent-panel>`** (default: `var(--lr-space-2xs)`) — `[part=\"cancel\"]`/ `[part=\"retry\"]` padding while `compact`."},{"name":"--lr-subagent-panel-compact-font-size","description":"**`<lr-subagent-panel>`** (default: `var(--lr-font-size-2xs)`) — `[part=\"task\"]`/ `[part=\"model\"]` font size while `compact`."},{"name":"--lr-subagent-panel-compact-trigger-gap","description":"**`<lr-subagent-panel>`** (default: `var(--lr-space-2xs)`) — Gap between `[part=\"run-trigger\"]`'s label/status/task/model/progress while `compact`."},{"name":"--lr-subagent-panel-compact-trigger-padding","description":"**`<lr-subagent-panel>`** (default: `var(--lr-space-2xs) var(--lr-space-s)`) — `[part=\"run-trigger\"]` padding while `compact`."},{"name":"--lr-subagent-panel-hover-background","description":"**`<lr-subagent-panel>`** (default: `var(--lr-color-surface-raised)`) — Hovered fill of each run row's trigger and action buttons. The pressed fill is this value mixed a further `--lr-color-mix-active` toward `--lr-color-mix-partner`, so retuning hover carries the press with it."},{"name":"--lr-subagent-panel-progress-fill","description":"**`<lr-subagent-panel>`** (default: `var(--lr-color-brand)`) — Progress fill."},{"name":"--lr-subagent-panel-progress-track","description":"**`<lr-subagent-panel>`** (default: `var(--lr-color-border)`) — Progress track."},{"name":"--lr-subagent-panel-radius","description":"**`<lr-subagent-panel>`** (default: `var(--lr-radius)`) — Corner radius of each run row. `frame=\"plain\"` still squares the corners."},{"name":"--lr-subagent-panel-selected-border","description":"**`<lr-subagent-panel>`** (default: `var(--lr-color-brand)`) — Selected run border."},{"name":"--lr-suggestion-chips-disabled-opacity","description":"**`<lr-suggestion-chips>`** (default: `0.5`) — Opacity of a chip whose suggestion sets `disabled`."},{"name":"--lr-suggestion-chips-hover-bg","description":"**`<lr-suggestion-chips>`** (default: `var(--lr-color-brand-quiet)`) — Background of a hovered chip."},{"name":"--lr-suggestion-chips-hover-border","description":"**`<lr-suggestion-chips>`** (default: `var(--lr-color-brand)`) — Border color of a hovered chip."},{"name":"--lr-suggestion-chips-justify","description":"**`<lr-suggestion-chips>`** (default: `flex-start`) — Main-axis packing of the chip row. `center` centers every line, the wrapped final one included — what `::part(base)` alone cannot do."},{"name":"--lr-svg-viewer-active-border","description":"**`<lr-svg-viewer>`** (default: `var(--lr-color-warning, var(--lr-color-brand))`) — Border color of the `[part=\"region-highlight\"]` matching `activeHighlightId`. Distinct from the resting highlight border, so the active region can be recolored without touching the rest."},{"name":"--lr-svg-viewer-highlight-accent-color","description":"**`<lr-svg-viewer>`** (default: `var(--lr-color-brand)`) — Accent highlight border and hover tint."},{"name":"--lr-svg-viewer-highlight-danger-color","description":"**`<lr-svg-viewer>`** (default: `var(--lr-color-danger)`) — Danger highlight border and hover tint."},{"name":"--lr-svg-viewer-highlight-neutral-color","description":"**`<lr-svg-viewer>`** (default: `var(--lr-color-neutral)`) — Neutral highlight border and hover tint."},{"name":"--lr-svg-viewer-highlight-success-color","description":"**`<lr-svg-viewer>`** (default: `var(--lr-color-success)`) — Success highlight border and hover tint."},{"name":"--lr-svg-viewer-highlight-warning-color","description":"**`<lr-svg-viewer>`** (default: `var(--lr-color-warning)`) — Warning highlight border and hover tint."},{"name":"--lr-svg-viewer-max-height","description":"**`<lr-svg-viewer>`** (default: `none`) — Maximum block size of the scrollable body before it scrolls internally. Also settable via the `max-height` property."},{"name":"--lr-swatch-picker-fill-size","description":"**`<lr-swatch-picker>`** (default: `var(--lr-theme-swatch-picker-fill-size, var(--lr-size-1-5rem))`) — Visible fill/icon diameter for the swatch. Its private default follows the active tier. Set `--lr-theme-swatch-picker-fill-size` on an ancestor to give every tier a shared default, or set this component hook on an ancestor/direct host to override every tier."},{"name":"--lr-swatch-picker-gap","description":"**`<lr-swatch-picker>`** (default: `var(--lr-space-xs)`) — Gap between swatches."},{"name":"--lr-swatch-picker-gemstone-selected-blur","description":"**`<lr-swatch-picker>`** (default: `var(--lr-gemstone-selected-blur, var(--lr-size-0-5rem))`) — Selected glow blur used by `mode=\"gemstone\"` when `--lr-swatch-picker-selected-blur` is not overridden. Applies to a plain color-fill swatch and to a consumer-supplied `icon` override; the automatic gemstone glyph itself is themed by `--lr-gemstone-selected-blur` directly (see `theme/gemstones.js`'s `gemstoneSelectedGlyphStyles`), which this hook's own default now aliases so the two cannot silently drift apart."},{"name":"--lr-swatch-picker-gemstone-shine-duration","description":"**`<lr-swatch-picker>`** (default: `var(--lr-gemstone-selected-shine-duration, var(--lr-transition-ambient))`) — Selected shine timing used by `mode=\"gemstone\"` when `--lr-swatch-picker-shine-duration` is not overridden. Same scope and aliasing as `--lr-swatch-picker-gemstone-selected-blur` above."},{"name":"--lr-swatch-picker-hit-size","description":"**`<lr-swatch-picker>`** (default: `var(--lr-size-2-5rem)`) — Hit-area size (both min-inline-size and min-block-size) for the swatch button. Its private default follows the active tier and is floored at 24px; an inherited or direct public value wins."},{"name":"--lr-swatch-picker-selected-blur","description":"**`<lr-swatch-picker>`** (default: `0`) — Blur radius of that same ring. 0 by default (a crisp ring); set a real length (e.g. 0.4rem) for a soft glow instead."},{"name":"--lr-swatch-picker-selected-color","description":"**`<lr-swatch-picker>`** (default: `var(--lr-color-brand)`) — Ring color drawn around the selected swatch, themeable independently of the focus ring and every other ring color."},{"name":"--lr-swatch-picker-shine-duration","description":"**`<lr-swatch-picker>`** (default: `0s`) — Duration of a rhythmic brighten-and-settle \"shine\" on the selected swatch. `0s` (the default) is a no-op -- today's static look for every existing consumer. Set a real duration (e.g. 1.6s) for a pulsing shine; disabled outright under `prefers-reduced-motion: reduce`. Independent of `--lr-swatch-picker-selected-blur` (a separate `filter: brightness()` animation, not `box-shadow`), so the two compose freely, and works identically for a plain color circle and an icon swatch alike."},{"name":"--lr-swatch-picker-wrap","description":"**`<lr-swatch-picker>`** (default: `wrap`) — `flex-wrap` on the swatch row. Reproduces today's hardcoded wrapping row by default; set `nowrap` to confine every swatch to a single row (e.g. inside a fixed-width popover panel whose height must not shift from a second row)."},{"name":"--lr-switch-checked-label-color","description":"**`<lr-switch>`** (default: `var(--lr-switch-label-color)`) — Text color of `[part='label']` while checked, independently themeable from the unchecked color."},{"name":"--lr-switch-checked-thumb-fill","description":"**`<lr-switch>`** (default: `var(--lr-switch-thumb-fill)`) — Thumb fill while checked, independently themeable from the unchecked fill."},{"name":"--lr-switch-checked-track-border","description":"**`<lr-switch>`** (default: `var(--lr-switch-track-border)`) — Border of `[part='track']` while checked, independently themeable from the unchecked border, so a bordered track can differ by state without reaching for `::part(track)` plus the `checked` custom state. Takes a whole `border` shorthand value, like `--lr-switch-track-border`; give both states the same border *width* unless a size change between them is what you want, since the track is `box-sizing: content-box` and a border grows its outer footprint."},{"name":"--lr-switch-checked-track-fill","description":"**`<lr-switch>`** (default: `var(--lr-color-brand)`) — Track fill while checked."},{"name":"--lr-switch-gap","description":"**`<lr-switch>`** (default: `var(--lr-space-s)`) — Gap between the track and label."},{"name":"--lr-switch-label-color","description":"**`<lr-switch>`** (default: `var(--lr-color-text)`) — Text color of `[part='label']`, and the checked-state fallback when `--lr-switch-checked-label-color` is unset."},{"name":"--lr-switch-thumb-fill","description":"**`<lr-switch>`** (default: `var(--lr-color-surface)`) — Thumb fill while unchecked, and the checked-state fallback when `--lr-switch-checked-thumb-fill` is unset."},{"name":"--lr-switch-thumb-offset","description":"**`<lr-switch>`** (default: `var(--lr-size-2px)`) — Inset of the thumb from the track's edges."},{"name":"--lr-switch-track-active-fill","description":"**`<lr-switch>`** (default: `color-mix(...)`) — Track fill while pressed."},{"name":"--lr-switch-track-block-size","description":"**`<lr-switch>`** (default: `calc(var(--lr-form-control-height) * 0.5)`) — Block size of the track, half the `size` tier's shared control height; the thumb's diameter is derived from it minus twice `--lr-switch-thumb-offset`."},{"name":"--lr-switch-track-border","description":"**`<lr-switch>`** — Border of `[part='track']`, and the checked-state fallback when `--lr-switch-checked-track-border` is unset. Undeclared by default (no border renders at all), matching today's chrome."},{"name":"--lr-switch-track-fill","description":"**`<lr-switch>`** (default: `var(--lr-color-border)`) — Resting fill of `[part='track']`, used as the source for the hover and press fallbacks."},{"name":"--lr-switch-track-hover-fill","description":"**`<lr-switch>`** (default: `color-mix(...)`) — Track fill while hovered."},{"name":"--lr-switch-track-inline-size","description":"**`<lr-switch>`** (default: `calc(var(--lr-switch-track-block-size) * 1.8)`) — Inline size of the track, and (with the block size) the distance the thumb travels when checked. Derived from the block size, so re-sizing the track keeps its aspect ratio."},{"name":"--lr-tab-group-active-bg","description":"**`<lr-tab-group>`** (default: `color-mix(in oklab, transparent, var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Background of a pressed, non-disabled tab."},{"name":"--lr-tab-group-active-color","description":"**`<lr-tab-group>`** (default: `var(--lr-tab-group-hover-color, var(--lr-color-text))`) — Text color of a pressed, non-disabled tab."},{"name":"--lr-tab-group-hover-color","description":"**`<lr-tab-group>`** (default: `var(--lr-color-text)`) — Text color of a hovered, non-disabled tab. Independent of the selected-state props above. Pressed-tab and scroll-control hooks use inline `var()` fallbacks rather than a `:host` declaration, so they inherit from the group or any ancestor without retheming the other states."},{"name":"--lr-tab-group-indicator-color","description":"**`<lr-tab-group>`** (default: `var(--lr-color-brand)`) — Color of the selected tab's underline, themeable independently of its text color."},{"name":"--lr-tab-group-panel-hover-outline-color","description":"**`<lr-tab-group>`** (default: `var(--lr-color-border)`) — Outline color of the mouse-hover preview on `[part=\"panel\"]`. Set to `transparent` to opt out of the hover treatment entirely."},{"name":"--lr-tab-group-panel-hover-outline-offset","description":"**`<lr-tab-group>`** (default: `var(--lr-focus-ring-offset)`) — Offset of the mouse-hover preview on `[part=\"panel\"]`."},{"name":"--lr-tab-group-panel-hover-outline-style","description":"**`<lr-tab-group>`** (default: `solid`) — Outline style of the mouse-hover preview on `[part=\"panel\"]`."},{"name":"--lr-tab-group-panel-hover-outline-width","description":"**`<lr-tab-group>`** (default: `var(--lr-border-width-thin)`) — Outline width of the mouse-hover preview on `[part=\"panel\"]`."},{"name":"--lr-tab-group-scroll-button-active-bg","description":"**`<lr-tab-group>`** (default: `color-mix(in oklab, transparent, var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Background of a pressed overflow scroll control."},{"name":"--lr-tab-group-scroll-button-active-color","description":"**`<lr-tab-group>`** (default: `var(--lr-color-text)`) — Text color of a pressed overflow scroll control."},{"name":"--lr-tab-group-scroll-button-hover-color","description":"**`<lr-tab-group>`** (default: `var(--lr-color-text)`) — Text color of a hovered overflow scroll control."},{"name":"--lr-tab-group-selected-color","description":"**`<lr-tab-group>`** (default: `var(--lr-color-brand)`) — Text color of the selected tab. Scoped to `[aria-selected='true']` only, so it never repaints a hovered unselected tab (which is what hijacking `--lr-color-brand` library-wide used to do)."},{"name":"--lr-tab-group-vertical-nav-max-inline-size","description":"**`<lr-tab-group>`** (default: `var(--lr-size-12rem)`) — Maximum logical inline size of a vertical `start`/`end` nav. Long labels ellipsize inside that bound so the panel remains usable at narrow allocations."},{"name":"--lr-table-cell-color","description":"**`<lr-table>`** (default: `inherit`) — Text colour of body cells; inherits the host's own colour by default."},{"name":"--lr-table-cell-link-color","description":"**`<lr-table>`** (default: `var(--lr-color-brand)`) — Colour of an anchor returned from a column's `cell(row)`. Such an anchor renders inside this component's shadow root, so page CSS cannot reach it and `::part()` cannot select past the first compound selector to reach it either; without this hook it computes to the UA default link blue. Set `revert` for the UA default."},{"name":"--lr-table-cell-link-hover-color","description":"**`<lr-table>`** (default: `var(--lr-table-cell-link-color,var(--lr-color-brand))`) — Colour of that anchor on hover and `:focus-visible`, which also thicken its underline."},{"name":"--lr-table-cell-padding","description":"**`<lr-table>`** (default: `var(--lr-space-s)`) — Padding of a header cell, a body cell, and the row-total cell."},{"name":"--lr-table-cell-padding-compact","description":"**`<lr-table>`** (default: `var(--lr-space-xs) var(--lr-space-s)`) — Padding of a group-header cell and a footer cell, which default to a tighter block/inline shorthand than `--lr-table-cell-padding` rather than sharing it outright."},{"name":"--lr-table-font-size","description":"**`<lr-table>`** (default: `inherit`) — Font size of the `<table>` element and, through normal inheritance, every cell inside it. The rest of the font shorthand (family, weight, etc.) keeps inheriting from the host regardless of this override."},{"name":"--lr-table-header-sorted-bg","description":"**`<lr-table>`** (default: `var(--lr-color-surface)`) — Background of the currently-sorted column's header cell (`[aria-sort]` other than `none`), including a `sticky` column's own header cell. Same rationale as `--lr-table-row-selected-bg`: `::part(header-cell)[aria-sort]` is invalid CSS, so this token is the supported way to recolor the sorted header without hijacking a library-wide token."},{"name":"--lr-table-header-sorted-color","description":"**`<lr-table>`** (default: `inherit`) — Text color of the currently-sorted column's header cell."},{"name":"--lr-table-heat-t","description":"**`<lr-table>`** — This cell's position on the heat-tint ramp, as a percentage string. Set inline by the component on each `[data-heat]` cell; not consumer-settable."},{"name":"--lr-table-heat-tint-hi","description":"**`<lr-table>`** (default: `var(--lr-color-brand)`) — High endpoint of the heat-tint ramp used by `heatValue` columns. Inherits from theme ancestors."},{"name":"--lr-table-heat-tint-lo","description":"**`<lr-table>`** (default: `var(--lr-color-brand-quiet)`) — Low endpoint of the heat-tint ramp used by `heatValue` columns. Inherits from theme ancestors."},{"name":"--lr-table-max-height","description":"**`<lr-table>`** (default: `none`) — Cap on the scroll container's block size, past which the table body scrolls."},{"name":"--lr-table-resize-handle-active-bg","description":"**`<lr-table>`** (default: `var(--lr-table-resize-handle-hover-bg,var(--lr-color-brand))`) — Resize-handle pressed background."},{"name":"--lr-table-resize-handle-active-opacity","description":"**`<lr-table>`** (default: `calc(var(--lr-table-resize-handle-hover-opacity,var(--lr-table-resize-handle-opacity,0.12))*2)`) — Resize-handle pressed opacity."},{"name":"--lr-table-resize-handle-hover-bg","description":"**`<lr-table>`** (default: `var(--lr-color-brand)`) — Resize-handle hover/focus background."},{"name":"--lr-table-resize-handle-hover-opacity","description":"**`<lr-table>`** (default: `var(--lr-table-resize-handle-opacity,0.12)`) — Resize-handle hover/focus opacity."},{"name":"--lr-table-resize-handle-opacity","description":"**`<lr-table>`** (default: `0.12`) — Hover/focus opacity of the resize handle. Legacy shared-state hook; inherits from theme ancestors."},{"name":"--lr-table-resize-min-width","description":"**`<lr-table>`** (default: `var(--lr-size-3rem)`) — Default minimum width for a resizable column without an explicit pixel `minWidth`. Inherits from theme ancestors."},{"name":"--lr-table-row-selected-bg","description":"**`<lr-table>`** (default: `var(--lr-color-brand-quiet)`) — Background of a row whose `aria-selected` is `true`, including that row's own `sticky` column cell -- a sticky cell otherwise paints its own opaque surface and would hide the selected fill. Shadow Parts forbids an attribute selector after `::part()`, so `::part(row)[aria-selected]` is invalid CSS and the selected row could otherwise only be restyled by hijacking the library-wide `--lr-color-brand-quiet` token."},{"name":"--lr-table-row-stripe-bg","description":"**`<lr-table>`** (default: `transparent`) — Background of alternating body rows, including each row's own `sticky` column cell. The token is read only on rows carrying the internal stripe marker, so it can be set on the table or an ancestor without affecting group, expanded, hover, or selected rows."},{"name":"--lr-table-sticky-offset","description":"**`<lr-table>`** (default: `0`) — Distance a `sticky` column pins from the inline edge. Measured and set inline per column by the component so multiple sticky columns stack instead of overlapping; falls back to `0` for the first one, or before the first measurement pass."},{"name":"--lr-tag-remove-hover-background","description":"**`<lr-tag>`** (default: `color-mix(in srgb, currentColor 16%, transparent)`) — Background of the remove button on hover."},{"name":"--lr-tag-remove-radius","description":"**`<lr-tag>`** (default: `var(--lr-badge-radius)`) — Corner radius of the remove button, defaulting to the tag's own corner so retuning one retunes both."},{"name":"--lr-task-list-background","description":"**`<lr-task-list>`** (default: `var(--lr-color-surface)`) — Fill of the outer card (`[part=\"base\"]`) while `frame=\"card\"`. `frame=\"plain\"` still removes the fill entirely."},{"name":"--lr-task-list-border-color","description":"**`<lr-task-list>`** (default: `var(--lr-color-border)`) — Colour of the outer card's border and of the header/body divider, which `frame=\"plain\"` keeps."},{"name":"--lr-task-list-compact-body-padding","description":"**`<lr-task-list>`** (default: `var(--lr-space-2xs) var(--lr-space-s) var(--lr-space-s)`) — `[part=\"body\"]` padding while `compact`."},{"name":"--lr-task-list-compact-gap","description":"**`<lr-task-list>`** (default: `var(--lr-space-2xs)`) — Gap between `[part=\"body\"]`'s item rows while `compact`."},{"name":"--lr-task-list-compact-header-font-size","description":"**`<lr-task-list>`** (default: `var(--lr-font-size-sm)`) — `[part=\"header\"]` font size while `compact`."},{"name":"--lr-task-list-compact-header-gap","description":"**`<lr-task-list>`** (default: `var(--lr-space-2xs)`) — Gap between `[part=\"header\"]`'s toggle/label/summary while `compact`."},{"name":"--lr-task-list-compact-header-padding","description":"**`<lr-task-list>`** (default: `var(--lr-space-2xs) var(--lr-space-s)`) — `[part=\"header\"]` padding while `compact`."},{"name":"--lr-task-list-error-color","description":"**`<lr-task-list>`** (default: `var(--lr-color-danger)`) — Error status icon color."},{"name":"--lr-task-list-pending-color","description":"**`<lr-task-list>`** (default: `var(--lr-color-text-quiet)`) — Pending status icon color."},{"name":"--lr-task-list-radius","description":"**`<lr-task-list>`** (default: `var(--lr-radius)`) — Corner radius of the outer card. `frame=\"plain\"` still squares the corners."},{"name":"--lr-task-list-running-color","description":"**`<lr-task-list>`** (default: `var(--lr-color-brand)`) — Running status icon color."},{"name":"--lr-task-list-spin","description":"**`<lr-task-list>`** (default: `var(--lr-transition-ambient)`) — Running-status icon spin animation duration/timing."},{"name":"--lr-task-list-success-color","description":"**`<lr-task-list>`** (default: `var(--lr-color-success)`) — Success status icon color."},{"name":"--lr-terminal-bg-black","description":"**Shared design token** — Canonical shared component token for terminal bg black. Reads `--lr-theme-terminal-bg-black`."},{"name":"--lr-terminal-bg-blue","description":"**Shared design token** — Canonical shared component token for terminal bg blue. Reads `--lr-theme-terminal-bg-blue`."},{"name":"--lr-terminal-bg-bright-black","description":"**Shared design token** — Canonical shared component token for terminal bg bright black. Reads `--lr-theme-terminal-bg-bright-black`."},{"name":"--lr-terminal-bg-bright-blue","description":"**Shared design token** — Canonical shared component token for terminal bg bright blue. Reads `--lr-theme-terminal-bg-bright-blue`."},{"name":"--lr-terminal-bg-bright-cyan","description":"**Shared design token** — Canonical shared component token for terminal bg bright cyan. Reads `--lr-theme-terminal-bg-bright-cyan`."},{"name":"--lr-terminal-bg-bright-green","description":"**Shared design token** — Canonical shared component token for terminal bg bright green. Reads `--lr-theme-terminal-bg-bright-green`."},{"name":"--lr-terminal-bg-bright-magenta","description":"**Shared design token** — Canonical shared component token for terminal bg bright magenta. Reads `--lr-theme-terminal-bg-bright-magenta`."},{"name":"--lr-terminal-bg-bright-red","description":"**Shared design token** — Canonical shared component token for terminal bg bright red. Reads `--lr-theme-terminal-bg-bright-red`."},{"name":"--lr-terminal-bg-bright-white","description":"**Shared design token** — Canonical shared component token for terminal bg bright white. Reads `--lr-theme-terminal-bg-bright-white`."},{"name":"--lr-terminal-bg-bright-yellow","description":"**Shared design token** — Canonical shared component token for terminal bg bright yellow. Reads `--lr-theme-terminal-bg-bright-yellow`."},{"name":"--lr-terminal-bg-cyan","description":"**Shared design token** — Canonical shared component token for terminal bg cyan. Reads `--lr-theme-terminal-bg-cyan`."},{"name":"--lr-terminal-bg-green","description":"**Shared design token** — Canonical shared component token for terminal bg green. Reads `--lr-theme-terminal-bg-green`."},{"name":"--lr-terminal-bg-magenta","description":"**Shared design token** — Canonical shared component token for terminal bg magenta. Reads `--lr-theme-terminal-bg-magenta`."},{"name":"--lr-terminal-bg-red","description":"**Shared design token** — Canonical shared component token for terminal bg red. Reads `--lr-theme-terminal-bg-red`."},{"name":"--lr-terminal-bg-white","description":"**Shared design token** — Canonical shared component token for terminal bg white. Reads `--lr-theme-terminal-bg-white`."},{"name":"--lr-terminal-bg-yellow","description":"**Shared design token** — Canonical shared component token for terminal bg yellow. Reads `--lr-theme-terminal-bg-yellow`."},{"name":"--lr-terminal-border-color","description":"**`<lr-terminal>`** (default: `var(--lr-color-border)`) — Colour of the outer card's border and of the toolbar/log divider, which `frame=\"plain\"` keeps."},{"name":"--lr-terminal-color-black","description":"**Shared design token** — Canonical shared component token for terminal color black. Reads `--lr-theme-terminal-color-black`."},{"name":"--lr-terminal-color-blue","description":"**Shared design token** — Canonical shared component token for terminal color blue. Reads `--lr-theme-terminal-color-blue`."},{"name":"--lr-terminal-color-bright-black","description":"**Shared design token** — Canonical shared component token for terminal color bright black. Reads `--lr-theme-terminal-color-bright-black`."},{"name":"--lr-terminal-color-bright-blue","description":"**Shared design token** — Canonical shared component token for terminal color bright blue. Reads `--lr-theme-terminal-color-bright-blue`."},{"name":"--lr-terminal-color-bright-cyan","description":"**Shared design token** — Canonical shared component token for terminal color bright cyan. Reads `--lr-theme-terminal-color-bright-cyan`."},{"name":"--lr-terminal-color-bright-green","description":"**Shared design token** — Canonical shared component token for terminal color bright green. Reads `--lr-theme-terminal-color-bright-green`."},{"name":"--lr-terminal-color-bright-magenta","description":"**Shared design token** — Canonical shared component token for terminal color bright magenta. Reads `--lr-theme-terminal-color-bright-magenta`."},{"name":"--lr-terminal-color-bright-red","description":"**Shared design token** — Canonical shared component token for terminal color bright red. Reads `--lr-theme-terminal-color-bright-red`."},{"name":"--lr-terminal-color-bright-white","description":"**Shared design token** — Canonical shared component token for terminal color bright white. Reads `--lr-theme-terminal-color-bright-white`."},{"name":"--lr-terminal-color-bright-yellow","description":"**Shared design token** — Canonical shared component token for terminal color bright yellow. Reads `--lr-theme-terminal-color-bright-yellow`."},{"name":"--lr-terminal-color-cyan","description":"**Shared design token** — Canonical shared component token for terminal color cyan. Reads `--lr-theme-terminal-color-cyan`."},{"name":"--lr-terminal-color-green","description":"**Shared design token** — Canonical shared component token for terminal color green. Reads `--lr-theme-terminal-color-green`."},{"name":"--lr-terminal-color-magenta","description":"**Shared design token** — Canonical shared component token for terminal color magenta. Reads `--lr-theme-terminal-color-magenta`."},{"name":"--lr-terminal-color-red","description":"**Shared design token** — Canonical shared component token for terminal color red. Reads `--lr-theme-terminal-color-red`."},{"name":"--lr-terminal-color-white","description":"**Shared design token** — Canonical shared component token for terminal color white. Reads `--lr-theme-terminal-color-white`."},{"name":"--lr-terminal-color-yellow","description":"**Shared design token** — Canonical shared component token for terminal color yellow. Reads `--lr-theme-terminal-color-yellow`."},{"name":"--lr-terminal-compact-line-padding-inline","description":"**`<lr-terminal>`** (default: `var(--lr-space-xs)`) — Inline padding of each rendered `[part=\"line\"]` while `compact`."},{"name":"--lr-terminal-compact-toolbar-gap","description":"**`<lr-terminal>`** (default: `var(--lr-space-2xs)`) — Gap between `[part=\"toolbar\"]`'s buttons while `compact`."},{"name":"--lr-terminal-compact-toolbar-padding","description":"**`<lr-terminal>`** (default: `var(--lr-space-2xs) var(--lr-space-xs)`) — `[part=\"toolbar\"]` padding while `compact`."},{"name":"--lr-terminal-height","description":"**`<lr-terminal>`** (default: `var(--lr-size-20rem)`) — Block size of `[part=\"viewport\"]`, the scrollable log region. Not declared on `:host`, so it is inherited — set it on the host or any ancestor."},{"name":"--lr-terminal-highlight-accent-bg","description":"**`<lr-terminal>`** (default: `var(--lr-color-brand-quiet)`) — Background of an `accent`-tone highlighted line. Decoupled from the shared `--lr-color-brand-quiet` token also used by `[part=\"copy-button\"]`/`[part=\"download-button\"]`'s hover state, and from any `::part('line')` override (the background is applied inline, so a stylesheet rule can't beat it without `!important`)."},{"name":"--lr-terminal-highlight-danger-bg","description":"**`<lr-terminal>`** (default: `var(--lr-color-danger-quiet)`) — Background of a `danger`-tone highlighted line."},{"name":"--lr-terminal-highlight-neutral-bg","description":"**`<lr-terminal>`** (default: `var(--lr-color-surface)`) — Background of a `neutral`-tone highlighted line."},{"name":"--lr-terminal-highlight-success-bg","description":"**`<lr-terminal>`** (default: `var(--lr-color-success-quiet)`) — Background of a `success`-tone highlighted line."},{"name":"--lr-terminal-highlight-warning-bg","description":"**`<lr-terminal>`** (default: `var(--lr-color-warning-quiet)`) — Background of a `warning`-tone highlighted line."},{"name":"--lr-terminal-line-active-bg","description":"**`<lr-terminal>`** (default: `color-mix(in oklab, var(--lr-terminal-line-hover-bg, var(--lr-color-brand-quiet)), var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Pressed background of an ordinary rendered line."},{"name":"--lr-terminal-line-hover-bg","description":"**`<lr-terminal>`** (default: `var(--lr-color-brand-quiet)`) — Hover background of an ordinary rendered `[part=\"line\"]`."},{"name":"--lr-terminal-radius","description":"**`<lr-terminal>`** (default: `var(--lr-radius)`) — Corner radius of the outer card. `frame=\"plain\"` still squares the corners."},{"name":"--lr-terminal-search-active-outline-color","description":"**`<lr-terminal>`** (default: `var(--lr-color-brand)`) — Outline color for the active search match's line."},{"name":"--lr-terminal-search-outline-color","description":"**`<lr-terminal>`** (default: `var(--lr-color-warning)`) — Outline color for a line containing a non-active search match."},{"name":"--lr-terminal-surface-color","description":"**`<lr-terminal>`** (default: `var(--lr-color-surface-raised)`) — Card-frame background and the fallback foreground for inverse ANSI segments without an explicit background. The `frame=\"plain\"` escape remains transparent."},{"name":"--lr-terminal-toolbar-button-active-bg","description":"**`<lr-terminal>`** (default: `color-mix(in oklab, var(--lr-terminal-toolbar-button-hover-bg, var(--lr-color-brand-quiet)), var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Pressed background of the toolbar buttons."},{"name":"--lr-terminal-toolbar-button-hover-bg","description":"**`<lr-terminal>`** (default: `var(--lr-color-brand-quiet)`) — Hover background of `[part=\"copy-button\"]` and `[part=\"download-button\"]`."},{"name":"--lr-test-results-failed-color","description":"**`<lr-test-results>`** (default: `var(--lr-color-danger)`) — Failed-state foreground."},{"name":"--lr-test-results-filter-active-bg","description":"**`<lr-test-results>`** (default: `var(--lr-color-brand-quiet)`) — Background of a pressed (active) status filter toggle."},{"name":"--lr-test-results-filter-active-border","description":"**`<lr-test-results>`** (default: `var(--lr-color-brand)`) — Border color of a pressed (active) status filter toggle."},{"name":"--lr-test-results-filter-active-color","description":"**`<lr-test-results>`** (default: `var(--lr-color-brand)`) — Text color of a pressed (active) status filter toggle. Restyling the pressed state otherwise requires overriding the library-wide brand tokens, since `::part(filter-toggle)[aria-pressed]` is invalid CSS."},{"name":"--lr-test-results-passed-color","description":"**`<lr-test-results>`** (default: `var(--lr-color-success)`) — Passed-state foreground."},{"name":"--lr-test-results-running-color","description":"**`<lr-test-results>`** (default: `var(--lr-color-brand)`) — Running-state foreground."},{"name":"--lr-test-results-skipped-color","description":"**`<lr-test-results>`** (default: `var(--lr-color-text-quiet)`) — Skipped-state foreground."},{"name":"--lr-test-results-spinner-size","description":"**`<lr-test-results>`** (default: `var(--lr-size-1em)`) — Diameter of the composed spinner in a running test row."},{"name":"--lr-textarea-border-color","description":"**`<lr-textarea>`** (default: `var(--lr-color-border)`) — Border color of the field. Its private default follows `appearance` in the same way as `--lr-textarea-fill`."},{"name":"--lr-textarea-fill","description":"**`<lr-textarea>`** (default: `transparent`) — Background of the field. Its private default follows `appearance`; the documented default is `appearance=\"outlined\"`'s value."},{"name":"--lr-textarea-focus-border-color","description":"**`<lr-textarea>`** (default: `var(--lr-textarea-border-color)`) — Field border color while the native textarea is focused. Unset, it resolves to this field's own resting border color, so a textarea with no override renders exactly as before this hook existed."},{"name":"--lr-textarea-font-size","description":"**`<lr-textarea>`** (default: `var(--lr-form-control-font-size)`) — Font size of the native textarea, from the active `size` tier of the shared ladder."},{"name":"--lr-textarea-hover-border-color","description":"**`<lr-textarea>`** (default: `var(--lr-color-brand)`) — Field border color while the native textarea is hovered."},{"name":"--lr-textarea-max-block-size","description":"**`<lr-textarea>`** (default: `none`) — Maximum auto-grown block size before the textarea scrolls."},{"name":"--lr-textarea-padding","description":"**`<lr-textarea>`** (default: `var(--lr-form-control-padding-inline)`) — Padding of the native textarea on all four sides, from the active `size` tier of the shared form-control ladder (`internal/sizes.styles.ts`). The ladder's *inline* gutter is used on every side deliberately: its block padding is `0` at the two tightest tiers because a control row's height floor supplies the space there, and a textarea has no such floor -- the first line of text would sit on the border."},{"name":"--lr-textarea-radius","description":"**`<lr-textarea>`** (default: `var(--lr-form-control-radius)`) — Corner radius of the field, from the active `size` tier of the shared ladder (the two tightest tiers take a smaller radius). `pill` changes the private default to `--lr-radius-pill`; a public value still wins."},{"name":"--lr-theme-border-radius-m","description":"**Application theme input** — Canonical application theme input for border radius m."},{"name":"--lr-theme-border-radius-pill","description":"**Application theme input** — Application theme input for --lr-radius-pill."},{"name":"--lr-theme-border-radius-xs","description":"**Application theme input** — Application theme input for --lr-radius-xs."},{"name":"--lr-theme-border-width-medium","description":"**Application theme input** — Application theme input for --lr-border-width-medium."},{"name":"--lr-theme-border-width-thick","description":"**Application theme input** — Application theme input for --lr-border-width-thick."},{"name":"--lr-theme-border-width-thin","description":"**Application theme input** — Application theme input for --lr-border-width-thin."},{"name":"--lr-theme-color-border-strong","description":"**Application theme input** — Canonical application theme input for color border strong."},{"name":"--lr-theme-color-brand-border-loud","description":"**Application theme input** — Canonical application theme input for color brand border loud."},{"name":"--lr-theme-color-brand-border-normal","description":"**Application theme input** — Canonical application theme input for color brand border normal."},{"name":"--lr-theme-color-brand-border-quiet","description":"**Application theme input** — Canonical application theme input for color brand border quiet."},{"name":"--lr-theme-color-brand-fill-loud","description":"**Application theme input** — Canonical application theme input for color brand fill loud."},{"name":"--lr-theme-color-brand-fill-normal","description":"**Application theme input** — Canonical application theme input for color brand fill normal."},{"name":"--lr-theme-color-brand-fill-quiet","description":"**Application theme input** — Canonical application theme input for color brand fill quiet."},{"name":"--lr-theme-color-brand-on-loud","description":"**Application theme input** — Canonical application theme input for color brand on loud."},{"name":"--lr-theme-color-brand-on-normal","description":"**Application theme input** — Canonical application theme input for color brand on normal."},{"name":"--lr-theme-color-brand-on-quiet","description":"**Application theme input** — Canonical application theme input for color brand on quiet."},{"name":"--lr-theme-color-chart-1","description":"**Application theme input** — Canonical application theme input for color chart 1."},{"name":"--lr-theme-color-chart-2","description":"**Application theme input** — Canonical application theme input for color chart 2."},{"name":"--lr-theme-color-chart-3","description":"**Application theme input** — Canonical application theme input for color chart 3."},{"name":"--lr-theme-color-chart-4","description":"**Application theme input** — Canonical application theme input for color chart 4."},{"name":"--lr-theme-color-chart-5","description":"**Application theme input** — Canonical application theme input for color chart 5."},{"name":"--lr-theme-color-chart-6","description":"**Application theme input** — Canonical application theme input for color chart 6."},{"name":"--lr-theme-color-chart-7","description":"**Application theme input** — Canonical application theme input for color chart 7."},{"name":"--lr-theme-color-chart-8","description":"**Application theme input** — Canonical application theme input for color chart 8."},{"name":"--lr-theme-color-danger-border-loud","description":"**Application theme input** — Canonical application theme input for color danger border loud."},{"name":"--lr-theme-color-danger-border-normal","description":"**Application theme input** — Canonical application theme input for color danger border normal."},{"name":"--lr-theme-color-danger-border-quiet","description":"**Application theme input** — Canonical application theme input for color danger border quiet."},{"name":"--lr-theme-color-danger-fill-loud","description":"**Application theme input** — Canonical application theme input for color danger fill loud."},{"name":"--lr-theme-color-danger-fill-normal","description":"**Application theme input** — Canonical application theme input for color danger fill normal."},{"name":"--lr-theme-color-danger-fill-quiet","description":"**Application theme input** — Canonical application theme input for color danger fill quiet."},{"name":"--lr-theme-color-danger-on-loud","description":"**Application theme input** — Canonical application theme input for color danger on loud."},{"name":"--lr-theme-color-danger-on-normal","description":"**Application theme input** — Canonical application theme input for color danger on normal."},{"name":"--lr-theme-color-danger-on-quiet","description":"**Application theme input** — Canonical application theme input for color danger on quiet."},{"name":"--lr-theme-color-focus","description":"**Application theme input** — Canonical application theme input for color focus."},{"name":"--lr-theme-color-mix-active","description":"**Application theme input** — Application theme input for --lr-color-mix-active."},{"name":"--lr-theme-color-mix-hover","description":"**Application theme input** — Application theme input for --lr-color-mix-hover."},{"name":"--lr-theme-color-mix-partner","description":"**Application theme input** — Application theme input for --lr-color-mix-partner."},{"name":"--lr-theme-color-neutral-border-loud","description":"**Application theme input** — Canonical application theme input for color neutral border loud."},{"name":"--lr-theme-color-neutral-border-normal","description":"**Application theme input** — Canonical application theme input for color neutral border normal."},{"name":"--lr-theme-color-neutral-border-quiet","description":"**Application theme input** — Canonical application theme input for color neutral border quiet."},{"name":"--lr-theme-color-neutral-fill-loud","description":"**Application theme input** — Canonical application theme input for color neutral fill loud."},{"name":"--lr-theme-color-neutral-fill-normal","description":"**Application theme input** — Canonical application theme input for color neutral fill normal."},{"name":"--lr-theme-color-neutral-fill-quiet","description":"**Application theme input** — Canonical application theme input for color neutral fill quiet."},{"name":"--lr-theme-color-neutral-on-loud","description":"**Application theme input** — Canonical application theme input for color neutral on loud."},{"name":"--lr-theme-color-neutral-on-normal","description":"**Application theme input** — Canonical application theme input for color neutral on normal."},{"name":"--lr-theme-color-neutral-on-quiet","description":"**Application theme input** — Canonical application theme input for color neutral on quiet."},{"name":"--lr-theme-color-no-data","description":"**Application theme input** — Canonical application theme input for color no data."},{"name":"--lr-theme-color-on-strong-overlay","description":"**Application theme input** — Canonical application theme input for color on strong overlay."},{"name":"--lr-theme-color-overlay","description":"**Application theme input** — Canonical application theme input for color overlay."},{"name":"--lr-theme-color-overlay-strong","description":"**Application theme input** — Canonical application theme input for color overlay strong."},{"name":"--lr-theme-color-shadow","description":"**Application theme input** — Application theme input for --lr-color-shadow."},{"name":"--lr-theme-color-success-border-loud","description":"**Application theme input** — Canonical application theme input for color success border loud."},{"name":"--lr-theme-color-success-border-normal","description":"**Application theme input** — Canonical application theme input for color success border normal."},{"name":"--lr-theme-color-success-border-quiet","description":"**Application theme input** — Canonical application theme input for color success border quiet."},{"name":"--lr-theme-color-success-fill-loud","description":"**Application theme input** — Canonical application theme input for color success fill loud."},{"name":"--lr-theme-color-success-fill-normal","description":"**Application theme input** — Canonical application theme input for color success fill normal."},{"name":"--lr-theme-color-success-fill-quiet","description":"**Application theme input** — Canonical application theme input for color success fill quiet."},{"name":"--lr-theme-color-success-on-loud","description":"**Application theme input** — Canonical application theme input for color success on loud."},{"name":"--lr-theme-color-success-on-normal","description":"**Application theme input** — Canonical application theme input for color success on normal."},{"name":"--lr-theme-color-success-on-quiet","description":"**Application theme input** — Canonical application theme input for color success on quiet."},{"name":"--lr-theme-color-surface-border","description":"**Application theme input** — Canonical application theme input for color surface border."},{"name":"--lr-theme-color-surface-default","description":"**Application theme input** — Canonical application theme input for color surface default."},{"name":"--lr-theme-color-surface-overlay","description":"**Application theme input** — Canonical application theme input for color surface overlay."},{"name":"--lr-theme-color-surface-raised","description":"**Application theme input** — Canonical application theme input for color surface raised."},{"name":"--lr-theme-color-text-normal","description":"**Application theme input** — Canonical application theme input for color text normal."},{"name":"--lr-theme-color-text-quiet","description":"**Application theme input** — Canonical application theme input for color text quiet."},{"name":"--lr-theme-color-warning-border-loud","description":"**Application theme input** — Canonical application theme input for color warning border loud."},{"name":"--lr-theme-color-warning-border-normal","description":"**Application theme input** — Canonical application theme input for color warning border normal."},{"name":"--lr-theme-color-warning-border-quiet","description":"**Application theme input** — Canonical application theme input for color warning border quiet."},{"name":"--lr-theme-color-warning-fill-loud","description":"**Application theme input** — Canonical application theme input for color warning fill loud."},{"name":"--lr-theme-color-warning-fill-normal","description":"**Application theme input** — Canonical application theme input for color warning fill normal."},{"name":"--lr-theme-color-warning-fill-quiet","description":"**Application theme input** — Canonical application theme input for color warning fill quiet."},{"name":"--lr-theme-color-warning-on-loud","description":"**Application theme input** — Canonical application theme input for color warning on loud."},{"name":"--lr-theme-color-warning-on-normal","description":"**Application theme input** — Canonical application theme input for color warning on normal."},{"name":"--lr-theme-color-warning-on-quiet","description":"**Application theme input** — Canonical application theme input for color warning on quiet."},{"name":"--lr-theme-duration-fast","description":"**Application theme input** — Application theme input for --lr-duration-fast."},{"name":"--lr-theme-duration-icon","description":"**Application theme input** — Application theme input for --lr-duration-icon."},{"name":"--lr-theme-duration-normal","description":"**Application theme input** — Application theme input for --lr-duration-base."},{"name":"--lr-theme-duration-slow","description":"**Application theme input** — Application theme input for --lr-duration-ambient."},{"name":"--lr-theme-easing-emphasized","description":"**Application theme input** — Application theme input for --lr-easing-emphasized."},{"name":"--lr-theme-easing-linear","description":"**Application theme input** — Application theme input for --lr-easing-linear."},{"name":"--lr-theme-easing-standard","description":"**Application theme input** — Application theme input for --lr-easing-standard."},{"name":"--lr-theme-focus-ring-offset","description":"**Application theme input** — Canonical application theme input for focus ring offset."},{"name":"--lr-theme-focus-ring-width","description":"**Application theme input** — Canonical application theme input for focus ring width."},{"name":"--lr-theme-font-family-body","description":"**Application theme input** — Canonical application theme input for font family body."},{"name":"--lr-theme-font-family-mono","description":"**Application theme input** — Canonical application theme input for font family mono."},{"name":"--lr-theme-font-size-2xl","description":"**Application theme input** — Canonical application theme input for font size 2xl."},{"name":"--lr-theme-font-size-2xs","description":"**Application theme input** — Canonical application theme input for font size 2xs."},{"name":"--lr-theme-font-size-3xl","description":"**Application theme input** — Canonical application theme input for font size 3xl."},{"name":"--lr-theme-font-size-3xs","description":"**Application theme input** — Canonical application theme input for font size 3xs."},{"name":"--lr-theme-font-size-lg","description":"**Application theme input** — Canonical application theme input for font size lg."},{"name":"--lr-theme-font-size-m","description":"**Application theme input** — Canonical application theme input for font size m."},{"name":"--lr-theme-font-size-md-sm","description":"**Application theme input** — Canonical application theme input for font size md sm."},{"name":"--lr-theme-font-size-sm","description":"**Application theme input** — Canonical application theme input for font size sm."},{"name":"--lr-theme-font-size-xl","description":"**Application theme input** — Canonical application theme input for font size xl."},{"name":"--lr-theme-font-size-xs","description":"**Application theme input** — Canonical application theme input for font size xs."},{"name":"--lr-theme-font-weight-bold","description":"**Application theme input** — Application theme input for --lr-font-weight-bold."},{"name":"--lr-theme-font-weight-medium","description":"**Application theme input** — Application theme input for --lr-font-weight-medium."},{"name":"--lr-theme-font-weight-normal","description":"**Application theme input** — Application theme input for --lr-font-weight-normal."},{"name":"--lr-theme-font-weight-semibold","description":"**Application theme input** — Application theme input for --lr-font-weight-semibold."},{"name":"--lr-theme-form-control-height-2xs","description":"**Application theme input** — Application theme input for --lr-form-control-height-2xs."},{"name":"--lr-theme-form-control-height-l","description":"**Application theme input** — Application theme input for --lr-form-control-height-l."},{"name":"--lr-theme-form-control-height-m","description":"**Application theme input** — Application theme input for --lr-form-control-height-m."},{"name":"--lr-theme-form-control-height-s","description":"**Application theme input** — Application theme input for --lr-form-control-height-s."},{"name":"--lr-theme-form-control-height-xl","description":"**Application theme input** — Application theme input for --lr-form-control-height-xl."},{"name":"--lr-theme-form-control-height-xs","description":"**Application theme input** — Application theme input for --lr-form-control-height-xs."},{"name":"--lr-theme-form-control-radius","description":"**Application theme input** — Application input for --lr-form-control-radius; falls back to the shared token default."},{"name":"--lr-theme-graph-cat-1","description":"**Application theme input** — Canonical application theme input for graph cat 1."},{"name":"--lr-theme-graph-cat-2","description":"**Application theme input** — Canonical application theme input for graph cat 2."},{"name":"--lr-theme-graph-cat-3","description":"**Application theme input** — Canonical application theme input for graph cat 3."},{"name":"--lr-theme-graph-cat-4","description":"**Application theme input** — Canonical application theme input for graph cat 4."},{"name":"--lr-theme-graph-cat-5","description":"**Application theme input** — Canonical application theme input for graph cat 5."},{"name":"--lr-theme-graph-cat-6","description":"**Application theme input** — Canonical application theme input for graph cat 6."},{"name":"--lr-theme-graph-cat-7","description":"**Application theme input** — Canonical application theme input for graph cat 7."},{"name":"--lr-theme-graph-cat-8","description":"**Application theme input** — Canonical application theme input for graph cat 8."},{"name":"--lr-theme-hover-brightness","description":"**Application theme input** — Application theme input for --lr-hover-brightness."},{"name":"--lr-theme-icon-button-size","description":"**Application theme input** — Canonical application theme input for icon button size."},{"name":"--lr-theme-line-height-1-4","description":"**Application theme input** — Application theme input for --lr-line-height-1-4."},{"name":"--lr-theme-line-height-compact","description":"**Application theme input** — Application theme input for --lr-line-height-compact."},{"name":"--lr-theme-line-height-loose","description":"**Application theme input** — Application theme input for --lr-line-height-loose."},{"name":"--lr-theme-line-height-none","description":"**Application theme input** — Application theme input for --lr-line-height-none."},{"name":"--lr-theme-line-height-normal","description":"**Application theme input** — Application theme input for --lr-line-height-normal."},{"name":"--lr-theme-line-height-snug","description":"**Application theme input** — Application theme input for --lr-line-height-snug."},{"name":"--lr-theme-opacity-disabled","description":"**Application theme input** — Application theme input for --lr-opacity-disabled."},{"name":"--lr-theme-opacity-muted","description":"**Application theme input** — Application theme input for --lr-opacity-muted."},{"name":"--lr-theme-otp-input-segment-size","description":"**Application theme input** — Application theme input for --lr-otp-input-segment-size."},{"name":"--lr-theme-popover-viewport-clamp","description":"**Application theme input** — Application theme input for --lr-popover-viewport-clamp."},{"name":"--lr-theme-scroll-fade-size","description":"**Application theme input** — Application theme input for --lr-scroll-fade-size."},{"name":"--lr-theme-scrollbar-gutter","description":"**`<lr-code-block>`, `<lr-code-block-core>`** (default: `auto`) — Opt-in theme-level scrollbar gutter honored by `body`; see `--lr-theme-scrollbar-width`.\n\n**`<lr-code-editor>`** (default: `auto`) — Opt-in theme-level scrollbar gutter honored by the `editor` scroll frame; see `--lr-theme-scrollbar-width`.\n\n**`<lr-table>`** (default: `auto`) — Opt-in theme-level scrollbar gutter honored by the `base` scroll container; see `--lr-theme-scrollbar-width`.\n\n**`<lr-virtual-list>`** (default: `auto`) — Opt-in theme-level scrollbar gutter honored by the `base` scroll viewport; see `--lr-theme-scrollbar-width`."},{"name":"--lr-theme-scrollbar-width","description":"**`<lr-code-block>`** (default: `auto`) — Opt-in theme-level scrollbar width honored by `body`; unset, renders identically to before. Set on `:root` or any ancestor to retune every internal scroll container in the library at once. Shared with `lr-code-block-core` (which reuses this stylesheet).\n\n**`<lr-code-block-core>`** (default: `auto`) — Opt-in theme-level scrollbar width honored by `body`; unset, renders identically to before. Set on `:root` or any ancestor to retune every internal scroll container in the library at once. Shared with `lr-code-block` (this component reuses its stylesheet).\n\n**`<lr-code-editor>`** (default: `auto`) — Opt-in theme-level scrollbar width honored by the `editor` scroll frame; unset, renders identically to before. Set on `:root` or any ancestor to retune every internal scroll container in the library at once.\n\n**`<lr-table>`** (default: `auto`) — Opt-in theme-level scrollbar width honored by the `base` scroll container; unset, renders identically to before. Set on `:root` or any ancestor to retune every internal scroll container in the library at once.\n\n**`<lr-virtual-list>`** (default: `auto`) — Opt-in theme-level scrollbar width honored by the `base` scroll viewport; unset, renders identically to before. Set on `:root` or any ancestor to retune every internal scroll container in the library at once."},{"name":"--lr-theme-shadow-color","description":"**Application theme input** — Canonical application theme input for shadow color."},{"name":"--lr-theme-shadow-l","description":"**Application theme input** — Canonical application theme input for shadow l."},{"name":"--lr-theme-shadow-m","description":"**Application theme input** — Canonical application theme input for shadow m."},{"name":"--lr-theme-shadow-s","description":"**Application theme input** — Canonical application theme input for shadow s."},{"name":"--lr-theme-shadow-xl","description":"**Application theme input** — Canonical application theme input for shadow xl."},{"name":"--lr-theme-shadow-xs","description":"**Application theme input** — Canonical application theme input for shadow xs."},{"name":"--lr-theme-size-0-02em","description":"**Application theme input** — Application theme input for --lr-size-0-02em."},{"name":"--lr-theme-size-0-03em","description":"**Application theme input** — Application theme input for --lr-size-0-03em."},{"name":"--lr-theme-size-0-04em","description":"**Application theme input** — Application theme input for --lr-size-0-04em."},{"name":"--lr-theme-size-0-05rem","description":"**Application theme input** — Application theme input for --lr-size-0-05rem."},{"name":"--lr-theme-size-0-0625rem","description":"**Application theme input** — Application theme input for --lr-size-0-0625rem."},{"name":"--lr-theme-size-0-09375rem","description":"**Application theme input** — Application theme input for --lr-size-0-09375rem."},{"name":"--lr-theme-size-0-125rem","description":"**Application theme input** — Application theme input for --lr-size-0-125rem."},{"name":"--lr-theme-size-0-15rem","description":"**Application theme input** — Application theme input for --lr-size-0-15rem."},{"name":"--lr-theme-size-0-1875rem","description":"**Application theme input** — Application theme input for --lr-size-0-1875rem."},{"name":"--lr-theme-size-0-1rem","description":"**Application theme input** — Application theme input for --lr-size-0-1rem."},{"name":"--lr-theme-size-0-25rem","description":"**Application theme input** — Application theme input for --lr-size-0-25rem."},{"name":"--lr-theme-size-0-3125rem","description":"**Application theme input** — Application theme input for --lr-size-0-3125rem."},{"name":"--lr-theme-size-0-35em","description":"**Application theme input** — Application theme input for --lr-size-0-35em."},{"name":"--lr-theme-size-0-375rem","description":"**Application theme input** — Application theme input for --lr-size-0-375rem."},{"name":"--lr-theme-size-0-3em","description":"**Application theme input** — Application theme input for --lr-size-0-3em."},{"name":"--lr-theme-size-0-4375rem","description":"**Application theme input** — Application theme input for --lr-size-0-4375rem."},{"name":"--lr-theme-size-0-4em","description":"**Application theme input** — Application theme input for --lr-size-0-4em."},{"name":"--lr-theme-size-0-4rem","description":"**Application theme input** — Application theme input for --lr-size-0-4rem."},{"name":"--lr-theme-size-0-5em","description":"**Application theme input** — Application theme input for --lr-size-0-5em."},{"name":"--lr-theme-size-0-5rem","description":"**Application theme input** — Application theme input for --lr-size-0-5rem."},{"name":"--lr-theme-size-0-625rem","description":"**Application theme input** — Application theme input for --lr-size-0-625rem."},{"name":"--lr-theme-size-0-6875rem","description":"**Application theme input** — Application theme input for --lr-size-0-6875rem."},{"name":"--lr-theme-size-0-6rem","description":"**Application theme input** — Application theme input for --lr-size-0-6rem."},{"name":"--lr-theme-size-0-75em","description":"**Application theme input** — Application theme input for --lr-size-0-75em."},{"name":"--lr-theme-size-0-75rem","description":"**Application theme input** — Application theme input for --lr-size-0-75rem."},{"name":"--lr-theme-size-0-7em","description":"**Application theme input** — Application theme input for --lr-size-0-7em."},{"name":"--lr-theme-size-0-875em","description":"**Application theme input** — Application theme input for --lr-size-0-875em."},{"name":"--lr-theme-size-0-8rem","description":"**Application theme input** — Application theme input for --lr-size-0-8rem."},{"name":"--lr-theme-size-0-9375rem","description":"**Application theme input** — Application theme input for --lr-size-0-9375rem."},{"name":"--lr-theme-size-1-0625rem","description":"**Application theme input** — Application theme input for --lr-size-1-0625rem."},{"name":"--lr-theme-size-1-1rem","description":"**Application theme input** — Application theme input for --lr-size-1-1rem."},{"name":"--lr-theme-size-1-25rem","description":"**Application theme input** — Application theme input for --lr-size-1-25rem."},{"name":"--lr-theme-size-1-5em","description":"**Application theme input** — Application theme input for --lr-size-1-5em."},{"name":"--lr-theme-size-1-5rem","description":"**Application theme input** — Application theme input for --lr-size-1-5rem."},{"name":"--lr-theme-size-1-75rem","description":"**Application theme input** — Application theme input for --lr-size-1-75rem."},{"name":"--lr-theme-size-1-875rem","description":"**Application theme input** — Application theme input for --lr-size-1-875rem."},{"name":"--lr-theme-size-10px","description":"**Application theme input** — Application theme input for --lr-size-10px."},{"name":"--lr-theme-size-10rem","description":"**Application theme input** — Application theme input for --lr-size-10rem."},{"name":"--lr-theme-size-12em","description":"**Application theme input** — Application theme input for --lr-size-12em."},{"name":"--lr-theme-size-12rem","description":"**Application theme input** — Application theme input for --lr-size-12rem."},{"name":"--lr-theme-size-14px","description":"**Application theme input** — Application theme input for --lr-size-14px."},{"name":"--lr-theme-size-14rem","description":"**Application theme input** — Application theme input for --lr-size-14rem."},{"name":"--lr-theme-size-15rem","description":"**Application theme input** — Application theme input for --lr-size-15rem."},{"name":"--lr-theme-size-16px","description":"**Application theme input** — Application theme input for --lr-size-16px."},{"name":"--lr-theme-size-16rem","description":"**Application theme input** — Application theme input for --lr-size-16rem."},{"name":"--lr-theme-size-18rem","description":"**Application theme input** — Application theme input for --lr-size-18rem."},{"name":"--lr-theme-size-1em","description":"**Application theme input** — Application theme input for --lr-size-1em."},{"name":"--lr-theme-size-1px","description":"**Application theme input** — Application theme input for --lr-size-1px."},{"name":"--lr-theme-size-1rem","description":"**Application theme input** — Application theme input for --lr-size-1rem."},{"name":"--lr-theme-size-2-25rem","description":"**Application theme input** — Application theme input for --lr-size-2-25rem."},{"name":"--lr-theme-size-2-5ch","description":"**Application theme input** — Application theme input for --lr-size-2-5ch."},{"name":"--lr-theme-size-2-5rem","description":"**Application theme input** — Application theme input for --lr-size-2-5rem."},{"name":"--lr-theme-size-20rem","description":"**Application theme input** — Application theme input for --lr-size-20rem."},{"name":"--lr-theme-size-22rem","description":"**Application theme input** — Application theme input for --lr-size-22rem."},{"name":"--lr-theme-size-24px","description":"**Application theme input** — Application theme input for --lr-size-24px."},{"name":"--lr-theme-size-24rem","description":"**Application theme input** — Application theme input for --lr-size-24rem."},{"name":"--lr-theme-size-280px","description":"**Application theme input** — Application theme input for --lr-size-280px."},{"name":"--lr-theme-size-28px","description":"**Application theme input** — Application theme input for --lr-size-28px."},{"name":"--lr-theme-size-28rem","description":"**Application theme input** — Application theme input for --lr-size-28rem."},{"name":"--lr-theme-size-2px","description":"**Application theme input** — Application theme input for --lr-size-2px."},{"name":"--lr-theme-size-2rem","description":"**Application theme input** — Application theme input for --lr-size-2rem."},{"name":"--lr-theme-size-3-5em","description":"**Application theme input** — Application theme input for --lr-size-3-5em."},{"name":"--lr-theme-size-3-5rem","description":"**Application theme input** — Application theme input for --lr-size-3-5rem."},{"name":"--lr-theme-size-30rem","description":"**Application theme input** — Application theme input for --lr-size-30rem."},{"name":"--lr-theme-size-32rem","description":"**Application theme input** — Application theme input for --lr-size-32rem."},{"name":"--lr-theme-size-36rem","description":"**Application theme input** — Application theme input for --lr-size-36rem."},{"name":"--lr-theme-size-38rem","description":"**Application theme input** — Application theme input for --lr-size-38rem."},{"name":"--lr-theme-size-3ch","description":"**Application theme input** — Application theme input for --lr-size-3ch."},{"name":"--lr-theme-size-3px","description":"**Application theme input** — Application theme input for --lr-size-3px."},{"name":"--lr-theme-size-3rem","description":"**Application theme input** — Application theme input for --lr-size-3rem."},{"name":"--lr-theme-size-48rem","description":"**Application theme input** — Application theme input for --lr-size-48rem."},{"name":"--lr-theme-size-4ch","description":"**Application theme input** — Application theme input for --lr-size-4ch."},{"name":"--lr-theme-size-4px","description":"**Application theme input** — Application theme input for --lr-size-4px."},{"name":"--lr-theme-size-4rem","description":"**Application theme input** — Application theme input for --lr-size-4rem."},{"name":"--lr-theme-size-5em","description":"**Application theme input** — Application theme input for --lr-size-5em."},{"name":"--lr-theme-size-5rem","description":"**Application theme input** — Application theme input for --lr-size-5rem."},{"name":"--lr-theme-size-6ch","description":"**Application theme input** — Application theme input for --lr-size-6ch."},{"name":"--lr-theme-size-6em","description":"**Application theme input** — Application theme input for --lr-size-6em."},{"name":"--lr-theme-size-6px","description":"**Application theme input** — Application theme input for --lr-size-6px."},{"name":"--lr-theme-size-6rem","description":"**Application theme input** — Application theme input for --lr-size-6rem."},{"name":"--lr-theme-size-7rem","description":"**Application theme input** — Application theme input for --lr-size-7rem."},{"name":"--lr-theme-size-8em","description":"**Application theme input** — Application theme input for --lr-size-8em."},{"name":"--lr-theme-size-8rem","description":"**Application theme input** — Application theme input for --lr-size-8rem."},{"name":"--lr-theme-size-neg-0-15rem","description":"**Application theme input** — Application theme input for --lr-size-neg-0-15rem."},{"name":"--lr-theme-size-neg-0-25rem","description":"**Application theme input** — Application theme input for --lr-size-neg-0-25rem."},{"name":"--lr-theme-size-neg-1px","description":"**Application theme input** — Application theme input for --lr-size-neg-1px."},{"name":"--lr-theme-size-neg-4px","description":"**Application theme input** — Application theme input for --lr-size-neg-4px."},{"name":"--lr-theme-size-neg-6px","description":"**Application theme input** — Application theme input for --lr-size-neg-6px."},{"name":"--lr-theme-size-neg-8px","description":"**Application theme input** — Application theme input for --lr-size-neg-8px."},{"name":"--lr-theme-space-2xl","description":"**Application theme input** — Canonical application theme input for space 2xl."},{"name":"--lr-theme-space-2xs","description":"**Application theme input** — Canonical application theme input for space 2xs."},{"name":"--lr-theme-space-l","description":"**Application theme input** — Canonical application theme input for space l."},{"name":"--lr-theme-space-m","description":"**Application theme input** — Canonical application theme input for space m."},{"name":"--lr-theme-space-s","description":"**Application theme input** — Canonical application theme input for space s."},{"name":"--lr-theme-space-xs","description":"**Application theme input** — Canonical application theme input for space xs."},{"name":"--lr-theme-terminal-bg-black","description":"**Application theme input** — Canonical application theme input for terminal bg black."},{"name":"--lr-theme-terminal-bg-blue","description":"**Application theme input** — Canonical application theme input for terminal bg blue."},{"name":"--lr-theme-terminal-bg-bright-black","description":"**Application theme input** — Canonical application theme input for terminal bg bright black."},{"name":"--lr-theme-terminal-bg-bright-blue","description":"**Application theme input** — Canonical application theme input for terminal bg bright blue."},{"name":"--lr-theme-terminal-bg-bright-cyan","description":"**Application theme input** — Canonical application theme input for terminal bg bright cyan."},{"name":"--lr-theme-terminal-bg-bright-green","description":"**Application theme input** — Canonical application theme input for terminal bg bright green."},{"name":"--lr-theme-terminal-bg-bright-magenta","description":"**Application theme input** — Canonical application theme input for terminal bg bright magenta."},{"name":"--lr-theme-terminal-bg-bright-red","description":"**Application theme input** — Canonical application theme input for terminal bg bright red."},{"name":"--lr-theme-terminal-bg-bright-white","description":"**Application theme input** — Canonical application theme input for terminal bg bright white."},{"name":"--lr-theme-terminal-bg-bright-yellow","description":"**Application theme input** — Canonical application theme input for terminal bg bright yellow."},{"name":"--lr-theme-terminal-bg-cyan","description":"**Application theme input** — Canonical application theme input for terminal bg cyan."},{"name":"--lr-theme-terminal-bg-green","description":"**Application theme input** — Canonical application theme input for terminal bg green."},{"name":"--lr-theme-terminal-bg-magenta","description":"**Application theme input** — Canonical application theme input for terminal bg magenta."},{"name":"--lr-theme-terminal-bg-red","description":"**Application theme input** — Canonical application theme input for terminal bg red."},{"name":"--lr-theme-terminal-bg-white","description":"**Application theme input** — Canonical application theme input for terminal bg white."},{"name":"--lr-theme-terminal-bg-yellow","description":"**Application theme input** — Canonical application theme input for terminal bg yellow."},{"name":"--lr-theme-terminal-color-black","description":"**Application theme input** — Canonical application theme input for terminal color black."},{"name":"--lr-theme-terminal-color-blue","description":"**Application theme input** — Canonical application theme input for terminal color blue."},{"name":"--lr-theme-terminal-color-bright-black","description":"**Application theme input** — Canonical application theme input for terminal color bright black."},{"name":"--lr-theme-terminal-color-bright-blue","description":"**Application theme input** — Canonical application theme input for terminal color bright blue."},{"name":"--lr-theme-terminal-color-bright-cyan","description":"**Application theme input** — Canonical application theme input for terminal color bright cyan."},{"name":"--lr-theme-terminal-color-bright-green","description":"**Application theme input** — Canonical application theme input for terminal color bright green."},{"name":"--lr-theme-terminal-color-bright-magenta","description":"**Application theme input** — Canonical application theme input for terminal color bright magenta."},{"name":"--lr-theme-terminal-color-bright-red","description":"**Application theme input** — Canonical application theme input for terminal color bright red."},{"name":"--lr-theme-terminal-color-bright-white","description":"**Application theme input** — Canonical application theme input for terminal color bright white."},{"name":"--lr-theme-terminal-color-bright-yellow","description":"**Application theme input** — Canonical application theme input for terminal color bright yellow."},{"name":"--lr-theme-terminal-color-cyan","description":"**Application theme input** — Canonical application theme input for terminal color cyan."},{"name":"--lr-theme-terminal-color-green","description":"**Application theme input** — Canonical application theme input for terminal color green."},{"name":"--lr-theme-terminal-color-magenta","description":"**Application theme input** — Canonical application theme input for terminal color magenta."},{"name":"--lr-theme-terminal-color-red","description":"**Application theme input** — Canonical application theme input for terminal color red."},{"name":"--lr-theme-terminal-color-white","description":"**Application theme input** — Canonical application theme input for terminal color white."},{"name":"--lr-theme-terminal-color-yellow","description":"**Application theme input** — Canonical application theme input for terminal color yellow."},{"name":"--lr-theme-transition-fast","description":"**Application theme input** — Application theme input for --lr-transition-fast."},{"name":"--lr-theme-transition-normal","description":"**Application theme input** — Application theme input for --lr-transition-base."},{"name":"--lr-theme-transition-slow","description":"**Application theme input** — Application theme input for --lr-transition-ambient."},{"name":"--lr-theme-z-index-base","description":"**Application theme input** — Canonical application theme input for z index base."},{"name":"--lr-theme-z-index-content","description":"**Application theme input** — Canonical application theme input for z index content."},{"name":"--lr-theme-z-index-dropdown","description":"**Application theme input** — Canonical application theme input for z index dropdown."},{"name":"--lr-theme-z-index-modal","description":"**Application theme input** — Canonical application theme input for z index modal."},{"name":"--lr-theme-z-index-popover","description":"**Application theme input** — Canonical application theme input for z index popover."},{"name":"--lr-theme-z-index-toast","description":"**Application theme input** — Canonical application theme input for z index toast."},{"name":"--lr-thinking-panel-background","description":"**`<lr-thinking-panel>`** (default: `var(--lr-color-surface)`) — Fill of the outer card (`[part=\"base\"]`) while `frame=\"card\"`. `frame=\"plain\"` still removes the fill entirely."},{"name":"--lr-thinking-panel-body-hover-outline-color","description":"**`<lr-thinking-panel>`** (default: `var(--lr-color-border)`) — Outline color of the mouse-hover preview on `[part=\"body\"]`. Set to `transparent` to opt out of the hover treatment entirely."},{"name":"--lr-thinking-panel-body-hover-outline-offset","description":"**`<lr-thinking-panel>`** (default: `calc(-1 * var(--lr-focus-ring-offset))`) — Inward offset of the mouse-hover preview on `[part=\"body\"]`, keeping the outline inside its own scrollport so it is not clipped at the edge."},{"name":"--lr-thinking-panel-body-hover-outline-style","description":"**`<lr-thinking-panel>`** (default: `solid`) — Outline style of the mouse-hover preview on `[part=\"body\"]`."},{"name":"--lr-thinking-panel-body-hover-outline-width","description":"**`<lr-thinking-panel>`** (default: `var(--lr-focus-ring-width)`) — Outline width of the mouse-hover preview on `[part=\"body\"]`."},{"name":"--lr-thinking-panel-border-color","description":"**`<lr-thinking-panel>`** (default: `var(--lr-color-border)`) — Colour of the outer card's border and of the header/body divider, which `frame=\"plain\"` keeps."},{"name":"--lr-thinking-panel-compact-body-padding","description":"**`<lr-thinking-panel>`** (default: `var(--lr-space-s)`) — `[part=\"body\"]` padding while `compact`."},{"name":"--lr-thinking-panel-compact-header-font-size","description":"**`<lr-thinking-panel>`** (default: `var(--lr-font-size-sm)`) — Font size of `[part=\"header\"]` while `compact`."},{"name":"--lr-thinking-panel-compact-header-gap","description":"**`<lr-thinking-panel>`** (default: `var(--lr-space-2xs)`) — Gap between the header toggle, label, and duration while `compact`."},{"name":"--lr-thinking-panel-compact-header-padding","description":"**`<lr-thinking-panel>`** (default: `var(--lr-space-2xs) var(--lr-space-s)`) — `[part=\"header\"]` padding while `compact`."},{"name":"--lr-thinking-panel-max-block-size","description":"**`<lr-thinking-panel>`** (default: `var(--lr-size-16rem)`) — Cap on how tall the expanded reasoning transcript grows before `[part=\"body\"]` scrolls internally."},{"name":"--lr-thinking-panel-pending-color","description":"**`<lr-thinking-panel>`** (default: `var(--lr-color-brand)`) — Live pending-state color."},{"name":"--lr-thinking-panel-radius","description":"**`<lr-thinking-panel>`** (default: `var(--lr-radius)`) — Corner radius of the outer card. `frame=\"plain\"` still squares the corners."},{"name":"--lr-thread-list-excerpt-highlight-background","description":"**`<lr-thread-list>`** (default: `var(--lr-color-warning-quiet)`) — Background of `<mark>` descendants returned by `renderExcerpt`."},{"name":"--lr-thread-list-excerpt-highlight-foreground","description":"**`<lr-thread-list>`** (default: `inherit`) — Foreground of `<mark>` descendants returned by `renderExcerpt`."},{"name":"--lr-thread-list-excerpt-highlight-padding","description":"**`<lr-thread-list>`** (default: `0`) — Padding of `<mark>` descendants returned by `renderExcerpt`."},{"name":"--lr-thread-list-excerpt-highlight-radius","description":"**`<lr-thread-list>`** (default: `var(--lr-radius-xs)`) — Corner radius of `<mark>` descendants returned by `renderExcerpt`."},{"name":"--lr-thread-list-group-toggle-active-bg","description":"**`<lr-thread-list>`** (default: `color-mix(in oklab, var(--lr-thread-list-group-toggle-hover-bg, var(--lr-color-surface-raised)), var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Group-toggle pressed background."},{"name":"--lr-thread-list-group-toggle-active-color","description":"**`<lr-thread-list>`** (default: `var(--lr-thread-list-group-toggle-hover-color, var(--lr-color-text))`) — Group-toggle pressed foreground."},{"name":"--lr-thread-list-group-toggle-hover-bg","description":"**`<lr-thread-list>`** (default: `var(--lr-color-surface-raised)`) — Group-toggle hover background."},{"name":"--lr-thread-list-group-toggle-hover-color","description":"**`<lr-thread-list>`** (default: `var(--lr-color-text)`) — Group-toggle hover foreground."},{"name":"--lr-thread-list-row-action-active-bg","description":"**`<lr-thread-list>`** (default: `color-mix(in oklab, var(--lr-thread-list-row-action-hover-bg, var(--lr-color-surface-raised)), var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Row-action pressed background."},{"name":"--lr-thread-list-row-action-active-color","description":"**`<lr-thread-list>`** (default: `var(--lr-thread-list-row-action-hover-color, var(--lr-color-text))`) — Row-action pressed foreground."},{"name":"--lr-thread-list-row-action-hover-bg","description":"**`<lr-thread-list>`** (default: `var(--lr-color-surface-raised)`) — Row-action hover background."},{"name":"--lr-thread-list-row-action-hover-color","description":"**`<lr-thread-list>`** (default: `var(--lr-color-text)`) — Row-action hover foreground."},{"name":"--lr-thread-list-search-clear-size","description":"**`<lr-thread-list>`** (default: `var(--lr-size-1-5rem)`) — Box size of the search field's clear button. Deliberately not tiered by `size`: it is a tap target floored at the shared minimum target size, not a text box."},{"name":"--lr-thread-list-search-font-size","description":"**`<lr-thread-list>`** — Text size of the search field. Unset while `size` is, so the field inherits the ambient text size; a `size` tier resolves it to that tier's shared form-control font size."},{"name":"--lr-thread-list-search-gap","description":"**`<lr-thread-list>`** (default: `var(--lr-space-xs)`) — Gap between the search field and its clear button."},{"name":"--lr-thread-list-search-min-height","description":"**`<lr-thread-list>`** — Minimum row height of the search field. Unset while `size` is, so the field is exactly as tall as its own text plus padding; a `size` tier resolves it to that tier's shared form-control height."},{"name":"--lr-thread-list-search-padding","description":"**`<lr-thread-list>`** (default: `var(--lr-space-s)`) — Gutter around the built-in search field. Deliberately not tiered by `size`, which sizes the field itself."},{"name":"--lr-thread-list-search-padding-block","description":"**`<lr-thread-list>`** (default: `var(--lr-space-xs)`) — Block gutter of the search field. A `size` tier replaces the default with that tier's shared form-control block gutter."},{"name":"--lr-thread-list-search-padding-inline","description":"**`<lr-thread-list>`** (default: `var(--lr-space-s)`) — Inline gutter of the search field. A `size` tier replaces the default with that tier's shared form-control inline gutter."},{"name":"--lr-thread-list-search-radius","description":"**`<lr-thread-list>`** (default: `var(--lr-radius)`) — Corner radius of the search field. A `size` tier replaces the default with that tier's shared form-control radius."},{"name":"--lr-time-input-action-active-bg","description":"**`<lr-time-input>`** — Clear/expand/Now pressed fill; derived from hover when unset."},{"name":"--lr-time-input-action-color","description":"**`<lr-time-input>`** (default: `var(--lr-color-text-quiet)`) — Resting clear/expand color."},{"name":"--lr-time-input-action-hover-bg","description":"**`<lr-time-input>`** (default: `var(--lr-color-brand-quiet)`) — Clear/expand/Now hover fill."},{"name":"--lr-time-input-action-hover-color","description":"**`<lr-time-input>`** (default: `var(--lr-color-text)`) — Hovered clear/expand color."},{"name":"--lr-time-input-border-color","description":"**`<lr-time-input>`** (default: `var(--lr-color-border)`) — Outer row border color, with appearance-specific fallbacks."},{"name":"--lr-time-input-color","description":"**`<lr-time-input>`** (default: `var(--lr-color-text)`) — Outer row text color, including the accent appearance fallback."},{"name":"--lr-time-input-column-active-bg","description":"**`<lr-time-input>`** — Picker-option pressed fill; derived from hover when unset."},{"name":"--lr-time-input-column-hover-bg","description":"**`<lr-time-input>`** (default: `var(--lr-color-brand-quiet)`) — Picker-option hover fill."},{"name":"--lr-time-input-column-selected-active-bg","description":"**`<lr-time-input>`** — Selected-option pressed fill; derived when unset."},{"name":"--lr-time-input-column-selected-bg","description":"**`<lr-time-input>`** (default: `var(--lr-color-brand)`) — Selected option fill."},{"name":"--lr-time-input-column-selected-color","description":"**`<lr-time-input>`** (default: `var(--lr-color-on-brand)`) — Selected option text."},{"name":"--lr-time-input-column-selected-font-weight","description":"**`<lr-time-input>`** (default: `var(--lr-font-weight-semibold)`) — Selected option weight."},{"name":"--lr-time-input-column-selected-hover-bg","description":"**`<lr-time-input>`** — Selected-option hover fill; derived when unset."},{"name":"--lr-time-input-control-height","description":"**`<lr-time-input>`** — Exact outer row height. Unset by default, which leaves `--lr-time-input-control-min-height` as a floor only; set it to a length to both floor and cap the row (e.g. to pixel-match `<lr-date-input>` in the same toolbar). Because it is never declared by the component itself, it can be set from an ancestor or an outer-tree rule as well as inline on the element."},{"name":"--lr-time-input-control-min-height","description":"**`<lr-time-input>`** (default: `var(--lr-form-control-height)`) — Outer row height floor, taken from the active `size` tier of the shared form-control ladder (`internal/sizes.styles.ts`), so a time field is exactly as tall as an `<lr-input>`/ `<lr-select>` of the same tier."},{"name":"--lr-time-input-fill","description":"**`<lr-time-input>`** (default: `transparent`) — Outer row background, with appearance-specific fallbacks."},{"name":"--lr-time-input-focus-border-color","description":"**`<lr-time-input>`** (default: `var(--lr-color-brand)`) — Open/focused row border."},{"name":"--lr-time-input-gap","description":"**`<lr-time-input>`** (default: `var(--lr-form-control-gap)`) — Gap between segments, adornments, and actions in the outer row. Undeclared on the host so ancestor theme wrappers can set it."},{"name":"--lr-time-input-radius","description":"**`<lr-time-input>`** (default: `var(--lr-form-control-radius)`) — Outer row corner radius. `pill` supplies `--lr-radius-pill` only as the fallback, so a component-scoped value wins."},{"name":"--lr-time-input-segment-active-bg","description":"**`<lr-time-input>`** — Segment pressed fill; derived from hover when unset."},{"name":"--lr-time-input-segment-focus-bg","description":"**`<lr-time-input>`** (default: `var(--lr-time-input-segment-hover-bg,var(--lr-color-brand-quiet))`) — Keyboard-focused segment fill."},{"name":"--lr-time-input-segment-hover-bg","description":"**`<lr-time-input>`** (default: `var(--lr-color-brand-quiet)`) — Segment hover fill."},{"name":"--lr-time-range-base-size","description":"**`<lr-time-range>`** (default: `1.5rem*scale`) — Brush baseline block size."},{"name":"--lr-time-range-handle-bg","description":"**`<lr-time-range>`** (default: `var(--lr-color-brand)`) — Resting handle background."},{"name":"--lr-time-range-handle-border-color","description":"**`<lr-time-range>`** (default: `var(--lr-color-surface)`) — Resting handle border."},{"name":"--lr-time-range-handle-hover-bg","description":"**`<lr-time-range>`** — Hovered handle background; defaults to a hover-state mix of `--lr-time-range-handle-bg`."},{"name":"--lr-time-range-handle-pressed-bg","description":"**`<lr-time-range>`** — Pressed handle background; defaults to an active-state mix of `--lr-time-range-handle-bg`."},{"name":"--lr-time-range-handle-size","description":"**`<lr-time-range>`** (default: `14px*scale`) — Visible handle diameter."},{"name":"--lr-time-range-hit-size","description":"**`<lr-time-range>`** (default: `max(24px,28px*scale)`) — Actual drag hit-area diameter; endpoint handles are inset by half this distance so the hit geometry stays inside the host."},{"name":"--lr-time-range-preset-active-bg","description":"**`<lr-time-range>`** (default: `var(--lr-color-brand)`) — Background of the active preset button (`[data-active]`, i.e. the preset whose button produced the current range). Declared as an inline `var()` fallback (never on `:host`), so setting it on the element or an ancestor recolors only the active preset without hijacking the library-wide `--lr-color-brand` token."},{"name":"--lr-time-range-preset-active-border-color","description":"**`<lr-time-range>`** (default: `var(--lr-color-brand)`) — Border color of the active preset button."},{"name":"--lr-time-range-preset-active-color","description":"**`<lr-time-range>`** (default: `var(--lr-color-on-brand)`) — Text color of the active preset button."},{"name":"--lr-time-range-preset-font-size","description":"**`<lr-time-range>`** — Preset button font size, scaled by `size`."},{"name":"--lr-time-range-preset-gap","description":"**`<lr-time-range>`** (default: `var(--lr-space-xs)`) — Gap between preset buttons."},{"name":"--lr-time-range-preset-hover-border-color","description":"**`<lr-time-range>`** (default: `var(--lr-color-brand)`) — Border color of a hovered preset button."},{"name":"--lr-time-range-preset-padding","description":"**`<lr-time-range>`** — Preset button padding, scaled by `size`."},{"name":"--lr-time-range-preset-pressed-bg","description":"**`<lr-time-range>`** — Background of a pressed preset button; defaults to an active-state mix of `--lr-color-surface`."},{"name":"--lr-time-range-preset-pressed-border-color","description":"**`<lr-time-range>`** — Border color of a pressed preset button; defaults to an active-state mix of `--lr-color-brand`."},{"name":"--lr-time-range-preset-radius","description":"**`<lr-time-range>`** (default: `var(--lr-radius)`) — Preset button corner radius."},{"name":"--lr-time-range-size-scale","description":"**`<lr-time-range>`** (default: `1`) — Unitless multiplier applied proportionally to the handle, track, and preset-button dimensions based on the current `size` tier; the drag hit-area is floored at 24px (WCAG 2.5.8)."},{"name":"--lr-time-range-track-size","description":"**`<lr-time-range>`** (default: `4px*scale`) — Track and selected-range thickness."},{"name":"--lr-timeline-active-ring-color","description":"**`<lr-timeline-item>`** (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."},{"name":"--lr-timeline-cluster-bg","description":"**`<lr-timeline>`, `<lr-timeline-item>`** (default: `var(--lr-color-brand)`) — Cluster count pill background."},{"name":"--lr-timeline-cluster-color","description":"**`<lr-timeline>`, `<lr-timeline-item>`** (default: `var(--lr-color-on-brand)`) — Cluster count pill foreground."},{"name":"--lr-timeline-cluster-size","description":"**`<lr-timeline>`** (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\n**`<lr-timeline-item>`** (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."},{"name":"--lr-timeline-collision-offset","description":"**`<lr-timeline>`** (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."},{"name":"--lr-timeline-gap","description":"**`<lr-timeline>`** (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."},{"name":"--lr-timeline-marker-color","description":"**`<lr-timeline-item>`** (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."},{"name":"--lr-timeline-marker-size","description":"**`<lr-timeline-item>`** (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."},{"name":"--lr-timeline-rail-color","description":"**`<lr-timeline-item>`** (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."},{"name":"--lr-timeline-rail-width","description":"**`<lr-timeline-item>`** (default: `var(--lr-border-width-medium)`) — Thickness of the connecting rail line. Inherits from theme ancestors."},{"name":"--lr-timeline-time-extent","description":"**`<lr-timeline>`** (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. Horizontal overlap and stack modes measure actual item/lane height independently and update it when content changes. Ignored in the default `scale=\"flow\"`."},{"name":"--lr-toast-accent-color","description":"**`<lr-toast>`** (default: `var(--lr-color-border)`) — Accent bar / icon color of a slotted item. Its private default follows `variant`; an inherited or direct public value wins.\n\n**`<lr-toast-item>`** (default: `var(--lr-color-border)`) — Color of the accent bar and the icon. Its private default follows each non-neutral `variant`'s loud fill from the shared semantic grid; `neutral` keeps the plain border color, so an informational toast reads as unaccented. An inherited or direct public value remains authoritative."},{"name":"--lr-toast-accent-width","description":"**`<lr-toast>`** (default: `var(--lr-size-4px)`) — Width of a slotted item's accent bar. Read by `<lr-toast-item>`'s own stylesheet, so set it on the item.\n\n**`<lr-toast-item>`** (default: `var(--lr-size-4px)`) — Width of the accent bar, and the extra inline-start padding reserved for it."},{"name":"--lr-toast-close-button-active-bg","description":"**`<lr-toast-item>`** (default: `color-mix(in oklab, transparent, var(--lr-color-mix-partner) var(--lr-color-mix-active))`) — Background of the enabled close button while pressed."},{"name":"--lr-toast-close-button-active-color","description":"**`<lr-toast-item>`** (default: `var(--lr-color-text)`) — Foreground of the enabled close button while pressed."},{"name":"--lr-toast-close-button-hover-bg","description":"**`<lr-toast-item>`** (default: `transparent`) — Background of the enabled close button while hovered."},{"name":"--lr-toast-close-button-hover-color","description":"**`<lr-toast-item>`** (default: `var(--lr-color-text)`) — Foreground of the enabled close button while hovered."},{"name":"--lr-toast-font-size","description":"**`<lr-toast>`** (default: `var(--lr-font-size-m)`) — Font size of a slotted item. Its private default follows `size`; an inherited or direct public value wins.\n\n**`<lr-toast-item>`** (default: `var(--lr-font-size-m)`) — Font size of the item. Its private default follows `size` across the shared six-step ladder; an inherited or direct public value wins."},{"name":"--lr-toast-gap","description":"**`<lr-toast>`** (default: `var(--lr-space-s)`) — Gap between stacked items."},{"name":"--lr-toast-hide-duration","description":"**`<lr-toast>`** (default: `var(--lr-transition-base, 180ms ease-out)`) — Hide transition of a slotted item. Read by `<lr-toast-item>`, so set it on the item.\n\n**`<lr-toast-item>`** (default: `var(--lr-transition-base, 180ms ease-out)`) — Opacity/transform transition used while hiding."},{"name":"--lr-toast-item-gap","description":"**`<lr-toast-item>`** (default: `var(--lr-space-s)`) — Gap between the item icon, message, and close button. Unlike `--lr-toast-gap`, this does not affect spacing between stacked items."},{"name":"--lr-toast-item-radius","description":"**`<lr-toast-item>`** (default: `var(--lr-radius)`) — Corner radius of the item surface and its accent bar's inline-start corners. Pointer-state hooks are inline fallbacks, so they inherit from the item or an ancestor without recoloring the item surface or the stack."},{"name":"--lr-toast-padding","description":"**`<lr-toast>`** (default: `var(--lr-space-m)`) — Padding of a slotted item. Its private default follows `size`; an inherited or direct public value wins.\n\n**`<lr-toast-item>`** (default: `var(--lr-space-m)`) — Padding of the item. Its private default follows `size` across the shared six-step ladder; an inherited or direct public value wins."},{"name":"--lr-toast-show-duration","description":"**`<lr-toast>`** (default: `var(--lr-transition-base, 180ms ease-out)`) — Show transition of a slotted item. Read by `<lr-toast-item>`, so set it on the item.\n\n**`<lr-toast-item>`** (default: `var(--lr-transition-base, 180ms ease-out)`) — Opacity/transform transition used while showing."},{"name":"--lr-toast-width","description":"**`<lr-toast>`** (default: `var(--lr-size-28rem)`) — Inline size of the stack, capped by the usable logical safe-area rectangle."},{"name":"--lr-token-input-action-hover-bg","description":"**`<lr-token-input>`** (default: `var(--lr-color-brand-quiet)`) — Edit/remove hover background."},{"name":"--lr-token-input-border-color","description":"**`<lr-token-input>`** (default: `var(--lr-color-border)`) — Resting border color of the input row. The invalid and focused states keep their own hooks and still win over it."},{"name":"--lr-token-input-control-height","description":"**`<lr-token-input>`** — Exact input-wrapper height. Unset by default, which leaves `--lr-token-input-control-min-height` as a floor only; set it to a length to both floor and cap the row (e.g. to pixel-match a sibling field in the same toolbar row). An uncapped row grows as tokens wrap; a capped row clips inline overflow and intentionally scrolls in the block axis so wrapped tokens and their hit-area-floored actions remain reachable. Because it is never declared by the component itself, it can be set from an ancestor or an outer-tree rule as well as inline on the element."},{"name":"--lr-token-input-control-min-height","description":"**`<lr-token-input>`** (default: `var(--lr-form-control-height)`) — Input-wrapper block-size floor. Reads the shared form-control height ladder, so retuning `--lr-theme-form-control-height-*` moves this control and every sibling field together."},{"name":"--lr-token-input-edit-hover-bg","description":"**`<lr-token-input>`** (default: `var(--lr-token-input-action-hover-bg)`) — Editable token label hover background, independently themeable from the remove action."},{"name":"--lr-token-input-edit-pressed-bg","description":"**`<lr-token-input>`** — Editable token label pressed background; defaults to an active-state mix of `--lr-token-input-edit-hover-bg`."},{"name":"--lr-token-input-editor-inline-size","description":"**`<lr-token-input>`** (default: `var(--lr-size-6rem)`) — Inline size of the inline token editor opened by `editable`."},{"name":"--lr-token-input-fill","description":"**`<lr-token-input>`** (default: `var(--lr-color-surface)`) — Resting background of the input row."},{"name":"--lr-token-input-focus-border-color","description":"**`<lr-token-input>`** (default: `var(--lr-color-brand)`) — Focused row border color."},{"name":"--lr-token-input-font-size","description":"**`<lr-token-input>`** — Input-wrapper/token font size, scaled by `size`."},{"name":"--lr-token-input-gap","description":"**`<lr-token-input>`** (default: `var(--lr-space-xs)`) — Gap between form/row children."},{"name":"--lr-token-input-input-inline-size","description":"**`<lr-token-input>`** (default: `var(--lr-size-8rem)`) — `flex-basis` of the native text input within the token row."},{"name":"--lr-token-input-invalid-border-color","description":"**`<lr-token-input>`** (default: `var(--lr-color-danger)`) — Invalid row border color."},{"name":"--lr-token-input-min-input-inline-size","description":"**`<lr-token-input>`** (default: `var(--lr-size-4rem)`) — Inline-size floor of the native text input, so it stays usable once tokens wrap."},{"name":"--lr-token-input-padding","description":"**`<lr-token-input>`** — Input-wrapper padding, scaled by `size`."},{"name":"--lr-token-input-radius","description":"**`<lr-token-input>`** (default: `var(--lr-radius)`) — Row/token corner radius. `pill` changes its private default to `--lr-radius-pill`; an inherited or direct public value still wins."},{"name":"--lr-token-input-remove-hover-bg","description":"**`<lr-token-input>`** (default: `var(--lr-token-input-action-hover-bg)`) — Remove action hover background, independently themeable from the editable label."},{"name":"--lr-token-input-remove-pressed-bg","description":"**`<lr-token-input>`** — Remove action pressed background; defaults to an active-state mix of `--lr-token-input-remove-hover-bg`."},{"name":"--lr-token-input-token-bg","description":"**`<lr-token-input>`** (default: `var(--lr-color-brand-quiet)`) — Token chip background."},{"name":"--lr-token-input-token-gap","description":"**`<lr-token-input>`** (default: `var(--lr-space-2xs)`) — Gap inside token chips."},{"name":"--lr-token-input-token-padding","description":"**`<lr-token-input>`** — Per-token chip padding, scaled by `size`."},{"name":"--lr-tool-approval-dialog-hover-border-color","description":"**`<lr-tool-approval-dialog>`** (default: `var(--lr-color-brand)`) — Border color of a valid, editable raw-JSON args editor on hover. Invalid and pending states retain their semantic chrome."},{"name":"--lr-tool-approval-dialog-invalid-border-color","description":"**`<lr-tool-approval-dialog>`** (default: `var(--lr-color-danger)`) — Border color of an invalid raw-JSON editor."},{"name":"--lr-tool-approval-dialog-mono-font","description":"**`<lr-tool-approval-dialog>`** (default: `var(--lr-font-mono)`) — Font family for the tool name and the raw-JSON args editor."},{"name":"--lr-tool-approval-dialog-overlay-color","description":"**`<lr-tool-approval-dialog>`** (default: `var(--lr-color-overlay)`) — Backdrop scrim color."},{"name":"--lr-tool-call-chip-accent","description":"**`<lr-tool-call-chip>`** (default: `var(--lr-color-text-quiet)`) — Accent color for the status glyph and text. Its private default follows `status` (`running` → brand, `success` → success, `error` → danger, `denied` → warning); an inherited or direct public override always wins."},{"name":"--lr-tool-call-chip-bg","description":"**`<lr-tool-call-chip>`** (default: `var(--lr-color-surface)`) — Chip background. Its private default follows the same `status` rules using each status's `-quiet` tint; a public override wins."},{"name":"--lr-tool-call-chip-border","description":"**`<lr-tool-call-chip>`** (default: `var(--lr-color-border)`) — Chip border color. Its private default becomes transparent for every non-`pending` status; a public override wins."},{"name":"--lr-tool-call-chip-spin","description":"**`<lr-tool-call-chip>`** (default: `var(--lr-transition-ambient)`) — Running-icon animation duration and timing."},{"name":"--lr-tool-param-form-invalid-border-color","description":"**`<lr-tool-param-form>`** (default: `var(--lr-color-danger)`) — Border color of an invalid generated native text or number input."},{"name":"--lr-tool-result-dialog-denied-bg","description":"**`<lr-tool-result-dialog>`** (default: `var(--lr-color-warning-quiet)`) — Denied status background."},{"name":"--lr-tool-result-dialog-denied-color","description":"**`<lr-tool-result-dialog>`** (default: `var(--lr-color-warning)`) — Denied status foreground."},{"name":"--lr-tool-result-dialog-error-bg","description":"**`<lr-tool-result-dialog>`** (default: `var(--lr-color-danger-quiet)`) — Error status background."},{"name":"--lr-tool-result-dialog-error-color","description":"**`<lr-tool-result-dialog>`** (default: `var(--lr-color-danger)`) — Error status foreground."},{"name":"--lr-tool-result-dialog-maximized-inset","description":"**`<lr-tool-result-dialog>`** — Insets for the maximized panel."},{"name":"--lr-tool-result-dialog-overlay-color","description":"**`<lr-tool-result-dialog>`** (default: `var(--lr-color-overlay)`) — Backdrop color."},{"name":"--lr-tool-result-dialog-pending-bg","description":"**`<lr-tool-result-dialog>`** (default: `transparent`) — Pending status background."},{"name":"--lr-tool-result-dialog-pending-color","description":"**`<lr-tool-result-dialog>`** (default: `var(--lr-color-text-quiet)`) — Pending status foreground."},{"name":"--lr-tool-result-dialog-running-bg","description":"**`<lr-tool-result-dialog>`** (default: `var(--lr-color-brand-quiet)`) — Running status background."},{"name":"--lr-tool-result-dialog-running-color","description":"**`<lr-tool-result-dialog>`** (default: `var(--lr-color-brand)`) — Running status foreground."},{"name":"--lr-tool-result-dialog-spin","description":"**`<lr-tool-result-dialog>`** (default: `var(--lr-transition-ambient)`) — Running-status animation duration and timing."},{"name":"--lr-tool-result-dialog-success-bg","description":"**`<lr-tool-result-dialog>`** (default: `var(--lr-color-success-quiet)`) — Success status background."},{"name":"--lr-tool-result-dialog-success-color","description":"**`<lr-tool-result-dialog>`** (default: `var(--lr-color-success)`) — Success status foreground."},{"name":"--lr-tool-result-view-font","description":"**`<lr-tool-result-view>`** (default: `var(--lr-font-mono)`) — Font family for the `fallback=\"text\"` preformatted output."},{"name":"--lr-tool-select-dialog-body-hover-outline-color","description":"**`<lr-tool-select-dialog>`** (default: `var(--lr-color-border)`) — Outline color of the mouse-hover preview on `[part=\"body\"]`. Set to `transparent` to opt out of the hover treatment entirely."},{"name":"--lr-tool-select-dialog-body-hover-outline-offset","description":"**`<lr-tool-select-dialog>`** (default: `calc(-1 * var(--lr-border-width-thin))`) — Inward offset of the mouse-hover preview on `[part=\"body\"]`, keeping the outline inside its own scrollport so it is not clipped at the edge."},{"name":"--lr-tool-select-dialog-body-hover-outline-style","description":"**`<lr-tool-select-dialog>`** (default: `solid`) — Outline style of the mouse-hover preview on `[part=\"body\"]`."},{"name":"--lr-tool-select-dialog-body-hover-outline-width","description":"**`<lr-tool-select-dialog>`** (default: `var(--lr-border-width-thin)`) — Outline width of the mouse-hover preview on `[part=\"body\"]`."},{"name":"--lr-tool-select-dialog-overlay-color","description":"**`<lr-tool-select-dialog>`** (default: `var(--lr-color-overlay)`) — Backdrop scrim color."},{"name":"--lr-tool-select-dialog-search-font-size","description":"**`<lr-tool-select-dialog>`** (default: `inherit`) — Text size of the search field."},{"name":"--lr-tool-select-dialog-search-min-height","description":"**`<lr-tool-select-dialog>`** (default: `auto`) — Minimum row height of the search field, for matching it to a themed search field of a chosen density tier. Point it at `--lr-form-control-height-s` (or any tier of that ladder) to line this field up with the rest of an application's controls."},{"name":"--lr-tool-select-dialog-search-padding-block","description":"**`<lr-tool-select-dialog>`** (default: `var(--lr-space-s)`) — Block gutter of the search field."},{"name":"--lr-tool-select-dialog-search-padding-inline","description":"**`<lr-tool-select-dialog>`** (default: `var(--lr-space-m)`) — Leading gutter of the search field. The trailing gutter is reserved for the overlaid clear button."},{"name":"--lr-tool-select-dialog-search-radius","description":"**`<lr-tool-select-dialog>`** (default: `var(--lr-radius)`) — Corner radius of the search field."},{"name":"--lr-tool-timeline-approved-bg","description":"**`<lr-tool-timeline>`** (default: `var(--lr-color-success-quiet)`) — Approved badge background."},{"name":"--lr-tool-timeline-approved-color","description":"**`<lr-tool-timeline>`** (default: `var(--lr-color-success)`) — Approved badge foreground."},{"name":"--lr-tool-timeline-denied-bg","description":"**`<lr-tool-timeline>`** (default: `var(--lr-color-danger-quiet)`) — Denied badge background."},{"name":"--lr-tool-timeline-denied-color","description":"**`<lr-tool-timeline>`** (default: `var(--lr-color-danger)`) — Denied badge foreground."},{"name":"--lr-tool-timeline-denied-marker-color","description":"**`<lr-tool-timeline>`** (default: `var(--lr-color-warning)`) — Rail-dot color for a `status=\"denied\"` entry, decoupled from the pending-approval border below so a consumer can retint either independently."},{"name":"--lr-tool-timeline-error-color","description":"**`<lr-tool-timeline>`** (default: `var(--lr-color-danger)`) — Expanded error text."},{"name":"--lr-tool-timeline-error-marker-color","description":"**`<lr-tool-timeline>`** (default: `var(--lr-color-danger)`) — Error rail dot."},{"name":"--lr-tool-timeline-gap","description":"**`<lr-tool-timeline>`** (default: `var(--lr-space-l)`) — Vertical gap between entries."},{"name":"--lr-tool-timeline-marker-size","description":"**`<lr-tool-timeline>`** (default: `var(--lr-size-0-625rem)`) — Diameter of an entry's rail dot; also the width of the marker gutter column."},{"name":"--lr-tool-timeline-pending-approval-border-color","description":"**`<lr-tool-timeline>`** (default: `var(--lr-color-warning)`) — Color of the entry body's leading border while `data-pending-approval=\"true\"`."},{"name":"--lr-tool-timeline-pending-marker-color","description":"**`<lr-tool-timeline>`** (default: `var(--lr-color-text-quiet)`) — Rail-dot color for a `status=\"pending\"` entry."},{"name":"--lr-tool-timeline-running-marker-color","description":"**`<lr-tool-timeline>`** (default: `var(--lr-color-brand)`) — Running rail dot."},{"name":"--lr-tool-timeline-success-marker-color","description":"**`<lr-tool-timeline>`** (default: `var(--lr-color-success)`) — Success rail dot."},{"name":"--lr-tooltip-arrow-size","description":"**`<lr-tooltip>`** — Retained Lyra fallback for `--arrow-size`."},{"name":"--lr-tooltip-background","description":"**`<lr-tooltip>`** — Tooltip background color (default `--lr-color-neutral`)."},{"name":"--lr-tooltip-color","description":"**`<lr-tooltip>`** — Tooltip text color (default `--lr-color-on-neutral`)."},{"name":"--lr-tooltip-max-inline-size","description":"**`<lr-tooltip>`** — Retained Lyra fallback for `--max-width`."},{"name":"--lr-tour-backdrop-color","description":"**`<lr-tour>`** — Backdrop scrim fill. Defaults to `--lr-color-overlay`."},{"name":"--lr-tour-popover-max-width","description":"**`<lr-tour>`** — Maximum popover inline size. Defaults to `--lr-size-22rem`."},{"name":"--lr-tour-progress-dot-current-bg","description":"**`<lr-tour>`** (default: `var(--lr-color-brand)`) — Background of `progress-dot` for the current step, without repainting every other component that reuses the shared brand token."},{"name":"--lr-tour-spotlight-radius","description":"**`<lr-tour>`** — Corner radius shared by the cutout and the ring. Defaults to `--lr-radius`."},{"name":"--lr-tour-spotlight-ring-color","description":"**`<lr-tour>`** — Spotlight ring color. Defaults to `--lr-color-brand`."},{"name":"--lr-tour-spotlight-ring-width","description":"**`<lr-tour>`** — Spotlight ring thickness. Defaults to `--lr-border-width-medium`."},{"name":"--lr-trace-tree-bar-track-bg","description":"**`<lr-trace-tree>`** (default: `var(--lr-color-surface-raised)`) — Duration bar track."},{"name":"--lr-trace-tree-denied-color","description":"**`<lr-trace-tree>`** (default: `var(--lr-color-warning)`) — Denied status text and bar."},{"name":"--lr-trace-tree-error-color","description":"**`<lr-trace-tree>`** (default: `var(--lr-color-danger)`) — Error status text and bar."},{"name":"--lr-trace-tree-max-indent","description":"**`<lr-trace-tree>`** (default: `var(--lr-size-12rem)`) — Maximum visual nesting indentation; semantic `aria-level` remains exact at deeper levels."},{"name":"--lr-trace-tree-pending-color","description":"**`<lr-trace-tree>`** (default: `var(--lr-color-text-quiet)`) — Pending status text and bar."},{"name":"--lr-trace-tree-row-active-bg","description":"**`<lr-trace-tree>`** (default: `var(--lr-color-brand-quiet)`) — Background of the active (`activeSpanId`) row. Shadow Parts forbids an attribute selector after `::part()`, so the active row could otherwise only be restyled by hijacking the library-wide `--lr-color-brand-quiet` token. Pairs with `--lr-trace-tree-row-active-color`: set both together, since the defaults assume the active background stays on the same side of the lightness midpoint as the ambient surface — a dark tint in light mode needs the matching text color set too, or the row's secondary text drops below the WCAG AA contrast floor."},{"name":"--lr-trace-tree-row-active-color","description":"**`<lr-trace-tree>`** (default: `var(--lr-color-text)`) — Foreground reference for the active (`activeSpanId`) row. It sets the color of that row's secondary text (`detail`, `duration`, `tokens-in`, `tokens-out`, `cost`, and the `pending` status label), which is raised from the quiet token to full-strength text so it clears WCAG AA against the active row's tint. The semantic status labels keep their own hue but are mixed 25% toward this same value, so overriding it re-aims every foreground on the row at once rather than leaving the status colors stranded. See the pairing caveat on `--lr-trace-tree-row-active-bg`."},{"name":"--lr-trace-tree-running-color","description":"**`<lr-trace-tree>`** (default: `var(--lr-color-brand)`) — Running status text and stripe."},{"name":"--lr-trace-tree-running-stripe-bg","description":"**`<lr-trace-tree>`** (default: `var(--lr-color-brand-quiet)`) — Running stripe contrast."},{"name":"--lr-trace-tree-success-color","description":"**`<lr-trace-tree>`** (default: `var(--lr-color-success)`) — Success status text and bar."},{"name":"--lr-trace-tree-toggle-hover-bg","description":"**`<lr-trace-tree>`** (default: `var(--lr-color-brand-quiet)`) — Toggle hover background."},{"name":"--lr-transition-ambient","description":"**`<lr-chat-message>`** (default: `1.8s ease-in-out`) — Streaming-indicator animation duration and timing function.\n\n**`<lr-skeleton>`** (default: `1.8s ease-in-out`) — Animation duration and timing function shared by the pulse and sheen effects.\n\n**`<lr-tool-call-chip>`** (default: `1.8s ease-in-out`) — Pending-icon pulse duration and timing.\n\n**Shared design token** — Canonical shared component token for transition ambient. Reads `--lr-theme-transition-slow`."},{"name":"--lr-transition-base","description":"**Shared design token** — Canonical shared component token for transition base. Reads `--lr-theme-transition-normal`."},{"name":"--lr-transition-fast","description":"**Shared design token** — Canonical shared component token for transition fast. Reads `--lr-theme-transition-fast`."},{"name":"--lr-transition-interactive","description":"**Shared design token** — Shared pointer-interaction transition: fill, text and border colour move together on hover and press, derived from the fast transition token so reduced motion flattens it."},{"name":"--lr-tree-badge-brand-bg","description":"**`<lr-tree-item>`** (default: `var(--lr-color-brand-quiet)`) — Brand badge background."},{"name":"--lr-tree-badge-brand-color","description":"**`<lr-tree-item>`** (default: `var(--lr-color-brand)`) — Brand badge text color."},{"name":"--lr-tree-badge-danger-bg","description":"**`<lr-tree-item>`** (default: `var(--lr-color-danger-quiet)`) — Danger badge background."},{"name":"--lr-tree-badge-danger-color","description":"**`<lr-tree-item>`** (default: `var(--lr-color-danger)`) — Danger badge text color."},{"name":"--lr-tree-badge-neutral-bg","description":"**`<lr-tree-item>`** (default: `var(--lr-color-surface)`) — Neutral badge background."},{"name":"--lr-tree-badge-neutral-color","description":"**`<lr-tree-item>`** (default: `var(--lr-color-text-quiet)`) — Neutral badge text color."},{"name":"--lr-tree-badge-success-bg","description":"**`<lr-tree-item>`** (default: `var(--lr-color-success-quiet)`) — Success badge background."},{"name":"--lr-tree-badge-success-color","description":"**`<lr-tree-item>`** (default: `var(--lr-color-success)`) — Success badge text color."},{"name":"--lr-tree-badge-warning-bg","description":"**`<lr-tree-item>`** (default: `var(--lr-color-warning-quiet)`) — Warning badge background."},{"name":"--lr-tree-badge-warning-color","description":"**`<lr-tree-item>`** (default: `var(--lr-color-warning)`) — Warning badge text color."},{"name":"--lr-tree-checkbox-checked-bg","description":"**`<lr-tree-item>`** (default: `var(--lr-color-brand)`) — Checked control background."},{"name":"--lr-tree-checkbox-checked-border-color","description":"**`<lr-tree-item>`** (default: `var(--lr-color-brand)`) — Checked control border."},{"name":"--lr-tree-checkbox-checked-color","description":"**`<lr-tree-item>`** (default: `var(--lr-color-on-brand)`) — Checked glyph color."},{"name":"--lr-tree-checkbox-indeterminate-bg","description":"**`<lr-tree-item>`** (default: `var(--lr-color-brand)`) — Indeterminate control background."},{"name":"--lr-tree-checkbox-indeterminate-border-color","description":"**`<lr-tree-item>`** (default: `var(--lr-color-brand)`) — Indeterminate control border."},{"name":"--lr-tree-checkbox-indeterminate-color","description":"**`<lr-tree-item>`** (default: `var(--lr-color-on-brand)`) — Indeterminate glyph color."},{"name":"--lr-tree-depth","description":"**`<lr-tree-item>`** (default: `0`) — Internal indent plumbing, not a retheming knob: this node's `depth`, written inline onto `[part=\"row\"]` by the component and multiplied by `--indent-size` (capped at `--lr-size-8rem`) to produce the row's `padding-inline-start`."},{"name":"--lr-tree-selected-bg","description":"**`<lr-tree-item>`** (default: `var(--lr-color-brand-quiet)`) — Background of the selected row."},{"name":"--lr-tree-selected-color","description":"**`<lr-tree-item>`** (default: `var(--lr-color-brand)`) — Text color of the selected row."},{"name":"--lr-typing-dot-size","description":"**`<lr-typing-indicator>`** (default: `var(--lr-space-s)`) — Diameter of each dot in the `dots` and `pulse` variants. The `size` property supplies compact and roomy tier overrides."},{"name":"--lr-typing-dot-stagger-1","description":"**`<lr-typing-indicator>`** (default: `600ms`) — Delay for the second dot in the dots variant."},{"name":"--lr-typing-dot-stagger-2","description":"**`<lr-typing-indicator>`** (default: `1200ms`) — Delay for the third dot in the dots variant."},{"name":"--lr-typing-duration","description":"**`<lr-typing-indicator>`** (default: `var(--lr-transition-ambient)`) — Animation duration and timing function for the dot-bounce/pulse/cursor-blink loop, shared by all variants. Aliases the shared `--lr-transition-ambient` token (default `1.8s ease-in-out`) by default, so retiming just this component doesn't affect other ambient-looping components in the library."},{"name":"--lr-typing-gap","description":"**`<lr-typing-indicator>`** (default: `var(--lr-space-xs)`) — Gap between dots in the `dots` variant. The `size` property supplies compact and roomy tier overrides."},{"name":"--lr-video-playlist-item-current-background","description":"**`<lr-video-playlist>`** (default: `var(--lr-color-brand-fill-quiet)`) — Current playlist-item background."},{"name":"--lr-video-playlist-item-current-border-color","description":"**`<lr-video-playlist>`** (default: `var(--lr-color-brand)`) — Current playlist-item border color."},{"name":"--lr-video-poster-play-button-hover-background","description":"**`<lr-video>`** (default: `color-mix(...)`) — Poster play-button hover background."},{"name":"--lr-video-poster-play-button-hover-border-color","description":"**`<lr-video>`** (default: `var(--lr-color-brand)`) — Poster play-button hover border color."},{"name":"--lr-virtual-list-height","description":"**`<lr-virtual-list>`** (default: `var(--lr-size-24rem)`) — The scroll viewport's height. A virtualized list needs a bounded scroll extent, so this ships a default rather than collapsing to zero when a caller does not size the host. Ignored while `scrollElement` names an external scroller, whose own height is the visible band."},{"name":"--lr-virtual-list-hover-outline-color","description":"**`<lr-virtual-list>`** (default: `var(--lr-color-border-strong)`) — Outline color of the mouse-hover preview on `[part=\"base\"]` (a subtler, always-focusable-target preview of its own `:focus-visible` ring). Set to `transparent` to opt out of the hover treatment entirely."},{"name":"--lr-virtual-list-hover-outline-offset","description":"**`<lr-virtual-list>`** (default: `calc(-1 * var(--lr-border-width-thin))`) — Inward offset of the mouse-hover preview on `[part=\"base\"]`, keeping the outline inside its own scrollport so it is not clipped at the edge."},{"name":"--lr-virtual-list-hover-outline-style","description":"**`<lr-virtual-list>`** (default: `solid`) — Outline style of the mouse-hover preview on `[part=\"base\"]`."},{"name":"--lr-virtual-list-hover-outline-width","description":"**`<lr-virtual-list>`** (default: `var(--lr-border-width-thin)`) — Outline width of the mouse-hover preview on `[part=\"base\"]`."},{"name":"--lr-voice-picker-gap","description":"**`<lr-voice-picker>`** (default: `var(--lr-space-xs)`) — Gap between the field and preview action, and between trigger, combobox, and option children."},{"name":"--lr-voice-picker-max-inline-size","description":"**`<lr-voice-picker>`** (default: `var(--lr-size-24rem)`) — The host's own width ceiling. Set a length to retune it, or `none` to let the control fill its container the way `<lr-select>` does."},{"name":"--lr-voice-picker-open-border-color","description":"**`<lr-voice-picker>`** (default: `var(--lr-color-brand)`) — Open trigger border color."},{"name":"--lr-voice-picker-option-active-bg","description":"**`<lr-voice-picker>`** (default: `var(--lr-color-brand-quiet)`) — Active option fill."},{"name":"--lr-voice-picker-option-disabled-opacity","description":"**`<lr-voice-picker>`** (default: `0.5`) — Opacity of an option row whose catalog entry sets `disabled`."},{"name":"--lr-voice-picker-option-selected-bg","description":"**`<lr-voice-picker>`** (default: `transparent`) — Selected option fill."},{"name":"--lr-voice-picker-option-selected-border","description":"**`<lr-voice-picker>`** (default: `var(--lr-color-brand)`) — Selected option border."},{"name":"--lr-voice-picker-option-selected-color","description":"**`<lr-voice-picker>`** (default: `var(--lr-color-brand)`) — Selected option text."},{"name":"--lr-voice-picker-option-selected-font-weight","description":"**`<lr-voice-picker>`** (default: `var(--lr-font-weight-semibold)`) — Selected option label weight."},{"name":"--lr-voice-picker-option-synthetic-border-color","description":"**`<lr-voice-picker>`** (default: `var(--lr-color-border)`) — Border color of a synthetic stale-value option row."},{"name":"--lr-voice-picker-option-synthetic-border-style","description":"**`<lr-voice-picker>`** (default: `dashed`) — Border style of a synthetic stale-value option row."},{"name":"--lr-voice-picker-option-synthetic-font-style","description":"**`<lr-voice-picker>`** (default: `italic`) — Font style of a synthetic stale-value option label."},{"name":"--lr-voice-picker-preview-active-border","description":"**`<lr-voice-picker>`** (default: `var(--lr-color-brand)`) — Active preview border."},{"name":"--lr-voice-picker-preview-active-color","description":"**`<lr-voice-picker>`** (default: `var(--lr-color-brand)`) — Active preview icon."},{"name":"--lr-voice-picker-preview-hover-bg","description":"**`<lr-voice-picker>`** (default: `var(--lr-color-brand-quiet)`) — Shared hover/press fill for the standalone and row preview actions."},{"name":"--lr-voice-picker-preview-hover-color","description":"**`<lr-voice-picker>`** (default: `var(--lr-color-brand)`) — Shared hover/press icon color for the standalone and row preview actions."},{"name":"--lr-voice-picker-radius","description":"**`<lr-voice-picker>`** (default: `var(--lr-form-control-radius)`) — Trigger, combobox, listbox, option, and preview-action corner radius."},{"name":"--lr-voice-picker-trigger-border-color","description":"**`<lr-voice-picker>`** (default: `var(--lr-color-border)`) — Resting trigger/combobox border color, independent of the open-state color below."},{"name":"--lr-voice-picker-trigger-fill","description":"**`<lr-voice-picker>`** (default: `var(--lr-color-surface)`) — Resting trigger/combobox background."},{"name":"--lr-voice-picker-trigger-height","description":"**`<lr-voice-picker>`** — Exact trigger/combobox height. Unset by default (a floor only, via `-trigger-min-height`); set a length to both floor and cap the control, e.g. to pixel-match a sibling field in the same toolbar row. Takes precedence over `-trigger-min-height`, and the preview action follows whichever of the two is in play."},{"name":"--lr-voice-picker-trigger-min-height","description":"**`<lr-voice-picker>`** (default: `var(--lr-form-control-height)`) — Trigger/combobox block-size floor. Reads the shared form-control height ladder, so retuning `--lr-theme-form-control-height-*` moves this control and every sibling field together. The preview action follows it, so raising the floor keeps the pair the same height; the action's own WCAG hit-area floor still wins below `--lr-icon-button-size`."},{"name":"--lr-widget-backdrop-inset","description":"**`<lr-widget>`** (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."},{"name":"--lr-widget-fullscreen-inset","description":"**`<lr-widget>`** (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."},{"name":"--lr-widget-overlay-color","description":"**`<lr-widget>`** (default: `var(--lr-color-overlay)`) — The fullscreen scrim's color, applied to `[part=\"backdrop\"]`."},{"name":"--lr-widget-view-toggle-active-bg","description":"**`<lr-widget>`** (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."},{"name":"--lr-widget-view-toggle-active-border-color","description":"**`<lr-widget>`** (default: `transparent`) — Border color of the pressed view toggle. Like the active background and text hooks, it is an inline inherited fallback."},{"name":"--lr-widget-view-toggle-active-color","description":"**`<lr-widget>`** (default: `var(--lr-color-brand)`) — Text color of the pressed view toggle."},{"name":"--lr-widget-view-toggle-hover-bg","description":"**`<lr-widget>`** (default: `var(--lr-color-brand-quiet)`) — Background of a hovered `[part=\"view-toggle\"]`."},{"name":"--lr-widget-view-toggle-hover-color","description":"**`<lr-widget>`** (default: `var(--lr-color-text)`) — Text color of a hovered `[part=\"view-toggle\"]`."},{"name":"--lr-word-cloud-color-1","description":"**`<lr-word-cloud>`** (default: `var(--lr-color-brand)`) — First entry of the default categorical palette."},{"name":"--lr-word-cloud-color-2","description":"**`<lr-word-cloud>`** (default: `var(--lr-color-success)`) — Second entry of the default categorical palette."},{"name":"--lr-word-cloud-color-3","description":"**`<lr-word-cloud>`** (default: `var(--lr-color-warning)`) — Third entry of the default categorical palette."},{"name":"--lr-word-cloud-color-4","description":"**`<lr-word-cloud>`** (default: `var(--lr-color-danger)`) — Fourth entry of the default categorical palette."},{"name":"--lr-word-cloud-color-5","description":"**`<lr-word-cloud>`** (default: `var(--lr-color-chart-1)`) — Fifth entry of the default categorical palette."},{"name":"--lr-word-cloud-color-6","description":"**`<lr-word-cloud>`** (default: `var(--lr-color-chart-2)`) — Sixth entry of the default categorical palette."},{"name":"--lr-word-cloud-color-7","description":"**`<lr-word-cloud>`** (default: `var(--lr-color-chart-3)`) — Seventh entry of the default categorical palette."},{"name":"--lr-word-cloud-color-8","description":"**`<lr-word-cloud>`** (default: `var(--lr-color-chart-4)`) — Eighth entry of the default categorical palette."},{"name":"--lr-xml-viewer-active-attribute-color","description":"**`<lr-xml-viewer>`** (default: `var(--lr-color-brand)`) — Outline color of the `[part=\"attribute\"]` an attribute-addressing `node-path` anchor resolved to."},{"name":"--lr-xml-viewer-active-match-color","description":"**`<lr-xml-viewer>`** (default: `var(--lr-color-warning)`) — Outline color of the `[part=\"node\"]` holding the current search match. Scoped to the active match, so the dashed outline on the other matches keeps the shared warning token."},{"name":"--lr-xml-viewer-highlight-accent-background","description":"**`<lr-xml-viewer>`** (default: `var(--lr-color-brand-quiet)`) — Row background of an accent-tone (the default tone) `highlights` entry."},{"name":"--lr-xml-viewer-highlight-active-outline","description":"**`<lr-xml-viewer>`** (default: `var(--lr-color-brand)`) — Outline color of the `highlights` entry currently named by `activeHighlightId`."},{"name":"--lr-xml-viewer-highlight-danger-background","description":"**`<lr-xml-viewer>`** (default: `var(--lr-color-danger-quiet)`) — Row background of a danger-tone `highlights` entry."},{"name":"--lr-xml-viewer-highlight-neutral-background","description":"**`<lr-xml-viewer>`** (default: `var(--lr-color-surface-raised)`) — Row background of a neutral-tone `highlights` entry. Deliberately not `--lr-color-surface`: the viewer's own ambient background would render a neutral highlight as unhighlighted."},{"name":"--lr-xml-viewer-highlight-success-background","description":"**`<lr-xml-viewer>`** (default: `var(--lr-color-success-quiet)`) — Row background of a success-tone `highlights` entry."},{"name":"--lr-xml-viewer-highlight-warning-background","description":"**`<lr-xml-viewer>`** (default: `var(--lr-color-warning-quiet)`) — Row background of a warning-tone `highlights` entry."},{"name":"--lr-xml-viewer-match-bg","description":"**`<lr-xml-viewer>`** (default: `var(--lr-color-warning-quiet)`) — Background of a matching `[part=\"tag\"]`/`[part=\"attribute-value\"]`."},{"name":"--lr-xml-viewer-match-color","description":"**`<lr-xml-viewer>`** (default: `var(--lr-color-warning)`) — Outline color of a (non-active) `[part=\"node\"]` search match, and the tint source for a matching `[part=\"text\"]`'s background. Distinct from `--lr-xml-viewer-active-match-color`, so the non-active matches can be recolored without touching the active one."},{"name":"--lr-xml-viewer-max-height","description":"**`<lr-xml-viewer>`** (default: `none`) — Maximum block size of the scrollable body before it scrolls internally. Also settable via the `max-height` property."},{"name":"--lr-xml-viewer-tag-color","description":"**`<lr-xml-viewer>`** (default: `var(--lr-color-brand)`) — Text color of `[part=\"tag\"]`, an element's rendered tag name, independent of the active-attribute outline above."},{"name":"--lr-zoomable-frame-control-hover-background","description":"**`<lr-zoomable-frame>`** (default: `var(--lr-color-brand-quiet)`) — Zoom control hover background; its active background derives from the same value."},{"name":"--lr-zoomable-frame-zoom","description":"**`<lr-zoomable-frame>`** (default: `1`) — Read-only resolved iframe scale written from `zoom`."},{"name":"--main-width","description":"**`<lr-page>`** — Web Awesome alias for `--lr-page-main-width`."},{"name":"--marker-height","description":"**`<lr-slider>`** — Marker block size."},{"name":"--marker-width","description":"**`<lr-slider>`** — Marker inline size."},{"name":"--mask-char","description":"**`<lr-otp-input>`** (default: `'•'`) — Mapped alias for `--lr-otp-input-mask-char`."},{"name":"--max","description":"**`<lr-split-panel>`** (default: `100%`) — Maximum size of the primary pane, or the start pane when `primary` is unset."},{"name":"--max-height","description":"**`<lr-data-grid>`** (default: `var(--lr-size-30rem)`) — Scroll viewport maximum height; `none` renders all."},{"name":"--max-width","description":"**`<lr-dropdown>`** (default: `var(--lr-overlay-max-inline-size,var(--lr-size-20rem))`) — Maximum inline size inherited from the popover surface.\n\n**`<lr-popover>`** (default: `var(--lr-overlay-max-inline-size,var(--lr-size-20rem))`) — Maximum inline size of the popup.\n\n**`<lr-tooltip>`** (default: `var(--lr-tooltip-max-inline-size,var(--lr-size-20rem))`) — Maximum inline size of the tooltip."},{"name":"--menu-width","description":"**`<lr-page>`** — Web Awesome alias for `--lr-page-menu-width`."},{"name":"--min","description":"**`<lr-split-panel>`** (default: `0`) — Minimum size of the primary pane, or the start pane when `primary` is unset."},{"name":"--padding","description":"**`<lr-card>`** (default: `var(--spacing,var(--lr-space-m))`) — Shoelace-compatible section padding.\n\n**`<lr-tab-panel>`** (default: `0`) — Inner panel padding.\n\n**`<lr-toast-item>`** — Mapped alias for `--lr-toast-padding`."},{"name":"--point-radius","description":"**`<lr-bar-chart>`, `<lr-bubble-chart>`, `<lr-chart>`, `<lr-doughnut-chart>`, `<lr-histogram>`, `<lr-line-chart>`, `<lr-pie-chart>`, `<lr-polar-area-chart>`, `<lr-radar-chart>`, `<lr-scatter-chart>`** (default: `var(--lr-space-2xs)`) — Line/scatter point radius."},{"name":"--popup-border-width","description":"**`<lr-popup>`** (default: `var(--lr-border-width-thin)`) — Popup/arrow border width."},{"name":"--poster-play-button-background","description":"**`<lr-video>`** (default: `var(--lr-color-surface-overlay)`) — Poster play-button background."},{"name":"--primary-color","description":"**`<lr-icon>`** (default: `currentColor`) — Primary duotone layer color."},{"name":"--primary-opacity","description":"**`<lr-icon>`** (default: `1`) — Primary duotone layer opacity."},{"name":"--pulse-color","description":"**`<lr-badge>`, `<lr-tag>`** (default: `var(--lr-badge-pulse-color)`) — Upstream-compatible pulse-ring color."},{"name":"--row-height","description":"**`<lr-data-grid>`** (default: `var(--lr-size-3-5rem)`) — Estimated and minimum row height."},{"name":"--row-hover-background","description":"**`<lr-data-grid>`** — Hovered-row background."},{"name":"--scroll-hint","description":"**`<lr-carousel>`** — Logical padding that reveals the nearest adjacent slides."},{"name":"--secondary-color","description":"**`<lr-icon>`** (default: `currentColor`) — Secondary duotone layer color."},{"name":"--secondary-opacity","description":"**`<lr-icon>`** (default: `0.4`) — Secondary duotone layer opacity."},{"name":"--segment-border-radius","description":"**`<lr-otp-input>`** (default: `var(--lr-form-control-radius,var(--lr-radius))`) — Corner radius of a segment."},{"name":"--segment-gap","description":"**`<lr-otp-input>`** (default: `var(--lr-space-xs)`) — Gap between segments; ignored by `contained`."},{"name":"--segment-size","description":"**`<lr-otp-input>`** (default: `2.5em`) — Exact inline and block size of each non-shrinking segment at the default size tier."},{"name":"--selected-background","description":"**`<lr-data-grid>`** (default: `var(--lr-color-brand-quiet)`) — Selected-row background."},{"name":"--shadow-color","description":"**`<lr-scroller>`** (default: `var(--lr-color-surface)`) — Base color of each edge shadow."},{"name":"--shadow-size","description":"**`<lr-scroller>`** (default: `var(--lr-size-2rem)`) — Inline/block extent of each edge shadow."},{"name":"--sheen-color","description":"**`<lr-skeleton>`** (default: `var(--lr-skeleton-sheen-color)`) — Upstream-compatible sheen color."},{"name":"--show-delay","description":"**`<lr-tooltip>`** (default: `150ms`) — Interaction show delay when `show-delay` is not explicit."},{"name":"--show-duration","description":"**`<lr-accordion-item>`** — Upstream-compatible alias for `--lr-accordion-item-show-duration`.\n\n**`<lr-combobox>`** (default: `var(--lr-transition-fast)`) — Listbox enter-transition duration.\n\n**`<lr-date-input>`** (default: `var(--lr-transition-fast)`) — Popup enter-transition duration.\n\n**`<lr-details>`** (default: `var(--lr-duration-base)`) — Expand-icon transition duration.\n\n**`<lr-dialog>`** — Mapped opening animation duration.\n\n**`<lr-drawer>`** — Opening slide duration.\n\n**`<lr-dropdown>`** (default: `var(--lr-transition-fast)`) — Opening transition duration.\n\n**`<lr-popover>`** (default: `var(--lr-duration-fast)`) — Opening transition duration.\n\n**`<lr-popup>`** (default: `var(--lr-duration-fast)`) — Activation transition duration.\n\n**`<lr-select>`** (default: `var(--lr-transition-fast)`) — Listbox enter-transition timing.\n\n**`<lr-time-input>`** (default: `var(--lr-duration-fast)`) — Picker opening duration.\n\n**`<lr-toast-item>`** — Mapped alias for `--lr-toast-show-duration`.\n\n**`<lr-tree-item>`** (default: `var(--lr-duration-base)`) — Expansion motion duration."},{"name":"--size","description":"**`<lr-avatar>`** (default: `var(--lr-avatar-size)`) — Upstream-compatible avatar diameter.\n\n**`<lr-drawer>`** — Mapped drawer size for the active axis.\n\n**`<lr-progress-ring>`** (default: `var(--lr-progress-ring-size)`) — Upstream-compatible outer diameter."},{"name":"--slide-gap","description":"**`<lr-carousel>`** (default: `var(--lr-space-m)`) — Gap between slides."},{"name":"--slider-handle-size","description":"**`<lr-color-picker>`** — Upstream alias for `--lr-color-picker-slider-handle-size`."},{"name":"--slider-height","description":"**`<lr-color-picker>`** — Upstream alias for `--lr-color-picker-slider-block-size`."},{"name":"--spacing","description":"**`<lr-accordion-item>`** — Upstream-compatible alias for `--lr-accordion-item-spacing`.\n\n**`<lr-card>`** (default: `var(--lr-space-m)`) — Space around and between card sections.\n\n**`<lr-details>`** — Upstream-compatible spacing override for the summary and content.\n\n**`<lr-dialog>`** (default: `var(--lr-dialog-spacing,var(--lr-space-l))`) — Mapped shared region spacing.\n\n**`<lr-divider>`** (default: `0`) — Space on both block sides (inline sides when vertical).\n\n**`<lr-drawer>`** (default: `var(--lr-dialog-spacing,var(--lr-space-l))`) — Web Awesome shared region spacing."},{"name":"--speed","description":"**`<lr-spinner>`** (default: `var(--lr-spinner-duration)`) — Upstream-compatible rotation duration."},{"name":"--stripe-background","description":"**`<lr-data-grid>`** (default: `var(--lr-color-surface-raised)`) — Alternating-row background."},{"name":"--subheader-height","description":"**`<lr-page>`** — Web Awesome alias for `--lr-page-subheader-height`."},{"name":"--submenu-offset","description":"**`<lr-dropdown-item>`, `<lr-menu-item>`** (default: `-2px`) — Final signed distance between a submenu and its parent row. Negative values overlap the parent menu; positive values add separation. Mirrors under RTL."},{"name":"--success-color","description":"**`<lr-copy-button>`** (default: `var(--lr-color-success)`) — Success-state icon color."},{"name":"--swatch-size","description":"**`<lr-color-picker>`** — Shoelace alias for `--lr-color-picker-palette-swatch-size`."},{"name":"--swing-angle","description":"**`<lr-icon>`** (default: `15deg`) — Peak swing angle."},{"name":"--symbol-color","description":"**`<lr-rating>`** (default: `var(--lr-rating-empty-color,var(--lr-color-border))`) — Compatibility alias for the inactive symbol color. `--lr-rating-empty-color` wins when both are set."},{"name":"--symbol-color-active","description":"**`<lr-rating>`** (default: `var(--lr-rating-fill,var(--lr-color-warning))`) — Compatibility alias for the active symbol color. `--lr-rating-fill` wins when both are set."},{"name":"--symbol-size","description":"**`<lr-rating>`** — Shoelace-compatible symbol size. It feeds the current `size` step when `--lr-rating-size` is unset; the Lyra-prefixed property wins when both are set."},{"name":"--symbol-spacing","description":"**`<lr-rating>`** (default: `var(--lr-space-xs)`) — Compatibility spacing around symbols."},{"name":"--tag-max-size","description":"**`<lr-combobox>`** (default: `var(--lr-size-5rem)`) — Maximum inline size of a built-in selected tag.\n\n**`<lr-select>`** (default: `var(--lr-size-12rem)`) — Maximum inline size of one selected-value tag."},{"name":"--text-color","description":"**`<lr-data-grid>`** (default: `var(--lr-color-text)`) — Grid foreground."},{"name":"--thumb-height","description":"**`<lr-slider>`** — Upstream thumb block size."},{"name":"--thumb-size","description":"**`<lr-slider>`** — Shoelace alias setting both thumb dimensions.\n\n**`<lr-switch>`** (default: `calc(var(--height, var(--lr-switch-track-block-size)) - (var(--lr-switch-thumb-offset) * 2))`) — WA/Shoelace thumb diameter alias."},{"name":"--thumb-width","description":"**`<lr-slider>`** — Upstream thumb inline size."},{"name":"--tooltip-offset","description":"**`<lr-slider>`** — Shoelace tooltip distance alias."},{"name":"--track-active-offset","description":"**`<lr-slider>`** — Additional indicator offset."},{"name":"--track-color","description":"**`<lr-progress-bar>`** (default: `var(--lr-progress-track-color)`) — Upstream-compatible track color.\n\n**`<lr-progress-ring>`** (default: `var(--lr-progress-ring-track-color)`) — Upstream-compatible track color.\n\n**`<lr-spinner>`** (default: `var(--lr-color-brand-quiet)`) — Upstream-compatible track color.\n\n**`<lr-tab-group>`** — Upstream track color."},{"name":"--track-color-active","description":"**`<lr-slider>`** — Filled indicator color."},{"name":"--track-color-inactive","description":"**`<lr-slider>`** — Resting track color."},{"name":"--track-height","description":"**`<lr-progress-bar>`** (default: `var(--lr-progress-track-height)`) — Web Awesome-compatible track height.\n\n**`<lr-slider>`** — Shoelace alias for track thickness."},{"name":"--track-size","description":"**`<lr-slider>`** — Web Awesome alias for track thickness."},{"name":"--track-width","description":"**`<lr-progress-ring>`** (default: `var(--lr-progress-ring-track-width)`) — Upstream-compatible track width.\n\n**`<lr-spinner>`** (default: `var(--lr-spinner-track-width)`) — Upstream-compatible track width.\n\n**`<lr-tab-group>`** — Upstream track width."},{"name":"--transition-duration","description":"**`<lr-data-grid>`** (default: `var(--lr-duration-fast)`) — Interaction transition duration."},{"name":"--wag-angle","description":"**`<lr-icon>`** (default: `12deg`) — Peak wag angle."},{"name":"--width","description":"**`<lr-dialog>`, `<lr-drawer>`** (default: `var(--lr-dialog-width,auto)`) — Mapped panel width alias.\n\n**`<lr-divider>`** (default: `var(--lr-border-width-thin)`) — Separator thickness.\n\n**`<lr-switch>`** (default: `var(--lr-switch-track-inline-size)`) — WA/Shoelace alias for the track's inline size.\n\n**`<lr-toast>`** — Mapped alias for `--lr-toast-width`."}]}}}
