/* ════════════════════════════════════════════════════════════════
   UltraGastro — arkusz główny
   Zasady: 08_UI_UX.md
   Bez buildu, bez Node, bez webfontów. Jeden plik.
   ════════════════════════════════════════════════════════════════ */

:root {
  /* Marka */
  --brand:          #E0567A;
  --brand-dark:     #C13A5E;
  --brand-light:    #FCE7EE;

  /* Tło i powierzchnie */
  --bg:             #F7F7F9;
  --surface:        #FFFFFF;
  --surface-alt:    #FAFAFB;
  --border:         #E4E4E8;
  --border-strong:  #C9C9D1;

  /* Tekst */
  --text:           #16161A;
  --text-muted:     #6B6B76;
  --text-subtle:    #9A9AA5;
  --text-inverse:   #FFFFFF;

  /* Statusy — jedyna dozwolona semantyka kolorów */
  --ok:             #16A34A;
  --ok-bg:          #DCFCE7;
  --ok-border:      #A7F3C4;
  --warn:           #B45309;
  --warn-bg:        #FEF3C7;
  --warn-border:    #FCD34D;
  --danger:         #DC2626;
  --danger-bg:      #FEE2E2;
  --danger-border:  #FCA5A5;
  --info:           #2563EB;
  --info-bg:        #DBEAFE;
  --info-border:    #93C5FD;

  /* Wykresy */
  --c1: #2563EB; --c2: #E0567A; --c3: #16A34A;
  --c4: #D97706; --c5: #7C3AED; --c6: #0891B2;

  /* Typografia */
  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
          "Helvetica Neue", Arial, sans-serif;
  --font-mono: ui-monospace, "SF Mono", SFMono-Regular, Consolas,
               "Liberation Mono", Menlo, monospace;

  /* Odstępy — skala 4 px */
  --s1: 4px;  --s2: 8px;  --s3: 12px; --s4: 16px;
  --s5: 24px; --s6: 32px; --s7: 48px; --s8: 64px;

  /* Zaokrąglenia i cienie */
  --r-sm: 6px; --r: 10px; --r-lg: 16px; --r-full: 999px;
  --shadow-sm: 0 1px 2px rgba(0,0,0,.06);
  --shadow:    0 2px 8px rgba(0,0,0,.08);
  --shadow-lg: 0 8px 24px rgba(0,0,0,.12);
}

/* ── Reset ────────────────────────────────────────────────────── */

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

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.55;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, p, figure, ul, ol { margin: 0; }
ul, ol { padding: 0; list-style: none; }
img, svg { max-width: 100%; height: auto; display: block; }

a { color: var(--brand-dark); text-decoration: none; }
a:hover { text-decoration: underline; }

:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

code, kbd, pre { font-family: var(--font-mono); font-size: .9em; }

code {
  background: var(--surface-alt);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  padding: 1px 5px;
}

/* Liczby zawsze tej samej szerokości — inaczej kolumna kwot się rozsypuje */
.num, td.num, .stat-value, .mono {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum";
}
.num, td.num { text-align: right; }

/* ── Układ strony ─────────────────────────────────────────────── */

.page {
  max-width: 880px;
  margin: 0 auto;
  padding: var(--s6) var(--s4) var(--s8);
}
.page--wide { max-width: 1140px; }

@media (max-width: 640px) {
  .page { padding: var(--s5) var(--s4) var(--s7); }
}

.stack > * + * { margin-top: var(--s5); }
.stack-sm > * + * { margin-top: var(--s3); }

/* ── Nagłówek produktu ────────────────────────────────────────── */

.brand {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--s2);
  font-size: 18px;
  font-weight: 700;
  color: var(--text);
  margin-bottom: var(--s5);
}
.brand:hover { text-decoration: none; }
.brand-mark { font-size: 22px; line-height: 1; }

/* ── Karta ────────────────────────────────────────────────────── */

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: var(--s5);
}
.card--flush { padding: 0; overflow: hidden; }
.card--accent { border-color: var(--brand); }

.card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s3);
  padding: var(--s4) var(--s5);
  border-bottom: 1px solid var(--border);
  background: var(--surface-alt);
}
.card-head h2 {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.card-body { padding: var(--s5); }

/* ── Bohater strony /version ──────────────────────────────────── */

.hero {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: var(--s7) var(--s5);
  text-align: center;
}

.hero-version {
  font-size: 48px;
  font-weight: 700;
  letter-spacing: -.02em;
  line-height: 1.05;
  font-variant-numeric: tabular-nums;
}
.hero-name {
  font-size: 17px;
  color: var(--text-muted);
  margin-top: var(--s2);
}
.hero-meta {
  font-size: 13px;
  color: var(--text-subtle);
  margin-top: var(--s4);
}

@media (max-width: 640px) {
  .hero { padding: var(--s6) var(--s4); }
  .hero-version { font-size: 38px; }
}

/* ── Pasek postępu ────────────────────────────────────────────── */

.progress {
  height: 8px;
  background: var(--border);
  border-radius: var(--r-full);
  overflow: hidden;
  margin: var(--s5) auto var(--s3);
  max-width: 460px;
}
.progress-bar {
  height: 100%;
  background: var(--brand);
  border-radius: var(--r-full);
  transition: width .3s ease;
}
/* Etap 0 to uczciwe 0% — pusty pasek, bez sztucznej kropki */
.progress-bar[style*="width: 0%"] { background: transparent; }
.progress-label {
  font-size: 13px;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}

/* ── Lista stanu (klucz → wartość → status) ───────────────────── */

.status-list { border-top: 1px solid var(--border); }
.status-list > li {
  display: flex;
  align-items: baseline;
  gap: var(--s3);
  padding: var(--s3) var(--s5);
  border-bottom: 1px solid var(--border);
}
.status-list > li:nth-child(even) { background: var(--surface-alt); }

.status-dot {
  flex: none;
  width: 9px; height: 9px;
  border-radius: 50%;
  margin-top: 6px;
  background: var(--text-subtle);
}
.status-dot--ok      { background: var(--ok); }
.status-dot--warning { background: var(--warn); }
.status-dot--error   { background: var(--danger); }

.status-label { flex: 1 1 auto; min-width: 0; }
.status-value {
  flex: none;
  color: var(--text-muted);
  font-size: 14px;
  font-variant-numeric: tabular-nums;
}
.status-hint {
  display: block;
  font-size: 13px;
  color: var(--text-muted);
  margin-top: 2px;
}
.status-list--compact > li { padding-top: var(--s2); padding-bottom: var(--s2); }

@media (max-width: 560px) {
  /* Na wąskim ekranie wartość schodzi pod etykietę i jest wyrównana do lewej —
     mieszanka wyrównań w jednej kolumnie wygląda na przypadek. */
  .status-list > li { flex-wrap: wrap; }
  .status-value,
  .status-value.num { width: 100%; padding-left: 21px; text-align: left; }
}

/* ── Tabela ───────────────────────────────────────────────────── */

.table-wrap { overflow-x: auto; }

table.data {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
}
table.data th {
  text-align: left;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .03em;
  text-transform: uppercase;
  color: var(--text-muted);
  padding: var(--s3) var(--s4);
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
/* Nagłówek kolumny liczbowej też do prawej.
   `.num` z góry pliku ma NIŻSZĄ swoistość niż `table.data th` powyżej,
   więc samo `class="num"` na `<th>` nie robiło nic — choć wygląda,
   jakby robiło. Do etapu 10 nie było tego widać, bo nagłówki liczbowe
   („POWINNO BYĆ”, „WARTOŚĆ”) są długie i wypełniają kolumnę. W siatce
   HACCP nagłówkiem jest „10:00” przy szerokiej kolumnie i rozjazd
   z liczbami pod spodem rzuca się w oczy. */
table.data th.num { text-align: right; }
table.data td {
  padding: var(--s3) var(--s4);
  border-bottom: 1px solid var(--border);
  vertical-align: top;
}
table.data tbody tr:nth-child(even) { background: var(--surface-alt); }
table.data tbody tr:last-child td { border-bottom: 0; }

/* Kolumny drugorzędne znikają na wąskim ekranie, żeby status zawsze był widoczny
   bez przewijania w bok. */
.tylko-waski { display: none; }

/*
 | ── SKRÓCONE NAGŁÓWKI KOLUMN ────────────────────────────────────────
 |
 | `.tylko-szeroki` i `.tylko-waski` w jednym `<th>` dają dwa podpisy tej
 | samej kolumny: pełny na monitorze, skrócony na telefonie.
 |
 | Powstało to, bo na karcie zamówienia same NAGŁÓWKI „Zamówiono”
 | i „Dostarczono” zajmowały 226 z 308 dostępnych pikseli i wypychały poza
 | krawędź kolumnę „Różnica” — jedyną liczbę, dla której ten ekran powstał.
 | Schowanie którejkolwiek kolumny nic by nie dało: za szerokie były
 | SŁOWA, nie liczby.
 |
 | To jest coś innego niż `.optional`, które znika całą kolumną razem
 | z zawartością i służy rzeczom drugorzędnym. Tutaj kolumna ma zostać,
 | schudnąć ma tylko podpis.
 */
.tylko-szeroki { display: inline; }

@media (max-width: 560px) {
  table.data th.optional, table.data td.optional { display: none; }
  table.data th, table.data td { padding-left: var(--s3); padding-right: var(--s3); }

  /* Odwrotność `.optional`: to, co na szerokim ekranie ma własną kolumnę,
     a na wąskim musi dosiąść się do sąsiada, żeby nie zniknąć zupełnie.
     Schowanie kolumny z KWOTĄ bez takiego dopisku zabierałoby akurat tę
     liczbę, dla której ktoś tabelę otwiera. */
  .tylko-waski   { display: block; }
  .tylko-szeroki { display: none; }

  /* W nagłówku skrót ma stać w linii, a nie pod spodem. */
  table.data th .tylko-waski { display: inline; }

  /*
   | ── ODZNAKA W TABELI ŁAMIE SIĘ NA TELEFONIE ───────────────────────
   |
   | `.badge` ma `white-space: nowrap`, bo na szerokim ekranie odznaka
   | przełamana w połowie wygląda na zepsutą. W tabeli na telefonie robi
   | jednak coś gorszego: „Działanie naprawcze" w rejestrze HACCP zajmuje
   | 161 z 308 dostępnych pikseli i wypycha kolumnę WYNIK poza krawędź —
   | czyli jedyną rzecz, o którą pyta sanepid.
   |
   | Dwa wiersze tekstu kosztują trochę wysokości. Ucięta kolumna kosztuje
   | całą informację.
   */
  table.data .badge { white-space: normal; }
}

/* ── Odznaki ──────────────────────────────────────────────────── */

.badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 12px;
  font-weight: 600;
  padding: 2px 9px;
  border-radius: var(--r-full);
  border: 1px solid transparent;
  white-space: nowrap;
}
.badge--ok      { background: var(--ok-bg);     color: var(--ok);     border-color: var(--ok-border); }
.badge--warning { background: var(--warn-bg);   color: var(--warn);   border-color: var(--warn-border); }
.badge--danger  { background: var(--danger-bg); color: var(--danger); border-color: var(--danger-border); }
.badge--info    { background: var(--info-bg);   color: var(--info);   border-color: var(--info-border); }
.badge--muted   { background: var(--surface-alt); color: var(--text-muted); border-color: var(--border); }

/* ── Komunikaty ───────────────────────────────────────────────── */

.notice {
  display: flex;
  gap: var(--s3);
  padding: var(--s4);
  border-radius: var(--r);
  border: 1px solid var(--border);
  background: var(--surface);
  font-size: 14px;
}
.notice-icon { flex: none; font-size: 16px; line-height: 1.4; }
.notice-body { min-width: 0; }
/* Osobnym wierszem jest tylko NAGŁÓWEK komunikatu. Bez `>` każde
   pogrubienie w treści łamało linię — nazwisko lądowało w swoim
   wierszu, a data zaczynała następny od samego przecinka. */
.notice-body > strong { display: block; margin-bottom: 2px; }
.notice a { font-weight: 600; }

.notice--ok      { background: var(--ok-bg);     border-color: var(--ok-border); }
.notice--warning { background: var(--warn-bg);   border-color: var(--warn-border); }
.notice--danger  { background: var(--danger-bg); border-color: var(--danger-border); }
.notice--info    { background: var(--info-bg);   border-color: var(--info-border); }

/* ── Przyciski ────────────────────────────────────────────────── */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s2);
  min-height: 44px;
  padding: 0 var(--s5);
  font: inherit;
  font-size: 15px;
  font-weight: 600;
  color: var(--text-inverse);
  background: var(--brand);
  border: 1px solid var(--brand);
  border-radius: var(--r);
  cursor: pointer;
  text-align: center;
  transition: background .15s ease, border-color .15s ease;
}
.btn:hover { background: var(--brand-dark); border-color: var(--brand-dark); text-decoration: none; }
.btn:disabled { opacity: .5; cursor: not-allowed; }

