agentleFS
napnap11napnap11/claude-skills/ui-polish/SKILL.md

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

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 AzureSkill

    design

    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

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
  1. Distinctive:

    No URL and on main/master: ask the user for one.

    line 79
  2. Distinctive:

    If the output is non-empty, STOP and use AskUserQuestion:

    line 91
  3. Distinctive:

    If no browser tool is found, fall back to source-code design review: read the Tailwind config, CSS variables, component source, and layout …

    line 110
  4. Very specific:

    When CDP_MODE=true: skip cookie-import prompts (the real browser already carries cookies), skip user-agent overrides, skip …

    line 118
  5. Very specific:

    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).

    line 120
  6. Distinctive:

    Don't make me think: Every page should be self-evident.

    line 137
  7. Distinctive:

    Clarity over consistency: When a small inconsistency makes something significantly clearer, take the clarity.

    line 154
  8. Distinctive:

    Run the full audit, then load the prior baseline.

    line 199
  9. Distinctive:

    Write the First Impression as a structured critique:

    line 211
  10. Very specific:

    Source-code fallback: read tailwind.config.*, the CSS variable definitions, and shared style files.

    line 258
  11. Very specific:

    After the first navigation, check whether the URL redirected to a login-like path (/login, /signin, /auth, /sso).

    line 276
  12. Distinctive:

    No blacklisted fonts (Papyrus, Comic Sans, Lobster, Impact, Jokerman)

    line 312
  13. Very specific:

    If the primary font is Inter/Roboto/Open Sans/Poppins -> flag as potentially generic

    line 313
  14. Distinctive:

    No letter-spacing on lowercase text

    line 320
  15. Distinctive:

    No color-only encoding (always add labels, icons, or patterns)

    line 326
  16. Distinctive:

    No red/green-only combinations (8% of men have red-green deficiency)

    line 331
  17. Distinctive:

    No horizontal scroll on mobile

    line 341
  18. Distinctive:

    No horizontal scroll on any viewport

    line 364
  19. Very specific:

    Only transform and opacity animated (not width, height, top, left)

    line 377
  20. Distinctive:

    No placeholder/lorem ipsum text visible in production

    line 383
  21. Distinctive:

    No visible font-swap flash (FOUT) — critical fonts preloaded

    line 413
  22. Distinctive:

    Keep a running goodwill meter (start at 70/100).

    line 437
  23. Distinctive:

    Grade computation: every category starts at A.

    line 482
  24. Very specific:

    Regression: when design-baseline.json exists or --regression is set, load the baseline and compare per-category deltas, new findings, and …

    line 501
  25. Very specific:

    Default — run this inline, no fan-out: Do one in-context adversarial pass yourself: re-read the repo source through the design-consistency …

    line 509
  26. Distinctive:

    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, …

    line 515
  27. Distinctive:

    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 …

    line 591
  28. Distinctive:

    Prefer Tailwind class changes over custom CSS.

    line 598
  29. Distinctive:

    Prefer CSS over structural/JSX changes.

    line 599
  30. Distinctive:

    Do NOT refactor surrounding code, add features, or "improve" unrelated things.

    line 600
  31. Distinctive:

    If the fix touches JS behavior (broken dropdowns, animation failures, conditional rendering, interactive state), study the existing test …

    line 631
  32. Distinctive:

    Every 5 fixes, or right after any revert, compute risk:

    line 635
  33. Distinctive:

    If risk > 20%: STOP. Show the user what's been done so far.

    line 647
  34. Distinctive:

    Hard cap: 30 fixes: Stop regardless of remaining findings.

    line 649
  35. Very specific:

    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):

    line 665
  36. Very specific:

    Baseline: write design-baseline.json next to the report for regression mode.

    line 722
  37. Very specific:

    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 …

    line 724
  38. Distinctive:

    No flat single-color backgrounds — use gradients, images, subtle patterns

    line 769
  39. Distinctive:

    No cards in the hero. Cards only when the card IS the interaction

    line 772
  40. Distinctive:

    Avoid: dashboard-card mosaics, thick borders, decorative gradients, ornamental icons

    line 782
  41. Distinctive:

    No default font stacks (Inter, Roboto, Arial, system)

    line 789
  42. Distinctive:

    NEVER small, low-contrast type (body text < 16px or contrast ratio < 4.5:1)

    line 793
  43. Distinctive:

    NEVER use placeholder-as-label (labels must stay visible once the field has content)

    line 794
  44. Distinctive:

    ALWAYS preserve the visited vs unvisited link distinction

    line 795
  45. Distinctive:

    NEVER float headings between paragraphs (a heading must sit visually closer to the section it introduces)

    line 796
  46. Very specific:

    Screenshots are evidence: Every finding needs at least one.

    line 803
  47. Distinctive:

    Quick Wins matter: Always surface the 3-5 highest-impact fixes that take under 30 minutes.

    line 806
  48. Distinctive:

    CSS-first: Prefer Tailwind class changes — safer and more reversible than structural ones.

    line 807
  49. Distinctive:

    One commit per fix: Never bundle.

    line 808
  50. Distinctive:

    Document incrementally: Write each finding to the report as you find it.

    line 811
  51. Very specific:

    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 …

    line 812
  52. Very specific:

    Clean working tree required: If dirty, offer commit/stash/abort before proceeding.

    line 813
  53. Distinctive:

    Revert on regression: If a fix makes things worse, git revert HEAD immediately.

    line 814
  54. Distinctive:

    Self-regulate: Follow the risk heuristic.

    line 815
  55. Distinctive:

    After the audit and fixes, point to the next step:

    line 821

