@charset "UTF-8";

/* ═══════════════════════════════════════════════════════════════════════════
   KROJE PISMA — osadzone lokalnie
   ═══════════════════════════════════════════════════════════════════════════
   Satoshi (tekst) i Clash Display (nagłówki), oba w wersji ZMIENNEJ: jeden
   plik pokrywa cały zakres grubości zamiast pięciu osobnych. Razem 70 KB.

   Pokrycie polskich znaków zweryfikowane przez parsowanie tablicy `cmap`
   obu plików — komplet 18 znaków diakrytycznych plus typografia („ ” — · ×).

   Osadzenie lokalne usuwa ostatnie połączenie z hostem zewnętrznym: strona
   nie odpytuje już fonts.googleapis.com ani fonts.gstatic.com, przez co
   pierwszy render nie czeka na obcy serwer, a CSP mogło zostać zaostrzone.
   ═══════════════════════════════════════════════════════════════════════════ */
@font-face {
  font-family: 'Satoshi';
  src: url('Satoshi-Variable.woff2') format('woff2');
  font-weight: 300 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Clash Display';
  src: url('ClashDisplay-Variable.woff2') format('woff2');
  font-weight: 200 700;
  font-style: normal;
  font-display: swap;
}
/* ═══════════════════════════════════════════════════════════════════════════
   RUNPOTEC — PROGRAM DEALERSKI PL
   Arkusz główny. Mobile-first. Zero frameworków.

   SPIS TREŚCI
   01. Tokeny (CSS variables)
   02. Reset i podstawy
   03. Typografia i elementy współdzielone
   04. Przyciski
   05. Animacje scrollowania
   06. Header + nawigacja
   07. Hero
   08. Marquee
   09. Sekcje / siatki
   10. Filary (prowizja + szkolenia)
   11. Karty, oczekiwania
   12. Wiersze produktowe
   13. Proces
   14. Pasek CTA
   15. FAQ
   16. Formularz
   17. Footer + FAB
   18. Breakpointy
   19. Dostępność / reduced-motion / druk
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── 01. TOKENY ──────────────────────────────────────────────────────────── */
:root {
  /* Marka */
  --red:        #e30613;
  --red-600:    #c00510;
  --red-700:    #9d040d;
  --red-soft:   rgba(227, 6, 19, .12);
  --red-glow:   rgba(227, 6, 19, .38);

  /* Skala ciemna */
  --ink:        #0b0c0f;
  --ink-2:      #12141a;
  --ink-3:      #191c23;
  --ink-4:      #22262f;
  --ink-5:      #2e333d;

  /* Skala jasna */
  --paper:      #f4f5f7;
  --paper-2:    #ffffff;
  --paper-3:    #e9ebef;

  /* Tekst */
  --tx-on-dark:      #ffffff;
  --tx-on-dark-mute: #98a1ae;
  --tx-on-light:      #14161b;
  --tx-on-light-mute: #575f6c;

  /* Linie */
  --line-dark:  rgba(255, 255, 255, .09);
  --line-dark-2:rgba(255, 255, 255, .16);
  --line-light: rgba(11, 12, 15, .10);

  /* Typografia */
  --font-body:    'Satoshi', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif;
  --font-display: 'Clash Display', 'Satoshi', 'Segoe UI', Arial, sans-serif;

  /* Rytm */
  --container:   1280px;
  --gutter:      clamp(1.15rem, 4vw, 2.5rem);
  --section-y:   clamp(4.5rem, 9vw, 9rem);
  --hdr-h:       76px;

  /* Kształt i głębia */
  --r-sm:  6px;
  --r:     12px;
  --r-lg:  18px;
  --sh-1:  0 1px 2px rgba(11, 12, 15, .06), 0 2px 6px rgba(11, 12, 15, .05);
  --sh-2:  0 14px 34px -10px rgba(11, 12, 15, .18), 0 4px 12px rgba(11, 12, 15, .07);
  --sh-3:  0 40px 90px -28px rgba(0, 0, 0, .62), 0 12px 32px -12px rgba(0, 0, 0, .45);
  --sh-red:0 18px 42px -14px var(--red-glow);

  /* ── Ruch ────────────────────────────────────────────────────────────────
     Krzywe dobrane pod długie, spokojne wyhamowanie zamiast szybkiego
     „doskoku”. To ono odpowiada za wrażenie gładkości — nie sama długość
     animacji, tylko to, że koniec ruchu jest miękki i przewidywalny. */
  --ease:      cubic-bezier(.25, .1, .25, 1);   /* ogólnego przeznaczenia */
  --ease-out:  cubic-bezier(.16, 1, .3, 1);     /* mocne wyhamowanie na końcu */
  --ease-soft: cubic-bezier(.32, .72, 0, 1);    /* miękkie wejście i wyjście */

  --t-fast:   .24s var(--ease);
  --t:        .38s var(--ease);
  --t-slow:   .78s var(--ease-out);
}

/* ── 02. RESET I PODSTAWY ────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }

* { margin: 0; }

html {
  -webkit-text-size-adjust: 100%;
  /* Bez `scroll-behavior: smooth` — przewijaniem do kotwic steruje JS
     (dłuższa krzywa z wyhamowaniem, patrz moduł smoothAnchors w main.js).
     Zostawienie obu naraz powodowałoby, że natywna animacja walczy
     z własną i ruch się zacina. Przy wyłączonych animacjach JS nie
     przechwytuje kliknięć i działa zwykły, natychmiastowy skok. */
  scroll-padding-top: calc(var(--hdr-h) + 12px);

  /* Twarda blokada przewijania w poziomie.
     `clip` zamiast `hidden` jest tu KLUCZOWE: `hidden` wymusiłoby
     `overflow-y: auto`, co utworzyłoby kontener przewijania i zabiło
     `position: sticky` w sekcji Linia produktowa. `clip` nie tworzy
     kontenera. Deklaracja `hidden` przed nim to fallback dla przeglądarek
     bez obsługi `clip` (Safari < 16). */
  overflow-x: hidden;
  overflow-x: clip;
}

body {
  font-family: var(--font-body);
  font-size: clamp(1rem, .25vw + .95rem, 1.0625rem);
  line-height: 1.65;
  color: var(--tx-on-dark);
  background: var(--ink);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
  overflow-x: clip;                 /* patrz komentarz przy html */
  font-feature-settings: 'kern' 1, 'liga' 1;
}

img, svg, video { display: block; max-width: 100%; }
img { height: auto; }

svg {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
  width: 1.25em;
  height: 1.25em;
  flex: none;
}

a { color: inherit; text-decoration: none; }

button, input, select, textarea { font: inherit; color: inherit; }
button { background: none; border: 0; cursor: pointer; }

ul, ol { list-style: none; padding: 0; }

address { font-style: normal; }

::selection { background: var(--red); color: #fff; }

/* ── Ziarno ────────────────────────────────────────────────────────────────
   Delikatna faktura na całej stronie. Płaskie, gładkie ciemne tło czyta się
   jako „wypełnienie kolorem"; szum na poziomie kilku procent nadaje mu
   głębi charakterystycznej dla dobrego druku.

   Szum jest generowany w locie (SVG feTurbulence w data-URI) — zero
   dodatkowych requestów i zero plików graficznych. Bez `mix-blend-mode`,
   bo pełnoekranowe blendowanie wymusza przemalowania przy przewijaniu.
   Na telefonach wyłączone: zysk wizualny jest tam znikomy, a to jedna
   warstwa kompozycji mniej. */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  opacity: .038;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 160px 160px;
}
@media (max-width: 900px) {
  body::after { display: none; }
}

:focus-visible {
  outline: 2px solid var(--red);
  outline-offset: 3px;
  border-radius: 3px;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 200;
  background: var(--red);
  color: #fff;
  padding: .85rem 1.4rem;
  font-weight: 700;
}
.skip-link:focus { left: 0; }

/* Pasek przewijania (WebKit) — detal, który podnosi wrażenie „dopieszczenia” */
::-webkit-scrollbar { width: 11px; }
::-webkit-scrollbar-track { background: var(--ink-2); }
::-webkit-scrollbar-thumb { background: var(--ink-5); border-radius: 99px; border: 3px solid var(--ink-2); }
::-webkit-scrollbar-thumb:hover { background: var(--red); }

/* ── 03. TYPOGRAFIA I ELEMENTY WSPÓŁDZIELONE ─────────────────────────────── */
.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.container--narrow { max-width: 900px; }

/* Nagłówki na Clash Display — to krój wystawowy, ma nieść charakter marki.
   Maksymalna grubość tego fontu to 700, więc nie żądamy 800: przeglądarka
   musiałaby ją syntezować, co pogrubia litery sztucznie i brzydko. */
/* ── ZASADA TYPOGRAFICZNA ──────────────────────────────────────────────────
   Dwa kroje i jasny podział, bez wyjątków:
     Clash Display  → wyłącznie nagłówki i duże liczby ozdobne
     Satoshi        → cała reszta, łącznie z drobnymi etykietami

   Clash ma ciasny domyślny rytm — przy ujemnym odstępie i dużym stopniu
   sąsiednie wyrazy zlewały się w jeden („który sam”). Stąd zerowy odstęp
   międzyliterowy i dodatnie word-spacing. */
h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.16;
  /* Clash Display ma bardzo ciasny rytm własny — przy zerowym trackingu
     litery się zlewają („potrzebujesz”, „procedur”). Dodatni odstęp
     międzyliterowy plus wyraźny odstęp międzywyrazowy rozwiązują to
     bez zmiany kroju. */
  letter-spacing: .018em;
  word-spacing: .14em;
  text-wrap: balance;
}
/* Nagłówki drobne wracają na Satoshi — Clash jest tam za wyrazisty */
.faq__q, .formcard__head h3, .card__title, .step__title, .footer__col h4 {
  font-family: var(--font-body);
  font-weight: 650;
  word-spacing: normal;
}

/* Drobne etykiety również na Satoshi — reguła domykająca jest na KOŃCU
   arkusza (sekcja 20), bo komponenty deklarują własny krój niżej w pliku
   i przy równej specyficzności wygrywa ostatnia deklaracja. */

/* Bez ujemnego trackingu — te klasy nadpisywały regułę nagłówków i to one
   odpowiadały za sklejone wyrazy widoczne w sekcjach „Trzy kroki”,
   „Zanim zadzwonimy” i „Wszystko, czego potrzebujesz”. */
.h2 { font-size: clamp(1.85rem, 3.6vw, 3.15rem); }
.h3 { font-size: clamp(1.3rem, 1.9vw, 1.75rem); }

/* Bez `white-space: nowrap` — na wąskim ekranie wyróżniona fraza jest dłuższa
   niż szerokość okna i wypychała nagłówek poza kadr. */
.hl { color: var(--red); position: relative; }

.lead {
  font-size: clamp(1.03rem, .55vw + .9rem, 1.2rem);
  line-height: 1.72;
  color: var(--tx-on-dark-mute);
  max-width: 62ch;
  text-wrap: pretty;
}
.lead--center { margin-inline: auto; text-align: center; }

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: .6rem;
  font-family: var(--font-display);
  font-size: .82rem;
  font-weight: 600;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--tx-on-dark-mute);
}
.eyebrow--dark { color: var(--tx-on-light-mute); }
.eyebrow__dot {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--red);
  box-shadow: 0 0 0 4px var(--red-soft);
}

.stack { display: flex; flex-direction: column; align-items: flex-start; gap: 1.25rem; }

/* Lista z „ptaszkami” */
.ticks { display: grid; gap: .85rem; }
.ticks li {
  position: relative;
  padding-left: 2.1rem;
  color: var(--tx-on-dark-mute);
  line-height: 1.6;
}
.ticks li strong { color: var(--tx-on-dark); font-weight: 650; }
/* Punktor: pełne czerwone koło z białym znacznikiem. Poprzednia wersja
   (blade tło + czerwony ptaszek na obwódce) była na jasnej karcie
   praktycznie niewidoczna i wyglądała na niedokończoną. */
.ticks li::before {
  content: '';
  position: absolute;
  left: 0; top: .3em;
  width: 1.15rem; height: 1.15rem;
  border-radius: 50%;
  background: var(--red);
  box-shadow: 0 2px 7px -2px var(--red-glow);
}
.ticks li::after {
  content: '';
  position: absolute;
  left: .34rem; top: .58em;
  width: .42rem; height: .21rem;
  border-left: 2px solid #fff;
  border-bottom: 2px solid #fff;
  transform: rotate(-45deg);
}
.ticks--tight { gap: .7rem; font-size: .97rem; }

/* Media z ramką „inżynierską” */
.media { position: relative; margin: 0; }
.media picture { display: contents; }
/* Rendery produktowe mają przezroczyste tło, więc NIE kadrujemy ich (contain)
   i nie dajemy box-shadow — prostokątny cień pod wyciętym produktem wygląda
   jak błąd. Cień robi filter, który podąża za sylwetką. */
.media img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: contain;
  padding: clamp(.75rem, 2vw, 1.5rem);
  filter:
    drop-shadow(0 24px 30px rgba(0, 0, 0, .8))
    drop-shadow(0 0 60px rgba(227, 6, 19, .14));
}
/* Odsłanianie zdjęcia maską — obraz „wyjeżdża” zza dolnej krawędzi
   i jednocześnie zjeżdża ze skali. Sam zanik krycia wyglądał zbyt zwyczajnie.
   `clip-path` nie koliduje z paralaksą, która operuje na `transform`. */
.media img {
  clip-path: inset(0 0 100% 0);
  transition: clip-path 1.25s var(--ease-out), scale 1.4s var(--ease-out);
  scale: 1.06;
}
[data-anim].is-in .media img,
.media[data-anim].is-in img {
  clip-path: inset(0 0 0 0);
  scale: 1;
}
@media (prefers-reduced-motion: reduce) {
  .media img { clip-path: none; scale: 1; transition: none; }
}

.media--framed::before {
  content: '';
  position: absolute;
  inset: -.9rem -.9rem auto auto;
  width: 46%;
  aspect-ratio: 1;
  border-top: 2px solid var(--red);
  border-right: 2px solid var(--red);
  border-radius: 0 var(--r) 0 0;
  pointer-events: none;
  z-index: 2;
}
.media--framed::after {
  content: '';
  position: absolute;
  inset: auto auto -.9rem -.9rem;
  width: 30%;
  aspect-ratio: 1;
  border-bottom: 2px solid var(--line-dark-2);
  border-left: 2px solid var(--line-dark-2);
  border-radius: 0 0 0 var(--r);
  pointer-events: none;
}
.section--light .media--framed::after { border-color: rgba(11, 12, 15, .18); }

/* ── 04. PRZYCISKI ───────────────────────────────────────────────────────── */
.btn {
  --btn-bg: transparent;
  --btn-fg: currentColor;
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .6rem;
  padding: .84rem 1.5rem;
  border-radius: var(--r-sm);
  font-weight: 700;
  font-size: .95rem;
  letter-spacing: -.005em;
  white-space: nowrap;
  background: var(--btn-bg);
  color: var(--btn-fg);
  transition: transform var(--t-fast), box-shadow var(--t), background-color var(--t), border-color var(--t), color var(--t);
  overflow: hidden;
  isolation: isolate;
}
.btn svg { width: 1.1em; height: 1.1em; }
.btn:active { transform: translateY(1px) scale(.995); }

.btn--lg { padding: 1.06rem 1.9rem; font-size: 1rem; }
.btn--block { width: 100%; }

/* Primary — pełny gradient marki. Płaska czerwień wygląda na domyślną;
   gradient z rozjaśnieniem u góry i przyciemnieniem u dołu daje przyciskowi
   bryłę, a górna krawędź świetlna sugeruje wypukłość. */
.btn--primary {
  --btn-fg: #fff;
  background: linear-gradient(168deg, #ff2a3c 0%, var(--red) 42%, var(--red-700) 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .28),
    inset 0 -1px 0 rgba(0, 0, 0, .22),
    0 12px 30px -10px var(--red-glow),
    0 2px 6px rgba(0, 0, 0, .22);
}
.btn--primary::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(168deg, #ff4152 0%, #f01021 45%, var(--red-600) 100%);
  opacity: 0;
  transition: opacity var(--t);
}
.btn--primary:hover {
  transform: translateY(-2px);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .34),
    0 22px 48px -14px var(--red-glow),
    0 4px 10px rgba(0, 0, 0, .26);
}
.btn--primary:hover::before { opacity: 1; }
.btn--primary svg { transition: transform var(--t); }
.btn--primary:hover svg { transform: translateX(4px); }

