> ## Documentation Index
> Fetch the complete documentation index at: https://substrate.docs.unknowncreatives.studio/llms.txt
> Use this file to discover all available pages before exploring further.

# Brand Config: The YAML That Defines a Substrate Brand

> Every Substrate brand is one YAML config: an open intents map plus elevation, typography, shape, motion, space, and flexibility. Learn the file layout, the required sections, and how keys are normalized at load.

A brand in Substrate is a directory containing a YAML config. That file is the only place you author brand identity — the pipeline reads it and emits solver inputs, style descriptors, and baked per-mode token files for every platform. There is no JSON config, no root-level config file, and no registration step: brands are discovered by scanning the brands directory.

<Note>
  **Demo brands only.** All brand configurations bundled with the Substrate engine, and all brand names used in examples throughout these docs, are fictional demonstrations created to exercise the engine. They do not represent clients or customers of Substrate or its authors, and no affiliation with, sponsorship by, or endorsement from any real company is implied.
</Note>

## File layout

Two shapes are supported, and which one you get depends entirely on the directory structure.

<Tabs>
  <Tab title="Brand family">
    A family directory holds a shared `config.global.yaml`, and each sub-brand directory holds a `config.yaml` containing only its deltas. Most of the engine's bundled demo brands ship this way. For a fictional airline family, Aurora Airways:

    ```
    src/brands/aurora/
    ├── config.global.yaml      # shared foundation
    ├── booking/config.yaml     # deltas only
    ├── rewards/config.yaml     # deltas only
    └── premium/config.yaml     # deltas only
    ```

    Each sub-brand becomes its own brand, with the merged slug `{parent}-{sub}` — `aurora-rewards`. See [Inheritance](/multi-brand/inheritance) for the merge rules.
  </Tab>

  <Tab title="Flat brand">
    A brand with no sub-brands is a single directory with a single `config.yaml` — here, a fictional standalone brand, Acme:

    ```
    src/brands/acme/
    └── config.yaml
    ```

    The slug is the directory name — `acme`.
  </Tab>
</Tabs>

<Note>
  **Keys are authored in kebab-case and normalized to camelCase at load.** `heading-family` becomes `headingFamily`, `duration-base` becomes `durationBase`, and so on throughout the schema. The exception is named-resource maps — `intents`, `gradients`, `ramps`, `materials`, `rampOutputs` — whose direct child keys are your own identifiers and round-trip verbatim one level deep. The scheme-track grammar keys (`scheme-end`, `scheme-track`, `from-intent`) also keep their kebab spelling at any depth, because the kernel consumes them that way. This rule holds for every config page in this section.
</Note>

## The required sections

Seven sections are non-optional. A config missing any of them is incomplete, and a config missing the required intents fails to load outright. Here is an example foundation for the fictional Acme brand (`src/brands/acme/config.global.yaml`), trimmed to the required sections:

```yaml theme={null}
intents:
  brand:
    hue: 277        # Acme Indigo
    chroma: 0.268
  neutral:
    hue: 251        # cool-tinted neutrals
    chroma: 0.012
  danger:
    hue: 11
    chroma: 0.228

elevation:
  step-light: 0.015
  step-dark: 0.04
  sunken-step: 0.02

typography:
  heading-family: "'Acme Sans', 'Inter', system-ui, sans-serif"
  body-family: "'Acme Sans', 'Inter', system-ui, sans-serif"
  base-font-size: 1
  scale-ratio: 1.25

shape:
  radius-base: 6

motion:
  duration-base: 200
  easing: "cubic-bezier(0.25, 0.1, 0.25, 1)"

space:
  unit: 4

flexibility:
  scheme: true
  contrast: { min: 0.75, max: 1.5 }
  density: { min: 0.8, max: 1.3 }
  type-scale: { min: 0.9, max: 1.4 }
  motion: { min: 0, max: 1 }
```

## Every section at a glance

Field-by-field detail, defaults, and a worked example for every section live in the [Config Schema reference](/reference/config-schema) — each row links straight to it. The authoring guides in this section cover the *why* per domain.

