/* hero.css - split hero with particle spark. Owner: HERO. */

/* Landing split-hero rules — scoped to :not(.panel) so they do NOT hit the merged
   alethia FRAME hero (id="hero" class="panel hero") on index.html / templates.
   The bare id would otherwise beat the .alethia .hero classes on specificity. */
#hero:not(.panel):not(.hero-variant) {
  position: relative;
  min-height: 100dvh;
  overflow: hidden;
  display: grid;
  /* Orbit left, copy centre, king right. Both point clouds are drawn into the
     one full-bleed canvas at 19% and 82% across (js/particles.js targets()), so
     the two empty side tracks are what reserve room for them — those numbers
     and these must stay in step. */
  /* The centre track is capped by viewport width as well as by rem, or on a
     narrow desktop (~1030px) the 44rem copy column starves the side tracks to
     ~120px and the orbit gets drawn straight over the headline. */
  /* Narrower than it looks like it should be: the king is drawn at its full
     original scale (particles.js figScale) and right-anchored, so the copy
     column has to yield the width the mark needs. */
  grid-template-columns: 1fr minmax(0, min(38rem, 40vw)) 1fr;
  align-items: center;
  padding: clamp(5rem, 12vh, 6rem) var(--gutter) 3rem;
  /* body owns the petrol to ink ground; hero only adds a soft sky glow */
  background: radial-gradient(ellipse 64% 64% at 50% 52%, rgba(94, 154, 200, 0.09), transparent 70%);
}

#hero:not(.panel):not(.hero-variant) > .hero-inner {
  grid-column: 2;
  text-align: center;
}

/* Centred copy: the sub-line keeps its 38ch measure but must centre within the
   track rather than hug the left edge. */
#hero:not(.panel):not(.hero-variant) .hero-sub {
  margin-left: auto;
  margin-right: auto;
}

/* Below the split, the grid collapses to one track and only the king is drawn
   (particles.js drops the orbit on mobile), so the copy sits over the mark. */
@media (max-width: 767px) {
  #hero:not(.panel):not(.hero-variant) {
    grid-template-columns: minmax(0, 1fr);
  }

  #hero:not(.panel):not(.hero-variant) > .hero-inner {
    grid-column: 1;
  }
}

#spark-canvas {
  position: absolute;
  inset: 0;
  /* A canvas is a replaced element: with inset:0 alone it keeps its intrinsic
     300x150 instead of stretching. particles.js resizes the backing store, but
     the CSS box must be told to fill the hero too. */
  width: 100%;
  height: 100%;
  z-index: 0;
  pointer-events: none;
}

.hero-inner {
  position: relative;
  z-index: 1;
  max-width: 41rem;
}

/* In the three-track split the column already sets the measure; a second
   41rem cap here would push the copy off-centre inside its own track. */
#hero:not(.panel):not(.hero-variant) > .hero-inner {
  max-width: 100%;
}

.hero-inner .label {
  font-size: var(--step-label);
  font-weight: var(--w-regular);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--sky);
  margin-bottom: 1.25rem;
}

#hero:not(.panel):not(.hero-variant) h1 {
  font-size: var(--step-hero);
  font-weight: var(--w-light);
  letter-spacing: var(--track-tight);
  line-height: 1.08;
  color: var(--pale);
  margin: 0 0 1.5rem;
  text-wrap: balance;
}

#hero:not(.panel):not(.hero-variant) h1 em.accent {
  font-style: normal;
}

.hero-sub {
  font-size: var(--step-body);
  line-height: 1.6;
  color: var(--steel);
  max-width: 38ch;
  margin: 0 0 2.25rem;
}

.hero-inner .cta {
  display: inline-block;
}

/* .cta-hero: the primary page action, deliberately heavier than the compact
   text-link .nav-cta in the persistent nav (font-family:var(--mono),
   font-size:.72rem, letter-spacing:.14em — see two-world.css). Same font
   family + tracking system as the base .cta pill (font-sans, --w-accent),
   just scaled up so it reads as the one thing to click on the page. */
