Skip to content

Schema reference

The standard is three lexicons (AT Protocol schemas) under the place.mode.standard.* namespace. Two are records you save to your account; one is a set of shared type definitions the others reuse.

Lexicon Kind What it is
place.mode.standard.theme record A saved theme, one complete look, keyed by the expression it serves.
place.mode.standard.profile record Your participation (no default-theme pointer).
place.mode.standard.defs definitions Shared building blocks the theme record references.

One complete look, saved to your account. Its record key is the expression it serves: …/theme/dark, …/theme/com.homedepot.easter, …/theme/default, so a repo holds at most one theme per expression (a second write to the same key overwrites). You can still publish many themes; each just serves a distinct expression. The record is self-contained: it carries its own full copy of the values and references no other theme.

Field Type Required Notes
(record key) string · valid rkey The expression this theme serves (dark, com.homedepot.easter, default). Case-sensitive; any valid record key is a safe data-mode token (the delimiters data-mode uses, / and whitespace, can’t appear in one). This is the identity; there is no expresses field, and displayName below is presentation only. See Common expressions.
displayName string · ≤64 graphemes : Optional display name, presentation only: identity and matching stay on the record key; an app never matches or dedupes on it. (Same limits as a Bluesky profile’s displayName.)
description string · ≤256 graphemes : Optional human-readable description.
aspects aspects The theme’s renderable style, grouped by aspect, the only part rendered to CSS variables. A required container; each aspect inside is optional but complete when present.
fonts array of fontDescriptor : Font faces the theme’s text relies on, theme-level assets referenced by text.*.family, rendered to document-global @font-face (not variables), which is why they sit here beside aspects rather than inside it. Optional.
createdAt string · datetime ISO-8601 timestamp.
// saved at rkey "dark" → at://did:plc:…/place.mode.standard.theme/dark
{
"$type": "place.mode.standard.theme",
"displayName": "Midnight Ride",
"description": "My dark look.",
"aspects": {
"color": {
"control": { "background": "#0b1020", "foreground": "#e6e9f5", "border": "#1c2540" },
"action": { "primary": { "…": "" }, "secondary": { "…": "" }, "auxiliary": { "…": "" } },
"surface": { "primary": { "…": "" }, "secondary": { "…": "" }, "auxiliary": { "…": "" } }
}
},
"createdAt": "2026-07-09T00:00:00Z"
}

A singleton (record key self) that declares you participate in the standard. It’s a participation flag and the anchor for domain verification, and the natural home for future user-level settings. There is no default-theme pointer: your baseline look is simply the theme you saved at the reserved record key default, matched like any other concept (see Common expressions).

Field Type Required Notes
createdAt string · datetime
{
"$type": "place.mode.standard.profile",
"createdAt": "2026-07-09T00:00:00Z"
}

The shared building blocks. The theme record references these by name; you never write them standalone. This is where the 33 intents live, grouped by aspect.

The container the theme record’s aspects field points at, the renderable style, grouped by aspect. Each aspect is optional but complete when present; new aspects (motion, density, …) are added here as the core grows.

Field References Notes
color colorAspect The 21 color intents. Optional, complete when present.
typography typographyAspect The 12 text intents. Optional, complete when present. (Fonts its text relies on are theme-level; see the theme’s fonts.)

The three color values for one purpose. All required.

Field Type Notes
background string · ≤128 Any CSS <color>.
foreground string · ≤128 Text / icon color.
border string · ≤128 Border color.

Typography metrics for one text priority. All required. (No color; a text’s color comes from the surface it sits on.)

Field Type Notes
size string · ≤128 CSS <length-percentage> (e.g. 1rem).
weight string · ≤128 CSS <font-weight>.
family string · ≤256 CSS font-family; matched to a fonts entry by name.
lineHeight string · ≤128 CSS line-height.

actionPriorities · surfacePriorities · textPriorities

Section titled “actionPriorities · surfacePriorities · textPriorities”

Three priority levels, each referencing the intent above. All three required.

Priority counts down: from the thing claiming most of a reader’s attention to the thing claiming least. What that means depends on the purpose, which is why each purpose has its own definition rather than sharing one.

Field actionPriorities surfacePriorities textPriorities
primary The one thing the screen most wants you to do A surface that interrupts the page: modal, dialog, alert, sheet Headlines and titles
secondary A supporting choice A surface over the page, not instead of it: flyout, menu, popover Body copy
auxiliary The quietest choice The page, and everything on it rather than above it: cards, bars, panels Detail and help: captions, hints, legal

The first two reference colorIntent, the third textIntent.

The complete color aspect, 21 intents. All required.

Field References Purpose
control colorIntent Form inputs. No priority; all controls are peers.
action actionPriorities Buttons / links, by priority.
surface surfacePriorities Non-interactive containers, by how far above the page they sit.

The complete typography aspect, 12 text intents.

Field Type Required Notes
text textPriorities The 12 text intents.

The font faces the text relies on are not part of this aspect; they’re theme-level assets in the theme’s fonts, matched to a text.*.family by name. (An aspect renders to scoped variables; fonts render to document-global @font-face, so they live separately.)

One CSS @font-face. Per the CSS spec only two things are necessary, so only family is schema-required, and a source (src or file) is required by the standard. A minimal entry is { family, src }.

Field Type Required Notes
family string · ≤256 The font-family name.
src string · ≤1024 see note A URL, or a CSS src value.
file blob · font/* · ≤5 MB see note A font file stored on your account; preferred over src (it travels with you and can’t rot).
weight string · ≤32 : font-weight descriptor or range.
style string · ≤32 : font-style.
stretch string · ≤64 : font-stretch / width.
unicodeRange string · ≤2048 : unicode-range, lets several entries share one family for subsetting.
display string · ≤32 : font-display.

Each intent’s path becomes a CSS custom property: color.surface.primary.background--color-surface-primary-background (camelCase segments kebab-cased: lineHeightline-height). That deterministic naming is what lets one person’s theme travel between apps. An app applies a theme by setting those variables on an element marked with a data-mode attribute (never :root) and ranking competing sources with cascade layers; the Mode Contract has the full rules for emitting and resolving these.