/* Breacer — Aurora
 * ============================================================================
 * Light that comes from BELOW the edge, in multiple colors, covered by a
 * curved horizon.
 *
 * Replaces the old .mood-wash: one ellipse from above, one color, no shape.
 * Three things make the difference:
 *
 *   1. The light source sits OUTSIDE the frame, below the bottom edge. You
 *      only see the top of the falloff curve, which makes it read as light
 *      coming from somewhere instead of a smudge stuck on the screen.
 *   2. Three colors SIDE BY SIDE, summed with screen so they genuinely
 *      blend in the overlap. That blending is why it reads as one source.
 *   3. A curved horizon covers the light at the bottom. That is what turns
 *      a gradient into a shape: without the curve you get a blurry smear,
 *      with the curve it gets direction.
 *
 * WHY AT THE BOTTOM
 * Not just aesthetics. The New card on the dashboard ran aground on
 * readability for three rounds because there was light BEHIND the text.
 * Light at the bottom edge and text at the top never meet -- that is a
 * structural fix, not a dimmer.
 *
 * USAGE
 *   <div class="aurora" aria-hidden="true"></div>
 * inside a parent with position:relative and overflow:hidden. Status
 * classes (typing/thinking/problem/matched) are below and match what
 * setMood() already toggles, so the existing wiring stays unchanged.
 */

.aurora,
.mood-wash {
  --aurora-h1: 226;   /* left    */
  --aurora-h2: 226;   /* middle  */
  --aurora-h3: 226;   /* right   */
  --aurora-sat: 85%;
  --aurora-a: 0.30;   /* opacity of the light */
  --aurora-rise: 26%; /* how high the horizon sits */
  --aurora-blur: 44px;
  --aurora-ground: #05060A;
  --aurora-lift: 0px; /* extra vertical offset of the light source */

  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  border-radius: inherit;
  isolation: isolate;
}

/* --- The light -------------------------------------------------------- */
.aurora::before,
.mood-wash::before {
  content: '';
  position: absolute;
  left: -20%;
  right: -20%;
  /* Not too far down: at -30% the bright core of the gradient stayed
     entirely below the edge and you only saw the faint tail. Now the core
     sits just below the horizon, where it belongs. */
  bottom: calc(-14% + var(--aurora-lift));
  height: 72%;
  background:
    radial-gradient(42% 58% at 24% 100%, hsl(var(--aurora-h1) var(--aurora-sat) 60% / var(--aurora-a)) 0%, transparent 72%),
    radial-gradient(38% 52% at 52% 100%, hsl(var(--aurora-h2) var(--aurora-sat) 58% / var(--aurora-a)) 0%, transparent 72%),
    radial-gradient(42% 58% at 79% 100%, hsl(var(--aurora-h3) var(--aurora-sat) 56% / var(--aurora-a)) 0%, transparent 72%);
  /* screen instead of normal: where two colors overlap they add up to a
     third color, exactly like real light. With normal, the top one would
     simply cover the bottom one and you'd see three separate blobs.
     NOTE: plus-lighter does NOT work here -- that is a composite mode that
     only mix-blend-mode accepts, not background-blend-mode. The browser
     silently falls back to 'normal' (measured), so it looks like it's
     working while it does nothing. */
  background-blend-mode: screen;
  filter: blur(var(--aurora-blur));
  transition: background 1.2s ease, filter 1.2s ease;
}

/* --- The horizon ------------------------------------------------------- *
 * A masked plane in the ground color that covers the light at the bottom.
 * The curve sits in the mask (an SVG path), not in a border-radius: that
 * way the line can wave asymmetrically instead of being a symmetric dome.
 * Color comes from a CSS variable and not from the SVG, because a data URI
 * cannot read custom properties.
 */
.aurora::after,
.mood-wash::after {
  content: '';
  position: absolute;
  left: -2%;
  right: -2%;
  bottom: -1px;
  height: var(--aurora-rise);
  background: var(--aurora-ground);
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1200 240' preserveAspectRatio='none'%3E%3Cpath d='M0,240 L0,150 C160,150 230,42 430,42 C650,42 720,176 930,176 C1060,176 1130,150 1200,150 L1200,240 Z' fill='white'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1200 240' preserveAspectRatio='none'%3E%3Cpath d='M0,240 L0,150 C160,150 230,42 430,42 C650,42 720,176 930,176 C1060,176 1130,150 1200,150 L1200,240 Z' fill='white'/%3E%3C/svg%3E");
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  transition: height 1.2s ease;
}

/* --- Statuses -------------------------------------------------------- *
 * Same classes that setMood() already toggles. Standby is deliberately ONE
 * color with a low horizon: flat and still. The more that's happening, the
 * more colors and the higher the horizon.
 */
