/**
 * product-details.css — pięć zakładek karty produktu: pasek pigułek i jeden
 * panel na zakładkę (opis, specyfikacja, wysyłka, kalkulator, asystent).
 * Makieta: product.html, sekcja product-details.
 *
 * Wymaga tokens.css, base.css i components/ring.css. Dwie zakładki stoją
 * w CAŁOŚCI na cudzych arkuszach i tego pliku nie dotyczą:
 *   - „Oblicz ilość"        -> sections/calculator.css   (.dc-calculator__*),
 *   - „Zapytaj o szczegóły" -> sections/ai-assistant.css (.dc-ai-assistant__*).
 * To nie jest przeoczenie, tylko cel: jeden wygląd, trzy widoki. Wszystkie
 * reguły w tamtych plikach są selektorami JEDNOKLASOWYMI, więc widok
 * wygląda identycznie, gdziekolwiek stoi — sprawdzone przed napisaniem tego
 * pliku. Gdyby któraś z tych zakładek miała się tu różnić, różnicę zapisuje
 * ZMIENNA na rodzicu, a nie kopia reguły (reguła 18).
 *
 * Każdy plik sekcji ładuje się na KAŻDEJ stronie, więc wszystko własne siedzi
 * pod prefiksem .dc-product-details__. Wyjątki: .dc-ring (komponent)
 * i .dc-icon (rejestr) — dostrajane wyłącznie w selektorze potomnym.
 *
 * JEDNA REGUŁA [data-theme='dark'] — znaczek na przykładowym świadectwie,
 * który obie makiety rysują CIEMNY. Nie jest to kolor wpisany z ręki, tylko
 * przełączenie między parą tokenów o zbieżnej wartości; pełne uzasadnienie
 * przy samej regule (sekcja 10) i w decisions.md (2026-08-28, help-cta).
 * Cała reszta kolorów w obu motywach podmienia tokeny (reguła 10).
 *
 * 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. Co z tego wynikło:
 *   - PIGUŁKA ZAKŁADKI to ranga 3 (C.1): promień pigułki zamiast 16,
 *     Inter 600 zamiast Plus Jakarta 700, a wybrana bierze --dc-gradient-cta
 *     z tuszem --dc-on-accent — nie czarne wypełnienie z makiety.
 *     Wybrana NIE MA poświaty: --dc-shadow-accent należy wyłącznie do
 *     rangi 1 (C.4). Kopia wzoru: .dc-volume-picker__tab i .dc-nav__link.
 *   - PRZYCISKI PRZY CERTYFIKACIE to ranga 1 (pobranie) i ranga 2 („jak
 *     czytać") — kopie .dc-volume-picker__submit i .dc-hero__cta--secondary.
 *   - HOVER BEZ UNIESIENIA (C.2): makietowe translateY(-4px) na kaflach
 *     specyfikacji i scale(1.05) na kaflach zdjęć NIE zostały przeniesione.
 *     Poza C.2 nie przeszłyby też reguły 14 — to kafle nieklikalne, więc
 *     reakcja na kursor obiecywałaby interakcję, której nie ma.
 *   - ODNOŚNIK „Zapytaj o termin" wg reguły 22: rusza się sam grot,
 *     obrys stoi.
 *
 * CO JEST TU LICZBĄ, A NIE TOKENEM (reguła 17, punkt 5 — grep ma to znaleźć
 * i te trafienia są świadome):
 *   1. Punkty zatrzymania, środki i kadry (`130% 95% at 50% 12%`, `85%`,
 *      `55%`, `10% center`, `82%`, `56%`, `70%`) — geometria rysunku,
 *      jak w hero.css.
 *   1a. `rgba(var(--dc-shadow-color), …)` w plamie pod packshotem — kanał
 *      barwy z tokenu, literałem jest sama alfa (bez relative color syntax
 *      CSS nie umie dodać alfy do gotowego koloru).
 *   2. WYMIARY Z MAKIETY, KTÓRYCH SCALENIE BYŁOBY WIDAĆ (ta sama decyzja
 *      co w product-hero.css, pkt 5): kadr opisu 420, kafel zdjęcia 250,
 *      scena świadectwa 320, samo świadectwo 250.
 *   3. `rotate(2deg)`, skale i przesunięcia w klatkach
 *      `dcProductDetailsFloat` i `dcProductDetailsKen` — amplituda ruchu
 *      z makiety (dcFloat, dcKen), nie wartości projektowe.
 *
 * Pozostałe scalenia wg reguły 15 stoją przy regułach, których dotyczą.
 */

/* ==========================================================================
   1. RAMA SEKCJI I PASEK ZAKŁADEK

   .dc-product-details nie ma deklaracji: .dc-container i .dc-section
   z base.css dają dokładnie makietowe max-width 1240 / padding 64px 32px
   (reguła 8). Klasa zostaje w znaczniku jako nazwa bloku.
   ========================================================================== */

/* Pasek jest wyśrodkowany jako całość, a pigułki zawijają się w nim same —
   przy 390 px wchodzą w dwa i trzy wiersze. Odstęp do panelu 8 z makiety. */
.dc-product-details__tabs {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--dc-space-4);
  width: fit-content;
  margin-inline: auto;
  margin-block-end: var(--dc-space-8);
  padding: var(--dc-space-6);
  border: var(--dc-border) solid var(--dc-border-subtle);
  border-radius: var(--dc-radius-pill);
  background-color: var(--dc-surface-glass);
  -webkit-backdrop-filter: var(--dc-blur-sm);
  backdrop-filter: var(--dc-blur-sm);

  /* Makietowe 0 8px 26px .1 -> --dc-shadow-lg (0 10 30 .08), plus włosowa
     kreska u góry. Szyna nie jest dzieckiem panelu, więc reguła „dziecko
     stopień niżej" (C.4) jej nie dotyczy. */
  box-shadow: var(--dc-shadow-lg), var(--dc-shadow-inset-top);
}

