Theming

How it works

Every component reads semantic tokens only (--accent, --fg, --bg-canvas, --radius-panel…), which resolve from a two-tier scale: a raw foundation palette (--n-0 … --n-1000) mapped to roles. A theme just re-points those variables.

ThemeProvider applies a config on mount by setting the variables on <html> — the same runtime mutation the live Configurator (top-right) performs. Because it's just CSS variables, a theme cascades to every component instantly, with zero rebuilds.

Predefined Theme Presets

Shavin UI ships with 17 curated theme presets out of the box. Each preset bundles an accent color, gray scale family, radius, panel background style, and display/body typography pairing.

light
DefaultZinc
Neutral:Zinc
Radius:medium
Fonts:Space Grotesk
Mode:light
dark
LinearZinc
Neutral:Zinc
Radius:medium
Fonts:Inter
Mode:dark
light
NordicGray
Neutral:Gray
Radius:large
Fonts:Outfit
Mode:light
dark
VanguardZinc
Neutral:Zinc
Radius:medium
Fonts:Space Grotesk
Mode:dark
dark
CyberZinc
Neutral:Zinc
Radius:large
Fonts:JetBrains Mono
Mode:dark
light
EditorialStone
Neutral:Stone
Radius:medium
Fonts:Fraunces
Mode:light
dark
Neo TokyoZinc
Neutral:Zinc
Radius:medium
Fonts:Space Grotesk
Mode:dark
light
OasisStone
Neutral:Stone
Radius:large
Fonts:Outfit
Mode:light
light
OceanZinc
Neutral:Zinc
Radius:medium
Fonts:Space Grotesk
Mode:light
dark
VelvetSlate
Neutral:Slate
Radius:large
Fonts:Playfair Display
Mode:dark
light
MinimalGray
Neutral:Gray
Radius:small
Fonts:Outfit
Mode:light
light
WarmStone
Neutral:Stone
Radius:large
Fonts:Lora
Mode:light
light
PlayfulSlate
Neutral:Slate
Radius:large
Fonts:Space Grotesk
Mode:light
dark
SunsetStone
Neutral:Stone
Radius:large
Fonts:Outfit
Mode:dark
dark
MidnightZinc
Neutral:Zinc
Radius:medium
Fonts:Space Grotesk
Mode:dark
dark
TerminalZinc
Neutral:Zinc
Radius:none
Fonts:JetBrains Mono
Mode:dark

Smart Accent Token System

When you set an accent color (preset or hex), @shavin/ui dynamically computes a coordinated cluster of WCAG AAA accessible CSS custom properties:

--accent

Base brand accent RGB triplet (e.g. 62 99 221).

--accent-hover

Automatically mixed +12% lighter in dark mode or -12% darker in light mode for interactive hover states.

--accent-fg

Optimal text/icon foreground on solid accent buttons (10 10 12 or 255 255 255) via relative luminance.

--accent-contrast / --accent-text

Accessible accent text color guaranteeing contrast on soft surfaces (e.g. Lime darkened on white, Monochrome inverted in dark mode).

Config properties

accentColor

24 named presets (Monochrome, Grass, Blue, Iris…) or a literal #hex

grayColor

Zinc · Slate · Gray · Neutral · Stone — the neutral family

appearance

light · dark (toggled via the .dark class — app-controlled)

LightDark
radius

none · small · medium · large · full

scaling

90 · 95 · 100 · 105 · 110 (%) — density via root font-size

AAA
panelBackground

solid · translucent — popover/menu/dialog surfaces

SolidTranslucent
displayFont / bodyFont

heading & body font presets

DisplayBody

Declare a theme in code

Mount ThemeProvider once (e.g. at the app root, or drop it in bare as a fire-and-forget config step). This is exactly what the Configurator's Copy Theme button emits.

import { ThemeProvider } from "@shavin/ui";

export function App({ children }) {
  return (
    <ThemeProvider
      accentColor="Grass"        // preset name or "#rrggbb"
      grayColor="Slate"
      radius="medium"
      scaling={100}
      panelBackground="solid"
      displayFont="Space Grotesk"
      bodyFont="Inter"
    >
      {children}
    </ThemeProvider>
  );
}

Prefer no wrapper? Override the semantic variables directly — the components pick them up the same way:

:root {
  --accent: 70 167 88;      /* r g b — brand accent */
  --radius-lg: 0.5rem;
  --radius-panel: 0.75rem;
}
.dark {
  --accent: 86 202 106;     /* lighter accent for dark mode */
}

Foundation and semantic tokens are documented under Colors, Radius, and Shadows. Applying a preset name resolves to these same variables via applyAccentColor / applyGrayColor / applyThemePreset (exported for programmatic use).

Configure Theme
Theme
Accent Color
Custom
Gray Family
Appearance
Radius
Scaling
Panel Style
Heading Font
Body Font