ui-polish
Skill1 starsChanged 5 months agoMITView on GitHub
Designer-who-codes skill: audit a rendered UI against exacting visual standards, then fix what surfaces directly in source with one atomic commit per fix. Spans visual hierarchy, typography, color and contrast, spacing and layout, interaction states, responsive behavior, motion, content, AI-slop detection, and performance treated as a design concern. Emits letter grades (A-F) per category plus a headline Design Score and a standalone AI Slop Score. Three depth modes — Quick, Standard, Deep — with a default diff-aware pass scoped to a feature branch. Use when the user says "ui polish", "/ui-polish", "audit the UI", "visual audit", "check for AI slop", "design score", "polish the UI", or after shipping UI changes on a branch and wanting a visual audit plus fixes.
17 other projects use a version of this.
Adopted by
Most recently taken up by
- Markssuave/Markssuave-Agent-skillstheir own version, first seen Nov 8, 2026
- lukashouthoofd/cenekathontheir own version, first seen Nov 8, 2026
- trina-app/trina-axtheir own version, first seen Nov 8, 2026
- vijaysuperpositionist/skillstheir own version, first seen Nov 1, 2026
- cindyeme/ui-polishtheir own version, first seen Nov 1, 2026
- aictrl-dev/skillstheir own version, first seen Oct 22, 2026
Used with
Projects with it also use design.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
Microsoft AzureSkilldesign
Design rules and conventions for the API Center Portal. Use when editing detail pages, card components, badges, layout, navigation, sidebars, or headers. Covers badge styling, metadata placement, page navigation patterns, and layout alignment.
Also in 3 projects that use this
Other versions17 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 17
- trina-app/trina-ax★ 117same name
- felvieira/claude-skills-fv★ 27same name
- icons8/agent-skills★ 12same name
- The-Utopia-Studio/skills★ 6same name
- aictrl-dev/skills★ 3same name
- AhmedMerza/agent-skills★ 2same name
- AhmedMerza/claude-skills★ 2same name
- cindyeme/ui-polish★ 2same name
- jukrap/ai-agent-playbook★ 2same name
- lukashouthoofd/cenekathon★ 1same name
7 more not listed
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository24 other files it gives its agents.
- authorship-validatorSkill
- auth-setupSkill
- code-reviewSkill
- design-reviewSkill
- design-systemSkill
- devex-reviewSkill
- diagram-siteSkill
- doc-syncSkill
- file-followup-issuesSkill
- handoffSkill
- idea-reviewSkill
- investigate-bugSkill
- plan-reviewSkill
- pr-commentSkill
- pre-merge-reviewSkill
- qa-fixSkill
- qa-reportSkill
- qaSkill
- scope-reviewSkill
- semantic-compressorSkill
- shipSkill
- sql-performanceSkill
- team-retroSkill
- weekly-planSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
55 rules. 0 are common, 41 are distinctive, and 14 are very specific to this project.
0
Common
Most of the 14 edited versions we read keep these.
41
Distinctive
This author's own choices. Worth a look.
14
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 79
No URL and on main/master: ask the user for one.
- Distinctive: line 91
If the output is non-empty, STOP and use AskUserQuestion:
- Distinctive: line 110
If no browser tool is found, fall back to source-code design review: read the Tailwind config, CSS variables, component source, and layout …
- Very specific: line 118
When CDP_MODE=true: skip cookie-import prompts (the real browser already carries cookies), skip user-agent overrides, skip …
- Very specific: line 120
Outside-model reviewer (optional): if codex is on PATH, you MAY call it as an external voice for a source-code design audit (see Phase 7).
- Distinctive: line 137
Don't make me think: Every page should be self-evident.
- Distinctive: line 154
Clarity over consistency: When a small inconsistency makes something significantly clearer, take the clarity.
- Distinctive: line 199
Run the full audit, then load the prior baseline.
- Distinctive: line 211
Write the First Impression as a structured critique:
- Very specific: line 258
Source-code fallback: read tailwind.config.*, the CSS variable definitions, and shared style files.
- Very specific: line 276
After the first navigation, check whether the URL redirected to a login-like path (/login, /signin, /auth, /sso).
- Distinctive: line 312
No blacklisted fonts (Papyrus, Comic Sans, Lobster, Impact, Jokerman)
- Very specific: line 313
If the primary font is Inter/Roboto/Open Sans/Poppins -> flag as potentially generic
- Distinctive: line 320
No letter-spacing on lowercase text
- Distinctive: line 326
No color-only encoding (always add labels, icons, or patterns)
- Distinctive: line 331
No red/green-only combinations (8% of men have red-green deficiency)
- Distinctive: line 341
No horizontal scroll on mobile
- Distinctive: line 364
No horizontal scroll on any viewport
- Very specific: line 377
Only transform and opacity animated (not width, height, top, left)
- Distinctive: line 383
No placeholder/lorem ipsum text visible in production
- Distinctive: line 413
No visible font-swap flash (FOUT) — critical fonts preloaded
- Distinctive: line 437
Keep a running goodwill meter (start at 70/100).
- Distinctive: line 482
Grade computation: every category starts at A.
- Very specific: line 501
Regression: when design-baseline.json exists or --regression is set, load the baseline and compare per-category deltas, new findings, and …
- Very specific: line 509
Default — run this inline, no fan-out: Do one in-context adversarial pass yourself: re-read the repo source through the design-consistency …
- Distinctive: line 515
Opt-in — fan out only after the user agreed to parallelism: When they have, run the two lenses as a Workflow judge panel instead of inline, …
- Distinctive: line 591
If the user asked for an audit only (no source edits, no commits — see *Gather context first*), skip this phase and go straight to the …
- Distinctive: line 598
Prefer Tailwind class changes over custom CSS.
- Distinctive: line 599
Prefer CSS over structural/JSX changes.
- Distinctive: line 600
Do NOT refactor surrounding code, add features, or "improve" unrelated things.
- Distinctive: line 631
If the fix touches JS behavior (broken dropdowns, animation failures, conditional rendering, interactive state), study the existing test …
- Distinctive: line 635
Every 5 fixes, or right after any revert, compute risk:
- Distinctive: line 647
If risk > 20%: STOP. Show the user what's been done so far.
- Distinctive: line 649
Hard cap: 30 fixes: Stop regardless of remaining findings.
- Very specific: line 665
Write to .design-reports/design-audit-{domain-or-branch}-{YYYY-MM-DD}.md (fall back to ~/.claude/design-reports/ if the repo is read-only):
- Very specific: line 722
Baseline: write design-baseline.json next to the report for regression mode.
- Very specific: line 724
TODOS.md update: if the repo has a TODOS.md, add deferred findings as TODOs and annotate any fixed finding that was already listed there …
- Distinctive: line 769
No flat single-color backgrounds — use gradients, images, subtle patterns
- Distinctive: line 772
No cards in the hero. Cards only when the card IS the interaction
- Distinctive: line 782
Avoid: dashboard-card mosaics, thick borders, decorative gradients, ornamental icons
- Distinctive: line 789
No default font stacks (Inter, Roboto, Arial, system)
- Distinctive: line 793
NEVER small, low-contrast type (body text < 16px or contrast ratio < 4.5:1)
- Distinctive: line 794
NEVER use placeholder-as-label (labels must stay visible once the field has content)
- Distinctive: line 795
ALWAYS preserve the visited vs unvisited link distinction
- Distinctive: line 796
NEVER float headings between paragraphs (a heading must sit visually closer to the section it introduces)
- Very specific: line 803
Screenshots are evidence: Every finding needs at least one.
- Distinctive: line 806
Quick Wins matter: Always surface the 3-5 highest-impact fixes that take under 30 minutes.
- Distinctive: line 807
CSS-first: Prefer Tailwind class changes — safer and more reversible than structural ones.
- Distinctive: line 808
One commit per fix: Never bundle.
- Distinctive: line 811
Document incrementally: Write each finding to the report as you find it.
- Very specific: line 812
Show screenshots to the user: After every $B screenshot, $B snapshot -a -o, or $B responsive, use the Read tool on the output file(s) so …
- Very specific: line 813
Clean working tree required: If dirty, offer commit/stash/abort before proceeding.
- Distinctive: line 814
Revert on regression: If a fix makes things worse, git revert HEAD immediately.
- Distinctive: line 815
Self-regulate: Follow the risk heuristic.
- Distinctive: line 821
After the audit and fixes, point to the next step:
“Common” is measured: kept by at least 6 in 10 of the 14 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
UI Polish — Visual Audit, Fix, Verify
Wear two hats at once: senior product designer and frontend engineer. Inspect the rendered UI with an unforgiving eye, then go into the source and fix what you found. You hold firm opinions on typography, spacing, and hierarchy, and you have no patience for interfaces that look generic or machine-generated.
Judge like a designer, not a QA tester. The question is never just "does it work?" — it's "does this feel right, look deliberate, and respect the person using it?"
Gather context first
This skill ships standalone, so it can't assume your project's conventions, house style, or preferences the way it could for its author. Before doing the main work:
- Auto-detect what you safely can from the repo — language/stack, base branch, build/test commands, existing config and docs. Never ask for something you can read for yourself.
- Ask, don't assume, for the rest. Where an input, convention, or preference would change the result and you can't reliably detect it, ask ONE concise
AskUserQuestion(put a sensible default first, labelled Recommended) instead of guessing. The user has less context than this skill's author assumed — a wrong silent default is worse than a quick question. Don't ask about things you can detect, and don't ask more than you need.
For this skill, confirm up front (only the items you can't already detect):
- Fix-and-commit, or audit-only? — the default is to fix findings in source with one atomic commit each. If the user only wants the report (no source edits, no commits), confirm before touching files.
- What to audit — the target URL/route(s), or confirm diff-aware mode on the current branch; and whether the dev server is already running (and on which port).
- Base branch for diff-aware mode — auto-detect the repo's default branch; confirm only when it's ambiguous. Don't assume
main. - Depth mode — Quick (homepage + 2), Standard (5-8 pages), or Deep (10-15). Default Standard.
- Auth — does the target require login, and should it use imported browser cookies or credentials?
How this runs
The entire audit-fix-verify loop runs inline in the main conversation by default. That is deliberate: the interactive spine depends on it. The clean-tree ceremony, the auth-detection prompt, the DESIGN.md save offer, the per-finding triage, and the self-regulation STOP gates all need the user to answer you directly through AskUserQuestion. The browser-driven audit (navigate → screenshot → extract → re-test) is likewise a serial, stateful chain — each step builds on the rendered state and on git mutations from the previous fix — so it stays inline too.
There is exactly one piece that can be parallelized: Phase 7, the Adversarial Review. The two reviewer lenses (a Claude design-consistency pass and an optional outside-model source audit) are genuinely independent diagnoses over the same repo. By default, run them inline, one after the other. Parallel subagents can be faster on large jobs (big diffs, many files, deep multi-pass analysis), but before spawning any subagent or Workflow, stop and ask the user, for example:
This is large ([many pages / big diff]). I can do it inline here (cheaper, slower) or fan out [the adversarial design panel as parallel subagents] (faster, more tokens). Which do you want?
Spawn subagents/workflows only after an explicit yes. If the user declines or doesn't answer, do the whole job inline. Only on an explicit yes should you fan the two lenses out as a Workflow judge panel and then return to the main loop to merge the voices.
If — and only if — you do fan out to a Workflow: agent() calls run in the background; they cannot call AskUserQuestion, cannot talk to the user, and cannot write files. So every gate, ceremony, per-finding walkthrough, self-regulation STOP, and every file write (the report, design-baseline.json, TODOS.md updates, every screenshot saved via $B, every git commit) stays in the main loop. A workflow does headless compute only — read the repo, diagnose consistency patterns, return structured findings — and hands results back for you to present and decide on. Set model: 'opus' on every agent() call so no lightweight tier leaks in, and pass everything in through args (Workflow scripts have no Date.now / Math.random / filesystem access — timestamps, screenshots, commits, and file writes all belong to the main loop).
Arguments
Read $ARGUMENTS:
- A target URL → audit it directly (
https://myapp.com,http://localhost:3000). - A scope hint — "focus on the settings page", "just the homepage" → diff-scope or page-scope the audit.
- A depth/mode hint —
--quick,--deep,--regression→ pick the matching mode below. - A PR number / commit ref / branch name → scope the diff-aware audit to that ref.
- Empty → on a feature branch, enter diff-aware mode automatically; on main/master, ask for a URL.
Setup
Pull these parameters out of the user's request:
| Parameter | Default | Override example |
| Target URL | auto-detect or ask | https://myapp.com, http://localhost:3000 |
| Scope | Full site or diff-scoped | Focus on the settings page, Just the homepage |
| Depth | Standard (5-8 pages) | --quick (homepage + 2), --deep (10-15 pages) |
| Output dir | .design-reports/ | Output to ~/.claude/design-reports |
| Auth | None | Sign in as user@example.com, Import cookies from cookies.json |
No URL and on a feature branch: drop straight into diff-aware mode. This is the common case — the user just shipped UI changes on a branch and wants them audited.
No URL and on main/master: ask the user for one.
Look for DESIGN.md:
Check the repo root for DESIGN.md, design-system.md, or similar. If one exists, read it — every design decision is then measured against it, and deviations from the stated system carry higher severity. If none exists, fall back to universal design principles plus the project's Tailwind/CSS config. Offer to generate a DESIGN.md from the inferred system at the end of Phase 2.
Demand a clean working tree:
git status --porcelainIf the output is non-empty, STOP and use AskUserQuestion:
"Your working tree has uncommitted changes. ui-polish needs a clean tree so each design fix lands as its own atomic commit."
A) Commit my changes — commit everything now with a descriptive message, then start the audit B) Stash my changes — stash, run the audit, pop the stash afterward C) Abort — I'll clean up manually
RECOMMENDATION: A — uncommitted work should be captured as a commit before ui-polish layers its own fix commits on top.
Browser automation tool ($B):
This skill needs a browser automation tool to render the app and collect screenshots. Detect one in this order:
command -v browse >/dev/null 2>&1 && B=browse
[ -z "$B" ] && [ -x "./scripts/browse" ] && B="./scripts/browse"If no browser tool is found, fall back to source-code design review: read the Tailwind config, CSS variables, component source, and layout markup; predict the rendered output; and document findings as source references. Screenshots and live interaction checks are skipped in this fallback.
Detect CDP mode (when $B is wired to a real browser):
$B status 2>/dev/null | grep -q "Mode: cdp" && echo "CDP_MODE=true" || echo "CDP_MODE=false"When CDP_MODE=true: skip cookie-import prompts (the real browser already carries cookies), skip user-agent overrides, skip headless-detection workarounds.
Outside-model reviewer (optional): if codex is on PATH, you MAY call it as an external voice for a source-code design audit (see Phase 7). It is optional. If it isn't available, run a single Claude reviewer as the adversarial pass, or skip the phase.
Create output directories:
mkdir -p .design-reports/screenshots
# Fall back to ~/.claude/design-reports/ if the repo is read-only or the user prefersUX Principles: How Users Actually Behave
These describe how real people move through interfaces — observed behavior, not taste. Apply them before, during, and after every design call.
The Three Laws of Usability
- Don't make me think. Every page should be self-evident. The moment a user pauses to ask "What do I click?" or "What does this mean?", the design has already lost. Self-evident beats self-explanatory beats requires-explanation.
- Clicks don't matter, thinking does. Three mindless, unambiguous clicks beat one click that demands a decision. Each step should land as an obvious choice, never a riddle.
- Omit, then omit again. Cut half the words on every page, then cut half of what survives. Happy talk — self-congratulatory filler — and instructions both have to go. If something needs to be read to be used, the design failed.
How Users Actually Behave
- Users scan, they don't read. Build for scanning: visual hierarchy (prominence equals importance), clearly bounded regions, headings and bullet lists, highlighted key terms. Billboards at 60 mph, not product brochures.
- Users satisfice. They take the first reasonable option, not the best one. Make the right choice the most visible choice.
- Users muddle through. They don't reverse-engineer how things work — they improvise. Once something works, they keep doing it.
- Users skip instructions. They dive in. Any guidance has to be brief, perfectly timed, and impossible to miss, or it goes unread.
Billboard Design for Interfaces
- Lean on convention. Logo top-left, nav top/left, search as a magnifying glass. Don't get clever with navigation.
- Hierarchy is everything. Group related things visually. Contain nested things visually. More important means more prominent. If everything shouts, nothing is heard.
- Make clickable things look clickable. Shape, placement, and styling should signal interactivity before any interaction — especially on mobile, where there's no hover.
- Kill the noise. It comes from three places: shouting (too many elements competing), disorganization, and clutter. Fix by subtraction, not addition.
- Clarity over consistency. When a small inconsistency makes something significantly clearer, take the clarity.
Navigation as Wayfinding
People on the web have no innate sense of scale, direction, or position. Navigation has to keep answering: What site is this? What page am I on? What are the major sections? What are my options here? Where am I? How do I search?
The trunk test: mask everything except the navigation. You should still be able to tell what site this is, what page you're on, and what the major sections are. If you can't, the navigation has failed.
The Goodwill Reservoir
Users arrive with a reservoir of goodwill. Every point of friction drains it.
Drains faster: hiding what users want (pricing, contact). Punishing them for not doing it your way (rigid phone-number formats). Asking for information you don't need. Throwing sizzle in the path (splash screens, forced tours). Looking unprofessional or sloppy.
Refills: know what users want and surface it. Tell them what they need upfront. Save them steps. Make error recovery painless. When in doubt, apologize.
Mobile: Same Rules, Higher Stakes
Everything above holds on mobile, only more so. Space is scarce, but never trade usability for it. Affordances have to be VISIBLE — no cursor means no hover-to-discover. Touch targets are at least 44px. Prioritize ruthlessly: what's needed in a hurry stays close at hand, everything else is a few taps away behind an obvious path.
Modes
Full (default when a URL is provided)
Systematic sweep of every page reachable from the homepage. Visit 5-8 pages. Full checklist, responsive screenshots, interaction-flow testing. Produces a complete audit report with letter grades.
Quick (--quick)
Homepage plus 2 key pages. First Impression + Design System Extraction + an abbreviated checklist. Fastest route to a design score.
Deep (--deep)
The full treatment: 10-15 pages, every interaction flow, the exhaustive checklist. For pre-launch audits or major redesigns.
Diff-aware (automatic on a feature branch with no URL)
- Determine the base branch by auto-detecting the repo's default branch (e.g.
git symbolic-ref refs/remotes/origin/HEAD) — don't assumemain; confirm only if it's ambiguous. Thengit diff <base>...HEAD --name-onlyto list changed files - Map changed files to the pages/routes/components they affect
- Detect a running app on common local ports (3000, 4000, 8080)
- Audit only the affected pages
Regression (--regression, or when design-baseline.json exists)
Run the full audit, then load the prior baseline. Compare per-category grade deltas, new findings, resolved findings. Append a regression table to the report.
Workflow
Phase 1: First Impression
The most distinctly designerly output. React in your gut before you analyze anything.
- Navigate to the target URL
- Capture a full-page desktop screenshot:
$B screenshot .design-reports/screenshots/first-impression.png - Write the First Impression as a structured critique:
- "The site communicates [what]." (what it says at a glance — competence? playfulness? confusion?)
- "I notice [observation]." (what jumps out, good or bad — be specific)
- "The first 3 things my eye lands on are: [1], [2], [3]." (a hierarchy check — are these the three the designer intended? If not, the hierarchy is lying.)
- "One word for this: [word]." (gut verdict)
Narration mode: write in first person, as a user scanning for the very first time. "I'm looking at this page... my eye goes to the logo, then a wall of text I skip, then... wait, is that a button?" Name specific elements, positions, weights. If you can't name something specifically, you're not scanning — you're generating platitudes.
Page Area Test: point at each clearly bounded region of the page. Can you name its purpose instantly? ("Things I can buy," "Today's deals," "How to search.") Any region you can't name within two seconds is poorly defined. List them.
Take a position. A designer reacts; they don't hedge.
Source-code fallback: with $B unavailable, read the main page component and the global styles. Write the First Impression from what the code implies the page would render. Flag the fallback explicitly in the report.
Phase 2: Design System Extraction
Extract the design system the site actually uses — not what DESIGN.md claims, but what renders:
# Fonts in use (capped to avoid timeout)
$B js "JSON.stringify([...new Set([...document.querySelectorAll('*')].slice(0,500).map(e => getComputedStyle(e).fontFamily))])"
# Color palette in use
$B js "JSON.stringify([...new Set([...document.querySelectorAll('*')].slice(0,500).flatMap(e => [getComputedStyle(e).color, getComputedStyle(e).backgroundColor]).filter(c => c !== 'rgba(0, 0, 0, 0)'))])"
# Heading hierarchy
$B js "JSON.stringify([...document.querySelectorAll('h1,h2,h3,h4,h5,h6')].map(h => ({tag:h.tagName, text:h.textContent.trim().slice(0,50), size:getComputedStyle(h).fontSize, weight:getComputedStyle(h).fontWeight})))"
# Touch target audit
$B js "JSON.stringify([...document.querySelectorAll('a,button,input,[role=button]')].filter(e => {const r=e.getBoundingClientRect(); return r.width>0 && (r.width<44||r.height<44)}).map(e => ({tag:e.tagName, text:(e.textContent||'').trim().slice(0,30), w:Math.round(e.getBoundingClientRect().width), h:Math.round(e.getBoundingClientRect().height)})).slice(0,20))"
# Performance baseline
$B perfLay the findings out as an Inferred Design System:
- Fonts: list with usage counts. Flag more than 3 distinct families.
- Colors: the extracted palette. Flag more than 12 unique non-gray colors. Note warm/cool/mixed.
- Heading Scale: h1-h6 sizes. Flag skipped levels and non-systematic size jumps.
- Spacing Patterns: sampled padding/margin values. Flag off-scale values.
- Border radius: hierarchical, or uniformly bubbly everywhere?
Compare the extracted system against DESIGN.md if it exists, and flag deviations. Then offer: "Want me to save this as your DESIGN.md? I can lock these observations in as your project's design-system baseline."
Source-code fallback: read tailwind.config.*, the CSS variable definitions, and shared style files. Pull the tokens straight from config.
Phase 3: Page-by-Page Visual Audit
For each page in scope:
$B goto <url>
$B snapshot -i -a -o ".design-reports/screenshots/{page}-annotated.png"
$B responsive ".design-reports/screenshots/{page}"
$B console --errors
$B perfAuth Detection
After the first navigation, check whether the URL redirected to a login-like path (/login, /signin, /auth, /sso). If it did, AskUserQuestion: "This site requires authentication. Want to import cookies from your browser, or provide credentials?"
Trunk Test (run on every page)
Imagine landing on this page with no context. Can you immediately answer:
- What site is this?
- What page am I on?
- What are the major sections?
- What are my options at this level?
- Where am I in the overall scheme?
- How do I search?
Score: PASS (all 6 clear) / PARTIAL (4-5 clear) / FAIL (3 or fewer). A FAIL is a HIGH-impact finding no matter how polished the visuals are.
Design Audit Checklist (10 categories, ~80 items)
Each finding gets an impact rating (high/medium/polish) and a category.
1. Visual Hierarchy & Composition (8 items)
- Clear focal point? One primary CTA per view?
- Eye flows naturally top-left to bottom-right?
- Visual noise — competing elements?
- Information density appropriate for the content type?
- Z-index clarity — nothing unexpectedly overlapping?
- Above-the-fold content communicates purpose in 3 seconds?
- Squint test: hierarchy still legible when blurred?
- White space is intentional, not leftover?
2. Typography (15 items)
- Font count <= 3
- Scale follows a ratio (1.25 major third or 1.333 perfect fourth)
- Line-height: 1.5x body, 1.15-1.25x headings
- Measure: 45-75 chars per line (66 ideal)
- Heading hierarchy: no skipped levels (h1->h3 without h2)
- Weight contrast: >=2 weights used for hierarchy
- No blacklisted fonts (Papyrus, Comic Sans, Lobster, Impact, Jokerman)
- If the primary font is Inter/Roboto/Open Sans/Poppins -> flag as potentially generic
text-wrap: balanceortext-prettyon headings- Curly quotes, not straight quotes
- Ellipsis character (
...) as one glyph, not three dots font-variant-numeric: tabular-numson number columns- Body text >= 16px
- Caption/label >= 12px
- No letter-spacing on lowercase text
3. Color & Contrast (10 items)
- Palette coherent (<=12 unique non-gray colors)
- WCAG AA: body text 4.5:1, large text 3:1, UI components 3:1
- Semantic colors consistent (success=green, error=red, warning=amber)
- No color-only encoding (always add labels, icons, or patterns)
- Dark mode: surfaces use elevation, not just lightness inversion
- Dark mode: text off-white (~#E0E0E0), not pure white
- Primary accent desaturated 10-20% in dark mode
color-scheme: darkon the html element if dark mode is present- No red/green-only combinations (8% of men have red-green deficiency)
- Neutral palette is warm or cool consistently — not mixed
4. Spacing & Layout (12 items)
- Grid consistent at all breakpoints
- Spacing uses a scale (4px or 8px base), not arbitrary values
- Alignment consistent — nothing floats outside the grid
- Rhythm: related items closer, distinct sections further apart
- Border-radius hierarchy (not uniform bubbly on everything)
- Inner radius = outer radius - gap (nested elements)
- No horizontal scroll on mobile
- Max content width set (no full-bleed body text)
env(safe-area-inset-*)for notch devices- URL reflects state (filters, tabs, pagination in query params)
- Flex/grid used for layout (not JS measurement)
- Breakpoints: mobile (375), tablet (768), desktop (1024), wide (1440)
5. Interaction States (10 items)
- Hover state on all interactive elements
focus-visiblering present (neveroutline: nonewithout a replacement)- Active/pressed state with depth or color shift
- Disabled: reduced opacity +
cursor: not-allowed - Loading: skeleton shapes match the real content layout
- Empty states: warm message + primary action + visual (not just "No items.")
- Error messages: specific + include the fix/next step
- Success: confirmation animation or color, auto-dismiss
- Touch targets >= 44px on all interactive elements
cursor: pointeron all clickable elements- Mindless-choice audit: every decision point is obvious. If a click requires thought about whether it's right, flag as HIGH.
6. Responsive Design (8 items)
- Mobile layout makes design sense (not just stacked desktop columns)
- Touch targets sufficient on mobile (>= 44px)
- No horizontal scroll on any viewport
- Images responsive (srcset, sizes, or CSS containment)
- Text readable without zoom on mobile (>= 16px body)
- Navigation collapses appropriately (hamburger, bottom nav)
- Forms usable on mobile (correct input types, no autoFocus on mobile)
- No
user-scalable=noormaximum-scale=1in the viewport meta
7. Motion & Animation (6 items)
- Easing: ease-out entering, ease-in exiting, ease-in-out moving
- Duration: 50-700ms range (nothing slower unless it's a page transition)
- Purpose: every animation communicates something
prefers-reduced-motionrespected- No
transition: all— properties listed explicitly - Only
transformandopacityanimated (not width, height, top, left)
8. Content & Microcopy (8 items)
- Empty states designed with warmth (message + action + illustration/icon)
- Error messages specific: what happened + why + what to do next
- Button labels specific ("Save API Key" not "Continue" or "Submit")
- No placeholder/lorem ipsum text visible in production
- Truncation handled (
text-overflow: ellipsis,line-clamp,break-words) - Active voice ("Install the CLI" not "The CLI will be installed")
- Loading states end with an ellipsis glyph
- Destructive actions have a confirmation modal or undo window
- Happy talk detection: scan for "Welcome to...", self-congratulatory text. Flag it.
- Instructions detection: visible instructions longer than one sentence. Flag the instructions AND the interaction they're compensating for.
- Happy talk word count: classify each text block as "useful content" vs "happy talk." Report: "This page has X words. Y (Z%) are happy talk."
9. AI Slop Detection (10 anti-patterns — the blacklist)
The test: would a human designer at a respected studio actually ship this?
- Purple/violet/indigo gradient backgrounds or blue-to-purple color schemes
- The 3-column feature grid: icon-in-colored-circle + bold title + 2-line description, repeated 3x symmetrically. THE most recognizable AI layout.
- Icons in colored circles as section decoration (SaaS starter-template look)
- Centered everything (
text-align: centeron all headings, descriptions, cards) - Uniform bubbly border-radius on every element
- Decorative blobs, floating circles, wavy SVG dividers (if a section feels empty, it needs better content, not decoration)
- Emoji as design elements (rockets in headings, emoji as bullet points)
- Colored left-border on cards (
border-left: 3px solid <accent>) - Generic hero copy ("Welcome to [X]", "Unlock the power of...", "Your all-in-one solution for...")
- Cookie-cutter section rhythm (hero -> 3 features -> testimonials -> pricing -> CTA, every section the same height)
10. Performance as Design (6 items)
- LCP < 2.0s (web apps), < 1.5s (informational sites)
- CLS < 0.1 (no visible layout shifts during load)
- Skeleton quality: shapes match the real content layout, shimmer animation
- Images:
loading="lazy", width/height set, WebP/AVIF format - Fonts:
font-display: swap, preconnect to CDN origins - No visible font-swap flash (FOUT) — critical fonts preloaded
Phase 4: Interaction Flow Review
Walk 2-3 key user flows and judge the feel, not just the function:
$B snapshot -i
$B click @e3
$B snapshot -DEvaluate:
- Response feel: does clicking feel responsive? Any missing loading states?
- Transition quality: intentional, or generic/absent?
- Feedback clarity: did the action clearly succeed or fail? Is feedback immediate?
- Form polish: focus states visible? Validation timing right? Errors near their source?
Narration mode: narrate in first person. "I click 'Sign Up'... spinner appears... 3 seconds pass... still spinning... I'm getting nervous. Finally the dashboard loads, but where am I?"
Goodwill Reservoir (track across the flow)
Keep a running goodwill meter (start at 70/100). It's a heuristic, not a measurement — the value is in naming the specific drains and fills.
Subtract for:
- Hidden information the user would want: -15
- Format punishment (rejecting valid input): -10
- Unnecessary information requests: -10
- Interstitials, splash screens, forced tours: -15
- Sloppy or unprofessional appearance: -10
- Ambiguous choices that require thinking: -5 each
Add for:
- Top user tasks obvious and prominent: +10
- Upfront about costs and limitations: +5
- Saves steps (direct links, smart defaults, autofill): +5 each
- Graceful error recovery with a specific fix: +10
- Apologizes when things go wrong: +5
Report it as a dashboard. Below 30 = critical UX debt. 30-60 = needs work. Above 60 = healthy.
Phase 5: Cross-Page Consistency
Compare screenshots and observations across pages:
- Navigation bar consistent across all pages?
- Footer consistent?
- Component reuse vs one-off designs (the same button styled three ways)?
- Tone consistency (one page playful while another is corporate)?
- Spacing rhythm carries across pages?
Phase 6: Scoring
Two headline scores:
- Design Score: {A-F} — weighted average across all 10 categories
- AI Slop Score: {A-F} — a standalone grade with a pithy verdict
Per-category grades:
- A: Intentional, polished, delightful. Shows design thinking.
- B: Solid fundamentals, minor inconsistencies. Professional.
- C: Functional but generic. No major problems, no design point of view.
- D: Noticeable problems. Feels unfinished or careless.
- F: Actively hurting UX. Needs significant rework.
Grade computation: every category starts at A. Each High-impact finding drops it one full letter. Each Medium drops it half. Polish findings are noted but don't move the grade. Floor is F.
Category weights for the Design Score:
| Category | Weight |
| Visual Hierarchy | 15% |
| Typography | 15% |
| Spacing & Layout | 15% |
| Color & Contrast | 10% |
| Interaction States | 10% |
| Responsive | 10% |
| Content Quality | 10% |
| AI Slop | 5% |
| Motion | 5% |
| Performance Feel | 5% |
AI Slop counts for 5% of the Design Score, and is also graded on its own as a headline metric.
Regression: when design-baseline.json exists or --regression is set, load the baseline and compare per-category deltas, new findings, and resolved findings. Append a regression table.
Phase 7: Adversarial Review (optional)
Before fixing anything, get an independent second read on the diagnosis. A design-consistency reviewer and an optional outside-model source auditor look at the same repo through different lenses and catch different classes of failure, so a second opinion that agrees is stronger signal than a single pass.
Default — run this inline, no fan-out. Do one in-context adversarial pass yourself: re-read the repo source through the design-consistency lens below, and, if codex is on PATH, optionally shell out to it once (read-only) and fold its output in. No subagents, no Workflow.
The design-consistency lens asks about patterns across files rather than isolated violations: are spacing values systematic across the codebase or scattered? Is there ONE color system or several competing approaches? Do responsive breakpoints share a consistent set? Is accessibility handled consistently or only in spots? For each finding, record what is wrong, the severity (critical/high/medium), and the file:line.
If codex is available, run it in read-only mode against the source (a design classifier plus the litmus checks and hard rejection criteria below, timeout 5 minutes) and fold its findings in under a CODEX SAYS (design source audit): header. If Codex fails for any reason — auth, timeout, empty response — continue with the consistency lens alone. Never block on Codex.
Opt-in — fan out only after the user agreed to parallelism. When they have, run the two lenses as a Workflow judge panel instead of inline, then return to the main loop to present and merge the voices:
export const meta = {
name: 'ui-polish-adversarial',
description: 'Independent design-audit panel — one lens per agent — over the repo source',
phases: [{ title: 'Challenge' }],
}
const FINDING_SCHEMA = {
type: 'object',
properties: {
voice: { type: 'string' }, // CLAUDE SUBAGENT | CODEX
findings: {
type: 'array',
items: {
type: 'object',
properties: {
what: { type: 'string' },
severity: { type: 'string' }, // critical | high | medium
location: { type: 'string' }, // file:line
},
required: ['what', 'severity'],
},
},
},
required: ['voice', 'findings'],
}
const LENSES = [
{
key: 'claude-consistency',
voice: 'CLAUDE SUBAGENT (design consistency)',
instruction:
'You are an independent senior product designer doing a source-code design audit on this repo. ' +
'Focus on CONSISTENCY PATTERNS across files rather than individual violations: ' +
'Are spacing values systematic across the codebase? Is there ONE color system or scattered approaches? ' +
'Do responsive breakpoints follow a consistent set? Is the accessibility approach consistent or spotty? ' +
'For each finding: what is wrong, severity (critical/high/medium), and file:line.',
},
{
key: 'codex-source-audit',
voice: 'CODEX (design source audit)',
instruction:
'You are an outside-model source-code design auditor. Apply a design classifier plus litmus checks ' +
'and hard rejection criteria to the repo source. For each finding: what is wrong, severity ' +
'(critical/high/medium), and file:line.',
},
]
const panel = await parallel(LENSES.map(l => () =>
agent(
`${l.instruction}\n\nRepo root: ${args.repoRoot}. DESIGN.md present: ${args.hasDesignMd}. ` +
`Report findings only — do not edit any files. Tag your voice as "${l.voice}".`,
{ label: `challenge:${l.key}`, phase: 'Challenge', model: 'opus', schema: FINDING_SCHEMA }
)
))
return panel.filter(Boolean)Pass args: { repoRoot: "<repo root path>", hasDesignMd: true|false }. In the fan-out path the Codex lens runs as an agent() with the source-audit prompt rather than blocking the panel on the codex CLI; if you'd rather call the real codex exec binary in read-only mode, do so in the main loop AFTER the workflow returns and fold its output in under the CODEX SAYS (design source audit): header. If the Workflow itself fails or times out, fall back to a single in-loop Agent-tool reviewer, or skip.
Whether inline or fanned out, present each voice under its own header (CLAUDE SUBAGENT (design consistency): / CODEX SAYS (design source audit):) in the main loop, and merge findings into triage with [subagent] / [codex] / [cross-model] tags.
Phase 8: Triage
Sort findings by impact, then decide what gets fixed:
- High Impact: fix first. Shapes the first impression and erodes user trust.
- Medium Impact: fix next. Costs polish, felt subconsciously.
- Polish: fix if there's time.
Mark anything that can't be fixed from source (third-party widgets, copy owned by the team) as deferred.
Phase 9: Fix Loop
If the user asked for an audit only (no source edits, no commits — see Gather context first), skip this phase and go straight to the report.
For each fixable finding, in impact order:
9a. Locate source — glob/grep for the affected component or style file. Touch only files directly tied to the finding.
9b. Fix — make the minimal change.
- Prefer Tailwind class changes over custom CSS.
- Prefer CSS over structural/JSX changes.
- Do NOT refactor surrounding code, add features, or "improve" unrelated things.
9c. Commit:
git add <only-changed-files>
git commit -m "style(design): FINDING-NNN — short description"One commit per fix. Never bundle. If the repo follows a different commit-message convention (check git log for the prevailing style), match it instead of this style(design): prefix.
9d. Re-test:
$B goto <affected-url>
$B screenshot ".design-reports/screenshots/finding-NNN-after.png"
$B console --errors
$B snapshot -DCapture a before/after screenshot pair for every fix.
9e. Classify:
- verified — re-test confirms the fix, no new errors
- best-effort — fix applied but couldn't be fully verified (e.g., needs specific browser state)
- reverted — regression detected ->
git revert HEAD-> mark the finding deferred
9e.5. Regression test (only when the fix touches JS behavior):
Design fixes are usually CSS-only. Skip regression tests for pure CSS changes — rerunning this skill catches CSS regressions.
If the fix touches JS behavior (broken dropdowns, animation failures, conditional rendering, interactive state), study the existing test patterns, write a regression test that encodes the exact bug condition, and commit: test(design): regression test for FINDING-NNN.
9f. Self-regulation (STOP AND EVALUATE):
Every 5 fixes, or right after any revert, compute risk:
DESIGN-FIX RISK:
Start at 0%
Each revert: +15%
Each CSS-only file change: +0% (safe)
Each JSX/TSX/component file change: +5% per file
After fix 10: +1% per additional fix
Touching unrelated files: +20%If risk > 20%: STOP. Show the user what's been done so far. Ask whether to keep going.
Hard cap: 30 fixes. Stop regardless of remaining findings.
Phase 10: Final Audit
Once all fixes are in:
- Re-run the audit on every affected page
- Recompute the Design Score and AI Slop Score
- If the final scores are WORSE than baseline: WARN prominently — something regressed.
Phase 11: Report
Write to .design-reports/design-audit-{domain-or-branch}-{YYYY-MM-DD}.md (fall back to ~/.claude/design-reports/ if the repo is read-only):
# Design Audit — {branch or domain}
**Date:** YYYY-MM-DD
**Branch:** {branch}
**Mode:** Quick / Standard / Deep / Diff-aware
**DESIGN.md:** Found / Not found
**Adversarial review:** Claude subagent / Codex / both
---
## First Impression
[Phase 1 output]
## Inferred Design System
[Phase 2 extraction — fonts, colors, spacing, radii]
## Scores
| Category | Grade | Findings |
|----------|-------|----------|
| Visual Hierarchy | X | N issues |
| Typography | X | N issues |
| Spacing & Layout | X | N issues |
| Color & Contrast | X | N issues |
| Interaction States | X | N issues |
| Responsive | X | N issues |
| Content Quality | X | N issues |
| AI Slop | X | N issues |
| Motion | X | N issues |
| Performance Feel | X | N issues |
| **Design Score** | **X** | |
| **AI Slop Score** | **X** | |
## Goodwill Reservoir
[Dashboard + top drains/fills]
## Quick Wins (top 5 highest-impact, <30 min each)
1. [finding + fix]
2. ...
## All Findings
[Full details per finding — category, impact, evidence, before/after screenshots, fix status, commit SHA, files changed]
## Summary
- Findings: N total (X high, Y medium, Z polish)
- Fixed: N (verified: X, best-effort: Y, reverted: Z)
- Deferred: N
- Design Score: X -> Y (after fixes)
- AI Slop Score: X -> Y
## PR Summary
> "Design audit found N issues, fixed M. Design score X -> Y, AI slop score X -> Y."Baseline: write design-baseline.json next to the report for regression mode.
TODOS.md update: if the repo has a TODOS.md, add deferred findings as TODOs and annotate any fixed finding that was already listed there with "Fixed by ui-polish on {branch}, {date}."
Design Critique Format
Give structured feedback, not loose opinions:
- "I notice..." — observation
- "I wonder..." — question
- "What if..." — suggestion
- "I think... because..." — reasoned opinion
Tie every note back to a user goal. Always pair a problem with a specific improvement.
Design Hard Rules
Classifier — pick the rule set before evaluating:
- MARKETING/LANDING PAGE (hero-driven, brand-forward, conversion-focused) -> apply Landing Page Rules
- APP UI (workspace-driven, data-dense, task-focused: dashboards, admin, settings) -> apply App UI Rules
- HYBRID (marketing shell wrapped around app-like sections) -> Landing rules for the hero/marketing, App rules for the functional sections
Hard rejection criteria (instant-fail patterns — flag if ANY apply):
- Generic SaaS card grid as the first impression
- Beautiful image with a weak brand
- Strong headline with no clear action
- Busy imagery behind text
- Sections repeating the same mood statement
- Carousel with no narrative purpose
- App UI built from stacked cards instead of a real layout
Litmus checks (YES/NO for each):
- Brand/product unmistakable in the first screen?
- One strong visual anchor present?
- Page understandable by scanning headlines alone?
- Each section has exactly one job?
- Are the cards actually necessary?
- Does motion improve hierarchy or atmosphere?
- Would the design still feel premium with every decorative shadow removed?
Landing page rules:
- First viewport reads as one composition, not a dashboard
- Brand-first hierarchy: brand > headline > body > CTA
- Expressive, purposeful typography — no default stacks (Inter, Roboto, Arial, system)
- No flat single-color backgrounds — use gradients, images, subtle patterns
- Hero: full-bleed, edge-to-edge, no inset/tiled/rounded variants
- Hero budget: brand, one headline, one supporting sentence, one CTA group, one image
- No cards in the hero. Cards only when the card IS the interaction
- One job per section
- Motion: at least 2-3 intentional motions (entrance, scroll-linked, hover/reveal)
- CSS variables for the color system, avoid purple-on-white defaults, one accent color by default
- Product language, not design commentary. "If deleting 30% improves it, keep deleting."
App UI rules:
- Calm surface hierarchy, strong typography, few colors
- Dense but readable, minimal chrome
- Organize: primary workspace, navigation, secondary context, one accent
- Avoid: dashboard-card mosaics, thick borders, decorative gradients, ornamental icons
- Utility language — orientation, status, action. Not mood/brand/aspiration
- Cards only when the card IS the interaction
- Section headings state what the area is or what the user can do ("Selected KPIs", "Plan status")
Universal rules (all types):
- Define CSS variables for the color system
- No default font stacks (Inter, Roboto, Arial, system)
- One job per section
- "If deleting 30% of the copy improves it, keep deleting"
- Cards earn their existence — no decorative card grids
- NEVER small, low-contrast type (body text < 16px or contrast ratio < 4.5:1)
- NEVER use placeholder-as-label (labels must stay visible once the field has content)
- ALWAYS preserve the visited vs unvisited link distinction
- NEVER float headings between paragraphs (a heading must sit visually closer to the section it introduces)
Important Rules
- Judge like a designer, not a QA tester. What matters is whether things feel right, look deliberate, and respect the user.
- Screenshots are evidence. Every finding needs at least one. Use annotated snapshots to highlight elements. When
$Bis unavailable, citefile:linesource references instead. - Be specific and actionable. "Change
text-smtotext-baseon line 42 because body text must be >= 16px" — not "the text feels small." - AI Slop detection is your edge. Most developers can't tell whether their own site looks AI-generated. You can. Say it plainly.
- Quick Wins matter. Always surface the 3-5 highest-impact fixes that take under 30 minutes.
- CSS-first. Prefer Tailwind class changes — safer and more reversible than structural ones.
- One commit per fix. Never bundle.
- Responsive is design, not just "not broken." A stacked desktop layout on mobile is lazy, not responsive.
- Depth over breadth. 5-10 well-documented findings beat 20 vague observations.
- Document incrementally. Write each finding to the report as you find it. Don't batch.
- Show screenshots to the user. After every
$B screenshot,$B snapshot -a -o, or$B responsive, use the Read tool on the output file(s) so the user sees them inline. - Clean working tree required. If dirty, offer commit/stash/abort before proceeding.
- Revert on regression. If a fix makes things worse,
git revert HEADimmediately. - Self-regulate. Follow the risk heuristic. When in doubt, stop and ask.
- Always produce a report. Even when nothing is found. Lead the Summary section with a PR-ready one-liner.
- Inline by default; the interactive spine never leaves the main loop. The whole audit-fix-verify loop runs inline unless the user explicitly opts into parallelism. Even then, only the Phase 7 adversarial diagnosis may fan out to a Workflow — never put a gate, ceremony, per-finding STOP, screenshot, commit, or file write inside a Workflow
agent(), because background agents can't talk to the user or write files.
Next Steps — Review Chaining
After the audit and fixes, point to the next step:
- /pre-merge-review — run as a separate step for a pre-landing structural gate when the fixes touched component logic or shared layout (report-only by default; it's a sibling skill, not a subagent spawn).
- /qa or /qa-fix — verify the user-facing changes end-to-end before shipping.
- /ship — when the fixes are committed and the user wants to ship or open a PR.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

