/* ============================================================
   OSSUARY COLLECTIVE — shared CRT + theme foundation
   Loaded by every page. Page-specific styles stay inline in
   each page's own <style> block.

   Theme variables are overwritten at runtime by the terminal's
   `theme` command via document.documentElement.style; the values
   here are the default "phosphor green" palette and the resting
   state for pages that don't ship a theme switcher.
   ============================================================ */

/* ---------- self-hosted fonts ----------
   Served from this domain, so the site makes no third-party requests at all.
   Both families are SIL OFL 1.1; the licences ship verbatim beside the files
   in /assets/fonts/. Deliberately NOT subset: Google's CSS API slices its
   woff2 by unicode-range and box drawing (U+2500-257F) falls outside every
   slice, so the whole compound's box-drawing art — `pipes`, the skull,
   `defrag` — used to fall back to whatever monospace the visitor's OS had.
   IBM Plex Mono covers those ranges itself. One font now owns both the
   glyphs and the spaces between them, which is why the grids line up. */
@font-face {
  font-family: "VT323";
  src: url("/assets/fonts/vt323-regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "IBM Plex Mono";
  src: url("/assets/fonts/ibm-plex-mono-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "IBM Plex Mono";
  src: url("/assets/fonts/ibm-plex-mono-600.woff2") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}

:root {
  --bg: #030503;
  --phosphor: #33ff66;
  --phosphor-dim: #1d8f43;
  --hex: #145c2e;
  --amber: #ffb000;
  --alarm: #ff2b2b;
  /* Deep companion to --alarm, for full-bleed washes rather than text: the
     perimeter's #flash slams this over the whole viewport at 0.85 opacity
     behind ACCESS DENIED. --alarm itself is far too hot at that size — it
     buries the headline it's supposed to be punctuating. Constant across
     every theme, exactly like --bg and --alarm, so `theme` never touches
     it and applyTheme() has no business setting it. */
  --alarm-deep: #5c0000;
  --phosphor-glow: 51, 255, 102;
  --amber-glow: 255, 176, 0;
  --alarm-glow: 255, 43, 43;
}

/* CRT-effect toggles (driven by the terminal `theme` command) */
body.no-scanlines .crt::before { opacity: 0; }
body.no-flicker .flicker { display: none; }

* { margin: 0; padding: 0; box-sizing: border-box; }

html, body {
  min-height: 100%;
  background: var(--bg);
  overflow-x: hidden;
  overflow-y: auto;
}

/* Base body type. Pages set their own font-size / line-height. */
body {
  font-family: "IBM Plex Mono", monospace;
  color: var(--phosphor);
}

/* ---------- CRT chrome ---------- */
.crt {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 50;
}
.crt::before {
  content: "";
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(
    to bottom,
    rgba(0, 0, 0, 0) 0px,
    rgba(0, 0, 0, 0) 2px,
    rgba(0, 0, 0, 0.22) 3px,
    rgba(0, 0, 0, 0.22) 4px
  );
}
.crt::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(ellipse at center, rgba(0,0,0,0) 55%, rgba(0,0,0,0.55) 100%),
    radial-gradient(ellipse at center, rgba(var(--phosphor-glow), 0.04), rgba(0,0,0,0) 70%);
}
.flicker {
  position: fixed;
  inset: 0;
  background: rgba(160, 255, 190, 0.02);
  pointer-events: none;
  z-index: 51;
  animation: flicker 4s infinite;
}
@keyframes flicker {
  0%, 100% { opacity: 0.55; }
  3%  { opacity: 0.2; }
  9%  { opacity: 0.7; }
  11% { opacity: 0.15; }
  12% { opacity: 0.6; }
  47% { opacity: 0.5; }
  48% { opacity: 0.85; }
  50% { opacity: 0.45; }
  73% { opacity: 0.6; }
  74% { opacity: 0.25; }
  75% { opacity: 0.55; }
}

/* Shared blinking cursor (index & terminal both use it) */
.cursor {
  display: inline-block;
  width: 0.6em;
  height: 1em;
  background: var(--phosphor);
  vertical-align: text-bottom;
  animation: blink 1s steps(1) infinite;
}
@keyframes blink { 50% { opacity: 0; } }

@media (prefers-reduced-motion: reduce) {
  .flicker { animation: none; }
  .cursor { animation: none; }
}
