Skip to contentVibraUI
Live preview · measured contrast · CSS out

Theme generator

An accent, a neutral ladder, a radius, a face and a rhythm. A real dashboard page repaints as you go, every text tier’s contrast is measured on every plane it sits on, and the theme copies out as CSS.

Contrast, measured

Each text tier on each plane it sits on, from the tokens the export writes, by WCAG 2’s ratio — and the full suite CI runs on the kit’s own palettes: light 122 of 122 · dark 122 of 122 pass.

Contrast in the light mode
TextBack­ground--backgroundCard--cardMuted--mutedBrand muted--brand-mutedAccent--accent
Foreground--foreground4.5:1 floor
19.79:1Pass
19.79:1Pass
17.88:1Pass
16.10:1Pass
17.88:1Pass
Muted text--muted-foreground4.5:1 floor
6.00:1Pass
6.00:1Pass
5.42:1Pass
4.88:1Pass
5.42:1Pass
Subtle text--faint-foreground4.5:1 floor
5.74:1Pass
5.74:1Pass
5.19:1Pass
4.67:1Pass
5.19:1Pass
Accent text--brand4.5:1 floor
17.91:1Pass
17.91:1Pass
16.18:1Pass
14.57:1Pass
16.18:1Pass
Text on accent--brand-foreground on --brand4.5:1 floor
17.15:1Pass

Export

Every token the generator sets and nothing it does not, in both modes. Paste the first over the palette in your globals.css; the second wears the same values on any wrapper.

/* Vibra theme. Edit it again: https://vibraui.com/themes/generator?accent=0.205_0_0&neutral=neutral&radius=0.625&font=sans&density=comfortable&chart=accent&mode=light */:root {  --radius: 0.625rem;  /* Planes. */  --background: oklch(1 0 0);  --surface: oklch(0.985 0 0);  --card: oklch(1 0 0);  --popover: oklch(1 0 0);  --muted: oklch(0.965 0 0);  --secondary: oklch(0.965 0 0);  --accent: oklch(0.965 0 0);  /* Ink. */  --foreground: oklch(0.145 0 0);  --card-foreground: oklch(0.145 0 0);  --popover-foreground: oklch(0.145 0 0);  --muted-foreground: oklch(0.5 0 0);  --faint-foreground: oklch(0.51 0 0);  --secondary-foreground: oklch(0.205 0 0);  --accent-foreground: oklch(0.205 0 0);  /* The accent. */  --brand: oklch(0.205 0 0);  --brand-foreground: oklch(0.985 0 0);  --brand-muted: oklch(0.93 0 0);  /* Lines. */  --border: oklch(0.905 0 0);  --rule: oklch(0.87 0 0);  --input: oklch(0.63 0 0);  --chart-grid: oklch(0.905 0 0);  /* Charts. */  --chart-1: oklch(0.66 0 0);  --chart-2: oklch(0.55 0.19 258);  --chart-3: oklch(0.55 0.11 190);  --chart-4: oklch(0.58 0.16 55);  --chart-5: oklch(0.55 0.2 300);  --chart-6: oklch(0.3 0 0);  --chart-7: oklch(0.5 0 0);  --chart-8: oklch(0.4 0 0);  /* Sidebar. */  --sidebar: oklch(0.976 0 0);  --sidebar-foreground: oklch(0.4 0 0);  --sidebar-accent: oklch(0.92 0 0);  --sidebar-accent-foreground: oklch(0.145 0 0);  --sidebar-border: oklch(0.905 0 0);}.dark {  /* Planes. */  --background: oklch(0.145 0 0);  --surface: oklch(0.185 0 0);  --card: oklch(0.205 0 0);  --popover: oklch(0.24 0 0);  --muted: oklch(0.269 0 0);  --secondary: oklch(0.269 0 0);  --accent: oklch(0.269 0 0);  /* Ink. */  --foreground: oklch(0.985 0 0);  --card-foreground: oklch(0.985 0 0);  --popover-foreground: oklch(0.985 0 0);  --muted-foreground: oklch(0.71 0 0);  --faint-foreground: oklch(0.72 0 0);  --secondary-foreground: oklch(0.985 0 0);  --accent-foreground: oklch(0.985 0 0);  /* The accent. */  --brand: oklch(0.985 0 0);  --brand-foreground: oklch(0.205 0 0);  --brand-muted: oklch(0.3 0 0);  /* Lines. */  --border: oklch(0.27 0 0);  --rule: oklch(0.36 0 0);  --input: oklch(0.6 0 0);  --chart-grid: oklch(0.29 0 0);  /* Charts. */  --chart-1: oklch(0.75 0 0);  --chart-2: oklch(0.68 0.16 258);  --chart-3: oklch(0.72 0.12 190);  --chart-4: oklch(0.75 0.15 60);  --chart-5: oklch(0.7 0.17 300);  --chart-6: oklch(0.88 0 0);  --chart-7: oklch(0.6 0 0);  --chart-8: oklch(0.54 0 0);  /* Sidebar. */  --sidebar: oklch(0.205 0 0);  --sidebar-foreground: oklch(0.8 0 0);  --sidebar-accent: oklch(0.269 0 0);  --sidebar-accent-foreground: oklch(0.985 0 0);  --sidebar-border: oklch(0.27 0 0);}

Or start from a palette

22 finished themes ship beside Vibra’s own, each one attribute on any wrapper, each held to the same contrast floors this page measures.