/* ==========================================================================
   The loading screen. Shared by the landing page and the game, and the first
   stylesheet each of them links, so it paints on the very first frame: a dark
   ground the page's own background matches, the brand mark (assets/mark.png,
   derived from the source emblem by tools/make-mark.mjs) and one hairline
   progress track.

   The overlay is up by default and comes down only when the page's first
   screen is genuinely complete — every image decoded and every font in on the
   landing page, the world built, the shaders compiled, the character loaded
   and one full frame drawn in the game (src/boot.js drives it). Three states
   live on the root element:

     (none)  before src/boot.js has run: the overlay shows
     loading the page is still assembling its first screen
     ready   the first screen is complete: the overlay is gone
     skip    no loading screen at all — the fall arrives from the landing page
             with everything already warm (src/game/gate.js)

   Without JavaScript, noscript.css removes the overlay instead.
   ========================================================================== */

:root { --boot-bg: #05070c; --boot-accent: #e8202a; }

/* the ground is painted by the document itself, so there is no white flash before any stylesheet or image lands */
html { background: var(--boot-bg); }

.boot {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: grid;
  place-items: center;
  align-content: center;
  gap: clamp(22px, 4.5vmin, 34px);
  background: var(--boot-bg);
  /* a faint lift at the centre so the mark sits in its own light */
  background-image: radial-gradient(60% 50% at 50% 46%, rgba(255, 255, 255, 0.045), rgba(255, 255, 255, 0) 70%);
  opacity: 1;
  touch-action: none;
  overscroll-behavior: contain;
  transition: opacity 340ms cubic-bezier(0.25, 0.1, 0.25, 1);
  /* keeps the mark clear of a notch or a home indicator on phones */
  padding: max(16px, env(safe-area-inset-top)) max(16px, env(safe-area-inset-right)) max(16px, env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left));
}

.boot__mark {
  width: clamp(84px, 19vmin, 132px);
  height: auto;
  /* the mark fades in on its own decode, so a slow connection never shows a half-painted emblem */
  opacity: 0;
  transform: scale(0.94);
  transition: opacity 420ms ease-out, transform 420ms cubic-bezier(0.2, 0.7, 0.3, 1);
  filter: drop-shadow(0 0 clamp(14px, 3vmin, 26px) rgba(232, 32, 42, 0.22));
  animation: boot-breathe 3.4s ease-in-out infinite;
}
.boot__mark.is-in { opacity: 1; transform: none; }

@keyframes boot-breathe {
  0%, 100% { filter: drop-shadow(0 0 clamp(14px, 3vmin, 26px) rgba(232, 32, 42, 0.22)); }
  50% { filter: drop-shadow(0 0 clamp(22px, 4.5vmin, 40px) rgba(232, 32, 42, 0.38)); }
}

/* one hairline track; the fill is the honest weighted progress, eased so it never jumps or stalls dead */
.boot__track {
  position: relative;
  width: clamp(124px, 27vmin, 184px);
  height: 2px;
  background: rgba(255, 255, 255, 0.13);
  overflow: hidden;
  border-radius: 2px;
}
.boot__fill {
  display: block;
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: calc(var(--boot-p, 0) * 100%);
  background: linear-gradient(to right, var(--boot-accent), #ff8088);
  box-shadow: 0 0 8px rgba(232, 32, 42, 0.55);
}

/* the reveal: the mark lifts away as the ground clears */
.boot.is-done { opacity: 0; pointer-events: none; }
.boot.is-done .boot__mark { transform: scale(1.06); animation: none; }

.boot__sr { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }

html[data-boot="ready"] .boot,
html[data-boot="skip"] .boot { display: none; }

@media (prefers-reduced-motion: reduce) {
  .boot { transition-duration: 120ms; }
  .boot__mark { animation: none; transition: opacity 160ms linear; transform: none; }
  .boot__mark.is-in { transform: none; }
  .boot.is-done .boot__mark { transform: none; }
}
