/* ════════════════════════════════════════════════════════════════════════════
   Homepage preloader variants — admin-selectable: 24, 29, 30, 33.
   Markup wrappers are `.pl-variant.pl-<N>` so styles can't collide with the
   /loading-preview/ gallery (which uses .lscreen / ls-).
   ════════════════════════════════════════════════════════════════════════════ */

/* ── Variant switcher ────────────────────────────────────────────────────── */
#preloader { --pl-scale: 1.6; }
#preloader .pl-variant { display: none; position: absolute; inset: 0; align-items: center; justify-content: center; overflow: hidden; }
#preloader[data-loader="24"] .pl-24,
#preloader[data-loader="29"] .pl-29,
#preloader[data-loader="30"] .pl-30,
#preloader[data-loader="33"] .pl-33 { display: flex; }

/* ── Shared logo + text ──────────────────────────────────────────────────── */
#preloader .pl-content {
    position: relative;
    text-align: center;
    z-index: 2;
}
#preloader .pl-logo {
    width: calc(260px * var(--pl-scale));
    height: auto;
    max-width: 92%;
    object-fit: contain;
    display: block;
    margin: 0 auto calc(22px * var(--pl-scale));
    filter: drop-shadow(0 0 calc(28px * var(--pl-scale)) rgba(167,205,58,.32));
}
#preloader .pl-name {
    font-size: calc(1.1rem * var(--pl-scale));
    font-weight: 600;
    letter-spacing: -.01em;
    color: var(--text);
}
#preloader .pl-name span { color: var(--accent); }
#preloader .pl-tag {
    margin-top: calc(8px * var(--pl-scale));
    font-size: calc(.7rem * var(--pl-scale));
    letter-spacing: .18em;
    text-transform: uppercase;
    color: var(--text-3);
}

/* Reduce scale on mobile so the loader doesn't overflow narrow screens */
@media (max-width: 720px) {
    #preloader { --pl-scale: 1.1; }
}

/* ════════════════════════════════════════════════════════════════════════════
   24 · Curtain Reveal
   ════════════════════════════════════════════════════════════════════════════ */
#preloader .pl-24 { position: absolute; inset: 0; }
#preloader .pl24-curtain {
    position: absolute; top: 0;
    width: 50%; height: 100%;
    background: linear-gradient(180deg, var(--bg-2), var(--bg-1));
    box-shadow: inset 0 0 60px rgba(0,0,0,.5);
    z-index: 5;
}
#preloader .pl24-curtain-l {
    left: 0;
    animation: pl24-left 3.2s ease-in-out infinite;
    border-right: 1px solid var(--accent);
    box-shadow: inset 0 0 60px rgba(0,0,0,.5), 1px 0 12px rgba(167,205,58,.3);
}
#preloader .pl24-curtain-r {
    right: 0;
    animation: pl24-right 3.2s ease-in-out infinite;
    border-left: 1px solid var(--accent);
    box-shadow: inset 0 0 60px rgba(0,0,0,.5), -1px 0 12px rgba(167,205,58,.3);
}
@keyframes pl24-left {
    0%, 25%   { transform: translateX(0); }
    55%, 80%  { transform: translateX(-102%); }
    100%      { transform: translateX(0); }
}
@keyframes pl24-right {
    0%, 25%   { transform: translateX(0); }
    55%, 80%  { transform: translateX(102%); }
    100%      { transform: translateX(0); }
}
#preloader .pl-24 .pl-content {
    animation: pl24-content 3.2s ease-in-out infinite;
    opacity: 0;
}
@keyframes pl24-content {
    0%, 35%   { opacity: 0; transform: scale(.92); }
    55%, 80%  { opacity: 1; transform: scale(1); }
    100%     { opacity: 0; transform: scale(.96); }
}

/* ════════════════════════════════════════════════════════════════════════════
   29 · 3D Flip
   ════════════════════════════════════════════════════════════════════════════ */
