## accordion (`poetry_accordion`)

A vertically stacked set of interactive headings that each reveal a section of content.

Class: Poetry::Ui::Accordion::Component - BEM block `poetry-ui-accordion`.
Slot REQUIRED: with_item (at least one item) - a call without it raises.
- `collapsible:` (boolean) - default false - With type: :single, allows the open section to be closed again.
- `heading_level:` (symbol) - one of h2|h3|h4|h5|h6, default "h3" - The heading element wrapping each trigger; pick it to fit the page outline.
- `open:` (list) - default "dynamic" - Value keys of the sections rendered expanded on load.
- `type:` (symbol) - one of single|multiple, default "single" - Whether one section (:single) or several (:multiple) may be open at once.
Slots: items (The accordion sections. Each takes value: (its open-state key), title:, and a block of panel content; disabled: true locks the section closed.; many; with_item yields NOTHING to the block - no |param|, write content directly).
- PART `accordion` - The list root - both controllers (the open-set machine and roving focus) ride here | states: data-orientation=vertical (always vertical - the only axis the accordion ships)
- PART `accordion-item` - One value-keyed section wrapping its header and panel | states: data-open (the item is expanded (server-rendered from open:; the controller flips the pair at runtime)); data-closed (the item is collapsed); data-value (the item's open-state key (always present)); data-disabled (with_item(disabled: true) - the item is locked (styling hook; the trigger carries the native disabled attribute))
- PART `accordion-header` - The heading element (heading_level:, h3 default) hosting the trigger button
- PART `accordion-trigger` - The toggle button inside the header - the chevron rotation rides aria-expanded, not a data attribute | states: data-panel-open (its panel is open (controller-written; absent while closed)); data-disabled (with_item(disabled: true) - stamped beside the native disabled attribute; roving focus filters it out at query time)
- PART `accordion-trigger-icon` - The chevron svg inside the trigger (aria-hidden) - rotates with the item
- PART `accordion-content` - The role=region panel - the presence animation and the measured height var ride here | states: data-open (panel is open or entering); data-closed (panel is closed or animating out (hidden lands after the exit finishes)) | vars: --accordion-panel-height (the measured content height (controller-written) that feeds the accordion-down/up keyframes)
- WIRING root: `poetry--core--accordion` registers; values type, collapsible | `poetry--core--roving-focus` registers; values orientation, manage_tabindex; actions keydown on keydown
- WIRING trigger: `poetry--core--accordion` actions toggle on click
- RULE: Items via with_item(value:, title:) { panel content } - value is the open-state key.
- RULE: type: :single (default) opens one at a time; pass collapsible: true to allow closing it.
- RULE: Server-render the open item(s) via open: %w[value] - never toggle data-open/data-closed by hand.
- RULE: heading_level: fits the page outline (h3 default) - the trigger button lives inside it.
- RULE: The chevron is built in - never add another indicator icon to the trigger.
- RULE: disabled: true on with_item locks that item (native disabled on the trigger; roving focus skips it).
