@font-face {
  font-family: "IBM Plex Mono";
  src: url("IBMPlexMono-Regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "IBM Plex Mono";
  src: url("IBMPlexMono-Bold.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

:root {
  --bg: #0b0b0b;
  --fg: #d0d0d0;
  --bar-h: 52px; /* control-bar height incl. padding; grid reserves this on touch */
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: "IBM Plex Mono", "DejaVu Sans Mono", Menlo, Consolas, monospace;
  height: 100%;
  overflow: hidden;
}

/* ratzilla's DomBackend sizes the grid as cols = innerW/10, rows = innerH/20
   (see ratzilla::utils::get_window_size). Match it exactly so the grid
   fills the viewport and never overflows. */
#grid {
  padding: 0;
  margin: 0;
  font-size: 16.5px;   /* IBM Plex Mono advance ~0.6em -> ~9.9px (<=10) */
  line-height: 20px;   /* exact row height to match rows = innerH/20 */
  white-space: pre;
}
#grid pre { margin: 0; line-height: 20px; }

/* On touch, ratzilla sizes the grid to the PHYSICAL screen (taller than the
   visible viewport), so the input row would fall below the fold. Bottom-anchor
   the grid above the reserved control bar so the prompt + newest lines stay
   visible; the oversized top (old lines, top border) clips upward. */
html.is-touch #grid {
  position: fixed;
  left: 0;
  right: 0;
  bottom: calc(var(--bar-h) + env(safe-area-inset-bottom, 0px));
}

/* title strip: only on touch, where the ratatui title clips off-top */
#titlebar { display: none; }
html.is-touch #titlebar {
  display: flex;
  align-items: center;
  gap: 10px;
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: calc(28px + env(safe-area-inset-top, 0px));
  padding: env(safe-area-inset-top, 0px) 12px 0;
  z-index: 9300; /* above grid, below effect overlays (9500+) */
  background: linear-gradient(180deg, rgba(10, 12, 15, 0.96), rgba(10, 12, 15, 0));
  font-size: 13px;
  color: rgba(180, 200, 210, 0.75);
  pointer-events: none;
}
#titlebar .dots { color: rgba(120, 140, 160, 0.55); letter-spacing: 2px; }
#titlebar .name { letter-spacing: 3px; font-weight: 700; }

/* hidden input that summons the mobile soft keyboard */
#kbd {
  position: fixed;
  left: -9999px;
  top: 0;
  width: 1px;
  height: 1px;
  opacity: 0;
  border: 0;
  padding: 0;
}

/* touch control bar: cohesive with the bezel, translucent, inside safe area */
#controls {
  position: fixed;
  left: 8px;
  right: 8px;
  bottom: calc(6px + env(safe-area-inset-bottom, 0px));
  height: 44px;
  display: none;
  gap: 8px;
  padding: 4px;
  background: linear-gradient(180deg, rgba(16, 19, 24, 0.72), rgba(10, 12, 16, 0.92));
  border: 1px solid rgba(120, 140, 160, 0.16);
  border-radius: 12px;
  z-index: 9600;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
html.is-touch #controls { display: flex; }
#controls button {
  flex: 1 1 0;
  min-width: 0;
  background: rgba(34, 38, 44, 0.9);
  color: var(--fg);
  border: 1px solid rgba(120, 140, 160, 0.14);
  border-radius: 8px;
  font: inherit;
  font-size: 15px;
  cursor: pointer;
  user-select: none;
  -webkit-user-select: none;
  touch-action: manipulation;
  text-shadow: 0 0 4px rgba(160, 200, 220, 0.25);
}
#controls button:active,
#controls button.active {
  background: rgba(70, 90, 105, 0.95);
  border-color: rgba(160, 200, 220, 0.4);
}

/* CARRY-FORWARD from Task 1: ratzilla's mobile path (get_screen_size) uses
   rows = screenHeight / 19, not / 20. Match it with a 19px cell — but ONLY
   for real mobile/tablet, keyed on the same user-agent test ratzilla uses
   (is_mobile() = UA contains "mobile"/"tablet"). A narrow DESKTOP window is
   NOT mobile and still needs 20px, so this must NOT be a viewport-width
   media query. The `.is-mobile` class is set in controls.js (Task 4). */
html.is-mobile #grid, html.is-mobile #grid pre { line-height: 19px; }

/* --- screen dressing: background + bezel -------------------------------- */

body {
  background:
    radial-gradient(ellipse at 50% 40%, #14161a 0%, #0b0b0b 70%, #060607 100%);
}

/* soft monitor treatment: NO border line (the ratatui box-border is the only
   frame). Rounded-corner mask + outer glow + edge vignette read as a screen. */
#bezel {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 9200;
  border-radius: 12px;
  box-shadow:
    inset 0 0 90px 20px rgba(0, 0, 0, 0.55),
    inset 0 0 3px rgba(160, 200, 220, 0.10);
}
/* round the actual screen corners so the grid reads as a CRT, not a rectangle */
html, body { border-radius: 12px; }
#grid { border-radius: 12px; }

/* --- CRT atmosphere ---------------------------------------------------- */

/* per-cell phosphor glow: currentColor = each cell's own color, so the
   per-speaker palette keeps its hue while glowing */
#grid span {
  text-shadow: 0 0 5px currentColor;
}

/* faint scanlines (control bar is an overlay now, so full height) */
body::before {
  content: "";
  position: fixed;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  pointer-events: none;
  z-index: 9000;
  background: repeating-linear-gradient(
    0deg,
    rgba(0, 0, 0, 0.16) 0 1px,
    transparent 1px 3px
  );
}

/* vignette darkening the edges */
body::after {
  content: "";
  position: fixed;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  pointer-events: none;
  z-index: 8999;
  background: radial-gradient(
    ellipse at center,
    transparent 50%,
    rgba(0, 0, 0, 0.6) 100%
  );
}

@media (prefers-reduced-motion: reduce) {
  body.fx-flash #fx-flash,
  body.fx-glitch #grid { animation: none !important; }
  body.fx-flash #fx-flash { opacity: 0; }
}

/* --- effect overlays --------------------------------------------------- */
#fx-flash, #fx-mood {
  position: fixed;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  pointer-events: none;
  z-index: 9500;
  opacity: 0;
}

/* one-shot flash */
body.fx-flash #fx-flash {
  background: #ffffff;
  animation: smobb-flash 120ms ease-out;
}
@keyframes smobb-flash {
  from { opacity: 0.85; }
  to   { opacity: 0; }
}

/* sustained mood tint */
body.mood-redalert   #fx-mood { background: #ff0000; opacity: 0.10; }
body.mood-coldcyan   #fx-mood { background: #00d0ff; opacity: 0.08; }
body.mood-corruption #fx-mood { background: #33ff33; opacity: 0.08; }

/* corruption glitch on the grid */
body.fx-glitch #grid {
  animation: smobb-glitch 180ms steps(2) infinite;
}
@keyframes smobb-glitch {
  0%   { transform: translate(0, 0); filter: none; }
  50%  { transform: translate(-2px, 1px); filter: hue-rotate(25deg) saturate(1.4); }
  100% { transform: translate(0, 0); filter: none; }
}

/* accessibility: kill all motion */
body.reduced #fx-flash,
body.reduced.fx-glitch #grid {
  animation: none !important;
}
body.reduced #fx-flash { opacity: 0; }
body.reduced #controls button[data-key="F3"] { background: rgba(70, 90, 105, 0.95); }
