/* Living hero art. The sky is split into layers (stars, twinkling stars, a seamless cloud band, the
   back tree row): the clouds flow endlessly to the left, about forty stars breathe, each on its own
   slow cycle, and the front trees sway. Nothing smears the pixel art: the cloud strip is moved by
   script in whole device pixels, the stars only change opacity, and the trees are redrawn per screen
   pixel from the nearest art pixel. */

/* Sky: same box as the old single image (100px taller than the section), cropped like object-fit
   cover around the centre */
.hm-sky {
  position: absolute;
  z-index: 10;
  left: 0;
  top: 0;
  width: 100%;
  height: calc(100% + 100px);
  overflow: hidden;
  container-type: size;
  background: #000;
  pointer-events: none;
  will-change: transform;
}
.hm-cover {
  position: absolute;
  left: 50%;
  top: 50%;
  width: max(100cqw, 100cqh);
  aspect-ratio: 1 / 1;
  transform: translate(-50%, -50%);
}
.hm-cover > img,
.hm-pines > img {
  position: absolute;
  top: 0;
  left: 0;
  display: block;
  width: 100%;
  height: 100%;
  max-width: none;
  image-rendering: pixelated;
  user-select: none;
  -webkit-user-select: none;
  -webkit-user-drag: none;
}

/* Stars: one span per star pixel (one art pixel square). Each star fades to its own dimmest level
   and back over its own duration, starting at its own point, so no two move together. */
.hm-stars {
  position: absolute;
  inset: 0;
}
.hm-stars > span {
  position: absolute;
  width: calc(100% / 916);
  height: calc(100% / 916);
  animation: hm-star var(--d, 5s) ease-in-out var(--w, 0s) infinite;
}
@keyframes hm-star {
  0%, 100% { opacity: 1; }
  50% { opacity: var(--lo, 0.3); }
}

/* Clouds: an endless band that flows left. The strip is two copies of a seamless 1600-art-pixel tile
   (3200 wide for the 916-wide sky); the page script slides it one tile every four minutes and
   rounds every position to a whole device pixel, so the dither never shimmers. Without the script
   it simply stands still. */
.hm-cover > .hm-flow {
  width: calc(100% * 3200 / 916);
  will-change: transform;
}
/* Below 768 there is no monitor and the hero is taller than it is wide, so the art square is exactly
   the sky's height and the band (cloud tops from 32% of the art down) would sit behind the white
   intro text. There the band alone drops so its highest tops land about 200px above the hero's
   bottom (the sky box runs 100px past it), just behind the last button, with the live feed link on
   the clouds, as in the reference. A static offset in whole pixels; the script still owns the
   sideways motion through transform. */
@media (max-width: 767px) {
  .hm-cover > .hm-flow {
    translate: 0 calc(68cqh - 300px);
    translate: 0 round(calc(68cqh - 300px), 1px);
  }
}

/* Front pines: same box as before (the page width, square, pushed 400px below the section). The
   page script redraws the trees with WebGL so they bend smoothly from their bases (crisp pixels, smooth
   motion) on a canvas over art rows 400-990; .still is the original picture, shown until that starts
   and whenever it can't (no WebGL, reduced motion) */
.hm-pines {
  position: absolute;
  z-index: 40;
  left: 0;
  bottom: -400px;
  width: 100%;
  aspect-ratio: 1 / 1;
  pointer-events: none;
  will-change: transform;
}
.hm-pines > canvas {
  position: absolute;
  left: 0;
  top: calc(100% * 400 / 991);
  display: block;
  width: 100%;
  height: calc(100% * 591 / 991);
}
.hm-pines.gl-on > .still,
.hm-pines:not(.gl-on) > canvas {
  visibility: hidden;
}

/* Two characters (Hero.dc.html moves them and handles the pokes). Sprites are Higgsfield art snapped
   to the palette; --s is CSS px per art pixel, --f the pose. The astronaut is drawn at 2x from 1024
   and 1x below; the lead at 1.5x, small enough that his flag stays clear of the buttons above.
   The astronaut: a 40x62 cell, five poses (float, wave, startled, upside down, thumbs up). */
