UI4 Review Reviews CSS changes and auto-fixes token violations. --- Important: Palette vs Semantic Tokens tokens are the raw color palette (e.g., , ). These are used only in to define semantic tokens. tokens are context-aware semantic tokens (e.g., , ). These handle light/dark theming automatically. Components and elements should ALWAYS use semantic tokens, never palette tokens directly. --- Process Step 1: Get Changed CSS Files Or if a specific file is provided, use that directly. Step 2: Parallel Violation Detection Run these grep searches IN PARALLEL to detect all violation types at once:…

\n```\n\nOr if a specific file is provided, use that directly.\n\n### Step 2: Parallel Violation Detection\n\n**Run these grep searches IN PARALLEL** to detect all violation types at once:\n\n```bash\n# 1. SCSS Nesting Violations (BEM patterns that don't work in CSS)\ngrep -n '&__\\|&--' \"$FILE\"\n\n# 2. Hardcoded Spacing (px/rem values that should be tokens)\ngrep -nE ':\\s*[0-9]+px|:\\s*[0-9.]+rem' \"$FILE\"\n\n# 3. Hardcoded Colors (hex, rgb, rgba - includes box-shadow)\ngrep -nE '#[0-9a-fA-F]{3,8}|rgba?\\(' \"$FILE\"\n\n# 4. Legacy Theme Variables\ngrep -nE 'var\\(--theme-|var\\(--style-|var\\(--base\\)' \"$FILE\"\n\n# 5. Old Token Names (pre-UI4 naming)\ngrep -nE '\\-\\-bg-default|\\-\\-bg-secondary|\\-\\-text-default|\\-\\-text-secondary|\\-\\-icon-default|\\-\\-icon-secondary|\\-\\-border-default|\\-\\-border-strong' \"$FILE\"\n\n# 6. Raw Palette Usage (should use semantic tokens instead)\n# Skip this check for colors.css which defines the semantic tokens\ngrep -nE 'var\\(--ramp-' \"$FILE\"\n```\n\n**Invoke all 6 grep commands in a single parallel batch**, then analyze results.\n\n**Note:** Raw `--ramp-*` violations are only flagged in component CSS files, not in `colors.css` where they're used to define semantic tokens.\n\n### Step 3: Auto-Fix by Priority\n\n1. **SCSS Nesting** (breaks CSS entirely) — Fix first\n2. **Legacy Variables** (deprecated) — Replace with new tokens\n3. **Old Token Names** (pre-UI4) — Convert to `--color-*` naming\n4. **Raw Palette Usage** (`--ramp-*` in components) — Replace with semantic `--color-*` tokens\n5. **Hardcoded Values** (spacing, colors, radius) — Replace with tokens\n\n### Step 4: Report\n\nAfter fixing, report:\n\n- Total violations found\n- Violations auto-fixed\n- Violations that need manual review (no clear token match)\n\n---\n\n## Violation Reference\n\n### SCSS Nesting (BREAKS CSS)\n\n| Pattern | Issue | Fix |\n| --------------------------- | ------------------- | ------------------------------------ |\n| `&__element` | BEM element concat | Use flat `.block__element` selector |\n| `&--modifier` | BEM modifier concat | Use flat `.block--modifier` selector |\n| `.child { .parent--mod & }` | Parent reference | Move to `.parent--mod .child` |\n\n**What DOES work:** `&:hover`, `&:focus`, `&::before`, `& .child`\n\n---\n\n### Spacing Tokens\n\n| Value | Token |\n| -------------- | -------------- |\n| 4px / 0.25rem | `--spacer-1` |\n| 8px / 0.5rem | `--spacer-2` |\n| 12px / 0.75rem | `--spacer-2-5` |\n| 16px / 1rem | `--spacer-3` |\n| 24px / 1.5rem | `--spacer-4` |\n| 32px / 2rem | `--spacer-5` |\n| 40px / 2.5rem | `--spacer-6` |\n\n**Rounding rules — ALWAYS round to nearest token:**\n\n| Pixel Range | Token | Notes |\n| ----------- | --------------------- | ----------------------------- |\n| 0-2px | `--spacer-0` | Use 0 |\n| 3-6px | `--spacer-1` (4px) | 5-6px rounds to 4px |\n| 7-10px | `--spacer-2` (8px) | 10px rounds DOWN to 8px |\n| 11-14px | `--spacer-2-5` (12px) | 13.33px rounds to 12px |\n| 15-20px | `--spacer-3` (16px) | 15px, 20px both round to 16px |\n| 21-28px | `--spacer-4` (24px) | |\n| 29-36px | `--spacer-5` (32px) | 30px rounds to 32px |\n| 37-48px | `--spacer-6` (40px) | |\n\n**Rule:** For values ≤ 40px, ALWAYS use a single token (no `calc()`). For values > 40px, use `calc()` with a spacer token.\n\n**Exceptions:** `0`, percentages, `auto`, `inherit`, `-1px` (for clip offsets)\n\n---\n\n### Stroke Width Tokens\n\n| Value | Token |\n| ----- | ---------------------- |\n| 1px | `--stroke-width-small` |\n\n---\n\n### Radius Tokens\n\n| Value | Token |\n| ---------------- | ----------------- |\n| 2px / 0.125rem | `--radius-small` |\n| 5px / 0.3125rem | `--radius-medium` |\n| 13px / 0.8125rem | `--radius-large` |\n| 9999px | `--radius-full` |\n\n---\n\n### Elevation Tokens (Box Shadows)\n\nDefined in `packages/ui/src/css/elevations.css`.\n\n**Never use hardcoded `rgba()` for box-shadows.** Use elevation tokens instead:\n\n| Token | Use Case |\n| ------------------------------ | --------------------------------- |\n| `--elevation-300-tooltip` | Tooltips, small floating elements |\n| `--elevation-400-menu-panel` | Menus, dropdowns, floating panels |\n| `--elevation-500-modal-window` | Modals, dialogs, full overlays |\n\n```css\n/* ❌ BAD - hardcoded shadow */\nbox-shadow: 0 -2px 16px -2px rgba(0, 0, 0, 0.2);\n\n/* ✅ GOOD - elevation token */\nbox-shadow: var(--elevation-400-menu-panel);\n```\n\nElevations automatically adjust for light/dark themes.\n\n---\n\n### Semantic Color Tokens (UI4 Naming)\n\nAll semantic colors use the `--color-` prefix. The `default` category and variant are implicit.\n\n| Old Name | New Name (UI4) |\n| ------------------- | ------------------------- |\n| `--bg-default` | `--color-bg` |\n| `--bg-secondary` | `--color-bg-secondary` |\n| `--bg-hover` | `--color-bg-hover` |\n| `--bg-selected` | `--color-bg-selected` |\n| `--bg-brand` | `--color-bg-brand` |\n| `--bg-danger` | `--color-bg-danger` |\n| `--bg-success` | `--color-bg-success` |\n| `--bg-warning` | `--color-bg-warning` |\n| `--text-default` | `--color-text` |\n| `--text-secondary` | `--color-text-secondary` |\n| `--text-tertiary` | `--color-text-tertiary` |\n| `--text-brand` | `--color-text-brand` |\n| `--text-danger` | `--color-text-danger` |\n| `--text-success` | `--color-text-success` |\n| `--icon-default` | `--color-icon` |\n| `--icon-secondary` | `--color-icon-secondary` |\n| `--icon-tertiary` | `--color-icon-tertiary` |\n| `--icon-brand` | `--color-icon-brand` |\n| `--icon-danger` | `--color-icon-danger` |\n| `--border-default` | `--color-border` |\n| `--border-strong` | `--color-border-strong` |\n| `--border-selected` | `--color-border-selected` |\n| `--border-brand` | `--color-border-brand` |\n\n---\n\n### Legacy Variables (Replace Immediately)\n\n| Legacy | Replacement |\n| ----------------------- | ---------------------- |\n| `--theme-elevation-0` | `--color-bg` |\n| `--theme-elevation-50` | `--color-bg-secondary` |\n| `--theme-elevation-100` | `--color-border` |\n| `--theme-text` | `--color-text` |\n| `--style-radius-m` | `--radius-medium` |\n\n**`var(--base)` Conversion:** Legacy token = 20px. Convert using:\n\n| Original | Pixels | Replacement |\n| ------------------- | ------ | ------------------------------- |\n| `var(--base) * 0.4` | 8px | `var(--spacer-2)` |\n| `var(--base) * 0.5` | 10px | `calc(var(--spacer-1) * 2.5)` |\n| `var(--base) * 0.6` | 12px | `var(--spacer-2-5)` |\n| `var(--base)` | 20px | `calc(var(--spacer-4) * 0.833)` |\n| `var(--base) * 2` | 40px | `var(--spacer-6)` |\n\nSee ui4 skill Step 1 for full conversion table.\n\n---\n\n## Behavior\n\n**DO NOT just report violations. FIX THEM immediately using replace_string_in_file or multi_replace_string_in_file.**\n\nWhen a violation has no clear token match (e.g., `3px` or an unusual rem value), flag it for manual review but don't guess.\n\nFor each violation:\n\n1. Identify the exact line and value\n2. Determine the correct token replacement\n3. Use `replace_string_in_file` to fix it immediately\n4. Report what was fixed\n\n**Only flag (don't fix) when:**\n\n- No matching token exists (e.g., 18px badge size)\n- Value is intentional (e.g., `1px` border, `0`)\n- Ambiguous replacement\n\n**Empty CSS files:** If a component's CSS file becomes empty after migration (all styles now handled by shared components like `Button`), delete the CSS file and remove its import from the component.\n\n---\n\n## Output Format\n\nAfter auto-fixing, report:\n\n```\n## Auto-Fixed\n\n✅ Collapsible/index.css:9 — `height: 2rem` → `height: var(--spacer-5)`\n✅ Collapsible/index.css:120 — `width: 2rem` → `width: var(--spacer-5)`\n\n## Flagged (Manual Review)\n\n⚠️ ErrorPill/index.css:15 — `height: 1.125rem` (18px) — no matching token\n```\n\n---\n\n## Summary\n\nAfter all fixes, provide a simple summary:\n\n| File | Fixed | Flagged |\n| --------------------- | ----- | ------- |\n| Collapsible/index.css | 2 | 1 |\n| ErrorPill/index.css | 0 | 2 |\n---","attachment_filenames":[],"attachments":[],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"UI4 Review","type":"text"}]},{"type":"paragraph","content":[{"text":"Reviews CSS changes and ","type":"text"},{"text":"auto-fixes","type":"text","marks":[{"type":"strong"}]},{"text":" token violations.","type":"text"}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":2},"content":[{"text":"Important: Palette vs Semantic Tokens","type":"text"}]},{"type":"paragraph","content":[{"text":"--ramp-*","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":" tokens","type":"text","marks":[{"type":"strong"}]},{"text":" are the raw color palette (e.g., ","type":"text"},{"text":"--ramp-white-1000","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"--ramp-blue-500","type":"text","marks":[{"type":"code_inline"}]},{"text":"). These are used ","type":"text"},{"text":"only","type":"text","marks":[{"type":"strong"}]},{"text":" in ","type":"text"},{"text":"colors.css","type":"text","marks":[{"type":"code_inline"}]},{"text":" to define semantic tokens.","type":"text"}]},{"type":"paragraph","content":[{"text":"--color-*","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":" tokens","type":"text","marks":[{"type":"strong"}]},{"text":" are context-aware semantic tokens (e.g., ","type":"text"},{"text":"--color-bg","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"--color-text-brand","type":"text","marks":[{"type":"code_inline"}]},{"text":"). These handle light/dark theming automatically.","type":"text"}]},{"type":"paragraph","content":[{"text":"Components and elements should ALWAYS use ","type":"text","marks":[{"type":"strong"}]},{"text":"--color-*","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":" semantic tokens, never ","type":"text","marks":[{"type":"strong"}]},{"text":"--ramp-*","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":" palette tokens directly.","type":"text","marks":[{"type":"strong"}]}]},{"type":"code_block","attrs":{"wrap":false,"language":"css"},"content":[{"text":"/* ❌ BAD - using raw palette */\nbackground: var(--ramp-white-1000);\n\n/* ✅ GOOD - using semantic token */\nbackground: var(--color-bg);","type":"text"}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":2},"content":[{"text":"Process","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 1: Get Changed CSS Files","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"git status --porcelain | grep '\\.css

