§ brand
Identyfikacja
wizualna.
Marka, kolory i typografia Zebrania.edu.pl — system projektowy „A". Wklej ten adres agentowi AI, aby strony, prezentacje i grafiki pozostały spójne z serwisem.
§ 01 zasady
Zasady projektowe
Pięć reguł rozstrzygających każdy kompromis. Sprawdź je, zanim dodasz kolor, cień lub nowy komponent.
Jasno domyślnie, ciepłe neutralne
Płótno to ciepła biel, nigdy czyste #fff ani #000. Tryb ciemny jest pochodną tokenów przez light-dark() — nie osobnym projektem. Sekcje czytelne, gęste informacyjnie, bez ciemnych „momentów marki".
Mech na akcent, oliwka na przycisk
Akcent jest rozdzielony wg roli: mech (#82b842) barwi linki, chipy i stany aktywne; wypełnienie CTA to osobna, głęboka oliwka (#4f7a12) z białym tekstem. Średnie zielenie leżą w martwej strefie kontrastu — ani czarny, ani biały tekst na nich nie czyta się dobrze.
Minimalizm narzędziowy
Cienkie obramowania 1px plus subtelny cień wyniesienia — nie albo-albo. Promień 6px. Jedna obramowana powierzchnia na grupę treści; karty nie zagnieżdżają się w kartach.
Space Grotesk na wystawie, Geist w pracy
Nagłówki niosą Space Grotesk. Tekst i interfejs — Geist. Kody, adresy i identyfikatory — Geist Mono. Żaden inny krój nie wchodzi do systemu.
Status osobno od akcentu
Sukces, błąd i ostrzeżenie mają własne tokeny semantyczne — zieleń statusu to inna zieleń niż mech marki. Akcent nigdy nie udaje komunikatu o stanie.
§ 02 neutralne
Płótno, powierzchnie i tekst
Neutralne są ciepłe — nigdy czyste #fff/#000. Każdy token deklaruje parę light-dark(); motyw ciemny to te same tokeny, nie osobna paleta.
§ 03 akcent
Mech i oliwka — akcent rozdzielony wg roli
Mech barwi tinty i tekst; wypełnienie CTA to osobna, głęboka oliwka z białym tekstem. Ten rozdział istnieje, bo na średniej zieleni ani czarny, ani biały tekst nie osiąga 4.5:1.
§ 04 typografia
Space Grotesk na wystawie, Geist w pracy
Trzy kroje, trzy role. Nagłówki — Space Grotesk. Tekst i interfejs — Geist. Kody klas, adresy i identyfikatory — Geist Mono.
display · Space Grotesk
Aa Bb 123
body · Geist
Aa Bb 123
mono · Geist Mono
Aa Bb 123
§ 05 komponenty
Wzorce komponentów
Wzory używane w całym serwisie. Kopiuj je dosłownie — nie wymyślaj nowych afordancji dla znanych zadań.
znak marki — zebra
16px
24px
32px
64px
on fill
lockup
Jeden znak na każdej powierzchni: favicon, nawigacja serwisu, powłoka aplikacji, strona pomocy, drukowany plakat dołączenia i og-image (GH-2419). To jeden plik /favicon.svg, utrzymywany bajtowo identycznie w apps/www, apps/web i apps/help, bo te trzy aplikacje budują się niezależnie — zmieniasz jeden, zmieniasz wszystkie trzy. Siatka slotów z sekcji hero jest motywem produktu, nie znakiem marki, i nigdy go nie zastępuje. Znak pochodzi z zebry Noto Emoji (Apache-2.0), z viewBox obciętym do grafiki, żeby całe zwierzę wypełniało kadr przy 16px.
przyciski — komponent Button
Warianty nazwane kodowo: primary (oliwkowe CTA), secondary (obrys), ghost (bez tła), danger (obrys destrukcyjny), danger-fill (pełne destrukcyjne CTA), success. Skala sm/md/lg + stany loading/disabled/fullWidth. Renderowane realnym komponentem Button — bliźniaczym z aplikacją (ADR-104), te same tokeny i klasy.
ikony — komponent Icon + registry
Nazwy to intencje (co ikona znaczy), nie kształty — podmiana glifu to jedna linijka w registry.ts, nigdy w miejscach użycia (GH-2006). Ikony dziedziczą kolor przez currentColor i rozmiar przez font-size. Bliźniacze z aplikacją (ADR-104).
chipy i odznaki
Chip roli: tinta mchu /10 z obrysem /30. Statusy: tinty tokenów semantycznych /15. Kody (klasy, tokeny): Geist Mono na płótnie z obramowaniem. Kontekst relacji zawsze etykietą — nigdy przełącznikiem ról (ADR-094 § 3).
górny pasek nawigacji
Znakiem marki jest zebra — jeden znak na stronie marketingowej, w aplikacji, na stronie pomocy i na drukowanym plakacie dołączenia (GH-2419). Aktywna sekcja to wypełniony slot, nie podkreślenie. Wysokość paska i scroll-margin sekcji czyta ten sam token --site-nav-h, a promień narożnika slotu to --radius-slot (2px, celowo nie --radius-xs). Logowanie ma wagę drugorzędną: jedyny wypełniony przycisk akcentu na stronie należy do rejestracji w hero (GH-2246).
tabela z paginacją
| Uczeń | Klasa | Status | Akcje |
|---|---|---|---|
| Zofia Nowak | 4a | Aktywna | Edytuj |
| Jan Kowalski | 4a | Oczekuje | Edytuj |
| Maria Wiśniewska | 4b | Szkic | Edytuj |
Nagłówki: mono, uppercase, --color-muted na płótnie. Wiersze parzyste: tinta płótna /60. Pager w karcie tabeli: licznik, wybór liczby elementów na stronę (preferencja użytkownika) i przyciski stron — aktywna strona wypełnieniem CTA. Długie treści ucinane z tooltipem — nie zawijane.
formularz — pola, switch, segmenty
Pola: powierzchnia z obramowaniem, fokus pierścieniem mchu. Błąd: obrys + komunikat --color-danger. Switch: tor 999px, włączony wypełnieniem CTA. Segmenty: aktywny na powierzchni z subtelnym cieniem.
nakładki i stany — modal, toast, menu, pusty stan
Nowe wydarzenie
Brak wydarzeń
Utwórz pierwsze zebranie, aby zobaczyć je tutaj.
Modal: nagłówek/treść/stopka rozdzielone cienkimi liniami; wizard krokami w nagłówku; cień tylko na nakładkach. Toast: inwersja (--color-ink na tle, --color-canvas tekstem), znacznik mchem. Destrukcyjne pozycje menu — --color-danger, zawsze przez wspólny dialog potwierdzenia. Pusty stan: przerywane obramowanie.
nawigacja — rail i breadcrumbs
Jeden lewy rail, bez górnego paska (ADR-094 § 2). Aktywna pozycja: tinta mchu + ikona --color-accent-strong. Grupy etykietami mono uppercase. Dzieci jako awatary z inicjałami w tincie mchu. Breadcrumbs dla obszarów wielopoziomowych (Klasy › 4a › Uczeń): poprzednie poziomy klikalne w --color-muted, bieżący pogrubiony; jedna wspólna ścieżka drill-down dla wszystkich wejść.
karta z siatką slotów — motyw produktu
Dzień Otwarty
Klasa 3B · 15 marca
- Wolny — powierzchnia z obramowaniem, hover tintą mchu
- ✓ Moja rezerwacja — wypełnienie CTA · ● Zarezerwowany przez innych — płótno
- — Wyłączony · ⏰ Konflikt między dziećmi (blokada) · 🔒 Własny dyżur (paski)
Stany niebookowalne wyjaśniają się po kliknięciu — ikona nigdy nie jest jedynym nośnikiem znaczenia (ADR-094 § 4).
stany powłoki — WakeIndicator, ShellNotice
Aplikacja się uruchamia
Była uśpiona i właśnie się budzi. Zwykle trwa to kilka sekund.
WakeIndicator — role="status", aria-live="polite"
Aplikacja się uruchamia
Była uśpiona i właśnie się budzi. Potrwa to kilka sekund. Spróbuj ponownie.
ShellNotice — role="alert"
Nie udało się wczytać menu
Sama strona działa — nie wczytała się tylko nawigacja. Spróbuj ponownie za chwilę.
ShellNotice — role="alert"
Stany oczekiwania i błędu dla strumieniowanej powłoki aplikacji (ADR-122, GH-2416). WakeIndicator renderuje się w gałęzi oczekiwania {#await} powłoki, gdy budzi się backend — 600ms opóźnienie w CSS sprawia, że rozgrzany start nigdy go nie pokazuje. ShellNotice pokrywa dwa końcowe wyniki, których strumieniowane ładowanie nie może przekazać do +error.svelte: budzenie się i błąd — Ponów uruchamia tylko ładowanie powłoki, nie strony pod nią.
§ 06 reguły
Tak i nie
Szybka ściąga. W razie wątpliwości wybierz wzorzec już użyty na stronie głównej.
✓ tak
- Utrzymuj jasne płótno (--color-canvas) jako domyślne; ciemny motyw wyłącznie przez tokeny light-dark().
- Maluj główne CTA oliwkowym wypełnieniem (--color-accent-fill) z białym tekstem (--color-accent-fg).
- Używaj mchu (--color-accent) tylko jako tinty: tła /10–/15, chipy, pierścienie fokusa, aktywna nawigacja.
- Prowadź krawędzie kart cienkim obramowaniem (--color-border) z promieniem 6px.
- Składaj nagłówki ze Space Grotesk, tekst z Geist, kody i adresy z Geist Mono.
- Sygnalizuj stany tokenami semantycznymi: --color-success, --color-danger, --color-warning.
✗ nie
- Nie kładź ciemnego tekstu na zielonym wypełnieniu — to odrzucony wariant szmaragdowy o słabym kontraście.
- Nie używaj czystego #fff ani #000 — neutralne są zawsze ocieplone.
- Nie wypełniaj dużych powierzchni mchem; akcent to reflektor, nie farba.
- Nie wprowadzaj nowych barw akcentu — mech + oliwka + tokeny statusu to komplet.
- Nie zagnieżdżaj zaokrąglonych kart w kartach; jedna obramowana powierzchnia na grupę treści.
- Nie buduj ciemnych sekcji „dla efektu" — hierarchię niesie typografia i odstępy, nie inwersja tła.
§ 07 dla agentów ai
Podsumowanie maszynowe
Wklej ten blok do promptu agenta, aby zakotwiczyć decyzje projektowe. Zwięźle — resztę agent wywnioskuje z tej strony.
Design system: Zebrania.edu.pl ("system A", ADR-094)
Reference: https://zebrania.edu.pl/brand
Stack Astro / SvelteKit + Tailwind CSS v4. Tokens as CSS variables
in @theme, themed via light-dark() + [data-theme].
Fonts Space Grotesk (display) · Geist (body/UI) · Geist Mono (codes).
Mood Light-first, warm, dev-tool minimalist. Product for Polish
schools — calm and trustworthy, not flashy.
Palette (light · dark)
--color-canvas #faf9f8 · #14110d page canvas (warm, never #fff)
--color-surface #ffffff · #1c1917 cards, panels
--color-border #e7e2da · #34302a 1px hairlines
--color-ink #1c1a17 · #f5f2ec primary text
--color-muted #57534e · #a8a29a secondary text
--color-accent #82b842 · #9bcd5a moss tint — links, chips, focus
--color-accent-strong #4f7a12 · #b7e07a accent-as-text
--color-accent-fill #4f7a12 (both) primary CTA fill (deep olive)
--color-accent-fg #ffffff (both) text on CTA fill
--color-success #1a7f37 · #3fb950
--color-danger #cf222e · #f85149
--color-warning #b45309 · #d29922
Brand mark (canonical, GH-2419)
the zebra · /favicon.svg · one mark on every surface, no variants
copies: apps/www/public · apps/web/src/lib/assets · apps/help
byte-identical, no shared package — change one, change all three
uses: favicon · site nav · app shell · help site · join poster · og-image
never a second mark, a wordmark-only lockup, or the 🦓 emoji as a stand-in
source Noto Emoji U+1F993 (Apache-2.0), viewBox cropped to artwork bbox
Primary CTA
bg: --color-accent-fill · text: --color-accent-fg (white) · bold
radius: 6px · hover: --color-accent-fill-strong (#3f6310)
Chip / badge
bg: accent at 10–15% opacity · text: --color-accent-strong · pill radius
Headline
font: Space Grotesk · weight 700–800 · color: --color-ink
Body / UI
font: Geist · 16px base · secondary text: --color-muted
Components (patterns from mockup "A", ADR-094 § 5)
table mono-uppercase headers on canvas · zebra rows (canvas/60)
truncate + tooltip, never wrap
pager inside the card: count · page-size select · page buttons
chip pill · role: accent/10 + accent/30 border · status: token/15
switch 999px track · checked = --color-accent-fill
modal header/body/footer split by hairlines · wizard steps in header
shadows on overlays ONLY (modal, toast, menus)
toast inverted: --color-ink bg, --color-canvas text, moss check
ctxmenu destructive items in --color-danger, routed via confirm dialog
empty dashed border on surface
navrail single left rail, no top bar · active = accent/10 tint
child avatars: initials in moss tint
crumbs drill-down areas only (Klasy › 4a › Uczeń) · prior levels
clickable in --color-muted · current level bold ink
booking slot states: free/mine/reserved/disabled/conflict/own-duty
non-bookable states explain on click, icon never sole carrier
shell WakeIndicator (role=status, aria-live=polite, 600ms reveal
delay) for the pending branch of the streamed shell load;
ShellNotice (role=alert, waking/failed variants, Retry) for
its two terminal outcomes (ADR-122, GH-2416)
Rules
1 Light-first. Dark mode only via light-dark() tokens — never a redesign.
2 Accent split by role: moss = tint/text, deep olive = CTA fill.
Never dark text on a green fill (mid-green contrast dead zone).
3 Warm neutrals only — no pure #fff/#000, no cool grays.
4 1px hairline borders + subtle elevation shadow · radius 6px.
5 Status colors are separate semantic tokens, never the brand accent.
6 No new accent hues. Moss + olive + status tokens are the full set.
7 One mark everywhere — the zebra. The hero's slot grid is a product
motif, not the mark; it never stands in for the brand mark.