/**
 * marquee.css — pas treści przewijający się bez końca. Komponent
 * wielokrotnego użytku, w dwóch osiach: w bok (domyślnie) i w pionie
 * (.dc-marquee--vertical, sekcja 3).
 *
 * Wymaga tokens.css. Mechanika ruchu siedzi w assets/js/marquee.js —
 * ten plik jest KONSTRUKCJĄ pasa, skrypt tylko podaje mu przesunięcie.
 *
 * PODZIAŁ PRACY MIĘDZY CSS I JS — ten sam co w tilt-card.css. Skrypt nie
 * zna ani jednego koloru i ani jednej wartości projektowej. Zapisuje na
 * pasie JEDNĄ długość — --dc-marquee-x, przesunięcie w pikselach, klatka
 * po klatce — a maskę, geometrię i zachowanie przy braku zgody na ruch
 * bierze na siebie CSS.
 *
 * Powód takiego cięcia jest ten sam co przy przechyle karty: wartości
 * projektowe mają być widoczne dla reguł tego projektu — dla grepa po
 * hex/rgb/px i dla kontroli nierozwiązanych var(). To, czego skrypt nie
 * zna, nie może się po cichu rozjechać z paletą.
 *
 * --dc-marquee-x TO NIE POKRĘTŁO. Nie ustawia jej ani sekcja, ani strona —
 * pisze ją wyłącznie marquee.js. Komponent NIE MA wariantów: prędkości
 * i próg zawijania są w skrypcie wpisane na stałe, dokładnie tak jak kąt
 * przechyłu w tilt-card. Gdyby pas miał kiedyś jechać inaczej, to jest
 * decyzja projektowa do podjęcia, a nie pokrętło do dołożenia na zapas.
 *
 * ZNACZNIKI, których komponent oczekuje — grupa, w niej dowolna liczba
 * zamaskowanych okien, w każdym jeden pas:
 *
 *   <div data-dc-marquee>
 *     <div class="dc-marquee">
 *       <div class="dc-marquee__track" data-dc-marquee-track>…karty…</div>
 *     </div>
 *     <div class="dc-marquee">
 *       <div class="dc-marquee__track" data-dc-marquee-track
 *            data-dc-marquee-reverse>…karty…</div>
 *     </div>
 *   </div>
 *
 * GRUPA JEST JEDNOSTKĄ STANU: pasy w jednej grupie dzielą pauzę (najazd na
 * jeden zatrzymuje oba, jak w makiecie) i razem wchodzą i wychodzą z pola
 * widzenia — poza ekranem cała grupa przestaje liczyć klatki (marquee.js).
 *
 * KOMPONENT NIE MA KONTROLKI PAUZY. Miał ją przez chwilę, pod WCAG 2.2.2;
 * została usunięta razem z przyciskiem w reviews (decyzja z 2026-08-28,
 * pełny zapis w docs/decisions.md). Skutek: ruch da się zatrzymać wyłącznie
 * kursorem, więc kryterium 2.2.2 nie jest spełnione, a użytkownikowi
 * klawiatury i dotyku zostaje samo prefers-reduced-motion. Gdy decyzja
 * wróci, kontrolka wraca tu — nie stoi na zapas, bo komponent bez wariantów
 * to jedna z zasad tego projektu.
 *
 * LISTA W PASIE MUSI BYĆ PODWOJONA. Skrypt zawija ruch na POŁOWIE
 * szerokości pasa (scrollWidth / 2), więc treść w drugiej połowie musi
 * być dokładnie tą samą treścią co w pierwszej — inaczej w chwili
 * zawinięcia obraz przeskakuje. Podwojenie robi szablon, nie komponent:
 * to on wie, co powtarza, i on musi zdjąć drugą kopię z drzewa
 * dostępności (aria-hidden), żeby czytnik ekranu nie przeczytał
 * każdej pozycji dwa razy.
 */

