/* ============================================================
   CAVMIR — HERO MOTION LAYER
   Loads AFTER main.css, so equal-specificity rules here win.

   What it adds to the homepage hero:
     1. Media life      — the video breathes instead of sitting still
     2. Ambient light   — a generative canvas light-field (hero-motion.js)
     3. Specular rake   — a soft light sweep, like sun across glass
     4. Film grain      — filmic texture; also kills gradient banding
     5. Kinetic type    — per-line mask reveal, staggered
     6. Scroll dissolve — hero content lifts and fades out on scroll

   Everything animates transform / opacity / filter only — no layout.

   TWO CLASSES DRIVE IT, both added by hero-motion.js:
     .hm-armed    — "JS is alive": only now do we hide anything. Without
                    JS the hero renders exactly as it always did, fully
                    visible. Nothing here may hide content unconditionally.
     .hm-in — added once the CAVMIR title-card preloader opens its
                    curtains, so the reveal is never spent behind them.
   ============================================================ */

.hero--motion {
  --hm-ease: cubic-bezier(0.16, 1, 0.3, 1);
  --hm-copper: #C26A3F;
  /* Written by hero-motion.js each frame. */
  --hm-px: 0px;   /* pointer parallax x */
  --hm-py: 0px;   /* pointer parallax y */
  --hm-sy: 0px;   /* scroll dissolve lift */
  --hm-op: 1;     /* scroll dissolve fade  */
  /* Contain the screen-blend layers to this section. */
  isolation: isolate;
}

/* Lift the existing content above the new light layers. */
.hero--motion .hero-content { z-index: 6; }
.hero--motion .hero-scroll  { z-index: 6; }

/* ── 0. Vignette ───────────────────────────────────────────────
   Static, and the one layer that survives reduced motion and small
   screens: it is what makes the frame read as a lens rather than a
   flat photo, and it buys the headline contrast on the left. */
.hero--motion::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 4;
  pointer-events: none;
  background: radial-gradient(
    118% 92% at 50% 42%,
    rgba(0, 0, 0, 0) 45%,
    rgba(12, 4, 10, 0.34) 78%,
    rgba(10, 3, 9, 0.62) 100%
  );
}

/* ── 1. Media life ─────────────────────────────────────────────
   .hero-bg already carries a JS scroll-parallax transform (main.js),
   so the drift rides on .hero-video, which nothing else touches. */
.hero--motion.hm-in .hero-video {
  will-change: transform;
  animation: hmDrift 38s ease-in-out infinite alternate;
}
@keyframes hmDrift {
  from { transform: scale(1.015) translate3d(0, 0, 0); }
  to   { transform: scale(1.10)  translate3d(-1.1%, -0.9%, 0); }
}

/* ── 2. Ambient light field ────────────────────────────────────
   The canvas is deliberately tiny (see hero-motion.js) and stretched
   here — the browser's own upscaling is what makes it soft, which is
   far cheaper than a large CSS blur repainting every frame. */
.hero--motion .hero-aurora {
  position: absolute;
  inset: -14%;
  width: 128%;
  height: 128%;
  z-index: 3;
  pointer-events: none;
  mix-blend-mode: screen;
  opacity: 0;
  transform: translate3d(calc(var(--hm-px) * 2.6), calc(var(--hm-py) * 2.6), 0);
  transition: opacity 2.2s ease 0.15s;
}
.hero--motion.hm-in .hero-aurora { opacity: 0.46; }

/* ── 3. Specular rake ──────────────────────────────────────────
   A wide, very soft band of light that crosses the hero every ~14s. */
.hero--motion .hero-rake {
  position: absolute;
  inset: 0;
  z-index: 4;
  pointer-events: none;
  overflow: hidden;
}
.hero--motion .hero-rake::after {
  content: '';
  position: absolute;
  top: -60%;
  left: 0;
  width: 30%;
  height: 220%;
  background: linear-gradient(
    90deg,
    rgba(255, 255, 255, 0) 0%,
    rgba(255, 240, 232, 0.07) 42%,
    rgba(255, 246, 240, 0.13) 50%,
    rgba(255, 240, 232, 0.07) 58%,
    rgba(255, 255, 255, 0) 100%
  );
  transform: rotate(16deg) translate3d(-80vw, 0, 0);
  opacity: 0;
}
.hero--motion.hm-in .hero-rake::after {
  animation: hmRake 14s cubic-bezier(0.42, 0, 0.28, 1) 3.2s infinite;
}
@keyframes hmRake {
  0%        { transform: rotate(16deg) translate3d(-80vw, 0, 0); opacity: 0; }
  8%        { opacity: 1; }
  48%       { opacity: 1; }
  60%, 100% { transform: rotate(16deg) translate3d(190vw, 0, 0); opacity: 0; }
}

/* ── 4. Film grain ─────────────────────────────────────────────
   feTurbulence baked to a data URI: one small tile, no request. */
.hero--motion .hero-grain {
  position: absolute;
  inset: -60px;
  z-index: 5;
  pointer-events: none;
  opacity: 0.048;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 160px 160px;
}
.hero--motion.hm-in .hero-grain {
  animation: hmGrain 0.9s steps(5) infinite;
}
@keyframes hmGrain {
  0%   { transform: translate3d(0, 0, 0); }
  20%  { transform: translate3d(-14px, 8px, 0); }
  40%  { transform: translate3d(9px, -12px, 0); }
  60%  { transform: translate3d(-7px, -6px, 0); }
  80%  { transform: translate3d(12px, 10px, 0); }
  100% { transform: translate3d(0, 0, 0); }
}

