/* ═══════════════════════════════════════════════════════════════════════════
   ewi.agency ticket software · arkusz stylów
   ═══════════════════════════════════════════════════════════════════════════

   Wygląd przeniesiony z panelu ewi.agency (ai-ewicms/assets/panel.css): te
   same zmienne, ta sama metryka, ten sam jeden akcent. Dzięki temu uploader
   stoi obok panelu jak jego część, a nie jak osobne narzędzie.

   Zasada stamtąd, której trzymamy się i tu: gradient jest JEDEN i pracuje
   w jednym miejscu — na polu zrzutu plików. Nie wchodzi na przyciski ani na
   tabele, bo wtedy przestaje cokolwiek znaczyć.

   Ekran dzieli się na dwie kolumny: po lewej zdjęcie klienta (stała,
   nieruchoma płaszczyzna przez cały proces), po prawej kolejne kroki —
   PIN, wgrywanie, potwierdzenie.

   ── UKŁAD PLIKU ─────────────────────────────────────────────────────────
     1. Zmienne — motyw jasny i ciemny
     2. Reset i typografia
     3. Układ dwukolumnowy
     4. Lewa kolumna — zdjęcie klienta
     5. Prawa kolumna — treść kroków
     6. Przyciski, pola
     7. Klawiatura PIN
     8. Pole zrzutu i lista plików
     9. Potwierdzenie zgłoszenia
    10. Panel zgłoszeń
    11. Przełącznik motywu
    12. Ruch, dostępność, wersja mobilna
   ═══════════════════════════════════════════════════════════════════════ */


/* ── 1. Zmienne ───────────────────────────────────────────────────────── */
:root {
  --app: #efece2;
  --panel: #faf9f5;
  --panel-2: #f4f2ea;
  --line: #e2ded0;
  --line-2: #d2cdba;

  --text: #1c1b17;
  --text-2: #56534a;
  --text-3: #7a7768;

  --blue: #1583ff;
  --blue-ink: #0a68d8;
  --blue-soft: rgba(21, 131, 255, .09);
  --blue-line: rgba(21, 131, 255, .26);

  --good: #14804a;
  --warn: #b7791f;
  --bad: #c93c31;

  /* Barwy stanu sprawy. Nazwy to klucze z src/Status.php — jeden stan ma
     jedną barwę wszędzie: w panelu obsługi, u oddziału i w przeglądzie
     zarządu. Wcześniej plakietka „W trakcie prac" brała --blue, czyli akcent
     MARKI. U NaturHouse akcentem jest zieleń, więc ten sam stan bywał zielony
     obok zielonego „Zamknięte" (1,16:1, 13 stopni odcienia) i jednocześnie
     niebieski w wierszu obok, bo obwódkę wiersza maluje kanoniczna 'barwa'
     z PHP. Stan sprawy jest faktem o sprawie i nie ma prawa zmieniać się
     razem z barwami klienta.

     Odcienie są ciemniejsze od kanonicznych 'barwa' z src/Status.php, bo tam
     służą jako obwódki i kropki — element graficzny, próg 3:1 — a tutaj jako
     pismo 11,5 px, próg 4,5:1. Kanoniczne #2e7de0 daje na białej karcie
     3,54:1; te wartości dają 4,5–5,8:1 na każdej płaszczyźnie w aplikacji.
     Odcień zostaje ten sam: 37° dla zgłoszonych, 213° dla prac, 146° dla
     zamkniętych — czyli plakietka i obwódka wiersza to nadal ta sama barwa. */
  --st-zgloszone: #8a5b0d;
  --st-w-trakcie: #1f5fae;
  --st-zamkniete: #0a6b34;

  --aura-1: rgba(47, 107, 255, .13);
  --aura-2: rgba(122, 90, 248, .10);

  --grad: linear-gradient(118deg, #2f6bff 0%, #21d4fd 46%, #7a5af8 100%);
  --grad-soft: linear-gradient(118deg, rgba(47,107,255,.10) 0%, rgba(33,212,253,.10) 46%, rgba(122,90,248,.10) 100%);

  --r: 12px;
  --r-sm: 8px;
  --shadow: 0 1px 2px rgba(52, 46, 32, .05), 0 1px 3px rgba(52, 46, 32, .04);
  --shadow-lift: 0 10px 30px rgba(52, 46, 32, .13);

  --display: "Poppins", system-ui, sans-serif;
  --ui: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;

  color-scheme: light;
}

[data-theme="dark"] {
  --app: #0a1220;
  --panel: #101a2b;
  --panel-2: #0d1626;
  --line: rgba(255, 255, 255, .08);
  --line-2: rgba(255, 255, 255, .15);

  --text: #e8eef7;
  --text-2: #9aaac0;
  --text-3: #6b7c93;

  --blue: #5b9cf5;
  --blue-ink: #8ab8ff;
  --blue-soft: rgba(91, 156, 245, .14);
  --blue-line: rgba(91, 156, 245, .36);

  --good: #3fbf7f;
  --warn: #e0a33e;
  --bad: #ef6f5e;

  /* Te same trzy stany rozjaśnione — patrz komentarz w :root. Muszą zdać
     próg na DWÓCH ciemnych płaszczyznach naraz: granatowej karcie panelu
     (#101a2b) i ciemnozielonej karcie klienta, która powstaje z --blue-ink
     domieszanego czernią. Ta druga jest jaśniejsza, więc to ona wyznacza
     dolną granicę: 5,18 / 4,90 / 4,86:1. */
  --st-zgloszone: #e8b45a;
  --st-w-trakcie: #8fbcf7;
  --st-zamkniete: #52cf90;

  --aura-1: rgba(47, 107, 255, .30);
  --aura-2: rgba(33, 212, 253, .15);

  --shadow: 0 1px 2px rgba(0, 0, 0, .4);
  --shadow-lift: 0 16px 40px rgba(0, 0, 0, .55);

  color-scheme: dark;
}


/* ── 2. Reset i typografia ────────────────────────────────────────────── */
* { margin: 0; padding: 0; box-sizing: border-box; }

body {
  background: var(--app);
  color: var(--text);
  font: 400 14px/1.55 var(--ui);
  -webkit-font-smoothing: antialiased;
  transition: background .25s, color .25s;
}

a { color: inherit; text-decoration: none; }
/* Komponenty niżej ustawiają display: flex/grid, a to bije atrybut hidden
   z domyślnego arkusza przeglądarki. Bez tej linii ukrywane bloki
   (podsumowanie, pasek postępu, komunikat błędu) zostają widoczne. */
[hidden] { display: none !important; }
ul, ol { list-style: none; }
img, svg { max-width: 100%; display: block; }
input, select, textarea, button { font: inherit; color: inherit; }

h1, h2, h3 { font-family: var(--display); font-weight: 600; letter-spacing: -.02em; line-height: 1.2; }
h1 { font-size: 27px; }
h2 { font-size: 17px; }

.muted { color: var(--text-2); }
.tiny  { font-size: 12px; color: var(--text-3); }
.mono  { font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace; }

:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; border-radius: 4px; }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }


/* ── 3. Układ dwukolumnowy ────────────────────────────────────────────── */
.split { min-height: 100vh; display: grid; grid-template-columns: 1.05fr 1fr; }


/* ── 4. Lewa kolumna — zdjęcie klienta ────────────────────────────────────
   Zdjęcie jest podmieniane per klient, więc kontrast białych napisów nie
   może zależeć od tego, co na nim jest. Stąd ta sama konstrukcja warstw
   co na ekranie logowania w panelu: równy przyciemniacz ustawia podłogę
   kontrastu, gradienty dokładają cień pod znak i pod stopkę, na końcu
   idzie barwna poświata marki.                                            */
