/* Landing Cuzca: wspólny system ruchu. Kontrakt atrybutów w MOTION.md.
   Zasady: tylko transform i opacity, zero nasłuchu scrolla, jeden ruchomy element naraz,
   ruch wyłącznie pod html.motion-ok (brak reduce-motion i saveData). Bez tej klasy
   strona jest statyczna i kompletna. */

:root {
  --ease-out-quint: cubic-bezier(0.23, 1, 0.32, 1);
  --t-crossfade: 220ms;
  --t-swap: 180ms;
  --t-mask: 520ms;
  --t-entry: 1100ms;
  --tilt-rest: rotateY(-16deg) rotateX(5deg) rotateZ(1deg);
  --story-bg: var(--c-bg);
}

/* ---------- Ziarno (globalne, statyczne) ---------- */
/* Zapieczony kafel PNG zamiast filtra SVG; bez mix-blend, bo na warstwie fixed jest drogi.
   z-index -1: nad tłem płótna, pod każdą sekcją z własnym tłem. */

body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  background: url(/assets/fx/grain.png) repeat;
  background-size: 128px 128px;
  opacity: 0.035;
  pointer-events: none;
}

/* ---------- Pauza poza ekranem ---------- */

[data-pause-offscreen].is-offscreen,
[data-pause-offscreen].is-offscreen::before,
[data-pause-offscreen].is-offscreen::after { animation-play-state: paused !important; }

/* ---------- 1. Reveal ---------- */
/* Wariant IO (Firefox i przeglądarki bez osi widoku) jest w base.css (.is-in).
   Tu: maska nagłówków i wariant sterowany scrollem. */

/* Maska: nagłówek to statyczne okno (overflow: clip), a wewnętrzny <span class="mask-line">
   (dodaje go motion.js) wjeżdża od dołu samym transformem, więc animacja idzie na kompozytorze.
   Padding z ujemnym marginesem daje miejsce na polskie znaki nad wersalikami Bebas (Ś, Ę, Ż)
   bez zmiany układu. IO obserwuje sam nagłówek, który nie jest przycięty. */
html.js-reveal [data-reveal="mask"] {
  opacity: 1;
  transform: none;
  overflow: clip;
  padding-block: 0.14em 0.06em;
  margin-block: -0.14em -0.06em;
}
html.js-reveal [data-reveal="mask"] > .mask-line {
  display: block;
  transform: translateY(110%);
}
html.js-reveal [data-reveal="mask"].is-in > .mask-line {
  transform: none;
  transition: transform var(--t-mask) var(--ease-out-quint);
  transition-delay: calc(var(--i, 0) * 60ms);
}

@supports (animation-timeline: view()) {
  html.js-reveal.motion-ok [data-reveal]:not([data-reveal="mask"]) {
    transition: none;
    animation: cz-rise both cubic-bezier(0.2, 0.7, 0.3, 1);
    animation-timeline: view();
    animation-range: entry 0% entry 35%;
  }
}
@keyframes cz-rise {
  from { opacity: 0; transform: translateY(var(--reveal-y)); }
  to { opacity: 1; transform: none; }
}

/* ---------- 2. Pętle wideo: pierścień postępu w przycisku ---------- */
/* Dwie połówki: każda przycina półokrąg, który obraca się transformem (WAAPI z motion.js,
   zsynchronizowane z currentTime wideo). Zero malowania w trakcie pętli. */

.video-toggle__ring {
  position: absolute;
  inset: -1px;
  border-radius: 50%;
  opacity: 0;
  transition: opacity var(--t-fast) ease;
  pointer-events: none;
}
.video-toggle[data-state="playing"] .video-toggle__ring,
.video-toggle[data-state="paused"] .video-toggle__ring { opacity: 1; }
.video-toggle__half { position: absolute; inset: 0; }
.video-toggle__half--r { clip-path: inset(0 0 0 50%); }
.video-toggle__half--l { clip-path: inset(0 50% 0 0); }
.video-toggle__arc {
  position: absolute;
  inset: 0;
  border: 2px solid var(--c-accent);
  border-radius: 50%;
}
/* Łuk prawej połówki to lewy półokrąg (wjeżdża w prawą połowę przy obrocie 0 -> 180),
   łuk lewej połówki to prawy półokrąg (druga połowa pętli). */
.video-toggle__half--r .video-toggle__arc { clip-path: inset(0 50% 0 0); }
.video-toggle__half--l .video-toggle__arc { clip-path: inset(0 0 0 50%); opacity: 0; }
/* Bez ruchu pierścień nie postępuje, a nieruchome łuki zostawiały ząbki na styku połówek. */
html:not(.motion-ok) .video-toggle__ring { display: none; }

