# Cowork UI Kit — Semantic Token Reference

The tokens you'll use 90% of the time. Full enumeration in [`tokens/foundation.css`](tokens/foundation.css) (primitives) + [`tokens/semantic.css`](tokens/semantic.css) (role-based).

Convention: components reference **semantic** tokens (`var(--surface)`, `var(--primary)`), not foundation HSL. Override foundation in brand presets → entire palette shifts via math.

---

## 1. Color — surfaces

| Token | Description | Example use |
|---|---|---|
| `--bg` | Page background. Maps to `--warm-bg` in `.aesthetic-warm` and `--dark-bg` in `.aesthetic-dark`. | `body { background: var(--bg); }` |
| `--surface` | Card / panel background, 1 step elevated from `--bg`. | `.card { background: var(--surface); }` |
| `--surface-2` | Nested card / sidebar / sticky toolbar, 2 steps elevated. | `.sidebar { background: var(--surface-2); }` |
| `--border` | Default border (visible). | `input { border: 1px solid var(--border); }` |
| `--rule` | Subtle hairline divider (lower contrast than `--border`). | `.row { border-bottom: 1px solid var(--rule); }` |

## 2. Color — text

| Token | Description | Example use |
|---|---|---|
| `--text` | Primary text. AAA on bg in both warm + dark. | `body { color: var(--text); }` |
| `--text-2` | Secondary text — captions, meta, labels. AAA 7:1. | `.meta { color: var(--text-2); }` |
| `--text-3` | Tertiary text — placeholders, muted hints. AA-large 4.5:1. | `.placeholder { color: var(--text-3); }` |

## 3. Color — brand (primary)

| Token | Description | Example use |
|---|---|---|
| `--primary` | Brand primary color. | `.btn { background: var(--primary); }` |
| `--primary-deep` | -10% L from primary. Pressed/active state, link text on light bg. | `a:active { color: var(--primary-deep); }` |
| `--primary-hover` | -5% L from primary. Button hover background. | `.btn:hover { background: var(--primary-hover); }` |
| `--primary-active` | -15% L. Strong pressed state. | `.btn:active { background: var(--primary-active); }` |
| `--primary-soft` | +25% L (clamped 45–82%). Soft chip background. | `.chip { background: var(--primary-soft); }` |
| `--primary-bg` | +30% L at 0.15 alpha. Active row highlight, nav active. | `.nav-item.active { background: var(--primary-bg); }` |
| `--primary-on` | Text/icon color on top of `--primary` fill. Brand can override. | `.btn { color: var(--primary-on); }` |
| `--primary-ring` | Focus ring color (primary at 0.3 alpha). | `outline-color: var(--primary-ring);` |

**Brand override:** if your `--primary` has L ≥ 50%, declare `--primary-on: hsl(0 0% 100%);` (white) in your brand file. CLI `node _build/contrast-check-brand.js --h H --s S --l L --brand-file brands/your.brand.css` honors this.

## 4. Color — accent + highlight

| Token | Description |
|---|---|
| `--accent` | Secondary brand color, complementary to primary. |
| `--accent-deep` | -10% L from accent. S clamped to 70 to prevent neon. |
| `--accent-soft` | +25% L clamped 45–85%. Soft accent surfaces. |
| `--highlight` | Tertiary band (deck/landing accent only). |
| `--highlight-soft` | +15% L from highlight. |

## 5. Color — status semantic

Pairs are `--<status>` (solid) + `--<status>-soft` (0.2 alpha tint) + `--<status>-on` (text on solid where applicable). All AA-compliant on cream + dark.

| Status | Solid | Soft tint | On (text) |
|---|---|---|---|
| Success | `--success` | `--success-soft` | `--success-on` |
| Danger  | `--danger`  | `--danger-soft`  | `--danger-on` |
| Warning | `--warning` | `--warning-soft` | — |
| Info    | `--info`    | `--info-soft`    | — |

