/**
 * Postcard — strona główna: jeden ekran ze stosem kart.
 *
 * Karty 2–5 to WARSTWY jednej sceny 1920×1109 na wspólnym pasiastym tle:
 * najgłębiej koperta RSVP z zawieszką i prezentem (eksport ekranu 4),
 * na niej owal planu dnia z talerzem ze sztućcami, wyżej welinowa
 * kartka dress code'u (obie z ekranu 3), na wierzchu bilet z taśmami
 * (ekran 2). Elementy leżą absolutnie w procentach sceny, fonty w cqw
 * względem jej szerokości (1 cqw = 19,2 px przy pełnym rozmiarze).
 * Karty w trybie stosu są przezroczyste, więc głębsze warstwy
 * prześwitują zza wierzchnich dokładnie jak w eksportach.
 *
 * Dwa tryby na tych samych scenach:
 *  — bez JS: karty to zwykłe sekcje jedna pod drugą ze scrollem,
 *    każda na własnych pasach;
 *  — z JS (html.karty): karty to pełnoekranowe warstwy jedna NA
 *    drugiej, scena wyśrodkowana i zmieszczona w viewporcie —
 *    reguły na końcu pliku.
 *
 * Telefon (≤740 px) nie ma eksportów tych ekranów — kompozycje są
 * adaptacją do pionu 393×856: elementy większe i wycentrowane, karty
 * kryjące (bez prześwitywania, które w pionie robiłoby bałagan).
 */

/* === Scena hero ============================================== */

.hero {
  position: relative;
  overflow: hidden;
  aspect-ratio: 1920 / 1109;
  container-type: inline-size;
}

.hero * { position: absolute; }

/* --- Stos pod pocztówką (monitor) --------------------------- */

/* Owalny pasiasty talerz za pocztówką */
.hero__plate {
  left: 45.6%; top: 4.9%; width: 27.6%; height: 86.6%;
  border-radius: 50%;
  background-color: var(--c-stripe);
  background-image: repeating-linear-gradient(90deg,
      var(--c-stripe-dark) 0 1.1cqw, var(--c-stripe) 1.1cqw 2.6cqw);
}
.hero__plate::before {
  content: '';
  position: absolute; inset: 6% 8%;
  border-radius: 50%;
  border: .12cqw solid var(--c-ink);
  background: var(--c-paper);
}

/* Biały pasek papieru u góry */
.hero__sheet-top {
  left: 29.2%; top: 8.4%; width: 21%; height: 7%;
  transform: rotate(-3deg);
}

/* Pozioma taśma filmowa u góry */
.hero__strip-mini {
  left: 32.2%; top: 5.6%; width: 19%; height: 8%;
  transform: rotate(-9deg);
  background: var(--c-ink);
  border-radius: .3cqw;
}
.hero__strip-mini::before,
.hero__strip-mini::after {
  content: '';
  position: absolute; left: 2%; right: 2%; height: 20%;
  background-image: repeating-linear-gradient(90deg,
      var(--c-paper) 0 .78cqw, transparent .78cqw 1.42cqw);
}
.hero__strip-mini::before { top: 8%; }
.hero__strip-mini::after  { bottom: 8%; }

/* Kartka za gwiazdką po lewej */
.hero__sheet-star {
  left: 12.8%; top: 18.5%; width: 5.4%; height: 12.4%;
  transform: rotate(24deg);
}

.hero__star {
  left: 12.4%; top: 18.7%; width: 4.9%;
  transform: rotate(-14deg);
}

/* Koperta i kartka z zagiętym rogiem po prawej */
.hero__envelope {
  left: 64.4%; top: 8.9%; width: 15.7%;
  transform: rotate(-6deg);
}

.hero__sheet-right {
  left: 67.7%; top: 10.1%; width: 12.8%; height: 35.2%;
  transform: rotate(2deg);
}

/* Koronkowy talerzyk wystający zza prawej krawędzi pocztówki */
.hero__lace {
  left: 63.5%; top: 17%; width: 16.5%;
  transform: rotate(-18deg);
}

/* Bilecik-prezent za kwiatem */
.hero__gift {
  left: 79%; top: 52.6%; width: 11.1%;
  color: var(--c-ink);
  transform: rotate(12deg);
}
.hero__gift svg { width: 100%; height: auto; }
.gift-line { fill: var(--c-paper); opacity: .85; }

/* Pionowa taśma filmowa z lewej — klatki wystają pod pocztówką */
.hero__filmA {
  left: 18%; top: 26.5%; width: 19.8%;
  transform: rotate(-8deg);
}

/* Strzępek papieru i ząbkowany skrawek na dole */
.hero__scrap {
  left: 32.6%; top: 82.8%; width: 11%; height: 9.2%;
  transform: rotate(-5deg);
  clip-path: polygon(0 12%, 14% 0, 60% 4%, 100% 0, 97% 55%, 100% 92%,
                     55% 100%, 20% 95%, 0 100%);
}

.hero__scallop {
  left: 33.4%; top: 83.4%; width: 9.2%; height: 7.4%;
  transform: rotate(-8deg);
  background:
    linear-gradient(var(--c-ink), var(--c-ink)) top / 100% 72% no-repeat,
    radial-gradient(circle at 50% 18%, var(--c-ink) 58%, transparent 60%)
      bottom / 1.5cqw 56% repeat-x;
}

