/* panel.css — język wizualny dashboardu (przebudowa 2026-09-16).

   Zastępuje midday.css. Wzorzec: gęsta konsola operatora w rodzaju Sales CRM
   (Kargul Studio) — wiersz 42 px, pismo 12/11,5 (skala w tokenach `--fs-*`), powierzchnie „z fazą" zamiast
   kresek, pigułki w tonie stanu, pastylkowe przyciski — plus reguły z better-ui
   i emil-design-eng: promienie koncentryczne, cień na głębokość a kreska na
   strukturę, przejścia tylko na tym, co się zmienia, wciśnięcie 0,96, wyjścia
   krótsze niż wejścia, zero animacji na skrótach klawiszowych.

   Nazwy klas są te same, co w poprzednim arkuszu — widoki renderowane
   stringami w public/js/widoki/ nie musiały się zmieniać, wymieniamy skórę.
   Poprzedni arkusz leży w kopia-zapasowa/public-2026-09-16-przed-przebudowa-ui/.

   Motyw: :root = jasny, html.dark = ciemny. Wybór zapisuje app.js
   w localStorage; systemowego prefers-color-scheme NIE czytamy —
   właściciel chce jasny jako domyślny niezależnie od ustawień systemu.
   Jeden mechanizm przełączania (klasa), nie dwa. */

:root {
  color-scheme: light;

  /* --- powierzchnie. Trzy stopnie: strona, karta, wnętrze karty. Karta
     odcina się od strony pierścieniem cienia (`--cien-ramka`), nie kreską —
     cień jest półprzezroczysty, więc trzyma się każdego tła. Kreska zostaje
     tam, gdzie DZIELI: wiersze list, nagłówki, pola formularzy. */
  --background: #F2F3F5;
  --card: #FFFFFF;
  --card-2: #F5F6F8;        /* hover wiersza, wnętrza, nagłówki tabel */
  --sidebar: #F5F6F8;        /* = --card-2; #F7F7F9 różnił się o 2 jednostki — niewidoczny bliźniak */
  --foreground: #111214;
  --primary: #16171A;       /* pełne tło elementów „żywych": timer, dymek własny */
  --primary-fg: #FAFAFB;
  --muted: #E6E7EA;         /* tory pasków, szkielety, tła kodu */
  /* Szyna i drobne ikony. Był osobną wartością #626870 (3 jednostki od
     --text-secondary, w ciemnym identyczny) — dwie barwy bliżej niż krok
     rampy to jedna, która się rozjechała. Wskazuje teraz tę samą. */
  --muted-fg: var(--text-secondary);
  --accent: #EDEEF1;        /* tło zaznaczenia w szynie i menu */
  --border: #E4E5E9;
  --border-strong: #CFD1D6;
  --input: #D5D7DC;         /* obrys pola formularza — ciemniejszy od kreski dzielącej */
  /* Zmierzone: 5,9:1 na karcie, 5,3:1 na stronie, 5,1:1 na tle
     zaznaczenia — używane przy 12 px, gdzie próg 4,5:1 obowiązuje w pełni. */
  --text-secondary: #5F6470;

  /* --- akcent: JEDEN kolor na to, co interaktywne — przycisk główny,
     obwódka fokusu, aktywne pole. Indygo jak w serwisie wzorcowym; biały
     tekst ma na nim 7,3:1, więc ta sama wartość służy w obu motywach.
     Nie wchodzi w dane: tam zielony/bursztyn/czerwony niosą znaczenie. */
  --brand: #4124FB;
  --brand-fg: #FFFFFF;
  --brand-hover: #3719E0;
  --brand-soft: rgba(65, 36, 251, .12);
  /* Akcent jako kolor TEKSTU (dziś w kalendarzu, inicjały opiekuna).
     --brand to wypełnienie: na ciemnej karcie ma 2,3:1, więc tekst
     dostaje własny token — w jasnym ta sama wartość, w ciemnym jaśniejsza. */
  --brand-tekst: #4124FB;
  /* Obwódka fokusu ma własny token, bo akcent nie wszędzie ma 3:1 z tym,
     co obok: na białym 7,3:1, ale na ciemnej stronie 2,5:1 — tam trzeba
     jaśniejszego indygo. Zmierzone. */
  --fokus: #4124FB;

  /* --- stan. Każdy w trzech rolach: pełny kolor (kropka, liczba w kaflu),
     tło pigułki, obrys pigułki. Tekst pigułki = pełny kolor: w jasnym
     motywie ten sam odcień czyta się na tincie (ok 4,8:1, warn 5,0:1,
     bad 5,3:1 — zmierzone). */
  --ok: #177A3E;
  --ok-bg: #E6F6EC;
  --ok-border: #BFE6CC;
  --ok-tekst: #177A3E;
  /* Ostrzeżenie w jasnym motywie w trzech odcieniach bursztynu (decyzja
     z 24 września): brąz #8A5F0A był czytelny, ale na białym wyglądał jak
     błąd druku. Grafika (kropki, paski, łuki) bierze jasny #F59E0B, liczby
     od 19 px #D97706 (3,2:1 — próg dla dużego tekstu), drobny tekst #B45309
     (4,5:1 na tle pigułki). Ciemny motyw ma jeden kolor, bo #FBBF24 na
     ciemnym tle jest czytelny w każdym rozmiarze. */
  --warn: #F59E0B;
  --warn-bg: #FEF3C7;
  --warn-border: #FDE68A;
  --warn-tekst: #B45309;
  --warn-duze: #D97706;
  --bad: #BE1F1F;
  --bad-bg: #FDEAEA;
  --bad-border: #F5C4C4;
  --bad-tekst: #BE1F1F;
  --idle: #9A9EA6;
  --neutral-bg: #EDEEF1;      /* = --accent; #EEEFF2 różnił się o 1 jednostkę */
  --neutral-kryjacy: #EDEEF1; /* zasłona przewijania: musi być kryjąca */
  --neutral-border: #E0E2E6;
  --neutral-tekst: #3F434A;

  --hover-bg: #EDEEF1;
  --overlay: rgba(17, 18, 20, .36);
  --chart-grid: #E6E7EA;
  --chart-axis: #6B7078;    /* 5,0:1 na karcie przy 11 px — #7A7F88 miał 4,0 */
  --chart-line: #111214;
  --chart-line-2: #9A9EA6;

  /* --- cienie. Trzy role, trzy tokeny:
     `--cien-ramka`  — pierścień 1 px + lekkie uniesienie: karty i panele
                       (recepta „shadow as border" z better-ui, wersja jasna).
     `--faza`        — powierzchnia sterowania (przycisk, pastylka, pole
                       segmentowane): pierścień + rozjaśnienie górnej krawędzi,
                       żeby element wyglądał na WYPUKŁY, a nie namalowany.
     `--cien-pop`    — to, co naprawdę unosi się nad treścią: menu, arkusz,
                       szukajka, toast. */
  --cien-ramka: 0 0 0 1px rgba(0, 0, 0, .06), 0 1px 2px -1px rgba(0, 0, 0, .06), 0 2px 4px 0 rgba(0, 0, 0, .04);
  --cien-ramka-hover: 0 0 0 1px rgba(0, 0, 0, .09), 0 1px 2px -1px rgba(0, 0, 0, .08), 0 2px 4px 0 rgba(0, 0, 0, .06);
  --faza: 0 0 0 1px rgba(0, 0, 0, .08), 0 1px 1px rgba(0, 0, 0, .04), inset 0 1px 0 rgba(255, 255, 255, .9);
  --faza-hover: 0 0 0 1px rgba(0, 0, 0, .12), 0 1px 2px rgba(0, 0, 0, .06), inset 0 1px 0 rgba(255, 255, 255, .9);
  --faza-pelna: 0 0 0 1px rgba(0, 0, 0, .18), inset 0 1px 0 rgba(255, 255, 255, .18);
  --cien-pop: 0 16px 40px rgba(0, 0, 0, .14), 0 4px 12px rgba(0, 0, 0, .06), 0 0 0 1px rgba(0, 0, 0, .06);
  --obrys-obrazu: rgba(0, 0, 0, .1); /* czysta czerń — tinta czytałaby się jak brud na krawędzi */

  /* --- promienie. Koncentryczne: zewnętrzny = wewnętrzny + wypełnienie.
     Menu 12 = pozycja 6 + wypełnienie 6; szukajka 12 = wiersz 6 + 6;
     panel 10 z wierszami bez własnego promienia. Pastylki pełne — to
     etykiety i przyciski, nie pojemniki. */
  --r: 10px;
  --r-s: 8px;
  --r-xs: 6px;
  --r-menu: 12px;
  --r-pill: 999px;

  /* --- ruch. Jedna krzywa na interakcje (better-ui), mocniejsze wyjście
     na wejścia (emil), krzywa szuflady na arkusz. Wysoka częstotliwość
     (hover, wiersz, klawisz) dostaje ≤150 ms albo nic. */
  --ease: cubic-bezier(0.2, 0, 0, 1);
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  --ease-drawer: cubic-bezier(0.32, 0.72, 0, 1);
  --t-szybko: 100ms;
  --t: 150ms;
  --t-wejscie: 220ms;
  --t-wyjscie: 150ms;

  --sans: Geist, system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono: "Geist Mono", Consolas, "SF Mono", Menlo, monospace;

  /* --- szyna. Stała szerokość, zwijana przyciskiem, NIE po najechaniu:
     rozsuwanie się treści przy każdym przejściu myszy przez lewą krawędź
     było najczęstszym ruchem na ekranie i nic nie mówiło. */
  --szyna: 172px;             /* tyle, ile trzeba na znak i najdłuższą nazwę pozycji (de, ru) */
  --szyna-zwinieta: 60px;
  --pasek: 58px;             /* wysokość paska górnego i nagłówka szyny */

  /* Szerokość treści nie ma górnej granicy (decyzja właściciela z 1 października):
     przestrzenie robocze mają panele o regulowanej szerokości, więc zajmują
     całe okno. Nie wracaj do `--stage-w: 100vw` — przy `zoom: .9` na `body`
     100vw to szerokość okna w pikselach PRZED pomniejszeniem, czyli o 10 %
     za mało, i scena znów stała wyśrodkowana z pasami po bokach (30 października). */
  --pad-x: clamp(16px, 2.5vw, 28px);
  /* Skala całego panelu (uwaga z 25 września: pismo jak u Okary, gęściej).
     Jedna liczba zamiast stu rozmiarów; `pozycjonuj` i wysokość rzędu paneli
     dzielą przez nią. Telefon zostaje w skali 1 — tam pismo i tak jest małe. */
  --zoom: .9;

  /* --- skala pisma (6 października: „za duże czcionki, a rzeczy obok mają
     nagle większe przyciski"). Rozmiar idzie z ROLI, nie z widoku — każdy
     font-size w arkuszu wskazuje jeden z tych tokenów, więc kolejna zmiana
     skali to jedna linijka tutaj. Poniżej 11 px schodzą tylko osie
     wykresów i inicjały w kółkach (te trzymają się wymiaru kółka). */
  --fs-os: 11px;            /* osie i podpisy wykresów */
  --fs-etykieta: 11px;      /* etykiety paneli, sekcji, grup (zdaniem od 1 listopada); .badge */
  --fs-drobne: 11px;        /* odznaki (.hchip, .tag), kod, dopiski, legendy */
  --fs-meta: 11px;          /* meta wiersza, pomoc, etykieta pola, pigułka */
  --fs-tresc: 12px;         /* treść wiersza, pola, menu, toast, czat */
  --fs-kontrolka: 12px;     /* .btn, .chip, .row-act, .okno, szyna — jeden rozmiar w roli */
  --fs-akcent: 13px;        /* wyróżniona nazwa w karcie, pole Ctrl+K */
  --fs-tytul-karty: 14px;   /* arkusz, dialog, pusty stan, wykres, nazwa klienta */
  --fs-tytul: 16px;         /* tytuł widoku */
  --fs-liczba-s: 18px;      /* liczba w nagłówku panelu, suma modułów */
  --fs-liczba-m: 21px;      /* KPI finansów, pierścień, statystyka */
  --fs-liczba: 21px;        /* liczba w kaflu */
  --fs-liczba-xl: 26px;     /* liczba karty Pulpitu */
  --fs-powitanie: 21px;     /* powitanie Pulpitu */
  /* Wysokość kontrolek w treści: przycisk formularza, pastylka i pole stoją
     obok siebie w jednym rzędzie, więc mają jedną wysokość. */
  --h-kontrolka: 30px;
}

html.dark {
  color-scheme: dark;
  /* Jedna rodzina szarości, bez chłodnej karty: strona 161616, karta i szyna
     1C1C1C (szyna leży na warstwie karty, nie między stroną a kartą),
     wnętrze 212121, kreska 2A2A2A — na tyle mocna, żeby karta miała krawędź
     bez pomocy cienia. Kolor niosą tylko statusy i brand. */
  --background: #161616;
  --card: #1C1C1C;
  --card-2: #212121;
  --sidebar: #1C1C1C;
  --foreground: #F9FBFF;
  --primary: #F2F4F6;
  --primary-fg: #141619;
  --muted: #2A2A2A;
  --accent: #2A2A2A;
  --border: #2A2A2A;
  --border-strong: #3A3A3A;
  --input: #3A3A3A;
  /* 6,0:1 na karcie, 5,0:1 na tle zaznaczenia (#2A2A2A) — tam stoją
     etykiety przełącznika i skrót w szukajce. #8A8A8A miał tam 4,2:1. */
  --text-secondary: #999999;

  --brand: #4124FB;
  --brand-fg: #F9FBFF;
  --brand-hover: #5238FF;
  --brand-soft: rgba(96, 72, 255, .22);
  --brand-tekst: #A99FFF;    /* 7,4:1 na karcie, 6,1:1 na --brand-soft */
  --fokus: #8B7DFF;          /* 5,6:1 na stronie, 4,4:1 na tle zaznaczenia */

  /* Pigułki ciemne: tinta 12 % pełnego koloru na karcie, bez obrysu, tekst
     w pełnym kolorze. Trzy zielenie (tło + obrys + pastel) czytały się na
     ciemnym jak doklejony klocek — jedna warstwa wystarczy. Pełny kolor
     idzie też w liczby i kropki na tle karty. */
  --ok: #22C55E;
  --ok-bg: rgba(34, 197, 94, .12);
  --ok-border: transparent;
  --ok-tekst: #0B0B0C;
  --warn: #FBBF24;
  --warn-bg: rgba(251, 191, 36, .12);
  --warn-border: transparent;
  --warn-tekst: #FBBF24;
  --warn-duze: #FBBF24;
  --bad: #F97373;
  --bad-bg: rgba(249, 115, 115, .12);
  --bad-border: transparent;
  --bad-tekst: #F97373;
  --idle: #676767;
  --neutral-bg: rgba(255, 255, 255, .07);
  --neutral-kryjacy: #262626; /* .07 bieli na #161616 */
  --neutral-border: transparent;
  --neutral-tekst: #D4D4D4;

  --hover-bg: #212121;
  --overlay: rgba(0, 0, 0, .6);
  --chart-grid: #262626;
  --chart-axis: #8F8F8F;
  --chart-line: #F9FBFF;
  --chart-line-2: #676767;

  /* W ciemnym motywie warstwowy cień jest niewidoczny — zostaje jeden
     biały pierścień (better-ui). Faza sterowania wprost z wzorca:
     ciemny pierścień na zewnątrz, jasna krawędź górna i jasny pierścień
     wewnętrzny. */
  --cien-ramka: 0 0 0 1px rgba(255, 255, 255, .06);
  --cien-ramka-hover: 0 0 0 1px rgba(255, 255, 255, .12);
  --faza: 0 0 0 1px rgba(0, 0, 0, .4), inset 0 1px 0 rgba(255, 255, 255, .1), inset 0 0 0 1px rgba(255, 255, 255, .06);
  --faza-hover: 0 0 0 1px rgba(0, 0, 0, .4), inset 0 1px 0 rgba(255, 255, 255, .14), inset 0 0 0 1px rgba(255, 255, 255, .1);
  --faza-pelna: 0 0 0 1px rgba(0, 0, 0, .5), inset 0 1px 0 rgba(255, 255, 255, .2);
  --cien-pop: 0 16px 40px rgba(0, 0, 0, .5), 0 0 0 1px #0E0E0E;
  --obrys-obrazu: rgba(255, 255, 255, .1); /* czysta biel, z tego samego powodu */
}

/* ------------------------------------------------------------------ podstawy */

*, *::before, *::after { box-sizing: border-box; }

/* Atrybut `hidden` musi wygrywać z każdą regułą layoutu. Bez tego reguła
   w rodzaju `.field { display: block }` bije domyślny `display:none`
   przeglądarki i „ukryte" pola formularzy zostają widoczne — złapane
   testem przełączania typu kanału. */
[hidden] { display: none !important; }

html, body { margin: 0; padding: 0; }

body {
  background: var(--background);
  color: var(--foreground);
  font-family: var(--sans);
  font-size: var(--fs-tresc);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  /* Przy włączonym przeglądaniu z kursorem (F7 w Chrome) klik w zwykły tekst
     stawiał migającą kreskę; kursor zostaje tylko tam, gdzie się pisze. */
  caret-color: transparent;
}

input, textarea, select, [contenteditable] { caret-color: auto; }

a { color: inherit; }

/* Nacisk w projekcie to waga 500. Przeglądarka daje <strong>/<b> 700,
   a Geist ładujemy w 400/500/600, więc rysowało się to jako 600 — i każdy
   widok łatał to ręcznie. Klasy z własną wagą (liczby 600) nadal wygrywają. */
strong, b { font-weight: 500; }

/* Kontrolki dziedziczą krój strony. Bez tego każde pole i przycisk bez
   klasy projektu rysuje się Arialem 13,33 px przeglądarki — klasy niżej
   i tak nadpisują rozmiar, ten reset łapie to, co klasy nie ma. */
button, input, select, textarea { font: inherit; }

/* Zdjęcia i loga dostają cienki obrys w czystej czerni/bieli o niskiej
   nieprzezroczystości — spójna głębia z resztą powierzchni, a `outline`
   nie rusza układu. */
img.awatar-podglad, .awatar img, .marka-logo {
  outline: 1px solid var(--obrys-obrazu);
  outline-offset: -1px;
}

/* Suwaki: zostaje sam kciuk — cienki, zaokrąglony, w kolorze tekstu
   pomocniczego, na przezroczystym torze. Celowo BEZ `scrollbar-width`/
   `scrollbar-color`: Chromium, gdy zobaczy którąkolwiek z nich, przestaje
   czytać `::-webkit-scrollbar`. Wyjątkiem jest `scrollbar-width: none`
   w `.sidebar-nav`, bo tam chodzi o schowanie paska. */
