/* ============================================================
   SURFYTECH PAGE LOADER  -  "SWIRL" MARK
   Replaces the legacy surfytechprogress.gif spinner.
   Loaded AFTER css/style.css, so these rules win over the old
   #loading / #loading-image block.

   THE MARK
   The mark is the real Surfytech logo swirl, not a generic ring:
   the seven tapered blade paths lifted straight out of
   img/surfytech-logo.svg and re-framed on a square viewBox around
   their true bounding box (405 x 446 user units, so the square adds
   a little breathing room on the sides). Because it is the actual
   artwork, the loader is unmistakably the brand rather than a
   spinner that merely borrows its colours.

   Two motions, and only two, so it reads as one object turning:
   the swirl rotates as a single group, and a hairline dashed ring
   counter-rotates outside it. The blades are filled shapes, not
   strokes, so no round-cap tricks are needed and the tapered
   silhouette survives being scaled down to a small size.

   THE WORDMARK
   The "Surfytech" text is deliberately NOT shown next to the mark.
   The mark already identifies the brand, and the status line below
   already says "Loading", so the word was redundant. The .sh-l-brand
   rules are kept as a no-op for any page still shipping that markup.

   THE BACKGROUND
   A layered, image-free backdrop: a deep navy base gradient, a
   fine grid masked to fade at the edges, three slowly drifting
   brand auroras (blue / purple / mint) and a vignette on top. The
   auroras are plain radial gradients with soft falloff rather than
   blurred elements, so they stay cheap to composite on mobile.

   SEO / resilience contract (unchanged):
   - The overlay is `display:none` by DEFAULT and only revealed once
     JS has added .sh-js to <html>. If JavaScript fails or is disabled
     the overlay never renders and the content stays visible and
     crawlable.
   - js/scripts.js adds .sh-loader-done and removes the node once the
     injected header and the banner are ready, plus hard timeouts.
   ============================================================ */

/* Legacy GIF rules kept neutralised for any page still using the old markup. */
#loading-image { display: none !important; }

/* ---------- overlay shell ------------------------------------------------ */
#loading.sh-loader {
    display: none;
    position: fixed;
    inset: 0;
    width: 100%;
    height: 100%;
    min-height: 100vh;
    min-height: 100dvh;
    z-index: 99999;                 /* above header (1000) and mega panel (1199) */
    align-items: center;
    justify-content: center;
    overflow: hidden;
    isolation: isolate;
    font-family: "Open Sans", sans-serif;
    background: linear-gradient(168deg, #070d2c 0%, #04081d 48%, #08062a 100%);
}

/* Revealed only when JS is alive. */
.sh-js #loading.sh-loader { display: flex; }

/* Marked by scripts.js when the page is ready; fades the overlay out. */
#loading.sh-loader.sh-loader-done {
    opacity: 0;
    visibility: hidden;
    transition: opacity .5s ease, visibility .5s ease;
}

/* ---------- background artwork ------------------------------------------ */
.sh-l-bg {
    position: absolute;
    inset: 0;
    z-index: 0;
    overflow: hidden;
    pointer-events: none;
}
.sh-l-bg-grid,
.sh-l-bg-orb,
.sh-l-bg-vig { position: absolute; display: block; }

/* Fine engineering grid, faded out well before the edges so it never
   looks like a hard-edged panel. */
