/*
 * Branded loading + transition system (shared mechanics, per-brand theming).
 *
 * Per-app theming is driven by two custom properties set on :root in each app's
 * App.razor <head> (so the boot overlay is themed before app.css even loads):
 *   --brand-mark : url(...) of the app's icon PNG  (REQUIRED, no default below)
 *   --brand-accent : the spinner ring / progress-bar color
 *   --brand-boot-bg : full-screen boot overlay background
 *
 * Three loading moments, three treatments:
 *   A. Cold boot      -> #app-boot full-screen branded overlay (this file)
 *   B. Route nav      -> #nav-progress bar + .brand-spinner in <Navigating>
 *   C. In-page data    -> skeletons (Placeholder/*Skeleton), NOT a spinner
 */

:root {
    --brand-accent: #7b1e3b;          /* wine default; per-app override */
    --brand-boot-bg: #faf7f3;
    --brand-spinner-size: 64px;
}

/* ---- The branded mark spinner (reused by boot overlay + <Navigating>) ---- */
.brand-spinner {
    position: relative;
    width: var(--brand-spinner-size);
    height: var(--brand-spinner-size);
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

/* The logo mark: a circular "coin" filling the ring, breathing in and out.
   Clipping to a circle (cover + border-radius) keeps icons that ship with an
   opaque square background (most of them) from showing as a square-in-a-circle;
   transparent marks (e.g. Vinelog) simply fill the coin. */
.brand-spinner__mark {
    width: 82%;
    height: 82%;
    background-image: var(--brand-mark);
    background-size: cover;
    background-repeat: no-repeat;
    background-position: center;
    border-radius: 50%;
    animation: brand-breathe 1.6s ease-in-out infinite;
}

/* A thin arc ring rotating around the mark for continuous motion. */
.brand-spinner::before {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: 50%;
    border: 2px solid color-mix(in srgb, var(--brand-accent) 18%, transparent);
    border-top-color: var(--brand-accent);
    animation: brand-spin 0.9s linear infinite;
}

@keyframes brand-spin {
    to { transform: rotate(360deg); }
}

@keyframes brand-breathe {
    0%, 100% { transform: scale(0.92); opacity: 0.75; }
    50%      { transform: scale(1.0);  opacity: 1; }
}

/* ---- A. Cold-boot overlay ---- */
#app-boot {
    position: fixed;
    inset: 0;
    z-index: 2147483646;          /* above everything except the reconnect modal */
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1.1rem;
    background: var(--brand-boot-bg);
    opacity: 1;
    transition: opacity 0.45s ease;
}

#app-boot .brand-spinner {
    --brand-spinner-size: 88px;
}

#app-boot .app-boot__wordmark {
    font-size: 0.82rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: color-mix(in srgb, var(--brand-accent) 70%, #6b6b6b);
    opacity: 0.85;
}

/* Hidden once the circuit is live (toggled by brand-loading.js). */
#app-boot.app-boot--done {
    opacity: 0;
    pointer-events: none;
}

/* ---- B. Top navigation progress bar ----
   The bar element is created by js/nav-progress.js. These styles are
   self-contained (accent-driven) so any surface that ships brand-loading.css +
   nav-progress.js gets a themed bar with no app.css dependency. */
.nav-progress {
    position: fixed;
    top: 0;
    left: 0;
    height: 3px;
    width: 0;
    z-index: 10001;
    background: linear-gradient(to right,
        var(--brand-accent),
        color-mix(in srgb, var(--brand-accent) 55%, #fff),
        var(--brand-accent));
    box-shadow: 0 0 8px color-mix(in srgb, var(--brand-accent) 50%, transparent);
    opacity: 0;
    transition: width 180ms ease, opacity 200ms ease;
    pointer-events: none;
}
.nav-progress.is-active { opacity: 1; }
.nav-progress.is-done {
    opacity: 0;
    transition: width 120ms ease, opacity 260ms ease 80ms;
}

/* The branded spinner shown when a navigation exceeds the slow-nav threshold
   (armed/cleared by js/nav-progress.js around its start()/done()). */
#nav-spinner {
    position: fixed;
    inset: 0;
    z-index: 2147483644;
    display: flex;
    align-items: center;
    justify-content: center;
    background: color-mix(in srgb, var(--brand-boot-bg) 70%, transparent);
    backdrop-filter: blur(2px);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.25s ease;
}

#nav-spinner.nav-spinner--active {
    opacity: 1;
}

/* The Router <Navigating> fragment host (BrandSpinner.razor) */
.brand-navigating {
    position: fixed;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: color-mix(in srgb, var(--brand-boot-bg) 70%, transparent);
    z-index: 1200;
}

/* ---- Page transition: fade each route in on navigation ---- */
.page-fade {
    animation: page-fade-in 0.32s ease both;
}

@keyframes page-fade-in {
    from { opacity: 0; transform: translateY(6px); }
    to   { opacity: 1; transform: translateY(0); }
}

/* Content that streams in (StreamRendering) fades rather than popping. */
.stream-fade {
    animation: stream-fade-in 0.4s ease both;
}

@keyframes stream-fade-in {
    from { opacity: 0; }
    to   { opacity: 1; }
}

/* ---- Respect reduced-motion: drop transforms/spins, keep simple fades ---- */
@media (prefers-reduced-motion: reduce) {
    .brand-spinner::before { animation: brand-spin 1.6s linear infinite; }
    .brand-spinner__mark,
    .page-fade,
    .stream-fade { animation: none; }
    #app-boot, #nav-spinner { transition: opacity 0.2s ease; }
    .nav-progress { transition: opacity 120ms linear; }
}