```css
.badge.ok   { background: var(--success-soft); color: var(--success); }
.alert.err  { background: var(--danger-soft);  border-color: var(--danger); }
```

## 6. Color — aesthetic semantic (advanced)

Direct refs only when you must force a specific aesthetic regardless of `<body>` class. Prefer `--bg`/`--surface` which auto-swap.

Warm: `--warm-bg`, `--warm-surface`, `--warm-surface-2`, `--warm-border`, `--warm-rule`, `--warm-text`, `--warm-text-2`, `--warm-text-3`

Dark: `--dark-bg`, `--dark-surface`, `--dark-surface-2`, `--dark-sidebar`, `--dark-border`, `--dark-border-soft`, `--dark-text`, `--dark-text-2`, `--dark-text-3`

Dark vivid (dashboard accents): `--dark-violet`, `--dark-cyan`, `--dark-emerald`, `--dark-amber`, `--dark-danger` (each has a `-soft` counterpart at 0.15 alpha).

## 7. Spacing — 4px base scale

`--space-unit` = 4px. Use multipliers, never hardcoded px.

| Token | Value | Common use |
|---|---|---|
| `--space-0` | 0 | reset |
| `--space-1` | 4 | tight icon gap |
| `--space-2` | 8 | chip padding |
| `--space-3` | 12 | small gap |
| `--space-4` | 16 | default gap, mobile body padding |
| `--space-5` | 20 | card padding y |
| `--space-6` | 24 | card padding x, section gap |
| `--space-8` | 32 | desktop body padding, between sections |
| `--space-10` | 40 | hero padding |
| `--space-12` | 48 | wide gap |
| `--space-16` | 64 | hero section breathing |
| `--space-20` | 80 | section break |
| `--space-24` | 96 | major section break |
| `--space-32` | 128 | landing hero |

`--space-7` (28px) is a legacy alias bridging 6 ↔ 8.

## 8. Typography

```
--type-base: 16px;      base for body
--type-ratio: 1.25;     not 1.333 — softer modular scale
```

| Token | Px | Use |
|---|---|---|
| `--type-xs` | 12 | min (WCAG floor) |
| `--type-sm` | 14 | caption, meta |
| `--type-md` | 16 | body |
| `--type-lg` | 20 | lead paragraph |
| `--type-xl` | 24 | H4 |
| `--type-2xl` | 30 | H3 |
| `--type-3xl` | 36 | H2 |
| `--type-4xl` | 48 | H1 dashboard |
| `--type-5xl` | 60 | hero secondary |
| `--type-6xl` | 72 | landing hero |
| `--type-7xl` | 96 | display |
| `--type-8xl` | 128 | mega display |

**Line-height:** `--lh-tight` (1.1, display), `--lh-snug` (1.25, headings), `--lh-normal` (1.5, body), `--lh-relaxed` (1.65, long-read), `--lh-loose` (1.75).

**Tracking:** `--tracking-tighter` (-0.05em, hero), `--tracking-tight` (-0.025em, H1-H3), `--tracking-normal` (0, body), `--tracking-wide` (0.05em, eyebrow), `--tracking-wider` (0.1em, label), `--tracking-widest` (0.2em, allcaps).

## 9. Radius

| Token | Value | Use |
|---|---|---|
| `--r-sm` | 4 | input, small button |
| `--r-md` | 8 | button, badge, chip |
| `--r-lg` | 12 | card, panel |
| `--r-xl` | 16 | hero card |
| `--r-2xl` | 24 | modal |
| `--r-3xl` | 32 | landing block |
| `--r-full` | 9999 | pill, avatar |

## 10. Shadow + elevation

Plain shadows (warm): `--shadow-xs`, `--shadow-sm`, `--shadow-md`, `--shadow-lg`, `--shadow-xl`, `--shadow-2xl`.

Glows (dark accent surfaces): `--glow-primary`, `--glow-violet`, `--glow-emerald`.

