Skip to content
component-aesthetic-checker logo

Component Aesthetic Checker SKILL

component-aesthetic-checker

Validates shadcn/ui component customization depth, ensuring components aren't used with default props and checking for consistent design system implementation across Tanstack Start applications

SKILL.md

Full skill instructions

Component Aesthetic Checker SKILL

Activation Patterns

This SKILL automatically activates when:

  • shadcn/​ui components (Button, Card, Input, etc.) are used in .react files
  • Component props are added or modified
  • The ui prop is customized for component variants
  • Design system tokens are referenced in components
  • Multiple components are refactored together
  • Before component library updates

Expertise Provided

Component Customization Depth Analysis

  • Default Prop Detection: Identifies components using only default values
  • UI Prop Validation: Ensures ui prop is used for deep customization
  • Design System Consistency: Validates consistent pattern usage across components
  • Spacing Patterns: Checks for proper Tailwind spacing scale usage
  • Icon Usage: Validates consistent icon library and sizing
  • Loading States: Ensures async components have loading feedback

Specific Checks Performed

❌ Critical Issues (Insufficient Customization)
<!-- These patterns trigger alerts: -->

<!-- Using default props only -->
<Button onClick="submit">Submit</​Button>

<!-- No UI prop customization -->
<Card>
  <p>Content</​p>
</​Card>

<!-- Inconsistent spacing -->
<div className="p-4">  <!-- Random spacing values -->
  <Button className="mt-3 ml-2">Action</​Button>
</​div>

<!-- Missing loading states -->
<Button onClick="asyncAction">Save</​Button>  <!-- No :loading prop -->
✅ Correct Customized Patterns
<!-- These patterns are validated as correct: -->

<!-- Deep customization with ui prop -->
<Button
  color="brand-coral"
  size="lg"
  variant="solid"
  :ui="{
    font: 'font-heading',
    rounded: 'rounded-full',
    padding: { lg: 'px-8 py-4' }
  }"
  loading={isSubmitting"
  className="transition-all duration-300 hover:scale-105"
  onClick="submit"
>
  Submit
</​Button>

<!-- Fully customized card -->
<Card
  :ui="{
    background: 'bg-white dark:bg-brand-midnight',
    ring: 'ring-1 ring-brand-coral/​20',
    rounded: 'rounded-2xl',
    shadow: 'shadow-xl',
    body: { padding: 'p-8' },
    header: { padding: 'px-8 pt-8 pb-4' }
  }"
  className="transition-shadow duration-300 hover:shadow-2xl"
>
  <template #header>
    <h3 className="font-heading text-2xl">Title</​h3>
  <p className="text-gray-700 dark:text-gray-300">Content</​p>
</​Card>

<!-- Consistent spacing (Tailwind scale) -->
<div className="p-6 space-y-4">
  <Button className="mt-4">Action</​Button>
</​div>

