Your CSS in, a complete light and dark theme out.
shadcn gives you a handful of colors at setup. Everything after that is hand-editing every variable in globals.css — then doing the whole thing again for the .dark block.
Drop in your Tailwind stylesheet, change the colors you care about, and get the file back with the rest derived — foregrounds, chart scale, sidebar, and a dark block that was generated, not copied.
Every field group previews real primitives in the theme you’re building.
How it works
Paste a file or start from the shadcn preset. Either way you leave with CSS, not a config account.
- 01
Pick your colors
Hex for primary, secondary and accent. Every field is prefilled from your file, and anything you leave alone keeps the value it already had.
- 02
The rest is derived
Foregrounds are re-derived to clear a 4.5:1 contrast floor. One hex becomes the five-step chart scale. The whole dark block is generated from your light colors, not copied from shadcn's.
- 03
Copy or download
You get your own file back with only the variable blocks rewritten. Comments, imports and formatting survive byte-for-byte.
Works with the globals.css you already have
No migration, no lock-in, no rewrite of your stylesheet. It reads the file, edits the variables, and hands the rest back untouched.
Tailwind v4
@theme inline plus oklch() — the exact shape shadcn generates today.
Your syntax
Edits are written back in whatever format the var already used — oklch(), hsl(), rgb() or hex — with alpha carried over.
Hand-rolled
Any stylesheet with a :root block. Imports, custom variants, keyframes, plugin CSS and every untouched declaration survive byte-for-byte.
The honest limit
The editable fields are the shadcn token set. Other variables in your :root are read, counted, previewed and preserved — they just aren't editable here.
Nothing leaves your machine
Parsing, derivation and preview all run entirely in the browser. Your globals.css is never uploaded.
Questions
What kind of globals.css does it accept?
Any stylesheet with a :root block, whether it sits at the top level or inside @layer base. Edits are written back in whatever color format your file already uses, and every declaration you didn't touch survives byte-for-byte.
Does it overwrite my globals.css?
No. You get a copy back. Only the variables you actually changed are rewritten — imports, comments, keyframes, plugin CSS and every untouched declaration survive byte-for-byte.
How is the dark theme generated?
It is derived from your light colors rather than copied from shadcn's defaults. Surfaces anchor in a near-black and stack upward by elevation, brand colors keep their hue and lift into a readable band, and text is chosen by measured contrast against the surface it lands on. Any derived value can be overridden by hand.
Do I need a shadcn project?
No. Any stylesheet with a :root block works. Give it no file at all and it generates a fresh theme from the shadcn preset.
What about @media (prefers-color-scheme: dark)?
Not currently supported. Dark values are read and written from class-style selectors only: .dark, :root.dark, html.dark and [data-theme="dark"]. A :root block nested inside a prefers-color-scheme media query is deliberately skipped so it is never mistaken for the base one.
Is my CSS uploaded anywhere?
No. Parsing, derivation and preview all run in your browser. Nothing is sent to a server, and there is no sign-up.
Three hex values. One file back.
No account, no upload, no migration.