# Spinner and skeleton

Status: stable

Show that something is loading.

Loading indicators show that something is on its way. Use a spinner for a short wait or an action in progress. Use skeleton lines when you know the shape of what is coming, such as rows of a list, so the page does not jump when it loads.

Both stop moving for people who have turned on reduced motion.

## Example

```html
<div class="at-stack at-stack--tight">
  <div class="at-inline"><span class="at-spinner" role="status" aria-label="Loading"></span> Loading readings</div>
  <span class="at-skeleton at-skeleton--short"></span>
  <span class="at-skeleton at-skeleton--medium"></span>
</div>
```

## Anatomy

1. **Spinner (.at-spinner)**: 20px by 20px; border: 2px solid var(--at-border); border-top-color: var(--at-border-primary); animation: 0.8s spin

2. **Skeleton line (.at-skeleton)**: height: 1rem /* 16px */; background: var(--at-bg-neutral); border-radius: var(--at-radius-1); animation: 1.4s pulse

## Size and spacing

- **Skeleton widths**: .at-skeleton: 100%; .at-skeleton--medium: 70%; .at-skeleton--short: 40%

- **Spinner**: width and height: 1.25rem /* 20px */

## Variants

### Spinner

A short wait, or an action in progress. Put a few words beside it.

```html
<div class="at-inline"><span class="at-spinner" role="status" aria-label="Loading"></span> Loading readings</div>
```

### Skeleton

Placeholder lines in the shape of the content that is coming. Mix widths so it looks like text.

```html
<div class="at-stack at-stack--tight" aria-busy="true"><span class="at-skeleton"></span><span class="at-skeleton at-skeleton--medium"></span><span class="at-skeleton at-skeleton--short"></span></div>
```

## When to use

- Spinner: waiting for a short load or a save.
- Skeleton: the first load of a list, table or card.

## When not to use

- Loads that finish in under about 300ms: show nothing, to avoid a flash.
- Nothing to load: use an empty state.

## Content

- Say what is loading: "Loading readings", not just "Loading".

## Do and don't

Do: One spinner with a short label.

```html
<div class="at-inline"><span class="at-spinner" role="status" aria-label="Loading readings"></span> Loading readings</div>
```

Don't: Several spinners and no label.

```html
<div class="at-inline"><span class="at-spinner"></span><span class="at-spinner"></span><span class="at-spinner"></span></div>
```

## Do

- Keep the layout stable while loading.

## Don't

- Show a spinner for the whole screen.

## Code

```html
<div class="at-stack at-stack--tight">
  <div class="at-inline"><span class="at-spinner" role="status" aria-label="Loading"></span> Loading readings</div>
  <span class="at-skeleton at-skeleton--short"></span>
  <span class="at-skeleton at-skeleton--medium"></span>
</div>
```

## Classes

| Class | What it does |

|---|---|

| `at-spinner` | Rotating ring |

| `at-skeleton` | Grey placeholder bar, full width |

| `at-skeleton--short / --medium` | 40% / 70% width |

## Tokens

`--at-border`, `--at-border-primary`, `--at-bg-neutral`

## Accessibility

- Give the spinner role="status" and a label. Animations stop when reduced motion is on.