.btn--secondary {
  color: var(--text);
  background: var(--surface);
  border-color: var(--border-strong);
}
.btn--secondary:hover { background: var(--surface-alt); border-color: var(--text-subtle); }

.btn--ghost {
  color: var(--brand-dark);
  background: transparent;
  border-color: transparent;
  padding: 0 var(--s3);
}
.btn--ghost:hover { background: var(--brand-light); }

.btn--block { display: flex; width: 100%; }
.btn--lg { min-height: 56px; font-size: 16px; }

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s3);
  align-items: center;
}

@media (max-width: 480px) {
  .btn-row { flex-direction: column; align-items: stretch; }
  .btn-row .btn { width: 100%; }
}

/* ── Formularz ────────────────────────────────────────────────── */

.field { margin-bottom: var(--s4); }

.field label {
  display: block;
  font-size: 13px;
  font-weight: 500;
  color: var(--text-muted);
  margin-bottom: 5px;
}
.field .req { color: var(--danger); }

/* Pola formularza: WSZYSTKIE typy tekstowe, nie cztery wypisane z nazwy.
   Pierwsza wersja wyliczała `text`, `password`, `number` i `email` — i przez
   dziewięć etapów nikt nie zauważył, że `date`, `month`, `tel` oraz każdy
   `textarea` zostają bez stylu. A samych pól daty jest w systemie 28,
   od etapu 3.

   Widać to było dopiero wtedy, gdy w jednym formularzu stanęły obok siebie
   pole daty i pole tekstowe: jedno maleńkie i systemowe, drugie na pełną
   szerokość. Wyliczanie zamieniliśmy na wykluczanie, żeby nowy typ pola
   dostawał styl sam z siebie, zamiast czekać, aż ktoś dopisze go do listy. */
.field input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="hidden"]),
.field select,
.field textarea {
  width: 100%;
  min-height: 48px;
  padding: 0 var(--s3);
  /* 16px jest wymagane — mniejsza czcionka powoduje, że iOS przybliża stronę */
  font: inherit;
  font-size: 16px;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--r);
}
.field textarea {
  min-height: 84px;
  padding: var(--s3);
  line-height: 1.5;
  /* Tylko w pionie — rozciągnięty w bok textarea rozwala układ karty. */
  resize: vertical;
}
/* Pola wyboru pliku nie da się ostylować do końca (przycisk rysuje
   przeglądarka), ale ramka i tło mają je odróżnić od zwykłego pola:
   tu się nie pisze, tu się coś wybiera. */
.field input[type="file"] {
  width: 100%;
  padding: var(--s3);
  font: inherit;
  font-size: 14px;
  background: var(--surface-alt);
  border: 1px dashed var(--border-strong);
  border-radius: var(--r);
}
.field input:focus, .field select:focus, .field textarea:focus {
  border-color: var(--brand);
  outline: 2px solid var(--brand-light);
  outline-offset: 0;
}
.field--error input { border-color: var(--danger); }

.field-hint { font-size: 12px; color: var(--text-subtle); margin-top: 4px; }
.field-error { font-size: 13px; color: var(--danger); margin-top: 4px; font-weight: 500; }

.field-row {
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: var(--s3);
}
@media (max-width: 480px) {
  .field-row { grid-template-columns: 1fr; }
}

/* ── Rozwijana sekcja ─────────────────────────────────────────── */

details.reveal { border-radius: var(--r-lg); }
details.reveal > summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s3);
  padding: var(--s4) var(--s5);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--text-muted);
  background: var(--surface-alt);
  border-bottom: 1px solid transparent;
}
details.reveal > summary::-webkit-details-marker { display: none; }
details.reveal > summary::after {
  content: "▾";
  font-size: 12px;
  transition: transform .2s ease;
}
details.reveal[open] > summary { border-bottom-color: var(--border); }
details.reveal[open] > summary::after { transform: rotate(180deg); }

/* ── Historia wersji ──────────────────────────────────────────── */

.release { padding: var(--s4) var(--s5); border-bottom: 1px solid var(--border); }
.release:last-child { border-bottom: 0; }

.release-head {
  display: flex;
  align-items: baseline;
  gap: var(--s3);
  flex-wrap: wrap;
}
.release-version {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.release-name { color: var(--text-muted); flex: 1 1 auto; }
.release-date { font-size: 13px; color: var(--text-subtle); }

.changes { margin-top: var(--s3); }
.changes h4 {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: var(--s2);
}
.changes ul { margin-bottom: var(--s3); }
.changes li {
  position: relative;
  padding-left: var(--s4);
  font-size: 14px;
  margin-bottom: 3px;
}
.changes li::before {
  content: "";
  position: absolute;
  left: 4px; top: 9px;
  width: 4px; height: 4px;
  border-radius: 50%;
  background: var(--text-subtle);
}

/* ── Strony błędów ────────────────────────────────────────────── */

.error-page {
  max-width: 560px;
  margin: 0 auto;
  padding: var(--s8) var(--s4);
  text-align: center;
}
.error-code {
  font-size: 64px;
  font-weight: 700;
  color: var(--border-strong);
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.error-title { font-size: 22px; font-weight: 700; margin-top: var(--s4); }
.error-text { color: var(--text-muted); margin-top: var(--s3); }
.error-actions { margin-top: var(--s6); display: flex; gap: var(--s3); justify-content: center; flex-wrap: wrap; }

/* ── Blok kodu / SQL ──────────────────────────────────────────── */

pre.code {
  background: #16161A;
  color: #E4E4E8;
  padding: var(--s4);
  border-radius: var(--r);
  overflow-x: auto;
  font-size: 13px;
  line-height: 1.5;
}
pre.code .c { color: #9A9AA5; }

/* ── Pomocnicze ───────────────────────────────────────────────── */

.muted   { color: var(--text-muted); }
.subtle  { color: var(--text-subtle); }
.small   { font-size: 13px; }
.tiny    { font-size: 12px; }
.center  { text-align: center; }
.strong  { font-weight: 600; }
.nowrap  { white-space: nowrap; }
.mt-0 { margin-top: 0; }
.mt-3 { margin-top: var(--s3); }
.mt-4 { margin-top: var(--s4); }
.mt-5 { margin-top: var(--s5); }
.mb-3 { margin-bottom: var(--s3); }
.mb-4 { margin-bottom: var(--s4); }

.section-title {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: var(--s3);
}

/* ── Stopka ───────────────────────────────────────────────────── */

.footer {
  margin-top: var(--s7);
  padding-top: var(--s4);
  border-top: 1px solid var(--border);
  text-align: center;
  font-size: 12px;
  color: var(--text-subtle);
}
.footer a { color: var(--text-muted); }

/* ── Pasek diagnostyczny (tylko tryb dev) ─────────────────────── */

.devbar {
  position: fixed;
  bottom: 0; left: 0; right: 0;
  z-index: 999;
  display: flex;
  gap: var(--s4);
  padding: 6px var(--s4);
  font-size: 12px;
  font-family: var(--font-mono);
  color: #E4E4E8;
  background: rgba(22,22,26,.94);
  font-variant-numeric: tabular-nums;
}
.devbar strong { color: #FFF; }

/* ── Dostępność ───────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    transition-duration: .01ms !important;
  }
}

/* ── Wydruk ───────────────────────────────────────────────────── */

@media print {
  body { background: #FFF; }
  .btn, .devbar, .footer, details.reveal > summary::after { display: none !important; }
  .card, .hero { border-color: #CCC; break-inside: avoid; }
  .page { max-width: none; padding: 0; }
  details.reveal[open] > summary { border: 0; }
}

/* ════════════════════════════════════════════════════════════════
   SZKIELET APLIKACJI (od etapu 1)
   Menu boczne + górna belka. Na telefonie menu wysuwa się z lewej.
   ════════════════════════════════════════════════════════════════ */

:root {
  --topbar-h: 56px;
  --sidebar-w: 240px;
}

body.has-shell { background: var(--bg); }

.shell { min-height: 100vh; }

/* ── Górna belka ──────────────────────────────────────────────── */

.topbar {
  position: sticky;
  top: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  gap: var(--s3);
  height: var(--topbar-h);
  padding: 0 var(--s4);
  background: var(--surface);
  border-bottom: 1px solid var(--border);
}

.topbar-burger {
  display: none;
  align-items: center;
  justify-content: center;
  width: 44px; height: 44px;
  margin-left: calc(var(--s3) * -1);
  font-size: 20px;
  color: var(--text);
  background: none;
  border: 0;
  border-radius: var(--r);
  cursor: pointer;
}
.topbar-burger:hover { background: var(--surface-alt); }

.topbar-brand {
  display: flex;
  align-items: center;
  gap: var(--s2);
  font-weight: 700;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
}
.topbar-brand:hover { text-decoration: none; }
.topbar-brand-name { overflow: hidden; text-overflow: ellipsis; }

/* ── Przełącznik punktu ───────────────────────────────────────── */

.switcher { position: relative; margin-left: auto; }
.switcher > summary {
  display: flex;
  align-items: center;
  gap: 6px;
  height: 36px;
  padding: 0 var(--s3);
  font-size: 14px;
  color: var(--text);
  background: var(--surface-alt);
  border: 1px solid var(--border);
  border-radius: var(--r);
  cursor: pointer;
  list-style: none;
  white-space: nowrap;
}
.switcher > summary::-webkit-details-marker { display: none; }
.switcher > summary::after { content: "▾"; font-size: 11px; color: var(--text-muted); }
.switcher[open] > summary { border-color: var(--border-strong); }

.switcher-menu {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  z-index: 50;
  min-width: 220px;
  padding: var(--s2);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r);
  box-shadow: var(--shadow-lg);
}
.switcher-item {
  display: block;
  padding: 9px var(--s3);
  font-size: 14px;
  color: var(--text);
  border-radius: var(--r-sm);
}
.switcher-item:hover { background: var(--surface-alt); text-decoration: none; }
.switcher-item.is-current { background: var(--brand-light); color: var(--brand-dark); font-weight: 600; }

.switcher-static {
  margin-left: auto;
  font-size: 14px;
  color: var(--text-muted);
  white-space: nowrap;
}

/* ── Menu użytkownika ─────────────────────────────────────────── */

.usermenu { position: relative; }
.usermenu > summary {
  display: flex;
  align-items: center;
  gap: var(--s2);
  height: 40px;
  padding: 0 var(--s2);
  border-radius: var(--r);
  cursor: pointer;
  list-style: none;
}
.usermenu > summary::-webkit-details-marker { display: none; }
.usermenu > summary:hover { background: var(--surface-alt); }

.avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px; height: 32px;
  flex: none;
  font-size: 12px;
  font-weight: 700;
  color: var(--text-inverse);
  background: var(--brand);
  border-radius: 50%;
}
.usermenu-name { font-size: 14px; }

.usermenu-panel {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  z-index: 50;
  min-width: 220px;
  padding: var(--s2);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r);
  box-shadow: var(--shadow-lg);
}
.usermenu-head {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: var(--s2) var(--s3) var(--s3);
  border-bottom: 1px solid var(--border);
  margin-bottom: var(--s2);
}
.usermenu-item {
  display: block;
  width: 100%;
  padding: 9px var(--s3);
  font: inherit;
  font-size: 14px;
  text-align: left;
  color: var(--text);
  background: none;
  border: 0;
  border-radius: var(--r-sm);
  cursor: pointer;
}
.usermenu-item:hover { background: var(--surface-alt); text-decoration: none; }
.usermenu-item--button { color: var(--danger); }

/* ── Menu boczne ──────────────────────────────────────────────── */

.sidebar {
  position: fixed;
  top: var(--topbar-h);
  left: 0;
  bottom: 0;
  z-index: 30;
  width: var(--sidebar-w);
  padding: var(--s4) var(--s3);
  overflow-y: auto;
  background: var(--surface);
  border-right: 1px solid var(--border);
}

.nav-item {
  display: flex;
  align-items: center;
  gap: var(--s3);
  min-height: 44px;
  padding: 0 var(--s3);
  font-size: 15px;
  font-weight: 500;
  color: var(--text);
  border-radius: var(--r);
  border-left: 3px solid transparent;
  cursor: pointer;
  list-style: none;
}
.nav-item::-webkit-details-marker { display: none; }
.nav-item:hover { background: var(--surface-alt); text-decoration: none; }
.nav-item.is-active {
  background: var(--brand-light);
  border-left-color: var(--brand);
  color: var(--brand-dark);
  font-weight: 600;
}
.nav-icon { font-size: 17px; line-height: 1; width: 20px; text-align: center; }

.nav-group > summary::after {
  content: "▾";
  margin-left: auto;
  font-size: 11px;
  color: var(--text-subtle);
  transition: transform .2s ease;
}
.nav-group[open] > summary::after { transform: rotate(180deg); }

.nav-sub {
  display: block;
  min-height: 38px;
  padding: 9px var(--s3) 9px 46px;
  font-size: 14px;
  color: var(--text-muted);
  border-radius: var(--r);
}
.nav-sub:hover { background: var(--surface-alt); color: var(--text); text-decoration: none; }
.nav-sub.is-active { color: var(--brand-dark); font-weight: 600; background: var(--brand-light); }

.nav-backdrop { display: none; }

/* ── Treść ────────────────────────────────────────────────────── */

.content { margin-left: var(--sidebar-w); }
.content-inner {
  max-width: 960px;
  padding: var(--s6) var(--s5) var(--s8);
}

.page-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s4);
  flex-wrap: wrap;
  margin-bottom: var(--s2);
}
.page-head h1 { font-size: 24px; font-weight: 700; }
.page-head .muted { font-size: 14px; }

/* ── Telefon ──────────────────────────────────────────────────── */

@media (max-width: 900px) {
  .sidebar {
    transform: translateX(-100%);
    transition: transform .2s ease;
    box-shadow: var(--shadow-lg);
  }
  body.nav-open .sidebar { transform: translateX(0); }

  body.nav-open .nav-backdrop {
    display: block;
    position: fixed;
    inset: var(--topbar-h) 0 0 0;
    z-index: 20;
    background: rgba(0,0,0,.35);
  }

  .topbar-burger { display: inline-flex; }
  .content { margin-left: 0; }
  .content-inner { padding: var(--s5) var(--s4) var(--s7); }

  .usermenu-name { display: none; }
  .switcher > summary { max-width: 40vw; overflow: hidden; text-overflow: ellipsis; }
}

@media (max-width: 560px) {
  .topbar-brand-name { display: none; }
}

/* ── Pole wyboru z etykietą ───────────────────────────────────── */

.check {
  display: flex;
  align-items: flex-start;
  gap: var(--s3);
  min-height: 44px;
  padding: 6px 0;
  font-size: 15px;
  cursor: pointer;
}
.check input[type="checkbox"] {
  width: 20px; height: 20px;
  margin-top: 2px;
  flex: none;
  accent-color: var(--brand);
  cursor: pointer;
}
.check-hint { display: block; font-size: 13px; color: var(--text-muted); }

.check-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: var(--s2) var(--s4);
}

