/* KickShield — jeden arkusz, zero toolchainu JS/CSS (D8). */

:root {
    --bg: #0f1115;
    --bg-raised: #171a21;
    --bg-card: #1c2029;
    --border: #2a2f3a;
    --text: #e6e6e6;
    --text-muted: #9aa3b2;
    --accent: #d4a017;
    --accent-hover: #e8b62e;
    --accent-contrast: #14161b;
    --danger: #e5484d;
    --ok: #46a758;
    --radius: 10px;
    --font: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
    --mono: ui-monospace, "Cascadia Mono", Consolas, monospace;
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
    margin: 0;
    background: var(--bg);
    color: var(--text);
    font-family: var(--font);
    line-height: 1.6;
}

.site { min-height: 100dvh; display: flex; flex-direction: column; }
.site-main { flex: 1; }
.container { max-width: 1040px; margin: 0 auto; padding: 0 1.25rem; }

h1, h2, h3 { line-height: 1.2; }
a { color: var(--accent); text-decoration: none; }
a:hover { color: var(--accent-hover); }
.muted { color: var(--text-muted); }
.error { color: var(--danger); }
/* Potwierdzenie musi mieć swój kolor tak samo jak błąd. Bez tej reguły
   „wypłata zlecona" wyglądała jak zwykły akapit, a czerwone było wyłącznie to,
   co poszło źle — czyli sygnał dostawał tylko ten, komu się nie udało. */
.success { color: var(--ok); }

/* Nagłówek */
.site-header {
    border-bottom: 1px solid var(--border);
    background: rgba(15, 17, 21, 0.92);
    position: sticky; top: 0; z-index: 10;
    backdrop-filter: blur(8px);
}
.nav-row { display: flex; align-items: center; justify-content: space-between; height: 60px; }
.brand { font-size: 1.25rem; font-weight: 700; color: var(--text); letter-spacing: -0.02em; }
.brand span { color: var(--accent); }
.nav-links { display: flex; align-items: center; gap: 1.25rem; }
.nav-links > a { color: var(--text-muted); font-weight: 500; }
.nav-links > a:hover { color: var(--text); }

/* Przełącznik menu istnieje wyłącznie na telefonie. Na desktopie `display:
   none`, a nie samo schowanie wzrokowe — schowane pole zostaje w kolejności
   Tab i klawiatura zatrzymywałaby się na sterowniku, którego nie ma. */
.nav-toggle, .nav-burger { display: none; }

/* Stopka */
.site-footer { border-top: 1px solid var(--border); padding: 1.5rem 0; margin-top: 4rem; }
.footer-row { display: flex; justify-content: space-between; flex-wrap: wrap; gap: 0.75rem; font-size: 0.9rem; }
.footer-links { display: flex; flex-wrap: wrap; gap: 1.25rem; }
.footer-links a { color: var(--text-muted); }

/* Przyciski */
.btn {
    display: inline-block;
    padding: 0.55rem 1.3rem;
    border-radius: var(--radius);
    border: 1px solid transparent;
    font: inherit; font-weight: 600;
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s, color 0.15s;
}
.btn-primary { background: var(--accent); color: var(--accent-contrast); }
.btn-primary:hover { background: var(--accent-hover); color: var(--accent-contrast); }
.btn-outline { border-color: var(--border); color: var(--text); background: transparent; }
.btn-outline:hover { border-color: var(--accent); color: var(--accent); }
.btn-danger { background: transparent; border-color: var(--border); color: var(--danger); }
.btn-danger:hover { border-color: var(--danger); }
.btn.disabled, .btn[aria-disabled="true"] { pointer-events: none; opacity: 0.45; }
.btn-lg { padding: 0.8rem 2rem; font-size: 1.05rem; }

/* Hero */
.hero { text-align: center; padding: 5rem 0 3.5rem; }
.hero h1 { font-size: clamp(2rem, 5vw, 3.2rem); margin: 0 0 1rem; }
.hero h1 em { color: var(--accent); font-style: normal; }
.hero p.lead { font-size: 1.15rem; color: var(--text-muted); max-width: 640px; margin: 0 auto 2rem; }
.hero-actions { display: flex; gap: 1rem; justify-content: center; flex-wrap: wrap; }

