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 $value
MUST NOT both appear. The token addressed by $token
MUST 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.
{
"$overrides": [
{
"$token": "#/button/bg",
"$when": { "prefers-color-scheme": "dark" },
"$ref": "#/color/brand/dark"
}
]
}
{
"$overrides": [
{
"$token": "#/button/text",
"$when": { "prefers-color-scheme": "dark" },
"$value": { "colorSpace": "srgb", "components": [1, 1, 1, 1] }
}
]
}
{
"$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.