.aurora.typing,
.mood-wash.typing {
  --aurora-h1: 38; --aurora-h2: 32; --aurora-h3: 26;
  --aurora-a: 0.34; --aurora-rise: 29%;
}

/* The state from the reference: violet, amber and green side by side, a
   high wavy horizon, slowly moving light. */
.aurora.thinking,
.mood-wash.thinking {
  --aurora-h1: 275; --aurora-h2: 42; --aurora-h3: 150;
  --aurora-sat: 92%; --aurora-a: 0.46; --aurora-rise: 34%;
}
.aurora.thinking::before,
.mood-wash.thinking::before {
  animation: auroraDrift 7s ease-in-out infinite;
}

.aurora.problem,
.mood-wash.problem {
  --aurora-h1: 12; --aurora-h2: 5; --aurora-h3: 30;
  --aurora-a: 0.34; --aurora-rise: 20%;
}

.aurora.matched,
.mood-wash.matched {
  --aurora-h1: 150; --aurora-h2: 145; --aurora-h3: 165;
  --aurora-sat: 80%; --aurora-a: 0.50; --aurora-rise: 32%;
}
.aurora.matched::before,
.mood-wash.matched::before {
  animation: auroraFlash 1.6s ease-out forwards;
}

/* The Watchdog speaks its own status vocabulary (warning/critical/
   recovered) because that's about system health, not about a trigger.
   Those statuses get their aurora translation here, so the Watchdog uses
   the same mood layer as the rest of the brand instead of an eleventh
   system of its own. The JS that toggles them is unchanged. */
.aurora.warning,
.mood-wash.warning {
  --aurora-h1: 42; --aurora-h2: 30; --aurora-h3: 50;
  --aurora-sat: 95%; --aurora-a: 0.48; --aurora-rise: 30%;
}
.aurora.critical,
.mood-wash.critical {
  --aurora-h1: 8; --aurora-h2: 0; --aurora-h3: 18;
  --aurora-sat: 95%; --aurora-a: 0.55; --aurora-rise: 24%;
}
.aurora.critical::before,
.mood-wash.critical::before {
  animation: auroraDrift 2.4s ease-in-out infinite;
}
.aurora.recovered,
.mood-wash.recovered {
  --aurora-h1: 150; --aurora-h2: 145; --aurora-h3: 165;
  --aurora-sat: 80%; --aurora-a: 0.55; --aurora-rise: 34%;
}
.aurora.recovered::before,
.mood-wash.recovered::before {
  animation: auroraFlash 1.6s ease-out forwards;
}

@keyframes auroraDrift {
  0%, 100% { transform: translateX(0) scaleY(1); }
  50%      { transform: translateX(3%) scaleY(1.08); }
}
@keyframes auroraFlash {
  0%   { opacity: 0.4; transform: scaleY(0.9); }
  30%  { opacity: 1;   transform: scaleY(1.1); }
  100% { opacity: 1;   transform: scaleY(1); }
}

/* Page-wide variant: fixed to the viewport, behind everything. The
   existing .mood-wash elements on index.html and dashboard.html keep their
   own position/z-index from their page CSS; this rule only makes the
   aurora layers above apply there too. */
.mood-wash {
  position: fixed;
  inset: 0;
  z-index: -2;

  /* Since the mood layers have been reduced to this one (the
     .presence-ring, the .dot-field and the three .liquid-bg blobs have
     been cleaned up), the aurora carries the whole screen alone. The old
     values were tuned for a background where three other things were
     already happening; on its own that was too little -- the top of the
     page turned flat black.
     A bit more opacity and a slightly higher horizon, only in the
     page-wide variant. The card variant (.aurora.on-surface) stays
     restrained: there, text sits closer to the light. */
  --aurora-a: 0.42;
  --aurora-rise: 32%;
  --aurora-blur: 56px;
}
.mood-wash.typing { --aurora-a: 0.46; --aurora-rise: 35%; }
.mood-wash.thinking { --aurora-a: 0.58; --aurora-rise: 40%; }
.mood-wash.matched { --aurora-a: 0.60; --aurora-rise: 38%; }
.mood-wash.problem { --aurora-a: 0.44; --aurora-rise: 26%; }

/* On a card or panel: a bit more subdued than page-wide, because the
   surface is much smaller and the text sits closer. */
.aurora.on-surface {
  --aurora-a: 0.26;
  --aurora-blur: 34px;
  --aurora-rise: 30%;
  --aurora-ground: #0C0E12;
  z-index: 0;
}

@media (prefers-reduced-motion: reduce) {
  .aurora::before,
  .mood-wash::before,
  .aurora.thinking::before,
  .mood-wash.thinking::before,
  .aurora.matched::before,
  .mood-wash.matched::before {
    animation: none !important;
  }
}
