Foundations

Every city, its own colour

The accent is the only saturated colour on a screen, and it belongs to the city the player is in. One contract paints it everywhere: the hub, the game and the web site.

The same UI, every city

Each card overrides the three accent tokens for its own subtree with accentStyleVars. Nothing else changes — every *-primary and text-brand utility follows.
Los Santos#FAB432

Şehre gir

Açık
Janti#FE004F

Şehre gir

Açık
Toolbar pick#FAB432

Şehre gir

Açık

The contract

Three properties, written together or not at all.

--primary

The accent itself.

--primary-foreground

Black or white, whichever has the higher contrast on the accent. Writing a new --primary without it can leave labels invisible.

--primary-hover

Ten lightness points down, hue untouched.

--ring and --brand-text are never written by an app. The preset reads them as var(--ring, var(--primary)), so they follow the nearest accent; a light theme may set a darker --brand-text for text on white.

The contrast gate

Measured against the NUI’s background, #09090b, where the accent appears nearly everywhere. The hub-gateway refuses anything under 3 : 1 (WCAG non-text contrast) on save; between 3 and 4.5 it accepts with a warning. Pick a custom colour in the toolbar and read the verdict here.
#FAB432
Good · 4.5 : 1+
Contrast on #09090b11.03 : 1
Refused below3 : 1
Warned below4.5 : 1
--primary-foreground#000000
--primary-hover#f3a006

accentStyleCss('#fab432')

html:root {
  --primary:39 95.2% 58.8%;
  --primary-foreground:0 0% 0%;
  --primary-hover:39 95.2% 48.8%
}

Painting it

The package’s accent module is pure and dependency-free: it runs in the browser, in Bun, in the gateway and in the NUI.
client — whole document
import { applyAccent } from '@fastrp/design-tokens/accent';

// Inline on <html>; an unusable colour removes the
// properties, so the stylesheet default shows.
applyAccent(city.accentColor);
server render — no yellow flash
import { accentStyleCss } from '@fastrp/design-tokens/accent';

const css = accentStyleCss(city.accentColor);
// <style>{css}</style> in <head>
one subtree
import { accentStyleVars } from '@fastrp/design-tokens/accent';

<div style={accentStyleVars(other.accentColor) as CSSProperties}>
  …
</div>
a form that edits it
import { accentVerdict } from '@fastrp/design-tokens/accent';

accentVerdict('#fe004f'); // 'good' | 'low' | 'refused' | 'invalid'