/**
 * product-hero.css — górna część karty produktu w układzie DWUKOLUMNOWYM:
 * po lewej galeria jako PIONOWA ROLKA zdjęć (aktywne pośrodku, sąsiednie
 * wystają nad nim i pod nim), miniatury i wstęga; po prawej panel zakupowy.
 * Jedna szklana karta z jedną obwódką. Koncept: product.html (dwie kolumny,
 * ten sam co starter-kit-buy) + rolka zamiast pojedynczej sceny — decyzja
 * Andrzeja 2026-08-31, uzasadnienie w nagłówku hero.php.
 *
 * Wymaga tokens.css, base.css, components/ring.css i components/marquee.css.
 * Każdy plik sekcji ładuje się na KAŻDEJ stronie, więc wszystko siedzi pod
 * prefiksem .dc-product-hero__ i nic stąd nie może wyciec na cudze znaczniki.
 * Wyjątki: .dc-ring, .dc-marquee (komponenty) i .dc-icon (rejestr) — dostrajane
 * wyłącznie w selektorze potomnym pod prefiksem sekcji.
 *
 * ANI JEDNEJ REGUŁY [data-theme='dark'] — kolory w obu motywach podmieniają
 * tokeny (reguła 10). Obwódka w motywie ciemnym przestała się „urywać"
 * przy zdjęciach nie przez kolor, tylko przez KOLEJNOŚĆ WARSTW (sekcja 1),
 * która jest wspólna dla obu motywów.
 *
 * MAKIETA NIESIE UKŁAD I WYMIARY, NIE STYL. Generator rysuje przyciski,
 * złoto, cienie i najazdy sprzed audytu; system z design-audit.md (C)
 * wygrywa. Kopie (skill, §0 „nie wymyślaj"):
 *   - .dc-product-hero__submit    ← .dc-volume-picker__submit (ranga 1),
 *   - .dc-product-hero__assistant ← .dc-hero__cta + --secondary (ranga 2),
 *   - .dc-product-hero__fraction  ← .dc-nav__link[aria-current] (segment
 *                                   na torze z nagłówka),
 *   - .dc-product-hero__flag      ← .dc-volume-picker__flag (C.8, flaga),
 *   - .dc-product-hero__step      ← ranga 4 (przycisk ikonowy z tłem),
 *                                   ta sama konstrukcja co strzałki bloga.
 * Panel, miniatury, wstęga i wybór pakietu są zapisem z starter-kit-buy.css
 * (ten sam koncept, ta sama makieta) — różnice stoją przy regułach.
 *
 * CO JEST TU LICZBĄ, A NIE TOKENEM (reguła 17, punkt 5 — grep ma coś znaleźć
 * i te trafienia są świadome):
 *   1. Punkty zatrzymania i środek gradientu kolumny (`130% 95% at 50% 12%`,
 *      `85%`) — geometria rysunku, jak w hero.css.
 *   2. `scale(0.8)` / `scale(1.12)` w tętnie kropki — amplituda ruchu
 *      z makiety (dcPulse), nie wartość projektowa.
 *   3. `1px` / `-1px` w __radio — geometria ukrycia kontrolki (ta sama co
 *      w .dc-sr-only w base.css), nie odstęp.
 *   4. `blur(4px)` w stanie wejściowym packshotu — wartość ze skilla
 *      better-ui dla wejścia treści, geometria ruchu.
 *   5. WYMIAR Z MAKIETY, KTÓREGO SCALENIE BYŁOBY WIDAĆ (decyzja Andrzeja
 *      2026-08-30: reguła 15 obejmuje wartości nierozróżnialne dla oka, nie
 *      stopień dużego napisu): cena clamp(36px, 4.4vw, 46px).
 *   6. GEOMETRIA ROLKI: `0.06` (o tyle maleje slajd oddalony o jedną
 *      pozycję), `0.4` / `0.15` (krycie zasłony przyciemniającej sąsiada
 *      w spoczynku i na najeździe), `4 / 3` (proporcja slajdu = proporcja
 *      plików packshotów), `50%` (środek rolki). Przesunięcie i stopień
 *      oddalenia podaje skrypt jako zmienne --dc-product-hero-offset
 *      i --dc-product-hero-dim (0 … 1). To rysunek mechanizmu, nie odstęp
 *      z drabinki; odstęp między slajdami JEST tokenem.
 *   7. PROGI @media — zmierzone, patrz komentarze przy regułach.
 *
 * Pozostałe scalenia wg reguły 15 stoją przy regułach, których dotyczą.
 */

/* ==========================================================================
   1. RAMA SEKCJI, KARTA I OBWÓDKA
   ========================================================================== */

/* .dc-product-hero nie ma deklaracji: .dc-container i .dc-section z base.css
   dają dokładnie makietowe max-width 1240 / padding 64px 32px (reguła 8). */

/* Szklana karta. Scalenia: tło biel .5 = --dc-surface-glass-soft co do cyfry,
   szkło blur(20) saturate(165%) = --dc-blur-lg co do cyfry, obwódka biel .7
   -> --dc-border-subtle, cień 0 16px 50px .09 -> --dc-shadow-xl
   (0 16 44 .14) + inset .92 -> --dc-shadow-inset-top (.95), reguła 13.
   BEZ overflow: hidden na karcie — poświata obwódki leży 4 px poza obrysem
   (design-audit.md, partia 6); przycina dopiero owijka niżej. */
.dc-product-hero__card {
  position: relative;
  isolation: isolate;
  border: var(--dc-border) solid var(--dc-border-subtle);
  border-radius: var(--dc-radius-28);
  background-color: var(--dc-surface-glass-soft);
  -webkit-backdrop-filter: var(--dc-blur-lg);
  backdrop-filter: var(--dc-blur-lg);
  box-shadow: var(--dc-shadow-xl), var(--dc-shadow-inset-top);

  /* FAZA I ZWROT OBWÓDKI — numer 4 z rejestru w components/ring.css:
     start o 4/12 obrotu (120°), parzysty = w prawo. Rejestr ma zajęte
     wszystkie dwanaście numerów; reguła mówi „numer, którego nie ma na TEJ
     SAMEJ stronie", a 4 nosi origin — sekcja wyłącznie strony głównej,
     która z kartą produktu nigdy nie stoi razem. */
  --dc-ring-delay: calc(var(--dc-duration-ring) * -4 / 12);
}

/* KOLEJNOŚĆ WARSTW — inaczej niż w pozostałych sekcjach z obwódką i celowo.
   Komponent stawia każdą warstwę .dc-ring na --dc-z-base, a sekcje kładą
   owijkę treści wyżej (--dc-z-raised), żeby rozmyta poświata nie wchodziła
   na treść. Tu kolumna galerii ma NIEPRZEZROCZYSTE tło na całą wysokość
   karty, więc owijka nad obwódką zasłaniała łuk i refleks wzdłuż całej
   lewej krawędzi — w motywie ciemnym obwódka „urywała się" przy zdjęciach
   (zgłoszenie Andrzeja, 2026-08-31; w jasnym biel na bieli tego nie
   pokazywała). Łuk i refleks idą więc NAD owijkę: mają 1,5 px grubości,
   leżą dokładnie na krawędzi i nie przyjmują zdarzeń, więc nad treścią
   niczego nie psują. Poświata zostaje POD owijką (ta sama warstwa
   --dc-z-base, owijka później w drzewie), bo ona jedna rozlewa się do
   środka karty. Nie zmiana w komponencie: to różnica jednego wystąpienia
   (reguła 18 — sekcja zapisuje to, czym się różni). */
.dc-product-hero__card > .dc-ring--arc,
.dc-product-hero__card > .dc-ring--specular {
  z-index: var(--dc-z-raised);
}

/* Owijka treści: przycina do promienia karty (patrz wyżej) i leży nad
   poświatą, pod łukiem.

   SIATKA JAK W starter-kit-buy: repeat(auto-fit, minmax(340px, 1fr)) — 340
   to --dc-measure-xs co do cyfry. Kolumny zwijają się same (reguła 9),
   a próg jednej kolumny i tak wyznacza panel, nie siatka (sekcja 15).

   min(…, 100%) W MINIMUM, nie samo 340: minmax() z twardym minimum NIGDY
   nie schodzi poniżej tej wartości, więc gdy kontener jest węższy, tor
   wystawałby poza niego (zmierzone w starter-kit-buy przy 390 px: 14 px
   za szeroko). min() zdejmuje minimum do szerokości kontenera. */