| Section                                                                  | Requirement | What it authors                                                                                                                                    |
| ------------------------------------------------------------------------ | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| [`intents`](/reference/config-schema#intents-—-required)                 | Required    | Open map of `hue`/`chroma` colors; only `brand` and `neutral` are mandatory, and custom intents are first-class. See [Color](/brand-config/color). |
| [`elevation`](/reference/config-schema#elevation-—-required)             | Required    | Lightness steps for raised and sunken surfaces, per scheme direction.                                                                              |
| [`typography`](/reference/config-schema#typography-—-required)           | Required    | Font stacks, base size in rem, the modular `scale-ratio`, optional `fluid` and `density` blocks. See [Typography](/brand-config/typography).       |
| [`shape`](/reference/config-schema#shape-motion-space-—-required)        | Required    | `radius-base` in px — scaled by density at runtime, never fixed.                                                                                   |
| [`motion`](/reference/config-schema#shape-motion-space-—-required)       | Required    | `duration-base` and `easing`, both required. See [Motion](/brand-config/motion).                                                                   |
| [`space`](/reference/config-schema#shape-motion-space-—-required)        | Required    | One spatial `unit` in px — there is no spacing ladder. See [Spacing & Density](/brand-config/spacing-density).                                     |
| [`flexibility`](/reference/config-schema#flexibility-—-required)         | Required    | `{ min, max }` bounds per preference axis — the runtime clamps the sliders to them.                                                                |
| [`presets`](/reference/config-schema#presets-—-optional)                 | Optional    | Named positions on the preference continuum: `mode`, `density`, and `contrast` maps.                                                               |
| [`gradients`](/reference/config-schema#gradients-—-optional)             | Optional    | Named gradient recipes — the one place lightness is authored.                                                                                      |
| [`ramps`](/reference/config-schema#ramps-and-color-—-optional)           | Optional    | Stepped opaque scales generated from an intent, for Tailwind-style palettes and DTCG export.                                                       |
| [`materials`](/reference/config-schema#materials-and-effects-—-optional) | Optional    | Surface treatments — per-channel filters, alpha, noise — applied via `data-mode`.                                                                  |
| [`system`](/reference/config-schema#system-—-optional)                   | Optional    | Per-brand deep-merge overrides of the engine's tuning defaults.                                                                                    |

## What the loader does with it

Discovery is a directory scan. For each directory under the brands root, the loader checks for `config.global.yaml` (family) or `config.yaml` (flat), parses the YAML, normalizes the keys, deep-merges family and sub-brand layers where both exist, and stamps the `slug` from the directory structure. That slug is what appears in generated CSS as `[data-brand="aurora-rewards"]`.

Two validations run at load. The intent roster must contain `brand` and `neutral`, or the load throws a missing-required-intent error. Any intent using scheme-track grammar is desugared and validated, including reference cycles and unknown intent names.

<Warning>
  Substrate has no build verb and no per-brand build flag. Generation runs as `npm run generate` in the engine checkout, which regenerates every brand. The `substrate` CLI is a consumer-side onboarding tool with the verbs `init`, `add`, `upgrade`, `adopt`, `setup`, and `artifact` — see [the CLI reference](/tooling/cli).
</Warning>

## Explore each config section

<CardGroup cols={2}>
  <Card title="Color" icon="palette" href="/brand-config/color">
    The open intents map, hue and chroma, scheme tracks, and the solver primitives each intent produces.
  </Card>

  <Card title="Typography" icon="text-size" href="/brand-config/typography">
    Base size, scale ratio, and the continuous power-of-ratio model that replaces a step ladder.
  </Card>

  <Card title="Spacing & Density" icon="layout" href="/brand-config/spacing-density">
    One space unit, multiplied at each use site by the runtime density and scale factors.
  </Card>

  <Card title="Motion" icon="wand-sparkles" href="/brand-config/motion">
    Base duration and easing, and how the motion factor scales them at runtime.
  </Card>

  <Card title="Core Concepts" icon="atom" href="/core-concepts">
    Why the values are computed at runtime rather than baked, and how the preference vector drives them.
  </Card>

  <Card title="Multi-Brand" icon="layer-group" href="/multi-brand/overview">
    Families, sub-brands, deltas-only authoring, and the per-brand output tree.
  </Card>
</CardGroup>
