/* zapis_form — sections/zapis_form.php
   Formularz zapisu na kurs. Mobile-first: reguły bazowe to jedna kolumna
   (testowana na 360px), @media (min-width: 1024px) to układ dwukolumnowy
   z przyklejoną szyną po prawej.

   ── Czym to się różni od paczki „Formularz zapisu na kurs" ────────────────
   Paczka stoi na DS 1.2 (tokeny --color-*, --text-*, klasy .t-*, .input,
   .field). Obowiązuje AKTUALNY design system serwisu (assets/css/
   design-system.css, tokeny --ds-*), więc przeniesione są KOMPOZYCJA
   i PROPORCJE, a wartości pochodzą z dzisiejszych tokenów. Świadomie:
     • wszystkie stopnie pisma z aktualnej skali (--ds-text-*); wszystko, co
       w paczce miało 10,5–12,5px, wjechało na 13px — poniżej 13px nie ma
       w treści nic (CLAUDE.md, reguła 10). Dotyczy: eyebrow karty kursu,
       podtytułu przełącznika, plakietek, noty „do zapłaty teraz" i paska
       zaufania;
     • waga 600 zamiast 700 wszędzie (reguła 8) — także w numerkach sekcji
       i w eyebrow;
     • ramki 1px zamiast 1,5px (reguła 18);
     • zielony tekst (cena rabatowa, „Rabaty razem", prezent) w
       --ds-color-success-ink zamiast lokalnego --en-green z paczki: token
       systemowy jest ciemniejszy i sam trafia w próg APCA, więc paczkowe
       --en-green / --en-green-ink są niepotrzebne (reguła 12 — litery biorą
       wariant -ink);
     • ramki niezaznaczonych opcji w --ds-color-hairline-cool zamiast
       lokalnego --en-line-soft (ten sam efekt, zero nowych tokenów);
     • pola formularza na .form-control z design systemu (16px, iOS nie
       przybliża widoku przy focusie) — tylko wysokość podniesiona do 52px
       i focus bez halo, zgodnie z paczką;
     • promienie z tokenów: karty 18px (--ds-radius-xl) zamiast 20px,
       opcje 14px (--ds-radius-lg), przyciski 12px (--ds-radius-md);
     • karta kursu rozwija się Bootstrapowym .collapse — bez własnego JS;
     • plakietki to systemowe .badge-success / .badge-warn / .badge-live
       (kropka „na żywo" dochodzi z ::before, nie z markupu).
   Wartości projektowe SPOZA tokenów, zachowane 1:1 za paczką: szerokość
   szyny 428px, wysokość pola 52px, wysokość CTA 56px i zapas 32px pod
   paskiem CTA. Siatka adresu na telefonie (1fr 132px / 132px 1fr) odstaje
   od paczki (1fr 104px / 118px 1fr) — nr domu/lokalu i kod pocztowy były
   za ciasne na realnych wartościach (np. "12A/34"), więc kolumna urosła
   kosztem sąsiada w tym samym wierszu (on i tak jest elastyczny, 1fr).
   ------------------------------------------------------------------------- */

/* ── Siatka strony ──────────────────────────────────────────────────────── */
.zf { display: block; background-color: var(--ds-color-canvas); }

.zf-grid {
  max-width: 1320px;
  margin-inline: auto;
  /* Dolny zapas pod przyklejonym CTA — bez niego pasek zasłania stopkę treści.
     140px = 132px + 8px, o tyle urósł .zf-sticky po podniesieniu jego
     paddingu dolnego z --ds-space-3 na -5. */
  padding: 16px var(--ds-space-4) 140px;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--ds-space-6);
}

/* Na telefonie .zf-rail przepuszcza dzieci wprost do siatki (display: contents),
   więc karta kursu może wskoczyć na samą górę przez `order`. Od 1024px szyna
   wraca do bycia kolumną w prawej kolumnie siatki. */
