/* Style, których prototyp nie ma, a WordPress ich wymaga.
   Prototyp to statyczny HTML: nie zna klas dostępności WP ani klas, które
   redaktor wstawia z edytora. Ten plik NIE jest generowany z prototypu —
   tu dopisujemy ręcznie. Reszta CSS-u leci z tools/wytnij-css.py. */

#page-root { margin: 0; padding: 0; }

/* Wcięcie podpozycji w menu mobilnym — odróżnia je od samodzielnych linków */
.in-mob .in-mob-child > a { padding-left: 28px; }

/* --- paleta marki (21.08) -----------------------------------------------
   Brandbook Instytutu ma PIĘĆ kolorów i tylko ich wolno używać:
       #643B81  fiolet (podstawowy)
       #5E689A  granatowy błękit
       #67B6C0  turkus
       #C6C4D8  jasna lawenda
       #E7EDF9  bardzo jasny błękit (tło stron)

   Tokeny `--brand-50…900` w tokeny.css to automatyczna drabinka odcieni,
   którą generator wyliczył sobie z #643B81 — i to ONA wchodziła na stronę
   jako „prawie czarny śliwkowy" (#281834) na ciemnych kafelkach i na
   wyróżnionym pakiecie w cenniku. Takiego koloru nie ma w brandbooku.

   Dlatego przepinamy całą drabinkę na kolory marki. Robimy to na poziomie
   tokenów, a nie pojedynczych reguł, bo `--brand-900` siedzi w ~15 miejscach
   w komponenty.css i strony/index.css — poprawianie ich po kolei zostawiłoby
   następny ciemny kafelek na później.

   ⚠️ Nie ruszamy tu --brand-50 / --brand-100. To nie są „kolory" tylko
   powierzchnie kart: prawie biała mgiełka, na której karta odcina się od
   jasnobłękitnego tła strony. Podmiana ich na #E7EDF9 zlałaby karty z tłem.
   Przeliczamy je za to wprost z lawendy marki (#C6C4D8 rozbielone), żeby i
   one wychodziły z palety, a nie z drabinki generatora. */
:root {
    --brand-900: #643B81;
    --brand-800: #643B81;
    --brand-700: #643B81;
    --brand-600: #5E689A;   /* hover przycisków — druga barwa marki */
    --brand-500: #643B81;
    --brand-400: #5E689A;
    --brand-300: #C6C4D8;
    --brand-200: #C6C4D8;
    --brand-100: #E4E3EE;   /* #C6C4D8 @ ~45% na bieli */
    --brand-50:  #F2F1F6;   /* #C6C4D8 @ ~22% na bieli */
}

/* --- dostępność ---------------------------------------------------------
   Bez tej reguły link „Przejdź do treści" jest zwykłym, widocznym linkiem:
   rysuje pasek nad nagłówkiem i spycha całą stronę w dół (hero wjeżdża pod
   nagłówek przez margin-top: -96px, więc widać wtedy jasny pas nad fioletem). */
.screen-reader-text {
    position: absolute !important;
    width: 1px; height: 1px;
    margin: -1px; padding: 0; border: 0;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    overflow: hidden;
    white-space: nowrap;
    word-wrap: normal;
}

