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.

Tailwind v4Shadcn Theme GenerationNo sign-upRuns in your browserCopy-paste ready
Core colorsPreview
Primary *
#FF9E20#6D5CFF#22A06B
Secondary *
#215E61#1F2B4D#103B2C
Accent *
#D0F1BF#D9D5FF#CDEEDD

Every field group previews real primitives in the theme you’re building.

Light
ButtonBadge
Dark · derived
ButtonBadge
Three steps

How it works

Paste a file or start from the shadcn preset. Either way you leave with CSS, not a config account.

  1. 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.

  2. 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.

  3. 03

    Copy or download

    You get your own file back with only the variable blocks rewritten. Comments, imports and formatting survive byte-for-byte.

Compatibility

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.

Dark blocks it finds.dark:root.darkhtml.dark[data-theme="dark"]

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.

FAQ

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.

Open the editor