agentsclimarketplace

Tailwind v4 shadcn setup

Skill S3YED/appie-kit/skills/design/tailwind-v4-shadcn-setup

Build Your Own AI Employee. The complete starter kit for OpenClaw + Hermes Agent. 155 deduplicated skills, drag-and-drop workspace, case studies, install scripts.

Install
npx -y skills add S3YED/appie-kit --skill tailwind-v4-shadcn-setup

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 6 stars6 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Set up Tailwind CSS v4 + shadcn/ui for a new Next.js SaaS project in 2026. Covers CSS-first @theme configuration, OKLCH colors, tw-animate-css, container queries, RSC optimization, and all critical gotchas.

SKILL.md

7.9 KB, as published. Nobody here has run it

Tailwind CSS v4 + shadcn/ui Setup for AI Agents

Use this skill when setting up a new Next.js project with Tailwind CSS v4 and shadcn/ui, or when writing code for one. It encodes all the critical gotchas that differ from Tailwind v3.

Quick Setup

# 1. Create Next.js project
npx create-next-app@latest my-app --typescript --tailwind --app

# 2. shadcn/ui init (auto-detects Tailwind v4)
npx shadcn@latest init

# 3. Add core components
npx shadcn@latest add button card input dialog tabs select form

# 4. Install tw-animate-css (replaces tailwindcss-animate)
npm install tw-animate-css

globals.css Template

This is the canonical globals.css for Tailwind v4 + shadcn/ui:

@import "tailwindcss";
@import "tw-animate-css";

@custom-variant dark (&:is(.dark *));

@theme inline {
  --radius-sm: calc(var(--radius) - 4px);
  --radius-md: calc(var(--radius) - 2px);
  --radius-lg: var(--radius);
  --radius-xl: calc(var(--radius) + 4px);

  --color-background: var(--background);
  --color-foreground: var(--foreground);
  --color-card: var(--card);
  --color-card-foreground: var(--card-foreground);
  --color-primary: var(--primary);
  --color-primary-foreground: var(--primary-foreground);
  --color-secondary: var(--secondary);
  --color-secondary-foreground: var(--secondary-foreground);
  --color-muted: var(--muted);
  --color-muted-foreground: var(--muted-foreground);
  --color-accent: var(--accent);
  --color-accent-foreground: var(--accent-foreground);
  --color-destructive: var(--destructive);
  --color-border: var(--border);
  --color-ring: var(--ring);
  --color-input: var(--input);
  --color-chart-1: var(--chart-1);
  --color-chart-2: var(--chart-2);
  --color-chart-3: var(--chart-3);
  --color-chart-4: var(--chart-4);
  --color-chart-5: var(--chart-5);
}

:root {
  --background: oklch(1 0 0);
  --foreground: oklch(0.145 0 0);
  --card: oklch(1 0 0);
  --card-foreground: oklch(0.145 0 0);
  --primary: oklch(0.205 0 0);
  --primary-foreground: oklch(0.985 0 0);
  --secondary: oklch(0.96 0.01 264);
  --secondary-foreground: oklch(0.205 0 0);
  --muted: oklch(0.96 0.01 264);
  --muted-foreground: oklch(0.46 0.02 264);
  --accent: oklch(0.96 0.01 264);
  --accent-foreground: oklch(0.205 0 0);
  --destructive: oklch(0.53 0.22 27);
  --destructive-foreground: oklch(0.985 0 0);
  --border: oklch(0.91 0.01 264);
  --input: oklch(0.91 0.01 264);
  --ring: oklch(0.205 0 0);
  --chart-1: oklch(0.55 0.22 250);
  --chart-2: oklch(0.63 0.18 170);
  --chart-3: oklch(0.45 0.14 40);
  --chart-4: oklch(0.68 0.19 300);
  --chart-5: oklch(0.58 0.16 10);
  --radius: 0.5rem;
}

.dark {
  --background: oklch(0.145 0 0);
  --foreground: oklch(0.985 0 0);
  --card: oklch(0.145 0 0);
  --card-foreground: oklch(0.985 0 0);
  --primary: oklch(0.922 0 0);
  --primary-foreground: oklch(0.205 0 0);
  --secondary: oklch(0.26 0.02 264);
  --secondary-foreground: oklch(0.985 0 0);
  --muted: oklch(0.26 0.02 264);
  --muted-foreground: oklch(0.64 0.02 264);
  --accent: oklch(0.26 0.02 264);
  --accent-foreground: oklch(0.985 0 0);
  --destructive: oklch(0.55 0.22 27);
  --destructive-foreground: oklch(0.985 0 0);
  --border: oklch(0.26 0.02 264);
  --input: oklch(0.26 0.02 264);
  --ring: oklch(0.84 0.01 264);
  --chart-1: oklch(0.65 0.22 250);
  --chart-2: oklch(0.70 0.18 170);
  --chart-3: oklch(0.68 0.14 40);
  --chart-4: oklch(0.72 0.19 300);
  --chart-5: oklch(0.65 0.16 10);
}

