liquiddesign

Design system

Jedno źródło prawdy dla designu i kodu

Cała platforma jest zbudowana z tokenów i komponentów opisanych na tej stronie. Te same nazwy działają w Figmie, w kodzie i w rozmowie zespołu, więc przekazanie projektu nie wymaga tłumaczenia.

Kolory

Trzy rodziny: ink buduje tła i głębię, mist odpowiada za tekst, a glow, pulse, ok i danger niosą znaczenie. Komponent nigdy nie używa wartości hex wprost.

ink-950

Tło strony

ink-900

Tło paneli i kart

ink-700

Obramowania, szkielety

mist-50

Nagłówki, tekst główny

mist-300

Tekst akapitów

mist-500

Tekst pomocniczy

glow-400

Akcent, akcje główne

pulse-400

Akcent wtórny

ok-400

Sukces

danger-400

Błędy, destrukcja

Skala typograficzna

Siedem nazwanych kroków opartych o clamp(), kalibrowanych do ekranów referencyjnych: minimum każdego kroku przypada na 390 px, maksimum na 1440 px. Zwęż okno przeglądarki, a każdy wiersz poniżej płynnie zmaleje razem z resztą platformy.

Płynie, nie skacze

text-fluid-xs

Metki, podpisy, kod

Płynie, nie skacze

text-fluid-sm

Tekst pomocniczy, listy

Płynie, nie skacze

text-fluid-base

Akapity

Płynie, nie skacze

text-fluid-lg

Wyróżnione akapity, lead

Płynie, nie skacze

text-fluid-xl

Tytuły sekcji i kart

Płynie, nie skacze

text-fluid-2xl

Nagłówki stron drugorzędnych

Płynie, nie skacze

text-fluid-3xl

Nagłówki główne

Skala odstępów

Odstępy dostają tę samą dyscyplinę co tekst: jeden token clamp() zamiast pary klas z progiem, kalibrowany między 390 a 1440 px. Paski poniżej mają szerokość swojego tokenu, więc rosną razem z oknem.

p-fluid-2xs

4 → 8 px

Najmniejszy rytm, odstęp ikon

p-fluid-xs

16 → 20 px

Padding kart w demo

p-fluid-sm

20 → 24 px

Padding paneli i ramek demo

p-fluid-md

24 → 32 px

Padding dużych kart

p-fluid-lg

48 → 64 px

Pion podstron

p-fluid-xl

56 → 80 px

Pion stopki

p-fluid-2xl

64 → 96 px

Pion sekcji strony głównej

px-gutter

16 → 24 px

Marginesy strony, nie krok skali

Konfiguracja Tailwinda

Tak, to Tailwind, ale nie w domyślnym ustawieniu. W wersji 4 nie ma już pliku tailwind.config.js: konfiguracją jest blok @theme w globals.css. Ten sam plik czyta zespół i agent AI, więc nie ma drugiego źródła prawdy.

Domyślną drabinę pięciu breakpointów czyści --breakpoint-*: initial. W jej miejscu stoją trzy progi w rem, więc reagują na ustawienie rozmiaru tekstu w przeglądarce. xl i 2xl nie wróciły, bo żaden widok ich nie potrzebował.

Rozmiary pochodzą z tokenów, nie z progów. Dlatego cały arkusz stylów zamyka się w ośmiu blokach @media z progiem szerokości, a te pilnują wyłącznie struktury całej strony. Przełączniki w środku komponentów przeszły na container queries: sześć progów, każdy równy minimalnej szerokości treści, którą przełącza.

  1. 01

    Token płynny

    Rozmiar tekstu, padding i marginesy strony biorą clamp() z tokenu. Wartość rośnie z każdym pikselem szerokości, więc nie ma martwej strefy, w której layout jest już ciasny, a skala jeszcze duża.

    text-fluid-lg, p-fluid-md, px-gutter

  2. 02

    Container query

    Komponent pyta swój kontener, nie ekran, więc działa w każdym miejscu, do którego go przeniesiesz. Tak przełącza się tu tabela w listę kart: liczy się szerokość panelu, nie szerokość okna.

    @container, @[40rem]:block, cqi

  3. 03

    Siatka, która sama liczy kolumny

    Liczba kolumn wynika z dostępnego miejsca i minimalnej szerokości karty, nie z listy progów. Jedna klasa obsługuje zegarek i monitor, a treść nigdy nie ląduje w kolumnie węższej niż czytelna.

    grid-auto-sm, grid-auto-md, grid-auto-xl

  4. 04

    Breakpoint

    Ostatni szczebel i tylko dla struktury całej strony: pozioma nawigacja w menu pełnoekranowe, asymetryczny layout lekcji, sidebar checklisty. Nigdy dla rozmiaru tekstu ani rytmu odstępów. Przełącznik w środku komponentu należy do szczebla 02.

    lg:flex, lg:grid-cols-[2fr_3fr], md:grid-cols-2

Cała konfiguracja mieszka w @theme, obok siebie dla designu i kodu
@import "tailwindcss";

@theme {
  --breakpoint-*: initial;
  --breakpoint-sm: 40rem;
  --breakpoint-md: 48rem;
  --breakpoint-lg: 64rem;

  --color-glow-400: #45e3cb;
  --text-fluid-base: clamp(1rem, 0.93rem + 0.29vw, 1.1875rem);
  --text-fluid-base--line-height: 1.65;
  --spacing-fluid-md: clamp(1.5rem, 1.31rem + 0.76vw, 2rem);
  --spacing-gutter: clamp(1rem, 0.81rem + 0.76vw, 1.5rem);
}
Tak wygląda skalowanie na progach: cztery rozmiary jednej karty
<article className="p-4 text-sm sm:p-5 sm:text-base lg:p-8">
  <h2 className="text-lg sm:text-xl lg:text-3xl">{title}</h2>
</article>
Ta sama karta na tokenach: dwie klasy, płynne przejście
<article className="p-fluid-md text-fluid-base">
  <h2 className="text-fluid-2xl">{title}</h2>
</article>

Komponenty

Każdy komponent ma wbudowane zachowania z zasad platformy: rezerwację miejsca na błędy, stałe wymiary w stanie ładowania i płynną typografię. Używasz go i dobre nawyki przychodzą same.

Przyciski

Włącz stan ładowania i zmierz przyciski wzrokiem. Spinner zastępuje etykietę w tej samej komórce siatki, więc wymiary nie drgną.

Pola formularza

Slot na błąd jest wbudowany w komponent, więc żaden formularz w projekcie nie może o nim zapomnieć.

Adres musi zawierać znak @.

Statusy

Pięć odcieni wystarcza na cały cykl życia projektu. Nowe kolory dodajemy do tokenów, nigdy do pojedynczego komponentu.

SzkicW tokuReviewGotoweZablokowane
Użycie komponentów w dowolnym widoku platformy
import { Button } from "@/components/ui/Button";
import { Input } from "@/components/ui/Input";
import { Badge } from "@/components/ui/Badge";

<Input label="Adres e-mail" error={errors.email} />
<Button loading={submitting}>Zapisz zmiany</Button>
<Badge tone="ok">Gotowe</Badge>