/* ==========================================================================
 * SAMA MATCHA — sm-product.css (KROK 1: galeria + buy box)
 * Scope: body.sm-product-page / .single-product
 * Tokeny only. Zero hexów / surowych px odstępów (wyjątki: 1px, 44px, 56px CTA).
 * ========================================================================== */

/* ---------- layout: dwie kolumny ≥1024, galeria sticky (D1 / D1b) ----------
 *
 * Podział 55/45. Liczby z pomiaru na 1440 (kontener Blocksy 1290, gap --sp-5):
 *   galeria 674 px → minus miniatury 80 px i gap 16 px → kadr 578 px
 *   kadr 4:5       → 722 px wysokości, mieści się w 754 px użytecznej wysokości
 *                    okna 900 px (header 114 px + oddech), więc sticky ma sens
 *   buy box 552 px → treść ograniczona do 46ch, resztę zostawiamy jako margines
 *
 * Dlaczego 4:5, a nie natywne 2:3 zdjęć: przy kadrze 578 px proporcja 2:3 daje
 * 867 px wysokości, czyli więcej niż użyteczna wysokość okna — jedno zdjęcie
 * wypychałoby buy box poza ekran i unieważniało sticky.
 */
@media (min-width: 1024px) {
  body.sm-product-page .product-entry-wrapper {
    display: grid;
    grid-template-columns: minmax(0, 55fr) minmax(0, 45fr);
    gap: var(--sp-5);
    align-items: start;
  }

  /* Blocksy: `.ct-default-gallery .woocommerce-product-gallery { width: var(--product-gallery-width, 50%) }`
   * oraz `.entry-summary { width: calc(100% - …) }` — swoistość 0,2,0, więc bije
   * `.sm-gallery { width: 100% }`. W siatce oba dzieci dostawały 50% swojego
   * toru: galeria 307 px z 613 px (stąd pustka po lewej), buy box też 307 px
   * (czyli ~33ch, poniżej celu czytelności). Poniżej swoistość 0,3,1. */
  body.sm-product-page .product-entry-wrapper > .woocommerce-product-gallery,
  body.sm-product-page .product-entry-wrapper > .entry-summary {
    width: 100%;
  }

  /* Sticky tylko na galerii. Buy box jest wyższy od galerii, więc jego sticky
   * nic nie dawał, a przy dwóch sticky elementach w jednym rzędzie dolna
   * krawędź wyższego blokowała przewijanie krótszego. */
  body.sm-product-page .woocommerce-product-gallery,
  body.sm-product-page .sm-gallery {
    position: sticky;
    top: calc(var(--sp-4) + 4.5rem);
  }
}

/* ---------- rytm pionowy buy boxa (D4) ----------
 * Bazowy odstęp --sp-2 wiąże wiersze o tej samej roli (overline → tytuł →
 * deskryptor). Większy oddech pojawia się tylko na granicy grup, gdzie zmienia
 * się rola treści: opis → wybór formatu → akcja → warunki → szczegóły.
 *
 * Docelowo, od góry: 8 · 8 · 24 · 40 · 24 px.
 */
body.sm-product-page .entry-summary {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  max-width: 46ch; /* długość linii ważniejsza niż wypełnienie kolumny */

  /* Blocksy rozstawia elementy buy boxa własnym marginesem:
   * `.product[class*=gallery] .entry-summary-items>*{margin-bottom:var(--product-element-spacing,10px)}`
   * — a `.entry-summary` nosi obie klasy. Margines sumował się z `gap` i rytm
   * zsuwał się ze skali (mierzone 18 · 18 · 43 · 59 · 34). Zerujemy u źródła,
   * przez zmienną Blocksy, nie przez wojnę swoistości. */
  --product-element-spacing: 0px;
}

/* Woo dokłada jeszcze własne marginesy do <h1> i <p>. Reset musi przebić
 * selektor Blocksy (0,3,0) — stąd `.product` w ścieżce. Odstępy niosą `gap`
 * i jawne marginesy granic grup poniżej. */
body.sm-product-page .product .entry-summary > * {
  margin-block: 0;
}

