/* ==========================================================================
   SOZ 2.0 — Design System
   Motyw ciemny · marka: czerń / złoto / biel
   Wszystkie kolory serii danych zwalidowane skryptem (kontrast, CVD,
   pasmo jasności) względem powierzchni #141416.
   ========================================================================== */

:root {
  /* --- Powierzchnie --------------------------------------------------- */
  --plane:        #0A0A0B;   /* tło strony */
  --surface:      #141416;   /* karty, panele */
  --surface-2:    #1C1C20;   /* elementy uniesione, hover */
  --surface-3:    #252529;   /* aktywne, wejścia formularzy */

  /* --- Atrament ------------------------------------------------------- */
  --ink:          #FFFFFF;   /* 18.4:1 */
  --ink-2:        #C7C4BC;   /* 10.6:1 — teksty pomocnicze */
  --ink-3:        #8B8880;   /*  5.2:1 — etykiety, osie */
  --ink-4:        #5A5852;   /* bardzo stonowane */

  /* --- Złoto marki ---------------------------------------------------- */
  --gold-300:     #E8C766;   /* podświetlenia, hover na tekście */
  --gold-400:     #D9B44A;   /* AKCENT GŁÓWNY — linki, aktywna nawigacja */
  --gold-500:     #B5901E;   /* seria danych nr 1, obramowania */
  --gold-600:     #8A6D14;
  --gold-wash:    rgba(217,180,74,.10);
  --gold-wash-2:  rgba(217,180,74,.18);

  /* --- Linie ---------------------------------------------------------- */
  --line:         rgba(255,255,255,.08);
  --line-2:       rgba(255,255,255,.14);
  --grid:         #232326;

  /* --- Stany (zawsze z ikoną i etykietą, nigdy sam kolor) ------------- */
  --ok:           #3FB950;
  --warn:         #EE7B3C;
  --crit:         #F04E4E;
  --info:         #4C9AFF;
  --ok-wash:      rgba(63,185,80,.12);
  --warn-wash:    rgba(238,123,60,.12);
  --crit-wash:    rgba(240,78,78,.12);
  --info-wash:    rgba(76,154,255,.12);

  /* --- Serie danych (kolejność stała, nigdy zapętlana) ---------------- */
  --series-1:     #B5901E;   /* złoto  — wesela */
  --series-2:     #3B82F6;   /* błękit — pozostałe imprezy */
  --series-3:     #14A085;   /* morski */
  --series-4:     #8B7BE8;   /* fiolet */
  --series-5:     #D24F7A;   /* róż */

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

  /* --- Geometria ------------------------------------------------------ */
  --r-sm: 6px; --r: 10px; --r-lg: 14px; --r-xl: 18px;
  --shadow: 0 1px 2px rgba(0,0,0,.4), 0 8px 24px rgba(0,0,0,.28);
  --sidebar-w: 236px;
  --topbar-h: 58px;
  --topbar-bg:  rgba(10,10,11,.86);   /* tło paska górnego */
}

* { box-sizing: border-box; }
html, body { height: 100%; }

body {
  margin: 0;
  background: var(--plane);
  color: var(--ink-2);
  font: 15px/1.55 var(--font);
  -webkit-font-smoothing: antialiased;
}

a { color: var(--gold-400); text-decoration: none; }
.logo { display: block; flex: none; border-radius: 11px;
        box-shadow: 0 2px 10px rgba(217,180,74,.22); }
a:hover { color: var(--gold-300); }

h1,h2,h3,h4 { color: var(--ink); margin: 0; font-weight: 600; letter-spacing: -.01em; }
h1 { font-size: 24px; }
h2 { font-size: 18px; }
h3 { font-size: 15px; }

::selection { background: var(--gold-wash-2); color: var(--ink); }

/* --- Pasek górny ------------------------------------------------------ */
/* Tło paska było wpisane na sztywno jako rgba(10,10,11,.86) — czyli czarne
   niezależnie od motywu. W jasnym wyglądało to jak cudzy element wklejony
   na górę strony. Teraz to zmienna, którą motyw podmienia razem z resztą. */
.topbar {
  position: fixed; inset: 0 0 auto 0; height: var(--topbar-h); z-index: 40;
  display: flex; align-items: center; gap: 20px; padding: 0 20px;
  background: var(--topbar-bg); backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--line);
}

/* Szerokość MINIMALNA, nie sztywna.

   Wcześniej było `width: calc(var(--sidebar-w) - 20px)`, czyli 216 px —
   żeby marka kończyła się równo z bocznym menu. Tyle że sam znak zajmuje
   ~96 px, a „System Obsługi Zleceń" potrzebuje ~118 px: razem z odstępami
   nie mieściło się i napis urywał się w połowie.

   Teraz pasek marki zaczyna się od tej szerokości, ale wolno mu urosnąć.
   Równanie z menu jest miłe dla oka; ucięty napis nie jest. */
.brand {
  display: flex; align-items: center; gap: 12px; text-decoration: none;
  min-width: calc(var(--sidebar-w) - 20px); flex: none;
}
.brand-mark-wide, .brand-mark-narrow { display: flex; align-items: center; flex: none; }
.brand-mark-narrow { display: none; }

/* Podpis systemu: informacja o narzędziu, nie o zespole — więc cicho,
   pionową kreską odsunięty od znaku. */
.brand-sub {
  color: var(--ink-4); font-size: 11px; line-height: 1.2; letter-spacing: .01em;
  padding-left: 12px; border-left: 1px solid var(--line-2);
  white-space: nowrap; flex: none;
}

/* Na średnich ekranach podpis ustępuje miejsca wyszukiwarce — ona jest
   potrzebna do pracy, a podpis tylko ładny. */
@media (max-width: 1180px) {
  .brand { min-width: 0; }
  .brand-sub { display: none; }
}

/* Znak dobierany do motywu. Serwer nie wie, jak ustawiony jest telefon przy
   opcji „jak w systemie", więc oba warianty idą w HTML-u, a wybiera CSS. */
.logo-on-light { display: none; }
[data-theme="light"] .logo-on-dark  { display: none; }
[data-theme="light"] .logo-on-light { display: block; }

@media (prefers-color-scheme: light) {
  [data-theme="system"] .logo-on-dark  { display: none; }
  [data-theme="system"] .logo-on-light { display: block; }
}

/* Wordmark nie dostaje cienia ani zaokrąglenia — to napis, nie kafelek. */
.logo-wordmark { box-shadow: none; border-radius: 0; }

.topbar-spacer { flex: 1; }

.quicksearch {
  display: flex; align-items: center; gap: 9px; min-width: 260px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: 999px; padding: 7px 14px; color: var(--ink-3); font-size: 13.5px;
}
.quicksearch kbd {
  margin-left: auto; font: 11px var(--mono); color: var(--ink-4);
  border: 1px solid var(--line-2); border-radius: 4px; padding: 1px 5px;
}

.avatar {
  width: 32px; height: 32px; border-radius: 50%; display: grid; place-items: center;
  background: var(--surface-3); color: var(--gold-300); border: 1px solid var(--line-2);
  font-size: 12.5px; font-weight: 650; cursor: pointer;
}

/* --- Nawigacja boczna ------------------------------------------------- */
.sidebar {
  position: fixed; top: var(--topbar-h); bottom: 0; left: 0; width: var(--sidebar-w);
  padding: 16px 12px; overflow-y: auto;
  border-right: 1px solid var(--line); background: var(--plane);
}
.nav-group { color: var(--ink-4); font-size: 10.5px; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase; margin: 18px 0 7px 11px; }
.nav-group:first-child { margin-top: 2px; }
.nav-item {
  display: flex; align-items: center; gap: 11px; padding: 8px 11px;
  border-radius: var(--r-sm); color: var(--ink-2); font-size: 14px;
  cursor: pointer; transition: background .12s, color .12s;
}
.nav-item:hover { background: var(--surface); color: var(--ink); }
.nav-item.active { background: var(--gold-wash); color: var(--gold-300); font-weight: 600; }
.nav-item.active .ico { color: var(--gold-400); }
.nav-item .ico { width: 17px; color: var(--ink-3); flex: none; }
.nav-item .badge {
  margin-left: auto; background: var(--surface-3); color: var(--ink-2);
  border-radius: 999px; font-size: 11px; padding: 1px 7px; font-weight: 600;
}
.nav-item .badge.warn { background: var(--warn-wash); color: var(--warn); }

/* --- Układ treści ----------------------------------------------------- */
.main { margin: var(--topbar-h) 0 0 var(--sidebar-w); padding: 26px 28px 64px; }
.page-head { display: flex; align-items: flex-end; gap: 16px; margin-bottom: 22px; }
.page-head p { margin: 4px 0 0; color: var(--ink-3); font-size: 13.5px; }

/* --- Karty ------------------------------------------------------------ */
.card {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); overflow: hidden;
}
.card > header {
  display: flex; align-items: center; gap: 10px;
  padding: 13px 17px; border-bottom: 1px solid var(--line);
}
.card > header h3 { flex: 1; font-size: 14px; }
.card > header .hint { color: var(--ink-4); font-size: 12px; }
.card-body { padding: 17px; }

.grid { display: grid; gap: 16px; }
.g-4 { grid-template-columns: repeat(4, 1fr); }
.g-2 { grid-template-columns: repeat(2, 1fr); }
.g-main { grid-template-columns: 1.55fr 1fr; align-items: start; }

/* --- Kafelki statystyk ------------------------------------------------ */
.tile {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: 15px 17px 16px; position: relative; overflow: hidden;
}
.tile.is-current { border-color: var(--gold-600); background:
  linear-gradient(160deg, var(--gold-wash), transparent 62%), var(--surface); }
