Tokeny i zależności
Techniczny: DraftAkceptacja: ApprovedToken to nazwana decyzja wyglądu: kolor, odstęp, promień, poziom skali
typograficznej, czas animacji. Komponent pyta o rolę (color.brand.primary),
nie o konkretny odcień. Dzięki temu ta sama linia kodu wygląda inaczej
w pięciu markach i dwóch trybach, a sam kod się nie zmienia.
Konsument widzi jedną warstwę
Dział zatytułowany „Konsument widzi jedną warstwę”Jedynym kontraktem jest warstwa semantyczna: --color-*, --spacing-*,
--radius-*, --font-*, --shadow-*, --size-*, --border-width-*,
--breakpoint-*, --focus-ring, --motion-*. Komponenty
w ui/ i strony styleguide’u używają wyłącznie jej.
<button className="bg-action-primary text-text-on-action rounded-md">Przejdź do wyceny</button>// Klasa z domyślnej palety Tailwinda i literał. Żadne z nich nie przełączy się// z data-brand, nawet jeśli dziś trafia w kolor marki.<button className="bg-blue-600">Przejdź do wyceny</button><button style={{ background: "#4A78AD" }}>Przejdź do wyceny</button>Pierwszej z tych dwóch linii nie da się już skompilować. dist/theme.css
gasi domyślny motyw Tailwinda w tych przestrzeniach nazw, w których zbiór
tokenów jest całym zbiorem systemu — kolory, typografia, odstępy, promienie,
cienie, kontenery i progi układu. bg-blue-600, font-medium, gap-4,
max-w-md i wariant 2xl: nie mają po tym żadnej wartości do wzięcia, więc
Tailwind nie generuje dla nich klasy. Zostają dwa słowa kluczowe CSS:
transparent i currentColor — nie są wartością marki i w tokenach
odpowiednika nie mają. Drugą linię, literał w atrybucie style, zatrzymuje
bramka no-hardcoded.
Warstwy core, brand i mode są wewnętrzne. Nie mają zmiennych CSS,
nie stanowią publicznego kontraktu i zmieniają się bez ostrzeżenia. Jedyny
wyjątek to namespace --motion-*, opisany niżej.
Od roli do wartości
Dział zatytułowany „Od roli do wartości”Cztery warstwy, jedna droga. Przykład: tło przycisku primary.
| Warstwa | Co trzyma | W tym przykładzie |
|---|---|---|
core | prymitywy wspólne dla wszystkich marek: skala odstępów, promienie, skala typograficzna, rampa navy, statusy, ruch | w tym przykładzie nie bierze udziału, bo stopnie rampy marki trzyma warstwa brand |
brand | paletę jednej marki | brand.role.buttonPrimary wskazuje brand.primary.700 — ten sam stopień w każdej z pięciu marek |
mode | przemapowanie ról na tryb jasny albo ciemny | tło przycisku nie zależy od trybu, więc mode go nie dotyka; dotyka np. background.page (navy-50 w light, navy-900 w dark) |
semantic | rolę, o którą pyta komponent | color.action.primary = {brand.role.buttonPrimary} → --color-action-primary |
Stopień znaczy w każdej marce to samo: tło przycisku głównego stoi na 700,
stan hover na 800, active na 900 — wszędzie. Numeru stopnia i tak nie
wpisujesz nigdzie; pytasz o color.action.primary.
| Podgląd | Rola (token) | Zmienna CSS | Klasa Tailwind | Hex — light | Hex — dark |
|---|---|---|---|---|---|
color.brand.primary | --color-brand-primary | bg-brand-primary | #4A78AD | #4A78AD | |
color.action.primary | --color-action-primary | bg-action-primary | #274A74 | #274A74 | |
color.action.hover | --color-action-hover | bg-action-hover | #1A3556 | #1A3556 | |
color.action.active | --color-action-active | bg-action-active | #10243D | #10243D | |
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 |
Pięć marek, dwa tryby
Dział zatytułowany „Pięć marek, dwa tryby”Markę i tryb ustawiasz dwoma atrybutami na <html>:
<html data-brand="travel" data-theme="dark">data-brand:insurance,home,health,motoalbotravel;data-theme:lightalbodark.
Pięć marek razy dwa tryby daje 10 kombinacji. Nazwy ról są w każdej te same,
zmieniają się wartości. Bez atrybutów strona dostaje insurance i light.
Tryb ciemny nie jest drugą paletą, tylko innym przemapowaniem tych samych ról.
Marka różnicuje dziś wyłącznie kolor: brand.*, action.*, accent.*,
text.link, border.focus i focus.ring. Odstępy, promienie, typografia,
cienie i ruch są wspólne dla wszystkich pięciu.
insurance.lightinsurance.darkhome.lighthome.darkhealth.lighthealth.darkmoto.lightmoto.darktravel.lighttravel.darkStrony styleguide’u nie ustawiają data-brand. Dokumentacja żyje na stałej,
neutralnej palecie. Komponent w konkretnej marce i trybie oglądasz na stronach
/preview/*, które mają własny przełącznik.
Jak konsumować
Dział zatytułowany „Jak konsumować”.card { background: var(--color-background-surface); padding: var(--spacing-stack-lg); border-radius: var(--radius-lg);}<div className="bg-background-surface p-stack-lg rounded-lg">…</div>// tokens/dist/tokens.json — nazwa tokenu jest kluczem mapy `tokens`data.tokens["color.brand.primary"].cssVar // "--color-brand-primary"data.tokens["color.brand.primary"].values["health.dark"]Build wydaje sześć artefaktów w tokens/dist/: css/tokens.css (zmienne do
importu), tokens.json (płaska mapa z wartością w każdej z 10 kombinacji),
theme.css (rejestracja w Tailwind v4), type-scale.css (klasy text-<rola>)
i type-scale.json (ta sama skala jako dane). Szósty plik, palette.json,
pokazuje pełne rampy na stronie koloru i podaje
barwy narzędziom (generator znaku, walidator literałów). Nie jest interfejsem
dla kodu produktu. Nazw nie zgadujemy, czytamy je
z tokens.json. Mechanika budowania:
README paczki — źródło w repo: packages/design/tokens/README.md.
Tokeny ruchu
Dział zatytułowany „Tokeny ruchu”core.motion.* jest stałe: nie zależy ani od marki, ani od trybu, więc trafia
do dist/ bezpośrednio, pod własnym prefiksem --motion-*. To jedyny wyjątek
od reguły „nigdy core”.
| Token | Zmienna CSS | Wartość | Podgląd |
|---|---|---|---|
core.motion.duration.slow | --motion-duration-slow | 320ms | |
core.motion.duration.base | --motion-duration-base | 200ms | |
core.motion.duration.fast | --motion-duration-fast | 120ms | |
core.motion.easing.accelerate | --motion-easing-accelerate | cubic-bezier(0.4, 0, 1, 1) | |
core.motion.easing.decelerate | --motion-easing-decelerate | cubic-bezier(0, 0, 0.2, 1) | |
core.motion.easing.standard | --motion-easing-standard | cubic-bezier(0.4, 0, 0.2, 1) |
Kiedy którego czasu i krzywej użyć, opisuje Ruch i reduced motion.
Jak dodać albo zmienić token
Dział zatytułowany „Jak dodać albo zmienić token”Kolejność jest stała: źródło → build → bramka → strona.
- Źródło. Wybierz warstwę. Nowy prymityw wspólny dla marek idzie do
core.tokens.json, wartość jednej marki dobrands/<marka>.tokens.json, różnica między trybami domodes/{light,dark}.tokens.json, nowa rola dla komponentów dosemantic.tokens.json. Wartości są statyczne i commitowane. - Build.
pnpm -F @polisoteka/design-tokens buildprzelicza wszystkie 10 kombinacji naraz. Token bez wartości w którejkolwiek z nich nie przejdzie. - Bramka.
pnpm -F @polisoteka/design-tokens check:tokenssprawdza kompletność i kontrast par, które realnie renderują komponenty. Nową parę tekst/tło dopisujesz do listy par zanim jej użyjesz, nie po pierwszym audycie. - Strona. Rola widoczna w dokumentacji ma trafić do tabeli na właściwej
stronie fundamentów, a nie do prozy. Tabele czytają
tokens.json, więc same podążają za wartością.
Gdy kontrast nie przechodzi, korygujesz odcień w tokens/src. Progu w bramce
nie obniżasz.
Granice
Dział zatytułowany „Granice”- Komponent nie sięga do
core,brandanimode. Wyjątkiem jest--motion-*. - W komponentach i na stronach nie ma literałów: ani hex, ani
rgb(), ani pikseli odstępu, ani nazw krojów spozafont.family.*. tokens/dist/jest wynikiem budowania. Ręczna poprawka tam znika przy najbliższym przebiegu.- Nowy token powstaje dla roli, która powtarza się w systemie. Jedno miejsce użycia to znak, że rola już istnieje pod inną nazwą.
- Marka nie rozgałęzia kodu komponentu. Różnicę między portalami niesie wartość tokenu, nie warunek w JSX.
Weryfikacja
Dział zatytułowany „Weryfikacja”Token działa, gdy:
buildicheckkończą się zielono, a token ma wartość w każdej z 10 kombinacji wdist/tokens.json;- komponent zmienia wygląd po przestawieniu
data-brandidata-theme, bez zmiany w kodzie komponentu; - bramka
pnpm design:checkprzechodzi, łącznie z kontrolą literałów w zbudowanym styleguide; - nowa para tekst/tło ma wpis w liście par bramki kontrastu.
Kontrakt obszaru — źródło w repo: packages/design/AGENTS.md,
README paczki tokenów — źródło w repo: packages/design/tokens/README.md,
bramka kontrastu — źródło w repo: packages/design/tokens/src/artifact.ts,
Kolor, Typografia,
Odstępy i rytm,
Standard dostępności.