🎁 Get the FREE AI Skills Starter Guide β€” Subscribe β†’
BytesAgainBytesAgain
πŸ¦€ ClawHub

shadcn-tailwind

by @tenequm

Build UIs with Tailwind CSS v4 and shadcn/ui. Covers CSS variables with OKLCH colors, component variants with CVA, responsive design, dark mode, and Tailwind...

Versionv0.1.1
Downloads424
TERMINAL
clawhub install shadcn-tailwind

πŸ“– About This Skill


name: shadcn-tailwind description: Build UIs with Tailwind CSS v4 and shadcn/ui. Covers CSS variables with OKLCH colors, component variants with CVA, responsive design, dark mode, and Tailwind v4.2 features. Supports Radix UI and Base UI primitives, CLI 3.0, and visual styles. Use when building interfaces with Tailwind, styling shadcn/ui components, implementing themes, or working with utility-first CSS. Triggers on tailwind, shadcn, utility classes, CSS variables, OKLCH, component styling, theming, dark mode, radix ui. metadata: version: "0.1.1"

Styling with Tailwind CSS

Build accessible UIs using Tailwind CSS v4 utility classes and shadcn/ui component patterns. Tailwind v4 uses CSS-first configuration only - never create or modify tailwind.config.js/tailwind.config.ts. Supports Radix UI (default) or Base UI as primitive libraries.

Critical Rules

No tailwind.config.js - CSS-First Only

