Skip to main content

Theming

Customize the visual theme for applications using @distri/react by overriding CSS variables. The theming system is built on Tailwind CSS with shadcn/ui design tokens.

Quick Start

Import the default theme files:

// Import both files for default theme
import '@distri/react/theme.css'; // Default color variables
import '@distri/react/globals.css'; // Tailwind utilities (required)

The theme.css provides default light/dark mode colors. The globals.css provides Tailwind utilities and component styles.

Custom Theme

/* your-app.css */
@import '@distri/react/globals.css';

/* Override specific variables */
:root {
--primary: 220 90% 50%; /* Custom blue primary */
}

.dark {
--primary: 220 80% 60%; /* Lighter blue for dark mode */
}

Option 2: Complete Theme Override

/* your-app.css */
@import '@distri/react/globals.css';

:root {
/* Core Colors */
--background: 0 0% 100%;
--foreground: 222.2 84% 4.9%;
--card: 0 0% 100%;
--card-foreground: 222.2 84% 4.9%;
--popover: 0 0% 100%;
--popover-foreground: 222.2 84% 4.9%;

/* Brand Colors */
--primary: 188 100% 28%;
--primary-foreground: 0 0% 100%;
--highlight: 188 70% 45%;

/* Secondary & Muted */
--secondary: 210 40% 96%;
--secondary-foreground: 222.2 84% 4.9%;
--muted: 210 40% 96%;
--muted-foreground: 215.4 16.3% 46.9%;

/* Accent & Destructive */
--accent: 188 55% 92%;
--accent-foreground: 188 80% 20%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 210 40% 98%;

/* Borders & Input */
--border: 214.3 31.8% 91.4%;
--input: 214.3 31.8% 91.4%;
--ring: 188 100% 28%;

/* Sidebar */
--sidebar: 0 0% 98%;
--sidebar-foreground: 240 5.3% 26.1%;
--sidebar-primary: 188 100% 28%;
--sidebar-accent: 240 4.8% 95.9%;
--sidebar-border: 220 13% 91%;

/* Layout */
--radius: 0.5rem;
--thread-content-max-width: 768px;
}

.dark {
--background: 220 16% 8%;
--foreground: 210 33% 95%;
--card: 220 17% 12%;
--card-foreground: 210 33% 95%;
--popover: 220 17% 12%;
--popover-foreground: 210 33% 95%;

--primary: 188 100% 28%;
--primary-foreground: 0 0% 100%;
--highlight: 188 70% 45%;

--secondary: 220 18% 16%;
--secondary-foreground: 210 33% 95%;
--muted: 220 18% 16%;
--muted-foreground: 215 20% 65%;

--accent: 188 30% 22%;
--accent-foreground: 188 70% 85%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 210 40% 98%;

--border: 220 18% 20%;
--input: 220 18% 20%;
--ring: 188 70% 45%;

--sidebar: 216 18% 6%;
--sidebar-foreground: 210 33% 95%;
--sidebar-primary: 188 70% 45%;
--sidebar-accent: 220 18% 14%;
--sidebar-border: 220 18% 18%;
}

CSS Variables Reference

Core Colors

VariableLight DefaultDark DefaultDescription
--background0 0% 100%220 16% 8%Page background
--foreground222.2 84% 4.9%210 33% 95%Main text color
--card0 0% 100%220 17% 12%Card backgrounds
--card-foregroundSame as foregroundSame as foregroundCard text
--popoverSame as cardSame as cardPopover/dropdown bg
--popover-foregroundSame as foregroundSame as foregroundPopover text

Brand Colors

VariableLight DefaultDark DefaultDescription
--primary188 100% 28%188 100% 28%Primary brand color (#007C91)
--primary-foreground0 0% 100%0 0% 100%Text on primary
--highlight188 70% 45%188 70% 45%Accent highlight (rgb(34,174,195))

Secondary & Muted

VariableLight DefaultDark DefaultDescription
--secondary210 40% 96%220 18% 16%Secondary backgrounds
--secondary-foreground222.2 84% 4.9%210 33% 95%Secondary text
--muted210 40% 96%220 18% 16%Muted/disabled backgrounds
--muted-foreground215.4 16.3% 46.9%215 20% 65%Muted text

Accent & Destructive

VariableLight DefaultDark DefaultDescription
--accent188 55% 92%188 30% 22%Accent color
--accent-foreground188 80% 20%188 70% 85%Accent text
--destructive0 84.2% 60.2%0 62.8% 30.6%Error/delete actions
--destructive-foreground210 40% 98%210 40% 98%Destructive text

Borders & Input

VariableLight DefaultDark DefaultDescription
--border214.3 31.8% 91.4%220 18% 20%Border color (#2a2f3a dark)
--inputSame as borderSame as borderInput field borders
--ring188 100% 28%188 70% 45%Focus ring color
VariableLight DefaultDark DefaultDescription
--sidebar0 0% 98%216 18% 6%Sidebar bg (#0c0e11 dark)
--sidebar-foreground240 5.3% 26.1%210 33% 95%Sidebar text
--sidebar-primary188 100% 28%188 70% 45%Active nav item
--sidebar-accent240 4.8% 95.9%220 18% 14%Hover states
--sidebar-border220 13% 91%220 18% 18%Sidebar borders

Layout

VariableDefaultDescription
--radius0.5remBorder radius
--thread-content-max-width768pxMax width for chat content

Color Format

All colors use HSL format without the hsl() wrapper:

--primary: 188 100% 28%;  /* H S% L% */

This allows using opacity modifiers:

background: hsl(var(--primary) / 0.5);  /* 50% opacity */

Dark Mode

Dark mode is activated by adding the dark class to <html> or a parent element:

<html class="dark">

Or toggle via JavaScript:

document.documentElement.classList.toggle('dark');

React Integration

import { useState, useEffect } from 'react';
import '@distri/react/theme.css';
import '@distri/react/globals.css';

function App() {
const [darkMode, setDarkMode] = useState(false);

useEffect(() => {
if (darkMode) {
document.documentElement.classList.add('dark');
} else {
document.documentElement.classList.remove('dark');
}
}, [darkMode]);

return (
<div>
<button onClick={() => setDarkMode(!darkMode)}>
Toggle Dark Mode
</button>
{/* Your app content */}
</div>
);
}

Files

  • globals.css - Tailwind utilities + component styles (required)
  • theme.css - Default color variables (imported by globals.css)

Best Practices

  1. Import globals.css first: Always import globals.css before your custom overrides
  2. Use HSL format: Keep colors in HSL format for consistency and opacity support
  3. Define both light and dark: Always provide both :root and .dark variants
  4. Test contrast: Ensure sufficient contrast ratios for accessibility
  5. Use semantic names: Stick to the provided variable names for consistency