/* Sekcje */
.section { padding: 3.5rem 0; }
.section h2 { font-size: 1.8rem; margin: 0 0 0.5rem; text-align: center; }
.section > .container > p.sub { text-align: center; color: var(--text-muted); margin: 0 0 2.5rem; }

/* Zestawienie "bez / z" na wejściu — pierwsza rzecz, którą widzi kupujący.
   Poprzednia wersja była dwoma szarymi blokami tekstu z wynikiem zakopanym
   w akapicie, a strona "przed" jedynie przygaszona, co czytało się jak
   WYŁĄCZONE, nie jak ZŁE. Teraz niesie to trójka: kolor semantyczny, rysunek
   i wynik podany największą czcionką w sekcji. */
.split { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 1.5rem; max-width: 900px; margin: 0 auto; }
.split-card {
    position: relative; padding: 1.75rem;
    border: 1px solid var(--border); border-radius: 14px;
    background: var(--bg-card);
}
/* Delikatna poświata od góry zamiast płaskiego tła — karta "po" ma wyglądać
   na tę właściwą, zanim ktoś przeczyta nagłówek. */
.split-card.bad {
    border-color: rgba(229, 72, 77, 0.32);
    background: linear-gradient(180deg, rgba(229, 72, 77, 0.07), transparent 55%), var(--bg-card);
}
.split-card.good {
    border-color: rgba(212, 160, 23, 0.5);
    background: linear-gradient(180deg, rgba(212, 160, 23, 0.09), transparent 55%), var(--bg-card);
    box-shadow: 0 20px 45px -28px rgba(212, 160, 23, 0.55);
}
.split-tag {
    margin: 0; font-size: 0.75rem; font-weight: 700;
    letter-spacing: 0.09em; text-transform: uppercase;
    display: flex; align-items: center; gap: 0.5rem;
}
.split-tag::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.split-card.bad .split-tag { color: var(--danger); }
.split-card.good .split-tag { color: var(--accent); }
.split-art { display: block; width: 100%; height: auto; margin: 1.35rem auto 1.5rem; }
/* Impuls biegnący złotą trasą. Statyczna linia mówi "jest droga", ruchoma —
   "ruch NIĄ IDZIE", a to jest właśnie ta różnica, którą sprzedajemy.
   Krótka kreska na bardzo długiej przerwie, więc widać jeden przebiegający
   błysk, a nie migającą linię. */
.split-flow { stroke-dasharray: 16 420; animation: split-flow 1.9s linear infinite; }
@keyframes split-flow { from { stroke-dashoffset: 436; } to { stroke-dashoffset: 0; } }

/* Delikatne uniesienie pod kursorem — karta reaguje, więc wygląda na żywą,
   a nie na obrazek. */
.split-card { transition: transform 0.18s ease, box-shadow 0.18s ease; }
.split-card.good:hover { transform: translateY(-3px); box-shadow: 0 26px 55px -26px rgba(212, 160, 23, 0.6); }
/* Wynik jest tu najważniejszy i ma być największy — to jedyne zdanie, które
   ktoś przelatujący stronę naprawdę przeczyta. */
