/* ==========================================================================
   ALDAR FARMA — components.css
   ========================================================================== */

/* ==========================================================================
   SKIP LINK
   ========================================================================== */
.skip-link {
  position: absolute;
  top: var(--space-3);
  left: var(--space-3);
  z-index: var(--z-toast);
  padding: var(--space-3) var(--space-5);
  background-color: var(--brand);
  color: var(--text-inverse);
  border-radius: var(--radius-sm);
  font-weight: var(--weight-semibold);
  text-decoration: none;
  transform: translateY(calc(-100% - var(--space-4)));
  transition: transform var(--dur-base) var(--ease-out);
}

.skip-link:focus-visible {
  transform: translateY(0);
  color: var(--text-inverse);
}

/* ==========================================================================
   PANEL
   Duży, zaokrąglony blok wpuszczony w tło strony. Podstawowy nośnik
   charakteru layoutu — treść siedzi w kartach, a nie w pasach na pełną
   szerokość ekranu.
   ========================================================================== */
.panel {
  position: relative;
  margin-inline: var(--panel-inset);
  padding: var(--panel-pad) var(--panel-pad-x);
  border-radius: var(--radius-panel);
  overflow: hidden;
  isolation: isolate;
  /* Ta sama poprawka co przy .section--inverse > .container (layout.css):
     overflow:hidden gubi zaokrąglone przycinanie, gdy w środku jest
     potomek z transform ([data-reveal] przy wejściu ma). contain:paint
     wymusza malowanie wyłącznie wewnątrz granic elementu, niezależnie
     od tego, co dzieje się z warstwami kompozycji w środku. */
  contain: paint;
}

/* Panel w sekcji ma tę samą szerokość co hero — przez cały ekran, minus
   wspólny margines. Musi to być dokładnie ta sama reguła co przy
   .section--inverse, inaczej dwa sąsiadujące ciemne bloki różniłyby się
   szerokością i widać by było, że nie leżą w jednej linii. */
.section > .panel {
  margin-inline: var(--panel-inset);
}

.panel--dark {
  background-color: var(--green-950);
  color: var(--text-inverse);
}

/* Ta sama poświata co na .section--inverse (layout.css) — inny selektor
   z tego samego powodu, dla którego istnieje: „Oferta" korzysta z .panel
   jako osobnego komponentu, nie z .section--inverse, więc bez tego dublowania
   dostałaby płaskie tło, podczas gdy sąsiednie ciemne panele mają głębię. */
.panel--dark::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  /* border-radius:inherit + środek gradientu odsunięty od 0%/0% —
     patrz komentarz przy .section--inverse > .container::before
     w layout.css, to ten sam problem i ten sam fix. */
  border-radius: inherit;
  background-image:
    radial-gradient(ellipse 55% 45% at 10% 8%,
      color-mix(in srgb, var(--green-500) 16%, transparent), transparent 68%),
    radial-gradient(ellipse 45% 40% at 92% 92%,
      color-mix(in srgb, var(--green-400) 10%, transparent), transparent 68%);
}

.panel--dark > * {
  position: relative;
  z-index: 1;
}

/* Rozjaśniamy wyłącznie nagłówki leżące bezpośrednio na panelu.
   Zagnieżdżone białe karty mają własne, ciemne nagłówki — gdyby reguła
   działała na wszystkie potomki, tytuły kart zniknęłyby na białym tle. */
.panel--dark > h2,
.panel--dark > h3,
.panel--dark > .section-head h2,
.panel--dark > .section-head h3 {
  color: var(--text-inverse);
}

.panel--light {
  background-color: var(--bg-elevated);
  border: 1px solid var(--border);
}

/* Stopka panelu — domknięcie kompozycji: krótka uwaga po lewej,
   wyjście do pełnej oferty po prawej. */
.panel__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-5);
  margin-block-start: var(--space-8);
  padding-block-start: var(--space-6);
  border-block-start: 1px solid rgba(255, 255, 255, 0.14);
}

.panel--light .panel__foot {
  border-block-start-color: var(--border);
}

.panel__note {
  font-size: var(--text-sm);
  color: var(--text-on-dark-muted);
  max-width: 40ch;
}

.panel--light .panel__note {
  color: var(--text-muted);
}


/* ==========================================================================
   PIGUŁKA ETYKIETY (chip)
   Zastępuje klasyczne „— NAGŁÓWEK SEKCJI". Obrysowana pigułka czyta się
   jak znacznik kategorii, a nie jak kolejny wiersz tekstu.
   ========================================================================== */
/* Eyebrow edytorialny: etykieta + krótka kreska w kolorze marki, bez
   obwódki/tła. Pigułka z kropką (poprzednia wersja) czytała się jak
   domyślny badge z gotowego szablonu — kreska jest rzadsza i cichsza,
   a i tak niesie ten sam sygnał "to jest nagłówek kategorii". */
.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  letter-spacing: var(--tracking-widest);
  text-transform: uppercase;
  color: var(--brand);
  white-space: nowrap;
}

.chip::before {
  content: '';
  width: 22px;
  height: 2px;
  flex-shrink: 0;
  background-color: currentColor;
}

.chip--on-dark {
  color: rgba(255, 255, 255, 0.86);
}

/* Wariant na ciemnym tle włączany kontekstem, a nie dodatkową klasą
   w znaczniku — miejsc użycia jest kilkadziesiąt i ręczne pilnowanie
   modyfikatora skończyłoby się rozjazdem. */
.section--inverse .chip,
.panel--dark .chip {
  color: rgba(255, 255, 255, 0.86);
}

/* Wyjątek: hero strony głównej dostaje zieleń marki zamiast bieli —
   ale jasny wariant (--accent-light), bo głęboka zieleń logotypu
   (--brand) na ciemnym wideo byłaby prawie nieczytelna. Selektor
   .hero:not(.hero--page) jak wszędzie indziej w tym projekcie, gdy
   zmiana ma dotyczyć wyłącznie strony głównej — karuzela w sekcji
   Oferta używa tego samego .chip--on-dark i ma zostać biała. */
.hero:not(.hero--page) .chip {
  color: var(--accent-light);
}

/* ==========================================================================
   PRZYCISKI
   Wysokość min. 48px — wymóg dla obsługi w rękawicach (persona: rolnik w terenie).
   ========================================================================== */
.btn {
  --btn-bg: var(--brand);
  --btn-fg: var(--text-inverse);
  --btn-border: transparent;

  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: 3rem;
  padding: var(--space-3) var(--space-6);
  border: 1px solid var(--btn-border);
  border-radius: var(--radius-full);
  background-color: var(--btn-bg);
  color: var(--btn-fg);
  font-family: var(--font-body);
  font-size: var(--text-base);
  font-weight: var(--weight-semibold);
  line-height: 1.2;
  letter-spacing: var(--tracking-tight);
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
  transition: background-color var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out),
              transform var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-fast) var(--ease-out);
}

.btn:hover {
  color: var(--btn-fg);
  transform: translateY(-2px);
  box-shadow: var(--shadow-md);
}

.btn:active {
  transform: translateY(0);
  box-shadow: none;
}

/* Główne CTA — złoto z ciemnozielonym napisem (7.6:1 na panelu, 5.9:1
   na jasnym tle). Jeden kolor akcji na całej stronie, żeby użytkownik
   nie musiał się zastanawiać, co jest klikalne. */
.btn--primary {
  --btn-bg: var(--cta);
  --btn-fg: var(--cta-ink);
}
.btn--primary:hover {
  --btn-bg: var(--cta-hover);
}

/* Wariant zielony — dla akcji drugorzędnych, które i tak muszą być pełne
   (np. przycisk w nagłówku obok złotego CTA byłby dwoma równorzędnymi
   wezwaniami). */
.btn--brand {
  --btn-bg: var(--brand-solid);
  --btn-fg: var(--text-inverse);
}
.btn--brand:hover {
  --btn-bg: var(--brand-hover);
}

/* Okrągły kafel ze strzałką, wciągnięty w prawą krawędź pigułki.
   Sygnał „to prowadzi dalej" bez dokładania słów. */
.btn__badge {
  display: grid;
  place-items: center;
  width: 1.875rem;
  height: 1.875rem;
  margin-inline: var(--space-1) calc(var(--space-3) * -1);
  border-radius: var(--radius-full);
  background-color: color-mix(in srgb, var(--btn-fg) 16%, transparent);
  transition: background-color var(--dur-fast) var(--ease-out),
              transform var(--dur-base) var(--ease-out);
}

.btn__badge svg {
  width: 0.875rem;
  height: 0.875rem;
}

.btn:hover .btn__badge {
  background-color: color-mix(in srgb, var(--btn-fg) 28%, transparent);
  transform: translate(2px, -2px);
}

.btn--lg .btn__badge {
  width: 2.25rem;
  height: 2.25rem;
  margin-inline-end: calc(var(--space-4) * -1);
}

/* Obrys — akcja drugorzędna na jasnym tle */
.btn--secondary {
  --btn-bg: transparent;
  --btn-fg: var(--brand);
  --btn-border: var(--border-strong);
}
.btn--secondary:hover {
  --btn-bg: var(--white);
  --btn-border: var(--brand);
}

/* Na ciemnym tle / na zdjęciu */
.btn--on-dark {
  --btn-bg: rgba(255, 255, 255, 0.1);
  --btn-fg: var(--white);
  --btn-border: rgba(255, 255, 255, 0.4);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
}
.btn--on-dark:hover {
  --btn-bg: var(--white);
  --btn-fg: var(--green-950);
  --btn-border: var(--white);
}

/* Jasna zieleń z ciemnym napisem (5.2:1). Sam kolor logotypu
   (--green-500) dałby tu tylko 3.6:1, więc jako tło przycisku nie wchodzi. */
.btn--accent {
  --btn-bg: var(--accent-bright);
  --btn-fg: var(--green-950);
}
.btn--accent:hover {
  --btn-bg: var(--green-300);
}

.btn--ghost {
  --btn-bg: transparent;
  --btn-fg: var(--brand);
  --btn-border: transparent;
  padding-inline: var(--space-3);
}
.btn--ghost:hover {
  --btn-bg: var(--green-100);
  box-shadow: none;
}

.btn--lg {
  min-height: 3.5rem;
  padding-inline: var(--space-8);
  font-size: var(--text-lg);
}

.btn--block {
  width: 100%;
}

.btn__icon {
  width: 1.125em;
  height: 1.125em;
  flex-shrink: 0;
  transition: transform var(--dur-base) var(--ease-out);
}

.btn:hover .btn__icon--arrow {
  transform: translateX(3px);
}

.btn[disabled],
.btn[aria-disabled='true'] {
  opacity: 0.55;
  pointer-events: none;
}

/* Link ze strzałką — akcja tekstowa */
.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-weight: var(--weight-semibold);
  text-decoration: none;
  color: var(--brand);
}

.link-arrow svg {
  width: 1.1em;
  height: 1.1em;
  transition: transform var(--dur-base) var(--ease-out);
}

.link-arrow:hover svg {
  transform: translateX(4px);
}

/* ==========================================================================
   NAGŁÓWEK STRONY
   ========================================================================== */
.header {
  --header-h: 5rem;
  position: fixed;
  inset-block-start: 0;
  inset-inline: 0;
  z-index: var(--z-header);
  height: var(--header-h);
  display: flex;
  align-items: center;
  transition: background-color var(--dur-base) var(--ease-out),
              box-shadow var(--dur-base) var(--ease-out),
              border-color var(--dur-base) var(--ease-out);
  border-block-end: 1px solid transparent;
}

/* Wariant przezroczysty — tylko nad hero */
.header--transparent {
  background-color: transparent;
}

/* Po przewinięciu: subtelny glass. Jedno z dwóch miejsc w projekcie
   z backdrop-filter — jest kosztowny renderowo. */
.header.is-stuck,
.header:not(.header--transparent) {
  background-color: color-mix(in srgb, var(--sand-50) 82%, transparent);
  backdrop-filter: blur(16px) saturate(180%);
  -webkit-backdrop-filter: blur(16px) saturate(180%);
  border-block-end-color: var(--border);
  box-shadow: var(--shadow-sm);
}

.header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-6);
  width: 100%;
}

/* Nagłówek korzysta ze zwykłego kontenera — tego samego, co treść sekcji
   poniżej hero. */

/* ---- Logotyp ----
   Dwa warianty tego samego znaku: ciemny na jasne tło i jasny na ciemne.
   Oba są w DOM-ie i przełączane widocznością, a nie podmianą atrybutu src —
   podmiana src przy przewijaniu powodowałaby mignięcie pustego miejsca
   w momencie, gdy nagłówek zmienia stan. Łącznie ok. 20 kB, jednorazowo. */
.logo {
  display: inline-flex;
  align-items: center;
  text-decoration: none;
  flex-shrink: 0;
}

/* Logotyp poziomy ma wysoki kafel po lewej, więc przy małej wysokości
   napis obok robi się nieczytelny. 3rem to minimum, przy którym „Centrum
   Rolnicze" pod nazwą da się jeszcze odczytać. */
.logo__img {
  display: block;
  width: auto;
  height: 3rem;
  background-color: transparent;
}

@media (min-width: 48em) {
  .logo__img {
    height: 3.375rem;
  }
}

/* Domyślnie widoczny jest wariant ciemny */
.logo__img--light {
  display: none;
}

.header--transparent:not(.is-stuck) .logo__img--dark {
  display: none;
}

.header--transparent:not(.is-stuck) .logo__img--light {
  display: block;
}

/* Stopka i menu mobilne wymuszają wariant wprost — nie zależą od stanu
   nagłówka, więc trzymają tylko jeden obrazek w znaczniku. */
