/* ed42.com — terminal shell desktop.
 * Tokens vienen de tokens.css (Design System). Aquí solo layout + animaciones.
 */

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  min-height: 100vh;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: var(--lh-normal);
  overflow: hidden;
}

::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: var(--bg); }
::-webkit-scrollbar-thumb { background: var(--ed-red-dim); }
::-webkit-scrollbar-thumb:hover { background: var(--ed-red); }

/* ============================================================
 * SHELL — grid de zonas
 * ============================================================
 * Desktop: 3 columnas (left-rail, terminal, right-rail) + filas
 * topbar, contenido, prompt, hint.
 *
 *   topbar   topbar   topbar
 *   left     term     right
 *   left     prompt   right
 *   hint     hint     hint
 */
.shell {
  display: grid;
  grid-template-areas:
    "topbar topbar topbar"
    "left   term   right"
    "left   prompt right"
    "hint   hint   hint";
  grid-template-rows: auto 1fr auto auto;
  grid-template-columns: minmax(0, 240px) 1fr minmax(0, 240px);
  width: 100vw;
  height: 100vh;
  gap: 0;
}

@media (max-width: 900px) {
  .shell {
    grid-template-areas:
      "topbar"
      "term"
      "prompt"
      "hint";
    grid-template-columns: 1fr;
  }
  .zone-left, .zone-right { display: none; }
}

/* ============================================================
 * ZONAS — chrome común
 * ============================================================ */
.zone {
  position: relative;
  border: var(--bw-1) solid var(--border-dim);
  overflow: hidden;
}

.zone-topbar  { grid-area: topbar;  display: flex; align-items: center; gap: var(--sp-4); padding: var(--sp-2) var(--sp-4); border-top: 0; border-left: 0; border-right: 0; }
.zone-left    { grid-area: left;    border-left: 0; }
.zone-terminal{ grid-area: term;    padding: 0; }
.zone-right   { grid-area: right;   border-right: 0; }
.zone-prompt  { grid-area: prompt;  display: flex; align-items: center; gap: var(--sp-3); padding: var(--sp-3) var(--sp-4); }
.zone-hint    { grid-area: hint;    display: flex; justify-content: space-between; align-items: center; padding: var(--sp-2) var(--sp-4); border-bottom: 0; border-left: 0; border-right: 0; }

/* canvas de fondo por zona — el módulo visual dibuja aquí */
.zone-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  image-rendering: pixelated;
}
.zone-canvas-bg {
  z-index: 0;
}

/* ============================================================
 * TOPBAR
 * ============================================================ */
.topbar-tag {
  font-family: var(--font-pixel);
  letter-spacing: var(--ls-pixel);
  color: var(--fg-strong);
  text-shadow: var(--glow-text);
}
.topbar-status { color: var(--fg-muted); flex: 1; }
.topbar-clock  { color: var(--fg-muted); }

/* ============================================================
 * TERMINAL — log
 * ============================================================ */
.terminal-log {
  position: relative;
  z-index: 1;
  height: 100%;
  overflow-y: auto;
  overflow-x: hidden;
  padding: var(--sp-4);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: var(--lh-normal);
}
.log-line {
  margin: 0 0 var(--sp-1);
  white-space: pre-wrap;
  word-break: break-word;
  overflow-wrap: anywhere;
  max-width: 100%;
}
.log-line[data-kind="operator"] { color: var(--fg-strong); }
.log-line[data-kind="miniedie"] { color: var(--fg); }
.log-line[data-kind="dim"]      { color: var(--fg-muted); }
.log-line[data-kind="cmd"]      { color: var(--fg-strong); font-family: var(--font-pixel); font-size: var(--fs-small); letter-spacing: var(--ls-pixel); }
.log-line[data-kind="ok"]       { color: var(--ed-red-hot); }
.log-line[data-kind="err"]      { color: var(--ed-red-hot); text-shadow: var(--glow-text); }
.log-line[data-kind="warn"]     { color: var(--fg); }
.log-line[data-kind="hot"]      { color: var(--fg-strong); text-shadow: var(--glow-text); }

.log-line-author {
  font-family: var(--font-pixel);
  font-size: var(--fs-micro);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--fg-muted);
  margin-right: var(--sp-2);
}

/* ============================================================
 * PROMPT — terminal-style con block cursor que sigue al input
 * ============================================================
 * Estructura:
 *   .zone-prompt
 *     .prompt-chevron  (prefix estático '>')
 *     .prompt-wrap     (contiene mirror visible + input invisible)
 *       .prompt-mirror (lo que se ve)
 *         .prompt-before (texto antes del cursor)
 *         .prompt-caret  (█ parpadeante)
 *         .prompt-after  (texto después del cursor)
 *       .prompt-input  (captura keys, NO se ve)
 */