.split-outcome {
    margin: 0 0 0.4rem; line-height: 1.1; font-weight: 800;
    font-size: clamp(1.45rem, 2.6vw, 1.95rem); letter-spacing: -0.02em;
}
.split-card.bad .split-outcome { color: #ef8b8e; }
.split-card.good .split-outcome { color: var(--text); }
.split-detail { margin: 0; color: var(--text-muted); font-size: 0.95rem; }
/* Sekcja jest ciągiem dalszym hero, nie osobnym rozdziałem — nie zaczyna się
   nagłówkiem, więc pełny odstęp od góry rozjeżdżałby ją z leadem. */
.section.pitch { padding-top: 0.5rem; }
.pitch-actions { margin-top: 2.5rem; }

/* Karty cech */
.features { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 1.25rem; }
/* Ikona i nagłówek stoją w JEDNYM RZĘDZIE, opis pod nimi w kolumnie nagłówka.
   Wcześniej ikona siedziała nad tekstem, przez co nagłówek — po skróceniu
   opisów do jednego zdania — gubił się między nią a akapitem. Nagłówek jest
   tu treścią („Nie dotykamy klienta Tibii", „To nie jest VPN"), więc ma stać
   tam, gdzie wzrok pada najpierw. Ten sam układ dostały kroki niżej. */
.feature {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 1.5rem;
    display: grid;
    grid-template-columns: 40px 1fr;
    column-gap: 0.85rem;
    row-gap: 0.6rem;
    /* Wiersze przy GÓRZE karty, nadmiar wysokości zostaje na dole. Bez tego
       `align-content` ma wartość `stretch`, a karty w siatce są rozciągane do
       równej wysokości — więc każda rozdzielała swój nadmiar między dwa wiersze
       i robiła to INACZEJ, zależnie od długości tytułu. Sąsiadujące ikony
       stawały wtedy na różnej wysokości (zmierzone: 25 px i 31 px), a akapity
       pod nimi wyglądały na wyśrodkowane w pionie bez powodu.
       Wyrównanie do GÓRY, nie do środka, i to też jest przemyślane: przy
       `center` tytuł zawinięty do dwóch linii robi wyższy wiersz i spycha
       ikonę w dół, więc sąsiednie kafelki znów rozjeżdżają się o kilka pikseli
       (zmierzone na portugalskim: 9 px). Ikona ma stać w tym samym miejscu
       zawsze — pilnuje tego `start`, a wyśrodkowanie tytułu WZGLĘDEM ikony
       robi `min-height` na samym nagłówku niżej. */
    align-content: start;
    align-items: start;
}
/* Wysokość ikony jako minimum nagłówka: krótki tytuł centruje się w tym pudełku
   naprzeciw ikony, a długi rośnie w dół od jej górnej krawędzi. Ikona nie
   drgnie w żadnym z tych przypadków. */
.feature h3 {
    margin: 0; font-size: 1.05rem;
    min-height: 40px; display: grid; align-items: center;
}
/* Druga kolumna wskazana wprost: bez tego akapit trafiłby pod ikonę, czyli
   w pierwszą kolumnę drugiego rzędu, i miałby czterdzieści pikseli szerokości. */
.feature p { grid-column: 2; margin: 0; color: var(--text-muted); font-size: 0.95rem; }
/* Kafelki dostają ten sam język wizualny co blok otwierający — akcentowana
   ikona i reakcja na kursor. Bez tego sekcja wyglądała przy nim jak surowy
   tekst wrzucony w ramkę. */
.feature-icon {
    display: grid; place-items: center;
    width: 40px; height: 40px;
    border-radius: 11px; color: var(--accent);
    background: rgba(212, 160, 23, 0.1);
    border: 1px solid rgba(212, 160, 23, 0.26);
}
.feature-icon svg { width: 21px; height: 21px; }
.feature { transition: border-color 0.18s ease, transform 0.18s ease; }
.feature:hover { border-color: rgba(212, 160, 23, 0.45); transform: translateY(-2px); }

/* Kroki */
.steps { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 1.25rem; counter-reset: step; }
/* Oddech pod nagłówkiem sekcji. `.section h2` ma tylko 0,5 rem marginesu, bo
   zwykle podpiera go akapit `.sub` z własnym odstępem — tutaj takiego akapitu
   nie ma i kafelki zaczynały się tuż pod tytułem. Wskazane sąsiedztwem, żeby
   nie ruszać odstępu tam, gdzie `.sub` jednak stoi (cennik). */
.section h2 + .steps { margin-top: 1.5rem; }
/* Numer OBOK nagłówka, w jednym rzędzie — ten sam układ co karty cech niżej;
   obie sekcje mają się czytać jak jeden system, a nie dwa pomysły na kafelek.
   Numer stał kiedyś w lewym marginesie i wtedy nagłówek zaczynał się cztery
   centymetry od krawędzi kafelka; siatka rozwiązuje to inaczej niż tamten
   margines, bo opis wraca pod nagłówek, a nie owija się wokół numeru. */
.step {
    padding: 1.5rem;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    display: grid;
    grid-template-columns: 40px 1fr;
    column-gap: 0.85rem;
    row-gap: 0.6rem;
    /* To samo co przy kartach cech: bez `start` numery 1, 2, 3 stały na trzech
       różnych wysokościach, bo każdy kafelek inaczej rozdzielał nadmiar — a przy
       `align-items: center` dokładał się do tego tytuł zawinięty do dwóch linii. */
    align-content: start;
    align-items: start;
}
.step::before {
    counter-increment: step; content: counter(step);
    display: grid; place-items: center;
    width: 40px; height: 40px;
    border-radius: 11px; font-weight: 700;
    color: var(--accent);
    background: rgba(212, 160, 23, 0.1);
    border: 1px solid rgba(212, 160, 23, 0.26);
}
.step h3 {
    margin: 0; font-size: 1rem;
    min-height: 40px; display: grid; align-items: center;
}
.step p { grid-column: 2; margin: 0; color: var(--text-muted); font-size: 0.92rem; }

/* Poradnik: te same kroki, ale ustawione w JEDNEJ kolumnie. Trzy kafelki obok
   siebie czyta się jak menu do wyboru, a lead mówi wprost, żeby iść po kolei —
   pionowa lista trzyma kolejność 1–4 w jednej osi wzroku i nie rozjeżdża się,
   gdy tłumaczenie wydłuża pytanie do dwóch linii.
   Odnośnikiem jest CAŁA karta, nie samo pytanie, więc dostaje kolor zwykłego
   tekstu i tę samą reakcję na kursor co kafelki cech; akcent zostaje na pytaniu. */
.steps.path { grid-template-columns: 1fr; gap: 1rem; }
.steps.path .step {
    color: var(--text);
    transition: border-color 0.18s ease, transform 0.18s ease;
}
.steps.path .step h3 { color: var(--accent); font-size: 1.05rem; }
.steps.path .step:hover { border-color: rgba(212, 160, 23, 0.45); transform: translateY(-2px); }
.steps.path .step:hover h3 { color: var(--accent-hover); }

/* Przycisk stał tuż pod ostatnią kartą — `.prose p` nie ma marginesu górnego,
   więc odnośnik do cennika wyglądał jak piąty element listy. */
.steps.path + p { margin-top: 2rem; }

/* Cennik */
.pricing { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 1.5rem; max-width: 720px; margin: 0 auto; }
.price-card {
    background: var(--bg-card); border: 1px solid var(--border);
    border-radius: var(--radius); padding: 2rem; text-align: center;
    display: flex; flex-direction: column; gap: 0.4rem;
}
.price-card.premium { border-color: var(--accent); }
.price-card .plan-name { font-size: 1.1rem; font-weight: 700; }
.price-card .price { font-size: 2.4rem; font-weight: 700; }
.price-card .price small { font-size: 1rem; color: var(--text-muted); font-weight: 400; }
.price-card ul { list-style: none; padding: 0; margin: 0.75rem 0 1.25rem; color: var(--text-muted); font-size: 0.95rem; text-align: left; }
.price-card li { padding: 0.3rem 0 0.3rem 1.5rem; position: relative; }
.price-card li::before { content: "✓"; position: absolute; left: 0; color: var(--ok); }
.price-card .btn { margin-top: auto; }
.badge { display: inline-block; background: var(--accent); color: var(--accent-contrast); border-radius: 999px; font-size: 0.75rem; font-weight: 700; padding: 0.1rem 0.7rem; margin: 0 auto 0.4rem; }

/* FAQ */
.faq { max-width: 720px; margin: 0 auto; display: flex; flex-direction: column; gap: 0.75rem; }
.faq details { background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius); padding: 0 1.25rem; }
.faq summary { cursor: pointer; font-weight: 600; padding: 1rem 0; list-style: none; }
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: "+"; float: right; color: var(--accent); font-size: 1.2rem; }
.faq details[open] summary::after { content: "–"; }
.faq details p { margin: 0 0 1rem; color: var(--text-muted); }

