Semantic tokens editor

Route: Library → Properties → Tokens → Semantic

Aliases referencing primitives. Each binds to a primitive in light + (optionally) dark mode.

Semantic tokens are the middle tier. They name a rolebg-accent, fg-default, border-focus — and point at a primitive in light, with an optional dark override. See three-tier tokens for the model.

Layout

The page renders tokens in four categories, ordered:

  1. Background — ID prefix bg-
  2. Foreground — ID prefix fg-
  3. Border — ID prefix border-
  4. Other — no recognized prefix

Each row has six columns:

Swatch ID Name Light → primitive Dark → primitive ×
Resolved color Stable identifier Display name Light binding dropdown Optional dark override Delete

The swatch reflects the resolved value following the reference chain.

Editing

  • Light binding — the dropdown lists every primitive. Pick one; the swatch updates instantly.
  • Dark binding — the rightmost dropdown is the dark-mode override. Leave it blank to fall through to the light chain (most semantics don't need a dark override).
  • ID and Name are click-to-edit inline like primitives.

Adding

Click + Add in any category header. A new semantic appears with tier: 'semantic' and references pointing at the first available primitive. Rename and re-bind.

Deleting

Click × on any row. component bindings that referenced this semantic now resolve through what's left in the chain (often nothing) — they show as broken in the component-mapping editor until you re-bind them.

Dark-mode resolution

When you toggle dark mode in the top nav:

  1. Tostada resolves through darkReferences first.
  2. If darkReferences is empty, it falls back to references — meaning dark mode uses the same primitive as light.
  3. If the primitive itself has a darkValue, that wins.

So you only need a dark override on semantics whose intent actually changes between modes (typically surfaces — bg-base, fg-default, border-default). The brand accent usually stays the same.

Common patterns

  • Two semantics pointing at one primitive. bg-accent and border-focus might both resolve to color-blue-500 today and diverge tomorrow. That's the point of the semantic layer.
  • Override only what differs. If bg-base is white in light and near-black in dark, set its darkReferences and leave the rest empty.
  • Don't fork dark for the whole palette. See light and dark.

Broken references

If a referenced primitive is deleted, the row shows an empty swatch. Fix it by picking a new primitive from the dropdown — no error state, just a missing color until you re-bind.