DESIGN.md Field Reference

Every top-level YAML key the parser recognizes (nine in 0.4.0, including the new omitted key), what value type each accepts, the three primitive token types (Color, Dimension, Reference), the seven typography sub-fields, the eight component sub-tokens, and the canonical section order. All drawn from @google/design.md 0.4.0 (spec-config.yaml, spec.md, and dist/linter/index.js).

Last reviewed against @google/design.md 0.4.0 (released July 27, 2026).

Try it in the tool


Top-level frontmatter fields#

The parser recognizes exactly nine top-level YAML keys. Any other key produces no tokens and is left out of every export format. Two lint rules report such keys: unknown-key warns when a key looks like a typo of a schema key (an edit distance of two or less, so omited suggests omitted), and token-like-ignored, new in 0.4.0, warns when an unknown key holds token-like values such as hex colors or dimensions. The CLI reference covers every rule.

KeyTypeRequiredDescription
versionstringNoFormat version string. The current value is "alpha". Omitting this field is valid.
namestringRecommendedShort human-readable name for the design system (for example, Heritage or Mono Studio). Consumed by agents and display tools.
descriptionstringNoOne-line summary of the visual identity. Shown in diffs and agent context.
omittedarray<string | OmittedSection>NoNew in 0.4.0. Token groups the file leaves out on purpose (colors, typography, spacing, rounded, components). Each entry is a group name or an object with section and an optional reason. See the next section.
colorsmap<string, Color>NoColor tokens as name-to-color pairs. Any CSS color string is accepted; six-digit hex (#RRGGBB) is the recommended default.
typographymap<string, TypographyObject>NoTypography tokens as name-to-object pairs. Each object holds up to seven sub-fields (see below).
roundedmap<string, Dimension>NoBorder-radius scale as name-to-dimension pairs (for example, sm: 4px, md: 8px).
spacingmap<string, Dimension | number>NoSpacing scale as name-to-dimension pairs. Used for padding, margin, and gap tokens. Unitless numbers (column counts, ratios) are also accepted.
componentsmap<string, ComponentObject>NoComponent-level token groups. Each entry maps a component name to an object with up to eight sub-tokens (see below).

The omitted key#

New in 0.4.0. omitted lists the token groups a file leaves out on purpose, so the linter stops reporting them as missing. Each entry is either a plain group name or an object with a section name and an optional reason:

omitted:
  - spacing
  - section: rounded
    reason: "No rounded corners defined in brand book"

The flow form omitted: [spacing, rounded] works too.

Valid names. Exactly the five token groups: colors, typography, spacing, rounded, and components, compared case-insensitively (Spacing works). These are frontmatter token groups, not the Markdown sections below, so layout, shapes, or elevation are not valid entries.

What it suppresses.

What it does not suppress. Every other rule runs as before. missing-primary still fires when colors exist without a primary token, and any tokens you do define are validated normally. No rule reports colors or components as missing, so listing those two only documents the intent.

Findings. The omitted-rules rule validates the list. Its findings carry one of three sub-rule ids in the JSON rule field, not omitted-rules itself:

ruleSeverityPathWhen it fires
declared-omissioninfoomitted.<group>A valid group is listed and defines no tokens. The message reads <group> intentionally omitted, followed by a dash and no <group> tokens will be validated.
redundant-omissionwarningomittedThe group is listed, but tokens are defined for it, so the entry has no effect.
unknown-omissionwarningomittedThe name is not one of the five groups.

Real 0.4.0 output for a file that lists layout:

{
  "severity": "warning",
  "path": "omitted",
  "message": "unknown section name 'layout' in omitted key",
  "rule": "unknown-omission"
}

A misspelled key (omited:) is not read as omitted: unknown-key flags it and the missing-section findings come back. In the viewer at /tool, the matching Markdown section (for example ## Layout for spacing) shows an omitted group that defines no tokens as intentionally omitted, with the reason if you gave one, instead of an empty state.


Primitive token types#

Color#

Any valid CSS color string. The 0.4.0 spec lists these formats:

  • Hex: #RGB, #RGBA, #RRGGBB, #RRGGBBAA
  • Named colors: red, cornflowerblue, transparent
  • Functional: rgb(), rgba(), hsl(), hsla(), hwb()
  • Wide-gamut: oklch(), oklab(), lch(), lab()
  • Mixing: color-mix(in srgb, ...)

Six-digit hex (#RRGGBB) remains the recommended default. The linter converts every value to sRGB for the contrast check, and every export format converts colors to lowercase hex (cornflowerblue becomes #6495ed; DTCG adds sRGB components).

colors:
  primary: "#1A1C1E"
  tertiary: "#B8422E"
  neutral: "#F7F5F2"
primary#1A1C1E tertiary#B8422E neutral#F7F5F2

A value that does not parse is an error, and the token is left out of every export:

'<value>' is not a valid color. Expected a CSS color value (e.g., #ffffff, rgb(0 0 0), oklch(0.5 0.2 240)).

Since 0.4.0, color-mix() needs explicit percentage weights: color-mix(in srgb, #1A1C1E 40%, #FFFFFF) is valid, while color-mix(in srgb, #1A1C1E 0.4, #FFFFFF) is rejected with the error above. Leaving the weights out entirely still parses as an even mix. Angles in grad units, such as hsl(100grad 50% 50%), also parse correctly since 0.4.0.

Dimension#

A number followed immediately by a unit. The three accepted units are px, em, and rem. No space between the number and the unit. Negative values are valid (used for negative letter-spacing).

rounded:
  sm: 4px
  md: 8px
spacing:
  base: 1rem
  tight: 0.5em
typography:
  body-md:
    letterSpacing: "-0.02em"

Token Reference#

A string of the form {path.to.token} that resolves to a token defined elsewhere in the same frontmatter. The reference path is a dot-separated chain of YAML keys.

components:
  button-primary:
    backgroundColor: "{colors.primary}"
    textColor: "{colors.on-primary}"
    rounded: "{rounded.md}"
    typography: "{typography.label-md}"

Depth limits (from spec-config.yaml):

LimitValueWhat it governs
max_reference_depth10How many hops a reference chain may follow before the parser stops resolving.
max_token_nesting_depth20Maximum depth of nested token objects before a standalone error finding is emitted (message: "Token nesting depth exceeds maximum allowed depth of 20"). This is distinct from a broken-ref error.

A component reference that points to a non-existent token triggers a broken-ref error (severity: error). An alias inside a token group, such as a color whose value is {colors.missing}, is not reported; that token is dropped.

Nested groups and dot paths#

Tokens under colors, spacing, and rounded can sit in nested groups. A nested token's name is its dot path, so the accent below is the color brand.accent, referenced as {colors.brand.accent}:

colors:
  primary: "#1A1C1E"
  brand:
    accent: "#B8422E"

Since 0.4.0, the linter reports collisions between flattened dot keys and nested groups as errors, and skips the later definition:

  • A flat key written with a dot that repeats a nested path, such as brand.accent: "#C0502F" next to the brand group above: Duplicate token path 'colors.brand.accent' detected.
  • A flat key that matches a nested path once its dots become hyphens, such as brand-accent: "#D0603F" next to the brand group: Grouped colors token flattens to 'brand-accent', which is already defined.

The hyphen form matters because flat outputs use it: the css-vars export writes brand.accent as --color-brand-accent.


Typography object#

Each entry under typography maps a name to an object with up to seven sub-fields. All sub-fields are optional; a token with only fontFamily and fontSize is valid.

Sub-fieldTypeDescription
fontFamilystringCSS font-family value. No quotes needed in YAML unless the name contains special characters.
fontSizeDimensionSize with unit (px, em, rem). Example: 48px, 1.5rem.
fontWeightnumberNumeric weight such as 400 or 700. In YAML, either a bare number or a quoted string is accepted; both are equivalent.
lineHeightDimension or numberA Dimension (e.g., 24px) or a unitless multiplier (e.g., 1.6). A unitless number multiplies fontSize, matching standard CSS behavior.
letterSpacingDimensionTracking value. Negative values tighten headlines; positive values open up all-caps labels. Example: "-0.02em", "0.1em".
fontFeaturestringMaps to CSS font-feature-settings. Controls OpenType features such as tabular numbers ("tnum") or stylistic alternates ("ss01").
fontVariationstringMaps to CSS font-variation-settings. Used with variable fonts. Example: "'wght' 650, 'opsz' 32".

Since 0.4.0, an unrecognized typography sub-property produces a warning. The finding comes from the model builder rather than a lint rule, so it has no rule field:

{
  "severity": "warning",
  "path": "typography.body-md.lineHeigth",
  "message": "'lineHeigth' is not a recognized typography property. Valid properties: fontFamily, fontSize, fontWeight, lineHeight, letterSpacing, fontFeature, fontVariation."
}

Example:

typography:
  h1:
    fontFamily: Public Sans
    fontSize: 48px
    fontWeight: 600
    lineHeight: 1.1
    letterSpacing: "-0.02em"
  body-md:
    fontFamily: Public Sans
    fontSize: 16px
    fontWeight: 400
    lineHeight: 1.6
  label-caps:
    fontFamily: Space Grotesk
    fontSize: 12px
    fontWeight: 500
    lineHeight: 1.0
    letterSpacing: "0.1em"

Recommended token names (from spec-config.yaml): headline-display, headline-lg, headline-md, body-lg, body-md, body-sm, label-lg, label-md, label-sm. Custom names are accepted without error.


Component sub-tokens#

Each entry under components maps a component name to an object. The recognized sub-tokens are:

Sub-tokenTypeDescription
backgroundColorColorFill color of the component surface. Checked against textColor for WCAG AA contrast.
textColorColorForeground color for text and icons. Checked against backgroundColor for WCAG AA contrast.
typographyTypography (Reference)Reference to a typography token (e.g., {typography.label-md}). Resolved at lint time.
roundedDimensionCorner radius. Accepts a literal Dimension or a reference (e.g., {rounded.md}).
paddingDimensionInternal padding. Accepts a literal Dimension value.
sizeDimensionGeneral size (used for icon size, avatar diameter, etc.).
heightDimensionExplicit height of the component.
widthDimensionExplicit width of the component.

Unknown sub-token names produce a broken-ref warning (severity: warning), not an error. The valid sub-token names are: backgroundColor, textColor, typography, rounded, padding, size, height, width.

Example:

components:
  button-primary:
    backgroundColor: "{colors.primary-60}"
    textColor: "{colors.primary-20}"
    rounded: "{rounded.md}"
    padding: 12px
  button-primary-hover:
    backgroundColor: "{colors.primary-70}"

Canonical section order#

Markdown sections (introduced with ## headings) must appear in this order when present. Sections may be omitted freely; only the relative order of those that do appear is checked. (The omitted frontmatter key is unrelated: it names token groups, not these Markdown sections.)

PositionCanonical nameAccepted aliases
1OverviewBrand & Style
2Colors
3Typography
4LayoutLayout & Spacing
5Elevation & DepthElevation
6Shapes
7Components
8Do's and Don'ts

Out-of-order sections trigger a section-order warning. Additional or custom sections (Icons, Accessibility, Voice & Tone, etc.) are accepted and preserved by the parser without error. Duplicate top-level YAML keys across multiple code blocks in the same file trigger a parser-level error (the adapter returns a DUPLICATE_SECTION error code, e.g., "Section 'colors' is defined in both frontmatter and code block 2").


The spec-config defines recommended names per token group to maximize interoperability with agents and exporters:

Colors: primary, secondary, tertiary, neutral, surface, on-surface, error

Typography: headline-display, headline-lg, headline-md, body-lg, body-md, body-sm, label-lg, label-md, label-sm

Rounded: none, sm, md, lg, xl, full

These names are recommendations only. Custom names do not produce errors or warnings.


Spec version#

The format version is still alpha. The current package is @google/design.md 0.4.0, released July 27, 2026, and still pre-1.0. Inspect the live rules table (eleven rules in 0.4.0) with:

npx @google/design.md spec --rules

Was this page helpful?