.visual {
  position: relative; overflow: hidden;
  display: flex; flex-direction: column; justify-content: space-between;
  padding: 42px; color: #fff; background: #0a1220;
  --scrim: .10;
}
.visual__photo { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.visual::after {
  content: ""; position: absolute; inset: 0;
  background:
    linear-gradient(rgba(6, 12, 22, var(--scrim)), rgba(6, 12, 22, var(--scrim))),
    linear-gradient(to top, rgba(6, 12, 22, .95) 0%, rgba(6, 12, 22, .5) 46%, rgba(6, 12, 22, .2) 100%),
    linear-gradient(105deg, rgba(6, 12, 22, .8) 0%, rgba(6, 12, 22, .15) 62%),
    linear-gradient(215deg, rgba(47, 107, 255, .42) 0%, rgba(122, 90, 248, 0) 55%);
}
/* Warstwy treści nad zdjęciem i poświatą. Wyliczone z nazwy, nie przez
   `.visual > *` — tamten zapis miał tę samą wagę co reguła zdjęcia i
   zdejmował mu position: absolute, przez co fotografia wchodziła
   w układ zamiast wypełniać kolumnę. */
.visual__logo, .visual__claim, .visual__meta { position: relative; z-index: 2; }
.visual__glow {
  position: absolute; z-index: 1; width: 62vw; height: 62vw; max-width: 760px; max-height: 760px;
  right: -18%; top: -22%; border-radius: 50%; pointer-events: none;
  background: radial-gradient(circle, rgba(21, 131, 255, .5) 0%, rgba(122, 90, 248, .2) 42%, transparent 68%);
  filter: blur(28px);
}

.visual__logo { display: flex; align-items: center; gap: 14px; }
.visual__logo-img { height: auto; width: auto; max-height: 46px; max-width: 240px; filter: drop-shadow(0 2px 10px rgba(0, 0, 0, .45)); }

.visual__claim h2 {
  font-family: var(--display); font-weight: 700;
  font-size: clamp(28px, 3.2vw, 44px); line-height: 1.05; letter-spacing: -.035em; color: #fff;
}
.visual__claim p { margin-top: 16px; font-size: 15px; color: rgba(255, 255, 255, .8); max-width: 420px; }

.visual__meta { display: flex; gap: 34px; flex-wrap: wrap; font-size: 11.5px; color: rgba(255, 255, 255, .6); }
.visual__meta b {
  display: block; font-family: var(--display); font-weight: 700; font-size: 20px;
  color: #fff; letter-spacing: -.02em;
}


/* ── 4b. Lewa kolumna bez zdjęcia — ekran obsługi ─────────────────────────
   Agencja nie ma tu własnej fotografii, a fotografia klienta należy do
   klienta. Warstwy z `.visual::after` są przyciemniaczem ZDJĘCIA: bez niego
   pod spodem ich dolny gradient robi z granatu czarną plamę i zjada hasło.
   Dlatego wariant agencyjny podmienia je w całości — granat marki, chłodna
   poświata i ledwo widoczna siatka, żeby płaszczyzna nie czytała się jak
   pusty prostokąt. Zmienna --scrim z bloku wyżej jest tu bez znaczenia,
   bo nie ma czego przyciemniać.                                            */
.visual--agencja {
  background: #0a1220;
  /* W ciemnym motywie prawa kolumna też jest granatowa (--panel: #101a2b)
     i granica kolumn ginie w dolnej połowie ekranu. Jeden piksel ją trzyma. */
  box-shadow: inset -1px 0 0 rgba(255, 255, 255, .09);
}
.visual--agencja::after {
  background:
    linear-gradient(160deg, rgba(47, 107, 255, .20) 0%, rgba(122, 90, 248, .10) 38%, transparent 66%),
    linear-gradient(to top, rgba(6, 12, 22, .72) 0%, rgba(6, 12, 22, .18) 52%, transparent 100%),
    repeating-linear-gradient(0deg, rgba(255, 255, 255, .055) 0 1px, transparent 1px 56px),
    repeating-linear-gradient(90deg, rgba(255, 255, 255, .055) 0 1px, transparent 1px 56px);
}
/* Druga poświata, po przekątnej od tej z `.visual__glow` — sama jedna
   zostawiała dolny róg martwy, dokładnie pod hasłem. */
.visual--agencja::before {
  content: ""; position: absolute; z-index: 1; pointer-events: none;
  left: -22%; bottom: -28%; width: 54vw; height: 54vw;
  max-width: 620px; max-height: 620px;
  border-radius: 50%; filter: blur(30px);
  background: radial-gradient(circle, rgba(33, 212, 253, .30) 0%, rgba(33, 212, 253, 0) 66%);
}


/* ── 5. Prawa kolumna ─────────────────────────────────────────────────── */
.side {
  position: relative; overflow: hidden;
  display: grid; align-content: center; justify-items: center;
  padding: 46px 30px; background: var(--panel);
}
.side--top { align-content: start; overflow-y: auto; }

/* Poświata pod treścią — ma być czuć, że coś się dzieje, i nie umieć
   wskazać co. Mocniejsza zaczęłaby przeszkadzać w czytaniu etykiet. */
.side__aura { position: absolute; inset: 0; z-index: 0; overflow: hidden; pointer-events: none; }
.side__aura span { position: absolute; display: block; border-radius: 50%; filter: blur(60px); }
.side__aura span:first-child {
  width: 46vw; max-width: 560px; aspect-ratio: 1; left: -17%; top: -24%;
  background: radial-gradient(circle, var(--aura-1) 0%, transparent 68%);
}
.side__aura span:last-child {
  width: 40vw; max-width: 480px; aspect-ratio: 1; right: -19%; bottom: -26%;
  background: radial-gradient(circle, var(--aura-2) 0%, transparent 70%);
}
.side__box { position: relative; z-index: 2; width: 100%; max-width: 380px; }
.side__box--wide { max-width: 520px; }

.step { font-size: 11px; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; color: var(--text-3); }
.lead { margin-top: 9px; color: var(--text-2); font-size: 14px; }
.side__box h1 { margin-top: 12px; }


/* ── 6. Przyciski i pola ──────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  height: 36px; padding: 0 14px;
  border: 1px solid transparent; border-radius: var(--r-sm);
  background: none; cursor: pointer;
  font-size: 13px; font-weight: 500; white-space: nowrap;
  transition: background .16s, border-color .16s, color .16s, opacity .16s;
}
.btn:disabled { opacity: .4; cursor: not-allowed; }
.btn--primary { background: var(--blue); color: #fff; }
.btn--primary:not(:disabled):hover { background: var(--blue-ink); }
.btn--quiet { border-color: var(--line-2); color: var(--text); background: var(--panel); }
.btn--quiet:not(:disabled):hover { border-color: var(--text-3); }
.btn--bad { border-color: var(--line-2); color: var(--bad); background: var(--panel); }
.btn--bad:not(:disabled):hover { border-color: var(--bad); background: rgba(201, 60, 49, .08); }
.btn--block { width: 100%; height: 44px; font-size: 14px; }
.btn--sm { height: 30px; padding: 0 10px; font-size: 12px; }

.field-row { margin-top: 16px; }
/* Wartość, której nie da się zmienić, bo nie pochodzi z formularza — wygląda
   jak treść, nie jak wyszarzone pole. Wyszarzone pole obiecuje, że da się je
   odblokować; ten wiersz niczego nie obiecuje. */
.stala { margin: 0; font-size: 14.5px; font-weight: 600; color: var(--text); line-height: 1.4; }
.label { display: block; margin-bottom: 6px; font-size: 12px; font-weight: 500; color: var(--text-2); }
.field {
  width: 100%; min-height: 40px; padding: 9px 12px;
  border: 1px solid var(--line-2); border-radius: var(--r-sm);
  background: var(--panel-2); color: var(--text);
  transition: border-color .16s, box-shadow .16s, background .16s;
}
.field:focus { outline: none; border-color: var(--blue); box-shadow: 0 0 0 3px var(--blue-soft); background: var(--panel); }
textarea.field { min-height: 108px; resize: vertical; line-height: 1.6; }

.alert {
  margin-top: 14px; padding: 10px 12px; border-radius: var(--r-sm);
  border: 1px solid var(--blue-line); background: var(--blue-soft); font-size: 13px;
}
.alert--bad { border-color: rgba(201, 60, 49, .35); background: rgba(201, 60, 49, .09); color: var(--bad); }
.alert--good { border-color: rgba(20, 128, 74, .3); background: rgba(20, 128, 74, .09); color: var(--good); }


/* ── 7. Klawiatura PIN ────────────────────────────────────────────────────
   Kwadraty pokazują tylko, ile cyfr wpisano — nigdy samych cyfr. Klawiatura
   ekranowa jest tu dlatego, że kod bywa wpisywany na telefonie w terenie,
   a nie przy klawiaturze fizycznej. Klawisze mają 60 px, bo to minimum,
   przy którym nie trafia się w sąsiednią cyfrę kciukiem.                   */
.pin { display: flex; gap: 10px; justify-content: center; margin: 26px 0 4px; }
.pin__box {
  width: 44px; height: 54px; border-radius: var(--r-sm);
  border: 1px solid var(--line-2); background: var(--panel-2);
  display: grid; place-items: center;
  transition: border-color .16s, background .16s, transform .16s;
}
.pin__box::after {
  content: ""; width: 11px; height: 11px; border-radius: 50%;
  background: var(--blue); opacity: 0; transform: scale(.4);
  transition: opacity .16s, transform .18s cubic-bezier(.2, .9, .3, 1.4);
}
.pin__box.is-filled { border-color: var(--blue-line); background: var(--blue-soft); }
.pin__box.is-filled::after { opacity: 1; transform: scale(1); }
.pin__box.is-next { border-color: var(--blue); box-shadow: 0 0 0 3px var(--blue-soft); }
.pin.is-bad { animation: shake .34s; }
@keyframes shake {
  20% { transform: translateX(-7px); } 45% { transform: translateX(6px); }
  70% { transform: translateX(-4px); } 100% { transform: translateX(0); }
}

.keypad { margin-top: 22px; display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.keypad__key {
  height: 60px; border-radius: var(--r);
  border: 1px solid var(--line-2); background: var(--panel-2);
  font-family: var(--display); font-size: 21px; font-weight: 600; color: var(--text);
  cursor: pointer; transition: background .14s, border-color .14s, transform .08s;
}
.keypad__key:hover { background: var(--blue-soft); border-color: var(--blue-line); }
.keypad__key:active { transform: scale(.96); }
.keypad__key--soft { font-size: 16px; font-weight: 500; color: var(--text-2); }
.keypad__key--soft:hover { color: var(--text); }

.gate__hint { margin-top: 22px; text-align: center; font-size: 12px; color: var(--text-3); }
.gate__error { margin-top: 14px; text-align: center; font-size: 13px; color: var(--bad); min-height: 18px; }


/* ── 8. Pole zrzutu i lista plików ────────────────────────────────────────
   JEDYNE miejsce z gradientem. Pole zrzutu jest celem całego ekranu, więc
   to ono dostaje całą ekspresję systemu; wszystko dokoła zostaje płaskie. */
/* display: block, bo strefa jest teraz <label> — a etykieta jest domyślnie
   elementem liniowym i cały blok rozjechałby się do szerokości tekstu. */
.drop {
  display: block;
  position: relative; margin-top: 18px; padding: 34px 22px;
  border: 1.5px dashed var(--blue-line); border-radius: var(--r);
  background: var(--grad-soft);
  text-align: center; cursor: pointer;
  transition: border-color .16s, background .16s, transform .16s;
}
.drop:hover { border-color: var(--blue); }
/* Skupienie widać na całej strefie, bo skupialne jest pole schowane w środku
   — bez tego użytkownik klawiatury nie wiedziałby, gdzie stoi. */
.drop:focus-within { border-color: var(--blue); box-shadow: 0 0 0 3px var(--blue-soft); }
.drop.is-over { border-color: var(--blue); border-style: solid; transform: scale(1.01); box-shadow: var(--shadow-lift); }
.drop__icon {
  width: 52px; height: 52px; margin: 0 auto 12px; border-radius: 50%;
  display: grid; place-items: center; color: #fff; background: var(--grad);
}
.drop__title { display: block; font-family: var(--display); font-weight: 600; font-size: 15.5px; }
.drop__hint { display: block; margin-top: 5px; font-size: 12.5px; color: var(--text-2); }

/* Pole wyboru pliku jest niewidoczne, ale nadal JEST — nie „display: none".
   Element ukryty w ten sposób wypada z drzewa dostępności i z kolejności
   tabulacji, więc czytnik ekranu nie miał czego ogłosić, a klawiatura nie
   miała na czym stanąć. Zwinięcie do jednego piksela zostawia jedno i drugie,
   a wyglądu nie zmienia. */
.drop input[type="file"] {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; border: 0;
  overflow: hidden; white-space: nowrap;
  clip-path: inset(50%);
}

.files { margin-top: 16px; display: grid; gap: 8px; }
.file {
  display: grid; grid-template-columns: 26px 1fr auto; align-items: center; gap: 11px;
  padding: 10px 12px; border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--panel-2);
}
.file__icon { color: var(--text-3); display: grid; place-items: center; }
/* Nazwa i rozmiar to dwa wiersze, nie jeden ciąg — bez display: block
   spany sklejały się w „plik.zip87,9 KB". */
.file__name { display: block; font-size: 13px; word-break: break-all; }
.file__meta { display: block; margin-top: 2px; font-size: 11.5px; color: var(--text-3); }
.file__side { display: flex; align-items: center; gap: 8px; font-size: 11.5px; color: var(--text-3); }
.file__bar { grid-column: 1 / -1; height: 3px; border-radius: 3px; background: var(--line); overflow: hidden; }
.file__bar i { display: block; height: 100%; width: 0; background: var(--grad); transition: width .2s; }
.file.is-done .file__icon { color: var(--good); }
.file.is-bad  { border-color: rgba(201, 60, 49, .35); }
.file.is-bad .file__icon { color: var(--bad); }
.file__why { color: var(--bad); font-weight: 500; }
.file__x {
  border: none; background: none; color: var(--text-3); cursor: pointer;
  width: 26px; height: 26px; border-radius: var(--r-sm);
}
.file__x:hover { background: var(--blue-soft); color: var(--text); }

.summary {
  margin-top: 16px; display: flex; justify-content: space-between; align-items: center;
  padding: 12px 14px; border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--panel-2);
  font-size: 13px;
}
.summary b { font-family: var(--display); }

.progress { margin-top: 16px; }
.progress__bar { height: 6px; border-radius: 6px; background: var(--line); overflow: hidden; }
.progress__bar i { display: block; height: 100%; width: 0; background: var(--grad); transition: width .25s; }
.progress__text { margin-top: 8px; font-size: 12px; color: var(--text-2); text-align: center; }


/* ── 9. Potwierdzenie ─────────────────────────────────────────────────── */
.ticket {
  margin-top: 20px; padding: 24px; border-radius: var(--r);
  border: 1px solid var(--blue-line); background: var(--blue-soft); text-align: center;
}
.ticket__label { font-size: 11px; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; color: var(--text-3); }
.ticket__code {
  margin-top: 8px; font-family: var(--display); font-weight: 700;
  font-size: clamp(30px, 5vw, 42px); letter-spacing: .16em; color: var(--text);
}
.ticket__note { margin-top: 10px; font-size: 12.5px; color: var(--text-2); }

.deflist { margin-top: 18px; display: grid; gap: 1px; background: var(--line); border: 1px solid var(--line); border-radius: var(--r-sm); overflow: hidden; }
.deflist div { display: flex; justify-content: space-between; gap: 14px; padding: 10px 13px; background: var(--panel-2); font-size: 13px; }
.deflist dt { color: var(--text-2); }
.deflist dd { font-weight: 500; text-align: right; word-break: break-all; }


/* ── 10. Panel zgłoszeń ───────────────────────────────────────────────── */
.shell { /* Panel obsługi to narzędzie pracy, nie tekst do czytania — lista
       zgłoszeń ma dziewięć kolumn i przy 1080 px nie mieściła się na
       ekranie, a karta ucinała to, co wystawało. */
    max-width: 1440px; margin: 0 auto; padding: 30px 22px 60px; }
.shell--narrow { max-width: 520px; padding-top: 90px; }

.topbar {
  border-bottom: 1px solid var(--line); background: var(--panel);
  position: sticky; top: 0; z-index: 20;
}
.topbar__in {
  /* Ta sama szerokość co .shell — inaczej belka rozjeżdża się z treścią. */
    max-width: 1440px; margin: 0 auto; padding: 8px 22px; min-height: 56px;
  display: flex; align-items: center; gap: 8px 16px;
  /* Znak, pięć odnośników i guzik motywu potrzebują 661 px, a telefon daje
     380. Bez zawijania belka rozpychała stronę na całą tę różnicę. Wysokość
     jest tu dolną granicą, a nie liczbą sztywną: przy dwóch liniach belka
     ma urosnąć, nie przyciąć zawartość. */
  flex-wrap: wrap;
}
.topbar__mark { display: flex; align-items: center; gap: 9px; font-family: var(--display); font-weight: 600; letter-spacing: -.02em; }
.topbar__mark i { width: 9px; height: 9px; border-radius: 50%; background: var(--blue); }
.topbar nav { display: flex; flex-wrap: wrap; gap: 4px; margin-left: auto; }
.topbar nav a {
  padding: 7px 11px; border-radius: var(--r-sm); font-size: 13px; color: var(--text-2);
  transition: background .14s, color .14s;
}
.topbar nav a:hover, .topbar nav a[aria-current] { background: var(--blue-soft); color: var(--text); }

/* Nazwa roli jest opisem, nie nawigacją, więc to ona ustępuje pierwsza.
   Znak z rolą, pięć odnośników i guzik motywu potrzebują razem 933 px —
   poniżej tego belka i tak by się zawinęła, a bez roli mieści się w jednej
   linii do jakichś 670 px. Sam znak zostaje, więc dalej wiadomo, w czyim
   narzędziu się jest. */
@media (max-width: 940px) {
    .topbar__role { display: none; }
}

/* Znak bez roli, pięć odnośników i guzik motywu potrzebują 666 px —
   poniżej tego belka zawija się naprawdę. `flex-basis: 100%` oddaje wtedy
   odnośnikom całą drugą linię, przez co guzik motywu zostaje przy znaku
   zamiast lądować sam na trzeciej — a `margin-left: auto` wędruje
   z odnośników na guzik, żeby dalej trzymał się prawej krawędzi. */
@media (max-width: 668px) {
    .topbar__in { padding: 8px 14px; }
    .topbar nav { order: 1; flex-basis: 100%; margin-left: 0; }
    .topbar .theme--inline { margin-left: auto; }

    /* Przyklejona belka ma sens, dopóki jest jedną linią. Zawinięta zajmuje
       na telefonie jedną szóstą ekranu, i to na stałe — w narzędziu, w
       którym patrzy się na tabele. Zjeżdża więc z treścią. */
    .topbar { position: static; }
}

.page-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 18px; flex-wrap: wrap; margin-bottom: 20px; }

.tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 12px; margin-bottom: 20px; }
.tile { padding: 15px 16px; border: 1px solid var(--line); border-radius: var(--r); background: var(--panel); box-shadow: var(--shadow); }
.tile span { font-size: 11px; font-weight: 600; letter-spacing: .07em; text-transform: uppercase; color: var(--text-3); }
.tile b { display: block; margin-top: 5px; font-family: var(--display); font-size: 25px; font-weight: 700; letter-spacing: -.03em; }

