/* =========================================================================
   PODSTRONY seotonin — wspólna baza.
   Ten arkusz trzyma to, co na wszystkich podstronach musi wyglądać identycznie:
   warstwy (pole → welon → treść → chrome), znak marki, pasek, stopkę, przyciski,
   kinetyczne odsłony i rytm rozdziałów. Reszta (to, co dana podstrona ma
   własnego) mieszka w jej pliku.
   Wyciągnięte 1:1 ze strony głównej, żeby podstrona nie mogła się rozjechać.
   ========================================================================= */
html{scroll-behavior:auto;background:var(--paper)}
/* Ciemne rozdziały podstron: własne tło na telefonie — powód opisany przy tej
   samej regule w home.css (biały tekst na jasnym tle, gdy płótno nie odświeży
   klatki, to najgorsza możliwa awaria czytelności). */
@media (max-width:899px),(hover:none){
  /* Ta sama warstwa co na stronie głównej — powód opisany tam. */
  body::after{content:"";position:fixed;inset:0;z-index:2;pointer-events:none;
    background:var(--ink-950);opacity:0;transition:opacity .7s var(--ease)}
  /* Pole zeszło w atrament samo — warstwa tylko lekko pogłębia ogon.
     Nie zeszło (uśpiona karta, oszczędzanie baterii, utracony kontekst) —
     bierze całą robotę na siebie, żeby biały tekst nigdy nie stanął na jasnym. */
  html[data-ink] body::after{opacity:.62}
  html[data-ink][data-fieldink] body::after{opacity:.18}
}

/* Telefon przewija się płynnie i nic go nie przyciąga — powód opisany przy tej
   samej decyzji w home.css. Dociąganie zostaje dla myszy i gładzika. */
body{margin:0;overflow-x:clip;background:transparent}
/* warstwy: pole → welon czytelności → treść → chrome */
#field{position:fixed;inset:0;z-index:0;display:block;width:100%;height:100%;pointer-events:none}
.veil{position:fixed;inset:0;z-index:1;pointer-events:none;background:rgba(251,250,247,.42);
  transition:background .7s var(--ease)}
