/* ============================================================
   LET MARK COOK — 06 hero graphics

   A separate file on purpose. The hero's existing furniture — the orbit,
   the sparks, the glow — lives in css/02-hero.css alongside the coat
   reveal, and that file is not to be touched. Everything here is new,
   sits behind all of it, and can be deleted whole without the reveal
   noticing.

   Driven by its own animation rather than by scroll: the stage is pinned,
   so an element inside it barely moves relative to the viewport and
   parallax would do almost nothing. Continuous slow motion is what fills
   the frame while Mark is held still.
   ============================================================ */

.haze {
  position: absolute;
  inset: 0;
  z-index: 0;          /* behind the orbit and the portrait, both later siblings */
  overflow: hidden;
  pointer-events: none;
}

/* ---------- turning rings ----------
   A plain circle rotating is invisible — it maps onto itself. Each ring is
   therefore transparent except for two arcs, so there is something for the
   eye to follow round. Three of them at different sizes, speeds and
   directions read as depth rather than as one spinning hoop. */
.haze__ring {
  position: absolute;
  left: 50%;
  top: 50%;
  border-radius: 50%;
  border: 1px solid transparent;
  border-top-color: rgba(255, 90, 31, .55);
  border-right-color: rgba(247, 244, 238, .16);
  transform: translate(-50%, -50%);
  will-change: transform;
}

@keyframes haze-turn {
  from { transform: translate(-50%, -50%) rotate(0deg); }
  to   { transform: translate(-50%, -50%) rotate(360deg); }
}

.haze__ring--1 { width:  86vmin; height:  86vmin; animation: haze-turn  64s linear infinite; }
.haze__ring--2 { width: 122vmin; height: 122vmin; animation: haze-turn 104s linear infinite reverse; border-top-color: rgba(255,162,58,.40); }
.haze__ring--3 { width: 168vmin; height: 168vmin; animation: haze-turn 156s linear infinite; border-top-color: rgba(247,244,238,.14); }

/* ---------- dot field ----------
   Masked to an ellipse so it fades out well before the edges instead of
   ending on a visible rectangle, and drifting slowly so the hero is never
   completely still even before anyone scrolls. */
.haze__grid {
  position: absolute;
  inset: -12%;
  background-image: radial-gradient(rgba(247, 244, 238, .13) 1px, transparent 1px);
  background-size: 34px 34px;
  -webkit-mask-image: radial-gradient(ellipse at center, #000 0%, transparent 66%);
  mask-image: radial-gradient(ellipse at center, #000 0%, transparent 66%);
  animation: haze-drift 34s ease-in-out infinite alternate;
  will-change: transform;
}
@keyframes haze-drift {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(0, -28px, 0); }
}

/* ---------- the name, set enormous and almost invisible ----------
   Deliberately far below the threshold where it competes with the wordmark
   that rises later — it is texture, and should read as a shape long before
   it reads as words. */
/* ---------- the watermark, which becomes the headline ----------
   A deliberate clone of .headline: the same display face, the same
   clamp, the same .84 line-height, the same -.04em tracking and the
   same flex-wrap with the same .28em gap — and stretched edge to edge
   with the same gutter, so it breaks across lines at exactly the same
   points. Identical metrics are the whole trick: at the end of the
   handover it is scale 1 sitting on the real wordmark, so the two are
   the same width and the same shape and read as one thing resolving.

   js/07-stage.js already publishes the headline's arrival as --r-o on
   the stage, and custom properties inherit — so this needs no
   javascript and that file is never touched. */
.haze__word {
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  padding-inline: var(--gutter);

  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0 .28em;

  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(2.6rem, min(14vw, 15vh), 9rem);
  font-size: clamp(2.6rem, min(14vw, 15svh), 9rem);
  line-height: .84;
  letter-spacing: -.04em;
  text-transform: uppercase;
  color: transparent;
  -webkit-text-stroke: 1px rgba(247, 244, 238, .055);

  --hand: var(--r-o, 0);

  /* Two stages, deliberately offset, because running both off the same
     number is what stopped it reading as a merge: the watermark was still
     37% larger than the headline halfway through, and by the time it
     reached 1:1 it had already faded out. There was never a frame where
     the two were actually superimposed.

     --settle finishes first (by about 0.55): the watermark arrives at the
     headline's exact size and position and sits on it. --fade only starts
     at 0.45, so there is a real overlap where one is lying on top of the
     other before it dissolves. That hold is the merge. */
  /* Two different signals, both already published by js/07-stage.js, so the
     convergence happens WHILE you scroll down through the hero instead of
     all at the end.

     --o-o is the orbit fading out across the early part of the runway, so
     one minus it is a 0-to-1 ramp that starts as soon as you scroll. The
     watermark is therefore travelling from the first moment. --r-o is the
     headline arriving, later — so by the time the fade begins the watermark
     has already settled onto the title and the two lie on top of each other
     for a real stretch before it dissolves.

     --hw-dy is measured by js/10-watermark.js. It has to be: a fixed offset
     lands at one screen height and falls past the title on any other. */
  --settle: calc(1 - var(--o-o, 1));
  /* The fade is held back so the watermark is still clearly there for the
     stretch where it is lying on the title. Straight --r-o put it at 16%
     opacity before the headline had finished arriving. */
  --fade:   clamp(0, calc((var(--r-o, 0) - .3) / .7), 1);

  opacity: calc(.9 * (1 - var(--fade)));

  /* --hw-dy is where the headline FINISHES. But the headline is still moving
     while this is happening: .stage__reveal slides up on its own --r-y as it
     arrives. Landing on the final spot alone meant settling on empty space
     32px above a title that had not got there yet. Adding --r-y makes the
     watermark track where the headline actually is, frame by frame, so the
     two genuinely meet. */
  transform:
    translateY(-50%)
    translateY(calc(var(--settle) * (var(--hw-dy, 0px) + var(--r-y, 0rem))))
    scale(calc(1.75 - var(--settle) * .75));
  transform-origin: center center;
}

.haze__word i {
  display: flex;
  font-style: normal;
}

.haze__word i {
  display: block;
  font-style: normal;
}

@media (prefers-reduced-motion: reduce) {
  .haze__ring, .haze__grid, .haze__word { animation: none; }
}

/* ---------- runway length ----------
   An override, not an edit: css/02-hero.css sets .stage to 260svh (290 on a
   touch screen) and that file is not to be touched, but this sheet loads
   after it at the same specificity, so the value here wins.

   The whole sequence — coat, lift, wordmark — is expressed as fractions of
   this height, so shortening it compresses all of them together and nothing
   in js/07-stage.js needs to know. Roughly a third less scrolling to reach
   the same place. Note js still sets an inline 190svh on very short screens,
   which correctly overrides this. */
.stage { height: 180vh; height: 180svh; }

@media (pointer: coarse) {
  .stage { height: 200vh; height: 200svh; }
}
