Color Accessibility and Contrast
Espalier automatically enforces contrast on all semantic text tokens using the Advanced Perceptual Contrast Algorithm (APCA). When you configure a theme, the system generates text and heading colors that meet APCA Lc targets against their intended background pairs — you do not need to check or tune contrast manually for the standard token set.
APCA Lc targets used by Espalier
| Token | Lc target | Background pair |
|---|---|---|
--esp-color-text |
≥ Lc 75 | --esp-color-background |
--esp-color-type-overline |
≥ Lc 90 | --esp-color-background |
--esp-color-type-label |
≥ Lc 75 | --esp-color-background |
--esp-color-type-lead |
≥ Lc 75 | --esp-color-background |
--esp-color-type-caption |
≥ Lc 90 | --esp-color-background |
--esp-color-headings |
≥ Lc 60 | --esp-color-background |
--esp-color-headings-hover |
≥ Lc 60 | --esp-color-background |
--esp-color-link |
≥ Lc 75 | --esp-color-background |
--esp-color-link-hover |
≥ Lc 75 | --esp-color-link-hover-bg |
--esp-color-danger-text |
≥ Lc 75 | --esp-color-background |
--esp-color-action-text |
≥ Lc 75 | --esp-color-action-background |
--esp-color-input-caret |
≥ Lc 60 | --esp-color-layer-2 |
--esp-color-input-selection |
≥ Lc 60 | --esp-color-input-selection-bg |
When Espalier adjusts your colors
If a theme's seed color produces text tokens that do not meet the Lc targets, the system shifts the lightness of the affected tokens until they do. This means a theme built from a very light or very dark seed may produce text colors that differ noticeably from what a simple lightness derivation would give. This is intentional: accessibility takes precedence over exact palette fidelity.
To see exactly which tokens were adjusted, by how much, and against which background, take a theme fit report — it reports every enforcement action with its Lc target and the score before and after.
Custom colors outside the token system
APCA enforcement applies only to the tokens Espalier generates. If you
introduce custom colors in your application CSS, contrast checking is your
responsibility. A lightness delta of at least 40–50 points in OKLCH L between
foreground and background is a reasonable starting heuristic, but direct APCA
tooling gives more accurate results for specific font sizes and weights.