From ui-designer
Review a UI implementation against design system conventions, accessibility, consistency, responsiveness, dark mode, and component patterns.
npx claudepluginhub hpsgd/turtlestack --plugin ui-designerThis skill is limited to using the following tools:
Review $ARGUMENTS against design system conventions.
Provides UI/UX resources: 50+ styles, color palettes, font pairings, guidelines, charts for web/mobile across React, Next.js, Vue, Svelte, Tailwind, React Native, Flutter. Aids planning, building, reviewing interfaces.
Fetches up-to-date documentation from Context7 for libraries and frameworks like React, Next.js, Prisma. Use for setup questions, API references, and code examples.
Calculates TAM/SAM/SOM using top-down, bottom-up, and value theory methodologies for market sizing, revenue estimation, and startup validation.
Review $ARGUMENTS against design system conventions.
This review checks implementation quality across six dimensions. Read all target files before starting. Search for the project's design system primitives and Tailwind config to understand what is available.
Before reviewing, gather context:
tailwind.config.js / tailwind.config.ts to understand the theme (colours, spacing, breakpoints, fonts)components/ui/, components/shared/, or similar directoriesglobals.css, variables.css, etc.)Search for these violations:
# Hardcoded hex colours (should use theme tokens)
grep -rn '#[0-9a-fA-F]\{3,8\}' --include="*.tsx" --include="*.jsx" --include="*.css"
# Hardcoded rgb/hsl values
grep -rn 'rgb(\|rgba(\|hsl(' --include="*.tsx" --include="*.jsx" --include="*.css"
# Arbitrary Tailwind colour values
grep -rn '\[#' --include="*.tsx" --include="*.jsx"
Rule: All colours must come from the theme. Hardcoded values break dark mode, theming, and consistency. The only exception is SVG paths that require specific fill values.
# Custom font sizes outside the scale
grep -rn 'fontSize:\|font-size:' --include="*.tsx" --include="*.jsx" --include="*.css" | grep -v 'text-xs\|text-sm\|text-base\|text-lg\|text-xl\|text-2xl\|text-3xl'
# Arbitrary text size values in Tailwind
grep -rn 'text-\[' --include="*.tsx" --include="*.jsx"
Rule: Use the type scale. Custom font sizes create visual inconsistency and make future scale changes painful.
# Arbitrary spacing values
grep -rn 'p-\[\|m-\[\|gap-\[\|space-\[' --include="*.tsx" --include="*.jsx"
# Inline style spacing
grep -rn 'padding:\|margin:' --include="*.tsx" --include="*.jsx" | grep -v '.css\|.module'
Rule: Use the spacing scale (4px increments in Tailwind). Arbitrary values like py-[72px] or mt-[13px] indicate a spacing system violation. If the design requires non-standard spacing, the design should be questioned, not worked around with arbitrary values.
# Arbitrary border radius
grep -rn 'rounded-\[' --include="*.tsx" --include="*.jsx"
Rule: Use the border radius scale. Consistent rounding is one of the most visible aspects of design system coherence.
Search for patterns that reinvent existing primitives:
# Custom button implementations (should use Button component)
grep -rn '<button' --include="*.tsx" --include="*.jsx" | grep -v 'Button\|button type="submit"'
# Custom link implementations (should use Link from next/link or router)
grep -rn '<a ' --include="*.tsx" --include="*.jsx" | grep -v 'Link\|anchor'
# Custom input implementations
grep -rn '<input' --include="*.tsx" --include="*.jsx" | grep -v 'Input\|Field'
Rule: Use the design system's component primitives. Custom <button> elements bypass shared styling, accessibility features, and loading states.
Check that components follow established conventions:
variant for visual/semantic differences (not type, style, kind)size for size variations (not large, isSmall)className accepted for style overrides (using clsx or cn for merging)as or asChild for polymorphic rendering (not component, tag)on (not handle)# String concatenation for classes (should use clsx/cn)
grep -rn 'className={.*+\|className={.*`' --include="*.tsx" --include="*.jsx" | grep -v 'clsx\|cn('
# Ternary in className without clsx
grep -rn 'className={.*?' --include="*.tsx" --include="*.jsx" | grep -v 'clsx\|cn('
Rule: Use clsx or cn for conditional class composition. Template literals and string concatenation produce unreadable class strings and do not handle undefined/false values cleanly.
# dark:hidden / dark:block pattern (should use ThemeImage)
grep -rn 'dark:hidden\|dark:block' --include="*.tsx" --include="*.jsx"
# Checking for images without ThemeImage
grep -rn '<img\|<Image' --include="*.tsx" --include="*.jsx" | grep -v 'ThemeImage'
Rule: Use ThemeImage for images that need dark mode variants. The dark:hidden / dark:block pattern duplicates DOM elements and increases payload.
Check that the implementation handles all required states:
hover: classes present on interactive elementsfocus: or focus-visible: classes present — MUST be visibleactive: class for press feedbackdisabled: classes AND aria-disabled or disabled attribute# Interactive elements without hover states
grep -rn 'onClick' --include="*.tsx" --include="*.jsx" -l | xargs grep -L 'hover:'
# Interactive elements without focus states
grep -rn 'onClick' --include="*.tsx" --include="*.jsx" -l | xargs grep -L 'focus:\|focus-visible:'
# Components using fetch/query without loading state
grep -rn 'useQuery\|useSWR\|fetch(' --include="*.tsx" --include="*.jsx" -l | xargs grep -L 'loading\|isLoading\|skeleton\|Skeleton'
# Components without error handling
grep -rn 'useQuery\|useSWR' --include="*.tsx" --include="*.jsx" -l | xargs grep -L 'error\|isError\|Error'
tabIndex={0} and keyboard handlerstabIndex values (breaks natural flow)alt text on imagesaria-label on icon-only buttonssr-only text for visual-only information# Find potential contrast issues: light grey text on white
grep -rn 'text-gray-300\|text-gray-400\|text-slate-300\|text-slate-400' --include="*.tsx" --include="*.jsx"
# Icon-only buttons without labels
grep -rn '<button\|<Button' --include="*.tsx" --include="*.jsx" | grep 'Icon\|icon' | grep -v 'aria-label\|sr-only\|title'
Verify the component has responsive styles:
# Check for responsive breakpoint usage
grep -rn 'sm:\|md:\|lg:\|xl:' --include="*.tsx" --include="*.jsx" [target]
Rule: Every layout component must have at least mobile and desktop styles. Components that only have desktop styles are incomplete.
w-[400px]) that overflow on mobile — use max-w- or responsive widthsflex-col sm:flex-row# Fixed widths that may overflow
grep -rn 'w-\[.*px\]\|width:.*px' --include="*.tsx" --include="*.jsx" | grep -v 'max-w\|min-w'
forwardRef if it wraps a native elementclassName for customisationnext/image with proper dimensionsReact.lazy or dynamic imports# Object literals in JSX (cause re-renders)
grep -rn 'style={{' --include="*.tsx" --include="*.jsx"
# Array literals in JSX props
grep -rn '={\[\]}\|={(\[' --include="*.tsx" --include="*.jsx"
Present findings in three severity levels:
# Design Review: [Target]
**Reviewed:** [files/components reviewed]
**Design system:** [name/location of the design system referenced]
## Blockers (must fix before merge)
Issues that break accessibility, design system compliance, or user experience.
### [Issue title]
- **File:** `[path:line]`
- **Issue:** [What is wrong]
- **Fix:** [Specific change to make]
## Suggestions (should fix, not blocking)
Issues that reduce quality but are not critical.
### [Issue title]
- **File:** `[path:line]`
- **Issue:** [What is wrong]
- **Fix:** [Specific change to make]
## Nits (minor, fix if touching this code)
Style preferences, minor inconsistencies, optimisations.
### [Issue title]
- **File:** `[path:line]`
- **Issue:** [What is wrong]
- **Fix:** [Specific change to make]
## Summary
- Blockers: N
- Suggestions: N
- Nits: N
- **Verdict:** [Approve / Approve with changes / Request changes]
Verdict criteria:
/ui-designer:component-spec — review the design against the component spec to catch deviations./ui-designer:accessibility-audit — run an accessibility audit alongside the design review for UI changes.