# Radio

## Overview

The radio component is a single-select form control for choosing exactly one option from a related set.

The component pattern uses a native `<fieldset>` with a native `<legend>` and native radio inputs inside wrapping `<label>` elements, so the group keeps its semantics without requiring classed wrappers.

## When to use

Use radios when users must choose one option from a small set that should remain visible.

## When not to use

Do not use radios for a long list or choices that should remain collapsed until interaction; use select.

## Usage

```html
<fieldset>
  <legend>Contact method</legend>
  <label>
    <input type="radio" name="contact-method" value="email" checked />
    Email
  </label>
  <label>
    <input type="radio" name="contact-method" value="phone" />
    Phone
  </label>
</fieldset>
```

Use this component when the user must pick one option from a small, always-visible set.

Use a select instead when the list is longer or should stay collapsed until interaction.

The group should use native `<fieldset>` and `<legend>` elements so assistive technology announces the shared question and the currently selected option in context.

Each radio should stay inside its own wrapping `<label>` so the full text remains clickable without extra helper markup.

## Behavior

Covered by [Playwright behavior tests](../../tests/e2e/forms-inputs.spec.js).

- RDO-001: The group stacks options with shared layout theme spacing rather than radio-specific density values.
- RDO-002: Each option keeps native radio rendering and browser interaction while the accent color follows the shared primary token.
- RDO-003: Disabled options should dim through shared text tokens rather than bespoke disabled colors.
- RDO-004: Focus must remain clearly visible for keyboard users.
## Accessibility

- Use a native `<fieldset>` and `<legend>` for related radio questions instead of a plain container and heading.
- Give every radio in the group the same `name` so browsers enforce the single-selection rule.
- Wrap each radio in a native `<label>` so the label text enlarges the interactive target.
- Keep option text descriptive enough to make sense when announced on its own.
- Do not replace the native radio with custom scripted markup unless the product truly requires behavior the platform cannot provide.

## Variables

| Variable | Type | Description |
| --- | --- | --- |
| `--radio-color-primary` | `<color>` | Sets --radio-color-primary so the component can default to shared theme or layout tokens while exposing an overrideable component API. |
| `--radio-color-primary-subtle` | `<color>` | Sets --radio-color-primary-subtle so the component can default to shared theme or layout tokens while exposing an overrideable component API. |
| `--radio-color-text` | `<color>` | Sets --radio-color-text so the component can default to shared theme or layout tokens while exposing an overrideable component API. |
| `--radio-color-text-accent` | `<color>` | Sets --radio-color-text-accent so the component can default to shared theme or layout tokens while exposing an overrideable component API. |
| `--radio-color-text-subtle` | `<color>` | Sets --radio-color-text-subtle so the component can default to shared theme or layout tokens while exposing an overrideable component API. |
| `--radio-control-border-width` | `<length>` | Sets --radio-control-border-width so the component can default to shared theme or layout tokens while exposing an overrideable component API. |
| `--radio-control-gap` | `<length>` | Sets --radio-control-gap so the component can default to shared theme or layout tokens while exposing an overrideable component API. |
| `--radio-focus-ring-size` | `<length>` | Sets --radio-focus-ring-size so the component can default to shared theme or layout tokens while exposing an overrideable component API. |
| `--radio-font-family-sans` | `Any` | Sets --radio-font-family-sans so the component can default to shared theme or layout tokens while exposing an overrideable component API. |
| `--radio-font-size` | `<length>` | Sets --radio-font-size so the component can default to shared theme or layout tokens while exposing an overrideable component API. |
| `--radio-line-height` | `<number>` | Sets --radio-line-height so the component can default to shared theme or layout tokens while exposing an overrideable component API. |
| `--radio-space-inline` | `<length>` | Sets --radio-space-inline so the component can default to shared theme or layout tokens while exposing an overrideable component API. |

## Depends On

- `--color-primary`
- `--color-primary-subtle`
- `--color-text`
- `--color-text-accent`
- `--color-text-subtle`
- `--font-family-sans`
- `--font-line-height-body`
- `--font-size`
- `--layout-control-border-width`
- `--layout-control-gap`
- `--layout-focus-ring-size`
- `--layout-space-inline`
