/* Shared branded loading screen for desktop, mobile and authentication. */
#loader-overlay,
.app-loader-overlay {
    position: fixed;
    inset: 0;
    z-index: 99999;
    overflow: hidden;
    isolation: isolate;
    opacity: 1;
    visibility: visible;
    background:
        radial-gradient(circle at 50% 46%, var(--accent-red-glow-medium) 0, transparent 19rem),
        linear-gradient(145deg, #08080a 0%, #0d090b 48%, #050506 100%);
    transition: opacity var(--loader-fade-duration, .32s) ease,
                visibility var(--loader-fade-duration, .32s) ease;
}

#loader-overlay::before,
.app-loader-overlay::before {
    content: "";
    position: absolute;
    width: min(76vw, 42rem);
    aspect-ratio: 1;
    border: 1px solid color-mix(in srgb, var(--accent-red) 10%, transparent);
    border-radius: 50%;
    box-shadow:
        0 0 0 5rem color-mix(in srgb, var(--accent-red) 1.7%, transparent),
        0 0 0 10rem color-mix(in srgb, var(--accent-red) 1%, transparent);
    animation: loaderOrbit 4.8s ease-in-out infinite;
    pointer-events: none;
}

#loader-overlay::after,
.app-loader-overlay::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    opacity: .18;
    background-image:
        linear-gradient(rgba(255,255,255,.022) 1px, transparent 1px),
        linear-gradient(90deg, rgba(255,255,255,.022) 1px, transparent 1px);
    background-size: 3.25rem 3.25rem;
    -webkit-mask-image: radial-gradient(circle at center, #000, transparent 70%);
    mask-image: radial-gradient(circle at center, #000, transparent 70%);
    pointer-events: none;
}

#loader-overlay.is-fading,
.app-loader-overlay.is-fading {
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
}

#loader-overlay .loader-logo-container,
#loader-overlay .app-loader-logo-wrap,
.app-loader-overlay .app-loader-logo-wrap {
    position: relative;
    z-index: 1;
    width: 6.75rem;
    height: 7.7rem;
    margin: 0 0 .85rem;
    display: flex;
    align-items: center;
    justify-content: center;
    filter: drop-shadow(0 .8rem 2rem rgba(0,0,0,.55));
}

#loader-overlay .loader-logo-container::before,
#loader-overlay .app-loader-logo-wrap::before,
.app-loader-overlay .app-loader-logo-wrap::before {
    content: "";
    position: absolute;
    inset: .45rem .05rem;
    z-index: -1;
    border-radius: 2rem;
    border: 1px solid color-mix(in srgb, var(--accent-red) 25%, transparent);
    background: linear-gradient(145deg, rgba(255,255,255,.055), rgba(255,255,255,.012));
    box-shadow: inset 0 1px rgba(255,255,255,.07), 0 0 2.5rem var(--accent-red-glow-weak);
    transform: rotate(8deg);
}

#loader-overlay .app-loader-mark,
.app-loader-overlay .app-loader-mark {
    width: 4.55rem;
    height: 5.8rem;
    overflow: visible;
}

#loader-overlay .app-loader-mark-trace,
.app-loader-overlay .app-loader-mark-trace {
    stroke-dasharray: 420;
    stroke-dashoffset: 420;
    animation: loaderMarkPremium 1.9s cubic-bezier(.65,0,.35,1) infinite;
}

.loader-brand-copy {
    z-index: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    margin-bottom: 1.55rem;
    line-height: 1;
    user-select: none;
}

.loader-brand-name {
    color: #f8f7f8;
    font: 750 1rem/1.2 'Onest', "Segoe UI", sans-serif;
    letter-spacing: -.02em;
}

.loader-brand-name span { color: var(--accent-red-bright); }

.loader-brand-caption {
    margin-top: .62rem;
    color: #77737c;
    font: 650 .52rem/1.2 'Onest', "Segoe UI", sans-serif;
    letter-spacing: .25em;
    text-transform: uppercase;
}

#loader-overlay .progress-container,
#loader-overlay .app-loader-track,
.app-loader-overlay .app-loader-track {
    z-index: 1;
    width: min(10.5rem, 46vw);
    height: 2px;
    margin: 0;
    overflow: visible;
    border: 0;
    border-radius: 999px;
    background: rgba(255,255,255,.08);
}

#loader-overlay .progress-bar,
#loader-overlay .app-loading-bar,
.app-loader-overlay .app-loading-bar {
    position: relative;
    width: 100% !important;
    height: 100%;
    border-radius: inherit;
    background: linear-gradient(90deg, var(--accent-red-dim), var(--accent-red-bright));
    box-shadow: 0 0 1.2rem var(--accent-red-glow);
    transform: translateZ(0) scaleX(var(--loader-scale, 0));
    transform-origin: left center;
    transition: transform var(--loader-progress-duration, .72s) cubic-bezier(.22, 1, .36, 1);
    will-change: transform;
    backface-visibility: hidden;
}

#loader-overlay .progress-bar.is-loaded,
#loader-overlay .app-loading-bar.is-loaded,
.app-loader-overlay .app-loading-bar.is-loaded { --loader-scale: 1; }

#loader-overlay .progress-bar::after,
#loader-overlay .app-loading-bar::after,
.app-loader-overlay .app-loading-bar::after {
    content: "";
    position: absolute;
    top: 50%;
    right: -.18rem;
    width: .34rem;
    height: .34rem;
    border-radius: 50%;
    background: #fff;
    box-shadow: 0 0 .8rem var(--accent-red-bright);
    transform: translateY(-50%);
}

@keyframes loaderMarkPremium {
    0% { stroke-dashoffset: 420; opacity: .25; }
    43%, 68% { stroke-dashoffset: 0; opacity: 1; }
    100% { stroke-dashoffset: -420; opacity: .25; }
}

@keyframes loaderOrbit {
    0%, 100% { transform: scale(.96); opacity: .55; }
    50% { transform: scale(1.035); opacity: .9; }
}

/* A continuous spinner is smoother than a milestone-based progress bar. */
#loader-overlay .progress-container,
#loader-overlay .app-loader-track,
.app-loader-overlay .app-loader-track {
    width: 1.85rem;
    height: 1.85rem;
    overflow: visible;
    border: 2px solid rgba(255,255,255,.09);
    border-radius: 50%;
    background: transparent;
    box-shadow: inset 0 0 .8rem rgba(0,0,0,.25);
    animation: loaderSpinner .78s linear infinite;
    will-change: transform;
    backface-visibility: hidden;
}

#loader-overlay .progress-container::after,
#loader-overlay .app-loader-track::after,
.app-loader-overlay .app-loader-track::after {
    content: "";
    position: absolute;
    inset: -2px;
    border: 2px solid transparent;
    border-top-color: var(--accent-red-bright);
    border-right-color: color-mix(in srgb, var(--accent-red) 38%, transparent);
    border-radius: 50%;
    filter: drop-shadow(0 0 .35rem var(--accent-red-glow));
}

#loader-overlay .progress-bar,
#loader-overlay .app-loading-bar,
.app-loader-overlay .app-loading-bar { opacity: 0; }

@keyframes loaderSpinner {
    to { transform: translateZ(0) rotate(360deg); }
}

@media (max-width: 600px) {
    #loader-overlay::before,
    .app-loader-overlay::before { width: 90vw; }
    #loader-overlay .loader-logo-container,
    #loader-overlay .app-loader-logo-wrap,
    .app-loader-overlay .app-loader-logo-wrap { width: 6rem; height: 7rem; }
    .loader-brand-name { font-size: .92rem; }
}

@media (prefers-reduced-motion: reduce) {
    #loader-overlay::before,
    .app-loader-overlay::before,
    #loader-overlay .progress-container,
    #loader-overlay .app-loader-track,
    .app-loader-overlay .app-loader-track,
    #loader-overlay .app-loader-mark-trace,
    .app-loader-overlay .app-loader-mark-trace { animation: none; }
    #loader-overlay .app-loader-mark-trace,
    .app-loader-overlay .app-loader-mark-trace { stroke-dashoffset: 0; opacity: 1; }
}

/* ------------------------------------------------------------------
   Mosaïque : des pixels tombent un à un et composent le B, puis
   « Backend Social » s'écrit. Les autres designs sont gardés dans
   docs/loader-designs/.
   ------------------------------------------------------------------ */
#loader-overlay .loader-logo-container,
#loader-overlay .app-loader-logo-wrap,
.app-loader-overlay .app-loader-logo-wrap {
    width: auto;
    height: auto;
    margin: 0 0 1.35rem;
    filter: none;
}

#loader-overlay .loader-logo-container::before,
#loader-overlay .app-loader-logo-wrap::before,
.app-loader-overlay .app-loader-logo-wrap::before { display: none; }

.app-loader-mosaic {
    display: grid;
    grid-template-columns: repeat(5, .95rem);
    gap: .32rem;
    filter: drop-shadow(0 0 1.1rem var(--accent-red-glow-weak));
}

.app-loader-mosaic b {
    width: .95rem;
    height: .95rem;
    border-radius: .26rem;
}

.app-loader-mosaic b.on {
    background: linear-gradient(145deg, var(--accent-red-bright), var(--accent-red));
    opacity: 0;
    transform: translateY(-1.1rem) scale(.4);
    animation: loaderMosaicDrop 3.4s cubic-bezier(.3, 1.4, .5, 1) infinite;
    animation-delay: var(--d, 0s);
    will-change: transform, opacity;
}

.loader-brand-name { display: flex; }
.loader-brand-name span { color: inherit; }
.loader-brand-name > span,
.loader-brand-name .loader-brand-accent > span {
    display: inline-block;
    opacity: 0;
    animation: loaderMosaicLetter 3.4s ease infinite;
    /* Le nom apparaît presque tout de suite : sur un rechargement rapide le
       chargeur disparaît vers 1 s, le nom devait donc être lisible avant. */
    animation-delay: calc(.25s + var(--i, 0) * .03s);
}
.loader-brand-name .loader-brand-accent { display: inline-flex; opacity: 1; animation: none; color: var(--accent-red-bright); }

/* La mosaïque indique déjà le chargement : le spinner devient superflu. */
#loader-overlay .progress-container,
#loader-overlay .app-loader-track,
.app-loader-overlay .app-loader-track { display: none; }

@keyframes loaderMosaicDrop {
    0% { opacity: 0; transform: translateY(-1.1rem) scale(.4); }
    10%, 82% { opacity: 1; transform: none; }
    94%, 100% { opacity: 0; transform: scale(.6); }
}

@keyframes loaderMosaicLetter {
    0% { opacity: 0; transform: translateY(.35rem); }
    5%, 50% { opacity: 1; transform: none; }
    /* Sort avec les pixels (fin de boucle), sans déborder sur la suivante. */
    60%, 100% { opacity: 0; transform: none; }
}

@media (max-width: 600px) {
    .app-loader-mosaic { grid-template-columns: repeat(5, .82rem); gap: .28rem; }
    .app-loader-mosaic b { width: .82rem; height: .82rem; }
}

@media (prefers-reduced-motion: reduce) {
    .app-loader-mosaic b.on,
    .loader-brand-name > span,
    .loader-brand-name .loader-brand-accent > span { animation: none; opacity: 1; transform: none; }
}

/* Délais de la mosaïque et des lettres : la CSP (style-src sans
   'unsafe-inline') bloque les attributs style="", ils sont donc ici. */
.app-loader-mosaic b:nth-child(1) { --d: 0.000s; }
.app-loader-mosaic b:nth-child(2) { --d: 0.045s; }
.app-loader-mosaic b:nth-child(3) { --d: 0.090s; }
.app-loader-mosaic b:nth-child(4) { --d: 0.135s; }
.app-loader-mosaic b:nth-child(6) { --d: 0.180s; }
.app-loader-mosaic b:nth-child(10) { --d: 0.225s; }
.app-loader-mosaic b:nth-child(11) { --d: 0.270s; }
.app-loader-mosaic b:nth-child(15) { --d: 0.315s; }
.app-loader-mosaic b:nth-child(16) { --d: 0.360s; }
.app-loader-mosaic b:nth-child(17) { --d: 0.405s; }
.app-loader-mosaic b:nth-child(18) { --d: 0.450s; }
.app-loader-mosaic b:nth-child(19) { --d: 0.495s; }
.app-loader-mosaic b:nth-child(21) { --d: 0.540s; }
.app-loader-mosaic b:nth-child(25) { --d: 0.585s; }
.app-loader-mosaic b:nth-child(26) { --d: 0.630s; }
.app-loader-mosaic b:nth-child(30) { --d: 0.675s; }
.app-loader-mosaic b:nth-child(31) { --d: 0.720s; }
.app-loader-mosaic b:nth-child(32) { --d: 0.765s; }
.app-loader-mosaic b:nth-child(33) { --d: 0.810s; }
.app-loader-mosaic b:nth-child(34) { --d: 0.855s; }
.loader-brand-name > span:nth-child(1) { --i: 0; }
.loader-brand-name > span:nth-child(2) { --i: 1; }
.loader-brand-name > span:nth-child(3) { --i: 2; }
.loader-brand-name > span:nth-child(4) { --i: 3; }
.loader-brand-name > span:nth-child(5) { --i: 4; }
.loader-brand-name > span:nth-child(6) { --i: 5; }
.loader-brand-name > span:nth-child(7) { --i: 6; }
.loader-brand-name > span:nth-child(8) { --i: 7; }
.loader-brand-name .loader-brand-accent > span:nth-child(1) { --i: 8; }
.loader-brand-name .loader-brand-accent > span:nth-child(2) { --i: 9; }
.loader-brand-name .loader-brand-accent > span:nth-child(3) { --i: 10; }
.loader-brand-name .loader-brand-accent > span:nth-child(4) { --i: 11; }
.loader-brand-name .loader-brand-accent > span:nth-child(5) { --i: 12; }
.loader-brand-name .loader-brand-accent > span:nth-child(6) { --i: 13; }