body.sm-product-page .product .entry-summary > .woocommerce-product-details__short-description {
  margin-bottom: var(--sp-3); /* + gap = 24 px przed wyborem formatu */
}
body.sm-product-page .product .entry-summary > .sama-free-shipping--buybox {
  margin-top: var(--sp-3); /* + gap + padding = 40 px przed warunkami */
}
body.sm-product-page .product .entry-summary > .sm-buybox__faq {
  margin-top: var(--sp-3); /* + gap = 24 px przed szczegółami */
}
body.sm-product-page .sm-format {
  margin-top: var(--sp-3);
}

/* ---------- buy box typography ---------- */
.sm-buybox__overline {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--fs-overline);
  font-weight: 500;
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--c-moss);
}

/* Kanji jako inline SVG (inc/kanji.php) — skaluje się z fontem, dziedziczy kolor.
   1.25em, bo kwadratowy glif CJK przy równej wysokości optycznie ginie
   przy wersalikach łacińskich. */
.sm-kanji {
  display: block;
  flex: 0 0 auto;
  width: 1.25em;
  height: 1.25em;
  color: inherit;
}
.sm-kanji--text {
  /* Fallback dla znaku poza mapą konturów — stos systemowy CJK. */
  font-family: "Hiragino Sans", "Yu Gothic", "Noto Sans JP", "MS Gothic", sans-serif;
  line-height: 1;
}

body.sm-product-page .product_title,
body.sm-product-page .entry-summary > h1 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 2rem; /* 32px — spec buy box */
  line-height: 1.15;
  color: var(--c-text);
}

.sm-buybox__descriptor {
  margin: 0;
  font-size: var(--fs-body);
  color: var(--c-muted);
}

/* PAKIET C: `.sm-buybox__price` usunięty — cena żyje w wierszu wariantu. */

.sm-buybox__batch {
  margin: 0;
  font-size: var(--fs-caption);
  color: var(--c-muted);
}

/* ---------- format radios (D2 / D3) ----------
 * Tło zaznaczonego wiersza sięga poza kolumnę tekstu, żeby nie kleiło się do
 * liter; ujemny margines na liście trzyma tekst w jednej osi z tytułem i CTA.
 */
.sm-format {
  display: flex;
  flex-direction: column;
  border-top: var(--line);
  margin-inline: calc(var(--sp-2) * -1);
}
.sm-format__row {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-2);
  border-bottom: var(--line);
  cursor: pointer;
  outline: none;
  transition: background-color var(--t-fast) var(--ease);
}
.sm-format__body {
  display: flex;
  flex: 1 1 auto;
  min-width: 0;
  flex-direction: column;
  gap: var(--sp-1);
}

/* Kółko radio — nośnik stanu. Zaznaczenie czytelne bez czytania ceny. */
.sm-format__radio {
  flex: 0 0 auto;
  width: 1.125rem;
  height: 1.125rem;
  margin-top: 0.2em; /* na linię bazową nazwy formatu */
  border: 1px solid var(--c-line);
  border-radius: var(--r-full);
  background: var(--c-paper);
  position: relative;
  transition:
    border-color var(--t-fast) var(--ease),
    background-color var(--t-fast) var(--ease);
}
.sm-format__radio::after {
  content: "";
  position: absolute;
  inset: 0;
  margin: auto;
  width: 0.5rem;
  height: 0.5rem;
  border-radius: var(--r-full);
  background: var(--c-ink);
  transform: scale(0);
  transition: transform var(--t-fast) var(--ease);
}

/* Hover: tylko tło, zero ruchu. Wiersz nie skacze pod kursorem.
 * Tylko na niezaznaczonych — hover jest zapowiedzią wyboru, a na wierszu już
 * wybranym nie ma czego zapowiadać. Bez tego zaznaczenie i hover dawały
 * identyczne tło (--c-cream to jedyny jasny odcień w palecie) i stan czytało
 * się wyłącznie z kółka radio. */
.sm-format__row[aria-checked="false"]:hover {
  background-color: var(--c-cream);
}
.sm-format__row[aria-checked="false"]:hover .sm-format__radio {
  border-color: var(--c-ink);
}

/* Zaznaczony wiersz — kontrast tła NIESIE stan, więc hairline gaśnie
 * (doktryna elewacji: tło albo hairline, nigdy dwa naraz). */
.sm-format__row[aria-checked="true"] {
  background-color: var(--c-cream);
  border-bottom-color: transparent;
}
.sm-format__row[aria-checked="true"] .sm-format__radio {
  border-color: var(--c-ink);
}
.sm-format__row[aria-checked="true"] .sm-format__radio::after {
  transform: scale(1);
}
.sm-format__row[aria-checked="true"] .sm-format__name,
.sm-format__row[aria-checked="true"] .sm-format__price {
  color: var(--c-ink);
}