/* Kwiat na wierzchu, po prawej */
.hero__flower {
  left: 62.6%; top: 50%; width: 17.4%;
  z-index: 4;
}

/* Spinacz i klamerka nad pocztówką */
.hero__clip {
  left: 25.8%; top: 5.3%; width: 6%;
  z-index: 5;
  transform: rotate(-7deg);
}

.hero__clamp {
  left: 36.05%; top: 2.6%; width: 8.4%;
  z-index: 5;
  transform: rotate(-4deg);
}

/* === Pocztówka =============================================== */

.postcard {
  left: 18.65%; top: 15.15%; width: 56.9%; height: 69.2%;
  z-index: 3;
}

/* Granatowa mata pod pocztówką */
.postcard::before {
  content: '';
  position: absolute; inset: -1.8% -1.4%;
  background: var(--c-ink);
}

.postcard__face {
  position: absolute; inset: 0;
  box-shadow: 0 .3cqw 1.2cqw rgba(0, 0, 0, .18);
}

.postcard__title {
  left: 0; right: 4.5%; top: 7.2%;
  font-size: 1.36cqw;
  letter-spacing: .1em;
  text-align: center;
  /* Tytuł z panelu bywa dłuższy niż projektowy — zawija się zamiast
     wystawać poza pocztówkę. */
  overflow-wrap: break-word;
}

.postcard__divider {
  left: 50.1%; top: 15.9%; height: 80.2%; width: .08cqw;
  background: var(--c-ink);
  opacity: .85;
}

.postcard__message {
  left: 3%; width: 43.5%; top: 23.5%;
  max-height: 54%;
  overflow: hidden;
  font-size: 1.3cqw;
  line-height: 2.24cqw;
  text-align: center;
}

.postcard__stamp {
  left: 75.3%; top: 7.8%; width: 19.2%;
}

/* Linie adresowe po prawej */
.postcard__lines {
  left: 55.6%; width: 37.2%; top: 45%;
}
.postcard__lines * { position: static; }

.postcard__line {
  min-height: 2.3cqw;
  /* Najwyżej dwie linie — trzecia wjeżdżałaby na podpis pary. */
  max-height: 4.2cqw;
  overflow: hidden;
  margin-bottom: .3cqw;
  border-bottom: .08cqw solid var(--c-ink);
  font-size: 1.22cqw;
  line-height: 2cqw;
  text-align: center;
  overflow-wrap: break-word;
}

.postcard__line--blank { min-height: 2.05cqw; margin-bottom: .45cqw; }

.postcard__signature {
  left: 62%; top: 80.4%;
  max-width: 32%;
  font-size: 1.85cqw;
  line-height: 2.15cqw;
  transform: rotate(-4deg);
  white-space: pre-line;
}

/* Polaroid przyklejony taśmą */
.postcard__polaroid {
  left: 12.2%; top: 49.7%; width: 28%;
  z-index: 2;
  padding: 1.15cqw 1.3cqw 0;
  background: var(--c-polaroid);
  box-shadow: 0 .25cqw 1cqw rgba(0, 0, 0, .25);
  transform: rotate(-9deg);
}
.postcard__polaroid * { position: static; }

.postcard__photo {
  aspect-ratio: 285 / 200;
  overflow: hidden;
}
.postcard__photo img { width: 100%; height: 100%; object-fit: cover; }

.postcard__photo-date {
  padding: .45cqw 0 0;
  font-size: 1.15cqw;
  text-align: center;
  color: var(--c-ink);
}

.postcard__rings {
  display: block;
  width: 2.3cqw;
  margin: 0 auto .5cqw;
  color: var(--c-ink);
}
.postcard__rings svg { width: 100%; height: auto; }

.postcard__tape {
  left: 5.8%; top: 43%; width: 14.2%; height: 12.2%;
  z-index: 3;
  transform: rotate(-21deg);
}

/* === Taśma filmowa (komponent) =============================== */
/* Granatowy pas z perforacją i trzema okienkami na zdjęcia. */