/* ==========================================================================
   1. OKNO Z WYGASZONYMI KRAWĘDZIAMI

   Maska wygasza pas przy obu krawędziach, więc karty nie są ucinane
   pionową krawędzią, tylko rozpływają się w tło. Dzięki temu pas może
   być pełnej szerokości okna i nie potrzebuje żadnej ramki.

   PRZYSTANKI 8% I 92% SĄ Z MAKIETY DOSŁOWNIE i nie podlegają scalaniu
   (reguła 15 obejmuje odstępy, promienie i rozmiary pisma — nie liczbę
   ani położenie przystanków gradientu). Są procentami szerokości okna,
   więc wygaszenie skaluje się samo: przy 1440 px daje ok. 115 px, przy
   390 px ok. 31 px, i w obu przypadkach zajmuje ten sam ułamek obrazu.

   `black` W MASCE TO NIE KOLOR — to kanał alfy. Maska czyta z gradientu
   wyłącznie przezroczystość: `transparent` znaczy „wytnij", `black` znaczy
   „zostaw w całości". Żaden piksel tej barwy nie trafia na ekran, więc nie
   ma tu czego brać z palety ani z czym scalać — to ta sama kategoria co
   perspective(700px) w tilt-card.css. Zapisane słowem kluczowym, a nie
   hex-em, właśnie po to, żeby nie udawało wartości projektowej.

   -webkit-mask-image stoi obok mask-image dla Safari, które do dziś
   wymaga prefiksu przy masce z gradientu. Kolejność bez znaczenia,
   obie deklaracje są niezależne.
   ========================================================================== */

.dc-marquee {
  overflow: hidden;
  -webkit-mask-image: linear-gradient(
    90deg,
    transparent 0%,
    black 8%,
    black 92%,
    transparent 100%
  );
  mask-image: linear-gradient(
    90deg,
    transparent 0%,
    black 8%,
    black 92%,
    transparent 100%
  );
}

/* ==========================================================================
   2. PAS

   width: max-content — pas ma być tak szeroki, jak suma jego kart, a nie
   tak szeroki jak okno. Bez tego karty ścisnęłyby się do szerokości okna
   i scrollWidth przestałby cokolwiek znaczyć.

   Pionowy oddech 6 px z makiety: karty mają cień rzucany, a okno wyżej
   ma overflow: hidden, więc bez tej wyściółki cień byłby ucięty równo
   przy górnej i dolnej krawędzi pasa.
   ========================================================================== */

/* Wartość SPOCZYNKOWA przesunięcia, zadeklarowana bezwarunkowo — pas bez
   skryptu (brak JS, zgoda na ruch cofnięta) stoi na zerze, czyli pokazuje
   pierwsze karty od lewej. Deklaracja stoi tu z tego samego powodu co
   --dc-tilt-card-dx w tilt-card.css: opisuje spoczynek w tym samym pliku
   co ruch i sprawia, że kontrola nierozwiązanych tokenów (reguła 17,
   punkt 5) nie zgłasza zmiennej pisanej wyłącznie przez skrypt.

   To NIE jest pokrętło — nadpisuje ją wyłącznie marquee.js. */
.dc-marquee__track {
  --dc-marquee-x: 0;

  display: flex;
  width: max-content;
  padding-block: var(--dc-space-6);
  transform: translateX(var(--dc-marquee-x));
}

/* Warstwa kompozycji zakładana na stałe, inaczej niż przy przechyle karty.
   Tam warstwa powstawała dopiero na :hover, bo karta w spoczynku miała
   wyglądać dokładnie jak przed dołożeniem efektu. Tu pas nie ma spoczynku:
   transformacja zmienia się w KAŻDEJ klatce od pierwszej, więc promocja do
   własnej warstwy jest potrzebna przez cały czas życia pasa i zdejmuje
   przemalowywanie kilkudziesięciu kart z głównego wątku. */