/* ── Pusty stan ───────────────────────────────────────────────── */

.empty {
  padding: var(--s7) var(--s5);
  text-align: center;
}
.empty-icon { font-size: 40px; line-height: 1; margin-bottom: var(--s4); }
.empty-title { font-size: 17px; font-weight: 600; margin-bottom: var(--s2); }
.empty-text { color: var(--text-muted); font-size: 14px; max-width: 420px; margin: 0 auto var(--s5); }

/* ══════════════════════════════════════════════════════════════════
   ETAP 2 — kartoteka produktów
   ══════════════════════════════════════════════════════════════════ */

/* ── Pasek filtrów ────────────────────────────────────────────── */

.filters {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s4);
  align-items: flex-end;
}
.filters .field { margin: 0; min-width: 140px; }
.filters .field--grow { flex: 1 1 220px; }
.filters .field--actions { display: flex; gap: var(--s2); }

/* Na telefonie filtry idą w jedną kolumnę — cztery pola obok siebie
   na szerokości 360 px to cztery pola nie do trafienia palcem.
   `flex-basis` z układu poziomego trzeba przy tym SKASOWAĆ: w kolumnie
   oś główna to wysokość, więc `flex: 1 1 220px` robiło z pola szukania
   słup wysoki na 220 px i zostawiało pod nim dziurę na pół ekranu. */
@media (max-width: 700px) {
  .filters { flex-direction: column; align-items: stretch; }
  .filters .field { min-width: 0; }
  .filters .field--grow { flex: 0 1 auto; }
  .filters .field--actions { justify-content: flex-start; }
}

/* ── Strony ───────────────────────────────────────────────────── */

.pager {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--s4);
  flex-wrap: wrap;
}
.pager-info { font-size: 14px; color: var(--text-muted); }

/* ── Zakładki na karcie produktu ──────────────────────────────── */

.tabs {
  display: flex;
  gap: var(--s1);
  border-bottom: 1px solid var(--border);
  overflow-x: auto;
  margin-bottom: var(--s5);
}
.tab {
  padding: var(--s3) var(--s4);
  font-size: 14px;
  font-weight: 500;
  color: var(--text-muted);
  text-decoration: none;
  border-bottom: 2px solid transparent;
  white-space: nowrap;
}
.tab:hover { color: var(--text); }
.tab.is-active {
  color: var(--brand-dark);
  border-bottom-color: var(--brand);
  font-weight: 600;
}

/* ── Drobiazgi w tabelach ─────────────────────────────────────── */

/* Kropka koloru kategorii — ten sam kolor wróci na wykresach od etapu 4,
   więc kategoria ma być rozpoznawalna po kolorze już tutaj. */
.dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  margin-right: 6px;
  vertical-align: baseline;
}

.row-actions { text-align: right; white-space: nowrap; }
.row-actions a { font-size: 13px; }

table.data tr.is-muted td { opacity: .55; }

/* Wcięcie podkategorii na liście kategorii. */
.indent { padding-left: var(--s5); }

/* ── Podgląd przed zapisem (import, masowa zmiana cen) ────────── */

.preview-row {
  display: flex;
  justify-content: space-between;
  gap: var(--s4);
  padding: var(--s2) 0;
  border-bottom: 1px solid var(--border);
  font-size: 14px;
}
.preview-row:last-child { border-bottom: 0; }
.preview-before { color: var(--text-muted); text-decoration: line-through; }
.preview-after  { color: var(--ok); font-weight: 600; }

/* Lista problemów w imporcie — czerwona, ale czytelna, nie krzykliwa. */
.issues { margin: 0; padding: 0; list-style: none; font-size: 14px; }
.issues li {
  padding: var(--s2) 0;
  border-bottom: 1px solid var(--border);
  display: flex;
  gap: var(--s3);
}
.issues li:last-child { border-bottom: 0; }
.issue-row {
  flex: 0 0 auto;
  font-variant-numeric: tabular-nums;
  color: var(--text-subtle);
  min-width: 72px;
}

/* ── Karta produktu: dwie kolumny na szerokim ekranie ─────────── */

.split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--s5);
}
@media (max-width: 760px) {
  .split { grid-template-columns: 1fr; }
}

/* Para etykieta-wartość na karcie produktu. */
.facts { margin: 0; }
.facts > div {
  display: flex;
  justify-content: space-between;
  gap: var(--s4);
  padding: var(--s3) 0;
  border-bottom: 1px solid var(--border);
  font-size: 14px;
}
.facts > div:last-child { border-bottom: 0; }
.facts dt { color: var(--text-muted); }
.facts dd { margin: 0; font-weight: 500; text-align: right; }

/* ══════════════════════════════════════════════════════════════════
   ETAP 3 — utargi i koszty
   ══════════════════════════════════════════════════════════════════ */

/* ── Zamknięcie dnia: pola kwot pod kciuk ─────────────────────── */

/* Ten ekran otwiera się codziennie, na telefonie, po ośmiu godzinach
   pracy. Pola są duże celowo — 56 px to wysokość, w którą trafia się
   bez celowania, a 18 px czcionki czyta się w słońcu. */
.money-field { margin-bottom: var(--s4); }

.money-input {
  position: relative;
  display: flex;
  align-items: center;
}
.money-input input {
  height: 56px;
  font-size: 20px;
  font-weight: 600;
  padding-right: 44px;
  font-variant-numeric: tabular-nums;
}
.money-suffix {
  position: absolute;
  right: var(--s4);
  color: var(--text-subtle);
  font-size: 15px;
  pointer-events: none;
}

/* Suma — jedyna liczba na ekranie, której nikt nie wpisuje. */
.suma {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s4);
  margin: var(--s5) calc(var(--s5) * -1) calc(var(--s5) * -1);
  padding: var(--s4) var(--s5);
  background: var(--brand-light);
  border-top: 1px solid var(--border);
  border-radius: 0 0 var(--r) var(--r);
}
.suma-label { font-weight: 600; color: var(--brand-dark); }
.suma-kwota {
  font-size: 26px;
  font-weight: 700;
  color: var(--brand-dark);
  font-variant-numeric: tabular-nums;
}

/* ── Ilości sprzedanych produktów ─────────────────────────────── */

.qty-row {
  display: flex;
  align-items: center;
  gap: var(--s3);
  padding: var(--s2) 0;
  border-bottom: 1px solid var(--border);
}
.qty-row:last-child { border-bottom: 0; }
.qty-name { flex: 1 1 auto; font-size: 14px; line-height: 1.3; }
.qty-name .tiny { display: block; }
.qty-input {
  flex: 0 0 84px;
  height: 44px;
  text-align: right;
  font-size: 16px;
  font-variant-numeric: tabular-nums;
}
.qty-unit {
  flex: 0 0 42px;
  font-size: 13px;
  color: var(--text-subtle);
}

/* ── Kwoty w tabelach ─────────────────────────────────────────── */

.money-cell {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  font-weight: 600;
}
.money-cell--muted { font-weight: 400; color: var(--text-muted); }
.money-cell--minus { color: var(--danger); }
.money-cell--plus  { color: var(--ok); }

/* Wiersz podsumowania pod tabelą. */
tfoot.sum td {
  border-top: 2px solid var(--border-strong);
  font-weight: 700;
  padding-top: var(--s3);
}

/* ── Paski udziału kategorii kosztów ──────────────────────────── */

.share { margin: 0; }
.share-row {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--s2) var(--s4);
  align-items: baseline;
  padding: var(--s2) 0;
}
.share-name { font-size: 14px; }
.share-value { font-variant-numeric: tabular-nums; font-weight: 600; font-size: 14px; }
.share-bar {
  grid-column: 1 / -1;
  height: 6px;
  border-radius: 3px;
  background: var(--surface-alt);
  overflow: hidden;
}
/* display:block jest tu konieczne: `.share-fill` to <span>, a element
   liniowy ignoruje wysokość — pasek był w kodzie, ale nie było go widać.
   Wyszło dopiero na zrzucie ekranu dashboardu w etapie 4. */
.share-fill { display: block; height: 100%; border-radius: 3px; }

/* ── Znaczniki statusu utargu ─────────────────────────────────── */