.film {
  position: relative;
  width: 100%;
  aspect-ratio: 370 / 790;
  background: color-mix(in srgb, var(--c-ink) 92%, #000);
  border-radius: 1%/0.5%;
  box-shadow: 0 .3cqw 1cqw rgba(0, 0, 0, .3);
}

.film::before,
.film::after {
  content: '';
  position: absolute; top: 1.5%; bottom: 1.5%; width: 7.5%;
  background-image: repeating-linear-gradient(180deg,
      var(--c-paper) 0 2.5%, transparent 2.5% 4.55%);
}
.film::before { left: 4.5%; }
.film::after  { right: 4.5%; }

.film__frames {
  position: absolute; inset: 3.5% 17.5%;
  display: flex;
  flex-direction: column;
  gap: 3.2%;
}

.film__frame {
  position: relative;
  flex: 1;
  overflow: hidden;
}
.film__frame img { width: 100%; height: 100%; object-fit: cover; filter: sepia(.5) contrast(.96); }

/* === Karty i wspólna scena =================================== */
/* Fallback bez JS: sekcje jedna pod drugą, każda na pasach. */

.karta { position: relative; }

/* Scena warstwy: te same proporcje i wyśrodkowanie na wszystkich
   kartach 2–5, żeby elementy głębszych warstw trafiały w te same
   miejsca ekranu co w eksportach. */
.warstwa {
  position: relative;
  margin: 0 auto;
  /* Elementy sceny bywają szersze od niej (bilet na telefonie leży
     w poprzek) — bez ucięcia strona dostawałaby poziomy pasek
     przewijania w trybie bez JS, gdzie karta nie chowa nadmiaru. */
  overflow: hidden;
  width: min(1920px, 100vw);
  aspect-ratio: 1920 / 1109;
  container-type: inline-size;
}

.warstwa > * { position: absolute; }

/* --- Warstwa biletu (eksport ekranu 2) ----------------------- */

/* Kremowy skrawek papieru za biletem — jego róg wystaje między
   taśmą a biletem, reszta chowa się pod nimi. */
.bilet-scrap {
  left: 29.8%; top: 12.6%; width: 20%; height: 38%;
  transform: rotate(-14deg);
  box-shadow: 0 .2cqw .8cqw rgba(0, 0, 0, .25);
}

.bilet-filmA {
  left: 15.9%; top: 18.5%; width: 17.2%;
  z-index: 2;
  transform: rotate(4deg);
}

.bilet-filmB {
  left: 30.6%; top: 10.3%; width: 17.2%;
  z-index: 2;
  transform: rotate(-10deg);
}

/* Klamerka leży w eksporcie ekranu 2 UKOŚNIE — zmierzone z sylwetki
   +27,6° (w hero ta sama klamerka stoi prawie prosto, −4,7°). Przy
   dawnych −3° dolna część uchwytu nie sięgała tam, gdzie w projekcie,
   i to wyglądało na złe proporcje rysunku. */
.bilet-clamp {
  left: 37.07%; top: 1.93%; width: 8.6%;
  z-index: 4;
  transform: rotate(27deg);
}

/* Taśmy na tej karcie mają klatki niemal kwadratowe — proporcje
   z eksportu ekranu 2 (pas 330×800, klatki 250×255). Hero zostaje
   przy swoim wariancie komponentu. */
.warstwa--bilet .film { aspect-ratio: 330 / 800; }
.warstwa--bilet .film::before { left: 2.5%; width: 7%; }
.warstwa--bilet .film::after  { right: 2.5%; width: 7%; }
.warstwa--bilet .film__frames { inset: 2.5% 12%; gap: 1.5%; }

/* Bilet: granatowy podkład + papier z wycięciami na środkach
   krawędzi (wymiary i układ zmierzone z wyprostowanego eksportu:
   papier 1060×562, obrót −25,2°, treść przesunięta w prawo
   względem linii).

   Kształt zmierzony z eksportu ekranu 2 po wyprostowaniu biletu
   (papier przeskalowany do 1059 px szerokości):
     — narożniki to WYCIĘCIA kołowe o promieniu 58 px (5,52% szerokości
       × 10,4% wysokości), a nie ścięte rogi: pomiar profilu krawędzi
       daje x = √(58² − y²) co do piksela;
     — wcięcia na dłuższych krawędziach są trójkątne (boki pod 45°)
       o rozpiętości 780→868 px i głębokości 41 px, ze szpicem
       na 72,9% szerokości — dokładnie nad linią kropek;
     — łuk narożnika składamy z pięciu punktów co 18°.
   Polygon nie umie łuków, więc każde wycięcie to kilka punktów. */
.ticket {
  left: 26.7%; top: 30.2%; width: 55.2%;
  aspect-ratio: 1060 / 562;
  z-index: 3;
  transform: rotate(-25.2deg);
  filter: drop-shadow(0 .4cqw 1.2cqw rgba(0, 0, 0, .35));
}

.ticket__back,
.ticket__body {
  position: absolute;
  clip-path: polygon(
    5.52% 0, 68.8% 0, 72.9% 7.2%, 77% 0, 94.48% 0,
    94.75% 3.21%, 95.53% 6.11%, 96.76% 8.41%, 98.29% 9.89%, 100% 10.4%,
    100% 89.6%,
    98.29% 90.11%, 96.76% 91.59%, 95.53% 93.89%, 94.75% 96.79%, 94.48% 100%,
    77% 100%, 72.9% 92.8%, 68.8% 100%, 5.52% 100%,
    5.25% 96.79%, 4.47% 93.89%, 3.24% 91.59%, 1.71% 90.11%, 0 89.6%,
    0 10.4%,
    1.71% 9.89%, 3.24% 8.41%, 4.47% 6.11%, 5.25% 3.21%);
}

.ticket__back {
  inset: -5.4% -2.8%;
  background: var(--c-ink);
}

.ticket__body { inset: 0; }

/* Ząbki na krótszych krawędziach biletu: półkola WGRYZIONE w papier,
   nie koraliki doklejone z zewnątrz — clip-path rodzica ucina koło
   dokładnie na krawędzi. Z eksportu: rozstaw 48 px, wgryzienie 11 px
   w głąb papieru przy cięciwie 26 px, czyli koło o promieniu 13,2 px
   ze środkiem 2,2 px NA ZEWNĄTRZ krawędzi. Pas zaczyna się tam, gdzie
   kończy wycięcie narożnika (10,4% wysokości) — dziewięć ząbków. */
.ticket__body::before,
.ticket__body::after {
  content: '';
  position: absolute; top: 10.4%; bottom: 10.4%; width: 2.4%;
  background-image: radial-gradient(circle at 50% 50%, var(--c-ink) 48%, transparent 51%);
  background-size: 100% 11.1%;
}
.ticket__body::before { left: -1.4%; }
.ticket__body::after  { right: -1.4%; }

.ticket__main {
  position: absolute; left: 5.7%; top: 18%; width: 57.8%; height: 59%;
  display: flex;
  flex-direction: column;
  align-items: center;
  color: var(--c-ink);
  /* Dłuższe teksty z panelu zawijają się, a nadmiar nie wyjeżdża
     poza papier biletu. */
  overflow: hidden;
}

/* Teksty siedzą w eksporcie odrobinę na prawo od środka linii. */
.ticket__title, .ticket__venue, .ticket__rings, .ticket__names {
  position: relative;
  left: 7.4%;
}

.ticket__rule { width: 100%; border: 0; border-top: .16cqw solid var(--c-ink); margin: .3cqw 0; }

.ticket__title {
  font-size: 1.2cqw;
  letter-spacing: .12em;
  margin-bottom: .3cqw;
}

.ticket__venue {
  font-size: 1.25cqw;
  letter-spacing: .04em;
  margin: .2cqw 0 .3cqw;
}

.ticket__rings {
  width: 4.4cqw;
  margin: 2cqw auto .9cqw;
  color: var(--c-ink);
}
.ticket__rings svg { width: 100%; height: auto; }

.ticket__names {
  font-size: 1.7cqw;
}

.ticket__band {
  display: flex;
  width: 100%;
  margin-top: auto;
  border-top: .1cqw solid var(--c-ink);
  border-bottom: .1cqw solid var(--c-ink);
}

.ticket__band > span {
  flex: 48;
  padding: .55cqw .4cqw;
  font-size: 1.3cqw;
  letter-spacing: .06em;
  text-align: center;
}

.ticket__band > span:first-child { flex: 52; }

.ticket__band > span + span { border-left: .1cqw solid var(--c-ink); }

/* Odcinek biletu z pionowymi napisami */
.ticket__stub {
  position: absolute; left: 71%; top: 11%; width: 24%; height: 81%;
  display: flex;
  justify-content: space-evenly;
  color: var(--c-ink);
}

/* Linia perforacji: osiem kropek średnicy 22,5 px co 58,6 px, kolumna
   na 72,85% szerokości biletu — czyli pod szpicem wcięcia. Wcześniej
   kropki były o połowę mniejsze i o 2% w lewo od wcięcia. */
.ticket__dots {
  position: absolute; left: 1.7%; top: -2.1%; bottom: -0.9%; width: 12%;
  background-image: radial-gradient(circle at 50% 50%, var(--c-ink) 34%, transparent 38%);
  background-size: 100% 12.5%;
  background-repeat: repeat-y;
}

.ticket__stub-title,
.ticket__stub-note {
  writing-mode: vertical-rl;
  text-align: center;
  letter-spacing: .1em;
}

.ticket__stub-title { font-size: 1.05cqw; line-height: 2.2; max-height: 96%; overflow: hidden; }
.ticket__stub-note  { font-size: .9cqw; line-height: 2; max-height: 96%; overflow: hidden; }

/* --- Warstwa dress code'u (lewa część ekranu 3) -------------- */

/* Welinowa kartka: półprzezroczysta biel przepuszcza pasy tła
   i elementy głębszych warstw — wartość krycia zmierzona z eksportu. */
.dress-sheet {
  left: 17.9%; top: 13.4%; width: 28.7%; height: 74.9%;
  transform: rotate(-10.8deg);
  background: rgba(243, 245, 246, .75);
  box-shadow: 0 .3cqw 1.4cqw rgba(0, 0, 0, .18);
  color: var(--c-ink);
}

.dress-sheet > * { position: absolute; }

/* Treść kartki siedzi w eksporcie na prawo od środka arkusza —
   zawieszka z parą zajmuje lewą górną ćwiartkę. */
.dress-sheet__title {
  left: 12%; right: 0; top: 6.5%;
  font-size: 2.4cqw;
  text-align: center;
}

.dress-sheet__text {
  left: 6%; width: 82%; top: 44.2%;
  max-height: 26%;
  overflow: hidden;
  font-size: 1.3cqw;
  line-height: 2.05cqw;
  text-align: center;
  /* Pismo na welinie biegnie w eksporcie odrobinę płycej niż krawędzie
     arkusza (−9° zamiast −10,8°). */
  transform: rotate(1.8deg);
}

.dress-sheet__kisses {
  left: 20.5%; top: 70.7%; width: 75%; height: 12%;
  display: flex;
  align-items: flex-end;
  gap: 2.5%;
}
.dress-sheet__kisses img { width: 23%; height: auto; }

.dress-sheet__note {
  left: 30%; width: 60%; top: 87.5%;
  max-height: 9%;
  overflow: hidden;
  font-size: 1.3cqw;
  text-align: center;
}

/* Welinowa zawieszka z parą tańczącą — wisi w tym samym miejscu,
   co zawieszka z terminem na najgłębszej warstwie, która lekko
   przez nią prześwituje. */
.dress-tag {
  left: 25.8%; top: 11.4%; width: 13.4%;
  z-index: 3;
  transform: rotate(19.5deg);
}
.dress-tag__img { width: 100%; opacity: .92; }

/* Para stoi w eksporcie PROSTO (sylwetka −10,9° do poziomu ekranu),
   choć zawieszka wisi przechylona o 19,5° — stąd obrót przeciwny.
   Bez niego para przechylała się razem z owalem, głowa pana młodego
   wychodziła poza krawędź, a rysunek wypełniał owal inaczej niż
   w projekcie. Sam couple-dance.svg jest eksportem z Figmy 1:1. */
.dress-tag__couple {
  position: absolute;
  left: 13.1%; top: 27.3%; width: 72%;
  color: var(--c-ink);
  transform: rotate(-30.4deg);
}
.dress-tag__couple svg { width: 100%; height: auto; }

/* Kokarda nad prawym górnym rogiem kartki — grafika ma węzeł
   u góry i tasiemki w dół; w eksporcie wisi odbita w poziomie. */
.dress-bow {
  left: 36.8%; top: 3.5%; width: 13.8%;
  aspect-ratio: 275 / 420;
  object-fit: cover;
  object-position: top;
  z-index: 4;
  transform: scaleX(-1);
}

.dress-star {
  left: 12.5%; top: 20.7%; width: 4.9%;
  z-index: 2;
}

/* --- Warstwa planu dnia (prawa część ekranu 3) --------------- */

.plate {
  left: 45.6%; top: 4.9%; width: 29%; height: 85.9%;
  border-radius: 50%;
  background-color: var(--c-stripe);
  background-image: repeating-linear-gradient(90deg,
      var(--c-stripe-dark) 0 1.1cqw, var(--c-stripe) 1.1cqw 2.6cqw);
  box-shadow: 0 .4cqw 1.4cqw rgba(0, 0, 0, .3);
}

.plate__inner {
  position: absolute; inset: 4.7% 8.3%;
  border-radius: 50%;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 14.5% 8% 0;
  /* Owal tnie nadmiar planu dnia zamiast wypuszczać go na pasy. */
  overflow: hidden;
}

.plate__inner::before {
  content: '';
  position: absolute; inset: 4.8% 5.6%;
  border-radius: 50%;
  border: .09cqw solid var(--c-ink);
  box-shadow: 0 0 0 .24cqw var(--c-paper), 0 0 0 .3cqw var(--c-ink);
  pointer-events: none;
}

.plate__title {
  font-size: 2.1cqw;
  line-height: 1.1;
  margin-left: 2%;
}

.plate__couple {
  width: 31%;
  margin: 3.2% auto 2%;
  color: var(--c-ink);
}
.plate__couple svg { width: 100%; height: auto; }

/* Reset marginesów dl/dd — domyślny margines dd zawężał wiersze
   i łamał punkty planu na dwie linie. */
.plate__items {
  display: flex;
  flex-direction: column;
  gap: .6cqw;
  margin: -1.2cqw 0 0;
}

.plate__items dd { margin: 0; }

.plate__time {
  font-size: 1.35cqw;
  letter-spacing: .05em;
  margin-bottom: 1.05cqw;
}

.plate__what {
  font-size: 1.85cqw;
  line-height: 1.2;
}

.plan-emblem {
  left: 68.9%; top: 17.4%; width: 12%;
  z-index: 2;
  transform: rotate(4deg);
  filter: drop-shadow(0 .3cqw .9cqw rgba(0, 0, 0, .4));
}

.plan-star-denim {
  left: 64.5%; top: 67.9%; width: 4.6%;
  z-index: 3;
  transform: rotate(-8deg);
}

.plan-star-metal {
  left: 65.1%; top: 75.7%; width: 4.4%;
  z-index: 3;
  transform: rotate(6deg);
}

/* --- Warstwa koperty RSVP (eksport ekranu 4) ----------------- */
/* --spread: 1 = układ z eksportu (zawieszka obok koperty, prezent
   na jej rogu), 0 = elementy przysunięte na kopertę. spread.js
   przełącza wartość per element po KLIKNIĘCIU; start i stan bez JS
   to 1 — dokładnie eksport ekranu 4. */

.stage--teaser { --spread: 1; }

/* Klikalne elementy sceny: płynny przejazd po kliknięciu. */
.teaser-ruchomy { cursor: pointer; }

@media (prefers-reduced-motion: no-preference) {
  .teaser-tag,
  .teaser-gift {
    transition: transform 0.6s cubic-bezier(0.33, 1, 0.68, 1);
  }
}

.teaser-tag {
  left: 25.8%; top: 11.4%; width: 13.4%;
  z-index: 2;
  transform: translate(calc((1 - var(--spread)) * 29cqw),
                       calc((1 - var(--spread)) * 1cqh)) rotate(19.5deg);
  will-change: transform;
}
.teaser-tag img { width: 100%; }

.teaser-tag__text {
  position: absolute;
  left: 50%; top: 62%;
  width: 170%;
  transform: translate(-50%, -50%) rotate(-95.5deg);
  color: var(--c-ink);
  font-size: 1.7cqw;
  line-height: 2.6cqw;
  text-align: center;
}

.teaser-envelope {
  left: 40.9%; top: 11.3%; width: 39.1%;
  z-index: 1;
  color: inherit;
  text-decoration: none;
  display: block;
  transform: rotate(0deg);
}

.teaser-envelope__img { width: 100%; }

.teaser-envelope__seal {
  position: absolute;
  left: 38.3%; top: 42.5%; width: 20.9%;
}

.teaser-envelope__cta {
  position: absolute;
  left: 5.5%; right: 6.5%; top: 80.1%;
  text-align: center;
  font-size: 2.2cqw;
  color: var(--c-ink);
}

/* Pudełko prezentu jest w eksporcie ekranu 4 przechylone W PRAWO
   (+20,2° zmierzone z dolnej krawędzi pudełka), nie w lewo. Przy −9°
   pętle kokardy siadały niżej i wyglądały na skrócone — sam rysunek
   (gift.svg) jest co do geometrii eksportem z Figmy 1:1. */
.teaser-gift {
  left: 66.97%; top: 48.48%; width: 22.8%;
  z-index: 2;
  transform: translate(calc((1 - var(--spread)) * -14cqw),
                       calc((1 - var(--spread)) * -12cqh)) rotate(20.2deg);
  color: var(--c-ink);
  will-change: transform;
}
.teaser-gift > svg { width: 100%; height: auto; }

/* Napis siedzi w pudełku prezentu: stała wysokość i ucięty nadmiar,
   żeby dłuższy tekst z panelu nie wystawał poza kształt. */
.teaser-gift__text {
  position: absolute;
  left: 23.5%; top: 32%; width: 58%; height: 58%;
  overflow: hidden;
  text-align: center;
  color: var(--c-paper);
  transform: rotate(-4deg);
}

/* Wielkość pisma z eksportu: „Registry” ~23 px, notka ~19 px przy
   interlinii 40 px (mierzone z szerokości wierszy). Przy dawnych
   1,6/1,3 cqw notka łamała się na sześć wierszy zamiast pięciu
   i ostatni („everything to us”) wypadał poza pudełko. */
.teaser-gift__title { font-size: 1.2cqw; margin-bottom: .4cqw; }
.teaser-gift__note  { font-size: 1cqw; line-height: 2.05cqw; }

/* Bazgrołek obrączek na pasach pod zawieszką */
.koperta-rings {
  left: 34.4%; top: 72.6%; width: 2.7%;
  color: var(--c-ink);
  opacity: .8;
}
.koperta-rings svg { width: 100%; height: auto; }

/* === Telefon (≤740 px) ======================================= */
/* Hero wg eksportu 393×856; karty stosu to pionowe adaptacje
   ekranów 2–4 — elementy większe, wycentrowane, karty kryjące. */

@media (max-width: 740px) {

  .hero { aspect-ratio: 393 / 856; }

  /* Stos: na telefonie zostają kartki, klips, spinacz, kokardka,
     gwiazdka, serwetka i skrawek biletu z datą. */
  .hero__plate, .hero__strip-mini, .hero__envelope, .hero__lace,
  .hero__gift, .hero__filmA, .hero__sheet-star { display: none; }

  .hero__sheet-top {
    left: 9%; top: 15.2%; width: 82%; height: 71%;
    transform: rotate(2.5deg);
  }

  .hero__sheet-right {                 /* granatowa podkładka */
    left: 8%; top: 16.8%; width: 84%; height: 71%;
    background: var(--c-ink);
    transform: rotate(-1.5deg);
  }

  .hero__clamp { left: 46%; top: 12%; width: 10.5%; }
  .hero__clip  { left: 64.5%; top: 12.3%; width: 10.5%; }

  .hero__star { left: 8%; top: 80.5%; width: 9%; z-index: 2; }

  .hero__scrap {
    left: 12%; top: 76%; width: 48%; height: 13%;
    transform: rotate(-14deg);
  }

  .hero__scallop {
    left: 58%; top: 76.5%; width: 26%; height: 9%;
    transform: rotate(-16deg);
  }

  /* Serwetka wystająca u dołu */
  .hero__doily { display: block; }

  .postcard { left: 5%; top: 14.7%; width: 86.5%; height: 71%; }
  .postcard::before { inset: -2.2% -2.6%; transform: rotate(2deg); }
  .postcard__face { transform: rotate(-2deg); }

  /* Wnętrze pocztówki — porządek pionowy z eksportu telefonu.
     Elementy siedzą na .postcard__face, więc dziedziczą jej obrót. */
  .postcard__title {
    left: 7%; right: 29%; top: 8.2%;
    font-size: 4.3cqw;
    letter-spacing: .06em;
    text-align: left;
  }

  .postcard__divider { display: none; }

  .postcard__stamp { left: 70%; top: 9.4%; width: 23.5%; }

  /* Blok linii adresowych kończy się tuż nad podpisem — dłuższy tekst
     z panelu jest ucinany, zamiast wjeżdżać podpisowi w wiersze. */
  .postcard__lines {
    left: 14%; width: 55%; top: 17.9%;
    max-height: 24.5cqw;
    overflow: hidden;
  }
  .postcard__line {
    min-height: 8.2cqw; max-height: 15.2cqw; margin-bottom: 1cqw;
    font-size: 4.1cqw; line-height: 7.4cqw;
  }
  .postcard__line--blank { display: none; }

  .postcard__signature {
    left: 19%; top: 34%;
    max-width: 62%;
    font-size: 4.9cqw; line-height: 6cqw;
  }

  .postcard__polaroid { left: 53%; top: 35.4%; width: 42%; padding: 3cqw 3.2cqw 0; transform: rotate(3deg); }
  .postcard__photo { aspect-ratio: 128 / 90; }
  .postcard__photo-date { font-size: 3.2cqw; padding-top: 1.2cqw; }
  .postcard__rings { width: 6.4cqw; margin-bottom: 1.4cqw; }

  .postcard__tape { left: 44%; top: 32.7%; width: 19%; height: 5.5%; transform: rotate(-14deg); }

  .postcard__message {
    left: 8%; width: 86%; top: 63.2%;
    max-height: 34%;
    font-size: 4.15cqw; line-height: 7cqw;
  }

  /* Kwiat na telefonie leży na pocztówce po lewej */
  .hero__flower {
    display: block;
    left: 2.5%; top: 40%; width: 36%;
    z-index: 4;
  }

  /* Karty muszą mieć pełną szerokość, inaczej procentowe sceny
     liczą się od zerowej szerokości elastycznego rodzica i znikają. */
  .talia { display: flex; flex-direction: column; }
  .karta { width: 100%; }

  .warstwa { width: 100vw; aspect-ratio: 393 / 856; }

  /* Bilet STAJE W PIONIE — tak jak w eksporcie mobilnym sekcji 2.
     W poprzek wystawał poza oba brzegi telefonu, pionowe napisy
     odcinka ucinała prawa krawędź, a dolna trzecia część ekranu
     stała pusta. Teraz taśmy z klamerką siedzą w lewym górnym rogu,
     a bilet biegnie ukośnie w dół przez resztę ekranu.
     Skrawek papieru wyglądał w pionie jak zabłąkany kwadrat — znika. */
  .bilet-scrap { display: none; }
  .bilet-filmA { left: -5%; top: 8%; width: 30%; }
  .bilet-filmB { left: 25%; top: 3%; width: 30%; }
  .bilet-clamp { left: 33%; top: 0%; width: 15%; transform: rotate(-4deg); }
  .ticket      { left: -9.3%; top: 48.1%; width: 128%; transform: rotate(-72deg); }

  .ticket__title  { font-size: 3.2cqw; }
  .ticket__venue  { font-size: 3cqw; }
  .ticket__rings  { width: 8cqw; margin: 1.2cqw auto .2cqw; }
  .ticket__names  { font-size: 4.6cqw; margin-bottom: .8cqw; }
  .ticket__rule   { margin: .6cqw 0; }
  .ticket__band   { margin-top: 1.6cqw; }
  .ticket__band > span { padding: 1.4cqw .8cqw; font-size: 2.7cqw; }
  /* Odcinek odsunięty od perforacji; kropki zostają pod szpicem
     wcięcia (72,9% długości biletu) mimo węższego odcinka. */
  .ticket__stub { left: 74%; width: 21%; }
  .ticket__dots { left: -11.2%; }

  /* 2,4 i 2 cqw to na 393 px było 9,4 i 7,9 px — nie do przeczytania.
     Ciaśniejsza interlinia trzyma oba napisy nad linią kropek; przy
     domyślnej 2,2 trzeci wiersz tytułu wchodził na perforację. */
  .ticket__stub-title { font-size: 3cqw; line-height: 1.5; }
  .ticket__stub-note  { font-size: 2.6cqw; line-height: 1.6; }

  /* Dress code: kartka niemal na całą szerokość; zawieszka z parą
     wisi po prawej, żeby nie zasłaniać nagłówka. Kartka sięga niżej
     niż wcześniej — pod nią zostawała pusta ćwiartka ekranu. */
  .dress-sheet { left: 4%; top: 12%; width: 92%; height: 76%; transform: rotate(-6deg); }
  .dress-sheet__title { left: -18%; right: 34%; top: 5%; font-size: 8.5cqw; }
  .dress-sheet__text  { top: 36%; max-height: 30%; font-size: 5cqw; line-height: 8cqw; }
  .dress-sheet__kisses { top: 72%; }
  .dress-sheet__note  { left: 20%; width: 66%; top: 88%; font-size: 4.6cqw; }
  .dress-tag  { left: 45%; top: 2%; width: 36%; }
  .dress-bow  { left: 64%; top: -1%; width: 32%; }
  .dress-star { left: 2%; top: 14%; width: 15%; }

  /* Plan dnia: owal wycentrowany, talerz ze sztućcami pod nim.
     Owal wyższy, talerz i gwiazdki zeszły niżej — dół ekranu był pusty. */
  .plate { left: 6%; top: 7%; width: 88%; height: 76%; }
  .plate__couple { width: 30%; }
  .plate__title { font-size: 6.4cqw; }
  .plate__time  { font-size: 4.2cqw; margin-bottom: 2cqw; }
  .plate__what  { font-size: 5.4cqw; }
  .plate__items { gap: 2.6cqw; margin-top: 0; }
  .plan-emblem { left: 56%; top: 74%; width: 32%; }
  .plan-star-denim { left: 6%; top: 74%; width: 15%; }
  .plan-star-metal { left: 13%; top: 82%; width: 13%; }

  /* Koperta: zawieszka u góry, koperta w środku, prezent na dole.
     Zawieszka wchodziła wcześniej na kopertę, a prezent uciekał poza
     prawą krawędź z uciętą notką — teraz trzy elementy nie zachodzą
     na siebie i wypełniają ekran do dołu. Przesunięcie po kliknięciu
     liczymy w cqw (nie cqh), żeby nie zależało od wysokości okna. */
  .teaser-tag {
    left: 8%; top: 1%; width: 28%;
    transform: translate(calc((1 - var(--spread)) * 24cqw),
                         calc((1 - var(--spread)) * 52cqw)) rotate(14deg);
  }
  .teaser-tag__text { font-size: 4.2cqw; line-height: 6.4cqw; }
  .teaser-envelope { left: 5%; top: 33%; width: 90%; }
  .teaser-envelope__cta { font-size: 6.4cqw; }
  .teaser-gift {
    left: 21%; top: 68.7%; width: 58%;
    transform: translate(calc((1 - var(--spread)) * -8cqw),
                         calc((1 - var(--spread)) * -55cqw)) rotate(20deg);
  }
  .teaser-gift__title { font-size: 4.2cqw; margin-bottom: 1cqw; }
  .teaser-gift__note  { font-size: 2.9cqw; line-height: 4.3cqw; }
  .koperta-rings { left: 6%; top: 63%; width: 10%; }
}

/* Serwetka — widoczna tylko na telefonie */
.hero__doily {
  display: none;
  left: 6%; top: 71%; width: 56%; height: 22%;
  border-radius: 50%;
  background: var(--c-white);
  -webkit-mask: radial-gradient(circle 3.2cqw, #000 97%, transparent) 0 0 / 7cqw 7cqw;
          mask: radial-gradient(circle 3.2cqw, #000 97%, transparent) 0 0 / 7cqw 7cqw;
  transform: rotate(-8deg);
}

/* === Tryb kart (html.karty — klasę dokłada skrypt) =========== */
/* Cała strona to jeden ekran bez scrolla. Karty leżą jedna NA drugiej
   jako pełnoekranowe warstwy; wierzch stosu to pierwsza karta w DOM,
   stąd malejące z-index. Na monitorze karty 2–5 są przezroczyste —
   pasy niesie .talia, a głębsze warstwy prześwitują zza wierzchnich.
   cards.js zdejmuje wierzchnią kartę klasą .karta--zdjeta — grafika
   ODJEŻDŻA W BOK naprzemiennie (nieparzyste w lewo, parzyste w prawo,
   z lekkim obrotem — zaakceptowana próbka mechaniki) — i wraca gestem
   w górę z tej samej strony. */

html.karty body.home-page {
  height: 100dvh;
  overflow: hidden;
}

html.karty .talia {
  position: fixed;
  inset: 0;
  display: block;
  height: 100dvh;
  overflow: hidden;
}

html.karty .karta {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  overflow: hidden;
  margin: 0;
  padding: 0;
}

/* Na monitorze karty stosu nie zasłaniają głębszych warstw —
   kryje tylko hero (wierzch talii). Telefon zostaje przy kartach
   kryjących: pionowe kompozycje nakładałyby się nieczytelnie. */
@media (min-width: 741px) {
  html.karty .karta:not(.karta--hero) { background: none; }
}

html.karty .karta--hero    { z-index: 50; }
html.karty .karta--bilet   { z-index: 40; }
html.karty .karta--dress   { z-index: 30; }
html.karty .karta--plan    { z-index: 20; }
html.karty .karta--koperta { z-index: 10; }

html.karty .karta--zdjeta {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}

html.karty .karta:nth-child(odd).karta--zdjeta {
  transform: translateX(-115%) rotate(-7deg);
}

html.karty .karta:nth-child(even).karta--zdjeta {
  transform: translateX(115%) rotate(7deg);
}

@media (prefers-reduced-motion: no-preference) {
  html.karty .karta {
    transition: opacity .7s ease, transform .7s ease, visibility 0s;
  }
  /* Zdjęta karta znika z drzewa dostępności dopiero PO rozpłynięciu. */
  html.karty .karta--zdjeta {
    transition: opacity .7s ease, transform .7s ease, visibility 0s .7s;
  }
}

/* ?karta=N — zrzuty ekranu dostają stan bez animacji. */
html.karty .talia--skok .karta { transition: none !important; }

/* Sceny mieszczą się w viewporcie W CAŁOŚCI: szerokość ogranicza
   i okno, i wysokość ekranu przeliczona proporcjami eksportu.
   Wszystkie karty stosu używają tej samej formuły, żeby warstwy
   celowały w te same piksele. */

html.karty .hero {
  width: min(100vw, calc(100dvh * 1920 / 1109));
  background: none;
}

html.karty .warstwa { width: min(100vw, calc(100dvh * 1920 / 1109)); }

@media (max-width: 740px) {
  html.karty .hero    { width: min(100vw, calc(100dvh * 393 / 856)); }
  html.karty .warstwa { width: min(100vw, calc(100dvh * 393 / 856)); }
}
