/* concepts/baby-zen/app/css/hero.css
   ---------------------------------------------------------------------------
   The hero: moon, baby, glow, reflection and the nine sound rings.

   The artwork lives in a 340 x 256 pt stage — the rect MALINGER.md measured out
   of Start.png at x 27–367, y 174–430 — and everything inside it is placed as a
   percentage of that stage, so the hero moves as one piece. The stage hangs from
   the top of the slot main-screen.css gives us and is centred horizontally: the
   slot absorbs the column's slack, and that slack belongs below the moon, not
   above it. The ring centre sits 136 pt down from the stage top; js/ui/hero.js
   and dev/keyhero.mjs work from the same numbers.

   Only transform and opacity animate. This runs on a phone at 3 a.m. with the
   screen dimmed — a filter or box-shadow animation here would cost real battery
   for something nobody is supposed to consciously notice.
   --------------------------------------------------------------------------- */

.bz-hero {
  --hero-level: 0;
  /* The arcs, sampled off the fasit and written as the mixes of brand tokens
     they actually are. The left set sits over the teal side of the aurora and
     reads cooler there; the right set is the violet one. */
  --hero-ring-l: color-mix(in srgb, var(--violet) 30%, var(--ink) 70%);
  --hero-ring-r: color-mix(in srgb, var(--violet) 36%, var(--ink) 64%);

  position: relative;

  /* The hero slot's top edge lands a few points above the y 174 that
     MALINGER.md measured the artwork's rect at — the fixed rows above it in
     main-screen.css round down. The stage sits on the measured rect rather
     than on the slot, and this is the whole of that correction: if the column
     above ever moves, this is the one number to retune or retire. */
  --hero-slot-nudge: 5px;
}

/* One element breathes, so the moon and its rings stay locked together. */
.bz-hero-stage {
  position: absolute;
  top: var(--hero-slot-nudge);
  left: 50%;
  width: 340px;
  height: 256px;
  margin-left: -170px;
  transform-origin: 50% 53.125%;      /* the ring centre, 136 / 256 */
  animation: bz-hero-breathe var(--dur-breath, 4s) var(--ease) infinite alternate;
  will-change: transform;
}

/* ── The artwork ──────────────────────────────────────────────────────────
   Numbers straight out of `node dev/keyhero.mjs`; re-key and paste if the
   source illustration is ever re-exported. */
.bz-hero-moon {
  position: absolute;
  left: 13.74%;
  top: -0.13%;
  width: 64.90%;
  height: 96.34%;
  user-select: none;
  -webkit-user-drag: none;
  /* The grade — saturation and brightness down to the mockup's dusk — is baked
     into the PNG by dev/keyhero.mjs rather than done here. Same picture either
     way, but the element under it breathes, and a saturate()/brightness() pass
     is work the compositor redoes as it does. Keep exactly one of the two, and
     keep the cheap one; the keyer prints the numbers it used.

     What stays is the violet bleed the artwork throws onto the sky around it.
     That one is genuinely additive: it is light outside the cut-out, so no
     amount of re-keying can put it in the PNG. */
  filter:
    drop-shadow(0 0 26px rgba(124, 92, 232, 0.28))
    drop-shadow(0 0 60px rgba(88, 108, 232, 0.16));
}

/* ── The rings ────────────────────────────────────────────────────────────
   Drawn behind the moon, which is how the artwork has them: the inner two arcs
   are hidden by the crescent and only show through its halo. */
.bz-hero-rings {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}

.bz-hero-ring {
  fill: none;
  stroke-linecap: round;
  transform-box: view-box;
  transform-origin: 172.5px 136px;
}

.bz-hero-ringset {
  transform-box: view-box;
  transform-origin: 172.5px 136px;
  transition: transform var(--dur-ui) var(--ease), opacity var(--dur-ui) var(--ease);
}

/* ── The warm glow the baby gets while we are soothing ────────────────────── */
.bz-hero-warm {
  position: absolute;
  left: 35.7%;
  top: 33.6%;
  width: 35.3%;
  height: 46.9%;
  border-radius: 50%;
  background: radial-gradient(closest-side, var(--warm-baby) 0%, rgba(244, 201, 164, 0) 72%);
  opacity: 0;
  mix-blend-mode: screen;
  transition: opacity 1.6s var(--ease);
  pointer-events: none;
}

/* ── Phases ───────────────────────────────────────────────────────────────
   DESIGN-SPEC kap. 2, row 5. Idle is a breath you are not supposed to see;
   listening sends a slow swell outward through the arcs; soothing pulls them
   in, softens them, and warms the light on the baby. */

/* Listening: a wave that starts at the moon and travels out. The per-ring
   delay is negative so every arc is already mid-cycle on the first frame —
   nothing "starts" when the session does, it was always breathing. */
.bz-hero[data-phase='listening'] .bz-hero-ring {
  animation: bz-hero-pulse 3.4s var(--ease) infinite;
  animation-delay: calc(var(--i) * -0.26s);
}

/* Honest UI: the arcs only reach full strength when the microphone is actually
   hearing something. A dead-quiet room leaves them visibly dimmer. */
.bz-hero[data-phase='listening'] .bz-hero-ringset {
  opacity: calc(0.52 + 0.48 * var(--hero-level));
}

.bz-hero[data-phase='soothing'] .bz-hero-ringset {
  transform: scale(0.9);
  opacity: 0.6;
}
.bz-hero[data-phase='soothing'] .bz-hero-ring {
  animation: bz-hero-settle 5.5s var(--ease) infinite;
  animation-delay: calc(var(--i) * -0.4s);
}
.bz-hero[data-phase='soothing'] .bz-hero-warm { opacity: 0.42; }

.bz-hero[data-phase='fading-out'] .bz-hero-ringset {
  transform: scale(1.04);
  opacity: 0.28;
}
.bz-hero[data-phase='fading-out'] .bz-hero-warm { opacity: 0.16; }

/* ── Keyframes ────────────────────────────────────────────────────────────
   Frame 0 is always the resting state, because ?anim=0 (tokens.css) parks
   every animation on its first frame for the fasit renders. */
@keyframes bz-hero-breathe {
  from { transform: scale(1); }
  to   { transform: scale(1.015); }
}

@keyframes bz-hero-pulse {
  0%   { transform: scale(1);     opacity: 1; }
  45%  { transform: scale(1.035); opacity: 0.45; }
  100% { transform: scale(1);     opacity: 1; }
}

@keyframes bz-hero-settle {
  0%   { transform: scale(1);     opacity: 1; }
  50%  { transform: scale(0.985); opacity: 0.7; }
  100% { transform: scale(1);     opacity: 1; }
}

/* Ambient motion off: park everything on the resting frame, keep the looks.
   tokens.css already pauses animations for html[data-anim='off']; this covers
   the user preference, where "paused" is not enough — nothing should be
   mid-transition either. */
@media (prefers-reduced-motion: reduce) {
  .bz-hero-stage,
  .bz-hero-ring {
    animation: none;
  }
  .bz-hero-ringset,
  .bz-hero-warm {
    transition: none;
  }
}
