/* ============================================================================
   nurtoo.pl — arkusz stylów

   Plik konsumuje WYŁĄCZNIE tokeny z `tokens.css`: zero hexów, zero rozmiarów
   pisma w px, zero wartości wpisanych z palca. Bramka jest jedna i policzalna:

     grep -E '^[^ /*].*\{' public/styles.css | grep -oE '#[0-9a-fA-F]{3,8}' | wc -l

   ma zwracać ZERO. 🔴 Liczy WIERSZE REGUŁ, a nie cały plik, i to nie jest
   ustępstwo: komentarze cytują wartości, które zeszły (`#27322f`, `#bcd4ce`),
   bo bez tego nie da się napisać, co i dlaczego zniknęło. Bramka licząca cały
   plik kazałaby usunąć te cytaty, czyli **zmienić treść po to, żeby pomiar
   wypadł zielono** — dokładnie ten mechanizm, który reguła o zawężaniu bramek
   nazywa najdroższym: zły pomiar wprowadza w błąd, zła bramka zmienia kod.

   🔴 DO 2d.7 PLIK MIAŁ TRZY CZĘŚCI I TO JEST HISTORIA WARTA ZAPAMIĘTANIA, bo
   tłumaczy, dlaczego migracja szła stroną po stronie, a nie jednym commitem.
   Część druga („mostek zmiennych", 15 nazw w rodzaju `--ink` czy `--gold-500`
   przetłumaczonych na tokeny) i trzecia („zastane", 159 reguł wyciętych bajtowo
   z arkusza sprzed redesignu) istniały po to, żeby strona niezmigrowana
   wyglądała DOKŁADNIE tak samo jak przed zmianą, dopóki nie przyjdzie jej
   paczka. Reguła, która z tego wynikała i której warto pilnować przy każdej
   następnej migracji: **wygląd strony zmienia się w paczce tej strony i w
   żadnej innej**, a klasa dzielona z niezmigrowaną stroną wymaga w nowej
   warstwie NOWEJ NAZWY, bo ta sama nazwa znaczy, że obie reguły działają na
   obu stronach.

   Ostatnie trzy reguły zastane zeszły w 2d.7 i każda inaczej: `h1,h2,h3,h4`
   była ŻYWA (niosła odstępy międzyliterowe i interlinię dla nagłówków bez
   klasy typograficznej) i jej treść przeszła do pięciu reguł komponentowych;
   `.readout .rv.gold` była martwa, ale przez KOMBINACJĘ klas, więc wykrywacz
   reguł bez użytkowników jej nie widział; `.hero-grid,.founder` dublowała
   regułę tokenową inną wartością odstępu.
   ============================================================================ */
/* ============================================================================
   Nurtoo — arkusz redesignu (v2). Konsumuje WYŁĄCZNIE tokeny z tokens.css.

   ZAKRES: komponenty potrzebne przez `index.next.html`. To dowód kierunku,
   nie pełny arkusz serwisu. Pozostałe 14 stron nadal chodzi na `styles.css`
   i nie są tą zmianą tknięte.

   BRAMKA: w tym pliku nie ma ani jednej wartości hex, ani jednego rgb() i ani
   jednego rozmiaru pisma w px. Każdy kolor, rozmiar, odstęp i promień jest
   tokenem. Sprawdzalne gremem, i tak zostało sprawdzone.

   ODEJŚCIE OD REGUŁ APPLE, ŚWIADOME: reguły każą użyć systemowego stosu pism
   (na urządzeniach Apple daje San Francisco bez kosztu). Nurtoo ma własne
   pisma w brandbooku i wymóg self-hostingu z preloadem, więc brandbook wygrywa.
   Systemowy stos zostaje jako awaryjny, w tej właśnie kolejności.
   ============================================================================ */

@font-face{font-family:'Sora';src:url('../../fonts/Sora.woff2') format('woff2');font-weight:100 800;font-style:normal;font-display:swap}
@font-face{font-family:'Inter';src:url('../../fonts/Inter.woff2') format('woff2');font-weight:100 900;font-style:normal;font-display:swap}
@font-face{font-family:'IBM Plex Mono';src:url('../../fonts/IBMPlexMono-Regular.woff2') format('woff2');font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:'IBM Plex Mono';src:url('../../fonts/IBMPlexMono-Medium.woff2') format('woff2');font-weight:500;font-style:normal;font-display:swap}

/* ---------------------------------------------------------------- podstawy */
*,*::before,*::after{box-sizing:border-box}

html{
  scroll-behavior:smooth;
  /* pasek nawigacji jest przyklejony, więc kotwica bez tego wpada pod niego */
  scroll-padding-top:calc(var(--nt-space-9) + var(--nt-space-2));
}
@media (prefers-reduced-motion: reduce){ html{scroll-behavior:auto} }

body{
  margin:0;
  min-height:100dvh;
  background:var(--nt-surface-base);
  color:var(--nt-label-1);
  font-family:var(--nt-font-text);
  font-size:var(--nt-text-body);
  font-weight:var(--nt-text-body-weight);
  line-height:var(--nt-text-body-leading);
  letter-spacing:var(--nt-text-body-track);
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
  overflow-x:hidden;
}

img{max-width:100%;height:auto}
a{color:inherit;text-decoration:none}
strong,b{font-weight:600;color:inherit}

/* Fokus: jeden pierścień, jedna reguła, wysoki kontrast wobec obu motywów.
   Na pasie marki token podmienia się lokalnie (patrz `.on-brand`). */
:focus-visible{
  outline:var(--nt-focus-ring-width) solid var(--nt-focus-ring);
  outline-offset:var(--nt-focus-ring-offset);
  border-radius:var(--nt-radius-xs);
}
.on-brand{ --nt-focus-ring: var(--nt-focus-ring-on-brand); }

.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);border:0;white-space:nowrap}
/* Odnośnik „przejdź do treści" ma się POKAZAĆ, kiedy dostanie fokus. Ukryty
   na stałe jest przydatny tylko dla czytnika ekranu, a przydaje się też
   osobie, która po prostu chodzi tabulatorem. */
.skip-link:focus-visible{
  position:fixed;top:var(--nt-space-3);left:var(--nt-space-3);
  width:auto;height:auto;margin:0;clip-path:none;
  z-index:100;
  padding:var(--nt-space-3) var(--nt-space-4);
  background:var(--nt-surface-elevated);color:var(--nt-label-1);
  border-radius:var(--nt-radius-md);box-shadow:var(--nt-shadow-2);
  font-size:var(--nt-text-subhead);font-weight:600;
}

.mono{font-family:var(--nt-font-mono);font-variant-numeric:tabular-nums}

/* ------------------------------------------------------- skala typograficzna
   Klasy pomocnicze istnieją, żeby komponent nie ustawiał czterech właściwości
   z palca. Każdy poziom to rozmiar + waga + tracking + interlinia razem. */
.t-display-1{font-family:var(--nt-font-display);font-size:var(--nt-text-display-1);font-weight:var(--nt-text-display-1-weight);letter-spacing:var(--nt-text-display-1-track);line-height:var(--nt-text-display-1-leading)}
.t-display-2{font-family:var(--nt-font-display);font-size:var(--nt-text-display-2);font-weight:var(--nt-text-display-2-weight);letter-spacing:var(--nt-text-display-2-track);line-height:var(--nt-text-display-2-leading)}
.t-title-1{font-family:var(--nt-font-display);font-size:var(--nt-text-title-1);font-weight:var(--nt-text-title-1-weight);letter-spacing:var(--nt-text-title-1-track);line-height:var(--nt-text-title-1-leading)}
.t-title-2{font-family:var(--nt-font-display);font-size:var(--nt-text-title-2);font-weight:var(--nt-text-title-2-weight);letter-spacing:var(--nt-text-title-2-track);line-height:var(--nt-text-title-2-leading)}
.t-title-3{font-family:var(--nt-font-display);font-size:var(--nt-text-title-3);font-weight:var(--nt-text-title-3-weight);letter-spacing:var(--nt-text-title-3-track);line-height:var(--nt-text-title-3-leading)}
.t-headline{font-family:var(--nt-font-display);font-size:var(--nt-text-headline);font-weight:var(--nt-text-headline-weight);letter-spacing:var(--nt-text-headline-track);line-height:var(--nt-text-headline-leading)}
.t-lead{font-size:var(--nt-text-lead);font-weight:var(--nt-text-lead-weight);letter-spacing:var(--nt-text-lead-track);line-height:var(--nt-text-lead-leading)}
.t-subhead{font-size:var(--nt-text-subhead);letter-spacing:var(--nt-text-subhead-track);line-height:var(--nt-text-subhead-leading)}
.t-footnote{font-size:var(--nt-text-footnote);letter-spacing:var(--nt-text-footnote-track);line-height:var(--nt-text-footnote-leading)}
.t-caption{font-size:var(--nt-text-caption);font-weight:var(--nt-text-caption-weight);letter-spacing:var(--nt-text-caption-track);line-height:var(--nt-text-caption-leading)}

