/* ── GALERIA STRONY PRODUKTOWEJ: mobilna karuzela + FILM HERO ───────────────
   Wspólny plik dla wszystkich stron produktowych (modules/*.html + _pg-template).
   Na mobile, gdy w galerii jest WIĘCEJ NIŻ JEDNA grafika, pg-gallery.js dokłada
   `.is-carousel` na `.gallery` i owija ją w `.gallery-frame`. Wtedy galeria staje
   się poziomą karuzelą (swipe, snap), a w prawym dolnym rogu leci licznik „1 z N".
   Reguły są celowo o wyższej specyficzności (.gallery.is-carousel ...) niż inline
   `.gallery` / `.gallery-item` w stronach, więc wygrywają niezależnie od kolejności.
   Desktop i pojedyncza grafika: JS nic nie robi, wygląd bez zmian.
   FILM HERO (sekcja na dole pliku): gdy galeria z admina ma ≥3 grafiki,
   pg-gallery.js przełącza .product-hero w pełnoszeroki pasek zdjęć z rack
   focusem (klasa .is-film) — style też tu, żeby działały na każdej stronie. */

.gallery-counter { display: none; }

/* Grafiki galerii pełny kontrast OD RAZU (nie tylko po hoverze). Strony mają
   inline `.gallery-item img { opacity: .85 }`, co na desktopie wygląda jak „nic
   załadowane" / wyszarzenie; na mobile karuzela i tak dawała opacity 1. Wyższa
   specyficzność (.gallery .gallery-item img) wygrywa niezależnie od kolejności. */
.gallery .gallery-item img { opacity: 1; }

/* Wpis wideo (Bunny Stream) w kaflu galerii: wypełnia kadr jak grafika
   (strony stylują inline tylko `.gallery-item img`, więc video ma bazę tu). */
.gallery .gallery-item video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Klatki EXTRA w trybie film hero: wiersze po 3 kafle 1×1, a niepełny wiersz
   domyka SZEROKI kadr o wysokości kafla (reszta 1 → panorama 3×1, reszta 2 →
   1×1 + 2×1). Cover kadruje panoramę z pełnej grafiki. Karuzela mobile ma
   własną geometrię, więc spany jej nie dotyczą (:not(.is-carousel)). */
.gallery:not(.is-carousel) .gallery-item.gitem-w2 {
  grid-column: span 2;
  aspect-ratio: 2 / 1;
  padding: 0;
}
.gallery:not(.is-carousel) .gallery-item.gitem-w3 {
  grid-column: span 3;
  aspect-ratio: 3 / 1;
  padding: 0;
}
.gallery:not(.is-carousel) .gitem-w2 img,
.gallery:not(.is-carousel) .gitem-w3 img,
.gallery:not(.is-carousel) .gitem-w2 video,
.gallery:not(.is-carousel) .gitem-w3 video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* ── LIGHTBOX (powiększenie na pełny ekran) ──────────────────────────────────
   Sekcja .gallery otwiera go TYLKO na desktopie (guard w JS; na mobile jest
   karuzela). Kadry FILM HERO otwierają go wszędzie: klik/tap w OSTRY kadr =
   powiększenie (na dotyku pinch-zoom + przesuwanie, double-tap = zbliżenie,
   tap = zamknij). Klik w margines wokół obrazu (albo Esc) zamyka; na desktopie
   klik w sam obraz nie zamyka. Kadr wideo powiększa się jako <video> (dalej
   autoplay + muted + loop). */
