/* ==========================================================================
   LOADER - CANONICAL (single source of truth)
   --------------------------------------------------------------------------
   Supersedes: loader.css + the inline <style id="si-loader-gif-bg"> blocks
   and the decorative pre-paint blocks that used to live in
   _User_Layout.cshtml / _Admin_Layout.cshtml.

   Loaded in <head> AFTER the theme (site.min.css) so it wins without an
   !important arms race. Behaviour is driven by loader.js.

   Tiered loaders (right loader for the job):
     1. Cold-boot splash      -> #loading-wrap  (full screen, branded Cloud.gif)
                                  shown ONCE per tab session (html.si-booted
                                  hides it on subsequent in-app navigations).
     2. In-app navigation      -> NProgress top bar (loader.js). animsition's
                                  own full-page overlay is neutralised below.
     3. Table search/filter    -> .dataTables_processing (table-local text).
     4. Button / inline action -> .spinner-border (brand green).

   Brand tokens: green #3FA92B, navy #0F1014 / rgba(15,23,42,*).
   ========================================================================== */


/* ==========================================================================
   1) COLD-BOOT SPLASH  (#loading-wrap)
   --------------------------------------------------------------------------
   A plain fixed full-viewport overlay with a very high z-index. Because it
   is a direct child of <body> with position:fixed it covers the topnav +
   sidebar on its own - NO :has() z-index suppression hacks needed.
   ========================================================================== */
html body #loading-wrap,
html body .loader-overlay#loading-wrap {
    position: fixed !important;
    top: 0 !important;
    left: 0 !important;
    right: 0 !important;
    bottom: 0 !important;
    width: 100% !important;
    height: 100% !important;
    margin: 0 !important;
    padding: 0 !important;
    /* overflow: hidden !important; */
    z-index: 2147483600 !important;                 /* topmost - above modals/toasts */
    /* Very light green frosted veil; the page behind is blurred via
       backdrop-filter so the content shows through (frosted) behind the loader. */
    background: rgb(147 228 145 / 9%) !important;
    backdrop-filter: blur(8px) saturate(115%) !important;
    -webkit-backdrop-filter: blur(8px) saturate(115%) !important;
    isolation: isolate !important;                  /* own stacking context */
    /* NOTE: deliberately NO `display` here. The overlay is visible by default
       (block); html.si-booted sets display:none to hide it on later navs, and
       a manual .show()/.hide() drives display inline. The inner #preloader is
       absolutely centred so it stays centred whatever display the overlay has. */
    opacity: 1;
    visibility: visible;
    pointer-events: auto !important;
    /* transition: opacity .25s ease, visibility .25s linear; */
    font-family: "Poppins", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif !important;
}

/* Soft blurred green orbs for depth (subtle, on-brand). */
html body #loading-wrap::before,
html body #loading-wrap::after {
    content: "" !important;
    position: absolute !important;
    border-radius: 50% !important;
    filter: blur(60px) !important;
    pointer-events: none !important;
    z-index: 0 !important;
}
html body #loading-wrap::before {
    width: 320px !important; height: 320px !important;
    left: -60px !important; top: -60px !important;
    background: rgba(118, 209, 100, .45) !important;
}
html body #loading-wrap::after {
    width: 360px !important; height: 360px !important;
    right: -80px !important; bottom: -90px !important;
    background: rgba(63, 169, 43, .28) !important;
}

/* Loader wrapper (#preloader / .loader-gif) - absolutely centred so it stays
   centred regardless of the overlay's display (block on manual .show(), etc). */
html body #loading-wrap #preloader,
html body #loading-wrap .loader-gif {
    position: absolute !important;
    top: 50% !important;
    left: 50% !important;
    transform: translate(-50%, -50%) !important;
    -webkit-transform: translate(-50%, -50%) !important;
    z-index: 1 !important;
    width: auto !important;
    height: auto !important;
    margin: 0 !important;
    background: transparent !important;
    display: flex !important;
    flex-direction: column !important;
    align-items: center !important;
    justify-content: center !important;
    gap: 20px !important;
}