/* Niezaznaczone: wyciszone, ale czytelne — nie schodzimy poniżej --c-muted. */
.sm-format__row[aria-checked="false"] .sm-format__name,
.sm-format__row[aria-checked="false"] .sm-format__price {
  color: var(--c-text);
}

.sm-format__row:focus-visible {
  outline: 2px solid var(--c-ink);
  outline-offset: -2px;
}

.sm-format__main {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--sp-3);
}
.sm-format__name {
  font-size: var(--fs-body);
  font-weight: 500;
  color: var(--c-text);
}
.sm-format__price {
  font-size: var(--fs-body);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  color: var(--c-text);
  white-space: nowrap;
}

/* Cena za czarkę — drugi stopień hierarchii: to liczba, którą klient porównuje
 * między formatami, więc stoi wyżej i większym stopniem niż cena za 100 g. */
.sm-format__serving {
  font-size: var(--fs-small);
  color: var(--c-text);
  font-variant-numeric: tabular-nums;
}

/* Cena za 100 g — najmniejszy stopień, obowiązek informacyjny. */
.sm-format__meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  font-size: var(--fs-caption);
  color: var(--c-muted);
  font-variant-numeric: tabular-nums;
}
.sm-format__note::before {
  content: "·";
  margin-right: var(--sp-2);
  speak: never;
}

@media (prefers-reduced-motion: reduce) {
  .sm-format__row,
  .sm-format__radio,
  .sm-format__radio::after {
    transition: none;
  }
}

/* Select Woo — widoczny dla skryptu, niewidoczny wizualnie (nie display:none).
 * Bez !important: swoistość body.sm-product-page + form wystarcza vs Blocksy/Woo. */
body.sm-product-page form.variations_form table.variations,
body.sm-product-page form.variations_form .variations select.sm-sr-only-select,
body.sm-product-page .variations select.sm-sr-only-select {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

body.sm-product-page .woocommerce-variation-add-to-cart {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  margin-top: var(--sp-2);
}

/* Blocksy quantity dokłada inline display:block — ukrywamy (ilość = 1). */
body.sm-product-page .quantity {
  display: none !important; /* swoistość vs inline Blocksy type-2 */
}

/* Podwójna cena: Woo .woocommerce-variation-price vs nasze .sm-buybox__price */
body.sm-product-page .single_variation_wrap .woocommerce-variation-price,
body.sm-product-page .woocommerce-variation-price {
  display: none; /* ta sama informacja w .sm-buybox__price */
}

/* PAKIET A (A4): wiersz akcji musi umieć zawinąć — komunikat inline siada
   pod CTA, a nie obok niego. */
body.sm-product-page .ct-cart-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2);
}

/* Komunikat po dodaniu do koszyka — wyciszona linia, link tekstowy. */
.sm-atc {
  flex: 1 0 100%;
  order: 99;
  margin: 0;
  font-size: var(--fs-caption);
  color: var(--c-muted);
}
.sm-atc[hidden] { display: none; }
.sm-atc__link {
  color: var(--c-moss);
  text-decoration: underline;
  text-underline-offset: 0.2em;
}
.sm-atc__link:hover { color: var(--c-ink); }

body.sm-product-page .single_add_to_cart_button,
body.sm-product-page .single_add_to_cart_button.button {
  width: 100%;
  min-height: 56px; /* CTA mobile — wyjątek celowy */
  height: 56px;
  white-space: nowrap; /* tekst CTA w jednej linii — A4 */
  /* Spoczynek --c-forest, hover --c-ink. Drabinka palety to ink #16281D →
   * forest #1E3A2B → moss → sage, od najciemniejszego. „Hover ciemnieje
   * (--c-ink → --c-forest)” dawałoby więc rozjaśnienie; kolejność odwrócona,
   * żeby kierunek był zgodny z intencją. */
  background: var(--c-forest);
  color: var(--c-paper);
  border: 0;
  border-radius: var(--r-sm);
  font-family: var(--font-sans);
  font-size: var(--fs-body);
  font-weight: 500;
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  cursor: pointer;
  transition: background var(--t-fast) var(--ease);
}
/* CTA na hover CIEMNIEJE. Globalna reguła Woo w sama-refactor.css
 * (`.woocommerce .single_add_to_cart_button:hover { background: var(--sm-moss) }`,
 * swoistość 0,3,0) ma tę samą swoistość i ładuje się później, więc rozjaśniała
 * przycisk. Kwalifikator `button.` daje 0,3,1 i wygrywa bez !important. */
