/* =====================================================================
   theme-login.css — ekrany logowania SSO (login_sso_v, forgot_password_v,
   reset_password_v; blocked_v ładuje ten plik, ale nadpisuje tło i kolor body).

   UKŁAD (WCAG 1.4.10 Reflow, 2.4.11/2.4.12 Focus Not Obscured)
   - body: kolumna flex o wysokości min. 100dvh (fallback 100vh), BEZ height:100%
     i BEZ centrowania align-items/justify-content — przy karcie wyższej niż okno
     centrowanie flex ucinało GÓRĘ karty (logo, nagłówek) poza zasięgiem przewijania.
   - Karta (.login-card, element <main>) ma margin:auto — auto-marginesy centrują
     ją w wolnym miejscu, a gdy miejsca brak, spadają do 0 (nic nie jest ucinane).
   - Stopka (footer.site-footer) jest w PRZEPŁYWIE dokumentu, na końcu strony,
     a nie position:fixed — wcześniej na telefonie (~250 px wysokości) zasłaniała
     przycisk „Zaloguj się” i wersję systemu.

   MOTYWY (spójne z przełącznikiem w całym systemie PANS — pracownik, sylabus,
   student, plan_zajec): atrybut data-theme na <html> = light | dark | hc,
   ustawiany przed arkuszami przez sso/partials/theme_head_v.php z cookie
   ui-theme (brak cookie → prefers-color-scheme). :root = motyw JASNY (domyślny,
   gdy skrypt nie ustawi data-theme); bez JS i przy ciemnym systemie działa
   rezerwa @media (prefers-color-scheme: dark). Każdy kolor zależny od motywu
   idzie przez tokeny (custom properties) — reguły nie mają literałów kolorów.
   blocked_v ładuje ten arkusz, ale nie ma data-theme ani .login-card — ma
   własny jasny styl (rezerwa bez JS jest dlatego ograniczona do :has(.login-card)).

   KONTRAST (WCAG 1.4.6 AAA ≥ 7:1 dla tekstu, 1.4.11 / 2.4.13 ≥ 3:1 dla obrysów
   i wskaźników fokusu). Liczone wzorem luminancji WCAG 2.x z mieszaniem alfa
   w sRGB, w OBU końcach gradientu tła (wartości „jasny koniec / ciemny koniec”).

   CIEMNY (data-theme="dark") — tło #0f4f70 / #1b355f:
     biały tekst na tle strony ....................................  8,85 / 12,20
     karta = ciemne szkło rgba(0,0,0,.18) → #0c415c / #162b4e:
       biały tekst ................................................ 10,90 / 14,10
       tekst pomocniczy rgba(255,255,255,.85) (--text-soft) .......  8,33 / 10,55
     pole formularza rgba(0,0,0,.25) nad kartą → #093145 / #10203a:
       biały tekst ................................................ 13,66 / 16,28
       placeholder rgba(255,255,255,.85) .......................... 10,25 / 12,06
       obrys pola rgba(255,255,255,.7) vs karta ...................  6,21 /  7,63
     stopka rgba(0,0,0,.35) nad tłem, biały tekst ................. 13,27 / 15,86
     wskaźnik fokusu: obrys 3 px #fff z odsunięciem, vs karta ..... 10,90 / 14,10
     przycisk „Zaloguj się”: tekst #1b355f na #fff 12,20; hover #dbe7f3 9,72;
       active #c3d5e8 8,14; białe tło przycisku vs karta .......... 10,90 / 14,10
     zieleń „spełnione” #b6e3c9 na karcie (reset hasła) ...........  7,69 /  9,95
     przełącznik motywu: tło jak karta, biały tekst 10,90 / 14,10; obrys
       rgba(255,255,255,.7) nad szkłem segmentu rgba(0,0,0,.18) (tło segmentu
       sięga pod obrys: background-clip border-box) vs tło strony 5,04 / 6,61;
       aktywny = tło #fff, tekst #1b355f 12,20
     tor miernika siły hasła (reset) #e9ecef jak dotąd (Bootstrap w data-bs-theme
       dark dałby #343a40 — 1,06 / 1,23 wobec karty); pasek dekoracyjny
     przycisk Google: #3c4043 na #fff 10,47 (hover #202124 na #f8f9fa 15,27)

   JASNY (:root, data-theme="light") — tło #e8f0f7 / #d3dfeb:
     tekst #12283f na tle strony .................................. 13,02 / 11,08
     karta rgba(255,255,255,.85) → #fcfdfe / #f8fafc:
       tekst #12283f .............................................. 14,72 / 14,33
       tekst pomocniczy #33475c ...................................  9,39 /  9,14
       link i tekst przycisku Google #1b355f ...................... 11,98 / 11,66
     pole: tło #fff, tekst #12283f 14,99; placeholder #44566a 7,54;
       obrys 1 px #5b7590 vs karta ................................  4,69 /  4,57
     przycisk „Zaloguj się”: tekst #fff na #1b355f 12,20; hover #142a4d 14,30;
       active #0f2340 15,73; tło przycisku vs karta ............... 11,98 / 11,66
     wskaźnik fokusu 3 px #0f2f4a vs karta ........................ 13,51 / 13,15
     stopka rgba(0,0,0,.06) → #dae2e8 / #c6d2dd, tekst #12283f .... 11,44 /  9,75
     zieleń „spełnione” #0f5132 na karcie .........................  9,19 /  8,95
     przełącznik: tło jak karta, tekst #12283f 14,72 / 14,33; obrys #5b7590
       vs tło strony 4,15 / 3,53; aktywny = tło #1b355f, tekst #fff 12,20
     przycisk Google: tło #fff, tekst #1b355f 12,20, obrys #5b7590 vs karta
       4,69 / 4,57 (Material #dadce0 miałby 1,3:1)
     tor miernika siły hasła #dde5ec z obrysem 1 px #5b7590 vs karta 4,69 / 4,57
       (pasek aria-hidden, siłę podaje tekst — dekoracyjny)
     linie „lub” rgba(18,40,63,.3) i obrys karty/plakietki logo — dekoracyjne

   WYSOKI KONTRAST (data-theme="hc") — tło #000, bez gradientu, bez półprzezroczystości:
     tekst #fff 21,00; pomocniczy #e6e6e6 16,83; link #66f0ff 15,47 (podkreślony)
     pole: tło #000, obrys 2 px #fff 21,00, placeholder #e6e6e6 16,83
     przycisk główny: tekst #000 na #00e5ff 13,65; hover #66f0ff 15,47;
       active #00c4db 9,92; tło vs karta #000 ≥ 9,92
     wskaźnik fokusu 3 px #00e5ff vs #000 ......................... 13,65
     przycisk Google: #202124 na #fff 16,10, obrys 2 px #fff
     zieleń „spełnione” #7dffb5 .................................... 16,84
     tor miernika siły hasła #000 z obrysem 1 px #fff 21,00

   WSPÓLNE: komunikaty z tłem NIEPRZEZROCZYSTYM (biały tekst) — niezależne od
     motywu: błąd #842029 9,46; ostrzeżenie #664d03 7,99; sukces #0f5132 9,36;
     informacja #055160 8,93; prace częściowe #0b4a6f 9,45. Obrys: ciemny motyw
     rgba(255,255,255,.5), jasny — tło komunikatu przyciemnione rgba(0,0,0,.25)
     (bez białej ramki na jasnej karcie), hc — 2 px #fff.
   Poprzedni motyw (#2185b0 → #2a5298, jasne szkło 10% bieli) dawał 4,16:1 na tle,
   3,56:1 na karcie i 2,68:1 w polach — nie spełniał nawet AA.

   RUCH: animacje wyłącznie w prefers-reduced-motion: no-preference; stan
   początkowy (opacity:0) jest w tym samym bloku, więc przy ograniczonym ruchu
   treść jest widoczna od razu.
   ===================================================================== */

