Set up Tailwind v4 + shadcn/ui themed UI with dark mode. Install deps, configure CSS variables via @theme inline, wire dark mode toggle, verify. Use whenever the user mentions Tailwind v4, setting up Tailwind theming, shadcn/ui colours, dark mode, or troubleshooting colours not
Installs just this skill. Get the whole plugin for auto-invocation.
โก How it fires
How this skill gets triggered: by you, by Claude, or both.
Fires itselfClaude auto-loads it when your prompt matches the work.
You can call itInvoke it directly when you want it.
Slash command/tailwind-theme-builder
๐๏ธ Context preview
The summary Claude sees to decide when to auto-load this skill.
Set up Tailwind v4 + shadcn/ui themed UI with dark mode. Install deps, configure CSS variables via @theme inline, wire dark mode toggle, verify. Use whenever the user mentions Tailwind v4, setting up Tailwind theming, shadcn/ui colours, dark mode, or troubleshooting colours not
๐ Stats
Stars940
Forks96
LanguagePython
LicenseMIT
๐ฆ Ships with jezweb-skills
</> SKILL.md
tailwind-theme-builder.SKILL.md
---name: tailwind-theme-builder
description: "Set up Tailwind v4 + shadcn/ui themed UI with dark mode. Install deps, configure CSS variables via @theme inline, wire dark mode toggle, verify. Use whenever the user mentions Tailwind v4, setting up Tailwind theming, shadcn/ui colours, dark mode, or troubleshooting colours not working, tw-animate-css errors, @theme inline conflicts, @apply breaking after upgrade, or v3 โ v4 migration issues."
compatibility: claude-code-only
---# Tailwind Theme Builder
Set up a fully themed Tailwind v4 + shadcn/ui project with dark mode. Produces configured CSS, theme provider, and working component library.
## Architecture: The Four-Step Pattern
Tailwind v4 requires a specific architecture for CSS variable-based theming. This pattern is **mandatory** -- skipping or modifying steps breaks the theme.
### How It Works
```
CSS Variable Definition --> @theme inline Mapping --> Tailwind Utility Class
--background --> --color-background --> bg-background
(with hsl() wrapper) (references variable) (generated class)
```
Dark mode switching:
```
ThemeProvider toggles .dark class on <html>
--> CSS variables update automatically (.dark overrides :root)
--> Tailwind utilities reference updated variables
--> UI updates without re-render
/* 3. Apply base styles (NO hsl() wrapper here) */
@layer base {
body {
background-color: var(--background);
color: var(--foreground);
}
}
```
**Result:** `bg-background`, `text-primary` etc. work automatically. Dark mode switches via `.dark` class -- no `dark:` variants needed for semantic colours.
### Step 4: Set Up Dark Mode
Copy `assets/theme-provider.tsx` to your components directory, then wrap your app:
```typescript
import { ThemeProvider } from '@/components/theme-provider'
`cn()` from `@/lib/utils` properly merges and deduplicates Tailwind classes.
**#12 -- Radix Select empty value**
Radix UI Select does not allow empty string values. Use `value="placeholder"` instead of `value=""`.
**#14 -- Required dependencies**
```json
{
"dependencies": {
"tailwindcss": "^4.1.0",
"@tailwindcss/vite": "^4.1.0",
"clsx": "^2.1.1",
"tailwind-merge": "^3.3.1"
},
"devDependencies": {
"@types/node": "^24.0.0"
}
}
```
**#17 -- tw-animate-css**
`tailwindcss-animate` is deprecated in Tailwind v4. shadcn/ui docs may still reference it. Causes build failures and import errors. Use `tw-animate-css` or `@tailwindcss/motion` instead.
**#18 -- Duplicate @layer base after shadcn init**
`shadcn init` adds its own `@layer base` block. Check `src/index.css` immediately after running init and merge any duplicate blocks into one.
WRONG:
```css
@layer base { body { background-color: var(--background); } }
@layer base { * { border-color: hsl(var(--border)); } } /* duplicate from shadcn */
```
CORRECT:
```css
@layer base {
* { border-color: var(--border); }
body { background-color: var(--background); color: var(--foreground); }
}
```
### Prevention Checklist
- [ ] No `tailwind.config.ts` file (or it's empty)
- [ ] `components.json` has `"config": ""`
- [ ] All colors have `hsl()` wrapper in `:root`
- [ ] `@theme inline` maps all variables
- [ ] `@layer base` doesn't wrap `:root`
- [ ] Theme provider wraps app
- [ ] Tested in light, dark, and system modes
- [ ] All text has sufficient contrast
---
## Dark Mode Testing Checklist
- [ ] Light mode displays correctly
- [ ] Dark mode displays correctly
- [ ] System mode respects OS setting
- [ ] Theme persists after page refresh
- [ ] Toggle component shows current state
- [ ] All text has proper contrast
- [ ] No flash of wrong theme on load
- [ ] Works in incognito mode (graceful fallback)
---
## Asset Files
Copy from `assets/` directory:
- `index.css` -- Complete CSS with all colour variables
- `components.json` -- shadcn/ui v4 config
- `vite.config.ts` -- Vite + Tailwind plugin
- `theme-provider.tsx` -- Dark mode provider
- `utils.ts` -- `cn()` utility
## Reference Files
- `references/migration-guide.md` -- v3 to v4 migration