/* Przetarcie światłem przy najechaniu — detal, który odróżnia przycisk
   „zrobiony” od „wygenerowanego”. Jedna warstwa, wyłącznie transform. */
.btn--primary::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(105deg, transparent 32%, rgba(255, 255, 255, .3) 50%, transparent 68%);
  transform: translateX(-130%);
  transition: transform .9s var(--ease-out);
  pointer-events: none;
}
.btn--primary:hover::after { transform: translateX(130%); }

.btn--outline {
  --btn-fg: var(--tx-on-dark);
  border: 1px solid var(--line-dark-2);
  backdrop-filter: blur(6px);
}
.btn--outline:hover { border-color: var(--red); color: #fff; background: rgba(227, 6, 19, .1); transform: translateY(-2px); }

.btn--ghost { --btn-fg: var(--tx-on-dark-mute); padding: .6rem .8rem; font-size: .9rem; }
.btn--ghost:hover { --btn-fg: #fff; }

.btn--dark { --btn-bg: var(--ink); --btn-fg: #fff; }
.btn--dark:hover { --btn-bg: #000; transform: translateY(-2px); box-shadow: var(--sh-2); }

.btn--linkish { --btn-fg: rgba(255, 255, 255, .9); padding-inline: .4rem; }
.btn--linkish strong { border-bottom: 2px solid rgba(255, 255, 255, .45); }
.btn--linkish:hover strong { border-color: #fff; }

/* Stan wysyłki formularza */
.btn__spinner {
  width: 1.1em; height: 1.1em;
  border: 2px solid rgba(255, 255, 255, .35);
  border-top-color: #fff;
  border-radius: 50%;
  display: none;
  animation: spin .7s linear infinite;
}
.btn.is-loading { pointer-events: none; opacity: .82; }
.btn.is-loading .btn__spinner { display: block; }
@keyframes spin { to { transform: rotate(360deg); } }

/* ── 05. ANIMACJE SCROLLOWANIA ───────────────────────────────────────────────
   Sterowane IntersectionObserverem (assets/js/main.js).
   Świadoma decyzja: bez GSAP. Efekt identyczny, 0 KB zależności,
   kompozycja wyłącznie na transform/opacity → praca na GPU.            */
/* Mniejsze przesunięcia, dłuższy czas, mocniejsze wyhamowanie.
   Duży dystans + krótki czas = element „wskakuje”. Mały dystans + długi
   czas + miękka krzywa = element „dopływa” na miejsce. */
[data-anim] {
  opacity: 0;
  transition:
    opacity   1.05s var(--ease-out),
    transform 1.2s  var(--ease-out),
    filter    .95s  var(--ease-out);
  transition-delay: calc(var(--d, 0) * 110ms);
  will-change: transform, opacity;
}
[data-anim="up"]       { transform: translate3d(0, 26px, 0) scale(.994); }
[data-anim="in-left"]  { transform: translate3d(-8%, 0, 0) scale(.972); filter: blur(2px); }
[data-anim="in-right"] { transform: translate3d(8%, 0, 0)  scale(.972); filter: blur(2px); }
/* Wejście z lekką perspektywą — karta „kładzie się” na miejsce zamiast
   wsuwać z boku. Przy trzech kartach obok siebie czyta się to spokojniej
   niż trzy jednoczesne przesunięcia poziome. */
[data-anim="rise3d"] {
  transform: perspective(1400px) rotateX(7deg) translate3d(0, 46px, 0) scale(.97);
  transform-origin: 50% 100%;
}

[data-anim].is-in {
  opacity: 1;
  transform: none;
  filter: none;
  will-change: auto;
}

[data-delay="1"] { --d: 1; }
[data-delay="2"] { --d: 2; }
[data-delay="3"] { --d: 3; }
[data-delay="4"] { --d: 4; }

/* Kaskada pozycji listy — punkty wchodzą kolejno, nie całym blokiem.
   Indeks --sd nadaje JS przy starcie (patrz moduł animacji wejścia). */
[data-anim] > li {
  opacity: 0;
  transform: translate3d(0, 12px, 0);
  transition:
    opacity   .8s var(--ease-out),
    transform .9s var(--ease-out);
  transition-delay: calc(var(--d, 0) * 110ms + var(--sd, 0) * 80ms);
}
[data-anim].is-in > li { opacity: 1; transform: none; }

/* ── ODSŁANIANIE NAGŁÓWKÓW SŁOWO PO SŁOWIE ────────────────────────────────
   Każdy wyraz wyjeżdża zza własnej maski, z narastającym opóźnieniem.
   Podziału na wyrazy dokonuje JS (moduł splitHeadings) — dzięki temu treść
   w plikach tłumaczeń pozostaje zwykłym tekstem, bez znaczników.

   padding/margin-bottom są konieczne: `overflow: hidden` na inline-block
   ucinałby ogonki i zjazdy liter (ą, ę, ł, g, y) w polskich nagłówkach. */
.w {
  display: inline-block;
  overflow: hidden;
  vertical-align: top;
  padding-bottom: .16em;
  margin-bottom: -.16em;
}
.w > i {
  display: inline-block;
  font-style: inherit;
  transform: translate3d(0, 108%, 0);
  transition: transform 1.15s var(--ease-out);
  transition-delay: calc(var(--wi, 0) * 45ms);
  will-change: transform;
}
[data-anim].is-in .w > i { transform: none; }

/* Nagłówek z podziałem na wyrazy nie animuje się już „jako blok” —
   ruch niesie sama kaskada, inaczej efekty nakładałyby się na siebie. */
[data-anim].has-words {
  opacity: 1;
  transform: none;
  filter: none;
}

@media (prefers-reduced-motion: reduce) {
  .w > i { transform: none; transition: none; }
}

/* Odsłonięcie linii nagłówka (maska + wyjazd od dołu) */
.reveal { display: block; overflow: hidden; padding-bottom: .08em; }
.reveal > span {
  display: block;
  transform: translate3d(0, 105%, 0);
  transition: transform 1.35s var(--ease-out);
  transition-delay: calc(var(--d, 0) * 135ms);
}
.reveal.is-in > span { transform: none; }

/* ── 06. HEADER ──────────────────────────────────────────────────────────── */
.hdr {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 100;
  height: var(--hdr-h);
  display: flex;
  align-items: center;
  /* Dłuższe, miękkie przejście — nagłówek ma się „osadzać”, a nie przeskakiwać
     między stanami przy pierwszym ruchu kółka. */
  transition:
    background-color .5s var(--ease-out),
    backdrop-filter  .5s var(--ease-out),
    border-color     .5s var(--ease-out),
    height           .45s var(--ease-out);
  border-bottom: 1px solid transparent;
}
.hdr.is-stuck {
  height: 64px;
  background: rgba(11, 12, 15, .82);
  backdrop-filter: blur(16px) saturate(150%);
  border-bottom-color: var(--line-dark);
}
.hdr__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.25rem;
}
/* Pasek postępu skalujemy transformem, nie szerokością — width wymusza
   przeliczenie układu w każdej klatce, transform idzie po stronie GPU.
   Dłuższa krzywa sprawia, że pasek płynnie dogania scroll zamiast skakać. */
.hdr__progress {
  position: absolute;
  left: 0; bottom: -1px;
  height: 2px;
  width: 100%;
  transform: scaleX(0);
  transform-origin: left;
  background: linear-gradient(90deg, var(--red-700), var(--red));
  transition: transform .28s var(--ease-out);
  will-change: transform;
}

/* min-height 44px — logotyp jest klikalny (powrót na górę), więc musi być
   wygodnym celem dotykowym, a sam obrazek ma tylko ~28 px wysokości. */
.brand { display: flex; align-items: center; gap: .85rem; flex: none; min-height: 44px; }
.brand picture { display: contents; }
/* Logo ma proporcje ok. 5,35:1 — sterujemy wysokością, szerokość dolicza się
   sama. Wersja przyklejona nagłówka jest niższa, więc logo też się kurczy. */
/* Logotyp zawiera wordmark ORAZ claim pod nim, więc sam napis to tylko ~70%
   wysokości pliku. Przy 24 px marka robiła się nieczytelna — stąd 34 px. */
.brand__logo { height: 50px; width: auto; transition: height var(--t); }
.hdr.is-stuck .brand__logo { height: 40px; }
.brand__mark {
  font-family: var(--font-display);
  font-size: 1.42rem;
  font-weight: 700;
  letter-spacing: .07em;
  line-height: 1;
  color: #fff;
  position: relative;
}
.brand__mark::after {
  content: '';
  position: absolute;
  right: -.42rem; bottom: .1em;
  width: 6px; height: 6px;
  background: var(--red);
}
.brand__mark--sm { font-size: 1.2rem; }
.brand__divider { width: 1px; height: 24px; background: var(--line-dark-2); }
.brand__sub {
  font-size: .66rem;
  line-height: 1.25;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--tx-on-dark-mute);
  font-weight: 600;
}

.nav { display: flex; align-items: center; gap: 1.9rem; }
.nav__list { display: flex; align-items: center; gap: 1.75rem; }
.nav__list a {
  position: relative;
  font-size: .93rem;
  font-weight: 550;
  color: var(--tx-on-dark-mute);
  transition: color var(--t-fast);
  padding-block: .3rem;
  white-space: nowrap;              /* pozycja menu nigdy nie łamie się na dwie linie */
}
/* Podkreślenie wyjeżdża od lewej przy wejściu kursora i chowa się w prawo
   przy jego zejściu — dwa różne punkty zaczepienia zamiast jednego. */
.nav__list a::after {
  content: '';
  position: absolute;
  left: 0; bottom: 0;
  width: 100%; height: 2px;
  background: var(--red);
  transform: scaleX(0);
  transform-origin: right;
  transition: transform .45s var(--ease-out);
}
.nav__list a:hover::after,
.nav__list a.is-active::after { transform-origin: left; }
.nav__list a:hover, .nav__list a.is-active { color: #fff; }
.nav__list a:hover::after, .nav__list a.is-active::after { transform: scaleX(1); }
.nav__phone { display: none; }

/* ── Przełącznik wersji językowej ──────────────────────────────────────────
   Flagi mają różne proporcje (PL 1,6:1, US 1,9:1), więc każda dostaje ten sam
   kadr i object-fit: cover — inaczej rządek wyglądałby na poszarpany. */
.lang {
  display: flex;
  align-items: center;
  gap: .2rem;
  padding: .2rem;
  border: 1px solid var(--line-dark);
  border-radius: 99px;
  flex: none;
}
.lang__opt {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: .42rem;
  padding: .34rem .68rem;
  border-radius: 99px;
  font-size: .78rem;
  font-weight: 700;
  letter-spacing: .06em;
  color: var(--tx-on-dark-mute);
  transition: color var(--t-fast), background-color var(--t-fast), opacity var(--t-fast);
}
.lang__opt img {
  width: 18px;
  height: 12px;
  object-fit: cover;
  border-radius: 2px;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, .22);
}
.lang__opt.is-active {
  background: rgba(255, 255, 255, .09);
  color: #fff;
}
/* Nieaktywny język — pełnoprawny odnośnik, rozjaśnia się przy najechaniu */
.lang__opt:not(.is-active) { opacity: .62; }
.lang__opt:not(.is-active):hover { opacity: 1; color: #fff; background: rgba(255, 255, 255, .05); }

.burger {
  display: none;
  width: 44px; height: 44px;
  position: relative;
  flex: none;
  margin-right: -.5rem;
}
.burger span {
  position: absolute;
  left: 11px;
  width: 22px; height: 2px;
  background: #fff;
  border-radius: 2px;
  transition: transform var(--t), opacity var(--t-fast), width var(--t);
}
.burger span:nth-child(1) { top: 15px; }
.burger span:nth-child(2) { top: 21px; width: 16px; }
.burger span:nth-child(3) { top: 27px; }
.burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); width: 22px; }

/* ── 07. HERO ────────────────────────────────────────────────────────────── */
.hero {
  position: relative;
  min-height: 100svh;
  display: flex;
  align-items: center;
  padding-top: calc(var(--hdr-h) + clamp(2.5rem, 6vw, 5rem));
  padding-bottom: clamp(4rem, 8vw, 7rem);
  overflow: clip;
  background: radial-gradient(120% 90% at 78% 12%, #1b1f27 0%, var(--ink) 58%);
}
.hero__bg { position: absolute; inset: 0; pointer-events: none; overflow: hidden; }
/* Winieta — przyciemnione narożniki wypychają treść do przodu i nadają
   kadrowi głębi. Bez niej tło jest płaskie jak wypełnienie kolorem. */
.hero__bg::after {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(120% 95% at 50% 40%, transparent 42%, rgba(0, 0, 0, .55) 100%);
}
.hero__grid {
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(to right, rgba(255, 255, 255, .045) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(255, 255, 255, .045) 1px, transparent 1px);
  background-size: 74px 74px;
  mask-image: radial-gradient(115% 85% at 22% 20%, #000 12%, transparent 72%);
}
.hero__glow {
  position: absolute;
  top: -22%; right: -12%;
  width: 62vw; aspect-ratio: 1;
  background: radial-gradient(circle, var(--red-glow) 0%, transparent 62%);
  filter: blur(28px);
  opacity: .55;
  /* Bardzo powolne „oddychanie" poświaty — statyczne tło wygląda na martwe,
     ale ruch musi być na granicy zauważalności, żeby nie rozpraszał. */
  animation: heroGlow 11s ease-in-out infinite;
}
@keyframes heroGlow {
  0%, 100% { opacity: .48; transform: scale(1); }
  50%      { opacity: .62; transform: scale(1.06); }
}
.hero__slash {
  position: absolute;
  left: -8%; bottom: -34%;
  width: 46%; height: 130%;
  background: linear-gradient(180deg, transparent, rgba(227, 6, 19, .09));
  transform: rotate(15deg);
  border-right: 1px solid rgba(227, 6, 19, .22);
}

.hero__inner {
  position: relative;
  display: grid;
  gap: clamp(2.75rem, 6vw, 4.5rem);
  align-items: center;
}
.hero__copy { display: flex; flex-direction: column; align-items: flex-start; gap: 1.5rem; }

.hero__title {
  font-family: var(--font-display);
  font-size: clamp(2.4rem, 6.5vw, 4.9rem);
  font-weight: 600;
  /* Przy dużym stopniu tracking może być mniejszy niż w mniejszych
     nagłówkach, ale zerowy nadal sklejał wyrazy — stąd wartości dodatnie. */
  letter-spacing: .008em;
  word-spacing: .12em;
  line-height: 1.08;
}
.hero__title em {
  font-style: normal;
  color: var(--red);
  position: relative;
}
.hero__lead { max-width: 54ch; }

.hero__actions { display: flex; flex-wrap: wrap; gap: .85rem; }

.hero__stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 1px;
  width: 100%;
  margin-top: .85rem;
  background: var(--line-dark);
  border-radius: var(--r);
  overflow: hidden;
  border: 1px solid var(--line-dark);
}
.stat { padding: 1.05rem 1.2rem; background: rgba(255, 255, 255, .022); }
.stat__label {
  font-size: .72rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--tx-on-dark-mute);
  font-weight: 600;
}
.stat__value {
  font-family: var(--font-display);
  /* clamp, nie stała wartość — kafelek ma minmax(140px, 1fr), więc dłuższa
     wartość musi mieć jak zejść, zamiast wyjść poza ramkę */
  font-size: clamp(1.35rem, 1.9vw, 1.85rem);
  font-weight: 700;
  line-height: 1.15;
  margin-top: .2rem;
  color: #fff;
}

/* Pasek cech pod CTA — zastąpił kafelki z liczbami. Lekki, typograficzny,
   nie konkuruje z nagłówkiem o uwagę. */
.hero__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .7rem 1.4rem;
  margin-top: .6rem;
  font-family: var(--font-display);
  font-size: .84rem;
  font-weight: 600;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--tx-on-dark-mute);
}
.hero__meta span { display: flex; align-items: center; gap: 1.4rem; }
.hero__meta span:not(:last-child)::after {
  content: '';
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--red);
  box-shadow: 0 0 0 3px var(--red-soft);
  flex: none;
}