UI4 Review Reviews CSS changes and auto-fixes token violations. --- Important: Palette vs Semantic Tokens tokens are the raw color palette (e.g., , ). These are used only in to define semantic tokens. tokens are context-aware semantic tokens (e.g., , ). These handle light/dark theming automatically. Components and elements should ALWAYS use semantic tokens, never palette tokens directly. --- Process Step 1: Get Changed CSS Files Or if a specific file is provided, use that directly. Step 2: Parallel Violation Detection Run these grep searches IN PARALLEL to detect all violation types at once:…

","type":"text"}]},{"type":"paragraph","content":[{"text":"Or if a specific file is provided, use that directly.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 2: Parallel Violation Detection","type":"text"}]},{"type":"paragraph","content":[{"text":"Run these grep searches IN PARALLEL","type":"text","marks":[{"type":"strong"}]},{"text":" to detect all violation types at once:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# 1. SCSS Nesting Violations (BEM patterns that don't work in CSS)\ngrep -n '&__\\|&--' \"$FILE\"\n\n# 2. Hardcoded Spacing (px/rem values that should be tokens)\ngrep -nE ':\\s*[0-9]+px|:\\s*[0-9.]+rem' \"$FILE\"\n\n# 3. Hardcoded Colors (hex, rgb, rgba - includes box-shadow)\ngrep -nE '#[0-9a-fA-F]{3,8}|rgba?\\(' \"$FILE\"\n\n# 4. Legacy Theme Variables\ngrep -nE 'var\\(--theme-|var\\(--style-|var\\(--base\\)' \"$FILE\"\n\n# 5. Old Token Names (pre-UI4 naming)\ngrep -nE '\\-\\-bg-default|\\-\\-bg-secondary|\\-\\-text-default|\\-\\-text-secondary|\\-\\-icon-default|\\-\\-icon-secondary|\\-\\-border-default|\\-\\-border-strong' \"$FILE\"\n\n# 6. Raw Palette Usage (should use semantic tokens instead)\n# Skip this check for colors.css which defines the semantic tokens\ngrep -nE 'var\\(--ramp-' \"$FILE\"","type":"text"}]},{"type":"paragraph","content":[{"text":"Invoke all 6 grep commands in a single parallel batch","type":"text","marks":[{"type":"strong"}]},{"text":", then analyze results.","type":"text"}]},{"type":"paragraph","content":[{"text":"Note:","type":"text","marks":[{"type":"strong"}]},{"text":" Raw ","type":"text"},{"text":"--ramp-*","type":"text","marks":[{"type":"code_inline"}]},{"text":" violations are only flagged in component CSS files, not in ","type":"text"},{"text":"colors.css","type":"text","marks":[{"type":"code_inline"}]},{"text":" where they're used to define semantic tokens.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 3: Auto-Fix by Priority","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"SCSS Nesting","type":"text","marks":[{"type":"strong"}]},{"text":" (breaks CSS entirely) — Fix first","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Legacy Variables","type":"text","marks":[{"type":"strong"}]},{"text":" (deprecated) — Replace with new tokens","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Old Token Names","type":"text","marks":[{"type":"strong"}]},{"text":" (pre-UI4) — Convert to ","type":"text"},{"text":"--color-*","type":"text","marks":[{"type":"code_inline"}]},{"text":" naming","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Raw Palette Usage","type":"text","marks":[{"type":"strong"}]},{"text":" (","type":"text"},{"text":"--ramp-*","type":"text","marks":[{"type":"code_inline"}]},{"text":" in components) — Replace with semantic ","type":"text"},{"text":"--color-*","type":"text","marks":[{"type":"code_inline"}]},{"text":" tokens","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Hardcoded Values","type":"text","marks":[{"type":"strong"}]},{"text":" (spacing, colors, radius) — Replace with tokens","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 4: Report","type":"text"}]},{"type":"paragraph","content":[{"text":"After fixing, report:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Total violations found","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Violations auto-fixed","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Violations that need manual review (no clear token match)","type":"text"}]}]}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":2},"content":[{"text":"Violation Reference","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"SCSS Nesting (BREAKS CSS)","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Pattern","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Issue","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Fix","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"&__element","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"BEM element concat","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Use flat ","type":"text"},{"text":".block__element","type":"text","marks":[{"type":"code_inline"}]},{"text":" selector","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"&--modifier","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"BEM modifier concat","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Use flat ","type":"text"},{"text":".block--modifier","type":"text","marks":[{"type":"code_inline"}]},{"text":" selector","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":".child { .parent--mod & }","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Parent reference","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Move to ","type":"text"},{"text":".parent--mod .child","type":"text","marks":[{"type":"code_inline"}]}]}]}]}]},{"type":"paragraph","content":[{"text":"What DOES work:","type":"text","marks":[{"type":"strong"}]},{"text":" ","type":"text"},{"text":"&:hover","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"&:focus","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"&::before","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"& .child","type":"text","marks":[{"type":"code_inline"}]}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":3},"content":[{"text":"Spacing Tokens","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Value","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Token","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"4px / 0.25rem","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--spacer-1","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"8px / 0.5rem","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--spacer-2","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"12px / 0.75rem","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--spacer-2-5","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"16px / 1rem","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--spacer-3","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"24px / 1.5rem","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--spacer-4","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"32px / 2rem","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--spacer-5","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"40px / 2.5rem","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--spacer-6","type":"text","marks":[{"type":"code_inline"}]}]}]}]}]},{"type":"paragraph","content":[{"text":"Rounding rules — ALWAYS round to nearest token:","type":"text","marks":[{"type":"strong"}]}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Pixel Range","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Token","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Notes","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"0-2px","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--spacer-0","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Use 0","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"3-6px","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--spacer-1","type":"text","marks":[{"type":"code_inline"}]},{"text":" (4px)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"5-6px rounds to 4px","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"7-10px","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--spacer-2","type":"text","marks":[{"type":"code_inline"}]},{"text":" (8px)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"10px rounds DOWN to 8px","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"11-14px","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--spacer-2-5","type":"text","marks":[{"type":"code_inline"}]},{"text":" (12px)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"13.33px rounds to 12px","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"15-20px","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--spacer-3","type":"text","marks":[{"type":"code_inline"}]},{"text":" (16px)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"15px, 20px both round to 16px","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"21-28px","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--spacer-4","type":"text","marks":[{"type":"code_inline"}]},{"text":" (24px)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph"}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"29-36px","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--spacer-5","type":"text","marks":[{"type":"code_inline"}]},{"text":" (32px)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"30px rounds to 32px","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"37-48px","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--spacer-6","type":"text","marks":[{"type":"code_inline"}]},{"text":" (40px)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph"}]}]}]},{"type":"paragraph","content":[{"text":"Rule:","type":"text","marks":[{"type":"strong"}]},{"text":" For values ≤ 40px, ALWAYS use a single token (no ","type":"text"},{"text":"calc()","type":"text","marks":[{"type":"code_inline"}]},{"text":"). For values > 40px, use ","type":"text"},{"text":"calc()","type":"text","marks":[{"type":"code_inline"}]},{"text":" with a spacer token.","type":"text"}]},{"type":"paragraph","content":[{"text":"Exceptions:","type":"text","marks":[{"type":"strong"}]},{"text":" ","type":"text"},{"text":"0","type":"text","marks":[{"type":"code_inline"}]},{"text":", percentages, ","type":"text"},{"text":"auto","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"inherit","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"-1px","type":"text","marks":[{"type":"code_inline"}]},{"text":" (for clip offsets)","type":"text"}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":3},"content":[{"text":"Stroke Width Tokens","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Value","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Token","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"1px","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--stroke-width-small","type":"text","marks":[{"type":"code_inline"}]}]}]}]}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":3},"content":[{"text":"Radius Tokens","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Value","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Token","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"2px / 0.125rem","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--radius-small","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"5px / 0.3125rem","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--radius-medium","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"13px / 0.8125rem","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--radius-large","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"9999px","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--radius-full","type":"text","marks":[{"type":"code_inline"}]}]}]}]}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":3},"content":[{"text":"Elevation Tokens (Box Shadows)","type":"text"}]},{"type":"paragraph","content":[{"text":"Defined in ","type":"text"},{"text":"packages/ui/src/css/elevations.css","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]},{"type":"paragraph","content":[{"text":"Never use hardcoded ","type":"text","marks":[{"type":"strong"}]},{"text":"rgba()","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":" for box-shadows.","type":"text","marks":[{"type":"strong"}]},{"text":" Use elevation tokens instead:","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Token","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Use Case","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--elevation-300-tooltip","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Tooltips, small floating elements","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--elevation-400-menu-panel","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Menus, dropdowns, floating panels","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--elevation-500-modal-window","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Modals, dialogs, full overlays","type":"text"}]}]}]}]},{"type":"code_block","attrs":{"wrap":false,"language":"css"},"content":[{"text":"/* ❌ BAD - hardcoded shadow */\nbox-shadow: 0 -2px 16px -2px rgba(0, 0, 0, 0.2);\n\n/* ✅ GOOD - elevation token */\nbox-shadow: var(--elevation-400-menu-panel);","type":"text"}]},{"type":"paragraph","content":[{"text":"Elevations automatically adjust for light/dark themes.","type":"text"}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":3},"content":[{"text":"Semantic Color Tokens (UI4 Naming)","type":"text"}]},{"type":"paragraph","content":[{"text":"All semantic colors use the ","type":"text"},{"text":"--color-","type":"text","marks":[{"type":"code_inline"}]},{"text":" prefix. The ","type":"text"},{"text":"default","type":"text","marks":[{"type":"code_inline"}]},{"text":" category and variant are implicit.","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Old Name","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"New Name (UI4)","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--bg-default","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--color-bg","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--bg-secondary","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--color-bg-secondary","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--bg-hover","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--color-bg-hover","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--bg-selected","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--color-bg-selected","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--bg-brand","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--color-bg-brand","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--bg-danger","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--color-bg-danger","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--bg-success","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--color-bg-success","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--bg-warning","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--color-bg-warning","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--text-default","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--color-text","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--text-secondary","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--color-text-secondary","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--text-tertiary","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--color-text-tertiary","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--text-brand","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--color-text-brand","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--text-danger","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--color-text-danger","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--text-success","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--color-text-success","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--icon-default","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--color-icon","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--icon-secondary","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--color-icon-secondary","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--icon-tertiary","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--color-icon-tertiary","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--icon-brand","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--color-icon-brand","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--icon-danger","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--color-icon-danger","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--border-default","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--color-border","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--border-strong","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--color-border-strong","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--border-selected","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--color-border-selected","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--border-brand","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--color-border-brand","type":"text","marks":[{"type":"code_inline"}]}]}]}]}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":3},"content":[{"text":"Legacy Variables (Replace Immediately)","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Legacy","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Replacement","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--theme-elevation-0","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--color-bg","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--theme-elevation-50","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--color-bg-secondary","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--theme-elevation-100","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--color-border","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--theme-text","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--color-text","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--style-radius-m","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"--radius-medium","type":"text","marks":[{"type":"code_inline"}]}]}]}]}]},{"type":"paragraph","content":[{"text":"var(--base)","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":" Conversion:","type":"text","marks":[{"type":"strong"}]},{"text":" Legacy token = 20px. Convert using:","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Original","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Pixels","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Replacement","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"var(--base) * 0.4","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"8px","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"var(--spacer-2)","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"var(--base) * 0.5","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"10px","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"calc(var(--spacer-1) * 2.5)","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"var(--base) * 0.6","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"12px","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"var(--spacer-2-5)","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"var(--base)","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"20px","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"calc(var(--spacer-4) * 0.833)","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"var(--base) * 2","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"40px","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"var(--spacer-6)","type":"text","marks":[{"type":"code_inline"}]}]}]}]}]},{"type":"paragraph","content":[{"text":"See ui4 skill Step 1 for full conversion table.","type":"text"}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":2},"content":[{"text":"Behavior","type":"text"}]},{"type":"paragraph","content":[{"text":"DO NOT just report violations. FIX THEM immediately using replace_string_in_file or multi_replace_string_in_file.","type":"text","marks":[{"type":"strong"}]}]},{"type":"paragraph","content":[{"text":"When a violation has no clear token match (e.g., ","type":"text"},{"text":"3px","type":"text","marks":[{"type":"code_inline"}]},{"text":" or an unusual rem value), flag it for manual review but don't guess.","type":"text"}]},{"type":"paragraph","content":[{"text":"For each violation:","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Identify the exact line and value","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Determine the correct token replacement","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Use ","type":"text"},{"text":"replace_string_in_file","type":"text","marks":[{"type":"code_inline"}]},{"text":" to fix it immediately","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Report what was fixed","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Only flag (don't fix) when:","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"No matching token exists (e.g., 18px badge size)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Value is intentional (e.g., ","type":"text"},{"text":"1px","type":"text","marks":[{"type":"code_inline"}]},{"text":" border, ","type":"text"},{"text":"0","type":"text","marks":[{"type":"code_inline"}]},{"text":")","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Ambiguous replacement","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Empty CSS files:","type":"text","marks":[{"type":"strong"}]},{"text":" If a component's CSS file becomes empty after migration (all styles now handled by shared components like ","type":"text"},{"text":"Button","type":"text","marks":[{"type":"code_inline"}]},{"text":"), delete the CSS file and remove its import from the component.","type":"text"}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":2},"content":[{"text":"Output Format","type":"text"}]},{"type":"paragraph","content":[{"text":"After auto-fixing, report:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"## Auto-Fixed\n\n✅ Collapsible/index.css:9 — `height: 2rem` → `height: var(--spacer-5)`\n✅ Collapsible/index.css:120 — `width: 2rem` → `width: var(--spacer-5)`\n\n## Flagged (Manual Review)\n\n⚠️ ErrorPill/index.css:15 — `height: 1.125rem` (18px) — no matching token","type":"text"}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":2},"content":[{"text":"Summary","type":"text"}]},{"type":"paragraph","content":[{"text":"After all fixes, provide a simple summary:","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"File","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Fixed","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Flagged","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Collapsible/index.css","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"2","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"1","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"ErrorPill/index.css","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"0","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"2","type":"text"}]}]}]}]},{"type":"hr","attrs":{"markup":"---"}}]},"metadata":{"date":"2026-06-05","name":"ui4-review","author":"@skillopedia","source":{"stars":42740,"repo_name":"payload","origin_url":"https://github.com/payloadcms/payload/blob/HEAD/.claude/skills/ui4-review/SKILL.md","repo_owner":"payloadcms","body_sha256":"51b37d45d4d0b5f9eb746efd9fc9c4433656858c283b0c07ad0415a92c56d856","cluster_key":"3bc7831975b9f2e5ed95dcc25fa56005c3d37b19dc8fa5004cff00fc2b02e987","clean_bundle":{"format":"clean-skill-bundle-v1","source":"payloadcms/payload/.claude/skills/ui4-review/SKILL.md","bundle_sha256":"48c23de936b45aa44e302660ea7756a8e97c44ef112df65705b209504b0cd91e","attachment_count":0,"text_attachments":0,"binary_attachments":0},"cluster_size":1,"skill_md_path":".claude/skills/ui4-review/SKILL.md","import_metadata":{"date":"2026-06-05","author":"@skillopedia","version":"v1","category":"web-development","category_label":"Web"},"exact_dupes_collapsed_into_this":0},"version":"v1","category":"web-development","import_tag":"clean-skills-v1","description":"Review UI4 CSS migrations for proper token usage. Checks that CSS variables are used instead of hardcoded values."}},"renderedAt":1782987981397}

UI4 Review Reviews CSS changes and auto-fixes token violations. --- Important: Palette vs Semantic Tokens tokens are the raw color palette (e.g., , ). These are used only in to define semantic tokens. tokens are context-aware semantic tokens (e.g., , ). These handle light/dark theming automatically. Components and elements should ALWAYS use semantic tokens, never palette tokens directly. --- Process Step 1: Get Changed CSS Files Or if a specific file is provided, use that directly. Step 2: Parallel Violation Detection Run these grep searches IN PARALLEL to detect all violation types at once:…