.card { border: 1px solid var(--line); border-radius: var(--r); background: var(--panel); box-shadow: var(--shadow); overflow: hidden; }
.card + .card { margin-top: 18px; }
.card__head { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 14px 18px; border-bottom: 1px solid var(--line); background: var(--panel-2); }
.card__body { padding: 18px; }

.table { width: 100%; border-collapse: collapse; }
.table th {
  padding: 12px; font-size: 11px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase;
  color: var(--text-3); text-align: left; white-space: nowrap;
  border-bottom: 1px solid var(--line); background: var(--panel-2);
}
.table td { padding: 14px 12px; border-bottom: 1px solid var(--line); vertical-align: middle; }
.table tr:last-child td { border-bottom: none; }
.table tbody tr { transition: background .14s; }
.table tbody tr:hover { background: var(--blue-soft); }
.table .right { text-align: right; }
.table .nowrap { white-space: nowrap; }

.code-pill {
  display: inline-block; padding: 4px 9px; border-radius: 6px;
  border: 1px solid var(--blue-line); background: var(--blue-soft);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 13px; letter-spacing: .08em;
}
.pill { display: inline-block; padding: 3px 9px; border-radius: 999px; font-size: 11.5px; border: 1px solid var(--line-2); color: var(--text-2); }
/* Obwódka i tło biorą się z tej samej barwy co pismo, więc plakietka zostaje
   jednym kolorem, a nie trójką dobieranych osobno wartości. Przezroczystość
   zamiast gotowego jasnego odcienia — ta sama plakietka stoi na białej karcie
   klienta, na kremowym panelu obsługi i na ciemnej karcie, a tint z domieszką
   tła pasuje do każdej z nich. Modyfikatory `pill--good` i `pill--warn`
   opisują też rzeczy niebędące stanem sprawy („jest"/„brak", „czynne") —
   jadą tą samą zielenią i tym samym bursztynem, bo znaczą to samo. */
.pill--good { border-color: color-mix(in srgb, var(--st-zamkniete) 38%, transparent); color: var(--st-zamkniete); background: color-mix(in srgb, var(--st-zamkniete) 12%, transparent); }
.pill--warn { border-color: color-mix(in srgb, var(--st-zgloszone) 38%, transparent); color: var(--st-zgloszone); background: color-mix(in srgb, var(--st-zgloszone) 12%, transparent); }
.pill--info { border-color: color-mix(in srgb, var(--st-w-trakcie) 38%, transparent); color: var(--st-w-trakcie); background: color-mix(in srgb, var(--st-w-trakcie) 12%, transparent); }

.empty { padding: 52px 20px; text-align: center; color: var(--text-3); }
.empty svg { margin: 0 auto 12px; color: var(--line-2); }

/* Rząd przycisków pod formularzem — z oddechem po obu stronach.
   Bez marginesu przyklejał się do karty nad sobą i pod sobą, a przy dwóch
   kartach jedna pod drugą wyglądał, jakby należał do obu naraz.
   Ten sam rytm 18 px co odstęp nad pojedynczym przyciskiem. */
.actions {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    margin: 18px 0;
}

/* W stopce karty odstęp daje już sama karta — tam margines byłby podwójny. */
.konto__akcje .actions,
.card__body > .actions:last-child { margin-bottom: 0; }

.card--message { padding: 26px; text-align: center; }
.card--message p { margin-top: 10px; }
.card--message .btn { margin-top: 18px; }


/* ── 11. Przełącznik motywu ───────────────────────────────────────────── */
.theme {
  position: absolute; top: 18px; right: 18px; z-index: 5;
  width: 34px; height: 34px; display: grid; place-items: center;
  border: 1px solid var(--line-2); border-radius: 50%; background: var(--panel-2);
  /* Tło jest w przejściu, choć sam `.theme` go nie zmienia: robi to
     `.brandnav .theme:hover` na ekranach klienta. Bez tej pozycji krążek
     przeskakiwał na kolor natychmiast, podczas gdy odnośniki tuż obok
     (`.brandnav a`) przechodziły płynnie tą samą wartością .14s. */
  color: var(--text-2); cursor: pointer; transition: background .14s, color .14s, border-color .14s;
}
.theme:hover { color: var(--text); border-color: var(--text-3); }
.theme--inline { position: static; }
[data-theme="dark"] .theme .theme__sun,
:root:not([data-theme="dark"]) .theme .theme__moon { display: none; }


/* ── 12. Ruch, dostępność, wersja mobilna ─────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .001ms !important; transition-duration: .001ms !important; }
}

@media (max-width: 900px) {
  .split { grid-template-columns: 1fr; }
  /* Zdjęcie schodzi do pasa nad treścią — dalej mówi, u kogo jesteśmy,
     ale nie zjada ekranu telefonu. Cytat i liczby znikają: na 180 px
     wysokości i tak nie mają gdzie stanąć. */
  .visual { min-height: 184px; padding: 22px; }
  .visual__claim, .visual__meta { display: none; }
  .side { padding: 30px 20px 50px; align-content: start; }
  .side__box, .side__box--wide { max-width: 520px; margin: 0 auto; }
}
@media (max-width: 560px) {
  .shell { padding: 20px 14px 50px; }
  .table th:nth-child(3), .table td:nth-child(3) { display: none; }
}


/* ── 13. Znaki składane z napisu ──────────────────────────────────────────
   Nie każda marka ma logotyp w pliku. Bramka pokazuje znak ewitryny (do
   wpisania PIN-u nie wiadomo, czyj to gość), a Szczep-Pol nie ma logotypu
   w ogóle — jego znak jest na stronie złożony z tekstu. Obrazek SVG by tu
   nie pomógł: kroje pisma nie ładują się do pliku wstawionego przez <img>,
   więc napis wyszedłby domyślnym systemowym fontem. Składamy go więc tak
   samo jak oryginał, z kroju, który strona i tak już wczytała.            */
.wordmark {
  font-family: var(--display); font-weight: 700;
  font-size: 27px; letter-spacing: -.04em; color: #fff; white-space: nowrap;
}

.wordmark--ewi .dot {
  color: #1583ff;
  text-shadow: 0 0 22px rgba(21, 131, 255, .95), 0 0 52px rgba(21, 131, 255, .5);
}

/* Znak składany z napisu stoi tam, gdzie normalnie jest logotyp z pliku —
   ten sam cień co pod obrazkiem, żeby litery nie odklejały się od poświaty.
   Kropka zachowuje swój błękitny blask, bo `.wordmark--ewi .dot` nadpisuje
   text-shadow na sobie. */
.visual__logo .wordmark { font-size: 29px; text-shadow: 0 2px 10px rgba(0, 0, 0, .45); }

/* Szczep-Pol: trzy kwadraty i napis o zmiennej grubości w dwóch barwach —
   dokładnie jak w nagłówku szczeppol.ewitryna.one. */
