SPINNER: Loading indicator (border spinner)
VARIANTS: Base | Sm | Lg | any tw:text-* colour

Indicates an indeterminate loading state. Colour inherits from currentColor — pair with a semantic text utility. Always carries role="status" and an accessible name. For buttons, keep using .tw-btn-loading; this component is for pages, cards, and panels. Ported per DR-2026-12.

Colours

Colour: set with a text utility; the border uses currentColor.

<div class="tw-spinner-border tw:text-primary" role="status" aria-label="Loading"></div>

Sizes

<div class="tw-spinner-border tw-spinner-border-sm ..."> · <div class="tw-spinner-border tw-spinner-border-lg ...">

With visible label (loading panel)

Loading applications…

<div class="tw-spinner-border ..." aria-hidden="true"></div><p>Loading applications…</p> — when a visible label exists, hide the ring from assistive tech instead of double-announcing.

Dots and bars

Shapes for other jobs: a ring is wrong for a typing indicator or an inline activity meter. Both inherit currentColor like the border spinner and calm their animation under reduced motion. Markup is three unclassed <span> children.

Emma is typing…
<span class="tw-spinner-dots" role="status" aria-label="Emma is typing"><span></span><span></span><span></span></span>