/* Wyimek — mocne zdanie zamykające blok tekstu */
.quote {
  margin-top: .4rem;
  padding: .2rem 0 .2rem 1.5rem;
  border-left: 3px solid var(--red);
  font-size: clamp(1.02rem, 1.25vw, 1.16rem);
  font-weight: 500;
  line-height: 1.62;
  color: #fff;
  max-width: 54ch;
}

.hero__visual { position: relative; margin: 0; }
.hero__visual picture { display: contents; }
.hero__visual img {
  width: 100%;
  aspect-ratio: 4 / 3.4;
  object-fit: contain;
  filter:
    drop-shadow(0 34px 44px rgba(0, 0, 0, .9))
    drop-shadow(0 0 90px rgba(227, 6, 19, .2));
}

/* ── KARUZELA HERO ─────────────────────────────────────────────────────────
   Slajdy leżą jeden na drugim; przełączanie to wyłącznie opacity i skala,
   więc przejście jest w całości po stronie GPU. Wysokość bierze się
   z pierwszego slajdu (position: static), reszta jest pozycjonowana
   absolutnie — dzięki temu kontener nie skacze przy zmianie produktu. */
.carousel { position: relative; }

.carousel__slide {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  opacity: 0;
  transform: scale(.97);
  visibility: hidden;
  transition:
    opacity .85s var(--ease-out),
    transform 1.1s var(--ease-out),
    visibility .85s;
  pointer-events: none;
}
/* Pierwszy slajd zostaje w przepływie NA STAŁE i tylko on wyznacza wysokość
   kontenera. Aktywny slajd nie może wracać do przepływu — przy aktywnym
   slajdzie innym niż pierwszy w układzie stałyby dwa naraz i kontener
   robił się dwukrotnie za wysoki. */
.carousel__slide:first-child { position: relative; }
.carousel__slide.is-active {
  opacity: 1;
  transform: none;
  visibility: visible;
  pointer-events: auto;
}

.carousel__shot { position: relative; display: block; border-radius: var(--r); }
.carousel__shot img { transition: transform 1s var(--ease-out); }
.carousel__shot:hover img { transform: scale(1.035); }

/* Znacznik odnośnika zewnętrznego — pojawia się przy najechaniu */
.carousel__ext {
  position: absolute;
  top: .35rem; right: .35rem;
  display: grid;
  place-items: center;
  width: 2.3rem; height: 2.3rem;
  border-radius: 50%;
  background: rgba(11, 12, 15, .82);
  border: 1px solid var(--line-dark-2);
  backdrop-filter: blur(8px);
  color: #fff;
  opacity: 0;
  transform: scale(.8) translateY(-4px);
  transition: opacity var(--t), transform var(--t);
}
.carousel__ext svg { width: 1.05rem; height: 1.05rem; }
.carousel__shot:hover .carousel__ext,
.carousel__shot:focus-visible .carousel__ext { opacity: 1; transform: none; }

/* Panel z parametrami — „po boku” zdjęcia */
.carousel__info {
  margin-top: .35rem;
  padding: .9rem 1.1rem;
  background: rgba(11, 12, 15, .72);
  border: 1px solid var(--line-dark);
  border-left: 3px solid var(--red);
  border-radius: var(--r-sm);
  backdrop-filter: blur(10px);
}
.carousel__cat {
  display: block;
  font-family: var(--font-display);
  font-size: .7rem;
  font-weight: 600;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--red);
}
.carousel__name {
  display: block;
  font-family: var(--font-display);
  font-size: clamp(1.05rem, 1.5vw, 1.25rem);
  font-weight: 600;
  color: #fff;
  margin: .15rem 0 .5rem;
}
.carousel__spec { display: flex; flex-wrap: wrap; gap: .3rem .95rem; }
.carousel__spec li {
  position: relative;
  font-size: .82rem;
  font-weight: 500;
  color: var(--tx-on-dark-mute);
  padding-left: .85rem;
}
.carousel__spec li::before {
  content: '';
  position: absolute;
  left: 0; top: .55em;
  width: 4px; height: 4px;
  border-radius: 50%;
  background: var(--red);
}
.carousel__extra { margin-top: .5rem; font-size: .76rem; color: var(--tx-on-dark-mute); }
.carousel__extra a { color: #fff; text-decoration: underline; text-underline-offset: 2px; }
.carousel__extra a:hover { color: var(--red); }

/* Paski postępu zamiast kropek — od razu widać, ile produktów jest w rotacji.
   Cienkie kreski (3 px) ginęły na ciemnym tle; teraz mają wyraźny tor,
   zaokrąglenie i powiększone pole kliknięcia poprzez padding. */
.carousel__nav { display: flex; gap: .45rem; margin-top: 1rem; }
.carousel__dot {
  flex: 1;
  height: 5px;
  padding: 0;
  border: 0;
  border-radius: 99px;
  background: rgba(255, 255, 255, .16);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .06);
  overflow: hidden;
  cursor: pointer;
  transition: background-color var(--t), box-shadow var(--t);
}
.carousel__dot:hover { background: rgba(255, 255, 255, .3); }
.carousel__dot.is-active { box-shadow: 0 0 14px -2px var(--red-glow); }
.carousel__bar {
  display: block;
  height: 100%;
  width: 100%;
  background: var(--red);
  transform: scaleX(0);
  transform-origin: left;
}
/* Pasek aktywnego slajdu wypełnia się w tempie automatycznej zmiany */
.carousel__dot.is-active .carousel__bar { animation: carouselBar var(--carousel-time, 5.5s) linear forwards; }
.carousel__dot.is-done .carousel__bar { transform: scaleX(1); }
@keyframes carouselBar { from { transform: scaleX(0); } to { transform: scaleX(1); } }

/* Zatrzymanie rotacji przy najechaniu — użytkownik czyta, my nie przeszkadzamy */
.carousel.is-paused .carousel__dot.is-active .carousel__bar { animation-play-state: paused; }

@media (prefers-reduced-motion: reduce) {
  .carousel__slide { transition: none; }
  .carousel__dot .carousel__bar { animation: none; transform: scaleX(1); }
}

.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}
/* Ramka dekoracyjna była projektowana pod pojedyncze, statyczne zdjęcie.
   Po dołożeniu karuzeli panel z parametrami i paski postępu wychodziły
   poza jej obrys — ramka obejmuje teraz CAŁY blok, z zapasem na oddech. */
.hero__frame {
  position: absolute;
  inset: -1rem -1rem -1rem -1rem;
  border: 1px solid rgba(227, 6, 19, .32);
  border-radius: var(--r-lg);
  pointer-events: none;
}
/* Plakietka wysunięta poza kadr zdjęcia i opuszczona do samego dołu —
   przy pozycji nad produktem zasłaniała podwozie stojaka. */
.hero__badge {
  position: absolute;
  left: -1.4rem; bottom: -.4rem;
  background: rgba(11, 12, 15, .9);
  backdrop-filter: blur(10px);
  border: 1px solid var(--line-dark-2);
  border-left: 3px solid var(--red);
  border-radius: var(--r-sm);
  padding: .8rem 1.1rem;
  box-shadow: var(--sh-2);
}
.hero__badge strong { display: block; font-size: .95rem; letter-spacing: .02em; }
.hero__badge span { font-size: .78rem; color: var(--tx-on-dark-mute); }

.hero__scroll {
  position: absolute;
  left: 50%; bottom: 1.4rem;
  transform: translateX(-50%);
  display: none;
  align-items: center;
  gap: .55rem;
  font-size: .7rem;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--tx-on-dark-mute);
  font-weight: 600;
}
.hero__scroll span {
  width: 1px; height: 34px;
  background: linear-gradient(180deg, var(--red), transparent);
  animation: scrollHint 2.1s var(--ease) infinite;
}
@keyframes scrollHint {
  0%, 100% { transform: scaleY(.35); opacity: .45; transform-origin: top; }
  50%      { transform: scaleY(1);   opacity: 1;   transform-origin: top; }
}

/* ── 08. MARQUEE ─────────────────────────────────────────────────────────── */
/* Pasek marki. Poprzednia wersja (szary tekst 34% na ciemnym tle, dodatkowo
   wygaszany maską po bokach) była praktycznie niewidoczna. Teraz jest to
   pełnokrwisty element identyfikacji: czerwień marki, białe wersaliki,
   lekkie podniesienie cieniem. */
.marquee {
  position: relative;
  background: linear-gradient(90deg, var(--red-700) 0%, var(--red) 50%, var(--red-700) 100%);
  padding-block: 1.05rem;
  overflow: hidden;
  border-block: 1px solid rgba(0, 0, 0, .4);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .16),
    inset 0 -1px 0 rgba(0, 0, 0, .2),
    0 18px 46px -20px var(--red-glow);
}
.marquee__track {
  display: flex;
  gap: 2.75rem;
  width: max-content;
  animation: marquee 42s linear infinite;
}
.marquee__item {
  font-family: var(--font-display);
  font-size: 1.05rem;
  font-weight: 600;
  letter-spacing: .19em;
  text-transform: uppercase;
  color: #fff;
  text-shadow: 0 1px 2px rgba(0, 0, 0, .3);
  display: flex;
  align-items: center;
  gap: 2.75rem;
  white-space: nowrap;
}
.marquee__item::after {
  content: '';
  width: 6px; height: 6px;
  background: rgba(255, 255, 255, .9);
  border-radius: 50%;
  flex: none;
}
@keyframes marquee { to { transform: translateX(-50%); } }
.marquee:hover .marquee__track { animation-play-state: paused; }

/* ── 09. SEKCJE ──────────────────────────────────────────────────────────── */
.section { padding-block: var(--section-y); position: relative; }

.section--dark  { background: var(--ink); }
.section--light {
  background: var(--paper);
  color: var(--tx-on-light);
}

/* ── Zmiękczenie styków sekcji ─────────────────────────────────────────────
   Przejścia jasne↔ciemne były cięte na ostro, przez co strona czytała się
   jak stos osobnych bloków. Delikatny gradient u góry każdej sekcji łączy
   je w jedną kompozycję i dodaje głębi bez ani jednego dodatkowego elementu. */
.section--light::before,
.section--dark::before {
  content: '';
  position: absolute;
  inset: 0 0 auto 0;
  height: clamp(80px, 12vw, 160px);
  pointer-events: none;
  z-index: 0;
}
.section--light::before { background: linear-gradient(180deg, rgba(11, 12, 15, .07), transparent); }
.section--dark::before  { background: linear-gradient(180deg, rgba(255, 255, 255, .05), transparent); }
/* Treść musi zostać nad gradientem */
.section > .container { position: relative; z-index: 1; }
.section--light .lead { color: var(--tx-on-light-mute); }
.section--light .ticks li { color: var(--tx-on-light-mute); }
.section--light .ticks li strong { color: var(--tx-on-light); }

.section__head {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 1.1rem;
  margin-bottom: clamp(2.75rem, 5vw, 4.5rem);
}
/* Cienka kreska domykająca nagłówek sekcji — drobiazg, który porządkuje
   kompozycję i odbiera jej „wygenerowany” charakter. */
.section__head::after {
  content: '';
  width: 3.5rem;
  height: 2px;
  margin-top: .35rem;
  background: linear-gradient(90deg, var(--red), transparent);
  border-radius: 2px;
}
.section__head .h2 { max-width: 22ch; }
.section__head .lead { max-width: 58ch; }

.grid-2 { display: grid; gap: clamp(2.5rem, 5vw, 4.5rem); align-items: center; }

/* Mini-KPI z animowanym licznikiem */
.minikpi {
  display: flex;
  flex-wrap: wrap;
  gap: 2.25rem;
  padding-top: 1.35rem;
  border-top: 1px solid var(--line-dark);
  width: 100%;
}
.minikpi div { display: flex; flex-direction: column; }
.minikpi b {
  font-family: var(--font-display);
  font-size: 2.6rem;
  font-weight: 700;
  line-height: 1;
  color: #fff;
  font-variant-numeric: tabular-nums;
}
.minikpi span {
  font-size: .84rem;
  color: var(--tx-on-dark-mute);
  letter-spacing: .02em;
  margin-top: .3rem;
}

/* ── 10. FILARY ──────────────────────────────────────────────────────────── */
.pillars {
  display: grid;
  gap: clamp(1.5rem, 2.6vw, 2.25rem);
  margin-bottom: clamp(2.25rem, 4vw, 3.5rem);
}

/* Karta filaru: subtelny gradient zamiast płaskiej bieli i cień budowany
   warstwowo (blisko + daleko), dzięki czemu unosi się nad tłem zamiast
   leżeć na nim płasko. */
.pillar {
  position: relative;
  background: linear-gradient(170deg, #fff 0%, #fbfbfd 100%);
  border: 1px solid var(--line-light);
  border-radius: var(--r-lg);
  padding: clamp(1.75rem, 3vw, 2.75rem);
  box-shadow:
    0 1px 2px rgba(11, 12, 15, .05),
    0 8px 18px -10px rgba(11, 12, 15, .12),
    0 24px 48px -28px rgba(11, 12, 15, .18);
  transition: transform var(--t-slow), box-shadow var(--t-slow), border-color var(--t);
  overflow: hidden;
}
.pillar::before {
  content: '';
  position: absolute;
  inset: 0 0 auto 0;
  height: 3px;
  background: linear-gradient(90deg, var(--red), var(--red-700));
  transform: scaleX(0);
  transform-origin: left;
  transition: transform .55s var(--ease-out);
}
.pillar:hover {
  transform: translateY(-8px);
  box-shadow:
    0 1px 2px rgba(11, 12, 15, .06),
    0 18px 34px -14px rgba(11, 12, 15, .18),
    0 44px 72px -36px rgba(227, 6, 19, .3);
  border-color: rgba(227, 6, 19, .32);
}
.pillar:hover::before { transform: scaleX(1); }

/* ── Światło pod kursorem ──────────────────────────────────────────────────
   Współrzędne --mx/--my podaje JS. Sam gradient nie rusza `transform`,
   więc nie kłóci się z uniesieniem karty ani z animacją wejścia. */
.pillar, .card, .step { --mx: 50%; --my: 0%; }
.pillar::after, .card::after, .step::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: radial-gradient(420px circle at var(--mx) var(--my),
              rgba(227, 6, 19, .13), transparent 62%);
  opacity: 0;
  transition: opacity .45s var(--ease-out);
  pointer-events: none;
  z-index: 0;
}
.pillar:hover::after, .card:hover::after, .step:hover::after { opacity: 1; }
/* Treść kart musi zostać nad poświatą */
.pillar > *, .card > *, .step > * { position: relative; z-index: 1; }
.card, .step { position: relative; }

/* Numer wyraźnie czerwony, nie ledwie widoczna szarość — nadaje kartom rytm
   i od razu komunikuje, że filary są trzy. */
.pillar__num {
  position: absolute;
  top: clamp(1.1rem, 2vw, 1.6rem);
  right: clamp(1.25rem, 2.5vw, 2rem);
  font-family: var(--font-display);
  font-size: clamp(2.6rem, 4.5vw, 3.6rem);
  font-weight: 700;
  line-height: 1;
  color: var(--red);
  opacity: .16;
  letter-spacing: -.04em;
  transition: opacity var(--t);
}
.pillar:hover .pillar__num { opacity: .32; }

.pillar__icon {
  display: grid;
  place-items: center;
  width: 3.25rem; height: 3.25rem;
  border-radius: var(--r-sm);
  background: var(--red);
  color: #fff;
  margin-bottom: 1.4rem;
  box-shadow: 0 10px 24px -10px var(--red-glow);
}
.pillar__icon svg { width: 1.65rem; height: 1.65rem; stroke-width: 1.7; }

.pillar__title {
  font-size: clamp(1.35rem, 2.2vw, 1.85rem);
  margin-bottom: .85rem;
  color: var(--tx-on-light);
}
.pillar__desc {
  color: var(--tx-on-light-mute);
  margin-bottom: 1.5rem;
  max-width: 46ch;
}

/* Wyróżnik jako ciemny panel na jasnej karcie — mocny kontrast przyciąga
   wzrok dokładnie tam, gdzie jest sedno oferty. Wartość i opis JEDEN POD
   DRUGIM: przy układzie obok siebie opis łamał się w wąską kolumnę
   i cały blok wyglądał na zepsuty. */