.logo--on-dark .logo__img--light {
  display: block;
}

/* ---- Nawigacja desktop ---- */
.nav {
  display: none;
}

@media (min-width: 62em) {
  .nav {
    display: flex;
    align-items: center;
    gap: var(--space-1);
  }
}

.nav__link {
  position: relative;
  display: inline-flex;
  align-items: center;
  height: 2.75rem;
  padding-inline: var(--space-4);
  border-radius: var(--radius-full);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  text-decoration: none;
  color: var(--text);
  white-space: nowrap;
  transition: color var(--dur-fast) var(--ease-out),
              background-color var(--dur-fast) var(--ease-out);
}

.nav__link:hover {
  background-color: color-mix(in srgb, var(--green-700) 8%, transparent);
  color: var(--brand);
}

.nav__link[aria-current='page'] {
  color: var(--brand);
  font-weight: var(--weight-semibold);
}

.nav__link[aria-current='page']::after {
  content: '';
  position: absolute;
  inset-block-end: 0.45rem;
  inset-inline: 50%;
  width: 4px;
  height: 4px;
  margin-inline-start: -2px;
  border-radius: var(--radius-full);
  background-color: var(--accent);
}

.header--transparent:not(.is-stuck) .nav__link {
  color: rgba(255, 255, 255, 0.9);
}
.header--transparent:not(.is-stuck) .nav__link:hover,
.header--transparent:not(.is-stuck) .nav__link[aria-current='page'] {
  background-color: rgba(255, 255, 255, 0.14);
  color: var(--white);
}

/* ---- Akcje w nagłówku ---- */
.header__actions {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.header__phone {
  display: none;
}

@media (min-width: 75em) {
  .header__phone {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    font-size: var(--text-sm);
    font-weight: var(--weight-semibold);
    text-decoration: none;
    color: var(--text);
  }
  .header__phone svg {
    width: 1.05em;
    height: 1.05em;
    color: var(--accent-ink);
  }
  .header--transparent:not(.is-stuck) .header__phone {
    color: var(--white);
  }
  .header--transparent:not(.is-stuck) .header__phone svg {
    color: var(--green-300);
  }
}

.header__cta {
  display: none;
}

@media (min-width: 62em) {
  .header__cta {
    display: inline-flex;
  }
}

/* ---- Hamburger ---- */
.nav-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 3rem;
  height: 3rem;
  border-radius: var(--radius-full);
  color: var(--text);
  transition: background-color var(--dur-fast) var(--ease-out);
}

.nav-toggle:hover {
  background-color: color-mix(in srgb, var(--green-700) 8%, transparent);
}

.header--transparent:not(.is-stuck) .nav-toggle {
  color: var(--white);
}
.header--transparent:not(.is-stuck) .nav-toggle:hover {
  background-color: rgba(255, 255, 255, 0.16);
}

@media (min-width: 62em) {
  .nav-toggle {
    display: none;
  }
}

.nav-toggle__bars {
  position: relative;
  width: 22px;
  height: 14px;
}

.nav-toggle__bars span {
  position: absolute;
  inset-inline: 0;
  height: 2px;
  border-radius: 2px;
  background-color: currentColor;
  transition: transform var(--dur-base) var(--ease-out),
              opacity var(--dur-fast) var(--ease-out);
}

.nav-toggle__bars span:nth-child(1) { top: 0; }
.nav-toggle__bars span:nth-child(2) { top: 6px; }
.nav-toggle__bars span:nth-child(3) { top: 12px; }

.nav-toggle[aria-expanded='true'] .nav-toggle__bars span:nth-child(1) {
  transform: translateY(6px) rotate(45deg);
}
.nav-toggle[aria-expanded='true'] .nav-toggle__bars span:nth-child(2) {
  opacity: 0;
}
.nav-toggle[aria-expanded='true'] .nav-toggle__bars span:nth-child(3) {
  transform: translateY(-6px) rotate(-45deg);
}

/* ==========================================================================
   MENU MOBILNE
   ========================================================================== */
.mobile-menu {
  position: fixed;
  inset: 0;
  z-index: var(--z-menu);
  display: flex;
  flex-direction: column;
  padding: calc(var(--header-h, 5rem) + var(--space-6)) var(--gutter) var(--space-8);
  background-color: var(--bg);
  overflow-y: auto;
  overscroll-behavior: contain;
  visibility: hidden;
  opacity: 0;
  transform: translateY(-0.75rem);
  transition: opacity var(--dur-base) var(--ease-out),
              transform var(--dur-base) var(--ease-out),
              visibility 0s linear var(--dur-base);
}

.mobile-menu.is-open {
  visibility: visible;
  opacity: 1;
  transform: translateY(0);
  transition-delay: 0s;
}

@media (min-width: 62em) {
  .mobile-menu {
    display: none;
  }
}

.mobile-menu__list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
}

.mobile-menu__link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  min-height: 3.5rem;
  padding-block: var(--space-3);
  border-block-end: 1px solid var(--border);
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-tight);
  text-decoration: none;
  color: var(--text);
}

.mobile-menu__link[aria-current='page'] {
  color: var(--brand);
}

.mobile-menu__link svg {
  width: 1rem;
  height: 1rem;
  color: var(--text-subtle);
}

.mobile-menu__footer {
  margin-block-start: auto;
  padding-block-start: var(--space-8);
  display: grid;
  gap: var(--space-3);
}

/* ==========================================================================
   HERO
   ========================================================================== */
/* Hero nie jest sekcją rozciągniętą na cały ekran, tylko PANELEM wpuszczonym
   w tło strony: margines dookoła, duże zaokrąglenie, treść u dołu, pasek
   liczb wtopiony w dolną krawędź.

   Wysokość celowo NIE wynosi 100svh. Pełny ekran wypycha pierwszą sekcję
   poza kadr i użytkownik nie widzi, że strona ma ciąg dalszy. Tutaj dolna
   krawędź panelu jest widoczna od razu — to czytelne zaproszenie do przewinięcia. */
.hero {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-height: clamp(34rem, 78svh, 52rem);
  /* Panel dochodzi do samej góry okna. Margines górny zostawiał nad nagłówkiem
     jasny pasek, przez który przezroczysta nawigacja wisiała nad białym tłem —
     wyglądało to na niedokończone, a nie na zamierzony margines karty. */
  margin: 0 var(--panel-inset) var(--panel-inset);
  border-radius: 0 0 var(--radius-panel) var(--radius-panel);
  padding-block-start: calc(var(--header-h, 5rem) + var(--space-10));
  overflow: hidden;
  isolation: isolate;
  color: var(--text-inverse);
}

.hero__media {
  position: absolute;
  inset: 0;
  z-index: -2;
  overflow: hidden;
}

/* Warstwa przesuwana przy parallaksie. Gradient (::after na .hero__media)
   zostaje nieruchomy — gdyby jechał razem z obrazem, przyciemnienie zjeżdżałoby
   z tekstu przy przewijaniu. */
.hero__parallax {
  position: absolute;
  inset: 0;
  will-change: transform;
}

.hero__media img,
.hero__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Wideo tła.
   Startuje niewidoczne i pojawia się dopiero, gdy przeglądarka faktycznie je
   odtwarza. Do tego czasu (a przy wolnym łączu, oszczędzaniu danych lub
   preferencji ograniczonego ruchu — na zawsze) widać kadr statyczny.
   Dzięki temu element LCP to lekki obrazek, nie plik wideo. */
.hero__video {
  opacity: 0;
  transition: opacity 700ms var(--ease-out);
  pointer-events: none;
}

.hero__video.is-playing {
  opacity: 1;
}

/* Przyciemnienie kierunkowe, nie równomierne.
   Tekst siedzi po lewej — tam scrim jest niemal pełny. Prawa strona kadru
   zostaje odsłonięta, żeby zdjęcie było widać, a nie tylko zieloną taflę.
   Druga warstwa to wąski pas pod nagłówkiem: bez niego białe linki
   nawigacji tracą kontrast nad jasnym niebem. */
.hero__media::after {
  content: '';
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to bottom,
      rgba(12, 28, 4, 0.45) 0,
      rgba(12, 28, 4, 0) 10rem),
    linear-gradient(100deg,
      rgba(12, 28, 4, 0.94) 0%,
      rgba(12, 28, 4, 0.80) 28%,
      rgba(12, 28, 4, 0.42) 54%,
      rgba(12, 28, 4, 0.10) 82%,
      rgba(12, 28, 4, 0.04) 100%);
}

.hero__body {
  position: relative;
  z-index: 1;
  display: grid;
  gap: var(--space-8);
  align-items: end;
  /* Treść hero trafia w tę samą kolumnę 1240 px, w której stoją sekcje
     pod nim — inaczej na szerokim ekranie nagłówek startuje przy krawędzi
     panelu, a wszystko poniżej jest wyśrodkowane, i hero „rozjeżdża się"
     w prawo. Wariant „inner": blok nadrzędny to sam panel, nie sekcja. */
  padding: var(--panel-pad) var(--panel-pad-x-inner);
  padding-block-end: clamp(var(--space-8), 4vw, var(--space-12));
}

/* Karta zaufania ląduje obok treści dopiero wtedy, gdy jest na to miejsce.
   Wcześniej stoi pod tekstem — nie chcemy jej zwężać do nieczytelnego paska. */
/* Druga kolumna ma SZTYWNĄ szerokość, nie „auto".
   Przy „auto" ścieżka dopasowuje się do max-content karty, a że karta
   zawiera kilka zdań, jej max-content jest ogromny — kolumna z nagłówkiem
   zapadała się wtedy do zera i tekst łamał się po jednej literze. */
@media (min-width: 64em) {
  .hero__body {
    grid-template-columns: minmax(0, 1fr) 20rem;
    gap: var(--space-12);
  }
}

.hero__content {
  max-width: 46rem;
}

/* Wyłącznie hero strony głównej (nie ma klasy .hero--page) dostaje szerszy,
   bardziej „oddychający" układ. Zamiast kolejnej sztywnej wartości rem,
   zdejmujemy ograniczenie całkowicie — kolumna treści w gridzie hero__body
   i tak jest już ograniczona do (szerokość panelu − 20rem na karty − odstęp),
   więc bez max-width tekst po prostu wypełnia to, co realnie dostępne,
   zamiast urywać się w połowie i zostawiać pusty pas przed kartami. */
.hero:not(.hero--page) .hero__content {
  max-width: none;
}

@media (min-width: 64em) {
  .hero:not(.hero--page) .hero__body {
    gap: var(--space-16);
  }
}

.hero__title {
  margin-block-start: var(--space-5);
  font-size: var(--text-hero);
  font-weight: var(--weight-extra);
  line-height: 1.03;
  letter-spacing: var(--tracking-tighter);
  color: var(--white);
}

/* Pomiędzy bazowym --text-hero (do 80px, za ciężki przy szerszej kolumnie)
   a pierwszą poprawką (64px, okazało się za skromne). Szczyt 72px —
   wyraźnie większy niż na podstronach (56px), bez „krzyczenia". */
.hero:not(.hero--page) .hero__title {
  margin-block-start: var(--space-6);
  font-size: clamp(2.5rem, 1.6rem + 3.6vw, 4.5rem);
}

/* Wyróżnienie w nagłówku zawsze złotem — tym samym kolorem co przyciski.
   Zieleń zostaje kolorem konstrukcji (panele, logotyp, ikony), złoto niesie
   uwagę. Mieszanie tych ról sprawia, że żaden z nich nic nie znaczy. */
.hero__title em {
  font-style: normal;
  color: var(--accent);
}

.hero__lead {
  margin-block-start: var(--space-6);
  max-width: 34rem;
  font-size: var(--text-lg);
  line-height: var(--leading-snug);
  color: rgba(255, 255, 255, 0.86);
}

/* Rozmiar zostaje przy bazowym --text-lg — wcześniejsze --text-xl przy
   poszerzonej kolumnie robiło zbyt długie i zbyt grube wiersze naraz.
   Węższy max-width niż u nagłówka to celowe: akapit czyta się dobrze
   do ok. 65–75 znaków w wierszu, powyżej tego oko się gubi — inaczej
   niż nagłówek, który może iść na pełną szerokość kolumny. */
.hero:not(.hero--page) .hero__lead {
  margin-block-start: var(--space-8);
  max-width: 42rem;
}

.hero__actions {
  margin-block-start: var(--space-8);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
}

.hero:not(.hero--page) .hero__actions {
  margin-block-start: var(--space-10);
  gap: var(--space-4);
}

/* ---- Pasek liczb wtopiony w dolną krawędź panelu ----
   W referencji to element, który najmocniej buduje wrażenie „konkretu":
   zamiast osobnej sekcji ze statystykami, liczby są częścią pierwszego
   ekranu i domykają kompozycję panelu. */
.statbar {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  border-block-start: 1px solid rgba(255, 255, 255, 0.16);
  background-color: rgba(15, 33, 3, 0.35);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  /* Wcięcie boczne siedzi na PASKU, nie na polach. Procent w --panel-pad-x-inner
     liczy się od bloku nadrzędnego: tu jest nim cały panel hero, więc pierwsza
     liczba trafia dokładnie pod nagłówek. Gdyby padding stał na polu, procent
     liczyłby się od jednej kolumny siatki i wcięcie by nie działało. */
  padding-inline: var(--panel-pad-x-inner);
}

