Brand derivation (applyBrand)

Turn a handful of brand choices — one color, two fonts, a radius feel — into a complete, accessible theme with a single pure function.

Most projects don't design a token system — they have a logo color and a font. applyBrand(theme, brand) (shipped in @flexa/core, built on the FDS token model) derives everything else deterministically.

import { defaultTheme } from 'flexa-design-system';
import { applyBrand } from '@flexa/core';

const theme = applyBrand(defaultTheme(), {
  primaryColor: '#0f766e',
  headingFont: '"Fraunces", serif',
  bodyFont: '"Inter", sans-serif',
  radius: 'lg',
});

What gets derived

Brand fieldTokens re-pointedDerivation
primaryColorcolor.primary + hover/active + on-primary + focus ringHover/active darken toward black; on-primary picks white or black by max contrast
secondaryColorthe color.secondary familySame derivation as primary
headingFont / bodyFontfont.family-heading / font.family-baseVerbatim stacks
radiusthe whole radius.* scale5 presets: none / sm / md / lg / xl
fontScalethe whole ref.font-size.* rampModular scale from base × ratio (9 steps)
densitythe whole ref.space.* rampMultiplier 0.8–1.2 (compact ↔ airy)
containerWidthsize.container-lgVerbatim CSS length

Why a function and not a config file

Because it's pure and total: same brand in, same theme out, on any runtime — build scripts, the browser (this site's playground runs it live), or a server. An empty brand returns the theme untouched, so it composes safely.

Derivation is also where accessibility lives: you can pick any primary, but on-primary is computed, and checkThemeContrast tells you immediately if your mid-tone choice can't carry readable text.

Scales, not values

Note that fontScale and density re-point primitive ramps, not individual tokens. Because every semantic size aliases into those ramps, one multiplier restyles the whole system consistently — there is no way to make h3 bigger than h2 by accident.