/* ══════════════════════════════════════════════════════════════════════════
   zapis_sms — sections/zapis_sms.php
   Modal potwierdzenia zapisu kodem z SMS-a. Na telefonie arkusz dojeżdżający
   od dołu, od 1024px wyśrodkowane okno 520px. Chrom własny, mechanika
   (przyciemnienie, focus trap, Escape, blokada przewijania) z modala Bootstrapa.

   ── Różnice wobec paczki projektowej „Modals potwierdzenia zapisu kurs" ──
   Paczka celowała w inny design system (Tailwind v4, tokeny --color-… i
   --text-…, skala o ~10% wyższa). Zmiany wobec css/modal-sms.css z paczki:
     1. Tokeny --color-…, --radius-…, --duration-… → --ds-* z design-system.css.
     2. font-weight: 700 (badge, tytuł, CTA) → var(--ds-weight-semi) = 600.
        Waga 600 to sufit systemu (CLAUDE.md → „Twarde reguły wyglądu", p. 8).
     3. Ramki kratek 1.5px → 1px (p. 18 — połówka piksela renderuje się
        nierówno na ekranach 2×/3×).
     4. Promień arkusza 28px → var(--ds-radius-xxl) = 24px, kratek 12px →
        var(--ds-radius-md) = 12px (p. 17, promienie ciasne).
     5. Własny .sms-modal__cta (78 linii: tło, cień, hover, active, disabled)
        skasowany — CTA to atom .btn.btn-lg.btn-solar.btn-block z
        design-system.css. Zostaje tylko szerokość i stan „Sprawdzamy kod…".
     6. Własny .sms-modal__badge → atom .badge.badge-success (tekst w
        success-ink, nie w żywym --ds-color-success — p. 12).
     7. Własny .sms-modal__resend (18 linii podkreślenia malowanego
        gradientem) → atom .lnk.
     8. Własne .sms-modal/.sms-modal__scrim/.sms-modal__sheet z
        [data-open=true] i @keyframes sms-sheet-up → .modal Bootstrapa.
     9. Blok @media (prefers-reduced-motion) skasowany — obsłużony globalnie
        w design-system.css (CLAUDE.md → „Stabilność i wydajność", p. 2).
    10. Dolny padding arkusza 60px → calc(var(--ds-space-3) + safe-area), tak
        jak w .zf-sticky (assets/css/zapis_form.css) — CTA modala stoi w tym
        samym miejscu ekranu co CTA formularza, więc ma mieć ten sam odstęp
        od paska gestów iPhone'a.

   ── Ścisk na telefonie (kod SMS, 2026) ──────────────────────────────────
   Po otwarciu klawiatury numerycznej widoczna wysokość ekranu spada poniżej
   wysokości arkusza i trzeba było go scrollować. Odstępy i kratki na kod
   ścieśnione na mobile (desktop bez zmian — tam klawiatura nie zabiera
   miejsca na ekranie): padding i gap arkusza/treści o jeden stopień skali
   niżej, padding-top kratek i nagłówka body zdjęty, kratki 66×64 → 58×54
   (wciąż nad podłogą celu dotykowego 44px, CLAUDE.md p. 15). Elementy na
   ścieżce zakupu z twardym minimum (CTA 52px, wiersz „wyślij ponownie" 44px,
   stopnie pisma z p. 10) zostają bez zmian — ścieśniamy odstępy między nimi,
   nie same elementy.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── Przyciemnienie ───────────────────────────────────────────────────────
   Bootstrap wpina .modal-backdrop jako dziecko <body>, nie modala — nie da
   się tego dosięgnąć selektorem zaczepionym o .zsms. Gdy w serwisie stanie
   drugi modal, ta reguła (i tylko ona z tego pliku) przenosi się do
   design-system.css jako wspólny token przyciemnienia. */
.modal-backdrop {
  --bs-backdrop-bg: var(--ds-color-ink);
  --bs-backdrop-opacity: 0.58;
}

/* Jedno mocne CTA na ekran telefonu (CLAUDE.md p. 2): przy otwartym modalu
   przyklejony pasek formularza z drugim żółtym przyciskiem schodzi z ekranu.
   Bootstrap wiesza .modal-open na <body> na czas otwarcia. */
body.modal-open .zf-sticky { display: none; }

/* ── Arkusz (telefon) ─────────────────────────────────────────────────────
   .modal-dialog Bootstrapa jest wyśrodkowany; na telefonie dociskamy go do
   dołu ekranu i rozciągamy na całą szerokość — reszta (przyciemnienie,
   Escape, focus trap) zostaje jego. */
