Tailwind Adapter
Tailwind Adapter
Tailwind CSS v4 integration patterns for Variable Contract. Generate CSS custom properties from Variable Contract JSON using Tailwind CSS v4’s CSS-first approach.
Role
Tailwind adapter generates CSS custom properties from Variable Contract JSON. Variables map to Tailwind CSS v4’s @theme directive. No JavaScript config files. Pure CSS.
Why Tailwind CSS v4
Tailwind CSS v4 is pure CSS. No JavaScript config. Design Engineers MUST master Tailwind CSS v4. Variable Contract variables map directly to CSS custom properties that Tailwind CSS v4 consumes.
Tailwind CSS v4 approach
Tailwind CSS v4 uses CSS-first configuration:
- Define theme in CSS using
@themedirective - Use CSS custom properties (CSS theme variables)
- No
tailwind.config.jsfile needed - Aligns with native web standards
- Dynamic utility values (spacing scale accepts any value)
- Automatic content detection (no
contentarray needed) - Built-in import support (no
postcss-importneeded)
See Tailwind CSS v4 documentation for complete details.
Integration patterns
Pattern 1: CSS custom properties
Generate CSS custom properties from Variable Contract JSON. Tailwind CSS v4 reads CSS variables directly.
Style Dictionary config:
{
"source": ["tokens/**/*.json"],
"platforms": {
"css": {
"transformGroup": "css",
"buildPath": "dist/",
"files": [
{
"destination": "theme.css",
"format": "css/variables"
}
]
}
}
}
Generated output (dist/theme.css):
@import "tailwindcss";
@theme {
/* Colors */
--color-primary-500: #0066cc;
--color-primary-50: #e6f2ff;
--color-primary-900: #003366;
--color-text-primary: #1a1a1a;
--color-text-secondary: #666666;
--color-surface-brand: var(--color-primary-500);
/* Spacing */
--spacing-xs: 0.25rem;
--spacing-sm: 0.5rem;
--spacing-md: 1rem;
--spacing-lg: 1.5rem;
--spacing-xl: 2rem;
/* Typography */
--font-family-sans: "Inter", system-ui, sans-serif;
--font-size-base: 1rem;
--font-size-lg: 1.125rem;
}
Component usage:
<button className="bg-surface-brand text-white px-4 py-2">
Click me
</button>
Pattern 2: Direct CSS generation
Transform Variable Contract JSON directly to CSS custom properties.
Variable Contract:
{
"color": {
"primary": {
"500": {
"$type": "color",
"$value": "#0066cc"
}
},
"surface": {
"brand": {
"$type": "color",
"$value": "{color.primary.500}"
}
}
},
"spacing": {
"md": {
"$type": "dimension",
"$value": "1rem"
}
}
}
Generated CSS:
@import "tailwindcss";
@theme {
--color-primary-500: #0066cc;
--color-surface-brand: var(--color-primary-500);
--spacing-md: 1rem;
}
Variable mapping
Colors
Variable Contract: color.primary.500
CSS: --color-primary-500: #0066cc
Tailwind: bg-primary-500 or text-primary-500
Spacing
Variable Contract: spacing.md
CSS: --spacing-md: 1rem
Tailwind: p-md or m-md
Tailwind CSS v4 uses a dynamic spacing scale. The --spacing variable defines the base unit, and utilities like px-8, mt-17, w-29 are generated dynamically using calc(var(--spacing) * N).
Typography
Variable Contract: typography.fontFamily.sans
CSS: --font-family-sans: "Inter", sans-serif
Tailwind: font-sans
Modes support
Tailwind CSS v4 handles modes via CSS custom properties. Generate mode-specific CSS or use CSS variable overrides.
Variable Contract with modes:
{
"color": {
"surface": {
"background": {
"$type": "color",
"$value": {
"light": "#ffffff",
"dark": "#000000"
}
}
}
}
}
Generated CSS:
@theme {
--color-surface-background: #ffffff; /* default: light */
}
@media (prefers-color-scheme: dark) {
@theme {
--color-surface-background: #000000; /* dark mode */
}
}
Design Engineer requirements
Design Engineer MUST:
- Master Tailwind CSS v4 CSS-first approach
- Understand CSS custom properties and
@themedirective - Map Variable Contract structure to CSS custom properties
- Test variables in Tailwind components before approval
- Maintain CSS generation pipeline (no JavaScript config)
Workflow
- Designer creates variables in Figma
- Export from Figma
- Design Engineer normalizes with adapter
- Design Engineer generates CSS custom properties from Variable Contract JSON
- Design Engineer tests variables in Tailwind CSS v4 components
- Commit Variable Contract JSON and generated CSS
- Frontend Developer consumes Tailwind utilities in components
Example component
Variable Contract:
{
"color": {
"surface": {
"brand": {
"$type": "color",
"$value": "{color.primary.500}"
}
}
}
}
Generated CSS:
@import "tailwindcss";
@theme {
--color-primary-500: #0066cc;
--color-surface-brand: var(--color-primary-500);
}
Component usage:
<button className="bg-surface-brand text-white px-4 py-2">
Click me
</button>
Tailwind CSS v4 generates: background-color: var(--color-surface-brand)
Validation
Tailwind adapter MUST:
- Generate valid CSS custom properties syntax
- Map all Variable Contract variables to CSS custom properties
- Preserve variable references (use CSS
var()syntax) - Handle modes (generate mode-specific CSS or CSS variable overrides)
- Follow Tailwind CSS v4 naming conventions (
--color-*,--spacing-*,--font-*)
Failure modes
If Tailwind adapter fails:
- Variables don’t map to CSS custom properties (wrong structure)
- CSS syntax errors (invalid custom property names)
- Missing variables in CSS (generation incomplete)
- Mode values not handled (light/dark themes broken)
- Wrong naming convention (Tailwind CSS v4 doesn’t recognize variables)
Installation
Tailwind CSS v4 installation:
Install Tailwind CSS:
npm i tailwindcss @tailwindcss/postcssAdd PostCSS plugin:
export default { plugins: ["@tailwindcss/postcss"], };Import Tailwind in CSS:
@import "tailwindcss";
For Vite projects, use @tailwindcss/vite plugin instead. See Tailwind CSS v4 installation guide for details.
Out of scope
- Tailwind utility class generation (use Tailwind’s built-in utilities)
- Custom Tailwind plugins (separate concern)
- JavaScript config files (Tailwind CSS v4 doesn’t use them)
- Vite/PostCSS setup details (see Tailwind CSS v4 docs)