/* ============================================================================
 * login-background.css — v2.8.161
 *
 * Cinematic custom background system for the login page + optional app-wide
 * background. All effects respect the navbar perf-tier picker and the OS
 * prefers-reduced-motion preference.
 *
 * Layered structure (back-to-front):
 *   .ts-login-bg
 *     .ts-login-bg__image      — the photo (animated)
 *     .ts-login-bg__overlay    — solid dim color
 *     .ts-login-bg__vignette   — radial darkening at edges
 *     .ts-login-bg__grain      — SVG fractal noise
 *     .ts-login-bg__chromatic  — RGB-split aberration tint
 *
 * Animation keyed via data-anim + data-speed attributes on the root.
 * ============================================================================ */

/* ───────────────────────────────────────────────────────────────────────
 * LOGIN BACKGROUND — full viewport fixed layer, z-index below all content
 * ─────────────────────────────────────────────────────────────────────── */
.ts-login-bg,
.ts-bg-preview {
    --anim-duration: 30s;
    --anim-timing: ease-in-out;
}
.ts-login-bg {
    position: fixed;
    inset: 0;
    z-index: 0;
    overflow: hidden;
    pointer-events: none;
    background: linear-gradient(180deg, var(--bg-gradient-top, #0f172a) 0%, var(--bg-gradient-bottom, #020617) 100%);
}
.ts-login-bg__layer {
    position: absolute;
    inset: 0;
    pointer-events: none;
    will-change: transform, opacity;
}
.ts-login-bg__image,
.ts-bg-preview .ts-bg-image {
    background-image: var(--bg-url, none);
    background-position: var(--bg-position, center center);
    background-size: var(--bg-size, cover);
    background-repeat: no-repeat;
    filter: blur(var(--bg-blur, 0px));
    transform-origin: center center;
}
.ts-login-bg__overlay,
.ts-bg-preview .ts-bg-overlay {
    background-color: var(--bg-overlay-color, #020617);
    opacity: var(--bg-overlay-opacity, 0.55);
}
.ts-login-bg__vignette,
.ts-bg-preview .ts-bg-vignette {
    box-shadow: inset 0 0 220px 60px rgba(0, 0, 0, 0.65);
}
.ts-login-bg__grain,
.ts-bg-preview .ts-bg-grain {
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/></filter><rect width='100%25' height='100%25' filter='url(%23n)' opacity='0.4'/></svg>");
    mix-blend-mode: overlay;
    opacity: 0.45;
}
.ts-login-bg__chromatic,
.ts-bg-preview .ts-bg-chromatic {
    background:
        linear-gradient(120deg, rgba(255, 50, 100, 0.06) 0%, transparent 25%, rgba(40, 200, 255, 0.06) 100%);
    mix-blend-mode: screen;
}

/* ───────────────────────────────────────────────────────────────────────
 * ANIMATIONS — selected via data-anim on .ts-login-bg or .ts-bg-preview
 * Duration scales via data-speed (slow=30s, medium=15s, fast=8s).
 * ─────────────────────────────────────────────────────────────────────── */
[data-speed="slow"]   { --anim-duration: 30s; }
[data-speed="medium"] { --anim-duration: 15s; }
[data-speed="fast"]   { --anim-duration: 8s; }

[data-anim="ken-burns"] .ts-login-bg__image,
[data-anim="ken-burns"] .ts-bg-image,
[data-anim="cinematic"] .ts-login-bg__image,
[data-anim="cinematic"] .ts-bg-image {
    animation: tsBgKenBurns var(--anim-duration) var(--anim-timing) infinite alternate;
}
[data-anim="zoom-in"] .ts-login-bg__image,
[data-anim="zoom-in"] .ts-bg-image {
    animation: tsBgZoomIn var(--anim-duration) var(--anim-timing) infinite alternate;
}
[data-anim="pan-left"] .ts-login-bg__image,
[data-anim="pan-left"] .ts-bg-image {
    animation: tsBgPanLeft var(--anim-duration) linear infinite alternate;
}
[data-anim="pan-right"] .ts-login-bg__image,
[data-anim="pan-right"] .ts-bg-image {
    animation: tsBgPanRight var(--anim-duration) linear infinite alternate;
}
[data-anim="pulse"] .ts-login-bg__image,
[data-anim="pulse"] .ts-bg-image {
    animation: tsBgPulse calc(var(--anim-duration) * 0.4) ease-in-out infinite;
}
[data-anim="cinematic"] .ts-login-bg__overlay,
[data-anim="cinematic"] .ts-bg-overlay {
    animation: tsBgOverlayBreath calc(var(--anim-duration) * 0.6) ease-in-out infinite alternate;
}

/* Parallax tilt — driven by JS mouse move, no CSS keyframe needed */
[data-anim="parallax"] .ts-login-bg__image,
[data-anim="parallax"] .ts-bg-image {
    transition: transform 0.35s cubic-bezier(0.16, 1, 0.3, 1);
}

@keyframes tsBgKenBurns {
    0%   { transform: scale(1.0) translate(0, 0); }
    50%  { transform: scale(1.12) translate(-2%, -1.5%); }
    100% { transform: scale(1.18) translate(2%, 1%); }
}
@keyframes tsBgZoomIn {
    0%   { transform: scale(1.0); }
    100% { transform: scale(1.22); }
}
@keyframes tsBgPanLeft {
    0%   { transform: translateX(0) scale(1.08); }
    100% { transform: translateX(-3%) scale(1.08); }
}
@keyframes tsBgPanRight {
    0%   { transform: translateX(0) scale(1.08); }
    100% { transform: translateX(3%) scale(1.08); }
}
@keyframes tsBgPulse {
    0%, 100% { filter: blur(var(--bg-blur, 0px)) brightness(1.0); }
    50%      { filter: blur(var(--bg-blur, 0px)) brightness(1.12); }
}
@keyframes tsBgOverlayBreath {
    0%   { opacity: var(--bg-overlay-opacity, 0.55); }
    100% { opacity: calc(var(--bg-overlay-opacity, 0.55) * 0.78); }
}

/* ───────────────────────────────────────────────────────────────────────
 * PERFORMANCE TIER + REDUCED MOTION — kill all animations
 * Static still image always preserves the visual.
 * ─────────────────────────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
    .ts-login-bg__image, .ts-login-bg__overlay,
    .ts-bg-image, .ts-bg-overlay {
        animation: none !important;
        transform: none !important;
    }
}
body[data-perf-tier="saver"] .ts-login-bg__image,
body[data-perf-tier="saver"] .ts-login-bg__overlay,
body[data-perf-tier="saver"] .ts-login-bg__grain,
body[data-perf-tier="saver"] .ts-login-bg__chromatic {
    animation: none !important;
    transform: none !important;
}
/* Saver tier: drop grain + chromatic (cheaper paint) */
body[data-perf-tier="saver"] .ts-login-bg__grain,
body[data-perf-tier="saver"] .ts-login-bg__chromatic { display: none; }

/* ───────────────────────────────────────────────────────────────────────
 * APP-WIDE BACKGROUND — behind the main content of every authenticated page
 * Heavily blurred + dimmed by default to keep cards readable.
 * ─────────────────────────────────────────────────────────────────────── */
.ts-app-bg {
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background-color: transparent;
}
.ts-app-bg__image {
    position: absolute;
    inset: 0;
    background-image: var(--app-bg-url, none);
    background-position: center center;
    background-size: cover;
    background-repeat: no-repeat;
    opacity: calc(var(--app-bg-opacity, 8) / 100);
    filter: blur(var(--app-bg-blur, 12px));
}
.ts-app-bg__dim {
    position: absolute;
    inset: 0;
    background: rgba(2, 6, 23, calc(var(--app-bg-dim, 40) / 100));
}
[data-bs-theme="light"] .ts-app-bg__dim {
    background: rgba(255, 255, 255, calc(var(--app-bg-dim, 40) / 100));
}
.ts-app-bg--fixed { position: fixed; }
.ts-app-bg--scroll { position: absolute; }

body[data-perf-tier="saver"] .ts-app-bg__image {
    filter: none;
}

/* ───────────────────────────────────────────────────────────────────────
 * Z-INDEX SAFETY — the login form card MUST stay above the background
 * ─────────────────────────────────────────────────────────────────────── */
.ts-login-bg + main,
body:has(.ts-login-bg) main { position: relative; z-index: 1; }
