/* bg.css — fixed full-viewport WebGL background lives behind
   the page content. The root + overlay together give us a
   readability tint without altering the page's own backgrounds. */

.bg-root {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  overflow: hidden;
  contain: strict;
}

.bg-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}

/* ============================================================
   GUARANTEED STARFIELD FALLBACK (no WebGL / no CDN required)
   ------------------------------------------------------------
   The WebGL starfield (bg-stars.js) loads OGL from esm.sh and
   needs a working GL context. When EITHER is unavailable —
   offline, a blocked CDN (e.g. a school/corporate network),
   reduced-motion driver blocklists, headless --disable-gpu —
   the canvas never mounts. Because `body.has-bg` is transparent
   (so the canvas can show through, see below), a missing canvas
   used to leave the page WHITE with light cream text = invisible
   content on every page (the bug this fixes).

   So we paint our own dark base + CSS starfield that ALWAYS
   renders, sitting at z-index:-2 — i.e. BEHIND the WebGL canvas
   (.bg-root is z-index:-1). When WebGL works it draws an opaque
   near-black starfield on top and you see the premium animated
   version; when it doesn't, these CSS stars are what shows.
   Either way: stars visible, text readable. (See animation-
   library MISTAKES.md #3/#4/#6.)
   ============================================================ */

/* Dark base on the ROOT element — paints behind everything,
   covers the full scroll height, and (unlike a body bg) sits
   behind the z-index:-1 canvas so it never hides it. */
html {
  background-color: var(--color-black, #0A0A0F);
}

/* Nebula wash layer — soft purple/cyan clouds on the dark base. */
body.has-bg::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -2;
  pointer-events: none;
  background-color: var(--color-black, #0A0A0F);
  background-repeat: no-repeat;
  background-image:
    radial-gradient(70vw 60vh at 16% 18%, rgba(79, 79, 158, 0.22), transparent 58%),
    radial-gradient(65vw 55vh at 84% 80%, rgba(91, 194, 221, 0.15), transparent 58%),
    radial-gradient(55vw 55vh at 60% 42%, rgba(79, 79, 158, 0.10), transparent 62%);
}

/* Star layer — a single tiled cell of scattered dots. Tile is
   large (340px) so the repeat reads as a random field. Dot
   colours: mostly warm cream, a few brand cyan/purple. A gentle
   twinkle modulates opacity between 0.8 and 1.0 only — the stars
   are never hidden, so they stay visible even if the animation
   never runs (no opacity:0 fallback trap). */
body.has-bg::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -2;
  pointer-events: none;
  background-repeat: repeat;
  background-size: 340px 340px;
  background-image:
    radial-gradient(1.4px 1.4px at 20px 30px,   rgba(248, 242, 228, 0.75), transparent),
    radial-gradient(2px 2px     at 300px 60px,  rgba(248, 242, 228, 1),    transparent),
    radial-gradient(1.3px 1.3px at 130px 110px, rgba(248, 242, 228, 0.65), transparent),
    radial-gradient(1.6px 1.6px at 250px 150px, rgba(91, 194, 221, 0.85),  transparent),
    radial-gradient(1.8px 1.8px at 60px 180px,  rgba(248, 242, 228, 0.90), transparent),
    radial-gradient(1.3px 1.3px at 190px 40px,  rgba(248, 242, 228, 0.60), transparent),
    radial-gradient(2px 2px     at 330px 250px, rgba(248, 242, 228, 0.95), transparent),
    radial-gradient(1.5px 1.5px at 90px 300px,  rgba(248, 242, 228, 0.80), transparent),
    radial-gradient(1.5px 1.5px at 210px 280px, rgba(126, 126, 210, 0.85), transparent),
    radial-gradient(2.4px 2.4px at 160px 220px, rgba(248, 242, 228, 1),    transparent),
    radial-gradient(1.3px 1.3px at 40px 250px,  rgba(248, 242, 228, 0.60), transparent),
    radial-gradient(1.5px 1.5px at 280px 200px, rgba(248, 242, 228, 0.78), transparent),
    radial-gradient(1.3px 1.3px at 150px 325px, rgba(248, 242, 228, 0.65), transparent),
    radial-gradient(1.6px 1.6px at 110px 70px,  rgba(91, 194, 221, 0.75),  transparent),
    radial-gradient(1.3px 1.3px at 235px 95px,  rgba(248, 242, 228, 0.62), transparent),
    radial-gradient(1.4px 1.4px at 15px 140px,  rgba(248, 242, 228, 0.70), transparent),
    radial-gradient(1.3px 1.3px at 320px 160px, rgba(248, 242, 228, 0.60), transparent),
    radial-gradient(1.7px 1.7px at 70px 90px,   rgba(248, 242, 228, 0.85), transparent);
  animation: bg-stars-twinkle 7s ease-in-out infinite;
}