@media (prefers-reduced-motion: no-preference) {
    .toast.toast-animated {
        opacity: 0;
        transform: translateY(20px);
        animation: toast-slide-in 0.6s ease forwards;
    }
    @keyframes toast-slide-in {
        to { opacity: 1; transform: translateY(0); }
    }

    /* Karta logowania: pojawienie się + lekkie podniesienie */
    .login-card {
        opacity: 0;
        transform: translateY(12px);
        animation: cardFadeIn .9s ease forwards;
        animation-delay: .15s; /* chwilę przed stopką (ta ma .3s) */
    }
    @keyframes cardFadeIn {
        to { opacity: 1; transform: translateY(0); }
    }

    /* Stopka: łagodne pojawienie się (dotąd animacja działała także przy
       ograniczonym ruchu, bo była poza tym blokiem) */
    footer.site-footer {
        opacity: 0;
        animation: footerFadeIn 1.2s ease forwards;
        animation-delay: .3s;
    }
    @keyframes footerFadeIn {
        to { opacity: 1; }
    }
}

/* ---------------------------------------------------------------------
   TOKENY MOTYWÓW
   --------------------------------------------------------------------- */

/* JASNY — domyślny (także gdy skrypt anty-FOUC nie ustawi data-theme) */
:root {
    color-scheme: light;
    --page-bg-from: #e8f0f7;
    --page-bg-to: #d3dfeb;
    --text: #12283f;                           /* 14,7 / 14,3 na karcie */
    --text-soft: #33475c;                      /* 9,4 / 9,1 */
    --link: #1b355f;                           /* 12,0 / 11,7 */
    --glass-bg: rgba(255, 255, 255, 0.85);     /* karta → #fcfdfe / #f8fafc */
    --glass-border: rgba(18, 40, 63, 0.18);    /* krawędź dekoracyjna karty */
    --card-border-width: 1px;
    --card-blur: blur(12px);
    --card-shadow: 0 8px 32px rgba(18, 40, 63, 0.12);
    --input-bg: #fff;
    --input-bg-focus: #fff;
    --input-fg: #12283f;                       /* 15,0 */
    --input-placeholder: #44566a;              /* 7,5 */
    --input-border: #5b7590;                   /* 4,7 / 4,6 vs karta (1.4.11) */
    --input-border-width: 1px;
    --input-border-focus: #0f2f4a;
    --focus-ring: #0f2f4a;                     /* 13,5 / 13,2 vs karta (2.4.13) */
    --btn-primary-bg: #1b355f;
    --btn-primary-fg: #fff;                    /* 12,2 */
    --btn-primary-hover-bg: #142a4d;
    --btn-primary-active-bg: #0f2340;
    --btn-disabled-fg: #12283f;
    --btn-disabled-border: rgba(18, 40, 63, 0.6);
    --ok-soft: #0f5132;                        /* 9,2 / 9,0 */
    --footer-bg: rgba(0, 0, 0, 0.06);          /* → #dae2e8 / #c6d2dd */
    --footer-fg: #12283f;                      /* 11,4 / 9,8 */
    --footer-border: 1px solid rgba(18, 40, 63, 0.2);
    --footer-blur: blur(8px);
    --divider-line: rgba(18, 40, 63, 0.3);     /* linie „lub” — dekoracyjne */
    --logo-bg: #fff;
    --logo-ring: rgba(18, 40, 63, 0.18);       /* obrys plakietki — dekoracyjny */
    --notice-border: 1px solid rgba(0, 0, 0, 0.25); /* tło komunikatu przyciemnione */
    --google-bg: #fff;
    --google-fg: #1b355f;                      /* 12,2 */
    --google-border: 1px solid #5b7590;        /* 4,7 / 4,6 vs karta */
    --google-hover-bg: #eef3f8;
    --google-hover-fg: #12283f;
    --switch-border: 1px solid #5b7590;        /* 4,2 / 3,5 vs tło strony */
    --switch-hover-border: #5b7590;
    --meter-track: #dde5ec;                    /* tor miernika siły hasła (reset) */
    --meter-border: 1px solid #5b7590;         /* 4,7 / 4,6 vs karta */
    --target-min: 44px;                        /* 2.5.5 Target Size (AAA) */
}

