/* =========================================================================
   SYSTEM TOKENÓW — cały produkt, oba motywy (2026-07-12)
   Wszystkie kolory idą przez zmienne, redefiniowane per motyw. Komponenty
   NIGDY nie odwołują się do surowego hexa (poza wyjątkami komentowanymi) —
   dzięki temu przełącznik jasny/ciemny działa na CAŁYM produkcie naraz.
   Warianty: base = jasny (fallback), @media dark = systemowy, [data-theme]
   = ręczny przełącznik (wygrywa nad systemem w obie strony).

   Nazwy --bg/--panel/--ink/--muted/--accent/--border/--danger zachowane 1:1,
   żeby istniejące ekrany działały bez przeróbek. Reszta to nowe tokeny designu.
   Neutrale z lekkim odchyłem ku indygo; jeden stonowany akcent (indygo).
   ========================================================================= */
:root {
    color-scheme: light dark;

    /* --- neutrale (jasny) --- */
    --bg: #eef1f6;
    --panel: #ffffff;
    --surface-2: #f7f9fc;   /* zebra, drugorzędne tło */
    --surface-3: #eef2f8;   /* nagłówki tabel, wyróżnione komórki */
    --ink: #1a2230;
    --ink-soft: #3a4658;
    --muted: #5c6879;
    --border: #dde3ec;
    --border-soft: #e8edf4;

    /* --- akcent (indygo) --- */
    --accent: #3949ab;
    --accent-strong: #2c3a8f;   /* hover */
    --accent-soft: #e6e9f7;      /* tło aktywnych/hover wierszy */
    --accent-wash: rgba(57, 73, 171, 0.10);  /* micro-bar w komórkach dashboardu */
    --on-accent: #ffffff;        /* tekst NA akcencie (przyciski) */

    /* --- semantyka (osobno od akcentu) --- */
    --danger: #dc2626;
    --danger-soft: #fee2e2;
    --danger-ink: #991b1b;
    --good: #1d6f42;             /* Excel, aktywny */
    --good-soft: #dcfce7;
    --good-ink: #166534;
    --flag: #9a7400;             /* ostrzeżenia */
    --flag-soft: #fff8e6;
    --flag-ink: #7a5b00;
    --flag-line: #f5d77a;

    /* --- badge'e statusów (pastelowe pary tło/tekst) --- */
    --badge-import-bg: #e0e7ff; --badge-import-ink: #3730a3;
    --badge-manual-bg: #dcfce7; --badge-manual-ink: #166534;
    --badge-hidden-bg: #e5e7eb; --badge-hidden-ink: #6b7280;
    --pa-zlecony-bg: #fef3c7; --pa-zlecony-ink: #92400e;
    --pa-zaplanowany-bg: #dbeafe; --pa-zaplanowany-ink: #1e40af;
    --pa-aktywny-bg: #dcfce7; --pa-aktywny-ink: #166534;
    --pa-zaplanowana_pauza-bg: #f3e8ff; --pa-zaplanowana_pauza-ink: #6b21a8;
    --pa-pauza-bg: #e5e7eb; --pa-pauza-ink: #374151;
    --pa-zaplanowane_wylaczenie-bg: #ffedd5; --pa-zaplanowane_wylaczenie-ink: #9a3412;
    --pa-wylaczony-bg: #fee2e2; --pa-wylaczony-ink: #991b1b;

    /* --- pozostałe --- */
    --code-bg: #f0f2f5;
    --shadow-card: 0 1px 2px rgba(20,30,55,0.04), 0 4px 16px rgba(20,30,55,0.05);

    /* --- aliasy dashboardu (--pt-*) na wspólne tokeny --- */
    --pt-surface: var(--panel);
    --pt-surface-2: var(--surface-2);
    --pt-surface-3: var(--surface-3);
    --pt-ink: var(--ink);
    --pt-ink-soft: var(--ink-soft);
    --pt-muted: var(--muted);
    --pt-line: var(--border);
    --pt-line-soft: var(--border-soft);
    --pt-accent: var(--accent);
    --pt-accent-strong: var(--accent-strong);
    --pt-accent-soft: var(--accent-soft);
    --pt-radius: 12px;
    --pt-radius-sm: 8px;
    --pt-shadow: var(--shadow-card);
    --pt-fs-label: 11px;
    --pt-ls-label: 0.06em;
}

/* Dark: redefiniujemy TYLKO wartości tokenów; komponenty (stylowane przez
   tokeny) same się przełączają. Badge'e dostają ciemniejsze, mniej jaskrawe
   tła + jaśniejszy tekst, żeby pastelowe pola nie świeciły na ciemnym. */
@media (prefers-color-scheme: dark) {
    :root {
        --bg: #10141c; --panel: #171d28; --surface-2: #1c2331; --surface-3: #222b3b;
        --ink: #e8ecf3; --ink-soft: #c2cad6; --muted: #8b97a8;
        --border: #2a3444; --border-soft: #232c3a;
        --accent: #8b9bff; --accent-strong: #a5b2ff; --accent-soft: #232c47;
        --accent-wash: rgba(139,155,255,0.14); --on-accent: #10141c;
        --danger: #f2777a; --danger-soft: #3a1d1f; --danger-ink: #f2b8ba;
        --good: #5fbf92; --good-soft: #163027; --good-ink: #9fe0c0;
        --flag: #e0bb55; --flag-soft: #2c2612; --flag-ink: #e8cf8a; --flag-line: #4a3f1c;
        --badge-import-bg: #262b52; --badge-import-ink: #b7c0ff;
        --badge-manual-bg: #16302400; --badge-manual-bg: #163024; --badge-manual-ink: #9fe0c0;
        --badge-hidden-bg: #2a3444; --badge-hidden-ink: #9aa6b6;
        --pa-zlecony-bg: #3a2f12; --pa-zlecony-ink: #f0cd7a;
        --pa-zaplanowany-bg: #1c2c4a; --pa-zaplanowany-ink: #9fbcff;
        --pa-aktywny-bg: #163024; --pa-aktywny-ink: #9fe0c0;
        --pa-zaplanowana_pauza-bg: #2f2145; --pa-zaplanowana_pauza-ink: #d6b8ff;
        --pa-pauza-bg: #2a3444; --pa-pauza-ink: #c2cad6;
        --pa-zaplanowane_wylaczenie-bg: #3a2818; --pa-zaplanowane_wylaczenie-ink: #f0b788;
        --pa-wylaczony-bg: #3a1d1f; --pa-wylaczony-ink: #f2b8ba;
        --code-bg: #1c2331;
        --shadow-card: 0 1px 2px rgba(0,0,0,0.3), 0 6px 20px rgba(0,0,0,0.28);
    }
}
:root[data-theme="dark"] {
    --bg: #10141c; --panel: #171d28; --surface-2: #1c2331; --surface-3: #222b3b;
    --ink: #e8ecf3; --ink-soft: #c2cad6; --muted: #8b97a8;
    --border: #2a3444; --border-soft: #232c3a;
    --accent: #8b9bff; --accent-strong: #a5b2ff; --accent-soft: #232c47;
    --accent-wash: rgba(139,155,255,0.14); --on-accent: #10141c;
    --danger: #f2777a; --danger-soft: #3a1d1f; --danger-ink: #f2b8ba;
    --good: #5fbf92; --good-soft: #163027; --good-ink: #9fe0c0;
    --flag: #e0bb55; --flag-soft: #2c2612; --flag-ink: #e8cf8a; --flag-line: #4a3f1c;
    --badge-import-bg: #262b52; --badge-import-ink: #b7c0ff;
    --badge-manual-bg: #163024; --badge-manual-ink: #9fe0c0;
    --badge-hidden-bg: #2a3444; --badge-hidden-ink: #9aa6b6;
    --pa-zlecony-bg: #3a2f12; --pa-zlecony-ink: #f0cd7a;
    --pa-zaplanowany-bg: #1c2c4a; --pa-zaplanowany-ink: #9fbcff;
    --pa-aktywny-bg: #163024; --pa-aktywny-ink: #9fe0c0;
    --pa-zaplanowana_pauza-bg: #2f2145; --pa-zaplanowana_pauza-ink: #d6b8ff;
    --pa-pauza-bg: #2a3444; --pa-pauza-ink: #c2cad6;
    --pa-zaplanowane_wylaczenie-bg: #3a2818; --pa-zaplanowane_wylaczenie-ink: #f0b788;
    --pa-wylaczony-bg: #3a1d1f; --pa-wylaczony-ink: #f2b8ba;
    --code-bg: #1c2331;
    --shadow-card: 0 1px 2px rgba(0,0,0,0.3), 0 6px 20px rgba(0,0,0,0.28);
}
/* Light: ręczny przełącznik wymusza jasny nawet gdy system jest ciemny.
   Wartości = base :root (dublujemy, bo [data-theme] musi wygrać nad @media). */
:root[data-theme="light"] {
    --bg: #eef1f6; --panel: #ffffff; --surface-2: #f7f9fc; --surface-3: #eef2f8;
    --ink: #1a2230; --ink-soft: #3a4658; --muted: #5c6879;
    --border: #dde3ec; --border-soft: #e8edf4;
    --accent: #3949ab; --accent-strong: #2c3a8f; --accent-soft: #e6e9f7;
    --accent-wash: rgba(57,73,171,0.10); --on-accent: #ffffff;
    --danger: #dc2626; --danger-soft: #fee2e2; --danger-ink: #991b1b;
    --good: #1d6f42; --good-soft: #dcfce7; --good-ink: #166534;
    --flag: #9a7400; --flag-soft: #fff8e6; --flag-ink: #7a5b00; --flag-line: #f5d77a;
    --badge-import-bg: #e0e7ff; --badge-import-ink: #3730a3;
    --badge-manual-bg: #dcfce7; --badge-manual-ink: #166534;
    --badge-hidden-bg: #e5e7eb; --badge-hidden-ink: #6b7280;
    --pa-zlecony-bg: #fef3c7; --pa-zlecony-ink: #92400e;
    --pa-zaplanowany-bg: #dbeafe; --pa-zaplanowany-ink: #1e40af;
    --pa-aktywny-bg: #dcfce7; --pa-aktywny-ink: #166534;
    --pa-zaplanowana_pauza-bg: #f3e8ff; --pa-zaplanowana_pauza-ink: #6b21a8;
    --pa-pauza-bg: #e5e7eb; --pa-pauza-ink: #374151;
    --pa-zaplanowane_wylaczenie-bg: #ffedd5; --pa-zaplanowane_wylaczenie-ink: #9a3412;
    --pa-wylaczony-bg: #fee2e2; --pa-wylaczony-ink: #991b1b;
    --code-bg: #f0f2f5;
    --shadow-card: 0 1px 2px rgba(20,30,55,0.04), 0 4px 16px rgba(20,30,55,0.05);
}

/* color-scheme musi śledzić RĘCZNY wybór motywu, inaczej przy systemowym dark a
   wymuszonym jasnym (data-theme=light) natywne widżety (inputy, scrollbary,
   date-picker) zostają ciemne - stąd ciemne pola CC na jasnym tle. */
:root[data-theme="light"] { color-scheme: light; }
:root[data-theme="dark"] { color-scheme: dark; }

* { box-sizing: border-box; }

body {
    margin: 0;
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
    background: var(--bg);
    color: var(--ink);
}

.topbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 28px;
    height: 60px;
    background: var(--panel);
    border-bottom: 1px solid var(--border);
    position: sticky;
    top: 0;
    z-index: 40;
}

.topbar .brand {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    font-weight: 700;
    font-size: 17px;
    letter-spacing: -0.01em;
    color: var(--ink);
}
/* Znak marki: kwadrat z „P" — kotwica wizualna zamiast samego tekstu */
.topbar .brand-mark {
    display: grid;
    place-items: center;
    width: 28px;
    height: 28px;
    border-radius: 7px;
    background: var(--accent);
    color: var(--on-accent);
    font-weight: 800;
    font-size: 15px;
}
.topbar .links { display: flex; gap: 4px; align-items: center; }
.topbar a {
    text-decoration: none;
    color: var(--ink-soft);
    font-weight: 500;
    padding: 7px 12px;
    border-radius: 8px;
    transition: background .14s, color .14s;
}
.topbar a:hover { background: var(--surface-3); color: var(--ink); }
/* Aktywna zakładka — wiadomo gdzie jesteś */
.topbar a.active {
    color: var(--accent);
    background: var(--accent-soft);
    font-weight: 600;
}
.topbar a.logout { color: var(--muted); }

