/* ============================================
   Wedding Landing — Komponenty współdzielone
   Używane przez oba ekrany (index.php, rsvp.php)
   ============================================ */

/* === Typografia ==========================================
   .script-title  — Mea Culpa (Dress Code, Registry, Rsvp, imiona)
   .section-label — Magra wersalikami (THE DATE, TRAVEL, …)
   .lede          — akapit treści
   ========================================================= */
.script-title {
  font-family: var(--font-script);
  font-size: var(--fs-script-section);
  font-weight: var(--fw-regular);
  line-height: var(--lh-script);
  text-align: center;
}

.section-label {
  font-size: var(--fs-heading);
  font-weight: var(--fw-regular);
  line-height: var(--lh-body);
  text-transform: uppercase;
  text-align: center;
}

.lede {
  max-width: var(--prose-w);
  margin-inline: auto;
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  text-align: center;
}

/* === Łukowy panel ========================================
   Bordowa płyta z kopulastą górą. Ten sam kształt niesie
   kartę „details” na stronie głównej i kartę formularza RSVP.
   ========================================================= */
.arch-panel {
  position: relative;
  width: var(--content-w);
  margin-inline: auto;
  padding-inline: var(--sp-4);
  color: var(--text-on-burgundy);
  text-align: center;
  background: var(--c-burgundy);
  border-radius: var(--r-arch) var(--r-arch) 0 0;
}

/* === Blob ================================================
   Organiczne przejścia między sekcjami. W Figmie to ogromne
   obrócone kształty wystające daleko poza kadr — nie border-radius.
   Kształt niesie maska SVG, kolor zostaje w tokenach, więc
   zmiana palety nie wymaga edycji plików graficznych.
   ========================================================= */
.blob {
  position: absolute;
  pointer-events: none;
}

/* mask-image trafia do reguł wariantów (.blob--*), nie tutaj:
   url() podany przez custom property przeglądarka rozwiązuje względem
   dokumentu, a nie arkusza, przez co ścieżka względna się rozjeżdża. */
.blob::before {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: var(--blob-w);
  height: var(--blob-h);
  background: var(--blob-color);
  transform: translate(-50%, -50%) rotate(var(--blob-rot));
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
}

/* === Pasmo zdjęciowe ===================================== */
.photo-band {
  position: relative;
  width: 1932px;
  margin-left: -5px;
  overflow: hidden;
}

.photo-band picture {
  display: block;
  width: 100%;
  height: 100%;
}

/* Makieta rozciąga te zdjęcia do ramki (fill), nie kadruje ich (cover) —
   stąd celowo niezachowane proporcje oryginału. */
.photo-band img {
  width: 100%;
  height: 100%;
  object-fit: fill;
}

/* === Próbki kolorów (dress code) ========================= */
.swatch-row {
  display: flex;
  gap: var(--sp-4);
  align-items: center;
  justify-content: center;
}

.swatch {
  width: 113.83px;
  height: 99.24px;
  flex: none;
  background: var(--swatch-color);
  -webkit-mask: url('../img/swatches/heart.svg') no-repeat center / contain;
  mask: url('../img/swatches/heart.svg') no-repeat center / contain;
}

/* === Licznik ============================================= */
.countdown {
  display: flex;
  gap: var(--countdown-gap, 40px);
  align-items: flex-start;
  justify-content: center;
}

.countdown-unit {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 15px;
  width: 205px;
  flex: none;
}

.countdown-unit__digits {
  display: flex;
  gap: 15px;
}

.countdown-unit__digit {
  display: grid;
  place-items: center;
  width: 95px;
  height: 123px;
  font-size: var(--fs-countdown-digit);
  line-height: 1;
  color: var(--countdown-tile-fg);
  background: var(--countdown-tile-bg);
  border-radius: 100px;
  font-variant-numeric: tabular-nums;
}

.countdown-unit__label {
  font-size: var(--fs-countdown-label);
  line-height: var(--lh-body);
  color: var(--countdown-tile-fg);
}