.pillar__figure {
  display: block;
  padding: 1.15rem 1.3rem;
  margin-bottom: 1.6rem;
  background: linear-gradient(150deg, var(--ink-4) 0%, var(--ink) 100%);
  border-radius: var(--r-sm);
  border-left: 3px solid var(--red);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .07),
    0 10px 24px -14px rgba(0, 0, 0, .5);
}
.pillar__figure b {
  display: block;
  font-family: var(--font-display);
  font-size: clamp(1.9rem, 3.4vw, 2.5rem);
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: -.01em;
  color: #fff;
  margin-bottom: .45rem;
}
.pillar__figure span {
  display: block;
  font-size: .86rem;
  line-height: 1.55;
  color: var(--tx-on-dark-mute);
}
.pillar__figure em {
  display: block;
  margin-top: .3rem;
  font-style: normal;
  font-weight: 600;
  color: #fff;
}

/* Blok „mówimy wprost” — świadome pozycjonowanie oferty */
.honest {
  display: grid;
  gap: 1.5rem;
  align-items: start;
  background: var(--ink);
  color: #fff;
  border-radius: var(--r-lg);
  padding: clamp(1.75rem, 3.4vw, 3rem);
  position: relative;
  overflow: hidden;
  box-shadow: var(--sh-2);
}
.honest::after {
  content: '';
  position: absolute;
  right: -14%; top: -55%;
  width: 46%; aspect-ratio: 1;
  background: radial-gradient(circle, rgba(227, 6, 19, .3), transparent 62%);
  pointer-events: none;
}
.honest__label {
  align-self: start;
  display: inline-block;
  font-family: var(--font-display);
  font-size: .78rem;
  font-weight: 600;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--red);
  border: 1px solid rgba(227, 6, 19, .45);
  border-radius: 99px;
  padding: .42rem 1rem;
  white-space: nowrap;
}
.honest__title { font-size: clamp(1.3rem, 2.2vw, 1.7rem); margin-bottom: .9rem; }
.honest p { color: var(--tx-on-dark-mute); max-width: 68ch; }
.honest p + p { margin-top: .9rem; }
.honest strong { color: #fff; }
.honest__kicker {
  font-size: clamp(1.02rem, 1.4vw, 1.18rem);
  font-weight: 600;
  color: #fff !important;
  padding-left: 1.1rem;
  border-left: 2px solid var(--red);
}

/* ── 11. KARTY / OCZEKIWANIA ─────────────────────────────────────────────── */
.cards {
  display: grid;
  gap: clamp(1.15rem, 2.2vw, 1.75rem);
  margin-bottom: clamp(2.5rem, 4.5vw, 4rem);
}
.card {
  background: linear-gradient(165deg, var(--ink-3), var(--ink-2));
  border: 1px solid var(--line-dark);
  border-radius: var(--r);
  padding: clamp(1.5rem, 2.6vw, 2.1rem);
  transition: transform var(--t-slow), border-color var(--t), background-color var(--t);
}
.card:hover { transform: translateY(-5px); border-color: rgba(227, 6, 19, .38); }
/* Kafelki profilu partnera — wyśrodkowane w pionie i poziomie.
   Wyrównanie do lewej zostawiało nierówne, poszarpane bloki tekstu
   o różnej liczbie linii. */
.card { text-align: center; display: flex; flex-direction: column; align-items: center; }
.card p { max-width: 34ch; }

.card__icon {
  display: grid;
  place-items: center;
  width: 2.9rem; height: 2.9rem;
  border-radius: var(--r-sm);
  background: rgba(255, 255, 255, .05);
  color: var(--red);
  margin-bottom: 1.2rem;
  transition: background-color var(--t);
}
.card:hover .card__icon { background: var(--red-soft); }
.card__icon svg { width: 1.5rem; height: 1.5rem; }
.card__title { font-size: 1.16rem; margin-bottom: .6rem; }
.card p { color: var(--tx-on-dark-mute); font-size: .96rem; }

.expect {
  border: 1px solid var(--line-dark);
  border-radius: var(--r-lg);
  padding: clamp(1.6rem, 3vw, 2.5rem);
  background: rgba(255, 255, 255, .018);
}
.expect__title {
  font-size: 1.16rem;
  margin-bottom: 1.4rem;
  padding-bottom: 1rem;
  border-bottom: 1px solid var(--line-dark);
}
.expect__list { display: grid; gap: 1rem; }
.expect__list li {
  display: flex;
  gap: 1rem;
  align-items: baseline;
  color: var(--tx-on-dark-mute);
  font-size: .97rem;
}
.expect__list span {
  font-family: var(--font-display);
  font-size: .95rem;
  font-weight: 700;
  color: var(--red);
  letter-spacing: .06em;
  flex: none;
}

/* ── 12. LINIA PRODUKTOWA ─────────────────────────────────────────────────
   Sekcja-popisówka. Dwa tryby, sterowane z JS:

     MOBILE / reduced-motion  → zwykły stos kart; karty wjeżdżają naprzemiennie
                                z boków przez IntersectionObserver.
     DESKTOP (≥901 px)        → przyklejona scena; pozycja każdego produktu jest
                                czystą funkcją postępu przewijania sekcji.

   Stan początkowy animacji włącza dopiero klasa .is-armed dodawana z JS —
   bez JavaScriptu wszystko jest po prostu widoczne, bez żadnych sztuczek.
   ───────────────────────────────────────────────────────────────────────── */
/* UWAGA: żaden przodek .lineup__stage nie może mieć overflow innego niż
   visible — inaczej position: sticky przestaje działać. Przycinanie
   wyjeżdżających produktów robi sam .lineup__stage (to element przyklejony,
   więc własny overflow mu nie przeszkadza). */
.lineup {
  background: var(--ink);
  position: relative;
}

.lineup__stage { padding-block: var(--section-y); position: relative; }

.lineup__bg { display: none; }

.lineup__head {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 1rem;
  margin-bottom: clamp(2.5rem, 5vw, 4rem);
}
.lineup__title {
  font-size: clamp(2rem, 5.5vw, 3.6rem);
  letter-spacing: .006em;
  line-height: 1.02;
}
.lineup__sub { color: var(--tx-on-dark-mute); max-width: 46ch; }

.lineup__items { display: grid; gap: clamp(2.5rem, 5vw, 4rem); }

.lineup__item {
  position: relative;
  display: grid;
  gap: 1.5rem;
  align-items: center;
  padding-inline: var(--gutter);
  max-width: var(--container);
  margin-inline: auto;
  width: 100%;
}

/* Wjazd z boku — uzbrajany z JS, wyzwalany obserwatorem */
.lineup__items.is-armed .lineup__item {
  opacity: 0;
  transform: translate3d(var(--from, 12%), 0, 0) scale(.96);
  transition: opacity .9s var(--ease-out), transform 1.05s var(--ease-out);
}
.lineup__item[data-side="left"] { --from: -12%; }
.lineup__items.is-armed .lineup__item.is-in { opacity: 1; transform: none; }

.lineup__num {
  position: absolute;
  left: var(--gutter);
  top: -.35em;
  font-family: var(--font-display);
  font-size: clamp(5rem, 17vw, 9rem);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -.05em;
  color: rgba(255, 255, 255, .045);
  pointer-events: none;
  z-index: 0;
}

.lineup__shot {
  margin: 0;
  display: grid;
  place-items: center;
  position: relative;
  z-index: 1;
}
.lineup__shot picture { display: contents; }
.lineup__shot img {
  width: 100%;
  height: auto;
  max-height: 46vh;
  max-height: 46svh;
  object-fit: contain;
  /* Rendery mają kanał alfa — cień idzie za sylwetką produktu,
     a czerwona poświata osadza go na ciemnym tle sceny. */
  filter:
    drop-shadow(0 26px 34px rgba(0, 0, 0, .85))
    drop-shadow(0 0 70px rgba(227, 6, 19, .16));
}

.lineup__info { display: flex; flex-direction: column; align-items: flex-start; gap: .9rem; position: relative; z-index: 1; }
.lineup__cat {
  font-family: var(--font-display);
  font-size: .78rem;
  font-weight: 600;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--red);
  padding: .35rem .85rem;
  border: 1px solid rgba(227, 6, 19, .4);
  border-radius: 99px;
}
.lineup__name { font-size: clamp(1.4rem, 2.8vw, 2.15rem); letter-spacing: .012em; }
.lineup__desc { color: var(--tx-on-dark-mute); max-width: 52ch; }
.lineup__note {
  font-size: .84rem;
  font-weight: 700;
  letter-spacing: .04em;
  color: #fff;
  padding-left: .9rem;
  border-left: 2px solid var(--red);
}

.lineup__rail, .lineup__hint { display: none; }

/* ── Wyciąg z karty katalogowej ────────────────────────────────────────────
   Siatka 2×2 par etykieta/wartość. Grupa docelowa czyta parametry przed
   opisem, więc mają wyglądać jak fragment karty technicznej, a nie jak
   ozdobne tagi. */
.specs {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1px;
  width: 100%;
  max-width: 31rem;
  background: var(--line-dark);
  border: 1px solid var(--line-dark);
  border-radius: var(--r-sm);
  overflow: hidden;
}
.specs__row { background: rgba(255, 255, 255, .022); padding: .58rem .85rem; }
.specs dt {
  font-size: .66rem;
  font-weight: 600;
  letter-spacing: .11em;
  text-transform: uppercase;
  color: var(--tx-on-dark-mute);
  margin-bottom: .2rem;
}
.specs dd {
  margin: 0;
  font-family: var(--font-display);
  font-size: 1.05rem;
  font-weight: 600;
  line-height: 1.2;
  color: #fff;
  font-variant-numeric: tabular-nums;
}

/* ── 13. PROCES ──────────────────────────────────────────────────────────── */
.steps {
  display: grid;
  gap: clamp(1.5rem, 3vw, 2rem);
  counter-reset: step;
  position: relative;
}
.step {
  position: relative;
  z-index: 1;                    /* nad kropkowanym łącznikiem (.steps::before) */
  padding: clamp(1.6rem, 2.8vw, 2.25rem);
  /* Kroki wyśrodkowane — numer, tytuł i czas tworzą wtedy jedną oś */
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  /* Tło nieprzezroczyste — łącznik ma być widoczny tylko w przerwach
     między kartami, nie pod nimi. */
  background: linear-gradient(170deg, #181b22, #121419);
  border: 1px solid var(--line-dark);
  border-radius: var(--r);
  transition: border-color var(--t), transform var(--t-slow);
}
.step:hover { border-color: rgba(227, 6, 19, .4); transform: translateY(-4px); }
.step__no {
  font-family: var(--font-display);
  display: block;
  font-size: 2.6rem;
  font-weight: 700;
  line-height: 1;
  color: var(--red);
  letter-spacing: -.03em;
  margin-bottom: .9rem;
}
.step__title { font-size: 1.22rem; margin-bottom: .55rem; }
.step p { color: var(--tx-on-dark-mute); font-size: .97rem; max-width: 36ch; }
.step__meta {
  display: inline-block;
  margin-top: 1.1rem;
  font-size: .74rem;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--red);
  padding: .34rem .7rem;
  border: 1px solid rgba(227, 6, 19, .32);
  border-radius: 99px;
}

/* ── 14. PASEK CTA ───────────────────────────────────────────────────────── */
.ctaband {
  background: linear-gradient(105deg, var(--red-700), var(--red) 55%, #ff1e30);
  padding-block: clamp(2.75rem, 5vw, 4.25rem);
  position: relative;
  overflow: hidden;
}
.ctaband::before {
  content: '';
  position: absolute;
  inset: 0;
  background-image: linear-gradient(115deg, rgba(0, 0, 0, .22) 0 42%, transparent 42.4%);
  pointer-events: none;
}
.ctaband__inner {
  position: relative;
  display: grid;
  gap: 1.75rem;
  align-items: center;
}
.ctaband__title {
  font-size: clamp(1.4rem, 2.9vw, 2.3rem);
  color: #fff;
  max-width: 30ch;
}
.ctaband__sub { color: rgba(255, 255, 255, .88); margin-top: .55rem; }
.ctaband__actions { display: flex; flex-wrap: wrap; align-items: center; gap: 1rem; }

/* ── 15. FAQ ─────────────────────────────────────────────────────────────── */
.faq { display: grid; gap: .75rem; }
.faq__item {
  background: var(--paper-2);
  border: 1px solid var(--line-light);
  border-radius: var(--r);
  overflow: hidden;
  transition: border-color var(--t), box-shadow var(--t);
}
.faq__item[open] { border-color: rgba(227, 6, 19, .35); box-shadow: var(--sh-1); }
.faq__q {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.25rem;
  padding: 1.15rem clamp(1.1rem, 2.4vw, 1.6rem);
  font-weight: 650;
  font-size: clamp(1rem, 1.2vw, 1.08rem);
  color: var(--tx-on-light);
  cursor: pointer;
  list-style: none;
  transition: color var(--t-fast);
}
.faq__q::-webkit-details-marker { display: none; }
.faq__q:hover { color: var(--red); }

.faq__sign { position: relative; width: 16px; height: 16px; flex: none; }
.faq__sign::before, .faq__sign::after {
  content: '';
  position: absolute;
  inset: 50% 0 auto 0;
  height: 2px;
  background: var(--red);
  border-radius: 2px;
  transition: transform var(--t);
}
.faq__sign::after { transform: rotate(90deg); }
.faq__item[open] .faq__sign::after { transform: rotate(0); }

.faq__a { padding: 0 clamp(1.1rem, 2.4vw, 1.6rem) 1.3rem; }
.faq__a p {
  color: var(--tx-on-light-mute);
  font-size: .99rem;
  border-left: 2px solid var(--paper-3);
  padding-left: 1.1rem;
  max-width: 72ch;
}
.faq__item[open] .faq__a { animation: faqIn .42s var(--ease-out); }
@keyframes faqIn {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: none; }
}

/* ── 16. FORMULARZ ───────────────────────────────────────────────────────── */
.section--form {
  background:
    radial-gradient(90% 70% at 88% 8%, rgba(227, 6, 19, .13), transparent 62%),
    linear-gradient(180deg, var(--ink-2), var(--ink));
  border-top: 1px solid var(--line-dark);
}
.grid-form { display: grid; gap: clamp(2.5rem, 5vw, 4.5rem); align-items: start; }
.formside { display: flex; flex-direction: column; align-items: flex-start; gap: 1.35rem; }

.contactbox {
  display: grid;
  gap: 1px;
  width: 100%;
  background: var(--line-dark);
  border: 1px solid var(--line-dark);
  border-radius: var(--r);
  overflow: hidden;
  margin-top: .5rem;
}
.contactbox__row {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 1.05rem 1.25rem;
  background: rgba(255, 255, 255, .022);
  transition: background-color var(--t);
}
.contactbox__row:hover { background: rgba(227, 6, 19, .1); }
.contactbox__row svg { color: var(--red); width: 1.35rem; height: 1.35rem; }
.contactbox__row b { display: block; font-size: 1.02rem; font-weight: 650; }
.contactbox__row em { font-style: normal; font-size: .8rem; color: var(--tx-on-dark-mute); }

/* ═══════════════════════════════════════════════════════════════════════════
   15b. PASEK DOMEN I TECHNOLOGII (sekcja o marce)
   ═══════════════════════════════════════════════════════════════════════════
   Język wizualny: karta katalogowa, nie strona reklamowa. Cienkie linie
   miarowe, narożne celowniki, wersaliki z szeroką światłością i cyfry
   tabelaryczne. Marka sprzedaje austriacką precyzję, więc sekcja techniczna
   ma wyglądać jak rysunek warsztatowy, a nie jak baner.

   Uwaga: ŻADNEGO trzeciego kroju pisma. Techniczny charakter robią wersaliki,
   światło międzyliterowe i `tabular-nums` na Satoshi — nie font monospace.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Ziarno na ciemnych sekcjach. Jednolita czerń wygląda na ekranie płasko;
   delikatny szum daje wrażenie materiału. `::before` jest już zajęty przez
   gradient styku sekcji, więc szum idzie na `::after`. */
.section--dark::after,
.section--form::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  opacity: .035;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E");
}

.bandhead {
  margin-top: clamp(3rem, 6vw, 5rem);
  padding-top: clamp(1.6rem, 3vw, 2.4rem);
  border-top: 1px solid var(--line-dark);
}
.bandhead .eyebrow { margin-bottom: .85rem; }
.bandhead .lead { margin-top: 1rem; }
.h3--band {
  font-size: clamp(1.45rem, 2.4vw, 2.05rem);
  line-height: 1.18;
  letter-spacing: -.005em;
}

