/* crt.css — phosphor terminal look: type, bloom, scanlines, vignette, flicker.
   Motion rules: only `transform` and `opacity` are ever animated/transitioned.
   Never `transition: all`. Custom ease lives in --ease-out. */

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

:root {
  --bg: #010401;
  --green: #00ff41;
  --green-dim: #4fae62; /* dimmer than --green but still >=7:1 on --bg (WCAG AA) */
  --glow-1: rgba(0, 255, 65, 0.85);
  --glow-2: rgba(0, 255, 65, 0.5);
  --glow-3: rgba(0, 255, 65, 0.28);
  --aberration-r: rgba(255, 32, 64, 0.16);
  --aberration-b: rgba(32, 180, 255, 0.16);
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  --font-mono:
    "VT323", ui-monospace, "SFMono-Regular", Menlo, Consolas, "Liberation Mono",
    monospace;
}

* {
  box-sizing: border-box;
}

html,
body {
  height: 100%;
  /* Dynamic viewport height: on mobile this tracks the *visible* viewport,
     shrinking when the on-screen keyboard opens, so flex-centered content
     (namely the terminal input) never ends up hidden behind the keyboard.
     Falls back to the plain 100% above on browsers that don't support it. */
  height: 100dvh;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--green);
  font-family: var(--font-mono);
  /* Fluid type: scales down on narrow phones, holds at the original 22px
     from ~500px viewport width up. Floor of 16px keeps it legible. */
  font-size: clamp(16px, 4.4vw, 22px);
  line-height: 1.5;
  overflow: hidden;
  -webkit-font-smoothing: antialiased;
}

:focus-visible {
  outline: 2px solid var(--green);
  outline-offset: 3px;
}

/* Shared phosphor glow: soft bloom + a faint chromatic fringe, never neon slop. */
.phosphor {
  color: var(--green);
  text-shadow:
    -1px 0 0 var(--aberration-r),
    1px 0 0 var(--aberration-b),
    0 0 4px var(--glow-1),
    0 0 12px var(--glow-2),
    0 0 22px var(--glow-3);
}

.crt {
  position: relative;
  height: 100vh;
  height: 100dvh; /* see html,body — tracks the keyboard-shrunk viewport */
  width: 100vw;
}

/* --- Digital rain (background, terminal-only) ---
   Canvas-drawn falling glyphs. Sits at the bottom of the stack — below the
   bloom/vignette/scanline/flicker overlays (so the CRT texture still reads
   on top of it, same as the rest of the scene) and well below .terminal,
   which gets its own dark backing so text stays crisp over the rain. Hidden
   until the rabbit is activated; matrix.js toggles .is-visible. */

.matrix-rain {
  position: fixed;
  z-index: 0;
  inset: 0;
  opacity: 0;
  pointer-events: none;
  transition: opacity 1400ms var(--ease-out);
}

.matrix-rain.is-visible {
  opacity: 1;
}

/* prefers-reduced-motion path: no canvas animation runs (see matrix.js) —
   just a flat, dim green wash standing in for it. */
.matrix-rain.is-static {
  background: rgba(0, 255, 65, 0.035);
}

/* --- Overlays (decorative, non-interactive) --- */

.bloom,
.vignette,
.scanlines,
.flicker {
  position: fixed;
  inset: 0;
  pointer-events: none;
}

.bloom {
  z-index: 1;
  background: radial-gradient(
    ellipse at center,
    rgba(0, 255, 65, 0.06) 0%,
    rgba(0, 255, 65, 0.02) 45%,
    rgba(0, 255, 65, 0) 72%
  );
  animation: bloom-flicker 7s ease-in-out infinite;
}

.vignette {
  z-index: 2;
  background: radial-gradient(
    ellipse at center,
    rgba(0, 0, 0, 0) 55%,
    rgba(0, 0, 0, 0.6) 100%
  );
}

.scanlines {
  z-index: 3;
  background: repeating-linear-gradient(
    to bottom,
    rgba(0, 0, 0, 0) 0px,
    rgba(0, 0, 0, 0) 1px,
    rgba(0, 0, 0, 0.18) 2px,
    rgba(0, 0, 0, 0.18) 3px
  );
  mix-blend-mode: multiply;
}

