Configuration
How Aidash Components is themed — Tailwind CSS v4 tokens declared in your global stylesheet. No JS config file, no build step, no bespoke DSL.
CSS-first
Aidash uses Tailwind CSS v4's @theme directive. All tokens — colors, typography, radii, shadows — live in your CSS file.
@import "tailwindcss";
@custom-variant dark (&:where(.dark, .dark *));
@theme {
/* All design tokens live here */
}tailwind.config.js. If you have one from a previous project, you can delete it — everything moves into @theme.Brand palette
Change these ten values and every button, ring, accent, and hover state re-themes to match.
@theme {
--color-brand-50: oklch(0.97 0.01 250);
--color-brand-100: oklch(0.93 0.04 250);
--color-brand-200: oklch(0.87 0.08 250);
--color-brand-300: oklch(0.78 0.13 250);
--color-brand-400: oklch(0.68 0.17 252);
--color-brand-500: oklch(0.62 0.20 255);
--color-brand-600: oklch(0.54 0.20 255);
--color-brand-700: oklch(0.46 0.18 255);
--color-brand-800: oklch(0.38 0.15 255);
--color-brand-900: oklch(0.30 0.12 255);
}Semantic tokens
Names components reach for at runtime — background, foreground, muted, primary, ring. Split into :root (light) and .dark (dark) blocks.
:root {
--background: oklch(1 0 0);
--foreground: oklch(0.145 0 0);
--card: oklch(1 0 0);
--card-foreground: oklch(0.145 0 0);
--primary: var(--color-brand-500);
--primary-foreground: oklch(0.985 0 0);
--muted: oklch(0.97 0 0);
--muted-foreground: oklch(0.556 0 0);
--border: oklch(0.92 0 0);
--ring: var(--color-brand-500);
}
.dark {
--background: oklch(0.145 0 0);
--foreground: oklch(0.985 0 0);
--card: oklch(0.18 0 0);
--card-foreground: oklch(0.985 0 0);
--primary: var(--color-brand-400);
--primary-foreground: oklch(0.145 0 0);
--muted: oklch(0.22 0 0);
--muted-foreground: oklch(0.68 0 0);
--border: oklch(0.26 0 0);
--ring: var(--color-brand-400);
}Typography
Font families and the scale. Aidash defaults to Inter for body and JetBrains Mono for code.
@theme {
--font-body: "Inter", ui-sans-serif, system-ui, sans-serif;
--font-display: "Inter", ui-sans-serif, system-ui, sans-serif;
--font-mono: "JetBrains Mono", ui-monospace, monospace;
--text-xs: 0.75rem; /* 12 */
--text-sm: 0.875rem; /* 14 */
--text-base: 1rem; /* 16 */
--text-lg: 1.125rem; /* 18 */
--text-xl: 1.25rem; /* 20 */
--text-2xl: 1.5rem; /* 24 */
--text-3xl: 1.875rem; /* 30 */
--text-4xl: 2.25rem; /* 36 */
}Radii
Four values cover the corner radii components reach for — lg for buttons and inputs, xl for cards and larger surfaces, md and sm for small inline details. Fully round shapes like chips use rounded-full, so they ignore these tokens.
@theme {
--radius-sm: 4px;
--radius-md: 6px;
--radius-lg: 8px;
--radius-xl: 12px;
}Dark mode
Toggle by adding class='dark' on the <html> element. The .dark selector overrides every semantic token.
'use client';
import { useEffect, useState } from 'react';
export function ThemeToggle() {
const [dark, setDark] = useState(false);
useEffect(() => {
setDark(document.documentElement.classList.contains('dark'));
}, []);
function toggle() {
const next = !dark;
setDark(next);
document.documentElement.classList.toggle('dark', next);
localStorage.setItem('theme', next ? 'dark' : 'light');
}
return (
<button onClick={toggle}>
{dark ? 'Light' : 'Dark'}
</button>
);
}<head>. See the Dark mode guide.Motion
Duration and easing tokens shared across every animation.
@theme {
--ease-standard: cubic-bezier(0.2, 0, 0, 1);
--ease-spring: cubic-bezier(0.25, 1.2, 0.4, 1);
--duration-fast: 120ms;
--duration-base: 180ms;
--duration-slow: 280ms;
}Also see
Deeper dives into individual token families.