/* Stage video — the explainer that rises out of the hero.
   Shared by the static pages (/salesos/, /ontos/). It reads the page's own
   Climbee tokens (--ink-*, --bone-*, --amber, --line*, --font-sans, --dur-*,
   --ease-*, --container-max, --gutter), so it carries no palette of its own.

   One frame, three states:
     ambient  a muted loop under the hero, drawn only while it is on screen.
              The frame starts inset, at the width of the page, and widens to
              the largest 16:9 that fits the viewport as the reader scrolls
              (--p, 0..1, written by stage.js). Pinned while it is full.
     playing  "Assistir com som" restarts the real video from 0 with sound
              and a quiet control bar.
     ended    holds the last frame (each video closes on its own line) and
              offers the next step.

   Without JS the frame is a plain <video controls>. With reduced motion, or
   on a phone, the frame stays at page width and nothing is pinned. */

.sv { --p: 0; position: relative; background: var(--ink-800); color: var(--bone-200); }

/* Geometry. Both lengths resolve against the pin's width, so the same
   expression works for width and margin-top. */
.sv-frame {
  --w0: min(var(--container-max), calc(100% - 2 * var(--gutter)));
  --wf: min(100%, calc((100vh - var(--nav-h, 0px)) * 1.7778));
  position: relative;
  margin-inline: auto;
  width: calc(var(--w0) + (var(--wf) - var(--w0)) * var(--p));
  aspect-ratio: 16 / 9;
  background: var(--ink-800);
  overflow: hidden;
  isolation: isolate;
}

/* The pin sits under the page's fixed nav (--nav-h) and holds for 70vh. */
.sv.is-js { height: calc(100vh - var(--nav-h, 0px) + 70vh); }
.sv.is-js .sv-pin { position: sticky; top: var(--nav-h, 0px); height: calc(100vh - var(--nav-h, 0px)); }
.sv.is-js .sv-frame {
  margin-top: calc((100vh - var(--nav-h, 0px) - (var(--w0) + (var(--wf) - var(--w0)) * var(--p)) * 0.5625) / 2 * var(--p));
}
.sv:not(.is-js) .sv-pin { padding-block: 0 var(--space-9); }

.sv-frame video { position: absolute; inset: 0; width: 100%; height: 100%; display: block; object-fit: cover; background: var(--ink-800); }
/* No line around the frame: the picture sits on the page's own ink. When a
   video's background is a shade off the page (data-feather), its edges
   dissolve into the page instead of ending in a seam. */