h1,h2,h3,h4{margin:0;font-family:var(--nt-font-display)}
p{margin:0}

/* ------------------------------------------------------------------- układ */
.container{
  max-width:var(--nt-width-content);
  margin-inline:auto;
  padding-inline:max(var(--nt-gutter), env(safe-area-inset-left));
}
/* 🔴 SZEROKOSC KOLUMNY STOI TU RAZ, DLA DWOCH SELEKTOROW, i to jest cala
   tresc tej zmiany z 2d.3. `.col-prose` to kolumna o szerokosci prozy BEZ
   typografii prozy: uzywa jej naglowek wpisu i lista Aktualnosci, gdzie stoja
   metka, tytul i lead, kazde z wlasna skala. Gdyby te trzy deklaracje zostaly
   powtorzone w drugiej regule, mielibysmy dwie odpowiedzi na jedno pytanie
   o szerokosc kolumny i nic nie pilnowaloby ich zgodnosci. */
.prose,.col-prose{max-width:var(--nt-width-prose);margin-inline:auto;padding-inline:var(--nt-gutter)}

section{padding-block:var(--nt-section-y)}
.section-tight{padding-block:var(--nt-space-8)}

/* Etykieta sekcji. Zmiana wobec dzisiejszej strony: kolor schodzi ze złota na
   neutralny poziom 3 etykiet. Powód zmierzony, nie estetyczny — złoto jako
   tekst ma 2,02:1 na papierze i 2,84:1 na białym, czyli nie przechodzi progu
   4,5:1 w żadnym z siedmiu miejsc, w których dziś stoi. Hierarchię dźwiga
   krój, wielkość i kapitaliki, nie kolor. */
.eyebrow{
  display:inline-block;
  font-family:var(--nt-font-mono);
  font-size:var(--nt-text-eyebrow);
  font-weight:var(--nt-text-eyebrow-weight);
  letter-spacing:var(--nt-text-eyebrow-track);
  line-height:var(--nt-text-eyebrow-leading);
  text-transform:uppercase;
  color:var(--nt-label-3);
}
.lead{
  font-size:var(--nt-text-lead);
  letter-spacing:var(--nt-text-lead-track);
  line-height:var(--nt-text-lead-leading);
  color:var(--nt-label-2);
  max-width:var(--nt-measure-lead);
}
.sec-head > h2{max-width:var(--nt-measure-headline);margin-block:var(--nt-space-3) var(--nt-space-3)}
.sec-head > .lead{max-width:var(--nt-measure-lead)}
.sec-head.center{margin-inline:auto;text-align:center}
.sec-head.center > h2,.sec-head.center > .lead{margin-inline:auto}

.stack-4 > * + *{margin-top:var(--nt-space-4)}
.mt-6{margin-top:var(--nt-space-6)}
.mt-7{margin-top:var(--nt-space-7)}

/* ---------------------------------------------------------------- przyciski */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:var(--nt-space-2);
  min-height:var(--nt-target-min);
  padding:var(--nt-space-3) var(--nt-space-5);
  font-family:var(--nt-font-display);
  font-size:var(--nt-text-subhead);
  font-weight:600;
  letter-spacing:var(--nt-text-subhead-track);
  border-radius:var(--nt-radius-md);
  border:1px solid transparent;
  cursor:pointer;
  max-width:100%;
  white-space:normal;
  text-wrap:balance;
  transition:background-color var(--nt-duration-fast) var(--nt-ease-out),
             border-color var(--nt-duration-fast) var(--nt-ease-out),
             color var(--nt-duration-fast) var(--nt-ease-out),
             transform var(--nt-duration-fast) var(--nt-ease-out);
}
/* Reakcja na dotknięcie zamiast unoszenia na hover. Unoszenie o -2px na hover
   nie istnieje na dotyku, a wciśnięcie działa wszędzie i jest natychmiastowe. */
.btn:active{transform:scale(var(--nt-press-scale))}
.btn-lg{padding:var(--nt-space-4) var(--nt-space-6);font-size:var(--nt-text-headline)}
.btn:disabled,.btn[aria-disabled="true"]{
  background:var(--nt-surface-sunken);border-color:var(--nt-separator);
  color:var(--nt-label-4);cursor:not-allowed;transform:none;
}

.btn-primary{background:var(--nt-accent);color:var(--nt-on-accent)}
.btn-primary:hover{background:var(--nt-accent-strong)}

.btn-ghost{background:transparent;border-color:var(--nt-separator-strong);color:var(--nt-label-1)}
.btn-ghost:hover{border-color:var(--nt-link);color:var(--nt-link)}

.on-brand .btn-ghost{border-color:var(--nt-separator-on-brand);color:var(--nt-label-on-brand-1)}
.on-brand .btn-ghost:hover{border-color:var(--nt-label-on-brand-1)}

/* --------------------------------------------------------------------- znak
   Ostatnie „o" złote to reguła brandbooka i zostaje. Złoto ma tu 2,02:1, ale
   znak firmowy jest wyłączony z wymogu kontrastu (WCAG 1.4.3, logotypy) —
   zapisane wprost, żeby nie wyglądało na przeoczenie. */
.logo{display:inline-flex;align-items:center;gap:var(--nt-space-3);min-height:var(--nt-target-min)}
.logo svg{display:block;flex:0 0 auto}
.logo .word{font-family:var(--nt-font-display);font-weight:600;font-size:var(--nt-text-title-2);letter-spacing:var(--nt-text-title-2-track);color:var(--nt-label-1)}
.logo .o2{color:var(--nt-accent)}

/* --------------------------------------------------------------- nawigacja */
.nav{
  position:sticky;top:0;z-index:50;
  background:var(--nt-material-bar);
  -webkit-backdrop-filter:var(--nt-material-filter);
  backdrop-filter:var(--nt-material-filter);
  border-bottom:1px solid transparent;
  transition:border-color var(--nt-duration-base) var(--nt-ease-out);
}
/* Pasek nie dostaje cienia po przewinięciu, tylko hairline. Cień był
   animowany, a animowanie box-shadow jest kosztowne i nie daje tu nic, czego
   nie daje kreska: informacja jest jedna — „treść przewija się pod paskiem". */
.nav.scrolled{border-bottom-color:var(--nt-separator)}
.nav-inner{display:flex;align-items:center;justify-content:space-between;gap:var(--nt-space-4);min-height:calc(var(--nt-target-min) + var(--nt-space-6))}
.nav-links{display:flex;align-items:center;gap:var(--nt-space-6)}
.navlink{
  display:inline-flex;align-items:center;justify-content:center;
  min-height:var(--nt-target-min);
  /* 🔴 Szerokość też jest celem dotyku, i to jest poprawka pomiaru z kroku 1.
     Tabela bramek zapisała wtedy „cele dotyku poniżej 44px: 0 / 0", ale reguła
     patrzyła na WYSOKOŚĆ. Pomiar 2d.1c, liczący MNIEJSZY BOK prostokąta,
     pokazał jedno trafienie: odnośnik „O nas" ma 43px szerokości, bo tyle ma
     jego tekst. `min-width` dokłada mu jeden piksel i nie rusza rytmu paska,
     w odróżnieniu od dołożenia odstępu poziomego, które rozepchnęłoby
     wszystkie odnośniki i zmieniło zaakceptowany wygląd. */
  min-width:var(--nt-target-min);
  padding-block:var(--nt-space-2);
  font-size:var(--nt-text-subhead);font-weight:500;
  color:var(--nt-label-2);
  transition:color var(--nt-duration-fast) var(--nt-ease-out);
}
.navlink:hover{color:var(--nt-label-1)}
.navlink[aria-current="page"],.navlink.active{color:var(--nt-label-1)}
.nav-cta{display:flex;align-items:center;gap:var(--nt-space-3)}

.has-dd{position:relative;display:flex;align-items:center}
.dd-toggle{display:inline-flex;align-items:center;gap:var(--nt-space-2)}
.caret{width:7px;height:7px;border-right:2px solid currentColor;border-bottom:2px solid currentColor;transform:rotate(45deg) translateY(-1px);opacity:.6}

/* Menu wychodzi z przycisku, który je zrodził, i wraca tą samą drogą.
   Animujemy wyłącznie transform i opacity. */
