/ui4-review
Review UI4 CSS migrations for proper token usage. Checks that CSS variables are used instead of hardcoded values.
$ npx -y skills add payloadcms/payload --skill ui4-review --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/ui4-review
Context preview
The summary Claude sees to decide when to auto-load this skill.
Review UI4 CSS migrations for proper token usage. Checks that CSS variables are used instead of hardcoded values.
SKILL.md
ui4-review.SKILL.mdname: ui4-review
description: Review UI4 CSS migrations for proper token usage. Checks that CSS variables are used instead of hardcoded values.
UI4 Review
Reviews CSS changes and **auto-fixes** token violations.
---
Important: Palette vs Semantic Tokens
**`--ramp-*` tokens** are the raw color palette (e.g., `--ramp-white-1000`, `--ramp-blue-500`). These are used **only** in `colors.css` to define semantic tokens.
**`--color-*` tokens** are context-aware semantic tokens (e.g., `--color-bg`, `--color-text-brand`). These handle light/dark theming automatically.
**Components and elements should ALWAYS use `--color-*` semantic tokens, never `--ramp-*` palette tokens directly.**
/* ❌ BAD - using raw palette */
background: var(--ramp-white-1000);
/* ✅ GOOD - using semantic token */
background: var(--color-bg);
---
Process
Step 1: Get Changed CSS Files
git status --porcelain | grep '\.css$'
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:
# 1. SCSS Nesting Violations (BEM patterns that don't work in CSS)
grep -n '&__\|&--' "$FILE"
# 2. Hardcoded Spacing (px/rem values that should be tokens)
grep -nE ':\s*[0-9]+px|:\s*[0-9.]+rem' "$FILE"
# 3. Hardcoded Colors (hex, rgb, rgba - includes box-shadow)
grep -nE '#[0-9a-fA-F]{3,8}|rgba?\(' "$FILE"
# 4. Legacy Theme Variables
grep -nE 'var\(--theme-|var\(--style-|var\(--base\)' "$FILE"
# 5. Old Token Names (pre-UI4 naming)
grep -nE '\-\-bg-default|\-\-bg-secondary|\-\-text-default|\-\-text-secondary|\-\-icon-default|\-\-icon-secondary|\-\-border-default|\-\-border-strong' "$FILE"
# 6. Raw Palette Usage (should use semantic tokens instead)
# Skip this check for colors.css which defines the semantic tokens
grep -nE 'var\(--ramp-' "$FILE"**Invoke all 6 grep commands in a single parallel batch**, then analyze results.
**Note:** Raw `--ramp-*` violations are only flagged in component CSS files, not in `colors.css` where they're used to define semantic tokens.
Step 3: Auto-Fix by Priority
1. **SCSS Nesting** (breaks CSS entirely) — Fix first 2. **Legacy Variables** (deprecated) — Replace with new tokens 3. **Old Token Names** (pre-UI4) — Convert to `--color-*` naming 4. **Raw Palette Usage** (`--ramp-*` in components) — Replace with semantic `--color-*` tokens 5. **Hardcoded Values** (spacing, colors, radius) — Replace with tokens
Step 4: Report
After fixing, report:
- Total violations found
- Violations auto-fixed
- Violations that need manual review (no clear token match)
---
Violation Reference
SCSS Nesting (BREAKS CSS)
| Pattern | Issue | Fix | | --------------------------- | ------------------- | ------------------------------------ | | `&__element` | BEM element concat | Use flat `.block__element` selector | | `&--modifier` | BEM modifier concat | Use flat `.block--modifier` selector | | `.child { .parent--mod & }` | Parent reference | Move to `.parent--mod .child` |
**What DOES work:** `&:hover`, `&:focus`, `&::before`, `& .child`
---
Spacing Tokens
| Value | Token | | -------------- | -------------- | | 4px / 0.25rem | `--spacer-1` | | 8px / 0.5rem | `--spacer-2` | | 12px / 0.75rem | `--spacer-2-5` | | 16px / 1rem | `--spacer-3` | | 24px / 1.5rem | `--spacer-4` | | 32px / 2rem | `--spacer-5` | | 40px / 2.5rem | `--spacer-6` |
**Rounding rules — ALWAYS round to nearest token:**
| Pixel Range | Token | Notes | | ----------- | --------------------- | ----------------------------- | | 0-2px | `--spacer-0` | Use 0 | | 3-6px | `--spacer-1` (4px) | 5-6px rounds to 4px | | 7-10px | `--spacer-2` (8px) | 10px rounds DOWN to 8px | | 11-14px | `--spacer-2-5` (12px) | 13.33px rounds to 12px | | 15-20px | `--spacer-3` (16px) | 15px, 20px both round to 16px | | 21-28px | `--spacer-4` (24px) | | | 29-36px | `--spacer-5` (32px) | 30px rounds to 32px | | 37-48px | `--spacer-6` (40px) | |
**Rule:** For values ≤ 40px, ALWAYS use a single token (no `calc()`). For values > 40px, use `calc()` with a spacer token.
**Exceptions:** `0`, percentages, `auto`, `inherit`, `-1px` (for clip offsets)
---
Stroke Width Tokens
| Value | Token | | ----- | ---------------------- | | 1px | `--stroke-width-small` |
---
Radius Tokens
| Value | Token | | ---------------- | ----------------- | | 2px / 0.125rem | `--radius-small` | | 5px / 0.3125rem | `--radius-medium` | | 13px / 0.8125rem | `--radius-large` | | 9999px | `--radius-full` |
---
Elevation Tokens (Box Shadows)
Defined in `packages/ui/src/css/elevations.css`.
**Never use hardcoded `rgba()` for box-shadows.** Use elevation tokens instead:
| Token | Use Case | | ------------------------------ | --------------------------------- | | `--elevation-300-tooltip` | Tooltips, small floating elements | | `--elevation-400-menu-panel` | Menus, dropdowns, floating panels | | `--elevation-500-modal-window` | Modals, dialogs, full overlays |
/* ❌ BAD - hardcoded shadow */
box-shadow: 0 -2px 16px -2px rgba(0, 0, 0, 0.2);
/* ✅ GOOD - elevation token */
box-shadow: var(--elevation-400-menu-panel);
Elevations automatically adjust for light/dark themes.
---
Semantic Color Tokens (UI4 Naming)
All semantic colors use the `--color-` prefix. The `default` category and variant are implicit.
| Old Name | New Name (UI4) | | ------------------- | ------------------------- | | `--bg-
Read more
name: ui4-review description: Review UI4 CSS migrations for proper token usage. Checks that CSS variables are used instead of hardcoded values.
UI4 Review
Reviews CSS changes and **auto-fixes** token violations.
---
Important: Palette vs Semantic Tokens
**`--ramp-*` tokens** are the raw color palette (e.g., `--ramp-white-1000`, `--ramp-blue-500`). These are used **only** in `colors.css` to define semantic tokens.
**`--color-*` tokens** are context-aware semantic tokens (e.g., `--color-bg`, `--color-text-brand`). These handle light/dark theming automatically.
**Components and elements should ALWAYS use `--color-*` semantic tokens, never `--ramp-*` palette tokens directly.**
/* ❌ BAD - using raw palette */ background: var(--ramp-white-1000); /* ✅ GOOD - using semantic token */ background: var(--color-bg);
---
Process
Step 1: Get Changed CSS Files
git status --porcelain | grep '\.css$'
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:
# 1. SCSS Nesting Violations (BEM patterns that don't work in CSS)
grep -n '&__\|&--' "$FILE"
# 2. Hardcoded Spacing (px/rem values that should be tokens)
grep -nE ':\s*[0-9]+px|:\s*[0-9.]+rem' "$FILE"
# 3. Hardcoded Colors (hex, rgb, rgba - includes box-shadow)
grep -nE '#[0-9a-fA-F]{3,8}|rgba?\(' "$FILE"
# 4. Legacy Theme Variables
grep -nE 'var\(--theme-|var\(--style-|var\(--base\)' "$FILE"
# 5. Old Token Names (pre-UI4 naming)
grep -nE '\-\-bg-default|\-\-bg-secondary|\-\-text-default|\-\-text-secondary|\-\-icon-default|\-\-icon-secondary|\-\-border-default|\-\-border-strong' "$FILE"
# 6. Raw Palette Usage (should use semantic tokens instead)
# Skip this check for colors.css which defines the semantic tokens
grep -nE 'var\(--ramp-' "$FILE"**Invoke all 6 grep commands in a single parallel batch**, then analyze results.
**Note:** Raw `--ramp-*` violations are only flagged in component CSS files, not in `colors.css` where they're used to define semantic tokens.
Step 3: Auto-Fix by Priority
1. **SCSS Nesting** (breaks CSS entirely) — Fix first 2. **Legacy Variables** (deprecated) — Replace with new tokens 3. **Old Token Names** (pre-UI4) — Convert to `--color-*` naming 4. **Raw Palette Usage** (`--ramp-*` in components) — Replace with semantic `--color-*` tokens 5. **Hardcoded Values** (spacing, colors, radius) — Replace with tokens
Step 4: Report
After fixing, report:
- Total violations found
- Violations auto-fixed
- Violations that need manual review (no clear token match)
---
Violation Reference
SCSS Nesting (BREAKS CSS)
| Pattern | Issue | Fix | | --------------------------- | ------------------- | ------------------------------------ | | `&__element` | BEM element concat | Use flat `.block__element` selector | | `&--modifier` | BEM modifier concat | Use flat `.block--modifier` selector | | `.child { .parent--mod & }` | Parent reference | Move to `.parent--mod .child` |
**What DOES work:** `&:hover`, `&:focus`, `&::before`, `& .child`
---
Spacing Tokens
| Value | Token | | -------------- | -------------- | | 4px / 0.25rem | `--spacer-1` | | 8px / 0.5rem | `--spacer-2` | | 12px / 0.75rem | `--spacer-2-5` | | 16px / 1rem | `--spacer-3` | | 24px / 1.5rem | `--spacer-4` | | 32px / 2rem | `--spacer-5` | | 40px / 2.5rem | `--spacer-6` |
**Rounding rules — ALWAYS round to nearest token:**
| Pixel Range | Token | Notes | | ----------- | --------------------- | ----------------------------- | | 0-2px | `--spacer-0` | Use 0 | | 3-6px | `--spacer-1` (4px) | 5-6px rounds to 4px | | 7-10px | `--spacer-2` (8px) | 10px rounds DOWN to 8px | | 11-14px | `--spacer-2-5` (12px) | 13.33px rounds to 12px | | 15-20px | `--spacer-3` (16px) | 15px, 20px both round to 16px | | 21-28px | `--spacer-4` (24px) | | | 29-36px | `--spacer-5` (32px) | 30px rounds to 32px | | 37-48px | `--spacer-6` (40px) | |
**Rule:** For values ≤ 40px, ALWAYS use a single token (no `calc()`). For values > 40px, use `calc()` with a spacer token.
**Exceptions:** `0`, percentages, `auto`, `inherit`, `-1px` (for clip offsets)
---
Stroke Width Tokens
| Value | Token | | ----- | ---------------------- | | 1px | `--stroke-width-small` |
---
Radius Tokens
| Value | Token | | ---------------- | ----------------- | | 2px / 0.125rem | `--radius-small` | | 5px / 0.3125rem | `--radius-medium` | | 13px / 0.8125rem | `--radius-large` | | 9999px | `--radius-full` |
---
Elevation Tokens (Box Shadows)
Defined in `packages/ui/src/css/elevations.css`.
**Never use hardcoded `rgba()` for box-shadows.** Use elevation tokens instead:
| Token | Use Case | | ------------------------------ | --------------------------------- | | `--elevation-300-tooltip` | Tooltips, small floating elements | | `--elevation-400-menu-panel` | Menus, dropdowns, floating panels | | `--elevation-500-modal-window` | Modals, dialogs, full overlays |
/* ❌ BAD - hardcoded shadow */ box-shadow: 0 -2px 16px -2px rgba(0, 0, 0, 0.2); /* ✅ GOOD - elevation token */ box-shadow: var(--elevation-400-menu-panel);
Elevations automatically adjust for light/dark themes.
---
Semantic Color Tokens (UI4 Naming)
All semantic colors use the `--color-` prefix. The `default` category and variant are implicit.
| Old Name | New Name (UI4) | | ------------------- | ------------------------- | | `--bg-
Payload is the open-source, fullstack Next.js framework, giving you instant backend superpowers. Get a full TypeScript backend and admin panel instantly. Use Payload as a headless CMS or for building powerful applications.
Repo: payloadcms/payload
Other skills on payload.
- /audit-dependencies
Use when fixing dependency vulnerabilities, running pnpm audit, or when the audit-dependencies CI check fails
Open skill - /generate-translations
Use when new translation keys are added to packages to generate new translations strings
Open skill - /triage-ci-flake
Use when CI tests fail on main branch after PR merge, when investigating flaky test failures, or when user provides a PR URL/number to aggregate all failing tests
Open skill - /ui4-convert-tests
Use when UI changes are complete and e2e tests need updating. Analyzes what changed in UI components and systematically finds/fixes affected tests.
Open skill - /ui4
Manually invoked skill for reskinning Payload UI components. Requires Figma URL. Usage: /ui4
Open skill - /payload
Use when working with Payload projects (payload.config.ts, collections, fields, hooks, access control, Payload API). Use when debugging validation errors, security issues, relationship queries, transactions, or hook behavior.
Open skill

