# How accessible is it?

What the palette guarantees for contrast in every hue and mode, and what you still need to check.

Text you draw with the tokens passes WCAG AA on the page and card backgrounds, in both modes and every hue. Four things stay yours to check: text on the third background, control borders, meaning shown by hue alone, and Increase Contrast.

```swift
let theme = Color.proOrange   // Lisbon

VStack(alignment: .leading, spacing: 4) {
    Text("Lisbon")
        .font(.headline)
        .foregroundStyle(theme.foregroundPrimary)
    Text("3 nights from October 12")
        .font(.subheadline)
        .foregroundStyle(theme.foregroundSecondary)
    Text("€480")
        .font(.subheadline)
        .foregroundStyle(theme.foregroundTertiary)   // _700 in light mode, _300 in dark
}
.padding()
.background(theme.backgroundPrimary)     // _50 in light mode, _1000 in dark
```

What this draws, with `Color.proOrange`:

| Color                 | light mode                             | dark mode                              |
| --------------------- | -------------------------------------- | -------------------------------------- |
| `backgroundPrimary`   | color(display-p3 0.9936 0.9528 0.9271) | #301404                                |
| `foregroundPrimary`   | #301404                                | color(display-p3 0.9936 0.9528 0.9271) |
| `foregroundSecondary` | #6e3612                                | color(display-p3 0.978 0.79 0.6716)    |
| `foregroundTertiary`  | #90491a                                | color(display-p3 0.9695 0.664 0.4686)  |

The faintest line, the price in light mode, measures 6.10:1. AA asks 4.5:1 for body text.

## What's guaranteed

### The same ratio in every hue

```swift
Color.proOrange._100.contrastRatio(to: Color.proOrange._700)   // 5.53, Lisbon
Color.proPink._100.contrastRatio(to: Color.proPink._700)       // 5.53, Kyoto
Color.proSky._100.contrastRatio(to: Color.proSky._700)         // 5.53, Reykjavík
```

Every hue has the same lightness at each stop, so a pair of stops measures the same in all 36 hues and in your brand's family, and [theming](https://colortokenskit.com/advanced/themes/index.md) keeps your contrast. Gray has its own ladder: 8.73:1 for this pair.

### Stops far enough apart

What this draws, with `#00B386`:

| Color               | light mode                             | dark mode                              |
| ------------------- | -------------------------------------- | -------------------------------------- |
| `backgroundPrimary` | #eaf8f2                                | color(display-p3 0.0176 0.1298 0.086)  |
| `_500/_550`         | color(display-p3 0.1935 0.624 0.4631)  | color(display-p3 0.1717 0.5709 0.4222) |
| `_650/_400`         | color(display-p3 0.1368 0.4655 0.3425) | color(display-p3 0.2666 0.7286 0.5502) |
| `_750/_300`         | color(display-p3 0.0977 0.3637 0.2645) | #4cd2a5                                |