.dropdown{
  position:absolute;top:100%;left:50%;
  margin-top:var(--nt-space-3);
  width:min(330px, calc(100vw - 2 * var(--nt-gutter)));
  padding:var(--nt-space-2);
  background:var(--nt-surface-elevated);
  border:1px solid var(--nt-separator);
  border-radius:var(--nt-radius-lg);
  box-shadow:var(--nt-shadow-3);
  transform:translateX(-50%) translateY(-6px) scale(.98);
  transform-origin:top center;
  opacity:0;visibility:hidden;
  transition:opacity var(--nt-duration-fast) var(--nt-ease-out),
             transform var(--nt-duration-spring) var(--nt-spring),
             visibility 0s linear var(--nt-duration-fast);
  z-index:60;
}
.has-dd:hover .dropdown,.has-dd:focus-within .dropdown{
  opacity:1;visibility:visible;
  transform:translateX(-50%) translateY(0) scale(1);
  transition-delay:0s;
}
/* Escape zdejmuje nakładkę, a fokus wraca na odnośnik, który ją zrodził
   (pozycja W6). Lista kontrolna `apple-design` wymaga tego wprost, a WCAG
   1.4.13 tego samego: treść pokazana na hover albo fokus musi dać się
   odrzucić klawiaturą. Do 2d menu zamykało się WYŁĄCZNIE odjazdem kursora
   albo fokusu.
   🔴 Reguła stoi PO regule hoveru i ma tę samą specyficzność (0,3,0), więc
   wygrywa KOLEJNOŚCIĄ W PLIKU, a nie `!important`. Przeniesienie jej wyżej
   zepsułoby ją bez żadnego ostrzeżenia, dlatego to zdanie tu stoi.
   Klasę zdejmuje `app.js`, gdy kursor albo fokus opuszcza pasek, żeby menu
   dało się otworzyć ponownie bez przeładowania strony. */
.has-dd.zamkniete .dropdown{
  opacity:0;visibility:hidden;
  transform:translateX(-50%) translateY(-6px) scale(.98);
  transition-delay:0s;
}
/* mostek, żeby przejście kursora między odnośnikiem a panelem nie gasiło go */
.dropdown::before{content:"";position:absolute;top:calc(-1 * var(--nt-space-3));left:0;right:0;height:var(--nt-space-3)}
.dd-item{
  display:flex;gap:var(--nt-space-3);align-items:flex-start;
  padding:var(--nt-space-3);
  border-radius:var(--nt-radius-md);
  transition:background-color var(--nt-duration-fast) var(--nt-ease-out);
}
.dd-item:hover,.dd-item[aria-current="page"]{background:var(--nt-surface-tint)}
.dd-item .di{flex:0 0 auto;width:34px;height:34px;border-radius:var(--nt-radius-sm);background:var(--nt-surface-tint);display:grid;place-items:center}
.dd-item:hover .di{background:var(--nt-surface-elevated)}
.dd-item .di svg{width:18px;height:18px;stroke:var(--nt-label-brand);fill:none;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.dd-item .t{display:block;font-family:var(--nt-font-display);font-weight:600;font-size:var(--nt-text-subhead);color:var(--nt-label-1)}
.dd-item .d{display:block;margin-top:2px;font-size:var(--nt-text-footnote);line-height:var(--nt-text-footnote-leading);color:var(--nt-label-3)}

.menu-btn{
  display:none;
  width:var(--nt-target-min);height:var(--nt-target-min);
  background:none;border:0;cursor:pointer;
  padding:var(--nt-space-3);
}
.menu-btn span{display:block;width:20px;height:2px;background:var(--nt-label-1);border-radius:var(--nt-radius-full);transition:transform var(--nt-duration-base) var(--nt-ease-out),opacity var(--nt-duration-fast) linear}
.menu-btn span + span{margin-top:5px}
.menu-btn[aria-expanded="true"] span:nth-child(1){transform:translateY(7px) rotate(45deg)}
.menu-btn[aria-expanded="true"] span:nth-child(2){opacity:0}
.menu-btn[aria-expanded="true"] span:nth-child(3){transform:translateY(-7px) rotate(-45deg)}

/* Menu mobilne jako warstwa NAD treścią, nie rozpychająca treść.
   Dzięki temu animujemy transform, a nie max-height. */
.mobile-menu{
  display:none;
  position:absolute;left:0;right:0;top:100%;
  padding:var(--nt-space-2) 0 var(--nt-space-4);
  background:var(--nt-surface-elevated);
  border-bottom:1px solid var(--nt-separator);
  box-shadow:var(--nt-shadow-2);
  transform:translateY(-8px);opacity:0;visibility:hidden;
  transition:opacity var(--nt-duration-fast) var(--nt-ease-out),
             transform var(--nt-duration-spring) var(--nt-spring),
             visibility 0s linear var(--nt-duration-fast);
}
.mobile-menu.open{transform:translateY(0);opacity:1;visibility:visible;transition-delay:0s}
.mobile-menu a{
  display:flex;align-items:center;min-height:var(--nt-target-min);
  padding:var(--nt-space-2) var(--nt-gutter);
  font-size:var(--nt-text-body);font-weight:500;color:var(--nt-label-1);
}
.mobile-menu a.sub{padding-left:calc(var(--nt-gutter) + var(--nt-space-5));font-weight:400;font-size:var(--nt-text-subhead);color:var(--nt-label-2)}

/* ---------------------------------------------------------------- sekcja hero */
.hero{padding-top:var(--nt-space-8);padding-bottom:var(--nt-space-9)}
.hero-grid{display:grid;grid-template-columns:1fr 1fr;gap:var(--nt-space-9);align-items:center}
.hero h1{margin-block:var(--nt-space-4)}
.hero h1 .accent{color:var(--nt-label-brand)}
.cta-row{display:flex;gap:var(--nt-space-3);flex-wrap:wrap;margin-block:var(--nt-space-6) var(--nt-space-4)}
.microtrust{display:flex;align-items:center;gap:var(--nt-space-2);font-size:var(--nt-text-footnote);line-height:var(--nt-text-footnote-leading);color:var(--nt-label-3)}
.microtrust .dot{width:7px;height:7px;border-radius:var(--nt-radius-full);background:var(--nt-accent);flex:0 0 auto}

/* --------------------------------------------------- nagłówek podstrony
   Odpowiednik `.hero` dla stron, ktore nie sa strona glowna: etykieta,
   tytul, akapit wprowadzajacy.

   🔴 ZASTEPUJE ZASTANE `.page-hero`, KTOREGO NIE DA SIE ZMIGROWAC W PACZCE
   JEDNEJ STRONY, bo uzywa go osiem stron naraz (zmierzone gremem po `src/`
   przy 2d.3). Paczka przegladajaca jedna strone nie ma prawa zmienic wygladu
   siedmiu, ktorych nie przeglada, wiec `.page-hero` zostaje w czesci zastanej
   i schodzi z niej strona po stronie w 2d.4-2d.6. Ten komponent jest wiec
   inwestycja dla tamtych paczek, dokladnie tak samo jak `.prose` byla nia
   w 2d.2: slownik komponentow powstaje PRZED najtrudniejsza strona. */
.page-head{padding-top:var(--nt-space-8);padding-bottom:var(--nt-space-6)}
.page-head h1{
  margin-block:var(--nt-space-3) var(--nt-space-4);
  max-width:var(--nt-measure-headline);
  font-size:var(--nt-text-display-2);font-weight:var(--nt-text-display-2-weight);
  letter-spacing:var(--nt-text-display-2-track);line-height:var(--nt-text-display-2-leading);
  color:var(--nt-label-1);
}

/* ------------------------------------------- panel interaktywny (drabina transz) */
.panel{
  background:var(--nt-surface-elevated);
  border:1px solid var(--nt-separator);
  border-radius:var(--nt-radius-2xl);
  padding:var(--nt-space-5);
  box-shadow:var(--nt-shadow-2);
}
.panel h3{font-family:var(--nt-font-display);font-size:var(--nt-text-headline);font-weight:600;letter-spacing:var(--nt-text-headline-track);line-height:var(--nt-text-headline-leading)}
.panel .sub{margin-top:var(--nt-space-1);font-size:var(--nt-text-footnote);line-height:var(--nt-text-footnote-leading);color:var(--nt-label-3)}
.panel .note{margin-top:var(--nt-space-4);font-size:var(--nt-text-caption);line-height:var(--nt-text-caption-leading);letter-spacing:var(--nt-text-caption-track);color:var(--nt-label-3)}

.bars{display:grid;grid-template-columns:repeat(6,1fr);gap:var(--nt-space-2);align-items:end;height:196px;margin-block:var(--nt-space-5) var(--nt-space-2)}
.barcol{display:flex;flex-direction:column;justify-content:flex-end;height:100%;gap:var(--nt-space-2)}
.bar{
  width:100%;
  border-radius:var(--nt-radius-xs) var(--nt-radius-xs) 2px 2px;
  background:var(--nt-bar-idle);
  transition:background-color var(--nt-duration-base) var(--nt-ease-out);
}
.bar.done{background:var(--nt-bar-done)}
.bar.last{background:var(--nt-accent)}
/* Etap w toku dostaje DRUGI kanał rozróżnienia, nie tylko kolor: jego etykieta
   idzie na poziom 1 i wagę 500. Złoto wobec słupka biernego ma w motywie
   jasnym 1,78:1 — hue różni się mocno, ale kolor sam nie powinien być jedynym
   nośnikiem stanu. */
.bar.last ~ .barlabel{color:var(--nt-label-1);font-weight:500}
/* Etykiety słupków: na wąskim ekranie ZNIKAJĄ, a nie kurczą się do 8,5px.
   Nazwę etapu i tak niesie podpis suwaka, więc informacja nie ginie. */
.barlabel{font-size:var(--nt-text-caption);letter-spacing:var(--nt-text-caption-track);line-height:var(--nt-text-caption-leading);color:var(--nt-label-3);text-align:center;min-height:4.2em}

.slider-wrap{margin-block:var(--nt-space-2) var(--nt-space-4)}
.slider-wrap label{
  display:block;
  font-family:var(--nt-font-mono);font-size:var(--nt-text-caption);
  letter-spacing:var(--nt-text-eyebrow-track);text-transform:uppercase;
  color:var(--nt-label-3);
}
/* Suwak ma 44px wysokości pola dotyku, choć widoczny tor ma 6px. */
input[type=range]{
  -webkit-appearance:none;appearance:none;
  width:100%;height:var(--nt-target-min);
  margin:0;background:transparent;cursor:pointer;
}
input[type=range]::-webkit-slider-runnable-track{
  height:6px;border-radius:var(--nt-radius-full);
  background:linear-gradient(var(--nt-accent),var(--nt-accent)) no-repeat var(--nt-surface-tint);
  background-size:var(--fill,50%) 100%;
}
input[type=range]::-webkit-slider-thumb{
  -webkit-appearance:none;
  width:24px;height:24px;margin-top:-9px;
  border-radius:var(--nt-radius-full);
  background:var(--nt-accent);
  border:3px solid var(--nt-surface-elevated);
  box-shadow:var(--nt-shadow-1);
}
input[type=range]::-moz-range-track{
  height:6px;border-radius:var(--nt-radius-full);
  background:linear-gradient(var(--nt-accent),var(--nt-accent)) no-repeat var(--nt-surface-tint);
  background-size:var(--fill,50%) 100%;
}
input[type=range]::-moz-range-thumb{
  width:18px;height:18px;border-radius:var(--nt-radius-full);
  background:var(--nt-accent);border:3px solid var(--nt-surface-elevated);
}

.readouts{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--nt-space-3);border-top:1px solid var(--nt-separator);padding-top:var(--nt-space-4)}
.readout .rv{font-family:var(--nt-font-mono);font-variant-numeric:tabular-nums;font-size:var(--nt-text-title-3);font-weight:500;color:var(--nt-label-1)}
/* Wyróżniona liczba: dziś złota (2,84:1). Wyróżnienie robi WAGA i pozycja,
   a jeśli kolor ma zostać, to w wariancie dopuszczonym do tekstu. */
