/* ============================================================
   Vidzero concept v4. THE FLOW
   The transition toolkit applied to the real page. One engine drives every
   join: a tall `.tx` wrapper, a sticky stage inside it, scroll progress through
   the wrapper written as --p (0 to 1, eased), consumed by CSS.
   Toolkit in use here: push through (why -> crew). Hard cut is deliberately
   absent; see concept-brief.md.
   Ground rule: warm paper is the base, dark is only for screens.
   ============================================================ */

/* ---------- the shared join engine ---------- */
.tx { position: relative; height: 185vh; }
.tx__stage { position: sticky; top: 0; height: 100vh; overflow: hidden; }

/* ---------- shared section furniture ---------- */
.lede { font-family: var(--f-body); font-size: clamp(1.15rem, 1.7vw, 1.45rem); line-height: 1.55; color: var(--ink-soft); }

/* ============================================================
   THE WHY, v3 (paper, content only). Superseded, markup gone.
   The client's problem in their words. No footage: this is the first proof
   that the page does not need video to hold attention.
   ============================================================ */
.why { padding-block: clamp(7rem, 16vh, 12rem) clamp(4rem, 8vh, 7rem); }
.why__title {
  font-size: clamp(2.4rem, 6.4vw, 6.2rem); max-width: 17ch; text-wrap: balance;
}
.why__title .mark { background: linear-gradient(180deg, transparent 58%, rgba(82,113,255,.42) 58% 94%, transparent 94%); }
.why__body { margin-top: clamp(1.6rem, 3vw, 2.4rem); max-width: 46ch; text-wrap: pretty; }
.why__body + .why__body { margin-top: 1.1rem; }

/* ============================================================
   THE JOIN, v3: PUSH THROUGH, on a person. Superseded, markup gone.
   The bridge line sits beside one portrait. The camera enters that portrait
   until it is the frame, which is the argument made physical: you need people
   who already live in this world, so we go into one of them.
   The start rect is MEASURED from the resting card by flow.js (--sx/--sy/--sr
   /--sb). Never hand-tune this in vw; it will not register.
   ============================================================ */
.push { background: var(--paper); }
.push__bridge {
  position: absolute; left: 0; right: 0; top: 50%; transform: translateY(-50%);
  max-width: var(--container); margin-inline: auto; padding-inline: var(--container-pad);
  display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr);
  gap: clamp(2rem, 5vw, 5rem); align-items: center;
  opacity: calc(1 - var(--p) * 2.1);
}
.push__bridge h2 { font-size: clamp(1.9rem, 4vw, 3.6rem); max-width: 18ch; }
.push__bridge p { margin-top: 1rem; max-width: 36ch; }

/* the resting card the camera pushes into */
.push__card { position: relative; aspect-ratio: 4 / 5; overflow: hidden; background: var(--paper-2); }
.push__card img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 18%; }

/* the same portrait, growing from exactly where that card sits */
.pushee {
  position: absolute; overflow: hidden; background: var(--screen);
  inset:
    calc((1 - var(--p)) * var(--sy, 22vh))
    calc((1 - var(--p)) * var(--sr, 8vw))
    calc((1 - var(--p)) * var(--sb, 22vh))
    calc((1 - var(--p)) * var(--sx, 55vw));
}
/* A studio headshot at full bleed reads as a blown-up corporate portrait, not
   a film frame (the same lesson that killed the rack-focus crew idea). Crop in
   hard as it grows so head and shoulders fill the frame and the empty studio
   backdrop drops away. */
.pushee img { width: 100%; height: 100%; object-fit: cover;
  object-position: 50% calc(20% - var(--p) * 8%);
  transform: scale(calc(1 + var(--p) * .34)); }
/* the frame only earns a grade once it is actually a frame */
.pushee__grade { position: absolute; inset: 0; opacity: var(--p);
  background:
    linear-gradient(180deg, rgba(8,5,32,.18) 30%, rgba(8,5,32,.72) 100%),
    /* a wedge under the caption specifically: the copy sits over a pale shirt
       otherwise, and measured 2.14:1 before this existed */
    linear-gradient(100deg, rgba(6,4,26,.88) 0%, rgba(6,4,26,.55) 34%, rgba(6,4,26,0) 62%); }