.dc-product-hero__inner {
  position: relative;
  z-index: var(--dc-z-base);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(var(--dc-measure-xs), 100%), 1fr));
  overflow: hidden;
  border-radius: inherit;
}

/* ==========================================================================
   2. GALERIA — KOLUMNA
   Makieta: kolumna z tłem radial(130% 95% at 50% 12%, #fff 0%, #eef0f3 85%)
   i kreską po prawej rgba(30,40,60,.08). Biel to --dc-surface, szarość
   #eef0f3 to --dc-surface-sunken nałożone na --dc-surface (w motywie ciemnym
   oba tokeny są ciemne, więc kolumna ciemnieje razem z kartą).
   Kolumna jest stosem: rolka bierze cały nadmiar wysokości (flex: 1),
   miniatury i wstęga stoją przy dolnej krawędzi.
   ========================================================================== */
.dc-product-hero__gallery {
  display: flex;
  flex-direction: column;
  min-width: 0;
  border-inline-end: var(--dc-border) solid var(--dc-border-line);
  background-color: var(--dc-surface);
  background-image: radial-gradient(
    130% 95% at 50% 12%,
    transparent 0%,
    var(--dc-surface-sunken) 85%
  );
}

/* ==========================================================================
   3. ROLKA
   Rolka jest oknem o wysokości, jaką zostawi panel po prawej; slajdy leżą
   w niej ABSOLUTNIE, każdy zaczepiony w połowie wysokości okna i przesunięty
   o swoją odległość od BIEŻĄCEJ POZYCJI rolki. Wysokość slajdu wynika
   z szerokości kolumny i proporcji 4:3, więc nic tu nie jest mierzone
   skryptem: skrypt ustawia wyłącznie liczbę (ułamkową — pozycja rolki jest
   ciągła i animowana klatka po klatce, hero.php pkt 3), a translate liczy
   przesunięcie w PROCENTACH WŁASNEJ WYSOKOŚCI slajdu (100% + odstęp).
   Pozycja aktywnego to −50% (środek slajdu w środku okna).

   BEZ PRZEJŚĆ CSS na slajdzie — celowo. Pierwsza wersja (2026-08-31) dawała
   każdemu slajdowi transition na transform i skokowo nowe pozycje; przy
   przejeździe o kilka slajdów (dalekie zdjęcie, potem pakiet) sąsiedzi
   znikali natychmiast, a nowy wjeżdżał zza krawędzi, nieraz z niewłaściwej
   strony — „dziwny skok" (Andrzej). Teraz ruch prowadzi skrypt, a CSS tylko
   rysuje bieżącą klatkę: przesunięcie, skalę i przyciemnienie liczy z tych
   samych dwóch zmiennych, więc trzy wielkości zmieniają się w jednym rytmie.

   DLACZEGO NIE overflow-y: auto ze scroll-snap. Natywne przewijanie
   zatrzymuje się na końcu listy — a rolka ma być pętlą — i przy kółku
   myszy nad tak wysokim elementem albo więzi stronę (overscroll-behavior:
   contain), albo obraca rolkę tylko do końca listy. Przesunięcia liczone
   modulo dają pętlę bez klonów slajdów, a o tym, KIEDY kółko obraca rolkę,
   decyduje skrypt (uzbrajanie ruchem wskaźnika — hero.php).
   ========================================================================== */
.dc-product-hero__reel {
  position: relative;
  container-type: size;
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
  cursor: grab;
  touch-action: pan-y;
  user-select: none;
  -webkit-user-select: none;
}

/* Rolka przyjmuje gest przeciągnięcia (skrypt): touch-action: pan-y
   oddaje przeglądarce pionowe przewijanie palcem, poziomy ruch zostaje
   gestem; cursor: grab zapowiada to myszą. */
.dc-product-hero__reel:active {
  cursor: grabbing;
}

/* Lista slajdów wypełnia okno; sama nie ma wymiarów poza tym. */
.dc-product-hero__slides {
  position: absolute;
  inset: 0;
}

/* Slajd: wcięcie boczne 32, proporcja 4:3 = proporcja plików packshotów
   (600 × 450, zmierzone 2026-08-31 w starter-kit-buy), promień 20
   -> --dc-radius-22, cień 0 14px 38px .08 -> --dc-shadow-lg (C.4: karta
   rzędu drugiego pod panelem xl). Tło --dc-surface-on-dark (biel w OBU
   motywach — tyle co biel JPG-a packshotu, żeby plik zlewał się z tłem
   slajdu). Odstęp między slajdami --dc-space-20. Skala: slajd oddalony
   o jedną pozycję ma 0,94 (1 − 0,06 × dim), pomiędzy — proporcjonalnie.

   ROZMIAR SLAJDU Z DWÓCH OGRANICZEŃ, NIE Z SAMEJ SZEROKOŚCI (druga
   poprawka 2026-08-31). Pierwsza wersja brała szerokość kolumny minus
   wcięcie i wysokość z proporcji; wysokość rolki zależy tymczasem od
   PANELU obok (łamanie tytułu i opisu, liczba wierszy), więc na jednym
   ekranie trzy zdjęcia miały 12 px oddechu, a na innym dotykały krawędzi
   karty i szyny miniatur („jakby style się nie załadowały" — Andrzej, ze
   zrzutem). Teraz rolka jest kontenerem zapytań (container-type: size),
   a slajd bierze MNIEJSZĄ z dwóch szerokości: kolumna minus 2 × 32 albo
   taka, przy której trzy slajdy 4:3 z dwoma odstępami 20 i oddechem 24
   na obu końcach mieszczą się w wysokości rolki (100cqh). Zmierzone przy
   1440 (rolka 1223 px): wysokość wygrywa — slajd 504 × 378, oddech 24 px
   plus 11 z pomniejszenia sąsiadów. Przy dłuższym panelu wygrywa szerokość
   (523 × 392) i oddech rośnie; przy krótszym slajdy maleją, a oddech
   zostaje. Szerokość, nie wysokość, jest tu deklarowana, bo tylko z niej
   aspect-ratio umie policzyć drugi wymiar przy pozycjonowaniu absolutnym;
   inset-inline: 0 + margin-inline: auto centrują slajd o znanej
   szerokości. Jednostki cqw/cqh — ta sama generacja przeglądarek co
   :has(), na którym stoi już wybór pakietu. */
.dc-product-hero__slide {
  position: absolute;
  inset-inline: 0;
  inset-block-start: 50%;
  width: min(
    calc(100cqw - 2 * var(--dc-space-32)),
    calc((100cqh - 2 * var(--dc-space-20) - 2 * var(--dc-space-24)) / 3 * 4 / 3)
  );
  margin-inline: auto;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  border-radius: var(--dc-radius-22);
  background-color: var(--dc-surface-on-dark);
  box-shadow: var(--dc-shadow-lg);
  transform:
    translateY(calc(-50% + var(--dc-product-hero-offset, 0) * (100% + var(--dc-space-20))))
    scale(calc(1 - 0.06 * var(--dc-product-hero-dim, 0)));
}

/* Przyciemnienie sąsiada to ZASŁONA w kolorze powierzchni motywu, nie
   opacity slajdu: w jasnym motywie zdjęcie blednie ku bieli, w ciemnym
   cofa się w ciemność karty — opacity dawało w ciemnym szarawy, biały
   prostokąt packshotu. Krycie zasłony rośnie z oddaleniem (0 pośrodku,
   0,4 przy sąsiedzie), więc podczas przejazdu zdjęcie rozjaśnia się
   płynnie, w tym samym rytmie co ruch i skala. */
.dc-product-hero__slide::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-color: var(--dc-surface);
  opacity: calc(0.4 * var(--dc-product-hero-dim, 0));
}

/* Sąsiad (−1 / +1) w spoczynku: klikalny — kliknięcie wciąga go na środek
   (skrypt). Najazd tylko kryciem zasłony (C.2: bez ruchu), z przejściem;
   klasa --near stoi wyłącznie w spoczynku, więc przejście nie ściga
   animacji przejazdu. */
.dc-product-hero__slide--near {
  cursor: pointer;
}

.dc-product-hero__slide--near::after {
  transition: opacity var(--dc-duration-base) var(--dc-ease);
}

.dc-product-hero__slide--near:hover::after {
  opacity: 0.15;
}

/* Dalszy (|przesunięcie| ≥ 2): schowany. Stoi poza oknem rolki, więc
   przeskok z jednej strony pętli na drugą (z −n/2 na +n/2) jest tam
   niewidoczny. visibility, nie display: slajd ma zachować pozycję, z której
   za chwilę wjedzie. */
