/* Style bazowe — komponenty wg wzorców sekcji 5, WCAG wg sekcji 6 kontekstu. */

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

body {
  margin: 0;
  background: var(--tlo-strony);
  color: var(--tekst);
  font-family: var(--czcionka);
  font-size: 17px;
  line-height: 1.5;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

/* 2.4.7 / 2.4.11 — fokus widoczny na każdym tle */
:focus-visible {
  outline: 3px solid var(--fokus);
  outline-offset: 2px;
}

.pomin-do-tresci {
  position: absolute;
  left: -9999px;
  background: var(--tlo-karty);
  color: var(--akcja);
  padding: 12px 16px;
  z-index: 10;
}

.pomin-do-tresci:focus {
  left: 8px;
  top: 8px;
}

/* pasek górny: granat + pas czerwieni 3 px */
.pasek-gorny {
  background: var(--granat-marki);
  color: #ffffff;
  border-bottom: 3px solid var(--czerwien-marki);
  padding: 12px 24px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}

.pasek-gorny__znak {
  font-weight: 700;
  font-size: 17px;
  color: #ffffff;
  text-decoration: none;
}

.pasek-gorny__uzytkownik {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 15px;
  flex-wrap: wrap;
}

/* Nazwisko w pasku jako wejście na „Moje konto" (M10-K1). Kolor paska, podkreślenie mówi,
   że to odnośnik — sam kolor na granatowym tle by tego nie powiedział (WCAG 1.4.1). */
.pasek-gorny__konto {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 3px;
}

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

main {
  flex: 1;
  width: 100%;
}

/* pas oznaczeń projektu — wysokość stała, poza obszarem treści */
.pas-oznaczen {
  background: var(--tlo-karty);
  border-top: 1px solid var(--ramka-karty);
  min-height: 64px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 24px;
  padding: 8px 24px;
  flex-wrap: wrap;
  font-size: 15px;
  color: var(--tekst-pomocniczy);
}

/* karta logowania */
.logowanie {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 44px 16px;
  gap: 20px;
}

.logowanie__naglowek {
  text-align: center;
  max-width: 560px;
}

.logowanie__naglowek h1 {
  font-size: 30px;
  font-weight: 700;
  line-height: 1.15;
  color: var(--granat-marki);
  margin: 0 0 8px;
}

.logowanie__podtytul {
  color: var(--tekst-pomocniczy);
  font-size: 16px;
  margin: 0;
}

/* KARTA WYPEŁNIA SWÓJ POJEMNIK. Do 2026-09-17 stało tu `max-width: 560px` — miara kolumny
   tekstu dobrana dla karty logowania — i obowiązywała KAŻDĄ kartę w systemie. Skutkiem był
   pas pustego miejsca po prawej na ekranach treści: pomiar z 2026-09-17 dał 26 bloków poniżej
   progu udziału, w tym kartę 560 px w torze 1637 px (34%). Polecenie Władysława: ekrany mają
   wypełniać szerokość.
   Miara kolumny tekstu ZOSTAJE, ale tam, gdzie jest regułą UKŁADU, a nie domyślną wartością:
   w rodzinie `.logowanie` (logowanie, przypomnienie hasła, strona statusu, odmowy ekranów),
   która jest WYŚRODKOWANA — tam wąska kolumna nie zostawia pustego pasa z jednej strony,
   tylko symetryczny margines, i jest tym, czego żąda czytelność zdania.
   Modyfikator `karta--szeroka` zniknął razem z tą zmianą: zdejmował ograniczenie, którego
   już nie ma. */
.karta {
  background: var(--tlo-karty);
  border: 1px solid var(--ramka-karty);
  border-radius: var(--promien);
  padding: 28px;
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 18px;
}

/* Rodzina wyśrodkowana — jedyne miejsce, w którym miara kolumny tekstu jest regułą układu. */
.logowanie > .karta {
  max-width: 560px;
}

.karta h2 {
  font-size: 24px;
  font-weight: 700;
  line-height: 1.2;
  margin: 0;
  color: var(--granat-marki);
}

/* pola formularza */
.pole {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.pole label {
  font-size: 16px;
  font-weight: 600;
}

/* Kontrolka tekstowa pola — lista WYKLUCZAJĄCA, nie wyliczająca typy. Wyliczanie („email,
   password, text") zostawiało bez stylu każdy typ dopisany później: `tel` w kartotece
   personelu, `number` przy liczbie dzieci, `date` i `time` w kreatorze — pola miały wygląd
   domyślny przeglądarki obok pól ostylowanych (znalezione oglądaniem 2026-09-01).
   Wykluczone są typy, które NIE są prostokątem tekstowym i mają własne reguły niżej:
   pole wyboru, radio, przycisk i pole ukryte. */
.pole input:not([type="checkbox"], [type="radio"], [type="submit"], [type="button"], [type="hidden"]),
.pole textarea,
.pole select {
  min-height: 48px;
  padding: 10px 12px;
  font: inherit;
  border: 2px solid var(--ramka-pola);
  border-radius: var(--promien);
  background: var(--tlo-karty);
  color: var(--tekst);
}

.pole input[aria-invalid="true"] {
  border-color: var(--blad-ramka);
}

/* Wszystko pod kontrolką: podpis i komunikat błędu. Odstęp taki sam jak między elementami
   pola (6 px), bo stopka jest przegrodą techniczną — czytelnik ma nie widzieć, że istnieje.
   Po co jest, mówi komentarz przy `.pola-obok`. */
.pole__stopka {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.pole__podpis {
  font-size: 15px;
  color: var(--tekst-pomocniczy);
}

.pole__blad {
  font-size: 15px;
  color: var(--blad-tekst);
  font-weight: 600;
}

.pole-haslo {
  display: flex;
  gap: 8px;
  align-items: stretch;
}

.pole-haslo input {
  flex: 1;
  /* Bez tego pole nie kurczy się poniżej swojej szerokości naturalnej i przy 390 px wypycha
     przycisk „Pokaż" poza ekran — zmierzone 2026-09-28 na „Moje konto" (5 px przewijania
     poziomego w karcie z wewnętrznym odstępem). Na ekranie logowania karta jest szersza, więc
     tam tego nie było widać. */
  min-width: 0;
}

/* Pole tylko do odczytu z czynnością obok (karta osoby: placówka i „Przenieś do innej
   placówki", Q173). Z zawijaniem, w odróżnieniu od pola hasła: etykieta czynności jest dłuższa
   niż „Pokaż" i przy 390 px nie mieści się obok pola — przycisk schodzi wtedy pod nie, zamiast
   rozpychać stronę w poziomie. */
.pole-z-akcja {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: stretch;
}

.pole-z-akcja input {
  flex: 1 1 12rem;
  min-width: 0;
}

.wybor {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 16px;
}

.wybor input[type="checkbox"] {
  width: 24px;
  height: 24px;
  accent-color: var(--akcja);
}

/* grupa pól radio — wybór, przy którym skutek każdej opcji stoi obok niej (makieta M1) */
.wybory {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 16px;
  border: 1px solid var(--ramka-karty);
  border-radius: var(--promien);
}

.wybory legend {
  padding: 0 6px;
  font-size: 16px;
  font-weight: 600;
}

.wybory[aria-invalid="true"] {
  border-color: var(--blad-ramka);
}

/* Opis skutku stoi POD etykietą, w tej samej kolumnie — inaczej rozjeżdża się
   z kontrolką przy dłuższym zdaniu. Cel dotykowy 44 px z odstępem (2.5.8). */
.wybory .wybor {
  display: grid;
  grid-template-columns: auto 1fr;
  column-gap: 10px;
  row-gap: 2px;
  align-items: center;
  min-height: 44px;
}

.wybory input[type="radio"] {
  width: 24px;
  height: 24px;
  accent-color: var(--akcja);
}

.wybor__opis {
  grid-column: 2;
  font-size: 15px;
  color: var(--tekst-pomocniczy);
}

/* przyciski */
.przycisk {
  font: inherit;
  font-weight: 600;
  border-radius: var(--promien);
  cursor: pointer;
  min-height: 48px;
  padding: 10px 22px;

  /* Przycisk musi być BLOKIEM w linii, nie elementem inline. Element inline nie ma
     wysokości: `min-height` i wypełnienie wychodzą wtedy poza wiersz i nachodzą na tekst
     nad przyciskiem — w panelu „wymaga poprawy" przycisk zakrywał 11 px komentarza PLZ,
     czyli treści, po którą nauczyciel tam wchodzi (znalezione oglądaniem 2026-09-01).
     Element `<button>` ma to z natury, `<a class="przycisk">` nie — a przycisk bywa jednym
     i drugim. `align-items` domyka rzecz: napis stoi w pionie na środku, nie przy górnej
     krawędzi wypełnienia. */
  display: inline-flex;
  align-items: center;
  justify-content: center;

  /* Przycisk bywa odnośnikiem („Dodaj salę", „Anuluj", powroty z ekranów odmowy) — bez tego
     dziedziczy podkreślenie z odnośnika i wygląda jak przycisk z linią pod napisem. */
  text-decoration: none;
}

.przycisk--podstawowy {
  background: var(--akcja);
  border: 2px solid var(--akcja);
  color: #ffffff;
}

.przycisk--podstawowy:hover {
  background: var(--akcja-hover);
  border-color: var(--akcja-hover);
}

.przycisk--pomocniczy {
  background: var(--tlo-karty);
  border: 2px solid var(--ramka-pola);
  color: var(--tekst);
  min-height: 44px;
}

.przycisk--w-pasku {
  background: transparent;
  border: 2px solid #ffffff;
  color: #ffffff;
  min-height: 44px;
}

/* panele komunikatów — 4 odmiany; kolor nigdy sam (podpis słowny w treści) */
.panel {
  border: 2px solid;
  border-radius: var(--promien);
  padding: 14px 16px;
  font-size: 16px;
}

.panel--blad {
  border-color: var(--blad-ramka);
  background: var(--blad-tlo);
  color: var(--blad-tekst);
}

.panel--sukces {
  border-color: var(--sukces-ramka);
  background: var(--sukces-tlo);
  color: var(--sukces-tekst);
}

.panel--ostrzezenie {
  border-color: var(--ostrzezenie-ramka);
  background: var(--ostrzezenie-tlo);
  color: var(--ostrzezenie-tekst);
}

.panel--neutralny {
  border-color: var(--neutralny-ramka);
  background: var(--neutralny-tlo);
  color: var(--neutralny-tekst);
}

.panel h3 {
  margin: 0 0 6px;
  font-size: 17px;
}

.panel p {
  margin: 0;
}

/* Przycisk wyjścia z panelu — odsunięty od zdania, które go uzasadnia. Panel bez odstępu
   sklejał akcję z ostatnim wierszem treści i przycisk czytał się jak część zdania. */
.panel__akcja {
  margin-top: 12px;
}

/* PRZEDRUK: sekcja z nagłówkiem i OSOBNYM PANELEM NA KAŻDY PLAN (rozdz. 13.6, układ
   z 2026-09-17). Do tego dnia była to jedna lista w jednym panelu — a każdy plan ma własne
   trzy kontrolki i własne potwierdzenie, więc jest osobnym zadaniem. Ten sam kształt co
   `.do-poprawy`, bo to ten sam wzorzec: „kilka rzeczy do zrobienia, każda ze swoim wyjściem". */
.do-przedruku {
  margin-bottom: 20px;
}

.do-przedruku h2 {
  font-size: 20px;
  margin: 0 0 10px;
}

/* Skutek RAZ, nad panelami: jest taki sam dla wszystkich planów, a powtórzony tyle razy,
   ile planów, przestaje być czytany. */
.do-przedruku__skutek {
  margin: 0 0 12px;
  color: var(--tekst-pomocniczy);
}

/* Trzy kontrolki jednego planu w rzędzie, zawijane dopiero przy braku miejsca. Bez tego
   `<form>` przycisku „potwierdzam" jest elementem blokowym i łamie wiersz ZAWSZE. */
.do-przedruku__akcje {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

.do-przedruku__akcje form {
  margin: 0;
}

/* ODSTĘP POD PANELEM JEST WŁASNOŚCIĄ PANELU, NIE JEGO POJEMNIKA.
   Do 2026-09-17 reguła wymieniała pojemniki (`main`, `.karta-tresci`, `dialog`, `form`…)
   i obowiązywała wyłącznie ich BEZPOŚREDNIE dzieci. Skutek był taki, że panel postawiony
   w sekcji — a tak stoją alerty przedruku i alerty „do poprawy" — nie dostawał ani jednego
   piksela przerwy i sąsiednie alerty **stykały się ramkami**. Wada wracała dwa razy w jeden
   dzień: najpierw na pulpicie (dopisano `.pulpit` do listy), potem w sekcji alertów
   przedruku — czyli lista pojemników jest tym rodzajem mechanizmu, który trzeba pamiętać
   rozszerzać, a więc zabezpieczeniem poziomu 5. Teraz nie ma listy: odstęp ma KAŻDY panel,
   gdziekolwiek stoi.
   `:not(:last-child)` — po ostatnim panelu odstęp robi już wyściółka albo margines
   pojemnika, a dodatkowy margines rozpychałby kartę od dołu. */
.panel:not(:last-child) {
  margin-bottom: 16px;
}

/* JEDYNY WYJĄTEK, i jest nim RODZAJ POJEMNIKA, nie jego nazwa: pojemnik układający dzieci
   właściwością `gap` odmierza odstęp sam, a margines by się do niego DODAŁ i dał podwójną
   przerwę. Lista obejmuje pojemniki z `gap`, które mogą nieść panele. */
:where(.karta, .karty-para, .karty-obok, .kreator, .logowanie) > .panel {
  margin-bottom: 0;
}

/* 1.4.10 reflow — bez poziomego przewijania od 320 px.
   Cele dotykowe mobile z tabeli §4 kontekstu: akcja główna 56 px, pomocnicza 52 px,
   pola formularza i listy wyboru 52 px. */
@media (max-width: 480px) {
  .karta {
    padding: 18px;
  }

  .przycisk--podstawowy {
    min-height: 56px;
    width: 100%;
  }

  .przycisk--pomocniczy {
    min-height: 52px;
  }

  .pole input:not([type="checkbox"], [type="radio"], [type="submit"], [type="button"], [type="hidden"]),
  .pole textarea,
  .pole select {
    min-height: 52px;
  }
}

/* ── układ z nawigacją boczną (makieta: pasek górny → nawigacja 220 px → treść) ── */
.uklad {
  display: flex;
  flex: 1;
  align-items: stretch;
  width: 100%;
}

.nawigacja {
  flex: 0 0 220px;
  background: var(--tlo-karty);
  border-right: 1px solid var(--ramka-karty);
  padding: 16px 0;
}

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

.nawigacja__pozycja {
  display: block;
  min-height: 48px;
  padding: 13px 20px;
  color: var(--tekst);
  text-decoration: none;
  font-weight: 600;
  border-left: 4px solid transparent;
}

.nawigacja__pozycja:hover {
  background: var(--tlo-naglowka);
}

.nawigacja__pozycja--biezaca {
  border-left-color: var(--akcja);
  background: var(--tlo-naglowka);
  color: var(--akcja);
}

.uklad__tresc {
  flex: 1 1 auto;
  min-width: 0;
  padding: 20px 24px 32px;
}

/* Pulpit nauczyciela (Q100) wypełnia obszar treści. Stało tu `max-width: 980px` przez pół
   dnia 2026-09-17 — zdjęte poleceniem Władysława tego samego dnia: ograniczenie zostawiało
   657 px pustego miejsca po prawej przy 1920 px i to było pierwsze, co widać po zalogowaniu. */
.pulpit {
  width: 100%;
}

.okruszki {
  display: flex;
  gap: 8px;
  align-items: center;
  font-size: 15px;
  color: var(--tekst-pomocniczy);
  margin-bottom: 16px;
}

.okruszki a {
  color: var(--akcja);
}

/* ── nagłówek strony z nawigacją miesięcy ── */
.naglowek-strony {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 20px;
}

.naglowek-strony__miesiac {
  display: flex;
  align-items: center;
  gap: 12px;
}

/* Nagłówek z PODTYTUŁEM pod nazwą, a nie z drugą treścią obok niej. Domyślny nagłówek jest
   rzędem („Mój plan" ⟷ „wrzesień 2026"); tu adres i gmina opisują to, co stoi w H1, więc
   muszą stać POD nim, nie zostać zepchnięte na prawą krawędź. */
.naglowek-strony--z-podtytulem {
  display: block;
}

.naglowek-strony__podtytul {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  margin: 6px 0 0;
  color: var(--tekst-pomocniczy);
}

.naglowek-strony h1 {
  font-size: 28px;
  font-weight: 700;
  line-height: 1.2;
  margin: 0;
  color: var(--granat-marki);
}

.przycisk--strzalka {
  min-width: 44px;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
  font-weight: 700;
  color: var(--akcja);
  border-color: var(--akcja);
  text-decoration: none;
}

/* ── planer: siatka miesiąca nad panelem limitów ──
   Kalendarz na CAŁĄ szerokość, limity pod nim (polecenie zamawiającego 2026-09-02).
   Wcześniej limity zajmowały 340 px prawej kolumny — po dodaniu sobót i niedziel siatka
   ma siedem kolumn zamiast pięciu i w węższej kolumnie bloki zajęć zlewały się w słupki. */
.planer {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.planer__siatka {
  min-width: 0;
}

.planer__limity {
  background: var(--tlo-karty);
  border: 2px solid var(--granat-marki);
  border-radius: var(--promien);
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.planer__limity h2 {
  margin: 0;
  font-size: 20px;
  color: var(--granat-marki);
}

.miesiac {
  width: 100%;
  border-collapse: separate;
  border-spacing: 6px;
  table-layout: fixed;
}

.miesiac__podpis {
  text-align: left;
  font-size: 15px;
  color: var(--tekst-pomocniczy);
  padding-bottom: 8px;
}

.miesiac th {
  font-size: 14px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  background: var(--tlo-naglowka);
  color: var(--tekst-pomocniczy);
  padding: 8px 4px;
  text-align: left;
}

.miesiac__dzien {
  /* Wyłącznie min-height: sztywna wysokość kontenera tekstu łamie 1.4.12 (odstępy
     tekstu) — przy interlinii 1.5× treść musi móc rozepchnąć komórkę. */
  min-height: 118px;
  vertical-align: top;
  border: 1px solid var(--ramka-karty);
  background: var(--tlo-karty);
  padding: 6px;
}

.miesiac__dzien--poza {
  background: var(--tlo-pustego);
  border-style: dashed;
}

/* Sobota i niedziela: w siatce SĄ, ale zajęć w nich nie będzie (weekend zostaje blokadą
   zapisu — KrokDzienWolny, Q84). Odcień to tylko podpowiedź; informację niesie nazwa dnia
   w nagłówku kolumny i w komórce, nie kolor (WCAG 1.4.1).
   Ten sam token co `.miesiac th` powyżej, i to jest CELOWE, a nie przypadek: kolumna
   weekendowa czyta się wtedy jako jeden pas ciągnący się od nagłówka w dół. Osobnej klasy
   na sam nagłówek dlatego NIE MA — nadałaby mu ten sam kolor, który już ma. */
.miesiac__dzien--wolny {
  background: var(--tlo-naglowka);
}

.miesiac__numer {
  display: block;
  font-size: 15px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  margin-bottom: 4px;
}

/* Nagłówek tabeli niesie nazwę dnia na szerokim ekranie, więc w komórce byłaby powtórzeniem.
   Odsłaniana dopiero w reflow, gdzie <thead> znika — patrz media query niżej. */
.miesiac__dzien-nazwa {
  display: none;
}

.zajecia {
  display: flex;
  flex-direction: column;
  border-left: 4px solid;
  border-radius: var(--promien);
  padding: 6px 8px;
  margin-bottom: 4px;
  font-size: 14px;
}

.zajecia__godzina {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.zajecia__szczegoly,
.zajecia__stan {
  font-size: 13px;
  color: var(--tekst-pomocniczy);
}

.zajecia--zaakceptowane {
  border-left-color: var(--sukces-ramka);
  background: var(--sukces-tlo);
}

.zajecia--oczekuje {
  border-left-color: var(--neutralny-ramka);
  background: var(--neutralny-tlo);
}

.zajecia--do-poprawy {
  border-left-color: var(--ostrzezenie-ramka);
  background: var(--ostrzezenie-tlo);
}

/* Sześć stanów obiegu (makieta M5) potrzebuje sześciu wyglądów. Kolor nigdy nie niesie
   informacji sam (WCAG 1.4.1) — każdy blok ma podpis słowny w `.zajecia__stan`. */
.zajecia--robocze {
  border-left-color: var(--nieaktywny-ramka);
  background: var(--nieaktywny-tlo);
}

.zajecia--wycofane {
  border-left-color: var(--nieaktywny-ramka);
  background: var(--nieaktywny-tlo);
  text-decoration: line-through;
}

.legenda {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  list-style: none;
  margin: 12px 0 0;
  padding: 0;
  font-size: 15px;
}

.legenda li {
  display: flex;
  align-items: center;
  gap: 8px;
}

.legenda__znak {
  width: 16px;
  height: 16px;
  border-left-width: 4px;
  border-left-style: solid;
  display: inline-block;
}

/* ── panel limitów ── */

/* Panel stoi pod siatką i na całą szerokość, więc wiersze limitów układają się w tyle
   kolumn, ile się zmieści. 300 px to szerokość, przy której podpis „6 z 32 jednostek ·
   zostaje 26 jednostek" jeszcze nie łamie się na trzy wiersze. */
.limity__lista {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 16px 24px;
}

.limit {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--linia-tabeli);
}

.limit__nazwa {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/* natywny <progress>: bez stylu inline i bez własnej semantyki paska */
.limit__pasek {
  display: block;
  width: 100%;
  height: 12px;
  appearance: none;
  background: var(--postep-tlo);
  border: 1px solid var(--postep-ramka);
  border-radius: var(--promien);
}

.limit__pasek::-webkit-progress-bar {
  background: var(--postep-tlo);
}

.limit__pasek::-webkit-progress-value {
  background: var(--akcja);
}

.limit__pasek::-moz-progress-bar {
  background: var(--akcja);
}

.limit__podpis {
  font-size: 15px;
  color: var(--tekst-pomocniczy);
  font-variant-numeric: tabular-nums;
}

.limit--ostrzezenie .limit__nazwa,
.limit--ostrzezenie .limit__podpis {
  color: var(--ostrzezenie-tekst);
}

.limit--ostrzezenie .limit__pasek::-webkit-progress-value {
  background: var(--ostrzezenie-ramka);
}

.limit--ostrzezenie .limit__pasek::-moz-progress-bar {
  background: var(--ostrzezenie-ramka);
}

/* 1.4.10 reflow — na 390 px siatka miesiąca ustępuje liście dni (pusta krata nie niesie
   informacji); jeden szablon, przełączenie CSS-em.
   Kolejności pionowej ten blok NIE zmienia: limity są pod siatką na każdej szerokości
   (polecenie zamawiającego 2026-09-02). Do tego dnia stało tu `column-reverse`, żeby panel
   nie chował się pod listą ~30 dni — zamawiający zdecydował inaczej, po obejrzeniu obu
   wariantów. Nie przywracaj tego bez pytania: to nie jest przeoczenie. */
@media (max-width: 900px) {
  .uklad {
    flex-direction: column;
  }

  .nawigacja {
    flex: 1 1 auto;
    border-right: none;
    border-bottom: 1px solid var(--ramka-karty);
    padding: 8px 0;
  }

  .nawigacja ul {
    display: flex;
    flex-wrap: wrap;
  }

  /* Nazwa dnia wraca do komórki: <thead> jest tu ukryty, a po dodaniu sobót i niedziel
     sama liczba nie mówi już, czy tego dnia wolno cokolwiek zaplanować. */
  .miesiac__dzien-nazwa {
    display: inline;
  }

  .miesiac,
  .miesiac tbody,
  .miesiac tr,
  .miesiac__dzien {
    display: block;
    width: auto;
    height: auto;
  }

  .miesiac thead {
    display: none;
  }

  /* PODPIS TABELI RAZEM Z TABELĄ — inaczej zostaje `display: table-caption` w kontenerze,
     który tabelą już nie jest. Skutek zmierzony na 390 px: podpis kalendarza miał 81,6 px
     szerokości przy tabeli 342 px i 390,5 px WYSOKOŚCI — łamał się na jedno słowo w wierszu
     i zajmował pół ekranu telefonu. Powód: caption bez tabeli tworzy anonimową tabelę
     o szerokości shrink-to-fit, a `thead` jest tu ukryty, a komórki mają szerokość zero,
     więc nie ma czym jej rozepchnąć — zostaje szerokość najdłuższego słowa.
     Reguła stoi przy KAŻDEJ tabeli przełączanej na blok (patrz też .kolejka poniżej), bo
     defekt należy do przełączenia, nie do konkretnego podpisu. Podpisy dla czytnika ekranu
     wyłączone selektorem: mają własne schowanie i szerokość 1 px. */
  .miesiac > caption:not(.tylko-dla-czytnika) {
    display: block;
  }

  .miesiac__dzien--poza {
    display: none;
  }

  .miesiac__dzien {
    min-height: 0;
    margin-bottom: 6px;
  }
}

/* ── kreator dodawania zajęć (makieta M4-P2 i M4-P4) ────────────────────────────── */

/* Wskaźnik kroków: TRZY kroki — aktywność, szczegóły, powtarzanie serii (P5, sesja 7). */
.kroki {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  list-style: none;
  margin: 0 0 18px;
  padding: 0;
}

.krok {
  border: 2px solid var(--ramka-pola);
  border-radius: var(--promien);
  padding: 6px 14px;
  font-size: 15px;
  font-weight: 600;
  color: var(--tekst-pomocniczy);
  background: var(--tlo-karty);
}

.krok--biezacy {
  background: var(--akcja);
  border-color: var(--akcja);
  color: #ffffff;
}

.przycisk--dodaj {
  min-height: 52px;
  align-self: center;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
}

.blokada {
  margin-bottom: 18px;
}

.blokada__wyjscie {
  margin-top: 8px;
}

.wybor-grupy {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 16px;
  margin-bottom: 22px;
  max-width: 780px;
}

.wybor-grupy .pole {
  flex: 1 1 320px;
}

/* Kafle jako grupa pól wyboru: ten sam wygląd co w makiecie, a obsługa klawiaturą
   i czytnikiem ekranu wynika z semantyki, nie z dopisanych ról. */
.kafle {
  display: grid;
  /* min(280px, 100%): na 320 px (1.4.10 reflow) kolumna zwęża się do kontenera zamiast
     wymuszać przewijanie poziome — 280 px + poziome wcięcia treści dawało 328 px. */
  grid-template-columns: repeat(auto-fill, minmax(min(280px, 100%), 1fr));
  gap: 12px;
  border: none;
  margin: 0 0 20px;
  padding: 0;
}

.kafle legend {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--tekst-etykiety);
  padding: 0 0 10px;
}

/* Kafel JEST przyciskiem zatwierdzającym formularz: jedno kliknięcie albo Enter przenosi
   do kroku 2. Reset styli przycisku, bo wygląd ma zostać z makiety, a semantyka z HTML —
   dzięki temu „kafel wyczerpany" to zwykłe disabled, obsługiwane przez przeglądarkę
   i czytnik ekranu bez dopisanych ról. */
.kafel {
  display: flex;
  flex-direction: column;
  align-items: flex-start;

  /* 10 px, nie 6: kafel niesie od 2026-09-01 cztery wiersze (nazwa, obszar z limitem,
     licznik pozostałych jednostek, liczba własnych grup), a przy 6 px zawijające się
     zdanie licznika stykało się z wierszem pod nim. */
  gap: 10px;
  min-height: 132px;
  padding: 14px;
  font: inherit;
  text-align: left;
  color: var(--tekst);
  background: var(--tlo-karty);
  border: 1px solid var(--ramka-karty);
  border-radius: var(--promien);
  cursor: pointer;
}

.kafel:hover:not(:disabled) {
  border-color: var(--akcja);
  background: var(--tlo-naglowka);
}

.kafel:focus-visible {
  outline: 3px solid var(--fokus);
  outline-offset: 2px;
}

.kafel:disabled,
.kafel--niedostepny {
  background: var(--nieaktywny-tlo);
  border-color: var(--nieaktywny-ramka);
  color: var(--nieaktywny-tekst);
  cursor: not-allowed;
}

/* Powód wyłączenia kafla w kolorze OSTRZEŻENIA, nie w szarości całego kafla (makieta P2:
   „zostaje 1 h — za mało na blok" ma #8a3f07 właśnie na kaflu wyłączonym; polecenie
   zamawiającego 2026-09-02). Kolor tylko wzmacnia treść — zdanie o zamkniętych drogach stoi
   w liczniku i czyta je czytnik ekranu przez `aria-describedby` (WCAG 1.4.1). Reguła wisi
   na `:disabled`, więc nie ma drugiej flagi „to ostrzeżenie", która mogłaby się rozjechać
   ze stanem kafla. Kontrast pary z `--nieaktywny-tlo` pilnuje strażnik tokenów. */
.kafel:disabled .kafel__licznik,
.kafel--niedostepny .kafel__licznik {
  color: var(--ostrzezenie-tekst);
}

/* Sekcja kafli w trakcie przeliczania po zmianie grupy — sygnał widoczny i dla czytnika
   ekranu (aria-busy), i wzrokowo, bez podmiany treści na „ładowanie". */
#kafle-aktywnosci[aria-busy="true"] .kafle {
  opacity: 0.6;
}

.kafel__nazwa {
  font-size: 19px;
  font-weight: 700;
}

.kafel__opis {
  font-size: 15px;
  color: var(--tekst-pomocniczy);
}

.kafel__licznik {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/* Trzecia linia kafla — zwykły element w kolumnie, NIE pozycjonowany absolutnie.
   Absolutne `bottom: 12px` było dobre, dopóki wyżej stało jedno krótkie zdanie: od chwili,
   gdy licznik zaczął nieść zdanie zawijające się do dwóch wierszy („Twoje grupy tu pełne —
   w nowej grupie zostaje 16 części"), treść w kolumnie wchodziła pod element wyjęty
   z układu i napisy nakładały się na siebie (znalezione oglądaniem 2026-09-01).
   `margin-top: auto` trzyma tę linię przy dolnej krawędzi, gdy kafel jest wyższy
   od swojej treści — czyli daje to, po co było `bottom`, nie wychodząc z układu. */
.kafel__powod {
  margin-top: auto;
  padding-top: 2px;
  font-size: 14px;
  color: var(--nieaktywny-tekst);
}

.kreator {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
}

/* Bez górnej granicy szerokości: formularz wypełnia miejsce obok podglądu tygodnia
   (decyzja Władysława, 2026-08-27 — makieta miała kartę 760 px). `none` jawnie,
   bo inaczej wraca 560 px z ogólnej .karta. */
.kreator__formularz {
  /* Podstawa 480 px, nie 700: przy 700 px formularz i podgląd nie mieściły się obok siebie
     w kolumnie treści (≈1000 px przy nawigacji bocznej) i zawijały się jedno pod drugie —
     czyli układ dwukolumnowy z makiet P4 i P5 nie działał na ekranie, dla którego został
     narysowany. Formularz nadal rośnie do całej wolnej szerokości (`flex-grow: 1`), więc
     na szerokim monitorze wygląda tak jak przedtem. Znalezione oglądaniem 2026-09-01. */
  flex: 1 1 480px;
  max-width: none;
}

/* ── podgląd tygodnia obok formularza (makieta M4-P4: kolumna 420 px) ── */
.kreator__tydzien {
  flex: 1 1 320px;
  max-width: 420px;
  align-self: flex-start;
}

.kreator__tydzien h2 {
  font-size: 20px;
}

.tydzien__dzien h3 {
  margin: 0 0 4px;
  font-size: 16px;
  color: var(--granat-marki);
}

.tydzien__blok {
  margin: 0 0 6px;
  padding: 6px 8px;
  border-left: 4px solid var(--neutralny-ramka);
  background: var(--neutralny-tlo);
  font-size: 15px;
}

.tydzien__godziny {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  margin-right: 6px;
}

/* dopisek „(wymagane)" w etykiecie — słowo zamiast gwiazdki (§4, §6 p. 11) */
.pole__wymagane {
  font-weight: 400;
  color: var(--tekst-pomocniczy);
}

/* Znacznik „zmienione" przy etykiecie pola ruszonego korektą (M7-E6). Tło i ramka, nie sam
   kolor tekstu: stan podany SŁOWEM jest tu nośnikiem, a plakietka odróżnia go od etykiety. */
.pole__znacznik {
  font-size: 13px;
  font-weight: 400;
  padding: 1px 6px;
  border: 1px solid var(--ostrzezenie-ramka);
  border-radius: var(--promien);
  background: var(--ostrzezenie-tlo);
  color: var(--ostrzezenie-tekst);
  white-space: nowrap;
}

/* Nagłówek KARTY z plakietką po prawej (M7-E6: „Popraw wpis" ⟷ „Miesiąc otwarty").
   Osobno od `.naglowek-strony`, bo tamten niesie H1 strony i ma własny rozmiar czcionki. */
.naglowek-karty {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
  justify-content: space-between;
}

.naglowek-karty h2 {
  margin: 0;
}

/* Historia wpisu (M7-E6). Lista uporządkowana, bo kolejność wersji jest treścią: numer
   wersji rośnie bez luk i to on wiąże wiersz z rekordem audytu. */
.historia-wpisu {
  list-style: none;
  margin: 0 0 16px;
  padding: 0;
}

.historia-wpisu__wiersz {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 12px;
  padding: 10px 0;
  border-top: 1px solid var(--linia-tabeli);
}

.historia-wpisu__kiedy {
  flex: 0 0 auto;
  color: var(--tekst-etykiety);
  font-variant-numeric: tabular-nums;
}

.historia-wpisu__co {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1 1 12rem;
}

/* Liczby różnicy w kroju o stałej szerokości znaku — „6 → 7" czyta się jako para wartości,
   a nie jako zdanie. */
.historia-wpisu__zmiany {
  font-family: var(--czcionka-mono);
  font-size: 14px;
  color: var(--tekst);
}

.historia-wpisu__powod {
  color: var(--tekst-pomocniczy);
}

/* przycisk wyjścia z blokady — odsłaniany skryptem obok ukrywanego zdania */
.blokada__ustaw {
  margin-top: 8px;
}

.kontekst-kreatora {
  margin-bottom: 20px;
}

.kontekst-kreatora p {
  margin-top: 6px;
}

/* Rząd PÓL — wyłącznie pól. Rząd przycisków albo pól wyboru stojących obok siebie ma własną
   klasę `.rzad` niżej, bo miara kolumny (200 px) i wspólne tory są tu dla pola, nie dla
   przycisku.

   Wiersz etykiet i wiersz kontrolek są WSPÓLNYMI torami siatki (`subgrid`), a nie wysokością
   każdego pudełka z osobna. Powód jest mechaniczny: flex umie wyrównać rząd do góry ALBO
   do dołu i ŻADNE z tych wyrównań nie ustawia kontrolek w jednej linii.
   • `flex-end` (tak było do 2026-09-22) wyrównuje DOŁY pudełek — więc pole z podpisem pod
     kontrolką jedzie w górę o wysokość podpisu;
   • `flex-start` wyrównuje GÓRY — więc pole z etykietą łamaną na dwa wiersze jedzie w dół
     o wysokość wiersza.
   Oba przypadki stoją obok siebie w kroku 2 kreatora: pomiar z 2026-09-22 dał tam 71 px
   rozjazdu przy 1024 px („Godzina zakończenia" ma podpis, „Godzina rozpoczęcia (wymagane)"
   łamie etykietę). Trzy tory znaczą: etykiety mają wspólną wysokość i kontrolki startują
   w jednym miejscu niezależnie od tego, co pod nimi stoi.

   Tory trzy, nie cztery: WSZYSTKO pod kontrolką jest jednym elementem (`.pole__stopka`
   z `_PoleFormularza`). Element czwarty nie dostałby własnego toru, tylko wylądował
   w trzecim — jeden na drugim. */
.pola-obok {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  grid-template-rows: auto auto auto;
  column-gap: 16px;

  /* Odstęp między WIERSZAMI pól po zawinięciu; odstęp wewnątrz pola (6 px) nadaje sobie
     samo pole niżej — siatka podrzędna może mieć własne odstępy. */
  row-gap: 16px;
  align-items: start;
}

.pola-obok > .pole {
  display: grid;
  grid-template-rows: subgrid;
  grid-row: span 3;
  row-gap: 6px;

  /* Kolumna pola wyliczana z JEGO miejsca, nie z treści. Siatka bez tej reguły dorabia
     kolumnę o mierze `auto`, czyli szerokiej na najszerszą treść — a treścią bywa lista
     rozwijana z kodem grupy albo długi podpis. Zmierzone 2026-09-22 przy 1024 px: pole
     „Grupa" miało pudełko 334 px i kontrolkę 485 px, czyli 151 px NA SĄSIEDNIEJ KOLUMNIE,
     z podpisami wydrukowanymi jeden na drugim. `minmax(0, 1fr)` znaczy „kolumna wolno
     zwęzić do zera", więc zawija się tekst zamiast wychodzić poza pole. */
  grid-template-columns: minmax(0, 1fr);
}

/* Rząd pól, których WARTOŚĆ jest krótka — liczba, godzina, plakietka (metryka karty
   scenariusza, makieta S3a). Zmienia sam tor, nie mechanizm: wspólne tory i siatka podrzędna
   zostają te same, więc to nie jest obejście wyrównania.

   130 px, nie 200 i nie 140 — obie liczby zmierzone na tym ekranie: przy 200 px cztery
   wartości łamią się na dwa wiersze już przy 1024 px (kolumna treści ma tam 691 px), a przy
   140 px rząd na telefonie (277 px w karcie) schodzi do JEDNEJ kolumny, czyli cztery pudełka
   jedno pod drugim zamiast dwóch par. 130 px daje cztery kolumny przy 1024 px i dwie przy
   390 px — tyle, ile było przed przejściem na rząd pól. */
.pola-obok--metryka {
  grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
}

/* Rząd elementów obok siebie, które POLAMI NIE SĄ: przyciski wyjścia z kroku, pola wyboru dni
   tygodnia. Do 2026-09-22 nosiły `.pola-obok` i dostawały wtedy siatkę o torze 200 px — pięć
   pól wyboru zajęłoby wtedy trzy kolumny zamiast jednego rzędu. */
.rzad {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  align-items: center;
}

/* Kolumna pól: ten sam rytm pionowy (18 px), co między elementami karty. Potrzebna wszędzie
   tam, gdzie pola stoją jedno pod drugim NIE będąc dziećmi `.karta` — sam `<form>` jest
   blokiem, a `.pole` nie ma marginesów, więc bez tej klasy podpis jednego pola dotyka
   etykiety następnego (zmierzone 2026-09-02: 0 px w kroku 2 kreatora). Klasa, nie reguła
   na `form`: `display: flex` na każdym formularzu rozciągnąłby pojedyncze przyciski
   w tabelach na całą szerokość komórki. */
.pola-pion {
  display: flex;
  flex-direction: column;
  gap: 18px;
}

/* Ramka, tło i wysokość idą z reguły wspólnej dla wszystkich kontrolek pola (wyżej) —
   tutaj zostaje WYŁĄCZNIE to, co jest własne dla pól liczbowych i czasu: cyfry o równej
   szerokości, żeby kolumna godzin nie „skakała" przy zmianie wartości. */
.pole input[type="date"],
.pole input[type="time"],
.pole input[type="number"] {
  font-variant-numeric: tabular-nums;
}

.pole input[readonly] {
  background: var(--tlo-strony);
  color: var(--tekst-pomocniczy);
}

@media (max-width: 480px) {
  .kafel {
    min-height: 72px;
  }

  /* Nadpisania `position: static` dla `.kafel__powod` już tu NIE MA: linia powodu nie jest
     od 2026-09-01 pozycjonowana absolutnie w żadnej szerokości, więc cofanie pozycjonowania
     na telefonie opisywałoby regułę, której nie ma. */
}

/* wiersz panelu limitów = jeden plan (grupa + aktywność), z akcją złożenia */
.limit__grupa {
  display: block;
  font-size: 14px;
  color: var(--tekst-pomocniczy);
  margin-bottom: 6px;
}

.limit__zloz {
  margin-top: 10px;
  width: 100%;
}

.limit__zloz:disabled {
  background: var(--nieaktywny-tlo);
  border-color: var(--nieaktywny-ramka);
  color: var(--nieaktywny-tekst);
  cursor: not-allowed;
}

/* ── kolejka akceptacji planów (makiety M5-A1 i M5-A2) ──────────────────────────── */

/* Tekst wyłącznie dla czytnika ekranu: nagłówek kolumny z akcją i dopowiedzenie przy
   odnośniku „Otwórz plan". Bez display:none i bez visibility:hidden — te znikają także
   dla czytnika (2.4.4: cel odnośnika ma być zrozumiały poza kontekstem wiersza). */
.tylko-dla-czytnika {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* POJEMNIK PRZEWIJANY dla tabeli danych. Tabela w trybie tabelarycznym ma szerokość
   MINIMALNĄ wynikającą z liczby kolumn i najdłuższych słów w nich — i ta liczba nie ma nic
   wspólnego z progiem, przy którym arkusz przełącza tabelę na karty. Zmierzone przy 1024 px:
   spis aktywności potrzebuje 1160,6 px (10 kolumn) i dostaje 691, personel 887,4 wobec 741,
   kartoteka grup 837 wobec 691. Skutków było TRZY, wszystkie z jednej przyczyny: przewijanie
   całej strony (5 ekranów), wejście tabeli w padding karty (3 ekrany) i NACHODZENIE TABELI
   NA SĄSIEDNIĄ KOLUMNĘ UKŁADU o 136 px („Moje zajęcia" — treść na treści, i to jest
   najgorszy z trzech, bo żadna miara okna go nie widzi).

   DLACZEGO PRZEWIJANIE, A NIE WYŻSZY PRÓG PRZEŁĄCZENIA. Próg jest jeden dla wszystkich
   tabel, a szerokości minimalne idą od 716,6 do 1160,6 px — więc próg musiałby obsłużyć
   najgorszą tabelę (~1500 px okna) i zamieniłby w karty także te, które mieszczą się
   z zapasem. To jest dokładnie defekt naprawiony tego samego dnia rano: element za wąski
   wobec miejsca, które daje mu układ (R-80). `table-layout: fixed` odpada z tego samego
   powodu — równe kolumny dają 69 px na „MAPOWANIE BUDŻETOWE" i wiersz na kilka linii.

   Pasek pojawia się WYŁĄCZNIE wtedy, gdy tabela nie mieści się w swoim miejscu, więc reguła
   nie potrzebuje żadnej liczby i nie zmienia niczego tam, gdzie tabela się mieszczy.
   Fokusowalność pojemnika (2.1.1 — przewijana treść musi być osiągalna klawiaturą) nadaje
   `tabele-przewijane.js`, i tylko przy faktycznym przewijaniu: `tabindex` na pojemniku,
   który się nie przewija, byłby pustym przystankiem w kolejności tabulacji. */
.tabela-przewijana {
  overflow-x: auto;
  /* Przewijanie tabeli nie porywa strony, gdy palec dojedzie do końca zakresu. */
  overscroll-behavior-x: contain;
  /* CONTAIN JEST TU KONIECZNE, nie ozdobne — i to jest pomiar, nie przekonanie.
     Samo `overflow-x: auto` przycina tabelę WIZUALNIE (sprawdzone `elementFromPoint`:
     za prawą krawędzią pojemnika jest już tło karty, nie komórka), ale nadmiar nadal
     propaguje do obszaru przewijania DOKUMENTU: `documentElement.scrollWidth` zostawał
     1391 px przy oknie 1024 i strona dawała się przewinąć o 382 px — w PUSTE MIEJSCE.
     Objaw jest wtedy gorszy od pierwotnego, bo pasek przewijania obiecuje treść, której
     tam nie ma. Zmierzone warianty: `overflow-x: hidden` — 1391 (bez zmiany),
     `max-width: 100%` — 1391, usunięcie podpisu tabeli — 1391, `contain: paint` — 1009,
     czyli dokładnie szerokość obszaru. */
  contain: paint;
}

/* Obramowanie fokusu na pojemniku, nie na tabeli — to pojemnik dostaje fokus. */
.tabela-przewijana:focus-visible {
  outline: 3px solid var(--fokus);
  outline-offset: 2px;
}

.kolejka,
.zajecia-planu {
  width: 100%;
  border-collapse: collapse;
  background: var(--tlo-karty);
  border: 1px solid var(--ramka-karty);
}

.kolejka__podpis {
  text-align: left;
  font-size: 15px;
  color: var(--tekst-pomocniczy);
  padding-bottom: 8px;
}

.kolejka th,
.zajecia-planu th {
  font-size: 14px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  background: var(--tlo-naglowka);
  color: var(--tekst-pomocniczy);
  text-align: left;
  padding: 10px 16px;
  border-bottom: 1px solid var(--ramka-karty);
}

.kolejka td,
.zajecia-planu td {
  padding: 12px 16px;
  border-bottom: 1px solid var(--linia-tabeli);
  vertical-align: top;
}

.kolejka tbody tr:last-child td,
.zajecia-planu tbody tr:last-child td {
  border-bottom: none;
}

.kolejka__liczba {
  font-variant-numeric: tabular-nums;
}

.kolejka__dopisek {
  display: block;
  font-size: 14px;
  color: var(--tekst-pomocniczy);
}

/* Kolumna akcji stoi przy PRAWEJ krawędzi tabeli: akcje mają być w każdym wierszu w tym
   samym miejscu i nie zlewać się z treścią wiersza. Nagłówek „Akcje" jest widoczny, nie sam
   dla czytnika — kolumna bez podpisu wygląda jak dane bez nazwy. */
.kolejka th.kolejka__akcja,
.kolejka td.kolejka__akcja {
  text-align: right;
}

/* Odstęp MIĘDZY akcjami, nie margines na każdej — skrajna nie odsuwa się wtedy od krawędzi.
   Bez tego „Edytuj" i „Wyłącz" czytają się jak jeden odnośnik. */
.kolejka__akcja > * + * {
  margin-left: 20px;
}

/* Pojedyncza akcja nie łamie się na dwie linie — złamana („Otwórz / plan") wygląda jak dwa
   cele kliknięcia, a jest jednym. Zakaz dotyczy akcji, nie całej komórki: para akcji ma się
   móc przenieść do następnego wiersza, gdy kolumna jest wąska. */
.kolejka__akcja > a,
.kolejka__akcja > form {
  display: inline-block;
  white-space: nowrap;
}

/* Akcja wiersza, która MUSI być przyciskiem, bo zmienia dane (POST) — wygląda jak odnośnik
   obok niej. Trzy różne wyglądy akcji w jednej komórce („Edytuj", „Wyłącz", „Włącz")
   czytały się jak trzy różne rodzaje czynności, a są jednym (znalezione oglądaniem
   2026-09-01). `LinkText` zamiast wpisanej barwy: odnośniki tabeli nie mają w projekcie
   własnego tokenu i biorą kolor przeglądarki, więc wpisana wartość rozjechałaby się z nimi
   przy pierwszej zmianie motywu. */
.akcja-wiersza {
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  color: LinkText;
  text-decoration: underline;
  cursor: pointer;
  white-space: nowrap;
}

.akcja-wiersza:focus-visible {
  outline: 3px solid var(--fokus);
  outline-offset: 2px;
}

/* plakietka stanu — kolor wzmacnia słowo, nigdy go nie zastępuje (1.4.1) */
.plakietka {
  display: inline-block;
  font-size: 14px;
  font-weight: 700;
  padding: 4px 9px;
  border: 2px solid;
  border-radius: var(--promien);
  white-space: nowrap;
}

.plakietka--neutralna {
  border-color: var(--neutralny-ramka);
  background: var(--neutralny-tlo);
  color: var(--neutralny-tekst);
}

.plakietka--sukces {
  border-color: var(--sukces-ramka);
  background: var(--sukces-tlo);
  color: var(--sukces-tekst);
}

.plakietka--ostrzezenie {
  border-color: var(--ostrzezenie-ramka);
  background: var(--ostrzezenie-tlo);
  color: var(--ostrzezenie-tekst);
}

.plakietka--nieaktywna {
  border-color: var(--nieaktywny-ramka);
  background: var(--nieaktywny-tlo);
  color: var(--nieaktywny-tekst);
}

/* karta planu: nagłówek z danymi, nad tabelą terminów. Szerokość ograniczona (makieta
   M5-A2 ma kartę 760 px) — para etykieta/wartość rozjechana na całą szerokość ekranu
   przestaje być parą i trzeba ją wodzić wzrokiem.
   `karta-tresci` to ta sama forma pod nazwą niezwiązaną z jednym ekranem (karta placówki,
   makieta M2 A5/C2). Jedna reguła, dwie nazwy — kopia rozjechałaby się przy pierwszej
   zmianie odstępów; nazwa `karta-planu` zostaje, dopóki nie wróci ktoś do ekranu M5. */
.karta-planu,
.karta-tresci {
  background: var(--tlo-karty);
  border: 1px solid var(--ramka-karty);
  border-radius: var(--promien);
  padding: 20px 24px;
  margin-bottom: 24px;
  /* Bez `max-width: 820px` — zdjęte 2026-09-17 razem z miarą z `.karta`. Pomiar pokazywał
     820 px w torze 1637 px (50%) na pięciu ekranach: karcie zajęć planu, wzorcu graficznym,
     korekcie po zamknięciu, imporcie placówek i karcie gminy. Modyfikator
     `karta-tresci--szeroka`, który to ograniczenie zdejmował, zniknął jako zbędny. */
}

/* Dwie karty obok siebie (makieta M2 C2: dane placówki + kartoteka sal), jedna pod drugą
   poniżej ~880 px. Przełączenie robi zawijanie flexa, nie drugi szablon — ta sama treść
   w tej samej kolejności czytania na telefonie i na monitorze. */
.karty-obok {
  display: flex;
  flex-wrap: wrap;
  gap: 24px;
  align-items: flex-start;
}

/* Para kart wypełnia CAŁY obszar treści: ograniczenie 820 px dotyczy karty stojącej samotnie
   (długość wiersza tekstu), a nie kolumny w rzędzie — inaczej na szerokim ekranie obie karty
   przestają rosnąć i zostaje pusty pas z prawej. */
.karty-obok > .karta-tresci {
  flex: 1 1 420px;
  min-width: 0;
  max-width: none;
}

.dane {
  margin: 0;
}

.dane__wiersz {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  justify-content: space-between;
  padding: 10px 0;
  border-bottom: 1px solid var(--linia-tabeli);
}

.dane__wiersz:last-child {
  border-bottom: none;
}

.dane dt {
  color: var(--tekst-pomocniczy);
}

.dane dd {
  margin: 0;
  font-weight: 600;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.naglowek-sekcji {
  font-size: 20px;
  color: var(--granat-marki);
  margin: 0 0 12px;
}

/* panel „Sprawdzenia systemu" (makieta M5-A2) — stan sukcesu, ale kolor tylko wzmacnia:
   treść niesie zdanie przy każdym punkcie, nie zielona ramka (WCAG 1.4.1) */
.sprawdzenia {
  margin-bottom: 24px;
  padding: 18px 20px;
  border: 2px solid var(--sukces-ramka);
  border-radius: var(--promien);
  background: var(--sukces-tlo);
}

.sprawdzenia__naglowek {
  margin: 0 0 10px;
  font-size: 14px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--sukces-tekst);
}

.sprawdzenia__lista {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
  color: var(--sukces-tekst);
  font-weight: 600;
}

.sprawdzenia__znak {
  margin-right: 8px;
}

.sprawdzenia__uwaga {
  margin: 12px 0 0;
  font-size: 15px;
  line-height: 1.55;
  color: var(--tekst-pomocniczy);
}

/* Okno formularza (karta placówki: dodanie i zmiana nazwy sali). Bez skryptu przeglądarka
   renderuje `dialog[open]` jako zwykły blok w treści strony i formularz działa tak samo —
   skrypt podmienia to na okno modalne z pułapką fokusu i obsługą Escape (R-18). */
.okno {
  width: min(560px, calc(100% - 32px));
  margin: 0 0 24px;
  padding: 24px;
  border: 1px solid var(--ramka-karty);
  border-radius: var(--promien);
  background: var(--tlo-karty);
  color: var(--tekst);
}

/* Okno modalne wyśrodkowane; przy `dialog[open]` bez skryptu marginesy zostają w treści. */
.okno[open]:modal {
  margin: auto;
  /* Zapas dla pasków przyklejonych (niżej) przy przewijaniu DO ELEMENTU. Przeglądarka mierzy
     „czy widoczny" krawędzią obszaru przewijania, a nie krawędzią paska — i dla pola
     CZĘŚCIOWO widocznego nie przewija wcale. Zmierzone 2026-09-02 na oknie odesłania,
     Shift+Tab z dołu okna na pole powodu: bez tej reguły okno zostaje przewinięte (80 px),
     etykieta pola stoi na 19 px pod paskiem sięgającym 87 px, a z 49 px wysokości pola widać
     11 px. Z regułą okno wraca na 0, etykieta na 99 px, pole widoczne w całości.
     Wartości są ZAOKRĄGLONE W GÓRĘ wysokości pasków (zmierzone 66 px i 91 px) — nie da się
     ich wyliczyć w CSS, bo wysokość bierze się z treści. Za duża wartość przewija o kilka
     pikseli więcej niż trzeba; za mała wraca do defektu opisanego wyżej. */
  scroll-padding-block: 80px 100px;
}

/* Okno wyższe od ekranu: NAGŁÓWEK i RZĄD AKCJI zostają w widoku, przewija się środek
   (polecenie zamawiającego 2026-09-02). Powód jest mierzalny: przy oknie przeglądarki
   720 px treść okna odesłania ma 739 px, więc przycisk zatwierdzający stał ~60 px pod
   krawędzią — a to jest przycisk decyzji nieodwracalnej, o którym PLZ ma nie zgadywać,
   czy istnieje. Nagłówek przyklejony z tego samego powodu: niesie PRZEDMIOT decyzji
   (nazwę sali, kod grupy, nazwisko), którego nie ma już na przycisku.

   Wyłącznie w stanie `:modal`, czyli po podmianie przez `okna.js`. Bez skryptu `dialog[open]`
   jest zwykłym blokiem w treści strony, przewija się CAŁA STRONA, a nie okno — przyklejenie
   liczyłoby się wtedy do okna przeglądarki i rząd przycisków wędrowałby po ekranie przy
   przewijaniu kartoteki.

   Ujemne marginesy plus własna wyściółka: `.okno` ma wyściółkę 24 px, a element przyklejony
   do krawędzi obszaru przewijania zostawiłby ją nad sobą jako pasek, przez który przejeżdża
   treść. Marginesy rozciągają tło na całą szerokość okna, wyściółka odtwarza odstęp. */
/* Bez `>`: w oknach formularzy (sala, liczba dzieci) nagłówek stoi WEWNĄTRZ formularza,
   a w oknach decyzji jest dzieckiem okna. Selektor potomka obejmuje oba układy — sam `> h2`
   po cichu pomijał dwa okna z czterech (znalezione pomiarem 2026-09-02: pasek nagłówka miał
   tam 30 px zamiast wysokości z wyściółką). Formularz nie ma własnej wyściółki, więc ujemne
   marginesy liczą się do krawędzi okna w obu układach. */
.okno[open]:modal h2 {
  position: sticky;
  top: -24px;
  z-index: 1;
  margin: -24px -24px 12px;
  padding: 24px 24px 12px;
  background: var(--tlo-karty);
}

.okno[open]:modal .decyzja__akcje {
  position: sticky;
  bottom: -24px;
  z-index: 1;
  margin: 0 -24px -24px;
  padding: 16px 24px 24px;
  background: var(--tlo-karty);
  /* Linia oddziela akcje od przewijanej treści — bez niej przyklejony rząd przycisków
     wygląda jak część zdania, które właśnie pod nim przejechało. */
  border-top: 1px solid var(--linia-tabeli);
}

.okno::backdrop {
  /* Przyciemnienie tła — jedyna wartość koloru bez tokena w tym pliku poza bielą na granacie:
     `docs/19` nie definiuje tokena przesłony, a odcień nie niesie żadnej informacji. */
  background: rgb(35 33 29 / 55%);
}

/* nagłówek sekcji z akcją po prawej (karta placówki: „Dane placówki" + plakietka,
   „Sale w placówce" + przycisk) */
.naglowek-sekcji-z-akcja {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 8px;
}

/* Nagłówek i podpis pod nim to jedna myśl — odstęp z marginesu nagłówka PLUS domyślnego
   marginesu akapitu rozsuwał je na 28 px, czyli bardziej niż sekcje między sobą. */
.naglowek-sekcji-z-akcja .naglowek-sekcji {
  margin-bottom: 0;
}

.naglowek-sekcji-z-akcja + .pole__podpis {
  margin-top: 0;
}

/* panel „Czy da się planować zajęcia" (makieta karty placówki). Ramka wyróżnia panel,
   ale znaczenia nie niesie kolor: każdy punkt ma zdanie, a stan warunku jest podany
   słowem dla czytnika ekranu (WCAG 1.4.1). */
.gotowosc {
  border-width: 2px;
  border-color: var(--granat-marki);
}

.gotowosc__lista {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.gotowosc__punkt {
  display: grid;
  grid-template-columns: 1.25em 1fr;
  gap: 10px;
  line-height: 1.5;
}

.gotowosc__znacznik {
  font-weight: 700;
  text-align: center;
}

.gotowosc__punkt--spelniony .gotowosc__znacznik {
  color: var(--sukces-tekst);
}

.gotowosc__punkt--niespelniony {
  font-weight: 600;
}

.gotowosc__punkt--niespelniony .gotowosc__znacznik {
  color: var(--blad-tekst);
}

/* Liczba, nie warunek — znacznik jest wyłącznie kropką porządkową, więc stonowany. */
.gotowosc__punkt--liczba .gotowosc__znacznik {
  color: var(--tekst-pomocniczy);
}

.gotowosc .pole__podpis {
  margin-top: 14px;
}

/* Nazwa grupy pochodzi z kartoteki i bywa jednym nierozdzielnym ciągiem (kod przydziału
   z makiety M4 to `0413-03-012-0091-01-06`, a format jest otwarty — Q58). Bez łamania
   taki ciąg rozpycha stronę i łamie 1.4.10: przewijanie poziome poniżej 320 px.
   Sprawdzone na 375 px — nagłówek karty planu wychodził na 494 px. */
.naglowek-strony h1,
.okruszki span {
  overflow-wrap: anywhere;
}

/* 1.4.10 reflow — na wąskim ekranie wiersz tabeli staje się kartą; jeden szablon,
   przełączenie CSS-em (19-ui-tokeny). Etykieta kolumny wraca przed wartością z atrybutu
   data-etykieta, bo bez nagłówka sama wartość („16 terminów") traci znaczenie. */
@media (max-width: 900px) {
  .kolejka,
  .kolejka tbody,
  .kolejka tr,
  .kolejka td,
  .zajecia-planu,
  .zajecia-planu tbody,
  .zajecia-planu tr,
  .zajecia-planu td {
    display: block;
    width: auto;
  }

  .kolejka thead,
  .zajecia-planu thead {
    display: none;
  }

  /* Ten sam defekt co przy kalendarzu — patrz komentarz przy `.miesiac > caption`.
     Widoczne podpisy tych tabel to „Personel w kolejności alfabetycznej" (M1)
     i podpis kolejki akceptacji; zmierzone na 390 px razem z kalendarzem. */
  .kolejka > caption:not(.tylko-dla-czytnika),
  .zajecia-planu > caption:not(.tylko-dla-czytnika) {
    display: block;
  }

  .kolejka tr,
  .zajecia-planu tr {
    border-bottom: 1px solid var(--ramka-karty);
    padding: 8px 0;
  }

  .kolejka td,
  .zajecia-planu td {
    border-bottom: none;
    padding: 6px 16px;
  }

  /* W karcie wiersza nie ma kolumn, więc nie ma prawej krawędzi, do której warto równać —
     akcje wracają pod etykietę „Akcje", tak jak każda inna wartość. */
  .kolejka td.kolejka__akcja {
    text-align: left;
  }

  /* ETYKIETA W TEJ SAMEJ LINII CO WARTOŚĆ, nie nad nią — i to jest jedyna rzecz, która
     w trybie kart ustępuje. Jedna pozycja kolejki miała na telefonie 504 px wysokości,
     czyli półtorej pozycji na ekran przy czterdziestu w kolejce (zmierzone 2026-09-14,
     390 × 844). Siedem komórek × wiersz etykiety to około 120 px samych nagłówków pól,
     przy wartościach w rodzaju „12.10.2026" i „2 godz." — czyli krótszych od własnej
     etykiety.
     `display: inline` zamiast `block` NIE UKRYWA NICZEGO: żadna etykieta ani wartość nie
     znika, zmienia się wyłącznie łamanie. Wartość dłuższa od reszty linii zawija się pod
     etykietę tak jak dotąd, a wartość będąca blokiem (lista terminów, formularz akcji)
     sama zaczyna nową linię — bez ani jednej reguły na wyjątek. Dlatego wybrano to zamiast
     skracania treści: skracanie wymagałoby decyzji, CO ma zniknąć, a tej decyzji nie ma
     po co podejmować, żeby odzyskać te same piksele. */
  .kolejka td::before,
  .zajecia-planu td::before {
    content: attr(data-etykieta);
    display: inline;
    margin-right: 8px;
    font-size: 14px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--tekst-etykiety);
  }

  .dane__wiersz {
    flex-direction: column;
    gap: 2px;
  }

  .dane dd {
    text-align: left;
  }
}

/* ── decyzja PLZ o planie (makiety M5-A3 i M5-A4) ───────────────────────────────── */

/* Sekcja decyzji trzyma tę samą szerokość co karta planu i panel sprawdzeń — trzy bloki
   o różnych szerokościach czytałyby się jak trzy niepowiązane ekrany. Od 2026-09-17 tą
   wspólną szerokością jest PEŁNA szerokość obszaru treści, więc reguła nie ma już czego
   ustawiać; zostaje sam odstęp niżej. */
.decyzja {
  margin-top: 24px;
}

/* Przyciski obok siebie, ale nie sklejone: decyzje są nieodwracalne, a odstęp jest tu
   zabezpieczeniem przed kliknięciem nie w ten przycisk (makieta A9 rozsuwa je na telefonie
   z tego samego powodu). Przy wąskim ekranie schodzą pod siebie. */
.decyzja__akcje {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 16px;
  margin-bottom: 10px;
}

.zwrot .decyzja__akcje {
  margin-top: 20px;
}

/* Jak wyżej: wspólna reguła daje ramkę i tło, tutaj zostaje własne zachowanie obszaru
   tekstowego — wysokość na kilka wierszy i zmiana rozmiaru tylko w pionie (w poziomie
   rozciągałaby układ karty). */
.pole textarea {
  width: 100%;
  min-height: 120px;
  resize: vertical;
}

.pole textarea[aria-invalid="true"] {
  border-color: var(--blad-ramka);
}

/* Panel „Co się stanie" — stan NEUTRALNY, nie sukces: to zapowiedź skutków decyzji,
   której jeszcze nie podjęto. Zielona ramka czytałaby się jak potwierdzenie. */
.skutki {
  margin-top: 20px;
  padding: 18px 20px;
  border: 2px solid var(--neutralny-ramka);
  border-radius: var(--promien);
  background: var(--neutralny-tlo);
}

.skutki__naglowek {
  margin: 0 0 10px;
  font-size: 14px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--neutralny-tekst);
}

.skutki__lista {
  margin: 0;
  padding-left: 20px;
  display: grid;
  gap: 8px;
}

/* ── karta zajęć nauczyciela (makieta M4-P7) ────────────────────────────────────── */

/* Blok w siatce miesiąca jest odnośnikiem do karty zajęć. Wygląd zostaje ten sam co
   przed zmianą — zmienia się cel kliknięcia, nie układ, więc kolor i podkreślenie
   odnośnika nie mogą przebić stanu bloku (stan niesie podpis słowny, nie kolor). */
a.zajecia {
  color: inherit;
  text-decoration: none;
}

a.zajecia:hover .zajecia__aktywnosc {
  text-decoration: underline;
}

a.zajecia:focus-visible {
  outline: 3px solid var(--fokus);
  outline-offset: 2px;
}

/* Formularz poprawy i formularz rezygnacji na karcie zajęć. Klasa niesie SAM odstęp pod
   kartą — tło, ramkę, wyściółkę i rytm 18 px daje `.karta`, którą oba formularze noszą
   razem z tą klasą. Do 2026-09-17 niosła też szerokość 820 px; zdjęta razem z resztą
   stałych miar. */
.karta-zajec {
  margin-bottom: 24px;
}

/* ── moduł M5: kolejka zajęć, karta decyzji, odesłanie do poprawy ─────────────────── */

/* Akcja zbiorcza nad tabelą (M5-A1). Bez niej szesnaście zajęć jednej serii to szesnaście
   decyzji — przycisk stoi nad kolejką, bo tam trafia wzrok po zaznaczeniu wierszy. */
.kolejka__akcje-zbiorcze {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  margin: 12px 0;
}

.kolejka th.kolejka__zaznacz,
.kolejka td.kolejka__zaznacz {
  width: 44px;
  text-align: center;
}

/* Pole wyboru w rozmiarze celu dotykowego (44 px, WCAG 2.5.8) — wiersz kolejki bywa
   zaznaczany z telefonu, między zajęciami. */
.kolejka__zaznacz input[type="checkbox"] {
  width: 22px;
  height: 22px;
  margin: 11px;
}

/* Poprawka po odrzuceniu, „ta decyzja" w kontekście dnia i wpis zakwestionowany przez PLZ
   na liście „Moje zajęcia" — wyróżnienie wiersza. Ramka od lewej, nie samo tło: w trybie
   wysokiego kontrastu tło znika, ramka zostaje. Kolor NIGDY nie jest jedynym nośnikiem stanu
   — obok stoi plakietka ze słowem (1.4.1). */
.kolejka__wiersz--poprawka {
  border-left: 4px solid var(--ostrzezenie-ramka);
  background: var(--ostrzezenie-tlo);
}

/* Wiersz z FORMULARZEM otwartym pod pozycją, której dotyczy (zmiany harmonogramu: wybór
   zastępcy, uzasadnienie odwołania). Wyróżniony tłem i ramką od lewej, bo bez tego formularz
   wygląda jak kolejna pozycja listy, a nie jak rozwinięcie tej jednej. Komórka dostaje pełną
   wyściółkę — domyślna wyściółka komórki tabeli jest dobrana dla wiersza danych, nie dla pól
   formularza. */
.kolejka__wiersz--formularz > td {
  border-left: 4px solid var(--granat-marki);
  background: var(--tlo-pomocnicze);
  padding: 20px 24px;
}

/* Powód poprawy w wierszu: ten sam dopisek co pozostałe, ale w kolorze tekstu ostrzeżenia,
   bo niesie żądanie od człowieka, a nie podpis danych. Kontrast tego tokenu jest mierzony
   razem z resztą palety. */
.kolejka__dopisek--uwaga {
  color: var(--ostrzezenie-tekst);
}

.plakietka--uwaga {
  border-color: var(--ostrzezenie-ramka);
  background: var(--ostrzezenie-tlo);
  color: var(--ostrzezenie-tekst);
  font-size: 13px;
}

/* Dwie karty obok siebie na karcie decyzji (M5-A2: dane i panel sprawdzeń).
   Na wąskim ekranie jedna pod drugą — bez zapytania o media, samą siatką. */
.karty-para {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 16px;
  align-items: start;
  margin-bottom: 24px;
}

/* Lista sprawdzeń systemu: znacznik „✓" z pseudoelementu, żeby nie wchodził do treści
   kopiowanej ani do odczytu czytnika ekranu — tam liczy się zdanie, nie ozdobnik. */
.lista-sprawdzen {
  list-style: none;
  margin: 0;
  padding: 0;
}

.lista-sprawdzen li {
  position: relative;
  padding: 4px 0 4px 26px;
}

.lista-sprawdzen li::before {
  content: "✓";
  position: absolute;
  left: 0;
  color: var(--sukces-tekst);
  font-weight: 700;
}

/* Para etykieta/wartość na karcie decyzji — ta sama forma co `.dane`, ale w liście
   opisowej: karta ma dwie kolumny, więc wartość stoi pod etykietą, nie obok. */
.opis {
  margin: 0;
}

.opis dt {
  font-size: 14px;
  color: var(--tekst-pomocniczy);
  margin-top: 10px;
}

.opis dd {
  margin: 2px 0 0;
  font-weight: 600;
}

.opis dd .pole__podpis {
  display: block;
  font-weight: 400;
}

/* Przyciski decyzji pod kartą. Akcja niszcząca oddzielona odstępem od akceptującej
   (wymóg dostępności z makiety M5: „na telefonie akcja niszcząca oddzielona 8-pikselowym
   odstępem od akceptacji, obie 56 px"). */
.karta__akcje {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  margin-top: 16px;
}

.karta__akcje form {
  margin: 0;
}

/* Odesłanie do poprawy i rezygnacja — decyzje odwracalne wyłącznie przez drugą stronę
   obiegu, więc wygląd inny niż akcji podstawowej i inny niż pomocniczej. */
.przycisk--ostrzezenie {
  background: var(--ostrzezenie-tlo);
  border: 2px solid var(--ostrzezenie-ramka);
  color: var(--ostrzezenie-tekst);
  min-height: 44px;
}

/* Sekcja „N zajęcia wymagają poprawy" NAD kalendarzem (M5-A5: odrzucenie ma być widoczne
   od razu po zalogowaniu). */
.do-poprawy {
  margin-bottom: 20px;
}

.do-poprawy h2 {
  font-size: 20px;
  margin: 0 0 10px;
}

/* Panel „wymaga poprawy" jest jedynym panelem z AKCJĄ w środku, więc jako jedyny potrzebuje
   odstępu między treścią a przyciskiem — `.panel p { margin: 0 }` daje reszcie paneli
   zwartość, której nie chcemy tu tracić globalnie. Kolumna, nie zawijanie: komentarz PLZ
   bywa długi, a przycisk ma zostać pod nim, nie obok jego ostatniego wiersza. */
.do-poprawy .panel {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
}

/* Pasek filtrów listy (makieta M2 A4: „Szukaj … · Gmina · Status · Okres udziału · Filtruj").
   Karta pomocnicza NAD tabelą, nie kolumna z boku: przy siedmiu kolumnach tabela zabiera całą
   szerokość, a filtr wciśnięty obok niej zwężałby kolumnę adresu do dwóch słów. */
.filtry {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 16px;
  margin-bottom: 16px;
  border: 1px solid var(--ramka-karty);
  background: var(--tlo-pomocnicze);
}

.filtry__pola {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: flex-end;
}

/* Pole filtra rośnie do dostępnej szerokości, ale nie schodzi poniżej czytelnej: lista
   rozwijana z nazwą gminy i liczbą („Turośń Kościelna (3)") ucięta w połowie przestaje
   odpowiadać na pytanie, co jest wybrane. */
.filtry__pole {
  flex: 1 1 200px;
  min-width: 0;
  margin-bottom: 0;
}

.filtry__pole--szeroki {
  flex: 2 1 280px;
}

/* Rząd plakietek aktywnych filtrów — oddzielony linią od samych pól, bo mówi o innym stanie:
   pola pokazują, co można ustawić, plakietki, co JEST ustawione. */
.filtry__aktywne {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
  padding-top: 12px;
  border-top: 1px solid var(--linia-tabeli);
}

/* Krzyżyk zdejmujący filtr: pole dotyku 44 px (2.5.5), bo to samodzielna akcja, a nie
   ozdoba plakietki. */
.filtry__aktywne .plakietka a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 24px;
  min-height: 24px;
  margin-left: 6px;
  font-weight: 700;
  text-decoration: none;
}

.filtry__aktywne .plakietka a:hover,
.filtry__aktywne .plakietka a:focus-visible {
  text-decoration: underline;
}

/* Okres udziału w wierszu tabeli: para dat i jednozdaniowy skutek jedna pod drugą — wzorzec
   ustalony w tym module przez paczkę projektową. Daty monospace, bo są oznaczeniem terminu,
   a nie zdaniem; cyfry tabelaryczne, żeby kolumna się nie chwiała. */
.okres__daty {
  display: block;
  font-family: var(--czcionka-mono);
  font-variant-numeric: tabular-nums;
}

.okres__skutek {
  display: block;
  font-size: 14px;
  color: var(--tekst-pomocniczy);
}

/* Skutek inny niż „udział trwa" jest wyróżniony, ale NIE samym kolorem: wyróżnienie
   towarzyszy zdaniu, które mówi to samo słowami („planowanie zablokowane", „udział
   zakończony") — 1.4.1. */
.okres__skutek--uwaga {
  font-weight: 600;
  color: var(--ostrzezenie-tekst);
}

/* Stronicowanie (128 placówek, 25 na stronie). Odnośniki, nie przyciski: przejście na stronę
   jest nawigacją, więc ma dać się otworzyć w nowej karcie i wrócić przyciskiem „wstecz". */
.stronicowanie {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  margin-top: 16px;
}

/* Strona bieżąca NIE jest odnośnikiem — odnośnik prowadzący tam, gdzie już jesteś, jest
   dla czytnika ekranu obietnicą przejścia, którego nie będzie. */
.stronicowanie__biezaca {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  padding: 8px 14px;
  font-weight: 700;
  color: var(--tlo-karty);
  background: var(--akcja);
  border: 2px solid var(--akcja);
  border-radius: var(--promien);
}

/* Karta aktywności (M3-S2a): metryka po lewej, wąska kolumna pól edytowalnych po prawej.
   PROPORCJA jest treścią, nie układem — makieta uzasadnia ją zdaniem „formularz jest w 80%
   do odczytu; nie udajemy formularza tam, gdzie nie ma czego wpisać". Stąd 2fr do 1fr,
   a nie połowa na połowę: równe kolumny sugerowałyby, że po obu stronach jest tyle samo
   do zrobienia. Poniżej 900 px kolumny wracają jedna pod drugą — metryka pierwsza, bo
   to ona odpowiada na pytanie, po co się tu weszło. */
.slownik-karta {
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: var(--odstep-sekcji, 24px);
  align-items: start;
}

@media (max-width: 900px) {
  .slownik-karta {
    grid-template-columns: 1fr;
  }
}

/* Wartość pola, którego nie da się zmienić — wygląda jak dana, nie jak wyłączona kontrolka.
   Wyłączona kontrolka mówi „odblokuj mnie", a te wartości nie mają trybu odblokowania:
   pochodzą z wniosku i zmienia je aneks (M3-S2a). */
.pole__wartosc {
  margin: 0;
  font-size: 17px;
}

/* Nagłówek sekcji wewnątrz tabeli — oceny funkcjonalne jako osobna grupa wierszy (M3-S2).
   BEZ `text-transform: uppercase`: nagłówek niesie jednostkę godziny („po 2 h"), a wersaliki
   robiły z niej „2 H" — symbol jednostki nie jest skrótem i wielka litera znaczy co innego.
   Znalezione oglądaniem 2026-09-03. */
.kolejka__sekcja th {
  padding-top: 22px;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--tekst-pomocniczy);
  background: var(--tlo-strony);
}


/* Pasek formatowania nad polem opisowym scenariusza (M3-S3a). Trzy przyciski i tyle —
   zbiór dopuszczalnego formatowania pochodzi z ograniczenia generatora dokumentu, więc
   pasek nie ma miejsca, do którego dałoby się dołożyć czwarty bez zmiany białej listy
   w domenie. Wstawiany skryptem, dlatego bez skryptu nie zostaje po nim puste miejsce. */
.pasek-formatowania {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 8px;
}

/* Przyciski paska są niższe od zwykłych (44 px to minimum dla akcji głównych, a te
   stoją w rzędzie nad polem), ale nadal spełniają 2.5.8 dla celu wskazywania: 32 px
   wysokości przy odstępie 8 px daje obszar 40 px, czyli powyżej progu AA. */
.pasek-formatowania .przycisk {
  min-height: 32px;
  padding: 4px 10px;
  font-size: 15px;
}

/* ── Ewidencja: „Moje zajęcia" i dziennik (makieta M7) ─────────────────────────────── */

/* Dwie kolumny: listy i panele boczne. Ta sama proporcja co w planerze (siatka + limity) —
   panel „miesiąc w liczbach" i „papier a system" czyta się OBOK listy, nie pod nią. */
.ewidencja {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 340px;
  gap: 24px;
  align-items: start;
}

.ewidencja__listy > * + *,
.ewidencja__panele > * + * {
  margin-top: 24px;
}

.przypomnienie .przycisk {
  margin-top: 12px;
}

/* Kafle części scenariusza (M7-E2) to GRUPA WYBORU renderowana wspólnym partialem pola —
   te same etykiety, to samo wiązanie komunikatu (WCAG 3.3.1). Różnicą jest wyłącznie układ:
   szesnaście pozycji w jednej kolumnie dałoby ekran o wysokości dwóch przewinięć, a wybór
   części ma być jednym spojrzeniem. Grid na `fieldset`, `legend` przez całą szerokość. */
.kafle-czesci .wybory {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: 8px;
  align-items: start;
}

.kafle-czesci .wybory legend,
.kafle-czesci .opcje-pozostale {
  grid-column: 1 / -1;
}

.kafle-czesci .wybor {
  margin: 0;
  min-height: 72px;
  align-items: start;
}

/* Rozwinięcie z resztą opcji (M7-E2: „Pokaż wszystkie 16 części"). Bez skryptu — `details`
   obsługuje się klawiaturą i działa wszędzie. */
.opcje-pozostale > summary {
  display: flex;
  align-items: center;
  min-height: 44px;
  color: var(--akcja);
  cursor: pointer;
}

.opcje-pozostale > summary:focus-visible {
  outline: 3px solid var(--fokus);
  outline-offset: 2px;
}

.kafle-czesci .opcje-pozostale[open] {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: 8px;
}

.kafle-czesci .opcje-pozostale[open] > summary {
  grid-column: 1 / -1;
}

/* Cztery kafle liczb nad tabelami (makieta M7-E7). `auto-fit` z minimum 200 px, bo to samo
   pole ma się zwinąć do dwóch kolumn na tablecie i do jednej na telefonie BEZ drugiego
   szablonu i bez punktu przełamania na każdą szerokość. */
.liczby-ewidencji {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 16px;
  margin-bottom: 24px;
}

.liczba {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 16px;
  background: var(--tlo-karty);
  border: 1px solid var(--ramka-karty);
  border-radius: var(--promien);
}

.liczba__etykieta {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--tekst-etykiety);
}

.liczba__wartosc {
  font-size: 28px;
  line-height: 1.15;
  font-variant-numeric: tabular-nums;
}

.liczba__podpis {
  font-size: 14px;
  color: var(--tekst-pomocniczy);
}

/* Kafel W ROLI ODNOŚNIKA — pulpit nauczyciela (Q100). Kolor i podkreślenie zdejmowane
   CELOWO: kafel jest już wyodrębniony ramką i tłem, a niebieski wielkopunktowy licznik
   czytałby się jak stan błędu. Cel dotykowy ma pełną powierzchnię kafla, nie sam napis —
   dlatego odnośnikiem jest kafel, a nie słowo w jego środku (2.5.5). */
a.liczba {
  text-decoration: none;
  color: inherit;
}

a.liczba:hover {
  border-color: var(--granat-marki);
}

/* Oświadczenie ODCZYTANE z rekordu zamknięcia — cytat, nie akapit ekranu: to zdanie, które
   człowiek podpisał, i ma się różnić od treści, którą ekran układa sam. */
.oswiadczenie {
  margin: 12px 0 0;
  padding: 12px 16px;
  border-left: 3px solid var(--ramka-karty);
  background: var(--tlo-pomocnicze);
  color: var(--tekst-pomocniczy);
}

/* 1.4.10 reflow — panele schodzą pod listy, a nie obok nich.
   PRÓG 1200 px, NIE 900 jak w pozostałych siatkach, i to jest liczba z pomiaru. Kolumna
   panelu jest stała (340 px), a kolumna listy bierze RESZTĘ — przy oknie 1024 px reszta to
   319 px, bo nawigacja boczna zabiera 221 px, a marginesy treści 48. W 319 px stoi tabela
   kolejki o szerokości minimalnej 508,5 px (zmierzone 2026-09-14): tabela przewija się
   wtedy w środku karty, mając OBOK siebie 340 px panelu pomocniczego. To jest ta sama
   dysproporcja co w R-80 — element wąski nie dlatego, że miejsca nie ma, tylko dlatego,
   że układ oddał je czemuś mniej ważnemu. Panel „miesiąc w liczbach" jest dopowiedzeniem
   do listy, więc przy ciasnocie ustępuje pierwszy.
   1200 px jest najmniejszą szerokością, przy której lista dostaje 755 px, czyli mieści obie
   swoje tabele (508,5 i 430 px) z zapasem. Próg 900 px pozostałych siatek NIE ZMIENIA SIĘ:
   tam kolumny są ułamkowe i zwężają się razem z oknem, więc nie zabierają listom reszty. */
@media (max-width: 1200px) {
  .ewidencja {
    grid-template-columns: minmax(0, 1fr);
  }

  .ewidencja__panele {
    margin-top: 24px;
  }
}

/* Telefon (makieta M7-E9, 390 px). Pola liczbowe 52–56 px z tekstem 20–22 px — dziennik
   wypełnia się w sali, z papierową listą w ręku, więc trzy liczby muszą dać się wpisać
   kciukiem. Kafle na jedną kolumnę: dwie po 190 px łamią tytuł co drugie słowo. */
@media (max-width: 480px) {
  .kafle-czesci .wybory,
  .kafle-czesci .opcje-pozostale[open] {
    grid-template-columns: minmax(0, 1fr);
  }

  .pole input[type="number"],
  .pole input[readonly] {
    min-height: 56px;
    font-size: 21px;
  }

  /* „Zajęcia się nie odbyły" oddzielone od zapisu (M7-E9) — akcja o innym skutku nie może
     stać kciukiem przy przycisku zapisu. Cel dotykowy 52 px, jak przy akcji pomocniczej:
     przycisk o innym kolorze nie przestaje być przyciskiem na telefonie. */
  .przycisk--ostrzezenie {
    min-height: 52px;
  }

  /* Akcja wiersza listy jest na telefonie GŁÓWNYM celem dotykowym (M7-E9: „Wypełnij
     dziennik"), a jako zwykły odnośnik miała wysokość samego tekstu — 26 px. Reguła jest
     wspólna z kolejką PLZ i tam poprawia to samo (WCAG 2.5.5). */
  .akcja-wiersza {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }

  .karta__akcje .przycisk--ostrzezenie {
    margin-top: 8px;
  }
}

/* Nagłówek serii w kolejce PLZ (M5-A1). Od 2026-09-24 ciało tabeli jest NA PLAN (Q167), a seria
   stoi w nim wierszem nagłówka — plan, jego serie i zajęcia są jedną grupą także dla czytnika
   ekranu. Wyróżnienie tłem I linią od góry — samo tło znika w trybie wysokiego kontrastu. */
.kolejka__seria-naglowek td {
  background: var(--tlo-naglowka);
  border-top: 2px solid var(--ramka-karty);
}

/* Nagłówek PLANU (Q167) — nad nagłówkami serii, więc linia grubsza niż przy serii: hierarchia
   ma być widoczna bez koloru (1.4.1), a tło to samo, bo to ten sam rodzaj wiersza. */
.kolejka__plan-naglowek td {
  background: var(--tlo-naglowka);
  border-top: 3px solid var(--ramka-karty);
}

/* Nagłówki planu i serii na WĄSKIM ekranie (wiersze są tam kartami): pole wyboru OBOK opisu,
   w jednym pasie z tłem i linią. Bez tej reguły obie komórki stawały blokami jedna pod drugą,
   a komórka pola — o stałej szerokości 44 px — zostawiała nad polem krótki ogonek linii i tła,
   z opisem osobnym blokiem niżej (zrzut 390 px przy Q167; nagłówek serii miał to od M5-A1). */
@media (max-width: 900px) {
  .kolejka tr.kolejka__plan-naglowek,
  .kolejka tr.kolejka__seria-naglowek {
    display: flex;
    align-items: center;
    padding: 0;
    background: var(--tlo-naglowka);
  }

  .kolejka tr.kolejka__plan-naglowek {
    border-top: 3px solid var(--ramka-karty);
  }

  .kolejka tr.kolejka__seria-naglowek {
    border-top: 2px solid var(--ramka-karty);
  }

  .kolejka tr.kolejka__plan-naglowek td,
  .kolejka tr.kolejka__seria-naglowek td {
    border-top: none;
    background: none;
  }

  /* Wymiary JAWNE, nie z treści: komórka pola ma 44 px celu dotykowego i nic więcej, a opis
     bierze resztę pasa i zaczyna się od lewej. Z szerokością wyliczaną z treści pole
     zachodziło na opis, a opis układał się jak wyśrodkowany (zrzut 390 px). */
  .kolejka tr.kolejka__plan-naglowek td.kolejka__zaznacz,
  .kolejka tr.kolejka__seria-naglowek td.kolejka__zaznacz {
    flex: 0 0 44px;
    width: 44px;
    padding: 0;
  }

  .kolejka tr.kolejka__plan-naglowek td:not(.kolejka__zaznacz),
  .kolejka tr.kolejka__seria-naglowek td:not(.kolejka__zaznacz) {
    flex: 1 1 auto;
    min-width: 0;
    padding: 8px 16px 8px 4px;
    text-align: left;
  }

  /* Komórki nagłówków nie mają etykiety kolumny (`data-etykieta`), a pusty pseudoelement
     etykiety wcinał pierwszą linię opisu o swój odstęp. */
  .kolejka tr.kolejka__plan-naglowek td::before,
  .kolejka tr.kolejka__seria-naglowek td::before {
    content: none;
  }
}

/* „Zaznacz wszystkie" przy przycisku akcji zbiorczej (Q167). Pole i etykieta w jednym celu
   dotykowym 44 px (WCAG 2.5.8) — etykieta jest klikalna, więc cel obejmuje cały napis. */
.kolejka__zaznacz-wszystkie {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
}

.kolejka__zaznacz-wszystkie input[type="checkbox"] {
  width: 22px;
  height: 22px;
  margin: 0;
}

/* Zwinięte terminy serii: lista pod <details>, nie kolejne wiersze tabeli. Wiersz tabeli
   schowany w <details> psuje strukturę tabeli dla czytnika ekranu — lista nie psuje. */
.kolejka__terminy {
  list-style: none;
  margin: 8px 0 0;
  padding: 0;
  display: grid;
  gap: 8px;
}

.kolejka__terminy li {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;

  /* ZAWIJANIE, nie przewijanie strony. Wiersz tej listy ma od 2026-09-15 dwa odnośniki
     do dokumentów (dziennik i lista obecności) obok kodu grupy, który jest nierozrywalny
     — bez zawijania rząd rozpychał dokument do 594 px w oknie 390 px i CAŁA strona
     przewijała się w poziomie. Złapał to pomiar układu; objawem był jeden wiersz, a cenę
     płaciły wszystkie ekrany telefonu. */
  flex-wrap: wrap;
}