@media (min-width: 56em) {
  .statbar {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

.statbar__item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding-block: clamp(var(--space-4), 2vw, var(--space-6));
  padding-inline: var(--space-6);
  border-block-start: 1px solid rgba(255, 255, 255, 0.1);
}

/* Skrajne pola przylegają do krawędzi kolumny (bez wewnętrznego odstępu) —
   pierwsza liczba pod nagłówkiem, ostatnia równo z prawą krawędzią treści. */
.statbar__item:nth-of-type(odd) { padding-inline-start: 0; }
.statbar__item:nth-of-type(even) { padding-inline-end: 0; }

@media (min-width: 56em) {
  .statbar__item { padding-inline: var(--space-6); }
  .statbar__item:first-of-type { padding-inline-start: 0; }
  .statbar__item:last-of-type { padding-inline-end: 0; }
}

/* Pierwsze dwa elementy tworzą górny rząd na mobile — nie potrzebują
   kreski nad sobą, bo mają ją już od paska. */
.statbar__item:nth-of-type(-n + 2) {
  border-block-start: none;
}

@media (min-width: 56em) {
  .statbar__item {
    border-block-start: none;
    border-inline-start: 1px solid rgba(255, 255, 255, 0.14);
  }
  .statbar__item:first-of-type {
    border-inline-start: none;
  }
}

/* Na mobile kolumny rozdziela pionowa kreska między parami */
.statbar__item:nth-of-type(odd) {
  border-inline-end: 1px solid rgba(255, 255, 255, 0.14);
}

@media (min-width: 56em) {
  .statbar__item:nth-of-type(odd) {
    border-inline-end: none;
  }
}

.statbar__icon {
  display: grid;
  place-items: center;
  width: 2.25rem;
  height: 2.25rem;
  flex-shrink: 0;
  border-radius: var(--radius-full);
  background-color: rgba(255, 255, 255, 0.1);
  color: var(--accent);
}

.statbar__icon svg {
  width: 1.125rem;
  height: 1.125rem;
}

.statbar__value {
  display: block;
  font-family: var(--font-display);
  font-size: clamp(1.375rem, 1.1rem + 1.1vw, 1.875rem);
  font-weight: var(--weight-extra);
  line-height: 1.05;
  letter-spacing: var(--tracking-tighter);
  color: var(--white);
  font-variant-numeric: tabular-nums;
}

.statbar__suffix {
  color: var(--accent);
}

.statbar__label {
  display: block;
  margin-block-start: 2px;
  font-size: var(--text-xs);
  line-height: 1.3;
  color: rgba(255, 255, 255, 0.68);
}

/* ---- Stos kart dowodowych ----
   Google na górze, Rzetelna Firma pod spodem. Na desktopie obie karty
   siedzą w tej samej, sztywnej kolumnie hero__body (20rem) — parent ma
   align-items:end, więc cały stos „wisi" od dołu wiersza w górę, dokładnie
   w miejscu, które wcześniej było pustym fragmentem zdjęcia nad kartą
   Rzetelnej Firmy. */
.hero__proof-stack {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  width: 100%;
}

/* ---- Pływająca karta zaufania ----
   Odpowiednik karty z ocenami z referencji. Zamiast wymyślonych gwiazdek
   pokazujemy realny, weryfikowalny dowód: wizytówkę w programie
   weryfikacji przedsiębiorców. */
.hero__proof {
  display: block;
  width: 100%;
  padding: var(--space-5);
  border-radius: var(--radius-lg);
  background-color: rgba(255, 255, 255, 0.94);
  backdrop-filter: blur(14px) saturate(160%);
  -webkit-backdrop-filter: blur(14px) saturate(160%);
  border: 1px solid rgba(255, 255, 255, 0.55);
  box-shadow: var(--shadow-xl);
  text-decoration: none;
  color: var(--text);
  transition: transform var(--dur-base) var(--ease-out),
              box-shadow var(--dur-base) var(--ease-out);
}

.hero__proof:hover {
  transform: translateY(-3px);
  color: var(--text);
}

.hero__proof img {
  width: 7rem;
  height: auto;
  background-color: transparent;
}

/* Na wąskim ekranie karta stoi w kolumnie pod treścią i rozpycha hero.
   Skracamy ją do samego sedna — pełny opis jest w stopce i na „O nas". */
@media (max-width: 63.99em) {
  .hero__proof {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    align-items: center;
    gap: var(--space-4);
    width: 100%;
    padding: var(--space-4);
  }
  .hero__proof img {
    width: 5rem;
  }
  .hero__proof-title {
    margin-block-start: 0;
    font-size: var(--text-sm);
  }
  .hero__proof-text {
    display: none;
  }
  .hero__proof-link {
    grid-column: 2;
    margin-block-start: var(--space-1);
  }
}

.hero__proof-title {
  margin-block-start: var(--space-4);
  font-family: var(--font-display);
  font-size: var(--text-base);
  font-weight: var(--weight-bold);
  letter-spacing: var(--tracking-tight);
  line-height: 1.25;
}

.hero__proof-text {
  margin-block-start: var(--space-2);
  font-size: var(--text-xs);
  line-height: 1.45;
  color: var(--text-muted);
}

.hero__proof-link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin-block-start: var(--space-4);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  color: var(--accent-ink);
}

.hero__proof-link svg {
  width: 0.85em;
  height: 0.85em;
  transition: transform var(--dur-base) var(--ease-out);
}

.hero__proof:hover .hero__proof-link svg {
  transform: translate(2px, -2px);
}

/* ---- Wariant: ocena Google ----
   Ten sam kafel co Rzetelna Firma (biel, blur, cień), inna treść: mały
   znak marki zamiast szerokiego logotypu, i rząd z gwiazdkami zamiast
   akapitu opisu. Dane wstrzykuje build.py z assets/data/opinie.json —
   patrz funkcja hero_ocena_google(); karta w ogóle się nie renderuje,
   dopóki nie ma tam realnej oceny z Google. */
.hero__proof-google-icon {
  width: 1.75rem;
  height: 1.75rem;
}

.hero__proof--google .hero__proof-title {
  margin-block-start: var(--space-3);
}

.hero__proof-rating {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin-block-start: var(--space-2);
  font-size: var(--text-sm);
}

.hero__proof-rating strong {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: var(--weight-extra);
  color: var(--text);
}

.hero__proof-rating-count {
  color: var(--text-muted);
}

.hero__proof--google .hero__proof-link {
  margin-block-start: var(--space-3);
}

/* Ten sam kompaktowy układ co bazowa karta (ikona w kolumnie 1, treść
   w kolumnie 2), ale jawnie rozmieszczony na trzech wierszach — przy
   czterech widocznych dzieciach (ikona, tytuł, ocena, link) automatyczne
   przepływanie siatki 2-kolumnowej rozrzuciłoby je w złej kolejności. */
@media (max-width: 63.99em) {
  .hero__proof--google .hero__proof-google-icon {
    grid-column: 1;
    grid-row: 1 / -1;
    align-self: start;
    margin-block-start: 0.2em;
  }
  .hero__proof--google .hero__proof-title {
    grid-column: 2;
    grid-row: 1;
    margin-block-start: 0;
  }
  .hero__proof--google .hero__proof-rating {
    grid-column: 2;
    grid-row: 2;
    margin-block-start: var(--space-1);
  }
  .hero__proof--google .hero__proof-link {
    grid-column: 2;
    grid-row: 3;
    margin-block-start: var(--space-1);
  }
}

/* ---- Hero podstrony ---- */
.hero--page {
  min-height: min(58svh, 30rem);
  padding-block-start: calc(var(--header-h, 5rem) + var(--space-8));
}

.hero--page .hero__body {
  padding-block-end: clamp(var(--space-8), 4vw, var(--space-12));
  /* Treść hero staje w tej samej kolumnie co sekcje pod nim.
     Wariant „inner" — blok nadrzędny to sam panel hero, nie sekcja. */
  padding-inline: var(--panel-pad-x-inner);
}

.hero--page .hero__title {
  font-size: var(--text-4xl);
}

/* Hero podstrony jest niski i tekst rozciąga się na całą jego szerokość —
   kierunkowy scrim ze strony głównej zostawiłby prawą krawędź nagłówka
   nad jasnym fragmentem zdjęcia. Tu przyciemnienie musi sięgać dalej. */
.hero--page .hero__media::after {
  background:
    linear-gradient(to bottom,
      rgba(12, 28, 4, 0.50) 0,
      rgba(12, 28, 4, 0) 10rem),
    linear-gradient(100deg,
      rgba(12, 28, 4, 0.95) 0%,
      rgba(12, 28, 4, 0.88) 42%,
      rgba(12, 28, 4, 0.68) 72%,
      rgba(12, 28, 4, 0.50) 100%);
}

/* ==========================================================================
   OKRUSZKI
   ========================================================================== */
.breadcrumb {
  font-size: var(--text-sm);
}

.breadcrumb ol {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  list-style: none;
  padding: 0;
  margin: 0;
}

.breadcrumb li::after {
  content: '/';
  margin-inline-start: var(--space-2);
  color: rgba(255, 255, 255, 0.4);
}

.breadcrumb li:last-child::after {
  content: none;
}

.breadcrumb a {
  color: rgba(255, 255, 255, 0.78);
  text-decoration: none;
}

.breadcrumb a:hover {
  color: var(--white);
  text-decoration: underline;
}

.breadcrumb [aria-current='page'] {
  color: var(--white);
  font-weight: var(--weight-medium);
}

/* ==========================================================================
   STATYSTYKI / LICZNIKI
   ========================================================================== */
.stats {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-8) var(--space-6);
}

@media (min-width: 56em) {
  .stats {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: var(--space-6);
  }
}

.stat {
  position: relative;
  padding-inline-start: var(--space-5);
  border-inline-start: 2px solid color-mix(in srgb, var(--accent) 45%, transparent);
}

.section--inverse .stat {
  border-inline-start-color: rgba(255, 255, 255, 0.24);
}

.stat__value {
  display: block;
  font-family: var(--font-display);
  font-size: clamp(2.25rem, 1.6rem + 2.6vw, 3.5rem);
  font-weight: var(--weight-extra);
  line-height: var(--leading-none);
  letter-spacing: var(--tracking-tighter);
  color: var(--brand);
  font-variant-numeric: tabular-nums;
}

.section--inverse .stat__value {
  color: var(--white);
}

.stat__suffix {
  color: var(--accent);
}

.stat__label {
  display: block;
  margin-block-start: var(--space-3);
  font-size: var(--text-sm);
  line-height: var(--leading-snug);
  color: var(--text-muted);
}

.section--inverse .stat__label {
  color: var(--text-on-dark-muted);
}

/* ==========================================================================
   KARTA KATEGORII (ze zdjęciem)
   ========================================================================== */
.card {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-height: 15rem;
  padding: var(--space-6);
  border-radius: var(--radius-lg);
  overflow: hidden;
  isolation: isolate;
  color: var(--text-inverse);
  background-color: var(--green-900);
  transition: transform var(--dur-base) var(--ease-out),
              box-shadow var(--dur-base) var(--ease-out);
}

.card:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-lg);
}

.card__media {
  position: absolute;
  inset: 0;
  z-index: -2;
}

.card__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 700ms var(--ease-out);
}

.card:hover .card__media img {
  transform: scale(1.06);
}

.card__media::after {
  content: '';
  position: absolute;
  inset: 0;
  /* Scrim musi wytrzymać najgorszy przypadek: białe pismo na prześwietlonym
     zdjęciu (kłos w słońcu, niebo). Stąd 0.88 jeszcze na 30% wysokości —
     tyle zajmuje blok tekstu na najmniejszej karcie. */
  background: linear-gradient(to top,
    rgba(16, 38, 23, 0.96) 0%,
    rgba(16, 38, 23, 0.88) 30%,
    rgba(16, 38, 23, 0.62) 52%,
    rgba(16, 38, 23, 0.28) 76%,
    rgba(16, 38, 23, 0.14) 100%);
  transition: opacity var(--dur-base) var(--ease-out);
}

.card__icon {
  width: 2.75rem;
  height: 2.75rem;
  margin-block-end: auto;
  display: grid;
  place-items: center;
  border-radius: var(--radius-full);
  background-color: rgba(255, 255, 255, 0.14);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  color: var(--green-300);
}

.card__icon svg {
  width: 1.375rem;
  height: 1.375rem;
}

.card__title {
  margin-block-start: var(--space-6);
  font-size: var(--text-xl);
  color: var(--white);
}

.card--lg .card__title {
  font-size: var(--text-2xl);
}

.card__text {
  margin-block-start: var(--space-2);
  max-width: 32ch;
  font-size: var(--text-sm);
  line-height: var(--leading-snug);
  color: rgba(255, 255, 255, 0.82);
}

.card--lg .card__text {
  font-size: var(--text-base);
  max-width: 40ch;
}

/* „Stretched link" — całą kartę robi klikalną bez zagnieżdżania <a> w <a>
   i bez div[onclick]. Link pozostaje jedynym elementem interaktywnym. */
.card__link::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  border-radius: inherit;
}

.card__link {
  color: inherit;
  text-decoration: none;
  font-weight: var(--weight-semibold);
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin-block-start: var(--space-5);
  font-size: var(--text-sm);
}

.card__link svg {
  width: 1em;
  height: 1em;
  transition: transform var(--dur-base) var(--ease-out);
}

.card:hover .card__link svg {
  transform: translateX(4px);
}

.card:focus-within {
  outline: 3px solid var(--focus-ring);
  outline-offset: 3px;
}

.card__link:focus-visible {
  outline: none;
}

/* ==========================================================================
   KARTA MARKI (premium)
   ========================================================================== */
.brand-card {
  position: relative;
  display: flex;
  flex-direction: column;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background-color: var(--bg-elevated);
  border: 1px solid var(--border);
  transition: transform var(--dur-base) var(--ease-out),
              box-shadow var(--dur-base) var(--ease-out),
              border-color var(--dur-base) var(--ease-out);
}