.tile-label { display: flex; align-items: center; gap: 7px;
  color: var(--ink-3); font-size: 12px; font-weight: 600; letter-spacing: .04em; }
.tile.is-current .tile-label { color: var(--gold-300); }
.tile-value { color: var(--ink); font-size: 34px; font-weight: 650;
  line-height: 1.05; margin: 9px 0 3px; letter-spacing: -.03em; }
.tile-unit { color: var(--ink-3); font-size: 13px; font-weight: 400; margin-left: 5px; }
.tile-split { display: flex; gap: 14px; margin-top: 11px;
  padding-top: 11px; border-top: 1px solid var(--line); font-size: 12.5px; }
.tile-split div { display: flex; align-items: center; gap: 6px; color: var(--ink-2); }
.tile-split b { color: var(--ink); font-weight: 650; }
.dot { width: 8px; height: 8px; border-radius: 2px; flex: none; }

/* --- Widget sprawdzania terminu --------------------------------------- */
.checker {
  background: linear-gradient(155deg, rgba(217,180,74,.13), transparent 58%), var(--surface);
  border: 1px solid var(--gold-600); border-radius: var(--r-lg); padding: 19px;
}
.checker h3 { color: var(--gold-300); font-size: 14px; }
/* Wiersz sprawdzania terminu.

   Na telefonie data, liczba dni i przycisk nie mieszczą się obok siebie —
   przycisk wchodził na pole daty i trafienie w cokolwiek było loterią.
   Poniżej 560 px układ przestaje być rzędem i staje się kolumną: pola jedno
   pod drugim, przycisk na dole i na całą szerokość.

   `!important` jest tu potrzebne, bo szerokość listy dni jest wpisana
   w atrybucie style — a atrybut wygrywa z każdą regułą arkusza. */
.checker-row { display: flex; gap: 9px; margin-top: 13px; flex-wrap: wrap; }

@media (max-width: 560px) {
  .checker-row { flex-direction: column; align-items: stretch; }
  .checker-row .input { flex: 1 1 auto !important; width: 100%; }
  .checker-row .btn { width: 100%; justify-content: center; }
}
.input {
  flex: 1; background: var(--surface-3); border: 1px solid var(--line-2);
  border-radius: var(--r); padding: 10px 13px; color: var(--ink);
  font: 15px var(--font); outline: none;

  /* `min-width: 0` — JEDNA LINIJKA, DWIE USTERKI.
     Element w układzie flex ma domyślnie `min-width: auto`, czyli „nie
     zwężaj mnie poniżej mojej naturalnej szerokości". Przy zwykłym polu
     tekstowym to nic nie znaczy. Przy `input[type=date]` na iPhonie owszem:
     pole ma wbudowaną szerokość na pełną datę i NIE DA SIĘ jej zwęzić —
     więc `width: 100%` nie pomagało i pole wychodziło poza kartę
     „Sprawdź termin", zarówno w systemie, jak i na widoku dla klienta. */
  min-width: 0;
}
.input:focus { border-color: var(--gold-500); box-shadow: 0 0 0 3px var(--gold-wash); }
.btn {
  background: var(--gold-400); color: #0A0A0B; border: none; border-radius: var(--r);
  padding: 10px 18px; font: 650 14px var(--font); cursor: pointer; white-space: nowrap;
  /* inline-flex zamiast domyślnego układu przycisku: napis stoi dokładnie
     w środku w pionie i w poziomie. Przy zwykłym <button> przeglądarka
     dokłada własne wyrównanie i „Zamień na zlecenie" siedziało odrobinę
     za wysoko i za bardzo w lewo. */
  display: inline-flex; align-items: center; justify-content: center;
  text-align: center; line-height: 1.2; text-decoration: none;
}
.btn:hover { background: var(--gold-300); }
.btn.ghost { background: transparent; color: var(--ink-2); border: 1px solid var(--line-2); }
.btn.ghost:hover { background: var(--surface-2); color: var(--ink); }
.btn.sm { padding: 6px 12px; font-size: 13px; }

.verdict {
  display: flex; align-items: center; gap: 11px; margin-top: 13px;
  padding: 11px 14px; border-radius: var(--r); font-size: 14px;
}
.verdict.free  { background: var(--ok-wash);   color: var(--ok);   border: 1px solid rgba(63,185,80,.3); }
.verdict.busy  { background: var(--crit-wash); color: var(--crit); border: 1px solid rgba(240,78,78,.3); }
.verdict.resv  { background: var(--warn-wash); color: var(--warn); border: 1px solid rgba(238,123,60,.3); }
/* Długi adres w komunikacie ma się ŁAMAĆ, a nie wyjeżdżać poza ramkę.
   Ten sam mechanizm co wyżej: `<b>` jest elementem flex, więc domyślnie
   nie zwęża się poniżej swojej treści — a treścią bywa adres linku dla
   klienta, czyli 60 znaków bez spacji. `anywhere` zamiast `break-word`,
   bo w adresie nie ma gdzie łamać „po ludzku". */
.verdict b { color: inherit; min-width: 0; overflow-wrap: anywhere; }
.verdict .sub { color: var(--ink-3); font-size: 12.5px; margin-left: auto; }

/* --- Mini kalendarz --------------------------------------------------- */
.cal { display: grid; grid-template-columns: repeat(7, 1fr); gap: 5px; }
.cal-dow { color: var(--ink-4); font-size: 10.5px; font-weight: 700;
  text-align: center; letter-spacing: .06em; padding-bottom: 3px; }
.cal-day {
  position: relative; aspect-ratio: 1; border-radius: 8px;
  background: var(--surface-2); border: 1px solid transparent;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  font-size: 13px; color: var(--ink-2); cursor: default;
}
.cal-day.pad { background: transparent; color: var(--ink-4); opacity: .35; }
.cal-day.today { border-color: var(--gold-400); color: var(--gold-300); font-weight: 700; }
.cal-day.has { cursor: pointer; }
.cal-day.has:hover { border-color: var(--line-2); background: var(--surface-3); }
.cal-day .mark { width: 5px; height: 5px; border-radius: 50%; margin-top: 3px; }
.cal-day.free-sat { box-shadow: inset 0 0 0 1px rgba(63,185,80,.28); }

/* Karta z dymkiem albo listą podpowiedzi nie może przycinać zawartości.
   Zwykła karta ma `overflow: hidden` (zaokrąglone rogi przy tabelach) —
   i to ona ucinała dymki nad kalendarzem oraz listę lokali w formularzu. */
.card.pops { overflow: visible; }

.pop {
  position: absolute; bottom: calc(100% + 9px); left: 50%; transform: translateX(-50%);
  width: 214px; padding: 11px 13px; z-index: 30;
  background: var(--surface-3); border: 1px solid var(--line-2);
  border-radius: var(--r); box-shadow: var(--shadow);
  opacity: 0; visibility: hidden; transition: opacity .13s, transform .13s;
  text-align: left; pointer-events: none;
}
.cal-day:hover .pop, .pop.show { opacity: 1; visibility: visible; }
.pop::after {
  content: ''; position: absolute; top: 100%; left: 50%; margin-left: -6px;
  border: 6px solid transparent; border-top-color: var(--line-2);
}
/* Dymek wyjęty z układu strony i ustawiony względem okna (public/js/soz.js).
   Dzięki temu żaden przodek z przewijaniem go nie utnie, a przy krawędzi
   ekranu — np. przy niedzieli w ostatniej kolumnie — dymek sam się przesuwa
   i w razie potrzeby wyskakuje pod spodem zamiast nad. */
.pop.is-fixed {
  position: fixed; bottom: auto; left: 0; top: 0; transform: none; margin: 0;
}
.pop.is-fixed::after { display: none; }

.pop .pd { color: var(--ink-3); font-size: 11px; letter-spacing: .04em; }
.pop .pt { color: var(--ink); font-size: 13.5px; font-weight: 600; margin: 3px 0 2px; }
.pop .pp { color: var(--ink-2); font-size: 12.5px; line-height: 1.4; }
.pop .pk { display: inline-flex; align-items: center; gap: 5px;
  margin-top: 7px; font-size: 11px; color: var(--ink-3); }

/* --- Znaczniki / plakietki -------------------------------------------- */
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 9px; border-radius: 999px; font-size: 11.5px; font-weight: 600;
  background: var(--surface-3); color: var(--ink-2); border: 1px solid var(--line);
}
.chip.gold { background: var(--gold-wash); color: var(--gold-300); border-color: var(--gold-600); }
.chip.ok   { background: var(--ok-wash);   color: var(--ok);   border-color: rgba(63,185,80,.3); }
.chip.warn { background: var(--warn-wash); color: var(--warn); border-color: rgba(238,123,60,.3); }
.chip.crit { background: var(--crit-wash); color: var(--crit); border-color: rgba(240,78,78,.3); }
.chip.info { background: var(--info-wash); color: var(--info); border-color: rgba(76,154,255,.3); }

/* --- Odliczanie / wyróżniona liczba ----------------------------------- */
.hero-num { display: flex; align-items: baseline; gap: 9px; }
.hero-num b { color: var(--gold-300); font-size: 44px; font-weight: 650;
  line-height: 1; letter-spacing: -.035em; }
.hero-num span { color: var(--ink-3); font-size: 14px; }

/* „DZIŚ", „JUTRO", „POJUTRZE" zamiast liczby dni.
   Słowo jest dłuższe niż liczba, więc nie może być tak duże jak ona —
   ale było zmniejszone do 27 px i ginęło. To jest najważniejsze zdanie
   na pulpicie w dniu wesela; ma się rzucać w oczy z odległości ręki. */
.hero-num b.hero-word { font-size: 34px; letter-spacing: -.01em; }