“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.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

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:

  1. 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.
  2. 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:

ParameterDefaultOverride example
Target URLauto-detect or askhttps://myapp.com, http://localhost:3000
ScopeFull site or diff-scopedFocus on the settings page, Just the homepage
DepthStandard (5-8 pages)--quick (homepage + 2), --deep (10-15 pages)
Output dir.design-reports/Output to ~/.claude/design-reports
AuthNoneSign 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 --porcelain

If 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 prefers

UX 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

  1. 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.
  2. 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.
  3. 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)

  1. Determine the base branch by auto-detecting the repo's default branch (e.g. git symbolic-ref refs/remotes/origin/HEAD) — don't assume main; confirm only if it's ambiguous. Then git diff <base>...HEAD --name-only to list changed files
  2. Map changed files to the pages/routes/components they affect
  3. Detect a running app on common local ports (3000, 4000, 8080)
  4. 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.

  1. Navigate to the target URL
  2. Capture a full-page desktop screenshot: $B screenshot .design-reports/screenshots/first-impression.png
  3. 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 perf

Lay 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 perf

Auth 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:

  1. What site is this?
  2. What page am I on?
  3. What are the major sections?
  4. What are my options at this level?
  5. Where am I in the overall scheme?
  6. 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: balance or text-pretty on headings
  • Curly quotes, not straight quotes
  • Ellipsis character (...) as one glyph, not three dots
  • font-variant-numeric: tabular-nums on 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: dark on 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-visible ring present (never outline: none without 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: pointer on 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=no or maximum-scale=1 in 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-motion respected
  • No transition: all — properties listed explicitly
  • Only transform and opacity animated (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?

  1. Purple/violet/indigo gradient backgrounds or blue-to-purple color schemes
  2. The 3-column feature grid: icon-in-colored-circle + bold title + 2-line description, repeated 3x symmetrically. THE most recognizable AI layout.
  3. Icons in colored circles as section decoration (SaaS starter-template look)
  4. Centered everything (text-align: center on all headings, descriptions, cards)
  5. Uniform bubbly border-radius on every element
  6. Decorative blobs, floating circles, wavy SVG dividers (if a section feels empty, it needs better content, not decoration)
  7. Emoji as design elements (rockets in headings, emoji as bullet points)
  8. Colored left-border on cards (border-left: 3px solid <accent>)
  9. Generic hero copy ("Welcome to [X]", "Unlock the power of...", "Your all-in-one solution for...")
  10. 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 -D

Evaluate:

  • 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:

CategoryWeight
Visual Hierarchy15%
Typography15%
Spacing & Layout15%
Color & Contrast10%
Interaction States10%
Responsive10%
Content Quality10%
AI Slop5%
Motion5%
Performance Feel5%

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 -D

Capture 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:

  1. Re-run the audit on every affected page
  2. Recompute the Design Score and AI Slop Score
  3. 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):

  1. Generic SaaS card grid as the first impression
  2. Beautiful image with a weak brand
  3. Strong headline with no clear action
  4. Busy imagery behind text
  5. Sections repeating the same mood statement
  6. Carousel with no narrative purpose
  7. App UI built from stacked cards instead of a real layout

Litmus checks (YES/NO for each):

  1. Brand/product unmistakable in the first screen?
  2. One strong visual anchor present?
  3. Page understandable by scanning headlines alone?
  4. Each section has exactly one job?
  5. Are the cards actually necessary?
  6. Does motion improve hierarchy or atmosphere?
  7. 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

  1. Judge like a designer, not a QA tester. What matters is whether things feel right, look deliberate, and respect the user.
  2. Screenshots are evidence. Every finding needs at least one. Use annotated snapshots to highlight elements. When $B is unavailable, cite file:line source references instead.
  3. Be specific and actionable. "Change text-sm to text-base on line 42 because body text must be >= 16px" — not "the text feels small."
  4. AI Slop detection is your edge. Most developers can't tell whether their own site looks AI-generated. You can. Say it plainly.
  5. Quick Wins matter. Always surface the 3-5 highest-impact fixes that take under 30 minutes.
  6. CSS-first. Prefer Tailwind class changes — safer and more reversible than structural ones.
  7. One commit per fix. Never bundle.
  8. Responsive is design, not just "not broken." A stacked desktop layout on mobile is lazy, not responsive.
  9. Depth over breadth. 5-10 well-documented findings beat 20 vague observations.
  10. Document incrementally. Write each finding to the report as you find it. Don't batch.
  11. 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.
  12. Clean working tree required. If dirty, offer commit/stash/abort before proceeding.
  13. Revert on regression. If a fix makes things worse, git revert HEAD immediately.
  14. Self-regulate. Follow the risk heuristic. When in doubt, stop and ask.
  15. Always produce a report. Even when nothing is found. Lead the Summary section with a PR-ready one-liner.
  16. 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.

Download now (ZIP)

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
What did you use it for? e.g. Reviewing pull requests in a Rails app

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.