OKLCH Studio · shadcn/ui base colour
shadcn/ui Neutral theme: OKLCH CSS variables, hex & contrast
shadcn/ui Neutral: primary #171717 light / #e5e5e5 dark (oklch(0.205 0 0)). 21 of 22 checked pairs meet WCAG AA 4.5:1 (light 10/11, dark 11/11). Copy the full light and dark token set as OKLCH, @theme mapping or hex.
Neutral is a base colour: it defines the complete token set for light and dark mode. Source: shadcn/ui (MIT, © 2023 shadcn); all themes.
Preview
Card title
Muted description text on the card.
Muted block with input border
Card title
Muted description text on the card.
Muted block with input border
light mode tokens
| Token | Swatch | oklch() | Hex | In sRGB |
|---|---|---|---|---|
| --background | oklch(1 0 0) | #ffffff | Yes | |
| --foreground | oklch(0.145 0 0) | #0a0a0a | Yes | |
| --card | oklch(1 0 0) | #ffffff | Yes | |
| --card-foreground | oklch(0.145 0 0) | #0a0a0a | Yes | |
| --popover | oklch(1 0 0) | #ffffff | Yes | |
| --popover-foreground | oklch(0.145 0 0) | #0a0a0a | Yes | |
| --primary | oklch(0.205 0 0) | #171717 | Yes | |
| --primary-foreground | oklch(0.985 0 0) | #fafafa | Yes | |
| --secondary | oklch(0.97 0 0) | #f5f5f5 | Yes | |
| --secondary-foreground | oklch(0.205 0 0) | #171717 | Yes | |
| --muted | oklch(0.97 0 0) | #f5f5f5 | Yes | |
| --muted-foreground | oklch(0.556 0 0) | #737373 | Yes | |
| --accent | oklch(0.97 0 0) | #f5f5f5 | Yes | |
| --accent-foreground | oklch(0.205 0 0) | #171717 | Yes | |
| --destructive | oklch(0.577 0.245 27.325) | #e7000b | No — hex is clipped | |
| --border | oklch(0.922 0 0) | #e5e5e5 | Yes | |
| --input | oklch(0.922 0 0) | #e5e5e5 | Yes | |
| --ring | oklch(0.708 0 0) | #a1a1a1 | Yes | |
| --chart-1 | oklch(0.87 0 0) | #d4d4d4 | Yes | |
| --chart-2 | oklch(0.556 0 0) | #737373 | Yes | |
| --chart-3 | oklch(0.439 0 0) | #525252 | Yes | |
| --chart-4 | oklch(0.371 0 0) | #404040 | Yes | |
| --chart-5 | oklch(0.269 0 0) | #262626 | Yes | |
| --sidebar | oklch(0.985 0 0) | #fafafa | Yes | |
| --sidebar-foreground | oklch(0.145 0 0) | #0a0a0a | Yes | |
| --sidebar-primary | oklch(0.205 0 0) | #171717 | Yes | |
| --sidebar-primary-foreground | oklch(0.985 0 0) | #fafafa | Yes | |
| --sidebar-accent | oklch(0.97 0 0) | #f5f5f5 | Yes | |
| --sidebar-accent-foreground | oklch(0.205 0 0) | #171717 | Yes | |
| --sidebar-border | oklch(0.922 0 0) | #e5e5e5 | Yes | |
| --sidebar-ring | oklch(0.708 0 0) | #a1a1a1 | Yes |
dark mode tokens
| Token | Swatch | oklch() | Hex | In sRGB |
|---|---|---|---|---|
| --background | oklch(0.145 0 0) | #0a0a0a | Yes | |
| --foreground | oklch(0.985 0 0) | #fafafa | Yes | |
| --card | oklch(0.205 0 0) | #171717 | Yes | |
| --card-foreground | oklch(0.985 0 0) | #fafafa | Yes | |
| --popover | oklch(0.205 0 0) | #171717 | Yes | |
| --popover-foreground | oklch(0.985 0 0) | #fafafa | Yes | |
| --primary | oklch(0.922 0 0) | #e5e5e5 | Yes | |
| --primary-foreground | oklch(0.205 0 0) | #171717 | Yes | |
| --secondary | oklch(0.269 0 0) | #262626 | Yes | |
| --secondary-foreground | oklch(0.985 0 0) | #fafafa | Yes | |
| --muted | oklch(0.269 0 0) | #262626 | Yes | |
| --muted-foreground | oklch(0.708 0 0) | #a1a1a1 | Yes | |
| --accent | oklch(0.269 0 0) | #262626 | Yes | |
| --accent-foreground | oklch(0.985 0 0) | #fafafa | Yes | |
| --destructive | oklch(0.704 0.191 22.216) | #ff6467 | No — hex is clipped | |
| --border | oklch(1 0 0 / 10%) | #ffffff (10% alpha) | Yes | |
| --input | oklch(1 0 0 / 15%) | #ffffff (15% alpha) | Yes | |
| --ring | oklch(0.556 0 0) | #737373 | Yes | |
| --chart-1 | oklch(0.87 0 0) | #d4d4d4 | Yes | |
| --chart-2 | oklch(0.556 0 0) | #737373 | Yes | |
| --chart-3 | oklch(0.439 0 0) | #525252 | Yes | |
| --chart-4 | oklch(0.371 0 0) | #404040 | Yes | |
| --chart-5 | oklch(0.269 0 0) | #262626 | Yes | |
| --sidebar | oklch(0.205 0 0) | #171717 | Yes | |
| --sidebar-foreground | oklch(0.985 0 0) | #fafafa | Yes | |
| --sidebar-primary | oklch(0.488 0.243 264.376) | #1447e6 | Yes | |
| --sidebar-primary-foreground | oklch(0.985 0 0) | #fafafa | Yes | |
| --sidebar-accent | oklch(0.269 0 0) | #262626 | Yes | |
| --sidebar-accent-foreground | oklch(0.985 0 0) | #fafafa | Yes | |
| --sidebar-border | oklch(1 0 0 / 10%) | #ffffff (10% alpha) | Yes | |
| --sidebar-ring | oklch(0.556 0 0) | #737373 | Yes |
Contrast audit (WCAG 2)
21 of 22 checked pairs meet AA 4.5:1. Pairs with a translucent side are skipped. A suggested fix keeps hue and chroma and moves the foreground's lightness to the nearest AA value, using the same logic as the contrast checker.
| Pair | Ratio | APCA Lc | AA 4.5 | AA large 3 | Fix / details |
|---|---|---|---|---|---|
| foreground on background#0a0a0a on #ffffff | 19.79:1 | 106 | Pass | Pass | Pair page → |
| card-foreground on card#0a0a0a on #ffffff | 19.79:1 | 106 | Pass | Pass | Pair page → |
| popover-foreground on popover#0a0a0a on #ffffff | 19.79:1 | 106 | Pass | Pass | Pair page → |
| primary-foreground on primary#fafafa on #171717 | 17.17:1 | -104 | Pass | Pass | |
| secondary-foreground on secondary#171717 on #f5f5f5 | 16.44:1 | 99 | Pass | Pass | |
| muted-foreground on muted#737373 on #f5f5f5 | 4.34:1 | 67 | Fail | Pass | Set muted-foreground to oklch(0.516 0.000 0.0) (#676767, 5.18:1). |
| muted-foreground on background#737373 on #ffffff | 4.74:1 | 73 | Pass | Pass | Pair page → |
| accent-foreground on accent#171717 on #f5f5f5 | 16.44:1 | 99 | Pass | Pass | |
| destructive on background#e7000b on #ffffff | 4.76:1 | 70 | Pass | Pass | Pair page → |
| sidebar-foreground on sidebar#0a0a0a on #fafafa | 18.96:1 | 103 | Pass | Pass | |
| sidebar-primary-foreground on sidebar-primary#fafafa on #171717 | 17.17:1 | -104 | Pass | Pass |
| Pair | Ratio | APCA Lc | AA 4.5 | AA large 3 | Fix / details |
|---|---|---|---|---|---|
| foreground on background#fafafa on #0a0a0a | 18.96:1 | -104 | Pass | Pass | |
| card-foreground on card#fafafa on #171717 | 17.17:1 | -104 | Pass | Pass | |
| popover-foreground on popover#fafafa on #171717 | 17.17:1 | -104 | Pass | Pass | |
| primary-foreground on primary#171717 on #e5e5e5 | 14.23:1 | 89 | Pass | Pass | |
| secondary-foreground on secondary#fafafa on #262626 | 14.49:1 | -101 | Pass | Pass | |
| muted-foreground on muted#a1a1a1 on #262626 | 5.85:1 | -48 | Pass | Pass | |
| muted-foreground on background#a1a1a1 on #0a0a0a | 7.66:1 | -51 | Pass | Pass | |
| accent-foreground on accent#fafafa on #262626 | 14.49:1 | -101 | Pass | Pass | |
| destructive on background#ff6467 on #0a0a0a | 6.85:1 | -47 | Pass | Pass | |
| sidebar-foreground on sidebar#fafafa on #171717 | 17.17:1 | -104 | Pass | Pass | |
| sidebar-primary-foreground on sidebar-primary#fafafa on #1447e6 | 6.54:1 | -84 | Pass | Pass |
Copy code
shadcn/ui v4 globals.css (OKLCH)
:root {
--background: oklch(1 0 0);
--foreground: oklch(0.145 0 0);
--card: oklch(1 0 0);
--card-foreground: oklch(0.145 0 0);
--popover: oklch(1 0 0);
--popover-foreground: oklch(0.145 0 0);
--primary: oklch(0.205 0 0);
--primary-foreground: oklch(0.985 0 0);
--secondary: oklch(0.97 0 0);
--secondary-foreground: oklch(0.205 0 0);
--muted: oklch(0.97 0 0);
--muted-foreground: oklch(0.556 0 0);
--accent: oklch(0.97 0 0);
--accent-foreground: oklch(0.205 0 0);
--destructive: oklch(0.577 0.245 27.325);
--border: oklch(0.922 0 0);
--input: oklch(0.922 0 0);
--ring: oklch(0.708 0 0);
--chart-1: oklch(0.87 0 0);
--chart-2: oklch(0.556 0 0);
--chart-3: oklch(0.439 0 0);
--chart-4: oklch(0.371 0 0);
--chart-5: oklch(0.269 0 0);
--radius: 0.625rem;
--sidebar: oklch(0.985 0 0);
--sidebar-foreground: oklch(0.145 0 0);
--sidebar-primary: oklch(0.205 0 0);
--sidebar-primary-foreground: oklch(0.985 0 0);
--sidebar-accent: oklch(0.97 0 0);
--sidebar-accent-foreground: oklch(0.205 0 0);
--sidebar-border: oklch(0.922 0 0);
--sidebar-ring: oklch(0.708 0 0);
}
.dark {
--background: oklch(0.145 0 0);
--foreground: oklch(0.985 0 0);
--card: oklch(0.205 0 0);
--card-foreground: oklch(0.985 0 0);
--popover: oklch(0.205 0 0);
--popover-foreground: oklch(0.985 0 0);
--primary: oklch(0.922 0 0);
--primary-foreground: oklch(0.205 0 0);
--secondary: oklch(0.269 0 0);
--secondary-foreground: oklch(0.985 0 0);
--muted: oklch(0.269 0 0);
--muted-foreground: oklch(0.708 0 0);
--accent: oklch(0.269 0 0);
--accent-foreground: oklch(0.985 0 0);
--destructive: oklch(0.704 0.191 22.216);
--border: oklch(1 0 0 / 10%);
--input: oklch(1 0 0 / 15%);
--ring: oklch(0.556 0 0);
--chart-1: oklch(0.87 0 0);
--chart-2: oklch(0.556 0 0);
--chart-3: oklch(0.439 0 0);
--chart-4: oklch(0.371 0 0);
--chart-5: oklch(0.269 0 0);
--sidebar: oklch(0.205 0 0);
--sidebar-foreground: oklch(0.985 0 0);
--sidebar-primary: oklch(0.488 0.243 264.376);
--sidebar-primary-foreground: oklch(0.985 0 0);
--sidebar-accent: oklch(0.269 0 0);
--sidebar-accent-foreground: oklch(0.985 0 0);
--sidebar-border: oklch(1 0 0 / 10%);
--sidebar-ring: oklch(0.556 0 0);
}Tailwind v4 @theme inline mapping
@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-card: var(--card);
--color-card-foreground: var(--card-foreground);
--color-popover: var(--popover);
--color-popover-foreground: var(--popover-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-destructive: var(--destructive);
--color-border: var(--border);
--color-input: var(--input);
--color-ring: var(--ring);
--color-chart-1: var(--chart-1);
--color-chart-2: var(--chart-2);
--color-chart-3: var(--chart-3);
--color-chart-4: var(--chart-4);
--color-chart-5: var(--chart-5);
--color-sidebar: var(--sidebar);
--color-sidebar-foreground: var(--sidebar-foreground);
--color-sidebar-primary: var(--sidebar-primary);
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
--color-sidebar-accent: var(--sidebar-accent);
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
--color-sidebar-border: var(--sidebar-border);
--color-sidebar-ring: var(--sidebar-ring);
}Hex fallback (for tools without OKLCH support)
:root {
--background: #ffffff;
--foreground: #0a0a0a;
--card: #ffffff;
--card-foreground: #0a0a0a;
--popover: #ffffff;
--popover-foreground: #0a0a0a;
--primary: #171717;
--primary-foreground: #fafafa;
--secondary: #f5f5f5;
--secondary-foreground: #171717;
--muted: #f5f5f5;
--muted-foreground: #737373;
--accent: #f5f5f5;
--accent-foreground: #171717;
--destructive: #e7000b;
--border: #e5e5e5;
--input: #e5e5e5;
--ring: #a1a1a1;
--chart-1: #d4d4d4;
--chart-2: #737373;
--chart-3: #525252;
--chart-4: #404040;
--chart-5: #262626;
--radius: 0.625rem;
--sidebar: #fafafa;
--sidebar-foreground: #0a0a0a;
--sidebar-primary: #171717;
--sidebar-primary-foreground: #fafafa;
--sidebar-accent: #f5f5f5;
--sidebar-accent-foreground: #171717;
--sidebar-border: #e5e5e5;
--sidebar-ring: #a1a1a1;
}
.dark {
--background: #0a0a0a;
--foreground: #fafafa;
--card: #171717;
--card-foreground: #fafafa;
--popover: #171717;
--popover-foreground: #fafafa;
--primary: #e5e5e5;
--primary-foreground: #171717;
--secondary: #262626;
--secondary-foreground: #fafafa;
--muted: #262626;
--muted-foreground: #a1a1a1;
--accent: #262626;
--accent-foreground: #fafafa;
--destructive: #ff6467;
--border: #ffffff1a;
--input: #ffffff26;
--ring: #737373;
--chart-1: #d4d4d4;
--chart-2: #737373;
--chart-3: #525252;
--chart-4: #404040;
--chart-5: #262626;
--sidebar: #171717;
--sidebar-foreground: #fafafa;
--sidebar-primary: #1447e6;
--sidebar-primary-foreground: #fafafa;
--sidebar-accent: #262626;
--sidebar-accent-foreground: #fafafa;
--sidebar-border: #ffffff1a;
--sidebar-ring: #737373;
}Related colours
Light primary: oklch(0.205 0 0) · #171717