UI Theming System
UI Theming System
Section titled “UI Theming System”The UI library uses a modern CSS theming system based on OKLCH colors and CSS custom properties. This provides precise color control, excellent dark mode support, and easy customization.
What is OKLCH?
Section titled “What is OKLCH?”OKLCH (Oklch) is a perceptually uniform color space that provides:
- Consistent Lightness: Same perceived brightness across hues
- Wide Gamut: Access to P3 and Rec. 2020 colors
- Intuitive Adjustments: Change lightness, chroma, or hue independently
/* OKLCH format: oklch(lightness chroma hue) */--color-primary: oklch(0.552 0.278 264);/* L C H *//* 55.2% 27.8 264° */Theme Structure
Section titled “Theme Structure”Base Variables
Section titled “Base Variables”Defined in packages/ui/theme.css:
:host { /* Background & Foreground */ --background: oklch(0.999 0.0017 245); --foreground: oklch(0.09 0.005 20);
/* Primary - Main accent color */ --primary: oklch(0.552 0.278 264); --primary-foreground: oklch(0.98 0.005 245);
/* Secondary */ --secondary: oklch(66.532% 0.0383 271.338); --secondary-foreground: oklch(0.98 0.005 245);
/* Muted - Subtle backgrounds */ --muted: oklch(0.9213 0.0146 240); --muted-foreground: oklch(0.45 0.015 20);
/* Accent - Highlights */ --accent: oklch(0.92 0.015 245); --accent-foreground: oklch(0.09 0.005 20);
/* Semantic Colors */ --danger: oklch(0.628 0.257 29.2); --danger-foreground: oklch(0.98 0.013 17.4);
--warning: oklch(0.845 0.167 83.9); --warning-foreground: oklch(0.22 0.084 86.1);
--success: oklch(0.7 0.17 142); --success-foreground: oklch(0.98 0.05 142);
--info: oklch(0.44043 0.16728 263.481); --info-foreground: oklch(0.97277 0.01784 223.858);
/* Borders & Inputs */ --border: oklch(0.095 0.005 20); --input: oklch(0.802 0 20); --ring: oklch(0.09 0.005 20);}Dark Mode
Section titled “Dark Mode”Dark mode is activated by adding the .dark class:
.dark { --background: oklch(0.2031 0.0608 268); --foreground: oklch(0.98 0.013 20); --primary: oklch(0.602 0.278 264); --primary-foreground: oklch(0.98 0.005 20); --secondary: oklch(0.66 0.0383 271.338); --secondary-foreground: oklch(0.98 0.005 20); --muted: oklch(0.275 0.0586 268); --muted-foreground: oklch(0.649 0.015 20); --accent: oklch(0.36 0.0608 268); --accent-foreground: oklch(0.98 0.013 20); --border: oklch(0.9913 0.0178 260); --input: oklch(0.5013 0.0178 260); --ring: oklch(0.9613 0.0178 260);}TailwindCSS Integration
Section titled “TailwindCSS Integration”The theme variables are mapped to Tailwind classes:
@theme inline { --color-background: var(--background); --color-foreground: var(--foreground); --color-primary: var(--primary); --color-primary-foreground: var(--primary-foreground); --color-secondary: var(--secondary); --color-secondary-foreground: var(--secondary-foreground); --color-muted: var(--muted); --color-muted-foreground: var(--muted-foreground); --color-accent: var(--accent); --color-accent-foreground: var(--accent-foreground); --color-danger: var(--danger); --color-danger-foreground: var(--danger-foreground); --color-warning: var(--warning); --color-warning-foreground: var(--warning-foreground); --color-success: var(--success); --color-success-foreground: var(--success-foreground); --color-info: var(--info); --color-info-foreground: var(--info-foreground); --color-border: var(--border); --color-input: var(--input); --color-ring: var(--ring);}Using Theme Colors in Templates
Section titled “Using Theme Colors in Templates”<template> <!-- Background colors --> <div class="bg-background text-foreground">Default</div> <div class="bg-primary text-primary-foreground">Primary</div> <div class="bg-muted text-muted-foreground">Muted</div>
<!-- Semantic colors --> <div class="bg-danger text-danger-foreground">Danger</div> <div class="bg-success text-success-foreground">Success</div> <div class="bg-warning text-warning-foreground">Warning</div>
<!-- Borders --> <div class="border border-border">Bordered</div>
<!-- Focus rings --> <input class="focus:ring-2 focus:ring-ring" /></template>Semantic Color Usage
Section titled “Semantic Color Usage”| Color | Purpose | Use For |
|---|---|---|
primary | Main brand/action | Primary buttons, links, accents |
secondary | Supporting | Secondary actions, less emphasis |
muted | Subtle | Backgrounds, disabled states |
accent | Highlight | Hover states, selections |
danger | Destructive | Delete, error states |
success | Positive | Completion, valid states |
warning | Caution | Warnings, pending states |
info | Informational | Tips, neutral info |
Customizing the Theme
Section titled “Customizing the Theme”Option 1: Override CSS Variables
Section titled “Option 1: Override CSS Variables”/* In your custom CSS */:root { /* Change primary to a green */ --primary: oklch(0.6 0.2 145); --primary-foreground: oklch(0.98 0.02 145);}
.dark { --primary: oklch(0.65 0.2 145);}Option 2: Create Theme Presets
Section titled “Option 2: Create Theme Presets”export const themes = { default: { primary: 'oklch(0.552 0.278 264)', // Purple }, ocean: { primary: 'oklch(0.6 0.2 220)', // Blue }, forest: { primary: 'oklch(0.55 0.18 150)', // Green }, sunset: { primary: 'oklch(0.6 0.25 30)', // Orange },};
export function applyTheme(themeName: keyof typeof themes) { const theme = themes[themeName]; const root = document.documentElement;
Object.entries(theme).forEach(([key, value]) => { root.style.setProperty(`--${key}`, value); });}Dark Mode Toggle
Section titled “Dark Mode Toggle”<script setup>import { ref, watchEffect } from 'vue';
const isDark = ref(false);
watchEffect(() => { // For regular Vue apps document.documentElement.classList.toggle('dark', isDark.value);});
// For web components, the theme prop handles this// <form-component theme="dark" /></script>
<template> <button @click="isDark = !isDark"> {{ isDark ? '☀️ Light' : '🌙 Dark' }} </button></template>Complete Color Palette
Section titled “Complete Color Palette”The theme includes the full Tailwind color palette in OKLCH:
@theme { /* Red */ --color-red-50: oklch(0.971 0.013 17.38); --color-red-500: oklch(0.637 0.237 25.331); --color-red-900: oklch(0.396 0.141 25.723);
/* Green */ --color-green-50: oklch(0.982 0.018 155.826); --color-green-500: oklch(0.723 0.219 149.579); --color-green-900: oklch(0.393 0.095 152.535);
/* Blue */ --color-blue-50: oklch(0.97 0.014 254.604); --color-blue-500: oklch(0.623 0.214 259.815); --color-blue-900: oklch(0.379 0.146 265.522);
/* And all other Tailwind colors... */}Best Practices
Section titled “Best Practices”- Use semantic colors (
primary,danger, etc.) not raw colors - Test in both modes - always verify light and dark themes
- Maintain contrast - use
*-foregroundcolors for text on colored backgrounds - Prefer OKLCH for custom colors - better perceptual uniformity