/* ==========================================================================
   Prezentacja ekosystemu DNET — arkusz decku
   Docelowa ścieżka na produkcji: /prezentacja/styl.css

   DLACZEGO OSOBNY ARKUSZ, A NIE main.css SERWISU
   /assets/* ma nagłówek `max-age=31536000, immutable`. Dołożenie czegokolwiek
   do main.css wymusiłoby bump `?v=` w 12 plikach HTML — a przy pominięciu
   choćby jednego część serwisu serwowałaby stary arkusz przez rok.
   Deck trzyma swój CSS u siebie i ten problem znika w całości.

   TOKENY SĄ PRZEPISANE Z main.css, NIE WYMYŚLONE. Deck ma wyglądać jak
   dnet-tech.pl, nie jak osobny produkt. Jedyne własne wartości to te,
   których serwis nie ma, bo nie ma slajdów (--u, rytm aktów).
   ========================================================================== */

/* === 1. Tokeny === */
:root{
  /* warstwy — przepisane z main.css */
  --bg:#0a0b10;
  --bg-alt:#0e1016;
  --surface:#13151c;
  --surface-2:#171a22;
  --text:#f1f3f8;
  --muted:#8b93a7;
  --muted-strong:#a3acc2;
  --border:rgba(255,255,255,.08);
  --border-strong:rgba(255,255,255,.14);

  /* marka */
  --primary:#8b5cf6;
  --primary-dark:#7c3aed;
  --accent:#38bdf8;
  --violet:#a974f0;
  --green:#22c55e;
  --amber:#f59e0b;
  --brand-grad:linear-gradient(135deg,#8b5cf6,#a855f7,#38bdf8);
  --focus-ring:#38bdf8;

  /* kolory statusów — DOKŁADNIE te same co plakietki .tag-* w main.css,
     żeby kafel w decku i karta produktu mówiły tym samym kolorem */
  --st-gotowy:#4ade80;
  --st-beta:#fbbf24;
  --st-demo:#38bdf8;
  --st-rozwoj:#a9b1c2;

  /* kroje — z /assets/css/fonts.css, self-host */
  --font:'Inter','Segoe UI',system-ui,-apple-system,sans-serif;
  --mono:'JetBrains Mono',ui-monospace,'Cascadia Code',monospace;

  /* JEDNOSTKA SLAJDU
     Cała typografia decku jest wielokrotnością --u, więc slajd skaluje się
     do okna zamiast łamać się przy nietypowej proporcji. Bierzemy MNIEJSZY
     z wymiarów: przy szerokim, niskim oknie (laptop 16:10 z paskiem zadań)
     decyduje wysokość, inaczej tekst wyjeżdża poza kadr. */
  --u:min(1.2vw,2.1vh);

  /* Elewacja przepisana 1:1 z main.css serwisu — deck ma mówić tym samym
     językiem powierzchni co karty produktów, a nie własnym. */
  --elev-1:linear-gradient(180deg,rgba(255,255,255,.05),rgba(255,255,255,.015));
  --card-rest:inset 0 1px 0 rgba(255,255,255,.05),0 16px 36px -26px rgba(0,0,0,.75);
  --radius-karta:calc(.85*var(--u));

  --ease-out:cubic-bezier(.22,.61,.36,1);
  --ease-spring:cubic-bezier(.34,1.56,.64,1);
  --dur:.55s;
}

/* === 2. Reset === */
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
html,body{height:100%}
html{-webkit-text-size-adjust:100%}
body{
  font-family:var(--font);color:var(--text);background:var(--bg);
  line-height:1.55;-webkit-font-smoothing:antialiased;
  overflow:hidden;                 /* w trybie slajdów strona się nie przewija */
}
img,svg{display:block;max-width:100%}
button{font-family:inherit;color:inherit;cursor:pointer;background:none;border:0}
a{color:inherit;text-decoration:none}
ul,ol{list-style:none}

:focus-visible{outline:3px solid var(--focus-ring);outline-offset:3px}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
.skip{
  position:absolute;left:12px;top:-60px;z-index:120;
  background:var(--primary);color:#fff;padding:10px 18px;border-radius:0 0 10px 10px;
  font-weight:600;transition:top .2s;
}
.skip:focus{top:0}

/* === 3. Awaria: brak danych ===
   Deck liczy WSZYSTKIE liczby z /assets/js/data.js. Gdyby ten plik się nie
   wczytał, slajdy pokazałyby puste miejsca albo zera — czyli skłamałyby cicho.
   Zamiast tego mówimy głośno, że danych nie ma. */
#awaria{
  position:fixed;inset:0;z-index:200;display:grid;place-items:center;
  background:var(--bg);padding:8vw;text-align:center;
}
#awaria[hidden]{display:none}
#awaria h1{font-size:clamp(1.4rem,4vw,2.2rem);margin-bottom:14px}
#awaria p{color:var(--muted-strong);max-width:52ch;margin:0 auto 10px}
#awaria code{font-family:var(--mono);font-size:.9em;color:var(--accent)}

/* === 4. Scena === */
.deck{position:fixed;inset:0;overflow:hidden;isolation:isolate}

/* POŚWIATA WĘDRUJE PRZEZ AKTY.
   Wcześniej jeden gradient stał nieruchomo przez wszystkie 22 slajdy, więc
   przejście z aktu do aktu było niewidoczne — nic nie sygnalizowało, że
   zmienił się rozdział. Teraz plama przesuwa się i zmienia odcień razem
   z aktem; ruch jest powolny i daleko za treścią, więc nie odciąga uwagi.
   Kierunek czytamy z `data-akt` na aktywnym slajdzie — jedno źródło,
   to samo, którego używa pasek postępu. */
