﻿/* ══ Farebná téma používateľa ══════════════════════════════════════════════
   `--brand` je JEDINÁ farba, ktorú si používateľ vyberá (Nastavenia → Aplikácia).
   Hodnota sa vykresľuje priamo do `style` atribútu elementu <html> v App.razor,
   takže prepíše hodnotu deklarovanú nižšie a platí už pri prvom vykreslení.

   Všetky ostatné odtiene témy sa z nej odvodia cez `color-mix()` — nie je čo
   držať v synchronizácii na strane C#.

   DÔLEŽITÉ: sémantické farby (--success, --danger, --warning, --income,
   --outcome, --savings, --backup, --invest a farby rozpočtov) sa z `--brand`
   ZÁMERNE neodvodzujú. Nesú význam a musia zostať rovnaké pre každú tému. */

/* ── Dark theme (default) ──
   Selektory sú zámerne ukotvené na `:root` (element <html>): FluentDesignTheme
   pridáva `data-theme` aj na <body>, a neukotvený selektor by tak premenné
   deklaroval priamo na <body> — vlastná deklarácia má prednosť pred dedením,
   čím by prekryla farbu používateľa zo `style` atribútu na <html>. */
:root,
:root[data-theme="dark"] {
    --brand: #3fb950;
    --bg-body: #07080b;
    --bg-surface: #0d0f14;
    --bg-card: #111318;
    --bg-sidebar: linear-gradient(180deg, color-mix(in srgb, var(--brand) 9%, #0b0d12) 0%, color-mix(in srgb, var(--brand) 3%, #07080b) 100%);
    --bg-header: #0d0f14;
    --border-color: #1c1e26;
    --border-subtle: #252830;
    --text-primary: #e8eaf2;
    --text-secondary: #a3a8c0;
    --text-muted: #7d8298;
    --accent: var(--brand);
    --accent-hover: color-mix(in oklab, var(--brand) 76%, #ffffff);
    --accent-subtle: color-mix(in srgb, var(--brand) 15%, transparent);
    /* Dekoratívne vrstvy (aurora, mriežka bodiek, žiara sidebaru). */
    --brand-glow: color-mix(in srgb, var(--brand) 22%, transparent);
    --brand-veil: color-mix(in srgb, var(--brand) 7%, transparent);
    --brand-line: color-mix(in srgb, var(--brand) 30%, transparent);
    /* Celková sila dekoratívneho pozadia; jednotlivé dizajny ju už neriešia. */
    --backdrop-intensity: 1;
    --success: #3fb950;
    --success-subtle: rgba(63,185,80,.15);
    --warning: #f5a623;
    --warning-subtle: rgba(245,166,35,.13);
    --danger: #f75353;
    --danger-subtle: rgba(247,83,83,.13);
    --info: #4d9fff;
    --info-subtle: rgba(77,159,255,.12);
    --purple: #c084fc;
    --purple-subtle: rgba(192,132,252,.12);
    --teal: #22d3ee;
    --teal-subtle: rgba(34,211,238,.12);
    --pink: #f472b6;
    --pink-subtle: rgba(244,114,182,.12);
    --nav-active-bg: color-mix(in srgb, var(--brand) 12%, transparent);
    --nav-hover-bg: rgba(255,255,255,.04);
    --sidebar-text: rgba(255,255,255,.78);
    --sidebar-text-muted: rgba(255,255,255,.46);
    --sidebar-border: rgba(255,255,255,.06);
    --sidebar-hover-bg: rgba(255,255,255,.05);
    --shadow-sm: 0 1px 4px rgba(0,0,0,.55);
    --shadow-md: 0 4px 16px rgba(0,0,0,.65);
    --shadow-lg: 0 8px 30px rgba(0,0,0,.75);
    --radius-sm: 6px;
    --radius-md: 10px;
    --radius-lg: 14px;
    /* ── Chart / category palette ── */
    --income:    #58a6ff;
    --outcome:   #bc8cff;
    --savings:   #3fb950;
    --backup:    #f85149;
    --invest:    #39d2c0;
    --remainder: #8b949e;
    color-scheme: dark;
}

/* ── Light theme ── */
:root[data-theme="light"] {
    --brand: #2563eb;
    --bg-body: #f0f2f5;
    --bg-surface: #ffffff;
    --bg-card: #ffffff;
    --bg-sidebar: linear-gradient(180deg, color-mix(in srgb, var(--brand) 5%, #ffffff) 0%, color-mix(in srgb, var(--brand) 8%, #f3f4f6) 100%);
    --bg-header: #ffffff;
    --border-color: #d1d5db;
    --border-subtle: #e5e7eb;
    --text-primary: #111827;
    --text-secondary: #4b5563;
    --text-muted: #6b7280;
    /* Na svetlom podklade sa farba mierne stmaví, aby biely text na tlačidlách
       zostal čitateľný aj pri svetlých voľbách (žltá, tyrkysová). */
    --accent: color-mix(in oklab, var(--brand) 80%, #1a1a1a);
    --accent-hover: var(--brand);
    --accent-subtle: color-mix(in srgb, var(--brand) 10%, transparent);
    --brand-glow: color-mix(in srgb, var(--brand) 16%, transparent);
    --brand-veil: color-mix(in srgb, var(--brand) 5%, transparent);
    --brand-line: color-mix(in srgb, var(--brand) 22%, transparent);
    /* Na svetlom podklade je dekorácia výraznejšia, preto ju stlmíme. */
    --backdrop-intensity: .62;
    --success: #16a34a;
    --success-subtle: rgba(22,163,74,.1);
    --warning: #ca8a04;
    --warning-subtle: rgba(202,138,4,.1);
    --danger: #dc2626;
    --danger-subtle: rgba(220,38,38,.1);
    --info: #2563eb;
    --info-subtle: rgba(37,99,235,.1);
    --purple: #7c3aed;
    --purple-subtle: rgba(124,58,237,.1);
    --teal: #0d9488;
    --teal-subtle: rgba(13,148,136,.1);
    --pink: #db2777;
    --pink-subtle: rgba(219,39,119,.1);
    --nav-active-bg: color-mix(in srgb, var(--brand) 12%, transparent);
    --nav-hover-bg: rgba(0,0,0,.04);
    --sidebar-text: #374151;
    --sidebar-text-muted: rgba(55,65,81,.72);
    --sidebar-border: #e5e7eb;
    --sidebar-hover-bg: rgba(0,0,0,.04);
    --shadow-sm: 0 1px 3px rgba(0,0,0,.08);
    --shadow-md: 0 4px 12px rgba(0,0,0,.1);
    --shadow-lg: 0 8px 24px rgba(0,0,0,.12);
    --radius-sm: 6px;
    --radius-md: 10px;
    --radius-lg: 14px;
    /* ── Chart / category palette ── */
    --income:    #1d6fa8;
    --outcome:   #7c3aed;
    --savings:   #16a34a;
    --backup:    #dc2626;
    --invest:    #0d9488;
    --remainder: #6b7280;
    color-scheme: light;
}

/* ── Veľkosť písma celej aplikácie ──
   Celé UI je rozmerané v `rem`, takže veľkosť koreňového písma škáluje text aj
   odsadenia naraz. Používateľ si ju prepína v Nastavenia → Aplikácia; voľba sa
   prenáša cookie `bm-text-size` na atribút `data-text-size` na elemente <html>. */
html {
    font-size: 18px;
}

html[data-text-size="small"] {
    font-size: 16px;
}

html[data-text-size="medium"] {
    font-size: 18px;
}

html[data-text-size="large"] {
    font-size: 20px;
}

html[data-text-size="xlarge"] {
    font-size: 22px;
}

/* ── Typografická škála ──
   Nový kód používa tieto tokeny namiesto vlastných hodnôt, aby v aplikácii
   nevznikali ďalšie „mikro" veľkosti. Spodná hranica je `--fs-2xs` (.82rem);
   nič menšie sa nepoužíva ani pre odznaky a popisky grafov. */
:root {
    --fs-2xs: .82rem;
    --fs-xs: .88rem;
    --fs-sm: .92rem;
    --fs-md: .97rem;
    --fs-base: 1rem;
    --fs-lg: 1.15rem;
    --fs-xl: 1.35rem;
    --fs-2xl: 1.6rem;
    --fs-3xl: 2rem;
}

/* ── Shared overspent / exhausted budget footer ──
   Pätička sa zobrazuje pod obsahom karty rozpočtu oddelená čiarou.
   Prečerpaný (>100 %) je červený s informáciou o sume; vyčerpaný (=100 %)
   je neutrálny/sivý. */
.budget-over-footer {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 6px 12px;
    border-top: 1px solid rgba(248, 81, 73, .18);
    font-size: .88rem;
    font-weight: 700;
    color: #f85149;
    position: relative;
    z-index: 1;
    pointer-events: none;
}

.budget-over-footer .bi {
    font-size: .97rem;
}

/* ── Emoji ikony rozpočtov a cieľov ──
   Ikona je uložená ako emoji znak, nie ako glyf z fontu. Emoji ignorujú `color`, takže farbu
   rozpočtu nesie okolitý wrapper (pozadie/rámček), nie samotná ikona. Explicitná emoji rodina
   zabráni tomu, aby prehliadač vykreslil monochromatický textový variant. */
.emoji-icon {
    font-family: 'Apple Color Emoji', 'Segoe UI Emoji', 'Noto Color Emoji', sans-serif;
    font-style: normal;
    line-height: 1;
    display: inline-block;
}

/* Vyčerpaný (=100 %, ešte nie prečerpaný) — neutrálny sivý vzhľad. */
.budget-over-footer.is-exhausted {
    color: var(--text-muted);
    border-top-color: rgba(255, 255, 255, .08);
}



html, body {
    font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
    background: var(--bg-body);
    color: var(--text-primary);
    margin: 0;
    transition: background .25s ease, color .25s ease;
}

a, .btn-link {
    color: var(--accent);
}

.btn-primary {
    color: #fff;
    background-color: var(--accent);
    border-color: var(--accent);
}

.btn-primary:hover {
    background-color: var(--accent-hover);
    border-color: var(--accent-hover);
}

.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
    box-shadow: 0 0 0 0.1rem var(--bg-body), 0 0 0 0.25rem var(--accent);
}

.content {
    padding-top: 1.1rem;
}

h1:focus {
    outline: none;
}

.valid.modified:not([type=checkbox]) {
    outline: 1px solid var(--success);
}

.invalid {
    outline: 1px solid var(--danger);
}

.validation-message {
    color: var(--danger);
}

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

    .blazor-error-boundary::after {
        content: "An error has occurred."
    }

.darker-border-checkbox.form-check-input {
    border-color: #929292;
}

.form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder {
    color: var(--bs-secondary-color);
    text-align: end;
}

.form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder {
    text-align: start;
}

/* ══ Dekoratívne pozadie ═══════════════════════════════════════════════════
   Vrstva vo farbe témy pod celým obsahom. Je čisto vizuálna — `pointer-events: none`
   a `aria-hidden`, takže nezasahuje do ovládania ani do čítačiek obrazovky.
   Leží pod obsahom (`z-index: 0`); hlavička, sidebar a obsah stoja nad ňou.

   Dizajn si používateľ vyberá v Nastavenia → Aplikácia; voľba sa prenáša cookie
   `bm-background` na atribút `data-backdrop` elementu <html>. Každý dizajn je len sada
   premenných, ktoré vykreslia vrstvy komponentu AppBackdrop (zdola nahor):

     --backdrop-glow               obrázok vrstvy s mäkkými žiarami
     --backdrop-texture            výplň textúrnej vrstvy (gradient vo farbe témy)
     --backdrop-texture-mask       maska textúry — SVG z images/backdrops (dym, žilky, polygóny…)
     --backdrop-texture-size       veľkosť masky; `cover` roztiahne kompozíciu cez celé okno
     --backdrop-texture-opacity    priehľadnosť textúry
     --backdrop-pattern            obrázok vrstvy so vzorom (mriežka, bodky, pruhy…)
     --backdrop-pattern-size       veľkosť dlaždice vzoru
     --backdrop-pattern-position   posun dlaždice — dvom vrstvám vzoru dá iný raster
     --backdrop-pattern-inset      odsadenie vrstvy so vzorom od okrajov
     --backdrop-pattern-opacity    priehľadnosť vzoru
     --backdrop-pattern-transform  naklonenie vzoru do perspektívy
     --backdrop-pattern-mask       maska, ktorou sa vzor stráca pri okrajoch
     --backdrop-strand-opacity     priehľadnosť zväzku vlákien (0 = nevidno ho)
     --backdrop-particles-opacity  priehľadnosť časticovej vrstvy (kreslí ju tsParticles)
     --backdrop-grain-opacity      sila filmového zrna cez celú plochu
     --backdrop-vignette-opacity   sila vinety, ktorou dekorácia pri okrajoch prejde do pozadia
     --backdrop-glow-anim          animácia vrstvy so žiarou (skratka `animation`, `none` = statická)
     --backdrop-texture-anim       animácia textúrnej vrstvy
     --backdrop-pattern-anim       animácia vrstvy so vzorom
     --backdrop-strand-anim        animácia zväzku vlákien
     --backdrop-grain-anim         animácia zrna (jemné mihotanie, aby plocha nikdy nestála)

   Vrstvy vzoru aj žiary berú ZOZNAM obrázkov — hustotu dizajnu teda netreba riešiť ďalšou
   vrstvou v DOM, stačí pridať gradient a k nemu jeho veľkosť do `--backdrop-pattern-size`.

   Textúry sú samostatné SVG súbory (images/backdrops). Sú to iné dokumenty, takže o farbe
   témy nevedia — preto sa používajú ako MASKA nad výplňou `--backdrop-texture`, ktorá farbu
   dodá. Tvar teda určuje súbor, farbu vždy `--brand`.

   Pohyblivé dizajny stoja na tých istých vrstvách, ale ich pohyb nekreslí CSS — kreslí ho
   časticová vrstva (`js/backdrop-particles.js`, tsParticles). Vrstvy popísané tu im dávajú
   len pokojné pozadie. Animácie nižšie preto ostávajú pre prípad, že by niektorý dizajn
   potreboval rozhýbať aj samotné vrstvy; animuje sa v nich výhradne `transform` a `opacity`
   — obe rieši kompozítor, takže pozadie cez celé okno nestojí ani prekreslenie, ani rozvrhnutie.

   Nový dizajn = jeden blok premenných nižšie + jedna položka v BackgroundSemantics.

   Selektor `[data-backdrop="…"]` je zámerne neukotvený, aby tie isté pravidlá použili aj
   ukážky v nastaveniach, ktoré majú atribút priamo na sebe. Ide o dedené vlastnosti, takže
   ukážka prekryje hodnoty z <html> len vo svojom vnútri — na rozdiel od potomkových
   selektorov, kde by o víťazovi rozhodovalo poradie pravidiel, nie blízkosť elementu. */
.app-backdrop {
    position: absolute;
    overflow: hidden;
    pointer-events: none;
    opacity: var(--backdrop-intensity);
}

/* Pozadie celej stránky. */
.app-backdrop-page {
    position: fixed;
    inset: 0;
    z-index: 0;
    contain: strict;
}

.app-backdrop-glow,
.app-backdrop-texture,
.app-backdrop-grain,
.app-backdrop-strands {
    position: absolute;
    inset: 0;
}

.app-backdrop-glow {
    background-image: var(--backdrop-glow);
    animation: var(--backdrop-glow-anim);
}

.app-backdrop-texture {
    background-image: var(--backdrop-texture);
    opacity: var(--backdrop-texture-opacity);
    animation: var(--backdrop-texture-anim);
    -webkit-mask-image: var(--backdrop-texture-mask);
    mask-image: var(--backdrop-texture-mask);
    -webkit-mask-size: var(--backdrop-texture-size);
    mask-size: var(--backdrop-texture-size);
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    -webkit-mask-position: center;
    mask-position: center;
}

.app-backdrop-pattern {
    position: absolute;
    inset: var(--backdrop-pattern-inset);
    background-image: var(--backdrop-pattern);
    background-size: var(--backdrop-pattern-size);
    background-position: var(--backdrop-pattern-position);
    opacity: var(--backdrop-pattern-opacity);
    transform: var(--backdrop-pattern-transform);
    transform-origin: center top;
    -webkit-mask-image: var(--backdrop-pattern-mask);
    mask-image: var(--backdrop-pattern-mask);
    animation: var(--backdrop-pattern-anim);
}

.app-backdrop-strands {
    width: 100%;
    height: 100%;
    opacity: var(--backdrop-strand-opacity);
    animation: var(--backdrop-strand-anim);
}

/* Časticová vrstva. Element je v komponente prázdny — canvas doň vloží tsParticles zo
   skriptu `js/backdrop-particles.js`. Priehľadnosť je premenná, aby sa dala sila častíc
   doladiť pri dizajne v CSS, bez zásahu do konfigurácie v skripte.

   Rozmer canvasu je POVINNÝ a musí byť v percentách. Knižnica pozoruje samotný canvas a pri
   každej zmene mu prepočíta kresliacu plochu na `offsetWidth × hustota bodov displeja`.
   Bez rozmeru v CSS by `offsetWidth` vychádzal práve z tejto prepočítanej hodnoty, takže by
   sa pri každom kroku znova vynásobila — canvas by rástol do stratena, až kým by prehliadaču
   nedošla pamäť. Percentá to lámu: veľkosť canvasu drží táto vrstva, ktorá je ukotvená
   o okraje rodiča a o obsah sa neopiera. */
.app-backdrop-particles {
    position: absolute;
    inset: 0;
    opacity: var(--backdrop-particles-opacity);
}

.app-backdrop-particles canvas {
    display: block;
    width: 100%;
    height: 100%;
}

/* Filmové zrno cez všetky vrstvy. Dlaždica šumu je len maska, farbu dáva téma —
   preto je zrno vždy zladené s vybranou farbou a nešpiní pozadie do sivej. */
.app-backdrop-grain {
    background-color: var(--brand);
    opacity: var(--backdrop-grain-opacity);
    animation: var(--backdrop-grain-anim);
    -webkit-mask-image: url("images/backdrops/grain.svg");
    mask-image: url("images/backdrops/grain.svg");
    -webkit-mask-size: 200px 200px;
    mask-size: 200px 200px;
}

/* Vineta — dekorácia sa pri okrajoch stráca do farby stránky, takže obsah v strede
   ostane čitateľný a pozadie pôsobí hlbšie. Je nad všetkými vrstvami, preto `::after`. */
.app-backdrop::after {
    content: "";
    position: absolute;
    inset: 0;
    background-image: radial-gradient(125% 95% at 50% 35%, transparent 30%, var(--bg-body) 100%);
    opacity: var(--backdrop-vignette-opacity);
}

/* Používatelia s obmedzením pohybu: vzor zostane plochý, bez perspektívneho naklonenia,
   a žiadna vrstva sa nehýbe — z pohyblivého dizajnu ostane jeho pokojná podoba. */
@media (prefers-reduced-motion: reduce) {
    .app-backdrop-pattern {
        transform: none;
    }

    .app-backdrop-glow,
    .app-backdrop-texture,
    .app-backdrop-pattern,
    .app-backdrop-strands,
    .app-backdrop-grain {
        animation: none;
    }
}

/* Východiskové hodnoty celej sady — jediné miesto, kde sú definované. Bez tohto resetu by
   ukážka v nastaveniach zdedila z <html> tie premenné, ktoré jej vlastný dizajn nedeklaruje
   (napr. naklonenie mriežky z Aurory). Špecifickosť je rovnaká ako pri dizajnoch, takže
   o víťazovi rozhoduje poradie — reset preto musí zostať nad nimi. */
[data-backdrop] {
    --backdrop-glow: none;
    --backdrop-texture: none;
    --backdrop-texture-mask: none;
    --backdrop-texture-size: cover;
    --backdrop-texture-opacity: 1;
    --backdrop-pattern: none;
    --backdrop-pattern-size: auto;
    --backdrop-pattern-position: 0 0;
    --backdrop-pattern-inset: 0;
    --backdrop-pattern-opacity: 1;
    --backdrop-pattern-transform: none;
    --backdrop-pattern-mask: none;
    --backdrop-strand-opacity: 0;
    --backdrop-particles-opacity: 1;
    --backdrop-grain-opacity: 0;
    --backdrop-vignette-opacity: 0;
    --backdrop-glow-anim: none;
    --backdrop-texture-anim: none;
    --backdrop-pattern-anim: none;
    --backdrop-strand-anim: none;
    --backdrop-grain-anim: none;
}

/* ── Pohyb vrstiev ──
   Každá snímka mení len `transform` alebo `opacity`. Vrstvy, ktoré sa posúvajú, sú najprv
   zväčšené (`scale`), aby sa pri posune neodhalil okraj vrstvy — posun je vždy menší ako
   to, o koľko vrstva presahuje okno.

   Animácie s `alternate` sa vracajú tou istou cestou späť, takže nepotrebujú zladiť prvú
   a poslednú snímku. Jediná animácia, ktorá sa naozaj opakuje dokola (`backdrop-grid-run`),
   posúva vzor presne o jednu dlaždicu — vzor je preto na konci v tej istej polohe ako na
   začiatku a skok nevidno. */

/* Žiara zosilnie a zoslabne a pritom sa aj posunie — svetlo za plochou dýcha a putuje,
   takže zmenu vidno aj tam, kde je gradient príliš mäkký na to, aby bolo vidieť škálovanie. */
@keyframes backdrop-breathe {
    0% {
        opacity: .58;
        transform: scale(1.04) translate3d(-1.5%, 1%, 0);
    }

    50% {
        opacity: 1;
        transform: scale(1.14) translate3d(1.5%, -1.5%, 0);
    }

    100% {
        opacity: .58;
        transform: scale(1.04) translate3d(-1.5%, 1%, 0);
    }
}

/* Sféry obehnú okruh. Snímky nie sú rozostupené rovnomerne (25/45/70 %), takže dráha
   nemá stále tempo — obeh pôsobí ako plávanie, nie ako otáčanie kolesa. */
@keyframes backdrop-float {
    0% {
        transform: scale(1.2) translate3d(0, 0, 0) rotate(0deg);
    }

    25% {
        transform: scale(1.2) translate3d(5%, -3.5%, 0) rotate(1deg);
    }

    45% {
        transform: scale(1.2) translate3d(2%, 4.5%, 0) rotate(1.8deg);
    }

    70% {
        transform: scale(1.2) translate3d(-4.5%, 2%, 0) rotate(.6deg);
    }

    100% {
        transform: scale(1.2) translate3d(0, 0, 0) rotate(0deg);
    }
}

/* Pásy sa prelejú z jednej strany na druhú, pritom sa natočia a nadýchnu — vlnenie látky. */
@keyframes backdrop-sway {
    from {
        transform: scale(1.3) translate3d(-7%, -1.5%, 0) rotate(-3.4deg);
    }

    to {
        transform: scale(1.42) translate3d(7%, 1.5%, 0) rotate(3.4deg);
    }
}

/* Dym plynie našikmo cez okno; posun je väčší než pri ostatných, preto aj väčšie zväčšenie. */
@keyframes backdrop-drift {
    from {
        transform: scale(1.45) translate3d(-9%, 3%, 0) rotate(-1.5deg);
    }

    to {
        transform: scale(1.45) translate3d(9%, -3%, 0) rotate(1.5deg);
    }
}

/* Zväzok vlákien sa hojdá okolo svojho stredu a pritom sa nadychuje — stuha sa vlní a mení
   šírku, ale ostáva na mieste. Vlákna sú tenké čiary, takže aj malé natočenie je dobre vidieť. */
@keyframes backdrop-strand-wave {
    0% {
        transform: scale(1.06) rotate(-3.2deg) translate3d(-1%, 0, 0);
    }

    50% {
        transform: scale(1.14) rotate(.4deg) translate3d(1%, -1.2%, 0);
    }

    100% {
        transform: scale(1.06) rotate(3.2deg) translate3d(-1%, 0, 0);
    }
}

/* Vodorovné plynutie druhej vrstvy. Používa sa ako protipohyb k hlavnej vrstve dizajnu
   (cez `alternate-reverse`) — dve vrstvy idúce proti sebe dajú ploche hĺbku paralaxy. */
@keyframes backdrop-glide {
    from {
        transform: scale(1.25) translate3d(-8%, -2%, 0);
    }

    to {
        transform: scale(1.25) translate3d(8%, 2%, 0);
    }
}

/* Pomalé otáčanie organickej textúry. Pri maskách typu dym či oblaky sa tak tvary neustále
   presúvajú aj vtedy, keď posun vrstvy práve stojí v krajnej polohe. */
@keyframes backdrop-swirl {
    from {
        transform: scale(1.3) rotate(-2.5deg);
    }

    to {
        transform: scale(1.3) rotate(2.5deg);
    }
}

/* Zrno sa mihoce a posúva o pár pixelov. Dlaždica šumu je hustá, takže tento nepatrný posun
   je z celej sady najlepšie viditeľný pohyb — plocha vďaka nemu nikdy nevyzerá zamrznuto.

   Snímky prepíšu `opacity` vrstvy, preto ju musia počítať z `--backdrop-grain-opacity`:
   inak by zrno počas animácie zosilnelo na plnú hodnotu a dizajn by stratil svoju silu zrna. */
@keyframes backdrop-shimmer {
    0% {
        opacity: calc(var(--backdrop-grain-opacity) * .55);
        transform: translate3d(0, 0, 0);
    }

    50% {
        opacity: var(--backdrop-grain-opacity);
        transform: translate3d(-6px, 4px, 0);
    }

    100% {
        opacity: calc(var(--backdrop-grain-opacity) * .55);
        transform: translate3d(0, 0, 0);
    }
}

/* Mriežka v perspektíve sa hojdá do strán. Pre vzory s maskou je to jediný spôsob, ako ich
   rozhýbať: maska je pripútaná k vrstve, takže sa posúva s ňou — pri `alternate` sa však vráti
   tou istou cestou a nikde neskočí. Naklonenie musí byť aj tu súčasťou snímok. */
@keyframes backdrop-grid-sway {
    from {
        transform: perspective(700px) rotateX(58deg) translate3d(-3.5%, 0, 0);
    }

    to {
        transform: perspective(700px) rotateX(58deg) translate3d(3.5%, 3%, 0);
    }
}

/* Mriežka v perspektíve sa posúva k divákovi. Naklonenie musí byť súčasťou snímok,
   inak by ho animácia počas behu prepísala; posun 84 px = jedna dlaždica hrubšieho rastra. */
@keyframes backdrop-grid-run {
    from {
        transform: perspective(700px) rotateX(58deg) translate3d(0, 0, 0);
    }

    to {
        transform: perspective(700px) rotateX(58deg) translate3d(0, 84px, 0);
    }
}

/* ── Aurora ── zväzok prúdiacich vlákien, mriežka bodiek v perspektíve a žiara.
   Mriežka pripomína plochu vlniacu sa v diaľke; zvislé čiary v nej dobiehajú do horizontu,
   ktorý podčiarkuje úzka žiara. Maska necháva vzor pri okrajoch zmiznúť. */
[data-backdrop="aurora"] {
    --backdrop-glow:
        radial-gradient(37.5% 45% at 27.5% 20%, color-mix(in srgb, var(--brand-glow) 50%, transparent), transparent 100%),
        radial-gradient(35% 42.5% at 85% 92.5%, var(--brand-veil), transparent 100%),
        radial-gradient(55% 1.5% at 50% 25%, color-mix(in srgb, var(--brand) 45%, transparent), transparent 100%);
    --backdrop-texture: linear-gradient(200deg, var(--brand-glow) 0%, transparent 65%);
    --backdrop-texture-mask: url("images/backdrops/clouds.svg");
    --backdrop-texture-opacity: .5;
    --backdrop-pattern:
        radial-gradient(circle, var(--brand) .9px, transparent 1px),
        linear-gradient(to right, var(--brand-veil) 1px, transparent 1px);
    --backdrop-pattern-size: 14px 14px, 84px 84px;
    --backdrop-pattern-inset: 25% -15% -25% 15%;
    --backdrop-pattern-opacity: .3;
    --backdrop-pattern-transform: perspective(700px) rotateX(58deg);
    --backdrop-pattern-mask: radial-gradient(115% 75% at 55% 25%, #000 0%, transparent 72%);
    --backdrop-strand-opacity: .55;
    --backdrop-grain-opacity: .05;
    --backdrop-vignette-opacity: .45;
}

/* ── Žiara ── najpokojnejší dizajn: svetlo zhora, protiľahlý nádych vpravo dole
   a sotva viditeľný dym, aby plocha nebola úplne prázdna. */
[data-backdrop="glow"] {
    --backdrop-glow:
        radial-gradient(62% 45% at 50% 0%, var(--brand-glow), transparent 100%),
        radial-gradient(45% 40% at 88% 96%, var(--brand-veil), transparent 100%);
    --backdrop-texture: linear-gradient(180deg, var(--brand-glow), transparent 80%);
    --backdrop-texture-mask: url("images/backdrops/clouds.svg");
    --backdrop-texture-opacity: .4;
    --backdrop-grain-opacity: .04;
    --backdrop-vignette-opacity: .4;
}

/* ── Sféry ── štyri veľké rozostrené gule; striedanie silnejšej a slabšej dáva hĺbku.
   Tenké obruče okolo dvoch z nich pridajú plánovitosť, aby to neboli len škvrny. */
[data-backdrop="orbs"] {
    --backdrop-glow:
        radial-gradient(26% 32% at 16% 22%, var(--brand-glow), transparent 100%),
        radial-gradient(22% 28% at 74% 10%, var(--brand-veil), transparent 100%),
        radial-gradient(30% 36% at 62% 86%, var(--brand-glow), transparent 100%),
        radial-gradient(18% 24% at 6% 76%, var(--brand-veil), transparent 100%);
    --backdrop-pattern:
        radial-gradient(circle 250px at 16% 22%, transparent 0 247px, var(--brand-line) 247px 250px, transparent 250px),
        radial-gradient(circle 175px at 74% 10%, transparent 0 173px, var(--brand-veil) 173px 175px, transparent 175px),
        radial-gradient(circle 320px at 62% 86%, transparent 0 317px, var(--brand-line) 317px 320px, transparent 320px);
    --backdrop-pattern-size: 100% 100%;
    --backdrop-pattern-opacity: .5;
    --backdrop-grain-opacity: .05;
    --backdrop-vignette-opacity: .4;
}

/* ── Mriežka ── technické „rysovacie" pozadie: hrubý raster s jemnejším vnútri,
   ako na milimetrovom papieri. Maska ho drží pri hornom okraji. */
[data-backdrop="grid"] {
    --backdrop-glow:
        radial-gradient(55% 45% at 50% 0%, var(--brand-glow), transparent 100%),
        radial-gradient(40% 35% at 12% 92%, var(--brand-veil), transparent 100%);
    --backdrop-pattern:
        linear-gradient(to right, var(--brand-line) 1px, transparent 1px),
        linear-gradient(to bottom, var(--brand-line) 1px, transparent 1px),
        linear-gradient(to right, var(--brand-veil) 1px, transparent 1px),
        linear-gradient(to bottom, var(--brand-veil) 1px, transparent 1px);
    --backdrop-pattern-size: 112px 112px, 112px 112px, 28px 28px, 28px 28px;
    --backdrop-pattern-opacity: .6;
    --backdrop-pattern-mask: radial-gradient(125% 90% at 50% 0%, #000 12%, transparent 82%);
    --backdrop-grain-opacity: .05;
    --backdrop-vignette-opacity: .45;
}

/* ── Bodky ── bodkovaný papier, do ktorého je votkaná redšia sieť krúžkov. */
[data-backdrop="dots"] {
    --backdrop-glow:
        radial-gradient(45% 40% at 82% 6%, var(--brand-glow), transparent 100%),
        radial-gradient(38% 34% at 10% 88%, var(--brand-veil), transparent 100%);
    --backdrop-pattern:
        radial-gradient(circle, var(--brand) 1.1px, transparent 1.4px),
        radial-gradient(circle, transparent 0 5px, var(--brand-line) 5px 6.2px, transparent 6.2px);
    --backdrop-pattern-size: 24px 24px, 96px 96px;
    --backdrop-pattern-position: 0 0, 12px 12px;
    --backdrop-pattern-opacity: .26;
    --backdrop-pattern-mask: radial-gradient(110% 95% at 50% 5%, #000 20%, transparent 82%);
    --backdrop-grain-opacity: .05;
    --backdrop-vignette-opacity: .4;
}

/* ── Vrstevnice ── tri sústavy kruhov s rôznym stredom sa prekrývajú do mapy terénu;
   žilkovanie pod nimi pridá dojem zvetraného povrchu. */
[data-backdrop="topography"] {
    --backdrop-glow:
        radial-gradient(45% 50% at 22% 26%, var(--brand-veil), transparent 100%),
        radial-gradient(40% 45% at 80% 80%, var(--brand-veil), transparent 100%);
    --backdrop-texture: linear-gradient(140deg, var(--brand-glow), transparent 70%);
    --backdrop-texture-mask: url("images/backdrops/veins.svg");
    --backdrop-texture-opacity: .3;
    --backdrop-pattern:
        repeating-radial-gradient(circle at 22% 26%, transparent 0 34px, var(--brand-line) 34px 35px),
        repeating-radial-gradient(circle at 78% 74%, transparent 0 46px, var(--brand-line) 46px 47px),
        repeating-radial-gradient(circle at 52% 6%, transparent 0 26px, var(--brand-veil) 26px 27px);
    --backdrop-pattern-opacity: .5;
    --backdrop-pattern-mask: radial-gradient(120% 110% at 40% 40%, #000 10%, transparent 85%);
    --backdrop-grain-opacity: .06;
    --backdrop-vignette-opacity: .45;
}

/* ── Pruhy ── šrafovanie v dvoch rytmoch: hustý raster a cez neho široké pásy. */
[data-backdrop="stripes"] {
    --backdrop-glow:
        radial-gradient(50% 45% at 15% 5%, var(--brand-glow), transparent 100%),
        radial-gradient(45% 40% at 88% 90%, var(--brand-veil), transparent 100%);
    --backdrop-pattern:
        repeating-linear-gradient(135deg, var(--brand-line) 0 1px, transparent 1px 20px),
        repeating-linear-gradient(135deg, var(--brand-veil) 0 4px, transparent 4px 160px);
    --backdrop-pattern-opacity: .55;
    --backdrop-pattern-mask: linear-gradient(155deg, #000 0%, transparent 75%);
    --backdrop-grain-opacity: .05;
    --backdrop-vignette-opacity: .4;
}

/* ── Mramor ── žilky z SVG masky nad diagonálnou výplňou; najvýraznejší z organických
   dizajnov, preto má aj najsilnejšiu vinetu, aby text v strede zostal pokojný. */
[data-backdrop="marble"] {
    --backdrop-glow:
        radial-gradient(60% 55% at 25% 18%, var(--brand-glow), transparent 100%),
        radial-gradient(50% 50% at 85% 88%, var(--brand-veil), transparent 100%);
    --backdrop-texture:
        linear-gradient(135deg,
            color-mix(in srgb, var(--brand) 48%, transparent) 0%,
            color-mix(in srgb, var(--brand) 18%, transparent) 55%,
            transparent 92%);
    --backdrop-texture-mask: url("images/backdrops/veins.svg");
    --backdrop-texture-opacity: .38;
    --backdrop-grain-opacity: .07;
    --backdrop-vignette-opacity: .6;
}

/* ── Dym ── nízkofrekvenčný šum roztiahnutý cez celé okno; pramene dymu presvitajú
   cez seba a zrno im dodá zrnitosť fotografie. */
[data-backdrop="smoke"] {
    --backdrop-glow:
        radial-gradient(70% 60% at 30% 12%, var(--brand-glow), transparent 100%),
        radial-gradient(45% 45% at 90% 80%, var(--brand-veil), transparent 100%);
    --backdrop-texture:
        linear-gradient(160deg,
            color-mix(in srgb, var(--brand) 30%, transparent) 0%,
            color-mix(in srgb, var(--brand) 9%, transparent) 55%,
            transparent 95%);
    --backdrop-texture-mask: url("images/backdrops/clouds.svg");
    --backdrop-texture-opacity: .5;
    --backdrop-grain-opacity: .1;
    --backdrop-vignette-opacity: .55;
}

/* ── Hodváb ── široké pásy prelievajúce sa cez plochu ako látka v pohybe. */
[data-backdrop="silk"] {
    --backdrop-glow:
        radial-gradient(65% 55% at 72% 25%, var(--brand-veil), transparent 100%),
        radial-gradient(50% 45% at 12% 85%, var(--brand-veil), transparent 100%);
    --backdrop-texture:
        linear-gradient(115deg,
            color-mix(in srgb, var(--brand) 32%, transparent) 0%,
            var(--brand-glow) 45%,
            transparent 88%);
    --backdrop-texture-mask: url("images/backdrops/silk.svg");
    --backdrop-texture-opacity: .5;
    --backdrop-grain-opacity: .05;
    --backdrop-vignette-opacity: .5;
}

/* ── Polygóny ── nepravidelná sieť trojuholníkových plôšok; každá má v maske vlastnú
   priehľadnosť, takže sa lámu ako svetlo na brúsenej ploche. */
[data-backdrop="facets"] {
    --backdrop-glow:
        radial-gradient(60% 55% at 18% 10%, var(--brand-glow), transparent 100%),
        radial-gradient(45% 40% at 92% 95%, var(--brand-veil), transparent 100%);
    --backdrop-texture:
        linear-gradient(150deg,
            color-mix(in srgb, var(--brand) 38%, transparent) 0%,
            color-mix(in srgb, var(--brand) 12%, transparent) 60%,
            transparent 95%);
    --backdrop-texture-mask: url("images/backdrops/facets.svg");
    --backdrop-texture-opacity: .6;
    --backdrop-grain-opacity: .06;
    --backdrop-vignette-opacity: .5;
}

/* ── Kruhy ── matica krúžkov s druhým, posunutým rastrom drobných bodiek medzi nimi;
   maska necháva sieť najjasnejšiu v strede a k okrajom ju stlmí. */
[data-backdrop="halftone"] {
    --backdrop-glow:
        radial-gradient(55% 50% at 50% 42%, var(--brand-glow), transparent 100%),
        radial-gradient(40% 40% at 88% 92%, var(--brand-veil), transparent 100%);
    --backdrop-pattern:
        radial-gradient(circle, transparent 0 3.2px, var(--brand-line) 3.2px 4.4px, transparent 4.4px),
        radial-gradient(circle, transparent 0 1.2px, var(--brand-line) 1.2px 2.2px, transparent 2.2px);
    --backdrop-pattern-size: 20px 20px, 20px 20px;
    --backdrop-pattern-position: 0 0, 10px 10px;
    --backdrop-pattern-opacity: .42;
    --backdrop-pattern-mask: radial-gradient(95% 90% at 50% 45%, #000 5%, transparent 88%);
    --backdrop-grain-opacity: .05;
    --backdrop-vignette-opacity: .55;
}

/* ══ Pohyblivé dizajny ═════════════════════════════════════════════════
   Na rozdiel od statických dizajnov ich pohyb NEROBÍ CSS. Vrstvy nižšie sú len pokojné
   pozadie — žiara a textúra, žiadna animácia — a samotný pohyb kreslí časticová vrstva,
   ktorú plní tsParticles zo skriptu `js/backdrop-particles.js`. Tam je aj konfigurácia
   každého z týchto dizajnov; tu je len plocha, na ktorej častice stoja.

   Preto sú žiary zámerne slabšie ako pri statických dizajnoch: nad nimi ešte pribudnú
   častice a dve výrazné vrstvy nad sebou by už obsah stránky pretlačili.

   Pri `prefers-reduced-motion` sa častice vôbec nespustia — z dizajnu ostane práve tá
   pokojná plocha, ktorá je popísaná tu. */

/* ── Súhvezdie ── sieť svetelných bodov nad tmavou plochou. Pozadie je takmer prázdne:
   kompozíciu tvoria samotné body a čiary medzi nimi, takže akýkoľvek vzor pod nimi by
   s nimi súťažil o pozornosť. */
[data-backdrop="constellation"] {
    --backdrop-glow:
        radial-gradient(60% 50% at 50% 0%, var(--brand-glow), transparent 100%),
        radial-gradient(45% 40% at 85% 90%, var(--brand-veil), transparent 100%);
    --backdrop-grain-opacity: .04;
    --backdrop-vignette-opacity: .5;
}

/* ── Svetlušky ── mäkké svetlo v niekoľkých ohniskách, medzi ktorými svetlušky poletujú.
   Ohniská sú rozmiestnené po celej ploche, aby sa častica nemala kam stratiť do tmy. */
[data-backdrop="fireflies"] {
    --backdrop-glow:
        radial-gradient(35% 40% at 20% 25%, var(--brand-glow), transparent 100%),
        radial-gradient(30% 35% at 78% 18%, var(--brand-veil), transparent 100%),
        radial-gradient(40% 45% at 60% 88%, var(--brand-glow), transparent 100%);
    --backdrop-texture: linear-gradient(200deg, var(--brand-glow) 0%, transparent 70%);
    --backdrop-texture-mask: url("images/backdrops/clouds.svg");
    --backdrop-texture-opacity: .3;
    --backdrop-grain-opacity: .06;
    --backdrop-vignette-opacity: .45;
}

/* ── Hexagóny ── plást šesťuholníkov nad tmavou plochou. Pod ním leží riedka technická
   mriežka: šesťuholníky sa otáčajú a plávajú, mriežka stojí, a práve ten rozdiel dá oku
   mieru, podľa ktorej pohyb vidí. */
[data-backdrop="hexagons"] {
    --backdrop-glow:
        radial-gradient(55% 45% at 50% 0%, var(--brand-glow), transparent 100%),
        radial-gradient(45% 40% at 15% 95%, var(--brand-veil), transparent 100%);
    --backdrop-pattern: linear-gradient(to right, var(--brand-veil) 1px, transparent 1px),
        linear-gradient(to bottom, var(--brand-veil) 1px, transparent 1px);
    --backdrop-pattern-size: 72px 72px, 72px 72px;
    --backdrop-pattern-opacity: .22;
    --backdrop-pattern-mask: radial-gradient(100% 80% at 50% 40%, #000 0%, transparent 80%);
    --backdrop-grain-opacity: .04;
    --backdrop-vignette-opacity: .5;
}

/* ── Uzly ── hustá sieť uzlov uzavretá v okne — uzly sa od okrajov odrážajú, takže plocha
   je rovnomerne obsadená a graf sa nikdy nevyprázdni. Pozadie preto ostáva takmer holé;
   kompozíciu tvoria samotné uzly a spoje medzi nimi. */
[data-backdrop="nodes"] {
    --backdrop-glow:
        radial-gradient(60% 50% at 25% 15%, var(--brand-glow), transparent 100%),
        radial-gradient(50% 45% at 80% 85%, var(--brand-veil), transparent 100%);
    --backdrop-grain-opacity: .04;
    --backdrop-vignette-opacity: .45;
}

/* ── Obvod ── doska plošných spojov: body idú len vodorovne a zvislo a spoje medzi nimi
   preto vychádzajú v pravých uhloch. Mriežka pod nimi má rovnaký raster ako ich rozostupy,
   takže stopy pôsobia, že sa jej držia. */
[data-backdrop="circuit"] {
    --backdrop-glow:
        radial-gradient(70% 50% at 50% 100%, var(--brand-glow), transparent 100%),
        radial-gradient(40% 35% at 12% 10%, var(--brand-veil), transparent 100%);
    --backdrop-pattern: linear-gradient(to right, var(--brand-line) 1px, transparent 1px),
        linear-gradient(to bottom, var(--brand-line) 1px, transparent 1px);
    --backdrop-pattern-size: 110px 110px, 110px 110px;
    --backdrop-pattern-opacity: .18;
    --backdrop-pattern-mask: radial-gradient(110% 85% at 50% 50%, #000 0%, transparent 85%);
    --backdrop-grain-opacity: .05;
    --backdrop-vignette-opacity: .5;
}

/* ── Polygóny ── nízkopolygónová plocha: trojuholníkové plôšky a medzi nimi vyplnené oká
   siete. Vzor pod nimi je zámerne len náznak — plôšky sa prekrývajú a ich krytie sa sčítava,
   takže výraznejšie pozadie by sa v nich stratilo. */
[data-backdrop="lowpoly"] {
    --backdrop-glow:
        radial-gradient(65% 55% at 70% 10%, var(--brand-glow), transparent 100%),
        radial-gradient(50% 45% at 20% 90%, var(--brand-veil), transparent 100%);
    --backdrop-texture: linear-gradient(200deg, var(--brand-glow) 0%, transparent 70%);
    --backdrop-texture-mask: url("images/backdrops/facets.svg");
    --backdrop-texture-opacity: .22;
    --backdrop-grain-opacity: .05;
    --backdrop-vignette-opacity: .5;
}

/* ── Meteory ── nočná obloha: riedke hviezdy stoja, meteory cez ne presvištia.
   Hviezdy sú vzor, nie častice — nehybná vrstva nestojí ani snímku a rozdiel medzi
   stojacou oblohou a letiacim meteorom je práve to, na čom dizajn stojí. */
[data-backdrop="meteors"] {
    --backdrop-glow:
        radial-gradient(70% 45% at 50% 0%, var(--brand-glow), transparent 100%),
        radial-gradient(40% 40% at 15% 85%, var(--brand-veil), transparent 100%);
    --backdrop-pattern:
        radial-gradient(circle, var(--brand) .8px, transparent 1.2px),
        radial-gradient(circle, var(--brand-line) 1.3px, transparent 1.8px);
    --backdrop-pattern-size: 96px 96px, 152px 152px;
    --backdrop-pattern-position: 0 0, 48px 36px;
    --backdrop-pattern-opacity: .3;
    --backdrop-pattern-mask: radial-gradient(110% 85% at 50% 20%, #000 0%, transparent 78%);
    --backdrop-grain-opacity: .05;
    --backdrop-vignette-opacity: .5;
}

/* ── Mince ── svetlo zdola, po ktorom mince stúpajú nahor. Žiara je pri spodnom okraji
   najsilnejšia, takže častica sa rodí vo svetle a smerom hore sa stratí — pohyb má tým
   začiatok aj koniec, hoci žiadna častica nikdy nezhasne. */
[data-backdrop="coins"] {
    --backdrop-glow:
        radial-gradient(75% 55% at 50% 105%, var(--brand-glow), transparent 100%),
        radial-gradient(45% 40% at 20% 15%, var(--brand-veil), transparent 100%);
    --backdrop-texture: linear-gradient(0deg, var(--brand-glow) 0%, transparent 60%);
    --backdrop-texture-mask: url("images/backdrops/clouds.svg");
    --backdrop-texture-opacity: .28;
    --backdrop-grain-opacity: .05;
    --backdrop-vignette-opacity: .5;
}

/* ── Prúd ── vodorovný svetelný pás cez stred plochy a v ňom uháňajúce ťahy. Riedke
   vodorovné čiary pod nimi držia smer aj vtedy, keď práve žiadny ťah nejde stredom plochy —
   bez nich by sa dizajn na chvíľu zmenil na obyčajnú žiaru. */
[data-backdrop="stream"] {
    --backdrop-glow:
        radial-gradient(85% 30% at 50% 45%, var(--brand-glow), transparent 100%),
        radial-gradient(40% 35% at 90% 12%, var(--brand-veil), transparent 100%);
    --backdrop-pattern: repeating-linear-gradient(0deg, var(--brand-veil) 0 1px, transparent 1px 38px);
    --backdrop-pattern-opacity: .35;
    --backdrop-pattern-mask: radial-gradient(90% 70% at 50% 50%, #000 10%, transparent 85%);
    --backdrop-grain-opacity: .05;
    --backdrop-vignette-opacity: .5;
}

/* ── Bez pozadia ── žiadne premenné; vrstvy sa vykreslia prázdne. */

/* ── Ukážka dizajnu v nastaveniach ──
   Ukážka sa kreslí rovno v rozmeroch dlaždice, nie ako zmenšená obrazovka. Žiary, textúry
   aj vineta sú zadané v percentách alebo `cover`, takže sa do dlaždice zmestí celá kompozícia;
   vzory majú svoju skutočnú hustotu — dlaždica je teda ich výrez v mierke 1 : 1.
   Zmenšovanie celej vrstvy by síce zachovalo kompozíciu vzoru, ale čiary hrubé 1 px by
   sa scvrkli pod jeden pixel a z dlaždíc by ostali prázdne obdĺžniky. */
.app-backdrop-preview {
    inset: 0;
}

/* Ukážky pohyblivých dizajnov štandardne stoja a rozbehnú sa až pod kurzorom alebo po výbere.
   Naraz bežiaca animácia v každej dlaždici by z nastavení urobila nepokojnú plochu a čítať
   sa v nej dá horšie než v ktorejkoľvek z nich. */
.app-backdrop-preview .app-backdrop-glow,
.app-backdrop-preview .app-backdrop-texture,
.app-backdrop-preview .app-backdrop-pattern,
.app-backdrop-preview .app-backdrop-strands,
.app-backdrop-preview .app-backdrop-grain {
    animation-play-state: paused;
}

.backdrop-tile:hover .app-backdrop-preview .app-backdrop-glow,
.backdrop-tile:hover .app-backdrop-preview .app-backdrop-texture,
.backdrop-tile:hover .app-backdrop-preview .app-backdrop-pattern,
.backdrop-tile:hover .app-backdrop-preview .app-backdrop-strands,
.backdrop-tile:hover .app-backdrop-preview .app-backdrop-grain,
.backdrop-tile:has(.backdrop-tile-input:checked) .app-backdrop-preview .app-backdrop-glow,
.backdrop-tile:has(.backdrop-tile-input:checked) .app-backdrop-preview .app-backdrop-texture,
.backdrop-tile:has(.backdrop-tile-input:checked) .app-backdrop-preview .app-backdrop-pattern,
.backdrop-tile:has(.backdrop-tile-input:checked) .app-backdrop-preview .app-backdrop-strands,
.backdrop-tile:has(.backdrop-tile-input:checked) .app-backdrop-preview .app-backdrop-grain {
    animation-play-state: running;
}

/* ── Výber pozadia v Nastavenia → Aplikácia ──
   Dlaždice sú tu, a nie v scoped CSS karty vzhľadu, lebo obsahujú komponent AppBackdrop —
   na jeho elementy by sa zo scoped CSS dalo dosiahnuť len cez `::deep`. */
.backdrop-field {
    margin-bottom: 1.25rem;
}

.backdrop-field-label {
    display: block;
    margin-bottom: .6rem;
    font-size: .95rem;
    font-weight: 600;
    color: var(--text-primary);
}

/* Dizajnov je veľa a karta nastavení môže byť úzka aj široká, preto sa dlaždice ukladajú
   do mriežky, ktorá si počet stĺpcov dopočíta sama — v najužšej karte vyjdú dva. */
.backdrop-tiles {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(148px, 1fr));
    gap: .8rem;
}

.backdrop-tile {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .4rem;
    cursor: pointer;
}

/* Prepínač ostáva v DOM kvôli klávesnici a čítačkám obrazovky, ale nekreslí sa —
   jeho stav nesie orámovanie dlaždice. */
.backdrop-tile-input {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}

.backdrop-tile-frame {
    position: relative;
    width: 100%;
    aspect-ratio: 16 / 10;
    overflow: hidden;
    border: 2px solid var(--border-color);
    border-radius: var(--radius-md);
    background: var(--bg-body);
    transition: border-color .15s ease, box-shadow .15s ease;
}

.backdrop-tile:hover .backdrop-tile-frame {
    border-color: var(--brand-line);
}

.backdrop-tile:has(.backdrop-tile-input:checked) .backdrop-tile-frame {
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-subtle);
}

.backdrop-tile:has(.backdrop-tile-input:focus-visible) .backdrop-tile-frame {
    outline: 2px solid var(--accent);
    outline-offset: 3px;
}

/* Ukážka pohyblivého dizajnu stojí, kým na ňu používateľ neprejde myšou — bez tohto štítku
   by sa od statických dizajnov nedala odlíšiť. */
.backdrop-tile-badge {
    position: absolute;
    top: .3rem;
    right: .3rem;
    padding: .05rem .4rem;
    border-radius: var(--radius-sm);
    background: var(--accent-subtle);
    color: var(--text-primary);
    font-size: .68rem;
    font-weight: 600;
    letter-spacing: .02em;
}

.backdrop-tile-name {
    font-size: .88rem;
    color: var(--text-secondary);
}

.backdrop-tile:has(.backdrop-tile-input:checked) .backdrop-tile-name {
    font-weight: 600;
    color: var(--text-primary);
}

/* ── Scrollbar styling ── */
::-webkit-scrollbar {
    width: 6px;
    height: 6px;
}

::-webkit-scrollbar-track {
    background: transparent;
}

::-webkit-scrollbar-thumb {
    background: var(--border-subtle);
    border-radius: 3px;
}

::-webkit-scrollbar-thumb:hover {
    background: var(--text-muted);
}

/* ══ Informačná lišta o cookies ═══════════════════════════════════════════
   Nejde o súhlasovú lištu — aplikácia používa len technicky nevyhnutné
   a funkčné cookies. Lišta preto nič neblokuje, iba informuje. */
.cookie-notice {
    position: fixed;
    left: 50%;
    bottom: 1rem;
    transform: translateX(-50%);
    z-index: 1200;
    display: flex;
    align-items: center;
    gap: .85rem;
    width: min(46rem, calc(100vw - 2rem));
    padding: .85rem 1.1rem;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-lg);
    background: var(--bg-card);
    box-shadow: var(--shadow-lg);
    color: var(--text-secondary);
    font-size: .9rem;
    line-height: 1.5;
}

.cookie-notice-icon {
    flex-shrink: 0;
    font-size: 1.25rem;
    color: var(--accent);
}

.cookie-notice p {
    margin: 0;
    flex: 1;
}

.cookie-notice strong {
    color: var(--text-primary);
    font-weight: 600;
}

.cookie-notice a {
    color: var(--accent);
    text-decoration: none;
}

.cookie-notice a:hover {
    text-decoration: underline;
}

.cookie-notice-btn {
    flex-shrink: 0;
    padding: .45rem 1.1rem;
    border: none;
    border-radius: var(--radius-md);
    background: var(--accent);
    color: #fff;
    font-size: .9rem;
    font-weight: 600;
    cursor: pointer;
    transition: opacity .15s;
}

.cookie-notice-btn:hover {
    opacity: .9;
}

@media (max-width: 640px) {
    .cookie-notice {
        flex-wrap: wrap;
        font-size: .85rem;
    }

    .cookie-notice-btn {
        width: 100%;
    }
}


/* ══ Karty nastavení ═══════════════════════════════════════════════════════
   Spoločný vzhľad pre štyri sekcie Administrácie. Používa premenné témy, takže funguje
   aj v svetlom režime. Nové karty nastavení stavajú na tomto bloku. */
.settings-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1.5rem;
}

/* Dva stĺpce sú horná hranica zámerne. Pri automatickom počte stĺpcov vychádzali na širokom
   monitore tri, no sekcie majú párny počet úzkych kariet — posledný riadok tak zostával
   z tretiny prázdny a karty vedľa seba nesedeli na spoločnú mriežku. */
@media (min-width: 62rem) {
    .settings-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

.settings-card {
    display: flex;
    flex-direction: column;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-lg);
    background: var(--bg-card);
    overflow: hidden;
    transition: border-color .2s, box-shadow .2s;
}

.settings-card:hover {
    border-color: var(--brand-line);
    box-shadow: var(--shadow-md);
}

.settings-card.full-width {
    grid-column: 1 / -1;
}

.settings-card-header {
    display: flex;
    align-items: flex-start;
    gap: .9rem;
    padding: 1.5rem 1.5rem 0;
}

.settings-card-header > .bi {
    flex-shrink: 0;
    margin-top: .2rem;
    font-size: 1.25rem;
    color: var(--accent);
}

.settings-card-header h2 {
    margin: 0;
    font-size: 1.05rem;
    font-weight: 700;
    letter-spacing: -.01em;
    color: var(--text-primary);
}

.settings-card-body {
    flex: 1;
    padding: .65rem 1.5rem 1.15rem;
}

.settings-card-footer {
    display: flex;
    justify-content: flex-end;
    padding: 0 1.5rem 1.5rem;
}

.settings-desc {
    margin: 0 0 1.1rem;
    color: var(--text-secondary);
    font-size: .93rem;
    line-height: 1.55;
}

/* Medzinadpis vnútri karty nastavení — oddeľuje skupinu prepínačov od zvyšku. */
.settings-subtitle {
    margin: 1.4rem 0 .35rem;
    font-size: .95rem;
    font-weight: 700;
}

/* ── Odkaz na súvisiacu stránku ── */
.quick-link {
    display: flex;
    align-items: center;
    gap: .6rem;
    margin-top: 1rem;
    padding: .75rem 1rem;
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    background: var(--bg-surface);
    color: var(--text-secondary);
    font-size: .92rem;
    text-decoration: none;
    transition: border-color .15s, color .15s;
}

.quick-link:hover {
    border-color: var(--accent);
    color: var(--text-primary);
}

.quick-link > .bi:first-child {
    color: var(--accent);
}

/* ══ Formuláre v nastaveniach ══════════════════════════════════════════════
   Bootstrap si polia farbí po svojom, takže v tmavom režime svietili biele
   a fokus mal cudziu modrú. Tu ich preberáme pod premenné témy, aby celá
   sekcia Administrácia reagovala na zvolenú farbu accentu. */
.admin-content .form-control,
.admin-content .form-select {
    background-color: var(--bg-surface);
    border: 1px solid var(--border-color);
    color: var(--text-primary);
}

.admin-content .form-control::placeholder {
    color: var(--text-muted);
}

.admin-content .form-control:focus,
.admin-content .form-select:focus {
    background-color: var(--bg-surface);
    border-color: var(--accent);
    color: var(--text-primary);
    box-shadow: 0 0 0 .2rem var(--accent-subtle);
}

.admin-content .form-control:disabled,
.admin-content .form-control[readonly] {
    background-color: var(--bg-card);
    color: var(--text-secondary);
}

.admin-content .form-floating > label {
    padding: 1rem 1.2rem;
    color: var(--text-muted);
}

.admin-content .form-floating > .form-control,
.admin-content .form-floating > .form-select {
    height: 3.5rem;
    padding-top: 1.75rem;
    padding-bottom: .65rem;
    border-radius: var(--radius-md);
}

.admin-content .form-floating {
    margin-bottom: 0;
}

.admin-content .mb-3 {
    margin-bottom: .75rem !important;
}

/* Jednoformulárové stránky (heslo, email, 2FA) stoja na strede a nie sú širšie,
   než sa dá pohodlne prečítať — predtým sa lepili k ľavému okraju. */
.settings-narrow {
    max-width: 34rem;
    margin: 0 auto;
}

/* Rad tlačidiel pod obsahom karty; na úzkych displejoch sa roztiahnu na celú šírku. */
.settings-actions {
    display: flex;
    flex-wrap: wrap;
    gap: .6rem;
    margin-top: 1rem;
}

.settings-actions .btn {
    flex: 1 1 12rem;
}

/* Informačná hláška vnútri karty nastavení — jemnejšia než bootstrapový alert. */
.settings-note {
    display: flex;
    align-items: flex-start;
    gap: .6rem;
    margin: 0 0 1rem;
    padding: .8rem 1rem;
    border: 1px solid var(--border-subtle);
    border-left: 3px solid var(--accent);
    border-radius: var(--radius-md);
    background: var(--bg-surface);
    color: var(--text-secondary);
    font-size: .9rem;
    line-height: 1.5;
}

.settings-note.is-warning { border-left-color: var(--warning); }
.settings-note.is-danger  { border-left-color: var(--danger); }

.settings-note > .bi {
    flex-shrink: 0;
    margin-top: .1rem;
    color: var(--accent);
}

.settings-note.is-warning > .bi { color: var(--warning); }
.settings-note.is-danger  > .bi { color: var(--danger); }

.settings-note strong {
    color: var(--text-primary);
}

.settings-note p {
    margin: .25rem 0 0;
}

/* ══ Karty nastavení — spoločné prvky ══════════════════════════════════════
   Karty sekcií Administrácia žijú ako komponenty v Components/Account/Shared/Settings.
   Ich vzhľad je preto tu, nie v scoped CSS jednotlivých stránok — po zlúčení dvanástich
   stránok do štyroch sekcií by inak tie isté triedy museli byť rozkopírované v každej. */

/* ── Kotvy na karty v rámci sekcie ──
   Sekcie sú dlhšie než pôvodné jednoúčelové stránky, preto sa dá na kartu skočiť. */
.settings-subnav {
    display: flex;
    flex-wrap: wrap;
    gap: .4rem;
    margin-bottom: 1.5rem;
}

.settings-subnav a,
.settings-subnav button {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    padding: .35rem .75rem;
    border: 1px solid var(--border-subtle);
    border-radius: 999px;
    background: var(--bg-surface);
    color: var(--text-secondary);
    font-size: .85rem;
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
    font-family: inherit;
    transition: border-color .15s, color .15s;
}

.settings-subnav a:hover,
.settings-subnav button:hover {
    border-color: var(--accent);
    color: var(--text-primary);
}

.settings-subnav .bi {
    font-size: .95rem;
    color: var(--accent);
}

/* ── Záložky sekcie ──
   Sekcia zobrazuje vždy jednu kartu; ostatné čakajú za svojou záložkou. Otvorená záložka
   musí byť rozoznateľná na prvý pohľad, inak človek nevie, na ktorú časť sa práve pozerá. */
.settings-subnav--tabs {
    margin-bottom: 1.25rem;
}

.settings-subnav--tabs a,
.settings-subnav--tabs button {
    padding: .45rem .9rem;
    font-size: .9rem;
}

.settings-subnav--tabs a.is-active,
.settings-subnav--tabs button.is-active {
    border-color: var(--accent);
    background: var(--accent-subtle);
    color: var(--text-primary);
    font-weight: 600;
}

/* Otvorená je vždy jedna karta — dva stĺpce by ju nechali sedieť v ľavej polovici. */
.settings-grid--single {
    grid-template-columns: 1fr;
}

/* Kotva nesmie skončiť pod prilepenou hlavičkou. */
.admin-content [id] {
    scroll-margin-top: 5rem;
}

/* Druhá a ďalšia mriežka na tej istej stránke potrebuje odstup od predchádzajúceho bloku. */
.settings-grid--spaced {
    margin-top: 1.5rem;
}

/* ── Prepínač ── */
.settings-toggle {
    display: flex;
    align-items: flex-start;
    gap: .75rem;
    padding: .6rem 0;
    font-size: .97rem;
    font-weight: 500;
    color: var(--text-primary);
    cursor: pointer;
}

.settings-toggle input[type="checkbox"] {
    flex-shrink: 0;
    width: 1.25rem;
    height: 1.25rem;
    margin-top: .05rem;
    border-radius: 6px;
    accent-color: var(--accent);
    cursor: pointer;
}

/* Doplňujúca veta pod názvom prepínača — vysvetlí, čo sa zapnutím zmení. */
.settings-toggle small {
    display: block;
    margin-top: .15rem;
    font-size: .84rem;
    font-weight: 400;
    line-height: 1.45;
    color: var(--text-muted);
}

/* ── Prázdny stav v karte ── */
.settings-empty {
    display: flex;
    align-items: center;
    gap: .6rem;
    margin: 0;
    padding: 1.5rem;
    border: 1px dashed var(--border-color);
    border-radius: var(--radius-md);
    color: var(--text-muted);
    font-size: .9rem;
}

.settings-empty .bi {
    font-size: 1.15rem;
}

/* ══ Účet ══════════════════════════════════════════════════════════════════ */

/* ── Fotka ── */
.avatar-block {
    display: flex;
    align-items: flex-start;
    gap: 1.5rem;
    flex-wrap: wrap;
}

.avatar-preview {
    width: 7rem;
    height: 7rem;
    flex-shrink: 0;
    border-radius: 50%;
    border: 2px solid var(--border-color);
    object-fit: cover;
    background: var(--bg-surface);
}

.avatar-placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--accent-subtle);
    color: var(--accent);
    font-size: 2.2rem;
    font-weight: 700;
    letter-spacing: .02em;
}

.avatar-actions {
    display: flex;
    flex-direction: column;
    gap: .75rem;
    min-width: 15rem;
    flex: 1;
}

.avatar-identity {
    display: flex;
    flex-direction: column;
    gap: .15rem;
}

.avatar-identity strong {
    font-size: 1.05rem;
    color: var(--text-primary);
}

.avatar-identity span {
    font-size: .88rem;
    color: var(--text-muted);
}

.avatar-upload-form {
    display: flex;
    align-items: center;
    gap: .6rem;
    flex-wrap: wrap;
}

/* Natívny file input je neštýlovateľný, preto ho skryjeme pod label,
   ktorý sa tvári ako tlačidlo. */
.avatar-file {
    display: inline-flex;
    align-items: center;
    gap: .45rem;
    padding: .45rem .9rem;
    border: 1px dashed var(--border-color);
    border-radius: var(--radius-md);
    background: var(--bg-surface);
    color: var(--text-secondary);
    font-size: .9rem;
    cursor: pointer;
    transition: border-color .15s, color .15s;
}

.avatar-file:hover {
    border-color: var(--accent);
    color: var(--text-primary);
}

.avatar-file input[type="file"] {
    /* Skrytý, no stále dosiahnuteľný klávesnicou aj čítačkou obrazovky. */
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

.avatar-hint {
    margin: 0;
    color: var(--text-muted);
    font-size: .82rem;
}

/* ── Formulár profilu ── */
.profile-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
    gap: 1rem;
}

.profile-bio {
    min-height: 6.5rem;
    resize: vertical;
}

/* ── Fakty o účte ──
   Dlaždice sa musia prispôsobiť obsahu: prihlasovací email býva dlhší než ostatné
   hodnoty a v pevnej šírke sa orezával. */
.profile-facts {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
    gap: 1rem;
    margin: 0;
}

.profile-facts div {
    display: flex;
    flex-direction: column;
    gap: .2rem;
    padding: .75rem .9rem;
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    background: var(--bg-surface);
}

.profile-facts dt {
    color: var(--text-muted);
    font-size: .8rem;
    font-weight: 500;
}

.profile-facts dd {
    margin: 0;
    color: var(--text-primary);
    font-size: .95rem;
    font-weight: 600;
    /* Email nemá medzeru, na ktorej by sa zalomil — bez tohto by pretiekol z dlaždice. */
    overflow-wrap: anywhere;
}

/* ══ Aplikácia ═════════════════════════════════════════════════════════════ */

/* ── Vzhľad ──
   Karta je na celú šírku, preto stoja voľby vedľa seba: vľavo farba a písmo,
   vpravo mriežka pozadí, ktorá šírku naozaj využije. */
.appearance-layout {
    display: grid;
    grid-template-columns: minmax(0, 20rem) minmax(0, 1fr);
    gap: 2rem;
    align-items: start;
}

.appearance-column {
    display: flex;
    flex-direction: column;
}

@media (max-width: 900px) {
    .appearance-layout {
        grid-template-columns: 1fr;
        gap: 1.25rem;
    }
}

/* ── Výber farby témy ── */
.theme-color-field {
    margin-bottom: 1.25rem;
}

.theme-color-field > label {
    display: block;
    margin-bottom: .6rem;
    font-size: .95rem;
    font-weight: 600;
    color: var(--text-primary);
}

.theme-color-row {
    display: flex;
    align-items: center;
    gap: .9rem;
    flex-wrap: wrap;
}

/* Natívny color input zbavený rámčeka prehliadača, aby vyzeral ako veľká farebná dlaždica. */
.theme-color-input {
    width: 3.5rem;
    height: 2.75rem;
    padding: 0;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    background: transparent;
    cursor: pointer;
    flex-shrink: 0;
}

.theme-color-input::-webkit-color-swatch-wrapper {
    padding: 4px;
}

.theme-color-input::-webkit-color-swatch {
    border: none;
    border-radius: 8px;
}

.theme-color-input::-moz-color-swatch {
    border: none;
    border-radius: 8px;
}

.theme-swatches {
    display: flex;
    gap: .5rem;
    flex-wrap: wrap;
}

.theme-swatch {
    width: 1.9rem;
    height: 1.9rem;
    padding: 0;
    border-radius: 50%;
    border: 2px solid transparent;
    background: var(--swatch);
    cursor: pointer;
    transition: transform .15s ease, box-shadow .15s ease;
}

.theme-swatch:hover {
    transform: scale(1.15);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--swatch) 30%, transparent);
}

.theme-swatch:focus-visible {
    outline: none;
    border-color: var(--text-primary);
}

.theme-color-hint {
    margin: .6rem 0 0;
    font-size: .88rem;
    color: var(--text-muted);
}

/* ══ Zabezpečenie ══════════════════════════════════════════════════════════ */

/* ── Kontrolný zoznam ── */
.security-checks {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr));
    gap: .85rem;
}

.security-check {
    display: flex;
    align-items: center;
    gap: .75rem;
    padding: .9rem 1rem;
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    background: var(--bg-surface);
}

.security-check > .bi {
    flex-shrink: 0;
    font-size: 1.2rem;
}

.security-check.is-ok > .bi {
    color: var(--success);
}

.security-check.is-warn {
    border-color: color-mix(in srgb, var(--warning) 35%, var(--border-subtle));
}

.security-check.is-warn > .bi {
    color: var(--warning);
}

.security-check > div {
    display: flex;
    flex-direction: column;
    gap: .1rem;
    flex: 1;
    min-width: 0;
}

.security-check strong {
    font-size: .93rem;
    color: var(--text-primary);
}

.security-check span {
    font-size: .82rem;
    line-height: 1.45;
    color: var(--text-muted);
}

.security-check .btn {
    flex-shrink: 0;
}

/* ── Prepojené účty ── */
.provider-list {
    list-style: none;
    margin: 0 0 1rem;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: .4rem;
}

.provider-row {
    display: flex;
    align-items: center;
    gap: .8rem;
    padding: .7rem .9rem;
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    background: var(--bg-surface);
}

.provider-icon {
    flex-shrink: 0;
    width: 2rem;
    height: 2rem;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-sm);
    background: var(--accent-subtle);
    color: var(--accent);
    font-size: .9rem;
}

.provider-name {
    flex: 1;
    min-width: 0;
    font-size: .95rem;
    font-weight: 600;
    color: var(--text-primary);
}

.provider-row form {
    flex-shrink: 0;
    margin: 0;
}

/* ── Zoznam zariadení a pripojených aplikácií ── */
.sessions-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: .4rem;
}

.session-row {
    display: flex;
    align-items: center;
    gap: .8rem;
    padding: .7rem .9rem;
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    background: var(--bg-surface);
}

/* Zariadenie, na ktorom používateľ práve sedí, sa musí dať nájsť očami hneď. */
.session-row.is-current {
    border-left: 3px solid var(--accent);
}

.session-icon {
    flex-shrink: 0;
    width: 2rem;
    height: 2rem;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-sm);
    background: var(--accent-subtle);
    color: var(--accent);
    font-size: .9rem;
}

.session-main {
    display: flex;
    flex-direction: column;
    gap: .15rem;
    flex: 1;
    min-width: 0;
}

.session-name-row {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: .4rem;
}

.session-name-row strong {
    font-size: .92rem;
    font-weight: 600;
    color: var(--text-primary);
}

.session-chip {
    padding: .05rem .45rem;
    border-radius: 20px;
    font-size: .78rem;
    font-weight: 700;
    white-space: nowrap;
}

.chip-web     { background: var(--info-subtle);   color: var(--info); }
.chip-mobile  { background: var(--purple-subtle); color: var(--purple); }
.chip-current { background: var(--accent-subtle); color: var(--accent); }

.session-meta {
    font-size: .78rem;
    color: var(--text-muted);
}

/* Platnosť prihlásenia — hlavne na ladenie, preto presný čas aj zostávajúci interval. */
.session-expiry {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: .3rem;
    font-size: .78rem;
    color: var(--text-secondary);
}

.session-expiry > .bi {
    color: var(--accent);
}

.session-expiry strong {
    color: var(--text-primary);
    font-variant-numeric: tabular-nums;
}

.session-expiry-rule {
    color: var(--text-muted);
    font-style: italic;
}

.session-expiry.expiry-soon,
.session-expiry.expiry-soon > .bi { color: var(--warning); }
.session-expiry.expiry-soon strong { color: var(--warning); }

.session-expiry.expiry-gone,
.session-expiry.expiry-gone > .bi { color: var(--danger); }
.session-expiry.expiry-gone strong { color: var(--danger); }

.session-action {
    flex-shrink: 0;
    margin: 0;
}

.sessions-bulk {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: .6rem;
    margin: 1rem 0 0;
    padding-top: 1rem;
    border-top: 1px solid var(--border-subtle);
}

.sessions-bulk-hint {
    flex: 1;
    min-width: 14rem;
    font-size: .8rem;
    line-height: 1.45;
    color: var(--text-muted);
}

/* ── Zoznam bezpečnostných udalostí ── */
.activity-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: .4rem;
}

.activity-row {
    display: flex;
    align-items: center;
    gap: .8rem;
    padding: .7rem .9rem;
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    background: var(--bg-surface);
}

/* Udalosti hodné pozornosti nesú farebný pruh vľavo — v zozname sa nájdu očami hneď. */
.activity-row.is-sensitive {
    border-left: 3px solid var(--warning);
}

.activity-icon {
    flex-shrink: 0;
    width: 2rem;
    height: 2rem;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-sm);
    background: var(--accent-subtle);
    color: var(--accent);
    font-size: .9rem;
}

