Sutra UI uses CSS custom properties (variables) for theming, making it easy to customize colors, spacing, and more without modifying component code.

CSS Variables Overview

All theme values are defined as CSS custom properties in :root. Override them in your app.css after importing sutra_ui.css.

@import "../../deps/sutra_ui/priv/static/sutra_ui.css";

/* Your theme overrides */
:root {
  --primary: oklch(0.65 0.20 145);
  --primary-foreground: oklch(0.98 0 0);
}

Color Variables Reference

Core Colors

VariableDescriptionUsage
--backgroundPage backgroundMain app background
--foregroundDefault text colorBody text
--cardCard backgroundsCards, panels
--card-foregroundCard textText on cards
--popoverPopover/dropdown backgroundsMenus, tooltips
--popover-foregroundPopover textText in popovers

Interactive Colors

VariableDescriptionUsage
--primaryPrimary brand colorButtons, links, focus rings
--primary-foregroundText on primaryButton text
--secondarySecondary actionsSecondary buttons
--secondary-foregroundText on secondarySecondary button text
--accentHover/active statesHighlights
--accent-foregroundText on accentHighlight text

Semantic Colors

VariableDescriptionUsage
--destructiveError/danger colorDelete buttons, errors
--destructive-foregroundText on destructiveError button text
--mutedMuted backgroundsDisabled states
--muted-foregroundMuted textPlaceholders, hints

UI Colors

VariableDescriptionUsage
--borderBorder colorDividers, outlines
--inputInput border colorForm field borders
--ringFocus ring colorFocus indicators

Other

VariableDescriptionDefault
--radiusBase border radius0.5rem

OKLCH Color Format

Sutra UI uses OKLCH colors for better perceptual uniformity across the color spectrum.

--primary: oklch(0.623 0.214 259.815);
/*         oklch(L     C     H      )
           L = Lightness (0-1)
           C = Chroma (0-0.4, saturation)
           H = Hue (0-360, color wheel)
*/

Common Hue Values

ColorHue Range
Red~25-35
Orange~60-80
Yellow~95-110
Green~140-160
Cyan~190-210
Blue~250-270
Purple~290-310
Pink~340-360

Example: Creating a Green Theme

:root {
  /* Green primary */
  --primary: oklch(0.65 0.20 145);
  --primary-foreground: oklch(0.98 0 0);
  
  /* Complementary destructive (red) */
  --destructive: oklch(0.55 0.25 30);
  --destructive-foreground: oklch(0.98 0 0);
}

Using shadcn/ui Themes

Sutra UI uses the same CSS variable names as shadcn/ui, so you can copy themes directly!

Step 1: Visit shadcn/ui Themes

Go to ui.shadcn.com/themes and customize a theme.

Step 2: Copy the CSS Variables

Click "Copy code" and paste into your app.css:

@import "../../deps/sutra_ui/priv/static/sutra_ui.css";

/* Paste shadcn theme here - it just works! */
:root {
  --background: oklch(1 0 0);
  --foreground: oklch(0.141 0.005 285.823);
  --card: oklch(1 0 0);
  --card-foreground: oklch(0.141 0.005 285.823);
  --popover: oklch(1 0 0);
  --popover-foreground: oklch(0.141 0.005 285.823);
  --primary: oklch(0.21 0.006 285.885);
  --primary-foreground: oklch(0.985 0 0);
  --secondary: oklch(0.967 0.001 286.375);
  --secondary-foreground: oklch(0.21 0.006 285.885);
  --muted: oklch(0.967 0.001 286.375);
  --muted-foreground: oklch(0.552 0.016 285.938);
  --accent: oklch(0.967 0.001 286.375);
  --accent-foreground: oklch(0.21 0.006 285.885);
  --destructive: oklch(0.577 0.245 27.325);
  --border: oklch(0.92 0.004 286.32);
  --input: oklch(0.92 0.004 286.32);
  --ring: oklch(0.705 0.015 286.067);
  --radius: 0.5rem;
}

