## checkbox (`poetry_checkbox`)

A control for toggling a single value on or off.

Class: Poetry::Ui::Checkbox::Component - BEM block `poetry-ui-checkbox`.
- `checked:` (checked_state) - default false - The state as ONE tri-valued option (true, false, or :indeterminate) - there is no separate indeterminate: flag.
- `disabled:` (boolean) - default false - Disables the visual button and the hidden input together.
- `label:` (string) - aria-label fallback when no <label for>/Field association exists.
- `name:` (string) - Form participation: present renders the hidden native input pair; absent leaves the checkbox visual-only (controlled UI).
- `required:` (boolean) - default false - aria-required ONLY, never native required - native required on the hidden input would make an unfocusable control invalid.
- `unchecked_value:` (string) - default "0" - The paired hidden input's value submitted when unchecked; nil suppresses the pair (the checkbox-array idiom).
- `value:` (string) - default "1" - The value submitted when checked (the Rails check_box "1").
- PART `checkbox` - The visual button[role=checkbox] - reflects the hidden input via aria-checked plus the checked triple | states: data-checked (checked (the controller reflects every toggle here, aria-checked in step)); data-unchecked (unchecked - the indicator goes invisible); data-indeterminate (checked: :indeterminate (server/programmatic only; the first toggle resolves it to checked))
- PART `checkbox-indicator` - Centering span around the check glyph (minus when indeterminate) - CSS-hidden while unchecked, never unmounted | states: data-checked (mirrors the control (the controller reflects state on every part wearing the triple)); data-unchecked (mirrors the control - the indicator is invisible); data-indeterminate (mirrors the control - the glyph swaps to minus)
- WIRING root: `poetry--core--checked` registers; values input_id (if form_participant?); actions toggle on click
- RULE: A select-all run rides poetry_checkbox_group (wrapper) + poetry_checkbox_group_all (the mixed-state parent) + poetry_checkbox_group_item per member - toggles fan out and re-derive automatically.
- RULE: Use poetry_checkbox (or f.check_box) - never a raw input[type=checkbox] with hand-written Tailwind, and never a hand-rolled button[role=checkbox].
- RULE: Always give it a name: in forms - a checkbox without one submits nothing (visual-only mode is for controlled UI like DataTable row selection ONLY).
- RULE: Every checkbox needs an accessible name: a Label/Field for= association (preferred) or label:.
- RULE: Indeterminate is set programmatically/server-side only - no user gesture produces it; use it for select-all parents.
- RULE: Select-all recipe: wrap parent + rows in data-controller="poetry--core--checkbox-group" with data-action="poetry:checkbox:change->poetry--core--checkbox-group#changed"; mark the parent box data: {"poetry--core--checkbox-group-target": "all"} and each row box target "item" - the parent fans out, rows re-derive checked/unchecked/indeterminate (DataTable's selectable: already does this for its own rows).
- RULE: Instant-effect settings use Switch; pressed UI tools use Toggle; one-of-N uses RadioGroup.
- RULE: NEVER write the checked attributes (data-checked/data-unchecked/data-indeterminate) without aria-checked and the input's checked property (the controller writes all three; agents patching DOM must too).
- RULE: Don't suppress unchecked_value unless using the array idiom - an unchecked box that submits nothing silently keeps the old server value.