/* display: flex wygrywa z atrybutem hidden, więc szyna schowana do startu
   skryptu musi mieć to napisane wprost. Ta sama pułapka co przy szynie
   miniatur w product-hero.css. */
.dc-product-details__tabs[hidden] {
  display: none;
}

/* RANGA 3 — pigułka wyboru (C.1). Promień pigułki, Inter 600, rozmiar pisma
   z górnego krańca pasma rangi (14). Padding 12/16 daje wysokość 40 px —
   ZMIERZONE: przy 10/16 wychodziło 36, czyli poniżej pasma rangi (38–42),
   a makietowa pigułka ma 38 (pad 11/20 przy interlinii domyślnej).
   40 to zarazem wysokość .dc-volume-picker__tab, jedynej dziś pigułki
   wyboru w motywie. Makieta: pad 11/20, r16, Plus Jakarta 700 13,5 —
   patrz nagłówek.
   Lista transition zawiera WSZYSTKO, co się zmienia (C.2), łącznie z color
   i tłem obrazkowym stanu wybranego. */
.dc-product-details__tab {
  padding: var(--dc-space-12) var(--dc-space-16);
  border: var(--dc-border) solid var(--dc-border-line);
  border-radius: var(--dc-radius-pill);
  background-color: var(--dc-surface-glass);
  box-shadow: var(--dc-shadow-inset-top);
  color: var(--dc-text-secondary);
  font-family: var(--dc-font-body);
  font-size: var(--dc-text-md);
  font-weight: var(--dc-weight-medium);
  line-height: var(--dc-leading-none);
  white-space: nowrap;
  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),
    transform var(--dc-duration-fast) var(--dc-ease-out);
}

/* base.css daje :focus-visible promień --dc-radius-6, co ścięłoby rogi
   pigułki na czas fokusu. Przywrócenie promienia bije base'a wyższą
   specyficznością (0,2,0 wobec 0,1,0) — nie licząc na kolejność wczytania
   (reguła 8). Ten sam zabieg co w volume-picker i hero. */
.dc-product-details__tab:focus-visible {
  border-radius: var(--dc-radius-pill);
}

/* Najazd tylko na NIEwybraną: wybrana nie ma dokąd się zmienić. Stan niesie
   aria-selected, więc selektor jest atrybutowy — nie ma jak rozjechać
   wyglądu ze stanem ogłaszanym czytnikowi ekranu. */
.dc-product-details__tab[aria-selected='false']:hover {
  border-color: var(--dc-accent-a50);
  background-color: var(--dc-surface);
  color: var(--dc-text);
}

/* Wybrana: --dc-gradient-cta (L tint / D pełne złoto), obwódka a50,
   tusz --dc-on-accent. BEZ poświaty — ta należy do rangi 1 (C.4). */
.dc-product-details__tab[aria-selected='true'] {
  border-color: var(--dc-accent-a50);
  background-image: var(--dc-gradient-cta);
  color: var(--dc-on-accent);
  font-weight: var(--dc-weight-bold);
}

/* Kliknięcie = nacisk; ranga 3 dostaje samo zmniejszenie (C.1). */
.dc-product-details__tab:active {
  transform: scale(0.97);
}

/* ==========================================================================
   2. PANELE

   Odstęp od paska 26 -> --dc-space-24. Bez skryptu panele stoją jeden pod
   drugim (patrz preambuła details.php), więc dostają odstęp między sobą;
   ze skryptem sąsiedztwo znika razem z ukryciem, ale margines i tak byłby
   naliczony sąsiadowi ukrytego elementu — dlatego zeruje go selektor
   z rolą, którą dokłada skrypt.
   ========================================================================== */

.dc-product-details__panel {
  padding-block-start: var(--dc-space-24);
}

.dc-product-details__panel[hidden] {
  display: none;
}

.dc-product-details__panel + .dc-product-details__panel {
  margin-block-start: var(--dc-space-32);
}

.dc-product-details__panel[role='tabpanel'] + .dc-product-details__panel[role='tabpanel'] {
  margin-block-start: 0;
}

/* Wejście panelu po przełączeniu zakładki. Animacja, nie przejście: panel
   wraca z display: none, a przejścia się wtedy nie odpalają. Ruch jest
   minimalny (6 px) i tylko w osi pionowej — treść ma się pojawić, a nie
   przyjechać. Bez skryptu roli nie ma, więc nie ma i animacji. */
@keyframes dcProductDetailsPanelIn {
  from {
    opacity: 0;
    transform: translateY(var(--dc-space-6));
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.dc-product-details__panel[role='tabpanel'] {
  animation: dcProductDetailsPanelIn var(--dc-duration-base) var(--dc-ease-out);
}

/* ==========================================================================
   3. OPIS — karta ze zdjęciem i tekstem

   Karta: r28, tło .5 = --dc-surface-glass-soft co do cyfry, szkło
   blur(20) saturate(165%) = --dc-blur-lg, obwódka biel .7 ->
   --dc-border-subtle, cień 0 16px 50px .09 -> --dc-shadow-xl (0 16 44 .14)
   + inset-top (reguła 13). overflow: hidden przycina zdjęcie do promienia;
   obwódki .dc-ring ta karta nie ma (makieta jej tu nie rysuje), więc nie ma
   też poświaty do obcięcia.
   Siatka: makietowe minmax(340px) -> --dc-grid-min-lg (320); min(…, 100%)
   obowiązkowe jak w base.css, inaczej przy 390 px tor jest szerszy niż karta.
   ========================================================================== */

.dc-product-details__story {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(var(--dc-grid-min-lg), 100%), 1fr));
  overflow: hidden;
  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);
}

/* Kadr 420 z makiety DOSŁOWNIE (nagłówek, pkt 2): o nim decyduje proporcja
   zdjęcia obok kolumny tekstu, a najbliższy token skróciłby je o 20 px. */
.dc-product-details__figure {
  position: relative;
  min-height: 420px;
  overflow: hidden;
}

/* PŁYNNY NAJAZD (makieta: dcKen 22 s ease-in-out). Klatki wprost z makiety
   — skala i przesunięcie to amplituda ruchu, nie wartość projektowa
   (nagłówek, pkt 3). Kadr ma overflow: hidden, więc powiększony obraz nie
   wychodzi poza kartę.

   Czas: calc(--dc-duration-float-slow * 2) = 22 s co do sekundy. Token
   rodziny ruchu ciągłego, nie liczba z głowy: komentarz przy nim mówi
   „duży obraz produktu", a to jest największy obraz w sekcji — tylko
   wolniejszy, bo najazd ma być niezauważalny. */
@keyframes dcProductDetailsKen {
  0%,
  100% {
    transform: scale(1.06) translate(0, 0);
  }

  50% {
    transform: scale(1.15) translate(-2%, 1.5%);
  }
}

.dc-product-details__photo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  animation: dcProductDetailsKen calc(var(--dc-duration-float-slow) * 2) var(--dc-ease) infinite;
}

/* Winieta z makiety: przejaśnienie do prawej krawędzi, żeby styk ze szkłem
   nie był twardą kreską. Punkt zatrzymania to geometria rysunku (nagłówek). */
.dc-product-details__shade {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-image: linear-gradient(90deg, var(--dc-accent-a00) 55%, var(--dc-accent-a15));
}

/* Plakietka złoża. Makieta: r14, pad 10/16, biel .85, obwódka .95,
   cień 0 10px 28px .2 -> --dc-radius-12 / --dc-space-10 / --dc-space-16 /
   --dc-surface-glass / --dc-border-subtle / --dc-shadow-lg. */
.dc-product-details__deposit {
  position: absolute;
  inset-inline-start: var(--dc-space-20);
  inset-block-end: var(--dc-space-20);
  display: inline-flex;
  align-items: center;
  gap: var(--dc-space-8);
  margin: 0;
  padding: var(--dc-space-10) var(--dc-space-16);
  border: var(--dc-border) solid var(--dc-border-subtle);
  border-radius: var(--dc-radius-12);

  /* NIE --dc-surface-glass: to szkło jest BIAŁE w obu motywach (.86 -> .05),
     więc na ciemnej stronie pigułka leżąca na ZDJĘCIU robi się przezroczysta
     i kremowy tekst siada na fotografii — zmierzone 1,27:1. Makieta ma tu
     dwa różne kolory (biel .85 w jasnej, rgba(10,8,5,.62) w ciemnej), czyli
     powierzchnię PRZEŁĄCZANĄ: to jest --dc-surface z alfą, przez color-mix,
     tak jak karta wyniku w calculator.css. Po zmianie 15,4–17,2:1 (jasny)
     i 12,9–14,6:1 (ciemny). */
  background-color: color-mix(in srgb, var(--dc-surface) 88%, transparent);
  -webkit-backdrop-filter: var(--dc-blur-sm);
  backdrop-filter: var(--dc-blur-sm);
  box-shadow: var(--dc-shadow-lg);
  color: var(--dc-text);
  font-size: var(--dc-text-sm);
  font-weight: var(--dc-weight-bold);
  letter-spacing: var(--dc-tracking-wide);
  text-transform: uppercase;
}

.dc-product-details__deposit img {
  display: block;
  width: var(--dc-space-16);
  height: auto;
}

/* Padding clamp(36px, 4vw, 56px) z makiety, złożony z tokenów: 36 -> 32
   (pasmo 32/40), sufit 56 bez scalania. */
.dc-product-details__prose {
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: clamp(var(--dc-space-32), 4vw, var(--dc-space-56));
}

/* ==========================================================================
   4. TYPOGRAFIA WSPÓLNA DLA PANELI
   Nadtytuł: jedna czwórka z audytu (C.8) — 12 / 600 / --dc-tracking-widest,
   --dc-accent-strong (reguła J: makietowe #9a8230 nie daje 4,5:1),
   odstęp do nagłówka 14.
   ========================================================================== */

.dc-product-details__eyebrow {
  margin: 0 0 var(--dc-space-14);
  color: var(--dc-accent-strong);
  font-size: var(--dc-text-sm);
  font-weight: var(--dc-weight-medium);
  letter-spacing: var(--dc-tracking-widest);
  text-transform: uppercase;
}

/* Makietowe clamp(26px, 3vw, 36px) i clamp(28px, 3.4vw, 38px) wpadają
   w pasmo --dc-display-4 i --dc-display-3; oba nagłówki paneli biorą
   --dc-display-3, bo są nagłówkami PANELU, nie karty. Interlinia 1,12
   zawsze przy nagłówku wielowierszowym (C.10). Odstęp do akapitu 14 (C.10;
   makieta 18). */
.dc-product-details__heading {
  margin: 0 0 var(--dc-space-14);
  color: var(--dc-text);
  font-family: var(--dc-font-display);
  font-size: var(--dc-display-3);
  font-weight: var(--dc-weight-black);
  line-height: var(--dc-leading-tight);
  letter-spacing: var(--dc-tracking-tight);
  text-wrap: balance;
}

/* Nagłówek bloku wewnątrz panelu (certyfikat) — makietowe
   clamp(22px, 2.4vw, 30px) = --dc-display-5 co do pasma. */
.dc-product-details__heading--sm {
  font-size: var(--dc-display-5);
}

/* Akapit wiodący: 15,5 -> --dc-text-lg, interlinia 1,7 ->
   --dc-leading-relaxed (1,6), szerokość wiersza --dc-measure-lg. */
.dc-product-details__lead {
  max-width: var(--dc-measure-lg);
  margin: 0 0 var(--dc-space-24);
  color: var(--dc-text-muted);
  font-size: var(--dc-text-lg);
  line-height: var(--dc-leading-relaxed);
}

.dc-product-details__lead > :last-child {
  margin-block-end: 0;
}

/* ==========================================================================
   5. OPIS — cztery punkty ze studzienkami
   Studzienka wg C.8: 40 px, r --dc-radius-12, a15 + 1px a30, ikona 20 px
   --dc-accent-strong (makieta: 38 px, r11, a14 + a30, ikona 18 px #9a8230).
   ========================================================================== */

.dc-product-details__points {
  display: flex;
  flex-direction: column;
  gap: var(--dc-space-14);
  margin: 0;
}

.dc-product-details__point {
  display: flex;
  align-items: flex-start;
  gap: var(--dc-space-12);
}

.dc-product-details__well {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  width: var(--dc-space-40);
  height: var(--dc-space-40);
  border: var(--dc-border) solid var(--dc-accent-a30);
  border-radius: var(--dc-radius-12);
  background-color: var(--dc-accent-a15);
  color: var(--dc-accent-strong);
}

/* Duża studzienka — 48 px z makiety, promień z pomiaru audytu (partia 6:
   „48 = r12"), nie z pasma dużej studzienki C.8 (56 / r16). */
.dc-product-details__well--lg {
  width: var(--dc-space-48);
  height: var(--dc-space-48);
}

/* Treść punktu: 14,5 -> --dc-text-md, interlinia 1,55 = --dc-leading-normal
   co do cyfry. Etykieta (pierwsze zdanie) tuszem --dc-text. */
.dc-product-details__point-text {
  color: var(--dc-text-secondary);
  font-size: var(--dc-text-md);
  line-height: var(--dc-leading-normal);
}

.dc-product-details__point-label {
  color: var(--dc-text);
  font-weight: var(--dc-weight-bold);
}

/* ==========================================================================
   6. OPIS — trzy kafle ze zdjęciami

   Siatka: makietowe minmax(240px) -> --dc-grid-min-sm (220). Kafel 250
   z makiety dosłownie (nagłówek, pkt 2), promień 20 -> --dc-radius-22,
   cień 0 12px 32px .12 -> --dc-shadow-lg.
   ========================================================================== */

.dc-product-details__tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(var(--dc-grid-min-sm), 100%), 1fr));
  gap: var(--dc-space-18);
  margin: var(--dc-space-18) 0 0;
}

.dc-product-details__tile {
  position: relative;
  height: 250px;
  overflow: hidden;
  border-radius: var(--dc-radius-22);
  box-shadow: var(--dc-shadow-lg);
}

/* Dwa tryby z makiety: fotografia wypełnia kafel, packshot na bieli stoi
   na jasnym podkładzie i mieści się w całości. Ten sam podział co na scenie
   w product-hero. Środek i zatrzymanie gradientu — geometria (nagłówek). */
.dc-product-details__tile--contain {
  background-image: radial-gradient(130% 95% at 50% 12%, var(--dc-surface), var(--dc-surface-sunken) 85%);
}

/* PACKSHOT Z BIBLIOTEKI TO JPEG NA BIELI, NIE WYCINANKA.
   Pliki motywu (worek.png, pallet.png) mają kanał alfa, więc leżą na
   podkładzie kafla, a drop-shadow niżej idzie po kształcie worka. Zdjęcia
   z biblioteki mediów niosą własne, nieprzezroczyste tło — zmierzone:
   254,254,254 i 255,255,255 w każdym rogu. Na ciemnym podkładzie rysowało
   ono biały prostokąt pośrodku kafla, a cień obrysowywał ten prostokąt
   zamiast worka.

   Lekarstwo to ten sam zabieg, który stosuje już .dc-product-hero__thumb--pack:
   podkład BIAŁY W OBU MOTYWACH. --dc-surface-on-dark jest do tego stworzony
   i z założenia się nie przełącza (decisions.md, 2026-08-30), więc biel
   zdjęcia i biel kafla są jedną płaszczyzną, a granicy nie widać.
   Cień schodzi: na nieprzezroczystym prostokącie nie ma czego obrysować. */
.dc-product-details__tile--contain.dc-product-details__tile--photo {
  background-image: none;
  background-color: var(--dc-surface-on-dark);
}

.dc-product-details__tile--contain.dc-product-details__tile--photo .dc-product-details__tile-image {
  filter: none;
}

.dc-product-details__tile--cover .dc-product-details__tile-image {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;

  /* Kadr z makiety: środek przesunięty w lewo, żeby bryły węgla nie uciekały
     pod podpis. Punkt kadrowania to geometria rysunku (nagłówek). */
  object-fit: cover;
  object-position: 10% center;
}

/* Packshot stoi NA DNIE kafla, nie w jego środku — makieta: wysokość 205
   z 250 (czyli 82%) i 10 px do dolnej krawędzi. Wyśrodkowanie w pionie
   odrywałoby worek od podłoża, na którym leży jego cień. */
.dc-product-details__tile--contain .dc-product-details__tile-image {
  position: absolute;
  inset-inline-start: 50%;
  inset-block-end: var(--dc-space-10);
  width: auto;
  max-width: calc(100% - 2 * var(--dc-space-16));
  height: 82%;
  object-fit: contain;
  transform: translateX(-50%);

  /* drop-shadow, a nie box-shadow: box-shadow obrysowałby PROSTOKĄT obrazu,
     a drop-shadow idzie po kanale alfa, czyli po kształcie worka (ten sam
     zapis co w hero.css i volume-picker.css). Makietowe 0 10px 18px .18
     -> --dc-shadow-lg. */
  filter: drop-shadow(var(--dc-shadow-lg));
}

/* Plama pod packshotem — makieta rysuje ją osobnym <div>. Tu pseudoelement:
   warstwa bez treści nie potrzebuje znacznika (reguła 18 mówi to samo
   o warstwach, które NIE są konfiguracją wystąpienia). Szerokość 56%,
   wysokość 20 i rozmycie 8 z makiety; kanał barwy z tokenu, literałem jest
   sama alfa (nagłówek).

   ::before, NIE ::after, i ani jednego z-index — wszystkie trzy warstwy
   kafla są pozycjonowane z `z-index: auto`, więc malują się w kolejności
   drzewa: pseudoelement, zdjęcie, podpis. ::after kładłoby plamę NA
   zdjęciu, a ratowanie tego z-indeksem podniosłoby zdjęcie nad podpis —
   zmierzone: podpis na packshocie schodził wtedy do 1,56:1, bo pigułkę
   zasłaniał worek. Kolejność drzewa załatwia to bez ani jednej warstwy. */
.dc-product-details__tile--contain::before {
  content: '';
  position: absolute;
  inset-inline-start: 50%;
  inset-block-end: var(--dc-space-16);
  width: 56%;
  height: var(--dc-space-20);
  background-image: radial-gradient(ellipse, rgba(var(--dc-shadow-color), 0.16), rgba(var(--dc-shadow-color), 0) 70%);
  filter: blur(var(--dc-space-8));
  transform: translateX(-50%);
}

/* Podpis: pigułka .88 na --dc-surface (patrz uzasadnienie przy
   .dc-product-details__deposit — ta sama pigułka na zdjęciu, ten sam
   powód), 11,5 -> --dc-text-xs, pad 7/13 -> --dc-space-6 / --dc-space-12. */
.dc-product-details__tile-caption {
  position: absolute;
  inset-inline-start: var(--dc-space-14);
  inset-block-end: var(--dc-space-14);
  display: inline-flex;
  padding: var(--dc-space-6) var(--dc-space-12);
  border-radius: var(--dc-radius-pill);
  background-color: color-mix(in srgb, var(--dc-surface) 88%, transparent);
  -webkit-backdrop-filter: var(--dc-blur-sm);
  backdrop-filter: var(--dc-blur-sm);
  box-shadow: var(--dc-shadow-sm);
  color: var(--dc-text);
  font-size: var(--dc-text-xs);
  font-weight: var(--dc-weight-bold);
}

/* ==========================================================================
   7. OPIS — pasek czterech liczb

   Treść opisuje FIRMĘ, nie produkt — ta sama co w home/about.php (TODO
   w details.php). Makieta: r20, pad 26/30, biel .62, obwódka .85,
   cień 0 8px 26px .07 + inset. Siatka minmax(200px) -> --dc-grid-min-sm.

   SELEKTOR ZŁOŻONY (.dc-product-details .dc-product-details__facts, 0,2,0),
   a nie sama klasa (0,1,0): base.css zeruje padding regułą
   `ul[role='list']` o specyficzności 0,1,1, która wygrywa z pojedynczą
   klasą. Bez tego pasek stoi z padding: 0 — zmierzone: wysokość 69 px
   zamiast makietowych 123, a tekst dochodzi do samego zaokrąglenia
   i pasek wygląda na ucięty (zgłoszenie Andrzeja, 2026-08-30).
   Ta sama pułapka i ten sam zapis co .dc-nav .dc-nav__list w header.css;
   margines przechodzi, bo jego reset stoi w base.css na 0,0,1.
   Padding 26/30 -> --dc-space-28 w obu kierunkach (pasmo 24/28/32).
   ========================================================================== */

.dc-product-details .dc-product-details__facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(var(--dc-grid-min-sm), 100%), 1fr));
  gap: var(--dc-space-20) var(--dc-space-28);
  margin: var(--dc-space-18) 0 0;
  padding: var(--dc-space-28);
  border: var(--dc-border) solid var(--dc-border-subtle);
  border-radius: var(--dc-radius-22);
  background-color: var(--dc-surface-glass-soft);
  box-shadow: var(--dc-shadow-lg), var(--dc-shadow-inset-top);
}

/* Kreska 2 px złota .5: --dc-border-heavy, bo tylko grubość całopikselowa
   czyta się jako wyróżnienie (uwaga do reguły 19). */
.dc-product-details__fact {
  display: flex;
  flex-direction: column;
  gap: var(--dc-space-4);
  border-inline-start: var(--dc-border-heavy) solid var(--dc-accent-a50);
  padding-inline-start: var(--dc-space-16);
}

/* Liczba nie jest nagłówkiem: pod nią stoi dopowiedzenie, nie treść, którą
   zapowiada (reguła 6 — warunek reguły 20 nie zachodzi). */
.dc-product-details__fact-value {
  color: var(--dc-text);
  font-family: var(--dc-font-display);
  font-size: var(--dc-text-4xl);
  font-weight: var(--dc-weight-black);
  letter-spacing: var(--dc-tracking-snug);
  line-height: var(--dc-leading-tight);
}

.dc-product-details__fact-label {
  color: var(--dc-text-muted);
  font-size: var(--dc-text-base);
  line-height: var(--dc-leading-normal);
}

/* ==========================================================================
   8. SPECYFIKACJA — panel z obwódką i sześć kafli

   Panel: r28, pad 44 -> --dc-space-48, tło .46 -> --dc-surface-glass-soft,
   obwódka .65 -> --dc-border-subtle, cień 0 12px 44px .08 -> --dc-shadow-xl
   + inset-top. position + isolation wymagane przez ring.css; overflow
   ZOSTAJE POZA panelem, bo poświata obwódki leży 4 px za obrysem
   (design-audit.md, partia 6) — nic tu do przycięcia nie ma.
   ========================================================================== */

.dc-product-details__spec {
  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 2 z rejestru w components/ring.css:
     start o 2/12 obrotu (60°), parzysty = w prawo. Numer nosi `about` —
     sekcja wyłącznie strony głównej, która z kartą produktu nigdy nie stoi
     razem (ten sam wybór co przy product-hero, które wzięło 4 po `origin`).
     Dwa pozostałe panele tej sekcji fazy nie deklarują: biorą ją razem
     z klasą gospodarza — kalkulator numer 11, asystent 8. */
  --dc-ring-delay: calc(var(--dc-duration-ring) * -2 / 12);
}

/* Treść nad warstwami obwódki — z-index, bo .dc-ring ma własny z komponentu. */
.dc-product-details__spec-inner {
  position: relative;
  z-index: var(--dc-z-raised);
  padding: var(--dc-space-48);
}

/* Makietowy odstęp do siatki 36 -> --dc-space-32. */
.dc-product-details__spec-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--dc-space-24);
  margin-block-end: var(--dc-space-32);
}

.dc-product-details__spec-head .dc-product-details__heading {
  margin-block-end: 0;
}

/* Plakietka zielona — jedyne miejsce w sekcji, gdzie kolor niesie znaczenie
   inne niż złoto. Alfy przez color-mix, bo drabinki alfy dla zieleni
   w tokenach nie ma i nie powstaje dla jednego użycia (reguła 15).
   Makieta: rgba(62,124,89,.08) / .25, tekst #3e7c59 — --dc-success. */
.dc-product-details__seal {
  display: inline-flex;
  align-items: center;
  gap: var(--dc-space-8);
  margin: 0;
  padding: var(--dc-space-10) var(--dc-space-18);
  border: var(--dc-border) solid color-mix(in srgb, var(--dc-success) 25%, transparent);
  border-radius: var(--dc-radius-12);
  background-color: color-mix(in srgb, var(--dc-success) 8%, transparent);
  color: var(--dc-success);
  font-size: var(--dc-text-base);
  font-weight: var(--dc-weight-bold);
}

/* Siatka kafli: makietowe minmax(280px) trafia w --dc-grid-min-md
   co do piksela. */
.dc-product-details__specs {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(var(--dc-grid-min-md), 100%), 1fr));
  gap: var(--dc-space-16);
  margin: 0;
}

/* Kafel: r18, pad 24/22, tło .72 -> --dc-surface-glass (.86; pasmo .5/.86),
   obwódka .9 -> --dc-border-subtle, cień 0 10px 30px .08 = --dc-shadow-lg
   co do cyfry — i o stopień niżej niż panel (C.4). BEZ najazdu: kafel nie
   jest klikalny (nagłówek pliku). */
.dc-product-details__spec-card {
  display: flex;
  flex-direction: column;
  padding: var(--dc-space-24) var(--dc-space-22);
  border: var(--dc-border) solid var(--dc-border-subtle);
  border-radius: var(--dc-radius-18);
  background-color: var(--dc-surface-glass);
  box-shadow: var(--dc-shadow-lg), var(--dc-shadow-inset-top);
}

/* Nadtytuł KARTY, nie sekcji: 12 / 600 / --dc-tracking-wider,
   --dc-text-subtle, odstęp do treści 8 (C.8). Makieta: 11,5 / 700 / .1em
   w odcieniu #9a958a, który tokens.css odrzucił przy --dc-text-subtle. */
.dc-product-details__spec-label {
  margin-block-end: var(--dc-space-8);
  color: var(--dc-text-subtle);
  font-size: var(--dc-text-sm);
  font-weight: var(--dc-weight-medium);
  letter-spacing: var(--dc-tracking-wider);
  text-transform: uppercase;
}

/* Liczba: 30 = --dc-numeral-sm co do piksela; interlinia 1 i trakt -0,02em
   trafiają w --dc-leading-none i --dc-tracking-tight co do znaku. */
.dc-product-details__spec-value {
  color: var(--dc-text);
  font-family: var(--dc-font-display);
  font-size: var(--dc-numeral-sm);
  font-weight: var(--dc-weight-black);
  line-height: var(--dc-leading-none);
  letter-spacing: var(--dc-tracking-tight);
}

/* Dopisek: 12,5 -> --dc-text-sm, złoty tekst bierze --dc-accent-strong
   (reguła J). Odstęp 5 -> --dc-space-6. */
.dc-product-details__spec-note {
  margin-block-start: var(--dc-space-6);
  color: var(--dc-accent-strong);
  font-size: var(--dc-text-sm);
  font-weight: var(--dc-weight-bold);
}

/* Pasek jest ILUSTRACJĄ bez skali (TODO w details.php) — stąd aria-hidden
   w znacznikach i zero semantyki miernika tutaj. Wysokość 5 -> --dc-space-6,
   tor rgba(0,0,0,.07) -> --dc-surface-sunken, wypełnienie gradientem
   #C9A84C -> #e8cf8a = --dc-gradient-gold. */
.dc-product-details__bar {
  display: block;
  overflow: hidden;
  height: var(--dc-space-6);
  margin-block-start: var(--dc-space-14);
  border-radius: var(--dc-radius-pill);
  background-color: var(--dc-surface-sunken);
}

.dc-product-details__bar-fill {
  display: block;
  width: var(--dc-product-details-bar, 100%);
  height: 100%;
  border-radius: inherit;
  background-image: var(--dc-gradient-gold);
}

/* ==========================================================================
   9. SPECYFIKACJA — blok certyfikatu

   Makieta: r24 -> --dc-radius-22, tło .62 -> --dc-surface-glass-soft,
   obwódka .85 -> --dc-border-subtle, cień 0 16px 44px .12 = --dc-shadow-xl
   co do cyfry + inset. Siatka minmax(300px) -> --dc-grid-min-md (280).
   ========================================================================== */

.dc-product-details__cert {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(var(--dc-grid-min-md), 100%), 1fr));
  overflow: hidden;
  margin-block-start: var(--dc-space-24);
  border: var(--dc-border) solid var(--dc-border-subtle);
  border-radius: var(--dc-radius-22);
  background-color: var(--dc-surface-glass-soft);
  box-shadow: var(--dc-shadow-xl), var(--dc-shadow-inset-top);
}