#preloader .pl-29 .pl-content { perspective: 800px; }
#preloader .pl-29 .pl-logo {
    transform-style: preserve-3d;
    backface-visibility: hidden;
    opacity: 0;
    animation: pl29-flip 3.4s cubic-bezier(.2,.8,.3,1) infinite;
}
@keyframes pl29-flip {
    0%       { transform: perspective(600px) rotateY(-95deg) scale(.7); opacity: 0; }
    18%      { opacity: 1; }
    40%, 80% { transform: perspective(600px) rotateY(0)       scale(1); opacity: 1; }
    100%     { transform: perspective(600px) rotateY(95deg)  scale(.7); opacity: 0; }
}
#preloader .pl-29 .pl-name,
#preloader .pl-29 .pl-tag {
    opacity: 0;
    transform: translateY(calc(22px * var(--pl-scale)));
    animation: pl29-slide 3.4s cubic-bezier(.2,.8,.3,1) infinite;
}
#preloader .pl-29 .pl-name { animation-delay: .3s; }
#preloader .pl-29 .pl-tag  { animation-delay: .5s; }
@keyframes pl29-slide {
    0%, 18%  { opacity: 0; transform: translateY(calc(22px * var(--pl-scale))); }
    35%, 80% { opacity: 1; transform: translateY(0); }
    100%     { opacity: 0; transform: translateY(calc(-12px * var(--pl-scale))); }
}

/* ════════════════════════════════════════════════════════════════════════════
   30 · Stamp Impact
   ════════════════════════════════════════════════════════════════════════════ */
#preloader .pl-30 { position: absolute; inset: 0; }
#preloader .pl-30 .pl-logo {
    opacity: 0;
    animation: pl30-stamp 3.6s cubic-bezier(.5,1.4,.5,1) infinite;
}
@keyframes pl30-stamp {
    0%        { opacity: 0; transform: translateY(calc(-180px * var(--pl-scale))) scale(1.4); }
    14%       { opacity: 1; transform: translateY(0) scale(1.25); }
    19%       { transform: translateY(0) scale(.92); }
    24%       { transform: translateY(0) scale(1.04); }
    30%, 82%  { opacity: 1; transform: translateY(0) scale(1); }
    100%      { opacity: 0; transform: translateY(0) scale(.95); }
}
#preloader .pl30-impact {
    position: absolute; top: 50%; left: 50%;
    width: 0; height: 0;
    border: calc(3px * var(--pl-scale)) solid var(--accent);
    border-radius: 50%;
    opacity: 0;
    box-shadow: 0 0 calc(20px * var(--pl-scale)) rgba(167,205,58,.4);
    animation: pl30-impact 3.6s ease-out infinite;
}
#preloader .pl30-impact-2 { animation-delay: .08s; border-color: var(--brand-2, #4FB7E6); }
@keyframes pl30-impact {
    0%, 13%  { width: 0; height: 0; margin: 0; opacity: 0; border-width: calc(4px * var(--pl-scale)); }
    15%      { opacity: 1; }
    55%      { width: calc(640px * var(--pl-scale)); height: calc(640px * var(--pl-scale)); margin: calc(-320px * var(--pl-scale)); opacity: 0; border-width: 1px; }
    100%     { opacity: 0; }
}
#preloader .pl-30 .pl-name {
    opacity: 0;
    animation: pl30-shake 3.6s ease-out infinite;
}
@keyframes pl30-shake {
    0%, 14%  { opacity: 0; transform: translateX(0); }
    15%      { opacity: 1; transform: translate(-3px, 1px); }
    17%      { transform: translate(3px, -1px); }
    19%      { transform: translate(-2px, 0); }
    21%      { transform: translate(2px, 0); }
    23%, 82% { transform: translate(0, 0); opacity: 1; }
    100%     { opacity: 0; }
}
#preloader .pl-30 .pl-tag {
    opacity: 0;
    animation: pl-fade 3.6s ease-out infinite;
    animation-delay: .35s;
}
@keyframes pl-fade {
    0%, 25%  { opacity: 0; }
    35%, 82% { opacity: 1; }
    100%     { opacity: 0; }
}

/* ════════════════════════════════════════════════════════════════════════════
   33 · Spray Foam Guy
   ════════════════════════════════════════════════════════════════════════════ */
