<!-- GENERATED by scripts/build-llms.mjs from llms/agent-tools.md — do not edit this file. -->

# `lr-compare-panel`

- **Import** `import '@aceshooting/lyra-ui/components/lr-compare-panel.js';` (stable tag alias; registers the tag)
- **Class** `LyraComparePanel`, also available unregistered from `@aceshooting/lyra-ui/components/agent-tools/compare-panel/compare-panel.class.js`
- **Family** `components/agent-tools/` — see `llms/index.md` for its siblings
- **Status** `stable` since `4.0.0` — see the maturity and deprecation policy in `llms/shared.md`
- **Release history** [CHANGELOG.md](../../CHANGELOG.md); family-wide breaking-change summaries: [llms-full.txt](../../llms-full.txt)
- **Deprecations** none
- **Optional peers** none
- **Themeable via** 9 parts, 5 custom properties — see this component's own `@csspart`/`@cssprop` list below
- **Library-wide behavior** (events, form association, `locale`/`strings`, tokens, TS types): `llms/shared.md`

---

## `lr-compare-panel`

Side-by-side A/B output comparison with a winner vote (LMSYS-arena / LangSmith-pairwise style): two
slotted panes, a vote bar, synchronized reading.

Disabled vote buttons retain their resting colors during hover and press, including an existing
selected vote.

At narrow widths, stacked response panes size to their content up to
`--lr-compare-panel-max-height`. Short responses remain fully readable; longer responses retain the
configured height limit and scrolling.

**Properties:** `labelA: string = ''` (attribute `label-a`) and `labelB: string = ''` (attribute
`label-b`) — pane headings. `vote: 'a' | 'b' | 'tie' | 'both-bad' | null = null` (reflected) — the
recorded winner, host-writable to reflect a previously-recorded vote back. `itemId: string = ''`
(attribute `item-id`) — an opaque id round-tripped through `lr-vote`. Changing only `itemId` clears
the prior vote; assigning both `itemId` and a controlled `vote` in one update preserves the explicit
vote regardless of property assignment order. `allowedVotes: readonly CompareVote[] = ['a', 'b',
'tie', 'both-bad']` (attribute: false) is the positive list of choices to render, always projected
in that canonical order; repeated/foreign values do not create controls. The list is clone-owned,
bounded, and frozen; reassign a new array after changing the allowed choices. `syncScroll: boolean =
false` (attribute `sync-scroll`) links both panes'
scroll position. `disabled: boolean = false` (reflected) disables every vote button and suppresses
`lr-vote`.

**Slots:** `a` (the first output — any content, a chat message, markdown, a viewer), `b` (the second
output), and `prompt` (optional shared-input header above both panes).

**Events:** `lr-vote` — `detail: { choice: 'a' | 'b' | 'tie' | 'both-bad'; itemId: string }`.
This is a cancelable veto point emitted before `vote` changes; call `preventDefault()` to preserve
the prior vote.

**CSS parts:** `base` (the outer wrapper), `prompt` (the optional prompt header, hidden when the
`prompt` slot is empty), `panes` (the row, or under 640px column, wrapping both panes), `pane-a`,
`pane-b` (each pane's labeled scroll region), `pane-header` (a pane's visible heading), `vote-bar`
(the `role="group"` row of vote buttons), `vote-button` (one vote button), and `live-region` (the
internal vote-announcement live region).

**Themeable custom properties:** `--lr-compare-panel-max-height` (default `var(--lr-size-24rem)`) —
cap on each pane's scroll region before it scrolls internally;
`--lr-compare-panel-selected-background` (default `var(--lr-color-brand-quiet)`),
`--lr-compare-panel-selected-border-color` (default `var(--lr-color-brand)`), and
`--lr-compare-panel-selected-color` (default `var(--lr-color-brand)`), and
`--lr-compare-panel-selected-font-weight` (default `var(--lr-font-weight-semibold)`) style the
selected vote button without changing shared brand tokens.