Layered elevation system (`--elevation-0` flat → `--elevation-5` highest) — composed border + multi-shadow for depth perception. Use case mapping:

| Token | Use case |
|---|---|
| `--elevation-0` | flat content |
| `--elevation-1` | list row hover, ghost button hover |
| `--elevation-2` | card default, button raised |
| `--elevation-3` | dropdown, popover, tooltip |
| `--elevation-4` | modal, drawer |
| `--elevation-5` | command palette, toast |

## 11. Motion

| Token | Value | Use |
|---|---|---|
| `--dur-fast` | 150ms | hover, focus ring |
| `--dur-base` | 250ms | open/close |
| `--dur-slow` | 400ms | dramatic reveal |
| `--ease-out` | iOS-like decelerate | enters |
| `--ease-out-soft` | Material standard | most UI |
| `--ease-in-out` | symmetric | re-orderings |
| `--ease-bounce` | spring-y | playful |
| `--ease-spring` | gentle spring | drawer pop |

All animations honor `prefers-reduced-motion: reduce` — collapsed to 0.01ms when user opted out.

## 12. Focus ring

```css
--focus-ring: hsl(var(--brand-primary-h) var(--brand-primary-s) var(--brand-primary-l) / 0.65);
--focus-ring-offset: 2px;
--focus-ring-width: 2px;
```

`:focus-visible` applies globally. Mouse click does NOT show ring (modern UA behavior). Forced-colors / high-contrast mode forces `CanvasText` outline (system color, no alpha).

---

## 13. Editorial patterns (archetype D)

For long-form article layout. Pair với `aesthetic-warm` + body class `brand-<slug>`. Tokens defined ở [`tokens/foundation.css`](tokens/foundation.css).

### Tokens (surfaced v0.5.5)

| Token | Value | Use |
|---|---|---|
| `--prose-width` | 680px | Optimal body reading column |
| `--prose-width-narrow` | 580px | Mobile / tight grid / pull quote |
| `--prose-width-wide` | 760px | Generous editorial / hero captions |
| `--lh-prose` | 1.7 | Body line-height (serif at 18-19px) |
| `--lh-pull-quote` | 1.3 | Big pull-quote display line-height |
| `--font-serif` | `'Source Serif 4', 'Lora', serif` | Body prose |
| `--font-display` | `'Plus Jakarta Sans', 'Inter', sans-serif` | Display headlines |

### Drop cap recipe

```css
.article-body p:first-of-type::first-letter {
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 400;
  font-size: var(--type-7xl);   /* ~96px */
  color: var(--primary-deep);
  float: left;
  line-height: 1;
  margin: 0.05em 0.1em 0 0;
  padding: 0;
}
```

### Pull quote recipe

```html
<blockquote class="pull">
  "Chúng ta nhầm chuyển động với ý nghĩa."
</blockquote>
```
```css
.pull {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: var(--type-3xl);
  line-height: var(--lh-pull-quote);
  color: var(--text-2);
  border-left: 3px solid var(--primary);
  padding: var(--space-2) 0 var(--space-2) var(--space-6);
  margin: var(--space-8) 0;
  max-width: var(--prose-width-narrow);
}
```

### Footnote recipe

```html
<p>Body text with ref<sup><a href="#fn1" id="ref1">[1]</a></sup>.</p>

<aside class="footnotes">
  <ol>
    <li id="fn1">Footnote content. <a href="#ref1">↩</a></li>
  </ol>
</aside>
```
```css
.footnotes {
  margin-top: var(--space-12);
  padding-top: var(--space-6);
  border-top: 1px solid var(--rule);
  font-size: var(--type-sm);
  color: var(--text-2);
}
.footnotes sup a { text-decoration: none; color: var(--primary-deep); }
```

### Tips