/* --- Listy danych ------------------------------------------------------ */
.dl { display: grid; grid-template-columns: auto 1fr; gap: 9px 18px; font-size: 13.5px; }
.dl dt { color: var(--ink-3); }
.dl dd { color: var(--ink); margin: 0; }

.rows { display: flex; flex-direction: column; }
.row {
  display: flex; align-items: center; gap: 13px; padding: 12px 17px;
  border-bottom: 1px solid var(--line);
}
.row:last-child { border-bottom: none; }
.row:hover { background: var(--surface-2); }
.row .rdate {
  width: 52px; flex: none; text-align: center; line-height: 1.1;
}
.row .rdate b { display: block; color: var(--ink); font-size: 17px; font-weight: 650; }
.row .rdate span { color: var(--ink-3); font-size: 10.5px; text-transform: uppercase; letter-spacing: .05em; }
.row .rmain { flex: 1; min-width: 0; }
.row .rmain b { display: block; color: var(--ink); font-size: 14px; font-weight: 550;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.row .rmain span { color: var(--ink-3); font-size: 12.5px; }
.row .rside { text-align: right; flex: none; }
.row .rside b { display: block; color: var(--ink); font-size: 14px; font-variant-numeric: tabular-nums; }

/* --- Wykres ------------------------------------------------------------ */
.legend { display: flex; gap: 16px; align-items: center; font-size: 12.5px; color: var(--ink-2); }
.legend i { width: 9px; height: 9px; border-radius: 2px; display: inline-block; margin-right: 6px; }

.tt {
  position: fixed; z-index: 60; pointer-events: none; opacity: 0;
  background: var(--surface-3); border: 1px solid var(--line-2); border-radius: var(--r-sm);
  padding: 9px 12px; box-shadow: var(--shadow); font-size: 12.5px; transition: opacity .1s;
}
.tt b { color: var(--ink); display: block; margin-bottom: 4px; font-size: 13px; }
.tt .r { display: flex; align-items: center; gap: 7px; color: var(--ink-2); }
.tt .r span { margin-left: auto; color: var(--ink); font-variant-numeric: tabular-nums; }

/* --- Tabela ------------------------------------------------------------ */
table.data { width: 100%; border-collapse: collapse; font-size: 13.5px; }
table.data th {
  text-align: left; color: var(--ink-3); font-size: 11.5px; font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase;
  padding: 10px 14px; border-bottom: 1px solid var(--line-2); white-space: nowrap;
}
table.data td { padding: 12px 14px; border-bottom: 1px solid var(--line); color: var(--ink-2); }
table.data tr:hover td { background: var(--surface-2); }
table.data td.num { text-align: right; font-variant-numeric: tabular-nums; color: var(--ink); }
table.data td.strong { color: var(--ink); font-weight: 550; }

/* --- Elementy pomocnicze ---------------------------------------------- */
.muted { color: var(--ink-3); }
.tabs { display: flex; gap: 4px; }
.tab { padding: 6px 13px; border-radius: 999px; font-size: 13px; color: var(--ink-3); cursor: pointer; }
.tab:hover { background: var(--surface-2); color: var(--ink-2); }
.tab.on { background: var(--gold-wash); color: var(--gold-300); font-weight: 600; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }

@media (max-width: 1180px) {
  .g-main { grid-template-columns: 1fr; }
  .g-4 { grid-template-columns: repeat(2, 1fr); }
}


/* --- Kafelki sezonów: pasek proporcji i stonowany akcent --------------- */
.tile-bar { display: flex; gap: 2px; height: 6px; border-radius: 3px;
  overflow: hidden; margin: 11px 0 0; background: var(--surface-2); }
.tile-bar i { display: block; height: 100%; }
.tile::before { content: ''; position: absolute; inset: 0 0 auto 0; height: 3px; }

/* Akcent słabnie z oddaleniem sezonu — kolor koduje „jak blisko", a nie
   przypadkową kategorię. Dane (wesela/pozostałe) mają własne, stałe barwy. */
.tile.tone-0::before { background: linear-gradient(90deg, var(--gold-300), var(--gold-500)); }
.tile.tone-1::before { background: linear-gradient(90deg, var(--gold-500), var(--gold-600)); }
.tile.tone-2::before { background: linear-gradient(90deg, var(--gold-600), rgba(138,109,20,.45)); }
.tile.tone-3::before { background: rgba(138,109,20,.30); }
.tile.tone-1 { background: linear-gradient(160deg, rgba(217,180,74,.075), transparent 60%), var(--surface); }
.tile.tone-2 { background: linear-gradient(160deg, rgba(217,180,74,.03), transparent 60%), var(--surface); }
.tile.tone-1 .tile-label { color: #B9A272; }
.tile.tone-2 .tile-label { color: #99917C; }

/* --- Nawigacja kalendarza ---------------------------------------------- */
.cal-nav { display: flex; gap: 5px; margin-left: auto; }
.cal-nav button {
  background: var(--surface-2); border: 1px solid var(--line-2); color: var(--ink-2);
  border-radius: var(--r-sm); padding: 4px 10px; font: 500 13px var(--font);
  cursor: pointer; line-height: 1.5;
}
.cal-nav button:hover { background: var(--surface-3); color: var(--ink); border-color: var(--gold-600); }
.cal-day.out { opacity: .28; }
.cal-day.out .mark { opacity: .5; }
a.cal-day { text-decoration: none; color: inherit; }
a.cal-day:hover { border-color: var(--gold-500); }
.pop .pgo { color: var(--gold-300); font-size: 11px; margin-top: 7px;
  padding-top: 6px; border-top: 1px solid var(--line); }

/* --- Pozostałe granie w tym samym weekendzie --------------------------- */
.weekend {
  background: linear-gradient(150deg, rgba(217,180,74,.09), transparent 55%), var(--surface);
  border: 1px solid var(--gold-600); border-radius: var(--r-lg); padding: 15px 17px;
}
.wk-head { display: flex; align-items: baseline; gap: 10px; margin-bottom: 11px; }
.wk-head b { color: var(--gold-300); font-size: 13.5px; }
.wk-head span { color: var(--ink-3); font-size: 12px; margin-left: auto; }
.wk-list { display: grid; gap: 7px; }
.wk-item {
  display: flex; align-items: center; gap: 11px; text-decoration: none;
  background: var(--surface-2); border-radius: var(--r); padding: 9px 12px;
}
.wk-item:hover { background: var(--surface-3); }
.wk-day { flex: none; width: 46px; }
.wk-day b { display: block; color: var(--ink); font-size: 12.5px; }
.wk-day span { color: var(--ink-3); font-size: 11px; }
.wk-main { flex: 1; min-width: 0; }
.wk-main b { display: block; color: var(--ink); font-size: 13.5px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.wk-main span { color: var(--ink-3); font-size: 11.5px; }
.wk-amt { color: var(--ink-2); font-size: 13px; font-weight: 600; white-space: nowrap; }

/* --- Wiersze klikalne --------------------------------------------------- */
a.row { text-decoration: none; color: inherit; }
a.row:hover { background: var(--surface-2); }
.rgo { color: var(--ink-4); font-size: 17px; flex: none; margin-left: 4px; }
a.row:hover .rgo, .wk-item:hover .rgo { color: var(--gold-400); }
.card-link { display: block; text-decoration: none; color: inherit; }
.card-link:hover { border-color: var(--gold-600); }
.card-link:hover .hint { color: var(--gold-400); }
.title-link { color: var(--ink); }
.title-link:hover { color: var(--gold-300); }

/* --- Ramki notatek ------------------------------------------------------ */
.note-box { background: var(--surface-2); border-radius: var(--r);
  padding: 13px 15px; margin-bottom: 11px; }
.note-box.gold { background: var(--gold-wash); border: 1px solid var(--gold-600); }
.note-label { color: var(--ink-3); font-size: 11.5px; font-weight: 700;
  letter-spacing: .06em; margin-bottom: 6px; }
.note-box.gold .note-label { color: var(--gold-300); }
.note-text { font-size: 13.5px; color: var(--ink-2); }

/* --- Menu użytkownika (element <details>, bez JavaScriptu) ------------- */
.user-menu { position: relative; }
.user-menu > summary { list-style: none; }
.user-menu > summary::-webkit-details-marker { display: none; }
.user-menu .dropdown {
  position: absolute; right: 0; top: calc(100% + 9px); min-width: 210px; z-index: 50;
  background: var(--surface-2); border: 1px solid var(--line-2);
  border-radius: var(--r); box-shadow: var(--shadow); overflow: hidden;
}
.user-menu .dropdown-head { padding: 11px 14px; border-bottom: 1px solid var(--line); }
.user-menu .dropdown-head b { display: block; color: var(--ink); font-size: 13.5px; }
.user-menu .dropdown-head span { color: var(--gold-300); font-size: 11.5px; }
.user-menu .dropdown a,
.user-menu .dropdown button {
  display: block; width: 100%; text-align: left; padding: 9px 14px;
  color: var(--ink-2); font: 13.5px var(--font); background: none;
  border: none; cursor: pointer; text-decoration: none;
}
.user-menu .dropdown a:hover,
.user-menu .dropdown button:hover { background: var(--surface-3); color: var(--ink); }

.quicksearch input {
  flex: 1; background: none; border: none; outline: none;
  color: var(--ink); font: 13.5px var(--font); min-width: 0;
}
.quicksearch input::placeholder { color: var(--ink-3); }
a.nav-item { text-decoration: none; }

/* Nawigacja kalendarza jako odnośniki (adres da się zapisać w zakładce) */
.cal-nav a {
  background: var(--surface-2); border: 1px solid var(--line-2); color: var(--ink-2);
  border-radius: var(--r-sm); padding: 4px 10px; font: 500 13px var(--font);
  text-decoration: none; line-height: 1.5;
}
.cal-nav a:hover { background: var(--surface-3); color: var(--ink); border-color: var(--gold-600); }
.cal-nav a.is-now { color: var(--gold-300); border-color: var(--gold-600); }


/* ======================================================================
   ETAP 3 — kalendarz, listy, formularz, wolne soboty
   ====================================================================== */

/* --- Wspólne drobiazgi ------------------------------------------------ */
.col { display: grid; gap: 16px; align-content: start; }
.head-actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-left: auto; }
.crumb { display: flex; gap: 7px; align-items: center; color: var(--ink-4);
  font-size: 12px; margin-bottom: 5px; }
.crumb a { color: var(--ink-3); text-decoration: none; }
.crumb a:hover { color: var(--gold-300); }
.muted { color: var(--ink-3); font-size: 13px; }
.ok-text { color: var(--ok); }
.gold-text { color: var(--gold-300); }
.sub { display: block; color: var(--ink-3); font-size: 11.5px; margin-top: 2px; }
.person { color: var(--ink); font-size: 15px; font-weight: 600; }
.stack { display: grid; gap: 9px; margin-top: 11px; }
.btn.wide { width: 100%; text-align: center; }
.btn.danger { color: var(--crit); border-color: rgba(240,78,78,.35); }
.btn.danger:hover { background: var(--crit-wash); color: var(--crit); }
.is-loading { opacity: .45; transition: opacity .12s; pointer-events: none; }

/* Komunikaty nad treścią (odwołanie, wygasająca rezerwacja, błędy) */
.banner { border-radius: var(--r); padding: 13px 16px; margin-bottom: 16px;
  font-size: 13.5px; border: 1px solid var(--line-2); background: var(--surface); }
.banner.ok   { background: var(--ok-wash);   border-color: rgba(63,185,80,.3);  color: var(--ink-2); }
.banner.info { background: var(--info-wash); border-color: rgba(76,154,255,.3); color: var(--ink-2); }
.banner.warn { background: var(--warn-wash); border-color: rgba(238,123,60,.3); color: var(--ink-2); }
.banner.crit { background: var(--crit-wash); border-color: rgba(240,78,78,.3); color: var(--ink-2); }
.banner b { color: var(--ink); }

/* PRZYCISK W POWIADOMIENIU MA WYGLĄDAĆ JAK PRZYCISK.
   Reguła niżej barwi odnośniki w treści komunikatu na kolor akcentu.
   Łapała też `<a class="btn">` — a przycisk ma TŁO w kolorze akcentu,
   więc napis w tym samym kolorze na nim znikał. W motywie „Żywy" wyszło
   to najgorzej: granatowy napis na granatowym przycisku.
   `:not(.btn)` zostawia przyciskowi jego własny kolor napisu. */
.banner a:not(.btn) { color: var(--gold-300); }
.banner .btn { color: #0A0A0B; }
.banner .btn.ghost { color: var(--ink); }
.err-list { margin: 7px 0 0 18px; color: var(--ink-2); }
.err-list li { margin-top: 3px; }

/* Pary etykieta/wartość na stronie szczegółów */
.facts { display: grid; gap: 11px; }
.facts.tight { gap: 8px; margin-top: 13px; }
.facts > div { display: flex; gap: 14px; align-items: baseline; }
.facts dt { color: var(--ink-3); font-size: 12.5px; min-width: 132px; flex: none; }
.facts dd { color: var(--ink); font-size: 13.5px; margin: 0; }
.facts dd a { color: var(--gold-300); }

/* --- Pasek przeskoku po miesiącach i latach --------------------------- */
.mnav { display: grid; gap: 7px; }
.mnav-row { display: flex; align-items: center; gap: 9px; }
.mnav-label { color: var(--ink-4); font-size: 10.5px; font-weight: 700;
  letter-spacing: .09em; text-transform: uppercase; width: 54px; flex: none; }
.mnav-btns { display: flex; gap: 4px; flex-wrap: wrap; flex: 1; min-width: 0; }
.mnav-jump { display: flex; gap: 4px; flex: none; }
.mnav-btn { display: inline-flex; align-items: center; gap: 5px;
  background: var(--surface); border: 1px solid var(--line); color: var(--ink-2);
  border-radius: var(--r-sm); padding: 5px 10px; font: 500 12.5px var(--font);
  text-decoration: none; white-space: nowrap; }
.mnav-btn:hover { background: var(--surface-2); color: var(--ink); border-color: var(--line-2); }
.mnav-btn.is-now { color: var(--gold-300); }
.mnav-btn.is-current { background: var(--gold-wash-2); color: var(--gold-300);
  border-color: var(--gold-600); font-weight: 650; }
.mnav-count { font-style: normal; font-size: 10px; color: var(--ink-4);
  background: var(--surface-3); border-radius: 999px; padding: 1px 5px; }
.mnav-btn.is-current .mnav-count { background: rgba(217,180,74,.2); color: var(--gold-300); }

/* --- Duży kalendarz miesięczny ---------------------------------------- */
.mcal-body { padding: 12px; }
.mcal { min-width: 660px; }        /* poniżej tej szerokości siatka przewija się w poziomie */
.mcal-head, .mcal-week { display: grid; grid-template-columns: repeat(7, 1fr); gap: 5px; }
.mcal-week { margin-top: 5px; }
.mcal-dow { color: var(--ink-4); font-size: 10.5px; font-weight: 700;
  letter-spacing: .07em; text-transform: uppercase; padding: 3px 4px; }
.dow-short { display: none; }
.mcal-cell { position: relative; min-height: 96px; background: var(--surface-2);
  border: 1px solid transparent; border-radius: var(--r-sm); padding: 5px; }
.mcal-cell.out { opacity: .38; }
.mcal-cell.past { background: rgba(28,28,32,.45); }
.mcal-cell.today { border-color: var(--gold-400); }
.mcal-cell.free-sat { box-shadow: inset 0 0 0 1px rgba(63,185,80,.32); }
.mcal-num { display: flex; align-items: center; gap: 6px; margin-bottom: 4px; }
.mcal-num span { color: var(--ink-2); font-size: 12px; font-weight: 600; }
.mcal-cell.today .mcal-num span { color: var(--gold-300); }
.mcal-tag { font-style: normal; font-size: 9.5px; letter-spacing: .05em;
  text-transform: uppercase; color: var(--gold-400); }
.mcal-tag.free { color: var(--ok); }
.mcal-item { display: block; text-decoration: none; border-radius: 5px;
  padding: 4px 6px; margin-bottom: 3px; border-left: 3px solid var(--series-4);
  background: var(--surface-3); }
.mcal-item:hover { background: var(--surface); }
.mcal-item b { display: block; color: var(--ink); font-size: 11.5px; font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mcal-item span { display: block; color: var(--ink-3); font-size: 10.5px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mcal-item.kind-order       { border-left-color: var(--series-1); }
.mcal-item.kind-reservation { border-left-color: var(--warn); }
.mcal-item.kind-block       { border-left-color: var(--ink-4); }
.mcal-add { position: absolute; right: 5px; bottom: 4px; width: 21px; height: 21px;
  display: grid; place-items: center; border-radius: 5px; color: var(--ink-4);
  text-decoration: none; font-size: 15px; opacity: 0; }
.mcal-cell:hover .mcal-add { opacity: 1; }
.mcal-add:hover { background: var(--gold-wash); color: var(--gold-300); }

.legend .lg { display: inline-block; width: 10px; height: 10px; border-radius: 3px;
  margin-right: 6px; vertical-align: -1px; }
.lg.kind-order { background: var(--series-1); }
.lg.kind-reservation { background: var(--warn); }
.lg.kind-block { background: var(--ink-4); }
.lg.lg-sat { background: transparent; box-shadow: inset 0 0 0 1px rgba(63,185,80,.6); }

/* --- Wolne soboty ------------------------------------------------------ */
.season-switch { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 15px; }
.season-btn { flex: 1; min-width: 82px; text-align: center; text-decoration: none;
  background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--r-sm);
  padding: 7px 9px; }
.season-btn:hover { border-color: var(--line-2); background: var(--surface-3); }
.season-btn b { display: block; color: var(--ink-2); font-size: 13.5px; }
.season-btn span { display: block; color: var(--ink-4); font-size: 11px; margin-top: 1px; }
.season-btn.is-current { background: var(--gold-wash-2); border-color: var(--gold-600); }
.season-btn.is-current b { color: var(--gold-300); }
.season-btn.is-current span { color: var(--gold-400); }
.free-sat-head .hero-num b { font-size: 38px; }
.free-sat-head .hero-num span { color: var(--ink-3); font-size: 13px; }
.free-sat-months { display: grid; gap: 11px; margin-top: 16px;
  padding-top: 14px; border-top: 1px solid var(--line); }
.fsm { display: flex; gap: 12px; align-items: baseline; }
.fsm-name { width: 88px; flex: none; color: var(--ink-3); font-size: 12px; }
.fsm-dates { display: flex; gap: 5px; flex-wrap: wrap; }
.fsd { display: inline-block; background: var(--surface-2); border: 1px solid var(--line-2);
  border-radius: var(--r-sm); padding: 3px 8px; font-size: 12.5px; color: var(--ink-2);
  text-decoration: none; font-variant-numeric: tabular-nums; }
a.fsd:hover { border-color: var(--ok); color: var(--ok); background: var(--ok-wash); }

/* --- Listy ------------------------------------------------------------- */
.filters { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 16px; }
.filters .input { flex: 0 1 auto; width: auto; }
.filters input[type="search"] { flex: 1 1 220px; }
.table-wrap { overflow-x: auto; }
.tbl { width: 100%; border-collapse: collapse; min-width: 620px; }
.tbl th { text-align: left; color: var(--ink-4); font-size: 10.5px; font-weight: 700;
  letter-spacing: .07em; text-transform: uppercase; padding: 11px 14px;
  border-bottom: 1px solid var(--line); white-space: nowrap; }
.tbl td { padding: 11px 14px; border-bottom: 1px solid var(--line);
  font-size: 13.5px; color: var(--ink-2); vertical-align: top; }
.tbl tbody tr { cursor: pointer; }
.tbl tbody tr:hover { background: var(--surface-2); }
.tbl tbody tr.is-inactive { opacity: .55; }
.tbl td b { color: var(--ink); font-weight: 600; }
.tbl td.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.tbl th.num { text-align: right; }
.tbl td.empty { text-align: center; color: var(--ink-3); padding: 34px 14px; cursor: default; }
.tbl td.empty a { color: var(--gold-300); }
.tbl a.title-link { text-decoration: none; }

.pager { display: flex; align-items: center; gap: 12px; margin-top: 15px; }
.pager-btn { background: var(--surface); border: 1px solid var(--line-2); color: var(--ink-2);
  border-radius: var(--r-sm); padding: 6px 13px; font-size: 13px; text-decoration: none; }
.pager-btn:hover { background: var(--surface-2); color: var(--ink); }
.pager-btn.is-off { opacity: .35; }
.pager-info { color: var(--ink-3); font-size: 12.5px; margin-left: auto; }

/* --- Formularz wpisu --------------------------------------------------- */
.bform .card { margin: 0; }
/* Atrybut `hidden` musi wygrywać z każdą regułą `display`.
   Przeglądarka nadaje mu `display: none`, ale ze stylu wbudowanego
   o najniższym priorytecie — więc `.field { display: grid }` niżej
   po prostu go przykrywało. Skutek: przy blokadzie terminu pola
   „Ile dni" i „Poprawiny" zostawały na ekranie mimo `hidden`,
   a formularz mówił dwie sprzeczne rzeczy naraz. */
[hidden] { display: none !important; }

.fgrid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 13px; }
.fgrid + .fgrid { margin-top: 13px; }
.field { display: grid; gap: 5px; }
.field.wide { grid-column: 1 / -1; }
.field + .field { margin-top: 13px; }
.fgrid .field + .field { margin-top: 0; }
.field label { color: var(--ink-3); font-size: 12px; }
.field .input { width: 100%; }
.field textarea.input { resize: vertical; line-height: 1.5; font: 400 13.5px var(--font); }
.help { color: var(--ink-4); font-size: 11.5px; line-height: 1.45; }
.check { display: flex; align-items: center; gap: 8px; margin-top: 11px;
  color: var(--ink-3); font-size: 12.5px; cursor: pointer; }

.kind-pick { display: grid; grid-template-columns: repeat(3, 1fr); gap: 9px; }
.kind-opt { display: block; background: var(--surface-2); border: 1px solid var(--line);
  border-radius: var(--r); padding: 11px 13px; cursor: pointer; }
.kind-opt:hover { border-color: var(--line-2); }
.kind-opt input { position: absolute; opacity: 0; width: 0; height: 0; }
.kind-opt b { display: block; color: var(--ink-2); font-size: 13.5px; }
.kind-opt span { display: block; color: var(--ink-4); font-size: 11.5px; margin-top: 3px; }
.kind-opt.is-on { background: var(--gold-wash-2); border-color: var(--gold-600); }
.kind-opt.is-on b { color: var(--gold-300); }

.date-verdict { display: grid; gap: 6px; margin-top: 13px; }
.date-verdict:empty { display: none; }
.conflict { display: block; background: var(--crit-wash); border: 1px solid rgba(240,78,78,.3);
  border-radius: var(--r-sm); padding: 8px 11px; font-size: 12.5px;
  color: var(--ink-2); text-decoration: none; }
.conflict:hover { color: var(--ink); border-color: var(--crit); }
.neighbour { background: var(--surface-2); border-radius: var(--r-sm);
  padding: 7px 11px; font-size: 12px; color: var(--ink-3); }
.save-card { position: sticky; top: calc(var(--topbar-h) + 16px); }
.save-card .card-body { display: grid; gap: 8px; }

/* ======================================================================
   Telefony i tablety
   ----------------------------------------------------------------------
   Powód: na smartfonie kalendarz był ucinany, a kafle sezonów wychodziły
   poza ekran. Nawigacja boczna zamienia się w poziomy pasek nad treścią,
   szerokie siatki schodzą do jednej kolumny, a kalendarz przewija się
   w poziomie zamiast być przycięty.
   ====================================================================== */
@media (max-width: 1000px) {
  .g-main { grid-template-columns: 1fr; }
  .kind-pick { grid-template-columns: 1fr; }
  .save-card { position: static; }
}

@media (max-width: 900px) {
  :root { --sidebar-w: 0px; }

  .topbar { padding: 0 14px; gap: 10px; }

  /* Na telefonie pełny napis „Szybki Numer · zespół muzyczny" zjadałby
     połowę paska. Zostaje sam okrągły znak — rozpoznawalny, a zajmuje tyle
     co ikona. Podpis systemu chowamy: na tym ekranie i tak wiadomo,
     w czym się jest. */
  .brand { width: auto; }
  .brand-mark-wide { display: none; }
  .brand-mark-narrow { display: flex; }
  /* Podpis systemu ZOSTAJE także na telefonie. Był chowany „bo nie ma
     miejsca", a miejsca jest aż nadto: w pasku stoi tylko okrągły znak
     i literki konta, reszta to pustka. Bez podpisu nie widać, w czym
     się właściwie jest. Poniżej 380 px znika — tam faktycznie ciasno. */
  /* `display: flex` na `.brand`, więc podpis wraca jako element tego
     układu. Reguła z bloku 1180 px go schowała, a tu jest już inny powód:
     wyszukiwarki na telefonie i tak nie ma, więc miejsce jest wolne. */
  .brand-sub { display: block; font-size: 10.5px; padding-left: 10px; }
  .quicksearch { display: none; }

  /* ODSTĘP OD PASKÓW U GÓRY LICZY SIĘ RAZ, NA <body>.
     Wcześniej każdy element odsuwał się sam: menu własnym marginesem,
     treść swoim. Dopóki pasek u góry był jeden, wychodziło na to samo.
     Po dołożeniu paska „ŚRODOWISKO TESTOWE" trzeba było poprawić dwa
     miejsca, poprawiłem jedno — i nagłówek z logo zasłonił menu, którego
     na telefonie nie dało się przez to kliknąć.
     Teraz odstęp jest jeden i nie ma czemu się rozjechać. */
  body:not(.auth-page) { padding-top: var(--topbar-h); }
  body.is-test:not(.auth-page) { padding-top: calc(var(--topbar-h) + var(--test-bar-h)); }

  /* Nawigacja: poziomy pasek z przewijaniem zamiast kolumny z boku */
  .sidebar { position: static; width: auto; height: auto; border-right: 0;
    border-bottom: 1px solid var(--line); display: flex; gap: 4px;
    overflow-x: auto; padding: 8px 12px; margin-top: 0;
    -webkit-overflow-scrolling: touch; }
  .sidebar .nav-group { display: none; }
  .nav-item { flex: none; white-space: nowrap; padding: 7px 12px; }

  .main { margin: 0; padding: 18px 14px 56px; }
  .page-head { flex-wrap: wrap; gap: 10px; }
  .head-actions { margin-left: 0; width: 100%; }
  .head-actions .btn { flex: 1; text-align: center; }
}

@media (max-width: 380px) {
  /* Najwęższe telefony: tu na podpis faktycznie nie ma miejsca. */
  .brand-sub { display: none; }
}

@media (max-width: 760px) {
  .g-4 { grid-template-columns: repeat(2, 1fr); }
  .fgrid { grid-template-columns: 1fr; }
  .mnav-row { align-items: flex-start; }
  .mnav-label { width: 44px; padding-top: 6px; }
  .dow-long { display: none; }
  .dow-short { display: inline; }

  /* Kalendarz nie jest ucinany — przewija się w poziomie w swojej ramce */
  .mcal-body { overflow-x: auto; padding: 10px; }

  .facts > div { flex-direction: column; gap: 2px; }
  .facts dt { min-width: 0; }
  /* Filtry na telefonie: pole szukania na całą szerokość, listy obok
     siebie, przyciski w jednym rzędzie. Wcześniej każdy element zajmował
     osobny wiersz i sam pasek filtrów zjadał pół ekranu. */
  .filters { flex-direction: row; flex-wrap: wrap; gap: 7px; margin-bottom: 12px; }
  .filters input[type="search"] { flex: 1 1 100%; padding: 9px 12px; font-size: 14px; }
  .filters .input { flex: 1 1 calc(50% - 4px); width: auto; min-width: 0;
    padding: 8px 10px; font-size: 13px; }
  .filters .btn { flex: 1 1 calc(50% - 4px); padding: 8px 12px; font-size: 13px; }
  .fsm { flex-direction: column; gap: 5px; }
  .fsm-name { width: auto; }
}

@media (max-width: 520px) {
  .g-4, .g-2 { grid-template-columns: 1fr; }
  .tile-value { font-size: 28px; }
  .hero-num b { font-size: 34px; }
  .season-btn { min-width: 0; }
  .pager { flex-wrap: wrap; }
  .pager-info { width: 100%; margin-left: 0; order: -1; }
}

/* Notatki wieloliniowe: znaki nowej linii z bazy zachowujemy stylem, a nie
   funkcją nl2br. Dzięki temu treść przechodzi przez zwykłe escapowanie
   Blade'a i nigdzie w projekcie nie ma surowego wstawiania HTML-a. */
.note-text.lines { white-space: pre-line; }

/* --- Generator listy wolnych terminów ---------------------------------- */
.copy-text { width: 100%; font: 400 13px/1.6 var(--mono); resize: vertical;
  background: var(--plane); color: var(--ink-2); }
.copy-row { display: flex; align-items: center; gap: 12px; margin-top: 11px; }
.copy-status { font-size: 12.5px; }
.copy-status.is-ok { color: var(--ok); }
.copy-status.is-warn { color: var(--warn); }

/* Pole z adresem dla klienta tuż po skopiowaniu. Zielona obwódka trzyma się
   dwie sekundy — tyle, żeby oko zdążyło ją zauważyć, i nie dłużej, bo potem
   wyglądałaby jak stan pola, a nie jak potwierdzenie czynności. */
[data-do-skopiowania] { cursor: pointer; }
[data-do-skopiowania].is-copied { border-color: var(--ok); box-shadow: 0 0 0 2px color-mix(in srgb, var(--ok) 26%, transparent); }
.free-list { display: grid; gap: 5px; margin-top: 16px;
  padding-top: 14px; border-top: 1px solid var(--line); }
.free-item { display: flex; align-items: center; gap: 10px;
  background: var(--surface-2); border-radius: var(--r-sm); padding: 7px 11px; }
.free-item b { color: var(--ink); font-size: 13.5px; font-variant-numeric: tabular-nums; }
.free-item > span { color: var(--ink-4); font-size: 12px; }
.free-item .chip { margin-left: auto; font-style: normal; }
.free-item .rgo { margin-left: auto; text-decoration: none; font-size: 15px; }
.free-item .chip + .rgo { margin-left: 8px; }
.free-item .rgo:hover { color: var(--gold-300); }
.free-item.is-warned { box-shadow: inset 0 0 0 1px rgba(238,123,60,.28); }

/* Etykieta rodzaju wpisu — te same barwy co w legendzie kalendarza, żeby
   „rezerwacja" wyglądała wszędzie tak samo. */
.chip.kind-order       { background: var(--gold-wash); color: var(--gold-300); border-color: var(--gold-600); }
.chip.kind-reservation { background: var(--warn-wash); color: var(--warn); border-color: rgba(238,123,60,.3); }
.chip.kind-block       { background: rgba(255,255,255,.05); color: var(--ink-3); border-color: var(--line-2); }

/* --- Strony publiczne dla klientów (kwestionariusz, oferta) ------------- */
body.pub { display: block; background: var(--plane); }
.pub-wrap { max-width: 660px; margin: 0 auto; padding: 28px 16px 56px; display: grid; gap: 16px; }
.pub-head { display: flex; align-items: baseline; gap: 10px;
  padding-bottom: 14px; border-bottom: 1px solid var(--line); }
.pub-head b { color: var(--gold-300); font-size: 15px; letter-spacing: .04em; }
.pub-head span { color: var(--ink-4); font-size: 12.5px; }
.pub-wrap h1 { color: var(--ink); font-size: 20px; }
.pub-event { display: flex; gap: 26px; flex-wrap: wrap; margin-top: 16px;
  padding: 13px 15px; background: var(--surface-2); border-radius: var(--r); }
.pub-event span { display: block; color: var(--ink-4); font-size: 11px;
  text-transform: uppercase; letter-spacing: .07em; }
.pub-event b { color: var(--ink); font-size: 14px; }
.pub-done { text-align: center; padding: 34px 20px; }
.pub-tick { width: 52px; height: 52px; margin: 0 auto 16px; border-radius: 50%;
  display: grid; place-items: center; font-size: 26px;
  background: var(--ok-wash); color: var(--ok); }
.pub-foot { color: var(--ink-4); font-size: 12px; text-align: center; padding-top: 8px; }
.check span { line-height: 1.5; }
.check input[type="checkbox"] { flex: none; margin-top: 2px; align-self: flex-start; }

/* Znak zespołu w pasku górnym: własny plik PNG bez tła i zaokrągleń. */
.logo.logo-mark { border-radius: 0; background: none; }

/* --- Podpowiedzi do pól tekstowych ------------------------------------
   Lista pokazuje się dopiero od trzeciego wpisanego znaku (public/js/soz.js).
   Wcześniej wszystkie nazwy siedziały w <datalist> i przy 600 lokalach
   przeglądarka wysypywała na ekran całą bazę. */
.field { position: relative; }

.lookup {
  position: absolute; z-index: 40; left: 0; right: 0; top: 100%;
  margin-top: 4px; max-height: 292px; overflow-y: auto;
  background: var(--surface-2); border: 1px solid var(--line-2);
  border-radius: var(--r); box-shadow: 0 12px 28px rgba(0,0,0,.45);
}
.lookup-item {
  display: block; width: 100%; text-align: left; background: none; border: none;
  border-bottom: 1px solid var(--line); padding: 9px 13px; cursor: pointer;
  font: 13.5px var(--font); color: var(--ink-2);
}
.lookup-item:last-child { border-bottom: none; }
.lookup-item:hover, .lookup-item.is-active { background: var(--surface-3); color: var(--ink); }
.lookup-name   { display: block; color: var(--ink); }
.lookup-detail { display: block; color: var(--ink-4); font-size: 12px; margin-top: 1px; }
.lookup-src {
  display: inline-block; margin-top: 3px; font-size: 10.5px; letter-spacing: .05em;
  text-transform: uppercase; color: var(--gold-300);
}
/* Lista podpowiedzi też jest ustawiana względem okna — inaczej ucinała ją
   karta formularza, a na dole ekranu chowała się pod krawędzią. */
.lookup.is-fixed { position: fixed; left: 0; right: auto; top: 0; margin: 0; }

/* --- Wykresy ----------------------------------------------------------
   Kolory serii są wspólne z resztą systemu i przeszły kontrolę
   rozróżnialności przy daltonizmie na ciemnym tle (najgorsza sąsiadująca
   para: ΔE 15,6 przy deuteranopii, przy progu 8). Siatka i osie celowo
   ledwo widoczne — mają nie konkurować z danymi. */
.chart { width: 100%; height: auto; display: block; }
.chart-grid { stroke: var(--line); stroke-width: 1; }
.chart-axis { fill: var(--ink-4); font-size: 10px; font-family: var(--font); }
.chart-bar-a { fill: var(--series-1); }
.chart-bar-b { fill: var(--series-2); }
.chart g:hover .chart-bar-a { fill: var(--gold-300); }
.chart g:hover .chart-bar-b { fill: #5C9BFF; }

.chart-legend { display: flex; gap: 16px; margin-top: 10px; font-size: 12px; color: var(--ink-3); }
.chart-legend i { display: inline-block; width: 9px; height: 9px; border-radius: 2px;
  margin-right: 6px; vertical-align: middle; }
.chart-legend .lg-a { background: var(--series-1); }
.chart-legend .lg-b { background: var(--series-2); }

/* Dymek na wykresie.

   Zastępuje dymek systemowy z `<title>`: ten pojawia się po sekundzie
   i wygląda jak podpowiedź z lat dziewięćdziesiątych, więc sprawdzenie
   trzech wartości na dwunastu słupkach trwało dłużej niż zajrzenie
   do tabeli. Ten wyskakuje od razu i stoi przy kursorze.

   `position: fixed`, bo dymek żyje na końcu strony i musi trafić
   w miejsce liczone względem okna, nie względem rodzica. `pointer-events:
   none`, bo dymek pod kursorem odbierałby najechanie samemu słupkowi
   i migałby w kółko. */
.chart-tip {
  position: fixed; z-index: 90; pointer-events: none;
  background: var(--surface-3); color: var(--ink);
  border: 1px solid var(--line-2); border-radius: var(--r-sm);
  padding: 7px 11px; font-size: 12.5px; line-height: 1.35;
  box-shadow: 0 6px 22px rgba(0,0,0,.32);
  max-width: 280px;
}
.chart-tip[hidden] { display: none; }

/* Ognisko z klawiatury na słupku — obrys zamiast domyślnej ramki,
   która w SVG bywa niewidoczna. */
.chart g:focus { outline: none; }
.chart g:focus rect:first-of-type { stroke: var(--ink); stroke-width: 1.5; }

/* Poziome paski też mają dymek — te same reguły, inny kształt. */
.hbar-row[data-hint] { cursor: default; }
.hbar-row[data-hint]:hover .hbar-fill { filter: brightness(1.18); }

/* Poziome paski — rodzaje imprez, sale, dni tygodnia. Przy tych danych
   liczy się nazwa (bywa długa) i porównanie długości, a nie precyzyjny
   odczyt wartości z osi. */
.hbars { display: grid; gap: 9px; }
.hbar-row { display: grid; grid-template-columns: 1fr auto; gap: 4px 10px; align-items: baseline; }
.hbar-label { color: var(--ink-2); font-size: 13px; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.hbar-value { color: var(--ink); font-size: 13px; font-weight: 650; }
.hbar-track { grid-column: 1 / -1; height: 7px; border-radius: 4px; background: var(--surface-3); }
.hbar-fill  { height: 100%; border-radius: 4px; background: var(--series-1); min-width: 3px; }
.hbar-sub   { grid-column: 1 / -1; color: var(--ink-4); font-size: 11.5px; margin-top: -2px; }

/* Zmiana wobec poprzedniego sezonu. Kolor NIGDY nie niesie znaczenia sam —
   towarzyszy mu strzałka i liczba. */
.delta { font-size: 12px; font-weight: 650; }
.delta.up   { color: var(--ok); }
.delta.down { color: var(--crit); }
.delta.flat { color: var(--ink-4); }

/* ==========================================================================
   Stopka systemu
   ========================================================================== */
.app-footer {
  margin: 28px 0 6px; padding-top: 14px; border-top: 1px solid var(--line);
  color: var(--ink-4); font-size: 12.5px;
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
}
.app-footer b { color: var(--ink-3); font-weight: 650; }
.app-footer .sep { color: var(--ink-4); }

/* Tekst ciągły — lista zmian. */
.prose h2 { font-size: 19px; margin: 22px 0 8px; }
.prose h3 { font-size: 15.5px; margin: 18px 0 6px; color: var(--gold-300); }
.prose h2:first-child, .prose h3:first-child { margin-top: 0; }
.prose p  { margin: 0 0 10px; }
.prose ul { margin: 0 0 14px; padding-left: 20px; }
.prose li { margin-bottom: 5px; }
.prose hr { border: 0; border-top: 1px solid var(--line); margin: 20px 0; }
.prose code { font-family: var(--mono); font-size: 12.5px; color: var(--gold-300); }

/* ==========================================================================
   Wycena w kalkulatorze

   Świadomie NIE tabela. Tabela na telefonie wypychała kwoty poza ekran —
   trzeba było przesuwać zawartość w bok, żeby zobaczyć to jedyne, po co
   się tu wchodzi. Poniższy układ zwija się sam: przy wąskim ekranie kwota
   ląduje pod nazwą pozycji, zamiast uciekać w prawo.
   ========================================================================== */
.quote { padding: 4px 0; }
.quote-row {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 10px 16px; flex-wrap: wrap;
  padding: 10px 18px; border-bottom: 1px solid var(--line);
}
.quote-row:last-child { border-bottom: 0; }
.quote-label { flex: 1 1 180px; color: var(--ink-2); }
.quote-label b { color: var(--ink); }
.quote-label .hint { display: block; margin-top: 2px; }
.quote-amount { flex: 0 0 auto; color: var(--ink); font-weight: 650;
  font-variant-numeric: tabular-nums; white-space: nowrap; }
.quote-row.is-total { background: var(--gold-wash); }
.quote-row.is-total .quote-amount { color: var(--gold-300); font-size: 18px; }

/* ==========================================================================
   Konta użytkowników
   ========================================================================== */
tr.is-off td { opacity: .62; }
.chip.off { background: var(--surface-3); color: var(--ink-3); }
.row-actions { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
.row-actions form { display: inline; }

/* ==========================================================================
   MOTYW JASNY

   Ten sam układ, inne wartości zmiennych. Nic poza tym blokiem nie wie,
   że motyw w ogóle się zmienia — dlatego przełącznik nie może niczego
   popsuć w widokach.

   Wybór „jak w systemie" (data-theme="system") oddaje decyzję przeglądarce:
   jasny w dzień, ciemny wieczorem, jeśli tak ma ustawiony telefon.

   Kolory serii danych dla jasnego tła są osobne i przeszły ten sam komplet
   kontroli co ciemne (pasmo jasności, minimalna nasycenie, rozróżnialność
   przy daltonizmie, kontrast do powierzchni).
   ========================================================================== */
[data-theme="light"] {
  --plane:        #F4F3EF;
  --surface:      #FFFFFF;
  --surface-2:    #F3F2EE;
  --surface-3:    #E8E6E0;

  --ink:          #17171A;
  --ink-2:        #3D3C39;
  --ink-3:        #6A6862;
  --ink-4:        #93908A;

  --gold-300:     #6B540F;
  --gold-400:     #8A6D14;
  --gold-500:     #B5901E;
  --gold-600:     #6B540F;
  --gold-wash:    rgba(138,109,20,.09);
  --gold-wash-2:  rgba(138,109,20,.16);

  --line:         rgba(0,0,0,.10);
  --line-2:       rgba(0,0,0,.17);
  --grid:         #E2E0DA;

  --ok:           #1A7F37;
  --warn:         #A9520E;
  --crit:         #C22B2B;
  --info:         #1F6FEB;
  --ok-wash:      rgba(26,127,55,.10);
  --warn-wash:    rgba(169,82,14,.10);
  --crit-wash:    rgba(194,43,43,.10);
  --info-wash:    rgba(31,111,235,.10);

  --series-1:     #8A6D14;
  --series-2:     #1F6FEB;
  --series-3:     #0E8C7C;
  --series-4:     #6D53C9;
  --series-5:     #B03060;

  --topbar-bg:  rgba(255,255,255,.88);
  --shadow: 0 1px 2px rgba(0,0,0,.06), 0 8px 24px rgba(0,0,0,.07);
}

@media (prefers-color-scheme: light) {
  [data-theme="system"] {
    --plane:        #F4F3EF;
    --surface:      #FFFFFF;
    --surface-2:    #F3F2EE;
    --surface-3:    #E8E6E0;

    --ink:          #17171A;
    --ink-2:        #3D3C39;
    --ink-3:        #6A6862;
    --ink-4:        #93908A;

    --gold-300:     #6B540F;
    --gold-400:     #8A6D14;
    --gold-500:     #B5901E;
    --gold-600:     #6B540F;
    --gold-wash:    rgba(138,109,20,.09);
    --gold-wash-2:  rgba(138,109,20,.16);

    --line:         rgba(0,0,0,.10);
    --line-2:       rgba(0,0,0,.17);
    --grid:         #E2E0DA;

    --ok:           #1A7F37;
    --warn:         #A9520E;
    --crit:         #C22B2B;
    --info:         #1F6FEB;
    --ok-wash:      rgba(26,127,55,.10);
    --warn-wash:    rgba(169,82,14,.10);
    --crit-wash:    rgba(194,43,43,.10);
    --info-wash:    rgba(31,111,235,.10);

    --series-1:     #8A6D14;
    --series-2:     #1F6FEB;
    --series-3:     #0E8C7C;
    --series-4:     #6D53C9;
    --series-5:     #B03060;

    --topbar-bg:  rgba(255,255,255,.88);
  --shadow: 0 1px 2px rgba(0,0,0,.06), 0 8px 24px rgba(0,0,0,.07);
  }
}

/* Podświetlenie słupka przy najechaniu — w jasnym motywie musi ciemnieć,
   a nie jaśnieć, inaczej znika w tle. */
[data-theme="light"] .chart g:hover .chart-bar-a { fill: #6B540F; }
[data-theme="light"] .chart g:hover .chart-bar-b { fill: #1550B8; }

@media (prefers-color-scheme: light) {
  [data-theme="system"] .chart g:hover .chart-bar-a { fill: #6B540F; }
  [data-theme="system"] .chart g:hover .chart-bar-b { fill: #1550B8; }
}

/* Wypunktowanie opisu oferty na stronie dla klienta. Odstępy większe niż
   w zwykłej liście — to się CZYTA, a nie przegląda wzrokiem. */
.offer-list { margin: 0; padding-left: 20px; color: var(--ink-2); }
.offer-list li { margin-bottom: 7px; line-height: 1.55; }
.offer-list li::marker { color: var(--gold-400); }

/* Klikalny cały wiersz tabeli. JEDYNY SPOSÓB, W JAKI TO ROBIMY.

   Link obejmuje wyłącznie tytuł, a wiersz bywa szeroki na pół ekranu —
   trafienie w kilkunastoznakowy numer wymaga celowania, zwłaszcza na
   telefonie. `::after` rozciąga obszar kliknięcia na cały wiersz, ale
   element pozostaje ZWYKŁYM ODNOŚNIKIEM: działa klawiatura, środkowy
   przycisk myszy i „otwórz w nowej karcie".

   CZEMU NIE `onclick` NA WIERSZU. Poza tym, że odbierałby wszystkie trzy
   powyższe rzeczy — po prostu NIE DZIAŁA. W listach zleceń i umów stało
   dokładnie to i było martwe: nasza polityka bezpieczeństwa treści ma
   `script-src` bez `'unsafe-inline'`, więc przeglądarka odmawia wykonania
   skryptu wpisanego w atrybut. Odmawia po cichu — na stronie nic się nie
   dzieje, komunikat idzie tylko do konsoli. Stąd wrażenie, że „klikanie
   w wiersz przestało działać": klikać dawało się wyłącznie w datę, bo tylko
   ona była prawdziwym odnośnikiem.

   Sprawdzone w przeglądarce, nie na oko: nakładka pokrywa całą szerokość
   wiersza (element pod kursorem w ostatniej komórce to `a.stretch`), a ten
   sam `onclick` bez nagłówka CSP działa — czyli to nagłówek go wyciął,
   a nie błąd w pomiarze. Krok 13 w `tools/check_project.sh` pilnuje,
   żeby atrybut `on*` nie wrócił do żadnego szablonu. */
.tbl tr.row-link:hover { background: var(--surface-2); }

/* NAKŁADKI `::after` TU JUŻ NIE MA — i to jest cała historia tej sekcji.
   Zostawiam ją opisaną, bo wygląda jak rozwiązanie lepsze od obecnego
   i ktoś (ja za rok) będzie chciał do niej wrócić.

   Działało to tak: `position: relative` na `<tr>`, a na odnośniku z datą
   `::after { inset: 0 }` — przezroczysta nakładka na cały wiersz. Zaleta
   nie do przecenienia: wiersz zostawał ZWYKŁYM ODNOŚNIKIEM, więc działała
   klawiatura, środkowy przycisk myszy i „otwórz w nowej karcie", bez linijki
   JavaScriptu. Sprawdziłem to w przeglądarce i przechodziło.

   Sprawdziłem w CHROMIUM. A Safari na iPhonie NIE UZNAJE `position: relative`
   na wierszu tabeli — nakładka nie ma się więc do czego przyczepić i bierze
   za punkt odniesienia najbliższego pozycjonowanego przodka, czyli w praktyce
   pół strony. Skutek na telefonie: kliknięcie gdziekolwiek otwierało jakiś
   wpis, zwykle nie ten, w który się celowało.

   Dlatego wiersz obsługuje teraz JavaScript (moduł „klikalny wiersz"
   w public/js/soz.js). Odnośnik z datą zostaje na miejscu i jest nadal
   prawdziwym odnośnikiem — klawiatura i „otwórz w nowej karcie" działają
   przez niego, a nie przez nakładkę. Skrypt tylko rozszerza obszar
   trafienia na resztę wiersza. */
/* Kursor „rączka" nad CAŁYM wierszem, nie tylko nad tytułem — bo to jedyny
   znak, że w wiersz w ogóle wypada kliknąć. Nakładka i tak jest odnośnikiem,
   ale komórki pod nią mają własny kursor tekstowy. */
.tbl tr.row-link > td { cursor: pointer; }
/* Kursor w środku wiersza. Odnośniki i przyciski zachowują swój własny —
   „rączka" nad polem tekstowym sugerowałaby, że kliknięcie coś otworzy,
   a ono ma po prostu przyjąć tekst. Tego, co dzieje się przy kliknięciu,
   pilnuje skrypt (patrz wyżej), a nie warstwy `z-index`. */
.tbl tr.row-link input,
.tbl tr.row-link select,
.tbl tr.row-link textarea,
.tbl tr.row-link label { cursor: auto; }
.tbl tr.row-link a,
.tbl tr.row-link button { cursor: pointer; }

/* ==========================================================================
   MOTYW „ŻYWY"

   Trzeci wariant, wzorowany na SOZ 1.9. Tamten system stał na Bootstrapie
   z gotowym szablonem: białe tło treści, szare menu, kolorowe kafle stanów.
   Wokalistka pracowała w nim kilka lat i ma to w rękach — dla niej ciemny
   motyw ze złotem jest nie tyle brzydki, ile OBCY, a przy wpisywaniu
   dziesiątego zlecenia w tygodniu obcość kosztuje czas.

   Czym różni się od jasnego:
     · treść jest BIAŁA, nie kremowa — menu i pasek górny wyraźnie szare,
       więc widać, gdzie kończy się nawigacja, a zaczyna praca;
     · akcentem jest niebieski, nie złoto — kolor marki zostaje na papierze
       (umowy, oferty), w interfejsie ustępuje czytelności;
     · stany są nasycone, jak kafle z 1.9: zielony, pomarańczowy, czerwony.

   Kolory serii przeszły pełną kontrolę na białym tle (pasmo jasności,
   nasycenie, rozróżnialność przy daltonizmie, kontrast):
   najgorsza sąsiadująca para ma ΔE 13,0 przy deuteranopii, przy progu 8.
   Nie zmieniaj ich „na oko".
   ========================================================================== */
[data-theme="vivid"] {
  --plane:        #FFFFFF;   /* tło treści — białe, o to chodzi */
  --surface:      #FFFFFF;
  --surface-2:    #F1F3F7;
  --surface-3:    #E4E8EF;

  --ink:          #17171A;
  --ink-2:        #3A3D42;
  --ink-3:        #5B6068;
  --ink-4:        #6A6F77;

  /* „Złoto" w tym motywie znaczy niebieski. Nazwy zmiennych zostają te same,
     bo używa ich cały arkusz — przemianowanie ich w trzech motywach naraz
     dałoby trzy okazje na pomyłkę i ani jednej korzyści. */
  --gold-300:     #0A4FB5;
  --gold-400:     #0B5ED7;
  --gold-500:     #0B5ED7;
  --gold-600:     #0A4FB5;
  --gold-wash:    rgba(11,94,215,.08);
  --gold-wash-2:  rgba(11,94,215,.16);

  --line:         rgba(0,0,0,.11);
  --line-2:       rgba(0,0,0,.18);
  --grid:         #DFE3EA;

  --ok:           #1A7F37;
  --warn:         #A9520E;
  --crit:         #C22B2B;
  --info:         #0B5ED7;
  --ok-wash:      rgba(26,127,55,.12);
  --warn-wash:    rgba(169,82,14,.12);
  --crit-wash:    rgba(194,43,43,.12);
  --info-wash:    rgba(11,94,215,.12);

  --series-1:     #0B5ED7;
  --series-2:     #C2410C;
  --series-3:     #03897B;
  --series-4:     #6D28D9;
  --series-5:     #BE185D;

  --topbar-bg:    rgba(233,236,241,.94);
  --shadow: 0 1px 2px rgba(16,24,40,.06), 0 8px 22px rgba(16,24,40,.08);
}

/* Menu i pasek górny SZARE, treść biała. To jedyne miejsce w całym arkuszu,
   w którym motyw robi coś więcej niż podmianę zmiennych — bo w pozostałych
   dwóch nawigacja ma to samo tło co strona i nie ma czego rozdzielać. */
[data-theme="vivid"] .sidebar { background: #E9ECF1; border-right-color: rgba(0,0,0,.10); }
[data-theme="vivid"] .topbar  { border-bottom-color: rgba(0,0,0,.10); }
[data-theme="vivid"] .nav-item:hover { background: #DBE0E9; }
[data-theme="vivid"] .nav-item.active { background: var(--gold-wash-2); color: var(--gold-300); }

/* Karta na białym tle musi mieć widoczną krawędź — inaczej biel na bieli
   znosi podział na kafle i strona robi się jedną płachtą. */
[data-theme="vivid"] .card { border-color: rgba(0,0,0,.12); box-shadow: var(--shadow); }

/* Znak: pasek górny jest jasny, więc obowiązuje wersja ciemna. */
[data-theme="vivid"] .logo-on-dark  { display: none; }
[data-theme="vivid"] .logo-on-light { display: block; }

[data-theme="vivid"] .chart g:hover .chart-bar-a { fill: #0A4FB5; }
[data-theme="vivid"] .chart g:hover .chart-bar-b { fill: #9A340A; }

/* ==========================================================================
   ŚRODOWISKO TESTOWE

   Pasek na samej górze, nad paskiem systemu, przyklejony i bez przycisku
   zamykania. Ostrzeżenie, które da się schować, jest schowane po dwóch dniach
   — a wtedy ktoś wpisuje prawdziwą rezerwację do systemu, który za tydzień
   zostanie skasowany.

   KOLOR JEST POMARAŃCZOWY, NIE CZERWONY. Czerwony w tym systemie znaczy
   „coś jest zepsute" (`--crit`, odwołane zlecenia, błędy). Środowisko testowe
   nie jest awarią — jest stanem, w którym wszystko działa poprawnie, tylko
   nie na prawdziwych danych. Czerwony pasek wiszący cały czas nauczyłby oko
   ignorować także prawdziwe komunikaty o błędach.

   Reszta układu zjeżdża o wysokość paska. Wszystkie trzy elementy trzymane
   są `position: fixed`, więc bez tego pasek zasłoniłby nagłówek systemu.
   ========================================================================== */
:root { --test-bar-h: 34px; }

.test-bar {
  position: fixed; inset: 0 0 auto 0; height: var(--test-bar-h); z-index: 60;
  display: flex; align-items: center; gap: 12px; padding: 0 16px;
  background: var(--warn); color: #1B1206;
  font-size: 12.5px; line-height: 1.2;
  box-shadow: 0 1px 0 rgba(0,0,0,.25);
}
.test-bar b { letter-spacing: .06em; font-size: 12px; flex: none; }
.test-bar span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.test-bar-ver { margin-left: auto; opacity: .75; flex: none; }

body.is-test .topbar  { top: var(--test-bar-h); }
body.is-test .sidebar { top: calc(var(--topbar-h) + var(--test-bar-h)); }
body.is-test .main    { margin-top: calc(var(--topbar-h) + var(--test-bar-h)); }

/* NA TELEFONIE UKŁAD JEST INNY I TE TRZY REGUŁY WYŻEJ NIE WYSTARCZAJĄ.

   Poniżej 900 px menu przestaje być kolumną z boku: `.sidebar` dostaje
   `position: static` i schodzi pod pasek systemu WŁASNYM MARGINESEM
   (`margin-top: var(--topbar-h)`). Na elemencie nierozmieszczonym
   bezwzględnie właściwość `top` nie robi nic — więc menu zostawało pod
   paskiem systemu zepchniętym w dół przez pasek testowy i po prostu
   znikało pod nim. Na telefonie nie dało się w nie kliknąć.

   Do tego `.main` na telefonie ma `margin: 0`, bo płynie za menu w zwykłym
   układzie strony. Odziedziczony `margin-top` z reguły wyżej wstawiłby tam
   dziewięćdziesiąt pikseli pustego miejsca u góry każdej strony.

   Stąd oba przypadki rozdzielone. Sprawdzone w przeglądarce na 390 px:
   tools/ — patrz proof w opisie zmiany. */
@media (max-width: 900px) {
  /* Na telefonie odstęp od pasków liczy `<body>` (patrz blok wyżej),
     więc menu i treść nie odsuwają się już same. */
  body.is-test .sidebar { margin-top: 0; }
  body.is-test .main    { margin-top: 0; }
}

/* Na wąskim ekranie z paska zostaje sam napis — na zdanie wyjaśniające nie
   ma miejsca, a urwane w połowie byłoby gorsze niż jego brak. */
@media (max-width: 720px) {
  .test-bar span:not(.test-bar-ver) { display: none; }
}

/* Strony bez menu — logowanie, odzyskiwanie hasła i widoki dla klienta —
   mają własny układ (`.auth-page`) i nie mają czego przesuwać poza samą
   treścią. Bez tego pasek zasłania górę formularza. */
body.is-test.auth-page { padding-top: var(--test-bar-h); }
