Skip to content

Theming and overrides

Sections marked as "Note" or "Example" are non-normative. Everything else is normative.

This chapter defines how layered documents evaluate overrides and resolve context-specific variants.

Layered documents

Token documents MAY be layered to create themes. When multiple documents are merged, later documents MUST override earlier ones for identical JSON Pointer paths. Theme identifiers SHOULD use human‑readable names such as light and dark. Conditional variants MAY be expressed using $extensions.

$overrides

A token document MAY include a $overrides array at the document root. Each override maps contextual conditions to an alternate token reference or value. Overrides are evaluated sequentially. Consumers MUST process overrides in array order, evaluating each entry against the current context. When multiple matching entries target the same $token, the last matching entry MUST take effect and earlier matches MUST be ignored.

An override object MUST contain a $token field whose value is a JSON Pointer to the token being overridden and a $when object describing the matching context. It MUST provide either a $ref field pointing to an existing token, an inline $value field, or a $fallback field supplying one or more alternatives. $ref and $valueMUST NOT both appear. The token addressed by $tokenMUST declare a base $value or $ref so resolution can fall back to the original definition when no override applies. The override target MUST be a token object that declares $type; pointers resolving to collections or untyped nodes MUST be reported as errors.

Override $token, $ref, and $fallback entries share the same lexical rules as token aliases: each string MUST contain a # fragment encoding the JSON Pointer using /-delimited segments with ~0/~1 escapes and MUST either start with # or prefix the pointer with a relative path or HTTP(S) URI.

Inline values within overrides- including those nested inside $fallback chains- MUST satisfy the schema for the target token's declared $type. Referenced tokens MUST resolve to the same $type. An override that omits all of $ref, $value, and $fallback, or that specifies both $ref and $value, is invalid and MUST be ignored.

The $fallback field MAY be a single object containing $ref or $value and its own $fallback, or it MAY be an array of such objects evaluated in order. Consumers apply the first entry that resolves; subsequent entries act as fallbacks in case earlier ones cannot be resolved.

The $token pointer for an override MUST resolve to an existing token. When evaluating $ref entries- including those nested inside $fallback chains- consumers MUST ensure that every pointer they dereference resolves. If override evaluation exhausts its candidates without producing a resolved pointer, consumers MUST treat the unresolved pointer as an error rather than silently ignoring the override.

When resolving overrides- including nested $fallback chains- consumers MUST detect circular dependencies. Implementations MUST track visited override targets during resolution and report an error if evaluation returns to a previously visited target.

This specification does not define the structure of the $when object; producers and consumers MAY agree on arbitrary keys (for example prefers-color-scheme or platform). Consumers encountering $when keys they do not recognise MUST ignore those keys. When no recognised keys match the current context, the override does not apply and the base token value MUST be used.

Overrides do not replace the referenced tokens; they redirect aliases based on context. Tokens for each variant MUST be declared separately to preserve explicitness.

json
{
  "$overrides": [
    {
      "$token": "#/button/bg",
      "$when": { "prefers-color-scheme": "dark" },
      "$ref": "#/color/brand/dark"
    }
  ]
}
json
{
  "$overrides": [
    {
      "$token": "#/button/text",
      "$when": { "prefers-color-scheme": "dark" },
      "$value": { "colorSpace": "srgb", "components": [1, 1, 1, 1] }
    }
  ]
}
json
{
  "$overrides": [
    {
      "$token": "#/button/text",
      "$when": { "prefers-color-scheme": "dark" },
      "$fallback": [
        { "$ref": "#/color/brand/dark" },
        { "$value": { "colorSpace": "srgb", "components": [1, 1, 1, 1] } }
      ]
    }
  ]
}

A complete document demonstrating override mechanics is available at examples/overrides.tokens.json.

Common condition keys

Producers and consumers MAY support a shared vocabulary of $when keys to express contextual overrides. Common examples include:

prefers-color-scheme : User colour scheme preferences such as light or dark.

prefers-reduced-motion : User preference indicating reduced or standard motion effects.

prefers-contrast : User preference for contrast levels like more, less, or no-preference.

platform : Target runtime or operating system such as android, ios, or web.

locale : Language or regional settings influencing typography or content direction.

reduced-data : Network data-saver state signalling whether high-bandwidth resources should be avoided.

INFO

Metadata-driven context keys are described in Metadata.