# Button

A compact action control for submitting, confirming, navigating, or revealing work. Use one primary button for the dominant action in a group; use secondary or ghost buttons for alternatives.

## Install

```html
<link rel="stylesheet" href="/tokens.css">
<link rel="stylesheet" href="/components/button/button.css">
```

No JavaScript is required.

## Canonical example

```html
<button class="au-btn au-btn--primary" type="button">Run component</button>
```

## Variants

| Variant | Class | Use |
|---|---|---|
| Primary | `au-btn--primary` | One dominant action |
| Secondary | `au-btn--secondary` | A contained alternative |
| Ghost | `au-btn--ghost` | Low-emphasis action in a toolbar |
| Danger | `au-btn--danger` | Destructive action after confirmation |
| Link | `au-btn--link` | Inline navigation or lightweight action |
| Icon | `au-btn--icon` | Icon-only action; provide an accessible label |

Sizes: `au-btn--sm`, default, and `au-btn--lg`. Combine a size modifier with a variant modifier.

## States

- Default, hover, focus-visible, active, and disabled are native CSS states.
- Add `data-au-state="loading"` and `aria-busy="true"` while work is pending. Keep the label in the DOM.
- The button itself does not invent success or error state. The host renders those states beside the affected object.

## CSS variables

| Variable | Default | Purpose |
|---|---|---|
| `--au-btn-bg` | variant token | Background |
| `--au-btn-fg` | `var(--au-fg)` | Text/icon color |
| `--au-btn-border` | transparent | Border color |
| `--au-btn-radius` | `var(--au-radius-md)` | Corner radius |
| `--au-btn-height` | `40px` | Hit area height |
| `--au-btn-padding-inline` | `16px` | Horizontal breathing room |
| `--au-btn-gap` | `8px` | Icon and label gap |

## Events

Buttons use native `click` and form events. They do not dispatch a custom event or require `agent-ui.js`. Hosts may add `data-au-action` and listen for the shared runtime events when composing the button inside another component.

## Accessibility

- Use a native `<button>` for actions and `<a>` for navigation.
- Always provide a visible label or an accessible `aria-label` for icon-only buttons.
- Do not disable a button to communicate loading; use `data-au-state="loading"`, `aria-busy`, and prevent duplicate submission in host code.
- The focus ring is visible without hover and meets the project WCAG 2.1 AA target.

## No-JS behavior

The button remains a native, keyboard-accessible control without `agent-ui.js`. A form can submit normally, and a host can replace the surrounding HTML after a server response.

## Security

The component renders no user-provided HTML and has no network behavior. Keep labels as text content. If a host injects dynamic labels, use `textContent` or an equivalent escaping path.

## Size budget

Target: ≤3KB minified CSS. JavaScript: 0B. The action component carries the full variant, size, loading, and reduced-motion contract.