.activity-row.is-sensitive .activity-icon {
    background: var(--warning-subtle);
    color: var(--warning);
}

.activity-main {
    display: flex;
    flex-direction: column;
    gap: .1rem;
    flex: 1;
    min-width: 0;
}

.activity-main strong {
    font-size: .92rem;
    font-weight: 600;
    color: var(--text-primary);
}

.activity-details {
    font-size: .84rem;
    color: var(--text-secondary);
}

.activity-meta {
    font-size: .78rem;
    color: var(--text-muted);
}

.activity-time {
    flex-shrink: 0;
    font-size: .8rem;
    color: var(--text-muted);
    white-space: nowrap;
}

/* ══ Údaje a súkromie ══════════════════════════════════════════════════════ */

/* ── Nastavenie automatických záloh ── */
.backup-settings-inner {
    display: flex;
    flex-direction: column;
    gap: .25rem;
}

.backup-status-row {
    display: flex;
    align-items: center;
    gap: .6rem;
    margin-bottom: .5rem;
    font-size: .95rem;
    color: var(--text-secondary);
}

.backup-status-row .bi {
    color: var(--accent);
    font-size: 1rem;
}

.backup-status-row strong {
    color: var(--text-primary);
}

/* ── Dlaždice s počtami záznamov ── */
.data-tiles {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
    gap: .85rem;
}

