Color checkpoints
Whether the color system is complete, readable, well named and well layered: roles, states, contrast, naming and alias chains.
Each checkpoint reports pass, warning, fail or skipped. A finding for a checkpoint links its section on this page.
Completeness
Semantic color roles defined
color-completeness-semantic-roles
Whether color tokens cover five roles: surface, text, border, accent and muted. A token's role comes from its role field, or else from its name; for example bg counts as surface, primary as accent and secondary as muted.
| Result | When |
|---|---|
| Pass | All five roles have tokens. |
| Warning | 1 or 2 roles are missing. |
| Fail | 3 or more roles are missing, or no color tokens are defined. |
| Skipped | Not reported by this checkpoint. |
How to improve. Add tokens for the missing roles.
Dark mode variants
color-completeness-dark-mode
Whether the color system supports dark mode, from the hasDarkMode flag and each token's hasDarkVariant, or else from token names containing dark.
| Result | When |
|---|---|
| Pass | hasDarkMode is true and at least 80% of tokens have a dark variant. |
| Warning | hasDarkMode is true with fewer than 80% covered; dark-named tokens exist without the flag; hasDarkMode is false; or support cannot be determined. |
| Fail | Not reported by this checkpoint. |
| Skipped | No color tokens were provided. |
How to improve. Set hasDarkMode, and mark each token that has a dark variant with hasDarkVariant.
Interactive state colors
color-completeness-interactive-states
Whether hover, focus, active and disabled colors are defined, from the interactiveStates config or, without it, from token names.
| Result | When |
|---|---|
| Pass | All four states are defined. |
| Warning | Some are missing: up to two with the config, or any number above zero when read from token names. |
| Fail | 3 or more are missing from the config, or no state appears in any token name. |
| Skipped | Not reported by this checkpoint. |
How to improve. Define a color for every interactive state.
Status colors defined
color-completeness-status-colors
Whether success, error, warning and info colors exist, from the statusColors config or, without it, from token names. Names containing danger or destructive count as error.
| Result | When |
|---|---|
| Pass | All four are defined. |
| Warning | Some are missing: up to two with the config, or at least one found by name. |
| Fail | 3 or more are missing from the config, or none is found by name. |
| Skipped | Not reported by this checkpoint. |
How to improve. Add the missing status colors.
Surface and text pairs
color-completeness-surface-text-pairs
Whether both surface and text tokens exist, and whether the pairs config, which contrast checking uses, declares at least one pair that puts a detected text token on a detected surface token. Pairs between other tokens do not count.
| Result | When |
|---|---|
| Pass | Both kinds exist and at least one declared pair puts a text token on a surface token. |
| Warning | Both kinds exist but no declared pair puts a text token on a surface token. |
| Fail | Surface tokens, text tokens or both are missing. |
| Skipped | Not reported by this checkpoint. |
How to improve. Declare which text tokens go on which surface tokens in the pairs config.
Relationships
Contrast meets WCAG AA
color-relationships-contrast-aa
The contrast ratio of each foreground and background pair: the declared pairs or, without them, combinations of up to five surface and five text tokens. Normal text needs 4.5:1 (7:1 when the check runs at level AAA) and large text 3:1.
| Result | When |
|---|---|
| Pass | Every checkable pair meets its minimum. |
| Warning | Some pairs fall short, but no more than half. |
| Fail | More than half of the pairs fall short. |
| Skipped | There are no pairs to check, or no pair has values that can be read as hex, rgb or hsl. |
How to improve. Darken the foreground or lighten the background of each failing pair.
Logical color hierarchy
color-relationships-semantic-hierarchy
Whether primary (or accent), secondary and muted colors step down in visual weight, judged by their contrast against white.
| Result | When |
|---|---|
| Pass | Primary outweighs secondary and secondary outweighs muted, for the values that can be read. |
| Warning | The hierarchy is inverted; there is no primary or accent token; or there is a primary but no secondary or muted token. |
| Fail | Not reported by this checkpoint. |
| Skipped | Not reported by this checkpoint. |
How to improve. Make primary the strongest color, then secondary, then muted.
Status colors are distinct
color-relationships-status-distinction
Whether each pair of status colors (success, error, warning, info) is at least 80 apart, measured as straight-line distance between their RGB values.
| Result | When |
|---|---|
| Pass | Every pair is far enough apart. |
| Warning | Some pairs are too close. |
| Fail | Not reported by this checkpoint. |
| Skipped | Fewer than 2 status colors can be read. |
How to improve. Move similar status colors further apart, and do not rely on red and green alone.
Dark mode contrast
color-relationships-dark-mode-contrast
The contrast of declared pairs whose foreground or background name contains dark, against a minimum of 4.5:1.
| Result | When |
|---|---|
| Pass | Every dark pair meets 4.5:1. |
| Warning | Some fall short, or dark mode is declared but no dark pairs are declared. |
| Fail | Not reported by this checkpoint. |
| Skipped | hasDarkMode is not true, or no dark pair can be read. |
How to improve. Declare dark mode pairs and adjust any below 4.5:1.
Interactive states look different
color-relationships-interactive-progression
Whether each state looks different from the next, in the order default, hover, focus, active, disabled: adjacent states must be at least 15 apart in RGB distance. Values come from the interactiveStates config or from token names.
| Result | When |
|---|---|
| Pass | Every adjacent pair is distinct. |
| Warning | Some adjacent states look the same. |
| Fail | Not reported by this checkpoint. |
| Skipped | Fewer than 2 state colors can be read. |
How to improve. Make hover, focus and active visibly different from each other.
Naming
Consistent naming convention
color-naming-convention
Which naming convention each token name follows, compared with the declared namingConvention or, without one, with the most common convention.
| Result | When |
|---|---|
| Pass | With a declared convention, at least 90% follow it. Without one, every name follows the same convention. |
| Warning | With a declared convention, fewer than 90% follow it. Without one, at least 80% follow the most common. |
| Fail | Without a declared convention, fewer than 80% follow the most common one. |
| Skipped | No tokens were provided. |
How to improve. Pick one convention and rename the outliers.
Semantic names over primitive names
color-naming-semantic-over-primitive
The share of tokens with semantic names rather than primitive ones, such as blue-500, a hex value, a bare number or light-red. Tokens with the primitive role count as primitive.
| Result | When |
|---|---|
| Pass | At least 90% are semantic. |
| Warning | Between 60% and 90%. |
| Fail | Below 60%. |
| Skipped | No tokens were provided. |
How to improve. Add a semantic layer, such as accent-primary or surface-muted, that references the primitives, and have components use it.
No ambiguous or conflicting names
color-naming-no-ambiguity
Generic names (color1, c2, custom-3, or names starting with temp, new-, old- or test) and pairs of names that become identical once case, dashes and underscores are ignored, such as text-primary and textPrimary.
| Result | When |
|---|---|
| Pass | No such names. |
| Warning | Some, up to 20% of tokens. |
| Fail | More than 20% of tokens. |
| Skipped | No tokens were provided. |
How to improve. Give generic tokens descriptive names, and resolve names that collide.
Valid alias chains
color-naming-alias-chain
Whether every token's aliasOf points to a token that exists.
| Result | When |
|---|---|
| Pass | Every alias resolves, or no token uses aliases and none looks like a reference. |
| Warning | Some aliases are broken, up to half; or values look like references but aliasOf is not set. |
| Fail | More than half of the aliases are broken. |
| Skipped | Not reported by this checkpoint. |
How to improve. Point each broken alias at an existing token, and use aliasOf for every reference.
Role-based prefixes
color-naming-role-prefix
The share of non-primitive tokens whose name starts with a role prefix such as surface, text, border, accent, status, hover or button.
| Result | When |
|---|---|
| Pass | At least 80%, or every token is a primitive. |
| Warning | Between 50% and 80%. |
| Fail | Below 50%. |
| Skipped | No tokens were provided. |
How to improve. Prefix tokens with their role: surface-, text-, border-, accent-, status-.
Usage
No orphaned primitives
color-usage-no-orphaned
Primitive tokens (the primitive role, or no role and no alias) that no other token aliases. It only applies once some tokens use aliasOf.
| Result | When |
|---|---|
| Pass | Every primitive is referenced, or no token uses aliases (scored 80 in that case). |
| Warning | Some primitives are not referenced, up to 30% of them. |
| Fail | More than 30% of primitives are not referenced. |
| Skipped | No tokens were provided. |
How to improve. Remove unused primitives, or reference them from semantic tokens.
No duplicate values
color-usage-no-duplicates
Groups of tokens with direct (non-alias) values that are the same color once normalized.
| Result | When |
|---|---|
| Pass | No duplicates, or fewer than 2 direct-value tokens. |
| Warning | Tokens that repeat another token's value make up 20% or less of direct-value tokens. |
| Fail | They make up more than 20%. |
| Skipped | No tokens were provided. |
How to improve. Merge duplicates, or have both tokens reference one shared primitive.
No circular references
color-usage-no-circular-refs
Tokens whose alias chain loops back on itself.
| Result | When |
|---|---|
| Pass | No cycles, or no aliases. |
| Warning | Not reported by this checkpoint. |
| Fail | Any cycle. |
| Skipped | Not reported by this checkpoint. |
How to improve. Break each cycle by pointing one token at a direct value.
Short alias chains
color-usage-alias-depth
Alias chains longer than 3 levels, for example primitive, semantic, component.
| Result | When |
|---|---|
| Pass | No chain is longer than 3 levels, or no aliases exist. |
| Warning | Some chains are longer. |
| Fail | Not reported by this checkpoint. |
| Skipped | Not reported by this checkpoint. |
How to improve. Flatten chains to 3 levels or fewer.
Semantic to primitive ratio
color-usage-token-ratio
The share of semantic tokens (an alias, or a role other than primitive or other) among tokens classified as semantic or primitive (the primitive role).
| Result | When |
|---|---|
| Pass | At least 50% are semantic. |
| Warning | Below 50%, or no token is classified either way. |
| Fail | Not reported by this checkpoint. |
| Skipped | No tokens were provided. |
How to improve. Add semantic tokens that reference primitives, and tag tokens with roles.