From frontend
Tailwind CSS v4 utility-first discipline: CSS-first configuration, design tokens via @theme, and principled class composition. Invoke whenever task involves any interaction with Tailwind CSS — writing, reviewing, refactoring, debugging, or understanding utility classes, theme configuration, custom utilities, dark mode, or Tailwind integration with frameworks.
npx claudepluginhub xobotyi/cc-foundry --plugin frontendThis skill uses the workspace's default tool permissions.
**Utility classes are the default. Custom CSS is the escape hatch.**
Generates design tokens/docs from CSS/Tailwind/styled-components codebases, audits visual consistency across 10 dimensions, detects AI slop in UI.
Records polished WebM UI demo videos of web apps using Playwright with cursor overlay, natural pacing, and three-phase scripting. Activates for demo, walkthrough, screen recording, or tutorial requests.
Delivers idiomatic Kotlin patterns for null safety, immutability, sealed classes, coroutines, Flows, extensions, DSL builders, and Gradle DSL. Use when writing, reviewing, refactoring, or designing Kotlin code.
Utility classes are the default. Custom CSS is the escape hatch.
**Tailwind builds on CSS fundamentals.** Before writing or reviewing Tailwind code, invoke the `css` skill to load specificity, box model, and layout knowledge.Skill(frontend:css)
Skip only for trivial class additions where no CSS reasoning is needed.
Tailwind CSS uses CSS-first configuration: design tokens live in @theme, custom utilities use @utility, and there is
no JavaScript configuration file. Constrain yourself to the design system; break out only with intention.
${CLAUDE_SKILL_DIR}/references/theme-configuration.md]: Theme tokens, @theme options, namespace
mapping, color system${CLAUDE_SKILL_DIR}/references/class-authoring.md]: Class composition, variants, dark mode,
breakpoints${CLAUDE_SKILL_DIR}/references/custom-utilities-and-variants.md]: @utility,
@custom-variant, directives, @source${CLAUDE_SKILL_DIR}/references/layout.md]: Display, position, flexbox, grid, alignment, order
utilities${CLAUDE_SKILL_DIR}/references/sizing-and-spacing.md]: Spacing scale, width/height, padding/margin,
borders, box model${CLAUDE_SKILL_DIR}/references/typography.md]: Font properties, text spacing, styling, decoration,
layout${CLAUDE_SKILL_DIR}/references/backgrounds-and-effects.md]: Gradients, shadows, rings, opacity,
SVG, filters${CLAUDE_SKILL_DIR}/references/transforms-and-animations.md]: Transitions, animations, 2D/3D
transforms, masks${CLAUDE_SKILL_DIR}/references/framework-integration.md]: Preflight, CSS Modules, class binding
(React, Vue, Svelte)@import "tailwindcss"; — provides preflight reset, theme variables, and all utilities. No
@tailwind base/components/utilities (v3 syntax)@tailwindcss/vite plugin. PostCSS: install @tailwindcss/postcss. CLI:
npx @tailwindcss/cli -i input.css -o output.csstailwind.config.js in v4 — all configuration lives in CSS via @themepostcss-import and autoprefixer — v4 handles both internally@import, nesting,
variables, vendor prefixes)@theme)@theme defines design tokens that generate utility classes — not equivalent to :root. Use @theme for values
needing utilities; use :root for CSS variables that only need var() access@theme must be top-level (not nested under selectors or media queries)@theme values compile to :root { } CSS vars in output--color-primary, --color-surface — not --color-blue-500 or --color-gray-100oklch(0.72 0.11 178) — perceptually uniform, works with CSS color-mix()@theme Options@theme { } — Default: only emit used vars@theme static { } — Always emit all vars@theme inline { } — Inline var() references into utility outputUse @theme inline when a token references another variable — prevents CSS variable resolution failures in the cascade.
--color-* → bg-*, text-*, border-*, ring-*, fill-*, stroke-*, etc.--font-* → font-* (family)--text-* → text-* (size)--font-weight-* → font-* (weight)--tracking-* → tracking-*--leading-* → leading-*--breakpoint-* → Responsive variants: sm:*, md:*--container-* → Container query variants: @sm:*, and max-w-*--spacing-* or --spacing → px-*, py-*, m-*, w-*, h-*, etc.--radius-* → rounded-*--shadow-* / --inset-shadow-* → shadow-* / inset-shadow-*--blur-* → blur-*--ease-* → ease-*--animate-* → animate-*Breakpoints generate variants, not utilities. Colors generate multiple utility families from a single namespace.
@theme--color-*: initial removes all defaults in that namespace--*: initial for fully custom theme--color-lime-*: initialblack and white--color-* token generates utilities across bg-*, text-*, border-*, ring-*, fill-*, stroke-*, etc.bg-sky-500/50 — per-property, not whole-element--alpha() for CSS opacity: compiles to color-mix(in oklab, ...)bg-opacity-* (removed in v4) — always bg-color/opacityPut @theme in a standalone CSS file and @import it after @import "tailwindcss".
text-red-600 yes, `text-${color}-600` never.
Tailwind scans source files as plain textprettier-plugin-tailwindcss — do not manually sort classesbg-(--brand-color) — parenthesis syntax auto-wraps in var(). Do not use
bg-[var(--brand)] (v3 verbose form)dark:lg:hover:bg-indigo-600. v3 was right-to-left — reverse stacking order
when migrating@themebg-red-500! — the ! goes at end, after all modifiersgrid-cols-[1fr_500px_2fr]. Escape for literal underscore:
content-['hello\_world']text-(length:--my-var) for font-size, text-(color:--my-var) for text colorUnprefixed = all sizes. Prefix = that breakpoint and up.
sm: — 40rem (640px)
md: — 48rem (768px)
lg: — 64rem (1024px)
xl: — 80rem (1280px)
2xl: — 96rem (1536px)
Don't use sm: to mean "mobile only" — it means 640px and up
Unprefixed for mobile base, override at breakpoints
Range targeting: md:max-xl:flex (only between md and xl)
Arbitrary breakpoints: min-[900px]:grid-cols-3
Custom breakpoints: define in @theme { --breakpoint-xs: 30rem; }
@container on parent, @md:flex-row on children@container/main + @sm/main:flex-col@3xs (16rem) through @7xl (80rem)@min-[475px]:flex-row--container-* in @themehover:, focus:, active:, visited:, focus-visible:, focus-within:, disabled:,
required:, invalid:, checked:, read-only:, indeterminate:, first:, last:, odd:, even:, empty:has-checked: (element has checked descendant), not-focus: (element is NOT focused)group on parent, group-hover:text-white on child. Named groups:
group/item + group-hover/item:visible for nested disambiguationin-focus:opacity-100peer on sibling, peer-invalid:visible on target. Named peers for
disambiguationhas-checked:bg-indigo-50, group-has-[a]:block, peer-has-checked:ring-2prefers-color-scheme media query — dark: works without config@custom-variant dark (&:where(.dark, .dark *));@custom-variant dark (&:where([data-theme=dark], [data-theme=dark] *));<head>, never in a deferred bundlecolor-scheme for native UI: scheme-light dark:scheme-dark on <html> matches scrollbars and form controls to
active theme@utilityutilities layer automatically and support all variants (hover:, focus:,
lg:, etc.)@utility content-auto { content-visibility: auto; }@utility scrollbar-hidden { &::-webkit-scrollbar { display: none; } }@utility tab-* with --value()--value() resolution modes: --value(--ns-*) (theme key), --value(integer) (bare value), --value([integer])
(arbitrary value), --value("inherit") (literal)--value(--tab-size-*, integer, [integer])--modifier() reads the modifier portion (text-lg/tight)-utility-* form@utility and @custom-variant over JS plugins for new code@custom-variant@custom-variant theme-midnight (&:where([data-theme="midnight"] *));@slot for multiple rules or media queriesdark variant for class-based toggling@variant: Apply variants in custom CSS: @variant dark { background: black; }@apply: Compose utilities into custom CSS — last resort only. Place in @layer components. Single-element
patterns only@reference: Import theme context in Vue/Svelte <style> blocks or CSS Modules without duplicating output CSS@plugin: Load JS plugins. CSS-native @utility/@custom-variant preferred@layer precedence: base < components < utilities. Utilities always win@source: Register additional scan paths, exclude paths, safelist with @source inline() using brace expansion--alpha(var(--color-lime-300) / 50%) → color-mix(in oklab, ...)--spacing(4) → calc(var(--spacing) * 4) — also valid in arbitrary valuestheme() is deprecated — use var(--color-red-500) instead@source).gitignored, node_modules, binaries, CSS files, lock files@source "../node_modules/@my-company/ui-lib" for external packages@source not "../src/legacy" to exclude directories@source inline("underline") for safelisting (brace expansion supported)@source not inline(...) to explicitly exclude from generation@import "tailwindcss" source(none) disables auto-detection entirely@import "tailwindcss" source("../src") sets base scan path@apply. In React/Vue/Svelte, extract a component. In server templates, extract a
partial. @apply is the last resort@apply only for single-element patterns — multi-element structures belong in template components@apply-based classes in @layer components so utilities can override@apply uses: third-party library overrides, legacy HTML you don't controlUse flex for 1D flow, grid for 2D placement. gap over margin hacks.
sr-only for visually hidden, screen-reader accessible; not-sr-only to reverse. hidden removes from flow;
invisible keeps spaceabsolute inset-0 (fill parent), sticky top-0 z-10 (sticky header)flex-1 (grow/shrink, ignore initial), flex-auto (respect initial), flex-none (fixed size)grid-cols-<n>, col-span-<n>, col-span-full, grid-flow-densegap-<n>, gap-x-<n>, gap-y-<n> — works in both flex and gridisolate creates a new stacking context without z-indexSee ${CLAUDE_SKILL_DIR}/references/layout.md for full display, position, flexbox, grid, alignment, order, and
visibility utility catalogs.
--spacing drives all spacing utilities. 1 unit = 0.25rem (4px). Customize: @theme { --spacing: 4px; }.
w-<n>, h-<n> (spacing scale), w-<fraction> (percentage), w-full, w-screen, w-dvw, h-dvh.
size-<n> sets bothmin-w-*, max-w-*, min-h-*, max-h-*p-* (all), px-*/py-*, ps-*/pe-* (logical)auto and negatives (-mt-4). mx-auto centers block elementsgap-* with flex/grid over space-x-<n> / space-y-<n>border, border-<n>, per-side (border-t, border-s/border-e)currentColor (v3 was gray-200) — always specify colordivide-x-<n>, divide-y-<n>, divide-{color} between childrenv4 scale shift: rounded without suffix maps to xs size (was md in v3). Per-side, per-corner, and logical
variants (rounded-s-*, rounded-ss-*) available. See ${CLAUDE_SKILL_DIR}/references/sizing-and-spacing.md for the
full scale table.
outline-hidden over outline-none — preserves outlines in forced-colors modefocus:outline-2 focus:outline-offset-2 focus:outline-sky-500box-border (default), box-content; overflow-auto, overflow-clipoverscroll-contain prevents scroll chainingSee ${CLAUDE_SKILL_DIR}/references/sizing-and-spacing.md for the full spacing scale, width/height keywords, container
scale, viewport units, and box model details.
font-sans, font-serif, font-mono. Custom via --font-* in @themetext-xs through text-9xl — each sets both font-size and default line-height. Override inline:
text-sm/6, text-lg/loosefont-thin (100) through font-black (900)tabular-nums for tables/pricing — composable, reset with normal-numstext-start/text-end over text-left/text-right for i18ntext-balance for headings, text-pretty to prevent orphans in body texttruncate for single-line overflow; line-clamp-<n> for multi-linetext-shadow-sm through text-shadow-lgSee ${CLAUDE_SKILL_DIR}/references/typography.md for full font properties, text spacing, styling, decoration, and text
layout utility catalogs.
bg-linear-to-r (not bg-gradient-to-r), bg-radial, bg-conic. Default interpolation is
oklabshadow-sm in v3 = shadow-xs in v4ring-3 for thick ringsbg-{color}/{opacity} — never bg-opacity-*fill-current inherits parent text color — idiomatic for icon componentsobject-cover + explicit dimensions for imagesaspect-square (1/1), aspect-video (16/9), aspect-3/2See ${CLAUDE_SKILL_DIR}/references/backgrounds-and-effects.md for full gradient, shadow, ring, filter, backdrop, and
mask utility catalogs.
transition-colors, transition-transform, transition-opacity — never
transition-allrotate-45 scale-110 translate-x-4--animate-* and @keyframes in @themetransform-3d for translate-z-*backdrop-blur-sm bg-white/30See ${CLAUDE_SKILL_DIR}/references/transforms-and-animations.md for full transition, animation, 2D/3D transform,
filter, and mask utility catalogs.
motion-safe: or disable with motion-reduce:transition-nonesr-only / not-sr-only for screen reader accessibilityforced-color-adjust-none only for elements where forced colors destroys essential visual information — always
include sr-only text labelforced-colors: variant for styles only in forced colors moderole="list" on unstyled lists — VoiceOver doesn't announce list-style: none elements as listsdisplay: blockcursor: default, placeholder is text color at 50% opacitytailwindcss/theme.css and tailwindcss/utilities.css individually<style>Each module is processed separately — causes slower builds and missing @theme context. Use @reference "../app.css"
in <style> blocks, or prefer CSS variables directly: background-color: var(--color-blue-500).
clsx for conditional composition, cva for variant APIs, cn = twMerge(clsx(...)) for className
overrides:class="{ 'bg-indigo-600': primary }" or array with cn()class={cn("rounded-md", primary && "bg-indigo-600", className)}When writing Tailwind CSS:
When reviewing Tailwind CSS:
The CSS skill is a prerequisite — it provides specificity, box model, and layout knowledge that Tailwind abstracts but does not replace. Framework skills handle class binding in each framework.
Utility classes are the default. When in doubt, keep configuration in @theme and styling in markup.