Przejdź do treści

Kolor

Zamknięta, generowana paleta w OKLCH. Dwanaście stopni na każdy odcień, jedno zadanie na stopień i kontrast, który wynika z obliczeń — nie z nadziei.

System kolorów prfct jest celowo mały. Nie ma tu blue-500, po który można by sięgnąć, ani kodu hex do wklejenia. Każdy kolor w produkcie pochodzi z 12-stopniowej skali, a każdy stopień istnieje po to, żeby wykonywać jedno konkretne zadanie. Wybierz zadanie, a stopień wybierze się sam.

Podgląd wdrożeniaGotowe
x

Zasady

Domyślnie monochromatycznie. Powierzchnie, tekst i główne akcje są neutralne. Na spokojnym płótnie nieliczne kolorowe elementy mogą nieść znaczenie, zamiast walczyć o uwagę.

Kolor to sygnał, nie dekoracja. prfct używa barwy tylko do trzech zadań:

  • Marka oznacza stan i zaznaczenie: zaznaczone pola wyboru, włączone przełączniki, postęp, pierścienie fokusu, linki.
  • Statusy komunikują wyniki: sukces, ostrzeżenie, błąd i informację.
  • Odcienie kategorialne rozróżniają serie na wykresach oraz tagi — nigdy nie niosą znaczenia.

Nigdy sam kolor. Każdy stan oznaczony kolorem jest też oznaczony kształtem, ikoną albo tekstem, więc pozostaje czytelny przy zaburzeniach widzenia barw, w wydruku w skali szarości i w trybie wymuszonych kolorów (WCAG 1.4.1).

Skale

prfct ma dziesięć skal: neutralną gray, skalę marki brand, którą dostosujesz w motywie, cztery odcienie statusów i cztery odcienie kategorialne. Poniżej oba tryby, wyrenderowane z tego samego arkusza stylów.

123456789101112
gray
brand
red
amber
green
blue
orange
teal
violet
pink
123456789101112
gray
brand
red
amber
green
blue
orange
teal
violet
pink

Kliknij dowolną próbkę, aby skopiować jej token. Oba tryby są renderowane na żywo z tego samego CSS — każdy panel to po prostu poddrzewo z klasą .light lub .dark.

Skale są generowane w OKLCH — percepcyjnie jednorodnej przestrzeni barw, w której równe przyrosty jasności wyglądają na równe w każdym odcieniu. Dlatego bursztyn ostrzeżenia i błękit informacji na tym samym stopniu mają tę samą wagę wizualną — a tego HSL nie potrafi.

Anatomia skali

Każdy z dwunastu stopni ma jedną rolę. Komponenty nigdy nie dobierają stopni na oko — wybierają je według roli.

1
2
3
4
5
6
7
8
9
10
11
12
Tła
1 · 2
Płótno aplikacji i subtelne powierzchnie, takie jak paski boczne, wnęki i paskowane wiersze.
Wypełnienia komponentów
3 · 4 · 5
Wypełnienia elementów interaktywnych: spoczynkowe, po najechaniu oraz wciśnięte lub zaznaczone.
Obramowania
6 · 7 · 8
Subtelne separatory, domyślne obramowania komponentów oraz obramowania mocne lub po najechaniu.
Wypełnienia pełne
9 · 10
Najczystszy wyraz barwy — wypełnione przyciski, odznaki, wskaźniki — i jej stan po najechaniu.
Tekst
11 · 12
Tekst o niższym kontraście (≥ 4,5:1 na każdym wypełnieniu, stopnie 1–5) i tekst o wysokim kontraście (≥ 11:1).
StopnieRolaTypowe klasy
1–2Tło aplikacji i subtelne tłabg-gray-1, bg-brand-2
3–5Wypełnienia komponentów — spoczynkowe, po najechaniu, wciśniętebg-gray-3 hover:bg-gray-4 active:bg-gray-5
6–8Obramowania — subtelne, domyślne, mocneborder-gray-6, hover:border-gray-8
9–10Wypełnienia pełne i ich stan po najechaniubg-brand-9 hover:bg-brand-10
11Tekst o niższym kontraście, ikony, linki — AA na stopniach 1–5text-brand-11
12Tekst o wysokim kontraścietext-gray-12

Tokeny semantyczne

Przez większość czasu stopni skali w ogóle nie dotkniesz. Tokeny semantyczne nazywają przeznaczenie koloru i w każdym trybie wskazują na konkretny stopień. Ich nazwy trzymają się konwencji shadcn/ui — background, primary, muted-foreground — dzięki czemu każdy komponent zgodny z shadcn działa z prfct bez zmian.

Powierzchnie

Płótno strony.

whitegray-1

Zagłębione obszary, które obramowują treść: paski boczne, wnęki, kod.

gray-1gray-1

Wyniesione powierzchnie: karty, panele, kafelki.

whitegray-2

Powierzchnie pływające: menu, popovery, podpowiedzi, okna dialogowe.

whitegray-2

Domyślny tekst i ikony.

gray-12gray-12

Akcje

