/* ============================================================
   LOADER.CSS — Écran de chargement de marque (home + arcade)
   Partagé par templates/utils/loader.html, piloté par loader.js.
   N'apparaît que sur une visite « fraîche » (décision serveur :
   aucune page du site vue depuis > 30 min). Couvre le 1er paint,
   attend les polices, puis se lève.
   Correction critique : DOUBLE filet de sécurité — @keyframes CSS
   à 4s + timeout JS à 3,5s → ne reste JAMAIS bloqué.
   Masqué sous prefers-reduced-motion.
   ============================================================ */
body.is-loading { overflow: hidden; }

.luv-loader {
    position: fixed;
    inset: 0;
    z-index: 9500; /* au-dessus de tout : navbar 1100, modales 2000, toasts 5000, chatbot 9400 */
    display: grid;
    place-items: center;
    /* Marine profond par défaut (site principal). Surchargé en casino ci-dessous. */
    background: radial-gradient(120% 90% at 50% 40%, #0e1c38 0%, #060d1c 62%, #04091a 100%);
    /* Filet PUR CSS : si le JS ne se déclenche jamais, on se lève à 4s. */
    animation: luvLoaderFailsafe 0.6s ease 4s forwards;
}
.luv-loader[hidden] { display: none; }

/* Navigation interne (voile déjà vu dans cette session d'onglet) : le script de
   tête pose .loader-seen sur <html> AVANT peinture → masqué sans aucun flash.
   sessionStorage étant per-origin, le site principal et l'arcade sont distincts. */
html.loader-seen .luv-loader { display: none !important; }

/* Casino (arcade.luvreizel.com) : fond quasi-noir légèrement chaud. */
body.theme-casino .luv-loader {
    background: radial-gradient(120% 90% at 50% 40%, #17150e 0%, #0a0a07 60%, #050504 100%);
}

.luv-loader-inner {
    display: grid;
    justify-items: center;
    gap: 26px;
    animation: luvLoaderPulse 2.4s ease-in-out infinite;
}
.luv-loader-logo-wrap {
    position: relative;
    display: grid;
    place-items: center;
    width: clamp(60px, 13vw, 84px);
    aspect-ratio: 1;
}
.luv-loader-halo {
    position: absolute;
    inset: -30%;
    border-radius: 50%;
    background: radial-gradient(circle at 50% 48%,
        rgba(255, 184, 0, 0.30), rgba(255, 138, 31, 0.10) 45%, transparent 70%);
    filter: blur(18px);
    animation: luvLoaderHalo 2.4s ease-in-out infinite;
}
.luv-loader-logo {
    position: relative;
    width: 100%;
    height: auto;
    object-fit: contain;
    filter: drop-shadow(0 10px 22px rgba(0, 0, 0, 0.55));
}
.luv-loader-bar {
    position: relative;
    width: clamp(120px, 30vw, 180px);
    height: 3px;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.08);
    overflow: hidden;
}
.luv-loader-bar span {
    position: absolute;
    top: 0;
    left: -40%;
    height: 100%;
    width: 40%;
    border-radius: inherit;
    background: linear-gradient(90deg, transparent, var(--luv-orange, #FFB800), transparent);
    animation: luvLoaderSweep 1.15s cubic-bezier(0.4, 0, 0.2, 1) infinite;
}
/* Sortie déclenchée par le JS (rapide) — remplace le failsafe. */
.luv-loader.is-done {
    animation: luvLoaderOut 0.55s cubic-bezier(0.22, 1, 0.36, 1) forwards;
    pointer-events: none;
}

@keyframes luvLoaderSweep    { 0% { left: -40%; } 100% { left: 100%; } }
@keyframes luvLoaderPulse    { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-4px); } }
@keyframes luvLoaderHalo     { 0%, 100% { opacity: 0.7; transform: scale(1); } 50% { opacity: 1; transform: scale(1.08); } }
@keyframes luvLoaderOut      { to { opacity: 0; visibility: hidden; } }
@keyframes luvLoaderFailsafe { to { opacity: 0; visibility: hidden; pointer-events: none; } }

/* Rendu lent (html.no-hwaccel, posé par le script de tête / loader.js / perf-degrade.js) :
   le halo flouté animé en boucle est saccadé sans accélération graphique → on le fige
   (le voile reste net, et sa sortie se fait en simple fondu, cf. loader.js). */
html.no-hwaccel .luv-loader-halo { animation: none; }

/* Profils sensibles au mouvement : aucun voile, contenu immédiat. */
@media (prefers-reduced-motion: reduce) {
    .luv-loader { display: none !important; }
}
