/* ============================================================
   Vidzero concept v3. HERO: shot through the viewfinder
   Full-bleed footage inside a camera EVF/monitor HUD.
   Scroll drives --p (0..1): the viewfinder zooms to fill the screen.
   Mouse drives --mx/--my (-1..1): reticle drift + handheld follow.
   Strip test: operating a camera, not media beside text. Passes.
   ============================================================ */
.vf { position: relative; --p: 0; --mx: 0; --my: 0; }
.vf__spacer { height: 150vh; }            /* scroll room for the zoom, then it cuts to The Why */

/* 100dvh, not 100vh. This was already an open bug (mobile chrome cuts a 100vh
   section) and it is now load-bearing: the lift registers the room's top against
   this exact height, so the two must be the same unit or the reveal starts off
   by the height of the browser chrome. See room.css, THE LIFT. */
.vf__stage {
  position: sticky; top: 0; height: 100dvh; overflow: hidden;
  background: radial-gradient(120% 120% at 50% 45%, #0b0724 0%, #050310 70%, #020109 100%);
}

/* the EVF viewport: inset at p=0 (looking through the finder), full-bleed at p=1 */
.vf__screen {
  position: absolute; left: 50%; top: 50%;
  width: calc(100vw - (1 - var(--p)) * 17vw);
  /* dvh to match the stage: on phones 100vh is the LARGE viewport, so a vh
     calc inside a 100dvh stage silently eats most of the vertical inset
     while the browser toolbar is up (Nick's real-device pass: the battery
     readout kept finding the bottom edge) */
  height: calc(100dvh - (1 - var(--p)) * 20dvh);
  transform: translate(-50%, -50%);
  border-radius: calc((1 - var(--p)) * 18px);
  overflow: hidden;
  box-shadow: 0 40px 120px rgba(0,0,0,.6);
}
.vf__sway { position: absolute; inset: -2%; animation: vf-sway 9s ease-in-out infinite; }  /* handheld sway */
@keyframes vf-sway {
  0%,100% { transform: translate(0,0) rotate(0deg); }
  25% { transform: translate(0.6%, -0.5%) rotate(0.18deg); }
  50% { transform: translate(-0.5%, 0.4%) rotate(-0.15deg); }
  75% { transform: translate(0.4%, 0.5%) rotate(0.12deg); }
}
.vf__video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  transform: scale(1.06) translate(calc(var(--mx) * -14px), calc(var(--my) * -14px));
  filter: saturate(1.02) contrast(1.04); transition: filter .9s var(--ease-out); }
.vf.is-focusing .vf__video { filter: blur(16px) saturate(1.02); }   /* focus-pull-in on load */

/* eyecup vignette, fades as it fills */
.vf__vignette { position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(78% 78% at 50% 50%, transparent 58%, rgba(2,1,9,.72) 100%);
  opacity: calc(1 - var(--p)); }
/* landing scrim for contrast, strongest at rest, gone by the time it fills */
.vf__scrim { position: absolute; inset: 0; pointer-events: none;
  opacity: clamp(0, calc(1 - var(--p) * 2), 1);
  background:
    linear-gradient(118deg, rgba(3,2,14,.74) 0%, rgba(3,2,14,.4) 32%, transparent 60%),
    linear-gradient(0deg, rgba(3,2,14,.5) 0%, transparent 40%); }

/* ---- HUD (all fades out as the shot fills the screen) ---- */
.vf__hud { position: absolute; pointer-events: none; opacity: clamp(0, calc(1 - var(--p) * 1.7), 1);
  font-family: var(--f-mono); font-size: .72rem; letter-spacing: .12em; color: var(--on-dark-soft); text-transform: uppercase; }
.vf__hud--tl { top: 4%; left: 4%; display: flex; align-items: center; gap: .6em; }
.vf__hud--tr { top: 4%; right: 4%; }
.vf__hud--bl { bottom: 4%; left: 4%; }        /* used by chyron scrim area */
.vf__hud--br { bottom: 4%; right: 4%; display: grid; gap: .35em; justify-items: end; }
.vf__rec { display: inline-flex; align-items: center; gap: .5em; color: var(--on-dark); }
.vf__rec i { width: 10px; height: 10px; border-radius: 50%; background: var(--rec); box-shadow: 0 0 10px var(--rec); }

