/* ---------------------------------------------------------------------------
 * burnt-synapse shared background — v1
 *
 * one mount point per page:   <div id="bg" aria-hidden="true"></div>
 * plus:  <link rel="stylesheet" href="/assets/bg/bg-v1.css">
 *        <script src="/assets/bg/bg-v1.js" defer></script>
 *
 * the system renders three fixed layers behind the content (pointer-events
 * none, z-index -3):
 *   .bb-base   vertical bg gradient + faint ember radials   (was .bg)
 *   .bb-art    the active ascii variant                    (was #waves)
 *   .bb-grain  feTurbulence noise                          (was .grain)
 *
 * variants, selection and the central default live in bg-v1.js:
 *   ?bg=<id>  >  localStorage["burnt.bg.variant"]  >  DEFAULT
 *
 * every variant is deterministic (seeded or pure math), honors
 * prefers-reduced-motion (static frame), and scales density down below 760px.
 * css variants animate transform/opacity only; the one canvas variant runs a
 * single rAF loop, paused while the tab is hidden, DPR capped at 2.
 * --------------------------------------------------------------------------- */

#bg { position: fixed; inset: 0; z-index: -3; pointer-events: none; }
#bg > * { position: absolute; inset: 0; }

.bb-base {
  z-index: 0;
  background:
    radial-gradient(60% 50% at 70% 10%, rgba(255, 122, 47, 0.07), transparent 60%),
    radial-gradient(50% 45% at 20% 85%, rgba(255, 196, 107, 0.045), transparent 60%),
    linear-gradient(180deg, var(--bg, #08060a) 0%, var(--bg2, #0f0a13) 100%);
}

.bb-art { z-index: 1; overflow: hidden; }

.bb-grain {
  z-index: 2;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23n)' opacity='0.05'/%3E%3C/svg%3E");
}

/* ---- variant: wave — the original field, ported as-is ----
 * seven rows of glyph noise riding a sine curve, drifting horizontally
 * over 100–200s, each row bobbing ±6px. 160-char rows doubled for a
 * seamless -50% drift loop. */
#bg .wave {
  position: absolute; left: 0; top: var(--y, 50%);
  width: max-content;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: var(--fs, 11px);
  letter-spacing: .18em;
  white-space: nowrap;
  color: rgba(255, 196, 107, var(--o, .04));
  will-change: transform;
  animation: bb-drift var(--dur, 140s) linear infinite;
}
#bg .wave.ember { color: rgba(255, 122, 47, var(--o, .04)); }
#bg .wave.rev { animation-direction: reverse; }
#bg .wave .row {
  display: inline-block;
  will-change: transform;
  animation: bb-bob var(--bob, 12s) ease-in-out infinite alternate;
}
#bg .wave i { display: inline-block; font-style: normal; }
#bg .t0 { transform: translateY(-10px); }
#bg .t1 { transform: translateY(-8px); }
#bg .t2 { transform: translateY(-6px); }
#bg .t3 { transform: translateY(-4px); }
#bg .t4 { transform: translateY(-2px); }
#bg .t5 { transform: translateY(0); }
#bg .t6 { transform: translateY(2px); }
#bg .t7 { transform: translateY(4px); }
#bg .t8 { transform: translateY(6px); }
#bg .t9 { transform: translateY(8px); }
#bg .t10 { transform: translateY(10px); }
@keyframes bb-drift { to { transform: translateX(-50%); } }
@keyframes bb-bob {
  from { transform: translateY(-6px); }
  to   { transform: translateY(6px); }
}

/* ---- variant: rain — falling glyph columns, soft comet tails ----
 * each column is one 2x-viewport strip of seeded glyphs sliding down by
 * exactly one viewport height per cycle; the repeating mask (same period)
 * fades each window's edges, so the loop is seamless and each column reads
 * as a soft-headed streak. transform-only, 16 strips (8 small). */
