Agents

Building on-brand with Claude Code

Sync → preview → build a real product on brand tokens → rebrand as a diff.

The synced folder turns "make it on-brand" from a prompt-engineering wish into a dependency. This walkthrough goes from nothing to an on-brand Next.js page, then a rebrand.

1. Sync

npm install -g braaand
braaand auth login
braaand sync

Every brand you can access lands in ~/Documents/Braaand (change with braaand sync set-root). Each brand folder is self-describing — open its CLAUDE.md and any agent knows the rules.

2. Preview

In Claude Code:

"Show me Reform Society's colors and type on dark"

The agent runs braaand sync status --json (never guesses paths), reads brand.json, composes swatch grid + type specimens into _shared/shell.html, and opens Previews/preview.html — with the brand's real woff2 fonts and download links per asset.

3. Build

"Build a landing page hero for Reform Society in this Next.js + Tailwind project"

The agent copies the brand into the project — never links:

src/brand/tokens.css          ← copied from <brand>/dist/
src/brand/fonts.css           ← paths rewritten for the project
src/brand/tailwind.tokens.css ← Tailwind v4 @theme
src/brand/style-guide.tailwind.css ← the base tags + named classes (@layer base + @utility)
src/brand/style-guide.with-tailwind.css ← the ONE import: Tailwind first, then the four above
public/fonts/*.woff2          ← copied from <brand>/fonts/
/* app/globals.css — one line; the order lives inside the file */
@import "../src/brand/style-guide.with-tailwind.css";

A project that already imports tailwindcss keeps its own import and adds the four files after it (tokens.css, fonts.css, tailwind.tokens.css, style-guide.tailwind.css) — the tag rules sit in the same base layer as Preflight and win only by coming later. Cascade layers order by first declaration, so no extra layer can make that rule go away; owning the file that imports Tailwind is what does.

Then it builds with token utilities only — bg-brand-dark, text-brand-accent-on-dark, font-brand-heading, p-brand-lg — no raw hex, no re-declared fonts. With the style guide imported, a bare <h1> or <p> is already on-brand and the named classes (heading-style-h2, text-size-large, padding-section-medium, container-large, button is-secondary) cover the rest; braaand design-system show <brandId> lists every one with its provenance, so read it before hand-writing type. Tailwind v3 projects register dist/tailwind.preset.js instead; plain-CSS projects use var(--brand-*) directly. The copied files keep their provenance header:

/* Reform Society · brand v14 · synced 2026-07-17T09:42Z · generated by Braaand — do not edit */

Copying (instead of a live hosted stylesheet) is deliberate: deployed products can't reach your home folder, and a rebrand should never restyle production silently. The copy is the lockfile.

If the project uses shadcn/ui, the components come from upstream and Braaand themes them. One command installs both, offline:

npx shadcn@latest add ~/Documents/Braaand/reform-society/dist/ui-kit.json

That pulls the standard shadcn components from upstream and applies the brand: dist/ui.css carries the full shadcn token surface (--primary, --background, --border, --radius, the chart and sidebar sets, light and dark) plus an @layer sheet of [data-slot] rules for the things a token can't carry — the true button pill, uppercase CTAs, letter-spacing, the display face on card titles. An untouched <Button> comes out on-brand.

You can see and tune all of this at Brand → Design System before you build. Braaand ships no component code, deliberately: the components stay upstream's and stay current, and a rebrand reaches them because they were never forked. Which is also the one rule — never hand-edit components/ui/* to brand it. An edited component is invisible to the next braaand sync.

Motion travels the same way. dist/motion.css carries the brand's reveals and drifts as @keyframes plus one class per preset — add brand-motion-rise to a heading and it enters exactly like a heading in the brand's ads, on the brand's own curve and timing; stagger a list with --brand-motion-delay. dist/motion.json is the manifest for anything else: each ease as CSS, as a numeric bezier, and as a GSAP CustomEase path, plus the durations, staggers and per-role defaults (heading → rise, cta → pop + pulse). The rule for agents is the same as for colors: animate with these, never with invented curves.

3a. Start a new project — braaand init

For a NEW project the fastest honest path is one command:

braaand init <brandId> my-site