.deck::before{
  content:"";position:absolute;inset:-20%;z-index:0;pointer-events:none;
  background:
    radial-gradient(46% 38% at var(--ax,18%) var(--ay,12%),
      color-mix(in srgb,var(--akt-kolor,#8b5cf6) 26%,transparent),transparent 70%),
    radial-gradient(40% 34% at calc(100% - var(--ax,18%)) calc(100% - var(--ay,12%)),
      rgba(56,189,248,.13),transparent 70%);
  transition:background 1.2s var(--ease-out);
}
/* Osiem aktów, osiem pozycji i odcieni. Kolory brane z palety kategorii
   serwisu, żeby deck nie wprowadzał barw, których strona nie zna. */
.deck[data-akt="0"]{--ax:50%;--ay:16%;--akt-kolor:#8b5cf6}
.deck[data-akt="1"]{--ax:14%;--ay:20%;--akt-kolor:#a855f7}
.deck[data-akt="2"]{--ax:26%;--ay:14%;--akt-kolor:#38bdf8}
.deck[data-akt="3"]{--ax:52%;--ay:22%;--akt-kolor:#a974f0}
.deck[data-akt="4"]{--ax:74%;--ay:16%;--akt-kolor:#f43f5e}
.deck[data-akt="5"]{--ax:22%;--ay:74%;--akt-kolor:#10b981}
.deck[data-akt="6"]{--ax:78%;--ay:70%;--akt-kolor:#38bdf8}
.deck[data-akt="7"]{--ax:50%;--ay:80%;--akt-kolor:#f59e0b}
.deck[data-akt="z"]{--ax:50%;--ay:50%;--akt-kolor:#8b5cf6}

/* JEDNA OŚ PIONOWA.
   Zmierzone przed zmianą: treść zaczynała się na x=195 na czternastu slajdach
   i na x=95 na czterech szerokich, a etykieta aktu stała ZAWSZE na x=95 —
   czyli na czternastu slajdach podpis aktu wisiał sto pikseli na lewo od
   wszystkiego innego. Przy przenikaniu slajdów ten skok widać jako drganie.
   Teraz wszystko startuje od lewej krawędzi pola; szerokie slajdy rosną
   w PRAWO, a nie na obie strony. Hero i uderzenia zostają wyśrodkowane —
   to ich świadoma różnica, nie niekonsekwencja.

   Wiersz 1 siatki to pas etykiety aktu, wiersz 2 to treść. Na slajdach bez
   etykiety wiersz 1 ma zerową wysokość i treść centruje się jak dawniej. */
.slide{
  position:absolute;inset:0;z-index:1;
  display:grid;
  grid-template-rows:auto 1fr;
  align-items:center;justify-items:start;
  padding:calc(4*var(--u)) calc(5*var(--u)) calc(6*var(--u));
  opacity:0;visibility:hidden;
  /* WYJŚCIE: krótkie, liniowe, BEZ ruchu. Gdyby slajd odjeżdżał, przez chwilę
     jechałyby dwa czytelne zdania w przeciwne strony — to nie jest przejście,
     to zderzenie. Cięcie w 0,18 s. */
  transition:opacity .18s linear,visibility 0s linear .18s;
}
.slide.hero,.slide.strike{justify-items:center}
/* WEJŚCIE: z opóźnieniem, żeby poprzedni slajd zdążył zgasnąć — cięcie,
   nie podwójna ekspozycja. */
.slide.on{opacity:1;visibility:visible;transition:opacity .3s var(--ease-out) .14s,visibility 0s}
.wrap{position:relative;z-index:2;grid-row:2;width:100%;max-width:calc(64*var(--u))}
.slide[data-w="szeroki"] .wrap{max-width:calc(82*var(--u))}

/* Stały pas nagłówka. Zmierzone przed zmianą: górna krawędź tytułu wędrowała
   w zakresie 103–282 px, a skoki między sąsiednimi slajdami sięgały 143 px.
   Układ był powtarzalny, ale kotwica nie — najgorsza możliwa kombinacja:
   deck jednocześnie nudził schematem i męczył tym, że schemat nie stoi
   w miejscu. ⚠ `screen` jest konieczne: bez niego reguła łapie także druk. */
@media screen and (min-width:861px) and (min-height:421px){
  .slide:not(.hero):not(.strike) .wrap{min-height:calc(27*var(--u))}
}

/* --- numer aktu i podpis w rogu --- */
/* Etykieta aktu jest teraz PIERWSZYM WIERSZEM SIATKI, nie elementem
   wiszącym absolutnie. Dzięki temu dziedziczy tę samą miarę co treść
   i nie da się jej rozjechać z lewą krawędzią slajdu. */
.akt{
  grid-row:1;align-self:start;z-index:3;
  margin-bottom:calc(1.6*var(--u));
  font-family:var(--mono);font-size:calc(.86*var(--u));
  letter-spacing:.22em;text-transform:uppercase;color:var(--muted);
}
.akt b{color:var(--accent);font-weight:700}

/* --- wielka liczba w tle --- */
/* Cyfra-widmo. Skalę ustawia deck.js przez --gskala, bo zależy od LICZBY ZNAKÓW:
   zmierzone na renderach — „7" przy 26u czyta się jak podpis, a „161k" przy tej
   samej wielkości rozłazi się na pół slajdu i przecina wiersze dowodów.
   Kroju monotypowego nie da się zmierzyć w CSS, więc liczy to skrypt.
   ⚠ Skala idzie zmienną, NIE stylem w linii — styl w linii wygrałby
   z regułą trybu czytania i rozsadził widmo na telefonie. */
.ghost{
  position:absolute;z-index:0;pointer-events:none;user-select:none;
  right:calc(2*var(--u));bottom:calc(1*var(--u));
  font-family:var(--mono);font-weight:700;line-height:.8;
  font-size:calc(var(--gskala,26)*var(--u));
  color:transparent;-webkit-text-stroke:1px rgba(255,255,255,.05);
  letter-spacing:-.03em;
}

/* === 5. Typografia slajdu === */
h1.tyt{
  font-size:calc(3.1*var(--u));font-weight:800;line-height:1.08;
  letter-spacing:-.02em;text-wrap:balance;
}
h2.tyt{
  font-size:calc(2.45*var(--u));font-weight:750;line-height:1.14;
  letter-spacing:-.015em;text-wrap:balance;
}
.tyt em{
  font-style:normal;
  background:var(--brand-grad);-webkit-background-clip:text;background-clip:text;
  color:transparent;
}
/* Akcent pod słowem. ⚠ NIE `box-shadow: inset` — to rysuje pas ZA glifami,
   który przy .28em zachodzi na dolną część liter i czyta się jak zaznaczenie
   myszką, nie jak podkreślenie. Prawdziwe podkreślenie z odsunięciem trzyma
   się pod linią pisma i nie brudzi tekstu. */
.tyt u{
  text-decoration:underline;
  text-decoration-color:rgba(139,92,246,.8);
  text-decoration-thickness:.085em;
  text-underline-offset:.16em;
  text-decoration-skip-ink:none;
}
.lead{
  font-size:calc(1.24*var(--u));color:var(--muted-strong);
  max-width:62ch;margin-top:calc(1.2*var(--u));
}
.nad{
  font-family:var(--mono);font-size:calc(.88*var(--u));
  letter-spacing:.2em;text-transform:uppercase;color:var(--accent);
  margin-bottom:calc(1*var(--u));
}
.dop{
  font-size:calc(.95*var(--u));color:var(--muted);
  margin-top:calc(1.4*var(--u));max-width:70ch;
}
.zrodlo{
  font-family:var(--mono);font-size:calc(.78*var(--u));color:var(--muted);
  letter-spacing:.06em;margin-top:calc(1.6*var(--u));
}

/* --- slajd-uderzenie: jedno zdanie na czarnym --- */
.slide.strike{background:#04060c}
.slide.strike .wrap{max-width:calc(48*var(--u));text-align:center}
.slide.strike p{
  font-size:calc(2.5*var(--u));font-weight:750;line-height:1.24;
  letter-spacing:-.015em;text-wrap:balance;
}

/* --- slajd tytułowy --- */
.slide.hero .wrap{text-align:center;max-width:calc(56*var(--u))}
.slide.hero .znak{
  font-family:var(--mono);font-size:calc(1.05*var(--u));letter-spacing:.34em;
  text-transform:uppercase;color:var(--muted);margin-bottom:calc(2*var(--u));
}
.slide.hero .stopka{
  margin-top:calc(2.6*var(--u));font-family:var(--mono);
  font-size:calc(.95*var(--u));color:var(--muted);letter-spacing:.1em;
}

/* === 6. Wejścia (wyłączalne) ===

   SPOCZYNEK = STAN KOŃCOWY. RUCH = `animation`, NIE `transition`.

   Poprzednia wersja robiła odwrotnie: `.rv` miało stan spoczynkowy UKRYTY
   (`opacity:0`), a widoczność brała z `.slide.on`. Wymagało to trzech osobnych
   reguł ratunkowych — dla klasy `bez-ruchu`, dla `prefers-reduced-motion`
   i dla trybu czytania — i dwie z nich zdążyły się rozjechać.
   Teraz element W SPOCZYNKU JEST WIDOCZNY, a animacja tylko go wprowadza.
   Wyłączenie ruchu nie wymaga niczego przywracać: `animation:none` wystarcza.

   ⚠ `backwards`, NIE `both`. `both` obejmuje `forwards`, a wypełnienie w przód
   działa na poziomie „animation origin", który bije każdą zwykłą deklarację
   autora. Kropka `data-st="rozwoj"` zostałaby po animacji przypięta na
   `opacity:1` i reguła wygaszająca przegrałaby — czternaście kropek świeciłoby
   jednakowo, a to one niosą całą tezę slajdu 01.

   ⚠ Keyframe MA TYLKO `from`. Niejawna klatka 100% równa się wtedy własnej
   wyliczonej wartości elementu, więc `.rv` dochodzi do 1, a przygaszona kropka
   do .42 — bez pisania dwóch osobnych keyframe'ów.

   Czas .6s i dystans 1.1u zostają takie, jakie były — to wartości zmierzone
   na renderach, a nie do zmiany przy okazji wymiany mechanizmu. */
@keyframes wchodzi{
  from{opacity:0;transform:translateY(calc(1.1*var(--u)))}
}

/* KIERUNEK PRZEJŚCIA.
   Blok treści wjeżdża z tej strony, z której „przyszedł" — w przód znaczy
   z prawej, wstecz z lewej. Dystans jest mały (0,6u ≈ 11 px przy 1600×900):
   ma nieść informację o kierunku, a nie robić widowisko. Kierunek ustawia
   deck.js przez `data-kier` na kontenerze sceny.
   ⚠ Animacja siedzi na `.wrap`, a nie na `.slide` — inaczej wypełnienie
   animacji trzymałoby `opacity` slajdu i przejście wygaszające nigdy by
   nie wystartowało. */
@keyframes wjazd{
  from{opacity:0;transform:translateX(var(--kier,0))}
}
.deck[data-kier="przod"] .slide.on .wrap{--kier:calc(.6*var(--u))}
.deck[data-kier="tyl"]   .slide.on .wrap{--kier:calc(-.6*var(--u))}
.slide.on .wrap{animation:wjazd .34s var(--ease-out) .14s backwards}

.rv{opacity:1;transform:none}
/* Elementy wchodzą PO tym, jak blok dojedzie — stąd wspólne przesunięcie
   o czas wjazdu. Bez tego kaskada rusza w trakcie jazdy i wygląda na drganie. */
.slide.on .rv{
  animation:wchodzi .6s var(--ease-out) backwards;
  animation-delay:calc(.14s + var(--i,0) * .08s);
}
.slide.on .wrap > .rv:nth-child(1){--i:0}
.slide.on .wrap > .rv:nth-child(2){--i:1}
.slide.on .wrap > .rv:nth-child(3){--i:2}
.slide.on .wrap > .rv:nth-child(4){--i:3}
.slide.on .wrap > .rv:nth-child(5){--i:4}

/* === 7. Elementy treści === */

/* --- pasek 14 kropek (slajd 01) --- */
.kropki{display:flex;flex-wrap:wrap;justify-content:center;gap:calc(.55*var(--u));margin-top:calc(2.2*var(--u))}
/* Spoczynek = stan końcowy (patrz sekcja 6). Kropka „w rozwoju" jest
   przygaszona ZAWSZE, nie tylko po animacji — dlatego keyframe nie może
   mieć klatki `to`, a wypełnienie musi być `backwards`, nie `both`. */
.kropka{
  width:calc(1.5*var(--u));height:calc(1.5*var(--u));
  background:var(--st-rozwoj);
}
.slide.on .kropka{
  animation:wchodzi .38s var(--ease-out) backwards;
  animation-delay:calc(.25s + var(--i,0) * .045s);
}

/* KSZTAŁT, NIE TYLKO KOLOR — ta sama gramatyka co znacznik `.st` w sekcji 7
   i co plakietki `.tag-*` na stronie. Pasek na slajdzie 01 niesie całą tezę
   decku, więc nie może opierać się na kanale, którego część widzów nie ma.

   ⚠ Romb przez `clip-path`, NIE przez `transform:rotate`. Animacja wejścia
   ustawia `transform`, więc obrót zostałby przez nią zjedzony — kropka „beta"
   wyszłaby kwadratem i zlała się z „w rozwoju". */
.kropka[data-st="gotowy"]{background:var(--st-gotowy);border-radius:50%}
.kropka[data-st="beta"]  {background:var(--st-beta);clip-path:polygon(50% 0,100% 50%,50% 100%,0 50%)}
.kropka[data-st="demo"]  {background:var(--st-demo);clip-path:polygon(50% 0,100% 100%,0 100%)}
/* Krycie .55, nie .42. Zmierzone: przy .42 wypełnienie dawało wobec tła 2,4:1,
   a kropka niesie informację, więc obowiązuje próg 3:1 dla elementów
   nietekstowych. Przy .55 wychodzi 3,1:1 i przygaszenie nadal czytelnie
   odróżnia „w rozwoju" od reszty. */
.kropka[data-st="rozwoj"]{background:var(--st-rozwoj);opacity:.55;border-radius:1px}

/* Próbka w legendzie musi mieć ten sam kształt co kropka nad nią — inaczej
   legenda tłumaczy kolor, a pasek mówi kształtem. */
.legenda-kropek i[data-st="gotowy"]{background:var(--st-gotowy);border-radius:50%}
.legenda-kropek i[data-st="beta"]  {background:var(--st-beta);border-radius:0;clip-path:polygon(50% 0,100% 50%,50% 100%,0 50%)}
.legenda-kropek i[data-st="demo"]  {background:var(--st-demo);border-radius:0;clip-path:polygon(50% 0,100% 100%,0 100%)}
.legenda-kropek i[data-st="rozwoj"]{background:var(--st-rozwoj);border-radius:1px;opacity:.55}
.legenda-kropek{
  display:flex;flex-wrap:wrap;justify-content:center;gap:calc(1.4*var(--u));margin-top:calc(1.2*var(--u));
  font-family:var(--mono);font-size:calc(.82*var(--u));color:var(--muted);
}
.legenda-kropek span{display:inline-flex;align-items:center;gap:calc(.5*var(--u))}
.legenda-kropek i{width:calc(.9*var(--u));height:calc(.9*var(--u));border-radius:50%;display:block}

/* --- mapa kategorii (slajdy 05–06) --- */
.mapa{
  display:grid;grid-template-columns:repeat(5,1fr);gap:calc(1*var(--u));
  margin-top:calc(1.8*var(--u));
}
.kol{
  border:1px solid var(--border);border-radius:var(--radius-karta);
  padding:calc(1*var(--u)) calc(.9*var(--u));
  background-color:var(--surface);background-image:var(--elev-1);box-shadow:var(--card-rest);
  border-top:2px solid var(--kat,var(--primary));
}
/* ⚠ Bez `space-between`. Po dołożeniu ikony wiersz ma TRZY dzieci, a wtedy
   space-between robi dwie szczeliny i nazwa ucieka na środek kolumny.
   Licznik spychamy marginesem. `align-items:center`, nie `baseline` —
   pusty inline-flex ikony nie ma linii bazowej. */
.kol-gl{display:flex;align-items:center;gap:calc(.5*var(--u));margin-bottom:calc(.2*var(--u))}
.kol-gl u{margin-left:auto}

/* Kafel ikony kategorii — `.prod-ico` z main.css przeliczone na skalę --u.
   Kolor bierze z `--kat`, czyli z rejestru kategorii, tak jak na stronie. */
.kat-ico{
  display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;
  width:calc(1.9*var(--u));height:calc(1.9*var(--u));
  border-radius:calc(.5*var(--u));
  background:linear-gradient(145deg,
    color-mix(in srgb,var(--kat,var(--primary)) 92%,#fff),
    color-mix(in srgb,var(--kat,var(--primary)) 72%,#000));
  border:1px solid color-mix(in srgb,var(--kat,var(--primary)) 55%,transparent);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.28),
             0 6px 16px -8px color-mix(in srgb,var(--kat,var(--primary)) 80%,transparent);
}
.kat-ico svg{width:calc(1.05*var(--u));height:calc(1.05*var(--u));color:#fff;
  filter:drop-shadow(0 1px 2px rgba(0,0,0,.35))}
/* `<th>` nie jest flexem, więc `gap` tam nie działa — ikona potrzebuje
   własnego odstępu i wyrównania do środka wiersza. */
.tab th .kat-ico{margin-right:calc(.55*var(--u));vertical-align:middle}
.kol-gl b{font-size:calc(1.02*var(--u));font-weight:700;line-height:1.2}
.kol-gl u{
  text-decoration:none;font-family:var(--mono);font-weight:700;
  font-size:calc(1.15*var(--u));color:var(--kat,var(--primary));
}
.kol-op{
  font-family:var(--mono);font-size:calc(.68*var(--u));letter-spacing:.12em;
  text-transform:uppercase;color:var(--muted);margin-bottom:calc(.7*var(--u));
}
.poz{
  display:flex;align-items:center;gap:calc(.55*var(--u));
  padding:calc(.42*var(--u)) 0;font-size:calc(.92*var(--u));
  border-top:1px solid rgba(255,255,255,.05);
}
/* Kolejność `--i` jest WSPÓLNA dla pięciu kolumn (deck.js, jeden licznik),
   żeby mapa czytała się od lewej do prawej, a nie pięcioma słupkami naraz. */
.slide.on .poz{
  animation:wchodzi .45s var(--ease-out) backwards;
  animation-delay:calc(.2s + var(--i,0) * .035s);
}
.poz:first-of-type{border-top:0}

/* ZNACZNIK STANU: kolor ORAZ kształt.
   Serwis robi tak samo (.tag-*::before) i z tego samego powodu — przy
   nierozróżnianiu barw sam kolor nie niesie informacji. */
.st{width:calc(.72*var(--u));height:calc(.72*var(--u));flex:0 0 auto;display:block}
.st[data-st="gotowy"]{background:var(--st-gotowy);border-radius:50%}
.st[data-st="beta"]{background:var(--st-beta);transform:rotate(45deg)}
.st[data-st="demo"]{background:var(--st-demo);clip-path:polygon(50% 0,100% 100%,0 100%)}
.st[data-st="rozwoj"]{background:var(--st-rozwoj);border-radius:1px;opacity:.75}

/* --- tabela dwukolumnowa (zasady, granice, legenda) --- */
.tab{width:100%;border-collapse:collapse;margin-top:calc(1.5*var(--u))}
.tab th,.tab td{
  text-align:left;vertical-align:top;padding:calc(.85*var(--u)) calc(.9*var(--u));
  border-top:1px solid var(--border);font-size:calc(1.02*var(--u));
}
.tab tr:first-child th,.tab tr:first-child td{border-top:0}
.tab th{
  width:34%;font-weight:700;color:var(--text);
}
.tab td{color:var(--muted-strong)}
.tab .num{
  font-family:var(--mono);font-weight:700;color:var(--accent);
  font-variant-numeric:tabular-nums;white-space:nowrap;
}

/* Wiersz legendy stanów: znacznik + nazwa + licznik.
   ⚠ To DIV wewnątrz komórki, nie `display:flex` NA komórce. Flex nałożony
   wprost na <th> odbiera jej rolę komórki tabeli, przez co szerokość 34%
   przestaje obowiązywać — druga kolumna zabierała miejsce i „W rozwoju"
   łamało się na dwie linie, a licznik uciekał pod spód. Zmierzone na renderze. */
.stan-box{
  display:flex;align-items:center;gap:calc(.6*var(--u));
  white-space:nowrap;
}
.stan-box .stan-licz{margin-left:auto;padding-left:calc(1.2*var(--u))}

/* --- lista dowodów (slajdy 13, 14) --- */
.dowody{display:grid;gap:calc(.55*var(--u));margin-top:calc(1.6*var(--u))}
.dow{
  display:grid;grid-template-columns:1fr auto;align-items:center;gap:calc(1*var(--u));
  padding:calc(.8*var(--u)) calc(1.1*var(--u));
  border:1px solid var(--border);border-radius:var(--radius-karta);
  background-color:var(--surface);background-image:var(--elev-1);box-shadow:var(--card-rest);
  font-size:calc(1.02*var(--u));
}
.dow b{
  font-family:var(--mono);font-size:calc(1.5*var(--u));font-weight:700;
  color:var(--accent);font-variant-numeric:tabular-nums;
}
.dow span{color:var(--muted-strong)}

/* --- wiersz powiązania (slajd 09) --- */
.rel{
  display:flex;align-items:center;gap:calc(.8*var(--u));flex-wrap:wrap;
  border:1px solid var(--border);border-radius:var(--radius-karta);
  padding:calc(.75*var(--u)) calc(1*var(--u));margin-bottom:calc(.5*var(--u));
  /* Nieprzezroczysta podstawa, jak pozostale karty — inaczej cyfra-widmo
     przeswituje przez wiersz. Ten sam jezyk powierzchni co na stronie. */
  background-color:var(--surface);background-image:var(--elev-1);
  box-shadow:var(--card-rest);
}
/* ⚠ Twarde powiazanie musi ZACHOWAC obwodke. To jedyne miejsce, w ktorym
   deck rozroznia „rdzen" od „integracji" — samo tlo tego nie uniesie. */
.rel.hard{
  border-color:rgba(139,92,246,.42);
  background-image:linear-gradient(180deg,rgba(139,92,246,.10),rgba(139,92,246,.04));
}
.rel b{font-weight:650}
.rel .strz{color:var(--muted);font-family:var(--mono)}
.rel .co{margin-left:auto;color:var(--muted);font-size:calc(.9*var(--u));text-align:right}
.rel .co i{font-style:normal;color:var(--violet);font-weight:650}

/* --- graf ekosystemu (slajd 09) --- */
.graf{margin-top:calc(1.2*var(--u))}
/* Wysokość SPĘTANA jednostką slajdu, nie proporcją. Bez tego SVG rozciągał się
   do 806 px na polu 1550 px i wypychał tytuł poza kadr — zmierzone na renderze. */
.graf svg{display:block;width:100%;height:calc(22*var(--u));overflow:visible}

.kraw{
  stroke:rgba(255,255,255,.16);stroke-width:1.4;
  stroke-dasharray:var(--dlug,600);stroke-dashoffset:0;
}
.kraw.twarda{stroke:rgba(169,116,240,.75);stroke-width:2.6}
.kraw-etyk{
  fill:var(--muted-strong);font-family:var(--mono);font-size:13px;
  letter-spacing:.04em;
  /* Obrys w kolorze tła wycina etykietę z rysunku — inaczej kreska grafu
     przechodzi przez litery. */
  paint-order:stroke;stroke:var(--bg);stroke-width:5px;stroke-linejoin:round;
}
.kraw.twarda + .kraw-etyk{fill:var(--violet)}

.graf-podzial line{stroke:var(--border);stroke-width:1;stroke-dasharray:2 6}
.podzial-etyk{
  fill:var(--muted);font-family:var(--mono);font-size:12px;
  letter-spacing:.14em;text-transform:uppercase;
}
.slide.on .graf .graf-podzial{animation:wchodzi .6s var(--ease-out) .55s backwards}

.wezel-aura{fill:var(--kat,#8b5cf6);opacity:.14}
.wezel-tlo{
  fill:var(--bg-alt);stroke:var(--kat,#8b5cf6);stroke-width:2;
}
/* Dojrzałość niesie WYPEŁNIENIE, nie tylko obwódka: produkt gotowy jest pełny,
   w rozwoju — pusty. Ta sama logika co przygaszone kropki na slajdzie 01. */
.wezel[data-st="gotowy"] .wezel-tlo,
.wezel[data-st="komercyjny"] .wezel-tlo{fill:var(--kat,#8b5cf6)}
.wezel[data-st="beta"] .wezel-tlo{fill:color-mix(in srgb,var(--kat,#8b5cf6) 45%,var(--bg-alt))}
.wezel[data-st="demo"] .wezel-tlo{fill:color-mix(in srgb,var(--kat,#8b5cf6) 45%,var(--bg-alt))}
.wezel[data-st="rozwoj"] .wezel-aura{opacity:.06}
.wezel[data-st="rozwoj"] .wezel-tlo{stroke-dasharray:3 3;stroke-opacity:.6}

.wezel-podpis{
  fill:var(--text);font-family:var(--font);font-size:13px;font-weight:650;
  paint-order:stroke;stroke:var(--bg);stroke-width:4px;stroke-linejoin:round;
}
.wezel[data-st="rozwoj"] .wezel-podpis{fill:var(--muted-strong);font-weight:500}

/* Rysowanie na oczach: krawędzie „wybiegają" od środka, węzły siadają po nich.
   Wszystko ginie pod wyłącznikiem ruchu, bo to zwykłe `animation`. */
@keyframes rysuj{ from{stroke-dashoffset:var(--dlug,600);opacity:0} }
/* Samo krycie, ZERO transformacji — elementy, ktore maja wlasny `transform`
   (obrocone etykiety krawedzi), stracilyby go przez klatke z translate. */
@keyframes pojaw{ from{opacity:0} }
@keyframes siada{ from{opacity:0;transform:scale(.4)} }
.slide.on .graf .kraw{
  animation:rysuj .7s var(--ease-out) backwards;
  animation-delay:calc(.35s + var(--i,0) * .07s);
}
.slide.on .graf .kraw-etyk{
  /* ⚠ `pojaw`, NIE `wchodzi` — etykieta ma własny `transform` obrotu
     w atrybucie, a klatka z translate skasowałaby go w całości
     i wszystkie podpisy wróciłyby do poziomu. */
  animation:pojaw .5s var(--ease-out) backwards;
  animation-delay:calc(.9s + var(--i,0) * .07s);
}
.slide.on .graf .wezel{
  transform-box:fill-box;transform-origin:center;
  animation:siada .5s var(--ease-spring) backwards;
  animation-delay:calc(.2s + var(--i,0) * .05s);
}

/* --- żetony (slajd 10, 12) --- */
.zetony{display:flex;flex-wrap:wrap;gap:calc(.55*var(--u));margin-top:calc(1.4*var(--u))}
.zeton{
  display:inline-flex;align-items:center;gap:calc(.5*var(--u));
  border:1px solid var(--border);border-radius:999px;
  padding:calc(.5*var(--u)) calc(1*var(--u));
  font-weight:600;
  background-color:var(--surface);background-image:var(--elev-1);
}

/* --- drobne klasy używane przez deck.js ---
   ŚWIADOMIE KLASY, NIE STYLE W LINII. Rozmiar wpisany w atrybut `style`
   jako calc(x*var(--u)) przechodzi przez tryb czytania nietknięty i schodzi
   poniżej progu czytelności, bo podłoga z sekcji 10 nie ma go jak dosięgnąć.
   Zmierzone: takie miejsca dawały 12,0–12,3 px na ekranie 375 px. */
.mini{
  font-family:var(--mono);font-size:calc(.82*var(--u));
  color:var(--muted);letter-spacing:.04em;
}
.mini-prawo{margin-left:auto}
.nazwa-filaru{font-size:calc(1.15*var(--u));font-weight:700}
.dowod-min{font-size:calc(.92*var(--u));color:var(--muted-strong)}
.dowod-min b{
  font-family:var(--mono);color:var(--accent);
  margin-right:calc(.4*var(--u));font-variant-numeric:tabular-nums;
}
.karta-filaru{display:block}
.karta-filaru .gl{display:flex;align-items:center;gap:calc(.6*var(--u));margin-bottom:calc(.4*var(--u))}
.karta-filaru .op{color:var(--muted-strong);font-size:calc(.98*var(--u))}
.karta-filaru .lista{display:flex;flex-wrap:wrap;gap:calc(.3*var(--u)) calc(1.4*var(--u));margin-top:calc(.5*var(--u))}

/* --- cytat --- */
.cyt{
  border-left:2px solid var(--primary);
  padding:calc(.8*var(--u)) 0 calc(.8*var(--u)) calc(1.4*var(--u));
  margin-top:calc(1.6*var(--u));
  font-size:calc(1.16*var(--u));color:var(--text);max-width:64ch;
}
.cyt cite{display:block;margin-top:calc(.6*var(--u));font-style:normal;
  font-family:var(--mono);font-size:calc(.78*var(--u));color:var(--muted);letter-spacing:.06em}

/* --- ścieżki CTA (slajd 21) --- */
.sciezki{display:grid;grid-template-columns:repeat(3,1fr);gap:calc(.9*var(--u));margin-top:calc(1.8*var(--u))}
.sc{
  border:1px solid var(--border);border-radius:var(--radius-karta);
  padding:calc(1.2*var(--u));display:flex;flex-direction:column;gap:calc(.6*var(--u));
  background-color:var(--surface);background-image:var(--elev-1);box-shadow:var(--card-rest);
}
.sc-gl{display:flex;align-items:center;gap:calc(.6*var(--u));font-weight:700;font-size:calc(1.05*var(--u))}
.sc-gl u{text-decoration:none;font-family:var(--mono);color:var(--muted);font-size:calc(.9*var(--u))}
.sc p{color:var(--muted-strong);font-size:calc(.95*var(--u));flex:1}
/* Przycisk. ⚠ NIE `--brand-grad`. Zmierzone: biały tekst na gradiencie marki
   ma pod glifami 3,68–4,11:1, a w najjaśniejszym punkcie przebiegu (czysty
   #38bdf8) tylko 2,18:1 — poniżej progu nawet dla dużego tekstu. Ciemniejszy
   wariant tego samego przejścia trzyma 5,38:1 w najgorszym punkcie i zachowuje
   kierunek fiolet→błękit, czyli rozpoznawalność marki. Token `--brand-grad`
   zostaje nietknięty, bo używa go typografia, gdzie kolorem jest sam tekst. */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:calc(.4*var(--u));
  padding:calc(.7*var(--u)) calc(1.2*var(--u));border-radius:calc(.6*var(--u));
  background:linear-gradient(135deg,#7c3aed,#9333ea,#0369a1);
  color:#fff;font-weight:700;font-size:calc(.95*var(--u));
  box-shadow:var(--card-rest);
  transition:transform .2s var(--ease-out),box-shadow .2s var(--ease-out);
}
/* Hover NIE rozjaśnia tła — to zabrałoby z powrotem wywalczony kontrast.
   Zamiast tego uniesienie i cień, tak jak przyciski na stronie. */
.btn:hover{transform:translateY(-2px);box-shadow:0 22px 44px -22px rgba(124,58,237,.65)}
.btn.pusty{
  background:none;border:1px solid var(--border-strong);color:var(--text);box-shadow:none;
}
.btn.pusty:hover{border-color:var(--primary);color:var(--primary);box-shadow:none;transform:translateY(-2px)}

/* === 8. Pasek postępu i sterowanie === */
#postep{
  position:fixed;left:0;right:0;bottom:0;height:3px;z-index:60;
  display:flex;gap:2px;padding:0 2px 2px;pointer-events:none;
}
#postep .akt-seg{flex:1 1 auto;background:rgba(255,255,255,.09);border-radius:2px;overflow:hidden}
#postep .akt-seg i{display:block;height:100%;width:0;background:var(--brand-grad);
  transition:width .35s var(--ease-out)}

#pult{
  position:fixed;left:50%;bottom:calc(1.6*var(--u));transform:translateX(-50%) translateY(calc(1*var(--u)));
  z-index:70;display:flex;align-items:center;gap:calc(.5*var(--u));
  padding:calc(.5*var(--u)) calc(.8*var(--u));
  border:1px solid var(--border-strong);border-radius:999px;
  background:rgba(10,11,16,.86);backdrop-filter:blur(8px);
  opacity:0;visibility:hidden;transition:opacity .25s,transform .25s,visibility 0s linear .25s;
}
#pult.on{opacity:1;visibility:visible;transform:translateX(-50%);transition-delay:0s}
#pult button{
  width:calc(2.2*var(--u));height:calc(2.2*var(--u));border-radius:50%;
  display:grid;place-items:center;color:var(--muted);
  font-family:var(--mono);font-size:calc(.9*var(--u));font-weight:700;
  transition:color .2s,background .2s;
}
#pult button:hover{color:var(--text);background:rgba(255,255,255,.08)}
#pult .licz{
  font-family:var(--mono);font-size:calc(.88*var(--u));color:var(--muted);
  padding:0 calc(.6*var(--u));font-variant-numeric:tabular-nums;white-space:nowrap;
}
#pult .kreska{width:1px;height:calc(1.4*var(--u));background:var(--border-strong)}

/* === 9. Spis slajdów === */
#spis{
  position:fixed;inset:0;z-index:90;background:rgba(6,8,14,.96);
  padding:calc(4*var(--u));overflow:auto;
  opacity:0;visibility:hidden;transition:opacity .25s,visibility 0s linear .25s;
}
#spis.on{opacity:1;visibility:visible;transition-delay:0s}
#spis h2{font-size:calc(1.6*var(--u));margin-bottom:calc(1.6*var(--u))}
.spis-akt{margin-bottom:calc(1.6*var(--u))}
.spis-akt > b{
  display:block;font-family:var(--mono);font-size:calc(.8*var(--u));
  letter-spacing:.2em;text-transform:uppercase;color:var(--accent);
  margin-bottom:calc(.6*var(--u));
}
.spis-lista{display:grid;grid-template-columns:repeat(auto-fill,minmax(calc(16*var(--u)),1fr));gap:calc(.5*var(--u))}
.spis-lista button{
  text-align:left;display:flex;gap:calc(.7*var(--u));align-items:baseline;
  padding:calc(.6*var(--u)) calc(.8*var(--u));border-radius:calc(.5*var(--u));
  border:1px solid var(--border);font-size:calc(.92*var(--u));color:var(--muted-strong);
  transition:border-color .2s,color .2s;
}
.spis-lista button:hover,.spis-lista button.tu{border-color:var(--primary);color:var(--text)}
.spis-lista button i{font-family:var(--mono);font-style:normal;color:var(--muted);font-size:calc(.82*var(--u))}

/* === 9a. PODŁOGA CZYTELNOŚCI W KADRZE ===

   Podłoga 13 px z sekcji 10 obowiązuje wyłącznie poniżej 860 px. W kadrze
   `--u = min(1.2vw,2.1vh)` bierze SZEROKOŚĆ przy każdej proporcji poniżej
   1,75:1 — a wtedy tekst pomocniczy schodzi poniżej czytelności na sprzęcie,
   który wcale nie jest telefonem. Zmierzone: 1600×900 → `.kol-op` 12,9 px;
   1366×768 → 11,0; 1280×720 → 10,3; 1024×768 → **8,4 px**, a 1024 > 860,
   więc tryb czytania się NIE włącza. To jest rzutnik 4:3, czyli dokładnie
   ten sprzęt, na którym deck bywa pokazywany.

   PORZĄDEK PODŁÓG JEST CZĘŚCIĄ REGUŁY: treść wyżej niż etykiety.
   Gdyby etykieta miała podłogę wyższą od tekstu płynącego, przy wąskim
   kadrze podpis byłby większy od tego, co podpisuje.

   ⚠ Reguły trybu czytania (sekcja 10) stoją PO tym bloku i mają równą albo
   wyższą specyficzność, więc poniżej 860 px dalej wygrywają. Selektory tutaj
   są GOŁE (0,1,0) właśnie po to — `.slide.hero .stopka` pobiłoby `.stopka`
   z sekcji 10 i złamało gwarancję „poniżej 860 px nic się nie zmienia".

   ⚠ POŁOŻENIE. Blok MUSI stać za sekcjami 7–9, które te klasy definiują,
   i przed sekcją 10. Wstawiony wcześniej przegrywa kolejnością przy równej
   specyficzności — sprawdzone pomiarem: `.kol-op` zostawało na 8,36 px
   przy 1024×768, mimo poprawnie napisanej podłogi.

   ⚠ PODŁOGA OBOWIĄZUJE TYLKO TAM, GDZIE JEST NA NIĄ MIEJSCE.
   Zmierzone: przy 1366×470 podniesienie tekstu do 13 px wypychało slajd 15
   poza kadr o 13 px. W tak niskim oknie --u schodzi do 9,87 px i podłoga
   jest większa niż naturalny rozmiar o jedną trzecią — czyli przestaje być
   zabezpieczeniem, a staje się przyczyną. Próg 560 px wysokości przepuszcza
   rzutnik 4:3 (768 px), dla którego ta reguła powstała, i odcina paski. */
@media (min-height:560px){
  .tab th,.tab td,.dow,.rel   {font-size:max(13px,calc(1.02*var(--u)))}
  .poz,.dowod-min             {font-size:max(13px,calc(.92*var(--u)))}
  .zeton,.sc p,.btn           {font-size:max(13px,calc(.95*var(--u)))}
  .karta-filaru .op           {font-size:max(13px,calc(.98*var(--u)))}
  .rel .co,.dop               {font-size:max(12px,calc(.92*var(--u)))}
  .zrodlo,.cyt cite,.legenda-kropek,.mini,
  .spis-lista button i,.akt,.nad{font-size:max(11px,calc(.84*var(--u)))}
  .spis-akt > b               {font-size:max(11px,calc(.8*var(--u)))}
  .stopka,.znak,.sc-gl u      {font-size:max(11px,calc(.95*var(--u)))}
  #pult .licz,#pult button    {font-size:max(11px,calc(.88*var(--u)))}
  .kol-op                     {font-size:max(10px,calc(.68*var(--u)))}
}

/* === 10. Tryb czytania ===
   Poniżej 860 px slajd przestaje być kadrem, a staje się sekcją. Powód jest
   pomiarowy, nie estetyczny: tabele i mapa pięciu kolumn nie mieszczą się
   w kadrze telefonu przy żadnej wielkości --u, która pozostaje czytelna.
   Zamiast zmniejszać tekst do nieczytelności — pozwalamy przewijać. */
@media (max-width:860px),(max-height:420px){
  html,body{overflow:auto;height:auto}

  /* ⚠ NIE skalujemy trybu czytania samym zmniejszeniem --u. Zmierzone:
     przy --u:8,5px cała prezentacja mieściła się bez przewijania w poziomie,
     ale tekst pomocniczy schodził do 6,6 px, a tekst główny do 8,7 px —
     czyli poniżej progu czytelności na telefonie.
     Powód jest strukturalny: w kadrze nagłówek ma do tekstu proporcję ~3:1
     i to działa, gdy --u ≈ 22 px (68 px vs 22 px). Na ekranie 375 px tekst
     musi mieć ~16 px, a nagłówek ~30 px, czyli proporcję ~1,9:1.
     Dlatego tryb czytania dostaje WŁASNĄ skalę w rem, a --u obsługuje
     już tylko odstępy. */
  :root{--u:15px}

  .deck{position:static;inset:auto;overflow:visible}
  .deck::before{position:fixed;inset:0}
  .slide{
    position:relative;inset:auto;opacity:1;visibility:visible;
    min-height:auto;display:block;
    padding:44px 20px;
    border-top:1px solid var(--border);
  }
  .slide:first-child{border-top:0}
  .wrap,.slide[data-w="szeroki"] .wrap{max-width:none}
  /* Reguł ratunkowych dla .rv i .poz już tu nie ma — po odwróceniu mechanizmu
     (sekcja 6) spoczynek JEST stanem końcowym, a w trybie czytania żaden slajd
     nie ma klasy `.on`, więc animacja nigdy nie rusza. Jedno miejsce mniej,
     które może się rozjechać. */

  .ghost{font-size:5.5rem;right:12px;bottom:auto;top:10px}
  .akt{position:static;margin-bottom:18px}
  .mapa{grid-template-columns:1fr;gap:16px}
  .sciezki{grid-template-columns:1fr}
  .dow{grid-template-columns:1fr;gap:4px}
  .rel .co{margin-left:0;text-align:left;flex-basis:100%}
  .tab th,.tab td{display:block;width:auto;padding:5px 0}
  .tab th{padding-top:14px}
  .tab tr:first-child th{padding-top:0}
  #postep,#pult{display:none}
  #spis{position:static;opacity:1;visibility:visible;display:none}
  .slide.strike{padding-top:64px;padding-bottom:64px}

  /* --- skala typograficzna telefonu --- */
  h1.tyt{font-size:clamp(1.75rem,7.6vw,2.3rem)}
  h2.tyt{font-size:clamp(1.45rem,6.2vw,1.95rem)}
  .slide.strike p{font-size:clamp(1.3rem,5.6vw,1.75rem)}
  .lead,.cyt{font-size:1.06rem}
  .tab th,.tab td,.poz,.dow,.rel,.zeton,.sc p,.btn,.dop,.spis-lista button,
  .dowod-min,.karta-filaru .op{font-size:1rem}
  .dow b{font-size:1.35rem}
  .kol-gl b,.sc-gl,.nazwa-filaru{font-size:1.05rem}
  .kol-gl u{font-size:1.15rem}

  /* PODŁOGA CZYTELNOŚCI. Nic w decku nie schodzi poniżej 13 px — to jest
     granica, poniżej której tekst pomocniczy przestaje być informacją,
     a staje się ozdobą. */
  .nad,.akt,.zrodlo,.cyt cite,.kol-op,.legenda-kropek,.rel .co,
  .sc-gl u,.stopka,.znak,.spis-lista button i,#powrot,.mini{font-size:.82rem}

  /* ⚠ .num ma w kadrze `white-space:nowrap`, bo tam trzyma liczby. W tabeli
     „Dane i prywatność" trzyma jednak całe nagłówki HTTP — i to one rozpychały
     tabelę do 433 px na ekranie 375 px. Zmierzone: 16 elementów wystających
     poza kadr. Tu wolno im się łamać. */
  .tab .num{white-space:normal;overflow-wrap:anywhere}

  /* GRAF USTĘPUJE LIŚCIE. Rysunek skalowany z 1400 jednostek do szerokości
     telefonu daje podpisy rzędu trzech pikseli — to już nie jest obraz.
     Lista niesie DOKŁADNIE te same dane, z tego samego źródła. */
  .graf svg{display:none}
  .graf-lista{
    position:static;width:auto;height:auto;margin:0;padding:0;
    overflow:visible;clip:auto;white-space:normal;
    display:grid;gap:10px;
  }
  .graf-lista li{
    font-size:1rem;color:var(--muted-strong);
    padding-left:14px;border-left:2px solid var(--border-strong);
  }

  .kat-ico{width:30px;height:30px;border-radius:9px}
  .kat-ico svg{width:17px;height:17px}
  .st{width:11px;height:11px}
  .kropka{width:16px;height:16px}
}

/* Pasek czytania — zastępuje pult w trybie sekcji, żeby dało się wrócić
   na stronę bez szukania przycisku wstecz. */
#powrot{
  display:none;position:sticky;top:0;z-index:80;
  padding:10px 16px;background:rgba(10,11,16,.92);backdrop-filter:blur(8px);
  border-bottom:1px solid var(--border);
  /* .82rem, nie .78 — ta reguła stoi PO bloku trybu czytania, więc przy
     tej samej specyficzności wygrywała z podłogą czytelności i zbijała pasek
     do 12,5 px. Zmierzone, nie założone. */
  font-family:var(--mono);font-size:.82rem;letter-spacing:.1em;text-transform:uppercase;
  color:var(--muted);
}
#powrot a{color:var(--accent)}
@media (max-width:860px),(max-height:420px){ #powrot{display:block} }

/* === 10b. KADR: uderzenia i kulminacja ===

   ⚠ POŁOŻENIE. Te reguły mają tę samą specyficzność co bazowe z sekcji 5,
   więc rozstrzyga WYŁĄCZNIE kolejność w pliku. Wklejone wyżej przegrałyby
   po cichu — bez błędu, bez śladu, po prostu bez skutku.

   ⚠ PRÓG 860.01/420.01, nie 861/421. Tryb czytania łapie `max-width:860px`,
   więc zapis 861 zostawia szczelinę, w której nie działa ani jedno, ani drugie
   — a rzutnia bywa ułamkowa naprawdę (skalowanie 125 %, zoom, pasek przewijania).
   Zmieniasz próg tutaj — zmień go też w sekcji 10.

   ⚠ ŻADNYCH `transition` ani `animation` w tym bloku. Wyłącznik ruchu gasi
   `animation` globalnie, ale `transition` gasi imiennie dla `.rv`, `.slide`
   i `.poz` — ruch dopięty tutaj przeżyłby i klawisz A, i preferencję systemu. */
@media screen and (min-width:860.01px) and (min-height:420.01px){

  /* --- UDERZENIA ---
     Zmierzone przed zmianą: zdanie-uderzenie miało 47,3 px, a zwykły nagłówek
     slajdu z pięciowierszową tabelą 46,3 px. Stosunek 1,02 — czyli interpunkcja
     bez akcentu. Teraz 2,75u wobec 2,45u nagłówka. Twarde `<br>` wypadły
     ze slajdów 08 i 20; łamanie oddajemy `text-wrap:balance`, bo przy szerszym
     polu wymuszony podział zostawiał jedno słowo w ostatnim wierszu. */
  /* SKALA SCENICZNA na hero i uderzeniach. Reszta decku zostaje gęsta —
     to świadomy podział: slajdy nośne mają wielkość hasła, slajdy treściowe
     wielkość dokumentu. Zmierzone przed zmianą: uderzenie 47,3 px wobec 46,3 px
     zwykłego nagłówka, czyli deck nie miał ANI JEDNEGO stopnia pisma, który
     mówiłby „to jest ważniejsze". */
  .slide.strike .wrap{max-width:calc(66*var(--u))}
  .slide.strike p{font-size:calc(4.2*var(--u));line-height:1.12;letter-spacing:-.028em}
  .slide.hero .wrap{max-width:calc(74*var(--u))}
  .slide.hero h1.tyt{font-size:calc(4.7*var(--u));line-height:1.04;letter-spacing:-.03em}
  .slide.hero .lead{font-size:calc(1.45*var(--u))}

  /* --- KULMINACJA (slajd 19) ---
     Deck deklarował „najważniejszy slajd", a typografia mówiła „kolejna tabela":
     ten sam stopień pisma co na dziewięciu innych slajdach, ten sam układ,
     ta sama wysokość bloku co slajd 18 — różnica dwóch pikseli.

     ⚠ Ciemniejsze tło ODRZUCONE świadomie: slajd 20 jest uderzeniem na #04060c,
     więc przejście 19→20 nie dałoby żadnego skoku i zabieg byłby niewidoczny
     dokładnie tam, gdzie miał zadziałać. Kulminację niesie SKALA i jedna rzecz,
     której nie ma nigdzie indziej: pierwszy wiersz tabeli wraca do liczby,
     którą deck się otworzył. To domknięcie klamry, nie ozdoba. */
  .slide.kulminacja h2.tyt{font-size:calc(2.7*var(--u));max-width:calc(48*var(--u));line-height:1.06}
  .slide.kulminacja .lead{
    font-family:var(--mono);font-size:calc(.86*var(--u));
    letter-spacing:.14em;text-transform:uppercase;color:var(--muted);
    margin-top:calc(1*var(--u));
  }
  .slide.kulminacja .tab{table-layout:fixed;margin-top:calc(1.8*var(--u))}
  .slide.kulminacja .tab th{
    width:38%;font-size:calc(1.22*var(--u));font-weight:800;line-height:1.18;
    padding-block:calc(.85*var(--u));
  }
  .slide.kulminacja .tab td{
    width:62%;font-size:calc(.98*var(--u));color:var(--muted);
    padding-block:calc(.95*var(--u));padding-right:calc(4*var(--u));
  }
  .slide.kulminacja .tab th,
  .slide.kulminacja .tab td{border-top-color:var(--border-strong)}

  /* Klamra: „Siedem z czternastu" wraca w tym samym stopniu, w jakim
     otworzyło deck. Wiersz jest budowany z rejestru (deck.js, sekcja 14),
     więc liczba nie może się rozjechać ze slajdem 01. */
  .slide.kulminacja .tab tr:first-child th{
    font-size:calc(1.62*var(--u));line-height:1.1;color:var(--text);
  }
}

/* === 10a. WYŁĄCZNIK RUCHU — jedno miejsce, dwa wyzwalacze ===

   Wcześniej ta sama lista selektorów była rozsypana po trzech miejscach
   arkusza i dwa z nich zdążyły się rozjechać — `.poz` miało regułę ratunkową
   tylko dla klasy, a `.kropka` nie miało jej wcale.

   ⚠ POŁOŻENIE JEST CZĘŚCIĄ REGUŁY. Blok stoi NA KOŃCU, bo `.kropka` i `.poz`
   redeklarują animację z tą samą specyficznością — wcześniej w pliku
   przegrałby kolejnością. I PRZED blokiem druku, żeby druk mógł przywrócić
   `.slide{opacity:1;visibility:visible}`.

   ⚠ `.kropka` NIE dostaje `opacity:1`. Jej stan docelowy zależy od danych
   (kropka „w rozwoju" jest przygaszona), więc wymuszenie jedynki zrównałoby
   ją z gotowymi — czyli skłamałoby kolorem. Gasimy jej tylko ruch. */
html.bez-ruchu *,
html.bez-ruchu *::before,
html.bez-ruchu *::after{animation:none!important}
html.bez-ruchu .slide,
html.bez-ruchu #postep .akt-seg i,
html.bez-ruchu #pult,
html.bez-ruchu #spis,
html.bez-ruchu .btn,
html.bez-ruchu .skip,
html.bez-ruchu .spis-lista button{transition:none!important}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation:none!important}
  .slide,#postep .akt-seg i,#pult,#spis,.btn,.skip,
  .spis-lista button{transition:none!important}
}

/* === 11. Druk — jeden slajd na stronę ===
   Nie po to, żeby drukować deck, tylko żeby „zapisz jako PDF" dało
   materiał do wysłania mailem. Bez tego wyjdzie jedna czarna kartka. */
@media print{
  /* ⚠ Bez tego slajd niosący `.on` wystartuje animację wejścia w trakcie
     renderowania do PDF i przy `backwards` migawka może trafić w okno
     opóźnienia — ta jedna strona wyszłaby pusta. */
  *,*::before,*::after{animation:none!important}
  html,body{overflow:visible;height:auto;background:#fff;color:#000}
  .deck{position:static;overflow:visible}
  .deck::before{display:none}
  .slide{
    position:relative;inset:auto;opacity:1;visibility:visible;
    display:block;page-break-after:always;break-after:page;
    padding:16mm;border:0;min-height:auto;
  }
  .tyt em{background:none;-webkit-text-fill-color:#4c1d95;color:#4c1d95}
  .lead,.dop,.tab td,.sc p{color:#333}
  .ghost,#postep,#pult,#spis,#powrot,.skip{display:none}
  .btn{background:none;color:#4c1d95;border:1px solid #4c1d95}
  .kat-ico{background:none;box-shadow:none;border:1px solid #4c1d95}
  .kat-ico svg{color:#4c1d95;filter:none}
}
