Tailwind CSS Setup
> **Skill Purpose:** CSS framework configuration and styling system patterns
SKILL.md
Full skill instructions
Tailwind CSS Setup
Skill Purpose: CSS framework configuration and styling system patterns
Core Skill Pattern
Objective: Establish consistent styling system with utility-first CSS approach and design token management.
Universal Pattern:
- Define styling system requirements and design tokens
- Configure CSS framework and build process
- Set up custom themes and component styling
- Establish responsive design patterns
- Create styling organization and maintenance procedures
Key Decisions (Project-Specific):
- CSS framework selection and configuration approach
- Design system complexity vs utility usage
- Custom theme level and component styling needs
- Responsive design requirements and breakpoints
- Team styling workflow and organization
Project-Specific Implementation Notes
Customize per project:
- Framework selection based on styling preferences
- Theme complexity based on design requirements
- Component styling based on UI complexity
- Responsive needs based on target devices
- Organization based on team size and design process
Example Implementation (Tailwind CSS with Next.js Pattern)
Note: This is an example pattern using Tailwind CSS. Adapt CSS framework and configuration based on your specific project requirements and design system.
Prerequisites (Example)
- Project initialized
- Design requirements defined
- CSS framework selected
Example: Tailwind CSS Styling System Implementation
Framework-Specific Example: This demonstrates the pattern using Tailwind CSS with Next.js. Adapt for your CSS framework and design system.
1. Install Tailwind CSS Dependencies
# Install Tailwind CSS and its dependencies
npm install -D tailwindcss postcss autoprefixer
# Install shadcn/ui dependencies
npm install -D @tailwindcss/typography
npm install class-variance-authority clsx tailwind-merge
2. Initialize Tailwind CSS
# Initialize Tailwind CSS configuration
npx tailwindcss init -p
3. Configure Tailwind CSS
Update tailwind.config.ts:
import type { Config } from 'tailwindcss';
import typography from '@tailwindcss/typography';
const config: Config = {
content: [
'./src/pages/**/*.{js,ts,jsx,tsx,mdx}',
'./src/components/**/*.{js,ts,jsx,tsx,mdx}',
'./src/app/**/*.{js,ts,jsx,tsx,mdx}',
],
theme: {
extend: {
colors: {
// Zeus brand colors
border: 'hsl(var(--border))',
input: 'hsl(var(--input))',
ring: 'hsl(var(--ring))',
background: 'hsl(var(--background))',
foreground: 'hsl(var(--foreground))',
primary: {
DEFAULT: 'hsl(var(--primary))',
foreground: 'hsl(var(--primary-foreground))',
},
secondary: {
DEFAULT: 'hsl(var(--secondary))',
foreground: 'hsl(var(--secondary-foreground))',
},
destructive: {
DEFAULT: 'hsl(var(--destructive))',
foreground: 'hsl(var(--destructive-foreground))',
},
muted: {
DEFAULT: 'hsl(var(--muted))',
foreground: 'hsl(var(--muted-foreground))',
},
accent: {
DEFAULT: 'hsl(var(--accent))',
foreground: 'hsl(var(--accent-foreground))',
},
popover: {
DEFAULT: 'hsl(var(--popover))',
foreground: 'hsl(var(--popover-foreground))',
},
card: {
DEFAULT: 'hsl(var(--card))',
foreground: 'hsl(var(--card-foreground))',
},
// Custom Zeus colors
zeus: {
50: '#f0f9ff',
100: '#e0f2fe',
200: '#bae6fd',
300: '#7dd3fc',
400: '#38bdf8',
500: '#0ea5e9',
600: '#0284c7',
700: '#0369a1',
800: '#075985',
900: '#0c4a6e',
950: '#082f49',
},
},
borderRadius: {
lg: 'var(--radius)',
md: 'calc(var(--radius) - 2px)',
sm: 'calc(var(--radius) - 4px)',
},
fontFamily: {
sans: ['var(--font-sans)', 'system-ui', 'sans-serif'],
mono: ['var(--font-mono)', 'monospace'],
},
fontSize: {
xs: ['0.75rem', { lineHeight: '1rem' }],
sm: ['0.875rem', { lineHeight: '1.25rem' }],
base: ['1rem', { lineHeight: '1.5rem' }],
lg: ['1.125rem', { lineHeight: '1.75rem' }],
xl: ['1.25rem', { lineHeight: '1.75rem' }],
'2xl': ['1.5rem', { lineHeight: '2rem' }],
'3xl': ['1.875rem', { lineHeight: '2.25rem' }],
'4xl': ['2.25rem', { lineHeight: '2.5rem' }],
'5xl': ['3rem', { lineHeight: '1' }],
'6xl': ['3.75rem', { lineHeight: '1' }],
'7xl': ['4.5rem', { lineHeight: '1' }],
'8xl': ['6rem', { lineHeight: '1' }],
'9xl': ['8rem', { lineHeight: '1' }],
},
spacing: {
'18': '4.5rem',
'88': '22rem',
'128': '32rem',
},
maxWidth: {
'8xl': '88rem',
'9xl': '96rem',
},
animation: {
'fade-in': 'fadeIn 0.5s ease-in-out',
'slide-up': 'slideUp 0.3s ease-out',
'slide-down': 'slideDown 0.3s ease-out',
'scale-in': 'scaleIn 0.2s ease-out',
'spin-slow': 'spin 3s linear infinite',
},
keyframes: {
fadeIn: {
'0%': { opacity: '0' },
'100%': { opacity: '1' },
},
slideUp: {
'0%': { transform: 'translateY(10px)', opacity: '0' },
'100%': { transform: 'translateY(0)', opacity: '1' },
},
slideDown: {
'0%': { transform: 'translateY(-10px)', opacity: '0' },
'100%': { transform: 'translateY(0)', opacity: '1' },
},
scaleIn: {
'0%': { transform: 'scale(0.95)', opacity: '0' },
'100%': { transform: 'scale(1)', opacity: '1' },
},
},
boxShadow: {
'zeus': '0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)',
'zeus-lg': '0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)',
'zeus-xl': '0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)',
},
screens: {
'3xl': '1600px',
},
},
plugins: [typography],
},
plugins: [
require('@tailwindcss/typography'),
],
} satisfies Config;
export default config;
4. Configure PostCSS
Update postcss.config.js:
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};
5. Update Global CSS
Update src/app/globals.css:
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
:root {
--background: 0 0% 100%;
--foreground: 222.2 84% 4.9%;
--card: 0 0% 100%;
--card-foreground: 222.2 84% 4.9%;
--popover: 0 0% 100%;
--popover-foreground: 222.2 84% 4.9%;
--primary: 221.2 83.2% 53.3%;
--primary-foreground: 210 40% 98%;
--secondary: 210 40% 96%;
--secondary-foreground: 222.2 84% 4.9%;
--muted: 210 40% 96%;
--muted-foreground: 215.4 16.3% 46.9%;
--accent: 210 40% 96%;
--accent-foreground: 222.2 84% 4.9%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 210 40% 98%;
--border: 214.3 31.8% 91.4%;
--input: 214.3 31.8% 91.4%;
--ring: 221.2 83.2% 53.3%;
--radius: 0.5rem;
}
.dark {
--background: 222.2 84% 4.9%;
--foreground: 210 40% 98%;
--card: 222.2 84% 4.9%;
--card-foreground: 210 40% 98%;
--popover: 222.2 84% 4.9%;
--popover-foreground: 210 40% 98%;
--primary: 217.2 91.2% 59.8%;
--primary-foreground: 222.2 84% 4.9%;
--secondary: 217.2 32.6% 17.5%;
--secondary-foreground: 210 40% 98%;
--muted: 217.2 32.6% 17.5%;
--muted-foreground: 215 20.2% 65.1%;
--accent: 217.2 32.6% 17.5%;
--accent-foreground: 210 40% 98%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 210 40% 98%;
--border: 217.2 32.6% 17.5%;
--input: 217.2 32.6% 17.5%;
--ring: 224.3 76.3% 94.1%;
}
}
@layer base {
* {
@apply border-border;
}
body {
@apply bg-background text-foreground;
}
}
@layer components {
/* Zeus component styles */
.btn {
@apply inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50;
}
.btn-primary {
@apply bg-primary text-primary-foreground hover:bg-primary/90;
}
.btn-secondary {
@apply bg-secondary text-secondary-foreground hover:bg-secondary/80;
}
.btn-outline {
@apply border border-input bg-background hover:bg-accent hover:text-accent-foreground;
}
.btn-ghost {
@apply hover:bg-accent hover:text-accent-foreground;
}
.btn-sm {
@apply h-9 rounded-md px-3;
}
.btn-lg {
@apply h-11 rounded-md px-8;
}
.card {
@apply rounded-lg border bg-card text-card-foreground shadow-shadow;
}
.input {
@apply flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50;
}
.label {
@apply text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70;
}
/* Layout components */
.container {
@apply w-full mx-auto px-4 sm:px-6 lg:px-8;
}
.container-fluid {
@apply w-full px-4 sm:px-6 lg:px-8;
}
.container-narrow {
@apply max-w-4xl mx-auto px-4 sm:px-6 lg:px-8;
}
.container-wide {
@apply max-w-7xl mx-auto px-4 sm:px-6 lg:px-8;
}
/* Navigation */
.nav-link {
@apply text-sm font-medium transition-colors hover:text-primary;
}
.nav-link-active {
@apply text-primary;
}
/* Form styles */
.form-group {
@apply space-y-2;
}
.form-error {
@apply text-sm text-destructive;
}
.form-help {
@apply text-sm text-muted-foreground;
}
/* Table styles */
.table {
@apply w-full caption-bottom text-sm;
}
.table-header {
@apply border-b;
}
.table-row {
@apply border-b transition-colors hover:bg-muted/50;
}
.table-head {
@apply h-12 px-4 text-left align-middle font-medium text-muted-foreground;
}
.table-cell {
@apply p-4 align-middle;
}
/* Alert styles */
.alert {
@apply relative w-full rounded-lg border p-4;
}
.alert-default {
@apply bg-background text-foreground;
}
.alert-destructive {
@apply border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive;
}
/* Badge styles */
.badge {
@apply inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2;
}
.badge-default {
@apply border-transparent bg-primary text-primary-foreground hover:bg-primary/80;
}
.badge-secondary {
@apply border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80;
}
.badge-outline {
@apply text-foreground;
}
/* Skeleton styles */
.skeleton {
@apply animate-pulse rounded-md bg-muted;
}
}
@layer utilities {
/* Text utilities */
.text-balance {
text-wrap: balance;
}
/* Animation utilities */
.animate-in {
animation: fadeIn 0.5s ease-in-out;
}
.animate-out {
animation: fadeOut 0.5s ease-in-out;
}
/* Scroll utilities */
.scrollbar-hide {
-ms-overflow-style: none;
scrollbar-width: none;
}
.scrollbar-hide::-webkit-scrollbar {
display: none;
}
/* Focus utilities */
.focus-ring {
@apply focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2;
}
/* Grid utilities */
.grid-auto-fit {
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
}
.grid-auto-fill {
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
}
/* Aspect ratio utilities */
.aspect-square {
aspect-ratio: 1 / 1;
}
.aspect-video {
aspect-ratio: 16 / 9;
}
.aspect-photo {
aspect-ratio: 4 / 3;
}
/* Position utilities */
.safe-area-top {
padding-top: env(safe-area-inset-top);
}
.safe-area-bottom {
padding-bottom: env(safe-area-inset-bottom);
}
.safe-area-left {
padding-left: env(safe-area-inset-left);
}
.safe-area-right {
padding-right: env(safe-area-inset-right);
}
}
/* Custom scrollbar */
::-webkit-scrollbar {
width: 6px;
}
::-webkit-scrollbar-track {
background: hsl(var(--muted));
}
::-webkit-scrollbar-thumb {
background: hsl(var(--muted-foreground));
border-radius: 3px;
}
::-webkit-scrollbar-thumb:hover {
background: hsl(var(--border));
}
/* Print styles */
@media print {
.no-print {
display: none !important;
}
.print-only {
display: block !important;
}
}
/* High contrast mode */
@media (prefers-contrast: high) {
:root {
--border: 0 0% 0%;
--input: 0 0% 0%;
--ring: 0 0% 0%;
}
}
/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}
6. Create Tailwind Utilities
Create src/lib/utils.ts:
import { type ClassValue, clsx } from 'clsx';
import { twMerge } from 'tailwind-merge';
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}
// Conditional class names
export function conditionalClass(condition: boolean, className: string) {
return condition ? className : '';
}
// Responsive breakpoints
export const breakpoints = {
sm: '640px',
md: '768px',
lg: '1024px',
xl: '1280px',
'2xl': '1536px',
} as const;
// Responsive utility
export function responsive(classes: Record<string, string>) {
return Object.entries(classes)
.map(([breakpoint, className]) => {
if (breakpoint === 'base') return className;
return `${breakpoint}:${className}`;
})
.join(' ');
}
// Theme utilities
export function getCSSVariable(name: string): string {
return getComputedStyle(document.documentElement)
.getPropertyValue(`--${name}`)
.trim();
}
export function setCSSVariable(name: string, value: string): void {
document.documentElement.style.setProperty(`--${name}`, value);
}
// Color utilities
export function hexToRgb(hex: string): { r: number; g: number; b: number } | null {
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result
? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16),
}
: null;
}
export function rgbToHsl(r: number, g: number, b: number): string {
r /= 255;
g /= 255;
b /= 255;
const max = Math.max(r, g, b);
const min = Math.min(r, g, b);
let h = 0;
let s = 0;
const l = (max + min) / 2;
if (max !== min) {
const d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch (max) {
case r:
h = ((g - b) / d + (g < b ? 6 : 0)) / 6;
break;
case g:
h = ((b - r) / d + 2) / 6;
break;
case b:
h = ((r - g) / d + 4) / 6;
break;
}
}
return `${Math.round(h * 360)} ${Math.round(s * 100)}% ${Math.round(l * 100)}%`;
}
7. Create Theme Provider
Create src/components/theme-provider.tsx:
'use client';
import * as React from 'react';
import { ThemeProvider as NextThemesProvider } from 'next-themes';
import { type ThemeProviderProps } from 'next-themes/dist/types';
export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
return <NextThemesProvider {...props}>{children}</NextThemesProvider>;
}
8. Create Theme Toggle
Create src/components/theme-toggle.tsx:
'use client';
import * as React from 'react';
import { Moon, Sun } from 'lucide-react';
import { useTheme } from 'next-themes';
import { Button } from '@/components/ui/button';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
export function ThemeToggle() {
const { setTheme } = useTheme();
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline" size="icon">
<Sun className="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
<Moon className="absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
<span className="sr-only">Toggle theme</span>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem onClick={() => setTheme('light')}>
Light
</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme('dark')}>
Dark
</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme('system')}>
System
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
}
9. Update Package.json Scripts
Update package.json scripts:
{
"scripts": {
"tailwind:build": "tailwindcss -i ./src/app/globals.css -o ./dist/styles.css",
"tailwind:watch": "tailwindcss -i ./src/app/globals.css -o ./dist/styles.css --watch",
"tailwind:prod": "NODE_ENV=production tailwindcss -i ./src/app/globals.css -o ./dist/styles.css --minify"
}
}
10. Configure ESLint for Tailwind
Update .eslintrc.json:
{
"extends": ["next/core-web-vitals"],
"rules": {
"tailwindcss/no-custom-classname": "off",
"tailwindcss/enforces-shorthand": "error",
"tailwindcss/no-contradicting-classnames": "error"
}
}
Code Examples
Using Custom Components
// Button component example
import { cn } from '@/lib/utils';
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
variant?: 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost' | 'link';
size?: 'default' | 'sm' | 'lg' | 'icon';
}
export function Button({ className, variant = 'default', size = 'default', ...props }: ButtonProps) {
return (
<button
className={cn(
'btn',
{
'btn-primary': variant === 'default',
'btn-destructive': variant === 'destructive',
'btn-outline': variant === 'outline',
'btn-secondary': variant === 'secondary',
'btn-ghost': variant === 'ghost',
'btn-sm': size === 'sm',
'btn-lg': size === 'lg',
},
className
)}
{...props}
/>
);
}
Responsive Design Patterns
// Responsive grid example
export function ResponsiveGrid() {
return (
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{/* Grid items */}
</div>
);
}
// Responsive typography
export function ResponsiveText() {
return (
<div>
<h1 className="text-2xl md:text-3xl lg:text-4xl font-bold">
Responsive Heading
</h1>
<p className="text-sm md:text-base lg:text-lg">
Responsive paragraph text
</p>
</div>
);
}
// Responsive spacing
export function ResponsiveSpacing() {
return (
<div className="px-4 md:px-6 lg:px-8 py-8 md:py-12 lg:py-16">
<div className="space-y-4 md:space-y-6 lg:space-y-8">
{/* Content */}
</div>
</div>
);
}
Dark Mode Implementation
// Dark mode component
export function DarkModeComponent() {
return (
<div className="bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100">
<div className="border border-gray-200 dark:border-gray-700">
<h2 className="text-gray-800 dark:text-gray-200">
Dark mode compatible
</h2>
</div>
</div>
);
}
Animation Examples
// Animated components
export function AnimatedCard() {
return (
<div className="card animate-in">
<h3 className="text-lg font-semibold">Animated Card</h3>
<p className="text-muted-foreground">This card animates in</p>
</div>
);
}
export function LoadingSpinner() {
return (
<div className="animate-spin h-4 w-4 border-2 border-primary border-t-transparent rounded-full" />
);
}
Configuration Templates
Complete tailwind.config.ts for Zeus Framework
import type { Config } from 'tailwindcss';
import typography from '@tailwindcss/typography';
const config: Config = {
content: [
'./src/pages/**/*.{js,ts,jsx,tsx,mdx}',
'./src/components/**/*.{js,ts,jsx,tsx,mdx}',
'./src/app/**/*.{js,ts,jsx,tsx,mdx}',
],
theme: {
extend: {
colors: {
border: 'hsl(var(--border))',
input: 'hsl(var(--input))',
ring: 'hsl(var(--ring))',
background: 'hsl(var(--background))',
foreground: 'hsl(var(--foreground))',
primary: {
DEFAULT: 'hsl(var(--primary))',
foreground: 'hsl(var(--primary-foreground))',
},
secondary: {
DEFAULT: 'hsl(var(--secondary))',
foreground: 'hsl(var(--secondary-foreground))',
},
destructive: {
DEFAULT: 'hsl(var(--destructive))',
foreground: 'hsl(var(--destructive-foreground))',
},
muted: {
DEFAULT: 'hsl(var(--muted))',
foreground: 'hsl(var(--muted-foreground))',
},
accent: {
DEFAULT: 'hsl(var(--accent))',
foreground: 'hsl(var(--accent-foreground))',
},
popover: {
DEFAULT: 'hsl(var(--popover))',
foreground: 'hsl(var(--popover-foreground))',
},
card: {
DEFAULT: 'hsl(var(--card))',
foreground: 'hsl(var(--card-foreground))',
},
zeus: {
50: '#f0f9ff',
100: '#e0f2fe',
200: '#bae6fd',
300: '#7dd3fc',
400: '#38bdf8',
500: '#0ea5e9',
600: '#0284c7',
700: '#0369a1',
800: '#075985',
900: '#0c4a6e',
950: '#082f49',
},
},
borderRadius: {
lg: 'var(--radius)',
md: 'calc(var(--radius) - 2px)',
sm: 'calc(var(--radius) - 4px)',
},
fontFamily: {
sans: ['var(--font-sans)', 'system-ui', 'sans-serif'],
mono: ['var(--font-mono)', 'monospace'],
},
animation: {
'fade-in': 'fadeIn 0.5s ease-in-out',
'slide-up': 'slideUp 0.3s ease-out',
'slide-down': 'slideDown 0.3s ease-out',
'scale-in': 'scaleIn 0.2s ease-out',
'spin-slow': 'spin 3s linear infinite',
},
keyframes: {
fadeIn: {
'0%': { opacity: '0' },
'100%': { opacity: '1' },
},
slideUp: {
'0%': { transform: 'translateY(10px)', opacity: '0' },
'100%': { transform: 'translateY(0)', opacity: '1' },
},
slideDown: {
'0%': { transform: 'translateY(-10px)', opacity: '0' },
'100%': { transform: 'translateY(0)', opacity: '1' },
},
scaleIn: {
'0%': { transform: 'scale(0.95)', opacity: '0' },
'100%': { transform: 'scale(1)', opacity: '1' },
},
},
boxShadow: {
'zeus': '0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)',
'zeus-lg': '0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)',
'zeus-xl': '0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)',
},
},
},
plugins: [typography],
} satisfies Config;
export default config;
Best Practices
- Use CSS variables for theming - Enables easy dark mode switching
- Organize styles in layers - Base, components, utilities
- Create reusable components - Consistent design patterns
- Use responsive design patterns - Mobile-first approach
- Implement dark mode - Accessibility and user preference
- Optimize for performance - Purge unused styles
- Use semantic class names - Maintainable code
- Document custom utilities - Team collaboration
Stop Conditions
STOP and report if:
- Tailwind CSS compilation fails
- CSS variables don't work
- Dark mode doesn't function
- Responsive design breaks
- Animation performance issues
Expected Outcomes:
- Tailwind CSS compiles successfully
- All custom styles work correctly
- Dark mode functions properly
- Responsive design works on all breakpoints
- Animations perform smoothly
Verification Checklist
- Tailwind CSS compiles without errors
- Custom colors and variables work
- Dark mode toggles correctly
- Responsive design works on all breakpoints
- Custom components render correctly
- Animations function properly
- Theme provider works
- CSS purging works in production
- No CSS conflicts exist
Version: 1.0.0 Last Updated: 2026-01-31 Skill Category: Architecture - Scaffolding