/* Przełącznik motywu (jasny/ciemny) — ustawia data-theme na <html>, zapamiętuje
   w localStorage. Ikona zmienia się skryptem w base.html. */
.theme-toggle {
    margin-left: 8px;
    border: 1px solid var(--border);
    background: var(--panel);
    color: var(--muted);
    width: 34px;
    height: 34px;
    border-radius: 8px;
    cursor: pointer;
    font-size: 15px;
    line-height: 1;
    display: grid;
    place-items: center;
    padding: 0;
    transition: border-color .14s, color .14s;
}
.theme-toggle:hover { border-color: var(--accent); color: var(--accent); }
.theme-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

.container { max-width: 1240px; margin: 0 auto; padding: 28px 24px; }

h1 { font-size: 24px; margin-top: 0; }

.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 16px; margin-top: 20px; }
.card {
    display: block;
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 18px 20px;
    text-decoration: none;
    color: var(--ink);
    transition: border-color .15s, transform .15s;
}
.card:hover { border-color: var(--accent); transform: translateY(-2px); }
.card h2 { margin: 0 0 6px; font-size: 17px; }
.card p { margin: 0; color: var(--muted); font-size: 14px; }

/* Logowanie */
.login-box {
    max-width: 340px;
    margin: 80px auto;
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: 32px;
    text-align: center;
}
.login-box h1 { margin-bottom: 20px; }
.login-box label { display: block; text-align: left; font-size: 14px; color: var(--muted); margin-bottom: 6px; }
.login-box input {
    width: 100%;
    padding: 10px 12px;
    border: 1px solid var(--border);
    border-radius: 8px;
    font-size: 15px;
    margin-bottom: 16px;
}
.login-box button, button.primary {
    width: 100%;
    padding: 10px;
    background: var(--accent);
    color: var(--on-accent);
    border: none;
    border-radius: 8px;
    font-size: 15px;
    font-weight: 600;
    cursor: pointer;
}
.login-box button:hover { background: var(--accent-strong); }
.error { color: var(--danger); font-size: 14px; margin-bottom: 12px; }

/* Import */
.import-form {
    max-width: 460px;
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: 24px;
    margin-top: 20px;
}
.import-form label {
    display: block;
    font-size: 14px;
    color: var(--muted);
    margin-bottom: 14px;
}
.import-form input[type="file"] {
    display: block;
    margin-top: 6px;
    font-size: 14px;
}
.import-form button { margin-top: 8px; }

.result-box {
    background: var(--panel);
    border: 1px solid var(--border);
    border-left: 4px solid var(--accent);
    border-radius: 10px;
    padding: 18px 22px;
    margin: 20px 0;
}
.result-box h2 { margin-top: 0; font-size: 18px; }
.summary { border-collapse: collapse; }
.summary td { padding: 4px 16px 4px 0; font-size: 14px; }
.summary td:last-child { font-weight: 600; text-align: right; }
.warnings { color: var(--danger); font-size: 14px; margin: 8px 0 0; padding-left: 20px; }

/* Tabele danych (Parkingi, Wpisy) */
.muted-line { color: var(--muted); font-size: 14px; }
/* linia "co widze" nad tabela dashboardu - aktywny tryb + zakres. Celowo
   lekka (bez tla/ramki) - to tylko podpis kontekstu, nie wyrozniony blok.
   Wczesniej byl niebieski panel, ale nad zwinietym wykresem wisial bez
   kontekstu; teraz stonowana linia jak .muted-line. */
.scope-line {
    font-size: 13px;
    color: var(--muted);
    margin: 6px 0 0;
}
.data-table {
    width: 100%;
    border-collapse: collapse;
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: 10px;
    overflow: hidden;
    margin-top: 16px;
}
.data-table th, .data-table td {
    padding: 9px 14px;
    text-align: left;
    border-bottom: 1px solid var(--border);
    font-size: 14px;
}
.data-table th { background: var(--surface-3); font-weight: 600; }
.data-table tr:last-child td { border-bottom: none; }
.row-hidden { color: var(--muted); }
.row-hidden td:first-child { border-left: 3px solid var(--border); }

.link-btn {
    background: none;
    border: none;
    color: var(--accent);
    cursor: pointer;
    font-size: 14px;
    padding: 0;
}
.link-btn:hover { text-decoration: underline; }
/* placeholder w kolumnie akcji - slot zajety, ale akcja niedostepna
   (np. "Pauza" u oczekujacego). Wyszarzony i nieklikalny. */
.link-btn:disabled,
.link-btn.danger:disabled {
    color: var(--muted);
    opacity: .45;
    cursor: not-allowed;
}
.link-btn:disabled:hover { text-decoration: none; }

/* Panel dodawania */
.add-panel {
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 12px 16px;
    margin-top: 16px;
}
.add-panel summary { cursor: pointer; font-weight: 600; color: var(--accent); }
.inline-form {
    display: flex;
    gap: 10px;
    margin-top: 12px;
    flex-wrap: wrap;
}
.inline-form select, .inline-form input[type="text"], .inline-form input[type="number"], .inline-form input[type="date"] {
    padding: 8px 10px;
    border: 1px solid var(--border);
    border-radius: 8px;
    font-size: 14px;
}
.inline-form input[type="text"] { flex: 1; min-width: 200px; }
.inline-form button { width: auto; padding: 8px 18px; }

.section-h { font-size: 18px; margin-top: 28px; }

/* Badge zrodla wpisu */
.badge {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 10px;
    font-size: 12px;
    font-weight: 600;
}
.badge-import { background: var(--badge-import-bg); color: var(--badge-import-ink); }
.badge-manual { background: var(--badge-manual-bg); color: var(--badge-manual-ink); }
.badge-hidden { background: var(--badge-hidden-bg); color: var(--badge-hidden-ink); font-weight: 500; }

/* Statusy ParkAway */
.badge-pa-zlecony { background: var(--pa-zlecony-bg); color: var(--pa-zlecony-ink); }
.badge-pa-zaplanowany { background: var(--pa-zaplanowany-bg); color: var(--pa-zaplanowany-ink); }
.badge-pa-aktywny { background: var(--pa-aktywny-bg); color: var(--pa-aktywny-ink); }
.badge-pa-zaplanowana_pauza { background: var(--pa-zaplanowana_pauza-bg); color: var(--pa-zaplanowana_pauza-ink); }
.badge-pa-pauza { background: var(--pa-pauza-bg); color: var(--pa-pauza-ink); }
.badge-pa-zaplanowane_wylaczenie { background: var(--pa-zaplanowane_wylaczenie-bg); color: var(--pa-zaplanowane_wylaczenie-ink); }
.badge-pa-wylaczony { background: var(--pa-wylaczony-bg); color: var(--pa-wylaczony-ink); }

/* Sygnal wstecznego startu w kolumnie "Start". Nie jest to status ParkAway,
   tylko ostrzezenie operacyjne (sprawy sprzed daty do anulowania) - stad tokeny
   --flag-*, te same co w paskach ostrzezen na innych ekranach. white-space:
   normal, bo tresc jest zdaniem, nie jednym slowem jak przy statusach. */
.badge-cancel {
    background: var(--flag-soft);
    border: 1px solid var(--flag-line);
    color: var(--flag-ink);
    white-space: normal;
    margin-top: 4px;
}
/* Odhaczenie stoi pod badge, nie w kolumnie Akcje - dotyczy tej konkretnej
   informacji, a nie workflow parkingu. */
.ack-form { margin: 2px 0 0; }
.ack-form .link-btn { font-size: 12px; }
/* Uwagi wpisane przy uruchamianiu parkingu. Cicho, bo to kontekst do sygnalu
   obok, a nie osobny komunikat - ma sie czytac dopiero po nim. */
.start-note {
    display: inline-block;
    margin-top: 3px;
    font-size: 12px;
    font-style: italic;
    color: var(--muted);
    white-space: normal;
}

/* Filtr statusow */
.status-filter { display: flex; gap: 6px; flex-wrap: wrap; margin: 16px 0; }
.status-filter a {
    padding: 6px 12px;
    border: 1px solid var(--border);
    border-radius: 8px;
    text-decoration: none;
    color: var(--ink);
    font-size: 14px;
    background: var(--panel);
}
.status-filter a.on { background: var(--accent); color: var(--on-accent); border-color: var(--accent); }
/* Pozycja "Start wstecz" - inny WYMIAR niz status (parking bywa przy tym
   aktywny), wiec odcina sie kolorem ostrzezenia zamiast wtapiac w reszte paska.
   Tokeny --flag-* maja warianty w obu motywach, wiec nie trzeba wlasnego bloku. */
.status-filter a.filter-flag {
    background: var(--flag-soft);
    border-color: var(--flag-line);
    color: var(--flag-ink);
    font-weight: 600;
}
.status-filter a.filter-flag.on { background: var(--flag); color: var(--panel); border-color: var(--flag); }

/* Filtr regionu (CM) - drugi pasek pod statusami. Ten sam wyglad pozycji, ale
   z podpisem, bo bez niego dwa rzedy identycznych pigulek nie mowilyby, ktory
   wymiar zawezaja. Odstep od gory mniejszy, zeby oba paski czytalo sie jako
   jedna grupe filtrow. */
.cm-filter { margin-top: -6px; align-items: center; }
.cm-filter-label { font-size: 13px; color: var(--muted); margin-right: 2px; }

/* Komorka akcji w tabeli parkingow - przyciski zawsze w jednej linii
   (nowrap), zeby "Wylacz" nie spadal pod spod przy 3 akcjach. */
.actions-cell { display: flex; gap: 12px; align-items: center; flex-wrap: nowrap; }
.actions-cell form { display: inline-flex; gap: 4px; align-items: center; margin: 0; }
.actions-cell .link-btn { white-space: nowrap; }
.link-btn.danger { color: var(--danger); }
.plan-hint { font-size: 12px; color: var(--accent); }

/* Inline-edycja numeru CC w tabeli Parkingi */
.cc-set-form { display: inline-flex; gap: 4px; align-items: center; margin: 0; }
.cc-cell input[type="text"] {
    width: 5.5em; padding: 3px 6px; font-size: 13px;
    /* lekka tokenowa ramka zamiast ciężkiej domyślnej przeglądarki - w gęstej
       kolumnie CC pola mają się wtapiać, nie tłoczyć jak zamknięte pudełka.
       Wyróżnienie dopiero na focus. */
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--surface-2);
    color: var(--ink);
    font-family: inherit;
    font-variant-numeric: tabular-nums;
}
.cc-cell input[type="text"]:hover { border-color: var(--muted); }
.cc-cell input[type="text"]:focus {
    outline: none;
    border-color: var(--accent);
    background: var(--panel);
}

/* Okna (dialogi) akcji ParkAway - natywny <dialog>, otwierany przez parkingi.js */
.action-dialog {
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: 20px 22px;
    max-width: 360px;
    width: 90%;
    box-shadow: 0 10px 40px rgba(0, 0, 0, 0.25);
    color: var(--ink);
}
.action-dialog::backdrop { background: rgba(0, 0, 0, 0.45); }
.action-dialog h2 { margin: 0 0 12px; font-size: 17px; }
/* Okna akcji - jedna kolumna: etykieta, pole daty, przycisk na calej szerokosci.
   Zastapilo uklad z dwoma przyciskami ("... teraz" + "Zaplanuj" obok kalendarza);
   klasy .dialog-now/.dialog-or/.dialog-schedule zniknely razem z nim. */
.action-dialog .dialog-single {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin: 0;
}
.action-dialog .dialog-single button[type="submit"] { width: 100%; }
.action-dialog .dialog-field-label { font-size: 13px; color: var(--muted); }
/* Kalendarz single-date na calej szerokosci okna. flex:none jest tu ISTOTNE:
   okno uklada sie w KOLUMNIE, wiec flex-grow rozciagalby pole na wysokosc. */