.brand-card:hover {
  transform: translateY(-5px);
  box-shadow: var(--shadow-xl);
  border-color: transparent;
}

.brand-card__media {
  position: relative;
  aspect-ratio: 3 / 2;
  overflow: hidden;
  background-color: var(--sand-100);
}

.brand-card__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 700ms var(--ease-out);
}

.brand-card:hover .brand-card__media img {
  transform: scale(1.05);
}

.brand-card__badge {
  position: absolute;
  inset-block-start: var(--space-4);
  inset-inline-start: var(--space-4);
  z-index: 1;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-full);
  background-color: rgba(255, 255, 255, 0.92);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--green-700);
}

.brand-card__badge svg {
  width: 0.85rem;
  height: 0.85rem;
  color: var(--accent-ink);
}

.brand-card__body {
  display: flex;
  flex-direction: column;
  flex: 1;
  padding: var(--space-6) var(--space-6) var(--space-8);
}

.brand-card__title {
  font-size: var(--text-2xl);
  font-weight: var(--weight-extra);
  letter-spacing: var(--tracking-tighter);
  color: var(--brand);
}

.brand-card__text {
  margin-block-start: var(--space-3);
  font-size: var(--text-base);
  color: var(--text-muted);
}

.brand-card__meta {
  margin-block-start: var(--space-5);
  padding-block-start: var(--space-5);
  border-block-start: 1px solid var(--border);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  list-style: none;
  padding-inline: 0;
}

.brand-card__foot {
  margin-block-start: auto;
  padding-block-start: var(--space-6);
}

.brand-card__link::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
}

.brand-card:focus-within {
  outline: 3px solid var(--focus-ring);
  outline-offset: 3px;
}

.brand-card__link:focus-visible {
  outline: none;
}

/* ==========================================================================
   PIGUŁKA / TAG
   ========================================================================== */
.pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-full);
  background-color: var(--green-100);
  color: var(--green-700);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  white-space: nowrap;
}

/* Wariant dla pojedynczego, twardego faktu (liczba wariantów/formuł) —
   inny odcień niż zwykłe tagi kategorii, żeby oko od razu wyłapało liczbę. */
.pill--wheat {
  background-color: var(--wheat-100);
  border: 1px solid color-mix(in srgb, var(--wheat-700) 25%, transparent);
  color: var(--wheat-700);
  font-weight: var(--weight-semibold);
}

.pill--outline {
  background-color: transparent;
  border: 1px solid var(--border-strong);
  color: var(--text-muted);
}

/* ==========================================================================
   CECHA (ikona + tekst)
   ========================================================================== */
.feature {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-6);
  border-radius: var(--radius-md);
  background-color: var(--bg-elevated);
  border: 1px solid var(--border);
  transition: border-color var(--dur-base) var(--ease-out),
              box-shadow var(--dur-base) var(--ease-out),
              transform var(--dur-base) var(--ease-out);
}

.feature:hover {
  border-color: color-mix(in srgb, var(--accent) 40%, transparent);
  box-shadow: var(--shadow-md);
  transform: translateY(-3px);
}

.feature__icon {
  width: 3rem;
  height: 3rem;
  display: grid;
  place-items: center;
  border-radius: var(--radius-md);
  background-color: var(--green-100);
  color: var(--green-700);
}

.feature__icon svg {
  width: 1.5rem;
  height: 1.5rem;
}

.feature__title {
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
}

.feature__text {
  font-size: var(--text-sm);
  line-height: var(--leading-base);
  color: var(--text-muted);
}

/* Wariant bez ramki — na ciemnym tle */
.feature--bare {
  background-color: transparent;
  border-color: transparent;
  padding: 0;
}

.feature--bare:hover {
  transform: none;
  box-shadow: none;
  border-color: transparent;
}

.section--inverse .feature__icon {
  background-color: rgba(255, 255, 255, 0.1);
  color: var(--green-300);
}

.section--inverse .feature__text {
  color: var(--text-on-dark-muted);
}

/* ==========================================================================
   PARTNERZY / DYSTRYBUCJA

   Kafle z logotypami producentów. Pięć znaków o zupełnie różnych proporcjach
   (LOVOL jest bardzo szeroki, OrCal prawie 4:1, Syngenta z listkiem nad
   tekstem) — dlatego logotyp dostaje pole o STAŁEJ wysokości, a sam skaluje
   się w nim przez object-fit. Bez tego każdy kafel miałby inną linię bazową
   i rząd wyglądałby na krzywy.
   ========================================================================== */
.partners {
  display: grid;
  gap: clamp(var(--space-4), 1.6vw, var(--space-5));
  /* Liczba kolumn narzucona wprost, nie przez auto-fit. Przy pięciu kaflach
     automat lubi wyliczyć cztery kolumny i zostawić piąty kafel samotnie
     w drugim rzędzie — wygląda to na błąd, a nie na decyzję. */
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

@media (min-width: 48em) {
  .partners { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (min-width: 75em) {
  .partners { grid-template-columns: repeat(5, minmax(0, 1fr)); }
}

.partner {
  /* Wysokość odznaki trzymana w jednym miejscu: używa jej i sama odznaka,
     i pusty placeholder w kaflach bez odznaki. */
  --badge-h: 1.6875rem;

  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-6);
  border-radius: var(--radius-md);
  /* Biel, nie kolor marki — logotypy producentów bywają dostarczane
     z białym tłem wtopionym w plik i na barwnym kaflu tworzyłyby prostokąt. */
  background-color: var(--white);
  border: 1px solid var(--border);
  text-decoration: none;
  color: var(--text);
  transition: border-color var(--dur-base) var(--ease-out),
              box-shadow var(--dur-base) var(--ease-out),
              transform var(--dur-base) var(--ease-out);
}

.partner:hover {
  transform: translateY(-3px);
  border-color: color-mix(in srgb, var(--brand) 28%, transparent);
  box-shadow: var(--shadow-md);
  color: var(--text);
}

/* ---- Pole logotypu ---- */
.partner__logo {
  display: flex;
  align-items: center;
  height: 2.5rem;
  margin-block-end: var(--space-1);
}

.partner__logo img {
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
  object-position: left center;
  background-color: transparent;
  /* Delikatne stonowanie: pięć obcych palet obok siebie potrafi krzyczeć.
     Na hover znak wraca do pełnej mocy. */
  filter: saturate(0.88);
  transition: filter var(--dur-base) var(--ease-out);
}

.partner:hover .partner__logo img {
  filter: saturate(1);
}

/* Zapasowa wersja, gdy pliku z logotypem jeszcze nie ma */
.partner__logo--tekst {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: var(--weight-extra);
  letter-spacing: var(--tracking-tight);
  color: var(--brand);
}

.partner__desc {
  flex: 1;
  font-size: var(--text-sm);
  line-height: var(--leading-snug);
  color: var(--text-muted);
}

.partner__go {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  color: var(--accent-ink);
}

.partner__go svg {
  width: 0.9em;
  height: 0.9em;
  transition: transform var(--dur-base) var(--ease-out);
}

.partner:hover .partner__go svg {
  transform: translate(2px, -2px);
}

/* ---- Kafel wyróżniony (LOVOL — jedyna marka, której jesteśmy
        autoryzowanym dystrybutorem maszyn) ---- */
.partner--featured {
  border-color: color-mix(in srgb, var(--accent) 55%, transparent);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent) 25%, transparent);
}

.partner--featured:hover {
  border-color: var(--accent);
}

.partner__badge {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  height: var(--badge-h);
  padding-inline: 0.6rem;
  border-radius: var(--radius-full);
  background-color: var(--green-100);
  font-size: 0.6875rem;
  font-weight: var(--weight-bold);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--highlight-ink);
}

/* Kafle bez odznaki dostają pusty element tej samej wysokości, żeby
   wszystkie logotypy w rzędzie stały na jednej linii. Rozwiązanie przez
   marginesy było wrażliwe na zmianę wysokości odznaki — tutaj obie wartości
   biorą się z tej samej zmiennej i nie da się ich rozjechać. */
.partner:not(.partner--featured)::before {
  content: '';
  display: block;
  height: var(--badge-h);
}

@media (max-width: 47.99em) {
  .partner:not(.partner--featured)::before {
    display: none;
  }
}

/* ==========================================================================
   SLIDER OPINII
   Scroll Snap + przyciski. Zero biblioteki, działa bez JS.
   ========================================================================== */
.slider {
  position: relative;
}

/* Flexbox, nie Grid. Karuzela sizinguje karty przez procent szerokości na
   .slider__item, nie przez grid-auto-columns — z dobrego powodu.

   Gdy tor jest jednocześnie kontenerem grida I ma overflow-x:auto, procent
   w grid-auto-columns tworzy zależność kołową: szerokość toru miałaby
   zależeć od torów, a tory liczą się z procentu szerokości toru. Chrome
   rozwiązuje to po cichu, dzieląc miejsce po równo między WSZYSTKIE elementy
   zamiast trzymać zadaną szerokość — przy 5 kartach dostajemy 5 ściśniętych
   kolumn zamiast 3 szerokich ze scrollem do pozostałych dwóch.
   Flexbox tej niejednoznaczności nie ma: item o stałej szerokości (flex: none)
   po prostu ją zachowuje, a nadmiar elementów przelewa się w scroll. */
.slider__track {
  display: flex;
  gap: var(--space-5);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  scrollbar-width: none;
  /* Zapas, żeby cień karty nie był przycinany przez overflow */
  padding: var(--space-2) var(--space-1) var(--space-6);
  margin-inline: calc(var(--space-1) * -1);
}

.slider__track::-webkit-scrollbar {
  display: none;
}

.slider__item {
  flex: none;
  width: min(100%, 26rem);
  scroll-snap-align: start;
}

.slider__controls {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.slider__btn {
  display: grid;
  place-items: center;
  width: 3rem;
  height: 3rem;
  border-radius: var(--radius-full);
  border: 1px solid var(--border-strong);
  background-color: var(--bg-elevated);
  color: var(--brand);
  transition: background-color var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out);
}

.slider__btn:hover:not([disabled]) {
  background-color: var(--brand);
  border-color: var(--brand);
  color: var(--white);
}

.slider__btn[disabled] {
  opacity: 0.4;
  cursor: not-allowed;
}

.slider__btn svg {
  width: 1.125rem;
  height: 1.125rem;
}

/* ---- Slider na ciemnym panelu ---- */
.slider--on-dark .slider__btn {
  background-color: rgba(255, 255, 255, 0.08);
  border-color: rgba(255, 255, 255, 0.24);
  color: var(--white);
}

.slider--on-dark .slider__btn:hover:not([disabled]) {
  background-color: var(--cta);
  border-color: var(--cta);
  color: var(--cta-ink);
}

/* Kursor sygnalizuje, że karuzelę można ciągnąć myszą */
.slider__track--draggable {
  cursor: grab;
}

.slider__track--draggable.is-dragging {
  cursor: grabbing;
  scroll-snap-type: none;
  scroll-behavior: auto;
}

/* Podczas przeciągania blokujemy kliknięcia w karty — inaczej puszczenie
   przycisku myszy po przewinięciu otwierałoby przypadkową podstronę. */
.slider__track--draggable.is-dragging a {
  pointer-events: none;
}

/* ==========================================================================
   KARTA OFERTY (karuzela)
   ========================================================================== */
/* .offer-card żyje wyłącznie na ciemnych panelach (Oferta, Marki własne).
   Tokeny --shadow-* są dostrojone pod jasne tło i na czerni prawie znikają
   — stąd własny, znacznie mocniejszy cień, żeby karta realnie odklejała się
   od panelu, a nie tylko kontrastowała kolorem. */
.offer-card {
  position: relative;
  display: flex;
  flex-direction: column;
  height: 100%;
  padding: var(--space-4);
  border-radius: var(--radius-lg);
  background-color: var(--bg-elevated);
  color: var(--text);
  border: 1px solid rgba(255, 255, 255, 0.06);
  box-shadow: 0 24px 48px -20px rgba(0, 0, 0, 0.55),
              0 8px 20px -10px rgba(0, 0, 0, 0.35);
  transition: transform var(--dur-base) var(--ease-out),
              box-shadow var(--dur-base) var(--ease-out),
              border-color var(--dur-base) var(--ease-out);
}

.offer-card:hover {
  transform: translateY(-4px);
  border-color: rgba(255, 255, 255, 0.16);
  box-shadow: 0 32px 64px -20px rgba(0, 0, 0, 0.6),
              0 14px 28px -10px rgba(0, 0, 0, 0.4);
}

.offer-card__media {
  position: relative;
  aspect-ratio: 4 / 3;
  border-radius: var(--radius-md);
  overflow: hidden;
  background-color: var(--sand-100);
}

.offer-card__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 700ms var(--ease-out);
}

.offer-card:hover .offer-card__media img {
  transform: scale(1.05);
}

.offer-card__pill {
  position: absolute;
  inset-block-start: var(--space-3);
  inset-inline-start: var(--space-3);
  z-index: 1;
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.3rem 0.7rem;
  border-radius: var(--radius-full);
  background-color: rgba(255, 255, 255, 0.94);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  font-size: 0.6875rem;
  font-weight: var(--weight-bold);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--brand);
}

.offer-card__pill svg {
  width: 0.7rem;
  height: 0.7rem;
  color: var(--accent-ink);
}

.offer-card__body {
  display: flex;
  flex-direction: column;
  flex: 1;
  /* Dolny odstęp musi zmieścić okrągły przycisk w rogu (2.75rem + margines),
     inaczej ostatni wiersz opisu wchodzi pod strzałkę. */
  padding: var(--space-5) var(--space-2) 3.25rem;
}

