# Building with the Alert Enterprise brand

For AI agents and the people directing them. Read `llms.txt` for the index and `llms-full.txt` for the complete guidelines. This file covers how to produce output that passes review.

## 1. Load the system, do not copy values

For any HTML output (pages, prototypes, emails rendered in a browser, slides built in HTML), link the two stylesheets and write markup with the classes:

```html
<link rel="stylesheet" href="tokens/dist/tokens.css">
<link rel="stylesheet" href="css/components.css">
<body class="ae-root">
  <button class="ae-btn">Grant access</button>
  <button class="ae-btn ae-btn--outline">Cancel</button>
  <span class="ae-badge ae-badge--success ae-badge--dot">Granted</span>
</body>
```

Style your own layout with the custom properties, never with raw hex, px or curves:

```css
.hero { background: var(--ae-gradient-violet); color: var(--ae-text-on-brand); padding: var(--ae-space-16) var(--ae-layout-margin); }
.hero h1 { font: var(--ae-type-display); letter-spacing: var(--ae-type-display-tracking); }
```

When the target cannot load CSS (PowerPoint, Word, Figma, native code), read values from `tokens/dist/tokens.json` (DTCG) or `tokens/dist/tokens.flat.json`.

Dark: set `data-theme="dark"` on `<html>` or on any container. Every role flips; primitives do not.

## 2. Aeonik on everything

Every output uses Aeonik. Before producing a document, deck or image on a machine, check the font is installed (macOS: `ls ~/Library/Fonts | grep -i aeonik`; Windows: `Get-ChildItem $env:LOCALAPPDATA\Microsoft\Windows\Fonts -Filter Aeonik*`). If it is missing, run `bash scripts/install-aeonik.sh` or `scripts/install-aeonik.ps1`; both verify against `assets/fonts/fonts.json`. For HTML, link `assets/fonts/aeonik.css` (or `css/components.css`, which declares it). For PPTX and DOCX, set the theme fonts to Aeonik and embed fonts in the file. For anything handed to a person who may not have the font, offer `assets/fonts/Aeonik.zip`.

## 3. Components

| Need | Markup |
| --- | --- |
| Primary action (one per view) | `<button class="ae-btn">` |
| Secondary action | `.ae-btn--tonal` or `.ae-btn--outline` |
| Low-emphasis action | `.ae-btn--text` |
| Destructive action | `.ae-btn--danger` |
| Sizes | `.ae-btn--sm` (32px), default (40px), `.ae-btn--lg` (48px) |
| Loading | `aria-busy="true"` on the button |
| Text field | `.ae-field` > `.ae-field__label` + `.ae-input` + `.ae-field__help` + `.ae-field__error`; set `aria-invalid="true"` to show the error |
| Select, textarea | `.ae-select`, `.ae-textarea` |
| Checkbox, radio, switch | native `<input>` with `.ae-check`, `.ae-radio`, `.ae-switch` |
| Segmented control | `.ae-segmented` with `<button aria-pressed>` |
| Tabs | `.ae-tabs` with `<button role="tab" aria-selected>` |
| Filter chip | `.ae-chip` with `aria-pressed` |
| Status | `.ae-badge` + `--success`, `--warning`, `--danger`, `--info`, `--brand`, `--mark`; add `--dot`, `--live` |
| Count | `.ae-count` |
| Person | `.ae-avatar` (`--sm`, `--lg`, `--xl`), `.ae-avatar-group` |
| Container | `.ae-card` (`--raised`, `--interactive`, `--brand`, `--shield`) |
| List row | `.ae-list` > `.ae-row` > `.ae-row__main` > `.ae-row__title` + `.ae-row__meta` |
| Data table | `.ae-table`; `.num` for numbers, `.mono` for codes, `aria-sort` on sortable headers |
| Notice | `.ae-banner` + `--success`, `--warning`, `--danger`, `--brand` |
| Toast | `.ae-toast` |
| Dialog | `<dialog class="ae-dialog">` > `.ae-dialog__body` + `.ae-dialog__foot` |
| Tooltip | `.ae-tip` with `data-tip="..."` |
| Progress | `.ae-progress` with `style="--value:64%"`, `.ae-ring`, `.ae-stepper`, `.ae-skeleton` |
| Live event | `.ae-event` > `.ae-event__icon` + title/meta + `.ae-event__time` |
| Glass (only on imagery or gradients) | `.ae-glass` |
| Brand shape | `.ae-shield-shape`, `.ae-shield-shape-soft` |

State is always a native attribute or ARIA (`disabled`, `aria-pressed`, `aria-selected`, `aria-invalid`, `aria-busy`), never a class.

## 4. Assets

`assets/manifest.json` lists every file with its use. The common ones:

- Lockup on white: `assets/logo/ae-logo-full-coral-ink.svg`
- Lockup on black or purple: `assets/logo/ae-logo-full-coral-white.svg`
- Shield alone: `assets/logo/ae-shield-coral.svg`
- Icons: `assets/icons/icon-*.svg` (29 two-tone icons)
- Photography: `assets/photo/ae-photo-1.jpg` to `ae-photo-8.jpg`
- Fonts: `assets/fonts/Aeonik-Light.otf`, `Aeonik-Regular.otf`, `Aeonik-Bold.otf` (weights 300, 400, 700; `css/components.css` declares them), plus `DMSans-Variable.ttf` as the free fallback

Embed logo SVGs by reference or inline them unchanged. Never trace, retype or approximate the wordmark in text.

## 5. Checks before you deliver

Run through `tokens/dist/rules.json`. The ones most often broken:

1. The lockup is on white, black or #5F51D5, with clear space equal to the shield width.
2. One filled purple button per view.
3. Coral appears as a mark only: no coral fills behind text, no coral for errors.
4. No `linear-gradient` in brand surfaces. Use `--ae-gradient-*`.
5. Aeonik or DM Sans only. Sentence case headings.
6. Every text pairing passes WCAG AA (see `tokens/dist/contrast.json`).
7. Copy: no em or en dashes, no emoji, no buzzwords (seamless, empower, frictionless, robust, leverage, unlock), no "not just X, it's Y", no system internals in UI text.
8. The company is "Alert Enterprise", two words. Product names exact: "Employee Badge in Apple Wallet", "Corporate Badge in Google Wallet".
9. Nothing suggests Alert Enterprise makes hardware. Readers are HID, Wavelynx or LEGIC.
10. Motion honors `prefers-reduced-motion`.

## 6. Changing the system

Edit `tokens/src/tokens.mjs` and `guidelines/index.html`, then:

```
node tokens/build.mjs
python3 scripts/build-fonts.py   # only when a font file changes; needs fonttools and brotli
node scripts/build-agents.mjs
```

The first regenerates CSS, JSON, contrast and TOKENS.md. The second regenerates `llms.txt`, `llms-full.txt`, `agent-prompt.txt` and `assets/manifest.json` from the guidelines page. Never edit generated files by hand.
