/* =========================================================
   PANTRY approach section
   A process timeline. Desktop and tablet: the image and a red fill with
   one tick per step on the middle grid line stay pinned while the step
   text scrolls past. Phones and reduced motion: the steps
   stack, image then text. The grid line right of the text is hidden here.
   Motion lives in scripts/approach.js. Values come from tokens.css; the
   ones below only apply to this section.
   ========================================================= */

.approach {
  /* One step per pinned screen. */
  --approach-step-height: var(--stage-height);

  /* Square image box: about half the pinned screen, and always this far
     inside its column, so the images sit quietly beside the text. */
  --approach-media-max: calc(var(--stage-height) * 0.55);
  --approach-media-inset: var(--space-32);

  /* Scrub, read by JS. Share of the scroll between two steps over which
     image and text change (0 to 1); the rest of the time they hold. */
  --approach-crossfade-window: 0.6;
  /* Scale of an image as it arrives and as it leaves. */
  --approach-enter-scale: 0.7;
  --approach-exit-scale: 1.06;
  /* Scroll smoothing: share of the remaining distance caught up per frame. */
  --approach-lerp: 0.12;

  /* Ticks on the line, one per step. */
  --approach-tick-width: var(--space-12);
  --approach-tick-height: calc(var(--line-width) * 2);

  /* Phones: an image grows from this scale to full size over this share of
     the screen as it comes up (read by JS). */
  --approach-grow-scale: 0.86;
  --approach-grow-span: 0.6;
  --approach-step-gap: var(--space-96);

  /* Hides the grid line right of the text. Wider than the line's sideways
     sway (5px in scripts/lines.js). */
  --approach-mask-width: var(--space-12);

  padding-bottom: var(--space-64);
  overflow-x: clip;
}

/* ---------- Hidden grid line ----------
   The text spans two bays on desktop, so the line between them is covered
   from the top of the section to the bottom. It sits above the page lines
   and below everything else. JS places it; it is hidden below desktop. */

.approach-mask {
  position: absolute;
  z-index: -1;
  top: var(--line-width);
  bottom: 0;
  left: 0;
  width: var(--approach-mask-width);
  background: var(--color-canvas);
  transform: translateX(-50%);
  pointer-events: none;
}

.approach-mask[hidden] {
  display: none;
}

/* No plus marks on the hidden line. */
.approach > .marks .plus.at-75 {
  display: none;
}

/* ---------- Pinned stage ----------
   The stage is one screen tall and sticks to the top of the track. The
   steps pull up by one screen, so they scroll through the same space and
   the stage lets go exactly when the last step is in place.
   The track pulls up by the empty space above the image (measured by JS),
   so the image starts the usual title-to-body gap under the title. */

.approach-track {
  position: relative;
  margin-top: calc(var(--space-title-body) - var(--approach-frame-top, 0px));
}

.approach-stage {
  position: sticky;
  top: 0;
  z-index: 1;
  height: var(--approach-step-height);
  pointer-events: none;
}

.approach-stage > .container {
  height: 100%;
}

.grid-12.approach-stage-grid {
  height: 100%;
  row-gap: 0;
  align-items: center;
}

/* ---------- Image ----------
   Media: the column runs line to line. The images sit straight on the
   grid, no frame, centred in the column. JS scales and fades them; only
   transform and opacity change. */

.approach-frame {
  position: relative;
  width: min(100% - var(--approach-media-inset) * 2, var(--approach-media-max));
  aspect-ratio: 1;
  margin-inline: auto;
}

.approach-slide {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  opacity: 0;
  user-select: none;
  will-change: opacity, transform;
}

/* ---------- Line: fill and ticks ----------
   JS places the rail on the middle grid line, measured the same way as the
   page lines (scripts/lines.js), from the top of the image to its bottom.
   The fill reaches a tick when that step is in place. */

.approach-rail {
  position: absolute;
  top: 0;
  left: 0;
  width: var(--line-width);
  height: 0;
}

.approach-fill {
  position: absolute;
  inset: 0;
  background: var(--color-red-signal);
  transform: scaleY(0);
  transform-origin: top;
}

