Skip to content
Tailwind CSS Setup logo

Tailwind CSS Setup

> **Skill Purpose:** CSS framework configuration and styling system patterns

Coverage-Creatives/zeus0installs0stars

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:

  1. Define styling system requirements and design tokens
  2. Configure CSS framework and build process
  3. Set up custom themes and component styling
  4. Establish responsive design patterns
  5. 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

  1. Use CSS variables for theming - Enables easy dark mode switching
  2. Organize styles in layers - Base, components, utilities
  3. Create reusable components - Consistent design patterns
  4. Use responsive design patterns - Mobile-first approach
  5. Implement dark mode - Accessibility and user preference
  6. Optimize for performance - Purge unused styles
  7. Use semantic class names - Maintainable code
  8. 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