/* ── Trzy domeny asortymentu ───────────────────────────────────────────── */
.domains {
  display: grid;
  gap: 1px;
  margin: clamp(1.6rem, 3vw, 2.4rem) 0 0;
  padding: 0;
  list-style: none;
  background: var(--line-dark);
  border: 1px solid var(--line-dark);
  border-radius: var(--r);
  overflow: hidden;
}
.domain {
  position: relative;
  padding: clamp(1.3rem, 2.4vw, 1.9rem);
  background: rgba(255, 255, 255, .022);
  transition: background-color .45s var(--ease-out);
}
.domain:hover { background: rgba(255, 255, 255, .045); }
.domain__ix {
  display: block;
  margin-bottom: .8rem;
  font-family: var(--font-body);
  font-size: .74rem;
  font-weight: 700;
  letter-spacing: .16em;
  color: var(--red);
  font-variant-numeric: tabular-nums;
}
.domain__title {
  font-size: clamp(1.08rem, 1.5vw, 1.24rem);
  line-height: 1.25;
  margin-bottom: .6rem;
}
.domain__desc {
  font-size: .93rem;
  line-height: 1.62;
  color: var(--tx-on-dark-mute);
  margin-bottom: .9rem;
}
/* Wiersz miarowy — krótka kreska plus parametr wersalikami. */
.domain__meta {
  display: flex;
  align-items: center;
  gap: .55rem;
  font-family: var(--font-body);
  font-size: .72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .11em;
  color: var(--tx-on-dark);
}
.domain__meta::before {
  content: '';
  flex: none;
  width: 1.4rem;
  height: 1px;
  background: var(--red);
}

/* ── Karty technologii ─────────────────────────────────────────────────── */
.techgrid {
  display: grid;
  gap: clamp(1rem, 2vw, 1.4rem);
  margin-top: clamp(1.6rem, 3vw, 2.4rem);
}
.tech {
  position: relative;
  padding: clamp(1.4rem, 2.6vw, 2.1rem);
  background: linear-gradient(165deg, rgba(255, 255, 255, .05), rgba(255, 255, 255, .015));
  border: 1px solid var(--line-dark);
  border-radius: var(--r);
  overflow: hidden;
  transition: border-color .5s var(--ease-out), transform .6s var(--ease-out);
}
.tech:hover { border-color: rgba(227, 6, 19, .45); }
/* Narożny celownik — ten sam motyw co ramka zdjęcia w tej sekcji,
   dzięki temu blok techniczny czyta się jako część tej samej rodziny. */
.tech__corner {
  position: absolute;
  top: -1px; right: -1px;
  width: 2.6rem; height: 2.6rem;
  border-top: 1px solid rgba(227, 6, 19, .55);
  border-right: 1px solid rgba(227, 6, 19, .55);
  border-radius: 0 var(--r) 0 0;
  pointer-events: none;
}
.tech__kicker {
  font-family: var(--font-body);
  font-size: .7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .15em;
  color: var(--tx-on-dark-mute);
  margin-bottom: .55rem;
}
.tech__name {
  font-size: clamp(1.15rem, 1.7vw, 1.38rem);
  line-height: 1.2;
  margin-bottom: 1.1rem;
}
.tech__name sup { font-size: .5em; vertical-align: super; margin-left: .1em; color: var(--red); }

/* Wielka liczba — jedyne miejsce poza nagłówkami, gdzie wolno użyć Clash
   Display. Wartości są STATYCZNE (patrz komentarz w index.php): ten krój
   nie ma cyfr tabelarycznych, więc każde odliczanie przesuwałoby jednostkę. */
.tech__figure {
  display: flex;
  align-items: baseline;
  gap: .22rem;
  margin-bottom: .3rem;
  line-height: 1;
}
.tech__figure b {
  font-family: var(--font-display);
  font-size: clamp(2.8rem, 5.2vw, 3.9rem);
  font-weight: 600;
  letter-spacing: -.02em;
  color: #fff;
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
}
.tech__figure i {
  font-style: normal;
  font-family: var(--font-display);
  font-size: clamp(1.2rem, 2vw, 1.6rem);
  font-weight: 500;
  color: var(--red);
}
.tech__label {
  font-family: var(--font-body);
  font-size: .74rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .13em;
  color: var(--tx-on-dark-mute);
  padding-bottom: 1.15rem;
  margin-bottom: 1.15rem;
  border-bottom: 1px solid var(--line-dark);
}
.tech__desc {
  font-size: .93rem;
  line-height: 1.65;
  color: var(--tx-on-dark-mute);
  margin-bottom: 1rem;
}
.tech__facts { list-style: none; display: grid; gap: .5rem; }
.tech__facts li {
  display: flex;
  gap: .6rem;
  font-size: .855rem;
  line-height: 1.5;
  color: var(--tx-on-dark);
}
/* Kreska miarowa zamiast kropki — trzyma techniczny charakter sekcji. */
.tech__facts li::before {
  content: '';
  flex: none;
  width: .7rem;
  height: 1px;
  margin-top: .62rem;
  background: var(--red);
}

.technote {
  margin-top: 1.35rem;
  font-size: .78rem;
  line-height: 1.6;
  color: var(--tx-on-dark-mute);
  opacity: .8;
}

/* Delikatna głębia sterowana przewijaniem — bez JS, natywną osią czasu.
   Wyłącznie ozdoba: stan bazowy jest w pełni widoczny, więc brak wsparcia
   nie ukrywa ani jednego słowa. Ta sama zasada co przy sekcji Bestsellerów. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) and (min-width: 901px) {
    @keyframes rpGlebia {
      from { transform: translate3d(0, 22px, 0); }
      to   { transform: translate3d(0, -14px, 0); }
    }
    .tech__figure {
      animation: rpGlebia linear both;
      animation-timeline: view();
      animation-range: entry 8% exit 92%;
    }
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
   KARTA FORMULARZA
   ═══════════════════════════════════════════════════════════════════════════
   Biała plama na ciemnym tle — maksymalny kontrast dla jedynego CTA, które
   naprawdę się liczy. Karta ma sprawiać wrażenie dokumentu, nie widgetu:
   numerowane grupy pól, wskaźnik uzupełnienia, stopka z sygnałami zaufania.
   ═══════════════════════════════════════════════════════════════════════════ */
.formcard {
  background: var(--paper-2);
  color: var(--tx-on-light);
  border-radius: var(--r-lg);
  padding: clamp(1.5rem, 3.2vw, 2.75rem);
  box-shadow: var(--sh-3);
  position: relative;
  isolation: isolate;
  overflow: hidden;
  /* Plama światła podąża za kursorem — zmienne ustawia pointerGlow. */
  --mx: 50%;
  --my: 0%;
}
/* Warstwa światła pod treścią. `inset: 0` plus `overflow: hidden` na karcie
   przycinają plamę do zaokrąglonych narożników. */
.formcard > form,
.formcard > .success { position: relative; z-index: 1; }
.formcard__glow {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: radial-gradient(38rem 22rem at var(--mx) var(--my), rgba(227, 6, 19, .06), transparent 70%);
  opacity: 0;
  transition: opacity .5s var(--ease-out);
}
.formcard:hover .formcard__glow { opacity: 1; }
.formcard::before {
  content: '';
  position: absolute;
  inset: 0 0 auto 0;
  height: 4px;
  background: linear-gradient(90deg, var(--red), var(--red-700), var(--red));
  background-size: 200% 100%;
  border-radius: var(--r-lg) var(--r-lg) 0 0;
  transition: background-position 1.4s var(--ease-out);
}
.formcard:focus-within::before { background-position: 100% 0; }

/* Świetlny pierścień wokół karty, gdy użytkownik w niej pracuje.
   Rysowany maską wykrawającą środek — bez maski pełny prostokąt zasłoniłby
   treść, więc całość zamknięta w @supports. Kąt animuje @property; tam,
   gdzie go nie ma, pierścień zostaje nieruchomym gradientem. */
@property --rp-kat {
  syntax: '<angle>';
  inherits: false;
  initial-value: 0deg;
}
@supports ((mask-composite: exclude) or (-webkit-mask-composite: xor)) {
  .formcard::after {
    content: '';
    position: absolute;
    /* Wewnątrz krawędzi, bo karta ma `overflow: hidden` dla plamy światła —
       pierścień wypuszczony na zewnątrz zostałby przycięty. */
    inset: 0;
    border-radius: var(--r-lg);
    padding: 1.5px;
    background: conic-gradient(from var(--rp-kat),
      transparent 0deg, rgba(227, 6, 19, .0) 30deg,
      var(--red) 72deg, #ff7a63 96deg, var(--red) 120deg,
      rgba(227, 6, 19, 0) 165deg, transparent 360deg);
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
    mask: linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
    opacity: 0;
    pointer-events: none;
    transition: opacity .5s var(--ease-out);
  }
  .formcard:focus-within::after {
    opacity: 1;
    animation: rpObrotKata 5s linear infinite;
  }
}
@keyframes rpObrotKata { to { --rp-kat: 360deg; } }

/* Nagłówek karty: tytuł po lewej, wskaźnik uzupełnienia po prawej. */
.formcard__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1.2rem;
  margin-bottom: 1.15rem;
  padding-bottom: 1.1rem;
  border-bottom: 1px solid var(--paper-3);
}
.formcard__headtx { min-width: 0; }
.formcard__head h3 { font-size: 1.45rem; margin-bottom: .3rem; }
.formcard__head p { font-size: .88rem; color: var(--tx-on-light-mute); }
.formcard__note {
  font-size: .82rem;
  color: var(--tx-on-light-mute);
  text-align: center;
  margin-top: 1rem;
  line-height: 1.55;
}

/* Wskaźnik uzupełnienia — obwód SVG plus licznik. Kolor przechodzi
   z neutralnego w zielony dopiero po skompletowaniu, więc „zielono”
   znaczy naprawdę „gotowe”, a nie „coś tam wpisano”. */