.zsms .zsms-dialog {
  margin: 0;
  min-height: 100%;
  max-width: none;
  align-items: flex-end;
}

.zsms .zsms-sheet {
  position: relative;
  align-items: center;
  gap: var(--ds-space-3);
  padding: var(--ds-space-2) var(--ds-space-5) calc(var(--ds-space-3) + env(safe-area-inset-bottom));
  text-align: center;
  background-color: var(--ds-color-surface);
  border: none;
  border-radius: var(--ds-radius-xxl) var(--ds-radius-xxl) 0 0;
  box-shadow: var(--ds-shadow-lg);
}

/* Animacja wjazdu na transform (nie na height/top) — patrz CLAUDE.md
   → „Stabilność i wydajność", p. 2. Bootstrap sam podmienia klasy .show. */
.zsms.fade .zsms-dialog {
  transform: translateY(16px);
  transition: transform var(--ds-duration-slow) var(--ds-ease-out-soft);
}
.zsms.show .zsms-dialog { transform: none; }

/* Uchwyt arkusza — tylko telefon, czysta afordancja „to się zamyka w dół". */
.zsms-grabber {
  flex: none;
  width: 40px;
  height: 4px;
  margin: 0 auto;
  border-radius: var(--ds-radius-full);
  background-color: var(--ds-color-hairline);
}

/* ── Zamknięcie ───────────────────────────────────────────────────────────
   Na telefonie zamyka uchwyt i klik w tło; krzyżyk pokazuje się od 1024px,
   gdzie arkusz jest okienkiem i nie ma dolnej krawędzi do zsunięcia. */
.zsms-close {
  position: absolute;
  top: var(--ds-space-3);
  right: var(--ds-space-3);
  display: none;
  place-items: center;
  width: 44px;
  height: 44px;
  padding: 0;
  color: var(--ds-color-ink-secondary);
  background: none;
  border: none;
  border-radius: var(--ds-radius-sm);
  transition: background-color var(--ds-duration-base) var(--ds-ease-out-soft);
}
.zsms-close:hover { background-color: var(--ds-color-canvas-soft); }

/* ── Treść ───────────────────────────────────────────────────────────────── */
.zsms .zsms-body {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--ds-space-2);
  width: 100%;
  padding: 0;
}

.zsms-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.zsms-badge svg { flex: none; }

.zsms-title {
  margin: 0;
  font-family: var(--ds-font-display);
  font-size: var(--ds-text-h2);
  font-weight: var(--ds-weight-semi);
  line-height: 1.22;
  letter-spacing: -0.015em;
  color: var(--ds-color-ink);
}

.zsms-lead {
  margin: 0;
  max-width: 34ch;
  font-size: var(--ds-text-body);
  line-height: 1.55;
  color: var(--ds-color-ink-secondary);
  text-wrap: pretty;
}
/* Numer nie ma prawa się złamać w połowie — na 360px „+48 795 787 145"
   przy złamaniu wygląda jak dwa różne numery. */
.zsms-phone {
  color: var(--ds-color-primary-ink);
  font-weight: var(--ds-weight-semi);
  white-space: nowrap;
}

/* ── Kratki na kod ────────────────────────────────────────────────────────
   4 × 58px + 3 × 6px odstępu = 250px, mieści się na 360px z padding 20px
   po bokach (320px pola). Wysokość 54px — powyżej podłogi 44px celu
   dotykowego (CLAUDE.md p. 15); mniej niż desktopowe 84px (patrz media
   query niżej) właśnie po to, żeby po otwarciu klawiatury arkusz nie musiał
   się scrollować. */
.zsms-code {
  display: flex;
  justify-content: center;
  gap: 6px;
}

.zsms-digit {
  width: 58px;
  height: 54px;
  padding: 0;
  text-align: center;
  font-family: var(--ds-font-display);
  /* Cyfra kodu to jedyna treść tej kratki i jednocześnie potwierdzenie, że
     wpisanie się „złapało" — bierze stopień licznikowy ze skali. */
  font-size: var(--ds-text-numeral);
  font-weight: var(--ds-weight-semi);
  line-height: 1;
  color: var(--ds-color-ink);
  background-color: var(--ds-color-canvas-warm);
  border: 1px solid var(--ds-color-hairline-cool);
  border-radius: var(--ds-radius-md);
  outline: none;
  transition: border-color var(--ds-duration-base) var(--ds-ease-out-soft),
              background-color var(--ds-duration-base) var(--ds-ease-out-soft),
              box-shadow var(--ds-duration-base) var(--ds-ease-out-soft);
}
.zsms-digit:focus {
  background-color: var(--ds-color-canvas);
  border-color: var(--ds-color-primary);
  box-shadow: var(--ds-shadow-ring-focus);
}
.zsms-code[data-state="error"] .zsms-digit { border-color: var(--ds-color-error); }

