@layer sections {
  /* The hero is a tall track. Inside it a sticky stage holds the
     machine while --p (0 to 1) is written by the scroll driver. */
  .hero {
    position: relative;
    block-size: 320svh;
    --p: 0;
  }

  .hero__stage {
    position: sticky;
    inset-block-start: 0;
    block-size: 100svh;
    display: flex;
    flex-direction: column;
    justify-content: center;
    overflow: hidden;
  }

  /* Volcanic haze behind everything, drifts as you scroll. */
  .hero__haze {
    position: absolute;
    inset: -20%;
    background:
      radial-gradient(46% 40% at 22% 62%, oklch(0.665 0.192 38 / 0.16), transparent 68%),
      radial-gradient(40% 44% at 78% 34%, oklch(0.805 0.128 82 / 0.09), transparent 70%);
    transform: translate3d(0, calc(var(--p) * -8%), 0) scale(calc(1 + var(--p) * 0.14));
    pointer-events: none;
  }

  /* Oversized wordmark sits behind the machine and parts as it builds. */
  .hero__wordmark {
    position: absolute;
    inset-block-start: 50%;
    inset-inline: 0;
    translate: 0 -58%;
    font-family: var(--f-display);
    font-weight: 800;
    font-size: var(--t-3xl);
    line-height: 0.8;
    text-align: center;
    text-transform: uppercase;
    color: var(--c-basalt-up);
    letter-spacing: -0.03em;
    user-select: none;
    pointer-events: none;
    opacity: calc(1 - var(--p) * 0.45);
    transform: scale(calc(1 + var(--p) * 0.1));
  }

  .hero__art {
    position: relative;
    inline-size: min(112%, 1500px);
    margin-inline: auto;
    padding-inline: var(--gutter);
    transform: translate3d(calc(var(--p) * -3%), 0, 0) scale(calc(0.94 + var(--p) * 0.08));
    transform-origin: 55% 60%;
  }

  /* ---- ASSEMBLY -------------------------------------------------
     Each group flies in from its own vector. --p drives every one
     of them off a single scroll read. Stages are staggered by
     remapping --p per part in the script.                        */
  .hero .bike [data-part] {
    opacity: var(--part-o, 1);
    transform: translate3d(var(--part-x, 0), var(--part-y, 0), 0);
    transform-box: fill-box;
    transform-origin: center;
  }

  /* Wheels keep turning through the build. */
  .hero .bike .spin {
    rotate: calc(var(--p) * 900deg);
  }

  .hero__caption {
    position: absolute;
    inset-block-end: clamp(1.5rem, 5vh, 3.5rem);
    inset-inline: var(--gutter);
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--space-md);
    pointer-events: none;
  }

  .hero__caption p { max-inline-size: 34ch; font-size: var(--t-sm); }

  .hero__progress {
    inline-size: clamp(120px, 22vw, 280px);
    block-size: 2px;
    background: var(--c-basalt-hi);
    position: relative;
    overflow: hidden;
  }

  .hero__progress::after {
    content: "";
    position: absolute;
    inset: 0;
    background: var(--c-ember);
    transform: scaleX(var(--p));
    transform-origin: left;
  }

  /* ================================================================
     MOBILE OVERRIDES
     These must sit after the base rules above, not before them, or
     the equal-specificity base declarations win and the whole block
     silently does nothing.
     ================================================================ */
  @media (max-width: 47.9375rem) {
    /* Hero content pins to the top and clears the fixed nav (global
       convention). Padding is tightened from the standard 5rem/12rem
       because this hero is a single wide graphic rather than a text
       block; at the standard value the machine sat hard against the
       nav with a third of the stage empty beneath it. */
    .hero__stage {
      justify-content: flex-start;
      align-items: stretch;
      padding-block-start: max(
        calc(var(--nav-height, 74px) + env(safe-area-inset-top, 0px) + 1.25rem),
        5.25rem
      );
    }

    /* let the machine bleed past both gutters so it reads at phone width */
    .hero__art {
      inline-size: 132%;
      margin-inline: -16%;
      padding-inline: 0;
      transform: scale(calc(0.96 + var(--p) * 0.05));
    }

    /* wordmark rides up behind the machine rather than floating below it */
    .hero__wordmark {
      inset-block-start: 30%;
      translate: 0 -50%;
      font-size: clamp(3.5rem, 25vw, 7rem);
    }

    /* caption returns to normal flow so it closes up under the art
       instead of leaving a void in the middle of the stage */
    .hero__caption {
      position: static;
      inset: auto;
      flex-direction: column;
      align-items: flex-start;
      margin-block-start: var(--space-lg);
      padding-inline: var(--gutter);
    }
  }

  @media (orientation: landscape) and (max-height: 850px) and (pointer: coarse) {
    .hero { block-size: 240svh; }
    .hero__stage {
      justify-content: center;
      align-items: stretch;
      padding-block-start: calc(var(--nav-height, 74px) + env(safe-area-inset-top, 0px) + 0.5rem);
    }
    .hero__art { inline-size: 118%; margin-inline: -9%; }
    .hero__wordmark { font-size: clamp(2.5rem, 9vw, 5rem); inset-block-start: 50%; }
    .hero__caption { position: absolute; inset-block-end: 1rem; inset-inline: var(--gutter); }
  }

  @media (prefers-reduced-motion: reduce) {
    .hero { block-size: auto; }
    .hero__stage {
      position: static;
      block-size: auto;
      padding-block: var(--space-3xl);
    }
    .hero .bike [data-part] { opacity: 1; transform: none; }
    .hero .bike .spin { rotate: none; }
    .hero__haze, .hero__art, .hero__wordmark { transform: none; }
  }
}
