GitHub
Core
Glass
Brutal
Humanist

Theming

Versa UI ships with a powerful multi-theme architecture built on CSS custom properties (design tokens). Each theme defines a complete set of tokens that control colours, typography, spacing, corner radii, shadows, and effects — and every component adapts automatically.

Use the theme switcher in the navigation bar to preview all four themes in real time.


Available Themes

Versa UI includes 4 visual themes, each with light and dark modes:

ThemeDescription
coreClean, modern design with soft shadows and rounded corners
glassmorphismFrosted glass effects with layered depth
brutalismBold, high-contrast design with sharp edges
humanistRefined, luxurious, and sophisticated

Importing Themes

Import theme CSS files in your main stylesheet, after primitives.css:

Core Theme (Free)

/* Design tokens */
@import "@versaui/ui/react/styles/primitives.css";

/* Core theme — included free */
@import "@versaui/ui/react/styles/themes/core.css";

Glassmorphism Theme (Pro)

@import "@versaui/ui/react/styles/themes/glassmorphism.css";

Brutalism Theme (Pro)

@import "@versaui/ui/react/styles/themes/brutalism.css";

Humanist Theme (Pro)

@import "@versaui/ui/react/styles/themes/humanist.css";

Import only the themes you plan to use. Each theme CSS file is self-contained — importing multiple themes adds support for runtime switching between them.


Activating a Theme

Set the active theme and colour mode using data-theme and data-mode attributes on your root element:

<html data-theme="core" data-mode="light">
  <!-- or -->
<html data-theme="brutalism" data-mode="dark">

All Versa UI components will automatically adapt to the active theme and mode.


Dynamic Theme Switching

Toggle themes and modes programmatically at runtime:

function ThemeSwitcher() {
  const setTheme = (theme: 'core' | 'glassmorphism' | 'brutalism' | 'humanist') => {
    document.documentElement.dataset.theme = theme;
  };

  const setMode = (mode: 'light' | 'dark') => {
    document.documentElement.dataset.mode = mode;
  };

  return (
    <div>
      <button onClick={() => setTheme('core')}>Core Theme</button>
      <button onClick={() => setTheme('glassmorphism')}>Glassmorphism Theme</button>
      <button onClick={() => setTheme('brutalism')}>Brutalism Theme</button>
      <button onClick={() => setTheme('humanist')}>Humanist Theme</button>
      <button onClick={() => setMode('light')}>Light Mode</button>
      <button onClick={() => setMode('dark')}>Dark Mode</button>
    </div>
  );
}

System Preference Detection

Respect the user's system colour scheme preference:

import { useEffect } from 'react';

function useSystemColorScheme() {
  useEffect(() => {
    const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
    
    const updateMode = (e: MediaQueryListEvent | MediaQueryList) => {
      document.documentElement.dataset.mode = e.matches ? 'dark' : 'light';
    };

    updateMode(mediaQuery);
    mediaQuery.addEventListener('change', updateMode);
    
    return () => mediaQuery.removeEventListener('change', updateMode);
  }, []);
}

Typography per Theme

Each theme uses a different combination of font families. All fonts are loaded via the Google Fonts import in your CSS.

ThemeDisplay (H1–H5)Title (H6–H9)BodyCode
CoreManropeManropeManropeDM Mono
BrutalismSpace GroteskSpace GroteskDM SansDM Mono
GlassmorphismDM SansDM SansDM SansDM Mono
HumanistDM Serif DisplayPlus Jakarta SansPlus Jakarta SansDM Mono

Customizing Themes

Versa UI is fully customizable. All styling is controlled via CSS custom properties (tokens), making it easy to adapt the design system to your brand.

Changing Fonts

Override the typography tokens in your CSS to use your own brand fonts:

@layer base {
  :root {
    /* Replace with your brand fonts */
    --typography-font-family-body: 'Inter', system-ui, sans-serif;
    --typography-font-family-display: 'Poppins', system-ui, sans-serif;
    --typography-font-family-title: 'Inter', system-ui, sans-serif;
    
    /* Adjust font weights if needed */
    --typography-font-weight-body: 400;
    --typography-font-weight-display: 700;
    --typography-font-weight-title: 600;
  }
}

Don't forget to import your custom fonts:

@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300..700&family=Poppins:wght@400;600;700&display=swap');

Changing Brand Colors

Override the brand color tokens to match your brand palette:

@layer base {
  :root {
    /* Primary brand color (used for buttons, links, focus states) */
    --color-brand-primary-medium: #6366F1;    /* Main brand color */
    --color-brand-primary-strong: #4F46E5;    /* Darker shade */
    --color-brand-primary-stronger: #4338CA;  /* Even darker */
    --color-brand-primary-subtle: #818CF8;    /* Lighter shade */
    --color-brand-primary-subtler: #C7D2FE;   /* Even lighter */
    --color-brand-primary-subtlest: #EEF2FF;  /* Lightest/background */
    
    /* Secondary, tertiary, quaternary colors follow same pattern */
    --color-brand-secondary-medium: #8B5CF6;
    --color-brand-secondary-strong: #7C3AED;
    /* ... */
  }
  
  /* Dark mode overrides */
  [data-mode="dark"] {
    --color-brand-primary-medium: #818CF8;
    --color-brand-primary-strong: #A5B4FC;
    --color-brand-primary-subtle: #4F46E5;
    --color-brand-primary-subtler: #312E81;
    --color-brand-primary-subtlest: #1E1B4B;
  }
}

Use a tool like Realtime Colors or Coolors to generate a harmonious color palette, then map the shades to the Versa UI token structure.

Changing Corner Radius, Spacing & Shadows

@layer base {
  :root {
    /* Corner radius — default and thematic */
    --corner-radius-default-medium: 8px;
    --corner-radius-thematic-medium: 6px;

    /* Spacing scale (1–13) */
    --spacing-4: 8px;
    --spacing-6: 16px;
    --spacing-8: 24px;

    /* Elevation shadows */
    --elevation-small-1-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
    --elevation-medium-1-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.06);
    --elevation-large-1-shadow: 0 3px 12px 0 rgba(0, 0, 0, 0.08);
  }
}

Creating a Custom Theme

To create an entirely new theme, define all tokens under a new data-theme selector:

@layer base {
  [data-theme="my-brand"][data-mode="light"] {
    /* All your custom token values */
    --typography-font-family-body: 'Your Font', sans-serif;
    --color-brand-primary-medium: #YOUR_COLOR;
    --corner-radius-default-medium: 0px; /* Sharp corners */
    /* ... rest of tokens */
  }
  
  [data-theme="my-brand"][data-mode="dark"] {
    /* Dark mode variants */
  }
}

Then activate it:

<html data-theme="my-brand" data-mode="light">

When creating custom themes, ensure you define both light and dark mode variants for all color tokens. Missing tokens will fall back to the default theme values.


Theme Source Files

Browse the complete CSS source for each theme below. Pro themes require a paid license to access.

Loading core theme source...

On this page