# Cowork UI Kit — Token Exports

> **Designer ↔ Developer handoff layer.** Source = CSS (HSL math). Exports = JSON consumable by Figma + tooling.
>
> Iter 10 H · 2026-05-20 · v0.5.0

---

## TL;DR

```
foundation.css + semantic.css + brands/*.brand.css       (source of truth)
        │
        │   node _build/export-tokens.js
        ▼
tokens.w3c.json     ← W3C Design Token spec (DTCG)
tokens.figma.json   ← Figma Tokens Studio plugin format (7 themes)
```

| File | Format | Purpose | Token count |
|---|---|---|---|
| `foundation.css` + `semantic.css` | CSS | Source of truth — runtime | 250 decls |
| `tokens.json` | Internal flat JSON | AI/tooling fast-scan (legacy `build-tokens.js`) | — |
| **`tokens.w3c.json`** | **W3C DTCG** | **Style Dictionary, Specify, Supernova, custom tooling** | **140 tokens** |
| **`tokens.figma.json`** | **Tokens Studio** | **Figma plugin import — 7 brand themes** | **125 tokens** |

---

## 1 · For Designers — Import vào Figma qua Tokens Studio plugin

**Plugin:** [Tokens Studio for Figma](https://www.figma.com/community/plugin/843461159747178978/tokens-studio-for-figma) (free, open source).

### 3 step instructions

1. **Install plugin trong Figma**
   - Mở Figma → Resources (search) → cài "Tokens Studio for Figma" → Run plugin trong file Figma muốn sync tokens.

2. **Import JSON**
   - Trong panel Tokens Studio → menu **⋯ (top right)** → **Tools** → **Load from file/folder or preset**.
   - Chọn **Single file** → upload 📄 [tokens.figma.json](file:///C:/Users/DANG/AI-Cowork/00-templates/ui-kit/tokens/tokens.figma.json).
   - Plugin auto-detect 8 token sets: `global` + 7 brand sets (`brand/annhien`, `brand/khi`, ...) + 7 themes định nghĩa trong `$themes`.

3. **Switch brand theme + Apply to Figma styles**
   - Top of plugin → dropdown **Themes** → pick brand (vd "An Nhien — Trầm hương agarwood").
   - Click **Apply to Figma** → tokens được generate thành Figma Color/Text/Effect styles, sẵn để xài trong design.
   - Đổi theme khác → re-apply, styles auto remap (`primary` hue đổi nhưng tên style giữ nguyên).

**Workflow note:** Developer update CSS source → re-run `node _build/export-tokens.js` → commit + push JSON → designer re-import file mới (Tools → Update from file). Không cần copy hex tay nữa.

---

## 2 · For Developers — Regenerate JSON từ CSS source

### Cách chạy

```bash
cd 00-templates/ui-kit
node _build/export-tokens.js
```

Output (idempotent, deterministic):

```
[export-tokens] Iter 10 H — W3C + Figma Tokens export
[export-tokens]   foundation: 163 decls
[export-tokens]   semantic:   87 decls
[export-tokens]   brands:     7 (a-kryphan, ai-tools, annhien, betterbuy, haogood, khi, xanh)
[export-tokens] wrote tokens/tokens.w3c.json  (22.0 kB)
[export-tokens] wrote tokens/tokens.figma.json  (19.5 kB)
[export-tokens] tokens — W3C: 140, Figma: 125
```

### W3C JSON sample

Format khớp spec [DTCG draft](https://design-tokens.github.io/community-group/format/) — mỗi token có `$type`, `$value`, `$description`:

```json
{
  "color": {
    "success": {
      "$type": "color",
      "$value": "hsl(158 64% 27%)",
      "$description": "Status success — WCAG AA on white + on cream"
    }
  },
  "space": {
    "4": {
      "$type": "dimension",
      "$value": "16px",
      "$description": "Spacing 4 — default group gap"
    }
  },
  "brand": {
    "annhien": {
      "primary": {
        "$type": "color",
        "$value": "hsl(28 40% 38%)",
        "$description": "An Nhien — primary brand color"
      },
      "primary-deep": {
        "$type": "color",
        "$value": "hsl(28 40% 28%)",
        "$description": "An Nhien — primary darker (active/hover)"
      }
    }
  }
}
```

Consume bằng [Style Dictionary](https://styledictionary.com/) để emit tokens cho iOS Swift, Android XML, React Native, etc.

### Figma JSON sample

```json
{
  "global": {
    "color": {
      "warm-bg": { "value": "hsl(40 50% 96%)", "type": "color", "description": "Warm page bg" }
    }
  },
  "brand/annhien": {
    "color": {
      "primary": { "value": "hsl(28 40% 38%)", "type": "color", "description": "An Nhien — primary" }
    }
  },
  "$themes": [
    {
      "id": "theme-annhien",
      "name": "An Nhien — Trầm hương agarwood",
      "group": "Brand",
      "selectedTokenSets": { "global": "source", "brand/annhien": "enabled" }
    }
  ]
}
```

---

## 3 · Token naming convention

Tất cả token đều **kebab-case**, group nested theo category. Match cả W3C + Figma.

| Group | Path | Example |
|---|---|---|
| Status color | `color.{name}` | `color.success`, `color.danger` |
| Warm surface | `color.warm-{role}` | `color.warm-bg`, `color.warm-surface`, `color.warm-border` |
| Dark surface | `color.dark-{role}` | `color.dark-bg`, `color.dark-surface-2` |
| Dark accent | `color.dark-{accent}` | `color.dark-violet`, `color.dark-cyan` |
| Brand color | `brand.{name}.{role}` | `brand.annhien.primary`, `brand.khi.accent` |
| Spacing | `space.{n}` | `space.4` (=16px), `space.12` (=48px) |
| Radius | `radius.{size}` | `radius.md` (=8px), `radius.full` (=9999px) |
| Border width | `border.{n}` | `border.1` (=1px), `border.3` (=2px) |
| Font family | `typography.font-family.{name}` | `typography.font-family.sans`, `.serif` |
| Font size | `typography.font-size.{size}` | `typography.font-size.md` (=16px) |
| Line height | `typography.line-height.{name}` | `typography.line-height.normal` (=1.5) |
| Letter spacing | `typography.letter-spacing.{name}` | `typography.letter-spacing.tight` |
| Shadow | `shadow.{size}` | `shadow.md`, `shadow.2xl` |
| Duration | `duration.{name}` | `duration.fast` (=120ms) |
| Easing | `easing.{name}` | `easing.out`, `easing.bounce` |
| Z-index | `z-index.{role}` | `z-index.modal` (=70) |

**Rule:** Token name chỉ chứa lowercase + hyphen. Brand name = folder name của brand file (`annhien.brand.css` → `brand.annhien`).

---

## 4 · Source ↔ JSON mapping

| CSS source | JSON path | Resolution |
|---|---|---|
| `--brand-primary-h/s/l` trong `brands/annhien.brand.css` | `brand.annhien.primary` | Composed thành `hsl(h s l)` |
| `--status-success-l: 27%` trong `foundation.css` | `color.success.$value` | `hsl(158 64% 27%)` |
| `--space-4: calc(4px * 4)` | `space.4.$value` | Pre-resolved `16px` |
| `calc(var(--brand-primary-l) - 10%)` (annhien l=38%) | `brand.annhien.primary-deep` | Math evaluated → `28%` |
| `--lh-normal: 1.5` | `typography.line-height.normal.$value` | `1.5` (number) |

Math (`calc(L - 10%)`) được **resolve compile-time** — JSON ship concrete HSL values, không expression. Designer thấy số thật, không phải formula.

---

## 5 · Deployment

JSON files được serve trên 🌐 https://ui.dang.pm/tokens/ để designer/dev pull qua URL:

```
https://ui.dang.pm/tokens/tokens.w3c.json
https://ui.dang.pm/tokens/tokens.figma.json
```

Tokens Studio plugin support **load from URL** thay vì upload file — designer cấu hình 1 lần, sau đó Pull mỗi lần dev update tokens.

---

## 6 · Related

- 📄 [foundation.css](file:///C:/Users/DANG/AI-Cowork/00-templates/ui-kit/tokens/foundation.css) — primitive HSL + scales
- 📄 [semantic.css](file:///C:/Users/DANG/AI-Cowork/00-templates/ui-kit/tokens/semantic.css) — role-based composition
- 📁 [brands/](file:///C:/Users/DANG/AI-Cowork/00-templates/ui-kit/brands/) — 7 brand presets
- 🐍 [export-tokens.js](file:///C:/Users/DANG/AI-Cowork/00-templates/ui-kit/_build/export-tokens.js) — build script (Node.js, no deps)
- 📄 [INDEX.md](file:///C:/Users/DANG/AI-Cowork/00-templates/ui-kit/tokens/INDEX.md) — original architecture doc