@media (prefers-reduced-motion: no-preference) {
  .dc-marquee__track {
    will-change: transform;
  }
}

/* ==========================================================================
   3. WARIANT PIONOWY

   Ten sam pas obrócony o ćwierć obrotu: karty jadą w górę albo w dół
   zamiast w bok. Dołożony 2026-08-30 dla shared/reviews-summary, gdzie
   makieta karty produktu stawia dwa pasy PIONOWO obok podsumowania ocen.

   To WARIANT, nie drugi komponent — i to jest tu cała treść. Mechanika
   jest identyczna: te same prędkości, ten sam próg zawinięcia na połowie,
   to samo przesunięcie startowe pasa odwróconego, te same pauzy. Skrypt
   zmienia dokładnie dwie rzeczy: mierzy scrollHeight zamiast scrollWidth
   i zapisuje --dc-marquee-y zamiast --dc-marquee-x (marquee.js, atrybut
   data-dc-marquee-vertical na pasie). Pas bez tego atrybutu przechodzi
   ścieżką kodu nietkniętą, więc shared/reviews działa jak przedtem —
   sprawdzone.

   Uwaga o zdaniu z nagłówka „komponent NIE MA wariantów": ono broniło się
   przed POKRĘTŁAMI — prędkością, kątem, czasem podawanymi przez sekcję.
   Oś to nie pokrętło, tylko druga postać tej samej konstrukcji, wymuszona
   przez makietę, a nie przez wygodę sekcji. Wartości projektowych nadal
   nie podaje nikt z zewnątrz.

   Maska obraca się razem z osią: 180deg zamiast 90deg, te same przystanki
   8% i 92% z makiety. Wysokość okna podaje SEKCJA, bo to ona wie, ile
   miejsca ma w swoim układzie — komponent nie zgaduje wysokości tak samo,
   jak nie zgaduje szerokości w wariancie poziomym.
   ========================================================================== */

.dc-marquee--vertical {
  -webkit-mask-image: linear-gradient(
    180deg,
    transparent 0%,
    black 8%,
    black 92%,
    transparent 100%
  );
  mask-image: linear-gradient(
    180deg,
    transparent 0%,
    black 8%,
    black 92%,
    transparent 100%
  );
}

/* width: 100% zamiast max-content — w poziomie pas ma być szerszy od okna,
   w pionie ma być RÓWNY jego szerokości, a rosnąć w drugą oś. Stąd też
   height: max-content: to ona jest teraz sumą kart i to ją mierzy skrypt.
   Wyściółka przenosi się z osi pionowej na poziomą z tego samego powodu
   co w wariancie poziomym — cień karty nie ma być ucięty krawędzią okna. */
.dc-marquee--vertical .dc-marquee__track {
  --dc-marquee-y: 0;

  flex-direction: column;
  width: 100%;
  height: max-content;
  padding-block: 0;
  padding-inline: var(--dc-space-6);
  transform: translateY(var(--dc-marquee-y));
}

/* ==========================================================================
   4. BRAK ZGODY NA RUCH — REGUŁA 12

   Skrypt przy prefers-reduced-motion: reduce nie uruchamia się w ogóle:
   nie podpina ani jednego nasłuchu i nie zamawia ani jednej klatki (patrz
   marquee.js). Pas zostaje więc na --dc-marquee-x: 0 i po prostu stoi,
   pokazując pierwsze karty od lewej — treść jest czytelna, karty widoczne,
   nic nie zamiera w przypadkowej pozycji.

   Dlatego nie ma tu bloku @media z regułami wyłączającymi ruch: nie ma
   czego wyłączać, bo ruch nigdy się nie zaczyna. Jedyne, co warunek
   medialny robi wyżej, to nieprzyznanie warstwy kompozycji (will-change) —
   pas, który stoi, nie potrzebuje własnej warstwy.
   ========================================================================== */