.dc-product-hero__slide--far {
  visibility: hidden;
}

/* Packshot: contain na bieli (biel pliku = biel slajdu, więc wycinanka na
   całą szerokość slajdu). Fotografia z galerii: pełnokadrowa, cover.
   height: 100% wygrywa z base.css (img { height: auto }) specyficznością
   klasy — jak w fuel-switch. */
.dc-product-hero__image {
  position: relative;
  width: 100%;
  height: 100%;
  object-fit: contain;
  transition:
    opacity var(--dc-duration-slower) var(--dc-ease-out),
    filter var(--dc-duration-slower) var(--dc-ease-out);
}

.dc-product-hero__slide--photo .dc-product-hero__image {
  object-fit: cover;
}

/* PRZENIKANIE DWÓCH WARSTW przy zmianie pakietu (skrypt, pkt 5 w hero.php;
   skill better-ui, animations: wyjście krótsze i łagodniejsze niż wejście,
   oba ease-out, oba elementy w DOM, żeby tło nie prześwitywało).
   WEJŚCIE nowego packshotu: --in to stan startowy bez przejścia (krycie 0,
   rozmycie 4 px); zdjęcie przechodzi do spoczynku w --dc-duration-slower.
   WYJŚCIE ducha: --ghost to klon starego zdjęcia NAD nowym; --out gasi go
   w --dc-duration-fast. Bez przesunięcia w bok jak dotąd: slajd wariantu
   stoi w miejscu, zmienia się tylko liczba palet na nim. */
.dc-product-hero__image--in {
  opacity: 0;
  filter: blur(4px);
  transition: none;
}

.dc-product-hero__slide .dc-product-hero__image--ghost {
  position: absolute;
  inset: 0;
  pointer-events: none;
  transition: opacity var(--dc-duration-fast) var(--dc-ease-out);
}

.dc-product-hero__image--out {
  opacity: 0;
}

/* ==========================================================================
   4. STRZAŁKI ROLKI
   Dwa przyciski rangi 4 (ikonowy z tłem, jak strzałki bloga) w kolumnie
   przy prawej krawędzi okna, w połowie wysokości — na wysokości aktywnego
   slajdu, ale poza nim (slajd ma wcięcie 20, przycisk stoi w nim).
   Rozmiar 36 -> --dc-space-32 + obwódka; ikona 18.
   ========================================================================== */
.dc-product-hero__steps {
  position: absolute;
  inset-inline-end: var(--dc-space-6);
  inset-block-start: 50%;
  z-index: var(--dc-z-raised);
  display: flex;
  flex-direction: column;
  gap: var(--dc-space-6);
  transform: translateY(-50%);
}

.dc-product-hero__step {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--dc-space-32);
  height: var(--dc-space-32);
  padding: 0;
  border: var(--dc-border) solid var(--dc-border-line);
  border-radius: var(--dc-radius-full);
  background-color: var(--dc-surface-glass);
  color: var(--dc-text);
  box-shadow: var(--dc-shadow-sm);
  -webkit-backdrop-filter: var(--dc-blur-sm);
  backdrop-filter: var(--dc-blur-sm);
  cursor: pointer;
  transition:
    background-color var(--dc-duration-base) var(--dc-ease),
    border-color var(--dc-duration-base) var(--dc-ease),
    color var(--dc-duration-base) var(--dc-ease),
    box-shadow var(--dc-duration-base) var(--dc-ease),
    transform var(--dc-duration-fast) var(--dc-ease-out);
}

.dc-product-hero__step:focus-visible {
  border-radius: var(--dc-radius-full);
}

.dc-product-hero__step:hover {
  border-color: var(--dc-surface-inverse);
  background-color: var(--dc-surface-inverse);
  color: var(--dc-surface);
}

.dc-product-hero__step:active {
  transform: scale(0.97);
  box-shadow: var(--dc-shadow-sm), var(--dc-shadow-inset-press);
}

.dc-product-hero__step .dc-icon {
  flex: none;
}

/* Jedna ikona z rejestru (chevron-down): „poprzednie" to obrót o pół
   obrotu, bo rolka idzie w pionie. W jednej kolumnie (sekcja 15) rolka
   idzie w poziomie i obroty zmieniają się na ćwierć. */
.dc-product-hero__step--prev .dc-icon {
  transform: rotate(180deg);
}

/* ==========================================================================
   5. SZYNA MINIATUR — zapis z starter-kit-buy
   Makieta: grid repeat(5, 1fr), gap 10, padding 14px 16px, kreska górna,
   tło biel .6 -> --dc-surface-glass-soft (.5). Pięć kolumn zastąpione
   auto-fit z minimum --dc-space-80: kafli jest tyle, ile daje baza
   (slot wariantu + galeria, dziś 1 + 5); liczba kolumn zmierzona
   (sekcja 15).

   SELEKTOR POTOMNY (0,2,0), NIE SAMA KLASA — celowo. base.css zeruje
   padding każdej listy `ul[role='list']` selektorem o specyficzności
   (0,1,1), a klasa sekcji ma (0,1,0), więc pierwsza wersja tej reguły
   przegrywała i szyna stała bez odstępów: kafle dotykały krawędzi karty,
   kreski górnej i wstęgi (zgłoszenie Andrzeja ze zrzutem, 2026-08-31;
   zmierzone: padding 0, kafel 89 px zamiast 84). Odstęp boczny 32, nie
   makietowe 16: to NAJMNIEJSZE wcięcie slajdów rolki (--dc-space-32),
   więc miniatury stoją w jednej linii z krawędziami zdjęć, gdy o rozmiarze
   slajdu decyduje szerokość; gdy decyduje wysokość rolki (sekcja 3),
   slajd jest węższy i szyna wystaje poza niego symetrycznie o kilka
   pikseli — szyna jest osobnym pasem, nie częścią zdjęcia. Minimum kafla 64,
   nie 80 jak w starter-kit-buy: przy 32 z każdej strony sześć kafli po 80
   z odstępami (530 px) nie mieści się w 523 px i auto-fit łamałby szynę
   na 5 + 1; przy 64 kafel wychodzi 78 px szerokości na 80 wysokości —
   niemal kwadrat, jak kafle w makiecie. Pionowo 16 -> 14 wg reguły 15
   odrzucone: 16 daje kaflom taki sam oddech od kreski górnej, jaki mają
   od siebie (gap 10) plus obwódka — makietowe 14 przy realnym, a nie
   zerowym paddingu, wyglądało ciaśniej niż odstęp między kaflami. */
.dc-product-hero__gallery .dc-product-hero__thumbs {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(var(--dc-space-64), 1fr));
  gap: var(--dc-space-10);
  padding: var(--dc-space-16) var(--dc-space-32);
  border-block-start: var(--dc-border) solid var(--dc-border-line);
  background-color: var(--dc-surface-glass-soft);
}

/* Kafel: wysokość 84 -> --dc-space-80, promień 13 -> --dc-radius-12, tło
   biel -> --dc-surface, obwódka rgba(30,40,60,.1) -> --dc-border-line, cień
   0 1px 3px .05 = --dc-shadow-xs. Najazd: obwódka a50; uniesienie z makiety
   pominięte — C.2, hover wyłącznie kolorem. */
.dc-product-hero__thumb {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: var(--dc-space-80);
  padding: 0;
  overflow: hidden;
  border: var(--dc-border) solid var(--dc-border-line);
  border-radius: var(--dc-radius-12);
  background-color: var(--dc-surface);
  box-shadow: var(--dc-shadow-xs);
  transition:
    border-color var(--dc-duration-base) var(--dc-ease),
    box-shadow var(--dc-duration-base) var(--dc-ease),
    transform var(--dc-duration-fast) var(--dc-ease-out);
}

/* base.css daje :focus-visible promień --dc-radius-6 — przywracamy promień
   kafla wyższą specyficznością (0,2,0), jak w volume-picker. */
.dc-product-hero__thumb:focus-visible {
  border-radius: var(--dc-radius-12);
}

.dc-product-hero__thumb:hover {
  border-color: var(--dc-accent-a50);
}

/* Nacisk — ranga 4 (przycisk ikonowy z tłem): scale + inset-press. */
.dc-product-hero__thumb:active {
  transform: scale(0.97);
  box-shadow: var(--dc-shadow-xs), var(--dc-shadow-inset-press);
}

