/**
 * Realizacje - JEDNO przypiecie (position:sticky). PO TRZECH nieudanych
 * probach JS-owego "pin jedzie z dolu, position:fixed" - WNIOSEK: natywny
 * position:sticky (zero JS w petli scrolla do samego pozycjonowania) jest
 * jedyna droga ktora daje plynnosc. "Nachodzenie na usługi" = DOKLADNIE ta
 * sama technika co manifesto.css nachodzace na hero (ujemny margin-top).
 * Root cause "usługi ida do gory razem z portfolio w polowie" (zgloszony
 * przez usera) - usługi (services-moduly.js) nie mialy ZADNEGO celowego
 * buforu PO ostatniej karcie, tylko przypadkowy, niestabilny zapas z
 * entryBaselineRaw. FIX: dodany HOLD_AFTER_LAST_CARD_VH=60vh w
 * services-moduly.js (celowy, stabilny bufor - karta 9 zostaje "aktywna"
 * dluzej, sklampowana), co pozwolilo zwiekszyc margines tutaj z -30vh do
 * -90vh (razem daje ~pelne 100vh potrzebne zeby usługi realnie stały w
 * miejscu przez caly czas naturalnego "wjazdu" portfolio z dolu - ta sama
 * matematyka co przy hero/manifesto). */