/* Karty auth / formularze */
.auth-card, .narrow-card {
    max-width: 460px; margin: 4rem auto; padding: 2rem;
    background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius);
}
.narrow-card.wide { max-width: 640px; }
.auth-card h1, .narrow-card h1 { margin-top: 0; font-size: 1.5rem; }

/* Wybieramy przez WYKLUCZENIE, a nie przez `input[type="text"]`. Powód jest
   konkretny: komponent <InputText> Blazora renderuje `<input>` BEZ atrybutu
   `type`. Przeglądarka traktuje takie pole jak tekstowe i `element.type` zwraca
   "text", ale selektor atrybutowy go nie dopasowuje — więc każde pole tekstowe
   w serwisie chodziło na domyślnych stylach przeglądarki (21 px wysokości,
   1 px wypełnienia) i bez dolnego marginesu, przez co przycisk przyklejał się
   do pola. Wykluczenie łapie też pola bez atrybutu. */
/* Wykluczenie w :where(), a nie gołe :not(). Powód jest mierzalny: :not()
   przejmuje specyficzność swojego argumentu, więc trzy selektory atrybutowe
   dawały regule wagę (0,3,1) i wygrywała ona z późniejszym `table.data td input`
   (0,1,3) — pole w komórce tabeli zostawało rozciągnięte na 100%, podczas gdy
   `select` z tej samej reguły dawał się nadpisać, bo tam selektorem jest goły
   element. :where() ma specyficzność zerową, więc nadpisania działają. */
