body {
  background: #000;
  color: #00ffff;
  font-family: monospace;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  margin: 0;
  text-transform: uppercase;
}

/* ===============================
   CRT OVERLAY (tint + scan + lens/vignette)
================================ */

.crt-overlay {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 10;
  overflow: hidden;

  /* Base tint */
  background: rgba(0, 255, 255, 0.035);

  /* subtle “lens” suggestion */
  transform: perspective(1200px) translateZ(0);
}

/* Scanlines + moving sweep */
.crt-overlay::before {
  content: "";
  position: fixed; /* mobile-safe */
  inset: 0;
  pointer-events: none;
  z-index: 11;

  background:
    /* horizontal scanlines */
    repeating-linear-gradient(
      to bottom,
      rgba(0, 255, 255, 0.10) 0px,
      rgba(0, 255, 255, 0.00) 2px,
      rgba(0, 255, 255, 0.00) 6px
    ),
    /* thicker sweep band */
    linear-gradient(
      to bottom,
      rgba(0, 255, 255, 0.00),
      rgba(0, 255, 255, 0.12),
      rgba(0, 255, 255, 0.40),
      rgba(0, 255, 255, 0.12),
      rgba(0, 255, 255, 0.00)
    );

  opacity: 0.62;
  transform: translateY(-45%);
  animation: scanSweep 7s linear infinite;
}

/* Combined vignette + lens highlight (barrel illusion) */
.crt-overlay::after {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 12;

  background:
    /* lens highlight / curvature hint */
    radial-gradient(
      ellipse at center,
      rgba(0, 255, 255, 0.07) 0%,
      rgba(0, 255, 255, 0.02) 35%,
      rgba(0, 0, 0, 0.00) 55%
    ),
    /* vignette */
    radial-gradient(
      ellipse at center,
      rgba(0, 0, 0, 0.00) 55%,
      rgba(0, 0, 0, 0.22) 85%,
      rgba(0, 0, 0, 0.35) 100%
    );

  opacity: 0.60;
}

/* Intensify during authentication */
body.authing .crt-overlay {
  background: rgba(0, 255, 255, 0.06);
  animation: crtPulse 0.12s infinite alternate;
}

body.authing .crt-overlay::before {
  opacity: 0.80;
  animation-duration: 4.2s;
}

/* Mobile/tablet: bump visibility slightly */
@media (pointer: coarse) {
  .crt-overlay::before {
    opacity: 0.72;
    animation-duration: 8s;
  }
  body.authing .crt-overlay::before {
    opacity: 0.88;
  }
}

/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
  .crt-overlay::before {
    animation: none;
    transform: none;
    opacity: 0.55;
  }
  body.authing .crt-overlay {
    animation: none;
  }
}

@keyframes scanSweep {
  0%   { transform: translateY(-45%); }
  100% { transform: translateY(45%); }
}

@keyframes crtPulse {
  from { opacity: 0.55; }
  to   { opacity: 0.85; }
}

/* ===============================
   STAGE FLASH (beat-synced micro flicker)
================================ */

/* Default micro-flash */
body.stage-flash .crt-overlay {
  animation: stageFlash 0.14s ease-out 1;
}

/* Optional intensity variants via data attribute */
body.stage-flash[data-flash="soft"] .crt-overlay { --flash-boost: 1.0; }
body.stage-flash[data-flash="hard"] .crt-overlay { --flash-boost: 1.35; }
body.stage-flash[data-flash="confirm"] .crt-overlay { --flash-boost: 1.6; }

@keyframes stageFlash {
  0%   { opacity: calc(1 * var(--flash-boost, 1)); filter: brightness(1.05); }
  35%  { opacity: calc(1.22 * var(--flash-boost, 1)); filter: brightness(1.35); }
  100% { opacity: calc(1 * var(--flash-boost, 1)); filter: brightness(1.05); }
}

/* Reduced motion: keep subtle flash but remove animation */
@media (prefers-reduced-motion: reduce) {
  body.stage-flash .crt-overlay {
    animation: none;
  }
}

/* ===============================
   LAYOUT
================================ */

.terminal-container {
  position: relative;
  z-index: 2;
  width: 100%;
  display: flex;
  justify-content: center;

  /* Prevent blend/z-index weirdness with mix-blend-mode layers */
  isolation: isolate;
}

/* Panels */
.box {
  border: 2px solid #00ffff;
  padding: 40px;
  text-align: center;
  background: #000;
  box-shadow: 0 0 15px #00ffff;
  width: 90%;
  max-width: 500px;

  /* Stabilize jitter + GPU hint */
  will-change: transform, filter;
  transform: translateZ(0);
}

/* Shared panel stabilization */
.map-box,
.node-panel {
  will-change: transform, filter;
  transform: translateZ(0);
}

/* ===============================
   INPUT + BUTTON
================================ */

#observer-id {
  background: transparent;
  border: none;
  border-bottom: 1px solid #00ffff;
  color: #00ffff;
  font-size: 1.5em;
  width: 100%;
  outline: none;
  margin-bottom: 20px;
  text-align: center;
  font-family: inherit;
}

.btn {
  background: #00ffff;
  color: #000;
  border: none;
  padding: 12px 20px;
  cursor: pointer;
  font-weight: bold;
  width: 100%;
  font-family: inherit;
  transition: background 0.2s ease;
}

.btn:hover {
  background: #00dddd;
}

