OKLCH Studio · Accessible palettes · Product & UI
Accessible color palette for documentation sites (WCAG 2.2 verified)
Updated 2026-10-19
Documentation is read by people who are trying to get something done, often with the page next to an editor, in a terminal-like environment, for long stretches. The text is full of inline code, tables, links, callouts and copy buttons. The main risks are low-contrast code comments, pale grey sidebar links and callout backgrounds that quietly reduce text contrast.
This palette sets both body text and muted text at AAA, which is unusual and deliberate. In docs, the muted colour is used for sidebar entries, captions and breadcrumbs, which readers scan constantly. Links are held at AA and the focus ring at 3:1 or better, since docs readers often navigate by keyboard.
WCAG 2.2 AA is the typical standard in company accessibility policies, and docs for public or enterprise software are often covered. Callouts for info, success, warning and error are verified as labelled fills.
How to build a palette like this by hand is explained in the accessible colour palette guide; this page is the finished, verified result.
The palette: light and dark
Hex values are the sRGB result after gamut mapping. The oklch() values are those of the final hex, so converting either gives the same colour.
Appointment confirmed
Secondary text sits on the surface colour.
Link in primary · Accent text
Light theme
- Background
#F4F7FA
oklch(0.975 0.005 247.9)
Sample text
- Surface
#FBFFFF
oklch(0.997 0.004 197.1)
Sample text
- Text
#181B1D
oklch(0.220 0.006 236.8)
Sample text
- Muted text
#505457
oklch(0.443 0.007 240.0)
Sample text
- Primary
#006C9D
oklch(0.505 0.113 238.4)
Sample text
- Primary foreground
#FAFCFD
oklch(0.990 0.003 228.8)
Sample text
- Accent
#397949
oklch(0.521 0.100 149.8)
Sample text
- Border
#8A8E92
oklch(0.645 0.008 247.9)
Sample text
- Focus ring
#005D8D
oklch(0.457 0.107 241.3)
Sample text
- Success
#008158
oklch(0.5333 0.1163 162.37)
Sample text
- Success fill
#008457
oklch(0.5415 0.1211 160.71)
Sample text
- Success fill label
#FAFCFD
oklch(0.990 0.003 228.8)
Sample text
- Warning
#A06300
oklch(0.5541 0.1212 68.45)
Sample text
- Warning fill
#FFBA44
oklch(0.8335 0.1508 76.88)
Sample text
- Warning fill label
#0F1010
oklch(0.172 0.002 197.0)
Sample text
- Error
#A21A1B
oklch(0.4603 0.1706 26.95)
Sample text
- Error fill
#C8322E
oklch(0.551 0.187 27.1)
Sample text
- Error fill label
#FAFCFD
oklch(0.990 0.003 228.8)
Sample text
- Info
#2274AF
oklch(0.540 0.120 245.0)
Sample text
- Info fill
#1377B9
oklch(0.5501 0.1324 245.13)
Sample text
- Info fill label
#FAFCFD
oklch(0.990 0.003 228.8)
Sample text
Appointment confirmed
Secondary text sits on the surface colour.
Link in primary · Accent text
Dark theme
- Background
#141618
oklch(0.199 0.005 248.1)
Sample text
- Surface
#1E2122
oklch(0.245 0.005 219.7)
Sample text
- Text
#EBEFF2
oklch(0.950 0.006 239.8)
Sample text
- Muted text
#B9BFC2
oklch(0.801 0.008 228.9)
Sample text
- Primary
#67CAFF
oklch(0.7999 0.1195 234.40)
Sample text
- Primary foreground
#0C0D0E
oklch(0.158 0.003 248.0)
Sample text
- Accent
#95D7A2
oklch(0.821 0.100 149.9)
Sample text
- Border
#686C6F
oklch(0.529 0.007 239.9)
Sample text
- Focus ring
#67CAFF
oklch(0.7999 0.1195 234.40)
Sample text
- Success
#6CE5B5
oklch(0.839 0.130 164.9)
Sample text
- Success fill
#3BCD9A
oklch(0.759 0.143 165.0)
Sample text
- Success fill label
#0F1010
oklch(0.172 0.002 197.0)
Sample text
- Warning
#FFBC56
oklch(0.839 0.140 75.1)
Sample text
- Warning fill
#E9A11D
oklch(0.7605 0.1539 75.30)
Sample text
- Warning fill label
#0F1010
oklch(0.172 0.002 197.0)
Sample text
- Error
#F66D62
oklch(0.700 0.171 27.0)
Sample text
- Error fill
#FF7A6D
oklch(0.732 0.165 27.5)
Sample text
- Error fill label
#0F1010
oklch(0.172 0.002 197.0)
Sample text
- Info
#71BFFF
oklch(0.780 0.120 245.0)
Sample text
- Info fill
#61B9FF
oklch(0.760 0.132 244.8)
Sample text
- Info fill label
#0F1010
oklch(0.172 0.002 197.0)
Sample text
Contrast table: every verified pair
Pass or fail uses the raw WCAG 2.x ratio; the ratio shown is floored to two decimals so a near miss is never rounded up. APCA Lc is signed: positive is dark on light, negative is light on dark. Each row opens the pair in the checker.
| Pair | WCAG ratio | Target | Normal AA / AAA | Large AA / AAA | APCA Lc | APCA tier | Check |
|---|---|---|---|---|---|---|---|
| Text on background#181b1d on #f4f7fa | 16.09:1 | AAA 7:1 | Pass / Pass | Pass / Pass | +99.2 | Lc 75: body text | Open in checker |
| Text on surface#181b1d on #fbffff | 17.18:1 | AAA 7:1 | Pass / Pass | Pass / Pass | +103.7 | Lc 75: body text | Open in checker |
| Muted text on background#505457 on #f4f7fa | 7.11:1 | AAA 7:1 | Pass / Pass | Pass / Pass | +81.6 | Lc 75: body text | Open in checker |
| Muted text on surface#505457 on #fbffff | 7.59:1 | AAA 7:1 | Pass / Pass | Pass / Pass | +86.1 | Lc 75: body text | Open in checker |
| Primary as link text on background#006c9d on #f4f7fa | 5.37:1 | AA 4.5:1 | Pass / Fail | Pass / Pass | +73.3 | Lc 60: larger content text | Open in checker |
| Primary as link text on surface#006c9d on #fbffff | 5.74:1 | AA 4.5:1 | Pass / Fail | Pass / Pass | +77.8 | Lc 75: body text | Open in checker |
| Button label on primary#fafcfd on #006c9d | 5.61:1 | AA 4.5:1 | Pass / Fail | Pass / Pass | −81.4 | Lc 75: body text | Open in checker |
| Accent text on background#397949 on #f4f7fa | 4.87:1 | AA 4.5:1 | Pass / Fail | Pass / Pass | +70.8 | Lc 60: larger content text | Open in checker |
| Accent text on surface#397949 on #fbffff | 5.20:1 | AA 4.5:1 | Pass / Fail | Pass / Pass | +75.3 | Lc 75: body text | Open in checker |
| Border on background#8a8e92 on #f4f7fa | 3.06:1 | 3:1 (WCAG 1.4.11) | Fail / Fail | Pass / Fail | +55.4 | Lc 45: headlines and large text | Open in checker |
| Border on surface#8a8e92 on #fbffff | 3.27:1 | 3:1 (WCAG 1.4.11) | Fail / Fail | Pass / Fail | +59.9 | Lc 45: headlines and large text | Open in checker |
| Focus ring on background#005d8d on #f4f7fa | 6.62:1 | 3:1 (WCAG 1.4.11) | Pass / Fail | Pass / Pass | +79.1 | Lc 75: body text | Open in checker |
| Focus ring on surface#005d8d on #fbffff | 7.06:1 | 3:1 (WCAG 1.4.11) | Pass / Pass | Pass / Pass | +83.6 | Lc 75: body text | Open in checker |
| Success text on background#008158 on #f4f7fa | 4.56:1 | AA 4.5:1 | Pass / Fail | Pass / Pass | +68.4 | Lc 60: larger content text | Open in checker |
| Success text on surface#008158 on #fbffff | 4.87:1 | AA 4.5:1 | Pass / Fail | Pass / Pass | +72.9 | Lc 60: larger content text | Open in checker |
| Success badge label on fill#fafcfd on #008457 | 4.59:1 | AA 4.5:1 | Pass / Fail | Pass / Pass | −75.5 | Lc 75: body text | Open in checker |
| Warning text on background#a06300 on #f4f7fa | 4.56:1 | AA 4.5:1 | Pass / Fail | Pass / Pass | +68.6 | Lc 60: larger content text | Open in checker |
| Warning text on surface#a06300 on #fbffff | 4.87:1 | AA 4.5:1 | Pass / Fail | Pass / Pass | +73.1 | Lc 60: larger content text | Open in checker |
| Warning badge label on fill#0f1010 on #ffba44 | 11.21:1 | AA 4.5:1 | Pass / Pass | Pass / Pass | +73.1 | Lc 60: larger content text | Open in checker |
| Error text on background#a21a1b on #f4f7fa | 7.23:1 | AA 4.5:1 | Pass / Pass | Pass / Pass | +80.2 | Lc 75: body text | Open in checker |
| Error text on surface#a21a1b on #fbffff | 7.72:1 | AA 4.5:1 | Pass / Pass | Pass / Pass | +84.8 | Lc 75: body text | Open in checker |
| Error badge label on fill#fafcfd on #c8322e | 5.16:1 | AA 4.5:1 | Pass / Fail | Pass / Pass | −78.2 | Lc 75: body text | Open in checker |
| Info text on background#2274af on #f4f7fa | 4.66:1 | AA 4.5:1 | Pass / Fail | Pass / Pass | +69.3 | Lc 60: larger content text | Open in checker |
| Info text on surface#2274af on #fbffff | 4.98:1 | AA 4.5:1 | Pass / Fail | Pass / Pass | +73.8 | Lc 60: larger content text | Open in checker |
| Info badge label on fill#fafcfd on #1377b9 | 4.67:1 | AA 4.5:1 | Pass / Fail | Pass / Pass | −76.1 | Lc 75: body text | Open in checker |
| Pair | WCAG ratio | Target | Normal AA / AAA | Large AA / AAA | APCA Lc | APCA tier | Check |
|---|---|---|---|---|---|---|---|
| Text on background#ebeff2 on #141618 | 15.68:1 | AAA 7:1 | Pass / Pass | Pass / Pass | −96.1 | Lc 75: body text | Open in checker |
| Text on surface#ebeff2 on #1e2122 | 14.01:1 | AAA 7:1 | Pass / Pass | Pass / Pass | −94.8 | Lc 75: body text | Open in checker |
| Muted text on background#b9bfc2 on #141618 | 9.75:1 | AAA 7:1 | Pass / Pass | Pass / Pass | −66.6 | Lc 60: larger content text | Open in checker |
| Muted text on surface#b9bfc2 on #1e2122 | 8.71:1 | AAA 7:1 | Pass / Pass | Pass / Pass | −65.3 | Lc 60: larger content text | Open in checker |
| Primary as link text on background#67caff on #141618 | 9.90:1 | AA 4.5:1 | Pass / Pass | Pass / Pass | −67.6 | Lc 60: larger content text | Open in checker |
| Primary as link text on surface#67caff on #1e2122 | 8.85:1 | AA 4.5:1 | Pass / Pass | Pass / Pass | −66.3 | Lc 60: larger content text | Open in checker |
| Button label on primary#0c0d0e on #67caff | 10.62:1 | AA 4.5:1 | Pass / Pass | Pass / Pass | +69.5 | Lc 60: larger content text | Open in checker |
| Accent text on background#95d7a2 on #141618 | 10.81:1 | AA 4.5:1 | Pass / Pass | Pass / Pass | −72.4 | Lc 60: larger content text | Open in checker |
| Accent text on surface#95d7a2 on #1e2122 | 9.66:1 | AA 4.5:1 | Pass / Pass | Pass / Pass | −71.1 | Lc 60: larger content text | Open in checker |
| Border on background#686c6f on #141618 | 3.42:1 | 3:1 (WCAG 1.4.11) | Fail / Fail | Pass / Fail | −24.5 | Below Lc 30 | Open in checker |
| Border on surface#686c6f on #1e2122 | 3.05:1 | 3:1 (WCAG 1.4.11) | Fail / Fail | Pass / Fail | −23.2 | Below Lc 30 | Open in checker |
| Focus ring on background#67caff on #141618 | 9.90:1 | 3:1 (WCAG 1.4.11) | Pass / Pass | Pass / Pass | −67.6 | Lc 60: larger content text | Open in checker |
| Focus ring on surface#67caff on #1e2122 | 8.85:1 | 3:1 (WCAG 1.4.11) | Pass / Pass | Pass / Pass | −66.3 | Lc 60: larger content text | Open in checker |
| Success text on background#6ce5b5 on #141618 | 11.67:1 | AA 4.5:1 | Pass / Pass | Pass / Pass | −77.0 | Lc 75: body text | Open in checker |
| Success text on surface#6ce5b5 on #1e2122 | 10.42:1 | AA 4.5:1 | Pass / Pass | Pass / Pass | −75.7 | Lc 75: body text | Open in checker |
| Success badge label on fill#0f1010 on #3bcd9a | 9.42:1 | AA 4.5:1 | Pass / Pass | Pass / Pass | +64.5 | Lc 60: larger content text | Open in checker |
| Warning text on background#ffbc56 on #141618 | 10.86:1 | AA 4.5:1 | Pass / Pass | Pass / Pass | −72.8 | Lc 60: larger content text | Open in checker |
| Warning text on surface#ffbc56 on #1e2122 | 9.70:1 | AA 4.5:1 | Pass / Pass | Pass / Pass | −71.5 | Lc 60: larger content text | Open in checker |
| Warning badge label on fill#0f1010 on #e9a11d | 8.69:1 | AA 4.5:1 | Pass / Pass | Pass / Pass | +60.6 | Lc 60: larger content text | Open in checker |
| Error text on background#f66d62 on #141618 | 6.29:1 | AA 4.5:1 | Pass / Fail | Pass / Pass | −46.5 | Lc 45: headlines and large text | Open in checker |
| Error text on surface#f66d62 on #1e2122 | 5.62:1 | AA 4.5:1 | Pass / Fail | Pass / Pass | −45.2 | Lc 45: headlines and large text | Open in checker |
| Error badge label on fill#0f1010 on #ff7a6d | 7.49:1 | AA 4.5:1 | Pass / Pass | Pass / Pass | +54.2 | Lc 45: headlines and large text | Open in checker |
| Info text on background#71bfff on #141618 | 9.15:1 | AA 4.5:1 | Pass / Pass | Pass / Pass | −63.4 | Lc 60: larger content text | Open in checker |
| Info text on surface#71bfff on #1e2122 | 8.17:1 | AA 4.5:1 | Pass / Pass | Pass / Pass | −62.1 | Lc 60: larger content text | Open in checker |
| Info badge label on fill#0f1010 on #61b9ff | 8.97:1 | AA 4.5:1 | Pass / Pass | Pass / Pass | +62.0 | Lc 60: larger content text | Open in checker |
Status colours and colour blindness
The four status fills were simulated for protanopia, deuteranopia and tritanopia (Machado et al., 2009). Success against error, the pair most often confused, must stay at least 6 ΔE-OK ×100 apart under every simulation. The other pairs are shown for information, so keep an icon and a word on every status.
| Pair | Normal vision | Protanopia | Deuteranopia | Tritanopia | Held to 6 |
|---|---|---|---|---|---|
| success / warning | 34.5 | 26.3 | 39.2 | 31.9 | Shown only |
| success / error | 28.5 | 16.2 | 6.4 | 33.0 | Yes |
| success / info | 17.1 | 16.2 | 15.3 | 3.2 | Shown only |
| warning / error | 31.8 | 42.0 | 37.4 | 22.6 | Shown only |
| warning / info | 40.0 | 34.2 | 44.5 | 31.2 | Shown only |
| error / info | 30.3 | 24.1 | 21.6 | 33.0 | Shown only |
Fills as simulated:Normal visionProtanopiaDeuteranopiaTritanopia
| Pair | Normal vision | Protanopia | Deuteranopia | Tritanopia | Held to 6 |
|---|---|---|---|---|---|
| success / warning | 20.9 | 11.8 | 15.5 | 27.5 | Shown only |
| success / error | 28.8 | 15.3 | 6.4 | 31.3 | Yes |
| success / info | 17.7 | 15.2 | 14.3 | 3.8 | Shown only |
| warning / error | 13.3 | 13.2 | 10.5 | 5.5 | Shown only |
| warning / info | 28.5 | 26.0 | 28.7 | 26.2 | Shown only |
| error / info | 28.3 | 21.8 | 20.8 | 29.7 | Shown only |
Fills as simulated:Normal visionProtanopiaDeuteranopiaTritanopia
Why these colours
The primary is a blue at OKLCH hue 235 and chroma 0.12, quiet and technical, with a green accent at hue 150 for success notes and copy confirmations. Docs avoid strong chroma because large areas of text and code dominate the page, and low-chroma neutrals tinted toward blue at 0.005 keep the page restful.
Muted text at 7:1 is a design decision, not a necessity. It stops muted from becoming a place where low contrast hides, and since muted text is a dark grey on the light theme the visual difference from body text is small. Lightness was solved against both the page and the card colours.
Reading documentation is also an act of comparison, since people flip between a page, an editor and a terminal. That makes consistency valuable: the same link colour, the same callout styling and the same code background across every page mean readers learn the visual language once and then stop thinking about it, which leaves attention for the content.
The generator solved 50 pairs (25 light, 25 dark), and all of them meet their target on the raw WCAG ratio. The tightest is success text on background in the light theme at 4.56:1 against a target of 4.5:1. After gamut mapping to sRGB the light primary keeps 94% of the requested chroma; hue was held throughout.
How to use it
- Pick a code-highlighting theme and verify each token colour against the code block background with the contrast checker; syntax themes often fail on comments.
- Show callouts with an icon, a title word such as Warning, and the verified badge pair.
- Underline links within paragraphs; the link colour alone does not identify them reliably.
- Keep the focus ring on sidebar links and the copy button visible, and let keyboard users skip the navigation.
- Use the dark theme for code-heavy pages if your readers prefer it, and verify both themes.
Export
Generated from the verified values above, never typed by hand. Light and dark are both included.
CSS custom properties (hex, then oklch())
/* sRGB hex first: every browser. */
:root {
--color-background: #f4f7fa;
--color-surface: #fbffff;
--color-text: #181b1d;
--color-text-muted: #505457;
--color-primary: #006c9d;
--color-primary-foreground: #fafcfd;
--color-accent: #397949;
--color-border: #8a8e92;
--color-focus-ring: #005d8d;
--color-success: #008158;
--color-success-solid: #008457;
--color-success-solid-foreground: #fafcfd;
--color-warning: #a06300;
--color-warning-solid: #ffba44;
--color-warning-solid-foreground: #0f1010;
--color-error: #a21a1b;
--color-error-solid: #c8322e;
--color-error-solid-foreground: #fafcfd;
--color-info: #2274af;
--color-info-solid: #1377b9;
--color-info-solid-foreground: #fafcfd;
}
.dark {
--color-background: #141618;
--color-surface: #1e2122;
--color-text: #ebeff2;
--color-text-muted: #b9bfc2;
--color-primary: #67caff;
--color-primary-foreground: #0c0d0e;
--color-accent: #95d7a2;
--color-border: #686c6f;
--color-focus-ring: #67caff;
--color-success: #6ce5b5;
--color-success-solid: #3bcd9a;
--color-success-solid-foreground: #0f1010;
--color-warning: #ffbc56;
--color-warning-solid: #e9a11d;
--color-warning-solid-foreground: #0f1010;
--color-error: #f66d62;
--color-error-solid: #ff7a6d;
--color-error-solid-foreground: #0f1010;
--color-info: #71bfff;
--color-info-solid: #61b9ff;
--color-info-solid-foreground: #0f1010;
}
/* oklch() where supported: the same colours, unclipped values of the hex above. */
@supports (color: oklch(0 0 0)) {
:root {
--color-background: oklch(0.975 0.005 247.9);
--color-surface: oklch(0.997 0.004 197.1);
--color-text: oklch(0.220 0.006 236.8);
--color-text-muted: oklch(0.443 0.007 240.0);
--color-primary: oklch(0.505 0.113 238.4);
--color-primary-foreground: oklch(0.990 0.003 228.8);
--color-accent: oklch(0.521 0.100 149.8);
--color-border: oklch(0.645 0.008 247.9);
--color-focus-ring: oklch(0.457 0.107 241.3);
--color-success: oklch(0.5333 0.1163 162.37);
--color-success-solid: oklch(0.5415 0.1211 160.71);
--color-success-solid-foreground: oklch(0.990 0.003 228.8);
--color-warning: oklch(0.5541 0.1212 68.45);
--color-warning-solid: oklch(0.8335 0.1508 76.88);
--color-warning-solid-foreground: oklch(0.172 0.002 197.0);
--color-error: oklch(0.4603 0.1706 26.95);
--color-error-solid: oklch(0.551 0.187 27.1);
--color-error-solid-foreground: oklch(0.990 0.003 228.8);
--color-info: oklch(0.540 0.120 245.0);
--color-info-solid: oklch(0.5501 0.1324 245.13);
--color-info-solid-foreground: oklch(0.990 0.003 228.8);
}
.dark {
--color-background: oklch(0.199 0.005 248.1);
--color-surface: oklch(0.245 0.005 219.7);
--color-text: oklch(0.950 0.006 239.8);
--color-text-muted: oklch(0.801 0.008 228.9);
--color-primary: oklch(0.7999 0.1195 234.40);
--color-primary-foreground: oklch(0.158 0.003 248.0);
--color-accent: oklch(0.821 0.100 149.9);
--color-border: oklch(0.529 0.007 239.9);
--color-focus-ring: oklch(0.7999 0.1195 234.40);
--color-success: oklch(0.839 0.130 164.9);
--color-success-solid: oklch(0.759 0.143 165.0);
--color-success-solid-foreground: oklch(0.172 0.002 197.0);
--color-warning: oklch(0.839 0.140 75.1);
--color-warning-solid: oklch(0.7605 0.1539 75.30);
--color-warning-solid-foreground: oklch(0.172 0.002 197.0);
--color-error: oklch(0.700 0.171 27.0);
--color-error-solid: oklch(0.732 0.165 27.5);
--color-error-solid-foreground: oklch(0.172 0.002 197.0);
--color-info: oklch(0.780 0.120 245.0);
--color-info-solid: oklch(0.760 0.132 244.8);
--color-info-solid-foreground: oklch(0.172 0.002 197.0);
}
}Tailwind CSS v4 @theme
@theme {
/* light */
--color-background: oklch(0.975 0.005 247.9); /* #f4f7fa */
--color-surface: oklch(0.997 0.004 197.1); /* #fbffff */
--color-text: oklch(0.220 0.006 236.8); /* #181b1d */
--color-text-muted: oklch(0.443 0.007 240.0); /* #505457 */
--color-primary: oklch(0.505 0.113 238.4); /* #006c9d */
--color-primary-foreground: oklch(0.990 0.003 228.8); /* #fafcfd */
--color-accent: oklch(0.521 0.100 149.8); /* #397949 */
--color-border: oklch(0.645 0.008 247.9); /* #8a8e92 */
--color-focus-ring: oklch(0.457 0.107 241.3); /* #005d8d */
--color-success: oklch(0.5333 0.1163 162.37); /* #008158 */
--color-success-solid: oklch(0.5415 0.1211 160.71); /* #008457 */
--color-success-solid-foreground: oklch(0.990 0.003 228.8); /* #fafcfd */
--color-warning: oklch(0.5541 0.1212 68.45); /* #a06300 */
--color-warning-solid: oklch(0.8335 0.1508 76.88); /* #ffba44 */
--color-warning-solid-foreground: oklch(0.172 0.002 197.0); /* #0f1010 */
--color-error: oklch(0.4603 0.1706 26.95); /* #a21a1b */
--color-error-solid: oklch(0.551 0.187 27.1); /* #c8322e */
--color-error-solid-foreground: oklch(0.990 0.003 228.8); /* #fafcfd */
--color-info: oklch(0.540 0.120 245.0); /* #2274af */
--color-info-solid: oklch(0.5501 0.1324 245.13); /* #1377b9 */
--color-info-solid-foreground: oklch(0.990 0.003 228.8); /* #fafcfd */
/* dark: use as dark:bg-background-dark, or remap under a .dark selector */
--color-background-dark: oklch(0.199 0.005 248.1); /* #141618 */
--color-surface-dark: oklch(0.245 0.005 219.7); /* #1e2122 */
--color-text-dark: oklch(0.950 0.006 239.8); /* #ebeff2 */
--color-text-muted-dark: oklch(0.801 0.008 228.9); /* #b9bfc2 */
--color-primary-dark: oklch(0.7999 0.1195 234.40); /* #67caff */
--color-primary-foreground-dark: oklch(0.158 0.003 248.0); /* #0c0d0e */
--color-accent-dark: oklch(0.821 0.100 149.9); /* #95d7a2 */
--color-border-dark: oklch(0.529 0.007 239.9); /* #686c6f */
--color-focus-ring-dark: oklch(0.7999 0.1195 234.40); /* #67caff */
--color-success-dark: oklch(0.839 0.130 164.9); /* #6ce5b5 */
--color-success-solid-dark: oklch(0.759 0.143 165.0); /* #3bcd9a */
--color-success-solid-foreground-dark: oklch(0.172 0.002 197.0); /* #0f1010 */
--color-warning-dark: oklch(0.839 0.140 75.1); /* #ffbc56 */
--color-warning-solid-dark: oklch(0.7605 0.1539 75.30); /* #e9a11d */
--color-warning-solid-foreground-dark: oklch(0.172 0.002 197.0); /* #0f1010 */
--color-error-dark: oklch(0.700 0.171 27.0); /* #f66d62 */
--color-error-solid-dark: oklch(0.732 0.165 27.5); /* #ff7a6d */
--color-error-solid-foreground-dark: oklch(0.172 0.002 197.0); /* #0f1010 */
--color-info-dark: oklch(0.780 0.120 245.0); /* #71bfff */
--color-info-solid-dark: oklch(0.760 0.132 244.8); /* #61b9ff */
--color-info-solid-foreground-dark: oklch(0.172 0.002 197.0); /* #0f1010 */
}shadcn/ui variables (:root and .dark)
:root {
--background: oklch(0.975 0.005 247.9);
--foreground: oklch(0.220 0.006 236.8);
--card: oklch(0.997 0.004 197.1);
--card-foreground: oklch(0.220 0.006 236.8);
--popover: oklch(0.997 0.004 197.1);
--popover-foreground: oklch(0.220 0.006 236.8);
--primary: oklch(0.505 0.113 238.4);
--primary-foreground: oklch(0.990 0.003 228.8);
--secondary: oklch(0.997 0.004 197.1);
--secondary-foreground: oklch(0.220 0.006 236.8);
--muted: oklch(0.997 0.004 197.1);
--muted-foreground: oklch(0.443 0.007 240.0);
--accent: oklch(0.997 0.004 197.1);
--accent-foreground: oklch(0.220 0.006 236.8);
--destructive: oklch(0.551 0.187 27.1);
--destructive-foreground: oklch(0.990 0.003 228.8);
--border: oklch(0.645 0.008 247.9);
--input: oklch(0.645 0.008 247.9);
--ring: oklch(0.457 0.107 241.3);
--success: oklch(0.5415 0.1211 160.71);
--success-foreground: oklch(0.990 0.003 228.8);
--warning: oklch(0.8335 0.1508 76.88);
--warning-foreground: oklch(0.172 0.002 197.0);
--info: oklch(0.5501 0.1324 245.13);
--info-foreground: oklch(0.990 0.003 228.8);
--brand-accent: oklch(0.521 0.100 149.8);
}
.dark {
--background: oklch(0.199 0.005 248.1);
--foreground: oklch(0.950 0.006 239.8);
--card: oklch(0.245 0.005 219.7);
--card-foreground: oklch(0.950 0.006 239.8);
--popover: oklch(0.245 0.005 219.7);
--popover-foreground: oklch(0.950 0.006 239.8);
--primary: oklch(0.7999 0.1195 234.40);
--primary-foreground: oklch(0.158 0.003 248.0);
--secondary: oklch(0.245 0.005 219.7);
--secondary-foreground: oklch(0.950 0.006 239.8);
--muted: oklch(0.245 0.005 219.7);
--muted-foreground: oklch(0.801 0.008 228.9);
--accent: oklch(0.245 0.005 219.7);
--accent-foreground: oklch(0.950 0.006 239.8);
--destructive: oklch(0.732 0.165 27.5);
--destructive-foreground: oklch(0.172 0.002 197.0);
--border: oklch(0.529 0.007 239.9);
--input: oklch(0.529 0.007 239.9);
--ring: oklch(0.7999 0.1195 234.40);
--success: oklch(0.759 0.143 165.0);
--success-foreground: oklch(0.172 0.002 197.0);
--warning: oklch(0.7605 0.1539 75.30);
--warning-foreground: oklch(0.172 0.002 197.0);
--info: oklch(0.760 0.132 244.8);
--info-foreground: oklch(0.172 0.002 197.0);
--brand-accent: oklch(0.821 0.100 149.9);
}Design tokens (DTCG-style JSON)
{
"color": {
"light": {
"background": {
"$type": "color",
"$value": "oklch(0.975 0.005 247.9)",
"$description": "sRGB #f4f7fa"
},
"surface": {
"$type": "color",
"$value": "oklch(0.997 0.004 197.1)",
"$description": "sRGB #fbffff"
},
"text": {
"$type": "color",
"$value": "oklch(0.220 0.006 236.8)",
"$description": "sRGB #181b1d"
},
"text-muted": {
"$type": "color",
"$value": "oklch(0.443 0.007 240.0)",
"$description": "sRGB #505457"
},
"primary": {
"$type": "color",
"$value": "oklch(0.505 0.113 238.4)",
"$description": "sRGB #006c9d"
},
"primary-foreground": {
"$type": "color",
"$value": "oklch(0.990 0.003 228.8)",
"$description": "sRGB #fafcfd"
},
"accent": {
"$type": "color",
"$value": "oklch(0.521 0.100 149.8)",
"$description": "sRGB #397949"
},
"border": {
"$type": "color",
"$value": "oklch(0.645 0.008 247.9)",
"$description": "sRGB #8a8e92"
},
"focus-ring": {
"$type": "color",
"$value": "oklch(0.457 0.107 241.3)",
"$description": "sRGB #005d8d"
},
"success": {
"$type": "color",
"$value": "oklch(0.5333 0.1163 162.37)",
"$description": "sRGB #008158"
},
"success-solid": {
"$type": "color",
"$value": "oklch(0.5415 0.1211 160.71)",
"$description": "sRGB #008457"
},
"success-solid-foreground": {
"$type": "color",
"$value": "oklch(0.990 0.003 228.8)",
"$description": "sRGB #fafcfd"
},
"warning": {
"$type": "color",
"$value": "oklch(0.5541 0.1212 68.45)",
"$description": "sRGB #a06300"
},
"warning-solid": {
"$type": "color",
"$value": "oklch(0.8335 0.1508 76.88)",
"$description": "sRGB #ffba44"
},
"warning-solid-foreground": {
"$type": "color",
"$value": "oklch(0.172 0.002 197.0)",
"$description": "sRGB #0f1010"
},
"error": {
"$type": "color",
"$value": "oklch(0.4603 0.1706 26.95)",
"$description": "sRGB #a21a1b"
},
"error-solid": {
"$type": "color",
"$value": "oklch(0.551 0.187 27.1)",
"$description": "sRGB #c8322e"
},
"error-solid-foreground": {
"$type": "color",
"$value": "oklch(0.990 0.003 228.8)",
"$description": "sRGB #fafcfd"
},
"info": {
"$type": "color",
"$value": "oklch(0.540 0.120 245.0)",
"$description": "sRGB #2274af"
},
"info-solid": {
"$type": "color",
"$value": "oklch(0.5501 0.1324 245.13)",
"$description": "sRGB #1377b9"
},
"info-solid-foreground": {
"$type": "color",
"$value": "oklch(0.990 0.003 228.8)",
"$description": "sRGB #fafcfd"
}
},
"dark": {
"background": {
"$type": "color",
"$value": "oklch(0.199 0.005 248.1)",
"$description": "sRGB #141618"
},
"surface": {
"$type": "color",
"$value": "oklch(0.245 0.005 219.7)",
"$description": "sRGB #1e2122"
},
"text": {
"$type": "color",
"$value": "oklch(0.950 0.006 239.8)",
"$description": "sRGB #ebeff2"
},
"text-muted": {
"$type": "color",
"$value": "oklch(0.801 0.008 228.9)",
"$description": "sRGB #b9bfc2"
},
"primary": {
"$type": "color",
"$value": "oklch(0.7999 0.1195 234.40)",
"$description": "sRGB #67caff"
},
"primary-foreground": {
"$type": "color",
"$value": "oklch(0.158 0.003 248.0)",
"$description": "sRGB #0c0d0e"
},
"accent": {
"$type": "color",
"$value": "oklch(0.821 0.100 149.9)",
"$description": "sRGB #95d7a2"
},
"border": {
"$type": "color",
"$value": "oklch(0.529 0.007 239.9)",
"$description": "sRGB #686c6f"
},
"focus-ring": {
"$type": "color",
"$value": "oklch(0.7999 0.1195 234.40)",
"$description": "sRGB #67caff"
},
"success": {
"$type": "color",
"$value": "oklch(0.839 0.130 164.9)",
"$description": "sRGB #6ce5b5"
},
"success-solid": {
"$type": "color",
"$value": "oklch(0.759 0.143 165.0)",
"$description": "sRGB #3bcd9a"
},
"success-solid-foreground": {
"$type": "color",
"$value": "oklch(0.172 0.002 197.0)",
"$description": "sRGB #0f1010"
},
"warning": {
"$type": "color",
"$value": "oklch(0.839 0.140 75.1)",
"$description": "sRGB #ffbc56"
},
"warning-solid": {
"$type": "color",
"$value": "oklch(0.7605 0.1539 75.30)",
"$description": "sRGB #e9a11d"
},
"warning-solid-foreground": {
"$type": "color",
"$value": "oklch(0.172 0.002 197.0)",
"$description": "sRGB #0f1010"
},
"error": {
"$type": "color",
"$value": "oklch(0.700 0.171 27.0)",
"$description": "sRGB #f66d62"
},
"error-solid": {
"$type": "color",
"$value": "oklch(0.732 0.165 27.5)",
"$description": "sRGB #ff7a6d"
},
"error-solid-foreground": {
"$type": "color",
"$value": "oklch(0.172 0.002 197.0)",
"$description": "sRGB #0f1010"
},
"info": {
"$type": "color",
"$value": "oklch(0.780 0.120 245.0)",
"$description": "sRGB #71bfff"
},
"info-solid": {
"$type": "color",
"$value": "oklch(0.760 0.132 244.8)",
"$description": "sRGB #61b9ff"
},
"info-solid-foreground": {
"$type": "color",
"$value": "oklch(0.172 0.002 197.0)",
"$description": "sRGB #0f1010"
}
}
}
}Open in the studio
Take the primary colour into the picker, build a tonal scale from it, or check any pair of your own.
Open #006C9D in the OKLCH picker →Build a tonal scale →Check a pair
FAQ
- Do syntax highlighting colours need to pass?
- Code is text, so WCAG contrast applies. Many themes fail on comments and punctuation, so check them or choose a theme designed to meet AA.
- Why is muted text AAA here?
- Documentation uses muted text heavily for navigation and captions, and readers scan it constantly. Raising it costs little visually.
- Can I use these colours in a docs framework?
- Most frameworks accept CSS variables. Use the CSS export and map the names to your framework's variables.
- Where can I learn the basics?
- Start with the accessible colour palette guide for the method, and the WCAG vs APCA guide for the numbers.