<!-- Generated by emit-docs.ts — do not edit. -->
# Button

Action trigger. With `href` renders an anchor with identical styling (D33); `disabled` then maps to `aria-disabled`.

## Props

| Prop | Type | Default | Required | Description |
|---|---|---|---|---|
| `variant` | `"accent" \| "accent-subtle" \| "neutral" \| "neutral-subtle" \| "ghost" \| "danger" \| "danger-subtle" \| "outline"` | neutral | no | Visual variant. |
| `size` | `24 \| 32 \| 40 \| 48` | 32 | no | Height in px (24 \| 32 \| 40 \| 48). |
| `href` | `string` | — | no | Render as an anchor with this href (D33). disabled → aria-disabled, no href attribute, pointer-events: none. |
| `target` | `string` | — | no | Anchor target; only used with href. |
| `rel` | `string` | — | no | Anchor rel; only used with href. |
| `ref` | `Ref<HTMLButtonElement \| HTMLAnchorElement>` | — | no | Forwarded ref to the underlying element. |
| `className` | `string` | — | no | Additional CSS class name(s) merged onto the component's root element. |

## Keyboard & assistive tech

| Keys | Behavior |
|---|---|
| Enter / Space | Activates the button. |
| Tab | Focusable; visible focus ring via :focus-visible. |

With href it renders an <a>; disabled anchors get aria-disabled, lose the href attribute, and suppress activation (D33).

## Theming

Override `--psi-button-*` custom properties at any scope; interactive states derive automatically (L - 0.04 hover, L - 0.08 active).

## Variant guidance

- **accent** — Primary action, draws attention. Submit, CTA, main action in a group.
- **accent-subtle** — Accent tone, lower visual weight. Selected state, active filter, soft CTA.
- **neutral** — Default, structurally present. Secondary actions, toolbar buttons.
- **neutral-subtle** — Minimal chrome. Inline actions, table row actions.
- **ghost** — No visible container until hover. Icon-only triggers, compact toolbars.
- **outline** — Bordered ghost — visible structure, no fill until hover. Marketing CTA, download button; hover fills accent.
- **danger** — Destructive action. Delete, remove, disconnect.
- **danger-subtle** — Destructive context, low urgency. Warning badges, soft destructive hints.
- **success | warning** — Status communication (Tag only). Status badges, labels.

## Rules

- One accent per visual group; everything else neutral or ghost.
- danger only for actions with real consequences.
- Sizes are px numbers (24|32|40|48), never S/M/L.
- Typography tokens are --psi-text-{size}-{lineHeight}-{weight}.
- Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
- --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
- Wrap labeled form controls in Field — label association, description/error line, aria-describedby and aria-invalid come wired; don't hand-roll label+message rows.
- Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