Jedna, najważniejsza akcja. Domyślnie monochromatyczna.

gray-12gray-12

Akcje pomocnicze i ciche wypełnienia.

gray-3gray-3

Wyciszone wypełnienia: ścieżki, szkielety, szyny zakładek.

gray-3gray-3

Wypełnienie najechania i wyróżnienia elementów list i menu.

gray-3gray-4

Tekst drugorzędny, opisy, placeholdery. Spełnia 4,5:1.

gray-11gray-11

Marka

Kolor marki. Zaznaczenie, postęp, stany zaznaczone, akcent.

brand-9brand-9

Linki w tekście.

brand-11brand-11

Podświetlenie zaznaczonego tekstu.

brand-5brand-6

Wskaźnik fokusu klawiatury. Spełnia 3:1 na każdej powierzchni.

brand-9brand-10

Status

Akcje nieodwracalne i błędy. Wypełnienia używają `danger-9`, tekst — `danger-11`.

red-9red-10

Pozytywne wyniki.

green-9green-9

Ostrzeżenie. Zawsze z ciemnym tekstem.

amber-9amber-9

Neutralna informacja.

blue-9blue-9

Linie

Obramowania strukturalne: karty, separatory, tabele. Dekoracyjne.

gray-6gray-6

Podkreślona struktura i obrysy po najechaniu.

gray-7gray-7

Granice kontrolek formularzy. Spełnia 3:1 względem strony (WCAG 1.4.11).

gray-9gray-9

Przyciemnienie za powierzchniami modalnymi.

gray-12 @ 32%black @ 60%

Dane

Seria 1.

brand-9brand-10

Seria 2.

teal-9teal-9

Seria 3.

violet-9violet-10

Seria 4.

orange-9orange-9

Seria 5.

pink-9pink-10
// Reach for semantic tokens first…
<p className="text-muted-foreground">Last edited 2 hours ago</p>

// …and scale steps when you're building a component that needs a specific role.
<span className="bg-brand-3 text-brand-11">Beta</span>

Marka

Znakiem rozpoznawczym prfct jest ultramaryna — głęboki, nasycony niebieski inspirowany błękitem Kleina (International Klein Blue). Używamy jej oszczędnie, żeby nie traciła znaczenia: tam, gdzie ją widzisz, coś jest zaznaczone, aktywne albo ma fokus.

Skalę marki możesz dowolnie dostosować. Zmień jej odcień i nasycenie w kreatorze motywów, a wszystkie dwanaście stopni wygeneruje się na nowo — razem z gwarancjami kontrastu — podczas gdy kolory statusów zostaną na swoim miejscu. Dzięki temu sukces nigdy nie przybierze koloru twojej marki.

Kolory statusów

Odcienie statusów mają aliasy semantyczne, dzięki czemu komponenty mówią, co się stało, a nie jakim kolorem to namalować:

danger-1…12Alias skali red
warning-1…12Alias skali amber
success-1…12Alias skali green
info-1…12Alias skali blue
Wdrożonosuccess-2 · 6 · 9 · 11 · 12
Obniżona wydajnośćwarning-2 · 6 · 9 · 11 · 12
Niepowodzeniedanger-2 · 6 · 9 · 11 · 12
W kolejceinfo-2 · 6 · 9 · 11 · 12

Wszędzie stosuj ten sam przepis: stopień 2 na tło, 6 na obramowanie, 9 na pełne wypełnienie (z -contrast jako kolorem tekstu), 11 na tekst i ikony, 12 na tytuł na zabarwionym tle. Trzymają się go alerty, odznaki, powiadomienia i błędy w formularzach.

Płatność nieudana
Dobrze.Tekst statusu używa stopnia 11, który ma wyliczony kontrast AA na zabarwionych tłach własnej skali.
Płatność nieudana
Źle.Pełny stopień 9 jako kolor tekstu nie ma wystarczającego kontrastu na zabarwionych tłach, zwłaszcza w trybie ciemnym.

Kontrast

W prfct kontrast jest cechą palety, a nie etapem przeglądu. Kiedy skala powstaje, jej stopnie tekstu są wyliczane numerycznie względem jej wypełnień:

  • Stopień 11 osiąga co najmniej 4,5:1 na każdym wypełnieniu własnej skali — na stopniach od 1 do 5, łącznie ze stanami najechania i wciśnięcia — co odpowiada poziomowi AA w WCAG 2.2 dla tekstu podstawowego. W trybie ciemnym osiąga też 5:1 na stopniu 3, bo przez halację cienki jasny tekst na ciemnym tle czyta się trudniej.
  • Stopień 12 osiąga co najmniej 11:1 na stopniu 3.
  • Każde wypełnienie pełne (stopień 9) ma kolor tekstu -contrast, który spełnia 4,5:1: biały, gdzie to możliwe, a ciemny odcień tej samej barwy tam, gdzie biały nie wystarcza (bursztyn i pomarańcz).
  • Granice kontrolek formularzy używają tokenu input, który spełnia 3:1 względem strony zgodnie z WCAG 1.4.11 — to element, który większość design systemów po cichu pomija.