It runs create-next-app (TypeScript, Tailwind 4, App Router, src/), npx shadcn init with the brand's kit (the one command that applies the kit's components.json config), exports the bundle into src/brand/ with four starter sections, copies the fonts to public/fonts/, makes globals.css import with-tailwind.css as the one brand import, writes a /style-guide page that renders every tag, class and section so you can see the brand hold up before writing a line, drops src/brand/README.md, and links the project. --stack plain writes brand/ (the tokens and the plain style-guide.css) plus an index.html assembled from the sections' HTML twins instead; --no-shadcn skips the kit.

The doctrine behind it — the same four lines the skill, the synced root CLAUDE.md and every style-guide read carry:

  • NEW project → braaand init <brandId> [dir]: the preferred stack is Next.js 16 + Tailwind 4 + shadcn/ui, because the export is honest Tailwind 4 (with-tailwind.css is the ONE import) and the kit installs stock shadcn components already wearing the brand; the scaffold ships a /style-guide page proving it and links the project.
  • EXISTING project → braaand link <brandId> once, then copy dist/ (or the export bundle) in; import with-tailwind.css (Tailwind 4) or styles.css after your own Tailwind import; keep every provenance header intact.
  • ANOTHER stack (Vue, Svelte, Rails, SCSS, CSS-in-JS, native) → TRANSLATE, never invent: the same --brand-* names as CSS custom properties, the class names verbatim as your own classes, style-guide.css (the plain target — css.plain on get_style_guide) ported into the stack's idiom, the sections' HTML twins as the markup; keep the provenance header; a value that is not in the brand does not exist.
  • ALWAYS braaand check (MCP lint_project) before reporting a build done, and again after applying a rebrand diff — zero findings is the bar.

Two commands close the loop between a project and the brand it copied:

  • braaand link <brand> in the project registers it as a consumer — the stack (read off package.json), every vendored braaand file (found by its brand v<N> · generated by Braaand header) and the version it copied — into .braaand/project.json and on the brand's page (Design System → Export → Projects), so "where is this brand used, and which copies are behind" has an answer. braaand sync re-reports a linked project it is run inside; braaand unlink forgets it.
  • braaand check is the off-brand linter — a deterministic scan, no model — over the project's stylesheets and components: a raw hex / rgb / hsl that is not one of the brand's colours (the fix names the nearest one), a font-family the brand does not ship, an unlayered rule on a bare h1 / p / a that beats the style guide's base layer, a vendored copy whose header is behind the brand, a stylesheet that imports Tailwind but never the brand, and a braaand import placed before Tailwind. Exit 1 on findings — put it in CI. The same scan is lint_project over MCP and POST /api/brands/{id}/lint over REST. Run it before reporting a build done, and again after applying a rebrand diff.

3c. Another stack — translate, never invent

Not on Next.js + Tailwind? Nothing here needs it. The --brand-* names are CSS custom properties — use them as-is in SCSS, CSS-in-JS, a Svelte or Vue project, or port them into a Swift / Kotlin token file with the same names. The class names are yours to declare verbatim; style-guide.css (the plain target, css.plain on get_style_guide) has them written out as ordinary CSS, so a non-Tailwind project takes the file whole. The sections' .html twins are the markup for any templating language. Keep the provenance header on every copied file, and run braaand check at the end — the linter reads any stack. The one rule is that a value the brand does not carry does not exist: translate what is there, never invent what is not.

4. Rebrand as a dependency update

When the brand changes in Braaand, its version bumps (v14 → v15). In any project:

"Pick up the latest brand"

The agent runs braaand sync, diffs the project's copy against the synced dist/, and reports before touching anything:

primary #1A4D2E → #16402A · one new accent added · fonts unchanged. Apply?

Confirm, and the copy updates — with an offer to check the places the changed tokens are used.

Where each surface fits

  • This flow (synced folder) — products, prototypes, tools, emails: anything you build and own.
  • start_workflow / the factory — batch ad creatives: braaand produces, scores, and hands back a review board.
  • export_design_system (remote) — same tokens over the wire, for machines without a synced folder. themeId exports the brand as one of its themes; profile: "sites" adds sites/tokens.json + sites/motion-package.json for a Polyther site.