.readout .rv.signal{color:var(--nt-accent-ink-on-surface)}
.readout .rl{margin-top:var(--nt-space-1);font-size:var(--nt-text-caption);line-height:var(--nt-text-caption-leading);color:var(--nt-label-3)}

/* ------------------------------------------------------------- pas marki */
.band{background:var(--nt-surface-brand);color:var(--nt-label-on-brand-1)}
.band .eyebrow{color:var(--nt-label-on-brand-3)}
.band h2{color:var(--nt-label-on-brand-1);margin-block:var(--nt-space-3)}
.band p{color:var(--nt-label-on-brand-2);max-width:var(--nt-measure-lead)}
.band strong{color:var(--nt-label-on-brand-1)}
.band-center{text-align:center}
.band-center h2,.band-center p{margin-inline:auto}
.band-center p{margin-bottom:var(--nt-space-6)}

/* Sekcja stojąca o warstwę wyżej niż tło strony. Krok tła, nie obwódka —
   to jest właśnie to grupowanie, którego hairline nie umie unieść (1,19:1). */
.surface-elevated{background:var(--nt-surface-elevated)}

/* ------------------------------------------------------------ karty problemów */
.grid-3{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--nt-space-4);margin-top:var(--nt-space-7)}
.grid-2{display:grid;grid-template-columns:1fr 1fr;gap:var(--nt-space-5);align-items:start;margin-top:var(--nt-space-6)}
.card-plain{
  background:var(--nt-surface-elevated);
  border:1px solid var(--nt-separator);
  border-radius:var(--nt-radius-xl);
  padding:var(--nt-space-5);
}
/* Numer bólu przestaje być czerwony. To numeracja listy, nie stan błędu, więc
   kolor alarmowy niósł nieprawdziwą informację — i przy okazji nie przechodził
   4,5:1 na swoim tle (4,26:1). */
.card-plain .num{
  display:grid;place-items:center;
  width:28px;height:28px;margin-bottom:var(--nt-space-3);
  border-radius:var(--nt-radius-sm);
  background:var(--nt-surface-tint);
  font-family:var(--nt-font-mono);font-size:var(--nt-text-footnote);font-weight:500;
  color:var(--nt-label-2);
}
.card-plain h3{margin-bottom:var(--nt-space-2);font-size:var(--nt-text-headline);font-weight:var(--nt-text-headline-weight);letter-spacing:var(--nt-text-headline-track);line-height:var(--nt-text-headline-leading)}
.card-plain p{font-size:var(--nt-text-subhead);line-height:var(--nt-text-subhead-leading);color:var(--nt-label-2)}
/* Cytat persony: „zadanie do wykonania" wypowiedziane jej głosem. Kursywa
   i atrament poziomu 1, bo to jest teza karty, a nie jej komentarz. */
.card-plain .job{font-style:italic;color:var(--nt-label-1)}

/* ------------------------------------------------------------------- kroki */
.steps{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--nt-space-5);margin-top:var(--nt-space-8)}
.step{padding-top:var(--nt-space-4);border-top:2px solid var(--nt-separator-on-brand)}
.step .n{font-family:var(--nt-font-mono);font-size:var(--nt-text-footnote);font-weight:500;color:var(--nt-label-on-brand-3)}
.step h3{margin-block:var(--nt-space-2);font-size:var(--nt-text-headline);font-weight:var(--nt-text-headline-weight);letter-spacing:var(--nt-text-headline-track);line-height:var(--nt-text-headline-leading);color:var(--nt-label-on-brand-1)}
.step p{font-size:var(--nt-text-subhead);line-height:var(--nt-text-subhead-leading);color:var(--nt-label-on-brand-2)}

/* ------------------------------------------------------------------ moduły */
.feat{
  position:relative;
  background:var(--nt-surface-elevated);
  border:1px solid var(--nt-separator);
  border-radius:var(--nt-radius-xl);
  padding:var(--nt-space-5);
  transition:transform var(--nt-duration-base) var(--nt-ease-out);
}
/* Cień na pseudoelemencie, animowana jego przezroczystość. Animowanie
   `box-shadow` bezpośrednio jest na liście antywzorców i słusznie: każda klatka
   każe przeglądarce przeliczyć rozmycie, zamiast złożyć gotową warstwę. */
