A radio group asks for exactly one option out of a set the reader can see. It is the
honest control while the options still fit on the page: everything is visible at once, so
comparing the choices costs no interaction. `RadioGroup` is the field, it carries the
label, the description, the message and the status, and it owns the selection, and `Radio`
is one option inside it, receiving the group's state, name and tokens through context.

```tsx demo="forms/radio-preview"
```

## Usage

```tsx
import { Radio, RadioGroup } from "@asheeui/web";

<RadioGroup label="Delivery speed" defaultValue="standard">
  <Radio value="standard" label="Standard" />
  <Radio value="express" label="Express" />
</RadioGroup>
```

An uncontrolled group keeps the selection itself, which is enough while nothing else on
the page needs it. Pass `value` and `onChange` when the selection has to live with the rest
of the form, so the group reports the chosen value and the consumer decides what it means:

```tsx
<RadioGroup label="Delivery speed" value={speed} onChange={setSpeed}>
  <Radio value="standard" label="Standard" />
  <Radio value="express" label="Express" />
</RadioGroup>
```

## Variants

Two shapes, stated once for the whole group. `default` draws the circle and puts the label
beside it; `card` makes each option a bordered panel, so the choices read as blocks rather
than as lines. An application that wants cards everywhere states `variant: "card"` under
`components.radio` and every group follows.

The variant changes the panel, not the circle: a card still draws the circle at the radius
the radio resolves, while the panel rounds `full` down to `xl`, a card with pill corners
would be two vocabularies at once.

```tsx demo="forms/radio-variants"
```

## Orientation

`orientation` defaults to `vertical`, a column of options. Set it to `horizontal` and the
group lays the options in a row that wraps, which suits short labels that read as a single
question; a column is the better shape when an option needs a description underneath it,
because the descriptions then line up instead of fighting for the same line.

An option can be `disabled` on its own, and `disabled` on the group puts every option out
of reach while the labels stay readable. Everything else is inherited: `size`, `color`,
`variant`, `status` and the shared `name` come from the group unless the item states its
own. A `Radio` used outside a group keeps its own `checked` or `defaultChecked` state.

```tsx demo="forms/radio-orientation"
```

## Props

```props RadioGroup
```

The group's table is the one to read for the field. `label`, `description`, `message` and
`status` belong to the group, because a set of options has no single control to carry them,
and `value` or `defaultValue` is the selection itself.

```props Radio
```

An item needs a `value` and a label. Everything else it renders, the circle's accent, its
density, whether it is a dot or a card, whether it is available, arrives from the group
unless the item states its own, and the item's own prop wins.

Registered defaults belong to the component rather than to the application:
`components.radio` states `variant: "default"` and `radius: "full"`, so a radio stays round
and stays a radio whatever `defaultVariant` and `defaultRadius` say. `color` is not
registered, so it does follow the application's `defaultColor`, and `size` is registered as
`md`.

## Accessibility

- The group is a `role="radiogroup"` container. Its visible label names it through
  `aria-labelledby`, and the description and message are referenced with `aria-describedby`;
  the label is not attached to any one input, because none of them is the field.
- Each option is a real `<input type="radio">` inside its own `<label>`, so the visible text
  is the option's name and the checked state is the browser's. The arrow keys move between
  the options that share the group's generated name, and <kbd>Space</kbd> selects the option
  that has focus.
- The circle is decoration drawn from the input's state, and the focus ring is drawn from
  `focus-visible` on that circle, so it appears for a keyboard and not for a pointer. An
  option's `description` sits inside the same label, so it is read as part of the option's
  name rather than linked separately.
- `disabled` on an item takes it out of the tab order, and on the group takes every item
  with it while the labels stay readable. `required` marks the group's label; because a
  group has no single control to receive the attribute, state the rule in the description
  or the message as well.

The label, description and message behave as the [field anatomy](/concepts/fields) describes.

## Related

```related switch, dropmenu, form
```
