:root {
  --bg: #07040d;
  --bg-glow: #170b2e;
  --fg: #e7e2f5;
  --fg-dim: #8d84ab;
  --accent: #f472b6;
  --accent-2: #818cf8;
  --accent-3: #a855f7;
  --panel-bg: rgba(13, 7, 26, 0.52);
  --panel-border: rgba(255, 255, 255, 0.09);
  --font: "JetBrains Mono", "SFMono-Regular", Consolas, Menlo, monospace;
  --font-brand: "Nasalization", "JetBrains Mono", sans-serif;
}

@font-face {
  font-family: "Nasalization";
  src: url("/assets/fonts/nasalization.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

* {
  box-sizing: border-box;
}

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font);
  font-weight: 300;
  font-size: 15px;
}

.hidden {
  display: none !important;
}

a {
  color: var(--accent-2);
  text-decoration-color: rgba(129, 140, 248, 0.4);
}

a:hover {
  color: var(--accent);
}

button {
  font-family: var(--font);
  font-weight: 300;
  background: rgba(255, 255, 255, 0.03);
  color: var(--fg);
  border: 1px solid var(--panel-border);
  border-radius: 3px;
  padding: 0.3em 0.7em;
  font-size: 0.85em;
  cursor: pointer;
  transition: border-color 0.15s ease, color 0.15s ease;
}

button:hover {
  border-color: var(--accent);
  color: var(--accent);
}

/* Touch-only close affordance for the hidden full-screen commands (pong,
   synth, beats, compose, strudel) -- "esc to exit" has no equivalent on a
   device with no keyboard at all. Positioned absolutely within each
   panel -- all of them are position:relative already (see pong.css and
   its siblings), so this docks to each panel's own corner rather than
   the viewport's. Hidden on desktop: Escape already works there, and a
   floating X is just visual noise when a keyboard is already in play. */
.exit-btn {
  display: none;
  position: absolute;
  top: 0.75rem;
  right: 0.75rem;
  width: 28px;
  height: 28px;
  padding: 0;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  font-size: 0.9rem;
  line-height: 1;
  z-index: 2;
}

@media (pointer: coarse) {
  .exit-btn {
    display: flex;
  }
}

/* A tappable wrapper around an already-styled label (e.g. #synth-wave,
   #compose-wave) -- transparent so the label underneath still looks like
   plain text, not a second button nested inside a button-shaped box.
   Shared between synth.css and compose.css's wave toggles. */
.wave-toggle-btn {
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  font: inherit;
}

.wave-toggle-btn:hover {
  border: none;
}

::selection {
  background: rgba(244, 114, 182, 0.3);
  color: #fff;
}

/* ---------- animated cosmic backdrop ---------- */
#bg {
  position: fixed;
  inset: 0;
  /* 0, not a negative value -- z-index:-1 on a fixed element with no
     explicit stacking context on the foreground siblings gets painted
     behind the page in some browsers instead of merely behind #terminal/
     #gui, which is why the glass panels showed no backdrop at all.
     Explicit stacking on both sides (this at 0, panels at 1) is what
     actually keeps this behind them, reliably. */
  z-index: 0;
  overflow: hidden;
  background: radial-gradient(ellipse 90% 60% at 50% -10%, var(--bg-glow) 0%, var(--bg) 55%, #030106 100%);
}

#starfield {
  position: absolute;
  inset: 0;
  opacity: 0.8;
}

#brand-mark {
  position: fixed;
  top: 1.1rem;
  left: 1.5rem;
  z-index: 2;
  font-family: var(--font-brand);
  font-size: 0.85rem;
  letter-spacing: 0.18em;
  color: var(--fg-dim);
  opacity: 0.75;
  pointer-events: none;
  user-select: none;
}

.nebula {
  position: absolute;
  border-radius: 50%;
  filter: blur(90px);
  opacity: 0.5;
  mix-blend-mode: screen;
  will-change: transform;
}

.nebula--1 {
  width: 55vw;
  height: 55vw;
  top: -15%;
  left: -12%;
  background: radial-gradient(circle, var(--accent-3), transparent 70%);
  animation: drift1 46s ease-in-out infinite;
}

.nebula--2 {
  width: 48vw;
  height: 48vw;
  bottom: -18%;
  right: -8%;
  background: radial-gradient(circle, var(--accent-2), transparent 70%);
  animation: drift2 58s ease-in-out infinite;
}

.nebula--3 {
  width: 38vw;
  height: 38vw;
  top: 28%;
  left: 58%;
  background: radial-gradient(circle, var(--accent), transparent 70%);
  animation: drift3 52s ease-in-out infinite;
}

/* A fourth, smaller and dimmer than the other three -- extra depth behind
   the galactic band (drawn on the canvas, see background.js) without
   competing with it for attention. Opacity set here rather than folded
   into the gradient stop so it layers correctly under mix-blend-mode:
   screen like its siblings. */
.nebula--4 {
  width: 26vw;
  height: 26vw;
  top: 55%;
  left: 20%;
  opacity: 0.32;
  background: radial-gradient(circle, var(--accent-2), transparent 70%);
  animation: drift4 64s ease-in-out infinite;
}

@keyframes drift1 {
  0%, 100% { transform: translate(0, 0) scale(1); }
  50% { transform: translate(6vw, 8vh) scale(1.15); }
}

@keyframes drift2 {
  0%, 100% { transform: translate(0, 0) scale(1); }
  50% { transform: translate(-8vw, -6vh) scale(1.1); }
}

@keyframes drift3 {
  0%, 100% { transform: translate(0, 0) scale(1); }
  50% { transform: translate(-5vw, 5vh) scale(0.9); }
}

@keyframes drift4 {
  0%, 100% { transform: translate(0, 0) scale(1); }
  50% { transform: translate(4vw, -7vh) scale(1.2); }
}

@media (prefers-reduced-motion: reduce) {
  .nebula,
  #mic-btn.listening {
    animation: none;
  }
}