/* ── Komunikat ────────────────────────────────────────────────────────────
   Stała wysokość jednego wiersza: pojawienie się błędu nie ma prawa
   podnieść CTA w momencie, w którym użytkownik w nie celuje palcem. */
.zsms-msg {
  margin: 0;
  min-height: 20px;
  /* 14px, nie 13px jak w paczce: error-ink na bieli daje Lc 89, a próg dla
     13px to 90 (audyt APCA). Przy 14px próg wynosi 85. Ta sama decyzja i ten
     sam powód co w .zf-msg (assets/css/zapis_form.css) — a komunikat błędu
     w bramce zapisu jest na ścieżce zakupu, więc nie ma tu miejsca na
     świadome odstępstwo (CLAUDE.md → „Twarde reguły wyglądu", p. 11). */
  font-size: var(--ds-text-body-sm);
  line-height: 1.4;
  color: var(--ds-color-error-ink);
}

/* ── Ponowna wysyłka ──────────────────────────────────────────────────────
   Też stała wysokość — licznik i przycisk zamieniają się miejscami, a arkusz
   nie ma przy tym drgnąć. */
.zsms-resend-row {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 44px;
}
.zsms-resend {
  position: relative;
  padding: 0;
  font-size: var(--ds-text-body);
  background: none;
  border: none;
}
/* Cel dotykowy 44px (CLAUDE.md p. 15) rozciągnięty pseudoelementem, a nie
   paddingiem: atom .lnk maluje podkreślenie tłem w `background-position: 0
   100%`, więc każdy dolny padding odklejałby linię od tekstu na tyle pikseli,
   ile go dodamy. Nakładka nie rusza układu — sam wiersz i tak ma min-height
   44px, więc nie wchodzi na sąsiednie cele. */
.zsms-resend::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: 44px;
  transform: translateY(-50%);
}
.zsms-countdown {
  font-size: var(--ds-text-body);
  color: var(--ds-color-ink-muted);
}

/* ── CTA ──────────────────────────────────────────────────────────────────
   Wygląd bierze z atomu .btn-solar; tu tylko szerokość (atom .btn-block od
   1024px wraca do inline-block, a w arkuszu CTA zostaje na całą szerokość)
   i stan sprawdzania kodu. */
.zsms-cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 100%;
}
.zsms-cta:disabled {
  background-color: var(--ds-color-cta-solar);
  box-shadow: none;
  opacity: 0.45;
  transform: none;
}
.zsms-cta[data-loading="true"] { pointer-events: none; }

/* ── Desktop (1024px+): wyśrodkowane okno ────────────────────────────────── */
@media (min-width: 1024px) {
  .zsms .zsms-dialog {
    align-items: center;
    width: 520px;
    max-width: calc(100vw - 48px);
    margin: 0 auto;
  }

  .zsms .zsms-sheet {
    gap: var(--ds-space-5);
    padding: var(--ds-space-10) var(--ds-space-10) var(--ds-space-8);
    border-radius: var(--ds-radius-xxl);
  }

  .zsms-grabber { display: none; }
  .zsms-close   { display: grid; }

  .zsms .zsms-body { gap: var(--ds-space-4); padding-top: 0; }
  .zsms-lead       { max-width: 38ch; }

  .zsms-code  {
    gap: var(--ds-space-2);
    /* Na mobile ten padding jest zdjęty (patrz baza wyżej) — tu przywrócony,
       żeby zmiana zrobiona dla telefonu nie spłynęła na desktop, który
       problemu ze scrollowaniem po klawiaturze nie ma. */
    padding-top: var(--ds-space-1);
  }
  .zsms-digit {
    width: 76px;
    height: 84px;
    /* Skala desktopowa podnosi --ds-text-numeral do 44px — w kratce 76×84
       cyfra zaczyna dotykać krawędzi optycznej, więc ten jeden element
       zostaje na stopniu mobilnym (32px). Świadome odstępstwo od tokena,
       nie brak tokena: kratka nie rośnie proporcjonalnie do skali pisma. */
    font-size: 32px;
  }
}