.data-tile {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: .1rem;
    padding: .9rem 1rem;
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    background: var(--bg-surface);
}

.data-tile > .bi {
    margin-bottom: .3rem;
    font-size: 1.1rem;
    color: var(--accent);
}

.data-tile strong {
    font-size: 1.45rem;
    font-weight: 700;
    line-height: 1.1;
    color: var(--text-primary);
}

.data-tile span:last-child {
    font-size: .82rem;
    color: var(--text-muted);
}

.privacy-note {
    margin: 1.1rem 0 0;
    color: var(--text-secondary);
    font-size: .9rem;
    line-height: 1.6;
}

.privacy-note a {
    color: var(--accent);
    text-decoration: none;
}

.privacy-note a:hover {
    text-decoration: underline;
}

.privacy-note strong {
    color: var(--text-primary);
}

/* ── Zoznam súhlasov ── */
.consent-list {
    display: flex;
    flex-direction: column;
    gap: .6rem;
}

.consent-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: .8rem 1rem;
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    background: var(--bg-surface);
}

.consent-row > div {
    display: flex;
    flex-direction: column;
    gap: .15rem;
}

.consent-row strong {
    font-size: .95rem;
    color: var(--text-primary);
}

.consent-row span {
    font-size: .82rem;
    color: var(--text-muted);
}

