UI consistency checker
Load your design tokens and CSS — the tool finds off-palette colours, off-scale sizes, unknown variables and low-contrast pairs. Compare the current screenshot with an approved baseline and triage every finding in one list with statuses.
Free, no sign-up
Everything runs in this browser. Text is kept in localStorage, the approved baseline in this browser's IndexedDB, the current screenshot only in this tab's memory. Nothing is sent anywhere.
Design tokens
Paste or upload tokens: W3C DTCG JSON ($value/$type, {group.token} aliases), Style Dictionary / flat JSON, or CSS custom properties (:root plus a dark theme in .dark / [data-theme=dark]).
The format is detected automatically. In JSON, the dark theme is a top-level "dark" group.
Used to convert rem to px (usually 16).
How the check works
Tokens
W3C DTCG JSON ($value, $type, groups, {group.token} aliases with a cycle guard), Style Dictionary JSON, or CSS custom properties. The dark theme comes from .dark, [data-theme=dark], @media (prefers-color-scheme: dark) blocks, or a "dark" group in JSON.
CSS audit
Every declaration is checked against the tokens: colours by CIEDE2000 perceptual distance; spacing, radii, font sizes and line heights against the token scale; plus unknown var(--x), !important density, z-index and fonts. Each finding has a rule ID, file:line, the declaration and a suggestion.
Contrast
Pairs are matched by name (text / foreground / on-* against background / surface) or added manually; WCAG 2.x contrast is calculated per theme: AA and AAA for normal and large text, 3:1 for non-text elements.
Screenshots
Approve a baseline (a file or a screen capture) and compare the current screenshot: a pixel diff with tolerance, anti-aliasing handling and ignore regions, a difference image and a list of changed regions with a zoomed view.
Triage and report
All findings in one list: open / to fix / accepted deviation / false positive, an owner and a note. The report is Markdown, PDF via print, and CSV; the document is JSON with re-import and versions.
Rules and thresholds
The table is generated from the same code as the check. Severity is a guide for the fix queue, not a rating of product quality.
UIC-C01
- Rule
- Token colour written as a literal
- Severity
- low
- Threshold
- ΔE00 ≤ 1 from a colour token: replace the literal with the variable
UIC-C02
- Rule
- Colour nearly matches a token
- Severity
- medium
- Threshold
- 1 < ΔE00 ≤ 3: the nearest token was probably intended
UIC-C03
- Rule
- Off-palette colour
- Severity
- high
- Threshold
- ΔE00 > 3 from every colour token
UIC-T01
- Rule
- Near-duplicate colour tokens
- Severity
- medium
- Threshold
- Two different values in one theme closer than ΔE00 1, not aliases of each other (equal values for different roles are fine)
UIC-S01
- Rule
- Spacing off the scale
- Severity
- medium
- Threshold
- margin/padding/gap differs from every spacing token by more than 0.5 px
UIC-S02
- Rule
- Radius off the scale
- Severity
- low
- Threshold
- border-radius matches no radius token (except % and ≥ 999 px)
UIC-S03
- Rule
- Font size off the scale
- Severity
- medium
- Threshold
- font-size in px/rem matches no font-size token
UIC-S04
- Rule
- Line height off the scale
- Severity
- low
- Threshold
- line-height matches no line-height token of the same unit
UIC-S05
- Rule
- Shadow not from tokens
- Severity
- low
- Threshold
- box-shadow/text-shadow matches no shadow token (after normalisation)
UIC-V01
- Rule
- Unknown variable
- Severity
- high
- Threshold
- var(--x) is defined neither in the tokens nor in the audited CSS
UIC-I01
- Rule
- Frequent !important
- Severity
- medium
- Threshold
- ≥ 3 and over 5% of the file's declarations
UIC-Z01
- Rule
- Magic z-index
- Severity
- low
- Threshold
- A number other than -1, 0, 1 and layer-token values
UIC-F01
- Rule
- Font family not from tokens
- Severity
- medium
- Threshold
- The first font-family does not match any font token
UIC-K01
- Rule
- Text contrast below AA
- Severity
- high
- Threshold
- Normal text: below 4.5:1 (WCAG 1.4.3)
UIC-K02
- Rule
- Large-text contrast below AA
- Severity
- high
- Threshold
- Large text (24 px+, or 18.66 px+ bold): below 3:1
UIC-K03
- Rule
- Non-text contrast below 3:1
- Severity
- medium
- Threshold
- Control boundaries, focus, icons: below 3:1 (WCAG 1.4.11)
UIC-D01
- Rule
- Visual difference from the baseline
- Severity
- medium
- Threshold
- A connected area of changed pixels (8 px grid); 2%+ of the frame — high severity
UIC-D02
- Rule
- Screenshot size changed
- Severity
- medium
- Threshold
- Width or height differs from the baseline: the common top-left area is compared
- Colour: ΔE00 ≤ 1 is imperceptible — the same token written as a literal; up to 3 is “nearly matches” (usually a typo); above that is “off the palette”. Alpha differences are handled separately.
- Literals inside var(--x, …) and calc(…), variable definitions (--x: …) and SCSS variables ($x: …) are not checked for literals: they are part of the token system.
- If there are no tokens of the needed kind (for example, no spacing scale), the rule is skipped and the report says so — the tool does not invent a scale for you.
- Contrast: AA is 4.5:1 for normal text and 3:1 for large text, AAA is 7:1 and 4.5:1, non-text is 3:1. Thresholds are compared without rounding: 4.48:1 fails AA.
- Defaults: channel tolerance 24/255, anti-aliasing and 1 px shifts are not counted as changes, region grid 8 px.
How the token kind is determined
If a token has a $type (DTCG), it is used; otherwise the value and the name decide. Order matters: the first match wins.
Colour
- Name patterns (when $type is absent)
- $type: color, or the value parses as a colour
Shadow
- Name patterns (when $type is absent)
- shadow, elevation
Radius
- Name patterns (when $type is absent)
- radius, rounded, corner
Line height
- Name patterns (when $type is absent)
- line-height, leading
Font size
- Name patterns (when $type is absent)
- font-size, text-size, fs, type-scale
Font weight
- Name patterns (when $type is absent)
- font-weight, weight
Font family
- Name patterns (when $type is absent)
- font-family, font, family, typeface
Layer (z-index)
- Name patterns (when $type is absent)
- z-index, z, layer
Spacing
- Name patterns (when $type is absent)
- spac, gap, gutter, inset, pad, margin, space, size, s, sp
Limitations
- The source CSS is checked, not what the browser actually applied: the cascade, specificity and unused rules are not considered. Final computed styles need a browser and tests.
- Contrast pairs by name are a heuristic: the tool does not know which text sits on which background in the design. Mark a wrong pair as a false positive and add the right one manually.
- A semi-transparent background is composited on white (default theme) or black (dark theme) — if something else is underneath, add a pair with the final colour.
- The visual comparison is pixel-based: screenshots of one screen must be taken in the same browser, zoom and window size. Fonts and anti-aliasing differ between operating systems — tolerance and ignore regions exist for that.
- oklch/oklab are converted to sRGB with gamut clipping; lab(), lch(), color() and color-mix() are not parsed.
Privacy
- Everything runs in your browser: checking never sends tokens, CSS or screenshots to a server or puts them in the page address.
- Text, triage and versions are stored in this browser's localStorage. The approved baseline is stored in this browser's IndexedDB; the current screenshot lives only in the tab's memory. “Clear all” deletes all of it.
- A screen capture happens only when you press the button: one frame is taken and the capture stops immediately.
- Analytics receives only the fact of a comparison or an export and the file format — no content.
- The result reaches us only if you send a request yourself and keep the “Attach the result” box ticked — the form shows exactly what will be sent: the token count, findings by rule, contrast failures and the share of changed screenshot pixels. Screenshots never go with the request, and neither does the CSS or the token file as a whole.
Related tools
All tools · 40
Release readinessAn evidence-backed check matrix: CI, migrations, backups, a rollback plan, monitoring, risk exceptions and sign-off → a GO / NO-GO decision.
Screenshot → Bug reportA screenshot or video → private data hidden, the problem marked up, reproduction steps, a human check and export to GitHub, GitLab or Jira.
User flow testerA user-flow builder → ready Playwright tests guarded against running on production, coverage of key routes and a pass/fail results view.
API Mock StudioImport OpenAPI or define endpoints → test data, different HTTP responses, delays and errors, a request log, contract checks and a ready mock server.
MVP validation toolkitHypotheses with thresholds, a landing page and lead form, UTM links, a funnel, interviews and an experiment report → continue, pivot or stop.
Proposal builderProposal templates for IT projects: scope, phases, estimate, timeline, assumptions and exclusions, versions with number control, approval and PDF.Need a full UI audit?
The InterLAB audit is a paid review of layout, accessibility, performance and code with prioritised fixes. The first short conversation about the format is free.
- The first short conversation is free — we choose the format
- NDA — yours or ours
- Pricing after a brief and an agreed scope