@media (min-width: 901px) {
  .gallery .gallery-item { cursor: zoom-in; }
}
.pg-lightbox {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 8vh 9vw;                 /* margines wokół obrazu = strefa klik-zamknij */
  background: rgba(0, 0, 0, 0.82);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  cursor: zoom-out;
  opacity: 0;
  transition: opacity 0.18s ease;
  touch-action: none;               /* pinch/pan obsługuje JS, nie przeglądarka */
  overscroll-behavior: contain;
}
.pg-lightbox.is-open { opacity: 1; }
.pg-lightbox img,
.pg-lightbox video {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  border-radius: 16px;
  /* Rendery PNG/WebP mają przezroczyste tło — bez wypełnienia „pływają" na
     rozmytym backdropie. Dajemy tę samą powierzchnię co kafel galerii (--bg-alt),
     więc wyglądają jak w gridzie; dla zwykłych zdjęć (nieprzezroczystych) tło
     jest niewidoczne. */
  background: var(--bg-alt, #111);
  box-shadow: 0 30px 90px rgba(0, 0, 0, 0.5);
  cursor: default;                  /* klik na obraz nie zamyka (desktop) */
  transform-origin: center center;
  will-change: transform;
}
@media (max-width: 900px) {
  .pg-lightbox { padding: 4vh 4vw; }
}

@media (max-width: 900px) {
  .gallery.is-carousel {
    display: flex;
    flex-wrap: nowrap;
    gap: 0;
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .gallery.is-carousel::-webkit-scrollbar { display: none; }

  .gallery.is-carousel .gallery-item {
    flex: 0 0 100%;
    width: 100%;
    max-width: 100%;
    aspect-ratio: 1;
    padding: 0;
    scroll-snap-align: center;
  }
  .gallery.is-carousel .gallery-item img,
  .gallery.is-carousel .gallery-item video {
    width: 100%;
    height: 100%;
    object-fit: cover;
    opacity: 1;
  }

  /* Pojedynczy kafel wideo poza karuzelą (np. jedna pozycja 4+) na stronie
     ręcznej: kontener na mobile nie ma aspect-ratio, więc wideo trzyma własne
     proporcje z metadanych. Na pg- (.gallery-photos) kafel ma aspect 1 = cover. */
  .gallery:not(.is-carousel):not(.gallery-photos) .gallery-item video { height: auto; }

  /* Pojedyncza wgrana grafika (galeria zdjęć z admina, bez karuzeli) też
     wypełnia kadr z kadrowaniem, zamiast małego obrazka z paddingiem.
     Statyczne pojedyncze rendery 3D (.gallery bez .gallery-photos) zostają. */
  .gallery-photos .gallery-item {
    aspect-ratio: 1;
    padding: 0;
  }
  .gallery-photos .gallery-item img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    opacity: 1;
  }

  /* Ramka (owijka z JS) pozycjonuje licznik nad karuzelą, poza scrollem,
     więc „1 z N" siedzi w rogu i nie przewija się razem z kadrami. */
  .gallery-frame.is-active { position: relative; }
  .gallery-frame.is-active .gallery-counter {
    display: block;
    position: absolute;
    left: 12px;
    bottom: 12px;
    padding: 4px 11px;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 1px;
    line-height: 1;
    color: #fff;
    background: rgba(0, 0, 0, 0.55);
    border-radius: 999px;
    pointer-events: none;
    z-index: 3;
    -webkit-backdrop-filter: blur(4px);
    backdrop-filter: blur(4px);
  }
}

/* ── TYPOGRAFIA (wszystkie product pages — ten plik ładują tylko one) ────────
   Nagłówki: text-wrap balance = linie łamane po równo (pierwsza nie dłuższa
   od drugiej), więc żadnych wdów typu samotne „biurka." w drugiej linii.
   Akapity: pretty = zakaz pojedynczego słowa w ostatniej linii akapitu.
   Natywne CSS, zero JS; na jednolinijkowych tekstach nic nie zmienia. */
h1, h2, h3 { text-wrap: balance; }
p { text-wrap: pretty; }

/* ── FILM HERO: pełnoszeroki pasek zdjęć z rack focusem ──────────────────────
   pg-gallery.js buduje .phero-media (pasek) jako pierwsze dziecko .product-hero
   i dokłada .is-film na sekcję, gdy galeria z admina ma ≥3 grafiki. Aktywny kadr
   jest ostry, pozostałe dostają warstwę .phero-blur (ten sam obraz, stały CSS
   blur) — „rack focus" to wyłącznie crossfade opacity, więc animacja nie liczy
   blura per klatka i jest płynna też na iOS. Panel zakupowy (.product-hero-info)
   zostaje w markupie tam gdzie był: na desktopie CSS kładzie go NA zdjęciach
   (biały tekst + scrim od prawej), na mobile spływa pod pasek w normalnym flow.
   Specyficzność .product-hero.is-film celowo bije inline `.product-hero` stron.
   Brak ≥3 grafik / błąd JS = klasy nie ma i strona wygląda dokładnie jak dotąd. */

.product-hero.is-film {
  display: block;
  position: relative;
  padding: 0;
  margin-top: 48px;              /* topbar (fixed 48px) */
  min-height: 0;
  animation: pheroIn 0.45s ease both;   /* maskuje przełączenie layoutu po fetchu */
}
@keyframes pheroIn { from { opacity: 0; } to { opacity: 1; } }
.product-hero.is-film .product-hero-img { display: none; }

.phero-media {
  position: relative;
  /* wysokość sprzężona też z SZEROKOŚCIĄ okna (48vw): kwadratowy kadr przy
     anchorze 12vw kończy się na 60vw — 4vw oddechu do panelu (64vw), a szersze
     kadry odpływają w tilt-shift (pasy od 58vw) zanim dojdą do tekstu; kompozycja
     kadr|panel trzyma się od MacBooka po szeroki monitor */
  height: clamp(520px, min(calc(100svh - 128px), 48vw), 840px);
  background: #0a0a0a;           /* „łoże" paska: celowo ciemne w obu motywach */
  overflow: hidden;
  touch-action: pan-y;           /* pionowy scroll zostaje przy przeglądarce */
  cursor: grab;
  outline: none;
  user-select: none;
  -webkit-user-select: none;
}
/* Szkielet zapieczony w HTML (zero flasha): .phero-boot to puste .phero-media
   (ciemne łoże + wysokości wyżej/niżej działają 1:1), które JS podmienia na
   prawdziwy pasek albo usuwa przy odwrocie do klasycznego layoutu. Dopóki
   szkielet żyje (decyzja w toku), seedowa galeria z HTML nie może mignąć
   starym układem pod paskiem — hydrate zaraz ją przepisze albo odsłoni. */
.phero-boot { cursor: default; }
.product-hero:has(.phero-boot) ~ .gallery:not(.gallery-photos) { opacity: 0 !important; }

.phero-media.is-drag { cursor: grabbing; }
.phero-slide.is-focus { cursor: zoom-in; }   /* klik w ostry kadr = powiększenie */
.phero-media:focus-visible { outline: 2px solid var(--accent, #e85d04); outline-offset: -2px; }

.phero-track {
  display: flex;
  align-items: stretch;
  gap: 0;                        /* kadry stykają się: szew robi wyłącznie edge-blur */
  height: 100%;
  width: max-content;
  opacity: 0;
  transition: transform 0.72s cubic-bezier(0.16, 0.84, 0.24, 1), opacity 0.7s ease;
  will-change: transform;
}
.phero-media.is-ready .phero-track { opacity: 1; }
.phero-media.is-drag .phero-track { transition: none; }

.phero-slide {
  position: relative;
  flex: 0 0 auto;
  height: 100%;
  min-width: 60px;               /* bezpiecznik na niezaładowany obraz */
  margin: 0;
  overflow: hidden;              /* przycina rozjechane krawędzie warstwy blur */
  background: #101010;
}
.phero-slide img,
.phero-slide video {
  display: block;
  height: 100%;
  width: auto;
  max-width: 92vw;               /* bardzo szerokie kadry: cover zamiast 100vw+ */
  object-fit: cover;
  -webkit-user-drag: none;
}
.phero-blur {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scale(1.055);       /* chowa miękki brzeg blura + „focus breathing" */
  /* czysty OPTYCZNY defocus: bez przyciemniania (brightness brudził jasne
     fotografie), lekki saturate/contrast trzyma „bloom" świateł jak w szkle */
  filter: blur(22px) saturate(1.04) contrast(1.02);
  opacity: 1;
  transition: opacity 0.55s cubic-bezier(0.33, 0.02, 0.2, 1),
              transform 0.72s cubic-bezier(0.16, 0.84, 0.24, 1);
  pointer-events: none;
}
.phero-slide.is-focus .phero-blur { opacity: 0; transform: scale(1); }
.phero-media.is-drag .phero-blur { transition: none; }  /* w dragu opacity liczy JS per klatka */

/* Łączenia kadrów = głębia ostrości, nie cień: każdy kadr ma STAŁĄ, wąską
   strefę rozmycia przy lewej i prawej krawędzi (.phero-edge: rozmyta kopia
   z maską brzegową). UWAGA: to jest FALLBACK dla przeglądarek bez
   backdrop-filter — tam gdzie działa, pasek używa ciągłej optyki .phero-dof
   (niżej), a te warstwy są wyłączone. */
.phero-edge {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scale(1.055);
  filter: blur(16px) saturate(1.04);
  pointer-events: none;
  -webkit-mask-image: linear-gradient(90deg,
    #000 0, transparent clamp(30px, 4vw, 64px),
    transparent calc(100% - clamp(30px, 4vw, 64px)), #000 100%);
  mask-image: linear-gradient(90deg,
    #000 0, transparent clamp(30px, 4vw, 64px),
    transparent calc(100% - clamp(30px, 4vw, 64px)), #000 100%);
}

/* ── TILT-SHIFT: ciągła płaszczyzna ostrości na CAŁYM pasku ──────────────────
   Nad trackiem leży stała „optyka": pasy progressive backdrop-blur z maskami
   gradientowymi. Ostrość spada CIĄGLE od strefy aktywnego kadru ku bokom,
   PRZEZ kadry i ich łączenia (zero odcięcia blura na styku), a przesuwanie
   paska robi rack focus piksel po pikselu, jak w obiektywie. Strefa ostra
   pokrywa się z kompozycją: anchor 12vw → prawa burta rozmycia rusza od 58vw
   (overlay; panel na 64vw — szeroki kadr odpływa w blur ZANIM dojdzie do
   tekstu); w stacku 6vw → 90vw. Kadry, które wystają poza strefę (16:9),
   miękko odpływają w rozmycie pod scrimem — jak głębia ostrości w makro. */
.phero-dof {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  display: none;                   /* włącza się tylko przy wsparciu backdrop-filter */
}
.phero-dof i { position: absolute; top: 0; bottom: 0; }
@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .phero-dof { display: block; }
  /* ciągła optyka zastępuje warstwy per-kadr (specyficzność > .phero-slide img) */
  .phero-slide .phero-blur,
  .phero-slide .phero-edge { display: none; }
}

/* Overlay (≥1101px): lewa burta 3 pasy, prawa 5 — progresja jak spadek
   ostrości w szkle (2 → 5 → 9 → 14 → 20px), feathery masek się nakładają. */
@media (min-width: 1101px) {
  /* ── ARCHITEKTURA KUMULATYWNA (fix „szczelin ostrości" między pasami) ──
     Pasy NIE robią crossfade'u (fade-out obok fade-in = oba półprzezroczyste
     = prześwituje OSTRY oryginał jako pionowa szczelina). Zamiast tego każdy
     pas: feather wejściowy → #000 aż POD pełne krycie następnego pasa. Backdrop
     późniejszego pasa zawiera output wcześniejszych, więc rozmycia SKŁADAJĄ się
     (sigma_total = sqrt(sum sigma^2)) — wartości blur to DELTY, nie cele:
     prawa burta 2/4.5/7.5/10.5/14.5 daje efektywnie ~2/5/9/14/20. Rampa
     saturate/brightness/contrast też w DELTACH (mnoży się między pasami).
     Twarda krawędź końca słabszego pasa ginie pod pełnym kryciem mocniejszego.
     NIE wracać do masek gasnących z obu stron. Lewa burta do anchora 12vw. */
  .phero-dof i:nth-child(1) { left: 0; width: 12vw;
    -webkit-backdrop-filter: blur(4px) saturate(1.05);
            backdrop-filter: blur(4px) saturate(1.05);
    -webkit-mask-image: linear-gradient(90deg, #000 0, #000 75%, transparent 100%);
            mask-image: linear-gradient(90deg, #000 0, #000 75%, transparent 100%); }
  .phero-dof i:nth-child(2) { left: 0; width: 8vw;
    -webkit-backdrop-filter: blur(8px) saturate(1.03) brightness(1.02) contrast(1.03);
            backdrop-filter: blur(8px) saturate(1.03) brightness(1.02) contrast(1.03);
    -webkit-mask-image: linear-gradient(90deg, #000 0, #000 62%, transparent 100%);
            mask-image: linear-gradient(90deg, #000 0, #000 62%, transparent 100%); }
  .phero-dof i:nth-child(3) { left: 0; width: 4.5vw;
    -webkit-backdrop-filter: blur(16px) saturate(1.03) brightness(1.01) contrast(1.02);
            backdrop-filter: blur(16px) saturate(1.03) brightness(1.01) contrast(1.02);
    -webkit-mask-image: linear-gradient(90deg, #000 0, #000 55%, transparent 100%);
            mask-image: linear-gradient(90deg, #000 0, #000 55%, transparent 100%); }
  /* prawa burta rusza od 58vw (szeroki kadr odpływa w blur przed panelem 64vw) */
  .phero-dof i:nth-child(4) { left: 58vw; width: 10vw;
    -webkit-backdrop-filter: blur(2px) saturate(1.04);
            backdrop-filter: blur(2px) saturate(1.04);
    -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 30%, #000 100%);
            mask-image: linear-gradient(90deg, transparent 0, #000 30%, #000 100%); }
  .phero-dof i:nth-child(5) { left: 63vw; width: 13vw;
    -webkit-backdrop-filter: blur(4.5px) saturate(1.02) contrast(1.02);
            backdrop-filter: blur(4.5px) saturate(1.02) contrast(1.02);
    -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 31%, #000 100%);
            mask-image: linear-gradient(90deg, transparent 0, #000 31%, #000 100%); }
  .phero-dof i:nth-child(6) { left: 70vw; width: 16vw;
    -webkit-backdrop-filter: blur(7.5px) saturate(1.02) brightness(1.02) contrast(1.01);
            backdrop-filter: blur(7.5px) saturate(1.02) brightness(1.02) contrast(1.01);
    -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 31%, #000 100%);
            mask-image: linear-gradient(90deg, transparent 0, #000 31%, #000 100%); }
  .phero-dof i:nth-child(7) { left: 79vw; width: 17vw;
    -webkit-backdrop-filter: blur(10.5px) saturate(1.02) brightness(1.01) contrast(1.02);
            backdrop-filter: blur(10.5px) saturate(1.02) brightness(1.01) contrast(1.02);
    -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 35%, #000 100%);
            mask-image: linear-gradient(90deg, transparent 0, #000 35%, #000 100%); }
  .phero-dof i:nth-child(8) { left: 89vw; width: 11vw;
    -webkit-backdrop-filter: blur(14.5px) saturate(1.02) brightness(1.01) contrast(1.01);
            backdrop-filter: blur(14.5px) saturate(1.02) brightness(1.01) contrast(1.01);
    -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 55%, #000 100%);
            mask-image: linear-gradient(90deg, transparent 0, #000 55%, #000 100%); }
}

/* Stack (≤1100px): kadr zajmuje niemal całą szerokość — optyka tylko przy
   skrajach (peeki sąsiadów), 5 pasów, reszta wyłączona. */
@media (max-width: 1100px) {
  /* Kumulatywnie jak w overlay (blur = DELTY, maski #000 do końca pasa):
     lewa burta efektywnie ~12px przy krawędzi, prawa ~19px. */
  .phero-dof i:nth-child(1) { left: 0; width: 7vw;
    -webkit-backdrop-filter: blur(5px) saturate(1.05);
            backdrop-filter: blur(5px) saturate(1.05);
    -webkit-mask-image: linear-gradient(90deg, #000 0, #000 57%, transparent 100%);
            mask-image: linear-gradient(90deg, #000 0, #000 57%, transparent 100%); }
  .phero-dof i:nth-child(2) { left: 0; width: 4vw;
    -webkit-backdrop-filter: blur(11px) saturate(1.04) brightness(1.02) contrast(1.04);
            backdrop-filter: blur(11px) saturate(1.04) brightness(1.02) contrast(1.04);
    -webkit-mask-image: linear-gradient(90deg, #000 0, #000 50%, transparent 100%);
            mask-image: linear-gradient(90deg, #000 0, #000 50%, transparent 100%); }
  .phero-dof i:nth-child(3) { left: 88vw; width: 12vw;
    -webkit-backdrop-filter: blur(4px) saturate(1.05);
            backdrop-filter: blur(4px) saturate(1.05);
    -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 33%, #000 100%);
            mask-image: linear-gradient(90deg, transparent 0, #000 33%, #000 100%); }
  .phero-dof i:nth-child(4) { left: 92vw; width: 8vw;
    -webkit-backdrop-filter: blur(11px) saturate(1.04) brightness(1.02) contrast(1.04);
            backdrop-filter: blur(11px) saturate(1.04) brightness(1.02) contrast(1.04);
    -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 62%, #000 100%);
            mask-image: linear-gradient(90deg, transparent 0, #000 62%, #000 100%); }
  .phero-dof i:nth-child(5) { left: 96vw; width: 4vw;
    -webkit-backdrop-filter: blur(15px) saturate(1.03) brightness(1.02) contrast(1.02);
            backdrop-filter: blur(15px) saturate(1.03) brightness(1.02) contrast(1.02);
    -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 87%, #000 100%);
            mask-image: linear-gradient(90deg, transparent 0, #000 87%, #000 100%); }
  .phero-dof i:nth-child(6),
  .phero-dof i:nth-child(7),
  .phero-dof i:nth-child(8) { display: none; }
}

/* Scrim pod białym panelem zakupowym: wachlowany gradient od prawej. */
.phero-scrim {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background: linear-gradient(90deg,
    rgba(10, 10, 10, 0) 42%,
    rgba(10, 10, 10, 0.34) 64%,
    rgba(10, 10, 10, 0.78) 100%);
}

.phero-counter {
  position: absolute;
  left: 26px;
  bottom: 22px;
  z-index: 2;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 2px;
  color: rgba(255, 255, 255, 0.82);
  font-variant-numeric: tabular-nums;
  text-shadow: 0 1px 12px rgba(0, 0, 0, 0.5);
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.7s ease 0.15s;
}
.phero-media.is-ready .phero-counter { opacity: 1; }

/* Wyłączenie animacji przy prefers-reduced-motion (JS dokłada .is-reduced). */
.phero-media.is-reduced .phero-track,
.phero-media.is-reduced .phero-blur { transition-duration: 0.01s !important; }
.phero-no-anim, .phero-no-anim * { transition: none !important; }

/* ── P3D: MEGA model 3D wtopiony w końcową sekcję CTA (styl BASE) ────────────
   Gdy film hero zabiera modelowi nagłówek, pg-gallery.js przenosi żywy
   .hero-stage do .product-cta-section jako WIELKIE tło pod treścią „Zbuduj
   swój habitat": model wystaje poza kadr (overflow hidden), płynie parallaxem
   ze scrollem (transform na .p3d-wrap, nie na stage'u — clientWidth canvasa
   stały, viewer nie przelicza) i pozostaje interaktywny (hover / tap / swatch).
   Żadnej osobnej sekcji = zero pustego scrolla pod specyfikacją. */
.product-cta-section.has-p3d {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  min-height: min(68svh, 700px);   /* było 112svh: luft nad CTA ścięty ponad 2× */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
.product-cta-section.has-p3d > :not(.p3d-bg) {
  position: relative;
  z-index: 2;
}
.p3d-bg {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;                   /* interaktywny jest sam stage */
}
.p3d-wrap { will-change: transform; pointer-events: none; }
.p3d-bg .hero-stage {
  width: clamp(720px, 100vw, 1400px);     /* MEGA: szerokość okna, przycięty sekcją */
  max-width: none;                        /* bije inline max-width 480px / 34vh */
  pointer-events: auto;
  flex: 0 0 auto;
}
/* Strony stylują fallback PNG selektorami scoped do .product-hero-img
   (picture absolute + img 100%). Po przeprowadzce stage'a te reguły przestają
   łapać i PNG w flow rozpycha stage — odtwarzamy je w kontekście .p3d-bg. */
.p3d-bg .hero-stage picture {
  position: absolute;
  inset: 0;
  display: block;
}
.p3d-bg .hero-stage picture img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  filter: drop-shadow(0 20px 60px rgba(0, 0, 0, 0.3));
}
@media (prefers-color-scheme: light) {
  .p3d-bg .hero-stage picture img { filter: drop-shadow(0 20px 60px rgba(0, 0, 0, 0.1)); }
}
@media (max-width: 900px) {
  .product-cta-section.has-p3d { min-height: 62svh; }
  .p3d-bg .hero-stage { width: 150vw; }
}

/* Overlay (laptop / iPad landscape, ≥1101px): panel zakupowy NA zdjęciach,
   pozycjonowany PROPORCJONALNIE (left 63vw), nie od prawej burty — na każdej
   szerokości trzyma tę samą kompozycję względem paska i aktywnego kadru.
   Nadpisane zmienne motywu działają na wszystkie kontrolki panelu. */
@media (min-width: 1101px) {
  .product-hero.is-film .product-hero-info {
    position: absolute;
    top: 0;
    bottom: 0;
    /* 64vw (było 63): minimalny oddech od ostrego kadru (anchor 12vw), panel
       dalej NIE klejony do prawej burty (cap 440px od krawędzi). */
    left: min(64vw, calc(100vw - 440px));
    z-index: 3;
    display: flex;
    flex-direction: column;
    justify-content: center;
    width: min(400px, 34vw);
    max-width: none;
    pointer-events: none;          /* pusta przestrzeń nad/pod panelem = drag paska */
    color: #fff;                   /* baza dziedziczenia: H1 i spółka nie deklarują color */
    --text-primary: #fff;
    --text-secondary: rgba(255, 255, 255, 0.75);
    --text-ghost: rgba(255, 255, 255, 0.48);
    --border-mid: rgba(255, 255, 255, 0.34);
    --card-hover: rgba(255, 255, 255, 0.1);
    --bg: #0a0a0a;                 /* .product-cta: biały przycisk, ciemny tekst */
  }
  .product-hero.is-film .product-hero-info > * { pointer-events: auto; }
}

/* Stack (iPad portrait / okno w połowie ekranu / telefon, ≤1100px): pasek pełną
   szerokością u góry, panel POD nim, WYŚRODKOWANY jako blok (nie klejony do
   lewej krawędzi okna) i w kolorach motywu strony. */
@media (max-width: 1100px) {
  .phero-scrim { display: none; }
  .phero-counter { left: 16px; bottom: 14px; }
  .product-hero.is-film .product-hero-info {
    order: 0;
    padding: 26px 24px 4px;
    width: 100%;
    max-width: 640px;
    margin: 0 auto;
  }
}
@media (min-width: 901px) and (max-width: 1100px) {
  .phero-media { height: min(58vw, 52svh); }
  .phero-slide img, .phero-slide video { max-width: 90vw; }
}
/* Telefon (≤900px): MINIMAL — jedno zdjęcie na pełną szerokość, swipe ze
   snapem jak karuzela „1 z N" niżej. Zero peeków, zero tilt-shiftu i warstw
   blur (anchor 0 w silniku); zostaje licznik, pętla i tap = powiększenie. */
@media (max-width: 900px) {
  .phero-media { height: min(118vw, 56svh); cursor: default; }
  .phero-slide { width: 100vw; flex: 0 0 100vw; }
  .phero-slide img, .phero-slide video {
    width: 100vw;
    max-width: none;
    height: 100%;
    object-fit: cover;
  }
  .phero-dof { display: none !important; }
  .phero-slide .phero-blur,
  .phero-slide .phero-edge { display: none; }
}