/* The branded orb: soft glow behind a white cloud badge (spinning ring removed). */
html body #loading-wrap .si-loader-orb {
    position: relative !important;
    width: 108px !important;
    height: 108px !important;
    display: grid !important;
    place-items: center !important;
}
html body #loading-wrap .si-loader-glow {
    position: absolute !important;
    inset: -18px !important;
    border-radius: 50% !important;
    background: radial-gradient(circle, rgba(63, 169, 43, .22), transparent 68%) !important;
    animation: si-loader-glow 2.4s ease-in-out infinite !important;
}
html body #loading-wrap .si-loader-badge {
    position: relative !important;
    z-index: 1 !important;
    width: 124px !important;             /* wider PILL so the Cloud.gif logo fills it */
    height: 86px !important;
    border-radius: 20px !important;
    background-color: #fff !important;
    background-image: url("../images/Cloud.gif") !important;   /* brand loader image */
    background-repeat: no-repeat !important;
    background-position: center !important;
    background-size: 100px 68px !important;   /* bigger logo, preserves ~1.46:1 ratio */
    box-shadow: 0 12px 30px rgba(15, 23, 42, .12), 0 0 0 1px rgba(63, 169, 43, .12) !important;
    animation: si-loader-breathe 2.4s ease-in-out infinite !important;
}

/* Wordmark + caption + bouncing dots. */
html body #loading-wrap .si-loader-wordmark {
    font-size: 20px !important;
    font-weight: 700 !important;
    letter-spacing: -.01em !important;
    background: linear-gradient(135deg, #1a2236 0%, #3FA92B 120%) !important;
    -webkit-background-clip: text !important;
    background-clip: text !important;
    -webkit-text-fill-color: transparent !important;
    color: #1a2236 !important;
    margin: 0 !important;
}
html body #loading-wrap .si-loader-caption {
    font-size: 13px !important;
    font-weight: 500 !important;
    color: #7e8a9f !important;
    margin: -10px 0 0 !important;
}
html body #loading-wrap .si-loader-dots {
    display: flex !important;
    gap: 7px !important;
}
html body #loading-wrap .si-loader-dots i {
    width: 8px !important;
    height: 8px !important;
    border-radius: 50% !important;
    background: #3FA92B !important;
    opacity: .35 !important;
    animation: si-loader-dots 1.2s ease-in-out infinite !important;
}
html body #loading-wrap .si-loader-dots i:nth-child(2) { animation-delay: .18s !important; }
html body #loading-wrap .si-loader-dots i:nth-child(3) { animation-delay: .36s !important; }

@keyframes si-loader-spin { to { transform: rotate(360deg); } }
@keyframes si-loader-breathe { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.06); } }
@keyframes si-loader-glow { 0%, 100% { opacity: .35; transform: scale(1); } 50% { opacity: .6; transform: scale(1.08); } }
@keyframes si-loader-dots { 0%, 100% { opacity: .3; transform: translateY(0); } 50% { opacity: 1; transform: translateY(-4px); } }

/* Fade-out applied by loader.js right before display:none. */
html body #loading-wrap.sl-fading {
    opacity: 0 !important;
    visibility: hidden !important;
    pointer-events: none !important;
}

/* Honour the inline display:none loader.js sets after the fade. */
html body #loading-wrap[style*="display: none"],
html body #loading-wrap[style*="display:none"] {
    display: none !important;
}

/* The splash covers EVERY page (cold boot AND navigation) from the first paint
   until loader.js confirms everything has finished loading (window.load + AJAX
   idle), so the half-rendered page is never exposed. The head script still adds
   html.si-booted but it no longer hides the splash - the splash is the cover on
   every page now. */

