The feedback components are one story told at different distances: something happened, or nothing
is here, or something is still coming. What separates them is not their look but **how loudly they
say it** and **where the reader's attention already is**.

## The two channels

A screen reader is told about a change through a live region, and there are only two volumes:

| Channel | Role | When it speaks |
| --- | --- | --- |
| Polite | `status` | When the reader is idle, it waits its turn, and never interrupts a sentence |
| Assertive | `alert` | Immediately, interrupting whatever is being read |

Only a failure interrupts. Everything else waits. That rule is already in the components: an
`Alert` with `type="error"` or `type="warning"` is a `role="alert"`, while `info` and `success` are
a `role="status"`, the same component, at two volumes, chosen by what it is saying rather than by
how it looks.

A toast is a `status` too. It is a report of something the reader just did, not an emergency.

## Which surface

| The situation | The surface | Why that one |
| --- | --- | --- |
| The state of the thing on screen changed | [Alert](/components/feedback/alert) | It sits beside what it is about, so the connection is spatial as well as announced |
| A result of an action that has just finished | [Toast](/components/feedback/toast) | The reader is looking at where they acted, not at a corner of the window |
| A collection is empty | [EmptyState](/components/feedback/empty-state) | It replaces the content, so it explains the absence where the content would be |
| A load failed | [ErrorState](/components/feedback/error-state) | Same place as the content, with the retry beside the explanation |
| A region is on its way | [LoadingState](/components/feedback/loading-state) | It claims the room the content will take, so the page does not jump |
| The shape of what is coming is known | [Skeleton](/components/feedback/skeleton) | The reader learns the layout before the text arrives |
| A small, indeterminate wait | [Spinner](/components/feedback/spinner) | A busy indicator inside a control or a row |

The distinction worth holding on to: **an alert is about something on the page; a toast is about
something the reader did.** An alert that is really a result belongs in a toast, and a toast that
is really a state belongs beside the thing it is about.

## Silence is a decision too

Some of these are deliberately quiet, and the props say so:

- `Skeleton` is `aria-hidden` by default, because a placeholder that announces itself as a status
  is noise; `isBusy` with a `label` makes it a labelled busy status instead, which is what a
  skeleton with no visible text needs.
- `Spinner` is decorative, it carries `aria-hidden`, so a spinner inside a button is described
  by the button's own label, and a spinner on its own needs a `role="status"` wrapper and a label.
- `LoadingState` is always a `status`, because it is the region's whole presentation.
- `EmptyState` and `ErrorState` take the announcement as an option, not an assumption: a heading
  that is empty in the page's first markup was not a change, so announcing it would describe
  something that never happened. They announce when they are the answer to something, and because
  that is a decision about a product rather than about one screen it is registrable as well:
  `components.emptystate.role` (default `none`) and `components.errorstate.role` (default `alert`)
  state it once, and the instance's own `role` wins over them.

That rule is not stylistic. `DataTable` applies it to its own empty state: the presentation is a
`status` while it answers a query, and silent on first paint.

## Rules that hold everywhere

- **Nothing moves focus.** Feedback reports; it does not take the reader somewhere. A retry is a
  button the reader can tab to, not a focus target that grabs them.
- **A busy region keeps its size.** The spinner's or skeleton's room is claimed, so the content
  does not shove the page around when it arrives.
- **A failure says what to do next.** A message that only says "something went wrong" costs the
  reader a guess; `ErrorState`'s retry and `Alert`'s action are where the next step goes.
- **The four states are the whole set.** A region that can load can also be empty, can fail, and
  can be loading. A page that renders only the success case has three bugs waiting.

See [Accessibility](/concepts/accessibility) for the keyboard and role model the rest of the
library follows.