/* === Pola formularza ===================================== */
.field {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.field + .field {
  margin-top: var(--sp-field-group, 36px);
}

.field__label {
  max-width: var(--text-w);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  text-align: center;
}

.field__control {
  width: var(--text-w);
  margin-top: var(--sp-field-label, 42px);
}

/* Lista opcji siedzi bliżej etykiety niż pole tekstowe — w makiecie
   pigułki są osobnymi elementami w tym samym rytmie 36 px. */
.field__control.option-list {
  margin-top: var(--sp-option-label, var(--sp-field-gap, 36px));
}

.field__input {
  width: 100%;
  height: 82px;
  padding-inline: 64px;
  font-size: var(--fs-option);
  color: var(--text-on-burgundy);
  text-align: center;
  background: transparent;
  border: 4.85px solid var(--c-cream);
  border-radius: var(--r-pill);
}

.field__input::placeholder {
  color: color-mix(in srgb, var(--c-cream) 55%, transparent);
}

.field__input:focus-visible {
  outline: none;
  background: color-mix(in srgb, var(--c-cream) 10%, transparent);
}

/* Pigułka wyboru — w makiecie istnieje tylko stan spoczynku;
   stany hover/checked dorobione, bo bez nich wybór jest nieczytelny. */
.option-list {
  display: flex;
  flex-direction: column;
  gap: var(--sp-field-gap, 36px);
}

.option-pill {
  position: relative;
  display: grid;
  place-items: center;
  width: 100%;
  height: 82px;
  font-size: var(--fs-option);
  line-height: var(--lh-body);
  color: var(--text-on-burgundy);
  text-align: center;
  cursor: pointer;
  background: var(--c-burgundy-soft);
  border: 4.85px solid transparent;
  border-radius: var(--r-pill);
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease);
}

.option-pill input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.option-pill:hover {
  background: color-mix(in srgb, var(--c-burgundy-soft) 80%, var(--c-cream));
}

.option-pill:has(input:checked) {
  border-color: var(--c-cream);
  background: color-mix(in srgb, var(--c-burgundy-soft) 70%, var(--c-cream));
}

.option-pill:has(input:focus-visible) {
  outline: 3px solid var(--c-cream);
  outline-offset: 6px;
}

/* === Przycisk ============================================
   Makieta nie rysuje przycisku wysyłki, więc bierze on wymiary i kolory
   wprost z jej kontrolek: wysokość 82 px, obrys 4,854 px i promień
   194,145 px jak pola, wypełnienie kremem — tym samym, którym w makiecie
   pisane są etykiety na bordowej karcie.
   ========================================================= */
.btn {
  display: inline-grid;
  place-items: center;
  min-width: 520px;
  height: 82px;
  padding-inline: var(--sp-5);
  font-size: var(--fs-option);
  color: var(--c-burgundy);
  text-decoration: none;
  cursor: pointer;
  background: var(--c-cream);
  border: 4.85px solid var(--c-cream);
  border-radius: var(--r-pill);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}

/* Odwrócenie: przycisk przybiera postać pustego pola z makiety. */
.btn:hover {
  color: var(--c-cream);
  background: transparent;
}

.btn:focus-visible {
  outline: 3px solid var(--c-cream);
  outline-offset: 6px;
}

.btn[disabled] {
  opacity: 0.55;
  cursor: not-allowed;
}

/* === Stopka ==============================================
   Identyczna na obu ekranach.
   ========================================================= */
.site-footer {
  position: relative;
  z-index: 3;
  color: var(--text-on-burgundy);
  text-align: center;
}

.site-footer__contact {
  font-size: var(--fs-body);
  line-height: var(--lh-body);
}

.site-footer__contact a {
  text-decoration-color: color-mix(in srgb, currentColor 45%, transparent);
  text-underline-offset: 8px;
}

.site-footer__contact a:hover {
  text-decoration-color: currentColor;
}

.site-footer__names {
  margin-top: var(--sp-footer-names);
  font-size: var(--fs-script-footer);
}

.site-footer__sign {
  margin-top: var(--sp-footer-sign);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
}

/* === Komunikaty formularza =============================== */
/* Dopóki nie ma komunikatu, pole nie rezerwuje miejsca — inaczej
   karta formularza rośnie ponad wysokość z makiety. */
/* Miejsce na komunikat jest zarezerwowane także wtedy, gdy go nie ma.
   Inaczej po nieudanej wysyłce karta rośnie i cała dolna część strony
   — zdjęcie, licznik, stopka — przeskakuje w dół. */
.form-status {
  min-height: 58px;
  margin-top: var(--sp-4);
  font-size: var(--fs-option);
  line-height: var(--lh-body);
  text-align: center;
}

.form-status[data-state='error'] {
  color: var(--c-rose);
}