Poniższa macierz jest liczona z wygenerowanej palety podczas budowania. Gdyby jakakolwiek zmiana naruszyła gwarancję, pokazałaby to tabela — i testy.

Skala11 na 111 na 211 na 311 na 411 na 512 na 3Kontrast na 9
gray5,86AA5,65AA5,31AA4,97AA4,63AA15,0Lc 965,38AA
gray9,32AA8,81AA8,17AA7,53AA6,88AA14,8Lc 965,28AA
brand6,27AA6,05AA5,70AA5,32AA4,87AA11,7Lc 916,07AA
brand8,08AA7,65AA6,67AA5,88AA5,05AA12,1Lc 875,20AA
red6,00AA5,78AA5,44AA5,05AA4,60AA11,9Lc 914,93AA
red7,70AA7,32AA6,43AA5,69AA4,91AA12,1Lc 864,93AA
amber5,93AA5,73AA5,41AA5,04AA4,60AA11,7Lc 919,66AA
amber8,02AA7,60AA6,58AA5,74AA4,92AA12,0Lc 869,66AA
green5,82AA5,64AA5,33AA5,00AA4,60AA11,3Lc 914,74AA
green8,51AA8,04AA6,87AA5,91AA5,01AA12,0Lc 874,74AA
blue5,89AA5,70AA5,38AA5,02AA4,60AA11,6Lc 914,70AA
blue8,20AA7,76AA6,71AA5,85AA5,00AA12,0Lc 874,70AA
orange5,98AA5,77AA5,43AA5,05AA4,60AA11,8Lc 915,56AA
orange7,82AA7,42AA6,50AA5,71AA4,92AA12,1Lc 865,56AA
teal5,84AA5,65AA5,34AA5,01AA4,60AA11,4Lc 914,60AA
teal8,43AA7,97AA6,81AA5,87AA4,99AA12,0Lc 874,60AA
violet5,97AA5,76AA5,42AA5,05AA4,60AA11,9Lc 925,72AA
violet7,83AA7,43AA6,52AA5,76AA4,97AA12,1Lc 865,72AA
pink6,03AA5,81AA5,46AA5,07AA4,60AA11,9Lc 914,67AA
pink7,69AA7,30AA6,42AA5,68AA4,91AA12,1Lc 864,67AA
Zwiększony kontrast
Gdy system operacyjny prosi o większy kontrast (prefers-contrast: more), prfct automatycznie wzmacnia obramowania, granice kontrolek i tekst drugorzędny. W trybie dużego kontrastu w Windows (forced-colors: active) komponenty oddają pierwszeństwo kolorom systemowym, a pierścienie fokusu pozostają widoczne, bo są rysowane obrysem, a nie cieniem.

Tryb ciemny

Tryb ciemny to nie odwrócenie kolorów. Każda skala jest generowana dwukrotnie, z osobnymi krzywymi jasności i nasycenia: ciemne tła są prawie czarne, a nie czysto czarne, żeby uniknąć smużenia na ekranach OLED; zabarwione stopnie mają większe nasycenie, żeby przy niskiej jasności wciąż było w nich widać kolor; a stopnie tekstu są wyliczane względem ciemnych wypełnień. Powierzchnie zyskują elewację, stając się jaśniejsze, a nie rzucając cieni, których nikt nie zobaczy.

Dowolne poddrzewo może przełączyć tryb przez dodanie klasy — to przydatne w podglądach, osadzonych panelach i sekcjach marketingowych:

<section className="dark"></section>   {/* dark, even on a light page */}
<section className="light"></section>  {/* light, even on a dark page */}

Reguły

mutedbrand-3/11
Dobrze.Tokeny semantyczne i stopnie skali — paleta pozostaje spójna i gotowa na zmianę motywu.
#6366f1
Źle.Surowe kody hex i wartości arbitralne psują tryb ciemny, motywy i gwarancje kontrastu.
  • Nie polegaj na samym kolorze. Łącz kolory statusów z ikoną albo tekstem.
  • Nie wymyślaj stopni. Jeśli wydaje się, że brakuje jakiegoś koloru, najpewniej któraś rola jest używana niezgodnie z przeznaczeniem — wróć do tabeli powyżej.
  • Nie przekolorowuj komponentów przez className. Użyj wariantu albo dodaj nowy do komponentu, żeby ta decyzja była wspólna.

Dla programistów

Paleta to dane. Skale są opisane kilkoma liczbami w lib/tokens/palette.ts i generowane przez lib/color/scale.ts; pnpm tokens zapisuje styles/tokens.css oraz JSON w formacie DTCG dla narzędzi projektowych. Domyślna paleta Tailwinda jest usunięta, więc przypadkowe bg-blue-500 po prostu nie istnieje, zamiast po cichu odbiegać od systemu.

lib/tokens/palette.ts
export const huePresets = {
  ultramarine: { hue: 267, chroma: 0.24, lightness: 0.515, darkLightness: 0.55 },
  // …
}