/* Once the splash is gone, drop the pre-paint mint background on <html>. */
html.loader-done {
    background-color: transparent !important;
    background-image: none !important;
}

/* (The page-content filter:blur approach was removed - the splash now blurs the
   page behind it with backdrop-filter, per the chosen styling above.) */


/* ==========================================================================
   2) NEUTRALISE animsition's full-page transition overlay.
   --------------------------------------------------------------------------
   animsition (Site.js startLoading) injects <div class="loader-overlay">
   as a child of <html> on every navigation. We no longer want that dark
   full-screen takeover for routine in-app nav - NProgress shows progress
   instead. Keep it in the DOM (animsition's JS removes it) but invisible
   and click-through. The cold-boot splash (#loading-wrap, in <body>) is
   excluded via :not().
   ========================================================================== */
html > .loader-overlay:not(#loading-wrap),
html body .loader-overlay:not(#loading-wrap),
html body .global-loader,
html body .loading-overlay {
    background: transparent !important;
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
    pointer-events: none !important;
    opacity: 0 !important;
    visibility: hidden !important;
}
html .loader-overlay:not(#loading-wrap) .loader-content,
html .loader-overlay:not(#loading-wrap) .loader-index {
    display: none !important;
}

/* CRITICAL: animsition's CSS sets `.animsition { opacity: 0 }` on <body> until
   its JS fades the page in. Because our splash (#loading-wrap) lives INSIDE the
   body, that opacity:0 also hides the splash - so during load the user sees a
   blank page (especially on a hard refresh). Force the body visible: the splash
   covers the content via its own z-index until loader.js hides it, and nav
   feedback comes from NProgress, so animsition's body fade is not needed. */
html body.animsition,
body.animsition {
    opacity: 1 !important;
    -webkit-animation: none !important;
    animation: none !important;
}


/* ==========================================================================
   3) NPROGRESS - top progress bar in brand green.
   --------------------------------------------------------------------------
   Sits just under the topnav. The cold-boot splash (z 2147483600) covers it
   on first load; on in-app navigations it is the only indicator.
   ========================================================================== */
#nprogress { pointer-events: none; }
#nprogress .bar {
    background: #3FA92B !important;
    position: fixed !important;
    z-index: 2147483601 !important;     /* above the splash so it's visible during cold boot too */
    top: 0 !important;
    left: 0 !important;
    width: 100% !important;
    height: 3px !important;
}
/* The little glowing "comet" at the leading edge. */
#nprogress .peg {
    display: block !important;
    position: absolute !important;
    right: 0 !important;
    width: 100px !important;
    height: 100% !important;
    box-shadow: 0 0 10px #3FA92B, 0 0 6px #3FA92B !important;
    opacity: 1 !important;
    transform: rotate(3deg) translate(0px, -4px) !important;
}


/* ==========================================================================
   4) DATATABLES - TABLE-LOCAL processing indicator (no full-page dim).
   --------------------------------------------------------------------------
   Carried over verbatim from loader.css. On search/filter/paginate only the
   table area shows a centred "Processing..." caption - never the viewport.
   ========================================================================== */
html body .dataTables_wrapper,
html body .sl-table-card,
html body .table-responsive:has(table.dataTable) {
    position: relative !important;
}
html body .dataTables_wrapper { min-height: 328px !important; }
html body .table-responsive:has(table.dataTable) { min-height: 328px !important; }
html body .sl-table-card { min-height: 328px !important; }

html body table.table-report tbody tr.dataTables_empty td,
html body table.dataTable tbody tr.dataTables_empty td {
    height: 280px !important;
    vertical-align: middle !important;
    text-align: center !important;
}
html body table.table-report tbody tr.dataTables_empty td img,
html body table.dataTable tbody tr.dataTables_empty td img {
    display: block !important;
    margin: 0 auto !important;
    float: none !important;
    max-width: 100% !important;
}

html body .dataTables_processing,
html body div.dataTables_processing,
html body .dataTables_processing.card,
html body .dataTables_wrapper .dataTables_processing {
    position: absolute !important;
    top: 48px !important;                /* skip <thead> */
    left: 0 !important;
    right: 0 !important;
    bottom: 64px !important;             /* skip info + pagination footer */
    width: 100% !important;
    height: auto !important;
    min-height: 200px !important;
    margin: 0 !important;
    padding: 24px !important;
    background: transparent !important;  /* no backdrop - table stays visible */
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
    border: 0 !important;
    border-radius: 0 !important;
    box-shadow: none !important;
    color: #0F1014 !important;
    font-size: 14px !important;
    font-weight: 600 !important;
    letter-spacing: 0 !important;
    text-transform: none !important;
    text-align: center !important;
    line-height: 1.3 !important;
    text-indent: 0 !important;
    text-shadow: none !important;
    box-sizing: border-box !important;
    z-index: 100 !important;
    align-items: center !important;
    justify-content: center !important;
    flex-direction: column !important;
    gap: 12px !important;
    animation: dt-proc-in .22s ease-out !important;
    pointer-events: none !important;     /* clicks pass through */
}
@keyframes dt-proc-in {
    0%   { opacity: 0; }
    100% { opacity: 1; }
}
html body .dataTables_processing:not([style*="display: none"]):not([style*="display:none"]),
html body div.dataTables_processing:not([style*="display: none"]):not([style*="display:none"]) {
    display: flex !important;
    animation: dt-proc-in .22s ease-out, dt-text-pulse 1.6s ease-in-out infinite !important;
}
@keyframes dt-text-pulse {
    0%, 100% { color: rgba(15, 16, 20, .55); }
    50%      { color: rgba(15, 16, 20, 1);   }
}
html body .dataTables_processing[style*="display: none"],
html body .dataTables_processing[style*="display:none"] {
    display: none !important;
}
html body .dataTables_processing::before,
html body .dataTables_processing::after {
    display: none !important;
    content: none !important;
}


/* ==========================================================================
   5) Bootstrap inline spinners - brand green.
   ========================================================================== */
.spinner-border.text-primary,
.spinner-border.text-theme-1,
.spinner-grow.text-primary,
.spinner-grow.text-theme-1 {
    color: #3FA92B !important;
    border-color: currentColor;
    border-right-color: transparent;
}


/* ==========================================================================
   6) SKELETON TOOLKIT - theme-matched shimmer placeholders.
   --------------------------------------------------------------------------
   Reusable classes for the "structured blank page" experience. Build markup
   by hand or via window.siSkeleton.show(target, {head, stats, rows, cols})
   in loader.js, then siSkeleton.hide(target) when data arrives.

   Layout mirrors a typical list page: page-head (title + button) -> stat
   cards -> table rows. Shimmer uses the theme's soft greys so it reads as
   "loading" without clashing with the green/mint palette.
   ========================================================================== */
.si-sk {
    display: flex;
    flex-direction: column;
    gap: 16px;
    width: 100%;
    animation: si-sk-in .2s ease-out;
}
.si-sk.si-sk-hiding { opacity: 0; transition: opacity .2s ease; }
@keyframes si-sk-in { from { opacity: 0; } to { opacity: 1; } }

/* Shared shimmer surface for every placeholder block. */
.si-sk-title,
.si-sk-pill,
.si-sk-card,
.si-sk-cell,
.si-sk-line {
    background: linear-gradient(100deg, #eef1f6 30%, #f7f9fc 50%, #eef1f6 70%);
    background-size: 200% 100%;
    animation: si-sk-shimmer 1.3s linear infinite;
    border-radius: 8px;
    display: block;
}
@keyframes si-sk-shimmer { to { background-position: -200% 0; } }

.si-sk-head { display: flex; align-items: center; gap: 14px; }
.si-sk-title { width: 220px; height: 26px; border-radius: 9px; }
.si-sk-pill { width: 120px; height: 40px; border-radius: 10px; margin-left: auto; }

.si-sk-stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; }
.si-sk-card { height: 84px; border-radius: 14px; }

.si-sk-table {
    background: #fff;
    border: 1px solid #e5e9f0;
    border-radius: 14px;
    padding: 6px 14px;
    box-shadow: 0 2px 10px rgba(15, 23, 42, .03);
}
.si-sk-row {
    display: grid;
    grid-template-columns: 1.6fr 1fr 1fr .8fr .6fr;
    gap: 14px;
    padding: 14px 4px;
    border-bottom: 1px solid #f1f3f6;
}
.si-sk-row:last-child { border-bottom: 0; }
.si-sk-cell { height: 14px; align-self: center; }

@media (max-width: 768px) {
    .si-sk-stats { grid-template-columns: repeat(2, 1fr); }
}


/* ==========================================================================
   7) DATA-LOADING OVERLAY (#si-data-loader)
   --------------------------------------------------------------------------
   For IN-PAGE data loading (AJAX: filters, save, section refresh). A DARK,
   blurred, translucent overlay so the current page stays visible (dimmed)
   behind it, with the SAME Cloud.gif loader centered. Distinct from the mint
   full-page splash (#loading-wrap) - that one is opaque and covers everything.
   Driven by window.showLoader() / window.hideLoader() in loader.js; the
   element is injected into <body> on first use, so no markup is needed.
   ========================================================================== */
html body #si-data-loader {
    position: fixed !important;
    top: 0 !important; left: 0 !important; right: 0 !important; bottom: 0 !important;
    width: 100% !important; height: 100% !important;
    z-index: 2147483500 !important;            /* below the full splash (...600) */
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    background: rgba(15, 16, 20, 0.45) !important;          /* black, transparent */
    backdrop-filter: blur(4px) saturate(110%) !important;  /* blur the page behind */
    -webkit-backdrop-filter: blur(4px) saturate(110%) !important;
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity .35s ease, visibility .35s linear;
}
html body #si-data-loader.si-show {
    opacity: 1 !important;
    visibility: visible !important;
    pointer-events: auto !important;
}
html body #si-data-loader .si-dl-orb {
    position: relative;
    width: 104px; height: 104px;
    display: grid; place-items: center;
}
html body #si-data-loader .si-dl-glow {
    position: absolute; inset: -16px; border-radius: 50%;
    background: radial-gradient(circle, rgba(63, 169, 43, .30), transparent 68%);
    animation: si-loader-glow 2.4s ease-in-out infinite;
}
html body #si-data-loader .si-dl-badge {
    position: relative; z-index: 1;
    width: 124px; height: 86px; border-radius: 20px;
    background-color: #fff;
    background-image: url("../images/Cloud.gif");
    background-repeat: no-repeat;
    background-position: center;
    background-size: 100px 68px;
    box-shadow: 0 14px 34px rgba(0, 0, 0, .45), 0 0 0 1px rgba(63, 169, 43, .18);
    animation: si-loader-breathe 2.4s ease-in-out infinite;
}


/* ==========================================================================
   8) ACCESSIBILITY - respect prefers-reduced-motion.
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
    html body #loading-wrap,
    html body #loading-wrap::before,
    html body #loading-wrap .si-loader-ring,
    html body #loading-wrap .si-loader-badge,
    html body #loading-wrap .si-loader-glow,
    html body #loading-wrap .si-loader-dots i,
    html body #si-data-loader .si-dl-badge,
    html body #si-data-loader .si-dl-glow,
    html body .dataTables_processing,
    .si-sk-title, .si-sk-pill, .si-sk-card, .si-sk-cell, .si-sk-line,
    #nprogress .bar,
    #nprogress .peg {
        transition: none !important;
        animation: none !important;
    }
}
