/* ==========================================================================
   svc.css — podstrony usługowe (SEO, Google Ads)
   Wzorzec: żywa /ai-search/ + design aw-page (tokens.css).
   Wszystko scopowane pod .svc — zero wycieków do reszty serwisu.
   Zasady: animujemy TYLKO opacity/transform; dekoracje aria-hidden;
   prefers-reduced-motion + mobile = stan końcowy bez ruchu.
   ========================================================================== */

.svc {
  --ease: cubic-bezier(.2, .7, .2, 1);
  --serp-bg: #202124;
  --serp-line: #3c4043;
  --serp-link: #8ab4f8;
  --serp-txt: #bdc1c6;
  --serp-mut: #9aa0a6;
  font-family: var(--type-family-body), system-ui, sans-serif;
}

/* Sekcje: 1 sekcja = 1 ekran (desktop), dociąganie przewijania.
   Uwaga wydajność: svc.css ładuje się TYLKO na podstronach usługowych,
   więc stylujemy html wprost — bez html:has(.svc), które przy każdej zmianie
   w DOM wymuszało drogie przeliczanie stylów całej strony (TBT na mobile). */
html {
  /* scroll-snap USUNIĘTY (Karol, 16.07): przewijanie ma być luźne, nie sekcyjne.
     scroll-padding-top zostaje — utrzymuje odstęp pod belką przy skoku do kotwicy. */
  scroll-padding-top: 90px;
}
.svc-sec {
  position: relative;
  padding: clamp(48px, 6vw, 90px) 0;
  /* przeglądarka nie liczy układu sekcji poza ekranem — szybszy start (LCP/TBT);
     zarezerwowana wysokość zapobiega skokom układu (CLS) */
  content-visibility: auto;
  contain-intrinsic-size: auto 900px;
}
.svc-sec:first-of-type { content-visibility: visible; }
@media (min-width: 1025px) {
  /* Zasada Karola (10.07): jedna sekcja = jedna wysokość ekranu, treść na środku.
     Na stronie SEO KAŻDA sekcja treściowa ma klasę --full (także efekty i FAQ) —
     bez wyjątków, bo to mieszanka pełnoekranowych z „ciasnymi" psuła rytm. */
  .svc-sec--full {
    min-height: 100svh;
    display: flex;
    flex-direction: column;
    justify-content: center;
  }
  /* ⚠️ BŁĄD UKŁADU NA WSZYSTKICH 8 PODSTRONACH (zdiagnozowany pomiarem, sesja 17).
     `.svc-sec--full` jest kontenerem elastycznym (flex), a `.container` ma w środku
     `margin-inline: auto`. Auto-margines W POPRZEK osi flexa kasuje rozciąganie
     i kontener KURCZY SIĘ DO ZAWARTOŚCI zamiast trzymać stałą szerokość strony.

     Skutek, zmierzony przy oknie 1440 px: sekcje miały szerokości od 924 do 1425 px,
     więc każda zaczynała się w innym miejscu. Na sekcjach z tekstem wyśrodkowanym
     tego nie widać — widać dokładnie tam, gdzie treść jest wyrównana do lewej
     (stąd uwaga Karola „5% dziwnie dociągnięte do lewej”: liczba startowała 90 px
     dalej niż nagłówek strony).

     Naprawa: kontener ma trzymać pełną szerokość. Wąskie kolumny, które MAJĄ być
     wąskie (FAQ), dostają to jawnie niżej — zamiast brać wąskość z przypadku. */
  .svc-sec--full > .container { width: 100%; }
  /* Hero (uwaga Karola 10.07): pierwszy ekran bez pustej bandy pod belką.
     Belka (sticky, 32px odstępu + 70px pigułki = 102px) zabiera górę pierwszego
     ekranu, więc hero mieści się w tym, co zostaje — treść centruje się tuż
     pod belką zamiast w połowie pełnego 100svh. */
  .svc .svc-sec:first-of-type {
    min-height: calc(100svh - 102px);
    padding-top: 20px;
    padding-bottom: 24px;
  }
}
/* Niskie okna (laptop z belkami przeglądarki ~750–860px): makieta w hero
   przeskalowana w dół w całości (zoom = identyczne proporcje, zero ryzyka
   uciętych ogonków liter), żeby pierwszy ekran mieścił się nad zgięciem. */
@media (min-width: 1025px) and (max-height: 860px) {
  .svc .svc-sec:first-of-type .svc-win { zoom: .85; }
}
@media (min-width: 1025px) and (max-height: 780px) {
  .svc .svc-sec:first-of-type .svc-win { zoom: .76; }
}

/* ----- Nagłówki / typografia ----- */
.svc-h1 {
  margin-top: 18px;
  font-weight: 600;
  font-size: clamp(38px, 4.8vw, 68px);
  line-height: 1.04;
  letter-spacing: -0.025em;
  color: var(--text-heading);
  text-wrap: balance;
}
.svc-h2 {
  font-weight: 600;
  font-size: clamp(27px, 3.5vw, 46px);
  line-height: 1.07;
  letter-spacing: -0.022em;
  color: var(--text-heading);
  text-wrap: balance;
}
.svc-h1 .hl, .svc-h2 .hl { color: var(--text-accent); }
.svc-h2 .hl--block { display: block; }

/* TELEFON: nagłówek o stopień mniejszy (decyzja Karola 14.07).
   Powód: przy 27 px w linijkę wchodzi ~19 znaków, a para „potrzebujesz strategii?" ma 23 —
   ostatnie słowo MUSIAŁO zostawać samo (sierotka), bo dwa ostatnie słowa fizycznie nie
   mieściły się razem. Twarda spacja tego nie naprawi; jedyne wyjście to mniejsze pismo.
   Zmiana dotyczy tylko ekranów do 430 px — na tablecie i komputerze nic się nie zmienia. */
@media (max-width: 430px) {
  .svc-h2 { font-size: 24px; }
}
/* H1 w dwóch liniach (uwaga Karola 09.07): linia 1 mniejsza, zawsze w jednej linijce */
.svc-h1--stack span { display: block; }
.svc-h1__kicker {
  font-size: .56em;
  line-height: 1.15;
  letter-spacing: -0.015em;
  margin-bottom: 10px;
  white-space: nowrap;
}
.svc-lead {
  margin-top: 18px;
  max-width: 58ch;
  font-size: clamp(16px, 1.25vw, 18px);
  line-height: 1.62;
  color: var(--text-body);
}
.svc-lead strong { color: var(--text-primary); }
/* lead, który ma być PRZECZYTANY: większy i jaśniejszy (uwaga G Karola) */
.svc-lead--strong, .svc-lead--hero {
  font-size: clamp(17px, 1.4vw, 20px);
  line-height: 1.58;
  color: var(--color-alpha-white-80, rgba(255, 255, 255, .8));
}
.svc-lead--hero { margin-top: 22px; }
.svc-center { text-align: center; }
.svc-center .svc-lead { margin-inline: auto; }
.svc-cta-row { margin-top: 32px; display: flex; gap: 14px; flex-wrap: wrap; align-items: center; }
.svc-center .svc-cta-row, .svc-cta-row.svc-center { justify-content: center; }
.svc-note {
  margin-top: 14px;
  font-size: 14px;
  color: var(--text-body);
}
/* CTA: bez ciężkiej poświaty — czytelny przycisk (uwaga B5 Karola) */
.svc .btn--primary { box-shadow: 0 10px 26px -12px rgba(255, 44, 44, .5); }
.svc .btn--primary:hover { box-shadow: 0 12px 30px -12px rgba(255, 44, 44, .6); }

/* ----- Wejścia przy przewijaniu (odpowiednik AOS fade-up) -----
   Stan „ukryte przed animacją" TYLKO gdy działa JavaScript (html.js) —
   roboty Google i przeglądarki bez JS widzą pełną treść od razu.

   🔴 06.08.2026 — CIĘŻARY. Karol o /ai-search/: „animacje nie mają ciężarów,
   nie są smooth". Pomiar potwierdził: 19 z 27 elementów wchodziło w TYM SAMYM
   momencie (opóźnienie 0), wszystkie przez te same 700 ms i tę samą drogę 26 px
   — niezależnie od tego, czy to jednowierszowy przycisk, czy panel wysoki na 976 px.
   Tak wygląda suwak, a nie ruch przedmiotów o różnej masie.

   Lekarstwo (to samo, co zadziałało na /audyt-ai-search/: 300 / 520 / 760 ms):
   czas dojścia i długość drogi zależą od WYSOKOŚCI elementu. Wysokość, nie
   powierzchnia — bo pełnej szerokości nagłówek wysoki na 52 px jest lekki,
   choć zajmuje szeroki pas. Progi wzięte z pomiaru wszystkich 27 elementów:
     ≤ 200 px → lekki  (10 elementów), 200–500 px → średni (11), > 500 px → ciężki (6).
   Ruch zostaje w pionie i w głąb — na tej stronie nic nie jeździ w bok.

   🔴🔴 06.08.2026 WIECZOREM — DRUGIE PODEJŚCIE. Karol po pierwszym: „słabizna,
   w referencji mamy o wiele lepsze animacje, bardziej smooth". Pomiar obu stron
   obalił WSZYSTKIE trzy hipotezy, na których stało pierwsze podejście:
     · „stara ma więcej ruchu w tle" — ODWROTNIE. Przy nieruchomej stronie ruszało się
       2,1% obrazu na starej i 9,7% na nowej.
     · „stara odpala wejścia wcześniej" — NIE. Obie zaczynają, gdy górna krawędź jest
       ~820 px od góry okna (okno 900 px). Ten sam moment.
     · „kaskada jest za rzadka" — pierwsze podejście już to naprawiło (10 różnych opóźnień).
   PRAWDZIWA RÓŻNICA, nietknięta wcześniej: DŁUGOŚĆ DROGI. Na stronie-wzorcu KAŻDY
   z 14 elementów przejeżdża **100 px**; u nas 12 / 24 / 38 px — od 2,6 do 8 razy mniej.
   Przy takiej drodze nie widać dojścia, tylko rozjaśnienie w miejscu. Do tego wzorzec
   używa zwykłej krzywej `ease`, nie `cubic-bezier(.2,.7,.2,1)`.
   Odwzorowanie 1:1 ze wzorca: droga 100 px i krzywa `ease`. Trzy ciężary ZOSTAJĄ,
   ale różnicują już tylko CZAS (wzorzec ma 0,4 s — stąd 400 ms dla lekkich). */
html.js .svc [data-rv] {
  opacity: 0;
  transform: translateY(var(--rvy, 100px));
  transition: opacity var(--rvt, .4s) ease, transform var(--rvt, .4s) ease;
  transition-delay: var(--rvd, 0ms);
}
html.js .svc [data-rv].is-in { opacity: 1; transform: none; }

/* Trzy ciężary. Same zmienne — nie dokładają reguły ruchu, więc wyłączenie animacji
   przy ograniczonym ruchu (`transition: none` niżej w pliku) dalej wygrywa. */
.rv-lekki  { --rvt: 400ms; --rvy: 100px; }
.rv-sredni { --rvt: 500ms; --rvy: 100px; }
.rv-ciezki { --rvt: 620ms; --rvy: 100px; }

/* ============================================================================
   NAD ZGIĘCIEM BEZ CZEKANIA NA SKRYPT (18.08, czat G7 — szybkość).
   Pomiar Lighthouse: nagłówek hero czekał ~2,2 s, aż main.js wstanie i obserwator
   doda `.is-in` — a Google mierzy dokładnie ten element (LCP). Bezpośrednie
   dzieci siatki hero wchodzą więc czystym CSS-em od pierwszej klatki: ten sam
   ruch (droga --rvy, krzywa ease, ciężary --rvt, opóźnienia --rvd), tylko bez
   czekania na skrypt. Późniejsze `.is-in` od obserwatora niczego nie zmienia,
   bo stan końcowy jest identyczny.
   ⚠️ Celowo TYLKO pierwszy ekran (hero); reszta strony odsłania się jak dotąd,
   dopiero przy przewijaniu. */
html.js .svc .svc-hero__grid > [data-rv],
html.js .svc--case .cs2__herogrid > [data-rv] {
  opacity: 1;
  transform: none;
  transition: none;
  animation: rv-hero-wejscie var(--rvt, .5s) ease var(--rvd, 0ms) both;
}
@keyframes rv-hero-wejscie {
  from { opacity: 0; transform: translateY(var(--rvy, 100px)); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  html.js .svc .svc-hero__grid > [data-rv],
  html.js .svc--case .cs2__herogrid > [data-rv] { animation: none; }
}

/* ----- Okno produktu (wspólny wzorzec kart-okien) ----- */
.svc-win {
  position: relative;
  background: linear-gradient(180deg, var(--color-neutral-875), var(--color-neutral-925));
  border: 1px solid var(--border-default);
  border-radius: 20px;
  box-shadow: 0 50px 110px -50px rgba(0, 0, 0, .95);
}
.svc-win::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1px;
  background: linear-gradient(140deg, var(--accent-glow), transparent 34%, transparent 68%, var(--accent-glow));
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  opacity: .6;
  pointer-events: none;
}
.svc-win__bar {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 15px 18px;
  border-bottom: 1px solid var(--border-subtle);
}
.svc-win__dot { width: 9px; height: 9px; border-radius: 50%; background: var(--border-idle-dot); }
.svc-win__dot--red { background: var(--accent-default); }
.svc-win__label {
  margin-left: 6px;
  font-size: var(--type-size-xs);
  font-weight: 700;
  letter-spacing: .02em;
  color: var(--text-muted);
}
.svc-win__bar-end { margin-left: auto; display: flex; align-items: center; gap: 10px; }
.svc-win__body { padding: 18px; }

/* ----- Hero (układ 2 kolumny) ----- */
.svc-hero__grid {
  display: grid;
  grid-template-columns: 1.02fr .98fr;
  gap: clamp(32px, 4vw, 64px);
  align-items: center;
  padding-top: clamp(64px, 9vh, 110px);
}
/* Desktop: hero centruje się w pierwszym ekranie POD belką (patrz
   .svc-sec:first-of-type wyżej) — dodatkowy odstęp od belki niepotrzebny.
   Uwaga: ta reguła musi stać PO bazowej .svc-hero__grid (ta sama siła
   selektora — wygrywa późniejsza). */
@media (min-width: 1025px) {
  .svc-hero__grid { padding-top: 0; }
}

/* ==========================================================================
   Makieta wyników Google (SERP) — wspólna dla obu stron
   ========================================================================== */
.serp {
  background: var(--serp-bg);
  border-radius: 12px;
  padding: 14px;
  font-size: 13px;
}
.serp__search {
  display: flex;
  align-items: center;
  gap: 10px;
  background: #303134;
  border: 1px solid var(--serp-line);
  border-radius: 24px;
  padding: 9px 16px;
  color: #e8eaed;
  font-size: 14px;
  min-height: 40px;
}
.serp__search svg { width: 16px; height: 16px; flex: none; color: var(--serp-mut); }
.serp__q { white-space: nowrap; overflow: hidden; }
.serp__caret {
  display: inline-block;
  width: 2px;
  height: 1em;
  margin-left: 1px;
  vertical-align: -0.12em;
  background: var(--accent-default);
  animation: svcCaret .8s steps(1) infinite;
}
@keyframes svcCaret { 50% { opacity: 0; } }
.serp__row {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  padding: 10px 8px;
  border-radius: 10px;
}
.serp__fav {
  flex: none;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--fav, #303134);
  display: grid;
  place-items: center;
  font-size: 11px;
  font-weight: 700;
  color: var(--favc, var(--serp-mut));
}
/* favikony jak prawdziwe: mały znaczek SVG zamiast litery */
.serp__fav svg { width: 64%; height: 64%; display: block; }
.serp__fav--you { background: var(--accent-default); }
.serp__t { display: block; color: var(--serp-link); font-weight: 500; line-height: 1.3; }
.serp__u { display: block; font-size: 12px; color: var(--serp-mut); margin-top: 1px; }
.serp__d { font-size: 12px; color: var(--serp-txt); margin-top: 3px; line-height: 1.45; }