.sh-l-bg-grid {
    inset: -2px;
    background-image:
        linear-gradient(rgba(139, 176, 255, .055) 1px, transparent 1px),
        linear-gradient(90deg, rgba(139, 176, 255, .055) 1px, transparent 1px);
    background-size: 64px 64px;
    background-position: center center;
    -webkit-mask-image: radial-gradient(120% 88% at 50% 44%, #000 10%, rgba(0, 0, 0, .32) 56%, transparent 84%);
            mask-image: radial-gradient(120% 88% at 50% 44%, #000 10%, rgba(0, 0, 0, .32) 56%, transparent 84%);
}

/* Three brand auroras. Soft radial falloff only - no filter: blur(), so the
   compositor never has to rasterise a large blurred layer. */
.sh-l-bg-orb { border-radius: 50%; will-change: transform; }
.sh-l-bg-orb-a {
    width: 78vmax; height: 78vmax;
    left: -26vmax; top: -30vmax;
    background: radial-gradient(circle at 50% 50%, rgba(0, 87, 217, .40) 0%, rgba(0, 87, 217, .16) 40%, rgba(0, 87, 217, 0) 70%);
    animation: sh-l-drift-a 24s ease-in-out infinite alternate;
}
.sh-l-bg-orb-b {
    width: 66vmax; height: 66vmax;
    right: -22vmax; bottom: -24vmax;
    background: radial-gradient(circle at 50% 50%, rgba(186, 43, 226, .34) 0%, rgba(186, 43, 226, .13) 42%, rgba(186, 43, 226, 0) 70%);
    animation: sh-l-drift-b 28s ease-in-out infinite alternate;
}
.sh-l-bg-orb-c {
    width: 54vmax; height: 54vmax;
    left: 50%; top: 46%;
    margin: -27vmax 0 0 -27vmax;
    background: radial-gradient(circle at 50% 50%, rgba(97, 231, 194, .17) 0%, rgba(97, 231, 194, .06) 44%, rgba(97, 231, 194, 0) 72%);
    animation: sh-l-drift-c 20s ease-in-out infinite alternate;
}

/* Vignette on top of everything, so the mark always sits on the darkest,
   highest-contrast part of the frame. */
.sh-l-bg-vig {
    inset: 0;
    background: radial-gradient(78% 62% at 50% 46%, rgba(6, 11, 36, 0) 34%, rgba(4, 7, 24, .55) 74%, rgba(2, 4, 16, .92) 100%);
}

/* ---- size scale --------------------------------------------------------
   Every dimension is driven from one set of custom properties, so the whole
   loader (mark, wordmark, label, rail) resizes as a single unit instead of
   needing each value edited in turn.

   Default is the MEDIUM step. Two opt-in modifiers are available from the
   markup for the rare page that wants a different weight:
     <div class="sh-loader-inner sh-loader--sm">   compact
     <div class="sh-loader-inner sh-loader--lg">   full-bleed hero moment
   -------------------------------------------------------------------- */
.sh-loader-inner {
    --sh-l-size: 78px;           /* medium: the square the mark occupies    */
    --sh-l-gap: 18px;            /* vertical rhythm between the parts      */
    --sh-l-bar-w: 176px;         /* progress rail width                     */
    --sh-l-label-size: 10.5px;   /* status line cap height                  */
    --sh-l-label-track: 2.8px;
    position: relative;
    z-index: 1;                  /* above the background artwork */
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--sh-l-gap);
    text-align: center;
    padding: 24px;
    max-width: 92vw;
    /* One gentle entrance so the loader assembles rather than snapping on. */
    animation: sh-l-enter .5s cubic-bezier(.22, .75, .28, 1) both;
}

.sh-loader-mark { width: var(--sh-l-size); height: var(--sh-l-size); display: block; }
.sh-loader-mark svg { width: 100%; height: 100%; display: block; overflow: visible; }

/* compact step */
.sh-loader-inner.sh-loader--sm {
    --sh-l-size: 62px;
    --sh-l-gap: 15px;
    --sh-l-bar-w: 138px;
    --sh-l-label-size: 9.5px;
    --sh-l-label-track: 2.4px;
}

/* large step */
.sh-loader-inner.sh-loader--lg {
    --sh-l-size: 96px;
    --sh-l-gap: 22px;
    --sh-l-bar-w: 226px;
    --sh-l-label-size: 11.5px;
    --sh-l-label-track: 3.2px;
}

/* Indeterminate progress rail. The segment sweeps across a faint track and
   fades at both ends, so it never looks like a stalled or stuck bar. */
.sh-l-bar {
    width: var(--sh-l-bar-w, 176px);
    height: 3px;
    border-radius: 3px;
    background: rgba(126, 178, 255, .18);
    overflow: hidden;
}
.sh-l-bar > span {
    display: block;
    width: 42%;
    height: 100%;
    border-radius: 3px;
    background: linear-gradient(90deg, rgba(242, 246, 255, 0), #7fc4ff 35%, #ba2be2 70%, rgba(97, 231, 194, 0));
    animation: sh-l-sweep 1.45s cubic-bezier(.65, 0, .35, 1) infinite;
}
@keyframes sh-l-sweep {
    0%        { transform: translateX(-105%); }
    100%      { transform: translateX(255%); }
}
@keyframes sh-l-enter {
    from { opacity: 0; transform: translateY(8px) scale(.985); }
    to   { opacity: 1; transform: none; }
}

/* ---- the mark ---------------------------------------------------------- */
/* The swirl turns as ONE group around the centre of its own bounding box.
   transform-box:view-box pins that origin to the viewBox rather than to the
   group's tight bbox, so the mark spins about its true middle instead of
   wobbling around whichever blade currently reaches furthest. */
.sh-l-swirl {
    transform-box: view-box;
    transform-origin: 439.4px 985.9px;   /* bbox centre of the 540-unit viewBox */
    animation: sh-l-swirl-turn 5.2s cubic-bezier(.62, .04, .38, .96) infinite;
}
/* The guide ring turns the other way, slowly, so the mark never looks paused. */
.sh-l-track {
    transform-box: view-box;
    transform-origin: 439.4px 985.9px;
    animation: sh-l-swirl-rev 13s linear infinite;
}

/* Soft brand bloom pooled behind the mark, breathing gently. Drawn beneath the
   svg so the blades always sit on top of the glow. */
.sh-loader-mark { position: relative; }
.sh-loader-mark::before {
    content: "";
    position: absolute;
    inset: -30%;
    border-radius: 50%;
    z-index: 0;
    pointer-events: none;
    background: radial-gradient(circle at 50% 50%, rgba(0, 120, 223, .34) 0%, rgba(97, 231, 194, .16) 38%, rgba(186, 43, 226, 0) 68%);
    animation: sh-l-bloom 3.4s ease-in-out infinite;
}
.sh-loader-mark svg { position: relative; z-index: 1; overflow: visible; }

/* The wordmark line is intentionally unused: the mark identifies the brand on
   its own. Kept as a no-op so any page still carrying the markup is harmless
   rather than rendering a stray line of gradient text. */
.sh-l-brand { display: none; }

.sh-l-label {
    margin: calc(var(--sh-l-gap, 20px) * -.6) 0 0;
    font-size: var(--sh-l-label-size, 10.5px);
    font-weight: 700;
    letter-spacing: var(--sh-l-label-track, 2.8px);
    text-transform: uppercase;
    color: #8ea7c9;
}
.sh-l-dots i { font-style: normal; animation: sh-l-blink 1.4s infinite; }
.sh-l-dots i:nth-child(2) { animation-delay: .2s; }
.sh-l-dots i:nth-child(3) { animation-delay: .4s; }

@keyframes sh-l-swirl-turn { to { transform: rotate(360deg); } }
@keyframes sh-l-swirl-rev { to { transform: rotate(-360deg); } }
@keyframes sh-l-bloom {
    0%, 100% { opacity: .55; transform: scale(.92); }
    50%      { opacity: 1;   transform: scale(1.06); }
}
@keyframes sh-l-blink {
    0%, 60%, 100% { opacity: .25; }
    30%           { opacity: 1; }
}

/* Background auroras: a slow, opposing drift. Offsets are percentages of the
   orb's own size, so the motion scales with the viewport on any screen. */
@keyframes sh-l-drift-a {
    from { transform: translate3d(0, 0, 0) scale(1); }
    to   { transform: translate3d(7%, 9%, 0) scale(1.12); }
}
@keyframes sh-l-drift-b {
    from { transform: translate3d(0, 0, 0) scale(1.1); }
    to   { transform: translate3d(-8%, -7%, 0) scale(1); }
}
@keyframes sh-l-drift-c {
    from { transform: translate3d(0, 0, 0) scale(1); }
    to   { transform: translate3d(5%, -8%, 0) scale(1.15); }
}

/* Phones step down to the compact size so the loader never crowds a short
   viewport, and very small screens tighten a little further. */
@media (max-width: 575px) {
    .sh-loader-inner { --sh-l-size: 66px; --sh-l-gap: 15px; --sh-l-bar-w: 150px; }
    .sh-l-label { margin-top: calc(var(--sh-l-gap, 15px) * -.6); }
}

@media (max-width: 380px) {
    .sh-loader-inner { --sh-l-size: 58px; --sh-l-gap: 13px; --sh-l-bar-w: 134px; }
}

@media (prefers-reduced-motion: reduce) {
    /* Freeze on a static frame rather than hiding the animation, so the loader
       still reads as the brand mark instead of a blank box. The auroras stop
       drifting and settle at their rest position. */
    .sh-l-swirl, .sh-l-track,
    .sh-l-bar > span, .sh-l-dots i,
    .sh-loader-mark::before, .sh-loader-inner,
    .sh-l-bg-orb { animation: none !important; }
    .sh-l-swirl { transform: rotate(-14deg); }
    .sh-l-track { transform: rotate(22deg); }
    .sh-l-bg-orb { transform: none; }
    #loading.sh-loader.sh-loader-done { transition: none; }
}
