/* ═══════════════════════════════════════
           ZMIENNE KOLORÓW (CSS Custom Properties)
           ═══════════════════════════════════════ */
        :root {
            --accent:                 #3C2A21;
            --accent-light:           color-mix(in srgb, #3C2A21 12%, transparent);
            --accent-muted:           color-mix(in srgb, #3C2A21 60%, #888);
            --accent-subtle:          color-mix(in srgb, #3C2A21 10%, white);
            /* Tło kafelków planu lekcji — jasny kolor z pełną nieprzezroczystością */
            --accent-light-no-opacity: color-mix(in srgb, var(--accent) 8%, white);
            --color-accent:           var(--accent); /* kompatybilność z Tailwind v4 */
        }

        /* Fallbacki ról — zawsze aktywne; nadpisywane przez motywy z bazy */
        body.role-super_admin, body.role-admin, body.role-director {
            --accent:        #3C2A21;
            --accent-light:  color-mix(in srgb, #3C2A21 12%, transparent);
            --accent-muted:  color-mix(in srgb, #3C2A21 60%, #888);
            --accent-subtle: color-mix(in srgb, #3C2A21 10%, white);
        }
        body.role-teacher, body.role-pedagogue {
            --accent:        #2A3C31;
            --accent-light:  color-mix(in srgb, #2A3C31 12%, transparent);
            --accent-muted:  color-mix(in srgb, #2A3C31 60%, #888);
            --accent-subtle: color-mix(in srgb, #2A3C31 10%, white);
        }
        body.role-student, body.role-parent {
            --accent:        #21303C;
            --accent-light:  color-mix(in srgb, #21303C 12%, transparent);
            --accent-muted:  color-mix(in srgb, #21303C 60%, #888);
            --accent-subtle: color-mix(in srgb, #21303C 10%, white);
        }

        /* Motywy z bazy danych — nadpisują fallbacki powyżej */
        

        /* ═══════════════════════════
           KLASY POMOCNICZE
           ═══════════════════════════ */
        .custom-accent-text       { color: var(--accent) !important; }
        .custom-accent-muted      { color: var(--accent-muted) !important; }
        .custom-accent-svg        { stroke: var(--accent) !important; }
        .custom-accent-bg         { background-color: var(--accent) !important; }
        .custom-accent-border     { border-color: var(--accent) !important; }
        .custom-accent-subtle-bg  { background-color: var(--accent-subtle) !important; }

        /* ═══════════════════════════
           SIDEBAR — nowy design (klasy .kp-*)
           ───────────────────────────
           Pasek jest WYSPĄ na tokenach design systemu: nie używa --accent
           ani klas custom-accent-*, tylko --surface/--border/--muted i palety
           kategorycznej --c-*. Reszta aplikacji zostaje na akcencie roli.
           Kolor pojedynczej pozycji wjeżdża zmienną --kp-color ustawianą
           inline przy elemencie (wartość to token var(--c-…), nigdy hex).
           ═══════════════════════════ */
        #sidebar {
            background: var(--surface);
            /* Ramka TYLKO z prawej. Rozpisana na trzy własności, żeby
               pozostałe krawędzie wróciły do wartości początkowych CSS
               zamiast zostawać na `solid` z preflightu Tailwinda —
               niewidoczne przy zerowej szerokości, ale mierzalne.
               (Obie gałęzie naprawiły to niezależnie: tu została wersja
               z `main`, rozpisana na longhandy; wariant `border: none` +
               `border-right` daje ten sam computed style, ale wymaga
               pilnowania kolejności, bo skrót kasuje prawą krawędź.) */
            border-style: none solid none none;
            border-color: currentColor var(--border) currentColor currentColor;
            border-width: 0 1px 0 0;
            /* Pasek jest wyspą na tokenach, ale sam KONTENER dziedziczył
               typografię i kolor po <body> z klasami Tailwinda: stos
               `ui-sans-serif` zamiast `--font-body`, `line-height: 24px`
               zamiast `normal` i `rgb(17,24,39)` (gray-900) zamiast `--ink`.
               Pozycje mają własne deklaracje, więc rozjazd był widoczny
               dopiero w pomiarze kontenera, nie gołym okiem. */
            font-family: var(--font-body);
            line-height: normal;
            color: var(--ink);
            /* Fallback koloru pozycji. MUSI stać tutaj, a nie na .kp-nav-item:
               własność niestandardowa zadeklarowana na samym elemencie wygrywa
               z wartością odziedziczoną, więc deklaracja na .kp-nav-item
               zablokowałaby --kp-color ustawiane na kontenerze (stopka paska,
               blok dzieci folderu). */
            --kp-color: var(--muted);
        }
        /* Szyna nawigacji bez WIDOCZNEGO paska przewijania. Przewijanie
           zostaje (`overflow-y: auto` na <nav>), znika samo rysowanie.

           PO CO: w stanie zwiniętym pasek ma 76px, z czego na treść zostaje
           47px (2×14px paddingu + 1px prawej krawędzi). Klasyczny scrollbar
           zabierający miejsce (Windows, Linux, macOS z „Pokaż paski
           przewijania: Zawsze") zjada z tego ~15px, czyli jedną trzecią:
           ikona 19px z `flex: 0 0 auto` przestaje się mieścić w paddingu
           pozycji, zjeżdża z osi szyny i zostaje przycięta przez
           `overflow-x-hidden`, a pigułka podświetlenia chudnie z 47 do 32px.

           BEZWARUNKOWO, a nie tylko przy `data-sidebar-pinned="0"`: pasek
           zwinięty rozwija się na hover do 248px, więc reguła zależna od
           stanu albo hovera przywracałaby scrollbar przy każdym najechaniu
           kursorem i przesuwała całą listę o te ~15px w bok.

           KOMBINATOR `>` JEST ISTOTNY: wysuwany popup folderu jest <div>-em
           dopinanym do #sidebar z JS i ma własne `overflow-y` — ma ZACHOWAĆ
           swój pasek przewijania, bo to okno o pełnej szerokości, a nie
           wąska szyna. Dziecko bezpośrednie wyklucza go strukturalnie.

           Dwie własności, bo dzielą świat: `scrollbar-width` (Firefox,
           Chrome 121+, Safari 18.2+) i `::-webkit-scrollbar` (starsze
           WebKit). Ta sama para co w szynach kartoteki — `.kt-modulenav`
           (static/kartoteka/module.css) i `.kt-card-tabs` (osoba.css).

           Zastępczej maski gradientowej sygnalizującej przewijanie NIE ma
           i mieć nie będzie — zakazuje jej reguła „tło płaskie" design
           systemu (readme DS, sekcja Backgrounds). */
        #sidebar > nav { scrollbar-width: none; }
        #sidebar > nav::-webkit-scrollbar { display: none; }
        /* UWAGA: .sidebar-bg NIE dotyczy już paska bocznego — pasek ma własne
           tło z tokenu --surface. Klasa została jako zwykła utility półbiałego
           tła, bo używają jej templates/profile.html (plakietka przy awatarze)
           i templates/dashboard.html (kafelki planu). Nie usuwaj jej razem
           z resztą starych styli paska. */
        .sidebar-bg { background: rgba(255, 255, 255, 0.85); }
        /* Podpisy przy zwiniętym pasku są niewidoczne (opacity:0), ale przez
           overflow-visible wystają poza pasek i łapały hover — rozwijając go
           znad treści strony. Kliki i tak obsługuje rodzic (<a>/<button>). */
        #sidebar .kp-label { pointer-events: none; }
        /* ZASKOPOWANE DO PASKA (2026-07-29). `.kp-label` to także nazwa
           z katalogu prymitywów `kropka-ds/kp-components.css`, gdzie jest
           podpisem pola formularza. Dopóki te reguły były globalne, podpisy
           pól na KAŻDEJ wyspie DS gasły przy zwiniętym pasku (`opacity: 0`)
           — dług odnotowany w DECYZJE.md przy scalaniu katalogów, rozbrojony
           przy wyspie kartoteki. Pilnuje `SidebarLabelScopeTest`
           w apps/users/tests.py. (Reguła `.kp-dot` należała do tej samej
           pary; zniknęła razem z kropkami koloru 2026-07-30. Nazwa zostaje
           zastrzeżona dla paska w `tests/test_ds_stylesheets.py` — katalog
           nadal nie ma prawa jej przejąć.) */
        #sidebar .kp-label {
            transition: opacity 0.16s ease;
            white-space: nowrap;
        }

        .kp-nav-item {
            display: flex;
            align-items: center;
            gap: 14px;
            width: 100%;
            padding: 10px 12px;
            border-radius: var(--r-pill);
            color: var(--muted);
            font-family: var(--font-display);
            font-weight: 600;
            font-size: 14px;
            letter-spacing: -0.2px;
            text-decoration: none;
            transition: background-color var(--dur-fast) ease, color var(--dur-fast) ease;
        }
        /* Rozmiar i grubość kreski narzucone TU, a nie w samym SVG — właściwość
           CSS wygrywa z atrybutem prezentacyjnym stroke-width="2" wpisanym
           w heroicons, więc glify nie wymagały edycji poza podmianą klasy. */
        .kp-nav-icon {
            width: 19px;
            height: 19px;
            flex: 0 0 auto;
            fill: none;
            stroke: currentColor;
            stroke-width: 1.5;
        }
        /* Wspólna ramka ikony — nosi kropkę koloru i licznik, żeby obie
           przyczepiały się do tego samego punktu w każdej gałęzi markupu. */
        .kp-icon-wrap {
            position: relative;
            width: 19px;
            height: 19px;
            flex: 0 0 auto;
            display: flex;
            align-items: center;
            justify-content: center;
        }
        
        /* Hover i pozycja aktywna: pełne wypełnienie własnym kolorem.
           Aktywna CELOWO nie jest neutralnie szara jak w makiecie — szary
           wśród kolorowych sąsiadów czyta się jak wyłączony, nie wybrany. */
        .kp-nav-item:hover,
        .kp-nav-item.active {
            /* Tekst jest ZAWSZE biały (decyzja użytkownika + wymóg
               docs/Nowy-Design-Kropka/CLAUDE.md). Czytelność na jasnych
               barwach palety zapewnia przyciemnienie TŁA, nie zmiana koloru
               tekstu: --kp-fill-pct mówi, ile procent barwy zostaje, resztę
               dobiera czerń. Procent liczy sidebar_colors.get_fill_pct na
               progu 4.60:1 i wstawia szablon inline. Domyślne 100% znaczy
               „bez domieszki" — tyle wystarcza sześciu kolorom palety.
               #000 jest tu literałem świadomie: to punkt skrajny skali,
               a nie barwa motywu (jak #fff w --kp-on-color). */
            background-color: color-mix(in srgb, var(--kp-color) var(--kp-fill-pct, 100%), #000);
            color: var(--kp-on-color, #fff);
        }

        /* Folder: grzbiet w kolorze rodzica wzdłuż bloku dzieci (wariant D).
           Dzieci są w spoczynku neutralne, a na hover biorą kolor RODZICA —
           w markupie dostają --kp-color ustawione na kolor folderu. */
        .kp-group-content {
            position: relative;
            padding-left: 18px;
        }
        .kp-group-content::before {
            content: '';
            position: absolute;
            left: 7px;
            top: 2px;
            bottom: 2px;
            width: 4px;
            border-radius: 9999px;
            background: var(--kp-group-color, var(--border));
        }
        /* Grzbiet znika razem z etykietami przy zwiniętym pasku — folder i tak
           jest wtedy zamknięty, a 18px wcięcia wypchnęłoby ikony poza 76px. */
        html[data-sidebar-pinned="0"] #sidebar:not(:hover) .kp-group-content {
            padding-left: 0;
        }
        html[data-sidebar-pinned="0"] #sidebar:not(:hover) .kp-group-content::before {
            display: none;
        }

        /* Licznik — pigułka dosunięta do prawej krawędzi pozycji (makieta
           pulpitu, .kp-count). Dawniej: kółko 15x15 przyklejone do rogu ikony
           PLUS powtórzenie liczby w nawiasie przy etykiecie; jedno i drugie
           zniknęło, bo makieta ma jeden licznik, nie dwa.
           Klasa `kp-label` w znaczniku jest celowa: pigułka ma gasnąć razem
           z etykietami przy pasku zwiniętym do 76px. Bez tego wisiałaby przy
           krawędzi bez podpisu, do którego się odnosi (makieta osiąga to samo
           przez `overflow: hidden` na pasku). */
        #sidebar .kp-badge {
            margin-left: auto;
            display: inline-flex;
            align-items: center;
            justify-content: center;
            flex: 0 0 auto;
            min-width: 22px;
            height: 20px;
            padding: 0 6px;
            border-radius: 999px;
            font-family: var(--font-body);
            font-weight: 700;
            font-size: 11px;
            letter-spacing: 0;
            line-height: normal;
        }
        /* Warianty niosą ZNACZENIE naszych danych (pilne / ostrzegawcze), a nie
           trzy warianty makiety (--blue / --ink / --out), która koduje nimi
           rodzaj sekcji. Kolor licznika jest u nas sygnałem, więc zostaje. */
        #sidebar .kp-badge--urgent {
            background: var(--status-urgent);
            color: #fff;
        }
        #sidebar .kp-badge--warning {
            background: var(--status-warning);
            color: #fff;
        }
        
        /* Na wypełnionej pozycji (hover / aktywna) licznik idzie w półprzezroczystą
           biel — jak w makiecie. Dawna inwersja (tło w kolorze tekstu, tekst
           w kolorze pozycji) była potrzebna przy kółku na kolorowym tle; przy
           pigułce wystarcza mleczna powłoka i jest czytelniejsza. */
        .kp-nav-item:hover .kp-badge,
        .kp-nav-item.active .kp-badge {
            background: rgba(255, 255, 255, .22);
            color: var(--kp-on-color, #fff);
        }
        /* Powtórzone z podniesioną specyficznością dla wariantów. Reguła wyżej
           ma (0,3,0), a warianty stoją pod `#sidebar .kp-badge--*`, czyli
           (1,1,0) — bez tego powtórzenia wariant WYGRYWA z powłoką na
           wypełnionej pozycji i licznik zostaje ciemny na ciemnym tle.
           Wyszło pomiarem dsprobe: makieta raportowała rgba(255,255,255,.22),
           implementacja rgb(63,63,63) przy `--ink` na wypełnionej pozycji
           (kontrast ~2.2:1). Dotyczy WSZYSTKICH wariantów, nie tylko nowego. */
        #sidebar .kp-nav-item:hover .kp-badge,
        #sidebar .kp-nav-item.active .kp-badge {
            background: rgba(255, 255, 255, .22);
            color: var(--kp-on-color, #fff);
        }

        /* ── Zawartość panelu powiadomień ───────────────────────────────────
           ŹRÓDŁO: docs/Nowy-Design-Kropka/Powiadomienia.dc.html (`.kp-pop`).
           ZMIANA: openspec/changes/redesign-powiadomienia-ds, przeniesienie do
           górnego paska — openspec/changes/gorny-pasek-konta.

           DLACZEGO TUTAJ, a nie w arkuszu wyspy: panel jest chrome obecnym na
           KAŻDEJ stronie, a `static/notifications/list.css` ładuje się wyłącznie
           na `/notifications/`. Arkusz wyspy nie może być jego domem.

           DLACZEGO `.kp-notif-*`, a nie `.kp-pop` z makiety: `.kp-pop` to nazwa
           RODZAJOWA i jako taka należałaby do katalogu prymitywów — goła
           definicja poza katalogiem cicho nadpisuje prymityw. Przestrzeń
           `.kp-<ekran>-*` jest wzorcem już zapisanym w CLAUDE.md (`.kp-news-*`,
           `.kp-gc-*`).

           CHROME PANELU ZNIKŁO STĄD 2026-08-11. Reguły `.kp-notif-pop`
           (position/width/tło/obrys/cień/animacja), reset krawędzi
           `.kp-notif-pop *` i `@keyframes kp-notif-in` zastąpił prymityw
           `.kp-topbar-panel` z katalogu — panel wisi teraz pod dzwonkiem
           w górnym pasku, więc nie potrzebuje ani `position: fixed`, ani
           współrzędnych liczonych skryptem. Ten rozjazd z makietą był tu
           opisany jako „świadomie nieprzeniesiony, do decyzji użytkownika";
           decyzja zapadła. Zostaje WYŁĄCZNIE zawartość wiersza — ona jest
           taka sama niezależnie od tego, gdzie panel wisi. */
        .kp-notif-head {
            display: flex;
            align-items: center;
            gap: 10px;
            padding: 15px 16px 13px;
        }
        .kp-notif-heading {
            font-family: var(--font-display);
            font-weight: 700;
            font-size: 14px;
            letter-spacing: -.3px;
            color: var(--ink);
        }
        .kp-notif-meta {
            font-size: 11.5px;
            color: var(--muted);
        }
        .kp-notif-all {
            margin-left: auto;
            font-size: 12px;
            font-weight: 600;
            color: var(--link);
            text-decoration: none;
        }
        .kp-notif-all:hover { color: var(--link-hover); }
        .kp-notif-list {
            max-height: 330px;
            overflow-y: auto;
        }
        .kp-notif-item {
            display: grid;
            grid-template-columns: 8px 1fr auto;
            gap: 10px;
            align-items: center;
            padding: 11px 16px;
            border-top: 1px solid var(--border);
            text-decoration: none;
            transition: background 120ms ease;
        }
        .kp-notif-item:hover { background: var(--bg-sunken); }
        /* Kategoria → token barwy. Python zwraca KLUCZ, token trzyma CSS —
           ta sama reguła co na stronie listy (`static/notifications/list.css`). */
        .kp-notif-item--decyzje    { --kp-notif-cat: var(--c-clay); }
        .kp-notif-item--tablice    { --kp-notif-cat: var(--c-green); }
        .kp-notif-item--zamowienia { --kp-notif-cat: var(--c-cyan); }
        .kp-notif-item--uczniowie  { --kp-notif-cat: var(--c-violet); }
        .kp-notif-item--system     { --kp-notif-cat: var(--c-slate); }
        .kp-notif-dot {
            width: 7px;
            height: 7px;
            border-radius: 999px;
            background: transparent;
        }
        .kp-notif-item--unread .kp-notif-dot { background: var(--kp-notif-cat); }
        .kp-notif-text {
            min-width: 0;
            display: flex;
            flex-direction: column;
            gap: 2px;
        }
        .kp-notif-itemtitle {
            font-family: var(--font-display);
            font-size: 13px;
            font-weight: 500;
            letter-spacing: -.2px;
            color: var(--muted);
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
        }
        .kp-notif-item--unread .kp-notif-itemtitle {
            font-weight: 700;
            color: var(--ink);
        }
        .kp-notif-cat {
            font-size: 11px;
            color: var(--muted);
        }
        /* Ważność — ten sam środek wyrazu co na pełnej liście (`.pw-important`
           w static/notifications/list.css): SŁOWO w kolorze stanu pilnego,
           w rzędzie metadanych. Panel jest gęstszy, więc forma jest okrojona
           do samego napisu, bez plakietki i bez glifu — okrojenie formy jest
           dozwolone, zmiana środka wyrazu nie. */
        .kp-notif-important {
            font-weight: 700;
            color: var(--status-urgent);
        }
        .kp-notif-time {
            font-size: 11px;
            color: var(--hint);
            white-space: nowrap;
            font-variant-numeric: tabular-nums;
        }
        .kp-notif-empty {
            border-top: 1px solid var(--border);
            padding: 26px 20px 30px;
            display: flex;
            flex-direction: column;
            align-items: center;
            gap: 10px;
            text-align: center;
        }
        .kp-notif-emptyglyph {
            width: 44px;
            height: 44px;
            border-radius: 999px;
            display: inline-flex;
            align-items: center;
            justify-content: center;
            background: var(--bg-sunken);
            color: var(--muted);
            font-family: var(--font-display);
            font-weight: 700;
            font-size: 19px;
        }
        .kp-notif-emptybody {
            font-size: 12.5px;
            line-height: 1.5;
            color: var(--muted);
            max-width: 34ch;
        }
        /* Stopka mówi wprost, czym panel JEST: podglądem. Działania (przycisk
           akcji) żyją wyłącznie na pełnej liście — patrz `notification-actions`. */
        .kp-notif-foot {
            border-top: 1px solid var(--border);
            padding: 11px 16px;
            background: var(--bg-sunken);
            font-size: 11px;
            color: var(--muted);
        }

        /* Preflight Tailwinda (`*, ::before, ::after { border: 0 solid #e5e7eb }`)
           zostawia na KAŻDYM elemencie styl `solid` i kolor rgb(229,231,235) przy
           zerowej szerokości. Wizualnie to nic — ale computed style prymitywów
           paska rozjeżdżał się z makietą, która żadnych krawędzi tam nie deklaruje
           (`none` + currentcolor). Reguła CELOWO wylicza konkretne prymitywy
           zamiast `#sidebar *`: potomkowie używają utility Tailwinda z krawędzią
           (`border border-white` na awatarze, `border-gray-200` na submenu
           profilu) i hurtowy reset zgasiłby te krawędzie naprawdę. */
        #sidebar .kp-nav-item,
        #sidebar .kp-label {
            border-style: none;
            border-color: currentcolor;
        }
        

        /* Przycisk przypięcia w nagłówku paska — 34x34, radius 10 (makieta). */
        .sidebar-pinbtn {
            appearance: none;
            cursor: pointer;
            flex: 0 0 auto;
            margin-left: auto;
            width: 34px;
            height: 34px;
            border-radius: 10px;
            border: 1px solid transparent;
            background: transparent;
            color: var(--blue-600);
            display: inline-flex;
            align-items: center;
            justify-content: center;
            transition: background .14s ease, border-color .14s ease, color .14s ease,
                        opacity .16s ease;
        }
        .sidebar-pinbtn:hover {
            background: var(--bg-sunken);
            border-color: var(--border);
        }
        
        html[data-sidebar-pinned="0"] #sidebar:not(:hover) .sidebar-pinbtn {
            opacity: 0;
            pointer-events: none;
        }

        .transition-all-custom { transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); }

        /* ═══════════════════════════
           MOBILE RESPONSIVE — sidebar slide-in + main full-width
           ═══════════════════════════ */
        @media (max-width: 767px) {
            /* Sidebar przesunięty poza ekran domyślnie — wyjeżdża po toggle.
               Breakpoint zostaje 768px (makieta ma 940px) — cała reszta
               layoutu aplikacji jest zestrojona z 768px. */
            #sidebar {
                width: 248px !important;
                top: 0 !important;
                left: 0 !important;
                bottom: 0 !important;
                transform: translateX(-110%);
                transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
                box-shadow: var(--shadow-hero);
            }
            #sidebar.mobile-open {
                transform: translateX(0);
            }
            /* Na mobile pasek jest zawsze pełnej szerokości, więc etykiety
               widoczne niezależnie od stanu przypięcia. */
            #sidebar .kp-label {
                opacity: 1 !important;
                pointer-events: auto;
            }
            #sidebar .kp-group-content {
                padding-left: 18px !important;
            }
            #sidebar .kp-group-content::before {
                display: block !important;
            }
            /* Main na mobile bez wcięcia z lewej (sidebar ukryty).

               WCIĘCIA POZIOME 26px, tak samo jak na desktopie — makiety mają
               `padding: 20px 26px` niezależnie od szerokości okna, a przy 1rem
               kolumna treści miała 358px zamiast makietowych 338px.

               GÓRNE WCIĘCIE musi odsunąć treść spod hamburgera. Przycisk jest
               `position: fixed` w rogu (top 12px, wysokość 44px, czyli zajmuje
               pas 12–56px), a treść startowała od 16px — nakładka była pewna,
               nie zależna od strony. Defekt znalazły NIEZALEŻNIE trzy wyspy,
               co samo w sobie jest dowodem, że siedział we wspólnej chromie:
               zmierzone przy 390px na kartotece (hamburger przecinał nadpis
               „KARTOTEKA" i nagłówek „Rejestr osób"), na kalendarzu (tytuł
               „Kalendarz"), na księgowości (kicker „KSIĘGOWOŚĆ") oraz na
               tablicach i statystykach tablic (powrót, mikro-etykieta,
               nagłówek). 4.5rem = 12 + 44 + 16px oddechu; wersja z kartoteki
               dawała 4.25rem, wybrano hojniejszą. Makieta rozwiązuje to inaczej
               (pełny górny pasek) — to jest minimalna korekta kolizji, nie
               odtworzenie tamtego układu. */
            /* WARUNKIEM JEST OBECNOŚĆ CHROMY, NIE NAZWA TRASY (2026-08-20).

               Selektor celuje w `#main-content` sąsiadujący z hamburgerem, bo
               hamburger jest POWODEM istnienia tych wartości: 26px to wcięcie
               makietowe kolumny treści, a 4.5rem odsuwa treść spod przycisku
               stojącego `fixed` w pasie 12–56px. Strona, która hamburgera nie
               renderuje, nie ma czego omijać ani czym się odsuwać.

               Wcześniej reguła brzmiała gołe `#main-content` i obowiązywała
               WSZĘDZIE. Skutek zmierzony na 390px: strona startowa i `/why/`
               dostawały `72px 26px 64px 26px`, przez co przyklejony pasek
               strony startowej i jej otwarcie — oba pełnej szerokości — urywały
               się 26px przed krawędzią okna, a nad paskiem stał pas 72px
               pustki po hamburgerze, którego tam nie ma.

               To jest ta sama osłona, którą blok desktopowy ma od dawna
               (patrz komentarz przy `data-sidebar-pinned`, wyżej w tym pliku:
               „brak nadmiarowej padding-left na main-content (pusty pasek
               na landing'u)"). Blok mobilny jej nie miał — stąd ta zmiana.

               Strona wejścia rozwiązała to u siebie obejściem
               `#main-content:has(> .lg-root) { padding: 0 !important }`
               (`static/users/login.css:86`), którego `!important` istniał
               WYŁĄCZNIE po to, żeby pokonać `!important` stąd. Po tej zmianie
               tamta reguła jest bezczynna; zostaje na miejscu, żeby nie
               poszerzać zakresu, i czeka na osobne sprzątnięcie.

               Rodzeństwo potwierdzone pomiarem: na stronie z chromą
               `#main-content` sąsiaduje z `#mobile-menu-trigger`, `#sidebar`
               i `#topbar`; na stronie bez chromy nie ma żadnego z nich.

               `padding-bottom` celowo siedzi w tej samej regule: jest oddechem
               pod treścią wpuszczoną w powłokę, a strona niosąca własną stopkę
               (jak startowa) domyka się sama i doliczone 64px zostawiało pod
               nią martwy pas. */
            #mobile-menu-trigger ~ #main-content {
                padding-left: 26px !important;
                padding-right: 26px !important;
                padding-top: 4.5rem !important;
                padding-bottom: 4rem !important;
            }
            
            #topbar ~ #main-content { padding-top: 1.5rem !important; }
            #topbar { padding-left: 68px; padding-right: 16px; }
            /* Hamburger toggle visible only on mobile */
            #mobile-menu-trigger { display: flex !important; }
            /* Backdrop za sidebar gdy otwarty */
            #mobile-menu-backdrop {
                position: fixed; inset: 0; z-index: 49;
                background: rgba(0, 0, 0, 0.4); backdrop-filter: blur(4px);
                opacity: 0; visibility: hidden;
                transition: opacity 0.3s, visibility 0s linear 0.3s;
            }
            #mobile-menu-backdrop.mobile-open {
                opacity: 1; visibility: visible;
                transition: opacity 0.3s, visibility 0s;
            }
            /* Toast container na mobile — pełna szerokość minus marginesy */
            #toast-container {
                left: 0.5rem !important; right: 0.5rem !important;
                bottom: 0.5rem !important;
                max-width: none !important;
            }
            #toast-container .toast-item {
                width: 100%;
            }
        }
        #mobile-menu-trigger { display: none; }

        /* ── Animowane popupy menu (sidebar popup tabs + profile submenu) ─── */
        
        .sidebar-popup {
            position: absolute;
            opacity: 0;
            width: 266px;
            display: flex;
            flex-direction: column;
            gap: 3px;
            background: var(--surface);
            border: 1px solid var(--border);
            border-radius: 24px;
            box-shadow: var(--shadow-hero);
            /* height:0 + overflow:hidden zapobiega wliczaniu zamkniętego popupu
               do scroll-height scrollowalnego <nav> (position:absolute nie
               wyklucza go ze scroll-area gdy jest wewnątrz overflow:auto). */
            height: 0;
            overflow: hidden;
            transform: translateX(-6px) scale(0.96);
            transform-origin: left center;
            pointer-events: none;
            visibility: hidden;
            transition: opacity 160ms cubic-bezier(0.16, 1, 0.3, 1),
                        transform 160ms cubic-bezier(0.16, 1, 0.3, 1),
                        visibility 0s linear 160ms;
        }
        .sidebar-popup.popup-open {
            opacity: 1;
            height: auto;
            /* Padding dopiero tutaj: zamknięty panel ma `height: 0` po to, żeby
               nie wchodzić do scroll-area <nav>, a padding dołożyłby mu 20px
               mimo zerowej wysokości treści. */
            padding: 10px;
            overflow: visible;
            transform: translateX(0) scale(1);
            pointer-events: auto;
            visibility: visible;
            transition: opacity 160ms cubic-bezier(0.16, 1, 0.3, 1),
                        transform 160ms cubic-bezier(0.16, 1, 0.3, 1),
                        visibility 0s;
            animation: sidebar-fly-in .18s cubic-bezier(.32, .72, 0, 1);
        }
        
        .sidebar-popup-head {
            display: flex;
            align-items: center;
            gap: 9px;
            padding: 6px 8px 10px;
        }
        .sidebar-popup-dot {
            width: 8px;
            height: 8px;
            border-radius: 50%;
            flex: 0 0 auto;
            background: var(--fly, var(--ink-3));
        }
        .sidebar-popup-title {
            font-family: var(--font-display);
            font-weight: 700;
            font-size: 13px;
            letter-spacing: -0.2px;
            color: var(--ink);
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
        }
        .sidebar-popup-kicker {
            margin-left: auto;
            flex: 0 0 auto;
            font-family: var(--font-body);
            font-weight: 700;
            font-size: 9.5px;
            letter-spacing: 0.7px;
            text-transform: uppercase;
            color: var(--muted);
        }

        .sidebar-flyitem {
            position: relative;
            display: flex;
            align-items: center;
            gap: 11px;
            padding: 10px 16px;
            border-radius: var(--r-pill);
            background: transparent;
            border: 1px solid transparent;
            font-family: var(--font-body);
            font-weight: 600;
            font-size: 13px;
            color: var(--ink-2);
            text-decoration: none;
            width: 100%;
            text-align: left;
            transition: background .12s ease, color .12s ease, border-color .12s ease,
                        transform .14s cubic-bezier(.32, .72, 0, 1);
            animation: sidebar-flyitem-in .22s cubic-bezier(.32, .72, 0, 1) both;
        }
        /* Włosowy rozdzielacz MIĘDZY pozycjami (nie pod ostatnią) — gaśnie przy
           pozycji pod kursorem i przy następnej, żeby nie przecinał podkładu. */
        .sidebar-flyitem + .sidebar-flyitem::before {
            content: '';
            position: absolute;
            left: 14px;
            right: 14px;
            top: -2px;
            height: 1px;
            background: var(--border-soft);
            transition: opacity .12s ease;
        }
        .sidebar-flyitem:hover::before,
        .sidebar-flyitem:hover + .sidebar-flyitem::before { opacity: 0; }
        .sidebar-flyitem:hover {
            background: color-mix(in srgb, var(--fly, var(--ink-3)) 11%, var(--surface));
            border-color: color-mix(in srgb, var(--fly, var(--ink-3)) 38%, var(--border));
            color: var(--ink);
            transform: translateX(3px);
        }
        /* Pozycja niebezpieczna (wyloguj) zostaje czerwona — to sygnał, nie
           dekoracja, więc nie idzie za akcentem panelu. */
        .sidebar-flyitem--danger { color: var(--status-urgent); }
        .sidebar-flyitem--danger:hover {
            background: color-mix(in srgb, var(--status-urgent) 11%, var(--surface));
            border-color: color-mix(in srgb, var(--status-urgent) 38%, var(--border));
            color: var(--status-urgent);
        }
        /* Pozycja bieżąca zostaje podświetlona bez najechania — inaczej po
           wejściu na podstronę panel nie mówi, gdzie jesteś. */
        .sidebar-flyitem.is-active {
            background: color-mix(in srgb, var(--fly, var(--ink-3)) 11%, var(--surface));
            border-color: color-mix(in srgb, var(--fly, var(--ink-3)) 38%, var(--border));
            color: var(--ink);
        }
        .sidebar-flyitem-note {
            display: block;
            font-weight: 500;
            font-size: 11px;
            color: var(--muted);
        }
        .sidebar-flyitem-count {
            margin-left: auto;
            flex: 0 0 auto;
            display: inline-flex;
            align-items: center;
            justify-content: center;
            min-width: 22px;
            height: 20px;
            padding: 0 6px;
            border-radius: 999px;
            font-family: var(--font-body);
            font-weight: 700;
            font-size: 11px;
            color: #fff;
            background: var(--fly, var(--ink-3));
        }
        @keyframes sidebar-fly-in {
            from { opacity: 0; transform: translateX(-8px); }
            to   { opacity: 1; transform: translateX(0); }
        }
        @keyframes sidebar-flyitem-in {
            from { opacity: 0; transform: translateX(-6px); }
            to   { opacity: 1; transform: none; }
        }
        /* Wejście kaskadą — pozycje pojawiają się jedna po drugiej. */
        .sidebar-flyitem:nth-of-type(2) { animation-delay: .03s; }
        .sidebar-flyitem:nth-of-type(3) { animation-delay: .06s; }
        .sidebar-flyitem:nth-of-type(4) { animation-delay: .09s; }
        .sidebar-flyitem:nth-of-type(5) { animation-delay: .12s; }
        .sidebar-flyitem:nth-of-type(6) { animation-delay: .15s; }

        .avatar-box { width: 32px; height: 32px; flex-shrink: 0; overflow: hidden; border-radius: 9999px; }

        @keyframes bounce-short {
            0%, 100% { transform: translateY(0); }
            50% { transform: translateY(-4px); }
        }
        .animate-bounce-short { animation: bounce-short 1s ease-in-out infinite; }

        /* Pulsacja ocen niedostatecznych (=1) — w _grade_pill.html.
           Mocny czerwony glow + lekkie skalowanie, by od razu zwrócić uwagę. */
        @keyframes gradePulse {
            0%, 100% {
                box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.5);
                transform: scale(1);
            }
            50% {
                box-shadow: 0 0 0 6px rgba(239, 68, 68, 0);
                transform: scale(1.05);
            }
        }
        .grade-pulse-warning { /* anchor klasy; animacja w inline style w pill */ }

        /* Kremowe tło aplikacji */
        html { background-color: #FAF8F5; }
        body { background-color: #FAF8F5; }

        /* Wygaszenie przejść do pierwszej namalowanej klatki. Atrybut zdejmuje
           skrypt ③ w podwójnym rAF. Bez tego korekta trybu przez warstwę
           zapasową byłaby animowana przez `transition-colors duration-500`
           z <body>, czyli widoczna jako półsekundowe przenikanie. */
        html[data-boot] body,
        html[data-boot] body * { transition: none !important; }

        /* Ikony przełącznika trybu chowane atrybutem, nie klasą `.hidden`
           (ta pochodzi z Tailwinda z CDN i nie istnieje przy pierwszej klatce).
           Reguła jest konieczna, bo preflight Tailwinda ustawia
           `svg { display: block }` i bije `[hidden]` z arkusza przeglądarki. */
        #sun-icon[hidden],
        #moon-icon[hidden] { display: none; }

        /* ═══════════════════════════════════════════════════
           TRYB CIEMNY
           html.dark — tło poza obszarem dokumentu (overscroll) oraz okno
                       czasu, zanim <body> w ogóle istnieje
           body.dark — pełne style; klasa przychodzi z serwera (ciasteczko
                       kropka_dark), a nie ze skryptu na końcu strony
           ═══════════════════════════════════════════════════ */
        html.dark { background-color: #121212; }

        body.dark {
            background-color: #121212 !important;
            color: #e0e0e0 !important;
            --accent-light-no-opacity: color-mix(in srgb, var(--accent) 12%, #1e1e1e);
        }

        /* Tła */
        body.dark .bg-gray-50  { background-color: #121212 !important; }
        body.dark .bg-gray-100 { background-color: #1a1a1a !important; }
        body.dark .bg-white {
            background-color: #1e1e1e !important;
            color: #e0e0e0 !important;
            border-color: #333 !important;
        }
        body.dark .custom-accent-subtle-bg {
            background-color: color-mix(in srgb, var(--accent) 15%, #1e1e1e) !important;
        }

        /* Kolory tekstu */
        body.dark .text-gray-900,
        body.dark .text-gray-800,
        body.dark .text-gray-700 { color: #e0e0e0 !important; }
        body.dark .text-gray-600,
        body.dark .text-gray-500,
        body.dark .text-gray-400 { color: #9e9e9e !important; }

        /* Obramowania */
        body.dark .border-gray-200,
        body.dark .border-white   { border-color: #333 !important; }

        /* Elementy formularzy.

           FURTKA DLA WYSP DESIGN SYSTEMU (`:not(.kp-*)`).
           Ta warstwa ciemna nadpisuje wygląd przez !important i robi to na
           dwa sposoby. Reguły klasowe (.bg-white, .text-gray-700, …) rozbrajają
           się same, gdy element przestaje nosić utile Tailwinda. Ta reguła jest
           inna: łapie element po NAZWIE TAGU, więc zdjęciem klasy jej nie
           unikniesz, a !important wygrywa z każdą specyficznością — pole
           stylowane tokenami DS i tak dostałoby #2a2a2a (zmierzone).

           Wykluczenie działa OPT-IN: obejmuje wyłącznie elementy, które same
           zgłosiły się do design systemu klasą .kp-field z WSPÓLNEGO katalogu
           kropka-ds/kp-components.css. Bez niej pola wysp DS dostawały
           w trybie ciemnym #2a2a2a zamiast powierzchni DS rgb(29,31,29)
           — zmierzone.
           Formularze poza wyspami (a więc cała reszta aplikacji) nie zmieniają
           się o piksel. Każda kolejna wyspa DS z formularzem korzysta z tej
           samej furtki — nie dokładaj obejść z !important po stronie wyspy.

           Furtka niosła wcześniej trzy dodatkowe nazwy — .kp-input, .kp-sel
           i .kp-area, prywatne dla wyspy kanban. Tablica była ich JEDYNYM
           konsumentem i przeszła na .kp-field, więc wyjątki wypadły. Nie
           dokładaj tu nazw prywatnych dla wyspy: to jest kontrakt WSPÓLNY,
           a każda prywatna nazwa w nim zmusza kolejną wyspę do zgadywania,
           która z nich jest tą właściwą.
           Uzasadnienie: openspec redesign-kanban-board (design D9),
           redesign-gws-import (scalenie katalogów) oraz
           consolidate-ds-primitive-layer (zwężenie furtki do .kp-field). */
        body.dark input:not([type="color"]):not(.kp-field),
        body.dark select:not(.kp-field),
        body.dark textarea:not(.kp-field) {
            background-color: #2a2a2a !important;
            color: #e0e0e0 !important;
            border-color: #444 !important;
        }

        /* Hover na listach */
        body.dark .hover\:bg-gray-50:hover  { background-color: #252525 !important; }
        body.dark .hover\:bg-gray-200:hover { background-color: #2a2a2a !important; }
        body.dark .hover\:bg-orange-50:hover { background-color: rgba(124, 45, 18, 0.2) !important; }

        /* Dodatkowe tła szarości */
        body.dark .bg-gray-200 { background-color: #2a2a2a !important; }
        body.dark .bg-gray-700 { background-color: #2a2a2a !important; }
        body.dark .bg-gray-800 { background-color: #1a1a1a !important; }
        body.dark .bg-gray-900 { background-color: #121212 !important; }

        /* Kolorowe tła — znaczniki statusu i ikony */
        body.dark .bg-green-50,
        body.dark .bg-green-100  { background-color: rgba(20, 83, 45, 0.35) !important; }
        body.dark .bg-red-50,
        body.dark .bg-red-100    { background-color: rgba(127, 29, 29, 0.35) !important; }
        body.dark .bg-yellow-50,
        body.dark .bg-yellow-100 { background-color: rgba(113, 63, 18, 0.35) !important; }
        body.dark .bg-orange-50,
        body.dark .bg-orange-100 { background-color: rgba(124, 45, 18, 0.3) !important; }
        body.dark .bg-amber-50,
        body.dark .bg-amber-100  { background-color: rgba(120, 53, 15, 0.35) !important; }
        body.dark .bg-purple-50,
        body.dark .bg-purple-100 { background-color: rgba(88, 28, 135, 0.35) !important; }

        /* Kolorowy tekst — znaczniki statusu */
        body.dark .text-green-600,
        body.dark .text-green-700  { color: #4ade80 !important; }
        body.dark .text-red-600,
        body.dark .text-red-700,
        body.dark .text-red-800    { color: #f87171 !important; }
        body.dark .text-yellow-600,
        body.dark .text-yellow-700 { color: #facc15 !important; }
        body.dark .text-orange-600,
        body.dark .text-orange-700,
        body.dark .text-orange-800 { color: #fb923c !important; }
        body.dark .text-amber-600,
        body.dark .text-amber-700,
        body.dark .text-amber-800  { color: #fbbf24 !important; }
        body.dark .text-purple-600,
        body.dark .text-purple-700,
        body.dark .text-purple-800 { color: #c084fc !important; }

        /* Dodatkowe obramowania */
        body.dark .border-gray-100 { border-color: #2a2a2a !important; }
        body.dark .border-gray-300 { border-color: #444 !important; }
        body.dark .border-gray-600 { border-color: #555 !important; }
        body.dark .border-gray-700 { border-color: #444 !important; }
        body.dark .border-orange-200 { border-color: rgba(194, 65, 12, 0.5) !important; }

        /* Separatory wierszy tabeli */
        body.dark .divide-gray-50 > :not([hidden]) ~ :not([hidden]),
        body.dark .divide-gray-100 > :not([hidden]) ~ :not([hidden]) { border-color: #252525 !important; }

        /* Tekst akcentowany — rozjaśnienie względem koloru roli */
        body.dark .custom-accent-text  { filter: brightness(1.9) saturate(0.75); }
        body.dark .custom-accent-muted { filter: brightness(1.6) saturate(0.7); }
        body.dark .custom-accent-svg   { filter: brightness(1.9) saturate(0.75); }

        /* Pasek boczny NIE ma tu już reguł — ciemne kolory bierze z nadpisań
           tokenów DS (static/kropka-ds/tokens-colors.css, sekcja body.dark),
           a nie z nadpisań klas Tailwind przez !important.
           Poniżej została wyłącznie utility .sidebar-bg, której używają
           profile.html i dashboard.html — patrz komentarz przy jej definicji. */
        body.dark .sidebar-bg {
            background: rgba(30, 30, 30, 0.9) !important;
            border-color: rgba(255, 255, 255, 0.1) !important;
        }

        /* Journal app — dark mode */
        body.dark .lesson-card {
            background-color: #1e1e1e !important;
            border-color: #333 !important;
        }
        body.dark .day-col-header {
            background-color: #1a1a1a !important;
            border-color: #2a2a2a !important;
        }
        body.dark .week-nav-bar {
            background-color: #1e1e1e !important;
            border-color: #2a2a2a !important;
        }
        body.dark .filter-bar {
            background-color: #1a1a1a !important;
            border-color: #2a2a2a !important;
        }
        body.dark .no-lessons-cell {
            background-color: #1a1a1a !important;
            border-color: #2a2a2a !important;
            color: #444 !important;
        }
        body.dark .detail-card {
            background-color: #1e1e1e !important;
            border-color: #2a2a2a !important;
        }
        body.dark .meta-row {
            background-color: #1a1a1a !important;
            border-color: #2a2a2a !important;
        }
        body.dark .mapping-card {
            background-color: #1e1e1e !important;
            border-color: #2a2a2a !important;
        }
        body.dark .mapping-row:hover {
            background-color: #252525 !important;
        }
        body.dark .info-banner {
            background-color: rgba(120, 53, 15, 0.2) !important;
            border-color: rgba(120, 53, 15, 0.4) !important;
        }

        body.dark .bg-blue-100  { background-color: rgba(30, 64, 175, 0.35) !important; }
        body.dark .text-blue-700 { color: #93c5fd !important; }

        /* ═══════════════════════════════════════════════════════════
           BRAND SURFACES — ciepła paleta (beż + brąz) zamiast szarości.
           Używane na widokach admina (panele zgłoszeń itd.), gdzie chcemy
           mocniej zaznaczyć tożsamość marki Kropka.

           Wartości spójne z paletą landing.html / modal zgłoszeń:
             --coffee-dark  #3C2A21
             --coffee-soft  #8A6E5C
             --beige-dark   #D4BDAC
             --beige-light  #F4EAE0
             --cream        #FAF6F1
           ═══════════════════════════════════════════════════════════ */
        .brand-card {
            background-color: #FBF5EE;
            border: 1px solid rgba(212, 189, 172, 0.55);
        }
        body.dark .brand-card {
            background-color: #2a1d16 !important;
            border-color: rgba(212, 189, 172, 0.18) !important;
        }

        .brand-input {
            background-color: #FAF6F1;
            border: 1px solid rgba(212, 189, 172, 0.7);
            color: #3C2A21;
        }
        .brand-input::placeholder { color: rgba(60, 42, 33, 0.45); }
        .brand-input:focus {
            outline: none;
            border-color: #3C2A21;
            box-shadow: 0 0 0 3px rgba(60, 42, 33, 0.12);
        }
        body.dark .brand-input {
            background-color: #3a281c !important;
            border-color: rgba(212, 189, 172, 0.25) !important;
            color: #F4EAE0 !important;
        }
        body.dark .brand-input::placeholder { color: rgba(244, 234, 224, 0.4) !important; }
        body.dark .brand-input:focus {
            border-color: #D4BDAC !important;
            box-shadow: 0 0 0 3px rgba(244, 234, 224, 0.12) !important;
        }

        .brand-thead {
            background-color: rgba(212, 189, 172, 0.35);
            border-bottom: 1px solid rgba(212, 189, 172, 0.55);
        }
        body.dark .brand-thead {
            background-color: #1f140e !important;
            border-bottom-color: rgba(212, 189, 172, 0.18) !important;
        }
        .brand-thead th { color: #5F4435 !important; }
        body.dark .brand-thead th { color: #D4BDAC !important; }

        .brand-divide > * + * { border-top: 1px solid rgba(212, 189, 172, 0.35); }
        body.dark .brand-divide > * + * { border-top-color: rgba(212, 189, 172, 0.12) !important; }

        .brand-row-hover:hover { background-color: rgba(244, 234, 224, 0.5); }
        body.dark .brand-row-hover:hover {
            background-color: rgba(244, 234, 224, 0.04) !important;
        }

        .brand-inset {
            background-color: rgba(212, 189, 172, 0.25);
            border: 1px solid rgba(212, 189, 172, 0.4);
        }
        body.dark .brand-inset {
            background-color: rgba(244, 234, 224, 0.05) !important;
            border-color: rgba(212, 189, 172, 0.18) !important;
        }

        .brand-counter-pill {
            background-color: rgba(212, 189, 172, 0.4);
            color: #5F4435;
            font-weight: 700;
        }
        body.dark .brand-counter-pill {
            background-color: rgba(244, 234, 224, 0.08) !important;
            color: #D4BDAC !important;
        }

        .brand-text-secondary { color: #8A6E5C; }
        body.dark .brand-text-secondary { color: #D4BDAC !important; }
        /* WCAG AA: 4.5:1 dla tekstu < 18px na #FBF5EE — opacity ≥ 0.72 */
        .brand-text-muted { color: rgba(60, 42, 33, 0.72); }
        body.dark .brand-text-muted { color: rgba(244, 234, 224, 0.7) !important; }

        /* Pill "Odrzuć" w panelu admina — outlined w paletcie brand,
           odróżnia się od primary (Zapisz) i danger (Usuń). */
        .reject-pill {
            display: inline-flex;
            align-items: center;
            justify-content: center;
            padding: 0.375rem 0.75rem;
            border-radius: 9999px;
            background: transparent;
            border: 1.5px solid rgba(60, 42, 33, 0.4);
            color: #5F4435;
            font-weight: 700;
            font-size: 11px;
            cursor: pointer;
            transition: background-color 0.15s, border-color 0.15s, color 0.15s;
        }
        .reject-pill:hover {
            background: #3C2A21;
            border-color: #3C2A21;
            color: #F4EAE0;
        }
        body.dark .reject-pill {
            border-color: rgba(212, 189, 172, 0.35) !important;
            color: #D4BDAC !important;
        }
        body.dark .reject-pill:hover {
            background: #F4EAE0 !important;
            border-color: #F4EAE0 !important;
            color: #3C2A21 !important;
        }

        /* FAB lista zgłoszeń (admin) — wariant brand.
           UWAGA: klasa specyficzna dla widgetu typu FAB (okrągły przycisk
           z ikoną). Do innych powierzchni brand używaj .brand-card / -inset. */
        .brand-fab {
            background-color: #FBF5EE;
            border: 1px solid rgba(212, 189, 172, 0.6);
            color: #3C2A21;
        }
        .brand-fab:hover { background-color: #F4EAE0; }
        body.dark .brand-fab {
            background-color: #2a1d16 !important;
            border-color: rgba(212, 189, 172, 0.25) !important;
            color: #F4EAE0 !important;
        }
        body.dark .brand-fab:hover { background-color: #3a281c !important; }