.wordmark--szczeppol { display: inline-flex; align-items: center; gap: 13px; letter-spacing: 0; }
.wordmark__sq { display: flex; gap: 3px; }
.wordmark__sq i { display: block; width: 13px; height: 13px; }
.wordmark__sq i:nth-child(1) { background: #3b6db4; }
.wordmark__sq i:nth-child(2) { background: #2e7de0; }
.wordmark__sq i:nth-child(3) { background: #aab4c2; }
.wordmark__txt b { font-weight: 300; color: #fff; }
.wordmark__txt b.a { color: #4d8fdd; }
.wordmark__txt b.bold { font-weight: 700; }

/* Na ekranie klienta znak stoi na środku i jest o włos większy. */
.brandpage .wordmark { font-size: 30px; }


/* ── 14. Ekran klienta ────────────────────────────────────────────────────
   Panel po wpisaniu kodu PIN. Bramka jest wspólna dla wszystkich i tam sens
   miał podział na kolumnę ze zdjęciem i kolumnę z treścią — tutaj gość jest
   już rozpoznany, a ekran ma jedno zadanie: przyjąć pliki. Dlatego obok nie
   ma nic: płaszczyzna w kolorze firmy, znak u góry, karta na środku.

   Wszystkie barwy schodzą z dwóch zmiennych ustawianych przez `<body style>`
   na podstawie wpisu firmy (`--blue` = akcent, `--blue-ink` = ciemny kolor
   marki), więc kolejny klient nie wymaga ani jednej nowej reguły.

   Karta ma własne wartości płaszczyzn i pisma, niezależne od palety
   APLIKACJI: bierze je z barw marki, więc kolejny klient nie wymaga ani
   jednej nowej reguły. Nie znaczy to jednak, że ekran wygląda tak samo
   u każdego — jasny czy ciemny wybiera ten, kto patrzy. Stało tu zdanie
   odwrotne („ma wyglądać identycznie u każdego") i było prawdziwe dokładnie
   do chwili, w której powstał ciemny wariant tego ekranu (niżej w tym pliku,
   z osobno przeliczoną paletą). Dziś przeczyłoby dwóm rzeczom naraz:
   przełącznikowi motywu, który stoi w belce tego samego ekranu, oraz
   layout.php, który przy pustej pamięci przeglądarki bierze motyw
   z ustawienia systemu.

   Rozważaliśmy odwrotne wyjście — wyłączyć domyślkę systemową dla ekranów
   klienta i zostawić je zawsze jasne. Odpada z dwóch powodów: przełącznik
   w belce zostałby guzikiem, który raz działa, a raz nie, a kierownik
   oddziału z telefonem ustawionym na ciemno dostałby w wieczornej zmianie
   białą kartę prosto w oczy. Barwy marki niesie tu odcień, nie jasność —
   ciemny wariant jest zieloną kartą tak samo jak jasny.                    */
.brandpage {
  --display: "Montserrat", "Poppins", system-ui, sans-serif;
  --panel: #ffffff;
  --panel-2: #f5f9f6;
  --line: #e4ece7;
  --line-2: #d0ded5;
  --text: #12241d;
  --text-2: #4c5f56;
  --text-3: #7d8d85;
  --shadow: 0 1px 2px rgba(6, 32, 26, .06);
  --shadow-lift: 0 18px 46px rgba(6, 32, 26, .3);

  /* Jedna szerokość dla wszystkich kart na tym ekranie. Wcześniej karta
     zgłoszenia i karta rozmowy miały ją wpisaną osobno, przy równej wadze
     selektorów — i rozjeżdżały się o sto pikseli. */
  --card-w: 620px;

  position: relative; overflow: hidden;
  min-height: 100vh;
  display: grid; align-content: center; justify-items: center; gap: 24px;
  padding: 46px 20px 38px;
  color: #fff;
  background-color: var(--blue-ink);
  background-image:
    radial-gradient(120% 82% at 50% -12%, color-mix(in srgb, var(--blue) 42%, transparent) 0%, transparent 62%),
    linear-gradient(168deg,
      color-mix(in srgb, var(--blue-ink) 86%, white) 0%,
      var(--blue-ink) 46%,
      color-mix(in srgb, var(--blue-ink) 74%, black) 100%);
}

/* Poświata w kolorze akcentu — ta sama rola co na bramce: ma być czuć,
   że płaszczyzna żyje, i nie umieć wskazać, skąd to światło idzie. */
.brandpage__glow {
  position: absolute; z-index: 0; pointer-events: none;
  width: 78vw; max-width: 900px; aspect-ratio: 1;
  left: 50%; top: -46%; transform: translateX(-50%);
  border-radius: 50%; filter: blur(70px); opacity: .5;
  background: radial-gradient(circle, var(--blue) 0%, transparent 66%);
}
.brandpage > *:not(.brandpage__glow) { position: relative; z-index: 1; }

.brandpage__head {
  text-align: center;
  /* Pełna szerokość kolumny siatki — i to NIE jest ozdobnik, tylko warunek
     poprawnego rozmiaru znaku. `.brandpage` to grid z `justify-items: center`,
     więc bez tej linii nagłówek jest szeroki dokładnie na tyle, ile jego
     najszersza treść, czyli zwykle napis pod znakiem. A ponieważ reset wyżej
     nadaje `img, svg { max-width: 100% }`, obrazek nie rozpycha rodzica, tylko
     kurczy się do jego szerokości — o wielkości logo decydowała długość
     podpisu. Ten sam znak miał przez to 300 px na ekranie oddziału („Panel
     przesyłania zgłoszeń") i 157 px na przeglądzie zarządu („Przegląd
     zgłoszeń"). Nie da się tego naprawić sztywną szerokością na samym znaku,
     bo marki mają różne proporcje (patrz komentarz przy `.brandpage__logo`).
     Napisy stoją na środku, więc rozciągnięcie nagłówka niczego nie przesuwa,
     a przy okazji odcina wpływ każdej kolejnej pozycji w belce na znak. */
  width: 100%;
}
/* Znaki klientów mają bardzo różne proporcje: Naturhouse jest paskiem
   8:1, Hammermed prawie kwadratem. Sztywna wysokość robiła z jednego
   olbrzyma, a z drugiego znaczek. Ograniczamy więc obie osie — szeroki
   znak zatrzyma szerokość, wysoki zatrzyma wysokość. */
.brandpage__logo {
  height: auto; width: auto;
  max-height: 62px; max-width: 300px;
  margin: 0 auto;
  filter: drop-shadow(0 3px 14px rgba(0, 0, 0, .35));
}
.brandpage__kicker {
  margin-top: 14px; font-size: 11.5px; font-weight: 500;
  letter-spacing: .16em; text-transform: uppercase; color: rgba(255, 255, 255, .72);
}

.brandcard {
  width: 100%; max-width: var(--card-w);
  padding: 30px 30px 32px; border-radius: 18px;
  background: var(--panel); color: var(--text); box-shadow: var(--shadow-lift);
}
.brandcard h1 { font-size: 28px; }
.brandcard .lead { color: var(--text-2); }
.brandcard .step + h1 { margin-top: 10px; }

.brandpage__meta {
  display: flex; gap: 32px; flex-wrap: wrap; justify-content: center; text-align: center;
  font-size: 11.5px; color: rgba(255, 255, 255, .62);
}
.brandpage__meta b {
  display: block; font-family: var(--display); font-weight: 700; font-size: 18px;
  color: #fff; letter-spacing: -.02em;
}

.brandpage__foot { font-size: 12.5px; color: rgba(255, 255, 255, .62); text-align: center; }
.brandpage__foot a { color: #fff; text-decoration: underline; text-underline-offset: 3px; margin-left: 7px; }

@media (max-width: 560px) {
  .brandpage { padding: 32px 14px 30px; gap: 20px; }
  .brandcard { padding: 22px 18px 24px; border-radius: 14px; }
  .brandcard h1 { font-size: 24px; }
  .brandpage__meta { gap: 20px; }
}

/* Tło strony klienta sięga poza samą stronę: przy odbiciu przewijania
   (rubber-band na macOS) spod zielonej płaszczyzny wychodziło kremowe tło
   panelu. Kolor bierze się z tej samej zmiennej co gradient wyżej. */
body.on-brand { background: var(--blue-ink); }


/* ── Ciemny wariant ekranu klienta ────────────────────────────────────────
   Blok wyżej przedefiniowuje `--panel`, `--text` i resztę palety na własne,
   jasne wartości. Zmienne dziedziczą się w dół, a deklaracja na bliższym
   przodku bije tę odziedziczoną — `[data-theme="dark"]` siada na <html>,
   `.brandpage` na <main>, więc ciemny motyw nie miał jak wejść do karty.
   Przełącznik przestawiał atrybut i nie zmieniał ani jednego piksela, za to
   `color-scheme: dark` przechodził w dół bez przeszkód i przeglądarka malowała
   niezaznaczone pola wyboru i ikonę kalendarza tak, jakby stały na ciemnym —
   na białej karcie znikały. Stąd ten blok: musi mieć tę samą postać co blok
   jasny (przesłonięcie zmiennych), tylko wyżej w specyficzności.

   Barwy nie są wpisane na sztywno. Powstają z `--blue-ink` — ciemnego koloru
   marki, który `<body style>` bierze z wpisu firmy — domieszanego czernią.
   Dzięki temu ciemny wariant zostaje w barwach klienta (zielony ekran ma być
   ciemniejszy, a nie szary), a kolejna marka nie wymaga ani jednej nowej
   reguły, dokładnie jak w wariancie jasnym.                                */
[data-theme="dark"] .brandpage {
  /* Karta jaśniejsza od płaszczyzny, pola formularza ciemniejsze od karty —
     ta sama hierarchia głębi co w jasnym, tylko odbita. */
  --panel: color-mix(in srgb, var(--blue-ink) 78%, black);
  --panel-2: color-mix(in srgb, var(--blue-ink) 58%, black);
  --line: rgba(255, 255, 255, .10);
  --line-2: rgba(255, 255, 255, .18);
  --text: #e9f3ef;
  --text-2: #a9c4bb;
  --text-3: #8caea4;
  /* Jedyna barwa semantyczna, która wymaga korekty. `--good` i `--warn`
     z motywu ciemnego dają na tej karcie ponad 5:1, ale `--bad` (#ef6f5e)
     tylko 4,0:1 — poniżej progu dla drobnego pisma. Jaśniejszy odcień
     wraca powyżej 5:1. */
  --bad: #ff9182;
  --shadow: 0 1px 2px rgba(0, 0, 0, .5);
  --shadow-lift: 0 18px 46px rgba(0, 0, 0, .6);

  /* `color-scheme` celowo zostaje odziedziczone z <html>: skoro karta jest
     teraz ciemna, `dark` jest tu wreszcie prawdą i kontrolki systemowe
     wyglądają tak, jak powinny. */

  background-color: color-mix(in srgb, var(--blue-ink) 42%, black);
  background-image:
    radial-gradient(120% 82% at 50% -12%, color-mix(in srgb, var(--blue) 24%, transparent) 0%, transparent 62%),
    linear-gradient(168deg,
      color-mix(in srgb, var(--blue-ink) 55%, black) 0%,
      color-mix(in srgb, var(--blue-ink) 42%, black) 46%,
      color-mix(in srgb, var(--blue-ink) 28%, black) 100%);
}

/* Poświata w jasnym wariancie ożywia płaszczyznę; przy tej samej mocy na
   ciemnym robi się z niej jasna plama tuż nad kartą. */
[data-theme="dark"] .brandpage__glow { opacity: .28; }

/* Odbicie przewijania (rubber-band) musi pokazać ten sam przygaszony odcień
   co płaszczyzna — inaczej spod niej wyjrzy pełna zieleń z reguły wyżej. */
[data-theme="dark"] body.on-brand { background: color-mix(in srgb, var(--blue-ink) 42%, black); }

/* W jasnym wariancie najechanie przyciemnia przycisk do ciemnej barwy marki.
   Na ciemnej karcie ta sama barwa niemal zlewa się z tłem, więc kierunek
   trzeba odwrócić: najechanie rozjaśnia. */
[data-theme="dark"] .brandpage .btn--primary:not(:disabled):hover {
  background: color-mix(in srgb, var(--blue) 82%, white);
}

/* ── 15. Rozmowa przy zgłoszeniu ──────────────────────────────────────────
   Ten sam blok stoi po obu stronach: w panelu obsługi i u klienta. Różnią
   je tylko barwy dymków — wiadomości własnej strony są w akcencie, cudze
   płaskie. Świadomie NIE jest to komunikator: wiadomości idą od najstarszej
   do najnowszej i cała rozmowa jest widoczna naraz, bo to zapis ustaleń
   do sprawy, a nie czat.                                                   */
.talk { display: grid; gap: 12px; margin-bottom: 22px; }

.msg {
  padding: 12px 14px; border-radius: var(--r);
  border: 1px solid var(--line); background: var(--panel-2);
}
.msg--mine { border-color: var(--blue-line); background: var(--blue-soft); }
.msg__head { display: flex; align-items: baseline; gap: 10px; margin-bottom: 6px; }
.msg__head b { font-size: 13px; }
.msg__text { font-size: 13.5px; line-height: 1.6; word-break: break-word; }

.msg__files { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 11px; }
.msg__file {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 5px 10px; border-radius: 999px;
  border: 1px solid var(--line-2); background: var(--panel);
  font-size: 12px; max-width: 100%;
}
.msg__file:hover { border-color: var(--blue); }
.msg__file span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 210px; }
.msg__file em { font-style: normal; color: var(--text-3); font-size: 11px; }

.reply { padding-top: 4px; }
.reply__bar { display: flex; align-items: center; gap: 10px; margin-top: 10px; flex-wrap: wrap; }


/* ── 16. Ekrany klienta poza wgrywaniem ───────────────────────────────── */
.brandnav { display: flex; align-items: center; justify-content: center; gap: 4px; margin-top: 16px; flex-wrap: wrap; }
.brandnav a {
  padding: 6px 12px; border-radius: 999px; font-size: 12.5px;
  color: rgba(255, 255, 255, .72); border: 1px solid transparent;
  transition: background .14s, color .14s, border-color .14s;
}
.brandnav a:hover { color: #fff; background: rgba(255, 255, 255, .1); }
.brandnav a[aria-current] { color: #fff; border-color: rgba(255, 255, 255, .35); background: rgba(255, 255, 255, .12); }

/* Przełącznik motywu stoi w tej samej linii co odnośniki, więc musi mówić
   ich językiem. Sam `.theme` bierze barwy ze zmiennych, a `.brandpage`
   przestawia je na barwy karty — bez tej reguły guzik byłby jasnym krążkiem
   na barwnej płaszczyźnie, cięższym w nagłówku od samego znaku marki, i do
   tego wyglądałby identycznie w obu motywach, które przełącza. Tu zostaje
   sama obwódka i biel, dokładnie jak przy pozycji bieżącej wyżej.
   33 px zamiast domyślnych 34 zrównuje go z wysokością pigułek obok. */
.brandnav .theme {
  width: 33px; height: 33px;
  border-color: rgba(255, 255, 255, .35);
  background: transparent;
  color: rgba(255, 255, 255, .72);
}
.brandnav .theme:hover {
  border-color: rgba(255, 255, 255, .55);
  background: rgba(255, 255, 255, .1);
  color: #fff;
}

/* Ekrany z rozmową są szersze — wiadomości i lista plików potrzebują miejsca. */
.brandpage--wide { --card-w: 720px; }

/* Karta na zielonym musi sama ustawić kolor pisma. `.brandpage` maluje
   swoje dzieci na biało (napisy stoją na barwnej płaszczyźnie), a karta
   jest jasna — bez tej linii tekst rozmowy był biały na białym. */
.brandpage .card {
  width: 100%; max-width: var(--card-w);
  color: var(--text);
  border: none; border-radius: 18px; box-shadow: var(--shadow-lift);
}
.brandpage .card__head { background: var(--panel-2); }

.mylist { display: grid; gap: 8px; margin-top: 18px; }
.myrow {
  display: flex; align-items: center; gap: 13px;
  padding: 12px 14px; border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--panel-2); transition: border-color .14s, background .14s;
}
.myrow:hover { border-color: var(--blue-line); background: var(--blue-soft); }
.myrow__main { flex: 1; min-width: 0; display: grid; gap: 3px; }
.myrow__title { font-size: 13.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.myrow__side { flex-shrink: 0; }


/* ── 17. Kody PIN w panelu ────────────────────────────────────────────── */
.pinform { display: grid; grid-template-columns: 150px 1fr 1fr auto; gap: 12px; align-items: end; }
.pinform .btn { height: 40px; }
@media (max-width: 720px) { .pinform { grid-template-columns: 1fr; } }

/* Próbka barw szablonu — od razu widać, w co wpadnie klient po wpisaniu kodu. */
.swatch {
  display: inline-block; width: 26px; height: 13px; border-radius: 3px;
  margin-right: 8px; vertical-align: -1px;
  background: linear-gradient(105deg, var(--i) 0 52%, var(--a) 52% 100%);
  border: 1px solid var(--line-2);
}


/* ── 18. Stan sprawy ──────────────────────────────────────────────────────
   Trzy pozycje zawsze widoczne obok siebie, bieżąca wyróżniona. Nie lista
   rozwijana: status zmienia się często i ma być jednym kliknięciem, a nie
   dwoma plus czytaniem, co jest w środku. Widać przy okazji, co jeszcze
   może się z tą sprawą stać — czego lista rozwijana nie pokazuje.         */
.statusbar {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-bottom: 18px; padding: 10px 12px;
  border: 1px solid var(--line); border-radius: var(--r);
  background: var(--panel); box-shadow: var(--shadow);
}
.statusbar__label {
  font-size: 11px; font-weight: 600; letter-spacing: .07em;
  text-transform: uppercase; color: var(--text-3); margin-right: 4px;
}
.statusbar__hint { margin-left: auto; }

.statusbtn {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    height: 30px;
    padding: 0 13px;
    border-radius: 999px;
    cursor: pointer;
    border: 1px solid var(--line-2);
    background: var(--panel-2);
    color: var(--text-2);
    font-size: 12.5px;
    font-weight: 500;
    transition: border-color .14s, background .14s, color .14s;
}

/* Znak stanu w barwie statusu — ten sam zestaw ○ ◐ ● co w tablicy pracy
   i u kierownictwa. Dzięki temu „zamknięte" wygląda tak samo wszędzie,
   a nie zielono w jednym miejscu i niebiesko w drugim. */
.statusbtn__znak { color: var(--status); line-height: 1; font-size: 13px; }

.statusbtn:hover { border-color: var(--status); color: var(--text); }

.statusbtn.is-on {
    border-color: var(--status);
    background: color-mix(in srgb, var(--status) 12%, var(--panel));
    color: var(--text);
    font-weight: 600;
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--status) 26%, transparent);
}

.statusbtn.is-on .statusbtn__znak { color: var(--status); }


/* Zamknięcie sprawy jest nieodwracalne w praktyce (klient dostaje sygnał,
   że skończone), więc przycisk stoi osobno i wygląda inaczej niż reszta. */
.btn--close { border-color: var(--good); color: var(--good); background: var(--panel); }
.btn--close:not(:disabled):hover { background: rgba(20, 128, 74, .09); }

/* Sprawa zamknięta — w miejscu, gdzie normalnie stoi pole odpowiedzi.
   Komunikat zajmuje dokładnie to miejsce, żeby od razu było wiadomo,
   czego brakuje i dlaczego. */
.locked {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 13px 15px; border-radius: var(--r);
  border: 1px solid var(--line-2); background: var(--panel-2);
}
.locked__icon { color: var(--text-3); flex-shrink: 0; margin-top: 1px; }
.locked b { font-size: 13.5px; }
.locked p { margin-top: 3px; max-width: 52ch; }
.locked form { flex-shrink: 0; }

/* Rola narzędzia obok znaku w belce panelu — znak niesie markę, to słowo
   mówi, czym w tej marce jest ten konkretny ekran. */
.topbar__role {
  font-size: 11px; font-weight: 500; letter-spacing: .08em;
  text-transform: uppercase; color: var(--text-3);
}
.topbar__mark { gap: 10px; }
.topbar__mark .wordmark { font-size: 17px; color: var(--text); }
/* Poświata kropki jest projektowana pod ciemne zdjęcie na bramce. Na jasnej
   belce panelu nie świeci, tylko rozmazuje — więc tu jej nie ma. */
.topbar__mark .dot { text-shadow: none; }


/* ── 19. Kolor zgłoszenia (priorytet obsługi) ─────────────────────────────
   Kółko w pierwszej kolumnie listy. Prywatna notatka obsługi — nie pokazuje
   się nigdzie poza panelem, w szczególności nie u klienta.

   Wybór barwy siedzi w <details>, czyli w mechanizmie samej przeglądarki:
   działa bez JavaScriptu, obsługuje klawiaturę i zamyka się sam. Trzy barwy
   plus brak — więcej nie da się rozróżnić rzutem oka, a o to tu chodzi.    */
.marker { position: relative; }
.marker summary {
  list-style: none; cursor: pointer;
  width: 26px; height: 26px; display: grid; place-items: center;
  border-radius: 50%; transition: background .14s;
}
.marker summary::-webkit-details-marker { display: none; }
.marker summary:hover { background: var(--blue-soft); }

.marker__dot {
  width: 13px; height: 13px; border-radius: 50%;
  background: var(--m, transparent);
  border: 1.5px solid var(--m, var(--line-2));
  transition: background .14s, border-color .14s;
}

.marker__menu {
  position: absolute; z-index: 30; top: 30px; left: 0;
  display: flex; align-items: center; gap: 6px;
  padding: 7px 8px; border-radius: var(--r-sm);
  border: 1px solid var(--line-2); background: var(--panel);
  box-shadow: var(--shadow-lift);
}
.marker__opt {
  width: 22px; height: 22px; padding: 0; cursor: pointer;
  border: none; background: none; border-radius: 50%;
  display: grid; place-items: center;
}
.marker__opt span {
  width: 15px; height: 15px; border-radius: 50%;
  background: var(--m); border: 1.5px solid var(--m);
}
.marker__opt:hover { background: var(--panel-2); }
.marker__opt.is-on span { box-shadow: 0 0 0 2px var(--panel), 0 0 0 3.5px var(--m); }
.marker__clear {
  border: none; background: none; cursor: pointer; padding: 0 4px;
  font-size: 11.5px; color: var(--text-3); white-space: nowrap;
}
.marker__clear:hover { color: var(--text); }

/* Zamknięta sprawa przygasa — dalej jest na liście i dalej się w nią wchodzi,
   ale nie zabiera uwagi tym, co jeszcze czeka na zrobienie. */
.table tbody tr.is-closed { opacity: .4; }
.table tbody tr.is-closed:hover { opacity: 1; }

/* ── Pole kodu dostępu ─────────────────────────────────────────────────────
   Osiem znaków wpisywanych z kartki albo dyktowanych przez telefon. Szeroka
   litera i rozstrzelenie znaków, żeby dało się je policzyć wzrokiem.        */
.field--code {
    font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
    font-size: 26px;
    font-weight: 600;
    letter-spacing: .28em;
    text-align: center;
    text-transform: uppercase;
    padding-left: .28em;
}

.field--code.is-bad {
    border-color: var(--bad, #e0242c);
    animation: code-shake .36s;
}

@keyframes code-shake {
    0%, 100% { transform: translateX(0); }
    25%      { transform: translateX(-6px); }
    75%      { transform: translateX(6px); }
}

/* ── Ustawienia poczty ─────────────────────────────────────────────────────
   Cztery nowe drobiazgi na jeden ekran: dwie kolumny na pary pól, wiersz
   z przełącznikiem, zapis rozmowy z serwerem i ostrzeżenie w innym kolorze
   niż błąd — bo „działa, ale zwróć uwagę" to nie to samo co „nie działa".  */
.grid2 {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0 18px;
}

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

.checkrow {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 9px 0;
    cursor: pointer;
    line-height: 1.45;
}

.checkrow input {
    margin-top: 3px;
    width: 17px;
    height: 17px;
    accent-color: var(--blue);
    flex: none;
}

.alert--warn {
    background: rgba(214, 146, 12, .12);
    border-color: rgba(214, 146, 12, .38);
    color: var(--text);
}

.log {
    margin: 0;
    padding: 14px 16px;
    background: var(--sunk, rgba(127, 127, 127, .08));
    border: 1px solid var(--line);
    border-radius: 10px;
    font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
    font-size: 12.5px;
    line-height: 1.65;
    white-space: pre-wrap;
    word-break: break-word;
    overflow-x: auto;
}

/* Edycja adresu wprost w wierszu tabeli — pole i przycisk w jednej linii. */
.inline-edit {
    display: flex;
    gap: 6px;
    align-items: center;
}

.field--sm {
    padding: 6px 9px;
    font-size: 13px;
    min-width: 170px;
}

/* ── Formularz edycji w komórce tabeli ─────────────────────────────────────
   W tabeli kont takie formularze są w jednym wierszu cztery: rodzaj konta,
   placówka, opis roboczy i nowy kod. Każdy z nich to pole o dolnej granicy
   170 px plus przycisk obok, czyli 260 px, których kolumna nie ma jak
   oddać — sama ta czwórka wypychała tabelę o 370 px poza ekran 1280 px.
   Przycisk schodzi więc pod pole, a dolna granica pola jest w tabeli
   niższa: kolumnę ma dyktować jej zawartość, nie okrągła liczba z reguły
   pisanej pod formularz na całą szerokość karty.                            */
/* Pole i „Zapisz" w jednej linii. Zawijanie zrzucało przycisk pod pole,
   przez co każdy wiersz tabeli kont puchł do trzech linijek, a kolumny
   przestawały się ze sobą zgadzać w pionie. Pole oddaje szerokość,
   przycisk bierze tyle, ile potrzebuje. */
.table .inline-edit {
    flex-wrap: nowrap;
    align-items: center;
}

.table .inline-edit .field {
    min-width: 0;
    flex: 1 1 auto;
}

.table .inline-edit .btn {
    flex: 0 0 auto;
    white-space: nowrap;
}
.table .field--sm { min-width: 110px; }

/* Dopisek w nawiasie schodzi do drugiej linii nagłówka. Nagłówki tabeli są
   jednolinijkowe (`white-space: nowrap`), więc razem z dopiskiem ten jeden
   dyktował kolumnie o siedemdziesiąt pikseli więcej, niż potrzebowała jej
   zawartość. */
.table th .tiny { display: block; }

/* ── Okładka i miniatury ───────────────────────────────────────────────────
   Zgłoszenie z ośmioma zdjęciami wyglądało na liście tak samo jak zgłoszenie
   z ośmioma plikami tekstowymi. Okładka rozstrzyga to jednym spojrzeniem,
   a numer schodzi do małej plakietki — nadal jest, ale nie zabiera uwagi
   nazwie sprawy.                                                            */
.myrow__cover,
.subj__cover {
    width: 84px;
    height: 84px;
    flex: none;
    border-radius: 9px;
    object-fit: cover;
    background: var(--blue-soft);
    border: 1px solid var(--line);
}

.subj__cover { width: 72px; height: 72px; }

.myrow__cover--none,
.subj__cover--none {
    display: block;
    background:
        linear-gradient(135deg, transparent 46%, var(--line) 46%, var(--line) 54%, transparent 54%),
        var(--blue-soft);
}

.subj {
    display: flex;
    align-items: center;
    gap: 11px;
    text-decoration: none;
    color: inherit;
    min-width: 220px;
}

.subj__text { display: flex; flex-direction: column; gap: 4px; min-width: 0; }

.subj__title {
    font-weight: 600;
    line-height: 1.35;
    overflow-wrap: anywhere;
}

.subj:hover .subj__title { color: var(--blue); }

.code-pill--sm {
    font-size: 11px;
    padding: 1px 6px;
    letter-spacing: .06em;
    opacity: .75;
    align-self: flex-start;
}

/* Wiersz pliku to siatka ze sztywną pierwszą kolumną, dobraną pod małą
   ikonę dokumentu. Miniatura jest od niej znacznie szersza, więc wiersz,
   który ją niesie, dostaje własną szerokość pierwszej kolumny — inaczej
   zdjęcie zostaje ściśnięte do pionowego paska. */
.file--img { grid-template-columns: 64px 1fr auto; }

.file__thumb {
    width: 64px;
    height: 64px;
    flex: none;
    border-radius: 9px;
    object-fit: cover;
    border: 1px solid var(--line);
    background: var(--blue-soft);
}


/* ── Tabele szersze niż ekran ──────────────────────────────────────────────
   Karta ma `overflow: hidden`, żeby jej zaokrąglone rogi przycinały zawartość.
   Skutek uboczny: tabela szersza od karty była po prostu ucinana i nie dało
   się dojechać do ostatnich kolumn. Własny kontener przywraca przewijanie,
   nie odbierając karcie rogów.                                              */
.table-scroll {
    overflow-x: auto;
    overscroll-behavior-x: contain;
    -webkit-overflow-scrolling: touch;
}

/* Bez dolnej granicy kolumny zgniatałyby się do nieczytelnej szerokości
   zamiast uruchomić przewijanie. */
.table-scroll > .table { min-width: 900px; }

/* Pasek przewijania widoczny także na macOS, gdzie system chowa go do czasu
   ruchu — inaczej nic nie podpowiada, że dalej coś jest. */
.table-scroll::-webkit-scrollbar { height: 10px; }

.table-scroll::-webkit-scrollbar-thumb {
    background: var(--line);
    border-radius: 6px;
}

.table-scroll::-webkit-scrollbar-thumb:hover { background: var(--text-3); }

/* ── Odnośniki i miniatury w rozmowie ──────────────────────────────────────
   Adres wklejony w wiadomość ma być klikalny — inaczej odbiorca musi go
   zaznaczać i kopiować ręcznie, a przy długim linku do dysku łatwo urwać
   końcówkę. Bezpieczeństwo tej zamiany stoi po stronie PHP (View::text):
   treść jest najpierw w całości zamieniana na encje, a dopiero potem
   doklejany jest znacznik <a>.                                             */
.msg__link {
    color: var(--blue);
    text-decoration: underline;
    text-underline-offset: 2px;
    word-break: break-all;
}

.msg__link:hover { text-decoration-thickness: 2px; }

/* Załącznik będący zdjęciem pokazuje siebie, nie ikonę kartki. Pigułka
   rośnie i traci owalny kształt — przy 44 px obrazka wyglądałby dziwnie. */
.msg__file--img {
    padding: 6px 12px 6px 6px;
    border-radius: 12px;
}

.msg__thumb {
    width: 44px;
    height: 44px;
    flex: none;
    border-radius: 8px;
    object-fit: cover;
    border: 1px solid var(--line);
    background: var(--blue-soft);
}

/* ── Przejście między stronami listy ───────────────────────────────────── */
.pager {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
    padding: 14px 18px;
    border-top: 1px solid var(--line);
    flex-wrap: wrap;
}

.pager__stan { color: var(--text-2); font-size: 13.5px; }

.pager .is-off { opacity: .38; cursor: default; }

/* ── Oświadczenie o prawach do materiałów ──────────────────────────────────
   Przy formularzu wysyłki — wyróżnione ramką, bo to jedyne pole, którego
   zaznaczenie niesie skutek prawny, a nie tylko porządkowy.                */
.checkrow--oswiadczenie {
    margin-top: 18px;
    padding: 13px 15px;
    border: 1px solid var(--line);
    border-radius: var(--r-sm);
    background: var(--panel-2);
    font-size: 13px;
    color: var(--text-2);
}

/* W panelu obsługi — zapis tego, pod czym składający się podpisał. */
.oswiadczenie {
    margin-top: 16px;
    padding: 13px 15px;
    border-left: 3px solid var(--blue-line);
    background: var(--panel-2);
    border-radius: 0 var(--r-sm) var(--r-sm) 0;
}

.oswiadczenie p {
    margin: 6px 0;
    font-size: 13px;
    line-height: 1.55;
    color: var(--text-2);
}

/* ── Pola zgłoszenia w panelu i u klienta ─────────────────────────────── */
.szczegoly {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 6px 18px;
    margin: 16px 0 0;
    padding: 13px 15px;
    background: var(--panel-2);
    border-radius: var(--r-sm);
    font-size: 13.5px;
}

.szczegoly dt { color: var(--text-3); }
.szczegoly dd { margin: 0; font-weight: 500; }

@media (max-width: 520px) {
    .szczegoly { grid-template-columns: 1fr; gap: 2px; }
    .szczegoly dd { margin-bottom: 8px; }
}

/* ── Wybór formatów — zwijane grupy ────────────────────────────────────────
   Trzydzieści cztery pozycje nie mieszczą się na ekranie i nie powinny.
   Grupy zwinięte znacznikiem <details> działają bez skryptu, a otwiera się
   tylko tę, która akurat jest potrzebna.                                   */
.formaty {
    display: grid;
    gap: 6px;
    margin-top: 8px;
}

.formaty__grupa {
    border: 1px solid var(--line);
    border-radius: var(--r-sm);
    background: var(--panel-2);
    overflow: hidden;
}

.formaty__grupa summary {
    padding: 11px 14px;
    cursor: pointer;
    font-weight: 600;
    font-size: 13.5px;
    list-style: none;
    display: flex;
    align-items: center;
    gap: 8px;
}

/* Własna strzałka zamiast systemowego trójkąta — ten wygląda inaczej
   w każdej przeglądarce i psuje wyrównanie. */
.formaty__grupa summary::-webkit-details-marker { display: none; }

.formaty__grupa summary::before {
    content: "";
    width: 7px;
    height: 7px;
    flex: none;
    border-right: 2px solid var(--text-3);
    border-bottom: 2px solid var(--text-3);
    transform: rotate(-45deg);
    transition: transform .15s;
    margin-left: 2px;
}

.formaty__grupa[open] summary::before { transform: rotate(45deg); }

.formaty__grupa[open] summary { border-bottom: 1px solid var(--line); }

.formaty__licznik {
    margin-left: auto;
    font-weight: 600;
    font-size: 12px;
    color: var(--blue);
    background: var(--blue-soft);
    border-radius: 999px;
    padding: 1px 9px;
}

/* ── Kafelki formatów — dwie kolumny z miniaturą ───────────────────────────
   `auto-fill` z `minmax`, a nie sztywne `1fr 1fr`: liczba kolumn ma wynikać
   z miejsca, jakie kafelek dostał, a nie z szerokości okna. Akurat tutaj to
   istotne, bo lista siedzi w karcie o stałej szerokości — zapytanie o okno
   mówiłoby o czymś innym niż o rzeczywistym miejscu. Na karcie wychodzą dwie
   kolumny, na telefonie jedna, sama z siebie.

   `min(224px, 100%)` zamiast samego `224px`: gdyby kontener był węższy niż to
   minimum, siatka i tak zrobiłaby kolumnę 224 px i wypchnęła ją poza kartę.
   `100%` zdejmuje ten jeden przypadek.                                     */
.formaty__lista {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(224px, 100%), 1fr));
    align-items: start;
    gap: 4px 10px;
    padding: 10px 12px 14px;
}

.formaty__pozycja {
    display: flex;
    align-items: flex-start;
    gap: 9px;
    padding: 9px 10px;
    border: 1px solid transparent;
    border-radius: var(--r-sm);
    cursor: pointer;
    font-size: 13px;
    line-height: 1.45;
    color: var(--text-2);
}

.formaty__pozycja input {
    margin-top: 2px;
    width: 16px;
    height: 16px;
    flex: none;
    accent-color: var(--blue);
}

/* Najechanie zmienia obwódkę, a NIE tło: tłem kafelka prześwituje wnętrze
   prostokąta (--panel), więc podmiana tła na --panel zgasiłaby rysunek. */
.formaty__pozycja:hover {
    color: var(--text);
    border-color: var(--line);
}

/* Kafelek jest teraz na tyle duży, że czyta się jak przycisk — obwódka
   skupienia musi być widoczna na nim całym, a nie na samym polu wyboru
   16 px w rogu. */
.formaty__pozycja:focus-within {
    outline: 2px solid var(--blue);
    outline-offset: 1px;
}

/* Podświetlenie całego kafelka to dodatek: `:has()` gdzieś nie zadziała
   i wtedy po prostu go nie będzie. Sam znacznik zaznaczenia — grubsza ramka
   prostokąta niżej — stoi na zwykłym sąsiedztwie i działa wszędzie. */
.formaty__pozycja:has(input:checked) {
    border-color: var(--blue-line);
    background: var(--blue-soft);
    color: var(--text);
}

.formaty__tresc {
    display: grid;
    justify-items: start;
    gap: 6px;
    min-width: 0;
}

/* `height: auto` dopełnia globalny reset `svg { max-width: 100% }` — bez tego
   rysunek zwężony przez wąski kafelek zachowałby wysokość z atrybutu
   i proporcja by się rozjechała. */
.fmt { height: auto; }

.fmt__ksztalt {
    fill: var(--panel);
    stroke: var(--text-3);
    stroke-width: 1;
}

/* Wymiar nieustalony — kreska zamiast ciągłej linii, wnętrze puste. */
.fmt__ksztalt--nieznany {
    fill: none;
    stroke-dasharray: 3 3;
}

.fmt__wym  { fill: var(--text-2); font: 500 8px var(--ui); }
.fmt__znak { fill: var(--text-3); font: 600 15px var(--ui); }

/* Zaznaczony format dostaje grubszą ramkę w akcencie. Sąsiedztwo `~`, a nie
   `:has()`, bo to jedyny nośnik informacji „ten jest wybrany" w samym rysunku
   i musi działać w każdej przeglądarce. */
.formaty__pozycja input:checked ~ .formaty__tresc .fmt__ksztalt { stroke: var(--blue); stroke-width: 2; }
.formaty__pozycja input:checked ~ .formaty__tresc .fmt__wym     { fill: var(--text); }

/* Wyjście dla formatu spoza katalogu. Wygląda inaczej niż grupy wyżej — to
   nie jest kolejna grupa do rozwinięcia, tylko miejsce na to, czego w żadnej
   z nich nie ma. */
.formaty__inny {
    margin-top: 8px;
    padding: 11px 13px 12px;
    border: 1px dashed var(--line-2);
    border-radius: var(--r-sm);
}

.formaty__inny .label { font-size: 13px; }

/* Jedna kolumna na wąskim ekranie wychodzi już z `auto-fill` wyżej; ta reguła
   jest jawną gwarancją przy tym samym progu, którego karta klienta używa do
   zmiany własnych marginesów. */
@media (max-width: 560px) {
    .formaty__lista { grid-template-columns: 1fr; }
}

/* Wybrane formaty przy zgłoszeniu */
/* Bez wypunktowania i bez wcięcia.
   `padding-left` pod kropki odsuwał pierwszy wiersz o 18 px względem
   pozostałych wartości — kolumna przestawała być kolumną. Pozycje i tak
   stoją jedna pod drugą, więc kropki niczego nie rozdzielały. */
.szczegoly__lista {
    margin: 0;
    padding-left: 0;
    list-style: none;
}

.szczegoly__lista li { margin: 2px 0; }

/* ── Zakładka „Zgłoś uwagę" ────────────────────────────────────────────────
   Przy prawej krawędzi, na całą wysokość sesji roboczej. Zwijana znacznikiem
   <details>, więc działa bez skryptu — a to ważne akurat tutaj, bo uwagę
   zgłasza się często wtedy, gdy coś innego przestało działać.              */
.uwagi {
    position: fixed;
    right: 0;
    top: 50%;
    transform: translateY(-50%);
    z-index: 60;
    display: flex;
    align-items: flex-start;
}

.uwagi summary {
    list-style: none;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 13px 10px;
    background: var(--panel);
    border: 1px solid var(--line);
    border-right: none;
    border-radius: 10px 0 0 10px;
    box-shadow: var(--shadow);
    color: var(--text-2);
    font-size: 12.5px;
    font-weight: 600;
    /* Napis pionowo, żeby zakładka zabierała pas szerokości, nie pół ekranu. */
    writing-mode: vertical-rl;
    transition: color .15s, border-color .15s;
}

.uwagi summary::-webkit-details-marker { display: none; }
.uwagi summary svg { transform: rotate(90deg); }
.uwagi summary:hover { color: var(--blue); border-color: var(--blue-line); }

.uwagi[open] summary {
    color: var(--blue);
    border-color: var(--blue-line);
}

.uwagi__panel {
    width: 320px;
    max-width: calc(100vw - 60px);
    padding: 16px;
    background: var(--panel);
    border: 1px solid var(--line);
    border-right: none;
    border-radius: 12px 0 0 12px;
    box-shadow: var(--shadow);
    max-height: 80vh;
    overflow-y: auto;
}

.uwagi__wstep {
    margin: 0 0 12px;
    font-size: 12.5px;
    line-height: 1.5;
    color: var(--text-3);
}

.uwagi__ok,
.uwagi__blad {
    margin: 0 0 12px;
    padding: 9px 12px;
    border-radius: var(--r-sm);
    font-size: 13px;
}

.uwagi__ok   { background: rgba(0, 160, 70, .12); color: var(--text); }
.uwagi__blad { background: rgba(224, 36, 44, .12); color: var(--text); }

/* Na wąskim ekranie zakładka schodzi na dół — pionowy pas przy krawędzi
   zabierałby zbyt dużo miejsca na telefonie. */
@media (max-width: 620px) {
    .uwagi { top: auto; bottom: 0; right: 12px; transform: none; }
    .uwagi summary { writing-mode: horizontal-tb; border-radius: 10px 10px 0 0; border-right: 1px solid var(--line); }
    .uwagi summary svg { transform: none; }
    .uwagi__panel { border-radius: 12px 12px 0 0; border-right: 1px solid var(--line); }
}

/* Pojedyncza uwaga w panelu ustawień */
.uwaga {
    padding: 11px 0;
    border-top: 1px solid var(--line);
}

.uwaga:first-of-type { border-top: none; }
.uwaga__meta { display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap; }
.uwaga p { margin: 5px 0 0; font-size: 13.5px; line-height: 1.55; color: var(--text-2); }

/* ── Stopka z obiema markami ───────────────────────────────────────────────
   Znak klienta stoi u góry i jest duży — to jego panel. Znak agencji stoi
   tutaj, mniejszy, ale podpisany „obsługa graficzna", żeby było jasne, kto
   prowadzi narzędzie, a nie tylko czyje jest logo na wierzchu.             */
.stopka {
    display: flex;
    /* Do linii pisma, nie do środka pudełka. Znak „ewi.agency" ma małe
       litery z wydłużeniami dolnymi (g, y), a etykieta obok to wersaliki
       bez nich — przy wyrównaniu do środka pudełka masa optyczna znaku
       leci w dół, choć geometrycznie wszystko się zgadza. */
    align-items: baseline;
    justify-content: center;
    gap: 10px 18px;
    flex-wrap: wrap;
    padding-top: 4px;
}

.stopka__kto {
    display: inline-flex;
    align-items: baseline;
    gap: 10px;
}

.stopka__etykieta {
    font-size: 10.5px;
    letter-spacing: .13em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, .5);
}

/* Znak ewitryny w stopce — ten sam, co w panelu CMS-a, tylko mniejszy.
   Kropka niesie markę, więc zostaje w kolorze. */
.stopka .wordmark {
    font-size: 17px;
    letter-spacing: -.03em;
}

.stopka__dla {
    font-size: 12px;
    color: rgba(255, 255, 255, .45);
    padding-left: 18px;
    position: relative;
}

/* Kreska rozdzielająca rysowana osobno i wyśrodkowana względem wysokości
   znaku obok — przy wyrównaniu do linii pisma zwykłe border-left siedziałoby
   na wysokości tego napisu, nie całej stopki. */
.stopka__dla::before {
    content: "";
    position: absolute;
    left: 0;
    top: 50%;
    transform: translateY(-55%);
    height: 17px;
    border-left: 1px solid rgba(255, 255, 255, .18);
}

/* Na ekranie wejścia stopka siedzi w ciemnej kolumnie i zawija się
   pod znakiem, gdy kolumna jest wąska. */
@media (max-width: 620px) {
    .stopka__dla { padding-left: 0; }
    .stopka__dla::before { display: none; }
}

/* Stopka na jasnym tle — panel obsługi, ekran logowania obsługi, błędy.
   Te same treści, inne kolory, bo tło jest tam białe zamiast markowego. */


/* Wewnątrz kolumny na ekranie wejścia stopka nie potrzebuje własnego
   odstępu — kolumna ma swój. */

/* Znak agencji w stopce prowadzi na jej stronę. Podkreślenie pojawia się
   dopiero pod kursorem — stopka ma być podpisem, nie wołaniem o kliknięcie. */
.stopka__link {
    text-decoration: none;
    display: inline-block;
    transition: opacity .15s;
}

.stopka__link:hover { opacity: .78; }
.stopka__link:focus-visible { outline: 2px solid currentColor; outline-offset: 3px; border-radius: 4px; }

/* ── Przegląd dla kierownictwa ─────────────────────────────────────────────
   Jedna stronicowana lista zamiast trzech kolumn statusów. Kolumny nie
   zmniejszały ciężaru strony, tylko go rozsmarowywały: trzy razy po tysiącu
   wierszy to nadal tysiące węzłów w drzewie dokumentu. Jedyne, co dawały
   naprawdę — „ile czeka" — jest liczbą i mieści się w liczniku, a licznik
   ma tę przewagę, że po kliknięciu zawęża listę.

   Każdy licznik niesie barwę ORAZ znak graficzny. Sam kolor byłby
   niewidoczny dla osoby, która ich nie odróżnia, a to około ośmiu procent
   mężczyzn.                                                                */
.przeglad {
    width: 100%;
    max-width: 1100px;
    display: grid;
    gap: 14px;
}

.liczniki {
    display: grid;
    /* Liczba kafelków zależy od ekranu: przegląd kierownictwa ma cztery
       (trzy statusy plus „Wszystkie"), tablica pracy trzy. Sztywne
       `repeat(4, 1fr)` zostawiało na tablicy pustą czwartą kolumnę i rząd
       nie dochodził do prawej krawędzi. `auto-fit` liczy to sam. */
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    gap: 12px;
}

.licznik {
    /* Kafelek „Wszystkie" nie ma barwy statusu — dostaje neutralną, żeby
       obwódka u góry nie zniknęła i rząd nie rozjechał się o trzy piksele. */
    --status: var(--text-3);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 11px 14px;
    background: var(--panel);
    /* Kolor pisma jawnie, tak jak w .brandcard: strona ma barwne tło i białą
       treść, więc karta bez tego zapisu dziedziczy biały tekst. */
    color: var(--text);
    border: 1px solid var(--line);
    border-top: 3px solid var(--status);
    border-radius: var(--r);
    box-shadow: var(--shadow);
    text-decoration: none;
    transition: border-color .13s, box-shadow .13s;
}

.licznik:hover { border-color: var(--status); }

/* Wybrany licznik to jednocześnie czynny filtr — musi być widać, że lista
   pod spodem jest jego wycinkiem, a nie całością. */
.licznik.is-on {
    border-color: var(--status);
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--status) 32%, transparent);
}

.licznik__label {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 12.5px;
    color: var(--text-2);
}

.licznik__ikona { color: var(--status); line-height: 1; }

.licznik__ile {
    font-family: var(--display);
    font-size: 22px;
    font-weight: 700;
    letter-spacing: -.03em;
    color: var(--status);
}

.filtry {
    display: grid;
    grid-template-columns: minmax(170px, 250px) 1fr auto;
    gap: 12px;
    align-items: end;
    padding: 13px 15px;
    background: var(--panel);
    color: var(--text);
    border: 1px solid var(--line);
    border-radius: var(--r);
    box-shadow: var(--shadow);
}

.filtry__pole { min-width: 0; }
.filtry__pole .label { margin-bottom: 4px; }
/* Pola wypełniają swoją kolumnę siatki. Bez min-width: 0 własna szerokość
   minimalna pola rozpycha kolumnę i wysyła przycisk poza kartę. */
.filtry .field { width: 100%; min-width: 0; }
.filtry__akcje { display: flex; gap: 8px; }

.zkarta {
    background: var(--panel);
    color: var(--text);
    border: 1px solid var(--line);
    border-radius: var(--r);
    box-shadow: var(--shadow);
    overflow: hidden;
}

.zlista { list-style: none; margin: 0; padding: 0; }

.zlista__poz {
    --status: var(--text-3);
    border-top: 1px solid var(--line);
}

.zlista__poz:first-child { border-top: none; }

.zrow {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 10px 16px;
    border-left: 3px solid var(--status);
    color: inherit;
    text-decoration: none;
    transition: background .13s;
}

.zrow:hover { background: var(--blue-soft); }

.zrow__main { flex: 1; min-width: 0; display: grid; gap: 3px; }

.zrow__title {
    font-size: 13.5px;
    font-weight: 600;
    /* Jedna linia na tytuł: wiersz o stałej wysokości pozwala przelecieć
       wzrokiem pięćdziesiąt pozycji, a pełna nazwa czeka w środku. */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.zrow__meta { font-size: 11.5px; color: var(--text-3); }

.zrow .pill { flex: none; }

.zlista__pusto {
    margin: 0;
    padding: 30px 18px;
    text-align: center;
    font-size: 13px;
    color: var(--text-3);
}

@media (max-width: 900px) {
    .liczniki { grid-template-columns: repeat(2, 1fr); }
    .filtry { grid-template-columns: 1fr; }
}

@media (max-width: 560px) {
    /* Plakietka statusu schodzi pod treść, zamiast ściskać tytuł do trzech
       liter na wąskim ekranie. */
    .zrow { flex-wrap: wrap; gap: 8px; }
    .zrow__title { white-space: normal; overflow-wrap: anywhere; }
}

/* Barwy statusów przychodzą z src/Status.php wpisane wprost w atrybut `style`,
   więc nie da się ich podmienić regułą na samym elemencie — zapis w atrybucie
   bije każdy selektor. Rozjaśniamy je zatem tam, gdzie naprawdę widać kolor.
   Bez tego odcienie dobrane pod białą kartę (#2e7de0, #00a046) spadają na
   ciemnej do niecałych 3:1, czyli poniżej progu dla elementów graficznych;
   po domieszaniu bieli wracają powyżej 4,4:1. Znaki graficzne zostają —
   kolor nadal nie jest tu jedynym nośnikiem informacji.                     */
[data-theme="dark"] .brandpage .licznik { border-top-color: color-mix(in srgb, var(--status) 74%, white); }
[data-theme="dark"] .brandpage .licznik__ikona,
[data-theme="dark"] .brandpage .licznik__ile { color: color-mix(in srgb, var(--status) 74%, white); }
[data-theme="dark"] .brandpage .zrow { border-left-color: color-mix(in srgb, var(--status) 74%, white); }

/* ── Stopka w ciemnej kolumnie ekranu wejścia ──────────────────────────────
   Ten ekran nie ma na <body> klasy `on-brand`, bo prawa kolumna jest jasna.
   Skutkiem było to, że stopka w LEWEJ, ciemnej kolumnie dostawała kolory
   przewidziane dla jasnego tła — ciemny tekst na ciemnym tle, czyli znak
   agencji był tam obecny, ale niewidoczny.

   Selektory są celowo dłuższe od `body:not(.on-brand) .stopka …`, żeby wygrać
   specyficznością zamiast sięgać po !important.                             */

/* Kolumna układa treść w pionie i dosuwa ją do środka — bez tego stopka
   wisiałaby u dołu, oderwana od hasła, do którego się odnosi. */


/* Znak agencji na ekranie wejścia jest większy niż w pozostałych stopkach —
   to pierwszy kontakt z narzędziem i moment, w którym warto powiedzieć,
   kto je prowadzi. */


/* ── Stopka: pas w firmowym granacie ewi.agency ─────────────────────────
   Ma własne tło, nie dziedziczy go po stronie. To celowe: kolor marki
   klienta zmienia się per firma (NaturHouse jest zielony), a podpis
   „kto prowadzi to narzędzie" musi wyglądać wszędzie tak samo — inaczej
   ten sam pasek jest zielony w panelu klienta, jasny w panelu obsługi
   i niewidoczny na zdjęciu ekranu wejścia. */
.stopka {
    flex: 0 0 auto;
    margin-top: 0;
    padding: 26px 24px;
    background: #0a1220;
    border-top: 1px solid rgba(255, 255, 255, .07);
}

.stopka__etykieta,
body:not(.on-brand) .stopka__etykieta { color: rgba(255, 255, 255, .55); }

.stopka .wordmark,
body:not(.on-brand) .stopka .wordmark { color: #fff; font-size: 25px; }

/* Kropka niesie markę, więc świeci firmowym błękitem — a nie kolorem
   klienta, którym --blue bywa nadpisany na stronach z brandingiem. */
.stopka .wordmark .dot { color: #1583ff; }

.stopka__dla,
body:not(.on-brand) .stopka__dla { color: rgba(255, 255, 255, .5); font-size: 12.5px; padding-left: 18px; }

.stopka__dla::before,
body:not(.on-brand) .stopka__dla::before {
    display: block;
    border-left-color: rgba(255, 255, 255, .2);
    height: 20px;
}

/* Pas siada na dole okna także wtedy, gdy treści jest mało. Bez tego
   sekcje z min-height:100vh spychałyby go pod krawędź ekranu. */
body {
    min-height: 100dvh;
    display: flex;
    flex-direction: column;
}

/* Dwie osie, dwa różne powody.
   W pionie: element rośnie i spycha stopkę pod dolną krawędź okna — po to
   ta konstrukcja w ogóle powstała.
   W poziomie: element ma być szeroki na OKNO, nie na swoją treść. `.shell`
   ma `margin: 0 auto`, a automatyczny margines w osi poprzecznej wyłącza
   rozciąganie elementu elastycznego — bez podanej szerokości wypadała ona
   z treści. Skutkiem było to, że tabela szersza od ekranu rozpychała całą
   stronę, a `.card { overflow: hidden }` i `.table-scroll` nigdy się nie
   uruchamiały: nie miały czego przycinać, bo karta sama urosła do tabeli. */
body > .split,
body > .brandpage,
body > .shell,
body > main {
    flex: 1 0 auto;
    width: 100%;
    min-width: 0;
}

.split,
.brandpage { min-height: 0; }


/* Załącznik w rozmowie — etykieta udaje przycisk, a samo pole jest ukryte
   dostępnie: `display: none` wyrzuciłoby je z kolejności tabulacji i z drzewa
   dostępności, czyli klawiatura i czytnik ekranu straciłyby do niego dostęp. */
.zalacz { cursor: pointer; }

#reply-picker {
    position: absolute; width: 1px; height: 1px;
    padding: 0; margin: -1px; border: 0;
    overflow: hidden; white-space: nowrap;
    clip-path: inset(50%);
}

.reply__bar:has(#reply-picker:focus-visible) .zalacz {
    outline: 2px solid var(--blue);
    outline-offset: 2px;
}

.zalacz.is-off { opacity: .5; pointer-events: none; }


/* ── Dodany plik ma być widać ────────────────────────────────────────────
   Wiersz pliku był szarą belką na szarym tle karty, między innymi szarymi
   belkami — po dodaniu załącznika franczyzobiorca nie miał pewności, czy
   plik w ogóle wszedł. Teraz od razu po dodaniu wiersz dostaje zielony
   ptaszek i zielony brzeg. Barwy liczone z --good, więc ciemny motyw
   dostaje je razem z resztą, bez osobnej reguły. */
.file {
    /* Brzeg niesie większość sygnału, tło tylko go podpiera. Zmierzone:
       sam odcień tła dawał 1,15 wobec karty, czyli mniej więcej tyle co
       szare belki pól tekstowych obok — a to była właśnie skarga. Brzeg
       daje niemal 5, więc widać go od razu, i nie robi z formularza
       zielonej płachty. */
    border-left: 4px solid var(--good);
    background: color-mix(in srgb, var(--good) 11%, var(--panel-2));
}

.file__icon {
    color: var(--good);
}

.file__name {
    font-weight: 500;
}

/* Plik odrzucony musi wygrać nad stanem „dodany" — inaczej zielony brzeg
   przekonywałby, że wszystko w porządku, a plik nie poleci. */
.file.is-bad {
    border-left-color: var(--bad);
    background: color-mix(in srgb, var(--bad) 7%, var(--panel-2));
}

.file.is-bad .file__icon { color: var(--bad); }


/* ── Pliki źródłowe ──────────────────────────────────────────────────────
   Zaplecze warsztatowe zespołu: gdzie leżą materiały robocze, żeby przy
   przekazaniu sprawy nie trzeba było pytać kolegi. Wygląd celowo spokojny —
   to notatka, nie treść zgłoszenia. */
.zrodla { display: grid; gap: 8px; margin-bottom: 16px; }

.zrodlo {
    display: grid;
    grid-template-columns: 22px 1fr auto;
    align-items: start;
    gap: 10px;
    padding: 10px 12px;
    border: 1px solid var(--line);
    border-radius: var(--r-sm);
    background: var(--panel-2);
}

.zrodlo__ikona { color: var(--text-3); display: grid; place-items: center; padding-top: 1px; }
.zrodlo__tresc { min-width: 0; }
.zrodlo__tresc a { word-break: break-all; }
.zrodlo__opis  { display: block; margin-top: 2px; font-size: 12.5px; color: var(--text-2); }
.zrodlo__kto   { display: block; margin-top: 3px; color: var(--text-3); }
.zrodlo__x     { display: flex; }

.zrodla__dodaj { padding-top: 14px; border-top: 1px solid var(--line); }


/* ── Tablica pracy zespołu ───────────────────────────────────────────────
   Wiersz odpowiada na trzy pytania naraz: na czym stoi sprawa (znak stanu
   po lewej), czego dotyczy (środek) i kto ją prowadzi (prawa). Ostatnia
   kolumna jest tym, czego ekran kierownictwa nie ma — klient ma widzieć
   stan sprawy, a nie który grafik nad nią siedzi. */
.prow {
    display: grid;
    grid-template-columns: 26px 1fr auto;
    align-items: center;
    gap: 12px;
    padding: 11px 14px;
    text-decoration: none;
    color: inherit;
    border-radius: var(--r-sm);
}

.prow:hover { background: var(--panel-2); }

.prow__stan   { color: var(--status); font-size: 15px; text-align: center; }
.prow__tresc  { min-width: 0; }
.prow__tytul  { display: block; font-weight: 500; font-size: 13.5px; }
.prow__meta   { display: block; margin-top: 3px; font-size: 11.5px; color: var(--text-3); }

.prow__kto {
    font-size: 12px;
    color: var(--text-2);
    white-space: nowrap;
    padding: 3px 9px;
    border: 1px solid var(--line);
    border-radius: 999px;
}

/* Własna sprawa wyróżniona — po to, żeby „moje" dało się znaleźć wzrokiem
   na wspólnej liście, bez przełączania filtra. */
.prow__kto.is-moje {
    color: var(--blue-ink);
    border-color: var(--blue-line);
    background: var(--blue-soft);
    font-weight: 500;
}

.prow__wolne { color: var(--text-3); font-style: italic; }

@media (max-width: 640px) {
    .prow { grid-template-columns: 22px 1fr; }
    .prow__kto { grid-column: 2; justify-self: start; margin-top: 4px; }
}


/* ── Filtry z czterema polami ────────────────────────────────────────────
   Przegląd kierownictwa ma trzy pola (oddział, szukanie, przyciski),
   tablica pracy cztery — dochodzi „prowadzi". Bez własnej definicji czwarte
   pole zawijało się do drugiego rzędu, a pole szukania rozpychało się na
   całą kolumnę 1fr i wyglądało jak wyrwane z układu. */
.filtry--cztery {
    grid-template-columns: minmax(150px, 210px) minmax(130px, 180px) 1fr auto;
}

@media (max-width: 900px) {
    .filtry--cztery { grid-template-columns: 1fr 1fr; }
    .filtry--cztery .filtry__akcje { grid-column: 1 / -1; }
}

@media (max-width: 560px) {
    .filtry--cztery { grid-template-columns: 1fr; }
}


/* ── Pionowy rytm ekranów panelu ─────────────────────────────────────────
   Liczniki, filtry i lista stały jeden pod drugim bez żadnego odstępu,
   przez co ekran czytało się jak jeden zlepiony blok. Ekran kierownictwa
   miał to od początku (`.przeglad` z gap), ale tablica pracy i dziennik
   wstawiały moduły prosto do kolumny treści. Odstęp większy niż tam, bo
   bloków jest więcej i każdy jest osobną myślą. */
.stos {
    display: grid;
    gap: 18px;
}


/* ── Odstęp nad przyciskiem w formularzu ─────────────────────────────────
   Jedna reguła zamiast wpisywania go w znaczniku przy każdym przycisku
   z osobna. Dotąd tak właśnie było i rozjechało się na sześć wartości:
   8, 10, 12, 14, 16 i 18 px — a w sekcji plików źródłowych zapomniano go
   dopisać w ogóle i przycisk przyklejał się do pola.

   To jest cała przyczyna tamtego błędu: odstęp, o którym trzeba PAMIĘTAĆ,
   prędzej czy później zostaje pominięty przy kolejnym formularzu.

   18 px, bo tyle ma główny formularz zgłoszenia — najczęściej oglądany
   w całym systemie, więc to on wyznacza rytm. */
.field-row + .btn,
.field-row + button.btn,
.field-row + a.btn,
.checkrow + .btn,
.formaty + .btn,
form > .btn:last-child {
    margin-top: 18px;
}

/*
 * ...ale NIE w edycji w komórce tabeli.
 *
 * `form > .btn:last-child` wyżej jest wygodne i obejmuje formularze, których
 * jeszcze nie ma — i właśnie dlatego sięgnęło tam, gdzie nie trzeba: w panelu
 * kont każde pole to osobny formularz z przyciskiem „Zapisz" OBOK, a nie pod
 * spodem. Osiemnaście pikseli spychało go o pół wiersza w dół i cała tabela
 * wyglądała na rozsypaną.
 *
 * Reguła szeroka plus jeden wyjątek jest tu lepsza niż wyliczanie z góry
 * wszystkich formularzy, w których odstęp ma być — bo o dopisanie do takiej
 * listy znowu trzeba by pamiętać.
 */
/*
 * Wewnątrz POZIOMEJ grupy przycisków odstęp nie obowiązuje.
 *
 * Reguła wyżej celuje w przycisk kończący pionowy formularz — pod polami.
 * W poziomym rzędzie trafiała tylko w te przyciski, które siedzą we własnym
 * <form> (bo każda akcja to osobny formularz), a mijała te w zwykłym <div>.
 * Efekt: rząd „Rozmowa · Pobierz ZIP · Przebuduj paczkę · Usuń" rozjeżdżał
 * się w schodki dokładnie o 18 px.
 *
 * Wymieniam pojemniki, a nie polegam na tym, że przycisk siedzi w formularzu
 * — bo to formularz był tu przypadkiem, a nie regułą.
 */
.inline-edit > .btn,
.inline-edit > .btn:last-child,
.actions .btn,
.actions form > .btn,
.konto__akcje .btn,
.konto__akcje form > .btn,
.filtry__akcje .btn,
.filtry__akcje form > .btn,
.statusbar .btn,
.statusbar .statusbtn,
.wysilek .btn,
.wysilek .statusbtn,
.reply__bar .btn,
.brandnav .btn {
    margin-top: 0;
}

/* Dwa przyciski jeden pod drugim (np. „Wróć" pod „Dalej") stoją bliżej —
   należą do tej samej decyzji, więc nie rozdzielamy ich pełnym odstępem. */
.btn--block + .btn--block {
    margin-top: 8px;
}

/* ── Konta klientów ──────────────────────────────────────────────────────
   Lista kont była tabelą o dziewięciu kolumnach, a w każdym wierszu stały
   trzy osobne formularze i jeszcze zmiana kodu. Pola tekstowe schodziły
   przez to do kilkudziesięciu pikseli i „Kierownictwo NaturHouse" nie
   mieściło się w swoim własnym polu. Karta daje każdemu polu pełną
   szerokość, a przy wąskim oknie układa je jedno pod drugim.

   Karty leżą w .card__body, więc własnego tła nie biorą — .konto rysuje
   tylko obwódkę, żeby nie robić pudełka w pudełku. */


@media (max-width: 640px) {
}


/* Pasek pracochłonności — ten sam układ co pasek statusu nad nim, bo to ta
   sama czynność widziana z drugiej strony: tam wybierasz stan, tu zamykasz
   i od razu mówisz, ile to było roboty. */
.wysilek {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    margin: -8px 0 18px;
    padding: 10px 12px;
    border: 1px dashed var(--line-2);
    border-radius: var(--r);
}


/* Kolumna akcji — przyciski w jednym rzędzie i wyrównane do prawej krawędzi.
   Bez tego układały się w schodki o różnej długości i wiersz po wierszu
   trudno było trafić wzrokiem w ten sam przycisk. */
.table .right .btn { margin-left: 6px; }

.table .right {
    white-space: nowrap;
}


/* ── Konta klientów ──────────────────────────────────────────────────────
   Karty zamiast tabeli. Konto ma dziewięć rzeczy do pokazania i cztery do
   edycji — w dziewięciu kolumnach pola zwężały się do trzydziestu pikseli
   i ucinały treść w połowie słowa („Oddział Wad…"), a przyciski układały się
   w schodki. Karta daje każdemu polu pełną szerokość i trzyma razem to,
   co ze sobą związane. */
.konta {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(420px, 1fr));
    gap: 14px;
}

.konto {
    display: grid;
    gap: 14px;
    padding: 16px 18px;
    border: 1px solid var(--line);
    border-radius: var(--r);
    background: var(--panel);
}

/* Konto wyłączone przygaszone, ale CZYTELNE — trzeba na nim jeszcze
   kliknąć „Włącz", więc nie może być ledwo widoczne. */
.konto--off { opacity: .68; background: var(--panel-2); }
.konto--off:hover,
.konto--off:focus-within { opacity: 1; }

.konto__glowa {
    display: grid;
    gap: 5px;
    padding-bottom: 12px;
    border-bottom: 1px solid var(--line);
}

.konto__kto {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    flex-wrap: wrap;
}

.konto__mail { font-size: 13.5px; word-break: break-all; }

.konto__meta {
    display: flex;
    align-items: center;
    gap: 5px;
    flex-wrap: wrap;
    color: var(--text-3);
}

/* Dwa pola w rzędzie. Rola i kod są krótkie, placówka i opis potrzebują
   szerokości — dlatego te dwa idą przez całą kartę. */
.konto__pola {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
}

.konto__pole {
    display: grid;
    gap: 5px;
    min-width: 0;
}

.konto__pole:nth-child(2),
.konto__pole:nth-child(3) { grid-column: 1 / -1; }

.konto__pole .label { margin: 0; }
.konto__pole .label .tiny { font-weight: 400; color: var(--text-3); }

.konto__pole .inline-edit { flex-wrap: nowrap; align-items: center; }
.konto__pole .inline-edit .field { min-width: 0; flex: 1 1 auto; }
.konto__pole .inline-edit .btn { flex: 0 0 auto; white-space: nowrap; margin-top: 0; }

.konto__ostrzezenie { justify-self: start; }

.konto__akcje {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    padding-top: 12px;
    border-top: 1px solid var(--line);
}

.konto__nieusuwalne { color: var(--text-3); }

@media (max-width: 560px) {
    .konta { grid-template-columns: 1fr; }
    .konto__pola { grid-template-columns: 1fr; }
    .konto__pole:nth-child(2),
    .konto__pole:nth-child(3) { grid-column: auto; }
}


/* ── Powrót do listy ─────────────────────────────────────────────────────
   Był drobnym szarym odnośnikiem wielkości podpisu pod zdjęciem — czyli
   wyglądał na notatkę, a nie na jedyną drogę wyjścia z ekranu zgłoszenia.
   Człowiek, który go nie znajdzie, klika „wstecz" w przeglądarce albo wraca
   przez belkę; jedno i drugie znaczy, że element nie robi swojej roboty.

   Teraz jest tym, czym jest: kontrolką. Obwódka, wyraźna strzałka, rozmiar
   pisma jak w przyciskach obok. */
.wroc {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    height: 32px;
    padding: 0 14px 0 11px;
    margin-bottom: 14px;
    /* Obwódka w barwie pisma pomocniczego, nie w barwie linii.
       Zmierzone: --line-2 dawało wobec tła 1,35, czyli kształt ledwo się
       odcinał i przycisk czytał się jak zwykły tekst. */
    border: 1px solid var(--text-3);
    border-radius: 999px;
    background: var(--panel);
    /* Pełna barwa pisma, nie przygaszona: przy --text-2 kontrast wychodził
       2,73, czyli poniżej progu czytelności dla zwykłego tekstu. To jedyna
       droga wyjścia z tego ekranu — ma się rzucać w oczy, a nie ustępować
       tłu. */
    color: var(--text);
    font-size: 13.5px;
    font-weight: 600;
    text-decoration: none;
    transition: border-color .14s, color .14s, background .14s;
}

.wroc:hover {
    border-color: var(--blue-line);
    background: var(--blue-soft);
    color: var(--blue-ink);
}

.wroc:focus-visible {
    outline: 2px solid var(--blue);
    outline-offset: 2px;
}

/* Strzałka cofa się o włos przy najechaniu — drobiazg, ale mówi „to jest
   ruch wstecz", zanim człowiek przeczyta napis. */
.wroc svg { transition: transform .14s; }
.wroc:hover svg { transform: translateX(-2px); }

/* Na ekranach klienta karta ma białe tło na barwnej płaszczyźnie, więc
   przycisk musi mieć własne tło, a nie dziedziczyć przezroczystość. */
.brandcard .wroc { background: var(--panel-2); }


/* ── Panel uwag: zakładka zrośnięta z panelem ────────────────────────────
   Zakładka i panel to dwa osobne pudełka stojące obok siebie. Każde miało
   własną obwódkę i własne zaokrąglenia, więc po otwarciu w miejscu ich styku
   robił się wcięty narożnik i podwójna kreska — wyglądało to jak dwie kartki
   nałożone na siebie, a nie jak jedna rzecz.

   Teraz zaokrąglona jest tylko krawędź od strony ekranu, a styk jest płaski
   i pozbawiony obwódki. Panel dochodzi do prawej krawędzi okna, więc z tej
   strony też nie zaokrąglamy — zaokrąglenie na krawędzi ekranu wygląda jak
   niedomknięte okno. */
.uwagi summary {
    border-radius: 10px 0 0 10px;
    border-right: none;
    position: relative;
    z-index: 1;
}

.uwagi[open] summary {
    /* Styk bez cienia i bez kreski — zakładka i panel są jedną płaszczyzną. */
    box-shadow: none;
}

.uwagi__panel {
    border-radius: 0;
    border-left: none;
    border-right: none;
}

.uwagi__glowa {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    margin: -4px 0 12px;
    padding-bottom: 10px;
    border-bottom: 1px solid var(--line);
}

.uwagi__tytul {
    font-family: var(--display);
    font-weight: 700;
    font-size: 14px;
    letter-spacing: -.01em;
}

.uwagi__zamknij {
    display: grid;
    place-items: center;
    width: 28px;
    height: 28px;
    margin-right: -4px;
    border: 1px solid transparent;
    border-radius: 8px;
    background: transparent;
    color: var(--text-3);
    font-size: 20px;
    line-height: 1;
    cursor: pointer;
    transition: color .14s, background .14s, border-color .14s;
}

.uwagi__zamknij:hover {
    color: var(--text);
    background: var(--panel-2);
    border-color: var(--line);
}

.uwagi__zamknij:focus-visible {
    outline: 2px solid var(--blue);
    outline-offset: 1px;
}

@media (max-width: 700px) {
    /* Przy dole ekranu zakładka leży poziomo — wtedy zaokrąglamy górę,
       a styk jest na dole. */
    .uwagi summary { border-radius: 10px 10px 0 0; border-right: 1px solid var(--line); }
    .uwagi__panel { border-radius: 12px 12px 0 0; border-left: 1px solid var(--line); border-right: 1px solid var(--line); }
}

/* ── Kto prowadzi sprawę ──────────────────────────────────────────────────
   Pasek nad statusem: imię właściciela i jeden przycisk. Osobne nazwy, bo
   .prow to wiersz tablicy pracy — ta sama nazwa ściągnęłaby tu jego siatkę. */
.wlasc {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
    margin-bottom: 14px;
    padding: 10px 14px;
    border: 1px solid var(--line);
    border-radius: 10px;
    background: var(--panel-2);
    font-size: 13.5px;
}

.wlasc__kto { color: var(--text-2); }
.wlasc__akcja { margin: 0; }

/* ── Formularz zakładania konta (zespół i klienci) ────────────────────────
   Nie .pinform: tamten ma cztery wąskie kolumny wyrównane do dołu i jest
   zrobiony pod cztery krótkie pola bez podpowiedzi. Tutaj podpowiedzi mają
   różną długość, więc wyrównanie do dołu stawiało każde pole na innej
   wysokości. Kolumny same się układają, wyrównanie do góry, przycisk
   w osobnym wierszu. */
.zespolform {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 20px 22px;
    align-items: start;
}

.zespolform__akcja { grid-column: 1 / -1; }

/* ── Pliki, które nie doszły ──────────────────────────────────────────────
   Na ekranie potwierdzenia, w karcie. Czerwień tylko na obwódce i nagłówku:
   zgłoszenie JEST przyjęte, więc cała karta na czerwono kłamałaby o skali. */
.odpadly {
    margin: 18px 0 0;
    padding: 14px 16px;
    border: 1px solid #c02a20;
    border-radius: 10px;
    background: rgba(192, 42, 32, .06);
    text-align: left;
    font-size: 13.5px;
}

.odpadly b { color: #c02a20; }
.odpadly p { margin: 6px 0 0; color: var(--text-2); }
.odpadly ul { margin: 8px 0 0; padding-left: 18px; }
.odpadly li { margin-top: 4px; }
.odpadly__rada { font-size: 12.5px; color: var(--text-3); }
