ss-review logo

ss-review

Review UI code for design system compliance, accessibility, and best practices

SKILL.md

Full skill instructions

UI Design Review

Registry-first artifact boundary

When .styleseed/project.json and .styleseed/artifacts/index.json exist, resolve the requested artifact ID first, then read only .styleseed/bundles/<artifact-id>.md and .styleseed/manifests/<artifact-id>.json. Never fall back to the global legacy bundle for a registry project. Legacy projects may use .styleseed/effective-rules.md only when no registry exists.

Read .styleseed/effective-rules.md and .styleseed/manifest.json. If missing or stale, invoke /ss-resolve or $ss-resolve from STYLESEED.md first. Review task fitness and grammar coherence before framework conventions. For non-web artifacts, replace React/Tailwind-only checks with the active adapter's render/export checks.

When NOT to use

  • For accessibility-only issues → use /ss-a11y
  • For Nielsen UX heuristics → use /ss-audit
  • For a quick automated check → use /ss-lint
  • For non-UI code (data fetching, business rules)

Review the file: $ARGUMENTS

Checklist

1. Design Token and Recipe Compliance

  • No hardcoded hex colors (use semantic tokens: text-foreground, bg-brand, etc.)
  • No hardcoded px spacing in Tailwind (use p-6 not p-[24px])
  • Pattern geometry/elevation uses the selected recipe or explicit semantic variables
  • No hardcoded universal rounded-2xl + shadow + mx-6 language across unrelated recipes

2. Component Conventions

  • Uses data-slot attribute
  • Uses cn() for className merging
  • Props typed with React.ComponentProps<>
  • Supports className prop override
  • Named export (not default export for components)
  • No wrapper components that only add a className

3. Accessibility (a11y)

  • Touch targets >= 44x44px for interactive elements
  • focus-visible styles on all interactive elements
  • Proper aria-* attributes where needed
  • Color contrast meets WCAG AA (4.5:1 for text, 3:1 for large text)
  • Animations respect prefers-reduced-motion
  • Images have alt text
  • Form inputs have associated labels

4. Surface Best Practices

  • No horizontal overflow
  • Touch-friendly spacing between interactive elements
  • Mobile safe area insets handled when the adapter requires them
  • Desktop density/type and non-web canvas/export rules follow the selected adapter
  • Text sizes >= 12px for readability
  • Scrollable containers have -webkit-overflow-scrolling: touch

5. Performance

  • No unnecessary re-renders (stable references, memoization where needed)
  • Images are lazy-loaded
  • Heavy components are code-split

6. Typography

  • Uses the locked type family and recipe-fit type roles
  • Font sizes from the 14-step scale (10-48px, see CLAUDE.md)
  • Proper font weights (400, 500, 600, 700)
  • Display text (36-48px): leading-none + tracking-[-0.02em]
  • Heading text (18-24px): leading-snug + tracking-[-0.01em]
  • Body text (14-17px): leading-normal (no custom tracking)
  • Caption uppercase (10-13px): tracking-[0.05em] or tracking-wide
  • No line-height: 1.5 on display/heading text (too loose)

7. Spacing Consistency

  • Spacing uses one maintained token scale and the selected recipe's major rhythm
  • Off-scale values have an optical, canvas, or platform reason
  • Uses size-* shorthand instead of w-* h-*
  • Uses ms-*/me-* instead of ml-*/mr-* (logical properties)
  • Motion transitions use design tokens (duration-[var(--duration-fast)])

8. Coherence (VISUAL-CRAFT.md §C0 — the "one choice per axis" laws)

The biggest reason a UI reads as "AI-generated" isn't ugly parts — it's mixed parts. Check that each axis below uses ONE value system-wide; flag a mix as a real issue, not a nitpick.

  • One radius personality — sharp (0-4px) OR soft (8-12px) OR pill, applied to every card/button/input/modal. No mixing (e.g. a rounded-none panel with rounded-full buttons).
  • One identifiable primary action plus only the selected grammar's stable semantic, categorical, or brand roles — no competing decorative emphasis hues.
  • No emoji as UI icons (🚗🧺⭐ as list/nav/status/category markers) — they inject many uncontrolled hues; use one line-icon set in currentColor.
  • Status color = severity, not decoration — a normal/OK/"보통" state is neutral grey (not colored); color marks only the minority of rows that need attention; same value → same color.
  • No decorative hues — favorite stars, category dots, avatars use the accent or grey, not a new color each.
  • One shadow language — same light direction, same scale/tint; not some black + some tinted, some up-lit + some down-lit.
  • One icon family / fill mode / stroke weight across the file.
  • Nested-radius law — an element inside a rounded container uses inner = outer − padding, not the same radius (which bulges).
  • Consistent control heights — buttons, inputs, selects share a height set (e.g. 40px).
  • Errors/states never rely on color alone (icon + text too).

Output Format

Provide:

  1. Score: Pass / Needs Improvement / Fail
  2. Issues: List each violation with file:line reference
  3. Fixes: Concrete code changes for each issue