Skip to content

Contrast & Accessibility

Every ratio on this page is computed live from the token metadata, per mode, with the same functions the library ships. If your theme overrides the palette, you can run the identical WCAG check on it.

Requirements

WCAG 2.2 grades text contrast by ratio and text size: large text is at least 24px, or 18.66px bold. Section 508 incorporates WCAG 2.0 AA, so an AA pass at a given size is also a 508 pass.

LevelNormal textLarge text
WCAG AA4.5:13:1
WCAG AAA7:14.5:1
Section 5084.5:13:1

Pairing checker

Pick any two colors (palette hues, intent roles in either mode, or resolved text and surface roles) and read the ratio and pass/fail grades live.

Normal text: a birdie putt from the circle's edge. (16px)

Large text: par saves win rounds. (24px)

Contrast ratio 5.17:1 · relative luminance 0.153 on 1.000

RequirementMinimumResult
WCAG AA — normal text4.5:1Pass
WCAG AAA — normal text7:1Fail
WCAG AA — large text3:1Pass
WCAG AAA — large text4.5:1Pass
Section 508 — normal text4.5:1Pass
Section 508 — large text3:1Pass

How to read the ratio and grades:

Relative luminance
Perceived brightness on a 0 (black) to 1 (white) scale. The contrast ratio is computed from these two values.
Pass Fail
In the table above, each row is graded on its own: Pass meets that requirement's minimum ratio, Fail does not. A pairing can pass AA and still fail the stricter AAA on the next row.
AAA AA AA Large
In the sections below, a badge names the highest grade a pairing reaches, one per text size (16px and 24px): AAA (at least 7:1 normal, 4.5:1 large), AA (4.5:1 normal, 3:1 large), or AA Large (clears 3:1, large text only). A ratio under 3:1 reaches no grade and shows a red Fail.

Text on surfaces

Every token the theme paints text with (the semantic text roles and all seven intents) on both surface roles, in both modes, at normal (16px) and large (24px) sizes. Each panel uses the values that mode actually resolves: the default palette on light surfaces, the dark theme's companions ([data-theme="dark"]) on dark ones.