body.sm-product-page button.single_add_to_cart_button:hover,
body.sm-product-page button.single_add_to_cart_button.button:hover,
body.sm-product-page button.single_add_to_cart_button:active,
body.sm-product-page button.single_add_to_cart_button.button:active {
  background: var(--c-ink);
  color: var(--c-paper);
}

/* ---------- trust row ---------- */
.sm-trust {
  list-style: none;
  margin: 0;
  padding: var(--sp-3) 0 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2) var(--sp-3);
  border-top: var(--line);
  font-size: var(--fs-caption);
  color: var(--c-muted);
}
.sm-trust__item {
  margin: 0;
}
.sm-trust__item:not(:last-child)::after {
  content: "·";
  margin-left: var(--sp-3);
  color: var(--c-line);
}

/* ---------- free shipping in buy box (A6) ----------
 * Komponent współdzielony z mini-koszykiem ma tło --c-cream ORAZ ramkę, czyli
 * dwie warstwy elewacji naraz. W buy boksie na --c-paper zostaje sam hairline;
 * pasek jest warunkiem zakupu, nie kartą.
 */
body.sm-product-page .sama-free-shipping--buybox {
  margin-top: var(--sp-3);
  padding: var(--sp-3) 0 0;
  border: 0;
  border-top: var(--line);
  border-radius: 0;
  background: transparent;
}
/* Przy zerowym koszyku tor nie jest renderowany (PHP) — komunikat sam
   w sobie jest pełną informacją, więc nie zostawiamy po nim odstępu. */
body.sm-product-page .sama-free-shipping--buybox.is-empty .sama-free-shipping__label {
  margin-bottom: 0;
}

/* ---------- gallery ---------- */
.sm-gallery {
  display: grid;
  gap: var(--sp-3);
  width: 100%;
}
@media (min-width: 1024px) {
  .sm-gallery--multi {
    /* 80px miniatury — górna granica zakresu 72–80 ze specyfikacji; kadr
       dostaje całą resztę toru. */
    grid-template-columns: 80px minmax(0, 1fr);
    align-items: start;
  }
  .sm-gallery__thumbs {
    display: flex;
    flex-direction: column;
    gap: var(--sp-2);
    order: 0;
  }
  .sm-gallery__stage-wrap { order: 1; }
  body.sm-product-page .sm-gallery__dots {
    display: none; /* desktop: tylko thumbs; mobile: kropki */
  }
}

.sm-gallery__frame--empty,
.sm-gallery__slide {
  aspect-ratio: 4 / 5;
  background: var(--c-cream);
  margin: 0;
  overflow: hidden;
  border-radius: 0;
}