.status-pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 12px;
  font-weight: 600;
  padding: 3px 9px;
  border-radius: 999px;
  white-space: nowrap;
}
.status-pill--draft     { background: var(--surface-alt); color: var(--text-muted); }
.status-pill--submitted { background: var(--warn-bg);   color: var(--warn); }
.status-pill--approved  { background: var(--ok-bg);     color: var(--ok); }

/* ══════════════════════════════════════════════════════════════
   ETAP 4 — dashboard, wykresy, wybór opcji
   ══════════════════════════════════════════════════════════════ */

/* ── Wybór jednej z kilku opcji (ustawienia podatkowe) ────────── */

.choice {
  display: flex;
  gap: var(--s3);
  align-items: flex-start;
  padding: var(--s4);
  border: 1px solid var(--border);
  border-radius: var(--r);
  cursor: pointer;
  transition: border-color .12s, background .12s;
}
.choice:hover      { border-color: var(--border-strong); }
.choice--on        { border-color: var(--brand); background: var(--brand-light); }
.choice input      { margin-top: 3px; flex: 0 0 auto; width: 18px; height: 18px; accent-color: var(--brand); }
.choice-body       { display: flex; flex-direction: column; gap: var(--s1); }
.choice-title      { font-weight: 600; font-size: 15px; }
.choice-hint       { font-size: 13px; color: var(--text-muted); line-height: 1.5; }

/* ── Kafelki z liczbą i dynamiką ─────────────────────────────── */

.kpi-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(168px, 1fr));
  gap: var(--s3);
}
.kpi {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r);
  padding: var(--s4);
  display: flex;
  flex-direction: column;
  gap: var(--s1);
  min-width: 0;
}
.kpi--lead { background: var(--brand-light); border-color: var(--brand); }
.kpi-label {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .02em;
  text-transform: uppercase;
  color: var(--text-muted);
}
/* Kwota nie może się łamać w środku — „226 484 z / ł” w dwóch
   wierszach wygląda jak błąd, a nie jak liczba. Zamiast łamać,
   pozwalamy kafelkowi być szerszemu (minmax poniżej). */