.gauge {
  flex: none;
  position: relative;
  width: 3rem; height: 3rem;
}
.gauge svg { width: 100%; height: 100%; transform: rotate(-90deg); }
.gauge circle { fill: none; stroke-width: 3; }
.gauge__track { stroke: var(--paper-3); }
.gauge__fill {
  stroke: var(--red);
  stroke-linecap: round;
  /* obwód = 2πr, r = 19 */
  stroke-dasharray: 119.38;
  stroke-dashoffset: calc(119.38 - 119.38 * var(--gp, 0));
  transition: stroke-dashoffset .6s var(--ease-out), stroke .45s var(--ease-out);
}
.gauge.is-full .gauge__fill { stroke: #1d9c56; }
.gauge__num {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  font-size: .82rem;
  font-weight: 700;
  color: var(--tx-on-light);
  letter-spacing: 0;
}
.gauge__num i { font-style: normal; font-weight: 500; color: #9aa1ad; font-size: .68rem; }

/* Pasek stanu nad polami — jedno zdanie, które mówi, ile zostało. */
.formcard__state {
  display: flex;
  align-items: center;
  gap: .45rem;
  margin-bottom: 1.5rem;
  font-size: .8rem;
  font-weight: 600;
  color: var(--tx-on-light-mute);
  letter-spacing: .01em;
}
.formcard__state b { color: var(--tx-on-light); }
.formcard__state.is-ready { color: #14663a; }
.formcard__state.is-ready b { color: #14663a; }

.req { color: var(--red); font-weight: 700; }

/* ── Grupy pól ─────────────────────────────────────────────────────────────
   Formularz zostaje JEDNOEKRANOWY — rozbicie siedmiu pól na kroki zmusiłoby
   do klikania „dalej” i ukryło, o co w sumie prosimy. Numerowane grupy dają
   ten sam porządek bez odbierania podglądu całości. */
.fgroup { margin-bottom: 1.7rem; }
.fgroup:last-of-type { margin-bottom: 1.2rem; }
.fgroup__head {
  display: flex;
  align-items: center;
  gap: .6rem;
  margin-bottom: 1.15rem;
  font-family: var(--font-body);
  font-size: .74rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .13em;
  color: var(--tx-on-light-mute);
}
.fgroup__num {
  display: grid;
  place-items: center;
  flex: none;
  width: 1.6rem; height: 1.6rem;
  border-radius: 50%;
  background: var(--red);
  color: #fff;
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: 0;
  box-shadow: 0 4px 12px -4px rgba(227, 6, 19, .55);
}

.field { position: relative; margin-bottom: 1.15rem; }

/* Wiersz dwóch pól: odstęp daje grid, nie marginesy dzieci —
   inaczej przy układzie dwukolumnowym rytm pionowy się rozjeżdża. */
.field-row { display: grid; gap: 1.15rem; margin-bottom: 1.15rem; }
.field-row .field { margin-bottom: 0; }

/* `:not([type=checkbox]):not([type=radio])` jest KONIECZNE. Bez tego reguła
   trafiała też w ukryte radia kafli i w checkbox zgody: dostawały 24 px
   wypełnienia górnego, przez co ich pudełko rosło do 35×34 px. Były
   niewidoczne (opacity: 0), ale nadal łapały kliknięcia — nad legendą
   zestawu kafli powstawał niewidzialny przechwytywacz zdarzeń. */
.field input:not([type="checkbox"]):not([type="radio"]),
.field textarea,
.field select {
  width: 100%;
  padding: 1.5rem 1.05rem .62rem;
  background: #f6f7f9;
  border: 1px solid #e4e7ec;
  border-bottom: 2px solid #d3d8e0;
  border-radius: var(--r-sm) var(--r-sm) 4px 4px;
  font-family: var(--font-body);
  font-size: 1rem;
  color: var(--tx-on-light);
  transition:
    border-color .28s var(--ease-out),
    box-shadow .28s var(--ease-out),
    background-color .28s var(--ease-out);
  -webkit-appearance: none;
  appearance: none;
}
.field textarea { resize: vertical; min-height: 132px; line-height: 1.6; padding-top: 1.65rem; }
.field input::placeholder, .field textarea::placeholder { color: transparent; }

.field input:hover, .field textarea:hover, .field select:hover {
  background: #f1f3f6;
  border-bottom-color: #b9c0cc;
}
/* Aktywne pole rozjaśnia się i dostaje czerwoną podstawę — użytkownik od razu
   wie, gdzie jest, bez agresywnej obwódki dookoła całego pola.
   Bez `transform`: unoszenie pola ciągnęło za sobą unoszącą się etykietę
   i przy szybkim przechodzeniu tabulatorem całość drgała. */
.field input:focus, .field textarea:focus, .field select:focus {
  outline: none;
  background: #fff;
  border-color: #dfe3ea;
  border-bottom-color: var(--red);
  box-shadow: 0 10px 26px -16px rgba(11, 12, 15, .45), 0 0 0 3px var(--red-soft);
}

/* ── Etykieta unosząca się ─────────────────────────────────────────────────
   Etykieta startuje w miejscu podpowiedzi i wyjeżdża nad wpisywany tekst.
   `placeholder=" "` (spacja) jest konieczny: bez niego `:placeholder-shown`
   nigdy nie zadziała, bo pole bez atrybutu nie ma podpowiedzi.
   Etykieta zostaje CZYTELNA po uniesieniu — nie zmniejszamy jej poniżej
   11 px i nie rozjaśniamy poniżej kontrastu 4.5:1. */
/* `top` i przesunięcie po uniesieniu są WYMIERZONE, nie zgadnięte: w pozycji
   spoczynkowej środek etykiety musi pokryć się ze środkiem wpisywanego tekstu
   (pole ma 61 px, tekst środkuje się na 38 px), a po uniesieniu etykieta ma
   zmieścić się w 24 px górnego wypełnienia, nie wchodząc na tekst.
   Wartości są liczone od góry `.field`, nie od środka — przy błędzie pole
   rośnie w dół i `top: 50%` zaczęłoby dryfować. */
.field--float > label {
  position: absolute;
  left: 1.08rem;
  top: 1.9rem;
  font-family: var(--font-body);
  font-size: 1rem;
  font-weight: 500;
  line-height: 1;
  color: #8d94a1;
  letter-spacing: .005em;
  pointer-events: none;
  transform-origin: 0 0;
  transition: transform .22s var(--ease-out), color .22s var(--ease-out);
  will-change: transform;
}
.field--float > label em {
  font-style: normal;
  font-size: .78em;
  color: #a8aeb9;
  letter-spacing: .02em;
}
.field--float > input:focus + label,
.field--float > input:not(:placeholder-shown) + label,
.field--float > textarea:focus + label,
.field--float > textarea:not(:placeholder-shown) + label,
.field--select > label {
  transform: translateY(-1.42rem) scale(.72);
  color: var(--tx-on-light-mute);
}
.field--float > input:focus + label,
.field--float > textarea:focus + label { color: var(--red-600); }

/* Lista rozwijana ma etykietę uniesioną ZAWSZE — pusta pozycja „wybierz”
   zajmuje miejsce podpowiedzi, więc nie ma czego odsłaniać. */
.field--select select { padding-top: 1.5rem; }

/* Ptaszek poprawności — pojawia się po opuszczeniu pola z sensowną
   wartością. Sprawdzanie na `blur`, nie przy każdym znaku: podświetlanie
   niedokończonego adresu na czerwono to najczęstszy grzech formularzy. */
.field__mark {
  position: absolute;
  right: .95rem;
  top: 1.33rem;                       /* oś pola o wysokości 61 px */
  width: 1.15rem; height: 1.15rem;
  border-radius: 50%;
  background: #1d9c56;
  opacity: 0;
  transform: scale(.4);
  transition: opacity .2s var(--ease-out), transform .28s var(--ease-out);
  pointer-events: none;
}
.field__mark::after {
  content: '';
  position: absolute;
  left: .33rem; top: .21rem;
  width: .28rem; height: .5rem;
  border-right: 2px solid #fff;
  border-bottom: 2px solid #fff;
  transform: rotate(40deg);
}
.field.is-valid .field__mark { opacity: 1; transform: scale(1); }
.field.is-valid input { padding-right: 2.6rem; }

/* Mikrotekst „po co nam to” — stale widoczny, ale wyciszony. Zajmuje ten sam
   wiersz co komunikat błędu, więc pojawienie się błędu nic nie przesuwa. */
.field__hint,
.field__err {
  display: block;
  margin-top: .4rem;
  font-size: .765rem;
  line-height: 1.45;
  letter-spacing: .005em;
}
.field__hint { color: #8d94a1; font-weight: 500; }
.field__err  { display: none; color: var(--red); font-weight: 650; }
.field.has-error .field__err  { display: block; }
.field.has-error .field__hint { display: none; }

/* Stan błędu ustawiany przez JS — z odpowiedzi serwera albo z walidacji
   przy opuszczeniu pola. */
.field.has-error input,
.field.has-error textarea,
.field.has-error select {
  border-color: #f0b8bc;
  border-bottom-color: var(--red);
  background: #fffafa;
}
.field.has-error .field__mark { opacity: 0; }

/* Licznik znaków — dyskretny, pokazywany dopiero gdy użytkownik pisze. */
.field__count {
  position: absolute;
  right: .2rem;
  bottom: -1.15rem;
  font-size: .72rem;
  font-weight: 600;
  color: #a8aeb9;
  opacity: 0;
  transition: opacity .25s var(--ease-out), color .25s var(--ease-out);
}
.field--area { margin-bottom: 1.9rem; }
.field--area:focus-within .field__count { opacity: 1; }
.field__count.is-near { color: var(--red); }

/* Select z własną strzałką (bez obrazka, zero dodatkowych requestów) */
.select { position: relative; }
.select::after {
  content: '';
  position: absolute;
  right: 1.1rem; top: 58%;
  width: .5rem; height: .5rem;
  border-right: 2px solid var(--tx-on-light-mute);
  border-bottom: 2px solid var(--tx-on-light-mute);
  transform: translateY(-50%) rotate(45deg);
  pointer-events: none;
  transition: transform .25s var(--ease-out);
}
.select:focus-within::after { transform: translateY(-50%) rotate(225deg); border-color: var(--red); }
.field select { padding-right: 2.5rem; cursor: pointer; }

/* ── Kafle profilu działalności ────────────────────────────────────────────
   Trzy opcje w rozwijanej liście to ukrywanie treści bez zysku. Kafle
   pokazują od razu, do kogo program jest adresowany, i klika się je raz. */
.chipset { border: 0; padding: 0; margin: 0 0 1.35rem; }
.chipset legend {
  padding: 0;
  margin-bottom: .7rem;
  font-family: var(--font-body);
  font-size: .8rem;
  font-weight: 600;
  color: var(--tx-on-light-mute);
  letter-spacing: .005em;
}
.chipset legend em { font-style: normal; font-size: .88em; color: #a8aeb9; }
/* Jedna kolumna mimo pięciu pozycji: etykiety typu „Sklep z narzędziami
   profesjonalnymi” w dwóch kolumnach łamałyby się na trzy linie. */
.chipset__list { display: grid; gap: .42rem; }
.chip { cursor: pointer; }
/* Natywna kontrolka schowana, ale nie usunięta — czytnik ekranu i nawigacja
   klawiaturą muszą ją widzieć. Zerowanie wypełnienia i obramowania jest tu
   jawne, żeby żadna ogólniejsza reguła pól nie nadmuchała jej z powrotem. */
.chip input {
  position: absolute;
  opacity: 0;
  width: 1px; height: 1px;
  padding: 0;
  margin: 0;
  border: 0;
  background: none;
  pointer-events: none;
}
.chip__box {
  display: flex;
  align-items: center;
  gap: .7rem;
  padding: .68rem .9rem;
  background: #f6f7f9;
  border: 1px solid #e4e7ec;
  border-radius: var(--r-sm);
  transition:
    background-color .22s var(--ease-out),
    border-color .22s var(--ease-out),
    box-shadow .22s var(--ease-out);
}
.chip:hover .chip__box { background: #f1f3f6; border-color: #cfd5de; }
.chip__tick {
  flex: none;
  position: relative;
  width: 1.05rem; height: 1.05rem;
  border: 1.5px solid #c8cdd6;
  border-radius: 50%;
  background: #fff;
  transition: border-color .22s var(--ease-out), background-color .22s var(--ease-out);
}
.chip__tick::after {
  content: '';
  position: absolute;
  inset: .22rem;
  border-radius: 50%;
  background: #fff;
  transform: scale(0);
  transition: transform .26s var(--ease-out);
}
.chip__label {
  font-size: .9rem;
  font-weight: 550;
  line-height: 1.35;
  color: var(--tx-on-light);
}
.chip input:checked + .chip__box {
  background: #fff;
  border-color: var(--red);
  box-shadow: 0 0 0 1px var(--red), 0 8px 20px -14px rgba(227, 6, 19, .8);
}
.chip input:checked + .chip__box .chip__tick { background: var(--red); border-color: var(--red); }
.chip input:checked + .chip__box .chip__tick::after { transform: scale(1); }
.chip input:focus-visible + .chip__box { box-shadow: 0 0 0 3px var(--red-soft); }

/* ── Checkbox zgody ───────────────────────────────────────────────────────
   Ptaszek rysowany kreską SVG — `stroke-dashoffset` daje wrażenie
   pisania odręcznego zamiast pojawienia się gotowego znaczka. */
.field--check { margin-top: .35rem; margin-bottom: 1.4rem; }
/* padding-block daje etykiecie wygodny cel dotykowy — sam kwadracik ma ~21 px */
.check { display: flex; gap: .8rem; align-items: flex-start; cursor: pointer; padding-block: .3rem; }
.check input {
  position: absolute;
  opacity: 0;
  width: 1px; height: 1px;
  padding: 0;
  margin: 0;
  border: 0;
  background: none;
  pointer-events: none;
}
.check__box {
  flex: none;
  display: grid;
  place-items: center;
  width: 1.35rem; height: 1.35rem;
  margin-top: .1rem;
  border: 1.5px solid #c8cdd6;
  border-radius: 5px;
  background: #fbfbfc;
  transition: background-color .24s var(--ease-out), border-color .24s var(--ease-out);
}
.check__box svg { width: 88%; height: 88%; }
.check__box path {
  fill: none;
  stroke: #fff;
  stroke-width: 2.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 20;
  stroke-dashoffset: 20;
  transition: stroke-dashoffset .3s var(--ease-out);
}
.check input:checked + .check__box { background: var(--red); border-color: var(--red); }
.check input:checked + .check__box path { stroke-dashoffset: 0; }
.check input:focus-visible + .check__box { box-shadow: 0 0 0 4px var(--red-soft); }
.field--check.has-error .check__box { border-color: var(--red); background: #fffafa; }
/* Zgoda pisana normalnie, nie wersalikami — wielkie litery w długim zdaniu
   są wyraźnie trudniejsze do przeczytania, a to jedyne pole, które
   użytkownik MUSI zrozumieć przed kliknięciem. */
.check__text {
  font-size: .87rem;
  line-height: 1.62;
  color: var(--tx-on-light-mute);
  text-transform: none;
  letter-spacing: 0;
}

/* Link do polityki prywatności — poza etykietą, z własnym celem dotykowym */
.check__link { margin-top: .5rem; padding-left: 2.1rem; }
.check__link a {
  display: inline-flex;
  align-items: center;
  min-height: 40px;                 /* samodzielny odnośnik = pełny cel dotykowy */
  font-size: .84rem;
  font-weight: 600;
  color: var(--red);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.check__link a:hover { color: var(--red-600); }

/* ── Przycisk wysyłki: przebłysk ───────────────────────────────────────────
   Smuga światła przejeżdża raz na wejście kursora. Nie jest to pętla —
   ciągle migający przycisk w formularzu B2B wygląda na reklamę. */
.btn--send { position: relative; overflow: hidden; }
.btn--send::after {
  content: '';
  position: absolute;
  top: 0; bottom: 0;
  left: -60%;
  width: 45%;
  background: linear-gradient(100deg, transparent, rgba(255, 255, 255, .38), transparent);
  transform: skewX(-18deg);
  pointer-events: none;
}
.btn--send:hover::after { animation: rpPrzeblysk .85s var(--ease-out); }
@keyframes rpPrzeblysk {
  from { left: -60%; }
  to   { left: 130%; }
}
/* W trakcie wysyłania i po sukcesie przebłysk milczy. */
.btn--send.is-loading::after { display: none; }

/* ── Pasek zaufania pod przyciskiem ────────────────────────────────────────
   Trzy krótkie obietnice dokładnie tam, gdzie rodzi się wahanie: między
   wypełnionym formularzem a kliknięciem „wyślij”. */
.trustrow {
  display: grid;
  gap: .5rem;
  margin: 1.15rem 0 0;
  padding: 1rem 1.1rem;
  list-style: none;
  background: #f6f7f9;
  border: 1px solid var(--paper-3);
  border-radius: var(--r-sm);
}
.trustrow li {
  display: flex;
  align-items: center;
  gap: .6rem;
  font-size: .78rem;
  font-weight: 600;
  line-height: 1.4;
  color: var(--tx-on-light-mute);
  letter-spacing: .005em;
}
.trustrow svg {
  flex: none;
  width: 1.05rem; height: 1.05rem;
  fill: none;
  stroke: #1d9c56;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Honeypot — niewidoczny dla człowieka, widoczny dla bota.
   Bez display:none, bo część botów pomija ukryte pola. */
.hp {
  position: absolute !important;
  left: -9999px !important;
  top: auto;
  width: 1px; height: 1px;
  overflow: hidden;
}

/* Komunikat AJAX */
.alert {
  margin-top: 1.15rem;
  padding: 1rem 1.15rem;
  border-radius: var(--r-sm);
  font-size: .93rem;
  font-weight: 550;
  line-height: 1.55;
  border-left: 3px solid;
  animation: alertIn .38s var(--ease-out);
}
.alert--ok  { background: #ecfaf0; color: #14663a; border-color: #1d9c56; }
.alert--err { background: #fdf0f0; color: #9d0611; border-color: var(--red); }
@keyframes alertIn {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}

/* ── WYSYŁKA FORMULARZA — choreografia ─────────────────────────────────────
   Trzy stany karty: wysyłanie (is-sending), odpływanie formularza (is-done),
   wejście panelu sukcesu (is-revealed). Wszystko na transform/opacity. */

.formcard { transition: box-shadow .6s var(--ease-out); }

/* Stan wysyłki: pola przygasają i przestają reagować */
#dealerForm.is-sending .field,
#dealerForm.is-sending .check,
#dealerForm.is-sending .check__link {
  opacity: .45;
  pointer-events: none;
  transition: opacity .45s var(--ease-out);
}

/* Przycisk w trakcie wysyłki — etykieta odjeżdża w górę, spinner wjeżdża */
.btn__label { transition: opacity .3s var(--ease-out), transform .35s var(--ease-out); }
.btn.is-loading .btn__label { opacity: 0; transform: translateY(-120%); }
.btn.is-loading .btn__spinner { animation: spin .7s linear infinite, spinnerIn .35s var(--ease-out); }
@keyframes spinnerIn { from { opacity: 0; transform: scale(.5); } to { opacity: 1; transform: scale(1); } }

/* Odpłynięcie formularza */
.formcard.is-done > form {
  opacity: 0;
  transform: scale(.965) translateY(-10px);
  filter: blur(6px);
  pointer-events: none;
  transition:
    opacity .4s var(--ease),
    transform .5s var(--ease-out),
    filter .4s var(--ease);
}

/* Odrzucenie — krótkie potrząśnięcie */
.formcard.is-shaking { animation: shake .6s cubic-bezier(.36, .07, .19, .97); }
@keyframes shake {
  10%, 90% { transform: translateX(-2px); }
  20%, 80% { transform: translateX(4px); }
  30%, 50%, 70% { transform: translateX(-7px); }
  40%, 60% { transform: translateX(7px); }
}

/* ── Panel sukcesu ───────────────────────────────────────────────────────── */
.success {
  position: relative;
  text-align: center;
  padding: clamp(1.75rem, 4vw, 3rem) 0 clamp(1rem, 2vw, 1.5rem);
}

/* Poświata rozchodząca się spod znacznika */
.success__halo {
  position: absolute;
  left: 50%; top: clamp(2.6rem, 5vw, 4rem);
  width: 15rem; height: 15rem;
  margin: -7.5rem 0 0 -7.5rem;
  border-radius: 50%;
  background: radial-gradient(circle, var(--red-glow) 0%, transparent 62%);
  opacity: 0;
  transform: scale(.4);
  pointer-events: none;
}
.formcard.is-revealed .success__halo {
  animation: halo 1.6s var(--ease-out) .15s both;
}
@keyframes halo {
  0%   { opacity: 0;   transform: scale(.4); }
  45%  { opacity: .85; transform: scale(1.05); }
  100% { opacity: .35; transform: scale(1); }
}

/* Znacznik rysowany kreską: najpierw obwód, potem „ptaszek” */
.success__mark {
  position: relative;
  display: block;
  width: clamp(4.5rem, 9vw, 5.5rem);
  height: clamp(4.5rem, 9vw, 5.5rem);
  margin: 0 auto 1.5rem;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.success__circle {
  stroke: var(--red);
  stroke-width: 2.2;
  stroke-dasharray: 145;
  stroke-dashoffset: 145;
  opacity: .55;
}
.success__check {
  stroke: var(--red);
  stroke-width: 3.4;
  stroke-dasharray: 40;
  stroke-dashoffset: 40;
}
.formcard.is-revealed .success__circle { animation: rysujObwod .85s var(--ease-out) .1s forwards; }
.formcard.is-revealed .success__check  { animation: rysujPtaszek .45s var(--ease-out) .6s forwards; }
@keyframes rysujObwod  { to { stroke-dashoffset: 0; } }
@keyframes rysujPtaszek { to { stroke-dashoffset: 0; } }

/* Tekst wchodzi kaskadą pod znacznikiem */
.success__title, .success__text, .success__hint, .success__phone {
  opacity: 0;
  transform: translateY(14px);
}
.formcard.is-revealed .success__title { animation: wejdz .8s var(--ease-out) .62s both; }
.formcard.is-revealed .success__text  { animation: wejdz .8s var(--ease-out) .72s both; }
.formcard.is-revealed .success__hint  { animation: wejdz .8s var(--ease-out) .82s both; }
.formcard.is-revealed .success__phone { animation: wejdz .8s var(--ease-out) .92s both; }
@keyframes wejdz { to { opacity: 1; transform: none; } }

.success__title { font-size: clamp(1.35rem, 2.4vw, 1.65rem); margin-bottom: .6rem; }
.success__text  { color: var(--tx-on-light-mute); max-width: 40ch; margin-inline: auto; }
.success__hint  { color: var(--tx-on-light-mute); font-size: .88rem; margin-top: 1.15rem; line-height: 1.55; }
.success__phone {
  display: inline-block;
  margin-top: .5rem;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1.35rem, 2.6vw, 1.7rem);
  letter-spacing: .02em;
  color: var(--red);
}
.success__phone:hover { color: var(--red-600); }

/* Reduced-motion: żadnej choreografii, panel po prostu jest */
@media (prefers-reduced-motion: reduce) {
  .success__circle, .success__check { stroke-dashoffset: 0; }
  .success__title, .success__text, .success__hint, .success__phone { opacity: 1; transform: none; }
  .success__halo { opacity: .35; transform: scale(1); }
}

/* ── 17. FOOTER + FAB ────────────────────────────────────────────────────── */
.footer {
  background: var(--ink);
  border-top: 1px solid var(--line-dark);
  padding-top: clamp(2.75rem, 5vw, 4rem);
  font-size: .92rem;
}
.footer__grid {
  display: grid;
  gap: 2.25rem;
  padding-bottom: clamp(2rem, 4vw, 3rem);
}
.footer picture { display: contents; }
.footer__logo { height: 39px; width: auto; opacity: .92; }
.footer__desc { color: var(--tx-on-dark-mute); margin-top: 1rem; line-height: 1.6; }
.footer__desc strong { color: #fff; }
.footer__col h4 {
  font-size: .76rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--red);
  margin-bottom: 1rem;
  font-family: var(--font-display);
  font-weight: 600;
}
.footer__col { color: var(--tx-on-dark-mute); line-height: 1.85; }
.footer__col a { display: inline-block; transition: color var(--t-fast); }
.footer__col a:hover { color: #fff; }
nav.footer__col a { display: block; }
.footer__hours { margin-top: .9rem; font-size: .85rem; }

.footer__bottom {
  border-top: 1px solid var(--line-dark);
  padding-block: 1.5rem;
  display: grid;
  gap: .75rem;
  font-size: .8rem;
  color: #6b7280;
}
.footer__legal { line-height: 1.65; max-width: 90ch; }

/* ── NAWIGACJA KROPKOWA (prawa krawędź) ───────────────────────────────────
   Pionowy wskaźnik postępu z nazwami sekcji. Buduje go JS z istniejącego
   menu, więc nie duplikuje listy sekcji w znacznikach. Tylko desktop —
   na telefonie zabierałby szerokość treści. */
.dotnav {
  position: fixed;
  top: 50%;
  right: clamp(.9rem, 1.6vw, 1.6rem);
  transform: translateY(-50%);
  z-index: 80;
  display: none;
  flex-direction: column;
  gap: .95rem;
  opacity: 0;
  transition: opacity .5s var(--ease-out);
}
.dotnav.is-visible { opacity: 1; }
.dotnav__item {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  height: 12px;
}
.dotnav__dot {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: rgba(255, 255, 255, .28);
  transition: background-color var(--t), transform var(--t), box-shadow var(--t);
}
/* Na jasnych sekcjach kropki muszą się odwrócić kolorystycznie */
.dotnav.on-light .dotnav__dot { background: rgba(11, 12, 15, .22); }

.dotnav__item.is-active .dotnav__dot {
  background: var(--red);
  transform: scale(1.5);
  box-shadow: 0 0 0 4px var(--red-soft), 0 0 12px var(--red-glow);
}

/* Etykieta wysuwa się przy najechaniu */
.dotnav__label {
  position: absolute;
  right: calc(100% + .7rem);
  white-space: nowrap;
  font-size: .72rem;
  font-weight: 650;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: #fff;
  background: rgba(11, 12, 15, .88);
  border: 1px solid var(--line-dark-2);
  border-radius: 99px;
  padding: .32rem .7rem;
  opacity: 0;
  transform: translateX(6px);
  pointer-events: none;
  transition: opacity var(--t), transform var(--t);
  backdrop-filter: blur(8px);
}
.dotnav__item:hover .dotnav__label,
.dotnav__item:focus-visible .dotnav__label { opacity: 1; transform: none; }

@media (min-width: 1100px) and (prefers-reduced-motion: no-preference) {
  .dotnav { display: flex; }
}

/* ── FAQ: płynne rozwijanie ────────────────────────────────────────────────
   <details> nie animuje wysokości natywnie w większości przeglądarek,
   więc wysokość animuje JS na wrapperze .faq__a. */
.faq__a {
  overflow: hidden;
  will-change: height;
}
.faq__item[open] .faq__a { animation: none; }   /* zastąpione animacją JS */

/* Pływający CTA na mobile */
.fab {
  position: fixed;
  left: 50%;
  bottom: 1rem;
  transform: translate(-50%, 150%);
  z-index: 90;
  display: none;
  padding: .95rem 1.75rem;
  background: var(--red);
  color: #fff;
  font-weight: 700;
  font-size: .95rem;
  border-radius: 99px;
  box-shadow: 0 14px 34px -10px rgba(227, 6, 19, .65);
  transition: transform .45s var(--ease-out);
  white-space: nowrap;
}
.fab.is-visible { transform: translate(-50%, 0); }

/* ── 18. BREAKPOINTY ─────────────────────────────────────────────────────── */

/* ≤ 900 px — układ mobilny: menu w pełnoekranowej szufladzie */
@media (max-width: 900px) {
  .burger { display: block; }

  .nav {
    position: fixed;
    inset: 0;
    flex-direction: column;
    justify-content: center;
    align-items: stretch;
    gap: 0;
    padding: calc(var(--hdr-h) + 2rem) var(--gutter) 2.5rem;
    background: rgba(11, 12, 15, .97);
    backdrop-filter: blur(20px);
    transform: translateX(100%);
    transition: transform .45s var(--ease-out);
    overflow-y: auto;
  }
  .nav.is-open { transform: none; }

  .nav__list { flex-direction: column; align-items: stretch; gap: 0; }
  .nav__list li { border-bottom: 1px solid var(--line-dark); }
  .nav__list a {
    display: block;
    padding: 1.15rem 0;
    font-size: 1.32rem;
    font-weight: 700;
    color: #fff;
  }
  .nav__list a::after { display: none; }

  .brand__logo { height: 40px; }
  .hdr.is-stuck .brand__logo { height: 34px; }

  /* ── Bestsellery na telefonie ─────────────────────────────────────────────
     Nie jest to zwykły stos kart: JS steruje paralaksą zdjęcia i numeru
     (patrz tryb 'stack' w main.js), a tutaj dokładamy oprawę, żeby każda
     pozycja czytała się jak osobna scena, nie jak wiersz listy. */
  .lineup__item { padding-block: 1.25rem; }
  .lineup__item + .lineup__item { border-top: 1px solid var(--line-dark); padding-top: 2.75rem; }

  .lineup__shot, .lineup__num { will-change: transform; }

  /* Produkt na własnym, delikatnie świecącym podłożu */
  .lineup__shot::before {
    content: '';
    position: absolute;
    left: 50%; top: 50%;
    width: 116%; aspect-ratio: 1;
    transform: translate(-50%, -50%);
    background: radial-gradient(circle, rgba(227, 6, 19, .17) 0%, transparent 62%);
    filter: blur(12px);
    z-index: -1;
    pointer-events: none;
  }
  .lineup__shot img { max-height: 42vh; }

  /* Numer jako duży znak wodny za produktem */
  .lineup__num {
    font-size: clamp(6rem, 27vw, 11rem);
    color: rgba(255, 255, 255, .06);
    top: -.18em;
  }

  .lineup__name { font-size: clamp(1.45rem, 6.5vw, 1.9rem); }
  .lineup__cat  { font-size: .72rem; }

  /* Przełącznik języka w szufladzie: większy cel dotykowy */
  .lang { align-self: flex-start; margin-top: 1.85rem; padding: .26rem; }
  .lang__opt { padding: .55rem .95rem; font-size: .92rem; }
  .lang__opt img { width: 24px; height: 16px; }

  .nav__phone { display: inline-flex; margin-top: 1.25rem; justify-content: flex-start; padding-inline: 0; font-size: 1.05rem; }
  .nav__phone svg { color: var(--red); }
  .nav__cta { margin-top: 1rem; }

  body.nav-open { overflow: hidden; }

  .fab { display: block; }
}

/* ≥ 600 px */
@media (min-width: 600px) {
  .domains { grid-template-columns: repeat(2, 1fr); }
  .techgrid { grid-template-columns: repeat(2, 1fr); }
  .field-row { grid-template-columns: 1fr 1fr; }
  /* Nazwa firmy potrzebuje więcej miejsca niż dziesięciocyfrowy NIP. */
  .field-row--wide { grid-template-columns: 1.45fr 1fr; }
  .trustrow { grid-template-columns: repeat(3, auto); justify-content: space-between; gap: 1rem; }
  .trustrow li { font-size: .74rem; }
  .cards { grid-template-columns: repeat(2, 1fr); }
  .footer__grid { grid-template-columns: repeat(2, 1fr); }
  .honest { grid-template-columns: auto 1fr; }
  .footer__bottom { grid-template-columns: auto 1fr; align-items: center; gap: 2rem; }
  .footer__legal { text-align: right; }
}

/* ≥ 901 px — desktop */
@media (min-width: 901px) {
  /* Wyższy pasek, bo logotyp urósł do 50 px — inaczej nie miałby oddechu. */
  :root { --hdr-h: 96px; }

  .hero__inner { grid-template-columns: 1.08fr .92fr; }
  .hero__scroll { display: flex; }
  .hero__visual { order: 2; }

  .grid-2 { grid-template-columns: .95fr 1.05fr; }
  .grid-form { grid-template-columns: .88fr 1.12fr; }

  .domains { grid-template-columns: repeat(3, 1fr); }
  .techgrid { grid-template-columns: repeat(3, 1fr); }
  .bandhead .lead { max-width: 68ch; }

  .pillars { grid-template-columns: repeat(3, 1fr); }
  .pillar { padding: clamp(1.4rem, 2.2vw, 2rem); }
  .pillar__title { font-size: clamp(1.2rem, 1.7vw, 1.45rem); }
  .pillar__figure b { font-size: clamp(1.5rem, 2.4vw, 2.1rem); }
  .cards { grid-template-columns: repeat(3, 1fr); }
  .steps { grid-template-columns: repeat(3, 1fr); }

  /* Łącznik między krokami procesu.
     z-index: 0 (nie -1) — przy wartości ujemnej linia schowałaby się
     pod tłem sekcji, bo .section nie tworzy kontekstu układania. */
  .steps::before {
    content: '';
    position: absolute;
    top: 3.4rem;
    left: 12%;
    right: 12%;
    height: 1px;
    background: repeating-linear-gradient(90deg, var(--line-dark-2) 0 8px, transparent 8px 16px);
    z-index: 0;
  }

  .lineup__item { grid-template-columns: 1.02fr .98fr; gap: clamp(2rem, 4vw, 4rem); }
  .lineup__item[data-side="right"] .lineup__shot { order: 2; }

  .ctaband__inner { grid-template-columns: 1.15fr auto; }
  .ctaband__actions { justify-content: flex-end; }

  .footer__grid { grid-template-columns: 1.5fr 1fr 1fr 1fr; }
}

/* ────────────────────────────────────────────────────────────────────────
   LINIA PRODUKTOWA — tryb przyklejonej sceny.
   Warunek `prefers-reduced-motion: no-preference` jest w samej regule, więc
   użytkownik z wyłączonymi animacjami dostaje zwykły stos kart z góry,
   a nie „naprawiony” scroll-jacking.
   ──────────────────────────────────────────────────────────────────────── */
@media (min-width: 901px) and (prefers-reduced-motion: no-preference) {

  /* Wybieg przewijania: jeden ekran na produkt (+ wysokość samej sceny). */
  .lineup.is-scroll .lineup__runway { height: calc(100svh + var(--count) * 92vh); }

  .lineup.is-scroll .lineup__stage {
    position: sticky;
    top: 0;
    height: 100vh;                    /* fallback dla przeglądarek bez svh */
    height: 100svh;
    padding: calc(var(--hdr-h) + 1.25rem) 0 1.75rem;
    display: grid;
    grid-template-rows: auto minmax(0, 1fr) auto;
    gap: 1rem;
    overflow: hidden;
  }

  /* Tło sceny: czerwona poświata + siatka techniczna */
  .lineup.is-scroll .lineup__bg { display: block; position: absolute; inset: 0; pointer-events: none; }
  .lineup__glow {
    position: absolute;
    left: 50%; top: 46%;
    width: 74vh; aspect-ratio: 1;
    transform: translate(-50%, -50%);
    background: radial-gradient(circle, rgba(227, 6, 19, .19) 0%, transparent 64%);
    filter: blur(20px);
  }
  .lineup__grid {
    position: absolute;
    inset: 0;
    background-image:
      linear-gradient(to right, rgba(255, 255, 255, .04) 1px, transparent 1px),
      linear-gradient(to bottom, rgba(255, 255, 255, .04) 1px, transparent 1px);
    background-size: 78px 78px;
    mask-image: radial-gradient(80% 70% at 50% 50%, #000 10%, transparent 78%);
  }

  /* Nagłówek kurczy się do jednej linijki — scena należy do produktów. */
  /* Eyebrow + tytuł trzymają się lewej, podtytuł wypycha się na prawo.
     (space-between rozrzuciłoby trzy elementy i tytuł wylądowałby na środku.) */
  .lineup.is-scroll .lineup__head {
    flex-direction: row;
    align-items: flex-end;
    justify-content: flex-start;
    text-align: left;
    gap: 1.5rem;
    margin-bottom: 0;
    position: relative;
    z-index: 3;
  }
  .lineup.is-scroll .lineup__sub { margin-left: auto; }
  .lineup.is-scroll .lineup__title { font-size: clamp(1.9rem, 3.2vw, 2.8rem); }
  .lineup.is-scroll .lineup__title br { display: none; }
  .lineup.is-scroll .lineup__title .hl { margin-left: .3em; }
  .lineup.is-scroll .lineup__sub { text-align: right; max-width: 34ch; font-size: .93rem; }

  /* Produkty leżą jeden na drugim; widoczność steruje JS. */
  .lineup.is-scroll .lineup__items {
    position: relative;
    display: block;
    gap: 0;
    min-height: 0;
  }
  .lineup.is-scroll .lineup__item {
    position: absolute;
    inset: 0;
    max-width: none;
    /* Wyśrodkowanie do szerokości kontenera bez dodatkowego wrappera */
    padding-inline: max(var(--gutter), calc((100% - var(--container)) / 2));
    opacity: 0;
    visibility: hidden;
    transform: none;
    transition: none;               /* wszystko liczy JS, klatka po klatce */
    will-change: opacity;
  }
  .lineup.is-scroll .lineup__shot,
  .lineup.is-scroll .lineup__info { will-change: transform; }

  .lineup.is-scroll .lineup__shot img { max-height: 54svh; }
  .lineup.is-scroll .lineup__num {
    left: max(var(--gutter), calc((100% - var(--container)) / 2));
    top: 50%;
    transform: translateY(-50%);
    font-size: clamp(9rem, 19vw, 17rem);
    color: rgba(255, 255, 255, .038);
  }
  .lineup.is-scroll .lineup__item[data-side="right"] .lineup__num { left: auto; right: max(var(--gutter), calc((100% - var(--container)) / 2)); }

  /* ── Szyna: literalna „linia produktów" ────────────────────────────── */
  .lineup.is-scroll .lineup__rail {
    display: block;
    position: relative;
    z-index: 3;
    width: 100%;
    max-width: var(--container);
    margin-inline: auto;
    padding-inline: var(--gutter);
    height: 3rem;
  }
  .lineup__rail-base, .lineup__rail-fill {
    position: absolute;
    left: var(--gutter);
    right: var(--gutter);
    top: .48rem;
    height: 1px;
  }
  .lineup__rail-base { background: var(--line-dark-2); }
  .lineup__rail-fill {
    background: linear-gradient(90deg, var(--red-700), var(--red));
    box-shadow: 0 0 14px var(--red-glow);
    transform: scaleX(var(--fill, 0));
    transform-origin: left;
  }
  .lineup__nodes { display: flex; justify-content: space-between; position: relative; }
  .lineup__node {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .55rem;
  }
  .lineup__node::before {
    content: '';
    width: 9px; height: 9px;
    border-radius: 50%;
    background: var(--ink);
    border: 1px solid var(--line-dark-2);
    transition: background-color .35s var(--ease), border-color .35s var(--ease), box-shadow .35s var(--ease), transform .35s var(--ease);
  }
  .lineup__node b {
    font-family: var(--font-display);
    font-size: .78rem;
    font-weight: 600;
    letter-spacing: .12em;
    color: #4b515c;
    transition: color .35s var(--ease);
  }
  .lineup__node.is-on::before {
    background: var(--red);
    border-color: var(--red);
    box-shadow: 0 0 0 4px var(--red-soft), 0 0 14px var(--red-glow);
    transform: scale(1.15);
  }
  .lineup__node.is-on b { color: #fff; }

  .lineup.is-scroll .lineup__hint {
    display: block;
    position: absolute;
    right: var(--gutter);
    bottom: 4.4rem;
    z-index: 3;
    font-size: .68rem;
    font-weight: 700;
    letter-spacing: .28em;
    text-transform: uppercase;
    color: var(--tx-on-dark-mute);
    transition: opacity .4s var(--ease);
  }
  .lineup.is-scroll .lineup__hint::after {
    content: '';
    display: block;
    width: 1px; height: 26px;
    margin: .6rem auto 0;
    background: linear-gradient(180deg, var(--red), transparent);
    animation: scrollHint 2.1s var(--ease) infinite;
  }
  .lineup.is-scroll.is-engaged .lineup__hint { opacity: 0; }
}

/* Niskie ekrany desktopowe (laptopy 1366×768, 1280×720).
   Scena ma stałą wysokość 100svh, więc kolumna z opisem musi się w niej
   zmieścić bez przewijania — przy domyślnych rozmiarach najdłuższa pozycja
   (RUNPOLIFTER, cztery parametry + długa wartość wału) wypełniała ją co do
   piksela. Tu skracamy wszystkie odstępy naraz, zamiast ucinać treść. */
@media (min-width: 901px) and (max-height: 820px) and (prefers-reduced-motion: no-preference) {
  .lineup.is-scroll .lineup__shot img { max-height: 42svh; }
  .lineup.is-scroll .lineup__info    { gap: .62rem; }
  .lineup.is-scroll .lineup__name    { font-size: clamp(1.25rem, 2.1vw, 1.7rem); }
  .lineup.is-scroll .lineup__desc    { font-size: .92rem; line-height: 1.55; }
  .lineup.is-scroll .specs__row      { padding: .44rem .7rem; }
  .lineup.is-scroll .specs dt        { font-size: .62rem; margin-bottom: .12rem; }
  .lineup.is-scroll .specs dd        { font-size: .96rem; }
  .lineup.is-scroll .lineup__note    { font-size: .78rem; }
  .lineup.is-scroll .lineup__cat     { font-size: .72rem; padding: .28rem .7rem; }
}

/* Wąski desktop (901–1180 px): logotyp jest sporo szerszy od zastępczego
   wordmarku, więc na tym zakresie ściskamy odstępy w nawigacji, zamiast
   pozwolić jej się załamać. */
@media (min-width: 901px) and (max-width: 1180px) {
  .nav { gap: 1.15rem; }
  .nav__list { gap: 1.05rem; }
  .nav__list a { font-size: .88rem; }
  .brand { gap: .6rem; }
  .brand__logo { height: 42px; }
  .hdr.is-stuck .brand__logo { height: 35px; }
  /* Same flagi bez kodów — czytelne, a oszczędzają ok. 60 px w pasku */
  .lang__code { display: none; }
  .lang__opt { padding: .34rem .5rem; }
}

/* Poniżej ~1040 px podpis „Program dealerski PL" ustępuje miejsca menu —
   logotyp niesie tę samą informację o marce. */
@media (min-width: 901px) and (max-width: 1040px) {
  .brand__divider, .brand__sub { display: none; }
}

/* ≥ 1400 px — duże ekrany / 4K: rośnie oddech, nie rozmiar liter */
@media (min-width: 1400px) {
  :root { --container: 1380px; --section-y: 10rem; }
  .hero__stats { max-width: 620px; }
}
@media (min-width: 2000px) {
  :root { --container: 1560px; }
  body { font-size: 1.125rem; }
}

/* ── 19. DOSTĘPNOŚĆ / RUCH / DRUK ────────────────────────────────────────── */

/* Użytkownik prosi o mniej ruchu → pokazujemy wszystko od razu, statycznie. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
  [data-anim] { opacity: 1 !important; transform: none !important; filter: none !important; }
  .reveal > span { transform: none !important; }
  .marquee__track { animation: none; }
  .hero__glow { animation: none; }
  .fab { transition: none; }
}

/* Tryb wysokiego kontrastu / wymuszone kolory systemowe */
@media (forced-colors: active) {
  .btn { border: 1px solid currentColor; }
  .field input, .field textarea, .field select { border: 1px solid currentColor; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   19b. WARSTWA EFEKTÓW PREMIUM
   ═══════════════════════════════════════════════════════════════════════════
   Wybór technik z nagradzanych stron (By-Kin, Iventions, Mat Voyce,
   Uncommon Studio, Minh Pham), przełożony na czysty CSS/JS bez frameworka.

   ŚWIADOMIE POMINIĘTE: „weighted smooth scroll” (podpis By-Kin). Przechwycenie
   przewijania walczyłoby z przyklejoną sceną Bestsellerów, która czyta realną
   pozycję scrolla, odbiera użytkownikowi natywny pasek i szkodzi dostępności.
   Na stronie pozyskującej dealerów to zła wymiana.

   ZASADA: każdy efekt tutaj jest OZDOBĄ. Stan bazowy jest w pełni widoczny,
   więc brak wsparcia dla `animation-timeline` nie ukrywa ani jednego słowa.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Kinetyka kroju zmiennego ───────────────────────────────────────────────
   Clash Display jest krojem ZMIENNYM (200–700), więc grubość da się
   interpolować. Wielka liczba „dogęszcza się” przy wejściu w kadr — efekt
   rzadki, bo wymaga osadzonego kroju zmiennego, a my go już mamy.

   Szerokość liczby musi być ZAREZERWOWANA, inaczej grubnące cyfry przesuwają
   jednostkę („kg”, „mm”). Rezerwację wpisuje JS w pikselach, po zmierzeniu
   napisu przy docelowej grubości i po wczytaniu kroju.

   NIE da się tego zrobić w samym CSS: pierwsza wersja używała `calc(cyfry *
   1ch)`, ale jednostka `ch` sama zależy od grubości kroju — rezerwacja
   kurczyła się razem z tym, co miała kompensować, i jednostka dryfowała
   o 6 px. Cyfry tego kroju mają też bardzo różne szerokości („1” kontra „8”),
   więc żaden stały mnożnik na cyfrę nie daje równych odstępów. */
.tech__figure b {
  font-variation-settings: 'wght' 300;
  transition: font-variation-settings 1.1s var(--ease-out);
}
.tech.is-in .tech__figure b { font-variation-settings: 'wght' 620; }

@media (prefers-reduced-motion: reduce) {
  .tech__figure b { font-variation-settings: 'wght' 620; transition: none; }
}

/* ── Pasek kategorii reagujący na przewijanie ──────────────────────────────
   Wychylenie liter zależy od prędkości scrolla (zmienną ustawia JS).
   Daje wrażenie jednej ciągłej powierzchni, o które chodzi w „continuous
   surface” u By-Kin, bez przechwytywania samego przewijania.
   Skos idzie na ELEMENTY, nie na tor — tor ma własną animację przesuwu
   i nadpisanie jego `transform` zatrzymałoby pasek. */
.marquee__item {
  transform: skewX(var(--sk, 0deg));
  transition: transform .18s linear;
}

/* ── Światło punktowe na zdjęciach produktów ───────────────────────────────
   Iventions traktuje projekty jak „oświetlone instalacje”. Tu ten sam zabieg:
   plama światła podąża za kursorem po zdjęciu, zamiast płaskiego podświetlenia. */
.carousel__shot,
.lineup__shot { position: relative; }
.carousel__shot::after,
.lineup__shot::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(18rem 18rem at var(--mx, 50%) var(--my, 50%),
                              rgba(255, 255, 255, .11), transparent 68%);
  opacity: 0;
  transition: opacity .55s var(--ease-out);
}
.carousel__shot:hover::after,
.lineup__shot:hover::after { opacity: 1; }

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {

    /* Szew między sekcjami rozsuwa się od środka, gdy sekcja wchodzi w kadr.
       „Camera move” w wersji, która nie rusza treści — animowany jest sam
       gradient styku, więc nie ma ryzyka szczelin ani złamanego `sticky`. */
    @keyframes rpSzew {
      from { transform: scaleX(.35); opacity: 0; }
      to   { transform: scaleX(1);   opacity: 1; }
    }
    .section--dark::before,
    .section--light::before {
      transform-origin: 50% 0;
      animation: rpSzew linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 65%;
    }

    /* Łącznik kroków rysuje się w miarę przewijania sekcji procesu.
       Wcześniej był statyczną linią — teraz „prowadzi” wzrok przez trzy kroki. */
    @media (min-width: 901px) {
      @keyframes rpLacznik { from { transform: scaleX(0); } to { transform: scaleX(1); } }
      .steps::before {
        transform-origin: 0 50%;
        animation: rpLacznik linear both;
        animation-timeline: view();
        animation-range: entry 25% cover 55%;
      }
    }
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
   19c. FORMULARZ — WARSTWA NOWOCZESNEGO CSS
   ═══════════════════════════════════════════════════════════════════════════
   Wszystko tutaj to progresywne wzbogacenie. Każda właściwość siedzi we
   własnym `@supports` albo degraduje się bez szkody, bo formularz jest
   jedynym kanałem pozyskania dealera — nie może zależeć od świeżego API.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Kolor zaznaczenia i akcentu wewnątrz karty — spójny z marką.
   `accent-color` obsługuje natywne części kontrolek (kursor listy, zaznaczenie
   tekstu w niektórych silnikach), których nie da się ostylować inaczej. */
.formcard {
  accent-color: var(--red);
  --rp-sel: rgba(227, 6, 19, .16);
}
.formcard ::selection { background: var(--rp-sel); }

/* Etykiety i podpowiedzi łamane „ładnie” — bez sierotek na końcu wiersza. */
.field--float > label,
.field__hint,
.check__text,
.chipset legend { text-wrap: pretty; }

/* ── Samorosnące pole wiadomości ───────────────────────────────────────────
   `field-sizing: content` (Baseline od 06.2026) sprawia, że pole rośnie razem
   z treścią — koniec z paskiem przewijania w środku formularza i z ręcznym
   ciągnięciem uchwytu. Ograniczenia są KONIECZNE: bez `max-height` długa
   wiadomość rozepchnęłaby kartę na kilka ekranów i przycisk wysyłki
   wyjechałby poza zasięg.

   Gdzie właściwości nie ma, zostaje zwykłe pole z `min-height` i uchwytem —
   dokładnie to, co było wcześniej. */
@supports (field-sizing: content) {
  .field--area textarea {
    field-sizing: content;
    min-height: 7.5rem;
    max-height: 19rem;
    resize: none;                 /* uchwyt zbędny, gdy pole rośnie samo */
    overflow-y: auto;
  }
}

/* ── Wejście komunikatu błędu ──────────────────────────────────────────────
   `@starting-style` opisuje stan SPRZED pierwszego renderu, więc komunikat
   wstawiany do DOM potrafi się animować — wcześniej pojawiał się skokowo,
   bo przejście z `display: none` nie miało od czego startować. */
   `display .3s allow-discrete` w liście przejść jest KONIECZNE: komunikat
   startuje z `display: none`, a bez tego członu przeglądarka przeskakuje
   wprost do stanu końcowego i nie ma czego animować.

   Paska komunikatu zbiorczego (.alert) tu NIE dotykamy — ma już działającą
   animację `alertIn`. Dołożenie drugiego mechanizmu dublowałoby ruch, a przy
   braku wsparcia dla `@starting-style` odebrałoby animację, którą już ma. */
.field.has-error .field__err {
  transition:
    opacity .3s var(--ease-out),
    transform .3s var(--ease-out),
    display .3s allow-discrete;
  opacity: 1;
  transform: none;
}
@starting-style {
  .field.has-error .field__err {
    opacity: 0;
    transform: translateY(-4px);
  }
}

/* ── Stany grup pól sterowane wyłącznie CSS-em ─────────────────────────────
   `:has()` pozwala oznaczyć grupę bez ani jednej linii JS.

   Warunek jest dwuczłonowy i to nie przypadek: `:has(.field--req)` odsiewa
   grupę trzecią, która ma tylko pola opcjonalne — bez tego zapaliłaby się
   na zielono od razu po wejściu na stronę i kłamałaby o postępie. */
.fgroup:has(.field--req):not(:has(.field--req:not(.is-valid))) .fgroup__num {
  background: #1d9c56;
  box-shadow: 0 4px 12px -4px rgba(29, 156, 86, .55);
}
/* Numer ustępuje miejsca ptaszkowi — grupa domknięta czyta się od razu. */
.fgroup:has(.field--req):not(:has(.field--req:not(.is-valid))) .fgroup__num[data-num] {
  color: transparent;
  position: relative;
}
.fgroup:has(.field--req):not(:has(.field--req:not(.is-valid))) .fgroup__num[data-num]::after {
  content: '';
  position: absolute;
  left: .5rem; top: .42rem;
  width: .3rem; height: .55rem;
  border-right: 2px solid #fff;
  border-bottom: 2px solid #fff;
  transform: rotate(40deg);
}

/* Aktywna grupa dostaje pionową szynę akcentu — wzrok wie, gdzie jest,
   nawet po zerknięciu w bok. Wcześniej podświetlało się samo pole. */
/* Szyna rysuje się w MARGINESIE karty, nie w treści: `padding-left` jest
   zniesione równym `margin-left` na minusie. Bez tej kompensacji zapalenie
   szyny zwężało grupę o 15 px, czyli każde dotknięcie pola na telefonie
   przestawiało układ. Zapas mieści się w wypełnieniu karty (24 px na
   telefonie), więc szyna nie wychodzi poza kartę. */
.fgroup {
  padding-left: 0;
  margin-left: 0;
  border-left: 2px solid transparent;
  transition:
    border-color .4s var(--ease-out),
    padding-left .4s var(--ease-out),
    margin-left .4s var(--ease-out);
}
/* `:focus-within`, nie `:has(input:focus)`. Wyraża dokładnie tę intencję
   („w tej grupie jest ognisko”), jest krótsze i wspierane szerzej niż `:has()`
   — sięganie po nowsze narzędzie tam, gdzie starsze pasuje lepiej, to koszt
   bez zysku. `:has()` zostaje tylko tam, gdzie naprawdę nie ma zamiennika:
   przy sprawdzaniu, czy grupie zostało jeszcze niewypełnione pole wymagane. */
.fgroup:focus-within {
  border-left-color: var(--red);
  padding-left: .95rem;
  margin-left: -.95rem;
}
@media (prefers-reduced-motion: reduce) {
  .fgroup { transition: none; }
}

/* Wyraźny pierścień ogniska dla klawiatury — z odstępem, żeby nie zlewał się
   z obramowaniem pola. */
.formcard :focus-visible {
  outline: 2px solid var(--red);
  outline-offset: 2px;
}
.formcard input:focus-visible,
.formcard textarea:focus-visible,
.formcard select:focus-visible { outline: none; }   /* te mają własny stan */

/* ── 20. DOMKNIĘCIE TYPOGRAFII ─────────────────────────────────────────────
   Musi stać na końcu arkusza: komponenty wyżej deklarują własny krój, a przy
   równej specyficzności decyduje kolejność. Efekt to twardy podział —
   Clash Display TYLKO nagłówki i wielkie liczby ozdobne, Satoshi cała reszta. */
.eyebrow, .marquee__item, .lineup__cat, .specs dd, .success__phone,
.carousel__cat, .stat__value, .lineup__node b, .honest__label,
.expect__list span, .step__meta, .brand__sub, .lang__opt {
  font-family: var(--font-body);
  word-spacing: normal;
}

@media print {
  .hdr, .fab, .hero__bg, .marquee, .hero__scroll, .btn { display: none !important; }
  body { background: #fff; color: #000; }
  .section, .hero { padding-block: 1rem; }
  [data-anim] { opacity: 1 !important; transform: none !important; }
}
