/* Callogue — strona dokumentów prawnych i wizytówka.
   Bez zależności zewnętrznych: to ma stanąć na zwykłym hostingu statycznym.

   Paleta jest PRZENIESIONA 1:1 z aplikacji (app/src/main/java/com/callogue/ui/theme/Color.kt).
   Semantyka stamtąd obowiązuje też tutaj:
     • bursztyn = marka
     • grafit i kość = powierzchnie
   Drabinki powierzchni są celowo płaskie — karta odcina się KRAWĘDZIĄ, nie zmianą koloru.
   Szeroki rozstrzał robi z ekranu breję, co w apce zostało już raz naprawione. */

:root {
    /* kość — powierzchnie jasne (ciepła biel, nie zimna) */
    --bg: #F7F4EF;          /* Bone */
    --surface: #FCFAF6;     /* BoneLow */
    --card: #FFFFFF;        /* BoneLowest — karty w apce są białe */
    --card-alt: #F1ECE4;    /* BoneCard */
    --outline: #CFC8BC;     /* BoneOutline */
    --outline-soft: #E4DDD2;

    /* teksty */
    --text: #1C1B19;        /* InkLight */
    --muted: #5D5A53;       /* InkLightMuted */

    /* bursztyn — marka */
    --accent: #8A5A00;      /* AmberInk: czytelny bursztyn na jasnym tle */
    /* Kolor tekstu NA wypełnieniu bursztynem. Musi być zmienną, bo `--accent` ma
       w obu motywach przeciwną jasność: w jasnym to ciemny brąz #8A5A00, w ciemnym
       jasny bursztyn #E8A33D. Wpisany na sztywno ciemny tekst dawał w jasnym motywie
       kontrast 2.9 (brąz na czerni) — pigułka języka i numerki kroków były nieczytelne. */
    --on-accent: #FFF7E8;
    --accent-bg: #FBE7C2;   /* AmberContainerLight */
    --accent-on-bg: #2B1700;

    /* stany */
    --sage: #3F6B4C;
    --sage-bg: #D7E8DC;
    --danger: #B3261E;
    --danger-bg: #F9DEDC;

    --radius: 16px;
    --radius-sm: 12px;
    --maxw: 46rem;

    /* Płytka pod Callo. CELOWO nie jest przedefiniowana w bloku ciemnym: maskotka ma
       grafitowy korpus (#2B2A27), więc potrzebuje jasnego tła w OBU motywach. Użycie
       tu --accent-bg dawało w ciemnym #3A2B0C, czyli ciemny brąz — Callo znikał, zostawały
       same bursztynowe oczy. */
    --callo-plate: #FBE7C2;

    /* Warstwy tła i szkła — gramatyka przeniesiona z petermikolajewicz.dev:
       techniczna siatka, świecące kule w kolorze akcentu, karty ze szkła
       z rozjaśnieniem u górnej krawędzi. Tam akcentem jest androidowa zieleń,
       tu bursztyn — ma być rodzina, nie kopia. */
    --grid-line: rgb(43 42 39 / 0.06);
    --orb-1: rgb(232 163 61 / 0.10);
    --orb-2: rgb(232 163 61 / 0.06);
    --orb-3: rgb(143 185 155 / 0.06);
    --glass-bg: linear-gradient(160deg, rgb(255 255 255 / 0.82), rgb(255 255 255 / 0.45));
    --glass-border: rgb(43 42 39 / 0.10);
    --glass-inset: inset 0 1px 0 rgb(255 255 255 / 0.9);
    --shadow: 0 20px 50px -24px rgb(43 42 39 / 0.35);
}

@media (prefers-color-scheme: dark) {
    :root {
        --bg: #121211;          /* Graphite */
        --surface: #171615;     /* GraphiteSurface */
        --card: #211F1D;        /* GraphiteCard */
        --card-alt: #1B1A18;
        --outline: #3B3834;
        --outline-soft: #2A2825;

        --text: #EDE9E3;        /* InkDark */
        --muted: #9C978F;       /* InkDarkMuted */

        --accent: #E8A33D;      /* Amber — na grafcie świeci */
        --on-accent: #1C1B19;
        --accent-bg: #3A2B0C;   /* AmberContainerDark */
        --accent-on-bg: #FBE7C2;

        --sage: #8FB99B;
        --sage-bg: #1F2E22;
        --danger: #FFB4AB;
        --danger-bg: #93000A;

        --grid-line: rgb(232 163 61 / 0.045);
        /* Stonowane po pierwszej próbie: przy 0.26 bursztyn zalewał pół ekranu
           i całość wyglądała jak rozlana siarka, a nie jak poświata pod treścią. */
        --orb-1: rgb(232 163 61 / 0.11);
        --orb-2: rgb(232 163 61 / 0.07);
        --orb-3: rgb(143 185 155 / 0.06);
        --glass-bg: linear-gradient(160deg, rgb(255 255 255 / 0.055), rgb(255 255 255 / 0.018));
        --glass-border: rgb(255 255 255 / 0.09);
        --glass-inset: inset 0 1px 0 rgb(255 255 255 / 0.07);
        --shadow: 0 20px 50px -20px rgb(0 0 0 / 0.6);
    }
}

/* --- Przejścia między stronami --------------------------------------------
   Serwis jest wielodokumentowy — sześć osobnych plików HTML, bez żadnego routera —
   więc każde kliknięcie w nawigacji dawało białe mignięcie i skok do góry.
   `@view-transition` znosi to bez jednej linii JavaScriptu.

   Wsparcie wg dokumentacji zespołu Chrome (modern-web-guidance, sierpień 2026):
   „Supported by: Chrome 126 (Jun 2024), Edge 126 (Jun 2024), and Safari 18.2
   (Dec 2024). Unsupported in: Firefox." Nie jest to jeszcze Baseline, ale reguła
   degraduje się do zwykłej nawigacji — Firefox po prostu nie dostaje animacji
   i nic się nie psuje. Dlatego wchodzi bez `@supports`. */
@view-transition { navigation: auto; }

/* Nagłówek jest identyczny na każdej stronie, więc zamiast przenikać razem z resztą
   powinien zostać na miejscu. Nazwa musi być unikalna w obrębie dokumentu — jest
   jeden `header.site`, więc warunek jest spełniony. */
header.site { view-transition-name: naglowek; }

@media (prefers-reduced-motion: reduce) {
    ::view-transition-group(*),
    ::view-transition-old(*),
    ::view-transition-new(*) { animation: none !important; }
}

/* --- Łamanie tekstu -------------------------------------------------------
   `balance` wyrównuje długość wierszy w nagłówkach — w polskim ma to większe
   znaczenie niż w angielskim, bo długie słowa („zainstalujesz", „prywatności")
   zostawiają w dwuwierszowym nagłówku jedno słowo w drugiej linii.
   `pretty` pilnuje ostatniego wiersza akapitu, czyli sierot. Oba degradują się
   do zwykłego `wrap` tam, gdzie ich nie ma. */
h1, h2, h3, .lead, .eyebrow, figcaption, .cta-status { text-wrap: balance; }
p, li, dd { text-wrap: pretty; }

/* --- Tło: siatka i kule ---------------------------------------------------
   Siatka daje wrażenie rysunku technicznego, kule — głębi. Obie warstwy są
   `fixed`, więc treść płynie po nich i strona nabiera planów zamiast leżeć płasko.

   Siatka jest wygaszana maską ku dołowi: pełna kratka na całej wysokości robi
   z tekstu papier milimetrowy. Ma być czuć u góry i znikać tam, gdzie się czyta. */
.bg-grid,
.bg-orbs {
    position: fixed;
    inset: 0;
    pointer-events: none;
    z-index: -2;
}