Rendered on surface · light (#ffffff) with the light-mode token values.

A smooth backhand hyzer flares left and drops in the circle. Par saves win rounds. text 21.00 16px AAA 24px AAA
A smooth backhand hyzer flares left and drops in the circle. Par saves win rounds. text-muted 4.83 16px AA 24px AAA
A smooth backhand hyzer flares left and drops in the circle. Par saves win rounds. intent-neutral 4.83 16px AA 24px AAA
A smooth backhand hyzer flares left and drops in the circle. Par saves win rounds. intent-primary 5.17 16px AA 24px AAA
A smooth backhand hyzer flares left and drops in the circle. Par saves win rounds. intent-secondary 5.70 16px AA 24px AAA
A smooth backhand hyzer flares left and drops in the circle. Par saves win rounds. intent-danger 6.47 16px AA 24px AAA
A smooth backhand hyzer flares left and drops in the circle. Par saves win rounds. intent-warning 5.02 16px AA 24px AAA
A smooth backhand hyzer flares left and drops in the circle. Par saves win rounds. intent-success 5.02 16px AA 24px AAA
A smooth backhand hyzer flares left and drops in the circle. Par saves win rounds. intent-info 5.36 16px AA 24px AAA
Token (light / dark)surface · lightsurface-muted · lightsurface · darksurface-muted · dark
text #000000 · #ffffff21.00 AAA 19.57 AAA 21.00 AAA 14.59 AAA
text-muted #6b7280 · #9ca3af4.83 AA 4.50 AA 8.27 AAA 5.74 AA
intent-neutral #6b7280 · #9ca3af4.83 AA 4.50 AA 8.27 AAA 5.74 AA
intent-primary #2563eb · #60a5fa5.17 AA 4.82 AA 8.26 AAA 5.74 AA
intent-secondary #7c3aed · #a78bfa5.70 AA 5.31 AA 7.72 AAA 5.36 AA
intent-danger #b91c1c · #f871716.47 AA 6.03 AA 7.59 AAA 5.27 AA
intent-warning #b45309 · #fbbf245.02 AA 4.68 AA 12.58 AAA 8.74 AAA
intent-success #15803d · #4ade805.02 AA 4.67 AA 12.05 AAA 8.37 AAA
intent-info #0e7490 · #22d3ee5.36 AA 4.99 AA 11.62 AAA 8.07 AAA

Solid intent backgrounds

The solid Button and Badge case. The reference theme paints solid text with --hz-color-surface (white by default, black under the dark theme) because the dark companions are lighter than the surfaces they sit on.

A smooth backhand hyzer flares left and drops in the circle. Par saves win rounds. neutral light 4.83 16px AA 24px AAA
A smooth backhand hyzer flares left and drops in the circle. Par saves win rounds. neutral dark 8.27 16px AAA 24px AAA
A smooth backhand hyzer flares left and drops in the circle. Par saves win rounds. primary light 5.17 16px AA 24px AAA
A smooth backhand hyzer flares left and drops in the circle. Par saves win rounds. primary dark 8.26 16px AAA 24px AAA
A smooth backhand hyzer flares left and drops in the circle. Par saves win rounds. secondary light 5.70 16px AA 24px AAA
A smooth backhand hyzer flares left and drops in the circle. Par saves win rounds. secondary dark 7.72 16px AAA 24px AAA
A smooth backhand hyzer flares left and drops in the circle. Par saves win rounds. danger light 6.47 16px AA 24px AAA
A smooth backhand hyzer flares left and drops in the circle. Par saves win rounds. danger dark 7.59 16px AAA 24px AAA
A smooth backhand hyzer flares left and drops in the circle. Par saves win rounds. warning light 5.02 16px AA 24px AAA
A smooth backhand hyzer flares left and drops in the circle. Par saves win rounds. warning dark 12.58 16px AAA 24px AAA
A smooth backhand hyzer flares left and drops in the circle. Par saves win rounds. success light 5.02 16px AA 24px AAA
A smooth backhand hyzer flares left and drops in the circle. Par saves win rounds. success dark 12.05 16px AAA 24px AAA
A smooth backhand hyzer flares left and drops in the circle. Par saves win rounds. info light 5.36 16px AA 24px AAA
A smooth backhand hyzer flares left and drops in the circle. Par saves win rounds. info dark 11.62 16px AAA 24px AAA

Soft intent surfaces (Alert & Badge)

The reference theme derives these surfaces with color-mix(): backgrounds mix 10–14% of the intent color into the surface in light mode and 22–28% in dark (weak tints barely read as color on a dark surface). Text mixes 65–70% toward the text role in both modes. Tune the background strength with the --hz-alert-tint and --hz-badge-tint hooks. Everything below is that derivation over the mode's resolved values: proof the tints hold contrast, not only the raw hues.

neutral
Course update A smooth backhand hyzer flares left and drops in the circle.
chip 7.44 AAA title 7.16 AAA body 18.57 AAA
primary
Course update A smooth backhand hyzer flares left and drops in the circle.
chip 7.72 AAA title 7.48 AAA body 18.23 AAA
secondary
Course update A smooth backhand hyzer flares left and drops in the circle.
chip 8.12 AAA title 7.95 AAA body 18.08 AAA
danger
Course update A smooth backhand hyzer flares left and drops in the circle.
chip 8.71 AAA title 8.59 AAA body 17.70 AAA
warning
Course update A smooth backhand hyzer flares left and drops in the circle.
chip 7.59 AAA title 7.36 AAA body 18.36 AAA
success
Course update A smooth backhand hyzer flares left and drops in the circle.
chip 7.58 AAA title 7.29 AAA body 18.34 AAA
info
Course update A smooth backhand hyzer flares left and drops in the circle.
chip 7.95 AAA title 7.69 AAA body 18.29 AAA

Check your own palette

The math behind this page is part of the library: hexToRgb, rgbToHex, mixSrgb, relativeLuminance, contrastRatio, gradeContrast, bestLevel, and bestLevelLarge, exported from the package root and @hyzer-labs/ui/utils. Pure functions over hex strings (no DOM, SSR-safe), with the token metadata importable from @hyzer-labs/ui/tokens. If your theme overrides the palette, assert your pairings in a unit test the same way this library does:

import { gradeContrast, contrastRatio, mixSrgb } from '@hyzer-labs/ui';
import { palette } from '@hyzer-labs/ui/tokens';

// Your override for --hz-palette-primary
const brand = '#0f766e';

gradeContrast(brand, palette.white).aaNormal; // text on surface
gradeContrast(palette.white, brand).aaNormal; // solid button text

// On surface-muted: the same 6% color-mix the theme derives
contrastRatio(brand, mixSrgb(palette.gray, palette.white, 0.06));

For the full override workflow, see Theming → Tokens & Overrides: plain-CSS recipes and the hyzer CLI, whose generate step runs this same report over your config.

References: WCAG 2.2: 1.4.3 Contrast (Minimum) · WCAG 2.2: 1.4.6 Contrast (Enhanced) · WCAG 2.2: 1.4.11 Non-text Contrast · WAI-ARIA 1.2 · ARIA APG · Section 508