#bg .bb-rain {
  position: absolute; top: 0; left: var(--x);
  width: 1.4ch; height: calc(var(--p) * 2);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 10px; line-height: var(--lh, 14px);
  white-space: pre;
  color: rgba(255, 196, 107, var(--o, .045));
  will-change: transform;
  animation: bb-rain var(--dur, 16s) linear infinite;
  -webkit-mask-image: repeating-linear-gradient(180deg, transparent 0px, #000 calc(var(--p) * .18), #000 calc(var(--p) * .82), transparent var(--p));
          mask-image: repeating-linear-gradient(180deg, transparent 0px, #000 calc(var(--p) * .18), #000 calc(var(--p) * .82), transparent var(--p));
}
#bg .bb-rain.ember { color: rgba(255, 122, 47, var(--o, .07)); }
@keyframes bb-rain {
  from { transform: translateY(calc(var(--p) * -1)); }
  to   { transform: translateY(0); }
}

/* ---- variant: topo — ascii relief, two-tone contour survey ----
 * two overlapping <pre> grids (low band dim amber, high band ember) of one
 * deterministic 2d sine field; the pair sways ±1.5vw over 90s. */
#bg .bb-topo-drift {
  position: absolute; inset: 0;
  animation: bb-topo-drift 90s ease-in-out infinite alternate;
}
#bg .bb-topo {
  position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -50%);
}
#bg .bb-topo pre {
  margin: 0;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 10px; line-height: 1.6; letter-spacing: .18em;
  white-space: pre;
}
#bg .bb-topo .bb-topo-low  { color: rgba(255, 196, 107, .05); }
#bg .bb-topo .bb-topo-high { position: absolute; left: 0; top: 0; color: rgba(255, 122, 47, .075); }
@keyframes bb-topo-drift {
  from { transform: translateX(-1.5vw); }
  to   { transform: translateX(1.5vw); }
}

/* ---- variant: orbit — rings of glyphs orbiting the core ----
 * each ring is one rotating square (compositor); chars sit at fixed angles
 * via rotate()/translateY(-R vmin) so radius scales with the viewport.
 * 5 rings + a breathing core = 6 animated layers, ~150 static nodes. */
#bg .bb-orbit {
  position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  width: 100vmin; height: 100vmin;
}
#bg .bb-orbit-ring {
  position: absolute; inset: 0;
  color: rgba(255, 196, 107, 1);
  opacity: var(--o, .05);
  will-change: transform;
  animation: bb-spin var(--dur, 200s) linear infinite;
}
#bg .bb-orbit-ring.ember { color: rgba(255, 122, 47, 1); }
#bg .bb-orbit-ring.rev { animation-direction: reverse; }
#bg .bb-orbit-ring i {
  position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -50%) rotate(var(--a, 0deg)) translateY(calc(var(--r, 20vmin) * -1));
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-style: normal;
  white-space: nowrap;
}
#bg .bb-orbit-core {
  position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 14px;
  color: rgba(255, 122, 47, .9);
  opacity: .08;
  will-change: transform;
  animation: bb-core 9s ease-in-out infinite;
}
@keyframes bb-spin { to { transform: rotate(360deg); } }
@keyframes bb-core {
  0%, 100% { transform: translate(-50%, -50%) scale(1); opacity: .08; }
  50%      { transform: translate(-50%, -50%) scale(1.4); opacity: .16; }
}

/* ---- variant: scan — crt scanlines, sweep + phosphor flicker ----
 * static scanline raster + vignette; one 22vh light band sweeps top→bottom
 * every 8s; the raster flickers on 0.9s steps. two animated layers. */
#bg .bb-scan-bloom {
  background: radial-gradient(120% 90% at 50% 50%, transparent 55%, rgba(0, 0, 0, .28) 100%);
}
#bg .bb-scanlines {
  background: repeating-linear-gradient(180deg,
    rgba(5, 3, 8, .30) 0px, rgba(5, 3, 8, .30) 1px,
    transparent 1px, transparent 3px);
  animation: bb-flicker .9s steps(3, end) infinite;
}
@keyframes bb-flicker {
  0%   { opacity: .82; }
  100% { opacity: 1; }
}
#bg .bb-scan-sweep {
  left: 0; right: 0; top: 0; height: 22vh;
  background: linear-gradient(180deg,
    transparent 0%, rgba(255, 196, 107, .035) 35%,
    rgba(255, 122, 47, .06) 50%,
    rgba(255, 196, 107, .035) 65%, transparent 100%);
  will-change: transform;
  animation: bb-sweep 8s linear infinite;
}
@keyframes bb-sweep {
  from { transform: translateY(-25vh); }
  to   { transform: translateY(105vh); }
}

/* ---- variant: field — perspective starfield (the canvas one) ----
 * one canvas, one rAF loop, ~140 seeded glyph "stars" flying outward from
 * the center; pre-baked font/fill strings so the hot path allocates nothing;
 * DPR capped at 2; paused while the tab is hidden. */
#bg .bb-field {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
}

/* one switch for every css animation in this file */
@media (prefers-reduced-motion: reduce) {
  #bg .bb-anim { animation: none !important; }
}
