/* ===========================================================================
   The site intro overlay.
   ===========================================================================
   One 16:9 master serves every device, which is what the aspect-ratio problem
   forces when there is only one file:

   · Landscape and desktop — `cover`. The clip fills the screen and loses at
     most 10-25% of an edge, which is inside the safe area.
   · Portrait — `cover` would show about a quarter of the frame width on a
     phone, which is unusable. So the whole frame is fitted to the width
     (`contain`) and the space above and below is filled by a scaled, blurred
     copy of the same file. Same asset, one network fetch, two decoders for
     four seconds. It reads as deliberate rather than as letterboxing.

   The wash layer is only built on portrait, so desktop never pays for it.
   =========================================================================== */

#intro {
  position: fixed;
  inset: 0;
  z-index: 9999;
  overflow: hidden;
  /* Matches the page ground, so the moment before the first frame decodes is
     a considered colour rather than a white flash. */
  background: #050608;
  /* Hidden until the script arms it. Without this the overlay would sit over
     the page for anyone with JavaScript disabled, or if this file loads and
     the script does not. Fail open, always. */
  display: none;
}

#intro.intro--armed { display: block; }

#intro.intro--done {
  opacity: 0;
  pointer-events: none;
  transition: opacity .5s ease-out;
}

#intro video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  /* Landscape and desktop: fill the screen. */
  object-fit: cover;
  object-position: center;
}

/* The blurred fill. Present in the markup but inert unless portrait needs it,
   so it costs nothing on a laptop. */
#intro video#intro-wash { display: none; }

/* NB the `#intro video#…` selectors below. `#intro video` above is one id plus a
   type selector, which out-specifies a bare `#intro-video` — so the portrait
   rules silently lost and the clip stayed cropped on phones. Matching the
   specificity is the fix; raising it with !important would only hide the next
   one of these. */
@media (orientation: portrait) {
  /* Fitted to the width, then pushed up ~45%. Straight `contain` left the clip
     occupying about a quarter of a phone screen with blurred bands doing the
     rest, which is safe and small. The subject sits in the middle third of the
     frame, so trimming a third of the width costs nothing and buys back half
     again as much height. Still nowhere near the 74% a plain `cover` would
     throw away. */
  #intro video#intro-video {
    object-fit: contain;
    transform: scale(1.45);
  }
  /* Behind it, the same footage blown up and blurred to fill the bands. */
  #intro video#intro-wash {
    display: block;
    object-fit: cover;
    transform: scale(1.25);
    filter: blur(34px) brightness(.55) saturate(1.1);
    z-index: -1;
  }
}

/* A quiet way out that does not compete with the film. */
#intro .intro-skip {
  position: absolute;
  right: 1.25rem;
  bottom: 1.15rem;
  z-index: 5;
  font: 600 .62rem/1 "IBM Plex Mono", ui-monospace, monospace;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, .55);
  background: rgba(0, 0, 0, .35);
  border: 1px solid rgba(255, 255, 255, .2);
  border-radius: 3px;
  padding: .5rem .75rem;
  cursor: pointer;
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
}
#intro .intro-skip:hover {
  color: #fff;
  border-color: rgba(255, 255, 255, .45);
}

/* Belt and braces. The script already removes the overlay for a visitor who
   has asked for less motion; this makes it true even if the script never runs. */
@media (prefers-reduced-motion: reduce) {
  #intro { display: none !important; }
}