.flicker {
  z-index: 4;
  background: #000;
  opacity: 0;
  animation: flicker 6s infinite;
}

@keyframes bloom-flicker {
  0%,
  100% {
    opacity: 1;
  }
  4% {
    opacity: 0.92;
  }
  5% {
    opacity: 1;
  }
  38% {
    opacity: 1;
  }
  39% {
    opacity: 0.88;
  }
  41% {
    opacity: 1;
  }
  73% {
    opacity: 1;
  }
  74% {
    opacity: 0.94;
  }
  76% {
    opacity: 1;
  }
}

@keyframes flicker {
  0%,
  100% {
    opacity: 0;
  }
  7% {
    opacity: 0.025;
  }
  8% {
    opacity: 0;
  }
  53% {
    opacity: 0.015;
  }
  54% {
    opacity: 0;
  }
}

/* --- Scene --- */

.screen {
  position: relative;
  z-index: 10;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2rem;
  padding: max(2rem, env(safe-area-inset-top))
    max(2rem, env(safe-area-inset-right)) max(2rem, env(safe-area-inset-bottom))
    max(2rem, env(safe-area-inset-left));
}

@keyframes blink {
  0%,
  49.9% {
    opacity: 1;
  }
  50%,
  100% {
    opacity: 0;
  }
}

/* --- Rabbit ---
   Small, quiet, tucked into a randomly chosen corner (the corner-* class is
   set once at load by matrix.js, picked from rabbit.config.js's corner
   list). No glow, no bounce, no pulse — just a slow opacity fade-in, and it
   stays understated even once visible so it's easy to miss. */

.rabbit-btn {
  position: fixed;
  z-index: 20;
  appearance: none;
  background: none;
  border: none;
  padding: 0.5rem;
  margin: 0;
  cursor: pointer;
  opacity: 0;
  transition: opacity var(--fade-duration, 900ms) var(--ease-out);
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}

/* Corner offsets use max() against the safe-area insets so the rabbit never
   lands under a notch or the home-indicator bar on mobile — on non-notch
   devices env() resolves to 0 and the plain 1.25rem offset wins. */

.rabbit-btn.corner-top-left {
  top: max(1.25rem, env(safe-area-inset-top));
  left: max(1.25rem, env(safe-area-inset-left));
}

.rabbit-btn.corner-top-right {
  top: max(1.25rem, env(safe-area-inset-top));
  right: max(1.25rem, env(safe-area-inset-right));
}

.rabbit-btn.corner-bottom-left {
  bottom: max(1.25rem, env(safe-area-inset-bottom));
  left: max(1.25rem, env(safe-area-inset-left));
}

.rabbit-btn.corner-bottom-right {
  bottom: max(1.25rem, env(safe-area-inset-bottom));
  right: max(1.25rem, env(safe-area-inset-right));
}

.rabbit-btn.is-visible {
  opacity: 0.55;
}

.rabbit-btn[hidden] {
  display: none;
}

.rabbit-btn.is-visible:focus-visible {
  opacity: 0.9;
}

@media (hover: hover) and (pointer: fine) {
  .rabbit-btn.is-visible:hover {
    opacity: 0.9;
  }
}

.rabbit-img {
  display: block;
  width: clamp(28px, 4vw, 40px);
  height: auto;
}

/* --- Terminal (opening sequence + chat handoff) ---
   The centerpiece from load — opens with its own CRT panel "power on"
   transition at boot (see openTerminal() in matrix.js), then the wake-up
   sequence, connection beat, and Operator chat all print into the same
   scrollable log below. */

.terminal {
  width: min(90vw, 56ch);
  text-align: left;
  padding: 1.1rem 1.4rem;
  border: 1px solid rgba(0, 255, 65, 0.35);
  border-radius: 3px;
  /* Two layers: the original faint green tint on top of a near-opaque dark
     backing — the latter is what keeps terminal text crisp over the digital
     rain running behind it (see .matrix-rain). */
  background:
    linear-gradient(180deg, rgba(0, 255, 65, 0.05), rgba(0, 255, 65, 0.02)),
    rgba(1, 4, 1, 0.82);
  box-shadow:
    0 0 24px rgba(0, 255, 65, 0.08),
    inset 0 0 40px rgba(0, 255, 65, 0.03);
  opacity: 0;
  transform: scale(0.97);
  transition:
    opacity 500ms var(--ease-out),
    transform 500ms var(--ease-out);
}