@property --pl33-r { syntax: '<percentage>'; inherits: false; initial-value: 0%; }
#preloader .pl-33 {
    /* Spray emission point — image-relative percentages so it tracks the PNG
       at any viewport. Override these to retune. */
    --pl33-spray-x: 90%;
    --pl33-spray-y: 24%;
}
#preloader .pl33-scene {
    position: relative;
    display: flex;
    align-items: flex-end;
    justify-content: center;
    gap: 2%;
    width: 100%; height: 100%;
    padding: 0 3% 4%;
    box-sizing: border-box;
}
#preloader .pl33-guy-col {
    flex: 0 1 36%;
    height: 92%;
    display: flex;
    align-items: flex-end;
    justify-content: center;
    position: relative;
}
/* aspect-ratio matches the PNG (1024×1536). With inline-block + height:100%
   + max-width:100%, the wrap sizes to (height × 2/3) — and when the column
   gets narrow on mobile, max-width clamps the width and the aspect-ratio
   shrinks the height to match, so wrap dimensions ALWAYS equal the rendered
   image. That's what makes spray% relative to wrap == spray% relative to
   the image, on every viewport. */
#preloader .pl33-guy-wrap {
    position: relative;
    height: 100%;
    aspect-ratio: 2 / 3;
    max-width: 100%;
    display: inline-block;
    opacity: 0;
    transform: translateX(calc(-30px * var(--pl-scale)));
    animation: pl33-guy-enter 8s ease-out infinite, pl33-bob 3s ease-in-out infinite;
}
#preloader .pl33-guy {
    width: 100%;
    height: 100%;
    border: 0;
    outline: 0;
    display: block;
    object-fit: contain;
}
/* Don't reserve space (or show a broken-image icon) before JS swaps in the
   data-src. The src is only set when loader 33 is the chosen variant, so
   loaders 24/29/30 never trigger the eric_msf.png download. */
#preloader .pl33-guy:not([src]) { visibility: hidden; }
@keyframes pl33-guy-enter {
    0%        { opacity: 0; transform: translateX(calc(-30px * var(--pl-scale))); }
    8%, 88%   { opacity: 1; transform: translateX(0); }
    95%, 100% { opacity: 0; transform: translateX(calc(-10px * var(--pl-scale))); }
}
@keyframes pl33-bob {
    0%, 100% { translate: 0 0; }
    50%      { translate: 0 calc(-4px * var(--pl-scale)); }
}

