Theming
How to customise colors, switch themes, and make the design system your own
Why First — The Scenario
Your CA firm has a brand color — maybe a deep navy blue or a forest green. Every client presentation, every letter heading, every Excel report uses that color. It's on the website, the business cards, the email signature.
When you build an app for yourself or a client, it should carry that brand. Not the default shadcn blue that a thousand other apps use.
Theming is how you make the design system yours. And the key insight is this: you change the color in one place, and every single component updates automatically. Every button, every input focus ring, every badge, every link — all of them pull from the same definition.
The CSS Variables System
When shadcn/ui was set up, it added a block of CSS variables to your src/index.css file. These variables define the entire color palette for your app.
Here's what a typical section of that file looks like:
Every shadcn/ui component references these variables. The button's background color is hsl(var(--primary)). The input's focus ring is hsl(var(--ring)). Change the variable, change every component at once.
Understanding HSL Color Values
The values you see — like 222.2 47.4% 11.2% — are in HSL format (Hue, Saturation, Lightness). This is more intuitive than hex codes once you understand it:
| Part | What it controls | Range |
|---|---|---|
| H — Hue | The color itself | 0–360 (think of a color wheel: 0=red, 120=green, 240=blue) |
| S — Saturation | How vivid or gray | 0% = gray, 100% = full color |
| L — Lightness | How light or dark | 0% = black, 50% = normal, 100% = white |
You don't need to calculate these by hand. The shadcn/ui theme generator does it for you.
Notice there are no commas in the HSL values. The format 221 83% 53% (no commas) is used because the variables are consumed as hsl(var(--primary)) — the hsl() function wraps the value. This is a standard CSS custom property pattern.
Changing the Color Theme
Method 1 — Use the shadcn/ui Theme Generator (Recommended)
The fastest way to pick a theme:
Go to ui.shadcn.com/themes
Click through the color options on the left sidebar. The preview on the right updates live — you can see buttons, cards, inputs, and charts all update together.
When you find a color you like, click "Copy code" at the top right.
Paste the copied code into your src/index.css, replacing the existing :root and .dark blocks.
Save the file. Every component in your app immediately updates to the new color.
Method 2 — Edit Variables Directly
If you want a specific color for a client's branding:
- Find the HSL value for your brand color. Use a tool like hslpicker.com — pick your color, copy the HSL values.
- Update
--primaryand--ringin:rootwith your values. - Update the corresponding values in
.darkwith a slightly adjusted version for dark backgrounds.
Changing Border Radius
The --radius variable controls how rounded your corners are. One change affects all buttons, cards, inputs, and dialogs:
You can preview different radius settings on the ui.shadcn.com/themes page — there's a radius slider in the panel.
Dark Mode Implementation
shadcn/ui's CSS variables handle dark mode natively. You just need a way to toggle it. The standard approach uses the class strategy — adding a dark class to the <html> element.
Installing a Theme Toggle
Add the toggle component:
Then create a theme toggle component:
In practice, Claude handles this. Tell Claude: "Add a dark mode toggle to my navbar that switches between light, dark, and system modes" and it will set up the complete implementation. Understanding how it works helps you debug issues when they arise.
Writing Dark Mode Classes
For your own custom components (not shadcn/ui), add dark: variants for dark mode:
Common Theme Customisation Examples
Professional / Corporate (CA firm, legal)
Modern SaaS / Tech
Clean / Minimal
Friendly / Consumer
The Key Insight
You are not applying colors to individual components. You are defining a color system, and every component reads from it.
When a client asks you to change the app color from blue to green, you change four or five CSS variable values. Every button, every focused input, every link, every badge in the entire app updates instantly. This is the power of the design token system.
The alternative — manually going through every component and updating colors — is exactly what Tailwind's system is designed to eliminate.