<!-- Generated by scripts/build-agent-kit.ts for @aistrike-dev/ui@5.0.1. Do not edit. -->

# Tokens

## Choosing a background / surface

Never hardcode a surface hex. Use `theme.palette.background.*` via `sx`, or the
`backgroundColors` tokens. `backgroundUsage` ships in the package, so tooling can import it to
validate that generated UI uses the correct surface:

```ts
import { backgroundColors, backgroundUsage } from '@aistrike-dev/ui';
```

| Token | Hex | Role | Use for |
|---|---|---|---|
| `backgroundColors.page` | `#191919` | Page (rung 0) | The app shell, and bands that should recess below the body such as a table header. No longer pure black, so that a field on the shell has a rung to recess into. |
| `backgroundColors.primary` | `#1F1F1F` | Primary (rung 1) | Primary content background for a page or section, the recessed fill for a field hosted on a widget, and the unscoped table body / user chat bubble. |
| `backgroundColors.widget` | `#262626` | Widget (rung 2) | Widget / card surfaces sitting on the primary background. The rung most body text sits on, and what the text ramp is measured against. |
| `backgroundColors.surface` | `#2E2E2E` | Surface (rung 3) — Pop-up / Filter / Side Panel / AI chat | Elevated overlays and side panels that sit above content. From this rung up, quiet text must use `tertiary` rather than `subtle`. |
| `backgroundColors.raised` | `#333333` | Raised (rung 4) | Elements floating above an overlay, and portalled elements that cannot inherit a rung from the DOM. |
| `backgroundColors.overlay` | `#3A3A3A` | Overlay (rung 5, the ceiling) | The top of the ladder. Reaching it means three levels of containment; a fourth is clamped here rather than continuing to lighten. |
| `backgroundColors.tableDivider` | `#262626` | Table Divider | The rule between table rows. Subtler than `border` so the outline still reads. |
| `backgroundColors.darkGreen` | `#182724` | Dark Green | Subtle success-tinted surface for positive emphasis. |

## Severity

Severity is a reserved status scale, not a colour choice. Render it as
`<Chip variant="severity" color="..." />` with a text label - never colour alone, and never a
hardcoded hex. The ordered magnitude scale is
`critical` > `high` > `medium` > `low`; `info` and `untriaged` are separate states,
not rungs on it.

| Color | Dark | Light |
|---|---|---|
| `critical` | `#c80009` | `#BB010B` |
| `high` | `#EB2D36` | `#EB2D36` |
| `medium` | `#E99C16` | `#db9000` |
| `low` | `#D0C800` | `#c2bb01` |
| `info` | `#1266CC` | `#1266CC` |
| `untriaged` | `#C0C0C0` | `#b7b7b7` |

For categorical series identity in charts use `chartTokens[mode].series`, never the severity
scale.

## Spacing

Every margin, padding and gap lands on the 8px grid. Never use an arbitrary pixel
value such as `13px` or `18px`.

| Token | Pixels | `sx` factor | Use for |
|---|---|---|---|
| `spacing.none` | 0 | `0` | Collapse spacing explicitly. |
| `spacing.xxs` | 2 | `0.25` | Micro optical adjustments. |
| `spacing.xs` | 4 | `0.5` | Icon-to-text gap, compact chip or badge padding. |
| `spacing.sm` | 8 | `1` | Default element gap, small component padding. |
| `spacing.md` | 16 | `2` | Card padding, section gaps, form field spacing. |
| `spacing.lg` | 24 | `3` | Group separation, card body padding. |
| `spacing.xl` | 32 | `4` | Major section breaks, page-level gutters. |
| `spacing.xxl` | 48 | `6` | Page margins, hero spacing. |
| `spacing.xxxl` | 64 | `8` | Large layout gaps, top-of-page offset. |

In `sx` props use the MUI spacing factor, where each unit is 8px - `<Box sx={{ p: 3 }} />`
is 24px. Outside `sx`, import the named tokens:

```tsx
import { spacing } from '@aistrike-dev/ui';

const style = { padding: spacing.md, gap: spacing.sm };
```

- **Use `gap` or `Stack spacing`, not margins.** Parent-owned spacing avoids margin collapse and
  is easier to reason about.
- **Group by proximity.** Tighter spacing within a group, wider between groups. This is the main
  way to show structure without borders or dividers.
- **Never use spacing to fix alignment.** If elements do not line up, fix the layout with flex or
  grid rather than padding one side.
- **Keep spacing consistent across peers.** Two cards serving the same purpose share the same
  internal padding and the same gap to their neighbours.

## Typography

Every piece of visible text uses `Typography` with an explicit `variant`, or a component slot
that already applies one (`DialogTitle`, `DialogContentText`, `AlertTitle`, `EmptyState`,
`FormField`). Never drop a raw string into a `Box` / `div` / `span` and size it with a
`fontSize` literal. Pick the variant for the role, not the pixel size:

| Variant | Use for |
|---|---|
| `h1` | Rare. Marketing or empty-state heroes — not product chrome. |
| `h2` | Major page sections that sit above a page title. |
| `h3` | KPI figures and large stats (StatTile value). |
| `h4` | Page titles in templates (TablePageLayout, DetailsPageLayout). |
| `h5` | Investigation or subsection titles. |
| `h6` | Drawer headings and empty-state titles. |
| `subtitle1` | Card titles, form section titles, accordion summaries, dialog titles. |
| `subtitle2` | Compact headings: filter panels, table row titles, widget headers. |
| `body1` | Default reading text (14px): descriptions, dialog body, card copy, breadcrumbs. |
| `body2` | Dense annotations only (12px): deltas, compact secondary lines. Not default copy. |
| `caption` | Metadata, timestamps, helper counts, form labels, tooltips. |
| `overline` | Column headers, uppercase tags, category labels. |
| `button` | Reserved for Button. Do not use for prose. |

A container that may hold non-text children (a card body, a tab panel) keeps a `Box` and
applies the variant through `sx={{ typography: 'body1' }}` so it does not wrap a table in a
`<p>`.