.hero-inner .cta-hero {
  font-size: 1.15rem;
  padding: 1.05em 2.6em;
  letter-spacing: 0.01em;
}

/* Entry: staggered fade and rise, transform/opacity only */
@media (prefers-reduced-motion: no-preference) {
  .hero-inner > * {
    opacity: 0;
    transform: translateY(20px);
    animation: hero-in 0.9s var(--ease-out) forwards;
  }
  .hero-inner > :nth-child(1) { animation-delay: 0.15s; }
  .hero-inner > :nth-child(2) { animation-delay: 0.3s; }
  .hero-inner > :nth-child(3) { animation-delay: 0.5s; }
  .hero-inner > :nth-child(4) { animation-delay: 0.7s; }
}

@keyframes hero-in {
  to {
    opacity: 1;
    transform: none;
  }
}

/* ============================================================================
   VARIANT HERO — a lighter header echo of the landing hero for the sub-pages.
   Same typographic system (.label / h1 / .hero-sub / .cta) but NO point-cloud
   canvas, NO video, NO chess pieces, and a reduced height so it reads as a page
   header rather than a full-viewport takeover. Themed via [data-theme]: dark uses
   the ink/petrol ground + light text; light uses the pale ground + ink text.
   Selectors use #hero.hero-variant so they beat the #hero:not(.panel):not(.hero-variant) split-hero
   rules above without touching them.
   ============================================================================ */
#hero.hero-variant {
  position: relative;
  min-height: 62vh;
  max-width: none;      /* undo base.css section cage → full-bleed ground */
  margin-inline: 0;
  display: flex;
  align-items: center;
  overflow: hidden;
  padding: clamp(7rem, 16vh, 9rem) var(--gutter) clamp(3rem, 8vh, 4.5rem);
}
#hero.hero-variant[data-theme="dark"] {
  background:
    radial-gradient(ellipse 60% 70% at 72% 46%, rgba(94, 154, 200, 0.10), transparent 68%),
    linear-gradient(180deg, var(--ink), var(--navy) 62%, var(--ink));
}
#hero.hero-variant[data-theme="light"] {
  background:
    radial-gradient(ellipse 62% 72% at 72% 44%, rgba(94, 154, 200, 0.10), transparent 70%),
    linear-gradient(180deg, var(--pale), #DCE7F0 60%, var(--pale));
}

#hero.hero-variant .hero-inner {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 46rem;
}
#hero.hero-variant .label {
  font-size: var(--step-label);
  font-weight: var(--w-regular);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--sky);
  margin-bottom: 1.1rem;
}
#hero.hero-variant h1 {
  font-size: var(--step-hero);
  font-weight: var(--w-light);
  letter-spacing: var(--track-tight);
  line-height: 1.08;
  margin: 0 0 1.35rem;
  text-wrap: balance;
}
#hero.hero-variant[data-theme="dark"] h1 { color: var(--pale); }
#hero.hero-variant[data-theme="light"] h1 { color: var(--ink); }
#hero.hero-variant h1 em.accent {
  font-style: normal;
  font-weight: var(--w-accent);
  color: var(--sky);
}
#hero.hero-variant .hero-sub {
  font-size: var(--step-body);
  line-height: 1.6;
  max-width: 46ch;
  margin: 0 0 2rem;
}
#hero.hero-variant[data-theme="dark"] .hero-sub { color: var(--steel); }
#hero.hero-variant[data-theme="light"] .hero-sub { color: #41586a; }
#hero.hero-variant .cta { display: inline-block; }

@media (max-width: 767px) {
  #hero.hero-variant {
    min-height: 54vh;
    padding-top: 6.5rem;
    text-align: center;
  }
  #hero.hero-variant .hero-inner { margin-inline: auto; }
  #hero.hero-variant .hero-sub { margin-inline: auto; }
}

