/* ===========================================================================
   CRM Calmex Pologne — arkusz podstawowy

   Tokeny (kolory, promienie, cienie, kroje) są PRZENIESIONE z web/makieta/,
   czyli z makiety, którą klient zaakceptował. Nie są wymyślone od nowa.

   Wartości semantyczne mają policzony kontrast — komentarze przy nich
   pochodzą z makiety i tłumaczą, dlaczego akurat te odcienie. Zgodność
   pilnuje tools/sprawdz-tokeny.py: rozjazd między makietą a CRM-em
   zatrzymuje budowanie.
   =========================================================================== */

:root {
	/* akcent — ten sam co w szablonach maili, żeby panel i wiadomość
	   wyglądały na jeden system */
	--zielen:        #1a5f4a; --na-zieleni: #ffffff;
	--zielen-ciemna: #14493a;
	--zielen-mgla:   #e8f0ed;

	/* neutralne z lekkim odchyleniem w stronę akcentu */
	--tlo:           #f2f4f3;
	--panel:         #ffffff;
	--panel-2:       #fafbfa;
	--obramowanie:   #dfe3e1;
	--obramowanie-2: #eceeed;
	--tekst:         #23282a;
	--tekst-2:       #5d6663;
	--tekst-3:       #66706c;

	/* semantyczne — osobne od akcentu, bo stan musi być czytelny */
	--dobry:      #1a5f4a;
	--dobry-tlo:  #e8f0ed;
	/* #8a5616, nie jaśniej: na #faf0e2 dawało 3,89 przy wymaganych 4,5.
	   Bursztyn na kremowym tle jest zdradliwy — wygląda czytelnie na monitorze,
	   a znika na rzutniku. */
	--uwaga:      #8a5616;
	--uwaga-tlo:  #faf0e2;
	--zly:        #8a2f28; --na-zlym: #ffffff;
	--zly-tlo:    #f8eae9;
	--info:       #2c5772;
	--info-tlo:   #e7eef3;

	--r: 8px;
	--cien: 0 1px 2px rgba(20, 40, 35, .05), 0 4px 12px rgba(20, 40, 35, .04);

	--sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
	--serif: Georgia, "Times New Roman", serif;
	--mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;

	/* SKALA TEKSTU — pięć stopni, każdy z rolą.
	 *
	 * Odstępy mają nazwaną skalę od [[08_DECYZJE]] D73 („odstęp ma nazwę"),
	 * a tekst nie miał żadnej: w arkuszu stało jedenaście rozmiarów wpisanych
	 * na sztywno (11, 11.5, 12, 12.5, 13, 14, 15, 16, 17, 22, 28 px), z czego
	 * CZTERY pełniły tę samą rolę „drobny tekst pomocniczy" w czterech
	 * różnych wartościach: `.pod` 12, `.osoba-pod` 13, `.wyjasnienie-tresc`
	 * 12.5, `.plakietka` 11.
	 *
	 * Argument z D73 stosuje się tu dosłownie: cztery wartości nie niosły
	 * czterech znaczeń. Zmiana rytmu tekstu wymagała przejścia po całym
	 * arkuszu i zgadywania, które 13 px jest którym 13 px.
	 *
	 * `--tekst-plakietka` zostaje osobno od `--tekst-drobny`, bo plakietka
	 * jest elementem graficznym w linii tekstu i MUSI być mniejsza od zdania,
	 * w którym stoi — inaczej rozpycha wiersz.
	 */
	--tekst-plakietka: 11px;   /* plakietki, liczniki w kółkach             */
	--tekst-drobny:    12px;   /* `.pod` — zdanie pomocnicze, etykieta tabeli */
	--tekst-podpis:    13px;   /* podpis pola, etykieta tabeli             */
	--tekst-wiersz:    14px;   /* wiersz danych, treść zdarzenia, karta lejka */
	--tekst-bazowy:    15px;   /* treść — to samo, co `body`               */
	--tekst-naglowek:  22px;   /* `<h1>` ekranu                            */
}

* { box-sizing: border-box; }

body {
	margin: 0;
	font-family: var(--sans);
	font-size: var(--tekst-bazowy);
	line-height: 1.55;
	color: var(--tekst);
	background: var(--tlo);
	-webkit-font-smoothing: antialiased;
}

a { color: var(--zielen); }
a:hover { color: var(--zielen-ciemna); }

/* TEKST TYLKO DLA CZYTNIKA EKRANU.
 *
 * Nagłówek kolumny bywa na ekranie pusty, bo w kolumnie stoją same przyciski
 * i podpis byłby szumem. Dla czytnika ekranu pusty nagłówek znaczy jednak
 * „kolumna bez nazwy" — a wtedy nie da się powiedzieć, do czego należy
 * komórka, którą się właśnie czyta.
 *
 * Nie `display: none` ani `visibility: hidden`: jedno i drugie usuwa tekst
 * także z czytnika, czyli robi dokładnie to, czemu ta klasa ma zapobiec.
 * Kadr o zerowej wysokości jest jedynym sposobem, który zostawia treść
 * w drzewie dostępności. */
