/* ============================================
   HERO — layered cinematic scene
   Back → front: 1 atmosphere + ground, 2 mountains, 3 foreground rocks,
   4 crystal, 5 particles/fx, then shade, then content.

   Calm pass: every layer keeps its role but is dialled back so the crystal
   is the one bright thing. The text side is faded toward black on layers
   1–3, the fx layer only lives on the crystal's side, and idle motion is
   slower and smaller.

   All five artwork files share one ~1.86:1 canvas, so every plane lives on a
   single "stage" box with that aspect ratio. The stage covers the hero like
   object-fit: cover, which keeps the layers registered to each other at any
   viewport size. --stage-x / --stage-y act like object-position.
============================================ */
.hero{
  --stage-ratio: 1.8618;          /* 1711 × 919 artwork canvas */
  --stage-x: 50%;
  --stage-y: 62%;
  --crystal-x: 70%;               /* crystal centre, % of stage */
  --crystal-y: 58%;               /* low: hovering just above the valley floor */
  --crystal-w: 54%;               /* crystal canvas width, % of stage */
  --float: 6px;                   /* crystal bob amplitude */
  --tilt: .6deg;

  /* text-side fade shared by the landscape layers */
  --calm-mask: linear-gradient(90deg, rgba(0,0,0,.3) 0%, rgba(0,0,0,.5) 32%, #000 62%);

  position: relative; min-height: 100vh; min-height: 100svh;
  display:flex; flex-direction:column; justify-content:center;
  padding: 140px var(--gutter) 80px;
  /* line the copy up with the header's container edge on wide screens */
  padding-inline: max(var(--gutter), calc((100% - var(--container)) / 2 + var(--gutter)));
  overflow: hidden; isolation: isolate;
  background: #010101;            /* matches layer 1's sky */
}

.hero-scene{
  position:absolute; inset:-16px;  /* bleed so parallax never exposes an edge */
  z-index:0; pointer-events:none;
  container-type: size;
}
.hero.has-scene-js .hero-scene{ opacity:0; transition: opacity 1.8s var(--ease-soft); }
.hero.has-scene-js.is-live .hero-scene{ opacity:1; }

.hero-stage{
  position:absolute;
  width: max(100%, 186vh);                                       /* fallback */
  width: max(100cqw, calc(100cqh * var(--stage-ratio)));
  aspect-ratio: 1711 / 919;
  left: var(--stage-x); top: var(--stage-y);
  transform: translate(calc(var(--stage-x) * -1), calc(var(--stage-y) * -1));
}

.hero-plane{ position:absolute; inset:0; }
.hero.is-interactive .hero-plane{ will-change: transform; }

.hero-layer{
  position:absolute; inset:0; width:100%; height:100%; max-width:none;
  object-fit: cover; user-select:none; -webkit-user-drag:none;
}

/* ============================================
   Crystal energy cycle — one 9s clock drives the aura around the crystal,
   the atmosphere behind it, the light on the ground and a faint lift in the
   crystal itself, so the whole scene "breathes" together.
   Resting values (used under reduced motion) are a stable moderate glow.
============================================ */
.hero{ --energy: 9s; }

/* ---- Layer 1 atmosphere: fog kept, but quieter and faded on the text side ---- */
.layer-1{
  filter: brightness(.72) saturate(.9);
  -webkit-mask-image: var(--calm-mask);
          mask-image: var(--calm-mask);
}

/* Light behind the crystal rises with its energy */
.crystal-backlight{
  position:absolute; left: var(--crystal-x); top: calc(var(--crystal-y) + 4%);
  width: 46%; height: 62%; transform: translate(-50%,-50%);
  background: radial-gradient(closest-side, rgba(150,230,40,.16), rgba(150,230,40,.05) 55%, transparent);
  opacity:.75;
  animation: energyBacklight var(--energy) linear infinite;
}

/* ---- Layer 2 mountains: pushed back into the haze ---- */
.layer-2{
  opacity:.6;
  filter: brightness(.72) saturate(.85);
  -webkit-mask-image: var(--calm-mask);
          mask-image: var(--calm-mask);
}

/* ---- Layer 3 rocks: slightly darker so they frame rather than compete ---- */
.layer-3{ filter: brightness(.8) saturate(.9); }
/* Mask lives on the plane, not the <img>: Chromium drops this layer when a
   mask and a filter share the same element. */
.plane-3{
  -webkit-mask-image: linear-gradient(90deg, rgba(0,0,0,.35) 0%, rgba(0,0,0,.6) 32%, #000 58%);
          mask-image: linear-gradient(90deg, rgba(0,0,0,.35) 0%, rgba(0,0,0,.6) 32%, #000 58%);
}

/* Light pooled on the wet ground under the crystal */
.ground-glow{
  position:absolute; left: var(--crystal-x); top: 86%;
  width: 40%; height: 14%; transform: translate(-50%,-50%);
  background: radial-gradient(closest-side, rgba(190,255,70,.34), rgba(150,230,40,.1) 60%, transparent);
  mix-blend-mode: screen;
  opacity:.78;
  animation: energyGround var(--energy) linear infinite;
}

/* ---- Layer 4 crystal ---- */
.hero-crystal{
  position:absolute; left: var(--crystal-x); top: var(--crystal-y);
  width: var(--crystal-w); aspect-ratio: 1713 / 918;
  transform: translate(-51.4%, -52.2%);   /* centre of the crystal's visible bounds in its canvas */
}
.crystal-float, .crystal-tilt{ position:absolute; inset:0; }
.crystal-float{ animation: crystalFloat 8s ease-in-out infinite; }
.crystal-tilt{ transform-origin: 51% 55%; animation: crystalTilt 13s ease-in-out infinite; }
.layer-4{
  filter: brightness(1.025);
  animation: energyCore var(--energy) linear infinite;   /* ≤5% lift: the object stays stable */
}

/* Aura: a blurred duplicate of the crystal *behind* the original. Only its
   rim shows past the crystal's body, so the glow hugs the silhouette instead
   of forming a halo. Blur lives on the <img> (rasterised once); only the
   wrapper's opacity animates. */
.crystal-aura{
  position:absolute; inset:0;
  mix-blend-mode: plus-lighter;
  opacity:.6;
  animation: energyAura var(--energy) linear infinite;
}
/* Tinted to neon lime so the glow stays in the green band instead of blooming to white. */
.crystal-aura img{ filter: blur(10px) sepia(1) hue-rotate(50deg) saturate(3.4) brightness(1.05); }

/* ---- Layer 5 fx: gem shards, streaks and sparks across the whole scene.
   One artwork, split in two so each side drifts on its own clock ---- */
.fx-part{ position:absolute; inset:0; }
.fx-left{
  opacity:.45;                                   /* sits under the headline */
  -webkit-mask-image: linear-gradient(90deg, #000 42%, transparent 58%);
          mask-image: linear-gradient(90deg, #000 42%, transparent 58%);
}
.fx-right{
  -webkit-mask-image: linear-gradient(90deg, transparent 42%, #000 58%);
          mask-image: linear-gradient(90deg, transparent 42%, #000 58%);
}
.fx-left  .layer-5{ animation: fxDriftA 23s ease-in-out infinite alternate, fxFlicker 9s ease-in-out infinite; }
.fx-right .layer-5{ animation: fxDriftB 17s ease-in-out infinite alternate, fxFlicker 12s ease-in-out -4s infinite; }

.fx-motes i{
  position:absolute; width:4px; height:4px; border-radius:50%;
  background: radial-gradient(circle, rgba(215,255,110,.95), rgba(170,255,50,0) 70%);
  opacity:0; animation: mote 13s ease-in-out infinite;
}
.fx-motes i:nth-child(1){ left:58%; top:62%; animation-duration:14s; }
.fx-motes i:nth-child(2){ left:74%; top:40%; animation-duration:17s; animation-delay:-5s; width:3px; height:3px; }
.fx-motes i:nth-child(3){ left:83%; top:70%; animation-duration:12s; animation-delay:-8s; }
.fx-motes i:nth-child(4){ left:66%; top:24%; animation-duration:19s; animation-delay:-2s; width:3px; height:3px; }
.fx-motes i:nth-child(5){ left:90%; top:50%; animation-duration:15s; animation-delay:-11s; width:5px; height:5px; }
.fx-motes i:nth-child(6){ left:52%; top:78%; animation-duration:16s; animation-delay:-7s; width:3px; height:3px; }

/* ---- Legibility: darken the text column, vignette the corners, fade the base into the page ---- */
.hero-shade{
  position:absolute; inset:0;
  background:
    linear-gradient(90deg, rgba(1,1,1,.78) 0%, rgba(1,1,1,.55) 25%, rgba(1,1,1,.12) 45%, rgba(1,1,1,0) 55%),
    radial-gradient(120% 90% at 68% 50%, rgba(1,1,1,0) 55%, rgba(1,1,1,.5) 100%),
    linear-gradient(0deg, var(--bg) 0%, rgba(10,10,10,0) 13%);
}

/* ---- Keyframes (transform / opacity / filter only) ---- */
@keyframes crystalFloat{
  0%,100%{ transform: translate3d(0, calc(var(--float) * -.5), 0); }
  50%    { transform: translate3d(0, calc(var(--float) * .5), 0); }
}
@keyframes crystalTilt{
  0%,100%{ transform: rotate(calc(var(--tilt) * -1)); }
  50%    { transform: rotate(var(--tilt)); }
}
/* Energy curve, sampled every 0.5s from a monotone cubic through
   0s 30% · 2s 45% · 4s 80% · 5s 100% · 5.5s 90% · 7s 60% · 9s 30%.
   Played with linear timing so the curve's own shape is the easing — no
   per-keyframe ease stalls, no overshoot, and a flat, seamless loop point. */
@keyframes energyAura{
  0%{opacity:.300} 5.56%{opacity:.312} 11.11%{opacity:.344} 16.67%{opacity:.391} 22.22%{opacity:.450}
  27.78%{opacity:.522} 33.33%{opacity:.609} 38.89%{opacity:.704} 44.44%{opacity:.800} 50%{opacity:.923}
  55.56%{opacity:1} 61.11%{opacity:.900} 66.67%{opacity:.797} 72.22%{opacity:.694} 77.78%{opacity:.600}
  83.33%{opacity:.504} 88.89%{opacity:.406} 94.44%{opacity:.330} 100%{opacity:.300}
}
@keyframes energyBacklight{       /* same curve mapped to .5 → 1 */
  0%{opacity:.500} 5.56%{opacity:.508} 11.11%{opacity:.531} 16.67%{opacity:.565} 22.22%{opacity:.607}
  27.78%{opacity:.659} 33.33%{opacity:.721} 38.89%{opacity:.789} 44.44%{opacity:.857} 50%{opacity:.945}
  55.56%{opacity:1} 61.11%{opacity:.929} 66.67%{opacity:.855} 72.22%{opacity:.782} 77.78%{opacity:.714}
  83.33%{opacity:.646} 88.89%{opacity:.576} 94.44%{opacity:.522} 100%{opacity:.500}
}
@keyframes energyGround{          /* same curve mapped to .55 → 1 */
  0%{opacity:.550} 5.56%{opacity:.558} 11.11%{opacity:.578} 16.67%{opacity:.609} 22.22%{opacity:.646}
  27.78%{opacity:.693} 33.33%{opacity:.749} 38.89%{opacity:.810} 44.44%{opacity:.871} 50%{opacity:.951}
  55.56%{opacity:1} 61.11%{opacity:.936} 66.67%{opacity:.870} 72.22%{opacity:.804} 77.78%{opacity:.743}
  83.33%{opacity:.681} 88.89%{opacity:.618} 94.44%{opacity:.570} 100%{opacity:.550}
}
@keyframes energyCore{            /* same curve mapped to brightness 1 → 1.05 */
  0%{filter:brightness(1)} 5.56%{filter:brightness(1.001)} 11.11%{filter:brightness(1.003)} 16.67%{filter:brightness(1.007)}
  22.22%{filter:brightness(1.011)} 27.78%{filter:brightness(1.016)} 33.33%{filter:brightness(1.022)} 38.89%{filter:brightness(1.029)}
  44.44%{filter:brightness(1.036)} 50%{filter:brightness(1.045)} 55.56%{filter:brightness(1.05)} 61.11%{filter:brightness(1.043)}
  66.67%{filter:brightness(1.036)} 72.22%{filter:brightness(1.028)} 77.78%{filter:brightness(1.021)} 83.33%{filter:brightness(1.015)}
  88.89%{filter:brightness(1.008)} 94.44%{filter:brightness(1.002)} 100%{filter:brightness(1)}
}
@keyframes fxDriftA{
  from{ transform: translate3d(-4px, 3px, 0); }
  to  { transform: translate3d(5px, -6px, 0); }
}
@keyframes fxDriftB{
  from{ transform: translate3d(4px, 4px, 0); }
  to  { transform: translate3d(-5px, -7px, 0); }
}
@keyframes fxFlicker{
  0%,100%{ opacity:1; }
  40%    { opacity:.72; }
  70%    { opacity:.92; }
}
@keyframes mote{
  0%  { opacity:0; transform: translate3d(0, 0, 0); }
  30% { opacity:.85; }
  70% { opacity:.5; }
  100%{ opacity:0; transform: translate3d(12px, -46px, 0); }
}

/* Stop spending frames once the hero has scrolled away */
.hero.is-offscreen .hero-scene *{ animation-play-state: paused; }

/* ============================================
   HeroContent
============================================ */
.hero-inner{ position:relative; z-index:20; max-width: min(760px, 46vw); }

.hero .eyebrow{ font-family: var(--font-display); font-size:.78rem; letter-spacing:.24em; font-weight:500; margin-bottom: 30px; }

.hero-title{
  font-family: var(--font-display); font-weight:700;
  font-size: clamp(3rem, 6.6vw, 6rem);
  line-height: 1.02; letter-spacing:-0.01em;
  margin: 0 0 30px;
  text-shadow: 0 2px 30px rgba(0,0,0,.45);
}
.reveal-line{ display:block; overflow:hidden; }
.reveal-line > span{ display:block; }

.hero-sub{
  font-size: clamp(1rem, 1.3vw, 1.18rem); color: rgba(244,244,239,.78);
  font-weight:400; line-height:1.7; margin-bottom: 44px; max-width: 460px;
}

.hero-actions{ display:flex; gap:16px; }

/* ============================================
   Responsive
============================================ */
@media (max-width: 1080px){
  .hero{
    --stage-x: 58%;
    --crystal-x: 71%;
    --crystal-y: 60%;
    --crystal-w: 46%;
    --float: 5px;
    --tilt: .4deg;
  }
  .hero-inner{ max-width: min(560px, 52vw); }
}

/* Mobile: content sits in the empty sky; the landscape is a fixed-height band
   anchored to the bottom so the crystal floats over the valley beneath the copy. */
@media (max-width: 640px){
  .hero{
    --stage-x: 64%;
    --crystal-x: 58.5%;           /* visible band is ~40–77% of the stage at this width */
    --crystal-y: 60%;
    --crystal-w: 42%;
    --float: 4px;
    --tilt: .3deg;
    --calm-mask: none;
    min-height: max(100svh, 800px);
    justify-content:flex-start;
    padding-top: 108px;
  }
  .hero-stage{
    width:auto; height: 560px;
    top:auto; bottom:0;
    transform: translateX(calc(var(--stage-x) * -1));
  }
  .plane-3{ -webkit-mask-image:none; mask-image:none; }
  .plane-5{   /* the band has a top edge now; don't let particles stop on it */
    -webkit-mask-image: linear-gradient(180deg, transparent, #000 22%);
            mask-image: linear-gradient(180deg, transparent, #000 22%);
  }
  .fx-left{ display:none; }
  .fx-right{ -webkit-mask-image:none; mask-image:none; opacity:.7; }
  .fx-motes i:nth-child(n+4){ display:none; }
  .hero-inner{ max-width:100%; }
  .hero .eyebrow{ letter-spacing:.1em; font-size:.6rem; margin-bottom:20px; max-width:100%; }
  .eyebrow .rule{ width:24px; margin-right:12px; }
  .hero-title{ margin-bottom:22px; }
  .hero-sub{ margin-bottom:28px; }
  .btn-lg{ padding: 15px 26px; }
  .hero-shade{ background: linear-gradient(0deg, var(--bg) 0%, rgba(10,10,10,0) 10%); }
}

@media (prefers-reduced-motion: reduce){
  .hero-scene, .hero-scene *{ animation: none !important; transition: none !important; }
  .hero.has-scene-js .hero-scene{ opacity:1; }
  .fx-motes{ display:none; }
}
