/* =========================================================================
   Velaccio — Showreel

   Three scroll-driven movements:

     • the headline reveals line by line, each line clipped by its own box
     • the video is shown full-bleed, held there, and then — once the stage
       starts passing the top — tucks itself into the bottom-right corner in
       one smooth pass, and opens back out on the way up. Scroll fires it;
       scroll does not drive it.
     • the copy behind it is always present but dim, and lights up letter by
       letter, scrubbed off scroll position so the wipe tracks the wheel

   No pinning: main-style.css sets body{overflow:hidden}, which makes body a
   scroll container, and position:sticky never activates inside one. Progress
   is scrubbed from the stage's position in the viewport instead.

   The headline deliberately uses the same rem values as the hero h1 (11.9rem
   / 5.8rem below 1100px) so the two read at identical size — main-style.css
   drives html{font-size} off vw, so those rem values are already fluid.
   Everything else is px/vw, since a rem here would track the viewport twice.
   ========================================================================= */

.vel-showreel {
  position: relative;
  padding: clamp(64px, 10vw, 160px) 0 clamp(56px, 8vw, 130px);
  background: transparent;
}

/* ---- headline ------------------------------------------------------------ */

.vsw-title {
  margin: 0 0 clamp(30px, 3.6vw, 68px);
  /* matched to .section-hero .s-title, down to the line-height */
  font-family: "ABC Gravity Compressed", sans-serif;
  font-size: 11.9rem;
  font-weight: 900;
  line-height: .8;
  letter-spacing: normal;
  text-transform: uppercase;
  color: #fff;
}

/* ---- stage --------------------------------------------------------------- */

/* As big as the column allows, capped so it can't outgrow the viewport. */
.vsw-stage {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  /* Was held down to 78vh so the tuck could fire while the box was still
     wholly in view. It now fires well before that, so the cap is free to go
     back up and the full-bleed state can be as large as it wants. */
  max-height: 84vh;
}

/* The copy the video is hiding. Behind it (z-index 1 against the frame's 2)
   and bottom-left, so it is fully covered while the video is full-bleed and
   uncovered as the video pulls into the corner. The width is the exact
   complement of the tucked video's 28%, so the copy runs right up to the
   video's resting edge without any of it ending up permanently underneath. */
.vsw-under {
  position: absolute;
  left: 0;
  bottom: 0;
  z-index: 1;
  width: 72%;
  display: flex;
  flex-direction: column;
  gap: clamp(12px, 1.4vw, 22px);
  padding-bottom: clamp(4px, .8vw, 14px);
}

.vsw-label {
  color: rgba(255, 255, 255, .5);
  font-family: "Acid Grotesk", system-ui, sans-serif;
  font-size: clamp(14px, 1.2vw, 20px);
  font-weight: 500;
  letter-spacing: .02em;
}

.vsw-text {
  margin: 0;
  color: #fff;
  font-family: "Acid Grotesk", system-ui, sans-serif;
  font-weight: 400;
  font-size: clamp(24px, 2.75vw, 48px);
  line-height: 1.22;
  letter-spacing: -.01em;
}

/* Full-bleed until .is-tucked, then one pass into the bottom-right corner.
   A uniform scale, not a width/height pair: the stage is 16/9, so a scaled
   sub-box keeps that ratio and the video never squashes — and the whole move
   stays on the compositor. transform-origin is the corner it tucks into. */
.vsw-frame {
  position: absolute;
  right: 0;
  bottom: 0;
  z-index: 2;
  width: 100%;
  height: 100%;
  overflow: hidden;
  background: #0a0a0b;
  border-radius: 4px;
  transform: scale(1);
  transform-origin: 100% 100%;
  /* An ease-in-out, not the ease-out used for the text: front-loaded easing
     reads as a snap followed by a drift, which is exactly what a slow, smooth
     move must not do. This one leaves and arrives gently. */
  transition: transform 1.15s cubic-bezier(.5, 0, .2, 1),
              border-radius 1.15s cubic-bezier(.5, 0, .2, 1);
  will-change: transform;
}

.vsw-stage.is-tucked .vsw-frame {
  transform: scale(.28);
  /* the corner radius is scaled down with everything else, so it is authored
     large to land at ~11px on screen */
  border-radius: 26px;
}

.vsw-video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* ---- line + letter reveals ------------------------------------------------ */

/* Only hide the copy when the script is actually running, so a JS failure
   leaves plain readable text rather than an empty section. */
html.sr-js [data-sr-split]:not(.is-split),
html.sr-js [data-sr-chars]:not(.is-split) {
  visibility: hidden;
}

.sr-line {
  display: block;
  position: relative;
  overflow: clip;
  /* clip would otherwise crop descenders and the odd accent */
  padding-bottom: .08em;
  margin-bottom: -.08em;
}

/* Splitting into inline-blocks drops kerning, which can push a measured line
   just past its own width — hold it on one line rather than let it re-wrap.
   Nothing moves on these lines, so nothing needs clipping either. */
.sr-line--chars {
  white-space: nowrap;
  overflow: visible;
}

.sr-line-i {
  display: block;
  transform: translateY(110%);
  transition: transform .95s cubic-bezier(.16, 1, .3, 1);
  will-change: transform;
}

[data-sr-split].is-in .sr-line-i {
  transform: translateY(0);
}

/* Every letter is already in place; scroll only raises it out of the dark.
   Opacity is written per frame by the script, so no transition here on
   purpose — a transition would lag the wheel instead of tracking it. */
.sr-char {
  display: inline-block;
  opacity: var(--sr-dim);
  --sr-dim: .15;
}

.vsw-label .sr-char {
  --sr-dim: .22;
}

/* ---- narrow ---------------------------------------------------------------- */

@media (max-width: 1099px) {
  .vsw-title {
    font-size: 5.8rem;
  }
}

/* Below this the corner-shrink leaves a postage stamp, so the video simply
   sits above the copy at full width and the letters still scrub in. */
@media (max-width: 860px) {
  .vsw-stage {
    aspect-ratio: auto;
    max-height: none;
    display: flex;
    flex-direction: column;
    gap: clamp(20px, 5vw, 36px);
  }

  /* the corner tuck would leave a postage stamp here, so the video simply
     stays full width above the copy */
  .vsw-frame,
  .vsw-stage.is-tucked .vsw-frame {
    position: static;
    width: 100%;
    height: auto;
    aspect-ratio: 16 / 9;
    border-radius: 6px;
    transform: none;
  }

  .vsw-under {
    position: static;
    width: 100%;
    padding-bottom: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .sr-line-i {
    transition: none;
    transform: none;
  }

  .sr-char {
    opacity: 1;
  }

  .vsw-frame {
    transition: none;
  }
}
