The Spira design system.
Dark-first, generously rounded, and accessible. Built on Base UI primitives and a single token layer you can retheme in seconds — with every example available in React and pure HTML + Tailwind.
Customize
Theme
Pick a palette and a roundness to preview live, then copy the full src/app/globals.css — colors and radius baked in, everything else included.
Palette
Roundness
@import "tailwindcss";
/* === SPIRA THEME — edit colors/radius via /design, or swap this :root block === */
:root {
color-scheme: dark;
--radius: 18px;
--background: #08090a;
--foreground: #fafafa;
--surface: #101113;
--surface-raised: #16181b;
--border: #26292e;
--border-strong: #363a41;
--muted: #8a9099;
--accent: #fafafa;
--accent-from: #ffffff;
--accent-to: #b8bcc2;
--accent-foreground: #08090a;
--ring: #fafafa;
--danger: #fb7185;
--danger-foreground: #08090a;
}
/* structural tokens — shared by all themes. Leave as-is. */
:root {
--gradient-accent: linear-gradient(135deg, var(--accent-from), var(--accent-to));
/* minimal neutral elevation (subtle shadow, not a colored glow) */
--glow-accent: 0 4px 16px -8px rgb(0 0 0 / 0.5);
--glow-soft: 0 1px 2px rgb(0 0 0 / 0.2);
}
@theme inline {
/* colors → bg-* / text-* / border-* utilities */
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-surface: var(--surface);
--color-surface-raised: var(--surface-raised);
--color-border: var(--border);
--color-border-strong: var(--border-strong);
--color-muted: var(--muted);
--color-accent: var(--accent);
--color-accent-from: var(--accent-from);
--color-accent-to: var(--accent-to);
--color-accent-foreground: var(--accent-foreground);
--color-danger: var(--danger);
--color-danger-foreground: var(--danger-foreground);
--color-ring: var(--ring);
/* fonts (wired in layout.tsx) */
--font-sans: var(--font-sans);
--font-display: var(--font-display);
/* radius scale → rounded-* (derives from --radius in the theme block) */
--radius-xs: calc(var(--radius) - 10px);
--radius-sm: calc(var(--radius) - 6px);
--radius-md: var(--radius);
--radius-lg: calc(var(--radius) + 6px);
--radius-card: calc(var(--radius) + 10px);
--radius-pill: 9999px;
/* elevation → shadow-* */
--shadow-glow: var(--glow-accent);
--shadow-soft: var(--glow-soft);
/* large display type scale → text-* */
--text-display-sm: 1.75rem;
--text-display-sm--line-height: 1.1;
--text-display-md: 2.25rem;
--text-display-md--line-height: 1.08;
--text-display-lg: 3rem;
--text-display-lg--line-height: 1.04;
--text-display-xl: 4rem;
--text-display-xl--line-height: 1;
--text-display-2xl: 5.5rem;
--text-display-2xl--line-height: 0.98;
}
@layer base {
html {
isolation: isolate; /* Base UI: stacking context for popups/portals */
scroll-behavior: smooth;
}
body {
position: relative; /* Base UI: iOS 26+ Safari */
background: var(--background);
color: var(--foreground);
font-family: var(--font-sans), system-ui, sans-serif;
}
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}
}
Reference
Components
Each component has its own page with a live preview and both code variants. Hover the icons — they animate.