- Body width: hard-cap `max-width: var(--prose-width)` ở article container
- Para spacing: ≥ `var(--space-4)` (16px), tighter looks busy
- Mix Lora (body) + Instrument Serif (display) + Inter (meta) — see archetype D starter [`starter/archetypes/D-editorial.html`](starter/archetypes/D-editorial.html)
- For hero / inline image placeholders, prefer `hsl(var(--brand-primary-h) ...)` over hex literals so they shift with brand (current archetype D `img-*` blocks are scheduled for rebrand in v0.6)

---

## 14. Deck patterns (archetype E)

For pitch decks, slide presentations. Pair với `aesthetic-warm` (default) hoặc `aesthetic-dark`.

### Tokens (surfaced v0.5.5)

| Token | Value | Use |
|---|---|---|
| `--type-mega` | `clamp(120px, 12vw, 180px)` | Hero numbers, big stats |
| `--type-hero` | `clamp(180px, 16vw, 240px)` | Cover wordmark, slide 1 title |
| `--brand-mesh-1/2/3` | radial gradients (brand-relative) | Slide background ambient |

Note: `--brand-mesh-*` uses `var(--brand-primary-h)` so it shifts với brand swap. The older `.mesh-warm` class uses palette-fixed coral hues — for brand-tinted slides, prefer `.brand-mesh-1` (or compose your own with `var(--brand-primary-h)`).

### Slide ratio

Choose 1 ratio + stick:
- **16:9 (1280×720)**: standard pitch, projector-friendly
- **16:10 (1280×800)**: more vertical breathing room, web-native — kit default (matches `page-E-deck.html`)
- **4:5 (1080×1350)**: mobile-readable, Instagram-shareable

### Slide-stack pattern

Stack slides vertically as one HTML page:

```html
<section class="slide">...</section>
<section class="slide">...</section>
```
```css
.slide {
  width: 100%;
  min-height: 100vh;        /* full viewport */
  aspect-ratio: 16 / 10;    /* fixed ratio */
  padding: var(--space-16);
  border-bottom: 1px solid var(--rule);
  background: var(--brand-mesh-1), var(--bg);
}
```

### Big-number stat pattern

```html
<div class="stat">
  <div class="value">42</div>
  <div class="label">Clients shipped</div>
</div>
```
```css
.stat .value {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: var(--type-mega);
  line-height: 1;
  color: var(--primary-deep);
}
.stat .label {
  font-size: var(--type-md);
  color: var(--text-2);
  text-transform: uppercase;
  letter-spacing: var(--tracking-widest);
}
```

### Print / PDF export workflow

Kit ships `@media print` baseline. To export deck as PDF:

1. Open deck HTML trong Chrome
2. Cmd/Ctrl+P
3. Destination: **Save as PDF**
4. Layout: **Landscape**
5. Paper size: A4 hoặc US Letter (kit will scale slides)
6. Margins: **None**
7. Background graphics: **✓ ON** (preserves `--brand-mesh-*`)

Add `@page { margin: 0; }` + `.slide { page-break-after: always; }` ở deck stylesheet để slides render full-bleed + 1 slide/page.

### Slide indicator

```html
<div class="slide-num">1 / 6</div>
```
```css
.slide-num {
  position: absolute;
  bottom: var(--space-6);
  right: var(--space-8);
  font-size: var(--type-sm);
  font-family: var(--font-mono);
  color: var(--text-3);
}
```

---

## Related

- 📄 [BRAND-RECIPE.md](BRAND-RECIPE.md) — full step-by-step adding a brand
- 📄 [DESIGN-DECISIONS.md](DESIGN-DECISIONS.md) — ADRs explaining trade-offs
- 📄 [A11Y-RULES.md](A11Y-RULES.md) — contrast, motion, forced-colors enforcement
- 🔧 [`_build/contrast-check-brand.js`](_build/contrast-check-brand.js) — verify a brand HSL against WCAG AA
- 📁 [starter/archetypes/](starter/archetypes/) — 6 archetype skeletons + 1 minimal A starter