.pushee__cap {
  position: absolute; left: 0; right: 0; bottom: clamp(8vh, 12vh, 14vh);
  max-width: var(--container); margin-inline: auto; padding-inline: var(--container-pad);
  opacity: calc(max(0, var(--p) - .55) * 2.6);
}
.pushee__cap h2 { font-size: clamp(1.9rem, 4.4vw, 4.2rem); color: #fff; max-width: 20ch;
  text-shadow: 0 8px 46px rgba(0,0,0,.75); }
.pushee__cap p { margin-top: .9rem; max-width: 40ch; color: rgba(242,239,255,.9);
  font-family: var(--f-body); font-size: 1.08rem; line-height: 1.55; text-shadow: 0 4px 22px rgba(0,0,0,.8); }

/* ============================================================
   THE CREW, v3 (paper, portraits). Superseded, markup gone.
   The guide. Real names, real roles, what each person actually knows about
   this world. No monitors: the portfolio owns that language now.
   ============================================================ */
.crew2 { padding-block: clamp(5rem, 11vh, 9rem) clamp(6rem, 13vh, 10rem); }
.crew2__head { max-width: 40ch; }
.crew2__head h2 { font-size: clamp(2rem, 4.4vw, 4rem); max-width: 18ch; text-wrap: balance; }
.crew2__head p { margin-top: 1rem; }
.crew2__grid {
  margin-top: clamp(2.6rem, 5vw, 4rem);
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: clamp(1rem, 2vw, 1.6rem);
}
.crew2__person { position: relative; margin: 0; }
.crew2__shot { position: relative; aspect-ratio: 4 / 5; overflow: hidden; background: var(--paper-2); }
.crew2__shot img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 18%;
  transition: transform var(--dur-3) var(--ease-out), filter var(--dur-2) var(--ease-out); }
/* the hover is a focus pull, matching the toolkit rather than inventing a new move */
.crew2__person img { filter: saturate(.86); }
.crew2__person:hover img, .crew2__person:focus-within img { transform: scale(1.04); filter: saturate(1.05); }
.crew2__name { display: block; margin-top: .7rem; font-family: var(--f-display); font-weight: 800;
  font-size: clamp(1rem, 1.3vw, 1.2rem); color: var(--ink); letter-spacing: -.02em; }
.crew2__role { display: block; margin-top: .15rem; font-family: var(--f-body); font-style: italic;
  font-size: .95rem; color: var(--ink-soft); }
.crew2__knows { display: block; margin-top: .5rem; font-family: var(--f-body); font-size: .95rem;
  line-height: 1.45; color: #4a4468; max-width: 26ch;
  opacity: 0; transform: translateY(4px);
  transition: opacity var(--dur-2) var(--ease-out), transform var(--dur-2) var(--ease-out); }
.crew2__person:hover .crew2__knows, .crew2__person:focus-within .crew2__knows { opacity: 1; transform: none; }

/* ---------- responsive ---------- */
@media (max-width: 1024px) {
  .crew2__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .push__bridge { grid-template-columns: 1fr; gap: 2rem; }
  .push__card { max-width: 46vw; }
}
@media (max-width: 700px) {
  .tx { height: 150vh; }
  .crew2__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .push__card { max-width: 62vw; }
  .why__body { max-width: none; }
  /* the knows-line cannot depend on hover on touch, so it is simply always on */
  .crew2__knows { opacity: 1; transform: none; }
}

/* ---------- reduced motion: every join lands on its finished state ---------- */
@media (prefers-reduced-motion: reduce) {
  .push__bridge { opacity: 1; }
  .pushee { inset: 0; }
  .pushee__grade { opacity: 1; }
  .pushee__cap { opacity: 1; }
  .crew2__knows { opacity: 1; transform: none; }
  .crew2__shot img { transition: none; }
}
