:root {
  --bg: #080b08;
  --bg-deep: #050705;
  --fg: #4af626;
  --fg-dim: #2f7d20;
  --fg-bright: #b9ffa8;
  --muted: #6f8a68;
  --accent: #ffb000;
  --link: #7fe7ff;
  --fg-body: #9ce690;
  --glow: 0 0 6px rgba(74, 246, 38, .45);
  --glow-soft: 0 0 3px rgba(74, 246, 38, .22);
  --mono: "JetBrains Mono", ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
}
/* `theme amber` swaps the phosphor without touching layout. */
html[data-theme="amber"] {
  --fg: #ffb000; --fg-dim: #9a6a00; --fg-bright: #ffe0a3; --muted: #937a4a;
  --accent: #4af626; --fg-body: #f2ca7a;
  --glow: 0 0 6px rgba(255, 176, 0, .45); --glow-soft: 0 0 3px rgba(255, 176, 0, .22);
}

* { box-sizing: border-box; }
/* The document must never scroll: .screen is the only scroll container. */
html, body { height: 100%; overflow: hidden; overscroll-behavior: none; }
body {
  margin: 0;
  background: radial-gradient(120% 90% at 50% 0%, #0d130c 0%, var(--bg) 45%, var(--bg-deep) 100%);
  color: var(--fg);
  font: 400 15px/1.65 var(--mono);
  /* JetBrains Mono ligatures rewrite ASCII art: ||---- became |+---. */
  font-variant-ligatures: none;
  overflow: hidden;
  -webkit-font-smoothing: antialiased;
}

#rain { position: fixed; inset: 0; width: 100%; height: 100%; z-index: 0; opacity: .5; }
.vignette {
  position: fixed; inset: 0; z-index: 1; pointer-events: none;
  background: radial-gradient(110% 80% at 50% 45%, transparent 40%, rgba(0,0,0,.75) 100%);
}
.scanlines {
  position: fixed; inset: 0; z-index: 3; pointer-events: none; opacity: .35;
  background: repeating-linear-gradient(to bottom, rgba(0,0,0,.35) 0 1px, transparent 1px 3px);
  mix-blend-mode: multiply;
}

.shell {
  position: relative; z-index: 2;
  display: flex; flex-direction: column;
  width: min(980px, 100%);
  /* --app-h tracks visualViewport so an open mobile keyboard shrinks the
     terminal instead of hiding the prompt underneath itself. */
  height: var(--app-h, 100dvh);
  margin: 0 auto;
  padding: clamp(12px, 3vw, 40px) clamp(14px, 4vw, 40px) 0;
}

.titlebar {
  display: flex; align-items: center; gap: 12px;
  padding-bottom: 10px; margin-bottom: 14px;
  border-bottom: 1px solid rgba(74, 246, 38, .18);
  color: var(--muted); font-size: 12px; letter-spacing: .04em;
}
.dots { display: inline-flex; gap: 6px; }
.dots i { width: 9px; height: 9px; border-radius: 50%; background: currentColor; opacity: .4; }
.dots i:first-child { background: #ff5f56; opacity: .8; }
.dots i:nth-child(2) { background: #ffbd2e; opacity: .8; }
.dots i:last-child { background: #27c93f; opacity: .8; }
.title { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }

.screen {
  flex: 1 1 auto;
  overflow-y: auto;
  overflow-x: hidden;
  scrollbar-width: thin;
  scrollbar-color: var(--fg-dim) transparent;
  text-shadow: var(--glow);
  overscroll-behavior: contain;
}
.screen::-webkit-scrollbar { width: 8px; }
.screen::-webkit-scrollbar-thumb { background: var(--fg-dim); border-radius: 8px; }

/* Scroll anchoring fights the pin-to-bottom on every append. */
#out { overflow-anchor: none; }

.line { white-space: pre-wrap; word-break: break-word; min-height: 1.65em; color: var(--fg-body); }
.line.dim { color: var(--muted); text-shadow: none; }
.line.bright { color: var(--fg-bright); text-shadow: var(--glow); }
.line.warn { color: var(--accent); }
.line.err { color: #ff6b5e; text-shadow: 0 0 6px rgba(255,107,94,.4); }
/* The wordmark is an inline SVG, so it needs no font metrics at all. */
.line.banner {
  min-height: 0;
  color: var(--fg-bright);
  margin: 2px 0 6px;
  filter: drop-shadow(0 0 7px rgba(74, 246, 38, .4));
}
.line.banner svg { display: block; width: 100%; height: auto; }

.line.chest {
  min-height: 0;
  color: var(--accent);
  margin: 6px 0 10px;
  filter: drop-shadow(0 0 8px rgba(255, 176, 0, .35));
}
.line.chest svg { display: block; width: min(170px, 50%); height: auto; }

.line.navi {
  min-height: 0;
  color: var(--link);
  margin: 2px 0 8px 3ch;
  filter: drop-shadow(0 0 9px rgba(127, 231, 255, .55));
}
.line.navi svg { display: block; width: min(140px, 40%); height: auto; }

/* Ocarina buttons, drawn as N64 button faces rather than bare arrow glyphs. */
.line.notes {
  display: flex; gap: 7px; align-items: center;
  padding-left: 2ch; min-height: 0; margin: 2px 0 4px;
}
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.85em; height: 1.85em; border-radius: 50%;
  font-size: .82em; font-weight: 700; line-height: 1;
  border: 1px solid; text-shadow: none;
}
.btn.a { color: #9fd8ff; border-color: #4a9fd4; background: rgba(74, 159, 212, .14); }
.btn.c { color: #ffd75e; border-color: #c99a12; background: rgba(255, 213, 74, .14); }

.btn .tri { display: block; width: .78em; height: .78em; fill: currentColor; }
.btn .tri.down { transform: rotate(180deg); }
.btn .tri.left { transform: rotate(-90deg); }
.btn .tri.right { transform: rotate(90deg); }
html[data-theme="amber"] .line.banner { filter: drop-shadow(0 0 7px rgba(255, 176, 0, .4)); }
/* Hanging indent so a wrapped list comment stays under its entry on mobile. */
.line.sub { padding-left: 6ch; }

.line a { color: var(--link); text-underline-offset: 3px; }
.line a:hover { color: var(--fg-bright); background: rgba(127,231,255,.12); }
.line .k { color: var(--accent); }

.inputline {
  position: relative;
  display: flex; align-items: baseline; flex-wrap: wrap;
  padding-bottom: 8px;
  text-shadow: var(--glow);
}
.prompt { color: var(--fg-dim); margin-right: 8px; white-space: nowrap; }
.cmd { color: var(--fg-bright); text-shadow: var(--glow); }
.prompt b { color: var(--fg); font-weight: 700; }
.prompt em { color: var(--link); font-style: normal; }
.typed { white-space: pre-wrap; word-break: break-all; color: var(--fg-bright); }
.caret {
  display: inline-block; width: .58em; height: 1.05em;
  background: var(--fg); transform: translateY(.18em);
  animation: blink 1.05s steps(1) infinite; box-shadow: var(--glow);
}
.caret.off { animation: none; opacity: .35; }
@keyframes blink { 0%, 49% { opacity: 1 } 50%, 100% { opacity: 0 } }

/* The real input is invisible but sits exactly over the prompt line. It must
   stay inside .screen: an absolutely-positioned input parked off-screen escapes
   the scroll container, so the browser scrolls the whole document to reveal it
   on every keystroke and the terminal marches out of view. */
#cmd {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  margin: 0; padding: 0; border: 0; outline: none;
  background: transparent; color: transparent; caret-color: transparent;
  font: inherit;
}

/* In normal flow, not fixed: a floating bar overlapped the prompt whenever the
   mobile keyboard closed on a long screen. */
.chips {
  flex: 0 0 auto;
  display: flex; gap: 8px; justify-content: center; flex-wrap: wrap;
  padding: 10px 0 calc(10px + env(safe-area-inset-bottom));
}
.chips a, .chips button {
  font: inherit; font-size: 12px; color: var(--fg-dim);
  background: rgba(74,246,38,.05); border: 1px solid rgba(74,246,38,.2);
  border-radius: 999px; padding: 5px 12px; cursor: pointer;
  text-decoration: none; transition: color .15s, border-color .15s, background .15s;
}
.chips a:hover, .chips button:hover, .chips a:focus-visible, .chips button:focus-visible {
  color: var(--fg-bright); border-color: var(--fg); background: rgba(74,246,38,.14);
  outline: none; box-shadow: var(--glow);
}

.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;
}

@media (max-width: 560px) {
  body { font-size: 13px; }
  .titlebar .title { font-size: 11px; }
}

@media (prefers-reduced-motion: reduce) {
  .caret { animation: none; }
  #rain { display: none; }
  .scanlines { opacity: .18; }
}


/* Reverse-i-search prompt and its current hit. */
.rprompt { color: var(--accent); white-space: nowrap; margin-right: 8px; }
.rmatch { color: var(--fg-bright); }
.rmatch.miss { color: #ff6b5e; }

/* Snake board: fixed grid, must not reflow. */
/* Square cells, which a character grid cannot give: a glyph is about 0.6 as
   wide as the line is tall, so vertical steps covered twice the ground. */
.line.snake {
  min-height: 0;
  color: var(--fg-bright);
  touch-action: none;
  margin: 4px 0 2px;
}
.line.snake svg {
  display: block;
  width: min(430px, 100%);
  height: auto;
  /* The board is redrawn every tick, so a touch landing on the SVG would have
     its target detached mid-gesture and never reach the listener on the line. */
  pointer-events: none;
  /* Opaque, or the matrix rain shows straight through the play area. */
  background: rgba(3, 6, 3, .82);
  border-radius: 3px;
}
.line.snake .food { opacity: .9; }

/* Time circuit display: the dashboard's own colours, not the theme's. */
.tc-label { color: inherit; opacity: .75; font-size: .82em; letter-spacing: .12em; }
.tc-dest { color: #ff5f56; text-shadow: 0 0 6px rgba(255, 95, 86, .5); }
.tc-now { color: #4af626; text-shadow: 0 0 6px rgba(74, 246, 38, .5); }
.tc-last { color: #ffb000; text-shadow: 0 0 6px rgba(255, 176, 0, .5); }

.line.delorean {
  min-height: 0;
  color: var(--fg-bright);
  margin: 4px 0 6px;
  filter: drop-shadow(0 0 8px rgba(185, 255, 168, .35));
}
.line.delorean svg { display: block; width: min(320px, 92%); height: auto; }

/* The 88 mph jump. */
.flash {
  position: fixed; inset: 0; z-index: 9; pointer-events: none;
  background: #eaf7ff; animation: flashout .65s ease-out forwards;
}
@keyframes flashout { from { opacity: .8 } to { opacity: 0 } }

/* Two-column rows hang their wrapped text under the second column, so it does
   not fall back to column zero and read as another command name. */
.line.row { padding-left: var(--indent); text-indent: calc(var(--indent) * -1); }

/* A brief déjà vu, for `glitch`. */
.shell.glitching { animation: glitch .7s steps(2, end) 3; }
@keyframes glitch {
  0%   { transform: none; filter: none; }
  20%  { transform: translate(-2px, 1px) skewX(-0.6deg); filter: hue-rotate(25deg); }
  45%  { transform: translate(3px, -1px); filter: none; }
  70%  { transform: translate(-1px, 0) skewX(0.4deg); filter: hue-rotate(-20deg); }
  100% { transform: none; filter: none; }
}
@media (prefers-reduced-motion: reduce) { .shell.glitching { animation: none; } }
