Skip to content

Consolidate autobot-frontend's three base design-token sources #14785

Open

Description

@mrveiss

Part of #14774. Pairs with #14775 — that issue converges the vocabulary across packages; this one converges it within autobot-frontend.

Problem

autobot-frontend defines its base design tokens in three loaded files plus one unloaded copy. --bg-primary, --text-primary and --border-default are each declared in 8 files.

Loaded base sources:

File --var: declarations Loaded via
src/assets/css/design-tokens.css 678 src/assets/css/index.css → src/main.ts
src/assets/styles/theme.css 192 src/main.ts directly
src/assets/tailwind.css @theme block ~95 aliases src/main.ts

Per-theme overrides (legitimate, keep): css/themes/light.css, dark.css, accents.css, ember.css, _template.css, plus src/assets/aui-theme.css (49 vars).

An unloaded duplicate: src/assets/tokens.css declares 106 tokens but is imported by nothing — css/index.css imports ./design-tokens.css, not this file. Its own header says:

Master Design Tokens: src/assets/css/design-tokens.css
This file: src/assets/tokens.css (reference)

So it is a hand-maintained mirror that never reaches the browser, while reading as authoritative to anyone who opens it. Divergence between it and the master is silent and undetectable.

Why this blocks the umbrella

#14775 converges the token vocabulary across libs/autobot-ui, autobot-frontend and autobot-slm-frontend. That convergence cannot be verified or held while one package has three live definition sites and a fourth that looks live. Any guard test written for #14775 would have to pick one source and would silently miss drift in the others.

Approach

  1. Establish the precedence order that exists today — which file wins for a token declared in several. Load order is tailwind.css → styles/theme.css → css/index.css; confirm empirically rather than by reading, since later declarations win.
  2. Pick one base source. css/design-tokens.css is the self-declared master and has the most tokens.
  3. Reconcile styles/theme.css — its 192 tokens either move into the master or are demonstrated to be a distinct layer (it is also the file useThemeVariant.ts reads). Document which, do not merge blindly.
  4. Resolve src/assets/tokens.css. Diff it against the master first. Any token it defines that the master lacks is a real token that must be promoted — this is unfinished work to wire in, not dead weight to drop. Only once it is a proven subset does it become a redirect or get retired.
  5. Add a guard test asserting exactly one base declaration site per token name, with per-theme override files exempt.

Risks / constraints

  • Token consolidation is a visual-regression risk across 451 components. npm run test:visual baselines must be reviewed, not blanket-updated.
  • useThemeVariant.ts and usePreferences.ts read token files directly — check both before moving anything.
  • Do not delete tokens.css before step 4 proves it is a subset.

Acceptance criteria

  • Written precedence order for the loaded token sources, verified empirically
  • One base declaration site per token name; per-theme files hold overrides only
  • src/assets/tokens.css diffed against the master; any unique tokens promoted, with the diff recorded in the PR
  • Guard test fails on a second base declaration of any token name
  • Visual snapshots reviewed; no unintended diffs

Activity

  1. modified the milestones: v0.9.0, v0.10.0 on Sep 12, 2026
  2. mrveiss commented on Sep 26, 2026

    @mrveiss
    OwnerAuthor

    Re-measured on main at 12563bc052 before starting. The three loaded sources hold up. The fourth — the "unloaded duplicate" — is not what the body describes, and the difference changes the work.

    src/assets/tokens.css declares nothing

    The body says it "declares 106 tokens" and calls it a hand-maintained mirror. Measured:

    Lines in the file 310
    -- character sequences 143
    Custom-property declarations outside comments 0
    Non-comment, non-blank lines 0

    The whole file is one commentary block. Every --token in it is prose inside /* ... */, listing names and pointing at the real definitions:

     * NOTE: The master definition of all tokens is in design-tokens.css
     * This file is a canonical reference point and may be used for token organization.
    

    The "106 tokens" figure is a count of names mentioned in comments, not of declarations. A regex for --name: matches prose in a comment exactly as it matches a declaration, which is how the same file reads as 106 declarations and as zero.

    Why this matters rather than being a footnote

    It is not a duplicate token source. It cannot shadow, drift into, or override anything, because nothing in it reaches a parser even if it were imported. Merging it into design-tokens.css, or diffing its values against the live set, would be work against a file with no values.

    It is a stale document asserting canonicality. Its header calls it the "Design Tokens Canonical Reference" and says "Components should import design-tokens.css which includes this file" — and css/index.css:17 imports ./design-tokens.css, which does not include it. So a file that names itself canonical is unreferenced, and the sentence describing how it is wired in is false.

    That is the same defect this issue is about, one level up: the canonical source is asserted in a comment rather than declared anywhere a tool can read. It belongs to #17571's declaration work, not to a token-merge.

    The real consolidation is unchanged and is still three files — css/design-tokens.css (678), styles/theme.css (192), tailwind.css @theme (~95 aliases). The --bg-primary / --text-primary / --border-default-in-8-files observation stands; I have not re-derived it.

    Suggested change to the checklist

    • The fourth source is documentation, so the action is delete-or-rewrite, not merge. Nothing is lost: there are no values in it to preserve, which is checkable by the count above.
    • If it is kept, its header has to stop claiming both canonicality and an include that does not exist — a document that lies about its own wiring is worse than no document.
    • Do not schedule a value-diff against it. There is nothing to diff.

    Method note

    I nearly reported the opposite. My first parse returned 0 tokens and I treated that as a failed parse rather than a result, because a 0 from a regex is usually a broken regex — then checked the file and found the 0 was real. Worth stating because the same check run on the same file gives 106 or 0 depending on whether comments are stripped, and only one of those answers the question the issue is asking.

  3. 6 remaining items

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions