/**
 * cross-sell.css — „Często kupowane razem": trzy karty uzupełniające
 * zamówienie.
 *
 * Wymaga tokens.css i base.css. Wszystko pod prefiksem .dc-cross-sell__,
 * nic stąd nie wycieka na cudze znaczniki. Jedyny wyjątek to .dc-icon
 * (rejestr), dostrajana wyłącznie w selektorze potomnym pod prefiksem sekcji.
 *
 * BEZ OBWÓDKI .dc-ring — makieta nie rysuje jej tu w żadnej z wersji.
 * Warstwy, której nie ma w makiecie, nie dokładamy.
 *
 * CO JEST TU LICZBĄ, A NIE TOKENEM (reguła 17, punkt 5 — grep ma dwa
 * trafienia i oba są świadome): zapis rgba(var(--dc-shadow-color), N)
 * w cokole packshotu i w przyciemnieniu zdjęcia Big-Baga. To NIE jest
 * wpisany kolor — to IDIOM tokens.css, którym plik tokenów składa każdy
 * z ośmiu cieni (`rgba(var(--dc-shadow-color), 0.08)` i tak dalej).
 * Kanał --dc-shadow-color jest trójką liczb, a nie kolorem, więc
 * color-mix() go nie przyjmie, a innego tokenu NIOSĄCEGO KOLOR CIENIA
 * paleta nie ma. Zysk jest realny: obie warstwy ciemnieją razem z resztą
 * cieni w motywie ciemnym, bez ani jednej reguły [data-theme]. Podstawienie
 * jest tu bezpieczne, bo var() rozwiązuje się na ELEMENCIE SEKCJI, który
 * dziedziczy aktualną wartość kanału — to nie ta sama sytuacja co
 * nadpisywanie kanału pod gotowym tokenem cienia (pułapka opisana
 * w tokens.css i w partii 4 audytu).
 *
 * NAJAZD NA KARTĘ ZDJĘTY. Makieta unosi kartę o 6 px i pogłębia cień
 * (transition transform .28s). Dwa powody, oba twarde: (1) design-audit.md
 * C.2 — hover to WYŁĄCZNIE kolor, zero translate, a uniesienie zniknęło już
 * w partii 1 audytu ze wszystkich sekcji, które je miały; (2) karta nie jest
 * odnośnikiem — klikalny jest wyłącznie przycisk w jej rogu, więc reakcja
 * całej karty na kursor obiecywałaby kliknięcie, którego nie ma (reguła 14).
 * Najazd dostaje sam przycisk, wg rangi 1 z C.1.
 */

/* ==========================================================================
   1. NAGŁÓWEK SEKCJI
   Makieta: flex z align-items: flex-end i justify-content: space-between —
   układ pod drugi element po prawej, którego makieta ostatecznie nie ma
   (blok jest pusty). Przeniesiony zostaje sam nagłówek, bez pustej
   połówki flexa. Odstęp pod nagłówkiem 28 -> --dc-space-28.
   ========================================================================== */

/* .dc-cross-sell nie ma tu żadnej deklaracji — szerokość i marginesy boczne
   daje .dc-container, pionowy oddech .dc-section, obie z base.css bez
   modyfikacji (reguła 8). Klasa zostaje w znaczniku jako nazwa bloku. */

.dc-cross-sell__header {
  margin-block-end: var(--dc-space-28);
}

/* Nadtytuł: jedna czwórka z design-audit.md C.8 (partia 6) — 12 / 600 /
   --dc-tracking-widest, odstęp 14 do h2 (makieta ma 12, scalone).
   Kolor --dc-accent-strong (reguła J). */
.dc-cross-sell__eyebrow {
  margin-block-end: var(--dc-space-14);
  font-size: var(--dc-text-sm);
  font-weight: var(--dc-weight-medium);
  letter-spacing: var(--dc-tracking-widest);
  text-transform: uppercase;
  color: var(--dc-accent-strong);
}

/* Makietowe clamp(26px, 3vw, 34px) to --dc-display-4
   (clamp(26px, 3.2vw, 34px)) — podłoga i sufit trafiają co do piksela. */
.dc-cross-sell__heading {
  font-size: var(--dc-display-4);
}

/* ==========================================================================
   2. SIATKA
   Makietowe repeat(auto-fit, minmax(280px, 1fr)) trafia w --dc-grid-min-md
   co do piksela, odstęp 20 -> --dc-space-20. Bez breakpointu (reguła 9);
   liczba kolumn na trzech szerokościach zmierzona — tabela w raporcie.

   min(..., 100%) jest OBOWIĄZKOWE: bez niego ścieżka minimalna toru jest
   przy 390 px szersza niż kontener i karty wychodzą poza jego obrys.
   ========================================================================== */

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

/* ==========================================================================
   3. KARTA
   Scalenia: promień 20 -> --dc-radius-22 (skala tokenu to 20 / 22), tło .82
   -> --dc-surface-glass (.86), obwódka biel .9 -> --dc-border-subtle,
   cień 0 10px 32px .1 -> --dc-shadow-lg (0 10 30 .08) — stopień 2 z C.4,
   „karty rzędu drugiego", dokładnie ten przypadek.

   overflow: hidden — scena zdjęcia sięga krawędzi karty i musi zostać
   przycięta jej promieniem. Karta nie ma warstwy obwódki, więc nie ma tu
   konfliktu z poświatą, przed którym broniły się panele w partii 6.

   flex-direction: column plus flex: 1 na treści — stopka z ceną i przyciskiem
   siada przy dolnej krawędzi niezależnie od długości opisu, więc trzy karty
   mają przyciski w jednej linii. Tak samo robi makieta (margin-top: auto).
   ========================================================================== */

.dc-cross-sell__card {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border: var(--dc-border) solid var(--dc-border-subtle);
  border-radius: var(--dc-radius-22);
  background-color: var(--dc-surface-glass);
  -webkit-backdrop-filter: var(--dc-blur-xl);
  backdrop-filter: var(--dc-blur-xl);
  box-shadow: var(--dc-shadow-lg), var(--dc-shadow-inset-top);
}

/* ==========================================================================
   4. SCENA ZDJĘCIA

   MAKIETA RYSUJE TU PACKSHOT NA COKOLE: wycięty worek na przezroczystym tle,
   stojący na miękkim eliptycznym cieniu, nad gradientową podłogą (radial
   biel -> #eaecf0). Tej konstrukcji NIE DA SIĘ odtworzyć zdjęciami, które są
   w katalogu — wszystkie obrazy wariantów to JPEG-i z własnym tłem, bez
   kanału alfa (sprawdzone mime_content_type na załącznikach 146, 147, 85, 89).
   Cokół i gradient podłogi odpadają razem z packshotem: nie mają czego
   podpierać. Wracają, jeśli katalog dostanie wycinki PNG.

   ZMIERZONE ŹRÓDŁA (próbkowanie pikseli, 2026-08-30) — to one wyznaczają
   wszystkie trzy decyzje niżej:

     zestaw testowy   600 × 450 (4:3), tło #FDFDFD w każdym rogu,
                      produkt zajmuje 95,2% wysokości kadru
                      (margines: góra 4,4%, DÓŁ 0,4%)
     paleta 1 t       600 × 450 (4:3), tło #FEFEFE,
                      produkt 91,5% wysokości (góra 6,7%, dół 1,8%)
     coal-orzech.jpg  1376 × 768 (1,79:1), fotografia sceny na całą klatkę,
                      zero marginesu z którejkolwiek strony

   1. PROPORCJA KADRU 2/1 — Z MAKIETY (380 × 190). Wróciła po tym, jak
      kadr 4/3 okazał się za wysoki: karta rosła o 93 px i sekcja przestała
      wyglądać jak makieta. To NIE jest powrót do przycinania — patrz
      punkt 2, który tamten problem rozwiązuje inaczej.

   2. object-fit: contain, NIE cover. To jest cała sztuczka i to ona
      pozwala mieć jednocześnie niski kadr makiety i nietknięty produkt.
      Packshoty stoją na dolnej krawędzi własnego kadru (margines dolny
      0,4% i 1,8%), więc każde przycięcie W PIONIE tnie produkt — przy
      cover w kadrze 2/1 z materiału 4:3 znikałoby 33% wysokości.
      contain dopasowuje po WYSOKOŚCI: obraz dostaje 190 px wysokości
      i 253 px szerokości, a w kadrze 380 px zostają po bokach dwa pasy
      po ok. 62 px. Pasy są tłem sceny, a tło sceny jest bielą zgodną
      z tłem fotografii co do dwóch poziomów (punkt 3), więc ich nie widać.
      Produkt jest w całości i jest wysoki na 95% kadru.

   3. TŁO SCENY = --dc-surface-on-dark (#ffffff, token STAŁY w obu motywach —
      tokens.css deklaruje go raz i nie podmienia w bloku ciemnym). Zmierzone
      tło packshotów to #FDFDFD / #FEFEFE, czyli biel co do dwóch poziomów,
      więc pasy contain zlewają się z fotografią i szwu nie widać. Token
      powstał w partii 4 audytu dokładnie na tę rolę — jasna powierzchnia,
      która ma zostać jasna także w motywie ciemnym. Gdyby scena brała
      --dc-surface, w motywie ciemnym byłaby ciemna, a na niej biały
      prostokąt zdjęcia z ostrym szwem.
   ========================================================================== */

.dc-cross-sell__stage {
  position: relative;
  aspect-ratio: 2 / 1;
  overflow: hidden;
  background-color: var(--dc-surface-on-dark);
}

.dc-cross-sell__photo {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* FOTOGRAFIA SCENY — karta Big-Baga. Jedyne zdjęcie bez marginesu i bez
   pojedynczego przedmiotu do ocalenia, więc jako jedyne WOLNO przyciąć.
   W kadrze 2/1 z materiału 1,79:1 znika 10,5% wysokości — tyle, że scena
   traci trochę blatu nad i pod węglem, a nie sam węgiel. Bez cover
   fotografia dostałaby pasy bieli po bokach i jako jedyna wyglądałaby
   na wklejoną. Punkt kadrowania na 35% od lewej — przy środkowym worek
   przy prawej krawędzi tracił róg, a to on niesie markę. */
.dc-cross-sell__photo--scene {
  object-fit: cover;
  object-position: 35% center;
}

/* ==========================================================================
   5. TREŚĆ KARTY
   Padding 20/22/22 z makiety scalony do jednego --dc-space-22 na wszystkich
   krawędziach: różnica 2 px między górą a bokami jest w granicach szumu
   z reguły 15, a asymetria bez powodu utrudnia czytanie pliku.
   ========================================================================== */

.dc-cross-sell__body {
  display: flex;
  flex: 1;
  flex-direction: column;
  padding: var(--dc-space-22);
}

/* Tytuł JEST nagłówkiem (h3) — reguła 20: pod nim stoi treść, którą
   zapowiada (opis, cena, przycisk), a sekcja ma własny h2.
   Makietowe 16 px / 700 -> --dc-text-xl i --dc-weight-bold bez scalania,
   odstęp 5 -> --dc-space-6. */
.dc-cross-sell__title {
  margin-block-end: var(--dc-space-6);
  font-size: var(--dc-text-xl);
}

/* Opis: 13 px trafia w --dc-text-base, makietowe #9a958a to
   --dc-text-subtle. Odstęp 14 do stopki karty. */
.dc-cross-sell__note {
  margin-block-end: var(--dc-space-14);
  font-size: var(--dc-text-base);
  line-height: var(--dc-leading-relaxed);
  color: var(--dc-text-subtle);
}

/* ==========================================================================
   6. STOPKA KARTY — CENA I PRZYCISK
   margin-block-start: auto dosuwa stopkę do dolnej krawędzi karty
   (makietowe margin-top: auto), więc przyciski trzech kart stoją w jednej
   linii mimo opisów różnej długości.

   Formularz i <div> Big-Baga niosą tę samą klasę, bo pełnią tę samą rolę
   układową — różni je wyłącznie to, czy w środku jest przycisk, czy
   odnośnik.
   ========================================================================== */

.dc-cross-sell__buy {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--dc-space-12);
  margin-block-start: auto;
}

.dc-cross-sell__price {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--dc-space-6);
}

/* Kwota: makietowe 20 px / 800 -> --dc-text-4xl i --dc-weight-black.
   font-variant-numeric: tabular-nums, żeby ceny trzech kart miały cyfry
   tej samej szerokości — inaczej „1 499" i „127" mają różny rytm.  */
.dc-cross-sell__amount {
  font-family: var(--dc-font-display);
  font-size: var(--dc-text-4xl);
  font-weight: var(--dc-weight-black);
  line-height: var(--dc-leading-none);
  font-variant-numeric: tabular-nums;
  color: var(--dc-text);
}

/* „Wycena indywidualna" to nie kwota, tylko zdanie — bierze rozmiar
   o dwa stopnie mniejszy i wagę bold zamiast black, żeby nie udawać ceny
   wielkością. Zawijanie wyłączone: „Wycena / indywidualna" w dwóch
   wierszach rozpychało stopkę karty i wypychało przycisk poza linię
   sąsiednich kart. */
.dc-cross-sell__amount--quote {
  font-size: var(--dc-text-xl);
  font-weight: var(--dc-weight-bold);
  line-height: var(--dc-leading-snug);
}

.dc-cross-sell__gross {
  font-size: var(--dc-text-2xs);
  color: var(--dc-text-subtle);
}

/* Przelicznik na kilogram — to jest PORÓWNANIE JEDNOSTKOWE, które zastąpiło
   plakietkę „−15%" i cenę przekreśloną (decyzja 2026-08-30, patrz docblock
   cross-sell.php).

   STOI W LINII KWOTY, nie pod nią — dokładnie jak w makiecie („1 499 zł
   ≈ 1,50 zł/kg"). Wcześniej miał flex-basis: 100% i spychał się do
   własnego wiersza, przez co stopka karty miała trzy linie zamiast dwóch
   i cała sekcja rosła o 18 px na kartę. Zawinie się sam, gdy zabraknie
   miejsca — flex-wrap na rodzicu zostaje. */
.dc-cross-sell__per-kg {
  font-size: var(--dc-text-sm);
  font-weight: var(--dc-weight-bold);
  color: var(--dc-text-secondary);
}

/* Odniesienie do pojedynczego worka — ta sama treść i ten sam warunek
   co w product/hero: tylko przy realnej oszczędności. */
.dc-cross-sell__compare {
  flex-basis: 100%;
  font-size: var(--dc-text-2xs);
  color: var(--dc-text-subtle);
}

/* ==========================================================================
   7. PRZYCISK — RANGA 1 (design-audit.md, C.1)
   Makieta rysuje kwadrat 42 px o promieniu 12 z gradientem złota. System
   jest nowszy i wygrywa co do wypełnienia: ranga 1 to --dc-gradient-cta,
   1 px --dc-accent-a50, tekst --dc-on-accent i JEDEN promień na rangę —
   r16 dla rang 1–2 (C.9).

   BEZ --dc-shadow-accent — świadome odstępstwo od C.1, na wskazanie
   Andrzeja (2026-08-30) po porównaniu ze zrzutem makiety. Poświata jest
   w systemie zarezerwowana dla rangi 1 i C.4 nazywa ją „jedyną poświatą
   na stronie" — a tutaj ranga 1 występuje TRZY RAZY w jednym rzędzie,
   więc jedna poświata staje się trzema plamami obok siebie, każda
   rozlewająca się na krawędź swojej karty. Makieta rysuje te przyciski
   płasko (sam gradient i obwódka, zero cienia) i tak wyglądają lżej.
   Reszta przepisu rangi 1 zostaje bez zmian, więc przycisk nadal czyta
   się jako akcja główna karty — traci wyłącznie warstwę, która na trzech
   sąsiadach i tak sumowała się w plamę.

   Przycisk jest kwadratem, bo niesie samą ikonę — nazwę dostępną daje
   tekst w .dc-sr-only w znaczniku, osobny dla każdej karty.

   Wysokość: makietowe 42 px idzie na --dc-space-48, czyli w pasmo rangi 1
   (44–48 px). Tokenu 44 px w skali nie ma, a 48 jest bliżej niż 40.

   Ten sam element w dwóch znacznikach: <button type="submit"> przy karcie
   z koszykiem i <a href="tel:"> przy Big-Bagu. Jedna klasa, bo to jedna
   rzecz — akcja główna karty; różni je wyłącznie to, co się po niej dzieje.
   ========================================================================== */

.dc-cross-sell__submit {
  display: inline-flex;
  flex: none;
  align-items: center;
  justify-content: center;
  width: var(--dc-space-48);
  height: var(--dc-space-48);
  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);
  -webkit-backdrop-filter: var(--dc-blur-md);
  backdrop-filter: var(--dc-blur-md);
  box-shadow: 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);
}

/* Ikona bierze kolor tekstu przycisku — --dc-on-accent, nie złoto:
   złota kreska na złotym tle to problem kontrastu, który audyt wyłapał
   przy „Zapytaj" (C.3). WYŁĄCZNIE poza stanem „dodano": tam panel jest
   odwrócony (components/cart-added.css — grafit, tekst --dc-surface),
   a ta reguła (0,2,0) biła kolor komponentu i ptaszek stawał ciemny na
   ciemnym — „przycisk cały czarny" (zgłoszenie Andrzeja, 2026-08-31). */
.dc-cross-sell__submit:not([data-dc-cart-added='done']) .dc-icon {
  color: var(--dc-on-accent);
}

/* Najazd: sam kolor, zero ruchu (C.2). */
.dc-cross-sell__submit:hover:enabled,
a.dc-cross-sell__submit:hover {
  background-color: var(--dc-accent-a50);
}

/* Kliknięcie = nacisk: zmniejszenie plus cień wciśnięcia — jedyna
   transformacja dozwolona na elementach klikalnych (C.2). .97 jak
   w volume-picker. */
.dc-cross-sell__submit:active:enabled,
a.dc-cross-sell__submit:active {
  transform: scale(0.97);
  box-shadow: var(--dc-shadow-inset-press);
}

/* ==========================================================================
   8. PLUS ZAMIENIA SIĘ W PTASZEK

   Makieta obraca ikonę i podmienia ją na ptaszek w chwili dodania do
   koszyka. Motyw robi to samo BEZ ANI JEDNEJ LINII JAVASCRIPTU, bo nie ma
   czego dodawać: formularz i tak wysyła POST i strona wraca odświeżona,
   więc o tym, który rysunek wypisać, decyduje PHP po stanie koszyka
   (patrz docblock cross-sell.php). CSS-owi zostaje sam obrót.

   Dlaczego to NIE jest podmiana ikony transformą, jak przy chevronie:
   plus i ptaszek to dwa różne kształty, a nie ten sam obrócony. Rysunek
   podmienia znacznik, CSS tylko wprowadza nowy na scenę.

   Obrót gra RAZ, po dodaniu — atrybut data-dc-just-added dostaje wyłącznie
   przycisk wariantu wysłanego w tym żądaniu. Bez tego warunku ptaszek
   kręciłby się przy każdym wejściu na stronę, dopóki pakiet leży
   w koszyku, czyli zamieniłby potwierdzenie w tik nerwowy.

   Krzywa --dc-ease-out i czas --dc-duration-base: to samo, czym motyw
   animuje pozostałe przejścia stanu (C.2). Ćwierć obrotu, nie pełny —
   pełny obrót przy ptaszku wygląda jak ładowanie, a to jest potwierdzenie.
   ========================================================================== */

.dc-cross-sell__submit--added[data-dc-just-added] .dc-icon {
  animation: dcCrossSellCheck var(--dc-duration-base) var(--dc-ease-out) both;
}

@keyframes dcCrossSellCheck {
  from {
    transform: rotate(-90deg) scale(0.6);
    opacity: 0;
  }

  to {
    transform: rotate(0) scale(1);
    opacity: 1;
  }
}

/* Globalny wyłącznik w base.css tnie czas do 0,01 ms z jedną iteracją —
   dla przejścia JEDNORAZOWEGO to znaczy „od razu w stanie końcowym",
   czyli dokładnie to, o co chodzi: ptaszek stoi, nie wjeżdża. Blok jest
   mimo to wypisany (reguła 12), bo `both` utrzymuje klatkę końcową
   i bez jawnego zdjęcia animacji łatwo o wrażenie, że coś tu jeszcze
   działa. Sekcja dokłada ruch, więc sekcja go wyłącza. */
@media (prefers-reduced-motion: reduce) {
  .dc-cross-sell__submit--added[data-dc-just-added] .dc-icon {
    animation: none;
  }
}

/* Pakiet niedostępny. Przycisk ZOSTAJE w znaczniku i jest wyłączony,
   zamiast znikać — karta zachowuje wysokość sąsiadek, a użytkownik widzi,
   że tu też da się kupić, tylko nie teraz. Ten sam wybór co
   w volume-picker. */
.dc-cross-sell__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;
}

.dc-cross-sell__submit:disabled .dc-icon {
  color: var(--dc-text-subtle);
}