.action-dialog .cal-single { flex: none; width: 100%; }
.action-dialog .cal-single .cal-toggle {
    min-width: 0;
    width: 100%;
    text-align: left;
}
/* okno jest niewysokie i blisko dolu ekranu - panel kalendarza rozwija sie
   W GORE (nad polem), zeby zmiescil sie w calosci bez scrolla wewnatrz okna.
   overflow:visible na dialogu pozwala panelowi wyjsc poza jego obrys. */
.action-dialog { overflow: visible; }
.action-dialog .cal-single .cal-panel {
    top: auto;
    bottom: calc(100% + 4px);
}
.action-dialog .dialog-cancel { display: block; margin: 16px auto 0; }
/* Kroki okna startu (data -> pytanie o sprawy wstecz). Kazdy krok powtarza
   uklad kolumnowy formularza, bo jako element flex byłby jednym pudelkiem. */
.action-dialog [data-start-step] {
    display: flex;
    flex-direction: column;
    gap: 8px;
}
/* KONIECZNE: `display` z reguly wyzej bije `hidden` z arkusza przegladarki
   (ten dziala przez display:none o nizszej specyficznosci), wiec bez tego
   krok schowany przez JS zostaje na ekranie i oba widac naraz. */
.action-dialog [data-start-step][hidden] { display: none; }
.action-dialog .dialog-question {
    margin: 0 0 4px;
    font-size: 14px;
    line-height: 1.45;
}
/* Wybor odpowiedzi: klikalny wiersz z kropka. Klik ZAZNACZA i nic wiecej -
   uruchomienie siedzi w osobnym przycisku nizej. Wczesniej stały tu dwa
   przyciski wysylajace formularz od razu; stykaly sie bokami, a chybienie
   o kilka pikseli zapisywalo cudza decyzje bez szansy na cofniecie. */
.action-dialog .dialog-choice {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 10px 12px;
    border: 1px solid var(--border);
    border-radius: 8px;
    cursor: pointer;
}
.action-dialog .dialog-choice:hover { background: var(--surface-2); }
/* Zaznaczenie musi byc widoczne z odleglosci reki - to ono decyduje, co zrobi
   przycisk nizej, a sama kropka radia jest na to za mala. */
.action-dialog .dialog-choice:has(input:checked) {
    border-color: var(--accent);
    background: var(--accent-wash);
}
.action-dialog .dialog-choice input { margin-top: 2px; accent-color: var(--accent); }
.action-dialog .dialog-choice strong { display: block; font-size: 14px; font-weight: 600; }
.action-dialog .dialog-choice em {
    display: block;
    margin-top: 2px;
    font-size: 12px;
    font-style: normal;
    color: var(--muted);
}
/* Zatwierdzenie odsuniete od wyboru - to jedyny klik w tym oknie, ktorego nie
   da sie cofnac, wiec nie moze sasiadowac z niczym klikalnym. */
.action-dialog [data-start-confirm] { margin-top: 6px; }
.action-dialog [data-start-confirm]:disabled { opacity: .5; cursor: not-allowed; }

/* Filtr dashboardu: rzad grup "label nad polem", rowno wyrownanych.
   Kazda grupa to .field - dzieki temu nie ma wiszacych etykiet ani dziur. */
.filter-form {
    display: flex;
    gap: 16px;
    align-items: flex-end;
    flex-wrap: wrap;
    margin-top: 16px;
}
.filter-form .field { display: flex; flex-direction: column; gap: 4px; }
.filter-form .field > label { font-size: 12px; color: var(--muted); font-weight: 500; }
.filter-form select,
.filter-form input[type="text"],
.filter-form input[type="date"],
.filter-form .days-toggle {
    padding: 8px 10px;
    border: 1px solid var(--border);
    border-radius: 8px;
    font-size: 14px;
    background: var(--panel);
    color: var(--ink);
    height: 38px;
}

/* Form-kontrolki NIE dziedziczą color przez color-scheme (jak <table>) - bez
   jawnego color/tła tekst gubi się (biały na białym / ciemny na ciemnym), a
   przy systemowym dark natywne pole dostaje ciemne tło mimo wymuszonego jasnego
   motywu. Ustawiamy jawnie oba dla pól tekstowych; checkbox/radio zostawiamy
   natywne (nie chcemy im psuć wyglądu). Do tego color-scheme śledzi data-theme
   niżej, by natywne widżety trzymały się wybranego motywu. */
select, textarea,
input:not([type="checkbox"]):not([type="radio"]) {
    color: var(--ink);
    background-color: var(--panel);
}
button { color: var(--ink); }
.filter-form button[type="submit"] { width: auto; padding: 0 20px; height: 38px; }
/* margin-left:auto dosuwa akcje (Pokaż/Excel) do PRAWEJ krawędzi panelu -
   pola po lewej, przyciski po prawej (jak na makiecie). Na wąskim ekranie
   cofnięte do 0 w media query niżej. */
.filter-form .field-actions { flex-direction: row; align-items: center; gap: 12px; margin-left: auto; }
.filter-form .clear-days { font-size: 13px; color: var(--danger); }
/* eksport do Excela - przycisk wtorny (outline w zieleni Excela), spojny
   wysokoscia z "Pokaz" */
.filter-form .btn-export {
    display: inline-flex;
    align-items: center;
    height: 38px;
    padding: 0 16px;
    font-size: 14px;
    font-weight: 500;
    color: var(--good);
    background: var(--panel);
    border: 1px solid var(--good);
    border-radius: 6px;
    text-decoration: none;
    white-space: nowrap;
}
.filter-form .btn-export:hover { background: var(--good); color: var(--panel); }
.filter-form .hint-block { font-size: 12px; color: var(--muted); padding: 9px 0; }

/* Dropdown dni eksportow - przycisk + rozwijany panel z checkboxami.
   Zastepuje natywny <select multiple> (byl wysoki i brzydki). */
.days-dropdown { position: relative; }
.days-toggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    min-width: 150px;
    cursor: pointer;
    font-variant-numeric: tabular-nums;
    /* tło/ramka/kolor z tokenów WPROST - kalendarz i dni eksportów bywają POZA
       .filter-form (np. panel .stats-controls), gdzie nie łapały tła i przy
       ciemnym color-scheme dostawały brzydkie szare natywne tło przycisku */
    padding: 8px 10px;
    height: 38px;
    background: var(--panel);
    color: var(--ink);
    border: 1px solid var(--border);
    border-radius: 8px;
    font-size: 14px;
    font-family: inherit;
}
.days-toggle .caret { color: var(--muted); font-size: 12px; }
.days-toggle[aria-expanded="true"] { border-color: var(--accent); }
.days-panel {
    position: absolute;
    z-index: 20;
    top: calc(100% + 4px);
    left: 0;
    min-width: 100%;
    max-height: 240px;
    overflow-y: auto;
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: 8px;
    box-shadow: 0 6px 18px rgba(0, 0, 0, .12);
    padding: 4px;
}
.day-option {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 10px;
    border-radius: 6px;
    font-size: 14px;
    font-variant-numeric: tabular-nums;
    cursor: pointer;
    white-space: nowrap;
}
.day-option:hover { background: var(--surface-3); }
/* dzien mieszczacy sie w zakresie Od/Do - podswietlenie INFORMACYJNE
   (nie znaczy ze jest zaznaczony jako filtr) */
.day-option.in-range { background: var(--accent-soft); }
.day-option.in-range span { color: var(--accent); font-weight: 600; }

/* Kalendarz zakresu Od-Do (polski). Panel pozycjonowany jak .days-panel. */
.cal-dropdown { position: relative; }
.cal-toggle { min-width: 200px; }
.cal-panel {
    position: absolute;
    z-index: 20;
    top: calc(100% + 4px);
    left: 0;
    width: 280px;
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: 8px;
    box-shadow: 0 6px 18px rgba(0, 0, 0, .12);
    padding: 10px;
}
.cal-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 8px;
}
.cal-month { font-size: 14px; font-weight: 600; text-transform: capitalize; }
.cal-nav {
    width: 28px;
    height: 28px;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--panel);
    color: var(--muted);
    font-size: 16px;
    line-height: 1;
    cursor: pointer;
}
.cal-nav:hover { border-color: var(--accent); color: var(--accent); }
.cal-weekdays,
.cal-grid {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 2px;
}
.cal-weekdays {
    margin-bottom: 4px;
    font-size: 11px;
    color: var(--muted);
    text-align: center;
}
.cal-day {
    height: 32px;
    border: none;
    border-radius: 6px;
    background: transparent;
    color: inherit;
    font-size: 13px;
    font-variant-numeric: tabular-nums;
    cursor: pointer;
}
.cal-day:not(.cal-blank):hover { background: var(--surface-3); }
.cal-blank { cursor: default; }
/* dni pomiedzy krancami - ten sam odcien co .day-option.in-range */
.cal-day.in-range { background: var(--accent-soft); color: var(--accent); }
/* krance zakresu (od / do) */
.cal-day.selected { background: var(--accent); color: var(--on-accent); font-weight: 600; }
/* Tabela bywa szeroka (widok dzienny = nawet ~150 kolumn) i dluga (duzo
   parkingow). Scrolluje sie WEWNATRZ siebie w obu osiach:
   - overflow-x: scroll poziomy zamiast rozpychania strony,
   - max-height + overflow-y: wlasna wysokosc, dzieki czemu przyklejony
     naglowek + wiersz sum dzialaja w PIONIE (bez tego sticky liczy sie
     wzgledem kontenera, ktory wyjezdza poza ekran).
   Naglowek/kolumna/wiersz sum sa sticky wzgledem tej ramki. */
/* Wrapper tabeli: ramka ze scrollem (obie osie) + wlasna wysokosc (sticky
   liczy sie wzgledem niej). Full-bleed: wylamuje sie z kontenera 1100px i
   bierze (prawie) pelna szerokosc okna - naglowek strony i filtry zostaja
   waskie i czytelne, a tabela zyskuje miejsce. Ujemny margines cofa do
   krawedzi okna; szerokosc = pelne okno minus 2x24px oddechu. */
.table-wrap {
    overflow: auto;
    max-height: 75vh;
    width: calc(100vw - 48px);
    margin-left: calc(-50vw + 50% + 24px);
    margin-right: calc(-50vw + 50% + 24px);
}
/* Wariant BEZ full-bleed - tabela trzyma się szerokości kontenera (nie okna).
   Dla wąskich tabel (mało kolumn), gdzie full-bleed wygląda za szeroko względem
   reszty treści. Scroll poziomy zostaje na wypadek ciasnego ekranu. */
.table-wrap.table-contained {
    width: auto;
    margin-left: 0;
    margin-right: 0;
}
/* tabela wypelnia cala szerokosc wrappera (width:100%); przy malej liczbie
   kolumn rozciagaja sie one rowno, przy duzej wrapper przewija sie poziomo.
   border-collapse: separate jest KONIECZNE - przy 'collapse' position:sticky
   na komorkach (przyklejona kolumna 'Parking') nie dziala (usterka przegladarek).
   border-spacing:0 + obramowania na komorkach utrzymuja wyglad jak przy collapse. */
.dashboard-table {
    width: 100%;
    max-height: none;
    border-collapse: separate;
    border-spacing: 0;
    /* KLUCZOWE: .data-table ma overflow:hidden (zaokraglone rogi). Tu musi byc
       visible, inaczej sticky na komorkach liczy sie wzgledem TABELI (ktora sie
       nie przewija), a nie wrappera - i przyklejona kolumna 'Parking' wyjezdza. */
    overflow: visible;
}
.dashboard-table .num { text-align: right; font-variant-numeric: tabular-nums; }
.dashboard-table .total-cell { font-weight: 600; }
.dashboard-table .period-col { white-space: nowrap; }
/* Pierwsza kolumna (nazwa parkingu) i naglowek przyklejone - przy scrollu
   w prawo wiadomo ktory wiersz to co, przy scrollu w dol widac daty. */