.terminal.is-open {
  opacity: 1;
  transform: scale(1);
}

/* Minimal window-chrome affordance — three flat dots, no gradients/glow —
   just enough to read as a real terminal window, not a floating text block. */
.terminal-titlebar {
  display: flex;
  gap: 0.4rem;
  margin-bottom: 0.75rem;
  padding-bottom: 0.6rem;
  border-bottom: 1px solid rgba(0, 255, 65, 0.15);
}

.terminal-titlebar .dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: rgba(0, 255, 65, 0.25);
}

.terminal-log {
  display: flex;
  flex-direction: column;
  gap: 0.35em;
  margin-bottom: 0.5em;
  max-height: 40vh;
  max-height: 40dvh;
  overflow-y: auto;
}

.log-line {
  white-space: pre-wrap;
  word-break: break-word;
}

.log-line--system {
  color: var(--green-dim);
  text-shadow: 0 0 3px var(--glow-3);
}

.log-line--user {
  color: var(--green-dim);
}

.log-line--operator {
  color: var(--green);
}

.log-line--error {
  color: var(--green-dim);
  font-style: italic;
}

.terminal-form[hidden] {
  display: none;
}

.terminal-form {
  display: flex;
  align-items: flex-start;
  gap: 0.5ch;
}

.prompt {
  color: var(--green);
  text-shadow: 0 0 4px var(--glow-1);
  line-height: 1.5;
}

/* The input line: a fully-clickable, transparent native <input> sits on top
   of a visible text mirror. The mirror — typed text either side of a
   blinking block cursor — is what's actually seen, so the cursor always
   sits exactly at the caret: it IS the "type here" indicator. */

.input-line {
  position: relative;
  flex: 1;
  min-width: 0;
}

.input-display {
  display: block;
  min-height: 1.5em;
  white-space: pre-wrap;
  word-break: break-word;
  line-height: 1.5;
}

.input-cursor {
  display: inline-block;
  animation: blink 1s step-end infinite;
}

.input-cursor.is-idle {
  animation: none;
  opacity: 0.35;
}

.terminal-input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  background: transparent;
  border: none;
  outline: none;
  color: transparent;
  caret-color: transparent;
  font-family: var(--font-mono);
  /* >=16px keeps mobile Safari from auto-zooming in on focus. */
  font-size: 1.25rem;
  padding: 0;
  margin: 0;
  -webkit-tap-highlight-color: transparent;
}

.terminal-input:disabled {
  cursor: default;
}

.terminal-input::placeholder {
  color: transparent;
}

/* Screen-reader-only live region: announces completed lines/replies once,
   instead of spamming assistive tech on every typed character. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* --- Small screens: tighter insets, near-full-width terminal, shorter log
   so the input row always has room above the on-screen keyboard. --- */

@media (max-width: 640px) {
  .screen {
    padding: max(1.25rem, env(safe-area-inset-top))
      max(1rem, env(safe-area-inset-right))
      max(1.25rem, env(safe-area-inset-bottom))
      max(1rem, env(safe-area-inset-left));
    gap: 1.25rem;
  }

  .terminal {
    width: min(94vw, 56ch);
    padding: 0.9rem 1rem;
  }

  .terminal-log {
    max-height: 32vh;
    max-height: 32dvh;
  }
}

/* --- Reduced motion: keep fades, drop transforms/flicker/scanline animation --- */

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

  .rabbit-btn {
    transition-property: opacity;
  }

  .input-cursor {
    animation: none;
    opacity: 1;
  }

  .input-cursor.is-idle {
    opacity: 0.35;
  }

  .terminal {
    transition-property: opacity;
    transform: none;
  }

  .terminal.is-open {
    transform: none;
  }
}