.prompt-chevron {
  color: var(--fg-strong);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  text-shadow: 0 0 6px var(--fg-strong), 0 0 14px var(--ed-red-60);
}

.prompt-wrap {
  flex: 1;
  position: relative;
  height: 1.3em;
  display: flex;
  align-items: center;
}

.prompt-mirror {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  color: var(--fg);
  font-family: inherit;
  font-size: inherit;
  white-space: pre;
  pointer-events: none;
  overflow: hidden;
}
.prompt-before, .prompt-after { color: var(--fg); }
.prompt-caret {
  display: inline-block;
  color: var(--fg);
  background: transparent;
  opacity: 0;
  margin: 0 -1px;
  text-shadow: 0 0 6px var(--fg-strong);
}
.prompt-caret.caret-focused {
  animation: ed-blink var(--dur-blink) var(--ease-step) infinite;
  opacity: 1;
}
/* Cuando readonly (sin sesión vivo): cursor apagado */
.prompt-input[readonly] ~ .prompt-mirror .prompt-caret { display: none; }

.prompt-input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  background: transparent;
  border: 0;
  outline: 0;
  color: transparent;             /* texto invisible (lo dibuja el mirror) */
  caret-color: transparent;       /* sin caret nativo */
  font-family: inherit;
  font-size: inherit;
  -webkit-text-fill-color: transparent;
}
.prompt-input::placeholder { color: var(--fg-disabled); }
.prompt-input::selection {
  background: var(--ed-red-40);
  color: transparent;
}

/* ============================================================
 * HINT
 * ============================================================ */
.hint-cell { color: var(--fg-muted); }

/* ============================================================
 * BOX — views de edMirror (kairos, thalia, lyra, etc.)
 * ============================================================ */
.box {
  position: relative;
  border: var(--bw-1) solid var(--border);
  padding: var(--sp-3) var(--sp-4);
  margin: var(--sp-3) 0;
  background: var(--bg);
  /* mobile safety: contenido largo respeta el ancho del box */
  max-width: 100%;
  box-sizing: border-box;
  overflow-wrap: anywhere;
  word-break: break-word;
}