.dashboard-table th:first-child,
.dashboard-table td:first-child {
    position: sticky;
    left: 0;
    /* z-index nad komorkami danych - inaczej przewijana tresc sasiednich
       kolumn przeswituje spod przyklejonej nazwy parkingu */
    z-index: 1;
    background: var(--panel);
    /* cien na prawej krawedzi - wizualnie oddziela przyklejona kolumne */
    box-shadow: 1px 0 0 var(--border);
    /* tlo ma sie ciagnac z trescia (dlugie nazwy), nie urywac na sztywnej
       szerokosci - dlatego nowrap zamiast min-width */
    white-space: nowrap;
}
/* Naglowek: dwa przyklejone rzedy - 1) nazwy okresow na top:0,
   2) wiersz sum 'Razem' tuz pod nim (top = wysokosc rzedu okresow).
   --head-row-h to ustalona wysokosc rzedu naglowka, zeby drugi rzad usiadl
   dokladnie pod pierwszym bez nakladania. */
.dashboard-table { --head-row-h: 38px; }
.dashboard-table thead th {
    position: sticky;
    z-index: 1;
    background: var(--surface-3);
}
.dashboard-table thead .head-periods th { top: 0; height: var(--head-row-h); }
.dashboard-table thead .head-totals th { top: var(--head-row-h); }
.dashboard-table thead .head-totals { font-size: 13px; }
/* naglowki dat + 'Razem' do PRAWEJ - w jednej linii pionowej z liczbami pod
   nimi (liczby maja .num = right). Inaczej data po lewej, wartosci po prawej
   i kolumna sie "rozjezdza". Pierwsza kolumna ('Parking') zostaje do lewej. */
.dashboard-table thead .head-periods th { text-align: right; }
.dashboard-table thead .head-periods th:first-child { text-align: left; }
/* rog (Parking/Razem, pierwsza kolumna) musi byc nad obiema osiami sticky */
.dashboard-table thead th:first-child { z-index: 2; }
/* Caly naglowek + stopka: szare tlo musi siegac DO LEWEJ krawedzi, nie
   urywac sie na pierwszej kolumnie. Domyslnie przyklejona pierwsza kolumna
   ma biale tlo (var(--panel)) - tu nadpisujemy je szarym dla rogu 'Parking',
   wiersza sum 'Razem' i stopki, zeby pas byl ciagly. */
.dashboard-table thead th:first-child,
.dashboard-table tfoot td:first-child { background: var(--surface-3); }
.dashboard-table tfoot td {
    background: var(--surface-3);
    font-weight: 600;
    border-top: 2px solid var(--border);
}

/* =========================================================================
   Czytelnosc tabeli: zebra + hover + wyrozniony "Razem" + ciasniejsze wiersze.
   Cel: przy dlugiej, szerokiej tabeli liczb oko ma sie nie gubic w wierszu i
   od razu lapac sumy. Bez kolorowania wartosci (heatmapa odrzucona).
   ========================================================================= */

/* Zebra - naprzemienne tlo wierszy prowadzi wzrok w poziomie do liczby.
   Pierwsza kolumna jest sticky z wlasnym tlem - nadpisujemy je tym samym
   odcieniem, by pas byl ciagly. */
.dashboard-table tbody tr:nth-child(even) td { background: var(--surface-2); }
.dashboard-table tbody tr:nth-child(even) td:first-child { background: var(--surface-2); }

/* Hover - podswietl caly wiersz, by przy szerokiej tabeli nie zgubic linii.
   Mocniejsze niz zebra, ale slabsze niz gorace komorki (te zostaja czytelne). */
.dashboard-table tbody tr:hover td { background: var(--accent-soft); }
.dashboard-table tbody tr:hover td:first-child { background: var(--accent-soft); }

/* Kolumna "Razem" wyrozniona - to ona daje szybki oglad calego wiersza.
   Mocniejsza lewa krawedz oddziela ja od miesiecy, lekkie tlo + bold. */
.dashboard-table td.total-cell,
.dashboard-table thead .head-periods th:last-child,
.dashboard-table thead .head-totals th:last-child {
    border-left: 2px solid var(--border);
}
.dashboard-table td.total-cell { background: var(--surface-3); }
.dashboard-table tbody tr:hover td.total-cell { background: var(--accent-soft); }

/* Ciasniejsze wiersze - wiecej parkingow naraz na ekranie, mniej skrolowania.
   Nazwa parkingu zachowuje wieksza wage wizualna (to ona "kotwiczy" wiersz). */
.dashboard-table td, .dashboard-table th { padding: 6px 14px; }
.dashboard-table tbody td:first-child { font-weight: 500; }

/* ===== Wykres (Chart.js) ===== */
/* Sekcja CELOWO poza .table-wrap - tamta scrolluje obie osie, canvas nie moze
   w to wpasc. Cala sekcja jest zwijana w <details> (domyslnie zamknietym) -
   wykres jest opcjonalny i nie zasmieca widoku przy wejsciu. */
.chart-details { margin: 8px 0 24px; }
.chart-summary {
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 12px;
    font-weight: 500;
    color: var(--ink-soft);
    background: var(--surface-3);
    border: 1px solid var(--border);
    border-radius: 6px;
    user-select: none;
    width: max-content;
}
.chart-summary:hover { background: var(--surface-3); }
.chart-details[open] .chart-summary { margin-bottom: 12px; }
.chart-section { margin: 0; }

.chart-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    margin-bottom: 10px;
    flex-wrap: wrap;
}
.chart-types { display: flex; gap: 0; }
.chart-type-btn {
    padding: 6px 14px;
    border: 1px solid var(--border);
    background: var(--panel);
    color: var(--muted);
    font-size: 13px;
    cursor: pointer;
}
.chart-type-btn:first-child { border-radius: 8px 0 0 8px; }
.chart-type-btn:last-child { border-radius: 0 8px 8px 0; border-left: none; }
.chart-type-btn.is-active {
    background: var(--accent);
    color: var(--on-accent);
    border-color: var(--accent);
}

/* Drill-down - input + panel podpowiedzi (wzorzec .days-dropdown) */
/* Wybor parkingow do porownania - toggle + panel z szukajka i checkboxami */
.chart-pick { position: relative; }
.chart-pick-toggle {
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 200px;
    justify-content: space-between;
    padding: 8px 14px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--panel);
    font-size: 13px;
    cursor: pointer;
}
.chart-pick-toggle[aria-expanded="true"] { border-color: var(--accent); }
.chart-pick-toggle .caret { color: var(--muted); font-size: 12px; }
.chart-pick-panel {
    position: absolute;
    z-index: 20;
    top: calc(100% + 4px);
    right: 0;
    width: 320px;
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: 8px;
    box-shadow: 0 6px 18px rgba(0, 0, 0, .12);
    padding: 8px;
}
.chart-pick-search {
    width: 100%;
    padding: 8px 10px;
    margin-bottom: 6px;
    border: 1px solid var(--border);
    border-radius: 6px;
    font-size: 13px;
}
.chart-pick-search:focus { outline: none; border-color: var(--accent); }
.chart-pick-list { max-height: 260px; overflow-y: auto; }
.chart-pick-item {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 8px;
    border-radius: 6px;
    font-size: 13px;
    cursor: pointer;
}
.chart-pick-item:hover { background: var(--surface-3); }
.chart-pick-item input { cursor: pointer; }
.chart-pick-empty { margin: 8px; color: var(--muted); font-size: 13px; }
.chart-pick-foot {
    margin-top: 6px;
    padding-top: 6px;
    border-top: 1px solid var(--border);
    text-align: right;
}
.chart-pick-clear {
    border: none;
    background: transparent;
    color: var(--danger);
    font-size: 12px;
    cursor: pointer;
}

/* Canvas potrzebuje rodzica o OKRESLONEJ wysokosci (maintainAspectRatio:false),
   inaczej rosnie w nieskonczonosc przy kazdym resize. */
.chart-wrap {
    position: relative;
    height: 420px;
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 12px;
    background: var(--panel);
}

/* Ostrzezenie o zawezeniu widoku dziennego */
.warn-line {
    margin: 0 0 12px;
    padding: 8px 12px;
    background: var(--flag-soft);
    border: 1px solid var(--flag-line);
    border-radius: 8px;
    font-size: 13px;
    color: var(--flag-ink);
}

/* Wizyty API — nagłówek statystyk + filtry (spójne ze zmiennymi projektu) */
/* Ta sama siatka co pasek podsumowania na /dashboard (.pt-summary): kafle dziela
   szerokosc po rowno zamiast dociskac sie do tresci, wiec liczby ustawiaja sie
   w kolumny i pasek konczy sie tam, gdzie panel pod nim. auto-fit + minmax daje
   zwijanie na wezszym ekranie za darmo - bez media query i bez zalozenia, ile
   kafli ma dany ekran (Statystyki i Recydywisci maja 4, Surowe dane API 3). */
.stats-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: 12px;
    margin: 16px 0;
}
.stat-box {
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 14px 18px;
    min-width: 140px;
}
.stat-num {
    display: block;
    font-size: 22px;
    font-weight: 700;
    color: var(--ink);
}
.stat-label {
    display: block;
    font-size: 13px;
    color: var(--muted);
    margin-top: 2px;
}
.filter-line {
    display: flex;
    gap: 8px;
    align-items: center;
    flex-wrap: wrap;
    margin: 16px 0;
}
.filter-line input,
.filter-line select {
    padding: 8px 10px;
    border: 1px solid var(--border);
    border-radius: 8px;
    font-size: 14px;
    background: var(--panel);
    color: var(--ink);
    font-family: inherit;
}
/* select w filtrze - pelne obramowanie tokenowe jak dropdowny w Dashboardzie/
   Statystykach, zamiast golego natywnego. Wysokosc wychodzi z paddingu (ta sama
   co input przy box-sizing:border-box) - bez wymuszania height, zeby nie ruszyc
   pola w Wizytach, ktore dzieli te klase. */
.filter-line select { cursor: pointer; }
/* tylko bezposredni przycisk submit formularza - NIE przyciski wewnatrz
   kalendarza (dni, strzalki nav), ktore maja wlasne style .cal-*. Bez tego
   zawezenia .filter-line button malowal cala siatke dni na akcent. */
.filter-line > button {
    padding: 8px 16px;
    background: var(--accent);
    color: var(--on-accent);
    border: none;
    border-radius: 8px;
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
}
.filter-line > button:hover { background: var(--accent-strong); }

/* Statystyki wizyt — podtekst pod kaflem (np. "1.1 wizyt/auto") */
.stat-hint {
    display: block;
    font-size: 11.5px;
    color: var(--accent);
    margin-top: 3px;
}

/* Eksport Excel w Wizytach API — zielony jak w Dashboardzie, ale link w .filter-line */
.btn-export-link {
    display: inline-flex;
    align-items: center;
    padding: 8px 14px;
    font-size: 14px;
    font-weight: 500;
    color: var(--good);
    background: var(--panel);
    border: 1px solid var(--good);
    border-radius: 8px;
    text-decoration: none;
    white-space: nowrap;
}
.btn-export-link:hover { background: var(--good); color: var(--panel); }
/* trwa generowanie pliku (wizyty-export.js) - link nie jest <button>, wiec
   :disabled tu nie zadziala; wyglad jak .control-export:disabled */
.btn-export-link.is-busy {
    opacity: 0.45;
    cursor: not-allowed;
}
.btn-export-link.is-busy:hover { background: var(--panel); color: var(--good); }

/* Pełna tabela wizyt — długie pola (hash, GUID) zawężone i przycięte,
   żeby 15 kolumn dało się przewinąć poziomo bez rozpychania tabeli */
.cell-hash, .cell-id {
    max-width: 130px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-family: var(--mono, monospace);
    font-size: 12px;
    color: var(--muted);
}

/* Notka o zakresie statystyk (filtr ten-sam-dzień) */
.stats-scope-note {
    margin: -4px 0 16px;
    font-size: 13px;
}

/* Ikonka (?) z dymkiem — wyjaśnienie metryki (np. mediana). Tooltip CSS-owy
   pojawia się na hover I focus (dostępność: klawiatura/dotyk). */