.feat::after{
  content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;
  box-shadow:var(--nt-shadow-2);opacity:0;
  transition:opacity var(--nt-duration-base) var(--nt-ease-out);
}
.feat:hover{transform:translateY(-2px)}
.feat:hover::after{opacity:1}
.feat .ic{display:grid;place-items:center;width:40px;height:40px;margin-bottom:var(--nt-space-4);border-radius:var(--nt-radius-md);background:var(--nt-surface-tint)}
.feat .ic svg{width:22px;height:22px;stroke:var(--nt-label-brand);fill:none;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.feat h3{margin-bottom:var(--nt-space-2);font-size:var(--nt-text-headline);font-weight:var(--nt-text-headline-weight);letter-spacing:var(--nt-text-headline-track);line-height:var(--nt-text-headline-leading)}
.feat p{font-size:var(--nt-text-subhead);line-height:var(--nt-text-subhead-leading);color:var(--nt-label-2)}

/* ------------------------------------------------------- wiersz filaru
   Naprzemienny wiersz „tekst obok panelu", z którego zbudowany jest przegląd
   Produktu i strony poszczególnych filarów. Zastąpi zastany `.frow`, który
   ZOSTAJE do 2d.4b, bo używają go jeszcze `silnik-finansowy` i `platforma`
   — nowa nazwa jest tu konieczna, nie kosmetyczna: ta sama nazwa znaczyłaby,
   że obie reguły działają na obu stronach i migracja jednej zmienia drugą. */
.pillar-row{
  display:grid;grid-template-columns:1fr 1fr;
  gap:var(--nt-space-9);align-items:center;
  padding-block:var(--nt-space-8);
  border-top:1px solid var(--nt-separator);
}
.pillar-row:first-of-type{border-top:0}
.pillar-row.flip .pillar-panel{order:-1}
.pillar-row h3{
  margin-block:var(--nt-space-3);
  font-size:var(--nt-text-title-2);font-weight:var(--nt-text-title-2-weight);
  letter-spacing:var(--nt-text-title-2-track);line-height:var(--nt-text-title-2-leading);
  color:var(--nt-label-1);
}
.pillar-row p{font-size:var(--nt-text-subhead);line-height:var(--nt-text-subhead-leading);color:var(--nt-label-2)}
.pillar-row .btn{margin-top:var(--nt-space-5)}
.pillar-panel{
  position:relative;
  display:flex;flex-direction:column;gap:var(--nt-space-3);justify-content:center;
  min-height:200px;
  background:var(--nt-surface-elevated);
  border:1px solid var(--nt-separator);
  border-radius:var(--nt-radius-xl);
  padding:var(--nt-space-5);
  box-shadow:var(--nt-shadow-1);
}
/* Lista odhaczeń.

   🔴 NAZWA `.tick-list`, A NIE `.checklist`, I TO JEST POPRAWKA BŁĘDU Z TEJ
   SAMEJ PACZKI, nie kaprys. Najpierw nazwałem ten komponent `.checklist` —
   nazwą, którą część zastana JUŻ ZAJMUJE (używają jej `cennik` i `dla-kogo`).
   Reguła zastana stoi w pliku niżej, więc przy równej specyficzności WYGRYWAŁA:
   panel na stronie Produktu renderował się typografią zastaną, a nowa reguła
   nie robiła nic. **Żadna bramka tego nie złapała** — 15,5px przechodzi próg
   12px, kontrast też, więc pomiar był zielony, a strona nie stała na tokenach.
   Wyłapało to dopiero obejrzenie zrzutu: na liście były separatory, których
   nowa reguła nie rysuje.

   🔴 WNIOSEK OGÓLNIEJSZY OD PRZYPADKU: nazwa NOWEGO komponentu tokenowego
   podlega tej samej bramce antyduplikatowej co nowa zasada — przed nadaniem
   sprawdza się grepem, czy arkusz jej nie zajmuje. Nazwa „naturalna" jest przy
   tym najbardziej narażona, bo naturalna była też dla autora części zastanej.

   JEDNA lista zamiast dwóch: arkusz zastany trzymał listę
   z ptaszkiem (`.in-list`) i listę ze złotym kwadratem (`.card li`, `.frow li`)
   dla tej samej treści, czyli wyliczenia tego, co jest w środku. Znak wchodzi
   maską, a nie obrazkiem w tle, żeby brał kolor z tokenu i reagował na motyw
   — zastany wariant miał zieleń marki wpisaną w adres danych SVG. */
.tick-list{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:var(--nt-space-2)}
.tick-list li{position:relative;padding-left:var(--nt-space-7);font-size:var(--nt-text-subhead);line-height:var(--nt-text-subhead-leading);color:var(--nt-label-1)}
.tick-list li::before{
  content:"";position:absolute;left:0;top:0.15em;
  width:18px;height:18px;border-radius:var(--nt-radius-xs);
  background:var(--nt-surface-tint);
}
.tick-list li::after{
  content:"";position:absolute;left:4px;top:calc(0.15em + 4px);
  width:10px;height:10px;
  background:var(--nt-label-brand);
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12.5l4.5 4.5L19 7'/%3E%3C/svg%3E") center/contain no-repeat;
  mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12.5l4.5 4.5L19 7'/%3E%3C/svg%3E") center/contain no-repeat;
}

/* ---------------------------------------------------- odnośniki krzyżowe
   Blok „czytaj dalej" na dole stron filarów. Zastąpi zastane `.cross-*`,
   które ZOSTAJĄ do 2d.4b z tego samego powodu co `.frow`. Etykieta używa
   tokenowego `.eyebrow`, a odnośnik z grotem `.more`, więc ten blok nie
   wnosi ani jednej własnej reguły typograficznej. */
.crosslinks{display:grid;grid-template-columns:1fr 1fr;gap:var(--nt-space-4);margin-top:var(--nt-space-6)}
.crosslink{
  position:relative;
  display:flex;flex-direction:column;gap:var(--nt-space-1);
  background:var(--nt-surface-elevated);
  border:1px solid var(--nt-separator);
  border-radius:var(--nt-radius-lg);
  padding:var(--nt-space-5);
  transition:transform var(--nt-duration-base) var(--nt-ease-out),
             border-color var(--nt-duration-base) var(--nt-ease-out);
}
.crosslink::after{
  content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;
  box-shadow:var(--nt-shadow-2);opacity:0;
  transition:opacity var(--nt-duration-base) var(--nt-ease-out);
}
.crosslink:hover{transform:translateY(-2px);border-color:var(--nt-separator-strong)}
.crosslink:hover::after{opacity:1}
.crosslink .cx-title{
  font-family:var(--nt-font-display);
  font-size:var(--nt-text-headline);font-weight:var(--nt-text-headline-weight);
  letter-spacing:var(--nt-text-headline-track);line-height:var(--nt-text-headline-leading);
  color:var(--nt-label-1);
}
.crosslink .cx-desc{font-size:var(--nt-text-subhead);line-height:var(--nt-text-subhead-leading);color:var(--nt-label-2)}
.crosslink .more{margin-top:var(--nt-space-2)}
.crosslinks-back{margin-top:var(--nt-space-6);text-align:center}

/* ------------------------------------------------- panel z wierszami danych
   Miniaturowa tabela w panelu filaru: nazwa, kwota, znacznik stanu. Zastępuje
   zastane `.mini-row`, a nazwy zostają, bo używały ich WYŁĄCZNIE dwie strony
   tej paczki — reguła się PRZENOSI, a nie dubluje, więc kolizji nie ma. */
.mini-rows{display:flex;flex-direction:column;gap:var(--nt-space-2)}
.mini-row{
  display:flex;align-items:center;justify-content:space-between;gap:var(--nt-space-2);
  padding:var(--nt-space-3) var(--nt-space-4);
  border:1px solid var(--nt-separator);
  border-radius:var(--nt-radius-md);
  font-size:var(--nt-text-footnote);line-height:var(--nt-text-footnote-leading);
}
.mini-row .nm{color:var(--nt-label-1);font-weight:500}
.mini-row .amt{font-family:var(--nt-font-mono);font-variant-numeric:tabular-nums;color:var(--nt-label-1);margin-left:auto}

/* ------------------------------------------------------- znacznik stanu
   🔴 DWIE ZMIANY WOBEC WERSJI ZASTANEJ, OBIE ZMIERZONE, NIE ESTETYCZNE.

   Pismo 10,5px → przypis. Zastany znacznik był NAJMNIEJSZYM PISMEM CAŁEGO
   SERWISU i jedynym miejscem, w którym czwarta bramka `apple-design` (próg
   12px) świeciła czerwono po 2d.4a.

   Stan niesie ATRAMENT, a nie tło. Zastane warianty malowały tło hexem
   (`#e3f3ec`, `#eef1f0`) i brały kolor tekstu z `--success` albo `--slate`,
   przez co `pill.ok` miał 3,77:1, `pill.gold` 2,84:1, a `pill.wait` 1,08:1.
   Tokeny `*-ink` są zdefiniowane OSOBNO dla motywu jasnego i ciemnego właśnie
   po to, żeby próg trzymał się w obu — tło zostaje neutralne, a różnicę robi
   kolor pisma. To ta sama decyzja co przy złocie: kolor jako wypełnienie,
   nie jako jedyny nośnik informacji. */
.pill{
  display:inline-flex;align-items:center;
  padding:var(--nt-space-1) var(--nt-space-3);
  border-radius:var(--nt-radius-full);
  background:var(--nt-surface-tint);
  font-family:var(--nt-font-mono);
  font-size:var(--nt-text-footnote);line-height:var(--nt-text-footnote-leading);
  letter-spacing:var(--nt-text-eyebrow-track);
  text-transform:uppercase;
  color:var(--nt-label-2);
  white-space:nowrap;
}
.pill.ok{color:var(--nt-status-success-ink)}
/* 🔴 WARIANT ZŁOTY BIERZE ZŁOTO JAKO WYPEŁNIENIE, A NIE JAKO ATRAMENT, i to
   jest poprawka zmierzona w tej samej paczce, nie wybór z góry. Pierwsza wersja
   dawała mu `--nt-accent-ink-on-surface`, czyli jedyny token dopuszczający
   złoto jako tekst — ale ten token jest skalibrowany NA PAPIERZE (4,81:1),
   a znacznik stoi na tle podbarwionym: tam wychodzi **4,24:1**, czyli poniżej
   progu. Bramka to zmierzyła i zatrzymała 12 trafień. Złoto jako tło z tokenem
   atramentu przeznaczonym na akcent daje **7,79:1** w jasnym i **6,85:1**
   w ciemnym, i jest zgodne z rozstrzygnięciem „złoto wyłącznie jako
   wypełnienie". Token dobrany pod jedno tło nie przenosi się na inne. */
.pill.gold{background:var(--nt-accent);color:var(--nt-on-accent)}
.pill.wait{background:var(--nt-surface-sunken);color:var(--nt-label-2)}

/* ------------------------------------------------------- kolumna liczbowa
   Tabela cennika używa tego samego `.compare` co porównanie na stronie
   głównej — jedna tabela na serwis zamiast dwóch. Dochodzi wyłącznie kolumna
   liczbowa: wyrównanie do prawej i cyfry o stałej szerokości, żeby kwoty
   dawały się porównywać wzrokiem. 🔴 Sprawdzone przed dopisaniem, że strona
   główna nie ma `.num` WEWNĄTRZ `.compare` (jej `.num` to numer w `.card-plain`),
   więc ta reguła jej nie dotyka. */
.compare .num{text-align:right;font-family:var(--nt-font-mono);font-variant-numeric:tabular-nums}
/* Nota pod tabelą albo pod kalkulatorem: metadana, nie treść, więc poziom 3.
   Klasa stoi osobno, bo `.panel .note` obok jest zakotwiczona w panelu hero
   i nie da się jej użyć poza nim. */
.note{color:var(--nt-label-3)}
.note strong{color:var(--nt-label-2)}

/* ---------------------------------------------------------- kalkulator ceny
   Dwa panele: wejście na powierzchni wyniesionej, wynik na marce. Wynik
   dostaje `.on-brand`, więc bierze atramenty `--nt-label-on-brand-*`, które są
   zdefiniowane per motyw — zastana wersja miała tam wpisane `#fff`, `#bcd4ce`
   i `#9fc0b9`, i to z nich brały się trafienia kontrastu (2,2:1 na wyróżnionej
   liczbie i 11,5px na podpisie komórki). */
.calc{display:grid;grid-template-columns:1fr 1.05fr;gap:var(--nt-space-5);align-items:stretch;margin-top:var(--nt-space-6)}
.calc-in,.calc-out{border-radius:var(--nt-radius-xl);padding:var(--nt-space-6)}
.calc-in{background:var(--nt-surface-elevated);border:1px solid var(--nt-separator);box-shadow:var(--nt-shadow-1)}
.calc-out{background:var(--nt-surface-brand);color:var(--nt-label-on-brand-1)}
.calc-in h3{margin-bottom:var(--nt-space-5);font-size:var(--nt-text-headline);font-weight:var(--nt-text-headline-weight);letter-spacing:var(--nt-text-headline-track);line-height:var(--nt-text-headline-leading)}

.field{margin-bottom:var(--nt-space-5)}
.field:last-child{margin-bottom:0}
.field label{
  display:flex;justify-content:space-between;align-items:baseline;gap:var(--nt-space-3);
  margin-bottom:var(--nt-space-2);
  font-size:var(--nt-text-subhead);font-weight:500;color:var(--nt-label-1);
}
.field label .v{font-family:var(--nt-font-mono);font-variant-numeric:tabular-nums;color:var(--nt-label-brand);font-weight:500}
/* 🔴 Pole liczbowe ma 44px WYSOKOŚCI POLA DOTYKU. Zastane miało 20px i dawało
   wszystkie 12 trafień licznika celów dotyku, jakie zostały na serwisie. */
.field .inp{
  display:flex;align-items:center;gap:var(--nt-space-2);
  border:1px solid var(--nt-separator-strong);border-radius:var(--nt-radius-md);
  padding-inline:var(--nt-space-4);
  background:var(--nt-surface-base);
}
.field .inp:focus-within{border-color:var(--nt-link)}
.field .inp input{
  flex:1;min-width:0;min-height:var(--nt-target-min);
  border:0;outline:0;background:transparent;
  font-family:var(--nt-font-mono);font-variant-numeric:tabular-nums;
  font-size:var(--nt-text-subhead);color:var(--nt-label-1);
}
.field .inp .unit{font-size:var(--nt-text-footnote);color:var(--nt-label-3);white-space:nowrap}
.field .hint{margin-top:var(--nt-space-2);font-size:var(--nt-text-footnote);line-height:var(--nt-text-footnote-leading);color:var(--nt-label-3)}

.calc-out .calc-band{
  margin-bottom:var(--nt-space-2);
  font-family:var(--nt-font-mono);font-size:var(--nt-text-footnote);
  letter-spacing:var(--nt-text-eyebrow-track);text-transform:uppercase;
  color:var(--nt-label-on-brand-3);
}
.calc-out .big{font-family:var(--nt-font-display);font-weight:var(--nt-text-display-2-weight);font-size:var(--nt-text-display-2);line-height:1}
.calc-out .big .cur{font-size:.5em;font-weight:600;color:var(--nt-label-on-brand-2);margin-left:var(--nt-space-1)}
.calc-out .sub2{margin-top:var(--nt-space-2);font-size:var(--nt-text-footnote);color:var(--nt-label-on-brand-2)}
.calc-out .grid2{
  display:grid;grid-template-columns:1fr 1fr;gap:1px;
  background:var(--nt-separator-on-brand);
  border-radius:var(--nt-radius-md);overflow:hidden;margin-top:var(--nt-space-6);
}
.calc-out .cell{background:var(--nt-surface-brand);padding:var(--nt-space-3) var(--nt-space-4)}
.calc-out .cv{font-family:var(--nt-font-mono);font-variant-numeric:tabular-nums;font-size:var(--nt-text-headline);font-weight:500;color:var(--nt-label-on-brand-1)}
/* Wyróżniona liczba: waga i pozycja, nie kolor. Zastana wersja malowała ją
   złotem na zieleni marki, co dawało 4,04:1, czyli poniżej progu. */
.calc-out .cv.gold{color:var(--nt-label-on-brand-1);font-weight:700}
.calc-out .cl{margin-top:var(--nt-space-1);font-size:var(--nt-text-footnote);line-height:var(--nt-text-footnote-leading);color:var(--nt-label-on-brand-2)}
.calc-out .punch{
  margin-top:var(--nt-space-5);padding-top:var(--nt-space-4);
  border-top:1px solid var(--nt-separator-on-brand);
  font-size:var(--nt-text-subhead);line-height:var(--nt-text-subhead-leading);
  color:var(--nt-label-on-brand-2);
}
.calc-out .punch b{color:var(--nt-label-on-brand-1)}

/* ------------------------------------------------------------------- FAQ */
.faq{max-width:var(--nt-width-prose);margin:var(--nt-space-8) auto 0}
.qa{border-bottom:1px solid var(--nt-separator)}
.qa button{
  display:flex;justify-content:space-between;align-items:center;gap:var(--nt-space-4);
  width:100%;min-height:var(--nt-target-min);
  padding-block:var(--nt-space-4);
  background:none;border:0;text-align:left;cursor:pointer;
  font-family:var(--nt-font-display);font-size:var(--nt-text-headline);font-weight:600;
  color:var(--nt-label-1);
}
.qa .plus{flex:0 0 auto;width:22px;height:22px;position:relative;transition:transform var(--nt-duration-base) var(--nt-ease-out)}
.qa .plus::before,.qa .plus::after{content:"";position:absolute;left:50%;top:50%;background:var(--nt-label-brand);border-radius:var(--nt-radius-xs)}
.qa .plus::before{width:14px;height:2px;transform:translate(-50%,-50%)}
.qa .plus::after{width:2px;height:14px;transform:translate(-50%,-50%);transition:transform var(--nt-duration-base) var(--nt-ease-out)}
.qa[aria-open="true"] .plus::after{transform:translate(-50%,-50%) scaleY(0)}
.qa .ans{max-height:0;overflow:hidden;transition:max-height var(--nt-duration-slow) var(--nt-ease-out)}
.qa .ans p{margin:0;padding-bottom:var(--nt-space-5);font-size:var(--nt-text-subhead);line-height:var(--nt-text-subhead-leading);color:var(--nt-label-2);max-width:var(--nt-measure-prose)}
.divider-top{border-top:1px solid var(--nt-separator)}

/* --------------------------------------------------------- tabela porównawcza
   Kolumna Nurtoo wyróżnia się KROKIEM TŁA, nie obwódką: krok tła widać także
   przy wyłączonych kolorach autora, a hairline w tej roli miał 1,03:1. */
.table-scroll{max-width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}
.compare{width:100%;border-collapse:collapse;font-size:var(--nt-text-subhead)}
.compare th,.compare td{padding:var(--nt-space-3);text-align:left;border-bottom:1px solid var(--nt-separator)}
.compare thead th{font-family:var(--nt-font-display);font-size:var(--nt-text-footnote);font-weight:600;color:var(--nt-label-2)}
.compare thead th.us{color:var(--nt-label-brand)}
.compare td.c,.compare th.c{text-align:center;width:88px}
.compare tbody tr:last-child td{border-bottom:0}
/* „jest" i „nie ma" — oba na poziomie 3 etykiet albo wyżej, bo oba NIOSĄ
   informację. Dziś znak „nie ma" ma 1,94:1 i jest jedynym jej nośnikiem. */
.compare .yes{color:var(--nt-status-success-ink);font-weight:700}
.compare .no{color:var(--nt-label-3)}
/* 🔴 WYRÓŻNIENIE OSTATNIEJ KOLUMNY NALEŻY DO TABELI PORÓWNAWCZEJ, A NIE DO
   KAŻDEJ TABELI, i zawężenie tego selektora jest poprawką z 2d.5. Cennik
   wciągnął `.compare` jako wspólny komponent i dostał podświetloną kolumnę
   „≈ % zysku" — bo reguła mówiła „ostatnia kolumna", a miała na myśli
   „kolumnę Nurtoo". Modyfikator `.versus` nazywa to wprost; strona główna
   dostaje go w znacznikach i renderuje się identycznie, co potwierdzone
   porównaniem zrzutu przed i po. */
.compare.versus tbody td:last-child,.compare.versus thead th:last-child{background:var(--nt-surface-elevated)}
.compare thead th:last-child{border-radius:var(--nt-radius-sm) var(--nt-radius-sm) 0 0}

/* --------------------------------------------------------------- pas liczb */
.grid-4{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--nt-space-4);margin-top:var(--nt-space-7)}
.stat{background:var(--nt-surface-elevated);border:1px solid var(--nt-separator);border-radius:var(--nt-radius-lg);padding:var(--nt-space-5)}
.stat .sv{font-family:var(--nt-font-mono);font-variant-numeric:tabular-nums;font-size:var(--nt-text-title-1);font-weight:500;color:var(--nt-label-brand);line-height:1.1}
.stat .sl{margin-top:var(--nt-space-2);font-size:var(--nt-text-footnote);line-height:var(--nt-text-footnote-leading);color:var(--nt-label-2)}