@keyframes bg-stars-twinkle {
  0%, 100% { opacity: 0.82; }
  50%      { opacity: 1; }
}

/* Readability tint sits ABOVE the canvas but still below page
   content (z-index: -1 on .bg-root puts the whole subtree
   behind everything). Light variant softens aurora behind cream
   pages; dark variant deepens stars on the music page. */
.bg-overlay {
  position: absolute;
  inset: 0;
  pointer-events: none;
}
/* Both variants now use a dark tint — client wants the
   light pages flipped to black + white text so the aurora
   reads the same way it does behind the music page. */
.bg-overlay--light,
.bg-overlay--dark {
  background-color: rgba(10, 10, 15, 0.55);
}

/* When the WebGL bg is mounted, sections that previously had
   solid backgrounds need to let the canvas show through.
   The .has-bg modifier on <body> turns this on per-page. */
body.has-bg {
  /* Body's default solid #0A0A0F covers the z-index:-1 canvas.
     Drop it on bg pages so the starfield (which paints its own
     near-black base) is what the user actually sees. */
  background-color: transparent;
}
body.has-bg .section--light,
body.has-bg .section--dark {
  background-color: transparent;
}

/* TOKEN SWAP — the cleanest way to flip every selector that
   currently uses `var(--color-text-light)` (intended for dark
   text on cream) to cream text on dark. Propagates through
   bio body, about-preview, video labels, press blurbs, etc
   without per-selector overrides. */
body.has-bg {
  --color-text-light: #C0BAB2;       /* cream-tan body text */
}

/* Headings + labels that hardcode --color-black as a text
   colour need an explicit cream override — token swap doesn't
   touch them because --color-black is also used as a background
   colour elsewhere (footer, .section--dark) where it must stay. */
body.has-bg .section--light .section__title,
body.has-bg .section--light .section__eyebrow,
body.has-bg .section--light .disco__sub-heading,
body.has-bg .section--light h2,
body.has-bg .section--light h3,
body.has-bg .section--light h4,
body.has-bg .section--light .bio__notes-title,
body.has-bg .section--light .press__highlight-quote-text,
body.has-bg .section--light .press__sub-eyebrow,
body.has-bg .section--light .bio__quote p,
body.has-bg .section--light blockquote p,
body.has-bg .section--light .press__quote p {
  color: var(--color-cream);
}
/* Eyebrow on the dark backdrop reads better in cyan (10:1)
   than purple (which was tuned for cream). */
body.has-bg .section--light .section__eyebrow {
  color: var(--color-cyan);
}
/* About-page panels (.bio__facts) keep their own card-style
   background but their interior dark text needs to stay
   readable on the panel — not affected by the body flip. */

/* Disco card subtext (year, link) was tuned for cream bg — flip
   to a light-on-dark tone. Only relevant on the mobile static
   fallback because desktop replaces the cards with the canvas. */
body.has-bg .section--light .disco__card-year {
  color: rgba(248, 242, 228, 0.7);
}
body.has-bg .section--light .disco__card-link {
  color: var(--color-cyan);
}

/* Live page venue / city / note text was tuned for the original
   cream backdrop — flip to cream on the new dark backdrop so
   "THE TOTE" + "BRUNSWICK ARTISTS' BAR" etc. are readable. */
body.has-bg .section--light .live__venue,
body.has-bg .section--light .live__venue--big,
body.has-bg .section--light .live__city {
  color: var(--color-cream);
}
body.has-bg .section--light .live__note {
  color: rgba(248, 242, 228, 0.78);
}

body.has-bg .footer {
  /* Keep footer opaque so the canvas doesn't bleed into the
     credit area — readable contrast there is sacred. */
  background-color: var(--color-black);
}
body.has-bg .footer--on-light {
  /* Match: footer also flipped to dark on these pages. */
  background-color: var(--color-black);
  color: var(--color-text-dark);
}

/* (Previously hid .bg-root under prefers-reduced-motion. Removed
   because Windows defaults reduced-motion to "reduce" on many
   setups and the client wanted the animation visible.) */