.help-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 15px;
    height: 15px;
    margin-left: 5px;
    font-size: 11px;
    font-weight: 700;
    color: var(--muted);
    background: var(--border);
    border-radius: 50%;
    cursor: help;
    position: relative;
    vertical-align: middle;
}
.help-icon:hover, .help-icon:focus { color: var(--on-accent); background: var(--accent); outline: none; }
.help-icon::after {
    content: attr(data-tip);
    position: absolute;
    bottom: calc(100% + 8px);
    left: 50%;
    transform: translateX(-50%);
    white-space: nowrap;
    padding: 6px 10px;
    background: var(--ink);
    color: var(--on-accent);
    font-size: 12px;
    font-weight: 400;
    line-height: 1.3;
    letter-spacing: normal;
    text-transform: none;
    border-radius: 8px;
    box-shadow: 0 4px 12px rgba(0,0,0,.15);
    opacity: 0;
    visibility: hidden;
    transition: opacity .15s;
    z-index: 20;
    pointer-events: none;
}
.help-icon:hover::after, .help-icon:focus::after { opacity: 1; visibility: visible; }

/* Wariant tooltipa wysuwanego W DÓŁ — dla ikonek w nagłówkach tabeli, gdzie
   kontener .table-wrap (overflow:auto) przyciąłby dymek wysuwany do góry. */
.help-icon.tip-down::after {
    bottom: auto;
    top: calc(100% + 8px);
}

/* Ikonka (?) jest teraz <button> — reset domyślnego stylu przycisku
   (zachowujemy wygląd kółka z .help-icon wyżej) */
button.help-icon {
    border: none;
    font-family: inherit;
    line-height: 1;
    padding: 0;
}

