/* =========================================================
   HassounCube, atmosphere
   A slow drifting amethyst cloud field behind the whole UI.

   Kept in its own file on purpose: remove the <link> from a page and that
   page loses the clouds with nothing else disturbed. It does not touch, and
   does not replace, the static ambient field on body::before in global.css.
   The two stack: that one is the fixed base wash, this one moves over it.

   Structure expected in the markup, as the first element inside <body>:

     <div class="atmosphere" aria-hidden="true">
       <span class="cloud c1"></span>
       <span class="cloud c2"></span>
       <span class="cloud c3"></span>
     </div>

   Why a container of spans rather than more pseudo-elements: three blobs
   need three independent drift timings, and body only has ::before and
   ::after, one of which is already spoken for.
   ========================================================= */

.atmosphere {
  position: fixed;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
  /* The layer sits behind everything but the base background. Content is
     lifted above it by the existing `body > * { z-index: 1 }` rule, and this
     element is a body child too, so it must stay first in the markup. */
}

.cloud {
  position: absolute;
  display: block;
  border-radius: 50%;
  /* No blur filter: each cloud's radial gradient already fades to fully
     transparent before its edge, so it stays soft. Only transform changes
     per frame, never the paint. */
  will-change: transform;
}

/* Film grain over the cloud field. Flat digital gradients band into visible
   steps on many screens, especially the deep violets used here; a faint
   static noise breaks that up and gives the dark a little texture. Static,
   so it costs one paint, not one per frame. */
.atmosphere::after {
  content: "";
  position: absolute;
  inset: 0;
  opacity: 0.07;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1  0 0 0 0 1  0 0 0 0 1  0 0 0 0.9 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 180px 180px;
}

/* Top right, the brightest mass, drifting down and left */
.cloud.c1 {
  width: 46vw;
  height: 46vw;
  min-width: 380px;
  min-height: 380px;
  top: -8vw;
  right: -4vw;
  background: radial-gradient(circle, rgba(131, 11, 238, 0.30), rgba(131, 11, 238, 0) 68%);
  animation: driftOne 34s var(--ease) infinite alternate;
}

/* Left flank, deeper violet, slower and wider travel */
.cloud.c2 {
  width: 38vw;
  height: 38vw;
  min-width: 320px;
  min-height: 320px;
  top: 14vh;
  left: -6vw;
  background: radial-gradient(circle, rgba(139, 51, 224, 0.24), rgba(139, 51, 224, 0) 70%);
  animation: driftTwo 46s var(--ease) infinite alternate;
}

/* Low centre, the faint one that keeps the fold from going flat black */
.cloud.c3 {
  width: 52vw;
  height: 52vw;
  min-width: 420px;
  min-height: 420px;
  bottom: -16vw;
  left: 22vw;
  background: radial-gradient(circle, rgba(173, 79, 255, 0.16), rgba(173, 79, 255, 0) 70%);
  animation: driftThree 40s var(--ease) infinite alternate;
}

/* Translate and scale only. Animating width, top or filter would repaint the
   blur every frame, which is what makes this kind of effect stutter. */
@keyframes driftOne {
  from { transform: translate3d(0, 0, 0) scale(1); }
  to   { transform: translate3d(-8vw, 10vh, 0) scale(1.14); }
}
@keyframes driftTwo {
  from { transform: translate3d(0, 0, 0) scale(1.08); }
  to   { transform: translate3d(9vw, -8vh, 0) scale(1); }
}
@keyframes driftThree {
  from { transform: translate3d(0, 0, 0) scale(1); }
  to   { transform: translate3d(-10vw, -6vh, 0) scale(1.2); }
}

/* Phones: no clouds at all. The scene cube (css/scene-cube.css) carries the
   depth there, and three large blurred layers were the single most costly
   paint on an iPhone for an effect that mostly read as purple haze. The
   grain above stays. */
@media (max-width: 700px) {
  .cloud { display: none; }
}

/* Matches the rest of the site: motion is an enhancement, never a fixture.
   The clouds stay, they simply stop moving. */
@media (prefers-reduced-motion: reduce) {
  .cloud { animation: none; }
}
