OKLCH Studio · Accessible palettes · Special needs
ADA-oriented colour palette: conservative WCAG-based contrast
Updated 2026-10-19
The Americans with Disabilities Act does not contain a colour contrast number. In practice, accessibility claims, settlements and government rules in the US commonly point to WCAG, usually at AA, as the benchmark for web content. That is why people search for an ADA compliant colour palette: they want colours that make a WCAG-based claim defensible. This page is not legal advice.
A palette cannot make a site ADA compliant, and no colour set can. What it can do is remove one common, easily detected source of complaints, low contrast text, by giving you pairs with a margin. Here, body and muted text are at AAA, 7:1, and interactive colours and status colours at AA, 4.5:1, with 3:1 for borders and focus rings.
The margin matters because contrast gets lost in practice: gradients, opacity, hover states, tinted cards, and third-party widgets can each erode a pair. Starting from a conservative set means small erosion still stays above 4.5:1.
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
#F9F6F4
oklch(0.975 0.004 56.4)
Sample text
- Surface
#FFFDFB
oklch(0.995 0.003 67.8)
Sample text
- Text
#1C1A18
oklch(0.219 0.005 67.6)
Sample text
- Muted text
#575351
oklch(0.445 0.006 48.6)
Sample text
- Primary
#006AA0
oklch(0.502 0.118 241.4)
Sample text
- Primary foreground
#FDFBFB
oklch(0.990 0.002 17.2)
Sample text
- Accent
#A44C1D
oklch(0.521 0.130 45.3)
Sample text
- Border
#918D8B
oklch(0.646 0.006 48.6)
Sample text
- Focus ring
#005B90
oklch(0.454 0.113 244.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
#FDFBFB
oklch(0.990 0.002 17.2)
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
#100F0F
oklch(0.170 0.002 17.3)
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
#FDFBFB
oklch(0.990 0.002 17.2)
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
#FDFBFB
oklch(0.990 0.002 17.2)
Sample text
Appointment confirmed
Secondary text sits on the surface colour.
Link in primary · Accent text
Dark theme
- Background
#171614
oklch(0.201 0.004 84.6)
Sample text
- Surface
#22201F
oklch(0.245 0.004 48.6)
Sample text
- Text
#F1EEEB
oklch(0.951 0.005 67.8)
Sample text
- Muted text
#C1BDBA
oklch(0.801 0.006 59.6)
Sample text
- Primary
#6FC8FF
oklch(0.799 0.116 237.7)
Sample text
- Primary foreground
#0E0D0D
oklch(0.160 0.002 17.3)
Sample text
- Accent
#FFA87B
oklch(0.808 0.119 47.9)
Sample text
- Border
#6E6B68
oklch(0.530 0.006 67.7)
Sample text
- Focus ring
#6FC8FF
oklch(0.799 0.116 237.7)
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
#100F0F
oklch(0.170 0.002 17.3)
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
#100F0F
oklch(0.170 0.002 17.3)
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
#100F0F
oklch(0.170 0.002 17.3)
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
#100F0F
oklch(0.170 0.002 17.3)
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#1c1a18 on #f9f6f4 | 16.12:1 | AAA 7:1 | Pass / Pass | Pass / Pass | +99.1 | Lc 75: body text | Open in checker |
| Text on surface#1c1a18 on #fffdfb | 17.09:1 | AAA 7:1 | Pass / Pass | Pass / Pass | +103.2 | Lc 75: body text | Open in checker |
| Muted text on background#575351 on #f9f6f4 | 7.06:1 | AAA 7:1 | Pass / Pass | Pass / Pass | +81.4 | Lc 75: body text | Open in checker |
| Muted text on surface#575351 on #fffdfb | 7.49:1 | AAA 7:1 | Pass / Pass | Pass / Pass | +85.4 | Lc 75: body text | Open in checker |
| Primary as link text on background#006aa0 on #f9f6f4 | 5.46:1 | AA 4.5:1 | Pass / Fail | Pass / Pass | +73.7 | Lc 60: larger content text | Open in checker |
| Primary as link text on surface#006aa0 on #fffdfb | 5.79:1 | AA 4.5:1 | Pass / Fail | Pass / Pass | +77.8 | Lc 75: body text | Open in checker |
| Button label on primary#fdfbfb on #006aa0 | 5.70:1 | AA 4.5:1 | Pass / Fail | Pass / Pass | −81.7 | Lc 75: body text | Open in checker |
| Accent text on background#a44c1d on #f9f6f4 | 5.37:1 | AA 4.5:1 | Pass / Fail | Pass / Pass | +73.3 | Lc 60: larger content text | Open in checker |
| Accent text on surface#a44c1d on #fffdfb | 5.70:1 | AA 4.5:1 | Pass / Fail | Pass / Pass | +77.3 | Lc 75: body text | Open in checker |
| Border on background#918d8b on #f9f6f4 | 3.05:1 | 3:1 (WCAG 1.4.11) | Fail / Fail | Pass / Fail | +55.2 | Lc 45: headlines and large text | Open in checker |
| Border on surface#918d8b on #fffdfb | 3.24:1 | 3:1 (WCAG 1.4.11) | Fail / Fail | Pass / Fail | +59.2 | Lc 45: headlines and large text | Open in checker |
| Focus ring on background#005b90 on #f9f6f4 | 6.73:1 | 3:1 (WCAG 1.4.11) | Pass / Fail | Pass / Pass | +79.5 | Lc 75: body text | Open in checker |
| Focus ring on surface#005b90 on #fffdfb | 7.13:1 | 3:1 (WCAG 1.4.11) | Pass / Pass | Pass / Pass | +83.5 | Lc 75: body text | Open in checker |
| Success text on background#008158 on #f9f6f4 | 4.55:1 | AA 4.5:1 | Pass / Fail | Pass / Pass | +68.3 | Lc 60: larger content text | Open in checker |
| Success text on surface#008158 on #fffdfb | 4.83:1 | AA 4.5:1 | Pass / Fail | Pass / Pass | +72.4 | Lc 60: larger content text | Open in checker |
| Success badge label on fill#fdfbfb on #008457 | 4.58:1 | AA 4.5:1 | Pass / Fail | Pass / Pass | −75.3 | Lc 75: body text | Open in checker |
| Warning text on background#a06300 on #f9f6f4 | 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 #fffdfb | 4.83:1 | AA 4.5:1 | Pass / Fail | Pass / Pass | +72.6 | Lc 60: larger content text | Open in checker |
| Warning badge label on fill#100f0f on #ffba44 | 11.26:1 | AA 4.5:1 | Pass / Pass | Pass / Pass | +73.2 | Lc 60: larger content text | Open in checker |
| Error text on background#a21a1b on #f9f6f4 | 7.22:1 | AA 4.5:1 | Pass / Pass | Pass / Pass | +80.2 | Lc 75: body text | Open in checker |
| Error text on surface#a21a1b on #fffdfb | 7.66:1 | AA 4.5:1 | Pass / Pass | Pass / Pass | +84.2 | Lc 75: body text | Open in checker |
| Error badge label on fill#fdfbfb on #c8322e | 5.15:1 | AA 4.5:1 | Pass / Fail | Pass / Pass | −78.0 | Lc 75: body text | Open in checker |
| Info text on background#2274af on #f9f6f4 | 4.66:1 | AA 4.5:1 | Pass / Fail | Pass / Pass | +69.2 | Lc 60: larger content text | Open in checker |
| Info text on surface#2274af on #fffdfb | 4.94:1 | AA 4.5:1 | Pass / Fail | Pass / Pass | +73.3 | Lc 60: larger content text | Open in checker |
| Info badge label on fill#fdfbfb on #1377b9 | 4.66:1 | AA 4.5:1 | Pass / Fail | Pass / Pass | −75.9 | 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#f1eeeb on #171614 | 15.64:1 | AAA 7:1 | Pass / Pass | Pass / Pass | −96.1 | Lc 75: body text | Open in checker |
| Text on surface#f1eeeb on #22201f | 14.03:1 | AAA 7:1 | Pass / Pass | Pass / Pass | −94.9 | Lc 75: body text | Open in checker |
| Muted text on background#c1bdba on #171614 | 9.69:1 | AAA 7:1 | Pass / Pass | Pass / Pass | −66.3 | Lc 60: larger content text | Open in checker |
| Muted text on surface#c1bdba on #22201f | 8.69:1 | AAA 7:1 | Pass / Pass | Pass / Pass | −65.1 | Lc 60: larger content text | Open in checker |
| Primary as link text on background#6fc8ff on #171614 | 9.80:1 | AA 4.5:1 | Pass / Pass | Pass / Pass | −67.2 | Lc 60: larger content text | Open in checker |
| Primary as link text on surface#6fc8ff on #22201f | 8.79:1 | AA 4.5:1 | Pass / Pass | Pass / Pass | −65.9 | Lc 60: larger content text | Open in checker |
| Button label on primary#0e0d0d on #6fc8ff | 10.51:1 | AA 4.5:1 | Pass / Pass | Pass / Pass | +69.0 | Lc 60: larger content text | Open in checker |
| Accent text on background#ffa87b on #171614 | 9.59:1 | AA 4.5:1 | Pass / Pass | Pass / Pass | −66.0 | Lc 60: larger content text | Open in checker |
| Accent text on surface#ffa87b on #22201f | 8.60:1 | AA 4.5:1 | Pass / Pass | Pass / Pass | −64.8 | Lc 60: larger content text | Open in checker |
| Border on background#6e6b68 on #171614 | 3.41:1 | 3:1 (WCAG 1.4.11) | Fail / Fail | Pass / Fail | −24.5 | Below Lc 30 | Open in checker |
| Border on surface#6e6b68 on #22201f | 3.06:1 | 3:1 (WCAG 1.4.11) | Fail / Fail | Pass / Fail | −23.2 | Below Lc 30 | Open in checker |
| Focus ring on background#6fc8ff on #171614 | 9.80:1 | 3:1 (WCAG 1.4.11) | Pass / Pass | Pass / Pass | −67.2 | Lc 60: larger content text | Open in checker |
| Focus ring on surface#6fc8ff on #22201f | 8.79:1 | 3:1 (WCAG 1.4.11) | Pass / Pass | Pass / Pass | −65.9 | Lc 60: larger content text | Open in checker |
| Success text on background#6ce5b5 on #171614 | 11.63:1 | AA 4.5:1 | Pass / Pass | Pass / Pass | −77.0 | Lc 75: body text | Open in checker |
| Success text on surface#6ce5b5 on #22201f | 10.43:1 | AA 4.5:1 | Pass / Pass | Pass / Pass | −75.7 | Lc 75: body text | Open in checker |
| Success badge label on fill#100f0f on #3bcd9a | 9.46: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 #171614 | 10.83:1 | AA 4.5:1 | Pass / Pass | Pass / Pass | −72.7 | Lc 60: larger content text | Open in checker |
| Warning text on surface#ffbc56 on #22201f | 9.71:1 | AA 4.5:1 | Pass / Pass | Pass / Pass | −71.5 | Lc 60: larger content text | Open in checker |
| Warning badge label on fill#100f0f on #e9a11d | 8.73: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 #171614 | 6.27: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 #22201f | 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#100f0f on #ff7a6d | 7.52: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 #171614 | 9.12: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 #22201f | 8.18:1 | AA 4.5:1 | Pass / Pass | Pass / Pass | −62.1 | Lc 60: larger content text | Open in checker |
| Info badge label on fill#100f0f on #61b9ff | 9.01: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 hue is a blue at OKLCH hue 240 and chroma 0.12, with a warm orange accent at hue 45. The neutrals are a faint warm grey at hue 60. These are conservative choices on purpose: familiar link blue, a restrained palette and a warm page that is easy on the eyes.
The generator moves each role only as far as needed to reach its target against both the page and the card, which means primary and accent are the lightest values that still pass at AA, while text and muted text sit at AAA. The table lists every pair with its WCAG ratio and APCA Lc so that an auditor can follow the numbers.
Teams sometimes ask for a single number to put in a policy. A better statement is a list: which pairs exist in the design system, what ratio each reaches, and how they are re-tested when something changes. That list is what this page's tables provide, and it turns a vague promise of compliance into something an auditor or developer can verify line by line.
The generator solved 50 pairs (25 light, 25 dark), and all of them meet their target on the raw WCAG ratio. The tightest is muted text on background in the light theme at 7.06:1 against a target of 7:1. After gamut mapping to sRGB the light primary keeps 98% of the requested chroma; hue was held throughout.
How to use it
- Keep a record of the pairs you use and their ratios; evidence of testing helps in any review.
- Test overlays, hover and focus states, as well as default states.
- Use text alternatives and captions; colour is the easy part of an accessibility programme.
- Do not use opacity on text to make it lighter; compute a solid colour instead and verify it.
- Ask a qualified accessibility professional about legal exposure; this palette is a design aid only.
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: #f9f6f4;
--color-surface: #fffdfb;
--color-text: #1c1a18;
--color-text-muted: #575351;
--color-primary: #006aa0;
--color-primary-foreground: #fdfbfb;
--color-accent: #a44c1d;
--color-border: #918d8b;
--color-focus-ring: #005b90;
--color-success: #008158;
--color-success-solid: #008457;
--color-success-solid-foreground: #fdfbfb;
--color-warning: #a06300;
--color-warning-solid: #ffba44;
--color-warning-solid-foreground: #100f0f;
--color-error: #a21a1b;
--color-error-solid: #c8322e;
--color-error-solid-foreground: #fdfbfb;
--color-info: #2274af;
--color-info-solid: #1377b9;
--color-info-solid-foreground: #fdfbfb;
}
.dark {
--color-background: #171614;
--color-surface: #22201f;
--color-text: #f1eeeb;
--color-text-muted: #c1bdba;
--color-primary: #6fc8ff;
--color-primary-foreground: #0e0d0d;
--color-accent: #ffa87b;
--color-border: #6e6b68;
--color-focus-ring: #6fc8ff;
--color-success: #6ce5b5;
--color-success-solid: #3bcd9a;
--color-success-solid-foreground: #100f0f;
--color-warning: #ffbc56;
--color-warning-solid: #e9a11d;
--color-warning-solid-foreground: #100f0f;
--color-error: #f66d62;
--color-error-solid: #ff7a6d;
--color-error-solid-foreground: #100f0f;
--color-info: #71bfff;
--color-info-solid: #61b9ff;
--color-info-solid-foreground: #100f0f;
}
/* 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.004 56.4);
--color-surface: oklch(0.995 0.003 67.8);
--color-text: oklch(0.219 0.005 67.6);
--color-text-muted: oklch(0.445 0.006 48.6);
--color-primary: oklch(0.502 0.118 241.4);
--color-primary-foreground: oklch(0.990 0.002 17.2);
--color-accent: oklch(0.521 0.130 45.3);
--color-border: oklch(0.646 0.006 48.6);
--color-focus-ring: oklch(0.454 0.113 244.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.002 17.2);
--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.170 0.002 17.3);
--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.002 17.2);
--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.002 17.2);
}
.dark {
--color-background: oklch(0.201 0.004 84.6);
--color-surface: oklch(0.245 0.004 48.6);
--color-text: oklch(0.951 0.005 67.8);
--color-text-muted: oklch(0.801 0.006 59.6);
--color-primary: oklch(0.799 0.116 237.7);
--color-primary-foreground: oklch(0.160 0.002 17.3);
--color-accent: oklch(0.808 0.119 47.9);
--color-border: oklch(0.530 0.006 67.7);
--color-focus-ring: oklch(0.799 0.116 237.7);
--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.170 0.002 17.3);
--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.170 0.002 17.3);
--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.170 0.002 17.3);
--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.170 0.002 17.3);
}
}Tailwind CSS v4 @theme
@theme {
/* light */
--color-background: oklch(0.975 0.004 56.4); /* #f9f6f4 */
--color-surface: oklch(0.995 0.003 67.8); /* #fffdfb */
--color-text: oklch(0.219 0.005 67.6); /* #1c1a18 */
--color-text-muted: oklch(0.445 0.006 48.6); /* #575351 */
--color-primary: oklch(0.502 0.118 241.4); /* #006aa0 */
--color-primary-foreground: oklch(0.990 0.002 17.2); /* #fdfbfb */
--color-accent: oklch(0.521 0.130 45.3); /* #a44c1d */
--color-border: oklch(0.646 0.006 48.6); /* #918d8b */
--color-focus-ring: oklch(0.454 0.113 244.3); /* #005b90 */
--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.002 17.2); /* #fdfbfb */
--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.170 0.002 17.3); /* #100f0f */
--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.002 17.2); /* #fdfbfb */
--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.002 17.2); /* #fdfbfb */
/* dark: use as dark:bg-background-dark, or remap under a .dark selector */
--color-background-dark: oklch(0.201 0.004 84.6); /* #171614 */
--color-surface-dark: oklch(0.245 0.004 48.6); /* #22201f */
--color-text-dark: oklch(0.951 0.005 67.8); /* #f1eeeb */
--color-text-muted-dark: oklch(0.801 0.006 59.6); /* #c1bdba */
--color-primary-dark: oklch(0.799 0.116 237.7); /* #6fc8ff */
--color-primary-foreground-dark: oklch(0.160 0.002 17.3); /* #0e0d0d */
--color-accent-dark: oklch(0.808 0.119 47.9); /* #ffa87b */
--color-border-dark: oklch(0.530 0.006 67.7); /* #6e6b68 */
--color-focus-ring-dark: oklch(0.799 0.116 237.7); /* #6fc8ff */
--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.170 0.002 17.3); /* #100f0f */
--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.170 0.002 17.3); /* #100f0f */
--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.170 0.002 17.3); /* #100f0f */
--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.170 0.002 17.3); /* #100f0f */
}shadcn/ui variables (:root and .dark)
:root {
--background: oklch(0.975 0.004 56.4);
--foreground: oklch(0.219 0.005 67.6);
--card: oklch(0.995 0.003 67.8);
--card-foreground: oklch(0.219 0.005 67.6);
--popover: oklch(0.995 0.003 67.8);
--popover-foreground: oklch(0.219 0.005 67.6);
--primary: oklch(0.502 0.118 241.4);
--primary-foreground: oklch(0.990 0.002 17.2);
--secondary: oklch(0.995 0.003 67.8);
--secondary-foreground: oklch(0.219 0.005 67.6);
--muted: oklch(0.995 0.003 67.8);
--muted-foreground: oklch(0.445 0.006 48.6);
--accent: oklch(0.995 0.003 67.8);
--accent-foreground: oklch(0.219 0.005 67.6);
--destructive: oklch(0.551 0.187 27.1);
--destructive-foreground: oklch(0.990 0.002 17.2);
--border: oklch(0.646 0.006 48.6);
--input: oklch(0.646 0.006 48.6);
--ring: oklch(0.454 0.113 244.3);
--success: oklch(0.5415 0.1211 160.71);
--success-foreground: oklch(0.990 0.002 17.2);
--warning: oklch(0.8335 0.1508 76.88);
--warning-foreground: oklch(0.170 0.002 17.3);
--info: oklch(0.5501 0.1324 245.13);
--info-foreground: oklch(0.990 0.002 17.2);
--brand-accent: oklch(0.521 0.130 45.3);
}
.dark {
--background: oklch(0.201 0.004 84.6);
--foreground: oklch(0.951 0.005 67.8);
--card: oklch(0.245 0.004 48.6);
--card-foreground: oklch(0.951 0.005 67.8);
--popover: oklch(0.245 0.004 48.6);
--popover-foreground: oklch(0.951 0.005 67.8);
--primary: oklch(0.799 0.116 237.7);
--primary-foreground: oklch(0.160 0.002 17.3);
--secondary: oklch(0.245 0.004 48.6);
--secondary-foreground: oklch(0.951 0.005 67.8);
--muted: oklch(0.245 0.004 48.6);
--muted-foreground: oklch(0.801 0.006 59.6);
--accent: oklch(0.245 0.004 48.6);
--accent-foreground: oklch(0.951 0.005 67.8);
--destructive: oklch(0.732 0.165 27.5);
--destructive-foreground: oklch(0.170 0.002 17.3);
--border: oklch(0.530 0.006 67.7);
--input: oklch(0.530 0.006 67.7);
--ring: oklch(0.799 0.116 237.7);
--success: oklch(0.759 0.143 165.0);
--success-foreground: oklch(0.170 0.002 17.3);
--warning: oklch(0.7605 0.1539 75.30);
--warning-foreground: oklch(0.170 0.002 17.3);
--info: oklch(0.760 0.132 244.8);
--info-foreground: oklch(0.170 0.002 17.3);
--brand-accent: oklch(0.808 0.119 47.9);
}Design tokens (DTCG-style JSON)
{
"color": {
"light": {
"background": {
"$type": "color",
"$value": "oklch(0.975 0.004 56.4)",
"$description": "sRGB #f9f6f4"
},
"surface": {
"$type": "color",
"$value": "oklch(0.995 0.003 67.8)",
"$description": "sRGB #fffdfb"
},
"text": {
"$type": "color",
"$value": "oklch(0.219 0.005 67.6)",
"$description": "sRGB #1c1a18"
},
"text-muted": {
"$type": "color",
"$value": "oklch(0.445 0.006 48.6)",
"$description": "sRGB #575351"
},
"primary": {
"$type": "color",
"$value": "oklch(0.502 0.118 241.4)",
"$description": "sRGB #006aa0"
},
"primary-foreground": {
"$type": "color",
"$value": "oklch(0.990 0.002 17.2)",
"$description": "sRGB #fdfbfb"
},
"accent": {
"$type": "color",
"$value": "oklch(0.521 0.130 45.3)",
"$description": "sRGB #a44c1d"
},
"border": {
"$type": "color",
"$value": "oklch(0.646 0.006 48.6)",
"$description": "sRGB #918d8b"
},
"focus-ring": {
"$type": "color",
"$value": "oklch(0.454 0.113 244.3)",
"$description": "sRGB #005b90"
},
"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.002 17.2)",
"$description": "sRGB #fdfbfb"
},
"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.170 0.002 17.3)",
"$description": "sRGB #100f0f"
},
"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.002 17.2)",
"$description": "sRGB #fdfbfb"
},
"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.002 17.2)",
"$description": "sRGB #fdfbfb"
}
},
"dark": {
"background": {
"$type": "color",
"$value": "oklch(0.201 0.004 84.6)",
"$description": "sRGB #171614"
},
"surface": {
"$type": "color",
"$value": "oklch(0.245 0.004 48.6)",
"$description": "sRGB #22201f"
},
"text": {
"$type": "color",
"$value": "oklch(0.951 0.005 67.8)",
"$description": "sRGB #f1eeeb"
},
"text-muted": {
"$type": "color",
"$value": "oklch(0.801 0.006 59.6)",
"$description": "sRGB #c1bdba"
},
"primary": {
"$type": "color",
"$value": "oklch(0.799 0.116 237.7)",
"$description": "sRGB #6fc8ff"
},
"primary-foreground": {
"$type": "color",
"$value": "oklch(0.160 0.002 17.3)",
"$description": "sRGB #0e0d0d"
},
"accent": {
"$type": "color",
"$value": "oklch(0.808 0.119 47.9)",
"$description": "sRGB #ffa87b"
},
"border": {
"$type": "color",
"$value": "oklch(0.530 0.006 67.7)",
"$description": "sRGB #6e6b68"
},
"focus-ring": {
"$type": "color",
"$value": "oklch(0.799 0.116 237.7)",
"$description": "sRGB #6fc8ff"
},
"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.170 0.002 17.3)",
"$description": "sRGB #100f0f"
},
"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.170 0.002 17.3)",
"$description": "sRGB #100f0f"
},
"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.170 0.002 17.3)",
"$description": "sRGB #100f0f"
},
"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.170 0.002 17.3)",
"$description": "sRGB #100f0f"
}
}
}
}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 #006AA0 in the OKLCH picker →Build a tonal scale →Check a pair
FAQ
- Does the ADA require a particular contrast ratio?
- The statute does not. WCAG, commonly at level AA, is the benchmark that most guidance, rules and settlements reference. Which one applies to you is a legal question.
- Is using this palette enough to be compliant?
- No. It covers colour contrast only. Compliance depends on the whole experience, including keyboard access, labels and captions.
- Why AAA for text if AA is the benchmark?
- To leave a margin. Tints, overlays and third-party code often reduce contrast, and starting well above 4.5:1 keeps the result above it.
- How is it different from the WCAG palette?
- The WCAG compliant palette targets AA only. This one raises text and muted text to AAA for headroom.