Use when migrating Tailwind v3 to v4, configuring CSS-first @theme tokens, debugging Oxide engine errors, dealing with the absence of tailwind.config.js, container queries (@container) usage, layer cascade problems, or "dynamic class names not generating". Triggers: switching from `@tailwind base` to `@import "tailwindcss"`, RSC/Next.js streaming + CSS ordering, dark-mode strategy choices, custom variants via @variant, content-scanning glob tuning. NOT for Tailwind v3 (different config model), CSS-in-JS frameworks, vanilla CSS architecture (BEM/SMACSS), or react-native styling.
Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Une commande directe contourne le prompt de vérification. Examinez la source avant de l'exécuter.
Use when migrating Tailwind v3 to v4, configuring CSS-first @theme tokens, debugging Oxide engine errors, dealing with the absence of tailwind.config.js, container queries (@container) usage, layer cascade problems, or "dynamic class names not generating". Triggers: switching from `@tailwind base` to `@import "tailwindcss"`, RSC/Next.js streaming + CSS ordering, dark-mode strategy choices, custom variants via @variant, content-scanning glob tuning. NOT for Tailwind v3 (different config model), CSS-in-JS frameworks, vanilla CSS architecture (BEM/SMACSS), or react-native styling.
metadata
{"category":"Frontend & UI","tags":["tailwind","css","design-tokens","oxide","container-queries","frontend"],"provenance":{"kind":"first-party","owners":["port-daddy"]},"pairs-with":[{"skill":"web-design-expert","reason":"Owns the design decisions (layout, hierarchy, visual voice) that this skill's @theme tokens and utilities implement."},{"skill":"color-contrast-auditor","reason":"The @theme color tokens defined here should pass its contrast checks in both light and dark variants."},{"skill":"ideal-web-app-builder","reason":"The app-scaffolding skill whose Next.js/globals.css setup this skill's v4 import model plugs into."}],"io-contract":{"kind":"deliverable","consumes":["[Truncated]","[Truncated]"],"produces":["[Truncated]","[Truncated]"]}}
Tailwind v4 Expert
Tailwind v4 is a different tool than v3. The PostCSS-based JIT engine is gone, replaced by Oxide (Rust). The JS config file is gone, replaced by CSS-first @theme blocks. Plugins from v3 mostly need rewriting. If you're migrating, expect to rebuild — not patch — your config layer.
When to use
Migrating a v3 project (look for @tailwind base; @tailwind components; @tailwind utilities;).
Need design tokens (colors, fonts, breakpoints) consumed by both Tailwind and raw CSS.
Container queries — designing components that adapt to their container, not the viewport.
Custom variants beyond what v4 ships (@variant focus-within-sibling, etc.).
Dynamic class names disappearing from the build (Oxide can't see what isn't statically present).
There is no tailwind.config.js. There is no content array. @source adds globs to the default scan root (the file's dir + project conventions). Oxide statically scans these for class strings.
These tokens generate utilities (text-brand-500, font-display, 3xl:, w-128) AND are accessible as var(--color-brand-500) in raw CSS. One source of truth.
Namespaces that auto-generate utilities:
Token prefix
Generates
--color-*
text-*, bg-*, border-*, outline-*, etc.
--font-*
font-*
--text-*
text-* (font-size; pair with --text-*--line-height)
--spacing-*
m-*, p-*, w-*, h-*, gap-*, etc.
--breakpoint-*
sm:, md:, lg:… variants
--radius-*
rounded-*
--shadow-*
shadow-*
@layer cascade
@layer base {
body { @apply font-sans text-zinc-900; }
}
@layer components {
.btn { @apply rounded-lg px-4 py-2 font-semibold; }
}
/* Custom layer between components and utilities */@layer my-overrides {
.proseimg { border-radius: var(--radius-lg); }
}
Layers cascade: base → components → utilities → arbitrary user layers. Tailwind defines its own at @layer base, components, utilities; automatically; you rarely need to redeclare them.
Put @import "tailwindcss" and @theme in app/globals.css.
Import that file once in app/layout.tsx.
For RSC streaming, ensure the CSS link is in <head> (Next does this automatically when imported from layout).
Server Components can use Tailwind classes directly; no client boundary needed.
If you ship a workspace @my-org/ui package, add @source "../../packages/ui/**/*.{ts,tsx}" to your globals so Oxide scans it.
Anti-patterns
Dynamic class names that Oxide can't see
Symptom:text-${color}-500 works in dev, missing in production.
Diagnosis: Oxide is a static scanner — it sees string literals, not template strings.
Fix: Map the dynamic value to a literal class:
Or use CSS variables for the dynamic part: style={{ '--accent': color }} class="bg-[--accent]".
Migrating but keeping tailwind.config.js
Symptom: v4 builds, but custom theme tokens don't appear; warnings about unknown directives.
Diagnosis: v4 ignores tailwind.config.js. The presence of one suggests an incomplete migration.
Fix: Move theme.extend values into @theme, plugins into @variant/CSS, content into @source. Delete the file. Run npx @tailwindcss/upgrade@latest for an automated first pass.
@apply for everything
Symptom: CSS bundle bigger than v3, "components" file is 2000 lines of @apply.
Diagnosis: Each @apply inlines utilities; deeply-applied components don't dedupe well.
Fix: Apply once at the component boundary; compose via class strings (clsx/cva) for variants.
Forgetting @source for files outside the project root
Symptom: UI library shipped from a sibling workspace — its classes don't appear in production CSS.
Diagnosis: Default scan covers the project's own files. Workspace deps need explicit @source.
Fix:@source "../../packages/ui/src/**/*.{ts,tsx}" (relative to the CSS file, not the project root).
PurgeCSS-style mental model
Symptom: Engineers add classes to a "safelist" that doesn't exist.
Diagnosis: v4 doesn't purge — it generates. There's no allowlist; if the class isn't in a scanned file, it doesn't exist.
Fix: Use a stub component or comment that contains the literal classes:
// Tailwind safelist (do not delete): bg-red-500 bg-green-500 bg-blue-500constSTATUS_COLORS = { error: 'bg-red-500', ok: 'bg-green-500', info: 'bg-blue-500' };
v3 plugins copy-pasted into v4
Symptom:Plugin "tailwindcss/typography" failed to load.Diagnosis: v4's plugin API is incompatible with most v3 plugins.
Fix: Use the v4-native plugin (@tailwindcss/typography v0.6+ for v4), or rewrite the plugin's effects with @variant / @layer components / custom utilities.
Quality gates
No template-literal class strings without an explicit safelist or CSS-variable fallback.
tailwind.config.js deleted (or absent from a fresh project).
Every workspace dep with Tailwind classes has an @source glob.
Dark-mode strategy documented in one place; not scattered across components.
CSS bundle <50KB gzipped for a typical app; <30KB for a marketing page.
Container queries used wherever a component is reused at different widths (cards, sidebars).
Theme tokens accessible from raw CSS (var(--color-brand-500)) and from utilities.
Deterministic Audit
Before committing to a v4 setup or migration (or reviewing another agent's), write it
as a JSON plan matching schemas/tailwind-v4-plan.schema.json and run the deterministic
auditor:
auditTailwindV4(plan) (in scripts/tailwind_v4_audit.mjs) turns this skill's
anti-patterns and Quality Gates into machine-checkable rules over structured fields —
no keyword matching: v3 @tailwind directives in a v4 build, a surviving
tailwind.config.js, template-literal class names Oxide cannot see, workspace deps
with Tailwind classes but no @source glob, a scattered dark-mode strategy, unported
v3 plugins, and a CSS bundle over budget. It returns
{ pass, score, findings, recommendations }. examples/sample-input.json is a
completed v4 migration plan (pass: true). Version history lives in CHANGELOG.md.
NOT for
Tailwind v3 — different config model, different engine.
CSS-in-JS (Emotion, styled-components) — pair with css-in-js-architect skill.
Vanilla CSS architecture (BEM, SMACSS, ITCSS) — different paradigm.
React Native — Tailwind variants for RN exist but have different constraints.
Before calling any rendered page, artifact, dashboard, deck, or component done,
run the mechanical overflow/collision checker. It renders the page headlessly and
flags text-vs-text collisions, clipped/ellipsis-truncated elements, text escaping
its container, and horizontal page scroll — the visual defects a screenshot hides
and that only appear at a specific width or in one theme.
Resolve layout-overflow-guard from the active skill catalog before running it.
The command below shows the standard Claude install path; use the path reported
by your harness. If the skill is absent, install or sync it instead of skipping
this gate.
You do not need to read check_layout.py — invoke it with the Bash tool and
act on its report and exit code (non-zero = a defect). The script's source never
enters your context; only its findings do. Drive it to zero violations across
every width and both themes before you ship. Full detail: the
layout-overflow-guard skill.