/* The doctor's testimony: a pinned scene, not a card.
   The stage lives INSIDE step 12 (.step-video): scrollama keeps scene 12 through the whole stage, scrolling down and up,
   and every hard-coded scene index in main.js stays as it is. js/video.js turns the scroll position into a few CSS
   variables (--c copy, --f frame, --x exit on .vstage; opacity on .vs-veil), so every change is continuous: no class
   toggles at thresholds, no CSS filter on the animated valley, no backdrop-filter. Only opacity and transform move. */

/* ---------- a step that holds a stage = its text part + the pinned stage; the next step follows at once (the room lifts onto it) ----------
   .vs-text takes over the layout the step had before (same alignment at every width), so the card behaves as it always did. */
.step.step-video { display: block; min-height: 0; padding: 0; }
.step-video[data-step="12"] .vs-text { min-height: 100vh; display: flex; align-items: flex-start; padding: 8vh 0 0 6vw; }
@media (max-width: 1100px) { .step-video[data-step="12"] .vs-text { align-items: flex-end; padding: 0 0 4vh 6vw; } }
@media (max-width: 640px) { .step-video[data-step="12"] .vs-text { padding: 0 16px 4vh; } }
/* step 6 (the lost life-years): the original 150vh, card entering late, so the silhouettes finish exactly as before;
   a beat of 40vh with only the finished grid on screen, then the veil comes in; after the clip the story goes straight to the next scene */
.step-video[data-step="6"] .vs-text { min-height: 150vh; display: flex; align-items: flex-start; padding: 32vh 0 0 6vw; }
@media (max-width: 1100px) { .step-video[data-step="6"] .vs-text { align-items: flex-end; padding: 0 0 4vh 6vw; } }
@media (max-width: 640px) { .step-video[data-step="6"] .vs-text { padding: 0 16px 4vh; } }
.step-video[data-step="6"] .vstage { margin-top: 40vh; }
@media (max-width: 1100px) { .step-video[data-step="6"] .vstage { margin-top: 85vh; } }

.vstage { --run: 170vh; position: relative; height: calc(100vh + var(--run)); }
@supports (height: 100svh) { .vstage { height: calc(100svh + var(--run)); } }
.vs-pin {
  position: sticky; top: 0; height: 100vh;
  display: flex; align-items: center; justify-content: center;
  gap: clamp(36px, 6vw, 110px); padding: 0 5vw;
}
@supports (height: 100svh) { .vs-pin { height: 100svh; } }

/* ---------- the veil: the room goes dark, haze and dust drift through it ---------- */
.vs-veil {
  position: fixed; inset: 0; z-index: -1; pointer-events: none; overflow: hidden;
  opacity: 0;
  background:
    radial-gradient(ellipse 110% 90% at 60% 48%, rgba(9, 11, 15, 0.80) 0%, rgba(8, 10, 14, 0.92) 60%, rgba(7, 9, 12, 0.97) 100%);
}
.vs-haze {
  position: absolute; inset: -12%;
  background:
    radial-gradient(38% 34% at 24% 72%, rgba(178, 166, 148, 0.17), transparent 70%),
    radial-gradient(44% 38% at 80% 30%, rgba(178, 166, 148, 0.12), transparent 70%),
    linear-gradient(to top, rgba(150, 138, 120, 0.16), transparent 42%);
  animation: vs-haze 80s ease-in-out infinite alternate; will-change: transform;
}
@keyframes vs-haze { from { transform: translate3d(-3%, 1%, 0) scale(1.02); } to { transform: translate3d(4%, -2%, 0) scale(1.09); } }
.vs-dust i {
  position: absolute; left: var(--x); bottom: -6vh; width: var(--s); height: var(--s); border-radius: 50%;
  background: rgba(224, 214, 198, var(--o)); box-shadow: 0 0 calc(var(--s) * 2.4) rgba(224, 214, 198, 0.22);
  animation: vs-dust var(--d) linear var(--delay) infinite; will-change: transform;
}
@keyframes vs-dust { from { transform: translate3d(0, 0, 0); } to { transform: translate3d(var(--dx), -114vh, 0); } }

/* the valley's own text (labels, gauge, caption bar, source line) fades out with the veil instead of ghosting through it.
   --vs is the veil's opacity (set by js/video.js on #inversion); the !important beats the inline opacity main.js writes on the labels,
   and the rule only applies inside scene 12, where those labels are fully on anyway. */
body[data-scene="12"] #inversion .inv-labels, body[data-scene="12"] #inversion .inv-gauge, body[data-scene="12"] #inversion .inv-state,
body[data-scene="12"] #inversion .inv-src, body[data-scene="12"] #inversion .inv-head { opacity: calc(1 - var(--vs, 0)) !important; }