/* CIEMNY — wartości sprzed wprowadzenia motywów (wygląd bez zmian) */
html[data-theme="dark"] {
    color-scheme: dark;
    --page-bg-from: #0f4f70;
    --page-bg-to: #1b355f;
    --text: #fff;
    --text-soft: rgba(255, 255, 255, 0.85);    /* ≥ 8,3:1 na karcie */
    --link: #fff;
    --glass-bg: rgba(0, 0, 0, 0.18);           /* ciemne szkło karty */
    --glass-border: rgba(255, 255, 255, 0.3);  /* krawędź dekoracyjna karty */
    --card-border-width: 1px;
    --card-blur: blur(12px);
    --card-shadow: 0 8px 32px rgba(0, 0, 0, 0.25);
    --input-bg: rgba(0, 0, 0, 0.25);
    --input-bg-focus: rgba(0, 0, 0, 0.35);
    --input-fg: #fff;
    --input-placeholder: rgba(255, 255, 255, 0.85);
    --input-border: rgba(255, 255, 255, 0.7);  /* ≥ 6,2:1 vs karta (1.4.11) */
    --input-border-width: 1px;
    --input-border-focus: #fff;
    --focus-ring: #fff;                        /* ≥ 10,9:1 vs karta (2.4.13) */
    --btn-primary-bg: #fff;
    --btn-primary-fg: #1b355f;
    --btn-primary-hover-bg: #dbe7f3;
    --btn-primary-active-bg: #c3d5e8;
    --btn-disabled-fg: #fff;
    --btn-disabled-border: rgba(255, 255, 255, 0.6);
    --ok-soft: #b6e3c9;
    --footer-bg: rgba(0, 0, 0, 0.35);
    --footer-fg: #fff;
    --footer-border: 1px solid rgba(255, 255, 255, 0.2);
    --footer-blur: blur(8px);
    --divider-line: rgba(255, 255, 255, 0.25);
    --logo-bg: #fff;
    --logo-ring: transparent;
    --notice-border: 1px solid rgba(255, 255, 255, 0.5);
    --google-bg: #fff;
    --google-fg: #3c4043;                      /* 10,5 */
    --google-border: 1px solid #dadce0;        /* białe tło vs karta ≥ 10,9 */
    --google-hover-bg: #f8f9fa;
    --google-hover-fg: #202124;
    --switch-border: 1px solid rgba(255, 255, 255, 0.7);
    --switch-hover-border: rgba(255, 255, 255, 0.7);
    --meter-track: #e9ecef;                    /* jak przed motywami (Bootstrap light) */
    --meter-border: 0 none;
}