.consent-badge {
    flex-shrink: 0;
    padding: .2rem .6rem;
    border-radius: 999px;
    font-size: .75rem;
    font-weight: 600;
}

.consent-badge--required {
    background: var(--accent-subtle);
    color: var(--accent);
}

/* ── Nebezpečná zóna ── */
.settings-card--danger {
    border-color: color-mix(in srgb, var(--danger) 35%, var(--border-color));
}

.settings-card--danger .settings-card-header > .bi {
    color: var(--danger);
}

.danger-zone-body {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .6rem;
    max-width: 34rem;
    margin: 0 auto;
    padding: 2rem 1.5rem;
    text-align: center;
}

.danger-zone-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 2.75rem;
    height: 2.75rem;
    border-radius: 50%;
    background: var(--danger-subtle);
    color: var(--danger);
    font-size: 1.35rem;
}

.danger-zone-body h2 {
    margin: 0;
    font-size: 1.05rem;
    font-weight: 700;
    letter-spacing: -.01em;
    color: var(--text-primary);
}

.danger-zone-desc {
    margin: 0;
    font-size: .93rem;
    line-height: 1.55;
    color: var(--text-secondary);
}

.danger-zone-desc strong {
    color: var(--danger);
}

.danger-zone-hint {
    margin: 0 0 .4rem;
    font-size: .85rem;
    line-height: 1.55;
    color: var(--text-muted);
}

