One branding object read by every surface
A marketing agency running forty client accounts has a job nobody outside the industry sees. Keeping each client looking like themselves across everything at once.
The website, the email campaigns, the social cards and the landing pages all carry the same blue, the same font and the same voice, for forty different companies, and they keep carrying it as those companies grow and change. Brand consistency at that scale is an ongoing, expensive job, and one Giant Context tries to make disappear.
Why brand consistency slips
Brand consistency is the difference between a company that looks like a real business and one that looks assembled from parts. An audience notices, without being able to say why, when the email that arrives does not match the website it links to. Agencies charge for consistency because holding it is work, and across dozens of clients and dozens of surfaces it is a lot of work.
In most tools the brand lives in many places at once. The website has the brand colour pasted into its theme. The email template has the same colour typed in again. The social card generator has it a third time. Each of those is a copy, and copies drift. Someone tweaks the website's blue and forgets the email. A client rebrands and the change lands on the homepage this week, the newsletter next month, the old landing pages never.
Nobody decides a brand should fragment. It fragments because it exists in twenty copies and no two get updated together. Across forty clients that becomes a vigilance job nobody finishes, which is what makes it worth real money to solve.
The object
So a brand exists in exactly one place. One row holds the whole visual and creative identity, and there is no per-surface settings page anywhere in the platform.
The branding row
// core.project_brandings{ // media logoUrl, logoDarkUrl, faviconUrl,
// colour colorPrimary, colorSecondary, colorSuccess, colorError, colorWarning, colorInfo, backgroundLight, backgroundDark, paperLight, paperDark,
// type fontHeading, fontBody, fontScale, headingWeight, bodyWeight, lineHeight, letterSpacing,
// shape and spacing borderRadius, shadowIntensity, spacingScale,
// component styles buttonStyle, // squared | rounded | pill inputStyle, // outlined | filled | standard cardStyle, // flat | elevated | outlined
// AI design briefs contentDesignBrief, // how this brand writes imageDesignBrief, // how this brand looks in pictures voiceDesignBrief // how this brand sounds}The enumerated styles and the numeric scales are pinned by check constraints in the database rather than validated in the application, so a fontScale outside 0.5 to 3.0 or a buttonStyle of anything but those three values cannot be written at all.
The interesting half is what a page stores when someone picks the brand's blue.
A block does not store #6366f1. It stores the token primary. At render, a resolver takes that token, reads the brand's palette, and returns the actual colour, falling back to the theme when a token has no brand value.
Which is why changing a brand's primary recolours every block that referenced primary, without any block being touched. There is no migration, no sweep across pages, no job that rewrites stored styles. The pages never held the colour, so there is nothing in them to update.
The colour picker in the editor puts the brand's semantic colours first, so an author picking a colour is usually picking a token rather than a hex. Raw colours are still available, and a raw colour is the thing that will not move when the brand does.
What reads it
The website server resolves the brand at render. It reads the app's branding id, selects the brand row, and passes it into the page as props, so there is no client fetch on the hot path. The page wraps its content in a scoped theme built from those values, and the colours, typography and shape become the theme for that subtree.
The editor uses the same primitive. Preview and production share one code path, which removes the class of bug where a page looks right in the builder and wrong when published.
Fonts are self-hosted per tenant. The brand's chosen body and heading fonts are served from the platform's own origin, metric-matched so the fallback occupies the same space, which means no cross-origin stylesheet request and no reflow when the real font arrives. Any font a tenant picks gets this, not only the defaults.
The knowledge base and the developer portal render through the same path as the website, so they inherit the theme and the fonts without a branding stack of their own. Email resolves the brand at send and composites its colours and logo into the message.
The share-image route is brand-aware too. A link shared from a tenant's site produces a card in the tenant's fonts, with the tenant's logo, tinted with the tenant's accent, rather than a generic platform card.
The AI reads it too
Three of the columns are written for the model rather than the theme.
The content brief says how the brand writes, the voice brief says how it sounds, and the image brief says how it looks in pictures. Every generation stage reads them, so the copy and the tone come out of the brand rather than out of the model's defaults, and every generated image is produced against the brand's visual direction rather than to a generic prompt.
A brand here is a design system and a creative brief in one row. The theme half decides what a page looks like. The brief half decides what the platform writes and draws when nobody is watching.
One brand or many
The schema allows a project to hold many named brands, and any app can point at whichever one it wants. An agency could run a client's main site on one brand and a sub-brand campaign on another, in the same project.
That is switched off. Today a project has one brand and every app in it reads that brand, and the difference between the two is a settings page nobody can reach. The plumbing underneath is unchanged, and turning it on is a decision about whether the flexibility is worth the extra thing a customer has to understand. Early on it is not.
What it does not cover yet
The object is a working design system and stops short of a full brand standard. It covers colour, typography, logo, component styling and the creative direction for content and imagery.
A brand book covers more. Letter kerning, the finer spacing rules, print specifications, the usage policy saying where the logo may and may not go. None of that is in the object today, and it is where the object grows. Every rule that moves into it is a rule the platform can hold on a customer's behalf without the customer being a designer.
What the agency stops doing
An agency puts a client's brand into one row and stops policing consistency. Forty clients become forty rows, each read by that client's every surface, each changeable in one place. The never-finished job of keeping brands from drifting becomes setting the object once and keeping it current.
Building something like this
I'm Jesse. I build platforms end to end, and I'm open to work. If this is the kind of engineering you need, get in touch.