Tailwind v4 configures everything in CSS. Migrate any JS/TS config:

  • theme.extend.colors β†’ @theme { --color-*: ... }
  • plugins β†’ @plugin "..." or @utility
  • content β†’ @source "..."
  • tailwindcss-animate β†’ @import "tw-animate-css"
  • @layer utilities β†’ @utility name { ... }
  • Always Use Semantic Color Tokens

    // CORRECT - respects themes and dark mode
    

    // WRONG - breaks theming

    Always pair bg-* with text-*-foreground. Extend with success/warning/info in theming.md.

    Never Build Class Names Dynamically

    // WRONG - breaks Tailwind scanner
    
    bg-${color}-500}>

    // CORRECT - complete strings via lookup const colorMap = { red: "bg-red-500", blue: "bg-blue-500" } as const

    cn() Merge Order

    Defaults first, consumer className last (tailwind-merge last-wins):

    className={cn(buttonVariants({ variant, size }), className)}  // correct
    className={cn(className, buttonVariants({ variant, size }))}  // wrong
    

    Animation Performance

    // WRONG - transition-all causes layout thrashing
    

    // CORRECT - transition only what changes

    // CORRECT - respect reduced motion

    @theme vs @theme inline

  • @theme - static tokens, overridable by plugins
  • @theme inline - references CSS variables, follows dark mode changes
  • @theme { --color-brand: oklch(0.6 0.2 250); }          /* static */
    @theme inline { --color-primary: var(--primary); }       /* dynamic */
    

    See components.md for more pitfalls and theming.md for color system reference.

    Core Patterns

    CSS Variables for Theming

    shadcn/ui uses semantic CSS variables mapped to Tailwind utilities:

    /* globals.css - Light mode */
    :root {
      --background: oklch(1 0 0);
      --foreground: oklch(0.145 0 0);
      --primary: oklch(0.205 0 0);
      --primary-foreground: oklch(0.985 0 0);
      --muted: oklch(0.97 0 0);
      --muted-foreground: oklch(0.556 0 0);
      --border: oklch(0.922 0 0);
      --radius: 0.5rem;
    }

    /* Dark mode */ .dark { --background: oklch(0.145 0 0); --foreground: oklch(0.985 0 0); --primary: oklch(0.922 0 0); --primary-foreground: oklch(0.205 0 0); }

    /* Tailwind v4: Map variables */ @theme inline { --color-background: var(--background); --color-foreground: var(--foreground); --color-primary: var(--primary); }

    Usage in components:

    // Background colors omit the "-background" suffix
    

    Component Authoring Pattern

    Components use plain functions with data-slot attributes (React 19 - no forwardRef):

    import { cva, type VariantProps } from "class-variance-authority"
    import { cn } from "@/lib/utils"

    const buttonVariants = cva( "inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 disabled:pointer-events-none disabled:opacity-50", { variants: { variant: { default: "bg-primary text-primary-foreground shadow hover:bg-primary/90", destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90", outline: "border border-input bg-background hover:bg-accent", ghost: "hover:bg-accent hover:text-accent-foreground", link: "text-primary underline-offset-4 hover:underline", }, size: { default: "h-9 px-4 py-2", sm: "h-8 px-3 text-xs", lg: "h-10 px-8", icon: "size-9", }, }, defaultVariants: { variant: "default", size: "default" }, } )

    // Plain function with React.ComponentProps (not forwardRef) function Button({ className, variant, size, ...props }: React.ComponentProps<"button"> & VariantProps) { return (

    Icon spacing with data-icon:

    Responsive Design

    Mobile-first breakpoints:

    // Stack on mobile, grid on tablet+
    

    // Hide on mobile

    // Different layouts per breakpoint

    // Responsive text sizes

    Container Queries

    First-class in Tailwind v4, no plugin needed:

    Responds to container width, not viewport

    // Named containers

    Dark Mode

    // Use dark: prefix - but prefer semantic colors over manual dark: overrides
    
    // auto dark mode
    // manual override

    // Use next-themes for toggle: useTheme() β†’ setTheme("dark" | "light") // Always add suppressHydrationWarning to to prevent flash

    Common Component Patterns

    Card

    Title

    Description

    Content
    Footer

    Form Field

    Helper text

    Badge

    const badgeVariants = cva(
      "inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors",
      {
        variants: {
          variant: {
            default: "border-transparent bg-primary text-primary-foreground shadow",
            secondary: "border-transparent bg-secondary text-secondary-foreground",
            destructive: "border-transparent bg-destructive text-destructive-foreground",
            outline: "text-foreground",
          },
        },
      }
    )
    

    Layout Patterns

    Centered Layout

    {/* Content */}

    Sidebar Layout

    Content

    Dashboard Grid

    Wide card Regular Regular Full width

    Accessibility Patterns

    Focus Visible

    Screen Reader Only

    Close dialog
    

    Disabled States

    Tailwind v4 Features

    CSS-First Configuration

    @import "tailwindcss";

    /* Custom utilities (replaces @layer utilities) */ @utility tab-highlight-none { -webkit-tap-highlight-color: transparent; }

    /* Custom variants */ @custom-variant pointer-fine (@media (pointer: fine));

    /* Source control */ @source inline("{hover:,}bg-red-{50,100,200}"); @source not "./legacy";

    @theme Directive

    @theme {
      --color-primary: oklch(0.205 0 0);
      --font-sans: "Inter", system-ui;
    }

    /* With CSS variables (shadcn/ui pattern) */ @theme inline { --color-primary: var(--primary); }

    Animation

    @import "tw-animate-css";
    

    v4.1 Features

    // Text shadows
    

    // Gradient masks for fade effects

    Fades to transparent at bottom

    // Pointer-aware sizing

    v4.2 Features (February 2026)

    // Logical block properties (RTL/writing-mode aware)
    

    // Logical sizing (replaces w-*/h-* for logical layouts)

    // Font feature settings

    Tabular numbers

    // New color palettes: mauve, olive, mist, taupe

    Deprecation: start-*/end-* deprecated in favor of inset-s-*/inset-e-*.

    OKLCH Colors

    All shadcn/ui colors use OKLCH format: oklch(lightness chroma hue). Lightness 0-1, chroma 0-0.4 (0 = gray), hue 0-360. Base palettes: Neutral, Zinc, Slate, Stone, Gray. See theming.md for complete palettes and OKLCH reference.

    Best Practices

    Prefer Semantic Colors

    // Good - uses theme
    

    // Avoid - hardcoded

    Group Related Utilities

    Avoid Arbitrary Values

    // Prefer design tokens
    

    // Avoid when unnecessary

    Installation & CLI

    # Create new project with visual style + primitive selection
    npx shadcn create

    Initialize in existing project

    pnpm dlx shadcn@latest init

    Add components

    pnpm dlx shadcn@latest add button card form

    Add from community registries

    npx shadcn add @acme/button @internal/auth-system

    View/search registries

    npx shadcn view @acme/auth-system npx shadcn search @tweakcn -q "dark" npx shadcn list @acme

    Add MCP server for AI integration

    npx shadcn@latest mcp init

    Update existing components

    pnpm dlx shadcn@latest add button --overwrite

    Visual Styles

    npx shadcn create offers 5 built-in visual styles:

  • Vega - Classic shadcn/ui look
  • Nova - Compact, reduced padding
  • Maia - Soft and rounded, generous spacing
  • Lyra - Boxy and sharp, pairs with mono fonts
  • Mira - Dense, for data-heavy interfaces
  • These rewrite component code (not just CSS variables) to match the selected style.

    Troubleshooting

    Colors not updating: Check CSS variable in globals.css β†’ verify @theme inline includes the mapping β†’ clear build cache.

    Dark mode flash on load: Add suppressHydrationWarning to tag and ensure ThemeProvider wraps app with attribute="class".

    Found tailwind.config.js: Delete it. Run npx @tailwindcss/upgrade to auto-migrate to CSS-first config. All customization belongs in your CSS file via @theme, @utility, @plugin.

    Classes not detected: Check @source directives cover your component paths. Never construct class names dynamically (see Critical Rules).

    Component Patterns

    For detailed component patterns see components.md:

  • Composition: asChild pattern, data-slot attributes
  • Typography: Heading scales, prose styles, inline code
  • Forms: React Hook Form + Zod, Field component with FieldSet/FieldGroup
  • Icons: Lucide icons with data-icon attributes
  • Inputs: OTP, file, grouped inputs
  • Dialogs: Modal patterns and composition
  • Data Tables: TanStack table integration
  • Toasts: Sonner notifications
  • Pitfalls: cn() order, form defaultValues, dialog nesting, sticky, server/client
  • Resources

    See theming.md for complete color system reference:

  • @theme vs @theme inline (critical for dark mode)
  • Status color extensions (success, warning, info)
  • Z-index scale and animation tokens
  • All base palettes (Neutral, Zinc, Slate, Stone, Gray)
  • Summary

    Key concepts:

  • v4 CSS-first only - no tailwind.config.js, all config in CSS
  • Semantic colors only - never use raw palette (bg-blue-500), always bg-primary
  • Always pair bg-* with text-*-foreground
  • Never build class names dynamically - use object lookup with complete strings
  • cn() order - defaults first, consumer className last
  • No transition-all - transition only specific properties
  • @theme inline for dynamic theming, @theme for static tokens
  • Author components as plain functions with data-slot (React 19)
  • Apply CVA for component variants
  • Use motion-safe: / motion-reduce: for animations
  • Choose Radix UI or Base UI as primitive library
  • This skill targets Tailwind CSS v4.2 with shadcn/ui. For component-specific examples, see components.md. For color system, see theming.md.

    πŸ“‹ Tips & Best Practices

    Prefer Semantic Colors

    // Good - uses theme
    

    // Avoid - hardcoded

    Group Related Utilities

    Avoid Arbitrary Values

    // Prefer design tokens
    

    // Avoid when unnecessary