/* Kafel pośrodku rolki: obwódka a50, pierścień 1 px --dc-border-accent,
   cień --dc-shadow-lg (C.4). Stan niesie aria-pressed, więc selektor jest
   atrybutowy. */
.dc-product-hero__thumb[aria-pressed='true'] {
  border-color: var(--dc-accent-a50);
  box-shadow:
    0 0 0 var(--dc-border) var(--dc-border-accent),
    var(--dc-shadow-lg);
}

.dc-product-hero__thumb-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Kafel packshotu: biel w obu motywach i contain — jak slajd. */
.dc-product-hero__thumb--pack {
  background-color: var(--dc-surface-on-dark);
}

.dc-product-hero__thumb--pack .dc-product-hero__thumb-image {
  object-fit: contain;
}

/* ==========================================================================
   6. WSTĘGA PARAMETRÓW
   Ruch daje komponent .dc-marquee (maska 8/92 % z reviews). Makieta: tło
   rgba(201,168,76,.07) -> --dc-accent-a05, kreska górna line.
   ========================================================================== */
.dc-product-hero__ticker {
  border-block-start: var(--dc-border) solid var(--dc-border-line);
  background-color: var(--dc-accent-a05);
}

/* Pas jest listą: bez punktorów (role="list" + base.css). Komponent daje
   flex, szerokość max-content i przesunięcie; sekcja dokłada wyrównanie. */
.dc-product-hero__track {
  align-items: center;
}

/* Pozycja: gap 9 -> --dc-space-8, padding 14px 22px z makiety; separator
   to kropka 5 px a55 -> --dc-space-6 / a50. */
.dc-product-hero__param {
  display: inline-flex;
  flex: none;
  align-items: center;
  gap: var(--dc-space-8);
  padding: var(--dc-space-14) var(--dc-space-22);
  white-space: nowrap;
}

.dc-product-hero__param::after {
  content: '';
  width: var(--dc-space-6);
  height: var(--dc-space-6);
  margin-inline-start: var(--dc-space-14);
  border-radius: var(--dc-radius-full);
  background-color: var(--dc-accent-a50);
}

/* Gwiazdka: makieta ma ją wypełnioną złotem; rejestr trzyma ikony kreskowe,
   więc zostaje kontur w złocie (uwaga H — rejestr wygrywa). */
.dc-product-hero__param .dc-icon {
  flex: none;
  color: var(--dc-accent);
}

/* Wartość: PJS 800 14 #2A2620 -> display / black / text-md / --dc-text. */
.dc-product-hero__param-value {
  font-family: var(--dc-font-display);
  font-size: var(--dc-text-md);
  font-weight: var(--dc-weight-black);
  color: var(--dc-text);
}

/* Podpis: 11 600 rgba(58,52,42,.55) -> text-xs / medium / --dc-text-subtle
   (makietowa alfa .55 dawała 2,6:1 — token jest ciemniejszy). */
.dc-product-hero__param-label {
  font-size: var(--dc-text-xs);
  font-weight: var(--dc-weight-medium);
  color: var(--dc-text-subtle);
}

/* ==========================================================================
   7. PANEL ZAKUPOWY — OKRUSZKI, OCENA, TYTUŁ, AKAPIT
   Makieta: padding 38px 40px 36px -> --dc-space-40 (reguła 15).
   ========================================================================== */
.dc-product-hero__panel {
  display: flex;
  flex-direction: column;
  min-width: 0;
  padding: var(--dc-space-40);
}

/* Okruszki: 12.5 #9a958a, gap 9, margines 14 -> text-sm / --dc-text-subtle /
   --dc-space-8 / --dc-space-14. Lista bez punktorów (role="list" + base.css). */
.dc-product-hero__crumbs {
  margin-block-end: var(--dc-space-14);
}

.dc-product-hero__crumb-list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--dc-space-8);
  font-size: var(--dc-text-sm);
  color: var(--dc-text-subtle);
}

.dc-product-hero__crumb {
  display: inline-flex;
  align-items: center;
  gap: var(--dc-space-8);
}

/* Ukośnik-separator rysowany ::before, żeby nie mnożyć znaczników.
   Kolor #c9c3b6 z makiety: --dc-text-subtle w połowie krycia (ten sam
   color-mix co pierścień radio niżej — odcień makiety z tokenu). */
.dc-product-hero__crumb + .dc-product-hero__crumb::before {
  content: '/';
  color: color-mix(in srgb, var(--dc-text-subtle) 50%, transparent);
}

/* base.css daje każdemu <a> złoto i podkreślenie — okruszek jest szary
   i bez kreski; najazd kolorem do --dc-text (C.2), w liście transition. */
.dc-product-hero__crumb-link {
  color: var(--dc-text-subtle);
  text-decoration: none;
  transition: color var(--dc-duration-base) var(--dc-ease);
}

.dc-product-hero__crumb-link:hover {
  color: var(--dc-text);
}

/* Bieżąca strona: #161616 600 -> --dc-text / medium. */
.dc-product-hero__crumb-current {
  color: var(--dc-text);
  font-weight: var(--dc-weight-medium);
}

/* Wiersz oceny i dostępności: flex, gap 12, margines 14. */
.dc-product-hero__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--dc-space-8) var(--dc-space-12);
  margin-block-end: var(--dc-space-14);
}

/* Ocena: gap 7 -> 8. Odnośnik bez podkreślenia — podkreślenie ma sama
   liczba opinii. */
.dc-product-hero__rating {
  display: inline-flex;
  align-items: center;
  gap: var(--dc-space-8);
  color: var(--dc-text);
  text-decoration: none;
}

/* Gwiazdki 14 px -> --dc-text-md, gap 2 — kopia .dc-volume-picker__stars. */
.dc-product-hero__stars {
  display: inline-flex;
  gap: var(--dc-space-2);
  font-size: var(--dc-text-md);
  line-height: var(--dc-leading-none);
  color: var(--dc-border-line);
}

.dc-product-hero__star {
  position: relative;
  display: inline-block;
}

.dc-product-hero__star--full {
  color: var(--dc-accent);
}

.dc-product-hero__star-half {
  position: absolute;
  inset-block-start: 0;
  inset-inline-start: 0;
  width: 50%;
  overflow: hidden;
  color: var(--dc-accent);
}

/* 4,9: PJS 800 13.5 -> display / black / text-base. */
.dc-product-hero__rating-value {
  font-family: var(--dc-font-display);
  font-size: var(--dc-text-base);
  font-weight: var(--dc-weight-black);
}

/* „214 opinii": 13 #9a958a z kreską dolną rgba(154,149,138,.4)
   -> text-base / --dc-text-subtle / --dc-border-line. Kolor przejściem,
   bo odnośnik go zmienia na najeździe (C.2: color w liście transition). */
.dc-product-hero__reviews {
  border-block-end: var(--dc-border) solid var(--dc-border-line);
  font-size: var(--dc-text-base);
  color: var(--dc-text-subtle);
  transition: color var(--dc-duration-base) var(--dc-ease);
}

.dc-product-hero__rating:hover .dc-product-hero__reviews {
  color: var(--dc-text);
}

/* Dostępność: 12.5 600 #3e7c59, gap 6 -> text-sm / medium / --dc-success. */
.dc-product-hero__stock {
  display: inline-flex;
  align-items: center;
  gap: var(--dc-space-6);
  margin: 0;
  font-size: var(--dc-text-sm);
  font-weight: var(--dc-weight-medium);
  line-height: var(--dc-leading-snug);
  color: var(--dc-success);
}

.dc-product-hero__stock--out {
  color: var(--dc-text-subtle);
}

/* Kropka 7 px -> --dc-space-8 (C.8: kropka statusu 8 px, --dc-success).
   Czas tętna 2,2 s zapisany wprost: skala czasów motywu ma przejścia
   (0,15–0,45 s) i unoszenie (6–8 s), między nimi nie ma tokenu — ten sam
   przypadek co czasy blobów w calculator.css. */
.dc-product-hero__stock-dot {
  flex: none;
  width: var(--dc-space-8);
  height: var(--dc-space-8);
  border-radius: var(--dc-radius-full);
  background-color: currentColor;
  animation: dcProductHeroPulse 2.2s ease-in-out infinite;
}

/* Tytuł: PJS 800 clamp(28, 3vw, 38) / 1.08 / -.028em, margines 12.
   clamp -> --dc-display-3 (clamp 30 / 3.8vw / 40): różnica 2 px na obu
   końcach mieści się w szumie eksportu (reguła 15). Interlinia 1.08
   -> --dc-leading-tight (1.12), trakt -.028em -> --dc-tracking-tighter,
   text-wrap: balance z makiety. */