.portfolio-marquee {
    position: relative;
    /* NAD sekcja uslug (ona ma z-index 3 + FIXED warstwe tla na caly ekran) -
       bez tego jej aktywne tlo zamalowywalo pierwszy ekran portfolio. Solidne
       tlo sekcji przykrywa fixed warstwe w swoim obszarze. */
    z-index: 4;
    /* NACHODZENIE NA USŁUGI USUNIETE (bylo margin-top:-90vh) - user po
       przetestowaniu poprosil o powrot do standardowego przejscia miedzy
       sekcjami (sekcja realizacji zaczyna sie normalnie PO usługach, bez
       najezdzania). Razem z tym cofniety bufor HOLD_AFTER_LAST_CARD_VH w
       services-moduly.js (byl potrzebny wylacznie pod ten overlap).
       490vh = 580vh - 90vh: budzet fazy przewijania kart zostaje IDENTYCZNY
       (overlap zjadal pierwsze 90vh budzetu, teraz go po prostu nie ma). */
    /* 760vh (bylo 490vh) - SPOWOLNIENIE karuzeli. Pomiar na stagingu: pasek
       ma 9214 px poziomego przejazdu, a przy 490vh dostawal tylko 3704 px
       scrolla w pionie, czyli jeden klik kolka (~100 px) przesuwal karty o
       ~250 px - prawie cala karta (307 px) znikala w jednym ticku i nic nie
       bylo widac. Przy 760vh wychodzi ~1,55 px poziomo na 1 px pionowo, wiec
       karta zmienia sie mniej wiecej co dwa kliki kolka. */
    height: 760vh;
    background: var(--color-bg, #000408);
}

.portfolio-marquee__pin {
    position: sticky;
    /* top:0 nachodzilby pod staly pasek nawigacji (position:fixed, --nav-height). */
    top: var(--nav-height, 72px);
    height: calc(100vh - var(--nav-height, 72px));
    background: var(--color-bg, #000408);
    display: flex;
    flex-direction: column;
    /* Powrot do center (chwilowo bylo flex-start/left) - zmierzone na zywej
       referencji feed-forge: ich naglowek jest WYSRODKOWANY, karty startuja
       ~11vw od lewej (padding-left na .track nizej), a przy przewijaniu tna
       sie o krawedz EKRANU (full-bleed viewport, patrz
       .portfolio-marquee__viewport). User: "zrobmy to samo co u nich". */
    align-items: center;
    justify-content: center;
    text-align: center;
    padding-inline: clamp(24px, 6vw, 96px);
    /* Wiekszy odstep (bylo 28-48px) - user chcial wyrazna przerwe miedzy
       naglowkiem a karuzela, nie od razu przyklejone. */
    gap: clamp(56px, 8vw, 96px);
    padding-top: clamp(96px, 14vh, 180px);
    /* Duzy padding-bottom - przesuwa wysrodkowany flexem naglowek WYZEJ niz
       geometryczny srodek (user: idealny srodek byl "az za bardzo po srodku").
       Nie rusza karuzeli (.bottom jest position:absolute, poza przeplywem). */
    padding-bottom: clamp(140px, 22vh, 280px);
    overflow: visible;
}

/* Delikatne poswiaty w tle pinu (prosba usera 2026-09-14: "dodaj w tlo jakies
   poswiaty delikatne aby stworzyc glebie") - trzy duze, miekkie radiale w
   kolorach brandu (cyan/magenta/fiolet gradientu logo), alpha .05-.08 zeby
   nie konkurowaly z kartami. Na ::before pinu (sticky = poswiaty stoja w
   miejscu przez cale 490vh przypiecia), z-index 0 pod trescia (tekst i
   karuzela podniesione na z-index 1 nizej). To INNA rzecz niz usuniete
   wczesniej "tlo jak w usługach" (tamto bylo kopiowaniem siatki/glow 1:1
   pod overlap - zarzucone razem z overlapem). */
.portfolio-marquee__pin::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    background:
        radial-gradient(ellipse 55% 45% at 12% 18%, rgba(204, 0, 166, .07), transparent 70%),
        radial-gradient(ellipse 50% 42% at 88% 72%, rgba(115, 56, 234, .08), transparent 70%),
        radial-gradient(ellipse 45% 38% at 50% 108%, rgba(115, 56, 234, .06), transparent 72%);
}

.portfolio-marquee__text {
    /* Poczatkowy stan (opacity 1, brak przesuniecia) - portfolio-marquee.js
       nadpisuje to co klatke w oparciu o postep scrolla przez przypiecie. Transition
       tylko jako siatka bezpieczenstwa/wygladzenie miedzy klatkami rAF, GLOWNY ruch
       daje samo przeliczanie w JS (progres->opacity), nie ta transition. */
    transition: opacity .1s linear, transform .1s linear, filter .1s linear;
    /* Nad poswiatami tla (pin::before, z-index 0). */
    position: relative;
    z-index: 1;
}

.portfolio-marquee__bottom {
    /* ABSOLUTE (bylo w przeplywie flexa) - w przeplywie layout rezerwowal pod
       naglowkiem miejsce na cala karuzele (transform przesuwa tylko
       WIZUALNIE), wiec flex-center wypychal naglowek wysoko w gore i zostawal
       wielki pusty pas (zgloszone przez usera). Wyjety z przeplywu: naglowek
       (jedyne dziecko w przeplywie) sam laduje na srodku sekcji, a karuzela
       jest pozycjonowana niezaleznie - top:50% + translateY(-50% + X) z JS,
       gdzie X jedzie od ~45vh (start: wystaje z dolu) do 0 (koniec: idealnie
       wysrodkowana, dokladnie na miejscu po naglowku). */
    position: absolute;
    inset-inline: 0;
    top: 50%;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: clamp(24px, 3vw, 40px);
    transform: translateY(calc(-50% + 45vh));
    /* BEZ transition na transform (bylo .1s linear) - przy scrubowaniu
       scrollem nawet krotka transition daje "gumowe" doganianie pozycji,
       odbierane jako spowolnienie wyjazdu (zgloszone przez usera). Ruch jest
       teraz 1:1 z kolkiem. */
    /* Nad poswiatami tla (pin::before, z-index 0). */
    z-index: 1;
}

.portfolio-marquee__heading {
    margin: 0;
    font-family: var(--font-heading, 'Poppins'), sans-serif;
    font-weight: 800;
    letter-spacing: -.02em;
    /* Powiekszone (bylo 2-3.75rem) - user chcial wyrazniejszy, wiekszy naglowek jak
       na referencji (82px na ich desktopie). */
    font-size: clamp(2.75rem, 6.5vw, 5.75rem);
    color: var(--color-text, #fff);
}

/* "projekt" w gradiencie brandu (jak akcenty w what-you-get / about-crew). */
.portfolio-marquee__heading-accent {
    background: linear-gradient(100deg, #cc00a6 0%, #a01580 35%, #7338ea 70%, #4c1d9e 100%);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}

.portfolio-marquee__lead {
    margin: clamp(16px, 2.5vw, 28px) auto 0;
    /* 80ch (bylo 46ch) + krotsza tresc w PHP - user chcial JEDNO zdanie w
       JEDNEJ linijce (poprzednio lamalo sie na trzy). */
    max-width: 80ch;
    font-size: clamp(1rem, 1.3vw, 1.15rem);
    line-height: 1.6;
    color: var(--color-text-muted, rgba(255, 255, 255, .65));
}

.portfolio-marquee__viewport {
    /* Poziome gesty obsluguje ten pasek, pionowe oddajemy STRONIE.
       UWAGA: musza byc wymienione OBIE osie. Samo `pan-x` znaczy dla
       przegladarki "na tym elemencie wolno przesuwac WYLACZNIE w poziomie",
       czyli dokladnie odwrotnie niz mowil ten komentarz - swipe w gore/dol
       byl ignorowany i strona stala w miejscu, gdy palec trafil w pasek
       (zmierzone 2026-09-22 na emulowanym S22: 70 machniec przesunelo
       strone o 529 px). Przy obu osiach przegladarka sama wybiera kierunek
       po pierwszym ruchu palca: w bok jedzie karuzela, w dol strona. */
    touch-action: pan-x pan-y pinch-zoom;
    /* FULL-BLEED (bylo width:100% wewnatrz paddingu pina) - zmierzone na zywej
       referencji: przy przewijaniu ich karty tna sie o krawedz EKRANU (x=0),
       nie o wewnetrzna krawedz kontenera z paddingiem. Klasyczny trik
       "wyrwania" dziecka na pelna szerokosc okna z wysrodkowanego rodzica. */
    width: 100vw;
    margin-left: calc(50% - 50vw);
    /* overflow-x:auto (bylo hidden + CSS animation w .track) - user chcial
       zwykly, reczny scroll boczny (trackpad/kolko+shift) zamiast automatycznego
       przesuwania sie samo z siebie - "ja normalnie scrollem moge przescrollowac
       w bok". Native scroll, zero JS/scroll-hijackingu (ta sama lekcja co przy
       services-moduly wczesniej w tej sesji). */
    overflow-x: auto;
    overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
    /* Chowa natywny pasek scrolla (Chrome/Safari + Firefox) - czysciej wyglada,
       scroll dalej dziala normalnie (trackpad/shift+kolko/dotyk). */
    scrollbar-width: none;
    -ms-overflow-style: none;
    /* Maska TYLKO na prawej krawedzi (user: kolejne karty maja "wychodzic z
       otchlani" - stopniowe przejscie z czerni w widocznosc, nie twarde
       odciecie). LEWA krawedz celowo BEZ maski - wczesniejsza obustronna maska
       wygaszala pierwsza karte i rzad wygladal jakby "zaczynal sie od srodka"
       (zgloszone i naprawione wczesniej, nie wracac do obustronnej). Fade
       zaczyna sie ~78% szerokosci i dochodzi do pelnej przezroczystosci na
       samej krawedzi - na czarnym tle sekcji czyta sie dokladnie jak
       wylanianie sie z ciemnosci. */
    -webkit-mask-image: linear-gradient(90deg, #000 0%, #000 78%, transparent 99%);
    mask-image: linear-gradient(90deg, #000 0%, #000 78%, transparent 99%);
    /* Wejscie kart - FINALNA koncepcja (doprecyzowana przez usera po 4
       iteracjach): karty WIDOCZNE od poczatku, ale "przydymione" pod czarna
       nakladka (::after nizej, opacity sterowane z JS przez --dim) i lekko
       obnizone; scroll szybko (pierwsze ~12% budzetu) zdejmuje nakladke i
       unosi pasek z dolu. Kluczowa roznica vs nieudane wersje: przyciemnia
       CZARNA WARSTWA NAD kartami (karty caly czas widac "przez dym"), nie
       opacity samego paska (karty znikaly calkowicie - "wgl nie widac"). */
    position: relative;
    --dim: .85;
    transform: translateY(64px);
    transition: transform .1s linear;
}

.portfolio-marquee__viewport::after {
    content: "";
    position: absolute;
    inset: 0;
    background: #000;
    opacity: var(--dim, .85);
    pointer-events: none;
    transition: opacity .1s linear;
    /* Nad kartami i podpisami (te sa position:absolute wewnatrz kart). Nakladka
       pokrywa tylko widoczny obszar przy scrollLeft=0 - to wystarcza, bo zanim
       user zacznie przewijac karty w bok, --dim jest juz 0 (nakladka zdjeta na
       poczatku budzetu scrolla). */
    z-index: 2;
}

.portfolio-marquee__viewport::-webkit-scrollbar {
    display: none;
}

.portfolio-marquee__track {
    display: flex;
    align-items: stretch;
    /* Staly 24px - dokladnie gap-6 z referencji feed-forge. */
    gap: 24px;
    width: max-content;
    /* Animacja auto-scrolla USUNIETA (bylo: portfolio-marquee-scroll, 42s petla
       w nieskonczonosc) - user chcial reczny scroll, nie automatyczny suw. Karty
       tez juz NIE sa duplikowane 2x w PHP (bylo potrzebne tylko pod petle tej
       animacji, dla plynnego "wrap-around") - patrz portfolio-marquee.php. */
    /* padding-left 11vw - zmierzony start pierwszej karty w referencji
       (~218px przy 1928px). Track siedzi w full-bleed viewporcie (100vw), wiec
       ten padding wyznacza poczatkowa pozycje rzedu, a przy przewijaniu karty
       normalnie tna sie o krawedz ekranu. padding-right maly oddech na koncu. */
    padding-left: 11vw;
    padding-right: 4vw;
}

.portfolio-marquee__item {
    display: block;
    flex: 0 0 auto;
    /* 18.7vw - policzona pod twarde wymaganie usera "4 pelne + polowa piatej"
       przy rzedzie startujacym 11vw od lewej (padding-left .track): dostepne
       89vw, 4.5w + 4 gapy (24px ~ 5vw lacznie) = 89vw => w ~= 18.7vw.
       Kopiowanie surowego 16.2vw z referencji dawalo u nas 5+ kart (u nich
       viewport inaczej zagospodarowany). Stosunek w/h 1.41 jak w referencji. */
    width: clamp(285px, 19.2vw, 390px);
    height: clamp(402px, 27.1vw, 550px);
    border-radius: 16px;
    overflow: hidden;
    position: relative;
    background: var(--color-bg-alt, #131318);
    /* Neonowa obwodka + glow USUNIETE na prosbe usera (2026-09-14) - czyste
       karty bez obramowki, jak w referencji feed-forge. Zostaje tylko miekki
       cien pod spodem dla glebi. */
    box-shadow: 0 8px 30px rgba(0, 0, 0, .5);
}

/* Pionowy marquee wewnatrz karty - CIAGLY przesuw strony w dol z bezszwowym
   zawinieciem (dwie kopie obrazka jedna pod druga, translateY 0 -> -50%,
   linear, w nieskonczonosc). Zastapil animacje object-position gora-dol-gora
   ("ping-pong"), user chcial jednostajny ruch w jedna strone. */
.portfolio-marquee__item-media {
    position: absolute;
    inset: 0;
    display: block;
    overflow: hidden;
    /* Domyslnie "zgaszona" (user: cala karuzela wyszarzona/przyciemniona,
       kolory wracaja dopiero na hover konkretnej karty). */
    filter: grayscale(1) brightness(.5);
    transition: filter .35s ease;
}

.portfolio-marquee__item:hover .portfolio-marquee__item-media {
    filter: none;
}

.portfolio-marquee__item-scroll {
    display: flex;
    flex-direction: column;
    width: 100%;
    /* paused - strona wewnatrz karty NIE plynie sama z siebie; przewijanie
       startuje dopiero na hover (animation-play-state nizej) i wznawia sie
       od miejsca w ktorym stanelo przy zdjeciu kursora. */
    animation: portfolio-marquee-page-pan 45s linear infinite;
    animation-play-state: paused;
}

.portfolio-marquee__item:hover .portfolio-marquee__item-scroll {
    animation-play-state: running;
}

.portfolio-marquee__item-scroll img {
    display: block;
    width: 100%;
    height: auto;
    /* Gdyby zrzut byl NIZSZY niz karta (nietypowe, ale mozliwe) - dociagnij do
       pelnej wysokosci karty, zeby petla nie odslanila pustki. */
    min-height: 100%;
    object-fit: cover;
    object-position: 50% 0%;
}

@keyframes portfolio-marquee-page-pan {
    from { transform: translateY(0); }
    to   { transform: translateY(-50%); }
}

/* Podpis (nazwa klienta + tag) na dole zdjecia, na ciemnym gradiencie - wzorem
   referencji usera (social/video-ad portfolio). Realne dane z ACF (tytul +
   pierwszy portfolio_tags), NIE zmyslone statystyki jak w referencji (tam
   "+50% Monthly Revenue Growth") - tych liczb nie mamy jak zweryfikowac. */
/* ── STRZALKA W ROGU KARTY ──────────────────────────────────────
   Pojawia sie razem z podpisem, po najechaniu myszka. Mowi "kliknij, tu
   jest wiecej" - karta prowadzi do naszego case study, nie na strone
   klienta, wiec strzalka jest PROSTA (w prawo), nie ukosna. Ukosna czyta
   sie jako "wychodzisz z serwisu".
   Pseudoelement na karcie zamiast dodatkowego <span> w markupie: 32 karty
   razy jeden element mniej w drzewie. */
.portfolio-marquee__item::after {
    content: "";
    position: absolute;
    top: 12px;
    right: 12px;
    z-index: 3;
    width: 38px;
    height: 38px;
    border-radius: 50%;
    background:
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h13'/%3E%3Cpath d='m12.5 6 6 6-6 6'/%3E%3C/svg%3E") no-repeat center / 18px 18px,
        linear-gradient(135deg, #cc00a6 0%, #7338ea 100%);
    box-shadow: 0 6px 20px rgba(204, 0, 166, .45);
    opacity: 0;
    transform: translateY(-6px) scale(.85);
    transition: opacity .3s ease, transform .3s cubic-bezier(0.22, 1, 0.36, 1);
    pointer-events: none;
}

@media (hover: hover) and (pointer: fine) {
    .portfolio-marquee__item:hover::after {
        opacity: 1;
        transform: translateY(0) scale(1);
    }
}

/* Na dotyku nie ma hovera - strzalka widoczna na stale, przygaszona, zeby
   nie konkurowala ze zrzutem. */
@media (hover: none), (pointer: coarse) {
    .portfolio-marquee__item::after {
        opacity: .85;
        transform: none;
        width: 34px;
        height: 34px;
        background-size: 16px 16px, auto;
    }
}

.portfolio-marquee__item-caption {
    position: absolute;
    inset-inline: 0;
    bottom: 0;
    display: flex;
    flex-direction: column;
    gap: .15em;
    padding: 1.6rem 1.1rem .9rem;
    text-align: left;
    background: linear-gradient(0deg, rgba(0, 0, 0, .82) 0%, rgba(0, 0, 0, .45) 55%, transparent 100%);
    pointer-events: none;
    /* Ukryty domyslnie - pojawia sie dopiero na hover karty (razem z
       przywroceniem koloru i startem przewijania strony), user: "dopiero
       wtedy pojawiaja sie podpisy". */
    opacity: 0;
    transform: translateY(14px);
    transition: opacity .35s ease, transform .35s ease;
}

.portfolio-marquee__item:hover .portfolio-marquee__item-caption {
    opacity: 1;
    transform: translateY(0);
}

.portfolio-marquee__item-title {
    font-family: var(--font-heading, 'Poppins'), sans-serif;
    font-weight: 700;
    /* Powiekszone (bylo .9rem/.72rem) na prosbe usera. */
    font-size: clamp(1.1rem, 1.3vw, 1.35rem);
    color: #fff;
    line-height: 1.25;
}

.portfolio-marquee__item-tag {
    font-size: clamp(.85rem, 1vw, 1rem);
    font-weight: 600;
    letter-spacing: .03em;
    color: var(--color-primary, #cc00a6);
}

/* Przycisk HUD "btn-cyber" (ta sama stylistyka co uslugi, services-moduly.css -
   docielty cut-corner + neon glow + monospace + scanline, ale przygotowany tam a
   nigdzie NIE uzyty w markupie - user chcial dokladnie ten "kosmiczny" jezyk
   przyciskow na CTA portfolio, wiec dublujemy go tutaj (kazda sekcja ma wlasny,
   samodzielny CSS w tym motywie - zero cross-file zaleznosci miedzy parts). */
@keyframes portfolio-marquee-cta-glow {
    0%, 100% {
        box-shadow:
            0 4px 0 0 rgba(0, 0, 0, .4),
            0 0 0 1px rgba(204, 0, 166, .6),
            0 0 24px rgba(204, 0, 166, .4),
            0 0 48px rgba(115, 56, 234, .3);
    }
    50% {
        box-shadow:
            0 4px 0 0 rgba(0, 0, 0, .4),
            0 0 0 1px rgba(204, 0, 166, .6),
            0 0 32px rgba(204, 0, 166, .55),
            0 0 56px rgba(115, 56, 234, .4);
    }
}

.portfolio-marquee__cta {
    --btn-cut: 10px;
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 1rem 2.5rem;
    font-family: ui-monospace, 'SFMono-Regular', Menlo, Consolas, monospace;
    font-size: 1rem;
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: #fff;
    text-decoration: none;
    cursor: pointer;
    border: 1px solid rgba(204, 0, 166, .6);
    background: linear-gradient(135deg, #cc00a6 0%, #a01580 35%, #7338ea 70%, #4c1d9e 100%);
    clip-path: polygon(
        var(--btn-cut) 0,
        calc(100% - var(--btn-cut)) 0,
        100% var(--btn-cut),
        100% calc(100% - var(--btn-cut)),
        calc(100% - var(--btn-cut)) 100%,
        var(--btn-cut) 100%,
        0 calc(100% - var(--btn-cut)),
        0 var(--btn-cut)
    );
    box-shadow:
        0 4px 0 0 rgba(0, 0, 0, .4),
        0 0 0 1px rgba(204, 0, 166, .6),
        0 0 24px rgba(204, 0, 166, .4),
        0 0 48px rgba(115, 56, 234, .3);
    transition: transform .08s ease-out, background .2s ease, box-shadow .2s ease;
    overflow: hidden;
    animation: portfolio-marquee-cta-glow 3s ease-in-out infinite;
}

.portfolio-marquee__cta::before {
    content: "";
    position: absolute;
    inset: 0;
    background-image: repeating-linear-gradient(
        0deg,
        transparent 0,
        transparent 2px,
        rgba(0, 0, 0, .12) 2px,
        rgba(0, 0, 0, .12) 4px
    );
    pointer-events: none;
    clip-path: inherit;
}

.portfolio-marquee__cta:hover {
    background: linear-gradient(135deg, #e01ac0 0%, #b01890 35%, #8a4ff5 70%, #5a25b8 100%);
    color: #fff;
    box-shadow:
        0 4px 0 0 rgba(0, 0, 0, .4),
        0 0 0 1px rgba(204, 0, 166, .6),
        0 0 36px rgba(204, 0, 166, .5),
        0 0 64px rgba(115, 56, 234, .5);
}

.portfolio-marquee__cta:active {
    transform: translateY(4px);
    box-shadow:
        0 0 0 0 rgba(0, 0, 0, .4),
        0 0 0 1px rgba(204, 0, 166, .6),
        0 0 20px rgba(204, 0, 166, .4);
}

@media (max-width: 768px) {
    /* ── MOBILE: KROTKI PIN + natywna karuzela swipe ───────────
       Wersja bez pinu (sekcja w zwyklym przeplywie) gubila caly rytm
       przejscia: naglowek po prostu odjezdzal razem ze strona. User chce
       tego samego co na desktopie, tylko krocej - sekcja LAPIE sie na
       ekranie, jeden ruch palcem wypycha naglowek do tylu i podciaga
       karuzele z dolu, a potem pin puszcza i strona jedzie dalej.
       Budzet przypiecia: 100svh (przejscie zjada pierwsze ~55%, reszta to
       oddech na obejrzenie/przewiniecie kart). POZIOMY przesuw kart zostaje
       natywny (overflow-x + scroll-snap) - na dotyku nic tego nie pobije,
       patrz historia trzech nieudanych podejsc wyzej. */
    .portfolio-marquee {
        /* BUDZET PRZEWIJANIA: 260svh, bylo 100svh.
           Przy 100svh cale przejscie (naglowek do tylu, karuzela z dolu)
           mialo 0.48 x 844 = ok. 405 px przewijania. Jedno mocniejsze
           pociagniecie palcem na telefonie to 1500 px i wiecej, wiec
           animacja przelatywala w ulamku gestu i ladowales od razu w
           kolejnej sekcji - zgloszone przez usera jako "za szybko,
           przeskakuje". Teraz przejscie dostaje ok. 1050 px, czyli tyle,
           ze nawet szybki flick go nie zjada w calosci. Sasiednie sekcje
           dla porownania: uslugi 3.44 ekranu, astronauta 5.62. */
        height: calc(100svh + 160svh);
        /* NACHODZENIE NA MARTWY PAS USLUG. Kolo uslug centruje pozycje
           w pinie o wysokosci 100svh, wiec na samym koncu ostatnia usluga
           stoi na srodku ekranu, a cala dolna polowa jest pusta - i to ona
           dawala "strasznie duza przestrzen" przed naglowkiem realizacji
           (zgloszone przez usera). Sekcja ma solidne tlo i z-index 4, wiec
           wjezdza na te pustke i ja zjada.
           -32svh (270 px przy ekranie 844): ostatnia usluga konczy sie na
           496 px pinu, gorna krawedz realizacji wchodzi na 574 px - zostaje
           78 px zapasu, wiec karta uslugi nigdy nie jest przycieta. */
        /* 0, bylo -32svh. Ten ujemny margines zjadal martwy pas, ktory zostawal
           po PRZYPIETYM kole uslug. Po przebudowie uslug na zwykla liste
           (services-cine.css) martwego pasa juz nie ma, a margines zaczal
           zakrywac ostatnie pozycje listy - widoczne na zrzucie od usera. */
        margin-top: 0;
    }

    .portfolio-marquee__pin {
        position: sticky;
        /* Pod stalym paskiem nawigacji, tak jak na desktopie. */
        top: var(--nav-height, 64px);
        height: calc(100svh - var(--nav-height, 64px));
        /* Dolny padding podnosi naglowek nad geometryczny srodek (ta sama
           sztuczka co na desktopie) - inaczej nad nim zostaje 266 px pustki,
           a karuzela ledwo wystaje zza dolnej krawedzi. Karuzeli to nie
           rusza, bo jest position:absolute, poza przeplywem. */
        display: flex;
        flex-direction: column;
        /* flex-start, NIE center. Przy wysrodkowaniu naglowek stal 323 px od
           gory pinu, wiec gdy sekcja wjezdzala z dolu, miedzy ostatnia usluga
           a "Kazdy projekt to osobna misja" zostawal wielki czarny pas
           (zgloszone przez usera). Od gory naglowek pokazuje sie od razu,
           a karuzela i tak jest position:absolute na 50%, wiec jej to nie
           rusza. */
        justify-content: flex-start;
        padding-top: clamp(40px, 8svh, 76px);
        gap: clamp(18px, 3.5vh, 30px);
        overflow: visible;
    }

    /* opacity/transform/filter pisze JS (postep przypiecia). */
    .portfolio-marquee__text {
        padding: 0 20px;
    }

    .portfolio-marquee__heading {
        font-size: clamp(1.9rem, 8.5vw, 2.5rem);
    }

    .portfolio-marquee__lead {
        font-size: .95rem;
    }

    /* Wyjete z przeplywu - inaczej flex-center rezerwowalby miejsce na
       cala karuzele i naglowek wyladowalby przy gornej krawedzi. Pozycje
       w pionie pisze JS: od +45svh (wystaje z dolu) do 0 (na srodku). */
    .portfolio-marquee__bottom {
        position: absolute;
        inset-inline: 0;
        top: 50%;
        transform: translateY(calc(-50% + 45svh));
        gap: clamp(16px, 3vh, 26px);
    }

    .portfolio-marquee__viewport {
        --dim: 0;
        transform: none;
        overflow-x: auto;
        overflow-y: hidden;
        -webkit-overflow-scrolling: touch;
        scroll-snap-type: x mandatory;
        -webkit-mask-image: none;
        mask-image: none;
    }

    .portfolio-marquee__track {
        gap: 14px;
        /* Boczne wciecia = (100vw - karta)/2, zeby pierwsza i ostatnia
           mogly stanac na srodku przy snap-align: center. */
        padding-left: 12vw;
        padding-right: 12vw;
        transform: none;
    }

    .portfolio-marquee__item {
        width: 76vw;
        height: auto;
        aspect-ratio: 285 / 402;
        scroll-snap-align: center;
        /* WSZYSTKIE karty pelnym kolorem (prosba usera). */
        opacity: 1;
    }

    /* Kolor pelny zawsze - desktop trzyma go na hoverze, mobile ma zyc
       samo z siebie. */
    .portfolio-marquee__item-media {
        filter: none;
    }

    /* Jazda screenshotu TYLKO w kartach realnie widocznych w kadrze
       (.is-live dokłada portfolio-marquee.js przez IntersectionObserver) -
       wczesniej animowaly wszystkie karty non-stop, nawet poza ekranem,
       co na telefonie dawalo zauwazalne mikroprzyciecia (user). */
    .portfolio-marquee__item.is-live .portfolio-marquee__item-scroll {
        animation-play-state: running;
    }

    .portfolio-marquee__item-caption {
        opacity: 1;
        transform: none;
    }

    .portfolio-marquee__cta {
        font-size: .82rem;
        padding: .85rem 1.8rem;
    }

    /* Rzad nawigacji: [<] [Zobacz portfolio] [>] w jednej linii.
       CTA ma sciete rogi (clip-path) i wlasna wysokosc - bez wyrownania
       do srodka strzalki staly o 1px wyzej niz przycisk (zmierzone). */
    .portfolio-marquee__nav {
        display: flex;
        align-items: center;
        justify-content: center;
        gap: 12px;
    }

    .portfolio-marquee__nav .portfolio-marquee__cta {
        align-self: center;
    }

    .portfolio-marquee__nav .portfolio-marquee__arrow {
        align-self: center;
        flex: none;
    }

    .portfolio-marquee__arrow {
        width: 52px;
        height: 52px;
        border-radius: 50%;
        border: 1px solid rgba(204, 0, 166, .55);
        background: linear-gradient(135deg, rgba(204, 0, 166, .18), rgba(115, 56, 234, .18));
        color: #fff;
        display: flex;
        align-items: center;
        justify-content: center;
        cursor: pointer;
        transition: background .2s ease, transform .1s ease;
    }

    .portfolio-marquee__arrow:active {
        transform: scale(.92);
        background: linear-gradient(135deg, rgba(204, 0, 166, .4), rgba(115, 56, 234, .4));
    }

    .portfolio-marquee__arrow svg {
        width: 22px;
        height: 22px;
    }
}

@media (prefers-reduced-motion: reduce) {
    .portfolio-marquee {
        height: auto;
    }
    .portfolio-marquee__pin {
        position: static;
        height: auto;
    }
    .portfolio-marquee__track {
        animation: none;
        flex-wrap: wrap;
        width: 100%;
    }
    .portfolio-marquee__item-scroll {
        animation: none;
    }
}

/* Strzalki tylko na dotyku - desktop przewija karuzele scrollem.
   (CTA w rzedzie .nav zostaje widoczne wszedzie.) */
@media (min-width: 769px) {
    .portfolio-marquee__arrow { display: none; }
}


/* ---------- Filtr branzy (tylko landing) ---------- */

.portfolio-marquee__filters {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: .5rem;
    margin-top: 1.5rem;
}

.portfolio-marquee__filter {
    padding: .5rem 1rem;
    border-radius: 999px;
    background: rgba(255, 255, 255, .05);
    border: 1px solid rgba(255, 255, 255, .14);
    color: rgba(255, 255, 255, .72);
    font-family: var(--font-heading, 'Poppins'), sans-serif;
    font-size: .72rem;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    cursor: pointer;
    transition: border-color .25s ease, color .25s ease, background .25s ease;
}

.portfolio-marquee__filter:hover {
    border-color: rgba(204, 0, 166, .55);
    color: #fff;
}

.portfolio-marquee__filter.is-active {
    background: linear-gradient(135deg, #cc00a6 0%, #7338ea 100%);
    border-color: transparent;
    color: #fff;
}

/* Karta odfiltrowana wypada z ukladu paska, wiec karuzela liczy szerokosci
   tylko dla tego, co widac. */
.portfolio-marquee__item.is-filtered-out { display: none; }