.sm-gallery__stage {
  display: flex;
  gap: 0;
  overflow: hidden;
}
.sm-gallery__stage--snap {
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.sm-gallery__stage--snap::-webkit-scrollbar { display: none; }

.sm-gallery__slide {
  flex: 0 0 100%;
  scroll-snap-align: start;
  position: relative;
}

.sm-gallery__zoom {
  display: block;
  width: 100%;
  height: 100%;
  padding: 0;
  border: 0;
  background: var(--c-cream);
  cursor: zoom-in;
}
.sm-gallery__zoom img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Miniatura kwadratowa — `woocommerce_gallery_thumbnail` jest cropowany do
   100×100, więc kwadrat nie kadruje źródła po raz drugi. */
.sm-gallery__thumb {
  width: 80px;
  height: 80px;
  padding: 0;
  border: 0;
  background: var(--c-cream);
  cursor: pointer;
  opacity: 0.7;
  overflow: hidden;
  flex-shrink: 0;
  min-width: 44px;
  min-height: 44px;
  transition: opacity var(--t-fast) var(--ease);
}
.sm-gallery__thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.sm-gallery__thumb:hover { opacity: 1; }
/* Obramowanie, nie cień — cień jest zarezerwowany dla hoveru i sticky. */
.sm-gallery__thumb.is-active {
  opacity: 1;
  outline: 2px solid var(--c-ink);
  outline-offset: -2px;
}

.sm-gallery__dots {
  display: flex;
  justify-content: center;
  gap: var(--sp-2);
  padding-top: var(--sp-2);
}
.sm-gallery__dot {
  width: 8px;
  height: 8px;
  padding: 0;
  border: 0;
  border-radius: var(--r-full);
  background: var(--c-line);
  cursor: pointer;
  min-width: 44px;
  min-height: 44px;
  background-clip: content-box;
  padding: 18px; /* powiększa cel dotykowy wokół 8px kropki */
}
.sm-gallery__dot.is-active { background-color: var(--c-ink); background-clip: content-box; }

@media (max-width: 1023.98px) {
  .sm-gallery__thumbs { display: none; }
  .sm-gallery--single .sm-gallery__dots { display: none; }
}

.sm-gallery--single .sm-gallery__stage { overflow: hidden; }
.sm-gallery--empty .sm-gallery__frame--empty { width: 100%; }

/* ---------- lightbox (własny, nie PhotoSwipe) ---------- */
.sm-lightbox {
  position: fixed;
  inset: 0;
  z-index: 100000;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgb(20 35 26 / 0.92);
  padding: var(--sp-3);
}
.sm-lightbox[hidden] { display: none; }
.sm-lightbox__img {
  max-width: min(100%, 960px);
  max-height: 90vh;
  object-fit: contain;
  background: var(--c-cream);
}

/* Subtelny zoom przy OTWIERANIU lightboxa — nie na hover kadru głównego.
   Ruch prowadzi wzrok z miniatury/kadru do powiększenia i na tym kończy. */
.sm-lightbox.is-entering .sm-lightbox__img {
  animation: sm-lightbox-in var(--t-base) var(--ease) both;
}
@keyframes sm-lightbox-in {
  from {
    opacity: 0;
    transform: scale(0.97);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}
.sm-lightbox__close,
.sm-lightbox__prev,
.sm-lightbox__next {
  position: absolute;
  min-width: 44px;
  min-height: 44px;
  border: 0;
  background: transparent;
  color: var(--c-paper);
  font-size: var(--fs-h3);
  cursor: pointer;
}
.sm-lightbox__close { top: var(--sp-3); right: var(--sp-3); }
.sm-lightbox__prev { left: var(--sp-3); top: 50%; transform: translateY(-50%); }
.sm-lightbox__next { right: var(--sp-3); top: 50%; transform: translateY(-50%); }

/* ---------- related / tabs cleanup on PDP ---------- */
body.sm-product-page .woocommerce-tabs { display: none; }

/* Hide Blocksy default price range if somehow present */
body.sm-product-page .entry-summary > .price:not(.sm-buybox__price-current) {
  /* price layer disabled — belt & suspenders */
}

/* ==========================================================================
 * OPINIE (PAKIET E · 6e)
 *
 * Sekcja jest rodzeństwem `.product-entry-wrapper` wewnątrz `div.product`,
 * a ten idzie pełną szerokością — dlatego szerokość kontenera ustawiamy tu.
 * Odtwarzamy dokładnie mechanizm Blocksy z `.is-width-constrained`:
 *   .is-width-constrained{margin-inline:auto;width:var(--theme-container-width);
 *                         max-width:var(--theme-block-max-width)}
 * Sam `--theme-container-width` to 90vw (1296 px przy 1440) i sekcja wychodziła
 * 3 px na stronę poza galerię; realną krawędź trzyma `--theme-block-max-width`
 * (1290 px z Customizera). Dzięki tym samym zmiennym krawędzie zostaną zgodne,
 * gdy szerokość kontenera się kiedyś zmieni.
 *
 * Doktryna elewacji: zero kart, ramek i cieni. Opinie rozdziela hairline,
 * hierarchię niesie skala typograficzna.
 * ========================================================================== */
body.sm-product-page .sm-reviews {
  width: var(--theme-container-width, 100%);
  max-width: var(--theme-block-max-width, var(--container));
  margin-inline: auto;
  margin-block-start: var(--section-y);
  padding-block-start: var(--section-y);
  border-top: var(--line);
}

/* Blocksy stawia `#reviews` na `display: grid` i rozbija sekcję na dwie
   kolumny 613 px — lista opinii lądowała po lewej, a formularz (albo brama
   „tylko nabywcy”) po prawej, w połowie szerokości. Sekcja ma być jednym
   ciągiem: nagłówek, podsumowanie, lista, formularz. Długość linii pilnują
   `max-width: 65ch` na treści i na formularzu, nie podział kolumn. */
body.sm-product-page .sm-reviews .woocommerce-Reviews {
  display: block;
}

/* Woo domyślnie float:right na gwiazdkach — w wierszu podsumowania i w meta
   opinii mają zostać w kolejności czytania. */
body.sm-product-page .sm-reviews .star-rating {
  float: none;
}

body.sm-product-page .sm-reviews__title {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--fs-h2);
  font-weight: var(--fw-regular);
  line-height: 1.15;
  color: var(--c-text);
}

/* Stan zerowy: jedno zdanie, wyciszone. Zero gwiazdek, zero licznika —
   pusty widget ★ (0) szkodzi bardziej niż jego brak. */
body.sm-product-page .sm-reviews__invite {
  margin: var(--sp-3) 0 0;
  max-width: 65ch;
  font-size: var(--fs-body);
  color: var(--c-muted);
}

/* Brama „tylko nabywcy” stoi w miejscu formularza, więc dostaje ten sam
   hairline i rytm — inaczej doklejała się do ostatniej opinii. */
body.sm-product-page .sm-reviews__gate {
  margin: var(--sp-5) 0 0;
  padding-top: var(--sp-4);
  border-top: var(--line);
  max-width: 65ch;
  font-size: var(--fs-body);
  color: var(--c-muted);
}

/* ---------- podsumowanie: średnia · gwiazdki · licznik ---------- */
body.sm-product-page .sm-reviews__summary {
  display: flex;
  align-items: baseline;
  gap: var(--sp-2);
  margin: var(--sp-3) 0 0;
}
body.sm-product-page .sm-reviews__average {
  font-family: var(--font-display);
  font-size: var(--fs-h3);
  line-height: 1;
  color: var(--c-text);
  font-variant-numeric: tabular-nums;
}
body.sm-product-page .sm-reviews__count {
  font-size: var(--fs-caption);
  color: var(--c-muted);
}

/* Gwiazdki wyniku — glify Woo z fontu „woo”, barwione currentColor. */
body.sm-product-page .sm-reviews .star-rating,
body.sm-product-page .sm-reviews .sm-reviews__summary .star-rating {
  color: var(--c-moss);
}

/* ---------- lista opinii ---------- */
body.sm-product-page .sm-reviews__list {
  margin: var(--sp-4) 0 0;
  padding: 0;
  list-style: none;
}
body.sm-product-page .sm-reviews__list > li {
  padding-block: var(--sp-4);
  border-top: var(--line);
}
body.sm-product-page .sm-reviews__list > li:last-child {
  padding-bottom: 0;
}
/* Kontener opinii bez awatara — Woo trzymał na nim wcięcie pod obrazek. */
body.sm-product-page .sm-reviews__list .comment_container,
body.sm-product-page .sm-reviews__list .comment-text {
  display: block;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
}

body.sm-product-page .sm-review__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--sp-2);
  margin: var(--sp-2) 0 0;
}
body.sm-product-page .sm-review__author {
  font-size: var(--fs-small);
  font-weight: var(--fw-semibold);
  color: var(--c-text);
}
/* Etykieta zakupu w systemie overline: to znacznik zaufania, nie zdanie. */
body.sm-product-page .sm-review__verified {
  font: var(--fw-semibold) var(--fs-overline) / 1 var(--font-sans);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  font-style: normal;
  color: var(--c-moss);
}
body.sm-product-page .sm-review__date {
  font-size: var(--fs-caption);
  color: var(--c-muted);
}

