.Hero__hero {
  position: relative;
  min-height: 100vh;
  overflow: hidden;
  isolation: isolate;

  opacity: 0.5;
  filter: saturate(0.25);
  transition:
    opacity var(--dur) var(--ease),
    filter var(--dur) var(--ease);
}

.Hero__hero.Hero__resolved {
  opacity: 1;
  filter: saturate(1);
}

@media (min-width: 1024px) and (hover: hover) {
  .Hero__hero {
    filter: saturate(0.25) blur(4px);
  }

  .Hero__hero.Hero__resolved {
    filter: saturate(1) blur(0px);
  }
}

/**
 * On desktop the stage generates no box at all, so every layer inside it keeps
 * resolving against the section exactly as before and the ScrollTrigger pins
 * the section itself. The wrapper exists purely for touch.
 */
.Hero__stage {
  display: contents;
}

.Hero__plane {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

/**
 * The one radial gradient the design allows. Low and centred, so the wordmark
 * sits in a pool of light rather than on a flat field.
 */
.Hero__fog {
  position: absolute;
  inset: 0;
  z-index: 0;
  background: radial-gradient(
    ellipse 70% 55% at 50% 58%,
    rgb(58 58 64 / 38%) 0%,
    transparent 70%
  );
}

/**
 * Deliberately wider than any viewport. The word runs off both edges so the
 * frame is cropping it — the page reads as a shot of the name, not a logo
 * centred in a box.
 */
.Hero__wordmark {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  margin: 0;
  font-size: clamp(8rem, 40vw, 30rem);
  font-weight: 500;
  line-height: 0.88;
  letter-spacing: -0.03em;
  text-transform: uppercase;
  white-space: nowrap;
  color: transparent;
  -webkit-text-stroke: 1px var(--grey-2);
  user-select: none;
}

.Hero__reelWrap {
  position: absolute;
  top: 50%;
  left: 50%;
  z-index: 2;
  display: grid;
  /* The frame's size is the only knob for how big the figure reads — the
     sprite is sized as a percentage of it. */
  width: 700px;
  max-width: 88vw;
  transform: translate(-50%, -50%);
}

.Hero__frame {
  position: relative;
  aspect-ratio: 16 / 9;
  /* Scale runs from here, so the frame opens symmetrically from its centre. */
  transform-origin: center center;
  /* Clips the figure to the frame as it opens — he is a subject inside a shot,
     not a cutout laid over the page. */
  overflow: hidden;
}

.Hero__content {
  position: relative;
  z-index: 3;
  display: grid;
  align-content: end;
  min-height: 100vh;
  padding: clamp(2rem, 6vw, 7rem);
  pointer-events: none;
}

.Hero__scrub {
  position: absolute;
  bottom: clamp(1.5rem, 4vh, 3rem);
  left: 50%;
  display: grid;
  justify-items: center;
  gap: 0.6rem;
  transform: translateX(-50%);
  color: var(--grey-3);
  animation: scrub-pulse 2.4s var(--ease) infinite;
}

@keyframes scrub-pulse {
  0%,
  100% {
    opacity: 0.35;
  }
  50% {
    opacity: 1;
  }
}

/**
 * Touch. The picture holds still while the page keeps scrolling underneath it.
 *
 * This is not the pin: nothing takes the scroll away, the finger moves the page
 * at its normal rate the whole time, and flicking past it works. Only the stage
 * stays put — which is the part that was actually wrong before, because the
 * hero travelled 1:1 with scroll and he was off the top of the phone by the
 * time the turn was half done. Nobody on mobile ever saw him finish turning.
 *
 * The extra height IS the hold: a sticky box stays stuck for its parent's
 * height minus its own, so the hero is one screen of stage plus the same beats
 * the ScrollTrigger scrubs over.
 */
@media (max-width: 720px) {
  .Hero__hero {
    min-height: calc((1 + var(--hold-vh, 1.5)) * 100vh);
    /* Sticky does nothing inside a clipping ancestor. The clip belongs on the
       stage anyway — it is the box the wordmark overruns. */
    overflow: visible;
  }

  .Hero__stage {
    display: block;
    position: sticky;
    top: 0;
    height: 100vh;
    overflow: hidden;
  }
}

@media (prefers-reduced-motion: reduce) {
  .Hero__hero,
  .Hero__hero.Hero__resolved {
    filter: none;
  }

  .Hero__hero {
    transition: opacity var(--dur) var(--ease);
  }

  .Hero__plane,
  .Hero__frame {
    transform: none !important;
  }

  .Hero__scrub {
    animation: none;
    opacity: 1;
  }
}
