# Spin
> Generated from spin.contract.json — do not edit by hand.

A brand-coloured spinner for an indeterminate wait — loading a page, a panel, or results.

Tier: **leaf-lit**. Frameworks: HTML (paste-and-run, no build step) · React · Vue 3.

Surfaces: editor, dashboard, audience.

## Props
| Prop | Type | Default | Notes |
| --- | --- | --- | --- |
| `size` | small | default | large | `default` | Spinner diameter |
| `tip` | string | `—` | Optional caption shown under the ring |
| `spinning` | boolean | `false` | Wrapper mode only (with slotted children): show/hide the overlay scrim + centred ring. Toggling it flips a class on a persistent node — the child subtree is never rebuilt. |

## Visual standard (measured)
- Ring: 20×20 · 2px · track purple-20, head primary #6A1EBB
- Sizes: small 14 · default 20 · large 32
- Motion: rotate 0.9s linear infinite (respects reduced-motion); scrim fade + blur via motion-mid
- Tip: optional caption below (standalone) or under the centred ring (wrapper), text-secondary
- Wrapper: slot children; when spinning, scrim = bg-container @60% over blurred child, ring centred

## When to use
- **Spin** — an indeterminate wait with no measurable percentage
- **Progress** — you can measure completion (a percentage)
- **Skeleton** — you want to hold the shape of the content that is loading

Reach for Spin only when you cannot show a percentage or hold the layout. Keep one spinner per waiting region; pair it with a short tip for waits over ~1s. To block a region while it loads, wrap the content and toggle `spinning` rather than swapping it for a bare centred spinner — the layout holds and the child stays mounted.