.kpi-value {
  font-size: 25px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  line-height: 1.15;
  color: var(--brand-dark);
  white-space: nowrap;
}
.kpi--lead .kpi-value { font-size: 28px; }
.kpi-sub   { font-size: 12px; color: var(--text-muted); }
.kpi-delta {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 13px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.kpi-delta--up   { color: var(--ok); }
.kpi-delta--down { color: var(--danger); }
.kpi-delta--flat { color: var(--text-muted); }

/* ── Przełącznik okresu ──────────────────────────────────────── */

.periods {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
  align-items: center;
}
.period {
  font-size: 13px;
  font-weight: 600;
  padding: 6px 12px;
  border-radius: var(--r-full);
  border: 1px solid var(--border);
  color: var(--text-muted);
  background: var(--surface);
  white-space: nowrap;
}
.period:hover  { border-color: var(--border-strong); text-decoration: none; }
.period--on    { background: var(--brand); border-color: var(--brand); color: #fff; }
.period--on:hover { color: #fff; }

/* ── Wykresy (SVG rysowany po stronie serwera) ───────────────── */

.chart        { width: 100%; height: auto; display: block; }
.chart--stack { height: 22px; border-radius: 4px; overflow: hidden; }
.chart-bar  { fill: var(--brand); transition: fill .1s; }
.chart-bar:hover { fill: var(--brand-dark); }
.chart-bar--muted { fill: var(--border-strong); }
.chart-avg  { stroke: var(--danger); stroke-width: 1.5; stroke-dasharray: 4 3; fill: none; }
.chart-axis { stroke: var(--border); stroke-width: 1; }
.chart-label { font-size: 11px; fill: var(--text-muted); }
.chart-hit  { fill: transparent; }
.chart-hit:hover + .chart-tip, .chart-hit:focus + .chart-tip { opacity: 1; }
.chart-tip  { opacity: 0; pointer-events: none; transition: opacity .1s; }
.chart-tip rect { fill: var(--text); rx: 4; }
.chart-tip text { fill: var(--surface); font-size: 11px; font-weight: 600; }

/* Wykres liniowy — etap 10.
   Pasmo dopuszczalne jest TŁEM, nie dwiema kreskami: pytanie brzmi
   „czy jestem w środku”, a nie „gdzie dokładnie jest granica”. Punkt
   poza pasmem dostaje większy promień i kolor błędu, żeby dało się go
   znaleźć bez czytania osi — także na wydruku czarno-białym, gdzie
   z koloru zostaje sam rozmiar. */
.chart-band { fill: var(--ok-bg); }
.chart-line { fill: none; stroke: var(--brand); stroke-width: 2;
              stroke-linejoin: round; stroke-linecap: round; }
.chart-dot  { fill: var(--brand); }
.chart-dot--zly { fill: var(--danger); stroke: var(--surface); stroke-width: 1.5; }

.legend      { display: flex; flex-wrap: wrap; gap: var(--s3); margin-top: var(--s3); }
.legend-item { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--text-muted); }
.legend-dot  { width: 10px; height: 10px; border-radius: 3px; flex: 0 0 auto; }

/* ── Rachunek wyniku ─────────────────────────────────────────── */

.pnl { width: 100%; border-collapse: collapse; font-variant-numeric: tabular-nums; }
.pnl th, .pnl td { padding: var(--s2) 0; text-align: left; }
.pnl td.num, .pnl th.num { text-align: right; }
.pnl .pnl-group  { font-weight: 700; border-top: 1px solid var(--border); }
.pnl .pnl-item   { color: var(--text-muted); }
.pnl .pnl-item td:first-child { padding-left: var(--s4); }
.pnl .pnl-sum    { font-weight: 700; border-top: 2px solid var(--border-strong); font-size: 16px; }
.pnl .pnl-sum td { padding-top: var(--s3); }

/* ── Wydruk: jedna kartka A4, bez nawigacji ──────────────────── */

/* ── Wydruk ───────────────────────────────────────────────────
   Definition of Done etapu 4: raport dnia ma zmieścić się na JEDNEJ
   kartce A4. Pierwsza wersja wychodziła na dwie — nie przez nadmiar
   treści, tylko przez odstępy zaprojektowane pod ekran: karty miały
   po 20 px paddingu, przerwy między nimi kolejne 16, a liczba utargu
   34 px wysokości. Na papierze to wszystko jest do niczego niepotrzebne,
   więc tutaj skala jest osobna. */
@media print {
  .sidebar, .topbar, .footer, .devbar, .btn, .btn-row,
  .periods, .filters, .pager, .no-print { display: none !important; }

  /* `min-height: 100vh` na `.shell` trzyma stopkę przy dole ekranu —
     na wydruku rozciągało to stronę na drugą, PUSTĄ kartkę. */
  .shell, .content, .content-inner, .page {
    margin: 0; padding: 0; max-width: none; display: block;
    min-height: 0; height: auto;
  }
  .stack, .stack-sm { gap: 8pt; }

  .card {
    border: 1px solid #ccc;
    border-radius: 3pt;
    box-shadow: none;
    padding: 8pt 10pt;
    margin: 0 0 8pt;
    background: #fff;
    break-inside: avoid;
    page-break-inside: avoid;
  }
  .card--flush { padding: 0; }
  .card--accent { background: #fff; }
  .card-head { padding: 8pt 10pt 4pt; }

  body { background: #fff; font-size: 9.5pt; line-height: 1.35; }
  h1 { font-size: 14pt; margin: 0 0 2pt; }
  h2 { font-size: 11pt; margin: 0; }
  .section-title { font-size: 8pt; margin-bottom: 4pt; }

  /* Kwota utargu: na ekranie 34 px, na papierze wystarczy wyraźnie
     większa od reszty. */
  .card--accent p[style*="34px"],
  .card--accent p[style*="32px"] { font-size: 18pt !important; margin: 0 !important; }

  table.data th, table.data td,
  table.pnl th, table.pnl td { padding: 2.5pt 4pt; }
  table.data th, .pnl-group td { font-size: 8pt; }
  .facts { gap: 4pt 12pt; }
  .facts dt { font-size: 8pt; }
  .facts dd { font-size: 9.5pt; }
  .table-wrap { overflow: visible; }

  .print-only { display: block !important; }
  a[href]::after { content: ""; }
  a { color: #000; text-decoration: none; }

  @page { size: A4 portrait; margin: 12mm; }
}
.print-only { display: none; }

/* ══════════════════════════════════════════════════════════════
   ETAP 5 — kiosk, czas pracy
   ══════════════════════════════════════════════════════════════ */

/* ── Kiosk ────────────────────────────────────────────────────
   Ekran dotykany mokrą ręką, w pośpiechu, między klientami.
   Stąd przyciski 72 px (dokumentacja mówi „minimum 64”),
   duża typografia i brak czegokolwiek, co trzeba przeczytać. */

/* Tablet ma własny layout (app/Views/layouts/kiosk.php) — bez belki,
   bez menu, bez stopki z linkami. Tu tylko zerujemy margines strony,
   żeby ekran naprawdę sięgał krawędzi. */
.body--kiosk { margin: 0; background: var(--bg); }

.kiosk {
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  align-items: center;
  /* Środek pionu, nie góra: na tablecie 1024×768 treść przyklejona
     do górnej krawędzi zostawiała pół ekranu pustki. */
  justify-content: center;
  gap: var(--s4);
  padding: var(--s5) var(--s4) var(--s6);
  background: var(--bg);
  text-align: center;
}

/* Komunikat po odbiciu („Miłej pracy”, „Do zobaczenia”) — pasek na
   górze ekranu, znika sam po chwili. Musi być czytelny z dwóch metrów. */
.kiosk-flash { position: fixed; inset: 0 0 auto 0; z-index: 10; }
.kiosk-flash-item {
  padding: var(--s4);
  font-size: 20px;
  font-weight: 600;
  text-align: center;
  color: #fff;
  animation: kiosk-flash-znika 4s forwards;
}
.kiosk-flash-item--ok   { background: var(--ok); }
.kiosk-flash-item--blad { background: var(--danger); }

@keyframes kiosk-flash-znika {
  0%, 70%  { opacity: 1; }
  100%     { opacity: 0; visibility: hidden; }
}

@media (prefers-reduced-motion: reduce) {
  .kiosk-flash-item { animation: none; }
}

.devbar--kiosk { opacity: .5; }
/* Nagłówek dostaje `margin-bottom: auto`, bo stopka („To nie ja”)
   ma `margin-top: auto`. Bez tego jeden automatyczny margines zjadał
   całą wolną przestrzeń i treść lądowała przy górnej krawędzi mimo
   `justify-content: center`. Dwa automaty dzielą pustkę po równo. */
.kiosk-head    { display: flex; flex-direction: column; gap: 2px; margin-bottom: auto; }
.kiosk-brand   { font-size: 17px; font-weight: 700; }
.kiosk-punkt   { font-size: 14px; color: var(--text-muted); }
.kiosk-tytul   { font-size: 22px; font-weight: 600; margin-top: var(--s4); }
.kiosk-osoba h1{ font-size: 30px; margin: 0; }
.kiosk-data    { color: var(--text-muted); font-size: 15px; margin-top: 4px; }
.kiosk-drobne  { font-size: 13px; color: var(--text-muted); }

/* Kropki PIN-u */
.kiosk-kropki { display: flex; gap: var(--s4); justify-content: center; margin: var(--s5) 0; }
.kropka {
  width: 16px; height: 16px;
  border-radius: 50%;
  border: 2px solid var(--border-strong);
  background: transparent;
  transition: background .1s, border-color .1s, transform .1s;
}
.kropka--on { background: var(--brand); border-color: var(--brand); transform: scale(1.15); }

/* Klawiatura */
.kiosk-klawiatura {
  display: grid;
  grid-template-columns: repeat(3, 88px);
  gap: var(--s3);
  justify-content: center;
}
.kiosk-klawisz {
  height: 72px;
  font-size: 26px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  border-radius: var(--r);
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
  cursor: pointer;
  transition: transform .06s, background .06s;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}
.kiosk-klawisz:active { transform: scale(.94); background: var(--brand-light); }
.kiosk-klawisz--pusty { visibility: hidden; }
.kiosk-klawisz--kasuj { font-size: 22px; color: var(--text-muted); }

/* Duże przyciski akcji */
.kiosk-akcje { display: flex; flex-direction: column; gap: var(--s3); width: min(420px, 100%); }
.kiosk-btn {
  display: block;
  width: 100%;
  min-height: 76px;
  font-size: 20px;
  font-weight: 700;
  border: 0;
  border-radius: var(--r-lg);
  color: #fff;
  cursor: pointer;
  padding: var(--s4);
  transition: transform .06s, filter .1s;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}
.kiosk-btn:active         { transform: scale(.98); }
.kiosk-btn:hover          { filter: brightness(1.05); text-decoration: none; color: #fff; }
.kiosk-btn--start         { background: var(--ok); }
.kiosk-btn--przerwa       { background: var(--warn); }
.kiosk-btn--koniec        { background: var(--brand); }

/* Pasek stanu */
.kiosk-stan {
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  font-size: 15px;
  font-weight: 700;
  letter-spacing: .03em;
  padding: 8px 18px;
  border-radius: var(--r-full);
}
.kiosk-stan--praca   { background: var(--ok-bg);   color: var(--ok); }
.kiosk-stan--przerwa { background: var(--warn-bg); color: var(--warn); }
.kiosk-stan-kropka   { width: 10px; height: 10px; border-radius: 50%; background: currentColor; }
.kiosk-dzisiaj       { font-size: 17px; color: var(--text-muted); }
.kiosk-dzisiaj strong{ color: var(--text); font-variant-numeric: tabular-nums; }

.kiosk-stopka {
  margin-top: auto;
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 14px;
  padding-top: var(--s5);
}

.kiosk-blokada { max-width: 460px; margin: var(--s6) auto; display: grid; gap: var(--s3); }
.kiosk-blokada-ikona { font-size: 46px; }
.kiosk-blokada h1 { font-size: 24px; }

/* ── Moje godziny ─────────────────────────────────────────────
   Ekran otwierany z telefonu w trzy sekundy. Najważniejsza liczba
   ma być większa niż wszystko inne na stronie. */

.godziny-suma {
  font-size: 44px;
  font-weight: 700;
  line-height: 1.05;
  color: var(--brand-dark);
  font-variant-numeric: tabular-nums;
}
.godziny-podpis { color: var(--text-muted); font-size: 15px; }

.dzien-row {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: var(--s2) var(--s3);
  align-items: baseline;
  padding: var(--s3) 0;
  border-bottom: 1px solid var(--border);
}
.dzien-row:last-child { border-bottom: 0; }
.dzien-data  { font-weight: 600; font-variant-numeric: tabular-nums; min-width: 84px; text-align: left; }
.dzien-czas  { color: var(--text-muted); font-size: 14px; font-variant-numeric: tabular-nums; }
.dzien-suma  { font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }
.dzien-row--wolne .dzien-suma { color: var(--text-subtle); font-weight: 400; }

.sesja-znacznik {
  display: inline-block;
  font-size: 11px;
  font-weight: 600;
  padding: 2px 7px;
  border-radius: var(--r-full);
  background: var(--warn-bg);
  color: var(--warn);
  white-space: nowrap;
}

@media (max-width: 400px) {
  .kiosk-klawiatura { grid-template-columns: repeat(3, 30vw); }
  .kiosk-osoba h1   { font-size: 26px; }
  .godziny-suma     { font-size: 38px; }
}

/* ══════════════════════════════════════════════════════════════
   ETAP 6 — grafik i nieobecności
   ══════════════════════════════════════════════════════════════ */

/* ── Nawigacja tygodnia ──────────────────────────────────────── */

.tydzien-nawigacja {
  display: flex;
  gap: var(--s2);
  flex-wrap: wrap;
}

.page-head-akcje { display: flex; gap: var(--s2); flex-wrap: wrap; }

/* ── Siatka grafiku ──────────────────────────────────────────────
   Siedem kolumn plus nazwiska. Na telefonie tabela się nie zwija —
   przewija się w poziomie wewnątrz .table-wrap, bo grafik bez
   sąsiednich dni przestaje być grafikiem. Kolumna z nazwiskami
   zostaje przyklejona do lewej krawędzi, inaczej po przewinięciu
   nie wiadomo, czyj to wiersz. */

table.grafik {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
  min-width: 720px;
}
table.grafik th, table.grafik td {
  border: 1px solid var(--border);
  padding: var(--s2);
  vertical-align: top;
}
.grafik-osoba {
  position: sticky;
  left: 0;
  z-index: 2;
  background: var(--surface);
  text-align: left;
  min-width: 150px;
  font-weight: 600;
}
.grafik-osoba a { color: inherit; }
.grafik-osoba .tiny { display: block; font-weight: 400; }

.grafik-dzien { text-align: center; width: 12%; background: var(--surface-alt); }
.grafik-dzien--dzis { background: var(--brand-light); }
.grafik-dzien-nazwa { display: block; font-weight: 700; text-transform: uppercase; font-size: 12px; }
.grafik-dzien-data  { display: block; font-size: 12px; color: var(--text-muted); font-weight: 400; }

.grafik-komorka { min-height: 52px; }
.grafik-komorka--urlop { background: var(--warn-bg); }

/* Zmiana w komórce. `position: relative` jest potrzebne pod krzyżyk
   usuwania, który siedzi w rogu — bez niego wyskakiwałby poza kratkę. */
.grafik-zmiana {
  position: relative;
  background: var(--surface-alt);
  border-left: 3px solid var(--brand);
  border-radius: 4px;
  padding: 4px 18px 4px 6px;
  margin-bottom: 4px;
  line-height: 1.3;
}
.grafik-zmiana--confirmed { border-left-color: var(--ok); background: var(--ok-bg); }
.grafik-zmiana--declined  { border-left-color: var(--danger); background: var(--danger-bg); }
.grafik-godziny { font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; }
.grafik-zmiana .tiny { display: block; }
.grafik-status { position: absolute; top: 3px; right: 4px; font-size: 12px; color: var(--ok); }
.grafik-status--nie { color: var(--danger); }

.grafik-usun {
  position: absolute;
  bottom: 2px;
  right: 2px;
  border: 0;
  background: none;
  color: var(--text-subtle);
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
  padding: 2px 4px;
}
.grafik-usun:hover { color: var(--danger); }

.grafik-urlop {
  display: block;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  color: var(--warn);
  margin-bottom: 3px;
}

/* Przycisk „+” pokazuje się dopiero po najechaniu na komórkę —
   siedem razy osiem widocznych plusów zmieniłoby grafik w tablicę
   przycisków, na której nie widać godzin. Na dotyku hovera nie ma,
   więc tam jest widoczny zawsze. */
.grafik-dodaj {
  display: block;
  width: 100%;
  border: 1px dashed var(--border);
  background: none;
  color: var(--text-subtle);
  border-radius: 4px;
  padding: 2px;
  cursor: pointer;
  opacity: 0;
  transition: opacity .12s;
}
.grafik-komorka:hover .grafik-dodaj { opacity: 1; }
.grafik-dodaj:hover { border-color: var(--brand); color: var(--brand); }

@media (hover: none) {
  .grafik-dodaj { opacity: .6; }
}

.grafik-podsumowanie {
  text-align: center;
  background: var(--surface-alt);
  font-variant-numeric: tabular-nums;
}
.grafik-podsumowanie strong { display: block; font-size: 16px; }
.grafik-podsumowanie .tiny { display: block; color: var(--text-muted); }
.grafik-podsumowanie--pusto { background: var(--danger-bg); color: var(--danger); }

/* ── Widok miesiąca ──────────────────────────────────────────── */

table.grafik--miesiac { min-width: 900px; font-size: 12px; }
table.grafik--miesiac th, table.grafik--miesiac td { padding: 2px 3px; }
.grafik-dzien-maly { text-align: center; width: 26px; background: var(--surface-alt); }
.grafik-dzien-maly span { display: block; line-height: 1.2; }
.grafik-dzien-maly--weekend { background: var(--brand-light); }
.grafik-kratka {
  text-align: center;
  font-variant-numeric: tabular-nums;
  min-width: 26px;
}
.grafik-kratka span { display: block; font-weight: 600; }
.grafik-kratka--urlop { background: var(--warn-bg); color: var(--warn); }
/* Urlop i zmiana w jednej kratce — konflikt do rozwiązania przez człowieka. */
.grafik-kratka--konflikt { background: var(--danger-bg); color: var(--danger); }

/* ── Narzędzia tygodnia: kopiowanie i szablony ──────────────── */

.grafik-narzedzia {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: var(--s4);
}
.grafik-narzedzie label { display: block; font-size: 13px; font-weight: 600; margin-bottom: var(--s2); }
.grafik-narzedzie input {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  font: inherit;
  margin-bottom: var(--s2);
}
.grafik-narzedzie .btn { width: 100%; justify-content: center; }
.grafik-narzedzie p { margin-top: var(--s2); }

.szablony { margin-top: var(--s4); border-top: 1px solid var(--border); padding-top: var(--s3); }
.szablon {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s3);
  align-items: center;
  justify-content: space-between;
  padding: var(--s2) 0;
  border-bottom: 1px solid var(--border);
}
.szablon:last-child { border-bottom: 0; }
.szablon .tiny { display: block; color: var(--text-muted); }
.szablon-akcje { display: flex; gap: var(--s2); align-items: center; }

.btn--maly { min-height: 34px; padding: 4px 12px; font-size: 13px; }

.link-usun {
  border: 0;
  background: none;
  color: var(--text-subtle);
  font-size: 13px;
  text-decoration: underline;
  cursor: pointer;
  padding: 0;
}
.link-usun:hover { color: var(--danger); }

/* ── Mój grafik (telefon) ───────────────────────────────────── */

.grafik-duze {
  font-size: 40px;
  font-weight: 700;
  line-height: 1.05;
  color: var(--brand-dark);
  font-variant-numeric: tabular-nums;
}
.grafik-podpis { color: var(--text-muted); font-size: 14px; margin-top: var(--s2); }

.grafik-dzien-wiersz {
  display: flex;
  gap: var(--s3);
  padding: var(--s3) 0;
  border-bottom: 1px solid var(--border);
}
.grafik-dzien-wiersz:last-child { border-bottom: 0; }
.grafik-dzien-wiersz--dzis { background: var(--brand-light); margin: 0 calc(-1 * var(--s4)); padding-inline: var(--s4); }
.grafik-dzien-etykieta { flex: 0 0 92px; font-variant-numeric: tabular-nums; }
.grafik-dzien-etykieta .tiny { display: block; }
.grafik-dzien-tresc { flex: 1 1 auto; min-width: 0; }
.grafik-moja-zmiana { margin-bottom: var(--s2); }
.grafik-moja-zmiana:last-child { margin-bottom: 0; }
.grafik-moja-zmiana .tiny { margin-left: 4px; }

.grafik-decyzja { display: flex; gap: var(--s3); align-items: center; margin-top: var(--s2); flex-wrap: wrap; }
.grafik-nie-moge summary {
  cursor: pointer;
  font-size: 13px;
  color: var(--text-muted);
  text-decoration: underline;
}
.grafik-nie-moge form { margin-top: var(--s2); display: grid; gap: var(--s2); }
.grafik-nie-moge input {
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  font: inherit;
  width: 100%;
}

/* Karta na ekranie „Dzisiaj” */
.grafik-karta-wiersz { padding: 3px 0; font-size: 14px; }
.grafik-karta-dzien { display: inline-block; min-width: 78px; color: var(--text-muted); }

/* ── Znaczniki statusów ─────────────────────────────────────── */

.znacznik {
  display: inline-block;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .02em;
  padding: 2px 7px;
  border-radius: 999px;
  background: var(--surface-alt);
  color: var(--text-muted);
  white-space: nowrap;
}
.znacznik--ok, .znacznik--approved   { background: var(--ok-bg);     color: var(--ok); }
.znacznik--uwaga, .znacznik--rejected { background: var(--danger-bg); color: var(--danger); }
.znacznik--urlop, .znacznik--requested { background: var(--warn-bg);  color: var(--warn); }
.znacznik--cancelled { opacity: .7; }

/* ── Wnioski o wolne ────────────────────────────────────────── */

.wniosek { padding: var(--s4) 0; border-bottom: 1px solid var(--border); }
.wniosek:last-child { border-bottom: 0; }
.wniosek-glowa {
  display: flex;
  gap: var(--s3);
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
}
.wniosek p { margin-top: var(--s2); }
.wniosek-kolizje {
  margin-top: var(--s3);
  padding: var(--s3);
  background: var(--warn-bg);
  border-radius: var(--r-sm);
}
.wniosek-kolizje .tiny { display: inline-block; margin-right: var(--s3); font-variant-numeric: tabular-nums; }
.wniosek-decyzja {
  display: flex;
  gap: var(--s2);
  flex-wrap: wrap;
  align-items: center;
  margin-top: var(--s3);
}
.wniosek-decyzja input {
  flex: 1 1 220px;
  padding: 8px 12px;
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  font: inherit;
}

.zakladki { display: flex; gap: var(--s2); flex-wrap: wrap; }
.zakladka {
  padding: 6px 14px;
  border-radius: 999px;
  border: 1px solid var(--border);
  font-size: 14px;
  color: var(--text-muted);
  text-decoration: none;
}
.zakladka:hover { background: var(--surface-alt); text-decoration: none; }
.zakladka--aktywna { background: var(--brand); border-color: var(--brand); color: #fff; }

.pola-obok { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s3); }
.field--waska { min-width: 110px; }
.card-head-liczba { font-size: 14px; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.pusto { padding: var(--s5); text-align: center; color: var(--text-muted); }
.wiersz--uwaga { background: var(--danger-bg); }

/*
 | Wiersz POPRAWIONY po fakcie — wpis w rejestrze HACCP, który ktoś
 | skorygował. Musi być widoczny, bo inspektor patrzy właśnie na to:
 | nie na to, czy wszystko się zgadza, tylko czy poprawki są widoczne
 | jako poprawki. Wpis zmieniony po cichu jest gorszy niż jego brak.
 */
.wiersz--skorygowany { background: var(--warn-bg); }

/*
 | Wiersz WYŁĄCZONY — pozycja cennika, której już się nie kupuje.
 | Zostaje na ekranie, bo stare zamówienia się do niej odwołują,
 | ale ma nie mylić się z tym, co obowiązuje dziś.
 */
.wiersz--wylaczony td { color: var(--text-subtle); }
.wiersz--wylaczony strong { font-weight: 500; }

/*
 | `.field-label` to etykieta pola, które nie ma jednego `<input>`,
 | więc `<label for>` nie miałoby na co wskazywać — grupa radiobuttonów
 | („jak pilne”), zestaw kwadracików („dni dostaw”). Wygląda dokładnie
 | jak `.field label`, bo dla czytającego to jest to samo.
 */
.field-label {
  display: block;
  font-size: 13px;
  font-weight: 500;
  color: var(--text-muted);
  margin-bottom: 5px;
}

/* ── Druk grafiku miesiąca ──────────────────────────────────── */

@media print {
  table.grafik--miesiac { min-width: 0; font-size: 9px; }
  .table-wrap { overflow: visible; }
  .grafik-osoba { position: static; }
}

/* Zmiana stojąca w grafiku mimo zaakceptowanego wolnego. Pracownik ma
   to zobaczyć u siebie, nie dowiedzieć się w sobotę rano. */
.grafik-kolizja {
  background: var(--warn-bg);
  color: var(--warn);
  border-radius: var(--r-sm);
  padding: 6px 8px;
  margin-bottom: var(--s2);
  line-height: 1.4;
}

/* ══════════════════════════════════════════════════════════════
   ETAP 7 — magazyn
   ══════════════════════════════════════════════════════════════ */

/* Światła stanu. Cztery stany, bo czwarty mówi co innego niż pozostałe:
   ujemny to nie „mało towaru”, tylko „dane się nie zgadzają”. */
.stan--ok     { color: var(--ok); }
.stan--nisko  { color: var(--warn); }
.stan--brak   { color: var(--danger); }
.stan--ujemny { color: var(--danger); font-weight: 700; }
.stan--ok, .stan--nisko, .stan--brak, .stan--ujemny { font-variant-numeric: tabular-nums; }
td .stan--ok + .tiny,
td .stan--nisko + .tiny,
td .stan--brak + .tiny,
td .stan--ujemny + .tiny { display: block; }

.lista-braki--ujemne .stan--ujemny { font-weight: 700; }

/* Korekta wprost w wierszu tabeli — złożona do jednego słowa.
   Rozwinięta w każdym wierszu rozpychała kolumnę poza kartę (przycisk
   lądował poza ekranem), a po zawinięciu robiła z siedmiu produktów
   stronę na dwa ekrany. Tu jest jedno słowo do kliknięcia i formularz
   pod nim — bez grama JavaScriptu. */
.korekta-blok > summary {
  cursor: pointer;
  font-size: 13px;
  color: var(--brand);
  list-style: none;
  padding: 2px 0;
  white-space: nowrap;
}
.korekta-blok > summary::-webkit-details-marker { display: none; }
.korekta-blok > summary::before { content: "✎ "; }
.korekta-blok > summary:hover { text-decoration: underline; }
.korekta-blok[open] > summary { color: var(--text-muted); margin-bottom: 4px; }

.korekta {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  align-items: center;
  max-width: 190px;
}
.korekta input {
  width: 100%;
  padding: 5px 8px;
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  font: inherit;
  font-size: 13px;
}
.korekta .btn { width: 100%; }

/* Znaczniki rodzajów ruchu — kolor niesie kierunek, nie tylko nazwę. */
.znacznik--delivery,
.znacznik--transfer_in,
.znacznik--production  { background: var(--ok-bg);     color: var(--ok); }
.znacznik--sale,
.znacznik--transfer_out { background: var(--info-bg);   color: var(--text-muted); }
.znacznik--waste       { background: var(--danger-bg); color: var(--danger); }
.znacznik--correction,
.znacznik--count       { background: var(--warn-bg);   color: var(--warn); }

/* Lista braków na ekranie „Dzisiaj”. */
.lista-braki { margin: var(--s2) 0 0; padding-left: var(--s4); font-size: 14px; }
.lista-braki li { margin-bottom: 2px; }

/* ══════════════════════════════════════════════════════════════
   ETAP 9 — inwentaryzacja
   ══════════════════════════════════════════════════════════════ */

/* Ekran liczenia. Ten sam layout co kiosk (bez belki, bez menu,
   bez stopki), ale inny cel: kiosk czyta się z dwóch metrów, ten
   z odległości ręki — za to jedną ręką, bo w drugiej jest chochla.

   Stąd rozmiary: pole na ilość jest największym elementem na ekranie,
   a przyciski mają wysokość, w którą trafia się kciukiem bez patrzenia. */
.liczenie {
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  background: var(--bg);
}

/* Pasek postępu na samej górze — jedyna rzecz, która mówi „ile jeszcze”,
   bez zabierania miejsca treści. */
.liczenie-pasek { height: 4px; background: var(--border); flex: none; }
.liczenie-postep { height: 100%; background: var(--brand); transition: width .2s ease; }

.liczenie-naglowek {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--s3) var(--s4);
  flex: none;
}
.liczenie-licznik {
  font-size: 14px;
  font-weight: 600;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
.liczenie-wyjscie { font-size: 14px; color: var(--text-muted); }

.liczenie-tresc {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: var(--s4) var(--s4) var(--s6);
  max-width: 520px;
  width: 100%;
  margin: 0 auto;
  text-align: center;
}

.liczenie-kategoria {
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--text-subtle);
  margin: 0 0 var(--s2);
}
.liczenie-produkt {
  font-size: 30px;
  line-height: 1.15;
  margin: 0 0 var(--s2);
  overflow-wrap: anywhere;   /* „Lody gałka czekoladowa premium” nie może wyjść poza ekran */
}
.liczenie-sku { font-size: 13px; color: var(--text-subtle); margin: 0 0 var(--s5); }

/* Pole na ilość: największy element ekranu. Jednostka stoi obok, nie
   w środku pola — inaczej znikałaby pod wpisywaną liczbą.

   Pole NIE rozciąga się na całą szerokość: przy `width:100%` na telefonie
   spychało jednostkę na samą krawędź ekranu, gdzie wyglądała na przypadkowy
   znak, a nie na „litry”. Para liczba–jednostka ma się czytać jako jedno. */
.liczenie-pole {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: var(--s2);
  margin: var(--s5) 0;
}
.liczenie-pole input {
  flex: 0 1 240px;
  min-width: 0;
  padding: var(--s3) var(--s4);
  font-size: 40px;
  font-weight: 700;
  text-align: center;
  font-variant-numeric: tabular-nums;
  border: 2px solid var(--border-strong);
  border-radius: var(--r);
  background: var(--surface);
  color: var(--text);
}
.liczenie-pole input:focus {
  outline: none;
  border-color: var(--brand);
  box-shadow: 0 0 0 4px var(--brand-light);
}
.liczenie-jednostka {
  font-size: 24px;
  font-weight: 700;
  color: var(--text);
  flex: none;
}

.liczenie-uwaga {
  font-size: 13px;
  color: var(--warn);
  margin: 0 0 var(--s4);
}

.liczenie-przyciski {
  display: flex;
  gap: var(--s3);
  margin-top: var(--s4);
}
.liczenie-przyciski .btn { flex: 1; }
/* „Dalej” szersze od „Pomiń”: pomijanie ma być możliwe, ale nie
   równie kuszące co policzenie. */
.liczenie-przyciski .btn:last-child { flex: 2; }

.btn--duzy {
  padding: var(--s4) var(--s4);
  font-size: 17px;
  min-height: 56px;
}

.liczenie-podpowiedz {
  font-size: 13px;
  color: var(--text-muted);
  margin: var(--s5) 0 0;
}

/* ══════════════════════════════════════════════════════════════
   ETAP 10 — temperatury i alarmy
   ══════════════════════════════════════════════════════════════ */

/* ── Wpis pomiaru ─────────────────────────────────────────────
   Definition of Done: cztery temperatury w mniej niż 20 sekund.
   Wiersz jest siatką „opis | pole”, żeby liczby stały w jednej
   kolumnie — oko przeskakuje wtedy po pionie, zamiast szukać
   pola za każdym razem w innym miejscu. */

.pomiary { display: flex; flex-direction: column; gap: var(--s2); }

.pomiar {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: var(--s3);
  padding: var(--s3) 0;
  border-bottom: 1px solid var(--border);
}
.pomiar:last-child { border-bottom: 0; }

.pomiar-opis { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.pomiar-opis label { font-weight: 600; font-size: 15px; margin: 0; }

.pomiar-pole { display: flex; align-items: center; gap: var(--s2); }
.pomiar-pole input {
  /* Stała szerokość, nie 100%: para liczba–jednostka ma się czytać
     jako jedno. Ta sama poprawka co przy ekranie liczenia w etapie 9,
     gdzie rozciągnięte pole spychało „l” na krawędź telefonu. */
  flex: 0 0 108px;
  min-width: 0;
  padding: var(--s3);
  font-size: 22px;
  font-weight: 700;
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.pomiar-jednostka { font-size: 15px; font-weight: 600; color: var(--text-muted); flex: none; }

/* Urządzenie czekające na wyjaśnienie: pole naprawcze zajmuje całą
   szerokość wiersza, bo to zdanie, a nie liczba. */
.pomiar--zly { background: var(--danger-bg); border-radius: var(--r-sm); padding: var(--s3); }
.pomiar--zly .pomiar-pole input { border-color: var(--danger); }
.pomiar-akcja { grid-column: 1 / -1; }
.pomiar-akcja label { font-size: 13px; font-weight: 600; display: block; margin-bottom: 4px; }

.pomiary-zapisz { width: 100%; margin-top: var(--s4); }

@media (max-width: 640px) {
  .pomiar { grid-template-columns: 1fr auto; gap: var(--s2); }
  .pomiar-pole input { flex-basis: 92px; font-size: 20px; }
}

/* ── Centrum alarmów ──────────────────────────────────────────
   Alarm nie jest wierszem tabeli, tylko zdaniem: co się stało,
   gdzie, kiedy i co z tym zrobić. Dlatego blok, nie kolumny. */

.alarm { border-left: 4px solid var(--border-strong); }
.alarm--critical { border-left-color: var(--danger); }
.alarm--warning  { border-left-color: var(--warn); }
.alarm--info     { border-left-color: var(--info); }
.alarm--zamkniety { opacity: .62; }

.alarm-glowa { display: flex; align-items: flex-start; gap: var(--s3); }
.alarm-ikona { font-size: 18px; line-height: 1.4; flex: none; }
.alarm-tresc { flex: 1; min-width: 0; }
.alarm-tresc h2 { font-size: 16px; margin: 0 0 2px; }
.alarm-waga { flex: none; }
.alarm-opis { margin: var(--s3) 0 0; }

.alarm-akcje {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s2);
  margin-top: var(--s3);
}
.alarm-akcje form { margin: 0; }
.alarm-akcje .korekta-blok { flex-basis: 100%; }

.lista-zwarta { margin: var(--s2) 0 0; padding-left: var(--s4); }
.lista-zwarta li { font-size: 13px; margin-bottom: 2px; }

/* ── Raport HACCP ─────────────────────────────────────────────
   Kontrola szuka DZIUR, nie liczb. Pusta kratka musi być widoczna
   z odległości metra — także po wydrukowaniu na czarno-białej
   drukarce, gdzie z koloru nie zostaje nic. */

.haccp { font-variant-numeric: tabular-nums; }
.haccp-dzien { white-space: nowrap; font-weight: 600; }
.haccp-brak {
  display: inline-block;
  min-width: 34px;
  color: var(--danger);
  font-weight: 700;
}
.haccp-zly {
  font-weight: 700;
  color: var(--danger);
  text-decoration: underline;
  text-underline-offset: 2px;
}

@media print {
  /* Siatka miesiąca ma zmieścić się na jednej kartce razem z nagłówkiem
     i podsumowaniem: trzydzieści jeden wierszy przy odstępach z ekranu
     wychodzi na dwie strony. */
  .haccp th, .haccp td { padding: 1.2pt 3pt; font-size: 8pt; }
  .haccp-brak { color: #000; }
  .haccp-zly  { color: #000; text-decoration: underline; }
  .kpi-grid { gap: 6pt; }
  .kpi-value { font-size: 12pt !important; }
  .kpi-label, .kpi-sub { font-size: 7.5pt; }
}

/* ══════════════════════════════════════════════════════════════
   ETAP 11 — maszyny, serwisy, awarie
   ══════════════════════════════════════════════════════════════ */

/* ── Priorytet zgłoszenia ─────────────────────────────────────
   Radia, nie lista rozwijana: cztery opcje i jedno dotknięcie.
   Zgłasza pracownik w chwili, gdy maszyna właśnie stanęła —
   każde dodatkowe dotknięcie to sekundy, których nie ma. */

.priorytety { display: flex; flex-wrap: wrap; gap: var(--s2); }

.priorytet {
  flex: 1 1 120px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: var(--s3) var(--s2);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  cursor: pointer;
  font-size: 14px;
  text-align: center;
  background: var(--surface);
  transition: border-color .1s, background .1s;
}
.priorytet input { margin: 0; }
.priorytet:hover { background: var(--surface-alt); }

/* Zaznaczony priorytet niesie kolor swojej wagi — żeby po dotknięciu
   „krytyczny” było widać, że to nie jest zwykły wybór z listy. */
.priorytet:has(input:checked) { border-color: var(--brand); background: var(--brand-light); font-weight: 600; }
.priorytet--high:has(input:checked)     { border-color: var(--warn);   background: var(--warn-bg); }
.priorytet--critical:has(input:checked) { border-color: var(--danger); background: var(--danger-bg); }

/* ── Zdjęcie z miejsca awarii ─────────────────────────────────
   Ograniczone wysokością, nie szerokością: zdjęcie z telefonu jest
   pionowe i przy `width:100%` zajmowałoby cały ekran, spychając
   obieg naprawy pod trzy przewinięcia. */
.awaria-zdjecie {
  max-width: 100%;
  max-height: 320px;
  border-radius: var(--r-sm);
  border: 1px solid var(--border);
  display: block;
}

@media (max-width: 640px) {
  .priorytet { flex-basis: calc(50% - var(--s2)); }
  .awaria-zdjecie { max-height: 240px; }
}

@media print {
  .priorytety, .awaria-zdjecie { display: none; }
}

/* ══════════════════════════════════════════════════════════════
   ETAP 12 — checklisty, HACCP, daty ważności
   ══════════════════════════════════════════════════════════════ */

/* ── Pasek postępu listy ──────────────────────────────────────
   Postęp jest tu jedyną informacją, której nie da się odczytać
   z samych ptaszków bez liczenia — dlatego stoi nad listą,
   a nie pod nią. */
.lista-postep { margin-bottom: var(--s4); }

.lista-pasek {
  height: 8px;
  background: var(--surface-alt);
  border: 1px solid var(--border);
  border-radius: 999px;
  overflow: hidden;
}
.lista-pasek--maly { height: 6px; width: 84px; display: inline-block; vertical-align: middle; }

.lista-pasek-wnetrze {
  display: block;
  height: 100%;
  background: var(--brand);
  transition: width .2s ease;
}

.lista-licznik {
  display: flex;
  align-items: center;
  gap: var(--s2);
  flex-wrap: wrap;
  margin: var(--s2) 0 0;
}

/* ── Sama checklista ──────────────────────────────────────────
   Pozycja to wiersz, nie karta: osiem kart z ramkami zamieniłoby
   listę w ścianę prostokątów i wymusiło przewijanie tam, gdzie
   ma się zmieścić wszystko naraz. */
.checklista { list-style: none; margin: 0; padding: 0; }

.checklista-poz {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--s3);
  padding: var(--s3) 0;
  border-bottom: 1px solid var(--border);
  flex-wrap: wrap;
}
.checklista-poz:last-child { border-bottom: 0; }

/* Odhaczone zostaje na miejscu i blednie. Znikanie skracałoby listę,
   ale odbierało jedyną rzecz, po której widać postęp — i psuło
   cofnięcie pomyłki. */
.checklista-poz--zrobiona .checklista-etykieta {
  color: var(--text-muted);
  text-decoration: line-through;
  text-decoration-color: var(--border-strong);
}

.checklista-tresc { display: flex; gap: var(--s3); align-items: flex-start; flex: 1 1 240px; }
.checklista-ptaszek { font-size: 20px; line-height: 1.2; flex: 0 0 auto; }
.checklista-etykieta { margin: 0; font-weight: 500; }

.checklista-akcja {
  display: flex;
  align-items: center;
  gap: var(--s2);
  flex-wrap: wrap;
  flex: 0 1 auto;
}
.checklista-pole { display: flex; flex-direction: column; gap: 2px; }
.checklista-pole input { min-width: 120px; }

/* Przycisk odhaczenia jest duży, bo trafia się w niego kciukiem,
   często w rękawiczce jednorazowej. 44 px to minimum, poniżej
   którego trafienie przestaje być pewne. */
.btn--odhacz { min-height: 44px; min-width: 104px; }

.checklista-zdjecie {
  max-width: 100%;
  max-height: 180px;
  margin-top: var(--s2);
  border-radius: var(--r-sm);
  border: 1px solid var(--border);
  display: block;
}

/* ── Lista list (ekran „na dziś”) ─────────────────────────────── */
.listy { list-style: none; margin: 0; padding: 0; }

.lista-pozycja { padding: var(--s3) 0; border-bottom: 1px solid var(--border); }
.lista-pozycja:last-child { border-bottom: 0; }

.lista-link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s3);
  text-decoration: none;
  color: inherit;
  flex-wrap: wrap;
}
.lista-link:hover .lista-nazwa strong { color: var(--brand); }

.lista-nazwa { display: flex; flex-direction: column; gap: 2px; }
.lista-stan   { display: flex; align-items: center; gap: var(--s2); }
.lista-pozycja--zrobiona .lista-nazwa strong { color: var(--text-muted); font-weight: 500; }

/* ── Rejestr i raport HACCP ───────────────────────────────────── */
.haccp-typy {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: var(--s3);
}

.haccp-typ {
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  padding: var(--s3);
  background: var(--surface);
}
.haccp-typ strong { display: block; }
.haccp-typ--pusty { border-style: dashed; background: var(--surface-alt); }

/* Sekcja raportu, której nie udało się zebrać. Nie chowamy jej:
   dokument dla sanepidu ma NAZWAĆ to, czego w nim nie ma, bo cicha
   nieobecność czyta się jak „nikt tego nie robił”. */
.haccp-brak {
  border: 1px dashed var(--warn-border);
  background: var(--warn-bg);
  color: var(--warn);
  border-radius: var(--r-sm);
  padding: var(--s3);
}

/* ── Daty ważności ────────────────────────────────────────────── */
.partia-dni {
  display: inline-block;
  min-width: 3.5em;
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.partia--dzis    { color: var(--danger); font-weight: 600; }
.partia--wkrotce { color: var(--warn);   font-weight: 600; }
.partia--po      { color: var(--danger); font-weight: 700; }

@media (max-width: 640px) {
  .checklista-akcja { width: 100%; }
  .btn--odhacz { flex: 1 1 auto; }
  .checklista-pole input { min-width: 0; width: 100%; }
  .checklista-pole { flex: 1 1 120px; }
}

@media print {
  .checklista-akcja, .lista-pasek { display: none; }
}

/* ══════════════════════════════════════════════════════════════════
   ETAP 12–13 — formularze, zakupy, wydruki dokumentów

   Ten blok powstał po audycie, który porównał KAŻDĄ klasę użytą
   w widokach z klasami zdefiniowanymi w tym pliku. Wyszło 25 klas
   bez ani jednej reguły — w tym `form-grid` i `field--wide` używane
   od etapu 12 w sześciu plikach. Ekrany wyglądały „prawie dobrze”,
   bo pola i tak układają się jedno pod drugim, i dlatego przeszły
   przegląd na zrzutach ekranu.

   Audyt siedzi teraz w `testy/test_css.sh` i jest puszczany razem
   z resztą testów, żeby następna taka klasa nie dożyła paczki.
   ══════════════════════════════════════════════════════════════════ */

/* ── Siatka formularza ─────────────────────────────────────────── */
.form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 14px 18px;
  align-items: start;
}

/* Pole na całą szerokość siatki — opis, uwagi, adres. */
.field--wide { grid-column: 1 / -1; }

/*
 | Pole z „ptaszkiem”: etykieta MUSI być klikalna razem z kwadracikiem,
 | bo na telefonie sam kwadracik ma 16 px i trafia się w niego co drugi
 | raz. Stąd `<label>` obejmujący całość i powiększone pole dotyku.
 */
.field--checkbox {
  display: flex;
  align-items: flex-start;
  gap: 10px;
}
.field--checkbox input[type="checkbox"] {
  width: 20px;
  height: 20px;
  margin-top: 2px;
  flex: 0 0 auto;
}
.field--checkbox label { cursor: pointer; margin: 0; }

/* ── Przyciski: nazwy dopisane do istniejących ─────────────────── */
/*
 | `.btn` samo w sobie JEST przyciskiem głównym (marka na wypełnieniu),
 | ale od etapu 12 widoki piszą `btn btn--primary`, bo tak czyta się
 | wprost. Klasa nic nie zmienia i istnieje po to, żeby nie znaczyła
 | nic PRZYPADKIEM — deklaracja jest tu jawna zamiast milczącego
 | polegania na tym, że nieznana klasa jest nieszkodliwa.
 */
.btn--primary { /* celowo bez własnych reguł — patrz komentarz wyżej */ }

.btn--danger {
  background: var(--danger);
  border-color: var(--danger);
  color: #fff;
}
.btn--danger:hover { filter: brightness(.92); background: var(--danger); }

/*
 | Akcja, która wygląda jak odnośnik, a nie jak przycisk: „pokaż więcej”,
 | „wyczyść filtr”. Używana tam, gdzie przycisk sugerowałby wagę,
 | której ta czynność nie ma.
 */
.btn-link {
  background: none;
  border: 0;
  padding: 0;
  min-height: 0;
  color: var(--brand);
  font: inherit;
  text-decoration: underline;
  cursor: pointer;
}
.btn-link:hover { color: var(--brand-dark); background: none; }

/* ── Odstępy ───────────────────────────────────────────────────── */
.mt-2 { margin-top: 12px; }

/* ── Sekcja rozwijana ──────────────────────────────────────────── */
/*
 | `<details class="rozwijane">` — rzeczy potrzebne rzadko: usunięcie
 | dostawcy, historia cen, dane do przelewu. Zwinięte domyślnie, żeby
 | ekran pokazywał to, po co się na niego wchodzi.
 */
.rozwijane {
  border-top: 1px solid var(--border);
  margin-top: 16px;
  padding-top: 12px;
}
.rozwijane > summary {
  cursor: pointer;
  font-size: 13px;
  color: var(--text-muted);
  list-style: none;
}
.rozwijane > summary::-webkit-details-marker { display: none; }
.rozwijane > summary::after { content: " ▾"; }
.rozwijane[open] > summary::after { content: " ▴"; }
.rozwijane > summary:hover { color: var(--text); }
.rozwijane-tresc { padding-top: 12px; }

/* ── Pole ilości w tabeli ──────────────────────────────────────── */
/*
 | Wąskie pole liczbowe wewnątrz wiersza tabeli — propozycja zamówienia
 | i przyjęcie dostawy. Wyrównane do prawej i tabularne, żeby kolumna
 | liczb czytała się jak kolumna, a nie jak lista.
 |
 | `min-width` jest po to, żeby na telefonie pole nie skurczyło się
 | do trzech znaków: człowiek musi widzieć całe „12,500”, zanim
 | zdecyduje, czy je poprawić.
 */
.pole-ilosc {
  width: 100%;
  min-width: 84px;
  max-width: 120px;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* ── Tabela propozycji zamówienia ──────────────────────────────── */
.propozycja td { vertical-align: top; }
.propozycja .tiny { display: block; }
.propozycja input.pole-ilosc { margin-bottom: 2px; }

/* ── Dni dostaw dostawcy ───────────────────────────────────────── */
/*
 | Siedem kwadracików „w które dni przyjeżdża”. Wybór dnia to jedno
 | kliknięcie w kwadracik z nazwą, a nie lista rozwijana — bo to jest
 | wzór tygodnia i ma się go dać zobaczyć jednym spojrzeniem.
 */
.dni-tygodnia {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.dni-tygodnia .dzien {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: 13px;
  cursor: pointer;
  user-select: none;
}
.dni-tygodnia .dzien:hover { border-color: var(--brand); }
.dni-tygodnia .dzien:has(input:checked) {
  background: var(--brand-light);
  border-color: var(--brand);
  font-weight: 600;
}

/* ── Wydruk zamówienia ─────────────────────────────────────────── */
/*
 | Zamówienie jest pierwszym dokumentem, który WYCHODZI z firmy na
 | zewnątrz — jedzie do dostawcy. Dlatego ma nagłówek z danymi obu
 | stron i wersję tekstową do wklejenia w e-mail, dopóki poczta nie
 | wejdzie w etapie 15.
 */
.zamowienie-naglowek {
  display: flex;
  justify-content: space-between;
  gap: 24px;
  flex-wrap: wrap;
  padding-bottom: 12px;
  border-bottom: 2px solid var(--text);
  margin-bottom: 16px;
}
.zamowienie-strony {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 20px;
  margin-bottom: 18px;
}
.zamowienie-strony h3 {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--text-muted);
  margin: 0 0 4px;
}
.zamowienie-tekst {
  width: 100%;
  min-height: 220px;
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: 12px;
  line-height: 1.5;
  white-space: pre;
}

/* ── Wydruk rejestru HACCP ─────────────────────────────────────── */
.haccp-naglowek {
  display: flex;
  justify-content: space-between;
  gap: 24px;
  flex-wrap: wrap;
  padding-bottom: 12px;
  border-bottom: 2px solid var(--text);
  margin-bottom: 16px;
}
.haccp-tabela { width: 100%; border-collapse: collapse; font-size: 12px; }
.haccp-tabela th,
.haccp-tabela td { border: 1px solid var(--border); padding: 5px 7px; text-align: left; }
.haccp-tabela th { background: var(--surface-alt); font-size: 11px; }
.haccp-dzien-pusty { color: var(--text-subtle); font-style: italic; }
.haccp-podpis {
  margin-top: 32px;
  display: flex;
  justify-content: flex-end;
}
.haccp-podpis span {
  border-top: 1px solid var(--text);
  padding-top: 6px;
  min-width: 220px;
  text-align: center;
  font-size: 12px;
}

@media print {
  .zamowienie-tekst, .form-grid, .rozwijane { display: none; }
  .haccp-tabela { font-size: 10px; }
  .haccp-tabela th, .haccp-tabela td { padding: 3px 5px; }
}

@media (max-width: 560px) {
  .form-grid { grid-template-columns: 1fr; }
  .pole-ilosc { max-width: none; }
}

/* ══════════════════════════════════════════════════════════════════
   ETAP 14 — analityka
   ══════════════════════════════════════════════════════════════════ */

/*
 | Kafle wskaźników są SZERSZE od zwykłych KPI (`.kpi-grid`, 168 px),
 | bo każdy niesie trzy zdania objaśnienia: z czego się liczy, co
 | znaczy i ile wynosi u innych. Liczba bez tych trzech zdań jest
 | ozdobą, którą po miesiącu przestaje się czytać — a przy 168 px
 | nie ma gdzie ich zmieścić.
 */
.kafle {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: var(--s3);
}

/*
 | Słupek rytmu tygodnia. Rysowany szerokością elementu, nie obrazkiem
 | ani wykresem w JS — bo to jest jedna liczba na wiersz i wszystko,
 | co potrzebne, to zobaczyć, który słupek jest dłuższy.
 */
.rytm-slupek {
  display: block;
  height: 10px;
  border-radius: 5px;
  background: var(--brand);
  min-width: 2px;
}
.rytm-slupek--slaby { background: var(--border); }

/* Komórka ze słupkiem ma zająć resztę wiersza, a nie tyle, co liczba. */
.rytm-pasek { width: 45%; min-width: 90px; }

@media (max-width: 560px) {
  .kafle { grid-template-columns: 1fr; }
  .rytm-pasek { width: 32%; min-width: 60px; }
}

@media print {
  .rytm-slupek { background: #999 !important; -webkit-print-color-adjust: exact; }
}

/*
 |──────────────────────────────────────────────────────────────────
 | ETAP 15 — zadania w tle, poczta, dzwonek
 |──────────────────────────────────────────────────────────────────
 */

/*
 | Karta, która krzyczy. Używana w jednym miejscu: gdy zadania w tle
 | milczą od godzin. To jest stan, którego NIE WIDAĆ inaczej — system
 | wygląda normalnie, tylko raporty przestają przychodzić.
 */
.karta--alarm {
  border-color: var(--danger-border);
  background: var(--danger-bg);
}
.karta--alarm h2 { margin-bottom: var(--s2); }

/*
 | Adres crona do skopiowania. Łamany, nie przewijany w bok: link
 | z tokenem, którego nie widać w całości, jest bezużyteczny — a na
 | telefonie zaznacza się go palcem, nie kółkiem myszy.
 */
.kod-do-skopiowania {
  background: #16161A;
  color: #E4E4E8;
  padding: var(--s3);
  border-radius: var(--r);
  font-size: 12.5px;
  line-height: 1.6;
  word-break: break-all;
  white-space: pre-wrap;
  user-select: all;
}

/* ── Dzwonek w pasku ──────────────────────────────────────────── */

.dzwonek { position: relative; display: inline-flex; align-items: center; }

.dzwonek-przycisk {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 1px solid transparent;
  background: none;
  cursor: pointer;
  font-size: 18px;
  line-height: 1;
  text-decoration: none;
}
.dzwonek-przycisk:hover { background: var(--surface-alt); border-color: var(--border); }

/*
 | Licznik nieprzeczytanych. Minimalna szerokość równa wysokości, żeby
 | „1” było kółkiem, a „12” pigułką — bez skakania układu.
 */
.dzwonek-licznik {
  position: absolute;
  top: 0;
  right: 0;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: 9px;
  background: var(--danger);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  line-height: 18px;
  text-align: center;
  pointer-events: none;
}

.dzwonek-lista {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  width: 320px;
  max-width: calc(100vw - 24px);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r);
  box-shadow: var(--shadow-lg);
  z-index: 60;
  overflow: hidden;
}

.dzwonek-pozycja {
  display: block;
  padding: var(--s3);
  border-bottom: 1px solid var(--border);
  text-decoration: none;
  color: inherit;
}
.dzwonek-pozycja:last-child { border-bottom: 0; }
.dzwonek-pozycja:hover { background: var(--surface-alt); }
.dzwonek-pozycja--nowe { background: #FFF7ED; }
.dzwonek-pozycja--nowe:hover { background: #FFEDD5; }

.dzwonek-stopka {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--s2);
  padding: var(--s2) var(--s3);
  background: var(--surface-alt);
  border-top: 1px solid var(--border);
}

/* ── Skrzynka nadawcza ────────────────────────────────────────── */

.poczta-stan { display: flex; gap: var(--s4); flex-wrap: wrap; }
.poczta-stan div { min-width: 92px; }
.poczta-stan .liczba { font-size: 22px; font-weight: 700; display: block; }

/* ══ ETAP 16 ═══════════════════════════════════════════════════════ */

/*
 | ── PANEL ADMINISTRATORA MA WŁASNY KOLOR ──────────────────────────
 |
 | Administrator systemu ma w przeglądarce dwie karty naraz: swoją
 | lodziarnię i panel. Gdyby obie wyglądały tak samo, prędzej czy później
 | kliknąłby „usuń” w tej niewłaściwej.
 |
 | Podmieniamy WYŁĄCZNIE trzy zmienne marki, a nie osobny arkusz.
 | Wszystko inne — karty, tabele, przyciski, odznaki — zostaje wspólne,
 | więc poprawka w komponencie działa w obu miejscach naraz. Osobny
 | arkusz dla panelu znaczyłby dwa miejsca do poprawiania i jedno z nich
 | zawsze zostaje w tyle.
 |
 | Kolor jest stalowy, nie czerwony: panel nie jest strefą zagrożenia,
 | tylko innym budynkiem.
 */
body.panel-admina {
  --brand:       #46586F;
  --brand-dark:  #33445A;
  --brand-light: #E8EDF4;
}

/*
 | ── RZĄD Z PRZYCISKIEM PO PRAWEJ ───────────────────────────────────
 |
 | Wzorzec „opis z lewej, jedna akcja z prawej” powtarza się w kartach
 | (linki do kiosku, a wcześniej pozycje zamówienia). Do etapu 16 każdy
 | taki rząd miał własne `style="display:flex"` w widoku — czyli pięć
 | kopii tej samej decyzji, z których każda mogła się rozjechać osobno.
 |
 | `flex-wrap` jest tu istotny: na telefonie przycisk ma zejść pod opis,
 | a nie ściskać go do dwóch liter na wiersz.
 */
.rzad-miedzy {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--s3);
  flex-wrap: wrap;
}

/*
 | Karta wyłączonego linku do kiosku. Przygaszona, ale CZYTELNA — ma być
 | widać, że taki link kiedyś istniał i do którego punktu prowadził.
 | Skasowanie wiersza byłoby wygodniejsze i gorsze: pytanie „czy ten
 | tablet na pewno już nie działa” zadaje się po fakcie.
 */
.karta--wylaczona { opacity: .6; }