/* Padding clamp(30px, 4vw, 48px) z makiety, złożony z tokenów. */
.dc-product-details__cert-text {
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: clamp(var(--dc-space-28), 4vw, var(--dc-space-48));
}

.dc-product-details__cert-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--dc-space-12);
  margin: 0;
}

/* RANGA 1 — kopia .dc-volume-picker__submit (C.1): --dc-gradient-cta,
   1px a50, poświata --dc-shadow-accent, --dc-shadow-inset-top, tusz
   --dc-on-accent, r16, Inter 700 15. Ikona bierze --dc-on-accent razem
   z tekstem (currentColor w rejestrze), co naprawia kontrast z C.3. */
.dc-product-details__download {
  display: inline-flex;
  align-items: center;
  gap: var(--dc-space-8);
  padding: var(--dc-space-14) var(--dc-space-24);
  border: var(--dc-border) solid var(--dc-accent-a50);
  border-radius: var(--dc-radius-16);
  background-image: var(--dc-gradient-cta);
  box-shadow: var(--dc-shadow-accent), var(--dc-shadow-inset-top);
  color: var(--dc-on-accent);
  font-family: var(--dc-font-body);
  font-size: var(--dc-text-lg);
  font-weight: var(--dc-weight-bold);
  line-height: var(--dc-leading-none);
  transition:
    background-color var(--dc-duration-base) var(--dc-ease),
    border-color var(--dc-duration-base) var(--dc-ease),
    transform var(--dc-duration-fast) var(--dc-ease-out);
}

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

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

/* RANGA 2 — kopia .dc-hero__cta--secondary (C.1): szkło, 1px
   --dc-border-line, bez cienia, tusz --dc-text, r16, Inter 600, ta sama
   wysokość co ranga 1 obok. */
.dc-product-details__howto {
  display: inline-flex;
  align-items: center;
  padding: var(--dc-space-14) var(--dc-space-22);
  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-family: var(--dc-font-body);
  font-size: var(--dc-text-md);
  font-weight: var(--dc-weight-medium);
  line-height: var(--dc-leading-none);
  text-decoration: none;
  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),
    transform var(--dc-duration-fast) var(--dc-ease-out);
}

.dc-product-details__howto:hover {
  border-color: var(--dc-accent-a50);
  background-color: var(--dc-surface);
  color: var(--dc-text);
}

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

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

/* ==========================================================================
   10. SPECYFIKACJA — przykładowe świadectwo

   Ilustracja, nie dane (TODO w details.php). Scena 320 i karta 250
   z makiety dosłownie (nagłówek, pkt 2).
   ========================================================================== */

.dc-product-details__cert-stage {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 320px;
  padding: var(--dc-space-32);
  background-image: radial-gradient(130% 95% at 50% 12%, var(--dc-surface), var(--dc-surface-sunken) 85%);
}

/* Unoszenie z makiety (dcFloat 8 s): to plakietka dekoracyjna, nie karta
   z wynikiem do kliknięcia — w odróżnieniu od karty kalkulatora, której
   ruch świadomie zdjęto (decisions.md 2026-08-29). Amplituda i obrót
   z makiety (nagłówek, pkt 3). */
@keyframes dcProductDetailsFloat {
  0%,
  100% {
    transform: rotate(2deg) translateY(0);
  }

  50% {
    transform: rotate(2deg) translateY(calc(-1 * var(--dc-space-10)));
  }
}

.dc-product-details__sample {
  display: flex;
  flex-direction: column;
  width: 250px;
  margin: 0;
  padding: var(--dc-space-22);
  border-radius: var(--dc-radius-12);
  background-color: var(--dc-surface);
  box-shadow: var(--dc-shadow-2xl);
  transform: rotate(2deg);
  animation: dcProductDetailsFloat var(--dc-duration-float) var(--dc-ease) infinite;
}

.dc-product-details__sample-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-block-end: var(--dc-space-14);
}

.dc-product-details__sample-lab {
  color: var(--dc-text);
  font-size: var(--dc-text-3xs);
  font-weight: var(--dc-weight-black);
  letter-spacing: var(--dc-tracking-wider);
}

/* Znaczek: kwadrat CIEMNY W OBU MOTYWACH ze złotym ptaszkiem — obie makiety
   mają tu ten sam `#0e0e0e` z `#C9A84C`. Żaden pojedynczy token nie jest
   ciemny w obu motywach, ale para --dc-surface-inverse (jasny) /
   --dc-surface (ciemny) daje jedno i to samo `#1C1A17` — ten sam zabieg
   i to samo uzasadnienie co panel help-cta (decisions.md 2026-08-28).
   To JEDYNA reguła [data-theme='dark'] w tym pliku i pozornie tylko łamie
   regułę 10: przełącza między dwoma prawdziwymi tokenami o zbieżnej
   wartości, a nie wpisuje koloru. Złoto ptaszka jest niepodmieniane między
   motywami (tokens.css, sekcja 11), więc nie potrzebuje pary. */
.dc-product-details__sample-check {
  display: flex;
  align-items: center;
  justify-content: center;
  width: var(--dc-space-22);
  height: var(--dc-space-22);
  border-radius: var(--dc-radius-6);
  background-color: var(--dc-surface-inverse);
  color: var(--dc-accent);
}

[data-theme='dark'] .dc-product-details__sample-check {
  background-color: var(--dc-surface);
}

.dc-product-details__sample-kind {
  margin-block-end: var(--dc-space-2);
  color: var(--dc-text-subtle);
  font-size: var(--dc-text-3xs);
  letter-spacing: var(--dc-tracking-wider);
  text-transform: uppercase;
}

.dc-product-details__sample-batch {
  margin-block-end: var(--dc-space-12);
  color: var(--dc-text);
  font-family: var(--dc-font-display);
  font-size: var(--dc-text-base);
  font-weight: var(--dc-weight-black);
}