.dc-product-hero__title {
  margin-block-end: var(--dc-space-12);
  font-size: var(--dc-display-3);
  line-height: var(--dc-leading-tight);
  letter-spacing: var(--dc-tracking-tighter);
  text-wrap: balance;
}

/* Dopisek marki #9a8230 -> --dc-accent-strong (reguła J: złoty tekst). */
.dc-product-hero__title-tag {
  color: var(--dc-accent-strong);
}

/* Akapit: 15 / 1.65 / #5a5a5a / max-width 520 -> text-lg /
   --dc-leading-relaxed (1.6) / --dc-text-muted / --dc-measure-md (480;
   skala tokenu obejmuje 520). Margines 22 -> --dc-space-22. */
.dc-product-hero__lead {
  max-width: var(--dc-measure-md);
  margin-block-end: var(--dc-space-22);
  font-size: var(--dc-text-lg);
  line-height: var(--dc-leading-relaxed);
  color: var(--dc-text-muted);
  text-wrap: pretty;
}

.dc-product-hero__lead p {
  margin: 0;
}

.dc-product-hero__lead p + p {
  margin-block-start: var(--dc-space-10);
}

/* ==========================================================================
   8. PRZEŁĄCZNIK FRAKCJI — segment na torze, konstrukcja z nagłówka
   Makieta: tor gap 6, padding 6, r18, #ececec -> --dc-surface-sunken,
   margines dolny 20, PEŁNA szerokość panelu (koncept dwukolumnowy tak
   rysuje; makietowe max-width 460 z zestawu tu nie obowiązuje, bo wiersze
   pakietów niżej też idą na pełną szerokość). Segment: padding 11px 14px
   -> --dc-space-12 / --dc-space-14, r13 -> --dc-radius-12 (tor r18 −
   odstęp 6 = 12, C.9 co do piksela).
   ========================================================================== */
.dc-product-hero__fractions {
  display: flex;
  gap: var(--dc-space-6);
  margin-block-end: var(--dc-space-20);
  padding: var(--dc-space-6);
  border-radius: var(--dc-radius-18);
  background-color: var(--dc-surface-sunken);
}

/* Niewybrany: przezroczysty, tekst #9a958a -> --dc-text-subtle. Najazd
   jak .dc-nav__link:hover — tło --dc-surface, tekst --dc-text. */
.dc-product-hero__fraction {
  display: flex;
  flex: 1;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--dc-space-2);
  min-width: 0;
  padding: var(--dc-space-12) var(--dc-space-14);
  border-radius: var(--dc-radius-12);
  color: var(--dc-text-subtle);
  font-family: var(--dc-font-display);
  line-height: var(--dc-leading-tight);
  text-align: center;
  text-decoration: none;
  transition:
    background-color var(--dc-duration-base) var(--dc-ease),
    color var(--dc-duration-base) var(--dc-ease),
    box-shadow var(--dc-duration-base) var(--dc-ease),
    transform var(--dc-duration-fast) var(--dc-ease-out);
}

.dc-product-hero__fraction:focus-visible {
  border-radius: var(--dc-radius-12);
}

.dc-product-hero__fraction:hover {
  background-color: var(--dc-surface);
  color: var(--dc-text);
}

.dc-product-hero__fraction:active {
  transform: scale(0.97);
}

/* Bieżąca frakcja: biel z cieniem 0 2px 8px .1 -> --dc-shadow-sm
   (0 4 12 .08), tekst --dc-text. Segment jest WYPUKŁY (biały kafel
   z cieniem na szarym torze), więc nie inset-press jak w nagłówku. */
.dc-product-hero__fraction[aria-current='page'] {
  background-color: var(--dc-surface);
  color: var(--dc-text);
  box-shadow: var(--dc-shadow-sm);
}

/* Nazwa 800 15 -> black / text-lg; podpis 11.5 600 z kryciem .72
   -> text-xs / medium / --dc-text-subtle zamiast krycia (token trzyma
   próg kontrastu w obu stanach segmentu). */
.dc-product-hero__fraction-name {
  font-size: var(--dc-text-lg);
  font-weight: var(--dc-weight-black);
}

.dc-product-hero__fraction-sub {
  font-family: var(--dc-font-body);
  font-size: var(--dc-text-xs);
  font-weight: var(--dc-weight-medium);
  color: var(--dc-text-subtle);
}

/* ==========================================================================
   9. KOMUNIKATY KOSZYKA — kopia z volume-picker
   ========================================================================== */
.dc-product-hero__notices {
  display: flex;
  flex-direction: column;
  gap: var(--dc-space-10);
  margin-block-end: var(--dc-space-20);
}

.dc-product-hero__notice {
  padding: var(--dc-space-14) var(--dc-space-18);
  border: var(--dc-border) solid var(--dc-border-line);
  border-radius: var(--dc-radius-16);
  background-color: var(--dc-surface);
  font-size: var(--dc-text-md);
  color: var(--dc-text);
  box-shadow: var(--dc-shadow-sm);
}

.dc-product-hero__notice--success {
  border-color: var(--dc-success);
}

.dc-product-hero__notice--error {
  border-color: var(--dc-danger);
}

/* ==========================================================================
   10. WYBÓR PAKIETU
   Makieta: kolumna, gap 9 -> --dc-space-10, margines dolny 22.
   Wiersze są tu GĘSTSZE niż w poprzednim układzie (padding 14/16 zamiast
   18/20, nazwa text-lg zamiast xl, kwota text-xl zamiast 3xl): sześć
   wierszy stoi w jednej kolumnie obok galerii i ich łączna wysokość
   wyznacza wysokość całej karty — to wymiary koncepcyjne z product.html,
   te same, których używa starter-kit-buy dla swoich dwóch wierszy.
   ========================================================================== */

/* Fieldset bez ramki i wcięcia przeglądarki. */
.dc-product-hero__packs {
  display: flex;
  flex-direction: column;
  gap: var(--dc-space-10);
  margin: 0 0 var(--dc-space-22);
  padding: 0;
  border: 0;
  min-inline-size: 0;
}

/* Wiersz nagłówka listy: nadtytuł + podpowiedź, do linii pisma. */
.dc-product-hero__packs-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--dc-space-4) var(--dc-space-12);
}

/* Nadtytuł „WYBIERZ ILOŚĆ" (C.8: 12 / 600 / --dc-tracking-wider; kolor
   z makiety #9a8230 -> --dc-accent-strong, nie --dc-text-subtle z C.8 —
   złoto jest tu etykietą wyboru). */
.dc-product-hero__eyebrow {
  margin: 0;
  font-size: var(--dc-text-sm);
  font-weight: var(--dc-weight-medium);
  line-height: var(--dc-leading-snug);
  letter-spacing: var(--dc-tracking-wider);
  text-transform: uppercase;
  color: var(--dc-accent-strong);
}

/* Podpowiedź „1 paleta = …": 12.5 #9a958a -> text-sm / --dc-text-subtle. */
.dc-product-hero__packs-hint {
  font-size: var(--dc-text-sm);
  color: var(--dc-text-subtle);
}

/* Wiersz: gap 13 -> 14, padding 13px 16px -> --dc-space-14 /
   --dc-space-16, r15 -> --dc-radius-16, tło biel .72
   -> --dc-surface-glass (.86), obwódka 1.5 px rgba(228,226,220,.95)
   -> --dc-border-thick + --dc-border-line. Najazd: obwódka a50;
   uniesienie z makiety pominięte (C.2). Interlinia --dc-leading-tight:
   makieta ma w wierszu `normal`, a body daje 1,6, z którą wiersz rośnie. */
.dc-product-hero__pack {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--dc-space-14);
  padding: var(--dc-space-14) var(--dc-space-16);
  border: var(--dc-border-thick) solid var(--dc-border-line);
  border-radius: var(--dc-radius-16);
  background-color: var(--dc-surface-glass);
  line-height: var(--dc-leading-tight);
  cursor: pointer;
  transition:
    background-color var(--dc-duration-base) var(--dc-ease),
    border-color var(--dc-duration-base) var(--dc-ease),
    box-shadow var(--dc-duration-base) var(--dc-ease);
}

.dc-product-hero__pack:hover {
  border-color: var(--dc-accent-a50);
}

