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.
--bn-* token. Re-themes for free.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.
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.
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).
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.
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:
| weight | what | why it hurts |
|---|---|---|
| 3 | missing-token / hardcoded colour, dangling ref | breaks theming and dark mode |
| 1 | off-scale spacing·radius·duration, magic z-index, shadow geometry | cosmetic drift, no theming risk |
| 1 | fixable drift | trivial, but still off-system |
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.
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).