/* WYSOKI KONTRAST — czarne tło, biel i cyjan, zero półprzezroczystości */
html[data-theme="hc"] {
    color-scheme: dark;
    --page-bg-from: #000;
    --page-bg-to: #000;                        /* gradient z dwóch #000 = jednolite tło */
    --text: #fff;
    --text-soft: #e6e6e6;                      /* 16,8 */
    --link: #66f0ff;                           /* 15,5 */
    --glass-bg: #000;
    --glass-border: #fff;
    --card-border-width: 2px;
    --card-blur: none;
    --card-shadow: none;
    --input-bg: #000;
    --input-bg-focus: #000;
    --input-fg: #fff;
    --input-placeholder: #e6e6e6;
    --input-border: #fff;
    --input-border-width: 2px;
    --input-border-focus: #00e5ff;
    --focus-ring: #00e5ff;                     /* 13,6 vs #000 */
    --btn-primary-bg: #00e5ff;
    --btn-primary-fg: #000;                    /* 13,6 */
    --btn-primary-hover-bg: #66f0ff;
    --btn-primary-active-bg: #00c4db;
    --btn-disabled-fg: #fff;
    --btn-disabled-border: #fff;
    --ok-soft: #7dffb5;                        /* 16,8 */
    --footer-bg: #000;
    --footer-fg: #fff;
    --footer-border: 2px solid #fff;
    --footer-blur: none;
    --divider-line: #fff;
    --logo-bg: #fff;
    --logo-ring: #fff;
    --notice-border: 2px solid #fff;
    --google-bg: #fff;
    --google-fg: #202124;                      /* 16,1 */
    --google-border: 2px solid #fff;
    --google-hover-bg: #fff;
    --google-hover-fg: #000;
    --switch-border: 2px solid #fff;
    --switch-hover-border: #fff;
    --meter-track: #000;
    --meter-border: 1px solid #fff;            /* 21,0 */
}

/* Rezerwa bez JavaScriptu: data-theme nie jest ustawione, system ciemny →
   tokeny ciemne. Ograniczone do stron z kartą logowania (blocked_v ma własny
   jasny styl i ma zostać jasny). */
