/* ==========================================================================
   Intro hero + Home stage. Two modes:
   1. Fallback (no html.js-intro): normal stack. Poster still on top, then the
      Home floor as an ordinary full-height section. Used with no JS, a module
      error, reduced motion, or blocked playback. Never a blank runway.
   2. html.js-intro: a 320lvh runway with one sticky 100lvh stage. intro.js
      writes every visual from one progress value p via CSS variables.
   lvh (large viewport height) is used on purpose: the iPhone toolbar
   collapsing must not resize the stage or move progress.
   ========================================================================== */

/* ---------- fallback (default) ---------- */
.runway { position: relative; }
.stage { position: relative; display: flex; flex-direction: column; background: var(--navy-950); }
.film { order: 0; position: relative; aspect-ratio: 16 / 9; max-height: 100svh; width: 100%; overflow: hidden; background: var(--navy-950); }
.film-poster, .film-loop, .film-push { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.film-loop, .film-push { opacity: 0; }
.home-floor { order: 1; position: relative; min-height: 100svh; }
.intro-ui { order: 0; position: absolute; inset: 0 0 auto 0; z-index: 3; pointer-events: none; }
.intro-ui > * { pointer-events: auto; }
.intro-cue { display: none; }
.anchor { display: block; position: relative; top: 0; height: 0; }
html:not(.js-intro) .anchor { position: absolute; top: auto; }
html:not(.js-intro) .home-floor { scroll-margin-top: var(--nav-h); }
/* In the fallback the nav is always available */
html:not(.js-intro) .site-nav[data-state="hidden"] { transform: none; opacity: 1; pointer-events: auto; }
html:not(.js-intro) .film { margin-top: var(--nav-h); }

.intro-brand { position: absolute; left: var(--gutter); top: 22px; }
/* the page's h1 (visible in the very first frame, which is all Google renders: it never scrolls);
   weight and tracking reset from the global h1 rule so it looks exactly like the old paragraph */
.intro-name {
  position: absolute; left: var(--gutter); bottom: 28px;
  font-family: var(--f-display); font-size: clamp(18px, 1.6vw, 24px); color: #fff; line-height: 1.2;
  font-weight: 300; letter-spacing: normal;
  text-shadow: 0 2px 18px rgba(0,0,0,.55);
}
.intro-name span { display: block; margin-top: 4px; font-family: var(--f-body); font-size: 12px; letter-spacing: .18em; text-transform: uppercase; color: var(--copper-hi); }
/* fallback (no JS, reduced motion): keep the name and h1 over the poster, same box as the film */
html:not(.js-intro) .intro-ui {
  position: absolute; left: 0; right: 0; top: var(--nav-h);
  aspect-ratio: 16 / 9; max-height: calc(100svh - var(--nav-h)); pointer-events: none;
}
html:not(.js-intro) .intro-brand, html:not(.js-intro) .intro-cue { display: none; }

/* ---------- js-intro: the sticky stage ---------- */
html.js-intro .runway { height: 320lvh; }
html.js-intro .stage {
  position: sticky; top: 0; height: 100lvh; overflow: clip; display: block;
}
html.js-intro .home-floor,
html.js-intro .film,
html.js-intro .intro-ui { position: absolute; inset: 0; }
/* Home sits ABOVE the film: while it grows out of the laptop screen it only
   covers the screen quad (matrix3d), so the film shows everywhere else. */
html.js-intro .home-floor { z-index: 2; min-height: 0; }
/* his fingers and the laptop edge, drawn back over the live screen (intro.js); same layer as Home, later in the DOM */
.film-hands { display: none; }
html.js-intro .film-hands { display: block; position: absolute; inset: 0; width: 100%; height: 100%; z-index: 2; pointer-events: none; }
html.js-intro .film {
  z-index: 1; pointer-events: none; aspect-ratio: auto; max-height: none; margin: 0;
  transform-origin: var(--film-ox, 50%) var(--film-oy, 50%);
  transform: scale(var(--film-scale, 1));
  opacity: var(--film-opacity, 1);
  will-change: transform, opacity;
}
html.js-intro .intro-ui { z-index: 3; display: block; opacity: var(--ui-opacity, 1); }
html.js-intro .intro-cue {
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  position: absolute; left: 50%; bottom: 30px; transform: translateX(-50%);
  font-size: 12px; letter-spacing: .2em; text-transform: uppercase; color: var(--sky-100);
  text-shadow: 0 2px 14px rgba(0,0,0,.6);
  white-space: nowrap;           /* left:50% leaves it half the width; wrapping ran it into the name on 360-390 px phones */
}
html.js-intro .intro-cue i {
  width: 1px; height: 38px; background: linear-gradient(var(--copper-hi), transparent);
  animation: cue 1.8s var(--ease-out) infinite;
  transform-origin: top;
}
@keyframes cue { 0% { transform: scaleY(0); opacity: 1; } 70% { transform: scaleY(1); opacity: 1; } 100% { transform: scaleY(1); opacity: 0; } }
html.js-intro .anchor { position: absolute; left: 0; top: calc(100% - 100lvh); height: 1px; width: 1px; scroll-margin-top: 0; }

/* Home fading/scaling in from the laptop screen rect (values from intro.js) */
html.js-intro .home-floor {
  transform-origin: 0 0;
  transform: translate(var(--home-tx, 0px), var(--home-ty, 0px)) scale(var(--home-sx, 1), var(--home-sy, 1));
  opacity: var(--home-opacity, 1);
  will-change: transform, opacity;
}

/* phones: the push as an image sequence, drawn into a canvas that intro.js sizes to the
   exact cover box (media/phone/, js/phone-seq.js) */
.film-seq { position: absolute; left: 0; top: 0; width: 100%; height: 100%; opacity: 0; pointer-events: none; }
/* phones: the live robot floor pinned to the laptop screen (a 640x360 box, matrix3d from
   intro.js). It sits under Home in the stack, over the film, under his fingers (.film-hands). */
.film-screen { display: none; }
html.js-intro .film-screen {
  display: block; position: absolute; left: 0; top: 0; width: 640px; height: 360px;
  transform-origin: 0 0; z-index: 2; pointer-events: none; visibility: hidden; opacity: 0;
  background: #04102a url("../media/floor-poster-1280.jpg") center / 100% 100% no-repeat;
  backface-visibility: hidden; will-change: transform, opacity;
}
.film-screen video { display: block; width: 100%; height: 100%; object-fit: fill; }

/* extra film layers created by intro.js */
.film-end, .film-bloom { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.film-end { object-fit: cover; opacity: 0; }
.film-bloom {
  opacity: 0;
  background: radial-gradient(60% 55% at var(--bloom-x, 30%) var(--bloom-y, 60%), rgba(236, 246, 255, .95) 0%, rgba(168, 203, 230, .75) 35%, rgba(8, 26, 48, 0) 75%);
  mix-blend-mode: screen;
}
.film-loop, .film-push { transition: none; }

/* Phones in portrait (Nikola 2026-09-23: "I want the video to fully fit my
   phone, PHONE ONLY"): the film fills the whole screen. Since 2026-09-24 the
   phone push is an image sequence of the whole picture (no zoom), drawn by
   intro.js into .film-seq; the idle loop is the same picture. Name and cue sit
   on soft scrims over it. */
@media (max-width: 700px) and (orientation: portrait) {
  .film { aspect-ratio: auto; height: 100svh; max-height: none; }
  html:not(.js-intro) .intro-ui { aspect-ratio: auto; height: calc(100svh - var(--nav-h)); max-height: none; }
  html.js-intro .film { inset: 0; height: auto; }
  html.js-intro .intro-ui::before {
    content: ""; position: absolute; inset: 0; pointer-events: none;
    background:
      linear-gradient(180deg, rgba(4, 12, 30, .62) 0%, rgba(4, 12, 30, 0) 20%),
      linear-gradient(0deg, rgba(4, 12, 30, .88) 0%, rgba(4, 12, 30, .55) 16%, rgba(4, 12, 30, 0) 38%);
  }
  html.js-intro .intro-name { top: auto; bottom: calc(96px + env(safe-area-inset-bottom)); font-size: 26px; }
  html.js-intro .intro-name span { font-size: 11.5px; }
  html.js-intro .intro-cue { bottom: calc(22px + env(safe-area-inset-bottom)); }
}
/* Landscape phones: short viewport, keep chrome clear of the video's subject */
@media (orientation: landscape) and (max-height: 520px) {
  .intro-name { bottom: 14px; font-size: 16px; }
  html.js-intro .intro-cue { bottom: 12px; }
  .intro-brand { top: 12px; }
}

@media (prefers-reduced-motion: reduce) {
  html.js-intro .intro-cue i { animation: none; }
}

/* Pause motion button: only while motion is on screen (js/ui.js adds
   .is-away past the hero + Home), and a compact round icon on phones so it
   never sits on top of copy or form fields. */
.motion-toggle { transition: transform .3s var(--ease-out), opacity .3s var(--ease-out), border-color .18s; }
.motion-toggle.is-away { opacity: 0; transform: translateY(12px) scale(.9); pointer-events: none; }
@media (max-width: 700px) {
  .motion-toggle { width: 44px; height: 44px; min-height: 44px; padding: 0; justify-content: center; border-radius: 50%; }
  .motion-toggle .mt-label {
    position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
  }
}