/* A tick is a short rule across the line, at the end of each step's share
   of the rail (JS sets top). Rule colour until its step is reached, then red. */
.approach-tick {
  position: absolute;
  left: calc(var(--line-width) / 2);
  width: var(--approach-tick-width);
  height: var(--approach-tick-height);
  margin: calc(var(--approach-tick-height) / -2) 0 0 calc(var(--approach-tick-width) / -2);
  background: var(--color-rule);
}

.approach-tick::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--color-red-signal);
  opacity: 0;
  transition: opacity var(--duration) var(--ease);
}

.approach-tick.is-filled::after {
  opacity: 1;
}

/* ---------- Step text ---------- */

.approach-stage + .container {
  margin-top: calc(var(--approach-step-height) * -1);
}

.grid-12.approach-steps {
  row-gap: 0;
}

/* Each step is a full-width row on the same grid. Pinned: one screen tall,
   the text centred on the middle of the image. */
.grid-12.approach-step {
  row-gap: 0;
  align-items: center;
  min-height: var(--approach-step-height);
}

.approach-step-media {
  display: none;
}

/* Desktop: the two bays right of the middle line. Tablet: the right bay. */
.approach-step-body {
  grid-column: calc(var(--grid-columns) / 2 + 1) / span var(--d);
  border-top: var(--line-width) solid var(--color-rule);
  padding-top: var(--space-16);
  opacity: 0;
  will-change: opacity;
}

@media (max-width: 1023px) {
  .approach-step-body {
    grid-column: calc(var(--grid-columns-tablet) / 2 + 1) / span var(--t);
  }
}

/* Three voices from the same copy: a big thin mono numeral in red, the
   heavy title, then the first sentence a size up in ink with the rest in
   the usual grey lead. */
.approach-step-number {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--text-display-size);
  font-weight: var(--text-label-weight);
  line-height: var(--text-display-lh);
  letter-spacing: var(--text-display-ls);
  font-variant-numeric: tabular-nums;
  color: var(--color-red-signal);
}

.approach-step-title {
  margin-top: var(--space-24);
}

.approach-step-text {
  margin-top: var(--space-24);
}

.approach-step-lede {
  display: block;
  margin-bottom: var(--space-12);
  font-size: var(--text-item-size);
  line-height: var(--text-item-lh);
  letter-spacing: var(--text-item-ls);
  color: var(--color-ink);
}

/* ---------- Stacked: phones and reduced motion ----------
   No pinning. Each step is a row: image then text. On phones the image
   sits on top, full width; with reduced motion on wider screens it sits
   left of the text, as in the pinned layout. Images show at full size. */

@media (max-width: 639px), (prefers-reduced-motion: reduce) {
  .approach-stage {
    display: none;
  }

  .approach-track {
    margin-top: var(--space-title-body);
  }

  .approach-stage + .container {
    margin-top: 0;
  }

  .grid-12.approach-step {
    min-height: 0;
  }

  .grid-12.approach-step + .approach-step {
    margin-top: var(--approach-step-gap);
  }

  .approach-step-media {
    display: block;
  }

  .approach-step-img {
    display: block;
    width: min(100% - var(--approach-media-inset) * 2, var(--approach-media-max));
    height: auto;
    margin-inline: auto;
    user-select: none;
  }

  .approach-step-body {
    opacity: 1;
    will-change: auto;
  }
}

@media (max-width: 639px) {
  .grid-12.approach-step {
    row-gap: var(--space-24);
  }

  .approach-step-media,
  .approach-step-body {
    grid-column: 1 / -1;
  }

  /* The ASCII canvas (scripts/ascii.js) lies over the image and grows
     with it. */
  .approach-step-media {
    position: relative;
  }

  .approach-step-img,
  .approach-step-media .ascii-canvas {
    transform-origin: center bottom;
    will-change: transform;
  }
}

@media (min-width: 640px) and (prefers-reduced-motion: reduce) {
  .approach-step-media {
    grid-column: 1 / span var(--t);
  }
}

@media (min-width: 1024px) and (prefers-reduced-motion: reduce) {
  .approach-step-media {
    grid-column: 1 / span var(--d);
  }
}