.zf-rail, .zf-rail-top { display: contents; }
.zf-course       { order: -2; }
.zf-intro        { order: -1; }
.zf-main         { order: 0; }
.zf-summary      { order: 1; }
.zf-consent-wrap { order: 2; }
.zf-withdrawal-wrap { order: 2; }
.zf-privacy      { order: 3; }
.zf-trust        { order: 4; }

/* Pasek wyniku wysyłki (wraca z scripts/zapis.php przez ?ok / ?blad). */
.zf-status {
  order: -3;
  margin: 0;
  padding: 12px 14px;
  border-radius: var(--ds-radius-lg);
  /* 15px w wadze 600: teksty -ink na swoich tintach dają tu Lc ~80, a próg
     dla 14px to 85 (audyt APCA). Cięższa waga liczy się jak +2px, więc para
     przechodzi z zapasem. */
  font-size: var(--ds-text-body);
  font-weight: var(--ds-weight-semi);
  line-height: 1.45;
}
.zf-status-ok    { background-color: var(--ds-color-success-tint); color: var(--ds-color-success-ink); }
.zf-status-error { background-color: var(--ds-color-error-tint);   color: var(--ds-color-error-ink); }

/* Pole-pułapka na boty. Nie display:none — część botów pomija takie pola,
   a czytnikom ekranu wystarczy aria-hidden w markupie. */