/* Okienko z wyjaśnieniem mediany (natywny <dialog>) */
.help-dialog {
    max-width: 460px;
    width: calc(100vw - 40px);
    border: 1px solid var(--border);
    border-radius: 14px;
    padding: 24px 26px;
    background: var(--panel);
    color: var(--ink);
    box-shadow: 0 10px 40px rgba(0,0,0,.18);
}
.help-dialog::backdrop { background: rgba(0,0,0,.45); }
.help-dialog h2 { margin: 0 0 14px; font-size: 18px; }
.help-dialog p { margin: 10px 0; font-size: 14px; line-height: 1.55; }
.help-example {
    background: var(--code-bg, #f0f2f5);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 12px 14px;
    font-family: var(--mono, monospace);
    font-size: 12.5px;
    line-height: 1.5;
    white-space: pre;
    overflow-x: auto;
    margin: 12px 0;
}
.help-summary {
    background: var(--accent-soft, #dbe6fe);
    border-radius: 8px;
    padding: 11px 13px;
    font-size: 13.5px;
}
.help-close-row { margin-top: 16px; text-align: right; }
.help-close-btn {
    padding: 9px 20px;
    background: var(--accent);
    color: var(--on-accent);
    border: none;
    border-radius: 8px;
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
}
.help-close-btn:hover { background: var(--accent-strong); }

/* Filtr rozkladu postoju: etykieta "Koszyk co [select] do [input] min" jako
   jeden element flexa .filter-line (label zwija swoja zawartosc w linie). */
.filter-inline {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 14px;
    color: var(--muted, #555);
}
.filter-inline select,
.filter-inline .cap-input {
    padding: 8px 10px;
    border: 1px solid var(--border);
    border-radius: 8px;
    font-size: 14px;
}
.cap-input { width: 76px; }

/* Ostrzezenie inline (np. zawezony prog / zakres) - lzejsze niz .warn-line */
.warn-inline { color: var(--flag-ink); font-weight: 600; }

/* Rozklad postoju: wykres i tabela obok siebie, zwijane na waskim ekranie.
   minmax(0,...) na kolumnie wykresu - inaczej canvas rozpycha siatke. */
.duration-grid {
    display: grid;
    grid-template-columns: minmax(0, 1.4fr) minmax(260px, 1fr);
    gap: 16px;
    /* stretch = obie kolumny rownej wysokosci (wykres dopasowuje sie do tabeli) */
    align-items: stretch;
}
/* obie kolumny: podpis (staly) + tresc (rosnaca). Ta sama struktura po obu
   stronach => gory rowne, a flex rozciaga tresc na pelna wysokosc kolumny. */
.duration-chart-box, .duration-table-box { display: flex; flex-direction: column; }
/* kontener canvasu wypelnia reszte wysokosci po podpisie (rowna tabeli).
   min-height chroni przed splaszczeniem, gdy tabela krotka (malo koszykow). */
.duration-chart-wrap { flex: 1; min-height: 320px; }
/* podpisy obu kolumn bez gornego marginesu - gory kolumn na jednej linii.
   Maly dolny margines oddziela podpis od tresci (wykres/tabela). */
.duration-table-scope { margin-top: 0; margin-bottom: 8px; }
/* tabela dziedziczy margin-top z .data-table - zerujemy TU, by jej gora rownala
   sie z gora rysunku wykresu (oba tuz pod swoim podpisem). */
.duration-table-box .duration-table { margin-top: 0; }
/* tabela koszykow: podsumowanie "Razem" w tfoot wyroznione jak wiersz sumy */
.duration-table tfoot td {
    font-weight: 700;
    background: var(--surface-2);
    border-top: 2px solid var(--border);
}
@media (max-width: 780px) {
    .duration-grid { grid-template-columns: 1fr; }
}

/* Panel sterowania /wizyty-stats: jeden pasek, kontrolki w nazwanych grupach.
   Wszystko co zmienia dane jest tu; wykresy nizej tylko pokazuja wynik. */
/* Karta panelu = ten sam chrome co .filter-form.pt-panel na /dashboard (tokeny
   --pt-*, naglowek "FILTRY" oddzielony linia). Kontrolki zjechaly do wewnetrznego
   .stats-controls-body, bo naglowek karty musi byc PELNYM wierszem - zostawiony
   w tym samym flexie ustawilby sie obok pierwszej grupy pol. */
.stats-controls {
    display: block;
    margin: 16px 0 18px;
    padding: 0;
    background: var(--pt-surface);
    border: 1px solid var(--pt-line);
    border-radius: var(--pt-radius);
    box-shadow: var(--pt-shadow);
}
.stats-controls-body {
    display: flex;
    align-items: flex-end;
    flex-wrap: wrap;
    gap: 18px;
    padding: 16px 18px;
}
.control-group { display: flex; flex-direction: column; gap: 6px; }
.control-group-grow { flex: 1 1 220px; }  /* wybor parkingow bierze wolne miejsce */
/* mala etykieta nad grupa - grupuje kontrolki w logiczna calosc */
.control-label {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--muted);
}
.control-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.control-row select {
    padding: 8px 10px;
    border: 1px solid var(--border);
    border-radius: 8px;
    font-size: 14px;
    background: var(--panel);
}
/* przycisk "Pokaz" - JEDYNY sposob zatwierdzenia filtrow (zadne pole nie
   przeladowuje strony samo).
   DWA STANY, celowo bardzo rozne wizualnie:
   - spoczynek (ekran zgadza sie z panelem) - stonowany, bo klikniecie niczego
     by nie zmienilo; staly akcent tylko halasowal i nie niosl informacji,
   - .is-dirty - pelny akcent, zeby bylo widac, ze JEST co wyswietlic.
   Ramka 1px w OBU stanach (nie border:none + border w dirty) - inaczej przycisk
   zmienialby szerokosc i przeskakiwal w linii akcji. */
.control-submit {
    padding: 8px 16px;
    background: var(--surface-2);
    color: var(--muted);
    border: 1px solid var(--border);
    border-radius: 8px;
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.control-submit:hover { border-color: var(--accent); color: var(--ink); }
/* .is-dirty = w panelu sa zmiany, ktorych serwer jeszcze nie widzial. Bez
   auto-submitu nic innego tego nie sygnalizuje, a uzytkownik patrzy wtedy na
   liczby sprzed swojego wyboru (stats-controls.js::markDirty). */
.control-submit.is-dirty {
    background: var(--accent);
    color: var(--on-accent);
    border-color: var(--accent);
    animation: control-submit-wake 0.4s ease;
}
.control-submit.is-dirty:hover {
    background: var(--accent-strong);
    border-color: var(--accent-strong);
    color: var(--on-accent);
}
@keyframes control-submit-wake {
    from { transform: scale(1); }
    50%  { transform: scale(1.05); }
    to   { transform: scale(1); }
}
@media (prefers-reduced-motion: reduce) {
    .control-submit.is-dirty { animation: none; }
}
/* Akcje panelu (Pokaz + Reset) trzymane razem, dosuniete do prawej krawedzi
   paska (margin-left:auto odpycha je na koniec flexa .stats-controls-body). */
.control-actions {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-left: auto;
}
/* Reset filtrow: lzejszy niz "Pokaz" - to akcja porzucenia, nie glowna.
   Link stylizowany na przycisk (dziala bez JS, prowadzi na goly /wizyty-stats). */
.control-reset {
    padding: 8px 14px;
    background: transparent;
    color: var(--muted);
    border: 1px solid var(--border);
    border-radius: 8px;
    font-size: 14px;
    text-decoration: none;
    white-space: nowrap;
}
.control-reset:hover { border-color: var(--danger); color: var(--danger); }
/* Eksport Excel: zielony outline (jak w Wizytach API / Dashboardzie) */
.control-export {
    padding: 8px 14px;
    background: var(--panel);
    color: var(--good);
    border: 1px solid var(--good);
    border-radius: 8px;
    font-size: 14px;
    font-weight: 500;
    cursor: pointer;
    white-space: nowrap;
}
.control-export:hover { background: var(--good); color: var(--panel); }
/* wylaczony, gdy w panelu sa niezatwierdzone zmiany - plik nie zgadzalby sie
   z ekranem (stats-controls.js::markDirty) */
.control-export:disabled {
    opacity: 0.45;
    cursor: not-allowed;
}
.control-export:disabled:hover { background: var(--panel); color: var(--good); }
/* wybor parkingow w panelu: toggle pelnej szerokosci grupy, panel wysuwa w PRAWO
   (w toolbarze wykresu bylo right:0; tu grupa jest po lewej) */
.stats-controls .chart-pick { width: 100%; }
.stats-controls .chart-pick-toggle { width: 100%; }
.stats-controls .chart-pick-panel { left: 0; right: auto; }

/* =========================================================================
   DASHBOARD — "spokojny panel operacyjny" (2026-07-12)
   Tokeny --pt-* to teraz ALIASY na wspólne tokeny produktu (zdefiniowane w
   głównym :root wyżej), więc Dashboard dziedziczy oba motywy automatycznie -
   bez własnego bloku ciemnego. Neutrale z odchyłem ku indygo; jeden stonowany
   akcent. Sygnatura: micro-bary tła w komórkach liczb.
   ========================================================================= */

/* Naglowek strony */
.page-head { margin-bottom: 20px; }
.page-head h1 {
    margin: 0 0 4px;
    font-size: 25px;
    font-weight: 700;
    letter-spacing: -0.015em;
    text-wrap: balance;
}
.page-sub { margin: 0; color: var(--pt-muted); font-size: 14px; max-width: 64ch; }

/* Pasek podsumowania — 4 kafle, odczyt jednym rzutem oka przed tabela */
.pt-summary {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: 14px;
    margin-bottom: 18px;
}
.pt-stat {
    position: relative;
    overflow: hidden;
    background: var(--pt-surface);
    border: 1px solid var(--pt-line);
    border-radius: var(--pt-radius);
    padding: 15px 18px;
    box-shadow: var(--pt-shadow);
}
/* listwa akcentu na pierwszym kaflu = glowna metryka */
.pt-stat.is-primary::before {
    content: "";
    position: absolute; left: 0; top: 0; bottom: 0;
    width: 3px; background: var(--pt-accent);
}
.pt-stat .k {
    display: block;
    font-size: var(--pt-fs-label);
    text-transform: uppercase;
    letter-spacing: var(--pt-ls-label);
    font-weight: 700;
    color: var(--pt-muted);
    margin-bottom: 6px;
}
.pt-stat .v {
    display: block;
    font-size: 27px;
    font-weight: 700;
    line-height: 1.05;
    letter-spacing: -0.02em;
    font-variant-numeric: tabular-nums;
    color: var(--pt-ink);
}
.pt-stat .sub { display: block; font-size: 12.5px; color: var(--pt-muted); margin-top: 3px; }

/* Panel filtrow jako karta z tytulem. Nadpisuje wczesniejszy .filter-form
   (goly rzad kontrolek) - teraz karta z naglowkiem. */
.filter-form.pt-panel {
    display: block;
    background: var(--pt-surface);
    border: 1px solid var(--pt-line);
    border-radius: var(--pt-radius);
    box-shadow: var(--pt-shadow);
    padding: 0;
    margin-top: 16px;
    margin-bottom: 18px;
}
.pt-panel-head {
    display: flex; align-items: center; gap: 8px;
    padding: 12px 18px;
    border-bottom: 1px solid var(--pt-line-soft);
}
.pt-panel-head .t {
    font-size: var(--pt-fs-label);
    text-transform: uppercase;
    letter-spacing: var(--pt-ls-label);
    font-weight: 700;
    color: var(--pt-muted);
}
.pt-filters {
    display: flex;
    gap: 18px;
    align-items: flex-end;
    flex-wrap: wrap;
    padding: 16px 18px;
}
/* etykieta filtra: wieksza, uppercase - rytm "panelu operacyjnego" */
.filter-form.pt-panel .field > label {
    font-size: var(--pt-fs-label);
    text-transform: uppercase;
    letter-spacing: var(--pt-ls-label);
    font-weight: 600;
    color: var(--pt-muted);
}
/* "Pokaz" jest CICHY, dopoki w filtrach nic sie nie zmienilo. Akcent na tym
   przycisku ZNACZY „masz niezastosowane zmiany" (.is-dirty nadawane w
   dashboard.js) - ten sam mechanizm co .control-submit na /wizyty-stats.
   Wczesniej swiecil indygo zawsze, wiec nie niosl zadnej informacji. */
.filter-form.pt-panel button[type="submit"] {
    background: var(--pt-surface-3);
    color: var(--pt-muted);
    border: 1px solid var(--pt-line);
    border-radius: var(--pt-radius-sm);
    font-weight: 600;
    cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.filter-form.pt-panel button[type="submit"]:hover {
    border-color: var(--pt-accent);
    color: var(--pt-ink);
}
.filter-form.pt-panel button[type="submit"].is-dirty {
    background: var(--pt-accent);
    border-color: var(--pt-accent);
    color: var(--on-accent);
    animation: control-submit-wake 0.4s ease;
}
.filter-form.pt-panel button[type="submit"].is-dirty:hover {
    background: var(--pt-accent-strong);
    border-color: var(--pt-accent-strong);
    color: var(--on-accent);
}
/* Excel: ikona + tekst w jednej linii */
.filter-form.pt-panel .btn-export { gap: 7px; }

/* Karta (wspolna: wykres, tabela) */
.pt-card {
    background: var(--pt-surface);
    border: 1px solid var(--pt-line);
    border-radius: var(--pt-radius);
    box-shadow: var(--pt-shadow);
    margin-bottom: 18px;
    overflow: hidden;
}
.pt-card-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
    padding: 13px 18px;
    border-bottom: 1px solid var(--pt-line-soft);
    flex-wrap: wrap;
}
.pt-card-title {
    display: inline-flex; align-items: center; gap: 9px;
    font-size: 14px; font-weight: 600; color: var(--pt-ink);
}
.pt-card-title .ico { color: var(--pt-accent); display: inline-flex; }
.pt-card-meta { font-size: 13px; color: var(--pt-muted); }
.pt-card-foot {
    display: flex; align-items: center; justify-content: space-between;
    padding: 11px 18px; border-top: 1px solid var(--pt-line-soft);
    font-size: 13px; color: var(--pt-muted); flex-wrap: wrap; gap: 8px;
}
.pt-card-foot strong { color: var(--pt-ink-soft); }
.pt-card-foot a { color: var(--pt-accent); text-decoration: none; font-weight: 600; }
.pt-card-foot a:hover { text-decoration: underline; }

/* Karta wykresu bazuje na <details class="pt-card chart-details">. summary to
   pt-card-head - reset domyslnego markera <summary> (trojkacik), bo mamy tytul */
.chart-details.pt-card { margin: 8px 0 18px; }
.chart-details.pt-card > summary.chart-summary {
    cursor: pointer;
    list-style: none;
    /* nadpisuje stary .chart-summary (szara pigulka) - teraz to naglowek karty */
    background: transparent;
    border: none;
    border-bottom: 1px solid var(--pt-line-soft);
    border-radius: 0;
    padding: 13px 18px;
    width: auto;
    color: var(--pt-ink);
}
.chart-details.pt-card > summary::-webkit-details-marker { display: none; }
.chart-details.pt-card[open] > summary.chart-summary { margin-bottom: 0; }
.chart-details.pt-card .chart-section { padding: 18px; }
/* rozklad postoju ma wlasny kontener (wykres + tabela obok) - bez tego tresc
   dotykalaby krawedzi karty, bo padding siedzi tylko na .chart-section */
.chart-details.pt-card .duration-section { padding: 18px; }
.chart-details.pt-card .chart-toolbar { margin-bottom: 14px; }
/* przelacznik typu wykresu w nowym akcencie */
.chart-details.pt-card .chart-type-btn.is-active {
    background: var(--pt-accent);
    border-color: var(--pt-accent);
    color: var(--on-accent);
}

/* Tabela dashboardu — przemalowanie na nowy jezyk. Tylko .dashboard-table
   (NIE bazowa .data-table wspoldzielona z innymi ekranami). Tabela jest teraz
   w .pt-card, wiec zerujemy jej wlasna ramke/margines/cien (karta je daje). */
.pt-card .dashboard-table {
    border: none;
    border-radius: 0;
    margin-top: 0;
    background: var(--pt-surface);
    font-size: 13.5px;
    color: var(--pt-ink);
}
.pt-card .table-wrap {
    /* w karcie tabela scrolluje w obrebie karty, nie full-bleed jak dawniej */
    width: auto;
    margin: 0;
}
.dashboard-table thead th {
    background: var(--pt-surface-3);
    color: var(--pt-muted);
    font-size: var(--pt-fs-label);
    text-transform: uppercase;
    letter-spacing: var(--pt-ls-label);
    font-weight: 700;
    border-bottom: 1px solid var(--pt-line);
}
.dashboard-table thead .head-totals th {
    background: var(--pt-surface-2);
    color: var(--pt-ink);
    text-transform: none;
    letter-spacing: normal;
    font-size: 13px;
    border-bottom: 2px solid var(--pt-line);
}
.dashboard-table thead th:first-child,
.dashboard-table tfoot td:first-child { background: var(--pt-surface-3); }
.dashboard-table thead .head-totals th:first-child { background: var(--pt-surface-2); }
.dashboard-table th:first-child,
.dashboard-table td:first-child {
    background: var(--pt-surface);
    box-shadow: 1px 0 0 var(--pt-line-soft);
}
.dashboard-table td, .dashboard-table th { border-bottom: 1px solid var(--pt-line-soft); }
/* zebra + hover w tonacji indygo */
.dashboard-table tbody tr:nth-child(even) td,
.dashboard-table tbody tr:nth-child(even) td:first-child { background: var(--pt-surface-2); }
.dashboard-table tbody tr:hover td,
.dashboard-table tbody tr:hover td:first-child { background: var(--pt-accent-soft); }
/* kolumna "Razem" — kotwica wiersza */
.dashboard-table td.grand, .dashboard-table th.grand {
    font-weight: 700;
    background: var(--pt-surface-3);
    border-left: 2px solid var(--pt-line);
}
.dashboard-table tbody tr:hover td.grand { background: var(--pt-accent-soft); }
.dashboard-table thead .head-totals td.grand,
.dashboard-table thead th.grand { background: var(--pt-surface-3); }

/* pusta komorka (brak wpisow) — przygaszona kropka, nie pusto */
.dashboard-table .cell-empty { color: var(--pt-muted); }

/* Ciemny motyw Dashboardu wychodzi SAM: tokeny --pt-* to aliasy wspólnych
   tokenów produktu (główny :root), które przełącza @media/data-theme. Bez
   osobnego bloku ciemnego tutaj. */

@media (max-width: 720px) {
    .pt-filters { flex-direction: column; align-items: stretch; }
    .filter-form.pt-panel .field-actions { margin-left: 0; }
}

/* =========================================================================
   Recydywiści — lista numerów często trafiających do procesu (ParkAway).
   Wszystko przez wspólne tokeny, więc oba motywy wychodzą same.
   ========================================================================= */

/* pole progu "Min. trafień" - wąskie (to liczba, nie długi tekst) */
.filter-form .num-input { width: 110px; }

/* hover + rozwinięty wiersz (na wzór dashboardu, ale prościej) */
.recid-table tbody tr.main:hover td { background: var(--surface-2); }
.recid-table tbody tr.main.open td { background: var(--accent-soft); }

/* Numer jako chip — to kod, więc monospace jak hashe/ID w Wizytach */
.plate {
    display: inline-block;
    font-family: var(--mono, ui-monospace, "SF Mono", Menlo, Consolas, monospace);
    font-weight: 600;
    font-size: 13.5px;
    letter-spacing: .03em;
    padding: 3px 8px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 6px;
    color: var(--ink);
    font-variant-numeric: tabular-nums;
}

/* Kolumna "Trafień": liczba + pasek długości proporcjonalny do rekordu.
   Kodowanie częstości formą, nie tylko liczbą (najczęstsze rzucają się w oczy). */
.recid-table td.count-cell { position: relative; width: 120px; }
.count-bar {
    position: absolute;
    left: 0; top: 6px; bottom: 6px;
    background: var(--accent-wash);
    border-left: 2px solid var(--accent);
    border-radius: 0 4px 4px 0;
}
.count-val {
    position: relative;
    display: block;
    text-align: right;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    padding-right: 2px;
}
.recid-table td.when { font-variant-numeric: tabular-nums; color: var(--ink-soft); white-space: nowrap; }

/* Kolumna parkingów + przycisk rozwinięcia */
.park-cell { display: flex; align-items: center; gap: 10px; }
.park-name { color: var(--ink-soft); }
/* kod parkingu przy nazwie — drugorzędny, monospace jak inne identyfikatory */
.park-code {
    margin-left: 6px;
    padding: 1px 5px;
    border-radius: 4px;
    background: var(--surface-2);
    color: var(--muted);
    font-family: var(--mono, ui-monospace, "SF Mono", Menlo, Consolas, monospace);
    font-size: 11.5px;
}
/* Inicjały CM (region) — mocniejsze niż kod parkingu, bo to wymiar, po którym
   się filtruje, a nie identyfikator techniczny. Akcent w wersji stonowanej,
   żeby przy kilkudziesięciu wierszach nie krzyczał z każdej linii. */
.cm-tag {
    display: inline-block;
    padding: 1px 7px;
    border-radius: 999px;
    background: var(--accent-wash);
    color: var(--accent);
    font-size: 11.5px;
    font-weight: 700;
    letter-spacing: .04em;
}
.park-more {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    cursor: pointer;
    white-space: nowrap;
    padding: 2px 9px;
    font-size: 12px;
    font-weight: 600;
    font-family: inherit;
    color: var(--accent);
    background: var(--accent-soft);
    border: 1px solid transparent;
    border-radius: 20px;
}
.park-more:hover { border-color: var(--accent); }
.park-more .chev { transition: transform .16s; font-size: 10px; }
.park-more[aria-expanded="true"] .chev { transform: rotate(90deg); }

/* Wiersz szczegółów: rozbicie trafień na parkingi */
.recid-table tr.detail > td { padding: 0; background: var(--surface-2); }
.breakdown { padding: 6px 14px 12px 30px; }
.breakdown-head {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--muted);
    margin: 8px 0 6px;
}
.bd-row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 6px 0;
    border-top: 1px dashed var(--border);
    font-size: 13.5px;
}
.bd-row:first-of-type { border-top: none; }
.bd-park { flex: 1; color: var(--ink); }
.bd-count { font-weight: 700; font-variant-numeric: tabular-nums; min-width: 34px; text-align: right; color: var(--accent); }
.bd-when { color: var(--muted); font-variant-numeric: tabular-nums; min-width: 118px; text-align: right; }

@media (prefers-reduced-motion: reduce) {
    .park-more .chev { transition: none; }
}

/* =========================================================================
   Scalanie parkingów — ekran potwierdzenia (parkingi_scal.html).
   Dwie karty obok siebie, żeby różnicę między wpisami dało się złapać
   wzrokiem: to decyzja nieodwracalna, więc porównanie musi być dosłowne.
   ========================================================================= */

.merge-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 16px;
    margin: 18px 0;
}
/* Karty rysujemy tu jawnie: `.pt-panel` NIE ma bazowej definicji w tym pliku
   (istnieje tylko nadpisanie `.filter-form.pt-panel`), wiec samo dopisanie tej
   klasy zostawiloby plaski tekst na tle strony. Tokeny --pt-* jak w `.pt-card`. */