/* ── Responsive ── */
@media (max-width: 560px) {
    .avatar-block {
        justify-content: center;
        text-align: center;
    }

    .avatar-upload-form {
        justify-content: center;
    }

    .session-row,
    .activity-row {
        flex-wrap: wrap;
    }

    .session-action,
    .activity-time {
        width: 100%;
        padding-left: 2.8rem;
    }
}

@media (max-width: 480px) {
    .consent-row {
        flex-direction: column;
        align-items: stretch;
    }
}

/* ══ Pohyb a interakcia ════════════════════════════════════════════════════
   Jediné miesto, kde sú definované časy a krivky animácií celej aplikácie.
   Stránky ich už len používajú cez premenné — keď sa raz rozhodneme spomaliť
   alebo zrýchliť odozvu, mení sa to tu a nikde inde.

   DÔLEŽITÉ: aplikácia beží na Blazor Serveri, kde každá zmena stavu znamená
   cestu cez SignalR. Preto je všetka spätná väzba na dotyk a prejdenie myšou
   riešená čistým CSS — beží v prehliadači okamžite, bez čakania na server.

   Zámer je decentnosť. Ide o finančnú aplikáciu, ktorú človek otvorí desiatky
   ráz denne; pohyb má potvrdiť, že sa niečo stalo, nie upútať pozornosť. */
