/* ---------------------------------------------------------------------------
   Hero animation — draws the centrepiece instead of showing it as a still.
   Everything is namespaced `orbit-` and scoped under .orbit-hero, so nothing
   here can reach the rest of the site.

   .orbit-hero carries the exact box the <img> had: 980 x 470, pinned left and
   vertically centred in the 560px hero stage. The section's height is unchanged,
   which matters because js/site.js measures [data-hero-ref] to swap the nav.
   --------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------
   Mobile layout correction. Pre-existing and not animation related, but it has
   to be fixed here for the hero to be usable at all below ~1023px.

   The hero section is a grid with no explicit columns, so its implicit column
   sizes to its widest child. The centrepiece canvas is 980px wide in layout, so
   the column became 980px, and every centred child — eyebrow, headline, lede,
   CTA — centred on x=510 inside a 390px viewport. The section's overflow:hidden
   hid the result rather than fixing it. site-responsive.css scales the canvas
   with `transform`, which is purely visual and never shrinks the track.

   Capping the column at the container width restores centring for everything,
   and leaves the existing transform-scale steps to do their job.
   --------------------------------------------------------------------------- */
@media (max-width: 1023px){
  section[data-hero-ref]{ grid-template-columns: minmax(0, 1fr); }
}

/* ---------------------------------------------------------------------------
   Below 720px, stop scaling the 980px canvas and re-flow it instead.

   The transform-scale steps take the canvas to 36%, which puts the engraving's
   half-pixel strokes below one device pixel and the card type at ~3px. The
   composition survives as a shape but stops being legible. Re-flowing keeps
   both the planet and the cards at a readable size, stacked.
   --------------------------------------------------------------------------- */
@media (max-width: 719px){
  section[data-hero-ref] > div[style*="980px"]{
    transform: none !important;
    width: 100% !important;
    height: auto !important;
    margin-top: 4px !important;
    /* the lede sat flush against the last card with no breathing room */
    margin-bottom: 34px !important;
    display: grid;
    gap: 14px;
  }
  /* Stacked, the composition should read total first, then what it decomposes
     into — so the answer card comes up under the planet and the two supporting
     cards follow. DOM order is left-pair then answer, which only suits the
     desktop arrangement. */
  section[data-hero-ref] .orbit-hero{ order: 0 }
  section[data-hero-ref] > div[style*="980px"] > .orbit-card{ order: 1 }
  section[data-hero-ref] > div[style*="980px"] > div:not(.orbit-hero):not(.orbit-card){ order: 2 }
  /* the planet becomes a fluid block that keeps the artwork's aspect */
  section[data-hero-ref] .orbit-hero{
    /* relative, not static: the svg inside is absolutely positioned against this
       box, so it must stay a containing block or the planet escapes it */
    position: relative !important;
    overflow: hidden;
    /* the desktop rule pins this with top:50%; left:0 — as a grid item that would
       push it half its own row height down */
    top: auto !important;
    left: auto !important;
    transform: none !important;
    width: 100% !important;
    height: auto !important;
    aspect-ratio: 1 / 0.86;   /* taller than the artwork, so `slice` crops its empty margins */
  }
  /* every card group returns to normal flow at full width */
  section[data-hero-ref] > div[style*="980px"] > div:not(.orbit-hero){
    position: static !important;
    transform: none !important;
    width: 100% !important;
    left: auto !important;
    right: auto !important;
    top: auto !important;
  }
  /* the connector stubs that reach from a card toward the planet have nothing
     to point at once the composition is stacked, and trail off the edge */
  section[data-hero-ref] > div[style*="980px"] span[style*="left:100%"],
  section[data-hero-ref] > div[style*="980px"] span[style*="right:100%"]{
    display: none !important;
  }
  /* grid and flex children default to min-width:auto, so a card refuses to
     shrink below its longest unbreakable row and pushes past the screen edge
     on narrow phones. Let them shrink, and let the long mono strings wrap. */
  section[data-hero-ref] > div[style*="980px"],
  section[data-hero-ref] > div[style*="980px"] *{
    min-width: 0 !important;
  }
  section[data-hero-ref] > div[style*="980px"] .orbit-card{
    overflow-wrap: anywhere;
  }
}

/* Below ~360px a card's label and its figure stop fitting on one line and
   collide, because the rows are space-between with nowhere to go. Letting them
   wrap puts the figure underneath instead of on top of the label. */
