/* Loading screen. The only "menu" the game has: the "Heroes Beware" splash art
   (assets/ui/loading-bg.webp) and a progress shimmer that holds until main.js
   has the models resident — then the run starts directly. The logo lives in the
   art itself, so nothing here has to re-draw the title. */

.loading {
  position: fixed; inset: 0; z-index: 60; overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  /* The art is 16:9. Anchored to the top rather than centred because anything
     wider than 16:9 — a phone held sideways, an ultrawide monitor — crops
     vertically under `cover`, and centring that crop shaves the horns off the
     painted banner. Losing floor off the bottom instead costs nothing: the
     vignette already owns that strip.
     The bottom of the gradient goes nearly opaque on purpose: the splash has a
     painted bar slot down there whose width tracks the crop, so rather than
     chase it we sink it into the vignette and lay our own bar over the top. */
  background:
    linear-gradient(180deg,
      rgba(10,6,18,0) 46%,
      rgba(10,6,18,.55) 78%,
      rgba(10,6,18,.94) 92%,
      rgba(10,6,18,1) 100%),
    url('../assets/ui/loading-bg.webp') center top / cover no-repeat,
    radial-gradient(120% 100% at 50% 0%, #3d1f78 0%, #1d0e3a 70%);
  animation: ld-in .35s ease-out;
  transition: opacity .45s ease;
}
@keyframes ld-in { from { opacity: 0; } to { opacity: 1; } }

/* Portrait. `cover` on a tall phone zooms the 16:9 art so hard that the painted
   banner runs off both edges, so the art gets its own box instead: capped at
   178% — the widest it can be drawn while the banner still clears the viewport
   — and collapsing back to plain `cover` as the screen approaches square, so
   nothing jumps at the breakpoint.
   Owning a box (rather than being a background of the viewport) is what lets
   the art's own top and bottom edges dissolve: the band lands at a different
   height on every phone, and a viewport-anchored gradient cannot hug a seam
   that moves, but a gradient stacked inside this box is measured against the
   art itself. Both fades land on the same flat --ld-void the backdrop is
   painted in, which is the whole reason the backdrop is flat: the seam turns up
   anywhere between 67% and 99% of the screen depending on the handset, and only
   a single colour matches it at every one of them. (Deliberately not
   `mask-image` — when a mask fails to composite the entire splash disappears,
   and a loading screen is the worst place to find that out.)
   The -56.5% offset centres the banner rather than the canvas — the slime king
   pushes it right of the art's true middle. */
@media (max-aspect-ratio: 1/1) {
  .loading {
    --ld-void: #26134a;
    background: var(--ld-void);
  }
  .loading::before {
    content: '';
    position: absolute; left: 50%; top: 44%;
    width: min(178%, 179.2vh);
    aspect-ratio: 1376 / 768;
    transform: translate(-56.5%, -50%);
    background:
      linear-gradient(180deg,
        var(--ld-void) 0%, rgba(38,19,74,.55) 9%, rgba(38,19,74,0) 22%,
        rgba(38,19,74,0) 52%, rgba(38,19,74,.55) 76%, rgba(38,19,74,.93) 92%,
        var(--ld-void) 97%),
      url('../assets/ui/loading-bg.webp') center / 100% 100% no-repeat;
    pointer-events: none;
  }
}

/* Caption sits above the bar so both stay clear of the home indicator. */
.ld-inner {
  position: absolute; left: 0; right: 0;
  bottom: calc(5% + env(safe-area-inset-bottom, 0px));
  display: flex; flex-direction: column; align-items: center; gap: 12px;
}

/* Indeterminate shimmer — the real wait is the GLB fetch, which reports no
   progress, so the bar sells motion rather than measuring it. */
.ld-bar {
  width: min(340px, 60vw); height: 16px; border-radius: 9px;
  background: #1d122e; border: 2px solid #0e0818;
  box-shadow: inset 0 2px 5px rgba(0,0,0,.6), 0 2px 6px rgba(0,0,0,.4);
  overflow: hidden;
}
.ld-bar i {
  display: block; width: 40%; height: 100%; border-radius: 7px;
  background: linear-gradient(180deg, #c79dff, #8b5df0 55%, #5a2fb8);
  box-shadow: 0 0 10px rgba(165,97,255,.8);
  animation: ld-slide 1.15s ease-in-out infinite;
}
@keyframes ld-slide {
  0% { transform: translateX(-110%); }
  100% { transform: translateX(270%); }
}

/* The PLAY gate. Only built on portals that require a pre-roll (see
   Portal.needsStartGate) — the CrazyGames build drops straight into the run and
   never renders this. It replaces the shimmer bar in .ld-inner, so it inherits
   the same safe-area-aware footing and needs no positioning of its own.
   Sized generously because it is the one thing on the screen and it is the
   first thing a player touches, often on a phone. */
.ld-play {
  font-family: var(--font);
  font-size: clamp(20px, 5.2vw, 30px); font-weight: 900; letter-spacing: .16em;
  color: #2a1206;
  padding: 14px clamp(44px, 13vw, 76px);
  border: 3px solid #4a2a08;
  border-radius: 14px;
  cursor: pointer;
  background: linear-gradient(180deg, #ffe9a8 0%, #ffc75a 46%, #f0982c 100%);
  box-shadow:
    inset 0 2px 0 rgba(255,255,255,.75),
    inset 0 -4px 0 rgba(120,60,0,.35),
    0 5px 0 #7a4406,
    0 10px 22px rgba(0,0,0,.55);
  text-shadow: 0 1px 0 rgba(255,255,255,.45);
  /* Pulses so the eye lands on it immediately after the splash settles. */
  animation: ld-play-pulse 1.9s ease-in-out infinite;
  transition: transform .09s ease, box-shadow .09s ease, filter .18s ease;
  -webkit-tap-highlight-color: transparent;
}
.ld-play:hover { filter: brightness(1.06); }
/* Presses into its own drop shadow rather than moving under the finger. */
.ld-play:active {
  transform: translateY(4px);
  box-shadow:
    inset 0 2px 0 rgba(255,255,255,.6),
    inset 0 -2px 0 rgba(120,60,0,.35),
    0 1px 0 #7a4406,
    0 4px 10px rgba(0,0,0,.5);
}
.ld-play:focus-visible { outline: 3px solid #c79dff; outline-offset: 4px; }
/* While the pre-roll is being fetched: still legible, clearly not pressable. */
.ld-play:disabled {
  cursor: default; animation: none; filter: saturate(.45) brightness(.8);
  transform: translateY(4px);
  box-shadow: inset 0 2px 0 rgba(255,255,255,.4), 0 1px 0 #7a4406;
}
@keyframes ld-play-pulse {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.045); }
}
@media (prefers-reduced-motion: reduce) {
  .ld-play { animation: none; }
}

/* Warm gold to echo the painted "HEROES" above it. */
.ld-text {
  font-family: var(--font); font-size: 13px; font-weight: 900; letter-spacing: .22em;
  color: #ffe9b0; text-shadow: 0 2px 0 rgba(0,0,0,.85);
  animation: ld-dots 1.6s ease-in-out infinite;
}
@keyframes ld-dots { 0%, 100% { opacity: 1; } 50% { opacity: .55; } }