:root {
    /* Trvania — od stlačenia tlačidla po nábeh celej stránky. */
    --motion-press: 70ms;
    --motion-fast: 140ms;
    --motion-base: 220ms;
    --motion-slow: 340ms;
    /* Krivky — `out` pre všetko, čo prichádza k používateľovi (dobehne rýchlo
       a mäkko dosadne), `spring` len pre objavenie dialógov. */
    --ease-out: cubic-bezier(.22, .88, .36, 1);
    --ease-in-out: cubic-bezier(.4, 0, .2, 1);
    --ease-spring: cubic-bezier(.34, 1.36, .5, 1);
    /* Krok oneskorenia pri postupnom nábehu zoznamov. */
    --stagger-step: 35ms;
}

/* ── Sada základných animácií ──
   Menej je viac: štyri pohyby pokryjú celú aplikáciu. Všetko ostatné je len
   ich kombinácia s iným trvaním alebo oneskorením. */

/* Objavenie zdola — nábeh stránky, kariet a riadkov zoznamu.

   Pozor na `animation-fill-mode`: pri `bm-rise` používaj vždy `backwards`, nikdy `both`.
   Prehliadač totiž považuje animáciu posunu za „prebiehajúcu" aj po jej dobehnutí, kým ju
   dopĺňa dopredu (`forwards`/`both`), a taký prvok sa stáva vzťažným rámcom pre potomkov
   s `position: fixed`. Dialógy a prekryvy vnútri neho by sa potom prilepili na začiatok
   stránky namiesto na okno prehliadača a pri odscrollovanej stránke by boli useknuté.
   Koncový stav animácie je zhodný s bežným stavom prvku, takže `backwards` nič nemení. */
@keyframes bm-rise {
    from {
        opacity: 0;
        transform: translateY(8px);
    }

    to {
        opacity: 1;
        transform: none;
    }
}

/* Čisté zosvetlenie bez posunu — prekryvy dialógov, prepínanie záložiek. */
@keyframes bm-fade {
    from {
        opacity: 0;
    }

    to {
        opacity: 1;
    }
}

/* Vyskočenie dialógu. Mierny pretlak cez `--ease-spring` dodá pocit,
   že okno „dosadlo", nie že sa len zjavilo. */