/* Po tabulacji link ma się pokazać — inaczej nie ma z niego pożytku. */
.screen-reader-text:focus {
    position: fixed !important;
    top: 12px; left: 12px;
    z-index: 100;
    width: auto; height: auto;
    margin: 0; padding: 12px 20px;
    clip: auto; clip-path: none;
    background: var(--brand-primary, #643B81);
    color: #fff;
    font-weight: 600;
    text-decoration: none;
    border-radius: var(--radius-md, 8px);
}

/* --- treść z edytora ----------------------------------------------------
   Klasy, które WordPress wstawia do treści wpisów i stron. Prototyp ich nie
   zna, bo jego treść jest zapisana wprost w HTML-u. */
/* ⚠️ ATRYBUT `hidden` MUSI WYGRYWAĆ Z KLASAMI KOMPONENTÓW.
   `hidden` to w praktyce `display:none` z arkusza PRZEGLĄDARKI, więc dowolna
   nasza reguła z klasą (np. `.in-note{display:block}`) go pokonuje. Objaw jest
   mylący: element „ukryty" w HTML-u widać na stronie — na /gra-terapeutyczna/
   formularz dla grup pokazywał podziękowanie zanim ktokolwiek go wysłał, a pod
   nim wisiała pusta ramka (to był ukryty komunikat błędu). W motywie było już
   SZEŚĆ punktowych łatek na ten sam problem (`.in-prod[hidden]`, `.in-md[hidden]`
   itd.) — ta reguła zastępuje potrzebę dokładania kolejnych. 20.08.2026 */
[hidden] { display: none !important; }

.in-art-body img { max-width: 100%; height: auto; }
.in-art-body .alignleft { float: left; margin: 0 24px 16px 0; }
.in-art-body .alignright { float: right; margin: 0 0 16px 24px; }
.in-art-body .aligncenter { display: block; margin-inline: auto; }
.in-art-body .wp-caption { max-width: 100%; }
.in-art-body .wp-caption-text { font-size: 14px; color: var(--color-text-muted, #413B4D); }

/* --- ekran wyniku testu -------------------------------------------------
   Prototyp ma style .in-qz-res*, ale jego wynik był jednym akapitem. Nasz
   pokazuje jeszcze kroki pracy z kodem i rozkład punktów — te dwie listy
   dokładamy tutaj, w duchu reszty komponentu. */
.in-qz-steps { list-style: none; counter-reset: krok; margin: 0 0 26px; padding: 0; display: grid; gap: 12px; }
.in-qz-steps li { counter-increment: krok; position: relative; padding-left: 40px; font-size: 15px; line-height: 1.6; }
.in-qz-steps li::before {
    content: counter(krok);
    position: absolute; left: 0; top: -1px;
    width: 26px; height: 26px; display: grid; place-items: center;
    border-radius: 999px;
    background: var(--brand-100, #e8e2ec); color: var(--brand-700, #46295a);
    font-size: 13px; font-weight: 700;
}
.in-qz-score { list-style: none; margin: 0 0 26px; padding: 0; display: grid; gap: 6px; }
.in-qz-score li {
    display: flex; align-items: baseline; justify-content: space-between; gap: 14px;
    padding: 8px 0; border-bottom: 1px solid var(--color-border, #C6C4D8);
    font-size: 15px;
}
.in-qz-score li b { font-variant-numeric: tabular-nums; color: var(--brand-700, #46295a); }

/* Brak zaznaczonej odpowiedzi — krótkie podświetlenie listy zamiast alertu. */
.in-qz-opts.is-brak { animation: in-qz-brak .6s ease; }
@keyframes in-qz-brak {
    0%, 100% { box-shadow: 0 0 0 0 rgba(180,38,30,0); }
    30%      { box-shadow: 0 0 0 3px rgba(180,38,30,.28); }
}

/* Druk wyniku: zostaje sam wynik, bez nagłówka, stopki i pozostałych pytań. */
@media print {
    .in-hdr, .in-ftr, .in-cart, .in-scrim, .in-qz-copy, .in-qz-bar, .in-qz-nav { display: none !important; }
    .in-qz-s:not(.is-on) { display: none !important; }
    .in-qz-card { box-shadow: none; border: 0; }
}

/* --- formularz kontaktowy ----------------------------------------------
   Prototyp ma style .in-form/.in-f-w/.in-sel, ale nie zna pułapki na roboty
   ani komunikatów po wysyłce — te dwie rzeczy dokładamy tutaj. */
.in-hp { position: absolute !important; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.in-note--ok { border-color: rgba(103,182,192,.9); }
.in-note--err { border-color: rgba(180,38,30,.55); }
.in-chk { display: flex; gap: 12px; align-items: flex-start; font-size: 14px; line-height: 1.55; margin: 4px 0 8px; }
/* `width: auto` jest tu KLUCZOWE, nie kosmetyczne: formularze mają globalne
   input{width:100%}, a przy flex:0 0 auto bazą jest właśnie width — checkbox
   rozdymał się do 509 px i spychał etykietę do 78-pikselowej kolumny. */
.in-chk input { width: auto; flex: 0 0 auto; margin-top: 3px; accent-color: var(--brand-primary, #643B81); }
.in-chk span { flex: 1 1 auto; min-width: 0; }

/* --- WooCommerce ---------------------------------------------------------
   Prototyp nie zna klas sklepu. Zdejmujemy tylko to, co najbardziej gryzie
   się z układem: własne odstępy i kolory przycisków. Pełne przepisanie
   list i karty produktu to osobny krok. */
.woocommerce .in-wrap { max-width: var(--in-maxw, 1200px); }
/* ⚠️ Powyższa reguła łapie KAŻDY `.in-wrap` na stronie z klasą `woocommerce`,
   więc na /sklep/ zwężała także nasze hero i sekcje ACF — te same sekcje były
   tam o 320 px węższe niż na pozostałych podstronach (1120 px zamiast 1440).
   Wąska kolumna ma dotyczyć wyłącznie markupu WooCommerce: koszyka, kasy,
   konta i karty produktu. */
.woocommerce .in-hero > .in-wrap,
.woocommerce .in-sec > .in-wrap { max-width: none; }
.woocommerce ul.products { list-style: none; margin: 0; padding: 0; }
.woocommerce a.button,
.woocommerce button.button,
.woocommerce input.button,
.woocommerce #respond input#submit {
    background: var(--brand-primary, #643B81);
    color: var(--brand-on-primary, #fff);
    border-radius: var(--radius-md, 8px);
    font-family: inherit;
    font-weight: 600;
}
.woocommerce a.button:hover,
.woocommerce button.button:hover,
.woocommerce input.button:hover { background: var(--brand-600, #55326e); color: #fff; }
.woocommerce .price { color: var(--brand-700, #46295a); font-weight: 600; }

/* Nagłówek stron tekstowych (regulamin, polityka) — sekcje same go nie dają. */
.in-sec.in-art-head { padding-bottom: 0; }
.in-sec.in-art-head h1 { margin-bottom: 0; }

/* Adres e-mail w wąskiej szpalcie kontaktu łamał się w środku domeny
   („…numeroterapii.p / l"). Łamiemy tylko wtedy, gdy naprawdę nie mieści się
   w kolumnie, i po znakach, a nie w losowym miejscu. */
.in-ct-item-v a { overflow-wrap: anywhere; }

/* --- widżet rezerwacji Amelii -------------------------------------------
   Amelia v2 to aplikacja Vue (Element Plus) doklejająca własne style z paczki
   JS — część kolorów bierze z ustawień wtyczki (te przestawiliśmy na barwy
   marki), ale przyciski zostają na domyślnej zieleni. Nadpisujemy je tutaj.
   `!important` jest tu świadome: przebijamy style trzeciej strony wstrzykiwane
   po naszym arkuszu.

   ⚠️ To rozwiązanie TYMCZASOWE — razem z wymianą Amelii na własną rezerwację
   ten blok znika. */
#amelia-v2-booking .el-button--primary,
#amelia-v2-booking button[class*="--primary"],
#amelia-v2-booking .am-fs__footer-btn--next,
#amelia-v2-booking .am-button--primary {
    background: var(--brand-primary, #643B81) !important;
    border-color: var(--brand-primary, #643B81) !important;
    color: #fff !important;
    border-radius: var(--radius-pill, 9999px) !important;
    font-family: inherit !important;
    font-weight: 600 !important;
}
#amelia-v2-booking .el-button--primary:hover,
#amelia-v2-booking button[class*="--primary"]:hover {
    background: var(--brand-600, #55326e) !important;
    border-color: var(--brand-600, #55326e) !important;
}
/* Ramka panelu — dopasowana do kart prototypu, bez cienia Amelii. */
#amelia-v2-booking .am-fs,
#amelia-v2-booking .am-fs__wrapper {
    border-radius: var(--radius-xl, 20px) !important;
    font-family: inherit !important;
}
#amelia-v2-booking { font-family: var(--font-body, 'Source Sans Pro', sans-serif); }

/* --- rezerwacja i panel numeroterapeutki --------------------------------
   Prototyp nie ma tych ekranów (jego formularz rezerwacji tylko udaje
   wysyłkę), więc style pisane ręcznie — w kształtach reszty serwisu. */
.in-rez select { width: 100%; }
.in-rez-info { font-size: 13px; color: var(--color-text-muted, #413B4D); margin-top: 6px; }

.in-panel-kpis { margin: 0 0 34px; }
.in-panel-lista { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.in-panel-poz {
    display: flex; align-items: center; justify-content: space-between; gap: 14px;
    padding: 12px 16px;
    background: var(--in-surface, #fff);
    border: 1px solid var(--color-border, #C6C4D8);
    border-radius: var(--radius-md, 8px);
    font-size: 15px;
}
.in-panel-poz.is-zajety { background: var(--brand-50, #f3eff5); border-color: var(--brand-200, #d1c4d9); }
.in-panel-termin { font-weight: 600; }
.in-panel-stan {
    font-size: 12px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
    color: var(--brand-primary, #643B81);
}
.in-panel-usun {
    border: 1px solid rgba(11,18,32,.22); background: transparent;
    border-radius: var(--radius-pill, 9999px);
    padding: 6px 16px; font: inherit; font-size: 13px; cursor: pointer;
}
.in-panel-usun:hover { border-color: #b3261e; color: #b3261e; }

/* Przycisk w trakcie dodawania do koszyka — bez migania i bez podwójnych klików. */
/* Przycisk w trakcie dodawania do koszyka.
   ————————————————————————————————————————————————————————————
   Kręci się WYŁĄCZNIE kółko po prawej — podpis („Dodaj do koszyka") zostaje
   na miejscu. Wcześniej chowaliśmy cały napis i przycisk na moment robił się
   pustą pigułką; wyglądało to jak zawieszenie, a nie jak ładowanie.

   Strzałka bywa dorysowana na dwa sposoby: pseudoelementem `::after`
   (większość przycisków, patrz komponenty.css) albo elementem
   `.in-hero-arrow` w środku. Obsługujemy oba.
   `pointer-events` zostawiamy zablokowane, żeby drugi klik nie dorzucił
   pozycji jeszcze raz. */
.in-btn.is-laduje,
.in-btn-ghost.is-laduje,
.woocommerce a.button.is-laduje,
.woocommerce button.button.is-laduje { pointer-events: none; }

/* 1) strzałka z pseudoelementu — podmieniamy grafikę i kręcimy kółkiem */
.in-btn.is-laduje::after,
.in-btn-ghost.is-laduje::after {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23643B81' stroke-width='2.4' stroke-linecap='round'%3E%3Cpath d='M12 3.5a8.5 8.5 0 1 1-6.01 2.49'/%3E%3C/svg%3E") !important;
    background-size: 19px;
    animation: in-obrot .7s linear infinite;
    /* 19.08.2026: reset strzałki był tu zapisany z flagą ważności, przez co
       wygrywał z animacją i spinner zastygał na pierwszej klatce.
       Teraz zwykła deklaracja — animacja może nadpisać obrót. */
    transform: rotate(0deg);
}
.in-btn-ghost.is-laduje::after { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='2.4' stroke-linecap='round'%3E%3Cpath d='M12 3.5a8.5 8.5 0 1 1-6.01 2.49'/%3E%3C/svg%3E") !important; }

/* 2) strzałka jako element w środku (.in-hero-arrow)
   Kółko rysujemy maską na `currentColor`, a nie gotową grafiką: ta sama
   plakietka bywa granatowa z białą strzałką (hero) i biała z fioletową
   (jasny wariant hero), więc wpisany na sztywno kolor raz byłby niewidoczny. */
.is-laduje .in-hero-arrow > svg { display: none; }
.is-laduje .in-hero-arrow::after {
    content: "";
    width: 20px;
    height: 20px;
    background: currentColor;
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round'%3E%3Cpath d='M12 3.5a8.5 8.5 0 1 1-6.01 2.49'/%3E%3C/svg%3E") center / 20px no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round'%3E%3Cpath d='M12 3.5a8.5 8.5 0 1 1-6.01 2.49'/%3E%3C/svg%3E") center / 20px no-repeat;
    animation: in-obrot .7s linear infinite;
}

/* 3) przyciski Woo bez żadnej strzałki — kółko dostawiamy z boku podpisu */
.woocommerce a.button.is-laduje,
.woocommerce button.button.is-laduje { position: relative; padding-right: 46px; }
.woocommerce a.button.is-laduje::after,
.woocommerce button.button.is-laduje::after {
    content: "";
    position: absolute;
    top: 50%;
    right: 16px;
    width: 18px;
    height: 18px;
    margin-top: -9px;
    background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='2.4' stroke-linecap='round'%3E%3Cpath d='M12 3.5a8.5 8.5 0 1 1-6.01 2.49'/%3E%3C/svg%3E") center / 18px no-repeat;
    animation: in-obrot .7s linear infinite;
}

@keyframes in-obrot { to { transform: rotate(360deg); } }

/* Przy wyłączonych animacjach kółko stoi — sam podmieniony znak wystarczy. */
@media (prefers-reduced-motion: reduce) {
    .is-laduje::after,
    .is-laduje .in-hero-arrow::after { animation: none; }
}

/* Wyprzedany wariant — kształt przycisku, ale wyraźnie nieaktywny.
   Wygląd siedzi w JEDNYM miejscu, przy karcie cennika (szukaj `--cta-base`);
   tutaj zostaje samo zachowanie. */
.in-btn--brak {
    pointer-events: none;
}

/* Powód nieudanego dodania do koszyka — przy przycisku, nie na innej stronie. */
.in-koszyk-blad {
    margin: 10px 0 0;
    font-size: 13px;
    line-height: 1.5;
    color: #b3261e;
}

/* Zgoda RODO i przycisk wysyłki w siatce formularza.
   `.in-form-g` to grid 1fr 1fr — bez rozciągnięcia na obie kolumny zgoda
   i przycisk lądowały obok siebie w sąsiednich komórkach, a przycisk
   (inline-flex + promień pigułki) rozdymał się na całą komórkę w elipsę
   nachodzącą na tekst zgody. */
.in-form-g > .in-chk,
.in-form-g > button,
.in-form-g > .in-btn,
.in-form-g > .in-rez-info,
.in-form-g > .in-koszyk-blad { grid-column: 1 / -1; }

.in-form-g > button,
.in-form-g > .in-btn { justify-self: start; width: auto; }

/* ——— Krok wyboru numeroterapeutki w kreatorze rezerwacji ————————————————
   Pokazywany tylko przy wariantach, które nie wskazują jednej prowadzącej.
   Kafelki celowo dziedziczą wygląd .in-cal-chip (godziny), żeby oba kroki
   czytały się jako jeden kreator, a nie dwa różne komponenty.
   Uwaga: to plik pisany ręcznie — komponenty.css jest generowany z prototypu
   przez tools/wytnij-css.py i zmiany w nim zniknęłyby przy kolejnym buildzie. */
.in-rez-osoba[hidden] { display: none; }
.in-rez-osoby-lista { margin-top: 10px; }

.in-rez-osoba-chip {
    display: inline-flex; flex-direction: column; align-items: flex-start; gap: 2px;
    padding: 10px 18px; line-height: 1.3; text-align: left;
}
.in-rez-osoba-chip small {
    font-size: 12px; opacity: .68; font-weight: 400;
}
.in-rez-osoba-chip.is-on small { opacity: .85; }

.in-rez-osoba-hint { margin-top: 10px; }
.in-rez-osoba-hint[hidden] { display: none; }

/* Próba wysłania bez wybranej osoby — kalendarz jest wtedy schowany, więc
   komunikat spod niego byłby niewidoczny i formularz „nic by nie robił". */
.in-rez-osoba.is-blad .in-rez-osoby-lista {
    outline: 2px solid var(--brand-primary, #643B81); outline-offset: 6px; border-radius: 12px;
}
.in-rez-osoba.is-blad .in-rez-osoba-hint { color: var(--brand-primary, #643B81); font-weight: 600; }

/* ——— Paginacja bloga ————————————————————————————————————————————————
   W prototypie numery stron to <button>, u nas muszą być <a href> (bez linków
   Google nie zobaczy starszych wpisów). Linki dziedziczą globalne podkreślenie,
   którego przyciski nie miały — zdejmujemy je, żeby wyglądało jak w makiecie. */
.in-pagination a,
.in-pagination a:hover,
.in-pagination a:focus { text-decoration: none; }
.in-pagination .in-page-num,
.in-pagination .in-page-nav {
    display: inline-flex; align-items: center; justify-content: center;
}
.in-page-dots { color: var(--color-muted, #6b6585); padding: 0 4px; }

/* Kotwica listy wpisów — nagłówek strony jest przyklejony, więc bez zapasu
   sekcja wskoczyłaby pod niego i „Najnowsze wpisy" byłoby zasłonięte. */
#wpisy { scroll-margin-top: 110px; }

/* ——— Wyszukiwarka w nagłówku ————————————————————————————————————————— */
.in-szukaj { position: relative; display: inline-flex; align-items: center; }
/* Pole rozwija się POD paskiem nagłówka, nie na nim. Wariant „na pasku" zasłaniał
   pozycje menu („Kontakt", przycisk konsultacji) — przy tej szerokości nawigacji
   nie ma tam miejsca na pole 210 px. */
.in-szukaj-form {
    position: absolute; right: 0; top: calc(100% + 14px); transform: translateY(-6px);
    transform-origin: top right; display: flex; align-items: center; gap: 6px;
    background: #fff; border: 1px solid var(--color-border, #C6C4D8); border-radius: 999px;
    padding: 4px 4px 4px 16px; box-shadow: 0 10px 26px rgba(70, 63, 103, .14);
    opacity: 0; visibility: hidden; pointer-events: none;
    /* `visibility` NIE bierze udziału w animacji — przełącza się natychmiast.
       Inaczej pole przez ~180 ms jest jeszcze ukryte, a focus() na ukrytym
       elemencie nie działa i kursor nie wskakuje w pole po kliknięciu lupy. */
    transition: opacity .18s ease, transform .18s ease;
}
.in-szukaj.is-otwarte .in-szukaj-form {
    opacity: 1; visibility: visible; pointer-events: auto; transform: translateY(0);
}
.in-szukaj-form input[type="search"] {
    width: 210px; border: 0; outline: 0; background: transparent; font: inherit; font-size: 15px;
    padding: 6px 0; color: var(--color-text, #0B1220);
}
.in-szukaj-go {
    border: 0; border-radius: 999px; padding: 8px 16px; cursor: pointer;
    background: var(--brand-primary, #643B81); color: #fff; font: inherit; font-weight: 700; font-size: 14px;
}
.in-szukaj-go:hover { filter: brightness(1.08); }

/* Na wąskich ekranach pole nie zmieści się obok ikon — rozwijamy je pod nagłówkiem. */
@media (max-width: 720px) {
    .in-szukaj-form { position: fixed; left: 12px; right: 12px; top: 84px; transform: translateY(-6px); }
    .in-szukaj.is-otwarte .in-szukaj-form { transform: none; }
    .in-szukaj-form input[type="search"] { width: 100%; }
}

/* ——— Wyszukiwarka na liście wpisów ——————————————————————————————————— */
.in-posts-szukaj { display: flex; gap: 10px; margin: 0 0 34px; max-width: 520px; }
.in-posts-szukaj input[type="search"] {
    flex: 1 1 auto; min-width: 0; padding: 12px 18px; font: inherit; font-size: 15px;
    border: 1px solid var(--color-border, #C6C4D8); border-radius: 999px; background: #fff;
}
.in-posts-szukaj input[type="search"]:focus { outline: 2px solid var(--brand-primary, #643B81); outline-offset: 2px; }

/* ——— Landing e-booka / webinaru ————————————————————————————————————————
   Strona kampanijna: jeden cel — zostawić adres. Dlatego układ jest prosty
   (okładka + formularz obok siebie), a reszta sekcji tylko podpiera decyzję. */
.in-ebook-head { max-width: 760px; margin: 0 auto 40px; text-align: center; }
.in-ebook-h1 { font-family: 'DM Serif Display', Georgia, serif; font-size: clamp(30px, 4.2vw, 52px); line-height: 1.12; margin: 0 0 14px; }
/* Okładka jest pionowa i wychodzi wyższa od karty zapisu, więc przy
   `align-items: start` zwisała pod nią o ponad 100 px. Wyrównujemy kolumny
   w pionie i ograniczamy wysokość okładki, żeby obie strony kończyły się
   mniej więcej równo niezależnie od tego, ile pól ma formularz. */
.in-ebook-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 48px; align-items: center; }
/* Bez okładki druga kolumna byłaby pusta — zwężamy do jednej, wyśrodkowanej. */
.in-ebook-grid--solo { grid-template-columns: minmax(0, 620px); justify-content: center; }
.in-ebook-grid--solo .in-ebook-cechy {
    margin-top: 24px; padding-top: 20px; border-top: 1px solid var(--color-border, #C6C4D8);
}
.in-ebook-okladka { display: flex; flex-direction: column; }
.in-ebook-img {
    display: block; width: auto; max-width: 100%; max-height: 760px;
    margin-inline: auto; height: auto;
    border-radius: 18px; box-shadow: 0 26px 60px rgba(76, 71, 102, .18);
}
.in-ebook-cechy { list-style: none; padding: 0; margin: 20px 0 0; display: flex; flex-direction: column; gap: 10px; }
.in-ebook-cechy li { padding-left: 26px; position: relative; }
.in-ebook-cechy li::before { content: '✓'; position: absolute; left: 0; color: var(--brand-primary, #643B81); font-weight: 700; }
.in-ebook-zapis { background: #fff; border: 1px solid var(--color-border, #C6C4D8); border-radius: 20px; padding: 28px; }
.in-ebook-zapis-t { font-weight: 700; font-size: 18px; margin: 0 0 14px; }
.in-ebook-autor-grid { display: grid; grid-template-columns: 260px 1fr; gap: 36px; align-items: start; }
.in-ebook-autor-foto { width: 100%; height: auto; border-radius: 18px; }
.in-ebook-cta { text-align: center; }

@media (max-width: 860px) {
    .in-ebook-grid, .in-ebook-autor-grid { grid-template-columns: 1fr; gap: 28px; }
    .in-ebook-autor-foto { max-width: 220px; }
}
.in-ebook-lista { display: grid; grid-template-columns: repeat(2, 1fr); gap: 20px; margin-top: 26px; }
.in-ebook-korzysc { background: #fff; border: 1px solid var(--color-border, #C6C4D8); border-radius: 16px; padding: 22px; }
.in-ebook-korzysc h3 { margin: 0 0 8px;  }
.in-ebook-korzysc p { margin: 0; }
@media (max-width: 860px) { .in-ebook-lista { grid-template-columns: 1fr; } }

/* ——— Pokój webinarowy ——————————————————————————————————————————————————
   Film i czat obok siebie; czat tylko przy transmisji z YouTube. */
.in-webinar-head { max-width: 860px; margin: 0 auto 36px; text-align: center; }
.in-webinar-head h1 { font-family: 'DM Serif Display', Georgia, serif;  line-height: 1.12; margin: 0 0 14px; }
.in-webinar-grid { display: grid; grid-template-columns: 2fr 1fr; gap: 24px; align-items: stretch; }
.in-webinar-grid--solo { grid-template-columns: minmax(0, 960px); justify-content: center; }
.in-webinar-film { position: relative; aspect-ratio: 16 / 9; border-radius: 20px; overflow: hidden; background: #0f0d18; box-shadow: 0 26px 60px rgba(76, 71, 102, .18); }
.in-webinar-film iframe,
.in-webinar-film video { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.in-webinar-pusto { position: absolute; inset: 0; display: grid; place-items: center; padding: 24px; text-align: center; color: #fff; }
.in-webinar-czat { border-radius: 20px; overflow: hidden; background: #fff; border: 1px solid var(--color-border, #C6C4D8); min-height: 420px; }
.in-webinar-czat iframe { width: 100%; height: 100%; min-height: 420px; border: 0; display: block; }
.in-webinar-akcja { margin: 28px 0 0; text-align: center; }

@media (max-width: 900px) {
    .in-webinar-grid { grid-template-columns: 1fr; }
    .in-webinar-czat, .in-webinar-czat iframe { min-height: 340px; }
}

/* ——— pasek CTA: dwa przyciski ————————————————————————————————————————
   Sekcje CTA prowadzą do dwóch dróg naraz — sesji z numeroterapeutką i
   konsultacji z Olgą — bo jeden przycisk wybierał za klientkę, i to zwykle
   drożej.

   ⚠️ Drugi przycisk NIE ma własnej geometrii: bierze ją z `.in-btn-ghost`
   i nosi tę samą ikonę-kółko co pierwszy. Własne paddingi dawały dwa przyciski
   różnej wysokości, jeden ze strzałką, drugi bez — wyglądało to jak usterka.
   Tutaj zostaje wyłącznie kolor pod ciemny gradient. */
.in-cta-btns { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; justify-content: center; }
.in-sec.in-cta .in-cta-btn2,
.in-sec#cta .in-cta-btn2,
.in-cb .in-cta-btn2 {
    --cta-base: transparent;
    --cta-fill: var(--brand-accent, #67B6C0);
    --cta-hover-text: #fff;
    color: #fff;
    border: 1px solid rgba(255, 255, 255, .55);
}
.in-sec.in-cta .in-cta-btn2:is(:hover, :focus-visible),
.in-sec#cta .in-cta-btn2:is(:hover, :focus-visible),
.in-cb .in-cta-btn2:is(:hover, :focus-visible) { border-color: #fff; color: #fff; }
.in-cta-btn2 .in-cta-ic { border-color: rgba(255, 255, 255, .55); color: #fff; }

/* ⚠️ Geometrię bierzemy z przycisku GŁÓWNEGO w tej samej sekcji, nie z bazowego
   `.in-btn-ghost`: pigułka z kółkiem ma padding 8px z prawej (kółko dokleja się
   do krawędzi) i odstęp 14px, a ghost miał symetryczne 14/26. Efekt: dwa
   przyciski obok siebie różniły się wysokością o 14 px. */
.in-sec.in-cta .in-cta-btn2,
.in-sec#cta .in-cta-btn2,
.in-cb .in-cta-btn2 {
    padding: 8px 8px 8px 24px;
    gap: 14px;
    line-height: normal;
}

/* ——— pasek CTA: dwa przyciski ————————————————————————————————————————
   Sekcje CTA prowadzą teraz do dwóch dróg naraz — sesji z numeroterapeutką
   i konsultacji z Olgą — bo jeden przycisk wybierał za klientkę, i to zwykle
   drożej. Drugi jest obrysowany, żeby pierwszy pozostał główny. */
.in-cta-btns { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; justify-content: center; }
.in-cta-btn2 {
    display: inline-flex; align-items: center; justify-content: center;
    padding: 14px 26px;
    font-weight: 600; line-height: 1;
    color: #fff; text-decoration: none;
    background: rgba(255, 255, 255, .08);
    border: 1px solid rgba(255, 255, 255, .55);
    border-radius: var(--radius-pill, 9999px);
    transition: background .15s ease, border-color .15s ease;
}
.in-cta-btn2:hover { background: rgba(255, 255, 255, .18); border-color: #fff; color: #fff; }
.in-cta-btn2:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }

/* ——— szerokość graniczna strony ————————————————————————————————————————
   Prototyp był robiony pod 1440 px i szedł na pełną szerokość okna
   (`.in-wrap { max-width: none }`). Na monitorach 1920+ kolumna tekstu robiła
   się nieczytelnie szeroka, a siatki produktów rozjeżdżały się na pół ekranu.
   Ustawiamy jedną granicę dla całego serwisu; poniżej niej wszystko zachowuje
   się jak dotąd, powyżej treść zostaje wyśrodkowana i po bokach robi się margines.

   Dwa różne wzorce, bo kontenery inaczej trzymają gutter:
   • `.in-wrap` ma gutter w PADDINGU → granicę liczymy razem z nim,
   • `.in-pill` i bloki stopki mają gutter w MARGINESIE → używamy `width: min()`,
     żeby zachować odstęp od krawędzi na wąskich ekranach. */
:root { --in-strona: 1500px; }

.in-wrap,
.in-cta-inner,
.in-cb-inner {
    max-width: calc(var(--in-strona) + 2 * var(--in-hgut, 72px));
    margin-inline: auto;
}

.in-pill,
.in-ftr-top,
.in-ftr-grid,
.in-ftr-bot {
    width: min(100% - 2 * var(--in-hgut, 72px), var(--in-strona));
    margin-inline: auto;
}

/* Panel stopki jest kafelkiem z gradientem — ograniczamy sam kafelek, nie treść. */
.in-ftr-panel { max-width: calc(var(--in-strona) + 2 * var(--in-hgut, 72px)); margin-inline: auto; }

/* ——— galeria: jadący pas zdjęć ————————————————————————————————————————
   Jak na produkcji: tor sunie w lewo bez końca, krawędzie wygaszone maską,
   pas staje po najechaniu. Tor zawiera DWIE kopie listy, więc przesunięcie
   o -50% wraca dokładnie do punktu wyjścia — pętla nie ma szwu.

   Przy `prefers-reduced-motion` animacja w ogóle nie startuje i zostaje zwykły
   pas do przewinięcia; ruch bez możliwości zatrzymania jest męczący, a części
   osób realnie szkodzi. */
.in-galeria .in-gal-pas {
    margin-top: 28px;
    overflow: hidden;
    -webkit-mask-image: linear-gradient(to right, transparent 0%, #000 7%, #000 93%, transparent 100%);
            mask-image: linear-gradient(to right, transparent 0%, #000 7%, #000 93%, transparent 100%);
}
.in-galeria .in-gal-tor {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    gap: 20px;
    width: max-content;
    animation: in-gal-jedzie 48s linear infinite;
}
.in-galeria .in-gal-pas:hover .in-gal-tor,
.in-galeria .in-gal-pas:focus-within .in-gal-tor { animation-play-state: paused; }

.in-galeria .in-gal-tor > li { flex: 0 0 auto; width: 260px; }
.in-galeria .in-gal-tor img {
    display: block;
    width: 100%;
    height: 300px;
    object-fit: cover;
    border-radius: var(--radius-xl, 20px);
    background: var(--brand-50, #f3eff5);
}

@keyframes in-gal-jedzie {
    from { transform: translateX(0); }
    to   { transform: translateX(-50%); }
}

@media (max-width: 768px) {
    .in-galeria .in-gal-tor > li { width: 200px; }
    .in-galeria .in-gal-tor img { height: 230px; }
}
@media (max-width: 480px) {
    .in-galeria .in-gal-tor > li { width: 160px; }
    .in-galeria .in-gal-tor img { height: 190px; }
}

@media (prefers-reduced-motion: reduce) {
    .in-galeria .in-gal-pas { overflow-x: auto; }
    .in-galeria .in-gal-tor { animation: none; }
}

/* ——— wideo w splicie — kadr jak na str. gł. ————————————————————————— */
.in-split-wideo {
    justify-self: center;
    width: min(100%, 340px);
    position: relative;
    isolation: isolate;
}
.in-split-wideo::before {
    content: ""; position: absolute; z-index: -1;
    left: -18px; right: 18px; top: 18px; bottom: -18px;
    border-radius: 44px;
    background: rgba(100,59,129,.14);
}
.in-split-wideo video {
    display: block;
    width: 100%;
    aspect-ratio: 9 / 16;
    object-fit: cover;
    background: #0B1220;
    border-radius: 44px;
    box-shadow: 0 26px 60px rgba(11,18,32,.18);
    -webkit-mask-image: -webkit-radial-gradient(#fff, #000);
}
@media (max-width: 900px) {
    .in-split-wideo { width: min(100%, 300px); }
}

/* ——— wideo ——————————————————————————————————————————————————————————— */
.in-wideo-ramka {
    margin-top: 28px;
    border-radius: var(--radius-xl, 20px);
    overflow: hidden;
    box-shadow: 0 26px 60px rgba(76, 71, 102, .18);
    aspect-ratio: 16 / 9;
}
.in-wideo-self {
    position: relative;
}
.in-wideo-plakat {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    z-index: 1;
}
.in-wideo-plakat[hidden] { display: none; }
.in-wideo-ramka video {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Podglad filmu z YouTube. Iframe wchodzi dopiero po klikniecu (patrz
   template-parts/sekcje/wideo.php), wiec do tego czasu jest tu tylko obrazek
   i przycisk — zero skryptow Google'a. */
.in-yt {
    position: relative;
    aspect-ratio: 16 / 9;
    cursor: pointer;
}
.in-yt-plakat,
.in-yt iframe {
    position: absolute;
    inset: 0;
    display: block;
    width: 100%;
    height: 100%;
    border: 0;
}
.in-yt-plakat { object-fit: cover; }
.in-yt-play {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    width: 100%;
    height: 100%;
    padding: 0;
    background: none;
    border: 0;
    cursor: pointer;
}
.in-yt-play svg { filter: drop-shadow(0 6px 18px rgba(0, 0, 0, .35)); }
.in-yt-play-tlo {
    fill: #1e1a2b;
    fill-opacity: .82;
    transition: fill .18s ease, fill-opacity .18s ease;
}
.in-yt-play:hover .in-yt-play-tlo,
.in-yt-play:focus-visible .in-yt-play-tlo {
    fill: #cc0000;
    fill-opacity: 1;
}
.in-yt-play:focus-visible { outline: 3px solid #fff; outline-offset: -6px; }

/* ——— oferta dla grup: karta + okno z formularzem ————————————————————— */
.in-ofgrup-karta {
    background: #fff;
    border: 1px solid var(--color-border, #C6C4D8);
    border-radius: var(--radius-xl, 20px);
    padding: 32px 34px;
    max-width: 720px;
}
.in-ofgrup-lista { list-style: none; margin: 18px 0 24px; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.in-ofgrup-lista li { padding-left: 26px; position: relative; }
.in-ofgrup-lista li::before {
    content: '✓'; position: absolute; left: 0;
    color: var(--brand-primary, #643B81); font-weight: 700;
}

.in-ofgrup-okno {
    width: min(100% - 32px, 620px);
    max-height: 88vh;
    overflow-y: auto;
    border: 0;
    border-radius: var(--radius-xl, 20px);
    padding: 28px 30px 32px;
    background: #fff;
    color: var(--color-text, #0B1220);
}
.in-ofgrup-okno::backdrop { background: rgba(15, 13, 24, .55); }
.in-ofgrup-okno h2 { margin: 0 0 10px;  line-height: 1.2; }
.in-ofgrup-okno .in-lead { margin: 0 0 22px; }
.in-ofgrup-x { display: flex; justify-content: flex-end; margin: -8px -8px 0 0; }
.in-ofgrup-x .in-ic-btn { width: 38px; height: 38px; }

.in-ofgrup-form .in-form-g { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
@media (max-width: 560px) { .in-ofgrup-form .in-form-g { grid-template-columns: 1fr; } }
.in-ofgrup-form .in-f-w { margin-bottom: 16px; }
.in-ofgrup-grupa { border: 0; padding: 0; margin: 0 0 16px; }
.in-ofgrup-grupa legend {
    padding: 0; margin: 0 0 8px;
    font-size: 13px; font-weight: 600; letter-spacing: .02em;
    color: var(--color-text-muted, #413B4D);
}
.in-ofgrup-blad { border-color: rgba(180, 38, 30, .55); margin: 0 0 16px; }
.in-ofgrup-ok { margin-top: 8px; }
/* Etykiety przy radio dziedziczyły wersaliki po globalnym stylu `label`
   w formularzach — zdania w kapitalikach czytają się jak krzyk. */
.in-ofgrup-okno .in-chk,
.in-ofgrup-okno .in-chk span { text-transform: none; letter-spacing: 0; font-size: 15px; font-weight: 400; }
.in-ofgrup-grupa .in-chk { margin: 0 0 6px; }
.in-ofgrup-grupa .in-chk input { accent-color: var(--brand-primary, #643B81); }

/* ——— pas CTA z JEDNĄ kartą ceny ————————————————————————————————————————
   Wariant „karty" jest zbudowany pod dwie karty obok siebie. Przy jednej
   (certyfikacja gry) karta zostawała na pół szerokości kolumny, a przycisk
   wpadał pod nią z lewej — patrz `in-cta--jedna` w cta.php. */
.in-cta--jedna .in-cta-side { grid-template-columns: minmax(0, 1fr); justify-items: stretch; }
.in-cta--jedna .in-cta-side > .in-btn { justify-self: center; }
.in-cta--jedna .in-cta-inner { align-items: center; }
/* Nagłówek ma tu 13ch i łamał się na cztery linijki przy dłuższym haśle. */
.in-cta--jedna h2 { max-width: 22ch; }

/* ——— galeria na pełną szerokość ekranu —————————————————————————————————
   Pas ma dotykać obu krawędzi okna, żeby było widać, że jedzie dalej —
   ograniczenie 1500 px dotyczy kolumny treści, nie tego pasa. */
.in-galeria .in-gal-pas {
    width: 100vw;
    max-width: 100vw;
    margin-left: calc(50% - 50vw);
    margin-right: calc(50% - 50vw);
}
/* Nagłówek w tym wariancie stoi w węższej kolumnie (.95fr) i przy dużym
   stopniu pisma łamał się na pięć linijek, wchodząc pod kartę z ceną. */
.in-cta--jedna h2 { max-width: 20ch; }

/* ---------- Panel klienta ---------- */
.in-pk-h3 { margin: 30px 0 12px; }
.in-pk-lista { list-style: none; padding: 0; margin: 0 0 24px; display: grid; gap: 12px; }
.in-pk-it {
	display: flex; flex-wrap: wrap; gap: 12px 20px; align-items: center;
	padding: 16px 20px; border-radius: 14px; background: #fff;
	border: 1px solid rgba(76,71,102,.12);
}
.in-pk-kiedy { font-weight: 700; min-width: 190px; font-variant-numeric: tabular-nums; }
.in-pk-tresc { flex: 1 1 220px; }
.in-pk-kto { display: block; font-size: 14px; opacity: .7; }
.in-btn--maly { padding: 9px 18px; font-size: 14px; }
.in-pk-stopka { font-size: 14px; opacity: .8; margin-top: 26px; }

/* ---------- Strona 404 ---------- */
.in-404 { text-align: center; padding-bottom: 8px; }
.in-404-kod { letter-spacing: .28em; }
.in-404 .in-lead { max-width: 58ch; margin-left: auto; margin-right: auto; }
.in-404-sekcja { padding-top: 8px; }
.in-404-szukaj { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; margin: 26px 0 4px; }
.in-404-szukaj input {
	flex: 1 1 320px; max-width: 420px; padding: 14px 18px; border-radius: 999px;
	border: 1px solid rgba(76,71,102,.22); font: inherit; background: #fff;
}
.in-404-szukaj input:focus-visible { outline: 2px solid #6b5b95; outline-offset: 2px; }

.in-404-naglowek { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; flex-wrap: wrap; margin-bottom: 18px; }
.in-404-naglowek h2 {  margin: 0; }
.in-404-wiecej { font-size: 14px; white-space: nowrap; }

/* karty bloga */
.in-404-wpisy { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 22px; }
.in-404-wpis a { display: block; text-decoration: none; color: inherit; }
.in-404-wpis-foto {
	aspect-ratio: 16 / 10; border-radius: 16px; overflow: hidden; background: #f3f1f7;
	margin-bottom: 12px; box-shadow: 0 14px 34px -24px rgba(76,71,102,.4);
}
.in-404-wpis-foto img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .3s ease; }
.in-404-wpis a:hover .in-404-wpis-foto img { transform: scale(1.04); }
.in-404-data { font-size: 12px; letter-spacing: .12em; text-transform: uppercase; opacity: .6; }
.in-404-wpis h3 {  line-height: 1.35; margin: 6px 0 0; }

.in-404-stopka-blok { text-align: center; }
.in-404-stopka-tytul { font-size: 14px; opacity: .7; margin-bottom: 12px; }
.in-404-skroty { list-style: none; padding: 0; margin: 0; display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; }
.in-404-skroty a {
	display: inline-block; padding: 9px 18px; border-radius: 999px; font-size: 14px;
	border: 1px solid rgba(76,71,102,.18); text-decoration: none; color: inherit; background: #fff;
}
.in-404-skroty a:hover { border-color: rgba(76,71,102,.4); }

@media (prefers-reduced-motion: reduce) {
	.in-kar-foto img, .in-404-wpis-foto img { transition: none; }
	.in-kar-karta a:hover .in-kar-foto img, .in-404-wpis a:hover .in-404-wpis-foto img { transform: none; }
	.in-kar { scroll-behavior: auto; }
}

/* ——— Stany ładowania w koszyku (19.08.2026) ———
   WooCommerce nakłada na te elementy własny znak z fontu `WooCommerce`,
   animację `spin` i `opacity: .25`. Selektory Woo mają tę samą specyficzność
   co nasze, więc bez `!important` część jego deklaracji przechodzi i spinner
   stoi w miejscu. Stąd twarde nadpisania poniżej. */

body .woocommerce a.button.loading,
body .woocommerce button.button.loading,
body .woocommerce input.button.loading {
    opacity: 1 !important;
    padding-right: 46px !important;
    pointer-events: none;
}
body .woocommerce a.button.loading::after,
body .woocommerce button.button.loading::after,
body .woocommerce input.button.loading::after {
    content: "" !important;
    font-family: inherit !important;
    position: absolute !important;
    top: 50% !important;
    right: 16px !important;
    width: 18px; height: 18px; margin-top: -9px;
    background: currentColor;
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round'%3E%3Cpath d='M12 3.5a8.5 8.5 0 1 1-6.01 2.49'/%3E%3C/svg%3E") center / 18px no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round'%3E%3Cpath d='M12 3.5a8.5 8.5 0 1 1-6.01 2.49'/%3E%3C/svg%3E") center / 18px no-repeat;
    animation: in-obrot .7s linear infinite !important;
}

/* Usuwanie z mini-koszyka: spinner DOKŁADNIE w miejscu „×", nie na środku panelu.
   Nakładki blockUI Woo (ciemnienie kafelka) wyłączamy. */
.widget_shopping_cart_content .blockUI,
.widget_shopping_cart_content .blockOverlay,
.in-cart .blockUI,
.in-cart .blockOverlay { display: none !important; }

body a.remove.in-usuwa,
body a.remove_from_cart_button.in-usuwa {
    pointer-events: none;
    color: transparent !important;
    font-size: 0 !important;          /* gasi znak „×" z fontu Woo */
    position: relative;
}
body a.remove.in-usuwa::before { content: none !important; }
body a.remove.in-usuwa::after,
body a.remove_from_cart_button.in-usuwa::after {
    content: "" !important;
    position: absolute !important;
    top: 50% !important;
    left: 50% !important;
    width: 15px; height: 15px;
    margin: -7.5px 0 0 -7.5px;        /* środek SAMEGO przycisku, nie kontenera */
    background: var(--brand-primary, #643B81);
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.6' stroke-linecap='round'%3E%3Cpath d='M12 3.5a8.5 8.5 0 1 1-6.01 2.49'/%3E%3C/svg%3E") center / 15px no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.6' stroke-linecap='round'%3E%3Cpath d='M12 3.5a8.5 8.5 0 1 1-6.01 2.49'/%3E%3C/svg%3E") center / 15px no-repeat;
    animation: in-obrot .7s linear infinite !important;
}

/* ── Pasek liczb w hero profilu (jasne tło) ─────────────────────────────────
   `.in-hero-kpis` powstał dla fioletowego hero, więc ma biały tekst i
   `grid-column: 1`. W wariancie „profil" liczby stoją WEWNĄTRZ `.in-hero-txt`,
   czyli poza siatką `.in-wrap` — przypisanie do kolumny trzeba zdjąć, inaczej
   flexbox rodzica dostaje element z nieużywaną deklaracją gridu.
   20.08.2026 */
.in-hero-foto .in-hero-kpis {
    grid-column: auto;
    /* Bez kreski nad liczbami. W fioletowym hero `border-top` rozdziela dwa
       bloki na jednym tle i ma sens; tutaj liczby stoją tuż pod przyciskami
       i linia ciągnąca się przez pół szerokości wygląda na zabłąkaną. */
    border-top: 0;
    padding-top: 26px;
    gap: 18px clamp(28px, 3vw, 48px);
}
.in-hero-foto .in-hero-kpis b {
    color: var(--brand-primary, #643B81);
    font-size: clamp(28px, 2.1vw, 38px);
}
.in-hero-foto .in-hero-kpis span { color: var(--color-text-muted, #413B4D); }

/* ── Kafelki produktowe (.in-pr) — wersja wspólna ──────────────────────────
   Sekcja ACF `produkty` jest dostępna na KAŻDEJ stronie, ale jej style stały
   dotąd wyłącznie w `strony/index.css`, czyli w arkuszu ładowanym tylko na
   stronie głównej. Skutek: na /olga-stepinska/ sekcja wychodziła jako goły
   tekst i szare prostokąty. Reguły są przepisane tutaj, bo `strony/*.css`
   generuje `tools/wytnij-css.py` z prototypu i ręczna zmiana tam zniknęłaby
   przy najbliższym buildzie. Na stronie głównej obie kopie są identyczne.
   20.08.2026 */
    .in-pr-grid { display: grid; grid-template-columns: repeat(3, 1fr);
                  gap: 28px; margin-top: 8px; }
    .in-pr-it { position: relative; overflow: hidden;
                display: flex; flex-direction: column; gap: 22px;
                /* Karta zostaje BIAŁA — tło serwisu to mgła #E7EDF9 i to na niej
                   karty mają się odcinać (reguła tła z 13.08). Lawendowa płyta
                   z inspiracji zlewała się z mgłą prawie do niewidoczności. */
                background: #fff; border: 1px solid transparent;
                border-radius: 28px; padding: 20px 20px 34px;
                transition: transform .3s ease, box-shadow .3s ease; }
    .in-pr-it:hover { transform: translateY(-4px); box-shadow: 0 22px 50px rgba(100,59,129,.10); }
    .in-pr-it > * { position: relative; z-index: 1; }
    /* wyróżniony kafelek = lawendowa płyta, nie ramka i nie ciemny przycisk */
    .in-pr-it--hl { background: #F2ECF8; }
    /* jeden narożnik wyraźnie większy — ten sam gest, co łuk w hero */
    .in-pr-im { position: relative; border-radius: 18px 18px 72px 18px; overflow: visible;
                background: rgba(11,18,32,.06); }
    .in-pr-im img { display: block; width: 100%; aspect-ratio: 16/10; object-fit: cover;
                    border-radius: inherit; }
    /* kółko-obrys zachodzące na lewy dolny róg kadru */
    .in-pr-im::after {
        content: ""; position: absolute; left: -14px; bottom: -22px; width: 96px; height: 96px;
        border: 1px solid rgba(100,59,129,.28); border-radius: 50%; pointer-events: none;
    }
    /* treść ma własny wcięty margines — zdjęcie idzie szerzej niż tekst,
       przez co kafelek oddycha jak w inspiracji */
    .in-pr-body { display: flex; flex-direction: column; gap: 14px; flex: 1 1 auto;
                  padding: 10px 12px 0; }
    .in-pr-eyebrow { display: flex; align-items: center; gap: 10px; margin: 0;
                     font-size: 11px; font-weight: 700; letter-spacing: .16em;
                     text-transform: uppercase; color: var(--color-text-muted, #413B4D); }
    .in-pr-eyebrow::before { content: ""; flex: none; width: 7px; height: 7px;
                             border-radius: 50%; background: var(--brand-accent, #67B6C0); }
    /* tytuł kafelka szeryfem, jak nagłówek sekcji — różni je tylko stopień */
    html body .in-pr-it h3 { font-family: var(--font-display) !important; font-weight: 400 !important;
                              line-height: 1.15; margin: 0;
                             color: var(--brand-primary, #643B81); }
    .in-pr-d { font-size: 16px; line-height: 1.65; color: var(--color-text-muted, #413B4D);
               margin: 0; flex: 1 1 auto; }
    /* CTA jako odnośnik ze strzałką — świadomie NIE .in-btn/.in-btn-ghost,
       bo tamte klasy globalna reguła zamienia w pigułkę z kółkiem */
    .in-pr-link { display: inline-flex; align-items: center; gap: 10px; margin-top: 6px;
                  font-size: 16px; font-weight: 700; text-decoration: none;
                  color: var(--brand-primary, #643B81); }
    .in-pr-link svg { width: 18px; height: 18px; transition: transform .3s ease; }
    .in-pr-it:hover .in-pr-link svg,
    .in-pr-link:is(:hover, :focus-visible) svg { transform: translateX(4px); }
    /* cały kafelek jest klikalny — nakładka odnośnika, tekst linku zostaje
       widoczny dla czytników ekranu i klawiatury */
    .in-pr-link::after { content: ""; position: absolute; inset: 0; z-index: 2; }
    @media (max-width: 980px) { .in-pr-grid { grid-template-columns: 1fr; } }

/* Etykieta nad nagłówkiem sekcji — ta sama sytuacja co wyżej: `.in-ig-eyebrow`
   drukuje `sekcje/produkty.php` i `sekcje/insight.php`, a styl siedział tylko
   w arkuszu strony głównej. 20.08.2026 */
.in-ig-eyebrow { font-size: 12px; font-weight: 700; letter-spacing: .18em; text-transform: uppercase;
                 color: var(--color-text-muted, #413B4D); margin: 0 0 20px; }

/* ── Opis na karcie osoby ──────────────────────────────────────────────────
   Zajawka biografii jest przycięta do czterech wierszy, żeby karty w rzędzie
   miały równą wysokość niezależnie od długości tekstu na profilu. Wielokropek
   dokłada `line-clamp`, a przy tekście uciętym już w PHP jest on w treści —
   jedno i drugie kończy się tym samym znakiem, więc nie podwaja się.
   20.08.2026 */
.in-person-opis {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 4;
    line-clamp: 4;
    overflow: hidden;
    margin-bottom: 4px;
}

/* ── Wyprzedany pakiet w cenniku ───────────────────────────────────────────
   Na produkcji karta wyprzedanego wariantu jest wyszarzona w całości i ma
   plakietkę u góry — samo zastąpienie przycisku napisem „Wyprzedane" ginęło
   między punktami. Kolory zbijamy filtrem `grayscale`, a nie ręcznym
   przemalowaniem każdego elementu: karta ma ich kilkanaście (ptaszki listy,
   akcent ceny, ramka) i przy każdej zmianie skóry trzeba by je gonić.
   20.08.2026 */
.in-price--brak {
    position: relative;
    filter: grayscale(1);
    /* ⚠️ Przygaszenie NIE idzie już przez `opacity` na całej karcie.
       Historia: było .62, po zgłoszeniu Bartka z 21.08 podniesione do .8, bo
       napis na przycisku przestawał być czytelny. Problem w tym, że `opacity`
       działa na wszystko naraz — im mocniej gasimy tło, tym mocniej gasimy też
       kwotę i przycisk, więc nie da się przyciemnić karty bez utraty
       czytelności.

       Teraz karta zostaje na pełnej nieprzezroczystości, a przygaszenie robimy
       WYBIÓRCZO: ciemniejsze, bardziej szare tło i wyraźnie stonowane teksty
       opisowe, przy zachowanym kontraście kwoty i przycisku. Efekt jest
       mocniejszy niż wcześniej, a nic nie znika. Bartek, 24.08.2026 */
    opacity: 1;
    box-shadow: none;
}
/* ⚠️ Tło osobno i z mocniejszym selektorem. Powierzchnię kart ustawia wspólna
   reguła `.in-card, …, .in-price:not(.in-price--hl), …`, a `:not()` liczy się
   do szczegółowości — to dwie klasy, czyli więcej niż samo `.in-price--brak`.
   Bez prefiksu sekcji tło wracało do zwykłego i karta wcale się nie ściemniała. */
.in-sec.in-pricing .in-price--brak {
    background: #E4E4E8;
    border-color: rgba(11, 18, 32, .12);
}
/* Teksty opisowe schodzą do jasnej szarości — to one budują wrażenie
   „nieaktywne", bo jest ich w karcie najwięcej. */
.in-sec.in-pricing .in-price--brak :is(.in-price-l, .in-price-o, .in-price-n) {
    color: rgba(11, 18, 32, .42);
}
.in-sec.in-pricing .in-price--brak .in-check li {
    color: rgba(11, 18, 32, .48);
}
/* Ptaszki listy gasną razem z tekstem, inaczej zostają czarne i ciągną wzrok. */
.in-price--brak .in-check li::before,
.in-price--brak .in-check svg {
    opacity: .38;
}
/* Kwota i przycisk zostają czytelne — mają mówić, czego dotyczy „wyprzedane". */
.in-price--brak .in-price-a,
.in-price--brak .in-price-c {
    color: rgba(11, 18, 32, .55);
}

/* ⚠️ 21.08.2026 — samo wyszarzenie nie wystarczało. Karta stała obok dwóch
   kolorowych i owszem, była bledsza, ale plakietka „Wyprzedane" ginęła jako
   szary napis na szarym tle, a przycisk na dole wyglądał jak zwykły, tylko
   ciemniejszy — klient próbował w niego kliknąć. Wzmacniamy trzy sygnały
   naraz: plakietka na pełnym kontraście, cena przekreślona, przycisk bez
   wypełnienia. Kolor bierzemy jako `--brak-*`, bo filtr `grayscale` na karcie
   i tak zdejmie z nich nasycenie — chodzi wyłącznie o jasność. */
.in-price--brak .in-price-brak {
    margin: 0 0 14px;
    align-self: flex-start;
    padding: 6px 14px;
    border-radius: 999px;
    /* 21.08.2026: plakietka była na PEŁNEJ czerni i wyglądała jak naklejka
       z innego serwisu — zwłaszcza że reszta karty jest wyszarzona. Teraz
       jest szara plakietka na szarej karcie: czytelna, ale nie krzyczy.
       Ciemny tekst na jasnym wypełnieniu, bo `grayscale` i tak zdejmuje
       nasycenie — liczy się wyłącznie różnica jasności. */
    background: rgba(11, 18, 32, .10);
    border: 1px solid rgba(11, 18, 32, .18);
    color: var(--color-text, #0B1220);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .16em;
    text-transform: uppercase;
}

/* Przekreślona kwota mówi „to już było" szybciej niż jakikolwiek napis. */
.in-price--brak .in-price-v {
    text-decoration: line-through;
    text-decoration-thickness: 2px;
    text-decoration-color: rgba(11, 18, 32, .45);
}

/* Przycisk przestaje wyglądać na klikalny: bez wypełnienia, sama obwódka.
   ⚠️ `--cta-base`, nie `background`. Blok „CTA — wypełnienie" w komponenty.css
   maluje KAŻDY przycisk regułą `:is(.in-btn, …) { background-color:
   var(--cta-base) !important }` — zwykłe `background: transparent` tutaj
   przegrywało z tym `!important` i wyprzedany pakiet dostawał pełny fiolet
   z szarym napisem na wierzchu. Stąd zgłoszenie „nie widać napisu Wyprzedane".
   Podajemy więc WARTOŚĆ TOKENA, którą tamta reguła i tak weźmie.
   21.08.2026 */
.in-price--brak .in-btn--brak,
.in-btn--brak {
    --cta-base: transparent;
    --cta-fill: transparent;
    --cta-hover-text: var(--color-text, #0B1220);
    background: transparent;
    color: var(--color-text, #0B1220);
    border: 1px dashed rgba(11, 18, 32, .38);
    box-shadow: none;
    cursor: not-allowed;
}
.in-price--brak .in-btn--brak::after,
.in-price--brak .in-btn--brak svg { display: none; }
/* ⚠️ Po zdjęciu strzałki trzeba poprawić proporcje, bo cała geometria
   przycisku jest pod nią skrojona: wyściółka to `8px 8px 8px 26px` (z prawej
   miejsce zajmuje kółko ze strzałką), a wysokość 50 px bierze się właśnie
   z tego kółka. Bez strzałki zostawał kadłubek 118×39 px z napisem dosuniętym
   do prawej — obok aktywnego „Wybieram" 149×50 wyglądał na przypadkowy.
   Zgłoszone przez Bartka 24.08.2026. */
.in-price--brak .in-btn--brak,
.in-btn--brak {
    /* `!important` świadomie. Regułę od strzałki w `szkielet.css` zbudowano
       z `:is()` i sześciu `:not(:has(...))` — to około siedmiu klas
       szczegółowości, więc bez tego nie da się jej pokonać rozsądnym
       selektorem. Sama reguła jest w porządku: to ona robi z przycisków
       pigułki ze strzałką. Problem dotyczy wyłącznie tego jednego wariantu,
       któremu strzałkę chowamy. */
    padding: 14px 26px !important;
    min-height: 50px;
    justify-content: center !important;
    gap: 0 !important;
}
/* Reguła z wypełnieniem `rgba(11,18,32,.10)` stała tu do 21.08.2026 i była
   trzecim, sprzecznym opisem tego samego przycisku (obok tej wyżej i tej
   w okolicach wiersza 310). Została zwinięta do reguły wyżej. */

/* ── Krój tekstu: Source Sans 3, nie „Source Sans Pro" ─────────────────────
   ⚠️ CAŁY TEKST NA STRONIE LECIAŁ CZCIONKĄ SYSTEMOWĄ (21.08.2026).
   `tokeny.css` prosi o rodzinę **Source Sans Pro**, a `instytut_fonty_url()`
   ładuje z Google **Source Sans 3** — Adobe wycofało „Pro" i zastąpiło je
   „3" pod NOWĄ nazwą rodziny. Nazwy się nie zgadzały, dopasowanie nie
   następowało i przeglądarka schodziła na `system-ui`: San Francisco na
   macOS, Segoe UI na Windowsie. Zmierzone przez `CSS.getPlatformFontsForNode`
   — akapity renderowały się w `.SF NS`, nie w kroju z brandbooka.
   Objaw jest cichy: `getComputedStyle` pokazuje zadeklarowany stos, więc
   w DevToolach wygląda to na poprawne.
   `tokeny.css` generuje `tools/wytnij-css.py` z prototypu, dlatego poprawka
   siedzi tutaj — motyw.css ładuje się po nim i nie jest nadpisywany buildem.
   Zostawiamy „Source Sans Pro" w stosie: gdyby ktoś miał ją lokalnie
   zainstalowaną, to ten sam krój. */
:root {
    --font-body: 'Source Sans 3', 'Source Sans Pro', system-ui, sans-serif;
}

/* ── Nagłówki na kroju z brandbooka ────────────────────────────────────────
   `szkielet.css` (generowany z prototypu) nadpisuje `--font-display` na
   `DM Serif Display` i wymusza go na h1/h2 przez `!important`. Klientka
   zgłosiła 21.08.2026, że tego kroju nie ma w jej identyfikacji — brandbook
   zna dokładnie dwa: **Baloo 2** i **Source Sans**. Wracamy do Baloo 2.

   Nadpisanie siedzi tutaj, a nie w `szkielet.css`, bo tamten plik generuje
   `tools/wytnij-css.py` z prototypu i każdy build skasowałby poprawkę.
   `motyw.css` ładuje się PO nim, więc ta definicja wygrywa.

   Waga 500, nie 400: reguła z prototypu wymusza na h1/h2 `font-weight: 400`,
   co w szeryfowym DM Serif wyglądało dobrze, ale Baloo 2 przy 400 jest na
   duże stopnie za cienkie — reszta nagłówków w motywie stoi właśnie na 500. */
:root {
    --font-display: 'Baloo 2', system-ui, sans-serif;
}
/* ⚠️ Waga idzie z tokena skali, nie z liczby wpisanej tutaj — i MUSI być
   rozdzielona na poziomy. Ta reguła jest bardziej szczegółowa niż `html body h2`
   z warstwy skali (przez `:is()` i selektory z klasą), więc dopóki wszystkie
   nagłówki brały z niej jedną wagę, h2 wymienione niżej zostawały na 700, gdy
   reszta h2 zeszła do 500. Na jednej stronie stały wtedy obok siebie nagłówki
   sekcji w dwóch grubościach — zgłoszone przez Bartka 24.08.2026 (i wcześniej
   21.08 w drugą stronę, gdy było tu wpisane sztywne 500). */
html body h1,
html body .in-xh-h {
    /* Od 24.08.2026 h1 ma WŁASNY token — waga schodzi razem z hierarchią
       (h1 700, h2 600, reszta 500), więc h1 nie może już brać wagi „reszty". */
    font-weight: var(--t-waga-h1, 700) !important;
}
html body h2,
html body .in-fd-title,
html body .in-showcase-copy > h2,
html body .in-sec.in-split > .in-wrap > h2 {
    font-weight: var(--t-waga-h2, 500) !important;
}

/* ── Koniec z pojedynczym wyrazem w ostatnim wierszu ───────────────────────
   Nagłówki łamały się tak, że na końcu zostawał jeden wyraz („…z certyfikowaną
   / numeroterapeutką”). Zgłoszone przez Bartka 21.08.2026 — i nie był to jeden
   nagłówek, tylko kilkanaście na całym serwisie.

   `text-wrap: balance` rozkłada wiersze na możliwie równą długość, zamiast
   wypychać resztę do ostatniego. Przeglądarka robi to sama, po zmierzeniu
   tekstu, więc działa dla dowolnej treści z panelu — nie trzeba wstawiać
   twardych spacji ręcznie i nie psuje się przy zmianie tekstu.

   ⚠️ `balance` liczy się tylko do kilku wierszy (w Chrome do sześciu), dlatego
   akapity dostają `pretty` — ono nie wyrównuje długości, ale też pilnuje, żeby
   ostatni wiersz nie został sam. Starsze przeglądarki po prostu ignorują obie
   właściwości i łamią tekst jak dotąd. */
h1, h2, h3, h4,
.in-lead,
.in-xh-h,
.in-fd-title {
    text-wrap: balance;
}
p, li, .in-p {
    text-wrap: pretty;
}

/* ⚠️ Na telefonie `balance` szkodzi. Przy szerokim ekranie wyrównuje wiersze
   prawie za darmo, ale w kolumnie 350 px zaczyna oddawać jedną trzecią miejsca:
   „Nie pracujesz / tylko «w głowie»" zajmowało 230 z 390 px, „5 Krain, przez /
   które przejdziesz" 242 z 390. Nagłówki wyglądały, jakby ktoś wstawił twarde
   łamanie w losowym miejscu. Zgłoszone przez Bartka 22.08.2026.

   Zostaje `pretty`: łamie zachłannie, czyli wykorzystuje całą szerokość, ale
   nadal pilnuje, żeby w ostatnim wierszu nie został sam jeden wyraz — a o to
   chodziło we wczorajszej poprawce. Zmierzone przy 430 px: najdłuższy wiersz
   rośnie z 230 do 267 px, a przy „To jest gra transformacyjna na żywo"
   z 358 do 387 px, czyli praktycznie do krawędzi.

   Powyżej 600 px zostaje `balance` — tam nagłówki mieszczą się w jednym lub
   dwóch wierszach i wyrównanie długości tylko pomaga. */
@media (max-width: 600px) {
    h1, h2, h3, h4,
    .in-lead,
    .in-xh-h,
    .in-fd-title {
        text-wrap: pretty;
    }
}

/* ══════════════════════════════════════════════════════════════════════════
   RÓWNY START OPISÓW W KAFELKACH
   ──────────────────────────────────────────────────────────────────────────
   Tytuły kafelków startowały równo, ale tytuł łamiący się na dwa wiersze
   spychał opis pod sobą o 28–30 px w dół. Widać to było w każdym rzędzie,
   gdzie jedna nazwa jest dłuższa od pozostałych („Praca w Kronikach Akaszy"
   obok „Numerologii", „Dla poszerzających warsztat" obok „Dla terapeutów").
   Zgłoszone przez klientkę jako powtarzający się błąd.

   Rezerwujemy tytułowi wysokość DWÓCH wierszy — wtedy opis zaczyna się
   w tym samym miejscu niezależnie od długości nazwy, a krótkie tytuły
   po prostu mają pod sobą powietrze.

   ⚠️ `min-height`, nie `height` — tytuł z trzech wierszy (zdarza się na
   wąskich ekranach) ma się dalej mieścić, a nie wychodzić poza kafelek.
   Na telefonie kafelki idą jeden pod drugim, więc nie ma czego wyrównywać
   i rezerwacja tylko robiłaby dziury — stąd próg 861 px. */
@media (min-width: 861px) {
    .in-pn-it h3,
    .in-card-b h3,
    .in-pr-it h3 {
        min-height: calc(2 * 1.2em);
    }
}

/* ══════════════════════════════════════════════════════════════════════════
   ROZSYPANE KAFELKI — koniec nachodzenia, BEZ ucinania tekstu
   ──────────────────────────────────────────────────────────────────────────
   Sekcja „Rozpoznajesz siebie w którymś z tych zdań?" układa sześć kafelków
   absolutnie względem środka ekranu, w dwóch kolumnach po trzy. Zmierzone
   przed poprawką przy 1440×900: nachodziło na siebie SZEŚĆ par (największa
   nakładka 228×169 px), a wszystkie sześć wchodziło na nagłówek.

   Arytmetyka: kolumna ma wysokość okna (sekcja jest `sticky`, `height:100vh`),
   rozstaw wynosił ±23vh — przy oknie 900 px to 217 px między środkami —
   a kafelki miały 276–337 px wysokości. Trzy nie mieściły się w kolumnie.

   ⚠️ PIERWSZE PODEJŚCIE PRZYCINAŁO TEKST i to był błąd: z „Pracujesz nad sobą
   od lat… a pewne tematy dalej «nie puszczają»" zostawało „…a pewne tematy…".
   Te zdania są całą treścią tej sekcji, więc nie wolno ich skracać. Zamiast
   tego kafelek jest CIASNIEJSZY (mniejszy stopień pisma, mniejsze wypełnienie),
   a rozstaw pionowy rośnie do ±30vh — wtedy nawet trzywierszowy tytuł mieści
   się w kolumnie w całości.
   21.08.2026 */
@media (min-width: 1100px) {
    .in-sec.in-rozsyp .in-zd-it {
        width: clamp(230px, 17.5vw, 290px);
        padding: 20px 22px 22px;
    }
    .in-sec.in-rozsyp .in-zd-it h3 {
        
        line-height: 1.28;
        margin-bottom: 6px;
    }
    /* ⚠️ `p:not(.in-zd-n)` — numer kafelka też jest akapitem (<p class="in-zd-n">),
       więc bez tego wyjątku zjeżdżał z 56 px na 14 px i robił się nieczytelnym
       pyłkiem w rogu. Zgłoszone przez Bartka 21.08.2026. */
    .in-sec.in-rozsyp .in-zd-it p:not(.in-zd-n) {
        font-size: 14px;
        line-height: 1.5;
    }

    .in-sec.in-rozsyp .in-zd-it:nth-child(1) { --x: -31vw; --y: -30vh; }
    .in-sec.in-rozsyp .in-zd-it:nth-child(2) { --x: -34vw; --y:   0px; }
    .in-sec.in-rozsyp .in-zd-it:nth-child(3) { --x: -30vw; --y:  30vh; }
    .in-sec.in-rozsyp .in-zd-it:nth-child(4) { --x:  31vw; --y: -30vh; }
    .in-sec.in-rozsyp .in-zd-it:nth-child(5) { --x:  34vw; --y:   0px; }
    .in-sec.in-rozsyp .in-zd-it:nth-child(6) { --x:  30vw; --y:  30vh; }
}

/* Tytuł kafelka w siatkach sklepu i bloga bywa TRZYWIERSZOWY („Książka
   «Numeroterapia czyli edukacja duchowa. Podręcznik…»"), a rezerwacja dwóch
   wierszy wyżej takiego nie wyrówna. Przycinamy do dwóch wierszy — wtedy
   każdy kafelek w rzędzie ma tytuł tej samej wysokości, a pełna nazwa
   i tak stoi na stronie produktu czy wpisu. */
/* ⚠️ 21.08.2026 — przycinanie zdjęte z KAFELKÓW TREŚCI. „Twoje przekonania
   kształtują Twoją rzeczywistość" wyświetlało się jako „Twoje przekonania
   kształtują Twoją…", czyli tytuł bez najważniejszego słowa. Wyrównanie
   opisów załatwia rezerwacja dwóch wierszy (`min-height` w bloku „RÓWNY START
   OPISÓW"), a tytuł, który jest dłuższy, po prostu się łamie.
   Przycinanie zostaje TYLKO tam, gdzie tytuł jest nazwą własną produktu albo
   wpisu i pełna wersja stoi kliknięcie dalej. */
@media (min-width: 861px) {
    .in-sec.in-posts .in-card h3,
    .in-prod-b h3 {
        display: -webkit-box;
        -webkit-box-orient: vertical;
        -webkit-line-clamp: 2;
        line-clamp: 2;
        overflow: hidden;
    }
}

/* ── Kafelki „czy to o Tobie?" — jedno zdanie, nie tytuł z opisem ──────────
   Kafelek składa się z pola „Zdanie" i „Dopowiedzenie", ale czyta się je
   RAZEM: „Wchodzisz wciąż w te same relacje / i za każdym razem jesteś
   zdziwiona, że się to powtarza". Pogrubiona pierwsza część sugerowała
   nagłówek z opisem pod spodem, czyli dwie osobne myśli — a to jedno zdanie
   przełamane na dwie linijki. Zdejmujemy pogrubienie; różnica stopnia pisma
   i koloru wystarczy, żeby oddzielić zdanie od dopowiedzenia.
   Zgłoszone przez Bartka 21.08.2026 */
html body .in-sec.in-zdania .in-zd-it h3,
html body .in-sec.in-zdania .in-zd-it h3 + p {
    /* `!important` ORAZ `html body` z przodu. Sam `!important` nie wystarczył:
       grupa tekstu ciągłego w `skala.css` ma w `:is()` selektor
       `.in-sec > .in-wrap > .in-p` — TRZY klasy — więc cała grupa liczy się
       jak (0,3,2), dokładnie tyle co ta reguła. Przy remisie wygrywa plik
       ładowany później, czyli skala, i opis kafelka zostawał na 20 px, gdy
       tytuł miał 16. `html body` przechyla szalę tutaj.
       ⚠️ `:is()` bierze szczegółowość od NAJBARDZIEJ szczegółowego argumentu —
       łatwo się przeliczyć, bo wystarczy jeden „ciężki" selektor na liście.
       21.08.2026 */
    font-family: var(--font-heading, 'Baloo 2', sans-serif) !important;
    /* Stopień z tokena tekstu ciągłego — te kafelki to zdania do czytania,
       więc mają być tej samej wielkości co reszta serwisu. Wcześniej stało tu
       sztywne 16 px i wyłamywały się w dół. Zgłoszone przez Bartka 21.08.2026 */
    font-size: var(--t-body, 16px) !important;
    font-weight: 400 !important;
    line-height: 1.5 !important;
    color: var(--color-text, #0B1220);
    margin: 0;
    /* ⚠️ `display: inline` — to sedno poprawki. Zdanie i dopowiedzenie to dwa
       pola ACF, więc w kodzie strony są osobnymi blokami: <h3> i <p>. Blok
       zawsze zaczyna nowy wiersz, przez co tekst łamał się w środku zdania
       niezależnie od szerokości kafelka. Jako elementy liniowe płyną jednym
       ciągiem i zawijają się dopiero na krawędzi kafelka.
       Odstęp między nimi bierze się ze spacji w kodzie strony. */
    display: inline;
    /* `text-wrap: balance` (nasza reguła na wszystkie nagłówki) wyrównywała
       długość wierszy i robiła z „Wchodzisz wciąż w te same relacje" dwie
       krótkie linijki mimo miejsca w kafelku. Tu chcemy zwykłego zawijania. */
    text-wrap: initial;
}

/* ⚠️ ODWRÓCENIE POWYŻSZEGO tam, gdzie tytuł jest PRAWDZIWYM tytułem.
   Reguła wyżej powstała 21.08 dla kafelków z gry, gdzie „zdanie" i
   „dopowiedzenie" to dwie połowy JEDNEGO zdania — i tam jest słuszna.
   Na /konsultacja/ wytyczne dały tym kafelkom osobne tytuły („Bez iluzji",
   „Skok kwantowy") i przez tamtą regułę skleiły się z opisem w jeden akapit:
   „Bez iluzji Nie karmię Twojego ego…". Zgłoszone przez Bartka 24.08.2026.

   Rozróżnienie jest po DANYCH, nie po stronie: na grze pole tytułu jest puste,
   więc szablon w ogóle nie drukuje `h3` i ta reguła tam nie ma czego złapać. */
html body .in-sec.in-zdania .in-zd-it h3 {
    display: block !important;
    font-weight: var(--t-waga-naglowka, 700) !important;
    /* ⚠️ Stopień h3 ze skali, nie h5. Przez trzy dni stało tu `--t-h5` (17 px)
       przy tekście ciągłym 16 px — różnica jednego piksela sprawiała, że
       „Bez iluzji" czy „Skok kwantowy" czytało się jak pogrubiony akapit,
       a nie jak nagłówek kafelka. Bartek zgłaszał to dwa razy: „czemu te
       headery są jako zwykły tekst" (24.08) i „miały być jako heading tych
       komponentów jak w innych miejscach". Teraz mają dokładnie ten sam
       stopień co nagłówki kafelków gdzie indziej na stronie — 22 px. */
    font-size: var(--t-h3, 22px) !important;
    line-height: var(--t-h3-lh, 1.25) !important;
    margin: 0 0 10px !important;
    /* `max-width: 22ch` z komponentów było liczone dla stopnia 15 px i przy
       22 px zawężało tytuł bardziej niż kafelek. Tytuł ma się łamać na
       krawędzi kafelka, nie wcześniej. */
    max-width: none !important;
    /* Miejsce na DWA wiersze tytułu, na sztywno — żeby opisy we wszystkich
       kafelkach zaczynały się na tej samej wysokości. Bez tego „Bez iluzji"
       (jeden wiersz) podciągało swój opis o 27 px wyżej niż „Konkret zamiast
       motywacji" (dwa wiersze) i rząd wyglądał na poszarpany. Ta sama zasada
       co w kafelkach `.in-card-b h3`, tylko tam próg jest na 861 px — tu nie,
       bo poniżej 1400 px kafelki idą poziomym paskiem i STOJĄ OBOK SIEBIE
       na każdej szerokości, więc zawsze jest co wyrównywać.
       Zgłoszone przez Bartka 24.08.2026.
       ⚠️ `min-height`, nie `height` — tytuł z trzech wierszy ma się zmieścić. */
    min-height: calc(2 * var(--t-h3-lh, 1.25) * 1em);
}
html body .in-sec.in-zdania .in-zd-it h3 + p {
    display: block !important;
}

/* ── Kafelki „zdania" bez ikony: miejsce na numer ─────────────────────────
   Numer w rogu jest pozycjonowany absolutnie, więc sam z siebie nie odpycha
   tekstu. Dopóki kafelek miał ikonę (56 px + 30 px marginesu), tekst i tak
   zaczynał się pod numerem. Na stronach, gdzie w polu „Ikona" nic nie wybrano,
   ikony nie ma wcale — a odkąd zdanie i dopowiedzenie płyną liniowo, pierwszy
   wiersz startuje przy samej górze i wchodził pod cyfrę („Nie karmię Twojego
   ego 01"). Rezerwujemy pasek na numer tylko w kafelkach bez ikony.
   Zgłoszone przez Bartka 21.08.2026 */
/* ⚠️ selektor musi być `p.in-zd-n`, a nie `.in-zd-n`. W komponenty.css reguła
   `.in-sec.in-zdania .in-zd-it p { font-size: 15px }` stoi NIŻEJ i jest
   bardziej szczegółowa (trzy klasy + element) niż `.in-sec.in-zdania .in-zd-n`
   (trzy klasy), więc to ona ustalała stopień pisma numeru — stąd cyfra
   wielkości przypisu zamiast zapowiadanego w komentarzu „wielkiego serifu". */
.in-sec.in-zdania .in-zd-it p.in-zd-n { font-size: 56px; }

/* Na rozsypanych kafelkach ta sama cyfra musi być mniejsza: 56 px projektowano
   dla kafelka na 1/3 szerokości ekranu, a tutaj kafelek ma ~260 px i cyfra
   zachodziła na pierwszy wiersz tekstu.
   ⚠️ Ta reguła MUSI stać po regule bazowej, mimo że jest w @media. Obie mają
   tę samą szczegółowość (0,4,1), a media query jej nie podnosi — decyduje
   kolejność w pliku. */
@media (min-width: 1100px) {
    .in-sec.in-rozsyp .in-zd-it p.in-zd-n { font-size: 34px; top: 14px; right: 18px; }
}

/* Kafelki BEZ ikony: numer wraca do normalnego układu treści.
   Numer jest pozycjonowany absolutnie w prawym górnym rogu i sam z siebie nie
   odpycha tekstu — działało to tylko dzięki ikonie, która zajmowała 56 px u
   góry kafelka i spychała tekst pod cyfrę. Tam, gdzie w polu „Ikona" nic nie
   wybrano, ikony nie ma wcale, więc tekst wchodził wprost pod cyfrę („Nie
   karmię Twojego ego 01"). Rezerwowanie samego paska u góry nie wystarczyło:
   przy szerokim kafelku wiersze i tak przechodziły pod cyfrą z prawej strony.
   Dlatego w tych kafelkach numer przestaje być warstwą, a staje się zwykłym
   wierszem nad tekstem — wtedy nic pod niego nie podejdzie, niezależnie od
   szerokości kafelka i długości zdania.
   Zgłoszone przez Bartka 21.08.2026 */
.in-sec.in-zdania .in-zd-it:not(:has(.in-zd-ic)) p.in-zd-n {
    position: static;
    display: block;
    text-align: right;
    line-height: 1;
    margin: 0 0 10px;
}

/* ── Karta obszaru: tytuł na fioletowym tle ───────────────────────────────
   Aktywna (i najechana) karta w „Obszary pracy" przebarwia się na fiolet
   marki, a cała jej treść ma wtedy dziedziczyć biel — `.in-services-list
   .in-card-b h3` ma w komponenty.css wpisane `color: inherit` właśnie po to.
   Tylko że dalej w tym samym pliku stoi reguła ogólna:
       .in-sec:not(.in-feature):not(.in-icon-cards) .in-card .in-card-b h3
   i jest bardziej szczegółowa (cztery klasy kontra trzy), więc to ona ustala
   kolor tytułu — fiolet marki. Dopóki aktywna karta była prawie czarna, tytuł
   jakoś się przebijał; po przejściu na kolory brandbooka tło karty i tytuł to
   dokładnie ten sam #643B81 i tytuł znikł.
   Zgłoszone przez Bartka 21.08.2026 */
/* ⚠️ Selektor musi być DŁUŻSZY, niż się wydaje. Reguła ogólna ma dwa `:not()`,
   a `:not()` liczy się do szczegółowości tak samo jak zwykła klasa — wychodzi
   z niej pięć klas, nie trzy. Krótszy zapis (`.in-services-list > .in-card
   .is-active …`) przegrywał i tytuł dalej był fioletowy. */
.in-sec.in-services-stack .in-services-list > .in-card.is-active .in-card-b h3,
.in-sec.in-services-stack .in-services-list > .in-card:hover .in-card-b h3,
.in-sec.in-services-stack .in-services-list > .in-card:focus-visible .in-card-b h3 {
    color: #fff;
}

/* ── Ptaszki na wyróżnionej karcie cennika ────────────────────────────────
   Ptaszek nie jest znakiem tekstowym, tylko dwoma krawędziami pustego
   prostokąta obróconego o 45° (`border-width: 0 2px 2px 0`). Rysuje go więc
   `border-color`, a nie `color` — i dlatego reguła
       .in-price--hl .in-check li::before { color: var(--brand-300) }
   nigdy nie miała na niego wpływu. Dopóki wyróżniona karta była prawie
   czarna, fioletowe ptaszki jakoś się na niej broniły; po przejściu na kolory
   brandbooka tło karty i ptaszek to ten sam #643B81 i ptaszki znikły.
   Zgłoszone przez Bartka 21.08.2026 */
.in-price--hl .in-check li::before {
    border-color: #fff;
}

/* ── Nagłówek sekcji o założycielce: jeden kolor ──────────────────────────
   Pole „Nagłówek" łamie się na dwie linijki, a drugą prototyp wkłada w <span>
   i barwi na przygaszony grafit — miał być delikatny kontrapunkt dla ciemnego
   śliwkowego nagłówka. Po przejściu na kolory brandbooka nagłówek jest pełnym
   fioletem marki i ta różnica przestała być niuansem: zdanie wygląda, jakby
   ktoś zapomniał dokończyć formatowania w połowie.
   Zgłoszone przez Bartka 21.08.2026 */
/* ⚠️ `html body` z przodu nie jest ozdobą. Na stronie głównej ta sama reguła
   stoi w strony/index.css, który ładuje się PO tym pliku — przy równej
   szczegółowości wygrywał on i nagłówek dalej był dwukolorowy. */
html body .in-fd-title span { color: inherit; }

/* ── „Wybierz format sesji" — węższa przerwa, szersze karty ───────────────
   Sekcja stoi na podziale 1/3 (nagłówek) i 2/3 (karty) i tak ma zostać.
   Problemem była przerwa: 64 px między kolumnami plus 24 px między kartami
   zjadało prawie 140 px, a te piksele brały się z kart. Przy trzech pakietach
   karta schodziła do 258 px i pozycje listy łamały się po dwa–trzy słowa
   („Numeroterapeutki pracują / pod merytoryczną / superwizją Olgi N. /
   Stępińskiej"). Lewa kolumna i tak jest w dwóch trzecich pusta — nagłówek
   z leadem kończy się wysoko — więc odstęp niczego tam nie porządkuje.

   Ściągamy obie przerwy do minimum. Karty rosną o ~20 px każda, co wystarcza,
   żeby wiersze listy trzymały po cztery–pięć słów.
   Zgłoszone przez Bartka 21.08.2026 */
@media (min-width: 1001px) {
    .in-sec.in-pricing > .in-wrap {
        grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
        gap: 0 8px;
    }
    .in-sec.in-pricing > .in-wrap > .in-grid3 { gap: 12px; }
}

/* „cena obejmuje:" stoi teraz POD kwotą, jako zapowiedź listy (patrz
   template-parts/sekcje/cennik.php). Odstęp spod kwoty był liczony na to, że
   zaraz po niej idzie lista — z wtrąconym zdaniem robiła się z tego dziura. */
.in-price-v:has(+ .in-price-n) { margin-bottom: 14px; }

/* ── Kafelki „czy to o Tobie?" — jeden rząd, a gdy ciasno, przewijanie ────
   Siatka trzykolumnowa działa tylko wtedy, gdy zdań jest 3, 6 albo 9. Sekcje
   mają ich tyle, ile Olga napisała: gra 6, książka 5, konsultacja 4. Cztery
   w trzech kolumnach dawały 3 + 1 z sierotą w rogu, a po przełożeniu na dwie
   kolumny — szeroki kafelek z dwoma wierszami tekstu i połową wysokości pustą.

   Zamiast dobierać układ do liczby, kładziemy wszystkie w JEDNYM rzędzie.
   Kafelki rozciągają się, dopóki się mieszczą; gdy przestają, rząd zamienia
   się w przewijany w bok pasek. Bez skryptu — robi to `overflow-x` na
   kontenerze i `flex-shrink: 0` na kafelkach, więc działa też bez JS-u
   i palcem na telefonie.

   Zakres do 1399 px, bo od 1400 px kafelki się rozsypują wokół nagłówka
   i mają wtedy pozycjonowanie absolutne — tam rząd nie ma czego układać.
   Zgłoszone przez Bartka 21.08.2026 */
@media (max-width: 1399px) {
    .in-sec.in-zdania .in-zd-grid {
        display: flex;
        flex-wrap: nowrap;
        gap: 16px;
        overflow-x: auto;
        overscroll-behavior-x: contain;
        scroll-snap-type: x proximity;
        /* Wyściółka tylko na pasek przewijania i na obwódkę kafelka — cienia
           już nie ma, więc nie trzeba rezerwować miejsca po bokach. */
        padding: 0 0 16px;
        margin: 36px 0 24px;
        scrollbar-width: thin;
        scrollbar-color: var(--color-border, #C6C4D8) transparent;
    }
    .in-sec.in-zdania .in-zd-grid::-webkit-scrollbar { height: 6px; }
    .in-sec.in-zdania .in-zd-grid::-webkit-scrollbar-track { background: transparent; }
    .in-sec.in-zdania .in-zd-grid::-webkit-scrollbar-thumb {
        background: var(--color-border, #C6C4D8);
        border-radius: 999px;
    }

    /* `1 0 …` — rosną do pełnej szerokości, ale NIE kurczą się poniżej
       podstawy. To drugie jest tu sednem: bez `flex-shrink: 0` kafelki
       ścisnęłyby się do paska po 80 px zamiast wyjechać poza ekran. */
    .in-sec.in-zdania .in-zd-it {
        flex: 1 0 clamp(240px, 21vw, 320px);
        scroll-snap-align: start;
        padding: 26px 26px 28px;
    }
    .in-sec.in-zdania .in-zd-it p.in-zd-n { font-size: 34px; top: 16px; right: 20px; }
    .in-sec.in-zdania .in-zd-ic { width: 40px; height: 40px; margin-bottom: 18px; }
    .in-sec.in-zdania .in-zd-it:not(:has(.in-zd-ic)) p.in-zd-n { margin-bottom: 8px; }
}

/* ── Kafelki zdań bez cienia ──────────────────────────────────────────────
   Prototyp podkładał pod nie miękki cień na 46 px. W jednym rzędzie, gdzie
   kafelki stoją blisko siebie, cienie sąsiadów nachodziły na siebie i robiły
   szarą smugę pod całym paskiem — a przy przewijaniu i tak były przycinane
   na krawędziach. Zostaje sama obwódka; kafelek odcina się od tła bielą.
   Zgłoszone przez Bartka 21.08.2026 */
.in-sec.in-zdania .in-zd-it,
.in-sec.in-zdania .in-zd-it:hover,
.in-sec.in-zdania .in-zd-it:focus-visible {
    box-shadow: none;
}

/* ══════════════════════════════════════════════════════════════════════════
   SKALA TEKSTU — PRZENIESIONA do assets/css/skala.css (21.08.2026)
   ──────────────────────────────────────────────────────────────────────────
   Stały tu DWA bloki skali: jeden bez `!important`, drugi z. Razem z trzecim
   na końcu `szkielet.css` dawały trzy źródła prawdy o tym, ile ma mieć akapit
   — i na telefonie wychodziło z tego 14, 16 i 20 px na jednym ekranie.
   Cała skala (stopnie pisma ORAZ rytm pionowy sekcji) siedzi teraz w jednym
   pliku, ładowanym jako ostatni. Rozmiarów tekstu NIE dopisujemy tutaj.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── Kafelki jako karuzela ────────────────────────────────────────────────
   Wariant `karuzela` układa kafelki w JEDNYM rzędzie przewijanym w bok,
   zamiast łamać je na siatkę. Sprawdza się tam, gdzie pozycji jest dużo,
   a każda ma własny akapit — w siatce robiłby się z tego mur tekstu na pół
   ekranu, a najkrótsza pozycja i tak wymuszałaby wysokość na resztę.

   Ta sama mechanika co przy kafelkach „czy to o Tobie?": kafelki rosną,
   dopóki się mieszczą, a gdy przestają — rząd zamienia się w pasek. Bez
   skryptu, więc działa też palcem i bez JS-u. Wyściółka na dole robi miejsce
   paskowi przewijania, żeby nie wchodził na krawędź kafelków.
   Zgłoszone przez Bartka 21.08.2026 */
/* ── Karuzela na pełną szerokość ────────────────────────────────────────────
   Taśma siedziała w `.in-wrap` z gutterem 72 px z obu stron, więc ostatnia
   widoczna karta była UCINANA na krawędzi kolumny — wyglądało to jak błąd
   układu, a nie jak „jest tego więcej, przewiń". Zgłoszone przez Bartka
   21.08.2026.

   Zdejmujemy prawy gutter z `.in-wrap` i oddajemy go taśmie jako jej własną
   wyściółkę. Efekt: karty biegną do samej krawędzi ekranu i wyjeżdżają poza
   nią naturalnie, a po przewinięciu do końca ostatnia karta ma pod sobą te
   same 72 px, co reszta serwisu. Nagłówek i strzałki zostają na siatce.

   Tylko od 861 px — na telefonie gutter to 20 px i taśma i tak dochodzi
   do krawędzi. */
@media (min-width: 861px) {
    /* SAMA TAŚMA wychodzi poza kolumnę — ujemnym marginesem, a wyściółkę
       oddaje sobie z powrotem jako własną. Kontener zachowuje swój gutter,
       więc nagłówek, wprowadzenie, strzałki i przycisk pod spodem stoją
       równo z resztą serwisu.

       ⚠️ Pierwsze podejście (21.08.2026) zdejmowało gutter z KONTENERA
       i dokładało go dzieciom. Działało dla nagłówka, ale przycisk „Zobacz
       wszystkie wpisy" ma własną wyściółkę i tamtej nie przyjął — wylądował
       przy samej krawędzi ekranu. Zgłoszone przez Bartka.

       Po co w ogóle full-bleed: pas przewijania przycina zawartość na swoich
       krawędziach, więc gdy taśma kończyła się na 72 px, ostatnia widoczna
       karta wyglądała na uciętą, a nie na wyjeżdżającą poza ekran. */
    .in-sec.in-karuzela .in-grid2,
    .in-sec.in-karuzela .in-grid3,
    .in-sec.in-karuzela .in-grid4,
    .in-sec.in-karuzela .in-pr-grid {
        margin-inline: calc(var(--in-hgut, 72px) * -1);
        padding-inline: var(--in-hgut, 72px);
        scroll-padding-inline: var(--in-hgut, 72px);
    }

    /* Taśma osób idzie DO SAMYCH KRAWĘDZI EKRANU, nie do wcięcia treści.
       Kafelki mają zjeżdżać za brzeg z obu stron — inaczej po lewej i prawej
       zostają fioletowe pasy i taśma wygląda jak wstawka, a nie jak taśma.
       Zgłoszone przez Bartka 04.09.2026.

       `50% - 50vw` odmierza drogę od środka kafla treści do środka ekranu,
       więc działa niezależnie od tego, jak szeroki jest `.in-wrap`. Nadmiar
       z paska przewijania (100vw liczy go, szerokość strony nie) zbiera
       `html, body { overflow-x: clip }` ze szkielet.css — bez tego strona
       dostałaby własny pasek u dołu. */
    .in-sec.in-karuzela .in-people {
        width: 100vw;
        margin-inline: calc(50% - 50vw);
        /* Odwrotność marginesu: taśma jest szeroka na cały ekran, ale pierwszy
           kafelek zaczyna się RÓWNO Z NAGŁÓWKIEM, a za ostatnim zostaje tyle
           samo oddechu. `50vw - 50%` to dokładnie droga od krawędzi ekranu do
           krawędzi kolumny treści — liczy się sama, niezależnie od szerokości
           okna. Zgłoszone przez Bartka 04.09.2026. */
        padding-inline: calc(50vw - 50%);
        scroll-padding-inline: calc(50vw - 50%);
    }
}

.in-sec.in-karuzela .in-grid2,
.in-sec.in-karuzela .in-grid3,
.in-sec.in-karuzela .in-grid4,
.in-sec.in-karuzela .in-people,
.in-sec.in-karuzela .in-pr-grid {
    display: flex;
    flex-wrap: nowrap;
    gap: 16px;
    overflow-x: auto;
    /* ⚠️ `overflow-x: auto` sam z siebie zamyka TEZ pion — przegladarka nie
       potrafi trzymac jednej osi widocznej, a drugiej przewijanej. Tasma stawala
       sie przez to przewijalna w gore i w dol i przechwytywala kolko myszy przy
       przewijaniu strony. Zamykamy pion jawnie; cien i uniesienie karty na hover
       miesci sie w `padding-block` ponizej. Zgloszone przez Bartka 27.08.2026. */
    overflow-y: hidden;
    overscroll-behavior-x: contain;
    scroll-snap-type: x proximity;
    /* `overflow-x: auto` zamyka takze pion — przegladarka nie potrafi trzymac
       jednej osi widocznej, a drugiej przewijanej. Bez zapasu w pionie karta
       uniesiona na hover (translateY -4px) i jej cien (rozmycie 50 px)
       wychodzily poza tasme i byly scinane u gory i u dolu.
       Dol ma wiecej, bo miesci i cien, i pasek przewijania.
       Zgloszone przez Bartka 27.08.2026. */
    padding-block: 12px 30px;
    scrollbar-width: thin;
    scrollbar-color: var(--color-border, #C6C4D8) transparent;
}
.in-sec.in-karuzela .in-grid2::-webkit-scrollbar,
.in-sec.in-karuzela .in-grid3::-webkit-scrollbar,
.in-sec.in-karuzela .in-grid4::-webkit-scrollbar { height: 6px; }
.in-sec.in-karuzela .in-people { scrollbar-width: none; -ms-overflow-style: none; }
.in-sec.in-karuzela .in-people::-webkit-scrollbar { display: none; }
.in-sec.in-karuzela .in-grid2::-webkit-scrollbar-thumb,
.in-sec.in-karuzela .in-grid3::-webkit-scrollbar-thumb,
.in-sec.in-karuzela .in-grid4::-webkit-scrollbar-thumb {
    background: var(--color-border, #C6C4D8);
    border-radius: 999px;
}

/* Karta osoby w taśmie. Węższa od kafelka, bo portret w proporcji 3:4 przy
   340 px urósłby do 450 px wysokości i taśma zjadłaby cały ekran.
   `0 0` — ani nie rośnie, ani się nie kurczy: przy kilkunastu osobach zawsze
   jest co przewijać, więc rozciąganie do pełnej szerokości nie ma sensu. */
.in-sec.in-karuzela .in-people { margin-top: 44px; }

/* Opis bierze tyle miejsca, ile zostało w karcie, i nie rozpycha kafelka.
   Wszystkie karty w rzędzie są równie wysokie (flex), więc bez tego przy
   krótkim opisie zostawała pusta przestrzeń nad „Czytaj więcej", a przy długim
   trzeba było ciąć tekst w PHP na sztywną liczbę znaków. Teraz tnie go układ.

   Zanikanie dokładamy TYLKO wtedy, gdy tekst faktycznie się nie mieści — klasę
   dokłada `wspolne.js` po wyrenderowaniu. Maska nałożona na stałe wygaszałaby
   ostatni wiersz także przy krótkim opisie, który kończy się w dolnej strefie. */
.in-sec.in-karuzela .in-person-b { min-height: 0; }
.in-sec.in-karuzela .in-person-opis {
    flex: 1 1 auto;
    min-height: 0;
    overflow: hidden;
    margin-bottom: 12px;
}
.in-sec.in-karuzela .in-person-opis.jest-ciety {
    -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 2.4em), transparent);
            mask-image: linear-gradient(to bottom, #000 calc(100% - 2.4em), transparent);
}
/* Bez opisu do ucięcia przycisk „Czytaj więcej" nie ma czego dokończyć. */
.in-sec.in-karuzela .in-person-wiecej[hidden] { display: none; }
.in-sec.in-karuzela .in-person { flex: 0 0 clamp(220px, 20vw, 268px); }
@media (max-width: 760px) {
    /* Na telefonie karta leży na boku (patrz komponenty.css), więc potrzebuje
       więcej szerokości niż portret w pionie. */
    .in-sec.in-karuzela .in-person { flex: 0 0 calc(50vw - 24px); }
}

/* `1 0 …` — rosną do pełnej szerokości, ale nie kurczą się poniżej podstawy.
   Bez `flex-shrink: 0` osiem kafelków ścisnęłoby się do pasków po 90 px. */
.in-sec.in-karuzela .in-card {
    flex: 1 0 clamp(260px, 24vw, 340px);
    scroll-snap-align: start;
}

/* W karuzeli tytuł nie jest przycinany do dwóch wierszy — kafelki są
   równej wysokości z natury układu, a ucięta nazwa metody nic nie daje. */
@media (min-width: 861px) {
    .in-sec.in-karuzela .in-card-b h3 {
        display: block;
        -webkit-line-clamp: none;
        line-clamp: none;
        overflow: visible;
        min-height: 0;
    }
}

/* JEDEN wyglad strzalek dla wszystkich karuzel w serwisie — produktow,
   opinii (.in-tm-btn) i filmow pionowych (.in-fp-btn). Wczesniej kazdy
   komponent mial wlasny: rozne srednice, rozne obramowania, a opinie na
   hover robily sie turkusowe zamiast fioletowych. Wzorcem jest karuzela
   spod „Wybierz swoj punkt wejscia". Prosba Bartka 27.08.2026.
   Stare deklaracje usuniete z komponenty.css — ten plik laduje sie PRZED
   motyw.css, wiec zostawienie ich tam dawaloby dwie sprzeczne definicje.

/* Sterowanie karuzeli — strzałki pod paskiem, wyśrodkowane.
   ⚠️ Odstęp NAD strzałkami był 6 px i przyklejał je do taśmy — zgłoszone przez
   Bartka 25.08.2026. Teraz 18 px, czyli tyle, ile dzieli strzałki od przycisku
   pod nimi; panel czyta się jako osobny element sterujący, a nie jako część
   ostatniego kafelka. */
.in-kar-sterowanie {
    display: flex;
    justify-content: center;
    gap: 12px;
    margin: 18px 0 0;
}
.in-kar-sterowanie[hidden] { display: none; }
.in-kar-nav,
.in-tm-btn,
.in-fp-btn {
    display: grid;
    place-items: center;
    width: 44px;
    height: 44px;
    padding: 0;
    color: var(--brand-primary, #643B81);
    background: #fff;
    border: 1px solid var(--color-border, #C6C4D8);
    border-radius: 50%;
    cursor: pointer;
    transition: background-color .2s ease, border-color .2s ease, opacity .2s ease;
}
.in-kar-nav svg,
.in-tm-btn svg,
.in-fp-btn svg { width: 20px; height: 20px; }
.in-kar-nav:hover:not(:disabled),
.in-tm-btn:hover:not(:disabled),
.in-fp-btn:hover:not(:disabled) {
    background: var(--brand-primary, #643B81);
    border-color: var(--brand-primary, #643B81);
    color: #fff;
}
.in-kar-nav:focus-visible,
.in-tm-btn:focus-visible,
.in-fp-btn:focus-visible {
    outline: 2px solid var(--brand-primary, #643B81);
    outline-offset: 2px;
}
/* Na końcu paska strzałka zostaje widoczna, ale wyraźnie nieczynna — znika
   dopiero cały panel, gdy nie ma czego przewijać. */
.in-kar-nav:disabled,
.in-tm-btn:disabled,
.in-fp-btn:disabled { opacity: .3; cursor: default; }

/* ── Karuzela: skrócony opis i okno z całością ────────────────────────────
   Najdłuższy kafelek wyznaczał wysokość całemu rzędowi (przy Reiki i
   medytacjach wychodziło ponad 800 znaków), więc sekcja rosła na wysokość
   ekranu, a krótsze kafelki miały pod tekstem pół metra pustego tła.
   Przycinamy opis do sześciu wierszy; resztę pokazuje okno.
   Zgłoszone przez Bartka 21.08.2026 */
.in-sec.in-karuzela .in-card-b p {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 6;
    line-clamp: 6;
    overflow: hidden;
    margin-bottom: 0;
}
.in-sec.in-karuzela .in-card-b { display: flex; flex-direction: column; }

.in-card-wiecej {
    align-self: flex-start;
    margin-top: 12px;
    padding: 0;
    font-family: inherit;
    font-size: 14px;
    font-weight: 600;
    color: var(--brand-primary, #643B81);
    background: none;
    border: 0;
    border-bottom: 1px solid currentColor;
    cursor: pointer;
}
.in-card-wiecej:hover { color: var(--brand-secondary, #5E689A); }
.in-card-wiecej:focus-visible { outline: 2px solid var(--brand-primary, #643B81); outline-offset: 3px; }

/* Okno z pełnym opisem metody. */
.in-kar-okno { position: fixed; inset: 0; z-index: 120; display: grid; place-items: center; padding: 24px; }
.in-kar-okno[hidden] { display: none; }
.in-kar-okno-tlo { position: absolute; inset: 0; background: rgba(28, 20, 38, .55); }
.in-kar-okno-panel {
    position: relative;
    width: min(620px, 100%);
    max-height: 82vh;
    overflow-y: auto;
    padding: 34px 36px 36px;
    background: #fff;
    border-radius: var(--radius-xl, 20px);
    box-shadow: 0 32px 76px rgba(100, 59, 129, .25);
}
.in-kar-okno-h {
    margin: 0 0 14px;
    font-family: var(--font-heading, 'Baloo 2', sans-serif);
    font-size: 26px;
    font-weight: 500;
    line-height: 1.2;
    color: var(--brand-primary, #643B81);
}
.in-kar-okno-t { font-size: 16px; line-height: 1.65; color: var(--color-text-muted, #413B4D); }
.in-kar-okno-x {
    position: absolute; top: 14px; right: 14px;
    display: grid; place-items: center;
    width: 38px; height: 38px; padding: 0;
    color: var(--color-text-muted, #413B4D);
    background: var(--brand-50, #F2F1F6);
    border: 0; border-radius: 50%; cursor: pointer;
}
.in-kar-okno-x svg { width: 18px; height: 18px; }
.in-kar-okno-x:hover { background: var(--color-border, #C6C4D8); }
html.in-kar-okno-otwarte { overflow: hidden; }

/* ── Karuzela: bez pasków przewijania i bez cienia ────────────────────────
   ⚠️ `overflow-x: auto` sam z siebie NIE zostawia `overflow-y: visible` —
   przeglądarka wymusza wtedy `auto` w pionie, więc przy najmniejszym
   przekroczeniu wysokości (cień, zaokrąglenie wiersza) wyskakiwał drugi,
   pionowy pasek. Dlatego pion wyłączamy wprost.

   Poziomy pasek też chowamy: pod karuzelą stoją strzałki, a dodatkowa
   kreska pod kafelkami tylko zaśmiecała sekcję. Przewijanie palcem, kółkiem
   i tabulatorem działa dalej — chowamy sam wskaźnik, nie mechanizm.
   Zgłoszone przez Bartka 21.08.2026 */
.in-sec.in-karuzela .in-grid2,
.in-sec.in-karuzela .in-grid3,
.in-sec.in-karuzela .in-grid4 {
    overflow-y: hidden;
    padding-bottom: 0;
    scrollbar-width: none;
}
.in-sec.in-karuzela .in-grid2::-webkit-scrollbar,
.in-sec.in-karuzela .in-grid3::-webkit-scrollbar,
.in-sec.in-karuzela .in-grid4::-webkit-scrollbar { display: none; }

.in-sec.in-karuzela .in-card,
.in-sec.in-karuzela .in-card:hover {
    box-shadow: none;
}

.in-kar-sterowanie { margin-top: 18px; }

/* ── Wariant „lista": drobne kafelki bez ikon i numerów ───────────────────
   Skóra `feature` z odjętymi ozdobnikami. Powstała pod polecaną literaturę:
   to jest spis do przejrzenia, a nie oferta — wielki numer w rogu i ikona
   nadawały mu wagę, której nie ma mieć. Mniejszy stopień pisma i cztery
   kolumny zamiast trzech zbijają całość do przypisu na końcu strony.
   Zgłoszone przez Bartka 21.08.2026 */
.in-sec.in-lista .in-card::after { content: none; }
.in-sec.in-lista .in-card-ic { display: none; }
.in-sec.in-lista .in-card { padding: 20px 22px 22px; border-radius: 14px; box-shadow: none; }
.in-sec.in-lista .in-card-b h3 {
    font-family: var(--font-body, sans-serif);
    font-size: var(--t-body);
    font-weight: 700;
    line-height: 1.35;
    max-width: none;
    margin: 0 0 6px;
}
html body .in-sec.in-lista .in-card-b p {
    font-size: 14px !important;
    line-height: 1.55 !important;
    color: var(--color-text-muted, #413B4D);
}
@media (min-width: 1000px) {
    .in-sec.in-lista .in-grid3 { grid-template-columns: repeat(4, 1fr); gap: 14px; }
}

/* Tytuł w wariancie „lista" nie jest przycinany do dwóch wierszy — nazwisko
   autora ucinało się wtedy wielokropkiem („Bogusława…”), a to jedyna
   informacja, po której da się tę książkę znaleźć. */
@media (min-width: 861px) {
    .in-sec.in-lista .in-card-b h3 {
        display: block;
        -webkit-line-clamp: none;
        line-clamp: none;
        overflow: visible;
        min-height: 0;
    }
}

/* Rząd zdań „czy to o Tobie?" chowa pasek przewijania tak samo jak karuzela —
   pod spodem stoją strzałki (assets/js/karuzela.js). Jedna zasada dla
   wszystkich pasków przewijanych w bok w serwisie. */
@media (max-width: 1399px) {
    .in-sec.in-zdania .in-zd-grid {
        overflow-y: hidden;
        scrollbar-width: none;
        padding-bottom: 0;
        margin-bottom: 12px;
    }
    .in-sec.in-zdania .in-zd-grid::-webkit-scrollbar { display: none; }
}

/* ══════════════════════════════════════════════════════════════════════════
   HERO STRONY GŁÓWNEJ — bez portretu na telefonie (21.08.2026)
   ──────────────────────────────────────────────────────────────────────────
   Na desktopie portret stoi OBOK tekstu, w drugiej kolumnie — jest częścią
   kompozycji. Poniżej 900 px kolumny nie ma, więc kadr schodzi POD tekst
   razem z kafelkiem cytatu: na telefonie to cały dodatkowy ekran przewijania
   między wezwaniem do działania a pierwszą sekcją treści, na którym nie ma
   nic do zrobienia. Zdjęcie Olgi wraca zresztą niżej, w module „Wszystko
   zaczyna się od poznania siebie".

   `display: none` na CAŁEJ figurze — kafelek z cytatem jest jej dzieckiem
   (`figcaption`), więc znika razem z nią i nie trzeba go gasić osobno.

   ⚠️ Plik zdjęcia mimo to zjeżdża na telefon: `<img>` zostaje w kodzie strony
   i przeglądarka pobiera go, zanim policzy style. Żeby tego uniknąć, trzeba
   by nie drukować znacznika po stronie PHP — a tego nie da się zrobić
   bezpiecznie przy keszu LiteSpeed, który jedną kopię HTML-a oddaje i
   telefonom, i desktopom. Do rozmowy osobno.
   Zgłoszone przez Bartka 21.08.2026
   ══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 900px) {
    .in-xh-foto { display: none; }
}

/* ══════════════════════════════════════════════════════════════════════════
   MODUŁ „PRZEBIEG" (.in-showcase) — ten sam język co kafelki obszarów
   ──────────────────────────────────────────────────────────────────────────
   Zgłoszenie Bartka 21.08.2026: „ten komponent na mentoringu wygląda inaczej
   niż na /dla-kogo/ — tu jest wzór". I słusznie: to dwa różne układy z ACF
   (`showcase` i `obszary`), każdy przyjechał z innego ekranu prototypu, więc
   tytuł kroku miał 18 px krojem tekstowym w czerni, a tytuł kafelka obszaru
   28,8 px krojem nagłówkowym w fiolecie marki.

   Sam stopień i krój tytułu załatwia warstwa nagłówków w `skala.css`
   (`.in-showcase-step-copy strong` jest na jej liście). Tutaj zostaje to,
   co dotyczy wyłącznie tego modułu: kolor tytułu i wygląd numeru.

   Numer przestaje być wielką cyfrą krojem nagłówkowym, a staje się tą samą
   plakietką, co „OBSZAR 01" we wzorze — wersaliki, 11 px, rozstrzelenie
   .16em, fiolet marki. Kolumna numeru może przez to być węższa.
   ══════════════════════════════════════════════════════════════════════════ */
.in-showcase-step-copy strong {
    margin: 0 0 14px;
    color: var(--brand-primary, #643B81);
}
.in-showcase-n {
    padding-top: 6px;
    font-family: var(--font-body, 'Source Sans 3', sans-serif);
    font-size: 11px;
    font-weight: 700;
    line-height: 1.2;
    letter-spacing: .16em;
    color: var(--brand-primary, #643B81);
}
/* Kolumna liczby liczona była pod 28-piksellową cyfrę. Przy plakietce
   zostaje tyle, ile potrzebuje „01" w wersalikach. */
.in-showcase-step { grid-template-columns: 26px 38px minmax(0, 1fr) 78px; }
@media (max-width: 1050px) {
    .in-showcase-step { grid-template-columns: 26px 30px minmax(0, 1fr); }
}
@media (max-width: 600px) {
    .in-showcase-step { grid-template-columns: 24px 18px minmax(0, 1fr); gap: 12px; }
}
/* Opis kroku był 14 px przy tytule 28,8 px — za duży rozjazd. Tekst ciągły
   ma jeden stopień, więc idzie przez warstwę skali; tutaj tylko odstęp. */
.in-showcase-p { margin-top: 2px; }

/* ══════════════════════════════════════════════════════════════════════════
   PLAKIETKI PRZY ZDJĘCIU AUTORKI — koniec z ucieczką na górę strony
   ──────────────────────────────────────────────────────────────────────────
   `.in-fd-chip--name` i `--role` („Olga N Stępińska", „Autorka") są
   pozycjonowane bezwzględnie wewnątrz kadru. Kadr trzyma je jako kontekst,
   bo ma `position: relative` — ale `komponenty.css` gasi na wąskim ekranie
   przyklejenie kadru regułą `position: static` (żeby nie jechał ze scrollem).
   Razem z przyklejeniem znikał kontekst i obie plakietki lądowały w LEWYM
   GÓRNYM ROGU CAŁEJ STRONY, na pigułce menu — wyglądało to jak podmienione
   logo. Widoczne na każdej podstronie z modułem o autorce, poniżej 1100 px.

   `relative` zamiast `static` załatwia jedno i drugie: nie przykleja, a
   kontekst zostaje.
   Znalezione przy zgłoszeniu Bartka o zdjęciu autorki, 21.08.2026
   ══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 1100px) {
    /* ⚠️ `top: auto` jest tu OBOWIĄZKOWE. Reguła desktopowa to
       `position: sticky; top: 120px`. Przy `static` przesunięcie było
       ignorowane, ale `relative` już je honoruje — sama zamiana zsunęła kadr
       o 120 px w dół i nagłówek „Autorka" wchodził na zdjęcie. */
    .in-sec.in-founder .in-fd-media { position: relative; top: auto; }
}

/* Film w kadrze sekcji „tekst + tabela" — wygląd bierze z rolki przy kafelkach
   (`.in-cards-rolka`: zaokrąglenie, cień, tło), ale PROPORCJA jest inna.
   ⚠️ Rolka ma sztywne 9:16, bo tam leci nagranie pionowe (1080×1920). Tutaj
   plik jest POZIOMY (3840×2160) i w pionowym kadrze `object-fit: cover`
   przycinał mu boki tak, że z ujęcia zostawał środkowy pasek. Stąd kadr
   zbliżony do kwadratu — jak na produkcji — i szerszy, bo kolumna na to
   pozwala. Zgłoszone przez Bartka 21.08.2026. */
.in-media-rolka {
    width: min(100%, 440px);
    margin-inline: auto;
}
.in-media-rolka .in-cards-rolka-v {
    aspect-ratio: 1 / 1;
    height: auto;
}

/* ══════════════════════════════════════════════════════════════════════════
   KAFELKI OBOK PIONOWEJ ROLKI — wysokość z treści, film na całą kolumnę
   ──────────────────────────────────────────────────────────────────────────
   Dwa problemy zgłoszone przez Bartka 21.08.2026:

   1. Kafelki miały `min-height: 360px` — wartość dobraną pod rząd TRZECH
      kafelków z ikoną i długim opisem. W układzie 2×2 obok filmu, bez ikon,
      treść kończyła się w połowie i pod spodem została pusta połowa karty.
   2. Rolka trzymała sztywne 9:16, więc przy kolumnie kafelków wysokiej na
      744 px film miał 538 px i wisiał w powietrzu.

   Obie rzeczy tylko w sąsiedztwie filmu (`.in-cards-media`) i tylko na
   szerokim ekranie — w jednej kolumnie na telefonie sztywna wysokość i tak
   nie działa, a film w proporcji 9:16 jest tam w porządku.
   ══════════════════════════════════════════════════════════════════════════ */
@media (min-width: 981px) {
    .in-cards-media { align-items: stretch; }
    .in-cards-media > [class^="in-grid"] { align-items: stretch; }

    /* Wysokość z treści; równe kafelki robi `stretch` na siatce, nie liczba.
       ⚠️ Selektor musi zawierać `.in-sec.in-icon-cards`, bo reguła z 360 px
       ma trzy klasy — `.in-cards-media .in-card` (dwie) przegrywała z nią
       mimo późniejszego pliku. */
    .in-sec.in-icon-cards .in-cards-media .in-card { min-height: 0; }
    .in-sec.in-icon-cards .in-cards-media .in-card-b { padding: 32px 32px 34px; }
    /* Rezerwacja dwóch wierszy na tytuł ma sens w rzędzie po trzy, gdzie
       wyrównuje starty opisów. Przy „Ciało" i „Emocje" w układzie 2×2 dokłada
       tylko pusty wiersz. */
    .in-sec.in-icon-cards .in-cards-media .in-card-b h3 { min-height: 0; }

    /* Film dostaje dokładnie tyle, ile ma kolumna kafelków obok. */
    .in-cards-rolka { height: 100%; }
    .in-cards-rolka-v {
        height: 100%;
        aspect-ratio: auto;
        object-fit: cover;
    }
}

/* Karty produktów w taśmie — ta sama zasada co przy kafelkach: rosną do pełnej
   szerokości, ale nie kurczą się poniżej podstawy. Bez `flex-shrink: 0` cztery
   karty ścisnęłyby się do słupków. 21.08.2026 */
.in-sec.in-karuzela .in-pr-it {
    flex: 1 0 clamp(280px, 26vw, 380px);
    scroll-snap-align: start;
}

/* ══════════════════════════════════════════════════════════════════════════
   TAŚMY: pasek przewijania ukryty, cienie zdjęte
   ──────────────────────────────────────────────────────────────────────────
   Zasada z notatki o paskach przewijanych w bok: pasek jest ukryty, a pod
   spodem stoją strzałki — wszędzie tak samo. Reguły z prototypu zostawiały
   jednak widoczny pasek 6 px przy karuzeli kafelków i przy nowej taśmie
   produktów, a karty produktów niosły ze sobą cień, który w jednym rzędzie
   zlewał się w szarą smugę pod paskiem (ten sam problem, co przy kafelkach
   „czy to o Tobie?"). Zgłoszone przez Bartka 21.08.2026.
   ══════════════════════════════════════════════════════════════════════════ */
.in-sec.in-karuzela .in-grid2,
.in-sec.in-karuzela .in-grid3,
.in-sec.in-karuzela .in-grid4,
.in-sec.in-karuzela .in-pr-grid {
    scrollbar-width: none;          /* Firefox */
    -ms-overflow-style: none;       /* stare Edge */
}
.in-sec.in-karuzela .in-grid2::-webkit-scrollbar,
.in-sec.in-karuzela .in-grid3::-webkit-scrollbar,
.in-sec.in-karuzela .in-grid4::-webkit-scrollbar,
.in-sec.in-karuzela .in-pr-grid::-webkit-scrollbar {
    height: 0;
    display: none;
}
/* Dolna wyściółka robiła miejsce paskowi — bez paska jest zbędna. */
.in-sec.in-karuzela .in-grid2,
.in-sec.in-karuzela .in-grid3,
.in-sec.in-karuzela .in-grid4,
.in-sec.in-karuzela .in-pr-grid {
    padding-bottom: 4px;
}
.in-sec.in-karuzela .in-pr-it,
.in-sec.in-karuzela .in-pr-it:hover,
.in-sec.in-karuzela .in-pr-it:focus-visible {
    box-shadow: none;
}

/* ══════════════════════════════════════════════════════════════════════════
   WPROWADZENIE SEKCJI NA PEŁNĄ SZEROKOŚĆ
   ──────────────────────────────────────────────────────────────────────────
   Prototyp trzymał lead w kolumnie 860 px (`komponenty.css`) i dodatkowo
   w mierze 75 znaków (`szkielet.css`). Przy sekcji rozciągniętej na całą
   szerokość wyglądało to jak tekst ucięty do lewej połowy — zgłoszone przez
   Bartka 21.08.2026.

   Zdejmujemy oba ograniczenia dla leadu stojącego bezpośrednio w sekcji.
   ⚠️ Świadomy kompromis: przy 1440 px linijka ma ~100 znaków, czyli więcej
   niż typografia lubi. Jeśli kiedyś wróci „za długie linijki", to jest jedno
   miejsce do przywrócenia miary.

   Hero, CTA i kolumny przyklejone (`.in-services-head`, `.in-ct-head`,
   `.in-cert-head`) zachowują swoje miary — tam wąska szpalta jest częścią
   układu, a nie przypadkiem.
   ══════════════════════════════════════════════════════════════════════════ */
html body .in-sec > .in-wrap > .in-lead,
html body .in-sec > .in-wrap > .in-lead:first-of-type {
    max-width: none;
}

/* ⚠️ WYJĄTEK: sekcja z rozsypanymi kafelkami („Rozpoznajesz siebie w którymś
   z tych zdań?"). Tam kafelki są pozycjonowane absolutnie wokół środka ekranu,
   a tekst stoi w wąskim korytarzu między nimi. Reguła wyżej zdejmowała leadowi
   miarę i zdanie wjeżdżało pod kafelki — na 1440 px rozciągało się na 1296 px
   przy korytarzu szerokim na jakieś 640 px.

   Komponent ma własną miarę `min(54ch, 28vw)`, ale przegrywała: wariant
   `:first-of-type` wyżej liczy się jako cztery klasy plus dwa znaczniki,
   czyli więcej niż cztery klasy komponentu. Dlatego wyjątek musi mieć
   ten sam kształt selektora. Zgłoszone przez Bartka 22.08.2026. */
@media (min-width: 1400px) {
    html body .in-sec.in-rozsyp > .in-wrap > .in-lead,
    html body .in-sec.in-rozsyp > .in-wrap > .in-lead:first-of-type {
        max-width: min(54ch, 28vw);
    }
}

/* Odpowiedź w FAQ bywa wieloakapitowa i z wyliczeniem (od 21.08.2026 renderuje
   ją `wpautop`, nie `esc_html`). Ostatni akapit bez marginesu, żeby rozwinięta
   odpowiedź nie zostawiała pustego pasa nad krawędzią. */
.in-fq-a > p:last-child,
.in-faq-b .in-p > p:last-child { margin-bottom: 0; }
.in-fq-a ul,
.in-faq-b .in-p ul { margin: 10px 0 14px; padding-left: 1.2em; }
.in-fq-a li,
.in-faq-b .in-p li { margin-bottom: 6px; }

/* Podpis wykonawcy w stopce — ten sam stopień i kolor co dane spółki obok,
   żeby nie krzyczał bardziej od copyrightu. 21.08.2026 */
.in-ftr-autor {
    margin: 0;
    font-size: 13px;
    line-height: 1.5;
    color: var(--color-text-muted, #413B4D);
}
.in-ftr-autor a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }
.in-ftr-autor a:hover, .in-ftr-autor a:focus-visible { color: var(--brand-primary, #643B81); }

/* Krótki opis pakietu pod kwotą (`cennik` → „Krótki opis pod kwotą").
   Najdrobniejszy stopień w karcie: ma doprecyzować, co kupujesz, a nie
   konkurować z ceną nad sobą i listą pod sobą. 22.08.2026 */
.in-price-o {
    margin: 6px 0 18px;
    font-size: var(--t-small, 16px);
    line-height: 1.45;
    color: var(--color-text-muted, #413B4D);
}
.in-price--hl .in-price-o { color: rgba(255, 255, 255, .82); }

/* ── Odnośnik wpleciony w tekst sekcji ─────────────────────────────────────
   `szkielet.css` ustawia `a { color: inherit }` — bez tej reguły odnośnik
   „Poznaj warunki certyfikacji" w treści sekcji byłby nie do odróżnienia od
   zwykłego zdania. Podkreślenie odsunięte od liter, żeby ogonki (ą, ę, ż)
   nie siadały na kresce. 22.08.2026 */
.in-cert-link {
    margin: 18px 0 22px;
}
.in-cert-link a {
    color: var(--brand-primary, #643B81);
    font-weight: 700;
    text-decoration: underline;
    text-underline-offset: 4px;
    text-decoration-thickness: 2px;
}
.in-cert-link a:hover,
.in-cert-link a:focus-visible {
    color: var(--brand-800, #372047);
}

/* ── Rozsypane kafelki: bez strzałek karuzeli ──────────────────────────────
   Od 1400 px sekcja „Rozpoznajesz siebie w którymś z tych zdań?" przestaje
   być karuzelą: kafelki są pozycjonowane absolutnie i rozjeżdżają się wokół
   tekstu przy przewijaniu. Siatka wychodzi wtedy z przepływu, więc sterowanie
   karuzeli — normalnie POD kafelkami — wskakiwało tuż pod zdanie wprowadzające
   i wyglądało jak dwa przyciski donikąd. Nie ma czego przewijać, więc znika.
   Zgłoszone przez Bartka 22.08.2026 */
@media (min-width: 1400px) {
    .in-sec.in-rozsyp .in-kar-sterowanie {
        display: none;
    }
}

/* ── Drugi akapit wprowadzenia w hero na fiolecie ──────────────────────────
   `szkielet.css` daje `.in-hero-note` przygaszony ciemny kolor — dobry na
   białym tle wariantu „profil", nieczytelny na ciemnym fiolecie. Od 24.08.2026
   pole renderuje się także w wariancie z panelem (mentoring ma tam dwa
   akapity), więc potrzebuje własnego koloru. Ta sama miara co lead, żeby oba
   akapity tworzyły jedną kolumnę tekstu. */
.in-hero-purple .in-hero-note {
    color: rgba(255, 255, 255, .82);
    /* Ta sama miara co lead (760 px) — przy 60 znakach drugi akapit łamał się
       wcześniej niż pierwszy i wyglądało to jak dwa różne bloki tekstu. */
    max-width: 760px;
    margin: -8px 0 30px;
}

/* ── Tekst + tabela BEZ zdjęcia: pełna szerokość ───────────────────────────
   `.in-two` w szkielecie to siatka `1fr 1fr` — słusznie, bo komponent
   projektowano pod parę „tekst obok kadru". Gdy kadru nie ma (sekcja
   porównawcza na /mentoring/), tekst i tabela zostawały w lewej połowie,
   a prawa świeciła pustką: tabela miała 624 px przy 1296 px dostępnych.
   Szablon dokłada wtedy `--solo`, a tu rozkładamy to na pełną szerokość.
   Sama tabela też — jej `min-width: 520px` dobrany był pod wąską kolumnę.
   24.08.2026 */
.in-two.in-two--solo {
    display: block;
}
.in-two.in-two--solo .in-table {
    min-width: 0;
}
/* Proza potrzebuje miary, inaczej linijka ma ponad sto znaków i nie da się
   jej czytać. Ale 75 znaków (596 px) pod nagłówkiem na 1296 px wyglądało, jak
   gdyby tekst uciekał w lewy górny róg — zgłoszone przez Bartka 24.08.2026.
   Kompromis: w SZEROKICH sekcjach akapity idą w DWIE SZPALTY. Każda ma swoją
   miarę, więc czyta się dobrze, a blok wypełnia szerokość tak jak nagłówek
   i tabela pod nim. Poniżej 1100 px wraca jedna szpalta. */
.in-two.in-two--solo > div > .in-p {
    max-width: none;
}
@media (min-width: 1100px) {
    .in-two.in-two--solo > div {
        columns: 2;
        column-gap: 64px;
    }
    /* Nagłówek i tabela zostają na pełnej szerokości — łamiemy tylko akapity. */
    .in-two.in-two--solo > div > .in-tw,
    .in-two.in-two--solo > div > h2,
    .in-two.in-two--solo > div > .in-tags {
        column-span: all;
    }
    .in-two.in-two--solo > div > .in-p {
        break-inside: avoid;
        margin-bottom: 14px;
    }
}

/* ── Portret w sekcji o prowadzącej: mniej dominujący ──────────────────────
   Zmierzone na /mentoring/ przy 1440 px: kadr 587×733 px przy kolumnie tekstu
   wysokiej na 367 — zdjęcie dwa razy wyższe od tego, co obok. Im krótszy
   biogram, tym gorzej to wyglądało. Ograniczamy szerokość kadru i przycinamy
   go mocniej od góry: było `50% 15%`, czyli sporo powietrza nad głową.
   Zgłoszone przez Bartka 24.08.2026.

   Strona główna ma własny układ (`.in-fd`) i zostaje bez zmian. Na pozostałych
   stronach z tym komponentem tekst jest wyższy od zdjęcia (konsultacja 855 px,
   gra 588 px), więc mniejszy kadr im nie szkodzi. */
.in-sec.in-founder .in-fd-grid {
    /* Kadr i tekst rzadko mają tę samą wysokość — na mentoringu zdjęcie jest
       wyższe, na konsultacji tekst. Wyrównanie do góry zostawiało pod krótszą
       kolumną pustkę i całość wyglądała na przechyloną. Środek trzyma je razem.
       Zgłoszone przez Bartka 24.08.2026. */
    align-items: center;
}
.in-sec.in-founder .in-fd-media {
    width: 100%;
    max-width: 440px;
}
/* Kadr jest węższy od swojej kolumny (440 przy 587 px), więc dosuwamy go do
   tekstu zamiast zostawiać dziurę w środku sekcji. Bartek, 24.08.2026.

   ⚠️ TYLKO w układzie dwukolumnowym. Poniżej 1101 px sekcja układa się jedna
   pod drugą i `margin-left: auto` odpychało zdjęcie do prawej krawędzi ekranu,
   podczas gdy tekst zaczynał się przy lewej — zmierzone przy 900 px: kadr
   startował na 436, tekst na 24. */
@media (min-width: 1101px) {
    .in-sec.in-founder .in-fd-media {
        margin-left: auto;
    }
}
.in-sec.in-founder .in-fd-media img {
    aspect-ratio: 4 / 5;
    height: auto;
    object-position: 50% 32%;
}

/* ── Tabela w kolorach marki ───────────────────────────────────────────────
   Szapka miała szare tło i czarną kreskę pod spodem — na fioletowo-lawendowej
   stronie wyglądała jak wklejona z arkusza kalkulacyjnego. Teraz nagłówek
   siedzi na firmowym fiolecie, a linie wierszy biorą kolor z tej samej rodziny
   zamiast z czerni. Zgłoszone przez Bartka 24.08.2026. */
.in-table thead th {
    background: var(--brand-primary, #643B81);
    color: var(--brand-on-primary, #fff);
    border-bottom: 0;
    font-weight: 600;
}
.in-table thead th:first-child {
    border-radius: 14px 0 0 0;
}
.in-table thead th:last-child {
    border-radius: 0 14px 0 0;
}
.in-table thead ~ tbody tr:nth-child(odd) td {
    background: var(--brand-50, #f3eff5);
}
.in-table thead ~ tbody td {
    border-bottom: 1px solid var(--brand-100, #e8e2ec);
}
.in-table thead ~ tbody tr:last-child td {
    border-bottom: 0;
}
/* Etykieta wiersza w kolorze marki — pierwsza kolumna nadal ma prowadzić oko. */
.in-table thead ~ tbody td:first-child {
    color: var(--brand-800, #372047);
    font-weight: 600;
}

/* ── Wprowadzenie w sekcji modułów ─────────────────────────────────────────
   To samo zgłoszenie co wyżej: nagłówek szedł na 1120 px, a wprowadzenie
   kończyło się na 541 (68 znaków) i wyglądało na zgubione przy lewej krawędzi.
   Tu dwie szpalty nie mają sensu, bo to jedno zdanie — poszerzamy miarę do 90
   znaków, czyli 720 px. Dłuższe linijki byłyby już męczące. 24.08.2026 */
@media (min-width: 1100px) {
    .in-showcase-copy > .in-lead {
        max-width: 90ch;
    }
}

/* ── Karty cennika: wspólne wiersze, ceny na jednej linii ──────────────────
   Karty różnią się liczbą elementów w nagłówku: wyprzedana ma nad nazwą
   plakietkę „Wyprzedane", a nazwa pakietu raz mieści się w jednym wierszu,
   raz w dwóch („PAKIET STANDARD (3 MODUŁY) — POLECANE"). Przy zwykłym
   układzie kolumnowym każda kwota lądowała więc na innej wysokości, a pod
   nimi rozjeżdżało się wszystko dalej. Zgłoszone przez Bartka 24.08.2026.

   Rozwiązanie: siatka sekcji dostaje nazwane wiersze, a każda karta wchodzi
   w nią przez `subgrid` i przypisuje swoje części do KONKRETNYCH wierszy.
   Dzięki temu brak elementu (np. plakietki) zostawia pusty wiersz zamiast
   przesuwać resztę. Wysokość wiersza bierze się z najwyższej karty, więc
   kwoty, opisy, listy i przyciski stoją równo we wszystkich trzech.

   Tylko od 861 px — niżej karty układają się jedna pod drugą i nie ma czego
   równać. */
@media (min-width: 861px) {
    .in-sec.in-pricing .in-grid2,
    .in-sec.in-pricing .in-grid3 {
        /* plakietka | nazwa | kwota | opis | „cena obejmuje" | lista | przycisk */
        grid-template-rows: auto auto auto auto auto 1fr auto;
    }
    .in-sec.in-pricing .in-price {
        display: grid;
        grid-row: span 7;
        grid-template-rows: subgrid;
        row-gap: 0;
    }
    .in-sec.in-pricing .in-price-brak {
        grid-row: 1;
        /* W siatce element domyślnie rozciąga się na całą kolumnę — plakietka
           ma zostać pigułką na miarę napisu. */
        justify-self: start;
    }
    .in-sec.in-pricing .in-price-l    { grid-row: 2; }
    .in-sec.in-pricing .in-price-v    { grid-row: 3; }
    .in-sec.in-pricing .in-price-o    { grid-row: 4; }
    .in-sec.in-pricing .in-price-n    { grid-row: 5; }
    .in-sec.in-pricing .in-price .in-check { grid-row: 6; }
    .in-sec.in-pricing .in-price .in-btn {
        grid-row: 7;
        /* W siatce `margin-top: auto` z układu kolumnowego nie ma już sensu —
           przycisk i tak siedzi w ostatnim wierszu. */
        margin-top: 0;
        justify-self: start;
        align-self: end;
    }
}

/* ── Cennik z TRZEMA pakietami: wprowadzenie pod nagłówkiem ────────────────
   `komponenty.css` sadza w prawej kolumnie tylko `.in-grid2` i pojedynczą
   `.in-price` — siatka TRZECH pakietów nie była wymieniona, więc lądowała tam
   automatem i zajmowała wiersze po kolei. Wprowadzenie „Wybierz opcję, która
   najbardziej Ci odpowiada…" wypadało przez to POD kartami zamiast pod
   nagłówkiem: zmierzone y=6866 przy nagłówku na 6278. Bartek, 24.08.2026. */
@media (min-width: 861px) {
    .in-sec.in-pricing > .in-wrap > .in-grid3 {
        grid-column: 2;
        grid-row: 1 / -1;
        align-items: stretch;
    }
}

/* ── Karty cennika nie mogą się przelewać ──────────────────────────────────
   Zgłoszone przez Bartka 24.08.2026: między 862 a 1280 px treść PIERWSZEJ
   karty wychodziła poza jej krawędź — do 53 px przy 862 px. Kolumny siatki
   dzielą szerokość po równo (`1fr`), więc wszystkie karty są tej samej
   szerokości, a pierwsza ma najdłuższą etykietę („KONSULTACJA INDYWIDUALNA
   (1 SPOTKANIE)") pisaną wersalikami z rozstrzeleniem .14em.

   Element siatki ma domyślnie `min-width: auto` i nie da się go ścisnąć
   poniżej najdłuższego słowa — dlatego karta zwężała się razem z kolumną,
   a jej zawartość zostawała przy swojej szerokości i wystawała.

   Trzy rzeczy naraz: pozwalamy kartom i ich częściom zejść poniżej
   min-content, łamiemy długie etykiety, i pozwalamy jednostce ceny
   („zł / konsultacja") przejść do nowego wiersza zamiast pchać kwotę w bok. */
.in-sec.in-pricing .in-price,
.in-sec.in-pricing .in-price > * {
    min-width: 0;
}
.in-sec.in-pricing .in-price-l {
    overflow-wrap: break-word;
    hyphens: auto;
}
/* ⚠️ Kwota i jednostka zostają W JEDNEJ LINII i w SWOICH stopniach pisma.
   Historia tego miejsca, żeby nikt nie wracał do ślepych zaułków:
     1. `flex-wrap: wrap` — jednostka schodziła pod kwotę. Bartek: „to
        przenoszenie zł na dół nie przejdzie".
     2. Płynny stopień kwoty i jednostki — mieściło się, ale Bartek:
        „wielkości masz nie zmieniać".
   Rozwiązanie przyszło od strony treści, nie stylu: jednostka to teraz samo
   „zł", bez dopisku „/ konsultacja" i „/ pakiet". Przy 278 px karty sama
   liczba w 52 px plus krótkie „zł" mieszczą się z zapasem, na każdej
   szerokości. 24.08.2026 */
.in-sec.in-pricing .in-price-v {
    flex-wrap: nowrap;
}
.in-sec.in-pricing .in-price-c {
    white-space: nowrap;
}

/* ── Cennik: układ jednokolumnowy WCZEŚNIEJ ────────────────────────────────
   Sekcja dzieli szerokość na 4/12 dla nagłówka i 8/12 dla kart, a układ
   schodził do jednej kolumny dopiero poniżej 861 px. W przedziale 861–1100 px
   trzy karty dostawały po 200–224 px, z czego po odjęciu wyściółki zostawało
   136–160 px na wiersz z ceną — a „4 590 zł" w 52 px potrzebuje 149 px.
   Kwota z jednostką nie miała prawa się zmieścić.

   Zamiast zmniejszać pismo (Bartek: „wielkości masz nie zmieniać"), oddajemy
   kartom całą szerokość sekcji już od 1100 px. Nagłówek i wprowadzenie idą
   wtedy nad karty, tak jak na telefonie. 24.08.2026 */
@media (max-width: 1100px) {
    .in-sec.in-pricing > .in-wrap {
        grid-template-columns: 1fr;
        gap: 32px;
    }
    .in-sec.in-pricing > .in-wrap > h2,
    .in-sec.in-pricing > .in-wrap > .in-lead,
    .in-sec.in-pricing > .in-wrap > .in-note,
    .in-sec.in-pricing > .in-wrap > .in-grid2,
    .in-sec.in-pricing > .in-wrap > .in-grid3,
    .in-sec.in-pricing > .in-wrap > .in-price {
        grid-column: 1;
        grid-row: auto;
    }
    .in-sec.in-pricing > .in-wrap > h2 { margin-bottom: 0; }
}

/* ── Hero „samo zdjęcie": bez szklanej ramki ───────────────────────────────
   Wariant `--sama-foto` zerował w komponencie tło, obramowanie i cień, ale
   NIE rozmycie tła (`backdrop-filter: blur(12px)`) ani zaokrąglenia. Rozmycie
   działa na to, co jest ZA elementem, więc mimo przezroczystego tła rysowało
   na gradiencie hero wyraźny, zaokrąglony prostokąt wokół portretu — wyglądało
   jak druga ramka wokół zdjęcia. Zgłoszone przez Bartka 24.08.2026. */
/* ⚠️ Celujemy w PANEL, KTÓRY MA W ŚRODKU WYŁĄCZNIE ZDJĘCIE — nie w klasę
   `--sama-foto`. Szablon dokłada tę klasę tylko wtedy, gdy panel nie ma
   żadnych pól; na /konsultacja/ panel jest „pusty" inaczej: pola nagłówka
   i pozycji są puste, ale warunek w PHP i tak wybiera gałąź z pełnym panelem,
   więc zdjęcie ląduje w zwykłym `.in-hero-panel` ze szklaną ramką. */
@media (min-width: 981px) {
    .in-hero-purple > .in-wrap { position: relative; }
    .in-hero-purple .in-hero-panel:not(.in-hero-panel--sama-foto):not(:has(> .in-hero-panel-foto:only-child)) {
        position: absolute;
        right: 30px;
        top: 0;
        width: 300px;
    }
}

.in-hero-panel--sama-foto,
.in-hero-panel:has(> .in-hero-panel-foto:only-child) {
    padding: 0;
    background: none;
    border: 0;
    box-shadow: none;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    border-radius: 0;
}

/* ── Tytuł kafelka nie wchodzi pod numer ───────────────────────────────────
   Numer w rogu (`::after`, 56 px pisma) jest pozycjonowany absolutnie, więc
   nie odpycha tekstu — przy szerokim oknie tytuł się w nim mieścił, ale gdy
   kafel się zwężał, „Konkret nauki i pedagogiki" wchodziło wprost pod cyfrę.

   ⚠️ Pierwsze podejście (24.08) rezerwowało 96 px WYŚCIÓŁKI. Za dużo:
   `komponenty.css` daje temu nagłówkowi `max-width: 20ch`, czyli 264 px przy
   22 px pisma, a wyściółka zjadała z tego 96 — na tytuł zostawało 168 px
   i „Duchowość buddyjska" (221 px) łamała się na dwa wiersze bez powodu,
   choć w kafelku było 349 px miejsca. Zgłoszone przez Bartka tego samego dnia.

   Teraz ograniczamy SZEROKOŚĆ tytułu względem kafelka zamiast dokładać
   wyściółkę. Zmierzone przy 1440 px: kafel 417 px, wyściółka 34 px z każdej
   strony, numer 52–64 px stojący 30 px od krawędzi — czyli cyfra zaczyna się
   290 px od lewej krawędzi tekstu. `calc(100% - 76px)` daje tytułowi 273 px,
   zostaje 16 px odstępu, a wszystkie trzy tytuły mieszczą się w jednym wierszu.
   Zaleta względem wyściółki: miara skaluje się z kafelkiem, więc na wąskim
   ekranie odstęp zostaje, a na szerokim nie marnujemy miejsca. */
.in-sec.in-feature .in-card-b h3 {
    max-width: calc(100% - 76px);
    padding-right: 0;
}

/* ══════════════════════════════════════════════════════════════════════════
   DANE DO KONSULTACJI W FORMULARZU REZERWACJI
   ──────────────────────────────────────────────────────────────────────────
   Trzy pola pod kalendarzem: data urodzenia, imię i nazwisko z urodzenia,
   zdanie o intencji. Zamówione przez Bartka 24.08.2026.

   Data idzie w trzech listach obok siebie. Kolumny nie są równe, bo i dane
   nie są: „dzień" to dwie cyfry, „października" jedenaście znaków, rok cztery
   cyfry. Równy podział dawał listę miesięcy uciętą wielokropkiem przy pełnej
   szerokości kolumny obok.
   ────────────────────────────────────────────────────────────────────────── */
.in-rez-dane {
    /* ⚠️ Ten blok jest KAFELKIEM w siatce formularza (`.in-form-g`, dwie
       kolumny), a nie kolejną sekcją pod nią — bez tego siedział w lewej
       połowie i pola miały 331 px przy 691 px szerokości formularza.
       Sam w sobie jest też siatką, więc jego pola układają się dalej normalnie. */
    grid-column: 1 / -1;
    margin-bottom: 26px;
}
.in-rez-data {
    display: grid;
    grid-template-columns: 5.5rem 1fr 6.5rem;
    gap: 10px;
}
/* Na telefonie trzy listy w rzędzie robią się węższe niż ich własne napisy —
   miesiąc dostaje wtedy całą szerokość w drugim wierszu. */
@media (max-width: 480px) {
    .in-rez-data {
        grid-template-columns: 1fr 1fr;
    }
    .in-rez-data select:nth-child(2) {
        grid-column: 1 / -1;
        order: 3;
    }
}
.in-rez-dane textarea {
    resize: vertical;
    min-height: 3.4em;
}

/* ══════════════════════════════════════════════════════════════════════════
   MENU: PŁYNNY STOPIEŃ I ODSTĘPY MIĘDZY 1100 A 1440 px
   ──────────────────────────────────────────────────────────────────────────
   Menu desktopowe włącza się od 1100 px i to jest jego najciaśniejszy punkt:
   zmierzone przy 1100 px pigułka ma 1052 px, a jej zawartość potrzebuje
   1018 px — zostają 34 px zapasu na dziewięć pozycji. Wystarczy inna wersja
   kroju, dłuższa etykieta w menu albo dwucyfrowy licznik w koszyku i ikona
   torby wychodzi poza pigułkę. Tak to wyglądało u Bartka (24.08.2026).

   Zamiast kolejnego progu w @media dajemy wartości PŁYNNE: przy 1100 px menu
   jest ciasne, przy 1440 px wraca dokładnie do wartości z prototypu i wyżej
   już się nie zmienia. Każda z tych funkcji przechodzi przez te same dwa
   punkty (1100 → minimum, 1440 → wartość docelowa), więc menu ściska się
   równomiernie, a nie skokami.

   ⚠️ Reguły stoją TUTAJ, nie w `szkielet.css` — tamten plik jest generowany
   z prototypu przez `wytnij-css.py` i każda ręczna poprawka w nim ginie przy
   następnym przebudowaniu.
   ────────────────────────────────────────────────────────────────────────── */
@media (min-width: 1100px) {
    /* odstęp: 2 px przy 1100, 6 px od 1440 */
    .in-nav > ul {
        gap: clamp(2px, 1.18vw - 10.9px, 6px);
    }
    /* stopień pisma: 12 px przy 1100, 14 px od 1440 */
    .in-nav-l {
        font-size: clamp(12px, 0.59vw + 5.5px, 14px);
        padding-inline: clamp(7px, 1.18vw - 5.9px, 11px);
    }
    /* rozwijane („Numeroterapia", „Oferta") mają własny, mniejszy stopień */
    .in-dd-btn {
        font-size: clamp(11px, 0.59vw + 4.5px, 13px);
        padding-inline: clamp(10px, 1.18vw - 2.9px, 14px);
    }
    /* strzałka przy rozwijanym też się kurczy, inaczej zjada odzyskane miejsce */
    .in-dd-btn {
        gap: clamp(3px, 0.88vw - 6.7px, 6px);
    }
    /* odstępy w samej pigułce: znak – menu – ikony */
    .in-pill {
        gap: clamp(12px, 2.35vw - 13.9px, 20px);
    }
}

/* ══════════════════════════════════════════════════════════════════════════
   HERO Z PASEM LICZB — ma się mieścić na jednym ekranie
   ──────────────────────────────────────────────────────────────────────────
   Zgłoszenie Bartka 24.08.2026: liczby pod przyciskami („1,5 h", „2", „20+")
   wypadały poniżej krawędzi ekranu, a odstępy w hero były „gigantyczne".

   Zmierzone PRZED zmianą przy oknie 1440×900: hero 1123 px przy ekranie
   900 px, z czego 364 px to sama wyściółka (144 u góry, 220 u dołu), 72 px
   odstęp w siatce, a pas liczb łamał się na DWA wiersze, bo trzy pozycje
   potrzebowały 742 px przy kolumnie szerokiej na 612 px. Liczby kończyły się
   na 905 px — pięć pikseli pod krawędzią. Przy oknie 800 px było to 89 px.

   Trzy cięcia, każde zmierzone:
   1. wyściółka górna 144 → ok. 88 px (nagłówek strony ma 64 px wysokości,
      więc więcej niż jego wysokość plus oddech jest marnowane),
   2. wygaszenie gradientu u dołu — mnożnik z 0,75 na 0,42 i niższy zakres;
      pas liczb i tak stoi NAD jasną częścią, więc zapasu było za dużo,
   3. pas liczb jako siatka TRZECH równych kolumn zamiast zawijanego rzędu —
      etykiety łamią się wtedy wewnątrz swojej kolumny i wszystko mieści się
      w jednym wierszu.

   ⚠️ `min-height` wrapa liczy się od `100svh` minus obie wyściółki, więc
   zmniejszenie wyściółki NIE robi hero niższym, dopóki treść się w nim mieści
   — dopiero gdy treść przerasta ten limit, cięcia zaczynają działać. Dlatego
   punkt 3 jest tu równie ważny jak 1 i 2.
   ────────────────────────────────────────────────────────────────────────── */
@media (min-width: 1101px) {
    .in-hero.in-hero-purple-kpis {
        padding-top: clamp(80px, 6vw, 96px);
        --in-fade: clamp(180px, 20vh, 280px);
        --in-fade-safe: calc(var(--in-fade) * .42 + 18px);
    }
    .in-hero.in-hero-purple-kpis > .in-wrap {
        row-gap: 24px;
    }
    /* Trzy równe kolumny zamiast `flex-wrap`. `minmax(0, 1fr)`, bo bez zera
       najdłuższa etykieta („lat doświadczenia w pracy z podświadomością")
       rozpycha swoją kolumnę i wracamy do zawijania. */
    .in-hero.in-hero-purple-kpis .in-hero-kpis {
        display: grid;
        grid-template-columns: repeat(3, minmax(0, 1fr));
        gap: 0 clamp(18px, 2vw, 32px);
        padding-top: 18px;
    }
}

/* ── Miara nagłówka hero po zejściu do 36 px ──────────────────────────────
   `komponenty.css` daje `.in-hero-sub h1 { max-width: 20ch }`. Przy stopniu
   64 px to było ~890 px, czyli więcej niż szpalta — reguła nie robiła nic.
   Po zejściu hero do skali treści (36 px, 24.08.2026) 20ch to ~356 px przy
   szpalcie 612 px: nagłówek zwężał się do połowy dostępnego miejsca, a że
   „numeroterapeutyczna." samo w sobie potrzebuje ~356 px, przeglądarka
   zaczęła je DZIELIĆ — „Konsultacja nume-roterapeutyczna.".

   28ch (~500 px) mieści najdłuższy wyraz z zapasem, więc dzielenie przestaje
   być potrzebne, a nagłówek nadal nie rozciąga się na całą szpaltę.
   `min(100%, …)` pilnuje węższych okien. */
.in-hero-sub h1,
.in-hero-purple h1,
.in-hero-purple-kpis h1 {
    max-width: min(100%, 28ch);
}

/* Nota prawna w stopce — mniejsza od opisu i wyciszona, bo to zastrzeżenie,
   nie zdanie o marce. Dołożona 24.08.2026 wraz z polem `stopka_nota`. */
.in-ftr-nota {
    margin-top: 10px;
    font-size: var(--t-small, 14px);
    line-height: 1.5;
    opacity: .72;
}

/* ══════════════════════════════════════════════════════════════════════════
   NAGŁÓWEK STRONY GŁÓWNEJ — koniec z zakazem zawijania
   ──────────────────────────────────────────────────────────────────────────
   `strony/index.css` daje `.in-xh-h { max-width: none; text-wrap: nowrap }`.
   Miało to sens przy dawnym nagłówku: „Odkryj swój potencjał / i uwolnij się
   od blokad." to DWA krótkie zdania łamane ręcznym `<br>`, a `nowrap` pilnował,
   żeby każde stało w swojej linijce.

   Wytyczne z 24.08.2026 dają jedno długie zdanie bez `<br>` — „Odkryj wzorce,
   które kierują Twoimi decyzjami." Przy zakazie zawijania nie miało jak się
   złamać i wychodziło poza kolumnę, pod portret Olgi. Zmierzone przy 1280 px:
   napis potrzebuje 742 px, a kolumna ma 686.

   Pozwalamy zawijać i ograniczamy miarę, żeby nagłówek nigdy nie wszedł pod
   zdjęcie. `balance` wyrówna długość wierszy.

   ⚠️ Reguła stoi tutaj, bo `strony/index.css` jest generowany z prototypu.
   Ładuje się PO `motyw.css`, więc potrzebny jest `html body` — inaczej przy
   równej szczegółowości wygrywa plik ładowany później.
   ────────────────────────────────────────────────────────────────────────── */
html body .in-xh-h {
    text-wrap: balance;
    white-space: normal;
    max-width: min(100%, 28ch);
}

/* ══════════════════════════════════════════════════════════════════════════
   OPINIE NA STRONIE GŁÓWNEJ — równe wysokości kart
   ──────────────────────────────────────────────────────────────────────────
   `strony/index.css` ma tu `align-items: start` na taśmie i `align-self: start`
   na kartach, z komentarzem z 13.08: „karty układają się do treści — krótka
   opinia daje krótką kartę". Skutek uboczny: dolne krawędzie czterech kafli
   stoją na czterech różnych wysokościach. Zmierzone przy 1440 px:
   479, 448, 541 i 572 px.

   Podstrony mają to inaczej — `komponenty.css` daje im `align-items: stretch`
   i podpis dosunięty do dołu. Bartek prosi (24.08.2026), żeby strona główna
   zachowywała się tak samo, więc zrównujemy.

   ⚠️ Sam `stretch` na taśmie nie wystarczy: `align-self: start` na karcie jest
   silniejsze od `align-items` rodzica. Trzeba zdjąć jedno i drugie.

   ⚠️ Podpis (imię nad kreską) musi dostać `margin-top: auto`, inaczej przy
   krótkim cytacie zawiśnie w połowie wysokiej karty — to jest dokładnie ten
   problem, przed którym bronił się komentarz z 13.08.
   ────────────────────────────────────────────────────────────────────────── */
html body .in-sec.in-testimonials .in-tm-track {
    align-items: stretch;
}
html body .in-sec.in-testimonials .in-tm-it {
    align-self: stretch;
    /* Bez cienia — prośba Bartka 24.08.2026. Podstrony mają te karty płaskie,
       na obwódce; na stronie głównej wisiał pod nimi `0 18px 46px` w fiolecie
       i przy równych wysokościach rząd wyglądał jak cztery unoszące się płyty. */
    box-shadow: none;
}
html body .in-sec.in-testimonials .in-tm-it > figcaption,
html body .in-sec.in-testimonials .in-tm-it > .in-tm-a {
    margin-top: auto;
}

/* Etykieta kolumny stopki przejmuje wygląd dawnego `h3` — od 24.08.2026 to
   `<p class="in-ftr-kol-h">` wewnątrz `<nav aria-labelledby>`, bo nazwa grupy
   odnośników nie jest nagłówkiem treści (patrz `inc/menu.php`). Reguła
   w `szkielet.css` celuje w `h3`, więc powtarzamy tu jej część wizualną. */
.in-ftr .in-ftr-kol-h {
    margin: 0 0 20px;
    color: rgba(255, 255, 255, .62);
    font-family: var(--font-heading, 'Baloo 2', sans-serif);
    font-weight: var(--t-waga-naglowka);
}
@media (max-width: 768px) {
    .in-ftr .in-ftr-kol-h { margin-bottom: 10px; }
}

/* Tytuł kroku w sekcji „proces" bierze stopień ze skali (klasa `in-h3`),
   więc komponentowe `font-size: 18px` z `komponenty.css` musi ustąpić.
   Kolor zostaje fioletowy — Bartek 24.08.2026: „ten fiolet tu pasuje".
   Waga jak w nagłówkach, nie 600 z prototypu. */
html body .in-showcase-step-t {
    /* Znacznik to od 24.08.2026 `<h3>`, więc stopień i wagę daje skala.
       Zostaje kolor marki („ten fiolet tu pasuje") oraz zerowanie marginesów,
       bo nagłówek wnosi własne, a kafelek ma swój rytm. */
    margin: 0 0 10px;
    color: var(--brand-primary, #643B81);
}

/* ══════════════════════════════════════════════════════════════════════════
   SEKCJA KROKÓW — nagłówek przyklejony przy przewijaniu
   ──────────────────────────────────────────────────────────────────────────
   Układ jest dwukolumnowy: po lewej nagłówek z wprowadzeniem, po prawej lista
   kroków. Prawa kolumna bywa wysoka (na stronie głównej trzy kroki po kilka
   wierszy), więc przy przewijaniu lewa uciekała w górę i przez większość
   sekcji stała pusta kolumna. Zgłoszone przez Bartka 24.08.2026.

   `104px` to ta sama wartość, co `scroll-margin-top` kotwic w `szkielet.css` —
   wysokość przyklejonej pigułki nawigacji plus oddech.

   ⚠️ Tylko od 981 px. Niżej siatka schodzi do jednej kolumny (reguła
   w `komponenty.css`), więc przyklejanie nie miałoby czego trzymać, a na
   telefonie zjadałoby ekran.

   ⚠️ `align-items: start` na siatce jest warunkiem działania — element
   rozciągnięty na całą wysokość wiersza nie ma się jak przesuwać. Siatka ma
   to już ustawione, więc nie dokładamy.
   ────────────────────────────────────────────────────────────────────────── */
@media (min-width: 981px) {
    .in-sec.in-st .in-st-head {
        position: sticky;
        top: 104px;
    }
}

/* Przycisk pod wprowadzeniem w sekcji krokow (prosba Olgi z 27.08.2026 —
   „i moze pod tym — zrob sobie test"). Akapit `.in-lead` konczy sie wlasnym
   marginesem, wiec tutaj dokladamy tylko odstep, ktory oddziela przycisk od
   tekstu, i nic pod nim — nizej jest juz koniec kolumny. */
.in-sec.in-st .in-st-cta { margin: 26px 0 0; }

/* ══════════════════════════════════════════════════════════════════════════
   PRZYCISKI SKŁADAJĄ SIĘ PRZY ŚCISKANIU — reguła uniwersalna
   ──────────────────────────────────────────────────────────────────────────
   Prototyp dawał przyciskom `white-space: nowrap`, żeby krótka etykieta nie
   łamała się na dwa wiersze. Przy długich napisach („Umów konsultację
   z numeroterapeutką") kończyło się to inaczej: przycisk nie miał jak się
   zwęzić i wychodził poza panel. Zmierzone przy 390 px: panel dawał 308 px
   na treść, a przyciski miały 350 — po 21 px poza zaokrąglony róg z każdej
   strony. Zgłoszone przez Bartka 24.08.2026.

   Zamiast progu na telefon robimy to UNIWERSALNIE, o co Bartek prosił:
   przycisk nigdy nie przekracza swojego pojemnika, a etykieta zawija się
   dopiero wtedy, gdy naprawdę brakuje miejsca. Przy szerokim ekranie nic się
   nie zmienia, bo miejsca nie brakuje.

   ⚠️ Kółko ze strzałką ma `flex: 0 0 auto` w komponentach, więc nie ściska się
   razem z tekstem — zawija się sam napis, a strzałka zostaje okrągła.

   ⚠️ Nierozdzielność fraz („z Olgą N. Stępińską") załatwiają twarde spacje
   po stronie PHP (`instytut_frazy_nierozdzielne()`), nie CSS. Dzięki temu
   przycisk łamie się przed „z", a nie w środku nazwiska.
   ────────────────────────────────────────────────────────────────────────── */
html body :is(
    .in-btn,
    .in-btn-ghost,
    .in-cb-btn,
    .in-nav-cta,
    .in-cta-btn2
) {
    max-width: 100%;
    white-space: normal;
    /* ⚠️ Wyrównanie do lewej, nie dziedziczone. Sekcja wezwania ma
       `text-align: center` na całym panelu (`.in-cb-inner`), więc złamana
       etykieta środkowała się względem przycisku i drugi wiersz „pływał".
       Przy strzałce dosuniętej do prawej krawędzi tekst ma zaczynać się równo
       od lewej. Zgłoszone przez Bartka 24.08.2026. */
    text-align: left;
}
/* Etykieta ma się zawijać w swojej kolumnie, a nie rozpychać przycisku —
   bez tego flex liczy szerokość od najdłuższego wyrazu. */
html body :is( .in-btn, .in-btn-ghost, .in-cb-btn ) > span {
    min-width: 0;
}

/* ══════════════════════════════════════════════════════════════════════════
   PASKI PRZEWIJANE W BOK — ucięcie na KRAWĘDZI OKNA, nie w środku sekcji
   ──────────────────────────────────────────────────────────────────────────
   Wszystkie karuzele wychodziły poza gutter TYLKO w prawo (`margin-right`
   ujemny plus `padding-right`). Przy przewinięciu pierwsza karta była więc
   ucinana pionową krawędzią W ŚRODKU sekcji — wygląda to jak błąd renderowania,
   a nie jak kafelek wjeżdżający pod brzeg strony. Bartek zgłosił to trzy razy
   pod rząd 24.08.2026: na opiniach, na kartach produktowych i na blogu.

   Dlatego reguła jest jedna i obejmuje WSZYSTKIE paski naraz — te obsługiwane
   przez `karuzela.js` (kafelki, produkty, wpisy), pasek opinii i galerię.
   Wypust jest symetryczny: karta w spoczynku nadal zaczyna się przy kolumnie
   tekstu (bo tyle samo dokładamy jako wyściółkę), a przy przewijaniu chowa się
   pod krawędź okna.

   `scroll-padding-inline` pilnuje, żeby przyciąganie zatrzymywało karty równo
   z kolumną, a nie z krawędzią ekranu.
   ────────────────────────────────────────────────────────────────────────── */
html body :is(
    .in-karuzela .in-grid2,
    .in-karuzela .in-grid3,
    .in-karuzela .in-grid4,
    .in-karuzela .in-pr-grid,
    .in-sec.in-testimonials .in-tm-track,
    .in-gal--kar .in-tm-track,
    .in-tw-siatka
) {
    margin-inline: calc(-1 * var(--in-hgut));
    padding-inline: var(--in-hgut);
    scroll-padding-inline: var(--in-hgut);
}

/* Rząd zdań ma wypust tylko póki JEST paskiem — od 1400 px kafelki rozsypują
   się wokół nagłówka i są pozycjonowane absolutnie, więc nie ma czego wypuszczać. */
@media (max-width: 1399px) {
    html body .in-sec.in-zdania .in-zd-grid {
        margin-inline: calc(-1 * var(--in-hgut));
        padding-inline: var(--in-hgut);
        scroll-padding-inline: var(--in-hgut);
    }
}

/* Wezwanie z kartą ceny: kolumna z tekstem dosunięta do GÓRY, równo z kartą
   po prawej. `komponenty.css` daje jej `justify-content: flex-end`, więc
   nagłówek siadał na dole i przy niskiej karcie powstawał uskok — nagłówek
   zaczynał się grubo poniżej krawędzi karty. Zgłoszone przez Bartka
   24.08.2026: „niech się zaczyna tak jak ten kwadrat po prawo".

   ⚠️ Razem z tym musi zniknąć `margin-bottom: auto` z nadtytułu — to on
   rozpychał kolumnę, trzymając etykietę u góry, a resztę u dołu. */
.in-cta--karty .in-cta-main {
    justify-content: flex-start;
}
.in-cta--karty .in-cta-tag {
    margin-bottom: 18px;
}

/* Wezwanie z kartą ceny: prawa kolumna też do góry, i sekcja niższa.
   `komponenty.css` daje jej `align-self: end`, więc karta z ceną siadała
   na dole i stała niżej niż nagłówek obok. Do tego cały blok ma
   `min-height: 58svh` i wyściółkę do 92 px — przy tak krótkiej treści
   zostawało pół ekranu pustego fioletu. Zgłoszone przez Bartka 24.08.2026.

   ⚠️ Zmiany dotyczą TYLKO wariantu z kartami (`--karty`). Zwykłe wezwanie na
   końcu stron korzysta z tego samego `.in-cta-inner`, a tam wysokość na pół
   ekranu jest zamierzona — to duża plansza z jednym zdaniem. */
.in-cta--karty .in-cta-inner {
    min-height: 0;
    padding-block: clamp(44px, 4.5vh, 60px);
}
.in-cta--karty .in-cta-side {
    align-self: start;
}

/* ══════════════════════════════════════════════════════════════════════════
   JASNY PASEK NAD HERO — kilka pikseli tła strony
   ──────────────────────────────────────────────────────────────────────────
   Nagłówek jest przyklejony, ale zajmuje miejsce w układzie, więc hero wjeżdża
   pod niego ujemnym marginesem. Wartość była policzona na 96 px (i 82 px na
   telefonie), a nagłówek ma w rzeczywistości 98–99 px (i 84 px) — pigułka ma
   po 1 px obwódki u góry i u dołu, do tego zaokrąglenia sub-pikselowe.
   Zostawały 2–3 px tła strony nad fioletem, na KAŻDEJ szerokości.
   Zgłoszone przez Bartka 24.08.2026.

   Ciągniemy z zapasem, a nie „co do piksela": górna wyściółka hero ma 128–200
   px, więc kilka pikseli więcej jest niewidoczne, a pasek nie wróci przy
   następnej zmianie obwódki czy wysokości pigułki.
   ────────────────────────────────────────────────────────────────────────── */
html body :is(
    .in-hero-purple,
    .in-contact-hero,
    .in-xh
) {
    margin-top: -104px;
}
/* ⚠️ Próg 600 px, nie 860 — komponenty zmniejszają nagłówek dopiero tam
   (`@media (max-width: 600px)`). Przy 768 px nagłówek nadal ma 98 px i mój
   pierwszy strzał w 860 px odsłonił pasek z powrotem. Zmierzone. */
@media (max-width: 600px) {
    html body :is(
        .in-hero-purple,
        .in-contact-hero,
        .in-xh
    ) {
        margin-top: -92px;
    }
}

/* ══════════════════════════════════════════════════════════════════════════
   LISTA OSÓB NA TELEFONIE — TAŚMA Z KART DOKŁADNIE TAKICH JAK NA DESKTOPIE
   ──────────────────────────────────────────────────────────────────────────
   Bartek 25.08.2026, po kilku podejściach: „niech to będzie ten sam komponent
   co desktop, tylko 250 px", w taśmie przewijanej w bok.

   ⚠️ TO NIE JEST SAMO USTAWIENIE SZEROKOŚCI. `komponenty.css` w
   `@media (max-width: 760px)` PRZEBUDOWUJE kartę: kładzie ją na bok
   (`flex-direction: row`), daje fioletowe tło, zmniejsza zdjęcie do 124 px,
   obniża stopnie pisma i PRZYCINA opis do pięciu wierszy. Żeby dostać kartę
   „jak na desktopie", trzeba te przeróbki cofnąć po kolei — sama szerokość
   zostawiłaby kartę leżącą.

   ⚠️ Blok „siatka dopasowana do liczby osób" (też w `komponenty.css`) NIE jest
   w media query, a przez `:has()` i `:not()` ma wyższą szczegółowość niż
   reguły telefonowe — przy trzech osobach wymuszał trzy kolumny na każdej
   szerokości. Dlatego selektory niżej powtarzają wszystkie jego warianty.

   ⚠️ `min-width: 0` — element w układzie elastycznym ma domyślnie
   `min-width: auto` i nie zejdzie poniżej szerokości własnej treści.
   ────────────────────────────────────────────────────────────────────────── */
@media (max-width: 760px) {

    /* 1. Siatka → taśma */
    html body .in-people,
    html body .in-people:not(:has(> :nth-child(2))),
    html body .in-people:has(> :nth-child(2)):not(:has(> :nth-child(3))),
    html body .in-people:has(> :nth-child(3)):not(:has(> :nth-child(4))) {
        display: flex;
        grid-template-columns: none;
        flex-wrap: nowrap;
        gap: 16px;
        overflow-x: auto;
        overflow-y: visible;
        scroll-snap-type: x mandatory;
        -webkit-overflow-scrolling: touch;
        margin-inline: calc(-1 * var(--in-gut));
        padding-inline: var(--in-gut);
        scroll-padding-inline: var(--in-gut);
        scrollbar-width: none;
    }
    html body .in-people::-webkit-scrollbar { display: none; }

    /* 2. Karta: dwie na ekranie — cofnięcie przeróbek telefonowych */
    html body .in-people > .in-person {
        flex: 0 0 calc(50% - 10px);
        min-width: 0;
        scroll-snap-align: start;
        flex-direction: column;
        align-items: stretch;
        gap: 0;
        background: transparent;
        padding: 0 0 26px;
        border-radius: 28px;
    }

    /* 3. Zdjęcie jak na desktopie: pełna szerokość karty, proporcja 3/4, łuk */
    html body .in-people .in-person-m {
        flex: 0 0 auto;
        width: 100%;
        border-radius: 999px 999px 14px 14px;
    }

    /* 4. Tekst bez telefonowego zmniejszenia i BEZ przycinania do N wierszy */
    /* ⚠️ Odstęp pod zdjęciem. Desktop ma `padding: 20px 16px 0`, wersja
       telefonowa z `komponenty.css` ścinała go do `2px 0 0`. Wyzerowanie
       (moja pierwsza wersja tego bloku) przykleiło nazwisko do kadru —
       zgłoszone przez Bartka. Wracamy do wartości desktopowej. */
    html body .in-people .in-person-b { min-width: 0; padding: 20px 16px 0; }
    html body .in-people .in-person .in-p {
        font-size: 13px; line-height: 1.5;
        display: -webkit-box;
        -webkit-box-orient: vertical;
        -webkit-line-clamp: 4;
        line-clamp: 4;
        overflow: hidden;
    }
    html body .in-people .in-methods {
        font-size: 12px;
        display: -webkit-box;
        -webkit-box-orient: vertical;
        -webkit-line-clamp: 2;
        line-clamp: 2;
        overflow: hidden;
    }
}

/* ==========================================================================
   TESTY BEZ PUNKTACJI (27.08.2026)
   Nowy silnik pod /test/ — 1 albo 2 odpowiedzi na pytanie, bramka mailowa,
   pelna analiza na stronie pod tokenem.

   ⚠️ Styl siedzi TUTAJ, nie w `strony/test.css` ani `komponenty.css` — te dwa
   generuje `tools/wytnij-css.py` z prototypu i najblizszy build by je zjadl.
   Ta sama pulapka co przy sekcji `produkty` na profilu Olgi.
   ========================================================================== */

/* Jedna czerwien dla wszystkich stanow bledu w tescie — ta sama, ktora ma
   ramka komunikatu zbiorczego. */
.in-tst, .in-an { --in-blad: #B23A2E; }

.in-tst { max-width: 780px; margin-inline: auto; }

.in-tst-head { margin-bottom: var(--spacing-5); }
.in-tst-head h1 { margin: 0 0 var(--spacing-2); }
.in-tst-lead { color: var(--color-text-muted); margin: 0; max-width: 60ch; }

/* --- pasek postepu --- */
.in-tst-pasek { margin-bottom: var(--spacing-4); }
.in-tst-pasek-h {
    display: flex;
    justify-content: space-between;
    color: var(--color-text-muted);
    margin-bottom: var(--spacing-0);
}
.in-tst-tor { height: 6px; background: var(--brand-100); border-radius: var(--radius-pill); overflow: hidden; }
.in-tst-wype {
    height: 100%;
    width: 0;
    background: var(--brand-500);
    border-radius: var(--radius-pill);
    transition: width .3s ease;
}

/* --- ekrany i przejscie miedzy nimi --- */
/* Scena trzyma wysokosc na czas podmiany, zeby karta nie podskakiwala miedzy
   pytaniami o roznej dlugosci. Wysokosc ustawia JS; tu jest tylko przejscie. */
.in-tst-scena {
    transition: height .34s cubic-bezier(.4, 0, .2, 1);
}
/* ⚠️ Przycinanie TYLKO na czas przejscia (klase zdejmuje JS). Na stale
   `overflow: hidden` obcinalo obwodke fokusu na polach formularza przy lewej
   krawedzi i wypust wezwania CTA na ekranie wyniku, ktory celowo wychodzi
   poza kolumne. Poziomy suwak i tak nie powstanie — `.in-tst-root .in-sec`
   ma `overflow-x: clip`. 27.08.2026 */
.in-tst-scena.przesuwa { overflow: hidden; }

.in-tst-e { display: none; border: 0; padding: 0; margin: 0; }
.in-tst-e.is-on {
    display: block;
    opacity: 1;
    transform: none;
    transition: opacity .3s ease, transform .3s cubic-bezier(.16, .84, .44, 1);
}
/* Stan startowy wjezdzajacego ekranu — JS zdejmuje go w nastepnej klatce,
   zeby przejscie mialo od czego wystartowac. */
.in-tst-e.czeka { opacity: 0; transition: none; }
.in-tst-e.czeka.z-prawej { transform: translateX(26px); }
.in-tst-e.czeka.z-lewej { transform: translateX(-26px); }
/* Ekran wychodzacy: krocej niz wjazd, zeby nie bylo pustej chwili. */
.in-tst-e.znika {
    display: block;
    opacity: 0;
    transition: opacity .15s ease, transform .15s ease;
}
.in-tst-e.znika.w-lewo { transform: translateX(-22px); }
.in-tst-e.znika.w-prawo { transform: translateX(22px); }

/* Odpowiedzi wchodza kaskada — pol sekundy zycia, ale to ona sprawia, ze
   ekran wyglada na zbudowany, a nie podmieniony. Kaskada staje na szostej
   pozycji: przy dziesieciu odpowiedziach ostatnia czekalaby zbyt dlugo. */
@keyframes in-tst-wjazd {
    from { opacity: 0; transform: translateY(8px); }
    to { opacity: 1; transform: none; }
}
.in-tst-e.is-on .in-tst-o { animation: in-tst-wjazd .34s both cubic-bezier(.16, .84, .44, 1); }
.in-tst-e.is-on .in-tst-o:nth-child(1) { animation-delay: .06s; }
.in-tst-e.is-on .in-tst-o:nth-child(2) { animation-delay: .11s; }
.in-tst-e.is-on .in-tst-o:nth-child(3) { animation-delay: .16s; }
.in-tst-e.is-on .in-tst-o:nth-child(4) { animation-delay: .21s; }
.in-tst-e.is-on .in-tst-o:nth-child(n+5) { animation-delay: .26s; }
/* Bez tego kaskada odpalalaby sie od nowa przy kazdym zaznaczeniu odpowiedzi
   — zmiana klasy `is-on` na etykiecie wystarczy, zeby przegladarka uznala
   animacje za nowa. */
.in-tst-e.znika .in-tst-o { animation: none; }
.in-tst-k {
    padding: 0;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--brand-500);
    font-family: var(--font-heading);
}
.in-tst-q { margin: var(--spacing-1) 0 var(--spacing-2); }
.in-tst-h { color: var(--color-text-muted); margin: 0 0 var(--spacing-4); }

/* --- odpowiedzi --- */
.in-tst-opts { display: flex; flex-direction: column; gap: var(--spacing-2); }
.in-tst-o {
    display: grid;
    grid-template-columns: 22px 1fr;
    gap: var(--spacing-2);
    align-items: start;
    padding: var(--spacing-3);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    cursor: pointer;
    background: #fff;
    transition: border-color .15s ease, background .15s ease;
}
.in-tst-o:hover { border-color: var(--brand-400); }
.in-tst-o.is-on { border-color: var(--brand-500); background: var(--brand-50); }
/* Pole wyboru chowamy, ale zostaje w drzewie dostepnosci i lapie fokus. */
.in-tst-o input {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0;
    overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%);
    white-space: nowrap; border: 0;
}
.in-tst-box {
    width: 22px; height: 22px;
    border: 2px solid var(--color-border);
    border-radius: var(--radius-sm);
    display: block;
    margin-top: 2px;
    position: relative;
}
.in-tst-o.is-on .in-tst-box { border-color: var(--brand-500); background: var(--brand-500); }
.in-tst-o.is-on .in-tst-box::after {
    content: "";
    position: absolute;
    left: 6px; top: 2px;
    width: 5px; height: 10px;
    border: solid #fff;
    border-width: 0 2px 2px 0;
    transform: rotate(45deg);
}
.in-tst-o input:focus-visible ~ .in-tst-box { outline: 2px solid var(--brand-500); outline-offset: 2px; }
.in-tst-txt { line-height: 1.5; }

.in-tst-limit {
    margin: var(--spacing-2) 0 0;
    color: var(--brand-700);
}

.in-tst-nav {
    display: flex;
    gap: var(--spacing-2);
    align-items: center;
    margin-top: var(--spacing-5);
    flex-wrap: wrap;
}
.in-tst-wstecz {
    background: none;
    border: 0;
    color: var(--color-text-muted);
    cursor: pointer;
    font: inherit;
    padding: var(--spacing-2) 0;
}
.in-tst-wstecz:hover { color: var(--brand-500); }
.in-tst .in-btn[disabled] { opacity: .45; cursor: not-allowed; }

/* --- bramka mailowa --- */
/* Trzy pola w jednym rzedzie. Adres dostaje wiecej miejsca, bo jest najdluzszy
   — przy trzech rownych kolumnach imie i telefon marnowaly polowe szerokosci,
   a mail sie nie miescil. Przy dwoch kolumnach telefon zostawal sam w drugim
   rzedzie i po prawej ziala dziura. 28.08.2026 */
.in-tst-pola { display: grid; grid-template-columns: 1fr 1.3fr 1fr; gap: var(--spacing-3); }
.in-tst-pole { display: flex; flex-direction: column; gap: var(--spacing-0); }
.in-tst-pole span { color: var(--color-text-muted); }
.in-tst-pole input {
    padding: var(--spacing-2) var(--spacing-3);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    font: inherit;
}
.in-tst-pole input:focus-visible { outline: 2px solid var(--brand-500); outline-offset: 1px; }
.in-tst-zgoda {
    display: grid;
    grid-template-columns: 20px 1fr;
    gap: var(--spacing-2);
    align-items: start;
    margin-top: var(--spacing-3);
    line-height: 1.5;
    color: var(--color-text-muted);
}
.in-tst-zgoda input { margin-top: 3px; }
/* --- pole z bledem ---
   Kolor nie jest jedynym sygnalem: pod polem staje zdanie, co poprawic,
   a `aria-invalid` mowi to samo czytnikowi ekranu. Osoba nierozrozniajaca
   czerwieni ma dostac te sama informacje. */
.in-tst-pole.ma-blad > span { color: var(--in-blad, #B23A2E); }
.in-tst-pole.ma-blad input {
    border-color: var(--in-blad, #B23A2E);
    box-shadow: 0 0 0 3px rgba(178, 58, 46, .14);
}
.in-tst-pole.ma-blad input:focus-visible { outline-color: var(--in-blad, #B23A2E); }
.in-tst-zgoda.ma-blad { color: var(--in-blad, #B23A2E); }
.in-tst-zgoda.ma-blad input {
    outline: 2px solid var(--in-blad, #B23A2E);
    outline-offset: 2px;
}
.in-tst-pole-blad {
    display: block;
    margin-top: 4px;
    color: var(--in-blad, #B23A2E);
    line-height: 1.4;
}
/* W zgodzie komunikat stoi w drugiej kolumnie siatki, pod tekstem — nie pod
   kwadracikiem, bo tam ma szerokosc 20 px. */
.in-tst-zgoda .in-tst-pole-blad { grid-column: 2; }

.in-tst-blad {
    margin: var(--spacing-3) 0 0;
    padding: var(--spacing-2) var(--spacing-3);
    border-left: 3px solid #B23A2E;
    background: #FDF3F1;
    color: #7A2419;
}

/* --- nakladka „skladam analize" ---
   Na CALE okno. Wersja przykrywajaca sama scene zostawiala odsloniety pasek
   z wezwaniem do konsultacji, ktory celowo wychodzi poza kolumne — polowa
   ekranu zyla wtedy wlasnym zyciem. Po wyslaniu i tak przechodzimy do pelnej
   analizy, wiec nie ma czego oszczedzac. 31.08.2026 */
.in-tst-lad {
    position: fixed;
    inset: 0;
    z-index: 9999;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--spacing-3);
    /* Mgla serwisu, nie polprzezroczysta szyba: pod spodem stoi formularz,
       ktory przy przejsciu i tak zniknie, a przeswitujaca tresc tylko miga.
       Strona testu nie jest biala — biel odcinalaby sie tu jak plama. */
    background: #E7EDF9;
}
.in-tst-lad-k {
    width: 38px;
    height: 38px;
    border: 3px solid var(--color-border);
    border-top-color: var(--brand-500);
    border-radius: 50%;
    animation: in-tst-obrot .8s linear infinite;
}
.in-tst-lad-t { margin: 0; color: var(--color-text-muted); }
@keyframes in-tst-obrot { to { transform: rotate(360deg); } }

/* Bez ruchu: kolko zostaje, ale stoi — sam napis niesie te sama informacje. */
@media (prefers-reduced-motion: reduce) {
    .in-tst-lad-k { animation: none; }
}

/* --- prosba o pelna analize ---
   Od 31.08.2026 bramka nie jest osobnym ekranem PRZED wynikiem, tylko blokiem
   POD podsumowaniem: wynik dostaje kazdy, dane zostawia ten, kto chce obszerna
   analize. Odcinamy ja linia i tlem, zeby czytelnie odrozniala sie od tresci
   podsumowania i nie wygladala na jego dalszy ciag. */
.in-tst-brama {
    margin-top: var(--spacing-5);
    padding-top: var(--spacing-5);
    border-top: 1px solid var(--color-border);
}
.in-tst-brama-h {
    margin: 0 0 var(--spacing-1);
    font-family: var(--font-heading);
    font-weight: var(--font-weight-semibold);
    color: var(--brand-600);
}
.in-tst-brama .in-tst-h { margin-top: 0; }
.in-tst-brama .in-tst-pola { margin-top: var(--spacing-3); }

/* Potwierdzenie po wyslaniu — staje w miejscu, gdzie przed chwila byl formularz. */
.in-tst-ok {
    margin-top: var(--spacing-5);
    padding: var(--spacing-3) var(--spacing-4);
    border-left: 3px solid var(--brand-500);
    background: var(--brand-50, #F4EFF8);
    line-height: 1.6;
}

/* --- podsumowanie --- */
.in-tst-tresc { line-height: 1.7; }
.in-tst-tresc .in-tst-wz {
    font-family: var(--font-heading);
    font-weight: var(--font-weight-semibold);
    color: var(--brand-600);
}
.in-tst-tresc .in-tst-drobne { color: var(--color-text-muted); }

@media (max-width: 640px) {
    .in-tst-pola { grid-template-columns: 1fr; }
}

/* ── pasek z wezwaniem na stronie z analiza ──────────────────────────────
   Ta sama tresc co sekcja CTA, ale przyklejona do dolu okna. Przy analizie
   dlugosci 30 000 znakow sekcja na koncu strony jest w praktyce niewidoczna. */
.in-an-pasek {
    position: fixed;   /* jest tez punktem odniesienia dla krzyzyka w rogu */
    left: 0; right: 0; bottom: 0;
    z-index: 60;
    background: var(--brand-800, #372047);
    color: #fff;
    box-shadow: 0 -8px 28px rgba(11, 18, 32, .22);
    transform: translateY(100%);
    transition: transform .25s cubic-bezier(.4, 0, .2, 1);
}
.in-an-pasek.jest { transform: none; }
.in-an-pasek[hidden] { display: none; }
.in-an-pasek-in {
    max-width: var(--in-maxw, 1120px);
    margin-inline: auto;
    /* Z prawej zapas na krzyzyk, ktory siedzi w rogu — bez tego napis
       podjezdzalby pod niego przy waskim oknie. */
    padding: 14px calc(var(--in-gut, 24px) + 34px) 14px var(--in-gut, 24px);
    display: flex;
    align-items: center;
    gap: var(--spacing-3);
    flex-wrap: wrap;
}
.in-an-pasek-t {
    margin: 0;
    flex: 1 1 240px;
    font-family: var(--font-heading);
    font-weight: var(--font-weight-semibold);
    line-height: 1.25;
}
.in-an-pasek-btn { display: flex; gap: var(--spacing-2); flex-wrap: wrap; }
/* Przyciski na ciemnym tle: bialy wypelniony i bialy obrysowany.
   ⚠️ `--cta-base`, NIE `background`. Blok „CTA — wypelnienie" w komponenty.css
   maluje kazdy `.in-btn` regula `background-color: var(--cta-base) !important`,
   wiec zwykle `background: #fff` przegrywalo i pierwszy przycisk wychodzil
   fioletowy z fioletowym napisem — czyli niewidoczny (zgloszone 27.08.2026).
   Ta sama pulapka co przy plakietce „Wyprzedane" 21.08. Podajemy WARTOSC
   TOKENA, ktora tamta regula i tak wezmie. */
.in-an-pasek .in-btn {
    --cta-base: #fff;
    --cta-fill: var(--brand-accent, #67B6C0);
    --cta-hover-text: #fff;
    color: var(--brand-700, #46295a);
}
.in-an-pasek .in-btn + .in-btn {
    --cta-base: transparent;
    color: #fff;
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .55) !important;
}
/* ⚠️ Krzyzyk w PRAWYM GORNYM rogu PASKA, nie tresci. Ustawiony zwyczajnie we
   flexie ladowal na telefonie pod przyciskami, w lewym dolnym rogu — czyli tam,
   gdzie nikt go nie szuka. Punktem odniesienia jest `.in-an-pasek`, a nie
   `.in-an-pasek-in`: tresc jest scisnieta do kolumny 1120 px, wiec krzyzyk
   przypiety do niej wisial 160 px od krawedzi ekranu. 27.08.2026 */
.in-an-pasek-x {
    position: absolute;
    top: 6px;
    right: 6px;
    display: grid; place-items: center;
    width: 32px; height: 32px; padding: 0;
    background: none; border: 0; border-radius: 50%;
    color: rgba(255, 255, 255, .7);
    cursor: pointer;
}
.in-an-pasek-x:hover { color: #fff; background: rgba(255, 255, 255, .12); }
.in-an-pasek-x:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
.in-an-pasek-x svg { width: 18px; height: 18px; }

/* Miejsce pod paskiem, zeby nie zaslanial ostatnich zdan analizy ani stopki. */
body.in-an-z-paskiem { padding-bottom: 96px; }

@media (max-width: 640px) {
    .in-an-pasek-in { padding: 12px 16px 14px; gap: 10px; }
    /* Na telefonie napis dzieli wiersz z krzyzykiem, wiec zapas robimy przy nim,
       a nie na calej wysciolce — inaczej przyciski nizej traca 34 px. */
    .in-an-pasek-t { padding-right: 34px; }
    .in-an-pasek-t { flex-basis: 100%; font-size: 15px; }
    .in-an-pasek-btn { flex: 1 1 auto; }
    .in-an-pasek .in-btn { flex: 1 1 auto; justify-content: center; }
    body.in-an-z-paskiem { padding-bottom: 150px; }
}
@media (prefers-reduced-motion: reduce) {
    .in-an-pasek { transition: none; }
}

/* Wezwanie „Po tescie" doklejane do ekranu wyniku i do strony z analiza.
   Sekcja `cta` ma wlasna wysciolke `.in-sec`, liczona na to, ze stoi sama
   na dole strony — tutaj siedzi w srodku innej sekcji, wiec zdejmujemy gorny
   odstep i zostawiamy tylko przerwe od tresci wyzej. */
.in-tst-cta {
    margin-top: var(--spacing-7);
    /* ⚠️ Wezwanie siedzi w środku `.in-tst`, a ta ma `max-width: 780px` na
       potrzeby czytania pytań — bez wypustu pas CTA wychodził węższy niż
       wszędzie indziej na stronie (zgłoszone 27.08.2026). `margin-left: 50%`
       plus przesunięcie o połowę własnej szerokości środkuje szerszy blok
       względem węższego rodzica, bez znajomości jego szerokości. */
    /* Wezwanie stoi w kolumnie do czytania (`.in-tst` 780 px, `.in-an` 760 px),
       a ma wygladac dokladnie tak, jak na dole strony z wyborem testow — czyli
       na szerokosc okna minus margines serwisu. Zmierzony wzorzec: 1296 px przy
       oknie 1440. Stad wypust do pelnej szerokosci okna i margines oddany
       wysciolce, zamiast ograniczania do kolumny tresci (1120 px dawalo
       widoczna karte 976 px — o 320 px za waska).

       ⚠️ `100vw` liczy sie RAZEM z paskiem przewijania, wiec sam wypust
       potrafi dorzucic poziomy suwak. Dlatego `overflow-x: clip` na sekcji
       nadrzednej — `hidden` odpada, bo utworzylby kontekst przewijania
       i zepsul `position: sticky` gdziekolwiek wyzej. */
    width: 100vw;
    margin-inline: calc(50% - 50vw);
    padding-inline: var(--in-hgut, 72px);
}
.in-tst-root .in-sec, .in-an-root .in-sec { overflow-x: clip; }
.in-tst-cta .in-sec {
    padding-top: 0;
    padding-bottom: 0;
    margin-inline: 0;
}

/* ==========================================================================
   STRONA Z PELNA ANALIZA  /moja-analiza/{token}/
   ========================================================================== */

.in-an { max-width: 760px; margin-inline: auto; }
.in-an-head { padding-bottom: var(--spacing-5); border-bottom: 1px solid var(--color-border); }
.in-an-etykieta {
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--brand-500);
    font-family: var(--font-heading);
    margin: 0 0 var(--spacing-1);
}
.in-an-head h1 { margin: 0 0 var(--spacing-1); }
.in-an-meta { color: var(--color-text-muted); margin: 0; }

.in-an-wzorzec {
    margin-top: var(--spacing-4);
    padding: var(--spacing-4);
    background: var(--brand-50);
    border-radius: var(--radius-lg);
}
.in-an-wzorzec-l {
    margin: 0;
    font-family: var(--font-heading);
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--color-text-muted);
}
.in-an-wzorzec-n {
    margin: var(--spacing-0) 0 var(--spacing-2);
    font-family: var(--font-heading);
    font-weight: var(--font-weight-semibold);
    color: var(--brand-700);
}
.in-an-wzorzec p:last-child { margin-bottom: 0; }
.in-an-akcje { margin-top: var(--spacing-4); }

/* Pytanie: nagłówek trzyma się razem, analizy pod nim są wcięte i oparte
   o pionową szynę. Bez tego, przy dwóch zaznaczonych odpowiedziach, druga
   analiza wyglądała na dalszy ciąg pierwszej. */
.in-an-q { padding: var(--spacing-6) 0 0; }
.in-an-q-head {
    padding-bottom: var(--spacing-2);
    border-bottom: 2px solid var(--brand-200);
    margin-bottom: var(--spacing-4);
}
.in-an-ile {
    margin: var(--spacing-1) 0 0;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--brand-600);
    font-family: var(--font-heading);
    font-weight: var(--font-weight-semibold);
}
.in-an-nr {
    margin: 0 0 var(--spacing-0);
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--brand-500);
    font-family: var(--font-heading);
}
.in-an-q h2 { margin: 0 0 var(--spacing-2); }
.in-an-wstep { color: var(--color-text-muted); margin: 0 0 var(--spacing-3); }
.in-an-pomost {
    margin: 0 0 var(--spacing-4);
    padding: var(--spacing-3);
    border-left: 3px solid var(--brand-accent);
    background: #F2FAFB;
}

/* Szyna po lewej = głębokość. Wszystko, co należy do jednej odpowiedzi,
   wisi na jednej pionowej kresce, więc widać, gdzie kończy się jedna analiza,
   a zaczyna druga — i gdzie kończy się całe pytanie.
   Szyna po LEWEJ, nie po prawej: w piśmie od lewej to lewa krawędź wyznacza
   poziom zagnieżdżenia, więc wcięcie czyta się od razu, bez zastanawiania. */
.in-an-odp {
    border-left: 2px solid var(--brand-200);
    padding-left: var(--spacing-4);
    margin-left: 2px;
}
.in-an-odp + .in-an-odp { margin-top: var(--spacing-5); }
.in-an-wybor {
    position: relative;
    margin: 0 0 var(--spacing-3);
    padding: var(--spacing-3);
    background: var(--brand-50);
    border-radius: var(--radius-md);
    font-weight: var(--font-weight-semibold);
}
/* Kropka na szynie w miejscu każdej odpowiedzi — przy dwóch analizach od razu
   widać, że to dwa równorzędne punkty tego samego pytania, a nie ciąg dalszy. */
.in-an-wybor::before {
    content: "";
    position: absolute;
    left: calc(-1 * var(--spacing-4) - 6px);
    top: 22px;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: var(--brand-500);
    box-shadow: 0 0 0 4px var(--brand-bg, #fff);
}
.in-an-q.ma-dwie .in-an-wybor span { color: var(--brand-600); }
.in-an-wybor span {
    display: block;
    /* Ten sam krój co pozostałe wersaliki („PYTANIE 3", „TWOJA ANALIZA”) —
       jako jedyna etykieta leciała krojem tekstowym i odstawała. */
    font-family: var(--font-heading);
    letter-spacing: .1em;
    text-transform: uppercase;
    font-weight: var(--font-weight-regular);
    color: var(--color-text-muted);
    margin-bottom: 2px;
}
.in-an-tresc { line-height: 1.75; }
/* Srodtytuly wewnatrz analizy przychodza z Worda jako <h4>. */
.in-an-tresc h4 {
    margin: var(--spacing-4) 0 var(--spacing-1);
    color: var(--brand-700);
}
.in-an-tresc p { margin: 0 0 var(--spacing-2); }
.in-an-tresc ul { margin: 0 0 var(--spacing-3); padding-left: var(--spacing-4); }
.in-an-tresc li { margin-bottom: var(--spacing-0); }

.in-an-stopka {
    margin-top: var(--spacing-7);
    padding-top: var(--spacing-4);
    border-top: 1px solid var(--color-border);
    color: var(--color-text-muted);
}
.in-an-brak { max-width: 560px; }

/* Nagłówek kartki — tylko na wydruku. */
.in-an-druk { display: none; }

/* Rusztowanie marginesów wydruku (patrz komentarz w analiza-testu.php).
   Na ekranie ma nie istnieć — `display: contents` zdejmuje pudełka tabeli,
   więc `.in-an` zachowuje się dokładnie jak wcześniej. */
.in-an-kartka,
.in-an-kartka > *,
.in-an-kartka tr,
.in-an-kartka td { display: contents; }

@media print {
    /* ⚠️ `margin: 0` na `@page` — i to jest CELOWE. Data u góry i adres strony
       na dole nie są naszym HTML-em: rysuje je przeglądarka w marginesie
       kartki, więc znikają dopiero wtedy, gdy nie ma tam miejsca.
       Margines robi za nas `thead` tabeli `.in-an-kartka`, który powtarza się
       na każdej stronie wydruku — inaczej niż wyściółka `body`, działająca
       tylko na pierwszej kartce. Bez tego albo mamy adres na dole każdej
       strony, albo tekst dotyka krawędzi papieru i drukarka go ucina.
       27.08.2026 */
    @page { size: A4; margin: 0; }
    html body {
        padding: 0;
        background: #fff;
    }

    .in-an-kartka { display: table; width: 100%; border-collapse: collapse; }
    .in-an-kartka thead { display: table-header-group; }
    .in-an-kartka tbody { display: table-row-group; }
    .in-an-kartka tfoot { display: table-footer-group; }
    .in-an-kartka tr { display: table-row; }
    .in-an-kartka td { display: table-cell; }
    .in-an-kartka-g { height: 16mm; }   /* górny margines każdej kartki */
    .in-an-kartka-d { height: 14mm; }   /* dolny */
    .in-an-kartka-t { padding-inline: 14mm; vertical-align: top; }

    /* ⚠️ NAJWAŻNIEJSZA REGUŁA W TYM BLOKU. Sekcje ujawniają się przy przewijaniu
       (`.rv { opacity: 0 }` + IntersectionObserver w wspolne.js), a wydruk nie
       przewija — klient klikał „Drukuj" u góry strony i dostawał PDF, w którym
       treść poniżej pierwszego ekranu była PUSTA. Zmierzone 27.08.2026: z 21
       stron pierwsza miała nagłówek i od razu środek analizy, bez tytułu
       i bez pytania. Dotyczy KAŻDEJ drukowanej strony w serwisie, nie tylko
       analizy. */
    .rv, .rv.is-in, .js-anim, .in-ba-transform {
        opacity: 1 !important;
        transform: none !important;
        transition: none !important;
        animation: none !important;
    }

    /* ⚠️ NIE `header, footer` gołymi znacznikami. Nagłówek analizy i nagłówek
       każdego pytania to też `<header>`, a stopka analizy to `<footer>` —
       ta reguła kasowała je z wydruku razem z chromem serwisu. Objaw: PDF bez
       tytułu, bez danych i bez ani jednego pytania, sama treść analiz.
       Celujemy w konkretne klasy szkieletu. 27.08.2026 */
    .in-no-print, .in-hdr, .in-ftr, .in-header, .in-footer, .in-cart,
    /* Wezwanie do umówienia konsultacji: na papierze nie da się w nie kliknąć,
       a fioletowy pas na całą szerokość zjada tusz. Zostaje na ekranie. */
    .in-tst-cta, .in-an-pasek { display: none !important; }
    body.in-an-z-paskiem { padding-bottom: 0; }
    .in-an { max-width: none; }

    .in-an-druk {
        display: block;
        margin-bottom: 10mm;
        padding-bottom: 4mm;
        border-bottom: 1.5pt solid #cfcfcf;
    }
    .in-an-druk-m {
        margin: 0;
        font-family: var(--font-heading);
        font-weight: var(--font-weight-semibold);
        letter-spacing: .1em;
        text-transform: uppercase;
        color: #6b6b6b;
    }
    .in-an-druk-t {
        margin: 1mm 0 0;
        font-family: var(--font-heading);
        font-weight: var(--font-weight-bold);
    }

    /* Nagłówek strony z analizą: bez ozdób, żeby pierwsza kartka nie była
       w połowie pusta. */
    .in-an-head { padding-bottom: 6mm; }
    .in-an-data { display: none; }
    .in-an-wzorzec { background: #f4f4f4; padding: 4mm; }

    /* ── podział na kartki ──────────────────────────────────────────────
       Każde pytanie zaczyna nową stronę. Przy dwudziestu analizach to jedyny
       podział, który da się przewidzieć: bez niego pytanie 4 zaczynało się
       w ostatniej linijce kartki, a jego analiza szła dalej — czytelnik gubił,
       gdzie kończy się jedno, a zaczyna drugie.
       ⚠️ `:first-of-type` bez tego dostawałby pustą stronę tytułową. */
    .in-an-q { break-before: page; padding-top: 0; }
    .in-an-q:first-of-type { break-before: auto; padding-top: 8mm; }

    /* Stopka nie zaczyna własnej kartki dla jednego zdania. */
    .in-an-stopka { break-before: avoid-page; margin-top: 8mm; padding-top: 4mm; }

    /* Nagłówek kartki powtarzany nie jest (przeglądarki tego nie potrafią bez
       tabel), więc numer pytania musi wystarczyć za orientację — stąd zostaje
       nad każdym pytaniem, u góry nowej strony. */

    /* ⚠️ `break-inside: avoid` na całym pytaniu było życzeniowe: dwie analizy
       to ponad 3000 znaków, czyli więcej niż strona A4, więc przeglądarka i tak
       to ignorowała. Łamaniem sterujemy tam, gdzie da się je utrzymać. */
    .in-an-q { break-inside: auto; }
    .in-an-q-head { break-after: avoid-page; break-inside: avoid-page; }
    .in-an-wybor { break-after: avoid-page; break-inside: avoid-page; }
    .in-an-tresc h4 { break-after: avoid-page; break-inside: avoid-page; }
    .in-an-pomost { break-inside: avoid-page; }
    .in-an-tresc p, .in-an-tresc li { orphans: 3; widows: 3; }

    /* Szyna musi przeżyć wydruk — to ona pokazuje, że analiza należy do pytania
       wyżej, także gdy strona łamie się w jej środku. Kolory drukarek bywają
       zdradliwe, więc na papierze idzie szarość, nie fiolet. */
    .in-an-odp {
        border-left: 1.5pt solid #9a9a9a;
        -webkit-print-color-adjust: exact;
        print-color-adjust: exact;
    }
    .in-an-wybor { background: #f2f2f2; }
    .in-an-wybor::before { background: #6b6b6b; box-shadow: 0 0 0 3pt #fff; }
    .in-an-q-head { border-bottom-color: #9a9a9a; }
    a[href]::after { content: ""; }
}

/* ==========================================================================
   WYBOR TESTU  /test/
   ========================================================================== */

.in-tw-head { max-width: 62ch; margin-bottom: var(--spacing-6); }
.in-tw-head h1 { margin: 0 0 var(--spacing-2); }
/* Jeden przewijany rząd zamiast siatki `auto-fit`.
   ⚠️ Siatka zawijała kafle i przy zwężaniu okna zostawiała sierotę w drugim
   rzędzie (zgłoszone 27.08.2026). Pasek trzyma jeden rząd przy każdej
   szerokości. Pasek przewijania ukryty, strzałki dokłada `karuzela.js` —
   tak samo jak przy karuzeli kafelków i rzędzie zdań „czy to o Tobie?".
   `overflow-y: hidden` jest konieczne, bo samo `overflow-x: auto` wymusza pion. */
.in-tw-siatka {
    display: flex;
    gap: var(--spacing-3);
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
    /* Zapas w PIONIE na uniesienie kafla przy najechaniu (translateY -2px).
       ⚠️ Bez poziomego — z nim `scroll-snap` zatrzymywał się na 4 px zamiast 0
       i lewa strzałka wychodziła aktywna już na starcie paska. */
    padding-block: 4px 8px;
    margin-block: -4px -8px;
}
/* Wypust do krawędzi kolumny (`margin-inline` + `padding-inline` na szerokość
   marginesu) siedzi we wspólnej regule niżej — razem z karuzelą kafelków,
   opiniami i rzędem zdań. Dzięki temu kafel nie urywa się w środku układu,
   tylko dojeżdża do krawędzi tak samo jak na pozostałych stronach.
   ⚠️ Próbowałem tu rozmycia krawędzi maską — odrzucone 27.08.2026, bo żaden
   inny pasek w serwisie tak nie wygląda. */
.in-tw-siatka::-webkit-scrollbar { display: none; }
/* Kafle kurczą się, dopóki mieszczą się w kolumnie, i dopiero potem pasek
   zaczyna się przewijać. Dzięki temu na szerokim ekranie wszystkie pięć stoi
   obok siebie, `karuzela.js` nie znajduje czego przewijać i sam chowa strzałki.
   ⚠️ `min-width` wyznacza szerokość okna, od której strzałki znikają: pasek
   musi pomieścić `liczba kafli * min-width + odstępy`. Przy 230 px i pięciu
   kaflach potrzeba ~1214 px w kolumnie, czyli okna od ~1360 px (przy 200 px
   wystarczało ~1150 px). Ustawione na 230 px 27.08.2026 na prośbę Bartka.
   Gdyby kafli przybyło, próg przesunie się w górę — wtedy albo niższe
   `min-width`, albo strzałki zostają na stałe. */
.in-tw-siatka > * {
    flex: 1 1 230px;
    min-width: 230px;
    max-width: 320px;
    scroll-snap-align: start;
}
.in-tw-kafel {
    display: flex;
    flex-direction: column;
    min-height: 100%;
    gap: var(--spacing-1);
    padding: var(--spacing-4);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    background: #fff;
    text-decoration: none;
    color: inherit;
    transition: border-color .15s ease, transform .15s ease;
}
a.in-tw-kafel:hover { border-color: var(--brand-500); transform: translateY(-2px); }
.in-tw-kafel h2 { margin: 0; }
.in-tw-opis { margin: 0; color: var(--color-text-muted); line-height: 1.55; }
/* Etykieta jak pozostałe wersaliki w motywie: krój nagłówkowy, nie tekstowy.
   Bez tego jedna metadana na całej stronie leciała Source Sansem i odstawała
   od „PYTANIE 1", „TWOJA ANALIZA" i reszty plakietek. Stopień — najmniejszy
   w skali (`--t-micro`), przypisany w skala.css. */
.in-tw-czas {
    margin: 0;
    font-family: var(--font-heading);
    font-weight: var(--font-weight-semibold);
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--color-text-muted);
}
.in-tw-cta {
    margin-top: auto;
    padding-top: var(--spacing-2);
    font-family: var(--font-heading);
    font-weight: var(--font-weight-semibold);
    color: var(--brand-500);
}
.in-tw-kafel.is-wkrotce { background: var(--brand-50); border-style: dashed; }
.in-tw-kafel.is-wkrotce .in-tw-cta { color: var(--color-text-muted); }

@media (prefers-reduced-motion: reduce) {
    .in-tst-wype, a.in-tw-kafel { transition: none; }
    /* Ekrany przelaczaja sie bez ruchu — JS tez to sprawdza i pomija cale
       przejscie, ale styl musi byc odporny sam z siebie. */
    .in-tst-scena, .in-tst-e.is-on, .in-tst-e.znika { transition: none; }
    .in-tst-e.is-on .in-tst-o { animation: none; }
    .in-tst-e.czeka, .in-tst-e.znika { transform: none; }
}

.in-tw-notatka {
    margin-top: var(--spacing-5);
    padding: var(--spacing-3) var(--spacing-4);
    border-left: 3px solid var(--brand-accent);
    background: #F2FAFB;
    line-height: 1.6;
}
.in-tw-notatka p { margin: 0; }
.in-tw-notatka-t {
    font-family: var(--font-heading);
    font-weight: var(--font-weight-semibold);
    margin-bottom: 2px !important;
}
