Nocturne

Command Palette

Search for a command to run...

From Figma Tokens to Tailwind v4 CSS Variables

June 25, 2026 · 8 min read · by Abhishek

Tailwind v4 dropped tailwind.config.js in favour of a pure CSS configuration model. This turns out to be the best thing to happen to design token workflows — CSS variables defined in Tailwind’s @theme block become utility classes automatically.

Tailwind v4’s @theme block

@import "tailwindcss";
 
@theme {
  --color-highlight: oklch(0.68 0.20 265);
  --color-accent-1:  oklch(0.72 0.17 265);
}

This generates text-highlight, bg-highlight, border-highlight, and every other colour utility — no plugin, no config. The variable name maps directly to the utility name.

Exporting from Figma

Use the Tokens Studio (formerly Style Dictionary) Figma plugin to export your colour styles as a JSON token file:

{
  "color": {
    "highlight": { "value": "#7aa2f7", "type": "color" },
    "accent-1":  { "value": "#bb9af7", "type": "color" }
  }
}

Then run a small transform script to convert hex values to OKLCH and emit CSS variables:

import { formatHex, oklch, parse } from "culori"
 
function hexToOklch(hex: string): string {
  const c = oklch(parse(hex))!
  return `oklch(${c.l.toFixed(3)} ${c.c.toFixed(3)} ${c.h?.toFixed(1) ?? 0})`
}

The transform pipeline

Figma Tokens Studio
      ↓ export JSON
tokens.json
      ↓ transform script
theme.css  (@theme block with OKLCH values)
      ↓ import in globals.css
Tailwind utilities auto-generated
StepTool
DesignFigma + Tokens Studio
ExportJSON token file
TransformNode script (culori)
ConsumeTailwind v4 @theme

Multi-theme with data attributes

Nocturne takes this one step further — the @theme block defines the default (Tokyo Night) and per-theme overrides use html[data-site-theme] selectors:

@theme {
  --color-primary:   oklch(0.72 0.17 265);
  --color-highlight: oklch(0.68 0.20 265);
}
 
html[data-site-theme="mocha"] {
  --color-primary:   oklch(0.80 0.15 305);
  --color-highlight: oklch(0.82 0.12 350);
}

Switching themes is a single setAttribute("data-site-theme", id) call — no CSS class churn, no JS-in-CSS tricks.

Syncing Figma and code

The workflow becomes a one-way sync: Figma is the source of truth, the transform script produces the CSS. For Nocturne, palette sources come from @catppuccin/palette and @rose-pine/palette npm packages — versioned, testable, and diffable. Run pnpm sync:themes to regenerate all theme CSS from their latest palette definitions.

This work by Abhishek is licensed under CC BY 4.0 .

Published June 25, 2026.