ThemeSpec
The design-token document the car paints — colors, wallpaper, typography, shape, and gauge, with the hex rule and defaults.
ThemeSpec is the inline spec object inside a
ThemeManifest — the design-token
document the car consumes to build a Flutter ThemeData via
AppTheme.fromSpec(). It is embedded in the catalog row so a tile can
render a palette preview without downloading the bundle.
Omitting wallpaper, typography, shape, and gauge reproduces the
car's default look exactly — the feature ships inert.
Top-level
| Field | Type | Required | Default | Notes |
|---|---|---|---|---|
schema | int ≥ 1 | no | 1 | Spec document version. Must equal the host's THEME_SCHEMA to be fully understood; a higher value tells the car to fall back to its built-in default theme. |
brightness | "light" | "dark" | yes | — | Drives the ThemeData base brightness. |
colors | object | yes | — | The color tokens. See Colors. |
wallpaper | object | no | — | Optional wallpaper layer. See Wallpaper. |
typography | object | no | — | Optional font overrides. See Typography. |
shape | object | no | — | Optional corner-radius tokens. See Shape. |
gauge | object | no | — | Optional gauge skin. See Gauge. |
The object is strict — an unknown key at any level fails validation (it is almost always a typo for one of the fixed fields).
The hex format rule
Every color value is a hex string matching
^#([0-9a-fA-F]{6}|[0-9a-fA-F]{8})$ — that is, #RRGGBB or #AARRGGBB,
case-insensitive. The 8-digit form is alpha-first (ARGB), matching the
Flutter Color parser on the car.
Colors
The 8 surface keys map 1:1 onto the car's internal _Palette; the
brand/semantic keys map onto the Material ColorScheme. All surfaces
plus accent/secondary/error are required; warning and
neutral are optional and fall back to the car's built-in values.
Surfaces (required)
| Key | Maps to | Notes |
|---|---|---|
background | _Palette background | The base canvas behind everything. |
surfaceLow | _Palette low surface | Recessed / lowest-elevation surface. |
surfaceContainer | _Palette container | Default container/panel fill. |
surfaceHigh | _Palette high surface | Raised / highest-elevation surface. |
outline | _Palette outline | Primary border/divider color. |
outlineVariant | _Palette outline variant | Subtler border/divider color. |
onSurface | _Palette on-surface | Primary text/icon color on surfaces. |
onSurfaceVariant | _Palette on-surface variant | Secondary/muted text on surfaces. |
Brand / semantic
| Key | Required | Maps to | Default |
|---|---|---|---|
accent | yes | ColorScheme.primary (replaces direct AppColors.accent) | — |
secondary | yes | ColorScheme.secondary | — |
error | yes | ColorScheme.error | — |
warning | no | AppColors.warning | car built-in |
neutral | no | AppColors.neutral | car built-in |
Wallpaper
Optional whole object; every field is an optional bundle-relative path
the publish service rewrites to a CDN URL at submit time (identical to
icon). Omit the object for "no wallpaper — paint the solid surface
colors". Allowed extensions: PNG / JPEG / WebP / SVG.
| Key | Required | Notes |
|---|---|---|
home | no | Painted behind the home surface (light/default). |
homeDark | no | Optional dark-mode variant of the home wallpaper. |
cluster | no | Painted behind the instrument-cluster surface. |
Typography
Optional. v1 prefers system families (Inter / Cairo). Omit the whole
object to inherit the host font (Inter/Cairo by locale).
| Key | Type | Default | Notes |
|---|---|---|---|
family | string (1–64 chars) | "Inter" | Font family name. |
bundled | boolean | false | true → the family ships in the bundle fonts/ dir. Reserved for a future host release; the car may ignore it in v1. |
Shape
Optional corner-radius tokens. The defaults reproduce the car's exact
current look, so omitting shape is zero visual change.
| Key | Type | Default | Range |
|---|---|---|---|
cardRadius | number | 24 | 0–48 — card/panel corners. |
buttonRadius | number | 14 | 0–48 — button corners. |
inputRadius | number | 14 | 0–48 — text-input corners. |
Gauge
Optional gauge skin. The car may ignore this in v1 — it is parsed and round-tripped so a future host can render it without a schema bump.
| Key | Type | Required | Notes |
|---|---|---|---|
skin | string (1–32 chars) | yes | Skin identifier. The car maps known names to a painter and falls back to its default for unknown values. |
ringColor | hex color | no | Ring accent. Defaults to colors.accent on the car. |
Full example
{
"schema": 1,
"brightness": "dark",
"colors": {
"background": "#07070D",
"surfaceLow": "#0F1018",
"surfaceContainer": "#13141C",
"surfaceHigh": "#1A1C26",
"outline": "#4B5064",
"outlineVariant": "#24262F",
"onSurface": "#F3F4F8",
"onSurfaceVariant": "#8A90A4",
"accent": "#22D3A8",
"secondary": "#5B8CFF",
"error": "#E76F51",
"warning": "#F4A261",
"neutral": "#6A7088"
},
"wallpaper": {
"home": "./wallpaper/home.png",
"homeDark": "./wallpaper/home-dark.png",
"cluster": "./wallpaper/cluster.png"
},
"typography": { "family": "Inter", "bundled": false },
"shape": { "cardRadius": 24, "buttonRadius": 14, "inputRadius": 14 },
"gauge": { "skin": "neon", "ringColor": "#22D3A8" }
}Related
ThemeManifestreference — the row that carries thisspec.- Building a theme — authoring + publish.
- Categories — the closed
categoryenum.