Smithery Logo
MCPsSkillsDocsPricing
Login
Smithery Logo

Accelerating the Agent Economy

Resources

DocumentationPrivacy PolicySystem Status

Company

PricingAboutBlog

Connect

© 2026 Smithery. All rights reserved.

    alinaqi

    ui-web

    alinaqi/ui-web
    Design
    467

    About

    SKILL.md

    Install

    Install via Skills CLI

    or add to your agent
    • Claude Code
      Claude Code
    • Codex
      Codex
    • OpenClaw
      OpenClaw
    • Cursor
      Cursor
    • Amp
      Amp
    • GitHub Copilot
      GitHub Copilot
    • Gemini CLI
      Gemini CLI
    • Kilo Code
      Kilo Code
    • Junie
      Junie
    • Replit
      Replit
    • Windsurf
      Windsurf
    • Cline
      Cline
    • Continue
      Continue
    • OpenCode
      OpenCode
    • OpenHands
      OpenHands
    • Roo Code
      Roo Code
    • Augment
      Augment
    • Goose
      Goose
    • Trae
      Trae
    • Zencoder
      Zencoder
    • Antigravity
      Antigravity
    ├─
    ├─
    └─

    About

    Web UI - glassmorphism, Tailwind, dark mode, accessibility

    SKILL.md

    UI Design Skill (Web)


    MANDATORY: WCAG 2.1 AA Compliance

    These rules are NON-NEGOTIABLE. Every UI element must pass these checks.

    1. Color Contrast (CRITICAL)

    Text Contrast Requirements:
    ├── Normal text (<18px): 4.5:1 minimum
    ├── Large text (≥18px bold or ≥24px): 3:1 minimum
    ├── UI components (buttons, inputs): 3:1 minimum
    └── Focus indicators: 3:1 minimum
    
    FORBIDDEN COLOR COMBINATIONS:
    ✗ gray-400 on white (#9CA3AF on #FFFFFF = 2.6:1) - FAILS
    ✗ gray-500 on white (#6B7280 on #FFFFFF = 4.6:1) - BARELY PASSES
    ✗ white on yellow - FAILS
    ✗ light blue on white - USUALLY FAILS
    
    SAFE COLOR COMBINATIONS:
    ✓ gray-700 on white (#374151 on #FFFFFF = 9.2:1)
    ✓ gray-600 on white (#4B5563 on #FFFFFF = 6.4:1)
    ✓ gray-900 on white (#111827 on #FFFFFF = 16:1)
    ✓ white on gray-900, blue-600, green-700
    

    2. Visibility Rules (CRITICAL)

    ALL BUTTONS MUST HAVE:
    ✓ Visible background color OR visible border (min 1px)
    ✓ Text color that contrasts with background
    ✓ Minimum height: 44px (touch target)
    ✓ Padding: at least px-4 py-2
    
    NEVER CREATE:
    ✗ Buttons with transparent background AND no border
    ✗ Text same color as background
    ✗ Ghost buttons without visible borders
    ✗ White text on light backgrounds
    ✗ Dark text on dark backgrounds
    

    3. Required Element Styles

    // EVERY button needs visible boundaries
    // PRIMARY: solid background
    <button className="bg-gray-900 text-white px-4 py-3 rounded-lg">
      Primary
    </button>
    
    // SECONDARY: visible background
    <button className="bg-gray-100 text-gray-900 px-4 py-3 rounded-lg">
      Secondary
    </button>
    
    // GHOST: MUST have visible border
    <button className="border border-gray-300 text-gray-700 px-4 py-3 rounded-lg">
      Ghost
    </button>
    
    // NEVER DO THIS:
    <button className="text-gray-500">Invisible Button</button> // ✗ NO BOUNDARY
    <button className="bg-white text-white">Hidden</button>     // ✗ NO CONTRAST
    

    4. Focus States (REQUIRED)

    // EVERY interactive element needs visible focus
    className="focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2"
    
    // NEVER remove focus without replacement
    className="outline-none" // ✗ FORBIDDEN without ring replacement
    

    5. Dark Mode Contrast

    When implementing dark mode:
    ├── Text must be light (gray-100 to white) on dark backgrounds
    ├── Borders must be visible (gray-700 or lighter)
    ├── Never use gray-400 text on gray-900 bg (fails contrast)
    └── Test BOTH modes before shipping
    
    SAFE DARK MODE TEXT:
    ✓ text-white on bg-gray-900
    ✓ text-gray-100 on bg-gray-800
    ✓ text-gray-200 on bg-gray-900
    
    UNSAFE (FAILS CONTRAST):
    ✗ text-gray-500 on bg-gray-900 (2.4:1)
    ✗ text-gray-400 on bg-gray-800 (3.1:1)
    

    Core Philosophy

    Beautiful UI is not decoration - it's communication. Every visual choice should serve clarity, hierarchy, and user confidence. Default to elegance and restraint.

    Design Principles

    1. Visual Hierarchy

    Primary Action    → Bold, high contrast, prominent
    Secondary Action  → Subtle, lower contrast
    Tertiary/Links    → Minimal, text-style
    

    2. Spacing System (8px Grid)

    // Tailwind spacing scale - USE CONSISTENTLY
    const spacing = {
      xs: 'p-1',      // 4px  - tight internal
      sm: 'p-2',      // 8px  - compact
      md: 'p-4',      // 16px - default
      lg: 'p-6',      // 24px - comfortable
      xl: 'p-8',      // 32px - spacious
      '2xl': 'p-12',  // 48px - section gaps
    };
    
    // Rule: More whitespace = more premium feel
    // Rule: Consistent spacing > perfect spacing
    

    3. Typography Scale

    // Limit to 3-4 font sizes per page
    const typography = {
      hero: 'text-4xl md:text-5xl font-bold tracking-tight',
      heading: 'text-2xl md:text-3xl font-semibold',
      subheading: 'text-lg md:text-xl font-medium',
      body: 'text-base leading-relaxed',
      caption: 'text-sm text-gray-500',
    };
    
    // Rule: Never use more than 2 font families
    // Rule: Line height 1.5-1.7 for body text
    

    Glassmorphism (Web)

    Base Glass Card

    // Modern glass effect - use sparingly for emphasis
    const GlassCard = ({ children, className = '' }) => (
      <div className={`
        backdrop-blur-xl
        bg-white/10
        border border-white/20
        rounded-2xl
        shadow-xl
        shadow-black/5
        ${className}
      `}>
        {children}
      </div>
    );
    

    Glass Variants

    // Light mode glass
    const lightGlass = `
      backdrop-blur-xl
      bg-white/70
      border border-white/50
      shadow-lg shadow-gray-200/50
    `;
    
    // Dark mode glass
    const darkGlass = `
      backdrop-blur-xl
      bg-gray-900/70
      border border-white/10
      shadow-xl shadow-black/20
    `;
    
    // Frosted sidebar
    const frostedSidebar = `
      backdrop-blur-2xl
      bg-gradient-to-b from-white/80 to-white/60
      border-r border-white/30
    `;
    
    // Floating action glass
    const floatingGlass = `
      backdrop-blur-md
      bg-white/90
      rounded-full
      shadow-lg shadow-black/10
      border border-white/50
    `;
    

    When to Use Glassmorphism

    ✓ Hero sections with image backgrounds
    ✓ Floating cards over gradients
    ✓ Modal overlays
    ✓ Navigation bars (subtle)
    ✓ Feature highlights
    
    ✗ Every card (overuse kills the effect)
    ✗ Text-heavy content areas
    ✗ Forms (reduces contrast)
    ✗ Data tables
    

    Color System

    Semantic Colors

    const colors = {
      // Actions
      primary: 'bg-blue-600 hover:bg-blue-700',
      secondary: 'bg-gray-100 hover:bg-gray-200 text-gray-900',
      danger: 'bg-red-600 hover:bg-red-700',
      success: 'bg-green-600 hover:bg-green-700',
    
      // Surfaces
      background: 'bg-gray-50 dark:bg-gray-950',
      surface: 'bg-white dark:bg-gray-900',
      elevated: 'bg-white dark:bg-gray-800 shadow-lg',
    
      // Text
      textPrimary: 'text-gray-900 dark:text-white',
      textSecondary: 'text-gray-600 dark:text-gray-400',
      textMuted: 'text-gray-400 dark:text-gray-500',
    };
    

    Gradient Backgrounds

    // Subtle mesh gradient (modern, premium)
    const meshGradient = `
      bg-gradient-to-br
      from-blue-50 via-white to-purple-50
      dark:from-gray-950 dark:via-gray-900 dark:to-gray-950
    `;
    
    // Vibrant hero gradient
    const heroGradient = `
      bg-gradient-to-r
      from-blue-600 via-purple-600 to-pink-600
    `;
    
    // Subtle radial glow
    const radialGlow = `
      bg-[radial-gradient(ellipse_at_top,_var(--tw-gradient-stops))]
      from-blue-200/40 via-transparent to-transparent
    `;
    

    Component Patterns

    Buttons

    // Primary button - bold, confident
    const PrimaryButton = ({ children, ...props }) => (
      <button
        className="
          px-6 py-3
          bg-gray-900 dark:bg-white
          text-white dark:text-gray-900
          font-medium
          rounded-xl
          transition-all duration-200
          hover:bg-gray-800 dark:hover:bg-gray-100
          hover:shadow-lg hover:shadow-gray-900/20
          active:scale-[0.98]
          disabled:opacity-50 disabled:cursor-not-allowed
        "
        {...props}
      >
        {children}
      </button>
    );
    
    // Secondary button - subtle
    const SecondaryButton = ({ children, ...props }) => (
      <button
        className="
          px-6 py-3
          bg-gray-100 dark:bg-gray-800
          text-gray-900 dark:text-white
          font-medium
          rounded-xl
          transition-all duration-200
          hover:bg-gray-200 dark:hover:bg-gray-700
          active:scale-[0.98]
        "
        {...props}
      >
        {children}
      </button>
    );
    
    // Ghost button - minimal
    const GhostButton = ({ children, ...props }) => (
      <button
        className="
          px-4 py-2
          text-gray-600 dark:text-gray-400
          font-medium
          rounded-lg
          transition-colors duration-200
          hover:text-gray-900 dark:hover:text-white
          hover:bg-gray-100 dark:hover:bg-gray-800
        "
        {...props}
      >
        {children}
      </button>
    );
    

    Cards

    // Clean card with subtle elevation
    const Card = ({ children, className = '' }) => (
      <div className={`
        bg-white dark:bg-gray-900
        rounded-2xl
        border border-gray-200 dark:border-gray-800
        shadow-sm
        hover:shadow-md
        transition-shadow duration-300
        ${className}
      `}>
        {children}
      </div>
    );
    
    // Interactive card
    const InteractiveCard = ({ children, onClick }) => (
      <button
        onClick={onClick}
        className="
          w-full text-left
          bg-white dark:bg-gray-900
          rounded-2xl
          border border-gray-200 dark:border-gray-800
          p-6
          transition-all duration-300
          hover:border-gray-300 dark:hover:border-gray-700
          hover:shadow-lg
          hover:-translate-y-1
          active:scale-[0.99]
        "
      >
        {children}
      </button>
    );
    

    Input Fields

    const Input = ({ label, error, ...props }) => (
      <div className="space-y-2">
        {label && (
          <label className="block text-sm font-medium text-gray-700 dark:text-gray-300">
            {label}
          </label>
        )}
        <input
          className={`
            w-full px-4 py-3
            bg-gray-50 dark:bg-gray-800
            border-2 rounded-xl
            text-gray-900 dark:text-white
            placeholder-gray-400 dark:placeholder-gray-500
            transition-all duration-200
            focus:outline-none focus:ring-0
            ${error
              ? 'border-red-500 focus:border-red-500'
              : 'border-transparent focus:border-blue-500 focus:bg-white dark:focus:bg-gray-900'
            }
          `}
          {...props}
        />
        {error && (
          <p className="text-sm text-red-500">{error}</p>
        )}
      </div>
    );
    

    Micro-Interactions

    Transitions

    // Standard transitions - ALWAYS use
    const transitions = {
      fast: 'transition-all duration-150',      // Hover states
      normal: 'transition-all duration-200',    // Most interactions
      slow: 'transition-all duration-300',      // Card hovers, modals
      spring: 'transition-all duration-500 ease-out', // Page transitions
    };
    
    // Rule: Everything interactive should transition
    // Rule: 150-300ms feels responsive, >500ms feels slow
    

    Hover Effects

    // Scale on hover (buttons, cards)
    className="hover:scale-105 active:scale-95 transition-transform"
    
    // Lift on hover (cards)
    className="hover:-translate-y-1 hover:shadow-xl transition-all"
    
    // Glow on hover (CTAs)
    className="hover:shadow-lg hover:shadow-blue-500/25 transition-shadow"
    
    // Border highlight (inputs, cards)
    className="hover:border-gray-300 transition-colors"
    

    Loading States

    // Skeleton loader
    const Skeleton = ({ className = '' }) => (
      <div className={`
        animate-pulse
        bg-gray-200 dark:bg-gray-800
        rounded-lg
        ${className}
      `} />
    );
    
    // Spinner
    const Spinner = ({ size = 'md' }) => (
      <div className={`
        animate-spin rounded-full
        border-2 border-gray-200 dark:border-gray-700
        border-t-blue-600
        ${size === 'sm' ? 'w-4 h-4' : size === 'lg' ? 'w-8 h-8' : 'w-6 h-6'}
      `} />
    );
    
    // Button loading state
    <button disabled className="relative">
      <span className="opacity-0">Submit</span>
      <Spinner className="absolute inset-0 m-auto" />
    </button>
    

    Layout Patterns

    Container

    // Consistent max-width and padding
    const Container = ({ children, className = '' }) => (
      <div className={`
        max-w-7xl mx-auto
        px-4 sm:px-6 lg:px-8
        ${className}
      `}>
        {children}
      </div>
    );
    

    Section Spacing

    // Consistent vertical rhythm
    const Section = ({ children }) => (
      <section className="py-16 md:py-24">
        <Container>{children}</Container>
      </section>
    );
    

    Grid Systems

    // Feature grid
    <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
      {features.map(f => <FeatureCard key={f.id} {...f} />)}
    </div>
    
    // Bento grid (modern asymmetric)
    <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
      <div className="col-span-2 row-span-2">Large</div>
      <div className="col-span-1">Small</div>
      <div className="col-span-1">Small</div>
      <div className="col-span-2">Medium</div>
    </div>
    

    Dark Mode

    Implementation

    // Always design for both modes
    // Use CSS variables or Tailwind dark: prefix
    
    // Theme toggle
    const ThemeToggle = () => {
      const [dark, setDark] = useState(false);
    
      useEffect(() => {
        document.documentElement.classList.toggle('dark', dark);
      }, [dark]);
    
      return (
        <button onClick={() => setDark(!dark)}>
          {dark ? <SunIcon /> : <MoonIcon />}
        </button>
      );
    };
    

    Color Pairing

    Light Mode          Dark Mode
    ─────────────────────────────────
    white               gray-950
    gray-50             gray-900
    gray-100            gray-800
    gray-200            gray-700
    gray-900 (text)     white (text)
    gray-600 (secondary) gray-400
    blue-600            blue-500
    

    Accessibility

    Contrast Requirements

    WCAG AA: 4.5:1 for normal text, 3:1 for large text
    WCAG AAA: 7:1 for normal text, 4.5:1 for large text
    
    // Test: Use browser devtools or contrast checker
    // Rule: Never use gray-400 on white for body text
    

    Focus States

    // Always visible focus rings
    className="
      focus:outline-none
      focus-visible:ring-2
      focus-visible:ring-blue-500
      focus-visible:ring-offset-2
    "
    
    // Never remove focus styles without replacement
    // ✗ outline-none (alone)
    // ✓ outline-none + focus-visible:ring
    

    Screen Readers

    // Visually hidden but accessible
    const srOnly = "absolute w-px h-px p-0 -m-px overflow-hidden whitespace-nowrap border-0";
    
    // Icon buttons need labels
    <button aria-label="Close menu">
      <XIcon className="w-6 h-6" />
    </button>
    
    // Announce dynamic content
    <div role="status" aria-live="polite">
      {message}
    </div>
    

    Anti-Patterns

    Never Do

    ✗ More than 3 font sizes on a page
    ✗ Random spacing values (use 8px grid)
    ✗ Pure black (#000) on pure white (#fff)
    ✗ Colored text on colored backgrounds without checking contrast
    ✗ Animations longer than 500ms for UI elements
    ✗ Glassmorphism everywhere
    ✗ Drop shadows on everything
    ✗ Gradients on text (hard to read)
    ✗ Auto-playing animations that can't be stopped
    ✗ Removing focus indicators
    ✗ Gray text below 4.5:1 contrast
    ✗ Tiny click targets (< 44px)
    

    Common Mistakes

    // ✗ Too many shadows
    className="shadow-sm shadow-md shadow-lg" // Pick ONE
    
    // ✗ Inconsistent rounding
    className="rounded-sm rounded-lg rounded-2xl" // System: sm, lg, xl, 2xl
    
    // ✗ Competing focal points
    // One primary CTA per viewport
    
    // ✗ Over-decorated
    // If it doesn't serve function, remove it
    

    Quick Reference

    Modern Defaults

    // Border radius: 12-16px (rounded-xl to rounded-2xl)
    // Shadow: subtle (shadow-sm to shadow-md)
    // Font: Inter, SF Pro, system-ui
    // Primary: Near-black or brand color
    // Transitions: 200ms ease-out
    // Spacing: 8px grid (Tailwind default)
    

    Premium Feel Checklist

    □ Generous whitespace
    □ Subtle shadows (not harsh)
    □ Smooth transitions on all interactions
    □ Consistent border radius
    □ Limited color palette (2-3 colors max)
    □ Typography hierarchy (3 sizes max)
    □ High-quality imagery
    □ Micro-interactions on hover/focus
    □ Dark mode support
    
    Recommended Servers
    Browser tool
    Browser tool
    Exa Search
    Exa Search
    Svelte
    Svelte
    Repository
    alinaqi/claude-bootstrap
    Files