Tailwind css
Skill a5c-ai/babysitter/library/specializations/web-development/skills/tailwind-css
Babysitter enforces obedience on agentic workforces and enables them to manage extremely complex tasks and workflows through deterministic, hallucination-free self-orchestration
npx -y skills add a5c-ai/babysitter --skill tailwind-cssAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
What its author says it does
Copied from the file, not written here
Tailwind CSS configuration, custom plugins, design systems, theming, and component patterns for modern web applications.
SKILL.md
13.0 KB, as published. Nobody here has run it
Tailwind CSS Skill
Expert assistance for Tailwind CSS configuration, custom design systems, plugin development, and component styling patterns.
Capabilities
- Configure Tailwind CSS for various frameworks
- Create custom design tokens and themes
- Build reusable component patterns
- Develop custom Tailwind plugins
- Implement dark mode and theming
- Optimize production builds
Usage
Invoke this skill when you need to:
- Set up Tailwind CSS in a project
- Create a custom design system
- Build component style patterns
- Implement theming and dark mode
- Optimize Tailwind configuration
Inputs
| Parameter | Type | Required | Description |
|---|---|---|---|
| framework | string | No | react, nextjs, vue, vanilla |
| features | array | No | dark-mode, custom-colors, typography, forms, animations |
| designTokens | object | No | Custom colors, spacing, fonts |
| plugins | array | No | Tailwind plugins to include |
Configuration Example
{
"framework": "nextjs",
"features": ["dark-mode", "typography", "forms", "animations"],
"designTokens": {
"colors": {
"primary": "#3B82F6",
"secondary": "#10B981"
},
"fontFamily": {
"sans": "Inter",
"mono": "JetBrains Mono"
}
},
"plugins": ["@tailwindcss/typography", "@tailwindcss/forms"]
}
Output Structure
project/
├── tailwind.config.ts # Main configuration
├── postcss.config.js # PostCSS configuration
├── app/
│ └── globals.css # Global styles and layers
├── lib/
│ └── tailwind/
│ ├── plugins/
│ │ └── custom-plugin.ts
│ └── presets/
│ └── design-system.ts
└── components/
└── ui/
├── button.tsx # Component with variants
└── card.tsx
Generated Code Patterns
Tailwind Configuration
// tailwind.config.ts
import type { Config } from 'tailwindcss';
import typography from '@tailwindcss/typography';
import forms from '@tailwindcss/forms';
import animate from 'tailwindcss-animate';
const config: Config = {
darkMode: 'class',
content: [
'./pages/**/*.{js,ts,jsx,tsx,mdx}',
'./components/**/*.{js,ts,jsx,tsx,mdx}',
'./app/**/*.{js,ts,jsx,tsx,mdx}',
],
theme: {
extend: {
colors: {
primary: {
50: '#eff6ff',
100: '#dbeafe',
200: '#bfdbfe',
300: '#93c5fd',
400: '#60a5fa',
500: '#3b82f6',
600: '#2563eb',
700: '#1d4ed8',
800: '#1e40af',
900: '#1e3a8a',
950: '#172554',
},
secondary: {
50: '#ecfdf5',
100: '#d1fae5',
200: '#a7f3d0',
300: '#6ee7b7',
400: '#34d399',
500: '#10b981',
600: '#059669',
700: '#047857',
800: '#065f46',
900: '#064e3b',
950: '#022c22',
},
},
fontFamily: {
sans: ['var(--font-inter)', 'system-ui', 'sans-serif'],
mono: ['var(--font-jetbrains-mono)', 'monospace'],
},
animation: {
'fade-in': 'fadeIn 0.5s ease-in-out',
'slide-up': 'slideUp 0.3s 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' },
},
},
spacing: {
'18': '4.5rem',
'88': '22rem',
'128': '32rem',
},
borderRadius: {
'4xl': '2rem',
},
},
},
plugins: [typography, forms, animate],
};
export default config;
Global Styles
/* 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.1%;
--secondary-foreground: 222.2 47.4% 11.2%;
--muted: 210 40% 96.1%;
--muted-foreground: 215.4 16.3% 46.9%;
--accent: 210 40% 96.1%;
--accent-foreground: 222.2 47.4% 11.2%;
--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 47.4% 11.2%;
--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% 48%;
}
}
@layer base {
* {
@apply border-border;
}
body {
@apply bg-background text-foreground;
font-feature-settings: "rlig" 1, "calt" 1;
}
}
@layer components {
.btn {
@apply inline-flex items-center justify-center rounded-md text-sm font-medium
transition-colors focus-visible:outline-none focus-visible:ring-2
focus-visible:ring-ring focus-visible:ring-offset-2
disabled:opacity-50 disabled:pointer-events-none;
}
.btn-primary {
@apply btn bg-primary text-primary-foreground hover:bg-primary/90;
}
.btn-secondary {
@apply btn bg-secondary text-secondary-foreground hover:bg-secondary/80;
}
.btn-outline {
@apply btn border border-input bg-background hover:bg-accent
hover:text-accent-foreground;
}
.btn-ghost {
@apply btn hover:bg-accent hover:text-accent-foreground;
}
.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;
}
.card {
@apply rounded-lg border bg-card text-card-foreground shadow-sm;
}
}
@layer utilities {
.text-balance {
text-wrap: balance;
}
.animate-in {
animation-duration: 150ms;
animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
animation-fill-mode: both;
}
.fade-in {
animation-name: fadeIn;
}
.slide-in-from-top {
--tw-enter-translate-y: -100%;
animation-name: slideInFromTop;
}
}
Button Component with Variants
// components/ui/button.tsx
import { forwardRef } from 'react';
import { cva, type VariantProps } from 'class-variance-authority';
import { cn } from '@/lib/utils';
const buttonVariants = cva(
'inline-flex items-center justify-center whitespace-nowrap 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',
{
variants: {
variant: {
default: 'bg-primary text-primary-foreground hover:bg-primary/90',
destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/90',
outline: 'border border-input bg-background hover:bg-accent hover:text-accent-foreground',
secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',
ghost: 'hover:bg-accent hover:text-accent-foreground',
link: 'text-primary underline-offset-4 hover:underline',
},
size: {
default: 'h-10 px-4 py-2',
sm: 'h-9 rounded-md px-3',
lg: 'h-11 rounded-md px-8',
icon: 'h-10 w-10',
},
},
defaultVariants: {
variant: 'default',
size: 'default',
},
}
);
export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {
asChild?: boolean;
}
const Button = forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant, size, ...props }, ref) => {
return (
<button
className={cn(buttonVariants({ variant, size, className }))}
ref={ref}
{...props}
/>
);
}
);
Button.displayName = 'Button';
export { Button, buttonVariants };
Custom Plugin
// lib/tailwind/plugins/custom-plugin.ts
import plugin from 'tailwindcss/plugin';
export const customPlugin = plugin(
function ({ addUtilities, addComponents, matchUtilities, theme }) {
// Add custom utilities
addUtilities({
'.text-shadow': {
textShadow: '0 2px 4px rgba(0, 0, 0, 0.1)',
},
'.text-shadow-md': {
textShadow: '0 4px 8px rgba(0, 0, 0, 0.12)',
},
'.text-shadow-lg': {
textShadow: '0 8px 16px rgba(0, 0, 0, 0.15)',
},
'.text-shadow-none': {
textShadow: 'none',
},
});
// Add custom components
addComponents({
'.skeleton': {
animation: 'pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite',
backgroundColor: theme('colors.muted'),
borderRadius: theme('borderRadius.md'),
},
});
// Add dynamic utilities
matchUtilities(
{
'text-shadow': (value) => ({
textShadow: value,
}),
},
{ values: theme('textShadow') }
);
},
{
theme: {
textShadow: {
sm: '0 1px 2px rgba(0, 0, 0, 0.05)',
DEFAULT: '0 2px 4px rgba(0, 0, 0, 0.1)',
md: '0 4px 8px rgba(0, 0, 0, 0.12)',
lg: '0 8px 16px rgba(0, 0, 0, 0.15)',
},
},
}
);
Utility Functions
// lib/utils.ts
import { type ClassValue, clsx } from 'clsx';
import { twMerge } from 'tailwind-merge';
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}
Dark Mode Implementation
Theme Provider
// components/theme-provider.tsx
'use client';
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>;
}
Theme Toggle
// components/theme-toggle.tsx
'use client';
import { Moon, Sun } from 'lucide-react';
import { useTheme } from 'next-themes';
import { Button } from '@/components/ui/button';
export function ThemeToggle() {
const { setTheme, theme } = useTheme();
return (
<Button
variant="ghost"
size="icon"
onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}
>
<Sun className="h-5 w-5 rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
<Moon className="absolute h-5 w-5 rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
<span className="sr-only">Toggle theme</span>
</Button>
);
}
Dependencies
{
"dependencies": {
"clsx": "^2.1.0",
"tailwind-merge": "^2.5.0",
"class-variance-authority": "^0.7.0"
},
"devDependencies": {
"tailwindcss": "^3.4.0",
"postcss": "^8.4.0",
"autoprefixer": "^10.4.0",
"@tailwindcss/typography": "^0.5.0",
"@tailwindcss/forms": "^0.5.0",
"tailwindcss-animate": "^1.0.0"
}
}
Workflow
- Install Tailwind - Set up with framework
- Configure theme - Colors, fonts, spacing
- Create CSS layers - Base, components, utilities
- Build components - With variants using CVA
- Implement dark mode - CSS variables + provider
- Optimize production - Purge unused styles
Best Practices Applied
- CSS variables for theming
- Class variance authority for variants
- Tailwind merge for className conflicts
- Semantic color naming
- Mobile-first responsive design
- Accessible focus states
References
- Tailwind CSS Documentation: https://tailwindcss.com/docs
- shadcn/ui: https://ui.shadcn.com/
- Class Variance Authority: https://cva.style/docs
- tailwind-merge: https://github.com/dcastil/tailwind-merge
Target Processes
- design-system-setup
- component-styling
- theming-dark-mode
- responsive-design
- accessibility-styling