body.sm-product-page .sm-reviews__list .description {
  margin: var(--sp-2) 0 0;
  max-width: 65ch;
  font-size: var(--fs-body);
  line-height: 1.6;
  color: var(--c-text);
}
body.sm-product-page .sm-reviews__list .description > :last-child {
  margin-bottom: 0;
}

/* ---------- formularz ---------- */
body.sm-product-page .sm-reviews__form {
  margin-top: var(--sp-5);
  padding-top: var(--sp-4);
  border-top: var(--line);
  max-width: 65ch;
}
body.sm-product-page .sm-reviews__form .comment-reply-title {
  display: block;
  font-family: var(--font-display);
  font-size: var(--fs-h3);
  line-height: 1.2;
  color: var(--c-text);
}
body.sm-product-page .sm-reviews__form :is(p, .comment-form-rating) {
  margin-block: var(--sp-3) 0;
}
/* Etykieta nad kontrolką, tak jak przy polu opinii — Woo trzyma ten wiersz
   na flexie i „Twoja ocena” siedziała obok gwiazdek. */
body.sm-product-page .sm-reviews__form .comment-form-rating {
  display: block;
}
/* Etykiety jednym krojem. Bez tego „Twoja ocena” przychodziła z uppercase
   (styl Woo), a „Twoja opinia” z display:flex i ciemnym kolorem — dwie
   etykiety tego samego formularza wyglądały jak z dwóch systemów.
   Uppercase w tym projekcie znaczy overline, a etykieta pola nim nie jest. */