/* ------------------------------------------------------------ cytat założyciela
   Grupowanie odstępem i krokiem tła, bez gradientu i bez obwódki. */
.founder{
  display:grid;grid-template-columns:1.4fr 1fr;gap:var(--nt-space-8);align-items:center;
  background:var(--nt-surface-sunken);
  border-radius:var(--nt-radius-2xl);
  padding:var(--nt-space-8);
}
.founder blockquote{
  margin:0;
  font-family:var(--nt-font-display);font-weight:500;
  font-size:var(--nt-text-title-1);
  letter-spacing:var(--nt-text-title-1-track);
  line-height:1.3;
  color:var(--nt-label-1);
}
.founder .by{margin-top:var(--nt-space-4);font-size:var(--nt-text-footnote);line-height:var(--nt-text-footnote-leading);color:var(--nt-label-2)}
.founder .by b{color:var(--nt-label-1)}
.founder .stats{display:grid;gap:var(--nt-space-3)}

/* --------------------------------------------------------------- wezwanie */
.final{
  position:relative;overflow:hidden;
  background:var(--nt-surface-brand);
  border-radius:var(--nt-radius-2xl);
  padding:var(--nt-space-9) var(--nt-space-6);
  text-align:center;
}
.final h2{margin-inline:auto;margin-bottom:var(--nt-space-3);max-width:20ch;color:var(--nt-label-on-brand-1)}
.final p{margin-inline:auto;margin-bottom:var(--nt-space-6);max-width:46ch;color:var(--nt-label-on-brand-2)}
.demo-form{display:flex;gap:var(--nt-space-2);max-width:520px;margin-inline:auto;flex-wrap:wrap;justify-content:center}
.demo-form input,.demo-form select{
  flex:1;min-width:160px;min-height:var(--nt-target-min);
  padding:var(--nt-space-3) var(--nt-space-4);
  border-radius:var(--nt-radius-md);
  border:1px solid var(--nt-separator-on-brand);
  background:var(--nt-field-on-brand);
  color:var(--nt-label-on-brand-1);
  font-family:var(--nt-font-text);font-size:var(--nt-text-subhead);
}
.demo-form input:disabled,.demo-form select:disabled{color:var(--nt-label-on-brand-3);cursor:not-allowed}
.demo-form input::placeholder{color:var(--nt-label-on-brand-3)}
.demo-form select option{color:var(--nt-label-1);background:var(--nt-surface-elevated)}
/* Pole odrzucone przy walidacji. 🔴 Nośnikiem informacji „to jest błąd" jest
   OBRYS pola i treść komunikatu, a nie kolor tekstu komunikatu, jak było do
   2d. Dwa powody, oba mierzalne: kolor jako jedyny nośnik odpada z zasady,
   a złoto, którym ten komunikat był barwiony, ma na pasie marki 4,49:1,
   czyli PONIŻEJ progu 4,5:1 dla tekstu. Obrys jest elementem nietekstowym,
   więc obowiązuje go próg 3:1, a `--nt-c-danger-dim` daje tu 4,49:1. */
