Theme Studio
A live, browser-based editor for shadcn/ui color themes: pick a preset, tune the variables, share a URL, and copy paste-ready CSS.
Editor + live previewTheme Studio makes shadcn/ui's nineteen HSL theme variables directly editable, with an instant preview of real components and an exact @layer base block to paste back into a project. Doing this by hand means editing globals.css, reloading, and guessing. Built for developers who want to retheme without that trial-and-error.
The preview applies the theme you're editing as scoped CSS variables, so the ten real shadcn primitives inside it resolve to your colors through the normal cascade. The editor's own chrome reads a separate, fixed palette one level up. That separation lets you restyle any theme live without the tool reskinning itself out from under you.
HSL is the source of truth; hex only exists at the edges. The pickers and text fields speak hex, but the state, URL, and export all speak shadcn's own space-separated HSL, with a clean round-trip between them. The exported block comes out byte-identical to shadcn's native format, so it pastes straight in.
The URL stores deltas, not the whole theme. Only the variables you changed from a preset get serialized, so a clean preset link is just ?p=Ivory&m=light and shared links stay short. Sharing needs no backend at all.
ConfiguratorOne static Next.js App Router page renders a single client component. There is no API route, no database, and no auth anywhere in the tree. A theme is a plain in-memory object: a name plus a light and a dark record of nineteen HSL strings each, produced by five presets or a seed generator. Edits flow hex to HSL into one committed theme object that drives both the URL and the CSS export, while a parallel object holds the tweened values the preview renders during transitions. The only persistence is the URL.
Public and live at theme.javiertpadilla.com. Shipped: five light-and-dark presets, a one-color seed generator with live preview, per-variable editing across six collapsible groups, a light/dark toggle, animated preset transitions, URL sharing, copy-and-download export, a nine-section in-app guide, and a responsive mobile bottom sheet.
The morph animation works, but it's hand-coordinated across three copies of the render state with a requestAnimationFrame loop and a timeout safety net for throttled tabs; it wants to be a small state machine, and that's the first thing I'd refactor. I'd also make the corner-radius token editable rather than previewed-but-fixed, and add tests around the hex-to-HSL color math, which is exactly the pure logic that deserves them. Driving the preview and the export from one set of HSL values is the decision I'd keep.