@media (prefers-color-scheme: dark) {
    html:not([data-theme]):has(.login-card) {
        color-scheme: dark;
        --page-bg-from: #0f4f70;
        --page-bg-to: #1b355f;
        --text: #fff;
        --text-soft: rgba(255, 255, 255, 0.85);
        --link: #fff;
        --glass-bg: rgba(0, 0, 0, 0.18);
        --glass-border: rgba(255, 255, 255, 0.3);
        --card-shadow: 0 8px 32px rgba(0, 0, 0, 0.25);
        --input-bg: rgba(0, 0, 0, 0.25);
        --input-bg-focus: rgba(0, 0, 0, 0.35);
        --input-fg: #fff;
        --input-placeholder: rgba(255, 255, 255, 0.85);
        --input-border: rgba(255, 255, 255, 0.7);
        --input-border-focus: #fff;
        --focus-ring: #fff;
        --btn-primary-bg: #fff;
        --btn-primary-fg: #1b355f;
        --btn-primary-hover-bg: #dbe7f3;
        --btn-primary-active-bg: #c3d5e8;
        --btn-disabled-fg: #fff;
        --btn-disabled-border: rgba(255, 255, 255, 0.6);
        --ok-soft: #b6e3c9;
        --footer-bg: rgba(0, 0, 0, 0.35);
        --footer-fg: #fff;
        --footer-border: 1px solid rgba(255, 255, 255, 0.2);
        --divider-line: rgba(255, 255, 255, 0.25);
        --logo-ring: transparent;
        --notice-border: 1px solid rgba(255, 255, 255, 0.5);
        --google-fg: #3c4043;
        --google-border: 1px solid #dadce0;
        --google-hover-bg: #f8f9fa;
        --google-hover-fg: #202124;
        --switch-border: 1px solid rgba(255, 255, 255, 0.7);
        --switch-hover-border: rgba(255, 255, 255, 0.7);
        --meter-track: #e9ecef;
        --meter-border: 0 none;
    }
}

/* ---------------------------------------------------------------------
   UKŁAD I KOMPONENTY
   --------------------------------------------------------------------- */

body {
    background-color: var(--page-bg-to);
    background-image: linear-gradient(to right, var(--page-bg-from), var(--page-bg-to));
    font-family: 'Inter', sans-serif;
    margin: 0;
    color: var(--text);
    min-height: 100vh;
    min-height: 100dvh;
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
    padding-top: 1.5rem;
}

/* Pasek z przełącznikiem motywu — pierwszy element body, w PRZEPŁYWIE (nie
   fixed: nie zasłania treści przy powiększeniu ani na telefonie — 2.4.11),
   wyrównany do prawej. */
.login-topbar {
    flex-shrink: 0;
    display: flex;
    justify-content: flex-end;
    padding: 0 1rem;
}
/* Pasek ma w znacznikach atrybut hidden, zdejmowany dopiero przez skrypt
   przełącznika — bez JS (albo gdy skrypt się nie wykona) nie ma martwych
   przycisków z fałszywym stanem aria-pressed (4.1.2). display:flex wyżej
   nadpisałby domyślne [hidden] przeglądarki, stąd jawna reguła. */
.login-topbar[hidden] { display: none; }

/* Przełącznik motywu (segment, radio-like przez aria-pressed). Tło jak karta,
   obrys ≥ 3:1 wobec tła strony (1.4.11). Przy braku miejsca przyciski się
   zawijają zamiast wystawać (1.4.10). */
.login-theme {
    display: inline-flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    /* .5rem = 8 px: pierścień fokusu sięga 5 px poza przycisk (3 px + odsunięcie
       2 px), więc zostaje ≥ 3 px szczeliny do sąsiada — przy .25rem pierścień
       wchodził 1 px na wybrany przycisk i w hc zlewał się z jego tłem (1:1). */
    gap: .5rem;
    max-width: 100%;
    padding: .2rem;
    background: var(--glass-bg);
    backdrop-filter: var(--card-blur);
    -webkit-backdrop-filter: var(--card-blur);
    border: var(--switch-border);
    border-radius: .85rem;
}
.login-theme__btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .4rem;
    min-height: var(--target-min);             /* 2.5.5 (AAA) */
    min-width: var(--target-min);
    padding: 0 .7rem;
    margin: 0;
    border: 2px solid transparent;
    border-radius: .65rem;
    background: transparent;
    color: var(--text);
    font: inherit;
    font-size: .875rem;
    line-height: 1.2;
    white-space: nowrap;
    cursor: pointer;
}
.login-theme__btn:hover { border-color: var(--switch-hover-border); }
/* Stan wybrany — nie tylko kolorem: wypełnione tło (kształt), pogrubienie
   i znacznik ✓ za etykietą; kontrast tekstu jak w przycisku głównym. */