.merge-card,
.merge-form {
    background: var(--pt-surface);
    border: 1px solid var(--pt-line);
    border-radius: var(--pt-radius);
    box-shadow: var(--pt-shadow);
}
.merge-card { padding: 16px 18px; }
.merge-role {
    margin: 0 0 6px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--muted);
}
.merge-name { margin: 0 0 12px; font-size: 15px; font-weight: 600; color: var(--ink); }

/* etykieta/wartość w dwóch kolumnach — czyta się jak metryczka, nie jak zdanie */
.merge-facts {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 6px 14px;
    margin: 0;
    font-size: 13.5px;
}
.merge-facts dt { color: var(--muted); }
.merge-facts dd { margin: 0; color: var(--ink); font-variant-numeric: tabular-nums; }

.merge-form { padding: 16px 18px; }
.merge-choice { border: none; margin: 0 0 12px; padding: 0; }
.merge-choice legend {
    padding: 0;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--muted);
}
.merge-choice label {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 7px 0;
    cursor: pointer;
    color: var(--ink);
}
.merge-effect {
    margin: 0 0 14px;
    padding: 10px 12px;
    background: var(--surface-2);
    border-left: 3px solid var(--accent);
    border-radius: 4px;
    font-size: 13.5px;
    color: var(--ink);
}
/* `button.primary` ma globalnie width:100% (dziedziczy regule z login-boxa),
   wiec tu ja zdejmujemy - przycisk ma byc wielkosci akcji, nie calej karty. */
.merge-actions { display: flex; align-items: center; gap: 14px; }
.merge-actions button.primary { width: auto; padding: 10px 22px; }
/* furtka przy kolizji CC — świadomie lekka, to wyjście awaryjne, nie główna droga */
.merge-override { margin-top: 14px; }

@media (max-width: 720px) {
    .merge-grid { grid-template-columns: 1fr; }
}

/* ─────────────────────────────────────────────────────────────
   Decyzje CM: „windykuj" / „biała lista" przed windykacją.
   Dwa miejsca, wspólne tokeny: kolumna na /recydywisci i ekran
   Contract Managera pod podpisanym linkiem (/lista-cm/<CM>).
   ───────────────────────────────────────────────────────────── */

/* Kolor NIESIE znaczenie: zielony = numer zostaje w spokoju (biała lista),
   czerwony = idzie do windykacji. Dlatego tokeny good/danger, a nie neutralne
   szarości - to jedyna kolumna, w której trzeba rozpoznać stan na rzut oka. */
.decision-tag {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 2px 4px 2px 8px;
    border-radius: 999px;
    font-size: 11.5px;
    font-weight: 600;
    white-space: nowrap;
}
.decision-tag + .decision-tag { margin-left: 5px; }
.decision-white { background: var(--good-soft); color: var(--good-ink); }
.decision-enforce { background: var(--danger-soft); color: var(--danger-ink); }
/* Region przy decyzji jest KONIECZNY, nie ozdobny: ten sam numer bywa oceniony
   różnie w dwóch regionach i bez inicjałów wyglądałoby to na sprzeczność. */
.decision-cm {
    font-weight: 800;
    letter-spacing: .04em;
    opacity: .75;
}
.decision-cell { white-space: normal; }
/* Cofnięcie decyzji - dyskretne, bo to wyjątek, nie codzienna akcja */
.decision-undo { display: inline; }
.decision-undo button {
    width: 18px;
    height: 18px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: inherit;
    opacity: .45;
    font-size: 13px;
    line-height: 1;
    cursor: pointer;
}
.decision-undo button:hover { opacity: 1; background: rgba(0, 0, 0, .08); }

/* Powrót numeru mimo białej listy — sprawy dopisane PO decyzji CM.
   Kolory ostrzegawcze (--flag-*, jak badge wstecznego startu), nie --danger:
   to nie awaria ani błąd, tylko robota do wykonania po stronie CM. Stoi POD
   decyzją i w nowej linii, bo decyzja nadal obowiązuje — zmienia się wyłącznie
   to, że nie zadziałała. */
.decision-back {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-top: 4px;
    padding: 2px 4px 2px 8px;
    border-radius: 999px;
    background: var(--flag-soft);
    border: 1px solid var(--flag-line);
    color: var(--flag-ink);
    font-size: 11.5px;
    font-weight: 600;
    white-space: nowrap;
}
.decision-cell .decision-back { display: flex; width: fit-content; }
.back-when { font-weight: 500; opacity: .8; }
/* Odhaczenie jest tekstem, nie krzyżykiem jak przy cofaniu decyzji: tamto jest
   nieodwracalne, a to tylko wycisza sygnał do następnej sprawy. */
.decision-checked { display: inline; }
.decision-checked button {
    padding: 1px 7px;
    border: 1px solid var(--flag-line);
    border-radius: 999px;
    background: transparent;
    color: inherit;
    font-size: 11px;
    font-weight: 600;
    line-height: 1.5;
    cursor: pointer;
}
.decision-checked button:hover { background: rgba(0, 0, 0, .07); }
/* Kafel pojawia się tylko wtedy, gdy coś wróciło — obramowanie ma go wyróżnić
   w rzędzie neutralnych liczb. */
.stat-alert { border-color: var(--flag-line); background: var(--flag-soft); }
.stat-alert .stat-label, .stat-alert .stat-num { color: var(--flag-ink); }

/* „Czeka ≥ N dni" — stoi tam, gdzie normalnie jest decyzja. Neutralne szarości,
   bo samo czekanie nie jest jeszcze problemem; kolor dochodzi dopiero po dwóch
   tygodniach (.is-old), żeby wyróżnienie znaczyło „to już za długo". */
.waiting-tag, .cm-waiting {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 999px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    color: var(--muted);
    font-size: 11.5px;
    font-weight: 600;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}
.waiting-tag.is-old, .cm-waiting.is-old {
    background: var(--flag-soft);
    border-color: var(--flag-line);
    color: var(--flag-ink);
}