/* Acentos por weaver (espejan el mobile) */
.box[data-accent="amber"]  { --accent: var(--amber, #c88a00);  }
.box[data-accent="cyan"]   { --accent: var(--cyan,  #00a690);  }
.box[data-accent="violet"] { --accent: var(--violet,#8a4ed6);  }
.box[data-accent="default"]{ --accent: var(--ed-red);          }
.box { border-color: var(--accent); }

.box-title {
  font-family: var(--font-pixel);
  font-size: var(--fs-small);
  letter-spacing: var(--ls-pixel);
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: var(--sp-2);
  text-shadow: 0 0 6px color-mix(in srgb, var(--accent) 50%, transparent);
}

.box-line { color: var(--fg); margin: var(--sp-1) 0; }
.box-line[data-kind="dim"]  { color: var(--fg-muted); }
.box-line[data-kind="info"] { color: var(--fg); }

.box-examples {
  color: var(--fg-muted);
  font-size: var(--fs-small);
  margin: var(--sp-1) 0 var(--sp-3);
}

/* HELP — lista de comandos */
.box-cmdlist { display: flex; flex-direction: column; gap: var(--sp-1); }
.box-cmdrow  { display: flex; gap: var(--sp-3); align-items: baseline; }
.box-cmd {
  color: var(--accent);
  min-width: 140px;
  font-family: var(--font-mono);
}
.box-cmddesc { color: var(--fg-muted); }

/* KV — tabla key/value */
.box-kv { display: flex; flex-direction: column; gap: var(--sp-1); margin: var(--sp-2) 0; }
.box-kvrow { display: flex; justify-content: space-between; gap: var(--sp-3); }
.box-k { color: var(--fg-muted); }
.box-v { color: var(--fg-strong); text-align: right; }

/* CLIENTES — tarjetas con bar relativa y tags */
.box-client-card {
  margin: var(--sp-3) 0 var(--sp-4);
  padding-left: var(--sp-3);
  border-left: var(--bw-1) solid var(--ed-red-40);
}
.box-client-hdr {
  display: flex; gap: var(--sp-3); align-items: baseline;
  margin-bottom: var(--sp-2);
  flex-wrap: wrap;
}
.box-client-name { flex: 1; min-width: 0; color: var(--fg-strong); word-break: break-all; }
.box-client-tok  {
  color: var(--fg-strong); min-width: 110px; text-align: right;
  font-family: var(--font-mono);
}
.box-client-tips { color: var(--fg-muted); min-width: 80px; text-align: right; }

.box-client-track {
  position: relative;
  height: 6px;
  background: var(--ed-red-10);
  border: var(--bw-1) solid var(--ed-red-40);
  margin: var(--sp-1) 0 var(--sp-2);
  overflow: hidden;
}
.box-client-fill {
  height: 100%;
  background: var(--ed-red);
  transition: width 900ms cubic-bezier(.2,.7,.3,1);
  position: relative;
}
.box-client-fill[data-coupling="parasocial"]   { background: var(--violet); }
.box-client-fill[data-coupling="ritual"]       { background: var(--phosphor); }
.box-client-fill[data-coupling="co-creativo"]  { background: var(--cyan); }
.box-client-fill[data-coupling="simbiótico"]   { background: var(--cyan); }
.box-client-fill[data-coupling="transaccional"]{ background: var(--amber); }
.box-client-fill[data-coupling="exploratorio"] { background: var(--ed-red-mid); }
.box-client-fill[data-coupling="voyeur"]       { background: var(--ed-red-mid); }

.box-client-tags {
  display: flex; flex-wrap: wrap; gap: var(--sp-1);
  margin: var(--sp-1) 0;
}
.box-client-meta {
  color: var(--fg-muted);
  font-size: var(--fs-small);
  margin-top: var(--sp-1);
}

/* Tags / pills tipo pixel */
.tag {
  display: inline-block;
  padding: 2px var(--sp-2);
  font-family: var(--font-pixel);
  font-size: 11px;
  letter-spacing: var(--ls-pixel);
  text-transform: uppercase;
  border: var(--bw-1) solid currentColor;
  color: var(--fg-muted);
  background: var(--bg);
}
.tag-coupling[data-coupling="parasocial"]   { color: var(--violet); }
.tag-coupling[data-coupling="ritual"]       { color: var(--phosphor); }
.tag-coupling[data-coupling="co-creativo"]  { color: var(--cyan); }
.tag-coupling[data-coupling="simbiótico"]   { color: var(--cyan); }
.tag-coupling[data-coupling="transaccional"]{ color: var(--amber); }
.tag-coupling[data-coupling="exploratorio"] { color: var(--ed-red-mid); }
.tag-coupling[data-coupling="voyeur"]       { color: var(--ed-red-mid); }
.tag-edone { color: var(--fg); }

/* ALERTAS — histogram vertical de severidad + main */
.box-alert {
  display: flex;
  gap: var(--sp-3);
  margin: var(--sp-3) 0;
  align-items: stretch;
}
.box-alert[data-severity="4"] .sev-column .sev-tick[data-active="1"] { background: var(--ed-red-hot); }
.box-alert[data-severity="3"] .sev-column .sev-tick[data-active="1"] { background: var(--accent); }
.box-alert[data-severity="2"] .sev-column .sev-tick[data-active="1"] { background: var(--accent); opacity: 0.7; }
.box-alert[data-severity="1"] .sev-column .sev-tick[data-active="1"] { background: var(--accent); opacity: 0.5; }

.sev-column {
  width: 16px;
  display: flex;
  flex-direction: column-reverse;
  gap: 2px;
  padding-right: var(--sp-1);
  border-right: var(--bw-1) solid var(--ed-red-40);
}
.sev-tick {
  width: 100%;
  background: var(--ed-red-10);
  animation: sev-tick-in 280ms ease-out both;
  transform-origin: bottom;
}
.sev-tick[data-active="0"] { background: var(--ed-red-10); }
.sev-tick:nth-child(1) { animation-delay: 0ms;   }
.sev-tick:nth-child(2) { animation-delay: 80ms;  }
.sev-tick:nth-child(3) { animation-delay: 160ms; }
.sev-tick:nth-child(4) { animation-delay: 240ms; }
@keyframes sev-tick-in {
  0%   { transform: scaleY(0); }
  100% { transform: scaleY(1); }
}

/* flex children con texto: min-width:0 evita overflow horizontal */
.box-alert-main { flex: 1; min-width: 0; }
.box-alert-hdr {
  display: flex; gap: var(--sp-3); align-items: baseline;
  margin-bottom: var(--sp-1);
  flex-wrap: wrap;
}
.box-alert-sev  {
  color: var(--accent);
  font-family: var(--font-pixel);
  font-size: var(--fs-micro);
  letter-spacing: var(--ls-pixel);
}
.box-alert[data-severity="4"] .box-alert-sev { color: var(--ed-red-hot); }
.box-alert-type { color: var(--fg); flex: 1; }
.box-alert-when { color: var(--fg-muted); font-size: var(--fs-small); }
.box-alert-desc { color: var(--fg-muted); font-size: var(--fs-small); }

/* BARS — para sesion (con scanline texture interno) */
.box-bars { display: flex; flex-direction: column; gap: var(--sp-2); margin: var(--sp-3) 0 0; }
.box-bar  { display: flex; gap: var(--sp-3); align-items: center; }
.box-bar-label { min-width: 170px; color: var(--fg-muted); font-size: var(--fs-small); }
.box-bar-track {
  flex: 1; height: 10px;
  background: var(--ed-red-10);
  border: var(--bw-1) solid var(--accent);
  position: relative;
  overflow: hidden;
}
.box-bar-fill {
  height: 100%;
  background: var(--accent);
  background-image: repeating-linear-gradient(
    90deg,
    transparent 0,
    transparent 3px,
    rgba(0,0,0,0.25) 3px,
    rgba(0,0,0,0.25) 4px
  );
  animation: bar-scan-drift 1200ms steps(6, end) infinite;
}
@keyframes bar-scan-drift {
  0%   { background-position: 0 0; }
  100% { background-position: 4px 0; }
}
.box-bar-num  {
  min-width: 50px; text-align: right;
  color: var(--fg); font-size: var(--fs-small);
  font-family: var(--font-mono);
}

/* ============================================================
 * EFECTOS — counting, scramble, glitch flash, pulse
 * ============================================================ */

/* Counter activo — número que está siendo animado */
.box-v.counting,
.box-client-tok.counting,
.box-client-tips.counting,
.box-bar-num.counting {
  color: var(--fg-strong);
  text-shadow: 0 0 6px var(--accent);
}

/* Glitch flash — flash rápido del border del box al renderizar */
.box.glitch-flash {
  animation: box-flash 240ms steps(3, end);
}
@keyframes box-flash {
  0%   { box-shadow: 0 0 0 2px var(--accent); }
  50%  { box-shadow: 0 0 18px 2px var(--accent); }
  100% { box-shadow: 0 0 0 0 transparent; }
}

/* Glitch scanline — línea horizontal que cruza el box brevemente */
.glitch-scanline {
  position: absolute;
  left: -2%;
  right: -2%;
  height: 2px;
  background: var(--accent);
  box-shadow: 0 0 8px var(--accent);
  pointer-events: none;
  animation: scan-cross 120ms steps(8, end);
  z-index: 2;
}
@keyframes scan-cross {
  0%   { transform: translateX(-100%); opacity: 0; }
  20%  { opacity: 1; }
  100% { transform: translateX(100%); opacity: 0; }
}

/* Pulse — atención rítmica para items críticos (sev=4, valores altos) */
.pulse-emphasis {
  animation: pulse-emph var(--pulse-duration, 600ms) ease-in-out var(--pulse-count, 3);
  color: var(--fg-strong);
}
@keyframes pulse-emph {
  0%, 100% { text-shadow: 0 0 0 transparent; }
  50%      { text-shadow: 0 0 12px var(--accent), 0 0 4px var(--fg-strong); }
}

/* Spinner (loading) — los puntos rotativos al final de una línea dim */
.spinner-dots {
  display: inline-block;
  min-width: 24px;
  color: var(--fg-strong);
}

/* Typewriter — durante la escritura, cursor parpadeante al final del título */
.box-title.typewriter-active::after {
  content: '_';
  margin-left: 2px;
  animation: ed-blink var(--dur-blink) var(--ease-step) infinite;
  color: var(--accent);
}

/* Fade-in escalonado de los items dentro de un Box. Animación rápida +
 * stagger leve para que se sienta vintage sin demorar lectura. */
@keyframes box-item-in {
  0%   { opacity: 0; transform: translateY(2px); }
  100% { opacity: 1; transform: translateY(0); }
}
.box-line,
.box-kvrow,
.box-client,
.box-client-edone,
.box-client-coupling,
.box-alert,
.box-bar,
.box-cmdrow,
.box-narrative,
.box-meta,
.box-subtitle,
.box-examples {
  animation: box-item-in 180ms ease-out both;
}
.box .box-kvrow:nth-child(1)      { animation-delay: 40ms;  }
.box .box-kvrow:nth-child(2)      { animation-delay: 80ms;  }
.box .box-kvrow:nth-child(3)      { animation-delay: 120ms; }
.box .box-kvrow:nth-child(4)      { animation-delay: 160ms; }
.box .box-kvrow:nth-child(5)      { animation-delay: 200ms; }
.box .box-kvrow:nth-child(6)      { animation-delay: 240ms; }
.box .box-kvrow:nth-child(n+7)    { animation-delay: 280ms; }
.box .box-alert:nth-child(odd)    { animation-delay: 100ms; }
.box .box-alert:nth-child(even)   { animation-delay: 200ms; }
.box .box-bar:nth-child(1)        { animation-delay: 100ms; }
.box .box-bar:nth-child(2)        { animation-delay: 180ms; }
.box .box-bar:nth-child(3)        { animation-delay: 260ms; }
.box .box-bar:nth-child(n+4)      { animation-delay: 340ms; }
/* Llenado de las bars: width animada (de la línea inline-style) */
.box-bar-fill {
  transition: width 600ms cubic-bezier(.2,.7,.3,1);
}

/* ============================================================
 * HIVE BARS — bands horizontales animadas (Animal Hive vibe)
 * ============================================================ */
.hive-bars {
  display: flex;
  align-items: flex-end;
  gap: 3px;
  height: 14px;
  margin: var(--sp-2) 0 var(--sp-3);
  width: 100%;
}
.hive-bars-thin { height: 6px; gap: 2px; margin: var(--sp-3) 0; }
.hive-bars-sep  { opacity: 0.85; }

.hive-bar {
  flex: 1;
  min-width: 2px;
  background: var(--accent);
  box-shadow: 0 0 4px var(--accent), inset 0 0 1px rgba(0,0,0,0.4);
  animation: hive-pulse 1400ms ease-in-out infinite;
  transform-origin: bottom;
}
.hive-bars-thin .hive-bar {
  box-shadow: 0 0 3px var(--accent);
}
@keyframes hive-pulse {
  0%, 100% { transform: scaleY(0.85); opacity: 0.65; }
  50%      { transform: scaleY(1.05); opacity: 1; }
}

/* SUBTITLE — sub-secciones dentro de un Box (ej: alertas dentro de /cliente) */
.box-subtitle {
  font-family: var(--font-pixel);
  font-size: var(--fs-micro);
  letter-spacing: var(--ls-pixel);
  text-transform: uppercase;
  color: var(--fg-muted);
  margin: var(--sp-3) 0 var(--sp-1);
}

/* ============================================================
 * MARKDOWN — renderer block-level (tablas, headers, listas, code)
 * ============================================================ */
.box-md {
  margin: var(--sp-2) 0;
  color: var(--fg);
}

.md-h {
  font-family: var(--font-pixel);
  letter-spacing: var(--ls-pixel);
  text-transform: uppercase;
  color: var(--accent);
  text-shadow: 0 0 6px var(--accent),
               0.5px 0 0 rgba(255, 0, 85, 0.5),
               -0.5px 0 0 rgba(0, 200, 255, 0.25);
  margin: var(--sp-4) 0 var(--sp-2);
}
.md-h1 { font-size: var(--fs-h2); }
.md-h2 { font-size: var(--fs-h3); }
.md-h3 { font-size: var(--fs-small); }
.md-h4 { font-size: var(--fs-small); color: var(--fg-strong); }
.md-h5 { font-size: var(--fs-micro); color: var(--fg-muted); }
.md-h6 { font-size: var(--fs-micro); color: var(--fg-muted); opacity: 0.7; }

.md-p {
  margin: var(--sp-2) 0;
  white-space: pre-wrap;
  line-height: var(--lh-loose);
}

/* Inline markdown — bold / italic / code dentro de cualquier reveal */
.md-bold {
  color: var(--fg-strong);
  text-shadow: 0 0 6px var(--accent);
  /* VT323 no tiene un "bold" real, lo simulamos con shadow + color */
  filter: brightness(1.15);
}
.md-italic {
  color: var(--fg-strong);
  font-style: italic;
}
.md-inline-code {
  font-family: var(--font-mono);
  background: rgba(255, 0, 85, 0.10);
  border: var(--bw-1) solid var(--ed-red-40);
  padding: 0 var(--sp-1);
  color: var(--ed-red-hot);
}

.md-list {
  margin: var(--sp-2) 0;
  padding-left: 0;
  list-style: none;
}
ol.md-list { counter-reset: md-counter; }

.md-li {
  margin: var(--sp-1) 0;
  line-height: var(--lh-normal);
  /* NO flex: dentro del li hay muchos spans (un span por palabra de
   * revealText). Con display:flex se vuelven flex-items y se squeeze
   * a min-content (1 char por columna). Mantener flujo inline normal. */
}

/* Marker del ul — inline, fluye con el texto */
ul.md-list .md-li::before {
  content: '▸ ';
  color: var(--accent);
}

/* Marker del ol — inline-block para reservar ancho fijo del número */
ol.md-list .md-li {
  counter-increment: md-counter;
}
ol.md-list .md-li::before {
  content: counter(md-counter) ".";
  color: var(--accent);
  font-family: var(--font-mono);
  display: inline-block;
  min-width: 1.6em;
  margin-right: var(--sp-2);
  text-align: right;
}

.md-table-wrap {
  overflow-x: auto;
  margin: var(--sp-3) 0;
  border: var(--bw-1) solid var(--accent);
}
.md-table {
  border-collapse: collapse;
  width: 100%;
  font-size: var(--fs-small);
  font-family: var(--font-mono);
}
.md-table th, .md-table td {
  border: var(--bw-1) solid var(--ed-red-40);
  padding: var(--sp-1) var(--sp-2);
  text-align: left;
  vertical-align: top;
  word-break: break-word;
}
.md-table th {
  background: var(--ed-red-10);
  color: var(--accent);
  font-family: var(--font-pixel);
  font-size: var(--fs-micro);
  letter-spacing: var(--ls-pixel);
  text-transform: uppercase;
  text-shadow: 0 0 4px var(--accent);
}
.md-table tbody tr:nth-child(even) { background: rgba(255, 0, 85, 0.04); }
.md-table td { color: var(--fg); }

.md-code {
  font-family: var(--font-mono);
  background: rgba(255, 0, 85, 0.06);
  border: var(--bw-1) solid var(--ed-red-40);
  padding: var(--sp-3);
  white-space: pre-wrap;
  overflow-x: auto;
  font-size: var(--fs-small);
  color: var(--ed-red-hot);
  margin: var(--sp-2) 0;
}
.md-code[data-lang]::before {
  content: attr(data-lang);
  display: block;
  margin: 0 0 var(--sp-2);
  font-family: var(--font-pixel);
  font-size: var(--fs-micro);
  letter-spacing: var(--ls-pixel);
  text-transform: uppercase;
  color: var(--fg-muted);
}

.md-hr {
  border: 0;
  height: 0;
  margin: var(--sp-4) 0;
  background: linear-gradient(to right,
    transparent 0%,
    var(--accent) 30%,
    var(--accent) 70%,
    transparent 100%);
  height: var(--bw-2);
  box-shadow: 0 0 6px var(--accent);
}

/* NARRATIVA — texto largo */
.box-narrative {
  color: var(--fg);
  white-space: pre-wrap;
  line-height: var(--lh-loose);
  margin: var(--sp-2) 0;
}
.box-meta { color: var(--fg-muted); font-size: var(--fs-small); }

/* ============================================================
 * ESTADOS DEL SHELL (data-state)
 * ============================================================
 * boot     — primer load, antes de cualquier auth
 * roto     — sin sesión válida; modo glitchy
 * vivo     — sesión validada, terminal activo
 * dead     — (futuro) modo cerrado
 */
.shell[data-state="roto"] .prompt-input {
  pointer-events: none;
  color: var(--fg-disabled);
}
.shell[data-state="roto"] {
  animation: ed-flicker 4s steps(8, end) infinite;
}

/* ============================================================
 * ANIMACIONES BASE
 * ============================================================ */
@keyframes ed-blink {
  0%, 49% { opacity: 1; }
  50%, 100% { opacity: 0; }
}
@keyframes ed-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.55; }
}
@keyframes ed-flicker {
  0%, 100% { opacity: 1; }
  3%   { opacity: 0.8; }
  6%   { opacity: 1; }
  50%  { opacity: 0.98; }
  52%  { opacity: 0.85; }
  54%  { opacity: 1; }
}
@keyframes ed-scan-drift {
  0%   { background-position: 0 0; }
  100% { background-position: 0 3px; }
}
@keyframes ed-glow-pulse {
  0%, 100% { text-shadow: 0 0 8px var(--ed-red-60); }
  50%      { text-shadow: 0 0 14px var(--ed-red), 0 0 4px var(--ed-red-hot); }
}

/* ============================================================
 * CRT AMBIENT — scanlines densas, vignette curva, chromatic
 * aberration, flicker global, tearing, char swap.
 * ============================================================ */

/* Scanlines DENSAS (1px linea / 1px gap, drift más visible) */
.scanlines::after {
  background:
    repeating-linear-gradient(
      to bottom,
      transparent 0,
      transparent 1px,
      rgba(255, 0, 85, 0.10) 1px,
      rgba(255, 0, 85, 0.10) 2px
    );
  animation: ed-scan-drift 1400ms steps(6, end) infinite;
}

/* Vignette curva — esquinas oscuras puras via box-shadow inset.
 * Sin background ni mix-blend (que oscurecerían texto innecesariamente).
 * pointer-events: none → no roba clicks. */
.shell::before {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 9000;
  box-shadow:
    inset 0  0  80px 10px rgba(0,0,0,0.65),
    inset 0  0  180px 40px rgba(0,0,0,0.30);
}

/* Phosphor afterglow permanente en cursor del prompt y chevron */
.prompt-chevron, .cursor::after {
  text-shadow: 0 0 6px var(--fg-strong), 0 0 14px var(--ed-red-60);
}

/* Chromatic aberration SUTIL permanente en titles y topbar */
.box-title {
  /* Sobreescribe el text-shadow anterior con RGB split + glow accent */
  text-shadow:
    0 0 6px color-mix(in srgb, var(--accent) 55%, transparent),
    0.6px 0 0 rgba(255, 0, 85, 0.55),
    -0.6px 0 0 rgba(0, 200, 255, 0.30) !important;
}
.topbar-tag {
  text-shadow:
    0.5px 0 0 rgba(255, 0, 85, 0.5),
    -0.5px 0 0 rgba(0, 200, 255, 0.25),
    0 0 8px var(--ed-red-60);
}

/* Flicker leve ambient del body — siempre activo, muy sutil */
body {
  animation: crt-body-flicker 5800ms steps(40, end) infinite;
}
@keyframes crt-body-flicker {
  0%, 100% { filter: brightness(1.00) contrast(1.05); }
  47%      { filter: brightness(0.97) contrast(1.06); }
  50%      { filter: brightness(1.04) contrast(1.04); }
  53%      { filter: brightness(0.99) contrast(1.05); }
}

/* ── CRT effects controlados por crt.js ──────────────────────────────── */

/* Tearing — shake horizontal breve + brightness flash */
.shell.crt-tear {
  animation: crt-tear-shake 110ms steps(4, end);
}
@keyframes crt-tear-shake {
  0%   { transform: translateX(0)  skewX(0);      filter: none; }
  25%  { transform: translateX(-4px) skewX(0.4deg); filter: brightness(1.25) contrast(1.2); }
  50%  { transform: translateX(3px)  skewX(-0.3deg); filter: brightness(0.85); }
  75%  { transform: translateX(-1px) skewX(0.15deg); }
  100% { transform: translateX(0)    skewX(0); filter: none; }
}

/* Flicker global — opacity blink */
.shell.crt-flicker {
  animation: crt-global-flicker 90ms steps(3, end);
}
@keyframes crt-global-flicker {
  0%, 100% { opacity: 1; }
  33%      { opacity: 0.72; }
  66%      { opacity: 0.92; }
}

/* ── Bot reply burst — glitch invasivo cuando el bot responde ─────────── */
.shell.bot-reply-burst {
  animation: bot-burst-shake 380ms steps(9, end);
}
@keyframes bot-burst-shake {
  0%   { transform: translate(0); filter: none; }
  10%  { transform: translate(-9px, 3px) skew(0.9deg, 0); filter: brightness(1.6) contrast(1.3) saturate(1.5); }
  22%  { transform: translate(7px, -2px) skew(-0.5deg, 0); filter: brightness(0.55) invert(0.05) hue-rotate(15deg); }
  34%  { transform: translate(-4px, 1px); filter: brightness(1.35) contrast(1.2); }
  48%  { transform: translate(3px, -1px) skew(0.3deg, 0); filter: brightness(0.85); }
  62%  { transform: translate(-2px, 0); filter: brightness(1.1) contrast(1.05); }
  78%  { transform: translate(1px, 0); filter: brightness(0.97); }
  100% { transform: translate(0); filter: none; }
}

/* Overlay flash blanco → scanlines extra densas → fade out */
.bot-reply-overlay {
  position: absolute;
  inset: 0;
  z-index: 9998;
  pointer-events: none;
  animation: bot-burst-overlay 380ms steps(7, end);
}
@keyframes bot-burst-overlay {
  0%   { background: transparent; }
  10%  { background: rgba(255, 255, 255, 0.28); }
  20%  { background: rgba(255, 0, 85, 0.18); }
  32%  {
    background: repeating-linear-gradient(
      to bottom,
      transparent 0, transparent 1px,
      rgba(255, 0, 85, 0.42) 1px, rgba(255, 0, 85, 0.42) 2px
    );
  }
  46%  {
    background: repeating-linear-gradient(
      to bottom,
      transparent 0, transparent 1px,
      rgba(255, 255, 255, 0.18) 1px, rgba(255, 255, 255, 0.18) 2px
    );
  }
  62%  {
    background: linear-gradient(to bottom,
      transparent 0%,
      rgba(255, 0, 85, 0.22) 50%,
      transparent 100%);
  }
  100% { background: transparent; }
}

/* Scanline brillante que cruza el shell entero (más fuerte que crt-scan-flash) */
.bot-reply-scan {
  position: absolute;
  left: -2%;
  right: -2%;
  height: 4px;
  background: linear-gradient(to right,
    transparent 0%,
    #ffffff 10%,
    var(--ed-red-hot) 40%,
    var(--ed-red) 50%,
    var(--ed-red-hot) 60%,
    #ffffff 90%,
    transparent 100%);
  box-shadow: 0 0 22px var(--ed-red-hot), 0 0 8px #fff;
  pointer-events: none;
  z-index: 9999;
  animation: bot-burst-scan 280ms steps(8, end);
}
@keyframes bot-burst-scan {
  0%   { transform: translateX(-110%); opacity: 0; }
  15%  { opacity: 1; }
  85%  { opacity: 1; }
  100% { transform: translateX(110%); opacity: 0; }
}

/* Tracking error — desalineo horizontal breve (VCR vintage). Solo
 * el contenido (no el border): aplicamos en log + zones, no en shell. */
.shell.crt-tracking #log {
  animation: crt-tracking-y 140ms steps(5, end);
}
.shell.crt-tracking .zone-prompt,
.shell.crt-tracking .zone-hint {
  animation: crt-tracking-x 140ms steps(5, end);
}
@keyframes crt-tracking-y {
  0%   { transform: translate(0, 0); }
  20%  { transform: translate(-3px, 1px); }
  40%  { transform: translate(2px, -1px); }
  60%  { transform: translate(-1px, 0); }
  80%  { transform: translate(1px, 0); }
  100% { transform: translate(0, 0); }
}
@keyframes crt-tracking-x {
  0%, 100% { transform: translate(0, 0); }
  50%      { transform: translate(2px, 0); }
}

/* Scan flash — scanline brillante que cruza el log */
.crt-scan-flash {
  position: absolute;
  left: -2%;
  right: -2%;
  height: 2px;
  background: linear-gradient(
    to right,
    transparent 0%,
    var(--ed-red-hot) 20%,
    var(--ed-red) 50%,
    var(--ed-red-hot) 80%,
    transparent 100%
  );
  box-shadow: 0 0 12px var(--ed-red), 0 0 4px var(--ed-red-hot);
  pointer-events: none;
  z-index: 100;
  animation: scan-flash-cross 200ms steps(6, end);
}
@keyframes scan-flash-cross {
  0%   { transform: translateX(-100%); opacity: 0; }
  20%  { opacity: 1; }
  85%  { opacity: 1; }
  100% { transform: translateX(100%); opacity: 0; }
}

/* Chromatic aberration glitch temporal — afecta solo titles y topbar */
.shell.crt-chroma .box-title,
.shell.crt-chroma .topbar-tag,
.shell.crt-chroma .topbar-clock,
.shell.crt-chroma .hint-cell {
  text-shadow:
    2px 0 0 rgba(255, 0, 85, 0.85),
    -2px 0 0 rgba(0, 220, 255, 0.65),
    0 0 6px var(--accent, var(--ed-red)) !important;
  animation: crt-chroma-jitter 240ms steps(6, end);
}
@keyframes crt-chroma-jitter {
  0%   { transform: translateX(0); }
  20%  { transform: translateX(-1.5px); }
  40%  { transform: translateX(1px); }
  60%  { transform: translateX(-0.5px); }
  80%  { transform: translateX(1px); }
  100% { transform: translateX(0); }
}

/* scanlines drift sutil (override del .scanlines del tokens.css) */