/* thirds grid + reticle + corner brackets */
.vf__grid { position: absolute; inset: 0; pointer-events: none; opacity: calc((1 - var(--p)) * .5);
  background:
    linear-gradient(90deg, transparent 33.2%, rgba(239,234,250,.5) 33.2% 33.4%, transparent 33.4%),
    linear-gradient(90deg, transparent 66.5%, rgba(239,234,250,.5) 66.5% 66.7%, transparent 66.7%),
    linear-gradient(0deg, transparent 33.2%, rgba(239,234,250,.5) 33.2% 33.4%, transparent 33.4%),
    linear-gradient(0deg, transparent 66.5%, rgba(239,234,250,.5) 66.5% 66.7%, transparent 66.7%); }
.vf__reticle { position: absolute; top: 50%; left: 50%; width: 64px; height: 64px; pointer-events: none;
  transform: translate(-50%, -50%) translate(calc(var(--mx) * 26px), calc(var(--my) * 26px));
  opacity: calc(1 - var(--p)); }
.vf__reticle::before, .vf__reticle::after { content: ""; position: absolute; background: rgba(239,234,250,.85); }
.vf__reticle::before { left: 50%; top: 0; bottom: 0; width: 1.5px; transform: translateX(-50%); }
.vf__reticle::after { top: 50%; left: 0; right: 0; height: 1.5px; transform: translateY(-50%); }
/* the corner brackets are gone entirely (Nick, round 21: too much). The
   frame inset, REC and the HUD carry the viewfinder on their own. */