*::-webkit-scrollbar { width: 8px; height: 8px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-button { display: none; }
*::-webkit-scrollbar-thumb {
  background: color-mix(in srgb, var(--muted-fg) 40%, transparent);
  border-radius: 4px;
  border: 2px solid transparent;
  background-clip: padding-box;
}
*::-webkit-scrollbar-thumb:hover { background: var(--muted-fg); background-clip: padding-box; }
*::-webkit-scrollbar-corner { background: transparent; }

/* Zaznaczenie w tincie akcentu, nie w negatywie — negatyw przy kopiowaniu
   numeru z kartoteki wyglądał jak błąd renderowania. */
::selection { background: color-mix(in srgb, var(--brand) 24%, transparent); }

/* Fokus widoczny tylko z klawiatury — myszka nie maluje obwódek.
   Obwódka w akcencie, 2 px, z odstępem: ten sam znak na każdym elemencie. */
:focus { outline: none; }
:focus-visible { outline: 2px solid var(--fokus); outline-offset: 2px; }

/* Podział między krojami idzie po tym, CZYM liczba jest, nie po tym, że jest
   liczbą. Mono dostaje to, co się przepisuje i porównuje znak po znaku:
   numery dokumentów, NIP-y, daty, skróty klawiszowe. Kwoty i liczniki idą
   krojem tekstowym. `tabular-nums` trzyma stałą szerokość cyfry w obu. */
.mono, kbd {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
}
/* Adres i stos błędu w kodzie: najmniejsze pismo, jakie panel dopuszcza
   poza osiami wykresów (10,5 px przy zoomie .9 to 9,5 px na ekranie). */
.kod-adres { font-size: var(--fs-drobne); }
/* Blok tekstu maszynowego pod wierszem (argumenty narzędzia, podgląd
   treści, lista fraz) — jeden rozmiar zamiast trzech wpisanych w widokach. */
.kod-blok { margin: 8px 0 0; font-size: var(--fs-tresc); line-height: 1.6; white-space: pre-wrap; overflow-wrap: anywhere; }
.stos-bledu { margin-top: 6px; font-size: var(--fs-drobne); color: var(--text-secondary); line-height: 1.6; overflow-x: auto; white-space: pre; }

.tile-value, .row-amount, .rn-count, .liczba {
  font-variant-numeric: tabular-nums;
}

/* Nagłówki wyważone, opisy bez sieroty na końcu (better-typography). */
h1, h2, h3 { text-wrap: balance; }
.card-sub, .pusto-tresc, .pk-zdanie, .help { text-wrap: pretty; }

/* Dotyk: hover nie istnieje, a po stuknięciu zostaje przyklejony — tło
   z hoveru wracałoby dopiero po dotknięciu czegoś innego. */
@media (hover: none) {
  .row.clickable:hover, .sprawa:hover, .pytania .pytanie:hover, .konto-menu button:hover, .cmdk-row:hover:not([aria-selected=      ]) { background: transparent; }
  .nav-item:hover:not(.active) { background: none; color: var(--muted-fg); }
  .chart-hits > i:hover { background: transparent; }
}

/* Tryb wymuszonych kolorów: tło i cień znikają, więc aktywna pozycja
   i aktywny segment dostają obrys — inaczej nie widać, gdzie jesteś. */
@media (forced-colors: active) {
  .nav-item.active, .okno.active, .card-tabs button.active, .cmdk-row[aria-selected="true"] { outline: 2px solid; outline-offset: -2px; }
  .pill, .hchip, .badge, .nav-licznik, .btn, .chip, .row-act { border: 1px solid; }
}

/* ------------------------------------------------------------------- layout */

/* Szyna: stała, 172 px, z blokiem marki u góry jak w serwisie wzorcowym.
   Zwija się do 60 px przyciskiem w stopce (klasa `szyna-zwinieta` na <html>,
   zapamiętana w localStorage i nadana PRZED pierwszym rysowaniem w motyw.js,
   żeby nie mrugała). position: fixed — przewija się treść, nie szyna. */
.sidebar {
  position: fixed;
  inset: 0 auto 0 0;
  z-index: 40;
  width: var(--szyna);
  display: flex;
  flex-direction: column;
  background: var(--sidebar);
  border-right: 1px solid var(--border);
  overflow: hidden;
  transition: width var(--t-wejscie) var(--ease);
}

html.szyna-zwinieta .sidebar { width: var(--szyna-zwinieta); }

/* Blok marki: kafelek ze znakiem, obok nazwa i podpis. Kafelek ma fazę jak
   przyciski — to jedyny element szyny, który jest „przedmiotem", reszta
   to tekst. Wcięcie 14 px: ikony pozycji stoją na tej samej osi (14 + 8 = 22,
   znak 28 px ma środek na 28 → oś 14 + 14 = 28; ikony 20 px w pozycji
   z wypełnieniem 8 → 14 + 8 + 10 = 32). Różnica czterech pikseli jest
   celowa: znak jest większy i czytany osobno. */
.sidebar-logo {
  display: flex;
  align-items: center;
  gap: 10px;
  height: var(--pasek);
  min-height: var(--pasek);
  padding: 0 14px;
  border: 0;
  border-bottom: 1px solid var(--border);
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
  white-space: nowrap;
}

.sidebar-logo:focus-visible { outline-offset: -2px; }

.marka-kafel {
  flex: none;
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
}

/* Znak firmowy = favicon (`public/icons/icon.svg`): „Fałd" — wstęga zagięta
   w „V", bez kafelka. Wygląda zawsze tak samo (decyzja właściciela z 14 listopada):
   stan stron mówi już tylko `title` przycisku, kolor znaku się nie zmienia. */
.marka {
  flex: none;
  width: 24px;
  height: 24px;
}

.marka-logo { width: 28px; height: 28px; border-radius: var(--r-s); object-fit: cover; }
.marka-przod { fill: var(--brand); }
.marka-stan { fill: url(#vekord-tyl); }

.marka-tekst {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  transition: opacity var(--t) var(--ease);
}

/* Nazwa bez wersalików: „Vekord" niesie wielkość liter w sobie. */
.marka-tekst b {
  font-size: var(--fs-akcent);
  line-height: 1;
  overflow: hidden;
  text-overflow: ellipsis;
}

.marka-tekst small {
  font-size: var(--fs-meta);
  line-height: 1;
  color: var(--text-secondary);
  overflow: hidden;
  text-overflow: ellipsis;
}

html.szyna-zwinieta .marka-tekst { opacity: 0; }

/* Szyna nie pokazuje suwaka. Przewijanie ZOSTAJE — kółkiem, palcem
   i klawiaturą — znika sam pasek. */
.sidebar-nav {
  flex: 1;
  padding: 10px 12px;
  overflow-y: auto;
  overflow-x: hidden;
  scrollbar-width: none;
}

.sidebar-nav::-webkit-scrollbar { display: none; }

/* Pozycja: 30 px, `--fs-kontrolka`, ikona 16 px w kolorze tekstu pomocniczego; aktywna
   dostaje 32 px, tło i FAZĘ — wprost ze wzorca. Wysokość rośnie o 2 px, bo
   wypukły element ma prawo być odrobinę większy od płaskiego sąsiada; różnica
   idzie w margines, więc lista się nie przesuwa. */
.nav-item {
  position: relative;
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  height: 30px;
  margin: 1px 0;
  padding: 0 8px;
  border: 0;
  border-radius: var(--r-s);
  background: none;
  color: var(--muted-fg);
  font: inherit;
  font-size: var(--fs-kontrolka);
  font-weight: 500;
  line-height: 1;
  text-align: left;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color var(--t) var(--ease), color var(--t) var(--ease), box-shadow var(--t) var(--ease);
}

.nav-item:hover { color: var(--foreground); background: var(--hover-bg); }
.nav-item:focus-visible { outline-offset: -2px; }

.nav-item.active {
  height: 32px;
  margin: 0;
  color: var(--foreground);
  background: var(--accent);
  box-shadow: var(--faza);
}

/* Ikona: 16 px, kreska 1,5 px przy piśmie 500 (better-ui: waga kreski
   podąża za wagą tekstu; 1,5 przy medium 14 px czyta się równo). Kolor
   z tekstu pomocniczego, w aktywnej i pod kursorem — pełny. Zaokrąglone
   końce — bez nich zestaw wygląda na złożony z odcinków. */
.nav-item svg {
  flex: none;
  width: 16px;
  height: 16px;
  stroke: currentColor;
  fill: none;
  /* 2 przy piśmie 500 (better-ui: kreska podąża za wagą tekstu); w viewBoxie
     24 przy 16 px daje to 1,33 px na ekranie, więc nie robi się ciężka. */
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  color: var(--text-secondary);
  transition: color var(--t) var(--ease);
}

.nav-item:hover svg, .nav-item.active svg { color: var(--foreground); }

.nav-label {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  transition: opacity var(--t) var(--ease);
}

/* Licznik w nagłówku panelu przestrzeni (np. „Do zrobienia 4"). Z szyny
   liczniki zniknęły 2026-09-24 — tam były szumem przy każdym wejściu.
   Ton `bad`/`warn` mówi „jak bardzo", a nie tylko „ile". */
.nav-licznik {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 16px;
  min-width: 22px;
  padding: 0 4px;
  border-radius: var(--r-pill);
  background: var(--neutral-bg);
  color: var(--neutral-tekst);
  box-shadow: 0 0 0 1px var(--neutral-border);
  font-size: var(--fs-drobne);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

.nav-licznik.warn { background: var(--warn-bg); color: var(--warn-tekst); box-shadow: 0 0 0 1px var(--warn-border); }
.nav-licznik.bad { background: var(--bad-bg); color: var(--bad-tekst); box-shadow: 0 0 0 1px var(--bad-border); }

/* Nagłówek grupy: 11 px zdaniem (od 1 listopada bez wersalików) — dzieli
   listę, nie tytułuje. W zwiniętej szynie tekst znika, a zostaje sama kreska. */


/* Kreska pod Pulpitem — 1 px, prawie przezroczysta; dzieli, nie przyciąga oka. */
.nav-kreska { height: 1px; margin: 8px 8px; background: var(--border); }


html.szyna-zwinieta .nav-label { opacity: 0; pointer-events: none; }

/* Stopka: przełączniki tej przeglądarki (ustawienia, motyw, język) i zwijanie
   szyny. Rząd ikon w rozwiniętej, kolumna w zwiniętej — o tym decyduje
   miejsce, nie gust: w 60 px nie ma jak postawić czterech ikon obok siebie. */
.sidebar-foot {
  display: flex;
  align-items: center;
  gap: 2px;
  padding: 8px 12px;
  border-top: 1px solid var(--border);
}

.sidebar-foot .nav-item {
  width: auto;
  height: 30px;
  margin: 0;
  padding: 0 8px;
  gap: 6px;
  flex: none;
}

.sidebar-foot .nav-item.active { height: 30px; }

.sidebar-foot #btnSzyna { margin-left: auto; }

/* Etykiety ustawień i motywu znikają z oczu, ale ZOSTAJĄ w drzewie
   dostępności: `display: none` zabrałoby przyciskom nazwę. Język ma tekst
   widoczny — kula mówi „język", ale nie mówi KTÓRY. */
#btnSettings .nav-label,
#btnTheme .nav-label,
#btnSzyna .nav-label,
html.szyna-zwinieta #langLabel {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  opacity: 1;
}

html.szyna-zwinieta .sidebar-foot {
  flex-direction: column;
  padding: 8px 12px;
}

html.szyna-zwinieta .sidebar-foot .nav-item { width: 100%; padding: 0 8px; }
html.szyna-zwinieta .sidebar-foot #btnSzyna { margin: 0; }

/* Ikona zwijania: szewron obraca się razem ze stanem, na tej samej krzywej,
   co szerokość szyny — jeden ruch, nie dwa. */
#btnSzyna svg { transition: transform var(--t-wejscie) var(--ease), color var(--t) var(--ease); }
html.szyna-zwinieta #btnSzyna svg { transform: rotate(180deg); }

/* Para ikon motywu: obie w DOM, jedna nad drugą, przenikanie skalą,
   przezroczystością i rozmyciem (better-ui, dokładnie te wartości:
   0,25 → 1, 0 → 1, 4 px → 0). Nic nie jest podmieniane w locie, więc
   wejście i wyjście animują się symetrycznie. */
.ikona-para { position: relative; display: grid; width: 16px; height: 16px; flex: none; }
.ikona-para svg {
  grid-area: 1 / 1;
  width: 16px;
  height: 16px;
  transition: opacity 300ms var(--ease), scale 300ms var(--ease), filter 300ms var(--ease);
}
.ikona-para .ikona-ksiezyc { opacity: 0; scale: .25; filter: blur(4px); }
html.dark .ikona-para .ikona-ksiezyc { opacity: 1; scale: 1; filter: blur(0); }
html.dark .ikona-para .ikona-slonce { opacity: 0; scale: .25; filter: blur(4px); }

/* Treść odsunięta o szerokość szyny, tym samym ruchem co ona. */
.shell {
  margin-left: var(--szyna);
  min-height: calc(100vh / var(--zoom));
  display: flex;
  flex-direction: column;
  transition: margin-left var(--t-wejscie) var(--ease);
}

html.szyna-zwinieta .shell { margin-left: var(--szyna-zwinieta); }

/* Duże monitory: cały panel rośnie proporcjonalnie. Arkusz jest w pikselach,
   więc na 2560 px karty miały rozmiar z laptopa i tonęły w pustym tle. */
body { zoom: var(--zoom); }
@media (max-width: 700px) { :root { --zoom: 1; } }
@media (min-width: 1920px) { :root { --zoom: 1; } }
@media (min-width: 2400px) { :root { --zoom: 1.17; } }
@media (min-width: 3200px) { :root { --zoom: 1.3; } }

/* Pasek górny: szukajka po lewej jako pastylka z fazą i skrótem, konto po
   prawej jako pastylka ze zdjęciem i nazwą — układ nagłówka ze wzorca. */
.topbar {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  gap: 12px;
  height: var(--pasek);
  padding-inline: var(--pad-x);
  background: var(--background);
  border-bottom: 1px solid var(--border);
}

.topbar-szukaj {
  display: flex;
  align-items: center;
  gap: 8px;
  width: min(320px, 100%);
  height: 30px;
  padding: 0 6px 0 10px;
  border: 0;
  border-radius: var(--r-pill);
  background: var(--card);
  box-shadow: var(--faza);
  color: var(--text-secondary);
  font: inherit;
  font-size: var(--fs-kontrolka);
  text-align: left;
  cursor: text;
  transition: box-shadow var(--t) var(--ease), color var(--t) var(--ease);
}

.topbar-szukaj:hover { box-shadow: var(--faza-hover); color: var(--foreground); }
.topbar-szukaj span { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.topbar-szukaj kbd {
  flex: none;
  padding: 1px 4px;
  border-radius: 4px;
  background: var(--neutral-bg);
  box-shadow: 0 0 0 1px var(--neutral-border);
  color: var(--text-secondary);
  font-size: var(--fs-drobne);
  line-height: 14px;
}

.topbar-right { margin-left: auto; display: flex; align-items: center; gap: 8px; }
.offline-info { font-size: var(--fs-meta); color: var(--bad); }

/* Konto: pastylka 30 px ze zdjęciem 20 px i nazwą; menu pod spodem. */
.konto { position: relative; }
.awatar-podglad { width: 36px; height: 36px; border-radius: 50%; object-fit: cover; display: grid; place-items: center; }
.awatar-podglad.osoba-kolo { width: 36px; height: 36px; font-size: 13px; }
.row-act.jak-przycisk { cursor: pointer; display: inline-flex; align-items: center; }

.awatar {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 30px;
  padding: 0 10px 0 4px;
  border: 0;
  border-radius: var(--r-pill);
  background: var(--card);
  box-shadow: var(--faza);
  color: var(--foreground);
  font: inherit;
  font-size: var(--fs-kontrolka);
  cursor: pointer;
  transition: box-shadow var(--t) var(--ease), scale var(--t) var(--ease);
}

.awatar:hover { box-shadow: var(--faza-hover); }
.awatar:active { scale: .96; }
.awatar[aria-expanded="true"] { box-shadow: var(--faza-hover); }

/* Zdjęcie, inicjały i sylwetka to TRZY dzieci tego samego kółka 20 px;
   zawsze dokładnie jedno widoczne. Ton jak `.osoba-kolo` — jedna osoba,
   jedno kółko w całym panelu (audyt UI, M-17). */
.awatar-kolo {
  display: grid;
  place-items: center;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--brand-soft);
  color: var(--brand-tekst);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .02em;
  overflow: hidden;
  flex: none;
}
.awatar-kolo > * { grid-area: 1 / 1; }
.awatar-kolo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.awatar-kolo svg { width: 12px; height: 12px; stroke: currentColor; fill: none; stroke-width: 1.8; stroke-linecap: round; }
.awatar-nazwa { max-width: 160px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.awatar-nazwa:empty { display: none; }

/* Menu konta: promień 12 = pozycja 6 + wypełnienie 6 (koncentrycznie).
   Wchodzi skalą od 0,96 z rogu, w którym stoi przycisk — dymek rośnie
   z tego, co go otworzyło, nie ze środka. Wyjście natychmiastowe: ruch
   niczego by tu nie dodał. */
.konto-menu {
  position: absolute;
  right: 0;
  top: calc(100% + 6px);
  z-index: 30;
  min-width: 230px;
  padding: 6px;
  border-radius: var(--r-menu);
  background: var(--card);
  box-shadow: var(--cien-pop);
  transform-origin: top right;
  transition: opacity 120ms var(--ease-out), scale 120ms var(--ease-out);
}

@starting-style {
  .konto-menu { opacity: 0; scale: .96; }
}

.konto-menu-head { padding: 8px 10px 10px; margin-bottom: 4px; border-bottom: 1px solid var(--border); font-size: var(--fs-tresc); font-weight: 500; }
.konto-menu-head .row-meta { font-weight: 400; margin-top: 2px; }
.konto-menu button {
  display: block;
  width: 100%;
  padding: 8px 10px;
  border: 0;
  border-radius: var(--r-xs);
  background: transparent;
  color: var(--foreground);
  font: inherit;
  font-size: var(--fs-kontrolka);
  text-align: left;
  cursor: pointer;
  transition: background-color var(--t-szybko) var(--ease);
}
.konto-menu button:hover { background: var(--hover-bg); }
.konto-menu button.zly { color: var(--bad); }
.konto-menu .tylko-telefon { display: none; }
@media (max-width: 768px) { .konto-menu .tylko-telefon { display: block; } }

/* Tytuł widoku w karcie — pasek górny go nie niesie. `--fs-tytul` (16 px od 6 października, wcześniej 18):
   dwa stopnie nad treścią 12 px — tyle, ile trzeba, żeby stał nad
   treścią, a nie krzyczał. */
.card-title { margin: 0 0 4px; font-size: var(--fs-tytul); font-weight: 500; letter-spacing: -.015em; line-height: 1.2; }
.card-head .card-title { margin: 0; }
.card-title-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 4px; min-height: 30px; }
.przestrzen .card-title-row { margin-bottom: 0; }
.card-title-row .card-title { margin: 0; }
.card-title-lewa { display: flex; align-items: center; gap: 14px; min-width: 0; }

/* Panel zwijany (zgłoszenia, skrzynka): wiersz jest <summary>, reszta pod
   nim. Szewron po prawej mówi, że jest co rozwinąć — bez niego wiersz
   wyglądał jak zwykły, a zamknięta treść nie istniała. Obraca się razem
   ze stanem; sam stan jest w atrybucie `open`, nie w ruchu. */
details.zwijany > summary { list-style: none; cursor: pointer; }
details.zwijany > summary::-webkit-details-marker { display: none; }
details.zwijany > summary .row { border-bottom: 0; }
details.zwijany[open] > summary .row { border-bottom: 1px solid var(--border); margin-bottom: 12px; }
details.zwijany > summary:focus-visible { outline: none; }
details.zwijany > summary:focus-visible .row { outline: 2px solid var(--fokus); outline-offset: -2px; border-radius: var(--r); }
.szewron {
  display: inline-block;
  width: 16px;
  height: 16px;
  flex: none;
  color: var(--text-secondary);
  transition: transform var(--t) var(--ease);
  /* Kształt z maski, kolorem tekstu — jeden szewron dla obu motywów. */
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E") center / contain no-repeat;
  background: currentColor;
}
details.zwijany[open] > summary .szewron, details.sekcja.zwijana[open] > summary > .szewron { transform: rotate(180deg); }

/* Słabsi kandydaci w skrzynce: jedna linijka „pokaż inne · 2" zamiast
   dwóch pełnych wierszy z przyciskami. */
.inne-kandydaci > summary {
  padding: 8px 16px;
  color: var(--text-secondary);
  font-size: var(--fs-meta);
  cursor: pointer;
  list-style: none;
}
.inne-kandydaci > summary::-webkit-details-marker { display: none; }
.inne-kandydaci > summary::before { content: '›'; display: inline-block; margin-right: 6px; transition: transform var(--t) var(--ease); }
.inne-kandydaci[open] > summary::before { transform: rotate(90deg); }
.inne-kandydaci > summary:hover { color: var(--foreground); }

/* Dziennik zmian: wiersz to <summary>, szczegóły pod nim. */
.dz-wpis { border-bottom: 1px solid var(--border); }
.dz-wpis:last-child { border-bottom: 0; }
.dz-wpis > summary { list-style: none; cursor: pointer; border: 0; }
.dz-wpis > summary::-webkit-details-marker { display: none; }
.dz-wpis[open] > summary { background: var(--card-2); }
.dz-kiedy { flex: none; width: 88px; font-variant-numeric: tabular-nums; }
.dz-szczegoly { padding: 6px 16px 12px 116px; font-size: var(--fs-meta); white-space: normal; word-break: break-word; }
/* Formularz otwierany z nagłówka stoi nad listą i ma odstęp jak panele. */
.rozwijany { margin-bottom: 12px; }

/* Scena: całe miejsce obok szyny, przy krawędziach samo wcięcie. */
.stage {
  flex: 1;
  width: 100%;
  padding: 12px var(--pad-x) 64px;
}

.hint {
  display: flex;
  gap: 20px;
  align-items: center;
  padding-block: 12px;
  padding-inline: var(--pad-x);
  border-top: 1px solid var(--border);
  color: var(--text-secondary);
  font-size: var(--fs-meta);
}

.hint .right { margin-left: auto; }

/* Klawisz: mała wypukła pastylka, jak we wzorcu skrótów. */
kbd {
  display: inline-block;
  padding: 1px 4px;
  border-radius: 4px;
  background: var(--card);
  box-shadow: var(--faza);
  font-size: var(--fs-drobne);
  line-height: 16px;
  color: var(--foreground);
}

/* -------------------------------------------------------------- pulpit */

/* Strona startowa w trzech warstwach: „Na dziś" (sprawy, które nie czekają
   na przeglądanie kart), karty stanu z wykresem, osią czasu albo listą,
   pod spodem skróty i pytania do asystenta. Hierarchia bierze się
   z kształtu, nie z koloru. */

.pulpit-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 24px;
  margin-bottom: 12px;
}

/* Okna czasu stoją przy „Dostosuj”: bez dużego wykresu panel Finansów nie ma
   nagłówka, w którym mogłyby zostać. */
.pulpit-head-prawa { display: flex; align-items: center; gap: 8px; flex: none; max-width: 100%; }

/* Powitanie o stopień mniejsze niż wcześniej (26 zamiast 34): reszta ekranu
   zeszła do gęstości 14/12 i 34-pikselowy nagłówek krzyczał nad nią. */
.pulpit-witaj {
  margin: 0;
  font-size: var(--fs-powitanie);
  font-weight: 500;
  line-height: 1.15;
  letter-spacing: -.02em;
}

.pulpit-witaj .imie { color: var(--text-secondary); font-weight: 400; }

/* Przełącznik segmentowy (okna czasu na pulpicie, podzakładki w nagłówku):
   tor z fazą, aktywny segment jako wypukła pastylka. Promień koncentryczny:
   pełny tor, pełny segment, 2 px wypełnienia. Przejście tylko tła i cienia,
   150 ms — to sterowanie, nie pokaz. */
.okna {
  display: inline-flex;
  flex: none;
  gap: 2px;
  height: 30px;
  padding: 2px;
  border-radius: var(--r-pill);
  background: var(--neutral-bg);
  box-shadow: inset 0 0 0 1px var(--neutral-border);
}

.okno {
  display: inline-flex;
  align-items: center;
  height: 24px;
  padding: 0 12px;
  border: 0;
  border-radius: var(--r-pill);
  background: transparent;
  color: var(--text-secondary);
  font: inherit;
  font-size: var(--fs-kontrolka);
  font-weight: 500;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color var(--t) var(--ease), color var(--t) var(--ease), box-shadow var(--t) var(--ease);
}

.okno:hover { color: var(--foreground); }
.okno.active { background: var(--card); color: var(--foreground); box-shadow: var(--faza); }
.okno:focus-visible { outline-offset: -2px; }
.podzakladki .okno { padding: 0 12px; }

/* --- Na dziś: JEDYNE miejsce, w którym strona podnosi głos. Kropka
   z poświatą zamiast czerwonej liczby — kolor mówi „jak bardzo", nie „ile". */
.dzis {
  margin-bottom: 12px;
  border-radius: var(--r);
  background: var(--card);
  box-shadow: var(--cien-ramka);
  overflow: hidden;
}



.dzis-wiersz { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 16px; padding: 8px 16px; min-height: 42px; }
.dzis-wiersz .panel-label { margin: 0; }
.dzis-lista { display: flex; gap: 22px; min-width: 0; overflow: hidden; font-size: var(--fs-tresc); }
.dzis-poz { display: inline-flex; align-items: center; gap: 8px; white-space: nowrap; }
.dzis-poz .kropka { flex: none; width: 7px; height: 7px; border-radius: 50%; background: var(--warn); }
.dzis-poz .kropka.bad { background: var(--bad); }
.dzis-poz small { font-size: var(--fs-meta); color: var(--text-secondary); }
.dzis-poz.cisza { color: var(--text-secondary); }
.dzis-pokaz {
  height: 26px;
  padding: 0 10px;
  border: 0;
  border-radius: var(--r-pill);
  background: var(--card);
  box-shadow: var(--faza);
  color: var(--foreground);
  font: inherit;
  font-size: var(--fs-kontrolka);
  font-weight: 500;
  white-space: nowrap;
  cursor: pointer;
  transition: box-shadow var(--t) var(--ease), scale var(--t) var(--ease);
}
.dzis-pokaz:hover { box-shadow: var(--faza-hover); }
.dzis-pokaz:active { scale: .96; }
.dzis-pasek .sprawa:first-of-type { border-top: 1px solid var(--border); }


.sprawa {
  display: grid;
  grid-template-columns: 22px 1fr auto auto;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 42px;
  padding: 8px 16px;
  border: 0;
  border-top: 1px solid var(--border);
  background: transparent;
  color: var(--foreground);
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: background-color var(--t-szybko) var(--ease);
}

.sprawa:hover { background: var(--card-2); }
.sprawa:focus-visible { outline-offset: -2px; }

.kropka { width: 8px; height: 8px; border-radius: 50%; justify-self: center; }
.kropka.bad { background: var(--bad); box-shadow: 0 0 0 4px var(--bad-bg); }
.kropka.warn { background: var(--warn); box-shadow: 0 0 0 4px var(--warn-bg); }

.sprawa-tresc { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sprawa-meta { font-size: var(--fs-meta); color: var(--text-secondary); white-space: nowrap; }

.sprawa-akcja {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 26px;
  padding: 0 10px;
  border-radius: var(--r-pill);
  background: var(--card);
  box-shadow: var(--faza);
  color: var(--foreground);
  font-size: var(--fs-kontrolka);
  font-weight: 500;
  white-space: nowrap;
}

.sprawa-akcja svg { width: 14px; height: 14px; stroke: currentColor; fill: none; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }

/* --- karty: cztery w rzędzie (Pulpit ma się mieścić na jednym ekranie),
   poniżej 1100 px dwie. */
.pulpit-karty {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 12px;
  margin-bottom: 12px;
}
/* Niepełny ostatni rząd nie zostawia dziury (przegląd unslop, 1 listopada:
   czwarta karta stała sama obok dwóch trzecich pustki). Cztery karty mieszczą
   się w jednym rzędzie; przy innej liczbie ostatnia zabiera resztę rzędu.
   Liczba kart to wybór konta („Dostosuj"), więc reguła nie zna jej z góry. */
@media (min-width: 1101px) {
  .pulpit-karty:has(> :nth-child(4):last-child) { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .pulpit-karty:not(:has(> :nth-child(4):last-child)) > :last-child:nth-child(3n+1) { grid-column: span 3; }
  .pulpit-karty:not(:has(> :nth-child(4):last-child)) > :last-child:nth-child(3n+2) { grid-column: span 2; }
}
@media (min-width: 621px) and (max-width: 1100px) {
  .pulpit-karty > :last-child:nth-child(2n+1) { grid-column: span 2; }
}

/* Karta pulpitu jest przyciskiem: cała klikalna. Cień-ramka zamiast kreski;
   pod kursorem pierścień ciemnieje, tło zostaje — karta nie „gaśnie", tylko
   zaznacza, że słucha. Dolne wypełnienie ma zero, bo wykres polowy wychodzi
   na krawędzie. */
.pk {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  min-height: 132px;
  padding: 16px 16px 0;
  container-type: inline-size;
  border: 0;
  border-radius: var(--r);
  background: var(--card);
  box-shadow: var(--cien-ramka);
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
  overflow: hidden;
  transition: box-shadow var(--t) var(--ease);
}

.pk:hover { box-shadow: var(--cien-ramka-hover); }
.pk:focus-visible { outline-offset: -2px; }

.pk-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  /* Wysokość pigułki także bez niej — inaczej liczba w karcie bez stanu
     stoi wyżej niż u sąsiadów. */
  min-height: 22px;
  color: var(--text-secondary);
  font-size: var(--fs-tresc);
  font-weight: 500;
}

/* Pigułka stanu w nagłówku karty: ta sama rodzina co `.pill` w listach —
   tło i obrys w tonie, kropka, 22 px. */
.pk-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 22px;
  padding: 0 8px;
  border-radius: var(--r-pill);
  font-size: var(--fs-meta);
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Stan bez tonu (dokument „jeszcze nie ma", firma bez monitoringu) —
   neutralne tło jak `.pill.unknown`, inaczej pigułka nie miała tła wcale. */
.pk-pill { color: var(--neutral-tekst); background: var(--neutral-bg); box-shadow: inset 0 0 0 1px var(--neutral-border); }
.pk-pill::before { content: ""; flex: none; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.pk-pill.bad { background: var(--bad-bg); color: var(--bad-tekst); box-shadow: inset 0 0 0 1px var(--bad-border); }
.pk-pill.warn { background: var(--warn-bg); color: var(--warn-tekst); box-shadow: inset 0 0 0 1px var(--warn-border); }
.pk-pill.ok { background: var(--ok-bg); color: var(--ok-tekst); box-shadow: inset 0 0 0 1px var(--ok-border); }

/* Liczba jest tym, po co się na kartę patrzy. Jednostka stoi w mniejszym
   stopniu obok — nie jest częścią liczby. */
.pk-duza {
  margin-top: 12px;
  font-size: var(--fs-liczba-xl);
  font-weight: 500;
  line-height: 1.05;
  letter-spacing: -.025em;
  font-variant-numeric: tabular-nums;
}

.pk-duza small { margin-left: 2px; font-size: var(--fs-tytul-karty); color: var(--text-secondary); letter-spacing: 0; }
.pk-duza .druga { display: block; margin-top: 4px; font-size: var(--fs-tytul-karty); color: var(--text-secondary); }
.pk-duza.wiele { font-size: var(--fs-liczba); }

@container (max-width: 256px) {
  .pk-duza { font-size: calc(var(--fs-liczba-xl) * .9); }
  .pk-duza.wiele { font-size: calc(var(--fs-liczba) * .85); }
}

@container (max-width: 192px) {
  .pk-duza { font-size: calc(var(--fs-liczba-xl) * .8); }
  .pk-duza.wiele { font-size: calc(var(--fs-liczba) * .73); }
}

.pk-duza.warn { color: var(--warn-duze); }
.pk-duza.bad { color: var(--bad); }

/* Karta-zdanie (Faktury): jedno zdanie z pogrubionymi liczbami. */
.pk-zdanie { margin-top: 10px; font-size: var(--fs-akcent); line-height: 1.45; color: var(--text-secondary); }
.pk-zdanie b { color: var(--foreground); }

.pk-opis {
  margin-top: 6px;
  color: var(--text-secondary);
  font-size: var(--fs-meta);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Dół karty: pasek dni, mini słupki albo kropki (js/wykresy.js), oś czasu
   albo lista — zawsze dopchnięte do dołu, żeby trzy kafle w rzędzie miały
   dół na jednej wysokości. */
.pk-dol, .pk-pasek, .pk-mini, .pk-lista, .os { margin-top: auto; }
.pk-dol { display: block; height: 16px; }
/* Do zrobienia: pierwsza karta z rankingu i jej strona, między opisem a paskiem wag. */
.pk-pierwsza { display: flex; justify-content: space-between; gap: 8px; margin-top: 8px; font-size: var(--fs-tresc); }
.pk-pierwsza span:first-child { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pk-pierwsza .liczba { flex: none; max-width: 45%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text-secondary); font-size: var(--fs-meta); }

.pk-lista { display: flex; flex-direction: column; gap: 4px; padding: 10px 0 12px; font-size: var(--fs-tresc); }
.pk-lista .w { display: flex; justify-content: space-between; gap: 8px; }
.pk-lista .w span:first-child { min-width: 0; color: var(--text-secondary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pk-lista .liczba { flex: none; font-size: var(--fs-tresc); }
.pk-lista .liczba.bad { color: var(--bad); }

/* Oś 30 dni: kreska od dziś do terminu, kropka na terminie, pusta kropka
   na kolejnym. */
.os { display: block; padding: 0 0 14px; }

@media (max-width: 1100px) {
  .pulpit-karty { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 620px) {
  .pulpit-head { flex-direction: column; align-items: stretch; gap: 12px; }
  /* Okna czasu i „Dostosuj” zostają przyciskami, nie paskiem na całą szerokość. */
  .pulpit-head-prawa { align-self: flex-start; }
  .pulpit-tytul h2 { font-size: calc(var(--fs-powitanie) - 2px); }
  .okna { align-self: flex-start; }
  .pulpit-karty { grid-template-columns: 1fr; }
  .pk { min-height: 0; }
  .sprawa { grid-template-columns: 22px 1fr; }
  .sprawa-tresc { white-space: normal; }
  .sprawa-meta, .sprawa-akcja { grid-column: 2; justify-self: start; }
}

/* Miniwykres słupkowy: sam kształt, bez osi i opisów (inne widoki). */
.spark { height: 34px; margin-top: 12px; }
.spark-bars { display: flex; align-items: flex-end; gap: 2px; }
.spark-bars b { flex: 1 1 0; min-width: 1px; border-radius: 2px 2px 0 0; background: var(--chart-line); }
.spark-bars b.empty { background: var(--muted); border-radius: 2px; }
svg.spark { width: 100%; overflow: visible; }

/* Zakładka „Klienci": siatka kolumn — firma, usługi, abonament, opiekun,
   ostatnio, stan. Ta sama siatka w nagłówku i w wierszu, więc kolumny stoją
   równo bez tabeli. Poniżej 960 px wiersz wraca do dwóch linii, a nagłówek
   znika, bo nie miałby do czego się odnosić. */
/* JEDNA siatka na cały panel, wiersze i nagłówek biorą kolumny z podsiatki.
   Gdy każdy wiersz był własną siatką, tor `minmax(…, fr)` liczył się z treści
   TEGO wiersza i „Plan" stał w każdym wierszu gdzie indziej. Kolumny mają
   górny limit, bo na 2000 px proporcjonalne tory rozciągały nazwę firmy
   na pół ekranu; rośnie tylko kolumna usług, reszta trzyma rozmiar. */
.lista-firm {
  /* Wypełnienie wiersza w podsiatce zjada skrajne tory, więc lewy i prawy
     margines panelu dają pierwsza i ostatnia komórka własnym paddingiem.
     Obowiązujące tory (z kolumnami obszarów) stoją niżej, przy opiekunie. */
  --kolumny-firm: minmax(160px, 1.4fr) minmax(150px, 1.6fr) 72px 56px 64px 124px 104px minmax(110px, .9fr);
  display: grid;
  grid-template-columns: var(--kolumny-firm);
}
.lista-firm > * { grid-column: 1 / -1; }
.lista-firm .naglowek-tabeli {
  display: grid;
  grid-template-columns: subgrid;
  align-items: center;
  gap: 12px;
  height: 36px;
  padding: 0;
  border-bottom: 1px solid var(--border);
  color: var(--text-secondary);
  font-size: var(--fs-etykieta);
  font-weight: 500;
  white-space: nowrap;
}
.lista-firm .naglowek-tabeli > :last-child, .lista-firm .firma-opiekun { padding-right: 16px; }
.lista-firm .naglowek-tabeli > :first-child, .lista-firm .firma-nazwa { padding-left: 16px; }
/* Nagłówek nie wchodzi na sąsiada: wąska kolumna tnie etykietę wielokropkiem (pełna w dymku). */
.lista-firm .naglowek-tabeli > * { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.lista-firm .do-prawej { text-align: right; }
.firma-row { gap: 12px; }
.lista-firm .firma-row { display: grid; grid-template-columns: subgrid; align-items: center; padding-left: 0; padding-right: 0; }
.lista-firm .firma-row:last-child { border-bottom: 0; }
.firma-nazwa { min-width: 0; }
.firma-uslugi { display: flex; flex-wrap: wrap; gap: 4px; min-width: 0; }
.firma-mrr { text-align: right; white-space: nowrap; }
/* Kolumny obszarów: kropka na środku toru, pod wyśrodkowanym nagłówkiem. */
.naglowek-tabeli .sortuj.do-srodka { justify-self: center; max-width: 100%; }
.firma-obszar { display: flex; align-items: center; justify-content: center; min-width: 0; }

/* Układ liczony od szerokości PANELU, nie okna: lista stoi obok Podsumowania
   i Asystenta, więc przy szerokim oknie bywa wąska — media query jej nie
   widziało i kolumna Stan wyjeżdżała poza ramkę. */
.lista-firm-ramka { container: lista-firm / inline-size; }
@container lista-firm (max-width: 700px) {
  .lista-firm { display: block; }
  .lista-firm .naglowek-tabeli { display: none; }
  .lista-firm-ramka .filtry .filtry-sortuj { display: block; }
  /* Chipy usług w karcie tylko do odczytu (audyt UI, M-26): stuknięcie
     w pas usług otwiera kartotekę jak reszta wiersza; menu usługi zostaje
     w kartotece i na szerokiej liście. */
  .lista-firm .firma-uslugi .us-chip { pointer-events: none; }
  .lista-firm .firma-row { display: flex; flex-wrap: wrap; padding: 8px 16px; }
  .lista-firm .firma-opiekun { padding-right: 0; }
  .lista-firm .firma-nazwa { flex: 1 1 100%; order: 0; padding-left: 0; }
  /* Bez nagłówka kolumn kropka nic nie mówi — w karcie stoi przy niej nazwa obszaru. */
  .firma-obszar { order: 2; gap: 8px; padding-left: 4px; color: var(--text-secondary); font-size: var(--fs-meta); }
  .firma-obszar::after { content: attr(data-etykieta); }
  .firma-uslugi { order: 1; flex: 1 1 100%; }
  /* `.lista-firm` w selektorze: sam `.firma-plan` przegrywał z późniejszym `.row-stack { flex: 1 }`. */
  .lista-firm .firma-plan { order: 2; flex: 1 1 100%; }
  .firma-plan .row-meta { display: none; } /* liczniki są już w linii pod nazwą */
  .firma-mrr { order: 3; }
  .lista-firm .firma-row > .pusta { display: none; }
  .firma-mrr::before { content: attr(data-etykieta) ": "; color: var(--text-secondary); }
}

/* Tag usługi: kategoria, nie stan — dlatego własne odcienie, z dala od
   zieleni, bursztynu i czerwieni, które w tym panelu znaczą „działa",
   „uwaga", „awaria". Pięć odcieni, każdy zmierzony w obu motywach:
   niebieski (opieka), fiolet (social), morski (automatyzacje), róż (SEO),
   stalowy (technologia: WordPress, aplikacja, strona, kod). */
.tag {
  display: inline-flex;
  align-items: center;
  height: 20px;
  padding: 0 8px;
  border-radius: var(--r-pill);
  background: var(--tag-bg, var(--neutral-bg));
  color: var(--tag-tekst, var(--neutral-tekst));
  box-shadow: inset 0 0 0 1px var(--tag-border, var(--neutral-border));
  font-size: var(--fs-drobne);
  font-weight: 500;
  line-height: 1;
  white-space: nowrap;
}
.tagi-w-linii { display: inline-flex; flex-wrap: wrap; gap: 4px; margin-left: 8px; vertical-align: middle; }

/* Zespół: rola jako tag kategorii (nie stan). Kółko osoby to `.osoba-kolo`
   (ten sam ton i dwie litery co pasek górny i opiekun), tu tylko większe.
   Odcień roli bierze klasę z palety usług (.us-kolor-*, zespol.js). */
.osoba-kolo.zespol-inicjal { width: 28px; height: 28px; font-size: 11px; }

/* Szablony pytań: pastylki z ikoną nad listą. */
.szablony { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
.szablon {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 30px;
  padding: 0 12px 0 10px;
  border: 0;
  border-radius: var(--r-pill);
  background: var(--card);
  box-shadow: var(--faza);
  color: var(--foreground);
  font: inherit;
  font-size: var(--fs-kontrolka);
  font-weight: 500;
  cursor: pointer;
  transition: box-shadow var(--t) var(--ease), scale var(--t) var(--ease);
}
.szablon:hover { box-shadow: var(--faza-hover); }
.szablon:active { scale: .96; }
.szablon svg { width: 14px; height: 14px; stroke: currentColor; fill: none; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; color: var(--text-secondary); }

/* Pulpit wypełnia ekran, a czat siedzi na jego dole. */
.pulpit {
  display: flex;
  flex-direction: column;
  margin-bottom: -32px;
  min-height: calc(100vh / var(--zoom) - var(--pasek) - 20px - 32px);
}
.pytania { width: 100%; max-width: 760px; margin: auto auto 0; padding-top: 16px; }

.pytania-lista { display: flex; flex-direction: column; margin-top: 8px; border-radius: var(--r); box-shadow: var(--cien-ramka); overflow: hidden; }

.pytania .pytanie {
  border: 0;
  border-bottom: 1px solid var(--border);
  background: var(--card);
  color: var(--text-secondary);
  font: inherit;
  font-size: var(--fs-tresc);
  text-align: left;
  padding: 12px 16px;
  cursor: pointer;
  transition: background-color var(--t-szybko) var(--ease);
}

.pytania .pytanie:last-child { border-bottom: 0; }
.pytania .pytanie:hover { background: var(--card-2); }
/* Lista ma overflow:hidden (zaokrąglone rogi), więc obwódka na zewnątrz
   byłaby ucięta w całości — rysujemy ją do środka. */
.pytania .pytanie:focus-visible { outline-offset: -2px; }
.pytania .pytanie b { color: var(--foreground); }

/* Czat pod pytaniami: pole tekstowe bez ramki, pod nim rząd ikon i przycisk
   wysyłki. Enter wysyła; pytanie idzie do panelu asystenta. */
.czat {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 12px;
  padding: 14px 14px 10px;
  border-radius: var(--r);
  background: var(--card);
  box-shadow: var(--cien-ramka);
  transition: box-shadow var(--t) var(--ease);
}
.czat:focus-within { box-shadow: var(--cien-ramka-hover), 0 0 0 3px var(--brand-soft); }
.czat-pole {
  border: 0;
  padding: 0;
  background: transparent;
  color: var(--foreground);
  font: inherit;
  font-size: var(--fs-tresc); /* jak dymki — pole czatu w obszarach było o dwa stopnie większe niż w stronie */
  line-height: 1.5;
  min-height: 21px;
  max-height: 140px;
  resize: none;
  outline: none;
}
.czat-dol { display: flex; align-items: center; justify-content: space-between; }
.czat-lewo, .czat-prawo { display: flex; align-items: center; gap: 2px; }
.czat-prawo { gap: 6px; }
.czat-ikona.nagrywa { color: var(--bad); background: var(--bad-bg); }
.czat-ikona.nagrywa svg { animation: czat-puls 1.2s ease-in-out infinite; }
@keyframes czat-puls { 0%, 100% { opacity: 1; } 50% { opacity: .45; } }
.czat-plik { display: none; }
.czat-ikona.active { background: var(--primary); color: var(--primary-fg); }
.czat-ikona.active:hover { background: var(--primary); color: var(--primary-fg); opacity: .85; }
.czat-ikona:disabled { opacity: .35; cursor: not-allowed; }
.czat-stan { margin-left: 8px; font-size: var(--fs-tresc); color: var(--text-secondary); }
.czat-zalaczniki { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.czat-zalacznik {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 6px 4px 8px;
  border-radius: var(--r-pill);
  background: var(--neutral-bg);
  box-shadow: inset 0 0 0 1px var(--neutral-border);
  font-size: var(--fs-tresc);
}
.czat-zalacznik svg { width: 13px; height: 13px; stroke: currentColor; fill: none; stroke-width: 1.6; stroke-linejoin: round; color: var(--text-secondary); }
.czat-zalacznik button { display: grid; place-items: center; min-width: 24px; height: 24px; margin: -4px -2px -4px 0; border: 0; border-radius: var(--r-pill); background: transparent; color: var(--text-secondary); font: inherit; font-size: 15px; line-height: 1; padding: 0; cursor: pointer; }
.czat-zalacznik button:hover { color: var(--foreground); }
/* Obraz czekający na wysłanie: miniatura w miejscu chipa, „×" w rogu. */
.czat-zalacznik.obraz { position: relative; padding: 0; border-radius: var(--r-s); overflow: hidden; box-shadow: 0 0 0 1px var(--neutral-border); }
.czat-zalacznik.obraz img { display: block; width: 56px; height: 56px; object-fit: cover; }
.czat-zalacznik.obraz button { position: absolute; top: 2px; right: 2px; min-width: 20px; height: 20px; margin: 0; background: var(--card); box-shadow: var(--faza); color: var(--foreground); font-size: 13px; }
.czat-zalaczniki:empty { display: none; }
.chat-input .czat-zalaczniki { margin-bottom: 8px; }
/* Plik przeciągany nad polem — pole mówi, że go przyjmie. */
.czat.upuszczanie, .chat-input.upuszczanie { box-shadow: var(--cien-ramka-hover), 0 0 0 3px var(--brand-soft); }
.chip.ghost.active { background: var(--primary); color: var(--primary-fg); box-shadow: var(--faza-pelna); }
.czat-ikona, .czat-wyslij {
  display: grid;
  place-items: center;
  border: 0;
  border-radius: var(--r-pill);
  cursor: pointer;
  transition: background-color var(--t) var(--ease), color var(--t) var(--ease), scale var(--t) var(--ease);
}
.czat-ikona { width: 28px; height: 28px; background: transparent; color: var(--text-secondary); }
.czat-ikona:hover { background: var(--hover-bg); color: var(--foreground); }
.czat-wyslij { width: 28px; height: 28px; background: var(--brand); color: var(--brand-fg); box-shadow: var(--faza-pelna); }
.czat-wyslij:hover { background: var(--brand-hover); }
.czat-ikona:active, .czat-wyslij:active { scale: .96; }
.czat-ikona svg, .czat-wyslij svg { width: 15px; height: 15px; stroke: currentColor; fill: none; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }

/* Karty „co wymaga uwagi" — 1 kolumna na telefonie, 2 na tablecie, 3 na
   desktopie. Każda jest przyciskiem. */
.karty {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 12px;
  margin-bottom: 20px;
}

.karty[hidden] { display: none; }

.tiles {
  display: grid;
  grid-template-columns: repeat(var(--cols, 4), minmax(0, 1fr));
  gap: 12px;
  /* Odstęp pod kaflami daje rytm karty (`.card > .tiles + *`), nie kafle. */
}

.karta {
  border-radius: var(--r);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 12px;
  min-height: 108px;
  padding: 16px;
  border: 0;
  background: var(--card);
  box-shadow: var(--cien-ramka);
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: box-shadow var(--t) var(--ease);
}

.karta:hover { box-shadow: var(--cien-ramka-hover); }
.karta:focus-visible { outline-offset: -2px; }



/* Kafle opisujące JEDEN przedmiot: szczegóły strony, kartoteka firmy. */
.tile {
  border: 0;
  min-height: 96px;
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  gap: 4px;
}

.tile > .panel-label { font-size: var(--fs-meta); letter-spacing: 0; text-transform: none; margin-bottom: 4px; }
.tile-value { font-size: var(--fs-liczba); font-weight: 500; line-height: 1.05; letter-spacing: -.025em; font-variant-numeric: tabular-nums; }
.tile-delta { font-size: var(--fs-meta); color: var(--text-secondary); margin-top: auto; }

/* ------------------------------------------------------------------ panele */

/* Bez obrysu. Panel odcina się od strony pierścieniem cienia — kreska
   zostaje wewnątrz, między wierszami, gdzie DZIELI. */
.panel {
  background: var(--card);
  border: 0;
  border-radius: var(--r);
  box-shadow: var(--cien-ramka);
}

/* Panele stojące jeden pod drugim same się rozsuwają. W siatkach odstęp
   daje `gap`, więc margines musi tam zniknąć. */
/* `.panel + .panel` zniknęło: odstęp daje rytm karty (`.card > * + *`)
   albo `.stack-mt` w zagnieżdżeniu — reguła sąsiedztwa biła klasę
   specyficznością i ten sam panel dostawał raz 12, raz 16 px. */
.tiles > .panel + .panel, .lanes > .panel + .panel, .split > .panel + .panel { margin-top: 0; }

.panel-pad { padding: 14px 16px; }

/* Nagłówek panelu nad listą wierszy: etykieta po lewej, akcja po prawej,
   4 px do pierwszego wiersza. Wcześniej ten sam efekt pisało 41 ręcznych
   `padding-bottom:4px` z własnym flexem — `.lista-grup .grupa` ma to samo. */
.panel-head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px 12px;
  padding: 14px 16px 4px;
}
/* Etykieta odpycha resztę na prawo: liczba, pigułka i przycisk stoją
   razem przy prawej krawędzi, nie rozrzucone po szerokości. */
.panel-head > .panel-label { margin: 0 auto 0 0; }
.panel-head > .row-act, .panel-head > .chip { margin-left: 0; }
/* Pigułka przed sumą (Wpływy: „3 do powiązania") — suma nie odpycha jej na środek. */
.panel-head > .pill + .liczba { margin-left: 0; }
/* Nagłówek nad polami formularza (nie wierszami): pełny oddech na dole. */
.panel-head.z-polami { padding-bottom: 10px; }

/* Etykieta sekcji — JEDEN styl: nagłówek panelu, sekcja w panelu
   przestrzeni (`.pp-etykieta`) i grupa w palecie Ctrl+K. Licznik obok
   („INCYDENTY · 3") w tym samym kroju, bez osobnych 12 px (audyt UI, L-01). */
/* Nagłówek sekcji zdaniem (od 1 listopada bez wersalików) niesie hierarchię
   wielkością i kolorem: 13 px w kolorze treści, waga 500. Szare 11 px, które
   wystarczały wersalikom, zdaniem wyglądało mniej ważnie niż wiersze pod
   spodem (uwaga właściciela). Podpis grupy w Ctrl+K i nad kaflem zostaje
   drobny — tam etykieta nie tytułuje sekcji, tylko opisuje rzecz obok. */
.panel-label, .pp-etykieta {
  font-size: var(--fs-akcent);
  font-weight: 500;
  color: var(--foreground);
}
.cmdk-group-label, .tile > .panel-label {
  font-size: var(--fs-etykieta);
  font-weight: 500;
  color: var(--text-secondary);
}
:is(.panel-label, .pp-etykieta, .cmdk-group-label) .row-meta { font: inherit; letter-spacing: inherit; color: var(--text-secondary); }

.panel-pad > .panel-label, .tile > .panel-label { margin-bottom: 8px; }

.empty-note {
  padding: 18px 16px;
  color: var(--text-secondary);
  font-size: var(--fs-tresc);
}

/* Pusty widok: stan rzeczy pełnym kontrastem, następna czynność pod spodem. */
/* Tylko panel-pustka: `i.pusto` w wykresie („brak pomiaru") to inna rzecz. */
.panel.pusto {
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: 220px;
  padding: 40px 28px;
}

.pusto-tytul {
  margin: 0;
  max-width: 52ch;
  color: var(--foreground);
  font-size: var(--fs-tytul-karty);
  font-weight: 500;
}

.pusto-tresc {
  margin: 10px 0 0;
  max-width: 62ch;
  color: var(--text-secondary);
  font-size: var(--fs-tresc);
  line-height: 1.6;
}

.pusto-tresc code {
  padding: 1px 4px;
  border-radius: 4px;
  background: var(--muted);
  color: var(--foreground);
  font-family: var(--mono);
  font-size: var(--fs-meta);
}

/* ---- Rytm pionowy karty (2026-09-17) ------------------------------------
   Do tej pory odstęp między sekcjami miał cztery źródła (.panel + .panel
   12 px, .stack-mt 16 px, .tiles 20 px, .sekcja 20 px) i 148 ręcznych
   marginesów w widokach. Teraz odstęp daje KONTENER: każde bezpośrednie
   dziecko karty stoi 12 px pod poprzednim, a grupy (kafle, nagłówek grupy)
   dostają 20 px. Widok nie wpisuje marginesów między sekcjami. */
:root { --odstep-sekcji: 12px; --odstep-grupy: 20px; }
.card > * + * { margin-top: var(--odstep-sekcji); }
.card > .card-sub { margin-top: 0; }
.card > .tiles + *, .card > * + .tiles { margin-top: var(--odstep-grupy); }
.card > .section-head { margin-top: var(--odstep-grupy); }
.card > .section-head + * { margin-top: 8px; }
.card > .card-title-row + .tiles, .card > .card-head + .tiles, .card > .card-sub + .tiles { margin-top: var(--odstep-sekcji); }
/* Zagnieżdżone (w kolumnie, w rozwinięciu): ta sama odległość z klasy. */
.stack-mt { margin-top: var(--odstep-sekcji); }

.split { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }

/* Etykieta sekcji stojąca samodzielnie między panelami. */
.section-head {
  /* Odstępy nad i pod daje rytm karty; poza kartą (arkusz, rozwinięcie) — 20/8. */
  margin: 20px 0 8px;
  font-size: var(--fs-akcent);
  font-weight: 500;
  color: var(--foreground);
}

/* -------------------------------------------------------------------- karta */

.card { display: block; }

.card-head {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 14px;
  min-height: 30px;
}

.card-id {
  font-size: var(--fs-etykieta);
  font-weight: 500;
  color: var(--text-secondary);
}

/* Zakładki karty (rzadkie): ten sam przełącznik segmentowy co `.okna`. */
.card-tabs {
  margin-left: auto;
  display: inline-flex;
  gap: 2px;
  height: 30px;
  padding: 2px;
  border-radius: var(--r-pill);
  background: var(--neutral-bg);
  box-shadow: inset 0 0 0 1px var(--neutral-border);
}

.card-tabs button {
  height: 24px;
  padding: 0 12px;
  border: 0;
  border-radius: var(--r-pill);
  background: transparent;
  color: var(--text-secondary);
  font: inherit;
  font-size: var(--fs-kontrolka);
  font-weight: 500;
  cursor: pointer;
  white-space: nowrap;
  transition: background-color var(--t) var(--ease), color var(--t) var(--ease), box-shadow var(--t) var(--ease);
}

.card-tabs button:hover { color: var(--foreground); }
.card-tabs button.active { background: var(--card); color: var(--foreground); box-shadow: var(--faza); }

.card-sub { margin: 0 0 14px; font-size: var(--fs-tresc); color: var(--text-secondary); }

/* ------------------------------------------------------------------ wiersze */

.rows { display: block; }

/* Wiersz 42 px jak w tabeli wzorca: 8 px pionowego luzu wokół 26-pikselowej
   akcji, 16 px z boku. Kreska dzieląca zostaje — to struktura, nie głębia. */
.row {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 42px;
  padding: 8px 16px;
  border-bottom: 1px solid var(--border);
  font-size: var(--fs-tresc);
}

.panel > .row:last-child, .rows > .row:last-child { border-bottom: 0; }

.row-name { display: inline-flex; align-items: center; gap: 8px; min-width: 0; flex: 1; }
.row-name > span:not([class]) { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.row-meta { color: var(--text-secondary); font-size: var(--fs-meta); white-space: nowrap; }
.row-meta.wrap { white-space: normal; }
.row-amount { margin-left: auto; white-space: nowrap; }

/* Najlepsza wartość w kolumnie porównania: kolor I waga naraz — samo
   pogrubienie ginie w wierszu liczb, sam kolor nie działa dla wszystkich. */
.lider { color: var(--ok); font-weight: 500; }
.row-metrics { display: inline-flex; align-items: center; gap: 10px; flex: none; }
/* Kwota stoi na końcu wiersza: obok pigułki zmiennej szerokości kwoty nie tworzyły kolumny. */
.kwota-kolumna { min-width: 84px; text-align: right; font-variant-numeric: tabular-nums; }
.pill.nazwa { text-transform: none; }

.ellipsis {
  display: block;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Ten sam powód: link w uciętym tekście gubił obwódkę poza dolną kreską. */
.ellipsis > a:focus-visible { outline-offset: -2px; }

/* Lista z grupami (`listaGrup` w wspolne.js): jeden panel, wiersze jeden
   pod drugim, nagłówek grupy w środku tam, gdzie grupa ma go za co pokazać.
   Kreskę nad nagłówkiem daje dolna kreska wiersza wyżej — własny border-top
   dokładał drugą i na granicy grup wychodziło 2 px. Ostatni wiersz bez
   dolnej kreski, bo tę robi krawędź panelu. */
.lista-grup .grupa { padding: 12px 16px 4px; }
.lista-grup > .row:last-child { border-bottom: 0; }
.lista-grup .empty-note { border-bottom: 1px solid var(--border); }
.lista-grup .empty-note:last-child { border-bottom: 0; }

/* Wiersz dwupoziomowy: treść u góry, metadane pod spodem. */
.row-stack {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  min-width: 0;
  flex: 1;
}

.row-stack > * { max-width: 100%; }

/* Hover wiersza: 100 ms na samym tle — to jest interakcja wysokiej
   częstotliwości, dostaje najmniejsze możliwe przejście. */
.row.clickable { cursor: pointer; transition: background-color var(--t-szybko) var(--ease); }
.row.clickable:hover { background: var(--card-2); }
.row.clickable:focus-visible { outline-offset: -2px; }

/* Drobne akcje w wierszu: pastylka 26 px z fazą. Mniejsza niż .btn,
   żeby lista nie wyglądała jak formularz. */
.row-act {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 26px;
  padding: 0 10px;
  border: 0;
  border-radius: var(--r-pill);
  background: var(--card);
  box-shadow: var(--faza);
  color: var(--foreground);
  font: inherit;
  font-size: var(--fs-kontrolka);
  font-weight: 500;
  line-height: 1;
  cursor: pointer;
  white-space: nowrap;
  transition: box-shadow var(--t) var(--ease), color var(--t) var(--ease), background-color var(--t) var(--ease), scale var(--t) var(--ease);
}

/* Hover i wciśnięcie tylko dla aktywnych; :where nie podnosi specyficzności,
   więc reguły kontekstowe dalej wygrywają tak jak dotąd. */
.row-act:hover:where(:not(:disabled)) { box-shadow: var(--faza-hover); }
.row-act:active:where(:not(:disabled)) { scale: .96; }
.row-act.danger:hover:where(:not(:disabled)) { color: var(--bad-tekst); background: var(--bad-bg); box-shadow: 0 0 0 1px var(--bad-border); }
.row-act:disabled { opacity: .5; cursor: default; scale: 1; }

/* Na telefonie metryki schodzą pod nazwę strony. */
@media (max-width: 720px) {
  .row.site-row { flex-wrap: wrap; }
  .row.site-row .row-metrics { width: 100%; justify-content: flex-end; }
}

/* ---------------------------------------------------------- pigułki, badge */

/* Pigułka stanu: tło, obrys i tekst w JEDNYM tonie (tagi ze wzorca),
   kropka z przodu, 22 px. Obrys przez `box-shadow inset`, żeby nie zmieniał
   wymiaru względem pigułek bez obrysu. */
.pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 22px;
  padding: 0 8px;
  border: 0;
  border-radius: var(--r-pill);
  background: var(--neutral-bg);
  box-shadow: inset 0 0 0 1px var(--neutral-border);
  color: var(--neutral-tekst);
  font-size: var(--fs-meta);
  font-weight: 500;
  letter-spacing: 0;
  line-height: 1;
  text-transform: lowercase;
  white-space: nowrap;
}

.pill::before { content: ""; flex: none; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.pill.operational { color: var(--ok-tekst); background: var(--ok-bg); box-shadow: inset 0 0 0 1px var(--ok-border); }
.pill.degraded { color: var(--warn-tekst); background: var(--warn-bg); box-shadow: inset 0 0 0 1px var(--warn-border); }
.pill.down { color: var(--bad-tekst); background: var(--bad-bg); box-shadow: inset 0 0 0 1px var(--bad-border); }
.pill.unknown { color: var(--neutral-tekst); background: var(--neutral-bg); box-shadow: inset 0 0 0 1px var(--neutral-border); }

/* Odznaka w treści wiersza („SSL 12 dni"): ta sama rodzina, bez kropki,
   o stopień mniejsza. */
.hchip {
  display: inline-flex;
  align-items: center;
  height: 20px;
  padding: 0 8px;
  border-radius: var(--r-pill);
  background: var(--neutral-bg);
  box-shadow: inset 0 0 0 1px var(--neutral-border);
  color: var(--neutral-tekst);
  font-size: var(--fs-drobne);
  font-weight: 500;
  line-height: 1;
  white-space: nowrap;
}

.hchip.ok { color: var(--ok-tekst); background: var(--ok-bg); box-shadow: inset 0 0 0 1px var(--ok-border); }
.hchip.warn { color: var(--warn-tekst); background: var(--warn-bg); box-shadow: inset 0 0 0 1px var(--warn-border); }
.hchip.bad { color: var(--bad-tekst); background: var(--bad-bg); box-shadow: inset 0 0 0 1px var(--bad-border); }

.badge {
  display: inline-flex;
  align-items: center;
  height: 18px;
  padding: 0 8px;
  border: 0;
  border-radius: var(--r-pill);
  background: var(--neutral-bg);
  box-shadow: inset 0 0 0 1px var(--neutral-border);
  color: var(--neutral-tekst);
  font-size: var(--fs-etykieta);
  font-weight: 500;
  letter-spacing: .06em;
  line-height: 1;
  text-transform: uppercase;
  white-space: nowrap;
}

.badge.ok, .badge.new, .badge.feat { color: var(--ok-tekst); background: var(--ok-bg); box-shadow: inset 0 0 0 1px var(--ok-border); }
.badge.bad, .badge.fix { color: var(--bad-tekst); background: var(--bad-bg); box-shadow: inset 0 0 0 1px var(--bad-border); }
.badge.improved, .badge.perf { color: var(--warn-tekst); background: var(--warn-bg); box-shadow: inset 0 0 0 1px var(--warn-border); }

/* ---------------------------------------------------------------- przyciski */

/* Przycisk główny: pastylka w akcencie, jasna krawędź górna (faza pełna),
   wciśnięcie 0,96 na 150 ms — dokładnie te wartości, nie „mniej więcej".
   Ikona po stronie ikony dostaje 2 px mniej wypełnienia (wyrównanie
   optyczne), stąd ujemny margines svg. Wysokość i pismo jak pastylka i pole obok
   (`--h-kontrolka`, `--fs-kontrolka`) — główny wyróżnia KOLOR, nie rozmiar:
   „Zapisz frazy" o stopień większe od reszty panelu wyglądało jak pomyłka. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: var(--h-kontrolka);
  padding: 0 12px;
  border: 0;
  border-radius: var(--r-pill);
  background: var(--brand);
  box-shadow: var(--faza-pelna);
  color: var(--brand-fg);
  font: inherit;
  font-size: var(--fs-kontrolka);
  font-weight: 500;
  line-height: 1;
  cursor: pointer;
  white-space: nowrap;
  transition: background-color var(--t) var(--ease), box-shadow var(--t) var(--ease), color var(--t) var(--ease), scale var(--t) var(--ease);
}

.btn:hover:where(:not(:disabled)) { background: var(--brand-hover); }
.btn:active:where(:not(:disabled)) { scale: .96; }
.btn:disabled { opacity: .5; cursor: default; scale: 1; }
.btn > svg:first-child { margin-left: -2px; }
.btn svg { width: 15px; height: 15px; stroke: currentColor; fill: none; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }

.btn.secondary, .btn.ghost {
  background: var(--card);
  box-shadow: var(--faza);
  color: var(--foreground);
}

.btn.secondary:hover:where(:not(:disabled)), .btn.ghost:hover:where(:not(:disabled)) { background: var(--card); box-shadow: var(--faza-hover); }

.btn.danger { background: var(--bad-bg); color: var(--bad-tekst); box-shadow: 0 0 0 1px var(--bad-border); }
.btn.danger:hover:where(:not(:disabled)) { background: color-mix(in srgb, var(--bad) 14%, var(--bad-bg)); }

/* Rząd przycisków zawsze 12 px pod tym, co nad nim — widoki wpisywały tu
   siedem różnych wartości (6–18 px). Na początku kontenera bez odstępu. */
.btn-row { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-top: 12px; }
.btn-row:first-child, .panel-label + .btn-row { margin-top: 0; }

/* Pastylka narzędziowa (nagłówek zakładki, pasek, arkusz): 30 px z fazą. */
.chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: var(--h-kontrolka);
  padding: 0 12px;
  border: 0;
  border-radius: var(--r-pill);
  background: var(--card);
  box-shadow: var(--faza);
  color: var(--foreground);
  font: inherit;
  font-size: var(--fs-kontrolka);
  font-weight: 500;
  line-height: 1;
  cursor: pointer;
  white-space: nowrap;
  transition: box-shadow var(--t) var(--ease), background-color var(--t) var(--ease), color var(--t) var(--ease), scale var(--t) var(--ease);
}

.chip:hover:where(:not(:disabled)) { box-shadow: var(--faza-hover); }
.chip:active:where(:not(:disabled)) { scale: .96; }
.chip:disabled { opacity: .5; cursor: default; }
.chip.static { cursor: default; }
.chip.static:active { scale: 1; }
.chip.ghost { color: var(--foreground); }
.chip.ghost:hover { color: var(--foreground); }
/* Stan „rozwinięte" (Zwiń) — ciemne tło z .chip.ghost.active dostawało ciemny tekst z reguły wyżej. */
.chip.ghost.active, .chip.ghost.active:hover { color: var(--primary-fg); }

.chip-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--idle); flex: none; }
.chip-dot.up { background: var(--ok); }
.chip-dot.warn { background: var(--warn); }
.chip-dot.down { background: var(--bad); }

.plainlink { color: var(--muted-fg); text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: from-font; }
.plainlink:hover { color: var(--foreground); }
/* Tytuł dokumentu w liście to nazwa wiersza, nie boczny odnośnik. */
.plainlink.tytul-dok { color: var(--foreground); }

/* Pole pliku: przycisk przeglądarki „Choose File" ubrany w tę samą pastylkę
   co reszta akcji, nazwa wybranego pliku obok w kolorze pomocniczym. Samo
   pole zostaje natywne — klawiatura i czytnik nie tracą nic. */
input[type="file"].row-act {
  display: inline-flex;
  align-items: center;
  height: auto;
  min-height: 26px;
  padding: 0;
  background: transparent;
  box-shadow: none;
  color: var(--text-secondary);
  font-size: var(--fs-kontrolka);
  cursor: pointer;
}
input[type="file"].row-act::file-selector-button {
  height: 26px;
  margin-right: 8px;
  padding: 0 10px;
  border: 0;
  border-radius: var(--r-pill);
  background: var(--card);
  box-shadow: var(--faza);
  color: var(--foreground);
  font: inherit;
  font-size: var(--fs-kontrolka);
  font-weight: 500;
  cursor: pointer;
  transition: box-shadow var(--t) var(--ease);
}
input[type="file"].row-act:hover::file-selector-button { box-shadow: var(--faza-hover); }
input[type="file"].row-act:focus-visible { outline: none; }
input[type="file"].row-act:focus-visible::file-selector-button { outline: 2px solid var(--fokus); outline-offset: 2px; }

/* Liczba w tonie stanu: wpływ na zielono, strata na czerwono. Tylko liczby
   i fragmenty zdań — pigułki mają własne tło i własną regułę. */
.liczba.ok, .row-meta .ok { color: var(--ok); }
.liczba.warn, .row-meta .warn, .row-meta.warn { color: var(--warn-tekst); }
.liczba.bad, .row-meta .bad { color: var(--bad); }

/* --------------------------------------------------------------- formularze */

.field { display: block; margin-bottom: 12px; }

/* Etykieta pola: zdanie, `--fs-meta`, waga 500 — wersaliki zostają przy
   etykietach GRUP (dzielą), etykieta pola tytułuje jedno pole. */
.field > label, .field > span {
  display: block;
  margin-bottom: 4px;
  font-size: var(--fs-meta);
  font-weight: 500;
  color: var(--text-secondary);
}

/* Pole: obrys zostaje kreską (dostępność), wysokość i pismo jak przycisk
   obok (`--h-kontrolka`, `--fs-tresc`), promień 8. Fokus
   akcentem z poświatą 3 px. */
.field input, .field select, .field textarea,
.rm-add input, .rm-add select, .rn-bar select,
.blok input, .blok textarea {
  width: 100%;
  height: var(--h-kontrolka);
  padding: 0 10px;
  border: 1px solid var(--input);
  border-radius: var(--r-s);
  background: var(--card);
  color: var(--foreground);
  font: inherit;
  font-size: var(--fs-tresc);
  transition: border-color var(--t) var(--ease), box-shadow var(--t) var(--ease);
}

.field textarea, .blok textarea { height: auto; padding: 8px 10px; resize: vertical; line-height: 1.5; }

.field input:focus, .field select:focus, .field textarea:focus,
.rm-add input:focus, .rm-add select:focus, .rn-bar select:focus,
.blok input:focus, .blok textarea:focus {
  outline: none;
  border-color: var(--brand);
  box-shadow: 0 0 0 3px var(--brand-soft);
}

.field input::placeholder, .field textarea::placeholder,
.blok input::placeholder, .blok textarea::placeholder { color: var(--text-secondary); opacity: 1; }

.field-row { display: flex; gap: 12px; }
.field-row > .field { flex: 1; min-width: 0; }
/* Rząd pól, który sam jest ostatnią rzeczą w bloku (siatki w Ustawieniach,
   wiersz kontaktu): pola bez dolnego marginesu. Nie dla wszystkich .field-row,
   bo w formularzach kolejne rzędy dostają odstęp właśnie z .field. */
.field-row.zwarty > .field { margin-bottom: 0; }

.siatka-pol { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 10px 12px; }
.siatka-pol .field > label { font-size: var(--fs-meta); }
/* Formularz dodawania pod zdaniem pomocy (konto, szablon, klucz MCP): ten sam oddech co .btn-row. */
.help + .siatka-pol { margin-top: 12px; }
/* Pole obowiązkowe, które zostało puste. */
.field input.brak { border-color: var(--bad); }

/* Pasek zasłony — ma się odróżniać od pól, bo mówi, DLACZEGO są puste. */
.zaslona { display: flex; flex-direction: column; padding: 12px 14px; border-radius: var(--r); background: var(--card-2); box-shadow: var(--cien-ramka); }
.zaslona.odkryte { flex-direction: row; align-items: center; gap: 12px; }
.field input:disabled, .field select:disabled, .field textarea:disabled { opacity: .55; cursor: not-allowed; }

/* Akapit pomocy: 8 px od tego, co nad nim (wartość, którą i tak wpisywano
   ręcznie w połowie miejsc), 10 px do pól pod nim, zero na początku. */
.help { margin: 8px 0 0; font-size: var(--fs-meta); color: var(--text-secondary); line-height: 1.5; max-width: 72ch; }
.help:first-child { margin-top: 0; }
.panel-label + .help, .field > .help { margin-top: 4px; }
.panel-head + .help { margin: 0 16px 10px; }
.help + .field, .help + .field-row, .help + .okna, .help + .row, .help + .panel { margin-top: 10px; }
.help.pelna { max-width: none; }

.toggle {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: var(--fs-tresc);
  cursor: pointer;
}

.toggle input { width: 16px; height: 16px; margin: 0; accent-color: var(--brand); }
/* Kilka pól wyboru obok siebie: każde to osobne `label.toggle.lista` (kanon
   z Pulpitu), a rząd łamie się na wąskim ekranie zamiast wychodzić poza
   arkusz (audyt UI, L-22 e). */
.lista-pol { display: flex; flex-wrap: wrap; gap: 8px 16px; }

/* Ikona zdarzenia w historii firmy — jeden znak zamiast kolorowej plamy. */
.tl-icon {
  flex: none;
  width: 18px;
  text-align: center;
  font-family: var(--mono);
  font-size: var(--fs-meta);
  color: var(--muted-fg);
}

.tl-icon.bad { color: var(--bad); }
.tl-icon.warn { color: var(--warn-tekst); }
.tl-icon.ok { color: var(--ok); }

/* --------------------------------------------------------------- log/wpisy */

.log-entry {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 10px 16px;
  border-bottom: 1px solid var(--border);
}

.log-entry:last-child { border-bottom: 0; }

.log-main { flex: 1; min-width: 0; }
.log-title { display: flex; align-items: center; gap: 8px; font-size: var(--fs-akcent); }
.log-body { margin: 4px 0 0; font-size: var(--fs-tresc); color: var(--muted-fg); }
.log-age { flex: none; color: var(--text-secondary); font-size: var(--fs-meta); white-space: nowrap; }

/* ------------------------------------------------------------- szkielety

   Kształt tego, co zaraz przyjdzie — zamiast zdania „Wczytuję…". Odróżnia
   „nie ma jeszcze danych" od „nie ma nic do pokazania". Puls, nie połysk:
   połysk przy ośmiu kartach naraz robi się dyskoteką. */
.szk {
  display: block;
  border-radius: 4px;
  background: var(--muted);
  animation: szk-puls 1.4s ease-in-out infinite;
}

@keyframes szk-puls {
  0%, 100% { opacity: 1; }
  50% { opacity: .5; }
}

@media (prefers-reduced-motion: reduce) {
  .szk { animation: none; opacity: .75; }
}

.szk-karta { cursor: default; }
.szk-karta:hover { box-shadow: var(--cien-ramka); }

.szk-nadlinia { width: 88px; height: 12px; margin-bottom: 12px; }
.szk-tytul { width: 360px; max-width: 72%; height: 28px; }
.szk-etyk { width: 84px; height: 14px; }
.szk-liczba { width: 148px; height: 34px; margin-top: auto; }
.szk-opis { width: 108px; height: 12px; margin-top: 12px; }
.szk-sub { width: 280px; max-width: 60%; height: 12px; margin-bottom: 16px; }

.szk-wiersz { display: flex; align-items: center; gap: 16px; }
.szk-wiersz .szk-nazwa { height: 14px; }
.szk-wiersz .szk-metr { width: 72px; height: 12px; margin-left: auto; }

/* ---------------------------------------------------------- siatka dostępności */

.uptime-grid {
  display: flex;
  gap: 2px;
  align-items: stretch;
  height: 30px;
  margin-top: 12px;
}

.uptime-grid i {
  flex: 1 1 0;
  min-width: 2px;
  border-radius: 1px;
  background: var(--muted);
}

@media (max-width: 560px) {
  .uptime-grid { gap: 1px; }
  .uptime-grid i { min-width: 1px; }
}

/* Klasy dnia pochodzą z detailCard: operational | degraded | down | (puste = brak danych). */
.uptime-grid i.operational, .uptime-grid i.up { background: var(--ok); }
.uptime-grid i.degraded, .uptime-grid i.warn { background: var(--warn); }
.uptime-grid i.down { background: var(--bad); }

/* ------------------------------------------------------------------ wykresy */

/* Siatka kreskowana 3 3, brak linii osi, opisy 10 px, linia 2 px. Oś rysuje
   HTML, przebieg SVG: inaczej rozciąganie deformowałoby tekst razem z nim. */

.chart { display: flex; gap: 8px; height: 120px; margin-top: 12px; }

.chart-y {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  flex: none;
  font-size: var(--fs-drobne);
  color: var(--chart-axis);
  font-family: var(--mono);
  text-align: right;
  margin: -4px 0;
  line-height: 11px;
}

.chart-plot { position: relative; flex: 1; min-width: 0; }

.chart-siatka {
  position: absolute;
  inset: 0;
  background-size: 100% 1px;
  background-position: 0 0, 0 33.33%, 0 66.66%, 0 100%;
  background-repeat: no-repeat;
  background-image:
    repeating-linear-gradient(to right, var(--chart-grid) 0 3px, transparent 3px 6px),
    repeating-linear-gradient(to right, var(--chart-grid) 0 3px, transparent 3px 6px),
    repeating-linear-gradient(to right, var(--chart-grid) 0 3px, transparent 3px 6px),
    repeating-linear-gradient(to right, var(--chart-grid) 0 3px, transparent 3px 6px);
}

.chart-bars {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: flex-end;
  gap: 2px;
}

.chart-bars b { flex: 1 1 0; min-width: 2px; border-radius: 2px 2px 0 0; background: var(--chart-line); }
.chart-bars b.empty { background: var(--muted); }

.chart-svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }

.chart-krzywa { fill: none; stroke: var(--chart-line); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.chart-punkt { fill: var(--chart-line); stroke: none; }
.chart-obszar { fill: url(#fmObszar); stroke: none; }

/* Warstwa trafień: kolumna na punkt danych, podpowiedź nad nią. */
.chart-hits { position: absolute; inset: 0; display: flex; }
.chart-hits > i { flex: 1 1 0; min-width: 0; position: relative; cursor: default; }
.chart-hits > i:hover { background: color-mix(in srgb, var(--foreground) 6%, transparent); }

.chart-hits .tip {
  border-radius: var(--r-s);
  display: none;
  position: absolute;
  bottom: calc(100% + 6px);
  left: 50%;
  transform: translateX(-50%);
  z-index: 5;
  min-width: 96px;
  padding: 8px 8px;
  background: var(--card);
  box-shadow: var(--cien-pop);
  color: var(--foreground);
  font-family: var(--mono);
  font-size: var(--fs-drobne);
  line-height: 1.5;
  white-space: nowrap;
}

.chart-hits .tip b { display: block; color: var(--text-secondary); font-weight: 400; }
.chart-hits > i:hover .tip { display: block; }
.chart-hits > i:first-child .tip { left: 0; transform: none; }
.chart-hits > i:last-child .tip { left: auto; right: 0; transform: none; }

.chart-kropki { position: absolute; inset: 0; }
.chart-kropki i {
  position: absolute;
  width: 5px;
  height: 5px;
  margin: 0 0 -2.4px -2.4px;
  border-radius: 50%;
  background: var(--chart-line);
  border: 2px solid var(--card);
  box-sizing: content-box;
}

.chart-x {
  display: flex;
  justify-content: space-between;
  margin-top: 8px;
  font-size: var(--fs-drobne);
  color: var(--chart-axis);
  font-family: var(--mono);
}

.chart-empty { margin-top: 12px; color: var(--text-secondary); font-size: var(--fs-tresc); }

.bar {
  position: relative;
  height: 6px;
  border-radius: 3px;
  background: var(--muted);
  overflow: hidden;
}

.bar > i { position: absolute; inset: 0 auto 0 0; border-radius: 3px; background: var(--chart-line); }

/* PASEK POSTĘPU — jeden kształt dla wszystkich (audyt UI, L-06): 6 px,
   zaokrąglone końce, tor `--muted` (token tylko na tory pasków i od
   początku dominujący: .progress, .budget, .bar; `--accent` i `--border`
   to tła zaznaczenia i kreski, w ciemnym motywie `--accent` zlewał się
   z torem). Wypełnienie neutralne `--text-secondary`, stan nadpisują
   klasy ok/warn/bad. Wcześniej trzy wysokości (4/6/8 px) i trzy tory. */
.progress, .budget, .godz-pasek i, .proj-budzet-pasek, .real-pasek { display: block; height: 6px; border-radius: var(--r-pill); background: var(--muted); overflow: hidden; }
.progress > i, .budget > i, .godz-pasek b, .proj-budzet-pasek b, .real-pasek i { display: block; height: 100%; border-radius: var(--r-pill); background: var(--text-secondary); }

/* Mini-wykres w katalogu metryk. */
.spark { display: inline-flex; align-items: flex-end; gap: 2px; height: 22px; width: 90px; }
.spark b { flex: 1 1 0; min-height: 2px; border-radius: 1px; background: var(--chart-line); }

/* -------------------------------------------------------------- roadmapa */

.lanes { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }

.lane-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 16px 8px;
}

.lane-items { padding: 0 16px 12px; }

.lane-item {
  display: flex;
  gap: 8px;
  align-items: flex-start;
  padding: 8px 0;
  font-size: var(--fs-tresc);
  line-height: 1.4;
}

.lane-item + .lane-item { border-top: 1px solid var(--border); }

.lane-item i {
  flex: none;
  margin-top: 8px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--chart-line);
}

.lane-item.done { color: var(--text-secondary); text-decoration: line-through; }
.lane-item.done i { background: var(--ok); }

.lane-text { flex: 1; min-width: 0; }

/* Akcje wiersza roadmapy: obecne w DOM, wchodzą pod kursorem przezroczystością
   (nie `display`), żeby nie skakał układ; na dotyku zawsze widoczne. */
.lane-actions { display: inline-flex; gap: 2px; flex: none; opacity: 0; transition: opacity var(--t) var(--ease); }
.lane-item:hover .lane-actions, .lane-item:focus-within .lane-actions { opacity: 1; }
@media (hover: none) { .lane-actions { opacity: 1; } }

.lane-actions button {
  width: 24px;
  height: 24px;
  padding: 0;
  border: 0;
  border-radius: var(--r-pill);
  background: var(--card);
  box-shadow: var(--faza);
  color: var(--muted-fg);
  font: inherit;
  font-size: var(--fs-kontrolka);
  line-height: 1;
  cursor: pointer;
  transition: box-shadow var(--t) var(--ease), color var(--t) var(--ease);
}

.lane-actions button:hover { color: var(--foreground); box-shadow: var(--faza-hover); }

.rm-add { display: flex; gap: 8px; align-items: center; }
.rm-add input { flex: 1; min-width: 0; }
.rm-add select { width: auto; min-width: 140px; }
.rm-add .btn { height: var(--h-kontrolka); flex: none; }

@media (max-width: 560px) {
  .rm-add { flex-wrap: wrap; }
  .rm-add input { flex-basis: 100%; }
}

/* ------------------------------------------------------------- heatmapa git */

.hm-scroll { --hm-c: 11px; overflow-x: auto; margin-top: 12px; padding-bottom: 2px; }

.hm-months {
  display: grid;
  gap: 4px;
  margin-bottom: 4px;
  font-family: var(--mono);
  font-size: var(--fs-drobne);
  color: var(--text-secondary);
}

.hm-months span { grid-row: 1; white-space: nowrap; overflow: hidden; }

.hm-grid {
  display: grid;
  grid-template-rows: repeat(7, var(--hm-c));
  grid-auto-flow: column;
  gap: 4px;
}

.hm-grid i, .hm-legend i { width: var(--hm-c); height: var(--hm-c); border-radius: 2px; background: var(--muted); }

.hm-grid i.l1, .hm-legend i.l1 { background: color-mix(in srgb, var(--chart-line) 25%, var(--muted)); }
.hm-grid i.l2, .hm-legend i.l2 { background: color-mix(in srgb, var(--chart-line) 50%, var(--muted)); }
.hm-grid i.l3, .hm-legend i.l3 { background: color-mix(in srgb, var(--chart-line) 75%, var(--muted)); }
.hm-grid i.l4, .hm-legend i.l4 { background: var(--chart-line); }

.hm-legend {
  --hm-c: 10px;
  display: flex;
  align-items: center;
  gap: 4px;
  margin-top: 12px;
  font-size: var(--fs-drobne);
  color: var(--text-secondary);
}

.hm-legend i:first-of-type { margin-left: 4px; }
.hm-legend i:last-of-type { margin-right: 4px; }

/* ------------------------------------------------------------ release notes */

.rn-bar { display: flex; gap: 12px; align-items: center; padding: 12px 16px; }
.rn-bar select { flex: 1; min-width: 0; max-width: 360px; }
.rn-count { margin-left: auto; font-size: var(--fs-meta); color: var(--text-secondary); white-space: nowrap; }

/* Pasek zużycia budżetu godzin w kartotece firmy (kształt: „pasek postępu"). */
.budget { margin-top: 8px; }
.budget > i.over { background: var(--bad); }

/* Pole upuszczania plików — kreskowana ramka, bo to jedyne miejsce
   w interfejsie, które zaprasza do przeciągnięcia czegoś z zewnątrz. */
.dropzone {
  border: 1px dashed var(--border-strong);
  border-radius: var(--r);
  background: var(--card-2);
  padding: 20px;
  text-align: center;
  color: var(--muted-fg);
  font-size: var(--fs-tresc);
  transition: background-color var(--t) var(--ease), border-color var(--t) var(--ease);
}

.dropzone.over {
  border-color: var(--brand);
  background: var(--brand-soft);
  color: var(--foreground);
}

.dropzone p { margin: 0; }

/* --------------------------------------------------------------- diagnoza */

.row-stack.incident {
  gap: 0;
  padding: 10px 16px;
  border-bottom: 1px solid var(--border);
}

.row-stack.incident:last-child { border-bottom: 0; }
/* Wiersz wewnątrz karty incydentu nie ma własnej kreski ani wcięcia —
   daje je karta. Wcześniej to samo pisało dziewięć inline'ów w widokach. */
.row-stack.incident > .row { width: 100%; border: 0; padding: 0; }
/* Linijki pod wierszem (błąd, powód, argumenty, dowód) — odstęp daje karta,
   nie `style="margin-top:6px"` w widoku. */
.row-stack.incident > * + * { margin-top: 4px; }
.btn-row + .row-meta:not(:empty) { margin-top: 8px; }

/* Ikona linii przy nazwie (`ikonaWiersza` w widoki/wspolne.js) — zamiast emoji.
   Kolor roli drugorzędnej; w ostrzeżeniu i w dopisku bierze kolor tekstu. */
.ik { display: inline-block; flex: none; width: 14px; height: 14px; margin-right: 8px; vertical-align: -2px; stroke: currentColor; fill: none; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; color: var(--text-secondary); }
.warn > .ik, .row-meta .ik { color: inherit; }
.row-meta .ik { width: 12px; height: 12px; margin-right: 4px; }

.diagnoza {
  border-radius: var(--r-s);
  width: 100%;
  margin-top: 8px;
  padding: 12px 12px;
  border-left: 2px solid var(--border-strong);
  background: var(--card-2);
  font-size: var(--fs-tresc);
  line-height: 1.55;
}

.diagnoza-head {
  color: var(--text-secondary);
  font-size: var(--fs-etykieta);
  margin-bottom: 8px;
}

.diagnoza p { margin: 0; }
.diagnoza ol { margin: 8px 0 0; padding-left: 16px; }
.diagnoza li { margin-bottom: 4px; }

/* Runbook rozwinięty w wierszu: monospace, zawijanie i sufit wysokości. */
.runbook-tresc {
  margin: 6px 0 0; padding: 10px 12px;
  background: var(--card-2); border-radius: var(--r-s);
  font-size: var(--fs-meta); line-height: 1.6; color: var(--foreground);
  white-space: pre-wrap; word-break: break-word;
  max-height: 320px; overflow-y: auto;
}

/* Kolorowanie fragmentu zdania w treści wiersza — samo słowo, nie odznaka. */
.tone-bad { color: var(--bad); }
.tone-warn { color: var(--warn-tekst); }
.tone-ok { color: var(--ok); }

/* ------------------------------------------------------------------ arkusz */

/* Arkusz (szuflada z prawej). Wejście 220 ms na krzywej szuflady z lekkim
   przesunięciem i przezroczystością (`@starting-style`, bez JS); wyjście
   150 ms — krótsze niż wejście, bo uwaga już idzie gdzie indziej. Klasę
   `zamyka` stawia app.js na czas wyjścia i dopiero potem chowa element.
   Przejścia CSS, nie klatki kluczowe: da się je przerwać w pół drogi. */
.sheet { position: fixed; inset: 0; z-index: 60; }
.sheet[hidden] { display: none; }

.sheet-backdrop {
  position: absolute;
  inset: 0;
  background: var(--overlay);
  transition: opacity var(--t-wejscie) var(--ease-out);
}

.sheet-panel {
  position: absolute;
  inset: 0 0 0 auto;
  width: min(560px, 100%);
  display: flex;
  flex-direction: column;
  background: var(--card);
  box-shadow: var(--cien-pop);
  transition: transform var(--t-wejscie) var(--ease-drawer), opacity var(--t-wejscie) var(--ease-out);
}

@starting-style {
  .sheet-backdrop { opacity: 0; }
  .sheet-panel { transform: translateX(24px); opacity: 0; }
}

.sheet.zamyka .sheet-backdrop { opacity: 0; transition-duration: var(--t-wyjscie); }
.sheet.zamyka .sheet-panel { transform: translateX(16px); opacity: 0; transition-duration: var(--t-wyjscie); }

.sheet-head {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 20px;
  height: var(--pasek);
  min-height: var(--pasek);
  border-bottom: 1px solid var(--border);
}

.sheet-head h2 { margin: 0; font-size: var(--fs-tytul-karty); font-weight: 500; }
.sheet-head .chip { margin-left: auto; }

/* Treść arkusza na tle STRONY, nie karty: panele w środku mają się odcinać
   pierścieniem tak samo jak na scenie. Na tle karty panel na karcie znikał
   i wiersze Ustawień wyglądały jak luźne linie bez pudełka. */
.sheet-body { flex: 1; overflow-y: auto; padding: 20px; background: var(--background); }

/* Sekcja Ustawień: etykieta jak nagłówek sekcji na scenie, pod nią panel.
   Wcześniej etykieta była w stopniu podpisu pola, więc sekcja i pole
   formularza wyglądały tak samo, a wiersze bez panelu wisiały w powietrzu. */
.sekcja > label, .sekcja > summary > label {
  display: block;
  margin: 0 0 8px;
  font-size: var(--fs-akcent);
  font-weight: 500;
  color: var(--foreground);
}
.sekcja { margin-bottom: 20px; }
.sekcja .panel + .help, .sekcja .panel + .panel { margin-top: 8px; }
/* Przełącznik w wierszu panelu: kratka i tekst w jednej linii, kratka
   wyrównana do lewej krawędzi treści, nie do krawędzi panelu. */
.sekcja .row .toggle { display: flex; align-items: center; gap: 10px; }
.sekcja .row .toggle input { flex: none; }
/* POLE ZWARTE (30 px) — jedno dla każdego pola, które stoi w linii: w wierszu
   listy, obok przycisku, w tabeli katalogu usług. Formularz dodawania ma
   `.field` (34 px) z etykietą nad polem. Dawniej pól w linii było pięć
   kształtów, w tym pigułka `input.row-act` 26 px bez obrysu — pigułka jest
   dla przycisków (audyt UI, M-01). Klasa stoi albo na opakowaniu (etykieta
   i wąskie pole 64 px — wartości domyślne w Ustawieniach, cennik), albo
   wprost na polu (`input.ust-pole`). */
.ust-pole:not(input, select) { display: inline-grid; grid-template-columns: auto 64px; align-items: center; gap: 10px; }
.ust-pole input, .ust-pole select, input.ust-pole, select.ust-pole { height: 30px; padding: 0 8px; border: 1px solid var(--input); border-radius: var(--r-s); background: var(--card); color: var(--foreground); font: inherit; font-size: var(--fs-tresc); }
.ust-pole input, .ust-pole select { width: 64px; text-align: right; font-variant-numeric: tabular-nums; }
input.ust-pole, select.ust-pole { width: auto; min-width: 0; }
.ust-pole input:focus, .ust-pole select:focus, input.ust-pole:focus, select.ust-pole:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-soft); }
input.ust-pole::placeholder { color: var(--text-secondary); opacity: 1; }
input.ust-pole.warn { border-color: var(--warn); }
.ust-pole .jednostka { color: var(--text-secondary); font-size: var(--fs-tresc); text-align: right; white-space: nowrap; }
.ust-pole select { text-align: left; }
/* Wybór (waluta) nie mieści „PLN" obok strzałki w 64 px — rośnie do treści;
   prawa krawędź pól zostaje w jednej linii. */
.ust-pole:not(input, select):has(select) { grid-template-columns: auto minmax(64px, max-content); }
.ust-pole select { width: auto; min-width: 64px; }
/* Wartości domyślne na telefonie: etykieta i pole w JEDNYM rzędzie.
   Ogólne łamanie `.row` (pole na całą szerokość pod etykietą) robiło z
   każdej liczby wiersz na trzy linie; tu pole jest wąskie i mieści się
   obok etykiety, która sama się zawija, a opis zostaje pod nią. */
@media (max-width: 768px) {
  .row.ust-wiersz { flex-wrap: nowrap; }
  .row.ust-wiersz .row-stack { flex: 1 1 auto; }
  .row.ust-wiersz .row-metrics { width: auto; flex: none; }
}
/* Koszty: karty do zatwierdzenia nad miesiącami. Pola odczytu w karcie
   stoją po dwa w rzędzie, bo karta ma najwyżej ~300 px. */
.koszt-karty { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 280px), 1fr)); gap: 12px; align-items: start; }
.koszt-karta { display: flex; flex-direction: column; gap: 8px; padding: 12px 16px; min-width: 0; margin-top: 0; }
.koszt-karta-g { display: flex; align-items: flex-start; justify-content: space-between; gap: 8px; min-width: 0; }
.koszt-karta-g .row-amount { flex: none; }
.koszt-karta .btn-row { margin-top: 0; flex-wrap: wrap; }
.koszt-karta .koszt-pole .ust-pole { width: 100%; box-sizing: border-box; }
.koszt-popraw > summary { cursor: pointer; width: fit-content; }
.koszt-pola { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 8px; }
.panel-naglowek { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.panel-naglowek .panel-label { margin: 0; }
.koszt-pole { display: flex; flex-direction: column; gap: 4px; min-width: 0; font-size: var(--fs-drobne); color: var(--text-secondary); }
.koszt-kat { padding: 4px 16px 12px; }
.koszt-stos { display: flex; gap: 2px; height: 12px; }
.koszt-stos i { min-width: 4px; border-radius: 2px; background: var(--foreground); }
.koszt-stos-l { display: flex; flex-wrap: wrap; gap: 4px 16px; margin-top: 8px; }
/* Pole z przyciskiem albo kilka pól w jednej linii formularza (kompozytor posta). */
.pole-z-akcja { display: flex; gap: 6px; align-items: center; }
.field .pole-z-akcja > select { flex: 1; min-width: 0; width: auto; }
.field .pole-z-akcja > .btn { flex: none; }
.field .post-powtarzaj > #postPowtarzajCo { flex: none; width: 64px; }
.field .post-powtarzaj > #postPowtarzajKoniec { flex: none; width: 140px; }

/* Timer w pasku górnym — jedyny element z tykającą liczbą, więc ma
   wyglądać na żywy: pełne tło. */
.chip.timer {
  background: var(--primary);
  color: var(--primary-fg);
  box-shadow: var(--faza-pelna);
}

.chip.timer:hover { background: color-mix(in srgb, var(--primary) 88%, var(--background)); }
.chip.timer .chip-dot { background: var(--ok); }
.chip.timer .mono { font-variant-numeric: tabular-nums; }
/* Bezczynny stoper (od 26 września zawsze w pasku): spokojny, obrysowany. */
.chip.timer.bezczynny { background: transparent; color: var(--text-secondary); box-shadow: inset 0 0 0 1px var(--border-strong); }
.chip.timer.bezczynny:hover { color: var(--foreground); background: var(--accent); }
.chip.timer.bezczynny .chip-dot { background: var(--idle); }
.chip.timer.bezczynny .mono:empty { display: none; }
#timerWhat { max-width: 280px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.menu [role="menuitem"].naglowek:disabled { opacity: 1; cursor: default; font-size: var(--fs-etykieta); color: var(--text-secondary); padding-top: 6px; padding-bottom: 2px; }

/* Godziny przy zgłoszeniu i projekcie: „3,2 / 6 h" z paskiem (wspolne.js pasekGodzin) */
.godz-pasek { display: inline-flex; flex-direction: column; gap: 4px; min-width: 78px; font-size: var(--fs-meta); color: var(--text-secondary); }
.godz-pasek.warn { color: var(--warn-tekst); } .godz-pasek.warn b { background: var(--warn); }
.godz-pasek.bad { color: var(--bad-tekst); } .godz-pasek.bad b { background: var(--bad); }
/* Przycisk stopera w wierszu */
/* Rodzina akcji wiersza: 26 px z fazą, nie płaski obrys. */
.stoper-wiersz { flex: none; width: 26px; height: 26px; border-radius: 50%; border: 0; background: var(--card); box-shadow: var(--faza); color: var(--text-secondary); display: inline-grid; place-items: center; cursor: pointer; padding: 0; }
.stoper-wiersz svg { width: 11px; height: 11px; fill: currentColor; }
/* Zgłoszenia — lista z podglądem: wiersze po lewej, treść i następny krok
   wybranego po prawej. Układ liczony od szerokości panelu (obok stoi Kontekst):
   w wąskim podgląd zastępuje listę i wraca się przyciskiem „‹ Lista". */
.zgl-ramka { container: zgl / inline-size; }
.zgl-md { display: grid; grid-template-columns: minmax(240px, 2fr) minmax(0, 3fr); column-gap: 16px; row-gap: 12px; align-items: start; min-width: 0; }
.zgl-filtry { grid-column: 1 / -1; justify-self: start; max-width: 100%; overflow-x: auto; scrollbar-width: none; }
.zgl-ile { margin-left: 4px; color: var(--text-secondary); font-variant-numeric: tabular-nums; }
.zgl-lista { min-width: 0; padding-right: 16px; border-right: 1px solid var(--border); }
.zgl-w { display: flex; flex-direction: column; gap: 2px; width: 100%; min-height: 56px; padding: 8px 12px; border: 0; border-top: 1px solid var(--border); border-radius: 0; background: none; color: inherit; font: inherit; font-size: var(--fs-tresc); text-align: left; cursor: pointer; transition: background-color var(--t) var(--ease); }
.zgl-w[hidden], .zgl-sz[hidden] { display: none; }
.zgl-w:first-child { border-top: 0; }
.zgl-w:hover { background: var(--hover-bg); }
.zgl-w.wybrany { border-radius: var(--r-s); background: var(--brand-soft); }
.zgl-w.wybrany, .zgl-w.wybrany + .zgl-w { border-top-color: transparent; }
.zgl-w.zamkniete > .ellipsis { color: var(--text-secondary); }
.zgl-w-gora { display: flex; align-items: center; gap: 8px; min-width: 0; }
.zgl-prawo { margin-left: auto; flex: none; }
.zgl-podglad { min-width: 0; }
.zgl-sz { display: flex; flex-direction: column; gap: 12px; min-width: 0; font-size: var(--fs-tresc); }
.zgl-sz-g { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }
.zgl-sz-akcje { display: inline-flex; align-items: center; gap: 6px; }
.zgl-tresc { margin: 0; font-size: var(--fs-tytul-karty); line-height: 1.4; white-space: pre-wrap; overflow-wrap: anywhere; text-wrap: pretty; }
.zgl-dl { display: grid; grid-template-columns: max-content minmax(0, 1fr); align-items: center; gap: 6px 16px; margin: 0; }
.zgl-dl dt { color: var(--text-secondary); }
.zgl-dl dd { margin: 0; overflow-wrap: anywhere; }
.zgl-sz .rq-czas { margin-top: 0; }
.zgl-sz .btn-row { margin-top: 0; flex-wrap: wrap; }
.zgl-spec { display: flex; flex-direction: column; gap: 8px; padding-top: 12px; border-top: 1px solid var(--border); }
.zgl-spec p, .zgl-spec ul { margin: 0; }
.zgl-spec ul { padding-left: 18px; }
.zgl-spec li + li { margin-top: 4px; }
.zgl-pytania { color: var(--text-secondary); }
.zgl-wstecz { display: none; align-self: flex-start; }
/* Przychodzące stoją na tej samej liście z podglądem (js/przychodzace.js).
   Treść dokumentu widać od razu — po nią się tu wchodzi. */
.prz-tytul { min-width: 0; font-size: var(--fs-tytul-karty); font-weight: 500; line-height: 1.3; overflow-wrap: anywhere; }
.prz-tresc { margin: 0; padding: 10px 12px; border-radius: var(--r-s); background: var(--card-2); color: var(--text-secondary); line-height: 1.6; white-space: pre-wrap; overflow-wrap: anywhere; max-height: 240px; overflow-y: auto; }
.prz-kandydaci { display: flex; flex-direction: column; gap: 4px; }
.prz-kandydat { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-width: 0; padding: 6px 0; border-top: 1px solid var(--border); }
.prz-kandydaci .panel-label + .prz-kandydat { border-top: 0; }
.prz-kandydat > .row-stack { min-width: 0; }
/* Na telefonie `.row-metrics` dostaje całą szerokość wiersza; tu procent
   i przycisk mieszczą się obok nazwy, więc zostają w jednym rzędzie. */
.prz-kandydat > .row-metrics { width: auto; flex-wrap: nowrap; }
.prz-kandydat.najlepszy > .row-stack > .ellipsis { font-weight: 500; }
/* Dokumenty (js/dokumenty.js): po lewej firmy — jedna linijka, więc niżej
   niż zgłoszenie; po prawej pole szukania w treści nad listą plików. */
.dok-md { grid-template-columns: minmax(200px, 260px) minmax(0, 1fr); }
.dok-firma-w { min-height: 36px; justify-content: center; }
.dok-prawa { display: flex; flex-direction: column; gap: 12px; min-width: 0; }
.zgl-md.otwarty .dok-prawa { display: flex; }
.dok-szukaj { width: 100%; height: var(--h-kontrolka); padding: 0 12px; box-sizing: border-box; border: 1px solid var(--input); border-radius: var(--r-s); background: var(--card); color: var(--foreground); font: inherit; font-size: var(--fs-tresc); }
.dok-szukaj:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-soft); }
.dok-md.jedna-firma .dok-firma { display: none; }
.dok-fragment { white-space: normal; overflow-wrap: anywhere; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; }
.dok-fragment[hidden] { display: none; }
.dok-fragment mark { padding: 0 2px; border-radius: 3px; background: var(--warn-bg); color: var(--foreground); }
.dok-prawa .panel > .row[hidden], .dok-prawa .panel-head[hidden] { display: none; }
/* Typ pliku i „⋯" mieszczą się obok nazwy także na telefonie. */
.dok-prawa .panel > .row { flex-wrap: nowrap; }
.dok-prawa .panel > .row > .row-metrics { width: auto; flex: none; flex-wrap: nowrap; }
@container zgl (max-width: 620px) {
  .zgl-md { grid-template-columns: minmax(0, 1fr); }
  .zgl-lista { padding-right: 0; border-right: 0; }
  .zgl-podglad { display: none; }
  .zgl-md.otwarty .zgl-podglad { display: block; }
  .zgl-md.otwarty .zgl-lista, .zgl-md.otwarty .zgl-filtry { display: none; }
  .zgl-wstecz { display: inline-flex; }
}
.stoper-wiersz:hover { color: var(--foreground); box-shadow: var(--faza-hover); }
.stoper-wiersz.chodzi { background: var(--primary); box-shadow: var(--faza-pelna); }
.stoper-wiersz.chodzi i { width: 9px; height: 9px; border-radius: 2px; background: var(--primary-fg); }
/* Wycena i wpisy w rozwiniętym zgłoszeniu */
.rq-czas { display: flex; flex-direction: column; gap: 4px; margin-top: 10px; }
.rq-wycena { display: inline-flex; align-items: center; gap: 8px; font-size: var(--fs-tresc); color: var(--text-secondary); }
.rq-wycena input { width: 72px; }
.rq-wpis { display: grid; grid-template-columns: 80px minmax(0, 1fr) auto; gap: 10px; font-size: var(--fs-meta); padding: 4px 0; }
/* Szczegóły projektu: roadmapa (szersza, trzy kolumny) obok czasu. */
.proj-uklad { display: grid; grid-template-columns: minmax(0, 1.75fr) minmax(300px, 1fr); gap: 12px; align-items: start; }
@media (max-width: 1100px) { .proj-uklad { grid-template-columns: minmax(0, 1fr); } }
/* Nagłówek panelu projektu: tytuł sekcji (nie drobna etykieta), liczba po
   prawej, pasek postępu pod spodem — w obu panelach na tej samej wysokości. */
.proj-panel-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 10px; }
.proj-panel-tytul { margin: 0; font-size: var(--fs-tytul-karty); font-weight: 500; color: var(--foreground); }
.proj-panel-liczba { font-size: var(--fs-tresc); color: var(--text-secondary); white-space: nowrap; }
.proj-panel-liczba .liczba { font-size: var(--fs-akcent); font-weight: 500; color: var(--foreground); }
.proj-czas .proj-budzet-pasek + .row-meta { margin-top: 10px; }
.proj-uklad .panel-pad { padding: 18px 20px; }
.proj-roadmapa .lane-head, .proj-roadmapa .lane-items { padding-left: 20px; padding-right: 20px; }
.proj-roadmapa .rm-add.panel-pad { padding: 14px 20px; }
.proj-czas .proj-czas-etykieta { padding-left: 20px; padding-right: 20px; }
.proj-czas .sygnal.zwarty { padding-left: 20px; padding-right: 20px; }
.proj-czas .proj-czas-wpisy { padding-left: 20px; padding-right: 20px; }
/* Stoper chodzący przy tym projekcie: kropka jak w górnym pasku. */
.chip.stoper-chodzi { gap: 8px; }
.chip.stoper-chodzi i { width: 8px; height: 8px; border-radius: 50%; background: var(--bad); animation: stoper-puls 1.6s ease-in-out infinite; }
@keyframes stoper-puls { 50% { opacity: .35; } }
@media (prefers-reduced-motion: reduce) { .chip.stoper-chodzi i { animation: none; } }
.proj-roadmapa .lanes { gap: 0; border-top: 1px solid var(--border); }
.proj-roadmapa .lane + .lane { border-left: 1px solid var(--border); }
.proj-roadmapa .lane-items .empty-note { padding: 8px 0; }
.proj-roadmapa .rm-add { border-top: 1px solid var(--border); }
.proj-budzet-pasek.ok b { background: var(--ok); }
@media (max-width: 640px) {
  .proj-roadmapa .lanes { grid-template-columns: minmax(0, 1fr); }
  .proj-roadmapa .lane + .lane { border-left: 0; border-top: 1px solid var(--border); }
}
/* Czas projektu (listy.js czasProjektu) */
.proj-budzet-pasek.warn b { background: var(--warn); }
.proj-budzet-pasek.bad b { background: var(--bad); }

/* Projekty jako karty (wybór właściciela, 13 listopada 2026): budżet godzin
   i najbliższy termin na karcie, pełna lista terminów zwinięta pod spodem. */
.proj-karty { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(320px, 100%), 1fr)); gap: 12px; min-width: 0; align-items: start; }
.proj-karta { display: flex; flex-direction: column; gap: 8px; padding: 12px 16px; min-width: 0; font-size: var(--fs-tresc); }
.proj-karta-g { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-width: 0; }
.proj-karta-g .akcje { display: flex; align-items: center; gap: 4px; flex: none; }
.proj-karta-tytul { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; padding: 0; border: 0; background: none; color: inherit; font: inherit; text-align: left; cursor: pointer; border-radius: var(--r-s, 4px); }
.proj-karta-tytul:hover > .ellipsis:first-child { text-decoration: underline; }
.proj-karta-tytul:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.proj-karta-b { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 4px 8px; }
.proj-karta-b > b { font-weight: 500; font-variant-numeric: tabular-nums; }
.proj-karta-b .proj-budzet-pasek { grid-column: 1 / -1; height: 4px; }
.proj-karta-n { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.proj-karta-nd { display: flex; align-items: center; gap: 8px; }
.proj-karta > .grupa-zwijana { margin: 0 -16px -12px; border-top: 1px solid var(--border); }

/* Czas: klienci i stawki (wybór właściciela, 13 listopada 2026). Tabela
   przewija się w poziomie we własnej ramce; pasek = stawka efektywna,
   kreska = koszt godziny. */
/* Pasek liczb Czasu (13 listopada): fakty jak w Pozycjach, alarm „na stracie" przy prawej krawędzi. */
.czas-fakty { align-items: baseline; }
.czas-fakt { min-width: 0; }
.czas-fakt b { white-space: nowrap; }
.czas-fakt-d { margin-left: 2px; font-size: var(--fs-meta); color: var(--text-secondary); opacity: .8; }
.czas-fakt[title] { cursor: help; }
.czas-fakty-alarm { margin-left: auto; align-self: center; }
.czas-panel > .grupa-zwijana { border-top: 1px solid var(--border); }
.czas-tabela { overflow-x: auto; }
.czas-tabela table { width: 100%; min-width: 720px; border-collapse: collapse; font-size: var(--fs-tresc); }
.czas-tabela th { padding: 8px 12px; font-size: var(--fs-meta); font-weight: 400; color: var(--text-secondary); text-align: left; white-space: nowrap; border-bottom: 1px solid var(--border); }
.czas-tabela td { padding: 8px 12px; vertical-align: middle; border-top: 1px solid var(--border); white-space: nowrap; }
.czas-tabela tbody tr:first-child td { border-top: 0; }
.czas-tabela tbody tr:hover td { background: var(--hover-bg); }
.czas-tabela th:first-child, .czas-tabela td:first-child { padding-left: 16px; }
.czas-tabela th:last-child, .czas-tabela td:last-child { padding-right: 16px; }
.czas-tabela .p { text-align: right; font-variant-numeric: tabular-nums; }
.czas-tabela .sz { color: var(--text-secondary); }
.czas-tabela .tone-bad { color: var(--bad-tekst); }
.czas-klient { padding: 0; border: 0; background: none; color: inherit; font: inherit; text-align: left; cursor: pointer; border-radius: var(--r-s, 4px); }
.czas-klient:hover { text-decoration: underline; }
.czas-klient:focus-visible { outline: 2px solid var(--fokus); outline-offset: 2px; }
.czas-bullet { position: relative; display: block; width: 180px; height: 8px; border-radius: 2px; background: var(--muted); }
.czas-bullet b { display: block; height: 100%; border-radius: 2px; background: var(--text-secondary); }
.czas-bullet b.bad { background: var(--bad-tekst); }
.czas-bullet i { position: absolute; top: -3px; bottom: -3px; width: 2px; margin-left: -1px; background: var(--foreground); }
.proj-czas-etykieta { padding: 10px 14px 4px; border-top: 1px solid var(--border); }
.proj-czas-wpisy { padding: 2px 14px 10px; }

/* --------------------------------------------------------------- asystent */

.sheet-body.chat-body { padding: 0; overflow: hidden; display: flex; flex-direction: column; }

.chat { display: flex; flex-direction: column; flex: 1; min-height: 0; }

.chat-log {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 20px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.msg { display: flex; }
.msg.user { justify-content: flex-end; }

.bubble {
  border-radius: var(--r);
  max-width: 88%;
  padding: 10px 12px;
  background: var(--card-2);
  box-shadow: var(--cien-ramka);
  /* Pismo czatu 12 px, interlinia 1,5 (uwaga z 6 października: 13 px wciąż
     za duże) — długa odpowiedź mieści się w wąskim panelu bez ściany tekstu. */
  font-size: var(--fs-tresc);
  line-height: 1.5;
  overflow-wrap: anywhere;
}

/* Pytanie właściciela ma być widocznie „jego" — pełne tło. */
.msg.user .bubble {
  background: var(--primary);
  box-shadow: none;
  color: var(--primary-fg);
}

.bubble p { margin: 0 0 8px; }
.bubble p:last-child { margin-bottom: 0; }
.bubble ul { margin: 0 0 8px; padding-left: 16px; }
.bubble ul:last-child { margin-bottom: 0; }
.bubble li { margin-bottom: 4px; }
.bubble code { font-family: var(--mono); font-size: var(--fs-drobne); background: var(--muted); border-radius: 4px; padding: 1px 4px; }
/* Nagłówki z `markdownLite` (# → h3) — o stopień nad treścią, nie o trzy. */
.bubble h3, .bubble h4, .bubble h5, .bubble h6 { margin: 14px 0 6px; font-weight: 600; line-height: 1.35; }
.bubble h3 { font-size: 14px; }
.bubble h4 { font-size: 13px; }
.bubble h5, .bubble h6 { font-size: var(--fs-tresc); }
.bubble > :first-child { margin-top: 0; }

.bubble.blad { box-shadow: 0 0 0 1px var(--bad-border); background: var(--bad-bg); color: var(--bad-tekst); }
.bubble.mysli { display: inline-flex; align-items: baseline; gap: 1px; font-size: var(--fs-drobne); color: var(--text-secondary); }
.mysli-kropki { display: inline-flex; gap: 2px; margin-left: 1px; }
.mysli-kropki i { width: 3px; height: 3px; border-radius: 50%; background: currentColor; animation: mysli 1.2s ease-in-out infinite; }
.mysli-kropki i:nth-child(2) { animation-delay: .2s; }
.mysli-kropki i:nth-child(3) { animation-delay: .4s; }
@keyframes mysli { 0%, 80%, 100% { opacity: .25; } 40% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .mysli-kropki i { animation: none; opacity: .6; } }

.msg.bot { flex-direction: column; align-items: flex-start; }
/* Tabela w odpowiedzi asystenta i w dokumencie kontekstu (markdownLite):
   ramka jak u kart, przewija się w poziomie zamiast rozpychać dymek. */
.md-tabela { max-width: 100%; overflow-x: auto; margin: 6px 0; border-radius: var(--r-s); box-shadow: var(--cien-ramka); }
.md-tabela table { width: 100%; border-collapse: collapse; font-size: var(--fs-drobne); font-variant-numeric: tabular-nums; }
.md-tabela th, .md-tabela td { padding: 8px 10px; text-align: left; vertical-align: top; border-bottom: 1px solid var(--border); }
/* Dymek łamie słowa w dowolnym miejscu (overflow-wrap: anywhere) — w komórce
   to dawało „Darmo|wy dostę|p". Komórka łamie tylko między słowami, a za
   wąska tabela przewija się w poziomie. */
.md-tabela td, .md-tabela th { overflow-wrap: normal; word-break: normal; min-width: 7em; max-width: 22em; }
.md-tabela th { font-weight: 500; color: var(--text-secondary); background: var(--card-2); }
.md-tabela tr:last-child td { border-bottom: 0; }

/* Pliki dołączone do pytania stoją w dymku nad tekstem: obraz jako
   miniatura (klik = pełny podgląd), reszta jako chip z nazwą. */
.msg-pliki { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 6px; margin-bottom: 6px; }
.msg-obraz {
  display: block;
  padding: 0;
  border: 0;
  border-radius: var(--r-s);
  background: transparent;
  box-shadow: 0 0 0 1px color-mix(in srgb, currentColor 22%, transparent);
  overflow: hidden;
  cursor: zoom-in;
  transition: opacity var(--t-szybko) var(--ease);
}
.msg-obraz:hover { opacity: .88; }
.msg-obraz img { display: block; width: auto; max-width: 160px; height: 96px; object-fit: cover; }
.msg-plik {
  display: inline-flex;
  align-items: center;
  max-width: 100%;
  padding: 2px 8px;
  border-radius: var(--r-pill);
  background: var(--neutral-bg);
  box-shadow: inset 0 0 0 1px var(--neutral-border);
  font-size: var(--fs-tresc);
  overflow-wrap: anywhere;
}
/* Dymek pytania ma pełne tło (--primary bywa ciemne albo jasne) — chip liczy się od koloru jego tekstu. */
.msg.user .msg-plik { background: color-mix(in srgb, currentColor 12%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, currentColor 22%, transparent); color: inherit; }

.dialog:has(.podglad-obrazu) { width: min(960px, calc(100vw - 32px)); }
.podglad-obrazu img { display: block; max-width: 100%; max-height: calc(100vh - 180px); margin: 4px auto 0; border-radius: var(--r-s); object-fit: contain; }

.chat-input {
  flex: none;
  border-top: 1px solid var(--border);
  padding: 12px 20px 16px;
  background: var(--card);
}

.chat-input textarea {
  width: 100%;
  border: 1px solid var(--input);
  border-radius: var(--r-s);
  background: var(--card);
  color: var(--foreground);
  font: inherit;
  font-size: var(--fs-tresc);
  line-height: 1.5;
  padding: 8px 10px;
  resize: vertical;
  min-height: 56px;
  outline: none;
  transition: border-color var(--t) var(--ease), box-shadow var(--t) var(--ease);
}

.chat-input textarea:focus { border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-soft); }

.chat-actions { display: flex; align-items: center; gap: 8px; margin-top: 12px; }
.chat-meta { flex: 1; min-width: 0; color: var(--text-secondary); font-size: var(--fs-drobne); }

/* ------------------------------------------------------------------- cmdk */

/* Szukajka globalna. BEZ animacji wejścia: otwiera ją skrót klawiszowy
   używany dziesiątki razy dziennie, a ruch na takiej akcji tylko ją opóźnia.
   Okno wisi wysoko — lista wyników rośnie w dół i nie skacze pod kursorem.
   Promień 12 = wiersz 6 + wypełnienie listy 6. */
.cmdk { position: fixed; inset: 0; z-index: 85; }
.cmdk[hidden] { display: none; }

.cmdk-backdrop { position: absolute; inset: 0; background: var(--overlay); }

.cmdk-box {
  position: relative;
  border-radius: var(--r-menu);
  overflow: hidden;
  box-shadow: var(--cien-pop);
  width: min(640px, calc(100vw - 32px));
  margin: 10vh auto 0;
  background: var(--card);
  display: flex;
  flex-direction: column;
  max-height: 70vh;
}

.cmdk-input {
  display: flex;
  align-items: center;
  gap: 12px;
  height: 48px;
  padding: 0 12px 0 16px;
  border-bottom: 1px solid var(--border);
  flex: none;
}

.cmdk-input svg {
  width: 16px;
  height: 16px;
  flex: none;
  fill: none;
  stroke: var(--text-secondary);
  stroke-width: 1.6;
  stroke-linecap: round;
}

.cmdk-input input {
  flex: 1;
  min-width: 0;
  height: 100%;
  border: 0;
  background: none;
  color: var(--foreground);
  font: inherit;
  font-size: var(--fs-akcent);
  outline: none;
}

.cmdk-input input::placeholder { color: var(--text-secondary); }
.cmdk-input .chip { height: 24px; padding: 0 8px; font-size: var(--fs-drobne); }

.cmdk-results { overflow-y: auto; overscroll-behavior: contain; padding: 6px; }

.cmdk-group-label { padding: 10px 10px 4px; }

.cmdk-row {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 8px 10px;
  border: 0;
  border-radius: var(--r-xs);
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

/* Zaznaczenie z klawiatury wygląda jak hover myszą — to jedno i to samo
   miejsce. Bez przejścia: strzałka w dół chodzi po liście szybciej niż
   jakakolwiek animacja. */
.cmdk-row:hover,
.cmdk-row[aria-selected="true"] { background: var(--accent); }

.cmdk-row .t { min-width: 0; flex: 1; display: flex; flex-direction: column; gap: 2px; }
.cmdk-row .t span { color: var(--text-secondary); font-size: var(--fs-meta); }
/* Trafienie w tincie akcentu, nie bursztynu — bursztyn znaczy w tym
   interfejsie „uwaga", a trafienie w wyszukiwarce niczego nie ostrzega. */
.cmdk-row mark { background: var(--brand-soft); color: inherit; border-radius: 2px; }

.cmdk-row .enter {
  flex: none;
  color: var(--text-secondary);
  font-size: var(--fs-drobne);
  opacity: 0;
}

.cmdk-row[aria-selected="true"] .enter { opacity: 1; }
/* Skrót klawiszowy akcji widać zawsze, nie tylko przy zaznaczeniu — to
   podpowiedź na następny raz, a nie opis tego, co zrobi Enter. */
.cmdk-row .cmdk-skrot { flex: none; }

.cmdk-empty { padding: 24px 16px; color: var(--text-secondary); font-size: var(--fs-tresc); }

.cmdk-foot {
  display: flex;
  gap: 16px;
  flex: none;
  padding: 8px 16px;
  border-top: 1px solid var(--border);
  color: var(--text-secondary);
  font-size: var(--fs-drobne);
}

.chip-ico {
  width: 14px;
  height: 14px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
}

@media (max-width: 640px) {
  .cmdk-box { margin-top: 4vh; max-height: 88vh; }
  .cmdk-input { height: 44px; }
}

/* ----------------------------------------------------------------- logowanie */

.login {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: var(--background);
}

.login[hidden] { display: none; }

.login-box {
  border-radius: var(--r-menu);
  box-shadow: var(--cien-pop);
  width: min(380px, 100%);
  padding: 28px;
  background: var(--card);
}

.login-box h1 { margin: 0 0 8px; font-size: var(--fs-liczba-s); font-weight: 500; letter-spacing: -.015em; }
.login-box .help { margin: 0 0 20px; }
.login-box .btn { width: 100%; }

.login-error {
  margin-bottom: 12px;
  padding: 8px 12px;
  border-radius: var(--r-s);
  box-shadow: inset 0 0 0 1px var(--bad-border);
  background: var(--bad-bg);
  color: var(--bad-tekst);
  font-size: var(--fs-tresc);
}

.login-error[hidden] { display: none; }

/* Potwierdzenie bez alarmu: „link idzie", „hasło zapisane". */
.login-info {
  margin-bottom: 12px;
  padding: 8px 12px;
  border-radius: var(--r-s);
  box-shadow: inset 0 0 0 1px var(--ok-border);
  background: var(--ok-bg);
  color: var(--ok-tekst);
  font-size: var(--fs-tresc);
}

.login-info[hidden] { display: none; }

/* „Nie pamiętasz hasła?" — tekst, nie drugi przycisk pod przyciskiem. */
.login-link {
  display: block;
  width: 100%;
  margin-top: 12px;
  padding: 4px 0;
  border: 0;
  background: none;
  color: var(--muted-foreground);
  font: inherit;
  font-size: var(--fs-tresc);
  text-align: center;
  cursor: pointer;
  border-radius: var(--r-s);
}

.login-link:hover { color: var(--foreground); text-decoration: underline; text-underline-offset: 3px; }
.login-link:focus-visible { outline: 2px solid var(--fokus); outline-offset: 2px; }
.login-link[hidden] { display: none; }

/* ------------------------------------------------------------------- toast */

/* Wjeżdża od dołu o 8 px z przezroczystością (200 ms, mocne wyjście krzywej),
   schodzi o 6 px w 150 ms — wyjście krótsze i cichsze niż wejście. Klasę
   `znika` stawia app.js. Przejście, nie klatki: kolejny toast przerywa
   poprzedni bez skoku. */
.toast {
  border-radius: var(--r);
  box-shadow: var(--cien-pop);
  position: fixed;
  left: 50%;
  bottom: 24px;
  transform: translate(-50%, 0);
  z-index: 80;
  max-width: min(520px, calc(100vw - 32px));
  padding: 12px 16px;
  background: var(--card);
  color: var(--foreground);
  font-size: var(--fs-tresc);
  transition: transform 200ms var(--ease-out), opacity 200ms var(--ease-out);
}

@starting-style {
  .toast { transform: translate(-50%, 8px); opacity: 0; }
}

.toast.znika { transform: translate(-50%, 6px); opacity: 0; transition-duration: var(--t-wyjscie); }

/* Toast z błędem nie znika sam: zostaje, aż go zamkniesz. Czerwony
   pierścień odróżnia go od „Zapisane", a przycisk jest jedyną drogą
   wyjścia — błąd przeczytany w połowie nie jest błędem przeczytanym. */
.toast.blad { display: flex; align-items: center; gap: 12px; box-shadow: var(--cien-pop), 0 0 0 1px var(--bad-border); }
.toast-zamknij {
  flex: none;
  height: 26px;
  padding: 0 10px;
  border: 0;
  border-radius: var(--r-pill);
  background: var(--card);
  box-shadow: var(--faza);
  color: var(--foreground);
  font: inherit;
  font-size: var(--fs-kontrolka);
  font-weight: 500;
  cursor: pointer;
}

/* ------------------------------------------------------------------- mobile */

/* Poniżej 768 px szyna schodzi na dół jako pasek ikon — hover na dotyku
   nie istnieje, a zwijanie nie ma tam czego zwijać. */
@media (max-width: 768px) {
  .sidebar, html.szyna-zwinieta .sidebar {
    inset: auto 0 0 0;
    width: 100%;
    flex-direction: row;
    border-right: 0;
    border-top: 1px solid var(--border);
    transition: none;
  }

  .sidebar-logo, .sidebar-foot { display: none; }
  .sidebar-nav {
    display: flex; padding: 0 4px; overflow-x: auto;
    /* Dwie ostatnie pozycje nie mieszczą się na telefonie: cień przy krawędzi mówi, że jest dalej. */
    background:
      linear-gradient(270deg, var(--sidebar) 40%, transparent) right / 32px 100% no-repeat local,
      linear-gradient(270deg, color-mix(in srgb, var(--foreground) 16%, transparent), transparent) right / 22px 100% no-repeat scroll;
  }
  /* Kreska między Pulpitem a Klientami ma sens w kolumnie; w poziomym pasku
     zabierała 16 px, których brakowało ostatniej pozycji. */
  .nav-kreska { display: none; }

  .nav-item, .nav-item.active {
    flex-direction: column;
    justify-content: center;
    gap: 4px;
    height: 56px;
    margin: 0;
    padding: 0 12px;
    border-radius: 0;
    background: none;
    box-shadow: none;
    font-size: var(--fs-drobne);
    font-weight: 500;
  }

  .nav-item svg { width: 18px; height: 18px; }
  html.szyna-zwinieta .nav-label { opacity: 1; pointer-events: auto; }
  .nav-label { flex: none; }

  /* Wskaźnik aktywnej pozycji: kreska u góry kafelka. */
  .nav-item.active::after {
    content: '';
    position: absolute;
    left: 10px;
    right: 10px;
    top: 0;
    height: 2px;
    border-radius: 0 0 2px 2px;
    background: var(--foreground);
  }

  .shell, html.szyna-zwinieta .shell { margin-left: 0; padding-bottom: 56px; }

  /* Jeden rząd: szukajka bierze całą wolną szerokość, konto stoi przy
     prawej krawędzi. Wcześniej pasek łamał się na dwa poziomy i konto
     wisiało samotnie pod szukajką. Timer (rzadko widoczny) przewija się
     u siebie, nie rozpycha strony. */
  .topbar { height: 52px; gap: 8px; padding: 0 12px; }
  .topbar-szukaj { flex: 1; width: auto; min-width: 0; }
  .topbar-szukaj kbd { display: none; }
  /* Telefon nie ma klawiatury: znikają też stopka skrótów palety, skróty
     przy jej akcjach i sekcja „Skróty klawiszowe" w Ustawieniach (L-22 g). */
  .cmdk-foot, .cmdk-skrot, .skroty-klawiszowe { display: none; }
  /* Bez `overflow-x: auto`: przewijanie przycinało menu konta (absolutne
     dziecko `.konto`) — na telefonie otwierało się niewidoczne i nieklikalne.
     Stoper zamiast tego kurczy się z ellipsis. */
  .topbar-right { flex: none; max-width: 60%; min-width: 0; }
  .topbar-right > :not(.konto) { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .awatar-nazwa { display: none; }

  /* Tytuł, przełącznik podzakładek i akcja nie mieszczą się w jednym
     rzędzie na 390 px — przełącznik był przycinany do pierwszego segmentu
     przez przycisk akcji. Rząd się łamie; przełącznik dostaje własne
     przewijanie w poziomie, żeby przy czterech podzakładkach nie rozpychał
     strony. */
  .card-title-row { flex-wrap: wrap; }
  .card-title-lewa { flex-wrap: wrap; width: 100%; }
  .okna { max-width: 100%; overflow-x: auto; scrollbar-width: none; }
  .okna::-webkit-scrollbar { display: none; }

  .row { flex-wrap: wrap; }
  .row-metrics { width: 100%; justify-content: flex-end; }
  .row-meta { white-space: normal; }
  .row-name { flex-basis: 100%; }
  .tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .split, .lanes { grid-template-columns: minmax(0, 1fr); }
  .field-row { flex-wrap: wrap; }
  /* Sam flex-wrap nic nie dawał: pola z flex:1 i min-width:0 kurczyły się
     do zera zamiast schodzić do nowego rzędu. Podstawa 140 px je łamie. */
  .field-row > .field { flex: 1 1 140px; }
  .sheet-panel { width: 100%; }
  .sheet-head { height: 56px; min-height: 56px; padding: 0 16px; }
  .sheet-body { padding: 16px; }
  .hint { flex-wrap: wrap; gap: 12px; }
  /* Pola na telefonie 16 px, inaczej iOS przybliża stronę przy fokusie —
     KAŻDE pole, nie tylko w .field (pola w wierszu, czat, szukajka
     dokumentów). :is() bierze specyficzność najmocniejszego argumentu,
     więc wygrywa z klasami, które ustawiają 12–14 px. */
  :is(input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]):not([type="file"]):not([type="hidden"]), select, textarea) { font-size: 16px; }
}

@media (max-width: 520px) {
  .card-head { flex-wrap: wrap; }
  .card-tabs { margin-left: 0; width: 100%; overflow-x: auto; }
  .tiles { grid-template-columns: minmax(0, 1fr); }
}

/* Druk (raporty, strony statusu otwierane z dashboardu). */
@media print {
  .sidebar, .topbar-right, .hint, .sheet { display: none !important; }
  .shell { margin-left: 0; }
  .panel, .row { border-color: #ccc; box-shadow: none; }
  body { background: #fff; color: #000; }
}

/* Przeskocz do treści: niewidoczny, dopóki nie dostanie fokusu z klawiatury. */
.skip {
  position: fixed;
  top: 8px;
  left: 8px;
  z-index: 200;
  padding: 8px 14px;
  border-radius: var(--r-pill);
  background: var(--brand);
  color: var(--brand-fg);
  font-size: var(--fs-tresc);
  text-decoration: none;
  transform: translateY(-200%);
}
.skip:focus { transform: none; }

/* ------------------------------------------------ spójność (2026-09-17) */
/* Link w wierszu listy i przycisk-link nie są podkreślone: podkreślenie
   dopiero pod kursorem, jak w reszcie panelu. */
.row a, a.row-act, a.chip, a.btn { text-decoration: none; }
.row a:hover { text-decoration: underline; text-underline-offset: 3px; }
/* Grupa etykiet w nagłówku panelu (przełącznik + przycisk). */
.panel-head .akcje { display: inline-flex; gap: 6px; flex-wrap: wrap; margin-left: auto; }
/* Panel-podsumowanie: etykieta po lewej, jedna liczba po prawej. */
.panel-head > .liczba { margin-left: auto; font-size: var(--fs-liczba-s); letter-spacing: -.01em; }
/* Pustka wewnątrz panelu z wypełnieniem: bez drugiego wcięcia. */
.panel-pad .empty-note { padding: 10px 0 0; }
/* Pustka w sekcji przestrzeni (Podsumowanie, Kontakty, Konkurenci, sejf):
   sekcja ma już wcięcie, a 18/16 rozjeżdżało ją względem etykiety. */
.pp-sekcja .empty-note { padding: 0; }
/* Wiersz listy wewnątrz panelu z wypełnieniem (konta, szablony): bez drugiego wcięcia. */
.panel-pad > .row { padding-left: 0; padding-right: 0; }
/* Zdjęcie w kółku zespołu — zamiast inicjału, gdy konto je ma. */
.zespol-inicjal.zespol-foto { background: var(--neutral-bg); overflow: hidden; }
.zespol-inicjal.zespol-foto img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* ---------------------------------------------- wąskie ekrany (2026-09-17) */
/* Tytuł karty z podzakładkami (kartoteka, Monitoring) łamie się w dwa
   rzędy zamiast wypychać kartę poza ekran; przełącznik przewija się w poziomie. */
@media (max-width: 900px) {
  .card-title-row, .card-title-lewa { flex-wrap: wrap; }
  .card-head { flex-wrap: wrap; }
  .okna.podzakladki, .card-head .okna { max-width: 100%; overflow-x: auto; }
  .row-metrics { flex-wrap: wrap; justify-content: flex-end; }
}
/* Dwie kolumny (.split) w jedną; panel-pustka bez sztywnej wysokości. */
@media (max-width: 640px) {
  .split { grid-template-columns: minmax(0, 1fr) !important; }
  .panel.pusto { min-height: 0; padding: 24px 16px; }
  .panel-head { padding-left: 12px; padding-right: 12px; }
}
/* Wiersz na wąskim ekranie: opis w wierszu nie wyjeżdża pod metryki
   (ellipsis), etykieta i pigułka nie łamią się w pionie, a metryki
   schodzą pod nazwę dopiero wtedy, gdy się nie mieszczą. */
.row-name > .row-meta { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.row-name > .pill { flex: none; white-space: nowrap; }
@media (max-width: 900px) {
  .row { flex-wrap: wrap; }
  .row-metrics { margin-left: auto; }
}
/* Podgląd zdjęcia w wierszu ustawień: stoi przed tekstem jak inicjał w Zespole,
   nie w `.row-metrics` — te na telefonie zajmują całą linię. */
.podglad-konta { flex: none; margin-right: 2px; }
/* Przełącznik, który się przewija (kartoteka na wąskim ekranie): cień na
   prawej krawędzi mówi „jest dalej" i znika po przewinięciu do końca.
   Sztuczka z dwoma tłami: cień jest przypięty do ramki (`scroll`), a zasłona
   w kolorze tła jedzie z treścią (`local`) i na końcu go przykrywa. */
@media (max-width: 900px) {
  .okna.podzakladki, .card-head .okna {
    background:
      linear-gradient(90deg, var(--neutral-kryjacy) 40%, transparent) left / 32px 100% no-repeat local,
      linear-gradient(270deg, var(--neutral-kryjacy) 40%, transparent) right / 32px 100% no-repeat local,
      linear-gradient(270deg, color-mix(in srgb, var(--foreground) 16%, transparent), transparent) right / 22px 100% no-repeat scroll,
      linear-gradient(90deg, color-mix(in srgb, var(--foreground) 16%, transparent), transparent) left / 22px 100% no-repeat scroll,
      var(--neutral-kryjacy);
  }
}
/* Arkusz: sekcja po bloku, który sekcją nie jest (np. nagłówek + panel),
   dostaje ten sam oddech 20 px, jaki sekcje mają między sobą. */
.sheet-body > :not(.sekcja) + .sekcja, .sheet-body > .panel + .section-head { margin-top: var(--odstep-grupy); }
/* Sekcja zwijana w arkuszu (Stan konfiguracji): etykieta jest klikalna,
   szewron obraca się po otwarciu. Domyślnie zwinięta — to metryczka. */
details.sekcja.zwijana > summary { list-style: none; cursor: pointer; display: flex; align-items: center; gap: 8px; }
details.sekcja.zwijana > summary::-webkit-details-marker { display: none; }
details.sekcja.zwijana > summary > label { margin: 0; cursor: pointer; }
details.sekcja.zwijana > summary:hover > label { color: var(--foreground); }
details.sekcja.zwijana > summary:focus-visible { outline: 2px solid var(--fokus); outline-offset: 2px; border-radius: var(--r-s); }
details.sekcja.zwijana > summary > .szewron { width: 14px; height: 14px; margin: 0; }
details.sekcja.zwijana[open] > summary { margin-bottom: 8px; }
/* Podgląd posta: treść jak wpisana (łamanie linii zachowane), pliki w rzędzie. */
.post-podglad { white-space: pre-wrap; overflow-wrap: anywhere; font-size: var(--fs-tresc); line-height: 1.55; }
.post-media { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.post-media :is(img, video) { width: 120px; height: 120px; object-fit: cover; border-radius: var(--r-s); display: block; }
.post-media:first-child { margin-top: 0; }
.post-media + .field { margin-top: 12px; }
.row-stack.incident.clickable { cursor: pointer; }
.row-stack.incident.clickable:hover { background: var(--card-2); }
/* Dni pracy: siedem pastylek-przełączników, zaznaczony dzień wypełniony. */
.dni-pracy { display: inline-flex; gap: 4px; }
.dni-pracy .dzien { display: inline-flex; align-items: center; justify-content: center; min-width: 34px; height: 26px; padding: 0 6px; border-radius: var(--r-pill); background: var(--card); box-shadow: var(--faza); font-size: var(--fs-kontrolka); cursor: pointer; user-select: none; color: var(--text-secondary); }
.dni-pracy .dzien:has(input:checked) { background: var(--primary); color: var(--primary-fg); box-shadow: var(--faza-pelna); }
.dni-pracy .dzien input { position: absolute; opacity: 0; width: 0; height: 0; }
.dni-pracy .dzien:has(input:focus-visible) { outline: 2px solid var(--fokus); outline-offset: 2px; }

/* ============================================================ wykresy
   Moduł `js/wykresy.js`. Geometria w SVG rozciągniętym na szerokość
   (`preserveAspectRatio="none"`), etykiety, kropki i tooltipy w HTML
   pozycjonowanym procentami — dlatego nic tu nie ma stałej szerokości
   poza pierścieniem. Kolory wyłącznie z tokenów: serie neutralne
   `--chart-line`/`--chart-line-2`, stan `--ok`/`--warn`/`--bad`. */
/* Karta wykresu (wygląd z makiety): tytuł 16 px z opisem, po prawej
   pigułka albo przełącznik, obrys w kolorze kreski zamiast samego cienia. */
.wykres-panel { box-shadow: 0 0 0 1px var(--border); }
.wykres-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px 16px; flex-wrap: wrap; padding: 18px 20px 8px; }
.wykres-head-tekst { min-width: 0; }
.wykres-tytul { font-size: var(--fs-tytul-karty); font-weight: 500; line-height: 1.25; }
.wykres-opis { color: var(--text-secondary); font-size: var(--fs-tresc); margin-top: 4px; }
.wykres-head-prawa { display: flex; align-items: center; gap: 8px; flex: none; }
.wykres-panel > .wykres { padding: 12px 20px 16px; }
.wykres-panel > .wykres .wykres-osy { left: 20px; }
.wykres-panel > .wykres-obok { padding: 8px 20px 18px; }
.wykres-panel .empty-note { padding: 8px 20px 18px; }
.wykres-help { margin: 0 20px 16px; }
.wykres { position: relative; padding: 12px 16px 14px; font-size: var(--fs-meta); }
.wykres-pole { position: relative; height: var(--h, 200px); margin-left: 44px; }
.wykres-pole > svg { position: absolute; inset: 0; width: 100%; height: 100%; display: block; overflow: visible; }
.wykres-osy { position: absolute; left: 16px; top: 12px; width: 38px; height: var(--h, 200px); }
.wykres-osy span { position: absolute; right: 0; transform: translateY(-50%); font-family: var(--mono); font-size: var(--fs-os); color: var(--chart-axis); white-space: nowrap; }
.wykres-osx { position: relative; height: 18px; margin: 8px 0 0 44px; }
.wykres-osx span { position: absolute; top: 0; transform: translateX(-50%); font-size: var(--fs-os); color: var(--chart-axis); white-space: nowrap; }
.wykres-osx span:first-child { transform: none; }
.wykres-osx span:last-child { transform: translateX(-100%); }
.wykres-legenda { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px 16px; margin-top: 10px; color: var(--text-secondary); }
.wykres-legenda i { display: inline-block; width: 10px; height: 10px; border-radius: 2px; margin-right: 6px; vertical-align: -1px; }

/* Kursor: pionowa kreska i kropki na seriach; poza najechaniem kropki
   stoją na ostatnim punkcie — to „teraz" i on jest odpowiedzią. */
.wykres-kursor { position: absolute; top: 0; bottom: 0; width: 0; border-left: 1px dashed var(--border-strong); transform: translateX(-.5px); pointer-events: none; }
.wykres-kropka { position: absolute; width: 8px; height: 8px; margin: -4px; border-radius: 50%; box-shadow: 0 0 0 2px var(--card); pointer-events: none; transition: left var(--t-szybko), top var(--t-szybko); }
.wykres-tip {
  position: absolute; top: 8px; z-index: 2; min-width: 168px; padding: 8px 10px; margin-left: 12px;
  background: var(--card-2); border-radius: var(--r-s); box-shadow: var(--cien-pop);
  font-size: var(--fs-meta); line-height: 1.7; pointer-events: none; color: var(--foreground);
}
.wykres-tip.z-lewej { margin-left: -12px; transform: translateX(-100%); }
.wykres-tip b { display: block; color: var(--text-secondary); font-size: var(--fs-drobne); line-height: 1.5; margin-bottom: 4px; }
.wykres-tip-w { display: flex; justify-content: space-between; gap: 14px; }
.wykres-tip-w i { display: inline-block; width: 8px; height: 8px; border-radius: 2px; margin-right: 6px; }
.wykres-tip-w em { font-style: normal; font-size: var(--fs-drobne); font-variant-numeric: tabular-nums; margin-left: auto; }
.wykres-tip-w.suma { border-top: 1px solid var(--border); margin-top: 4px; padding-top: 4px; }
.wykres-tip-w em.ok { color: var(--ok-tekst); }
.wykres-tip-w em.bad { color: var(--bad-tekst); }

/* Słupki skumulowane: kolumny w HTML, żeby etykiety nie skalowały się
   z szerokością; siatka jako poziome kreski pod kolumnami. */
.wykres-siatka { position: absolute; inset: 0; pointer-events: none; }
.wykres-siatka i { position: absolute; left: 0; right: 0; border-top: 1px solid var(--chart-grid); }
.wykres-kolumny { position: absolute; inset: 0; display: flex; justify-content: space-around; gap: 4%; padding: 0 3%; }
.wykres-kol { position: relative; flex: 1 1 0; min-width: 0; max-width: 96px; height: 100%; }
.wykres-kol-slupek { position: absolute; left: 0; right: 0; bottom: 0; height: 100%; display: flex; flex-direction: column-reverse; justify-content: flex-start; }
.wykres-kol-slupek i { display: block; background: var(--chart-line); flex: none; }
.wykres-kol-slupek i:last-child { border-radius: 4px 4px 0 0; }
.wykres-kol-slupek i:first-child { border-radius: 0 0 2px 2px; }
.wykres-kol-slupek i:only-child { border-radius: 4px 4px 2px 2px; }
.wykres-kol-suma { position: absolute; left: 0; right: 0; bottom: var(--szczyt, 0); padding-bottom: 4px; text-align: center; font-size: var(--fs-drobne); font-variant-numeric: tabular-nums; color: var(--foreground); }
.wykres-kol-etykieta { position: absolute; left: 0; right: 0; top: 100%; padding-top: 8px; text-align: center; font-size: var(--fs-os); color: var(--chart-axis); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.wykres-slupki .wykres-pole { margin-bottom: 26px; }

/* Słupki poziome: wiersz = nazwa · pasek · meta. Kreska średniej idzie
   przez wszystkie paski w pionie. */
.wykres-poziome { padding-bottom: 28px; }
.wykres-wiersz { position: relative; display: grid; grid-template-columns: minmax(140px, 22%) 1fr 108px; gap: 12px; align-items: center; padding: 8px 0; }
.wykres-wiersz-nazwa { display: flex; flex-direction: column; min-width: 0; }
.wykres-wiersz-nazwa strong { font-size: var(--fs-tresc); font-weight: 400; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wykres-wiersz-nazwa .row-meta { overflow: hidden; text-overflow: ellipsis; }
.wykres-wiersz-meta { text-align: right; }
.wykres-pasek { position: relative; height: 22px; border-radius: 5px; background: var(--card-2); }
.wykres-pasek i { position: absolute; left: 0; top: 0; bottom: 0; border-radius: 5px; background: var(--chart-line); opacity: .9; }
.wykres-pasek i.ok { background: var(--ok); }
.wykres-pasek i.warn { background: var(--warn); }
.wykres-pasek i.bad { background: var(--bad); }
.wykres-pasek i.brak { background: var(--muted); opacity: 1; }
.wykres-pasek-liczba { position: absolute; top: 50%; transform: translateY(-50%); margin-left: 8px; font-size: var(--fs-meta); font-weight: 500; font-variant-numeric: tabular-nums; white-space: nowrap; }
.wykres-pasek-liczba.wewnatrz { margin-left: -8px; transform: translate(-100%, -50%); color: var(--card); }
.wykres-pasek-brak { position: absolute; left: 8%; top: 50%; transform: translateY(-50%); color: var(--text-secondary); font-size: var(--fs-drobne); white-space: nowrap; }
.wykres-srednia { position: absolute; top: 4px; bottom: 24px; left: calc(max(140px, 22%) + 12px); right: 120px; pointer-events: none; }
.wykres-srednia i { position: absolute; left: var(--x); top: 0; bottom: 0; border-left: 1px dashed var(--chart-axis); }
.wykres-srednia span { position: absolute; left: var(--x); top: 100%; transform: translateX(-50%); padding-top: 4px; font-size: var(--fs-os); color: var(--chart-axis); white-space: nowrap; }

/* Lejek: pasek wyśrodkowany, etykieta w środku, meta po prawej. */
.wykres-etap { display: grid; grid-template-columns: minmax(120px, 18%) 1fr minmax(120px, auto); gap: 12px; align-items: center; padding: 6px 0; }
.wykres-etap-nazwa { font-weight: 400; font-size: var(--fs-tresc); }
.wykres-etap-pasek { position: relative; height: 28px; display: flex; justify-content: center; align-items: center; }
.wykres-etap-pasek i { display: block; height: 100%; border-radius: 6px; background: var(--chart-line); }
.wykres-etap-pasek i.pusty { width: 60px; border: 1px dashed var(--border-strong); background: none; box-sizing: border-box; }
.wykres-etap-tekst { position: absolute; font-size: var(--fs-drobne); font-variant-numeric: tabular-nums; font-weight: 500; color: var(--foreground); white-space: nowrap; }
.wykres-etap-tekst.ciemny { color: var(--background); }
/* Napis stoi na pasku: na telefonie krótki pasek był węższy od napisu i tekst znikał na tle. */
@media (max-width: 768px) { .wykres-etap-pasek i:not(.pusty) { min-width: 46%; } }
.wykres-etap-meta { text-align: right; font-size: var(--fs-drobne); color: var(--text-secondary); }
.wykres-etap-meta.warn { color: var(--warn-tekst); }
.wykres-etap-meta.bad { color: var(--bad-tekst); }

/* Pierścień: stała wielkość, tekst nad środkiem. */
.wykres-pierscien { position: relative; width: var(--rozmiar, 132px); height: var(--rozmiar, 132px); flex: none; }
.wykres-pierscien svg { width: 100%; height: 100%; display: block; }
.wykres-pierscien-tekst { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; line-height: 1.1; }
.wykres-pierscien-tekst b { font-size: var(--fs-liczba-m); font-weight: 500; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.wykres-pierscien-tekst b small { font-size: var(--fs-meta); font-weight: 500; margin-left: 1px; }
.wykres-pierscien.dlugi .wykres-pierscien-tekst b { font-size: calc(var(--fs-liczba-m) - 6px); }
.wykres-pierscien-tekst small { max-width: 70%; }
.wykres-pierscien-tekst small { font-size: var(--fs-drobne); color: var(--text-secondary); margin-top: 4px; }
.wykres-obok { display: grid; grid-template-columns: auto 1fr; gap: 22px; align-items: center; padding: 8px 16px 14px; }
.wykres-obok .wykres { padding: 0; }
.wykres-obok .wykres-poziome { padding-bottom: 4px; }
.wykres-obok > div { min-width: 0; }
/* Panel „Finanse" na pulpicie: cztery liczby, trzy z mini linią okna.
   Przyciskiem jest tylko liczba, która dokądś prowadzi (zysk, do zapłaty). */
.fin { margin-bottom: 12px; overflow: hidden; }
.fin-kpi-row { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); }
.fin-kpi { position: relative; display: flex; flex-direction: column; align-items: flex-start; gap: 4px; padding: 14px 20px; border: 0; border-left: 1px solid var(--border); background: none; color: inherit; font: inherit; text-align: left; min-width: 0; }
.fin-kpi:first-child { border-left: 0; }
button.fin-kpi { cursor: pointer; }
button.fin-kpi:hover { background: var(--card-2); }
button.fin-kpi:focus-visible { outline-offset: -2px; }
.fin-kpi-sp { display: block; width: 100%; height: 34px; margin-top: 4px; }
.wykres-linia-mini { display: block; width: 100%; height: 100%; color: var(--chart-line); }
.wykres-linia-mini.ok { color: var(--ok); }
.wykres-linia-mini.drugi { color: var(--chart-line-2); }
.wykres-linia-mini .pole { fill: currentColor; opacity: .08; }
.wykres-linia-mini .kreska { fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linejoin: round; }
.fin-kpi-l { display: flex; align-items: center; gap: 8px; font-size: var(--fs-meta); color: var(--text-secondary); }
.fin-kpi-l i { width: 10px; height: 10px; border-radius: 2px; background: var(--chart-line); flex: none; }
.fin-kpi-l i.ok { background: var(--ok); } .fin-kpi-l i.warn { background: var(--warn); } .fin-kpi-l i.bad { background: var(--bad); }
.fin-kpi-l i.drugi { background: var(--chart-line-2); } .fin-kpi-l i.linia { background: var(--chart-line); }
.fin-kpi-v { font-size: var(--fs-liczba-m); font-weight: 500; letter-spacing: -.02em; font-variant-numeric: tabular-nums; line-height: 1.15; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.fin-kpi.bad .fin-kpi-v { color: var(--bad); }
.fin-kpi-d { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; font-size: var(--fs-meta); line-height: 1.5; color: var(--text-secondary); max-width: 100%; }
.fin-kpi-cz { white-space: nowrap; }
/* Telefon: po zawinięciu kropka zostawała na końcu linii, odstęp zastępuje ją. */
@media (max-width: 768px) { .fin-kpi-sep { display: none; } .fin-kpi-d { gap: 2px 8px; } }
.fin-kpi-d .warn { color: var(--warn-tekst); } .fin-kpi-d .bad { color: var(--bad-tekst); }
.delta { display: inline-flex; align-items: center; gap: 4px; font-size: var(--fs-drobne); font-weight: 500; padding: 1px 6px; border-radius: 5px; font-variant-numeric: tabular-nums; }
.delta.dobrze { background: var(--ok-bg); color: var(--ok-tekst); }
.delta.zle { background: var(--bad-bg); color: var(--bad-tekst); }
.delta.plaska { background: var(--neutral-bg); color: var(--neutral-tekst); }
.link-btn { border: 0; background: none; padding: 0; font: inherit; color: inherit; text-decoration: underline; text-underline-offset: 2px; cursor: pointer; }
.wykres-adnotacja { position: absolute; left: 8px; top: 6px; font-size: var(--fs-drobne); color: var(--chart-axis); background: var(--card); padding: 1px 6px; border-radius: 4px; box-shadow: 0 0 0 1px var(--border); pointer-events: none; }
.wykres-legenda i.kreska { background: none; height: 0; border-top: 2px dashed; vertical-align: 3px; }
@media (max-width: 960px) { .fin-kpi-row { grid-template-columns: repeat(2, minmax(0, 1fr)); } .fin-kpi:nth-child(3) { border-left: 0; } .fin-kpi:nth-child(n+3) { border-top: 1px solid var(--border); } }
/* Na telefonie kwota (zwłaszcza dwie waluty) nie mieści się w połowie
   szerokości — łamie się zamiast znikać pod wielokropkiem. */
@media (max-width: 620px) { .fin-kpi { padding: 12px 14px 14px; } .fin-kpi-v { white-space: normal; overflow-wrap: anywhere; font-size: var(--fs-liczba-s); } }

/* Kafle stanu: pasek dni / mini słupki / kropki zamiast pola pod linią. */
/* Dół kafla ma stałą wysokość, żeby trzy kafle w rzędzie kończyły się na
   tej samej linii bez względu na to, czy niosą pasek, słupki czy kropki. */
.pk-pasek, .pk-mini { display: flex; flex-direction: column; justify-content: flex-end; min-height: 34px; padding: 12px 0 16px; }
/* Do zrobienia: jeden pasek, odcinek na wagę (pilne · ważne · reszta). */
.pk-wagi { display: flex; gap: 3px; height: 10px; }
.pk-wagi i { min-width: 6px; border-radius: 2px; background: var(--muted); }
.pk-wagi i.bad { background: var(--bad); }
.pk-wagi i.warn { background: var(--warn); }
.pk-pasek .wykres-pasek-dni { display: block; width: 100%; height: 18px; }
.wykres-mini { display: flex; align-items: flex-end; gap: 4px; height: 44px; }
.wykres-mini i { flex: 1 1 0; min-width: 0; border-radius: 2px 2px 1px 1px; background: var(--chart-line); opacity: .85; }
.wykres-mini.ok i { background: var(--ok); } .wykres-mini.warn i { background: var(--warn); } .wykres-mini.bad i { background: var(--bad); }
.wykres-mini i.pusty { background: var(--chart-grid); opacity: 1; }
.wykres-kropki { display: block; width: 100%; height: 44px; }
.pk-mini-pusto { display: block; height: 44px; border-bottom: 1.5px solid var(--chart-grid); box-sizing: border-box; }
/* Lejek na kaflu (Leady): jeden pasek, odcinek na etap, odcień ciemnieje
   z etapem. Stoi na dole miejsca po wykresie, jak linia osi w kropkach. */
.wykres-etapy { display: flex; gap: 4px; height: 10px; }
.wykres-etapy i { min-width: 6px; border-radius: 2px; background: var(--chart-line); }
.pk-os { display: flex; justify-content: space-between; align-items: center; font-size: var(--fs-os); color: var(--chart-axis); margin-top: 4px; }

/* Paski dni: wiersz na stronę, 90 prostokątów w SVG (rozciąganie
   prostokątów nie boli), po prawej dostępność. */
.wykres-dni-wiersz { display: grid; grid-template-columns: minmax(120px, 20%) 1fr 64px; gap: 12px; align-items: center; padding: 4px 0; }
.wykres-dni-wiersz svg { display: block; width: 100%; height: 14px; }
.wykres-dni-nazwa { font-weight: 400; font-size: var(--fs-tresc); }
.wykres-dni-procent { text-align: right; font-size: var(--fs-meta); color: var(--text-secondary); }
.wykres-dni-procent.warn { color: var(--warn-tekst); }
.wykres-dni-procent.bad { color: var(--bad-tekst); }
.wykres-dni-os { display: flex; justify-content: space-between; margin: 4px 76px 0 calc(max(120px, 20%) + 12px); font-size: var(--fs-os); color: var(--chart-axis); }

@media (max-width: 620px) {
  .wykres-wiersz, .wykres-etap { grid-template-columns: 1fr; gap: 4px; }
  .wykres-wiersz-meta, .wykres-etap-meta { text-align: left; }
  .wykres-srednia { display: none; }
  .wykres-obok { grid-template-columns: 1fr; justify-items: center; }
  .wykres-dni-wiersz { grid-template-columns: 1fr 56px; }
  .wykres-dni-nazwa { grid-column: 1 / -1; }
  .wykres-dni-os { margin-left: 0; }
}

/* ======================================================= dialogi i menu
   Okna z `dialogi.js`. `<dialog>` i `[popover]` mają własne style
   przeglądarki (obrys, `inset: 0`, margines auto) — zdejmujemy je tu,
   reszta z tokenów jak arkusz i menu konta. */
.dialog {
  width: min(460px, calc(100vw - 32px));
  max-height: calc(100vh - 32px);
  padding: 0;
  border: 0;
  border-radius: var(--r-menu);
  background: var(--card);
  color: var(--foreground);
  box-shadow: var(--cien-pop);
  overflow: visible;
  transition: opacity var(--t-wejscie) var(--ease-out), scale var(--t-wejscie) var(--ease-out), display var(--t-wejscie) allow-discrete, overlay var(--t-wejscie) allow-discrete;
}
.dialog::backdrop { background: var(--overlay); transition: opacity var(--t-wejscie) var(--ease-out), display var(--t-wejscie) allow-discrete, overlay var(--t-wejscie) allow-discrete; }
@starting-style {
  .dialog[open] { opacity: 0; scale: .97; }
  .dialog[open]::backdrop { opacity: 0; }
}
.dialog:not([open]) { opacity: 0; scale: .97; }
.dialog:not([open])::backdrop { opacity: 0; }
.dialog-form { display: flex; flex-direction: column; gap: 8px; padding: 22px 22px 18px; }
.dialog-form.szeroka { width: min(600px, calc(100vw - 32px)); }
.dialog-tytul { margin: 0; font-size: var(--fs-tytul-karty); font-weight: 500; line-height: 1.3; }
.dialog-tresc { margin: 0; font-size: var(--fs-tresc); line-height: 1.5; color: var(--text-secondary); white-space: pre-line; }
.dialog-pola { margin-top: 8px; }
.dialog-pola .field:last-child { margin-bottom: 0; }
.dialog-stopka { display: flex; justify-content: flex-end; gap: 8px; margin-top: 12px; }
.dialog-stopka .btn { min-width: 88px; }

.menu-kotwica { display: inline-flex; align-items: center; }
.row-act.ikona { width: 26px; padding: 0; justify-content: center; }
@media (max-width: 768px) { .row-act.ikona { width: 36px; height: 36px; } }
.row-act.ikona svg { width: 15px; height: 15px; fill: currentColor; }
.row-act[aria-expanded="true"] { box-shadow: var(--faza-hover); background: var(--hover-bg); }

.menu {
  position: fixed;
  inset: auto;
  margin: 0;
  min-width: 180px;
  max-width: 320px;
  padding: 6px;
  border: 0;
  border-radius: var(--r-menu);
  background: var(--card);
  color: var(--foreground);
  box-shadow: var(--cien-pop);
  overflow: visible;
  transition: opacity 120ms var(--ease-out), scale 120ms var(--ease-out);
}
@starting-style { .menu:popover-open { opacity: 0; scale: .96; } }
.menu-tytul { padding: 6px 10px 8px; font-size: var(--fs-etykieta); font-weight: 500; color: var(--text-secondary); }
.menu-kreska { height: 1px; margin: 4px 6px; background: var(--border); }
.menu [role="menuitem"], .menu [role="menuitemcheckbox"] {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1px;
  width: 100%;
  padding: 8px 10px;
  border: 0;
  border-radius: var(--r-xs);
  background: transparent;
  color: var(--foreground);
  font: inherit;
  font-size: var(--fs-tresc);
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--t-szybko) var(--ease);
}
.menu [role="menuitem"]:hover, .menu [role="menuitem"]:focus-visible, .menu [role="menuitemcheckbox"]:hover, .menu [role="menuitemcheckbox"]:focus-visible { background: var(--hover-bg); outline: none; }
.menu [role="menuitem"]:disabled { opacity: .5; cursor: default; }
.menu [role="menuitem"].danger { color: var(--bad-tekst); }
.menu [role="menuitem"].danger:hover { background: var(--bad-bg); }
.menu [role="menuitem"].aktywna .menu-etykieta::after { content: " ✓"; color: var(--text-secondary); }
.menu-opis { font-size: var(--fs-meta); color: var(--text-secondary); }

.tip {
  position: fixed;
  inset: auto;
  margin: 0;
  max-width: 280px;
  padding: 6px 8px;
  border: 0;
  border-radius: var(--r-xs);
  background: var(--foreground);
  color: var(--background);
  font-size: var(--fs-meta);
  line-height: 1.4;
  box-shadow: var(--cien-pop);
  pointer-events: none;
  overflow: visible;
  transition: opacity 100ms var(--ease-out);
}
@starting-style { .tip:popover-open { opacity: 0; } }

/* ============================================================ kalendarz
   Miesiąc z agendą (Kalendarz), pasek tygodnia (Pulpit) i wybierak daty
   do pól — kalendarz.js. Rodzaje zdarzeń w kolorach palety kategorii,
   tony stanu tylko dla faktury po terminie. */
.kropka.ok { background: var(--ok); box-shadow: 0 0 0 4px var(--ok-bg); }
.kropka.drugi { background: var(--chart-line-2); box-shadow: none; }
.kropka.neutral { background: var(--muted-fg); box-shadow: none; }

.kal { padding: 14px 16px 16px; }
.kal-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 12px; }
.kal-nav { display: flex; align-items: center; gap: 6px; }
.kal-nav .row-act.ikona svg { width: 14px; height: 14px; fill: none; }
.kal-tytul { margin: 0 6px; min-width: 150px; font-size: var(--fs-tytul-karty); font-weight: 500; text-align: center; }
.kal-legenda { display: flex; flex-wrap: wrap; gap: 12px; font-size: var(--fs-meta); color: var(--text-secondary); }
.kal-legenda span { display: inline-flex; align-items: center; gap: 4px; }
.kal-legenda .kropka, .kal-poz .kropka { width: 7px; height: 7px; box-shadow: none; }
.kal-cialo { display: grid; grid-template-columns: minmax(0, 1fr) 300px; gap: 16px; }
.kal-tyg { display: grid; grid-template-columns: repeat(7, 1fr); padding: 0 0 6px; font-size: var(--fs-etykieta); color: var(--text-secondary); }
.kal-tyg span { text-align: center; }
.kal-komorki { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); grid-auto-rows: minmax(92px, auto); gap: 1px; background: var(--border); box-shadow: 0 0 0 1px var(--border); border-radius: var(--r-s); overflow: hidden; }
.kal-dzien { display: flex; flex-direction: column; gap: 4px; min-width: 0; padding: 6px; background: var(--card); cursor: pointer; transition: background-color var(--t-szybko) var(--ease); }
.kal-dzien:hover { background: var(--card-2); }
.kal-dzien:focus-visible { outline: 2px solid var(--fokus); outline-offset: -2px; }
/* `.dzis` to też blok „Na dziś" z Pulpitu: bez tego dzisiejsza komórka dostawała jego margines, cień i promień. */
.kal-dzien.dzis { margin-bottom: 0; border-radius: 0; box-shadow: none; overflow: visible; }
.kal-dzien.poza { background: var(--background); }
.kal-dzien.poza .kal-nr, .kal-dzien.weekend .kal-nr { color: var(--text-secondary); }
.kal-dzien.poza .kal-zd { opacity: .7; }
.kal-dzien.wybrany { box-shadow: inset 0 0 0 2px var(--brand); }
.kal-nr { display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 22px; border-radius: 50%; font-size: var(--fs-kontrolka); font-weight: 500; font-variant-numeric: tabular-nums; }
.kal-dzien.dzis .kal-nr { background: var(--brand); color: var(--brand-fg); }
.kal-zdarzenia { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.kal-zd { position: relative; display: flex; align-items: center; gap: 6px; min-width: 0; height: 20px; padding: 0 6px 0 8px; border: 0; border-radius: 4px; background: var(--neutral-bg); color: var(--foreground); font: inherit; font-size: var(--fs-drobne); text-align: left; cursor: pointer; }
.kal-zd::before { content: ""; position: absolute; left: 0; top: 3px; bottom: 3px; width: 3px; border-radius: 2px; background: var(--muted-fg); }
/* Kategoria zdarzenia w kolorze z palety chipów (`us-kolor-*` daje --tag-*);
   czerwień tylko dla stanu — faktura po terminie (audyt UI, M-07). */
.kal-zd[class*="us-kolor-"] { background: var(--tag-bg); color: var(--tag-tekst); } .kal-zd[class*="us-kolor-"]::before { background: var(--tag-tekst); }
.kal [class*="us-kolor-"].kropka { background: var(--tag-tekst); }
.kal-zd.bad { background: var(--bad-bg); color: var(--bad-tekst); } .kal-zd.bad::before { background: var(--bad); }
.kal-zd:hover { filter: brightness(1.08); }
.kal-zd .ellipsis { display: block; flex: 1; min-width: 0; }
.kal-zd time { flex: none; font-variant-numeric: tabular-nums; opacity: .8; }
.kal-wiecej { padding-left: 4px; font-size: var(--fs-drobne); color: var(--text-secondary); }
/* Agenda nie dyktuje wysokości: `contain: size` daje jej zerowy wkład do
   wiersza siatki, więc wiersz mierzy kalendarz, a agenda rozciąga się do
   niego i przewija resztę — bez pustego pola pod miesiącem. */
.kal-agenda { min-width: 0; padding-left: 16px; border-left: 1px solid var(--border); contain: size; overflow-y: auto; overscroll-behavior: contain; }
.kal-ag-head { display: flex; align-items: center; gap: 8px; min-height: 26px; margin-bottom: 8px; position: sticky; top: 0; z-index: 1; background: var(--card); }
.kal-ag-head .panel-label { margin: 0; }
.kal-ag-head .chip { margin-left: auto; }
/* Panel dnia (Kalendarz D): pozycja to <details>, które rozwija się do edycji. */
.kal-poz + .kal-poz, .kal-nowe + .kal-poz { border-top: 1px solid var(--border); }
.kal-poz > summary { display: flex; align-items: center; gap: 10px; min-height: 44px; padding: 6px 8px; border-radius: var(--r-xs); list-style: none; cursor: pointer; transition: background-color var(--t-szybko) var(--ease); }
.kal-poz > summary::-webkit-details-marker { display: none; }
.kal-poz > summary:hover, .kal-poz[open] > summary { background: var(--hover-bg); }
.kal-poz > summary:focus-visible { outline: 2px solid var(--fokus); outline-offset: -2px; }
.kal-poz[open] > summary .szewron { transform: rotate(180deg); }
.kal-poz .kropka { flex: none; }
.kal-poz-g { flex: 0 0 34px; display: flex; flex-direction: column; line-height: 1.3; font-variant-numeric: tabular-nums; }
.kal-poz-g small { font-size: var(--fs-drobne); opacity: .75; }
.kal-form { padding: 10px 8px 14px; }
.kal-form textarea { display: block; resize: vertical; font-family: inherit; }
.kal-form .field-row { flex-wrap: nowrap; }
.kal-form .field-row > .field { min-width: 0; }
.kal-godziny > .field { flex: 1 1 0; }
.kal-nowe { margin-bottom: 4px; border-radius: var(--r-s); background: var(--card-2); }
.kal-agenda .empty-note { padding: 8px; }
/* „Co dalej" pod dzisiejszym dniem: dni z najbliższych 14 z pozycjami-skrótami. */
.kal-dalej { margin-top: 12px; padding-top: 4px; border-top: 1px solid var(--border); }
.kal-dalej-dzien { display: flex; align-items: baseline; gap: 8px; padding: 10px 8px 2px; font-size: var(--fs-meta); font-weight: 500; }
.kal-skrot { display: flex; align-items: center; gap: 10px; width: 100%; min-height: 40px; padding: 4px 8px; border: 0; border-radius: var(--r-xs); background: none; color: inherit; font: inherit; font-size: var(--fs-tresc); text-align: left; cursor: pointer; transition: background-color var(--t-szybko) var(--ease); }
.kal-skrot:hover { background: var(--hover-bg); }
.kal-skrot:focus-visible { outline: 2px solid var(--fokus); outline-offset: -2px; }
.kal-skrot .kropka { flex: none; width: 7px; height: 7px; box-shadow: none; }
.kal-skrot .row-stack { min-width: 0; }
.kal-skrot-wiecej { min-height: 28px; padding-left: 61px; color: var(--text-secondary); font-size: var(--fs-meta); }
@media (max-width: 960px) {
  .kal-cialo { grid-template-columns: 1fr; }
  .kal-agenda { padding: 12px 0 0; border-left: 0; border-top: 1px solid var(--border); contain: none; overflow: visible; }
  .kal-ag-head { position: static; }
}
@media (max-width: 620px) {
  .kal-komorki { grid-auto-rows: minmax(52px, auto); }
  /* Na telefonie pasek zostaje kreską w kolorze kategorii — napis jest w panelu dnia. */
  .kal-zdarzenia { gap: 2px; }
  .kal-zd { height: 6px; padding: 0; border-radius: 3px; background: var(--muted-fg); }
  .kal-zd::before, .kal-zd .ellipsis, .kal-zd time, .kal-wiecej { display: none; }
  .kal-zd[class*="us-kolor-"] { background: var(--tag-tekst); } .kal-zd.bad { background: var(--bad); }
}

/* Pasek tygodnia na pulpicie. */
.tydz { padding: 12px 16px 12px; margin-bottom: 12px; }
.tydz-head { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.tydz-head .panel-label { margin: 0; }
.tydz-head .link-btn { margin-left: auto; }
.tydz-dni { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 6px; }
.tydz-dzien { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; min-width: 0; padding: 8px 10px; border: 0; border-radius: var(--r-s); background: var(--card-2); color: inherit; font: inherit; text-align: left; cursor: pointer; transition: box-shadow var(--t) var(--ease), background-color var(--t) var(--ease); }
.tydz-dzien:hover { box-shadow: var(--faza-hover); }
.tydz-dzien.minal { opacity: .6; }
.tydz-dzien.dzis { background: var(--card); box-shadow: 0 0 0 1px var(--brand); }
.tydz-dzien.dzis:hover { box-shadow: 0 0 0 1px var(--brand), var(--faza-hover); }
.tydz-nazwa { font-size: var(--fs-meta); color: var(--text-secondary); }
.tydz-nr { font-size: var(--fs-akcent); font-weight: 500; line-height: 1.2; font-variant-numeric: tabular-nums; }
.tydz-dzien.dzis .tydz-nr { color: var(--brand-tekst); }
.tydz-tekst { display: block; max-width: 100%; min-height: 1.4em; font-size: var(--fs-meta); color: var(--text-secondary); }
.tydz-tekst small { font-size: var(--fs-drobne); }
/* Na telefonie tydzień zaczyna się od dziś i przewija się w bok: minione dni
   wypychały dzisiejszy za krawędź, a dzień bez nazwy wydarzenia (dawne
   kropki) nie mówił, co wypada. */
@media (max-width: 720px) {
  .tydz-dni { grid-template-columns: none; grid-auto-flow: column; grid-auto-columns: minmax(104px, 1fr); overflow-x: auto; scrollbar-width: none; padding: 1px; margin: -1px; }
  .tydz-dni::-webkit-scrollbar { display: none; }
  .tydz-dzien.minal { display: none; }
}

/* Wybierak daty (popover przy polu z data-data). */
.dp { position: fixed; inset: auto; margin: 0; width: 272px; padding: 10px; border: 0; border-radius: var(--r-menu); background: var(--card); color: var(--foreground); box-shadow: var(--cien-pop); overflow: visible; }
@starting-style { .dp:popover-open { opacity: 0; } }
.dp-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px; }
.dp-tytul { font-size: var(--fs-tresc); font-weight: 500; }
.dp-tyg { display: grid; grid-template-columns: repeat(7, 1fr); margin-bottom: 2px; font-size: var(--fs-os); text-align: center; color: var(--text-secondary); }
.dp-dni { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.dp-dzien { height: 32px; border: 0; border-radius: var(--r-xs); background: transparent; color: var(--foreground); font: inherit; font-size: var(--fs-kontrolka); font-variant-numeric: tabular-nums; cursor: pointer; }
.dp-dzien:hover { background: var(--hover-bg); }
.dp-dzien.poza { color: var(--text-secondary); opacity: .55; }
.dp-dzien.dzis { box-shadow: inset 0 0 0 1px var(--border-strong); }
.dp-dzien.wybrany { background: var(--brand); color: var(--brand-fg); }
.dp-stopka { display: flex; justify-content: space-between; margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--border); }

/* ================================================================ filtry
   Pasek nad listą (wzorzec Data Table): szukajka, selekty, zakres dat,
   licznik i Wyczyść — `pasekFiltrow` w wspolne.js. Kontrolki 30 px jak
   przełącznik okien, promień pola, nie pastylki: to formularz, nie wybór. */
.filtry { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-bottom: 12px; }
.filtry input, .filtry select {
  height: 30px;
  padding: 0 10px;
  border: 1px solid var(--input);
  border-radius: var(--r-s);
  background: var(--card);
  color: var(--foreground);
  font: inherit;
  font-size: var(--fs-tresc);
  transition: border-color var(--t) var(--ease), box-shadow var(--t) var(--ease);
}
.filtry input:focus, .filtry select:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-soft); }
.filtry select { padding-right: 26px; cursor: pointer; color: var(--text-secondary); }
.filtry select.aktywny { color: var(--foreground); border-color: var(--border-strong); }
.filtry-szukaj { position: relative; display: inline-flex; flex: 1 1 200px; max-width: 320px; }
.filtry-szukaj svg { position: absolute; left: 9px; top: 50%; width: 14px; height: 14px; translate: 0 -50%; stroke: var(--text-secondary); fill: none; stroke-width: 2; stroke-linecap: round; pointer-events: none; }
.filtry-szukaj input { width: 100%; padding-left: 29px; }
.filtry-szukaj input::placeholder { color: var(--text-secondary); opacity: 1; }
.filtry-szukaj input::-webkit-search-cancel-button { cursor: pointer; }
.filtry-data { width: 118px; font-size: var(--fs-meta) !important; }
/* „Sortuj" zastępuje nagłówek kolumn tylko w układzie karty (zapytanie
   kontenera przy `.lista-firm-ramka`); na szerokiej liście sortuje nagłówek. */
.filtry .filtry-sortuj { display: none; }
.filtry-licznik { margin-left: auto; font-size: var(--fs-meta); color: var(--text-secondary); font-variant-numeric: tabular-nums; white-space: nowrap; }
.filtry-licznik + .row-act { margin-left: 0; }
@media (max-width: 620px) {
  .filtry-szukaj { flex-basis: 100%; max-width: none; }
  .filtry-licznik { margin-left: 0; }
}

/* Sortowanie po nagłówku kolumny (Klienci). */
.naglowek-tabeli .sortuj { display: inline-flex; align-items: center; gap: 4px; padding: 0; border: 0; background: none; color: inherit; font: inherit; letter-spacing: inherit; text-transform: inherit; cursor: pointer; }
.naglowek-tabeli .sortuj.do-prawej { justify-self: end; }
.naglowek-tabeli .sortuj:hover, .naglowek-tabeli .sortuj.aktywny { color: var(--foreground); }
.sortuj-strzalka { font-size: 11px; opacity: 0; transition: opacity var(--t) var(--ease); }
.sortuj:hover .sortuj-strzalka { opacity: .6; }
.sortuj.aktywny .sortuj-strzalka { opacity: 1; }

/* ======================================================== drobne wzorce
   Alert, kanban leadów, przełącznik, spinner w przycisku, „pokaż więcej",
   okruszki, karta po najechaniu, szuflada na telefonie. */

/* Alert: ostrzeżenie z ikoną i tytułem zamiast szarego akapitu `.help`. */
.alert { display: flex; gap: 10px; align-items: flex-start; padding: 10px 12px; border-radius: var(--r-s); background: var(--neutral-bg); box-shadow: inset 0 0 0 1px var(--neutral-border); font-size: var(--fs-tresc); line-height: 1.45; }
.alert svg { flex: none; width: 16px; height: 16px; margin-top: 1px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.alert strong { display: block; }
.alert p { margin: 2px 0 0; color: var(--text-secondary); }
.alert.warn { background: var(--warn-bg); box-shadow: inset 0 0 0 1px var(--warn-border); }
.alert.warn svg, .alert.warn strong { color: var(--warn-tekst); }
.alert.bad { background: var(--bad-bg); box-shadow: inset 0 0 0 1px var(--bad-border); }
.alert.bad svg, .alert.bad strong { color: var(--bad-tekst); }
.alert.ok { background: var(--ok-bg); box-shadow: inset 0 0 0 1px var(--ok-border); }
.alert.ok svg, .alert.ok strong { color: var(--ok-tekst); }
.panel-pad > .alert, .row + .alert { margin-top: 10px; }

/* Kanban leadów: kolumny etapów, karty do przeciągania. */
.kanban { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(240px, 1fr); gap: 12px; overflow-x: auto; padding-bottom: 4px; scroll-snap-type: x proximity; }
.kan-kolumna { display: flex; flex-direction: column; min-width: 0; border-radius: var(--r); background: var(--card-2); box-shadow: var(--cien-ramka); scroll-snap-align: start; transition: box-shadow var(--t) var(--ease), background-color var(--t) var(--ease); }
.kan-kolumna.nad { box-shadow: 0 0 0 2px var(--brand); background: var(--brand-soft); }
.kan-kolumna.zamknieta { opacity: .75; }
/* Jedna linia sum nad listą albo tablicą (Klienci, Leady). */
.kan-head { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: baseline; gap: 6px 8px; padding: 10px 12px 6px; }
/* Pasek w nagłówku kolumny: wartość etapu wobec najcięższego — to, co mówił duży lejek. */
.kan-pasek { flex: 1 0 100%; height: 4px; border-radius: 2px; background: var(--muted); overflow: hidden; }
.kan-pasek b { display: block; height: 100%; border-radius: 2px; background: var(--text-secondary); }
.kan-karta .row-meta.warn { color: var(--warn-tekst); }
.kan-tytul .menu-kotwica { flex: none; margin: -4px -6px -4px 0; }
.kan-head .panel-label { margin: 0; }
.kan-head .row-meta { white-space: nowrap; font-variant-numeric: tabular-nums; }
.kan-lista { display: flex; flex: 1; flex-direction: column; gap: 8px; min-height: 64px; padding: 4px 8px 10px; }
.kan-karta { display: flex; flex-direction: column; gap: 4px; padding: 10px 12px; border-radius: var(--r-s); background: var(--card); box-shadow: var(--cien-ramka); cursor: grab; transition: box-shadow var(--t) var(--ease), opacity var(--t) var(--ease); }
.kan-karta:hover { box-shadow: var(--faza-hover); }
.kan-karta.ciagnie { opacity: .4; cursor: grabbing; }
.kan-karta[draggable="false"] { cursor: default; }
.kan-tytul { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 4px 8px; font-size: var(--fs-tresc); }
/* Nazwa leada to treść wiersza, nie nagłówek — waga 400 jak w każdej liście. */
.kan-tytul strong { flex: 1 1 auto; min-width: 0; max-width: 100%; font-weight: 400; }
/* Stopka zawija się, zamiast wypychać akcje poza kartę: przy wąskiej kolumnie
   „31 dni bez ruchu" zostaje w pierwszej linii, a Przesuń i menu schodzą
   razem pod spód, do prawej krawędzi. */
.kan-pusto { padding: 14px 8px; border: 1px dashed var(--border-strong); border-radius: var(--r-s); font-size: var(--fs-meta); text-align: center; color: var(--text-secondary); }
@media (max-width: 720px) { .kanban { grid-auto-columns: minmax(78vw, 1fr); } }

/* Przełącznik zamiast checkboxa przy włącz/wyłącz. Listy wyboru
   (`.toggle.lista`) zostają checkboxami — tam się zaznacza kilka. */
.toggle:not(.lista) input[type="checkbox"] { position: relative; flex: none; width: 32px; height: 18px; margin: 0; border-radius: 999px; background: var(--neutral-bg); box-shadow: inset 0 0 0 1px var(--border-strong); appearance: none; cursor: pointer; transition: background-color var(--t) var(--ease), box-shadow var(--t) var(--ease); }
.toggle:not(.lista) input[type="checkbox"]::before { content: ""; position: absolute; top: 2px; left: 2px; width: 14px; height: 14px; border-radius: 50%; background: var(--card); box-shadow: 0 1px 2px rgba(0, 0, 0, .3); transition: translate var(--t) var(--ease), background-color var(--t) var(--ease); }
.toggle:not(.lista) input[type="checkbox"]:checked { background: var(--brand); box-shadow: none; }
.toggle:not(.lista) input[type="checkbox"]:checked::before { translate: 14px 0; background: #fff; }
.toggle:not(.lista) input[type="checkbox"]:focus-visible { outline: 2px solid var(--fokus); outline-offset: 2px; }
.toggle:not(.lista) input[type="checkbox"]:disabled { opacity: .5; cursor: not-allowed; }

/* Spinner w przycisku, który czeka na serwer. Tekst zostaje („Wysyłam…"),
   kółko stoi przed nim — bez tego klik w „Szkic AI" był ciszą. */
.czeka::before { content: ""; flex: none; width: 12px; height: 12px; border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%; animation: kreci .7s linear infinite; }
.btn.czeka, .row-act.czeka, .chip.czeka { gap: 8px; }
@keyframes kreci { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .czeka::before { animation-duration: 1.6s; } }

/* „Pokaż więcej" pod uciętą listą. */
.pokaz-wiecej { display: flex; justify-content: center; padding: 8px 0 4px; }

/* Okruszki nad tytułem widoku szczegółów. */
.okruszki { display: flex; align-items: center; gap: 6px; margin: 0 0 4px; font-size: var(--fs-meta); color: var(--text-secondary); }
.okruszek { padding: 0; border: 0; background: none; color: inherit; font: inherit; cursor: pointer; }
.okruszek:hover { color: var(--foreground); text-decoration: underline; text-underline-offset: 3px; }
.okruszek.biezacy { color: var(--foreground); cursor: default; text-decoration: none; }
.okruszki-sep { opacity: .6; }
.card-head + .card-sub, .okruszki + .card-head { margin-top: 0; }

/* Karta klienta po najechaniu na jego nazwę (HoverCard). */
.hover-karta { position: fixed; inset: auto; margin: 0; width: 280px; padding: 12px 14px; border: 0; border-radius: var(--r-menu); background: var(--card); color: var(--foreground); box-shadow: var(--cien-pop); overflow: visible; font-size: var(--fs-tresc); }
@starting-style { .hover-karta:popover-open { opacity: 0; translate: 0 4px; } }
.hover-karta { transition: opacity 120ms var(--ease-out), translate 120ms var(--ease-out); }
.hover-karta-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 6px; }
.hover-karta-head strong { font-size: var(--fs-akcent); min-width: 0; }
.hover-karta dl { display: grid; grid-template-columns: auto 1fr; gap: 4px 10px; margin: 0; }
.hover-karta dt { color: var(--text-secondary); font-size: var(--fs-meta); }
.hover-karta dd { margin: 0; font-variant-numeric: tabular-nums; }
.hover-karta .tagi-w-linii { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 8px; }

/* Szuflada na telefonie: arkusz wjeżdża z dołu, z uchwytem. */
@media (max-width: 720px) {
  .sheet-panel { inset: auto 0 0 0; width: 100%; max-height: 92vh; border-radius: 16px 16px 0 0; }
  .sheet-panel::before { content: ""; position: absolute; top: 8px; left: 50%; width: 36px; height: 4px; border-radius: 2px; background: var(--border-strong); translate: -50% 0; }
  .sheet-head { padding-top: 8px; }
  @starting-style { .sheet-panel { transform: translateY(24px); opacity: 0; } }
  .sheet.zamyka .sheet-panel { transform: translateY(16px); }
}

/* ============================================================== opiekun
   Kółko z inicjałami i nazwa konta — lista klientów, kartoteka, karta po
   najechaniu. W kartotece to przycisk z menu zespołu. */
.osoba { display: inline-flex; align-items: center; gap: 6px; min-width: 0; font-size: var(--fs-meta); }
.osoba-kolo { flex: none; display: grid; place-items: center; width: 22px; height: 22px; border-radius: 50%; background: var(--brand-soft); color: var(--brand-tekst); font-size: 10px; font-weight: 600; letter-spacing: .02em; }
.osoba.pusta { color: var(--text-secondary); }
.osoba.pusta .osoba-kolo { background: var(--muted); color: var(--muted-fg); }
.opiekun-chip { display: inline-flex; align-items: center; gap: 4px; padding: 2px 6px 2px 2px; border: 0; border-radius: var(--r-pill); background: none; color: inherit; font: inherit; cursor: pointer; vertical-align: middle; transition: background-color var(--t) var(--ease); }
.opiekun-chip:hover, .opiekun-chip[aria-expanded="true"] { background: var(--hover-bg); }
.opiekun-strzalka { font-size: 10px; color: var(--text-secondary); }
/* Tory: firma, usługi, cztery obszary (Strona, SEO, Posty, Automatyzacje), MRR, opiekun.
   Ułamki zamiast sztywnych sufitów: wolne miejsce idzie proporcjonalnie,
   a nie najpierw do kolumn z `max`, co ściskało usługi do jednego tagu w linii. */
.lista-firm { --kolumny-firm: minmax(160px, 1.4fr) minmax(150px, 1.6fr) 72px 56px 64px 84px 104px minmax(110px, .9fr); }
.firma-opiekun { min-width: 0; }
/* Musi stać PO bazowym `--kolumny-firm` wyżej — ta sama waga selektora,
   więc wygrywa późniejsza. W wąskim panelu tory obszarów się ścieśniają,
   a nagłówek tnie się wielokropkiem (pełna nazwa w dymku). */
@container lista-firm (max-width: 1000px) {
  .lista-firm { --kolumny-firm: minmax(116px, 1.4fr) minmax(104px, 1.6fr) 60px 44px 52px 72px 92px minmax(80px, .9fr); }
}
@container lista-firm (max-width: 700px) { .firma-opiekun { order: 3; } }
/* Imię i nazwisko spychały stan do osobnej linii; pełna nazwa jest w kartotece. */
@container lista-firm (max-width: 480px) { .firma-opiekun .osoba > span:last-child { display: none; } }

/* =============================================================== poczta
   Wygląd e-maili: formularz po lewej, podgląd (iframe srcdoc) po prawej.
   Newsletter: kompozytor z blokami. */
.poczta { display: grid; grid-template-columns: minmax(320px, 460px) minmax(0, 1fr); gap: 16px; align-items: start; }
.poczta-form .panel-head + .panel-pad { padding-top: 6px; }
.poczta-form .btn-row { padding: 0 16px 16px; }
.poczta-podglad { position: sticky; top: calc(var(--pasek) + 12px); }
.mail-ramka { display: block; width: 100%; height: min(78vh, 900px); border: 0; border-radius: 0 0 var(--r) var(--r); background: #fff; }
.newsletter-kompozytor .mail-ramka { height: 640px; border-radius: var(--r-s); box-shadow: var(--cien-ramka); }
.motywy { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 8px; margin-bottom: 14px; }
.motyw { display: flex; flex-direction: column; gap: 6px; padding: 6px; border-radius: var(--r-s); box-shadow: var(--cien-ramka); cursor: pointer; transition: box-shadow var(--t) var(--ease); }
.motyw:hover { box-shadow: var(--cien-ramka-hover); }
.motyw.wybrany { box-shadow: 0 0 0 2px var(--brand); }
.motyw input { position: absolute; opacity: 0; width: 0; height: 0; }
.motyw-probka { display: grid; place-items: center; height: 40px; border-radius: var(--r-xs); box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .08); }
.motyw-probka span { width: 26px; height: 10px; border-radius: 3px; }
.motyw-nazwa { font-size: var(--fs-meta); text-align: center; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.kolor-pole { display: flex; gap: 8px; align-items: center; }
.kolor-pole input[type="color"] { flex: none; width: 38px; height: 38px; padding: 2px; border: 1px solid var(--input); border-radius: var(--r-s); background: var(--card); cursor: pointer; }
.kolor-pole input[type="text"] { flex: 1; }
.logo-pole { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.logo-podglad { height: 32px; max-width: 180px; padding: 4px 8px; border-radius: var(--r-xs); background: var(--card-2); box-shadow: var(--cien-ramka); object-fit: contain; }
.field input[type="range"] { width: 100%; accent-color: var(--brand); }
.bloki { display: flex; flex-direction: column; gap: 10px; margin: 6px 0 10px; }
.blok { padding: 10px 12px 12px; border-radius: var(--r-s); background: var(--card-2); box-shadow: var(--cien-ramka); }
.blok-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; }
.blok-akcje { display: inline-flex; gap: 4px; }
.blok textarea, .blok input { width: 100%; }
.blok textarea + input { margin-top: 8px; }
.blok .field-row { margin: 0; }
.stat-edytor { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
.stat-para { display: grid; gap: 4px; }
.firmy-wybor { margin-top: 10px; max-height: 240px; overflow: auto; }
.okna label.okno { cursor: pointer; }
@media (max-width: 1100px) { .poczta { grid-template-columns: 1fr; } .poczta-podglad { position: static; } .mail-ramka { height: 640px; } }

/* ================================================ przestrzeń robocza strony
   Cztery panele obok siebie, każdy przewija się sam (decyzja z 24 września,
   docs/PLAN-OKARA.md 1.3). Szerokości, zwinięcia i kolejność (order)
   nakłada public/js/przestrzen.js po zmierzeniu rzędu — CSS opisuje tylko
   stany. Poniżej progu z uklad.js panele stają się zakładkami. */

.przestrzen { display: flex; flex-direction: column; gap: 8px; }
.pp-naglowek { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.pp-tytul { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; min-width: 0; }
.pp-tytul .card-title { margin: 0; }
/* Strona w grupie Kanały: ten sam odstęp co `.card-title-lewa` w Postach,
   Newsletterze i Kontach — przełącznik podzakładek stoi w tym samym miejscu (M-16). */
.pp-tytul:has(> .pp-kanaly) { gap: 14px; }
/* Przycisk Kanału (wariant A, 1 października): na komputerze go nie ma —
   tam stoi pasek podzakładek. Mniejszy od akcji obok (26 px, 12 px), żeby
   czytał się jako dopisek do nazwy strony, nie kolejne polecenie. */
.pp-kanal { display: none; }
/* Nagłówek Kanałów na telefonie: nazwa strony, przycisk Kanału i akcje
   w JEDNYM rzędzie, pasek podzakładek schowany (zastępuje go menu Kanału —
   trzy poziomy zakładek nad treścią zjadały pół ekranu). Nazwa jedyna się
   kurczy i ucina wielokropkiem; `display: contents` wpuszcza dzieci
   `.card-title-lewa` (Posty, Newsletter, Konta) do tego samego rzędu co
   w przestrzeni strony. `min-height` — rząd ma wysokość akcji także w Kontach,
   gdzie akcji nie ma, więc nagłówek nie skacze między podzakładkami. */
@media (max-width: 768px) {
  .card-title-row.naglowek-kanalu, .pp-tytul.naglowek-kanalu { display: flex; flex-wrap: nowrap; align-items: center; gap: 8px; min-height: 30px; }
  .naglowek-kanalu > .card-title-lewa { display: contents; }
  .naglowek-kanalu .pp-przelacznik { flex: 0 1 auto; min-width: 0; }
  .naglowek-kanalu .pp-przelacznik .card-title { min-width: 0; }
  .naglowek-kanalu > .pp-akcje { margin-left: auto; }
  .naglowek-kanalu .podzakladki { display: none; }
  .naglowek-kanalu .pp-kanal { display: inline-flex; flex: none; gap: 4px; height: 26px; padding: 0 8px; font-size: var(--fs-meta); }
  .pp-kanal-strzalka { font-size: 9px; color: var(--text-secondary); }
}
/* Nazwa strony = przełącznik na inną stronę (Strony w szynie otwierają od razu stronę). */
.pp-przelacznik { display: inline-flex; align-items: center; gap: 6px; min-width: 0; margin: 0 -8px; padding: 2px 8px; border: 0; border-radius: var(--r-s); background: none; color: inherit; font: inherit; cursor: pointer; transition: background-color var(--t) var(--ease), scale var(--t) var(--ease); }
.pp-przelacznik:hover, .pp-przelacznik[aria-expanded="true"] { background: var(--accent); }
.pp-przelacznik:active { scale: .96; }
.pp-przelacznik .card-title { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pp-przelacznik-strzalka { flex: none; color: var(--text-secondary); font-size: 13px; }
.pp-meta { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--fs-tresc); color: var(--text-secondary); }
.pp-akcje { display: flex; align-items: center; gap: 6px; flex: none; margin-left: auto; }
.pp-malo { flex: none; }

.pp-zakladki { display: none; }
.przestrzen.tryb-zakladki .pp-zakladki { display: flex; overflow-x: auto; align-self: stretch; }
.przestrzen.tryb-zakladki .pp-zakladki .okno { flex: 1 0 auto; }
/* Zakładki przestrzeni to TRZECI poziom nawigacji (szyna › podzakładki grupy
   › panele) — na telefonie podkreślenie jak kreska aktywnej pozycji szyny,
   nie trzecia identyczna pastylka `.okna` (audyt UI, M-28). */
.przestrzen.tryb-zakladki .pp-zakladki { height: auto; padding: 0; gap: 0; border-radius: 0; background: none; box-shadow: inset 0 -1px 0 var(--border); }
.przestrzen.tryb-zakladki .pp-zakladki .okno { position: relative; height: 36px; border-radius: 0; }
.przestrzen.tryb-zakladki .pp-zakladki .okno.active { background: none; box-shadow: none; }
.przestrzen.tryb-zakladki .pp-zakladki .okno.active::after { content: ''; position: absolute; left: 10px; right: 10px; bottom: 0; height: 2px; border-radius: 2px 2px 0 0; background: var(--foreground); }

.pp-rzad {
  display: flex;
  /* Wszystkie panele sięgają do dołu okna (decyzja właściciela z 1 października):
     kolumny różnej wysokości — krótki Kontekst i lista obok pełnego Asystenta —
     wyglądały na niedokończone. Treść zostaje u góry, przewija się w panelu. */
  align-items: stretch;
  height: calc(100vh / var(--zoom) - var(--pp-gora, 220px) - 16px);
  min-height: 460px;
}
.pp { max-height: 100%; }
.pp.zwiniety, .pp[data-panel="asystent"], .pp-uchwyt { align-self: stretch; }
/* Uchwyt przy górze, na wysokości nagłówków — w połowie rzędu wisiał w pustce pod krótkimi panelami. */
.pp-rzad > .pp-uchwyt { align-items: flex-start; padding-top: 12px; }
/* Rząd kończy się 16 px nad dołem okna — scena nie dokłada swoich 64 px
   marginesu, inaczej cała strona przewijałaby się o różnicę. */
.stage:has(.przestrzen:not(.tryb-zakladki)) { padding-bottom: 16px; }

.pp {
  position: relative;
  display: flex;
  flex-direction: column;
  min-width: 0;
  overflow: hidden;
  border-radius: var(--r);
  background: var(--card);
  box-shadow: var(--cien-ramka);
}
.pp.ukryty { display: none; }
.pp.cel-upuszczenia { box-shadow: 0 0 0 2px var(--brand); }

.pp-glowa {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: none;
  height: 40px;
  padding: 0 6px 0 8px;
  border-bottom: 1px solid var(--border);
  cursor: grab;
  user-select: none;
}
.pp-glowa:active { cursor: grabbing; }
.pp-kropki { flex: none; width: 14px; height: 14px; fill: var(--idle); }
.pp-nazwa { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--fs-tresc); font-weight: 500; color: var(--foreground); }
.pp-glowa-akcje { display: flex; align-items: center; gap: 2px; margin-left: auto; flex: none; }
.pp-przycisk {
  width: 28px;
  height: 28px;
  flex: none;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--text-secondary);
  font: inherit;
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  transition: background var(--t) var(--ease), color var(--t) var(--ease);
}
.pp-przycisk:hover { background: var(--accent); color: var(--foreground); }
.pp-przycisk:active { scale: .96; }
.pp-lupa svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; }
.pp-lupa.aktywna { background: var(--accent); color: var(--foreground); }
/* Pozycje w Google: fraza i pozycja w jednej linii (strona-seo.js pozycjePanel) */
/* Linia faktów nad listą (wspolne.js pasekFaktow) — zamiast rzędu kafli */
.fakty-pasek { display: flex; align-items: center; justify-content: space-between; gap: 8px 16px; flex-wrap: wrap; padding: 2px 4px 0; }
.fakty-tekst { font-size: var(--fs-tresc); color: var(--text-secondary); }
.fakty-tekst b { color: var(--foreground); }
/* Leady: opiekun w tytule karty, konwersja pod lejkiem */
.kan-opiekun { margin-left: auto; flex: none; }
.kan-opiekun .osoba > span:last-child { display: none; }
.lejek-konwersja { margin: -4px 0 0; }
/* Sejf zero-knowledge (widoki/dostepy.js) */
.pp-klodka { width: 13px; height: 13px; vertical-align: -2px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.pp-klodka.otwarta { color: var(--ok); }
.pp-sejf p.row-meta, .pp-sejf .pp-agent .row-meta { white-space: normal; }
/* Stan strony jako wiersze sygnałów (szczegoly.js stan) */
#pp-incydenty .sygnal:last-child { border-bottom: 0; }
.pp-dostep { display: grid; grid-template-columns: 1fr auto; column-gap: 8px; padding: 6px 0; border-bottom: 1px solid var(--border); }
.pp-dostep:last-of-type { border-bottom: 0; }
.pp-dostep-nazwa { grid-column: 1; min-width: 0; }
.pp-dostep-meta { grid-column: 1; min-width: 0; }
.pp-dostep-haslo { grid-column: 1; font-size: var(--fs-meta); user-select: all; }
.pp-dostep-akcje { grid-column: 2; grid-row: 1 / span 3; align-self: center; display: inline-flex; align-items: center; gap: 4px; }
.pp-dostep-form { display: grid; gap: 6px; margin-top: 6px; }
.pp-dostep-form input, .pp-dostep-form select { width: 100%; }
/* Panel „Social" strony */
.pp-agent { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; }
.pp-post { display: grid; grid-template-columns: 1fr auto; column-gap: 8px; width: 100%; padding: 6px 0; border: 0; border-bottom: 1px solid var(--border); background: none; color: var(--foreground); font: inherit; text-align: left; cursor: pointer; }
.pp-post:last-child { border-bottom: 0; }
.pp-post .pill { grid-column: 2; grid-row: 1 / span 2; align-self: center; }
.pp-post-tresc { grid-column: 1; grid-row: 1; min-width: 0; font-size: var(--fs-tresc); font-weight: 400; }
.pp-post-meta { grid-column: 1; grid-row: 2; }
.pp-post-meta { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pp-post:hover .pp-post-tresc { text-decoration: underline; text-underline-offset: 3px; }

.pp-tresc { flex: 1; min-height: 0; overflow: auto; padding: 12px; }
.pp-tresc > * + * { margin-top: var(--odstep-sekcji); }
.pp-tresc > .tiles + *, .pp-tresc > * + .tiles { margin-top: var(--odstep-grupy); }
/* Karta w karcie (audyt UI, M-08): panel wewnątrz panelu przestrzeni nie
   rysuje drugiej ramy — dwa pierścienie i niekoncentryczne promienie
   (10 w 10 z odstępem 12) czytały się jak pudełko w pudełku. Sąsiednie
   panele dzieli kreska, jak wiersze. Wykres zostaje w swojej ramce
   (`.wykres-panel`), bo ona odcina oś i legendę od listy pod spodem.
   Opakowania: lista Klientów, podzakładki Analityki strony, Praca w kartotece. */
:is(.pp-tresc, .pp-analityka, .pp-praca, .lista-firm-ramka) > .panel:not(.wykres-panel) { box-shadow: none; border-radius: 0; }
:is(.pp-tresc, .pp-analityka, .pp-praca, .lista-firm-ramka) > .panel:not(.wykres-panel) + .panel:not(.wykres-panel) { border-top: 1px solid var(--border); }
/* Kafle w panelu: tyle w rzędzie, ile się zmieści — panel bywa wąski. */
.pp-tresc .tiles { grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); }

/* Zwinięty panel: pasek 44 px z pionowym tytułem i przyciskiem rozwinięcia. */
.pp-szyna { display: none; }
.pp.zwiniety .pp-glowa, .pp.zwiniety .pp-tresc { display: none; }
.pp.zwiniety .pp-szyna { display: flex; flex-direction: column; align-items: center; gap: 12px; height: 100%; padding: 6px 0; }
.pp-szyna-nazwa { writing-mode: vertical-rl; transform: rotate(180deg); white-space: nowrap; font-size: var(--fs-etykieta); font-weight: 500; color: var(--text-secondary); }
.pp-szyna-auto { display: none; width: 8px; height: 8px; border-radius: 50%; background: var(--warn); }
.pp.auto .pp-szyna-auto { display: block; }

.pp-uchwyt { flex: 0 0 10px; display: flex; align-items: center; justify-content: center; cursor: col-resize; touch-action: none; }
.pp-uchwyt::before { content: ""; width: 3px; height: 36px; border-radius: 3px; background: var(--border-strong); transition: background var(--t) var(--ease); }
/* Fokus z klawiatury: zwykła obwódka projektu, nie samo ściemnienie kreski —
   to samo dawał hover, więc fokusu nie dało się odróżnić. */
.pp-uchwyt:hover::before { background: var(--text-secondary); }
.przestrzen.ciagniecie, .przestrzen.ciagniecie * { cursor: col-resize !important; user-select: none; }

/* Tryb wąski: jeden panel na całą szerokość, strona przewija się jak zwykle. */
.przestrzen.tryb-zakladki .pp-rzad { height: auto; min-height: 0; }
.przestrzen.tryb-zakladki .pp { display: none; }
.przestrzen.tryb-zakladki .pp.aktywny { display: flex; flex: 1 1 auto; }
.przestrzen.tryb-zakladki .pp-glowa { cursor: default; }
.przestrzen.tryb-zakladki .pp-nazwa { display: none; }
/* „Lista" nazywa tylko układ. Nazwa zostaje na pasku zwiniętego panelu i na zakładkach telefonu. */
.pp[data-panel="glowny"] .pp-nazwa { display: none; }
.przestrzen.tryb-zakladki .pp-glowa:not(:has(.pp-lupa, .okna)) { display: none; }
.przestrzen.tryb-zakladki .pp-kropki, .przestrzen.tryb-zakladki [data-pp-uklad] { display: none; }
/* Z akcji panelu zostaje sama lupa: zwijanie i menu układu dotyczą kolumn,
   których w trybie zakładek nie ma, ale bez lupy telefon traci szukanie
   i filtry (audyt UI, H-10). */
.przestrzen.tryb-zakladki .pp-glowa-akcje > :not(.pp-lupa) { display: none; }
.przestrzen.tryb-zakladki .pp-tresc { overflow: visible; }

/* Podzakładki Analityki przyklejone do góry przewijanej treści. */
.pp-podzakladki { position: sticky; top: -12px; z-index: 2; margin: -12px -12px 0; padding: 12px 12px 10px; background: var(--card); }
.pp-podzakladki .okna { display: flex; width: max-content; max-width: 100%; overflow-x: auto; }
/* Podzakładki w nagłówku panelu, obok nazwy (uwaga z 25 września): bez lepkiego
   paska w treści, przewijalne w poziomie, gdy panel jest wąski. */
.pp-glowa .pp-podzakladki { position: static; flex: 1 1 auto; min-width: 0; margin: 0 0 0 6px; padding: 0; background: none; z-index: auto; }
.pp-glowa .pp-podzakladki .okna { scrollbar-width: none; }
.pp-glowa .pp-podzakladki .okno { padding: 4px 8px; font-size: var(--fs-kontrolka); }
/* Podzakładki Analityki na telefonie: podkreślenie jak zakładki przestrzeni
   rząd wyżej, nie pastylki — po schowaniu paska Kanałów zostają dwa poziomy
   zakładek i oba mają wyglądać jak tekst z kreską, nie jak przełącznik. */
@media (max-width: 768px) {
  .pp-glowa .pp-podzakladki .okna { height: auto; padding: 0; gap: 16px; border-radius: 0; background: none; box-shadow: none; }
  .pp-glowa .pp-podzakladki .okno { height: 24px; padding: 0; border-radius: 0; }
  .pp-glowa .pp-podzakladki .okno.active { background: none; box-shadow: inset 0 -2px 0 var(--foreground); }
}
/* W trybie zakładek nazwa panelu jest już na pasku wyżej — w nagłówku zostają same podzakładki. */
.przestrzen.tryb-zakladki .pp-glowa:has(.pp-podzakladki) .pp-nazwa { display: none; }
.pp-analityka > * + * { margin-top: var(--odstep-sekcji); }
.pp-analityka > .tiles + *, .pp-analityka > * + .tiles { margin-top: var(--odstep-grupy); }

/* Kontekst */
.pp-sekcja { display: flex; flex-direction: column; gap: 6px; }
/* Sekcje Kontekstu oddzielone kreską — firma, dokumenty, strona, konkurenci
   zlewały się w jedną kolumnę faktów (uwaga z 25 września). */
.pp-sekcja + .pp-sekcja { padding-top: 12px; border-top: 1px solid var(--border); }
.pp-chipy { display: flex; flex-wrap: wrap; gap: 6px; }
/* Otwarte incydenty na górze Kontekstu — zamiast panelu „Do zrobienia". */
.pp-incydent { display: flex; align-items: center; gap: 8px; width: 100%; padding: 6px 8px; border: 0; border-radius: 8px; background: var(--bad-bg); color: var(--foreground); font: inherit; font-size: var(--fs-tresc); text-align: left; cursor: pointer; }
.pp-incydent.warn { background: var(--warn-bg); }
.pp-incydent .kropka { flex: none; }
.pp-incydent .row-meta { margin-left: auto; flex: none; }
.pp-firma-nazwa { align-self: flex-start; padding: 0; border: 0; background: none; color: var(--foreground); font: inherit; font-size: var(--fs-tytul-karty); font-weight: 500; text-align: left; cursor: pointer; }
.pp-firma-nazwa:hover { text-decoration: underline; text-underline-offset: 3px; }
.pp-chip { display: inline-flex; align-items: center; max-width: 100%; height: 22px; padding: 0 8px; border: 0; border-radius: 999px; background: var(--accent); color: var(--foreground); font: inherit; font-size: var(--fs-kontrolka); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
button.pp-chip { cursor: pointer; text-decoration: underline; text-underline-offset: 3px; }
.pp-konkurenci { display: grid; grid-template-columns: 1fr 1fr; gap: 6px 10px; }
.pp-konkurent { display: inline-flex; align-items: center; gap: 8px; min-width: 0; font-size: var(--fs-tresc); }
.pp-monogram { flex: none; display: inline-flex; align-items: center; justify-content: center; width: 18px; height: 18px; border-radius: 50%; background: var(--neutral-bg); color: var(--neutral-tekst); font-size: 10px; font-style: normal; font-weight: 600; }
.pp-fakt { display: flex; justify-content: space-between; gap: 10px; font-size: var(--fs-tresc); }
.pp-fakt span:first-child { color: var(--text-secondary); }
.pp-fakt span:last-child { min-width: 0; text-align: right; overflow-wrap: anywhere; font-variant-numeric: tabular-nums; }
.pp-lista { display: flex; flex-direction: column; gap: 4px; margin: 0; padding: 0; list-style: none; font-size: var(--fs-tresc); font-variant-numeric: tabular-nums; }
.pp-lista li { display: flex; justify-content: space-between; gap: 8px; min-width: 0; }
.pp-sekcja .row-act { align-self: flex-start; }
/* Przyciski pod listą stoją obok siebie; odstęp nad nimi daje `gap` sekcji. */
.pp-sekcja > .btn-row { margin-top: 0; gap: 6px; }
/* Kartoteka klienta: strony w Kontekście otwierają się kliknięciem. */
.pp-lista li.clickable { align-items: center; margin: 0 -6px; padding: 4px 6px; border-radius: 6px; cursor: pointer; }
.pp-lista li.clickable:hover { background: var(--accent); }

/* Do zrobienia */
.pp-karta { display: flex; flex-direction: column; gap: 6px; padding: 12px; border-radius: 10px; background: var(--card-2); }
.pp-karta strong { font-size: var(--fs-akcent); font-weight: 500; line-height: 1.35; }
.pp-karta p { margin: 0; }
.pp-karta .btn-row { margin-top: 2px; }
.pp-karta-zrodlo { display: flex; align-items: center; gap: 6px; font-size: var(--fs-etykieta); font-weight: 500; color: var(--text-secondary); }
.pp-karta-zrodlo::before { content: ""; flex: none; width: 7px; height: 7px; border-radius: 50%; background: var(--idle); }
.pp-karta.bad .pp-karta-zrodlo::before { background: var(--bad); }
.pp-karta.warn .pp-karta-zrodlo::before { background: var(--warn); }
/* Strona karty w kartotece klienta — nazwa własna, nie etykieta. */
.pp-karta-strona { color: var(--foreground); text-transform: none; letter-spacing: 0; }
/* Kolejka: wysiłek przy prawej krawędzi nadlinii, „wróciło" jako pigułka,
   dowód (adres, fraza, liczby) mocniej niż rada pod nim. */
.pp-karta-wysilek { margin-left: auto; font-weight: 500; letter-spacing: 0; text-transform: none; }
.pp-znacznik { padding: 1px 6px; border-radius: 999px; background: var(--warn-bg); color: var(--warn-tekst); font-weight: 500; letter-spacing: 0; text-transform: none; }
.pp-karta .pp-dowod { color: var(--foreground); font-size: var(--fs-tresc); overflow-wrap: anywhere; }
.pp-karta .btn-row { flex-wrap: wrap; }

/* Arkusz naprawy: „teraz" nad polem, licznik pod nim. */
.naprawa { display: flex; flex-direction: column; gap: 8px; }
.naprawa-glowa { display: flex; justify-content: space-between; gap: 8px; align-items: baseline; min-width: 0; }
.naprawa-glowa .row-meta { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.naprawa-przed { font-size: var(--fs-tresc); color: var(--text-secondary); overflow-wrap: anywhere; }
.naprawa-po { width: 100%; font: inherit; font-size: var(--fs-tresc); }
.naprawa-stopka { display: flex; justify-content: flex-end; }
.naprawa-licznik { font-size: var(--fs-meta); color: var(--text-secondary); font-variant-numeric: tabular-nums; }
.naprawa-licznik.warn { color: var(--warn-tekst); font-weight: 500; }

/* Udział w odpowiedziach AI: pasek klient vs konkurenci. */
.udzial-pasek { display: flex; gap: 2px; height: 10px; margin-bottom: 8px; border-radius: 999px; overflow: hidden; background: var(--muted); }
.udzial-pasek i { display: block; min-width: 4px; background: var(--idle); }
.udzial-pasek i.nasza { background: var(--brand, var(--ok)); }

/* PageSpeed: dwa urządzenia obok siebie, a w wąskiej Analityce jedno pod drugim. */
/* Blok urządzenia jest kompletny (pierścienie + kafelki), więc dwa stoją obok
   siebie tylko, gdy każdy ma ~330 px; węziej spadają jeden pod drugi w całości.
   min(…, 100%) — na telefonie panel bywa węższy niż 330 px i kolumna nie może
   go rozpychać. Blok jest kontenerem, bo kafle zwężają się według NIEGO,
   nie okna: ten sam panel stoi szeroko albo w wąskiej kolumnie przestrzeni. */
.psi-urzadzenia { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(330px, 100%), 1fr)); gap: 20px 28px; }
.psi-urzadzenie { display: flex; flex-direction: column; gap: 6px; min-width: 0; container: psi-blok / inline-size; }
.psi-kolo { display: flex; flex-direction: column; align-items: center; gap: 4px; }
.psi-kolo > span:last-child { font-size: var(--fs-drobne); color: var(--text-secondary); }

/* Moduły strony i koszty: liczby po prawej w dwóch liniach, suma na górze arkusza. */
.mod-liczby { display: flex; flex-direction: column; align-items: flex-end; gap: 2px; font-size: var(--fs-tresc); text-align: right; font-variant-numeric: tabular-nums; }
.mod-wiersz .row-metrics { align-items: center; gap: 12px; }
.mod-nieaktywny .row-title, .mod-nieaktywny .mod-liczby > span:first-child { color: var(--text-secondary); }
.mod-przelacznik { margin: 0; }
.mod-suma { display: flex; gap: 24px; margin-bottom: 4px; }
.mod-suma > span { display: flex; flex-direction: column; gap: 2px; }
.mod-suma strong { font-size: var(--fs-liczba-s); font-weight: 500; font-variant-numeric: tabular-nums; }

/* Kontekst klienta: lista dokumentów w kolumnie, propozycje konkurentów,
   arkusz dokumentu z różnicą wersji. */
.pp-doki { display: flex; flex-direction: column; }
.pp-dok { display: grid; grid-template-columns: auto 1fr auto; column-gap: 8px; grid-template-rows: auto; align-items: center; padding: 6px 0; border: 0; border-bottom: 1px solid var(--border); background: none; color: var(--foreground); font: inherit; text-align: left; cursor: pointer; }
.pp-dok:last-child { border-bottom: 0; }
.pp-dok:hover .pp-dok-nazwa { text-decoration: underline; text-underline-offset: 3px; }
/* Dokument otwiera się w arkuszu obok, nie rozwija w dół — szewron w prawo. */
.pp-dok .szewron { grid-row: auto; transform: rotate(-90deg); }
.pp-dok .kropka { grid-row: auto; width: 7px; height: 7px; border-radius: 50%; background: var(--idle); }
.pp-dok .kropka.ok { background: var(--ok); }
.pp-dok .kropka.warn { background: var(--warn); }
.pp-dok .kropka.bad { background: var(--bad); }
/* Nazwy dokumentów i sygnałów to etykiety listy, nie treść — mniejsze i szare,
   żeby wzrok szedł do wartości po prawej (uwaga z 6 października). */
.pp-dok-nazwa { font-size: var(--fs-meta); font-weight: 400; color: var(--text-secondary); }
.pp-dok:hover .pp-dok-nazwa { color: var(--foreground); }
.pp-propozycje { display: flex; flex-direction: column; gap: 4px; padding: 8px 0; }
.pp-propozycja { display: flex; align-items: center; gap: 8px; min-width: 0; font-size: var(--fs-tresc); }
.pp-propozycja .ellipsis { flex: 1; min-width: 0; }
.dok-glowa { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; min-height: var(--h-kontrolka); }
/* Arkusz nie ma odstępów między dziećmi — bez tego przyciski nagłówka
   dotykały ramki dokumentu. */
.sheet-body > .dok-glowa ~ :not(.help) { margin-top: 16px; }
.dok-akcje { display: flex; align-items: center; gap: 8px; margin-left: auto; }
.help.bad { color: var(--bad); }
.dok-tresc h3 { margin: 16px 0 6px; font-size: var(--fs-tytul-karty); font-weight: 500; }
.dok-tresc h4 { margin: 16px 0 6px; font-size: var(--fs-tresc); font-weight: 500; color: var(--text-secondary); }
.dok-tresc > :first-child { margin-top: 0; }
.dok-tresc p, .dok-tresc ul { margin: 0 0 8px; }
.dok-tresc ul { padding-left: 18px; }
.dok-edycja { width: 100%; min-height: 360px; font-family: var(--mono); font-size: var(--fs-tresc); line-height: 1.5; }
.dok-propozycja { padding: 0 0 12px; }
.dok-propozycja .btn-row { padding: 0 16px; }
.dok-roznica { max-height: 360px; overflow: auto; margin: 0 16px; border-radius: 8px; background: var(--card-2); font-family: var(--mono); font-size: var(--fs-meta); line-height: 1.55; }
.roz { display: grid; grid-template-columns: 18px 1fr; padding: 0 8px; white-space: pre-wrap; overflow-wrap: anywhere; color: var(--text-secondary); }
.roz.plus { background: var(--ok-bg); color: var(--foreground); }
.roz.minus { background: var(--bad-bg); color: var(--foreground); text-decoration: line-through; text-decoration-color: var(--bad); }

/* Asystent w panelu: rozmowa rośnie, pytania i pole zostają na dole. */
.pp-tresc[data-pp-tresc="asystent"] { display: flex; flex-direction: column; }
.pp-czat { display: flex; flex-direction: column; flex: 1; min-height: 0; gap: 10px; }
.pp-czat-kontekst { display: flex; flex-wrap: wrap; gap: 6px; }
.pp-czat-kontekst:empty { display: none; }
.pp-pigulka { display: inline-flex; align-items: center; gap: 6px; max-width: 100%; height: 24px; padding: 0 8px; overflow: hidden; border: 0; border-radius: 999px; background: var(--accent); color: var(--foreground); font: inherit; font-size: var(--fs-meta); white-space: nowrap; text-overflow: ellipsis; cursor: pointer; }
.pp-pigulka span { color: var(--text-secondary); }
.pp-pigulka.karta { background: var(--brand-soft); color: var(--brand-tekst); }
.pp-pigulka.wylaczona { background: transparent; box-shadow: inset 0 0 0 1px var(--border); color: var(--text-secondary); }
.pp-czat-log { flex: 1; min-height: 120px; padding: 4px 0; }
/* Pusta rozmowa: bez listy, gotowe pytania stają na środku panelu. */
.pp-czat:not(.ma-rozmowe) .czat-log-rama { flex: 0 0 auto; }
.pp-czat:not(.ma-rozmowe) .pp-czat-log { min-height: 0; padding: 0; }
.pp-czat:not(.ma-rozmowe) .pp-czat-pytania { margin-block: auto; }
.pytania.pp-czat-pytania { max-width: none; margin: 0; padding: 0; }
.pytania.pp-czat-pytania .pytania-lista { margin-top: 0; }
.pp-czat.ma-rozmowe .pp-czat-pytania { display: none; }
.pp-czat .czat { margin: 0; }

/* Audyt SEO w panelu: pierścień oceny, trzy liczby, sygnał | stan w jednej linii. */
.seo-glowa { display: flex; align-items: center; gap: 14px; padding: 12px 14px; border-bottom: 1px solid var(--border); }
.seo-glowa-tekst { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.seo-liczby { display: flex; flex-wrap: wrap; gap: 14px; font-size: var(--fs-meta); color: var(--text-secondary); }
.seo-liczba b { margin-right: 4px; font-size: var(--fs-tytul); font-weight: 500; color: var(--foreground); font-variant-numeric: tabular-nums; }
.seo-liczba.bad b { color: var(--bad); }
.seo-liczba.warn b { color: var(--warn-tekst); } /* 18 px — poniżej progu „dużych liczb", więc bursztyn tekstowy */
.seo-liczba.ok b { color: var(--ok-tekst); }
.seo-analiza .wykres-pierscien-tekst b { font-size: var(--fs-tytul); letter-spacing: 0; }
.sygnal { display: flex; align-items: flex-start; gap: 10px; padding: 10px 14px; border-bottom: 1px solid var(--border); }
.sygnal .kropka { flex: none; margin-top: 6px; }
.sygnal .kropka:not(.bad):not(.warn):not(.ok) { background: var(--idle); }
.sygnal .kropka.ok { background: var(--ok); box-shadow: 0 0 0 4px var(--ok-bg); }
.sygnal-tresc { display: flex; flex: 1; flex-direction: column; gap: 2px; min-width: 0; }
.sygnal-nazwa { font-size: var(--fs-meta); font-weight: 400; color: var(--text-secondary); }
/* Nazwy w listach wierszy bez wyróżnienia (6 października: „po co to tak
   wyróżniać") — kolor i miejsce w wierszu wystarczą; 500 zostaje tytułom. */
.sygnal-nazwa strong { font-weight: 400; }
.sygnal-stan { flex: none; font-size: var(--fs-meta); color: var(--text-secondary); font-variant-numeric: tabular-nums; }
/* Kafelki Web Vitals: skrót + wartość + słowo stanu, pełna nazwa w dymku. */
.cwv-kafel { display: flex; flex-direction: column; gap: 2px; min-width: 0; padding: 8px 8px; border-radius: 8px; background: var(--card-2); }
/* Skrót cichszy od wartości (waga 500, nie 600) — przy 600 LCP/FCP krzyczały
   głośniej niż liczba; rozmiaru nie zmniejszamy, 11 px to dolna granica. */
.cwv-skrot { display: inline-flex; align-items: center; gap: 4px; font-size: var(--fs-etykieta); font-weight: 500; letter-spacing: .04em; text-transform: uppercase; color: var(--text-secondary); }
.cwv-skrot .kropka { width: 6px; height: 6px; background: var(--idle); }
.cwv-skrot .kropka.ok { background: var(--ok); }
.cwv-skrot .kropka.warn { background: var(--warn); }
.cwv-skrot .kropka.bad { background: var(--bad); }
.cwv-wartosc { font-size: var(--fs-tresc); font-weight: 500; font-variant-numeric: tabular-nums; line-height: 1.2; }
.cwv-kafel.warn .cwv-wartosc { color: var(--warn-tekst); }
.cwv-kafel.bad .cwv-wartosc { color: var(--bad-tekst); }
/* Słowo stanu niesie informację — nie schodzi pod 11 px. Długie słowa
   (de „verbesserungswürdig") dzielą się z łącznikiem zamiast wychodzić
   poza kafel na telefonie. */
.cwv-slowo { font-size: var(--fs-drobne); color: var(--text-secondary); hyphens: auto; overflow-wrap: anywhere; }
/* Pierścienie w tej samej siatce 4 kolumn co kafle pod nimi — rosną razem
   z panelem, a każdy stoi nad środkiem swojego kafla (uwaga z 6 października). */
.psi-kola { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; margin-bottom: 6px; }
.psi-kolo > span:last-child { max-width: 100%; text-align: center; overflow-wrap: anywhere; }
@container psi-blok (max-width: 400px) { .psi-kola { gap: 4px; } }
.psi-kolo > span { font-size: var(--fs-drobne); }
/* Liczby w pierścieniach PageSpeed i audytu — mniejsze, na miarę 44 px;
   w PageSpeed 13 px, bo „100" w 14 px dotykało obręczy. */
.seo-analiza .wykres-pierscien-tekst b { font-size: var(--fs-akcent); letter-spacing: 0; }
.psi .wykres-pierscien-tekst b { font-size: var(--fs-tresc); }
/* Nagłówek PageSpeed stoi wprost w panelu (M-09), treść w panel-pad pod nim —
   bez drugiego wcięcia nagłówka, a z tym samym oddechem co wcześniej. */
.psi > .panel-head + .panel-pad { padding-top: 6px; }
/* Kafelki Web Vitals: stałe cztery kolumny (PageSpeed: LCP·FCP·TBT·CLS,
   czujka: LCP·INP·CLS·TTFB). minmax(0, …), bo 1fr = minmax(auto, 1fr)
   i najdłuższa wartość rozpychałaby kolumnę poza panel. */
.cwv-rzad { display: grid; gap: 6px; }
.cwv-rzad.cztery { grid-template-columns: repeat(4, minmax(0, 1fr)); }
/* Na telefonie cztery kafle muszą się zmieścić w ~320 px bez ucinania:
   mniej wcięcia i odstępów, wartość zostaje 13 px, słowo stanu 11 px. */
@container psi-blok (max-width: 400px) {
  .cwv-rzad { gap: 4px; }
  .cwv-kafel { padding: 6px; }
  .cwv-skrot { gap: 4px; }
}
.seo-analiza .seo-liczba b { font-size: var(--fs-akcent); }
/* Nagłówek bloku w audycie: „Sygnały" (statystyki) i „Problemy" (co nie przeszło). */
.seo-blok-head { display: flex; justify-content: space-between; align-items: center; padding: 10px 14px 6px; border-bottom: 1px solid var(--border); background: var(--card-2); }
.seo-blok-head + .seo-blok-head { border-top: 1px solid var(--border); }
.sygnal.problem { padding: 8px 14px; }
.sygnal.problem .row-meta.ellipsis { display: block; max-width: 100%; }
/* Wiersz „nazwa · stan" bez opisu: niższy, kropka w linii z tekstem. */
.sygnal.zwarty { align-items: center; padding: 8px 14px; }
.sygnal.zwarty .kropka { margin-top: 0; }
.sygnal-nazwa .kropka { display: inline-block; width: 7px; height: 7px; margin-right: 4px; border-radius: 50%; vertical-align: middle; background: var(--idle); }
.sygnal-nazwa .kropka.warn { background: var(--warn); }
.sygnal-nazwa .kropka.bad { background: var(--bad); }
.sygnal-stan.warn { color: var(--warn-tekst); }
.sygnal-stan.bad { color: var(--bad-tekst); }
.sygnal .pill { flex: none; }

/* Stany Analityki: licznik nad listą, grupa zwijana, sekcja pod listą, kolumny tabeli. */
.stan-licznik { padding: 10px 14px; border-bottom: 1px solid var(--border); }
details.stan-grupa > summary { list-style: none; cursor: pointer; }
details.stan-grupa > summary::-webkit-details-marker, details.stan-wiersz > summary::-webkit-details-marker { display: none; }
details.stan-grupa[open] > summary .szewron, details.stan-wiersz[open] > summary .szewron { transform: rotate(180deg); }
details.stan-wiersz > summary { list-style: none; cursor: pointer; }
.stan-wiersz-tresc { display: flex; flex-direction: column; gap: 4px; padding: 0 14px 10px; }
.stan-sekcja > summary .row { flex-wrap: nowrap; min-height: 0; padding: 8px 10px 8px 14px; }
.stan-sekcja > summary .row-stack { flex: 1 1 auto; width: auto; min-width: 0; }
.stan-sekcja .row-metrics { flex: none; flex-wrap: nowrap; gap: 8px; width: auto; }
details.zwijany.stan-sekcja[open] > summary .row { margin-bottom: 0; }
.stan-sekcja-nazwa { display: flex; align-items: center; gap: 10px; width: 100%; color: var(--foreground); font-size: var(--fs-tresc); }
.stan-sekcja-nazwa .kropka { flex: none; }
.stan-sekcja-tresc { padding: 12px; }
.stan-sekcja-tresc > * + * { margin-top: 12px; }
.stan-sekcja-tresc > .sygnal:last-child { border-bottom: 0; }
.pole-z-przyciskiem { display: flex; gap: 8px; align-items: center; }
.pole-z-przyciskiem input { flex: 1; min-width: 0; }

/* Kolumny tabeli: nagłówek ma ten sam odstęp co wiersz, inaczej liczby rozjeżdżają się z etykietami. */
.kole { display: inline-flex; gap: 10px; margin-left: auto; }
.seo-blok-head .kol-akcja { margin-left: 10px; }
.kol { display: inline-flex; flex: none; justify-content: flex-end; gap: 4px; width: 62px; text-align: right; }
.tabela-kol .sygnal { min-height: 36px; }
.kol.szeroka { width: 78px; }
.kol-akcja { flex: none; width: 26px; }
.tabela-kol { container-type: inline-size; }
@container (max-width: 460px) {
  .tabela-kol .kol.trzecia { display: none; }
  .kol { width: 56px; }
  .kol.szeroka { width: 68px; }
}
.seo-analiza .help { margin: 0; padding: 8px 14px 12px; }

/* Panel platformy (S4): konto operatora nie ma agencji, więc nie ma szyny,
   wyszukiwarki ani ustawień agencji — zostaje menu konta w nagłówku. */
body.tryb-platformy #sidebarNav,
body.tryb-platformy #btnSettings,
body.tryb-platformy #btnSearch { display: none; }

/* Autor wpisu czasu — w zespole najważniejsza rzecz w wierszu po godzinach. */
.wpis-osoba { color: var(--foreground); font-weight: 500; }

/* Użycie i limity agentów MCP (widoki/agenci.js) */
.mcp-staty { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 16px; margin-top: 14px; }
.mcp-stat { display: flex; flex-direction: column; gap: 2px; }
.mcp-stat-etykieta { font-size: var(--fs-meta); color: var(--text-secondary); }
.mcp-stat-wartosc { font-size: var(--fs-liczba-m); font-weight: 500; letter-spacing: -.01em; }
.mcp-limity { border-top: 1px solid var(--border); }
.mcp-limity .row { padding-left: 16px; padding-right: 16px; }

/* Wybór pliku (wspolne.js `polePliku`). W rzędzie przycisków: pigułka jak
   `row-act` i nazwa obok. Jako pole formularza (`.field > .plik-pole`): obrys
   i wysokość zwykłego pola, więc stoi równo z listą albo polem obok. */
.plik-pole { position: relative; display: inline-flex; align-items: center; gap: 10px; min-width: 0; max-width: 100%; cursor: pointer; }
.plik-pole .plik-wejscie, .field .plik-wejscie, .chip-plik .plik-wejscie {
  position: absolute; width: 1px; height: 1px; padding: 0; border: 0; opacity: 0; pointer-events: none;
}
.plik-przycisk {
  display: inline-flex; align-items: center; flex: none; height: 26px; padding: 0 10px;
  border-radius: var(--r-pill); background: var(--card); box-shadow: var(--faza);
  color: var(--foreground); font-size: var(--fs-kontrolka); font-weight: 500; white-space: nowrap;
  transition: box-shadow var(--t) var(--ease);
}
.plik-pole:hover .plik-przycisk { box-shadow: var(--faza-hover); }
.plik-pole:has(.plik-wejscie:focus-visible) .plik-przycisk { outline: 2px solid var(--fokus); outline-offset: 2px; }
.plik-nazwa { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--fs-meta); color: var(--text-secondary); }
.plik-nazwa.wybrany { color: var(--foreground); }
.field > .plik-pole {
  display: flex; width: 100%; height: var(--h-kontrolka); padding: 0 10px 0 4px;
  border: 1px solid var(--input); border-radius: var(--r-s); background: var(--card);
  transition: border-color var(--t) var(--ease), box-shadow var(--t) var(--ease);
}
.field > .plik-pole:has(.plik-wejscie:focus-visible) { border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-soft); }
.field > .plik-pole:has(.plik-wejscie:focus-visible) .plik-przycisk { outline: none; }
.field > .plik-pole .plik-nazwa { font-size: var(--fs-tresc); }

/* Kwoty pod paskiem budżetu w panelu Czas projektu. */
.proj-kwoty { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 18px; margin-top: 12px; font-size: var(--fs-tresc); }
.proj-kwoty .liczba { font-weight: 500; color: var(--foreground); }
.proj-kwoty > .row-meta:last-child { margin-left: auto; }

/* Pole wyciągu (Transakcje): wklejka i wybór pliku w jednym obrysie pola
   formularza; pasek z plikiem na dole jak w polu rozmowy. */
.wyciag-pole {
  display: flex; flex-direction: column; margin-top: 10px;
  border: 1px solid var(--input); border-radius: var(--r-s); background: var(--card);
  transition: border-color var(--t) var(--ease), box-shadow var(--t) var(--ease);
}
.wyciag-pole:focus-within { border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-soft); }
.wyciag-pole.nad { border-color: var(--brand); border-style: dashed; background: var(--brand-soft); }
.wyciag-pole textarea {
  width: 100%; min-height: 96px; padding: 10px 12px; border: 0; background: transparent; resize: vertical;
  color: var(--foreground); font: inherit; font-size: var(--fs-tresc); line-height: 1.5; outline: none;
}
.wyciag-pole textarea:not(:placeholder-shown) { font-family: var(--mono, ui-monospace, monospace); font-size: var(--fs-meta); }
.wyciag-pole textarea::placeholder { color: var(--text-secondary); }
.wyciag-pasek { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 6px 12px; padding: 8px 10px; border-top: 1px solid var(--border); }
.wyciag-pasek .row-meta { font-size: var(--fs-meta); }

/* ── Kartoteka klienta (widoki/klient.js) ──────────────────────────────── */
/* Pas liczb nad panelami Pracy. */
.kk-pas { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 1px; margin-bottom: 12px;
  border-radius: var(--r); overflow: hidden; background: var(--border); box-shadow: var(--cien-ramka); }
.kk-pole { display: flex; flex-direction: column; gap: 4px; min-width: 0; padding: 14px 16px; background: var(--card); }
.kk-pole-etykieta { font-size: var(--fs-meta); color: var(--text-secondary); }
.kk-pole-wartosc { font-size: var(--fs-liczba-m); font-weight: 500; letter-spacing: -.01em; color: var(--foreground); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kk-pole-pod { font-size: var(--fs-meta); color: var(--text-secondary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Na telefonie podpis karty i podtytuł zakładki łamią się zamiast ucinać:
   wielokropek chował treść bez żadnej drogi do niej (dotyk nie ma title,
   audyt UI, L-22 d). Stoi tu, a nie w bloku mobile wyżej, bo musi przyjść
   po regule `.kk-pole-pod`. */
@media (max-width: 768px) {
  .kk-pole-pod { white-space: normal; overflow: visible; }
}
.kk-pole.warn .kk-pole-wartosc { color: var(--warn-tekst); }
.kk-pole.bad .kk-pole-wartosc { color: var(--bad); }
/* Wdrożenie: nagłówek z paskiem, trzy kroki, reszta za „+N więcej". */
.kk-wdrozenie { margin-bottom: 12px; }
.kk-wdrozenie-glowa { display: flex; flex-direction: column; gap: 8px; border-bottom: 1px solid var(--border); }
.kk-wdrozenie-opis { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; }
.kk-wdrozenie-opis .liczba { font-weight: 500; color: var(--foreground); }
.kk-wiecej { padding: 8px 16px 10px; border-top: 1px solid var(--border); }
/* Kolejne panele Przeglądu i Pieniędzy — równy odstęp z kontenera. */
.pp-praca > .panel + .panel, .pp-praca > .panel + .kk-dodaj, .kk-dwie + .kk-dodaj { margin-top: 12px; }
/* Pasek faktów pod nazwą klienta — zamiast sekcji „Klient" i „Dla klienta"
   lewego Kontekstu, którego kartoteka nie ma od 13 listopada 2026. */
.kk-fakty { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 24px; margin-top: 8px; padding: 10px 16px; font-size: var(--fs-tresc); color: var(--text-secondary); }
.kk-fakt b { color: var(--foreground); font-weight: 500; font-variant-numeric: tabular-nums; }
.kk-fakt b.tone-bad { color: var(--bad); }
.kk-fakt b.tone-warn { color: var(--warn-tekst); }
.kk-fakty-linki { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 4px 12px; margin-left: auto; }
/* Przegląd w dwóch kolumnach; gdy panel Pracy jest wąski (rozwinięty
   asystent, telefon), kolumny stają jedna pod drugą. */
.pp-praca { container-type: inline-size; }
.pp-praca > .stack-mt:first-child { margin-top: 0; }
.kk-dwie { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: stretch; }
.kk-kol { display: flex; flex-direction: column; gap: 12px; min-width: 0; }
.kk-kol:first-child { padding-right: 12px; }
.kk-kol + .kk-kol { padding-left: 12px; border-left: 1px solid var(--border); }
/* Panele w kolumnie jak wszędzie w przestrzeni: bez ramy, z kreską między. */
.kk-kol > .panel { margin-top: 0; box-shadow: none; border-radius: 0; }
.kk-kol > .panel + .panel { border-top: 1px solid var(--border); }
@container (max-width: 760px) {
  .kk-dwie { grid-template-columns: minmax(0, 1fr); }
  .kk-kol:first-child { padding-right: 0; }
  .kk-kol + .kk-kol { margin-top: 12px; padding-left: 0; border-left: 0; border-top: 1px solid var(--border); }
}
/* Sekcja pisana dla wąskiej kolumny (ankieta, sejf) w szerokiej zakładce:
   przycisk zostaje przyciskiem, nie pasem na całą szerokość. */
.kk-sekcja .pp-sekcja > .btn { align-self: flex-start; }
.kk-incydenty { display: flex; flex-direction: column; gap: 6px; padding-top: 0; }
.kk-notatki { margin: 0; padding: 0 16px 14px; font-size: var(--fs-tresc); line-height: 1.5; white-space: pre-wrap; overflow-wrap: anywhere; }
/* Rząd „dodaj" zamiast pustych paneli. */
.kk-dodaj { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding: 12px 16px; border: 1px dashed var(--border-strong); border-radius: var(--r); }
.kk-dodaj > .row-meta { margin-right: 4px; }
/* Podpowiedź pod listą rozliczeń — pełnym zdaniem, nie drobnym drukiem z prawej. */
.kk-podpowiedz { padding: 10px 16px 12px; border-top: 1px solid var(--border); font-size: var(--fs-tresc); color: var(--text-secondary); }
.kk-podpowiedz strong { color: var(--foreground); }
/* Kontekst: akcja przy etykiecie sekcji, linki w jednej linii, szukajka dokumentów. */
.pp-etykieta-akcja { display: flex; justify-content: space-between; align-items: center; gap: 8px; }
.pp-etykieta-akcja .row-act { text-transform: none; letter-spacing: 0; font-weight: 500; }
.kk-linki { display: flex; flex-wrap: wrap; gap: 4px 16px; font-size: var(--fs-tresc); }
.kk-szukaj { margin-left: auto; flex: 1; max-width: 240px; }
.kk-szukaj input { width: 100%; height: 28px; padding: 0 10px; border: 1px solid var(--input); border-radius: var(--r-pill); background: var(--card); color: var(--foreground); font: inherit; font-size: var(--fs-tresc); }
.pp-tytul .pp-uslugi { margin-left: 0; }

/* ── Filtr kolumny listy klientów (dialogi.js `wyborKolumny`) ──────────── */
/* Monochromatycznie, jak reszta menu: zaznaczenie to wypełniony kwadrat
   w kolorze tekstu, liczby szare — bez koloru marki. */
.kol-filtr { min-width: 220px; max-height: min(420px, 70vh); overflow-y: auto; }
.menu .kol-opcja, .menu .kol-sort { flex-direction: row; align-items: center; gap: 10px; }
.kol-sort-ikona { width: 14px; flex: none; text-align: center; color: var(--text-secondary); }
.kol-ptaszek { flex: none; width: 14px; height: 14px; border-radius: 4px; box-shadow: inset 0 0 0 1.5px var(--border-strong); }
.kol-opcja[aria-checked="true"] .kol-ptaszek { background: var(--foreground) center / 12px no-repeat; box-shadow: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M4 8.2l2.6 2.6L12 5.4' fill='none' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); }
/* Motyw panelu to klasa html.dark — nie atrybut i nie ustawienie systemu,
   bo przy różnicy panelu i systemu ptaszek znikał (biały na białym). */
html.dark .kol-opcja[aria-checked="true"] .kol-ptaszek { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M4 8.2l2.6 2.6L12 5.4' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); }
.kol-opcja .menu-etykieta { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kol-ile { flex: none; font-size: var(--fs-meta); color: var(--text-secondary); font-variant-numeric: tabular-nums; }
.menu .kol-wyczysc { color: var(--text-secondary); }
/* Nagłówek z aktywnym filtrem: ciemniejszy tekst i liczba zaznaczonych w nawiasie-kropce. */
.kol-naglowek.filtruje { color: var(--foreground); }
.kol-licznik { margin-left: 4px; color: var(--text-secondary); font-variant-numeric: tabular-nums; }
.kol-licznik::before { content: "· "; }
/* Aktywne filtry nad tabelą: spokojne chipy z obrysem. */
.kol-chipy { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-bottom: 10px; }
.kol-chip { display: inline-flex; align-items: center; gap: 4px; height: 26px; padding: 0 4px 0 10px; border: 1px solid var(--border); border-radius: var(--r-pill); background: var(--card); color: var(--foreground); font: inherit; font-size: var(--fs-meta); cursor: pointer; }
.kol-chip:hover { border-color: var(--border-strong); }
.kol-chip-pole { color: var(--text-secondary); }
.kol-chip-x { display: inline-grid; place-items: center; width: 18px; height: 18px; border-radius: 50%; color: var(--text-secondary); }
.kol-chip:hover .kol-chip-x { background: var(--hover-bg); color: var(--foreground); }
.kol-chipy .row-meta { margin-left: 4px; }
.kol-chipy .link-btn { font-size: var(--fs-kontrolka); color: var(--text-secondary); }

/* ── Usługi agencji (server/uslugi.js) ───────────────────────────────────
   Chip = skrót usługi w kolorze kategorii. Pełna ramka: usługa w umowie;
   przerywana, bez tła: wykryta z danych (do potwierdzenia albo ukrycia). */
.us-chip { display: inline-flex; align-items: center; justify-content: center; min-width: 34px; height: 22px; padding: 0 8px; border-radius: 6px; border: 1px solid var(--tag-border, var(--border-strong)); background: var(--tag-bg, var(--card)); color: var(--tag-tekst, var(--foreground)); font: inherit; font-size: var(--fs-drobne); font-weight: 500; letter-spacing: .05em; line-height: 1; white-space: nowrap; }
button.us-chip { cursor: pointer; }
button.us-chip:hover { filter: brightness(.97); }
html.dark button.us-chip:hover { filter: brightness(1.15); }
.us-chip.auto { background: transparent; border-style: dashed; border-color: color-mix(in srgb, var(--tag-tekst, var(--text-secondary)) 55%, transparent); }
.firma-uslugi { gap: 4px; }
.us-edytuj { height: 22px; padding: 0 8px; border: 1px dashed var(--border-strong); border-radius: 6px; background: none; color: var(--text-secondary); font: inherit; font-size: var(--fs-meta); cursor: pointer; }
.us-edytuj:hover { color: var(--foreground); border-color: var(--text-secondary); }
.us-kolor-niebieski { --tag-bg: #E6EEFC; --tag-border: #C7D7F7; --tag-tekst: #1E4FCB; }
.us-kolor-fiolet { --tag-bg: #F0E9FB; --tag-border: #DCCFF5; --tag-tekst: #6D3BC7; }
.us-kolor-morski { --tag-bg: #DDF3F0; --tag-border: #B9E4DE; --tag-tekst: #0E6E66; }
.us-kolor-roz { --tag-bg: #FCE6F1; --tag-border: #F5C6DD; --tag-tekst: #B0246F; }
.us-kolor-indygo { --tag-bg: #E8E8FB; --tag-border: #CFCFF5; --tag-tekst: #3B3FB0; }
.us-kolor-miedz { --tag-bg: #F8EBE3; --tag-border: #EDD3C3; --tag-tekst: #9A4A1C; }
.us-kolor-oliwka { --tag-bg: #EEF0DF; --tag-border: #DADFBF; --tag-tekst: #5B6414; }
.us-kolor-stalowy { --tag-bg: #E9ECF1; --tag-border: #D5DAE2; --tag-tekst: #3F4A5A; }
html.dark .us-kolor-niebieski { --tag-bg: #1D2B3E; --tag-border: #2C4260; --tag-tekst: #BFDBFE; }
html.dark .us-kolor-fiolet { --tag-bg: #261F3F; --tag-border: #3A3060; --tag-tekst: #C9BDF5; }
html.dark .us-kolor-morski { --tag-bg: #0F2E2B; --tag-border: #1B4741; --tag-tekst: #9EE8DC; }
html.dark .us-kolor-roz { --tag-bg: #3A1A2B; --tag-border: #55263F; --tag-tekst: #F9BFDB; }
html.dark .us-kolor-indygo { --tag-bg: #22233F; --tag-border: #34365E; --tag-tekst: #C3C5FA; }
html.dark .us-kolor-miedz { --tag-bg: #36241A; --tag-border: #523626; --tag-tekst: #F4C9A8; }
html.dark .us-kolor-oliwka { --tag-bg: #2A2D17; --tag-border: #3F4422; --tag-tekst: #DDE3A6; }
html.dark .us-kolor-stalowy { --tag-bg: #262B33; --tag-border: #363D48; --tag-tekst: #CBD3DE; }
/* Katalog w Ustawieniach: skrót (w kolorze), nazwa, rozliczenie, usuń;
   opis wykrywania w drugiej linii pod nazwą — arkusz jest wąski. */
.us-katalog .us-wiersz { display: grid; grid-template-columns: 78px minmax(0, 1fr) 124px 28px; gap: 6px 10px; align-items: center; padding: 10px 14px; border-top: 1px solid var(--border); font-size: var(--fs-tresc); }
.us-katalog .us-wiersz.glowa { padding-top: 8px; padding-bottom: 8px; font-size: var(--fs-etykieta); color: var(--text-secondary); }
.us-katalog .us-wiersz .row-meta { grid-column: 2 / 4; font-size: var(--fs-meta); }
.us-katalog .us-wiersz .ust-pole { width: 100%; }
.us-skrot-pole { display: flex; align-items: center; gap: 6px; }
.us-katalog .us-wiersz input.us-skrot { width: 48px; flex: none; height: 26px; padding: 0 4px; border: 1px solid var(--tag-border); background: var(--tag-bg); color: var(--tag-tekst); text-align: center; text-transform: uppercase; font-size: var(--fs-etykieta); font-weight: 500; letter-spacing: .05em; }
/* Telefon: pola mają tam 16 px (iOS nie przybliża), a w tym rozmiarze
   trzy wersaliki nie mieszczą się w 48 px, a nazwa i sposób rozliczania
   w jednym rzędzie — skrót dostaje szerszą komórkę, wybór schodzi pod nazwę. */
@media (max-width: 768px) {
  .us-katalog .us-wiersz { grid-template-columns: 96px minmax(0, 1fr) 28px; }
  .us-katalog .us-wiersz input.us-skrot { width: 66px; }
  .us-katalog .us-wiersz > select { grid-column: 2; grid-row: 2; }
  .us-katalog .us-wiersz.glowa > :nth-child(3) { display: none; }
}
.us-kolor-btn { flex: none; width: 16px; height: 16px; padding: 0; border: 2px solid var(--card); border-radius: 50%; background: var(--tag-tekst); box-shadow: 0 0 0 1px var(--border-strong); cursor: pointer; }
.us-usun { width: 28px; height: 28px; border: 0; border-radius: var(--r-xs); background: none; color: var(--text-secondary); font-size: 16px; cursor: pointer; }
.us-usun:hover { background: var(--hover-bg); color: var(--foreground); }
.us-katalog .us-wiersz.ukryta input, .us-katalog .us-wiersz.ukryta select { opacity: .45; }
/* Cennik usług w formularzu firmy: zaznacz, chip, nazwa, cena z jednostką. */
.us-cennik { display: flex; flex-direction: column; }
.us-cena-wiersz { display: grid; grid-template-columns: 18px 44px minmax(0, 1fr) auto auto; gap: 10px; align-items: center; padding: 8px 12px; border-top: 1px solid var(--border); font-size: var(--fs-tresc); cursor: pointer; }
.us-cena-wiersz:first-child { border-top: 0; }
.us-cena-wiersz .ust-pole input { width: 96px; }
.us-cena-wiersz .us-ilosc input { width: 56px; }
.us-cena-wiersz:has(input[type=checkbox]:not(:checked)) .us-chip { opacity: .45; }

/* Licznik realizacji w chipie („ART 2/4"). */
.us-licznik { margin-left: 4px; font-weight: 500; letter-spacing: 0; opacity: .8; font-variant-numeric: tabular-nums; }
/* Pomarańcz #D97706 (`--warn-duze`; w ciemnym #FBBF24) — wybór właściciela
   mimo kontrastu ~2,7:1 na tincie chipu. Świadomie poniżej 4,5:1, nie zgłaszać w audytach (docs/DECISIONS.md,
   2026-10-01). */
.us-licznik.zalega { color: var(--warn-duze); opacity: 1; font-weight: 500; }
.us-chip:has(.us-licznik) { min-width: 0; }
/* Panel „Realizacja w tym miesiącu" w kartotece. */
.real-panel .real-wiersz { display: grid; grid-template-columns: 44px minmax(0, 1fr) minmax(80px, 180px) 64px auto; gap: 12px; align-items: center; padding: 10px 16px; border-top: 1px solid var(--border); font-size: var(--fs-tresc); }
.real-pasek.pelny i { background: var(--ok); }
.real-pasek.zalega i { background: var(--warn); }
.real-liczba { text-align: right; font-variant-numeric: tabular-nums; font-weight: 500; }
.real-liczba.zalega { color: var(--warn-tekst, var(--warn)); }
.real-przyciski { display: inline-flex; gap: 2px; }
/* ≤768 wiersz się łamie (§4): przy pięciu kolumnach opis dostawał jedno
   słowo w linii, a pasek nachodził na „+1". Nazwa i opis idą obok chipu na
   całą szerokość, pasek z liczbą i przyciskami — rząd niżej. To samo
   w cenniku formularza firmy: pola ceny schodzą pod nazwę, inaczej nazwa
   dostawała 0 px, a jednostka wypadała poza arkusz. */
@media (max-width: 768px) {
  .real-panel .real-wiersz { grid-template-columns: 44px minmax(0, 1fr) auto auto; row-gap: 8px; }
  .real-panel .real-wiersz > .row-stack { grid-column: 2 / -1; }
  .real-panel .real-pasek { grid-column: 1 / 3; }
  .us-cena-wiersz { grid-template-columns: 18px 44px minmax(0, 1fr) auto; row-gap: 8px; }
  .us-cena-wiersz > .ellipsis { grid-column: 3 / -1; }
  .us-cena-wiersz .us-ilosc { grid-column: 2 / 4; justify-self: start; }
  .us-cena-wiersz .ust-pole:not(.us-ilosc) input { width: 80px; }
}

/* L-20: przyciski spoza kanonu dostają te same stany co pastylki —
   przejście na nazwanych właściwościach i wciśnięcie .96. Próbki koloru
   (.us-kolor-btn) celowo poza grupą. */
button.us-chip, .kol-chip, .us-edytuj, .opiekun-chip, .us-usun, .stoper-wiersz {
  transition: background-color var(--t) var(--ease), border-color var(--t) var(--ease), color var(--t) var(--ease), box-shadow var(--t) var(--ease), filter var(--t) var(--ease), scale var(--t) var(--ease);
}
button.us-chip:active, .kol-chip:active, .us-edytuj:active, .opiekun-chip:active, .us-usun:active, .stoper-wiersz:active { scale: .96; }

/* Ograniczony ruch: znikają przesunięcia i skale, zostają przejścia
   koloru i przezroczystości, bo te pomagają zrozumieć, co się stało.
   Blok MUSI stać na końcu arkusza: reguły bazowe mają tę samą
   specyficzność, więc postawiony wcześniej przegrywał kaskadę i nie
   zdejmował niczego. Toast zostaje wyśrodkowany przesunięciem -50% —
   zdejmujemy mu tylko ruch w pionie, nie centrowanie. */
@media (prefers-reduced-motion: reduce) {
  .sheet-panel, .konto-menu, .menu, .dialog, .hover-karta { transition-property: opacity; transform: none; scale: 1; translate: none; }
  .toast { transition-property: opacity; }
  .sheet.zamyka .sheet-panel { transform: none; }
  .toast.znika { transform: translate(-50%, 0); }
  .dialog:not([open]) { scale: 1; }
  @starting-style {
    .sheet-panel { transform: none; }
    .toast { transform: translate(-50%, 0); }
    .konto-menu, .menu:popover-open, .dialog[open] { scale: 1; }
    .hover-karta:popover-open { translate: none; }
  }
  .ikona-para svg { transition-property: opacity; scale: 1; filter: none; }
  .sidebar, .shell, #btnSzyna svg, .marka-stan { transition: none; }
  .btn:active, .chip:active, .row-act:active, .awatar:active, .szablon:active,
  .dzis-pokaz:active, .czat-ikona:active, .czat-wyslij:active,
  .pp-przycisk:active, .pp-przelacznik:active,
  button.us-chip:active, .kol-chip:active, .us-edytuj:active, .opiekun-chip:active, .us-usun:active, .stoper-wiersz:active { scale: 1; }
  .czat-ikona.nagrywa svg { animation: none; }
}

/* Palec zamiast kursora (audyt UI, L-22 c): drobne przyciski — „Przesuń ▾"
   i „···" w Leadach, strzałki Kalendarza, ikony nagłówków paneli, chipy —
   dostają większy obszar trafienia przez niewidoczne `::after`, bez zmiany
   wyglądu. Poziomo tylko 3 px, żeby sąsiad w parze z odstępem 6 px nie
   tracił swojego kliknięcia. */
@media (pointer: coarse) {
  .row-act, .pp-przycisk, .kol-chip, button.us-chip { position: relative; }
  .row-act::after, .pp-przycisk::after, .kol-chip::after, button.us-chip::after {
    content: '';
    position: absolute;
    inset: -8px -3px;
  }
}

/* ── czat: karty rozmów, „Najnowsze", ikony pod odpowiedzią, pływająca ikona ──
   Wspólne dla Pulpitu, panelu Asystent i arkusza (widoki/czas.js). */
.czat-pasek { display: flex; align-items: center; gap: 8px; flex: none; min-width: 0; border-bottom: 1px solid var(--border); }
.czat-pasek:empty { display: none; }
.chat > .czat-pasek { padding: 0 12px 0 8px; }
.pytania > .czat-pasek { margin-bottom: 10px; }
.czat-karty { display: flex; align-self: stretch; gap: 2px; flex: 1; min-width: 0; overflow-x: auto; scrollbar-width: none; }
.czat-karty::-webkit-scrollbar { display: none; }
.czat-karta { display: inline-flex; align-items: center; flex: 0 1 auto; min-width: 30px; max-width: 180px; margin-bottom: -1px; border-bottom: 2px solid transparent; color: var(--text-secondary); transition: color var(--t-szybko) var(--ease); }
.czat-karta:hover { color: var(--foreground); }
/* W wąskim panelu aktywna karta zostaje czytelna, reszta ustępuje do ikony. */
.czat-karta.aktywna { flex-shrink: 0.2; min-width: min(104px, 70%); border-bottom-color: var(--foreground); color: var(--foreground); }
.czat-karta > [role="tab"] { display: inline-flex; align-items: center; gap: 6px; min-width: 0; height: 32px; padding: 0 2px 0 6px; border: 0; background: none; color: inherit; font: inherit; font-size: var(--fs-tresc); font-weight: 500; cursor: pointer; }
.czat-karta svg { flex: none; width: 13px; height: 13px; stroke: currentColor; fill: none; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.czat-karta-nazwa { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.czat-karta-czeka { flex: none; width: 6px; height: 6px; border-radius: 50%; background: var(--ok); }
.czat-karta-x { flex: none; width: 20px; height: 20px; padding: 0; border: 0; border-radius: var(--r-s); background: none; color: var(--text-secondary); font: inherit; font-size: 14px; line-height: 1; cursor: pointer; opacity: 0; transition: opacity var(--t-szybko) var(--ease), background-color var(--t-szybko) var(--ease); }
.czat-karta:hover .czat-karta-x, .czat-karta.aktywna .czat-karta-x, .czat-karta-x:focus-visible { opacity: 1; }
/* „×" nieaktywnej karty nie zajmuje miejsca, dopóki nie najedziesz — w wąskim panelu liczy się każdy piksel. */
.czat-karta:not(.aktywna):not(:hover):not(:focus-within) .czat-karta-x { display: none; }
.czat-karta-x:hover { background: var(--hover-bg); color: var(--foreground); }
.czat-karty-akcje { display: inline-flex; align-items: center; gap: 2px; flex: none; }
.czat-ikona svg.kropki { fill: currentColor; stroke: none; }
.pp-czat .czat-karty-akcje .czat-ikona { width: 24px; }
/* Wąski panel: nieaktywne karty to same ikony (nazwa w dymku `title`). */
.pp-czat { container-type: inline-size; }
@container (max-width: 360px) {
  .czat-karta:not(.aktywna) .czat-karta-nazwa { display: none; }
  .czat-karta:not(.aktywna) { flex: none; min-width: 0; }
}

.czat-log-rama { position: relative; display: flex; flex-direction: column; flex: 1; min-height: 0; }
.czat-log-rama > .chat-log { flex: 1; min-height: 0; }
.chat-log > .empty-note:only-child { margin-block: auto; }
.czat-najnowsze { position: absolute; right: 12px; bottom: 10px; display: inline-flex; align-items: center; gap: 4px; height: 26px; padding: 0 10px 0 8px; border: 0; border-radius: var(--r-pill); background: var(--foreground); color: var(--background); box-shadow: 0 4px 14px rgba(0, 0, 0, .25); font: inherit; font-size: var(--fs-tresc); font-weight: 500; cursor: pointer; transition: opacity var(--t-szybko) var(--ease); }
.czat-najnowsze[hidden] { display: none; }
.czat-najnowsze:hover { opacity: .88; }
.czat-najnowsze:active { scale: .96; }
.czat-najnowsze svg { width: 13px; height: 13px; stroke: currentColor; fill: none; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }

/* Ikony pod odpowiedzią: przy najechaniu, zawsze pod ostatnią, zawsze na dotyku
   i zawsze, gdy któryś kciuk jest wciśnięty — zaznaczenie ma być widać. */
.msg-akcje { display: inline-flex; gap: 1px; margin-top: 4px; padding: 2px; border-radius: var(--r-pill); box-shadow: inset 0 0 0 1px var(--border); opacity: 0; transition: opacity var(--t-szybko) var(--ease); }
.msg.bot:hover .msg-akcje, .msg.bot:focus-within .msg-akcje, .msg.bot.ostatnia .msg-akcje, .msg-akcje:has(.on) { opacity: 1; }
.msg-ikona { display: inline-grid; place-items: center; width: 23px; height: 22px; padding: 0; border: 0; border-radius: var(--r-pill); background: none; color: var(--text-secondary); cursor: pointer; transition: background-color var(--t-szybko) var(--ease), color var(--t-szybko) var(--ease); }
.msg-ikona:hover { background: var(--hover-bg); color: var(--foreground); }
.msg-ikona:active { scale: .96; }
.msg-ikona.on { background: var(--accent); color: var(--foreground); }
.msg-ikona svg { width: 12.5px; height: 12.5px; stroke: currentColor; fill: none; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.msg-ikona.on svg { fill: color-mix(in srgb, currentColor 22%, transparent); }

/* Zminimalizowany czat: okrągła ikona w rogu okna, ciemna w obu motywach
   (jak u Okary), z pulsującą kropką „asystent czeka". */
.czat-plywajacy { position: fixed; right: 20px; bottom: calc(20px + env(safe-area-inset-bottom, 0px)); z-index: 55; display: grid; place-items: center; width: 48px; height: 48px; padding: 0; border: 0; border-radius: 50%; background: #0B0B0C; color: #F2F4F6; box-shadow: 0 6px 20px rgba(0, 0, 0, .35), 0 0 0 1px rgba(255, 255, 255, .1); cursor: pointer; transition: scale var(--t-szybko) var(--ease); }
.czat-plywajacy:hover { scale: 1.04; }
.czat-plywajacy:active { scale: .96; }
.czat-plywajacy svg { width: 26px; height: 26px; }
.czat-plywajacy-kropka { position: absolute; top: 1px; right: 1px; width: 11px; height: 11px; border-radius: 50%; background: var(--ok); box-shadow: 0 0 0 2px var(--background); animation: czat-kropka 2s var(--ease) infinite; }
@keyframes czat-kropka {
  0%, 100% { box-shadow: 0 0 0 2px var(--background), 0 0 0 2px color-mix(in srgb, var(--ok) 60%, transparent); }
  60% { box-shadow: 0 0 0 2px var(--background), 0 0 0 7px transparent; }
}
@media (hover: none) {
  .msg-akcje, .czat-karta-x { opacity: 1; }
}
/* Na telefonie szyna jest dolnym paskiem (56 px) — ikona stoi nad nim. */
@media (max-width: 768px) {
  .czat-plywajacy { right: 16px; bottom: calc(56px + 16px + env(safe-area-inset-bottom, 0px)); }
}
@media (prefers-reduced-motion: reduce) {
  .czat-plywajacy-kropka { animation: none; }
  .czat-plywajacy:hover { scale: none; }
}

/* Oceny asystenta (Zespół → Agenci, panel platformy): wiersz = pytanie,
   rozwinięcie = odpowiedź, którą ktoś ocenił nisko albo zgłosił. */
.ocena-wpis + .ocena-wpis { border-top: 1px solid var(--border); }
.ocena-wpis .row-meta b { font-weight: 500; color: var(--foreground); }
.ocena-odpowiedz { margin: 0 16px 12px; padding: 10px 12px; max-height: 280px; overflow: auto; border-radius: var(--r-s); background: var(--card-2); font-size: var(--fs-tresc); line-height: 1.5; white-space: pre-wrap; overflow-wrap: anywhere; }

/* Marka klienta (A2, makiety zatwierdzone 2026-10-18): zakładka „Marka"
   w karcie firmy i arkusz przeglądu propozycji. Wszystko z tokenów panelu. */
.mk-logo { flex: none; display: grid; place-items: center; width: 36px; height: 36px; border-radius: var(--r-s); box-shadow: 0 0 0 1px var(--obrys-obrazu); overflow: hidden; background: var(--card-2); }
.mk-logo img { display: block; width: 100%; height: 100%; object-fit: contain; }
.mk-logo-pusty { font-family: var(--mono); font-size: var(--fs-drobne); color: var(--muted-fg); }
.mk-paleta { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 12px; }
.mk-sw-wrap { display: flex; flex-direction: column; align-items: center; gap: 4px; }
.mk-sw { display: block; width: 28px; height: 28px; border-radius: var(--r-xs); box-shadow: 0 0 0 1px var(--border-strong); }
.mk-hex { font-family: var(--mono); font-size: var(--fs-drobne); }
.mk-prawa { align-items: flex-end; text-align: right; }
.mk-filar { display: grid; grid-template-columns: minmax(0, 1.6fr) auto minmax(60px, 120px) 44px; gap: 12px; align-items: center; padding: 10px 16px; border-top: 1px solid var(--border); font-size: var(--fs-tresc); }
.panel-head + .mk-filar { border-top: 0; }
.mk-formaty { display: flex; flex-wrap: wrap; gap: 4px; }
@media (max-width: 560px) {
  .mk-filar { grid-template-columns: minmax(0, 1fr) 44px; row-gap: 6px; }
  .mk-filar .mk-formaty { grid-column: 1 / -1; grid-row: 2; }
  .mk-filar .real-pasek { grid-column: 1 / 2; grid-row: 3; }
  .mk-filar .real-liczba { grid-column: 2; grid-row: 1; }
}
.mk-zakazane { display: flex; flex-direction: column; gap: 6px; }
.mk-tagi { margin-left: 0; }
.mk-okna { margin-bottom: 12px; }
.mk-zrodla { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 12px 0 8px; }
.mk-zr.wylaczone { opacity: .5; }
.mk-porownanie { display: flex; flex-direction: column; gap: 12px; }
.mk-wersja { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.mk-porownanie .dok-roznica { margin: 0; max-height: none; }
.mk-sekcja .btn-row.panel-pad { margin-top: 0; padding-top: 0; }
.mk-edycja { min-height: 140px; }
.mk-format { display: inline-flex; align-items: center; gap: 6px; cursor: pointer; }
[data-filary-suma].warn { color: var(--warn-tekst); }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* Warianty copy od agenta w kompozytorze (A4): pełny tekst wariantu,
   odrzucony przygaszony — powód stoi pod spodem słowami. */
.post-copy input { flex: 1 1 100%; min-width: 0; }
.post-copy select, .post-copy .btn { flex: 0 0 auto; width: auto; }
.post-copy { flex-wrap: wrap; }
.copy-tresc { white-space: pre-wrap; overflow-wrap: anywhere; font-size: var(--fs-tresc); }
.copy-wariant { align-items: flex-start; }
.copy-wariant.odrzucony .copy-tresc { opacity: .6; }

/* Lokalnie (2026-10-19): punkt checklisty wizytówki Google — pole wyboru
   przy pierwszym wierszu, nazwa i dopisek łamią się zamiast uciekać w bok. */
.lk-punkt { display: flex; flex: 1; min-width: 0; align-items: flex-start; gap: 10px; }
.lk-punkt input { flex: none; margin-top: 1px; }

/* Odstępy pojedynczych elementów: zamiast stylu w linii, tylko stopnie siatki 4 px. */
.mt-4 { margin-top: 4px; }
.mt-8 { margin-top: 8px; }
.mt-12 { margin-top: 12px; }
.mb-0 { margin-bottom: 0; }
.mb-4 { margin-bottom: 4px; }
.mb-8 { margin-bottom: 8px; }
.mb-12 { margin-bottom: 12px; }
.mb-16 { margin-bottom: 16px; }
.ml-8 { margin-left: 8px; }
.pt-0 { padding-top: 0; }
.btn-row.zawijaj { flex-wrap: wrap; gap: 8px; align-items: center; }
.row-act.jak-przycisk { gap: 8px; }
summary, label.plainlink { cursor: pointer; }
a.row-act { text-decoration: none; }

.ml-auto { margin-left: auto; }
.akcje-w-linii { display: inline-flex; gap: 8px; }
.pl-0 { padding-left: 0; }
.min-0 { min-width: 0; }
.rosnie { flex: 1; }
.blok { display: block; }
.przewijaj-x { overflow-x: auto; }
.tlo-strony { background: var(--background); }
.tekst-slaby { color: var(--muted-fg); }
.zachowaj-linie { white-space: pre-wrap; }
.akapit-mt { margin: 8px 0 0; }
.lista-wcieta { margin: 8px 0 0 16px; }
.lista-punktowana { margin: 8px 0 0; padding-left: 16px; list-style: disc; }
.lista-przewijana { max-height: 220px; overflow-y: auto; }
.opcja-wiersz { display: flex; padding: 4px 0; }
.pole-120 { width: auto; min-width: 120px; }
.pole-150 { width: auto; min-width: 150px; }
.max-140 { max-width: 140px; }
.media-kafel { position: relative; display: block; width: 88px; cursor: pointer; }
.media-znacznik { position: absolute; top: 4px; left: 4px; z-index: 1; accent-color: var(--accent); }
.media-obraz { display: block; width: 88px; height: 88px; object-fit: cover; border-radius: 6px; }
.media-podpis { display: block; max-width: 88px; }

/* Listy z szyny (wersja A, 4 listopada): filtr w oknach, grupy zwijane,
   należności nad Fakturami, dopasowanie w wierszu Przychodzących. */
.okna-filtra { max-width: 100%; overflow-x: auto; scrollbar-width: none; }
.okno-ile { margin-left: 4px; color: var(--text-secondary); font-variant-numeric: tabular-nums; }
.okno.active .okno-ile { color: inherit; }

.grupa-zwijana + .grupa-zwijana { border-top: 1px solid var(--border); }
.grupa-zwijana > summary { display: flex; align-items: center; gap: 8px; min-height: 40px; padding: 8px 16px; list-style: none; cursor: pointer; }
.grupa-zwijana > summary::-webkit-details-marker { display: none; }
.grupa-zwijana > summary:focus-visible { outline: 2px solid var(--fokus); outline-offset: -2px; border-radius: var(--r); }
.grupa-zwijana > summary .panel-label { flex: none; margin: 0; }
.grupa-zwijana > summary .szewron { margin-left: auto; }
.grupa-zwijana > summary .grupa-suma + .szewron { margin-left: 0; }
.grupa-zwijana[open] > summary .szewron { transform: rotate(180deg); }
.grupa-suma { margin-left: auto; font-size: var(--fs-tresc); }
.grupa-zwijana > .panel { box-shadow: none; border-radius: 0; border-top: 1px solid var(--border); }
.grupa-zwijana > .row:last-child { border-bottom: 0; }

/* Lista stoi w panelu na całą szerokość: pasek faktów zaczyna się tam, gdzie tekst wierszy. */
:is(.pp-tresc, .lista-firm-ramka) > .fakty-pasek { padding-inline: 14px; }

/* Projekt niesie swoje terminy: nazwa mocniej, terminy wcięte pod nią. */
.pp-tresc > .panel > .row[data-project] .row-name { font-weight: 500; }
.pp-tresc > .panel > .row[data-project] ~ .row[data-zob] { padding-left: 30px; }


@media (max-width: 768px) {
  /* Nagłówek listy w dwóch rzędach, nie w trzech: akcje obok tytułu, podzakładki pod spodem. */
  .przestrzen .card-title-row:not(.naglowek-kanalu) { flex-direction: row; flex-wrap: wrap; align-items: center; }
  .przestrzen .card-title-row:not(.naglowek-kanalu) .card-title-lewa { display: contents; }
  .przestrzen .card-title-row:not(.naglowek-kanalu) .podzakladki { order: 3; flex-basis: 100%; }
  .przestrzen .card-title-row:not(.naglowek-kanalu) .pp-akcje { margin-left: auto; }
}
.sieci-posta { display: inline-flex; gap: 4px; }
.badge-blad { background: var(--bad-bg); color: var(--bad-tekst); }

/* Posty: kalendarz z obsługą (wybór właściciela, 13 listopada 2026). Kafelek
   na post w kolorze stanu, obok panel wybranego posta. */
.pkal { display: flex; flex-direction: column; gap: 12px; min-width: 0; }
.pkal-pasek { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 8px; min-width: 0; }
.pkal-filtry { display: flex; flex-wrap: wrap; gap: 8px; min-width: 0; }
.pkal-filtry .szewron { margin-right: -4px; }
.pkal-naw { display: inline-flex; align-items: center; gap: 8px; font-size: var(--fs-tresc); font-weight: 500; font-variant-numeric: tabular-nums; }
.pkal-dwie { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 12px; min-width: 0; }
.pkal-dwie > .pkal-mies-r { flex: 4 1 560px; min-width: 0; overflow-x: auto; }
.pkal-kol { flex: 1 1 300px; display: flex; flex-direction: column; gap: 12px; min-width: 0; }
.pkal-mies { min-width: 640px; }
.pkal-mies-g { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); padding: 8px 0; font-size: var(--fs-os); color: var(--text-secondary); text-align: center; }
.pkal-mies-k { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); border-top: 1px solid var(--border); }
.pkal-mk { display: flex; flex-direction: column; gap: 3px; min-width: 0; min-height: 100px; padding: 4px 6px; border-right: 1px solid var(--border); border-bottom: 1px solid var(--border); box-sizing: border-box; }
.pkal-mk:nth-child(7n) { border-right: 0; }
.pkal-mk.obok { background: var(--card-2, var(--sidebar)); color: var(--text-secondary); }
.pkal-nr { font-size: var(--fs-meta); font-variant-numeric: tabular-nums; }
.pkal-mk.pkal-dzis .pkal-nr { color: var(--brand-tekst); font-weight: 500; }
.pkal-z { display: flex; align-items: center; gap: 4px; width: 100%; min-width: 0; height: 20px; padding: 0 4px 0 5px; border: 0; border-radius: 4px; background: var(--muted); color: var(--foreground); font: inherit; font-size: var(--fs-meta); text-align: left; cursor: pointer; }
.pkal-z:hover { box-shadow: inset 0 0 0 1px var(--border-strong); }
.pkal-z:focus-visible { outline: 2px solid var(--fokus); outline-offset: 1px; }
.pkal-n { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pkal-s { display: inline-flex; gap: 1px; flex: none; }
.pkal-s svg { width: 10px; height: 10px; fill: currentColor; opacity: .72; }
.pkal-s svg.zle { fill: var(--bad-tekst); opacity: 1; }
.pkal-z.st-szkic, .pkal-leg.st-szkic { background: none; box-shadow: inset 0 0 0 1px var(--border-strong); color: var(--text-secondary); }
.pkal-z.st-czeka, .pkal-leg.st-czeka { background: var(--warn-bg); color: var(--warn-tekst); }
.pkal-z.st-klient, .pkal-leg.st-klient { background: var(--brand-soft); color: var(--brand-tekst); }
/* Uwaga klienta z linku akceptacji — cytat nad sieciami w panelu posta. */
.pkal-uwaga { padding: 8px 12px; border-radius: var(--r-s); background: var(--muted); box-shadow: inset 2px 0 0 var(--warn); overflow-wrap: anywhere; }
.pkal-uwaga p { margin: 2px 0 0; }
.pkal-z.st-zapl, .pkal-leg.st-zapl { background: var(--muted); color: var(--foreground); }
.pkal-z.st-czesc, .pkal-leg.st-czesc { background: var(--bad-bg); color: var(--bad-tekst); }
.pkal-z.st-blad, .pkal-leg.st-blad { background: var(--bad-bg); color: var(--bad-tekst); box-shadow: inset 0 0 0 1px var(--bad); }
.pkal-z.st-ok, .pkal-leg.st-ok { background: var(--ok-bg); color: var(--ok-tekst); }
.pkal-z.wybrany { box-shadow: inset 0 0 0 2px var(--brand); }
.pkal-legenda { display: flex; flex-wrap: wrap; gap: 4px 12px; padding: 8px 12px; font-size: var(--fs-drobne); color: var(--text-secondary); }
.pkal-legenda span { display: inline-flex; align-items: center; gap: 4px; }
.pkal-leg { display: inline-block; width: 10px; height: 10px; border-radius: 3px; }
.pkal-link { max-width: 100%; padding: 0; border: 0; background: none; color: inherit; font: inherit; text-align: left; cursor: pointer; }
.pkal-link:hover { text-decoration: underline; text-underline-offset: 3px; }
.pkal-link:focus-visible { outline: 2px solid var(--fokus); outline-offset: 2px; border-radius: 3px; }
.pkal-sz { padding: 16px; min-width: 0; }
.pkal-post { display: flex; flex-direction: column; gap: 12px; font-size: var(--fs-tresc); min-width: 0; }
.pkal-post-g { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.pkal-post-menu { margin-left: auto; }
.pkal-post .btn-row { margin-top: 0; flex-wrap: wrap; }
.pkal-tresc { padding: 12px; border-radius: var(--r-s); background: var(--card-2, var(--sidebar)); box-shadow: inset 0 0 0 1px var(--border); cursor: pointer; }
.pkal-tresc p { margin: 8px 0 0; line-height: 1.5; text-wrap: pretty; overflow-wrap: anywhere; white-space: pre-wrap; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 10; line-clamp: 10; overflow: hidden; }
.pkal-tresc-g { display: flex; align-items: center; gap: 8px; }
.pkal-tresc-g b { font-weight: 500; }
.pkal-foto { display: block; width: 100%; aspect-ratio: 16 / 10; object-fit: cover; margin-top: 8px; border-radius: var(--r-s); outline: 1px solid var(--obrys-obrazu); outline-offset: -1px; background: var(--muted); }
.pkal-sieci { display: flex; flex-direction: column; }
.pkal-siec { display: flex; align-items: center; gap: 8px; min-height: 34px; padding: 4px 0; border-top: 1px solid var(--border); min-width: 0; }
.pkal-siec:first-child { border-top: 0; }
.pkal-siec .badge { flex: none; min-width: 34px; justify-content: center; }
.pkal-siec-s { flex: 1; min-width: 0; overflow-wrap: anywhere; font-variant-numeric: tabular-nums; }
.pkal-siec a.row-act { text-decoration: none; }

/* Kompozytor posta: arkusz z polami po lewej i podglądem sieci po prawej
   (wybór właściciela, 13 listopada 2026). Jedyny arkusz szerszy niż 560 px. */
.sheet.szeroki .sheet-panel { width: min(1040px, 100%); }
.ko { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
.ko-glowa { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 8px 12px; }
.ko-dwie { display: grid; grid-template-columns: minmax(0, 1fr) minmax(280px, 380px); gap: 20px; align-items: start; min-width: 0; }
.ko-lewa { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
.ko-lewa .field { margin: 0; }
.ko-lewa textarea { display: block; font-family: inherit; }
.ko-rz { display: flex; justify-content: flex-end; margin-top: 6px; }
.ko-licz { font-variant-numeric: tabular-nums; }
.ko-sieci { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.ko-sieci .okna { align-self: flex-start; max-width: 100%; overflow-x: auto; }
.ko-sieci .okno { display: inline-flex; align-items: center; }
.ko-sieci .okno.ko-pominieta:not(.active) { opacity: .55; }
.ko-sieci .okno.ko-pominieta { text-decoration: line-through; }
.ko-wyj { width: 6px; height: 6px; margin-left: 6px; border-radius: 50%; background: var(--brand); }
.ko-wyj.zle { background: var(--bad); }
.ko-zle { color: var(--bad-tekst); }
.ko-wyjatek { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 12px; }
.ko-wyjatek .ko-licz { margin-left: auto; }
.ko-media { display: grid; grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); gap: 8px; margin-top: 6px; }
.ko-m { position: relative; display: block; margin: 0; padding: 0; border: 0; background: none; min-width: 0; }
.ko-m img { display: block; width: 100%; aspect-ratio: 1; object-fit: cover; border-radius: var(--r-s); outline: 1px solid var(--obrys-obrazu); outline-offset: -1px; background: var(--muted); }
button.ko-m { cursor: pointer; }
button.ko-m:hover img { opacity: .85; }
.ko-nr, .ko-m-akcje { position: absolute; top: 6px; display: flex; align-items: center; height: 22px; border-radius: var(--r-xs); background: var(--card); box-shadow: var(--faza); }
.ko-nr { left: 6px; min-width: 22px; justify-content: center; font-size: var(--fs-meta); font-weight: 500; font-variant-numeric: tabular-nums; }
.ko-m-akcje { right: 6px; }
.ko-m-akcje .row-act { height: 22px; min-width: 22px; padding: 0 4px; box-shadow: none; background: none; }
.ko-lewa .ko-media + .btn-row { margin-top: 10px; }
.ko-biblioteka { margin-top: 10px; padding: 8px; border-radius: var(--r-s); background: var(--card-2); }
.ko-wiecej > summary { display: inline-flex; list-style: none; cursor: pointer; }
.ko-wiecej > summary::-webkit-details-marker { display: none; }
.ko-wiecej[open] > summary .szewron { rotate: 90deg; }
.ko-wiecej > .field, .ko-wiecej > .field-row { margin-top: 12px; }
.ko-p { position: sticky; top: 0; min-width: 0; }
.ko-karta { overflow: hidden; border-radius: var(--r); background: var(--card); box-shadow: var(--cien-ramka); font-size: var(--fs-tresc); }
.ko-kg { display: flex; align-items: center; gap: 8px; padding: 12px; }
.ko-kn { font-weight: 500; }
.ko-kt { margin: 0; padding: 0 12px 12px; line-height: 1.5; white-space: pre-wrap; overflow-wrap: anywhere; }
.ko-kf { display: block; width: 100%; aspect-ratio: 1.91 / 1; object-fit: cover; background: var(--muted); }
.ko-kf.ko-kwadrat { aspect-ratio: 1; }
.ko-kf + .ko-kt, .ko-kwiecej + .ko-kt { padding-top: 12px; }
.ko-kwiecej { display: block; padding: 6px 12px 0; }
.ko-karta .empty-note { margin: 0; padding: 4px 12px 16px; }
.ko-s { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 8px; padding-top: 12px; border-top: 1px solid var(--border); }
@media (max-width: 1000px) {
  .ko-dwie { grid-template-columns: minmax(0, 1fr); }
  .ko-p { position: static; }
  .ko-karta { max-width: 420px; }
}
@media (max-width: 520px) {
  .ko-s { flex-direction: column-reverse; align-items: stretch; }
}


.karty-arkusz { display: flex; flex-direction: column; gap: 8px; }

.pp-glowa-prosta { cursor: default; }
.pp-glowa-prosta:active { cursor: default; }

/* ── Pozycje fraz (Kanały → Pozycje, wariant A z 13 listopada) ───────── */
.poz-pasek { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; }
.poz-tryb, .poz-filtry { align-self: flex-start; max-width: 100%; overflow-x: auto; scrollbar-width: none; }
.poz-ile { margin-left: 4px; color: var(--text-secondary); font-variant-numeric: tabular-nums; }
.poz-brak { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; color: var(--text-secondary); font-size: var(--fs-meta); }
.poz-md { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: 12px; align-items: start; min-width: 0; }
.poz-lista { overflow: hidden; min-width: 0; }
.poz-panel { padding: 16px; min-width: 0; position: sticky; top: 12px; }
.poz-fakty { display: flex; flex-wrap: wrap; gap: 8px 24px; padding: 12px 16px; border-bottom: 1px solid var(--border); color: var(--text-secondary); font-size: var(--fs-tresc); }
.poz-fakty b { color: var(--foreground); font-weight: 500; font-variant-numeric: tabular-nums; }
.poz-tabela { overflow-x: auto; }
.poz-tabela table { width: 100%; border-collapse: collapse; font-size: var(--fs-tresc); }
.poz-tabela th { padding: 8px; font-size: var(--fs-meta); font-weight: 400; color: var(--text-secondary); text-align: left; white-space: nowrap; border-bottom: 1px solid var(--border); }
.poz-tabela td { padding: 8px; vertical-align: middle; border-top: 1px solid var(--border); white-space: nowrap; }
.poz-tabela tbody tr:first-child td { border-top: 0; }
.poz-tabela th:first-child, .poz-tabela td:first-child { padding-left: 16px; }
.poz-tabela th:last-child, .poz-tabela td:last-child { padding-right: 16px; }
.poz-tabela .p { text-align: right; font-variant-numeric: tabular-nums; }
.poz-tabela tr.klik { cursor: pointer; }
.poz-tabela tr.klik:hover td { background: var(--hover-bg); }
.poz-tabela tr.wybrany td { background: var(--brand-soft); }
.poz-tabela td .badge { vertical-align: middle; }
.poz-tabela .tone-ok { color: var(--ok-tekst); }
.poz-tabela .tone-bad { color: var(--bad-tekst); }
.poz-sz { color: var(--text-secondary); }
.poz-b { font-weight: 500; }
.poz-fraza { padding: 0; border: 0; background: none; color: inherit; font: inherit; text-align: left; cursor: pointer; }
.poz-fraza:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; border-radius: 2px; }
.poz-szczegol { display: flex; flex-direction: column; gap: 12px; font-size: var(--fs-tresc); min-width: 0; }
.poz-sz-g { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; min-width: 0; }
.poz-nazwa { font-weight: 500; overflow-wrap: anywhere; }
.poz-grupa { margin-left: auto; }
.poz-wstecz { display: none; align-self: flex-start; }
.poz-liczby { display: flex; gap: 24px; }
.poz-liczby > span { display: flex; flex-direction: column; }
.poz-liczby b { font-size: var(--fs-liczba-m); font-weight: 500; line-height: 1.2; font-variant-numeric: tabular-nums; }
.poz-w { display: block; width: 100%; height: auto; }
.poz-w line { stroke: var(--chart-grid); stroke-width: 1; }
.poz-w path { fill: none; stroke: var(--chart-line); stroke-width: 1.6; stroke-linejoin: round; stroke-linecap: round; }
.poz-w circle { fill: var(--chart-line); stroke: var(--card); stroke-width: 2; }
.poz-w text { fill: var(--chart-axis); font-size: var(--fs-os); font-variant-numeric: tabular-nums; }
.poz-top-g { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.poz-top { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.poz-top li { display: flex; align-items: center; gap: 8px; min-height: 28px; padding: 0 8px; border-radius: var(--r-xs); min-width: 0; }
.poz-top li.my { background: var(--brand-soft); color: var(--brand-tekst); font-weight: 500; }
.poz-top .ellipsis { flex: 1; min-width: 0; }
.poz-nr { flex: none; width: 18px; color: var(--text-secondary); text-align: right; font-variant-numeric: tabular-nums; }
.poz-top li.my .poz-nr { color: inherit; }
.poz-top .poz-dalej { min-height: 16px; padding-left: 34px; color: var(--text-secondary); line-height: 1; }
@media (max-width: 1000px) {
  .poz-md { grid-template-columns: minmax(0, 1fr); }
  .poz-panel { display: none; position: static; }
  .poz-md.otwarty .poz-panel { display: block; }
  .poz-md.otwarty .poz-lista { display: none; }
  .poz-wstecz { display: inline-flex; }
}
@media (max-width: 768px) {
  .poz-tabela .poz-u { display: none; }
}

/* Konta i media, wersja A (13 listopada): konta, biblioteka i szablony obok
   siebie; poniżej 1100 px jedno pod drugim. Import planu treści zostaje pod
   spodem na całą szerokość. */
.konta-trzy { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; align-items: start; }
.konta-trzy > * { min-width: 0; }
/* „Wgraj" to chip z ukrytym polem pliku — wygląda jak akcja nagłówka, nie jak pole. */
.chip-plik { position: relative; }
.chip-plik:has(.plik-wejscie:focus-visible) { outline: 2px solid var(--fokus); outline-offset: 2px; }
.konta-formularz { border-bottom: 1px solid var(--border); }
@media (min-width: 1101px) { .konta-formularz .siatka-pol { grid-template-columns: minmax(0, 1fr); } }
.konta-pliki { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 12px; padding: 12px 16px 16px; }
.konta-plik { margin: 0; min-width: 0; }
.konta-plik img { display: block; width: 100%; aspect-ratio: 1; object-fit: cover; border-radius: var(--r-xs); outline: 1px solid var(--obrys-obrazu); outline-offset: -1px; }
.konta-plik figcaption { display: flex; align-items: center; gap: 2px; min-width: 0; margin-top: 4px; }
.konta-plik figcaption .row-meta { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
@media (max-width: 1100px) {
  .konta-trzy { grid-template-columns: minmax(0, 1fr); }
}

/* Faktury, wersja A (13 listopada): okna stanów nad tabelą, zaznaczanie
   i jedno przypomnienie dla kilku faktur naraz, suma w stopce. */
.fak-pasek { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 8px 12px; }
.fak-masowo { display: flex; align-items: center; gap: 8px; }
.fak-tabela .fak-w { width: 1%; padding-right: 0; }
.fak-tabela .fak-w input { display: block; margin: 0; }
.fak-klient { max-width: 280px; }
.fak-klient .poz-fraza { display: block; max-width: 100%; }
.fak-suma { display: flex; justify-content: space-between; flex-wrap: wrap; gap: 4px 12px; padding: 8px 16px; border-top: 1px solid var(--border); font-size: var(--fs-tresc); font-weight: 500; }
/* Telefon: zostaje klient (z numerem pod spodem), termin i kwota — reszta
   nie mieści się obok kwoty, a kwota jest tym, po co się tu przychodzi. */
.fak-nr { display: none; }
@media (max-width: 768px) {
  .fak-tabela .fak-u { display: none; }
  .fak-klient { white-space: normal; max-width: none; }
  .fak-klient .poz-fraza { white-space: normal; }
  .fak-nr { display: block; font-size: var(--fs-meta); color: var(--text-secondary); }
}

/* Przelewy (Finanse → Przelewy): wpływy i wypływy obok siebie, każda kolumna
   z własną sumą. auto-fit składa je w jedną, gdy panel listy jest wąski —
   w przestrzeni szerokość zależy od paneli obok, nie od okna. */
.prz-dwie { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr)); gap: 12px; align-items: start; }
.prz-dwie > .panel { min-width: 0; margin-top: 0; }

/* Agenci D: karty decyzji w siatce, pasek liczb nad nimi. */
.ag-fakty { border-bottom: 0; }
.ag-karty { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(320px, 100%), 1fr)); gap: 12px; }
.ag-karta { display: flex; flex-direction: column; gap: 10px; min-width: 0; padding: 12px 16px; font-size: var(--fs-tresc); }
.ag-karta-g { display: flex; align-items: baseline; gap: 8px; min-width: 0; }
.ag-karta-n { flex: none; font-weight: 500; }
.ag-karta-g .row-meta { min-width: 0; }
.ag-karta-dl { align-items: start; gap: 4px 16px; }
.ag-karta-dl dd { display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.ag-karta .btn-row { margin-top: auto; }
.ag-fakty b.tone-bad { color: var(--bad-tekst, var(--bad)); }

/* Ludzie A: tabela dostępu. Na telefonie zostaje osoba, rola i menu. */
.ludzie-tabela .c { text-align: center; }
.ludzie-osoba { display: flex; align-items: center; gap: 10px; min-width: 0; }
.ludzie-tabela td:first-child { max-width: 320px; }
.ludzie-m { width: 1%; text-align: right; }
.ludzie-wyl td:not(.ludzie-m) { opacity: .6; }
@media (max-width: 620px) {
  .ludzie-tabela .ludzie-u { display: none; }
  .ludzie-tabela td:first-child { max-width: 220px; }
}