.hm-astro-wrap {
  position: absolute;
  z-index: 25;
  inset: 0;
  pointer-events: none;
}
.hm-astro {
  --s: 1;
  --f: 0;
  position: absolute;
  left: 0;
  top: 0;
  display: block;
  width: calc(40px * var(--s));
  height: calc(62px * var(--s));
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  pointer-events: auto;
  will-change: transform;
}
@media (min-width: 1024px) {
  .hm-astro { --s: 2; }
}
.hm-astro:focus-visible,
.hm-lead:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.hm-astro-bob {
  display: block;
  width: 100%;
  height: 100%;
  animation: hm-bob 3.6s steps(8, jump-none) infinite alternate;
}
.hm-astro-sprite {
  display: block;
  width: 100%;
  height: 100%;
  background: url(../assets/863c8bf5074c48c0c0ca9acdba1ddca8.png) 0 0 / calc(200px * var(--s)) calc(62px * var(--s)) no-repeat;
  background-position-x: calc(-40px * var(--s) * var(--f));
  image-rendering: pixelated;
}
@keyframes hm-bob {
  from { transform: translateY(0); }
  to { transform: translateY(-7px); }
}
.hm-astro.is-hop .hm-astro-sprite {
  animation: hm-hop 0.6s steps(6, jump-none);
}
@keyframes hm-hop {
  50% { transform: translateY(-14px); }
}
.hm-astro.is-spin .hm-astro-sprite {
  animation: hm-spin 0.9s steps(8, jump-none);
}
@keyframes hm-spin {
  to { transform: rotate(360deg); }
}

/* The squad lead on the monitor's top edge: a 55x65 cell, six poses (stand, wave, tipping back,
   hanging by the hands, climbing over, dusting off) and a 27x15 flag of three frames flapping on his
   pole. The clip box ends exactly at the monitor's top edge, so when he drops he goes behind it. */
.hm-lead-clip {
  --s: 1.5;
  position: absolute;
  z-index: 3;
  left: 66%;
  bottom: 100%;
  width: calc(100px * var(--s));
  height: calc(90px * var(--s));
  overflow: hidden;
  pointer-events: none;
}
.hm-lead {
  --f: 0;
  position: absolute;
  left: calc(30px * var(--s));
  bottom: 0;
  width: calc(55px * var(--s));
  height: calc(65px * var(--s));
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  pointer-events: auto;
  transform-origin: 50% 100%;
}
.hm-lead-sprite {
  position: absolute;
  inset: 0;
  background: url(../assets/0de5b628018def93616ba09f082b0e95.png) 0 0 / calc(330px * var(--s)) calc(65px * var(--s)) no-repeat;
  background-position-x: calc(-55px * var(--s) * var(--f));
  image-rendering: pixelated;
}
.hm-lead-flag {
  position: absolute;
  left: calc(-21px * var(--s));
  top: calc(4px * var(--s));
  width: calc(27px * var(--s));
  height: calc(15px * var(--s));
  background: url(../assets/95b4059ef444582c820dac6a5983a0bd.png) 0 0 / calc(81px * var(--s)) calc(15px * var(--s)) no-repeat;
  image-rendering: pixelated;
  animation: hm-flap 0.66s steps(3) infinite;
}
@keyframes hm-flap {
  to { background-position-x: calc(-81px * var(--s)); }
}
.hm-lead.is-busy .hm-lead-flag {
  display: none;
}

/* Reduced motion: the still picture */
@media (prefers-reduced-motion: reduce) {
  .hm-stars > span,
  .hm-astro-bob,
  .hm-lead-flag {
    animation: none;
  }
}

/* the astronaut poked ten times drifts off (into the top right) and is brought back by a rescue */
.hm-astro-wrap {
  transition: translate 5s cubic-bezier(0.4, 0, 0.6, 1);
}
.hm-astro-wrap.is-adrift {
  translate: 70vw -90vh;
}
@media (prefers-reduced-motion: reduce) {
  .hm-astro-wrap { transition: none; }
}
