
/* ===================================================================
   ATMOSPHERE LAYER
   One opt-in destination field. Coded wash = the durable fallback;
   raster = an optional page-specific image layered above it.
   =================================================================== */
.mx-atmos {
  position: fixed;
  inset: 0;
  z-index: 0;                  /* site convention: decorative fixed layer UNDER z-index:1 content */
  pointer-events: none;
  overflow: hidden;
  /* per-family knobs (overridable inline by the page) */
  --atmos-opacity: 1;          /* wash opacity multiplier */
  --atmos-raster-opacity: 0;   /* 0 until a page supplies an image (see __raster) */
  --atmos-focal: 50% 0%;       /* raster focal / background-position */
  --atmos-grain: 0.05;
  background: var(--mx-bg, #0a0a0a);
  contain: layout paint;       /* paint/layout isolation; NOT `size` (a fixed inset:0 box must keep viewport size) */
}
.mx-atmos > * { position: absolute; inset: 0; }

/* ---- Raster slot: only paints when the page sets --atmos-m / --atmos-d.
   Desktop and mobile carry separate compositions AND separate focal points. ---- */
.mx-atmos__raster {
  background-image: var(--atmos-m, none);     /* mobile-first source */
  background-size: cover;
  background-position: var(--atmos-focal-m, var(--atmos-focal, 50% 0%));  /* mobile focal */
  background-repeat: no-repeat;
  opacity: var(--atmos-raster-opacity);
}
@media (min-width: 760px) {
  .mx-atmos__raster {
    background-image: var(--atmos-d, var(--atmos-m, none));
    background-position: var(--atmos-focal, 50% 0%);                      /* desktop focal */
  }
}

/* ---- Grain: one shared fractal-noise field (replaces per-template copies) ---- */
.mx-atmos__grain {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E");
  opacity: var(--atmos-grain);
  mix-blend-mode: overlay;
}

/* ---- Contrast mask + lower-page edge fade: protects text/cards/nav ----
   Top band kept a touch clearer for the masthead; body + lower page fade to
   near-solid bg so long scrolls never lose card-edge or text contrast. */
.mx-atmos__mask {
  background:
    linear-gradient(180deg,
      rgba(10,10,10,0.30) 0%,
      rgba(10,10,10,0.55) 46%,
      rgba(10,10,10,0.86) 82%,
      var(--mx-bg, #0a0a0a) 100%);
}

/* ===================================================================
   CODED WASHES — the durable per-family fallback.
   Each translates the FROZEN destination direction into restrained
   coded form using the locked --mx-<family> accents. These also render
   beneath any raster, so the family identity survives image failure.
   =================================================================== */

/* CAИON — accumulation: cyan-violet gathering toward form, top-weighted. */
.mx-atmos[data-atmos="canon"] .mx-atmos__wash {
  opacity: var(--atmos-opacity);
  background:
    radial-gradient(1100px 620px at 82% -8%,  color-mix(in srgb, var(--mx-canon) 16%, transparent), transparent 58%),
    radial-gradient(860px 520px at 6% 4%,      rgba(192,132,252,0.07), transparent 56%),
    radial-gradient(960px 760px at 50% 120%,   color-mix(in srgb, var(--mx-canon-deep) 9%, transparent), transparent 60%);
}

/* CAИON lanes (ALBUMS / ARTISTS / TRACKS / ARCHIVE) — SHARED_CHILD: a quieter,
   single-accent teal inheritance, no violet, so a lane reads as CAИON without
   owning a separate image. */
.mx-atmos[data-atmos="canon-lane"] .mx-atmos__wash {
  opacity: var(--atmos-opacity);
  background:
    radial-gradient(1000px 560px at 80% -10%, color-mix(in srgb, var(--mx-canon) 10%, transparent), transparent 60%),
    radial-gradient(720px 520px at 8% 6%,      color-mix(in srgb, var(--mx-canon-deep) 6%, transparent), transparent 58%);
}

/* TRACKS — signal and return: a quiet right-weighted teal depth. On desktop the
   return-depth raster paints above this; on mobile (no raster supplied) this IS the
   field behind the coded return arcs. Right-weighted to match the raster glow. */
.mx-atmos[data-atmos="tracks"] .mx-atmos__wash {
  opacity: var(--atmos-opacity);
  background:
    radial-gradient(900px 520px at 82% 4%,  color-mix(in srgb, var(--mx-canon) 12%, transparent), transparent 60%),
    radial-gradient(520px 380px at 90% 28%, color-mix(in srgb, var(--mx-canon-deep) 8%, transparent), transparent 62%);
}

/* ALBUMS — layered sleeves under glass: a quiet upper-left teal depth. On desktop the
   layered-sleeve raster paints above this; on mobile (no raster supplied) this IS the
   field. Upper-left-weighted to match the sleeve-plane raster. */
.mx-atmos[data-atmos="albums"] .mx-atmos__wash {
  opacity: var(--atmos-opacity);
  background:
    radial-gradient(860px 520px at 14% 6%,  color-mix(in srgb, var(--mx-canon) 12%, transparent), transparent 60%),
    radial-gradient(460px 360px at 8% 22%,  color-mix(in srgb, var(--mx-canon-deep) 8%, transparent), transparent 62%);
}

/* ARTISTS — creative gravity: a soft formless teal mass with quiet orbiting points. On
   desktop the gravity raster paints above this; on mobile (no raster supplied) this IS
   the field. A single soft core upper-left, no rings (distinct from AИNUAL). */
.mx-atmos[data-atmos="artists"] .mx-atmos__wash {
  opacity: var(--atmos-opacity);
  background:
    radial-gradient(720px 560px at 22% 14%, color-mix(in srgb, var(--mx-canon) 13%, transparent), transparent 58%),
    radial-gradient(420px 360px at 16% 26%, color-mix(in srgb, var(--mx-canon-deep) 8%, transparent), transparent 62%);
}

/* AИNUAL — cobalt orbit: a completed year held in one orbital system. */
.mx-atmos[data-atmos="annual"] .mx-atmos__wash {
  opacity: var(--atmos-opacity);
  background:
    radial-gradient(620px 620px at 50% 34%, transparent 41%, color-mix(in srgb, var(--mx-annual) 22%, transparent) 43%, transparent 47%),
    radial-gradient(940px 940px at 50% 34%, transparent 47%, color-mix(in srgb, var(--mx-annual-deep) 14%, transparent) 49%, transparent 53%),
    radial-gradient(1300px 1300px at 50% 34%, transparent 52%, color-mix(in srgb, var(--mx-annual-deep) 8%, transparent) 54%, transparent 58%),
    radial-gradient(720px 520px at 50% 30%, color-mix(in srgb, var(--mx-annual-deep) 16%, transparent), transparent 60%);
}

/* ROTATIOИ — mint flow: the current season moving through the archive. */
.mx-atmos[data-atmos="rotation"] .mx-atmos__wash {
  opacity: var(--atmos-opacity);
  background:
    radial-gradient(1200px 520px at 18% 8%,  color-mix(in srgb, var(--mx-rotation) 15%, transparent), transparent 56%),
    radial-gradient(1100px 700px at 96% 64%, color-mix(in srgb, var(--mx-rotation-deep) 11%, transparent), transparent 60%),
    linear-gradient(118deg, transparent 30%, color-mix(in srgb, var(--mx-rotation) 5%, transparent) 50%, transparent 72%);
}

/* LIVE — sparse magenta pulse: one active signal in darkness. Mostly black.
   Bloom anchored on the radar emblem (upper-left-centre), matching the real page,
   so the coded fallback stays coherent with the raster. */
.mx-atmos[data-atmos="live"] .mx-atmos__wash {
  opacity: var(--atmos-opacity);
  background:
    radial-gradient(620px 620px at 30% 28%, color-mix(in srgb, var(--mx-live) 18%, transparent), transparent 55%),
    radial-gradient(380px 380px at 30% 28%, color-mix(in srgb, var(--mx-live-deep) 14%, transparent), transparent 60%);
}

/* LEDGER — inscription: quiet gold, proof written into a durable system. */
.mx-atmos[data-atmos="ledger"] .mx-atmos__wash {
  opacity: var(--atmos-opacity);
  background:
    radial-gradient(900px 460px at 50% -6%, color-mix(in srgb, var(--mx-ledger) 8%, transparent), transparent 58%),
    repeating-linear-gradient(180deg, transparent 0 38px, rgba(255,225,77,0.018) 38px 39px);
}

/* RECORDS — monument: a single tall held glow. */
.mx-atmos[data-atmos="records"] .mx-atmos__wash {
  opacity: var(--atmos-opacity);
  background:
    radial-gradient(520px 900px at 50% 8%, color-mix(in srgb, var(--mx-records) 12%, transparent), transparent 56%);
}

/* RANKINGS — ordered geometry: exact hierarchy + position. */
.mx-atmos[data-atmos="rankings"] .mx-atmos__wash {
  opacity: var(--atmos-opacity);
  background:
    radial-gradient(1000px 480px at 50% -8%, color-mix(in srgb, var(--mx-rankings) 8%, transparent), transparent 58%),
    repeating-linear-gradient(180deg, transparent 0 30px, rgba(174,224,236,0.022) 30px 31px);
}

/* OBSERVATORY — aquamarine field: listeners as points in a relational map. */
.mx-atmos[data-atmos="observatory"] .mx-atmos__wash {
  opacity: var(--atmos-opacity);
  background:
    radial-gradient(900px 700px at 50% 30%,  color-mix(in srgb, var(--mx-observatory) 12%, transparent), transparent 60%),
    radial-gradient(3px 3px at 22% 36%, color-mix(in srgb, var(--mx-observatory) 55%, transparent), transparent 60%),
    radial-gradient(2px 2px at 38% 62%, color-mix(in srgb, var(--mx-observatory) 40%, transparent), transparent 60%),
    radial-gradient(2.5px 2.5px at 58% 28%, color-mix(in srgb, var(--mx-observatory) 48%, transparent), transparent 60%),
    radial-gradient(2px 2px at 71% 58%, color-mix(in srgb, var(--mx-observatory) 38%, transparent), transparent 60%),
    radial-gradient(3px 3px at 82% 40%, color-mix(in srgb, var(--mx-observatory) 50%, transparent), transparent 60%);
}

/* YOUTUBE — film: published audiovisual history, neutral silver. */
.mx-atmos[data-atmos="youtube"] .mx-atmos__wash {
  opacity: var(--atmos-opacity);
  background:
    radial-gradient(1100px 560px at 50% -10%, color-mix(in srgb, var(--mx-youtube) 7%, transparent), transparent 58%),
    repeating-linear-gradient(90deg, transparent 0 5px, rgba(205,210,214,0.012) 5px 6px);
}

/* PROFILE — personal artefact: identity-responsive, highly restrained. Uses the
   listener's --id-accent if the page sets one; silver fallback otherwise. */
.mx-atmos[data-atmos="profile"] .mx-atmos__wash {
  opacity: var(--atmos-opacity);
  background:
    radial-gradient(820px 520px at 50% -8%, color-mix(in srgb, var(--id-accent, var(--mx-youtube)) 9%, transparent), transparent 60%);
}

/* ===================================================================
   Optional, opt-in drift. Static is the default; a family adds .mx-atmos--drift
   for an extremely slow positional breathe on the WASH only (never the raster).
   Fully disabled under reduced motion and paused in background tabs by the host.
   =================================================================== */
.mx-atmos--drift .mx-atmos__wash {
  animation: mx-atmos-drift 48s ease-in-out infinite alternate;
  will-change: transform;
}
@keyframes mx-atmos-drift {
  from { transform: translate3d(0, 0, 0) scale(1); }
  to   { transform: translate3d(0, -1.4%, 0) scale(1.03); }
}

@media (prefers-reduced-motion: reduce) {
  .mx-atmos--drift .mx-atmos__wash { animation: none; }
}

/* Defensive: if a host ever prints/serialises the page, the atmosphere drops. */
@media print { .mx-atmos { display: none !important; } }