/* Radio ukryte wzrokowo, ale w drzewie i w kolejności fokusu — ta sama
   technika co .dc-sr-only, zapisana tu, bo utility z base.css jest dla
   treści, a to kontrolka (reguła 8: utility bez modyfikacji albo wcale). */
.dc-product-hero__radio {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Zaznaczony: tło a10, obwódka a50, BEZ poświaty 0 8px 22px a16 z makiety
   — C.4: poświata wyłącznie dla rangi 1. */
.dc-product-hero__pack:has(.dc-product-hero__radio:checked) {
  border-color: var(--dc-accent-a50);
  background-color: var(--dc-accent-a10);
}

/* Fokus z klawiatury na radio rysuje pierścień NA WIERSZU — pierścień
   z base.css (2 px --dc-accent-strong, offset 2), z promieniem wiersza. */
.dc-product-hero__pack:has(.dc-product-hero__radio:focus-visible) {
  outline: var(--dc-border-heavy) solid var(--dc-accent-strong);
  outline-offset: var(--dc-focus-offset);
}

/* Wyłączony (za mało worków): jak stan disabled przycisków (C.1). */
.dc-product-hero__pack:has(.dc-product-hero__radio:disabled) {
  border-color: var(--dc-border-line);
  background-color: var(--dc-surface-sunken);
  color: var(--dc-text-subtle);
  cursor: not-allowed;
}

/* Kropka radio 18 px -> --dc-space-18; zaznaczona 5.5 px złota
   -> --dc-space-6. Biel to --dc-surface, żeby w motywie ciemnym kropka
   nie świeciła białym oczkiem. Pierścień niezaznaczonej: makieta #c9c3b6.
   --dc-border-line na bieli jest niewidoczne, a --dc-text-subtle za ciemne;
   color-mix z połową krycia --dc-text-subtle daje odcień makiety
   bez literału. */
.dc-product-hero__dot {
  flex: none;
  width: var(--dc-space-18);
  height: var(--dc-space-18);
  border: var(--dc-border-heavy) solid color-mix(in srgb, var(--dc-text-subtle) 50%, transparent);
  border-radius: var(--dc-radius-full);
  background-color: var(--dc-surface);
  transition: border var(--dc-duration-base) var(--dc-ease);
}

.dc-product-hero__radio:checked + .dc-product-hero__dot {
  border: var(--dc-space-6) solid var(--dc-accent);
}

/* gap 1 -> 2 (skala 2/4). */
.dc-product-hero__pack-main {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--dc-space-2);
  min-width: 0;
}

.dc-product-hero__pack-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--dc-space-8);
}

/* Nazwa pakietu: PJS 800 15 #161616 -> display / black / text-lg. */
.dc-product-hero__pack-name {
  font-family: var(--dc-font-display);
  font-size: var(--dc-text-lg);
  font-weight: var(--dc-weight-black);
  color: var(--dc-text);
}

.dc-product-hero__pack:has(.dc-product-hero__radio:disabled) .dc-product-hero__pack-name,
.dc-product-hero__pack:has(.dc-product-hero__radio:disabled) .dc-product-hero__pack-amount {
  color: var(--dc-text-subtle);
}

/* Flaga („Bestseller", „Na start") — kopia .dc-volume-picker__flag bez
   pozycjonowania (C.8: pełne złoto, bez poświaty; jeden wygląd na rodzaj,
   makietowy tint na niezaznaczonym wierszu odrzucony). Makieta: padding
   3px 9px, 10 / 800 / .05em -> 4 / 8 / --dc-text-2xs / --dc-tracking-wide. */
.dc-product-hero__flag {
  display: inline-flex;
  align-items: center;
  padding: var(--dc-space-4) var(--dc-space-8);
  border-radius: var(--dc-radius-pill);
  background-color: var(--dc-accent);
  color: var(--dc-on-accent);
  font-size: var(--dc-text-2xs);
  font-weight: var(--dc-weight-bold);
  line-height: var(--dc-leading-none);
  letter-spacing: var(--dc-tracking-wide);
  text-transform: uppercase;
  white-space: nowrap;
}

/* Podpis: 12 #9a958a -> text-sm / --dc-text-subtle. */
.dc-product-hero__pack-sub {
  font-size: var(--dc-text-sm);
  color: var(--dc-text-subtle);
}

.dc-product-hero__pack-price {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--dc-space-2);
  margin-inline-start: auto;
  white-space: nowrap;
}

/* Cena wiersza: PJS 800 16 -> display / black / text-xl. */
.dc-product-hero__pack-amount {
  font-family: var(--dc-font-display);
  font-size: var(--dc-text-xl);
  font-weight: var(--dc-weight-black);
  letter-spacing: var(--dc-tracking-tight);
  color: var(--dc-text);
}

/* Cena za kg: 11.5 #9a958a -> text-xs / --dc-text-subtle; na zaznaczonym
   wierszu złoto 700 (to tekst, więc --dc-accent-strong, reguła J).
   Kolor przejściem (C.2). */
.dc-product-hero__pack-unit {
  font-size: var(--dc-text-xs);
  color: var(--dc-text-subtle);
  transition: color var(--dc-duration-base) var(--dc-ease);
}

.dc-product-hero__pack:has(.dc-product-hero__radio:checked) .dc-product-hero__pack-unit {
  font-weight: var(--dc-weight-bold);
  color: var(--dc-accent-strong);
}

/* ==========================================================================
   11. BLOK CENY
   Makieta: wiersz kwoty do linii pisma, gap 10px 14px; pod nim przelicznik
   i porównanie; dalej akcyza, zużycie i dopisek o dostawie — zapis z karty
   „Twój wybór" poprzedniego układu, teraz w kolumnie pod listą.
   ========================================================================== */
.dc-product-hero__price {
  margin-block-end: var(--dc-space-22);
}

.dc-product-hero__amount {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--dc-space-10) var(--dc-space-14);
  margin: 0;
}

/* Kwota: PJS 800 clamp(36, 4.4vw, 46) / 1 / -.03em — clamp z makiety
   DOSŁOWNIE (nagłówek, pkt 5): --dc-display-2 (34/4.4vw/48)
   i --dc-numeral-lg (44 bez clamp) nie trafiają w ten kształt.
   nowrap: wc_price() rozdziela tysiące zwykłą spacją, więc kwota
   łamałaby się po pierwszej cyfrze. */
.dc-product-hero__amount-value {
  white-space: nowrap;
  font-family: var(--dc-font-display);
  font-size: clamp(36px, 4.4vw, 46px);
  font-weight: var(--dc-weight-black);
  line-height: var(--dc-leading-none);
  letter-spacing: var(--dc-tracking-tighter);
  color: var(--dc-text);
}

/* „brutto": 14.5 #5a5a5a -> text-md / --dc-text-muted. */
.dc-product-hero__gross {
  font-size: var(--dc-text-md);
  color: var(--dc-text-muted);
}

/* Przelicznik i linia porównawcza: margines 12, gap 10. */
.dc-product-hero__unit-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--dc-space-10);
  margin: var(--dc-space-12) 0 0;
}

/* Pigułka ceny za kg: padding 6px 11px -> 6 / 12, r9 -> --dc-radius-8,
   tło a16 -> --dc-accent-a15, PJS 800 13 #7c6420 -> display / black /
   text-base / --dc-accent-strong (tag złoty z C.8 w rozmiarze makiety). */
.dc-product-hero__unit {
  display: inline-flex;
  align-items: center;
  padding: var(--dc-space-6) var(--dc-space-12);
  border-radius: var(--dc-radius-8);
  background-color: var(--dc-accent-a15);
  font-family: var(--dc-font-display);
  font-size: var(--dc-text-base);
  font-weight: var(--dc-weight-black);
  line-height: var(--dc-leading-snug);
  color: var(--dc-accent-strong);
  white-space: nowrap;
}

/* Linia porównawcza: 12.5 / 1.4 / #3e7c59 600 -> text-sm / --dc-leading-snug
   / --dc-success / medium. Treść to porównanie jednostkowe, nie procent
   z makiety (decyzja 2026-08-30). */
.dc-product-hero__compare {
  font-size: var(--dc-text-sm);
  font-weight: var(--dc-weight-medium);
  line-height: var(--dc-leading-snug);
  color: var(--dc-success);
}

/* Akcyza: margines i padding 12, kreska górna kreskowana
   rgba(30,40,60,.12) -> --dc-border-line. */