.chapter,.hdr,.ftr{position:relative;z-index:2}
.hdr{z-index:50}
a{color:inherit;text-decoration:none}
a:hover{color:var(--imp)}
::selection{background:var(--glow);color:#fff}
:focus-visible{outline:2.5px solid var(--imp);outline-offset:3px;border-radius:var(--r-sm)}
/* `grid-template-columns` dziala tylko wtedy, gdy `.wrap` jest gridem, a jest
   nim w kilkunastu miejscach (`.ch>.wrap`, `.open .wrap`, `.hero .wrap`...).
   Zadne z nich nie deklaruje sciezki, wiec dostawaly domyslna `auto` — a ta
   nie schodzi ponizej szerokosci minimalnej tresci. Zmierzone przy 320 px:
   „Pozycjonowanie" w naglowku ma 308,8 px, sciezka rosla ponad 280 px pola
   tresci i CALA kolumna wychodzila poza ekran. Uklady wielokolumnowe maja
   wyzsza swoistosc i nadpisuja te linie bez zmian. */
.wrap{max-width:1360px;margin-inline:auto;padding-inline:var(--gutter);width:100%;
  grid-template-columns:minmax(0,1fr)}

/* ---------- kinetyczne odsłony: słowa wypływają zza maski, rozmyte ---------- */
.rw{display:inline-block;overflow:hidden;vertical-align:top;padding:.16em .05em;margin:-.16em -.05em}
.rw>i{display:inline-block;font-style:normal;transform:translateY(112%);filter:blur(12px);opacity:0}
@keyframes rwin{to{transform:none;filter:blur(0);opacity:1}}
.heroreveal .rw>i{animation:rwin 1s var(--ease-out) both;animation-delay:calc(.2s + var(--wd,0s))}
@media (prefers-reduced-motion:no-preference){
  /* Odsłony sterowane obserwatorem, nie scroll-timeline: `body{overflow-x:hidden}`
     czyni z body kontener przewijania, przez co `view()` bywa martwy —
     a wtedy nagłówek zostaje na zawsze niewidoczny. */
  .reveal.in .rw>i{animation:rwin 1s var(--ease-out) both;animation-delay:var(--wd,0s)}
}
@media (prefers-reduced-motion:reduce){.rw>i{transform:none!important;filter:none!important;opacity:1!important}}
/* siatka bezpieczeństwa: naglówek w kadrze NIGDY nie zostaje niewidoczny/rozmyty */
.reveal.shown .rw>i{animation:none!important;opacity:1!important;filter:none!important;transform:none!important}

/* ---------- przyciski ---------- */
.btn{display:inline-flex;align-items:center;gap:12px;height:60px;padding:0 30px;border:0;border-radius:var(--r-full);
  font:600 var(--fs-body)/1 var(--font-text);cursor:pointer;white-space:nowrap;will-change:transform;
  transition:transform .4s var(--spring),box-shadow var(--dur-2) var(--ease),background-position var(--dur-3) var(--ease-out),color var(--dur-2) var(--ease)}
.btn svg{width:18px;height:18px}
.btn--p{background:var(--grad-cta);background-size:200% 100%;color:#fff;box-shadow:var(--shadow-lift)}
.btn--p:hover{background-position:100% 0;color:#fff}
.btn--g{background:rgba(255,255,255,.4);backdrop-filter:blur(10px);color:var(--fg);box-shadow:inset 0 0 0 1.5px var(--line-strong)}
.btn--g:hover{box-shadow:inset 0 0 0 1.5px var(--imp);color:var(--imp)}
.ink .btn--g{background:rgba(255,255,255,.06);color:#F4F2FA;box-shadow:inset 0 0 0 1.5px rgba(244,242,250,.28)}
.ink .btn--g:hover{color:#fff;box-shadow:inset 0 0 0 1.5px var(--imp)}
.kicker{display:inline-flex;align-items:center;gap:12px;margin:0;font:600 var(--fs-xs)/1 var(--font-mono);
  letter-spacing:.18em;text-transform:uppercase;color:var(--fg-faint)}
.kicker .dot{width:9px;height:9px;border-radius:50%;background:var(--grad);animation:pip 2.6s var(--ease) infinite}
.ink .kicker{color:rgba(244,242,250,.6)}
@keyframes pip{0%,100%{transform:scale(1);opacity:1}50%{transform:scale(.55);opacity:.7}}

/* ---------- header ---------- */
.hdr{position:fixed;inset:0 0 auto;height:94px;display:flex;align-items:center;
  transition:background .3s var(--ease),height .35s var(--ease-out),box-shadow .3s var(--ease)}
/* przyklejony pasek chudnie i przepuszcza tło — ma nie konkurować ze sceną */
.hdr[data-stuck]{height:70px;background:rgba(251,250,247,.66);backdrop-filter:blur(18px) saturate(120%)}
/* dolna krawędź przyklejonego paska to wiązanie, nie kreska interfejsu */
.hdr::after{content:"";position:absolute;left:0;right:0;bottom:0;height:1px;opacity:0;
  background:linear-gradient(90deg,transparent,color-mix(in srgb,var(--imp) 55%,transparent) 18%,
    color-mix(in srgb,var(--calm) 50%,transparent) 72%,transparent);
  transition:opacity .35s var(--ease)}
.hdr[data-stuck]::after{opacity:1}
/* na wąskich ekranach pasek mówi, w której sekcji jesteś (nawigacja jest ukryta) */
.hdr-here{margin-left:auto;font:600 var(--fs-xs)/1 var(--font-mono);letter-spacing:.16em;text-transform:uppercase;
  color:var(--fg-faint);opacity:0;transform:translateY(3px);
  transition:opacity .3s var(--ease),transform .3s var(--ease-out)}
.hdr[data-stuck] .hdr-here{opacity:1;transform:none}
@media (min-width:1000px){.hdr-here{display:none}}
.hdr .bar{display:flex;align-items:center;gap:clamp(20px,3vw,52px);width:100%}
/* ZNAK: nazwa złożona krojem, a jej „o" to pierścień benzenowy — chemia wchodzi
   jedną literą zamiast rysowanego alfabetu. Znak trzyma skalę paska (nie dominuje). */
.brand{display:inline-flex;align-items:center;gap:.06em;margin-right:auto;color:var(--fg);text-decoration:none;
  font-family:var(--font-display);font-size:1.02rem;letter-spacing:-.005em;line-height:1;
  font-variation-settings:'wght' 640,'wdth' 96;transition:opacity var(--dur-2) var(--ease)}
.brand .ring{width:.78em;height:.86em;flex:none;color:var(--imp);transform:translateY(.015em)}
.brand .ac{color:var(--imp)}
.brand:hover{opacity:.75;color:var(--fg)}
.hdr nav{display:none;gap:4px}
@media (min-width:1000px){.hdr nav{display:flex}}
/* Nawigacja: sam tekst i podkreślenie, które narasta — kropki pod hasłami
   robiły z paska tablicę ogłoszeń. */
.hdr nav{position:relative;gap:clamp(16px,2vw,34px)}
.hdr nav a{position:relative;display:inline-flex;align-items:center;padding:10px 0 8px;
  font:600 var(--fs-xs)/1 var(--font-mono);letter-spacing:.14em;text-transform:uppercase;color:var(--fg-faint);
  transition:color var(--dur-2) var(--ease)}
.hdr nav a::after{content:"";position:absolute;left:0;right:0;bottom:0;height:2px;border-radius:2px;
  background:var(--grad);transform:scaleX(0);transform-origin:left;
  transition:transform var(--dur-2) var(--ease-out)}
.hdr nav a:hover{color:var(--fg)}
.hdr nav a:hover::after{transform:scaleX(1)}
.hdr nav a[data-here]{color:var(--fg)}
.hdr nav a[data-here]::after{transform:scaleX(1)}
.hdr .btn{display:none;height:46px;padding:0 20px;font-size:var(--fs-xs);letter-spacing:.02em}
@media (min-width:1000px){.hdr .btn{display:inline-flex}}


/* ---------- rozdziały: wspólny rytm i ciemne sceny ---------- */
.chapter{padding-block:clamp(80px,11vh,150px)}
.ink{color:#F4F2FA}
/* bez WebGL pole nie ma skąd się wziąć — tylko wtedy ciemny rozdział maluje
   sobie tło sam, żeby jasny tekst nie leżał na jasnym papierze */
html[data-nogl] .ink{background:var(--ink-950)}
html[data-nogl] .veil{display:none}
#mol{position:fixed;inset:0;z-index:2;width:100%;height:100%;pointer-events:none;display:block}
.chapter,.ftr,.sc{position:relative;z-index:3}
main{position:relative;z-index:3}
/* pierwszy rozdział podstrony: pod paskiem, nie pod nim schowany */
.open{padding-top:clamp(140px,19vh,230px);padding-bottom:clamp(48px,8vh,110px)}
.open .wrap{display:grid;gap:clamp(20px,3vh,38px)}
.open h1{margin:0;font-family:var(--font-display);letter-spacing:-.045em;line-height:.92;
  font-variation-settings:'wght' 760,'wdth' 92,'opsz' 96;font-size:clamp(2.4rem,1rem + 5.4vw,6.4rem);
  max-width:20ch;text-wrap:balance}
.open h1 em{font-style:normal;background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent}
.open .lead{margin:0;font-size:var(--fs-lead);color:var(--fg-muted);max-width:52ch;text-wrap:pretty}
/* Rzad przyciskow. Regula stala TYLKO pod `.open`, wiec na stronie uslugi,
   w wyszukiwarce i w kaflu CTA `.acts` nie bylo w ogole rzedem: dwa CTA
   stały obok siebie w odstepie 4 px (sama spacja miedzy elementami
   liniowymi) i przy najmniejszym ruchu magnesu wchodzily na siebie.
   Odstep w poziomie jest sterowany z panelu. */
.acts{display:flex;flex-wrap:wrap;gap:var(--s-4) var(--ui-acts-gap,24px);align-items:center}
/* okruszki: droga, nie ozdoba */
.crumbs{display:flex;flex-wrap:wrap;align-items:center;gap:10px;margin:0;
  font:600 var(--fs-xs)/1 var(--font-mono);letter-spacing:.14em;text-transform:uppercase;color:var(--fg-faint)}
.crumbs a{color:var(--fg-faint)}.crumbs a:hover{color:var(--imp)}
.crumbs span{opacity:.5}
/* rozdział z nagłówkiem */
.ch{padding-block:clamp(56px,9vh,120px)}
.ch>.wrap{display:grid;gap:clamp(26px,4vh,52px)}
.ch h2{margin:0;font-family:var(--font-display);letter-spacing:-.04em;line-height:.95;
  font-variation-settings:'wght' 740,'wdth' 94,'opsz' 96;font-size:clamp(1.9rem,1rem + 3.2vw,4rem);
  max-width:22ch;text-wrap:balance}
.ch h3{margin:0;font-family:var(--font-display);letter-spacing:-.03em;line-height:1.05;
  font-variation-settings:'wght' 660,'wdth' 96;font-size:clamp(1.2rem,1rem + 1vw,1.9rem)}
.ch p{margin:0;text-wrap:pretty}
.muted{color:var(--fg-muted)}
.ink .muted{color:rgba(244,242,250,.62)}
.ink a:hover{color:var(--glow)}
.ink .rows .no,.ink .col-head span{color:var(--glow)}
.ink .btn--g{color:#F4F2FA;box-shadow:inset 0 0 0 1.5px rgba(244,242,250,.32)}
.ink .btn--g:hover{box-shadow:inset 0 0 0 1.5px rgba(244,242,250,.6)}
.ink .crumbs,.ink .crumbs a{color:rgba(244,242,250,.5)}
.ink .lead{color:rgba(244,242,250,.66)}
/* karty i pola na ciemnym: szkło z drugiej strony — jasny nalot zamiast bieli */
.ink .card,.ink .next a,.ink .po-author,.ink .svc-price,.ink .bl-filter button{
  background:rgba(255,255,255,.05);box-shadow:inset 0 0 0 1px rgba(244,242,250,.14);color:inherit}
.ink a.card:hover,.ink .next a:hover{box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--glow) 42%,transparent),var(--shadow-lift)}
.ink .next span,.ink .team span{color:var(--glow)}
.ink .team li{border-top-color:rgba(244,242,250,.16)}
.ink .team p,.ink .po-author p,.ink .svc-price small,.ink .say figcaption{color:rgba(244,242,250,.6)}
.ink .steps li,.ink .qa details,.ink .lg-sec,.ink .res,.ink .sv-facts,.ink .posts li,.ink .po-share{
  border-color:rgba(244,242,250,.16)}
.ink .steps p,.ink .prose p,.ink .prose li,.ink .p-sub{color:rgba(244,242,250,.66)}
.ink .steps .when,.ink .lg-sec h2 span,.ink .findings .rank,.ink .figs b{color:var(--glow)}
.ink .p-when,.ink .p-read,.ink .figs span,.ink .prose figcaption,.ink .shot-fig figcaption{color:rgba(244,242,250,.5)}
.ink .field label,.ink .co-map figcaption{color:rgba(244,242,250,.5)}
.ink .field input,.ink .field textarea{color:#F4F2FA;box-shadow:inset 0 -2px 0 rgba(244,242,250,.24)}
.ink .field input:focus,.ink .field textarea:focus{box-shadow:inset 0 -2.5px 0 var(--glow)}
.ink .toc a{color:rgba(244,242,250,.6)}
.ink .toc a:hover,.ink .toc a[data-here]{color:var(--glow)}
.ink .prose a,.ink .lg-sec a{color:var(--glow)}
/* wiersze rozdziału: tekst po lewej, wolne pole po prawej dla molekuły */
.two{display:grid;gap:clamp(24px,4vw,64px)}
@media (min-width:1000px){.two{grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr);align-items:start}}
.body-col{display:grid;gap:clamp(16px,2.4vh,28px);max-width:60ch}
/* listy faktów: linia zamiast pudełka */
.rows{list-style:none;margin:0;padding:0;display:grid}
.rows li{display:grid;grid-template-columns:2.6em minmax(0,1fr);gap:clamp(14px,2vw,28px);align-items:baseline;
  padding:clamp(14px,2vh,24px) 0;border-top:1px solid var(--line)}
.ink .rows li{border-top-color:rgba(244,242,250,.16)}
.rows li:last-child{border-bottom:1px solid var(--line)}
.ink .rows li:last-child{border-bottom-color:rgba(244,242,250,.16)}
.rows .no{font:600 var(--fs-sm)/1.2 var(--font-mono);color:var(--imp)}
.rows b{display:block;font-family:var(--font-display);letter-spacing:-.03em;line-height:1.15;
  font-variation-settings:'wght' 640,'wdth' 96;font-size:clamp(1.05rem,.98rem + .7vw,1.5rem)}
.rows small{display:block;margin-top:5px;color:var(--fg-muted);font-size:var(--fs-sm)}
.ink .rows small{color:rgba(244,242,250,.6)}
/* liczby: wynik jest grafiką, nie tabelką */
.figs{display:grid;gap:clamp(24px,3vw,52px);grid-template-columns:repeat(auto-fit,minmax(170px,1fr))}
.figs b{display:block;font-family:var(--font-display);font-size:clamp(2.4rem,1.4rem + 3.6vw,5rem);line-height:.85;
  letter-spacing:-.04em;font-variation-settings:'wght' 800,'wdth' 92;font-variant-numeric:tabular-nums;
  background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent}
.figs span{display:block;margin-top:12px;font-size:var(--fs-sm);color:var(--fg-muted);max-width:22ch}
.ink .figs span{color:rgba(244,242,250,.6)}
/* karty: wyłącznie zaokrąglone, szkło jak w resztcie strony */
.card{border-radius:var(--r-lg);background:rgba(255,255,255,.5);backdrop-filter:blur(14px);
  box-shadow:inset 0 0 0 1px var(--line),var(--shadow-2);padding:clamp(22px,3vw,38px);
  display:grid;gap:var(--s-4);transition:transform .45s var(--spring),box-shadow var(--dur-3) var(--ease)}
a.card:hover{transform:translateY(-4px);box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--imp) 30%,transparent),var(--shadow-lift)}
.ink .card{background:rgba(255,255,255,.05);box-shadow:inset 0 0 0 1px rgba(244,242,250,.14)}
.cards{display:grid;gap:clamp(18px,2.4vw,32px);grid-template-columns:repeat(auto-fit,minmax(260px,1fr))}
/* miejsce na Wasze zdjęcie */
image-slot{display:block;border-radius:var(--r-lg);overflow:hidden}
.shot{border-radius:var(--r-lg);overflow:hidden;box-shadow:var(--shadow-2)}
/* proza: jedna kolumna, którą da się czytać */
.prose{max-width:68ch;display:grid;gap:var(--s-5);font-size:clamp(1.02rem,.98rem + .25vw,1.15rem);line-height:1.72}
.prose h2{margin:clamp(18px,3vh,34px) 0 0;font-family:var(--font-display);letter-spacing:-.03em;line-height:1.08;
  font-variation-settings:'wght' 700,'wdth' 96;font-size:clamp(1.4rem,1.1rem + 1.4vw,2.2rem)}
.prose h3{margin:var(--s-4) 0 0;font-family:var(--font-display);letter-spacing:-.02em;
  font-variation-settings:'wght' 640,'wdth' 98;font-size:clamp(1.12rem,1rem + .6vw,1.45rem)}
.prose p,.prose li{margin:0;color:var(--fg);text-wrap:pretty}
.prose ul,.prose ol{margin:0;padding-left:1.3em;display:grid;gap:10px}
.prose a{color:var(--imp);text-decoration:underline;text-underline-offset:4px;text-decoration-thickness:1.5px}
.prose blockquote{margin:0;padding:clamp(18px,2.6vw,30px) 0;border-top:1px solid var(--line);border-bottom:1px solid var(--line);
  font-family:var(--font-display);font-size:clamp(1.25rem,1rem + 1.2vw,1.9rem);line-height:1.25;letter-spacing:-.03em;
  font-variation-settings:'wght' 620,'wdth' 96}
.prose figcaption{font:500 var(--fs-xs)/1.5 var(--font-mono);letter-spacing:.06em;color:var(--fg-faint)}
/* Kod w zdaniu i blok kodu. Poradniki techniczne sypia nazwami plikow
   i zapytaniami (`robots.txt`, `site:domena.pl`) — bez wlasnego tla nie
   odrozniaja sie od reszty akapitu. Tlo bierzemy z `--imp-soft`, ktory
   `.ink` podmienia sam, wiec ciemny rozdzial nie potrzebuje osobnej reguly.
   Bez kwadratow: pigulka w zdaniu, `--r-lg` na bloku. */
.prose code{font-family:var(--font-mono);font-size:.88em;background:var(--imp-soft);
  padding:.16em .5em;border-radius:var(--r-full);
  /* NIE `white-space:nowrap`. Dlugie polecenie staloby sie nierozdzielnym
     tokenem, a taki token podnosi szerokosc minimalna calej kolumny — ten sam
     mechanizm wysadzil uklad przy oknie 320 px („Pozycjonowanie" w naglowku).
     `anywhere` lamie dopiero wtedy, gdy naprawde nie ma miejsca, i jako jedyna
     wartosc obniza tez szerokosc minimalna. */
  overflow-wrap:anywhere}
.prose pre{margin:0;padding:clamp(16px,2.2vw,26px);background:var(--bg-sunken);
  border-radius:var(--r-lg);box-shadow:inset 0 0 0 1px var(--line);
  /* Szeroka linia ma przewijac sie WEWNATRZ bloku, nie ruszac strony. */
  overflow-x:auto;-webkit-overflow-scrolling:touch}
.prose pre code{background:none;padding:0;border-radius:0;white-space:pre;font-size:.86em}
/* spis treści przy dłuższym tekście */
.toc{position:sticky;top:120px;align-self:start;display:grid;gap:12px;font-size:var(--fs-sm)}
.toc p{margin:0 0 4px;font:600 var(--fs-xs)/1 var(--font-mono);letter-spacing:.16em;text-transform:uppercase;color:var(--fg-faint)}
.toc a{color:var(--fg-muted);padding:3px 0}
.toc a:hover,.toc a[data-here]{color:var(--imp)}
/* SPIS TRESCI NA TELEFONIE TO CO INNEGO NIZ NA DESKTOPIE.
   Na duzym ekranie spis siedzi w bocznej kolumnie (`.po-body` 14em + reszta)
   i to POLOZENIE mowi, ze to nawigacja — dlatego wystarcza mu szept: mala
   etykieta i linki w `--fg-muted`. Na telefonie kolumna znika, spis laduje
   w jednym strumieniu z trescia i ten sam szept czyta sie jak zwykly akapit
   linkow. Zamiast przejmowac wyglad z desktopu, dostaje wlasna forme: karte
   z rama, numeracja jak w reszcie serwisu (01, 02) i wierszami rozdzielonymi
   wlosowa linia. Cel dotyku rosnie przy okazji z 3 px wyscielki do 44 px. */
@media (max-width:999px){
  .toc{position:static;top:auto;gap:0;counter-reset:toc;
    padding:clamp(16px,4.5vw,24px) clamp(16px,4.5vw,24px) 6px;
    background:var(--bg-raised);border-radius:var(--r-lg);
    box-shadow:inset 0 0 0 1px var(--line)}
  .toc p{margin:0 0 8px;color:var(--fg-muted)}
  .toc a{display:grid;grid-template-columns:2.2em minmax(0,1fr);align-items:baseline;
    min-height:44px;padding:11px 0;border-top:1px solid var(--line);
    color:var(--fg);line-height:1.35}
  .toc p + a{border-top:0}
  .toc a::before{counter-increment:toc;content:counter(toc,decimal-leading-zero);
    font:600 var(--fs-xs)/1.6 var(--font-mono);letter-spacing:.1em;color:var(--fg-faint)}
  .toc a[data-here]{color:var(--imp)}
  .toc a[data-here]::before{color:var(--imp)}
  /* Karta na ciemnym rozdziale — ten sam chwyt, co przy panelach rezerwacji. */
  .ink .toc{background:rgba(255,255,255,.06)}
}
/* pytania i odpowiedzi bez ozdób */
.qa{display:grid}
.qa details{border-top:1px solid var(--line);padding:clamp(14px,2vh,22px) 0}
.qa details:last-of-type{border-bottom:1px solid var(--line)}
.qa summary{cursor:pointer;list-style:none;display:flex;gap:var(--s-4);align-items:baseline;
  font-family:var(--font-display);letter-spacing:-.03em;font-variation-settings:'wght' 640,'wdth' 96;
  font-size:clamp(1.05rem,.98rem + .55vw,1.35rem)}
.qa summary::-webkit-details-marker{display:none}
.qa summary::after{content:"+";margin-left:auto;color:var(--imp);font-family:var(--font-mono);font-weight:600}
.qa details[open] summary::after{content:"−"}
.qa p{margin:12px 0 0;max-width:62ch;color:var(--fg-muted)}
.ink .qa details{border-top-color:rgba(244,242,250,.16)}
.ink .qa details:last-of-type{border-bottom-color:rgba(244,242,250,.16)}
.ink .qa p{color:rgba(244,242,250,.62)}
/* wezwanie na koniec podstrony */
.end{padding-block:clamp(60px,10vh,130px)}
.end .wrap{display:grid;gap:clamp(20px,3vh,36px);justify-items:start}
.end h2{margin:0;font-family:var(--font-display);letter-spacing:-.045em;line-height:.94;
  font-variation-settings:'wght' 760,'wdth' 92,'opsz' 96;font-size:clamp(2rem,1rem + 3.6vw,4.4rem);max-width:22ch;text-wrap:balance}
.end h2 em{font-style:normal;background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent}

/* stopka: ostatnia scena, nie spis linków — wielkie domknięcie, potem drobny druk */
.ftr{background:var(--ink-950);color:#F4F2FA;padding:clamp(56px,9vh,110px) 0 var(--s-6)}
/* wiązanie zamiast zwykłej kreski — ten sam motyw, co łańcuch w nawigacji */
.ftr-top{position:relative;display:grid;gap:clamp(20px,3vh,36px);padding-bottom:clamp(34px,5vh,64px)}
.ftr-top::after{content:"";position:absolute;left:0;right:0;bottom:0;height:1px;
  background:linear-gradient(90deg,color-mix(in srgb,var(--imp) 60%,transparent),color-mix(in srgb,var(--calm) 55%,transparent),rgba(244,242,250,.14))}
@media (min-width:900px){.ftr-top{grid-template-columns:minmax(0,1fr) auto;align-items:end;gap:clamp(24px,4vw,72px)}}
.ftr-sign{margin:0;font-family:var(--font-display);letter-spacing:-.045em;line-height:.92;
  font-variation-settings:'wght' 760,'wdth' 92,'opsz' 96;font-size:clamp(2rem,1rem + 3.6vw,4.4rem);
  max-width:22ch;text-wrap:balance}
.ftr-sign em{font-style:normal;background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent}
.ftr-cta{display:inline-flex;align-items:center;justify-content:center;gap:14px;justify-self:start;
  height:58px;padding:0 clamp(24px,2.6vw,36px);border-radius:var(--r-full);color:#fff;
  background:var(--grad-cta);background-size:200% 100%;box-shadow:var(--shadow-lift);
  font:600 clamp(.98rem,.92rem + .3vw,1.15rem)/1 var(--font-text);
  transition:background-position var(--dur-3) var(--ease-out),transform .4s var(--spring)}
.ftr-cta:hover{background-position:100% 0;transform:translateY(-3px);color:#fff}
.ftr-cta svg{width:20px;height:20px;transition:transform .4s var(--spring)}
.ftr-cta:hover svg{transform:translateX(5px)}
.ftr .cols{display:grid;gap:clamp(28px,4vw,56px);grid-template-columns:1fr;margin-top:clamp(34px,5vh,64px)}
@media (min-width:720px){.ftr .cols{grid-template-columns:repeat(2,1fr)}}
@media (min-width:1060px){.ftr .cols{grid-template-columns:1.4fr repeat(3,1fr)}}
.ftr h4,.ftr .ftr-h{margin:0 0 var(--s-4);font:600 var(--fs-xs)/1 var(--font-mono);letter-spacing:.18em;text-transform:uppercase;
  color:rgba(244,242,250,.62)}
.ftr ul{list-style:none;margin:0;padding:0;display:grid;gap:12px}
.ftr a{color:rgba(244,242,250,.72);font-size:var(--fs-sm)}
.ftr a:hover{color:#fff}
/* kafel pierwiastka: znak marki opowiedziany językiem układu okresowego */
.el{display:grid;grid-template-columns:1fr auto;grid-template-rows:auto auto auto;gap:2px 8px;
  width:max-content;padding:14px 16px 12px;border:1px solid rgba(244,242,250,.28);border-radius:var(--r-sm);
  background:linear-gradient(140deg,color-mix(in srgb,var(--imp) 22%,transparent),transparent 70%)}
.el-no{grid-column:1;font:600 var(--fs-xs)/1 var(--font-mono);letter-spacing:.1em;color:rgba(244,242,250,.55)}
.el-mass{grid-column:2;grid-row:1;text-align:right;font:500 var(--fs-xs)/1 var(--font-mono);color:rgba(244,242,250,.45)}
.el-sym{grid-column:1/-1;font-family:var(--font-display);font-size:clamp(2.4rem,1.4rem + 2vw,3.4rem);line-height:.9;
  letter-spacing:-.04em;font-variation-settings:'wght' 780,'wdth' 90;
  background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent}
.el-name{grid-column:1/-1;font:600 var(--fs-xs)/1 var(--font-mono);letter-spacing:.2em;text-transform:uppercase;
  color:rgba(244,242,250,.6)}
.ftr .about p{color:rgba(244,242,250,.6);font-size:var(--fs-sm);max-width:34ch;margin:var(--s-4) 0 0;text-wrap:pretty}
.ftr-dir{display:flex;flex-wrap:wrap;gap:6px clamp(16px,2vw,28px)}
.ftr-dir a{font-family:var(--font-display);font-size:clamp(1rem,.94rem + .3vw,1.2rem);letter-spacing:-.02em;
  font-variation-settings:'wght' 660,'wdth' 96;color:#F4F2FA}
.ftr-dir a:hover{color:var(--glow)}
.ftr .legal{display:flex;flex-wrap:wrap;gap:var(--s-4);justify-content:space-between;margin-top:clamp(26px,3.6vh,46px);
  padding-top:var(--s-5);border-top:1px solid rgba(244,242,250,.14);
  font:500 var(--fs-xs)/1.5 var(--font-mono);letter-spacing:.06em;color:rgba(244,242,250,.62)}
.ftr .legal p{margin:0}
.ftr .legal a{font:inherit;color:rgba(244,242,250,.62)}
.ftr .legal a:hover{color:#fff}

.sticky{position:fixed;left:0;right:0;bottom:0;z-index:45;display:flex;gap:10px;
  padding:12px var(--gutter) calc(12px + env(safe-area-inset-bottom));background:rgba(251,250,247,.94);
  backdrop-filter:blur(12px);box-shadow:0 -1px 0 var(--line);transform:translateY(120%);transition:transform var(--dur-3) var(--ease-out)}
.sticky[data-show]{transform:none}
/* pasek jest position:fixed, więc dolna część dokumentu MUSI mieć zapas na jego
   wysokość — inaczej przykrywał drobny druk stopki i dolną krawędź wezwania */
@media (max-width:999px){
  body.has-sticky .ftr{padding-bottom:calc(96px + env(safe-area-inset-bottom))}
  body.has-sticky #kontakt{padding-bottom:calc(88px + env(safe-area-inset-bottom))}
}
.sticky .btn{flex:1;height:52px;padding:0 14px;font-size:var(--fs-sm)}
@media (min-width:1000px){.sticky{display:none}}

/* =========================================================================
   TELEFON: JEDNA KOTWICA — NA PROGU CIEMNEGO OGONA.

   Strona zmienia tło dokładnie RAZ (reguła „jedna zmiana tła na całą stronę”).
   Gdy przewijanie zatrzyma się w połowie tego progu, na jednym ekranie stoi
   tekst ciemny na jasnym i biały na ciemnym — i to wygląda jak usterka.
   Dlatego próg dostaje kotwicę: `proximity`, więc łapie tylko wtedy, gdy gest
   kończy się w jego pobliżu, i działa w obie strony. Poza tym jednym miejscem
   nic nie przyciąga — reszta strony płynie, tak jak ustaliliśmy.

   Selektor bierze PIERWSZY ciemny rozdział: każdy ciemny poprzedzony innym
   ciemnym kotwicę traci (`.ink ~ .ink`), więc w środku ogona nic już nie łapie.
   ========================================================================= */
@media (max-width:899px),(hover:none){
  /* Kinetyczna odsłona chowa każde słowo (`opacity:0`, blur, przesunięcie)
     i czeka na klasę `.in` od obserwatora. Na telefonie ten callback potrafi
     nie przyjść i nagłówek zostaje niewidoczny na zawsze. Zmierzone na żywej
     stronie: na /o-nas/ i /blog/ całe „Poznajmy Twoje cele” miało `opacity:0`
     przy `animation:none`. Strona główna rezygnuje z tej ozdoby na wąskim
     ekranie — reszta stron musi robić to samo, inaczej tracą nagłówek.
     Reguła MUSI stać PO bazowym `.rw>i{opacity:0}`: media query nie podnosi
     ważności, więc wstawiona wyżej przegrywa samą kolejnością. */
  .rw>i{display:inline;transform:none;filter:none;opacity:1;animation:none!important}
  /* Skoro odslona jest wylaczona, `overflow:hidden` na opakowaniu nie ma juz
     czego chowac — a trzymalo slowo w jednym kawalku. Zmierzone przy 320 px:
     „Pozycjonowanie" w `.rw` wystawalo 11 px poza ekran, mimo ze sam naglowek
     juz sie miescil. Opakowanie ma sie miescic i lamac jak zwykly tekst. */
  .rw{overflow:visible;max-width:100%}
  .rw,.rw>i{overflow-wrap:break-word}

  /* Ta sama siatka bezpieczenstwa, co w home.css. Przyciski z nazwa uslugi
     maja `white-space:nowrap`: „Poznaj szczegoly: Reklama i kampanie" mierzyl
     357 px i przy oknie 360 px wychodzil poza ekran. Zmierzone na /uslugi/. */
  .btn{max-width:100%;white-space:normal;padding-inline:clamp(18px,5vw,28px)}

  /* Okruszki mialy 13 px wysokosci celu — ponizej 24 px, ktore WCAG 2.5.8
     uznaje za minimum. Wyscielka pionowa powieksza sam cel, nie krój. */
  .crumbs a{padding-block:6px}

  html{scroll-snap-type:y proximity;scroll-padding-top:var(--ui-hdr-stuck,78px)}
  main section.ink{scroll-snap-align:start;scroll-snap-stop:always}
  main section.ink ~ section.ink{scroll-snap-align:none}
  /* Na stronie usługi ciemne rozdziały siedzą w <article>, a domknięcie stoi
     już poza nim — rodzeństwo ich nie łączy i wychodziły dwie kotwice 628 px
     od siebie. `:has()` domyka ten przypadek: cokolwiek ciemnego po bloku,
     który już ma ciemny rozdział, kotwicy nie dostaje. */
  main *:has(section.ink) ~ section.ink{scroll-snap-align:none}
  /* Strona bez ciemnego rozdziału ma próg mimo to: schodzi w atrament dopiero
     stopka (`data-pal="ink"`, biały tekst). Bez kotwicy /o-nas/, /blog/,
     /realizacje/ i strony prawne dawały dokładnie ten stan pośredni, o który
     poszło — pół ekranu jasne, pół ciemne. `:has()` wybiera te strony. */
  body:not(:has(main section.ink)) .ftr{scroll-snap-align:start;scroll-snap-stop:always}
}
@media (prefers-reduced-motion:reduce){html{scroll-snap-type:none}}

/* =========================================================================
   KADR ZATOPIONY W SCENIE

   Obrazek wstawiony wprost jest w tym projekcie ciałem obcym: strona to jeden
   ciągły świat z żywym polem pod spodem, a zdjęcie w prostokącie z cieniem
   czyta się jak naklejka na szybie. Zamiast tego kadr ROZPUSZCZA SIĘ BOKAMI
   w tle i dostaje po wierzchu powłokę w barwach pola.

   Dwie decyzje warte zapisania:

   1. Maska zdejmuje też cień. `mask-image` obejmuje CAŁE malowanie elementu,
      a domyślny obszar maski to border-box — więc cokolwiek `box-shadow`
      rysuje poza nim, znika. Cień zdejmujemy więc wprost, żeby nie zostawiać
      w arkuszu deklaracji, która nic nie robi.
   2. Powłoka to zwykły gradient, NIE `mix-blend-mode`. Tryby mieszania są tu
      na liście przyczyn zacięć przewijania (katalog pułapek), a przy obrazku
      na pełną szerokość kosztowałyby dokładnie tam, gdzie widać najbardziej.

   Tokeny `--imp-soft` i `--glow-soft` mają wariant ciemny, więc kadr w rozdziale
   `.ink` przygasa sam, bez osobnej reguły. Gdy przeglądarka nie zna `mask-image`,
   obrazek pokazuje się po prostu z ostrą krawędzią — nic się nie psuje. */
.shot,.scard .pic{
  position:relative;
  -webkit-mask-image:linear-gradient(to right,transparent 0,#000 7%,#000 93%,transparent 100%);
  mask-image:linear-gradient(to right,transparent 0,#000 7%,#000 93%,transparent 100%);
  box-shadow:none}
.shot::after,.scard .pic::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:
    radial-gradient(130% 90% at 8% 12%,var(--imp-soft),transparent 58%),
    radial-gradient(120% 100% at 92% 88%,var(--glow-soft),transparent 56%)}
/* Otwarcie usługi miało własną ramkę i papierowe tło — przy rozpuszczonych
   bokach pierścień urywałby się w powietrzu. */
.shot.sv-shot{background:transparent;box-shadow:none}

/* =========================================================================
   PODGLAD WDROZONEJ STRONY — ramka okna przegladarki.

   Komponent `.mock` byl w motywie od portu prototypu i nie uzywal go zaden
   szablon: pelne okno z paskiem adresu, kropkami i miejscem na ekran. Tutaj
   dostaje wreszcie zadanie — pokazuje strone, ktora zrobilismy. Dla agencji
   od stron to najkrotsza droga od „piszemy, ze umiemy" do „popatrz".

   Zrzut NIE dostaje oprawy `.shot` (rozpuszczone boki): ekran przegladarki ma
   miec ostra krawedz, bo to cytat z cudzej strony, nie kadr ze sceny. Rozpuszcza
   sie dopiero cale okno razem z rama — dlatego maske nosi `.mock`, nie obrazek.

   Pasek `LIVE` jest STATYCZNY. W home.css towarzyszy mu `@keyframes pip`
   pulsujacy bez konca; tu go nie wolamy, bo scena ma juz swoje okna bezruchu
   i dokladanie wiecznej animacji do siatki miniatur jest dokladnie tym, co
   podnosilo TBT. */
.mock{position:relative;display:block;border-radius:var(--r-lg);overflow:hidden;
  background:rgba(255,255,255,.55);backdrop-filter:blur(14px);
  box-shadow:var(--shadow-2);border:1px solid var(--line);text-decoration:none;color:inherit}
.ink .mock{background:rgba(255,255,255,.06);border-color:rgba(244,242,250,.16)}
.mock .chrome{display:flex;align-items:center;gap:8px;padding:11px 14px;border-bottom:1px solid var(--line)}
.ink .mock .chrome{border-bottom-color:rgba(244,242,250,.16)}
.mock .chrome i{width:9px;height:9px;border-radius:50%;background:var(--line-strong);flex:none}
.mock .chrome b{flex:1;min-width:0;margin-left:6px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font:500 var(--fs-xs)/1 var(--font-mono);color:var(--fg-muted);
  background:rgba(255,255,255,.55);padding:7px 12px;border-radius:var(--r-full);border:1px solid var(--line)}
.ink .mock .chrome b{background:rgba(255,255,255,.07);border-color:rgba(244,242,250,.16);color:rgba(244,242,250,.66)}
.mock .chrome .live{display:flex;align-items:center;gap:6px;flex:none;
  font:600 var(--fs-xs)/1 var(--font-mono);letter-spacing:.1em;text-transform:uppercase;color:var(--ok)}
.mock .chrome .live em{width:7px;height:7px;border-radius:50%;background:var(--ok);font-style:normal}
.mock .screen{display:block;aspect-ratio:16/10;overflow:hidden;background:var(--bg-sunken)}
.mock .screen img{display:block;width:100%;height:100%;object-fit:cover;object-position:top center}
.mock figcaption,.mock .cap{display:grid;gap:3px;padding:clamp(13px,1.7vw,18px)}
.mock .cap b{font-family:var(--font-display);font-size:clamp(1rem,.94rem + .3vw,1.18rem);
  letter-spacing:-.02em;font-variation-settings:'wght' 680,'wdth' 96}
.mock .cap span{font-size:var(--fs-sm);color:var(--fg-muted)}
.ink .mock .cap span{color:rgba(244,242,250,.6)}
a.mock{transition:transform .5s var(--ease-out),box-shadow .5s var(--ease-out)}
a.mock:hover{transform:translateY(-3px);box-shadow:var(--shadow-lift)}
/* Cale okno zatapia sie bokami w scenie — tak jak reszta kadrow. */
.sites .mock{-webkit-mask-image:linear-gradient(to right,transparent 0,#000 5%,#000 95%,transparent 100%);
  mask-image:linear-gradient(to right,transparent 0,#000 5%,#000 95%,transparent 100%)}
.sites{display:grid;gap:clamp(20px,2.8vw,38px);grid-template-columns:repeat(auto-fit,minmax(min(100%,300px),1fr))}