input:where(:not([type="checkbox"], [type="radio"], [type="hidden"])),
textarea, select {
    width: 100%; padding: 0.6rem 0.8rem; margin: 0.35rem 0 0.9rem;
    background: var(--bg-raised); color: var(--text);
    border: 1px solid var(--border); border-radius: var(--radius);
    font: inherit;
}
input:focus, textarea:focus { outline: 2px solid var(--accent); outline-offset: -1px; }
.account-input { font-family: var(--mono); letter-spacing: 0.06em; }
label { font-weight: 500; }

.radio-row { display: flex; gap: 0.6rem; align-items: baseline; padding: 0.45rem 0; }
.radio-row input { width: auto; margin: 0; }

/* Wybór regionu wyłączności na stronie płatności. Odsłania się CZYSTYM CSS-em
   po zaznaczeniu premium — ta strona jest renderowana statycznie, a włączanie
   interaktywności Blazora nad całym ekranem płatności tylko po to, żeby pokazać
   trzy przyciski, byłoby obwodem nad kasą (ta sama decyzja co przy menu D8).
   Wiersz planu musi się zawijać, bo bez tego blok wpadłby obok etykiety jako
   kolejny element elastyczny i ścisnąłby ją do jednej litery. */
.radio-row-expands { flex-wrap: wrap; }
.region-choice { display: none; flex-basis: 100%; margin: 0.4rem 0 0 1.6rem; }
#pay-premium:checked ~ .region-choice { display: block; }
.region-choice .radio-row { padding: 0.25rem 0; }
.region-choice p { margin: 0.35rem 0; }

/* Numer konta — ekran zapisu */
.number-box {
    font-family: var(--mono); font-size: 1.25rem; letter-spacing: 0.08em;
    background: var(--bg-raised); border: 1px dashed var(--accent);
    border-radius: var(--radius); padding: 1.1rem; text-align: center;
    margin: 1.25rem 0; user-select: all; overflow-wrap: anywhere;
}
/* Kod QR zawsze na bieli, także w ciemnym motywie: czytniki potrzebują
   kontrastu, a odwrócony kod część telefonów odczytuje gorzej albo wcale.
   Szerokość ograniczona, bo sam SVG skaluje się w nieskończoność. */
.qr-box {
    background: #fff; border-radius: var(--radius); padding: 0.75rem;
    margin: 1.25rem 0; width: fit-content; max-width: 100%; line-height: 0;
}
.qr-box svg { width: 200px; height: 200px; display: block; }

.warning-box {
    background: rgba(229, 72, 77, 0.08); border: 1px solid var(--danger);
    border-radius: var(--radius); padding: 0.9rem 1.1rem; font-size: 0.95rem;
}
.action-row { display: flex; gap: 0.75rem; flex-wrap: wrap; margin: 1.25rem 0; }
.check-row { display: flex; gap: 0.6rem; align-items: flex-start; margin: 1rem 0; }
.check-row input { width: auto; margin-top: 0.3rem; }