.dc-product-details__sample-row {
  display: flex;
  justify-content: space-between;
  gap: var(--dc-space-8);
  padding-block: var(--dc-space-6);
  border-block-end: var(--dc-border) solid var(--dc-border-line);
  color: var(--dc-text-muted);
  font-size: var(--dc-text-2xs);
}

.dc-product-details__sample-row:last-of-type {
  border-block-end: 0;
}

.dc-product-details__sample-figure {
  color: var(--dc-text);
  font-family: var(--dc-font-display);
  font-weight: var(--dc-weight-black);
}

.dc-product-details__sample-foot {
  display: flex;
  align-items: center;
  gap: var(--dc-space-6);
  margin-block-start: var(--dc-space-12);
  color: var(--dc-text-subtle);
  font-size: var(--dc-text-3xs);
}

.dc-product-details__sample-foot img {
  display: block;
  width: var(--dc-space-12);
  height: auto;
}

/* ==========================================================================
   11. WYSYŁKA — trzy kafle i pasek kosztów

   Kafle: siatka minmax(280px) = --dc-grid-min-md, r20 -> --dc-radius-22,
   pad 30 -> --dc-space-32, tło .72 -> --dc-surface-glass, cień
   0 10px 30px .08 = --dc-shadow-lg co do cyfry.
   ========================================================================== */

.dc-product-details__ships {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(var(--dc-grid-min-md), 100%), 1fr));
  gap: var(--dc-space-18);
  margin: 0 0 var(--dc-space-20);
}

.dc-product-details__ship {
  padding: var(--dc-space-32);
  border: var(--dc-border) solid var(--dc-border-subtle);
  border-radius: var(--dc-radius-22);
  background-color: var(--dc-surface-glass);
  box-shadow: var(--dc-shadow-lg), var(--dc-shadow-inset-top);
}

.dc-product-details__ship .dc-product-details__well {
  margin-block-end: var(--dc-space-16);
}

/* Tytuł kafla JEST nagłówkiem (reguła 20): pod nim stoi treść, którą
   zapowiada, a panel ma własny nagłówek nadrzędny. 17 = --dc-text-2xl. */
.dc-product-details__ship-title {
  margin: 0 0 var(--dc-space-8);
  color: var(--dc-text);
  font-family: var(--dc-font-display);
  font-size: var(--dc-text-2xl);
  font-weight: var(--dc-weight-bold);
  line-height: var(--dc-leading-tight);
}

.dc-product-details__ship-text {
  margin: 0;
  color: var(--dc-text-muted);
  font-size: var(--dc-text-md);
  line-height: var(--dc-leading-relaxed);
}

/* Pasek kosztów: r18, pad 20/24, tło .62 -> --dc-surface-glass-soft,
   cień 0 6px 22px .06 -> --dc-shadow-sm. */
.dc-product-details__costs {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--dc-space-14);
  padding: var(--dc-space-20) var(--dc-space-24);
  border: var(--dc-border) solid var(--dc-border-subtle);
  border-radius: var(--dc-radius-18);
  background-color: var(--dc-surface-glass-soft);
  box-shadow: var(--dc-shadow-sm);
}

.dc-product-details__costs-text {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: var(--dc-space-2);
  min-width: var(--dc-grid-min-sm);
  margin: 0;
}

.dc-product-details__costs-title {
  color: var(--dc-text);
  font-family: var(--dc-font-display);
  font-size: var(--dc-text-md);
  font-weight: var(--dc-weight-bold);
}

.dc-product-details__costs-line {
  color: var(--dc-text-muted);
  font-size: var(--dc-text-base);
  line-height: var(--dc-leading-normal);
}

.dc-product-details__costs-line strong {
  color: var(--dc-text);
}

/* ODNOŚNIK Z GROTEM — reguła 22: gap 8 -> 14 na najeździe, a ikona dostaje
   ujemny margines o różnicę gapów, więc obrys ma stałą szerokość
   i podkreślenie stoi. Kreska dolna 2 px złota (C.1, „linki z grotem"). */
.dc-product-details__ask {
  display: inline-flex;
  align-items: center;
  gap: var(--dc-space-8);
  padding-block-end: var(--dc-space-2);
  border-block-end: var(--dc-border-heavy) solid var(--dc-accent);
  color: var(--dc-text);
  font-family: var(--dc-font-body);
  font-size: var(--dc-text-lg);
  font-weight: var(--dc-weight-bold);
  text-decoration: none;
  white-space: nowrap;
  transition: gap var(--dc-duration-base) var(--dc-ease);
}

.dc-product-details__ask .dc-icon {
  transition: margin-inline-end var(--dc-duration-base) var(--dc-ease);
}

.dc-product-details__ask:hover {
  gap: var(--dc-space-14);
  color: var(--dc-text);
}

.dc-product-details__ask:hover .dc-icon {
  margin-inline-end: calc(var(--dc-space-8) - var(--dc-space-14));
}

/* ==========================================================================
   12. BEZRUCH (reguła 12)

   Globalny wyłącznik z base.css tnie CZAS animacji do 0,01 ms, co dla
   wejścia panelu znaczy „natychmiast" — i o to chodzi. Ale dla unoszenia
   świadectwa znaczyłoby „doskocz do końca i stój", czyli zamrożenie
   w przypadkowej klatce. Dlatego `animation: none` na samym świadectwie:
   skrót zeruje animation-name, którego globalny !important nie obejmuje.
   Karta zostaje w spoczynku, z obrotem z makiety.
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  /* Zdjęcie zatrzymuje się na klatce 0%/100%, czyli tam, gdzie najazd i tak
     spędza większość czasu — kadr wygląda jak w spoczynku, a nie jak
     stopklatka w połowie zbliżenia. */
  .dc-product-details__photo {
    animation: none;
    transform: scale(1.06);
  }

  .dc-product-details__sample {
    animation: none;
    transform: rotate(2deg);
  }

  .dc-product-details__panel[role='tabpanel'] {
    animation: none;
  }
}