@media (max-width: 359px){
  section[data-hero-ref] > div[style*="980px"] [style*="display:flex"]{
    flex-wrap: wrap;
    gap: 2px 10px;
  }
  /* with wrap on, a row packs left instead of spreading; keep the figure on the
     right edge where it reads as a value rather than as more label text */
  section[data-hero-ref] > div[style*="980px"] [style*="display:flex"] > *:last-child{
    margin-left: auto;
  }
  section[data-hero-ref] > div[style*="980px"] [style*="grid-template-columns"]{
    grid-template-columns: 1fr !important;
    row-gap: 2px;
  }
}

/* ---------------------------------------------------------------------------
   The answer card carried more vertical padding than it needed, standing ~15%
   taller than its content. Trimmed to 130px from 155px (-16%) by tightening the
   shell padding and the two internal gaps, leaving every type size untouched.

   Targeted structurally: this is the only .orbit-card that is a direct child of
   the stage — the two supporting cards sit inside a layout wrapper — so no
   text-matching or index guessing is involved.
   --------------------------------------------------------------------------- */
section[data-hero-ref] > div[style*="980px"] > .orbit-card > div{
  padding: 12px 20px 13px !important;
  row-gap: 10px !important;
}
section[data-hero-ref] > div[style*="980px"] > .orbit-card > div > div:first-child{
  padding-bottom: 8px !important;
}
section[data-hero-ref] > div[style*="980px"] > .orbit-card > div > div:last-child{
  row-gap: 8px !important;
}

.orbit-hero{
  --orbit-bg: var(--navy-deepest, #030f1a);  /* fills the planet body — must match the surface behind it */
  --orbit-ink: 224 242 250;                  /* ice, channels only, so the art can mix its own alphas */
  --orbit-faint: 142 200 224;                /* ice-faint, channels only */

  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 980px;
  height: 470px;
  display: block;
}
.orbit-hero > svg,
.orbit-hero > .orbit-hero__poster{
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}

/* stroke-drawing: each path reveals along its own length */
.orbit-draw{
  stroke-dasharray: var(--orbit-len);
  stroke-dashoffset: var(--orbit-len);
  animation: orbit-draw var(--orbit-dur, 1s) cubic-bezier(.3,.6,.3,1) forwards;
  animation-delay: var(--orbit-del, 0s);
}
@keyframes orbit-draw{ to{ stroke-dashoffset: 0 } }

/* the settle: one gentle push forward once the whole system has drawn,
   then back to rest. 2% about the planet's own centre. */
.orbit-settle{
  transform-box: view-box;
  transform-origin: 490px 246px;
  animation: orbit-settle .72s cubic-bezier(.22,.61,.36,1) 3.5s both;
}
@keyframes orbit-settle{
  0%   { transform: scale(1) }
  45%  { transform: scale(1.02) }
  100% { transform: scale(1) }
}

/* the drift: a slow, continuous rise and fall, starting once the settle has
   finished. On its own group and using `translate` rather than `transform`, so
   it composes with the settle's scale instead of overriding it. */
.orbit-hover{
  animation: orbit-hover 6.5s ease-in-out 4.3s infinite;
}
@keyframes orbit-hover{
  0%, 100% { translate: 0 0 }
  50%      { translate: 0 -7px }
}

/* the cards arrive toward the planet: left group from the left, the answer card
   from the right, staggered. `translate` again, so a card's own inline
   transform (several are centred with translateY(-50%)) is left untouched. */
.orbit-card{
  opacity: 0;
  translate: var(--orbit-from-x, 0) 12px;
  animation: orbit-card-in .72s cubic-bezier(.22,.61,.36,1) forwards;
  animation-delay: var(--orbit-card-del, 0s);
}
@keyframes orbit-card-in{
  to { opacity: 1; translate: 0 0 }
}

/* Reduced motion gets the finished drawing immediately — nothing mid-stroke,
   nothing mid-scale. */
@media (prefers-reduced-motion: reduce){
  .orbit-draw{ animation: none; stroke-dashoffset: 0 }
  .orbit-settle{ animation: none !important; transform: none !important }
  /* the drift is continuous, so it is the one thing that must not merely
     finish early — it must never start */
  .orbit-hover{ animation: none !important; translate: none !important }
  .orbit-card{ animation: none !important; opacity: 1 !important; translate: none !important }
}