.dc-product-hero__excise {
  margin-block-start: var(--dc-space-12);
  padding-block-start: var(--dc-space-12);
  border-block-start: var(--dc-border) dashed var(--dc-border-line);
}

/* Nota: 12 / 1.5 / #9a958a -> text-sm / --dc-leading-normal / subtle. */
.dc-product-hero__excise-note {
  margin: 0;
  font-size: var(--dc-text-sm);
  line-height: var(--dc-leading-normal);
  color: var(--dc-text-subtle);
}

/* Rozwijak: margines 5 -> 6 (skala 4/6). */
.dc-product-hero__excise-details {
  margin-block-start: var(--dc-space-6);
}

/* Przełącznik: 12 / 600 / #9a8230 -> text-sm / medium / --dc-accent-strong;
   bez znacznika przeglądarki (list-style + ::-webkit-details-marker).
   Grot STOI: to rozwijak, nie odnośnik „dowiedz się więcej", więc
   reguła 22 (grot w ruchu) go nie obejmuje (Andrzej, 2026-08-30). Najazd
   wyłącznie kolorem, do --dc-text (C.2). */
.dc-product-hero__excise-summary {
  display: inline-flex;
  align-items: center;
  gap: var(--dc-space-8);
  list-style: none;
  font-size: var(--dc-text-sm);
  font-weight: var(--dc-weight-medium);
  color: var(--dc-accent-strong);
  cursor: pointer;
  transition: color var(--dc-duration-base) var(--dc-ease);
}

.dc-product-hero__excise-summary::-webkit-details-marker {
  display: none;
}

.dc-product-hero__excise-summary .dc-icon {
  flex: none;
}

.dc-product-hero__excise-summary:hover {
  color: var(--dc-text);
}

/* Wiersz z kwotą: margines 8, padding 9px 12px -> 10 / 12, r11
   -> --dc-radius-12, tło rgba(30,40,60,.045) -> --dc-surface-sunken. */
.dc-product-hero__excise-row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--dc-space-4) var(--dc-space-10);
  margin: var(--dc-space-8) 0 0;
  padding: var(--dc-space-10) var(--dc-space-12);
  border-radius: var(--dc-radius-12);
  background-color: var(--dc-surface-sunken);
}

/* „Z akcyzą": 12.5 #5a5a5a -> text-sm / --dc-text-muted. */
.dc-product-hero__excise-label {
  font-size: var(--dc-text-sm);
  color: var(--dc-text-muted);
}

.dc-product-hero__excise-value {
  display: inline-flex;
  align-items: baseline;
  gap: var(--dc-space-6);
  white-space: nowrap;
}

/* Suma: PJS 800 15 -> display / black / text-lg; dopłata 11.5 #9a958a
   -> text-xs / --dc-text-subtle. */
.dc-product-hero__excise-total {
  font-family: var(--dc-font-display);
  font-size: var(--dc-text-lg);
  font-weight: var(--dc-weight-black);
  color: var(--dc-text);
}

.dc-product-hero__excise-add {
  font-size: var(--dc-text-xs);
  color: var(--dc-text-subtle);
}

/* „25 kg ≈ …": margines górny 12, gap 11 -> 10, padding 14px 15px
   -> 14 / 16, r14 -> --dc-radius-12, tło a10, obwódka a24
   -> --dc-border-accent (a30). Tekst 13.5 / 1.5 / 500 / #3a3428
   -> text-base / --dc-leading-normal / medium / --dc-text-secondary.
   Ikona 17 px -> --dc-accent-strong, przesunięta o 2 w dół do linii pisma.
   min-height na DWA wiersze tekstu: zdanie o palecie ma dwa, o worku
   jeden — bez rezerwy przyciski pod blokiem skakałyby przy zmianie radio
   (Andrzej, 2026-08-30). */
.dc-product-hero__lasts {
  display: flex;
  align-items: flex-start;
  gap: var(--dc-space-10);
  min-height: calc(2 * var(--dc-text-base) * var(--dc-leading-normal) + 2 * var(--dc-space-14) + 2 * var(--dc-border));
  margin: var(--dc-space-12) 0 0;
  padding: var(--dc-space-14) var(--dc-space-16);
  border: var(--dc-border) solid var(--dc-border-accent);
  border-radius: var(--dc-radius-12);
  background-color: var(--dc-accent-a10);
  font-size: var(--dc-text-base);
  font-weight: var(--dc-weight-medium);
  line-height: var(--dc-leading-normal);
  color: var(--dc-text-secondary);
}

.dc-product-hero__lasts .dc-icon {
  flex: none;
  margin-block-start: var(--dc-space-2);
  color: var(--dc-accent-strong);
}

/* Dopisek o dostawie: margines 8, 12.5 / 1.5 / #9a958a -> text-sm /
   --dc-leading-normal / --dc-text-subtle. min-height na jeden wiersz —
   worek i zestaw dopisku nie mają, a wysokość bloku ma stać (j.w.). */
.dc-product-hero__meta-line {
  min-height: calc(var(--dc-text-sm) * var(--dc-leading-normal));
  margin: var(--dc-space-8) 0 0;
  font-size: var(--dc-text-sm);
  line-height: var(--dc-leading-normal);
  color: var(--dc-text-subtle);
}

/* ==========================================================================
   12. PRZYCISKI
   ========================================================================== */

/* RANGA 1 — kopia .dc-volume-picker__submit; z makiety zostaje wysokość
   (padding 18px 28px) i rozmiar pisma 17 -> --dc-text-2xl. Pominięte: pełne
   złoto zamiast tintu, r14, PJS 800, uniesienie — różnice rangi 1 wobec
   makiety, rozstrzygnięte w audycie (C.1, C.2, C.5). */
.dc-product-hero__submit {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--dc-space-8);
  width: 100%;
  padding: var(--dc-space-18) var(--dc-space-28);
  border: var(--dc-border) solid var(--dc-accent-a50);
  border-radius: var(--dc-radius-16);
  background-image: var(--dc-gradient-cta);
  color: var(--dc-on-accent);
  font-size: var(--dc-text-2xl);
  font-weight: var(--dc-weight-bold);
  line-height: var(--dc-leading-none);
  -webkit-backdrop-filter: var(--dc-blur-md);
  backdrop-filter: var(--dc-blur-md);
  box-shadow: var(--dc-shadow-accent), var(--dc-shadow-inset-top);
  transition:
    background-color var(--dc-duration-base) var(--dc-ease),
    box-shadow var(--dc-duration-base) var(--dc-ease),
    transform var(--dc-duration-fast) var(--dc-ease-out);
}

.dc-product-hero__submit .dc-icon {
  flex: none;
}

.dc-product-hero__submit:focus-visible {
  border-radius: var(--dc-radius-16);
}

.dc-product-hero__submit:hover:enabled {
  background-color: var(--dc-accent-a50);
}

.dc-product-hero__submit:active:enabled {
  transform: scale(0.97);
  box-shadow: var(--dc-shadow-accent), var(--dc-shadow-inset-press);
}

.dc-product-hero__submit:disabled {
  border-color: var(--dc-border-line);
  background-color: var(--dc-surface-sunken);
  background-image: none;
  color: var(--dc-text-subtle);
  box-shadow: none;
  cursor: not-allowed;
}

/* Kwota w etykiecie — makietowe „Dodaj do koszyka → 4 359,00 zł". Osobny
   <span> z hidden, bo bez skryptu byłaby nieaktualna po zmianie
   zaznaczenia (nagłówek hero.php). */
.dc-product-hero__submit-amount {
  display: inline-flex;
  align-items: center;
  gap: var(--dc-space-8);
}

/* RANGA 2 — kopia .dc-hero__cta + --secondary; z makiety margines górny 10.
   Makietowe padding 15px 28px / PJS 700 15 ustępują geometrii kopii
   (C.1; skill §0 „nie wymyślaj"). Obwódka --dc-border-line, nie
   --dc-border-subtle jak w kopii: przycisk stoi na jasnej karcie, biała
   obwódka na bieli byłaby niewidoczna (Andrzej, 2026-08-30). */
