/* ==========================================================================
   Sustainability — the descent.

   The page is one fall, and one film.  A single stage is pinned for the
   whole of it and the reader's scroll is the only clock:

     0.00 → 0.20    above     the valley from the air
     0.20 → 0.40    surface   the fall ends on the vineyard floor
     0.40 → 0.60    under     through the soil, among the roots
     0.60 → 0.80    loop      back up the way we came, to the water
     0.83 → 0.905   proof     the animal, breathing, and the argument
     0.905 → 1.00   focus     the surround softens, the circle opens on it
                              and the three marks arrive beside it

   The first four are one continuous generated take, scrubbed frame by frame
   to the wheel: nothing plays by itself.  Every clip in it opens on the
   exact frame the last one closed on, the first is seeded from a real frame
   of the winery's own about-mid footage, and the last is pinned to end on
   the Terrain page's photograph of the Cyprus water frog — so the film does
   not cut to the animal, it arrives at it.

   The fall is monochrome and the colour returns at the water.  That is the
   whole argument in one gesture, and it costs a sentence of copy instead of
   a page of them.

   The animal is a second film rather than the last frame of the first,
   because at the end of the page the reader stops scrolling and a scrubbed
   film stops with them.  This one keeps breathing.
   ========================================================================== */

.sustainability { position: relative; background: var(--c-page); }
.sustainability > section:not(.sust__closing) { position: relative; z-index: 1; }

/* ---- The scroll track --------------------------------------------------- */
/* Twenty seconds of film across five movements.  700vh gives each a little
   over a screen of scroll, which is slow enough to read and slow enough that
   the fall still feels like falling. */
.descent {
  position: relative;
  height: 780vh;
  background: var(--c-black);
}

.descent__stage {
  position: sticky;
  top: 0;
  height: 100vh;
  overflow: hidden;
  background: var(--c-black);
  isolation: isolate;
}

/* ---- The film ----------------------------------------------------------- */
.descent__film { position: absolute; inset: 0; z-index: 1; }