/* Panel */
.panel-grid { display: grid; gap: 1.5rem; margin: 2.5rem 0; }
.panel-card { background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--radius); padding: 1.5rem; }
.panel-card h2 { margin: 0 0 1rem; font-size: 1.2rem; }
/* Zmiana planu. Ramka w kolorze akcentu, bo to jedyne miejsce w panelu,
   ktore o cos prosi - reszta karty tylko informuje. */
.upgrade-box { margin-top: 1.25rem; padding: 1rem; border: 1px solid var(--accent); border-radius: var(--radius); }
.upgrade-box h3 { margin: 0 0 .5rem; font-size: 1.05rem; }
.upgrade-box label { display: block; margin: .75rem 0 .25rem; }
.upgrade-box select { width: 100%; max-width: 22rem; margin-bottom: .75rem; }
.panel-header { display: flex; justify-content: space-between; align-items: center; margin-top: 2.5rem; flex-wrap: wrap; gap: 1rem; }
.panel-header h1 { margin: 0; }

/* Liczba, dla której istnieje cała karta: saldo partnera i liczniki panelu
   administratora. Bez reguły szły wielkością zwykłego akapitu, czyli tak samo
   jak podpis pod nimi. */
.big-number { font-size: 2rem; font-weight: 700; line-height: 1.2; margin: 0 0 0.35rem; }

table.data { width: 100%; border-collapse: collapse; font-size: 0.95rem; }
table.data th { text-align: left; color: var(--text-muted); font-weight: 500; padding: 0.5rem 0.75rem; border-bottom: 1px solid var(--border); }
table.data td { padding: 0.6rem 0.75rem; border-bottom: 1px solid var(--border); }
table.data tr:last-child td { border-bottom: none; }
/* Kontrolki w wierszu tabeli. Pełna szerokość rozpycha kolumnę do szerokości
   całej karty, a dolny margines rozjeżdża wiersz — oba biorą się z reguły dla
   pól formularza, która jest słuszna w formularzu i szkodliwa w komórce. */
table.data td input, table.data td select { width: auto; margin: 0; }
table.data td .rate-input { width: 5.5rem; }

/* Panel administratora: zlecenie wypłaty jako blok, nie wiersz tabeli —
   niesie dane do przelewu, które w komórce byłyby nieczytelne. */
.payout-row { border: 1px solid var(--border); border-radius: var(--radius); padding: 1rem; margin-bottom: 1rem; }
.payout-row p { margin: 0 0 0.4rem; }
.node-health { background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius); font-family: var(--mono); padding: 0.75rem; font-size: 0.85rem; white-space: pre-wrap; overflow-x: auto; margin: 0 0 1rem; }

.status-pill { display: inline-block; padding: 0.15rem 0.7rem; border-radius: 999px; font-size: 0.85rem; font-weight: 600; }
.status-pill.ok { background: rgba(70, 167, 88, 0.15); color: var(--ok); }
.status-pill.bad { background: rgba(229, 72, 77, 0.15); color: var(--danger); }

/* Strony tekstowe */
/* Padding boczny jest tu obowiązkowy: Security.razor używa .prose BEZ
   .container, więc bez tego na telefonie tekst dotykał krawędzi ekranu. */
.prose { max-width: 720px; margin: 2.5rem auto; padding: 0 1.25rem; }
.prose h1 { font-size: 1.8rem; }
.prose h2 { font-size: 1.2rem; margin-top: 2rem; }
/* Regulamin i polityka prywatności to teraz długie dokumenty — bez oddechu
   między akapitami czyta się je jak ścianę. */
.prose p { margin: 0 0 1rem; }
.prose li { margin-bottom: 0.4rem; }

/* Walidacja Blazora */
.validation-message { color: var(--danger); font-size: 0.9rem; }
h1:focus { outline: none; }

/* Błąd Blazora */
#blazor-error-ui {
    background: var(--danger); color: #fff; bottom: 0; left: 0; right: 0;
    display: none; padding: 0.6rem 1.25rem; position: fixed; z-index: 1000;
}
#blazor-error-ui .reload { color: #fff; text-decoration: underline; }
#blazor-error-ui .dismiss { cursor: pointer; float: right; }