.zf-trap {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* ── Nagłówek + prezent ─────────────────────────────────────────────────── */
.zf-title { margin: 0; }

.zf-lead {
  margin: 10px 0 0;
  font-family: var(--ds-font-body);
  font-size: var(--ds-text-body);
  line-height: 1.5;
  color: var(--ds-color-ink-secondary);
}

.zf-gift {
  margin: 14px 0 0;
  display: flex;
  gap: 10px;
  align-items: center;
  padding: 11px 13px;
  border-radius: var(--ds-radius-lg);
  background-color: var(--ds-color-success-tint);
  color: var(--ds-color-success-ink);
  /* 13px na mobile (na życzenie) — świadome odstępstwo od progu APCA:
     success-ink na success-tint to Lc 80,3, a przy 13px próg wynosi 90
     (CLAUDE.md reguła 11). Deficyt 9,7 pkt mieści się w dopuszczalnych 10,
     to nie ścieżka zakupu (CTA/cena/formularz), sprawdzone na 360px. Od
     1024px wraca do var(--ds-text-body), gdzie przechodzi z zapasem. */
  font-size: var(--ds-text-caption);
  line-height: 1.45;
}
.zf-gift-icon { flex: none; display: grid; place-items: center; }

/* ── Sekcje formularza ──────────────────────────────────────────────────── */
.zf-main { display: flex; flex-direction: column; gap: var(--ds-space-6); }

.zf-section { display: flex; flex-direction: column; gap: 12px; }

.zf-section-title {
  margin: 0;
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: var(--ds-text-h2);
  line-height: 1.25;
}

.zf-step {
  width: 26px;
  height: 26px;
  flex: none;
  border-radius: var(--ds-radius-full);
  background-color: var(--ds-color-primary-tint);
  color: var(--ds-color-primary-ink);
  display: grid;
  place-items: center;
  font-family: var(--ds-font-body);
  font-size: var(--ds-text-label);
  font-weight: var(--ds-weight-semi);
  line-height: 1;
}

.zf-section-lead {
  margin: -4px 0 0;
  font-size: var(--ds-text-body-sm);
  line-height: 1.45;
  color: var(--ds-color-ink-muted);
}

/* ── Pola ───────────────────────────────────────────────────────────────── */
.zf-fields { display: grid; grid-template-columns: minmax(0, 1fr); gap: 12px; }
.zf-fields-2      { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
.zf-fields-street { grid-template-columns: minmax(0, 1fr) 132px; }
.zf-fields-city   { grid-template-columns: 132px minmax(0, 1fr); }

.zf-field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
/* Na telefonie e-mail i telefon zajmują całą szerokość siatki — 165px na
   adres e-mail przy 360px to za mało (za projektem, artboard 390px).
   Na desktopie wracają do dwóch kolumn razem z imieniem i nazwiskiem. */
.zf-fields-2 > .zf-field-wide { grid-column: 1 / -1; }

.zf-label {
  font-family: var(--ds-font-body);
  font-weight: var(--ds-weight-regular);
  font-size: var(--ds-text-body);
  line-height: 1.3;
  color: var(--ds-color-ink-secondary);
}
.zf-req { color: var(--ds-color-error-ink); }

/* Pole na .form-control z design systemu; tu tylko wysokość z paczki (52px)
   i focus bez kolorowego halo — zamiast cienia podwaja się ramka przez
   inset box-shadow, więc nic nie przeskakuje o 1px. */
.zf-input { min-height: 52px; }
.zf-input:focus {
  border-color: var(--ds-color-primary);
  box-shadow: inset 0 0 0 1px var(--ds-color-primary);
}

.zf-hint {
  font-size: var(--ds-text-caption);
  line-height: 1.4;
  color: var(--ds-color-ink-muted);
}

/* Komunikat walidacji. Pusty span nie zajmuje miejsca (:empty → display:none),
   więc dopóki pole nie było sprawdzane, układ wygląda jak bez komunikatów. */
.zf-msg {
  /* 14px, nie 13px: potwierdzenie w success-ink daje na bieli Lc 86,7,
     a próg dla 13px to 90 (audyt APCA). Przy 14px próg wynosi 85. */
  font-size: var(--ds-text-body-sm);
  line-height: 1.4;
}
.zf-msg:empty { display: none; }

.zf-field-error .zf-input,
.zf-field-error .zf-input:focus { border-color: var(--ds-color-error); box-shadow: none; }
.zf-field-error .zf-msg { color: var(--ds-color-error-ink); }

.zf-field-ok .zf-input { border-color: var(--ds-color-success); }
.zf-field-ok .zf-msg { color: var(--ds-color-success-ink); }

/* ── Pola rodzica / opiekuna ────────────────────────────────────────────── */
.zf-guardian { display: flex; flex-direction: column; gap: 12px; }

.zf-note {
  margin: 0;
  padding: 11px 13px;
  border-radius: var(--ds-radius-lg);
  background-color: var(--ds-color-primary-tint);
  color: var(--ds-color-primary-ink);
  /* 15px, nie 14px — primary-ink na primary-tint daje Lc 82,7 (audyt APCA). */
  font-size: var(--ds-text-body);
  line-height: 1.45;
}

/* ── Przełącznik pełnoletności ──────────────────────────────────────────── */
.zf-seg {
  position: relative;
  display: flex;
  gap: 4px;
  padding: 4px;
  margin-top: 2px;
  border-radius: var(--ds-radius-lg);
  background-color: var(--ds-color-canvas-soft);
}
/* Natywne radio zostaje w DOM (klawiatura, czytniki, wysyłka), tylko schodzi
   z oczu — nie używamy display:none, bo to wyjmuje je z kolejności tabulacji. */
.zf-seg-input {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
  margin: 0;
  pointer-events: none;
}
.zf-seg-btn {
  flex: 1 1 0;
  min-width: 0;
  padding: 9px 6px;
  border-radius: var(--ds-radius-md);
  text-align: center;
  cursor: pointer;
  font-family: var(--ds-font-display);
  font-weight: var(--ds-weight-semi);
  line-height: 1.3;
  color: var(--ds-color-ink-secondary);
  transition: background-color var(--ds-duration-base) var(--ds-ease-out-soft),
              color var(--ds-duration-base) var(--ds-ease-out-soft);
}
.zf-seg-input:checked + .zf-seg-btn {
  background-color: var(--ds-color-canvas);
  color: var(--ds-color-ink);
  box-shadow: var(--ds-shadow-sm);
}
.zf-seg-input:focus-visible + .zf-seg-btn {
  outline: 2px solid var(--ds-color-primary);
  outline-offset: 2px;
}
.zf-seg-title { display: block; font-size: var(--ds-text-body-sm); }
.zf-seg-sub {
  display: block;
  font-family: var(--ds-font-body);
  font-weight: var(--ds-weight-regular);
  /* 14px i ink-secondary, choć w paczce było 11px: na tle ścieżki
     przełącznika (canvas-soft) ta para daje Lc 89, a próg dla 13px to 90
     (audyt APCA). Przy 14px próg wynosi 85. Hierarchię wobec tytułu niesie
     waga (400 wobec 600), nie stopień pisma. */
  font-size: var(--ds-text-body-sm);
  color: var(--ds-color-ink-secondary);
}

/* ── Opcje wyboru (grupa zajęciowa, sposób płatności) ───────────────────── */
.zf-options {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 10px;
}
.zf-option-input {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
  margin: 0;
  pointer-events: none;
}
.zf-option {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  padding: 14px;
  border: 1px solid var(--ds-color-hairline-cool);
  border-radius: var(--ds-radius-lg);
  background-color: var(--ds-color-canvas);
  cursor: pointer;
  transition: border-color var(--ds-duration-base) var(--ds-ease-out-soft),
              background-color var(--ds-duration-base) var(--ds-ease-out-soft);
}
.zf-options-compact .zf-option { padding: 12px; align-items: center; gap: 10px; }

.zf-option-input:checked + .zf-option {
  border-color: var(--ds-color-primary);
  background-color: var(--ds-color-primary-tint);
}
.zf-option-input:focus-visible + .zf-option {
  outline: 2px solid var(--ds-color-primary);
  outline-offset: 2px;
}

.zf-radio {
  width: 20px;
  height: 20px;
  flex: none;
  margin-top: 1px;
  border-radius: var(--ds-radius-full);
  background-color: var(--ds-color-canvas);
  border: 1px solid var(--ds-color-hairline-cool);
  transition: border-width var(--ds-duration-fast) var(--ds-ease-out-soft);
}
.zf-options-compact .zf-radio { margin-top: 0; }
/* Zaznaczenie to gruby pierścień, nie osobna kropka — nadpisujemy CAŁY skrót
   `border`, żeby po odznaczeniu wróciła cienka ramka, a nie kolor tekstu. */
.zf-option-input:checked + .zf-option .zf-radio { border: 6px solid var(--ds-color-primary); }

.zf-option-body {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 5px;
}
.zf-option-title {
  font-family: var(--ds-font-display);
  font-weight: var(--ds-weight-semi);
  font-size: var(--ds-text-body);
  line-height: 1.35;
  color: var(--ds-color-ink);
}
.zf-option-sub {
  font-size: var(--ds-text-body-sm);
  line-height: 1.4;
  color: var(--ds-color-ink-muted);
}
.zf-price {
  font-family: var(--ds-font-display);
  font-weight: var(--ds-weight-semi);
  font-size: var(--ds-text-body-sm);
  color: var(--ds-color-ink);
  font-variant-numeric: tabular-nums lining-nums;
}
.zf-price-save { color: var(--ds-color-success-ink); }
.zf-price-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

/* 12px, poniżej progu 13px z CLAUDE.md (reguła 10) — świadome odstępstwo na
   wyraźne życzenie Tomka, tylko na plakietkach tego formularza (nie zmienia
   .badge globalnie). */
.zf-options .badge { --bs-badge-font-size: 12px; font-size: 12px; }

/* ── Karta wybranego kursu ──────────────────────────────────────────────── */
.zf-course { padding: 0; overflow: hidden; border-radius: var(--ds-radius-xl); }
.zf-course-bar { height: 4px; }

.zf-course-head {
  width: 100%;
  display: flex;
  gap: 11px;
  align-items: center;
  padding: 12px;
  background: none;
  border: none;
  text-align: left;
  cursor: pointer;
  color: var(--ds-color-ink);
}
.zf-course-meta { flex: 1 1 auto; min-width: 0; display: block; }
.zf-course-eyebrow { display: block; letter-spacing: 0.05em; color: var(--ds-color-ink-muted); }
.zf-course-name {
  display: block;
  margin-top: 2px;
  font-family: var(--ds-font-display);
  font-weight: var(--ds-weight-semi);
  font-size: var(--ds-text-title);
  letter-spacing: -0.01em;
  color: var(--ds-color-ink);
}
.zf-course-facts {
  display: block;
  font-size: var(--ds-text-caption);
  line-height: 1.4;
  color: var(--ds-color-ink-muted);
}
.zf-chevron {
  flex: none;
  display: grid;
  place-items: center;
  color: var(--ds-color-primary);
  transition: transform var(--ds-duration-base) var(--ds-ease-out-soft);
}
.zf-course-head[aria-expanded="true"] .zf-chevron { transform: rotate(180deg); }

/* Cena wyrównana do treści karty, nie do kafla ikony (12px padding + 40px
   kafel + 11px odstęp = 63px). */
.zf-course-price {
  margin: -6px 0 0;
  padding: 0 12px 12px 63px;
  font-family: var(--ds-font-display);
  font-weight: var(--ds-weight-semi);
  font-size: var(--ds-text-body-sm);
  color: var(--ds-color-ink);
}

.zf-course-details { padding: 0 12px 14px; }

.zf-teacher {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px;
  border-radius: var(--ds-radius-md);
  background-color: var(--ds-color-canvas-warm);
}
.zf-teacher-photo { width: 40px; height: 40px; flex: none; border-radius: var(--ds-radius-full); object-fit: cover; }
.zf-teacher-meta { min-width: 0; }
.zf-teacher-name {
  display: block;
  font-family: var(--ds-font-display);
  font-weight: var(--ds-weight-semi);
  font-size: var(--ds-text-body-sm);
  color: var(--ds-color-ink);
}

.zf-course-included {
  margin: 14px 0 10px;
  font-family: var(--ds-font-display);
  font-weight: var(--ds-weight-semi);
  font-size: var(--ds-text-body-sm);
  color: var(--ds-color-ink);
}
.zf-checklist { margin: 0; display: flex; flex-direction: column; gap: 8px; }
.zf-checklist li { font-size: var(--ds-text-body-sm); line-height: 1.4; color: var(--ds-color-ink-secondary); }

/* ── Podsumowanie ───────────────────────────────────────────────────────── */
.zf-summary { padding: 0; overflow: hidden; border-radius: var(--ds-radius-xl); }
.zf-summary-body { padding: 14px 16px; display: flex; flex-direction: column; gap: 10px; }
.zf-summary-now {
  padding: 14px 16px;
  background-color: var(--ds-color-canvas-warm);
  border-top: 1px solid var(--ds-color-hairline);
}

.zf-row { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; }
.zf-row-label { font-size: var(--ds-text-body-sm); line-height: 1.4; color: var(--ds-color-ink-secondary); }
.zf-row-label-strong {
  display: block;
  font-family: var(--ds-font-display);
  font-weight: var(--ds-weight-semi);
  color: var(--ds-color-ink);
}
.zf-row-value {
  font-family: var(--ds-font-display);
  font-weight: var(--ds-weight-medium);
  font-size: var(--ds-text-body-sm);
  white-space: nowrap;
  font-variant-numeric: tabular-nums lining-nums;
}
.zf-row-value-muted { color: var(--ds-color-ink-muted); }
.zf-row-value-save  { color: var(--ds-color-success-ink); }
.zf-row-value-total {
  font-weight: var(--ds-weight-semi);
  font-size: var(--ds-text-h3);
  color: var(--ds-color-ink);
}
.zf-row-sum {
  padding: 8px 10px;
  border-radius: var(--ds-radius-md);
  background-color: var(--ds-color-success-tint);
  color: var(--ds-color-success-ink);
  font-size: var(--ds-text-label);
  font-weight: var(--ds-weight-semi);
}
.zf-row-sum span:last-child {
  font-family: var(--ds-font-display);
  font-size: var(--ds-text-body-sm);
  white-space: nowrap;
  font-variant-numeric: tabular-nums lining-nums;
}

.zf-hr { border: none; border-top: 1px solid var(--ds-color-hairline); margin: 0; opacity: 1; }
.zf-discounts { display: flex; flex-direction: column; gap: 10px; }
.zf-discounts-eyebrow { display: block; color: var(--ds-color-ink-muted); }

.zf-code { display: flex; flex-direction: column; gap: 10px; align-items: flex-start; }
/* Cel dotykowy linku „Mam kod specjalny" — 44px wysokości robi padding,
   podkreślenie zostaje przy samym tekście. */
.zf-link {
  border: none;
  background: none;
  padding: 11px 0;
  cursor: pointer;
  font-family: var(--ds-font-body);
  font-weight: var(--ds-weight-medium);
  font-size: var(--ds-text-body-sm);
  color: var(--ds-color-primary-ink);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.zf-link:hover { color: var(--ds-color-primary); }
.zf-code .zf-field { width: 100%; }

.zf-now {
  font-family: var(--ds-font-display);
  font-weight: var(--ds-weight-semi);
  font-size: var(--ds-text-h1);
  letter-spacing: -0.02em;
  line-height: 1.1;
  color: var(--ds-color-ink);
  white-space: nowrap;
  font-variant-numeric: tabular-nums lining-nums;
}
.zf-now-note {
  margin: 6px 0 0;
  font-size: var(--ds-text-caption);
  line-height: 1.4;
  color: var(--ds-color-ink-muted);
}

/* ── Zgoda, polityka, pasek zaufania ────────────────────────────────────── */
.zf-consent-wrap { position: relative; display: flex; flex-direction: column; gap: 6px; }
.zf-consent-input {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
  margin: 0;
  pointer-events: none;
}
/* min-height 44px: przy dwóch liniach tekstu etykieta ma 41px, a to jedyny
   sposób zaznaczenia zgody (CLAUDE.md, reguła 15). */
.zf-consent { display: flex; gap: 11px; align-items: flex-start; cursor: pointer; margin: 0; min-height: 44px; }
.zf-consent-box {
  width: 22px;
  height: 22px;
  flex: none;
  margin-top: 1px;
  border-radius: var(--ds-radius-xs);
  display: grid;
  place-items: center;
  background-color: var(--ds-color-canvas);
  border: 1px solid var(--ds-color-hairline-cool);
  color: transparent;
  transition: background-color var(--ds-duration-base) var(--ds-ease-out-soft),
              border-color var(--ds-duration-base) var(--ds-ease-out-soft);
}
.zf-consent-input:checked + .zf-consent .zf-consent-box {
  background-color: var(--ds-color-primary);
  border-color: var(--ds-color-primary);
  color: var(--ds-color-on-primary);
}
.zf-consent-input:focus-visible + .zf-consent .zf-consent-box {
  outline: 2px solid var(--ds-color-primary);
  outline-offset: 3px;
}
.zf-consent-text {
  font-size: var(--ds-text-body-sm);
  line-height: 1.45;
  color: var(--ds-color-ink-secondary);
}
.zf-consent-text a { color: var(--ds-color-primary-ink); text-decoration: underline; text-underline-offset: 2px; }
.zf-consent-wrap.zf-field-error .zf-consent-box { border-color: var(--ds-color-error); }
.zf-consent-wrap.zf-field-error .zf-msg { color: var(--ds-color-error-ink); }
.zf-consent-wrap .zf-msg { padding-left: 33px; }

.zf-privacy {
  margin: 0;
  font-size: var(--ds-text-caption);
  line-height: 1.45;
  color: var(--ds-color-ink-muted);
}
/* W szynie na desktopie ta notka leży na kremowym tle, gdzie primary-ink przy
   13px daje Lc 87,1 przy progu 90 (audyt APCA). Ciemniejszy primary-deep
   przechodzi i na bieli, i na kremie — bez podnoszenia stopnia przypisu. */
.zf-privacy .lnk { color: var(--ds-color-primary-deep); }

.zf-trust {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 8px 16px;
}
.zf-trust li {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: var(--ds-text-caption);
  color: var(--ds-color-ink-secondary);
}
/* Ptaszek jest glifem, nie ilustracją — bierze wariant -ink (CLAUDE.md, reguła 12). */
.zf-trust li::before {
  content: "✓";
  color: var(--ds-color-success-ink);
  font-size: var(--ds-text-label);
  line-height: 1;
}

/* ── CTA ────────────────────────────────────────────────────────────────── */
.zf-cta-rail { display: none; }

.zf-sticky {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 30;
  /* Bez paddingu u góry — pasek dowodu społecznego (.clv, pierwsze dziecko)
     wnosi własny odstęp od góry przez padding-top swojego tekstu, dokładnie
     jak na landingu kursu, gdzie .m-sticky też nie ma własnego paddingu
     (patrz komentarz przy .zf-sticky .clv niżej). Padding na dół: standardowy
     wzorzec co .m-sticky w course_stickybar.css — env(safe-area-inset-bottom)
     sam w sobie już rezerwuje dokładnie tyle miejsca, ile potrzeba na pasek
     gestów iPhone'a, bez sztywno dorzuconych dodatkowych pikseli.

     --safe-bottom (zamrożone przez assets/js/zapis_form.js, patrz punkt 6
     komentarza na górze tego pliku) zamiast env() na żywo: na Chrome na iOS
     env(safe-area-inset-bottom) zmienia wartość razem z chowaniem/pokazywaniem
     paska narzędzi, więc bez zamrożenia ten pasek zmieniałby wysokość przy
     każdym scrollu. Fallback na env() zostaje na wypadek wyłączonego JS.
     --ds-space-5 zamiast -3 pod CTA — wyraźnie więcej luzu od dołu niż od
     góry paska (ten sam wybór co .m-sticky w course_stickybar.css). */
  padding: 0 var(--ds-space-4) calc(var(--ds-space-5) + var(--safe-bottom, env(safe-area-inset-bottom)));
  background-color: var(--ds-color-canvas);
  border-top: 1px solid var(--ds-color-hairline);
  box-shadow: var(--ds-shadow-sticky-bar);
}
.zf-sticky .btn { min-height: 56px; }

/* Pasek dowodu społecznego (sections/course_last60mins_views.php, ten sam
   element co na landingu kursu) jako pierwsze dziecko .zf-sticky. Tam stoi
   w .m-sticky bez własnego paddingu poziomego (course_stickybar.css), więc
   ujemny margines wypycha go tu z paddingu .zf-sticky — tło sięga
   prawdziwych krawędzi ekranu tak samo jak na landingu, a najdłuższy
   komunikat rotatora ma na 360px te same 8px rynny co tam, zamiast 24px.

   Hairline (dziedziczony z bazowego .clv) zostaje — to ten sam separator,
   co na landingu, między rotującym tekstem a CTA. Margines na dole
   odtwarza tam ten sam odstęp: na landingu po hairline'u jest jeszcze
   padding-top .csb-inner (--ds-space-3); tu, bez oddzielnego wrappera na
   CTA, tę samą wartość niesie margin-bottom .clv. */
.zf-sticky .clv {
  margin: 0 calc(-1 * var(--ds-space-4)) var(--ds-space-3);
}

/* ── Desktop (1024px+) ──────────────────────────────────────────────────── */
@media (min-width: 1024px) {
  .zf { background-color: var(--ds-color-canvas-warm); }

  .zf-grid {
    padding: 36px var(--ds-space-5) 48px;
    grid-template-columns: minmax(0, 1fr) 428px;
    grid-template-areas:
      "status status"
      "intro  rail"
      "main   rail";
    gap: var(--ds-space-8);
    align-items: start;
  }
  /* Bez błędu ten wiersz siatki po prostu nie istnieje (auto-wysokość, nic
     go nie zajmuje) — nie trzeba go warunkować osobno w CSS. */
  .zf-status { grid-area: status; }
  .zf-intro { grid-area: intro; }
  .zf-main  { grid-area: main; gap: var(--ds-space-5); }
  /* Szyna przyklejona górą, za paczką — ale z ograniczoną wysokością.
     Przyklejony blok wyższy od okna NIGDY nie pokazuje swojego dołu, a tam
     jest CTA; na laptopie (okno ~750–950px) szyna z rabatami ma ~900px.
     Dlatego szyna nie przekracza wysokości okna, a przewija się w niej tylko
     część górna (karta kursu + podsumowanie). Zgoda, CTA i pasek zaufania
     zostają na dole szyny — zawsze widoczne. */
  .zf-rail {
    grid-area: rail;
    display: flex;
    flex-direction: column;
    gap: var(--ds-space-4);
    position: sticky;
    top: 84px;              /* wysokość paska górnego + oddech */
    align-self: start;
    max-height: calc(100vh - 84px - var(--ds-space-4));
  }
  /* flex: none na elementach dolnych — bez tego flexbox ściskałby je,
     zamiast przewinąć część górną. */
  .zf-rail > * { flex: none; }
  .zf-rail-top {
    display: flex;
    flex-direction: column;
    gap: var(--ds-space-4);
    flex: 0 1 auto;
    min-height: 0;          /* warunek, żeby element flex mógł się skurczyć */
    overflow-y: auto;
  }
  .zf-rail-top > * { flex: none; }
  /* `order` z układu telefonowego już nie obowiązuje — na desktopie decyduje
     kolejność w markupie. */
  .zf-status, .zf-course, .zf-intro, .zf-main, .zf-summary,
  .zf-consent-wrap, .zf-withdrawal-wrap, .zf-privacy, .zf-trust { order: 0; }

  .zf-lead { margin-top: 12px; }
  .zf-gift { margin-top: 16px; padding: 13px 16px; font-size: var(--ds-text-body); }

  /* Sekcje formularza jako białe karty na kremowym tle. */
  .zf-section {
    background-color: var(--ds-color-surface);
    border: 1px solid var(--ds-color-hairline);
    border-radius: var(--ds-radius-xl);
    box-shadow: var(--ds-shadow-sm);
    padding: 24px;
    gap: 14px;
  }
  .zf-step { width: 28px; height: 28px; font-size: var(--ds-text-body-sm); }

  .zf-fields { gap: 14px; }
  .zf-fields-2      { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .zf-fields-2 > .zf-field-wide { grid-column: auto; }
  .zf-fields-street { grid-template-columns: 3fr 1fr; }
  .zf-fields-city   { grid-template-columns: 1fr 3fr; }

  .zf-seg-title { font-size: var(--ds-text-body-lg); }
  .zf-options   { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 12px; }
  /* Metody płatności (bez .zf-options-compact) mają zostać pełnej szerokości
     nawet na desktopie — druga pod pierwszą, nie obok. */
  .zf-options:not(.zf-options-compact) { grid-template-columns: minmax(0, 1fr); }

  .zf-summary-body, .zf-summary-now { padding: 18px 20px; }

  /* .btn-block wraca od 1024px do inline-block/auto (design-system.css) —
     w szynie CTA musi zostać na pełną szerokość kolumny. */
  /* .btn.zf-cta-rail, nie samo .zf-cta-rail: .btn-lg.btn-solar z design
     systemu ma wyższą specyficzność i przykrywałoby min-height. */
  .btn.zf-cta-rail { display: block; width: 100%; min-height: 56px; }
  .zf-sticky   { display: none; }
}