.form-status[data-state='ok'] {
  color: var(--c-cream);
}

/* Pole-pułapka na boty — musi być zabrane z układu i z czytników. */
.hp-field {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* ============================================
   Mobile — Figma 54:777 (393 px)
   Wymiary przepisane z makiety, nie przeliczone ze skali.
   ============================================ */
@media (max-width: 767px) {
  .arch-panel {
    padding-inline: 0;
  }

  .photo-band {
    width: 100%;
    margin-left: 0;
  }

  .swatch {
    width: 39px;
    height: 34px;
  }

  /* Figma 54:814: pola i pigułki mają 30 px wysokości i obrys 1 px. */
  .field__input {
    height: 30px;
    padding-inline: 16px;
    border-width: 1px;
  }

  .option-pill {
    height: 30px;
    border-width: 1px;
  }

  .btn {
    min-width: 150px;
    height: 30px;
    padding-inline: 24px;
    border-width: 1px;
  }

  /* Dwa wiersze: najdłuższy komunikat łamie się w tej kolumnie na dwa. */
  .form-status {
    min-height: 34px;
    margin-top: 12px;
  }

  /* Figma 54:814: kafelek 31×40, promień 20, jednostka 66 px, odstęp 16 px. */
  .countdown {
    --countdown-gap: 16px;
  }

  .countdown-unit {
    width: 66px;
    gap: 5px;
  }

  .countdown-unit__digits {
    gap: 4px;
  }

  .countdown-unit__digit {
    width: 31px;
    height: 40px;
    font-size: 14px;
    border-radius: 20px;
  }

  .countdown-unit__label {
    font-size: 14px;
  }
}

/* ============================================
   Ekran powitalny — koperta jako przejście
   Nie pętla, tylko jedno wejście: koperta wjeżdża zamknięta, klapka
   odchyla się w tył, spod niej wyjeżdża kartka z imionami, a potem
   kartka przybliża się i wpuszcza gościa na stronę.
   Wszystkie czasy i kąty siedzą w tokens.css.
   ============================================ */
.preloader {
  position: fixed;
  inset: 0;
  z-index: 999;
  display: grid;
  place-items: center;
  background: var(--c-burgundy);
}

.preloader__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding-inline: 24px;
}

/* Proporcje 841 × 1051 z makiety; wnętrze liczone procentowo,
   więc jedna zmiana szerokości skaluje całość. */
.envelope-anim {
  position: relative;
  width: min(var(--env-size), 64vw);
  aspect-ratio: 841 / 1051;
  margin-top: 96px; /* miejsce, w które wyjedzie kartka */
  perspective: var(--env-perspective);
  animation: env-rise var(--env-t-in) var(--ease) both;
}

.envelope-anim__layer {
  position: absolute;
  left: 0;
  display: block;
  width: 100%;
}

.envelope-anim__layer img {
  display: block;
  width: 100%;
  height: 100%;
}

.envelope-anim__back {
  top: 0;
  z-index: 1;
  height: 68.51%; /* 720 / 1051 */
  /* Dopóki koperta jest zamknięta, jej wnętrza nie widać — klapka je
     zakrywa. Odsłania się dokładnie w takt jej podnoszenia. */
  animation: env-reveal var(--env-t-open) var(--ease) calc(var(--env-t-in) + var(--env-t-hold)) both;
}

.envelope-anim__card {
  position: absolute;
  top: 28.83%;  /* 303 / 1051 */
  left: 16.05%; /* 135 / 841 */
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  width: 67.9%;   /* 571 / 841 */
  height: 59.47%; /* 625 / 1051 */
  /* Treść przy górnej krawędzi: po wysunięciu tylko ta część kartki
     wystaje ponad kopertę. */
  padding: 11% 14px 0;
  color: var(--c-burgundy);
  text-align: center;
  background: var(--c-card);
  box-shadow: 0 12px 30px -16px rgba(0, 0, 0, 0.5);
  animation: env-card var(--env-t-slide) var(--ease)
             calc(var(--env-t-in) + var(--env-t-hold) + var(--env-t-open) * var(--env-overlap)) both;
}

.envelope-anim__front {
  top: 40.15%;    /* 422 / 1051 */
  z-index: 3;
  height: 59.85%; /* 629 / 1051 */
}

/* Zamknięta koperta — osobna grafika, nie obrót tyłu. Zajmuje obszar
   przodu i gaśnie dokładnie wtedy, gdy klapka rusza. */