.login-theme__btn[aria-pressed="true"] {
    background: var(--btn-primary-bg);
    border-color: var(--btn-primary-bg);
    color: var(--btn-primary-fg);
    font-weight: 600;
}
.login-theme__btn[aria-pressed="true"]::after {
    content: "\2713";                          /* ✓ — znacznik wyboru, dekoracyjny */
    content: "\2713" / "";                     /* pusty tekst alternatywny: bez „znacznik” w nazwie dostępnej */
    font-weight: 600;
    margin-left: -.1rem;
}
.login-theme__btn:focus-visible {
    outline: 3px solid var(--focus-ring);
    outline-offset: 2px;
}

.login-card {
    display: block;
    /* auto-marginesy: bezpieczne centrowanie bez ucinania góry karty */
    margin: auto;
    width: min(400px, calc(100% - 2rem));
    color: var(--text);
    background: var(--glass-bg);
    backdrop-filter: var(--card-blur);
    -webkit-backdrop-filter: var(--card-blur);
    border: var(--card-border-width) solid var(--glass-border);
    border-radius: 1.5rem;
    padding: 2.5rem 2rem;
    box-shadow: var(--card-shadow);
}

/* Wąskie ekrany (i powiększenie 200–400%): mniejsze marginesy, żeby treść
   (w tym widżet Turnstile) miała jak najwięcej miejsca */
@media (max-width: 400px) {
    .login-card {
        width: calc(100% - 1rem);
        padding: 2rem 1rem;
        border-radius: 1rem;
    }
    .login-topbar { padding: 0 .5rem; }
    .login-theme__btn { padding: 0 .5rem; gap: .3rem; }
}

/* Logo PANS jest granatowe (#22346c) na przezroczystym tle — na ciemnym motywie
   byłoby niewidoczne, dlatego stoi na białej plakietce (11,83:1). Obrys plakietki
   (jasny i hc) rysuje box-shadow — bez wpływu na wymiary obrazka. */
.logo {
    display: block;
    width: 100%;
    max-width: 340px;
    height: auto;
    margin: 0 auto 1.5rem;
    padding: .6rem .8rem;
    background: var(--logo-bg);
    box-shadow: 0 0 0 1px var(--logo-ring);
    border-radius: .75rem;
    box-sizing: border-box;
}

.login-title {
    color: var(--text);
    font-weight: 600;
}

.login-lead { color: var(--text-soft); }

.form-label { color: var(--text); font-weight: 600; }

/* Pole: color-scheme dziedziczone z <html> (light / dark / dark) — natywne
   elementy rysowane przez przeglądarkę (podgląd hasła w Edge, ikona klucza
   w Safari, tło autouzupełniania w Chromium) biorą paletę zgodną z tłem pola;
   niezgodna dawała ciemne glify na ciemnym polu (~1,4:1, 1.4.11). */
.form-control {
    min-height: var(--target-min);
    background-color: var(--input-bg);
    border: var(--input-border-width) solid var(--input-border);
    color: var(--input-fg);
}
.form-control::placeholder { color: var(--input-placeholder); opacity: 1; }
.form-control:focus {
    background-color: var(--input-bg-focus);
    border-color: var(--input-border-focus);
    color: var(--input-fg);
    box-shadow: none;
    outline: 3px solid var(--focus-ring);
    outline-offset: 2px;
}

/* Przycisk główny: pełne tło — wyraźnie rozpoznawalny (tło vs karta ≥ 9,9:1).
   Kolory przez zmienne Bootstrapa, bo reguły .btn:hover / :active / :focus-visible
   mają wyższą specyficzność niż sama klasa. Stan wyłączony: przezroczysty
   z obrysem — wyraźnie inny niż aktywny. */
.btn.login-btn {
    --bs-btn-color: var(--btn-primary-fg);
    --bs-btn-bg: var(--btn-primary-bg);
    --bs-btn-border-color: var(--btn-primary-bg);
    --bs-btn-hover-color: var(--btn-primary-fg);
    --bs-btn-hover-bg: var(--btn-primary-hover-bg);
    --bs-btn-hover-border-color: var(--btn-primary-hover-bg);
    --bs-btn-active-color: var(--btn-primary-fg);
    --bs-btn-active-bg: var(--btn-primary-active-bg);
    --bs-btn-active-border-color: var(--btn-primary-active-bg);
    --bs-btn-disabled-color: var(--btn-disabled-fg);
    --bs-btn-disabled-bg: transparent;
    --bs-btn-disabled-border-color: var(--btn-disabled-border);
    --bs-btn-focus-box-shadow: none;
    min-height: var(--target-min);
    font-weight: 600;
    transition: background-color .15s ease, border-color .15s ease;
}

