/* ============================================================================
   portal-loader.css — loading feedback for the staff portal.

   Paired with wwwroot/portal/js/portal-loader.js. Loaded from
   Views/Shared/portal/head.cshtml, so it reaches the 3 portal layouts.

   Two indicators:
     .portal-loadbar  thin top bar, shown while requests are in flight
     .preloader       the theme's existing full-screen overlay, re-shown
                      during page navigation (no rules redefined here, only
                      a fade-in modifier)
   ============================================================================ */

/* ── Top progress bar ──────────────────────────────────────────────────────
   z-index sits above the whole modal stack: bootstrap modal 1055, SweetAlert
   1060, _swalZIndexAboveModals() lifts to ~1105+. Saves fire from inside
   modals constantly, so the bar has to clear them. Stays below .preloader
   (99999) so the navigation overlay always wins. */
.portal-loadbar {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    height: 3px;
    z-index: 99998;
    pointer-events: none;
    opacity: 0;
    background: transparent;
    transition: opacity .2s ease;
    overflow: hidden;
}

.portal-loadbar.is-active { opacity: 1; }

.portal-loadbar__glow {
    display: block;
    height: 100%;
    width: 40%;
    border-radius: 0 3px 3px 0;
    background: var(--bs-primary, #ff6600);
    box-shadow: 0 0 10px 0 var(--bs-primary, #ff6600);
    animation: portal-loadbar-sweep 1.1s ease-in-out infinite;
}

@keyframes portal-loadbar-sweep {
    0%   { transform: translateX(-100%); }
    100% { transform: translateX(350%); }
}

/* An orange bloom reads harsher on a dark body — soften the glow only. The bar
   colour itself is var(--bs-primary), which is already theme-aware. */
[data-bs-theme="dark"] .portal-loadbar__glow {
    box-shadow: 0 0 8px 0 rgba(255, 102, 0, .55);
}

/* ── Double-submit guard ───────────────────────────────────────────────────
   Replaces protection that existed only as a side effect of the old blocking
   modal. While a write is in flight, submit-ish controls stop accepting
   clicks. Everything else on the page stays usable and scrollable.
   portal-loader.js guarantees this class is always removed — on completion,
   on error, and via its reaper if a success handler throws. */
body.portal-busy button[type="submit"],
body.portal-busy .btn-primary,
body.portal-busy [data-portal-guard] {
    pointer-events: none;
    opacity: .65;
    cursor: progress;
}

/* Opt-out for controls that must stay live during a request (e.g. a Cancel or
   Abort button that is meant to interrupt the very request in flight). */
body.portal-busy [data-portal-guard="off"] {
    pointer-events: auto;
    opacity: 1;
    cursor: pointer;
}

/* ── Navigation overlay ────────────────────────────────────────────────────
   .preloader already has its geometry and a theme-aware background
   (var(--bs-body-bg)) from the purchased theme's _spinner.scss. Nothing here
   redefines those — this only fades it back in when we re-show it, so it does
   not hard-cut on a link click. */
.preloader.portal-preloader--nav {
    animation: portal-preloader-fade .18s ease-in;
}

@keyframes portal-preloader-fade {
    from { opacity: 0; }
    to   { opacity: 1; }
}

/* ── Reduced motion ────────────────────────────────────────────────────────
   Keep the indicator, drop the movement. */
@media (prefers-reduced-motion: reduce) {
    .portal-loadbar__glow {
        animation: none;
        width: 100%;
        opacity: .7;
    }
    .preloader.portal-preloader--nav { animation: none; }
}

/* Never let either indicator reach paper. */
@media print {
    .portal-loadbar,
    .preloader { display: none !important; }
}
