Prior art: tokens and theming¶
This page covers token formats, tiers, naming and layering, and the CSS that lets several design systems share one page. For each item it gives what the work is and what the module takes from it. For how this fits the wider prior art, see the overview.
Checked against sources on 2026-10-04. Refresh versions and dates before quoting.
How to read the verdicts: adopt means use it as it is; adapt means take the idea and change its shape.
Formats and layering¶
W3C DTCG Format 2025.10 · adopt¶
The first stable design-token format, a W3C Community Group final report published on
2025-10-28 alongside the Color and Resolver modules. Tokens carry $value, $type,
$description, $deprecated and $extensions. The format supports aliases
({group.token}), nested groups with $extends, and colors as objects with an
explicit color space. Token and group names must not contain ., { or }.
For the module: the file format for contract declarations and theme values.
Drupal-specific data goes under $extensions.org.drupal.*.
Format spec · designtokens.org
DTCG Resolver Module 2025.10 · adopt¶
A .resolver.json file declares token sets, modifiers (theme, brand, mode) and a
resolution order. Given an input such as {theme: dark}, it returns one flat token
set, without a combinatorial explosion of files.
For the module: the target layering model: contract, then theme, then project. The
Resolver doesn't track provenance, so the module adds a from field per value. (v0
uses its own ordered layer list, and already records provenance.)
WordPress theme.json · adapt¶
Presets become --wp--preset--* variables. Values merge in layers: core, then theme,
then child theme, then the user's Global Styles, which are stored in the database and
edited in a UI.
For the module: take the layered origins, the parseable variable names and the user layer. Don't let themes choose preset names: patterns and plugins break when the theme changes.
Global settings and styles · Child themes
Style Dictionary, Tokens Studio, Figma Variables · adapt¶
Style Dictionary is the common build pipeline. It has supported DTCG since v4, with partial 2025.10 support (color in 5.3, dimension in 5.4); it doesn't support the Resolver module yet (#1590). Tokens Studio builds themes from combinations of token sets. Figma Variables have collections and modes, extended collections for brands (Enterprise plan), and native DTCG import and export since November 2025.
For the module: optional tooling. Drupal has to work without Node, so the module keeps a small PHP resolver.
Style Dictionary DTCG · Style Dictionary #1590 · Tokens Studio themes
Tiers and naming¶
Material 3, Fluent 2, Spectrum tiers · adopt¶
Tokens come in tiers. Material uses reference (raw palette), system (roles such as primary or surface) and component tokens; Fluent 2 uses global and alias tokens. Fluent's alias tokens include rest, hover and pressed states for light and dark. Spectrum publishes a draft machine-readable design data spec.
For the module: only the semantic (system or alias) tier is public contract. Primitives stay private to each theme, and component tokens belong to pattern specs.
Material theming · Fluent tokens · Spectrum spec
Shopify Polaris token naming · adopt¶
Semantic names follow a group-element-role-prominence-state grammar, for example
--p-color-bg-surface-hover. Polaris React is now deprecated in favour of Polaris web
components, and the token packages were last published in March 2025.
For the module: the same grammar for contract names, with states as suffixes, cited as a historical source.
Token package (archived repository) · Color tokens (archived page)
GNOME libadwaita CSS variables · adopt¶
A small platform contract of background and foreground pairs (window, view, card, accent, destructive, success, warning, error and more) that every app follows, now documented as CSS variables; the older named colors are discouraged. The accent color follows a system-wide preference.
For the module: bg/fg pairs as the basic unit, so contrast can be checked per pair. Its size is a good reference for v0.
Host-injected variables¶
Salesforce SLDS 2 global styling hooks · adopt¶
Semantic CSS variables (--slds-g-*) replace the old design tokens, and themes swap
their values. Salesforce tells component authors to only reference the hooks, never
redefine them, and ships SLDS Linter to enforce it. Component-level hooks
(--slds-c-*) are only a developer preview in SLDS 2 (Fall '26), and Salesforce still
advises components that rely on them to stay on SLDS 1 themes.
For the module: the closest analogue to this project. Keep the public contract global and semantic, and ship a linter from the start.
Styling hooks · SLDS 1 to SLDS 2
VS Code --vscode-* theme colors · adopt¶
VS Code exposes its theme colors (more than 750 are listed) as CSS variables in extension webviews, so extensions in any framework match any installed theme.
For the module: the consumption model: the host injects plain CSS variables. Not the size: the semantic tier stays small.
Figma plugin themeColors · adopt¶
With themeColors: true, Figma injects --figma-color-* variables and light and dark
classes into plugin UIs, and updates them live (not for externally hosted plugin UIs).
For the module: the minimal version of the idea: inject semantic variables into every island.
CSS for several design systems on one page¶
CSS @scope · adopt¶
Baseline (newly available) since 2026-03-24. Chrome has shipped it since 118, Safari since 17.4 and Firefox since 146; the Baseline date is when Safari 26.4 fixed a Safari 26 regression. Scope roots with lower boundaries let one design system's variables stop where another begins.
For the module: the target for nested regions such as the Navigation bar on a
frontend page, for example @scope ([data-ds="admin"]) to ([data-ds]). (v0 uses
attribute selectors and cascade layers.)
Cascade layers · adopt¶
Precedence follows the declared layer order, not specificity or load order. Unlayered
styles still beat layered ones, !important reverses the order, and a shadow root's
layers don't join the page's order.
For the module: declare one order up front, for example
@layer ds.contract, ds.theme, ds.project, ds.user, so project overrides always win.
@property registration · adapt¶
Typed custom properties with initial values and inheritance control. Registrations only take effect from the main document, not from inside shadow roots; properties used in shadow DOM still follow the document's registrations.
For the module: register contract tokens once, globally. Components never register their own.