.offer-card__title {
  font-size: var(--text-xl);
  font-weight: var(--weight-extra);
  letter-spacing: var(--tracking-tight);
  color: var(--text);
}

.offer-card__title a {
  color: inherit;
}

.offer-card__text {
  margin-block-start: var(--space-3);
  font-size: var(--text-sm);
  line-height: var(--leading-base);
  color: var(--text-muted);
}

/* Dodatkowe tagi — tylko tam, gdzie treść tego wymaga (marki własne).
   Zwykłe karty kategorii z Oferty nie mają tego elementu w HTML,
   więc reguła na nie nie działa. Jeden wyróżniony fakt (pill) plus reszta
   jako cichy podpis tekstowy — cztery równe piguły obok siebie robiły
   z karty tablicę naklejek zamiast eleganckiego opisu. */
.offer-card__meta {
  margin-block-start: var(--space-4);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-3);
}

.offer-card__tags {
  font-size: var(--text-xs);
  color: var(--text-subtle);
}

.offer-card__go {
  position: absolute;
  inset-block-end: var(--space-4);
  inset-inline-end: var(--space-4);
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: var(--radius-full);
  background-color: var(--green-100);
  color: var(--brand);
  transition: background-color var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out),
              transform var(--dur-base) var(--ease-out);
}

.offer-card__go svg {
  width: 1.125rem;
  height: 1.125rem;
}

.offer-card:hover .offer-card__go {
  background-color: var(--cta);
  color: var(--cta-ink);
  transform: translate(2px, -2px);
}

/* Cała karta klikalna przez rozciągnięty link w nagłówku.
   Okrągły przycisk jest wyłącznie ozdobą (aria-hidden) — gdyby to on niósł
   link, jego pseudoelement zakotwiczyłby się na nim samym, a nie na karcie,
   bo element pozycjonowany absolutnie tworzy własny blok odniesienia. */
.offer-card__link {
  color: inherit;
  text-decoration: none;
}

.offer-card__link::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 2;
  border-radius: inherit;
}

.offer-card:focus-within {
  outline: 3px solid var(--focus-ring);
  outline-offset: 3px;
}

.offer-card__link:focus-visible {
  outline: none;
}

/* Karta oferty na ciemnym panelu (Marki własne): biała karta w tym miejscu
   czytała się jako płaski, oderwany "biały prostokąt" — zbyt ostry skok
   kontrastu wobec premium, ciemnej stylistyki panelu (ten sam problem,
   który poświata w layout.css rozwiązuje dla samego tła panelu, karta
   go sobie z powrotem odtwarzała). Zamiast białego tła: przyciemniona,
   "szklana" powierzchnia w tonie panelu, zdjęcie od krawędzi do krawędzi
   z przejściem w tło karty u dołu — kadr staje się częścią karty,
   nie naklejką na niej. Dotyczy wyłącznie .section--inverse — karty
   w jasnej sekcji "Oferta" (ten sam komponent) zostają bez zmian. */
.section--inverse .offer-card {
  padding: 0;
  background-color: color-mix(in srgb, var(--white) 6%, transparent);
  border-color: rgba(255, 255, 255, 0.1);
  color: var(--text-inverse);
}

/* Specyficzność musi przebić .section--inverse .offer-card h3 (layout.css,
   ciemny tekst z czasów białej karty) — stąd powtórzona klasa karty. */
.section--inverse .offer-card .offer-card__title {
  color: var(--text-inverse);
}

.section--inverse .offer-card__media {
  aspect-ratio: 5 / 4;
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  background-color: rgba(255, 255, 255, 0.04);
}

.section--inverse .offer-card__media::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom, transparent 60%, rgba(9, 14, 14, 0.92) 100%);
  pointer-events: none;
}

.section--inverse .offer-card__body {
  padding: var(--space-5) var(--space-5) 3.25rem;
}

.section--inverse .offer-card__text {
  color: var(--text-on-dark-muted);
}

.section--inverse .offer-card__tags {
  color: var(--text-on-dark-muted);
  opacity: 0.85;
}

.section--inverse .offer-card__go {
  background-color: rgba(255, 255, 255, 0.12);
  color: var(--text-inverse);
}

.section--inverse .offer-card:hover .offer-card__go {
  background-color: var(--cta);
  color: var(--cta-ink);
}

/* ==========================================================================
   OCENA W GWIAZDKACH
   ========================================================================== */
.rating {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  color: var(--wheat-600);
}

.rating svg {
  width: 1.05rem;
  height: 1.05rem;
  fill: currentColor;
  stroke: none;
}

/* Gwiazdki „do pełna" — ledwie zaznaczone, żeby nie konkurowały z oceną */
.rating svg.is-empty {
  color: var(--border-strong);
}

/* Podsumowanie pod nagłówkiem sekcji */
.rating-summary {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-3);
  margin-block-start: var(--space-4);
  font-size: var(--text-sm);
  color: var(--text-muted);
}

.rating-summary strong {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: var(--weight-extra);
  color: var(--text);
}

/* Nagłówek karty: ocena po lewej, znak źródła po prawej */
.quote__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}

.quote__source {
  width: 1.25rem;
  height: 1.25rem;
  flex-shrink: 0;
  /* Logotyp Google ma własne kolory — nie wolno go przemalowywać */
  fill: none;
  stroke: none;
}

.reviews-note {
  margin-block-start: var(--space-5);
  font-size: var(--text-xs);
  color: var(--text-subtle);
  max-width: none;
}

.reviews-note a {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-weight: var(--weight-semibold);
  color: var(--accent-ink);
  text-decoration: none;
}

.reviews-note a svg {
  width: 0.85em;
  height: 0.85em;
}

.reviews-note a:hover {
  text-decoration: underline;
  text-underline-offset: 0.25em;
}

/* ---- Karta opinii ---- */
.quote {
  display: flex;
  flex-direction: column;
  height: 100%;
  padding: var(--space-8) var(--space-6) var(--space-6);
  border-radius: var(--radius-lg);
  background-color: var(--bg-elevated);
  border: 1px solid var(--border);
}

.quote__mark {
  width: 2rem;
  height: 2rem;
  color: var(--green-300);
}

.quote__text {
  margin-block-start: var(--space-4);
  font-size: var(--text-base);
  line-height: var(--leading-base);
  max-width: none;
}

.quote__foot {
  margin-block-start: auto;
  padding-block-start: var(--space-6);
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.quote__avatar {
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  flex-shrink: 0;
  border-radius: var(--radius-full);
  background-color: var(--green-700);
  color: var(--white);
  font-family: var(--font-display);
  font-weight: var(--weight-bold);
  font-size: var(--text-sm);
}

.quote__author {
  font-weight: var(--weight-semibold);
  font-size: var(--text-sm);
}

.quote__role {
  font-size: var(--text-xs);
  color: var(--text-muted);
}

/* ==========================================================================
   FAQ — natywny <details>, ARIA i klawiatura działają bez JS

   Płaska lista jednakowych pasków czyta się jak domyślny akordeon
   z każdego szablonu. Numer porządkowy porządkuje pytania (to naturalna
   lista, w przeciwieństwie do kart produktowych), pasek akcentu przy
   otwartym pytaniu daje punkt odniesienia z daleka, a realny cień
   w spoczynku odkleja każdy wiersz od tła zamiast polegać wyłącznie
   na cienkiej obwódce.
   ========================================================================== */
.faq {
  display: grid;
  gap: var(--space-4);
}

.faq__item {
  position: relative;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background-color: var(--bg-elevated);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
  transition: border-color var(--dur-base) var(--ease-out),
              box-shadow var(--dur-base) var(--ease-out),
              transform var(--dur-base) var(--ease-out);
}

.faq__item::before {
  content: '';
  position: absolute;
  inset-block: 0;
  inset-inline-start: 0;
  width: 3px;
  background-color: var(--accent);
  transform: scaleY(0);
  transition: transform var(--dur-base) var(--ease-out);
}

.faq__item:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-md);
}

.faq__item[open] {
  border-color: color-mix(in srgb, var(--accent) 45%, transparent);
  box-shadow: var(--shadow-lg);
}

.faq__item[open]::before {
  transform: scaleY(1);
}

.faq__q {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  min-height: 4rem;
  padding: var(--space-4) var(--space-5) var(--space-4) var(--space-6);
  cursor: pointer;
  list-style: none;
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-tight);
  transition: color var(--dur-fast) var(--ease-out);
}

.faq__q::-webkit-details-marker {
  display: none;
}

.faq__q:hover {
  color: var(--brand);
}

.faq__q-main {
  display: flex;
  align-items: baseline;
  gap: var(--space-4);
}

.faq__number {
  flex-shrink: 0;
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  color: var(--accent-ink);
  font-variant-numeric: tabular-nums;
}

.faq__icon {
  position: relative;
  flex-shrink: 0;
  width: 1.75rem;
  height: 1.75rem;
  border-radius: var(--radius-full);
  background-color: var(--green-100);
  box-shadow: var(--shadow-sm);
  transition: background-color var(--dur-base) var(--ease-out),
              box-shadow var(--dur-base) var(--ease-out);
}

.faq__icon::before,
.faq__icon::after {
  content: '';
  position: absolute;
  inset: 50% 26%;
  height: 2px;
  margin-block-start: -1px;
  border-radius: 2px;
  background-color: var(--green-700);
  transition: transform var(--dur-base) var(--ease-out),
              background-color var(--dur-base) var(--ease-out);
}

.faq__icon::after {
  transform: rotate(90deg);
}

.faq__item[open] .faq__icon {
  background-color: var(--accent);
  box-shadow: var(--shadow-md);
}

.faq__item[open] .faq__icon::before,
.faq__item[open] .faq__icon::after {
  background-color: var(--white);
}

.faq__item[open] .faq__icon::after {
  transform: rotate(0deg);
}

.faq__a {
  padding: 0 var(--space-5) var(--space-6) var(--space-6);
}

.faq__a p {
  color: var(--text-muted);
  max-width: 62ch;
}

/* FAQ na ciemnym panelu — ta sama "szklana" logika co karty ofert
   (.section--inverse .offer-card wyżej). Bez tego strona kończyła się
   trzema jasnymi sekcjami pod rząd (Opinie/FAQ/Kontakt) bez oddechu. */
.section--inverse .faq__item {
  border-color: rgba(255, 255, 255, 0.1);
  background-color: color-mix(in srgb, var(--white) 6%, transparent);
  box-shadow: none;
}

.section--inverse .faq__item:hover {
  border-color: rgba(255, 255, 255, 0.18);
  box-shadow: 0 20px 40px -20px rgba(0, 0, 0, 0.5);
}

.section--inverse .faq__item[open] {
  border-color: color-mix(in srgb, var(--accent-bright) 55%, transparent);
  box-shadow: 0 24px 48px -20px rgba(0, 0, 0, 0.55);
}

.section--inverse .faq__q {
  color: var(--text-inverse);
}

.section--inverse .faq__q:hover {
  color: var(--accent-light);
}

.section--inverse .faq__number {
  color: var(--accent-light);
}

.section--inverse .faq__icon {
  background-color: rgba(255, 255, 255, 0.1);
}

.section--inverse .faq__icon::before,
.section--inverse .faq__icon::after {
  background-color: var(--text-inverse);
}

.section--inverse .faq__a p {
  color: var(--text-on-dark-muted);
}


/* ==========================================================================
   FORMULARZ
   ========================================================================== */
.form {
  display: grid;
  gap: var(--space-5);
}

.form__row {
  display: grid;
  gap: var(--space-5);
}

@media (min-width: 40em) {
  .form__row--2 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.field {
  display: grid;
  gap: var(--space-2);
}

/* Etykieta zawsze widoczna — placeholder jako etykieta to antywzorzec:
   znika po rozpoczęciu pisania i jest nieczytelny dla czytników ekranu. */
.field__label {
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--text);
}

.field__required {
  color: var(--error);
  margin-inline-start: 0.15em;
}

.field__hint {
  font-size: var(--text-xs);
  color: var(--text-muted);
}

.field__control {
  width: 100%;
  min-height: 3.25rem;
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background-color: var(--bg-elevated);
  color: var(--text);
  font-size: var(--text-base);
  transition: border-color var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-fast) var(--ease-out);
}

.field__control::placeholder {
  color: var(--text-subtle);
}

.field__control:hover {
  border-color: var(--gray-400);
}

.field__control:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 30%, transparent);
}

.field__control:focus-visible {
  outline: none;
}

textarea.field__control {
  min-height: 8.5rem;
  resize: vertical;
  line-height: var(--leading-base);
}

select.field__control {
  appearance: none;
  padding-inline-end: var(--space-10);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='%236b6b66' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M5 8l5 5 5-5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--space-4) center;
  background-size: 1.25rem;
  cursor: pointer;
}

/* Stan błędu — komunikat przy polu, nie zbiorczo na górze formularza */
.field.is-invalid .field__control {
  border-color: var(--error);
}

.field.is-invalid .field__control:focus {
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--error) 22%, transparent);
}

.field__error {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--error);
}

.field__error svg {
  width: 1.05em;
  height: 1.05em;
  margin-block-start: 0.2em;
  flex-shrink: 0;
}

.field__error:empty {
  display: none;
}

/* ---- Zgoda / checkbox ---- */
.checkbox-field {
  display: grid;
  gap: var(--space-2);
}

.checkbox-field.is-invalid .checkbox input {
  outline: 2px solid var(--error);
  outline-offset: 2px;
}

.checkbox {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--space-3);
  align-items: start;
  cursor: pointer;
}

.checkbox input {
  width: 1.375rem;
  height: 1.375rem;
  margin: 0.15rem 0 0;
  accent-color: var(--green-700);
  cursor: pointer;
  flex-shrink: 0;
}