/* Przełącznik języka wyglądał dokładnie jak pozycja menu, więc czytał się jak
   kolejna podstrona. Obramowana pigułka mówi „to jest przełącznik". */
.lang-switch {
    border: 1px solid var(--border); border-radius: 999px;
    padding: 0.15rem 0.7rem; font-size: 0.9rem;
}
.lang-switch:hover { border-color: var(--accent); }

/* Widoczny fokus klawiatury. Domyślny pierścień przeglądarki gubi się na
   ciemnym tle, a bez niego nawigacja Tabem jest ślepa. :focus-visible, nie
   :focus — inaczej obwódka zapala się też po kliknięciu myszą. */
:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
    border-radius: 4px;
}

@media (max-width: 640px) {
    /* Pozycji jest sześć i w jeden wiersz nie wejdą: same szerokości pięciu
       pierwszych zapełniają 375 px bez reszty, więc ani ciaśniejsze odstępy,
       ani skrócenie przełącznika języka do „EN" nic nie dawały — sprawdzone
       pomiarem, nie na oko. Rozłożone na dwa wiersze rosły do 133 px, czyli
       piątej części ekranu telefonu, i to był powód, dla którego nagłówek
       przestawał tu być przyklejony. Zwinięte pod przycisk mieszczą się
       w jednym wierszu bez wyrzucania którejkolwiek pozycji, więc PRZYKLEJONY
       nagłówek wraca — reguła `position: static` zniknęła stąd razem ze swoim
       powodem. */
    .nav-row { height: auto; min-height: 60px; flex-wrap: wrap; }
    /* Widoczne tylko dla klawiatury i czytnika: samo pole ma być niewidzialne
       (klika się w kreski obok), ale musi zostać w kolejności Tab, żeby menu
       dało się otworzyć spacją. Stąd 1 px + clip zamiast `display: none`. */
    .nav-toggle {
        display: block; position: absolute;
        width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%);
    }
    .nav-burger {
        display: flex; align-items: center; justify-content: center;
        cursor: pointer; color: var(--text-muted);
        /* 44 px to najmniejsze pole, w które trafia się kciukiem bez celowania
           (wytyczne dostępności dotykowej). Sama ikona ma 24 px. */
        width: 44px; height: 44px; margin-right: -0.5rem;
    }
    .nav-burger:hover { color: var(--text); }
    .nav-toggle:focus-visible ~ .nav-burger {
        outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px;
    }
    /* Rozwinięte menu to lista POD paskiem, nie drugi wiersz paska: kciukiem
       trafia się w cały wiersz, a nie w same litery. */
    .nav-links {
        display: none;
        width: 100%; flex-direction: column; align-items: stretch; gap: 0;
        margin-top: 0.5rem; padding-bottom: 0.5rem;
        border-top: 1px solid var(--border);
    }
    .nav-toggle:checked ~ .nav-links { display: flex; }
    .nav-links > a:not(.btn):not(.lang-switch) { padding: 0.7rem 0.25rem; }
    /* Pigułki zostają pigułkami — rozciągnięte na całą szerokość udawałyby
       pola formularza. */
    .nav-links > .btn, .nav-links > .lang-switch { align-self: flex-start; margin-top: 0.5rem; }
    .hero { padding: 3rem 0 2.5rem; }
    /* Tabela urządzeń i płatności nie mieści się na telefonie — niech przewija
       się sama, zamiast rozpychać całą stronę w poziomie. */
    .panel-card { overflow-x: auto; }
}

/* Płynne przewijanie i animacje potrafią wywołać mdłości u osób wrażliwych na
   ruch, a system o tym wie. */
@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    * { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; }
}

/* Pola płatnika przy automatycznym odnawianiu. Odsunięte i obramowane, żeby
   było widać, że należą do zaznaczonej opcji, a nie do formularza w ogóle. */
.recurring-fields {
    margin: 0.25rem 0 1rem 1.6rem; padding: 0.9rem 1.1rem;
    border-left: 2px solid var(--border); border-radius: 0 var(--radius) var(--radius) 0;
    background: var(--bg-raised);
}
.recurring-fields p.muted { margin: 0 0 0.75rem; font-size: 0.9rem; }