@keyframes bm-pop {
    from {
        opacity: 0;
        transform: translateY(10px) scale(.965);
    }

    to {
        opacity: 1;
        transform: none;
    }
}

/* Vyrastenie stĺpca grafu zdola. Patrí sem, a nie ku konkrétnemu grafu, lebo stĺpce kreslia
   tri rôzne stránky (Prehľad, Štatistiky, Mapa mesiaca) a pohyb musí byť na všetkých rovnaký.
   Definícia v `.razor.css` by to nedokázala: izolácia štýlov premenuje názov animácie zvlášť
   pre každý komponent, takže by vznikli tri nezávislé kópie toho istého. */
@keyframes bm-grow-column {
    from {
        transform: scaleY(0);
        opacity: .35;
    }

    to {
        transform: scaleY(1);
        opacity: 1;
    }
}

/* Rozbalenie zhora — detaily transakcií, podpoložky rozpočtov. */
@keyframes bm-unfold {
    from {
        opacity: 0;
        transform: translateY(-4px);
    }

    to {
        opacity: 1;
        transform: none;
    }
}

/* ── Prečo sa hlavná oblasť ako celok neanimuje ──
   Zvádza to k tomu dať nábeh priamo na `.content` pri prechode medzi stránkami, ale
   v Blazor Serveri to dopadne zle. Stránka sa totiž vykresľuje v dvoch vlnách: najprv
   príde kostra (hlavička, tlačidlá, prípadne točiace sa koliesko), a až keď dobehne
   čítanie z databázy, Blazor obsah zahodí a postaví ho nanovo aj s dátami. Na prehl’ade
   uplynie medzi tými vlnami približne desatina sekundy.

   Animácia na `.content` by preto rozhýbala prázdnu kostru, ktorá o chvíľu zanikne,
   a hneď po nej by nabehol skutočný obsah — pôsobilo by to, akoby sa stránka načítala
   dvakrát. Nábeh preto patrí výhradne prvkom, ktoré nesú samotné dáta: tie vzniknú
   práve raz, v druhej vlne, takže sa rozhýbe presne to, čo používateľ prišiel vidieť.

   Z toho plynie pravidlo, ktoré platí v celej aplikácii:
   NA JEDNEJ STRÁNKE ANIMUJE SVOJ PRÍCHOD LEN JEDNA ÚROVEŇ PRVKOV.
   Nabehnú buď karty, alebo riadky v nich — nikdy oboje. Dve vrstvy pohybu cez seba
   sú presne to preblikávanie, ktorému sa vyhýbame. */

/* ── Oneskorené koliesko načítavania ──
   Stránka sa vykresľuje v dvoch vlnách (viď poznámku pri nábehu obsahu vyššie). V tej prvej
   sa objaví koliesko a v druhej ho vystrieda skutočný obsah. Keď sú dáta poruke rýchlo — a pri
   prepínaní v menu obvykle sú — svieti koliesko sotva desatinu sekundy a stihne akurát bliknúť.

   Preto zostáva prvých 200 ms priehľadné. Ak obsah dorazí do tej doby, koliesko zanikne skôr,
   než ho bolo vidieť, a prechod je jedno plynulé objavenie. Pri pomalšom načítaní sa koliesko
   objaví ako doteraz — vtedy je informácia „pracujem na tom" dôležitejšia než pokoj obrazu.

   Rieši to animácia, nie oneskorenie v kóde stránky: prehliadač tak nepotrebuje od servera nič
   navyše a správanie je rovnaké na všetkých stránkach, ktoré koliesko používajú. */
@keyframes bm-delayed-appear {
    from {
        opacity: 0;
    }

    to {
        opacity: 1;
    }
}

.loading-state,
.stats-loading,
.year-loading {
    animation: bm-delayed-appear var(--motion-base) var(--ease-out) 200ms backwards;
}

/* Pri obmedzenom pohybe koliesko nepreblikáva o nič menej, preto oneskorenie platí aj tu —
   nejde o pohyb, ale o to, čo sa vôbec zobrazí. */

/* ── Tlačidlá ──
   Zdvihnutie pri prejdení myšou, stlačenie pri kliknutí. Stlačenie je
   výrazne rýchlejšie ako zdvihnutie — inak pôsobí tlačidlo mäkko a nepresne. */
.btn,
.btn-icon,
.btn-card {
    transition: background-color var(--motion-fast) var(--ease-out), border-color var(--motion-fast) var(--ease-out), color var(--motion-fast) var(--ease-out), box-shadow var(--motion-base) var(--ease-out), transform var(--motion-fast) var(--ease-out);
}

    .btn:hover:not(:disabled),
    .btn-icon:hover:not(:disabled),
    .btn-card:hover:not(:disabled) {
        transform: translateY(-1px);
    }

    .btn:active:not(:disabled),
    .btn-icon:active:not(:disabled),
    .btn-card:active:not(:disabled) {
        transform: translateY(0) scale(.97);
        transition-duration: var(--motion-press);
    }

    .btn:disabled,
    .btn-icon:disabled {
        transform: none;
    }

/* Ikona vnútri tlačidla sa hýbe spolu s ním, ale o kúsok viac — drobný detail,
   vďaka ktorému pôsobí tlačidlo ako jeden hmotný celok. */
.btn .bi {
    transition: transform var(--motion-base) var(--ease-out);
}

.btn:hover:not(:disabled) .bi-plus-lg,
.btn:hover:not(:disabled) .bi-arrow-repeat {
    transform: rotate(90deg);
}

.btn:hover:not(:disabled) .bi-arrow-right {
    transform: translateX(3px);
}

/* ── Odkazy ── */
a {
    transition: color var(--motion-fast) var(--ease-out);
}

/* ── Formulárové polia ──
   Rámček a jeho žiara nabiehajú spolu, takže zaostrenie poľa je vidno aj
   periférne — bez toho si používateľ pri prechode tabulátorom stráca miesto. */
input,
select,
textarea,
.edit-input,
.edit-field {
    transition: background-color var(--motion-fast) var(--ease-out), border-color var(--motion-fast) var(--ease-out), box-shadow var(--motion-base) var(--ease-out);
}

/* ── Dialógy ──
   Prekryv sa len zosvetlí, samotné okno vyskočí. Rozdielne trvanie je zámerné:
   okno dobehne skôr, ako prekryv stmavne naplno, čím sa dostane do popredia. */
.modal-backdrop {
    animation: bm-fade var(--motion-base) var(--ease-out) both;
}

.modal-card,
.confirm-card {
    animation: bm-pop var(--motion-base) var(--ease-spring) both;
}

.modal-close {
    transition: background-color var(--motion-fast) var(--ease-out), color var(--motion-fast) var(--ease-out), transform var(--motion-fast) var(--ease-out);
}

    .modal-close:hover {
        transform: rotate(90deg);
    }

/* ── Karty ──
   Spoločné správanie pre karty, ktoré sa opakujú naprieč stránkami. Zdvihnutie
   je jemné (2 px) a väčšinu efektu nesie tieň — karta sa má „priblížiť",
   nie odskočiť. */
.kpi-card,
.section-card,
.stats-card,
.year-card,
.hero-stat-card {
    transition: transform var(--motion-base) var(--ease-out), box-shadow var(--motion-base) var(--ease-out), border-color var(--motion-base) var(--ease-out);
}

    .kpi-card:hover,
    .section-card:hover,
    .stats-card:hover,
    .year-card:hover,
    .hero-stat-card:hover {
        transform: translateY(-2px);
        box-shadow: var(--shadow-md);
    }

/* Ikona v hlavičke KPI karty ožije spolu s kartou. */
.kpi-icon {
    transition: transform var(--motion-base) var(--ease-spring);
}

.kpi-card:hover .kpi-icon {
    transform: scale(1.12);
}

/* ── Postupný nábeh KPI dlaždíc ──
   Dlaždice sa objavia zľava doprava. Päť krokov stačí — ďalšie dlaždice
   nabehnú spolu s poslednou, čo je pri takom krátkom oneskorení nepostrehnuteľné. */
.kpi-card {
    animation: bm-rise var(--motion-base) var(--ease-out) backwards;
}

    .kpi-card:nth-child(1) {
        animation-delay: 0ms;
    }

    .kpi-card:nth-child(2) {
        animation-delay: var(--stagger-step);
    }

    .kpi-card:nth-child(3) {
        animation-delay: calc(var(--stagger-step) * 2);
    }

    .kpi-card:nth-child(4) {
        animation-delay: calc(var(--stagger-step) * 3);
    }

    .kpi-card:nth-child(5) {
        animation-delay: calc(var(--stagger-step) * 4);
    }

    .kpi-card:nth-child(n+6) {
        animation-delay: calc(var(--stagger-step) * 5);
    }

/* ── Odznaky, štítky a legendy ── */
.legend-item,
.time-badge,
.virtual-badge,
.goal-badge,
.proj-badge,
.share-chip,
.day-chip,
.alloc-chip {
    transition: background-color var(--motion-fast) var(--ease-out), border-color var(--motion-fast) var(--ease-out), color var(--motion-fast) var(--ease-out), transform var(--motion-fast) var(--ease-out);
}

    .legend-item:hover,
    .alloc-chip:hover,
    .share-chip:hover {
        transform: translateY(-1px);
    }

/* ── Prepínače a zaškrtávacie polia ── */
input[type="checkbox"],
input[type="radio"] {
    transition: background-color var(--motion-fast) var(--ease-out), border-color var(--motion-fast) var(--ease-out), transform var(--motion-press) var(--ease-out);
}

    input[type="checkbox"]:active,
    input[type="radio"]:active {
        transform: scale(.88);
    }

/* ── Emoji ikony rozpočtov a cieľov ── */
.emoji-icon {
    transition: transform var(--motion-base) var(--ease-spring);
}

*:hover > .emoji-icon {
    transform: scale(1.1) rotate(-4deg);
}

/* ── Ukazovatele naplnenia ──
   Šírka sa dopĺňa plynulo, takže po zapísaní transakcie vidno, o koľko rozpočtu
   ubudlo. Bez prechodu by hodnota len skočila a zmena by unikla. */
.progress-bar,
.bar-fill,
.usage-fill,
.goal-fill {
    transition: width var(--motion-slow) var(--ease-out), background-color var(--motion-base) var(--ease-out);
}

/* ── Obmedzenie pohybu ──
   Používateľ, ktorý si pohyb v systéme vypol, dostane rovnakú aplikáciu bez
   animácií. Ponechávame len prechody farieb — tie nie sú pohybom a bez nich
   by rozhranie pôsobilo tvrdo. */
@media (prefers-reduced-motion: reduce) {
    .modal-backdrop,
    .modal-card,
    .confirm-card,
    .kpi-card {
        animation: none;
    }

    .btn:hover:not(:disabled),
    .btn:active:not(:disabled),
    .btn-icon:hover:not(:disabled),
    .btn-card:hover:not(:disabled),
    .kpi-card:hover,
    .section-card:hover,
    .stats-card:hover,
    .year-card:hover,
    .hero-stat-card:hover,
    .legend-item:hover,
    .alloc-chip:hover,
    .share-chip:hover,
    .modal-close:hover,
    .kpi-card:hover .kpi-icon,
    *:hover > .emoji-icon {
        transform: none;
    }
}


/* ══ Pohyb v nastaveniach ══════════════════════════════════════════════════
   Nastavenia sa vykresľujú staticky — Identity potrebuje HTTP odpoveď kvôli
   prihlasovacej cookie — takže tu neexistuje interaktívny okruh, cez ktorý by šlo
   čokoľvek animovať zo strany servera. Celý pohyb je preto v CSS a spúšťa ho už
   samotné zobrazenie stránky.

   Karty nabiehajú zhora nadol, v poradí, v akom sa čítajú. */
.settings-card {
    transition: transform var(--motion-base) var(--ease-out), box-shadow var(--motion-base) var(--ease-out), border-color var(--motion-base) var(--ease-out);
    animation: bm-rise var(--motion-base) var(--ease-out) backwards;
}

    .settings-grid > *:nth-child(1) {
        animation-delay: 0ms;
    }

    .settings-grid > *:nth-child(2) {
        animation-delay: var(--stagger-step);
    }

    .settings-grid > *:nth-child(3) {
        animation-delay: calc(var(--stagger-step) * 2);
    }

    .settings-grid > *:nth-child(n+4) {
        animation-delay: calc(var(--stagger-step) * 3);
    }

    /* Nebezpečná zóna sa zámerne nedvíha. Je to jediná karta, ktorá vedie k nezvratnej
       akcii, a nemá pôsobiť ako pozvánka na kliknutie. */
    .settings-card:not(.settings-card--danger):hover {
        transform: translateY(-2px);
        box-shadow: var(--shadow-md);
    }

/* ── Podnavigácia nastavení ── */
.settings-subnav a,
.settings-subnav button,
.quick-link {
    transition: background-color var(--motion-fast) var(--ease-out), color var(--motion-fast) var(--ease-out), border-color var(--motion-fast) var(--ease-out), transform var(--motion-fast) var(--ease-out);
}

    .quick-link:hover {
        transform: translateX(3px);
    }

/* ── Riadky zoznamov (zariadenia, prepojené účty, súhlasy, udalosti) ──
   Bez nábehu: sedia v karte nastavení, ktorá sa už objavuje sama. */
.session-row,
.activity-row,
.consent-row,
.provider-row,
.security-check {
    transition: background-color var(--motion-fast) var(--ease-out), border-color var(--motion-fast) var(--ease-out), transform var(--motion-fast) var(--ease-out);
}

    .session-row:hover,
    .activity-row:hover,
    .provider-row:hover {
        transform: translateX(3px);
    }