/* „Chrome" Google: logo G + pasek z ikonami + zakładki (hero SEO) */
.serp__bar { display: flex; align-items: center; gap: 12px; }
.serp__g { width: 26px; height: 26px; flex: none; }
.serp__bar .serp__search { flex: 1; min-width: 0; }
.serp__tools { margin-left: auto; display: flex; align-items: center; gap: 11px; flex: none; padding-left: 10px; border-left: 1px solid var(--serp-line); }
.serp__tools svg { width: 16px; height: 16px; display: block; }
.serp__tabs {
  display: flex;
  gap: 20px;
  margin-top: 8px;
  padding: 0 6px;
  border-bottom: 1px solid var(--serp-line);
  font-size: 12px;
  color: var(--serp-mut);
}
.serp__tabs span { padding: 3px 2px 8px; white-space: nowrap; }
.serp__tabs .is-act { color: var(--serp-link); box-shadow: inset 0 -2px 0 var(--serp-link); }
.serp__head { display: flex; align-items: center; gap: 8px; min-width: 0; }
.serp__site { display: flex; flex-direction: column; line-height: 1.25; font-size: 12px; color: #dadce0; min-width: 0; white-space: nowrap; }
.serp__site .serp__u { margin-top: 0; font-size: 10px; overflow: hidden; text-overflow: ellipsis; }
.serp__search--sm { min-height: 34px; padding: 7px 14px; font-size: 13px; border-radius: 20px; }
.serp__search--sm svg { width: 14px; height: 14px; }

/* nasz wynik — czerwona kropka przy marce */
.serp__row--you .serp__t { color: #fff; font-weight: 600; }
.serp__row--you { background: rgba(255, 44, 44, .07); border: 1px solid rgba(255, 44, 44, .35); }
.serp__you-dot {
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  margin-right: 7px;
  vertical-align: 2px;
  background: var(--accent-default);
  box-shadow: 0 0 9px 2px rgba(255, 44, 44, .55);
}

/* ==========================================================================
   SEO HERO — wspinaczka na pozycję 1
   ========================================================================== */
.climb { position: relative; }
.climb__list { --slot: 86px; position: relative; margin-top: 10px; height: calc(5 * var(--slot)); }
.climb__row {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 80px;
  transform: translateY(calc(var(--pos) * var(--slot)));
  transition: transform .6s var(--ease);
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 8px 12px;
  border-radius: 12px;
}
.climb__row > * { flex: none; }
.climb__row .serp__fav { width: 18px; height: 18px; font-size: 9px; }
.climb .serp__site { font-size: 11px; line-height: 1.2; }
.climb .serp__site .serp__u { font-size: 10px; }
.climb .serp__t {
  margin-top: 2px;
  font-size: 13px;
  line-height: 1.4;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.climb .serp__d {
  margin-top: 1px;
  font-size: 12px;
  line-height: 1.4;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.climb__row--you {
  background: rgba(255, 44, 44, .07);
  border: 1px solid rgba(255, 44, 44, .35);
  z-index: 2;
}
.climb__row--you .serp__t { color: #fff; font-weight: 600; }
.climb__row--you.is-top { box-shadow: 0 0 34px -6px rgba(255, 44, 44, .55); }
.climb__badge {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 12px;
  padding: 7px 14px;
  border-radius: 30px;
  border: 1px solid rgba(255, 44, 44, .4);
  background: rgba(255, 44, 44, .08);
  font-size: 15px;
  font-weight: 700;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
}
.climb__badge svg { width: 13px; height: 13px; color: var(--color-red-400); }

/* ==========================================================================
   SEO — drabina kliknięć (rozkład CTR po pozycjach)
   ========================================================================== */
.ctr__grid {
  margin-top: 44px;
  display: grid;
  grid-template-columns: .9fr 1.1fr;
  gap: clamp(32px, 4vw, 72px);
  align-items: center;
}
.svc-big {
  font-size: clamp(92px, 12vw, 190px);
  font-weight: 600;
  line-height: .95;
  letter-spacing: -0.04em;
  color: var(--text-heading);
  font-variant-numeric: tabular-nums;
}
.svc-big .pct { font-size: .48em; color: var(--text-heading); }
.svc-big-sub {
  margin-top: 12px;
  font-size: clamp(16px, 1.3vw, 19px);
  line-height: 1.5;
  color: var(--text-body);
  max-width: 34ch;
}
.svc-big-sub strong { color: var(--text-primary); }
.svc-src {
  margin-top: 12px;
  font-size: 14px;
  color: var(--text-body);
}
.ladder { display: flex; flex-direction: column; gap: 7px; }
.ladder .serp__search--sm { margin-bottom: 4px; }
.ladder__cols {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 2px 2px 3px;
  font-size: 14px;
  font-weight: 600;
  color: var(--text-body);
}
.ladder__row {
  display: grid;
  grid-template-columns: 26px 112px 1fr 64px;
  gap: 12px;
  align-items: center;
}
.ladder__pos {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  border: 1px solid var(--border-default);
  display: grid;
  place-items: center;
  font-size: 13px;
  font-weight: 700;
  color: var(--text-body);
  font-variant-numeric: tabular-nums;
}
.ladder__row--top .ladder__pos {
  border-color: rgba(255, 44, 44, .5);
  background: rgba(255, 44, 44, .09);
  color: var(--color-red-400);
}
/* szkielet wyniku Google: favicona + dwie linie tekstu (schemat, nie treść) */
.ladder__ghost { position: relative; height: 28px; }
.ladder__ghost i { position: absolute; display: block; border-radius: 4px; }
.ladder__fav {
  width: 14px;
  height: 14px;
  left: 0;
  top: 7px;
  border-radius: 50%;
  background: rgba(255, 255, 255, .16);
}
.ladder__l--1 { left: 22px; top: 5px; height: 6px; width: 76%; max-width: 84px; background: rgba(255, 255, 255, .22); }
.ladder__l--2 { left: 22px; top: 17px; height: 5px; width: 50%; max-width: 56px; background: rgba(255, 255, 255, .10); }
.ladder__row--top .ladder__l--1 { background: rgba(255, 255, 255, .34); }
.ladder__track {
  position: relative;
  height: 26px;
  border-radius: 7px;
  background: var(--color-alpha-white-04);
  border: 1px solid var(--border-subtle);
  overflow: hidden;
}
.ladder__fill {
  position: absolute;
  inset: 0;
  border-radius: 6px;
  transform-origin: left center;
  transform: scaleX(var(--sx));
  transition: transform 1s var(--ease);
  transition-delay: var(--d, 0ms);
  background: linear-gradient(90deg, rgba(255, 255, 255, .38), rgba(255, 255, 255, .16));
}
.ladder__row--top .ladder__fill { background: linear-gradient(90deg, rgba(255, 44, 44, .9), rgba(255, 44, 44, .45)); }
/* bez JS słupki od razu pełne; z JS chowamy do startu animacji */
html.js .svc .ladder:not(.is-in) .ladder__fill { transform: scaleX(0); }
.ladder__pct {
  font-size: 15px;
  font-weight: 600;
  color: var(--text-body);
  font-variant-numeric: tabular-nums;
}
.ladder__row--top .ladder__pct { color: var(--text-primary); font-weight: 700; }
.ladder__break {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 10px;
  font-size: 13px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text-body);
}
.ladder__break::before, .ladder__break::after {
  content: "";
  height: 1px;
  flex: 1;
  background: var(--border-subtle);
}
.ladder__p2 {
  margin-top: 8px;
  text-align: center;
  color: var(--text-body);
  font-size: 15px;
}
.ladder__p2 strong { color: var(--text-primary); font-variant-numeric: tabular-nums; }

/* ==========================================================================
   Karty korzyści („Co zyskujesz")
   ========================================================================== */
.gain {
  margin-top: 44px;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
}
.gain__card {
  background: linear-gradient(180deg, var(--surface-raised), var(--surface-sunken));
  border: 1px solid var(--border-card);
  border-radius: 24px;
  padding: 30px;
  transition: transform .25s ease, border-color .25s ease;
}
.gain__card:hover { transform: translateY(-4px); border-color: var(--border-accent); }
.gain__num {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .16em;
  color: var(--color-red-400);
  font-variant-numeric: tabular-nums;
}
.gain__card h3 {
  margin-top: 12px;
  font-size: clamp(22px, 1.9vw, 28px);
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--text-primary);
}
.gain__card p { margin-top: 12px; font-size: 15px; line-height: 1.62; color: var(--text-body); }
.gain__card p + p { margin-top: 10px; }
.gain__card p strong { color: var(--text-primary); }

/* SEO: mini-wizualizacje na kartach korzyści (stała wysokość = zero skoków układu) */
.gain__viz {
  min-height: 118px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: 9px;
  padding-bottom: 16px;
  margin-bottom: 16px;
  border-bottom: 1px solid var(--border-subtle);
}
.gain__query {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  background: #303134;
  border: 1px solid var(--serp-line);
  border-radius: 24px;
  padding: 9px 16px;
  font-size: 15px;
  color: #e8eaed;
}
.gain__query svg { width: 15px; height: 15px; flex: none; color: var(--serp-mut); }
.gain__viz-note { font-size: 14px; line-height: 1.45; color: var(--text-body); }
.gain__stat {
  font-size: clamp(34px, 3vw, 44px);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1;
  color: var(--text-heading);
  font-variant-numeric: tabular-nums;
}
.gain__chip {
  font-size: 13px;
  font-weight: 700;
  border: 1px solid var(--border-default);
  border-radius: 30px;
  padding: 5px 12px;
  color: var(--text-primary);
}
/* karta „Pokrycie całego lejka": trzy zapytania zwężające się jak lejek */
.gain__viz--funnel { align-items: flex-start; gap: 7px; }
.gain__fq {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  width: var(--fw, 100%);
  min-width: 0;
  background: #303134;
  border: 1px solid var(--serp-line);
  border-radius: 24px;
  padding: 6px 13px;
  font-size: 13px;
  color: #e8eaed;
  white-space: nowrap;
  overflow: hidden;
}
.gain__fq svg { width: 13px; height: 13px; flex: none; color: var(--serp-mut); }
.gain__fq em { font-style: normal; color: var(--serp-mut); font-size: 12px; margin-left: auto; padding-left: 8px; }
.gain__fq--hot { border-color: rgba(255, 44, 44, .45); background: rgba(255, 44, 44, .10); }
/* karta „Zoptymalizowana strona": pasek okna + potwierdzone obszary techniczne */
.gain__viz--site { align-items: flex-start; gap: 10px; }
.gain__site-bar {
  display: flex;
  gap: 5px;
  align-items: center;
  width: 100%;
  max-width: 260px;
  padding: 8px 11px;
  border: 1px solid var(--border-subtle);
  border-radius: 10px;
  background: var(--color-alpha-white-03);
}
.gain__site-bar i { width: 8px; height: 8px; border-radius: 50%; background: var(--border-idle-dot); }
.gain__site-bar i:first-child { background: var(--accent-default); }
.gain__checks { display: flex; flex-wrap: wrap; gap: 7px; }
.gain__checks em {
  font-style: normal;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 13px;
  font-weight: 600;
  color: var(--text-primary);
  border: 1px solid var(--border-default);
  border-radius: 30px;
  padding: 5px 12px;
}
/* znaczniki wyboru ZAWSZE białe — czerwony check czyta się jak ostrzeżenie (reguła Karola 11.07) */
.gain__checks em svg { width: 14px; height: 14px; color: #fff; }
/* karta „Wiesz, co zarabia" (Google Ads): mini-raport wydatek → efekt */
.gain__viz--rep { align-items: stretch; gap: 7px; }
.gain__rep {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 7px 12px;
  border: 1px solid var(--border-subtle);
  border-radius: 10px;
  background: var(--color-alpha-white-03);
}
.gain__rep em { font-style: normal; font-size: 13px; color: var(--text-body); }
.gain__rep strong { font-size: 15px; font-weight: 700; color: var(--text-primary); font-variant-numeric: tabular-nums; white-space: nowrap; }
.gain__rep--hot { border-color: rgba(255, 44, 44, .45); background: rgba(255, 44, 44, .08); }
/* karta „Największa dźwignia": stały koszt (przerywana) vs rosnący zwrot (czerwona) */
.gain__viz--roi { align-items: stretch; gap: 10px; }
.gain__viz--roi svg { width: 100%; height: 58px; display: block; }
.gain__roi-legend { display: flex; flex-wrap: wrap; gap: 6px 16px; font-size: 13px; color: var(--text-body); }
.gain__roi-legend em { font-style: normal; display: inline-flex; align-items: center; gap: 7px; }
.gain__roi-legend i { width: 16px; border-top: 2px solid var(--border-idle-dot); }
.gain__roi-legend .is-cost i { border-top-style: dashed; }
.gain__roi-legend .is-gain i { border-top-color: var(--accent-default); }

/* ==========================================================================
   Proces — 8 kroków w 2 grupach, akordeon
   ========================================================================== */
.proc {
  margin-top: 44px;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 24px;
  align-items: start;
}
.proc__group {
  background: var(--surface-overlay);
  border: 1px solid var(--border-subtle);
  border-radius: 24px;
  padding: 22px;
}
.proc__hint { margin: 12px 4px 6px; font-size: 15px; line-height: 1.55; color: var(--text-body); }

/* Dwa etapy współpracy — strzałka między kolumnami (wzorzec z SEO, od 11.07
   wspólny dla wszystkich podstron usługowych) */
.svc .proc { grid-template-columns: 1fr auto 1fr; }
.proc__stage {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 16px;
  font-weight: 700;
  color: var(--text-primary);
}
.proc__arrow {
  align-self: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 1px solid var(--border-default);
  background: var(--surface-overlay);
  display: grid;
  place-items: center;
  color: var(--color-red-400);
}
.proc__arrow svg { width: 18px; height: 18px; }
.proc__item { border-bottom: 1px solid var(--border-subtle); }
.proc__item:last-child { border-bottom: none; }
.proc__item > button { display: block; width: 100%; }
.proc__btn {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 16px 12px;
  text-align: left;
  border-radius: 10px;
}
.proc__title { font-size: 17px; font-weight: 600; color: var(--text-primary); }
.proc__chev { margin-left: auto; flex: none; width: 12px; height: 8px; color: var(--text-muted); transition: transform .3s var(--ease); }
.proc__item.is-open .proc__chev { transform: rotate(180deg); color: var(--color-red-400); }
.proc__panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows .35s var(--ease);
}
.proc__item.is-open .proc__panel { grid-template-rows: 1fr; }
.proc__panel-inner { overflow: hidden; }
.proc__panel p {
  padding: 0 12px 18px 39px;
  font-size: 15px;
  line-height: 1.62;
  color: var(--text-body);
}
.proc__item.is-open .proc__btn { background: var(--color-alpha-white-03); }
.proc__loop {
  margin-top: 16px;
  padding: 14px 4px 2px;
  border-top: 1px dashed var(--border-default);
  display: flex;
  align-items: center;
  gap: 9px;
  font-size: 13px;
  color: var(--text-body);
}
.proc__loop svg { width: 14px; height: 14px; flex: none; color: var(--color-red-400); }

/* Mocniejsza ekspozycja kroków procesu (uwagi Karola 10.07) — każdy krok
   w osobnej jasnej ramce, teksty rozjaśnione. Od 11.07 wzorzec wspólny
   dla wszystkich podstron usługowych. */
.svc .proc__group {
  padding: 26px;
  border: 1px solid rgba(255, 255, 255, .30);
  background: rgba(255, 255, 255, .04);
  box-shadow: 0 24px 60px -32px rgba(0, 0, 0, .8);
}
.svc .proc__hint { margin: 14px 4px 18px; color: rgba(255, 255, 255, .88); }
.svc .proc__item {
  border: 1px solid rgba(255, 255, 255, .16);
  border-radius: 14px;
  background: rgba(255, 255, 255, .06);
  margin-top: 10px;
  overflow: hidden;
  transition: border-color .25s ease;
}
.svc .proc__item.is-open { border-color: rgba(255, 44, 44, .55); }
.svc .proc__btn { padding: 16px 18px; border-radius: 0; }
.svc .proc__item.is-open .proc__btn { background: transparent; }
.svc .proc__title { font-size: 17px; color: #fff; }
.svc .proc__chev { color: var(--text-body); }
.svc .proc__panel p { padding: 0 18px 18px 18px; color: rgba(255, 255, 255, .88); }
.svc .proc__stage { font-size: 17px; color: #fff; }

/* Anty-sierotka GLOBALNIE (uwaga Karola 10.07 ×2): żaden akapit ani nagłówek
   nie może kończyć się pojedynczym słowem w ostatniej linijce.
   balance = równe linijki (nagłówki/podpisy), pretty = przeglądarka unika
   sierotki w zwykłych akapitach. */
.svc h1, .svc h2, .svc h3, .svc-center .svc-lead { text-wrap: balance; }
.svc p, .svc li { text-wrap: pretty; }

/* ==========================================================================
   SEO — wykres „procent składany"
   ========================================================================== */
.grow__grid {
  margin-top: 44px;
  display: grid;
  grid-template-columns: .92fr 1.08fr;
  gap: clamp(32px, 4vw, 64px);
  align-items: center;
}
/* wykres bez wewnętrznych odstępów — pozycje %-owe kamieni milowych trafiają
   DOKŁADNIE w układ współrzędnych SVG (uwaga Karola 09.07: kropki na krzywej) */
.grow__chart { position: relative; padding: 0; margin-top: 26px; }
.grow__chart svg { display: block; width: 100%; height: auto; position: relative; z-index: 1; }
/* słupki: każdy miesiąc dokłada „cegiełkę" pod krzywą */
.grow__bars {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: flex-end;
  gap: 4px;
  padding: 0 2px;
}
.grow__bars span {
  flex: 1;
  height: var(--h);
  background: linear-gradient(180deg, rgba(255, 255, 255, .07), rgba(255, 255, 255, .02));
  border-radius: 4px 4px 0 0;
  transform: scaleY(1);
  transform-origin: bottom;
  transition: transform .8s var(--ease);
  transition-delay: var(--d, 0ms);
}
/* bez JS wykres od razu pełny; z JS słupki rosną przy wejściu na sekcję */
html.js .svc .grow:not(.is-in) .grow__bars span { transform: scaleY(0); }
/* kamienie milowe: kropka NA krzywej + pionowa linia + dymek nad nią (chorągiewka) */
.grow__ms {
  position: absolute;
  z-index: 2;
  left: var(--x);
  bottom: var(--y);
  width: 0;
  height: 0;
  transition: opacity .6s var(--ease), transform .6s var(--ease);
  transition-delay: var(--d, 0ms);
}
html.js .svc .grow:not(.is-in) .grow__ms { opacity: 0; transform: translateY(8px); }
.grow__ms::before {
  content: "";
  position: absolute;
  left: -0.5px;
  bottom: 4px;
  width: 1px;
  height: var(--line, 34px);
  background: linear-gradient(0deg, rgba(255, 44, 44, .5), rgba(255, 44, 44, .12));
}
.grow__ms i {
  position: absolute;
  left: -5px;
  bottom: -5px;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: #0f0f12;
  border: 2px solid var(--accent-default);
  box-shadow: 0 0 10px 1px rgba(255, 44, 44, .4);
}
.grow__ms span {
  position: absolute;
  left: 0;
  bottom: calc(var(--line, 34px) + 8px);
  transform: translateX(var(--shift, -50%));
  white-space: nowrap;
  text-align: center;
  background: rgba(10, 10, 12, .96);
  border: 1px solid var(--color-alpha-white-15, rgba(255, 255, 255, .15));
  border-radius: 10px;
  padding: 8px 13px;
  font-size: 13px;
  line-height: 1.45;
  color: var(--text-body);
  box-shadow: 0 10px 26px -10px rgba(0, 0, 0, .8);
}
.grow__ms span strong { display: block; color: var(--text-primary); font-size: 13px; }
.grow__ms--end::before { display: none; }
/* dymek 24. miesiąca: na lewo od kropki, w pustce NAD krzywą (nie na wykresie) —
   nad kropką nie ma miejsca, bo krzywa kończy się przy górnej krawędzi okna */
.grow__ms--end span { left: auto; right: 14px; bottom: -10px; transform: none; text-align: right; }
/* etykiety miesięcy dokładnie pod swoimi punktami na osi (nie „na oko") */
.grow__months {
  position: relative;
  height: 22px;
  margin-top: 9px;
  font-size: 13px;
  letter-spacing: .06em;
  color: var(--text-body);
  font-variant-numeric: tabular-nums;
}
.grow__months span { position: absolute; left: var(--mx); transform: translateX(-50%); }
.grow__months span:first-child { transform: translateX(-12px); }
/* mobilna wersja kamieni milowych (na desktopie ukryta — tam są dymki na krzywej) */
.grow__mob { display: none; }

/* ==========================================================================
   Etykieta „Sponsorowane" w makietach wynikow (uzywana przez /performance-marketing/)
   ========================================================================== */
.adsw__tag {
  display: inline-block;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .06em;
  color: #e8eaed;
  border: 1px solid var(--serp-line);
  border-radius: 4px;
  padding: 1px 6px;
  margin-bottom: 4px;
}

/* ==========================================================================
   Efekty naszej pracy — karty wyników
   ========================================================================== */
.res {
  margin-top: 44px;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
}
.res-card {
  display: flex;
  flex-direction: column;
  background: linear-gradient(180deg, var(--surface-raised), var(--surface-sunken));
  border: 1px solid var(--border-card);
  border-radius: 24px;
  padding: 28px;
  transition: transform .25s ease, border-color .25s ease;
}
a.res-card:hover { transform: translateY(-4px); border-color: var(--border-accent); }
.res-card__tag {
  align-self: flex-start;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--text-muted);
  border: 1px solid var(--border-subtle);
  border-radius: 30px;
  padding: 4px 11px;
}
/* widoczna nazwa strony klienta, której dotyczy historia (uwaga H1 Karola) */
.res-card__site {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 14px;
  font-size: 15px;
  font-weight: 700;
  color: var(--text-primary);
}
.res-card__site i {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--accent-default);
  box-shadow: 0 0 8px 1px rgba(255, 44, 44, .5);
}
/* liczby wyników BIAŁE — czerwień kojarzy się ze spadkiem (uwaga H2 Karola) */
.res-card__num {
  margin-top: 10px;
  font-size: clamp(40px, 3.6vw, 56px);
  font-weight: 700;
  letter-spacing: -0.03em;
  color: var(--text-heading);
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
.res-card__num small { font-size: .5em; font-weight: 600; }
.res-card__num--sm { font-size: clamp(24px, 2.2vw, 34px); line-height: 1.18; letter-spacing: -0.01em; }
.res-card__what { margin-top: 7px; font-size: 15px; font-weight: 600; color: var(--text-primary); }
.res-card__spark { margin-top: 16px; width: 100%; height: 54px; display: block; }
.res-card__ba {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 7px;
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--border-subtle);
  font-size: 15px;
  color: var(--text-body);
  font-variant-numeric: tabular-nums;
}
.res-card__ba span { font-weight: 700; color: var(--text-primary); }
.res-card__ba svg { width: 14px; height: 14px; color: var(--accent-default); }
.res-card p { margin-top: 12px; font-size: 15px; line-height: 1.55; color: var(--text-body); }
.res-card__link {
  margin-top: auto;
  padding-top: 18px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 15px;
  font-weight: 700;
  color: var(--text-primary);
}
.res-card__link svg { width: 15px; height: 15px; color: var(--accent-default); }

/* ==========================================================================
   FAQ — akordeon
   ========================================================================== */
.faq { margin-top: 40px; max-width: 860px; margin-inline: auto; display: flex; flex-direction: column; gap: 12px; }
.faq__item {
  background: var(--color-neutral-900);
  border: 1px solid var(--border-subtle);
  border-radius: 16px;
  transition: border-color .3s ease;
}
.faq__item.is-open { border-color: rgba(255, 44, 44, .4); }
.faq__q {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 19px 22px;
  text-align: left;
  font-size: 17px;
  font-weight: 600;
  color: var(--text-primary);
}
.faq__q svg { margin-left: auto; flex: none; width: 13px; height: 9px; color: var(--text-muted); transition: transform .3s var(--ease); }
.faq__item.is-open .faq__q svg { transform: rotate(180deg); color: var(--color-red-400); }
.faq__a {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows .35s var(--ease);
}
.faq__item.is-open .faq__a { grid-template-rows: 1fr; }
.faq__a-inner { overflow: hidden; }
.faq__a p { padding: 0 22px 20px; font-size: 15px; line-height: 1.65; color: var(--text-body); }
.faq__a a { color: var(--text-accent); text-decoration: underline; text-underline-offset: 3px; }
/* zaproszenie pod listą pytań — jedno duże CTA */
.faq__more { margin-top: 36px; display: flex; justify-content: center; }
.faq__more .btn { padding: 20px 40px; font-size: 1.06em; }

/* ==========================================================================
   Finał — panel audytu + formularz + ścieżka 5 kroków
   ========================================================================== */
.audit {
  position: relative;
  border-radius: 26px;
  border: 1px solid var(--border-default);
  background: linear-gradient(180deg, #1a1a20, #0c0c0f);
  padding: clamp(28px, 3.4vw, 52px);
  overflow: hidden;
}
.audit::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: -220px;
  width: 640px;
  height: 340px;
  transform: translateX(-50%);
  background: radial-gradient(closest-side, rgba(255, 44, 44, .34), transparent);
  filter: blur(60px);
  pointer-events: none;
}
.audit__grid {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: 1.02fr .98fr;
  gap: clamp(28px, 3.5vw, 56px);
  /* `stretch` zamiast `start` (06.08): lewa kolumna dostaje wysokość całego rzędu,
     żeby wolne miejsce dało się rozdać niżej — bez tego kończyła się nad formularzem. */
  align-items: stretch;
}
/* Lewa kolumna jako słup. DWA zachowania, zależnie od tego, czy stoi w niej blok
   „człowiek, nie automat":
   — Z BLOKIEM: lista zjada nadmiar wysokości (`margin-bottom: auto`), więc blok siada
     na tej samej linii, co dno formularza (tak jest od 06.08 rano na ośmiu podstronach).
   — BEZ BLOKU: wolne miejsce rozkłada się PO RÓWNO nad treścią i pod nią — prośba Karola
     z 06.08 wieczorem („»Odbierz bezpłatny audyt SEO / Dowiesz się…« do wyśrodkowania").
   ⚠️ `justify-content: center` w kolumnie elastycznej centruje w PIONIE; w siatce znaczy
   co innego — dlatego reguła siedzi na kolumnie, a nie na `.audit__grid`. */
.audit__grid > :first-child { display: flex; flex-direction: column; }
.audit__grid > :first-child:has(.audit__human) > .audit__list { margin-bottom: auto; }
.audit__grid > :first-child:not(:has(.audit__human)) { justify-content: center; }
.audit__list { margin-top: 22px; display: flex; flex-direction: column; gap: 13px; }
.audit__list li { display: flex; gap: 12px; align-items: flex-start; font-size: 15px; line-height: 1.55; color: var(--text-body); }
/* znaczniki listy białe — czerwony check czyta się jak ostrzeżenie (reguła Karola 11.07) */
.audit__list svg { flex: none; width: 19px; height: 19px; margin-top: 2px; color: #fff; }
.audit__list strong { color: var(--text-primary); }
.audit__form { display: flex; flex-direction: column; gap: 13px; }
.audit__form .field { max-width: none; background: var(--color-alpha-white-04); }
.audit__form textarea.field { height: auto; min-height: 92px; padding: 12px 16px; resize: vertical; font-family: inherit; }
.audit__row { display: grid; grid-template-columns: 1fr 1fr; gap: 13px; }
.audit__form .btn { width: 100%; margin-top: 4px; }
.audit__rodo { font-size: 13px; line-height: 1.5; color: var(--text-body); }
.audit__done { padding: 22px 0; font-size: 17px; font-weight: 600; color: var(--text-primary); }
.audit__done span { color: var(--text-accent); }

/* ==========================================================================
   Finał w wersji z /kontakt/ (.aud2) — TYLKO /pozycjonowanie-stron/

   Karol 06.08 wieczorem: „przenieśmy tam formularz z kontaktu z rozpiską kroków,
   tylko bez zdjęcia Damiana i jego danych kontaktowych, a w to miejsce dajmy tytuł".

   Reguły przepisane 1:1 z `.kt-hero__*` i `.kt-time*` w content.css. Kopia, a nie
   wspólny plik, bo content.css NIE jest wczytywany na podstronach usługowych —
   wczytanie go tutaj ściągnęłoby style bloga, case study i /kontakt/ na stronę,
   która ich nie potrzebuje.
   ⚠️ Przy zmianie wyglądu na /kontakt/ trzeba poprawić OBA miejsca. Gdy układ
   wejdzie na wszystkie dziewięć podstron, warto scalić to z `.audit`.

   Różnice względem wzorca (świadome, obie z prośby Karola):
     — pasek u góry karty nie ma zdjęcia ani danych osoby, tylko tytuł sekcji,
     — nad kartą nie stoi osobny tytuł podstrony (na /kontakt/ „Zarezerwuj spotkanie").
   ========================================================================== */
.aud2 {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(320px, 1fr);
  grid-template-areas:
    "panel proctitle"
    "panel steps";
  grid-template-rows: auto 1fr;
  column-gap: clamp(32px, 3.5vw, 56px);
  row-gap: clamp(18px, 2.6vh, 28px);
  align-items: start;
}
/* Szklana karta z formularzem — wartości 1:1 z `.kt-hero__panel`. */
.aud2__panel {
  grid-area: panel;
  border: 1px solid var(--border-default, rgba(255, 255, 255, 0.16));
  border-radius: 24px;
  background: rgba(255, 255, 255, 0.06);
  backdrop-filter: blur(10px);
  box-shadow: 0 40px 90px rgba(0, 0, 0, 0.45);
  padding: clamp(24px, 2.4vw, 34px);
}
/* Pasek u góry karty — na /kontakt/ stoi tu zdjęcie i dane Damiana. Kreska pod spodem
   i odstępy zostają te same, żeby karta miała ten sam rytm co wzorzec. */
.aud2__top {
  padding-bottom: clamp(18px, 2.4vh, 24px);
  margin-bottom: clamp(20px, 2.6vh, 26px);
  border-bottom: 1px solid var(--border-subtle, rgba(255, 255, 255, 0.1));
}
.svc .aud2__h {
  margin: 0;
  font-size: var(--skala-h2);
  font-weight: 700;
  line-height: 1.12;
  letter-spacing: -0.02em;
  color: #fff;
  text-wrap: balance;
}
/* Nagłówek osi kroków. Wyściółka od góry równa wyściółce karty obok — dzięki temu oba
   tytuły zaczynają się na tej samej wysokości, mimo że jeden stoi w karcie, a drugi poza nią. */
.svc .aud2__proc-h {
  grid-area: proctitle;
  margin: 0;
  padding-top: clamp(24px, 2.4vw, 34px);
  font-size: var(--skala-grupa);
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -0.015em;
  color: #fff;
  max-width: 38ch;
  text-wrap: balance;
}
.aud2__proc { grid-area: steps; min-width: 0; }
.aud2__time { list-style: none; margin: 0; padding: 0; }
.aud2__step {
  position: relative;
  display: grid;
  grid-template-columns: 52px minmax(0, 1fr);
  gap: 20px;
  padding-bottom: clamp(36px, 5vh, 56px);
}
.aud2__step:last-child { padding-bottom: 0; }
/* oś łącząca — od dołu numeru do następnego węzła; przy ostatnim znika */
.aud2__step::before {
  content: "";
  position: absolute;
  left: 25px;
  top: 52px;
  bottom: -2px;
  width: 2px;
  background: linear-gradient(to bottom, rgba(255, 44, 44, 0.45), rgba(255, 255, 255, 0.07));
}
.aud2__step:last-child::before { display: none; }
.aud2__no {
  position: relative;
  z-index: 1;
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  border: 1px solid rgba(255, 44, 44, 0.4);
  background: #101014;
  font-family: var(--type-family-display), "Zalando Sans", "DM Sans", sans-serif;
  font-weight: 900;
  font-size: 1.25rem;
  color: #fff;
  font-variant-numeric: tabular-nums;
}
.aud2__body { padding-top: 0; min-width: 0; }
.svc .aud2__step-h { margin: 0 0 8px; color: #fff; font-size: 1.1875rem; font-weight: 600; line-height: 1.25; letter-spacing: -0.01em; }
.svc .aud2__step-t { margin: 0; color: var(--text-body, rgba(255, 255, 255, 0.8)); font-size: 0.9375rem; line-height: 1.6; max-width: none; text-wrap: pretty; }

/* Tablet i telefon: jedna kolumna w kolejności karta → tytuł kroków → kroki. */
@media (max-width: 1000px) {
  .aud2 {
    grid-template-columns: 1fr;
    grid-template-areas:
      "panel"
      "proctitle"
      "steps";
    grid-template-rows: auto auto auto;
    row-gap: clamp(20px, 3.2vh, 34px);
  }
  .svc .aud2__proc-h { padding-top: 0; margin: 0 0 clamp(16px, 2.6vh, 24px); }
  .svc .aud2__step-t { max-width: 62ch; }
  .aud2__step { padding-bottom: clamp(26px, 4vh, 40px); }
}

/* ścieżka „co się wydarzy po wysłaniu" */
.path {
  position: relative;
  z-index: 1;
  margin-top: clamp(28px, 3.4vw, 44px);
  padding-top: clamp(22px, 2.6vw, 32px);
  border-top: 1px solid var(--border-subtle);
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 14px;
}
/* kropka wyśrodkowana nad tekstem kroku (uwaga Karola 09.07), linia biegnie pod kropkami */
.path__step { position: relative; padding-top: 30px; text-align: center; }
.path__step::before {
  content: "";
  position: absolute;
  top: 8px;
  left: 50%;
  right: -50%;
  height: 1px;
  background: var(--border-subtle);
}
.path__step:last-child::before { display: none; }
.path__dot {
  position: absolute;
  top: 0;
  left: 50%;
  margin-left: -8.5px;
  width: 17px;
  height: 17px;
  border-radius: 50%;
  border: 1px solid var(--border-default);
  background: var(--color-neutral-900);
  /* box-shadow zdjęty z przejścia — poświatą steruje teraz klatkowanie `path-dojazd`,
     żeby dało się zrobić błysk w chwili dojazdu i dopiero po nim stan spoczynkowy. */
  transition: border-color .5s ease, background .5s ease;
}
/* Dojazd do kropki (Karol 06.08: „jak dojeżdża do kropki to ma być wyraźny efekt glow,
   większe światło"): krótki mocny błysk, po nim stała poświata — wyraźnie silniejsza
   niż wcześniejsze `0 0 12px 2px rgba(255,44,44,.45)`. */
.path__step.is-on .path__dot {
  border-color: var(--accent-default);
  background: var(--accent-default);
  box-shadow: 0 0 26px 7px rgba(255, 44, 44, .58), 0 0 9px 2px rgba(255, 150, 150, .55);
  animation: path-dojazd 700ms cubic-bezier(.2, .7, .2, 1) both;
}
@keyframes path-dojazd {
  0%   { box-shadow: 0 0 0 0 rgba(255, 44, 44, 0), 0 0 0 0 rgba(255, 150, 150, 0); }
  34%  { box-shadow: 0 0 44px 15px rgba(255, 44, 44, .92), 0 0 15px 4px rgba(255, 195, 195, .95); }
  100% { box-shadow: 0 0 26px 7px rgba(255, 44, 44, .58), 0 0 9px 2px rgba(255, 150, 150, .55); }
}
/* Ograniczony ruch: TYLE SAMO klas, co reguła grająca — inaczej przegrywa i błysk gra dalej. */
@media (prefers-reduced-motion: reduce) {
  .path__step.is-on .path__dot { animation: none !important; transition: none !important; }
}
.path__step.is-on::before { background: rgba(255, 44, 44, .4); }
.path__t { font-size: 15px; font-weight: 700; color: var(--text-primary); }
.path__d { margin-top: 5px; font-size: 15px; line-height: 1.5; color: var(--text-body); }

/* ==========================================================================
   Telefon z feedem (baza: .phone/.feed/.fpost) — używany przez hero
   /performance-marketing/ (.mchan). Reklama „ożywa": serduszka, licznik
   polubień, przycisk Kup teraz robi się czerwony. Na mobile/reduced
   i bez JS: od razu stan końcowy.
   ========================================================================== */
.phone {
  width: min(320px, 100%);
  margin: 0 auto;
  border: 1px solid var(--border-strong, rgba(255, 255, 255, .35));
  border-radius: 40px;
  background: #0a0a0c;
  padding: 10px;
  box-shadow: 0 30px 70px -30px rgba(0, 0, 0, .9);
}
.phone__screen { border-radius: 30px; overflow: hidden; background: #000; position: relative; }
.phone__notch {
  position: absolute;
  top: 7px;
  left: 50%;
  transform: translateX(-50%);
  width: 86px;
  height: 18px;
  border-radius: 12px;
  background: #0a0a0c;
  border: 1px solid rgba(255, 255, 255, .07);
  z-index: 3;
}
.phone__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 32px 14px 10px;
  font-weight: 700;
  font-size: 15px;
  color: #fff;
  border-bottom: 1px solid rgba(255, 255, 255, .08);
}
.phone__bar svg { width: 18px; height: 18px; color: #fff; opacity: .85; }
.feed { height: 438px; overflow: hidden; position: relative; }
.feed::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 46px;
  background: linear-gradient(0deg, #000, transparent);
  pointer-events: none;
}
.feed__track {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 10px 10px 16px;
  transform: translateY(var(--fy, 0px));
  transition: transform 1.6s cubic-bezier(.22, .61, .36, 1);
}
/* zatrzymujemy feed tak, żeby nad reklamą został skrawek poprzedniego posta —
   widać, że reklama siedzi MIĘDZY zwykłymi postami */
.fpost {
  flex: none;
  border: 1px solid rgba(255, 255, 255, .09);
  border-radius: 16px;
  background: #101013;
  overflow: hidden;
}
.fpost--ad { border-color: rgba(255, 255, 255, .14); transition: border-color .5s ease; }
.fpost__head { display: flex; align-items: center; gap: 9px; padding: 9px 11px; }
.fpost__ava { width: 26px; height: 26px; border-radius: 50%; flex: none; background: linear-gradient(135deg, #3b3b40, #232327); }
.fpost--ad .fpost__ava { background: radial-gradient(circle at 35% 30%, #ff5a5a, #a31212); }
.fpost__who { display: flex; flex-direction: column; line-height: 1.25; min-width: 0; }
.fpost__name { font-size: 13px; font-weight: 700; color: #fff; white-space: nowrap; }
.fpost__tag { font-size: 10px; color: #b9bcc4; letter-spacing: .02em; }
.fpost__img { height: 128px; position: relative; background: linear-gradient(160deg, #26262b, #151518); }
.fpost--ad .fpost__img { height: 148px; background: linear-gradient(150deg, #2a1518 0%, #1a1013 55%, #120d0e 100%); }
.fpost__img svg { position: absolute; inset: 0; margin: auto; width: 64px; height: 64px; color: rgba(255, 255, 255, .5); }
.fpost--ad .fpost__img svg { width: 74px; height: 74px; color: rgba(255, 255, 255, .8); }
.fpost__price {
  position: absolute;
  left: 10px;
  bottom: 10px;
  padding: 4px 10px;
  border-radius: 20px;
  background: rgba(0, 0, 0, .55);
  border: 1px solid rgba(255, 255, 255, .18);
  font-size: 12px;
  font-weight: 700;
  color: #fff;
  backdrop-filter: blur(4px);
}
.fpost__cta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 9px 12px;
  font-size: 13px;
  font-weight: 700;
  color: #fff;
  background: rgba(255, 255, 255, .06);
  border-top: 1px solid rgba(255, 255, 255, .08);
  transition: background .5s ease;
}
.fpost__cta svg { width: 13px; height: 13px; }
.fpost__actions {
  position: relative;
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 8px 11px 10px;
  font-size: 12px;
  color: #b9bcc4;
}
.fpost__actions svg { width: 15px; height: 15px; flex: none; }
.fpost__actions b { color: #fff; font-variant-numeric: tabular-nums; }
/* serduszka ulatujące znad ikony po „polubieniu" reklamy */
.fpost__hearts { position: absolute; left: 14px; top: 0; pointer-events: none; }
.fpost__hearts span {
  position: absolute;
  bottom: 0;
  width: 10px;
  height: 10px;
  opacity: 0;
  color: var(--accent-default);
}
.fpost__hearts span svg { width: 100%; height: 100%; fill: currentColor; }
@keyframes heartUp {
  0% { opacity: 0; transform: translateY(0) scale(.6); }
  18% { opacity: 1; }
  100% { opacity: 0; transform: translateY(-46px) scale(1.25); }
}

/* ----- Prowadzenie: ta sama kampania, dwa sposoby prowadzenia (okno z 2 wykresami).
       Stany „przed animacją" TYLKO pod html.js; bez JS i po animacji = stan końcowy.
       Okno ma stały rozmiar — rysują się wyłącznie linie (stroke-dashoffset). ----- */
.steer { max-width: 880px; margin: 44px auto 0; }
/* legenda jest kluczem do odczytania wykresów (uwaga Karola) — duża i jasna */
.steer__legend {
  display: flex;
  justify-content: center;
  gap: 28px;
  margin-bottom: 16px;
  font-size: 15px;
  font-weight: 600;
  color: var(--text-primary);
}
.steer__legend em { font-style: normal; display: inline-flex; align-items: center; gap: 9px; }
.steer__legend i { width: 24px; border-top: 2.5px dashed rgba(255, 255, 255, .8); }
.steer__legend .is-sale i { border-top: 3.5px solid var(--accent-default); }
.steer__grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.steer__col {
  border: 1px solid var(--border-subtle);
  border-radius: 16px;
  background: var(--color-alpha-white-03);
  padding: 18px 16px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.steer__col--hot { border-color: rgba(255, 44, 44, .45); background: rgba(255, 44, 44, .05); }
.steer__k { font-size: 15px; font-weight: 700; color: #fff; letter-spacing: .01em; }
.steer__chart { display: block; width: 100%; height: auto; }
.steer__ln { stroke-dasharray: 1; transition: stroke-dashoffset 1.3s var(--ease) .4s; }
.steer__ln--sale { transition-delay: .7s; }
.steer__fade { transition: opacity .8s ease .3s; }
.steer__x { transition: opacity .6s ease 1.9s; }
html.js .steer:not(.is-in) .steer__ln { stroke-dashoffset: 1; }
html.js .steer:not(.is-in) .steer__fade,
html.js .steer:not(.is-in) .steer__x { opacity: 0; }
.steer__note { font-size: 14px; line-height: 1.5; color: var(--text-body); margin-top: auto; }
.steer__note strong { color: var(--text-primary); }

/* ----- Droga jednego klienta w czasie (.jour): 4 przystanki, nad nimi szyna
       z kropką-klientem jadącą od wtorku do piątku; przystanki zapalają się,
       gdy kropka je mija. Stan bazowy (no-JS, reduced motion) = wszystko
       zapalone, kropka na końcu. Rozmiary stałe — animują się tylko kolory,
       transform wypełnienia szyny i pozycja kropki. ----- */
.jour { position: relative; margin-top: 64px; display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; }
/* kafel wyśrodkowany (uwaga Karola: treść dobita do lewej zostawiała pustą
   prawą stronę) — ikona, tytuł i opis w osi kafla, równo pod kropką szyny */
.jour__step {
  position: relative;
  border: 1px solid rgba(255, 44, 44, .5);
  border-radius: 18px;
  background: linear-gradient(180deg, var(--surface-raised), var(--surface-sunken));
  padding: 22px 18px;
  text-align: center;
  transition: border-color .5s ease, background .5s ease;
}
.jour__step::before {
  content: "";
  position: absolute;
  top: -24px;
  left: calc(50% - 5px);
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--accent-default);
  box-shadow: 0 0 10px rgba(255, 44, 44, .6);
  transition: background .5s ease, box-shadow .5s ease;
}
/* rozbłysk „zaliczenia przystanku" — pierścień rozchodzący się z kropki szyny,
   gdy dojeżdża do niej kropka-klient; czysty box-shadow, zero wpływu na układ */
.jour__step::after {
  content: "";
  position: absolute;
  top: -24px;
  left: calc(50% - 5px);
  width: 10px;
  height: 10px;
  border-radius: 50%;
  opacity: 0;
  pointer-events: none;
}
.jour.is-in .jour__step::after { animation: jourPing 1.15s ease-out forwards; }
.jour.is-in .jour__step:nth-child(1)::after { animation-delay: .5s; }
.jour.is-in .jour__step:nth-child(2)::after { animation-delay: 2.2s; }
.jour.is-in .jour__step:nth-child(3)::after { animation-delay: 3.9s; }
.jour.is-in .jour__step:nth-child(4)::after { animation-delay: 5.6s; }
@keyframes jourPing {
  0% { opacity: 1; background: #fff; box-shadow: 0 0 0 0 rgba(255, 44, 44, .9), 0 0 24px 8px rgba(255, 44, 44, .75); }
  100% { opacity: 0; background: rgba(255, 255, 255, 0); box-shadow: 0 0 0 27px rgba(255, 44, 44, 0), 0 0 34px 16px rgba(255, 44, 44, 0); }
}
/* mono ikony kanałów (uwaga Karola: cienkie kreski ginęły na czerwieni) */
.jour__ico {
  margin: 2px auto 0;
  width: 46px;
  height: 46px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--accent-default);
  background: var(--accent-default);
  color: #fff;
  transition: background .5s ease, border-color .5s ease;
}
.jour.is-in .jour__step:nth-child(1) .jour__ico { animation: jourPop .55s ease-out .5s both; }
.jour.is-in .jour__step:nth-child(2) .jour__ico { animation: jourPop .55s ease-out 2.2s both; }
.jour.is-in .jour__step:nth-child(3) .jour__ico { animation: jourPop .55s ease-out 3.9s both; }
.jour.is-in .jour__step:nth-child(4) .jour__ico { animation: jourPop .55s ease-out 5.6s both; }
@keyframes jourPop {
  0%, 100% { transform: scale(1); }
  45% { transform: scale(1.16); }
}
.jour__ico svg { width: 22px; height: 22px; }
.jour__t { margin-top: 14px; font-size: 17px; font-weight: 600; color: var(--text-primary); }
.jour__d { margin-top: 6px; font-size: 15px; line-height: 1.55; color: var(--text-body); }
.jour__step--end { background: linear-gradient(180deg, rgba(255, 44, 44, .10), var(--surface-sunken)); }
.jour__rail {
  position: absolute;
  top: -20px;
  left: calc(12.5% - 5px);
  width: calc(75% + 10px);
  height: 2px;
  border-radius: 2px;
  background: rgba(255, 255, 255, .12);
}
.jour__rail::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 2px;
  background: linear-gradient(90deg, rgba(255, 44, 44, .75), rgba(255, 44, 44, .4));
  transform-origin: left center;
  transition: transform 5.1s linear .5s;
}
.jour__dot {
  position: absolute;
  top: -5px;
  left: 100%;
  width: 12px;
  height: 12px;
  margin-left: -6px;
  border-radius: 50%;
  background: var(--accent-default);
  box-shadow: 0 0 14px rgba(255, 44, 44, .85);
  transition: left 5.1s linear .5s;
}
/* stany „przed animacją" — tylko gdy działa JS i sekcja jeszcze nie weszła */
html.js .jour:not(.is-in) .jour__step { border-color: var(--border-subtle); }
html.js .jour:not(.is-in) .jour__step--end { background: linear-gradient(180deg, var(--surface-raised), var(--surface-sunken)); }
html.js .jour:not(.is-in) .jour__ico { background: var(--color-alpha-white-04); border-color: var(--border-default); }
html.js .jour:not(.is-in) .jour__step::before { background: rgba(255, 255, 255, .28); box-shadow: none; }
html.js .jour:not(.is-in) .jour__rail::before { transform: scaleX(0); }
html.js .jour:not(.is-in) .jour__dot { left: 0; }
/* przystanki zapalają się w rytmie przejazdu kropki (start .5s, przystanek co 1.7s) */
.jour.is-in .jour__step:nth-child(1), .jour.is-in .jour__step:nth-child(1) .jour__ico, .jour.is-in .jour__step:nth-child(1)::before { transition-delay: .5s; }
.jour.is-in .jour__step:nth-child(2), .jour.is-in .jour__step:nth-child(2) .jour__ico, .jour.is-in .jour__step:nth-child(2)::before { transition-delay: 2.2s; }
.jour.is-in .jour__step:nth-child(3), .jour.is-in .jour__step:nth-child(3) .jour__ico, .jour.is-in .jour__step:nth-child(3)::before { transition-delay: 3.9s; }
.jour.is-in .jour__step:nth-child(4), .jour.is-in .jour__step:nth-child(4) .jour__ico, .jour.is-in .jour__step:nth-child(4)::before { transition-delay: 5.6s; }
@media (prefers-reduced-motion: reduce) {
  .jour__step, .jour__ico, .jour__step::before, .jour__rail::before, .jour__dot,
  .steer__ln, .steer__fade, .steer__x { transition: none !important; }
  .jour__step::after, .jour__ico { animation: none !important; }
}
@media (max-width: 1024px) {
  .jour { grid-template-columns: 1fr 1fr; row-gap: 34px; }
  .jour__rail { display: none; }
  .jour__step::before, .jour__step::after { display: none; }
}

/* ----- Remarketing: 4 kroki ścieżki powrotu klienta ----- */
.rmk { margin-top: 44px; display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; }
.rmk__step {
  position: relative;
  border: 1px solid var(--border-subtle);
  border-radius: 18px;
  background: linear-gradient(180deg, var(--surface-raised), var(--surface-sunken));
  padding: 22px 20px;
  transition: border-color .4s ease, background .4s ease;
}
.rmk__step:not(:last-child)::after {
  content: "";
  position: absolute;
  top: 50%;
  right: -14px;
  width: 14px;
  height: 1px;
  background: var(--border-default);
}
.rmk__ico {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--border-default);
  background: var(--color-alpha-white-04);
  color: #fff;
  transition: background .4s ease, border-color .4s ease;
}
.rmk__ico svg { width: 19px; height: 19px; }
.rmk__t { margin-top: 14px; font-size: 17px; font-weight: 600; color: var(--text-primary); }
.rmk__d { margin-top: 6px; font-size: 15px; line-height: 1.55; color: var(--text-body); }
.rmk__step.is-on { border-color: rgba(255, 44, 44, .5); }
.rmk__step.is-on .rmk__ico { background: var(--accent-default); border-color: var(--accent-default); }
.rmk__step--end.is-on { background: linear-gradient(180deg, rgba(255, 44, 44, .10), var(--surface-sunken)); }
@media (max-width: 1024px) {
  .rmk { grid-template-columns: 1fr 1fr; }
  .rmk__step:nth-child(2)::after { display: none; }
}
@media (max-width: 560px) {
  .rmk { grid-template-columns: 1fr; }
  .rmk__step::after { display: none; }
  .jour { grid-template-columns: 1fr; row-gap: 14px; }
  .steer__grid { grid-template-columns: 1fr; }
  .steer__legend { flex-wrap: wrap; row-gap: 4px; }
}

/* ==========================================================================
   AI Search (GEO) — czat z AI, siatki kropek prawdopodobieństwa (sygnatura
   żywej strony), sekwencja lejka AI → Google. Wzorce animacji z
   docs/research/research-aisearch.md.
   ========================================================================== */
.aichat { display: flex; flex-direction: column; gap: 12px; padding: 6px 2px; }
.aib {
  max-width: 88%;
  border-radius: 16px;
  padding: 12px 15px;
  font-size: 15px;
  line-height: 1.55;
  color: var(--text-primary);
}
.aib--user {
  align-self: flex-end;
  background: rgba(255, 255, 255, .07);
  border: 1px solid rgba(255, 255, 255, .10);
  border-bottom-right-radius: 6px;
}
.aib--bot {
  align-self: flex-start;
  background: rgba(255, 44, 44, .055);
  border: 1px solid rgba(255, 44, 44, .16);
  border-bottom-left-radius: 6px;
  transition: opacity .5s ease;
}
.aib__brand { color: var(--text-accent); font-weight: 700; white-space: nowrap; }
.aib__dot {
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--accent-default);
  box-shadow: 0 0 8px rgba(255, 44, 44, .7);
  margin-right: 6px;
  transform: translateY(-1px);
}
.ai-src { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; transition: opacity .5s ease; }
.ai-src span {
  font-size: 12px;
  border: 1px solid var(--border-default);
  border-radius: 6px;
  padding: 3px 8px;
  color: var(--text-body);
}
.ai-src .ai-src__k { border: none; padding-left: 0; color: var(--text-muted); }
.ai-typing { display: inline-flex; gap: 4px; padding: 10px 14px; }
.ai-typing[hidden] { display: none; }
.ai-typing i {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: rgba(255, 255, 255, .6);
  animation: tydots 1s ease-in-out infinite;
}
.ai-typing i:nth-child(2) { animation-delay: .16s; }
.ai-typing i:nth-child(3) { animation-delay: .32s; }
@keyframes tydots { 0%, 100% { opacity: .3; transform: translateY(0); } 50% { opacity: 1; transform: translateY(-3px); } }
/* stany „przed animacją" TYLKO pod html.js — bez JS wszystko widoczne */
html.js .svc [data-aichat] .aib--bot:not(.is-in),
html.js .svc [data-aichat] .ai-src:not(.is-in),
html.js .svc [data-flow] .flow__hide:not(.is-in) { opacity: 0; }

/* ----- siatki kropek: 5/100 vs 95/100 (prawdopodobieństwo rekomendacji) ----- */
.prob { margin-top: 44px; display: grid; grid-template-columns: 1fr auto 1fr; gap: clamp(14px, 2vw, 26px); align-items: center; }
.prob__panel { text-align: center; }
.prob__grid {
  display: grid;
  grid-template-columns: repeat(10, 1fr);
  gap: 7px;
  padding: clamp(14px, 1.6vw, 22px);
  border: 1px solid var(--border-subtle);
  border-radius: 18px;
  background: var(--color-alpha-white-03);
}
.prob__panel--hot .prob__grid { border-color: rgba(255, 44, 44, .38); background: rgba(255, 44, 44, .04); }
.prob__dot { position: relative; width: 100%; aspect-ratio: 1; border-radius: 50%; background: rgba(255, 255, 255, .13); }
.prob__dot--hot::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: var(--accent-default);
  box-shadow: 0 0 9px rgba(255, 44, 44, .55);
  opacity: 0;
  transform: scale(.55);
}
[data-prob].is-in .prob__dot--hot::after { animation: dotpop var(--dur, .95s) cubic-bezier(.2, .7, .2, 1) forwards; animation-delay: var(--d, 0ms); }
[data-prob].is-instant .prob__dot--hot::after { animation: none; opacity: 1; transform: none; }
@keyframes dotpop {
  0% { opacity: 0; transform: scale(.55); }
  60% { opacity: 1; transform: scale(1.16); }
  100% { opacity: 1; transform: scale(1); }
}
.prob__count {
  margin-top: 16px;
  font-size: clamp(40px, 4.6vw, 64px);
  font-weight: 700;
  line-height: 1;
  color: var(--text-heading);
  font-variant-numeric: tabular-nums;
}
.prob__count em { font-style: normal; font-size: .45em; color: var(--text-muted); }
.prob__cap { margin-top: 6px; font-size: 15px; color: var(--text-body); }
.prob__mid { display: flex; flex-direction: column; align-items: center; gap: 10px; }
.prob__mid svg {
  width: 34px;
  height: 34px;
  color: var(--accent-default);
  animation: arrowpulse 2.4s ease-in-out infinite;
  filter: drop-shadow(0 0 8px rgba(255, 44, 44, .45));
}
@keyframes arrowpulse { 0%, 100% { opacity: .45; transform: translateX(0); } 50% { opacity: 1; transform: translateX(4px); } }
.prob__pill {
  border: 1px solid var(--border-default);
  border-radius: 30px;
  padding: 6px 14px;
  font-size: 13px;
  font-weight: 700;
  color: var(--text-primary);
  white-space: nowrap;
}
@media (max-width: 900px) {
  .prob { grid-template-columns: 1fr; }
  .prob__mid svg { transform: rotate(90deg); animation: none; }
}

/* ----- lejek AI → Google: czat poleca → klient sprawdza w Google ----- */
.flow { display: flex; flex-direction: column; gap: 14px; }
.flow__join {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 13px;
  color: var(--text-body);
  padding-left: 6px;
}
.flow__join svg { width: 20px; height: 20px; flex: none; color: var(--accent-default); }
.flow__serp {
  border: 1px solid var(--serp-line, rgba(255, 255, 255, .12));
  border-radius: 14px;
  background: #202124;
  padding: 12px 14px;
}
.st2 { margin-top: 20px; display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.st2__card {
  border: 1px solid var(--border-subtle);
  border-radius: 16px;
  background: var(--color-alpha-white-03);
  padding: 18px 20px;
}
.st2__num { font-size: clamp(32px, 3vw, 44px); font-weight: 700; line-height: 1; color: var(--text-heading); font-variant-numeric: tabular-nums; }
.st2__txt { margin-top: 8px; font-size: 15px; line-height: 1.5; color: var(--text-body); }
.st2__txt strong { color: var(--text-primary); }
.st2__src { margin-top: 8px; font-size: 13px; color: var(--text-muted); }
@media (max-width: 640px) { .st2 { grid-template-columns: 1fr; } }

/* ==========================================================================
   Strategia marketingowa — hero „chaos → plan" (kanały zbiegają się w hub
   strategii i pracują na jeden cel), strzałki kierunków, lejek zwężający się,
   makieta strony WWW.
   ========================================================================== */
.plan__stage { position: relative; min-height: 330px; }
.plan__lines { position: absolute; inset: 0; width: 100%; height: 100%; }
.plan__lines path {
  stroke: rgba(255, 255, 255, .30);
  stroke-width: 1.5;
  fill: none;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  transition: stroke-dashoffset 1.1s ease .8s;
}
.plan__lines path.is-red { stroke: var(--accent-default); stroke-width: 2; transition-delay: 1.6s; }
.plan.is-in .plan__lines path { stroke-dashoffset: 0; }
.plan__chip {
  position: absolute;
  top: 5%;
  left: var(--x);
  transform: translate(calc(-50% + var(--sx, 0px)), var(--sy, 0px)) rotate(var(--sr, 0deg));
  opacity: .6;
  border: 1px solid var(--border-default);
  background: var(--color-alpha-white-04);
  border-radius: 30px;
  padding: 7px 14px;
  font-size: 13px;
  font-weight: 700;
  color: var(--text-primary);
  white-space: nowrap;
  transition: transform .95s cubic-bezier(.22, .61, .36, 1), opacity .95s ease;
  transition-delay: var(--pd, 0ms);
}
.plan.is-in .plan__chip { transform: translate(-50%, 0) rotate(0); opacity: 1; }
.plan__hub {
  position: absolute;
  left: 50%;
  top: 46%;
  transform: translate(-50%, -50%);
  width: 108px;
  height: 108px;
  display: grid;
  place-items: center;
}
.plan__hub-ring { position: absolute; inset: 0; width: 100%; height: 100%; }
.plan__hub-ring circle { fill: none; stroke: var(--accent-default); stroke-width: 1.5; stroke-dasharray: 3 7; opacity: .55; }
.plan.is-in .plan__hub-ring { animation: hubspin 18s linear infinite; transform-origin: center; }
@keyframes hubspin { to { transform: rotate(360deg); } }
.plan__hub-core {
  width: 80px;
  height: 80px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: rgba(255, 44, 44, .09);
  border: 1px solid rgba(255, 44, 44, .5);
  font-size: 13px;
  font-weight: 700;
  color: #fff;
  text-align: center;
}
.plan__goal {
  position: absolute;
  left: 50%;
  bottom: 3%;
  transform: translateX(-50%);
  display: inline-flex;
  align-items: center;
  gap: 9px;
  border: 1px solid var(--border-default);
  border-radius: 30px;
  padding: 10px 18px;
  font-size: 14px;
  font-weight: 700;
  color: var(--text-primary);
  background: var(--color-alpha-white-03);
  white-space: nowrap;
  transition: border-color .6s ease 2.2s, background .6s ease 2.2s;
}
.plan__goal svg { width: 16px; height: 16px; color: #fff; flex: none; }
.plan.is-in .plan__goal { border-color: rgba(255, 44, 44, .55); background: rgba(255, 44, 44, .08); }
.plan.is-instant .plan__chip, .plan.is-instant .plan__lines path, .plan.is-instant .plan__goal { transition: none; }
.plan.is-instant.is-in .plan__hub-ring { animation: none; }
@media (max-width: 480px) {
  .plan__stage { min-height: 300px; }
  .plan__chip { font-size: 10px; padding: 5px 8px; }
  /* na wąskim oknie 4 chipy ledwo się mieszczą — mniejsze i rozsunięte na całą
     szerokość (!important wygrywa z pozycją ustawioną inline; chipy = span 1–4) */
  .plan__chip:nth-of-type(1) { --x: 10% !important; }
  .plan__chip:nth-of-type(2) { --x: 35% !important; }
  .plan__chip:nth-of-type(3) { --x: 61% !important; }
  .plan__chip:nth-of-type(4) { --x: 87% !important; }
}

/* ----- lejek: kroki zwężają się jak lejek (reużywa .rmk__*) ----- */
.fun { margin-top: 44px; display: flex; flex-direction: column; gap: 12px; align-items: center; }
.fun .rmk__step { width: var(--fw, 100%); display: flex; align-items: center; gap: 16px; padding: 18px 22px; }
.fun .rmk__step::after { display: none; }
.fun .rmk__ico { margin: 0; }
.fun .rmk__body { flex: 1; min-width: 0; }
.fun .rmk__t { margin: 0; }
.fun .rmk__d { margin: 4px 0 0; }
.fun .fit__chip { margin: 0; flex: none; }
@media (max-width: 720px) {
  .fun .rmk__step { width: 100% !important; flex-wrap: wrap; }
}

/* ----- makieta strony WWW: elementy, które domykają sprzedaż ----- */
.smock { display: flex; flex-direction: column; gap: 12px; }
.smock__row { display: grid; grid-template-columns: 1fr auto; gap: 14px; align-items: center; }
.smock__panel { border: 1px solid var(--border-subtle); border-radius: 12px; background: var(--color-alpha-white-03); padding: 14px; }
.smock__line { height: 10px; border-radius: 6px; background: rgba(255, 255, 255, .16); margin-bottom: 8px; }
.smock__line--60 { width: 60%; }
.smock__line--40 { width: 40%; margin-bottom: 12px; }
.smock__cta { display: inline-block; padding: 8px 18px; border-radius: 20px; background: var(--accent-default); color: #fff; font-size: 12px; font-weight: 700; }
.smock__logos { display: flex; gap: 8px; align-items: center; }
.smock__logos i { width: 46px; height: 12px; border-radius: 6px; background: rgba(255, 255, 255, .16); }
.smock__fields { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.smock__field { flex: 1; min-width: 90px; height: 30px; border-radius: 8px; border: 1px solid var(--border-subtle); background: rgba(255, 255, 255, .05); }
.smock__ok { display: flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 700; color: #fff; }
.smock__ok svg { width: 18px; height: 18px; flex: none; }
.smock__tag {
  font-size: 13px;
  font-weight: 700;
  border: 1px solid var(--border-default);
  border-radius: 30px;
  padding: 6px 13px;
  color: var(--text-primary);
  white-space: nowrap;
}
@media (max-width: 560px) {
  .smock__row { grid-template-columns: 1fr; gap: 8px; }
  .smock__tag { justify-self: start; }
}

/* ==========================================================================
   Kwalifikacja „czy ta usługa ma sens w Twojej firmie?" — dwie kolumny tak/nie
   (wzorzec AdWise; z /pozycjonowanie-stron/, od 11.07 wspólne dla podstron).
   Znaczniki BIAŁE (czerwony check czyta się jak ostrzeżenie — uwaga Karola);
   czerwień tylko na ramce/poświacie karty „tak".
   ========================================================================== */
.fit {
  margin-top: 48px;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
}
.fit__col {
  position: relative;
  overflow: hidden;
  background: linear-gradient(180deg, var(--surface-raised), var(--surface-sunken));
  border: 1px solid var(--border-card);
  border-radius: 24px;
  padding: 32px;
  transition: transform .25s ease, border-color .25s ease;
}
.fit__col:hover { transform: translateY(-4px); }
.fit__col--yes { border-color: rgba(255, 44, 44, .32); }
.fit__col--yes:hover { border-color: rgba(255, 44, 44, .52); }
.fit__col--yes::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(120% 90% at 100% 0%, rgba(255, 44, 44, .13) 0%, transparent 55%);
}
.fit__col--alt:hover { border-color: var(--border-accent); }
.fit__head {
  margin: 0;
  font-size: 19px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: #fff;
}
.fit__list { list-style: none; margin: 22px 0 0; padding: 0; display: grid; gap: 18px; }
.fit__list li {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  font-size: 17px;
  line-height: 1.66;
  color: var(--text-primary);
}
.fit__ico {
  width: 26px;
  height: 26px;
  flex: none;
  margin-top: 3px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, .07);
  color: #fff;
}
.fit__ico svg { width: 15px; height: 15px; }
.fit__txt p { margin: 0; }
.fit__txt strong { color: #fff; }
.fit__chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 10px;
  padding: 7px 15px;
  border: 1px solid var(--border-default);
  border-radius: 999px;
  font-size: 14px;
  font-weight: 600;
  color: var(--text-primary);
  text-decoration: none;
  transition: border-color .2s ease, background .2s ease;
}
.fit__chip svg { width: 13px; height: 13px; color: var(--text-accent); }
.fit__chip:hover { border-color: var(--border-accent); background: rgba(255, 44, 44, .08); }
/* 11.08.2026, etap 4 domykany przed przełączeniem: pigułka miała 39 px przy progu
   44 px dla palca (na komputerze celuje się kursorem, więc zmiana dotyczy wyłącznie
   telefonu i tabletu).

   Najpierw próbowałem niewidocznej nakładki — tej samej, którą etap 4 naprawił
   etykietę kategorii nad tytułem wpisu, bo nie rusza wyglądu. Zmierzone: rozszerza
   pole trafienia w GÓRĘ, ale nie w dół — tam kliknięcie przechwytuje lista pod
   pigułką. Zamiast walczyć z kolejnością warstw dzień przed przełączeniem,
   podnoszę wyściółkę: rozwiązanie pewne i mierzalne.

   Skutek uboczny, świadomy: pigułka rośnie o 6 px (39 → 45). Ma widoczną obwódkę,
   więc tej zmiany widać — na telefonie wygląda jak wygodniejszy guzik.
   Cofnięcie: skasować ten blok. Wyściółka wraca do 7 px z reguły wyżej. */
@media (max-width: 820px) {
  .fit__chip:not(.fit__chip--inline) { padding-top: 10px; padding-bottom: 10px; }
}
/* pigułka W LINII tekstu punktu (uwaga Karola: pod tekstem rozciągała kolumnę
   i prawa strona była dłuższa niż lewa) — mniejsza, dokleja się do końca zdania */
.fit__chip--inline {
  margin: 0 0 0 8px;
  padding: 3px 12px;
  font-size: 13px;
  vertical-align: -1px;
}
/* Notka + przycisk w JEDNEJ karcie (sama ramka z tekstem wyglądała słabo). */
.fit__cta {
  display: flex;
  align-items: center;
  gap: 20px;
  margin-top: 28px;
  padding: 22px 26px;
  background: linear-gradient(180deg, var(--surface-raised), var(--surface-sunken));
  border: 1px solid var(--border-card);
  border-radius: 20px;
}
.fit__cta p {
  flex: 1;
  margin: 0;
  font-size: 16px;
  line-height: 1.6;
  color: var(--text-body);
}
.fit__cta strong { color: #fff; }
.fit__cta .btn { flex: none; }
/* wariant zwężony — ramka nie może być szersza niż okno grafiki nad nią (880px) */
.fit__cta--tight { max-width: 880px; margin-left: auto; margin-right: auto; }
@media (max-width: 860px) {
  .fit { grid-template-columns: 1fr; }
  .fit__col { padding: 26px 22px; }
  .fit__cta { flex-direction: column; align-items: flex-start; }
  .fit__cta .btn { align-self: stretch; justify-content: center; }
}

/* ==========================================================================
   Sekcja opiekuna klienta — zdjęcia w geometrii brandu (liść / panel / pigułka).
   Bazowy układ: zdjęcia po lewej (SEO). Wariant --flip: zdjęcia po prawej —
   używać na przemian między podstronami (nie kopiować układu 1:1).
   ========================================================================== */
.ppl {
  display: grid;
  grid-template-columns: 1.05fr 1fr;
  gap: clamp(28px, 4vw, 64px);
  align-items: center;
}
.ppl--flip .ppl__visual { order: 2; }
.ppl--flip .ppl__text { order: 1; }
.ppl__visual {
  display: grid;
  grid-template-columns: 1.5fr 1fr;
  grid-template-rows: 1fr auto;
  gap: 14px;
}
.ppl__visual > div {
  overflow: hidden;
  position: relative;
  border: 1px solid var(--border-strong, rgba(255, 255, 255, .39));
  box-shadow: 0 26px 54px -26px rgba(0, 0, 0, .85);
}
.ppl__visual img { width: 100%; height: 100%; object-fit: cover; filter: saturate(.94) contrast(1.06) brightness(.87); }
.ppl__photo { grid-row: 1 / 3; border-radius: 140px 24px 140px 24px; height: 480px; }
.ppl__photo img { object-position: 50% 30%; }
.ppl__photo::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(90% 70% at 85% 100%, rgba(255, 44, 44, .22) 0%, transparent 62%);
  mix-blend-mode: screen;
}
.ppl__mini { border-radius: 28px 28px 28px 96px; }
.ppl__mini img { object-position: 72% 30%; }
.ppl__pill { border-radius: 999px; height: 118px; }
.ppl__pill img { object-position: center 40%; }
@media (max-width: 1024px) {
  .ppl { grid-template-columns: 1fr; }
  .ppl__visual, .ppl--flip .ppl__visual { order: 2; }
  .ppl--flip .ppl__text { order: 1; }
  .ppl__photo { height: 400px; }
}
@media (max-width: 640px) {
  .ppl__visual { gap: 10px; }
  .ppl__photo { height: 320px; border-radius: 80px 18px 80px 18px; }
  .ppl__mini { border-radius: 20px 20px 20px 56px; }
  .ppl__pill { height: 88px; }
}

/* ==========================================================================
   Ludzki akcent pod listą audytu (adwise ma człowieka przy formularzu) —
   małe zdjęcie w geometrii brandu + obietnica bez presji.
   ========================================================================== */
.audit__human {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-top: 20px;
  padding-top: 18px;
  border-top: 1px solid var(--border-subtle);
}
.audit__human img {
  width: 68px;
  height: 68px;
  flex: none;
  object-fit: cover;
  object-position: 62% 22%;
  border-radius: 26px 10px 26px 10px;
  border: 1px solid var(--border-strong, rgba(255, 255, 255, .39));
  filter: saturate(.94) contrast(1.06) brightness(.87);
}
.audit__human p {
  margin: 0;
  font-size: 15px;
  line-height: 1.55;
  color: var(--text-muted);
}
.audit__human strong { color: var(--text-primary); }

/* ==========================================================================
   Responsywność
   ========================================================================== */
@media (max-width: 1024px) {
  .svc-sec { padding: 52px 0; }
  .svc-hero__grid { grid-template-columns: 1fr; gap: 36px; padding-top: 48px; }
  /* Pole siatki domyślnie NIE ZWĘŻA SIĘ poniżej najszerszego nierozrywalnego
     kawałka swojej treści. W makiecie okna (`.svc-win`) siedzą napisy pisane
     w jednej linijce (`white-space: nowrap`) — przez nie całe pole rozpychało się
     do 398 px na ekranie 390 px, a razem z nim WSZYSTKO w kolumnie: nagłówek,
     wstęp i guzik. Ucięte były więc rzeczy, które z makietą nie mają nic wspólnego.
     Zmierzone przed poprawką: /audyt-ai-search/ 398 px, /audyt-kampanii/ 374 px,
     /performance-marketing/ 438 px — przy dostępnych 350 px. */
  .svc-hero__grid > * { min-width: 0; }
  .ctr__grid, .grow__grid { grid-template-columns: 1fr; gap: 36px; }
  .gain, .res { grid-template-columns: 1fr; }
  .proc, .svc .proc { grid-template-columns: 1fr; }
  .proc__arrow { justify-self: center; transform: rotate(90deg); }
  .audit__grid { grid-template-columns: 1fr; }
  .path { grid-template-columns: 1fr; gap: 18px; }
  .path__step { padding-top: 0; padding-left: 30px; text-align: left; }
  .path__step::before { top: 20px; left: 8px; right: auto; bottom: -18px; width: 1px; height: auto; }
  .path__dot { top: 2px; left: 0; margin-left: 0; }
}
@media (max-width: 640px) {
  .svc-sec { padding: 42px 0; }
  .svc-big { font-size: 84px; }
  .climb__list { --slot: 86px; }
  .climb__row { height: 80px; padding: 8px 10px; }
  .serp__tabs { gap: 14px; }
  .serp__tabs span:nth-child(n+5) { display: none; }
  .ladder__row { grid-template-columns: 24px 1fr 56px; gap: 8px; }
  .ladder__ghost { display: none; }
  .ladder__pct { font-size: 13px; }
  .grow__bars { gap: 2px; }
  .grow__ms { display: none; }
  .grow__mob {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin-top: 14px;
    padding: 12px 4px 0;
    border-top: 1px solid var(--border-subtle);
    font-size: 13px;
    line-height: 1.45;
    color: var(--text-body);
    list-style: none;
  }
  .grow__mob li { display: flex; align-items: baseline; gap: 8px; }
  .grow__mob li::before {
    content: "";
    flex: none;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: #0f0f12;
    border: 2px solid var(--accent-default);
    transform: translateY(1px);
  }
  .grow__mob strong { color: var(--text-primary); white-space: nowrap; }
  /* lejek zapytań: na wąskich ekranach mniejsze zwężanie, żeby nic się nie ucinało */
  .gain__fq { width: calc(76% + var(--fw, 100%) * 0.24); }
  .audit { padding: 24px 18px; }
  .audit__row { grid-template-columns: 1fr; }
  .serp { padding: 10px; }
}

/* Telefon/tablet: wygaszamy RUCH, treść zostaje w stanie końcowym */
@media (max-width: 820px) {
  html { scroll-snap-type: none; }
  /* czytelność drobnych podpisów na telefonie (sesja 8, zasada >=13,5px) */
  .ladder__pos { font-size: 13px; }
  .ladder__pct { font-size: 13px; }
  .res-card__tag { font-size: 13px; }
  .svc-win__label { font-size: 13px; }
}

/* ==========================================================================
   Bez JavaScriptu (brak html.js): PEŁNA treść widoczna od razu — roboty
   Google i przeglądarki bez JS niczego nie tracą (twarde SEO techniczne).
   Stany „ukryte przed animacją" żyją wyłącznie pod html.js wyżej.
   ========================================================================== */
html:not(.js) .svc .proc__panel,
html:not(.js) .svc .faq__a,
html:not(.js) .svc .adsw__ad { grid-template-rows: 1fr; }
html:not(.js) .svc .adsw__ad .serp__row { opacity: 1; transform: none; }
html:not(.js) .svc .adsw .adsw__pill { display: none; }
/* Meta Ads bez JS: feed od razu na reklamie, przycisk czerwony, kroki podświetlone */
html:not(.js) .svc .feed__track { --fy: -192px; transition: none; }
html:not(.js) .svc .fpost__cta { background: var(--accent-default); }
html:not(.js) .svc .fpost--ad { border-color: rgba(255, 44, 44, .55); }
html:not(.js) .svc .fpost__hearts { display: none; }
html:not(.js) .svc .rmk__step { border-color: rgba(255, 44, 44, .5); }
html:not(.js) .svc .rmk__step .rmk__ico { background: var(--accent-default); border-color: var(--accent-default); }
/* Strategia bez JS: plan od razu ułożony */
html:not(.js) .svc .plan__chip { transform: translate(-50%, 0) rotate(0); opacity: 1; transition: none; }
html:not(.js) .svc .plan__lines path { stroke-dashoffset: 0; transition: none; }
html:not(.js) .svc .plan__goal { border-color: rgba(255, 44, 44, .55); background: rgba(255, 44, 44, .08); transition: none; }

/* Preferencja ograniczonego ruchu: wszystko od razu w stanie końcowym */
@media (prefers-reduced-motion: reduce) {
  html.js .svc [data-rv] { opacity: 1; transform: none; transition: none; }
  .svc .ladder__fill { transform: scaleX(var(--sx, 1)) !important; transition: none; }
  .svc .climb__row { transition: none; }
  .svc .grow__bars span { transform: scaleY(1) !important; transition: none; }
  .svc .grow__ms { opacity: 1 !important; transform: none !important; transition: none; }
  .svc .serp__caret { animation: none; }
  .svc .feed__track { transition: none; }
  .svc .fpost__hearts span { animation: none !important; }
}

/* ==========================================================================
   PERFORMANCE MARKETING — hero: jeden telefon, trzy aplikacje (.mchan).
   Ekran telefonu ma STAŁY rozmiar (uwaga Karola: nic nie może się rozciągać):
   panele aplikacji leżą absolutnie jeden na drugim w .mchan__stage o sztywnej
   wysokości. Przełączanie = poziomy SWIPE jak gest przesunięcia palcem
   (uwaga Karola: kropki na dole sugerują kolejne strony, więc panele mają
   się przesuwać, nie przenikać): aktywny panel wjeżdża z prawej (translateX
   102%→0), ustępujący wyjeżdża w lewo (0→−102%), pozostałe czekają z prawej
   bez animacji. Klipuje .phone__screen (overflow hidden). Bez JS widać panel
   Instagrama w stanie spoczynku (treść pozostałych paneli jest w HTML).
   ========================================================================== */
.mchan__stage { position: relative; height: 540px; }
.mchan__pane {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  transform: translateX(102%);
  pointer-events: none;
}
.mchan__pane--ig { transform: none; } /* domyślnie widoczny — także bez JS */
html.js .mchan.is-run .mchan__pane { transform: translateX(102%); transition: none; }
html.js .mchan.is-run .mchan__pane.is-anim { transition: transform .72s cubic-bezier(.3, .8, .3, 1); }
html.js .mchan.is-run .mchan__pane.is-on { transform: translateX(0); }
html.js .mchan.is-run .mchan__pane.is-prev { transform: translateX(-102%); }
.mchan .phone__bar { flex: none; }

/* kropki-wskaźnik aktywnej aplikacji */
.mchan__ind {
  position: absolute;
  left: 50%;
  bottom: 9px;
  transform: translateX(-50%);
  display: flex;
  gap: 6px;
  padding: 5px 9px;
  border-radius: 20px;
  background: rgba(0, 0, 0, .5);
  border: 1px solid rgba(255, 255, 255, .12);
  backdrop-filter: blur(4px);
  z-index: 4;
}
.mchan__ind span { width: 6px; height: 6px; border-radius: 50%; background: rgba(255, 255, 255, .28); transition: background .4s ease; }
.mchan__ind span.is-on { background: var(--accent-default); }

/* ----- panel Instagram: pasek relacji + gęstszy feed ----- */
.mchan__stories {
  flex: none;
  display: flex;
  gap: 12px;
  padding: 10px 12px 9px;
  border-bottom: 1px solid rgba(255, 255, 255, .08);
}
.mchan__story { display: flex; flex-direction: column; align-items: center; gap: 4px; min-width: 0; }
.mchan__story i {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  padding: 2.5px;
  background: conic-gradient(from 210deg, #f9ce34, #ee2a7b, #6228d7, #f9ce34);
  display: block;
}
.mchan__story--you i { background: conic-gradient(from 210deg, #ff2c2c, #7a0d0d, #ff2c2c); }
.mchan__story i::after {
  content: "";
  display: block;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  background: var(--av, #232327);
  border: 2px solid #000;
}
.mchan__story em { font-style: normal; font-size: 8px; color: #b9bcc4; max-width: 52px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* jeden znak „Twojej marki" (biała lampa .bmk) — identyczny w każdej aplikacji;
   kontener wg konwencji platformy: kółko (IG, Google), zaokrąglony kwadrat (LinkedIn).
   Czytelność (uwaga Karola: znak się zlewał): lampa powiększona + jasna
   obwódka na czerwonym medalionie odcina go od ciemnego tła. */
.mchan__story--you i { position: relative; }
.mchan__story--you .bmk { position: absolute; inset: 0; margin: auto; width: 68%; height: 68%; z-index: 1; }
.mchan__story--you i::after { border-color: rgba(255, 255, 255, .35); }
.fpost--ad .fpost__ava { display: grid; place-items: center; box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .55); }
.fpost--ad .fpost__ava .bmk { width: 80%; height: 80%; }
.mchan__liava { box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .55); }
.mchan__liava .bmk { width: 82%; height: 82%; }
.svc--pm .serp__fav--you {
  background: radial-gradient(circle at 35% 30%, #ff5a5a, #a31212);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .55);
}
.svc--pm .serp__fav--you .bmk { width: 80%; height: 80%; }
.mchan .feed { flex: 1; height: auto; min-height: 0; }
.mchan.is-scrolled .feed__track { --fy: -178px; }

/* sceny „zdjęciowe" postów — pełnowymiarowe ilustracje zamiast ikonki */
.fpost__img--scene { background: #0c0c0e; }
.fpost__img.fpost__img--scene svg,
.fpost--ad .fpost__img.fpost__img--scene svg { position: absolute; inset: 0; margin: 0; width: 100%; height: 100%; color: inherit; }
.mchan .fpost__img { height: 120px; }
.mchan .fpost__img--tall { height: 150px; }
.fpost__save { margin-left: 6px; display: inline-flex; }
.fpost__save svg { opacity: .8; }
.mchan .fpost__actions b { margin-left: 2px; }

/* ożywienie reklamy w feedzie */
.mchan .fpost--ad { border-color: rgba(255, 255, 255, .14); transition: border-color .5s ease; }
.mchan.is-ad .fpost--ad { border-color: rgba(255, 44, 44, .55); }
.mchan.is-ad .fpost__cta { background: var(--accent-default); }
.mchan.is-ad .fpost--ad .fpost__actions .ico-heart { color: var(--accent-default); fill: var(--accent-default); }
.mchan.is-ad .fpost__hearts span { animation: heartUp 1.3s ease-out forwards; }
.mchan.is-ad .fpost__hearts span:nth-child(2) { animation-delay: .22s; left: 7px; }
.mchan.is-ad .fpost__hearts span:nth-child(3) { animation-delay: .45s; left: -6px; }

/* ----- panel Google: wyszukiwanie + Twoja reklama nad wynikami ----- */
.phone__bar--g span:first-child { font-weight: 600; letter-spacing: .01em; }
.mchan__gword { display: inline-flex; align-items: center; gap: 8px; }
.mchan__gword svg { width: 18px; height: 18px; flex: none; }
.mchan__gbody {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 12px 12px 34px;
  background: var(--serp-bg);
  font-size: 13px;
}
.mchan__gbody .serp__row { padding: 9px 8px; }
/* wysokość wiersza reklamy jest zarezerwowana od początku (stały rozmiar) —
   animujemy tylko pojawienie się treści */
html.js .mchan:not(.is-gad):not(.is-instant) .mchan__gad .serp__row {
  opacity: 0;
  transform: translateY(-6px);
}
.mchan__gad .serp__row { transition: opacity .55s var(--ease) .1s, transform .55s var(--ease) .1s; }
/* ----- panel LinkedIn: post firmowy B2B ----- */
.mchan__libody {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 12px 12px 34px;
  background: #17191d;
}
.mchan__lipost { border: 1px solid rgba(255, 255, 255, .09); border-radius: 14px; background: #1e2126; overflow: hidden; }
.mchan__liava {
  width: 32px;
  height: 32px;
  border-radius: 7px;
  flex: none;
  display: grid;
  place-items: center;
  background: radial-gradient(circle at 35% 30%, #ff5a5a, #a31212);
  color: #fff;
  font-size: 12px;
  font-weight: 700;
}
.mchan__lifollow { margin-left: auto; font-size: 12px; font-weight: 700; color: #70b5f9; white-space: nowrap; }
.mchan__litxt { padding: 0 12px 9px; font-size: 12px; line-height: 1.5; color: #d5d8de; }
.mchan__licta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 9px 12px;
  font-size: 13px;
  font-weight: 700;
  color: #fff;
  background: #0a66c2;
  border-top: 1px solid rgba(255, 255, 255, .08);
}
.mchan__lireact {
  width: 17px;
  height: 17px;
  border-radius: 50%;
  background: #378fe9;
  display: inline-grid;
  place-items: center;
  flex: none;
}
.mchan__lireact svg { width: 11px; height: 11px; color: #fff; }
.mchan__licom { margin-left: auto; font-size: 11px; color: #b9bcc4; }

/* szkieletowe wiersze — sugerują dalsze wyniki pod reklamą */
.mchan__skel { display: flex; gap: 10px; padding: 9px 8px; align-items: flex-start; }
.mchan__skel .serp__fav { opacity: .5; }
.mchan__skel > span:last-child { flex: 1; display: flex; flex-direction: column; gap: 7px; padding-top: 4px; }
.mchan__skel i { display: block; height: 9px; border-radius: 5px; background: rgba(255, 255, 255, .10); width: var(--w, 70%); }
.mchan__lipost--half { opacity: .55; }
.mchan__pane--li .fpost__img--scene { height: 96px; }

/* stan natychmiastowy (mobile / reduced-motion / bez JS) */
.mchan.is-instant .mchan__pane, .mchan.is-instant .feed__track, .mchan.is-instant .fpost__cta,
.mchan.is-instant .fpost--ad, .mchan.is-instant .mchan__gad .serp__row { transition: none; }
.mchan.is-instant .fpost__hearts { display: none; }

@media (max-width: 480px) {
  .mchan__stage { height: 500px; }
  .mchan__story i { width: 40px; height: 40px; }
}

/* ==========================================================================
   AI SEARCH — pasek silników AI przy czacie hero (port z żywej strony).
   Ikony podświetlają się cyklicznie; przy reduced-motion pierwsza świeci na stałe.
   ========================================================================== */
.aiwrap { display: grid; grid-template-columns: auto 1fr; gap: 14px; align-items: stretch; }
.airail { display: flex; flex-direction: column; gap: 11px; padding-top: 8px; }
.airail__eng {
  width: 44px;
  height: 44px;
  border-radius: 13px;
  display: grid;
  place-items: center;
  background: var(--color-alpha-white-03);
  border: 1px solid var(--border-subtle);
  transition: border-color .35s var(--ease), background .35s var(--ease), box-shadow .35s var(--ease), transform .35s var(--ease);
}
.airail__eng img { width: 23px; height: 23px; display: block; opacity: .7; transition: opacity .35s var(--ease); }
.airail__eng.is-active {
  border-color: rgba(255, 44, 44, .6);
  background: rgba(255, 44, 44, .12);
  box-shadow: 0 0 0 4px rgba(255, 44, 44, .09);
  transform: translateX(3px);
}
.airail__eng.is-active img { opacity: 1; }
.airail__cap {
  font-size: 10px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--text-muted);
  font-weight: 700;
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  align-self: center;
  margin-top: 6px;
  opacity: .7;
}
@media (max-width: 820px) {
  .aiwrap { grid-template-columns: 1fr; gap: 10px; }
  .airail { flex-direction: row; padding-top: 0; justify-content: center; align-items: center; }
  .airail__eng.is-active { transform: translateY(-3px); }
  .airail__cap { writing-mode: horizontal-tb; transform: none; margin: 0 0 0 4px; }
}

/* ==========================================================================
   AI SEARCH — orbita procesu (port z żywej strony): 6 kroków na pierścieniu
   wokół czerwonego huba, kręcący się przerywany ring, sekwencyjny puls.
   Czysty CSS (bez JS); dekoracja — copy kroków jest w akordeonach wyżej.
   Na oknach ≤920 px ukryta (kroki czyta się w akordeonach).
   ========================================================================== */
.orb { position: relative; width: min(620px, 88vw); aspect-ratio: 1; margin: clamp(36px, 4.5vw, 60px) auto 0; }
.orb__ring { position: absolute; inset: 23%; color: var(--border-subtle); z-index: 0; }
.orb__ring circle { fill: none; stroke: currentColor; stroke-width: .5; }
.orb__ring--live { color: var(--accent-default); opacity: .5; transform-origin: 50% 50%; animation: orbSpin 18s linear infinite; }
.orb__ring--live circle { stroke-width: .7; stroke-dasharray: 3 7; }
@keyframes orbSpin { to { transform: rotate(360deg); } }
.orb__hub {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 30%;
  height: 30%;
  border-radius: 50%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: 5px;
  z-index: 1;
  background: radial-gradient(circle at 50% 36%, rgba(255, 44, 44, .20), rgba(12, 12, 16, .96) 72%);
  border: 1px solid rgba(255, 44, 44, .45);
  box-shadow: 0 0 70px -8px rgba(255, 44, 44, .5) inset, 0 30px 80px -30px rgba(255, 44, 44, .5);
}
.orb__hub b { font-size: clamp(15px, 1.4vw, 19px); font-weight: 600; color: #fff; letter-spacing: -.01em; }
.orb__hub small { font-size: clamp(11.5px, .95vw, 13px); color: rgba(255, 255, 255, .84); }
.orb__node { position: absolute; width: 0; height: 0; }
.orb__ic {
  position: absolute;
  left: 0;
  top: 0;
  transform: translate(-50%, -50%);
  width: 58px;
  height: 58px;
  border-radius: 17px;
  display: grid;
  place-items: center;
  border: 1px solid var(--border-subtle);
  background: #14141a;
  color: #fff;
  z-index: 3;
  animation: orbPulse 14.4s var(--ease) infinite;
  animation-delay: var(--dly);
}
.orb__ic svg { width: 29px; height: 29px; display: block; }
@keyframes orbPulse {
  0%, 74%, 100% { border-color: var(--border-subtle); background: #14141a; color: #fff; box-shadow: none; }
  10%, 28% { border-color: rgba(255, 44, 44, .6); background: #341619; color: var(--accent-default); box-shadow: 0 0 0 6px rgba(255, 44, 44, .09), 0 16px 40px -14px rgba(255, 44, 44, .85); }
}
.orb__lbl { position: absolute; width: 172px; display: flex; flex-direction: column; gap: 3px; }
.orb__lbl .no { font-size: 13px; color: var(--accent-default); font-weight: 700; letter-spacing: .1em; }
.orb__lbl b { font-size: clamp(14.5px, 1.2vw, 16.5px); font-weight: 600; color: #fff; letter-spacing: -.01em; }
.orb__lbl--top { left: 0; bottom: 42px; transform: translateX(-50%); align-items: center; text-align: center; }
.orb__lbl--bottom { left: 0; top: 42px; transform: translateX(-50%); align-items: center; text-align: center; }
.orb__lbl--right { left: 42px; top: 0; transform: translateY(-50%); align-items: flex-start; text-align: left; }
.orb__lbl--left { right: 42px; top: 0; transform: translateY(-50%); align-items: flex-end; text-align: right; }
.orb__n1 { left: 50%; top: 23%; }
.orb__n2 { left: 73.4%; top: 36.5%; }
.orb__n3 { left: 73.4%; top: 63.5%; }
.orb__n4 { left: 50%; top: 77%; }
.orb__n5 { left: 26.6%; top: 63.5%; }
.orb__n6 { left: 26.6%; top: 36.5%; }
@media (max-width: 920px) { .orb { display: none; } }
@media (prefers-reduced-motion: reduce) {
  .orb__ic, .orb__ring--live { animation: none !important; }
}

/* ==========================================================================
   AUDYT KAMPANII — hero: skan konta reklamowego (.scanw, data-scan).
   Okno raportu o STAŁYM rozmiarze: pasek prześwietlenia przesuwa się po
   wierszach kampanii, werdykty pojawiają się przez opacity w zarezerwowanych
   kolumnach, na końcu wjeżdża podsumowanie z licznikiem „do odzyskania".
   Czerwień = akcent marki (światło skanu, ramka podsumowania), NIGDY kolor
   błędu: werdykty białe/szare, znaczniki wyboru białe (reguły Karola).
   Bez JS i przy reduced-motion: stan końcowy od razu (ukrycia tylko html.js).
   ========================================================================== */
.scanw { max-width: 560px; margin-left: auto; width: 100%; }
.scanw .svc-win__body { position: relative; padding: 16px 16px 18px; }
.scanw__head {
  display: grid;
  grid-template-columns: 1fr 88px 158px;
  gap: 10px;
  padding: 2px 12px 10px;
  font-size: 13px;
  color: var(--text-muted);
}
.scanw__head span:nth-child(2) { text-align: right; }
.scanw__rows {
  position: relative;
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.scanw__row {
  display: grid;
  grid-template-columns: 1fr 88px 158px;
  gap: 10px;
  align-items: center;
  padding: 11px 12px;
  border-radius: 12px;
  border: 1px solid var(--border-subtle);
  background: var(--color-alpha-white-03, rgba(255, 255, 255, .03));
  transition: border-color .5s var(--ease), background .5s var(--ease), box-shadow .5s var(--ease);
}
/* akt 2: wiersz rozjaśnia się, gdy mija go pas światła (miękko, bez cienia —
   światło daje pas, wiersz tylko odpowiada) */
.scanw__row.is-lit {
  border-color: rgba(255, 44, 44, .4);
  background: rgba(255, 44, 44, .06);
}
/* akt 3: kampanie przepalające budżet zostają zaznaczone ramką (czerwień =
   akcent ramki jak przy podsumowaniu; kwota biała, tylko pogrubiona) */
.scanw__row.is-leak { border-color: rgba(255, 44, 44, .38); }
.scanw__row.is-leak .scanw__spend { color: var(--text-primary); font-weight: 600; }
.scanw__name { font-size: 15px; line-height: 1.35; color: var(--text-primary); }
.scanw__spend {
  font-size: 15px;
  color: var(--text-body);
  text-align: right;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.scanw__cell { display: grid; align-items: center; }
.scanw__cell > * { grid-area: 1 / 1; }
.scanw__st { display: inline-flex; align-items: center; gap: 7px; font-size: 13px; line-height: 1.3; }
.scanw__st svg { flex: none; width: 16px; height: 16px; color: #fff; }
/* werdykt „pracuje" ZIELONY — decyzja Karola (gate rundy 3, 12.07): wyjątek
   od reguły białych znaczników, dotyczy TYLKO werdyktu w makiecie skanu */
.scanw__st--ok { color: #3fd47c; }
.scanw__st--ok svg { color: #3fd47c; }
.scanw__st--leak { color: var(--text-primary); font-weight: 600; }
/* akt 4: zalecenie audytu w miejscu werdyktu (tylko wiersze-przepalacze);
   bez JS nigdy nie widać — to alternatywny stan animacji, nie treść */
.scanw__fix {
  display: none;
  align-items: center;
  gap: 7px;
  justify-self: start;
  padding: 5px 11px 5px 8px;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, .35);
  font-size: 13px;
  line-height: 1.3;
  color: var(--text-primary);
  white-space: nowrap;
}
.scanw__fix svg { flex: none; width: 13px; height: 13px; color: #fff; }
/* światło skanera: miękki PAS światła jak w skanerze dokumentów (gate rundy 4
   — zastąpił twardą kreskę, która przekreślała tekst i miała „ucięte boki").
   Pas na pełną szerokość okna, gradient gaśnie górą i dołem (nie po bokach),
   pozycję (translateY) prowadzi JS klatka po klatce — jeden płynny przejazd
   z łagodnym startem i hamowaniem. Jasność pulsuje przez opacity na wewnętrznej
   warstwie <i> — zero animacji box-shadow i layoutu. */
.scanw__beam {
  position: absolute;
  left: -16px;
  right: -16px;
  top: 0;
  height: 76px;
  opacity: 0;
  pointer-events: none;
  transition: opacity .35s var(--ease);
  will-change: transform;
  background: linear-gradient(180deg, transparent, rgba(255, 44, 44, .06) 28%, rgba(255, 44, 44, .15) 50%, rgba(255, 44, 44, .06) 72%, transparent);
}
.scanw__beam i {
  position: absolute;
  inset: 0;
  display: block;
  background: linear-gradient(180deg, transparent 32%, rgba(255, 80, 62, .26) 46%, rgba(255, 120, 92, .34) 50%, rgba(255, 80, 62, .26) 54%, transparent 68%);
  animation: scanwGlow 1.5s ease-in-out infinite;
}
@keyframes scanwGlow {
  0%, 100% { opacity: .4; }
  50% { opacity: 1; }
}
.scanw__sum {
  margin-top: 14px;
  display: grid;
  padding: 13px 16px;
  border-radius: 12px;
  border: 1px solid rgba(255, 44, 44, .45);
  background: rgba(255, 44, 44, .08);
}
/* dwa stany podsumowania w tym samym miejscu (akt 3: kwota, akt 4: plan) —
   nakładka siatki, więc ramka nigdy nie zmienia rozmiaru */
.scanw__sum-a,
.scanw__sum-b {
  grid-area: 1 / 1;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  transition: opacity .55s var(--ease);
}
.scanw__sum-b { opacity: 0; }
.scanw__sum em { font-style: normal; font-size: 15px; color: var(--text-body); }
.scanw__sum strong {
  font-size: 18px;
  color: var(--text-primary);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
/* stany „przed animacją" wyłącznie pod html.js — roboty widzą pełny wynik
   (werdykty + kwota do odzyskania; zalecenia to stan przejściowy animacji) */
html.js .svc [data-scan] .scanw__st { opacity: 0; transition: opacity .45s var(--ease); }
html.js .svc [data-scan] .scanw__row.is-done .scanw__st { opacity: 1; }
html.js .svc [data-scan] .scanw__sum {
  opacity: 0;
  transform: translateY(6px);
  transition: opacity .6s var(--ease), transform .6s var(--ease);
}
html.js .svc [data-scan].is-sum .scanw__sum { opacity: 1; transform: none; }
html.js .svc [data-scan].is-run:not(.is-instant):not(.is-sum) .scanw__beam { opacity: 1; }
/* akt 4: werdykty przepalaczy ustępują zaleceniom, reszta przygasa */
html.js .svc [data-scan] .scanw__fix { display: inline-flex; opacity: 0; transition: opacity .55s var(--ease); }
html.js .svc [data-scan].is-plan .scanw__row[data-leak] .scanw__st { opacity: 0; }
html.js .svc [data-scan].is-plan .scanw__row[data-leak] .scanw__fix { opacity: 1; }
html.js .svc [data-scan].is-plan .scanw__row:not([data-leak]) .scanw__st { opacity: .45; }
html.js .svc [data-scan].is-plan .scanw__sum-a { opacity: 0; }
/* zwłoka wejścia planu: najpierw znika kwota, potem wjeżdża plan (napisy
   nie nakładają się w półprzezroczystości) */
html.js .svc [data-scan].is-plan .scanw__sum-b { opacity: 1; transition-delay: .5s; }
/* stan końcowy bez ruchu (telefon / ograniczenie animacji): werdykty + kwota */
html.js .svc [data-scan].is-instant .scanw__st,
html.js .svc [data-scan].is-instant .scanw__sum { transition: none; opacity: 1; transform: none; }
html.js .svc [data-scan].is-instant .scanw__beam { opacity: 0; }
@media (max-width: 640px) {
  .scanw__head, .scanw__row { grid-template-columns: 1fr 70px 118px; gap: 8px; }
  .scanw__name, .scanw__spend { font-size: 13px; }
  .scanw__st { font-size: 13px; }
  .scanw__st svg { width: 14px; height: 14px; }
  .scanw__fix { font-size: 13px; padding: 4px 9px 4px 7px; }
}
@media (prefers-reduced-motion: reduce) {
  html.js .svc [data-scan] .scanw__beam { opacity: 0 !important; transition: none; }
  .scanw__beam i { animation: none !important; }
  html.js .svc [data-scan] .scanw__st,
  html.js .svc [data-scan] .scanw__sum { opacity: 1; transform: none; transition: none; }
}

/* --------------------------------------------------------------------------
   AUDYT KAMPANII — #zakres: mini-grafiki w kartach (.akv).
   Każda karta zakresu ma wizualizację nad tekstem (wzorzec kart korzyści
   z performance/SEO). Szlif rundy 3: grafiki komponowane na CAŁĄ szerokość
   karty i wyrównane wysokością (uwaga Karola: „większe, na miarę karty").
   Czerwień tylko jako akcent ramki-znaleziska.
   -------------------------------------------------------------------------- */
.svc--ak .gain__viz { min-height: 150px; width: 100%; }
.svc--ak .akv { flex-direction: row; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.akv__chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  border-radius: 999px;
  border: 1px solid var(--border-default);
  font-size: 15px;
  color: var(--text-primary);
  white-space: nowrap;
}
.akv__chip svg { width: 15px; height: 15px; flex: none; color: #fff; }
.akv__chip--hot { border-color: rgba(255, 44, 44, .5); background: rgba(255, 44, 44, .09); }
/* karta „Mierzenie sprzedaży" (gate rundy 4): dwa kafle „1 zakup w sklepie"
   ≠ „2 zakupy według panelu" — nierówność widać po omieceniu wzrokiem */
.svc--ak .akv--neq { justify-content: center; gap: 18px; flex-wrap: nowrap; }
.akv__tile {
  flex: 1;
  max-width: 168px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 18px 12px 15px;
  border-radius: 14px;
  border: 1px solid var(--border-default);
  text-align: center;
}
.akv__tile b { font-size: 44px; font-weight: 600; line-height: 1; color: var(--text-primary); font-variant-numeric: tabular-nums; }
.akv__tile span { font-size: 13px; line-height: 1.35; color: var(--text-body); }
.akv__tile--hot { border-color: rgba(255, 44, 44, .5); background: rgba(255, 44, 44, .07); }
.akv__neq { flex: none; font-size: 34px; color: var(--text-muted); }
/* karta „Hasła i wykluczenia": wiersze zapytań (rozmiary szlif rundy 3) */
.svc--ak .gain__viz--funnel { gap: 9px; justify-content: center; }
.svc--ak .gain__fq { font-size: 14px; padding: 8px 14px; }
.svc--ak .gain__fq svg { width: 15px; height: 15px; }
.svc--ak .gain__fq em { font-size: 13px; }
/* karta „Struktura konta" (szlif rundy 4): svg z liniami rozpięty DOKŁADNIE
   między chipami (gap 0, flex:1) — końce linii dotykają krawędzi chipów,
   a kompozycja wypełnia całą szerokość karty */
.svc--ak .akv--clash { flex-wrap: nowrap; gap: 0; }
.akv__col { display: flex; flex-direction: column; gap: 14px; flex: none; }
.akv__conv { flex: 1; min-width: 50px; height: 92px; align-self: center; }
.akv__conv path { stroke: rgba(255, 255, 255, .6); stroke-width: 2; vector-effect: non-scaling-stroke; }
.akv-cut { opacity: .68; }
.akv-cut s { text-decoration: line-through; text-decoration-color: rgba(255, 255, 255, .65); }
/* karta „Grupy odbiorców" (runda 4): okręgi na całą szerokość karty, etykiety
   mówią o reklamach, część wspólna wyraźnie rozjaśniona i połączona kreską
   z PEŁNYM zdaniem pod grafiką (zamiast „płacisz 2×") */
.svc--ak .akv--venn { display: block; }
.akv__vstage { position: relative; width: 100%; margin: 0 auto; }
.akv__venn { display: block; width: 100%; height: auto; }
.akv__vlab {
  position: absolute;
  display: inline-flex;
  align-items: center;
  padding: 5px 12px;
  border-radius: 999px;
  border: 1px solid var(--border-default);
  background: #121212;
  font-size: 13px;
  color: var(--text-primary);
  white-space: nowrap;
}
.akv__vlab--l { left: 0; top: -2px; }
.akv__vlab--r { right: 0; top: -2px; }
.akv__vcap {
  display: block;
  margin-top: 2px;
  text-align: center;
  font-size: 15px;
  line-height: 1.4;
  color: var(--text-primary);
}
.svc--ak .akv--wear { flex-direction: column; align-items: stretch; gap: 10px; justify-content: center; }
.akv__wsvg { width: 100%; height: 62px; display: block; }
.akv__legend { display: inline-flex; align-items: center; gap: 8px; font-size: 14px; color: var(--text-body); }
.akv__legend i { width: 18px; border-top: 2.5px solid rgba(255, 255, 255, .75); }
.akv__axis { display: flex; justify-content: space-between; }
.akv__axis em { font-style: normal; font-size: 13px; color: var(--text-muted); }
/* karta „Budżety i automaty" (gate rundy 4): koszt zdobycia jednego klienta
   w trzech kampaniach, najdroższa oflagowana „za drogo" — puste .akv__pad
   w pozostałych wierszach trzyma paski w jednej linii */
.svc--ak .akv--cpa { flex-direction: column; align-items: stretch; gap: 12px; justify-content: center; flex-wrap: nowrap; }
.akv__cap { font-size: 13px; color: var(--text-muted); }
.akv__crow { display: flex; align-items: center; gap: 12px; font-size: 13px; color: var(--text-primary); }
.akv__crow em { font-style: normal; width: 108px; flex: none; }
.akv__crow strong { width: 50px; flex: none; text-align: right; font-weight: 600; font-variant-numeric: tabular-nums; }
.akv__pad, .akv__flag { flex: none; width: 76px; box-sizing: border-box; }
.akv__flag {
  text-align: center;
  padding: 3px 0;
  border-radius: 999px;
  border: 1px solid rgba(255, 44, 44, .5);
  background: rgba(255, 44, 44, .09);
  font-size: 13px;
  font-weight: 600;
  white-space: nowrap;
}
.akv__meter {
  flex: 1;
  min-width: 40px;
  height: 8px;
  border-radius: 5px;
  background: linear-gradient(90deg, rgba(255, 255, 255, .34) var(--w, 50%), rgba(255, 255, 255, .08) var(--w, 50%));
}
/* wąskie okna: mniejsze chipy i ciaśniejsze wiersze, żeby kompozycje zostały
   w jednej linii i nic nie wystawało poza kartę */
@media (max-width: 640px) {
  .svc--ak .akv { gap: 8px; }
  .svc--ak .akv--clash, .svc--ak .akv--neq { gap: 0; }
  .svc--ak .akv--neq { gap: 12px; }
  .akv__chip { font-size: 13px; padding: 6px 11px; }
  .akv__conv { height: 72px; }
  .akv__col { gap: 8px; }
  .akv__crow { gap: 8px; font-size: 13px; }
  .akv__crow em { width: 92px; }
  .akv__crow strong { width: 44px; }
  .akv__pad, .akv__flag { width: 66px; }
  .akv__tile b { font-size: 36px; }
}

/* --------------------------------------------------------------------------
   AUDYT KAMPANII — #dlaczego: pasek budżetu dzielony na części (.bsp).
   Koncepcja z gate rundy 3 (12.07, zastąpiła nieczytelny strumień): jeden
   pasek = cały budżet; czerwona część pracuje na sprzedaż (pozytyw, akcent
   marki), szare części to wycieki, każda podpisana pod swoim kawałkiem.
   Stały rozmiar — animacja tylko clip-path/opacity/transform.
   -------------------------------------------------------------------------- */
.svc--ak .bsp { max-width: 560px; width: 100%; margin-left: auto; }
.bsp .svc-win__body { padding: 22px 20px 24px; }
.bsp__stage { display: flex; flex-direction: column; }
.bsp__pill {
  align-self: flex-start;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 9px 14px;
  border-radius: 12px;
  border: 1px solid var(--border-subtle);
  background: var(--color-alpha-white-03, rgba(255, 255, 255, .03));
}
.bsp__pill em { font-style: normal; font-size: 13px; color: var(--text-muted); white-space: nowrap; }
.bsp__pill strong { font-size: 17px; color: var(--text-primary); white-space: nowrap; font-variant-numeric: tabular-nums; }
/* proporcje kawałków = kwoty: 4 080 / 3 100 / 1 850 z 9 030 zł */
.bsp__bar { display: flex; height: 38px; margin-top: 18px; border-radius: 10px; overflow: hidden; }
.bsp__seg--work { width: 45.2%; background: rgba(255, 44, 44, .16); box-shadow: inset 0 0 0 1.5px rgba(255, 44, 44, .65); border-radius: 10px 0 0 10px; }
.bsp__seg--l1 { width: 34.3%; background: rgba(255, 255, 255, .13); }
.bsp__seg--l2 { width: 20.5%; background: rgba(255, 255, 255, .07); }
.bsp__ticks { position: relative; height: 20px; }
.bsp__ticks i { position: absolute; left: var(--tx); top: 0; width: 1px; height: 20px; background: rgba(255, 255, 255, .25); }
/* etykiety w języku klienta (gate rundy 4) są dłuższe — mogą łamać się
   na dwie linie, więc rezerwa wysokości większa niż przy starych podpisach */
.bsp__labs { position: relative; height: 78px; }
.bsp__lab { position: absolute; top: 4px; display: flex; flex-direction: column; gap: 1px; }
.bsp__lab em { font-style: normal; font-size: 13px; line-height: 1.3; color: var(--text-muted); max-width: 180px; }
.bsp__lab strong { font-size: 15px; color: var(--text-primary); white-space: nowrap; font-variant-numeric: tabular-nums; }
.bsp__lab--work { left: 0; }
.bsp__lab--work em { white-space: nowrap; }
.bsp__lab--l1 { left: 47%; }
.bsp__lab--l2 { right: 0; align-items: flex-end; text-align: right; max-width: 152px; }
/* stany „przed animacją" tylko pod html.js — bez JS schemat od razu pełny */
html.js .svc [data-drain] .bsp__pill { opacity: 0; transform: translateY(6px); transition: opacity .55s var(--ease), transform .55s var(--ease); }
html.js .svc [data-drain].is-go .bsp__pill { opacity: 1; transform: none; }
html.js .svc [data-drain] .bsp__bar { clip-path: inset(0 100% 0 0); transition: clip-path 1.1s var(--ease) .35s; }
html.js .svc [data-drain].is-go .bsp__bar { clip-path: inset(0 0 0 0); }
html.js .svc [data-drain] .bsp__ticks i,
html.js .svc [data-drain] .bsp__lab { opacity: 0; transform: translateY(6px); transition: opacity .55s var(--ease), transform .55s var(--ease); }
html.js .svc [data-drain].is-go .bsp__ticks i:nth-child(1),
html.js .svc [data-drain].is-go .bsp__lab--work { opacity: 1; transform: none; transition-delay: .7s; }
html.js .svc [data-drain].is-go .bsp__ticks i:nth-child(2),
html.js .svc [data-drain].is-go .bsp__lab--l1 { opacity: 1; transform: none; transition-delay: 1s; }
html.js .svc [data-drain].is-go .bsp__ticks i:nth-child(3),
html.js .svc [data-drain].is-go .bsp__lab--l2 { opacity: 1; transform: none; transition-delay: 1.3s; }
html.js .svc [data-drain].is-instant .bsp__bar { clip-path: none; transition: none; }
html.js .svc [data-drain].is-instant .bsp__pill,
html.js .svc [data-drain].is-instant .bsp__ticks i,
html.js .svc [data-drain].is-instant .bsp__lab { opacity: 1; transform: none; transition: none; }
/* wąskie okna: podpisy jako lista pod paskiem, z próbką koloru kawałka */
@media (max-width: 640px) {
  .bsp__ticks { display: none; }
  .bsp__labs { height: auto; margin-top: 14px; display: flex; flex-direction: column; gap: 10px; }
  .bsp__lab { position: static; flex-direction: row; align-items: center; gap: 10px; }
  .bsp__lab::before { content: ""; width: 16px; height: 11px; border-radius: 3px; flex: none; }
  .bsp__lab--work::before { background: rgba(255, 44, 44, .16); box-shadow: inset 0 0 0 1.5px rgba(255, 44, 44, .65); }
  .bsp__lab--l1::before { background: rgba(255, 255, 255, .13); }
  .bsp__lab--l2::before { background: rgba(255, 255, 255, .07); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .14); }
  .bsp__lab em { margin-right: auto; max-width: none; }
  .bsp__lab--l2 { align-items: center; text-align: left; max-width: none; }
}
@media (prefers-reduced-motion: reduce) {
  html.js .svc [data-drain] .bsp__bar { clip-path: none !important; transition: none; }
  html.js .svc [data-drain] .bsp__pill,
  html.js .svc [data-drain] .bsp__ticks i,
  html.js .svc [data-drain] .bsp__lab { opacity: 1 !important; transform: none !important; transition: none; }
}

/* liczba-kotwica „do 40%" (runda 4): mniejsza niż standardowe .svc-big —
   w tej kompozycji z przedrostkiem „do" pełny rozmiar przytłaczał kolumnę;
   „do" jako mniejszy, spokojniejszy przedrostek przed liczbą */
.svc--ak .svc-big { font-size: clamp(64px, 7.5vw, 104px); }
.svc--ak .svc-big__pre { font-size: 28px; font-weight: 500; color: var(--text-body); margin-right: .12em; }

/* --------------------------------------------------------------------------
   AUDYT KAMPANII — #dostajesz: makieta raportu (.deliv).
   Fizyczny deliverable audytu (jasna „kartka" na ciemnym tle — jedyny jasny
   element strony, czyta się jak wydrukowany dokument). Stały rozmiar,
   animacja wejścia tylko przez data-rv (opacity/transform).
   -------------------------------------------------------------------------- */
/* układ dwukolumnowy dotyczy KAŻDEJ podstrony, która używa makiety dokumentu
   (wcześniej był przypisany tylko do audytów, więc na nowych stronach sekcja
   rozjeżdżała się: makieta nachodziła na nagłówek, a tekst leciał na całą szerokość) */
.deliv {
  display: grid;
  grid-template-columns: minmax(0, 420px) minmax(0, 540px);
  justify-content: center;
  align-items: center;
  gap: 64px;
  margin-top: 44px;
}
.deliv__doc { position: relative; width: min(380px, 100%); margin: 0 auto; }
.deliv__page {
  position: absolute;
  inset: 0;
  border-radius: 14px;
  background: #ddd5c8;
  box-shadow: 0 18px 44px rgba(0, 0, 0, .45);
}
.deliv__page--b1 { transform: rotate(-2.4deg) translate(-7px, 6px); }
.deliv__page--b2 { transform: rotate(3.2deg) translate(9px, 10px); background: #cfc6b8; }
.deliv__front {
  position: relative;
  border-radius: 14px;
  background: linear-gradient(160deg, #f7f3ec 0%, #ece5d9 100%);
  padding: 26px 26px 24px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, .5);
}
.deliv__kicker { margin: 0 0 10px; font-size: 13px; letter-spacing: .08em; text-transform: uppercase; color: #6b6357; }
.deliv__title { margin: 0; font-size: 27px; font-weight: 700; line-height: 1.1; color: #17130e; }
.deliv__for { margin: 6px 0 18px; font-size: 14px; color: #5f574a; }
.deliv__shot {
  position: relative;
  border-radius: 10px;
  border: 1px solid #d8cfc0;
  background: #fbf8f2;
  padding: 12px 12px 30px;
  display: flex;
  flex-direction: column;
  gap: 9px;
}
.deliv__shot-row { display: flex; gap: 8px; align-items: center; }
.deliv__shot-row i { display: block; height: 9px; border-radius: 5px; background: #d9d0c0; width: var(--w, 50%); }
.deliv__shot-row i:last-child { margin-left: auto; }
.deliv__shot-row--mark { position: relative; }
.deliv__shot-row--mark i { background: #c9bda7; }
.deliv__shot-row--mark::after {
  content: "";
  position: absolute;
  inset: -6px -7px;
  border: 1.6px solid var(--accent-default);
  border-radius: 8px;
  pointer-events: none;
}
.deliv__note { position: absolute; right: 11px; bottom: 7px; font-style: normal; font-size: 13px; color: #8a7f6e; }
.deliv__verdict {
  margin-top: 12px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 10px;
  border-radius: 10px;
  border: 1px solid #d8cfc0;
  background: #fbf8f2;
  padding: 10px 12px;
  font-size: 14px;
  color: #3d372e;
}
.deliv__verdict em { font-style: normal; font-weight: 700; color: #17130e; white-space: nowrap; }
.deliv__prio-head { margin: 16px 0 9px; font-size: 13px; letter-spacing: .06em; text-transform: uppercase; color: #6b6357; }
.deliv__prio { display: flex; flex-wrap: wrap; gap: 8px; }
.deliv__chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  border-radius: 999px;
  border: 1px solid #d2c8b8;
  background: #f4efe6;
  padding: 7px 12px;
  font-size: 13px;
  color: #3d372e;
  white-space: nowrap;
}
.deliv__chip b {
  display: inline-grid;
  place-items: center;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--accent-default);
  color: #fff;
  font-size: 13px;
  font-weight: 700;
}
.deliv__head { margin: 0 0 14px; font-size: 15px; font-weight: 600; color: var(--text-primary); }
.deliv__why { margin: 18px 0 24px; font-size: 15px; line-height: 1.65; color: var(--text-body); }
.deliv__why strong { color: var(--text-primary); }
/* Na telefonie makieta i tekst MUSZĄ stanąć jeden pod drugim — na każdej podstronie,
   która używa makiety dokumentu, tak samo jak reguła .deliv wyżej.
   Wcześniej ta reguła (jako jedyna) była nadal przypisana do .svc--ak/.svc--as, więc
   /lejki-marketingowe/, /strategia-marketingowa/ i /strony-internetowe/ trzymały na
   telefonie DWIE kolumny po 136 px: kartka gniotła się w pasek (napisy wychodziły poza
   nią), a kolumna z listą i przyciskiem uciekała poza ekran. */
@media (max-width: 980px) {
  .deliv { grid-template-columns: 1fr; gap: 44px; }
  .deliv__body { max-width: 560px; margin: 0 auto; }
}

/* ==========================================================================
   AUDYT SEO — hero: prześwietlenie strony (.xrw, data-xray).
   Mechanika wybrana przez Karola w gate (12.07, żywy podgląd trzech wariantów):
   RENTGEN — makieta strony klienta „wywołuje się" element po elemencie w widok,
   którym ocenia ją Google, i każdy element dostaje werdykt prostym językiem.
   Świadomie INNA mechanika niż pas światła z /audyt-kampanii/ (reguła: każda
   strona ma własną animację hero). Okno ma STAŁY rozmiar — animujemy wyłącznie
   opacity/transform. Czerwień = akcent (numery kolejności napraw, ramka planu),
   NIGDY kolor błędu: znaleziska mają białe ramki i biały tekst.
   Bez JS i przy reduced-motion: stan końcowy od razu.
   ========================================================================== */
.xrw { max-width: 560px; margin-left: auto; width: 100%; }
.xrw .svc-win__body { padding: 16px; }
/* Makieta ma się czytać jako JEDNA strona, nie zbiór kafli: fragmenty leżą
   na wspólnej „kartce" (tło + ramka rysowane pod lewą kolumną), a werdykty
   wychodzą na margines i są PRZYCZEPIONE kreską do swojego fragmentu. */
.xrw__site { position: relative; display: flex; flex-direction: column; gap: 4px; }
.xrw__site::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: calc(100% - 190px);
  border-radius: 12px;
  border: 1px solid var(--border-subtle);
  background: var(--color-alpha-white-03, rgba(255, 255, 255, .03));
}
.xrw__row {
  position: relative;
  display: grid;
  grid-template-columns: 1fr 168px;
  gap: 22px;
  align-items: center;
}
/* rozbłysk „wywołania" zdjęcia rentgenowskiego: warstwa nad fragmentem strony,
   tylko opacity — gaśnie sama, nie zostaje na ekranie */
.xrw__flash {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: calc(100% - 190px);
  border-radius: 9px;
  pointer-events: none;
  opacity: 0;
  background: radial-gradient(120% 100% at 50% 50%, rgba(255, 255, 255, .16), transparent 70%);
}
.xrw__row.is-flash .xrw__flash { animation: xrwFlash .8s ease-out; }
@keyframes xrwFlash {
  0% { opacity: 0; }
  28% { opacity: 1; }
  100% { opacity: 0; }
}
/* szkielet strony klienta — to, co widzi człowiek. Fragment prześwietlony
   podświetla się na jasno (biel, nigdy czerwień: status negatywny nie może
   czytać się jak błąd), reszta kartki zostaje spokojna. */
.xrw__wf {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
  padding: 10px 12px;
  border-radius: 9px;
  background: transparent;
  transition: background .55s var(--ease);
}
.xrw__row.is-x .xrw__wf { background: rgba(255, 255, 255, .07); }
.xrw__wf i { display: block; height: 7px; border-radius: 4px; background: rgba(255, 255, 255, .2); }
.xrw__wf .xrw-im {
  height: 46px;
  border-radius: 8px;
  background: linear-gradient(145deg, rgba(255, 255, 255, .16), rgba(255, 255, 255, .06));
}
.xrw__wf .xrw-btn { width: 62px; height: 16px; border-radius: 6px; background: rgba(255, 255, 255, .3); }
.xrw__wf .xrw-nav { display: flex; gap: 6px; align-items: center; }
.xrw__wf .xrw-nav i { width: 32px; }
.xrw__wf .xrw-nav .xrw-lg { width: 22px; height: 14px; border-radius: 5px; background: rgba(255, 255, 255, .34); }
.xrw__wf .xrw-tiles { display: flex; gap: 6px; }
.xrw__wf .xrw-tiles i { flex: 1; height: 30px; border-radius: 7px; }
/* ten sam element „oczami Google": kontur zamiast wypełnienia, obrazek bez
   opisu = zakreskowane pole. Zmienia się tło i obwódka, nigdy rozmiar. */
.xrw__wf i, .xrw__wf .xrw-im { transition: background .55s var(--ease), box-shadow .55s var(--ease); }
.xrw__row.is-x .xrw__wf i,
.xrw__row.is-x .xrw__wf .xrw-im {
  background: transparent;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .3);
}
.xrw__row.is-x .xrw__wf .xrw-im {
  background: repeating-linear-gradient(135deg, rgba(255, 255, 255, .05) 0 6px, transparent 6px 12px);
}
/* werdykt w zarezerwowanej kolumnie: numer kolejności napraw wchodzi obok
   tekstu (miejsce na niego jest od początku), więc plakietka nie rośnie.
   Kreska WYCHODZI z krawędzi kartki i WCHODZI w plakietkę — widać, którego
   fragmentu strony dotyczy werdykt. */
.xrw__chip {
  position: relative;
  justify-self: end;
  display: flex;
  align-items: flex-start;
  gap: 9px;
  width: 100%;
  padding: 8px 12px;
  border-radius: 12px;
  border: 1px solid rgba(255, 255, 255, .42);
  background: #101014;
  font-size: 13px;
  line-height: 1.35;
  color: var(--text-body);
}
.xrw__chip::before {
  content: "";
  position: absolute;
  right: 100%;
  top: 50%;
  width: 22px;
  height: 1px;
  background: rgba(255, 255, 255, .38);
}
.xrw__chip b { display: block; font-weight: 600; color: var(--text-primary); }
.xrw__pri {
  flex: none;
  display: grid;
  place-items: center;
  width: 21px;
  height: 21px;
  margin-top: 1px;
  border-radius: 50%;
  background: var(--accent-default);
  color: #fff;
  font-size: 13px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.xrw__sum {
  margin-top: 13px;
  display: grid;
  padding: 13px 16px;
  border-radius: 12px;
  border: 1px solid rgba(255, 44, 44, .45);
  background: rgba(255, 44, 44, .08);
}
.xrw__sum-a, .xrw__sum-b {
  grid-area: 1 / 1;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  transition: opacity .55s var(--ease);
}
.xrw__sum em { font-style: normal; font-size: 15px; color: var(--text-body); }
.xrw__sum strong { font-size: 17px; color: var(--text-primary); white-space: nowrap; font-variant-numeric: tabular-nums; }
/* stany „przed animacją" wyłącznie pod html.js — bez JS widać pełny wynik
   (werdykty i licznik); numery kolejności to stan przejściowy animacji */
html.js .svc [data-xray] .xrw__chip {
  opacity: 0;
  transform: translateX(10px);
  transition: opacity .5s var(--ease), transform .5s cubic-bezier(.2, 1.3, .4, 1);
}
html.js .svc [data-xray] .xrw__row.is-x .xrw__chip { opacity: 1; transform: none; }
html.js .svc [data-xray] .xrw__pri { opacity: 0; transition: opacity .5s var(--ease); }
html.js .svc [data-xray].is-plan .xrw__pri { opacity: 1; }
html.js .svc [data-xray] .xrw__sum {
  opacity: 0;
  transform: translateY(6px);
  transition: opacity .6s var(--ease), transform .6s var(--ease);
}
html.js .svc [data-xray].is-sum .xrw__sum { opacity: 1; transform: none; }
html.js .svc [data-xray] .xrw__sum-b { opacity: 0; }
html.js .svc [data-xray].is-plan .xrw__sum-a { opacity: 0; }
/* zwłoka: najpierw znika licznik, potem wjeżdża plan (napisy się nie nakładają) */
html.js .svc [data-xray].is-plan .xrw__sum-b { opacity: 1; transition-delay: .45s; }
/* stan końcowy bez ruchu (telefon / ograniczenie animacji): werdykty + licznik */
html.js .svc [data-xray].is-instant .xrw__chip,
html.js .svc [data-xray].is-instant .xrw__sum { opacity: 1; transform: none; transition: none; }
html.js .svc [data-xray].is-instant .xrw__pri { opacity: 1; transition: none; }
html.js .svc [data-xray].is-instant .xrw__sum-b { opacity: 0; }
/* wąskie okna: kartka strony na całą szerokość, werdykt pod fragmentem
   (kreska-łącznik znika — nie ma marginesu, na którym mogłaby wisieć),
   podsumowanie w dwóch linijkach, żeby nie łamało się w pół słowa */
@media (max-width: 640px) {
  .xrw__site::before { width: 100%; }
  .xrw__site { gap: 10px; }
  .xrw__row { grid-template-columns: 1fr; gap: 8px; }
  .xrw__flash { width: 100%; }
  .xrw__chip { justify-self: stretch; }
  .xrw__chip::before { display: none; }
  .xrw__sum-a, .xrw__sum-b { flex-direction: column; align-items: flex-start; gap: 3px; }
  .xrw__sum em { white-space: nowrap; }
}
@media (prefers-reduced-motion: reduce) {
  html.js .svc [data-xray] .xrw__chip,
  html.js .svc [data-xray] .xrw__sum,
  html.js .svc [data-xray] .xrw__pri { opacity: 1 !important; transform: none !important; transition: none; }
  html.js .svc [data-xray] .xrw__sum-b { opacity: 0 !important; }
  .xrw__row.is-flash .xrw__flash { animation: none; }
}

/* --------------------------------------------------------------------------
   AUDYT SEO — #dlaczego: ta sama strona, dwa spojrzenia (.gvw, data-gview).
   Koncepcja wybrana w gate: po lewej strona oczami klienta, po prawej ta sama
   strona oczami Google (kontury zamiast obrazków + lista tego, czego Google
   nie dostaje). Ustawia narrację całej strony: audyt pokazuje Twoją stronę
   oczami wyszukiwarki. Stały rozmiar, animacja tylko opacity/transform/tło.
   -------------------------------------------------------------------------- */
.svc--as .gvw { max-width: 560px; width: 100%; margin-left: auto; }
.gvw .svc-win__body { padding: 20px 18px 22px; }
/* panele równej wysokości (stretch) — nierówne kolumny czytały się jak usterka */
.gvw__stage { display: grid; grid-template-columns: 1fr auto 1fr; gap: 12px; align-items: stretch; }
.gvw__pane {
  border: 1px solid var(--border-subtle);
  border-radius: 14px;
  padding: 14px;
  background: var(--color-alpha-white-03, rgba(255, 255, 255, .03));
}
.gvw__pane--g { border-color: rgba(255, 255, 255, .3); }
.gvw__h {
  margin: 0 0 11px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .02em;
  color: var(--text-muted);
}
.gvw__neq { align-self: center; font-size: 26px; color: var(--text-muted); }
.gvw__miss { margin-top: 12px; display: flex; flex-direction: column; gap: 7px; }
.gvw__miss em {
  font-style: normal;
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  line-height: 1.35;
  color: var(--text-body);
}
.gvw__miss em::before {
  content: "";
  flex: none;
  width: 12px;
  height: 1.5px;
  background: rgba(255, 255, 255, .5);
}
/* panel „oczami Google" wywołuje się przy wejściu na sekcję; bez JS stoi gotowy */
html.js .svc [data-gview] .gvw__pane--g .xrw__wf i { background: rgba(255, 255, 255, .2); box-shadow: none; }
html.js .svc [data-gview] .gvw__pane--g .xrw__wf .xrw-im {
  background: linear-gradient(145deg, rgba(255, 255, 255, .16), rgba(255, 255, 255, .06));
  box-shadow: none;
}
html.js .svc [data-gview].is-go .gvw__pane--g .xrw__wf i,
html.js .svc [data-gview].is-go .gvw__pane--g .xrw__wf .xrw-im {
  background: transparent;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .3);
}
html.js .svc [data-gview].is-go .gvw__pane--g .xrw__wf .xrw-im {
  background: repeating-linear-gradient(135deg, rgba(255, 255, 255, .05) 0 6px, transparent 6px 12px);
}
html.js .svc [data-gview] .gvw__miss em {
  opacity: 0;
  transform: translateY(6px);
  transition: opacity .5s var(--ease), transform .5s var(--ease);
}
html.js .svc [data-gview].is-go .gvw__miss em { opacity: 1; transform: none; }
html.js .svc [data-gview].is-go .gvw__miss em:nth-child(1) { transition-delay: .55s; }
html.js .svc [data-gview].is-go .gvw__miss em:nth-child(2) { transition-delay: .85s; }
html.js .svc [data-gview].is-go .gvw__miss em:nth-child(3) { transition-delay: 1.15s; }
html.js .svc [data-gview].is-instant .gvw__miss em { opacity: 1; transform: none; transition: none; }
.svc--as .svc-big-sub { max-width: 36ch; }
@media (max-width: 640px) {
  .gvw__stage { grid-template-columns: 1fr; }
  .gvw__neq { justify-self: center; }
}
@media (prefers-reduced-motion: reduce) {
  html.js .svc [data-gview] .gvw__miss em { opacity: 1 !important; transform: none !important; transition: none; }
}

/* --------------------------------------------------------------------------
   AUDYT SEO — #zakres: mini-grafika w KAŻDEJ karcie (.asv).
   Wzorzec z /audyt-kampanii/ (karty z samym tekstem czytają się jako leniwe).
   Wysokość grafik wyrównana, etykiety w języku klienta, czerwień tylko jako
   akcent znaleziska. Liczby ilustracyjne zgodne z makietą w hero.
   -------------------------------------------------------------------------- */
.svc--as .gain__viz { min-height: 150px; width: 100%; }
.svc--as .asv { align-items: stretch; justify-content: center; gap: 10px; }
.asv__cap { font-size: 13px; line-height: 1.35; color: var(--text-muted); }
/* 1. Czy Google widzi całą stronę: kafle podstron, część tylko w konturze */
.asv--pages { display: flex; flex-direction: column; gap: 12px; justify-content: center; }
.asv__pgrid { display: grid; grid-template-columns: repeat(6, 1fr); gap: 7px; }
.asv__pg { height: 44px; border-radius: 7px; background: rgba(255, 255, 255, .22); }
.asv__pg--off { background: transparent; box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .28); }
.asv__prow { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.asv__prow em { font-style: normal; font-size: 13px; color: var(--text-body); }
.asv__prow strong { font-size: 15px; color: var(--text-primary); font-variant-numeric: tabular-nums; }
/* 2. Szybkość: oś z granicą cierpliwości klienta i wynikiem strony */
.asv--speed { display: flex; flex-direction: column; gap: 14px; justify-content: center; }
.asv__track { position: relative; height: 10px; border-radius: 6px; background: rgba(255, 255, 255, .09); }
.asv__fill {
  position: absolute;
  inset: 0 auto 0 0;
  width: var(--w, 50%);
  border-radius: 6px;
  background: rgba(255, 255, 255, .34);
}
/* kreska progu SIĘGA do swojej etykiety (etykieta stoi dokładnie pod kreską,
   nie na brzegu) — inaczej nie widać, czego dotyczy podpis */
.asv__limit { position: absolute; left: var(--lx, 47%); top: -9px; bottom: -10px; width: 1.5px; background: rgba(255, 44, 44, .8); }
.asv__labs { position: relative; height: 44px; }
.asv__lab { position: absolute; top: 0; display: flex; flex-direction: column; gap: 1px; max-width: 150px; }
.asv__lab em { font-style: normal; font-size: 13px; line-height: 1.3; color: var(--text-muted); }
.asv__lab strong { font-size: 15px; color: var(--text-primary); font-variant-numeric: tabular-nums; }
.asv__lab--limit { left: var(--lx, 47%); transform: translateX(-50%); text-align: center; align-items: center; }
.asv__lab--you { right: 0; text-align: right; align-items: flex-end; }
/* 3. Treść: czego szuka klient kontra co mówi strona */
.asv--words { display: flex; flex-direction: column; gap: 10px; justify-content: center; }
.asv__q {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 8px 13px;
  border-radius: 24px;
  background: #303134;
  border: 1px solid var(--serp-line);
  font-size: 14px;
  color: #e8eaed;
}
.asv__q svg { width: 15px; height: 15px; flex: none; color: var(--serp-mut); }
.asv__q em { font-style: normal; margin-left: auto; padding-left: 10px; font-size: 13px; color: var(--serp-mut); white-space: nowrap; }
.asv__said {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 8px 13px;
  border-radius: 12px;
  border: 1px solid var(--border-default);
  font-size: 14px;
  color: var(--text-primary);
}
.asv__said em { font-style: normal; margin-left: auto; padding-left: 10px; font-size: 13px; color: var(--text-muted); white-space: nowrap; }
.asv__neq { align-self: center; font-size: 20px; color: var(--text-muted); line-height: 1; }
/* 4. Struktura: podstrony połączone linkami, część wisi w próżni */
.asv--map { display: flex; flex-direction: column; justify-content: center; gap: 10px; }
.asv__map { display: block; width: 100%; height: auto; }
.asv__map .lk { stroke: rgba(255, 255, 255, .42); stroke-width: 1.8; vector-effect: non-scaling-stroke; }
.asv__map .nd { fill: rgba(255, 255, 255, .24); }
.asv__map .nd--home { fill: rgba(255, 255, 255, .42); }
.asv__map .nd--lost {
  fill: transparent;
  stroke: rgba(255, 255, 255, .34);
  stroke-width: 1.4;
  stroke-dasharray: 5 3;
  vector-effect: non-scaling-stroke;
}
.asv__mcap { display: block; text-align: center; font-size: 14px; color: var(--text-primary); }
/* 5. Linki z innych stron: polecenia wartościowe i podejrzane */
/* liczba kwadracików = liczba linków w danym wierszu (policzalna wzrokiem,
   więc grafika nie kłóci się z żadną liczbą pod spodem) */
.asv--links { display: flex; flex-direction: column; gap: 11px; justify-content: center; }
.asv__lrow { display: flex; align-items: center; gap: 9px; font-size: 13px; color: var(--text-primary); }
.asv__lrow em { font-style: normal; width: 104px; flex: none; line-height: 1.3; color: var(--text-body); }
.asv__ldots { display: flex; gap: 5px; flex-wrap: nowrap; flex: 1; }
.asv__ldots i { width: 10px; height: 10px; flex: none; border-radius: 3px; background: rgba(255, 255, 255, .32); }
.asv__ldots--bad i { background: transparent; box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .3); }
/* pusty odstęp o szerokości plakietki — kropki obu wierszy kończą się równo */
.asv__pad, .asv__flag { flex: none; width: 96px; box-sizing: border-box; }
.asv__flag {
  padding: 3px 10px;
  border-radius: 999px;
  border: 1px solid rgba(255, 44, 44, .5);
  background: rgba(255, 44, 44, .09);
  font-size: 13px;
  font-weight: 600;
  white-space: nowrap;
}
/* 6. Konkurencja: te same zapytania, ich widać, Ciebie nie */
.asv--rivals { display: flex; flex-direction: column; gap: 9px; justify-content: center; }
.asv__rrow { display: flex; align-items: center; gap: 10px; font-size: 13px; }
.asv__rq {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 12px;
  border-radius: 24px;
  background: #303134;
  border: 1px solid var(--serp-line);
  color: #e8eaed;
  white-space: nowrap;
  overflow: hidden;
}
.asv__rq svg { width: 14px; height: 14px; flex: none; color: var(--serp-mut); }
.asv__rpos {
  flex: none;
  width: 86px;
  text-align: right;
  color: var(--text-body);
  font-variant-numeric: tabular-nums;
}
.asv__rpos--you { color: var(--text-primary); font-weight: 600; }
@media (max-width: 640px) {
  .asv__pgrid { grid-template-columns: repeat(6, 1fr); gap: 5px; }
  .asv__lrow em { width: 108px; }
  .asv__rpos { width: 74px; font-size: 13px; }
}

/* --------------------------------------------------------------------------
   AUDYT SEO — #lista: pełny zakres audytu (.scope) + granica usługi (.excl).
   Uwaga Karola (12.07): zakres ma być REALNY, oparty na researchu rynku, nie
   wymyślony — 48 punktów kontrolnych w 4 obszarach (źródła w
   docs/research/research-zakres-audytu.md), każdy przetłumaczony na język
   właściciela firmy. Blok „czego audyt nie obejmuje" to nasza przewaga:
   z 6 zbadanych agencji pisze o tym tylko jedna.
   Akordeony reużywają komponentu .faq (ten sam mechanizm otwierania).
   -------------------------------------------------------------------------- */
.scope { margin-top: 44px; }
.scope__q { display: flex; align-items: center; gap: 14px; text-align: left; }
/* liczba punktów w obszarze: kółko z liczbą, czerwień jako akcent porządku */
.scope__n {
  flex: none;
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: 1px solid rgba(255, 44, 44, .5);
  background: rgba(255, 44, 44, .09);
  font-size: 15px;
  font-weight: 700;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
}
.scope__list {
  list-style: none;
  margin: 0;
  padding: 0 4px 4px 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px 28px;
}
.scope__list li {
  position: relative;
  padding-left: 20px;
  font-size: 15px;
  line-height: 1.55;
  color: var(--text-body);
}
/* znacznik pozycji: krótka biała kreska (znaczniki wyboru zostają białe,
   a tu i tak nie są potwierdzeniem, tylko punktem listy) */
.scope__list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 11px;
  width: 11px;
  height: 1.5px;
  background: rgba(255, 255, 255, .45);
}
@media (max-width: 860px) {
  .scope__list { grid-template-columns: 1fr; gap: 10px; }
}

/* granica usługi: co NIE wchodzi w cenę audytu */
.excl {
  margin-top: 34px;
  padding: 30px 32px;
  border-radius: 24px;
  border: 1px solid var(--border-card);
  background: linear-gradient(180deg, var(--surface-raised), var(--surface-sunken));
}
.excl__head { margin: 0; font-size: 19px; font-weight: 600; color: #fff; }
.excl__lead { margin: 8px 0 0; font-size: 15px; line-height: 1.6; color: var(--text-body); }
.excl__list {
  list-style: none;
  margin: 20px 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px 28px;
}
.excl__list li { display: flex; align-items: flex-start; gap: 12px; }
/* znak „poza zakresem": pusty okrąg (nie czerwony krzyżyk — czerwień nie jest
   kolorem błędu, a to nie jest błąd, tylko granica usługi) */
.excl__list li > span {
  flex: none;
  width: 18px;
  height: 18px;
  margin-top: 3px;
  border-radius: 50%;
  border: 1.5px solid rgba(255, 255, 255, .4);
}
.excl__list p { margin: 0; font-size: 15px; line-height: 1.6; color: var(--text-body); }
.excl__list strong { color: var(--text-primary); }
@media (max-width: 860px) {
  .excl { padding: 24px 20px; }
  .excl__list { grid-template-columns: 1fr; }
}

/* ==========================================================================
   LEJKI MARKETINGOWE (Seria 14.4)
   Hero: lejek z ludźmi (.fnw / .fnl) — kropki-ludzie płyną w dół, na etapie
   „ogląda ofertę" strumień ucieka dziurą w ścianie, w puencie dziura zostaje
   załatana i licznik kupujących rośnie. Animujemy WYŁĄCZNIE transform/opacity,
   okno ma stały rozmiar. Etapy i liczby stoją POZA lejkiem (przyczepione
   kreską), więc wnętrze należy do ludzi i nic na nic nie nachodzi.
   ========================================================================== */
.svc--lej .svc-big { font-size: clamp(72px, 8.6vw, 132px); }

/* OSADZENIE WIELKIEJ LICZBY (uwaga Karola: „5% dociągnięte do lewej dziwnie wygląda").
   Zdiagnozowane POMIAREM, nie okiem — dwie osobne przyczyny:

   1. Sekcja była WĘŻSZA niż reszta strony. `.svc-sec--full` jest kontenerem
      elastycznym (flex), a `.container` ma w środku `margin-inline: auto` — auto-margines
      w poprzek osi flexa kasuje rozciąganie i kontener KURCZY SIĘ DO ZAWARTOŚCI.
      Zmierzone: sekcja „dlaczego" 1246 px przy sąsiednich 1425 px, czyli liczba
      zaczynała się 90 px dalej od lewej niż nagłówek strony. Na sekcjach z tekstem
      wyśrodkowanym tego nie widać — widać dokładnie tam, gdzie treść jest do lewej.
      (Ten sam mechanizm działa na pozostałych 6 podstronach — nie ruszam ich bez zgody.)

   2. Tusz cyfry zaczyna się DALEJ niż krawędź jej pudełka (lewy odsadzik glifu).
      Zmierzone canvasem: „5" ma 7,0 px odsadzika przy foncie 123,84 px (= .057em),
      a akapit pod spodem tylko 1 px. Lewa krawędź wychodziła poszarpana.
      Korekta w `em` skaluje się razem z fontem, więc trzyma się też na telefonie. */
.svc--lej #dlaczego > .container,
.svc--strat #dlaczego > .container { width: 100%; }
.svc--lej .svc-big { margin-left: -.057em; }   /* glif „5" */

/* SVG skalowany PROPORCJONALNIE (preserveAspectRatio="xMidYMid meet"), nie
   rozciągany. Rozciąganie robiło kreski grubsze w pionie niż w poziomie i to
   ono dawało „tani", niechlujny wygląd. Skalę i przesunięcie liczy JS. */

/* TŁO BEZ RAMKI (uwaga Karola: po zdjęciu udawanego okna „wygląda surowo").
   Zamiast obwódki — miękka CIEMNA poświata bez krawędzi. Dwa zadania:
   1. daje głębię i osadza lejek w kadrze, ale nie udaje okna;
   2. ⚠️ wygasza czerwoną poświatę tła sekcji, którą wcześniej zasłaniało ciemne
      okno. Bez tego cały lejek pływał w czerwieni — a czerwień ma być RZADKO
      i tylko tam, gdzie coś znaczy (tu: uciekający ludzie i otwór). */
/* BEZ ŻADNEJ PODKŁADKI POD LEJKIEM (decyzja Karola). Ani ramki udawanego okna,
   ani ciemnej poświaty — lejek leży wprost na tle sekcji. */
.fnw { position: relative; }

.fnl__stage {
  position: relative;
  height: 340px;
  overflow: hidden;
}
.fnl__svg { position: absolute; inset: 0; width: 100%; height: 100%; }

/* korpus naczynia — szkło z gradientem, nie płaski trapez */
.fnl__glass { fill: url(#fnlGlass); }
.fnl__floor { fill: url(#fnlFloor); }
/* ściany GRUBSZE (uwaga Karola: „linie tworzące lejek bardzo cienkie") */
.fnl__wall {
  fill: none;
  stroke: rgba(255, 255, 255, .46);
  stroke-width: 2.6;
  stroke-linejoin: round;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
}
/* (usunięte: „światło na szkle" wzdłuż lewej ściany — czytało się jako kreska
   niepodłączona do niczego, czyli dokładnie „linia urywająca się w powietrzu") */
/* wlot i wylot jako elipsy = naczynie widziane pod kątem, a nie rysunek trapezu */
.fnl__rim { fill: none; stroke: rgba(255, 255, 255, .55); stroke-width: 2.4; vector-effect: non-scaling-stroke; }
.fnl__rimfill { fill: rgba(255, 255, 255, .06); }

/* poszarpane krawędzie pęknięcia — otwór ma wyglądać na WYRWANY, nie narysowany */
.fnl__crack {
  fill: none;
  stroke: rgba(255, 255, 255, .46);
  stroke-width: 2.6;
  stroke-linejoin: round;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
  /* przy restarcie pętli poszarpane krawędzie WRACAJĄ płynnie, a nie wyskakują */
  transition: opacity .5s ease;
}
/* poświata otworu — jedyne miejsce, gdzie świeci czerwień. Zapala się raz i zostaje:
   dziura NIE jest już łatana (decyzja Karola — hero pokazuje sam problem). */
.fnl__glow { fill: url(#fnlGlow); opacity: 0; transition: opacity .7s ease; }
.fnw.is-leak .fnl__glow { opacity: 1; }

/* kropka = człowiek; pozycję ustawia JS transformem, nigdy layoutem.
   Ujemny margines wyśrodkowuje kropkę na wyliczonym punkcie. */
.fnl__d {
  position: absolute;
  top: 0;
  left: 0;
  width: 9px;
  height: 9px;
  margin: -4.5px 0 0 -4.5px;
  border-radius: 50%;
  background: #f2f3f5;
  box-shadow: 0 1px 3px rgba(0, 0, 0, .6);
  will-change: transform, opacity;
}
/* uciekł otworem = stracony */
.fnl__d.is-lost { background: var(--accent-default); box-shadow: 0 0 8px rgba(255, 44, 44, .6); }
/* doleciał na dół = kupił: błyska */
.fnl__d.is-buy { background: #fff; box-shadow: 0 0 14px rgba(255, 255, 255, .9); }

/* JEDYNA pigułka w kadrze — stoi NAD torem lotu uciekinierów i na prawo od
   ściany, więc nic nie zasłania i nic jej nie zasłania. Pozycję liczy JS
   z geometrii lejka, nie z krawędzi okna. */
.fnl__chip {
  position: absolute;
  padding: 8px 14px;
  border-radius: 999px;
  font-size: 15px;
  font-weight: 600;
  white-space: nowrap;
  background: rgba(255, 44, 44, .14);
  border: 1px solid rgba(255, 44, 44, .45);
  color: #ffd9d9;
  opacity: 0;
  transform: translateY(4px);
  transition: opacity .5s ease, transform .5s ease;
}
.fnw.is-leak .fnl__chip { opacity: 1; transform: none; }

/* PODPISY POZA SCENĄ (nad i pod lejkiem). Wcześniej wisiały w środku i musiały być
   drobne, żeby się zmieścić — Karol: „treści wokół lejka są za małe, mają być podobne
   do podpisu pod nagłówkiem" (ten ma 20 px). Poza sceną mają własne miejsce, więc mogą
   być duże. Efekt uboczny: żaden człowiek nie ma jak na nie wejść, bo scena jest
   przycięta — kropka nie zasłoni napisu z definicji, a nie „bo tak wyliczyłem". */
/* 20px = DOKŁADNIE tyle, co akapit pod nagłówkiem obok (zmierzone) */
.fnl__in {
  margin: 0 0 8px;
  text-align: center;
  font-size: 20px;
  line-height: 1.4;
  color: var(--text-body);
}

.fnl__out {
  margin: 10px 0 0;
  text-align: center;
  font-size: 20px;
  font-weight: 600;
  line-height: 1.3;
  color: var(--text-body);
}

/* ---------- sekcja „dlaczego": DROGA JEDNEGO KLIENTA (przebudowa, sesja 17) ----------
   Karol o poprzedniej wersji: „nie rozumiem jej sensu, to są 2 różne osoby, ta sama
   osoba? dlaczego w linii kupuje u kogoś innego nie ma kropek".

   Trzy diagnozy i trzy odpowiedzi:
   1. Dwie sylwetki naraz czytały się jako dwie osoby → jest JEDEN człowiek, jedno
      rozwidlenie drogi i dwa warianty tej samej historii, jeden PO drugim.
   2. Brak kropek na dolnej drodze wyglądał jak niedokończona grafika → nieobecność
      pokazujemy ZDARZENIEM: znak Twojej marki gaśnie w myśli klienta, a pustkę
      po nim zajmuje czyjś inny znak. Pustką niczego nie da się pokazać.
   3. Odstawało jakością od hero → scena jest bez ramki okna, z pełnowymiarowym
      człowiekiem, chmurką myśli i prawdziwymi sklepami (poprzeczka: „udawaj
      prawdziwą rzecz, nie rysuj schematu").

   BEZ JS scena stoi w stanie KOŃCOWYM (człowiek u Twoich drzwi, znak zapalony). */
.jrw { position: relative; }
/* miękka ciemna poświata BEZ KRAWĘDZI — daje głębię i wygasza czerwoną poświatę
   sekcji, ale nie udaje okna (elipsa wpisana w kadr, nie prostokąt z gradientem,
   bo gradient w prostokącie urywa się prostą linią przy krawędzi) */
.jrw::before,
.pulw::before {
  content: "";
  position: absolute;
  inset: -6% -4%;
  background: radial-gradient(ellipse closest-side at 50% 50%, rgba(0, 0, 0, .62), rgba(0, 0, 0, 0) 90%);
  pointer-events: none;
}
.jrn,
.pul { position: relative; width: 100%; height: auto; display: block; }

/* JEZDNIA: ciemny pas + przerywana linia środkowa. Dwie kreski 2 px nie czytały się
   jako droga (S3 — laik ma rozpoznać rzecz, nie odgadywać schemat). */
.jrn__asph { fill: none; stroke: #17181c; stroke-width: 17; stroke-linecap: round; }
.jrn__mid {
  fill: none;
  stroke: rgba(255, 255, 255, .26);
  stroke-width: 1.6;
  stroke-dasharray: 13 12;
  stroke-linecap: round;
}

/* TWOJE REKLAMY PRZY DRODZE — tabliczki ze znakiem marki, nie kropki.
   Zapalają się w chwili minięcia (ZDARZENIE, nie tło). */
.jrn__png-card { fill: rgba(255, 44, 44, .16); stroke: rgba(255, 44, 44, .5); stroke-width: 1.4; transition: fill .3s ease, stroke .3s ease; }
.jrn__png-mk path,
.jrn__png-mk circle { fill: rgba(255, 255, 255, .55); transition: fill .3s ease; }
.jrn__png-flash { fill: none; stroke: var(--accent-default); stroke-width: 2; opacity: 0; transform-origin: center; transform-box: fill-box; }
.jrn__png.is-hit .jrn__png-card { fill: rgba(255, 44, 44, .5); stroke: var(--accent-default); }
.jrn__png.is-hit .jrn__png-mk path,
.jrn__png.is-hit .jrn__png-mk circle { fill: #fff; }
.jrn__png.is-hit .jrn__png-flash { animation: jrnPing .8s ease-out; }
@keyframes jrnPing {
  0% { opacity: .9; transform: scale(.9); }
  100% { opacity: 0; transform: scale(1.55); }
}
/* bez JS reklamy stoją widoczne (stan końcowy); z JS pokazują się w 2. przejściu */
.jrn__pngs { opacity: 1; transition: opacity .45s ease; }
.svc.js .jrn__pngs { opacity: 0; }
.svc.js .jrn__pngs.is-on { opacity: 1; }

/* PODPISY: 16 px w kadrze 560 px, który renderuje się na ~717 px → 20,5 px na ekranie,
   czyli tyle, co akapit obok (18,7 px). Mierzone, nie oceniane na oko.

   Każdy podpis zapala się DOPIERO przy sklepie, do którego klient naprawdę wszedł —
   jest puentą aktu, nie stałą etykietą w kadrze. Dwie korzyści:
   (1) mniej stojącego tekstu (S2: najpierw wytnij);
   (2) znika kolizja zmierzona w akcie 1 — chmurka myśli klienta idącego dolną drogą
       wchodziła na napis „kupuje u Ciebie" (dokładnie ten błąd złapał test kolizji
       w sesji 17; wracał, bo napis stał w kadrze przez cały czas).
   BEZ JS oba podpisy stoją widoczne (stan końcowy). */
.jrn__lab { font-size: 16px; font-weight: 600; fill: var(--serp-mut); opacity: 1; transition: opacity .5s ease; }
.jrn__lab--win { fill: var(--text-primary); }
.svc.js .jrn__lab { opacity: 0; }
.svc.js .jrw.is-win .jrn__lab--win { opacity: 1; }
.svc.js .jrw.is-lose .jrn__lab--lose { opacity: 1; }

/* człowiek i jego MYŚL O TOBIE (chmurka ze znakiem marki) */
.jrn__man { fill: #f2f3f5; }
.jrn__bub-blob { fill: rgba(10, 10, 12, .82); stroke: rgba(255, 255, 255, .5); stroke-width: 1.8; }
.jrn__bub-tail { fill: rgba(255, 255, 255, .4); }

/* ZNAK TWOJEJ MARKI = czerwony krążek z BIAŁĄ lampą (ten sam wzorzec, co awatar
   „twoja.marka" w hero /performance-marketing/). Czerwona lampa na czarnym wnętrzu
   chmurki miała za mały kontrast i była za mała — a to ONA jest bohaterem sceny. */
.jrn__mk { transition: opacity .28s ease; }
.jrn__mk-disc { fill: var(--accent-default); }
.jrn__mk-lamp path,
.jrn__mk-lamp circle { fill: #fff; }
/* poświata, gdy myśl o Tobie jest zapalona — dokładnie to, co gaśnie i wraca */
.jrn__walk .jrn__mk { filter: drop-shadow(0 0 7px rgba(255, 44, 44, .75)); }

/* znak KOGOŚ INNEGO — wchodzi w pustą myśl dopiero, gdy Twój zgaśnie.
   Ten sam krążek, inna marka: pusta myśl wypełniona cudzym znakiem to obraz
   zapomnienia mocniejszy niż brak chmurki. */
.jrn__mk-taken { opacity: 0; transition: opacity .5s ease; }
.jrn__mk-taken circle { fill: rgba(255, 255, 255, .26); }
.jrn__mk-taken-in { fill: rgba(20, 20, 22, .9); }

/* sklepy: Twój (czerwony, ze znakiem) kontra cudzy (szary, bez twarzy) */
.jrn__shop { stroke-width: 1.5; }
.jrn__shop--you { fill: rgba(255, 44, 44, .3); stroke: var(--accent-default); transition: fill .5s ease, stroke .5s ease; }
.jrn__shop--other { fill: rgba(255, 255, 255, .035); stroke: rgba(255, 255, 255, .13); transition: fill .5s ease, stroke .5s ease; }
.jrn__sign--you { fill: rgba(255, 44, 44, .5); transition: fill .5s ease; }
.jrn__sign--other { fill: rgba(255, 255, 255, .07); }
.jrn__door { fill: rgba(0, 0, 0, .5); stroke: rgba(255, 255, 255, .1); stroke-width: 1; }
.jrn__mk-shop path,
.jrn__mk-shop circle { fill: #fff; transition: fill .5s ease; }
.jrn__mk-other { fill: rgba(255, 255, 255, .2); }
.jrn__glow { opacity: 1; transition: opacity .6s ease; }
/* z JS: sklep zapala się dopiero w chwili zakupu */
.svc.js .jrn__shop--you { fill: rgba(255, 44, 44, .1); stroke: rgba(255, 44, 44, .4); }
.svc.js .jrn__sign--you { fill: rgba(255, 44, 44, .2); }
.svc.js .jrn__mk-shop path,
.svc.js .jrn__mk-shop circle { fill: rgba(255, 255, 255, .5); }
.svc.js .jrn__glow { opacity: 0; }
.svc.js .jrw.is-win .jrn__shop--you { fill: rgba(255, 44, 44, .3); stroke: var(--accent-default); }
.svc.js .jrw.is-win .jrn__sign--you { fill: rgba(255, 44, 44, .5); }
.svc.js .jrw.is-win .jrn__mk-shop path,
.svc.js .jrw.is-win .jrn__mk-shop circle { fill: #fff; }
.svc.js .jrw.is-win .jrn__glow { opacity: 1; }
.svc.js .jrw.is-lose .jrn__shop--other { fill: rgba(255, 255, 255, .09); stroke: rgba(255, 255, 255, .3); }

/* ---------- mini-grafiki kart zakresu ----------
   ⭐ SESJA 18, decyzja Karola: karty 1 i 6 COFNIĘTE do wersji sprzed sesji 17.
   Moja przebudowa była tam regresem („zaliczyły regres… były takie bary z czerwonymi
   sekcjami"): droga z wyrwami czytała się jak szara kreska, a kropki-ludzie jak
   przypadkowe kropki. Karty 2–5 zostają nowe, bo ich STARE wersje były tabelkami
   z tekstem i cyframi („1 · dzień 1"), które Karol odrzucił wcześniej.

   WYSOKOŚĆ: wszystkie sześć mają 172 px (Karol: „za duże wielkościowo" — było 202).
   Karty rysunkowe trafiają w tę liczbę przez ograniczenie szerokości rysunku
   (306 px → 125 px wysokości + 12 gap + 18 podpis + 16 wyścielenie = 171 ≤ 172),
   a `min-height` dociąga je do równa. Wysokości są więc równe Z KONSTRUKCJI. */
.lkv { min-height: 172px; gap: 12px; align-items: center; text-align: center; }
.lkv__svg { width: 100%; max-width: 306px; height: auto; display: block; margin-inline: auto; }
.lkv__cap { font-size: 13px; line-height: 1.35; color: var(--text-body); }

/* wspólny język kart rysunkowych: ludzie, materiały, wiadomości */
.lkv__fig circle,
.lkv__fig path,
.lkv__fig rect { fill: rgba(255, 255, 255, .42); }
.lkv__step { stroke: rgba(255, 255, 255, .12); stroke-width: 1.4; }
.lkv__tick { stroke: rgba(255, 255, 255, .22); stroke-width: 1.4; }

/* 1 · MAPA DROGI (wersja sprzed sesji 17): kafle kroków, między nimi czerwone przerwy.
      Zasłoń tekst — zostaje łańcuch z dwoma wyrwanymi ogniwami. To działa. */
.lkv--map .lkv__path { display: flex; align-items: center; gap: 9px; width: 100%; }
.lkv__node,
.lkv__gapx { height: 42px; display: grid; place-items: center; border-radius: 8px; }
.lkv__node { flex: 1; border: 1px solid rgba(255, 255, 255, .22); background: rgba(255, 255, 255, .05); }
.lkv__node em { font-style: normal; font-size: 13px; color: var(--text-primary); }
.lkv__gapx {
  position: relative;
  flex: 0 0 42px;
  border: 1px dashed rgba(255, 44, 44, .6);
  background: rgba(255, 44, 44, .07);
}
.lkv__gapx em { font-style: normal; font-size: 14px; font-weight: 700; color: var(--color-red-400); }
.lkv__gapx::before,
.lkv__gapx::after {
  content: "";
  position: absolute;
  top: 50%;
  width: 9px;
  border-top: 1px solid rgba(255, 255, 255, .28);
}
.lkv__gapx::before { right: 100%; }
.lkv__gapx::after { left: 100%; }

/* 6 · POMIAR (wersja sprzed sesji 17): spadek pokazany kształtem, czerwony słupek
      to krok, na którym ludzie znikają. Zero liczb. */
.lkv--msr .lkv__bars { display: flex; align-items: flex-end; gap: 12px; height: 92px; width: 100%; }
.lkv--msr .lkv__bars i {
  flex: 1;
  height: var(--h);
  border-radius: 6px 6px 0 0;
  background: rgba(255, 255, 255, .18);
}
.lkv--msr .lkv__bars i.is-drop { background: rgba(255, 44, 44, .55); }

/* 2 · trzy materiały na trzech etapach */
.lkv__mat { fill: rgba(255, 255, 255, .06); stroke: rgba(255, 255, 255, .3); stroke-width: 1.3; }
.lkv__mat--hot { fill: rgba(255, 44, 44, .12); stroke: rgba(255, 44, 44, .5); }
.lkv__matln { stroke: rgba(255, 255, 255, .4); stroke-width: 1.6; stroke-linecap: round; }
.lkv__matln--hot { stroke: rgba(255, 180, 180, .7); }
.lkv__matsun { fill: rgba(255, 255, 255, .45); }
.lkv__matpic { fill: rgba(255, 255, 255, .3); }

/* 3 · strona z jedną decyzją */
.lkv__pg { fill: rgba(255, 255, 255, .04); stroke: rgba(255, 255, 255, .18); stroke-width: 1.3; }
.lkv__pgln { stroke: rgba(255, 255, 255, .3); stroke-width: 3.5; stroke-linecap: round; }
.lkv__fld { fill: rgba(255, 255, 255, .05); stroke: rgba(255, 255, 255, .22); stroke-width: 1.2; }
.lkv__btn { fill: var(--accent-default); }
.lkv__cur { fill: #fff; stroke: rgba(0, 0, 0, .5); stroke-width: 1; }

/* 4 · przypomnienia: prawdziwe wiadomości docierają do człowieka */
.lkv__fly { stroke: rgba(255, 255, 255, .2); stroke-width: 1.4; stroke-dasharray: 3 4; }
.lkv__env rect { fill: rgba(255, 255, 255, .07); stroke: rgba(255, 255, 255, .35); stroke-width: 1.3; }
.lkv__env-flap { fill: none; stroke: rgba(255, 255, 255, .35); stroke-width: 1.3; stroke-linejoin: round; }
.lkv__env--hot rect { fill: rgba(255, 44, 44, .18); stroke: rgba(255, 44, 44, .6); }
.lkv__env--hot .lkv__env-flap { stroke: rgba(255, 44, 44, .6); }

/* 5 · reklamy powracające (zostaje; łuk JASNY, nigdy czerwony na czerwonym) */
.lkv__rmk { width: 100%; max-width: 306px; height: auto; display: block; margin-inline: auto; }
.lkv__rmk-card { fill: rgba(255, 255, 255, .05); stroke: rgba(255, 255, 255, .16); stroke-width: 1; }
.lkv__rmk-ln { fill: rgba(255, 255, 255, .22); }
.lkv__rmk-ln--cta { fill: rgba(255, 255, 255, .4); }
.lkv__rmk-ad { fill: rgba(255, 44, 44, .2); stroke: rgba(255, 44, 44, .55); stroke-width: 1.2; }
.lkv__rmk-mk { opacity: .9; }
.lkv__rmk-arc {
  stroke: rgba(255, 255, 255, .55);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-dasharray: 3.5 5;
  fill: none;
}
.lkv__rmk-tip { fill: rgba(255, 255, 255, .85); stroke: none; }

/* rzędy kart równej wysokości (zakresowo: tylko te dwie podstrony) */
.svc--lej .gain,
.svc--strat .gain { grid-auto-rows: 1fr; }

@media (max-width: 1024px) {
  .two { grid-template-columns: 1fr; }
}
@media (max-width: 820px) {
  /* telefon: lejek czytelny, ale bez ruchu — stan końcowy od razu */
  .fnl__stage { height: 306px; }
  .fnl__row { width: 88px; }
  .fnl__row em { font-size: 13px; }
  /* 🔴 17.08.2026 (Karol): »hero tu ich tracisz przeswituje zarys lejka,
     musisz zwiekszyc krycie, zeby nie przeswitywalo«.

     PRZYCZYNA, ZMIERZONA: tlo pigulki ma 14% krycia (rgba(255,44,44,.14)).
     Na szerokim ekranie pigulka stoi OBOK rysunku i nie ma czego przeswitywac,
     ale ta regula przesuwa ja na prawa krawedz i NAKLADA na zarys lejka —
     wtedy kreski rysunku widac przez tlo. Komentarz przy pigulce mowil
     »nic jej nie zaslania«; ponizej 820 px to przestalo byc prawda.

     KRYCIE W GORE, WYGLAD BEZ ZMIAN. Odczytane z pikseli zrzutu przy 390 px:
       tlo strony pod pigulka   #8f1919
       pigulka na tym tle dzis  #9f1c1c  (= tlo + 14% czerwieni)
     Dlatego kolor tla wchodzi tu jako warstwa nieprzezroczysta #8f1919, a czerwien
     zostaje ta sama i w tym samym kryciu — piksel w piksel ten sam kolor co dzis,
     tylko rysunek pod spodem juz nie przechodzi. Obwodka bez zmian. */
  .fnl__chip {
    left: auto; right: 0; width: 132px; top: 236px;
    background: linear-gradient(rgba(255, 44, 44, .14), rgba(255, 44, 44, .14)) #8f1919;
  }
}

/* ==========================================================================
   STRONY INTERNETOWE (Seria 14.5)
   Hero: strona SKŁADA SIĘ na oczach klienta (.wbw / .wb) — elementy, które
   sprzedają, wlatują na swoje miejsce na JEDNEJ jasnej kartce (makieta czyta się
   jako jedna strona, nie jako kafle), stoper w rogu zatrzymuje się na 1,2 s,
   a na koniec zapalają się trzy dowody. Mechanika świadomie odwrotna do rentgenu
   z /audyt-seo/: tam strona jest rozbierana, tu składana i działająca.
   Animujemy wyłącznie opacity/transform, wysokości są zarezerwowane.
   ========================================================================== */
.wbw__body { padding: 18px; }

/* jasna kartka = prawdziwa strona klienta (kontrast do ciemnego serwisu) */
.wb {
  position: relative;
  height: 292px;
  padding: 14px;
  border-radius: 12px;
  background: #f2f2f4;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.wb__el {
  opacity: 0;
  transform: translate(var(--bx, 0), var(--by, 0)) scale(.97);
  /* miękkie dociśnięcie na końcu ruchu, zero drgania */
  transition: opacity .5s ease, transform .62s cubic-bezier(.2, 1.15, .32, 1);
}
.wbw.is-on .wb__el { opacity: 1; transform: none; }
.wbw.is-on .wb__el--head { transition-delay: .26s; }
.wbw.is-on .wb__el--photo { transition-delay: .42s; }
.wbw.is-on .wb__el--cta { transition-delay: .58s; }
.wbw.is-on .wb__el--proof { transition-delay: .80s; }
.wbw.is-on .wb__el--cards { transition-delay: 1.00s; }
.wbw.is-on .wb__el--foot { transition-delay: 1.20s; }

/* pasek nawigacji: prawdziwe logo, prawdziwe pozycje menu (nie paski-zaślepki) */
.wb__el--nav { display: flex; align-items: center; gap: 14px; }
.wb__brand {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 13px;
  font-weight: 700;
  color: #16161a;
}
.wb__brand i {
  width: 18px;
  height: 18px;
  border-radius: 5px;
  background: var(--accent-default);
}
.wb__menu { display: flex; gap: 12px; }
.wb__menu i {
  font-style: normal;
  font-size: 12px;
  font-weight: 500;
  color: #5c5c66;
}
.wb__navbtn {
  margin-left: auto;
  padding: 5px 11px;
  border-radius: 6px;
  border: 1px solid #16161a;
  font-size: 13px;
  font-weight: 600;
  color: #16161a;
  white-space: nowrap;   /* na wąskiej makiecie „Kup teraz" łamał się na dwie linijki */
}

/* koszyk w menu — bez niego pasek nie czyta się jak menu SKLEPU */
.wb__cart { position: relative; display: inline-flex; align-items: center; color: #16161a; }
.wb__cart em {
  position: absolute;
  top: -5px;
  right: -7px;
  min-width: 13px;
  height: 13px;
  padding: 0 3px;
  border-radius: 999px;
  background: var(--accent-default);
  color: #fff;
  font-style: normal;
  font-size: 9px;
  font-weight: 800;
  line-height: 13px;
  text-align: center;
}

/* HERO strony: nagłówek + cena + oceny po lewej, zdjęcie produktu po prawej */
.wb__hero { display: grid; grid-template-columns: 1fr 160px; gap: 16px; align-items: stretch; }
/* min-width:0 — bez tego kolumna elastyczna nie może zejść poniżej najdłuższego SŁOWA
   nagłówka i rozpycha całą makietę. Zmierzone na telefonie (390 px): okno przeglądarki
   robiło się 455 px szerokie w komórce o szerokości 335 px i wychodziło poza ekran. */
.wb__col { display: flex; flex-direction: column; gap: 9px; min-width: 0; }
.wb__el--head { display: flex; flex-direction: column; gap: 4px; }
.wb__eyebrow {
  margin: 0;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--accent-default);
}
.wb__h1 {
  margin: 0;
  font-size: 20px;
  font-weight: 700;
  line-height: 1.18;
  color: #16161a;
  letter-spacing: -0.015em;
}
.wb__h1 b { font-weight: 800; color: var(--accent-default); }
.wb__h2 { margin: 0; font-size: 12px; line-height: 1.4; color: #5c5c66; }

.wb__el--cta { display: flex; align-items: center; gap: 12px; }
.wb__price { font-size: 19px; font-weight: 800; color: #16161a; letter-spacing: -.01em; }
.wb__btn {
  padding: 8px 14px;
  border-radius: 8px;
  background: var(--accent-default);
  color: #fff;
  font-size: 13px;
  font-weight: 700;
}

/* opinie: prawdziwa gwiazdkowa ocena, nie szare prostokąty */
.wb__el--proof { display: flex; align-items: center; gap: 8px; }
.wb__stars { font-size: 12px; letter-spacing: 1px; color: #f5a623; }
.wb__rate { font-size: 12px; color: #5c5c66; }
.wb__rate b { color: #16161a; font-weight: 700; }

/* zdjęcie produktu — PRAWDZIWE zdjęcie wypełniające swój kadr, nie szara zaślepka
   i nie przypadkowy wycinek. Rozciąga się na całą wysokość kolumny hero. */
.wb__el--photo {
  border-radius: 10px;
  overflow: hidden;
  background: #e2e2e7;
  min-height: 118px;
}
.wb__el--photo img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* KAFLE — sekcja pod hero. To ona sprawia, że makieta czyta się jak STRONA
   (nagłówek → sekcja → stopka), a nie jak jeden pasek treści.
   margin-right REZERWUJE miejsce na telefon stojący przed prawym dolnym rogiem okna.
   Bez rezerwy telefon zasłaniał trzeci kafel i połowę stopki, i czytało się to jak
   usterka. Przy 1440 px nie ma dokąd go odsunąć — okno kończy się 25 px od krawędzi
   ekranu (zmierzone), więc to STRONA musi mu zrobić miejsce, a nie odwrotnie. */
.wb__el--cards { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; margin-right: 84px; }
.wb__card {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 7px 9px;
  border: 1px solid #e2e2e7;
  border-radius: 8px;
  background: #fff;
  font-size: 11px;
  font-weight: 600;
  color: #3c3c46;
}
.wb__card i {
  flex: none;
  display: grid;
  place-items: center;
  width: 20px;
  height: 20px;
  border-radius: 6px;
  background: rgba(255, 44, 44, .1);
  color: var(--accent-default);
  font-style: normal;
  font-size: 9px;
  font-weight: 800;
}

/* STOPKA — cichy pasek, ale bez niego strona nie ma dołu */
.wb__el--foot {
  display: flex;
  gap: 14px;
  padding-top: 8px;
  margin-right: 84px;      /* ta sama rezerwa na telefon, co w kaflach */
  border-top: 1px solid #e2e2e7;
  font-size: 10px;
  color: #8a8a92;
}

/* STOPER: liczy do 1,2 s i staje. Stoi PRZY OKNIE, nie na kartce — to NASZ pomiar,
   a nie element cudzej witryny. W środku strony wyglądał jak śmieć na czyjejś stronie. */
.wb__clock {
  position: absolute;
  /* -30, nie -14: przy -14 plakietka wchodziła na stopkę strony i zjadała znak „©" */
  left: -30px;
  bottom: 22px;
  padding: 7px 11px;
  border-radius: 9px;
  background: #16161a;
  border: 1px solid rgba(255, 255, 255, .16);
  box-shadow: 0 10px 26px -10px rgba(0, 0, 0, .9);
  color: #fff;
  font-size: 14px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  opacity: 0;
  transition: opacity .45s ease;
}
.wbw.is-on .wb__clock { opacity: 1; }

/* TELEFON: ta sama strona, ten sam układ. Stoi OBOK okna i wychodzi poza jego krawędź —
   tak pokazuje się makiety naprawdę. Wcześniej leżał NA ZDJĘCIU w środku strony
   i czytał się jak usterka (uwaga Karola: „nie przypomina prawdziwej strony"). */
.wb__phone {
  position: absolute;
  /* Wysunięty tylko o 14 px — dalej nie można, bo przy 1440 px okno kończy się 25 px
     od krawędzi ekranu (zmierzone: przy -38 telefon wychodził 13 px POZA EKRAN).
     Miejsce na niego robi sama strona (margin-right w kaflach i stopce). */
  right: -14px;
  bottom: -24px;
  width: 92px;
  height: 158px;
  padding: 8px 7px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  border-radius: 14px;
  border: 3px solid #16161a;
  background: #fff;
  box-shadow: 0 22px 50px -18px rgba(0, 0, 0, .95);
  opacity: 0;
  transform: translateX(26px) scale(.94);
  transition: opacity .55s ease, transform .7s cubic-bezier(.2, 1.15, .32, 1);
}
.wbw.is-phone .wb__phone { opacity: 1; transform: none; }
/* pasek stanu telefonu — bez niego to nie telefon, tylko biały prostokąt */
.wb__ph-bar { display: flex; align-items: center; justify-content: space-between; }
.wb__ph-bar i { display: block; height: 3px; border-radius: 2px; background: #d3d3da; }
.wb__ph-bar i:first-child { width: 22px; }
.wb__ph-bar i:last-child { width: 12px; }
.wb__ph-img {
  height: 62px;
  border-radius: 7px;
  background: url("/assets/img/image-case3.webp") center/cover no-repeat, #e2e2e7;
}
.wb__ph-h { font-size: 10px; font-weight: 700; line-height: 1.2; color: #16161a; }
.wb__ph-t { font-size: 9px; line-height: 1.3; color: #6c6c76; }
.wb__ph-btn {
  margin-top: auto;
  padding: 5px 0;
  border-radius: 6px;
  background: var(--accent-default);
  color: #fff;
  font-size: 9px;
  font-weight: 700;
  text-align: center;
}

/* ---------- sekcja „dlaczego": ta sama reklama, dwie strony ---------- */
.rc { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; align-items: stretch; }
.rc__col {
  display: flex;
  flex-direction: column;
  gap: 9px;
  padding: 14px;
  border: 1px solid var(--border-subtle);
  border-radius: 12px;
  background: rgba(255, 255, 255, .02);
  opacity: 0;
  transform: translateY(8px);
  transition: opacity .6s ease, transform .6s ease;
}
.rcw.is-go .rc__col { opacity: 1; transform: none; }
.rcw.is-go .rc__col--fast { transition-delay: .22s; }
.rc__col--fast { border-color: rgba(255, 44, 44, .35); }
.rc__h { font-size: 13px; font-weight: 700; letter-spacing: .08em; color: var(--serp-mut); }
.rc__col--fast .rc__h { color: var(--text-primary); }
.rc__pg {
  height: 112px;
  border-radius: 9px;
  background: #f2f2f4;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 8px;
  padding: 12px;
}
.rc__pg--fast { align-items: flex-start; justify-content: center; }
.rc__ln { height: 10px; width: var(--w); border-radius: 5px; background: #16161a; }
.rc__ln + .rc__ln { background: #b6b6bd; height: 8px; }
.rc__cta {
  margin-top: 4px;
  padding: 6px 11px;
  border-radius: 7px;
  background: var(--accent-default);
  color: #fff;
  font-size: 13px;
  font-weight: 700;
}
/* strona, która się ociąga: pusta kartka i kręcące się kółko (tylko transform) */
.rc__spin {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  border: 3px solid #d8d8de;
  border-top-color: #9a9aa4;
}
.rcw.is-go .rc__spin { animation: rcspin 1s linear infinite; }
@keyframes rcspin { to { transform: rotate(360deg); } }
.rc__t { font-size: 14px; font-weight: 700; color: var(--text-primary); }
.rc__d { font-size: 13px; line-height: 1.35; color: var(--text-body); }

/* ---------- mini-grafiki kart zakresu ---------- */
.wwv { min-height: 150px; gap: 10px; }
.wwv__cap { font-size: 13px; line-height: 1.35; color: var(--text-body); }

/* 1 · cel strony (wysokość zestrojona z pozostałymi kartami: 150 px) */
.wwv--goal .wwv__goals { display: flex; flex-direction: column; gap: 6px; width: 100%; }
.wwv--goal .wwv__goals em {
  font-style: normal;
  font-size: 13px;
  padding: 6px 11px;
  border: 1px solid var(--border-subtle);
  border-radius: 8px;
  color: var(--text-body);
}
.wwv--goal .wwv__goals em.is-on {
  border-color: rgba(255, 44, 44, .5);
  background: rgba(255, 44, 44, .08);
  color: var(--text-primary);
  font-weight: 600;
}

/* 2 · szkic układu */
.wwv--wire .wwv__wire {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 12px;
  border: 1px dashed rgba(255, 255, 255, .28);
  border-radius: 10px;
}
.wwv--wire .wwv__wire i { height: 9px; width: var(--w); border-radius: 4px; background: rgba(255, 255, 255, .2); }
.wwv__wbtn { width: 78px; height: 22px; border-radius: 6px; border: 1px dashed rgba(255, 44, 44, .6); }

/* 3 · język klienta kontra język strony (wysokość zestrojona: 150 px) */
.wwv--copy { gap: 6px; }
.wwv--copy .wwv__row {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 7px 11px;
  border: 1px solid var(--border-subtle);
  border-radius: 9px;
  background: rgba(255, 255, 255, .03);
}
.wwv--copy .wwv__row em { font-style: normal; font-size: 13px; color: var(--serp-mut); }
.wwv--copy .wwv__row b { font-size: 13px; font-weight: 700; color: var(--text-primary); }
.wwv--copy .wwv__row--bad { border-color: rgba(255, 44, 44, .4); background: rgba(255, 44, 44, .07); }
.wwv__neq { align-self: center; font-size: 14px; line-height: 1; color: var(--serp-mut); }

/* 4 · panel do edycji */
.wwv--cms .wwv__panel {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px;
  border: 1px solid var(--border-subtle);
  border-radius: 10px;
  background: rgba(255, 255, 255, .04);
}
.wwv__ptop { display: flex; align-items: center; gap: 8px; }
.wwv__ptop i { width: 16px; height: 16px; border-radius: 5px; background: var(--accent-default); }
.wwv__ptop em { font-style: normal; font-size: 13px; color: var(--text-body); }
.wwv__prow { display: flex; align-items: center; gap: 9px; }
.wwv__prow i { height: 9px; width: var(--w); border-radius: 4px; background: rgba(255, 255, 255, .22); }
.wwv__save {
  margin-left: auto;
  padding: 4px 10px;
  border-radius: 6px;
  background: var(--accent-default);
  color: #fff;
  font-size: 13px;
  font-weight: 600;
}

/* 5 · szybkość: gdzie jesteś wobec progu cierpliwości klienta */
.wwv--speed { align-items: stretch; }
.wwv__track {
  position: relative;
  height: 10px;
  border-radius: 5px;
  background: rgba(255, 255, 255, .12);
}
.wwv__fill {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: var(--w);
  border-radius: 5px;
  background: var(--accent-default);
}
.wwv__limit {
  position: absolute;
  left: var(--lx);
  top: -5px;
  bottom: -5px;
  width: 2px;
  background: rgba(255, 255, 255, .55);
}
.wwv__labs { position: relative; height: 40px; }
.wwv__lab { position: absolute; display: flex; flex-direction: column; gap: 1px; }
.wwv__lab strong { font-size: 14px; color: var(--text-primary); font-variant-numeric: tabular-nums; }
.wwv__lab em { font-style: normal; font-size: 13px; color: var(--text-body); }
.wwv__lab--you { left: 0; }
.wwv__lab--limit { left: var(--lx); }

/* 6 · pomiar zapytań: sześć słupków = sześć miesięcy, ostatni podpisany liczbą */
.wwv--care .wwv__mon { display: flex; align-items: flex-end; gap: 9px; height: 74px; width: 100%; }
.wwv--care .wwv__mon i {
  position: relative;
  flex: 1;
  height: var(--h);
  border-radius: 5px 5px 0 0;
  background: rgba(255, 255, 255, .18);
}
.wwv--care .wwv__mon i.is-now { background: var(--accent-default); }
.wwv--care .wwv__mon i em {
  position: absolute;
  left: 50%;
  bottom: 100%;
  transform: translateX(-50%);
  margin-bottom: 5px;
  font-style: normal;
  font-size: 13px;
  font-weight: 700;
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
}

@media (max-width: 1024px) {
  .rc { grid-template-columns: 1fr; }
}
@media (max-width: 820px) {
  .wb { height: 300px; }
  .wb__proofs { grid-template-columns: 1fr; }
  .wb__pf { flex-direction: row; align-items: baseline; gap: 8px; }
  /* ⚠️ Na telefonie makieta telefonu WYCHODZIŁA 110 px POZA EKRAN (zmierzone przy 390 px:
     prawa krawędź 500). Poza oknem może stać tylko na dużym ekranie — na małym wraca
     do środka kartki i kurczy się. Stoper też wraca do środka, bo poza lewą krawędzią
     nie ma już miejsca. */
  .wb__phone { right: 8px; bottom: 8px; width: 66px; height: 124px; padding: 6px 5px; gap: 4px; border-width: 2px; }
  .wb__ph-img { height: 40px; }
  .wb__ph-h { font-size: 8px; }
  .wb__ph-t { font-size: 8px; }
  .wb__ph-btn { font-size: 8px; padding: 4px 0; }
  .wb__clock { left: 10px; bottom: 10px; padding: 5px 8px; font-size: 12px; }
  /* stopka wylatuje: na wąskiej kartce plakietka stopera i tak na nią wchodziła
     (zmierzone), a bez stopki makieta nadal czyta się jak strona */
  .wb__el--foot { display: none; }
  .wb__el--cards { margin-right: 76px; }
  /* na wąskiej kartce wszystko schodzi o klasę, żeby makieta nadal czytała się
     jak strona, a nie jak ścisk. Trzeci kafel wylatuje — dwa wystarczą. */
  .wb__el--cards { grid-template-columns: 1fr 1fr; }
  .wb__card:last-child { display: none; }
  .wb__hero { grid-template-columns: 1fr 92px; gap: 10px; }
  .wb__h1 { font-size: 15px; }
  .wb__h2 { font-size: 10px; }
  .wb__eyebrow { font-size: 8px; }
  .wb__price { font-size: 15px; }
  .wb__btn { font-size: 11px; padding: 6px 10px; }
  /* to PASEK MENU rozpychał całą makietę: zmierzone min-content 331 px przy 271 px
     miejsca (nie zawija się, bo to flex w jednym wierszu). Dwie pozycje mniej i mieści
     się — dokładnie tak zachowuje się prawdziwa strona na węższym ekranie. */
  .wb__menu { gap: 8px; }
  .wb__menu i { font-size: 10px; }
  .wb__menu i:nth-child(n+3) { display: none; }
  .wb__brand { font-size: 12px; }
  .wb__navbtn { font-size: 10px; padding: 4px 8px; }
  .wb__el--photo { min-height: 96px; }
}

/* ==========================================================================
   STRATEGIA MARKETINGOWA (Seria 14.6) — mini-grafiki kart „co ustala strategia"
   Wysokości zestrojone z pozostałymi podstronami (150 px).
   ========================================================================== */
/* ---------- mini-grafiki kart „Co ustala strategia" (przebudowa, sesja 17) ----------
   Karol: „grafiki nie tłumaczą treści; »Gdzie jest miejsce do zajęcia« jest kompletnie
   dla mnie niezrozumiała, a co dopiero dla osoby bez backgroundu marketingowego".
   Cztery z sześciu były akapitami w ramce. Wszystkie sześć są teraz OBRAZKAMI
   w jednym kadrze 240×98 — równe wysokości kart wynikają z konstrukcji. */
.stv { min-height: 172px; gap: 12px; align-items: center; text-align: center; }
.stv__svg { width: 100%; height: auto; display: block; }
.stv__cap { font-size: 13px; line-height: 1.35; color: var(--text-body); }

/* 1 · kto jest Twoim klientem: tłum, a w nim JEDEN wyróżniony */
.stv__crowd circle,
.stv__crowd path { fill: rgba(255, 255, 255, .16); }
.stv__one circle,
.stv__one path { fill: #f2f3f5; }
.stv__ring { fill: rgba(255, 44, 44, .07); stroke: rgba(255, 44, 44, .55); stroke-width: 1.5; stroke-dasharray: 4 3; }

/* 2 · gdzie jest miejsce do zajęcia: WOLNE POLE jest naprawdę puste.
      Stara wersja (słupki 82/64/26%) przeczyła własnemu podpisowi — mówiła
      „konkurenci są więksi", a wolnego miejsca nie było widać wcale. */
.stv__shelf { stroke: rgba(255, 255, 255, .18); stroke-width: 1.6; stroke-linecap: round; }
.stv__slot--taken { fill: rgba(255, 255, 255, .07); stroke: rgba(255, 255, 255, .26); stroke-width: 1.3; }
.stv__slot-ln { stroke: rgba(255, 255, 255, .3); stroke-width: 2.4; stroke-linecap: round; }
.stv__slot--free { fill: none; stroke: rgba(255, 44, 44, .75); stroke-width: 1.6; stroke-dasharray: 5 4; }
.stv__take { stroke: rgba(255, 44, 44, .85); stroke-width: 1.8; }
.stv__take-tip { fill: rgba(255, 44, 44, .85); }

/* 3 · czym się wyróżniasz: cztery takie same, jeden inny */
.stv__same { fill: rgba(255, 255, 255, .07); stroke: rgba(255, 255, 255, .22); stroke-width: 1.2; }
.stv__diff { fill: rgba(255, 44, 44, .2); stroke: var(--accent-default); stroke-width: 1.6; }
.stv__diff-mk path,
.stv__diff-mk circle { fill: #fff; }

/* 4 · podział budżetu: szerokość pola = udział */
.stv__bar { stroke-width: 1.2; }
.stv__bar--a { fill: rgba(255, 255, 255, .1); stroke: rgba(255, 255, 255, .28); }
.stv__bar--b { fill: rgba(255, 44, 44, .28); stroke: rgba(255, 44, 44, .6); }
.stv__bar--c { fill: rgba(255, 255, 255, .06); stroke: rgba(255, 255, 255, .2); }
.stv__blab { font-size: 12px; font-weight: 600; fill: var(--text-primary); }
.stv__brace { fill: none; stroke: rgba(255, 255, 255, .2); stroke-width: 1.3; }

/* 5 · kartka planu z zakreślonym brakującym krokiem. NIE ta sama grafika, co droga
      na /lejki-marketingowe/: tam jest REALNA droga (rzeczywistość, którą się buduje),
      tu KARTKA, która ją diagnozuje. Inny przedmiot, inna rola. */
.stv__sheet { fill: rgba(255, 255, 255, .04); stroke: rgba(255, 255, 255, .2); stroke-width: 1.3; }
.stv__plan-ln { stroke: rgba(255, 255, 255, .22); stroke-width: 3; stroke-linecap: round; }
.stv__plan-road { stroke: rgba(255, 255, 255, .4); stroke-width: 2; stroke-linecap: round; }
.stv__plan-node { fill: rgba(255, 255, 255, .5); }
.stv__plan-gap { stroke: rgba(255, 44, 44, .8); stroke-width: 2; stroke-dasharray: 3 3; }
.stv__circle { fill: none; stroke: var(--accent-default); stroke-width: 1.8; }

/* 6 · cel ustalony z góry — i przekroczony */
.stv__goal { stroke: rgba(255, 44, 44, .8); stroke-width: 1.6; stroke-dasharray: 5 4; }
.stv__base { stroke: rgba(255, 255, 255, .16); stroke-width: 1.3; }
.stv__mo { fill: rgba(255, 255, 255, .16); }
.stv__mo--hit { fill: rgba(255, 44, 44, .5); }

/* ---------- sekcja „dlaczego": co zostaje w głowie klienta ---------- */
.svc--strat .svc-big { font-size: clamp(72px, 8.6vw, 132px); margin-left: -.024em; }  /* glif „1", zmierzone 3,0 px */
/* ---------- hero strategii: EKRAN PLANU ----------
   Poprzeczka to hero /performance-marketing/ (prawdziwy telefon z prawdziwą
   aplikacją). Tamta wygrywa głębią, realizmem i tym, że czerwień pada TYLKO na
   jedną rzecz. Tutaj tak samo: kafle są białe/szklane, a czerwone jest wyłącznie
   to, co jest WYNIKIEM — scalona wiązka, środek tarczy i krzywa sprzedaży. */
.pln__lab {
  font-size: 13px;
  font-weight: 600;
  fill: var(--text-primary);
}
/* ⭐ BŁĄD ZNALEZIONY POMIAREM: tej reguły NIE BYŁO w ogóle. Napisy „JEDEN CEL"
   i „SPRZEDAŻ" dziedziczyły więc `fill="none"` z atrybutu na <svg> i były
   NIEWIDOCZNE — Karol oglądał czerwoną krzywą bez żadnego podpisu i słusznie
   napisał, że to „losowy wykres". Zmierzone: getComputedStyle(...).fill === "none".
   Nie da się tego zobaczyć w kodzie: brakującej reguły nigdzie nie widać. */
.pln__cap {
  font-size: 15px;
  font-weight: 700;
  letter-spacing: .08em;
  fill: var(--serp-mut);
}
.pln__cap--big { font-size: 17px; fill: var(--text-primary); letter-spacing: .06em; }
/* kafel kanału: gradient + ramka = bryła, nie płaski prostokąt */
.pln__tile {
  fill: url(#plnTile);
  stroke: rgba(255, 255, 255, .18);
  stroke-width: 1;
  transition: stroke .5s ease;
}
.pln__ico { fill: none; stroke: rgba(255, 255, 255, .75); stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.pln__ico--fill { fill: rgba(255, 255, 255, .75); stroke: none; }

/* kafel „zapala się", gdy plan go włącza — ZDARZENIE.
   BEZ JS (brak klasy .js na .svc) kafle stoją zapalone: strona bez JavaScriptu
   pokazuje gotowy plan, a nie wygaszony, niedokończony ekran. */
.pln__row { opacity: 1; transition: opacity .55s ease; }
.svc.js .pln__row { opacity: .38; }
.svc.js .pln__row.is-on { opacity: 1; }
.pln__row.is-on .pln__tile { stroke: rgba(255, 255, 255, .42); }

/* WIĄZKI KANAŁÓW = wypełnione WSTĘGI, nie kreski.
   Obrysu (stroke) w SVG nie da się zwężać wzdłuż linii, a Karol zgłosił dokładnie to:
   „nie ma połączenia w kontekście grubości linii… jedna jest grubsza". Wstęga grubieje
   w drodze do scalenia i przy scaleniu cztery wstęgi stykają się bok w bok, dając
   dokładnie grubość wiązki scalonej (4 × 1,75 = 7). Kolor rozgrzewa się do czerwieni
   tym samym gradientem, co wcześniej — ten Karol pochwalił, więc zostaje. */
.pln__beam {
  fill: url(#plnWarm);
  stroke: none;
}
/* zasłonka, która odsłania wstęgę od kafla w stronę celu (odpowiednik „rysowania"
   kreski, którego przy wypełnieniu nie da się zrobić obrysem).
   BEZ JS zasłonki nie ma → wiązki stoją narysowane w całości. */
.pln__clip { transform-box: fill-box; transform-origin: 0 50%; }
.svc.js .pln__clip { transform: scaleX(0); }

/* scalona wiązka: JEDNA, czerwona — to jest sedno „kanały ciągną w tę samą stronę".
   Grubość 7 = suma czterech dobiegających wstęg. Zero skoku na styku. */
.pln__merge {
  fill: none;
  stroke: url(#plnBeam);
  stroke-width: 7;
  filter: drop-shadow(0 0 6px rgba(255, 44, 44, .55));
}
/* tarcza. Bez JS stoi TRAFIONA (stan końcowy), z JS zapala się dopiero po trafieniu. */
.pln__ring { fill: none; stroke: rgba(255, 255, 255, .22); stroke-width: 1.4; }
.pln__bull { fill: var(--accent-default); transition: fill .45s ease; }
.pln__hit { fill: url(#plnHit); opacity: 1; transition: opacity .6s ease; }
.svc.js .pln__bull { fill: rgba(255, 255, 255, .3); }
.svc.js .pln__hit { opacity: 0; }
/* trafienie: środek tarczy zapala się na czerwono i rozchodzi się poświata */
.svc.js .plan.is-hit .pln__bull { fill: var(--accent-default); }
.svc.js .plan.is-hit .pln__hit { opacity: 1; }

/* SPRZEDAŻ = PIENIĄDZE (decyzja Karola, sesja 18). Krzywa wymagała od widza znajomości
   własnej gramatyki („co jest na osi? co znaczy punkt?") i przegrywała test laika.
   Stos monet nie wymaga tłumaczenia: po trafieniu w cel PRZYBYWA PIENIĘDZY.
   Monety są nieprzezroczyste — półprzezroczyste nakładały się na siebie i stos robił
   się mazią zamiast stosem. Bez JS stoją ułożone (stan końcowy). */
.pln__base { stroke: rgba(255, 255, 255, .14); stroke-width: 1; }
.mon__coin { fill: #26262b; stroke: rgba(255, 255, 255, .5); stroke-width: 1.1; }
/* czerwień RAZ i z powodu: tylko ostatnia moneta, bo to ona niesie znak „zł" */
.mon__coin--top { fill: var(--accent-default); stroke: #ff7a7a; stroke-width: 1.2; }
.mon__zl { font-size: 15px; font-weight: 800; fill: #fff; }
.mon__glow { opacity: 1; transition: opacity 1s ease; }
.mon > g { opacity: 1; transform: none; transition: opacity .3s ease, transform .4s cubic-bezier(.2, .9, .3, 1); }
/* z JS: monety przylatują dopiero w chwili trafienia w cel — sprzedaż jest SKUTKIEM
   trafienia, a nie osobnym rysunkiem obok */
.svc.js .mon > g { opacity: 0; transform: translateY(-18px); }
.svc.js .mon__glow { opacity: 0; }
.svc.js .plan.is-sale .mon > g { opacity: 1; transform: none; }
.svc.js .plan.is-sale .mon__glow { opacity: 1; }

/* FALA UDERZENIOWA: wychodzi ze środka tarczy w chwili trafienia. To ona wiąże
   trafienie ze wzrostem sprzedaży — widz widzi JEDNO ZDARZENIE (plan → cel →
   sprzedaż rośnie), a nie dwa niezależne rysunki (uwaga Karola: „pokaż bardziej,
   że wykres obrazuje sprzedaż, jak się ma strategię"). */
.pln__pulse { fill: none; stroke: var(--accent-default); stroke-width: 2; opacity: 0; transform-box: fill-box; transform-origin: center; }
.svc.js .plan.is-hit .pln__pulse { animation: plnPulse 1.1s ease-out; }
@keyframes plnPulse {
  0% { opacity: .85; transform: scale(.5); }
  100% { opacity: 0; transform: scale(3.4); }
}

/* scena hero BEZ ramki udawanego okna — miękka ciemna poświata bez krawędzi */
.plnw { position: relative; }
.plnw::before {
  content: "";
  position: absolute;
  inset: -6% -4%;
  background: radial-gradient(ellipse closest-side at 50% 50%, rgba(0, 0, 0, .62), rgba(0, 0, 0, 0) 90%);
  pointer-events: none;
}
.plnw .pln { position: relative; }

/* ---------- strategia, sekcja „dlaczego": PIĘĆ SIŁ CIĄGNIE W RÓŻNE STRONY ----------
   Karol o poprzedniej wersji: „całkowicie do odrzutu, w ogóle jej nie rozumiem,
   nic mi ona nie mówi". I miał rację: trzy karty z NAPISAMI wysyłały komunikaty
   do głowy klienta — czyli znowu zdania w pudełkach. Zasłoń tekst i nie zostaje nic.

   Teraz w kadrze nie ma ANI JEDNEGO zdania. Pięcioro ludzi ciągnie skrzynię
   (Twoją firmę) na linach w pięć różnych stron: każdy się stara, skrzynia dygocze
   i stoi. Plan ustawia ich w jedną stronę — ta sama piątka, ta sama siła, a skrzynia
   przejeżdża linię celu. Sens niosą kierunek, siła i skutek.
   Czerwień pada TYLKO na cel (flaga + poświata) — czyli na to, co jest wynikiem. */
.pulw { position: relative; }

.pul__rope { stroke: rgba(255, 255, 255, .75); stroke-width: 1.6; stroke-linecap: round; transition: stroke .6s ease; }
.svc.js .pul__rope { stroke: rgba(255, 255, 255, .38); }
.svc.js .pulw.is-plan .pul__rope { stroke: rgba(255, 255, 255, .75); }

/* PIĘĆ TWOICH DZIAŁAŃ — krążek ze znakiem kanału zamiast anonimowej sylwetki.
   Karol: „to nie powinni ciągnąć ludzie, ale USŁUGI". Ikony te same, co na kaflach
   w hero, gdzie stoją przy nich podpisy — więc czytelnik rozpoznaje je bez czytania
   (limit „max 3 etykiety w kadrze" zostaje nienaruszony: w kadrze jest jedna). */
.pul__srv { fill: rgba(255, 255, 255, .1); stroke: rgba(255, 255, 255, .5); stroke-width: 1.6; }
.pul__ico { fill: none; stroke: #f2f3f5; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.pul__ico--fill { fill: #f2f3f5; stroke: none; }

/* skrzynia: prawdziwa skrzynia (deski), nie abstrakcyjny prostokąt */
.pul__box { fill: rgba(255, 255, 255, .08); stroke: rgba(255, 255, 255, .5); stroke-width: 2; }
.pul__slat { stroke: rgba(255, 255, 255, .2); stroke-width: 1.2; }
.pul__mk path,
.pul__mk circle { fill: rgba(255, 255, 255, .8); }

/* META: szachownica na ziemi + flaga. Cienka przerywana kreska z małą szarą flagą
   „nie zwracała uwagi" (Karol) — bo nie przedstawiała niczego konkretnego.
   Szachownicę rozpoznaje każdy, bez podpisu. Leży POD firmą i działaniami, więc
   przejeżdżają po niej, zamiast na nią wchodzić. */
.pul__meta { opacity: .5; transition: opacity .6s ease; }
.pul__pole { stroke: rgba(255, 255, 255, .55); stroke-width: 2.2; stroke-linecap: round; }
.pul__flag { fill: var(--accent-default); transition: fill .5s ease; }
.pul__glow { opacity: 1; transition: opacity .7s ease; }
.pul__lab { font-size: 17px; font-weight: 700; letter-spacing: .1em; fill: var(--serp-mut); }
/* bez JS: cel osiągnięty (stan końcowy). Z JS: meta zapala się dopiero po przejechaniu. */
.svc.js .pul__flag { fill: rgba(255, 255, 255, .32); }
.svc.js .pul__glow { opacity: 0; }
.svc.js .pul__meta { opacity: .3; }
.svc.js .pulw.is-goal .pul__flag { fill: var(--accent-default); }
.svc.js .pulw.is-goal .pul__glow { opacity: 1; }
.svc.js .pulw.is-goal .pul__meta { opacity: 1; }

/* ==========================================================================
   WSPOLNA SKALA STRONY — probka na /pozycjonowanie-stron/ (29.07.2026, v3)
   Siedem stopni z tokens.css, przypisane po ROLI W TRESCI, nie po nazwie klasy.
   Zasada: co zawiera inne naglowki, jest od nich wieksze.
   KOLEJNOSC MA ZNACZENIE — regula dla tekstu stoi PRZED regulami dla wstepu
   i naglowkow, bo maja te sama moc; ostatnia wygrywa.
   Uzasadnienie: docs/aw/RESEARCH-WYGLAD-WSPOLNY-v1.md
   ========================================================================== */

/* --- 1. TEKST DO CZYTANIA (najpierw, zeby dalsze reguly mogly go nadpisac) --- */
.svc p,
.svc li,
.svc .svc-lead,
.svc .svc-big-sub,
.svc .proc__loop,
.svc .proc__hint { font-size: var(--skala-tekst); line-height: 1.65; }

/* wyroznienie w tekscie: jasniejszy kolor zamiast ciezkiego pogrubienia */
.svc p > strong:only-child { font-weight: 500; color: var(--text-primary); }
.svc p strong { font-weight: 600; }

/* --- 2. ETYKIETY --- */
.svc .btn,
.svc .serp__q,
.svc .serp__t,
.svc .climb .serp__t,
.svc .climb__badge,
.svc .ladder__pct,
.svc .ladder__p2,
.svc .res-card__site,
.svc .res-card__what,
.svc .res-card__ba,
.svc .res-card__link,
.svc .fit__chip,
.svc .path__t,
.svc .path__d { font-size: var(--skala-etykieta); }

/* --- 3. PODPISY — najnizszy dopuszczalny stopien --- */
.svc .serp__site,
.svc .climb .serp__site,
.svc .serp__site .serp__u,
.svc .climb .serp__site .serp__u,
.svc .serp__tabs,
.svc .serp__tabs span,
.svc .serp__d,
.svc .climb .serp__d,
.svc .svc-win__label,
.svc .ladder__pos,
.svc .ladder__break,
.svc .gain__fq,
.svc .gain__roi-legend,
.svc .gain__roi-legend em,
.svc .res-card__tag,
.svc .svc-src,
.svc .grow__ms,
.svc .grow__ms span,
.svc .grow__ms span strong,
.svc .grow__months,
.svc .grow__months span,
.svc .audit__rodo { font-size: var(--skala-podpis); }

/* --- 4. WSTEP i TYTUL ELEMENTU — ten sam stopien, nigdy nie stoja obok siebie.
       Wstep: zdanie pod tytulem sekcji. Element: pojedynczy krok, pytanie, liczba. --- */
.svc .svc-lead--hero,
.svc .svc-center .svc-lead,
.svc .proc__title,
.svc .faq__q,
.svc .res-card__num,
.svc .res-card__num--sm { font-size: var(--skala-wstep); line-height: 1.45; }
.svc .proc__title,
.svc .faq__q,
.svc .res-card__num,
.svc .res-card__num--sm { font-weight: 700; line-height: 1.3; }
.svc .res-card__num small { font-size: 1em; }
.svc .proc__stage { font-weight: 700; }

/* --- 5. TYTUL GRUPY — zawiera tytuly elementow, wiec jest od nich wiekszy,
       ale wyraznie mniejszy od tytulu sekcji, zeby z nim nie konkurowal --- */
.svc .proc__stage,
.svc .gain__card h3 { font-size: var(--skala-grupa); font-weight: 700; line-height: 1.22; }

/* --- 6. TYTUL SEKCJI --- */
.svc .svc-h2 { font-size: var(--skala-h2); font-weight: 700; line-height: 1.12; }

/* --- 7. TYTUL PODSTRONY --- */
.svc .svc-h1 { font-size: var(--skala-h1); font-weight: 700; line-height: 1.08; }

/* liczba-kotwica sekcji: jeden rozmiar zamiast dwoch (bylo 172,8 px + 82,9 px) */
.svc .svc-big { font-size: var(--skala-h1); line-height: 1; }
.svc .svc-big .pct { font-size: 1em; }

/* Liczba pod siatką kropek na /ai-search/ („5/100" → „95/100").
   Znaleziona pomiarem w etapie 4: miała 16 px zamiast zaprojektowanych 40–64 px,
   a końcówka „/100" — 7,2 px, czyli mniej niż połowa najmniejszego tekstu w serwisie.
   Powód: liczba siedzi w znaczniku <p>, a reguła `.svc p` (dwa człony selektora)
   jest MOCNIEJSZA od `.prob__count` (jeden człon) i nadpisywała jej wielkość.
   Cała sekcja opiera się na tej liczbie, więc musi być czytelna z odległości ręki. */
.svc .prob__count { font-size: var(--skala-h1); line-height: 1; }
.svc .prob__count em { font-size: .45em; }

/* --- tablet --- */
@media (max-width: 860px) {
  .svc { --skala-h1: 44px; --skala-h2: 34px; --skala-grupa: 24px;
                  --skala-wstep: 19px; --skala-tekst: 17px; }
}
/* --- telefon --- */
@media (max-width: 480px) {
  .svc { --skala-h1: 36px; --skala-h2: 29px; --skala-grupa: 22px;
                  --skala-wstep: 18px; --skala-tekst: 16px; --skala-etykieta: 14px; }
}

/* ==========================================================================
   PANELE Z DANYMI — v4 (30.07.2026). Tylko to, co ma pokrycie w pomiarze.
   Pomiar 168 kart na 9 wzorach: scripts/karty-pomiar.mjs
   dane: docs/aw/porownanie-paneli-20260730/karty-wzory-{a,b,c}.json
   opis: docs/aw/RESEARCH-PANELE-Z-DANYMI-v1.md
   ========================================================================== */

/* --- 1. TLO KARTY: plaski kolor zamiast przejscia ---------------------------
   Wzory: plaski 130/168 (77%), przejscie 33 (20%), zdjecie 5 (3%).
   My przed zmiana: plaski 3/13 (23%), przejscie 10 (77%) — dokladnie odwrotnie.
   Kazdy plaski kolor to SRODEK przejscia, ktore zastepuje: karta nie robi sie
   jasniejsza ani ciemniejsza, znika tylko sam przeplyw. Zadna wartosc nie jest
   wzieta z wlasnego uznania.
   Obramowania i poswiaty (::before, ::after) zostaja — pomiar ich nie dotyczy. */
.svc {
  --karta-tlo: #111115;        /* srodek #16161c -> #0b0b0e (raised -> sunken)  */
  --karta-tlo-final: #131318;  /* srodek #1a1a20 -> #0c0c0f (panel audytu)      */
}
.svc .svc-win,
.svc .gain__card,
.svc .res-card,
.svc .fit__col { background: var(--karta-tlo); }
.svc .audit { background: var(--karta-tlo-final); }

/* --- 2. PUSTE KRESKI UDAJACE TEKST -----------------------------------------
   Drabina pozycji miala 10 wierszy x 2 kreski = 20 pustych kresek udajacych
   tytul i opis wyniku Google. Wzory: 1 karta na 168 ma ich >=3, najwiecej 6.
   Dowod, ze to sama ozdoba: na telefonie chowamy je od dawna (regula ponizej
   860 px) i wykres czyta sie tak samo. Zostaje numer pozycji, slupek i procent. */
.svc .ladder__ghost { display: none; }
/* UWAGA: tylko duze ekrany. Ponizej 860 px istnieje juz wlasna regula
   (.ladder__row: 24px 1fr 56px). Ta ma trzy klasy, czyli WIEKSZA moc, wiec bez
   tego ograniczenia nadpisalaby ustawienie telefonu. Sprawdzone pomiarem. */
@media (min-width: 861px) {
  .svc .ladder__row { grid-template-columns: 26px 1fr 64px; }
}

/* ==========================================================================
   AUDYT AI SEARCH (.svc--aia) — trzecia strona audytu, dołożona 05.08.2026
   na życzenie Karola („musimy zrobić dedykowaną podstronę”).

   JEDEN WZORZEC: strona jest PROTOKOŁEM Z PRZESŁUCHANIA modeli AI.
   Ten sam układ „pytanie klienta → kogo AI wymieniło” wraca trzy razy:
   w makiecie wprowadzenia (.aiaw), w porównaniu wyszukiwarki z AI (.aiac)
   i w kartach zakresu audytu (.aiav). Nic nowego poza tym.

   ⚠️ STAN SPOCZYNKOWY = STAN KOŃCOWY. Animacja tylko cofa element i odgrywa
   dojście, więc bez JavaScriptu i przy ograniczonym ruchu wszystko jest
   kompletne (ta sama zasada co na stronie głównej).
   ⚠️ Ruch ma CIĘŻARY (uwaga Karola: „animacje nie mają ciężarów”): duży blok
   podsumowania wchodzi dłużej (760 ms) niż wiersz (520 ms), a mały znacznik
   werdyktu najkrócej (300 ms). Równe czasy czytają się jak suwak.
   ========================================================================== */

/* --- makieta wprowadzenia: protokół odpowiedzi AI --- */
.aiaw .svc-win__body { display: flex; flex-direction: column; gap: 14px; padding: 20px 18px 22px; }
.aiaw__row {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding-bottom: 13px;
  border-bottom: 1px solid var(--border-subtle);
}
.aiaw__row:last-of-type { border-bottom: 0; padding-bottom: 4px; }
.aiaw__q {
  display: flex;
  align-items: center;
  gap: 9px;
  min-width: 0;
  font-size: 14px;
  color: #e8eaed;
}
.aiaw__q svg { width: 14px; height: 14px; flex: none; color: var(--serp-mut); }
.aiaw__q span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.aiaw__q em {
  font-style: normal;
  margin-left: auto;
  padding-left: 10px;
  flex: none;
  font-size: 12px;
  font-weight: 600;
  color: var(--serp-mut);
}
.aiaw__names { display: flex; flex-wrap: wrap; align-items: center; gap: 7px; }
.aiaw__chip {
  border: 1px solid var(--border-default);
  border-radius: 999px;
  padding: 5px 12px;
  font-size: 13px;
  color: var(--text-body);
  white-space: nowrap;
}
/* jedyne miejsce z czerwienią w makiecie — marka klienta. Czerwień pada RZADKO
   i zawsze na to, co jest tu najważniejsze (brandbook AW). */
.aiaw__chip--you {
  border-color: rgba(255, 44, 44, .55);
  background: rgba(255, 44, 44, .10);
  color: var(--text-heading);
  font-weight: 600;
}
.aiaw__verdict {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-left: auto;
  padding-left: 10px;
  flex: none;
  font-size: 12px;
  font-weight: 600;
  color: var(--text-body);
  white-space: nowrap;
}
.aiaw__verdict svg { width: 15px; height: 15px; flex: none; }
.aiaw__verdict--yes { color: var(--text-heading); }
.aiaw__sum {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 26px;
  margin-top: 2px;
  padding-top: 15px;
  border-top: 1px solid var(--border-default);
}
.aiaw__sum-a, .aiaw__sum-b { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.aiaw__sum em { font-style: normal; font-size: 12px; color: var(--serp-mut); }
.aiaw__sum strong {
  font-size: 17px;
  font-weight: 700;
  color: var(--text-heading);
  font-variant-numeric: tabular-nums;
}
/* ⚠️ W makiecie czerwień pada TYLKO na markę klienta (.aiaw__chip--you).
   Podsumowanie zostaje białe — inaczej w samym wprowadzeniu byłyby cztery
   czerwone elementy naraz (nagłówek, znacznik marki, liczba, guzik),
   a brandbook AW mówi wprost: czerwień pada RZADKO. */

/* --- porównanie: wyszukiwarka kontra sztuczna inteligencja --- */
.aiac {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  gap: 20px;
  align-items: stretch;
  margin-top: clamp(26px, 3vw, 40px);
}
.aiac__side {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: clamp(20px, 2.2vw, 28px);
  border: 1px solid var(--border-subtle);
  border-radius: 24px;
  background: var(--color-alpha-white-03);
}
.aiac__side--hot { border-color: rgba(255, 44, 44, .28); }
/* podpis kolumny to prawdziwa etykieta, nie szary mikropodpis pod ikoną —
   cienkie, rozstrzelone napisy w szarości zdradzają robotę AI
   (feedback_elementy_zdradzajace_ai_i_oble_ksztalty_20260804) */
.aiac__head { font-size: 15px; font-weight: 700; color: var(--text-heading); }
.aiac__viz {
  display: flex;
  flex-direction: column;
  gap: 7px;
  justify-content: center;
  min-height: 158px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--border-subtle);
}
.aiac__line {
  position: relative;
  width: var(--w, 100%);
  height: 13px;
  border-radius: 7px;
  background: rgba(255, 255, 255, .10);
}
.aiac__line--you {
  display: flex;
  align-items: center;
  height: 22px;
  padding: 0 11px;
  border: 1px solid rgba(255, 44, 44, .55);
  background: rgba(255, 44, 44, .10);
  font-size: 12px;
  font-weight: 700;
  color: var(--text-heading);
}
.aiac__more { font-size: 12px; color: var(--serp-mut); }
.aiac__bubble {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 7px;
  padding: 15px 16px;
  border: 1px solid var(--border-default);
  border-radius: 24px 24px 24px 6px;
  background: rgba(255, 255, 255, .05);
}
.aiac__bubble em { width: 100%; font-style: normal; font-size: 14px; color: #e8eaed; }
.aiac__txt { font-size: 15px; line-height: 1.55; color: var(--text-body); }
.aiac__vs {
  align-self: center;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .06em;
  color: var(--serp-mut);
}

/* --- rysunki w kartach zakresu audytu --- */
.aiav { width: 100%; }
.aiav--rivals { flex-direction: row; flex-wrap: wrap; align-items: center; }
.aiav__srow { display: flex; align-items: center; gap: 12px; width: 100%; font-size: 13px; color: var(--text-primary); }
.aiav__srow em { font-style: normal; width: 104px; flex: none; }
.aiav__srow strong {
  width: 44px;
  flex: none;
  text-align: right;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.aiav__meter {
  flex: 1;
  min-width: 40px;
  height: 8px;
  border-radius: 5px;
  background: linear-gradient(90deg, rgba(255, 255, 255, .34) var(--w, 50%), rgba(255, 255, 255, .08) var(--w, 50%));
}
.aiav__srow--you strong { color: var(--accent-default); }
.aiav__srow--you .aiav__meter {
  background: linear-gradient(90deg, rgba(255, 44, 44, .70) var(--w, 50%), rgba(255, 255, 255, .08) var(--w, 50%));
}
.aiav__quote {
  padding: 11px 14px;
  border: 1px solid var(--border-default);
  border-radius: 24px 24px 24px 6px;
  background: rgba(255, 255, 255, .05);
  font-size: 14px;
  color: #e8eaed;
}
.aiav__fix {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 13px;
  font-weight: 600;
  color: var(--text-heading);
}
.aiav__fix svg { width: 16px; height: 16px; flex: none; }
/* 🔴 Trzeci wiersz („Twoja strona") odjeżdżał o 39 px zamiast 9 — ZMIERZONE
   (0 / 26 / 82 px zamiast 0 / 26 / 52). Ustawienie samego justify-content
   i row-gap tego NIE naprawiło, więc ta jedna kompozycja idzie siatką
   zamiast układem elastycznym: siatka rozkłada wiersze deterministycznie. */
.aiav--src {
  display: grid;
  grid-template-rows: repeat(3, max-content);
  row-gap: 9px;
  align-content: center;
  /* ⚠️ justify-content: center dziedziczone z .gain__viz w SIATCE centruje
     kolumnę (w układzie elastycznym centrowało w pionie) — stąd „start" */
  justify-content: start;
  justify-items: start;
}
/* każdy wiersz dostaje SWOJE miejsce w siatce — przy układaniu automatycznym
   między drugim a trzecim wierszem powstawał pusty rząd wysokości 21 px */
.aiav--src > :nth-child(1) { grid-row: 1; }
.aiav--src > :nth-child(2) { grid-row: 2; }
.aiav--src > :nth-child(3) { grid-row: 3; }
.aiav__srcrow { display: flex; align-items: center; gap: 10px; font-size: 13px; color: var(--text-primary); }
.aiav__srcrow i { width: 8px; height: 8px; border-radius: 50%; flex: none; background: rgba(255, 255, 255, .55); }
.aiav__srcrow--miss { color: var(--serp-mut); }
.aiav__srcrow--miss i { background: transparent; border: 1px solid rgba(255, 255, 255, .35); }
.aiav__doc { display: flex; flex-direction: column; gap: 7px; width: 100%; }
.aiav__doc i { height: 9px; width: var(--w, 100%); border-radius: 5px; background: rgba(255, 255, 255, .10); }
.aiav__mark {
  align-self: flex-start;
  padding: 5px 12px;
  border: 1px solid rgba(255, 44, 44, .55);
  border-radius: 999px;
  background: rgba(255, 44, 44, .10);
  font-size: 12px;
  font-weight: 700;
  color: var(--text-heading);
}
.aiav__gaprow {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 6px 13px;
  border: 1px solid var(--serp-line);
  border-radius: 24px;
  background: #303134;
  font-size: 13px;
  color: #e8eaed;
}
.aiav__gaprow svg { width: 13px; height: 13px; flex: none; color: var(--serp-mut); }
.aiav__gaprow em { font-style: normal; margin-left: auto; padding-left: 8px; font-size: 12px; color: var(--serp-mut); }

/* --- dojście makiety: wiersze po kolei, werdykt krótko, podsumowanie najdłużej --- */
@keyframes aiaw-wejscie { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@keyframes aiaw-werdykt { from { opacity: 0; } to { opacity: 1; } }
html.js .svc--aia [data-rv]:not(.is-in) .aiaw__row,
html.js .svc--aia [data-rv]:not(.is-in) .aiaw__sum { opacity: 0; }
html.js .svc--aia [data-rv].is-in .aiaw__row {
  animation: aiaw-wejscie 520ms cubic-bezier(.22, .61, .36, 1) both;
  animation-delay: var(--d, 0ms);
}
html.js .svc--aia [data-rv].is-in .aiaw__verdict {
  animation: aiaw-werdykt 300ms ease both;
  animation-delay: calc(var(--d, 0ms) + 300ms);
}
html.js .svc--aia [data-rv].is-in .aiaw__sum {
  animation: aiaw-wejscie 760ms cubic-bezier(.22, .61, .36, 1) both;
  animation-delay: 1420ms;
}

@media (max-width: 900px) {
  .aiac { grid-template-columns: 1fr; }
  .aiac__vs { justify-self: center; }
}
@media (max-width: 640px) {
  .aiaw .svc-win__body { padding: 16px 14px 18px; }
  .aiaw__q { font-size: 13px; }
  .aiaw__chip { font-size: 12px; padding: 4px 10px; }
  .aiaw__verdict { margin-left: 0; padding-left: 0; width: 100%; }
  .aiav__srow em { width: 88px; }
  .aiav__srow strong { width: 40px; }
}
/* ⚠️ MOC REGUŁY: musi być tu „.is-in", inaczej reguła grająca
   (html.js .svc--aia [data-rv].is-in .aiaw__row) ma o jedną klasę więcej
   i WYGRYWA — przy ograniczonym ruchu animacja dalej się odgrywała.
   Złapane pomiarem: animationName zwracał „aiaw-wejscie" zamiast „none". */
@media (prefers-reduced-motion: reduce) {
  html.js .svc--aia [data-rv].is-in .aiaw__row,
  html.js .svc--aia [data-rv].is-in .aiaw__sum,
  html.js .svc--aia [data-rv].is-in .aiaw__verdict,
  html.js .svc--aia [data-rv]:not(.is-in) .aiaw__row,
  html.js .svc--aia [data-rv]:not(.is-in) .aiaw__sum { animation: none; opacity: 1; transform: none; }
}

/* ==========================================================================
   UWAGI KAROLA 11.08 (wieczór) — STRUKTURA I UKŁAD KATEGORII USŁUGOWYCH
   Źródło: „Uwagi do strony test.agencjawroclawska.pl", sekcja „kategorie usługowe".
   Blok stoi na końcu pliku celowo: przy równej sile selektora wygrywa reguła
   późniejsza, więc te ustawienia nadpisują wcześniejsze bez podbijania mocy.
   ========================================================================== */

/* --- 1. Pustka nad nagłówkiem (telefon i tablet) --------------------------
   Zmierzone przed zmianą: 108 px na WSZYSTKICH 9 podstronach (belka 80 px).
   Składały się na to trzy odstępy, każdy w innym miejscu pliku:
   52 px sekcji + 48 px siatki hero + 18 px marginesu nagłówka.
   Teraz całość trzyma jedna zmienna — zmiana odstępu to zmiana jednej liczby. */
@media (max-width: 1024px) {
  .svc .svc-sec:first-of-type { padding-top: var(--hero-odstep-gora, 20px); }
  .svc-hero__grid { padding-top: 0; }
  .hero__tytul .svc-h1 { margin-top: 0; }
}

/* --- 2. Kolejność w hero: nagłówek → animacja → podpis i guzik ------------
   Telefon i tablet: jedna kolumna, animacja wchodzi MIĘDZY nagłówek a podpis.
   Blok tekstowy jest w kodzie rozdzielony na dwa (.hero__tytul / .hero__tresc),
   bo inaczej nie da się wsunąć niczego pomiędzy nagłówek a podpis. */
@media (max-width: 1024px) {
  .svc-hero__grid > .hero__tytul { order: 1; }
  .svc-hero__grid > .hero__tresc { order: 3; }
  .svc-hero__grid > :not(.hero__tytul):not(.hero__tresc) { order: 2; }
  /* odstęp między blokami daje siatka (36 px) — podpis nie dokłada swojego */
  .hero__tresc > .svc-lead--hero { margin-top: 0; }
}
/* Komputer: układ dwukolumnowy BEZ ZMIAN. Nagłówek i treść jedno pod drugim
   w lewej kolumnie, makieta po prawej przez oba wiersze. Odstęp między
   nagłówkiem a podpisem robi margines podpisu (22 px), nie przerwa siatki. */
@media (min-width: 1025px) {
  .svc-hero__grid {
    grid-template-areas: "tytul wizual" "tresc wizual";
    grid-template-rows: auto auto;
    row-gap: 0;
    align-content: center;
  }
  .svc-hero__grid > .hero__tytul { grid-area: tytul; align-self: end; }
  .svc-hero__grid > .hero__tresc { grid-area: tresc; align-self: start; }
  .svc-hero__grid > :not(.hero__tytul):not(.hero__tresc) { grid-area: wizual; align-self: center; }
}

/* --- 3. Wielka liczba OBOK opisu, nie nad nim -----------------------------
   Uwaga Karola: „liczba odnosi się bezpośrednio do treści, która jest obok niej".
   Dotyczy 7 podstron z tym samym wzorcem: ai-search, audyt-kampanii, audyt-seo,
   lejki-marketingowe, pozycjonowanie-stron, strategia-marketingowa,
   strony-internetowe. Źródło i guzik zostają pod spodem, na całą szerokość. */
.ctr__grid > :first-child {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  column-gap: clamp(14px, 2.2vw, 32px);
  align-items: center;
}
.ctr__grid > :first-child > .svc-big { grid-column: 1; grid-row: 1; margin-top: 0; }
.ctr__grid > :first-child > .svc-big-sub { grid-column: 2; grid-row: 1; margin-top: 0; max-width: none; }
.ctr__grid > :first-child > .svc-src,
.ctr__grid > :first-child > .svc-cta-row,
.ctr__grid > :first-child > .svc-note { grid-column: 1 / -1; }
.ctr__grid > :first-child > .svc-src { margin-top: 18px; }

/* --- 4. Sekcja „Kiedy zobaczysz pierwsze efekty" (SEO) --------------------
   Na telefonie: nagłówek → wykres → podpis „Mówimy wprost…" i reszta.
   Na komputerze układ dwukolumnowy zostaje jak był. */
@media (max-width: 1024px) {
  .grow__grid > .grow__tytul { order: 1; }
  .grow__grid > .grow__tresc { order: 3; }
  .grow__grid > :not(.grow__tytul):not(.grow__tresc) { order: 2; }
  .grow__grid { gap: 24px; }
  .grow__tresc > .svc-lead:first-child { margin-top: 0; }
}
@media (min-width: 1025px) {
  .grow__grid {
    grid-template-areas: "tytul wykres" "tresc wykres";
    grid-template-rows: auto auto;
    row-gap: 0;
    align-content: center;
  }
  .grow__grid > .grow__tytul { grid-area: tytul; align-self: end; }
  .grow__grid > .grow__tresc { grid-area: tresc; align-self: start; }
  .grow__grid > :not(.grow__tytul):not(.grow__tresc) { grid-area: wykres; align-self: center; }
  .grow__tresc > .svc-lead:first-child { margin-top: 22px; }
}

/* --- 5. Hero na jeden ekran (telefon) — krok 1: odstępy ------------------
   Miejsca od dołu belki do dołu ekranu jest 764 px (iPhone 390 × 844).
   Same odstępy oddają 54 px: przerwy w siatce 36 → 22 px (dwie sztuki)
   i dolny odstęp pierwszej sekcji 42 → 16 px. Reszta musi przyjść
   z wysokości samych makiet — to jest liczone osobno dla każdej podstrony. */
@media (max-width: 1024px) {
  .svc-hero__grid { gap: 22px; }
  .svc .svc-sec:first-of-type { padding-bottom: 16px; }
}

/* --- 6. Kontrast szarej linii na wykresie „stały koszt" — wariant C ---------
   Wybór Karola 11.08. Było: biel 14%, grubość 2 px → kontrast do tła 1,48 : 1.
   Jest: biel 60%, grubość 2,4 px → kontrast 7,20 : 1 (×4,9).
   Dotyczy dwóch podstron z tym samym wykresem: /pozycjonowanie-stron/
   („stały koszt") i /performance-marketing/ („bez kampanii").
   ⚠️ Świadomie NIE ruszam wspólnej zmiennej --border-idle-dot: siedzą na niej
   też kropki w paskach makiet i kropki karuzel na stronie głównej.
   Cofnięcie: skasować ten blok i wpisać w obu podstronach z powrotem
   stroke="var(--border-idle-dot)" stroke-width="2". */
.svc { --kreska-koszt: rgba(255, 255, 255, .60); }
.gain__roi-legend .is-cost i { border-top-color: var(--kreska-koszt); border-top-width: 2.4px; }

/* --- 7. Hero na jeden ekran — wariant C (wybór Karola 11.08) --------------
   Zasada wariantu C: najpierw zdejmujemy z makiety ozdoby i ściskamy jej
   wnętrze, a dopiero to, co zostało ponad limit, oddajemy przeskalowaniem.
   Skalowanie jest ostatnie, bo jako jedyne zmniejsza pismo w makiecie.

   Limit na telefonie: 764 px (844 minus belka 80 px).
   `--makieta-skala` ustawiam osobno dla każdej podstrony, bo każda ma inną
   makietę i inną długość nagłówka ze wstępem.
   Cofnięcie: skasować ten blok. */
@media (max-width: 1024px) {
  .svc-hero__grid > :not(.hero__tytul):not(.hero__tresc) { zoom: var(--makieta-skala, 1); }

  /* SEO — ściśnięte wnętrze makiety Google: niższe wiersze wyników,
     bez paska zakładek („Wszystkie / Mapy / Grafika") i bez podpisu
     pod Twoim wynikiem. Makieta schodzi z 674 na 511 px, resztę bierze skala. */
  .svc--seo .svc-sec:first-of-type .climb__list { --slot: 62px; }
  .svc--seo .svc-sec:first-of-type .climb__row { height: 56px; padding: 6px 10px; }
  .svc--seo .svc-sec:first-of-type .serp__tabs { display: none; }
  .svc--seo .svc-sec:first-of-type .climb .serp__d { display: none; }
  .svc--seo .svc-sec:first-of-type .climb__badge { margin-top: 6px; }
}

/* Podstrony audytowe: makieta to lista wierszy, więc na telefonie skracamy listę.
   Zostają dwa/trzy pierwsze wiersze — tyle wystarczy, żeby pokazać kontrast
   („jest Twoja marka" kontra „nie ma"), a podsumowanie pod spodem zostaje,
   bo to ono niesie liczbę. Reszty ubytku dopełnia skala. */
@media (max-width: 1024px) {
  .svc--aia .svc-sec:first-of-type .aiaw__row:nth-of-type(n+3) { display: none; }
  .svc--ak  .svc-sec:first-of-type .scanw__row:nth-of-type(n+4) { display: none; }
  .svc--as  .svc-sec:first-of-type .xrw__row:nth-of-type(n+3) { display: none; }
}

/* Skala makiety, dobrana osobno dla każdej podstrony tak, żeby hero zmieścił się
   w 764 px. Liczby wzięte z pomiaru po zdjęciu ozdób, nie z oka.
   Im wyższa liczba, tym większe pismo w makiecie (1 = bez zmian). */
@media (max-width: 1024px) {
  /* 11.08 runda 2: po rozciągnięciu makiet na całą szerokość (blok 13 niżej)
     wnętrze ma więcej miejsca w wierszu, więc trzy podstrony mieszczą się przy
     WIĘKSZEJ skali — czyli z większym pismem w makiecie. Granicę wyznaczył
     pomiar: przy każdej z tych liczb otwarcie ma 764 px, czyli dokładnie tyle,
     ile zostaje na pierwszy ekran iPhone'a. Zostawiony zapas 1 punktu na
     różnice między przeglądarką sterowaną a prawdziwym telefonem.
     Było: .81 / .63 / .67. */
  .svc--ai    { --makieta-skala: .87; }
  .svc--aia   { --makieta-skala: .72; }
  .svc--ak    { --makieta-skala: .78; }
  .svc--as    { --makieta-skala: .57; }
  .svc--lej   { --makieta-skala: .86; }
  .svc--pm    { --makieta-skala: .67; }
  .svc--seo   { --makieta-skala: .78; }
  .svc--www   { --makieta-skala: .73; }
  /* .svc--strat mieści się bez skalowania */
}

/* --- 8. Kropki „AI pisze" przestają przesuwać stronę -----------------------
   Wskaźnik pisania pojawiał się i znikał JAKO ELEMENT UKŁADU, więc wszystko
   pod nim skakało w dół i z powrotem. Po włączeniu animacji na telefonie
   dawało to skok układu 0,28–0,35 przy progu „dobrze" 0,10 według Google.
   Teraz wskaźnik jest wyjęty z układu (pozycja bezwzględna bez współrzędnych,
   czyli dokładnie tam, gdzie stałby normalnie) — nic nie zajmuje i nic nie
   przesuwa. Dymek odpowiedzi i tak trzyma swoje miejsce od początku, bo gaśnie
   samą przezroczystością, a nie znikaniem z układu.
   Cofnięcie: skasować te dwie reguły. */
.aichat { position: relative; }
.aichat > .ai-typing { position: absolute; z-index: 2; }

/* ==========================================================================
   RUNDA 2 uwag Karola z 11.08 (wieczór) — bloki 9+
   ========================================================================== */

/* --- 9. Sekcja „dedykowany opiekun": guzik POD zdjęciami -------------------
   Uwaga Karola: „W sekcji dedykowany opiekun wszędzie CTA ma być pod zdjęciami".
   Na telefonie kolejność była: nagłówek → tekst → GUZIK → zdjęcia.
   Guzik wyszedł z bloku tekstowego i jest teraz osobnym, ostatnim dzieckiem
   sekcji (klasa `.ppl__cta` w 9 podstronach), więc na telefonie ląduje pod
   zdjęciami. Na komputerze wraca dokładnie tam, gdzie był: w tej samej
   kolumnie co tekst, tuż pod nim.
   Cofnięcie: skasować ten blok i wciągnąć `.ppl__cta` z powrotem do
   `.ppl__text` w 9 plikach (kopie w .claude/tmp/kopia-przed-runda2-11-08/). */
@media (max-width: 1024px) {
  .ppl__cta { order: 3; }
}
@media (min-width: 1025px) {
  .ppl {
    grid-template-rows: auto auto;
    align-content: center;
    row-gap: 0;
  }
  .ppl__visual, .ppl--flip .ppl__visual { grid-row: 1 / 3; align-self: center; }
  .ppl__visual { grid-column: 1; }
  .ppl__text   { grid-column: 2; grid-row: 1; align-self: end; }
  .ppl__cta    { grid-column: 2; grid-row: 2; align-self: start; }
  .ppl--flip .ppl__visual { grid-column: 2; }
  .ppl--flip .ppl__text, .ppl--flip .ppl__cta { grid-column: 1; }
}

/* --- 10. Droga klienta na telefonie: krok zapala się, gdy sam wejdzie w kadr --
   Zasada Karola z 11.08: animacja zaczyna się wtedy, gdy sekcja pojawia się
   na ekranie. Sztywne opóźnienia 0,5 / 2,2 / 3,9 / 5,6 s liczyły czas od wejścia
   całej sekcji, a ta ma na telefonie 867 px przy ekranie 844 px — czwarty krok
   wchodził w kadr 644 px przewinięcia PO starcie zegara.
   Klasę `jour--kadr` dokłada svc.js tylko poniżej 1025 px. Na komputerze
   nic się nie zmienia: cztery kroki stoją obok siebie i zegar zgadza się
   z ruchem kropki po szynie.
   Cofnięcie: skasować ten blok i funkcję `jour()` z końca svc.js. */
@media (max-width: 1024px) {
  .jour--kadr .jour__step,
  .jour--kadr .jour__step .jour__ico,
  .jour--kadr .jour__step::before { transition-delay: 0s !important; }
  html.js .jour--kadr .jour__step:not(.is-on) { border-color: var(--border-subtle); }
  html.js .jour--kadr .jour__step--end:not(.is-on) { background: linear-gradient(180deg, var(--surface-raised), var(--surface-sunken)); }
  html.js .jour--kadr .jour__step:not(.is-on) .jour__ico {
    background: var(--color-alpha-white-04);
    border-color: var(--border-default);
    animation: none;
  }
  .jour--kadr .jour__step.is-on .jour__ico { animation: jourPop .55s ease-out both; }
}

/* --- 11. Czat jak prawdziwy czat z modelem AI -----------------------------
   Wskazanie Karola z 11.08: „piszemy od dołu, potem nowa wiadomość przesuwa
   naszą do góry". Pytanie startuje przy dolnej krawędzi ramki, a wejście
   odpowiedzi wypycha je w górę.
   ⚠ Ruch robią PRZESUNIĘCIA (transform), nie marginesy. Pierwsza wersja
   przesuwała dymki marginesami i Google liczyło to jako skok układu: na wgranej
   wersji wyszło 0,1215 przy progu „dobrze" 0,10, bo marginesy wchodziły dopiero
   po wczytaniu krojów pisma. Przesunięcia nie ruszają układu strony w ogóle,
   więc skok wraca do zera, a efekt na ekranie jest ten sam.
   `--bot-h` (wysokość dymka odpowiedzi) ustawia svc.js po zmierzeniu dymka.
   Cofnięcie: skasować ten blok i funkcję `zywyCzat` z svc.js. */
html.js .aichat--zywy { overflow: hidden; }
html.js .aichat--zywy .aib--user,
html.js .aichat--zywy .aib--bot {
  transition: transform .62s cubic-bezier(.2, .7, .2, 1), opacity .45s ease .1s;
}
html.js .aichat--zywy:not(.is-odpowiedz) .aib--user,
html.js .aichat--zywy:not(.is-odpowiedz) .aib--bot {
  transform: translateY(var(--bot-h, 0px));
}
/* chwila „AI pisze": kropki wchodzą pod pytanie i podnoszą je o swoją wysokość —
   dokładnie tak, jak zachowuje się prawdziwy czat, zanim przyjdzie odpowiedź */
html.js .aichat--zywy .ai-typing { top: auto; bottom: 4px; left: 2px; }
html.js .aichat--zywy.is-pisze:not(.is-odpowiedz) .aib--user,
html.js .aichat--zywy.is-pisze:not(.is-odpowiedz) .aib--bot {
  transform: translateY(calc(var(--bot-h, 0px) - var(--pisze-h, 38px)));
}

/* --- 12. Kropki odwzorowane z żywej strony /ai-search/ ---------------------
   Karol wskazał starą stronę jako wzorzec: „animacja z kropkami jest smooth,
   ma glow, wygląda o wiele czyściej i taki poziom oczekuję".
   Odczytane z żywej strony (klasa `.geo-dot.lit::after`) i przeniesione tu
   jeden do jednego:
     poświata  0 0 13px 3px rgba(255,44,44,.72)   — u nas było 0 0 9px .55
     kropka zwykła  rgba(255,255,255,.17)          — u nas było .13
   Klatki ruchu (0,55 → 1,16 → 1,0), czasy (780–1450 ms) i rozrzut opóźnień
   (28–2400 ms) mieliśmy już takie same jak wzorzec — różnicę robiła
   wyłącznie poświata, czyli dokładnie to, o czym mówiłeś.
   ⚠ Na starej stronie animacja kropek jest WYŁĄCZONA poniżej 820 px
   (`.geo-dot.lit::after { animation: none !important }`), więc na telefonie
   wzorca nie ma czego kopiować — wersja z komputera wchodzi też na telefon.
   Każda z dwóch siatek ma teraz własny wyzwalacz (patrz svc.js, funkcja prob).
   Cofnięcie: skasować ten blok. */
.prob__dot { background: rgba(255, 255, 255, .17); }
.prob__dot--hot::after { box-shadow: 0 0 13px 3px rgba(255, 44, 44, .72); }
[data-prob] .prob__panel.is-in .prob__dot--hot::after {
  animation: dotpop var(--dur, .95s) cubic-bezier(.2, .7, .2, 1) both;
  animation-delay: var(--d, 0ms);
}
/* dopóki siatka nie weszła na ekran, jej kropki czekają wygaszone */
html.js [data-prob] .prob__panel:not(.is-in) .prob__dot--hot::after { opacity: 0; }

/* --- 13. Makieta w otwarciu na CAŁĄ szerokość ekranu ----------------------
   Trzy uwagi Karola z 11.08 mówiły to samo z trzech stron: „animacja ma być
   rozciągnięta do końca ekranu, teraz jest mała, mamy bez sensu marginesy
   z lewej i z prawej", „margines z prawej mniejszy niż z lewej, do rozciągnięcia
   i powiększenia", „trzeba ją zwęzić i rozciągnąć".
   Zmierzone przyczyny (telefon 390 px, kolumna od 20 do 370 px):
     /performance-marketing/ — makieta telefonu ma stałą szerokość 320 px,
       więc po przeskalowaniu zajmowała 214 px z 350 i zostawały po 88 px
       pustki z obu stron;
     /audyt-seo/ — okno makiety ma `max-width: 560px` i jest dosunięte do prawej
       (`margin-left: auto`), więc pustka 31 px stawała z LEWEJ: 51 px z lewej
       przy 20 px z prawej. Dokładnie to, co zgłosiłeś.
   Naprawa zdejmuje oba ograniczenia w otwarciu podstrony. Pozostałe siedem
   makiet już wypełniało szerokość i pomiar po zmianie potwierdza, że nic
   się w nich nie ruszyło.
   Wysokość otwarcia nie urosła ani o piksel (763 px w obu przypadkach
   przed i po), więc nie trzeba było niczego skracać.
   Cofnięcie: skasować ten blok. */
@media (max-width: 1024px) {
  .svc-hero__grid > .svc-win { max-width: none; margin-left: 0; }
  .svc-hero__grid > .phone { width: 100%; }
}

/* ==========================================================================
   RUNDA 2 — decyzje Karola z 12.08: A1=B · A4=A · A6=B · B4=C · B1=A
   plus nowa uwaga: CTA pod animacją w sekcji z wielką liczbą
   ========================================================================== */

/* --- 14. Sekcja z wielką liczbą: guzik POD animacją -----------------------
   Uwaga Karola z 12.08: „musimy zmienić kolejność jednego CTA na każdej
   podstronie — w sekcji, gdzie mamy cyfry, CTA ma być pod animacją".
   Na SEO tą animacją jest drabinka kliknięć od pozycji 1 do 10.
   Było na telefonie: liczba z opisem → źródło → GUZIK → animacja.
   Jest: liczba z opisem → źródło → animacja → GUZIK.
   Guzik wyszedł z bloku z liczbą i jest osobnym, ostatnim dzieckiem siatki
   (klasa `.ctr__cta` w 7 podstronach). Na komputerze wraca dokładnie tam,
   gdzie był: w lewej kolumnie, pod tekstem.
   Cofnięcie: skasować ten blok i wciągnąć `.ctr__cta` z powrotem do bloku
   z liczbą w 7 plikach — kopie w `.claude/tmp/kopia-przed-runda2-11-08/`. */
@media (min-width: 1025px) {
  .ctr__grid:has(> .ctr__cta) {
    grid-template-rows: auto auto;
    align-content: center;
    row-gap: 0;
  }
  .ctr__grid:has(> .ctr__cta) > :first-child { grid-column: 1; grid-row: 1; align-self: end; }
  .ctr__grid:has(> .ctr__cta) > :nth-child(2)  { grid-column: 2; grid-row: 1 / 3; align-self: center; }
  .ctr__grid:has(> .ctr__cta) > .ctr__cta      { grid-column: 1; grid-row: 2; align-self: start; margin-top: 32px; }
}
@media (max-width: 1024px) {
  .ctr__cta { margin-top: 4px; }
}

/* --- 15. A1 = wariant B: guzik odchudzony do progu palca i wyśrodkowany ---
   Twój wybór z 12.08. Wyściółka 17/31 → 12/22 px, więc guzik ma 44 px
   wysokości — dokładnie tyle, ile trzeba, żeby pewnie trafić kciukiem.
   Czerwieni mniej o 25%. Pismo w guziku bez zmian, tak jak prosiłeś.
   Wyśrodkowanie: guzik stał przy lewej krawędzi (środek 128 px przy środku
   ekranu 195 px) — teraz stoi na środku w każdej sekcji.
   ⚠️ Kontrast białego napisu na tej czerwieni zostaje 3,72 : 1 przy normie
   4,5 : 1 — to nie zmienia się od odchudzenia. Wariant D z ciemniejszą
   czerwienią czeka jako osobna decyzja.
   Cofnięcie: skasować ten blok. */
@media (max-width: 1024px) {
  .svc .btn--primary {
    padding: 12px 22px;
    box-shadow: 0 8px 18px -10px rgba(255, 44, 44, .45);
  }
  .svc .svc-cta-row,
  .svc .fit__cta { display: flex; justify-content: center; }
}

/* --- 16. A4 = wariant A: liczba większa o jedną trzecią -------------------
   Twój wybór z 12.08. Liczba 36 → 49 px (+36%). Odstęp między liczbą
   a tekstem 14 → 26 px, źródło 13 → 11 px i przygaszone do 55% — te dwie
   rzeczy podałeś wprost, więc weszły bez wyboru.
   Wariant A jako jedyny nie zwęża kolumny tekstu na tyle, żeby najdłuższe
   słowo z niej wystawało.
   Wchodzi na 7 podstron z tym wzorcem.
   Cofnięcie: skasować ten blok. */
@media (max-width: 1024px) {
  .svc .svc-big { font-size: calc(var(--skala-h1) * 1.35); }
  .ctr__grid > :first-child { column-gap: 26px; }
  .svc .svc-src { font-size: 11px; opacity: .55; margin-top: 22px; }
}

/* --- 17. A6 = wariant B: logo w belce mniejsze o jedną piątą --------------
   Twój wybór z 12.08. Logo 34 → 27 px, czyli 45% wysokości belki zamiast 57%.
   Odstęp nad i pod rośnie sam z 13 na 17 px, bo belka zostaje 60 px wysoka.
   🔴 Zmiana wchodzi na CAŁĄ stronę — belka jest wspólna ze stroną główną,
   blogiem i opisami wdrożeń.
   Przesunięcie sygnetu w prawo czeka na Twoje potwierdzenie — warianty
   osobno, bo prosiłeś o potwierdzenie przed wdrożeniem.
   Cofnięcie: skasować ten blok. */
@media (max-width: 1024px) {
  .logo { height: 27px; }
}

/* --- 18. B4 = wariant C: mocna poświata na ikonach kroków ----------------
   Twój wybór z 12.08. Poświata pojawia się razem z zapaleniem ikony
   na czerwono i zostaje — nie błyska i nie gaśnie.
   Wchodzi na telefonie i na komputerze, bo wskazanie („niech mają glow przy
   animacji") nie ograniczało się do telefonu.
   Cofnięcie: skasować ten blok. */
.jour .jour__ico { transition: background .5s ease, border-color .5s ease, box-shadow .8s ease; }
.jour--kadr .jour__step.is-on .jour__ico,
.jour.is-in .jour__step .jour__ico {
  box-shadow: 0 0 30px rgba(255, 44, 44, .85), 0 0 8px rgba(255, 44, 44, .6);
}
html.js .jour--kadr .jour__step:not(.is-on) .jour__ico { box-shadow: none; }

/* --- 19. A6 (dokończenie) = wariant A: sygnet dalej od lewego łuku belki ---
   Twój wybór z 12.08: „sygnet przesunąć trochę w prawo, żeby było więcej
   przestrzeni w lewym półokręgu".
   Zmierzone: lewy łuk belki ma promień 30 px, a logo zaczynało się 16 px
   od jej krawędzi — czyli wchodziło 14 px w sam łuk, tam gdzie pola jest
   najmniej. Po przesunięciu o 6 px zostaje w łuku 8 px.
   Cofnięcie: skasować ten blok. */
@media (max-width: 1024px) {
  .navbar__brand { padding-left: 6px; }
}

/* --- 20. Kropki 5/100 → 95/100 odwzorowane z żywej /ai-search/ (12.08) ------
   🔴 Twoja uwaga: „na test.agencjawroclawska.pl/ai-search/ dalej wygląda
   animacja bardzo źle […] wejdź na agencjawroclawska.pl/ai-search/ i przenieś
   dokładnie tę samą animację, chodzi o płynność ładowania kropek, glow,
   wielkość kropek".

   Runda z rana (blok 12 wyżej) przeniosła KOLOR kropki i poświatę, ale nie
   ruszyła GEOMETRII — a to ona robiła całą różnicę. Odczytane ze wzorca
   (`.geo-dotgrid` na żywej stronie) i zmierzone u nas przy 1440 px:

     żywa strona   siatka 288 px, BEZ ramki, tła i wyściółki,
                   odstęp clamp(5px, .6vw, 8px)      → kropka ~21,6 px
     nasza         siatka na całą szerokość kolumny (~516 px),
                   ramka + tło + wyściółka 22 px,
                   odstęp 7 px                        → kropka ~45 px

   Czyli nasze kropki były DWA RAZY większe od wzorca. Poświata `0 0 13px 3px`
   jest policzona pod kropkę 21 px — rozciągnięta na 45 px przestaje być łuną
   i robi się cienką obwódką. Stąd wrażenie „taniej" animacji przy tych samych
   kolorach. Do tego wzorzec nie ma pod kropkami żadnej płyty: sama siatka
   na tle sekcji, więc kropki niosą całą uwagę.

   Ten blok zdejmuje płytę i ustawia geometrię wzorca. Kolory, poświata, klatki
   ruchu (0,55 → 1,16 → 1,0), czasy (760–1450 ms) i rozrzut opóźnień
   (28–2400 ms) zostają — te już były zgodne co do wartości.
   Cofnięcie: skasować ten blok. */
.prob__grid {
  gap: clamp(5px, .6vw, 8px);
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
  max-width: 288px;
  margin: 0 auto;
  aspect-ratio: 1;
}
.prob__panel--hot .prob__grid { border: 0; background: none; }

/* --- 21. Makieta telefonu w otwarciu /performance-marketing/ o 20% większa ---
   🔴 Twoja uwaga z 12.08: „animacja do powiększenia o ok. 20%".

   Makieta ma szerokość 320 px, a jej wnętrze (wysokość ekranu 540 px, odstępy,
   wielkości pisma) jest podane w pikselach. Samo poszerzenie ramki rozjechałoby
   proporcje: telefon zrobiłby się szerszy, a treść w środku została w starej
   skali. `zoom` powiększa CAŁY element razem z zawartością i — w odróżnieniu
   od `transform: scale()` — rezerwuje na to miejsce w układzie, więc nic nie
   nachodzi na sąsiednie elementy.
   Zmierzone przy 1440 px: prawa kolumna otwarcia ma ~646 px, makieta rośnie
   z 320 na 384 px, czyli dalej mieści się z zapasem po 131 px z każdej strony.

   Tylko komputer i tablet powyżej 1024 px. Niżej makieta i tak idzie na całą
   szerokość ekranu (blok 13 wyżej), więc powiększanie nie ma tam sensu —
   a Ty oglądałeś komputer.
   Cofnięcie: skasować ten blok. */
@media (min-width: 1025px) {
  .svc--pm .phone { zoom: 1.2; }
}