.sv[data-feather] .sv-frame video {
  --f: 2.5%;
  -webkit-mask-image: linear-gradient(to right, transparent, #000 var(--f), #000 calc(100% - var(--f)), transparent), linear-gradient(to bottom, transparent, #000 var(--f), #000 calc(100% - var(--f)), transparent);
  -webkit-mask-composite: source-in;
  mask-image: linear-gradient(to right, transparent, #000 var(--f), #000 calc(100% - var(--f)), transparent), linear-gradient(to bottom, transparent, #000 var(--f), #000 calc(100% - var(--f)), transparent);
  mask-composite: intersect;
}
.sv.is-js .sv-main { opacity: 0; pointer-events: none; transition: opacity var(--dur-slow) var(--ease-standard); }
.sv.is-js .sv-loop { transition: opacity var(--dur-slow) var(--ease-standard); }
.sv:not(.is-js) .sv-loop { display: none; }
.sv[data-state="playing"] .sv-main,
.sv[data-state="ended"] .sv-main { opacity: 1; pointer-events: auto; }
.sv[data-state="playing"] .sv-loop,
.sv[data-state="ended"] .sv-loop { opacity: 0; }
.sv .sv-main::-webkit-media-controls { display: none !important; }
.sv:not(.is-js) .sv-main { position: absolute; }

/* The one affordance in the ambient state: a square amber key and a label.
   It has to read as "there is sound behind this" without covering the image. */
.sv-play {
  position: absolute; left: var(--space-5); bottom: var(--space-5); z-index: 2;
  display: inline-flex; align-items: stretch; height: var(--btn-height);
  padding: 0; border: var(--border-hair) solid var(--line-strong);
  background: rgba(22, 22, 21, 0.86); color: var(--bone-200);
  font: var(--fw-medium) var(--fs-label)/1 var(--font-sans);
  letter-spacing: var(--ls-label); text-transform: uppercase; cursor: pointer;
  transition: border-color var(--dur-base) var(--ease-standard), opacity var(--dur-slow) var(--ease-standard);
}
.sv-play:hover { border-color: var(--amber); }
.sv-play .k { display: grid; place-items: center; width: var(--btn-height); background: var(--amber); color: var(--ink-900); transition: background var(--dur-base) var(--ease-standard); }
.sv-play:hover .k { background: var(--amber-strong); }
.sv-play .k svg { width: 18px; height: 18px; display: block; }
.sv-play .l { display: flex; align-items: center; gap: var(--space-3); padding-inline: var(--space-5) var(--space-5); }
.sv-play .d { color: var(--text-muted); }
.sv[data-state="playing"] .sv-play, .sv[data-state="ended"] .sv-play { opacity: 0; pointer-events: none; }
.sv:not(.is-js) .sv-play { display: none; }

/* Control bar. Always visible while paused; fades after a still moment. */
.sv-bar {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 3;
  display: none; align-items: center; height: var(--btn-height);
  background: rgba(22, 22, 21, 0.9); border-top: var(--border-hair) solid var(--line);
  transition: opacity var(--dur-slow) var(--ease-standard);
}
.sv[data-state="playing"] .sv-bar { display: flex; }
.sv[data-state="playing"].is-idle .sv-bar { opacity: 0; }
.sv[data-state="playing"].is-idle .sv-frame { cursor: none; }
.sv-bar button {
  flex: 0 0 auto; display: grid; place-items: center; width: var(--btn-height); height: 100%;
  padding: 0; border: 0; background: none; color: var(--bone-200); cursor: pointer;
  transition: color var(--dur-fast) var(--ease-standard);
}
.sv-bar button:hover { color: var(--amber); }
.sv-bar button svg { width: 20px; height: 20px; display: block; }
.sv-bar button[aria-pressed="true"] { color: var(--amber); }
.sv-bar .t { flex: 0 0 auto; padding-inline: var(--space-3); font: var(--fw-medium) 12px/1 var(--font-sans); letter-spacing: var(--ls-label); color: var(--text-muted); font-variant-numeric: tabular-nums; }
.sv-bar input[type="range"] {
  -webkit-appearance: none; appearance: none; flex: 1 1 auto; min-width: 0; height: 100%;
  margin: 0; background: none; cursor: pointer; --v: 0%;
}
.sv-bar input[type="range"]::-webkit-slider-runnable-track { height: 3px; background: linear-gradient(to right, var(--amber) var(--v), var(--ink-500) var(--v)); }
.sv-bar input[type="range"]::-moz-range-track { height: 3px; background: var(--ink-500); }
.sv-bar input[type="range"]::-moz-range-progress { height: 3px; background: var(--amber); }
.sv-bar input[type="range"]::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 10px; height: 10px; margin-top: -3.5px; border: 0; border-radius: 0; background: var(--bone-200); }
.sv-bar input[type="range"]::-moz-range-thumb { width: 10px; height: 10px; border: 0; border-radius: 0; background: var(--bone-200); }
.sv-bar input[type="range"]:focus-visible { outline: var(--focus-width) solid var(--focus-ring); outline-offset: -2px; }
.sv-bar .ic-pause, .sv-bar .ic-mute { display: none; }
.sv-bar [data-on] .ic-play, .sv-bar [data-on] .ic-vol { display: none; }
.sv-bar [data-on] .ic-pause, .sv-bar [data-on] .ic-mute { display: block; }

/* End card. The last frame stays under it; each video ends on its thesis. */
.sv-end {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 4; display: none;
  flex-wrap: wrap; align-items: center; gap: var(--space-3) var(--space-3);
  padding: var(--space-4) var(--space-5);
  background: rgba(22, 22, 21, 0.94); border-top: var(--border-hair) solid var(--line);
}
.sv[data-state="ended"] .sv-end { display: flex; animation: sv-rise var(--dur-slow) var(--ease-out) both; }
.sv-end .sv-end-t { flex: 1 1 auto; margin: 0; font: var(--fw-medium) var(--fs-label)/1 var(--font-sans); letter-spacing: var(--ls-label); text-transform: uppercase; color: var(--text-muted); }
@keyframes sv-rise { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }

.sv-note { max-width: var(--container-max); margin: var(--space-4) auto 0; padding-inline: var(--gutter); font-size: var(--fs-caption); color: var(--text-muted); }
.sv.is-js .sv-note { display: none; }

/* Fullscreen: the largest 16:9, never cropped. */
.sv-frame:fullscreen { width: 100%; height: 100%; aspect-ratio: auto; margin: 0; }
.sv-frame:fullscreen video { object-fit: contain; }
.sv-frame:-webkit-full-screen { width: 100%; height: 100%; aspect-ratio: auto; margin: 0; }
.sv-frame:-webkit-full-screen video { object-fit: contain; }

/* Phone and reduced motion: no pinning, no growing. The frame is simply
   there, at the width of the page, right under the hero. */
@media (max-width: 719px), (prefers-reduced-motion: reduce) {
  .sv.is-js { height: auto; }
  .sv.is-js .sv-pin { position: static; height: auto; padding-bottom: var(--space-8); }
  .sv.is-js .sv-frame { margin-top: 0; }
  .sv { --p: 0 !important; }
  .sv-play { left: var(--space-3); bottom: var(--space-3); height: var(--btn-height-compact); }
  .sv-play .k { width: var(--btn-height-compact); }
  .sv-play .l { padding-inline: var(--space-4); gap: var(--space-2); }
  .sv-play .d { display: none; }
  .sv-bar { height: var(--btn-height-compact); }
  .sv-bar button { width: var(--btn-height-compact); }
  .sv-end { padding: var(--space-3); }
  .sv-end .sv-end-t { flex-basis: 100%; }
}
@media (prefers-reduced-motion: reduce) {
  .sv.is-js .sv-main, .sv.is-js .sv-loop, .sv-bar { transition: none; }
  .sv[data-state="ended"] .sv-end { animation: none; }
}
