$npx -y skills add educlopez/ui-craft --skill tokensAudit or establish the project's 3-layer token spine. Invoke when the user asks for tokens on their UI, or mentions 'tokens' alongside design / UI / frontend work.
| 1 | <!-- HARNESS MIRROR — do not edit here. Canonical source: skills/ or commands/. After editing source, copy into cli/assets/<harness>/ and repo-root harness mirrors. --> |
| 2 | |
| 3 | **Context:** this sub-skill is one lens of the broader `ui-craft` skill. If the `ui-craft` skill is also installed, read its SKILL.md first for Discovery + Anti-Slop + Craft Test, then apply the specific lens below. |
| 4 | |
| 5 | Read `references/tokens.md` before proceeding. The 3-layer contract (primitive → semantic → component) and the intentional-dark test are defined there. |
| 6 | |
| 7 | --- |
| 8 | |
| 9 | ## Step 1: Detect existing tokens |
| 10 | |
| 11 | Scan for token definitions in the project: |
| 12 | - CSS variables in `:root`, `[data-theme]`, `[data-mode]`, or theme wrapper selectors |
| 13 | - Tailwind config (`tailwind.config.js/ts`) under `theme.extend` or `theme` |
| 14 | - CSS-in-JS theme objects (`theme.ts`, `*.styles.ts`, `styled.d.ts`, `ThemeProvider`) |
| 15 | - `design-tokens.json` or `tokens.json` (Style Dictionary / Theo) |
| 16 | - `globals.css`, `variables.css`, `tokens.css` |
| 17 | |
| 18 | Build an inventory: which of the 7 categories exist (color / spacing / type / radii / shadows / motion / z-index), which layers are present (primitive / semantic / component), and whether both light and dark are defined. |
| 19 | |
| 20 | --- |
| 21 | |
| 22 | ## Step 2: Route based on the target the user described and inventory |
| 23 | |
| 24 | - **"audit"** → run audit only (Step 3). No proposals. |
| 25 | - **"establish"** → skip audit, go to Step 4. |
| 26 | - **"color" / "spacing" / "type" / "radii" / "shadows" / "motion" / "z-index"** → focus the audit and any proposal on that one category. |
| 27 | - **empty** → if tokens exist: audit. If nothing found: establish. |
| 28 | |
| 29 | --- |
| 30 | |
| 31 | ## Step 3: Audit (tokens exist) |
| 32 | |
| 33 | Evaluate against the contract in `references/tokens.md`. Output a severity-ranked gap list — don't propose code yet. |
| 34 | |
| 35 | Check: |
| 36 | |
| 37 | 1. **3-layer coverage** — are primitive, semantic, and component layers all present? Missing semantics is the most common gap: primitives exist but nothing switches for dark mode and no surface stack is defined. |
| 38 | 2. **7-category coverage** — any of (color / spacing / type / radii / shadows / motion / z-index) missing? Flag each absent category. |
| 39 | 3. **Intentional dark mode** — run the intentional-dark test: does dark mode do more than invert `--text-primary`? Is `--surface-canvas` a tinted near-black (not `#000`)? Is accent chroma reduced 10-15%? Are shadows replaced with border rings? |
| 40 | 4. **Naming discipline** — are primitives named for values (`--gray-500`) not roles (`--button-bg`)? Are semantics named for roles (`--text-primary`) not values (`--gray-900-text`)? |
| 41 | 5. **No arbitrary values** — inline colors, spacing, or z-index values that bypass the token system. |
| 42 | |
| 43 | Output format: |
| 44 | |
| 45 | | Severity | Category | Finding | |
| 46 | |---|---|---| |
| 47 | | Critical | Dark mode | `--surface-canvas` is `#000` — runs the intentional-dark test | |
| 48 | | High | Semantics | No surface stack — components use raw primitives | |
| 49 | | Medium | Shadows | Single-layer shadows — ambient layer missing | |
| 50 | | Low | Z-index | Arbitrary values (`z-index: 999`) in 3 components | |
| 51 | |
| 52 | Show what's missing. Do not propose code during audit unless the user asks. |
| 53 | |
| 54 | ### Step 3b — Converge mode (explicit opt-in) |
| 55 | |
| 56 | Load `skills/ui-craft/references/loops.md` preset `token-consistency` (budget = the default loop budget defined in loops.md). Emit the pre-flight cost notice. After fixing the top off-system value (raw hex color, arbitrary radius, or magic spacing), re-scan until zero off-system values or budget exhausted. |
| 57 | |
| 58 | --- |
| 59 | |
| 60 | ## Step 4: Establish (no tokens found) |
| 61 | |
| 62 | Propose a minimal spine inline. Cover all 7 categories. Always include both light and dark blocks — both intentional. |
| 63 | |
| 64 | **Minimal spine order:** |
| 65 | 1. Primitives — neutral ramp (gray-50 to gray-950), one accent ramp, semantic color bases, spacing scale, type scale, radii, shadows, motion, z-index. |
| 66 | 2. Semantics — surface stack (5 levels), text roles, border roles, accent roles, status roles (success / warning / error / info). |
| 67 | 3. Component tokens — defer unless a specific component is already being built. |
| 68 | |
| 69 | Use OKLCH for color unless the project uses sRGB across the board — in that case flag the gap, propose OKLCH, but don't auto-convert. |
| 70 | |
| 71 | **Before writing to a file, ask which file to write to.** Detect from project structure and suggest one: |
| 72 | - Tailwind project → `globals.css` (CSS variables inside `:root`) |
| 73 | - CSS-in-JS → `theme.ts` (exported theme object) |
| 74 | - Vanilla CSS → `tokens.css` (standalone variables file) |
| 75 | - Cross-platform / multi-consumer → `design-tokens.json` (Style Dictionary format) |
| 76 | |
| 77 | Confirm with the user before writing. |
| 78 | |
| 79 | --- |
| 80 | |
| 81 | ## Step 5: Never overwrite |
| 82 | |
| 83 | If the project has an existing token file, propose additions as patches — show what would change in a diff block: |
| 84 | |
| 85 | ```diff |
| 86 | :root { |
| 87 | + /* ── Semantic surface stack (new) ── */ |
| 88 | + --surface-canvas: var(--gray-50); |
| 89 | + --surface-raised: var(--gray-100); |