/* Stronger disabled feel + disable hover brighten during auth */
.btn:disabled,
body.authing .btn {
  opacity: 0.7;
  cursor: default;
}

.btn:disabled:hover,
body.authing .btn:hover {
  background: #00ffff;
}

/* Disabled input clarity */
#observer-id:disabled,
body.authing #observer-id {
  opacity: 0.65;
  cursor: not-allowed;
}

/* ===============================
   TERMINAL TEXT + HANDSHAKE
================================ */

#terminal-msg {
  min-height: 1.2em;
  letter-spacing: 0.08em;
  opacity: 0.95;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: clip;
}

/* On very small screens, allow wrap so long status lines remain readable */
@media (max-width: 420px) {
  #terminal-msg {
    white-space: normal;
    line-height: 1.25;
  }
}

/* Cursor that does NOT change layout */
#terminal-msg.typing::after {
  content: "▍";
  display: inline-block;
  margin-left: 6px;
  opacity: 1;
  animation: cursorBlink 0.9s steps(1) infinite;
}

@keyframes cursorBlink {
  50% { opacity: 0; }
}

.handshake {
  width: 100%;
  height: 10px;
  border: 1px solid rgba(0, 255, 255, 0.5);
  background: rgba(0, 255, 255, 0.04);
  overflow: hidden;
  margin: 8px 0 2px 0;
}

.handshake-bar {
  width: 0%;
  height: 100%;
  background: rgba(0, 255, 255, 0.9);
  box-shadow: 0 0 10px rgba(0, 255, 255, 0.6);

  /* JS now animates width frame-by-frame for “creep” */
  transition: none;
}

/* Fade-out before redirect */
body.fade-out {
  animation: fadeToBlack 0.35s ease forwards;
}

@keyframes fadeToBlack {
  from { opacity: 1; }
  to   { opacity: 0; }
}

/* ===============================
   SHARED MAP / NODE STYLES
================================ */

.small-link {
  color: #444;
  text-decoration: none;
  font-size: 0.8em;
}

.small-link:hover {
  color: #00ffff;
}

.status-online {
  color: #00ff00;
  font-weight: bold;
}

.map-box,
.node-panel {
  border: 2px solid #00ffff;
  padding: 40px;
  text-align: center;
  background: #000;
  box-shadow: 0 0 20px rgba(0, 255, 255, 0.2);
  width: 90%;
  max-width: 650px;
}

.map-box {
  max-width: 500px;
}

.node-link {
  color: #00ffff;
  text-decoration: none;
  display: block;
  margin: 20px 0;
  padding: 15px;
  border: 1px dashed rgba(0, 255, 255, 0.4);
}

.node-link:hover {
  background: rgba(0, 255, 255, 0.1);
  border-style: solid;
}

/* ===============================
   CHROMATIC SPLIT (during auth)
================================ */

body.authing .box,
body.authing .map-box,
body.authing .node-panel {
  position: relative;
  filter: saturate(1.05) contrast(1.05);
  animation: signalJitter 0.22s infinite alternate;
}

/* Ghost layers (cyan + red) */
body.authing .box::before,
body.authing .box::after,
body.authing .map-box::before,
body.authing .map-box::after,
body.authing .node-panel::before,
body.authing .node-panel::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  mix-blend-mode: screen;
  opacity: 0.18;
}

/* Cyan */
body.authing .box::before,
body.authing .map-box::before,
body.authing .node-panel::before {
  transform: translate(1px, 0);
  box-shadow: 0 0 0 1px rgba(0, 255, 255, 0.25);
}

/* Red */
body.authing .box::after,
body.authing .map-box::after,
body.authing .node-panel::after {
  transform: translate(-1px, 0);
  box-shadow: 0 0 0 1px rgba(255, 0, 60, 0.18);
}

@keyframes signalJitter {
  from { transform: translateX(0); }
  to   { transform: translateX(0.6px); }
}

/* Reduced motion: keep color effect, remove jitter */
@media (prefers-reduced-motion: reduce) {
  body.authing .box,
  body.authing .map-box,
  body.authing .node-panel {
    animation: none;
  }
}

/* ===============================
   BOOT: phosphor fade + power-on flicker
   (Updated: fade is half-speed slower)
================================ */

body.booting .box {
  opacity: 0;
  transform: scale(0.985);
  filter: brightness(0.85) blur(0.2px);

  /* Fade-in slowed from 0.85s -> 1.7s (half speed) */
  animation: bootFadeIn 1.7s ease forwards, powerFlicker 0.55s ease 0.18s 1;

  /* bloom during boot */
  box-shadow:
    0 0 12px rgba(0, 255, 255, 0.22),
    0 0 26px rgba(0, 255, 255, 0.12);
}

@keyframes bootFadeIn {
  to {
    opacity: 1;
    transform: scale(1);
    filter: brightness(1) blur(0);
  }
}

@keyframes powerFlicker {
  0%   { opacity: 0.10; }
  18%  { opacity: 0.85; }
  32%  { opacity: 0.35; }
  52%  { opacity: 1.00; }
  68%  { opacity: 0.65; }
  100% { opacity: 1.00; }
}

/* During auth, slightly more bloom */
body.authing .box {
  box-shadow:
    0 0 14px rgba(0, 255, 255, 0.28),
    0 0 34px rgba(0, 255, 255, 0.16);
}