.envelope-anim__closed {
  top: 40.15%;
  z-index: 5;
  height: 59.85%;
  animation: env-fade calc(var(--env-t-open) * 0.2) var(--ease)
             calc(var(--env-t-in) + var(--env-t-hold)) both;
}

/* Klapka to górny fragment grafiki tyłu, przycięty do linii zawiasu.
   Zamknięta jest odchylona o 180°, czyli leży na przodzie koperty —
   przez pierwsze klatki zakrywa ją prawdziwa grafika powyżej. */
.envelope-anim__flap {
  top: 0;
  z-index: 4;
  height: 40.15%;
  overflow: hidden;
  transform-origin: bottom center;
  animation: env-flap var(--env-t-open) var(--ease) calc(var(--env-t-in) + var(--env-t-hold)) both;
}

.envelope-anim__flap img {
  height: 170.63%; /* 720 / 422 — pełna grafika w przyciętym oknie */
}

/* Pieczęć woskowa spina zamkniętą klapkę z korpusem koperty. Leży nad
   wszystkim, bo w zamkniętym stanie jest najbliżej patrzącego, i puszcza
   dokładnie wtedy, gdy klapka rusza.
   Do czasu wgrania pieczęci z Figmy rysuje ją maska serca z Dress Code,
   barwiona kolorem palety — podmiana to zamiana maski na zdjęcie. */
.envelope-anim__seal {
  position: absolute;
  top: var(--env-seal-y);
  left: 50%;
  z-index: 5;
  display: block;
  width: var(--env-seal-size);
  aspect-ratio: 400 / 360;
  background: var(--c-burgundy);
  -webkit-mask: url('../img/swatches/heart.svg') no-repeat center / contain;
  mask: url('../img/swatches/heart.svg') no-repeat center / contain;
  transform: translate(-50%, -50%);
  animation: env-seal calc(var(--env-t-open) * 0.35) var(--ease) calc(var(--env-t-in) + var(--env-t-hold)) both;
}

.envelope-anim__kicker {
  font-family: var(--font-body);
  font-size: 11px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  opacity: 0.75;
}

.envelope-anim__names {
  font-family: var(--font-script);
  font-size: 32px;
  line-height: 1.1;
}

.envelope-anim__date {
  font-family: var(--font-body);
  font-size: 12px;
  letter-spacing: 0.14em;
  opacity: 0.75;
}

/* Pasek pokazuje się dopiero, gdy strona każe na siebie czekać dłużej,
   niż trwa sama choreografia — inaczej tylko rozprasza. */
.preloader__bar {
  width: 180px;
  height: 2px;
  margin-top: 34px;
  overflow: hidden;
  background: color-mix(in srgb, var(--c-cream) 22%, transparent);
  border-radius: 2px;
  opacity: 0;
  transition: opacity 0.4s var(--ease);
}

.preloader[data-waiting] .preloader__bar {
  opacity: 1;
}

.preloader__bar span {
  display: block;
  width: 40%;
  height: 100%;
  background: var(--c-cream);
  border-radius: 2px;
  animation: preloader-sweep 1.4s var(--ease) infinite;
}

/* === Wejście na stronę ===================================
   Kartka przybliża się do gościa i rozpływa, a bordowe tło znika —
   stąd wrażenie, że to ona wpuszcza go do środka.
   ======================================================== */
.preloader[data-done] {
  animation: env-veil var(--env-t-exit) var(--ease) both;
}

.preloader[data-done] .envelope-anim__card {
  animation: env-enter var(--env-t-exit) var(--ease) both;
}

.preloader[data-done] .envelope-anim__back,
.preloader[data-done] .envelope-anim__front,
.preloader[data-done] .envelope-anim__flap,
.preloader[data-done] .preloader__bar {
  animation: env-fade var(--env-t-exit) var(--ease) both;
}

@keyframes env-rise {
  from { transform: translateY(var(--env-rise-from)); opacity: 0; }
  to   { transform: translateY(0);                    opacity: 1; }
}

/* z-index przeskakuje w połowie obrotu: dopóki klapka jest zamknięta,
   leży na przodzie koperty; gdy minie pion, ląduje za nią i przestaje
   zasłaniać wyjeżdżającą kartkę. */