<!-- Proper loading state -->
<Button
  loading={isSubmitting"
  disabled={isSubmitting"
  onClick="asyncAction"
>
  { isSubmitting ? 'Saving...' : 'Save'}
</​Button>

Integration Points

Complementary to Existing Components

  • tanstack-ui-architect agent: Handles component selection and API guidance, SKILL validates implementation
  • frontend-design-specialist agent: Provides design direction, SKILL enforces consistency
  • shadcn-ui-design-validator: Catches generic patterns, SKILL ensures deep customization

Escalation Triggers

  • Component API questions → tanstack-ui-architect agent (with MCP lookup)
  • Design consistency issues → frontend-design-specialist agent
  • Complex component composition → /​es-component command
  • Full component audit → /​es-design-review command

Validation Rules

P1 - Critical (Default Component Usage)

  • No UI Prop Customization: Using shadcn/​ui components without ui prop
  • All Default Props: No color, size, variant, or other prop customizations
  • Missing Loading States: Async actions without :loading prop
  • No Hover States: Interactive components without hover feedback
  • Inconsistent Patterns: Same component with wildly different customizations

P1 - Critical (Distributional Convergence Anti-Patterns)

These patterns indicate generic "AI-generated" aesthetics and MUST be flagged:

Font Anti-Patterns (Auto-Detect)
// ❌ CRITICAL: Generic fonts that dominate 80%+ of websites
fontFamily: {
  sans: ['Inter', ...]        // Flag: "Inter is overused - consider Space Grotesk, Plus Jakarta Sans"
  sans: ['Roboto', ...]       // Flag: "Roboto is overused - consider IBM Plex Sans, Outfit"
  sans: ['Open Sans', ...]    // Flag: "Open Sans is generic - consider Satoshi, General Sans"
  sans: ['system-ui', ...]    // Flag: Only acceptable as fallback, not primary
}

// ❌ CRITICAL: Default Tailwind font classes without customization
className="font-sans"         // Flag if font-sans maps to Inter/​Roboto
className="text-base"         // Flag: Generic sizing, consider custom scale

Recommended Font Alternatives (suggest these in reports):

  • Body: Space Grotesk, Plus Jakarta Sans, IBM Plex Sans, Outfit, Satoshi
  • Headings: Archivo Black, Cabinet Grotesk, Clash Display, General Sans
  • Mono: JetBrains Mono, Fira Code, Source Code Pro
Color Anti-Patterns (Auto-Detect)
// ❌ CRITICAL: Purple gradients (most common AI aesthetic)
className="bg-gradient-to-r from-purple-500 to-purple-600"
className="bg-gradient-to-r from-violet-500 to-purple-500"
className="bg-purple-600"
className="text-purple-500"

// ❌ CRITICAL: Default gray backgrounds without brand treatment
className="bg-gray-50"        // Flag: "Consider brand-tinted background"
className="bg-white"          // Flag: "Consider atmospheric gradient or texture"
className="bg-slate-100"      // Flag if used extensively without brand colors

Recommended Color Approaches (suggest these in reports):

  • Use CSS variables with brand palette (--brand-primary, --brand-accent)
  • Tint grays with brand color: bg-brand-gray-50 instead of bg-gray-50
  • Gradients: Use brand colors, not default purple
  • Atmospheric: Layer gradients with subtle brand tints
Animation Anti-Patterns (Auto-Detect)
// ❌ CRITICAL: No transitions on interactive elements
<Button>Click</​Button>        // Flag: "Add transition-all duration-300"
<Card>Content</​Card>          // Flag: "Add hover:shadow-lg transition"

// ❌ CRITICAL: Only basic hover without micro-interactions
className="hover:bg-blue-600" // Flag: "Consider hover:scale-105 or hover:-translate-y-1"

Detection Rules (implement in validation):

// Font detection
const OVERUSED_FONTS = ['Inter', 'Roboto', 'Open Sans', 'Helvetica', 'Arial'];
const hasBadFont = (config) => OVERUSED_FONTS.some(f =>
  config.fontFamily?.sans?.includes(f)
);

// Purple gradient detection
const PURPLE_PATTERN = /(?:purple|violet)-[4-6]00/;
const hasPurpleGradient = (className) =>
  className.includes('gradient') && PURPLE_PATTERN.test(className);

// Missing animation detection
const INTERACTIVE_COMPONENTS = ['Button', 'Card', 'Link', 'Input'];
const hasNoTransition = (className) =>
  !className.includes('transition') && !className.includes('animate');

P2 - Important (Design System Consistency)

  • Random Spacing Values: Not using Tailwind spacing scale (p-4, mt-6, etc.)
  • Inconsistent Icon Sizing: Icons with different sizes in similar contexts
  • Mixed Color Approaches: Some components use theme colors, others use arbitrary values
  • Incomplete Dark Mode: Dark mode variants missing on customized components
  • No Focus States: Interactive elements without focus-visible styling

P3 - Polish (Enhanced UX)

  • Limited Prop Usage: Only using 1-2 props when more would improve UX
  • No Micro-interactions: Missing subtle animations on state changes
  • Generic Variants: Using 'solid', 'outline' without brand customization
  • Underutilized UI Prop: Not customizing padding, rounded, shadow in ui prop
  • Missing Icons: Buttons/​actions without supporting icons for clarity

Remediation Examples

Fixing Default Component Usage

<!-- ❌ Critical: Default props only -->
  <Button onClick="handleClick">
    Click me
  </​Button>

<!-- ✅ Correct: Deep customization -->
  <Button
    color="primary"
    size="lg"
    variant="solid"
    icon="i-heroicons-sparkles"
    :ui="{
      font: 'font-heading tracking-wide',
      rounded: 'rounded-full',
      padding: { lg: 'px-8 py-4' },
      shadow: 'shadow-lg hover:shadow-xl'
    }"
    className="transition-all duration-300 hover:scale-105 active:scale-95"
    onClick="handleClick"
  >
    Click me
  </​Button>

Fixing Missing Loading States

<!-- ❌ Critical: No loading feedback -->
const handleSubmit = async () => {
  await submitForm();
};

  <Button onClick="handleSubmit">
    Submit Form
  </​Button>

<!-- ✅ Correct: Proper loading state -->
const isSubmitting = ref(false);

const handleSubmit = async () => {
  isSubmitting.value = true;
  try {
    await submitForm();
  } finally {
    isSubmitting.value = false;
  }
};

  <Button
    loading={isSubmitting"
    disabled={isSubmitting"
    onClick="handleSubmit"
  >
    <span className="flex items-center gap-2">
      <Icon
        {&& "!isSubmitting"
        name="i-heroicons-paper-airplane"
      />
      { isSubmitting ? 'Submitting...' : 'Submit Form'}
    </​span>
  </​Button>

Fixing Inconsistent Spacing

<!-- ❌ P2: Random spacing values -->
  <div className="p-3">
    <Card className="mt-5 ml-7">
      <div className="p-2">
        <Button className="mt-3.5">Action</​Button>
      </​div>
    </​Card>
  </​div>

<!-- ✅ Correct: Tailwind spacing scale -->
  <div className="p-4">
    <Card className="mt-4">
      <div className="p-6 space-y-4">
        <Button>Action</​Button>
      </​div>
    </​Card>
  </​div>

<!-- Using consistent spacing: 4, 6, 8, 12, 16 (Tailwind scale) -->

Fixing Design System Inconsistency

<!-- ❌ P2: Inconsistent component styling -->
  <div>
    <!-- Button 1: Heavily customized -->
    <Button
      color="primary"
      :ui="{ rounded: 'rounded-full', shadow: 'shadow-xl' }"
    >
      Action 1
    </​Button>

    <!-- Button 2: Default (inconsistent!) -->
    <Button>Action 2</​Button>

    <!-- Button 3: Different customization pattern -->
    <Button color="red" size="xs">
      Action 3
    </​Button>
  </​div>

<!-- ✅ Correct: Consistent design system -->
// Define reusable button variants
const buttonVariants = {
  primary: {
    color: 'primary',
    size: 'lg',
    ui: {
      rounded: 'rounded-full',
      shadow: 'shadow-lg hover:shadow-xl',
      font: 'font-heading'
    },
    class: 'transition-all duration-300 hover:scale-105'
  },
  secondary: {
    color: 'gray',
    size: 'md',
    variant: 'outline',
    ui: {
      rounded: 'rounded-lg',
      font: 'font-sans'
    },
    class: 'transition-colors duration-200'
  }
};

  <div className="space-x-4">
    <Button v-bind="buttonVariants.primary">
      Action 1
    </​Button>

    <Button v-bind="buttonVariants.primary">
      Action 2
    </​Button>

    <Button v-bind="buttonVariants.secondary">
      Action 3
    </​Button>
  </​div>

Fixing Underutilized UI Prop

<!-- ❌ P3: Not using ui prop for customization -->
  <Card className="rounded-2xl shadow-xl p-8">
    <p>Content</​p>
  </​Card>

<!-- ✅ Correct: Proper ui prop usage -->
  <Card
    :ui="{
      rounded: 'rounded-2xl',
      shadow: 'shadow-xl hover:shadow-2xl',
      body: {
        padding: 'p-8',
        background: 'bg-white dark:bg-brand-midnight'
      },
      ring: 'ring-1 ring-brand-coral/​20'
    }"
    className="transition-shadow duration-300"
  >
    <p className="text-gray-700 dark:text-gray-300">Content</​p>
  </​Card>

MCP Server Integration

When shadcn/​ui MCP server is available:

Component Prop Validation

// Before validating customization depth, get actual component API
const componentDocs = await mcp.shadcn.get_component("Button");

// Validate that used props exist
// componentDocs.props: ['color', 'size', 'variant', 'icon', 'loading', 'disabled', ...]

// Check for underutilized props
const usedProps = ['color', 'size']; // From component code
const availableProps = componentDocs.props;
const unutilizedProps = availableProps.filter(p => !usedProps.includes(p));

// Suggest: "Consider using 'icon' or 'loading' props for richer UX"

UI Prop Structure Validation

// Validate ui prop structure against schema
const uiSchema = componentDocs.ui_schema;

// User code: :ui="{ font: 'font-heading', rounded: 'rounded-full' }"
// Validate: Are 'font' and 'rounded' valid keys in ui prop?
// Suggest: Other available ui customizations (padding, shadow, etc.)

Consistency Across Components

// Check multiple component instances
const buttonInstances = findAllComponents("Button");

// Analyze customization patterns
// Flag: Component used with 5 different customization styles
// Suggest: Create composable or variant system for consistency

Benefits

Immediate Impact

  • Prevents Generic Appearance: Ensures components are branded, not defaults
  • Enforces Design Consistency: Catches pattern drift across components
  • Improves User Feedback: Validates loading states and interactions
  • Educates on Component API: Shows developers full customization capabilities

Long-term Value

  • Consistent Component Library: All components follow design system
  • Faster Component Development: Clear patterns and examples
  • Better Code Maintainability: Reusable component variants
  • Reduced Visual Debt: Prevents accumulation of one-off styles

Usage Examples

During Component Usage

// Developer adds: <Button>Click me</​Button>
// SKILL immediately activates: "⚠️ P1: Button using all default props. Customize with color, size, variant, and ui prop for brand distinctiveness."

During Async Actions

// Developer creates async button: <Button onClick="submitForm">Submit</​Button>
// SKILL immediately activates: "⚠️ P1: Button triggers async action but lacks :loading prop. Add loading state for user feedback."

During Refactoring

// Developer adds 5th different button style
// SKILL immediately activates: "⚠️ P2: Button used with 5 different customization patterns. Consider creating reusable variants for consistency."

Before Deployment

// SKILL runs comprehensive check: "✅ Component aesthetic validation passed. 23 components with deep customization, consistent patterns, and proper loading states detected."

Design System Maturity Levels

Level 0: Defaults Only (Avoid)

<Button>Action</​Button>
<Card><p>Content</​p></​Card>
<Input value="value" />

Issues: Generic appearance, no brand identity, inconsistent with custom design

Level 1: Basic Props (Minimum)

<Button color="primary" size="lg">Action</​Button>
<Card className="shadow-lg"><p>Content</​p></​Card>
<Input value="value" placeholder="Enter value" />

Better: Some customization, but limited depth

Level 2: UI Prop + Classes (Target)

<Button
  color="primary"
  size="lg"
  :ui="{ rounded: 'rounded-full', font: 'font-heading' }"
  className="transition-all duration-300 hover:scale-105"
>
  Action
</​Button>

<Card
  :ui="{
    background: 'bg-white dark:bg-brand-midnight',
    ring: 'ring-1 ring-brand-coral/​20',
    shadow: 'shadow-xl'
  }"
>
  <p>Content</​p>
</​Card>

Ideal: Deep customization, brand-distinctive, consistent patterns

Level 3: Design System (Advanced)

<!-- Reusable variants from composables -->
<Button v-bind="designSystem.button.variants.primary">
  Action
</​Button>

<Card v-bind="designSystem.card.variants.elevated">
  <p>Content</​p>
</​Card>

Advanced: Centralized design system, maximum consistency

Component Customization Checklist

For each shadcn/​ui component, validate:

  • Props: Uses at least 2-3 props (color, size, variant, etc.)
  • UI Prop: Includes ui prop for deep customization (rounded, font, padding, shadow)
  • Classes: Adds Tailwind utilities for animations and effects
  • Loading State: Async actions have :loading and :disabled props
  • Icons: Includes relevant icons for clarity (:icon prop or slot)
  • Hover State: Interactive elements have hover feedback
  • Focus State: Keyboard navigation has visible focus styles
  • Dark Mode: Includes dark mode variants in ui prop
  • Spacing: Uses Tailwind spacing scale (4, 6, 8, 12, 16)
  • Consistency: Follows same patterns as other instances

This SKILL ensures every shadcn/​ui component is deeply customized, consistently styled, and provides excellent user feedback, preventing the default/​generic appearance that makes AI-generated UIs immediately recognizable.

More Design skills

brandkit logo
Design

brandkit

Premium brand-kit image generation for high-end identity systems, logo concepts, and visual-world presentations.

92.7K 345.8K
View

Premium website design-to-code skill that generates visual references first, then builds faithful frontend implementations.

92.7K 341.7K
View

Premium frontend image direction for landing pages and marketing sites, generating one distinct horizontal image per section.

92.7K 337.8K
View

Premium mobile app screen concepts and flows with clean hierarchy, strong imagery, and distinctive art direction.

92.7K 331.8K
View

Emil Kowalski's philosophy on UI polish, component design, and the invisible details that make software feel good.

43.5K 323.4K
View

Frontend design and iteration for production-grade interfaces, from concept to ship.

76.8K 313.3K
View

Reverse-engineer design tokens from public websites into starter token files for your project.

232 129.9K
View
Animate logo
Design

Animate

Builds an animation from scratch by making the decisions in the order that determines whether it feels right.

43.5K 117.9K
View

Create beautiful visual art in .png and .pdf documents using design philosophy. You should use this skill when the user asks to create a poster, piece of art, design, or other static piece. Create original visual designs, never copying existing artists' work to avoid copyright violations.

179.7K 114.2K
View

Applies Anthropic's official brand colors and typography to any sort of artifact that may benefit from having Anthropic's look-and-feel. Use it when brand colors or style guidelines, visual formatting, or company design standards apply.

179.7K 100.1K
View

Toolkit for styling artifacts with a theme. These artifacts can be slides, docs, reportings, HTML landing pages, etc. There are 10 pre-set themes with colors/fonts that you can apply to any artifact that has been creating, or can generate a new theme on-the-fly.

179.7K 89.5K
View

Design AI tools

Maze Guru logo
Images

Maze Guru

Chat-to-edit AI studio for product photos, portraits, branding, and video.

Freemium
View
R
Design

RoomGPT

Generate your dream room in seconds.

Paid
View

Redesign your interior in seconds using AI

Paid
View
Reroom logo
Design

Reroom

Transform rooms with AI-generated designs.

Freemium
View
Jife logo
Design

Jife

Transform Your Space with AI-Powered Japanese Interior Designs by Jife

Paid
View
Visily logo
Design

Visily

AI-powered wireframes for non-designers.

Free
View

Revolutionize Property Viewing with AI-Generated Floor Plans and Virtual Tours

Paid
View
Archsynth logo
Design

Archsynth

Transform sketches into stunning architectural renders with AI.

Paid
View