When you pick stops yourself, count the stops between text and background. 9 apart passes AA for large text and control borders, 12 for body text, and 14 passes AAA, in all 37 families and between them. [The distance rule](https://colortokenskit.com/advanced/color-theory/index.md#the-distance-rule) covers other uses.

### On screens without Display P3

These ratios are exact on Display P3 screens, which every iPhone since the iPhone 7 has. An sRGB-only screen, like many external monitors, clips the colors beyond sRGB and moves a few pairs slightly. The text tokens still pass AA, at 4.77:1 or more, and stops 12 apart still reach 4.5:1. Stops 9 apart can dip to 2.93:1, and white on `_600` to 4.48:1 in mint, teal and turquoise.

## What you still check

### Text on the tertiary background

What this draws, with `Color.proOrange`:

| Color                | light mode                          | dark mode                              |
| -------------------- | ----------------------------------- | -------------------------------------- |
| `backgroundTertiary` | color(display-p3 0.978 0.79 0.6716) | #90491a                                |
| `foregroundPrimary`  | #301404                             | color(display-p3 0.9936 0.9528 0.9271) |
| `foregroundTertiary` | #90491a                             | color(display-p3 0.9695 0.664 0.4686)  |

On `backgroundTertiary`, tertiary text falls under 4.5:1 in both modes, and secondary text does in dark mode. The lowest, 3.51:1, is enough only for large text, so use `foregroundPrimary` for body text there.

The app-wide gray tokens on `Color` pass there, at 5.24:1 or more. Inverted secondary and tertiary text fall short on `invertedBackgroundTertiary` too.

### Borders of controls

What this draws, with `#00B386`:

| Color               | light mode                             | dark mode                              |
| ------------------- | -------------------------------------- | -------------------------------------- |
| `backgroundPrimary` | #eaf8f2                                | color(display-p3 0.0176 0.1298 0.086)  |
| `foregroundPrimary` | color(display-p3 0.0176 0.1298 0.086)  | #eaf8f2                                |
| `outlinePrimary`    | color(display-p3 0.1547 0.5182 0.3824) | color(display-p3 0.3144 0.7788 0.5953) |

A border that shows where a control is, like these tags' edges, needs 3:1 under WCAG's [non-text contrast rule](https://www.w3.org/TR/WCAG22/#non-text-contrast). `outlinePrimary` reaches it on every background token, in every hue and both modes, at 3.08:1 or more, as in [borders people need to see](https://colortokenskit.com/advanced/color-theory/index.md#borders-people-need-to-see). `outlineSecondary` and `outlineTertiary` are faint on purpose, for dividers and card edges, which WCAG sets no minimum for.

### APCA scores

The ratios on this page are WCAG 2, the standard audits check. [APCA](https://colortokenskit.com/reference/glossary/index.md#apca), the candidate for WCAG 3, estimates luminance its own way, so its scores move up to Lc 1.2 between hues. [`contrastRatio(to:method:)`](https://colortokenskit.com/api/contrast-ratio/index.md) measures both.

### Meaning shown by hue alone

- Sold out, proRed.\_600: #ad5a5a
- Booked, proGreen.\_600: #44824b

* Sold out, deuteranopia: #857c56
* Booked, deuteranopia: #7a7149

Two families at the same stop differ only in hue. The second row is the pair as someone with deuteranopia, a red-green color blindness, sees it at full severity, and in grayscale the two are identical. So give color a second cue, as WCAG's [use of color rule](https://www.w3.org/TR/WCAG22/#use-of-color) asks: a label, an icon, or a difference in lightness. [Using tokens in charts](https://colortokenskit.com/advanced/charts/index.md) shows how for data.

### Increase Contrast

The tokens follow light and dark mode, not the Increase Contrast setting. [High contrast modes](https://colortokenskit.com/advanced/high-contrast/index.md) moves text and borders two stops further from the background when it's on.

## Sources

- W3C, [WCAG 2.2](https://www.w3.org/TR/WCAG22/): success criteria 1.4.1 (use of color), 1.4.3 and 1.4.6 (contrast) and 1.4.11 (non-text contrast).
- APCA, [Bronze simple mode](https://readtech.org/ARC/tests/bronze-simple-mode/), for Lc levels.
- Gustavo Machado, Manuel Oliveira and Leandro Fernandes, [A Physiologically-based Model for Simulation of Color Vision Deficiency](https://doi.org/10.1109/TVCG.2009.113), IEEE Transactions on Visualization and Computer Graphics, 2009, for the deuteranopia simulation.
- The library's [ColorTokens.swift](https://github.com/metasidd/ColorTokensKit-Swift/blob/main/Tests/ColorTokensKitTests/Marketing/Setup/ColorTokens.swift), for the stops behind each token.

## See also

- [Managing dark mode](https://colortokenskit.com/getting-started/dark-mode/index.md): Get dark mode without extra code: tokens switch stops for you, and your own colors can too.
- [Replacing your app colors](https://colortokenskit.com/getting-started/replacing-colors/index.md): Move backgrounds, text, outlines, states, gradients and charts to tokens, one screen at a time.
- [How the ramps are built](https://colortokenskit.com/under-the-hood/how-ramps-are-built/index.md): The lightness and chroma behind every stop, so any hue you pick gives the same contrast.
- [What does equal lightness cost?](https://colortokenskit.com/under-the-hood/trade-offs/index.md): What equal contrast costs, from quieter reds to olive yellows, and what you can do about each.

---

From ColorTokensKit, by Penguin Design Ventures: https://colortokenskit.com/basics/how-accessible/ (updated September 26, 2026).