/* Override with your brand colors */
:root {
  --primary: oklch(0.55 0.22 250);        /* your brand blue */
  --primary-foreground: oklch(0.98 0 0);   /* white text on primary */
  --radius: 0.5rem;
}
.dark {
  --primary: oklch(0.70 0.18 250);         /* lighter for dark mode */
  --primary-foreground: oklch(0.10 0 0);   /* dark text on primary */
}

components.json Template

{
  "$schema": "https://ui.shadcn.com/schema.json",
  "style": "new-york",
  "rsc": true,
  "tsx": true,
  "tailwind": {
    "config": "",
    "css": "src/styles/globals.css",
    "baseColor": "neutral",
    "cssVariables": true,
    "prefix": ""
  },
  "iconLibrary": "lucide",
  "aliases": {
    "components": "@/shared/components",
    "utils": "@/shared/utils",
    "ui": "@/shared/components/ui",
    "lib": "@/lib",
    "hooks": "@/shared/hooks"
  }
}

Container Queries Pattern

Use container queries for truly reusable components:

// Parent — establish the container
<div className="@container">  {/* or @container/card for named */}
  <ProductCard />
</div>

// Child — respond to container, not viewport
function ProductCard() {
  return (
    <div className="flex flex-col @md:flex-row @lg:gap-8">
      <Image className="w-full @md:w-1/3" />
      <div>
        <h3 className="text-lg @md:text-xl @lg:text-2xl font-bold">Title</h3>
        <span className="hidden @sm:inline text-primary">$29.99</span>
      </div>
    </div>
  );
}

Critical Gotchas

#GotchaWhat to do
1tailwindcss-animate doesn't work in v4Use tw-animate-css instead — import in CSS: @import "tw-animate-css"
2OKLCH, not HSLshadcn 2.3.0+ uses OKLCH color space. Use oklch() not hsl()
3Container parent needs measurable widthFlex columns with no explicit width break container queries
4@md:md:@md: = container query, md: = viewport media query. Don't mix
5shadcn components.json needs "rsc": trueRequired for Server Component projects
6Static shadcn components are server-safeInteractive ones (Dialog, Dropdown) include 'use client' already — no need to wrap
7Tailwind v4 is incompatible with Sass/LessCSS-first @theme directive: Sass can't parse it. Use plain CSS
8No forwardRef in componentsv4 uses React.ComponentProps<typeof Button> + data-slot attributes
9Default style deprecatedNew projects use "style": "new-york" exclusively
10Toast deprecatedUse sonner instead

Design Token Hierarchy

Brand tokens (--brand-blue-500) → Semantic tokens (--color-primary) → Component tokens (--button-bg)

Use semantic tokens in your CSS. AI agents (Claude Code, Cursor) parse CSS variables more reliably than JS config files.

@theme {
  /* Brand tokens */
  --color-brand-blue: oklch(0.55 0.22 250);
  --color-brand-green: oklch(0.63 0.18 170);

  /* Semantic tokens (map brand values) */
  --color-primary: var(--color-brand-blue);
  --color-success: var(--color-brand-green);
}

RSC Optimization

  • Server components for all static Tailwind-styled UI (no 'use client')
  • Client islands only where state/events exist
  • Variant computation server-side with class composition, not runtime
// ✅ Server Component — styling is just inert strings
function ProductCard({ title, price }: { title: string; price: number }) {
  const sizeClass = price > 100 ? 'text-xl' : 'text-base';
  return (
    <div className="rounded-lg border p-4">
      <h2 className={`font-bold ${sizeClass}`}>{title}</h2>
    </div>
  );
}

Reference Documents

  • references/research-2026-07-02.md — Full research context with source URLs, MCP server evaluation table, and all 10 AI agent gotchas in one place.

MCP Servers for Tailwind (recommended)

Install these in your Hermes/Claude config:

{
  "mcpServers": {
    "tailwindcss-docs-mcp": {
      "command": "npx",
      "args": ["-y", "tailwindcss-docs-mcp"]
    },
    "designmcp-server": {
      "command": "npx",
      "args": ["-y", "@cdej-lgtm/designmcp-server"]
    }
  }
}
  • tailwindcss-docs-mcp: Local semantic search over Tailwind docs (v3 + v4)
  • designmcp-server: shadcn/ui theming with OKLCH color science===ME:tailwind-v4-shadcn-setup

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.