| name | Design System Compliance |
| description | Ensure all UI components follow the design guidelines including purple-indigo gradient, rounded-xl borders, backdrop-blur-sm effects, dark mode support, and accessibility requirements |
Design System Compliance
This skill ensures all UI components follow the My Prompt Manager design guidelines for visual consistency, accessibility, and brand identity.
When to Use This Skill
Invoke this skill when:
- Creating new UI components
- Modifying existing components
- Adding buttons, forms, cards, or modals
- Implementing hover, focus, or active states
- Working on light/dark mode styling
- User asks for "design consistency", "styling", or "UI updates"
Critical Requirements
From docs/DESIGN_GUIDELINES.md:
CRITICAL: When creating or modifying UI components, you MUST follow the design guidelines in docs/DESIGN_GUIDELINES.md.
Non-Negotiables:
- Purple-indigo gradient for all primary actions
- rounded-xl (12px) for cards, inputs, buttons
- Dark mode support - EVERY style needs
dark: variant
- Backdrop-blur with semi-transparent backgrounds
- Predefined focus classes - Never create custom focus styles
- Accessibility - ARIA labels, keyboard navigation, color contrast
Design System Overview
Brand Identity
Primary Colors:
bg-linear-to-r from-purple-600 to-indigo-600
hover:from-purple-700 hover:to-indigo-700
Status Colors:
bg-green-500
bg-red-500
bg-yellow-500
bg-blue-500
Gray Scale:
bg-white
bg-gray-50
bg-gray-100
text-gray-900
text-gray-600
dark:bg-gray-900
dark:bg-gray-800
dark:bg-gray-700
dark:text-gray-100
dark:text-gray-400
Typography System
Font Sizes:
text-xs
text-sm
text-base
text-xl
text-2xl
Font Weights:
font-medium
font-semibold
font-bold
Common Patterns:
{}
<h1 className="text-xl font-bold text-gray-900 dark:text-gray-100">
Add New Prompt
</h1>
{}
<h2 className="text-sm font-semibold text-gray-700 dark:text-gray-300 mb-3">
Category
</h2>
{}
<p className="text-sm text-gray-600 dark:text-gray-400">
Description text
</p>
{}
<p className="text-xs text-gray-500 dark:text-gray-400 font-medium">
100/10000 characters
</p>
Spacing & Layout
Standard Spacing:
p-3
p-4
p-5
p-6
Common Gaps:
space-x-2
space-x-3
gap-3
Border Radius
Standard Values:
rounded-md
rounded-lg
rounded-xl
rounded-full
CRITICAL: Use rounded-xl (12px) for:
- All primary buttons
- All input fields
- All cards and containers
- All modals and dialogs
Effects & Shadows
Glassmorphism (Signature Effect):
bg-white/70 dark:bg-gray-800/70 backdrop-blur-sm
Shadow Scale:
shadow-xs
shadow-lg
shadow-xl
Transitions:
transition-all duration-200
Component Patterns
1. Primary Button
Pattern:
<button className="
px-6 py-3
text-sm font-semibold text-white
bg-linear-to-r from-purple-600 to-indigo-600
rounded-xl
hover:from-purple-700 hover:to-indigo-700
transition-all duration-200
shadow-lg hover:shadow-xl
disabled:opacity-50
focus-primary
">
Save Prompt
</button>
Key Elements:
- Purple-indigo gradient background
- White text
- rounded-xl (12px radius)
- Gradient hover state
- Shadow elevation
- Predefined focus class
Focus Class (Predefined in Tailwind config):
.focus-primary {
@apply focus:outline-hidden focus:ring-2 focus:ring-purple-500
focus:ring-offset-2 focus:ring-offset-white
dark:focus:ring-offset-gray-900;
}
2. Secondary Button
Pattern:
<button className="
px-6 py-3
text-sm font-semibold
text-gray-700 dark:text-gray-300
bg-white/60 dark:bg-gray-700/60 backdrop-blur-sm
border border-purple-200 dark:border-gray-600
rounded-xl
hover:bg-white/80 dark:hover:bg-gray-700/80
transition-all duration-200
focus-secondary
">
Cancel
</button>
Key Elements:
- Glassmorphism effect (semi-transparent + backdrop-blur)
- Border with purple tint
- Dark mode support
- No shadow (subtle appearance)
3. Input Fields
Text Input:
<input
type="text"
className="
w-full px-4 py-3
border border-purple-200 dark:border-gray-600
rounded-xl
focus-input
bg-white/60 dark:bg-gray-700/60 backdrop-blur-sm
transition-all duration-200
text-gray-900 dark:text-gray-100
placeholder-gray-500 dark:placeholder-gray-400
"
placeholder="Enter text..."
/>
Textarea:
<textarea
rows={8}
className="
w-full px-4 py-3
border border-purple-200 dark:border-gray-600
rounded-xl
focus-input
resize-none
bg-white/60 dark:bg-gray-700/60 backdrop-blur-sm
transition-all duration-200
text-gray-900 dark:text-gray-100
"
placeholder="Enter your prompt content..."
/>
Input with Error:
<input
className="
w-full px-4 py-3
border rounded-xl focus-input
bg-white/60 dark:bg-gray-700/60 backdrop-blur-sm
transition-all duration-200
text-gray-900 dark:text-gray-100
border-red-300 dark:border-red-500
"
/>
{errors.field && (
<p className="mt-2 text-sm text-red-600 dark:text-red-400 font-medium">
{errors.field}
</p>
)}
Focus Class:
.focus-input {
@apply focus:outline-hidden focus:ring-2 focus:ring-purple-500
focus:border-purple-500 dark:focus:ring-purple-400
dark:focus:border-purple-400;
}
4. Cards
Prompt Card:
<article className="
bg-white/70 dark:bg-gray-800/70 backdrop-blur-sm
border-b border-purple-100 dark:border-gray-700
p-5
hover:bg-white/90 dark:hover:bg-gray-800/90
transition-all duration-200
relative group
">
<h3 className="font-semibold text-gray-900 dark:text-gray-100 text-sm">
Prompt Title
</h3>
<p className="text-sm text-gray-600 dark:text-gray-400 mt-2">
Prompt content preview...
</p>
</article>
Settings Card:
<div className="
bg-white/70 dark:bg-gray-800/70 backdrop-blur-sm
border border-purple-100 dark:border-gray-700
rounded-xl
p-5
hover:shadow-md
transition-all duration-200
">
{}
</div>
Key Elements:
- Glassmorphism background
- rounded-xl for standalone cards
- border-b for list items
- Hover state for interaction feedback
5. Modals & Dialogs
Modal Container:
<div className="
fixed inset-0 z-50
flex items-center justify-center p-3
">
{}
<div
className="
absolute inset-0
bg-black bg-opacity-50
transition-opacity
"
onClick={onClose}
/>
{}
<div className="
relative
bg-white dark:bg-gray-800
rounded-xl p-3
shadow-xl
transform transition-all
max-w-xs w-full mx-2
backdrop-blur-sm
border border-purple-100 dark:border-gray-700
">
{}
</div>
</div>
Confirm Dialog:
<div className="p-5">
<div className="flex items-start">
{/* Icon */}
<div className="
shrink-0 flex items-center justify-center
h-8 w-8
rounded-full
bg-red-100 dark:bg-red-900/20
">
<svg className="w-6 h-6 text-red-600">{/* Icon */}</svg>
</div>
{/* Content */}
<div className="ml-3 flex-1">
<h3 className="text-sm leading-5 font-bold text-gray-900 dark:text-gray-100">
Delete Prompt
</h3>
<p className="mt-1 text-xs text-gray-600 dark:text-gray-400 leading-tight">
Are you sure? This action cannot be undone.
</p>
</div>
</div>
{}
<div className="mt-3 flex flex-row-reverse gap-2">
<button className="
px-3 py-1.5
text-xs font-semibold text-white
bg-red-600 hover:bg-red-700
rounded-lg shadow-xs
transition-colors
focus-danger
">
Delete
</button>
<button className="
px-3 py-1.5
text-xs font-semibold
text-gray-700 dark:text-gray-300
bg-white dark:bg-gray-700
border border-gray-300 dark:border-gray-600
rounded-lg
hover:bg-gray-50 dark:hover:bg-gray-600
transition-colors
focus-secondary
">
Cancel
</button>
</div>
</div>
6. Search Input
Pattern:
<div className="relative">
<div className="absolute inset-y-0 left-0 pl-4 flex items-center pointer-events-none z-10">
<svg className="h-5 w-5 text-purple-400 dark:text-purple-300">
{/* Search icon */}
</svg>
</div>
<input
type="text"
className="
w-full pl-12 pr-12 py-3
bg-white/60 dark:bg-gray-700/60 backdrop-blur-sm
border border-purple-200 dark:border-gray-600
rounded-xl
focus-input
text-sm
text-gray-900 dark:text-gray-100
placeholder-gray-500 dark:placeholder-gray-400
shadow-xs
hover:bg-white/80 dark:hover:bg-gray-700/80
transition-all duration-200
"
placeholder="Search prompts"
/>
</div>
7. Toggle Switch
Pattern:
<button
type="button"
role="switch"
aria-checked={checked}
onClick={() => onChange(!checked)}
className={`
w-11 h-6
relative inline-flex items-center
rounded-full
transition-all duration-200
focus:outline-hidden focus:ring-4 focus:ring-purple-300 dark:focus:ring-purple-800
${checked
? 'bg-linear-to-r from-purple-600 to-indigo-600 shadow-xs'
: 'bg-gray-200 dark:bg-gray-700'
}
${disabled ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer'}
`}
>
<span className={`
h-5 w-5
inline-block transform
rounded-full bg-white shadow-xs
transition-transform duration-200
border border-gray-300 dark:border-gray-600
${checked ? 'translate-x-6' : 'translate-x-[2px]'}
`} />
</button>
8. Icon Button
Pattern:
<button className="
p-2
text-gray-400 dark:text-gray-500
hover:text-purple-600 dark:hover:text-purple-400
rounded-lg
hover:bg-purple-50 dark:hover:bg-purple-900/20
transition-colors
focus-interactive
">
<svg className="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="..." />
</svg>
</button>
Focus Class:
.focus-interactive {
@apply focus:outline-hidden focus:ring-2 focus:ring-purple-500
focus:ring-offset-1 focus:ring-offset-white
dark:focus:ring-offset-gray-800 dark:focus:ring-purple-400;
}
Dark Mode Implementation
Strategy
Class-based dark mode with Tailwind CSS:
darkMode: 'class'
The .dark class is applied to the root element when dark mode is active.
Dark Mode Patterns
Every style MUST have a dark mode variant:
{}
<div className="
bg-white dark:bg-gray-900
text-gray-900 dark:text-gray-100
border-purple-200 dark:border-gray-600
">
{}
<div className="
bg-white
text-gray-900
border-purple-200
">
Common Dark Mode Combinations:
bg-white dark:bg-gray-900
bg-gray-50 dark:bg-gray-800
bg-white/70 dark:bg-gray-800/70
text-gray-900 dark:text-gray-100
text-gray-700 dark:text-gray-300
text-gray-500 dark:text-gray-400
border-purple-200 dark:border-gray-600
border-purple-100 dark:border-gray-700
hover:bg-purple-50 dark:hover:bg-purple-900/20
hover:text-purple-600 dark:hover:text-purple-400
focus:ring-purple-500 dark:focus:ring-purple-400
focus:ring-offset-white dark:focus:ring-offset-gray-900
Testing Dark Mode
Manual checklist:
Color Contrast Requirements (WCAG AA):
- Normal text: 4.5:1 contrast ratio
- Large text (18px+): 3:1 contrast ratio
- Interactive elements: 3:1 contrast ratio
Predefined Focus Classes
NEVER create custom focus styles. Always use these predefined classes:
.focus-primary
For primary action buttons:
.focus-primary {
@apply focus:outline-hidden focus:ring-2 focus:ring-purple-500
focus:ring-offset-2 focus:ring-offset-white
dark:focus:ring-offset-gray-900;
}
.focus-secondary
For secondary buttons and menu items:
.focus-secondary {
@apply focus:outline-hidden focus:ring-2 focus:ring-purple-500
focus:ring-offset-1 focus:ring-offset-white
dark:focus:ring-offset-gray-800;
}
.focus-danger
For delete/danger buttons:
.focus-danger {
@apply focus:outline-hidden focus:ring-2 focus:ring-red-500
focus:ring-offset-2 focus:ring-offset-white
dark:focus:ring-offset-gray-900;
}
.focus-input
For input fields:
.focus-input {
@apply focus:outline-hidden focus:ring-2 focus:ring-purple-500
focus:border-purple-500 dark:focus:ring-purple-400
dark:focus:border-purple-400;
}
.focus-interactive
For icon buttons and interactive elements:
.focus-interactive {
@apply focus:outline-hidden focus:ring-2 focus:ring-purple-500
focus:ring-offset-1 focus:ring-offset-white
dark:focus:ring-offset-gray-800 dark:focus:ring-purple-400;
}
Accessibility Requirements
ARIA Labels
All interactive elements MUST have appropriate ARIA labels:
{}
<button aria-label="Copy prompt to clipboard">
<svg aria-hidden="true">{/* Icon */}</svg>
</button>
{}
<input
type="text"
aria-label="Search prompts"
role="searchbox"
/>
{}
<article aria-labelledby="prompt-title-123">
<h3 id="prompt-title-123">Prompt Title</h3>
</article>
{}
<button
role="switch"
aria-checked={isEnabled}
aria-label="Enable dark mode"
>
Keyboard Navigation
All interactive elements must be keyboard accessible:
- Tab: Navigate between elements
- Enter/Space: Activate buttons
- Escape: Close modals/dropdowns
- Arrow keys: Navigate lists/menus
Example:
<button
onClick={handleClick}
onKeyDown={(e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
handleClick();
}
}}
>
Focus Management
Visible focus indicators are mandatory:
{}
<button className="focus-primary">Save</button>
{}
<button className="outline-hidden">Save</button>
Common Mistakes & Fixes
Mistake 1: Missing Dark Mode
Problem:
<div className="bg-white text-gray-900 border-gray-200">
Fix:
<div className="bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100 border-gray-200 dark:border-gray-700">
Mistake 2: Wrong Border Radius
Problem:
<button className="rounded-lg"> {}
Fix:
<button className="rounded-xl"> {}
Mistake 3: Missing Gradient on Primary Button
Problem:
<button className="bg-purple-600">Save</button>
Fix:
<button className="bg-linear-to-r from-purple-600 to-indigo-600">Save</button>
Mistake 4: Custom Focus Styles
Problem:
<button className="focus:outline-hidden focus:ring-2 focus:ring-blue-500">
Fix:
<button className="focus-primary">
Mistake 5: No Backdrop Blur
Problem:
<div className="bg-white/70"> {}
Fix:
<div className="bg-white/70 backdrop-blur-sm">
Mistake 6: Wrong Transition Duration
Problem:
<button className="transition-all duration-300"> {}
Fix:
<button className="transition-all duration-200">
Mistake 7: Missing ARIA Label
Problem:
<button>
<svg>{/* Icon */}</svg>
</button>
Fix:
<button aria-label="Copy to clipboard">
<svg aria-hidden="true">{/* Icon */}</svg>
</button>
Component Creation Checklist
When creating a new component, verify:
Quick Reference
Color Palette
from-purple-600 to-indigo-600
bg-purple-500
bg-green-500
bg-red-500
bg-yellow-500
bg-blue-500
bg-white, bg-gray-50, bg-gray-100
text-gray-900, text-gray-700, text-gray-500
dark:bg-gray-900, dark:bg-gray-800, dark:bg-gray-700
dark:text-gray-100, dark:text-gray-300, dark:text-gray-400
Common Class Combinations
Primary Button:
px-6 py-3 text-sm font-semibold text-white
bg-linear-to-r from-purple-600 to-indigo-600
rounded-xl hover:from-purple-700 hover:to-indigo-700
transition-all duration-200 shadow-lg hover:shadow-xl
disabled:opacity-50 focus-primary
Text Input:
w-full px-4 py-3
border border-purple-200 dark:border-gray-600
rounded-xl focus-input
bg-white/60 dark:bg-gray-700/60 backdrop-blur-sm
transition-all duration-200
text-gray-900 dark:text-gray-100
Card:
bg-white/70 dark:bg-gray-800/70 backdrop-blur-sm
border-b border-purple-100 dark:border-gray-700
p-5 hover:bg-white/90 dark:hover:bg-gray-800/90
transition-all duration-200
Related Documentation
- Complete Design Guidelines:
docs/DESIGN_GUIDELINES.md (comprehensive reference)
- Component Catalog:
docs/COMPONENTS.md (40+ component examples)
- React 19 Patterns:
docs/REACT_19_MIGRATION.md (form handling, optimistic updates)
Validation Workflow
Before marking component complete:
-
Visual Inspection:
- Check in browser (light mode)
- Check in browser (dark mode)
- Verify gradient on primary buttons
- Confirm rounded-xl borders
-
Accessibility Check:
- Tab through all interactive elements
- Verify focus indicators are visible
- Check ARIA labels in DevTools
- Test keyboard shortcuts (Enter, Escape)
-
Code Review:
- All styles have dark mode variants
- Uses predefined focus classes
- No console.* statements
- Follows spacing/typography scale
-
Testing:
- Run
npm test
- Run
npm run lint
- Both must pass
Last Updated: 2025-10-18
Skill Version: 1.0.0