Semantic Colors
Purpose-driven tokens. Each one resolves via the current .brand-<name> scope (and, orthogonally, .dark). Components consume the semantic name — never the brand primitive — so multi-brand theming is a single-class toggle.
Source of truth: tokens/src/semantic/semantic.json plus per-brand overrides in tokens/src/brand/*.json.
Background · brand
bg.brand
Primary brand fill (buttons, headers)
--color-bg-brandbg.brand-subtle
Light brand tint (cards, highlights)
--color-bg-brand-subtlebg.brand-strong
Deep brand (hero, dark UI)
--color-bg-brand-strongBackground · accent + secondary
bg.accent
Accent fills (CTAs, badges)
--color-bg-accentbg.accent-subtle
Light accent tint
--color-bg-accent-subtlebg.secondary
Secondary actions
--color-bg-secondarybg.secondary-subtle
Light secondary tint
--color-bg-secondary-subtleBackground · glass
bg.glass-dark
Glass fill on dark backgrounds (brand-neutral)
--color-bg-glass-darkbg.glass-light
Glass fill on light backgrounds (brand-neutral)
--color-bg-glass-lightText
text.primary
Body text
--color-text-primarytext.secondary
Muted/captions
--color-text-secondarytext.tertiary
Hint text (AA-safe)
--color-text-tertiarytext.brand
Brand-coloured text on light bg
--color-text-brandtext.accent
Accent-coloured text (TpEMIS only today)
--color-text-accenttext.on-brand
Text on brand-coloured bg
--color-text-on-brandtext.on-accent
Text on accent-coloured bg
--color-text-on-accenttext.on-glass
Text on glass surfaces (dark bg)
--color-text-on-glassSurface
surface
Default page / card surface
--color-surfacesurface-raised
Elevated surface (modal, dropdown)
--color-surface-raisedsurface-secondary
Subdued surface
--color-surface-secondarybackground
Page background
--color-backgroundBorder
border
Default border
--color-borderborder-subtle
Subtle dividers
--color-border-subtleborder-brand
Brand-tinted border
--color-border-brandborder-glass-dark
Glass border on dark (neutral)
--color-border-glass-darkborder-glass-light
Glass border on light (brand-tinted rgba)
--color-border-glass-lightInteractive
interactive.hover
Hover state for brand-fill buttons
--color-interactive-hoverinteractive.pressed
Pressed state
--color-interactive-pressedinteractive.focus
Focus ring colour
--color-interactive-focusinteractive.disabled
Disabled state (brand-invariant)
--color-interactive-disabledShadows
Per-brand entries retint via rgba(primary, alpha) overrides.
shadow.glass
Card shadow on dark glass (neutral)
--shadow-glassshadow.glass-light
Card shadow on light glass (brand-tinted)
--shadow-glass-lightshadow.brand-glow
Primary-CTA glow (brand-tinted rgba)
--shadow-brand-glowBlurs
Brand-invariant. Applied via backdrop-filter: blur().
blur.glass-standard
--blur-glass-standardDefault glass blur (16px)
blur.glass-subtle
--blur-glass-subtleSmall-surface blur (8px)
blur.glass-heavy
--blur-glass-heavyHero-overlay blur (24px)
State colors
Brand-invariant. Same values across all brands.
--color-state-success--color-state-warning--color-state-error--color-state-infoUsage rule
Always consume tokens (var(--color-accent), bg-accent), never primitive ramp entries (var(--color-navy-900)). The former re-themes automatically when the brand class flips; the latter freezes a component to TpGROUP's navy.