.demo-form input[aria-invalid="true"]{
  border-color:var(--nt-c-danger-dim);
  box-shadow:inset 0 0 0 1px var(--nt-c-danger-dim);
}
.form-msg{margin-top:var(--nt-space-4);min-height:1.5em;font-size:var(--nt-text-subhead);color:var(--nt-label-on-brand-1)}

/* ---------------------------------------------------------------------- proza
   Tekst ciągły: dokumenty prawne (paczka 2d.2), a od 2d.3 także treść wpisów.

   🔴 REGUŁY SĄ ELEMENTOWE, NIE KLASOWE, I TO JEST DECYZJA, NIE SKRÓT. Treść
   wpisów pochodzi z Markdownu, w którym klas się nie wpisuje, a dokumenty
   prawne są pisane prozą i mają wersje poprawiane przez prawnika, nie przez
   nas. Wymaganie klasy na każdym akapicie oznaczałoby, że kolejna wersja
   dokumentu przyjdzie bez klas i straci formatowanie — czyli kontrola zależna
   od czyjejś uwagi, i to uwagi osoby spoza tego repo.

   🔴 DZIĘKI TEMU BLOK <main> DOKUMENTU PRAWNEGO JEST WYCINKIEM BAJTOWYM:
   klasa stoi na opakowaniu, a w środku nie zmieniono ani jednego znaku.

   Zmiany wobec własnego arkusza stron prawnych, wszystkie zamierzone:
   · tekst 15,5px → 17px, czyli kotwica skali. Dokument prawny czyta się
     w całości, a nie skanuje, więc rozmiar poniżej kotwicy był tu najgorszym
     możliwym wyborem;
   · `#27322f` na przezroczysty atrament poziomu 2. Ten hex miał w motywie
     ciemnym 1,46:1, bo nie reagował na motyw wcale;
   · szerokość kolumny 820px → `--nt-width-prose`, czyli 68 znaków plus
     marginesy. Próg „poniżej 75 znaków w wierszu" jest teraz spełniony
     z konstrukcji, a nie z oszacowania w pikselach;
   · odnośniki dostają podkreślenie. W prozie kolor sam nie wystarcza,
     bo odnośnik w środku akapitu nie ma innego wyróżnika. */
.prose > * + *{margin-top:var(--nt-space-4)}
.prose h1{
  font-size:var(--nt-text-display-2);font-weight:var(--nt-text-display-2-weight);
  letter-spacing:var(--nt-text-display-2-track);line-height:var(--nt-text-display-2-leading);
  color:var(--nt-label-1);
}
.prose h2{
  margin-top:var(--nt-space-8);
  font-size:var(--nt-text-title-3);font-weight:var(--nt-text-title-3-weight);
  letter-spacing:var(--nt-text-title-3-track);line-height:var(--nt-text-title-3-leading);
  color:var(--nt-label-1);
}
/* 🔴 `h3` WCHODZI, CHOC DZIS NIE UZYWA GO ANI JEDEN WPIS — i to jest MIGRACJA
   istniejacej reguly `.post-body h3`, a nie nowa regula dopisana na zapas.
   Bez niej `###` w przyszlym wpisie wypadnie z sama rodzina pisma z reguly
   bazowej: bez rozmiaru, bez wagi i bez marginesu, czyli nieodroznialnie od
   akapitu — i NIC tego nie zglosi, bo Markdown zbuduje sie poprawnie. */
.prose h3{
  margin-top:var(--nt-space-6);
  font-size:var(--nt-text-headline);font-weight:var(--nt-text-headline-weight);
  letter-spacing:var(--nt-text-headline-track);line-height:var(--nt-text-headline-leading);
  color:var(--nt-label-1);
}
.prose p,.prose li{
  font-size:var(--nt-text-body);line-height:var(--nt-text-body-leading);
  color:var(--nt-label-2);
}
.prose ul,.prose ol{padding-left:var(--nt-space-5)}
.prose li + li{margin-top:var(--nt-space-2)}
.prose strong{font-weight:600;color:var(--nt-label-1)}
.prose a{color:var(--nt-link);text-decoration:underline;text-underline-offset:3px;text-decoration-thickness:1px}
.prose a:hover{color:var(--nt-link-hover)}
/* Data wersji dokumentu: metadana, nie treść, więc poziom 3 i rozmiar przypisu. */
.prose .updated{
  margin-top:var(--nt-space-2);
  font-size:var(--nt-text-footnote);letter-spacing:var(--nt-text-footnote-track);
  line-height:var(--nt-text-footnote-leading);color:var(--nt-label-3);
}
/* Wyciąg danych podmiotu: karta, bo to blok danych, a nie akapit dokumentu. */
.prose .box{
  background:var(--nt-surface-elevated);
  border:1px solid var(--nt-separator);
  border-radius:var(--nt-radius-lg);
  padding:var(--nt-space-4) var(--nt-space-5);
}
.prose .box p{color:var(--nt-label-1)}