.checkbox__text {
  font-size: var(--text-sm);
  line-height: var(--leading-snug);
  color: var(--text-muted);
}

.checkbox__text a {
  color: var(--brand);
}

/* Małe logo marki przed etykietą (katalog: filtr "Marka") — tylko tam
   gdzie _katalog_filtr_checkboxy() dostanie loga=..., więc zwykłe
   checkboxy (np. formularz kontaktowy) mają zostać bez zmian. */
.checkbox__label {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-width: 0;
}

.checkbox__logo {
  display: block;
  flex-shrink: 0;
  height: 1.125rem;
  width: auto;
  max-width: 3.25rem;
  object-fit: contain;
}

/* ---- Honeypot: pole-pułapka dla botów. Ukryte, ale nie display:none
        (część botów pomija ukryte w ten sposób pola). ---- */
.form__trap {
  position: absolute !important;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
  opacity: 0;
  pointer-events: none;
}

/* ---- Komunikat zwrotny ---- */
.form__status {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  border-radius: var(--radius-md);
  font-size: var(--text-sm);
  line-height: var(--leading-snug);
}

.form__status:empty {
  display: none;
}

/* Komunikat dostaje focus po wysyłce (tabindex="-1"), ale nie ma być
   przystankiem w normalnej nawigacji Tabem — stąd brak własnego obrysu
   poza :focus-visible odziedziczonym z base.css. */
.form__status:focus {
  outline: none;
}

.form__status--success {
  background-color: var(--green-100);
  border: 1px solid color-mix(in srgb, var(--success) 35%, transparent);
  color: var(--green-950);
}

.form__status--error {
  background-color: #fdeceb;
  border: 1px solid color-mix(in srgb, var(--error) 35%, transparent);
  color: #7a1a15;
}

.form__status svg {
  width: 1.25rem;
  height: 1.25rem;
  flex-shrink: 0;
  margin-block-start: 0.1em;
}

/* Stan wysyłania */
.btn.is-loading {
  pointer-events: none;
  opacity: 0.8;
}

.btn.is-loading .btn__icon--arrow {
  display: none;
}

.spinner {
  width: 1.1em;
  height: 1.1em;
  border: 2px solid currentColor;
  border-top-color: transparent;
  border-radius: var(--radius-full);
  animation: spin 700ms linear infinite;
}

/* ==========================================================================
   KONTAKT
   ========================================================================== */
.contact-card {
  padding: clamp(var(--space-6), 3vw, var(--space-10));
  border-radius: var(--radius-lg);
  background-color: var(--bg-elevated);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-md);
}

/* Na ciemnym panelu (np. FAQ) ta sama szklana logika co .offer-card
   i .faq__item — biała karta tutaj powtórzyłaby dokładnie ten sam
   problem "białego prostokąta", który już raz poprawialiśmy gdzie
   indziej na tej stronie. */
.section--inverse .contact-card {
  background-color: color-mix(in srgb, var(--white) 6%, transparent);
  border-color: rgba(255, 255, 255, 0.1);
  box-shadow: none;
  color: var(--text-on-dark-muted);
}

.section--inverse .contact-card .feature__title {
  color: var(--text-inverse);
}

/* Prawa kolumna sekcji kontaktowej: trzy równorzędne kafle jeden pod drugim.
   Wcześniej dane kontaktowe leżały luzem na tle strony, a sąsiadujące
   godziny otwarcia i mapa były w białych kartach — blok wyglądał, jakby
   ktoś zapomniał go dokończyć. */
.contact-side {
  display: grid;
  gap: var(--space-5);
  align-content: start;
}

.contact-list {
  display: grid;
  gap: var(--space-6);
  list-style: none;
  padding: 0;
  margin: 0;
}

.contact-item {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--space-4);
  align-items: start;
}

.contact-item__icon {
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: var(--radius-md);
  background-color: var(--green-100);
  color: var(--green-700);
}

.contact-item__icon svg {
  width: 1.25rem;
  height: 1.25rem;
}

.contact-item__label {
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-widest);
  text-transform: uppercase;
  color: var(--text-subtle);
}

.contact-item__value {
  display: block;
  margin-block-start: var(--space-1);
  font-size: var(--text-lg);
  font-weight: var(--weight-semibold);
  color: var(--text);
  text-decoration: none;
}

a.contact-item__value:hover {
  color: var(--brand);
}

.contact-item__note {
  font-size: var(--text-sm);
  color: var(--text-muted);
}

.map {
  border-radius: var(--radius-lg);
  overflow: hidden;
  border: 1px solid var(--border);
  background-color: var(--sand-100);
  min-height: 22rem;
}

.map iframe {
  display: block;
  width: 100%;
  height: 100%;
  min-height: 22rem;
  border: 0;
}

/* Mapa na pełną szerokość kontenera, pod kolumnami sekcji kontaktowej.
   Na wąskim ekranie zostaje wysoka (widać ulice), na szerokim przechodzi
   w pas panoramiczny — inaczej przy 1200 px szerokości i 22 rem wysokości
   wyglądałaby jak przypadkowy wycinek. */
.map--wide {
  margin-block-start: clamp(var(--space-8), 4vw, var(--space-12));
}

@media (min-width: 56em) {
  .map--wide,
  .map--wide iframe {
    min-height: 0;
    aspect-ratio: 21 / 7;
  }
}

.hours {
  display: grid;
  gap: var(--space-2);
  list-style: none;
  padding: 0;
  margin: 0;
}

.hours li {
  display: flex;
  justify-content: space-between;
  gap: var(--space-4);
  padding-block: var(--space-2);
  border-block-end: 1px dashed var(--border);
  font-size: var(--text-sm);
}

.hours li:last-child {
  border-block-end: none;
}

.hours__day {
  color: var(--text-muted);
}

.hours__time {
  font-weight: var(--weight-semibold);
  font-variant-numeric: tabular-nums;
}

/* ==========================================================================
   STOPKA
   ========================================================================== */
.footer {
  background-color: var(--bg-inverse-deep);
  color: var(--text-on-dark-muted);
  padding-block: var(--section-y-tight) var(--space-8);
}

.footer a {
  color: var(--text-on-dark-muted);
  text-decoration: none;
}

.footer a:hover {
  color: var(--white);
  text-decoration: underline;
  text-underline-offset: 0.25em;
}

.footer__top {
  display: grid;
  gap: var(--space-10);
}

@media (min-width: 48em) {
  .footer__top {
    grid-template-columns: 1.4fr repeat(3, minmax(0, 1fr));
    gap: var(--space-8);
  }
}

.footer__brand .logo__img {
  height: 3rem;
}

.footer__about {
  margin-block-start: var(--space-4);
  max-width: 30ch;
  font-size: var(--text-sm);
  line-height: var(--leading-base);
}

.footer__heading {
  font-family: var(--font-display);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  letter-spacing: var(--tracking-widest);
  text-transform: uppercase;
  color: var(--white);
  margin-block-end: var(--space-4);
}

.footer__list {
  display: grid;
  gap: var(--space-3);
  list-style: none;
  padding: 0;
  margin: 0;
  font-size: var(--text-sm);
}

.footer__bottom {
  margin-block-start: var(--space-12);
  padding-block-start: var(--space-6);
  border-block-start: 1px solid var(--border-inverse);
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--space-4);
  font-size: var(--text-xs);
}

.footer__legal {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-5);
  list-style: none;
  padding: 0;
  margin: 0;
}

/* ==========================================================================
   ZNAK CERTYFIKACYJNY (Rzetelna Firma)

   Znak zawsze na białym kaflu — logotyp ma czarny człon „FIRMA", który na
   ciemnej stopce po prostu by zniknął, a przemalowywanie cudzego znaku
   certyfikacyjnego jest niedopuszczalne. Biały kafel to jednocześnie
   standardowy sposób prezentacji tego typu oznaczeń.
   ========================================================================== */
.badge-cert {
  display: inline-flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-3) var(--space-5);
  border-radius: var(--radius-md);
  background-color: var(--white);
  border: 1px solid var(--border);
  text-decoration: none;
  transition: transform var(--dur-base) var(--ease-out),
              box-shadow var(--dur-base) var(--ease-out);
}

.badge-cert:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-md);
}

.badge-cert img {
  width: 6.5rem;
  height: auto;
  flex-shrink: 0;
  background-color: transparent;
}

.badge-cert__text {
  display: grid;
  gap: 2px;
  min-width: 0;
}

.badge-cert__title {
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wide);
  color: var(--text);
  line-height: 1.3;
}

.badge-cert__note {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-size: var(--text-xs);
  color: var(--accent-ink);
  line-height: 1.3;
}

.badge-cert__note svg {
  width: 0.85em;
  height: 0.85em;
}

/* Stopka jest ciemna — kafel musi zachować biel również tam.
   Kolumna stopki ma ~200 px, więc układ poziomy (znak obok podpisu) łamał
   tekst na cztery linie. Tutaj znak idzie nad podpisem. */
.footer .badge-cert {
  border-color: transparent;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-3);
  max-width: 15rem;
}

.footer .badge-cert__note {
  white-space: nowrap;
}

.footer .badge-cert__title {
  color: var(--graphite);
}

.footer .badge-cert:hover .badge-cert__title,
.footer .badge-cert:hover .badge-cert__note {
  text-decoration: none;
}

/* Wariant rozbudowany — sekcja zaufania na podstronie „O nas" */
.trust-block {
  display: grid;
  gap: var(--space-6);
  align-items: center;
  padding: clamp(var(--space-6), 3vw, var(--space-10));
  border-radius: var(--radius-lg);
  background-color: var(--bg-elevated);
  border: 1px solid var(--border);
}

@media (min-width: 48em) {
  .trust-block {
    grid-template-columns: auto minmax(0, 1fr);
    gap: var(--space-10);
  }
}

.trust-block__mark {
  display: grid;
  place-items: center;
  padding: var(--space-5) var(--space-6);
  border-radius: var(--radius-md);
  background-color: var(--sand-50);
  border: 1px solid var(--border);
}

.trust-block__mark img {
  width: 9rem;
  height: auto;
  background-color: transparent;
}

/* ==========================================================================
   ELEMENTY PŁYWAJĄCE (mobile)
   ========================================================================== */

/* Pasek szybkiego kontaktu — pojawia się po opuszczeniu hero.
   Druga (i ostatnia) instancja backdrop-filter w projekcie. */
.quick-bar {
  position: fixed;
  inset-block-end: 0;
  inset-inline: 0;
  z-index: var(--z-sticky);
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-3);
  padding: var(--space-3) var(--gutter);
  padding-block-end: max(var(--space-3), env(safe-area-inset-bottom));
  background-color: color-mix(in srgb, var(--white) 88%, transparent);
  backdrop-filter: blur(16px) saturate(180%);
  -webkit-backdrop-filter: blur(16px) saturate(180%);
  border-block-start: 1px solid var(--border);
  transform: translateY(110%);
  transition: transform var(--dur-base) var(--ease-out);
}

.quick-bar.is-visible {
  transform: translateY(0);
}

@media (min-width: 62em) {
  .quick-bar {
    display: none;
  }
}

/* Powrót na górę — desktop */
.to-top {
  position: fixed;
  inset-block-end: var(--space-6);
  inset-inline-end: var(--space-6);
  z-index: var(--z-sticky);
  display: none;
  place-items: center;
  width: 3rem;
  height: 3rem;
  border-radius: var(--radius-full);
  background-color: var(--brand);
  color: var(--white);
  box-shadow: var(--shadow-lg);
  opacity: 0;
  transform: translateY(0.75rem) scale(0.9);
  pointer-events: none;
  transition: opacity var(--dur-base) var(--ease-out),
              transform var(--dur-base) var(--ease-spring),
              background-color var(--dur-fast) var(--ease-out);
}

.to-top svg {
  width: 1.25rem;
  height: 1.25rem;
}

.to-top.is-visible {
  opacity: 1;
  transform: translateY(0) scale(1);
  pointer-events: auto;
}

.to-top:hover {
  background-color: var(--green-950);
}

@media (min-width: 62em) {
  .to-top {
    display: grid;
  }
}

/* ==========================================================================
   PASEK POSTĘPU PRZEWIJANIA

   Po lewej krawędzi, nie po prawej — prawa strona jest już zajęta przez
   przycisk „do góry" i (na mobile) pasek szybkiego kontaktu. Lewa krawędź
   jest przez całą stronę pusta: nagłówki, chipy i CTA zaczynają się dopiero
   od --panel-pad-x, więc pasek ma własny, nikomu nie zabrany pas.

   Sam pomysł „procent czy sekcje" — wybraliśmy procent, bo działa identycznie
   na każdej z kilkunastu podstron bez ręcznego wypisywania listy sekcji
   dla każdego szablonu. Wariant z kropkami-sekcjami wymagałby osobnej
   konfiguracji na LOVOL, kontakcie, każdej marce własnej — łatwo o rozjazd.
   ========================================================================== */
.scroll-rail {
  position: fixed;
  inset-inline-start: clamp(1rem, 2.5vw, 1.75rem);
  inset-block-start: 50%;
  transform: translateY(-50%);
  z-index: var(--z-sticky);
  display: none;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3);
  opacity: 0;
  transition: opacity var(--dur-base) var(--ease-out);
  pointer-events: none;
}

.scroll-rail.is-visible {
  opacity: 1;
}

@media (min-width: 62em) {
  .scroll-rail {
    display: flex;
  }
}

.scroll-rail__track {
  position: relative;
  width: 3px;
  height: min(26vh, 200px);
  border-radius: var(--radius-full);
  background-color: var(--border-strong);
  overflow: hidden;
}

