Kolor
DraftSemantic-only
Dział zatytułowany „Semantic-only”Komponenty i strony nigdy nie odwołują się do koloru wprost (#1E5A8C,
hsl(...)) ani do warstwy core/brand tokenów (--color-gray-500). Jedyny
dozwolony interfejs to rola semantyczna: color.background.page,
color.text.primary, color.brand.primary… Rola mówi, DO CZEGO kolor służy
— sama wartość zmienia się pod spodem zależnie od marki i trybu, a kod
komponentu nie wie (i nie musi wiedzieć), jaka to dziś wartość.
Jak używać
Dział zatytułowany „Jak używać”Ta sama rola, trzy miejsca użycia:
/* zmienna prosto z tokens.css */.card { background: var(--color-background-raised); color: var(--color-text-primary);}// klasa narzędziowa Tailwind — ta sama wartość co var() wyżej<div className="bg-background-raised text-text-primary">…</div>// ścieżka tokenu w tokens/dist/tokens.json (nazwa = klucz)tokens["color.background.raised"]// → cssVar: "--color-background-raised"// → value: "#FFFFFF" (insurance.light)// → values["insurance.dark"]: "#4A5361"Reguła: używamy WYŁĄCZNIE ról semantycznych (color.<kategoria>.<rola>).
Ramp bazowa (navy-500, blue-600…) nie istnieje jako publiczny kontrakt —
nie pojawia się w kodzie ui//docs/ pod żadną postacią.
Tabela ról
Dział zatytułowany „Tabela ról”Próbka pokazuje wartość roli w marce insurance (lewy kwadrat = light, prawy
= dark) — pełną macierz wszystkich pięciu marek pokazuje sekcja niżej.
| Podgląd | Rola (token) | Zmienna CSS | Klasa Tailwind | Hex — light | Hex — dark |
|---|---|---|---|---|---|
color.background.page | --color-background-page | bg-background-page | #F8F9FB | #0B1326 | |
color.background.surface | --color-background-surface | bg-background-surface | #FFFFFF | #1C2430 | |
color.background.raised | --color-background-raised | bg-background-raised | #FFFFFF | #4A5361 | |
color.background.inverse | --color-background-inverse | bg-background-inverse | #0B1326 | #FFFFFF | |
color.text.primary | --color-text-primary | text-text-primary | #1C2430 | #F8F9FB | |
color.text.secondary | --color-text-secondary | text-text-secondary | #4A5361 | #D2D8E2 | |
color.text.muted | --color-text-muted | text-text-muted | #667080 | #AEB6C2 | |
color.text.inverse | --color-text-inverse | text-text-inverse | #FFFFFF | #0B1326 | |
color.text.on-brand | --color-text-on-brand | text-text-on-brand | #FFFFFF | #FFFFFF | |
color.text.link | --color-text-link | text-text-link | #274A74 | #9FB8D6 | |
color.brand.primary | --color-brand-primary | bg-brand-primary | #355F92 | #355F92 | |
color.brand.hover | --color-brand-hover | bg-brand-hover | #274A74 | #274A74 | |
color.brand.active | --color-brand-active | bg-brand-active | #1A3556 | #1A3556 | |
color.brand.subtle | --color-brand-subtle | bg-brand-subtle | #E3ECF5 | #1A3556 | |
color.brand.on-subtle | --color-brand-on-subtle | text-brand-on-subtle | #1A3556 | #C5D6E8 | |
color.accent.default | --color-accent-default | bg-accent-default | #3183A4 | #3183A4 | |
color.accent.subtle | --color-accent-subtle | bg-accent-subtle | #DCF4F2 | #184D68 | |
color.border.default | --color-border-default | border-border-default | #D2D8E2 | #667080 | |
color.border.strong | --color-border-strong | border-border-strong | #667080 | #AEB6C2 | |
color.border.focus | --color-border-focus | border-border-focus | #355F92 | #9FB8D6 | |
color.status.success.bg | --color-status-success-bg | bg-status-success-bg | #F5F9F7 | #F5F9F7 | |
color.status.success.fg | --color-status-success-fg | text-status-success-fg | #0E7D36 | #0E7D36 | |
color.status.warning.bg | --color-status-warning-bg | bg-status-warning-bg | #FAF8F5 | #FAF8F5 | |
color.status.warning.fg | --color-status-warning-fg | text-status-warning-fg | #966106 | #966106 | |
color.status.danger.bg | --color-status-danger-bg | bg-status-danger-bg | #FAF5F5 | #FAF5F5 | |
color.status.danger.fg | --color-status-danger-fg | text-status-danger-fg | #D81212 | #D81212 | |
color.status.danger.surface | --color-status-danger-surface | bg-status-danger-surface | #D81212 | #D81212 | |
color.status.danger.on-surface | --color-status-danger-on-surface | text-status-danger-on-surface | #FFFFFF | #FFFFFF | |
color.status.danger.hover | --color-status-danger-hover | bg-status-danger-hover | #AD0E0E | #AD0E0E | |
color.status.danger.text | --color-status-danger-text | text-status-danger-text | #D81212 | #F15656 | |
color.status.info.bg | --color-status-info-bg | bg-status-info-bg | #F2F5F8 | #F2F5F8 | |
color.status.info.fg | --color-status-info-fg | text-status-info-fg | #1E62AE | #1E62AE |
Macierz marka × tryb
Dział zatytułowany „Macierz marka × tryb”data-brand (insurance/home/travel/health/moto) × data-theme (light/dark)
na <html> — 10 kombinacji. Tryb ciemny nie jest osobną paletą — to
przemapowanie tych samych ról na inne wartości (np. background.page z
jasnoszarego na granatowy), więc komponent napisany raz działa identycznie
w obu trybach. Zobacz komponent na żywo w dowolnej marce/trybie: dowolna
strona /preview/* (np. przy komponencie Button) ma własny przełącznik
marki/trybu w pasku narzędzi.
color.background.pagecolor.background.surfacecolor.background.raisedcolor.background.inversecolor.text.primarycolor.text.secondarycolor.text.mutedcolor.text.on-brandcolor.brand.primarycolor.brand.hovercolor.brand.activecolor.brand.subtlecolor.accent.defaultcolor.accent.subtlecolor.border.defaultcolor.border.strongcolor.status.success.fgcolor.status.warning.fgcolor.status.danger.fgcolor.status.info.fgKontrast by construction
Dział zatytułowany „Kontrast by construction”Każda para tekst/tło zdefiniowana w warstwie semantycznej przechodzi WCAG 2.2
AA (4.5:1 dla tekstu, 3:1 dla obrysu/focus) w każdej z 10 kombinacji —
sprawdza to tokens/check.mjs przy każdym buildzie tokenów, nie ręczna
kontrola na oko. Gdy odcień marki nie przechodzi progu, poprawka wchodzi w
tokens/src/brands/*.tokens.json — nigdy w próg wewnątrz check.mjs.
Konsekwencja dla komponentów: nie zestawiaj ról z różnych „rodzin”
dowolnie (np. color.text.on-brand na color.background.page) — role są
projektowane w zamierzonych parach (np. text.on-brand ↔ brand.primary
jako tło). Nowa para to decyzja do tokenów, nie do lokalnego CSS.
Paleta marek
Dział zatytułowany „Paleta marek”Nazwy ramp 1:1 z Figmą:
| Marka | Ramp primary | Ramp accent |
|---|---|---|
insurance |
blue |
turquoise (jedyny nazwany akcent — pozostałe pochodne) |
home |
red |
pochodny z primary |
health |
teal |
pochodny z primary |
moto |
violet |
pochodny z primary |
travel |
sky |
pochodny z primary |
@todo(S-GRAFIK): nazwany akcent dla home/health/moto/travel — dziś wyprowadzony automatycznie z ramp primary (
@todo(accent-grafik)wtokens/src/brands/*.tokens.json).
Neutralna rampa (color.background.*, color.text.*, color.border.*) to
navy: navy-50 = tło jasne, navy-800 = tekst, navy-900 = tło ciemne. Kolor
marki (color.brand.primary, tło CTA) wskazuje stop rampy primary oznaczony
jako „button-primary” — nie jest to ten sam numer stopnia w każdej marce
(600 dla insurance/home, 700 dla health/moto/travel); mapowanie żyje w
brands/*.tokens.json (sekcja role), żeby nazwy i wartości stopni zostały
1:1 z Figmą mimo tej niejednorodności.