/* ==========================================================================
   AJK Dream House Ltd. — Loading screen

   A once-per-session brand sting: the gold logo animation plays on a pure
   #000 field that matches the video's own background exactly, so the frame
   edges are invisible and the logo reads as if it were composited straight
   onto the page.

   Progressive enhancement: the overlay is display:none by default and only
   shown once <html> carries the `js` class. With JS off — or if site.js
   never arrives — the page is never covered. The `loader-done` failsafe
   class (set by an inline timeout in <head>) is the last line of defence.
   ========================================================================== */

.loader { display: none; }

/* Laptops only. Below this the loading screen never renders at all, and
   site.js checks the same query before it promotes the video sources — so a
   phone or tablet neither shows it nor downloads it. */
@media (min-width: 1000px) and (pointer: fine) {
  html.js .loader {
    position: fixed;
    inset: 0;
    z-index: 500;            /* above header (150), progress (200), skip-link (300) */
    display: grid;
    place-items: center;
    padding: var(--gutter);
    background: #000;        /* must stay pure black — matches the video matte */
    opacity: 1;
    transition: opacity 380ms var(--ease-out),
                visibility 380ms var(--ease-out),
                transform 380ms var(--ease-out);
  }

  /* Dismissed — the logo lifts toward the viewer as the curtain goes */
  html.js .loader.is-done {
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transform: scale(1.06);
  }
}

/* Hard failsafe — if the inline timeout fires, nothing can keep the page covered */
html.loader-done .loader { display: none !important; }

.loader__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  /* The bar tracks the stage width so the two read as one object */
  width: clamp(220px, 40vw, 420px);
}

/* ---- Video stage --------------------------------------------------------- */
/* Deliberately small. The source is 16:9 with the logo occupying ~73% of the
   frame width, so the surrounding black is dead space that simply disappears
   against the backdrop. */
.loader__stage {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  background: #000;
}

/* Video and still occupy the same box so swapping between them can't reflow */
.loader__stage > video,
.loader__stage > picture {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
}

.loader__video,
.loader__still {
  width: 100%;
  height: 100%;
  object-fit: contain;
  background: #000;
  display: block;
}

/* The still is only for the reduced-motion path */
.loader__stage > picture { display: none; }

/* ---- Progress bar -------------------------------------------------------- */
.loader__bar {
  position: relative;
  width: 100%;
  height: 2px;
  margin-top: clamp(18px, 2.4vw, 28px);
  border-radius: var(--r-pill);
  background: var(--layer-06);
  overflow: hidden;
}

.loader__fill {
  display: block;
  width: 100%;
  height: 100%;
  border-radius: inherit;
  background: var(--gold-grad);
  box-shadow: 0 0 12px var(--gold-35);
  transform: scaleX(0);
  transform-origin: left;
  /* Slightly lagging follow so the bar glides rather than steps */
  transition: transform 240ms var(--ease-out);
}

.loader__label {
  margin-top: 14px;
  font-variant-numeric: tabular-nums;
  color: var(--text-dim);
}
.loader__label b {
  font-weight: 600;
  color: var(--gold);
}

/* ---- Reduced motion ------------------------------------------------------ */
/* The video/still swap itself is done in site.js — it has to be, because the
   still's src is deferred and only JS knows whether to pay for it. Here we
   only take the motion out of the surrounding transitions. */
@media (prefers-reduced-motion: reduce) {
  html.js .loader { transition: opacity 200ms linear, visibility 200ms linear; }
  html.js .loader.is-done { transform: none; }
  .loader__fill { transition: transform 120ms linear; }
}

/* ---- Page beneath -------------------------------------------------------- */
/* Hold the hero entrance until the curtain is actually up, otherwise the
   choreography plays to nobody behind the overlay. */
html.is-loading,
html.is-loading body { overflow: hidden; }

html.js.is-loading .hero__inner > *:not(h1) { animation-play-state: paused; }

/* ---- The site popping in ------------------------------------------------- */
/* Deliberately not paired with a rule that hides the page while loading: the
   overlay is opaque, so it already does that, and a CSS-level hide would black
   the site out permanently if site.js ever failed to remove the class. The
   `both` fill only bites once .is-revealing is actually applied.

   Only header / main / footer are animated — never a wrapper around them.
   A transform on an ancestor of .site-header would become its containing
   block and break the fixed positioning outright. */
@keyframes pagePop {
  from { opacity: 0; transform: scale(0.965) translateY(12px); }
  to   { opacity: 1; transform: none; }
}

html.js.is-revealing .site-header,
html.js.is-revealing main,
html.js.is-revealing .site-footer {
  animation: pagePop 620ms var(--ease-back) both;
}
html.js.is-revealing main { animation-delay: 40ms; }
html.js.is-revealing .site-footer { animation-delay: 80ms; }

@media (prefers-reduced-motion: reduce) {
  html.js.is-revealing .site-header,
  html.js.is-revealing main,
  html.js.is-revealing .site-footer { animation: none; }
}