/* Tło toru dostosowuje się do sekcji, nad którą aktualnie stoi pasek —
   ciemny wariant, gdy JS wykryje, że ta wysokość ekranu nakłada się
   na ciemny panel, inaczej cienka szara kreska zlałaby się z tłem. */
.scroll-rail.is-on-dark .scroll-rail__track {
  background-color: rgba(255, 255, 255, 0.2);
}

.scroll-rail__fill {
  position: absolute;
  inset-inline: 0;
  inset-block-start: 0;
  width: 100%;
  height: 0%;
  border-radius: inherit;
  background-color: var(--accent);
  transition: height var(--dur-fast) linear;
}

.scroll-rail__pct {
  font-family: var(--font-display);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  font-variant-numeric: tabular-nums;
  letter-spacing: var(--tracking-tight);
  color: var(--text-muted);
  transition: color var(--dur-base) var(--ease-out);
}

.scroll-rail.is-on-dark .scroll-rail__pct {
  color: rgba(255, 255, 255, 0.72);
}

/* Ekrany niskie i szerokie: tor 26vh potrafi być wyższy niż pół okna
   pomniejszone o marginesy — chowamy pasek, żeby nie nachodził na treść. */
@media (max-height: 34em) {
  .scroll-rail {
    display: none;
  }
}

/* ==========================================================================
   TREŚĆ PODSTRON (prose)
   ========================================================================== */
/* Blok tekstu ciągłego ma własne ograniczenie długości wiersza — kontener
   jest szeroki, ale czytać się tego nie da powyżej ~68 znaków. */
.prose {
  max-width: var(--container-text);
}

.prose > * + * {
  margin-block-start: var(--space-5);
}

.prose h2 {
  margin-block-start: var(--space-12);
  font-size: var(--text-2xl);
}

.prose h3 {
  margin-block-start: var(--space-8);
}

.prose ul,
.prose ol {
  display: grid;
  gap: var(--space-3);
  max-width: var(--container-text);
  color: var(--text-muted);
}

.prose li::marker {
  color: var(--accent);
}

.prose p {
  color: var(--text-muted);
}

.prose strong {
  color: var(--text);
}

/* ==========================================================================
   LISTA PRODUKTÓW (podstrony marek)
   ========================================================================== */
.product {
  display: grid;
  /* grid-template-columns jawnie na minmax(0, 1fr), nie samo "1fr"/domyślne
     auto — bez tego niejawna kolumna gridu rośnie do naturalnej szerokości
     najszerszej zawartości (tu: <img> w .product__media), a nie do
     szerokości karty. Klasyczny "grid blowout": zmierzone realnie —
     karta 371px, ale jej własna kolumna gridu liczyła się na 560px,
     bo tyle chciał zająć jeden z obrazków modeli. */
  grid-template-columns: minmax(0, 1fr);
  align-content: start;
  border-radius: var(--radius-md);
  background-color: var(--bg-elevated);
  border: 1px solid var(--border);
  overflow: hidden;
  transition: border-color var(--dur-base) var(--ease-out),
              box-shadow var(--dur-base) var(--ease-out);
}

/* [hidden] i .product mają tę samą specyficzność (0-1-0) — bez tego katalog.js
   ustawia atrybut hidden na odfiltrowanych kartach, ale reguła .product{display:grid}
   wygrywa jako późniejsza w kaskadzie i karta zostaje widoczna mimo hidden=true. */
.product[hidden] {
  display: none;
}

.product:hover {
  border-color: color-mix(in srgb, var(--accent) 40%, transparent);
  box-shadow: var(--shadow-md);
}

/* Owija treść tekstową (bez zdjęcia). Osobny element zamiast paddingu
   wprost na .product — dzięki temu .product__media (gdy jest) może być
   pełnej szerokości karty bez ujemnych marginesów. Ta sama zasada co
   .offer-card / .offer-card__body gdzie indziej na stronie: zero
   ujemnych marginesów, zero niepewnych interakcji z grid/aspect-ratio. */
.product__body {
  display: grid;
  gap: var(--space-4);
  padding: var(--space-6);
}

.product__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
}

.product__name {
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
}

.product__desc {
  font-size: var(--text-sm);
  color: var(--text-muted);
}

.product__specs {
  display: grid;
  gap: var(--space-2);
  list-style: none;
  padding: 0;
  margin: 0;
  font-size: var(--text-sm);
}

.product__specs li {
  display: flex;
  justify-content: space-between;
  gap: var(--space-4);
  padding-block: var(--space-2);
  border-block-end: 1px dashed var(--border);
}

.product__specs li:last-child {
  border-block-end: none;
}

.product__specs dt,
.product__specs .spec-key {
  color: var(--text-muted);
}

.product__specs .spec-val {
  font-weight: var(--weight-semibold);
  text-align: end;
}

/* Zdjęcie modelu nad specyfikacją — zdjęcia produktowe na białym tle,
   object-fit:contain (nie cover) żeby nigdy nie obcinać maszyny, tło
   kafla daje im oddech zamiast białego na białym. */
.product__media {
  position: relative;
  align-self: start;
  width: 100%;
  aspect-ratio: 4 / 3;
  min-width: 0;
  min-height: 0;
  padding: var(--space-4);
  background-color: var(--sand-100);
  overflow: hidden;
}

/* position:absolute zamiast max-width/max-height na dziecku grida — na
   pionowych zdjęciach (np. realne zdjęcia produktów EkoPlon, 540×743)
   max-height:100% nie miało się do czego odnieść (niejawny wiersz grida
   liczy się z zawartości, więc jego wysokość bywa "nieokreślona" w chwili
   rozwiązywania procentów) i obrazek wylewał się poniżej kafla, zasłaniając
   treść karty. Pozycjonowanie względem .product__media (position:relative,
   wysokość zawsze pewna dzięki aspect-ratio) rozwiązuje procenty
   niezawodnie niezależnie od proporcji zdjęcia. */
.product__media img {
  position: absolute;
  inset: var(--space-4);
  width: calc(100% - var(--space-4) * 2);
  height: calc(100% - var(--space-4) * 2);
  object-fit: contain;
}

/* Sekcja "Modele" na /oferta/lovol/: 6 kart, świadomie dokładnie
   3 kolumny × 2 rzędy na szerszych ekranach — .grid--3 samo w sobie jest
   auto-fit (elastyczna liczba kolumn zależna od miejsca), tu chcemy
   sztywno 3, nie "ile się zmieści". */
@media (min-width: 56em) {
  #modele .grid--3 {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

/* ==========================================================================
   PUNKTY Z IKONĄ — pionowa lista, każdy wiersz spięty z akapitem obok
   (np. "Dlaczego LOVOL"). Kaskadowe wejście przez [data-reveal-group],
   ten sam mechanizm co siatki kart — nic nowego do utrzymania.
   ========================================================================== */
.icon-points {
  display: grid;
  gap: var(--space-6);
}

.icon-points__item {
  display: flex;
  align-items: center;
  gap: var(--space-4);
}

.icon-points__badge {
  flex-shrink: 0;
  display: grid;
  place-items: center;
  width: 3rem;
  height: 3rem;
  border-radius: 50%;
  background-color: var(--green-100);
  color: var(--accent-ink);
}

.icon-points__badge svg {
  width: 1.5rem;
  height: 1.5rem;
}

.icon-points__title {
  display: block;
  font-family: var(--font-display);
  font-weight: var(--weight-bold);
  letter-spacing: var(--tracking-tight);
}

.icon-points__text {
  font-size: var(--text-sm);
  color: var(--text-muted);
}

/* ==========================================================================
   KATALOG — /oferta/, filtrowana siatka produktów (aldar-preflight:
   assets/js/katalog.js robi filtrowanie/sortowanie po stronie klienta;
   bez JS wszystkie karty po prostu zostają widoczne, patrz .no-js niżej).
   ========================================================================== */
.catalog {
  display: grid;
  gap: var(--space-10);
  align-items: start;
  margin-block-start: var(--space-10);
}

@media (min-width: 56em) {
  .catalog {
    grid-template-columns: 15rem minmax(0, 1fr);
  }
}

.catalog__filters {
  display: grid;
  gap: var(--space-6);
  padding: var(--space-5);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background-color: var(--bg-elevated);
}

/* Telefony i tablety w pionie (< 56em): filtry jako panel wysuwany z lewej
   krawędzi zamiast bloku na pełną szerokość nad siatką — ten sam wzorzec
   co .mobile-menu (menu.js), tylko z boku i węższy. Powyżej 56em wraca
   stały, przyklejony pasek boczny (patrz media query niżej). */
@media (max-width: 55.99em) {
  .catalog__filters {
    position: fixed;
    inset-block: 0;
    inset-inline-start: 0;
    z-index: var(--z-menu);
    width: min(22rem, 85vw);
    max-height: none;
    border-radius: 0 var(--radius-lg) var(--radius-lg) 0;
    border-inline-start: none;
    align-content: start;
    overflow-y: auto;
    overscroll-behavior: contain;
    box-shadow: var(--shadow-lg);
    transform: translateX(-100%);
    transition: transform var(--dur-base) var(--ease-out);
  }

  .catalog__filters.is-open {
    transform: translateX(0);
  }
}

@media (min-width: 56em) {
  .catalog__filters {
    position: sticky;
    top: calc(var(--header-h, 5rem) + var(--space-6));
    max-height: calc(100vh - var(--header-h, 5rem) - var(--space-10));
    overflow-y: auto;
  }
}

/* Zakładka ze strzałką, przyklejona do lewej krawędzi ekranu — jedyny
   sposób otwarcia panelu filtrów na telefonie/tablecie. Chowa się pod
   otwartym panelem (niższy z-index niż .catalog__filters), zamykanie
   idzie przez X w panelu, tło (.catalog__filters-backdrop) albo Esc. */
.catalog__filters-toggle {
  position: fixed;
  inset-inline-start: 0;
  top: 50%;
  transform: translateY(-50%);
  z-index: var(--z-sticky);
  display: grid;
  place-items: center;
  width: 2.25rem;
  height: 3.5rem;
  border: 1px solid var(--border);
  border-inline-start: none;
  border-radius: 0 var(--radius-md) var(--radius-md) 0;
  background-color: var(--brand-solid);
  color: var(--white);
  box-shadow: var(--shadow-md);
  cursor: pointer;
}

.catalog__filters-toggle-icon {
  width: 1rem;
  height: 1rem;
  transition: transform var(--dur-base) var(--ease-out);
}

.catalog__filters-toggle[aria-expanded='true'] .catalog__filters-toggle-icon {
  transform: rotate(180deg);
}

@media (min-width: 56em) {
  .catalog__filters-toggle {
    display: none;
  }
}

.catalog__filters-backdrop {
  position: fixed;
  inset: 0;
  z-index: var(--z-overlay);
  background-color: rgb(0 0 0 / 45%);
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--dur-base) var(--ease-out),
              visibility 0s linear var(--dur-base);
}

.catalog__filters-backdrop.is-open {
  opacity: 1;
  visibility: visible;
  transition-delay: 0s;
}

@media (min-width: 56em) {
  .catalog__filters-backdrop {
    display: none;
  }
}

.catalog__filters-close {
  display: none;
}

@media (max-width: 55.99em) {
  .catalog__filters-close {
    display: grid;
    place-items: center;
    width: 2rem;
    height: 2rem;
    padding: 0;
    border: none;
    background: none;
    color: var(--text-muted);
    cursor: pointer;
  }

  .catalog__filters-close svg {
    width: 1.1rem;
    height: 1.1rem;
  }
}

.catalog__filters-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}

.catalog__filters-head .feature__title {
  font-size: var(--text-base);
}

.catalog__group {
  display: grid;
  gap: var(--space-3);
  padding: 0;
  border: none;
  border-block-start: 1px solid var(--border);
  padding-block-start: var(--space-5);
}

.catalog__group:first-of-type {
  border-block-start: none;
  padding-block-start: 0;
}

.catalog__group-title {
  padding: 0;
  /* .catalog__group ma jednolity gap (--space-3) między WSZYSTKIMI
     wierszami — bez tego tytuł grupy siedzi tak samo blisko pierwszego
     checkboxa jak checkboxy między sobą. Margines dokłada się DO gap,
     nie zamiast niego, więc rozdziela tytuł od listy bez ruszania
     odstępów między samymi checkboxami. */
  margin-block-end: var(--space-2);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--text-muted);
}

.catalog__toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  margin-block-end: var(--space-6);
}

.catalog__count {
  font-size: var(--text-sm);
  color: var(--text-muted);
}

.catalog__sort .field__control {
  min-height: 2.75rem;
  width: auto;
  font-size: var(--text-sm);
}

.catalog__empty {
  padding: var(--space-10) var(--space-6);
  text-align: center;
  color: var(--text-muted);
}

/* Ustawienia gridu katalogu — jawne liczby kolumn per breakpoint zamiast
   samego auto-fit z .grid--cards (layout.css), żeby telefon i tablet miały
   przewidywalny, zaprojektowany układ zamiast "cokolwiek się zmieści".
   Kolejność <link> w head() ładuje layout.css przed components.css, więc
   ta reguła (ta sama specyficzność, później w kaskadzie) wygrywa. */
.catalog__grid {
  grid-template-columns: minmax(0, 1fr);
}

@media (min-width: 30em) {
  .catalog__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 56em) {
  .catalog__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 75em) {
  .catalog__grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

/* Cała karta klikalna przez rozciągnięty link w nagłówku — ten sam trik
   co .offer-card__link, tylko scoped przez modyfikator (zwykłe .product,
   np. karty modeli LOVOL, mają zostać bez linku). */
.product--linked {
  position: relative;
}

.product__link {
  color: inherit;
  text-decoration: none;
}

.product__link::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 2;
  border-radius: inherit;
}