/* ── 5. Kinetic type ───────────────────────────────────────────
   Pointer parallax and scroll dissolve share one transform, composed
   from custom properties so they never overwrite each other. */
.hero--motion.hm-armed .hero-content {
  transform: translate3d(var(--hm-px), calc(var(--hm-py) + var(--hm-sy)), 0);
  opacity: var(--hm-op);
}

/* Each headline line sits in its own mask and rises out of it. The
   padding / negative-margin pair keeps descenders from clipping. */
.hero--motion .hm-line {
  display: block;
  overflow: hidden;
  padding-bottom: 0.1em;
  margin-bottom: -0.1em;
}
.hero--motion .hm-line > span { display: block; }
.hero--motion.hm-armed .hm-line > span {
  transform: translate3d(0, 112%, 0);
  opacity: 0;
  filter: blur(9px);
  transition:
    transform 1.25s var(--hm-ease),
    opacity 0.85s ease,
    filter 0.9s ease;
}
.hero--motion.hm-in .hm-line > span { transform: none; opacity: 1; filter: none; }
.hero--motion.hm-in .hm-line:nth-of-type(2) > span { transition-delay: 0.11s; }
.hero--motion.hm-in .hm-line:nth-of-type(3) > span { transition-delay: 0.22s; }

/* The accent line keeps the editorial serif but drops the old gold —
   hierarchy comes from the typeface, the weight and the copper rule. */
.hero--motion .hm-line em {
  font-style: normal;
  font-family: var(--font-editorial);
  font-weight: 300;
  color: #FFFFFF;
}

.hero--motion .hm-rule {
  display: block;
  width: min(340px, 46vw);
  height: 1px;
  margin: 26px 0 24px;
  background: linear-gradient(90deg, var(--hm-copper), rgba(255, 255, 255, 0.14));
  transform-origin: left center;
}
.hero--motion.hm-armed .hm-rule {
  transform: scaleX(0);
  transition: transform 1.3s var(--hm-ease) 0.55s;
}
.hero--motion.hm-in .hm-rule { transform: scaleX(1); }

.hero--motion.hm-armed .hero-sub,
.hero--motion.hm-armed .hero-actions {
  opacity: 0;
  transform: translate3d(0, 20px, 0);
  transition: opacity 1s ease, transform 1.1s var(--hm-ease);
}
.hero--motion.hm-in .hero-sub     { opacity: 1; transform: none; transition-delay: 0.50s; }
.hero--motion.hm-in .hero-actions { opacity: 1; transform: none; transition-delay: 0.64s; }

/* ── 6. Scroll cue ─────────────────────────────────────────────
   Replaces the bouncing gold marker with an ivory line that drains. */
.hero--motion .hero-scroll {
  color: rgba(255, 255, 255, 0.66);
  animation: none;
}
.hero--motion .hero-scroll::before {
  background: linear-gradient(to bottom, rgba(255, 255, 255, 0.85), rgba(255, 255, 255, 0));
  transform-origin: top center;
}
.hero--motion.hm-armed .hero-scroll {
  opacity: 0;
  transition: opacity 1s ease 1s;
}
.hero--motion.hm-in .hero-scroll { opacity: 1; }
.hero--motion.hm-in .hero-scroll::before {
  animation: hmScrollCue 2.6s cubic-bezier(0.65, 0, 0.35, 1) infinite;
}
@keyframes hmScrollCue {
  0%   { transform: scaleY(0); transform-origin: top center; }
  45%  { transform: scaleY(1); transform-origin: top center; }
  55%  { transform: scaleY(1); transform-origin: bottom center; }
  100% { transform: scaleY(0); transform-origin: bottom center; }
}

/* ── 7. Reduced motion ─────────────────────────────────────────
   Everything lands in its finished state; nothing loops. */
@media (prefers-reduced-motion: reduce) {
  .hero--motion .hero-aurora,
  .hero--motion .hero-rake,
  .hero--motion .hero-grain { display: none; }

  .hero--motion.hm-in .hero-video { animation: none; transform: scale(1.04); }

  .hero--motion.hm-armed .hero-content { transform: none; opacity: 1; }

  .hero--motion.hm-armed .hero-sub,
  .hero--motion.hm-armed .hero-actions,
  .hero--motion.hm-armed .hero-scroll { opacity: 1; transform: none; transition: none; }

  .hero--motion.hm-armed .hm-rule { transform: scaleX(1); transition: none; }

  .hero--motion.hm-armed .hm-line > span { transform: none; opacity: 1; filter: none; transition: none; }

  .hero--motion.hm-in .hero-scroll::before { animation: none; transform: scaleY(1); }
}

/* ── 8. Phones ─────────────────────────────────────────────────
   Trim the most expensive layers and shorten the throw. */
@media (max-width: 700px) {
  .hero--motion .hero-rake { display: none; }
  .hero--motion.hm-in .hero-aurora { opacity: 0.38; }
  .hero--motion .hero-grain { opacity: 0.038; }
  .hero--motion.hm-armed .hero-content {
    transform: translate3d(0, var(--hm-sy), 0);
  }
  .hero--motion .hm-rule { margin: 20px 0 18px; }
}