/* ---------- 3. Hero 3D (partial device-loop z tilt="1") ---------- */
/* Warstwy: .device__tilt = spoczynkowe pochylenie i prostowanie osią scrolla;
   .phone = wejście (przejście transform) i pochylenie za kursorem (JS, po wejściu).
   Bez motion-ok telefon stoi płasko. */

.device[data-tilt] { isolation: isolate; }
.device__tilt { grid-area: phone; position: relative; }
.device[data-tilt] .phone { grid-area: auto; }

/* Poświata pod telefonem: gradient, bez filter: blur. */
.device[data-tilt]::before,
.fx-glow::before {
  content: "";
  position: absolute;
  z-index: -1;
  left: -25%;
  right: -25%;
  bottom: 2%;
  height: 22%;
  background: radial-gradient(closest-side, rgba(74, 144, 217, 0.2), rgba(74, 144, 217, 0));
  pointer-events: none;
}
.fx-glow { position: relative; isolation: isolate; }

html.motion-ok .device__tilt {
  transform: perspective(1600px) var(--tilt-rest);
  transform-style: preserve-3d;
}
html.motion-ok .device[data-tilt] .phone {
  transform: rotateY(-16deg) translateY(40px);
  transition: transform var(--t-entry) var(--ease-out);
}
html.motion-ok .device[data-tilt].is-entered .phone { transform: none; }
html.motion-ok .device[data-tilt].is-pointer .phone { transition: none; }

/* Refleks światła nad szkłem: pas chalk 10 %. Poza szkłem w obu skrajnych położeniach
   (-60 % i 60 %), więc skok między wejściem a osią scrolla jest niewidoczny. */
html.motion-ok .device[data-tilt] .phone__screen::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(115deg, rgba(242, 239, 232, 0) 42%, rgba(242, 239, 232, 0.1) 50%, rgba(242, 239, 232, 0) 58%);
  transform: translateX(-60%);
  pointer-events: none;
}
html.motion-ok .device[data-tilt].is-entered .phone__screen::after {
  animation: cz-sheen-in var(--t-entry) var(--ease-out) backwards;
}
@keyframes cz-sheen-in {
  from { translate: 0 0; }
  to { translate: 120% 0; }
}

@supports (animation-timeline: scroll()) {
  html.motion-ok .device__tilt {
    animation: cz-straighten linear both;
    animation-timeline: scroll(root);
    animation-range: 0 70vh;
  }
  html.motion-ok .device[data-tilt].is-entered .phone__screen::after {
    animation:
      cz-sheen-in var(--t-entry) var(--ease-out) backwards,
      cz-sheen-scroll linear both;
    animation-timeline: auto, scroll(root);
    animation-range: normal, 0 70vh;
  }
}
@keyframes cz-straighten {
  from { transform: perspective(1600px) var(--tilt-rest); }
  to { transform: perspective(1600px) rotateY(0deg) rotateX(0deg) rotateZ(0deg) scale(0.94); }
}
@keyframes cz-sheen-scroll {
  from { transform: translateX(-60%); }
  to { transform: translateX(60%); }
}

/* ---------- Plama w tle (ambient) ---------- */
/* Statyczna poświata. Dryf usunięty: na scenie z nagraniem ma się ruszać jedna rzecz. */

.fx-ambient {
  position: absolute;
  z-index: -1;
  top: 8%;
  right: -10%;
  width: min(900px, 120vw);
  aspect-ratio: 1;
  background: radial-gradient(closest-side, rgba(27, 58, 92, 0.55), rgba(27, 58, 92, 0));
  pointer-events: none;
}

/* ---------- 4. Przyklejony telefon (data-story) ---------- */

/* Wariant statyczny: kroki jeden pod drugim, każdy z własnym telefonem. */
.story { display: grid; row-gap: var(--s-16); }
.story__step { display: grid; row-gap: var(--s-8); align-items: center; }
.story__text { display: grid; gap: var(--s-3); max-width: 40ch; }
.story__text p { color: var(--c-text-2); font-size: var(--fs-lead); line-height: 1.55; text-wrap: pretty; }
.story__media { --phone-w: clamp(230px, 64vw, 300px); }
.story__num { font-size: var(--fs-caption); color: var(--c-accent); letter-spacing: var(--tracking-label); }
@media (min-width: 64rem) {
  .story__step { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); column-gap: var(--s-16); }
}

.section--surface .story { --story-bg: var(--c-surface); }

/* Telefon w przyklejonym pasie: szerokość z wysokości pasa (ramka 422 x 868 = 0.486),
   pod ramką do dwóch wierszy podpisu (--band-meta). --band-h = cała wysokość pasa od
   górnej krawędzi sceny. */