/* Mobile: centered stack, spark sits behind the copy */
@media (max-width: 767px) {
  #hero:not(.panel):not(.hero-variant) {
    grid-template-columns: 1fr;
    padding-top: 5.5rem;
    padding-bottom: 2.5rem;
    text-align: center;
    background: radial-gradient(ellipse 90% 55% at 50% 56%, rgba(94, 154, 200, 0.09), transparent 72%);
  }
  .hero-inner {
    margin-inline: auto;
  }
  .hero-sub {
    margin-inline: auto;
  }
  .hero-inner .label {
    margin-bottom: 1rem;
  }
  #hero h1 {
    margin-bottom: 1.25rem;
  }
}

/* ============================================================================
   HERO MEDIA — the sector scene as a full-bleed page header.

   The variant hero already escapes the base.css section cage (max-width:none),
   so the picture genuinely spans the viewport rather than the measure. It is
   painted as an absolutely positioned <img> and not a background-image on
   purpose: only a real element can carry srcset/sizes, alt text and
   fetchpriority, and this image is the LCP element on every sector page.

   The class is hero-media-scrim, not hero-scrim: two-world.css already owns
   `.alethia .hero-scrim` with a different gradient at z-index 2. Nothing puts a
   variant hero inside .alethia today, so the collision is latent rather than
   live — which is exactly the kind that surfaces months later as a mystery.

   Two scrims, not one. The horizontal pass keeps the copy column legible over
   whatever the frame happens to put there; the vertical pass darkens under the
   fixed nav and lands the foot of the section back on the page ground, so the
   header dissolves into the body instead of ending on a hard seam.
   ============================================================================ */
#hero.hero-variant.has-media {
  min-height: min(78vh, 760px);
}

#hero.hero-variant .hero-media {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  z-index: 0;
}

#hero.hero-variant .hero-media-scrim {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}

#hero.hero-variant[data-theme="dark"] .hero-media-scrim {
  background:
    linear-gradient(90deg,
      rgba(12, 26, 38, 0.94) 0%,
      rgba(12, 26, 38, 0.86) 34%,
      rgba(12, 26, 38, 0.46) 68%,
      rgba(12, 26, 38, 0.30) 100%),
    linear-gradient(180deg,
      rgba(12, 26, 38, 0.74) 0%,
      rgba(12, 26, 38, 0.08) 32%,
      rgba(12, 26, 38, 0.62) 82%,
      var(--ink) 100%);
}

#hero.hero-variant[data-theme="light"] .hero-media-scrim {
  background:
    linear-gradient(90deg,
      rgba(232, 238, 244, 0.95) 0%,
      rgba(232, 238, 244, 0.88) 36%,
      rgba(232, 238, 244, 0.48) 70%,
      rgba(232, 238, 244, 0.32) 100%),
    linear-gradient(180deg,
      rgba(232, 238, 244, 0.70) 0%,
      rgba(232, 238, 244, 0.10) 32%,
      rgba(232, 238, 244, 0.60) 82%,
      var(--pale) 100%);
}

/* Below the breakpoint the copy centres, so a left-to-right scrim would darken
   the wrong half. Swap to a single vertical pass and let the frame breathe at
   the top, where the picture is doing the work. */
@media (max-width: 767px) {
  #hero.hero-variant.has-media {
    min-height: min(72vh, 620px);
  }
  #hero.hero-variant[data-theme="dark"] .hero-media-scrim {
    background: linear-gradient(180deg,
      rgba(12, 26, 38, 0.78) 0%,
      rgba(12, 26, 38, 0.34) 26%,
      rgba(12, 26, 38, 0.82) 68%,
      var(--ink) 100%);
  }
  #hero.hero-variant[data-theme="light"] .hero-media-scrim {
    background: linear-gradient(180deg,
      rgba(232, 238, 244, 0.74) 0%,
      rgba(232, 238, 244, 0.34) 26%,
      rgba(232, 238, 244, 0.80) 68%,
      var(--pale) 100%);
  }
}

/* A photographic ground needs more separation than a flat one: without this the
   light hairlines of a server rack or a crane read straight through the type. */
#hero.hero-variant.has-media[data-theme="dark"] h1,
#hero.hero-variant.has-media[data-theme="dark"] .label {
  text-shadow: 0 1px 24px rgba(12, 26, 38, 0.55);
}