/* Wskaźnik fokusu klawiatury: 3 px, odsunięty, ≥ 3:1 vs tło karty (2.4.7, 2.4.13) */
.login-card a:focus-visible,
.login-card button:focus-visible,
.btn.login-btn:focus-visible,
.site-footer a:focus-visible {
    outline: 3px solid var(--focus-ring);
    outline-offset: 3px;
    box-shadow: none;
}

/* Link tekstowy jako cel dotykowy ≥ 44 px wysokości (2.5.5 AAA) */
.login-link {
    display: inline-flex;
    align-items: center;
    min-height: var(--target-min);
    padding: 0 .25rem;
    color: var(--link);
    text-decoration: underline;
    text-underline-offset: .2em;
    border-radius: .25rem;
}
.login-link:hover { color: var(--link); text-decoration-thickness: 2px; }

/* Widżet Cloudflare Turnstile: „safe center” — gdy widżet jest szerszy niż
   kontener, nadmiar idzie w prawo (da się go przewinąć), a nie za lewą krawędź.
   Pierwsza deklaracja to rezerwa dla przeglądarek bez słowa „safe”. */
.login-turnstile {
    display: flex;
    justify-content: center;
    justify-content: safe center;
}

.version-text {
    font-size: .85rem;
    color: var(--text-soft);
    margin-top: .75rem;
}

/* Komunikat po przekierowaniu (flash) — w karcie, nad formularzem, z tłem
   nieprzezroczystym (kontrast policzalny niezależnie od tła strony i motywu) */
.login-flash {
    display: flex;
    gap: .6rem;
    align-items: flex-start;
    text-align: left;
    color: #fff;
    border: var(--notice-border);
    border-radius: .75rem;
    padding: .8rem 1rem;
    margin-bottom: 1.25rem;
    font-size: .95rem;
    line-height: 1.5;
}
.login-flash > i { margin-top: .2rem; flex-shrink: 0; }
.login-flash:focus { outline: 3px solid var(--focus-ring); outline-offset: 3px; }
.login-flash--error   { background: #842029; }
.login-flash--warning { background: #664d03; }
.login-flash--success { background: #0f5132; }
.login-flash--info    { background: #055160; }

/* Kolory pomocnicze Bootstrapa na karcie: .text-white-50 dawałby 3,97:1 na
   ciemnej karcie (a na jasnej byłby niewidoczny), .text-success (#198754)
   2,41:1 — podmiana na tokeny ≥ 7:1 (reset hasła). */
.login-card .text-white-50 { color: var(--text-soft) !important; }

/* Tor miernika siły hasła (reset_password_v): Bootstrap bierze go z
   --bs-secondary-bg, który przy data-bs-theme="dark" (motywy ciemny i hc) ma
   #343a40 — tor znikał na ciemnej karcie (1,06:1). Kolor z tokenu motywu. */
.login-card .progress {
    --bs-progress-bg: var(--meter-track);
    border: var(--meter-border);
}
.login-card .text-success { color: var(--ok-soft) !important; }

/* Stopka w przepływie dokumentu, na końcu strony */
footer.site-footer {
    flex-shrink: 0;
    width: 100%;
    background: var(--footer-bg);
    backdrop-filter: var(--footer-blur);
    -webkit-backdrop-filter: var(--footer-blur);
    border-top: var(--footer-border);
    text-align: center;
    padding: 1rem;
}

.footer-inner {
    max-width: 900px;
    margin: 0 auto;
}

.footer-ue-logo {
    display: inline-block;
    max-width: 100%;    /* obraz 851×117 — bez tego wystawał poza ekran 375 px */
    max-height: 52px;
    width: auto;
    height: auto;
    border-radius: .25rem;
    filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.3));
}

.footer-text {
    font-size: .9rem;
    line-height: 1.5;
    color: var(--footer-fg);
}

.site-footer a {
    color: var(--footer-fg);
    text-decoration: underline;
}

@media (max-width: 576px) {
    .footer-text { font-size: .85rem; }
}
