theme-system-design

Installation
SKILL.md

Theme System Design

Coverage

A theme system is a contract between design decisions and component code, expressed as named tokens that components consume and themes resolve. The mainstream model uses three tiers — reference tokens (raw values: blue.500 = #1E66F5), system or semantic tokens (intent-named: color.background.surface, color.text.primary), and component tokens (component-specific overrides: button.primary.background). Components consume system and component tokens only; themes provide reference-token-to-system-token mappings. This indirection is what allows a single theme swap to repaint the whole product without component edits.

CSS custom properties are the dominant runtime delivery mechanism for web themes. A theme is a set of custom-property assignments scoped to a selector — typically :root for the default, [data-theme="dark"] for alternates. Custom properties cascade and inherit, so a theme override on a subtree (a dark-on-light landing-page hero inside a light app) is a single attribute change. The W3C Design Tokens Community Group format (design-tokens.org) is the emerging interchange standard, expressed as JSON with $value, $type, and $description; tooling (Style Dictionary, Tokens Studio, Terrazzo) transforms it into platform outputs (CSS variables, iOS catalogs, Android resources).

Runtime switching has three operational pieces: persistence (localStorage or a cookie if SSR-sensitive), application (a class or data attribute on the document root before first paint to avoid flash), and propagation (notify components that read theme imperatively — chart libraries, canvases). The pre-paint application typically requires a small inline script in the document head that runs before the stylesheet loads.

Theme contracts make additive changes safe and breaking changes visible. Adding a new system token is safe; renaming or removing one is a breaking change requiring a deprecation cycle. Components that read tokens by exact name should not be expected to handle missing tokens gracefully — a missing token resolves to the CSS variable's fallback value (or invalid, depending on the property), which is rarely what's wanted in production.

Philosophy

The indirection earns its complexity by separating two rates of change: brand decisions change rarely, theme assignments (which brand color means "danger") change occasionally, and components change continuously. A flat token system collapses these into one rate and forces every component to know about every brand value. The three-tier model gives each rate of change its own surface to evolve on.

Semantic names beat descriptive names. color.background.surface tells a component author what to use; color.gray.100 forces them to know that gray.100 happens to be the surface color today and changes meaning when the theme flips. The discipline is to resist convenience names that leak appearance into the contract.

Related skills

More from jacob-balslev/skills

Installs
6
First Seen
12 days ago