.tylko-dla-czytnika {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

/* Fokus widoczny zawsze. Handlowiec pracuje szybko i klawiaturą — niewidoczny
   fokus to nie kwestia dostępności „w teorii", tylko zgubione pole formularza. */
:focus-visible {
	outline: 2px solid var(--zielen);
	outline-offset: 2px;
}

/* --- układ ---------------------------------------------------------------- */

.szkielet {
	display: grid;
	grid-template-columns: 232px 1fr;
	min-height: 100vh;
}

.bok {
	background: var(--panel);
	border-right: 1px solid var(--obramowanie);
	padding: 20px 0;
	display: flex;
	flex-direction: column;
}

.znak {
	padding: 0 20px 18px;
	display: flex;
	align-items: center;
	gap: 10px;
	border-bottom: 1px solid var(--obramowanie-2);
	margin-bottom: 14px;
}
.znak img { width: 168px; height: auto; }

/* Szukanie w boku — nad nawigacją, bo jest częstsze niż którakolwiek
   pozycja menu. Bez własnego przycisku: Enter w polu `type="search"`
   wysyła formularz, a przycisk zająłby szerokość, której w kolumnie
   232 px nie ma. */
.szukaj-globalne { margin: 0 12px 14px; }
.szukaj-globalne input {
	width: 100%;
	padding: 8px 11px;
	font: inherit;
	font-size: var(--tekst-podpis);
	border: 1px solid var(--obramowanie);
	border-radius: var(--r);
	background: var(--panel-2);
	color: var(--tekst);
}
.szukaj-globalne input::placeholder { color: var(--tekst-3); }
.szukaj-globalne input:focus { background: var(--panel); }

/* Podpowiedzi pod polem (2026-09-17, D187) — lista WYCHODZI poza boczny
   panel na treść: nazwa firmy z osobą i e-mailem nie mieści się w 220 px. */
.szukaj-globalne { position: relative; }
.podpowiedzi-szukania {
	position: absolute;
	top: calc(100% + 4px);
	left: 0;
	z-index: 40;
	width: max(100%, 360px);
	max-width: calc(100vw - 24px);
	max-height: 70vh;
	overflow-y: auto;
	margin: 0;
	padding: 6px 0;
	list-style: none;
	background: var(--panel);
	border: 1px solid var(--obramowanie);
	border-radius: var(--r);
	box-shadow: var(--cien);
}
.podpowiedzi-grupa {
	padding: 8px 12px 4px;
	font-size: var(--tekst-plakietka);
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: .04em;
	color: var(--tekst-2);
}
/* Rada i zasięg szukania — zdanie, nie nagłówek grupy: bez wersalików
   (2026-10-03, [[08_DECYZJE]] D794). „Wszystkie pasujące firmy” odcięte
   kreską od podpowiedzi nad nim. */
.podpowiedzi-uwaga { padding: 8px 12px; color: var(--tekst-2); }
.podpowiedzi-wszystkie { border-top: 1px solid var(--obramowanie-2); margin-top: 4px; }
.podpowiedzi-wszystkie a { color: var(--zielen); font-weight: 500; }
.podpowiedzi-szukania a {
	display: flex;
	flex-direction: column;
	gap: 1px;
	padding: 6px 12px;
	color: var(--tekst);
	text-decoration: none;
	font-size: var(--tekst-podpis);
}
.podpowiedzi-szukania [aria-selected="true"] a,
.podpowiedzi-szukania a:hover { background: var(--zielen-mgla); }
.podpowiedz-etykieta { font-weight: 500; }

.nawigacja { display: flex; flex-direction: column; gap: 2px; padding: 0 12px; }

.nawigacja a {
	display: flex;
	align-items: center;
	gap: 10px;
	padding: 9px 12px;
	border-radius: var(--r);
	color: var(--tekst-2);
	text-decoration: none;
	font-weight: 500;
}
.nawigacja a:hover { background: var(--panel-2); color: var(--tekst); }
.nawigacja a[aria-current="page"] {
	background: var(--zielen-mgla);
	color: var(--zielen-ciemna);
	font-weight: 600;
}

/* LICZNIK PRZY POZYCJI MENU — „Zadania 3", „Poczta 4".
 *
 * `margin-left: auto` dosuwa go do prawej krawędzi pozycji, więc liczby
 * układają się w kolumnę i da się je objąć wzrokiem bez czytania etykiet.
 *
 * Kolor akcentu, nie czerwień: to jest praca do zrobienia, a nie awaria.
 * Czerwona plakietka przy dwóch pozycjach naraz — a tak jest w typowy
 * poniedziałek — zamieniłaby stan zwykły w alarm i przestałaby cokolwiek
 * znaczyć. Czerwień zostaje dla rzeczy zepsutych (`.plakietka.zla`).
 *
 * `--tekst-plakietka`, bo to element graficzny w linii tekstu i MUSI być
 * mniejszy od etykiety, przy której stoi (skala tekstu, [[08_DECYZJE]] D73). */
.licznik-menu {
	margin-left: auto;
	min-width: 20px;
	padding: 1px 7px;
	border-radius: 10px;
	background: var(--zielen-mgla);
	color: var(--zielen-ciemna);
	font-size: var(--tekst-plakietka);
	font-weight: 600;
	font-variant-numeric: tabular-nums;
	text-align: center;
}
/* Na bieżącej pozycji tło menu jest już zielonkawe — plakietka w tym samym
   odcieniu zniknęłaby. Odwracamy ją. */
.nawigacja a[aria-current="page"] .licznik-menu {
	background: var(--zielen);
	color: var(--na-zieleni);
}

/* USUNIĘTE 2026-08-02: `.wkrotce` i `.etykieta-wkrotce`.

   Wyszarzały pozycje menu prowadzące do modułów jeszcze niezbudowanych —
   klient widział wtedy, co jest w planie. Wszystkie osiem modułów działa
   od tygodni, więc klas nikt już nie używał: przeszukanie szablonów
   zwracało wyłącznie komentarz odsyłający tutaj.

   Martwy styl jest tańszy niż martwy klucz konfiguracyjny, ale kosztuje
   tak samo: następny czytający sprawdza, gdzie jest używany, i traci na to
   kwadrans. */

/* PRZEJDŹ DO TREŚCI — widoczne tylko z klawiatury.
 *
 * Nie `display: none`: schowany w ten sposób odnośnik wypada z kolejności
 * Tab, czyli przestaje istnieć dokładnie dla tych, dla których jest. Stąd
 * zjechanie nad górną krawędź okna i powrót na `:focus`. */
.do-tresci {
	position: absolute;
	top: -100px;
	left: 12px;
	z-index: 10;
	padding: 10px 16px;
	background: var(--zielen);
	color: var(--na-zieleni);
	border-radius: 0 0 var(--r) var(--r);
	text-decoration: none;
	font-weight: 500;
	transition: top .12s;
}
.do-tresci:focus {
	top: 0;
	color: var(--na-zieleni);
}
/* `<main>` ma `tabindex="-1"`, żeby przeskok przeniósł FOKUS, a nie tylko
   widok. Obrys na nim jest wtedy zbędny — to cel skoku, nie kontrolka. */
.tresc:focus { outline: none; }

.stopka-boku {
	margin-top: auto;
	padding: 14px 20px 0;
	border-top: 1px solid var(--obramowanie-2);
	font-size: var(--tekst-drobny);
	color: var(--tekst-3);
}
/* Wydanie stojące na serwerze — najciszej, jak można: to informacja
   na jedno pytanie w miesiącu, a nie element pracy codziennej. */
.wersja-systemu {
	margin-top: 8px;
	font-variant-numeric: tabular-nums;
	color: var(--tekst-3);
	opacity: .75;
}
.stopka-boku form { margin: 6px 0 0; }
.stopka-boku button {
	background: none;
	border: 0;
	padding: 0;
	font: inherit;
	color: var(--zielen);
	cursor: pointer;
	text-decoration: underline;
}

.tresc {
	padding: 26px 30px 40px;
	min-width: 0;

	/* `clip`, a NIE `hidden` — i to jest cała subtelność tej reguły.
	   `hidden` tworzy kontener przewijania, co psuje `position: sticky`
	   wewnątrz i zmienia zachowanie kotwic. `clip` tylko przycina.

	   Po co w ogóle: dymek „?" jest ukryty przez `visibility`, a nie
	   `display: none` — celowo, bo `wyjasnienia.js` mierzy go PRZED
	   pokazaniem, żeby nie przeskakiwał. Ukryty element nadal zajmuje
	   miejsce w układzie, więc dymek stojący blisko prawej krawędzi dawał
	   stronie poziomy pasek przewijania, mimo że nic widocznego nie wystawało.

	   Zmierzone przed zmianą (nadmiar dokumentu w px):

	       ekran            375 px   1280 px
	       sekwencje          116      112     ← przy normalnej szerokości pracy
	       dostawcy           387        0
	       ustawienia          57        0
	       kampanie           228        0     ← rząd czterech przycisków akcji

	   DLACZEGO OD 801 px, a nie zawsze: sprawdzone pomiarem, że przy 375 px
	   dymki nie mieszczą się w treści NIGDZIE — ani w prawo, ani w lewo.
	   Przycięcie odebrałoby je tam całkowicie, a bez tej reguły dawały się
	   przynajmniej doprzewijać. Na telefonie zostaje więc stan zastany:
	   poziomy pasek jest, ale dymek da się przeczytać.

	   Właściwym rozwiązaniem dla telefonu byłby inny sposób ustawiania dymka
	   (na całą szerokość pod etykietą), a nie przycinanie — to jest zmiana
	   projektowa, nie poprawka, i nie robimy jej przy okazji.

	   Powyżej 801 px zmierzone: 0 z 7 dymków przyciętych na Ustawieniach,
	   0 z 2 na Dostawcach, 0 z 1 na Sekwencjach — po korekcie, którą robi
	   skrypt przy najechaniu. */
}

@media (min-width: 801px) {
	.tresc { overflow-x: clip; }
}

/* Dwie grupy, nie pięć elementów (2026-09-17, D183).
   Po lewej `.naglowek-tytul` — powrót, tytuł, podtytuł, jeden pod drugim.
   Po prawej `.naglowek-akcje` — przyciski razem. Dawny `space-between`
   rozkładał rodzeństwo równo po szerokości: przy czterech elementach
   przycisk „← kampanie" stał na środku ekranu, a podtytuł Telefonów —
   małym drukiem pośrodku, bez związku z tytułem. */
.naglowek-strony {
	display: flex;
	align-items: flex-end;
	justify-content: space-between;
	gap: 10px 16px;
	margin-bottom: 20px;

	/* Zawijanie, bo liczba przycisków akcji ROŚNIE z systemem.
	   Ekran kampanii miał trzy, po dodaniu „Dostawców" ma cztery — i na
	   telefonie (375 px) rząd wystawał poza stronę o 228 px. Bez tej reguły
	   każdy kolejny przycisk pogarsza sprawę po cichu, bo na laptopie
	   wszystko wygląda dobrze.

	   Handlowcy pracują z hoteli i od klientów (CLAUDE.md, zasada 2),
	   więc telefon nie jest tu przypadkiem brzegowym. */
	flex-wrap: wrap;
}
.naglowek-strony h1 {
	font-size: var(--tekst-naglowek);
	font-weight: 600;
	letter-spacing: -.01em;
	margin: 0;
}
.naglowek-tytul { flex: 1 1 320px; min-width: 0; }
.naglowek-akcje {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: flex-end;
	gap: 8px;
}
.naglowek-akcje:empty { display: none; }

/* „← lista firm" — odnośnik NAD tytułem, nie przycisk wśród akcji.
   Wyglądał jak akcja i stał tam, gdzie akcje, więc „wróć" i „Kopiuj jako
   szkic" różniły się wyłącznie napisem. */
.powrot {
	display: inline-block;
	margin-bottom: 4px;
	font-size: var(--tekst-podpis);
	color: var(--tekst-2);
	text-decoration: none;
}
.powrot:hover, .powrot:focus-visible { color: var(--zielen); text-decoration: underline; }
@media (max-width: 800px) {
	.naglowek-akcje { justify-content: flex-start; }
}

/* Akcja w pasku nagłówka wymagająca POST-a (czyli formularza), a nie
   odnośnika. Formularz jest blokowy i bez tej reguły łamie rząd przycisków
   na własną linijkę. */
.akcja-w-naglowku { display: inline; margin: 0; }

/* Dwa kafle wyboru drogi wysyłki (`wysylka/nowa-wysylka.html`).

   Osobno od `.karty`, bo tam minimum to 210 px i przy szerokim ekranie
   układa się z tego trzecia kolumna — a tu kafle są dokładnie DWA i są
   pytaniem rozstrzygającym („zapisali się czy nie"). Trzecia kolumna
   z pustką obok nich czytałaby się jak brakująca trzecia odpowiedź. */
.wybor-drogi {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
	gap: 14px;
	margin-bottom: 22px;
}

/* Tabela „Czym się różnią" nad kaflami (2026-09-20, [[08_DECYZJE]] D372).

   Pierwsza kolumna to PYTANIE („Ile wiadomości", „Kiedy przestaje"), więc
   jest nagłówkiem wiersza, a nie komórką: czyta się ją w pionie, jak spis
   pytań, i dopiero potem wodzi wzrokiem w bok po odpowiedziach. Ten sam
   układ co `.porownanie-duplikatow` przy scalaniu kartotek.

   Nie zawija się, bo nazwy są dwuwyrazowe, a złamane w pół przestają być
   kolumną pytań i zaczynają wyglądać jak treść. */
.porownanie-drog th[scope="row"] {
	text-align: left;
	font-weight: 500;
	color: var(--tekst-2);
	white-space: nowrap;
	vertical-align: top;
}

/* Dwie kolumny odpowiedzi dzielą się po równo — inaczej dłuższa treść
   sekwencji zabiera kampanii miejsce i tabela wygląda na przechyloną. */
.porownanie-drog td { width: 42%; vertical-align: top; }

/* Na telefonie odwrotnie: kolumna pytań ZAWIJA SIĘ, a odpowiedzi biorą, ile
   potrzebują. Zmierzone na 375 px — z `nowrap` „Kiedy wychodzą” zajmowało
   połowę szerokości ekranu, a odpowiedź obok łamała się co dwa słowa. Sama
   tabela przewija się w bok (`.przewijana`), więc nic nie ginie, ale
   przewijanie w bok po to, żeby przeczytać zdanie, jest ceną, której tu nie
   trzeba płacić. */
@media (max-width: 800px) {
	.porownanie-drog th[scope="row"] { white-space: normal; }
	.porownanie-drog td { width: auto; }
}

/* --- karty ---------------------------------------------------------------- */

.karty {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
	gap: 14px;
	margin-bottom: 22px;
}

.karta {
	background: var(--panel);
	border: 1px solid var(--obramowanie);
	border-radius: var(--r);
	box-shadow: var(--cien);
	padding: 16px 18px;
}

.karta .etykieta {
	font-size: var(--tekst-drobny);
	color: var(--tekst-2);
	text-transform: uppercase;
	letter-spacing: .04em;
	margin-bottom: 6px;
}
.karta .liczba {
	font-size: 28px;
	font-weight: 600;
	line-height: 1.1;
	font-variant-numeric: tabular-nums;
}
.karta .pod { font-size: var(--tekst-drobny); color: var(--tekst-3); margin-top: 4px; }

/* Kafelek pulpitu jest odnośnikiem — prowadzi do listy, którą podsumowuje.
   Bez tego trzeba przeczytać liczbę, a potem szukać jej w menu. */
a.karta {
	display: block;
	text-decoration: none;
	color: inherit;
	transition: border-color .12s, box-shadow .12s;
}
a.karta:hover,
a.karta:focus-visible {
	border-color: var(--zielen);
	box-shadow: 0 2px 10px rgb(0 0 0 / .10);
}

/* Zadania po terminie. Kolor NIE jest jedynym nośnikiem — podpis mówi
   „N po terminie" wprost, bo na czerwony nie każdy zareaguje tak samo. */
.karta.pilna { border-color: var(--zly); }
.karta.pilna .pod { color: var(--zly); font-weight: 600; }

/* --- komunikaty ----------------------------------------------------------- */

.komunikat {
	border-radius: var(--r);
	padding: 12px 16px;
	margin-bottom: 16px;
	border: 1px solid transparent;
}
.komunikat.info    { background: var(--info-tlo);  border-color: #c9dae5; color: var(--info); }
.komunikat.uwaga   { background: var(--uwaga-tlo); border-color: #e7d3ae; color: var(--uwaga); }
.komunikat.dobry   { background: var(--dobry-tlo); border-color: #bcd6cc; color: var(--dobry); }
.komunikat.zly     { background: var(--zly-tlo);   border-color: #e4c3c0; color: var(--zly); }

/* --- formularze ----------------------------------------------------------- */

label { display: block; font-size: var(--tekst-podpis); font-weight: 500; margin-bottom: 5px; }

/* `number`, `url`, `date` i `datetime-local` dopisane 2026-09-11.
   Jedenaście pól w systemie miało domyślny wygląd przeglądarki obok pól
   ostylowanych: port SMTP, limit dobowy, odstęp kroku, strona www kontaktu,
   termin wysyłki kampanii. Reguła dla `date` istniała przy okazji w TRZECH
   niemal identycznych kopiach — zostaje jedna, tutaj.
   `time` dopisane 2026-10-02 ([[08_DECYZJE]] D754): „Godzina” zadania stała
   gołym polem przeglądarki — mniejszym, inną czcionką — obok „Terminu”. */
input[type="text"], input[type="email"], input[type="password"],
input[type="search"], input[type="tel"], input[type="number"],
input[type="url"], input[type="date"], input[type="datetime-local"],
input[type="time"],
select, textarea {
	width: 100%;
	padding: 9px 11px;
	font: inherit;
	color: var(--tekst);
	background: var(--panel);
	border: 1px solid var(--obramowanie);
	border-radius: 6px;
}
/* FOKUS NA POLU — obrys w kolorze marki, nie we mgle.
 *
 * Do 2026-09-10 stało tu `outline: 2px solid var(--zielen-mgla)`, czyli
 * `#e8f0ed`. Kontrast tej barwy wobec białego panelu wynosi **1,19:1** —
 * obrys po prostu nie istniał. A ponieważ ta reguła ma swoistość (0,1,1),
 * a globalne `:focus-visible` (0,1,0), wygrywała ZAWSZE, niezależnie od
 * kolejności w pliku. Sto linijek wyżej stoi komentarz mówiący, że
 * niewidoczny fokus to „zgubione pole formularza" — reguła znosiła to
 * dokładnie dla pól formularza.
 *
 * Mgła zostaje jako POŚWIATA (`box-shadow`): daje miękkie podświetlenie
 * pola, którego szukał autor pierwszej wersji, i nie udaje obrysu.
 */
input:focus-visible, select:focus-visible, textarea:focus-visible {
	border-color: var(--zielen);
	outline: 2px solid var(--zielen);
	outline-offset: 1px;
	box-shadow: 0 0 0 3px var(--zielen-mgla);
}
/* Mysz i dotyk: sama ramka, bez obrysu — klikając, człowiek wie, gdzie
   kliknął, a obrys przy każdym kliknięciu w pole jest hałasem. */
input:focus, select:focus, textarea:focus { border-color: var(--zielen); }
/* Pole wskazane kotwicą („Wpisz hasło →” prowadzi do `#haslo`, D748) staje
   pod swoją etykietą, nie na samej krawędzi okna, która ją zasłania. */
input:target, select:target, textarea:target { scroll-margin-top: 48px; }

.przycisk {
	display: inline-block;
	padding: 9px 18px;
	font: inherit;
	font-weight: 500;
	color: var(--na-zieleni);
	background: var(--zielen);
	border: 1px solid var(--zielen);
	border-radius: 6px;
	cursor: pointer;
	text-decoration: none;
}
/* `display` wyżej przykrywa domyślne `[hidden] { display: none }`
   przeglądarki — każdy przycisk z atrybutem `hidden` był WIDOCZNY.
   Zmierzone 2026-09-26: „Popraw warunki segmentu” i „Zobacz jego firmy”
   na „Nowej wysyłce” bez wybranego segmentu (pusty adres — pierwszy
   prowadził na „Nowy segment”), „+ Dodaj podpis w innym języku”, którego
   `skrzynki.js` nie umiał schować, i „Kopiuj” bez schowka. Do tej pory
   łatane pojedynczo regułą przy kontenerze (`.segment-przyciski [hidden]`,
   `.wiadomosc-korekta [hidden]`); ta łapie wszystkie. */
.przycisk[hidden] { display: none; }
.przycisk:hover { background: var(--zielen-ciemna); border-color: var(--zielen-ciemna); color: var(--na-zieleni); }
.przycisk.drugorzedny {
	color: var(--tekst);
	background: var(--panel);
	border-color: var(--obramowanie);
}
.przycisk.drugorzedny:hover { background: var(--panel-2); color: var(--tekst); }

/* Akcja w toku — przycisk kliknięty, odpowiedź jeszcze nie wróciła.
   Klasę zakłada `formularze.js`; napis podmienia się z `data-trwa`.
   Bez tego wywołanie modelu (5-20 s) albo import wyglądały tak samo jak
   ekran przed kliknięciem, więc ludzie klikali drugi raz. */
.przycisk.trwa,
button.trwa {
	opacity: .6;
	cursor: progress;
}
/* `disabled` zakładamy klatkę później niż klasę — dopóki go nie ma,
   kursor i przezroczystość już mówią, że coś się dzieje. */
.przycisk[disabled],
button[disabled] { cursor: default; }

/* POLE ZABLOKOWANE MA WYGLĄDAĆ NA ZABLOKOWANE.
 *
 * Reguła pól wyżej ustawia `color` i `background` BEZWARUNKOWO, więc kasuje
 * domyślne wyszarzenie przeglądarki dla `:disabled`. Do 2026-09-10 nie było
 * nic w zamian: jedyny styl stanu zablokowanego dotyczył przycisków i był
 * nim sam `cursor`.
 *
 * Skutek jest sprawdzalny na ekranie „Ustawienia i treść" kampanii, która
 * już wyszła: segment, oprawa i nadawca są tam `disabled` (treści nie wolno
 * zmieniać po pierwszej wysłanej wiadomości). Pola wyglądały na w pełni
 * edytowalne — człowiek klikał, nic się nie działo i nie było powiedziane
 * dlaczego. Ramka informacyjna nad formularzem tłumaczy POWÓD, ale dopiero
 * wtedy, gdy ktoś skojarzy ją z tym polem.
 *
 * `readonly` obok `disabled`, bo temat i treść używają tego pierwszego —
 * dla człowieka to ta sama rzecz: „tego już nie zmienię".
 */
input:disabled, select:disabled, textarea:disabled,
input[readonly], textarea[readonly] {
	background: var(--panel-2);
	color: var(--tekst-2);
	border-color: var(--obramowanie-2);
	cursor: not-allowed;
}
/* Podpis pola też gaśnie — inaczej czarna etykieta nad szarym polem
   wygląda jak błąd renderowania, a nie jak stan. */
.pole:has(input:disabled) > label,
.pole:has(select:disabled) > label,
.pole:has(textarea:disabled) > label,
.pole:has(input[readonly]) > label,
.pole:has(textarea[readonly]) > label { color: var(--tekst-2); }

/* Pole, którego dotyczy komunikat o błędzie.
   Do 2026-09-10 błąd stał WYŁĄCZNIE na górze strony (`.komunikat`), a przy
   formularzu na piętnaście pól — jak „Nowa firma" — czytało się „Adres … jest
   na liście wykluczeń" i nie wiadomo było, które pole poprawić. */
input.zle, select.zle, textarea.zle {
	border-color: var(--zly);
	background: var(--zly-tlo);
}
input.zle:focus, select.zle:focus, textarea.zle:focus {
	border-color: var(--zly);
	outline: 2px solid var(--zly);
}

/* --- ekran logowania ------------------------------------------------------ */

body.logowanie {
	display: grid;
	place-items: center;
	min-height: 100vh;
	padding: 20px;
}

.pudelko-logowania {
	width: 100%;
	max-width: 380px;
	background: var(--panel);
	border: 1px solid var(--obramowanie);
	border-radius: var(--r);
	box-shadow: var(--cien);
	padding: 30px 30px 26px;
}
/* Strony publiczne (zapis, wypis, potwierdzenie) są szersze od logowania:
   niosą zdanie wyjaśniające, a nie dwa pola. Do 2026-09-11 robił to
   `style="max-width:460px"` w szablonie — nadpisanie reguły stąd, niewidoczne
   dla nikogo, kto czyta arkusz ([[08_DECYZJE]] D73). */
.pudelko-logowania.pudelko-publiczne { max-width: 460px; }
/* Adres, którego dotyczy strona — wyśrodkowany, bo jest jej tematem. */
.pod.adres-srodek { text-align: center; }
/* Formularz jednoprzyciskowy stojący w wierszu tabeli obok innych akcji —
   bez tego `<form>` łamie wiersz, bo jest elementem blokowym. */
.w-wierszu { display: inline-block; margin-left: 6px; }
/* Wiersz z treścią błędu doklejony pod wierszem skrzynki — bez odstępu
   u góry, żeby czytało się jak ciąg dalszy, a nie osobna pozycja. */
.wiersz-bledu { padding-top: 0; }
.tekst-zly { color: var(--zly); }
/* Ekran „Etapy lejka" — lista, nie tabela (2026-09-11). Nagłówki tabeli nie
   stały nad swoimi polami, bo wiersz był jedną komórką z formularzem flex. */
.wiersz-etapu {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px;
	padding: 10px 0;
	border-bottom: 1px solid var(--obramowanie);
}
.wiersz-etapu:last-child { border-bottom: 0; }
.pole-nazwa-etapu { flex: 1 1 200px; }
/* Strzałki kolejności nad polami wiersza (2026-09-17, D179) — zastąpiły pole
   liczby, więc `.pole-kolejnosci` zniknęło razem z nim. */
.przesuwanie-etapu { margin-bottom: 6px; align-items: center; }
/* Lejek i automatyka w trzech sekcjach (2026-09-23, D389). Wiersz etapu
   w JEDNEJ linii — strzałki, nazwa, dwa pola, liczba firm, Zapisz, Usuń —
   i zawija się dopiero na wąskim ekranie. Do tego dnia strzałki stały nad
   polami, a pod każdym wierszem to samo zdanie o usuwaniu. */
.wiersz-etapu label { margin-bottom: 0; }
.wiersz-etapu-pola { flex: 1 1 480px; flex-wrap: wrap; }
.liczba-firm-etapu { min-width: 56px; text-align: right; }
.wiersz-nowego-etapu { padding-top: 14px; }
.legenda-etapow { margin: -6px 0 4px; }
/* Reguła jako zdanie: „zdarzenie → etap”, trzy wiersze pod sobą. */
.reguly-lejka {
	display: grid;
	grid-template-columns: minmax(180px, max-content) auto minmax(200px, 360px);
	justify-content: start;
	gap: 10px 12px;
	align-items: center;
}
.regula-gdy { margin: 0; font-size: var(--tekst-wiersz); font-weight: 600; }
.regula-strzalka { color: var(--tekst-3); }
/* Ostrzeżenie przy regule na całą szerokość siatki, tuż pod swoim polem
   (2026-09-26, [[08_DECYZJE]] D502). */
.regula-uwaga { grid-column: 1 / -1; margin: -4px 0 4px; }
/* Miejsce na „Usuń” stoi zawsze, także puste — wiersz bez przycisku nie
   rozjeżdża kolumn, a powód „nie da się usunąć” idzie pod wiersz (D502).
   Szerokość = przycisk `.przycisk.drugorzedny.maly` z napisem „Usuń”. */
.miejsce-usun { flex: 0 0 auto; min-width: 62px; display: flex; justify-content: flex-end; }
.uzycia-etapu { flex-basis: 100%; margin: -4px 0 0 88px; }
/* NIEZAPISANE ZMIANY WIDAĆ (D502). `formularze.js` zakłada `zmieniony` na
   formularzu z `data-pilnuj-zmian`, w którym coś zmieniono. W wierszu etapu
   „Zapisz” zapala się jak przycisk główny — wiadomo, KTÓRY wiersz czeka;
   w pasku zapisu automatyki pojawia się zdanie. Bez skryptu nic się nie
   zapala, a ekran działa jak dotąd. */
.wiersz-etapu form.zmieniony .przycisk.drugorzedny {
	color: var(--na-zieleni);
	background: var(--zielen);
	border-color: var(--zielen);
}
.wiersz-etapu form.zmieniony .przycisk.drugorzedny:hover {
	background: var(--zielen-ciemna);
	border-color: var(--zielen-ciemna);
}
.niezapisane { display: none; }
form.zmieniony .niezapisane { display: inline; }
@media (max-width: 800px) {
	.wiersz-etapu .pole-nazwa-etapu { flex-basis: 100%; }
	.reguly-lejka { grid-template-columns: 1fr; gap: 4px; }
	.regula-strzalka { display: none; }
	.reguly-lejka select { margin-bottom: 10px; }
	.uzycia-etapu { margin-left: 0; }
}
/* RYNKI I TYPY ODBIORCY — STAŁE KOLUMNY (2026-10-07, [[08_DECYZJE]] D811).
   Wiersz był linią flex i pola przesuwały się za szerokością „6 firm” albo
   „w pliku importu: hurt”; na 390 px ekran miał ~5000 px. Węższy ekran:
   dwie linie o stałym składzie (u góry strzałki, kod, nazwa, firmy — pod
   spodem prefiks, „ukryty” i przyciski), od 1100 px — jedna siatka
   z nagłówkiem nad kolumnami. Pola wiążą się z formularzem przez `form=`,
   więc HTML nie dzieli wiersza na kawałki. */
.wiersz-slownika {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px;
	padding: 8px 0;
	border-bottom: 1px solid var(--obramowanie);
}
.wiersz-slownika:last-child { border-bottom: 0; }
.slownik-strzalki { display: flex; gap: 4px; flex: none; }
.wiersz-slownika .slownik-kod { flex: none; min-width: 36px; text-align: center; }
.slownik-typow .wiersz-slownika .slownik-kod { flex: 1 1 0; min-width: 0; text-align: left; overflow-wrap: anywhere; }
.wiersz-slownika .slownik-nazwa { flex: 1 1 100px; min-width: 0; }
.wiersz-slownika .slownik-firmy { flex: none; width: 52px; text-align: right; }
.slownik-przelamanie { flex-basis: 100%; height: 0; }
.wiersz-slownika .slownik-prefiks { flex: none; width: 80px; }
.wiersz-slownika .slownik-ukryty { flex: none; margin: 0; }
/* Miejsce na „Zapisz” + „Usuń” stoi zawsze — pole nazwy nie zmienia szerokości
   między wierszem z „Usuń” a wierszem bez (ta sama reguła co `.miejsce-usun`). */
.slownik-przyciski { display: flex; gap: 6px; align-items: center; justify-content: flex-end; min-width: 116px; margin-left: auto; }
.naglowek-slownika { display: none; }
@media (min-width: 1100px) {
	.wiersz-slownika {
		display: grid;
		grid-template-columns: 70px 44px minmax(160px, 320px) 84px 84px 64px 150px;
		grid-template-areas: "strzalki kod nazwa prefiks ukryty firmy przyciski";
		justify-content: start;
		gap: 8px 12px;
	}
	.slownik-typow .wiersz-slownika {
		grid-template-columns: 70px 220px minmax(160px, 320px) 84px 64px 150px;
		grid-template-areas: "strzalki kod nazwa ukryty firmy przyciski";
	}
	.slownik-strzalki { grid-area: strzalki; }
	.wiersz-slownika .slownik-kod { grid-area: kod; justify-self: start; }
	.wiersz-slownika .slownik-nazwa { grid-area: nazwa; }
	.wiersz-slownika .slownik-prefiks { grid-area: prefiks; width: auto; }
	.wiersz-slownika .slownik-ukryty { grid-area: ukryty; }
	.wiersz-slownika .slownik-firmy { grid-area: firmy; width: auto; }
	.slownik-przyciski { grid-area: przyciski; margin-left: 0; justify-content: flex-start; }
	.slownik-przelamanie { display: none; }
	.wiersz-slownika.naglowek-slownika {
		display: grid;
		padding: 0 0 4px;
		font-size: var(--tekst-podpis);
		color: var(--tekst-3);
	}
}
.pudelko-logowania .znak-logowania { text-align: center; margin-bottom: 22px; }
.pudelko-logowania .znak-logowania img { width: 200px; height: auto; }
/* Nazwa firmy nadawcy zamiast logo na stronie wypisu (D715). */
.pudelko-logowania .znak-tekstowy { font-size: 1.25rem; font-weight: 600; color: var(--tekst); }
.pudelko-logowania h1 { font-size: 17px; font-weight: 600; margin: 0 0 18px; text-align: center; }
.pudelko-logowania .pole { margin-bottom: 14px; }
.pudelko-logowania .przycisk { width: 100%; text-align: center; }
.pudelko-logowania .stopka {
	margin-top: 20px;
	text-align: center;
	font-size: var(--tekst-drobny);
	color: var(--tekst-3);
}

/* --- stan pusty ----------------------------------------------------------- */

.pusto {
	background: var(--panel);
	border: 1px dashed var(--obramowanie);
	border-radius: var(--r);
	padding: 34px 26px;
	text-align: center;
	color: var(--tekst-2);
}
.pusto h2 { font-size: 16px; font-weight: 600; color: var(--tekst); margin: 0 0 8px; }
.pusto p { margin: 0 auto; max-width: 46ch; }
/* Dwa przyciski pustego stanu w jednym wierszu, na telefonie jeden pod
   drugim (2026-09-27, [[08_DECYZJE]] D685: „Załóż segment” i „Wgraj listę
   firm”). */
.pusto .pusto-przyciski {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 8px;
	margin-top: 14px;
}
/* `.pusto p` zeruje marginesy — zdanie dopisane pod akapitem ich potrzebuje. */
.pusto p.odstep-maly { margin-top: 8px; }

/* --- tabele --------------------------------------------------------------- */

/* Tabele bywają szersze niż ekran (osiem kolumn na liście firm). Przewijanie
   ma się dziać W ŚRODKU tego pudełka, nie w całej stronie — inaczej na
   telefonie ucieka nawigacja i nagłówek. */
/* `position: relative` (2026-09-27, D642): schowany nagłówek kolumny
   (`.tylko-dla-czytnika`, `position: absolute`) liczył położenie od strony,
   nie od pudełka, i wypychał CAŁĄ stronę w bok — na 390 px o 9–22 px. */
.przewijana { overflow-x: auto; position: relative; }

.tabela {
	width: 100%;
	border-collapse: collapse;
	background: var(--panel);
	border: 1px solid var(--obramowanie);
	border-radius: var(--r);
	overflow: hidden;
	font-size: var(--tekst-wiersz);
}

.tabela thead th {
	text-align: left;
	font-size: var(--tekst-drobny);
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: .04em;
	color: var(--tekst-2);
	background: var(--panel-2);
	padding: 10px 12px;
	border-bottom: 1px solid var(--obramowanie);
	white-space: nowrap;
}

.tabela td { padding: 10px 12px; border-bottom: 1px solid var(--obramowanie-2); }
.tabela tbody tr:last-child td { border-bottom: 0; }
.tabela tbody tr:hover { background: var(--panel-2); }

/* Wiersz z ostrzeżeniami — na całą szerokość, pod wierszem, którego dotyczy.
   W kolumnie łamały się co dwa słowa i rozpychały tabelę poza stronę:
   najważniejsze zdanie na ekranie było najtrudniejsze do przeczytania.
   Kreska u góry znika, żeby czytało się jak dopisek do wiersza wyżej,
   a nie jak osobny dostawca. */
.tabela tr.wiersz-ostrzezen td {
	padding-top: 0;
	background: var(--zly-tlo);
	border-top: 0;
}
.tabela tr.wiersz-ostrzezen:hover { background: transparent; }

/* KOLUMNA LICZBOWA — razem z nagłówkiem.
 *
 * Do 2026-09-10 stało tu samo `.liczbowo` o swoistości (0,1,0), a nagłówki
 * tabel mają regułę `.tabela thead th { text-align: left }` o swoistości
 * (0,1,2). Wygrywała ona ZAWSZE, niezależnie od kolejności w pliku — więc
 * w każdej tabeli liczby stały przy prawej krawędzi, a ich nagłówki przy
 * lewej. Trzydzieści cztery nagłówki w trzynastu szablonach: wszystkie
 * raporty, lista firm, ekran Zespołu, sekwencje.
 *
 * `.tabela thead th.liczbowo` (0,2,2) bije tamtą regułę bez podnoszenia
 * swoistości wszystkiego innego i bez `!important`.
 */
.liczbowo { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.tabela thead th.liczbowo { text-align: right; }

/* TABELA JAKO KARTY NA TELEFONIE (2026-10-02, [[08_DECYZJE]] D737).
   Historia importów, Segmenty, Duplikaty, porównanie przed scaleniem i import
   → kolumny przewijały się w bok w `.przewijana`, a przyciski (Wyklucz,
   Usuń, Porównaj, wybór pola) stały poza ekranem — nikt nie przewija tabeli
   w bok, żeby znaleźć przycisk. Poniżej 800 px wiersz jest kartą: komórki
   jedna pod drugą, każda z podpisem z `data-etykieta` (nagłówek kolumny
   znika). Ten sam pomysł co karty kolejki telefonów (D338), bez kolejności
   na sztywno: kolejność kart = kolejność kolumn. `.z-naglowkiem` zostawia
   nagłówek (porównanie: „Nr 38 — otwórz” to odnośniki do kartotek). */
@media (max-width: 800px) {
	.tabela-karty, .tabela-karty tbody, .tabela-karty tr { display: block; width: 100%; }
	.tabela-karty thead { display: none; }
	.tabela-karty.z-naglowkiem thead { display: block; }
	.tabela-karty.z-naglowkiem thead th { display: block; white-space: normal; border-bottom: 0; }
	.tabela-karty tr { padding: 8px 12px; border-bottom: 1px solid var(--obramowanie-2); }
	.tabela-karty tbody tr:last-child { border-bottom: 0; }
	.tabela-karty td,
	.tabela-karty tbody th { display: block; padding: 3px 0; border: 0; text-align: left; width: auto; }
	.tabela-karty td.liczbowo { text-align: left; white-space: normal; }
	.tabela-karty td[data-etykieta]::before {
		content: attr(data-etykieta) ": ";
		color: var(--tekst-2);
		font-size: var(--tekst-drobny);
	}
	.tabela-karty td:empty { display: none; }
}

/* Zespół: „▸ więcej”, „▸ Zmień hasło” i „Moje konto →” łamały się na 1440 px
   w dwie–trzy linie, strzałka osobno od słowa (2026-10-03, [[08_DECYZJE]] D794). */
.tabela-zespolu td > details > summary,
.tabela-zespolu td > a.pod { white-space: nowrap; }

/* Nazwy modeli w „Na co poszło” (Asystent AI): „gpt-6.1-sol” łamało się
   na „gpt-” i resztę — przeglądarka tnie na łączniku (2026-10-05, [[08_DECYZJE]] D802). */
.nazwy-modeli code { white-space: nowrap; }

/* NAGŁÓWEK SORTUJĄCY — cała szerokość komórki jest celem kliknięcia.
 *
 * `display: block` i `margin` ujemny o tyle, ile wynosi dopełnienie `th`:
 * odnośnik obejmuje wtedy komórkę, a nie sam napis. Przy nagłówku o dwóch
 * słowach („Ostatni kontakt") różnica to kilkadziesiąt pikseli celu. */
.naglowek-sortujacy {
	display: block;
	margin: -10px -12px;
	padding: 10px 12px;
	color: inherit;
	text-decoration: none;
	white-space: nowrap;
}
.naglowek-sortujacy:hover { color: var(--zielen); background: var(--obramowanie-2); }
.naglowek-sortujacy.biezacy { color: var(--zielen); }
/* Strzałka ma STAŁE miejsce, także gdy jest pusta — inaczej nagłówki
   przeskakują w bok przy każdej zmianie porządku. */
.strzalka-porzadku {
	display: inline-block;
	width: 10px;
	margin-left: 4px;
	font-weight: 400;
}

/* Komórka liczbowa powyżej progu wyłącznika. Kolor bierze się z tej samej
   wartości, którą kieruje się mechanizm zatrzymujący wysyłkę — zieleń przy
   wskaźniku, przy którym system właśnie stanął, byłaby gorsza niż jej brak. */
.liczbowo.zle { color: var(--zly); font-weight: 600; }
.liczbowo .pod { margin-left: 4px; }

/* --- plakietki ------------------------------------------------------------ */

.plakietka {
	display: inline-block;
	font-size: var(--tekst-plakietka);
	font-weight: 600;
	letter-spacing: .02em;
	padding: 2px 8px;
	border-radius: 20px;
	background: var(--zielen-mgla);
	color: var(--zielen-ciemna);
	white-space: nowrap;
}
.plakietka.zla { background: var(--zly-tlo); color: var(--zly); }

/* Plakietka ostrzegawcza — „dzwoniono dziś" w kolejce telefonów.
   Osobna od `.zla`, bo to nie jest błąd: telefon mógł być zasadny,
   a plakietka ma zatrzymać rękę na sekundę, nie zabronić. */
.plakietka.uwaga { background: var(--uwaga-tlo); color: var(--uwaga); }

/* --- filtr ---------------------------------------------------------------- */

.filtr {
	background: var(--panel);
	border: 1px solid var(--obramowanie);
	border-radius: var(--r);
	box-shadow: var(--cien);
	padding: 16px 18px;
	margin-bottom: 14px;
}
/* Wybór „czyje zadania" — jedna linia, nie siatka pól jak w filtrze firm.
   Trzy elementy w rzędzie na szerokim oknie, w kolumnie na telefonie:
   `flex-wrap` bez własnego progu, bo próg tu nic nie dodaje. */
.pasek-czyje {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 10px;
}
.pasek-czyje select { width: auto; min-width: 160px; }

/* `wrap`, bo ta linia niesie cztery rzeczy: pole szukania, listę segmentów
   (min. 180 px), „Filtruj" i czasem „Wyczyść". Przy 375 px treść ma po
   odjęciu dopełnienia około 307 px, więc bez zawijania pole szukania
   zostawało kilkanaście pikseli, a rząd wystawał poza stronę. Ten sam filtr
   stoi na liście firm, w lejku i w kolejce telefonów ([[08_DECYZJE]] D55) —
   czyli na trzech ekranach, na których handlowiec pracuje z telefonu. */
.filtr-linia { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 14px; }
.filtr-linia input[type="search"] { flex: 1 1 180px; }
.filtr-pola {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
	gap: 12px;
}
/* ZAWĘŻENIA JAKO POLA WYBORU (2026-09-10).
 *
 * Zastąpiły `<select multiple size="4">`, który wymagał ctrl+klik — wiedzy,
 * której nie ma skąd wziąć, a której brak kosztuje cicho: zwykłe kliknięcie
 * w drugą pozycję ODZNACZAŁO pierwszą.
 *
 * `max-height` zamiast `size="4"`: ta sama wysokość na ekranie, a przy
 * piętnastu rynkach lista przewija się w swoim pudełku, nie rozpycha filtra.
 * Ramka jest tu potrzebna — bez niej cztery grupy pól zlewają się w jedną
 * kolumnę i nie widać, gdzie kończy się „Rynek", a zaczyna „Język". */
.filtr-wybory {
	max-height: 104px;
	overflow-y: auto;
	padding: 6px 8px;
	border: 1px solid var(--obramowanie);
	border-radius: 6px;
	background: var(--panel);
}
.filtr-wybory label {
	display: flex;
	align-items: center;
	gap: 6px;
	margin: 0;
	padding: 2px 0;
	font-size: var(--tekst-drobny);
	font-weight: 400;
	/* Cel kliknięcia to CAŁY wiersz, nie sam kwadracik — przy piętnastu
	   pozycjach to różnica między wygodnym i męczącym filtrem. */
	cursor: pointer;
}
.filtr-wybory input[type="checkbox"] {
	width: auto;
	margin: 0;
	flex: none;
}
/* FILTR NAD LISTĄ, LEJKIEM I TELEFONAMI — WSZYSTKO WIDAĆ (2026-10-07,
 * [[08_DECYZJE]] D811). Okienko na cztery pozycje pokazywało 4 z 8 etapów
 * i 4 z 16 rynków, reszta przewijała się w pudełku — a pola chowa i tak
 * rozwijka „więcej filtrów”. Etapy, języki i typy w całości; rynki w dwóch
 * kolumnach, w grupie na dwie kolumny siatki (na telefonie — cały wiersz,
 * bo siatka ma tam dwie albo jedną kolumnę). Ekran segmentu ma swoje. */
.filtr .filtr-wybory { max-height: none; overflow-y: visible; }
.filtr .grupa-rynkow { grid-column: span 2; }
.filtr .grupa-rynkow .filtr-wybory { columns: 2; column-gap: 12px; }
.filtr .grupa-rynkow .filtr-wybory label { break-inside: avoid; }
@media (max-width: 640px) {
	.filtr .grupa-rynkow { grid-column: 1 / -1; }
}
/* Podpis GRUPY pól. Wygląda jak `label`, ale nim nie jest: `label for=`
   wskazujący na kontener byłby dla czytnika ekranu nieprawdą, więc grupa ma
   `role="group"` i `aria-labelledby`. */
.etykieta-grupy {
	display: block;
	font-size: var(--tekst-podpis);
	font-weight: 500;
	margin-bottom: 5px;
}

.pasek-wyniku {
	display: flex;
	align-items: center;
	justify-content: space-between;
	flex-wrap: wrap;
	gap: 10px;
	margin-bottom: 12px;
	font-size: var(--tekst-wiersz);
	color: var(--tekst-2);
}
.zapis-segmentu { display: flex; gap: 8px; }
.zapis-segmentu input[type="text"] { width: 180px; }


.stronicowanie {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 18px;
	margin-top: 16px;
	font-size: var(--tekst-wiersz);
	color: var(--tekst-2);
}

/* --- porównanie duplikatów (2026-09-17, D186) ---------------------- */

/* Wiersz, w którym kartoteki się różnią — tło uwagi, nie błędu: różnica nie
   jest usterką, tylko tym, na co trzeba spojrzeć przed wyborem. */
.porownanie-duplikatow th[scope="row"] {
	text-align: left;
	font-weight: 500;
	color: var(--tekst-2);
	white-space: nowrap;
	padding: 10px 12px;
	border-bottom: 1px solid var(--obramowanie-2);
}
.porownanie-duplikatow tr.rozni-sie td,
.porownanie-duplikatow tr.rozni-sie th[scope="row"] { background: var(--uwaga-tlo); }
.scalenie-w-dwie-strony {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
	gap: 16px;
	margin-top: 16px;
}

/* --- skrzynka pocztowa (2026-09-17, D182) ----------------------------- */

/* Foldery po lewej, lista po prawej — układ, który zna każdy z Outlooka.
   Pod 800 px foldery idą nad listę (reguła niżej), bo obok siebie na
   telefonie zostałoby na temat wiadomości sto pikseli. */
.skrzynka {
	display: grid;
	grid-template-columns: minmax(180px, 240px) minmax(0, 1fr);
	gap: 16px;
	align-items: start;
}
.foldery-skrzynki ul { list-style: none; margin: 8px 0 0; padding: 0; }
.foldery-skrzynki a {
	display: flex;
	align-items: center;
	gap: 8px;
	padding: 7px 10px;
	border-radius: var(--r);
	color: var(--tekst-2);
	text-decoration: none;
	font-size: var(--tekst-wiersz);
}
.foldery-skrzynki a:hover { background: var(--panel-2); color: var(--tekst); }
.foldery-skrzynki a[aria-current="page"] {
	background: var(--zielen-mgla);
	color: var(--zielen-ciemna);
	font-weight: 600;
}
.adres-skrzynki { margin: 4px 0 0; overflow-wrap: anywhere; }

.szukaj-w-skrzynce { display: flex; gap: 8px; margin-bottom: 10px; }
.szukaj-w-skrzynce input[type="search"] { flex: 1 1 auto; }

/* Przełącznik dwóch widoków tej samej listy — nie filtr w formularzu i nie
   akcja w nagłówku. Wybrany wygląda jak wybrana zakładka, bo tym jest. */
.przelacznik-widoku {
	display: inline-flex;
	border: 1px solid var(--obramowanie);
	border-radius: var(--r);
	overflow: hidden;
	margin-bottom: 12px;
	font-size: var(--tekst-podpis);
}
.przelacznik-widoku a {
	padding: 6px 14px;
	color: var(--tekst-2);
	text-decoration: none;
	background: var(--panel);
}
.przelacznik-widoku a + a { border-left: 1px solid var(--obramowanie); }
/* Przełącznik i „?” z instrukcją w jednym rzędzie — także na telefonie, gdzie
   znak spadał sam do nowej linii (2026-10-07, [[08_DECYZJE]] D811). */
.przelacznik-z-pomoca { display: flex; align-items: center; gap: 2px; margin-bottom: 12px; }
.przelacznik-z-pomoca .przelacznik-widoku { margin-bottom: 0; }
.przelacznik-widoku a[aria-current="true"] {
	background: var(--zielen-mgla);
	color: var(--zielen-ciemna);
	font-weight: 600;
}

.tabela-skrzynki td.kto { white-space: nowrap; max-width: 260px; overflow: hidden; text-overflow: ellipsis; }
.tabela-skrzynki tr.nieprzeczytana td { font-weight: 600; color: var(--tekst); }
.tabela-skrzynki tr.nieprzeczytana td.kto { box-shadow: inset 3px 0 0 var(--zielen); }

.lista-zalacznikow { list-style: none; margin: 8px 0 0; padding: 0; }
.lista-zalacznikow li { padding: 4px 0; overflow-wrap: anywhere; }

.tresc-maila {
	margin: 0;
	white-space: pre-wrap;
	overflow-wrap: anywhere;
	font: inherit;
	font-size: var(--tekst-wiersz);
	line-height: 1.55;
}
.ramka-maila {
	display: block;
	width: 100%;
	height: 70vh;
	min-height: 420px;
	border: 1px solid var(--obramowanie-2);
	border-radius: var(--r);
	background: var(--panel);
}
/* `minmax(0, …)`, nie `1fr` (2026-10-03, [[08_DECYZJE]] D794): `1fr` to
   `minmax(auto, 1fr)`, więc kolumna „Od” (`nowrap`) rozpychała stronę na
   390 px o 145 px w bok. */
@media (max-width: 800px) {
	.skrzynka { grid-template-columns: minmax(0, 1fr); }
}

/* Na telefonie foldery jako jedna lista wyboru (2026-09-19, D349): pełny
   pasek nad listą spychał pierwszą wiadomość półtora ekranu w dół. „Nowy
   folder” i ściągawka skrótów klawiszowych na ekranie dotykowym nic nie dają. */
.foldery-waskie { display: none; }
@media (max-width: 800px) {
	.foldery-waskie { display: flex; align-items: center; gap: 8px; margin-top: 4px; }
	.foldery-waskie select { flex: 1 1 auto; min-width: 0; }
	.foldery-skrzynki .foldery-szerokie,
	.foldery-skrzynki .nowy-folder,
	.foldery-skrzynki .skroty-poczty { display: none; }
}

/* --- pełna poczta (2026-09-18, D270) --------------------------------- */

/* „Napisz” na górze paska folderów — pierwsza rzecz po przeczytaniu poczty. */
.foldery-skrzynki .przycisk.napisz {
	display: block;
	text-align: center;
	margin-bottom: 10px;
	padding: 9px 12px;
	color: var(--na-zieleni);
	font-weight: 600;
}
.foldery-skrzynki .przycisk.napisz:hover { color: var(--na-zieleni); background: var(--zielen-ciemna); }
.nowy-folder { margin-top: 10px; border-top: 1px solid var(--obramowanie-2); padding-top: 8px; }
.nowy-folder summary {
	cursor: pointer;
	font-size: var(--tekst-podpis);
	color: var(--tekst-2);
	padding: 4px 10px;
}
.nowy-folder form { padding: 6px 4px 0; }

.naglowek-folderu {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 8px 12px;
	margin-bottom: 10px;
}
.naglowek-folderu h2 { margin: 0; font-size: var(--tekst-bazowy); }
.akcje-folderu { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.menu-folderu { position: relative; }
.menu-folderu summary { list-style: none; }
.menu-folderu summary::-webkit-details-marker { display: none; }
.menu-folderu > .karta {
	position: absolute;
	right: 0;
	top: calc(100% + 4px);
	z-index: 30;
	width: 280px;
	box-shadow: var(--cien);
}

/* Pasek akcji nad listą i nad wiadomością. Grupy oddzielone odstępem, nie
   kreską: przeczytane/gwiazdka — porządki; archiwum/spam/kosz — wynosi
   z folderu; „Przenieś do” — osobno, bo ma własne pole. */
.pasek-poczty {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px 16px;
	padding: 8px 10px;
	margin-bottom: 10px;
	background: var(--panel);
	border: 1px solid var(--obramowanie-2);
	border-radius: var(--r);
}
.pasek-poczty-formularz { display: contents; }
.grupa-przyciskow { display: inline-flex; flex-wrap: wrap; gap: 6px; }
.przenies-do { display: inline-flex; align-items: center; gap: 6px; }
.przenies-do select { width: auto; max-width: 200px; padding: 4px 8px; }
.zaznacz-wszystkie { display: inline-flex; align-items: center; gap: 6px; cursor: pointer; }
.zaznacz-wszystkie input { width: auto; margin: 0; }
.przycisk.niebezpieczny { color: var(--zly); }
.przycisk.niebezpieczny:hover { background: var(--zly-tlo); color: var(--zly); }

.sasiednie { margin-left: auto; display: inline-flex; gap: 14px; font-size: var(--tekst-podpis); }

/* Gwiazdka — przycisk bez obramowania, pusta albo pełna. */
.kolumna-gwiazdki { width: 30px; text-align: center; padding-left: 0; padding-right: 0; }
.gwiazdka {
	background: none;
	border: 0;
	padding: 0 2px;
	font-size: 17px;
	line-height: 1;
	color: var(--tekst-3);
	cursor: pointer;
}
.gwiazdka:hover { color: var(--uwaga); }
.gwiazdka.wlaczona { color: var(--uwaga); }
.przycisk.z-gwiazdka { color: var(--uwaga); }

.czytanie { min-width: 0; display: flex; flex-direction: column; gap: 12px; }
.czytanie > .karta { margin: 0; }
.czytanie > .pasek-poczty { margin: 0; }
.w-kartotece {
	margin: 10px 0 0;
	padding-top: 10px;
	border-top: 1px solid var(--obramowanie-2);
	font-size: var(--tekst-wiersz);
}

/* Podpowiedzi adresów — ta sama lista co przy szukaniu w boku, pod polem. */
.pole-adresow { position: relative; }
.pole-adresow summary {
	cursor: pointer;
	font-size: var(--tekst-podpis);
	color: var(--tekst-2);
	margin-bottom: 6px;
}
.podpowiedzi-adresow { top: auto; margin-top: 4px; }
.przyciski-pisania { display: flex; flex-wrap: wrap; gap: 8px; }

/* Strona do wydruku (`poczta/druk.html`) — bez menu, sama wiadomość. */
body.wydruk { background: var(--panel); }
.wydruk-maila { max-width: 760px; margin: 24px auto; padding: 0 16px; }
.wydruk-maila h1 { font-size: var(--tekst-naglowek); margin: 8px 0 14px; }
.wydruk-maila .tresc-maila { margin-top: 16px; border-top: 1px solid var(--obramowanie); padding-top: 16px; }
@media print {
	.nie-drukuj { display: none !important; }
	.wydruk-maila { margin: 0; max-width: none; padding: 0; }
}

@media (max-width: 800px) {
	.sasiednie { margin-left: 0; }
	.menu-folderu > .karta { right: auto; left: 0; }
}

/* --- poczta: edytor, skróty, licznik, szukanie wszędzie (2026-09-18, D271) --- */

.szukaj-wszedzie { white-space: nowrap; font-size: var(--tekst-podpis); align-self: center; }

/* Wiersz pod kursorem klawiatury (j/k) — ta sama mgła co wybrany folder. */
.tabela-skrzynki tr.pod-kursorem td { background: var(--zielen-mgla); }

.skroty-poczty { margin-top: 10px; border-top: 1px solid var(--obramowanie-2); padding-top: 8px; }
.skroty-poczty summary { cursor: pointer; font-size: var(--tekst-podpis); color: var(--tekst-2); padding: 4px 10px; }
.skroty-poczty .dane { font-size: var(--tekst-drobny); margin: 6px 4px 0; }
kbd {
	display: inline-block;
	padding: 0 5px;
	font: inherit;
	font-family: var(--mono);
	font-size: var(--tekst-plakietka);
	line-height: 1.6;
	border: 1px solid var(--obramowanie);
	border-bottom-width: 2px;
	border-radius: 4px;
	background: var(--panel-2);
	color: var(--tekst);
}

/* Licznik nieprzeczytanych: liczba przy zakładce, kropka przy „Poczta” w menu. */
.zakladki .licznik-menu { margin-left: 6px; }
.kropka-poczty {
	width: 8px;
	height: 8px;
	margin-left: auto;
	border-radius: 50%;
	background: var(--info);
	flex: 0 0 auto;
}
.kropka-poczty + .licznik-menu, .licznik-menu + .kropka-poczty { margin-left: 6px; }

/* Edytor treści — pasek nad polem, pole wygląda jak zwykłe pole tekstowe. */
.edytor {
	border: 1px solid var(--obramowanie);
	border-radius: 6px;
	background: var(--panel);
}
.edytor:focus-within { border-color: var(--zielen); box-shadow: 0 0 0 3px var(--zielen-mgla); }
.pasek-edytora {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 4px;
	padding: 6px;
	border-bottom: 1px solid var(--obramowanie-2);
	background: var(--panel-2);
	border-radius: 6px 6px 0 0;
}
.pasek-edytora button {
	min-width: 32px;
	padding: 4px 8px;
	font: inherit;
	font-size: var(--tekst-podpis);
	color: var(--tekst);
	background: var(--panel);
	border: 1px solid var(--obramowanie);
	border-radius: 4px;
	cursor: pointer;
}
.pasek-edytora button:hover { background: var(--zielen-mgla); }
.odstep-paska { width: 8px; }
.pole-edytora {
	min-height: 320px;
	max-height: 70vh;
	overflow-y: auto;
	padding: 10px 12px;
	font-size: var(--tekst-wiersz);
	line-height: 1.55;
	outline: none;
	overflow-wrap: anywhere;
}
.pole-edytora blockquote { margin: 6px 0; padding-left: 12px; border-left: 3px solid var(--obramowanie); color: var(--tekst-2); }
.pole-edytora ul, .pole-edytora ol { margin: 6px 0; padding-left: 24px; }

/* Miniatura zdjęcia z załącznika — klik otwiera całość w nowej karcie. */
.miniatura-zalacznika { display: block; margin-bottom: 4px; }
.miniatura-zalacznika img {
	display: block;
	max-width: 220px;
	max-height: 160px;
	border: 1px solid var(--obramowanie-2);
	border-radius: 4px;
}

/* --- kartoteka ------------------------------------------------------------ */

.kartoteka {
	display: grid;
	grid-template-columns: minmax(260px, 340px) 1fr;
	gap: 16px;
	align-items: start;
}
.kolumna-lewa, .kolumna-prawa { display: flex; flex-direction: column; gap: 16px; min-width: 0; }

/* EKRAN, NA KTÓRYM SIĘ PISZE — odwrotne proporcje (2026-09-15).

   `.kartoteka` ma lewą kolumnę 260–340 px, bo powstała pod KARTĘ DANYCH
   firmy: nazwa, NIP, adres, telefon. Ustawienia kampanii używają tego samego
   układu, tylko odwrotnie — po lewej stoi to, co się PISZE (temat, treść,
   wersje językowe), a po prawej kartki ustawień. Skutek był mierzalny:
   pole treści i podgląd wiadomości dzieliły między siebie **302 px**, podczas
   gdy „Kto dostanie" i „Kiedy wychodzi" miały do dyspozycji ponad tysiąc.

   Zmierzone w przeglądarce przy oknie 1500 px, po dołożeniu ramki
   z gotową wiadomością ([[08_DECYZJE]] D174): grid `.edytor-z-podgladem`
   nie miał jak rozłożyć się na dwie kolumny, bo `minmax(360px, 1fr)`
   nie mieści się dwa razy w trzystu pikselach.

   Zwężenie pod 1040 px obsługuje ta sama reguła co `.kartoteka` niżej —
   jedna kolumna. Tylko że dwie klasy przebijały ją wagą i na telefonie
   zostawały dwie kolumny (zmierzone 2026-10-03 na ekranie skrzynki,
   [[08_DECYZJE]] D794) — stąd próg, jak przy `.rowno` niżej. */
@media (min-width: 1041px) {
	.kartoteka.pisanie { grid-template-columns: minmax(0, 2fr) minmax(280px, 1fr); }
}

/* PRZEGLĄD WYSYŁKI — dwie równe kolumny (2026-09-26): po lewej „Ustawienia”,
   po prawej karta włącznika z ramkami „Zanim włączysz” i prognozą. W układzie
   karty danych (260–340 px) włącznik stał pod ustawieniami, karta miała trzy
   ekrany wysokości, a prawa połowa okna była pusta.

   Tylko powyżej 1040 px: dwie klasy przebijają `.kartoteka` z reguł wąskich
   ekranów niżej, więc bez tego progu kolumny nie schodziłyby do jednej. */
@media (min-width: 1041px) {
	.kartoteka.rowno { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
}

/* HISTORIA FIRMY W JEDNEJ KOLUMNIE (2026-09-27, [[08_DECYZJE]] D638).
   Pod 1040 px kolumny stają jedna pod drugą — cała lewa (osoby, połączenia,
   „dlaczego nie dostaje maili”, dane firmy), potem prawa. Pole „Co się
   wydarzyło” stało przez to na telefonie 1400–1900 px od góry, czyli dwa
   ekrany przewijania po każdej rozmowie. `display: contents` rozpuszcza obie
   kolumny, a `order` układa karty: osoby (numery do dzwonienia), pilne
   (briefing, rozmowy bez wyniku), notatka, reszta, oś czasu na końcu.
   Na szerokim ekranie nic się nie zmienia — dwie kolumny jak dotąd. */
@media (max-width: 1040px) {
	.kartoteka.historia-firmy { display: flex; flex-direction: column; }
	.historia-firmy > .kolumna-lewa, .historia-firmy > .kolumna-prawa { display: contents; }
	.historia-firmy > .kolumna-lewa > .karta,
	.historia-firmy > .kolumna-prawa > .karta { order: 3; min-width: 0; }
	.historia-firmy > .kolumna-lewa > .karta:first-child { order: 0; }
	.historia-firmy > .kolumna-prawa > #panel-briefing,
	.historia-firmy > .kolumna-prawa > #panel-wynik { order: 1; }
	.historia-firmy > .kolumna-prawa > #panel-notatka { order: 2; }
	.historia-firmy > .kolumna-prawa > #historia { order: 4; }
}

.dane { display: grid; grid-template-columns: auto 1fr; gap: 6px 14px; margin: 0; font-size: var(--tekst-wiersz); }
.dane dt { color: var(--tekst-2); }
.dane dd { margin: 0; overflow-wrap: anywhere; }

.osoba { padding: 10px 0; border-bottom: 1px solid var(--obramowanie-2); }
.osoba:last-child { border-bottom: 0; padding-bottom: 0; }
.osoba-imie { font-weight: 600; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.osoba-pod { font-size: var(--tekst-podpis); color: var(--tekst-2); overflow-wrap: anywhere; }
.osoba-pod.ostrzezenie { color: var(--uwaga); }

/* Wykluczonego NIE ukrywamy — ma być widoczny i wyraźnie oznaczony.
   Ukrycie kończy się dopisaniem tej samej osoby drugi raz. */
.osoba.wykluczona .osoba-imie { color: var(--tekst-3); }

.formularz-notatki textarea { margin-bottom: 10px; }
.linia-notatki { display: flex; gap: 10px; align-items: center; }
/* `width: auto` — lista wyboru nie schodzi poniżej swojej treści
   (2026-09-27, [[08_DECYZJE]] D621). Z regułą bazową `width: 100%` pole
   jest dla przeglądarki „ściśliwe”: w rzędzie z polem daty albo długim
   podpisem kurczyło się do samej strzałki. Zmierzone: „Kogo dotyczy”
   w Zadaniach firmy 24 px, rola w Zespole 72 px („użytk…”), godziny okna
   wysyłki na telefonie 24 px. `max-width` — długa pozycja nie wypycha
   strony w bok. */
.linia-notatki select { flex: 1; width: auto; max-width: 100%; }
/* Hasło w wierszu Zespołu (2026-10-02, [[08_DECYZJE]] D770) — w wąskiej
   kolumnie tabeli pole kurczyło się do ok. 40 px i z podpowiedzi zostawało
   „mir”. Wiersz się zawija — przycisk „Zapisz” schodzi pod pole, zamiast
   wypychać tabelę w bok. */
.linia-notatki:has(> input[type="password"]) { flex-wrap: wrap; }
.linia-notatki input[type="password"] { flex: 1 1 9em; min-width: 9em; }
/* „Prośba klienta o dane” na Rejestrze zgód (D811) — przycisk nie łamie się
   na dwie linie obok pola adresu. */
.prosba-o-dane .przycisk { flex: none; }
/* Narzędzia asystenta nad „Wyślij” (2026-09-27, D645) — zawijają się na
   telefonie; lista języków nie zwija się do samej strzałki. */
.linia-asystenta { flex-wrap: wrap; }
.linia-asystenta select { min-width: 9em; }

/* „Co się wydarzyło" (2026-09-17, D184). Pole wyniku istnieje tylko dla
   rozmowy — pokazuje je `:has()`, bez skryptu. Bez obsługi `:has()` pole
   zostaje schowane, a serwer i tak odmówi rozmowy bez wyniku z czytelnym
   zdaniem, więc nic się nie zapisze po cichu źle. */
.formularz-wpisu .przelacznik-widoku { margin-bottom: 10px; }
.przelacznik-widoku label {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	margin: 0;
	padding: 6px 14px;
	color: var(--tekst-2);
	background: var(--panel);
	font-weight: 500;
	cursor: pointer;
}
.przelacznik-widoku label + label { border-left: 1px solid var(--obramowanie); }
.przelacznik-widoku label:has(input:checked) {
	background: var(--zielen-mgla);
	color: var(--zielen-ciemna);
	font-weight: 600;
}
.formularz-wpisu .tylko-rozmowa { display: none; }
.formularz-wpisu:has(input[name="rodzaj"][value="rozmowa"]:checked) .tylko-rozmowa { display: block; }
.nastepny-krok-wpisu { margin-top: 10px; }
.nastepny-krok-wpisu > summary { cursor: pointer; color: var(--zielen); }
.nastepny-krok-wpisu input[type="date"] { max-width: 170px; }
.zapis-rozmowy { display: inline-block; margin-top: 6px; color: var(--zielen); }

/* --- oś czasu ------------------------------------------------------------- */

.zdarzenie {
	padding: 12px 0 12px 14px;
	border-bottom: 1px solid var(--obramowanie-2);
	border-left: 3px solid var(--obramowanie);
	margin-left: 2px;
}
.zdarzenie:last-child { border-bottom: 0; }

/* Kolor paska koduje typ zdarzenia — na długiej osi czasu to szybsze
   niż czytanie plakietek. Kolory semantyczne, nie akcentowe.

   Do 2026-09-09 obietnica obejmowała PIĘĆ typów z ośmiu
   (`kontakty.models.TypZdarzenia`). Notatka, zadanie i odpowiedź
   automatyczna spadały na domyślną szarość z `.zdarzenie` — czyli na ten
   sam kolor, co świadomie szary `typ-import`.
   Skutek był odwrotny do zamierzonego: **najczęstszy wpis handlowca —
   notatka po rozmowie — nie miał własnego koloru**, a „jestem na urlopie"
   wyglądało jak wpis importu. Obietnica „skanujesz wzrokiem" nie działała
   dokładnie tam, gdzie skanuje się najwięcej ([[08_DECYZJE]] D74).

   `mail_auto` dostaje TEN SAM odcień co `mail_przy`, tylko przygaszony:
   to nadal poczta przychodząca, tyle że nie od człowieka. Osobny kolor
   sugerowałby osobną kategorię zdarzeń, a autoresponder jest odmianą
   maila, nie czymś obok. */
.zdarzenie.typ-mail_wy   { border-left-color: var(--info); }
.zdarzenie.typ-mail_przy { border-left-color: var(--dobry); }
.zdarzenie.typ-mail_auto { border-left-color: var(--dobry-tlo); }
.zdarzenie.typ-telefon   { border-left-color: var(--uwaga); }
.zdarzenie.typ-notatka   { border-left-color: var(--tekst-2); }
.zdarzenie.typ-zadanie   { border-left-color: var(--zly-tlo); }
.zdarzenie.typ-etap      { border-left-color: var(--zielen); }
.zdarzenie.typ-import    { border-left-color: var(--obramowanie); }
/* Zmiana danych kartoteki — szara jak import i z tego samego powodu:
   to jest zdarzenie ADMINISTRACYJNE, nie kontakt z klientem. Kolor akcentu
   stawiałby ją w jednym rzędzie z rozmową i mailem, a na osi czasu szuka się
   rozmów. Odróżnia się od importu tym, że ma autora i treść. */
.zdarzenie.typ-dane      { border-left-color: var(--obramowanie); }
/* SMS z klientem (2026-10-05, [[08_DECYZJE]] D807) — kolory jak mail w tę samą stronę. */
.zdarzenie.typ-sms_przy  { border-left-color: var(--dobry); }
.zdarzenie.typ-sms_wy    { border-left-color: var(--info); }

/* Skąd poszła wiadomość — plakietka przy zdarzeniu na osi czasu (D75).
   Mail z kampanii, krok sekwencji i list napisany ręcznie to ten sam
   `typ=mail_wy`; bez tej plakietki handlowiec czytał „mail wysłany 12.08"
   i nie wiedział, czy pisał sam, czy klient dostał masówkę. */
.plakietka.zrodlo {
	background: var(--info-tlo);
	color: var(--info);
}
.plakietka.zrodlo a { color: inherit; }

.zdarzenie-glowka {
	display: flex;
	align-items: center;
	gap: 8px;
	flex-wrap: wrap;
	font-size: var(--tekst-drobny);
	color: var(--tekst-2);
	margin-bottom: 4px;
}
.zdarzenie-tytul { font-weight: 600; }
.zdarzenie-tresc { font-size: var(--tekst-wiersz); overflow-wrap: anywhere; }

.pod { font-size: var(--tekst-drobny); color: var(--tekst-3); }

/* --- wyjaśnienia „?" ------------------------------------------------------
   Znak zapytania przy nazwie ustawienia; po najechaniu albo po wejściu
   klawiszem Tab pokazuje zdanie wyjaśniające, co ta rzecz robi.

   Dlaczego `wyjasnienie`, a nie `podpowiedz`
   ------------------------------------------
   Klasa `.podpowiedz` **była już zajęta**: opisuje blok podpowiedzi asystenta
   AI w kartotece i podpisy pod polami na ekranie skrzynki pocztowej. Pierwsza
   wersja tego komponentu nazywała się tak samo i nadpisała tamte reguły —
   pola skrzynki dostały `display: inline-block` i `line-height: 0`, a znak
   zapytania dostał ramkę i 12 px odstępu z reguły asystenta i przez to
   spadał pod tekst etykiety.

   Żadna kontrola tego nie złapała: `sprawdz-tokeny.py` pilnuje wariantów klas
   (`.komunikat.zly`), a nie kolizji nazw. Wyszło dopiero przy obejrzeniu
   ekranu w przeglądarce.

   Dlaczego <button>, a nie sam :hover na <span>
   ---------------------------------------------
   Na telefonie i tablecie `:hover` nie istnieje — dymek pokazany wyłącznie
   po najechaniu myszą jest tam niewidoczny na zawsze. Przycisk da się
   dotknąć, dostaje wtedy focus i `:focus-within` odsłania treść. Ten sam
   mechanizm obsługuje klawiaturę, więc nie ma osobnej ścieżki dla nikogo.

   `aria-label` i `role="tooltip"` są po to, żeby czytnik ekranu przeczytał
   wyjaśnienie, a nie sam znak zapytania — „pytajnik” bez treści jest gorszy
   niż brak przycisku.

   Treść nie znika sama i nie przykrywa pola formularza: dymek wychodzi POD
   znakiem, a nie nad nim, bo pod spodem zwykle jest opisywane pole. */
.wyjasnienie {
	position: relative;
	display: inline-block;
	vertical-align: middle;
	margin-left: 5px;
	/* Zerowy strut, żeby wysokość brała się z samego przycisku. Przy
	   `line-height: 1` kontener miał 29 px zamiast 16 i rozpychał wiersz. */
	line-height: 0;
}

.wyjasnienie-znak {
	width: 16px;
	height: 16px;
	padding: 0;
	border: 1px solid var(--obramowanie);
	border-radius: 50%;
	background: var(--panel-2);
	/* --tekst-2, nie --tekst-3: znak jest mały, a drobny tekst w jasnym
	   odcieniu przestaje być widoczny wcześniej niż duży. */
	color: var(--tekst-2);
	font: 600 11px/14px var(--sans);
	cursor: help;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	transition: background .12s, border-color .12s, color .12s;
}

.wyjasnienie-znak:hover,
.wyjasnienie-znak:focus-visible {
	background: var(--zielen-mgla);
	border-color: var(--zielen);
	color: var(--zielen);
}
.wyjasnienie-znak:focus-visible {
	outline: 2px solid var(--zielen);
	outline-offset: 2px;
}
/* Znak-odnośnik do rozdziału instrukcji (2026-10-07, [[08_DECYZJE]] D811). */
a.wyjasnienie-znak { text-decoration: none; cursor: pointer; }

.wyjasnienie-tresc {
	position: absolute;
	top: calc(100% + 7px);
	/* Dymek wyrasta W PRAWO od znaku, a nie jest wyśrodkowany pod nim.
	   Wyśrodkowany (`left: 50%; translateX(-50%)`) urywał się na lewej
	   krawędzi ekranu: etykiety stoją przy lewym brzegu karty, więc połowa
	   280-pikselowego dymka wychodziła poza stronę. Widać to było dopiero
	   na wąskim oknie — na szerokim treść jest odsunięta menu bocznym. */
	left: 0;
	z-index: 30;
	width: max-content;
	/* Nigdy szerszy niż okno. Bez tego na telefonie sam dymek wymusza
	   poziome przewijanie strony. */
	max-width: min(280px, calc(100vw - 28px));
	padding: 9px 11px;
	border: 1px solid var(--obramowanie);
	border-radius: var(--r);
	background: var(--panel);
	box-shadow: var(--cien);
	/* --tekst, nie --tekst-3: to jest treść do przeczytania, a nie podpis
	   pod czymś. Drobny szary tekst w dymku czyta się źle. */
	color: var(--tekst);
	font-size: var(--tekst-drobny);
	font-weight: 400;
	line-height: 1.5;
	text-align: left;
	text-transform: none;
	letter-spacing: normal;
	white-space: normal;
	/* `visibility`, nie `display`: przejście działa, a czytnik ekranu i tak
	   dostaje treść przez `aria-label` na przycisku. */
	visibility: hidden;
	opacity: 0;
	transition: opacity .12s, visibility .12s;
}

.wyjasnienie:hover .wyjasnienie-tresc,
.wyjasnienie:focus-within .wyjasnienie-tresc {
	visibility: visible;
	opacity: 1;
}

/* Przy prawej krawędzi dymek wyrastający w prawo wystaje poza stronę.
   Wariant przyklejany do prawej — używaj przy polach w prawej kolumnie. */
.wyjasnienie.do-prawej .wyjasnienie-tresc {
	left: auto;
	right: 0;
}

.wyjasnienie-tresc code {
	font-size: 11.5px;
	background: var(--panel-2);
}

/* W nagłówku karty (`.etykieta`) tekst jest WERSALIKAMI i rozstrzelony —
   dymek musi z tego wyjść, inaczej wyjaśnienie jest nieczytelne. */
.karta .etykieta .wyjasnienie-znak { text-transform: none; letter-spacing: normal; }
/* Adres e-mail w takim nagłówku też: „JEAN.MEIER@FENSTER-MEIER-GMBH.EXAMPLE”
   wersalikami czyta się jak kod, a adres trzeba umieć przepisać. */
.karta .etykieta .adres-w-etykiecie { text-transform: none; letter-spacing: normal; }

@media (prefers-reduced-motion: reduce) {
	.wyjasnienie-tresc, .wyjasnienie-znak { transition: none; }
}

/* Rozwijka z wariantami nagłówków na ekranie importu. Domyślnie zwinięta:
   potrzebna raz, przy pierwszym imporcie, a rozwinięta na stałe przykryłaby
   formularz, do którego się w niej zagląda. */
details.pod > summary {
	cursor: pointer;
	color: var(--zielen);
	padding: 6px 0;
}
details.pod > summary:focus-visible {
	outline: 2px solid var(--zielen);
	outline-offset: 2px;
}
.tabelka-kolumn { border-collapse: collapse; margin: 6px 0 10px; }
.tabelka-kolumn th {
	text-align: left;
	vertical-align: top;
	padding: 3px 12px 3px 0;
	font-weight: 600;
	white-space: nowrap;
}
.tabelka-kolumn td { padding: 3px 0; color: var(--tekst-3); }

/* --- formularze na kartach ------------------------------------------------ */

.formularz .pole { margin-bottom: 16px; }
.formularz .filtr-pola { margin-bottom: 16px; }
.zgoda label { display: flex; align-items: center; gap: 8px; font-weight: 400; }
.zgoda input[type="checkbox"] { width: auto; }

code {
	font-family: var(--mono);
	font-size: .9em;
	background: var(--panel-2);
	border: 1px solid var(--obramowanie-2);
	border-radius: 4px;
	padding: 1px 5px;
}

/* --- tablica lejka -------------------------------------------------------- */

/* Kolumny przewijają się w poziomie WEWNĄTRZ tablicy. Przewijanie całej
   strony zabrałoby nawigację poza ekran przy siedmiu etapach. */
.tablica {
	display: flex;
	gap: 12px;
	overflow-x: auto;
	padding-bottom: 10px;
	align-items: flex-start;
	/* Nadpisuje `lejek.js` — od miejsca, w którym tablica się zaczyna (D733). */
	--wysokosc-kolumny: calc(100vh - 220px);
}

.kolumna {
	flex: 0 0 240px;
	background: var(--panel-2);
	border: 1px solid var(--obramowanie);
	border-radius: var(--r);
	display: flex;
	flex-direction: column;
	/* Wysokość od miejsca, w którym tablica się zaczyna — liczy `lejek.js`,
	   żeby pasek przewijania tablicy był w oknie (2026-10-02, D733). Bez
	   skryptu — jak dotąd. */
	max-height: var(--wysokosc-kolumny);
}

/* KOLUMNY POZA EKRANEM (2026-10-02, [[08_DECYZJE]] D733). Przy 1440 px
   ostatnie kolumny stały za prawą krawędzią bez żadnego znaku, że są.
   Przycisk „Jeszcze N kolumn: … →” nad tablicą (z `lejek.js`) i cień przy
   krawędzi, za którą coś jest. */
.tablica-ramka { position: relative; }
.tablica-ramka::before,
.tablica-ramka::after {
	content: "";
	position: absolute;
	top: 0;
	bottom: 10px;
	width: 28px;
	pointer-events: none;
	opacity: 0;
	transition: opacity .15s;
}
.tablica-ramka::before { left: 0; background: linear-gradient(to left, transparent, rgba(0, 0, 0, .10)); }
.tablica-ramka::after { right: 0; background: linear-gradient(to right, transparent, rgba(0, 0, 0, .10)); }
.tablica-ramka.wiecej-z-lewej::before,
.tablica-ramka.wiecej-z-prawej::after { opacity: 1; }
.tablica-poza-ekranem { display: flex; flex-wrap: wrap; gap: 6px 8px; margin: 0 0 8px; }
.tablica-poza-ekranem[hidden] { display: none; }
.tablica-poza-ekranem .przycisk:last-child { margin-left: auto; }

/* Etapy końcowe wyciszamy — to archiwum, nie miejsce codziennej pracy. */
.kolumna.koncowa { opacity: .78; }

/* Kolumna pod przeciąganą kartą. Zmiana tła I obramowania, nie samego koloru
   — po samym odcieniu trudno poznać cel przy dużej tablicy. */
.kolumna.cel {
	background: var(--zielen-mgla);
	border-color: var(--zielen);
}

.kolumna-glowka {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 8px;
	padding: 10px 12px;
	font-size: var(--tekst-podpis);
	font-weight: 600;
	border-bottom: 1px solid var(--obramowanie);
	position: sticky;
	top: 0;
	background: var(--panel-2);
	border-radius: var(--r) var(--r) 0 0;
}

/* Kolumna końcowa zwinięta do paska (2026-09-17, D185) — patrz lejek.js.
   Nazwa pionowo, pod nią liczba i przycisk. Karty schowane, upuszczanie
   działa dalej, bo celem jest cała `.kolumna`. */
.kolumna.zwinieta { flex: 0 0 64px; }
.kolumna.zwinieta .kolumna-karty { display: none; }
.kolumna.zwinieta .kolumna-glowka {
	flex-direction: column;
	justify-content: flex-start;
	min-height: 220px;
	padding: 10px 4px;
	border-bottom: 0;
	border-radius: var(--r);
}
.kolumna.zwinieta .nazwa-kolumny { writing-mode: vertical-rl; transform: rotate(180deg); }
.zwin-kolumne {
	margin-left: 4px;
	padding: 1px 6px;
	font: inherit;
	font-size: var(--tekst-plakietka);
	font-weight: 500;
	color: var(--zielen);
	background: transparent;
	border: 1px solid var(--obramowanie);
	border-radius: 10px;
	cursor: pointer;
}
.kolumna.zwinieta .zwin-kolumne { margin: 6px 0 0; }

/* Co dalej z tą firmą — najbliższe otwarte zadanie albo jego brak. */
.karta-krok {
	margin-top: 6px;
	font-size: var(--tekst-drobny);
	color: var(--tekst-2);
	overflow-wrap: anywhere;
}
.karta-krok.po-terminie { color: var(--zly); font-weight: 600; }
.karta-krok.brak-kroku { color: var(--uwaga); }
/* „brak następnego kroku — zaplanuj” jest odnośnikiem (D659), ale zostaje
   bursztynowy: to sygnał, a podkreślenie mówi, że da się kliknąć. */
.karta-krok.brak-kroku a { color: inherit; }
.kolumna-glowka .licznik {
	font-variant-numeric: tabular-nums;
	font-weight: 600;
	color: var(--tekst-2);
	background: var(--panel);
	border: 1px solid var(--obramowanie);
	border-radius: 20px;
	padding: 1px 8px;
	font-size: var(--tekst-drobny);
}

.kolumna-karty { padding: 10px; overflow-y: auto; display: flex; flex-direction: column; gap: 8px; }
.pusta-kolumna { text-align: center; padding: 12px 0; }

.karta-lejka {
	background: var(--panel);
	border: 1px solid var(--obramowanie);
	border-radius: 6px;
	padding: 10px 11px;
	cursor: grab;
	box-shadow: var(--cien);
}
.karta-lejka:active { cursor: grabbing; }
.karta-lejka.niesiona { opacity: .4; }
.karta-nazwa { font-weight: 600; font-size: var(--tekst-wiersz); text-decoration: none; display: block; }
.karta-meta { font-size: var(--tekst-drobny); color: var(--tekst-3); margin-top: 3px; }
.karta-meta .bez-kontaktu { color: var(--uwaga); font-weight: 500; }

/* --- zadania -------------------------------------------------------------- */

.grupa-zadan { margin-bottom: 16px; }
.grupa-zadan.pilne { border-color: var(--uwaga); }
.grupa-zadan.zrobione { opacity: .75; }

.zadanie {
	display: flex;
	align-items: flex-start;
	gap: 10px;
	padding: 10px 0;
	border-bottom: 1px solid var(--obramowanie-2);
}
.zadanie:last-child { border-bottom: 0; }
.zadanie.zamkniete { justify-content: space-between; }

.zadanie-zamknij { margin: 0; }
/* Okrągły `.ptaszek` (✓ i ↩) zastąpiły od D797 przyciski z napisem
   „✓ Zrobione” i „↩ Przywróć” — reguły niżej, przy `.zadanie-szybkie`. */

.zadanie-tresc { flex: 1; min-width: 0; }
.zadanie-tytul { font-weight: 500; }
.zadanie-opis { font-size: var(--tekst-podpis); color: var(--tekst-2); margin-top: 3px; }
.zadanie-termin {
	font-size: var(--tekst-podpis);
	color: var(--tekst-3);
	font-variant-numeric: tabular-nums;
	white-space: nowrap;
}
.zadanie-termin.pilny { color: var(--uwaga); font-weight: 600; }
.zadanie.po-terminie .zadanie-tytul { color: var(--uwaga); }

/* Lista wewnątrz komunikatu — np. kampanie zatrzymane przez wyłącznik
   na pulpicie. Domyślne marginesy listy rozpychają ramkę komunikatu. */
.lista-zwarta { margin: 6px 0 0; padding-left: 20px; }
.lista-zwarta li { margin: 2px 0; }

/* Zaznaczanie firm i pasek akcji masowych na liście.
   Kolumna wyboru jest wąska i nie ma się rozciągać — nazwa firmy jest tu
   najważniejsza i to ona ma dostać całą wolną szerokość. */
.kolumna-wyboru { width: 34px; text-align: center; }
.kolumna-wyboru input[type="checkbox"] { width: auto; margin: 0; }

/* Zaznaczanie zadań do akcji hurtem (2026-09-18, D235) — pole przed
   ptaszkiem, na wysokości tytułu; „zaznacz wszystkie” przy nagłówku sekcji. */
.zadanie-wybor,
.zaznacz-sekcje input[type="checkbox"] { width: auto; margin: 6px 0 0; flex-shrink: 0; }
.zaznacz-sekcje { font-weight: 400; margin-left: 8px; }
.zaznacz-sekcje input[type="checkbox"] { margin: 0 4px 0 0; vertical-align: middle; }

.pasek-masowy {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px;
	margin-top: 12px;
	padding: 10px 12px;
	background: var(--panel-2);
	border: 1px solid var(--obramowanie);
	border-radius: var(--r);
}
.pasek-masowy select { width: auto; min-width: 150px; }

/* Pasek akcji hurtem nad listą firm (2026-09-18). Ukryty, dopóki nic nie
   jest zaznaczone — do tego dnia stał na stałe pod tabelą i pięć list
   rozwijanych czytano jak drugi filtr. `:has()` robi to bez JavaScriptu;
   `sticky` trzyma pasek przy górze, gdy zaznacza się wiersze niżej. */
.pasek-zaznaczenia {
	display: none;
	position: sticky;
	top: 8px;
	z-index: 5;
	margin: 0 0 10px;
	background: var(--zielen-mgla);
	border-color: var(--zielen);
	box-shadow: var(--cien);
}
form:has(input[name="firmy"]:checked) > .pasek-zaznaczenia { display: flex; }
.pasek-zaznaczenia select { min-width: 130px; }
.licznik-zaznaczenia { font-size: var(--tekst-wiersz); color: var(--zielen-ciemna); }

/* Krótkie kolumny listy nie łamią się na dwie linie („wykonawca / montaż”
   rozpychało wiersz do podwójnej wysokości) — miejsce oddaje nazwa firmy. */
.tabela td.bez-lamania { white-space: nowrap; }
/* „Następny krok” pod nazwą firmy i w nagłówku kartoteki (2026-09-27,
   [[08_DECYZJE]] D633) — po terminie na czerwono, jak na karcie lejka. */
.krok-listy.po-terminie,
.krok-naglowka a.po-terminie { color: var(--zly); font-weight: 600; }
.tabela-duplikatow { table-layout: fixed; }
.tabela-duplikatow th:nth-child(1) { width: 6%; }
.tabela-duplikatow th:nth-child(3),
.tabela-duplikatow th:nth-child(4) { width: 12%; }
.tabela-duplikatow th:nth-child(5) { width: 8%; }
.tabela-duplikatow th:nth-child(6) { width: 14%; }
.tabela-duplikatow th:nth-child(7) { width: 18%; }
.tabela-duplikatow td:last-child { text-align: right; }
.rozdzielacz-masowy {
	width: 1px;
	align-self: stretch;
	background: var(--obramowanie);
	margin: 0 4px;
}
/* Na wąskim ekranie pasek składa się w kolumnę — inaczej dwa wybory
   i dwa przyciski wypychają stronę w bok. */
@media (max-width: 800px) {
	.pasek-masowy { flex-direction: column; align-items: stretch; }
	.pasek-masowy select { width: 100%; }
	.rozdzielacz-masowy { display: none; }

	/* PASEK HURTU FIRM NA TELEFONIE (2026-09-27, [[08_DECYZJE]] D637).
	   Przyklejony do góry i złożony w kolumnę miał 385 px — przy 390×844
	   zasłaniał pół ekranu, pod którym przewijało się kilka wierszy listy.
	   Na telefonie stoi w miejscu (nie jedzie za przewijaniem) i jest
	   dwukolumnowy: licznik i podpisy przez całą szerokość, pola parami. */
	.pasek-zaznaczenia { position: static; box-shadow: none; }
	form:has(input[name="firmy"]:checked) > .pasek-zaznaczenia {
		display: grid;
		grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
		gap: 6px 8px;
	}
	.pasek-zaznaczenia .licznik-zaznaczenia,
	.pasek-zaznaczenia > label,
	.pasek-zaznaczenia > .pod,
	.pasek-zaznaczenia > select[name="rynek"],
	.pasek-zaznaczenia > select[name="jezyk"] { grid-column: 1 / -1; }
	.pasek-zaznaczenia select { min-width: 0; }
	.pasek-zaznaczenia .przycisk { width: 100%; }
}

/* „jutro" i „+7 dni" przy zadaniu.
   Dwa osobne formularze obok siebie, bo każdy niesie inną wartość `dni`,
   a zagnieżdżać formularzy nie wolno.
   ZAWSZE WIDOCZNE, SZARE (2026-10-07, [[08_DECYZJE]] D811). Od D85 wychodziły
   dopiero po najechaniu myszą — instrukcja mówiła, że są, a na ekranie ich
   nie było, więc człowiek ich nie szukał. Szary napis i jaśniejsza ramka
   nie przykrywają treści zadania; pełny kolor przy najechaniu na zadanie
   i z klawiatury, jak „✓ Zrobione · Usuń” obok (D797). */
.zadanie-przeloz { display: flex; gap: 4px; margin: 0; }
.zadanie-przeloz form { margin: 0; }
.zadanie-przeloz .przycisk { color: var(--tekst-3); border-color: var(--obramowanie-2); }
.zadanie:hover .zadanie-przeloz .przycisk,
.zadanie-przeloz .przycisk:focus-visible { color: var(--tekst); border-color: var(--obramowanie); }

/* Zadanie na Pulpicie (2026-10-07, [[08_DECYZJE]] D811) — ten sam wiersz co na
   Zadaniach, w karcie szerokiej na ok. 370 px: treść w pierwszej linii,
   „✓ Zrobione · jutro” i termin w drugiej, jak na telefonie (D627). */
.zadanie-zwiezle { flex-wrap: wrap; gap: 6px 8px; padding: 8px 0; }
.zadanie-zwiezle .zadanie-tresc { flex: 1 1 100%; }
.zadanie-zwiezle .zadanie-tresc > a { text-decoration: none; }
.zadanie-zwiezle .zadanie-tresc > a:hover { text-decoration: underline; }
.zadanie-zwiezle .zadanie-szybkie { order: 1; margin-left: 0; }
.zadanie-zwiezle .zadanie-przeloz { order: 2; flex-basis: auto; margin-left: 0; }
.zadanie-zwiezle .zadanie-termin { order: 3; margin-left: auto; align-self: center; }

/* „✓ Zrobione” i „Usuń” przy zadaniu — ZAWSZE widoczne (2026-10-04,
   [[08_DECYZJE]] D797); od D811 tak samo „jutro · +7 dni · edytuj” wyżej.
   Właściciel: „powinna być szybka opcja usuń albo zrobione”. Do tego dnia
   zrobione było okrągłym „✓” bez napisu, a usunięcie siedziało w pasku
   zaznaczonych i na ekranie edycji. Kolor dopiero pod kursorem: dwadzieścia
   czerwonych „Usuń” na liście krzyczałoby głośniej niż same zadania. */
.zadanie-szybkie { display: flex; gap: 4px; flex-shrink: 0; }
.zadanie-szybkie form { margin: 0; }
.przycisk.drugorzedny.zrobione:hover,
.przycisk.drugorzedny.zrobione:focus-visible {
	background: var(--zielen);
	border-color: var(--zielen);
	color: var(--na-zieleni);
}
.zadanie-szybkie .przycisk.niebezpieczny { color: var(--tekst-2); }
.zadanie-szybkie .przycisk.niebezpieczny:hover,
.zadanie-szybkie .przycisk.niebezpieczny:focus-visible {
	background: var(--zly-tlo);
	border-color: var(--zly);
	color: var(--zly);
}
/* „↩ Przywróć” — barwa uwagi, nie zieleń: robi odwrotność „Zrobione”
   (ta sama reguła co dawny okrągły `.ptaszek.cofnij`). */
.przycisk.drugorzedny.cofnij { color: var(--uwaga); }
.przycisk.drugorzedny.cofnij:hover,
.przycisk.drugorzedny.cofnij:focus-visible {
	background: var(--uwaga-tlo);
	border-color: var(--uwaga);
	color: var(--uwaga);
}

/* Historia zadań (D797): dzień nad grupą, rodzaj w plakietce przed tytułem. */
.historia-zadan .dzien-historii { margin: 14px 0 2px; }
.historia-zadan .dzien-historii:first-child { margin-top: 0; }
.historia-zadan .zadanie.zamkniete { align-items: center; }
.plakietka.plakietka-usuniete { background: var(--panel-2); color: var(--tekst-2); }
.historia-zadan .plakietka-zrobione,
.historia-zadan .plakietka-usuniete { min-width: 88px; text-align: center; flex-shrink: 0; }

/* Zadanie na telefonie: treść w pierwszej linii na całą szerokość,
   „jutro · +7 dni · edytuj” i termin w drugiej, pod treścią (2026-09-27,
   [[08_DECYZJE]] D627). Do tego dnia przyciski i termin zabierały wiersz,
   tytuł miał ok. 60 px — jedno słowo w linii — a przycisk „jutro” leżał
   na jego początku („Do[jutro] certyfikaty”). Wcięcie = pole wyboru
   (13 px) + ptaszek (26 px) + dwa odstępy; bez pola wyboru (kartoteka)
   — sam ptaszek. */
@media (max-width: 800px) {
	.zadanie { flex-wrap: wrap; }
	.zadanie-tresc { flex: 1 1 60%; }
	/* Od D797 bez okrągłego „✓” na początku wiersza — wcięcie to samo
	   pole wyboru (13 px + odstęp), a w kartotece żadne. Druga linia to
	   „✓ Zrobione · Usuń” i termin (najczęstsze), trzecia — „jutro · +7 dni
	   · edytuj”; kolejność w HTML zostaje ta z komputera. */
	.zadanie-szybkie { order: 1; }
	.zadanie-termin { order: 2; }
	.zadanie-przeloz { order: 3; flex-basis: 100%; margin-left: 0; }
	.zadanie:has(.zadanie-wybor) .zadanie-szybkie,
	.zadanie:has(.zadanie-wybor) .zadanie-przeloz { margin-left: 23px; }
	/* Historia zadań: tytuł na całą szerokość, pod nim rodzaj, godzina
	   i przycisk — plakietka przed tytułem zostawiała mu słowo w linii. */
	.historia-zadan .zadanie-tresc { flex-basis: 100%; order: 1; }
	.historia-zadan .plakietka-zrobione,
	.historia-zadan .plakietka-usuniete { order: 2; min-width: 0; }
	.historia-zadan .zadanie > time { order: 3; }
	.historia-zadan .zadanie > form,
	.historia-zadan .zadanie > a.przycisk { order: 4; margin-left: auto; }
	.zadanie-termin { margin-left: auto; align-self: center; }
}

/* Pasek „Zaznaczone zadania” — dopiero po zaznaczeniu, przyklejony u góry,
   jak pasek nad listą Firm (2026-09-27, D627). Pola wyboru należą do
   formularza przez atrybut `form`, a nie leżą w nim — stąd `:has()` na
   `main`, nie na formularzu. */
.pasek-zadan {
	display: none;
	position: sticky;
	top: 8px;
	z-index: 5;
	background: var(--zielen-mgla);
	border-color: var(--zielen);
	box-shadow: var(--cien);
}
main:has(input[form="hurt-zadan"]:checked) .pasek-zadan { display: flex; }
@media (max-width: 800px) {
	/* W rzędzie, nie w kolumnie: przyklejony pasek ma zasłaniać jak najmniej. */
	.pasek-zadan.pasek-masowy { flex-direction: row; align-items: center; }
	.pasek-zadan.pasek-masowy select { width: auto; min-width: 0; }
}

.formularz-zadania { margin-top: 12px; }
.formularz-zadania input[type="text"] { margin-bottom: 8px; }
/* Data o stałej szerokości, jak w „następnym kroku” — resztę rzędu bierze
   „Kogo dotyczy” (D621). */
.formularz-zadania input[type="date"] { max-width: 170px; }
/* Pola z etykietami nad sobą (D754) — przycisk „Dodaj” równo z dołem pól,
   a lista osób bierze resztę rzędu, jak dotąd sama lista bez etykiety. */
.linia-zadania { align-items: flex-end; flex-wrap: wrap; }
.linia-zadania .pole-osoby { flex: 1 1 180px; min-width: 0; }
.linia-zadania .pole-osoby select { width: 100%; }
.formularz-zadania input[type="time"] { max-width: 130px; }
/* Wygląd bierze reguła bazowa wyżej — tutaj zostaje tylko to, co ODMIENNE.
   Do 2026-09-11 stały tu trzy niemal identyczne kopie tego samego bloku. */

/* --- telefonia ------------------------------------------------------------ */

.przycisk.maly { padding: 4px 10px; font-size: var(--tekst-drobny); }

/* KOLEJKA JAKO KARTY NA TELEFONIE (2026-09-19, D338).
   Zmierzone w audycie 5 przy 375 px: tabela szeroka na 696 px, kolumna
   z „Zadzwoń”, „oddzwoń” i „zapisz rozmowę” od 591 px — poza ekranem
   w każdym wierszu. Poniżej 800 px wiersz jest kartą: kto, firma, numer,
   a pod nimi duży „Zadzwoń” na całą szerokość. */
@media (max-width: 800px) {
	.kolejka-karty thead { display: none; }
	.kolejka-karty, .kolejka-karty tbody { display: block; width: 100%; }
	.kolejka-karty tr {
		display: flex;
		flex-wrap: wrap;
		align-items: baseline;
		gap: 4px 12px;
		padding: 12px 0;
		border-bottom: 1px solid var(--obramowanie-2);
	}
	.kolejka-karty td { display: block; padding: 0; border: 0; }
	.kolejka-karty td.k-osoba { order: 1; flex: 1 1 100%; font-weight: 600; }
	.kolejka-karty td.k-firma { order: 2; }
	.kolejka-karty td.k-telefon { order: 3; }
	.kolejka-karty td.k-akcje { order: 4; flex: 1 1 100%; }
	.kolejka-karty td.k-etap,
	.kolejka-karty td.k-kontakt { order: 5; font-size: var(--tekst-drobny); }
	/* Nagłówek kolumny znika razem z `thead` — samo „nigdy” obok etapu nie
	   mówiło, czego dotyczy (2026-10-03, [[08_DECYZJE]] D794). */
	.kolejka-karty td.k-kontakt::before { content: "ostatni kontakt: "; color: var(--tekst-2); }
	.kolejka-karty .zadzwon-duzy { width: 100%; padding: 12px; font-size: 1.05em; }
}
/* SZERSZA KOLUMNA PRZYCISKÓW NA KOMPUTERZE (2026-10-07, [[08_DECYZJE]] D811).
   Przy 1440 px wiersz kolejki miał ok. 130–160 px: pod „Zadzwoń” stały jedno
   pod drugim „zadzwoń później: jutro · za 3 dni” / „za tydzień” / „zapisz
   rozmowę”. Teraz to jedna linia, a miejsce oddają Etap i Ostatni kontakt
   (szerokie na treść, bez łamania). Otwarte „zapisz rozmowę” bierze całą
   linię — „zadzwoń później” chowa wtedy `telefony.js` (D649). */
.k-akcje-dalej { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 14px; margin-top: 6px; }
.k-akcje-dalej .oddzwon,
.k-akcje-dalej .rozmowa-recznie { margin: 0; }
.k-akcje-dalej .rozmowa-recznie[open] { flex-basis: 100%; }
@media (min-width: 801px) {
	.kolejka-karty td.k-akcje { width: 380px; }
	.kolejka-karty td.k-etap,
	.kolejka-karty td.k-kontakt { width: 1%; white-space: nowrap; }
	/* Telefon wąski jak numer — długie plakietki („e-mail nie działa: …”) łamią się. */
	.kolejka-karty td.k-telefon { width: 1%; }
	.kolejka-karty td.k-telefon .plakietka { white-space: normal; }
	.kolejka-karty .zadzwon-pozniej { flex-wrap: nowrap; white-space: nowrap; }
}

/* FILTR KOLEJKI ZWINIĘTY NA TELEFONIE (2026-09-27, D649). Na szerokim
   ekranie nagłówka zwijki nie widać — filtr stoi otwarty jak dotąd. */
.filtr-kolejki > summary {
	cursor: pointer;
	padding: 10px 12px;
	margin-bottom: 8px;
	border: 1px solid var(--obramowanie);
	border-radius: var(--r);
	background: var(--panel);
	color: var(--tekst-2);
}
@media (min-width: 801px) {
	.filtr-kolejki > summary { display: none; }
}
.firmy-bez-numeru ul { margin: 4px 0 0; padding-left: 20px; }
.kotwica-kolejki { scroll-margin-top: 8px; }
.zadzwon-pozniej[hidden] { display: none; }

.osoba-telefon { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

/* ZAPISZ ROZMOWĘ Z WŁASNEGO TELEFONU — zwinięte, bo to droga druga, nie
   pierwsza. Rozwinięte w każdym z trzydziestu wierszy kolejki przykryłoby to,
   po co się na ten ekran przychodzi: listę numerów do wybrania. */
.rozmowa-recznie { margin-top: 6px; }
.rozmowa-recznie > summary {
	cursor: pointer;
	color: var(--zielen);
	white-space: nowrap;
}
.rozmowa-recznie form {
	display: flex;
	flex-direction: column;
	gap: 6px;
	margin: 8px 0 0;
	min-width: 190px;
}
.rozmowa-recznie select,
.rozmowa-recznie input[type="text"] { font-size: var(--tekst-drobny); }
.osoba-telefon form { margin: 0; }

/* Oddzwonienie jednym kliknięciem (2026-09-17): trzy małe przyciski w jednej
   linii pod „Zadzwoń". Zawijają się na wąskim ekranie, bo handlowiec
   obdzwania kolejkę także z telefonu. */
.oddzwon {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 4px;
	margin: 6px 0 0;
}

/* BRIEFING POD WIERSZEM KOLEJKI (2026-09-25, D472). Do tego dnia stał
   rozwinięty w kolumnie „Osoba” (46 znaków szerokości) i jeden briefing
   rozpychał wiersz na pół ekranu. Teraz to osobny wiersz na całą szerokość
   tabeli, schowany do kliknięcia „Briefing” — rozwija się pod osobą. */
.briefing-przelacznik[aria-expanded="true"] span { display: inline-block; transform: rotate(180deg); }
.briefing-przelacznik { margin-top: 6px; }
.tabela tr.briefing-wiersz[hidden] { display: none; }
.tabela tr.briefing-wiersz:hover { background: transparent; }
.tabela tr:has(+ tr.briefing-wiersz:not([hidden])) td { border-bottom-color: transparent; }
.tabela tr.briefing-wiersz > td { padding-top: 0; }
.briefing-panel {
	border-left: 3px solid var(--zielen);
	background: var(--panel-2);
	border-radius: 6px;
	padding: 12px 16px;
}
.briefing-glowka { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px; margin-bottom: 6px; }
.briefing-glowka button { margin-left: auto; }
.briefing-tresc { max-width: 90ch; }
.briefing-tresc p { margin: 0 0 8px; }
.briefing-tresc p:last-child { margin-bottom: 0; }
/* BEZ ANIMACJI ROZWIJANIA (2026-09-25, D475). Do tego dnia panel wjeżdżał
   160 ms (`opacity` + `translateY`) i każda klatka tego ruchu przemalowywała
   CAŁĄ kolejkę: 200 wierszy z formularzami. Zmierzone śladem przeglądarki
   na 191 wierszach: 41 ms pracy na kliknięcie, bez animacji 11 ms; przy
   procesorze laptopa (4× wolniej) strona stawała na ułamek sekundy przy
   każdym „Briefing” i „zwiń”. Briefing ma się pokazać od razu — nie wracaj
   tu z `animation` ani `transition`. `:has()` wyżej i `table-layout`
   zmierzone przy tej samej okazji: bez znaczenia. */
/* Cel odnośnika „Briefing” przy numerze w kartotece (D475) — z zapasem,
   żeby nad briefingiem było widać nagłówek karty, nie sam tekst. */
#panel-briefing .podpowiedz { scroll-margin-top: 56px; }
@media (max-width: 800px) {
	.kolejka-karty tr.briefing-wiersz { padding-top: 0; }
	.kolejka-karty tr.briefing-wiersz > td { flex: 1 1 100%; }
	.kolejka-karty tr:has(+ tr.briefing-wiersz:not([hidden])) { border-bottom-color: transparent; }
}

/* ── ROZMOWA PRZEZ KOMPUTER, NAGRANIA, TRANSKRYPCJA (2026-09-26, D520–D522) ── */

/* „Rozmawiam: na komórce / przez komputer” — nad kolejką. Ten sam wygląd co
   `.przelacznik-widoku`, ale z przyciskami: wybór zapisuje się na serwerze. */
.sposob-rozmowy {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px 12px;
	margin-bottom: 12px;
}
.przelacznik-sposobu {
	display: inline-flex;
	border: 1px solid var(--obramowanie);
	border-radius: var(--r);
	overflow: hidden;
	font-size: var(--tekst-podpis);
}
.przelacznik-sposobu button {
	padding: 6px 14px;
	border: 0;
	color: var(--tekst-2);
	background: var(--panel);
	font: inherit;
	cursor: pointer;
}
.przelacznik-sposobu button + button { border-left: 1px solid var(--obramowanie); }
.przelacznik-sposobu button[aria-pressed="true"] {
	background: var(--zielen-mgla);
	color: var(--zielen-ciemna);
	font-weight: 600;
}

/* Okno Słuchawki — wąskie (420 px), bez menu; jeden stan naraz. */
.okno-sluchawki { background: var(--tlo); }
.sluchawka { max-width: 480px; margin: 0 auto; padding: 16px; }
.sluchawka-glowka {
	display: flex;
	justify-content: space-between;
	align-items: center;
	gap: 8px;
	margin-bottom: 12px;
}
.sluchawka-glowka h1 { font-size: var(--tekst-bazowy); margin: 0; }
.sluchawka-glowka .plakietka.dobra { background: var(--dobry-tlo); color: var(--dobry); }
.sluchawka-glowka .plakietka.uwaga { background: var(--uwaga-tlo); color: var(--uwaga); }
.sluchawka-glowka .plakietka.zla { background: var(--zly-tlo); color: var(--zly); }
.sluchawka-kto { font-size: var(--tekst-bazowy); font-weight: 600; margin: 0; }
.sluchawka-czas {
	font-size: var(--tekst-naglowek);
	font-variant-numeric: tabular-nums;
	margin: 8px 0;
}
.sluchawka-przyciski { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.sluchawka-przyciski .przycisk { flex: 1 1 140px; }
/* „Rozłącz” — pełny czerwony, jak w każdym telefonie. `.niebezpieczny` zmienia
   sam kolor napisu i na zielonym tle przycisku dawał czerwień na zieleni. */
.przycisk.rozlacz,
.przycisk.rozlacz:hover { background: var(--zly); border-color: var(--zly); color: var(--na-zlym); }
.sluchawka-dzwoni { border-left: 3px solid var(--uwaga); }
.sluchawka .wynik-pola { flex-wrap: wrap; }

/* Transkrypcja jako rozmowa: nasza strona po prawej, klient po lewej. */
.odtwarzacz-rozmowy { width: 100%; margin-bottom: 8px; }
.transkrypcja { list-style: none; margin: 12px 0 0; padding: 0; max-width: 90ch; }
.wypowiedz {
	margin: 0 0 8px;
	padding: 8px 12px;
	border-radius: var(--r);
	background: var(--panel-2);
	border: 1px solid var(--obramowanie-2);
	margin-right: 12%;
}
.wypowiedz-my { background: var(--zielen-mgla); margin-right: 0; margin-left: 12%; }
.wypowiedz.teraz { border-color: var(--zielen); box-shadow: inset 3px 0 0 var(--zielen); }
.wypowiedz-glowka {
	display: flex;
	gap: 8px;
	align-items: baseline;
	font-size: var(--tekst-podpis);
}
.wypowiedz p { margin: 2px 0 0; font-size: var(--tekst-wiersz); }
.czas-wypowiedzi { font-variant-numeric: tabular-nums; font-size: var(--tekst-drobny); }

/* Streszczenie nagranej rozmowy na osi czasu kartoteki. */
.streszczenie-rozmowy {
	border-left: 3px solid var(--zielen);
	padding: 4px 12px;
	margin: 6px 0 0;
	font-size: var(--tekst-wiersz);
}
.streszczenie-rozmowy ul { margin: 0; padding-left: 18px; }

.wynik-rozmowy {
	padding: 12px 0;
	border-bottom: 1px solid var(--obramowanie-2);
	margin: 0;
}
.wynik-rozmowy:last-child { border-bottom: 0; }
.wynik-glowka {
	display: flex;
	align-items: baseline;
	gap: 8px;
	flex-wrap: wrap;
	margin-bottom: 8px;
}
.wynik-pola { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.wynik-pola select { flex: 0 0 190px; }
.wynik-pola input[type="text"] { flex: 1; min-width: 180px; }
.wynik-pola input[type="date"] { flex: 0 0 150px; }

/* Pola wyniku dopasowane do wyniku (2026-09-24, D391, `_wynik_pola.html`):
   data z podpisem tylko przy „umówiono”, „zapisz i oddzwoń:” z trzema
   krótkimi terminami zamiast trzech pełnych przycisków w drugim wierszu.
   `[hidden]` jawnie — `display: flex` wyżej przykrywa domyślne ukrycie. */
.wynik-termin { display: flex; align-items: center; gap: 6px; margin: 0; }
/* „puste = za tydzień” na wierzchu (D811) — w wąskiej kolumnie kolejki
   schodzi pod datę, podpisy nie łamią się w pół. */
.wynik-termin { flex-wrap: wrap; }
.wynik-termin > .pod { white-space: nowrap; }
.wynik-termin[hidden],
.wynik-pola .oddzwon[hidden] { display: none; }
.wynik-pola .oddzwon { margin: 0; align-items: center; }
.rozmowa-recznie .wynik-pola select,
.rozmowa-recznie .wynik-pola input[type="text"] { flex: 1 1 100%; }

/* „zadzwoń później: jutro · za 3 dni · za tydzień” w wierszu kolejki (D391) —
   przyciski formularza wyglądające jak odnośniki. Do tego dnia trzy
   obramowane przyciski w każdym wierszu, obok „Zadzwoń” i „zapisz rozmowę”. */
.jak-odnosnik {
	padding: 0;
	border: 0;
	background: none;
	color: var(--zielen);
	font: inherit;
	font-size: var(--tekst-drobny);
	text-decoration: underline;
	cursor: pointer;
}
.jak-odnosnik:hover { color: var(--zielen-ciemna); }
.zadzwon-pozniej { gap: 2px 10px; }

/* --- asystent ------------------------------------------------------------- */

.przyciski-asystenta {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	margin-top: 10px;
}

/* Blok propozycji asystenta na osi czasu — KRESKA ODDZIELAJĄCA, nie tekst
 * pomocniczy. Nazwa myli i dlatego była używana źle: do 2026-09-10 siedziała
 * w dwudziestu siedmiu miejscach jako podpowiedź pod polem formularza
 * (konfiguracja skrzynki, dostawcy, nadawcy, szablony, nowa firma).
 *
 * Skutek: te podpowiedzi renderowały się jako tekst 14 px na czarno
 * z poziomą linią NAD sobą — bo ta reguła nie ustawia ani `font-size`, ani
 * `color` — podczas gdy identyczne podpowiedzi na innych ekranach używają
 * `.pod` (12 px, szary). Ekran konfiguracji poczty wyglądał przez to jak
 * osiem sekcji przedzielonych kreskami.
 *
 * Tamte miejsca używają teraz `.pod`. Tutaj zostaje to, czym ta klasa jest.
 */
.podpowiedz {
	margin-top: 14px;
	padding-top: 12px;
	border-top: 1px solid var(--obramowanie-2);
}

/* Generowanie odpowiedzi — przy KONKRETNEJ wiadomości na osi czasu.
   Celowo dyskretne: to nie jest główna akcja kartoteki, tylko skrót
   dostępny tam, gdzie akurat leży wiadomość wymagająca odpowiedzi. */
.odpowiedz-ai {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	align-items: center;
	margin-top: 10px;
	padding-top: 10px;
	border-top: 1px dashed var(--obramowanie-2);
}

.odpowiedz-ai .wskazowka {
	flex: 1 1 220px;
	min-width: 0;   /* bez tego pole rozpycha oś czasu na wąskim ekranie */
	font-size: var(--tekst-podpis);
}

/* Propozycja jest w polu edycyjnym, nie w bloku tekstu — to nie jest
   ozdobnik. Chodzi o to, żeby od razu było widać, że TO SIĘ POPRAWIA,
   a nie kopiuje w ciemno. */
.tresc-podpowiedzi {
	margin-top: 6px;
	font-family: var(--sans);
	font-size: var(--tekst-wiersz);
	line-height: 1.5;
	background: var(--panel-2);
}

/* --- raporty -------------------------------------------------------------- */

.zakladki {
	display: flex;
	gap: 4px;
	margin-bottom: 16px;
	border-bottom: 1px solid var(--obramowanie);
	flex-wrap: wrap;
}
.zakladki a {
	padding: 9px 16px;
	text-decoration: none;
	color: var(--tekst-2);
	font-weight: 500;
	border-bottom: 2px solid transparent;
	margin-bottom: -1px;
}
.zakladki a:hover { color: var(--tekst); }
.zakladki a.wybrana {
	color: var(--zielen-ciemna);
	border-bottom-color: var(--zielen);
}

/* Trzeci poziom nawigacji (D58): ekrany wewnątrz zakładki.

   Celowo INNY kształt niż zakładki — plakietki zamiast podkreśleń. Dwa
   rzędy tego samego kształtu pod sobą czyta się jak jeden pasek, który się
   zawinął, i wtedy nie widać, że drugi rząd należy do jednej pozycji
   pierwszego. Zakładka podkreśla, podzakładka wypełnia. */
.podzakladki {
	display: flex;
	gap: 6px;
	flex-wrap: wrap;
	margin: -8px 0 16px;
}
.podzakladki a {
	padding: 5px 12px;
	border-radius: 999px;
	text-decoration: none;
	color: var(--tekst-2);
	font-size: var(--tekst-podpis);
	background: var(--panel-2);
	border: 1px solid var(--obramowanie);
}
.podzakladki a:hover { color: var(--tekst); }
.podzakladki a.wybrana {
	background: var(--zielen);
	border-color: var(--zielen);
	color: var(--na-zieleni);
}

.wybor-okresu {
	display: flex;
	/* Zawijanie (2026-09-19, D353): pole „albo od … do … Pokaż” nie mieściło
	   się w 375 px i przesuwało w bok CAŁĄ stronę każdego raportu
	   (scrollWidth 490, z oknem dat 547). */
	flex-wrap: wrap;
	align-items: center;
	gap: 10px;
	margin-bottom: 16px;
}
.wybor-okresu label { margin: 0; white-space: nowrap; }
.wybor-okresu select { width: auto; min-width: 170px; }

/* Rola w stopce panelu bocznego — handlowiec widzący mniej danych niż kolega
   ma wiedzieć, że to wynik uprawnień, a nie braku danych w systemie. */
.stopka-boku .rola {
	font-size: var(--tekst-plakietka);
	color: var(--tekst-3);
	text-transform: uppercase;
	letter-spacing: .04em;
}


/* --- porównanie treści obok siebie --------------------------------------- */

/* Wersja językowa a treść podstawowa, dwie kolumny. Pytanie przy każdym
   tłumaczeniu brzmi „czy to na pewno to samo": czy nie wypadł akapit, czy
   cena się zgadza, czy znacznik {{imie}} przeżył. Z jedną kolumną odpowiadało
   się na to przewijaniem ekranu w tę i z powrotem. */
.ostrzezenie { color: var(--uwaga); }
/* `.karta .pod` (podpis kafla pulpitu) jest mocniejsze od samego
   `.ostrzezenie`, więc każde „pod ostrzezenie” w karcie — „Dziś tak nie
   będzie” przy regułach wysyłki, przyczyny w kolejce telefonów, hasło —
   wychodziło szare jak zwykły podpis (zmierzone 2026-09-26, D502). */
.karta .pod.ostrzezenie { color: var(--uwaga); }

/* „asystent ▾” i „popraw notatkę” pod wpisem Historii (2026-10-07,
   [[08_DECYZJE]] D811). Dwie rzadkie czynności w jednej linii zamiast dwóch–
   trzech przycisków asystenta pod każdym wpisem; rozwinięta zajmuje całą
   szerokość. Strzałka „▾” jest w napisie — bez znacznika `<details>`, jak
   „więcej ▾” przy osobie. */
.zwijki-wpisu {
	display: flex;
	flex-wrap: wrap;
	gap: 4px 18px;
	align-items: baseline;
	margin-top: 8px;
}
.zwijki-wpisu > details[open] { flex-basis: 100%; }
.zwijki-wpisu > details > summary { cursor: pointer; }
.zwijki-wpisu > .edycja-danych { margin-top: 0; }
.asystent-wpisu > summary { list-style: none; }
.asystent-wpisu > summary::-webkit-details-marker { display: none; }
.asystent-wpisu-czynnosci {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	margin-top: 8px;
}
.asystent-wpisu-czynnosci > form { margin: 0; }
/* Wybór języka w linii z podpisem i przyciskiem, nie na całą szerokość. */
.asystent-wpisu .odpowiedz-ai select { width: auto; max-width: 100%; }

.porownanie {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 14px;
	margin-top: 10px;
}
.porownanie > div {
	border: 1px solid var(--obramowanie);
	border-radius: 6px;
	padding: 10px 12px;
	min-width: 0;
}
.tresc-obok {
	/* `pre`, nie `div`: treść maila ma akapity i wcięcia, a przy porównaniu
	   dwóch języków obok siebie łamanie w innych miejscach po każdej stronie
	   niweczy cały sens zestawienia. */
	white-space: pre-wrap;
	overflow-wrap: anywhere;
	font-family: inherit;
	font-size: var(--tekst-podpis);
	line-height: 1.5;
	margin: 8px 0 0;
	max-height: 320px;
	overflow-y: auto;
	color: var(--tekst-2);
}

/* Kilka pól obok siebie w jednej linii — wybór źródła, języka i przycisk. */
.wiersz-pol {
	display: flex;
	gap: 12px;
	align-items: flex-end;
	flex-wrap: wrap;
}
.wiersz-pol .pole { margin-bottom: 0; }

/* --- wąski laptop, tablet w poziomie, okno w podziale ekranu -------------- */
/*
   801–1040 px było do 2026-09-10 PASMEM BEZ POMIARU. Progi w tym arkuszu to
   tylko `max-width: 800px` i `min-width: 801px`, a komentarze z pomiarami
   mówią o 375, 900 i 1280 px.

   Co się tam dzieje: przy 801 px `.kartoteka` wraca do dwóch kolumn, czyli
   260 px na lewą i około 240 px na prawą. Oś czasu z historią kontaktu —
   maile, rozmowy, notatki — siedzi wtedy w kolumnie WĘŻSZEJ niż karta danych
   firmy obok. To samo z `.porownanie`: dwa okna treści maila po ~250 px,
   na ekranie scalania duplikatów, gdzie właśnie te dwie treści trzeba
   porównać.

   Jedna kolumna jest w tym pasmie czytelniejsza od dwóch złych. Handlowiec
   pracuje z hoteli i od klientów (CLAUDE.md, zasada 2), więc tablet
   w poziomie i okno na pół ekranu nie są przypadkiem brzegowym.
*/
@media (min-width: 801px) and (max-width: 1040px) {
	.kartoteka { grid-template-columns: 1fr; }
	.porownanie { grid-template-columns: 1fr; }
}
/* Listy pulpitu NIE są tu wymienione i to jest świadome: mają
   `repeat(auto-fit, minmax(280px, 1fr))`, czyli same schodzą do dwóch kolumn
   i do jednej. Dopisanie im progu nadpisałoby działającą regułę gorszą. */

/* --- telefony ------------------------------------------------------------- */

@media (max-width: 800px) {
	.kartoteka { grid-template-columns: 1fr; }
	.porownanie { grid-template-columns: 1fr; }
	.wiersz-pol { flex-direction: column; align-items: stretch; }
	/* W kolumnie podstawa `flex` liczy WYSOKOŚĆ (2026-10-01, [[08_DECYZJE]]
	   D718): „Nazwa oprawy” (`.pole.rosnace`, `flex: 1 1 260px` — szerokość
	   w rzędzie) miała na telefonie 260 px wysokości i pod polem stała pusta
	   dziura. Selektor `.pole.rosnace` osobno, bo ma większą wagę niż `> *`. */
	.wiersz-pol > *, .wiersz-pol > .pole.rosnace { flex-basis: auto; }
	/* Rząd pól łamie się na telefonie zamiast wychodzić poza ekran (D621):
	   siedem dni okna wysyłki stało w jednym rzędzie na 1020 px. */
	.linia-notatki { flex-wrap: wrap; }
	.pasek-wyniku { flex-direction: column; align-items: flex-start; }
	.zapis-segmentu { width: 100%; }
	.zapis-segmentu input[type="text"] { flex: 1; width: auto; }

	.szkielet { grid-template-columns: 1fr; }
	.bok {
		border-right: 0;
		border-bottom: 1px solid var(--obramowanie);
		padding-bottom: 12px;
	}
	.nawigacja { flex-direction: row; flex-wrap: wrap; }
	.tresc { padding: 20px 16px 32px; }

	/* Konto i „Wyloguj" NA KOŃCU strony, nie między menu a treścią.

	   Bok staje się na telefonie poziomym paskiem, a jego stopka —
	   `margin-top: auto` na szerokim oknie — lądowała wtedy w środku
	   ekranu: logo, szukanie, dwa rzędy menu, potem „kier / ADMINISTRATOR /
	   Wyloguj", i dopiero nazwa firmy. Zmierzone przy 375 px: ok. 150 px
	   chromu dokładnie tam, gdzie ma być treść ([[08_DECYZJE]] D58).

	   `order` na siatce szkieletu, a nie `display: none`: rola w stopce nie
	   jest ozdobnikiem — handlowiec widzący mniej danych niż kolega musi
	   wiedzieć, że to wynik uprawnień, a nie braku danych (`panel/context.py`).
	   Zostaje więc dostępna, tylko pod treścią. */
	/* Pięć wierszy, nie trzy (2026-10-01, [[08_DECYZJE]] D717): odkąd bok
	   jest `display: contents`, w siatce stoją osobno znak, szukanie, menu,
	   treść i stopka. „auto 1fr auto” dawało rozciągany wiersz SZUKANIU —
	   na krótkim ekranie („Nowe zadanie”, 390 px) pod polem szukania stał
	   pusty biały prostokąt na 160 px. Rośnie treść. */
	.szkielet { grid-template-rows: auto auto auto 1fr auto; }
	.bok { display: contents; }
	.znak, .szukaj-globalne, .nawigacja {
		order: 1;
		background: var(--panel);
	}
	.znak { padding: 20px 16px 14px; }
	.nawigacja { padding-bottom: 12px; border-bottom: 1px solid var(--obramowanie); }
	.tresc { order: 2; }
	.stopka-boku {
		order: 3;
		margin: 0;
		padding: 14px 16px;
		background: var(--panel);
		border-top: 1px solid var(--obramowanie);
	}

	/* Pole szukania nad rzędem menu, na całą szerokość. Zostaje na górze
	   celowo: na telefonie szuka się częściej niż przechodzi po modułach,
	   a menu zawinięte w rząd i tak zajmuje dwie linijki. */
	.szukaj-globalne { margin: 0 16px 10px; }

	/* Dymek „?" przypięty do DOŁU EKRANU, na całą szerokość.
	   To jest inny sposób ustawiania, nie przesunięcie — i tylko tutaj.

	   Na szerokim oknie dymek wyrasta od znaku zapytania i to jest właściwe:
	   widać, czego dotyczy. Na telefonie nie ma na to miejsca. Dymek ma 280 px,
	   treść przy 375 px ma 343 px — więc postawiony gdziekolwiek poza lewą
	   krawędzią wystaje poza stronę i daje jej poziomy pasek przewijania.
	   Zmierzone: Sekwencje 116 px, Ustawienia 57 px.

	   Przypięcie do dołu rozwiązuje to bez przycinania czegokolwiek, a przy
	   okazji daje dymek SZERSZY niż na wąskim ekranie był (332 px zamiast
	   280 px), czyli łatwiejszy do przeczytania kciukiem.

	   `wyjasnienia.js` pomija korektę strony poniżej 801 px — inaczej
	   nadpisałby `left`/`right` inline i dymek wróciłby pod znak zapytania. */
	.wyjasnienie-tresc {
		position: fixed;
		left: 12px;
		right: 12px;
		top: auto;
		bottom: 12px;
		width: auto;
		max-width: none;
	}
}


/* Podgląd wiadomości — ramka i tekst.
   Ramka izoluje style szablonu maila. Szablony mają własne reguły dla
   `body`, `table` i `a`; wstawione wprost w stronę przepisałyby wygląd
   całego panelu, więc trzymamy je tam, gdzie trzyma je klient pocztowy. */
.ramka-podgladu {
	width: 100%;
	height: 560px;
	border: 1px solid var(--obramowanie);
	border-radius: var(--r);
	background: #fff;   /* biel, bo taki jest domyślny kanwas maila */
	/* Rozciąganie w pionie: 560 px starcza na wiadomość krótką, a przy
	   dłuższej ofercie podgląd miał własny pasek przewijania wewnątrz
	   przewijanej strony. Jedna reguła zamiast drugiego ekranu. */
	resize: vertical;
}

/* Tłumaczenie pokazane wprost w liście „Przychodzące”. Wcięcie i kreska
   z boku, żeby na pierwszy rzut oka było widać, że to NIE jest to, co
   napisał klient — tylko maszynowa wersja tego. */
.tlumaczenie-w-liscie {
	margin-top: 4px;
	padding-left: 8px;
	border-left: 2px solid var(--obramowanie);
}

/* ODPOWIEDZI KLIENTÓW I SPOZA BAZY JAKO KARTY NA TELEFONIE (2026-09-27, D642).
   Zmierzone w audycie przy 390 px: tabela szeroka na 744 px w pudełku 320 px,
   temat ucięty, a „Odpowiedz”, „Prosi o wypis”, „Etap” i „Utwórz firmę”
   poza ekranem. Poniżej 800 px wiersz jest kartą — jak kolejka telefonów
   (D338) — a komórka akcji przestaje być `nowrap` (`.liczbowo`). */
@media (max-width: 800px) {
	.odpowiedzi-karty thead { display: none; }
	.odpowiedzi-karty,
	.odpowiedzi-karty tbody,
	.odpowiedzi-karty tr,
	.odpowiedzi-karty td { display: block; width: 100%; }
	.odpowiedzi-karty tr { padding: 10px 12px; border-bottom: 1px solid var(--obramowanie-2); }
	.odpowiedzi-karty td { padding: 2px 0; border: 0; text-align: left; white-space: normal; }
	.odpowiedzi-karty td:first-child { font-size: var(--tekst-drobny); }
}

/* PODGLĄD NA TELEFONIE.

   Wiadomość handlową czyta się dziś najczęściej na telefonie, a podgląd
   pokazywał wyłącznie szerokie okno — czyli jedyny wariant, w którym
   rozjechana tabela i za długi nagłówek nadal wyglądają dobrze.

   Węższa ramka, wyśrodkowana, z obramowaniem sugerującym urządzenie.
   Reguły są na końcu arkusza (D396, „RAMKA PODGLĄDU”): muszą wygrać
   z wysokościami `.wysoka` i `.karta-podgladu-maila`, które stoją niżej. */

/* JEDNA LISTA WYSYŁEK — [[08_DECYZJE]] D380.

   Poprzednia tabela kampanii miała czternaście kolumn i `.przewijana`,
   czyli pasek przewijania w poziomie PRZY JEDNYM WIERSZU. Nazwa kampanii
   łamała się wtedy na cztery linijki, żeby zrobić miejsce liczbom.

   Pięć kolumn mieści się bez przewijania także na wąskim laptopie, więc
   `.przewijana` tu nie ma. Reguły niżej pilnują tylko podziału miejsca:
   nazwa dostaje najwięcej, bo to po niej się szuka, a kolumna z jedną
   liczbą nie ma powodu być szersza niż jej nagłówek. */
.tabela-wysylek td:first-child {
	width: 34%;
}

.tabela-wysylek td:last-child,
.tabela-wysylek th:last-child {
	width: 1%;
	white-space: nowrap;
}

/* Ostrzeżenia i zdania pod wierszem. Plakietka w osobnej linii, nie obok
   nazwy: przy dwóch naraz („odbicia powyżej progu" + „zgoda POMIJANA")
   rozpychały wiersz na tyle, że reszta tabeli zaczynała się łamać. */
.tabela-wysylek td > div {
	margin-top: 3px;
}

/* PODGLĄD OPRAWY PRZY JEJ WYBORZE — [[08_DECYZJE]] D379.

   Pole „Oprawa HTML" było listą nazw, a nazwa oprawy nie mówi nic o tym,
   co ona robi z wiadomością. Ramka odpowiada na to jednym obrazkiem.

   NIŻSZA niż `.ramka-podgladu` na ekranie oprawy (320 px zamiast 560):
   tam podgląd JEST treścią ekranu, tutaj stoi w środku formularza, między
   wyborem segmentu a polem treści. Pełnej wysokości ramka rozpychałaby
   formularz tak, że przycisk „Zapisz" schodzi poza ekran — a `resize`
   zostaje, więc kto chce obejrzeć całość, ciągnie za róg. */
.oprawa-podglad {
	margin: 10px 0 4px;
}

.oprawa-podglad .ramka-podgladu {
	height: 320px;
}

/* Odstęp między odnośnikiem, przyciskiem odświeżania i zdaniem
   wyjaśniającym — inaczej sklejają się w jedną linię tekstu, w której
   przycisk wygląda na część zdania. */
[data-oprawa-drogi] > * + * {
	margin-left: 8px;
}

/* PODGLĄD TREŚCI NA ŻYWO — przy polu, w którym się pisze.

   Osobno od `.ramka-podgladu`: tamta izoluje CAŁY szablon maila w `iframe`,
   ta pokazuje sam układ treści wprost na stronie. Nie ma tu stylów maila,
   więc nie ma czego izolować — a `iframe` odświeżany przy każdym klawiszu
   mrugałby na biało.

   Skryptu może nie być; wtedy ramka zostaje `hidden` i ekran wygląda jak
   przed 2026-09-12. */
.ramka-podgladu-zywo {
	margin: 10px 0 4px;
	padding: 12px 14px;
	border: 1px solid var(--obramowanie);
	border-radius: var(--r);
	background: var(--tlo);
}

/* ── LICZNIK ZNAKÓW PRZY POLU TŁUMACZONYM ──────────────────────────────────

   Milczy, dopóki nie ma o czym mówić (`static/formularze.js` odsłania go na
   ostatniej piątej części limitu). Po przekroczeniu zmienia ton na bursztyn
   „uwagi" — nie na czerwień błędu: nic się nie zepsuło i nic nie jest
   zablokowane, tylko tłumaczenie obejmie sam początek tekstu.            */
.licznik-znakow { margin-top: 4px; }

/* Bursztyn „uwagi", nie czerwień błędu: nic się nie zepsuło i nic nie jest
   zablokowane — tekst jest tylko dłuższy, niż zmieści się w jednym
   tłumaczeniu albo w wierszu skrzynki odbiorcy. Ta sama klasa obsługuje
   licznik przy polu i dopisek przy temacie w podglądzie.                 */
.za-dlugie {
	color: var(--uwaga);
	font-weight: 600;
}

/* ── TEMAT I OSTRZEŻENIE W RAMCE PODGLĄDU ──────────────────────────────────

   Temat idzie tą samą wiadomością co treść i jest jedyną rzeczą, którą
   odbiorca widzi przed jej otwarciem — a tłumaczenie zmienia go razem
   z treścią. Stoi więc NAD panelami, nie obok nich.                      */
.podglad-temat {
	margin-bottom: 8px;
	padding-bottom: 8px;
	border-bottom: 1px solid var(--obramowanie-2);
}
.podglad-temat .pod { display: block; }
.podglad-temat strong { font-size: var(--tekst-wiersz); }

/* Znacznik, którego system nie umie podstawić. Tło, nie tylko kolor tekstu:
   to jest rzecz, która wyjdzie do klienta dosłownie.                     */
.podglad-ostrzezenie {
	margin: 0 0 8px;
	padding: 8px 10px;
	border-radius: 6px;
	background: var(--zly-tlo);
	color: var(--zly);
	font-size: var(--tekst-drobny);
}
.podglad-ostrzezenie code {
	font-family: var(--mono);
	font-size: .95em;
}

/* ── PISZESZ PO LEWEJ, WIDZISZ PO PRAWEJ ───────────────────────────────────

   Do 2026-09-12 pole treści zajmowało całą szerokość, a ramka podglądu stała
   POD nim. Przy treści na szesnaście wierszy znaczyło to, że wyniku nie widać
   podczas pisania — trzeba było przewinąć, obejrzeć, przewinąć z powrotem.
   Przy poprawianiu jednego akapitu kilkanaście razy.

   `auto-fit` z `minmax`, nie sztywne kolumny: ten sam zapis obsługuje trzy
   szerokości bez trzech progów w zapytaniach medialnych.

     * szeroki monitor  → pole | HTML | tekst  (trzy panele obok siebie)
     * laptop           → pole | HTML,  tekst schodzi pod spód
     * telefon          → wszystko jedno pod drugim

   360 px to najwęższy panel, w którym akapit maila nadal czyta się jak
   akapit, a nie jak kolumna gazety. Poniżej tej granicy lepsza jest jedna
   kolumna niż dwie złe — ta sama zasada, co przy `.kartoteka` w paśmie
   801–1040 px. */
/* `min(360px, 100%)` (2026-09-26): przy 390 px karta ma ok. 320 px, a kolumna
   „najmniej 360” wystawała poza nią — pole treści, „Wygląd” i podgląd
   przewijały stronę w bok. Poniżej 360 px kolumna bierze całą szerokość. */
.edytor-z-podgladem {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(360px, 100%), 1fr));
	gap: 14px;
	align-items: start;
}

/* `min-width: 0` na dzieciach gridu — bez tego długi wyraz albo wklejony
   adres rozpycha kolumnę ponad przydzieloną szerokość i cały układ ucieka
   w bok. Ta sama poprawka, co przy `.kolumna-lewa`. */
.edytor-z-podgladem > * { min-width: 0; }

/* Pole treści rośnie do wysokości panelu obok, żeby oba kończyły się w tym
   samym miejscu. `resize: vertical` zostaje — człowiek ma prawo je rozciągnąć. */
.edytor-z-podgladem textarea { min-height: 320px; }

/* Panel podglądu: nagłówek mówi, CO to jest. Bez nagłówków dwa bloki tekstu
   obok siebie wyglądają jak dwie wersje treści, a nie jak jedna treść w dwóch
   postaciach — a to jest cała różnica. */
.podglad-panel {
	border: 1px solid var(--obramowanie);
	border-radius: var(--r);
	background: var(--panel-2);
	padding: 10px 12px;
	min-width: 0;
}

.podglad-naglowek {
	margin: 0 0 8px;
	font-size: var(--tekst-podpis);
	font-weight: 600;
	color: var(--tekst-2);
	text-transform: uppercase;
	letter-spacing: .04em;
}

/* Dwa panele wewnątrz ramki podglądu, gdy ramka stoi sama (bez pola obok) —
   na przykład przy wersji językowej rozwiniętej w zwijce. Ten sam `auto-fit`,
   węższy próg: tutaj panele dzielą szerokość jednej kolumny, nie całego
   ekranu. */
.podglad-panele {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
	gap: 10px;
	align-items: start;
}

/* Ekran pełnego podglądu kampanii: RÓWNE kolumny.

   Nie `.kartoteka` — tam lewa kolumna ma 260–340 px, bo niesie kartę danych
   firmy. Tutaj obie niosą treść maila: po lewej to, co wpisano, i wersja
   tekstowa, po prawej złożony HTML. Do 2026-09-12 źródło stało POD ramką
   HTML w tej samej kolumnie, czyli dokładnie te dwie rzeczy, które trzeba
   porównać, były jedna pod drugą.

   `min(380px, 100%)`, nie gołe 380 px: telefon ma 375 px, po odjęciu
   marginesów kolumna dostaje 343 — i przez jedenaście dni każdy z trzech
   ekranów podglądu przewijał się w bok (zmierzone 2026-09-23, D387). */
.podglad-kolumny {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(380px, 100%), 1fr));
	gap: 16px;
	align-items: start;
}

/* Przełącznik wariantu podglądu: HTML czy wersja tekstowa.

   Wysyłka składa OBIE i obie dochodzą do odbiorcy — ramka przy polu
   pokazywała do 2026-09-12 tylko pierwszą. Przyciski, nie odnośniki:
   przeładowanie strony zabrałoby niezapisaną treść z pola.

   Od 2026-09-12 domyślnie widać OBA panele naraz, a te przyciski zwężają
   widok do jednego — przydają się na wąskim ekranie i przy bardzo długiej
   treści, gdzie dwie kolumny obok siebie zaczynają przeszkadzać. */
.podglad-warianty {
	display: flex;
	gap: 6px;
	margin: 6px 0 10px;
	flex-wrap: wrap;
}

/* Wersja tekstowa ma wyglądać jak tekst, a nie jak strona: stały krój,
   zachowane łamania, żadnych nagłówków ani pogrubień. Tak ją zobaczy
   klient z wyłączonym HTML-em. */
.podglad-panel .podglad-tekst-zywy {
	margin: 0;
	white-space: pre-wrap;
	overflow-wrap: anywhere;
	font-family: var(--mono, ui-monospace, Consolas, monospace);
	font-size: var(--tekst-podpis);
}

/* Wnętrze panelu — HTML złożony przez serwer albo `<pre>` wersji tekstowej.
   Przewijanie jest NA PANELU, nie na całej ramce: dwa panele obok siebie
   mają się kończyć w tym samym miejscu, a długość treści w jednym nie może
   przesuwać drugiego. */
.podglad-panel > :not(.podglad-naglowek) {
	font-size: var(--tekst-bazowy);
	line-height: 1.55;
	overflow-wrap: anywhere;   /* wklejony adres nie rozpycha karty */
}

.podglad-panel {
	max-height: 380px;
	overflow-y: auto;
}

.podglad-panel > :nth-child(2) { margin-top: 0; }
.podglad-panel > :last-child { margin-bottom: 0; }
.podglad-panel h2 { font-size: 1.15em; }
.podglad-panel h3 { font-size: 1.05em; }

.podglad-zastrzezenie { margin-top: 8px; }

/* Podgląd, którego nie udało się odświeżyć — sieć w hotelu bywa taka, jaka
   jest. Przygaszony, żeby nie udawał aktualnego, i bez komunikatu błędu:
   to jest wygoda, a nie warunek pracy. */
.podglad-nieaktualny .podglad-panele { opacity: .45; }
.podglad-nieaktualny .podglad-zastrzezenie::after {
	content: " Nie odświeżyłem ostatniej zmiany — sprawdź połączenie.";
	color: var(--zly);
}

/* Wersja tekstowa i źródło. `pre-wrap`, żeby długie akapity nie robiły
   poziomego paska na całą szerokość ekranu — mail tekstowy nie ma
   sztywnych łamań i nie powinien ich udawać w podglądzie. */
.podglad-tekst {
	white-space: pre-wrap;
	font-family: inherit;
	font-size: var(--tekst-podpis);
	background: var(--tlo);
	padding: 14px;
	border-radius: var(--r);
	border: 1px solid var(--obramowanie);
	overflow-x: auto;
	max-height: 420px;
}

/* Przełącznik formatu treści — jeden dla całego systemu
   (`templates/_format-tresci.html`).

   Wygląda jak przełącznik, a nie jak pole formularza, i to jest cały
   powód jego istnienia. Jako lista rozwijana wśród innych pól był
   przewijany bez czytania — a od niego zależy, czy `**Cena**` dotrze
   do klienta jako pogrubienie, czy jako gwiazdki. */
.format-tresci {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
	margin: 6px 0 8px;
}

.format-opcja {
	flex: 1 1 200px;
	display: grid;
	grid-template-columns: auto 1fr;
	grid-template-areas: "radio nazwa" "radio opis";
	gap: 0 10px;
	align-items: center;
	padding: 10px 12px;
	border: 1px solid var(--obramowanie);
	border-radius: var(--r);
	cursor: pointer;
	background: var(--panel);
}

.format-opcja input { grid-area: radio; margin: 0; }
.format-nazwa { grid-area: nazwa; font-weight: 600; }
.format-opis  { grid-area: opis; font-size: var(--tekst-drobny); color: var(--tekst-3); }

/* Wybrana opcja ma być widoczna z odległości metra — inaczej trzeba
   szukać, który krążek jest zaznaczony, i wybór znowu staje się polem
   formularza zamiast przełącznika. */
.format-opcja:has(input:checked) {
	border-color: var(--zielen);
	box-shadow: inset 0 0 0 1px var(--zielen);
	background: var(--zielen-mgla);
}

/* Obrys od klawiatury na całym kafelku, nie na samym krążku: krążek jest
   mały, a kafelek jest tym, w co się klika. */
.format-opcja:has(input:focus-visible) {
	outline: 2px solid var(--zielen);
	outline-offset: 2px;
}

/* Usunięcie danych osobowych (RODO art. 17) w kartotece.
   Schowane w `details`, bo to operacja nieodwracalna — przycisk w rzędzie
   z „Zadzwoń" zapraszałby do kliknięcia. Rozwinięcie jest tu barierą
   z premedytacją, a nie oszczędnością miejsca. */
.usuwanie-danych { margin-top: 8px; }
.usuwanie-danych summary { cursor: pointer; color: var(--zly); }
.usuwanie-danych input { margin: 6px 0; font-family: var(--mono); font-size: var(--tekst-drobny); }

/* Poprawianie danych w kartotece — zwinięte, bo patrzy się częściej niż
   poprawia. Nie jest to bariera jak przy usuwaniu danych osobowych, tylko
   porządek: rozwinięte formularze zasłoniłyby to, po co się tu wchodzi.

   Blok stał tu DWA RAZY, jeden pod drugim, z tym samym komentarzem
   i tymi samymi trzema regułami. Druga kopia nic nie zmieniała (te same
   wartości), ale kopia, która nic nie zmienia, jest gorsza od zwykłego
   powtórzenia: przy poprawce trafia się w jedną z dwóch i połowa reguł
   zostaje po staremu. */
.edycja-danych { margin-top: 10px; }
.edycja-danych summary { cursor: pointer; }
.edycja-danych .pole { margin-top: 8px; }

/* --- kartoteka: nagłówek, pasek akcji, zakładki (2026-09-09, D53) ---------
   Historia kontaktu ma być pierwsza, a każda czynność przy kliencie ma
   jedno miejsce startu — pasek pod nazwą firmy. Bez JavaScriptu wszystkie
   panele są widoczne jeden pod drugim; `kartoteka.js` pokazuje jeden naraz. */

.kartoteka-naglowek {
	display: flex;
	flex-direction: column;
	gap: 12px;
	margin: -6px 0 18px;
}
.plakietki-firmy {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px 10px;
}
.etap-inline {
	display: flex;
	align-items: center;
	gap: 6px;
	margin: 0;
}
.etap-inline label { margin: 0; white-space: nowrap; }
.etap-inline select { width: auto; padding: 5px 8px; font-size: var(--tekst-podpis); }

.pasek-akcji {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	align-items: center;
}
.pasek-akcji .przycisk { padding: 7px 14px; }

/* Rozwijka w pasku: `details` bez znacznika trójkąta, z listą przycisków
   pod spodem. Działa bez JS — to zwykłe `details`. */
.menu-akcji { position: relative; }
.menu-akcji > summary { list-style: none; cursor: pointer; }
.menu-akcji > summary::-webkit-details-marker { display: none; }
.menu-akcji-lista {
	position: absolute;
	z-index: 20;
	top: calc(100% + 4px);
	left: 0;
	min-width: 240px;
	background: var(--panel);
	border: 1px solid var(--obramowanie);
	border-radius: var(--r);
	box-shadow: var(--cien);
	padding: 6px;
	display: flex;
	flex-direction: column;
	gap: 2px;
}
.menu-akcji-lista form { margin: 0; }
.menu-akcji-lista button {
	display: block;
	width: 100%;
	text-align: left;
	background: none;
	border: 0;
	padding: 8px 10px;
	font: inherit;
	color: var(--tekst);
	border-radius: 6px;
	cursor: pointer;
}
.menu-akcji-lista button:hover { background: var(--panel-2); }
/* Odnośniki w tej samej liście — menu „⋯” Poczty (D435) miesza przejścia
   z akcjami, więc oba mają wyglądać tak samo. W nagłówku lista otwiera się
   w lewo: przy prawej krawędzi ekranu inaczej wychodziłaby poza niego. */
.menu-akcji-lista a {
	display: block;
	padding: 8px 10px;
	color: var(--tekst);
	border-radius: 6px;
	text-decoration: none;
}
.menu-akcji-lista a:hover { background: var(--panel-2); }
.naglowek-akcje .menu-akcji-lista { left: auto; right: 0; }

/* ── EKRANY WYSYŁKI I JEJ WIADOMOŚCI (2026-09-26, [[08_DECYZJE]] D540–D544) ──
   Nazwa wysyłki w nagłówku prowadzi do przeglądu, a „Ustawienia wysyłki”
   stoi przy niej małym odnośnikiem — z pięciu etapów i trzech ekranów
   wiadomości nie było drogi ani do jednego, ani do drugiego. */
.tytul-wysylki { color: inherit; text-decoration: none; }
.tytul-wysylki:hover, .tytul-wysylki:focus-visible {
	color: var(--zielen);
	text-decoration: underline;
}
.przy-tytule {
	margin-left: 12px;
	font-size: var(--tekst-podpis);
	font-weight: 400;
	color: var(--zielen);
	white-space: nowrap;
	vertical-align: middle;
}
/* Nazwa wiadomości na jej ekranach — plakietka jak w wierszu „Nowej
   wysyłki”, ale nagłówkiem (`h2`), bo to ona mówi, co jest otwarte. */
.tytul-wiadomosci { margin: 0; }
.tytul-ekranu-wiadomosci {
	margin: 0 0 14px;
	font-size: var(--tekst-bazowy);
	font-weight: 600;
}
.glowka-edycji { margin-bottom: 14px; }
/* „Popraw z AI” bez asystenta (D543) — wyszarzony, powód stoi pod nim. */
.wiadomosc-korekta .przycisk[disabled] {
	color: var(--tekst-3);
	background: var(--panel-2);
	border-color: var(--obramowanie);
}
.format-wysylki { margin: 12px 0; }
/* Lista „Wiadomości” (D540): karta na wiadomość, przyciski w jednym rzędzie.
   Menu „⋯” rozwija się pod CAŁYM rzędem, od jego lewej krawędzi — przypięte
   do samego „⋯” na 390 px wychodziło poza ekran (w prawo: przewijanie
   w bok, w lewo: ucięte pozycje). */
.wiadomosc-na-liscie .zdarzenie-tresc { margin: 4px 0 10px; color: var(--tekst-2); }
.wiadomosc-przyciski {
	position: relative;
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 6px;
}
.menu-wiadomosci { position: static; }
.menu-wiadomosci .menu-akcji-lista {
	left: 0;
	right: auto;
	max-width: 100%;
}
.menu-akcji-lista .pozycja-usun { color: var(--zly); }
.menu-akcji-lista .pozycja-opis { display: block; padding: 6px 10px; max-width: 260px; }
/* Wersja językowa pod swoją wiadomością — jeden zwarty wiersz. */
.wiersz-wersji {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 6px 10px;
	padding: 8px 12px;
}
.wiersz-wersji .wersja-temat { flex: 1 1 160px; min-width: 0; overflow-wrap: anywhere; }
.wiersz-wersji .wersja-akcje { display: inline-flex; align-items: center; gap: 6px; font-size: var(--tekst-podpis); }
.wiersz-wersji .wersja-akcje form { margin: 0; }
.wiersz-dokladania { display: flex; align-items: center; gap: 8px; }
/* Klauzula art. 14 do przepisania — zaznacza się jednym kliknięciem. */
.klauzula-art14 { white-space: pre-wrap; user-select: all; }
[data-klauzula-dla][hidden] { display: none; }

/* Informacja RODO pod treścią Pierwszej wiadomości „Nowej wysyłki”
   (2026-09-27, [[08_DECYZJE]] D671) — rozwijka jak lista odbiorców:
   rozwinięta, gdy w segmencie są kontakty z importu. Pole „Skąd masz te
   adresy?” i „Wstaw na końcu treści” — ta sama część na ekranie
   poprawiania pierwszej wiadomości. */
.karta-art14 {
	margin: 12px 0 0;
	padding: 8px 12px;
	border: 1px solid var(--obramowanie);
	border-radius: var(--r);
	background: var(--panel-2);
}
.karta-art14 > summary { cursor: pointer; padding: 2px 0; }
.karta-art14[open] > summary { margin-bottom: 6px; }
.karta-art14 > p { margin: 0 0 8px; }
.wstaw-klauzule .pole { margin-bottom: 8px; }
.wstaw-klauzule .przyciski-asystenta { flex-wrap: wrap; align-items: center; }
[data-klauzula-ze-skryptem][hidden] { display: none; }

/* Pasek zakładek kartoteki firmy — ZWYKŁE odnośniki do pięciu ekranów
   (`kontakty/zakladki_firmy.py`). Do 2026-09-14 stały tu zakładki
   przełączane JavaScriptem: bez skryptu wszystkie trzy panele leżały
   jeden pod drugim, a adres nie mówił, na który się patrzy. */
.zakladki-kartoteki { margin-top: 2px; }
.zakladki-kartoteki .licznik-menu { margin-left: 6px; }

.wiecej-osoby { margin-top: 6px; }
.wiecej-osoby > summary { color: var(--tekst-3); }
/* Strzałka „▾” jest w napisie — bez tej reguły obok stał jeszcze znacznik
   `<details>` i było „▸ więcej ▾” (2026-10-03, [[08_DECYZJE]] D794). */
.wiecej-osoby > summary { list-style: none; }
.wiecej-osoby > summary::-webkit-details-marker { display: none; }
.wiecej-osoby .edycja-danych, .wiecej-osoby form.osoba-pod { margin-top: 8px; }

/* --- pasek etapów kampanii (2026-09-09, D54) ------------------------------
   Pięć pól: cztery kroki i wyniki. Zrobione — zielone, bieżący — wypełniony,
   przyszłe — szare. Odnośniki prowadzą do kart na tym samym ekranie. */
.etapy-kampanii {
	display: flex;
	flex-wrap: wrap;
	gap: 6px 18px;
	list-style: none;
	margin: -4px 0 20px;
	padding: 0;
	font-size: var(--tekst-wiersz);
}
.etapy-kampanii li { display: flex; align-items: center; color: var(--tekst-3); }
.etapy-kampanii a, .etapy-kampanii li > span { display: inline-flex; align-items: center; gap: 8px; text-decoration: none; color: inherit; }
.etapy-kampanii a:hover { color: var(--tekst); }
.etapy-kampanii .numer {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 24px;
	height: 24px;
	border-radius: 50%;
	border: 1px solid var(--obramowanie);
	background: var(--panel);
	font-size: var(--tekst-drobny);
	font-weight: 600;
}
.etapy-kampanii li.zrobiony { color: var(--zielen-ciemna); }
.etapy-kampanii li.zrobiony .numer { border-color: var(--zielen); color: var(--zielen); background: var(--zielen-mgla); }
.etapy-kampanii li.biezacy { color: var(--tekst); font-weight: 600; }
.etapy-kampanii li.biezacy .numer { background: var(--zielen); border-color: var(--zielen); color: var(--na-zieleni); }
.etapy-kampanii li + li::before { content: "→"; margin-right: 18px; color: var(--obramowanie); }
/* Otwarty ekran (D460): podkreślona nazwa. Kółko mówi, gdzie wysyłka czeka,
   podkreślenie — gdzie jesteś; do 2026-09-25 był tylko pierwszy znak. */
.etapy-kampanii li.otwarty { color: var(--tekst); font-weight: 600; }
.etapy-kampanii li.otwarty .etap-nazwa { border-bottom: 2px solid var(--zielen); padding-bottom: 2px; }
/* Na telefonie pięć etapów łamało się na trzy linie, a strzałki „→” wisiały
   na początku drugiej i trzeciej (D794). Siatka w dwóch kolumnach, kolejność
   niosą numery w kółkach. */
@media (max-width: 640px) {
	.etapy-kampanii { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px 12px; }
	.etapy-kampanii li + li::before { content: none; }
}

/* Zdanie pod nagłówkiem pozycji menu bez zakładek (2026-09-09, D66).
   „Kogo dziś dzwonię" jest lepszym opisem ekranu niż słowo „Telefony" —
   ale nagłówek ma brzmieć tak, jak droga, którą się na ekran weszło.
   Zdanie schodzi więc o linijkę niżej, zamiast znikać. */
.naglowek-podtytul { margin: 2px 0 0; }

/* Linia stanu pod paskiem etapów (2026-09-09, D64). Kampania i sekwencja
   w biegu mają swoje liczby na wierzchu, a komplet wyników stoi pod etapem
   piątym — czyli tam, gdzie pasek go zapowiada. Jeden wiersz, nie siedem
   kart: przed pierwszą wysyłką te karty pokazywały same zera. */
.linia-stanu {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 6px 18px;
	margin: -6px 0 18px;
	font-size: var(--tekst-podpis);
	color: var(--tekst-2);
}
.linia-stanu > a { margin-left: auto; }

/* --- wspólny filtr firm (2026-09-09, D55) ---------------------------------- */
.filtr-linia select[name="segment"] { width: auto; min-width: 180px; max-width: 260px; }
.filtr-wiecej { margin-top: -4px; margin-bottom: 12px; }
.filtr-wiecej > summary { cursor: pointer; margin-bottom: 8px; }
/* Zwinięty filtr kończy się na „więcej filtrów” — bez pustego pasa pod spodem. */
.filtr-wiecej:last-child { margin-bottom: 0; }
.filtr-wiecej:not([open]) > summary { margin-bottom: 0; }

/* Rozwijka „zmień nazwę" przy segmencie (D58). Nazwa jest identyfikatorem
   wiersza i ma być czytelna; poprawka to czynność raz w życiu segmentu,
   więc chowa się pod rozwijką — tak samo jak „więcej ▾" przy osobie. */
.wiecej-segmentu { margin-top: 4px; }
.wiecej-segmentu summary { cursor: pointer; font-size: var(--tekst-drobny); }
.wiecej-segmentu form { margin-top: 6px; }

/* Trzy listy pod kafelkami pulpitu (D60). Pulpit odpowiada na pytanie
   „czym mam się dziś zająć" — do 2026-09-09 odpowiadał pięcioma liczbami,
   a instrukcja odsyłała stąd do zakładki Zadania. */
.pulpit-listy {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
	gap: 14px;
	margin-bottom: 18px;
}
.glowka-listy {
	display: flex;
	justify-content: space-between;
	align-items: baseline;
	gap: 10px;
}
.glowka-listy .etykieta { margin: 0; }
.wiersz-pulpitu {
	padding: 8px 0;
	border-top: 1px solid var(--obramowanie-2);
}
.wiersz-pulpitu:first-of-type { border-top: 0; }
.wiersz-pulpitu a { text-decoration: none; }
.wiersz-pulpitu a:hover { text-decoration: underline; }

/* Kafle pulpitu na telefonie — dwa w rzędzie, niższe (2026-09-27,
   [[08_DECYZJE]] D627). Jeden pod drugim zajmowały 640 px, a pierwsze
   zadanie na dziś stało na 1230–1550 px: półtora do dwóch ekranów
   przewijania przed odpowiedzią „co dziś zrobić”. */
@media (max-width: 800px) {
	.karty-pulpitu { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
	.karty-pulpitu .karta { padding: 10px 12px; }
	.karty-pulpitu .liczba { font-size: 22px; }
	.karty-pulpitu .etykieta { letter-spacing: 0; }
}

/* ===========================================================================
   Odstępy, szerokości i paski filtrów — nazwane, zamiast wpisywanych
   w każdy szablon z osobna (2026-09-10, [[08_DECYZJE]] D73)

   Skąd to
   -------
   W szablonach stało 157 atrybutów `style="…"`, z czego 84 to sam
   `margin-top` w SIEDMIU wartościach — 4, 6, 8, 10, 12, 14 i 16 px —
   używanych zamiennie w tej samej roli: odstęp nad zdaniem pod polem
   formularza. Reguły, która mówi „kiedy 8, a kiedy 10", nie było, bo nie
   dało się jej mieć: każdy odstęp powstawał osobno, przy pisaniu szablonu.

   Skutek widać przy przechodzeniu między ekranami jednego modułu: formularz
   kampanii oddzielał sekcje o 10 px, formularz dostawcy o 16 px, a krok
   sekwencji o 6 px. Interfejs „drgał", choć każdy ekran z osobna wyglądał
   dobrze. Drugi skutek jest utrzymaniowy i to on decyduje przy przekazaniu
   systemu: zmiana rytmu pionowego wymagała poprawki w kilkunastu plikach.

   Skala ma TRZY stopnie i to jest wybór, nie oszczędność. Siedem wartości
   nie niosło siedmiu znaczeń — niosło trzy: „tuż pod czymś", „nowy blok
   w karcie", „nowa sekcja". Więcej stopni to znowu zgadywanie.

       .odstep-maly    8px    zdanie pod polem, przycisk pod formularzem
       .odstep        12px    kolejny blok wewnątrz karty
       .odstep-duzy   20px    następna sekcja ekranu

   Czego tu CELOWO nie ma: klas w rodzaju `.mt-8`. Nazwa mówiąca wartość
   jest tym samym stylem inline, tylko przeniesionym — po pierwszej zmianie
   rytmu `.mt-8` zaczyna dawać 10 px i kłamie. Nazwy mówią ROLĘ.
   =========================================================================== */

.odstep-maly { margin-top: 8px; }
.odstep      { margin-top: 12px; }
.odstep-duzy { margin-top: 20px; }

/* Druga strona tej samej skali — odstęp POD elementem.
 *
 * Dopisane 2026-09-10, kiedy kontrola `OdstepMaNazwe` zaczęła łapać wszystkie
 * pisownie marginesu w atrybucie `style`, nie tylko `margin-top: Npx`.
 * Wyszło wtedy dwadzieścia jeden miejsc w jedenastu szablonach, pisanych
 * skrótem (`margin:6px 0 0`, `margin-bottom:14px`, `margin:0`) i dlatego
 * niewidocznych dla poprzedniej wersji testu.
 *
 * Wartości są TE SAME co w skali górnej. Nowe stopnie (4 px, 6 px, 10 px,
 * 14 px) nie powstały — po to jest skala, żeby cztery prawie-takie-same
 * wartości zeszły do jednej.
 *
 * Jeden stopień, nie trzy: tyle jest potrzebnych. Odpowiedników `-maly`
 * i `-duzy` nie ma, dopóki nikt ich nie używa — martwa reguła w arkuszu
 * kosztuje kwadrans następnemu czytającemu (`testy_spojnosci_stylu`
 * sprawdza to z obu stron). */
.odstep-dolny { margin-bottom: 12px; }

/* Zerowanie marginesu elementu, który ma swój własny (lista, `<pre>`,
   `<details>` w komórce tabeli). `margin: 0` wpisane inline stało w czterech
   miejscach. */
.bez-odstepu { margin: 0 !important; }

/* Zdanie wyjaśniające POD paskiem filtra — na liście, lejku, telefonach
   i w domu segmentów. Ujemny margines górny jest tu celowy: pasek wyniku
   filtra ma własny odstęp dolny, a bez ściągnięcia zdanie odrywa się od
   tego, co opisuje. */
.pod-filtrem { margin: -6px 0 16px; }

/* Tekst z serwera, w którym łamania linii ZNACZĄ: ostatni błąd IMAP,
   ostatni błąd kampanii, instrukcja z ekranu Gotowości. Krój dziedziczony,
   bo to nie jest kod — `<pre>` służy tu wyłącznie zachowaniu układu. */
.tekst-zachowany {
	white-space: pre-wrap;
	font-family: inherit;
	margin: 8px 0 0;
}

/* INSTRUKCJA OBSŁUGI (`panel/pomoc.html`) — wyrenderowana z pliku przez
 * `panel/instrukcja_html.py` (2026-09-18, D269). Do tego dnia stała tu
 * postać źródłowa w `<pre>` krojem maszynowym: gwiazdki, `###` i kreski tabel
 * w jedynym dokumencie pisanym dla handlowca.
 *
 * Akapity i listy mają ograniczoną szerokość — wiersz na całe okno czyta się
 * źle. Tabele nie: mają kolumny i przewijają się w bok, gdy się nie mieszczą,
 * zamiast mieszać zawartość komórek. */
.instrukcja {
	margin: 0;
	line-height: 1.65;
}
.instrukcja p,
.instrukcja ul,
.instrukcja ol,
.instrukcja blockquote { max-width: 80ch; margin: 0 0 12px; }
.instrukcja ul,
.instrukcja ol { padding-left: 22px; }
.instrukcja li { margin-bottom: 4px; }
.instrukcja h2,
.instrukcja h3,
.instrukcja h4 { margin: 24px 0 8px; line-height: 1.3; }
.instrukcja h2 { font-size: var(--tekst-naglowek); }
.instrukcja h3 { font-size: var(--tekst-bazowy); }
.instrukcja h4 { font-size: var(--tekst-wiersz); }
.instrukcja > :first-child { margin-top: 0; }
.instrukcja blockquote {
	padding: 8px 14px;
	border-left: 3px solid var(--obramowanie);
	background: var(--panel-2);
	color: var(--tekst-2);
}
.instrukcja blockquote > :last-child { margin-bottom: 0; }
.instrukcja hr { border: 0; border-top: 1px solid var(--obramowanie-2); margin: 20px 0; }
.instrukcja pre {
	margin: 0 0 12px;
	padding: 10px 12px;
	font-family: var(--mono);
	font-size: var(--tekst-drobny);
	background: var(--panel-2);
	overflow-x: auto;
}
.instrukcja-tabela { overflow-x: auto; margin: 0 0 14px; }
/* Polecenia z serwera zwinięte (2026-10-02, [[08_DECYZJE]] D752) — zwijka
   w kolorach cytatu, bo to ten sam rodzaj dopisku na marginesie. */
.instrukcja details.dla-technicznej {
	max-width: 80ch;
	margin: 0 0 12px;
	padding: 6px 14px;
	border-left: 3px solid var(--obramowanie);
	background: var(--panel-2);
	color: var(--tekst-2);
}
.instrukcja details.dla-technicznej > summary { cursor: pointer; font-size: var(--tekst-podpis); }
.instrukcja details.dla-technicznej[open] > summary { margin-bottom: 6px; }
.instrukcja details.dla-technicznej > :last-child { margin-bottom: 0; }

/* Lista kroków instrukcji z własnym wcięciem — numerowana droga
   konfiguracji dostawcy, wyliczenie w podglądzie kampanii. */
.lista-kroku {
	margin: 8px 0 0;
	padding-left: 20px;
	line-height: 1.9;
}
.lista-kroku > li { margin-bottom: 4px; }

/* ── CZYM PISZĄ ODBIORCY — WEWNĄTRZ KARTY WERSJI JĘZYKOWYCH ───────────────

   Ramka w ramce, bo to jest rozpoznanie stanu („kto dostanie co"), a karta,
   w której stoi, służy do działania („dopisz wersję"). Bez wydzielenia
   lista gubiła się między dwoma formularzami tej samej karty.          */
.karta-wewnetrzna {
	padding: 10px 12px;
	border: 1px solid var(--obramowanie-2);
	border-radius: 6px;
	background: var(--panel-2);
}

.lista-jezykow {
	margin: 6px 0 0;
	padding-left: 18px;
	font-size: var(--tekst-podpis);
	line-height: 1.8;
}

/* „Jest wersja" i „nie ma wersji" — ten sam kształt zdania, dwa kolory.
   Bursztyn, nie czerwień: brak wersji bywa poprawny (jeden język roboczy
   na kilka rynków), więc to uwaga, a nie błąd.                          */
.ok-wersja { color: var(--dobry); font-weight: 600; }
.brak-wersji { color: var(--uwaga); font-weight: 600; }

/* Temat wiadomości w podglądzie — jedyne miejsce, w którym temat jest
   treścią ekranu, a nie etykietą pola. */
.temat-podgladu {
	font-size: 16px;
	font-weight: 600;
	margin: 8px 0 0;
}

/* Formularz jednego obiektu: nowa firma, dostawca, nadawca, sekwencja,
   skrzynka. Do 2026-09-09 szerokość kolumny była wpisana w szablon i miała
   trzy wartości (820, 860 i raz 760 px) — przejście „Nowa firma" → „Nowa
   sekwencja" przesuwało pola o 40 px w bok. Jedna wartość, jedno miejsce. */
.formularz-jednego { max-width: 820px; }

/* Wąskie pole w rzędzie — wybór języka przy wersji i przy kroku sekwencji.
   Bez ograniczenia lista rozciąga się na całą kartę, choć jej najdłuższa
   pozycja ma dwadzieścia znaków. */
.pole-waskie { max-width: 220px; }

/* Pasek filtrów przełączających widok listy: odbiorcy kampanii, motyw
   podglądu. Klucz idzie w adresie, więc przełącznik jest zbiorem
   ODNOŚNIKÓW, nie formularzem — i dlatego potrzebuje własnego rzędu
   z odstępami, a nie `.przyciski-asystenta`, które opisuje co innego.

   Klasa `filtry-odbiorcow` stała w szablonie odbiorców od początku
   i NIE MIAŁA odpowiednika w arkuszu: rząd opierał się na domyślnym
   zawijaniu elementów liniowych, więc odstępy między przyciskami były
   inne niż w dwóch pozostałych paskach tego samego rodzaju. */
.filtry-odbiorcow {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	margin-bottom: 14px;
}

/* Podgląd szablonu maila bywa dłuższy niż podgląd pojedynczej wiadomości —
   ma nagłówek, treść i stopkę z wypisem. Wariant, nie druga kopia reguły:
   do 2026-09-09 dwa z trzech podglądów miały wysokość i ramkę wpisane
   inline, a wysokości rozjechały się o 60 px. */
.ramka-podgladu.wysoka { height: 620px; }

/* Pole, którego jedyną zawartością jest przycisk — w rzędzie `.wiersz-pol`
   ma usiąść w linii z polami obok.

   Do 2026-09-09 robiła to przekładka `<label>&nbsp;</label>`: pusta etykieta
   udająca etykietę, żeby przycisk zszedł na wysokość sąsiadów. Na szerokim
   oknie działała, ale w `@media (max-width: 800px)` rząd przechodzi na
   kolumnę — i pusty `&nbsp;` stawał się WIDOCZNYM pustym wierszem nad
   przyciskiem. Czytnik ekranu czytał go jako etykietę bez treści. */
.pole-przycisk > label { display: none; }
.pole-przycisk { display: flex; align-items: flex-end; }

/* Numer własny handlowca w tabeli Zespołu — krótki i stałej długości,
   więc pole nie ma powodu rozpychać kolumny. */
.pole-numer { max-width: 170px; }

/* Wiersz konta wyłączonego. Klasa `wylaczone` stała w szablonie Zespołu
   od jego powstania i NIE MIAŁA reguły w arkuszu: konto wyłączone wyglądało
   dokładnie jak czynne, a jedynym znakiem była plakietka na końcu wiersza. */
.tabela tr.wylaczone td { color: var(--tekst-3); }
.tabela tr.wylaczone td strong { font-weight: 500; }

/* Stopka boku: login, rola, a pod nimi dwie drogi — własne hasło
   i wylogowanie. Rząd, nie kolumna, bo obie mieszczą się w jednej linii
   i razem zajmują tyle miejsca, co samo „Wyloguj" wcześniej. */
.linie-konta {
	display: flex;
	align-items: baseline;
	gap: 12px;
	margin-top: 6px;
}
.linie-konta form { margin: 0; }

/* Pole wyboru („próba na sucho", „tylko do potwierdzonych zgód") wewnątrz
   karty, między zdaniem opisowym a przyciskiem. Odstęp był wpisywany
   inline w czterech miejscach, w dwóch różnych wartościach. */
.zgoda-w-karcie { margin: 12px 0; }

/* Formularz scalania pary duplikatów — jeden na każdą inną kartotekę
   w grupie, więc potrzebują odstępu między sobą. */
.formularz-scalania { margin-bottom: 10px; }

/* Przycisk stojący w jednej linii z nagłówkiem sekcji — potrzebuje odstępu
   od tekstu, żeby nie zlewał się z <h2>. */
.odstep-lewy { margin-left: 10px; }

/* ═══════════════════════════════════════════════════════════════════════════
   WYDRUK
   ═══════════════════════════════════════════════════════════════════════════

   Po co
   -----
   `raporty/views.eksport` nazywa odbiorcę wprost: „do arkusza, NA SPOTKANIE
   ZARZĄDU". Makieta zaakceptowana przez klienta ma blok `@media print`
   (`web/makieta/index.html`) — CRM nie miał go wcale, i nie był to brak
   kosmetyczny.

   Co było psute
   -------------
   `.przewijana { overflow-x: auto }` na ekranie przewija szeroką tabelę
   w jej kontenerze. Na papierze nie ma czego przewijać: nadmiar zostawał
   UCIĘTY przy krawędzi strony, bez żadnego znaku, że coś obcięto. Raport
   aktywności ma dziewięć kolumn liczbowych. Do tego drukowało się menu
   boczne, pole szukania i znaki zapytania dymków.

   Zasada: na papierze zostaje TREŚĆ i jej nagłówek. Wszystko, co służy
   do klikania, znika — przycisk na wydruku to martwy prostokąt.
   ═══════════════════════════════════════════════════════════════════════════ */
@media print {
	/* Cienie i tła paneli zjadają toner, a nic nie niosą na papierze. */
	body { background: #fff; font-size: 10.5pt; }

	/* Szkielet: jedna kolumna, bez boku. */
	.szkielet { display: block; min-height: 0; }
	.bok { display: none !important; }
	.tresc { padding: 0; }

	/* Wszystko, co jest do klikania albo do najechania. Dymki `?` mają sens
	   wyłącznie interaktywny — na papierze zostaje po nich sam znak. */
	.przycisk,
	.pasek-akcji,
	.pasek-masowy,
	.kolumna-wyboru,
	.zadanie-wybor,
	.zaznacz-sekcje,
	.filtr,
	.zapis-segmentu,
	.wyjasnienie,
	.stronicowanie,
	.doczytywanie,
	.wybor-okresu,
	.zadanie-przeloz,
	form[method="post"] button,
	.szukaj-globalne { display: none !important; }

	/* Nagłówek trzyma się swojej treści — inaczej tytuł raportu zostaje
	   na dole strony, a tabela zaczyna się na następnej. */
	.naglowek-strony { break-after: avoid; margin-bottom: 12pt; }
	.naglowek-strony h1 { font-size: 17pt; }
	.etykieta { break-after: avoid; }

	/* Karta nie dzieli się w pół między stronami. */
	.karta, .kpi, .karty > .karta {
		break-inside: avoid;
		box-shadow: none;
		border: 1px solid var(--obramowanie);
	}

	/* TABELE — sedno tej sekcji.
	   `table-layout: fixed` + łamanie długich słów zamiast przewijania:
	   adres e-mail albo nazwa firmy zawinie się, zamiast zniknąć za
	   krawędzią. `overflow: visible` zdejmuje kontener przewijania. */
	.przewijana { overflow: visible !important; }
	.tabela { font-size: 9pt; table-layout: fixed; width: 100%; }
	.tabela th, .tabela td {
		padding: 5pt 7pt;
		overflow-wrap: anywhere;
		word-break: break-word;
	}
	/* Na ekranie nagłówki i plakietki mają `nowrap`, żeby nie łamały się
	   w pół. Na papierze nadmiaru nie da się przewinąć, więc wolno im zawinąć. */
	.tabela th, .plakietka, .liczbowo { white-space: normal; }
	/* Nagłówek tabeli powtarza się na każdej stronie — bez tego druga
	   strona raportu to kolumny liczb bez podpisów. */
	.tabela thead { display: table-header-group; }
	.tabela tbody tr { break-inside: avoid; }

	/* Oś czasu kartoteki: jedno zdarzenie nie rozrywa się między stronami. */
	.zdarzenie { break-inside: avoid; }

	/* Lejek na papierze to lista kolumn jedna pod drugą — tablica
	   przewijana w poziomie nie ma na wydruku sensu. */
	.tablica { display: block; overflow: visible; }
	.tablica-poza-ekranem, .tablica-ramka::before, .tablica-ramka::after { display: none; }
	.kolumna { break-inside: avoid; margin-bottom: 10pt; width: auto; }
	.kolumna-glowka { position: static; }

	/* Odnośnik bez adresu jest na papierze nieodróżnialny od tekstu —
	   a w raporcie nazwy firm i kampanii SĄ odnośnikami. */
	a { color: inherit; text-decoration: none; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   SPIS TREŚCI INSTRUKCJI (2026-09-10)

   Ekran „Pomoc" wypisywał 1854 linie źródłowego Markdowna w jednym `<pre>`
   i mówił „szukaj Ctrl+F". Ctrl+F działa, ale trzeba wiedzieć, CZEGO szukać —
   a instrukcja jest pisana dla kogoś, kto jeszcze nie wie, jak nazywa się
   rzecz, o którą pyta.

   Dwie kolumny na szerokim oknie, jedna na wąskim: dwadzieścia dwa rozdziały
   w jednej kolumnie to ekran samego spisu.
   ═══════════════════════════════════════════════════════════════════════════ */
.spis-tresci ol {
	margin: 0;
	padding-left: 22px;
	columns: 2;
	column-gap: 32px;
}
.spis-tresci li { margin-bottom: 4px; break-inside: avoid; }
/* Spis podrozdziałów nad długim rozdziałem (D752) — oddzielony od treści. */
.spis-podrozdzialow {
	margin: 0 0 18px;
	padding-bottom: 14px;
	border-bottom: 1px solid var(--obramowanie-2);
}
@media (max-width: 800px) {
	.spis-tresci ol { columns: 1; }
}

/* Nagłówek rozdziału instrukcji. Odnośnik „↑ spis" NIE jest ozdobą: rozdział
   „Kampanie" ma trzysta linii, więc po dojściu do jego końca droga powrotna
   przez przewijanie to kilkanaście obrotów kółka. */
.rozdzial-instrukcji {
	margin: 0 0 10px;
	font-size: 17px;
	display: flex;
	align-items: baseline;
	gap: 12px;
}
.rozdzial-instrukcji:focus { outline: none; }

/* Zmiana etapu z karty lejka — droga DRUGA, nie pierwsza (2026-09-10).
 *
 * Przeciąganie zostaje drogą pierwszą dla myszy. To jest droga dla dotyku
 * i klawiatury, na których HTML5 drag-and-drop nie działa wcale.
 *
 * Zwinięte, bo rozwinięte w czterdziestu kartach przykryłoby to, po co się
 * na tablicę patrzy — nazwy firm. Ten sam wzorzec co `.rozmowa-recznie`
 * w kolejce telefonów, łącznie z tym, że na dotyku nie ma „najechania". */
.karta-etap { margin-top: 6px; }
.karta-etap > summary {
	cursor: pointer;
	color: var(--zielen);
	font-size: var(--tekst-plakietka);
}
.karta-etap form {
	display: flex;
	flex-direction: column;
	gap: 6px;
	margin-top: 6px;
}
.karta-etap select { font-size: var(--tekst-plakietka); padding: 4px 6px; }

/* „więcej ▾” w wierszu Odpowiedzi klientów (2026-10-07, [[08_DECYZJE]] D811).
 * W wierszu zostają „Odpowiedz” i „Nie wymaga odpowiedzi”; tłumaczenie,
 * streszczenie, etap i „Prosi o wypis” rozwijają się pod nimi, wyrównane
 * do prawej jak przyciski — na telefonie (karty) do lewej. „Prosi o wypis”
 * ostatnie i oddzielone kreską: nieodwracalne nie stoi przy codziennym. */
.wiecej-odpowiedzi { margin-top: 6px; }
.wiecej-odpowiedzi > summary {
	cursor: pointer;
	color: var(--zielen);
	font-size: var(--tekst-plakietka);
	/* „▾” jest w napisie — bez znacznika `<details>` obok (jak `.wiecej-osoby`, D794). */
	list-style: none;
}
.wiecej-odpowiedzi > summary::-webkit-details-marker { display: none; }
.wiecej-odpowiedzi-lista {
	display: flex;
	flex-direction: column;
	align-items: flex-end;
	gap: 6px;
	margin-top: 6px;
}
.wiecej-odpowiedzi-lista form { margin: 0; }
.etap-odpowiedzi {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: flex-end;
	gap: 6px;
}
.etap-odpowiedzi label { margin: 0; }
.etap-odpowiedzi select { width: auto; font-size: var(--tekst-plakietka); padding: 4px 6px; }
.wypis-odpowiedzi { padding-top: 6px; border-top: 1px solid var(--obramowanie-2); }
@media (max-width: 800px) {
	.wiecej-odpowiedzi-lista { align-items: flex-start; }
	.etap-odpowiedzi { justify-content: flex-start; }
}

/* Trzy paski okresu obok siebie na szerokim oknie, jeden pod drugim na wąskim.
   Osobne formularze, bo jeden musiałby rozstrzygać, co wygrywa przy obu
   wypełnionych — a rozstrzyga to `raporty/views._zakres`.

   POLE DATY MUSI MIEĆ SWOJĄ SZEROKOŚĆ ([[08_DECYZJE]] D381).

   Reguła ogólna nadaje `input[type="date"]` szerokość 100% — słusznie, bo
   pola dat stoją zwykle w formularzu jedno pod drugim. Tutaj stoją w PASKU
   FILTRA, więc każde z dwóch rozpychało się na całą wolną szerokość, pasek
   zawijał się na cztery rzędy, a „Okres" i „Handlowiec" rozjeżdżały się
   na boki wokół tej kolumny. Tak wyglądały wszystkie CZTERY raporty —
   zmierzone 2026-09-20 przy 1400 px: pasek 271 px wysokości zamiast 66.

   `max-content` zamiast `auto`: pole daty z `auto` w kontenerze flex nadal
   zgarnia wolne miejsce, bo `flex-basis` liczy się od zawartości dopiero
   przy `flex: 0 0 auto`. Szerokość treści („dd.mm.rrrr" + ikona kalendarza)
   jest tym, czego to pole potrzebuje, i niczym więcej. */
.paski-okresu {
	display: flex;
	flex-wrap: wrap;
	gap: 10px 26px;
	align-items: center;
	margin-bottom: 16px;
}
.paski-okresu .wybor-okresu { margin-bottom: 0; }
.paski-okresu input[type="date"] {
	width: max-content;
	flex: 0 0 auto;
	padding: 7px 9px;
}
/* Etykieta pola opisuje to, co stoi OBOK, nie pod spodem — inaczej pasek
   czyta się jak trzy formularze, a jest jednym filtrem. */
.paski-okresu label { color: var(--tekst-2); font-size: var(--tekst-drobny); }
.paski-okresu .pod { margin-left: 2px; }

.paski-okresu .pole-daty {
	display: inline-flex;
	align-items: center;
	gap: 8px;
}

/* Na telefonie pasek zawija się na rzędy — wtedy każdy formularz zajmuje
   całą szerokość, żeby etykiety stały w jednej kolumnie, a nie schodkami,
   a para „etykieta + pole daty" schodzi do następnego wiersza w całości. */
@media (max-width: 700px) {
	.paski-okresu { gap: 12px; }
	.paski-okresu > form { flex: 1 1 100%; }
	.paski-okresu .pole-daty { flex: 1 1 100%; }
	.paski-okresu .pole-daty label { flex: 0 0 4.2rem; }
	.paski-okresu .pole-daty input[type="date"] { flex: 1 1 auto; width: auto; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   SŁUPEK UDZIAŁU — raport konwersji lejka (2026-09-10)

   Osiem liczb w kolumnie procentów da się porównać dopiero po przeczytaniu
   wszystkich. Słupek pokazuje kształt lejka od razu — a to jest jedyne
   pytanie, z którym się na ten raport przychodzi: gdzie się zatyka.

   Rysowany SZEROKOŚCIĄ elementu, nie obrazkiem i nie biblioteką. Żadnego
   żądania do CDN-u — `Content-Security-Policy` w Caddym ma `default-src
   'self'` i by go nie przepuściło, a szósta zależność w projekcie, który ma
   stać latami, to szósta rzecz do aktualizowania.

   Kolor: akcent dla etapów w toku, zieleń „dobry" dla wygranego, czerwień
   dla zamkniętego bez sukcesu. Te same trzy znaczenia co plakietki obok,
   więc słupek i plakietka nie mogą powiedzieć czegoś innego.
   ═══════════════════════════════════════════════════════════════════════════ */
.slupek-komorka { width: 18%; min-width: 90px; max-width: 220px; }

/* ═══════════════════════════════════════════════════════════════════════════
   TABELE RAPORTÓW ([[08_DECYZJE]] D381)

   Nagłówek tabeli w całym systemie się NIE ZAWIJA (`.tabela thead th`)
   i to jest dobra reguła: „Ostatni kontakt" złamane na dwa wiersze wygląda
   jak dwie kolumny. Raporty mają jednak po dziesięć kolumn, a ich nagłówki
   są zdaniami („Dostało wiadomość", „Firm, które odpisały") — na
   „Skuteczności sekwencji" rozpychały tabelę do 1186 px przy 1108 px
   miejsca, więc kolumna z NAZWĄ sekwencji dostawała 96 px i łamała się
   na trzy wiersze, a ostatnia kolumna wyjeżdżała za krawędź. Zmierzone
   2026-09-20 przy oknie 1400 px, czyli na typowym laptopie.

   Zawijanie zdejmujemy więc tylko tu, gdzie nagłówki są zdaniami. Wartości
   w komórkach zawijać się nadal nie mogą — `.liczbowo` trzyma `nowrap`.
   ═══════════════════════════════════════════════════════════════════════════ */
.tabela.raport thead th { white-space: normal; }
/* Kolumna z nazwą: w raportach zawsze pierwsza i zawsze najważniejsza —
   to ona mówi, CZEGO dotyczy wiersz. */
.tabela.raport th:first-child,
.tabela.raport td:first-child { min-width: 10rem; }
/* „Razem” w stopce raportu Aktywność to `th scope="row"` — bez tej reguły
   przeglądarka centruje je w kolumnie nazw i wiersz sumy czytał się jak
   osobna, wcięta pozycja tabeli (2026-09-24, [[08_DECYZJE]] D394). */
.tabela tfoot th { text-align: left; padding: 10px 12px; }
.slupek {
	display: block;
	height: 10px;
	border-radius: 5px;
	background: var(--obramowanie-2);
	overflow: hidden;
}
.slupek-wypelnienie {
	display: block;
	height: 100%;
	background: var(--zielen);
	/* Zero procent ma być widoczne jako zero, nie jako brak słupka —
	   pusty tor mówi „zmierzone i wyszło zero", a brak toru nie mówi nic. */
	min-width: 0;
}
.slupek-wypelnienie.wygrany { background: var(--dobry); }
.slupek-wypelnienie.koncowy { background: var(--zly); }
/* „Bez etapu” to nie etap — słupek szary, bez znaczenia „w toku” (D657). */
.slupek-wypelnienie.bez-etapu { background: var(--tekst-3); }

/* Na wydruku tło elementu bywa pomijane („nie drukuj kolorów tła"), więc
   słupek zniknąłby, a kolumna została pusta. Obramowanie zostaje zawsze. */
@media print {
	.slupek { border: 1px solid var(--obramowanie); }
	.slupek-wypelnienie { background: var(--tekst-2) !important; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   IKONY POZYCJI MENU (2026-09-11)

   Dziewięć pozycji nazwanych samym tekstem czyta się słowo po słowie.
   Ikona daje kształt, po którym oko trafia w moduł bez czytania — a menu
   jest jedynym elementem, przez który przechodzi się kilkadziesiąt razy
   dziennie.

   `flex-shrink: 0` — przy długiej etykiecie („Ustawienia") ikona nie ma
   się zwężać w kreskę.

   NA TELEFONIE IKON NIE MA i to jest decyzja, nie oszczędność.
   Na wąskim ekranie menu przestaje być kolumną z boku i staje się poziomym
   paskiem NAD treścią (`@media (max-width: 800px)` wyżej). Każdy piksel
   jego szerokości przesuwa wtedy treść w dół, a D58 powstało właśnie po to,
   żeby zejść ze 150 px chromu nad pierwszą linijką. Ikona, która na
   szerokim oknie pomaga, na wąskim kosztowałaby trzeci rząd menu.
   ═══════════════════════════════════════════════════════════════════════════ */
.ikona-menu {
	width: 18px;
	height: 18px;
	flex-shrink: 0;
	opacity: .75;
}
.nawigacja a[aria-current="page"] .ikona-menu { opacity: 1; }
.nawigacja a:hover .ikona-menu { opacity: 1; }

@media (max-width: 800px) {
	.ikona-menu { display: none; }
}

/* Na wydruku menu i tak znika (`.bok { display: none }`), więc ikony
   nie potrzebują tam osobnej reguły. */

/* ── Zapytania ofertowe (2026-09-14) ───────────────────────────────────────
   Lista plików sprawy i wiadomości, z których pobiera się załączniki.
   Nazwa pliku bywa długa i bez spacji („ZO-2026-0014-dokumentacja-final…”),
   więc łamie się w dowolnym miejscu zamiast wypychać kartę w bok. */
.lista-plikow { list-style: none; margin: 8px 0 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.lista-plikow li { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; font-size: var(--tekst-wiersz); overflow-wrap: anywhere; }
.lista-plikow li > .pod { flex-basis: 100%; }
.lista-plikow form { display: inline; }

/* LISTA POŁĄCZEŃ — jedna linia na połączenie (2026-10-03, [[08_DECYZJE]] D794).
   Karta „Połączenia” w kartotece i „Wszystkie połączenia” pożyczały do tego
   dnia `.lista-plikow`, w której każdy `.pod` zajmuje cały wiersz: połączenie
   rozpadało się na 6–7 linii z „· jacek” na początku osobnej linii, a dwa
   połączenia zlewały się w jedno (zmierzone: 314 px na dwa). Kreska między
   połączeniami; formularz wyniku stoi pod swoim połączeniem, bez kreski. */
.lista-polaczen { list-style: none; margin: 8px 0 0; padding: 0; }
.lista-polaczen li {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 2px 8px;
	padding: 6px 0;
	border-top: 1px solid var(--obramowanie-2);
	font-size: var(--tekst-wiersz);
	overflow-wrap: anywhere;
}
.lista-polaczen li:first-child { border-top: 0; }
.lista-polaczen li.polaczenie-wynik { border-top: 0; padding-top: 0; }
.lista-polaczen form { display: inline; }

/* ════════════════════════════════════════════════════════════════════════════
   KAFLE PRZEGLĄDU USTAWIEŃ (2026-09-15)

   Osiem tematów Ustawień jako siatka, jeden kafel na temat: ikona, plakietka
   stanu, nazwa, jedno zdanie prawdziwego stanu. Cały kafel jest odnośnikiem.

   Dlaczego OSOBNA klasa, a nie `.karta`
   -------------------------------------
   `.karta` opisuje pudełko z etykietą i treścią i występuje na każdym ekranie
   systemu. Kafel przeglądu ma trzy rzeczy, których karta nie ma i mieć nie
   powinna: główkę z ikoną i plakietką rozepchaną na boki, obwódkę niosącą
   STAN, i minimalną wysokość równającą rząd przy różnej długości zdania.
   Dopisanie tego do `.karta` zmieniłoby wygląd kilkudziesięciu ekranów.

   `minmax(260px, 1fr)` — osiem kafli układa się w cztery kolumny przy 1280 px,
   trzy przy 1040, dwie przy 800 i jedną na telefonie. Minimum jest większe
   niż przy `.karty` (210 px), bo w kaflu stoi ZDANIE, nie liczba: przy 210 px
   „SES · zostało dziś 1850 z 2000 · okno otwarte” łamało się na cztery wiersze.
   ════════════════════════════════════════════════════════════════════════════ */
.kafle-ustawien {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
	gap: 14px;
}

.kafel {
	display: flex;
	flex-direction: column;
	gap: 6px;
	min-height: 128px;
	padding: 14px 16px 16px;
	background: var(--panel);
	border: 1px solid var(--obramowanie);
	border-radius: var(--r);
	box-shadow: var(--cien);
	text-decoration: none;
	color: inherit;
	transition: border-color .12s, box-shadow .12s;
}
.kafel:hover,
.kafel:focus-visible {
	border-color: var(--zielen);
	box-shadow: 0 2px 10px rgb(0 0 0 / .10);
}

.kafel-glowka {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 10px;
}

.ikona-kafla {
	width: 22px;
	height: 22px;
	flex-shrink: 0;
	color: var(--zielen);
}

/* Nazwa w kolorze odnośnika, bo nazwa JEST odnośnikiem — cały kafel prowadzi
   na ekran o tej nazwie. Zrzut od klienta miał w tym miejscu przycisk
   „Konfiguruj"; osobny przycisk w kaflu, który cały jest klikalny, daje dwa
   celowniki na jedno przejście — a przy dwóch kaflach z ośmiu („Zgody
   i wykluczenia", „Gotowość systemu") nie ma tam czego konfigurować i napis
   obiecywałby formularz, którego nie ma.

   Strzałka po nazwie mówi „to gdzieś prowadzi" bez obiecywania czego.
   `::after`, nie znak w szablonie: to jest wygląd odnośnika, nie treść —
   czytnik ekranu przeczyta samą nazwę ekranu. */
.kafel-nazwa {
	font-size: var(--tekst-bazowy);
	font-weight: 600;
	color: var(--zielen);
	margin-top: 2px;
}
.kafel-nazwa::after {
	content: " →";
	color: var(--tekst-3);
	font-weight: 400;
	transition: color .12s;
}
.kafel:hover .kafel-nazwa::after,
.kafel:focus-visible .kafel-nazwa::after { color: var(--zielen); }

/* Zdanie stanu — ten sam stopień i odcień co `.pod`, bo pełni tę samą rolę.
   `margin-top: auto` dociska je do dna kafla, żeby przy różnej długości nazw
   zdania w rzędzie stały w jednej linii. */
.kafel-stan {
	font-size: var(--tekst-drobny);
	color: var(--tekst-3);
	margin-top: auto;
	overflow-wrap: anywhere;
}
/* Temat z listy „Do zrobienia” — sama plakietka, bez zdania, więc i bez
   wysokości na zdanie: na telefonie lista i kafle nie mówią tego dwa razy
   (2026-10-07, [[08_DECYZJE]] D811). */
.kafel.kafel-na-liscie { min-height: 0; }
/* Linia „Wysyłka: gotowa / nie wyjdzie / pierwszy krok” nad listą (D811). */
.linia-wysylki { margin: 0 0 14px; }

/* STAN NIESIONY OBWÓDKĄ — obok plakietki, która mówi to samo słowem.
   Ta sama konstrukcja co `.karta.pilna` na pulpicie: kolor przyciąga wzrok
   do kafla, a przeczytać stan da się bez niego. */
.kafel-blad { border-color: var(--zly); }
.kafel-blad .ikona-kafla { color: var(--zly); }
.kafel-czeka { border-color: var(--uwaga); }
.kafel-czeka .ikona-kafla { color: var(--uwaga); }

/* Kafel w stanie „uwaga” zachowuje czerwoną obwódkę także pod kursorem:
   bez tego najechanie na najpilniejszy kafel gasiło jedyny znak, po którym
   da się go znaleźć wzrokiem w siatce ośmiu. */
.kafel-blad:hover,
.kafel-blad:focus-visible { border-color: var(--zly); }

/* Karty ekranu Gotowości (D393) zniknęły razem z ekranem 2026-09-24 (D448):
   lista stoi na Przeglądzie Ustawień, w karcie „Do zrobienia przez Ciebie”. */

/* --- edytor wiadomości: źródło po lewej, gotowy mail po prawej -------------
   (2026-09-15, [[08_DECYZJE]] D176)

   Do tego dnia przy polu treści stała ramka pokazująca SAM UKŁAD treści —
   bez oprawy, bez stopki i bez podstawionych znaczników — a prawdziwa
   wiadomość była pod przyciskiem „Podgląd", czyli na osobnym ekranie.
   Pisało się w jednym miejscu, a skutek oglądało w drugim.

   Układ kolumn bierzemy z `.podglad-kolumny` (równe kolumny, `auto-fit`
   od 380 px) — te same proporcje co na ekranie pełnego podglądu, bo pytanie
   jest to samo. Tutaj są tylko rzeczy, których tamten ekran nie ma.       */

/* Nagłówek: nazwa, język i typ w jednym wierszu. Trzy rzeczy odpowiadające
   na pytanie „co ja właściwie otworzyłem" — do 2026-09-15 rodzaj i źródło
   siedziały w liście definicyjnej POD polem kodu i pod ramką podglądu. */
.naglowek-szablonu { margin-bottom: 14px; }
/* Tylko na szerokim ekranie (D718): na telefonie rząd jest kolumną, a pola
   mają zająć całą szerokość — z `flex-start` „Nazwa oprawy” miała 196 px. */
@media (min-width: 801px) {
	.naglowek-szablonu .wiersz-pol { align-items: flex-start; }
}
.naglowek-szablonu .pole { min-width: 190px; }
/* Nazwa dostaje całą wolną szerokość: jest jedynym polem, którego treść
   bywa długa, a dwa pozostałe mają stałą liczbę znaków. */
.pole.rosnace { flex: 1 1 260px; }

/* Pole, którego NIE MA jak zmienić w miejscu — język wersji i typ oprawy.
   Wygląda jak wartość, nie jak zablokowana kontrolka: wyszarzony `select`
   sugeruje, że zaraz się odblokuje, a te dwie rzeczy zmienia się inaczej
   (wersję się kasuje i robi na nowo, typ decyduje o wymaganych znacznikach). */
.pole-stale {
	display: flex;
	flex-direction: column;
	gap: 4px;
	padding: 7px 0;
}

/* Zakładki źródła: „Kod HTML" i „Tekst widoczny". Bez JavaScriptu pasek
   zostaje widoczny, a oba panele stoją jeden pod drugim — czyli ekran jest
   kompletny, tylko mniej zwarty. */
.zakladki-zrodla {
	display: flex;
	gap: 6px;
	flex-wrap: wrap;
	margin-bottom: 10px;
}

/* Pole z kodem HTML: stały krój i drobny stopień, bo to jest kod, a nie
   tekst do czytania. Wysokość taka, żeby kończyło się mniej więcej tam,
   gdzie ramka podglądu obok. */
.pole-kodu {
	width: 100%;
	min-height: 420px;
	font-family: var(--mono, ui-monospace, Consolas, monospace);
	font-size: 12px;
	line-height: 1.45;
}

/* Lista fragmentów tekstu widocznego — dokładnie to, co pójdzie do
   tłumaczenia. Numerowana, bo po numerach chodzi też odpowiedź modelu
   (`asystent.akcje.przetlumacz_fragmenty`). Od D398 każdy fragment jest
   polem do poprawki, a przy tytule i linkach stoi, czym jest. */
.lista-fragmentow {
	margin: 0 0 8px;
	padding-left: 26px;
	font-size: var(--tekst-podpis);
	line-height: 1.6;
}
.lista-fragmentow li { margin-bottom: 6px; overflow-wrap: anywhere; }
.fragment-oprawy input { width: 100%; }
.fragment-oprawy input[readonly] { color: var(--tekst-2); background: transparent; }
.fragment-miejsce { display: block; margin-bottom: 1px; }

/* Chipy znaczników — wstawiają `{{imie}}` w miejsce kursora. Do 2026-09-15
   znaczniki stały pod polem jako tekst do przepisania z ręki, a literówka
   `{{imei}}` przechodzi przez podstawianie dosłownie i ląduje w skrzynce
   klienta. Bez JavaScriptu zostają wypisem — czyli tym, co było. */
.chipy-znacznikow {
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
	align-items: center;
	margin: 8px 0;
}
.chip-znacznika {
	font-family: var(--mono, ui-monospace, Consolas, monospace);
	font-size: var(--tekst-drobny);
	padding: 3px 9px;
	border-radius: 999px;
	border: 1px solid var(--obramowanie);
	background: var(--panel-2);
	color: var(--tekst-2);
	cursor: pointer;
}
.chip-znacznika:hover,
.chip-znacznika:focus-visible {
	border-color: var(--zielen);
	color: var(--zielen);
}

/* --- pasek języków oprawy (2026-09-15, [[08_DECYZJE]] D173) ---------------

   Jedno miejsce, w którym widać „ta oprawa istnieje w tylu językach,
   w tych brakuje". Kafelki, nie lista rozwijana: rynków jest osiem, a pytanie
   brzmi „czego brakuje", nie „co wybrać" — na to trzeba widzieć wszystko
   naraz. Ta sama logika, co przy siatce kafli Ustawień.                   */
.pasek-jezykow {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	margin: 10px 0;
}

.jezyk-kafel {
	display: flex;
	flex-direction: column;
	gap: 2px;
	min-width: 132px;
	padding: 8px 12px;
	border: 1px solid var(--obramowanie);
	border-radius: var(--r);
	background: var(--panel-2);
	color: var(--tekst);
	text-decoration: none;
	text-align: left;
	font: inherit;
	cursor: pointer;
}
.jezyk-kafel:hover,
.jezyk-kafel:focus-visible { border-color: var(--zielen); }

/* Język, który wersję MA — pełny kafel. Ten, którego nie ma, jest przerywany:
   różnicę widać z odległości i bez czytania, a to jest jedyne pytanie, które
   ten pasek ma na ekranie rozstrzygać. */
.jezyk-kafel.brak {
	border-style: dashed;
	color: var(--tekst-2);
}

/* Gdzie się teraz stoi. Bez tego pasek mówi, dokąd można pójść, a nie mówi,
   co jest otwarte — a ekran wersji niemieckiej wygląda tak samo jak ekran
   oprawy podstawowej. */
.jezyk-kafel.biezacy {
	border-color: var(--zielen);
	box-shadow: inset 0 0 0 1px var(--zielen);
}

/* Karta z gotową wiadomością — przy kampanii i przy kroku sekwencji.
   Schowana w HTML-u i odsłaniana przez `edytor-maila.js`: bez JavaScriptu
   nie ma czym jej wypełnić, a pusta ramka udaje działającą. Na ekranie
   oprawy ramkę składa serwer przy wejściu, więc tam karta jest widoczna
   od razu i tej klasy nie potrzebuje. */
.karta-podgladu-maila .ramka-podgladu { height: 520px; }

/* Ramka podglądu, która nie doszła do serwera. Nie chowamy jej: widać na niej
   POPRZEDNI wynik i to jest lepsze niż puste miejsce — ale człowiek ma
   wiedzieć, że patrzy na coś sprzed ostatniej poprawki. */
.podglad-nieaktualny iframe { opacity: .55; }

/* --- nowy segment i edycja segmentu (2026-09-18, [[08_DECYZJE]] D304) ------ */

/* Warunki po lewej, podgląd „kto wpada” po prawej i PRZYKLEJONY: przy
   zaznaczaniu rynków na dole formularza liczba ma zostać w polu widzenia,
   bo to ona odpowiada na pytanie, po które się tu przychodzi. Pod 1040 px
   jedna kolumna, podgląd pod przyciskami — ta sama granica co `.kartoteka`. */
.segment-uklad {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(280px, 340px);
	grid-template-areas: "pola boczny" "przyciski boczny";
	grid-template-rows: auto 1fr;
	gap: 16px;
	align-items: start;
}
.segment-pola { grid-area: pola; display: flex; flex-direction: column; gap: 16px; min-width: 0; }
.segment-boczny { grid-area: boczny; position: sticky; top: 16px; min-width: 0; }
.segment-uklad > .segment-przyciski { grid-area: przyciski; }
@media (max-width: 1040px) {
	.segment-uklad {
		grid-template-columns: minmax(0, 1fr);
		grid-template-areas: "pola" "boczny" "przyciski";
		grid-template-rows: none;
	}
	.segment-boczny { position: static; }
}

.segment-zasada { margin: 0 0 14px; }
.segment-warunki {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
	gap: 14px;
	margin-bottom: 14px;
}
.segment-warunki .pole { margin-bottom: 0; }
/* Na osobnym ekranie jest miejsce: lista rynków nie musi się przewijać
   w pudełku wysokim na cztery pozycje, jak w filtrze nad listą firm. */
.segment-warunki .filtr-wybory { max-height: 200px; }
.segment-przelaczniki label {
	display: flex;
	align-items: center;
	gap: 6px;
	font-weight: 400;
	cursor: pointer;
}
.segment-przelaczniki input[type="checkbox"] { width: auto; margin: 0; flex: none; }

.segment-przyciski { display: flex; flex-wrap: wrap; gap: 8px; }
/* `.przycisk` ma własne `display`, które przykrywa atrybut `hidden` — a ten
   przycisk chowa `segment-podglad.js`, gdy ramka przelicza się sama. */
.segment-przyciski [hidden] { display: none; }

.segment-liczby {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 12px;
	margin: 4px 0 10px;
}
.segment-liczby .liczba {
	font-size: 28px;
	font-weight: 600;
	line-height: 1.1;
	font-variant-numeric: tabular-nums;
}
.segment-wyjasnienie-liczb { margin: 0 0 12px; }
.segment-zero {
	margin: 0 0 12px;
	padding-left: 10px;
	border-left: 3px solid var(--obramowanie);
	font-size: var(--tekst-podpis);
	color: var(--tekst-2);
}
.segment-podglad .komunikat { margin: 0 0 12px; padding: 10px 12px; font-size: var(--tekst-podpis); }
.segment-probka { list-style: none; margin: 0; padding: 0; font-size: var(--tekst-wiersz); }
.segment-probka li {
	display: flex;
	justify-content: space-between;
	gap: 8px;
	padding: 4px 0;
	border-bottom: 1px solid var(--obramowanie-2);
}
.segment-probka li a { overflow-wrap: anywhere; }
.segment-probka .pod { white-space: nowrap; }
.segment-cala-lista { display: inline-block; font-size: var(--tekst-podpis); }
.segment-opis { margin: 0; font-size: var(--tekst-podpis); color: var(--tekst-2); overflow-wrap: anywhere; }
/* W trakcie przeliczania — stare liczby przygaszone, nie znikające:
   skakanie ramki przy każdym kliknięciu w rynek męczy bardziej niż czekanie. */
.segment-liczy .segment-liczby { opacity: .5; transition: opacity .15s; }

/* Wiersz segmentu na ekranie Segmentów: „Edytuj” i „Usuń” obok siebie. */
.akcje-segmentu { display: flex; gap: 6px; justify-content: flex-end; align-items: center; }
.akcje-segmentu form { margin: 0; }

/* --- odbiorcy sekwencji pojedynczo (2026-09-19, [[08_DECYZJE]] D305) ------- */

/* Rozwijka, bo domyślnie sekwencja idzie do CAŁEGO segmentu i tak ma zostać:
   lista kilkuset adresów otwarta na stałe zasłaniałaby kroki. Otwiera się
   sama, gdy ktoś już kogoś odznaczył — wtedy wybór ma być widać. */
.wybor-odbiorcow summary {
	cursor: pointer;
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 8px;
	padding: 4px 0;
}
.wybor-pasek {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px;
	margin: 10px 0;
}
.wybor-pasek input[type="search"] { flex: 1 1 220px; width: auto; min-width: 0; }
.wybor-pasek label {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	margin: 0;
	font-weight: 400;
	cursor: pointer;
}
.wybor-pasek input[type="checkbox"] { width: auto; margin: 0; }

/* Lista przewija się w swoim pudełku — formularz sekwencji ma pod nią
   jeszcze kroki, a segment bywa na kilkaset firm. */
.lista-odbiorcow {
	list-style: none;
	margin: 0 0 10px;
	padding: 0;
	max-height: 440px;
	overflow-y: auto;
	border: 1px solid var(--obramowanie);
	border-radius: 6px;
	background: var(--panel);
}
.odbiorca-firma { padding: 6px 10px; border-bottom: 1px solid var(--obramowanie-2); }
.odbiorca-firma:last-child { border-bottom: 0; }
.odbiorca-firma ul { list-style: none; margin: 2px 0 0; padding: 0 0 0 26px; }
.lista-odbiorcow label {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 4px 8px;
	margin: 0;
	padding: 2px 0;
	font-size: var(--tekst-wiersz);
	font-weight: 400;
	cursor: pointer;
	overflow-wrap: anywhere;
}
.lista-odbiorcow input[type="checkbox"] { width: auto; margin: 0; flex: none; }
.lista-odbiorcow .odbiorca-wylaczony { color: var(--tekst-3); cursor: default; }
/* Wyszukiwarka chowa wiersze atrybutem `hidden`, a `label` i `li` mają tu
   własne `display` — bez tej reguły schowane zostawałyby na ekranie. */
.wybor-odbiorcow [hidden] { display: none; }

/* ── IMPORT Z WKLEJONEJ TREŚCI ([[08_DECYZJE]] D358) ─────────────────────
   Ekran przeglądu ma trzy kolumny: zaznaczenie, DANE i fragment źródłowy.
   Środkowa niesie kilkanaście pól tekstowych na wiersz — siatka, a nie
   jedno pod drugim, bo przy dziesięciu kontaktach lista pionowa robi się
   ekranem na trzy przewinięcia i nie da się porównać wiersza z wierszem. */
.wklejka-pola {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
	gap: 4px 10px;
	margin: 0 0 4px;
}
.wklejka-pole { display: block; margin: 0; font-weight: 400; }
.wklejka-pole span { display: block; }
.wklejka-pole input { width: 100%; margin: 0; }
/* Uwaga przy wierszu, który nie przejdzie — ten sam kolor co komunikat zły,
   bo znaczy to samo. Sam `.pod` jest szary i ginie wśród etykiet pól. */
.pod.zly { color: var(--zly); }
/* Wklejony tekst do wglądu: zawijamy, bo to cudza treść dowolnej szerokości,
   i ograniczamy wysokość — nie po to się go otwiera, żeby przewijać ekran. */
.wklejka-zrodlo {
	white-space: pre-wrap;
	overflow-wrap: anywhere;
	max-height: 320px;
	overflow-y: auto;
	margin: 0;
}

/* --- doczytywanie listy firm (2026-09-20, [[08_DECYZJE]] D371) ---------- */

/* Stopka listy firm: licznik „Widać 50 ze 175 firm" i „Pokaż kolejne 50".
   Zastąpiła pasek stron NA TEJ JEDNEJ liście — jedynej, która ma i pola
   wyboru, i akcje hurtem, więc jedynej, na której przeładowanie ekranu
   kosztowało zaznaczenie.

   Licznik PIERWSZY, przycisk drugi: po doczytaniu przycisk wędruje w dół
   razem z tabelą, a liczba jest tym, po co się tu patrzy — „ile jeszcze
   zostało". Kolumna, nie rząd, bo przy 175 firmach oba zdania obok siebie
   rozjeżdżają się na wąskim ekranie. */
.doczytywanie {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 10px;
	margin-top: 16px;
	font-size: var(--tekst-wiersz);
	color: var(--tekst-2);
}

/* Odnośnik z `aria-busy` to doczytywanie w toku — ta sama konwencja co
   przyciski z `data-trwa` w `formularze.js`: widać, że coś się dzieje,
   i drugie kliknięcie nic nie robi. */
.doczytywanie [aria-busy="true"] {
	opacity: .6;
	pointer-events: none;
}

/* ── DWA POWROTY OBOK SIEBIE ([[08_DECYZJE]] D360) ───────────────────────
   Ekran w pozycji rysowanej kaflami dostaje drogę w górę („← Ustawienia"),
   a niektóre mają jeszcze własny powrót do rzeczy, o której mówią
   („← tablica lejka"). `.powrot` jest `inline-block`, więc siadają w jednym
   rzędzie i bez tej kropki zlewałyby się w jeden odnośnik. */
.powrot + .powrot::before {
	content: "·";
	margin: 0 8px;
	color: var(--tekst-3);
}
/* Okruszek tematu (`Ustawienia · Wysyłka`) nie zaczyna się od strzałki:
   strzałka znaczy „wyżej", a temat jest po drodze, nie nad nią. */
.powrot.okruszek { color: var(--tekst-2); }

/* --- kreator wysyłki (2026-09-20, [[08_DECYZJE]] D374) ------------------ */

/* Kafel „co z tego wyjdzie": odpowiedź SYSTEMU na trzy pytania wyżej.
   Wyróżniony tłem, bo jest jedyną rzeczą na tym ekranie, której człowiek nie
   wpisuje — a po zmianie odpowiedzi ma rzucić się w oczy, że się przeliczył.
   Obramowanie po lewej zamiast pełnej ramki: ramek na ekranach panelu pilnuje
   sufit w `panel/testy_wyjasnien`, a to nie jest rzecz do zrobienia TERAZ,
   tylko odpowiedź. */
.kreator-wynik {
	border-left: 3px solid var(--zielen);
	background: var(--zielen-mgla);
	padding: 14px 16px;
	margin: 18px 0;
	border-radius: 0 4px 4px 0;
}

/* Liczby nad werdyktem — „500 osób · zgodę potwierdziło 12". Rząd, bo to
   jedno zdanie rozbite na dwie liczby, a nie lista. */
.kreator-liczby {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px;
	font-size: var(--tekst-wiersz);
	color: var(--tekst-2);
	margin-bottom: 10px;
}

/* Sam werdykt: „Założę SEKWENCJĘ (3 kroki). Bo…". Pełny rozmiar tekstu —
   to jest zdanie, po którym człowiek klika „Dalej". */
.kreator-werdykt { line-height: 1.55; }

/* Ostrzeżenie w środku kafla nie potrzebuje własnego marginesu z góry:
   werdykt nad nim już go odsunął. */
.kreator-wynik .komunikat { margin: 10px 0 0; }
.kreator-wynik .pod { margin-top: 8px; }


/* --- „Nowa wysyłka": trzy kroki na jednym ekranie (2026-09-23, [[08_DECYZJE]] D385)

   Zgłoszenie właściciela: „żeby nie było takiego chaosu; ukryj instrukcje pod
   znakami zapytania; intuicyjny, profesjonalny, prosty". Ekran był jedną
   kolumną kart z etykietami wersalikami i jedenastoma zdaniami drobnego
   druku nad pierwszym polem treści.

   Zasady tego bloku:
   * sekcja = karta z NUMEREM i nagłówkiem zwykłym krojem — wersaliki
     `.karta .etykieta` są dobre dla kafla z liczbą, a nie dla kroku
     formularza, który się czyta od góry;
   * szerokość ograniczona: pole „Nazwa" na 1500 px to linijka, której
     koniec trzeba szukać wzrokiem;
   * pole ma oddech (`margin-bottom`), bo bez niego etykieta kolejnego pola
     przyklejała się do poprzedniego i zlewały się w jeden blok;
   * przycisk zapisu przyklejony do dołu okna.

   Tokeny wyłącznie z `:root` — kolory i skala tekstu (sprawdz-tokeny.py). */

/* 1240 px od D600 (2026-09-27): wiersz wiadomości ma dwie kolumny — pisanie
   i gotowy mail obok. Pola „Nazwa i odbiorcy” trzyma w 820 px reguła niżej. */
.formularz-wysylki { max-width: 1040px; }
form[data-wysylka].formularz-wysylki { max-width: 1240px; }
/* Karta „Usuń wysyłkę” pod formularzem ustawień — tej samej szerokości co on (D794). */
.formularz-wysylki + .karta { max-width: 1040px; }

.sekcja-wysylki {
	padding: 20px 22px 22px;
	margin-bottom: 16px;
}
.sekcja-wysylki .pole { margin-bottom: 16px; }
.sekcja-wysylki .pole:last-child { margin-bottom: 0; }

.sekcja-tytul {
	display: flex;
	align-items: center;
	gap: 10px;
	margin: 0 0 16px;
	font-size: var(--tekst-bazowy);
	font-weight: 600;
	color: var(--tekst);
}
.sekcja-tytul .wyjasnienie { margin-left: 0; }

.sekcja-numer {
	flex: none;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 26px;
	height: 26px;
	border-radius: 50%;
	background: var(--zielen-mgla);
	color: var(--zielen);
	font-size: var(--tekst-podpis);
	font-weight: 600;
	font-variant-numeric: tabular-nums;
}

/* Nagłówek sekcji z narzędziem po prawej (format treści w sekcji „Treść").
   Na wąskim ekranie narzędzie schodzi pod nagłówek, zamiast go ściskać. */
.sekcja-glowka {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 10px 16px;
	margin-bottom: 14px;
}
.sekcja-glowka .sekcja-tytul { margin: 0; }

/* Pole opcjonalne zwinięte do jednego odnośnika („+ Dodaj opis"). */
.pole-opcjonalne { margin-top: 6px; }
.pole-opcjonalne > summary {
	display: inline-block;
	cursor: pointer;
	color: var(--zielen);
	font-size: var(--tekst-podpis);
	list-style: none;
}
.pole-opcjonalne > summary::-webkit-details-marker { display: none; }
.pole-opcjonalne[open] > summary { color: var(--tekst-2); margin-bottom: 6px; }

/* Etykieta z akcją po prawej („Segment odbiorców … + Nowy segment"). */
.etykieta-z-akcja {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 8px;
	margin-bottom: 5px;
}
.etykieta-z-akcja label { margin-bottom: 0; }
.etykieta-z-akcja a { font-size: var(--tekst-podpis); white-space: nowrap; }

/* Przełącznik z opisem jako kafelek — tak jak wybór formatu w innych
   miejscach: wybór prawny ma być widać, a nie przeoczyć jako ptaszek
   w wierszu tekstu. Dymek stoi obok kafla, nie w nim (patrz szablon). */
.opcja-wiersz {
	position: relative;
}
/* Dymek wygląda na część kafla, ale stoi obok `<label>` — przycisk „?”
   wewnątrz etykiety przełączałby pole przy każdym dotknięciu. */
.opcja-wiersz > .wyjasnienie {
	position: absolute;
	top: 13px;
	right: 14px;
	margin: 0;
}
.opcja-zaznaczana {
	flex: 1 1 auto;
	display: flex;
	align-items: flex-start;
	gap: 10px;
	margin: 0;
	padding: 11px 44px 11px 14px;
	border: 1px solid var(--obramowanie);
	border-radius: var(--r);
	background: var(--panel);
	font-weight: 400;
	cursor: pointer;
}
.opcja-zaznaczana input { width: auto; margin: 3px 0 0; flex: none; }
.opcja-zaznaczana:has(input:checked) {
	border-color: var(--zielen);
	box-shadow: inset 0 0 0 1px var(--zielen);
	background: var(--zielen-mgla);
}
.opcja-zaznaczana:has(input:focus-visible) {
	outline: 2px solid var(--zielen);
	outline-offset: 2px;
}
.opcja-tresc { display: flex; flex-direction: column; gap: 1px; }
.opcja-tresc strong { font-weight: 600; font-size: var(--tekst-wiersz); }

/* „Gdy ktoś odpisze” (D390): stała zasada, pod nią dwie reguły do wyboru. */
.reguly-odpowiedzi {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 12px;
}
.regula-stala {
	display: flex;
	align-items: baseline;
	gap: 10px;
	color: var(--tekst-2);
}
.regula-znak { color: var(--zielen); font-weight: 600; }
.regula-opcja { padding-right: 14px; }
.reguly-odpowiedzi .regula-etap { margin: 0; max-width: 420px; }

/* Format treści w jednej linii: dwa segmenty zamiast dwóch kafli. */
.format-zwiezly {
	display: flex;
	align-items: center;
	gap: 8px;
}
.format-zwiezly-etykieta { font-size: var(--tekst-podpis); color: var(--tekst-2); }

.przelacznik-segmentowy {
	display: inline-flex;
	padding: 2px;
	border: 1px solid var(--obramowanie);
	border-radius: 7px;
	background: var(--panel-2);
}
.przelacznik-segmentowy label {
	position: relative;
	display: inline-flex;
	margin: 0;
	font-weight: 500;
	cursor: pointer;
}
/* Pole zostaje w drzewie dostępności i przyjmuje fokus z klawiatury —
   schowane tak jak `.tylko-dla-czytnika`, nie `display: none`. */
.przelacznik-segmentowy input {
	position: absolute;
	width: 1px;
	height: 1px;
	opacity: 0;
	margin: 0;
}
.przelacznik-segmentowy span {
	padding: 5px 12px;
	border-radius: 5px;
	font-size: var(--tekst-podpis);
	color: var(--tekst-2);
}
.przelacznik-segmentowy input:checked + span {
	background: var(--panel);
	color: var(--zielen);
	box-shadow: 0 0 0 1px var(--obramowanie), 0 1px 2px rgba(20, 40, 35, .08);
}
.przelacznik-segmentowy input:focus-visible + span {
	outline: 2px solid var(--zielen);
	outline-offset: 1px;
}

/* Chipy znaczników w linii „Popraw z AI · Wstaw mój podpis” każdej
   wiadomości (2026-09-26, [[08_DECYZJE]] D535) — bez własnego marginesu,
   odstęp daje `gap` linii. Do tej rundy stały raz, nad pierwszą wiadomością. */
.wiadomosc-korekta .chipy-znacznikow { margin: 0; gap: 4px; }

/* Wiersz z błędem po odrzuceniu (2026-09-26, [[08_DECYZJE]] D532): ramka
   i pola w kolorze błędu, zdanie pod główką. Przewija do niego skrypt. */
.wiadomosc-wysylki.z-bledem { border-color: var(--zly); }
.blad-wiersza { margin: 8px 0 4px; font-weight: 500; }
.formularz-wysylki [aria-invalid="true"] { border-color: var(--zly); }

/* „na: Jan Müller, … · osoba 1 z 15” nad ramką podglądu (D530). */
/* Zwykły akapit, nie flex: przy flexie „na:” odrywało się na wąskim
   ekranie od nazwiska do osobnej linii. */
.podglad-na-kim { margin: 0 0 8px; }
.podglad-na-kim [data-nastepna-osoba] { margin-left: 6px; vertical-align: baseline; }
.podglad-na-kim[hidden],
.podglad-na-kim [hidden] { display: none; }

/* ── WIADOMOŚĆ ────────────────────────────────────────────────────────────
   Każda wiadomość to ramka z główką: plakietka z nazwą, termin (przy
   follow-upie) i akcje po prawej. Wersja językowa jest WCIĘTA pod swoją
   wiadomością — widać, że należy do niej, a nie jest kolejnym mailem. */
.wiadomosc-wysylki {
	border: 1px solid var(--obramowanie);
	border-radius: var(--r);
	padding: 12px 16px 16px;
	margin-bottom: 12px;
	background: var(--panel);
}
.wiadomosc-wysylki .pole { margin-bottom: 12px; }
.wiadomosc-wysylki .pole:last-child { margin-bottom: 0; }

.wiadomosc-wysylki.wersja-jezykowa {
	margin-left: 28px;
	background: var(--panel-2);
	border-style: dashed;
}

.wiadomosc-glowka {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px 12px;
	min-height: 32px;
	margin-bottom: 10px;
}
.wiadomosc-glowka .plakietka { font-size: var(--tekst-podpis); padding: 2px 10px; }

.wiadomosc-odstep {
	display: inline-flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 6px;
	font-size: var(--tekst-podpis);
	color: var(--tekst-2);
}
.wiadomosc-odstep label { margin: 0; font-weight: 400; color: var(--tekst-2); }
.wiadomosc-odstep input[type="number"] { width: 64px; padding: 4px 6px; text-align: center; }
.wiadomosc-odstep .wyjasnienie { margin-left: 0; }

.wiadomosc-akcje {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	margin-left: auto;
}

/* `hidden` musi wygrać z `display` powyżej — reguła autora przykrywa
   domyślne `[hidden] { display: none }` przeglądarki. Bez tego pierwsza
   wiadomość mówiła „wyjdzie po 0 dniach od poprzedniej”, a przyciski
   działające tylko ze skryptem stały na ekranie także bez niego. */
.wiadomosc-odstep[hidden],
.wiadomosc-akcje[hidden],
.przycisk-dokladania[hidden] { display: none; }

/* „Popraw z AI” pod treścią (D399): przycisk, „Cofnij poprawkę” i jedno
   zdanie o wyniku w jednej linii, zawijane na wąskim ekranie. */
.wiadomosc-korekta {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px;
	margin-top: 8px;
}
.wiadomosc-korekta[hidden],
.wiadomosc-korekta [hidden] { display: none; }
.wiadomosc-korekta [data-stan-poprawki].uwaga { color: var(--uwaga); }
/* Asystent niegotowy (D537): „Popraw z AI” i „Przetłumacz” nieaktywne
   z góry — muszą też tak wyglądać, inaczej to zwykły przycisk, który nie
   reaguje. Powód w `title`. */
[data-asystent-niegotowy][disabled] { opacity: .55; }

/* Usuń — cichy znak, nie przycisk w kolorze błędu: to nie jest operacja
   niszcząca dane w bazie, tylko zdjęcie bloku z formularza. Czerwień
   dopiero pod kursorem, żeby było wiadomo, co się stanie. */
.przycisk-usun {
	width: 28px;
	height: 28px;
	padding: 0;
	border: 1px solid transparent;
	border-radius: 6px;
	background: none;
	color: var(--tekst-3);
	font: 400 20px/1 var(--sans);
	cursor: pointer;
}
.przycisk-usun:hover,
.przycisk-usun:focus-visible {
	color: var(--zly);
	background: var(--zly-tlo);
	border-color: var(--zly-tlo);
}

/* Menu „+ Wersja językowa" — lista języków pod przyciskiem. */
.menu-jezykow { position: relative; }
.menu-jezykow > summary { list-style: none; }
.menu-jezykow > summary::-webkit-details-marker { display: none; }
.menu-jezykow-lista {
	position: absolute;
	right: 0;
	top: calc(100% + 4px);
	z-index: 25;
	width: 240px;
	padding: 6px;
	border: 1px solid var(--obramowanie);
	border-radius: var(--r);
	background: var(--panel);
	box-shadow: 0 6px 20px rgba(20, 40, 35, .12);
}
.menu-jezykow-lista button {
	display: block;
	width: 100%;
	padding: 6px 10px;
	border: 0;
	border-radius: 5px;
	background: none;
	color: var(--tekst);
	font: inherit;
	font-size: var(--tekst-wiersz);
	text-align: left;
	cursor: pointer;
}
.menu-jezykow-lista button:hover,
.menu-jezykow-lista button:focus-visible { background: var(--zielen-mgla); color: var(--zielen); }
.menu-jezykow-lista button:disabled { color: var(--tekst-3); background: none; cursor: default; }
/* „polski” schowany przy podstawowej po polsku (2026-09-28, D692) — `display`
   z reguły wyżej przykrywał atrybut `hidden`. */
.menu-jezykow-lista button[hidden] { display: none; }
.menu-jezykow-lista .pod { margin: 6px 10px 2px; }

/* „+ Dodaj follow-up" — pełna szerokość, obrys przerywany: miejsce, w którym
   pojawi się następna wiadomość, a nie kolejny przycisk w rzędzie. */
.przycisk-dokladania {
	display: block;
	width: 100%;
	padding: 10px;
	border: 1px dashed var(--obramowanie);
	border-radius: var(--r);
	background: none;
	color: var(--zielen);
	font: inherit;
	font-weight: 500;
	cursor: pointer;
}
.przycisk-dokladania:hover,
.przycisk-dokladania:focus-visible { border-color: var(--zielen); background: var(--zielen-mgla); }

/* Podgląd przy polu w wersji zwięzłej: przyciski wariantu w jednej linii
   z nagłówkiem, bez akapitu zastrzeżeń pod spodem (jest w dymku). */
.podglad-zwiezly { padding: 10px 12px; }
.podglad-zwiezly .etykieta { margin-bottom: 0; }
.podglad-zwiezly .podglad-warianty { margin: 6px 0 8px; }

/* Oprawa: lista i odnośnik w jednym rzędzie. */
.oprawa-wiersz {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px 14px;
}
.oprawa-wiersz select { flex: 1 1 280px; width: auto; min-width: 0; }
.oprawa-wiersz a { font-size: var(--tekst-podpis); white-space: nowrap; }

/* ── PRZYCISK ZAPISU PRZYKLEJONY DO DOŁU OKNA ─────────────────────────────
   Przy trzech follow-upach z podglądami „Utwórz wysyłkę" był dwa ekrany
   pod miejscem, w którym kończy się pisać. `sticky`, nie `fixed`: pasek
   zostaje w przepływie strony i nie zasłania niczego pod formularzem.
   `.tresc` ma `overflow-x: clip`, nie `hidden` — z `hidden` sticky by
   nie działał (komentarz przy `.tresc`). */
.pasek-zapisu {
	position: sticky;
	bottom: 0;
	z-index: 20;
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px 12px;
	margin: 0 -4px;
	padding: 12px 4px;
	background: var(--tlo);
	border-top: 1px solid var(--obramowanie);
}
/* Pole, do którego przechodzi się Tabem, nie może stanąć POD paskiem.
   Zmierzone 2026-09-26 na „Nowej wysyłce” przy 1280×900: Tab z „Tematu”
   dawał fokus „Treści”, ale przeglądarka nie przewijała, bo pole zaczynało
   się 5 px pod górną krawędzią paska — pierwsze zdania pisało się na
   ślepo. `scroll-padding` mówi przeglądarce, ile miejsca zasłania pasek. */
html:has(.pasek-zapisu) { scroll-padding-bottom: 88px; }
/* Podsumowanie w pasku (D533): pełne na szerokim ekranie, krótkie na
   telefonie (reguła w `@media (max-width: 800px)` niżej). Własna klasa,
   nie `.pod`: tamto pasek na telefonie chowa w całości. Krój i kolor jak
   `.pod`, tylko o stopień ciemniejszy — to są liczby, nie przypis. */
.podsumowanie-wysylki { font-size: var(--tekst-drobny); color: var(--tekst-2); }
.podsumowanie-krotkie { display: none; }
/* Brak informacji RODO przy kontaktach z importu (2026-10-01, [[08_DECYZJE]]
   D702) — własna linijka pod przyciskiem, także na telefonie: to jedyne
   zdanie w pasku, które mówi o obowiązku prawnym, nie o liczbach. */
.pasek-ostrzezenie {
	flex-basis: 100%;
	font-size: var(--tekst-drobny);
	color: var(--zly);
}

/* Porównanie dróg pod formularzem — zwinięte, ciche. */
.jak-to-dziala { margin-top: 20px; max-width: 1040px; }
.jak-to-dziala > summary {
	cursor: pointer;
	color: var(--tekst-2);
	font-size: var(--tekst-podpis);
	padding: 6px 0;
}
.jak-to-dziala > summary:hover { color: var(--zielen); }
.jak-to-dziala-tytul {
	margin: 16px 0 4px;
	font-size: var(--tekst-podpis);
	font-weight: 600;
	color: var(--tekst-2);
}

@media (max-width: 800px) {
	.sekcja-wysylki { padding: 16px 14px 18px; }
	.wiadomosc-wysylki { padding: 10px 12px 14px; }
	.wiadomosc-wysylki.wersja-jezykowa { margin-left: 12px; }
	.wiadomosc-akcje { margin-left: 0; }
	/* Lista języków na całą szerokość główki wiadomości (2026-09-26).
	   Zaczepiona o przycisk (`left: 0`) wychodziła przy 390 px o 52 px za
	   prawą krawędź ekranu — przycisk stoi za plakietką, a lista ma 240 px.
	   Zaczepiona o główkę mieści się zawsze, gdziekolwiek stoi przycisk. */
	.wiadomosc-glowka { position: relative; }
	.menu-jezykow { position: static; }
	.menu-jezykow-lista { left: 0; right: 0; width: auto; }
	/* Na telefonie pasek przy dolnej krawędzi ma być jak najniższy — zdanie
	   „nic jeszcze nie wyjdzie” zajmowało tam dwie linijki z ośmiuset.
	   Podsumowanie (D533) zostaje w krótkiej wersji: „15 osób · 3 wiad.
	   · od pon 28.09, 08:00” — liczby, po których ocenia się wysyłkę. */
	.pasek-zapisu .pod,
	.podsumowanie-pelne { display: none; }
	.podsumowanie-krotkie:not([hidden]) { display: inline; }
}


/* --- „Import bazy": kroki, przyciski, reszta pod „?" (2026-09-23, [[08_DECYZJE]] D386)

   Zgłoszenie właściciela ze zrzutem ekranu „Wgraj plik": „prostsza,
   intuicyjna, logiczna; schowaj chaos pod znakami zapytania, żeby nie było
   tak dużo na stronie — tylko przyciski". Ten sam wzorzec co „Nowa wysyłka"
   (D385): numerowane sekcje `.sekcja-wysylki`, przycisk w `.pasek-zapisu`,
   objaśnienia w dymkach albo w zwiniętym „jak to działa" pod formularzem.

   Tokeny wyłącznie z `:root` (sprawdz-tokeny.py). */

.formularz-importu { max-width: 1040px; }

/* Pole pliku jako duża strefa „wybierz albo przeciągnij". Bez skryptu pole
   `<input type=file>` zostaje widoczne w środku strefy — przeglądarka sama
   pokazuje wtedy nazwę wybranego pliku. Klasę `z-js` dokłada
   `import-pliku.js` i dopiero ona chowa surowe pole („Choose File / No file
   chosen" po angielsku w polskim panelu), bo od tej chwili nazwę pliku
   wypisuje skrypt. Schowane jak `.tylko-dla-czytnika`, nie `display: none`
   — `required` i klawiatura muszą dalej działać. */
.strefa-pliku {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 4px;
	min-height: 132px;
	margin: 0;
	padding: 20px 16px;
	border: 2px dashed var(--obramowanie);
	border-radius: var(--r);
	background: var(--panel-2);
	text-align: center;
	font-weight: 400;
	cursor: pointer;
	transition: border-color .15s, background .15s;
}
.strefa-pliku:hover,
.strefa-pliku.nad { border-color: var(--zielen); background: var(--zielen-mgla); }
.strefa-pliku:has(input:focus-visible) { outline: 2px solid var(--zielen); outline-offset: 2px; }
.strefa-pliku-napis {
	font-size: var(--tekst-bazowy);
	font-weight: 600;
	color: var(--zielen);
	overflow-wrap: anywhere;
}
.strefa-pliku.wybrany { border-style: solid; border-color: var(--zielen); background: var(--zielen-mgla); }
.strefa-pliku.wybrany .strefa-pliku-napis { color: var(--tekst); }
.strefa-pliku input[type="file"] { max-width: 100%; margin-top: 6px; }
.strefa-pliku.z-js input[type="file"] {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0 0 0 0);
	white-space: nowrap;
	border: 0;
}

/* Nagłówek sekcji, który jest zarazem etykietą pola („Tekst z kontaktami").
   Globalny `label` ma krój podpisu i `display: block` — tu ma wyglądać jak
   reszta nagłówka. */
.sekcja-tytul .etykieta-sekcji { display: inline; margin: 0; font: inherit; color: inherit; }

/* Jedno zdanie o stanie („plik czeka", „dane pokazowe") — bez ramki
   na pół ekranu. */
.zdanie-stanu { margin: 0 0 12px; font-size: var(--tekst-wiersz); }

/* Plik i ustawienia nad tabelą kolumn — jedna karta, jedna linia. */
.plik-importu {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 10px 20px;
	margin-bottom: 16px;
}
.plik-importu-opis { font-size: var(--tekst-wiersz); overflow-wrap: anywhere; }
.plik-importu-naglowek {
	display: flex;
	align-items: center;
	gap: 8px;
	font-size: var(--tekst-podpis);
	color: var(--tekst-2);
}
.plik-importu-naglowek label { margin: 0; font-weight: 400; }
.plik-importu-naglowek input { width: 72px; }

/* Dwie opcje wczytania obok siebie — kafle z `.opcja-zaznaczana` (D385). */
.opcje-importu {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
	gap: 10px;
}

/* Wynik: baner próby i przycisk „Zapisz naprawdę" w jednym wierszu. */
.baner-importu {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 10px 20px;
}
.baner-importu form { display: flex; flex-wrap: wrap; gap: 8px; margin: 0; }
.baner-importu .pod { margin-top: 2px; }
/* Rynek „inny” nad banerem próby, z wyborem rynku na miejscu (2026-10-02,
   [[08_DECYZJE]] D730). Etykieta, lista i przycisk w jednym rzędzie;
   na telefonie zawijają się pod siebie. */
.rynek-importu-formularz {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px 12px;
	margin: 10px 0 0;
}
.rynek-importu-formularz select { width: auto; min-width: 180px; }
/* „Nowa wysyłka do tej partii” między ramką zapisu a kaflami liczb — z
   odstępem od kafli; do 2026-10-02 przycisk stał przyklejony do ich górnej
   krawędzi (D740). */
.wysylka-partii {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 6px 12px;
	margin: 10px 0 18px;
}

/* Uwagi importera — lista zamiast dziewięciu ramek. Pierwsze zdanie widać,
   reszta po rozwinięciu (filtr `pierwsze_zdanie`, panel/templatetags/teksty). */
.uwagi-importu { margin-bottom: 16px; }
.uwagi-lista { list-style: none; margin: 0; padding: 0; }
.uwagi-lista > li {
	position: relative;
	padding: 9px 0 9px 16px;
	border-top: 1px solid var(--obramowanie-2);
	font-size: var(--tekst-wiersz);
}
.uwagi-lista > li:first-child { border-top: 0; padding-top: 0; }
.uwagi-lista > li::before {
	content: "";
	position: absolute;
	left: 0;
	top: 16px;
	width: 7px;
	height: 7px;
	border-radius: 50%;
	background: var(--uwaga);
}
.uwagi-lista > li:first-child::before { top: 7px; }
.uwagi-lista summary { cursor: pointer; list-style: none; }
.uwagi-lista summary::-webkit-details-marker { display: none; }
.uwagi-lista summary::after {
	content: " więcej ▾";
	white-space: nowrap;
	color: var(--zielen);
	font-size: var(--tekst-podpis);
}
.uwagi-lista details[open] summary::after { content: " mniej ▴"; }
.uwagi-lista details p { margin: 6px 0 0; color: var(--tekst-2); }

/* Długie tabele wyniku (odrzucone wiersze, kolumny) zwinięte do jednej
   linii z liczbą — rozwija je ten, kto chce je przejrzeć. */
.karta-zwijana { margin-bottom: 16px; }
.karta-zwijana > summary {
	cursor: pointer;
	font-weight: 600;
	font-size: var(--tekst-wiersz);
}
.karta-zwijana > summary .pod { font-weight: 400; }
.karta-zwijana[open] > summary { margin-bottom: 10px; }

/* „Ten plik nie nadawał się do wysyłki" — zdanie i przycisk w jednym
   wierszu, objaśnienie w dymku. */
.wycofanie-partii {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 10px 20px;
	margin-top: 16px;
}
.wycofanie-partii form { margin: 0; }

.formularz-importu + .jak-to-dziala .tabelka-kolumn { font-size: var(--tekst-podpis); }

@media (max-width: 800px) {
	.strefa-pliku { min-height: 104px; }
	.plik-importu-naglowek { flex-wrap: wrap; }
}

/* --- Oprawy: prosty edytor i galeria obrazów (2026-09-23, [[08_DECYZJE]] D387)

   Zgłoszenie właściciela z ekranu oprawy: „brak możliwości wpisania logo
   albo wrzucenia własnego zdjęcia". Galeria to kafelki z miniaturą; w prostym
   edytorze kafelek jest przełącznikiem „to jest moje logo" (radio schowane,
   zaznaczenie widać po ramce), w kodzie HTML — ma „Wstaw" i „Podmień logo". */

.etykieta-pola {
	display: block;
	font-size: var(--tekst-podpis);
	font-weight: 500;
	margin-bottom: 5px;
}

.pola-kreatora { border: 0; margin: 0; padding: 0; min-width: 0; }
.pola-kreatora[disabled] { opacity: .5; }
.pola-kreatora .pole { margin-bottom: 14px; }
.pola-kreatora input[type="color"] {
	width: 64px;
	height: 38px;
	padding: 3px;
	cursor: pointer;
}

.kreator-zablokowany {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px 12px;
	margin: 0 0 12px;
	font-size: var(--tekst-podpis);
	color: var(--tekst-2);
}
.kreator-zablokowany[hidden] { display: none; }
.kreator-zablokowany p { margin: 0; }

.pole-z-jednostka { display: flex; align-items: center; gap: 6px; }
.pole-z-jednostka input { width: 96px; }

.galeria-lista {
	list-style: none;
	margin: 0 0 10px;
	padding: 0;
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(118px, 1fr));
	gap: 10px;
}

.obraz-pozycja { position: relative; display: flex; flex-direction: column; gap: 4px; min-width: 0; }

.obraz-kafel {
	display: flex;
	align-items: center;
	justify-content: center;
	height: 76px;
	margin: 0;
	padding: 6px;
	border: 1px solid var(--obramowanie);
	border-radius: var(--r);
	/* Szachownica z tła: logo na przezroczystym tle ma być widać, że JEST
	   przezroczyste — na białym znikałoby razem z białymi fragmentami. */
	background:
		linear-gradient(45deg, var(--obramowanie-2) 25%, transparent 25%) 0 0 / 12px 12px,
		linear-gradient(-45deg, var(--obramowanie-2) 25%, transparent 25%) 0 6px / 12px 12px,
		var(--panel);
	font-weight: 400;
	cursor: pointer;
	overflow: hidden;
}
.obraz-kafel img { max-width: 100%; max-height: 100%; object-fit: contain; }
.obraz-kafel input[type="radio"] {
	position: absolute;
	opacity: 0;
	width: 1px;
	height: 1px;
}
.obraz-kafel.bez-obrazu { background: var(--panel-2); color: var(--tekst-3); font-size: var(--tekst-podpis); }
.obraz-kafel:has(input:checked) {
	border-color: var(--zielen);
	box-shadow: inset 0 0 0 2px var(--zielen);
}
.obraz-kafel:has(input:focus-visible) { outline: 2px solid var(--zielen); outline-offset: 2px; }
div.obraz-kafel { cursor: default; }

.obraz-opis { font-size: var(--tekst-plakietka); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.obraz-akcje { display: flex; flex-wrap: wrap; gap: 4px; }
/* W kodzie kafelek niesie dwa przyciski obok siebie — szersza kolumna. */
.galeria-obrazow[data-galeria="kod"] .galeria-lista { grid-template-columns: repeat(auto-fill, minmax(184px, 1fr)); }
.obraz-akcje[hidden] { display: none; }

.obraz-usun {
	position: absolute;
	top: 2px;
	right: 2px;
	width: 22px;
	height: 22px;
	font-size: 16px;
	background: var(--panel);
	border-color: var(--obramowanie);
}
.obraz-usun[hidden] { display: none; }

.galeria-wgrywanie { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; }
.wgraj-obraz { display: inline-flex; align-items: center; margin: 0; cursor: pointer; }
.wgraj-obraz input[type="file"] {
	position: absolute;
	width: 1px;
	height: 1px;
	opacity: 0;
}
.wgraj-obraz:has(input:focus-visible) { outline: 2px solid var(--zielen); outline-offset: 2px; }
[data-bez-skryptu][hidden] { display: none; }

/* ── RAMKA PODGLĄDU: MOTYW, EKRAN, PEŁNY EKRAN — [[08_DECYZJE]] D396 ────────

   Zgłoszenie właściciela (2026-09-24): podgląd jasny, ciemny i na pełnym
   ekranie „trzeba profesjonalnie poprawić”. Do tego dnia nad ramką stały
   cztery jednakowe przyciski w rzędzie — dwa podświetlone naraz, więc nie
   było widać, że to DWA wybory po dwie możliwości. Teraz każdy wybór jest
   osobnym przełącznikiem z podpisem, a wciśnięty wariant niesie
   `aria-pressed` (czytnik ekranu mówi „wciśnięty”, nie tylko kolor).

   Pełny ekran to warstwa na całe okno (`podglad-ramki.js`) z tą samą
   ramką w środku — nie kopią, więc podgląd na żywo odświeża się dalej. */

.pasek-podgladu {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px 14px;
	margin-bottom: 10px;
}

.przelacznik-segmentowy {
	display: inline-flex;
	align-items: center;
	gap: 2px;
	padding: 2px;
	background: var(--panel-2);
	border: 1px solid var(--obramowanie);
	border-radius: 6px;
}
.przelacznik-opis {
	padding: 0 6px 0 8px;
	font-size: var(--tekst-drobny);
	color: var(--tekst-3);
}
.przelacznik-segmentowy > a,
.przelacznik-segmentowy > button {
	padding: 4px 12px;
	font: inherit;
	font-size: var(--tekst-podpis);
	font-weight: 500;
	line-height: 1.5;
	color: var(--tekst-2);
	background: transparent;
	border: 0;
	border-radius: 4px;
	cursor: pointer;
	text-decoration: none;
}
.przelacznik-segmentowy > a:hover,
.przelacznik-segmentowy > button:hover {
	color: var(--tekst);
	background: var(--panel);
}
.przelacznik-segmentowy > [aria-pressed="true"],
.przelacznik-segmentowy > [aria-pressed="true"]:hover {
	color: var(--na-zieleni);
	background: var(--zielen);
}
.przelacznik-segmentowy > :focus-visible {
	outline: 2px solid var(--zielen);
	outline-offset: 1px;
}

/* „Pełny ekran” na prawym końcu paska — to inna czynność niż wybór
   wariantu i nie ma wyglądać na trzecią grupę przełączników. */
.przycisk-pelny { margin-left: auto; }
.tytul-pelnego { display: none; }
.uwaga-motywu { margin: 0 0 10px; }

/* Telefon: 390 px kanwy (iPhone 12–15, większość Androidów) w ramce
   urządzenia, na tle, które odcina ją od karty. */
.scena-podgladu:has(> .ramka-podgladu.waska) {
	padding: 18px 12px;
	background: var(--tlo);
	border-radius: var(--r);
}
.ramka-podgladu.waska,
.karta-podgladu-maila .ramka-podgladu.waska {
	display: block;
	width: 410px;
	max-width: 100%;
	height: 720px;
	margin: 0 auto;
	border: 10px solid #1f2328;
	border-radius: 28px;
	box-shadow: 0 8px 28px rgba(20, 40, 35, .18);
	resize: none;
}

/* Ciemny motyw: kanwa ramki ciemna, zanim wiadomość się wczyta — inaczej
   każde przełączenie błyska bielą. */
.podglad-ramki.ciemny .ramka-podgladu { background: #121417; }

/* Pełny ekran. */
html.bez-przewijania { overflow: hidden; }

.podglad-ramki.pelny-ekran {
	position: fixed;
	inset: 0;
	z-index: 1000;
	display: flex;
	flex-direction: column;
	margin: 0;
	padding: 12px 24px 20px;
	background: var(--tlo);
}
.podglad-ramki.pelny-ekran .pasek-podgladu {
	flex: none;
	margin-bottom: 12px;
	padding-bottom: 12px;
	border-bottom: 1px solid var(--obramowanie);
}
.podglad-ramki.pelny-ekran .tytul-pelnego {
	display: block;
	max-width: 42ch;
	overflow: hidden;
	font-size: var(--tekst-wiersz);
	font-weight: 600;
	white-space: nowrap;
	text-overflow: ellipsis;
}
.podglad-ramki.pelny-ekran .uwaga-motywu { flex: none; }
.podglad-ramki.pelny-ekran .scena-podgladu {
	display: flex;
	flex: 1;
	justify-content: center;
	min-height: 0;
}
.podglad-ramki.pelny-ekran .scena-podgladu:has(> .ramka-podgladu.waska) {
	align-items: center;
	padding: 12px;
}
.podglad-ramki.pelny-ekran .ramka-podgladu {
	width: 100%;
	height: 100%;
	resize: none;
}
.podglad-ramki.pelny-ekran .ramka-podgladu.waska {
	width: 410px;
	height: min(100%, 860px);
}

@media (max-width: 640px) {
	.przycisk-pelny { margin-left: 0; }
	.podglad-ramki.pelny-ekran { padding: 8px 8px 12px; }
	.podglad-ramki.pelny-ekran .tytul-pelnego { flex-basis: 100%; }
}

/* ── WYGLĄD WIADOMOŚCI I GOTOWY MAIL PRZY NIEJ (2026-09-24, D397) ─────────
   „Wygląd” stoi pod treścią każdej wiadomości, a pod nim ramka „Tak dostanie
   odbiorca”. Zdanie pod listą mówi, co wyniknie z wyboru — jedno z dwóch,
   pokazuje je `oprawa-wybor.js`. */
.wyglad-wiadomosci .wyglad-opis { margin: 6px 0 0; }
.wyglad-wersji { margin: 0 0 12px; }

.podglad-maila-zwiezly {
	border-top: 1px dashed var(--obramowanie);
	padding-top: 12px;
	margin-top: 4px;
}
.podglad-maila-zwiezly .etykieta { margin-bottom: 6px; }
/* 280 px, nie 460 (2026-09-26, [[08_DECYZJE]] D535): ramka pod KAŻDĄ
   wiadomością miała 460 px także przy dwóch linijkach — trzy wiadomości to
   4 900 px strony. Dłuższy mail ogląda się „Pełnym ekranem” obok. */
.podglad-maila-zwiezly .ramka-podgladu { height: 280px; }

.pomiar-podsumowanie { margin: 10px 0 0; }

/* Ustawienia: lista wiadomości, każda z własnym wyglądem. */
.wyglad-w-ustawieniach {
	padding: 12px 0;
	border-top: 1px solid var(--obramowanie);
}
.etykieta + .wyglad-w-ustawieniach { border-top: 0; padding-top: 4px; }
.wyglad-w-ustawieniach .pole { margin-bottom: 0; }
.wyglad-naglowek {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 6px 12px;
	margin-bottom: 8px;
}
.wyglad-naglowek .plakietka { font-size: var(--tekst-podpis); padding: 2px 10px; }
.wyglad-naglowek a { margin-left: auto; }

/* ── Segment odbiorców (2026-09-26, [[08_DECYZJE]] D503) ──────────────────
   Wszystko, co da się zrobić z segmentem — zmienić, poprawić warunki,
   obejrzeć firmy, założyć nowy — jednym wierszem przycisków pod listą,
   zamiast odnośników w zdaniach. Ten sam wiersz na „Nowej wysyłce”,
   w ustawieniach, na „Zapisach” i w ramce pustego segmentu. */
.przyciski-segmentu {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px;
	margin-top: 8px;
}
.przyciski-segmentu .przycisk { margin: 0; }
/* Ukrywanie „Popraw warunki” i „Zobacz jego firmy” bez wybranego segmentu
   (`pole-segmentu.js`) działa dzięki `.przycisk[hidden]` przy `.przycisk`. */
.komunikat .przyciski-segmentu { margin-top: 10px; }
.segment-teraz { margin: 0 0 12px; }
/* Lista i „Zmień segment” w jednym wierszu — przycisk zatwierdza wybór. */
.wybor-segmentu { display: flex; gap: 8px; align-items: stretch; }
.wybor-segmentu select { flex: 1; min-width: 0; }
.wybor-segmentu .przycisk { white-space: nowrap; }
/* Nieaktywny, dopóki na liście stoi obecny segment (`pole-segmentu.js`) —
   zielony przycisk, który nic nie zrobi, wyglądałby na gotowy. */
.wybor-segmentu .przycisk[disabled] {
	background: var(--panel-2);
	border-color: var(--obramowanie);
	color: var(--tekst-2);
}
@media (max-width: 640px) {
	.wybor-segmentu { flex-direction: column; }
}
/* Karta segmentu stoi nad kartą zapisu — bez odstępu zlewały się w jedną. */
.karta-segmentu { margin-bottom: 16px; }
.przycisk.przy-wartosci { margin-left: 8px; vertical-align: baseline; }

/* Próba na przeglądzie, nad włącznikiem (2026-09-26, D551): pole i przycisk
   w jednym wierszu, na wąskim ekranie jedno pod drugim. */
.wiersz-proby { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.wiersz-proby input { flex: 1 1 14em; min-width: 0; }
/* Linijka „Próba: dziś 20:39 na … — treść bez zmian” pod polem próby
   (2026-09-27, D675). Zielona, gdy próba jest aktualna; bursztynowa, gdy
   jej nie było, treść zmieniła się po niej albo objęła tylko część. Adres
   bywa długi — łamie się, zamiast wypychać kartę w bok na telefonie. */
.linijka-proby { margin: 8px 0; font-size: var(--tekst-drobny); overflow-wrap: anywhere; }
.linijka-proby.aktualna { color: var(--dobry); }
.linijka-proby.uwaga { color: var(--uwaga); }
/* „Co wyjdzie” przy włączniku (D678) — rzut oka, nie druga lista wiadomości. */
.co-wyjdzie { list-style: none; margin: 0; padding: 0; }
.co-wyjdzie > li { padding: 8px 0; border-top: 1px solid var(--obramowanie); overflow-wrap: anywhere; }
.co-wyjdzie > li:first-child { border-top: 0; padding-top: 0; }
.co-wyjdzie-glowka { display: flex; flex-wrap: wrap; gap: 4px 8px; align-items: baseline; }
.co-wyjdzie-podglad { margin-left: auto; font-size: var(--tekst-drobny); }
.co-wyjdzie-temat { font-weight: 600; margin: 2px 0; }
/* Komplet na etapie „Odbiorcy” (D676): jedno zdanie zamiast formularza. */
.komplet-zapisanych { margin: 4px 0 0; color: var(--dobry); font-weight: 600; }
/* Lista Mailing na telefonie (2026-09-26, D558): plakietka stanu
   („nie ruszyła — zapisz kontakty”, „czeka na włączenie · 7”) i nagłówek
   „Wysłano do” nie łamały się, więc przy 390 px tabela wypychała stronę
   w bok. Na wąskim ekranie łamią się jak zwykły tekst. */
@media (max-width: 640px) {
	.tabela-wysylek .plakietka,
	.tabela-wysylek th,
	.tabela-wysylek td:last-child { white-space: normal; }
	.tabela-wysylek th, .tabela-wysylek td { padding-left: 6px; padding-right: 6px; }
	/* Pięć kolumn i tak nie mieści się w 358 px — tabela przewija się
	   we własnym pudełku, strona zostaje w miejscu. */
	.tabela-wysylek { display: block; overflow-x: auto; }
}

/* ── RUNDA R9: BUDOWANIE WIADOMOŚCI (2026-09-27, [[08_DECYZJE]] D600–D610) ──
   Tokeny wyłącznie z `:root` (sprawdz-tokeny.py). */

/* Gotowy mail OBOK pisania (D600). Na 1440×900 ramka pod polem zaczynała się
   ok. 290 px niżej, niż kończyło się pole, a przyklejony pasek zapisu
   zasłaniał jej początek — przy pisaniu jej nie było. Dwie kolumny od
   1100 px szerokości okna; węższe ekrany — jedna pod drugą, jak dotąd. */
.wiadomosc-uklad { display: block; }
.wiadomosc-pisanie > .pole { margin-bottom: 12px; }
.wiadomosc-podglad { margin-top: 4px; }
.podglad-czeka { display: none; }

@media (min-width: 1100px) {
	/* `stretch`: kolumna pisania rośnie do wysokości kolumny z mailem,
	   a zapas bierze pole treści (niżej) — oba kończą się w jednym miejscu. */
	.wiadomosc-uklad {
		display: grid;
		grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
		gap: 18px;
		align-items: stretch;
	}
	.wiadomosc-pisanie { display: flex; flex-direction: column; }
	.wiadomosc-pisanie > .pole-tresci { flex: 1 1 auto; display: flex; flex-direction: column; }
	.wiadomosc-pisanie > .pole-tresci > textarea { flex: 1 1 auto; }
	/* Lista „Wygląd” na całą szerokość kolumny, odnośnik pod nią — obok
	   siebie w pół szerokości ucinały „(zalecane)”. */
	.wiadomosc-pisanie .oprawa-wiersz select { flex-basis: 100%; }
	/* Pasek podglądu w jednej linii z „Pełnym ekranem”: napisy „Motyw”
	   i „Ekran” schodzą (grupy mają je w `aria-label`, czytnik je poda). */
	.wiadomosc-podglad .przelacznik-opis { display: none; }
	.wiadomosc-podglad .pasek-podgladu { gap: 8px; }
	.wiadomosc-podglad { margin-top: 0; }
	/* Kolumna podglądu nie ma już kreski nad sobą — stoi obok, nie pod. */
	.wiadomosc-podglad .podglad-maila-zwiezly {
		border-top: 0;
		padding-top: 0;
		margin-top: 0;
	}
	/* Pusta ramka nie stoi obok pustego pola — zdanie zamiast niej.
	   `:has` — ramkę chowa `edytor-maila.js`, gdy pola są puste. */
	/* `data-podpieta` stawia `edytor-maila.js` — bez skryptu ramka nie
	   odsłoni się nigdy, więc nie obiecujemy, że „się pojawi”. */
	.wiadomosc-podglad:has(> [data-podglad-maila][data-podpieta][hidden]) .podglad-czeka {
		display: flex;
		align-items: center;
		justify-content: center;
		min-height: 220px;
		margin: 0;
		padding: 16px;
		border: 1px dashed var(--obramowanie);
		border-radius: var(--r);
		color: var(--tekst-3);
		font-size: var(--tekst-podpis);
		text-align: center;
	}
	/* Ramka na wysokość okna, nie 280 px (D600). Obok pola nie wydłuża
	   strony tak jak pod nim, a przy 280 px stopka oprawy (dane firmy,
	   wypis) była ucięta. Na wysokość SAMEGO maila się nie da: ramka jest
	   piaskownicą bez `allow-same-origin` (w środku jest HTML oprawy pisany
	   ręcznie), więc skrypt strony nie zmierzy jej treści. Dłuższy mail —
	   uchwyt w rogu ramki albo „Pełny ekran”. */
	.wiadomosc-podglad .podglad-maila-zwiezly .ramka-podgladu {
		height: clamp(360px, calc(100vh - 380px), 620px);
	}
	.wiadomosc-pisanie textarea[name="krok_tresc"] { min-height: 240px; }
}

/* Pola sekcji „Nazwa i odbiorcy” w czytelnej szerokości — formularz ma od
   D600 1240 px, a pole „Nazwa” na całą szerokość to linijka, której końca
   szuka się wzrokiem. */
.formularz-wysylki .sekcja-odbiorcow > .pole { max-width: 820px; }

/* Ekrany jednej wiadomości (poprawianie, nowa wersja językowa) — ten sam
   układ co wiersz „Nowej wysyłki” (D600): pole treści rośnie do wysokości
   maila obok, zamiast zostawiać pod sobą pustą kolumnę; pasek podglądu
   w jednej linii z „Pełnym ekranem”. Tylko tu — `.edytor-z-podgladem`
   ma też edytor opraw, a tam lewa kolumna to kod HTML. */
.edytor-wiadomosci { align-items: stretch; }
.edytor-wiadomosci > div:first-child { display: flex; flex-direction: column; }
.edytor-wiadomosci > div:first-child > .pole-tresci { flex: 1 1 auto; display: flex; flex-direction: column; }
.edytor-wiadomosci > div:first-child > .pole-tresci > textarea { flex: 1 1 auto; }
@media (min-width: 1100px) {
	.edytor-wiadomosci .przelacznik-opis { display: none; }
	.edytor-wiadomosci .pasek-podgladu { gap: 8px; }
}

/* Nagłówek jak w skrzynce: Od i Temat nad gotowym mailem (D601). */
.naglowek-maila {
	display: grid;
	grid-template-columns: auto minmax(0, 1fr);
	gap: 2px 10px;
	margin: 0 0 8px;
	padding: 8px 12px;
	border: 1px solid var(--obramowanie);
	border-radius: var(--r);
	background: var(--panel-2);
	font-size: var(--tekst-podpis);
}
.naglowek-maila[hidden],
.naglowek-maila [hidden] { display: none; }
.naglowek-maila-etykieta { color: var(--tekst-3); }
.naglowek-maila-wartosc { min-width: 0; overflow-wrap: anywhere; color: var(--tekst); }
.naglowek-maila-temat { font-weight: 600; }
.naglowek-maila .pusty { color: var(--tekst-3); font-weight: 400; font-style: italic; }

/* Znacznik, którego wysyłka nie podstawi — zdanie pod polem (D603). */
.uwaga-znacznikow { margin: 6px 0 0; font-size: var(--tekst-podpis); }
.uwaga-znacznikow[hidden] { display: none; }
.uwaga-znacznika { display: block; }
.uwaga-znacznika + .uwaga-znacznika { margin-top: 4px; }
.uwaga-znacznika code { font-weight: 600; }
.uwaga-znacznika .przycisk { margin-left: 4px; vertical-align: baseline; }
[data-zly-znacznik] { border-color: var(--zly); }

/* Kto dostanie którą wersję — linijka pod główką wiadomości (D602). */
.jezyki-wiadomosci { margin: -2px 0 10px; }
.jezyki-wiadomosci[hidden] { display: none; }
.jezyki-wiadomosci .brak-wersji { color: var(--uwaga); font-weight: 500; }
.jezyki-wiadomosci .ma-wersje { color: var(--zielen-ciemna); }
.jezyki-wiadomosci .przycisk { margin-left: 2px; vertical-align: baseline; }

/* „wersja podstawowa” obok nazwy wiadomości, która ma wersje (D605). */
.plakietka-podstawowa {
	font-size: var(--tekst-drobny);
	color: var(--tekst-2);
	border: 1px dashed var(--obramowanie);
	border-radius: 999px;
	padding: 1px 8px;
}
.plakietka-podstawowa[hidden] { display: none; }
.menu-jezykow-lista [data-dopisek-podstawy] { display: block; margin: 0; }

/* Sekcje „Gdy ktoś odpisze” i „Pomiar” zwinięte do zdania (D604). Domyślne
   ustawienia są dobre, więc nie zajmują ekranu, na którym się pisze —
   rozwijają się same, gdy coś jest nie tak (brak skrzynki). */
.sekcja-zwijana { padding: 0; }
.sekcja-zwijana > details > summary {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 4px 12px;
	padding: 16px 22px;
	cursor: pointer;
	list-style: none;
}
.sekcja-zwijana > details > summary::-webkit-details-marker { display: none; }
.sekcja-zwijana > details > summary .sekcja-tytul { margin: 0; }
.sekcja-zwijana .sekcja-stan { flex: 1 1 280px; min-width: 0; color: var(--tekst-2); font-size: var(--tekst-podpis); }
.sekcja-zwijana .sekcja-zmien { color: var(--zielen); font-size: var(--tekst-podpis); font-weight: 500; }
.sekcja-zwijana > details[open] .sekcja-zmien { display: none; }
.sekcja-zwijana > details > summary:hover .sekcja-zmien { text-decoration: underline; }
.sekcja-zwijana .sekcja-zawartosc { padding: 0 22px 20px; }
.sekcja-zwijana .sekcja-zawartosc > .pod:first-child { margin-top: 0; }

/* Chipy znaczników NAZWAMI (D608) — „+ Imię”, krojem tekstu, nie kodu.
   Tylko wspólna część ekranów wiadomości; edytor opraw pokazuje w chipach
   kod (`{{link_wypisu}}`) i zostaje przy kroju maszynowym. */
.chipy-znacznikow[data-chipy-wiersza] .chip-znacznika { font-family: inherit; }

/* Ramka o językach skrócona do linijki na etapach bez decyzji (D609). */
.komunikat.jezyki-skrot { padding-top: 8px; padding-bottom: 8px; }

/* Karta zwinięta do jednej linii (2026-10-07, D811): Ustawienia i lista osób
   na etapie 4. Etykieta, stan, akcja i „szczegóły”, które znikają po
   rozwinięciu — jak „Zmień” w sekcjach Nowej wysyłki (D604). */
.karta-linia > summary {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 2px 10px;
	cursor: pointer;
	list-style: none;
}
.karta-linia > summary::-webkit-details-marker { display: none; }
.karta-linia > summary .etykieta { margin: 0; flex: 1 1 auto; }
/* Stan pod etykietą, na całą szerokość — w kolumnie 340–600 px obok
   etykiety łamał się w wąski słupek. */
.karta-linia .linia-stan { order: 5; flex: 1 1 100%; min-width: 0; color: var(--tekst-2); font-size: var(--tekst-podpis); overflow-wrap: anywhere; }
.karta-linia .linia-akcja { font-size: var(--tekst-podpis); }
.karta-linia .linia-pokaz { color: var(--zielen); font-size: var(--tekst-podpis); font-weight: 500; }
.karta-linia .linia-pokaz::after { content: " ▾"; }
.karta-linia > summary:hover .linia-pokaz { text-decoration: underline; }
.karta-linia[open] .linia-pokaz,
.karta-linia[open] .linia-stan { display: none; }
.karta-linia[open] > summary { margin-bottom: 10px; }

/* Kafel języka z wyborem „Przetłumacz / Napiszę sam” (D607). */
.kafel-wyboru { position: relative; }
.kafel-wyboru > summary { list-style: none; }
.kafel-wyboru > summary::-webkit-details-marker { display: none; }
.kafel-wyboru-lista {
	position: absolute;
	left: 0;
	top: calc(100% + 4px);
	z-index: 25;
	width: 260px;
	padding: 8px;
	border: 1px solid var(--obramowanie);
	border-radius: var(--r);
	background: var(--panel);
	box-shadow: 0 6px 20px rgba(20, 40, 35, .12);
}
.kafel-wyboru-lista .przycisk { display: block; width: 100%; margin-bottom: 6px; text-align: left; }
.kafel-wyboru-lista .pod { margin: 2px 0 8px; }
.kafel-wyboru-lista .pod:last-child { margin-bottom: 0; }

@media (max-width: 800px) {
	.sekcja-zwijana > details > summary { padding: 14px; }
	.sekcja-zwijana .sekcja-zawartosc { padding: 0 14px 16px; }
	/* Na telefonie lista w przepływie, pod rozwiniętym kaflem na całą
	   szerokość rzędu — pozycjonowana względem strony lądowała ~2000 px nad
	   kaflem i tap wyglądał, jakby nie działał (przegląd, 2026-09-27). */
	.kafel-wyboru[open] { flex-basis: 100%; }
	.kafel-wyboru-lista { position: static; width: auto; margin-top: 4px; }
}

/* Źródło danych partii importu (2026-09-28, D693): pole przy imporcie pod
   rzędem ustawień i dopisywanie w Historii importów. */
.pole-zrodla-importu { margin-top: 16px; max-width: 640px; }
.pole-zrodla-importu input { width: 100%; }
.zrodlo-partii { margin-top: 4px; }
.zrodlo-partii > summary { cursor: pointer; color: var(--zielen); }
.zrodlo-partii-formularz { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.zrodlo-partii-formularz input[type=text] { flex: 1 1 160px; min-width: 0; }

/* ── POWITANIA (2026-09-28, [[08_DECYZJE]] D698) ─────────────────────────
   Ustawienia → Wysyłka → Powitania. Język = zwijana karta z trzema polami
   formuł obok siebie (na telefonie jedno pod drugim) i przykładami pod
   spodem. Imiona — wiersz z nazwą, płcią, wołaczem i „Zapisz”, zawijany
   na wąskim ekranie zamiast przewijania w bok. */
.jezyk-powitania {
	border-top: 1px solid var(--obramowanie-2);
	padding: 12px 0;
}
.jezyk-powitania:first-of-type { border-top: 0; padding-top: 0; }
.jezyk-powitania > summary {
	cursor: pointer;
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 4px 10px;
}
.jezyk-powitania > summary .pod { overflow-wrap: anywhere; }
.formuly-powitania {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr));
	gap: 12px 16px;
	margin-top: 12px;
}
.formuly-powitania .pole { margin-bottom: 0; }
.przyklady-powitania { margin: 10px 0 8px; }
.przyklady-powitania ul { margin: 4px 0 0; padding-left: 18px; }
.lista-imion { list-style: none; margin: 8px 0 0; padding: 0; }
.lista-imion > li { border-bottom: 1px solid var(--obramowanie-2); padding: 8px 0; }
.lista-imion > li:last-child { border-bottom: 0; }
.imie-w-wierszu {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px 10px;
}
.imie-w-wierszu .imie-nazwa { flex: 1 1 180px; min-width: 0; overflow-wrap: anywhere; }
.imie-w-wierszu select { width: auto; }
.imie-w-wierszu input[type="text"] { width: 150px; max-width: 100%; }
.podpowiedz-powitania[hidden] { display: none; }
.podpowiedz-powitania .przycisk { margin-left: 4px; }

/* ── BUDOWA MAILA: Z CZEGO SIĘ SKŁADA (2026-10-02, [[08_DECYZJE]] D720) ──
 *
 * Rysunek maila po lewej, osiem części z opisem po prawej; numery łączą
 * jedno z drugim. Kolumny `minmax(0, …)`: zawartość (długi adres nadawcy)
 * nie może rozepchnąć siatki poza ekran telefonu — pułapka z D717. Poniżej
 * 1040 px jedno pod drugim: rysunek najpierw, bo to on tłumaczy numery. */
.budowa-maila {
	display: grid;
	grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
	gap: 20px;
	align-items: start;
}
@media (max-width: 1040px) {
	.budowa-maila { grid-template-columns: minmax(0, 1fr); }
}
.budowa-uwagi { margin: 6px 0 0; padding-left: 18px; }
.budowa-uwagi li + li { margin-top: 6px; }

.makieta-maila {
	background: var(--panel);
	border: 1px solid var(--obramowanie);
	border-radius: var(--r);
	box-shadow: var(--cien);
	overflow: hidden;
	font-size: var(--tekst-wiersz);
}
.makieta-naglowek {
	padding: 12px 16px;
	border-bottom: 1px solid var(--obramowanie-2);
	background: var(--panel-2);
}
.makieta-wiersz {
	display: flex;
	align-items: center;
	gap: 8px;
	min-width: 0;
}
.makieta-wiersz + .makieta-wiersz { margin-top: 6px; }
.makieta-pole { flex: none; width: 48px; color: var(--tekst-3); font-size: var(--tekst-podpis); }
.makieta-wartosc { min-width: 0; overflow-wrap: anywhere; }
.makieta-karta {
	margin: 14px;
	border: 1px solid var(--obramowanie-2);
	border-top: 4px solid var(--zielen);
	border-radius: 6px;
}
.makieta-czesc {
	display: flex;
	align-items: flex-start;
	gap: 10px;
	min-width: 0;
}
.makieta-czesc > span:last-child { min-width: 0; overflow-wrap: anywhere; }
.makieta-czesc .sekcja-numer { margin-top: -2px; }
.makieta-logo { align-items: center; padding: 12px 16px 0; }
.makieta-znak {
	padding: 4px 12px;
	border: 1px dashed var(--obramowanie);
	border-radius: 4px;
	color: var(--tekst-3);
	font-size: var(--tekst-podpis);
}
.makieta-tresc { padding: 14px 16px; }
.makieta-tresc .makieta-czesc + .makieta-czesc { margin-top: 12px; }
.makieta-rodo { color: var(--tekst-2); font-size: var(--tekst-podpis); }
.makieta-stopka {
	padding: 12px 16px 14px;
	border-top: 1px solid var(--obramowanie-2);
	color: var(--tekst-2);
	font-size: var(--tekst-podpis);
}

.czesci-maila { list-style: none; margin: 0; padding: 0; }
.czesci-maila > li {
	display: flex;
	gap: 12px;
	padding: 12px 0;
	border-bottom: 1px solid var(--obramowanie-2);
}
.czesci-maila > li:first-child { padding-top: 0; }
.czesci-maila > li:last-child { border-bottom: 0; }
.czesci-maila > li > div { min-width: 0; }
.czesci-maila p { margin: 4px 0 6px; color: var(--tekst-2); font-size: var(--tekst-wiersz); }
.czesc-tytul { margin: 2px 0 0; font-size: var(--tekst-bazowy); font-weight: 600; }
/* Zestaw firmy (2026-10-02, [[08_DECYZJE]] D790): plakietka stanu po lewej,
   zdanie z drogą do uzupełnienia obok. `min-width: 0` — długi adres nadawcy
   łamie się zamiast rozpychać kartę na telefonie (D717). */
.lista-zestawu { list-style: none; margin: 10px 0 0; padding: 0; }
.lista-zestawu > li {
	display: flex;
	align-items: baseline;
	gap: 10px;
	padding: 8px 0;
	border-bottom: 1px solid var(--obramowanie-2);
	font-size: var(--tekst-wiersz);
}
.lista-zestawu > li:last-child { border-bottom: 0; }
.lista-zestawu > li > .plakietka { flex: none; min-width: 44px; text-align: center; }
.lista-zestawu > li > div { min-width: 0; overflow-wrap: anywhere; }
/* Porównania zwinięte (D791) — nagłówek rozwijki czytany jak tytuł karty. */
.porownanie-zwiniete > summary { cursor: pointer; padding: 2px 0; }
.porownanie-zwiniete > summary:focus-visible { outline: 2px solid var(--zielen); outline-offset: 2px; }
.porownanie-zwiniete[open] > summary { margin-bottom: 10px; }
/* Porównanie dwóch wyglądów i wysyłki z Pocztą: nagłówek wiersza to nazwa
   cechy — czytany jak pierwsza kolumna tekstu, nie jak tytuł na środku. */
.tabela-porownania th[scope="row"] {
	text-align: left;
	padding: 10px 12px;
	font-weight: 600;
	font-size: var(--tekst-wiersz);
	border-bottom: 1px solid var(--obramowanie-2);
}
.tabela-porownania tbody tr:last-child th { border-bottom: 0; }
/* „Skąd się biorą części tego maila” pod ramką podglądu (D722). */
.skad-czesci { margin-top: 10px; font-size: var(--tekst-podpis); color: var(--tekst-2); }
.skad-czesci > summary { cursor: pointer; color: var(--zielen); }
.skad-czesci ul { margin: 8px 0; padding-left: 18px; }
.skad-czesci li + li { margin-top: 4px; }

/* --- zakładka „Asystent” (2026-10-04, [[08_DECYZJE]] D795) -------------- */

/* Układ jak Skrzynka: lista rozmów po lewej, rozmowa po prawej. `minmax(0, …)`
   z tego samego powodu co tam (D794): długi wiersz nie rozpycha strony. */
.asystent-uklad {
	display: grid;
	grid-template-columns: minmax(180px, 250px) minmax(0, 1fr);
	gap: 16px;
	align-items: start;
}
.asystent-lista { padding: 12px; }
.asystent-lista .przycisk.napisz { display: block; text-align: center; margin-bottom: 10px; }
.asystent-lista ul { list-style: none; margin: 0 0 10px; padding: 0; }
.asystent-lista li a {
	display: block;
	padding: 7px 10px;
	border-radius: var(--r);
	color: var(--tekst-2);
	text-decoration: none;
	font-size: var(--tekst-wiersz);
}
.asystent-lista li a:hover { background: var(--panel-2); color: var(--tekst); }
.asystent-lista li a[aria-current="page"] {
	background: var(--zielen-mgla);
	color: var(--zielen-ciemna);
	font-weight: 600;
}
.asystent-lista-tytul { display: block; overflow-wrap: anywhere; }
.asystent-lista li .pod { display: block; font-weight: 400; }

.asystent-rozmowa { min-width: 0; display: flex; flex-direction: column; gap: 12px; }
.asystent-glowka { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.asystent-glowka h2 { flex: 1 1 260px; margin: 0; font-size: 18px; overflow-wrap: anywhere; }

.asystent-wymiany { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 12px; }
.asystent-wpis { display: flex; flex-direction: column; gap: 8px; max-width: 760px; scroll-margin-top: 16px; }
.asystent-wpis-ty { align-self: flex-end; align-items: flex-end; max-width: min(620px, 92%); }
.asystent-wpis .asystent-dymek {
	padding: 10px 14px;
	border-radius: var(--r);
	font-size: var(--tekst-wiersz);
	overflow-wrap: anywhere;
}
.asystent-wpis-ty .asystent-dymek { background: var(--zielen-mgla); color: var(--zielen-ciemna); }
.asystent-wpis-odp .asystent-dymek {
	background: var(--panel);
	border: 1px solid var(--obramowanie);
	box-shadow: var(--cien);
}
.asystent-wpis-odp .asystent-dymek p { margin: 0 0 8px; }
.asystent-wpis-odp .asystent-dymek p:last-child,
.asystent-wpis-odp .asystent-dymek ul:last-child,
.asystent-wpis-odp .asystent-dymek ol:last-child { margin-bottom: 0; }
.asystent-wpis-odp .asystent-dymek ul,
.asystent-wpis-odp .asystent-dymek ol { margin: 0 0 8px; padding-left: 20px; }
.asystent-wpis-odp .asystent-dymek-odmowa { background: var(--uwaga-tlo); border-color: var(--uwaga-tlo); color: var(--uwaga); }
.asystent-wpis-odp .asystent-dymek-mysli { color: var(--tekst-3); font-style: italic; }

/* Karta pod odpowiedzią — węższa od zwykłej, bo stoi w rozmowie. */
.karta.karta-asystenta { padding: 12px 14px; font-size: var(--tekst-wiersz); }
.karta-asystenta p { margin: 0 0 6px; }
.karta-asystenta .lista-zwarta { margin-bottom: 6px; }
.karta-asystenta form { margin: 8px 0 4px; }
.karta-asystenta-akcje { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; margin: 6px 0; }

.co-sprawdzilem { font-size: var(--tekst-podpis); color: var(--tekst-2); }
.co-sprawdzilem > summary { cursor: pointer; color: var(--zielen); }
.co-sprawdzilem ul { margin: 6px 0 0; padding-left: 18px; }

.asystent-powitanie p { margin: 0 0 10px; max-width: 720px; }
.asystent-przyklady { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; }
.asystent-przyklady form { margin: 0; }
.asystent-przyklady .przycisk { text-align: left; white-space: normal; }

/* Pole pytania przyklejone do dołu okna — rozmowa przewija się nad nim. */
.asystent-pytanie {
	position: sticky;
	bottom: 0;
	background: var(--tlo);
	padding: 10px 0 12px;
	border-top: 1px solid var(--obramowanie-2);
}
.asystent-pytanie textarea { resize: vertical; min-height: 72px; }
.asystent-pytanie-dol { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 8px; }
.asystent-pytanie-dol .pod { flex: 1 1 260px; }

@media (max-width: 800px) {
	.asystent-uklad { grid-template-columns: minmax(0, 1fr); }
	/* Na telefonie lista rozmów zwinięta do kilku ostatnich — nad rozmową. */
	.asystent-lista ul { max-height: 170px; overflow-y: auto; }
	.asystent-wpis-ty { max-width: 100%; }
}

/* ── SZABLONY JAKO GOTOWE MAILE (2026-10-04, [[08_DECYZJE]] D796) ─────────
   Lista szablonów to karty z podglądem całego maila — szablon to cały mail
   (logo, treść, stopka), więc jego wygląd jest pierwszą rzeczą na karcie.
   Ramka jest obrazkiem: nie przewija się i nie łapie kliknięć — drogą do
   szablonu jest nazwa pod nią. Na telefonie karty idą jedna pod drugą. */
.szablony-siatka {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
	gap: 16px;
	margin-top: 12px;
}
.szablon-karta { display: flex; flex-direction: column; padding: 0; overflow: hidden; }
.szablon-karta-podglad {
	display: block;
	height: 300px;
	overflow: hidden;
	border-bottom: 1px solid var(--obramowanie);
	background: #fff;   /* biel, bo taki jest domyślny kanwas maila */
}
.szablon-karta-podglad iframe {
	/* Mail ma 600 px — ramka dwa razy szersza od karty, pomniejszona o połowę,
	   pokazuje cały układ zamiast lewego górnego rogu. */
	width: 200%;
	height: 200%;
	border: 0;
	transform: scale(0.5);
	transform-origin: 0 0;
	pointer-events: none;
}
.szablon-karta-opis { padding: 12px 14px 14px; display: flex; flex-direction: column; gap: 4px; }
.szablon-karta-nazwa { margin: 0; font-size: var(--tekst-wiersz); }
.szablon-karta-stan { margin-top: 4px; }

/* Przycisk „Wstaw treść szablonu” przy liście szablonu wiadomości (D796). */
/* `:not([hidden])` — `display: flex` zagłuszyłby atrybut `hidden` (skrypt chowa nim przycisk). */
.wstaw-tresc-szablonu:not([hidden]) { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 6px; }

/* ROZMOWA SMS (2026-10-05, [[08_DECYZJE]] D807) — dymki jak w telefonie:
   klient po lewej, my po prawej. Kolory z tokenów, jak oś czasu: wiadomość
   od klienta w zieleni „otrzymane”, nasza w błękicie „wysłane”. */
.sms-watek { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.sms-watek .sms { max-width: min(560px, 85%); padding: 8px 12px; border-radius: var(--r); border: 1px solid var(--obramowanie-2); }
.sms-watek .sms.od-klienta { align-self: flex-start; background: var(--dobry-tlo); }
.sms-watek .sms.od-nas { align-self: flex-end; background: var(--info-tlo); }
.sms-watek .sms-tresc { white-space: normal; overflow-wrap: anywhere; }
