Compliance X-rayBristlenose design system
Where each element sits — inside vs outside the token system

The Quotes lens, x-rayed.

Every component that builds a quote card, in all four theme combinations. Each is rendered live and ranked by how much of its styling flows through --bn-* tokens. Flip X-ray to light up everything that hardcodes a value the system should own — the exact line, the defect, and the fix are one expand away.

Lens compliance — themeable declarations
—Coveragehow much flows through tokens
—Healthseverity-weighted — how bad the gaps are
Inside the systemValue comes from a --bn-* token. Re-themes for free.
Fixable driftA literal that already has a matching token. A one-line fix, no decision needed.
Outside the systemNo token exists yet — blocked on a token/scale decision. This is where magenta points.
Components in lens8
≥ 80% coverage—/8
Decls · in / fix / out—
Cleanest → weakest—
A few repeated values drive most of the magenta, not per-component sloppiness. The most repeated outside-system values are border-radius: 2px ×12 in 10 files; gap: 0.5rem ×10 in 8 files; z-index: 200 ×8 in 8 files; letter-spacing: 0.04em ×8 in 4 files; margin-bottom: 0.25rem ×7 in 6 files. Where the same literal recurs, the fix is one token, not many edits. Weakest files by coverage: atoms/autocode-toast.css, atoms/activity-chip.css, organisms/minimap.css.
› How the score works — and the prior art it borrows from

Two numbers, side by side rather than blended — because a single figure hides the failure mode the field warns about: a component can be high-coverage but risky, or low-coverage but harmless.

The unit — a “themeable declaration”

Only declarations whose property should answer to the design system count toward the denominator: colour / background / border-colour, font family·size·weight·line-height, spacing (margin·padding·gap), radius, box-shadow, z-index, transition/duration. Structural geometry (display, position, flex, grid, layout width/height) is excluded. A small ignore-set is never a violation: 0, transparent, currentColor, inherit, 1px hairlines. Each themeable declaration is one of inside (a --bn-* token) · fixable (a literal that already equals an existing token) · outside (a literal with no token — missing family, off-scale, magic z-index, dangling ref).

Coverage — the metric you asked for

Coverage = (inside + 0.5 × fixable) ÷ themeable declarations × 100 100% = every themeable value is a token · 0% = every value is a raw literal

The industry’s de-facto signal: stylelint-declaration-strict-value flags each declaration where a token-worthy property carries a raw literal, so Coverage is just 1 − (violations ÷ targeted declarations), with half-credit for fixable drift — non-compliant today, but a one-line change with no decision to make.

Health — the borrowed refinement

Coverage treats a hardcoded brand colour that breaks dark mode the same as an off-scale margin. Health doesn’t. Following SonarQube’s per-rule-weight → normalise → band model, each violation carries a severity:

weightwhatwhy it hurts
3missing-token / hardcoded colour, dangling refbreaks theming and dark mode
1off-scale spacing·radius·duration, magic z-index, shadow geometrycosmetic drift, no theming risk
1fixable drifttrivial, but still off-system
Health = (1 − Σ(weight × violations) ÷ (3 × themeable declarations)) × 100

So blockquote and timecode — clean except for off-scale spacing — score moderate Coverage but high Health, while badge (missing danger/success tokens, hardcoded tints) sinks on both. That gap is the whole point: it tells you where the effort should go.

Roll-up & honest limits

Per-declaration → per-component → per-lens, weighted equally. Since 5 Nov 2026 the tallies are generated: scripts/build-compliance-catalogue.py runs the same classifier as scripts/audit-css.py over every component file (64 files, 81% coverage / 91% health), attaches each finding’s file:line and selector, and keeps the hand-written defect and fix wording wherever the same value is still there. Specimens are hand-built markup (27 of 64 files have one; the rest are scored from source). The on screen panel comes from experiments/token-xray/live-scan.mjs on the running app. The browser resolves var() away, so that scan compares each computed value with the token values: a literal that happens to equal a token passes it, and the source scan is the arbiter. Components are still weighted equally, whereas the adoption literature weights by render frequency.

Prior art borrowed — stylelint-declaration-strict-value (the raw coverage signal) · SonarQube (severity-weight → letter band) · Nathan Curtis / EightShapes, Omlet and Mews (coverage ratio + the two-axis, don’t-blend rule) · Salesforce SLDS Linter (hardcoded-value rule shape).