.session-icon,
.activity-icon,
.provider-icon {
    transition: transform var(--motion-base) var(--ease-spring);
}

.session-row:hover .session-icon,
.activity-row:hover .activity-icon,
.provider-row:hover .provider-icon {
    transform: scale(1.12);
}

/* ── Dlaždice s počtami záznamov ── */
.data-tile {
    transition: background-color var(--motion-fast) var(--ease-out), border-color var(--motion-fast) var(--ease-out), transform var(--motion-base) var(--ease-out), box-shadow var(--motion-base) var(--ease-out);
}


    .data-tile:hover {
        transform: translateY(-2px);
        box-shadow: var(--shadow-sm);
    }

/* ── Výber farby témy a pozadia ──
   Vzorka aj dlaždica pozadia sú voľby, ktoré človek porovnáva pohľadom, takže
   pohyb tu má jediný účel: ukázať, ktorú práve zvažuje. */
.theme-swatch {
    transition: transform var(--motion-base) var(--ease-spring), box-shadow var(--motion-base) var(--ease-out), border-color var(--motion-fast) var(--ease-out);
}

    .theme-swatch:hover {
        transform: scale(1.15);
    }

    .theme-swatch:active {
        transform: scale(.95);
        transition-duration: var(--motion-press);
    }

.backdrop-tile-frame {
    transition: transform var(--motion-base) var(--ease-out), box-shadow var(--motion-base) var(--ease-out), border-color var(--motion-fast) var(--ease-out);
}

.backdrop-tile:hover .backdrop-tile-frame {
    transform: translateY(-2px) scale(1.02);
    box-shadow: var(--shadow-md);
}

.backdrop-tile:active .backdrop-tile-frame {
    transform: translateY(0) scale(.99);
    transition-duration: var(--motion-press);
}

/* ── Fotka profilu ── */
.avatar-preview,
.avatar-placeholder {
    transition: transform var(--motion-base) var(--ease-spring), border-color var(--motion-fast) var(--ease-out);
}

.avatar-block:hover .avatar-preview,
.avatar-block:hover .avatar-placeholder {
    transform: scale(1.04);
}

@media (prefers-reduced-motion: reduce) {
    .settings-card {
        animation: none;
    }

    .settings-card:not(.settings-card--danger):hover,
    .quick-link:hover,
    .session-row:hover,
    .activity-row:hover,
    .provider-row:hover,
    .session-row:hover .session-icon,
    .activity-row:hover .activity-icon,
    .provider-row:hover .provider-icon,
    .data-tile:hover,
    .theme-swatch:hover,
    .theme-swatch:active,
    .backdrop-tile:hover .backdrop-tile-frame,
    .backdrop-tile:active .backdrop-tile-frame,
    .avatar-block:hover .avatar-preview,
    .avatar-block:hover .avatar-placeholder {
        transform: none;
    }
}

/* ══ Znovupripojenie k serveru ═════════════════════════════════════════════
   Blazor Server drží stránku pri živote cez SignalR. Keď sa spojenie stratí
   (uspatý notebook, výpadok Wi-Fi, reštart servera), framework nájde prvok
   `#components-reconnect-modal` a prepína mu stavové triedy:

     .components-reconnect-show          práve sa pripája
     .components-reconnect-retrying      pokus zlyhal, čaká sa na ďalší
     .components-reconnect-failed        pokusy sa minuli
     .components-reconnect-paused        server reláciu uspal
     .components-reconnect-resume-failed prebudenie relácie zlyhalo
     .components-reconnect-rejected      reláciu už nemožno obnoviť
     .components-reconnect-hide          spojenie beží ďalej

   Čísla (poradie pokusu, odpočet) dopĺňa do prvkov s predpísanými `id`.
   Všetko ostatné je naše — vzhľad sa preto riadi tokenmi témy a prekrytie
   vyzerá rovnako doma v tmavej aj svetlej. */
.reconnect-overlay {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 2000;
    /* Priehľadný závoj namiesto plnej farby: cez rozostrenie presvitá rozpracovaná
       obrazovka aj pohyblivé pozadie, takže výpadok pôsobí ako pauza, nie ako pád. */
    background: color-mix(in srgb, var(--bg-body) 78%, transparent);
    backdrop-filter: blur(14px) saturate(120%);
    -webkit-backdrop-filter: blur(14px) saturate(120%);
    padding: 1.5rem;
    place-content: center;
    justify-items: center;
    animation: bm-fade var(--motion-base) var(--ease-out) both;
}

/* Jemné svetlo v značkovej farbe za kartou — to isté, čo aplikácia používa na
   zvýraznenie dôležitých kariet, len na celú obrazovku. */
.reconnect-overlay::before {
    content: "";
    position: absolute;
    inset: -20%;
    background: radial-gradient(circle at 50% 42%, var(--brand-glow) 0%, transparent 55%);
    animation: bm-reconnect-breathe 6s var(--ease-in-out) infinite;
    pointer-events: none;
}

.components-reconnect-show,
.components-reconnect-retrying,
.components-reconnect-failed,
.components-reconnect-paused,
.components-reconnect-resume-failed,
.components-reconnect-rejected {
    display: grid;
}

.components-reconnect-hide {
    display: none;
}

.reconnect-card {
    position: relative;
    width: min(30rem, 100%);
    box-sizing: border-box;
    display: grid;
    justify-items: center;
    gap: 1.5rem;
    padding: 2.5rem 2rem 2.25rem 2rem;
    text-align: center;
    background: var(--bg-card);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    animation: bm-pop var(--motion-slow) var(--ease-spring) both;
}

/* ── Obežnica ──
   Tri vlny vybiehajúce zo stredu a bod, ktorý okolo neho krúži. Je to jediná
   časť prekrytia, ktorá sa hýbe stále — má povedať „pracujem na tom“, preto je
   pomalá a nevýrazná. */
.reconnect-orbit {
    position: relative;
    width: 7rem;
    height: 7rem;
    display: grid;
    place-items: center;
}

.reconnect-orbit-ring {
    position: absolute;
    inset: 0;
    border: 2px solid var(--brand);
    border-radius: 50%;
    opacity: 0;
    animation: bm-reconnect-ripple 2.4s var(--ease-out) infinite;
}

.reconnect-orbit-ring:nth-child(2) {
    animation-delay: .8s;
}

.reconnect-orbit-ring:nth-child(3) {
    animation-delay: 1.6s;
}

.reconnect-orbit-core {
    position: relative;
    width: 3.75rem;
    height: 3.75rem;
    display: grid;
    place-items: center;
    border-radius: 50%;
    background: var(--accent-subtle);
    border: 1px solid var(--brand-line);
    color: var(--brand);
    font-size: 1.6rem;
}

/* Bod obiehajúci po dráhe. Otáča sa celý obal a bod je posunutý na okraj —
   vďaka tomu stačí jedna animácia a dráha ostane presne kruhová. */
.reconnect-orbit-dot {
    position: absolute;
    inset: 0;
    animation: bm-reconnect-spin 3.2s linear infinite;
}

.reconnect-orbit-dot::after {
    content: "";
    position: absolute;
    top: -.3rem;
    left: calc(50% - .3rem);
    width: .6rem;
    height: .6rem;
    border-radius: 50%;
    background: var(--brand);
    box-shadow: 0 0 .75rem var(--brand);
}

/* ── Prepínanie obsahu podľa stavu ──
   Karta obsahuje všetky tri texty naraz a CSS ukáže ten, ktorý sedí k stavu.
   Inak by sa museli meniť z JS, ktoré v odpojenej aplikácii nemá kto zavolať. */
.reconnect-icon,
.reconnect-state {
    display: none;
}

.components-reconnect-show .reconnect-icon-live,
.components-reconnect-retrying .reconnect-icon-live,
.components-reconnect-failed .reconnect-icon-failed,
.components-reconnect-rejected .reconnect-icon-failed,
.components-reconnect-resume-failed .reconnect-icon-failed,
.components-reconnect-paused .reconnect-icon-paused {
    display: block;
}

.components-reconnect-show .reconnect-state-rejoining,
.components-reconnect-retrying .reconnect-state-rejoining,
.components-reconnect-failed .reconnect-state-failed,
.components-reconnect-rejected .reconnect-state-failed,
.components-reconnect-resume-failed .reconnect-state-failed,
.components-reconnect-paused .reconnect-state-paused {
    display: grid;
    gap: .5rem;
    justify-items: center;
    width: 100%;
    animation: bm-rise var(--motion-base) var(--ease-out) backwards;
}

/* Keď sa už nepripája, pohyb nemá čo hlásiť — obežnica zastane a stred sa
   sfarbí, aby bolo na prvý pohľad jasné, že sa čaká na používateľa. */
.components-reconnect-failed .reconnect-orbit-ring,
.components-reconnect-rejected .reconnect-orbit-ring,
.components-reconnect-resume-failed .reconnect-orbit-ring,
.components-reconnect-paused .reconnect-orbit-ring,
.components-reconnect-failed .reconnect-orbit-dot,
.components-reconnect-rejected .reconnect-orbit-dot,
.components-reconnect-resume-failed .reconnect-orbit-dot,
.components-reconnect-paused .reconnect-orbit-dot {
    display: none;
}

.components-reconnect-failed .reconnect-orbit-core,
.components-reconnect-rejected .reconnect-orbit-core,
.components-reconnect-resume-failed .reconnect-orbit-core {
    background: var(--danger-subtle);
    border-color: color-mix(in srgb, var(--danger) 40%, transparent);
    color: var(--danger);
}

.components-reconnect-paused .reconnect-orbit-core {
    background: var(--warning-subtle);
    border-color: color-mix(in srgb, var(--warning) 40%, transparent);
    color: var(--warning);
}

/* ── Texty ── */
.reconnect-title {
    margin: 0;
    font-size: 1.35rem;
    font-weight: 600;
    color: var(--text-primary);
}

.reconnect-text {
    margin: 0;
    max-width: 24rem;
    font-size: .95rem;
    line-height: 1.5;
    color: var(--text-secondary);
}

.reconnect-meta {
    margin: .25rem 0 0 0;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: .35rem .75rem;
    font-size: .85rem;
    color: var(--text-muted);
}

/* Odpočet dáva zmysel len medzi pokusmi; pri prvom pokuse by ukazoval nulu. */
.reconnect-countdown {
    display: none;
}

.components-reconnect-retrying .reconnect-countdown {
    display: inline;
}

.reconnect-meta span[id] {
    color: var(--text-secondary);
    font-variant-numeric: tabular-nums;
}

/* ── Pás pod textom ──
   Nemeria priebeh (nikto nevie, kedy sa server ozve), len ubezpečuje, že sa
   niečo deje. Preto sa donekonečna prebehne z jednej strany na druhú. */
.reconnect-track {
    position: relative;
    width: min(18rem, 100%);
    height: 3px;
    margin-top: .5rem;
    border-radius: 999px;
    background: var(--border-subtle);
    overflow: hidden;
}

.reconnect-track-bar {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 40%;
    border-radius: inherit;
    background: linear-gradient(90deg, transparent, var(--brand), transparent);
    animation: bm-reconnect-sweep 1.8s var(--ease-in-out) infinite;
}

/* ── Tlačidlá ──
   Vlastné, nie zdieľané z Bootstrapu: prekrytie musí vyzerať rovnako na
   prihlasovacích obrazovkách aj vo vnútri aplikácie. */
.reconnect-actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: .6rem;
    margin-top: .75rem;
}

.reconnect-btn {
    display: inline-flex;
    align-items: center;
    gap: .45rem;
    padding: .55rem 1.15rem;
    font-size: .92rem;
    font-weight: 500;
    color: var(--text-primary);
    background: var(--bg-surface);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: background-color var(--motion-fast) var(--ease-out), border-color var(--motion-fast) var(--ease-out), transform var(--motion-press) var(--ease-out);
}

.reconnect-btn:hover {
    background: var(--nav-hover-bg);
    border-color: var(--brand-line);
}

.reconnect-btn:active {
    transform: translateY(1px);
}

.reconnect-btn-primary {
    color: #fff;
    background: var(--brand);
    border-color: var(--brand);
}

.reconnect-btn-primary:hover {
    background: var(--accent-hover);
    border-color: var(--accent-hover);
}

@keyframes bm-reconnect-ripple {
    0% {
        transform: scale(.42);
        opacity: 0;
    }

    15% {
        opacity: .55;
    }

    100% {
        transform: scale(1);
        opacity: 0;
    }
}

@keyframes bm-reconnect-spin {
    to {
        transform: rotate(360deg);
    }
}

@keyframes bm-reconnect-sweep {
    0% {
        transform: translateX(-110%);
    }

    100% {
        transform: translateX(260%);
    }
}

@keyframes bm-reconnect-breathe {
    0%, 100% {
        opacity: .55;
    }

    50% {
        opacity: 1;
    }
}

@media (max-width: 480px) {
    .reconnect-card {
        padding: 2rem 1.25rem;
    }

    .reconnect-orbit {
        width: 5.5rem;
        height: 5.5rem;
    }
}

/* Kto si vypol animácie, dostane statickú kartu — informácia ostáva rovnaká. */
@media (prefers-reduced-motion: reduce) {
    .reconnect-overlay,
    .reconnect-overlay::before,
    .reconnect-card,
    .reconnect-orbit-ring,
    .reconnect-orbit-dot,
    .reconnect-track-bar,
    .components-reconnect-show .reconnect-state-rejoining,
    .components-reconnect-retrying .reconnect-state-rejoining,
    .components-reconnect-failed .reconnect-state-failed,
    .components-reconnect-paused .reconnect-state-paused {
        animation: none;
    }

    .reconnect-orbit-ring {
        opacity: .3;
    }
}