.descent__video,
.descent__frog {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Below the design width the stage is narrower than 16:9 and cover crops the
   sides away, which moves the animal off the 44% the spotlight is aimed at —
   on a phone it slid to 27%.  Anchoring the crop on the animal's own eye
   keeps it at 44% of the box whatever the shape of the box.

   BOTH films, not just the animal's.  The fall ends on the same shot the
   animal's clip opens on — the frog surfacing — so the two are one cut, and
   they were being cropped from different anchors: the fall from the default
   50% and the clip from 44%.  Identical footage, 72px apart on a 412px phone,
   which is the animal jumping sideways at the moment the cut lands.  Measured
   frame against frame the two sources match exactly — scale 1.00, dx 0, dy 0
   — so the jump was never in the film, only in how it was being placed. */
.descent__video,
.descent__frog { object-position: 44% 46%; }

/* The animal arrives full frame and in focus, and stays that way while the
   last movement is read.  Then the softness closes in from the edges of the
   picture towards the animal's eye, until only a circle of it is still sharp.

   That is the reverse of the way Terrain opens its spotlight, and it is the
   reverse for a reason: here the reader is looking at the animal itself for
   the length of a paragraph, so the picture has to be worth looking at whole
   before anything is taken away from it.

   --close runs 1 (wide open, the softness off the edge of the frame) to 0
   (settled on the eye), driven by the scroll timeline in js/sust-descent.js.

   Measured off the clip's own poster frame: the animal's eye sits at 44% of
   the width and 46% of the height.  The softness is aimed at the animal, not
   at the middle of the picture. */
.descent {
  --spot-x: 44%;
  --spot-y: 46%;
  /* The same circle the home map and the Terrain frog focus through: those two
     open a 33.1rem sharp circle under a 70.6rem dotted ring, and this was a
     27rem circle under a 57.5rem ring — 18% smaller, which is what made the
     three marks overhang it and the group read as sitting too low. */
  --spot-r: 33.1rem;

  /* Far enough out that the hole clears the frame on any shape of screen.
     The longest run is spot-to-corner; 56vw + 54vh is that hypotenuse's
     upper bound, which overshoots by about a third and never falls short —
     hypot() would be exact but an unsupported mask declaration would drop
     the whole rule and leave the picture permanently soft. */
  --spot-open: calc(56vw + 54vh);
}

/* The soft copy sits ON TOP of the sharp one now, with a hole cut in it, so
   the closing edge is a mask rather than a clip on the animal.  The hole's
   percentages resolve against this wrapper — the stage box — which is what
   keeps the edge concentric with the ring; the bleed lives on the image
   inside, where it cannot shift them. */
.descent__frogblur {
  position: absolute;
  inset: 0;
  z-index: 3;
  overflow: hidden;
  pointer-events: none;
  will-change: -webkit-mask-image, mask-image;
  --hole: calc(var(--spot-r) + (var(--spot-open) - var(--spot-r)) * var(--close, 1));
  -webkit-mask-image: radial-gradient(circle var(--hole) at var(--spot-x) var(--spot-y),
                                      transparent 97%, #000 100%);
          mask-image: radial-gradient(circle var(--hole) at var(--spot-x) var(--spot-y),
                                      transparent 97%, #000 100%);
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
}

/* Bled past the frame so the blur's own faded edge falls outside the wrapper
   and is cropped by its overflow, rather than showing as a soft border — the
   same trick terrain.css uses.

   The size has to be stated.  On an absolutely positioned replaced element
   all four insets do not stretch it: with width/height auto the image keeps
   its intrinsic 1280x720 and the right and bottom offsets are dropped.

   The darkening is carried in the same filter rather than by a pseudo-element,
   because an <img> is replaced content and cannot generate one.
   brightness(0.6) is the same multiply a 40% black cover would have made. */
.descent__frogblur img {
  position: absolute;
  inset: -3rem;
  width: calc(100% + 6rem);
  height: calc(100% + 6rem);
  max-width: none;              /* the reset's img cap would trim the bleed */
  object-fit: cover;
  object-position: 44% 46%;
  filter: blur(1.5rem) brightness(0.6);
}

}

/* The ring is not on the closing edge the whole way in — it would spend most
   of the move off-screen.  It arrives at the finished size as the edge
   settles onto it. */
.descent__ring {
  position: absolute;
  z-index: 4;
  opacity: 0;
  pointer-events: none;
  will-change: opacity;
  left: var(--spot-x);
  top: var(--spot-y);
  width: var(--ring-d);
  height: var(--ring-d);
  transform: translate(-50%, -50%);
}

/* Full frame and in focus — what is sharp is now decided by the hole in the
   layer above, not by a clip on this one.

   It is held down to 0.55 while the last movement is being read, and comes up
   to full as the softness closes.  The picture used to be carrying the soft
   layer's own brightness(0.6) by this point, so without something here the
   copy would be reading against a picture nearly twice as bright as the one
   it was set against: measured over the body text, white on it fell from
   4.4:1 to 3.3:1, and to 1.9:1 at the lightest tenth.  0.55 puts it at about
   5.3:1, which is better than it was, and the lift afterwards lands the
   brightness on the eye at the same moment the focus does. */
.descent__frog {
  z-index: 2;
  opacity: 0;
  filter: brightness(calc(1 - 0.45 * var(--close, 1)));
  will-change: opacity, filter;
}

/* Legibility for the copy, and the same top darkening the rest of the
   site's heroes use so the white header reads over the picture. */
.descent__scrim {
  position: absolute;
  inset: 0;
  z-index: 5;
  pointer-events: none;
  background:
    linear-gradient(to bottom, rgba(0,0,0,0.55) 0%, rgba(0,0,0,0) 32%),
    linear-gradient(to top,
      rgba(0,0,0,0.88) 0%,
      rgba(0,0,0,0.62) 24%,
      rgba(0,0,0,0.24) 46%,
      rgba(0,0,0,0)    64%);
}

/* ---- The copy ----------------------------------------------------------- */
.descent__copy { position: absolute; inset: 0; z-index: 4; pointer-events: none; }

.mv {
  position: absolute;
  left: var(--page-x);
  bottom: 11rem;
  width: 96rem;
  color: #fff;
  opacity: 0;
  transform: translateY(2.4rem);
  will-change: opacity, transform;
}

/* The opening statement is the same object as the Manifesto's and the
   Terrain's: .editorial carries the face, the size and the line height, and
   responsive.css already rescales --fs-editorial at every breakpoint, so
   this rule only has to undo .editorial's ink colour and give it room. */
.mv__statement {
  color: inherit;
  margin: 0;
}

/* Six lines of editorial need more width than the four movements that
   follow it. */
.mv--above { width: 140rem; }

.mv__lede {
  font-family: var(--f-body);
  font-weight: var(--fw-light);
  font-size: var(--fs-lead);
  line-height: var(--lh-lead);
  margin: 2.4rem 0 0;
  opacity: 0.86;
}

/* The label is the site's own .eyebrow and nothing else — this rule only
   places it and lets it take the movement's colour.  Setting the face by
   hand here was the mistake it replaces: CF Din Condensed carries a
   letter-spacing of -0.06em everywhere on the site, and spacing it out to
   +0.16em instead made the same typeface read as a different one. */
.mv__label {
  margin: 0 0 2.4rem;
  color: inherit;
  opacity: 0.78;
  /* Barlow Condensed, with the wine pages' spec labels — the client's call.
     The tracking comes down with it: --ls-ui's -0.06em was measured on the
     CF Din stand-in, and Barlow Condensed is the narrower face already. */
  font-family: var(--f-display);
  letter-spacing: -0.02em;
}

/* Same object as .terrain__heading and .about__heading: the editorial size
   from the type scale, and the face's own line height. */
.mv__heading {
  font-family: var(--f-editorial);
  font-weight: var(--fw-light);
  font-size: var(--fs-heading);
  line-height: normal;
  font-variation-settings: 'wdth' 100;
  font-optical-sizing: auto;
  margin: 0 0 2.6rem;
}

.mv__body {
  font-family: var(--f-body);
  font-weight: var(--fw-light);
  font-size: var(--fs-lead);
  line-height: var(--lh-lead);
  width: 69.5rem;
  margin: 0;
}

.mv__body--last { margin-top: 2.4rem; }


/* ---- The three marks, beside the animal --------------------------------- */
/* Laid out like terrain.css's frog facts: parked off the right edge, each
   arriving on its own, and not flush with one another — the middle one steps
   further out, which is what stops the group reading as a column stuck to
   the side of a circle. */
.marks {
  position: absolute;
  inset: 0;
  z-index: 5;
  list-style: none;
  margin: 0;
  padding: 0;
  pointer-events: none;
  color: #fff;
}

.marks__item {
  position: absolute;
  --mark-x: 27rem;
  left: calc(var(--spot-x) + var(--mark-x));
  width: var(--fact-w);
  opacity: 0;
  transform: translateX(6rem);
  will-change: opacity, transform;
}

/* Placed by the shared rule documented in home.css: tops 24rem apart, the
   first 24rem + half the last card's height above the ring centre, and the x
   the ring's reach at each icon plus the shared 18rem standoff. */
/* The tops are offsets from the ring's own centre, not percentages of the
   section, so the block cannot drift off the circle when the viewport
   changes shape. */
.marks__item--organic { top: calc(var(--spot-y) - 38rem);   --mark-x: 38.71rem; }
.marks__item--vegan   { top: calc(var(--spot-y) - 8.8rem);  --mark-x: 43.3rem; }
.marks__item--loop    { top: calc(var(--spot-y) + 20.4rem); --mark-x: 36.81rem; }

.marks__icon {
  display: block;
  height: 4rem;
  width: auto;
  margin: 0 0 var(--fact-gap);
  /* The marks are drawn in ink for a white page; here they are white. */
  filter: brightness(0) invert(1);
}

.marks__body {
  margin: 0;
  font-family: var(--f-body);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  font-weight: var(--fw-regular);
}

.marks__body b {
  display: block;
  font-weight: var(--fw-extrabold);
  text-transform: uppercase;
}

/* The argument and the spotlight are two beats, not one crowded screen:
   the copy has the frame to itself, then it leaves and the circle opens. */

/* ---- Closing ------------------------------------------------------------ */
.sust__closing { background: var(--c-page); }

/* ---- Reduced motion ----------------------------------------------------- */
/* No pin, no scrub, no film: the five movements become five plain blocks in
   a column between the two poster frames, and neither video is ever fetched.
   Everything the page says, it still says. */
@media (prefers-reduced-motion: reduce) {
  .descent { height: auto; background: var(--c-page); }

  .descent__stage {
    position: static;
    height: auto;
    overflow: visible;
    background: var(--c-page);
    padding: 0 0 6rem;
    display: flex;
    flex-direction: column;
  }

  /* The two posters become siblings of the copy so they can be ordered
     around it: the fall opens the page, the animal closes it. */
  .descent__film { display: contents; }
  .descent__scrim { display: none; }

  .descent__video,
  .descent__frog {
    position: static;
    width: 100%;
    height: auto;
    object-fit: contain;
    opacity: 1;
    clip-path: none;
  }

  /* No spotlight to open, so there is nothing to blur around. */
  .descent__frogblur, .descent__ring { display: none; }

  .mv--proof { width: auto; }

  .marks {
    position: static;
    order: 1;
    display: flex;
    flex-wrap: wrap;
    gap: 3.2rem 5rem;
    color: var(--c-ink);
    margin: 0 auto 8rem;
    max-width: 96rem;
    padding: 0 var(--page-x);
  }
  .marks__item {
    position: static;
    left: auto; top: auto;
    width: 28rem;
    opacity: 1;
    transform: none;
  }
  .marks__icon { filter: none; }

  .descent__video { order: 0; margin-bottom: 10rem; }
  /* A column flex item will not shrink below its content's max-content
     width unless told to, and with the hard breaks gone the statement's
     max-content width is the whole paragraph on one line. */
  .descent__copy  { order: 1; position: static; min-width: 0; }
  .descent__frog  { order: 2; margin-top: 4rem; }

  .mv,
  .mv--above {
    position: static;
    opacity: 1;
    transform: none;
    width: auto;
    max-width: 96rem;
    margin: 0 auto 10rem;
    left: auto;
    bottom: auto;
    padding: 0 var(--page-x);
    color: var(--c-ink);
  }


  /* The opening statement is composed with hard line breaks for a 1328px
     hero, and global.css holds .editorial at white-space: nowrap above
     1367 so those breaks are honoured rather than re-wrapped.  So the
     static column has to be wide enough for them: 133rem leaves 1200px of
     content against the longest line's 1124. */
  .mv--above { max-width: 133rem; }
}
