At a glance: a closed token layer with an automated audit reduced hardcoded CSS values from 1,044 to 0 across 59 components. The approach was validated with three independent test runs using agents with no prior knowledge of the system, each of which located the documentation, used existing tokens correctly, and ran the audit without being instructed to.

The Problem

A design system's conventions are only effective if the people, and systems, editing the codebase are aware of them. A plain-CSS design system has no compiler to enforce a rule like "use the token, not a raw hex value." That rule is typically maintained through code review and institutional knowledge.

An AI coding assistant has neither. It does not carry context from one session to the next, and without explicit guidance it tends to produce two specific failure modes when editing components/:

  • Fabricated values. When asked to add a variant, it will generate a plausible hex color or padding value rather than checking whether an existing token already covers the case.
  • No persistent context. Each session starts without knowledge of a component's established anatomy, which tokens it already uses, or which naming convention the file follows, unless that information is made explicit in the repository.

Over successive edits, this causes a design system to drift from its own rules: hardcoded values reappear, naming conventions diverge between files, and there is no single reference a new session, human or AI, can consult to get up to speed.

The Solution

Aural UI implements the pattern described in hvpandya.com/llm-design-systems: structured specifications, a closed token layer, and an automated audit, so that consistency does not depend on any individual session recalling the rules correctly. The implementation consists of four components.

CLAUDE.md: The Entry Point

CLAUDE.md at the repo root lays out what to do before touching components/, themes/, or tokens/:

  • Read the spec first. specs/components/<name>.md documents a component's anatomy, variants, states, and which tokens it should use; specs/foundations/<category>.md does the same for a token category.
  • Never hardcode a visual value in components/*.css — no raw hex/rgb colors, no raw px for spacing/sizing/radius, no raw z-index numbers. Use a token from tokens/core/ or tokens/semantic/, preferring the semantic token when one exists.
  • If no token covers the value, add one to the matching file in tokens/core/ (and a semantic alias if it's a color or has more than one meaning) rather than hardcoding it.
  • If a value is genuinely one-off and not worth a token, mark it with /* aural-ignore: <reason> */ — an escape hatch, not a default.
  • Don't invent a third naming convention. Most components use flat kebab-case classes; a few use BEM. Match whichever convention the file already uses.
  • Run the token audit before committing: npm run audit:tokens — zero errors required for any file touched.
  • After adding or changing a token, regenerate the reference doc with npm run generate:token-docs instead of hand-editing it, so it can't drift from source.
Read it yourself: the full file is at CLAUDE.md on GitHub.

specs/: Structured Documentation

Every real component and token category has a spec, written in a consistent, parseable shape rather than freeform prose:

  • specs/components/*.md — one 8-section spec (Metadata, Overview, Anatomy, Tokens used, Props/API, States, Code example, Cross-references) per component, 54 files covering all real components. The 5 theme-reskin CSS files (kinetic/neon/prismatic demo-site decorations) are documented as "Theme variants" inside button.md and card.md rather than getting their own specs, since they're docs-site decoration, not separate components.
  • specs/foundations/*.md — one doc per token category: color, spacing, size, typography, radius, elevation, motion, z-index, breakpoints, accessibility.
  • specs/patterns/ — composition patterns that span multiple components.
  • specs/tokens/token-reference.md — a generated master table of every token's name, value, and source file, rebuilt by npm run generate:token-docs so it can't drift from the actual token CSS. See the live version of this on the Design Tokens page.

The Token Audit

scripts/token-audit.js is a postcss-based scanner, run via npm run audit:tokens, that parses every components/*.css file and flags hardcoded colors, spacing, radius, z-index, font-size, font-weight, and duration values. Each finding includes the specific token that should replace it.

It runs on staged files via the pre-commit hook (lint-staged) and is a blocking step in CI: a pull request that introduces a new hardcoded value fails the build rather than producing a warning.

How to Use It

As a human contributor

  1. Read CLAUDE.md once. It's short, and it covers the full set of rules.
  2. Before editing a component, read its spec at specs/components/<name>.md for its anatomy, variants, and which tokens it already uses.
  3. Reach for an existing token from tokens/core/ or tokens/semantic/ before writing a new value; prefer the semantic token when one exists.
  4. Run npm run audit:tokens before committing — it also runs automatically on staged files via the pre-commit hook.
  5. If you added or changed a token, run npm run generate:token-docs to regenerate specs/tokens/token-reference.md rather than hand-editing it.

As an AI agent

This system is designed to be discovered automatically, without being told where to look. Point Claude Code, Cursor, or a similar tool at the repository, and CLAUDE.md is the entry point: an agent editing components/, themes/, or tokens/ is expected to find it, follow it to the relevant spec in specs/, and run npm run audit:tokens before considering a change done — the same workflow a human contributor follows above, just unprompted.

Validation

This system was applied to the entire existing component library, and the results were independently verified rather than assumed.

Hardcoded values: 1,044 → 0

1,044 hardcoded-value errors
before migration
→
0 errors across all 59
components/*.css files

All 59 components/*.css files were migrated to the closed token layer. Each substitution was verified to be value-preserving: it resolves to the identical literal it replaced, so no component's rendered appearance changed.

Three independent validation runs

To test whether the system is discoverable in practice, rather than simply well-documented, a fresh AI agent with no prior knowledge of the system was given a single-line task, "add an xl size variant to X", and run three times against Badge, Chips, and Tooltip. Each result was independently verified rather than self-reported. In each run, the agent:

  • located CLAUDE.md and the relevant component spec without being directed to either,
  • used only existing, real tokens, with no fabricated values,
  • and ran the token audit itself before considering the change complete.

Real bugs surfaced along the way

Migrating every component to real tokens did more than reorganize existing values: it surfaced pre-existing bugs that hardcoded values had been masking.

  • Dangling var() references to tokens that never existed, including a typo'd --color-primary-alpha-20 in place of the real --primary-alpha-20, which was silently breaking hover states and a search-highlight.
  • A stray unbalanced parenthesis in utilities/filters.css.
  • Several more dangling var() references, found in a later pass: --color-border (used by seven components, undefined outside the Kinetic theme), --primary-alpha-50, --color-primary-light, and the -border half of Alert Banner's info/success/warning tints. Each was fixed by adding the missing token rather than guessing at a replacement value.
  • A cascade bug between .toggle and .switch. A backwards-compatibility block in switch.css was silently overriding .toggle's own color tokens because of import order. Fixed by reordering the imports and confirming the rendered track color before and after; safe to do because .toggle has no real-world consumers to regress.
  • A broken public JS API. Aural.initFileUpload() queried class names that didn't exist in File Upload's actual markup, making it a complete no-op. Fixed to match the real classes and verified by simulating a file drop end-to-end.

Learn More

  • CLAUDE.md — the full rules file
  • specs/ on GitHub — browse every component and foundation spec
  • Design Tokens — the live, generated token reference
  • Contributing Guide — how this fits into the day-to-day contribution workflow