/* ==========================================================================
   DIVLAB PRELOADER — the homepage intro
   --------------------------------------------------------------------------
   Pairs with dvl-preloader.js. Standalone: imports nothing, and removing the
   pair removes the feature with no trace on the header or the hero.

   RUNS ONCE PER SESSION, ON THE HOMEPAGE ONLY. The gate is in the script
   (sessionStorage), not here — a stylesheet cannot know whether the visitor
   has already seen it, and shipping the markup hidden would still cost a
   paint on every navigation.

   The backdrop is #F2F2F2 and the type is #3A301E, per the brief — the dark
   field in the mockups is deliberately not reproduced.
   ========================================================================== */

:root {
  --dvl-pre-bg: #f2f2f2;
  --dvl-pre-ink: #3a301e;

  /* The word size. Measured off the storyboard: "Presence" spans roughly
     400px of a 1920 frame at this weight, which is ~72px. Fluid so it does
     not dominate a phone, where the same word has a third of the width. */
  --dvl-pre-word: clamp(34px, 3.75vw, 72px);

  /* The logo as it sits mid-screen, before it flies to the header. */
  --dvl-pre-logo: clamp(96px, 9vw, 172px);
}

/* ==========================================================================
   THE SHEET
   --------------------------------------------------------------------------
   z-index 99999: above the header (100 normally, 9500 with the menu open)
   and above every WebGL canvas on the page. Nothing should ever be in front
   of this while it is up.

   It is painted BEFORE the script runs. The element is written into the DOM
   by dvl-preloader.js at the top of <body>, but this rule is what stops the
   hero flashing in the gap between first paint and the first GSAP frame —
   so html.dvl-pre-armed is set by an inline class the moment the script
   parses, and removed when the sequence ends.
   ========================================================================== */
.dvl-pre {
  position: fixed;
  inset: 0;
  z-index: 999999;
  background: var(--dvl-pre-bg);

  /* Nothing underneath is meant to be reachable while this is up. */
  touch-action: none;
  overscroll-behavior: contain;

  /* GSAP drives every property here; a CSS transition on a scripted value
     does not smooth it, it fights it. Same rule the pinned sections needed. */
  transition: none !important;
}

/* ---- CENTRED BY GRID, NOT BY A TRANSLATE -----------------------------
   Both children occupy the SAME grid cell, so they stack without either
   reflowing the other, and `place-items: center` on the sheet puts that
   cell's contents dead centre. No positioning, no offset, nothing for the
   animation to overwrite.

   IT WAS `position:absolute; left:50%; top:50%; translate(-50%,-50%)` AND
   THAT IS THE BUG. GSAP animates `y` on the word and `scale` on the logo,
   and it writes those through the `transform` property — which REPLACES
   the centring translate on the very first frame. The element is then
   positioned with its top-left corner at the centre of the screen, so it
   renders down and to the right by half its own size. That is the
   off-centre drift in the review: not a centring mistake, a centring
   method that the animation destroys.

   Grid survives it because x/y/scale then compose on top of a box that is
   already where it should be, rather than being the only thing holding it
   there. The FLIP in dvl-preloader.js depends on this too: it measures the
   logo's rect and animates a delta, which is only correct if the resting
   position does not itself depend on a transform. */
.dvl-pre {
  display: grid;
  place-items: center;
}

.dvl-pre__word,
.dvl-pre__logo {
  grid-area: 1 / 1;
  text-align: center;
}

.dvl-pre__word {
  font-family: 'Inter', system-ui, sans-serif;
  font-weight: 300;
  font-size: var(--dvl-pre-word);
  line-height: 1.1;
  letter-spacing: var(--dvl-display-tracking, -0.061em);
  color: var(--dvl-pre-ink);
  white-space: nowrap;
  opacity: 0;
}

.dvl-pre__logo {
  width: var(--dvl-pre-logo);
  height: auto;
  opacity: 0;
  /* The FLIP measures this element's box, so it must not be scaled by
     anything other than the animation itself. */
  transform-origin: center center;
}

/* The page does not scroll while the sheet is up.

   overflow on the root rather than position:fixed on <body>: the homepage is
   driven by ScrollTrigger pins, and taking <body> out of flow would
   invalidate every pin's measurements and force a full recalculation when
   the class came off. */
html.dvl-pre-lock,
html.dvl-pre-lock body {
  overflow: hidden !important;
  overscroll-behavior: none;
}

/* THE HEADER LOGO IS HIDDEN UNTIL THE FLIGHT LANDS.

   The preloader animates its OWN copy of the logo into the header's
   position. Both being visible for the last frame of that flight is a
   visible double-image, so the real one is held back and revealed at the
   moment the flying copy is removed — which is what makes the hand-off read
   as one object arriving rather than two.

   visibility, not opacity: the FLIP measures the header logo's box with
   getBoundingClientRect() and a display:none element has no box at all. */
html.dvl-pre-armed .dvl-header img {
  visibility: hidden;
}

/* ==========================================================================
   REDUCED MOTION
   --------------------------------------------------------------------------
   The words and the flight are the whole feature, so there is nothing to
   degrade gracefully into — the sequence is skipped entirely in the script
   and the sheet never mounts. This rule only guarantees that if the class
   were somehow left on, nothing stays hidden.
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  html.dvl-pre-armed .dvl-header img {
    visibility: visible;
  }
}