/* ------------------------------------------------------------ Aktualności
   Lista wpisow i pojedynczy wpis. TRESC wpisu formatuje `.prose` wyzej, bo
   pochodzi z Markdownu i nie ma w srodku ani jednej klasy (zmierzone przy
   2d.3: cztery wpisy uzywaja wylacznie `p`, `h2`, `ul`, `li`, `strong`, `a`).
   Ten blok obsluguje to, co jest WOKOL tresci: karty na liscie, naglowek
   wpisu i odnosnik powrotny.

   🔴 METKA SCHODZI ZE ZLOTA NA NEUTRALNY POZIOM 3, i nie jest to wybor tej
   paczki: to rozstrzygniecie z 2026-09-07 („zloto wylacznie jako wypelnienie,
   metki i tagi na poziom 3") przylozone do metki, ktorej wtedy nikt nie
   przegladal. Zmierzone PRZED zmiana, motyw jasny: 2,61:1 na liscie i 2,84:1
   na wpisie, oba ponizej progu 4,5:1, razem 16 trafien licznika kontrastu. */
.post-list{display:grid;gap:var(--nt-space-4);margin-top:var(--nt-space-8)}
.post-list-sec{padding-top:0}
.post-card{
  position:relative;display:block;
  background:var(--nt-surface-elevated);
  border:1px solid var(--nt-separator);
  border-radius:var(--nt-radius-xl);
  padding:var(--nt-space-5) var(--nt-space-6);
  transition:transform var(--nt-duration-base) var(--nt-ease-out),
             border-color var(--nt-duration-base) var(--nt-ease-out);
}
/* Cien na pseudoelemencie, animowana jego przezroczystosc — wzorzec wziety
   z `.feat`, a nie wymyslony tutaj. Dzisiejsza karta animowala `box-shadow`
   wprost, czyli kazala przegladarce przeliczac rozmycie w kazdej klatce,
   a bramka kroku 1 wymaga w pozycji „animowane wlasciwosci ukladu" zera. */
.post-card::after{
  content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;
  box-shadow:var(--nt-shadow-2);opacity:0;
  transition:opacity var(--nt-duration-base) var(--nt-ease-out);
}
.post-card:hover{transform:translateY(-2px);border-color:var(--nt-separator-strong)}
.post-card:hover::after{opacity:1}
.post-meta{
  display:inline-block;
  font-family:var(--nt-font-mono);
  font-size:var(--nt-text-footnote);font-weight:var(--nt-text-eyebrow-weight);
  letter-spacing:var(--nt-text-eyebrow-track);
  line-height:var(--nt-text-footnote-leading);
  text-transform:uppercase;
  color:var(--nt-label-3);
}
.post-card h2{
  margin-block:var(--nt-space-2);
  font-size:var(--nt-text-title-3);font-weight:var(--nt-text-title-3-weight);
  letter-spacing:var(--nt-text-title-3-track);line-height:var(--nt-text-title-3-leading);
  color:var(--nt-label-1);
}
.post-card p{font-size:var(--nt-text-subhead);line-height:var(--nt-text-subhead-leading);color:var(--nt-label-2)}
/* Odnośnik „idź dalej" z grotem. Komponent, nie część karty wpisu: od 2d.4a
   używa go także blok odnośników krzyżowych na stronach filarów. Grot jedzie
   `transform`, więc animacja nie dotyka układu. */
.more{
  display:inline-flex;align-items:center;gap:var(--nt-space-2);
  margin-top:var(--nt-space-4);
  font-family:var(--nt-font-display);
  font-size:var(--nt-text-subhead);font-weight:600;
  color:var(--nt-label-brand);
}
.more .arw{transition:transform var(--nt-duration-base) var(--nt-ease-out)}
.post-card:hover .more .arw,.crosslink:hover .more .arw{transform:translateX(4px)}

.post-head{padding-top:var(--nt-space-8);padding-bottom:var(--nt-space-2)}
.post-head .post-meta{display:block;margin-top:var(--nt-space-3)}
.post-head h1{
  margin-block:var(--nt-space-3);
  max-width:var(--nt-measure-headline);
  font-size:var(--nt-text-display-2);font-weight:var(--nt-text-display-2-weight);
  letter-spacing:var(--nt-text-display-2-track);line-height:var(--nt-text-display-2-leading);
  color:var(--nt-label-1);
}
.post-body{padding-top:var(--nt-space-4);padding-bottom:var(--nt-space-9)}
/* Odnosnik powrotny. `min-height` rowny minimalnemu celowi dotyku, wzorzec ten
   sam co przy odnosnikach w stopce. Zastany `.post-back` mial 24px wysokosci
   i dawal 16 z 40 trafien licznika celow dotyku CALEGO serwisu; zastany
   `.cross-back` ma 262x24 i daje kolejnych 12, na trzech stronach filarow.

   🔴 NAZWA ZMIENIONA W 2d.4a Z `.post-back` NA `.backlink`, bo to jedno
   pojecie, a nie dwa: odnosnik wracajacy o poziom wyzej. Trzymanie dwoch nazw
   dalo w arkuszu zastanym dwie reguly roznice sie wylacznie szerokoscia celu
   dotyku, i obie byly za male. Zastany `.cross-back` ZOSTAJE do 2d.4b, bo
   uzywaja go jeszcze `silnik-finansowy` i `platforma`. */
.backlink{
  display:inline-flex;align-items:center;
  min-height:var(--nt-target-min);
  font-size:var(--nt-text-subhead);
  color:var(--nt-label-2);
  text-decoration:underline;text-underline-offset:3px;text-decoration-thickness:1px;
  transition:color var(--nt-duration-fast) var(--nt-ease-out);
}
.backlink:hover{color:var(--nt-label-1)}

/* ------------------------------------------------------------------ stopka */
.site-footer{padding-block:var(--nt-space-9) var(--nt-space-7);color:var(--nt-label-2)}
.foot-grid{display:flex;justify-content:space-between;gap:var(--nt-space-7);flex-wrap:wrap}
.site-footer .tagline{margin-top:var(--nt-space-3);max-width:34ch;font-size:var(--nt-text-subhead);line-height:var(--nt-text-subhead-leading);color:var(--nt-label-3)}
.foot-links{display:flex;gap:var(--nt-space-8);flex-wrap:wrap}
.foot-col h4{margin-bottom:var(--nt-space-2);font-family:var(--nt-font-display);font-size:var(--nt-text-footnote);font-weight:600;letter-spacing:var(--nt-text-footnote-track);line-height:var(--nt-text-footnote-leading);color:var(--nt-label-1)}
.foot-col a{display:flex;align-items:center;min-height:var(--nt-target-min);font-size:var(--nt-text-subhead);color:var(--nt-label-2);transition:color var(--nt-duration-fast) var(--nt-ease-out)}
.foot-col a:hover{color:var(--nt-link)}
.foot-bottom{
  display:flex;justify-content:space-between;flex-wrap:wrap;gap:var(--nt-space-2);
  margin-top:var(--nt-space-7);padding-top:var(--nt-space-5);
  border-top:1px solid var(--nt-separator);
  font-size:var(--nt-text-footnote);color:var(--nt-label-3);
}

/* ------------------------------------------------------------------ odsłona
   Ruch tylko po to, żeby powiedzieć „to właśnie weszło w kadr". Pod
   `prefers-reduced-motion` token czasu schodzi do 1ms, więc zostaje samo
   przejście stanu, a nie zniknięcie treści. */
.reveal{opacity:0;transform:translateY(16px);transition:opacity var(--nt-duration-slow) var(--nt-ease-out),transform var(--nt-duration-spring) var(--nt-spring)}
.reveal.in{opacity:1;transform:none}
@media (prefers-reduced-motion: reduce){ .reveal{opacity:1;transform:none} }

/* ============================================================================
   RESPONSYWNOŚĆ
   Punkty łamania trzymamy dwa, tak jak dziś, żeby nie mnożyć stanów.
   ============================================================================ */
@media (max-width:900px){
  .hero-grid,.founder,.grid-2,.pillar-row,.crosslinks,.calc{grid-template-columns:1fr;gap:var(--nt-space-7)}
  .pillar-row.flip .pillar-panel{order:0}
  .founder{padding:var(--nt-space-6)}
  .steps{grid-template-columns:repeat(2,1fr)}
  .grid-3{grid-template-columns:1fr}
  .grid-4{grid-template-columns:repeat(2,1fr)}
}
@media (max-width:680px){
  .nav-links{display:none}
  .nav-cta .btn-ghost{display:none}
  .menu-btn{display:grid;place-items:center}
  .mobile-menu{display:block}
  .steps{grid-template-columns:1fr}
  .final{padding:var(--nt-space-7) var(--nt-space-5)}
  /* patrz komentarz przy .barlabel: etykiety słupków znikają zamiast maleć */
  .barlabel{display:none}
  .bars{height:132px;margin-bottom:var(--nt-space-4)}
  .readouts{grid-template-columns:1fr;gap:var(--nt-space-4)}
  .founder blockquote{font-size:var(--nt-text-title-2);line-height:var(--nt-text-title-2-leading)}
  .compare{font-size:var(--nt-text-footnote)}
  .compare th,.compare td{padding:var(--nt-space-2)}
  .compare td.c,.compare th.c{width:56px}
}