.dark {
  --background: oklch(0.141 0.005 285.823);
  --foreground: oklch(0.985 0 0);
  /* ... dark mode variables */
}

Dark Mode

Sutra UI includes full dark mode support. Dark mode is activated by adding the dark class to the <html> element.

Using the Theme Switcher

The easiest way to add dark mode is with the built-in theme switcher:

<.theme_switcher />

This renders a button that toggles between light, dark, and system themes.

Manual Control

Toggle dark mode programmatically:

// Enable dark mode
document.documentElement.classList.add('dark')

// Disable dark mode
document.documentElement.classList.remove('dark')

// Toggle
document.documentElement.classList.toggle('dark')

Respecting System Preference

To automatically match the user's system preference:

if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
  document.documentElement.classList.add('dark')
}

Dark Mode Variables

Define dark mode overrides inside .dark:

:root {
  --background: oklch(1 0 0);
  --foreground: oklch(0.1 0 0);
}

.dark {
  --background: oklch(0.1 0 0);
  --foreground: oklch(0.95 0 0);
}

Per-Component Customization

You can override styles for specific components using CSS:

/* Custom button styles */
.btn {
  --radius: 9999px;  /* Fully rounded buttons */
}

/* Custom card styles */
.card {
  --radius: 1rem;  /* Larger radius for cards */
}

Complete Theme Example

Here's a complete custom theme:

@import "../../deps/sutra_ui/priv/static/sutra_ui.css";

:root {
  /* Brand colors - Blue theme */
  --primary: oklch(0.6 0.2 260);
  --primary-foreground: oklch(0.98 0 0);
  
  /* Backgrounds */
  --background: oklch(0.99 0.002 260);
  --foreground: oklch(0.15 0.01 260);
  
  /* Cards & Surfaces */
  --card: oklch(1 0 0);
  --card-foreground: oklch(0.15 0.01 260);
  --popover: oklch(1 0 0);
  --popover-foreground: oklch(0.15 0.01 260);
  
  /* Secondary & Muted */
  --secondary: oklch(0.95 0.01 260);
  --secondary-foreground: oklch(0.2 0.02 260);
  --muted: oklch(0.95 0.01 260);
  --muted-foreground: oklch(0.5 0.02 260);
  --accent: oklch(0.95 0.01 260);
  --accent-foreground: oklch(0.2 0.02 260);
  
  /* Semantic */
  --destructive: oklch(0.55 0.25 25);
  --destructive-foreground: oklch(0.98 0 0);
  
  /* Borders */
  --border: oklch(0.9 0.01 260);
  --input: oklch(0.9 0.01 260);
  --ring: oklch(0.6 0.2 260);
  
  /* Radius */
  --radius: 0.5rem;
}

.dark {
  --primary: oklch(0.7 0.18 260);
  --primary-foreground: oklch(0.1 0 0);
  
  --background: oklch(0.12 0.01 260);
  --foreground: oklch(0.95 0.005 260);
  
  --card: oklch(0.15 0.01 260);
  --card-foreground: oklch(0.95 0.005 260);
  --popover: oklch(0.15 0.01 260);
  --popover-foreground: oklch(0.95 0.005 260);
  
  --secondary: oklch(0.2 0.01 260);
  --secondary-foreground: oklch(0.9 0.005 260);
  --muted: oklch(0.2 0.01 260);
  --muted-foreground: oklch(0.6 0.02 260);
  --accent: oklch(0.25 0.02 260);
  --accent-foreground: oklch(0.9 0.005 260);
  
  --destructive: oklch(0.6 0.22 25);
  --destructive-foreground: oklch(0.98 0 0);
  
  --border: oklch(0.25 0.01 260);
  --input: oklch(0.25 0.01 260);
  --ring: oklch(0.5 0.15 260);
}

Next Steps