.dc-product-hero__assistant {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--dc-space-8);
  width: 100%;
  margin-block-start: var(--dc-space-10);
  padding: var(--dc-space-16) var(--dc-space-28);
  border: var(--dc-border) solid var(--dc-border-line);
  border-radius: var(--dc-radius-16);
  background-color: var(--dc-surface-glass);
  color: var(--dc-text);
  font-size: var(--dc-text-lg);
  font-weight: var(--dc-weight-medium);
  line-height: var(--dc-leading-none);
  -webkit-backdrop-filter: var(--dc-blur-sm);
  backdrop-filter: var(--dc-blur-sm);
  transition:
    background-color var(--dc-duration-base) var(--dc-ease),
    border-color var(--dc-duration-base) var(--dc-ease),
    color var(--dc-duration-base) var(--dc-ease),
    box-shadow var(--dc-duration-base) var(--dc-ease),
    transform var(--dc-duration-fast) var(--dc-ease-out);
}

.dc-product-hero__assistant:focus-visible {
  border-radius: var(--dc-radius-16);
}

.dc-product-hero__assistant:hover {
  border-color: var(--dc-surface-inverse);
  background-color: var(--dc-surface-inverse);
  color: var(--dc-surface);
}

.dc-product-hero__assistant:active {
  transform: scale(0.97);
  box-shadow: var(--dc-shadow-inset-press);
}

/* Sygnet 16 px; wysokość z pliku (auto). */
.dc-product-hero__assistant-mark {
  flex: none;
  width: var(--dc-space-16);
  height: auto;
}

/* ==========================================================================
   13. PASEK ZAUFANIA
   Makieta: rząd zawijany, gap 8px 18px, margines górny 18, 12.5 #9a958a
   -> text-sm / --dc-text-subtle; ikony 14 px, gap 6 -> 8. Rząd, nie kolumna
   jak w poprzednim układzie — tak rysuje to koncept dwukolumnowy.
   ========================================================================== */
.dc-product-hero__trust {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--dc-space-8) var(--dc-space-18);
  margin-block-start: var(--dc-space-18);
  font-size: var(--dc-text-sm);
  color: var(--dc-text-subtle);
}

.dc-product-hero__trust-item {
  display: inline-flex;
  align-items: center;
  gap: var(--dc-space-8);
}

.dc-product-hero__trust-item .dc-icon {
  flex: none;
}

/* ==========================================================================
   14. RUCH — tętno kropki dostępności
   Z makiety (dcPulse): krycie .35 -> 1, skala .8 -> 1.12, 2.2 s.
   ========================================================================== */
@keyframes dcProductHeroPulse {
  0%,
  100% {
    opacity: 0.35;
    transform: scale(0.8);
  }

  50% {
    opacity: 1;
    transform: scale(1.12);
  }
}

/* ==========================================================================
   15. SZEROKOŚCI — makieta nie ma wersji wąskiej, progi z pomiaru
   ========================================================================== */

/* PRÓG 970 px — ten sam, który starter-kit-buy zmierzył sweepem dla tego
   samego panelu (nazwa frakcji łamała się w środku wymiaru przy 960 px,
   zaokrąglone w górę do dziesiątki). Potwierdzone sweepem po przebudowie
   (2026-08-31, Groszek, motyw jasny):

     okno    kolumny   panel   segment frakcji   podpowiedź   wiersz „Zestaw"
     1240       2      587 px      1 wiersz       1 wiersz       63 px
     1050       2      492         1              1              63
     1040       2      487         1              1              88  (plakietka pod nazwą)
      971       2      453         1              1              88
      970       1      904         1              1              63

   Jedyne, co się łamie między 971 a 1040 px, to plakietka „Na start"
   schodząca POD nazwę pakietu (nagłówek wiersza 18 → 43 px) — zawinięcie
   flex-wrap, nie błąd rzeczowy, i ZAAKCEPTOWANE: próg 1050 zepchnąłby
   iPada w poziomie (1024 px) do jednej kolumny z obrazem na całą szerokość
   i panelem ekran niżej, a to jest dokładnie objaw, który ta przebudowa
   usuwa. Nazwa frakcji i podpowiedź o palecie trzymają jeden wiersz aż
   do progu.

   Poniżej progu zmieniają się cztery rzeczy: siatka schodzi na jedną
   kolumnę; kreska rozdzielająca przechodzi z prawej krawędzi galerii na
   jej dolną; ROLKA ZMIENIA OŚ — bez panelu obok nie ma z czego wziąć
   wysokości, więc dostaje proporcję 4:3 (jeden slajd) i przesuwa slajdy
   w poziomie, zgodnie z gestem palcem (touch-action: pan-y zostawia
   pionowy ruch przeglądarce); strzałki rozchodzą się na lewą i prawą
   krawędź i obracają o ćwierć obrotu. */
@media (max-width: 970px) {
  .dc-product-hero__inner {
    grid-template-columns: minmax(0, 1fr);
  }

  .dc-product-hero__gallery {
    border-inline-end: 0;
    border-block-end: var(--dc-border) solid var(--dc-border-line);
  }

  .dc-product-hero__reel {
    flex: none;
    aspect-ratio: 4 / 3;
  }

  /* Jeden slajd w oknie, więc ograniczenie „trzy w wysokości" nie
     obowiązuje: szerokość wraca do kolumny minus wcięcie 16. */
  .dc-product-hero__slide {
    inset-inline: var(--dc-space-16);
    width: auto;
    margin-inline: 0;
    transform:
      translate(calc(var(--dc-product-hero-offset, 0) * (100% + var(--dc-space-20))), -50%)
      scale(calc(1 - 0.06 * var(--dc-product-hero-dim, 0)));
  }

  /* Szyna idzie za wcięciem slajdu (16), żeby miniatury dalej stały
     w linii z krawędziami zdjęcia — zmierzone przed poprawką: 4 px
     rozjazdu przy 768 i 390. Minimum kafla wraca do 80: w jednej kolumnie
     szyna ma dość miejsca (768: sześć kafli po 103), a przy 390 minimum 64
     dawałoby rzędy 4 + 2 zamiast 3 + 3 (zmierzone). */
  .dc-product-hero__gallery .dc-product-hero__thumbs {
    grid-template-columns: repeat(auto-fit, minmax(var(--dc-space-80), 1fr));
    padding-inline: var(--dc-space-16);
  }

  .dc-product-hero__steps {
    inset-inline: var(--dc-space-6);
    flex-direction: row;
    justify-content: space-between;
  }

  .dc-product-hero__step--prev .dc-icon {
    transform: rotate(90deg);
  }

  .dc-product-hero__step--next .dc-icon {
    transform: rotate(-90deg);
  }
}

/* Poniżej 480 px cena wiersza schodzi POD nazwę, wyrównana do tekstu
   (wcięcie = kropka 18 + gap 14): obok siebie nazwa „Zestaw testowy
   3 × 25 kg" z plakietką i cena miały przy 390 px za mało miejsca na nazwę
   (zmierzone w poprzednim układzie, wiersz rósł do 133 px). Kwota i cena
   za kg w jednym rzędzie, do linii pisma. Paddingi sumują się (uwaga G):
   kontener 32 + karta 1 + panel 40 = 73 px z każdej strony, czyli 146
   z 390 — panel schodzi na 20. */
@media (max-width: 480px) {
  .dc-product-hero__panel {
    padding: var(--dc-space-20);
  }

  .dc-product-hero__pack {
    flex-wrap: wrap;
    row-gap: var(--dc-space-6);
  }

  .dc-product-hero__pack-price {
    flex-basis: 100%;
    flex-direction: row;
    align-items: baseline;
    gap: var(--dc-space-8);
    margin-inline-start: calc(var(--dc-space-18) + var(--dc-space-14));
  }

  /* „Zapytaj konsultanta AI o ten produkt" łamał się przy 390 px na dwa
     wiersze przez boczny padding 28 (zmierzone w starter-kit-buy). */
  .dc-product-hero__assistant {
    padding-inline: var(--dc-space-16);
  }
}

/* ==========================================================================
   16. RUCH OGRANICZONY
   Blok reduced-motion własny (reguła 12): globalny wyłącznik w base.css
   zamroziłby kropkę w przypadkowej klatce; tu ma stać w pełnym kryciu.
   Rolka: przejazd prowadzi skrypt i sam czyta tę samą preferencję
   (czas 0 s — slajdy przeskakują na miejsce); packshot: czas przejścia 0 s
   odczytuje skrypt i podmienia od razu, bez ducha. Sąsiedni slajd zostaje
   pomniejszony i przyciemniony: to wygląd, nie ruch.
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  .dc-product-hero__stock-dot {
    animation: none;
  }

  .dc-product-hero__slide--near::after,
  .dc-product-hero__image,
  .dc-product-hero__image--ghost,
  .dc-product-hero__image--out,
  .dc-product-hero__image--in {
    transition: none;
    filter: none;
  }
}
