Architektura
System studia projektowego i konwencje UI
DataFlow AI Platform prezentuje rozbudowany, bogaty w funkcje produkt ETL — projektowanie potoków danych, monitorowanie, zarządzanie, migrację i administrację — poprzez jeden spójny system wizualny. Ta strona dokumentuje język projektowy: model tokenów semantycznych, ciemny motyw amber/zinc, powłokę adaptującą się do person, współdzieloną bibliotekę komponentów oraz konwencje dostępności i responsywności, których przestrzega każdy ekran.
Zasady projektowe
Interfejs jest zbudowany z myślą o inżynierach danych telekomunikacyjnych, analitykach, administratorach i opiekunach danych pracujących przez długie sesje na gęstych ekranach operacyjnych. Cztery zasady kształtują każdą decyzję dotyczącą komponentów.
| Zasada | Co oznacza w praktyce |
|---|---|
| Semantyczne, nie dosłowne | Komponenty odwołują się do klas tokenów (bg-surface-1, text-heading) zamiast surowych kolorów, więc zmiana motywu nigdy nie dotyka kodu komponentów. |
| Najpierw ciemny | Domyślnym motywem jest ciemny; jasny jest w pełni wspieraną alternatywą. Oba wynikają z tego samego zestawu tokenów. |
| Adaptacja do persony | Powłoka — głównie pasek boczny — pokazuje tylko funkcje istotne dla aktywnej persony. |
| Podzielony kod i odporność | Każda strona jest ładowana leniwie i opakowana w granicę błędu; awaria jednego ekranu nigdy nie psuje powłoki. |
Model tokenów
Stylizacja korzysta z Tailwind CSS 4, podłączonego przez @tailwindcss/vite. Platforma nie rozsiewa wartości heksadecymalnych po komponentach. Zamiast tego definiuje warstwę semantycznych tokenów projektowych — nazwanych ról takich jak „surface" czy „heading" — a komponenty korzystają wyłącznie z nich.
Tokeny powierzchni
Powierzchnie są warstwowe. Powierzchnie o wyższych numerach znajdują się wizualnie bliżej użytkownika i są używane dla wyniesionych elementów, takich jak karty, panele i okna modalne.
| Klasa tokenu | Rola |
|---|---|
bg-surface-0 | Tło strony — najgłębsza warstwa |
bg-surface-1 | Karty, panele, pasek boczny |
bg-surface-2 | Wyniesione elementy — popovery, okna modalne, listy rozwijane |
Tokeny tekstu
Tokeny tekstu wyrażają hierarchię, a nie kolor. Nagłówek to text-heading niezależnie od motywu.
| Klasa tokenu | Rola |
|---|---|
text-heading | Tytuły stron i sekcji |
text-body | Główny tekst do czytania |
text-secondary | Tekst pomocniczy, etykiety |
text-muted | Tekst odznaczony, podpowiedzi, placeholdery |
Obramowanie i akcent
| Klasa tokenu | Rola |
|---|---|
border-primary | Domyślne separatory i kontury komponentów |
amber-500 | Akcent marki — akcje główne, aktywna nawigacja, podświetlenia fokusu |
SURFACE LAYERING (dark theme)
┌─ bg-surface-0 (page) ────────────────────────────────┐
│ │
│ ┌─ bg-surface-1 (card / panel) ─────────────────┐ │
│ │ text-heading Pipeline summary │ │
│ │ text-body 14 runs in the last 24 hours │ │
│ │ text-muted last updated 2 minutes ago │ │
│ │ ┌──────────────┐ │ │
│ │ │ bg-surface-2 │ │ │
│ │ │ (popover) │ │ │
│ │ └──────────────┘ │ │
│ │ [ amber-500 primary action ] │ │
│ └─────────────────────────────────────────────────┘ │
└───────────────────────────────────────────────────────┘
Dlaczego tokeny semantyczne
Ponieważ komponenty odwołują się do klas tokenów, a nie do dosłownych kolorów, przełączanie między motywem ciemnym i jasnym — lub późniejsza korekta palety — jest zmianą na poziomie warstwy tokenów. Żaden plik komponentu nie jest edytowany.
Referencja palety kolorów
Za tokenami semantycznymi kryje się konkretna paleta. Platforma jest produktem nastawionym na motyw ciemny, a kanonicznym akcentem jest złoty/bursztynowy #ffd200. Poniższe tabele podają dosłowne wartości, do których rozwiązywany jest każdy token.
Motyw ciemny — tła
| Rola | Hex | Tailwind | Zastosowanie |
|---|---|---|---|
| Bazowe | #09090b | zinc-950 | Główne tło strony — najgłębsza warstwa |
| Powierzchnia | #0c0c0f | własny | Przemienne tło sekcji, karty |
| Wyniesione | #18181b | zinc-900 | Pasek boczny, panele, okna modalne |
| Nakładka | rgba(255,255,255,0.03) | white/3 | Subtelne nakładki kart |
| Nakładka przy najechaniu | rgba(255,255,255,0.05) | white/5 | Stan najechania na kartę |
| Nakładka aktywna | rgba(255,255,255,0.06) | white/6 | Stan aktywny / wybrany |
Motyw ciemny — tekst
| Rola | Hex | Tailwind | Zastosowanie |
|---|---|---|---|
| Główny | #ffffff | white | Nagłówki, wyróżnienia |
| Drugorzędny | #f1f5f9 | slate-100 | Tekst główny |
| Stłumiony | #d1d5dc | gray-300 | Etykiety drugorzędne |
| Subtelny | #6a7282 | gray-500 | Placeholdery, podpowiedzi |
| Wyłączony | #4a5565 | gray-600 | Stan wyłączony |
Motyw ciemny — obramowania
| Rola | Hex | Tailwind | Zastosowanie |
|---|---|---|---|
| Domyślne | rgba(255,255,255,0.08) | white/8 | Obramowania kart, separatory |
| Subtelne | rgba(255,255,255,0.06) | white/6 | Subtelne separatory |
| Mocne | rgba(255,255,255,0.15) | white/15 | Obramowanie przycisku drugorzędnego |
Akcent — główny (złoty/bursztynowy)
| Rola | Hex | Zastosowanie |
|---|---|---|
| Akcent główny | #ffd200 | Główny kolor marki, CTA |
| Akcent główny przy najechaniu | #e6bd00 | Stan najechania |
| Tekst na akcencie głównym | #101828 | Tekst na tle akcentowym |
Akcent — paleta semantyczna
Akcent bursztynowy jest zarezerwowany dla akcji i marki. Znaczenie statusu i kategorii przekazuje stała paleta semantyczna.
| Kolor | Hex | Tailwind | Zastosowanie |
|---|---|---|---|
| Szmaragdowy | #10b981 | emerald-500 | Sukces, online, zdrowy |
| Niebieski | #3b82f6 | blue-500 | Informacja, linki, akcje drugorzędne |
| Cyjan | #06b6d4 | cyan-500 | Dane, metryki |
| Fioletowy | #8b5cf6 | violet-500 | Funkcje AI, specjalne |
| Purpurowy | #c084fc | purple-400 | Kreatywne, projektowe |
| Bursztynowy | #f59e0b | amber-500 | Ostrzeżenia |
| Czerwony | #ef4444 | red-500 | Błędy, destrukcyjne, krytyczne |
| Pomarańczowy | #f97316 | orange-500 | Uwaga, alerty |
| Różowy | #ec4899 | pink-500 | Wyróżnienia |
Ciemny motyw amber/zinc
Charakterystyczny wygląd to ciemny motyw amber/zinc: głębokie neutralne powierzchnie zinc niosące ciepły akcent bursztynowy. Zinc nadaje ekranom przeznaczonym na długie sesje bazę o niskim olśnieniu i niskim zmęczeniu; bursztyn (amber-500) oznacza nieliczne rzeczy, na które użytkownik powinien zareagować — przyciski główne, aktywny element nawigacji, pierścienie fokusu i kluczowe podświetlenia statusu.
Motyw ten jest domyślny. Jest kanonicznym wyrazem języka projektowego; motyw jasny to ten sam zestaw tokenów przemapowany dla jasnych środowisk.
| Motyw | Powierzchnie bazowe | Akcent | Domyślny |
|---|---|---|---|
| Ciemny | Neutralne tony zinc, od głębokich do wyniesionych | Bursztynowy (amber-500) | Tak |
| Jasny | Jasne tony neutralne, takie samo warstwowanie | Bursztynowy (amber-500) | Nie |
Motywy jasny i ciemny
Stan motywu jest własnością magazynu Zustand themeStore, utrwalanego w localStorage pod kluczem dataflow-theme. Jego wartość to 'dark' | 'light', domyślnie 'dark'.
Mechanizm to pojedyncze przełączanie klasy. Gdy motyw się zmienia, magazyn ustawia lub usuwa klasę dark na document.documentElement (<html>). Tailwind CSS 4 rozwiązuje każdy token semantyczny względem tej klasy, więc jedno przełączenie klasy zmienia motyw całej aplikacji.
themeStore.theme ──────────────► <html class="dark">
│ │
persisted to Tailwind 4 resolves
localStorage every semantic token
'dataflow-theme' against the class
│ │
restored on load components re-render
with no code change
App.tsx odczytuje theme z useThemeStore przy montowaniu i natychmiast synchronizuje klasę <html>, więc poprawny motyw jest stosowany przed pierwszym renderowaniem i nie ma migotania niewłaściwego motywu.
Mapowanie motywu
Ta sama rola semantyczna rozwiązuje się do innej konkretnej wartości w zależności od motywu. Akcent i CTA pozostają stałe — przemapowywane są tylko tony neutralne.
| Element | Tryb ciemny | Tryb jasny |
|---|---|---|
| Tło strony | #09090b (zinc-950) | #f8fafc (slate-50) |
| Powierzchnia | #0c0c0f | #ffffff |
| Pasek boczny | #18181b (zinc-900) | #ffffff |
| Tekst główny | #ffffff | #101828 |
| Tekst drugorzędny | #d1d5dc (gray-300) | #4a5565 (gray-600) |
| Tekst stłumiony | #6a7282 (gray-500) | #6a7282 (gray-500) |
| Obramowanie | white/8 | gray-200 (#e5e7eb) |
| Akcent | #ffd200 | #ffd200 |
| Przycisk CTA | Złoty gradient | Złoty gradient |
| Tekst CTA | #101828 | #101828 |
Powłoka adaptująca się do person
Aplikacja działa wewnątrz jednej trwałej powłoki — components/shell/AppShell.tsx — a powłoka ta adaptuje się do aktywnej persony. Istnieją cztery persony: engineer, analyst, admin i steward.
Jak persony są rozwiązywane
W produkcji persona jest wyprowadzana z ról Keycloak za pośrednictwem ROLE_PERSONA_MAP w auth/keycloak.ts. W trybie deweloperskim pochodzi z personaStore (activePersona, domyślnie engineer, utrwalana pod dataflow-persona).
Jak powłoka się adaptuje
Model nawigacji paska bocznego znajduje się w data/navigation.ts jako navigationItems. Każdy element deklaruje id, label, icon (nazwę ikony lucide), path, listę widoczności personas[] oraz opcjonalne children[]. Pasek boczny filtruje elementy według activePersona i dodatkowo uwzględnia flagę funkcji MIGRATION_CENTER_ENABLED z config/env.ts.
ENGINEER persona ANALYST persona ADMIN persona
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ ▸ Home │ │ ▸ Home │ │ ▸ Home │
│ ▸ Design │ │ ▸ Data │ │ ▸ Monitor │
│ Studio │ │ Browser │ │ ▸ Governance │
│ ▸ Monitor │ │ ▸ Monitor │ │ ▸ Migration │
│ ▸ My │ │ ▸ Marketplace│ │ ▸ Admin (6) │
│ Pipelines │ │ ▸ Templates │ │ ─ Users │
│ ▸ Connections│ │ │ │ ─ Security │
└──────────────┘ └──────────────┘ └──────────────┘
navigationItems filtered by activePersona + MIGRATION_CENTER_ENABLED flag
Poza filtrowaniem, ProtectedRoute egzekwuje dostęp persony dla każdej trasy: oblicza effectivePersona i wywołuje canAccess(persona, pathname) z data/permissions. Jeśli persona dotrze do ścieżki, której nie powinna widzieć, zamiast strony renderowany jest <AccessDenied />. Współdzielony prymityw UI PermissionGate pozwala pokazywać lub ukrywać poszczególne elementy sterujące — przyciski, akcje menu — według uprawnień w obrębie strony, która w innym przypadku jest widoczna.
Konwencje biblioteki komponentów
Komponenty są zorganizowane według obszaru funkcjonalnego w components/, z jednym współdzielonym, niezależnym od motywu zestawem UI w components/ui/.
Zestaw UI
Folder ui/ zawiera około czterdzieści prymitywów prezentacyjnych. Są one jedynym miejscem, gdzie podejmowane są decyzje o kolorze i odstępach; komponenty funkcjonalne je komponują.
| Kategoria | Prymitywy |
|---|---|
| Wyświetlanie danych | DataTable, DataGrid, Timeline, Accordion, TreeView, CodeBlock, Badge, Avatar |
| Formularze | Input, Select, Checkbox, Radio, Switch, Textarea, FileInput |
| Nawigacja | Tabs, Pagination, Breadcrumbs |
| Informacja zwrotna | Skeleton, EmptyState, AlertBanner, ProgressBar, Toast / ToastProvider, Popover, Tooltip |
| Wykresy | LineChart, BarChart, GaugeChart |
| Układ | Stack, Show, ResponsiveGrid, Divider, List |
| Dostęp | SkipNav, PermissionGate |
Foldery funkcjonalne — design-studio/, monitor/, governance/, admin/, migration/, ai-copilot/, data-browser/, pipelines/, connections/ — budują komponenty specyficzne dla ekranów na bazie zestawu.
Tabele
Tabele o dużym wolumenie — uruchomienia potoków danych, wiersze katalogu, dzienniki audytu — są zbudowane na @tanstack/react-table 8 i wirtualizowane za pomocą @tanstack/react-virtual 3, więc tabela z tysiącami wierszy renderuje tylko widoczne okno.
Powierzchnie grafów i kodu
W produkcie pojawiają się dwie wyspecjalizowane powierzchnie:
- Grafy przepływu korzystają z
@xyflow/react12 (React Flow) — kanwa potoku danych w Studiu Projektowym oraz graf pochodzenia danych w zarządzaniu. - Edycja kodu korzysta z
@monaco-editor/react4 dla definicji potoków danych w YAML oraz SQL.
Typografia
Platforma używa jednej rodziny bezszeryfowej dla tekstu UI i rodziny o stałej szerokości dla kodu, SQL i YAML.
/* UI text */
font-family: Inter, system-ui, -apple-system, sans-serif;
/* Code, SQL, pipeline YAML */
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
Skala typograficzna
| Poziom | Rozmiar | Grubość | Wysokość wiersza | Odstęp między literami | Zastosowanie |
|---|---|---|---|---|---|
| Display | 72px | 700 | 1.1 | -1.8px | Nagłówki hero |
| H1 | 48px | 700 | 1.0 | -0.5px | Nagłówki stron |
| H2 | 36px | 700 | 1.1 | normalny | Nagłówki sekcji |
| H3 | 24px | 600 | 1.3 | normalny | Nagłówki kart |
| H4 | 20px | 600 | 1.4 | normalny | Nagłówki podsekcji |
| Body Large | 18px | 400 | 1.6 | normalny | Akapity wiodące |
| Body | 16px | 400 | 1.5 | normalny | Domyślny tekst główny |
| Body Small | 14px | 400 | 1.5 | normalny | Opisy |
| Caption | 12px | 500 | 1.4 | normalny | Etykiety, metadane |
| Micro | 11px | 500 | 1.3 | 0.5px | Plakietki, tagi |
| Tiny | 10px | 600 | 1.2 | 0.5px | Etykiety nadkreślone |
Grubości fontu
| Grubość | Wartość | Zastosowanie |
|---|---|---|
| Regular | 400 | Tekst główny |
| Medium | 500 | Etykiety, podpisy |
| Semibold | 600 | Przyciski, podnagłówki |
| Bold | 700 | Nagłówki |
| Extrabold | 800 | Metryki wyświetlane |
Skala odstępów
Odstępy są zgodne z jednostką bazową Tailwind wynoszącą 4px. Komponenty czerpią ze stałego zestawu kroków zamiast z dowolnych wartości.
| Token | Wartość | Zastosowanie |
|---|---|---|
space-1 | 4px | Ciasne przerwy |
space-2 | 8px | Domyślna przerwa |
space-3 | 12px | Wypełnienie karty (kompaktowe) |
space-4 | 16px | Przerwa sekcji |
space-6 | 24px | Wypełnienie sekcji, standardowe wypełnienie karty |
space-8 | 32px | Duże odstępy sekcji |
space-12 | 48px | Sekcje strony |
space-16 | 64px | Główne sekcje |
Promień obramowania
| Token | Wartość | Zastosowanie |
|---|---|---|
rounded-sm | 6px | Tagi, małe plakietki |
rounded | 8px | Przyciski, pola wejściowe, małe karty |
rounded-md | 12px | Karty, panele |
rounded-lg | 16px | Duże karty, okna modalne |
rounded-full | 9999px | Pigułki, awatary, plakietki |
Cienie
| Token | Wartość | Zastosowanie |
|---|---|---|
shadow-sm | 0 1px 2px rgba(0,0,0,0.05) | Subtelne uniesienie |
shadow-md | 0 4px 6px -1px rgba(0,0,0,0.1) | Karty |
shadow-lg | 0 10px 15px -3px rgba(0,0,0,0.1) | Wyniesione karty, przyciski |
shadow-xl | 0 20px 25px -5px rgba(0,0,0,0.1) | Okna modalne, listy rozwijane |
shadow-2xl | 0 25px 50px -12px rgba(0,0,0,0.25) | Elementy hero |
shadow-glow | 0 0 20px rgba(255,210,0,0.15) | Złota poświata akcentu |
Przyciski i stany interakcji
Przyciski występują w trzech wagach — złote główne CTA, drugorzędne typu ghost oraz czerwone destrukcyjne — w rozmiarze standardowym i dużym.
/* Primary CTA — standard */
background: linear-gradient(to right, #ffd200, #d4a00a);
color: #101828;
font-weight: 600;
font-size: 14px;
padding: 8px 16px;
border-radius: 8px;
/* Primary CTA — large */
font-size: 16px;
padding: 16px 32px;
border-radius: 12px;
/* Secondary (ghost) */
background: transparent;
color: #d1d5dc;
border: 0.8px solid rgba(255,255,255,0.15);
/* Destructive */
background: #ef4444;
color: #ffffff;
Stany interakcji
Każdy interaktywny prymityw rozwiązuje te same cztery stany, więc przycisk, wiersz i element nawigacji reagują spójnie.
| Stan | Efekt |
|---|---|
| Najechanie | Rozjaśnienie o 10%, skala 1.02 |
| Aktywny | Przyciemnienie o 5%, skala 0.98 |
| Wyłączony | Przezroczystość 0.5, kursor not-allowed |
| Fokus | Pierścień 2px, amber-500/50 — akcent bursztynowy pełni jednocześnie rolę podświetlenia fokusu |
Gradienty
/* Gold text gradient — headlines */
background: linear-gradient(to right, #ffd200, #e6b800, #cc9e00);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
/* Gold button gradient */
background: linear-gradient(to right, #ffd200 0%, #d4a00a 50%, #b8860b 100%);
/* Subtle gold glow — background accent */
background: radial-gradient(rgba(255,210,0,0.08) 0%, transparent 60%);
Wzorce komponentów
Prymitywy zestawu UI są zbudowane z powyższych tokenów. Poniższe powracające wzorce definiują, jak karta, element nawigacji, plakietka, pole wejściowe, tabela i pasek kart wyglądają w motywie ciemnym.
| Wzorzec | Specyfikacja |
|---|---|
| Karta | bg white/3, border 1px white/8, promień 12px, wypełnienie 24px; najechanie → bg white/5, border white/12 |
| Element nawigacji paska bocznego | Domyślnie text-gray-400; najechanie text-white na bg white/5; aktywny text-amber-400 na bg amber-500/10 z border-l-2 border-amber-500 |
| Plakietka / tag | bg {color}-500/10, text {color}-400, border 1px {color}-500/20, promień 6px, wypełnienie 2px 8px, 11px medium |
| Pole wejściowe | bg white/5, border 1px white/10, promień 8px, biały tekst, placeholder gray-500; fokus → border amber-500/50, pierścień 2px amber-500/20 |
| Tabela | Nagłówek bg white/3, tekst nagłówka gray-400 wielkie litery 11px tracking-wider; obramowanie wiersza white/5, najechanie na wiersz white/3; tekst komórki gray-300 (dane) / biały (główny) |
| Pasek kart | Domyślnie text-gray-400 z border-b-2 border-transparent; najechanie text-gray-200 / border-gray-600; aktywny text-amber-400 / border-amber-500 |
Ikonografia
- Biblioteka — Lucide React. Ikoną logo marki jest glif
Workflowz Lucide. - Grubość kreski — domyślnie 1.5px.
- Rozmiary — mały 16px (
h-4 w-4, w linii z tekstem); domyślny 20px (h-5 w-5, nawigacja i przyciski); duży 24px (h-6 w-6, ikony funkcji). - Kolor — ikony dziedziczą kolor otaczającego tekstu, więc zmieniają motyw wraz z resztą UI.
Animacja i przejścia
Ruch jest powściągliwy i spójny. Każda klasa interakcji ma stały czas trwania i wygładzenie.
| Właściwość | Czas trwania | Wygładzenie |
|---|---|---|
| Przejścia kolorów | 150ms | ease |
| Tło | 200ms | ease-in-out |
| Transformacja (najechanie) | 200ms | ease-out |
| Otwarcie okna modalnego | 300ms | ease-out |
| Przełączenie paska bocznego | 300ms | ease-in-out |
| Spinner | 1000ms | linear (nieskończony) |
Punkty przełamań responsywnych
Układ jest rozwiązywany względem pięciu standardowych punktów przełamań Tailwind.
| Punkt przełamania | Szerokość | Zastosowanie |
|---|---|---|
sm | 640px | Telefon poziomo |
md | 768px | Tablet |
lg | 1024px | Pulpit |
xl | 1280px | Szeroki pulpit |
2xl | 1536px | Bardzo szeroki |
Prymitywy układu
Strony są montowane z niewielkiego zestawu prymitywów układu, tak aby odstępy, nagłówki stron i widoki dzielone wyglądały identycznie wszędzie.
| Prymityw | Folder | Rola |
|---|---|---|
PageContainer | layout/ | Standardowe opakowanie strony ze spójnym wypełnieniem i maksymalną szerokością |
PageHeader | layout/ | Tytuł, opis i obszar akcji na górze strony |
SplitPane | layout/ | Zmienne rozmiarem układy dwupanelowe (np. lista plus szczegóły) |
Sama powłoka dostarcza trwałą ramę: Sidebar, TopBar, ujście <main id="main-content"> oraz wyzwalacz i pasek boczny AI Copilot. Treść główna jest przesunięta o effectiveMargin, który śledzi bieżącą szerokość paska bocznego (zwinięty 60px, rozwinięty 240px).
Dostępność
Dostępność jest wbudowana w powłokę i zestaw UI, a nie doczepiana do każdej strony osobno.
- Pomiń nawigację. Powłoka renderuje link pomijający do
#main-content; prymitywSkipNavgo standaryzuje.<main>niesie celid="main-content". - Powierzchnia poleceń klawiaturowych. Wyszukiwanie globalne otwiera się skrótem
Ctrl/Cmd+Kpoprzez obsługę naciśnięcia klawisza w powłoce; paleta poleceń jest zbudowana nacmdk. HakuseKeyboardShortcutstandaryzuje pozostałe skróty. - Widoczność fokusu. Akcent bursztynowy pełni jednocześnie rolę podświetlenia fokusu, więc fokus klawiatury jest zawsze wyraźnie widoczny na powierzchniach zinc.
- Renderowanie świadome uprawnień.
PermissionGateiProtectedRoutezapewniają, że użytkownicy nie zobaczą — i nie mogą wejść tabulatorem do — elementów sterujących lub tras, z których nie mogą korzystać. - Stany ładowania i puste.
SkeletoniEmptyStatenadają każdej powierzchni asynchronicznej zdefiniowany, przyjazny dla czytników ekranu stan, zamiast pustego obszaru.
Odporny domyślnie
Każda strona jest opakowana w ErrorBoundary (wewnątrz SuspenseWrap), a panele używają PanelErrorFallback. Użytkownik zawsze widzi możliwą do odzyskania powierzchnię błędu, nigdy pusty ekran, gdy coś zawiedzie.
Zachowanie responsywne
Układ adaptuje się do trzech klas punktów przełamań, obliczanych przez useIsMobile, useIsTablet i useSidebarState z hooks/useResponsive (ze wspierającymi hakami useMediaQuery i useBreakpoint).
| Punkt przełamania | Nawigacja | Uwagi |
|---|---|---|
| Pulpit | Pełny pasek boczny, zwijany 60px ⇄ 240px | Treść główna przesunięta o effectiveMargin |
| Tablet | Zwinięty pasek boczny z rozwijaniem przy najechaniu | Kompaktowa chrom, te same trasy |
| Telefon | Nakładka MobileMenu + MobileBottomNav | Pasek boczny ukryty; dolna nawigacja dla głównych celów |
DESKTOP TABLET MOBILE
┌────┬────────────┐ ┌──┬──────────────┐ ┌──────────────┐
│side│ content │ │░░│ content │ │ TopBar │
│bar │ │ │ho│ │ ├──────────────┤
│240 │ │ │ve│ │ │ │
│px │ │ │r │ │ │ content │
│ │ │ │60│ │ │ │
│ │ │ │px│ │ ├──────────────┤
└────┴────────────┘ └──┴──────────────┘ │ ▣ ▣ ▣ ▣ nav │
└──────────────┘
Prymitywy układu ResponsiveGrid, Stack i Show pozwalają komponentom funkcjonalnym przepływać bez dedykowanego CSS z zapytaniami medialnymi, utrzymując zachowanie responsywne spójne z systemem projektowym zamiast improwizowane na każdej stronie.
Podsumowanie
System projektowy DataFlow AI opiera się na jednej idei stosowanej konsekwentnie: komponenty opisują role, a nie piksele. Semantyczne tokeny Tailwind 4 niosą znaczenie powierzchni, tekstu, obramowania i akcentu; ciemny motyw amber/zinc jest domyślnym wyrazem tych tokenów, a jasny to ten sam zestaw przemapowany; pojedyncze przełączenie klasy dark zmienia motyw wszystkiego; powłoka adaptuje się do aktywnej persony; czterdziestoelementowy zestaw UI i garść prymitywów układu utrzymują każdy ekran spójnym; a dostępność oraz zachowanie responsywne są podłączone do powłoki, tak że każda strona dziedziczy je za darmo.