> ## 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.

# Multi-Brand Architecture on a Single Substrate Engine

> Many brand families can share one Substrate engine. Brands are directories, discovery is a filesystem scan, and every brand inherits the same solver guarantees from its first generation.

Running many brands from one design system usually decays the same way: parallel token files drift, accessibility rules get enforced inconsistently, and every new brand is a fresh integration. Substrate avoids that by keeping the mathematics in one engine and reducing a brand to a config. The solver, the preference vector, the component descriptors, and the accessibility gate are shared; a brand supplies intent and policy.

## What a brand actually owns

More than color. A brand config carries its intents, but also its elevation steps, `shape.radius-base`, typography families and ratio, `motion.duration-base` and `easing`, `space.unit`, its `flexibility` policy bounding every user preference axis, its `presets` (including which mode and density levels exist at all), plus optional `gradients`, `ramps`, `materials`, and `system` overrides. See the [brand config overview](/brand-config/overview) for the full schema.

What a brand does *not* own is the solving. APCA lightness resolution, the scheme axis, CVD and warmth compensation, and the build-failing accessibility gate run identically for every brand. That is why a new brand inherits correct contrast behavior from its first generation rather than earning it.

## Project structure

Brands live in directories under `src/brands/`. There are two shapes, and the directory contents decide which one applies. Here is how a workspace with two fictional brands — the Aurora Airways family and the standalone Acme brand — would be laid out:

```
src/brands/
├── aurora/                     # brand family
│   ├── config.global.yaml      # shared foundation
│   ├── booking/config.yaml     # deltas only
│   ├── cargo/config.yaml
│   ├── corporate/config.yaml
│   ├── premium/config.yaml
│   └── rewards/config.yaml
└── acme/                       # flat brand
    └── config.yaml
```

A directory containing `config.global.yaml` is a **family**: each subdirectory holding a `config.yaml` becomes its own brand, with the merged slug `{parent}-{sub}` — `aurora-rewards`, `aurora-booking`. A directory containing only `config.yaml` is a **flat brand**, and its slug is the directory name.

The engine bundles several demo brand families in this layout for testing and demonstration.

<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>

<Note>
  There is no workspace file, no brand registry, and no registration step. Discovery is a filesystem scan of the brands directory — a brand exists because its directory does. Adding one is covered in [Adding a Brand](/multi-brand/adding-a-brand).
</Note>

## Generating

Generation runs from the engine checkout and covers every discovered brand in one pass:

```bash theme={null}
npm run generate
```

Narrower runs are available for iteration: `npm run generate:tokens`, `npm run generate:ramps`, `npm run generate:descriptors`, and `npm run generate:doc-views` each handle one artifact family, and most accept a target suffix such as `npm run generate:tokens:css` or `npm run generate:tokens:swift`. Every one has a `:check` variant that verifies the committed output matches what the current configs would produce, which is what CI runs.

<Warning>
  Substrate has no build verb and no per-brand build flag — you regenerate the corpus, not a single brand. The `substrate` CLI is a separate consumer-side onboarding tool whose verbs are `init`, `add`, `upgrade`, `adopt`, `setup`, and `artifact` — see [the CLI reference](/tooling/cli).
</Warning>

## Per-brand output

Output lands under `generated/brands/<family>/<sub>/`, one subdirectory per target. For the fictional `aurora-rewards`:

```
generated/brands/aurora/rewards/
├── css/            # brand.gen.css + tokens.{light,dark,highContrast,darkHighContrast}.gen.css
├── swift/          # brand.gen.swift, index.gen.swift, system.<mode>.gen.swift
├── compose/        # Kotlin — same per-mode shape as Swift
├── dtcg/           # DTCG-format design tokens
├── json/           # conformance vectors
├── react-native/
├── xcassets/       # Xcode asset catalog
└── docs/           # generated component documentation views
```

Globally shared artifacts — the continuous scalar expressions, text roles, component descriptors — live under `generated/global/` and are not duplicated per brand. Every generated file carries a `.gen.` marker in its name and a `DO NOT EDIT` header. Changes belong in the brand YAML.

## Why families are worth using

A family exists so that shared decisions live in one file. Updating `src/brands/aurora/config.global.yaml` propagates to all five Aurora sub-brands on the next generation; adding an intent there gives every sub-brand that intent automatically. A sub-brand's own config stays small — a well-factored sub-brand is often around thirty lines of genuine divergence over a shared foundation — and the validator actively flags any line in it that merely restates what it already inherits.

<CardGroup cols={2}>
  <Card title="Inheritance" icon="arrow-down-to-bracket" href="/multi-brand/inheritance">
    The deep-merge contract, null-delete semantics, and why sub-brand configs contain only deltas.
  </Card>

  <Card title="Adding a Brand" icon="circle-plus" href="/multi-brand/adding-a-brand">
    Create a directory, write a config, generate — with no registration step in between.
  </Card>
</CardGroup>