.product--linked:focus-within {
  outline: 3px solid var(--focus-ring);
  outline-offset: 3px;
}

.product__link:focus-visible {
  outline: none;
}

/* ==========================================================================
   GALERIA
   ========================================================================== */
.gallery {
  display: grid;
  gap: var(--space-4);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
}

.gallery__item {
  border-radius: var(--radius-md);
  overflow: hidden;
  background-color: var(--sand-100);
}

/* Miniatura jest teraz <button> (patrz galeria() w strony.py) — cały kafel
   klikalny i dostępny z klawiatury, nie tylko obrazek. */
.gallery__zoom {
  display: block;
  position: relative;
  width: 100%;
  padding: 0;
  border: none;
  background: none;
  cursor: zoom-in;
}

.gallery__zoom img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  aspect-ratio: 4 / 3;
  transition: transform 600ms var(--ease-out);
}

.gallery__zoom:hover img {
  transform: scale(1.05);
}

.gallery__zoom-icon {
  position: absolute;
  inset-block-end: var(--space-3);
  inset-inline-end: var(--space-3);
  display: grid;
  place-items: center;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: var(--radius-full);
  background-color: rgba(255, 255, 255, 0.9);
  color: var(--brand);
  opacity: 0;
  transform: translateY(4px);
  transition: opacity var(--dur-base) var(--ease-out),
              transform var(--dur-base) var(--ease-out);
}

.gallery__zoom-icon svg {
  width: 1.1rem;
  height: 1.1rem;
}

.gallery__zoom:hover .gallery__zoom-icon,
.gallery__zoom:focus-visible .gallery__zoom-icon {
  opacity: 1;
  transform: translateY(0);
}

/* ==========================================================================
   LIGHTBOX — powiększony podgląd zdjęcia z galerii
   ========================================================================== */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: grid;
  place-items: center;
  padding: var(--space-6);
  background-color: rgba(9, 14, 14, 0.92);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}

.lightbox[hidden] {
  display: none;
}

.lightbox__img {
  max-width: min(100%, 70rem);
  max-height: 85vh;
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-xl);
}

.lightbox__close {
  position: absolute;
  inset-block-start: var(--space-5);
  inset-inline-end: var(--space-5);
  display: grid;
  place-items: center;
  width: 3rem;
  height: 3rem;
  border: none;
  border-radius: var(--radius-full);
  background-color: rgba(255, 255, 255, 0.12);
  color: var(--white);
  transition: background-color var(--dur-fast) var(--ease-out);
}

.lightbox__close:hover {
  background-color: rgba(255, 255, 255, 0.22);
}

.lightbox__close svg {
  width: 1.35rem;
  height: 1.35rem;
}

/* ==========================================================================
   404
   ========================================================================== */
.notfound {
  display: grid;
  place-items: center;
  min-height: 70svh;
  text-align: center;
  padding-block: var(--section-y);
}

.notfound__code {
  font-family: var(--font-display);
  font-size: clamp(5rem, 18vw, 11rem);
  font-weight: var(--weight-extra);
  line-height: 0.85;
  letter-spacing: var(--tracking-tighter);
  color: var(--green-100);
}

/* ==========================================================================
   PODSTRONA PRODUKTU (PDP) — /oferta/{marka}/{produkt}/
   Sekcje warunkowe (.pdp__variants, korzyści, FAQ) renderują się tylko,
   gdy strony.py dostał dla produktu realne dane (PRODUKTY_SZCZEGOLY) —
   zero podstron z połowicznie zmyśloną treścią. Karty korzyści to ten sam
   komponent (.feature przez korzysci()) co reszta strony, nie osobny styl
   tylko tutaj.
   ========================================================================== */

/* --------------------------------------------------------------------------
   HERO — pełnoekranowy podział na biały panel (treść) i zielony panel
   (zdjęcie), sięgający od razu pod nagłówek (bez paska okruszków nad sobą —
   okruszki są teraz wewnątrz białego panelu). Zdjęcie duże, wyśrodkowane
   W zielonym panelu — nie na złączeniu kolorów (pierwsza wersja tego
   układu robiła zdjęcie na granicy paneli; klient to odrzucił). Pełna
   szerokość ekranu — celowo POZA .container, w przeciwieństwie do reszty
   strony.
   -------------------------------------------------------------------------- */
.pdp-hero-split {
  display: grid;
}

@media (min-width: 56em) {
  .pdp-hero-split {
    grid-template-columns: 1fr 1fr;
    min-height: 34rem;
  }
}

.pdp-hero-split__panel {
  display: flex;
  align-items: center;
  background-color: var(--bg-elevated);
  padding: var(--space-10) var(--gutter);
}

.pdp-hero-split__inner {
  width: 100%;
  max-width: 28rem;
  display: grid;
  gap: var(--space-5);
}

@media (min-width: 56em) {
  .pdp-hero-split__inner {
    margin-inline-start: auto;
  }
}

@media (min-width: 87.5em) {
  .pdp-hero-split__inner {
    margin-inline-end: var(--space-16);
  }
}

.pdp-hero-split__crumbs {
  margin-block-end: var(--space-2);
}

/* Domyślny .breadcrumb (components.css, wyżej) zakłada ciemne tło —
   biały tekst na białym .pdp-hero-split__panel (bg-elevated) był
   niewidoczny. Tu panel jest jasny, więc paleta odwrócona. */
.pdp-hero-split__crumbs li::after {
  color: var(--border-strong);
}

.pdp-hero-split__crumbs a {
  color: var(--text-muted);
}

.pdp-hero-split__crumbs a:hover {
  color: var(--brand);
}

.pdp-hero-split__crumbs [aria-current='page'] {
  color: var(--ink-900);
}

.pdp-hero-split__media {
  display: grid;
  place-items: center;
  background-color: var(--green-900);
  padding: var(--space-8) var(--gutter);
  min-height: 20rem;
}

.pdp-hero-split__img {
  display: block;
  width: auto;
  height: auto;
  /* max-width I max-height razem, nie sam width — realne zdjęcia produktów
     (worki EkoPlon, 540×743, pionowe) przy samym "width: min(85%, 24rem)"
     rosły do pełnej wysokości panelu wzdłuż osi Y (panel dopasowuje się do
     wysokości białej kolumny obok), wyglądając na "za duże", wręcz przycięte
     u góry/dołu. Podwójne ograniczenie pozwala przeglądarce dobrać wymiar,
     który mieści się w OBU limitach, więc pionowe zdjęcia zostają mniejsze
     i mają oddech, a poziome nadal wypełniają dostępną szerokość. */
  max-width: min(75%, 20rem);
  max-height: 20rem;
  /* base.css: img{background-color:var(--sand-100)} to placeholder na czas
     ładowania — dla zdjęć z usuniętym tłem po wczytaniu prześwitywał przez
     przezroczyste piksele jako widoczny szary prostokąt. Tu nie potrzebny
     (zielone tło panelu i tak nie miga bielą), więc wyłączony wprost. */
  background-color: transparent;
  filter: drop-shadow(0 24px 48px rgba(15, 33, 3, 0.35));
}

@media (min-width: 56em) {
  .pdp-hero-split__img {
    max-width: min(90%, 26rem);
    max-height: 26rem;
  }
}

.pdp__brand {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.pdp__brand img {
  height: 1.4rem;
  width: auto;
  object-fit: contain;
}

.pdp__brand span {
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
}

.pdp__title {
  font-family: var(--font-display);
  font-weight: var(--weight-extra);
  letter-spacing: var(--tracking-tight);
  font-size: var(--text-3xl);
  line-height: var(--leading-tight);
  margin: 0;
}

.pdp__tags {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

/* Zdanie propozycji wartości — jedno mocne zdanie zamiast zwykłego opisu,
   ma dać odpowiedź na "czy to dla mnie" w kilka sekund (F-pattern, patrz
   wireframe). Sam opis produktu jest niżej, w sekcji "Szczegóły". */
.pdp__value {
  font-size: var(--text-lg);
  font-weight: var(--weight-medium);
  color: var(--text);
  line-height: var(--leading-base);
  margin: 0;
}

.pdp__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-block-start: var(--space-1);
}

/* --------------------------------------------------------------------------
   WARIANTY (pojemności/gramatury) — tylko gdy produkt je realnie ma
   (np. Suplexan 0,25/1/5 l); worki o stałej gramaturze tej sekcji
   po prostu nie dostają.
   -------------------------------------------------------------------------- */
.pdp__variants {
  display: grid;
  gap: var(--space-2);
}

.pdp__variants-label {
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  color: var(--text-muted);
}

.pdp__variants-opts {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.pdp__variant {
  padding: 0.55rem 1rem;
  border-radius: var(--radius-full);
  border: 1.5px solid var(--border-strong);
  background-color: var(--bg-elevated);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--text);
}

.pdp__variant:first-child {
  border-color: var(--brand-solid);
  background-color: var(--green-50);
  color: var(--brand);
}

/* --------------------------------------------------------------------------
   SZCZEGÓŁY — Specyfikacja / Skład / Dawkowanie w 3 kolumnach obok siebie
   na desktopie (szybkie porównywanie danych), po jednej pod drugą niżej —
   świadomie bez zakładek, zgodnie z wybranym wariantem wireframe'u.
   Dokładnie 3 kolumny, tak jak w wireframe — opis produktu to osobny
   akapit nad siatką, nie czwarta kolumna.
   -------------------------------------------------------------------------- */
.pdp-details__intro {
  max-width: var(--container-text);
  margin-block-end: var(--space-8);
  font-size: var(--text-base);
  line-height: var(--leading-base);
  color: var(--text-muted);
}

.pdp-details__intro p {
  margin: 0 0 var(--space-3);
}

.pdp-details__grid {
  display: grid;
  gap: var(--space-8);
}

@media (min-width: 40em) {
  .pdp-details__grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

.pdp-details__col h3 {
  font-family: var(--font-display);
  font-weight: var(--weight-bold);
  font-size: var(--text-base);
  margin: 0 0 var(--space-3);
}

.pdp-details__col p {
  font-size: var(--text-sm);
  line-height: var(--leading-base);
  color: var(--text-muted);
  margin: 0 0 var(--space-3);
}

.pdp-details__brak {
  color: var(--text-subtle);
  font-style: italic;
}

.pdp-spec {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-sm);
}

.pdp-spec tr {
  border-block-end: 1px solid var(--border);
}

.pdp-spec td {
  padding: var(--space-2) var(--space-1);
  vertical-align: top;
}

.pdp-spec td:first-child {
  color: var(--text-subtle);
  font-weight: var(--weight-medium);
  padding-inline-end: var(--space-2);
}

.pdp-spec td:last-child {
  color: var(--text);
  font-weight: var(--weight-medium);
}

/* Zastępuje "Dawkowanie", gdy nie mamy realnych liczb — zamiast pustej
   treści albo zmyślonej dawki, kieruje do kontaktu. */
.pdp-fallback {
  background-color: var(--wheat-100);
  border: 1px solid color-mix(in srgb, var(--wheat-700) 25%, transparent);
  border-radius: var(--radius-md);
  padding: var(--space-4) var(--space-5);
  display: grid;
  gap: var(--space-2);
  font-size: var(--text-sm);
}

.pdp-fallback strong {
  font-family: var(--font-display);
  color: var(--wheat-700);
}

.pdp-fallback a {
  color: var(--brand);
  font-weight: var(--weight-semibold);
}

/* Dwukolumnowa lista Cechy / Korzyści na zielonych checkmarkach —
   wg referencji klienta (ciemny pasek ikona+etykieta nad tym, z pierwszej
   wersji, został usunięty na jego prośbę). */
.pdp-checklist-grid {
  display: grid;
  gap: var(--space-8);
}

@media (min-width: 40em) {
  .pdp-checklist-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.pdp-checklist h3 {
  font-family: var(--font-display);
  font-weight: var(--weight-bold);
  color: var(--brand);
  font-size: var(--text-lg);
  margin: 0 0 var(--space-4);
}

.pdp-checklist ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--space-3);
}

.pdp-checklist li {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  font-size: var(--text-sm);
  color: var(--text-muted);
}

.pdp-checklist li svg {
  flex-shrink: 0;
  width: 1.1rem;
  height: 1.1rem;
  margin-block-start: 0.15rem;
  color: var(--brand-solid);
}

.pdp-related {
  padding-block: var(--section-y);
}

.pdp-related h2 {
  font-family: var(--font-display);
  font-weight: var(--weight-extra);
  font-size: var(--text-2xl);
  margin: 0;
}

/* Karuzela (telefon/tablet, jak suwak opinii) → siatka 4 w rzędzie od
   64em, tego samego breakpointu co .pdp-details__grid niżej na stronie.
   Przyciski karuzeli znikają — cztery karty mieszczą się bez przewijania. */
@media (min-width: 64em) {
  .pdp-related .slider__controls {
    display: none;
  }

  .pdp-related__track {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    overflow: visible;
    scroll-snap-type: none;
    padding: 0;
    margin-inline: 0;
  }

  /* Selektor złożony (0-2-0), nie sama .pdp-related__item — responsive.css
     (ładowany jako ostatni <link>, patrz head() w build.py) ma własną,
     jednoklasową regułę „≥62em .slider__item { width: calc(.../3) }" dla
     suwaka opinii. Ta sama specyficzność + późniejszy plik = ich reguła
     wygrywała mimo media query tutaj, więc karty kurczyły się do ~1/3
     kolumny grida zamiast wypełniać ją w całości. Ten sam wzorzec bugu
     co .pdp__actions.pdp__actions--inline (patrz historia zmian). */
  .pdp-related__track .pdp-related__item {
    width: auto;
  }
}