/* Historia decyzji w rozwiniętym wierszu — pod rozbiciem na parkingi. */
.decision-history { margin-top: 10px; }
.decision-history .bd-park { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.hist-note { font-size: 12.5px; color: var(--muted); font-style: italic; }
.hist-source { font-size: 11.5px; color: var(--muted); font-weight: 600; }
/* Cofnięcie decyzji zapisujemy jako osobny krok — przekreślenie mówi „to już
   nie obowiązuje" bez dokładania kolejnego koloru do i tak gęstego wiersza. */
.hist-undone {
    font-size: 12px;
    font-weight: 600;
    color: var(--muted);
    text-decoration: line-through;
}

/* Panel „Linki dla CM" na /recydywisci */
.cm-links { margin-bottom: 18px; }
.cm-links > summary { cursor: pointer; list-style: none; }
.cm-links > summary::-webkit-details-marker { display: none; }
.cm-links-note { margin: 10px 14px 4px; }
.cm-links-list { padding: 4px 14px 14px; display: grid; gap: 8px; }
.cm-link-row { display: flex; align-items: center; gap: 10px; }
.cm-link-url {
    flex: 1;
    min-width: 0;
    padding: 6px 10px;
    font-family: var(--mono, ui-monospace, Menlo, Consolas, monospace);
    font-size: 12px;
    color: var(--muted);
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 6px;
}
.cm-link-copy {
    padding: 6px 14px;
    font-size: 12.5px;
    font-weight: 600;
    font-family: inherit;
    color: var(--accent);
    background: var(--accent-soft);
    border: 1px solid transparent;
    border-radius: 6px;
    cursor: pointer;
}
.cm-link-copy:hover { border-color: var(--accent); }
.cm-link-copy.is-done { background: var(--good-soft); color: var(--good-ink); }

/* ── Ekran Contract Managera (/lista-cm/<CM>) ──
   Osobny odbiorca: wchodzi z maila, klika raz na kilka tygodni, nie zna
   aplikacji. Stąd lista kart zamiast tabeli - decyzja ma być przy numerze,
   a nie w kolumnie, którą trzeba znaleźć wzrokiem. */
.topbar-guest .links { display: flex; align-items: center; gap: 14px; }
.cm-list { display: grid; gap: 2px; padding: 4px 0 6px; }
.cm-item {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: 10px 18px;
    padding: 12px 16px;
    border-top: 1px solid var(--border);
}
.cm-item:first-child { border-top: 0; }
.cm-item.is-decided { background: var(--surface-2); }
.cm-row-head { display: flex; align-items: baseline; gap: 14px; }
.cm-hits {
    font-size: 13px;
    font-weight: 700;
    color: var(--ink);
    font-variant-numeric: tabular-nums;
}
/* Suma przez wszystkie regiony — drugorzędna wobec „u Ciebie", bo decyzji nie
   podpiera; ma tylko sygnalizować, że auto jeździ też gdzie indziej. */
.cm-total {
    font-size: 12px;
    color: var(--muted);
    padding: 1px 7px;
    border-radius: 999px;
    background: var(--surface-3);
}
.cm-when { font-size: 12px; color: var(--muted); }
.cm-parks {
    grid-column: 1;
    display: flex;
    flex-wrap: wrap;
    gap: 6px 12px;
    font-size: 12.5px;
    color: var(--muted);
}
.cm-park em { font-style: normal; font-weight: 700; opacity: .8; }
.cm-note { font-size: 12.5px; color: var(--muted); font-style: italic; }
.cm-current { grid-column: 1; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.cm-empty { padding: 12px 16px; }
.cm-decided { margin-top: 18px; }
.cm-decided > summary { cursor: pointer; list-style: none; }
.cm-decided > summary::-webkit-details-marker { display: none; }
/* Sekcja „Wróciły mimo białej listy" — nad listą do decyzji. Wyróżniona ramką,
   bo to jedyne miejsce na tym ekranie, gdzie coś poszło nie tak; sam nagłówek
   ginąłby wśród identycznych kart. */
.cm-returned { margin-bottom: 18px; border-color: var(--flag-line); }
.cm-returned > .pt-panel-head { color: var(--flag-ink); background: var(--flag-soft); }
.cm-returned-note { padding: 12px 16px 0; margin: 0; }
.cm-item.is-returned { background: var(--flag-soft); }

/* Formularz decyzji: notatka + dwa przyciski. Grid-row 1/3, żeby przy wąskim
   oknie zjechał pod numer zamiast ściskać nazwy parkingów. */
.decide-form {
    grid-row: 1 / span 2;
    grid-column: 2;
    display: flex;
    align-items: center;
    gap: 8px;
}
.decide-note {
    width: 190px;
    padding: 7px 10px;
    font-size: 13px;
    color: var(--ink);
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: 6px;
}
.decide-btn {
    padding: 8px 16px;
    font-size: 13px;
    font-weight: 600;
    font-family: inherit;
    border: 1px solid transparent;
    border-radius: 6px;
    cursor: pointer;
}
.decide-enforce { background: var(--danger-soft); color: var(--danger-ink); }
.decide-white { background: var(--good-soft); color: var(--good-ink); }
.decide-enforce:hover { border-color: var(--danger); }
.decide-white:hover { border-color: var(--good); }
/* Która decyzja obowiązuje TERAZ - widoczne w sekcji „już zdecydowane",
   żeby zmiana zdania nie była zgadywanką. */
.decide-btn.is-current { outline: 2px solid currentColor; outline-offset: 1px; }

.cm-denied { max-width: 520px; margin: 40px auto; padding: 28px 30px; }

/* ===== Przypomnienie przed zapisem białej listy =====
   Ta sama treść leci w oknie na liście i na stronie potwierdzenia (droga bez
   JS), więc typografia siedzi w klasach `cm-ack-*` wspólnych dla obu - inaczej
   ten sam tekst wyglądałby jak dwa różne komunikaty.

   ZAŁOŻENIE UKŁADU: cały ciężar niesie TABLICA, reszta jest cicha. Numer jest
   podmiotem decyzji („czy TEN samochód ma stać u mnie"), a wcześniejsza wersja
   traktowała go jak drobną etykietę przy tekście - okno czytało się wtedy jak
   ostrzeżenie systemowe bez konkretu i dwa razy z rzędu wróciło jako „słabo
   widoczne" (2026-07-28). Odwrotność też była zła: czerwony bold na całości
   wyglądał jak komunikat błędu.
   Okno dziedziczy pudełko po `.action-dialog` (okna akcji ParkAway). */
.cm-ack-dialog { max-width: 460px; padding: 28px 30px 26px; }
.cm-ack-dialog::backdrop { background: rgba(0, 0, 0, 0.55); }

/* Nadpis mówi, o jakim rozstrzygnięciu jest okno - bez niego nagłówek musiałby
   powtarzać „biała lista" i konkurować z tablicą o uwagę. */
.cm-ack-eyebrow {
    margin: 0 0 14px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--danger);
}

.cm-ack-plate { margin: 0 0 18px; }
/* SYGNATURA OKNA: chip rysowany jak prawdziwa tablica - jasne pole, monospace
   i granatowa euro-banda z „PL". Nie jest to ozdoba: to jedyny element, po
   którym CM od razu wie, którego auta dotyczy pytanie, więc dostaje pełną
   skalę i kontrast. Kolory celowo NIE zmieniają się z motywem - tablica
   wygląda jak tablica także w ciemnym UI. */
.plate-lg {
    position: relative;
    padding: 9px 14px 9px 34px;
    font-size: 23px;
    letter-spacing: .06em;
    border-radius: 7px;
    background: #f7f8fa;
    color: #14181f;
    border: 1px solid #c9d0da;
    box-shadow: 0 1px 2px rgba(0, 0, 0, .18);
}
.plate-lg::before {
    content: "PL";
    position: absolute;
    top: 0; left: 0; bottom: 0;
    width: 24px;
    display: flex;
    align-items: flex-end;
    justify-content: center;
    padding-bottom: 5px;
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 0;
    color: #ffffff;
    background: #1a3a8f;
    border-radius: 6px 0 0 6px;
}

.cm-ack-head {
    margin: 0 0 16px;
    font-size: 19px;
    font-weight: 650;
    line-height: 1.3;
    color: var(--ink);
}

/* Zadania: pełny kontrast i waga 600 - czytają się mocno, ale nie jak błąd.
   Czerwień została TYLKO w licznikach; niesie tam sygnał „to jest robota",
   nie zabierając czytelności samej treści. Liczniki rysuje ::before, bo
   ::marker nie przyjmuje tła ani ramki. */
.cm-ack-list {
    margin: 0;
    padding: 0;
    list-style: none;
    counter-reset: cmack;
    display: grid;
    gap: 14px;
    font-size: 15px;
    font-weight: 600;
    line-height: 1.45;
    color: var(--ink);
}
.cm-ack-list li {
    counter-increment: cmack;
    display: grid;
    grid-template-columns: 26px 1fr;
    gap: 12px;
    align-items: start;
}
.cm-ack-list li::before {
    content: counter(cmack);
    display: flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    font-size: 13px;
    font-weight: 700;
    color: var(--danger-ink);
    background: var(--danger-soft);
    border-radius: 7px;
}

.cm-ack-actions {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-top: 24px;
}
/* Przycisk akceptacji: PEŁNY akcent produktu, nie pastel z .decide-white
   (ta klasa jest zaprojektowana pod rząd DWÓCH równorzędnych decyzji przy
   numerze - w oknie jasnozielone tło zlewało się z panelem). Indygo zamiast
   zieleni świadomie: zieleń znaczy w tym UI „gotowe/aktywne", a tutaj klik
   jest PRZYJĘCIEM OBOWIĄZKÓW, nie potwierdzeniem sukcesu. Zielony przycisk
   pod czerwoną listą dawał też dwa sprzeczne sygnały w jednym oknie. */
.cm-ack-actions .decide-btn {
    padding: 12px 22px;
    font-size: 14px;
    font-weight: 650;
    background: var(--accent);
    color: var(--on-accent);
    border-color: var(--accent);
}
.cm-ack-actions .decide-btn:hover { background: var(--accent-strong); border-color: var(--accent-strong); }
/* „Anuluj" jako wyjście drugorzędne. Nadpisanie `margin` jest konieczne:
   .action-dialog .dialog-cancel ustawia `margin: 16px auto 0` (tam przycisk
   stoi sam pod formularzem), co w tym rzędzie odpychałoby go na środek. */
.cm-ack-actions .dialog-cancel {
    margin: 0;
    padding: 12px 14px;
    font-family: inherit;
    font-size: 13.5px;
    color: var(--muted);
    background: none;
    border: 0;
    border-radius: 6px;
    cursor: pointer;
}
.cm-ack-actions .dialog-cancel:hover { color: var(--ink); background: var(--surface-2); }

/* Wejście okna: jeden ruch, nie zestaw efektów. Ma zaznaczyć, że coś się
   zatrzymało i czeka - stąd krótko i bez odbicia. */
@keyframes cm-ack-in {
    from { opacity: 0; transform: translateY(8px) scale(.985); }
    to { opacity: 1; transform: none; }
}
.cm-ack-dialog[open] { animation: cm-ack-in 160ms ease-out; }
@media (prefers-reduced-motion: reduce) {
    .cm-ack-dialog[open] { animation: none; }
}

/* Strona potwierdzenia (bez JS) - to samo wnętrze w karcie zamiast okna. */
.cm-ack-page { max-width: 480px; margin: 40px auto; padding: 30px 32px; }
.cm-ack-back { margin: 18px 0 0; font-size: 13px; }

@media (max-width: 720px) {
    .cm-item { grid-template-columns: 1fr; }
    .decide-form { grid-row: auto; grid-column: 1; flex-wrap: wrap; }
    .decide-note { width: 100%; }
}

/* --- Konta uzytkownikow (ekrany /uzytkownicy) ------------------------------
   Karty rysowane JAWNIE z tokenow, nie przez `pt-panel` - ta klasa nie ma
   reguly bazowej (istnieje tylko nadpisanie `.filter-form.pt-panel`), wiec
   samo jej dopisanie dalo by plaski tekst bez tla. Wzor: `.pt-card`. */
.ok-line {
    color: var(--good-ink);
    background: var(--good-soft);
    border: 1px solid var(--good);
    border-radius: 8px;
    padding: 9px 13px;
    font-size: 14px;
    margin-bottom: 14px;
}
.warn-text { color: var(--flag-ink); font-size: 12px; margin-left: 6px; }
.login-hint { color: var(--muted); font-size: 13px; margin-top: 14px; }

.user-card {
    background: var(--panel);
    color: var(--ink);
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: 18px;
    margin-bottom: 18px;
}
.user-card h2 { font-size: 15px; margin: 0 0 14px; color: var(--ink); }
/* Karta usuwania konta. Sam czerwony przycisk gubil sie posrod pozostalych
   kart - a ta jedyna niesie akcje, ktorej nie da sie cofnac. Tokeny --danger-*
   sa zdefiniowane w OBU motywach, wiec karta nie wymaga wlasnego bloku. */
.user-card.is-danger { border-color: var(--danger); }
.user-card.is-danger h2 { color: var(--danger-ink); }
.user-card > label,
.user-add-form label {
    display: block;
    font-size: 14px;
    color: var(--ink-soft);
    margin-bottom: 12px;
}
/* KRYTYCZNE: kontrolki nie dziedzicza koloru ani tla przez `color-scheme` -
   bez jawnych wartosci tekst ginie bialy-na-bialym w ciemnym motywie. */
.user-card input[type="text"],
.user-card input[type="email"],
.user-card input[type="password"],
.user-card input[type="date"],
.user-card select,
.user-add-form input,
.user-add-form select {
    display: block;
    margin-top: 5px;
    padding: 8px 10px;
    min-width: 260px;
    font-size: 14px;
    color: var(--ink);
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: 8px;
}
.user-card .check-line,
.user-card .check-line input { display: inline-flex; min-width: 0; }
.user-card .check-line {
    align-items: center;
    gap: 8px;
    margin-bottom: 4px;
}
.user-card .muted-line { margin: 0 0 14px; font-size: 12px; }

.user-add-form {
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
    align-items: flex-end;
    margin-bottom: 10px;
}
.user-add-form label { margin-bottom: 0; }

/* --- Ekran uprawnien konta ------------------------------------------------- */
.perm-groups { display: grid; gap: 14px; margin-bottom: 4px; }
.perm-groups.is-locked { opacity: 0.55; }
.perm-group {
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 10px 14px 12px;
}
.perm-group legend {
    font-size: 12px;
    font-weight: 600;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.03em;
    padding: 0 6px;
}
.perm-item { align-items: flex-start; gap: 9px; margin-bottom: 7px; font-size: 14px; }
.perm-item:last-child { margin-bottom: 0; }
.perm-item input { margin-top: 2px; }
.perm-reset { margin-top: 14px; font-size: 14px; }
.perm-admin-note {
    background: var(--flag-soft);
    color: var(--flag-ink);
    border: 1px solid var(--flag-line);
    border-radius: 8px;
    padding: 9px 12px;
    margin-bottom: 14px !important;
}
/* kolumna „Może" na liscie kont - liczba + podglad dwoch pierwszych pozycji */
.perm-cell { white-space: nowrap; }
.perm-cell .perm-peek {
    display: block;
    font-size: 12px;
    color: var(--muted);
    white-space: normal;
    max-width: 260px;
}

/* podpis „kto ostatnio ruszal ten parking" - pod nazwa, nie osobna kolumna
   (tabela parkingow ma ich juz osiem) */
.last-change {
    display: block;
    font-size: 11px;
    color: var(--muted);
    margin-top: 2px;
}
.field-actions { display: flex; gap: 12px; align-items: center; }

/* pola zakresu na ekranie konta: kalendarz i multi-select nie sa <input>, wiec
   nie moga siedziec w <label> jak reszta pol - stad wlasny wiersz z etykieta */
.scope-field { margin-bottom: 12px; }
.scope-label {
    display: block;
    font-size: 14px;
    color: var(--ink-soft);
    margin-bottom: 5px;
}
.user-card .chart-pick { max-width: 520px; }
/* parking bez kodu SSID - widoczny, ale wyraznie drugorzedny */
.chart-pick-item.is-muted > span { color: var(--muted); }

/* Wariant INLINE multi-selecta: lista widoczna od razu, szukajka nad nia.
   Uzywany tam, gdzie wybor jest trescia ekranu (przypisanie parkingow do konta),
   a nie filtrem obok - waski rozwijany panel zawijal dlugie nazwy parkingow
   na dwie linie i zaslanial reszte formularza. */
.chart-pick-inline { max-width: 100%; }
.chart-pick-inline .chart-pick-panel {
    position: static;
    width: 100%;
    max-width: 100%;
    box-shadow: none;
    margin-top: 0;
}
.chart-pick-inline .chart-pick-list { max-height: 340px; }
.chart-pick-inline .chart-pick-item { white-space: nowrap; }
.chart-pick-inline .chart-pick-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
}
.chart-pick-count { font-size: 13px; color: var(--muted); }
