SolaceThermasol Design System
Brand
Scheme

System

Governance

Solace is maintained as a versioned product — built from a single token source, released under semver via Changesets, and held to a published accessibility and contribution standard.

Principles of the system

Three rules hold the system together. They are not aspirations; they decide whether a change is allowed in.

  • Tokens are the single source of truth. Color, type, space, motion, and elevation are defined once as W3C DTCG JSON and compiled by Style Dictionary into CSS variables, the Tailwind preset, and TypeScript types. Nothing downstream hardcodes a value the tokens already own.
  • Components consume semantic tokens only. A component never reaches for a primitive like color.sand.500. It binds to intent — color.bg.canvas, color.text.primary — so that retheming is a token concern, never a component rewrite.
  • Accessibility is non-negotiable. Every component ships meeting WCAG 2.2 AA. An inaccessible component is not "done," and accessibility regressions block release the same way a failing test does.

Token naming convention

Tokens flow through three tiers. Each tier may only reference the tier above it, which keeps theming and refactors contained.

TierRoleExampleMay reference
PrimitiveRaw, immutable valuescolor.sand.500, space.4, font.size.lgnothing
SemanticMode-aware intent aliasescolor.bg.canvas, color.text.primary, color.accentprimitives
ComponentPer-component contractsbutton.primary.bg, input.border, card.paddingsemantic tokens

Naming is tier.category.role.variant in dot notation — readable in JSON, in code, and in design.

Semantic tokens resolve across two dimensions at once: brand (B2C warm ↔ B2B cool) and scheme (light ↔ dark). That gives four resolved modes from one semantic layer — for example, color.bg.canvas returns a warm cream in B2C light and a deep cool in B2B dark, while every component referencing it simply follows.

Versioning & releases

Solace follows semver, and every change ships with a Changeset declaring its bump. Changesets aggregate into the published changelog and drive the release.

BumpMeansExamples
MajorBreaking change; consumers must actremoving a component or prop, renaming a token, changing default behavior
MinorBackward-compatible additionnew component, new variant, new optional prop, new token
PatchBackward-compatible fixbug fix, a11y correction, docs-only change, internal refactor with no API change

Token changes are versioned with the same rules: renaming or removing a token is major, adding one is minor, retuning a primitive value within its contract is patch.

Contribution workflow

Changes move through a fixed path. New components carry one extra step at the front.

  1. Propose. Open an issue describing the problem and the use cases it serves. For a new component, open an RFC: anatomy, props/API sketch, states, accessibility plan, and prior art. The RFC must establish that the need is shared, not one-off.
  2. Design review. Align the proposal with foundations and existing patterns before any code. Confirm it uses semantic tokens and introduces no redundant primitives.
  3. Build with tests. Implement on Radix primitives with CVA variants, styled from tokens. Ship unit tests, interaction tests, and axe accessibility checks alongside.
  4. Document. Add the docs page — overview, anatomy, props, live playground, variants, accessibility notes, and do/don't — plus a Changeset.
  5. Review. Maintainers review code, tokens, a11y, and docs together. CI must pass: typecheck, lint, tests, and accessibility checks.
  6. Release. Merge triggers the Changeset version bump, changelog entry, and publish.

Accessibility standard

Solace targets WCAG 2.2 AA. Components are built on Radix primitives so semantics and ARIA are correct by default, and every component is verified against these requirements:

  • Keyboard. Every interactive element is reachable and operable by keyboard, with a logical tab order and no traps.
  • Focus. A visible :focus-visible indicator that meets contrast against its background — never removed, only styled.
  • Color contrast. Text and meaningful UI meet AA contrast in all four resolved modes. Color is never the only carrier of meaning.
  • Reduced motion. Animation honors prefers-reduced-motion, degrading to instant or minimal transitions.

Automated axe checks run in CI; they catch regressions but do not replace manual keyboard and screen-reader review during component review.

Deprecation policy

Nothing disappears without warning. Deprecation runs on a predictable, three-step cycle.

  1. Mark. Flag the API as deprecated with a JSDoc @deprecated tag and a console warning in development. The deprecation lands in a minor release.
  2. Document the replacement. State what to use instead, with a migration note and code example, in the docs and changelog. A deprecation is never published without a named successor.
  3. Remove at the next major. The deprecated API stays available through the current major and is removed only in the next major release, so consumers always have a full major cycle to migrate.

Design ↔ code sync

Tokens are the contract between design and code. Both sides resolve from the same DTCG source: code consumes the Style Dictionary outputs, and the design library mirrors the same primitive, semantic, and component tiers — so a token change propagates to both rather than being reconciled by hand.

A Figma library that mirrors the tokens is a planned stretch goal, added once the coded system has shipped. Until then, the published token reference is the canonical source for both designers and engineers, and any design value not expressed as a token is treated as a gap to close, not a precedent to follow.