@keyframes env-flap {
  from { transform: rotateX(var(--env-flap-angle)); z-index: 4; }
  49%  { z-index: 4; }
  50%  { z-index: 0; }
  to   { transform: rotateX(0deg); z-index: 0; }
}

/* Przesunięcie w procentach własnej wysokości — kartka wychodzi
   ponad górną krawędź koperty i tam się zatrzymuje. */
@keyframes env-card {
  from { transform: translateY(0);                    opacity: 0; }
  30%  { transform: translateY(0);                    opacity: 1; }
  to   { transform: translateY(calc(-1 * var(--env-card-lift))); opacity: 1; }
}

@keyframes env-enter {
  from {
    transform: translateY(calc(-1 * var(--env-card-lift))) scale(1);
    opacity: 1;
  }
  to {
    transform: translateY(calc(-1 * var(--env-card-lift))) scale(var(--env-exit-scale));
    opacity: 0;
  }
}

/* Wnętrze koperty wychodzi spod podnoszonej klapki. Kadrowanie liczone
   względem samego tyłu: 58,6 % jego wysokości to linia zawiasu. */
@keyframes env-reveal {
  from { clip-path: inset(58.6% 0 0 0); }
  to   { clip-path: inset(0 0 0 0); }
}

/* Wgrana pieczęć rysuje się sama — bez maski i bez barwienia. */
.envelope-anim__seal--art {
  background: none;
  -webkit-mask: none;
  mask: none;
}

.envelope-anim__seal--art img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* Pieczęć puszcza: strzela w górę i rozpływa się, zanim klapka minie pion. */
@keyframes env-seal {
  0%   { transform: translate(-50%, -50%) scale(1);    opacity: 1; }
  45%  { transform: translate(-50%, -58%) scale(1.14); opacity: 1; }
  100% { transform: translate(-50%, -74%) scale(0.86); opacity: 0; }
}

@keyframes env-fade {
  from { opacity: 1; }
  to   { opacity: 0; }
}

@keyframes env-veil {
  from { opacity: 1; visibility: visible; }
  to   { opacity: 0; visibility: hidden; }
}

@keyframes preloader-sweep {
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(250%); }
}

/* Bez ruchu: koperta stoi otwarta z wysuniętą kartką, przejście natychmiastowe. */
@media (prefers-reduced-motion: reduce) {
  .envelope-anim,
  .envelope-anim__flap,
  .envelope-anim__card {
    animation: none;
  }

  .envelope-anim__flap { transform: rotateX(0deg); z-index: 0; }
  .envelope-anim__back { clip-path: none; animation: none; }
  .envelope-anim__seal { display: none; }
  .envelope-anim__card { transform: translateY(calc(-1 * var(--env-card-lift))); }

  .preloader[data-done],
  .preloader[data-done] .envelope-anim__card,
  .preloader[data-done] .envelope-anim__back,
  .preloader[data-done] .envelope-anim__front,
  .preloader[data-done] .envelope-anim__flap {
    animation-duration: 0.2s;
  }
}

@media (max-width: 767px) {
  .envelope-anim { width: min(232px, 62vw); margin-top: 70px; }
  .envelope-anim__card { gap: 6px; padding: 14px 10px; }
  .envelope-anim__names { font-size: 24px; }
  .envelope-anim__kicker, .envelope-anim__date { font-size: 10px; }
  .preloader__bar { width: 140px; margin-top: 26px; }
}

/* ============================================
   Stany zależne od ustawień panelu
   ============================================ */

/* Zastępuje sekcję z kopertą, gdy klient ją wyłączy — bez tego
   goście nie mieliby jak trafić do formularza. */
.rsvp-link {
  position: relative;
  z-index: 5;
  padding: 140px 24px;
  text-align: center;
  background: var(--c-cream);
}

.rsvp-link .btn {
  color: var(--c-cream);
  background: var(--c-burgundy);
  border-color: var(--c-burgundy);
}

.rsvp-link .btn:hover {
  color: var(--c-burgundy);
  background: transparent;
}

/* Pasek nad podglądem nieopublikowanej strony. */
.preview-flag {
  position: sticky;
  top: 0;
  z-index: 1000;
  padding: 10px 16px;
  font-family: var(--font-body);
  font-size: 15px;
  color: var(--c-cream);
  text-align: center;
  background: var(--c-burgundy-soft);
}

@media (max-width: 767px) {
  .rsvp-link {
    padding: 60px 20px;
  }
}