#preloader .pl33-content-col {
    flex: 0 1 58%;
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: calc(6px * var(--pl-scale));
    text-align: center;
    position: relative;
    z-index: 2;
    min-width: 0;
}
#preloader .pl33-logo-wrap {
    position: relative;
    isolation: isolate;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin-bottom: calc(6px * var(--pl-scale));
}
#preloader .pl33-logo-wrap::before {
    content: "";
    position: absolute;
    top: 50%;
    left: -8%;
    width: 0;
    height: 240%;
    transform: translateY(-50%);
    background: radial-gradient(ellipse at 0% center,
        rgba(120,200,240,.75) 0%,
        rgba( 79,183,230,.55) 18%,
        rgba( 79,183,230,.28) 40%,
        rgba( 79,183,230,.10) 65%,
        transparent           85%);
    filter: blur(calc(18px * var(--pl-scale)));
    z-index: -1;
    pointer-events: none;
    opacity: 0;
    animation: pl33-glow 8s ease-out infinite;
}
@keyframes pl33-glow {
    0%, 14%   { opacity: 0;   width:   0%; }
    22%       { opacity: 1;   width:  35%; }
    40%       { opacity: 1;   width:  85%; }
    50%       { opacity: 1;   width: 110%; }
    62%       { opacity: 1;   width: 140%; }
    78%       { opacity: .85; width: 145%; }
    88%       { opacity: .55; width: 145%; }
    95%, 100% { opacity: 0;   width: 145%; }
}
#preloader .pl-33 .pl-logo {
    --pl33-r: 0%;
    width:  calc(220px * var(--pl-scale));
    height: auto;
    max-width: 95%;
    filter: none;
    margin: 0;
    -webkit-mask: radial-gradient(circle at 0% 50%, #000 var(--pl33-r), transparent calc(var(--pl33-r) + 12%));
            mask: radial-gradient(circle at 0% 50%, #000 var(--pl33-r), transparent calc(var(--pl33-r) + 12%));
    opacity: 0;
    animation: pl33-reveal 8s ease-out infinite;
}
@keyframes pl33-reveal {
    0%, 14%   { --pl33-r: 0%; opacity: 0; }
    20%       { opacity: 1; --pl33-r: 0%; }
    62%       { --pl33-r: 130%; opacity: 1; }
    88%       { opacity: 1; --pl33-r: 130%; }
    95%, 100% { opacity: 0; }
}
#preloader .pl-33 .pl-name {
    opacity: 0;
    transform: translateY(calc(12px * var(--pl-scale)));
    animation: pl33-text 8s ease-out infinite;
    animation-delay: .1s;
}
#preloader .pl-33 .pl-tag {
    opacity: 0;
    animation: pl33-text 8s ease-out infinite;
    animation-delay: .35s;
}
@keyframes pl33-text {
    0%, 55%   { opacity: 0; transform: translateY(calc(12px * var(--pl-scale))); }
    70%, 88%  { opacity: 1; transform: translateY(0); }
    95%, 100% { opacity: 0; }
}
#preloader .pl33-spray {
    position: absolute;
    left: var(--pl33-spray-x);
    top:  var(--pl33-spray-y);
    width: 0; height: 0;
    pointer-events: none;
    z-index: 3;
    opacity: 0;
    animation: pl33-spray-active 8s linear infinite;
}
@keyframes pl33-spray-active {
    0%, 10%   { opacity: 0; }
    14%, 62%  { opacity: 1; }
    68%, 100% { opacity: 0; }
}
#preloader .pl33-spray span {
    position: absolute;
    width: calc(7px * var(--pl-scale));
    height: calc(7px * var(--pl-scale));
    margin: calc(-3.5px * var(--pl-scale));
    border-radius: 50%;
    background: radial-gradient(circle at 35% 35%, #b8ecff 0%, #4FB7E6 55%, #2a8bc4 100%);
    box-shadow: 0 0 calc(10px * var(--pl-scale)) rgba(79,183,230,.6);
    opacity: 0;
    animation: pl33-particle linear infinite;
}
@keyframes pl33-particle {
    0%   { transform: translate(0,0) scale(.3); opacity: 0; }
    10%  { opacity: 1; transform: translate(calc(var(--ex) * .15), calc(var(--ey) * .15)) scale(.85); }
    55%  { opacity: .95; transform: translate(calc(var(--ex) * .8), calc(var(--ey) * .8)) scale(1.4); }
    100% { transform: translate(var(--ex), var(--ey)) scale(.5); opacity: 0; }
}
#preloader .pl33-muzzle {
    position: absolute;
    left: var(--pl33-spray-x);
    top:  var(--pl33-spray-y);
    width: calc(14px * var(--pl-scale));
    height: calc(14px * var(--pl-scale));
    margin: calc(-7px * var(--pl-scale));
    border-radius: 50%;
    background: radial-gradient(circle, rgba(167,205,58,.9) 0%, transparent 70%);
    opacity: 0;
    z-index: 4;
    animation: pl33-muzzle 8s linear infinite;
}
@keyframes pl33-muzzle {
    0%, 12%   { opacity: 0; transform: scale(.6); }
    14%, 62%  { opacity: 1; transform: scale(1.1); }
    68%, 100% { opacity: 0; }
}

/* Reduced motion — strip the animations so visitors who opted out aren't
   subjected to a 3–8s loop. The bar preloader is the historical fallback;
   here we just freeze each loader at a "fully revealed" state. */
@media (prefers-reduced-motion: reduce) {
    #preloader *,
    #preloader *::before { animation: none !important; opacity: 1 !important; }
    #preloader .pl-logo { -webkit-mask: none; mask: none; }
    #preloader .pl24-curtain-l,
    #preloader .pl24-curtain-r { display: none !important; }
}