/* audio meters (left): two channels bouncing with the levels, like a real camera */
.vf__meters { position: absolute; left: 4%; top: 50%; transform: translateY(-50%); display: flex; gap: 4px; pointer-events: none; opacity: calc(1 - var(--p)); }
.vf__meters span { width: 4px; height: 96px; background: linear-gradient(0deg, #46d17f 0 55%, #e7c04a 55% 82%, #e0554a 82% 100%); border-radius: 2px; opacity: .8;
  clip-path: inset(50% 0 0 0); animation: vf-meter 2600ms ease-in-out infinite; }
.vf__meters span:nth-child(1){ animation-duration: 2400ms; }
.vf__meters span:nth-child(2){ animation-duration: 3100ms; animation-delay: -900ms; }
@keyframes vf-meter {
  0% { clip-path: inset(60% 0 0 0); } 9% { clip-path: inset(20% 0 0 0); } 17% { clip-path: inset(46% 0 0 0); }
  27% { clip-path: inset(10% 0 0 0); } 37% { clip-path: inset(40% 0 0 0); } 48% { clip-path: inset(26% 0 0 0); }
  59% { clip-path: inset(56% 0 0 0); } 69% { clip-path: inset(15% 0 0 0); } 80% { clip-path: inset(44% 0 0 0); }
  90% { clip-path: inset(23% 0 0 0); } 100% { clip-path: inset(60% 0 0 0); }
}

/* zoom scale (right): marker rises W to T and the ratio ticks up as you scroll-zoom */
.vf__zoom { position: absolute; right: 4%; top: 50%; transform: translateY(-50%); display: flex; flex-direction: column;
  align-items: center; gap: 6px; pointer-events: none; opacity: calc(1 - var(--p));
  font-family: var(--f-mono); font-size: .58rem; letter-spacing: .14em; text-transform: uppercase; color: var(--on-dark-soft); }
.vf__zoom-cap { font-size: .52rem; opacity: .8; }
.vf__zoom-end { line-height: 1; }
.vf__zoom-track { position: relative; width: 4px; height: 110px; background: rgba(239,234,250,.18); border-radius: 2px; }
.vf__zoom-track::before { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: calc(var(--p) * 100%);
  background: linear-gradient(0deg, rgba(82,113,255,.5), rgba(82,113,255,.15)); border-radius: 2px; }
.vf__zoom-marker { position: absolute; left: 50%; bottom: calc(var(--p) * 100%); transform: translate(-50%, 50%);
  width: 11px; height: 11px; border-radius: 50%; background: var(--accent); box-shadow: 0 0 10px var(--accent); }
.vf__zoom-val { color: var(--on-dark); letter-spacing: .06em; }

/* ---- chyron (lower-third headline) ---- */
.vf__chyron { position: absolute; left: 9%; bottom: 13%; max-width: 46%; z-index: 2;
  opacity: clamp(0, calc(1 - var(--p) * 2.2), 1); }
.vf__chyron .kick { font-family: var(--f-mono); font-size: .72rem; letter-spacing: .2em; text-transform: uppercase; color: var(--accent);
  display: inline-block; padding-left: 14px; position: relative; margin-bottom: .8rem; }
.vf__chyron .kick::before { content: ""; position: absolute; left: 0; top: 50%; transform: translateY(-50%); width: 5px; height: 1.1em; background: var(--accent); }
.vf__chyron h1 { font-family: var(--f-display); font-weight: 800; color: #fff; font-size: clamp(2.2rem, 5.4vw, 5rem); line-height: .98; letter-spacing: -0.02em; text-shadow: 0 2px 30px rgba(0,0,0,.5); }
.vf__chyron h1 .u { color: var(--accent); }
.vf__chyron .sub { color: var(--on-dark-soft); font-family: var(--f-body); font-size: var(--t-lead); margin-top: 1rem; max-width: 34ch; }

/* ---- controls ---- */
/* a STAGE child, not a screen child (the screen clips and transforms, so
   the phone CTA could never sit in the band below the frame). These calcs
   are the old right:9%/bottom:13% OF THE FRAME re-expressed against the
   stage, so the desktop position is unchanged at every p. */
.vf__controls { position: absolute;
  right: calc((1 - var(--p)) * 8.5vw + 0.09 * (100vw - (1 - var(--p)) * 17vw));
  bottom: calc((1 - var(--p)) * 10dvh + 0.13 * (100dvh - (1 - var(--p)) * 20dvh));
  z-index: 2; display: flex; align-items: center; justify-content: flex-end;
  gap: clamp(.9rem, 1.4vw, 1.4rem);
  opacity: clamp(0, calc(1 - var(--p) * 2.2), 1); }
/* aperture + focus-lock CTA (chosen) */
/* the secondary: Play showreel, a LINK beside the primary (Nick, round
   30: the pill version read as a second button). The page's standard
   link grammar: accent underline, the marker band rising on hover; the
   label spans its own element because text-decoration on a flex anchor
   never reaches flex children. White label for legibility over the
   footage. Opens the full reel in its own tab (the compressed master;
   the source file carries no audio). */
.vf__play { display: inline-flex; align-items: center; gap: .55em;
  font-family: var(--f-display); font-weight: 700; font-size: .95rem; color: #fff;
  padding: .5em .3em; margin-block: -.5em; }
.vf__play > span {
  text-decoration: underline; text-underline-offset: 5px; text-decoration-thickness: 2px;
  text-decoration-color: var(--accent-on-dark, #8FA3FF);
  background-image: linear-gradient(color-mix(in srgb, var(--accent-on-dark, #8FA3FF) 26%, transparent),
                                    color-mix(in srgb, var(--accent-on-dark, #8FA3FF) 26%, transparent));
  background-repeat: no-repeat; background-position: 0 100%; background-size: 100% 0;
  transition: background-size var(--dur-1) var(--ease-out); }
.vf__play:hover > span, .vf__play:focus-visible > span { background-size: 100% .78em; }
.vf__play-tri { width: 0; height: 0;
  border-block: 4.5px solid transparent; border-left: 7px solid var(--accent-on-dark, #8FA3FF); }

.vf__cta { position: relative; display: inline-flex; align-items: center; gap: .7em;
  font-family: var(--f-display); font-weight: 700; font-size: .95rem; color: #fff;
  background: var(--accent); padding: .55em 1.5em .55em .55em; border-radius: var(--r-pill);
  transition: transform var(--dur-1) var(--ease-out), background var(--dur-1); }
.vf__cta:hover { background: var(--accent-ink); transform: translateY(-2px); }
.vf__cta-iris { position: relative; width: 38px; height: 38px; border-radius: 50%; overflow: hidden;
  background: repeating-conic-gradient(from 10deg, #141046 0 30deg, #2a2270 30deg 60deg);
  box-shadow: inset 0 0 0 2px rgba(255,255,255,.10); transition: transform .55s var(--ease-out); }
.vf__cta-iris::after { content: ""; position: absolute; inset: 42%; border-radius: 50%;
  background: #d6e2ff; box-shadow: 0 0 12px #a9c2ff; transition: inset .5s var(--ease-out); }
.vf__cta:hover .vf__cta-iris { transform: rotate(42deg); }
.vf__cta:hover .vf__cta-iris::after { inset: 22%; }
.vf__cta-lock { position: absolute; inset: -11px; pointer-events: none; transition: inset .35s var(--ease-out); }
.vf__cta-lock span { position: absolute; width: 14px; height: 14px; border: 2px solid rgba(255,255,255,.85); }
.vf__cta-lock span:nth-child(1){ top:0; left:0; border-right:0; border-bottom:0; }
.vf__cta-lock span:nth-child(2){ top:0; right:0; border-left:0; border-bottom:0; }
.vf__cta-lock span:nth-child(3){ bottom:0; left:0; border-right:0; border-top:0; }
.vf__cta-lock span:nth-child(4){ bottom:0; right:0; border-left:0; border-top:0; }
.vf__cta:hover .vf__cta-lock { inset: -4px; }
.vf__audio { font-family: var(--f-mono); font-size: .68rem; letter-spacing: .14em; text-transform: uppercase; color: var(--on-dark-soft);
  display: inline-flex; align-items: center; gap: .5em; border: 1px solid rgba(239,234,250,.3); border-radius: var(--r-pill); padding: .5em 1em; transition: color var(--dur-1), border-color var(--dur-1); }
.vf__audio i { width: 8px; height: 8px; background: var(--on-dark-soft); }
.vf__audio:hover { color: #fff; border-color: #fff; }
.vf__audio.is-on i { background: var(--accent); }

/* scroll hint (a real affordance, fades on scroll): a focus-ring pulse is banned, use a tick */
.vf__go { position: absolute; left: 50%; bottom: 3.5%; transform: translateX(-50%); z-index: 2; font-family: var(--f-mono); font-size: .66rem; letter-spacing: .2em; text-transform: uppercase; color: var(--on-dark-soft); opacity: calc(1 - var(--p) * 3); }

@media (max-width: 768px) {
  /* TALLER than it is thin (Nick's real-device pass, 28 August 2026): the
     wide side-inset pushed the frame's top edge into the brand mark and
     its bottom corners into the CTA. Deep top and bottom bands put the
     brand and REC on separate lines and give the CTA clear ground, and the
     growth still reads because the vertical travel is large. */
  .vf__screen { width: calc(100vw - (1 - var(--p)) * 13vw); height: calc(100dvh - (1 - var(--p)) * 24dvh); }
  .vf__chyron { max-width: 88%; bottom: 18%; }
  /* the CTA moves OUT of the frame into the bottom band, centred: inside
     the frame its lock corners sat on the viewfinder's own bracket corner,
     two framing languages in one spot (Nick's real-device pass) */
  .vf__controls { inset: auto 0 0 0; height: 12dvh; display: flex;
    align-items: center; justify-content: center; gap: 1.5rem; }
  /* the primary leads on phones, the link follows, with real air
     between them (Nick, round 31) */
  .vf__cta { order: 1; }
  .vf__play { order: 2; padding: .9em .3em; margin-block: 0; }
  .vf__meters, .vf__zoom { display: none; }
}
@media (max-width: 560px) {
  /* the small-screen viewfinder is REC only: the spec line collided with
     REC, the grid and reticle sat in the headline, and the battery kept
     finding something to clip against or collide with */
  .vf__hud--tr, .vf__grid, .vf__reticle, .vf__hud--br { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .vf__spacer { height: 0; }
  .vf__stage { position: relative; height: 100dvh; }
  .vf.is-focusing .vf__video { filter: none; }
  .vf__video { transform: none; }
  .vf__sway { animation: none; }
  .vf__meters span { animation: none; clip-path: inset(35% 0 0 0); }
}