html.motion-ok .story {
  grid-template-columns: minmax(0, 1fr);
  row-gap: 0;
  --band-meta: 56px;
  --band-phone-h: calc(54svh - var(--band-meta));
  --band-h: calc(var(--band-phone-h) + var(--band-meta) + var(--s-4));
}
html.motion-ok .story__step { display: contents; }
/* Każdy krok zajmuje dokładnie ekran pod pasem, tekst wyśrodkowany w tym oknie: na ekranie
   jest zawsze jeden krok, bez pustych połówek między krokami. */
html.motion-ok .story__text {
  grid-column: 1;
  grid-row: var(--row);
  align-content: center;
  min-height: calc(100svh - var(--nav-h) - var(--band-h));
  padding-block: var(--s-6);
}
html.motion-ok .story__step:first-child .story__text {
  min-height: calc(100svh - var(--nav-h));
  padding-top: calc(var(--band-h) + var(--s-6));
}
html.motion-ok .story__media {
  grid-column: 1;
  grid-row: 1 / span var(--steps);
  align-self: start;
  justify-self: center;
  position: sticky;
  top: var(--nav-h);
  z-index: 1;
  --phone-w: min(300px, calc(var(--band-phone-h) * 0.486));
  opacity: 0;
  visibility: hidden;
  transform: scale(1.02);
  transition:
    opacity var(--t-crossfade) ease,
    transform 320ms var(--ease-out-quint),
    visibility 0s linear var(--t-crossfade);
}
html.motion-ok .story__step[data-active] .story__media {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition:
    opacity var(--t-crossfade) ease,
    transform 320ms var(--ease-out-quint),
    visibility 0s;
}
/* Pas pod telefonem na mobile: od nagłówka do --band-h, obejmuje ramkę i wiersz podpisu
   z przyciskiem pętli. Tekst kroku chowa się pod nim, nie prześwituje z boków. */
html.motion-ok .story__media::before {
  content: "";
  position: absolute;
  z-index: -1;
  left: 50%;
  width: 100vw;
  top: calc(-1 * var(--s-2));
  height: calc(var(--band-h) + var(--s-2));
  translate: -50% 0;
  background: linear-gradient(to bottom, var(--story-bg) calc(100% - var(--s-3)), rgba(0, 0, 0, 0));
  pointer-events: none;
}
html.motion-ok .story__media { isolation: isolate; }
/* Podpis pod przyklejonym telefonem szerszy niż ramka (do 340 px, wyśrodkowany), żeby
   dłuższe podpisy mieściły się w dwóch wierszach, czyli w pasie (--band-meta). */
@media (max-width: 63.99rem) {
  html.motion-ok .story__media .device__meta {
    grid-column: 1 / -1;
    margin-inline: calc((var(--phone-w) - min(340px, 100vw - 2 * var(--gutter))) / 2);
    justify-content: center;
    text-align: center;
  }
}

@media (min-width: 64rem) {
  html.motion-ok .story {
    grid-template-columns: minmax(0, 4fr) minmax(0, 5fr);
    column-gap: var(--s-12);
  }
  html.motion-ok .story__text {
    min-height: 80vh;
    min-height: 80svh;
    align-content: center;
    padding-block: var(--s-10);
  }
  html.motion-ok .story__step:first-child .story__text { min-height: 80svh; padding-top: var(--s-10); }
  /* Telefon to bohater: do 400 px, wysokość = ekran minus nagłówek i 120 px oddechu,
     stoi bliżej tekstu (justify-self: start) i jest wyśrodkowany w pionie. */
  html.motion-ok .story__media {
    grid-column: 2;
    justify-self: start;
    --phone-w: min(400px, calc((100svh - var(--nav-h) - 120px) * 0.486));
    top: max(calc(var(--nav-h) + 24px), calc(var(--nav-h) + (100svh - var(--nav-h) - var(--phone-w) * 2.057 - 36px) / 2));
  }
  /* Reflektor za aktywnym telefonem zamiast pasa tła, proporcjonalny do telefonu. */
  html.motion-ok .story__media::before {
    left: -55%;
    right: -55%;
    width: auto;
    top: -5%;
    bottom: 5%;
    height: auto;
    translate: none;
    background: radial-gradient(closest-side, rgba(74, 144, 217, 0.12), rgba(74, 144, 217, 0));
  }
}

/* ---------- 5. Liczniki ---------- */

.count { font-variant-numeric: tabular-nums; display: inline-block; text-align: right; }

/* ---------- Reduced motion (dodatkowo do base.css) ---------- */

@media (prefers-reduced-motion: reduce) {
  html.js-reveal [data-reveal="mask"] > .mask-line { transform: none !important; }
}