body.sm-product-page .sm-reviews__form :is(.comment-form-rating, .comment-form-comment, .comment-form-author, .comment-form-email) > label {
  display: block;
  margin-bottom: var(--sp-1);
  font-size: var(--fs-caption);
  font-weight: var(--fw-regular);
  letter-spacing: normal;
  text-transform: none;
  color: var(--c-muted);
}
/* Pola bez ciężkich ramek: hairline u podstawy, nie prostokąt wokół. */
body.sm-product-page .sm-reviews__form :is(input[type="text"], input[type="email"], textarea) {
  width: 100%;
  padding: var(--sp-2) 0;
  border: 0;
  border-bottom: var(--line);
  border-radius: 0;
  background: transparent;
  font-family: var(--font-sans);
  font-size: var(--fs-body);
  color: var(--c-text);
  transition: border-color var(--t-fast) var(--ease);
}
body.sm-product-page .sm-reviews__form :is(input[type="text"], input[type="email"], textarea):focus {
  outline: none;
  border-bottom-color: var(--c-ink);
}
body.sm-product-page .sm-reviews__form textarea {
  min-height: 8rem;
  resize: vertical;
}

/* Gwiazdki w formularzu buduje `wc-single-product.js` z ukrytego <select>:
   role="radio", tabindex, aria-checked i obsługa strzałek są natywne. */
body.sm-product-page .sm-reviews__form p.stars {
  display: flex;
  gap: 0; /* cele dotykowe stykają się — pasek ocen, nie pięć osobnych ikon */
}
body.sm-product-page .sm-reviews__form p.stars a {
  color: var(--c-sage);
  min-width: 44px;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: var(--fs-h3); /* glif 15 px gubił się w celu 44 px */
  transition: color var(--t-fast) var(--ease);
}
body.sm-product-page .sm-reviews__form p.stars:hover a,
body.sm-product-page .sm-reviews__form p.stars a.active,
body.sm-product-page .sm-reviews__form p.stars a:focus-visible {
  color: var(--c-moss);
}

/* Wiersze zgody: natywny checkbox WordPressa (`comment-form-cookies-consent`)
   i wymagany checkbox rozszerzenia Blocksy Companion → Cookies Consent
   (`.gdpr-confirm-policy`). Oba w jednym układzie, żeby nie wyglądały jak
   dwa różne komponenty. */
body.sm-product-page .sm-reviews__form :is(.comment-form-cookies-consent, .gdpr-confirm-policy) {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-2);
}
body.sm-product-page .sm-reviews__form :is(.comment-form-cookies-consent, .gdpr-confirm-policy) label {
  display: inline;
  margin: 0;
  font-size: var(--fs-caption);
  color: var(--c-muted);
}
body.sm-product-page .sm-reviews__form :is(.comment-form-cookies-consent, .gdpr-confirm-policy) input[type="checkbox"] {
  margin-top: 0.15em; /* wyrównanie do pierwszej linii etykiety, nie do jej pudełka */
  flex: 0 0 auto;
}
body.sm-product-page .sm-reviews__privacy {
  max-width: 65ch;
  font-size: var(--fs-caption);
  color: var(--c-muted);
}

body.sm-product-page .sm-reviews__form .form-submit {
  margin-top: var(--sp-4);
}

@media (prefers-reduced-motion: reduce) {
  .sm-gallery__stage--snap { scroll-behavior: auto; }
  .sm-gallery__thumb { transition: none; }
  .sm-lightbox.is-entering .sm-lightbox__img { animation: none; }
  body.sm-product-page .sm-reviews__form :is(input, textarea, p.stars a) { transition: none; }
}