/* scene 6 (the lost life-years): the whole picture fades with the veil. The class is only there while the veil is up, and the
   rule is continuous at both ends (opacity 1 at --vs 0), so nothing steps when it is added or removed. */
body[data-scene="6"] #years.vs-faded { opacity: calc(1 - var(--vs, 0) * 0.97) !important; transition: none !important; }

/* ---------- the story's own motif: the lid, a thin warm line, behind the stage ---------- */
.vs-lid {
  position: absolute; left: 0; right: 0; top: 16%; height: 2px; pointer-events: none;
  background: linear-gradient(90deg, rgba(243, 163, 115, 0), rgba(243, 163, 115, 0.95) 16%, rgba(243, 163, 115, 0.95) 84%, rgba(243, 163, 115, 0));
  box-shadow: 0 0 20px 3px rgba(226, 113, 75, 0.38);
  opacity: calc(var(--c, 1) * (1 - var(--x, 0)));
  transform: scaleX(calc(0.3 + 0.7 * var(--c, 1)));
}
.vs-lid::after {
  content: ''; position: absolute; left: 0; right: 0; top: 2px; height: 130px;
  background: linear-gradient(to bottom, rgba(226, 113, 75, 0.17), rgba(226, 113, 75, 0));
}

/* ---------- words ---------- */
.vs-left { width: var(--left-w, min(440px, 34vw)); display: flex; flex-direction: column; gap: 30px; }
.vs-copy, .vs-who {
  opacity: calc(var(--c, 1) * (1 - var(--x, 0)));
  transform: translate3d(0, calc((1 - var(--c, 1)) * 26px - var(--x, 0) * 36px), 0);
}
.vs-tag { margin-bottom: 16px; }
.vs-q { font-weight: 800; font-size: var(--q-size, clamp(40px, 4.7vw, 74px)); line-height: 1.04; color: #fff; letter-spacing: -0.005em; text-wrap: balance; }
.vs-who { display: flex; flex-direction: column; gap: 4px; padding-top: 18px; position: relative; font-size: 15px; line-height: 1.4; }
.vs-who::before { content: ''; position: absolute; left: 0; top: 0; width: 44px; height: 2px; background: var(--accent); }
.vs-who strong { color: #fff; font-weight: 700; font-size: 18px; }
.vs-who span { color: var(--muted); }

/* ---------- the window: a vertical frame, the picture is the point ---------- */
.vs-frame {
  position: relative; margin: 0; flex: none;
  height: min(80vh, 780px); aspect-ratio: 9 / 16;
  border-radius: 6px; overflow: hidden; background: #0a0c10;
  box-shadow: 0 0 0 1px rgba(232, 228, 220, 0.16), 0 40px 90px rgba(0, 0, 0, 0.65), 0 0 150px rgba(226, 113, 75, 0.10);
  opacity: calc(var(--f, 1) * (1 - var(--x, 0)));
  transform: translate3d(0, calc((1 - var(--f, 1)) * 7vh - var(--x, 0) * 6vh), 0) scale(calc(0.955 + 0.045 * var(--f, 1)));
  pointer-events: none; will-change: transform, opacity;
}
@supports (height: 100svh) { .vs-frame { height: min(80svh, 780px); } }
.vstage.is-live .vs-frame { pointer-events: auto; }
.vs-video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; background: #0a0c10; }
/* the poster layer: the clean frame (no captions) shows until the clip plays, then dissolves into it; it comes back when the stage resets */
.vs-poster { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; pointer-events: none; opacity: 1; transition: opacity 0.6s ease; }
.vstage[data-state="playing"] .vs-poster, .vstage[data-state="paused"] .vs-poster, .vstage[data-state="ended"] .vs-poster { opacity: 0; }
.vs-tap { position: absolute; inset: 0; z-index: 1; border: 0; background: none; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.vs-tap:focus-visible { outline: 2px solid var(--accent); outline-offset: -4px; }

/* centre icons: play when paused, replay when ended, a quiet ring while it buffers */
.vs-state { position: absolute; inset: 0; z-index: 2; pointer-events: none; }
.vs-ic, .vs-spin {
  position: absolute; left: 50%; top: 50%; width: 78px; height: 78px; margin: -39px 0 0 -39px; border-radius: 50%;
  background: rgba(14, 17, 22, 0.62); border: 2px solid rgba(255, 255, 255, 0.88);
  display: grid; place-items: center; opacity: 0; transition: opacity 0.25s ease;
}
.vs-ic svg { width: 30px; height: 30px; fill: #fff; margin-left: 4px; }
.vs-ic.i-replay svg { margin-left: 0; }
.vstage[data-state="idle"] .i-play, .vstage[data-state="paused"] .i-play, .vstage[data-state="ended"] .i-replay { opacity: 1; }
.vs-spin { width: 54px; height: 54px; margin: -27px 0 0 -27px; background: none; border-color: rgba(255, 255, 255, 0.25); border-top-color: #fff; animation: vs-spin 0.9s linear infinite; }
.vstage.is-buffering .vs-spin { opacity: 1; }
@keyframes vs-spin { to { transform: rotate(360deg); } }

/* sound: the clip starts muted (the captions are burned in); one clear pill turns the voice on */
.vs-sound {
  position: absolute; left: 14px; bottom: 20px; z-index: 3; display: flex; align-items: center; gap: 8px;
  height: 38px; padding: 0 15px 0 11px; border: 0; border-radius: 19px; cursor: pointer;
  background: rgba(14, 17, 22, 0.84); color: #fff; font: 600 13px/1 var(--font); letter-spacing: 0.02em;
}
.vs-sound svg { width: 20px; height: 20px; fill: #fff; flex: none; }
.vs-sound .s-on { display: none; }
.vs-sound[aria-pressed="true"] .s-off { display: none; }
.vs-sound[aria-pressed="true"] .s-on { display: block; }
.vs-sound[aria-pressed="true"] .s-txt { display: none; }
.vs-sound[aria-pressed="true"] { padding: 0 11px; }
.vs-sound:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.vstage[data-state="playing"] .vs-sound[aria-pressed="false"] { animation: vs-pulse 2.6s ease-in-out infinite; }
@keyframes vs-pulse { 0%, 100% { box-shadow: 0 0 0 0 rgba(226, 113, 75, 0); } 50% { box-shadow: 0 0 0 7px rgba(226, 113, 75, 0.28); } }
.vs-full {
  position: absolute; right: 12px; top: 12px; z-index: 3; width: 36px; height: 36px; border: 0; border-radius: 50%; cursor: pointer;
  background: rgba(14, 17, 22, 0.7); display: grid; place-items: center;
}
.vs-full svg { width: 16px; height: 16px; fill: #fff; }
.vs-full:hover, .vs-full:focus-visible { background: var(--accent); outline: none; }
.vs-bar { position: absolute; left: 0; right: 0; bottom: 0; height: 3px; background: rgba(255, 255, 255, 0.2); z-index: 3; }
.vs-bar i { display: block; height: 100%; background: var(--accent); transform: scaleX(0); transform-origin: left; }

/* when it has finished: the story's own hint to keep going */
.vs-hint {
  position: absolute; left: 0; right: 0; bottom: 3.2vh; text-align: center; color: var(--muted); font-size: 15px;
  opacity: 0; transition: opacity 0.6s ease; pointer-events: none;
}
.vstage[data-state="ended"] .vs-hint { opacity: 1; }

/* ---------- tablets and phones: the words above, the frame in the middle, the name below ---------- */
@media (max-width: 1100px) {
  .vs-pin { flex-direction: column; gap: 14px; padding: 0 16px; }
  .vs-left { display: contents; }
  .vs-copy { order: 1; width: min(100%, 460px); }
  .vs-frame { order: 2; height: min(calc(100vh - var(--chrome-m, 220px)), calc(100vw * 16 / 9), 780px); }
  .vs-who { order: 3; width: min(100%, 460px); padding-top: 12px; }
  .vs-q { font-size: var(--q-size-m, clamp(30px, 8.2vw, 44px)); }
  .vs-tag { margin-bottom: 8px; }
  .vs-who strong { font-size: 16px; }
  .vs-who span { font-size: 14px; }
  .vs-lid { top: 3.4%; }
}
@supports (height: 100svh) { @media (max-width: 1100px) { .vs-frame { height: min(calc(100svh - var(--chrome-m, 220px)), calc(100vw * 16 / 9), 780px); } } }

/* reduced motion: no drifting, no pulse; the stage still pins and reveals, the video waits for a tap */
@media (prefers-reduced-motion: reduce) {
  .vs-haze, .vs-dust i, .vstage[data-state="playing"] .vs-sound[aria-pressed="false"] { animation: none; }
}

/* a clip that cannot be loaded (link gone, offline): the poster stays, the controls go, one quiet line says why */
.vs-error { position: absolute; left: 0; right: 0; bottom: 0; z-index: 4; padding: 40px 18px 22px; text-align: center; font-size: 15px; color: #fff;
            background: linear-gradient(to top, rgba(10,12,16,.92), rgba(10,12,16,0)); pointer-events: none; }
.vstage.is-broken .vs-state, .vstage.is-broken .vs-sound, .vstage.is-broken .vs-tap { display: none; }
.vstage.is-broken .vs-poster { opacity: 1 !important; }