.bg-grid {
    background-image:
        linear-gradient(var(--grid-line) 1px, transparent 1px),
        linear-gradient(90deg, var(--grid-line) 1px, transparent 1px);
    background-size: 76px 76px;
    -webkit-mask-image: radial-gradient(ellipse 90% 55% at 50% 0%, #000 30%, transparent 100%);
    mask-image: radial-gradient(ellipse 90% 55% at 50% 0%, #000 30%, transparent 100%);
}

.bg-orbs { z-index: -1; overflow: hidden; }

.bg-orbs i {
    position: absolute;
    display: block;
    border-radius: 50%;
    filter: blur(70px);
}

/* Mniejsze i mocniej rozmyte niż w pierwszej wersji — mają dawać poświatę przy
   krawędziach, a nie malować tło na bursztynowo. */
.bg-orbs i:nth-child(1) { width: 30vw; height: 30vw; left: -12vw; top: -10vw; background: var(--orb-1); }
.bg-orbs i:nth-child(2) { width: 24vw; height: 24vw; right: -10vw; top: 38vh; background: var(--orb-2); }
.bg-orbs i:nth-child(3) { width: 26vw; height: 26vw; left: 30vw; bottom: -16vw; background: var(--orb-3); }

@media (prefers-reduced-motion: no-preference) {
    .bg-orbs i { animation: dryf-kuli 26s ease-in-out infinite alternate; }
    .bg-orbs i:nth-child(2) { animation-duration: 34s; animation-delay: -8s; }
    .bg-orbs i:nth-child(3) { animation-duration: 30s; animation-delay: -16s; }
}

@keyframes dryf-kuli {
    from { transform: translate3d(0, 0, 0) scale(1); }
    to   { transform: translate3d(4vw, -3vh, 0) scale(1.12); }
}

/* --- Kroje pisma ----------------------------------------------------------
   Hostowane U SIEBIE, nie z CDN Google. Nie z powodu wydajności: wpięcie
   `fonts.gstatic.com` przekazuje adres IP użytkownika do Google przy każdym wejściu,
   a niemieckie sądy uznały to już za naruszenie RODO bez podstawy prawnej. Przy
   produkcie, którego argumentem sprzedażowym jest prywatność, byłby to zły żart —
   i kolejny podmiot do wpisania do rejestru czynności.

   Pliki zmienne (variable), tylko podzbiory latin i latin-ext, bo polskie ogonki
   siedzą w tym drugim. Razem ok. 250 KB, ładowane z `font-display: swap`,
   więc tekst jest widoczny od pierwszej klatki.

   Fraunces to miękki, lekko „książkowy" szeryf — daje ciepło i powagę naraz,
   czyli dokładnie ton tej marki. Inter niesie treść i nie walczy o uwagę. */
@font-face {
    font-family: "Fraunces";
    src: url("fonts/fraunces-latin-ext.woff2") format("woff2");
    font-weight: 400 700;
    font-display: swap;
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
    font-family: "Fraunces";
    src: url("fonts/fraunces-latin.woff2") format("woff2");
    font-weight: 400 700;
    font-display: swap;
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: "Inter";
    src: url("fonts/inter-latin-ext.woff2") format("woff2");
    font-weight: 400 700;
    font-display: swap;
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
    font-family: "Inter";
    src: url("fonts/inter-latin.woff2") format("woff2");
    font-weight: 400 700;
    font-display: swap;
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

* { box-sizing: border-box; }

/* `clip`, nie `hidden`: obie ucinają wystające elementy, ale `hidden` tworzy kontener
   przewijania i zepsułoby `position: sticky` w przypiętej sekcji poziomej. */
html { scroll-behavior: smooth; overflow-x: clip; }

body {
    margin: 0;
    background: var(--bg);
    color: var(--text);
    font-family: "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
    font-size: 17px;
    line-height: 1.7;
    -webkit-text-size-adjust: 100%;
    font-feature-settings: "cv05" 1, "ss03" 1; /* czytelniejsze l oraz ostrzejsze ł/ż */
}

/* Nagłówki szeryfem — kontrast z treścią robi połowę charakteru strony.
   `opsz` to oś optyczna Fraunces: przy dużych stopniach font sam wyostrza szeryfy
   i zacieśnia światło, więc nagłówek nie wygląda jak powiększony tekst. */
h1, h2, h3,
.brand,
.scene h3,
.event .title {
    font-family: "Fraunces", Georgia, "Times New Roman", serif;
    font-variation-settings: "SOFT" 30, "WONK" 1;
    font-weight: 600;
    letter-spacing: -0.015em;
}

h1 { font-variation-settings: "SOFT" 40, "WONK" 1, "opsz" 120; }

/* Gradientowy tekst na kluczowej frazie. `background-clip: text` wymaga
   przezroczystego koloru — bez zapasowego `color` przed nim starsza przeglądarka
   pokazałaby pustkę zamiast napisu. */
.grad {
    color: var(--accent);
    background-image: linear-gradient(115deg, #B9822C 0%, #E8A33D 45%, #8A5A00 100%);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
}

/* `background-image`, NIE skrót `background` — skrót resetuje `background-clip`
   z powrotem na `border-box` i zamiast liter wychodzi pełny bursztynowy prostokąt. */
@media (prefers-color-scheme: dark) {
    .grad { background-image: linear-gradient(115deg, #F7D9A6 0%, #E8A33D 50%, #C98A2E 100%); }
}
h2 { font-variation-settings: "SOFT" 35, "WONK" 1, "opsz" 60; }

/* Cytat w pasie scen — kursywa Fraunces jest tu mocniejsza niż jakikolwiek obrazek */
.scene .frame-quote p,
.callo-note p {
    font-family: "Fraunces", Georgia, serif;
    font-variation-settings: "SOFT" 60, "WONK" 1;
}

/* --- Ziarno ---------------------------------------------------------------
   Cieniutka warstwa szumu na całej stronie. Płaskie tło w jednym kolorze wygląda
   na ekranie jak plastik; ziarno daje mu fakturę papieru, nie zmieniając ani jednego
   koloru z palety. Generowane w SVG, więc zero dodatkowych żądań.
   Musi być `pointer-events: none`, inaczej przykryłoby całą stronę i zjadło kliknięcia. */
body::before {
    content: "";
    position: fixed;
    inset: 0;
    z-index: 9999;
    pointer-events: none;
    opacity: 0.04;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)'/%3E%3C/svg%3E");
}

@media (prefers-color-scheme: dark) {
    body::before { opacity: 0.055; }
}

/* --- Pojawianie się przy przewijaniu --------------------------------------
   Animacje sterowane przewijaniem (`animation-timeline`) zamiast obserwatora w JS:
   chodzą na wątku kompozytora, więc nie drgają, gdy główny wątek ma robotę.
   Wsparcie ~84% (Chrome/Edge 115+, Firefox 132+, Safari 18+); reszta po prostu
   widzi treść od razu, bo bez @supports nic się nie ukrywa. */
@supports (animation-timeline: view()) {
    @media (prefers-reduced-motion: no-preference) {
        .reveal {
            animation: reveal-up both;
            animation-timeline: view();
            animation-range: entry 5% cover 28%;
        }
    }
}

@keyframes reveal-up {
    from { opacity: 0; transform: translateY(28px); }
    to   { opacity: 1; transform: none; }
}

/* --- Nagłówek --- */

header.site {
    border-bottom: 1px solid var(--outline-soft);
    background: var(--surface);
    position: sticky;
    top: 0;
    z-index: 10;
}

header.site .inner {
    max-width: var(--maxw);
    margin: 0 auto;
    padding: 0.75rem 1.25rem;
    display: flex;
    align-items: center;
    gap: 0.75rem;
    flex-wrap: wrap;
}

.brand {
    font-weight: 700;
    font-size: 1.05rem;
    letter-spacing: -0.01em;
    text-decoration: none;
    color: var(--text);
    display: flex;
    align-items: center;
    gap: 0.6rem;
}

.brand svg { width: 2rem; height: 2rem; display: block; }

nav.site { margin-left: auto; display: flex; gap: 1rem; align-items: center; }

nav.site a {
    color: var(--muted);
    text-decoration: none;
    font-size: 0.9rem;
    padding: 0.2rem 0;
    border-bottom: 2px solid transparent;
}

nav.site a:hover { color: var(--text); }
nav.site a[aria-current="page"] { color: var(--accent); border-bottom-color: var(--accent); }

/* Przełącznik języka.
   Pierwsza wersja była jedną pigułką z napisem „EN" na tle `--accent-bg`. Dwa błędy:
   w ciemnym motywie to tło ma wartość #3A2B0C, czyli ciemny brąz — wychodziła brunatna
   plama z nieczytelnym napisem; a sam skrót drugiego języka nie mówi, na której wersji
   właśnie jesteś. Teraz widać oba, a bieżący jest wyróżniony.

   Druga wersja miała wspólny tor (ramka + tło) i pigułkę tylko pod aktywnym. Wyglądało
   to na niedokończone: bursztynowa plamka dotykała ramki od środka, a drugi język był
   samym tekstem w powietrzu — czyli oko widziało padding po jednej stronie i jego brak
   po drugiej. Teraz toru nie ma wcale, są dwie pigułki tej samej wielkości: aktywna
   wypełniona, druga obrysowana. `min-width` wyrównuje je mimo różnych szerokości liter. */
.lang-switch {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
}

/* Prefiks `nav.site` nie jest ozdobą. Reguła `nav.site a` wyżej ma szczegółowość
   (0,1,2), a samo `.lang-switch a` tylko (0,1,1) — więc to ona wygrywała i wtłaczała
   pigułce języka `padding: 0.2rem 0` oraz `border-bottom: 2px`. Aktywny język jest
   `<span>`, którego ta reguła w ogóle nie łapie, więc wyglądał poprawnie, a nieaktywny
   link tracił boczne marginesy i był o piksel wyższy. Stąd wyrównanie szczegółowości. */
nav.site .lang-switch a,
nav.site .lang-switch span {
    display: inline-block;
    /* 3rem, nie 2.6rem: „EN" jest o ~1 px szersze od „PL" i przy ciaśniejszym
       minimum wychodziło poza nie, więc pigułki miały różną szerokość. */
    min-width: 3rem;
    box-sizing: border-box;
    text-align: center;
    font-size: 0.76rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    line-height: 1.35;
    padding: 0.3rem 0.7rem;
    /* Przezroczysty obrys także na aktywnej pigułce, inaczej byłaby o 2 px niższa
       od nieaktywnej i obie przestałyby stać w jednej linii. */
    border: 1px solid transparent;
    border-radius: 999px;
    text-decoration: none;
    transition: background 0.15s, color 0.15s, border-color 0.15s;
}

/* Bieżący język: pełne wypełnienie bursztynem. Kolor tekstu z `--on-accent`,
   bo bursztyn ma w obu motywach przeciwną jasność — patrz komentarz przy zmiennej. */
.lang-switch [aria-current="true"] {
    background: var(--accent);
    color: var(--on-accent);
}

.lang-switch a:not([aria-current]) {
    color: var(--muted);
    border-color: var(--outline);
}

.lang-switch a:not([aria-current]):hover {
    color: var(--text);
    border-color: var(--accent);
    background: var(--outline-soft);
}

/* --- Treść --- */

main {
    max-width: var(--maxw);
    margin: 0 auto;
    padding: 2.5rem 1.25rem 5rem;
}

h1 {
    font-size: 2rem;
    line-height: 1.25;
    letter-spacing: -0.02em;
    margin: 0 0 0.4rem;
}

.meta {
    color: var(--muted);
    font-size: 0.9rem;
    margin: 0 0 2.5rem;
    padding-bottom: 1.5rem;
    border-bottom: 1px solid var(--outline-soft);
}

h2 {
    font-size: 1.28rem;
    letter-spacing: -0.01em;
    margin: 3rem 0 0.75rem;
    scroll-margin-top: 5rem;
}

h3 {
    font-size: 1.05rem;
    margin: 2rem 0 0.5rem;
    scroll-margin-top: 5rem;
}

p { margin: 0 0 1rem; }
ul, ol { margin: 0 0 1rem; padding-left: 1.35rem; }
li { margin-bottom: 0.4rem; }

a { color: var(--accent); }
strong { font-weight: 650; }

code {
    background: var(--card-alt);
    padding: 0.1em 0.4em;
    border-radius: 6px;
    font-size: 0.88em;
    font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
}

/* --- Spis treści --- */

.toc {
    background: var(--card);
    border: 1px solid var(--outline-soft);
    border-radius: var(--radius);
    padding: 1.1rem 1.4rem;
    margin-bottom: 2.5rem;
}

/* Etykieta jak nagłówek dnia w apce: wersaliki, rozstrzelone, wyciszone */
.toc p, .eyebrow {
    margin: 0 0 0.6rem;
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--muted);
    font-weight: 700;
}

.toc ol { margin: 0; padding-left: 1.2rem; columns: 2; column-gap: 2rem; }
.toc li { margin-bottom: 0.25rem; font-size: 0.92rem; }
.toc a { text-decoration: none; }
.toc a:hover { text-decoration: underline; }

@media (max-width: 34rem) {
    .toc ol { columns: 1; }
}

/* --- Wyróżnienia --- */

.callout {
    border-radius: var(--radius);
    padding: 1rem 1.25rem;
    margin: 1.5rem 0;
    border: 1px solid var(--outline-soft);
    background: var(--card);
}

.callout p:last-child { margin-bottom: 0; }

.callout.key { border-color: var(--accent); background: var(--accent-bg); color: var(--accent-on-bg); }
.callout.key a { color: var(--accent-on-bg); }
.callout.warn { border-color: var(--accent); background: var(--accent-bg); color: var(--accent-on-bg); }
.callout.danger { border-color: var(--danger); background: var(--danger-bg); color: var(--danger); }

.callout .label {
    display: block;
    font-size: 0.76rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    font-weight: 700;
    margin-bottom: 0.4rem;
    opacity: 0.85;
}

/* --- Tabele --- */

.table-wrap { overflow-x: auto; margin: 1.5rem 0; }

table {
    border-collapse: collapse;
    width: 100%;
    font-size: 0.93rem;
    min-width: 32rem;
}

th, td {
    border: 1px solid var(--outline-soft);
    padding: 0.6rem 0.8rem;
    text-align: left;
    vertical-align: top;
}

th { background: var(--card-alt); font-weight: 650; }

/* --- Strona główna --- */

/* --- Nagłówek strony ------------------------------------------------------
   Bursztynowa poświata pod Callo. Nie jest ozdobą: płaskie tło w jednym kolorze
   spłaszcza maskotkę, a rozmyta plama daje jej miejsce, w którym stoi. */
.hero { text-align: center; padding: 2.5rem 0 0.5rem; position: relative; }

.hero::before {
    content: "";
    position: absolute;
    top: -3rem;
    left: 50%;
    width: min(30rem, 110%);
    aspect-ratio: 1;
    transform: translateX(-50%);
    background: radial-gradient(circle, rgb(232 163 61 / 0.20) 0%, rgb(232 163 61 / 0.06) 42%, transparent 68%);
    pointer-events: none;
    z-index: -1;
}

@media (prefers-color-scheme: dark) {
    .hero::before {
        background: radial-gradient(circle, rgb(232 163 61 / 0.16) 0%, rgb(232 163 61 / 0.05) 45%, transparent 70%);
    }
}

/* Callo oddycha. Ruch jest ledwo zauważalny i to jest zamierzone — maskotka ma
   sprawiać wrażenie żywej, a nie machać do przechodniów. */
@media (prefers-reduced-motion: no-preference) {
    .hero .callo-plate { animation: oddech 6s ease-in-out infinite; }
}

@keyframes oddech {
    0%, 100% { transform: translateY(0) rotate(0deg); }
    50%      { transform: translateY(-9px) rotate(-1.2deg); }
}

/* Parallax pasa ze zdjęciem: fotografia płynie wolniej niż strona, więc pas
   zyskuje głębię zamiast przesuwać się jak naklejka. Skala 1.14 daje zapas,
   żeby przy skrajnym przesunięciu nie odsłonić krawędzi. */
@supports (animation-timeline: view()) {
    @media (prefers-reduced-motion: no-preference) {
        .photo-band img {
            animation: parallaks linear both;
            animation-timeline: view();
            animation-range: cover 0% cover 100%;
        }
    }
}

@keyframes parallaks {
    from { transform: translateY(-7%) scale(1.14); }
    to   { transform: translateY(7%)  scale(1.14); }
}

.hero svg { width: 8rem; height: 8rem; }
.hero h1 { font-size: 2.3rem; margin-top: 1rem; }

.lead { font-size: 1.12rem; color: var(--muted); margin-bottom: 2rem; }
.hero .lead { max-width: 34rem; margin-left: auto; margin-right: auto; }

.cards { display: grid; gap: 1rem; margin: 2rem 0; }

/* Karty partnerów. `auto-fit` zamiast sztywnej liczby kolumn, bo partnerów przybywa:
   przy dwóch układa dwie kolumny, przy trzech trzy, na wąskim ekranie schodzi do jednej
   — i nie wymaga ani zmiany klasy, ani media query, gdy dojdzie czwarty.
   Partnerzy celowo NIE są różnicowani: obok siebie czytają się jak równorzędne adresy
   do wyboru, jedna pod drugą jak ranking. */
.cards.partnerzy { grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); }

/* Logotypy partnerów. Stoją na jasnej płytce, bo to CUDZE znaki i nie wolno ich
   przemalować pod nasz motyw — a szare „CENTER" MiCenter na naszym ciemnym tle
   schodzi do ~2,9:1 kontrastu. Płytka jest prawie niewidoczna w jasnym motywie
   (biel na `--card`) i staje się białym kaflem w ciemnym, czyli pojawia się
   dokładnie tam, gdzie jest potrzebna. */
.partner-logo {
    display: inline-flex;
    align-items: center;
    /* `content-box`, bo arkusz ma globalne `border-box` — przy nim 26 px to CAŁA
       płytka razem z paddingiem, znak dotyka krawędzi i kafel wygląda na przycięty. */
    box-sizing: content-box;
    height: 34px;
    margin-bottom: 0.85rem;
    padding: 0.35rem 0.65rem;
    border-radius: 8px;
    background: #FFFFFF;
    justify-content: center;
}

/* ⚠️ Logotypy wyrównujemy MASĄ OPTYCZNĄ, nie wysokością. Wyrównanie wysokością działa
   tylko między znakami jednowierszowymi; znak dwuwierszowy (ikona + dwie linijki) dostaje
   przy tej samej wysokości połowę pola na tekst i czyta się o połowę słabiej niż sąsiedzi.
   MiCenter przy 24 px zajmuje 191×24 ≈ 4,6 tys. px²; „Kolega Informatyk" o proporcji 4:1
   potrzebuje na tyle samo 32 px. Płytka zostaje jednakowa, żeby rząd kart był wyrównany. */
.partner-logo img { height: 24px; width: auto; display: block; }
.partner-logo img.stos { height: 32px; }

/* MIUIservice nie ma pliku z logo — nigdzie, w żadnym formacie; ich własna strona
   składa nazwę dwoma kolorami (`--primary: #ff6b35` + ciemny) i tyle jest ich znaku.
   Odtwarzamy tę konwencję naszym krojem w tej samej wysokości co znak MiCenter,
   żeby karty były symetryczne. Do podmiany, gdy przyślą prawdziwy plik. */
.partner-logo.tekst {
    font-weight: 700;
    font-size: 1.1rem;
    line-height: 1;
    letter-spacing: -0.015em;
    color: #2B2A27;
}
.partner-logo.tekst b { color: #FF6B35; font-weight: 700; }


/* Szkło zamiast płaskiego wypełnienia: delikatny gradient, cienka jasna krawędź
   i rozjaśnienie wzdłuż górnego brzegu. To ostatnie robi największą różnicę —
   sugeruje, że karta ma grubość i łapie światło z góry. */
.card,
.toc,
.callout:not(.key):not(.warn):not(.danger),
.scene .frame,
.shots figure .shot {
    background-image: var(--glass-bg);
    border-color: var(--glass-border);
    box-shadow: var(--glass-inset), var(--shadow);
}

.card {
    display: block;
    background-color: var(--card);
    border: 1px solid var(--outline-soft);
    border-radius: var(--radius);
    padding: 1.3rem 1.5rem;
    text-decoration: none;
    color: inherit;
    transition: border-color 0.15s, transform 0.15s, box-shadow 0.15s;
}

.card:hover { box-shadow: var(--glass-inset), 0 24px 46px -22px rgb(232 163 61 / 0.35); }

.card:hover { border-color: var(--accent); transform: translateY(-2px); }
.card h2 { margin: 0 0 0.35rem; font-size: 1.12rem; color: var(--accent); }
.card p { margin: 0; color: var(--muted); font-size: 0.94rem; }

/* Podgląd wpisu w kalendarzu — ten sam motyw co pierwsza strona onboardingu */
.event {
    background: var(--card-alt);
    border-radius: var(--radius);
    padding: 1.1rem 1.3rem;
    margin: 1.5rem 0;
    display: flex;
    gap: 0.9rem;
}

.event .bar {
    width: 4px;
    border-radius: 2px;
    background: var(--accent);
    flex: none;
}

.event .time { color: var(--accent); font-size: 0.85rem; font-weight: 600; }
.event .title { font-weight: 650; }
.event .body { color: var(--muted); font-size: 0.92rem; }

/* --- Zrzuty ekranu --- */

/* Ramka telefonu: sam obrazek na płaskim tle wygląda jak wklejka, a nie jak ekran.
   Grafitowa obwódka jest tym samym kolorem co korpus Callo — spina zrzut z marką. */
.shot {
    display: block;
    width: 100%;
    max-width: 250px;
    /* BEZ tego obrazek bierze wysokość z atrybutu `height` w HTML i renderuje się
       250×1169 zamiast proporcjonalnie. Atrybuty width/height zostają, bo rezerwują
       miejsce i zapobiegają skakaniu układu przy wczytywaniu — ale proporcję musi
       przywrócić CSS. */
    height: auto;
    border-radius: 22px;
    border: 6px solid #2B2A27;
    background: #2B2A27;
    box-shadow: 0 6px 20px rgb(0 0 0 / 0.14);
    margin: 0 auto;
}

.shots {
    display: flex;
    flex-wrap: wrap;
    gap: 1.5rem;
    justify-content: center;
    margin: 2rem 0;
}

.shots figure { margin: 0; max-width: 250px; }

.shots figcaption {
    margin-top: 0.7rem;
    font-size: 0.86rem;
    color: var(--muted);
    text-align: center;
    line-height: 1.5;
}

/* --- Scrollytelling: telefon zostaje, treść płynie -------------------------

   Trzy kroki to jedna historia, a nie trzy osobne bloki. Telefon przypina się
   na czas czytania, a zrzuty przenikają się w miarę przewijania — czytelnik nie
   traci z oczu ekranu, o którym właśnie czyta.

   Robione WYŁĄCZNIE w CSS. Każdy krok nadaje sobie nazwaną oś czasu widoku
   (`view-timeline-name`), rodzic udostępnia je rodzeństwu przez `timeline-scope`,
   a nałożone na siebie zrzuty odsłaniają się kolejno wzdłuż tych osi.

   Warstwowo, nie naprzemiennie: pierwszy zrzut leży na spodzie i jest widoczny
   od początku, kolejne wjeżdżają NA niego i zostają. Dzięki temu nigdy nie ma
   klatki, w której nie widać żadnego ekranu — a przewijanie w górę odtwarza to
   wstecz, bo animacje sterowane przewijaniem są przewijalne w obie strony. */
.story {
    display: grid;
    grid-template-columns: 262px 1fr;
    gap: 3.5rem;
    margin: 3rem 0 4rem;
    timeline-scope: --krok1, --krok2, --krok3;
}

.story-phone {
    position: sticky;
    top: 5.5rem;
    aspect-ratio: 250 / 527;
    align-self: start;
}

/* Ramka pod PRAWDZIWY zrzut ekranu.
   Domyślne 250/527 (0,474) powstało pod rysowane makiety. Zrzut z telefonu 1080×2280
   po odcięciu paska nawigacji ma 0,511 — jest szerszy, więc `object-fit: cover`
   ścinał mu boki po ~3,5% z każdej strony i zjadał margines interfejsu.
   Własna proporcja zamiast tego: nic nie trzeba kadrować ani dokładać. */
.story-phone.foto { aspect-ratio: 720 / 1410; }

.story-phone .shot {
    position: absolute;
    inset: 0;
    max-width: none;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Krok wypełnia mniej więcej ekran, żeby w danej chwili czytało się jeden i żeby
   przełączenie zrzutu miało z czym się zgrać. */
.story-step {
    min-height: 78vh;
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 2rem 0;
}

/* Przełączanie zrzutów: obserwator przecięcia, nie oś czasu przewijania.
   Wersja na `animation-timeline` była elegantsza, ale nie umiałem jej tu zweryfikować —
   ukryty panel podglądu nie przewija strony i nie kompozytuje, więc oś czasu widoku
   nie ma czasu bieżącego. Skoro nie da się sprawdzić, czy działa, nie może zostać.
   Obserwator działa wszędzie i mieści się w kilkunastu liniach. */
.story-phone .shot {
    opacity: 0;
    transition: opacity 0.45s ease, transform 0.45s ease;
    transform: scale(0.985);
}

.story-phone .shot.is-active {
    opacity: 1;
    transform: none;
}

/* Bez skryptu (albo przy wyłączonych animacjach) widać pierwszy zrzut — tak samo
   jak w układzie mobilnym. Klasa `js` dokładana jest przez skrypt na starcie. */
html:not(.js) .story-phone .shot:first-child { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
    .story-phone .shot { transition: none; }
}

/* Bez przypinania: telefon nad opisem, historia zamienia się w zwykłe kroki */
@media (max-width: 52rem) {
    .story { grid-template-columns: 1fr; gap: 0; timeline-scope: none; }
    .story-phone { position: static; aspect-ratio: auto; max-width: 240px; margin: 0 auto 1.5rem; }
    .story-phone .shot { position: static; height: auto; }
    .story-phone .shot:nth-child(n+2) { display: none; }
    .story-step { padding: 1.5rem 0 3rem; }
}

/* Krok: zrzut obok opisu. Na wąskim ekranie zrzut idzie NAD tekstem, bo obrazek
   telefonu jest tu dowodem na to, co mówi akapit — ma go poprzedzać, nie domykać. */
.step {
    display: grid;
    grid-template-columns: 250px 1fr;
    gap: 2.5rem;
    /* Do góry, nie do środka: zrzut telefonu jest dwa razy wyższy od opisu, więc
       wyśrodkowanie zostawiało nad tekstem dziurę wielkości akapitu. */
    align-items: start;
    margin: 3.5rem 0;
}

/* Wspólne dla obu układów kroku: zwykłego (.step) i narracyjnego (.story-step).
   Wcześniej style wisiały tylko pod `.step`, więc w sekcji narracyjnej numer renderował
   się jako goła cyfra, a nagłówki i akapity szły domyślną typografią przeglądarki. */
.step .num,
.story-step .num {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.1rem;
    height: 2.1rem;
    border-radius: 999px;
    background: var(--accent);
    color: var(--on-accent);
    font-weight: 700;
    font-size: 0.95rem;
    margin-bottom: 0.9rem;
    flex: none;
    align-self: flex-start;
}

.step h3,
.story-step h3 {
    margin: 0 0 0.6rem;
    font-size: 1.35rem;
    letter-spacing: -0.01em;
}

.step p,
.story-step p { color: var(--muted); margin-bottom: 0.7rem; }

.step p strong,
.story-step p strong { color: var(--text); }

@media (max-width: 44rem) {
    .step { grid-template-columns: 1fr; gap: 1.2rem; }
    .step .shot { max-width: 240px; }
}

/* --- Wybór języka przy wielu wersjach -------------------------------------
   Przy dwóch językach przełącznik był parą pigułek. Przy dwunastu to musi być
   `<select>`: dwanaście pigułek nie mieści się w pasku, a na telefonie zawijają się
   w trzy rzędy i rozpychają nagłówek. Element natywny daje przy okazji obsługę
   klawiatury, czytników ekranu i systemowe menu na telefonie — za darmo.

   Bez JavaScriptu `onchange` nie zadziała, ale lista i tak pokazuje, na której
   wersji jesteś, a linki do pozostałych języków siedzą w `<link rel="alternate">`. */
.lang-select { margin: 0; display: flex; min-width: 0; }

/* Przy jedenastu językach najdłuższa nazwa („Nederlands") rozpycha `<select>`,
   a razem z trzema linkami pasek wychodził na telefonie 4 px poza ekran i strona
   dostawała przewijanie w poziomie. Nawigacja może się więc zawinąć do drugiego
   rzędu, a sama lista ma górny limit szerokości. */
@media (max-width: 32rem) {
    header.site .inner { flex-wrap: wrap; row-gap: 0.6rem; }
    nav.site { flex-wrap: wrap; gap: 0.55rem 0.9rem; justify-content: flex-start; margin-left: 0; }
    .lang-select select { max-width: 100%; }

    /* Belka jest przyklejona i przy tej szerokości łamie się na dwa rzędy — ma 141 px
       zamiast ~57 px. `scroll-margin-top: 5rem` z reguły bazowej zostawia 61 px za mało,
       więc cel kotwicy lądował POD belką: klikasz „Włącz nagrywanie" i nagłówka nie widać.
       Zapas do 9rem = 144 px. */
    h2, h3 { scroll-margin-top: 9rem; }
}

.lang-select select {
    font: inherit;
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--text);
    background: var(--card-alt);
    border: 1px solid var(--outline);
    border-radius: 999px;
    padding: 0.3rem 1.9rem 0.3rem 0.8rem;
    cursor: pointer;
    /* Własna strzałka, bo natywna bywa w innym kolorze niż reszta paska.
       `appearance: none` musi iść z jawnym tłem, inaczej Safari maluje swoje. */
    appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%238A5A00' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.7rem center;
    background-size: 0.62rem;
}

@media (prefers-color-scheme: dark) {
    .lang-select select {
        background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%23E8A33D' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E");
    }
}

.lang-select select:hover { border-color: var(--accent); }
.lang-select select:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Etykieta dla czytników ekranu — widoczna wyłącznie dla nich. Nie `display: none`,
   bo to usunęłoby ją także z drzewa dostępności. */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

/* Pisma spoza łacinki. Fraunces i Inter są tu wgrane jako podzbiory łacińskie,
   więc dewanagari i tak spadłoby na font systemowy — ale dopiero po nieudanej
   próbie, co daje mignięcie. Jawny stos od razu wskazuje właściwy krój. */
body.script-deva,
body.script-deva h1,
body.script-deva h2,
body.script-deva h3,
body.script-deva .lead {
    font-family: "Noto Sans Devanagari", "Nirmala UI", "Mangal", system-ui, sans-serif;
}

/* --- FAQ i test telefonu --------------------------------------------------
   Pytania siedzą w `<details>`, żeby strona dała się przejrzeć wzrokiem, a nie
   przewijać przez trzy ekrany. Element jest natywny: działa bez JavaScriptu,
   ma poprawną obsługę klawiatury i czytników ekranu, a treść zwiniętych sekcji
   i tak jest w DOM, więc indeksuje się normalnie. */
.faq {
    margin: 1.5rem 0 2.5rem;
    border: 1px solid var(--outline-soft);
    border-radius: var(--radius);
    overflow: hidden;
    background: var(--card);
}

.faq details { border-top: 1px solid var(--outline-soft); }
.faq details:first-child { border-top: 0; }

.faq summary {
    padding: 0.95rem 1.2rem 0.95rem 2.6rem;
    position: relative;
    cursor: pointer;
    font-weight: 600;
    font-size: 1rem;
    line-height: 1.45;
    list-style: none;
    transition: background 0.15s;
}

.faq summary::-webkit-details-marker { display: none; }

.faq summary:hover { background: var(--card-alt); }

.faq summary:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: -2px;
}

/* Znacznik rysowany z dwóch kresek zamiast znaku „+", bo obraca się płynnie
   i nie zależy od tego, czy dany font ma sensowny plus. */
.faq summary::before,
.faq summary::after {
    content: "";
    position: absolute;
    left: 1.15rem;
    top: 50%;
    width: 0.72rem;
    height: 2px;
    border-radius: 1px;
    background: var(--accent);
    transition: transform 0.2s ease;
}

.faq summary::after { transform: translateY(-50%) rotate(90deg); }
.faq summary::before { transform: translateY(-50%); }
.faq details[open] summary::after { transform: translateY(-50%) rotate(0deg); }

.faq details > div {
    padding: 0 1.2rem 1.1rem 2.6rem;
    color: var(--muted);
}

.faq details > div p:last-child,
.faq details > div ul:last-child { margin-bottom: 0; }

@media (prefers-reduced-motion: reduce) {
    .faq summary::before, .faq summary::after { transition: none; }
}

/* Test „czy Twój telefon nagrywa" — trzy kroki, bo to jedyna odpowiedź, która
   nie zestarzeje się przy następnej aktualizacji systemu. */
.test-steps {
    counter-reset: krok;
    list-style: none;
    margin: 1.4rem 0;
    padding: 0;
    display: grid;
    gap: 0.9rem;
}

.test-steps li {
    counter-increment: krok;
    display: grid;
    grid-template-columns: 2.1rem minmax(0, 1fr);
    gap: 0.9rem;
    align-items: start;
    margin: 0;
}

.test-steps li::before {
    content: counter(krok);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.1rem;
    height: 2.1rem;
    border-radius: 999px;
    background: var(--accent);
    color: var(--on-accent);
    font-weight: 700;
    font-size: 0.95rem;
}

/* Znaczniki w tabeli producentów. Nie tylko kolor — także znak, bo na kolorze
   samym w sobie nie można opierać informacji (daltonizm, wydruk mono). */
.mark-yes, .mark-no, .mark-maybe {
    font-weight: 700;
    white-space: nowrap;
}

.mark-yes { color: var(--sage); }
.mark-no { color: var(--danger); }
.mark-maybe { color: var(--accent); }

/* --- Makiety ekranów aplikacji --------------------------------------------
   Lista rozmów i rozwinięte podsumowanie, odtworzone tak jak wpis w kalendarzu.
   Poza tłumaczeniem załatwia to drugą rzecz: prawdziwy zrzut podsumowania niósł
   nazwę realnej firmy i treść o programie zdrowotnym z autentycznej rozmowy.
   W makiecie stoi tam historia z tartakiem, ta sama co w reszcie serwisu.

   Paleta jest jasna niezależnie od motywu strony — z tego samego powodu co przy
   `.calmock`: to ma wyglądać jak ekran telefonu, a nie jak kolejna sekcja. */
.appmock {
    --am-tlo: #F7F4EF;
    --am-karta: #FFFFFF;
    --am-tekst: #1C1B19;
    --am-przygasz: #5D5A53;
    --am-akcent: #8A5A00;
    --am-plakietka: #FBE7C2;
    --am-linia: #E4DDD2;

    background: var(--am-tlo);
    color: var(--am-tekst);
    display: flex;
    flex-direction: column;
    height: 100%;
    font-size: 0.72rem;
    line-height: 1.45;
    text-align: left;
    overflow: hidden;
}

.appmock .tresc { flex: 1; overflow: hidden; padding: 0.9rem 0.85rem 0; }
.appmock .marka { font-weight: 700; font-size: 1.05rem; margin: 0 0 0.7rem; }

.appmock .szukajka {
    display: flex; align-items: center; gap: 0.5rem;
    background: #EFE9DF; border-radius: 999px;
    padding: 0.45rem 0.8rem; color: var(--am-przygasz);
    margin-bottom: 0.6rem;
}

.appmock .filtr {
    display: inline-block; border: 1px solid var(--am-linia);
    border-radius: 999px; padding: 0.25rem 0.7rem;
    font-size: 0.68rem; margin-bottom: 0.8rem;
}

.appmock .sekcja {
    font-size: 0.6rem; letter-spacing: 0.09em; text-transform: uppercase;
    color: var(--am-przygasz); font-weight: 700; margin: 0.7rem 0 0.4rem;
}

.appmock .rozmowa {
    background: var(--am-karta); border: 1px solid var(--am-linia);
    border-radius: 12px; padding: 0.55rem 0.75rem; margin-bottom: 0.45rem;
    display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center;
}

.appmock .rozmowa .kto { font-weight: 700; font-size: 0.88rem; }
.appmock .rozmowa .meta { display: flex; align-items: center; gap: 0.4rem; margin-top: 0.15rem; }
.appmock .rozmowa .godz { color: var(--am-przygasz); font-size: 0.68rem; }

.appmock .plakietka {
    background: var(--am-plakietka); color: var(--am-akcent);
    border-radius: 4px; padding: 0.08rem 0.3rem;
    font-size: 0.55rem; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase;
}

.appmock .strzalka { color: var(--am-przygasz); font-size: 0.8rem; }

/* Rozwinięta karta — drugi ekran. */
.appmock .rozmowa.otwarta { display: block; }
.appmock .rozmowa.otwarta .naglowek { display: grid; grid-template-columns: minmax(0,1fr) auto; align-items: center; }
.appmock .rozmowa.otwarta .numer { color: var(--am-akcent); font-weight: 600; margin: 0.6rem 0 0.5rem; }
.appmock .rozmowa.otwarta .temat { color: var(--am-akcent); font-weight: 700; margin: 0 0 0.1rem; }
.appmock .rozmowa.otwarta .dlugosc { color: var(--am-przygasz); font-size: 0.66rem; margin: 0 0 0.6rem; }
.appmock .rozmowa.otwarta p { margin: 0 0 0.6rem; }
.appmock .rozmowa.otwarta .etykieta { font-size: 0.62rem; letter-spacing: 0.06em; font-weight: 700; margin-bottom: 0.2rem; }
.appmock .rozmowa.otwarta ul { margin: 0 0 0.6rem; padding-left: 0.85rem; list-style: none; }
.appmock .rozmowa.otwarta li { text-indent: -0.85rem; margin-bottom: 0.15rem; }
.appmock .rozmowa.otwarta li::before { content: "• "; }
.appmock .akcja { color: var(--am-akcent); font-weight: 600; display: block; margin-bottom: 0.5rem; }

.appmock .stopka-karty {
    display: flex; align-items: center; gap: 0.7rem;
    border-top: 1px solid var(--am-linia); padding-top: 0.55rem; margin-top: 0.3rem;
}
.appmock .stopka-karty .pigulka { border: 1px solid var(--am-linia); border-radius: 999px; padding: 0.25rem 0.65rem; }
.appmock .stopka-karty .link { color: var(--am-akcent); font-weight: 600; }
.appmock .stopka-karty .ikony { margin-left: auto; display: flex; gap: 0.6rem; color: var(--am-przygasz); }

/* Dolna nawigacja aplikacji. */
.appmock .nav {
    display: grid; grid-template-columns: repeat(3, 1fr);
    border-top: 1px solid var(--am-linia); background: var(--am-tlo);
    padding: 0.4rem 0 0.6rem; text-align: center; font-size: 0.6rem;
    color: var(--am-przygasz);
}
.appmock .nav .ikona { display: block; font-size: 0.95rem; margin-bottom: 0.15rem; }
.appmock .nav .aktywna { color: var(--am-akcent); font-weight: 700; }
.appmock .nav .aktywna .ikona {
    background: var(--am-plakietka); border-radius: 999px;
    padding: 0.1rem 0.75rem; display: inline-block;
}

/* --- Makieta wpisu w kalendarzu -------------------------------------------
   Odtworzony ekran szczegółów wydarzenia, a nie zrzut. Powód jest praktyczny:
   zrzut ma wypalony polski tekst i wypalone łamanie linii. Przemalowanie go na
   jedenaście języków oznaczałoby jedenaście razy trafić w te same prostokąty,
   a przy dewanagari doszedłby jeszcze font, którego w zrzucie nie ma. Tekst
   w HTML sam się zawija, więc dłuższe fińskie zdanie po prostu weźmie trzy
   wiersze zamiast dwóch.

   Paleta jest CELOWO jasna w obu motywach strony. To ma wyglądać jak ekran
   telefonu pokazujący jasną aplikację — gdyby makieta ciemniała razem ze stroną,
   przestałaby czytać się jako telefon i zaczęła jako kolejna sekcja serwisu. */
.calmock {
    --cm-tlo: #FDFBFF;
    --cm-tekst: #1B1B1F;
    --cm-przygasz: #45464F;
    --cm-linia: #E3E1EC;
    --cm-akcent: #7C8FE8;

    background: var(--cm-tlo);
    color: var(--cm-tekst);
    border-radius: 18px;
    padding: 1.15rem 1.15rem 1.4rem;
    font-size: 0.78rem;
    line-height: 1.5;
    text-align: left;
    overflow: hidden;
}

.calmock .pasek {
    display: flex;
    align-items: center;
    gap: 0.9rem;
    color: var(--cm-przygasz);
    font-size: 1.05rem;
    margin-bottom: 1.1rem;
}

.calmock .pasek .rozpychacz { margin-left: auto; }

.calmock .tytul {
    display: grid;
    grid-template-columns: 0.85rem minmax(0, 1fr);
    gap: 0.75rem;
    align-items: start;
    margin-bottom: 0.5rem;
}

.calmock .kropka {
    width: 0.85rem;
    height: 0.85rem;
    border-radius: 3px;
    background: var(--cm-akcent);
    margin-top: 0.32rem;
}

.calmock .tytul h4 {
    margin: 0;
    font-size: 1.12rem;
    font-weight: 500;
    line-height: 1.3;
    letter-spacing: -0.01em;
}

.calmock .kiedy {
    margin: 0 0 1.15rem 1.6rem;
    color: var(--cm-przygasz);
    font-size: 0.82rem;
}

/* Wiersze z ikoną — dzwonek przypomnienia i kreski opisu. Ikony są tekstowe,
   bo to makieta, a nie próba udawania konkretnej wersji Androida. */
.calmock .wiersz {
    display: grid;
    grid-template-columns: 1.6rem minmax(0, 1fr);
    gap: 0.35rem;
    align-items: start;
    padding-top: 0.85rem;
    border-top: 1px solid var(--cm-linia);
}

.calmock .wiersz + .wiersz { margin-top: 0.85rem; }
.calmock .wiersz .ikona { color: var(--cm-przygasz); font-size: 0.95rem; line-height: 1.3; }
.calmock .wiersz p { margin: 0 0 0.75rem; }
.calmock .wiersz p:last-child { margin-bottom: 0; }
.calmock .wiersz ul { margin: 0 0 0.75rem; padding-left: 0.9rem; list-style: none; }
.calmock .wiersz li { margin: 0 0 0.2rem; text-indent: -0.9rem; }
.calmock .wiersz li::before { content: "• "; }

.calmock .cicho { color: var(--cm-przygasz); }
.calmock .link { color: #4B5EAB; text-decoration: underline; }

/* Makieta wchodzi tam, gdzie stały zrzuty, więc dziedziczy ich klasę `.shot`
   (ramka telefonu, cień, zaokrąglenie). `.shot` było pisane pod obrazek, stąd
   te dwie poprawki dla wersji z treścią w środku. */
.shot-mock {
    overflow: hidden;
    padding: 0;
    /* `.shot` ustawia `height: auto`, co dla diva znaczy „tyle, ile treści".
       Tu jest to pożądane w poincie, gdzie makieta ma się cała zmieścić. */
}

/* W przypiętym telefonie kadr jest stały, więc makieta musi go wypełnić
   i uciąć nadmiar tekstu — dokładnie jak ekran telefonu. */
.story-phone .shot-mock { display: block; }

.story-phone .calmock {
    height: 100%;
    border-radius: 0;
    font-size: 0.62rem;
    padding: 0.9rem;
}

/* --- Dzień w kalendarzu ---------------------------------------------------
   Najmocniejszy argument produktu: nie pojedynczy wpis, tylko cały dzień gęsto
   wypełniony rozmowami, które wpadły tam same i leżą obok zwykłych wydarzeń.

   Świadomie ODTWORZONE, a nie zrzucone z telefonu. Prawdziwy zrzut takiego dnia
   niesie komplet nazwisk i numerów rozmówców, dane o zdrowiu, awatar właściciela
   i nazwy wewnętrznych projektów pracodawcy — a retusz kilkunastu osobnych pól
   zostawia szansę, że coś zostanie. Odtworzenie w HTML jest szczelne, ostrzejsze
   od zrzutu i działa w obu motywach.

   Siatka ma wiersz na każde 30 minut, więc wpis pozycjonuje się przez `grid-row`
   zamiast liczenia pikseli od góry. */
.daygrid {
    margin: 2.5rem 0 3rem;
    padding: clamp(1rem, 2.5vw, 1.8rem);
    border: 1px solid var(--glass-border);
    border-radius: calc(var(--radius) + 8px);
    background-image: var(--glass-bg);
    box-shadow: var(--glass-inset), var(--shadow);
}

.daygrid-head {
    display: flex;
    align-items: baseline;
    gap: 0.9rem;
    margin-bottom: 1.1rem;
    padding-bottom: 0.9rem;
    border-bottom: 1px solid var(--outline-soft);
}

.daygrid-head .dow { font-size: 0.8rem; color: var(--muted); text-transform: uppercase; letter-spacing: 0.08em; font-weight: 700; }
.daygrid-head .dom { font-size: 1.9rem; font-weight: 700; line-height: 1; }
.daygrid-head p { margin: 0; color: var(--muted); font-size: 0.92rem; }

.daygrid-body {
    display: grid;
    grid-template-columns: 3.4rem minmax(0, 1fr);
    /* 20 wierszy = od 08:00 do 18:00 co pół godziny. Wiersz musi być wyższy niż
       pigułka wpisu (ok. 26 px), inaczej wpisy w sąsiednich wierszach na siebie
       nachodzą — przy 1.55rem kolidowały trzy pary. */
    grid-template-rows: repeat(20, 1.95rem);
    column-gap: 0.6rem;
}

/* Godziny stoją co drugi wiersz, czyli o pełnych godzinach. */
.daygrid-body .h {
    grid-column: 1;
    font-size: 0.76rem;
    color: var(--muted);
    font-variant-numeric: tabular-nums;
    transform: translateY(-0.45em);
}

.daygrid-body .rule {
    grid-column: 2;
    border-top: 1px solid var(--outline-soft);
    min-width: 0;
}

.daygrid .ev {
    grid-column: 2;
    align-self: start;
    z-index: 1;
    display: flex;
    align-items: center;
    gap: 0.4rem;
    min-width: 0;
    margin-top: 2px;
    padding: 0.22rem 0.7rem;
    border-radius: 999px;
    font-size: 0.82rem;
    line-height: 1.35;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Wpis z rozmowy — bursztynowy, bo to on jest bohaterem. */
.daygrid .ev.call {
    background: var(--accent-bg);
    color: var(--accent-on-bg);
    border: 1px solid var(--accent);
}

/* Zwykłe wydarzenie użytkownika — celowo blade. Chodzi o pokazanie, że wpisy
   z rozmów wtapiają się w istniejący kalendarz, a nie zajmują go dla siebie. */
.daygrid .ev.own {
    background: var(--card-alt);
    color: var(--muted);
    border: 1px dashed var(--outline);
}

.daygrid .ev .t { font-weight: 700; font-variant-numeric: tabular-nums; flex: none; }

.daygrid-foot {
    margin: 1rem 0 0;
    font-size: 0.86rem;
    color: var(--muted);
}

/* Na wąskim ekranie siatka godzin przestaje mieć sens: pigułka ma ~250 px i sześć
   z dziewięciu wpisów ucinał wielokropek — czyli znikała dokładnie ta treść, która
   ma przekonywać. Poniżej 34rem rozkład zamienia się więc w prostą listę, gdzie
   tekst może się zawinąć. Godziny i linijki siatki znikają, bo każdy wpis i tak
   niesie swoją godzinę, a kolejność w DOM jest chronologiczna. */
@media (max-width: 34rem) {
    .daygrid-body {
        display: flex;
        flex-direction: column;
        gap: 0.45rem;
    }

    .daygrid-body .h,
    .daygrid-body .rule { display: none; }

    .daygrid .ev {
        align-items: flex-start;
        margin-top: 0;
        padding: 0.4rem 0.7rem;
        border-radius: var(--radius-sm);
        font-size: 0.8rem;
        white-space: normal;
        overflow: visible;
    }
}

/* --- Przyciski i wezwanie do działania ------------------------------------
   Strona przez cały czas nie miała ani jednego przycisku: prowadziła czytelnika
   przez całą narrację i zostawiała go bez żadnego następnego kroku.

   Od 30.08.2026 apka jest w Google Play i pobranie jest pierwszym przyciskiem.
   Drugim zostaje sprawdzenie, czy telefon w ogóle nagrywa rozmowy — bez tego
   aplikacja nie zrobi nic, a instalacja „na próbę" wraca jako jedna gwiazdka.
   To ten sam filtr, co w opisie sklepowym (STORE_LISTING.md: „odstraszenie
   niepasującego użytkownika jest tańsze niż jego pozyskanie"), tylko przesunięty
   o jedno miejsce w prawo zamiast skasowany. */
.btn {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.78rem 1.5rem;
    border: 1px solid transparent;
    border-radius: 999px;
    font-family: inherit;
    font-size: 0.98rem;
    font-weight: 700;
    line-height: 1.2;
    text-decoration: none;
    background: var(--accent);
    color: var(--on-accent);
    box-shadow: 0 6px 18px rgb(232 163 61 / 0.18);
    transition: transform 0.15s, box-shadow 0.15s, background 0.15s, border-color 0.15s;
}

.btn:hover { transform: translateY(-1px); box-shadow: 0 10px 26px rgb(232 163 61 / 0.28); }
.btn:active { transform: none; box-shadow: 0 4px 12px rgb(232 163 61 / 0.2); }

.btn.ghost {
    background: transparent;
    color: var(--text);
    border-color: var(--outline);
    box-shadow: none;
}

.btn.ghost:hover { border-color: var(--accent); background: var(--outline-soft); }

@media (prefers-reduced-motion: reduce) {
    .btn, .btn:hover, .btn:active { transform: none; transition: none; }
}

.cta-row {
    display: flex;
    flex-wrap: wrap;
    gap: 0.7rem;
    align-items: center;
    margin-top: 1.7rem;
}

.hero .cta-row { justify-content: center; }

.cta-status {
    margin-top: 1rem;
    font-size: 0.88rem;
    color: var(--muted);
}

.cta-status strong { color: var(--text); font-weight: 600; }

/* Domknięcie strony: ten sam panel ze szkła co przy poincie, żeby oba „przystanki"
   czytały się jako jedna rodzina, a nie dwa przypadkowe pudełka. */
.cta-final {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: clamp(1.2rem, 3vw, 2.2rem);
    align-items: center;
    margin: 3.5rem 0 2rem;
    padding: clamp(1.5rem, 3.5vw, 2.6rem);
    border: 1px solid var(--glass-border);
    border-radius: calc(var(--radius) + 8px);
    background-image: var(--glass-bg);
    box-shadow: var(--glass-inset), var(--shadow);
}

.cta-final h2 { margin: 0 0 0.5rem; font-size: clamp(1.4rem, 3vw, 1.9rem); }
.cta-final > div > p { color: var(--muted); margin-bottom: 0; }

.cta-final .callo-plate {
    width: 7.5rem;
    height: 7.5rem;
    flex: none;
}

@media (max-width: 44rem) {
    .cta-final { grid-template-columns: 1fr; justify-items: center; text-align: center; }
    .cta-final .cta-row { justify-content: center; }
}

/* --- Pointa historii: wpis w kalendarzu -----------------------------------
   Moment, do którego prowadzi cała narracja — otwierasz kalendarz, a wpis już tam jest.
   Zrzut wklejony po prostu w kolumnę tekstu byłby dowodem, ale nie byłby sceną, a to
   jest pointa. Więc telefon dostaje własny panel ze szkła i podpisy mówiące, na co
   patrzeć. Jest przy tym szerszy niż w krokach (`.shot` trzyma 250 px), bo tutaj
   sensem jest, żeby dało się PRZECZYTAĆ, co w tym wpisie stoi.

   `.reveal` NIE może wisieć na tym samym elemencie co `.wide`: animacja kończy się
   na `transform: none`, co skasowałoby `translateX(-50%)` centrujące pas na pełną
   szerokość — panel odskoczyłby w prawo. Dlatego `.wide` na zewnątrz, `.payoff .reveal`
   w środku. */
.payoff {
    display: grid;
    /* 21rem, nie węziej: zrzut ma 540 px szerokości, więc poniżej ~330 px opis
       wydarzenia robi się nieczytelny, a to on jest tu dowodem. */
    grid-template-columns: minmax(0, 21rem) minmax(0, 1fr);
    gap: clamp(1.5rem, 4vw, 3rem);
    align-items: center;
    margin: 2.5rem 0 3rem;
    padding: clamp(1.3rem, 3vw, 2.4rem);
    border: 1px solid var(--glass-border);
    border-radius: calc(var(--radius) + 8px);
    background-image: var(--glass-bg);
    box-shadow: var(--glass-inset), var(--shadow);
}

.payoff .shot {
    max-width: none;
    width: 100%;
    /* Ledwie widoczny obrót — tyle, żeby zrzut czytał się jak przedmiot położony
       na stole, a nie jak ilustracja wklejona w siatkę. */
    transform: rotate(-1.3deg);
}

.payoff h3 {
    margin: 0 0 0.7rem;
    font-size: clamp(1.3rem, 2.4vw, 1.7rem);
    letter-spacing: -0.015em;
}

.payoff > div > p { color: var(--muted); margin-bottom: 0.5rem; }
.payoff > div > p strong { color: var(--text); }

.payoff-notes {
    list-style: none;
    margin: 1.3rem 0 0;
    padding: 0;
    display: grid;
    gap: 0.8rem;
}

.payoff-notes li {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: 0.75rem;
    align-items: baseline;
    font-size: 0.95rem;
    line-height: 1.55;
    color: var(--muted);
}

.payoff-notes strong { color: var(--text); font-weight: 600; }

.payoff-notes .k {
    font-size: 0.68rem;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    font-weight: 700;
    color: var(--accent-on-bg);
    background: var(--accent-bg);
    padding: 0.22rem 0.6rem;
    border-radius: 999px;
    white-space: nowrap;
}

@media (max-width: 52rem) {
    .payoff { grid-template-columns: 1fr; justify-items: center; text-align: left; }
    .payoff .shot { max-width: 17rem; transform: none; }
    .payoff-notes .k { justify-self: start; }
}

/* --- Fotografie --- */

/* Zdjęcia są tłem nastroju, nie dowodem. Dowodem są zrzuty z aplikacji — dlatego
   fotografii jest MAŁO i żadna nie stoi obok kroku, żeby nie konkurowała ze zrzutem.
   Przy portretach nie wolno sugerować, że ta osoba korzysta z Callogue: modele
   z banku zdjęć nie udzielili zgody na rekomendowanie produktu. */
.photo-band {
    position: relative;
    margin: 2.5rem -1.25rem;
    overflow: hidden;
}

.photo-band img {
    display: block;
    width: 100%;
    height: 340px;
    object-fit: cover;
    object-position: center 35%;
}

/* Przyciemnienie, żeby karta na wierzchu była czytelna niezależnie od zdjęcia */
.photo-band::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(to right, rgb(18 18 17 / 0.82) 0%, rgb(18 18 17 / 0.45) 55%, rgb(18 18 17 / 0.15) 100%);
}

.photo-band .overlay {
    position: absolute;
    inset: 0;
    z-index: 1;
    display: flex;
    align-items: center;
    padding: 1.5rem 1.25rem;
}

.photo-band .overlay > * { max-width: 26rem; }

/* Wariant: tekst po PRAWEJ.
   Potrzebny, gdy na zdjęciu postać stoi po lewej — domyślny układ kładł jej napis
   na twarzy. Przyciemnienie musi się odwrócić razem z tekstem, bo inaczej napis
   ląduje na najjaśniejszej części kadru i przestaje być czytelny. */
.photo-band.prawo::after {
    background: linear-gradient(to left, rgb(18 18 17 / 0.82) 0%, rgb(18 18 17 / 0.45) 55%, rgb(18 18 17 / 0.15) 100%);
}

.photo-band.prawo .overlay { justify-content: flex-end; }

/* Karta wpisu na zdjęciu — zawsze jasna, bo leży na przyciemnionej fotografii */
.photo-band .event {
    background: rgb(247 244 239 / 0.96);
    color: #1C1B19;
    margin: 0;
    backdrop-filter: blur(2px);
}

.photo-band .event .time { color: #8A5A00; }
.photo-band .event .body { color: #5D5A53; }

@media (max-width: 44rem) {
    .photo-band img { height: 420px; }
    .photo-band::after {
        background: linear-gradient(to bottom, rgb(18 18 17 / 0.35) 0%, rgb(18 18 17 / 0.85) 60%);
    }
    .photo-band .overlay { align-items: flex-end; }
}

/* --- Poziomy pas scen ------------------------------------------------------
   Sytuacje, w których apka ma sens, ustawione w rząd zamiast jedna pod drugą.
   Czytelnik przewija je w bok — palcem, gładzikiem albo po prostu przewijając stronę,
   bo cały pas dryfuje poziomo wzdłuż pionowego przewijania.

   Baza jest odporna: zwykły `overflow-x` z przyciąganiem. Dryf jest DODATKIEM
   pod @supports — jak przeglądarka go nie zna, pas nadal się przewija ręcznie. */
/* --- Siatka scen (bento) --------------------------------------------------
   Zastąpiła przewijanie poziome. Powód nie jest estetyczny: pas wymagał albo
   ukrytego gestu (Shift + kółko), albo przypięcia sekcji na kilka ekranów, czyli
   odebrania czytelnikowi kontroli nad przewijaniem. Siatka pokazuje wszystko naraz,
   czyta się z góry na dół i nie wymaga tłumaczenia, jak jej używać.

   Kafle mają różne szerokości, żeby oko miało rytm — siedem identycznych
   prostokątów wygląda jak tabela, a nie jak opowieść. */
.scenes {
    display: grid;
    grid-template-columns: repeat(6, 1fr);
    gap: 1.15rem;
    margin: 2.5rem 0 3.5rem;
}

.scenes .scene { grid-column: span 2; }
.scenes .scene:nth-child(1),
.scenes .scene:nth-child(2) { grid-column: span 3; }

/* Kafel domykający: szeroki, ale NISKI. Przy proporcji 4/5 i sześciu kolumnach
   robił się z niego kwadrat wysoki na półtora ekranu — pusta bursztynowa plama
   pod jednym zdaniem. Szeroka i płaska ramka mieści cytat i nic więcej. */
.scenes .scene:last-child { grid-column: span 6; }
.scenes .scene:last-child .frame { aspect-ratio: 16 / 4.5; }

@media (max-width: 60rem) {
    .scenes { grid-template-columns: repeat(2, 1fr); }
    .scenes .scene { grid-column: span 1; }
    .scenes .scene:last-child { grid-column: span 2; }
    .scenes .scene:last-child .frame { aspect-ratio: 16 / 7; }
}

@media (max-width: 34rem) {
    .scenes { grid-template-columns: 1fr; }
    .scenes .scene { grid-column: span 1 !important; }
}

/* Sekcja szersza niż kolumna tekstu — inaczej kafle są za ciasne.

   `100vw` liczy się razem z paskiem przewijania, więc samo z siebie dawałoby stronie
   przewijanie w poziomie. Chroni przed tym 2,5rem odjętego marginesu: jest szerszy
   niż każdy pasek przewijania, jaki spotkasz. `--vw` zostaje jako punkt zaczepienia,
   gdyby kiedyś trzeba było podać dokładną szerokość widoczną ze skryptu — dziś nikt
   go nie ustawia i działa wartość zapasowa. */
.wide {
    width: min(calc(var(--vw, 100vw) - 2.5rem), 68rem);
    margin-inline: auto;
    position: relative;
    left: 50%;
    transform: translateX(-50%);
}

.scene .day {
    display: block;
    font-size: 0.74rem;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    font-weight: 700;
    color: var(--accent);
    margin-bottom: 0.45rem;
}

.scene {
    flex: 0 0 clamp(240px, 70vw, 320px);
    scroll-snap-align: center;
}

.scene .frame {
    position: relative;
    overflow: hidden;
    border-radius: var(--radius);
    border: 1px solid var(--outline-soft);
    aspect-ratio: 4 / 5;
}

.scene img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.scene h3 {
    margin: 1rem 0 0.3rem;
    font-size: 1.05rem;
    letter-spacing: -0.01em;
}

.scene p { margin: 0; color: var(--muted); font-size: 0.94rem; }

/* Karta bez zdjęcia — domyka pas cytatem zamiast kolejnej fotografii z banku */
.scene .frame-quote {
    display: grid;
    place-items: center;
    padding: 2rem;
    background: linear-gradient(150deg, var(--accent-bg), var(--card-alt));
    border-color: var(--accent);
}

.scene .frame-quote p {
    margin: 0;
    font-size: 1.35rem;
    line-height: 1.4;
    font-style: italic;
    color: var(--accent-on-bg);
    text-align: center;
}

/* Bursztynowa godzina jak w kalendarzu — spina scenę z resztą strony */
.scene .hour {
    position: absolute;
    left: 0.75rem;
    bottom: 0.75rem;
    background: rgb(247 244 239 / 0.94);
    color: #8A5A00;
    font-size: 0.8rem;
    font-weight: 700;
    padding: 0.15rem 0.6rem;
    border-radius: 999px;
}

@supports (animation-timeline: view()) {
    @media (prefers-reduced-motion: no-preference) and (min-width: 52rem) {
        .rail-track {
            animation: dryf linear both;
            animation-timeline: view();
            animation-range: cover 0% cover 100%;
        }
    }
}

/* Start od zera, nie od wartości dodatniej: przesunięcie w prawo odsłoniłoby pustkę
   przy lewej krawędzi pasa, zanim użytkownik zdąży cokolwiek przewinąć. */
@keyframes dryf {
    from { transform: translateX(0); }
    to   { transform: translateX(-7%); }
}

/* Zdjęcie towarzyszące akapitowi */
.figure-wide {
    margin: 2.5rem 0;
}

.figure-wide img {
    display: block;
    width: 100%;
    height: auto;
    border-radius: var(--radius);
    border: 1px solid var(--outline-soft);
}

.figure-wide figcaption {
    margin-top: 0.6rem;
    font-size: 0.85rem;
    color: var(--muted);
}

/* --- Callo --- */

/* Callo jest grafitowy (#2B2A27), a ciemne tło strony to #121211 — bez podkładki
   maskotka rozpływa się w tle i zostają same bursztynowe oczy. Jasna płytka pod spodem
   działa w obu motywach i wygląda na zamierzoną, a nie na łatę. */
.callo-plate {
    background: var(--callo-plate);
    border-radius: 24px;
    flex: none;
    display: grid;
    place-items: center;
}

/* Komentarz Callo pod krokiem: wypełnia pustkę obok wysokiego zrzutu i daje maskotce
   rolę, zamiast stawiać ją jako ozdobę. */
.callo-note {
    display: flex;
    align-items: center;
    gap: 1rem;
    margin-top: 1.75rem;
    padding-top: 1.5rem;
    border-top: 1px solid var(--outline-soft);
}

.callo-note .callo-plate { width: 84px; height: 84px; padding: 8px; }

/* Dotąd po kwestii Callo szedł zawsze `<h2>` albo koniec kontenera, więc `.callo-note`
   nie potrzebowała dolnego marginesu. Gdy następuje akapit, tekst startuje tuż przy
   płytce. Regułę wiążemy z sąsiedztwem, a nie z samą `.callo-note` — inaczej odstęp
   wskoczyłby też do kart kroków, gdzie kwestia jest ostatnim elementem i o odstęp
   dba już padding karty. */
.callo-note + p { margin-top: 1.6rem; }
.callo-note img { width: 100%; height: auto; display: block; }

.callo-note p {
    margin: 0;
    font-size: 0.97rem;
    color: var(--text);
    font-style: italic;
}

/* W nagłówku strony Callo stoi duży i też potrzebuje płytki */
.hero .callo-plate {
    width: 10.5rem;
    height: 10.5rem;
    padding: 0.9rem;
    margin: 0 auto;
    border-radius: 36px;
}

.hero .callo-plate svg { width: 100%; height: auto; }

@media (max-width: 44rem) {
    .callo-note { margin-top: 1.25rem; padding-top: 1.25rem; }
    .callo-note .callo-plate { width: 68px; height: 68px; }
}

/* Sekcja pełnej szerokości — wyróżnia „dlaczego to bezpieczne" z reszty strony */
.band {
    background: var(--surface);
    border-top: 1px solid var(--outline-soft);
    border-bottom: 1px solid var(--outline-soft);
    margin: 4rem -1.25rem;
    padding: 3rem 1.25rem;
}

.band > * { max-width: var(--maxw); margin-left: auto; margin-right: auto; }
.band h2:first-child { margin-top: 0; }

/* --- Stopka --- */

footer.site {
    border-top: 1px solid var(--outline-soft);
    margin-top: 4rem;
    padding-top: 1.5rem;
    color: var(--muted);
    font-size: 0.87rem;
}

footer.site a { color: var(--muted); }

/* Dane firmy w stopce. Tylko wersja PL — i tylko na stronach marketingowych:
   regulamin i polityka prywatności mają je w treści, w sekcji o usługodawcy,
   więc w stopce byłyby drugi raz na tej samej stronie.
   `address` domyślnie leci kursywą, stąd jawny `font-style`. */
/* Ikony społecznościowe w stopce. Obrys bierze `currentColor`, więc kolor idzie
   za motywem i za `:hover` bez osobnego kompletu reguł dla trybu ciemnego.
   Pole dotyku ma 34 px mimo 19-pikselowej ikony — palec na telefonie nie trafia
   w 19 px, a WCAG 2.5.8 chce minimum 24. */
.stopka-social {
    display: flex;
    gap: 0.4rem;
    margin: 0.75rem 0 0;
}
footer.site .stopka-social a {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    margin-left: -7px;      /* pole dotyku wystaje poza ikonę; kasujemy, żeby
                               pierwsza ikona stała w linii z tekstem wyżej */
    color: var(--muted);
    transition: color 0.15s;
}
footer.site .stopka-social a:hover,
footer.site .stopka-social a:focus-visible { color: var(--accent); }
.stopka-social svg {
    width: 19px;
    height: 19px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.9;
    stroke-linecap: round;
    stroke-linejoin: round;
}

footer.site .firma {
    font-style: normal;
    margin-top: 1rem;
    line-height: 1.6;
}

/* --- Cennik ------------------------------------------------------------------
   Dwie karty obok siebie dopiero od 44rem. Niżej idą jedna pod drugą, bo cena
   złożona z kwoty i okresu łamie się na wąskim ekranie w najgorszym możliwym
   miejscu — między liczbą a „/ miesiąc". */
.plans { display: grid; gap: 1rem; margin: 2rem 0; }

@media (min-width: 44rem) {
    .plans { grid-template-columns: 1fr 1fr; }
}

.plan {
    background-color: var(--card);
    background-image: var(--glass-bg);
    border: 1px solid var(--glass-border);
    border-radius: var(--radius);
    box-shadow: var(--glass-inset), var(--shadow);
    padding: 1.5rem;
}

/* Płatny plan wyróżniony obramowaniem, NIE wypełnieniem akcentem. Bursztyn ma
   w obu motywach przeciwną jasność, więc karta zalana kolorem wymagałaby osobnego
   koloru tekstu na motyw — obramowanie działa tak samo w jasnym i ciemnym. */
.plan.highlight { border-color: var(--accent); }

.plan h3 { margin: 0 0 0.2rem; font-size: 1.05rem; color: var(--accent); }

.plan .price { font-size: 1.9rem; font-weight: 700; line-height: 1.15; margin: 0.3rem 0 0.15rem; }

.plan .price small { font-size: 0.95rem; font-weight: 400; color: var(--muted); }

.plan .note { margin: 0 0 1rem; color: var(--muted); font-size: 0.9rem; }

.plan ul { margin: 0; padding-left: 1.15rem; }

.plan li { margin: 0.42rem 0; font-size: 0.95rem; }
