/* ============================================================
   STYLE — Mariscal Vorlan
   Movil primero, portrait, contenedor centrado como app (max 430px).
   Paleta colorida y luminosa, coherente con la direccion cartoon.
   ============================================================ */

:root {
  --bg: #f4ede0;            /* crema */
  --app-bg: #fffaf0;
  --ink: #2b2118;
  /* Texto secundario. Oscurecido en 012: el #8a7a66 anterior daba 4.16:1 sobre
     la tarjeta blanca y 4.0:1 sobre el fondo de la app, por debajo del 4.5:1 de
     WCAG AA para texto normal. */
  --muted: #756751;
  /* Y una version aun mas oscura para el texto apagado sobre `--line` (botones
     no comprables), donde ni `--muted` llega al 4.5:1. */
  --muted-strong: #6b5c48;
  --red: #c9302c;          /* rojo propaganda */
  --red-dark: #9c211d;
  --gold: #e6b800;
  --green: #3c9a5f;
  /* Verde oscurecido para lo que lleva TEXTO encima o es texto: blanco sobre
     `--green` se queda en 3.5:1 (012). Se sigue usando `--green` para el relleno
     claro del degradado de la barra, que no lleva texto. */
  --green-dark: #2f7a4b;
  --line: #e3d6c0;
  --card: #ffffff;
  --shadow: 0 2px 6px rgba(80, 55, 25, 0.12);
  --radius: 14px;
  --tap: 44px;             /* objetivo tactil minimo */
  /* Crema del ARTE (013), que no es la del CSS: los dioramas salen sobre un
     fondo que va de #F3E6C8 a #F0E2C5 segun la pieza, y la tarjeta es blanca.
     El marco lleva este crema para que la diferencia de tono entre piezas no se
     vea como un cuadrado pegado encima. Las dos paletas siguen separadas. */
  --art-cream: #f3e9d2;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  -webkit-text-size-adjust: 100%;
}

body {
  /* Sin zoom doble-tap ni menu de seleccion accidental en movil. */
  touch-action: manipulation;
  display: flex;
  justify-content: center;
  min-height: 100vh;
}

.app {
  width: 100%;
  max-width: 430px;
  min-height: 100vh;
  background: var(--app-bg);
  display: flex;
  flex-direction: column;
  /* Respeta el notch/safe-area en moviles. */
  padding: env(safe-area-inset-top) env(safe-area-inset-right)
           env(safe-area-inset-bottom) env(safe-area-inset-left);
}

/* --- Cabecera --------------------------------------------------------- */
/* Cabecera + pestañas pegadas arriba: la lista de instituciones (hasta 11
   tarjetas) hace scroll debajo sin perder los contadores ni las pestañas. */
.topbar-wrap {
  position: sticky;
  top: 0;
  z-index: 6;
}
.topbar {
  display: flex;
  gap: 12px;
  padding: 14px 16px;
  background: linear-gradient(135deg, var(--red), var(--red-dark));
  color: #fff;
}

.portrait {
  flex: 0 0 auto;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: var(--gold) radial-gradient(circle at 50% 35%, #fff6cf, var(--gold));
  border: 3px solid #fff;
  box-shadow: var(--shadow);
  position: relative;
}
/* Cara placeholder del Mariscal. Las piezas de la etapa (010) se dibujan
   encima y alrededor; esta siempre esta. */
.portrait::after {
  content: "★";
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 28px;
  color: var(--red-dark);
}

/* Busto de la etapa (013). Solo existe con `has-art`, es decir cuando la etapa
   declara imagen Y el archivo carga; si falla, ui.js quita la clase y vuelven
   las piezas de debajo, que se pintan siempre. El recorte a circulo va en la
   clase y no en `.portrait` a proposito: sin arte, las piezas TIENEN que poder
   salirse del circulo. */
.portrait.has-art { overflow: hidden; }
.portrait.has-art::after { content: none; }      /* fuera la estrella placeholder */
.portrait.has-art .vorlan-piece { display: none; }
.vorlan-art {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  /* `cover`: el busto sale cuadrado sobre crema y el retrato es un circulo, asi
     que se recorta en vez de dejar franjas dentro del oro. */
  object-fit: cover;
  border-radius: 50%;
  pointer-events: none;
  user-select: none;
  -webkit-user-select: none;
}

/* --- Banner de escenario (014) ----------------------------------------- */
/* Dos capas: el despacho de la etapa y el Mariscal recortado encima, a la
   izquierda y apoyado en el borde de abajo. Igual que en 013, TODO cuelga de una
   clase —`has-scene`, en el contenedor de la app— que ui.js pone solo cuando han
   cargado las DOS imagenes. Sin ella estas reglas no existen y la cabecera es
   byte a byte la de 013, con su barra roja y su retrato de 56 px. */
.scene { display: none; }
.has-scene .scene {
  display: block;
  position: relative;
  /* Proporcion 16:9 por padding y no por `aspect-ratio`: es la unica forma que
     funciona igual en cualquier webview, y el puerto a movil llega despues. */
  width: 100%;
  height: 0;
  padding-top: 56.25%;
  overflow: hidden;
  /* Se ve mientras cargan las imagenes y detras del recorte: el crema del ARTE,
     no el de la paleta, para que no haya escalon con el borde del banner. */
  background: var(--art-cream);
}
.scene-bg,
.scene-figure {
  position: absolute;
  pointer-events: none;
  user-select: none;
  -webkit-user-select: none;
}
.scene-bg {
  inset: 0;
  width: 100%;
  height: 100%;
  /* Los escenarios son 16:9 como el marco, asi que `cover` no recorta nada; esta
     por si alguna pieza futura no lo es. */
  object-fit: cover;
}
/* El Mariscal, en porcentajes para que el encuadre aguante de 375 a 430 px sin
   media queries: el tercio izquierdo del escenario se genero despejado justo
   para esto. `bottom: 0` lo apoya en el borde inferior, que es lo que lo hace
   leer como una persona de pie en la sala y no como una pegatina. */
.scene-figure {
  left: 3%;
  bottom: 0;
  height: 96%;
  width: auto;
}

/* Con banner, el degradado rojo del HUD sobra: los contadores pasan a crema y
   tinta. El retrato de 56 px se oculta —Vorlan ya esta en el banner, grande— y
   con el se va el circulo dorado; su aria-label lo hereda el banner, asi que la
   etapa se sigue anunciando. */
.has-scene .topbar {
  background: var(--art-cream);
  color: var(--ink);
}
.has-scene .portrait { display: none; }
/* Sobre crema, `--muted` se queda en 4,56:1 con estos 10 px en mayusculas;
   `--muted-strong` da 5,35:1 y deja margen (mismo criterio que 012). */
.has-scene .stat-label { color: var(--muted-strong); }

/* --- Piezas del retrato de Vorlan (010) -------------------------------- */
/* ui.js pinta un <span class="vorlan-piece piece-X"> por pieza de la etapa;
   TODO el dibujo vive aqui. Desde 013 son el FALLBACK del busto (DEC-MV-013):
   se siguen pintando siempre y solo las tapa `.portrait.has-art`, asi que una
   etapa sin arte, o con el archivo ausente, luce estos placeholders. Se quedan
   hasta que existan las nueve piezas. Van fuera del circulo sin recortarse, asi
   que el retrato no lleva overflow: hidden (lo lleva `has-art`). */
.vorlan-piece {
  position: absolute;
  pointer-events: none;
  line-height: 1;
}
.piece-medal  { bottom: -2px; left: -4px; font-size: 16px; }
.piece-medal::after  { content: "🎖"; }
.piece-medals { bottom: -2px; right: -4px; font-size: 16px; }
.piece-medals::after { content: "🏅"; }
.piece-glasses { top: 16px; left: 50%; transform: translateX(-50%); font-size: 15px; z-index: 2; }
.piece-glasses::after { content: "🕶"; }
.piece-crown  { top: -14px; left: 50%; transform: translateX(-50%); font-size: 18px; }
.piece-crown::after  { content: "👑"; }
/* Banda presidencial: una diagonal sobre el pecho, no un emoji. */
.piece-sash {
  inset: 0;
  border-radius: 50%;
  background: linear-gradient(60deg, transparent 38%, var(--red) 38%, var(--red) 56%, transparent 56%);
  opacity: 0.85;
}
/* Charreteras: dos cuadrados dorados a los lados. */
.piece-epaulettes {
  inset: 0;
}
.piece-epaulettes::before, .piece-epaulettes::after {
  content: "";
  position: absolute;
  bottom: 4px;
  width: 10px;
  height: 6px;
  border-radius: 2px;
  background: var(--gold);
  border: 1px solid #fff;
}
.piece-epaulettes::before { left: -6px; }
.piece-epaulettes::after  { right: -6px; }
/* Baston ceremonial: una barra inclinada al lado del retrato. */
.piece-cane {
  right: -10px;
  top: 4px;
  width: 4px;
  height: 46px;
  border-radius: 2px;
  background: linear-gradient(var(--gold), var(--red-dark));
  transform: rotate(12deg);
}
/* Capa: un abanico rojo POR DETRAS del circulo. */
.piece-cape {
  left: 50%;
  top: 8px;
  width: 76px;
  height: 58px;
  margin-left: -38px;
  z-index: -1;
  border-radius: 0 0 50% 50%;
  background: linear-gradient(var(--red), var(--red-dark));
  box-shadow: var(--shadow);
}
/* Halo: el ultimo escalon de la megalomania. */
.piece-halo {
  left: 50%;
  top: -12px;
  width: 44px;
  height: 12px;
  margin-left: -22px;
  border: 2px solid var(--gold);
  border-radius: 50%;
  background: transparent;
}

.topbar-main { flex: 1 1 auto; min-width: 0; }

.title {
  font-size: 20px;
  font-weight: 800;
  letter-spacing: 0.5px;
  line-height: 1.1;
}
/* El titulo de Vorlan crece con las etapas (010) y puede ocupar tres lineas a
   390 px: envuelve, nunca se trunca ni desmonta la cabecera. */
.subtitle {
  font-size: 12px;
  opacity: 0.9;
  font-style: italic;
  margin-top: 2px;
  line-height: 1.25;
  overflow-wrap: anywhere;
}

.stats {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px 12px;
  margin-top: 10px;
}
.stat { display: flex; align-items: baseline; gap: 6px; min-width: 0; }
/* El Poder Nacional ocupa las dos columnas (ver index.html). */
.stat-wide { grid-column: 1 / -1; }
/* El numero manda: si falta sitio se encoge la ETIQUETA, nunca el valor (un
   Poder truncado a "6,1..." no informa de nada). */
.stat-value {
  flex: 0 0 auto;
  font-size: 15px;
  font-weight: 700;
  white-space: nowrap;
}
.stat-label {
  flex: 0 1 auto;
  min-width: 0;
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  /* Sin opacidad: al 85% el blanco sobre el rojo de la cabecera bajaba a 4.2:1.
     La jerarquia ya la marcan el tamaño y las mayusculas (012). */
}

/* --- Pestañas --------------------------------------------------------- */
.tabs {
  display: flex;
  background: var(--app-bg);
  border-bottom: 2px solid var(--line);
  /* La adherencia la aporta .topbar-wrap; las pestañas ya van dentro de el. */
}
.tab {
  flex: 1;
  min-height: var(--tap);
  border: none;
  background: none;
  font: inherit;
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 1px;
  color: var(--muted);
  padding: 12px 8px;
  cursor: pointer;
  border-bottom: 3px solid transparent;
}
.tab.is-active {
  color: var(--red);
  border-bottom-color: var(--red);
}
.tab:focus-visible {
  outline: 3px solid var(--gold);
  outline-offset: -3px;
}

/* --- Pantallas -------------------------------------------------------- */
.screens { flex: 1 1 auto; }
.screen { padding: 14px 16px 28px; }
.screen[hidden] { display: none; }

/* --- Plan Quinquenal -------------------------------------------------- */
.plan {
  background: #fff8e6;
  border: 2px solid var(--gold);
  border-radius: var(--radius);
  padding: 10px 14px;
  margin-bottom: 14px;
}
.plan-title {
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 1.5px;
  color: var(--red-dark);
}
.plan-goal { font-size: 15px; font-weight: 600; margin-top: 3px; }

/* --- Boost publicitario simulado (007) ------------------------------- */
/* Un solo boton, dos estados claramente distintos: disponible (contorno
   dorado sobre crema) y activo (relleno dorado con el contador). */
.boost {
  width: 100%;
  min-height: var(--tap);
  margin-bottom: 14px;
  border: 2px dashed var(--gold);
  border-radius: 10px;
  background: var(--card);
  color: var(--red-dark);
  font: inherit;
  font-weight: 800;
  font-size: 13px;
  letter-spacing: 0.5px;
  cursor: pointer;
}
.boost:focus-visible { outline: 3px solid var(--red); outline-offset: 2px; }
.boost.is-active {
  border-style: solid;
  background: var(--gold);
  border-color: var(--red-dark);
  color: var(--ink);
  /* El contador cambia cada segundo: tabular para que no baile de ancho. */
  font-variant-numeric: tabular-nums;
}

/* --- Selector de compra ---------------------------------------------- */
.buymodes {
  display: flex;
  gap: 8px;
  margin-bottom: 14px;
}
.buymode {
  flex: 1;
  min-height: var(--tap);
  border: 2px solid var(--line);
  background: var(--card);
  border-radius: 10px;
  font: inherit;
  font-weight: 700;
  color: var(--muted);
  cursor: pointer;
}
.buymode.is-active {
  border-color: var(--red);
  color: #fff;
  background: var(--red);
}
.buymode:focus-visible {
  outline: 3px solid var(--gold);
  outline-offset: 2px;
}

/* --- Tarjeta de institucion ------------------------------------------ */
.institutions { display: flex; flex-direction: column; gap: 12px; }

.card {
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: var(--radius);
  padding: 12px 14px;
  box-shadow: var(--shadow);
  position: relative;          /* ancla del numero flotante */
  cursor: pointer;
  /* Tapear no debe hacer zoom ni seleccionar texto en movil. */
  user-select: none;
  -webkit-user-select: none;
  touch-action: manipulation;
}
.card:focus-visible {
  outline: 3px solid var(--gold);
  outline-offset: 2px;
}

/* --- Diorama de la tarjeta (013) -------------------------------------- */
/* La rejilla de dos columnas vive en `.has-art`, que ui.js pone solo cuando la
   institucion tiene arte Y la imagen carga. Sin la clase, la tarjeta es byte a
   byte la de antes: una tarjeta sin arte no puede regresionar, y no queda una
   columna vacia indentando el texto. El marco ocupa la columna 1 a la altura de
   las cuatro filas de texto; los botones siguen a lo ancho de las dos.
   El hijo de la rejilla es el envoltorio `.card-art-col` (015), no el marco: el
   marco recorta con `overflow: hidden` y el sello estampado tiene que salirse. */
.card.has-art {
  display: grid;
  grid-template-columns: 88px 1fr;
  column-gap: 10px;
}
.card.has-art .card-art-col {
  grid-column: 1;
  grid-row: 1 / span 4;
  align-self: start;
}
.card.has-art .card-head,
.card.has-art .card-row,
.card.has-art .card-next,
.card.has-art .progress {
  grid-column: 2;
  min-width: 0;                /* los nombres largos envuelven, no desbordan */
}
.card.has-art .buy,
.card.has-art .manager { grid-column: 1 / -1; }
/* La tarjeta bloqueada es compacta: solo cabecera y requisito al lado. */
.card-locked.has-art .card-art-col { grid-row: 1 / span 2; }
.card-locked.has-art .card-head,
.card-locked.has-art .card-req { grid-column: 2; min-width: 0; }
.card-locked.has-art .unlock { grid-column: 1 / -1; }

/* 88 px = la altura de la columna de texto (cabecera + fila + milestone +
   barra), asi que el marco no deja hueco muerto debajo. El crema y el borde son
   lo que absorbe la diferencia de tono entre piezas. */
.card-art-frame {
  width: 88px;
  height: 88px;
  border: 2px solid var(--line);
  border-radius: 10px;
  background: var(--art-cream);
  overflow: hidden;
}
/* `contain` respeta el encuadre del diorama; las franjas que pueda dejar son
   del mismo crema que el marco, asi que no se ven. La imagen no es un objetivo
   tactil: la tarjeta entera lo es, y asi el toque largo no ofrece "guardar
   imagen" en movil. */
.card-art {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  pointer-events: none;
  user-select: none;
  -webkit-user-select: none;
}
/* Ancla del sello. Mide lo mismo que el marco: no cambia la rejilla. */
.card-art-col { position: relative; }
/* Sello AUTOMATED estampado sobre la esquina del diorama (015), girado como un
   sello de verdad sobre la foto de un expediente. Fuera del flujo: ninguna linea
   de texto se mueve al contratar. Desborda un poco hacia el hueco de 10 px entre
   marco y texto y hacia abajo. 32 px y no los 58 de 015: a 58 tapaba medio
   diorama; a 32 ocupa ~70% menos de superficie y la palabra se sigue leyendo en
   pantallas de 2x (ademas suena entera en el lector, ver `.card-seal`). Con 3 px
   por fuera, la tinta desborda ~5 px: mas aire hasta el BUY y el texto que a 58.
   La pieza viene recta y con alfa; el giro es solo este. No es objetivo tactil:
   el toque sigue siendo la tarjeta. */
.card-stamp {
  position: absolute;
  right: -3px;
  bottom: -3px;
  width: 32px;
  height: 32px;
  transform: rotate(-9deg);
  pointer-events: none;
  user-select: none;
  -webkit-user-select: none;
}
.card-stamp[hidden] { display: none; }
.card-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px;
}
.card-name { font-size: 16px; font-weight: 800; }
.card-level { font-size: 13px; color: var(--muted); font-weight: 700; white-space: nowrap; }
.card-row {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  font-size: 13px;
  color: var(--muted);
  margin-top: 6px;
}
/* Sello AUTOMATED cuando la institucion tiene manager. */
.card-seal {
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.8px;
  color: var(--green-dark);
  border: 2px solid var(--green-dark);
  border-radius: 6px;
  padding: 1px 6px;
  white-space: nowrap;
  align-self: center;
}
.card-seal[hidden] { display: none; }

/* Texto oculto a la vista y NO al lector de pantalla (015). No `display: none`
   ni `visibility: hidden`, que lo quitarian tambien del lector. Con el sello
   estampado, el badge AUTOMATED pasa a ser esto: la palabra sigue sonando en su
   sitio de la tarjeta y sale de STRINGS, no del `alt` de la imagen. Si el sello
   falla, `has-stamp` se va y el badge verde reaparece sin reconstruir nada. */
.sr-only,
.card.has-stamp .card-seal {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Linea de proximo milestone. */
.card-next {
  font-size: 12px;
  color: var(--red-dark);
  font-weight: 600;
  margin-top: 6px;
}

.progress {
  height: 10px;
  background: var(--line);
  border-radius: 6px;
  overflow: hidden;
  margin: 8px 0;
}
.progress-fill {
  height: 100%;
  width: 100%;
  transform: scaleX(0);
  transform-origin: left center;
  background: linear-gradient(90deg, var(--green-dark), var(--green));
}
/* Sin transition: UI.render() ya pinta un valor nuevo por frame de rAF, asi que
   el reinicio de ciclo (de lleno a vacio) se ve tal cual sin arrastrar 90ms de
   retraso que dejaban el ultimo tramo sin pintar (022). */
/* Ciclo mas corto que `feedback.fastCycleSeconds` de tiempo real (milestones muy
   altos, o timeScale x100/x1000): perseguir el valor seria ruido. La barra se
   queda llena y con bandas, que se lee como "produciendo sin parar". */
.progress-fill.is-fast {
  transition: none;
  background-image: repeating-linear-gradient(
    115deg,
    var(--green-dark) 0 10px,
    var(--green) 10px 20px
  );
}
.buy {
  width: 100%;
  min-height: var(--tap);
  border: none;
  border-radius: 10px;
  background: var(--green-dark);
  color: #fff;
  font: inherit;
  font-weight: 800;
  letter-spacing: 0.5px;
  cursor: pointer;
  margin-top: 4px;
}
.buy:focus-visible { outline: 3px solid var(--gold); outline-offset: 2px; }
/* No comprable: apagado, con borde discontinuo y el texto cambiado a "NOT YET"
   desde ui.js. Tres señales (color, borde y palabra), ninguna imprescindible:
   el estado nunca depende solo del color (012). */
.buy.is-locked {
  background: var(--line);
  color: var(--muted-strong);
  border: 2px dashed #a4917a;
  cursor: default;
}

/* Boton de contratar manager (aparece al nivel 10). */
.manager {
  width: 100%;
  min-height: var(--tap);
  border: none;
  border-radius: 10px;
  background: var(--gold);
  color: var(--ink);
  font: inherit;
  font-weight: 800;
  letter-spacing: 0.3px;
  cursor: pointer;
  margin-top: 8px;
}
.manager:focus-visible { outline: 3px solid var(--red); outline-offset: 2px; }
.manager[hidden] { display: none; }
/* No alcanza para contratar: apagado, borde discontinuo y "NOT YET" en el texto
   (012). Sin opacidad: bajarla se llevaba el contraste por debajo del 4.5:1. */
.manager.is-locked {
  background: var(--line);
  color: var(--muted-strong);
  border: 2px dashed #a4917a;
  cursor: default;
}

/* --- Tarjeta bloqueada (004) ----------------------------------------- */
/* Compacta y visiblemente distinta de una normal: fondo apagado y borde
   discontinuo para que no parezca un error ni una institucion activa. */
.card-locked {
  background: #f6efe2;
  border: 2px dashed var(--line);
  box-shadow: none;
  cursor: default;
}
.card-locked .card-name { color: var(--muted); }
/* El diorama de una bloqueada, apagado (013). Tampoco aqui el color es la unica
   señal: siguen el texto LOCKED, la linea de requisito y el borde discontinuo. */
.card-locked .card-art { filter: grayscale(1) opacity(0.55); }
/* Requisito sin cumplir: informativo, no pulsable. */
.card-req {
  font-size: 13px;
  color: var(--muted);
  font-weight: 600;
  margin-top: 6px;
}
/* Boton de desbloqueo: destacado (oro) cuando es comprable. */
.unlock {
  width: 100%;
  min-height: var(--tap);
  border: none;
  border-radius: 10px;
  background: var(--gold);
  color: var(--ink);
  font: inherit;
  font-weight: 800;
  letter-spacing: 0.5px;
  cursor: pointer;
  margin-top: 8px;
}
.unlock:focus-visible { outline: 3px solid var(--red); outline-offset: 2px; }
.unlock[hidden] { display: none; }
/* Requisito cumplido pero sin dinero: visible pero apagado, no comprable. Misma
   receta que los otros dos botones: color + borde discontinuo + "NOT YET". */
.unlock.is-locked {
  background: var(--line);
  color: var(--muted-strong);
  border: 2px dashed #a4917a;
  cursor: default;
}

/* Entrada de una institucion recien desbloqueada (012): la tarjeta nueva llega
   con un destello dorado y un empujon corto, para que se vea que ha aparecido.
   Se quita sola pasado `feedback.unlockEnterMs`. */
.card.is-entering {
  animation: cardEnter 0.45s ease-out;
}
@keyframes cardEnter {
  0%   { opacity: 0; transform: translateY(-10px); border-color: var(--gold); box-shadow: 0 0 0 4px rgba(230, 184, 0, 0.45); }
  60%  { opacity: 1; transform: translateY(0);     border-color: var(--gold); box-shadow: 0 0 0 4px rgba(230, 184, 0, 0.30); }
  100% { opacity: 1; transform: translateY(0); }
}

/* --- Toasts (avisos breves no bloqueantes, 004) ---------------------- */
.toasts {
  position: fixed;
  left: 50%;
  bottom: 20px;
  transform: translateX(-50%);
  width: calc(100% - 32px);
  max-width: 398px;         /* 430 del app menos gutter */
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-items: center;
  pointer-events: none;
  z-index: 20;
}
.toast {
  background: var(--red-dark);
  color: #fff;
  font-weight: 700;
  font-size: 13px;
  padding: 10px 16px;
  border-radius: 10px;
  box-shadow: var(--shadow);
  animation: toastIn 2.6s ease forwards;
}
/* El aviso de Poder Nacional (005) usa el dorado para distinguirlo del de poblacion. */
.toast-power {
  background: var(--gold);
  color: var(--ink);
}
@keyframes toastIn {
  0%   { opacity: 0; transform: translateY(10px); }
  10%  { opacity: 1; transform: translateY(0); }
  85%  { opacity: 1; transform: translateY(0); }
  100% { opacity: 0; transform: translateY(-6px); }
}

/* --- Avisos de la tarjeta (012) --------------------------------------- */
/* Los tres salen POR ENCIMA de la tarjeta, cada uno en su esquina, y no tapan
   nada: dentro se comian el nivel y el nombre, y el flotante de una institucion
   automatizada esta practicamente siempre en pantalla. Son fichas opacas para
   que se lean sobre lo que quede detras. */
.floater, .level-pop, .milestone-pop {
  position: absolute;
  /* Justo por encima del borde: la ficha cae en el hueco entre tarjetas y en el
     relleno superior, nunca sobre el nombre ni sobre el nivel. */
  top: -18px;
  z-index: 2;
  padding: 1px 8px;
  border-radius: 9px;
  background: var(--card);
  border: 1px solid var(--line);
  box-shadow: var(--shadow);
  font-weight: 800;
  white-space: nowrap;
  pointer-events: none;
}

/* Pop al subir de nivel: izquierda, rojo, mas corto y mas pequeño que el de
   milestone para que no se confundan. Subir de nivel es rutina. */
.level-pop {
  left: 12px;
  font-size: 12px;
  color: var(--red);
  animation: levelPop 0.6s ease-out forwards;
}
@keyframes levelPop {
  0%   { opacity: 0; transform: translateY(4px) scale(0.9); }
  30%  { opacity: 1; transform: translateY(0) scale(1); }
  100% { opacity: 0; transform: translateY(-12px) scale(1); }
}

/* Pop al cruzar un milestone: centrado, dorado y mayor que el de nivel. Es el
   aviso importante de la tarjeta, asi que se lleva el sitio de honor. */
.milestone-pop {
  left: 50%;
  transform: translateX(-50%);
  font-size: 14px;
  color: #8a6a00;
  border-color: var(--gold);
  animation: milestonePop 1.2s ease-out forwards;
}
@keyframes milestonePop {
  0%   { opacity: 0; transform: translateX(-50%) scale(0.6); }
  25%  { opacity: 1; transform: translateX(-50%) scale(1.15); }
  60%  { opacity: 1; transform: translateX(-50%) scale(1); }
  100% { opacity: 0; transform: translateX(-50%) scale(1); }
}

/* Numero flotante "+V X" al cobrar un ciclo: derecha, verde. */
.floater {
  right: 12px;
  font-size: 13px;
  color: var(--green-dark);
  animation: floatUp 1s ease-out forwards;
}
@keyframes floatUp {
  0%   { opacity: 0; transform: translateY(4px); }
  20%  { opacity: 1; }
  100% { opacity: 0; transform: translateY(-18px); }
}

/* --- Pantalla MAS ----------------------------------------------------- */
.more-title {
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 1px;
  color: var(--red-dark);
  margin-bottom: 10px;
}
.stats-list { list-style: none; margin: 0; padding: 0; }
.stats-list li {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 4px;
  border-bottom: 1px solid var(--line);
  font-size: 14px;
}
.sl-label { color: var(--muted); }
.sl-value { font-weight: 700; }

/* --- Modal de regreso (006) ------------------------------------------ */
/* Centrado sobre el juego. El fondo oscurece pero el bucle sigue corriendo
   detras: es modal solo para el jugador, no para la simulacion. */
.modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(43, 33, 24, 0.55);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  z-index: 30;
}
.modal-backdrop[hidden] { display: none; }
.modal {
  width: 100%;
  max-width: 340px;
  background: var(--app-bg);
  border: 3px solid var(--red);
  border-radius: var(--radius);
  box-shadow: 0 8px 24px rgba(60, 40, 15, 0.35);
  padding: 20px 18px;
  text-align: center;
}
.modal-title {
  font-size: 17px;
  font-weight: 800;
  color: var(--red-dark);
  line-height: 1.25;
}
.modal-away {
  margin-top: 8px;
  font-size: 13px;
  font-weight: 700;
  color: var(--muted);
}
.modal-reward-label {
  margin-top: 14px;
  font-size: 12px;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--muted);
}
.modal-reward {
  font-size: 30px;
  font-weight: 800;
  color: var(--green-dark);
  line-height: 1.2;
}
.modal-note {
  margin-top: 10px;
  font-size: 12px;
  color: var(--muted);
}
.modal-btn {
  width: 100%;
  min-height: var(--tap);
  border: none;
  border-radius: 10px;
  font: inherit;
  font-weight: 800;
  letter-spacing: 0.5px;
  cursor: pointer;
  margin-top: 12px;
}
/* COLLECT es la accion principal; DOUBLE x2 es visible pero claramente
   secundario (contorno en vez de relleno). */
.modal-primary { background: var(--green-dark); color: #fff; }
.modal-primary:focus-visible { outline: 3px solid var(--gold); outline-offset: 2px; }
.modal-secondary {
  background: transparent;
  color: var(--red-dark);
  border: 2px solid var(--gold);
  margin-top: 8px;
}
.modal-secondary:focus-visible { outline: 3px solid var(--red); outline-offset: 2px; }
.modal-secondary[hidden] { display: none; }

/* --- Cartel de anuncio simulado (007) -------------------------------- */
/* Deliberadamente NO se parece a ninguna red publicitaria real: es un cartel
   de propaganda del propio juego, con su etiqueta de "Simulated ad" arriba. */
.ad { border-color: var(--gold); }
.ad:focus-visible { outline: 3px solid var(--gold); outline-offset: 2px; }
.ad-tag {
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--muted);
}
/* Cartel: bandas rojas y una estrella. Solo CSS, sin imagenes ni animacion
   (el bloque de prefers-reduced-motion del final ya corta cualquier animacion). */
.ad-art {
  height: 92px;
  margin: 10px 0 12px;
  border-radius: 10px;
  background:
    radial-gradient(circle at 50% 46%, var(--gold) 0 16px, transparent 17px),
    repeating-linear-gradient(-45deg, var(--red) 0 14px, var(--red-dark) 14px 28px);
}
.ad-countdown {
  margin-top: 14px;
  min-height: var(--tap);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  font-weight: 800;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.ad-countdown:empty { display: none; }

/* --- Guardado en la pantalla MAS (006) -------------------------------- */
.more-title-gap { margin-top: 26px; }
.save-hint {
  margin: 0 0 10px;
  font-size: 12px;
  color: var(--muted);
}
.save-actions { display: flex; gap: 8px; }
.save-btn {
  flex: 1;
  min-height: var(--tap);
  display: flex;
  align-items: center;
  justify-content: center;
  border: 2px solid var(--line);
  border-radius: 10px;
  background: var(--card);
  color: var(--ink);
  font: inherit;
  font-weight: 800;
  font-size: 13px;
  letter-spacing: 0.5px;
  text-decoration: none;
  cursor: pointer;
}
.save-btn:focus-visible { outline: 3px solid var(--gold); outline-offset: 2px; }
.save-btn[hidden] { display: none; }
.save-box {
  width: 100%;
  margin-top: 8px;
  padding: 8px;
  border: 2px solid var(--line);
  border-radius: 10px;
  background: var(--card);
  color: var(--ink);
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  font-size: 11px;
  resize: vertical;
}
.save-download { margin-top: 8px; }
.save-status {
  margin: 8px 0 0;
  font-size: 12px;
  font-weight: 700;
  color: var(--green-dark);
  min-height: 16px;
}
.save-warning {
  margin: 22px 0 6px;
  font-size: 12px;
  color: var(--muted);
}
/* RESET en rojo y a ancho completo: accion destructiva, lejos del resto. */
.save-danger {
  width: 100%;
  background: var(--red);
  border-color: var(--red-dark);
  color: #fff;
  margin-bottom: 24px;
}
/* Armado (primer toque): cambia de color y de texto antes de borrar de verdad. */
.save-danger.is-armed {
  background: var(--red-dark);
  border-color: var(--ink);
}

/* --- Burbuja de Vorlan (008) ------------------------------------------ */
/* Aviso breve bajo las pestañas, con el pico apuntando al retrato. No es
   modal ni roba el foco: solo se anuncia con aria-live. */
.vorlan-bubble {
  position: relative;
  margin: 8px 16px 0;
  padding: 10px 14px;
  background: #fff8e6;
  border: 2px solid var(--gold);
  border-radius: var(--radius);
  font-size: 13px;
  font-style: italic;
  font-weight: 600;
  color: var(--red-dark);
  box-shadow: var(--shadow);
  animation: bubbleIn 0.25s ease-out;
}
.vorlan-bubble[hidden] { display: none; }
.vorlan-bubble::before {
  content: "";
  position: absolute;
  top: -8px;
  left: 18px;
  width: 12px;
  height: 12px;
  background: #fff8e6;
  border-left: 2px solid var(--gold);
  border-top: 2px solid var(--gold);
  transform: rotate(45deg);
}
@keyframes bubbleIn {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Destello de la pestaña EMPIRE la primera vez que aparece (008). */
.tab.is-new { animation: tabFlash 1.6s ease-out 2; }
@keyframes tabFlash {
  0%, 100% { background: transparent; }
  30%      { background: var(--gold); color: var(--red-dark); }
}

/* --- Pestaña Imperio: mapa de nodos (008) ----------------------------- */
.map-hint {
  margin: -4px 0 10px;
  font-size: 12px;
  color: var(--muted);
}
.map-wrap {
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 8px;
}
/* El SVG escala al ancho de la app: las coordenadas son las del viewBox, no
   pixeles, asi que el mapa cabe sin scroll horizontal a 390 px. */
.map {
  display: block;
  width: 100%;
  height: auto;
}
.map-edge {
  stroke: var(--line);
  stroke-width: 4;
  stroke-linecap: round;
}
.map-node { cursor: pointer; }
.map-node:focus-visible {
  outline: 3px solid var(--gold);
  outline-offset: 2px;
}
.node-circle {
  fill: var(--card);
  stroke: var(--muted);
  stroke-width: 3;
}
.node-glyph {
  font-size: 22px;
  font-weight: 800;
  fill: var(--muted);
  pointer-events: none;
}
.node-label {
  font-size: 12px;
  font-weight: 700;
  fill: var(--ink);
  pointer-events: none;
  /* Halo del color del papel: los nombres cruzan las lineas de frontera. */
  stroke: var(--card);
  stroke-width: 3;
  paint-order: stroke fill;
}

/* Bandera dentro del nodo (015): recortada a circulo desde ui-empire.js. No
   recibe el toque; lo recibe el circulo, que se pinta encima. */
.node-flag { pointer-events: none; }
/* Distintivo con el simbolo de estado cuando hay bandera: circulo de papel con
   el trazo del color del estado y el mismo glifo dentro. Sobre papel y no sobre
   la bandera, asi que los pares de contraste de 012 siguen valiendo. */
.node-badge {
  fill: var(--card);
  stroke: var(--muted);
  stroke-width: 2;
  pointer-events: none;
}
.node-badge-glyph {
  font-size: 13px;
  font-weight: 800;
  fill: var(--muted);
  pointer-events: none;
}

/* Los cuatro estados se distinguen por COLOR, por BORDE y por SIMBOLO: nunca
   solo por color (el simbolo va dentro del nodo —o en su distintivo, con
   bandera— y el estado, en su aria-label). */
.map-node.is-current .node-circle {
  fill: var(--gold);
  stroke: var(--red);
  stroke-width: 5;
}
.map-node.is-current .node-glyph,
.map-node.is-current .node-badge-glyph { fill: var(--red-dark); }
.map-node.is-current .node-badge { stroke: var(--red); }

.map-node.is-conquered .node-circle {
  fill: #dff0e4;
  stroke: var(--green);
  stroke-width: 4;
}
.map-node.is-conquered .node-glyph,
.map-node.is-conquered .node-badge-glyph { fill: var(--green); }
.map-node.is-conquered .node-badge { stroke: var(--green); }

.map-node.is-available .node-circle {
  fill: var(--card);
  stroke: var(--red);
  stroke-width: 4;
  stroke-dasharray: 7 5;
}
.map-node.is-available .node-glyph,
.map-node.is-available .node-badge-glyph { fill: var(--red); }
.map-node.is-available .node-badge { stroke: var(--red); }

.map-node.is-locked .node-circle {
  fill: #f1ece2;
  stroke: var(--muted);
  stroke-width: 3;
  stroke-dasharray: 2 4;
}
.map-node.is-locked .node-glyph,
.map-node.is-locked .node-badge-glyph { fill: var(--muted); }
.map-node.is-locked .node-label { fill: var(--muted); }
/* Pais bloqueado con bandera: gris y atenuada, como el diorama de la tarjeta
   bloqueada (013). Cuarta señal, no la unica: siguen el trazo, el simbolo y el
   aria-label. */
.map-node.is-locked .node-flag { filter: grayscale(1) opacity(0.55); }

/* Pais abierto en la ficha: halo y nombre subrayado, sin tocar los colores de
   estado (el estado tiene que seguir leyendose igual). */
.map-node.is-selected .node-circle {
  filter: drop-shadow(0 0 5px rgba(43, 33, 24, 0.55));
}
.map-node.is-selected .node-label { text-decoration: underline; }

/* Con bandera, el circulo solo aporta el trazo y el glifo centrado se muda al
   distintivo. `transparent` y no `none`: el circulo sigue siendo lo que recibe
   el toque. TIENE que ir despues de las cuatro reglas de estado de arriba: misma
   especificidad, gana la ultima. Si la bandera falla, `has-flag` se va y vuelve
   el nodo de siempre. */
.map-node.has-flag .node-circle { fill: transparent; }
.map-node.has-flag .node-glyph { display: none; }

/* --- Ficha del pais --------------------------------------------------- */
.country-card {
  margin-top: 12px;
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 12px 14px;
}
/* Cabecera de la ficha: bandera y nombre en fila (015). Sin `has-flag` la
   bandera no ocupa sitio y el nombre queda donde estaba. */
.country-head {
  display: flex;
  align-items: center;
  gap: 10px;
}
.country-flag {
  display: none;
  flex: none;
  width: 48px;
  height: 32px;
  border: 2px solid var(--line);
  border-radius: 4px;
  object-fit: cover;
  pointer-events: none;
}
.country-card.has-flag .country-flag { display: block; }
.country-name { font-size: 17px; font-weight: 800; min-width: 0; }
.country-status {
  display: inline-block;
  margin-top: 4px;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  border: 2px solid var(--muted);
  border-radius: 6px;
  padding: 1px 6px;
  color: var(--muted);
}
.country-status.is-current   { color: var(--red-dark); border-color: var(--red); }
.country-status.is-conquered { color: var(--green-dark); border-color: var(--green-dark); }
.country-status.is-available { color: var(--red);      border-color: var(--red); }
.country-line {
  margin-top: 6px;
  font-size: 13px;
  color: var(--muted);
}

/* --- Panel de requisitos de la siguiente conquista --------------------- */
.req-panel {
  margin-top: 14px;
  background: #fff8e6;
  border: 2px solid var(--gold);
  border-radius: var(--radius);
  padding: 12px 14px;
}
.req-title {
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 1.5px;
  color: var(--red-dark);
}
.req-row { margin-top: 10px; }
.req-row[hidden] { display: none; }
.req-head {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  font-size: 12px;
  color: var(--muted);
}
.req-label { font-weight: 600; }
/* El valor va SIEMPRE en texto al lado de la barra: la barra sola no informa. */
.req-value { font-weight: 800; white-space: nowrap; }
.req-bar {
  margin-top: 4px;
  height: 8px;
  border-radius: 4px;
  background: var(--line);
  overflow: hidden;
}
.req-fill {
  height: 100%;
  background: var(--red);
  transform-origin: left center;
  transform: scaleX(0);
}
.req-row.is-ok .req-value { color: var(--green-dark); }
.req-row.is-ok .req-fill { background: var(--green); }
.req-verdict {
  margin-top: 12px;
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 0.5px;
  color: var(--muted);
}
.req-verdict.is-ready { color: var(--green-dark); }

/* --- Conquista: bonus imperial y boton CONQUER (009) ------------------ */
/* Las dos lineas del bonus se leen como una nota del panel, no como un boton:
   informan de lo que se gana ahora y de lo que se ganaria esperando. */
.imperial-now {
  margin-top: 10px;
  font-size: 13px;
  font-weight: 800;
  color: var(--red-dark);
}
.imperial-next {
  margin-top: 2px;
  font-size: 12px;
  color: var(--muted);
}
.imperial-now[hidden], .imperial-next[hidden] { display: none; }

/* Separado del resto del panel a proposito: es el boton mas caro de pulsar sin
   querer de todo el juego. */
.conquer-btn {
  width: 100%;
  min-height: 52px;
  margin-top: 16px;
  border: none;
  border-radius: 12px;
  background: var(--red);
  color: #fff;
  font: inherit;
  font-size: 15px;
  font-weight: 800;
  letter-spacing: 1.5px;
  cursor: pointer;
  box-shadow: var(--shadow);
}
.conquer-btn[hidden] { display: none; }
.conquer-btn:focus-visible { outline: 3px solid var(--gold); outline-offset: 2px; }

/* --- Prestige continental (010) --------------------------------------- */
/* Bonus permanente: una nota dorada del panel, visible tambien a mitad de la
   vuelta siguiente (es lo unico que sobrevive al reinicio). */
.continental-bonus {
  margin-top: 10px;
  padding: 8px 10px;
  border: 2px solid var(--gold);
  border-radius: 10px;
  background: #fff8e6;
  font-size: 13px;
  font-weight: 800;
  color: var(--red-dark);
}
.continental-bonus[hidden] { display: none; }

.proclaim-intro {
  margin-top: 14px;
  font-size: 13px;
  color: var(--muted);
}
.proclaim-intro[hidden] { display: none; }

/* Mismo tamaño y sitio que CONQUER (nunca se ven a la vez), pero dorado: es el
   boton mas gordo del juego y se nota. */
.proclaim-btn {
  margin-top: 10px;
  background: linear-gradient(135deg, var(--gold), #c79600);
  color: var(--ink);
  letter-spacing: 1px;
  font-size: 14px;
}
.proclaim-btn:focus-visible { outline: 3px solid var(--red-dark); outline-offset: 2px; }

/* Celebracion del Imperio Continental: cartel corto (2.6 s) que se retira solo.
   No captura toques (pointer-events: none) para no bloquear nada. */
.celebration {
  position: fixed;
  inset: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  background: radial-gradient(circle at 50% 45%, rgba(230, 184, 0, 0.35), rgba(43, 33, 24, 0.55));
  animation: celebrationIn 0.3s ease-out;
}
.celebration[hidden] { display: none; }
/* El cartel: titulo grande y, debajo, a quien celebra (institucion o pais). */
.celebration-card {
  max-width: 320px;
  padding: 18px 22px;
  border: 3px solid var(--gold);
  border-radius: var(--radius);
  background: var(--red);
  color: #fff;
  text-align: center;
  box-shadow: var(--shadow);
  animation: celebrationPop 0.5s ease-out;
}
.celebration-text {
  font-size: 22px;
  font-weight: 800;
  letter-spacing: 1.5px;
  text-shadow: 0 2px 0 var(--red-dark);
}
.celebration-sub {
  margin-top: 6px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.5px;
  color: #ffe9a8;
  overflow-wrap: anywhere;
}
.celebration-sub[hidden] { display: none; }
@keyframes celebrationIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes celebrationPop {
  0%   { transform: scale(0.7) rotate(-3deg); }
  60%  { transform: scale(1.06) rotate(1deg); }
  100% { transform: scale(1) rotate(0); }
}

/* Con los requisitos cumplidos, los candidatos del mapa dejan de ser un color
   mas: laten despacio y engordan el borde (con movimiento reducido, solo el
   borde). */
.screen.is-ready .map-node.is-available .node-circle {
  stroke-width: 5;
  animation: candidatePulse 1.8s ease-in-out infinite;
}
@keyframes candidatePulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.6; }
}

/* --- Dialogo de conquista (009) --------------------------------------- */
.conquest { border-color: var(--gold); max-width: 360px; text-align: left; }
.conquest:focus-visible { outline: 3px solid var(--gold); outline-offset: 2px; }
.conquest-step {
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 4px;
}
.conquest-step:empty { display: none; }
.conquest .modal-title { text-align: left; }
.conquest-body { margin-top: 12px; }

/* Cada opcion (pais o metodo) es una tarjeta pulsable entera: objetivo tactil
   generoso y el efecto escrito debajo del nombre, nunca solo un icono. */
.conquest-option {
  display: block;
  width: 100%;
  min-height: var(--tap);
  margin-bottom: 8px;
  padding: 10px 12px;
  text-align: left;
  background: var(--card);
  border: 2px solid var(--line);
  border-radius: 12px;
  font: inherit;
  color: var(--ink);
  cursor: pointer;
}
.conquest-option:focus-visible { outline: 3px solid var(--gold); outline-offset: 2px; }
.conquest-option-name {
  display: block;
  font-size: 15px;
  font-weight: 800;
  color: var(--red-dark);
}
.conquest-option-line {
  display: block;
  margin-top: 2px;
  font-size: 12px;
  color: var(--muted);
}
.conquest-intro {
  font-size: 14px;
  font-weight: 700;
  line-height: 1.35;
}
.conquest-gain {
  margin-top: 8px;
  font-size: 14px;
  font-weight: 800;
  color: var(--green-dark);
}
.conquest-list-title {
  margin-top: 12px;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--red-dark);
}
.conquest-list {
  margin-top: 2px;
  font-size: 12px;
  line-height: 1.35;
  color: var(--muted);
}
/* El aviso de "ya no cumples los requisitos" sale en el sitio donde se iba a
   pulsar, no como toast que se pierde. */
.conquest-warning {
  font-size: 13px;
  font-weight: 700;
  color: var(--red);
}
.conquest-warning:empty { display: none; }
.conquest-summary-label {
  margin-top: 10px;
  font-size: 11px;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--muted);
}
.conquest-summary-value {
  font-size: 26px;
  font-weight: 800;
  color: var(--green-dark);
  line-height: 1.2;
}
.conquest-summary-method {
  font-size: 15px;
  font-weight: 800;
  color: var(--red-dark);
}

/* --- Panel debug (011) ------------------------------------------------ */
/* Deliberadamente feo y distinto del juego: gris frio, borde discontinuo y
   monoespaciado. Tiene que ser imposible confundirlo con las estadisticas. */
.debug {
  margin: 28px 0 24px;
  border: 2px dashed #9aa4b0;
  border-radius: var(--radius);
  background: #eef1f4;
  color: #2c333a;
}
.debug-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 10px 12px;
  background: #dde3e9;
  border-bottom: 2px dashed #9aa4b0;
  border-radius: calc(var(--radius) - 2px) calc(var(--radius) - 2px) 0 0;
}
.debug-titles { min-width: 0; }
.debug-title {
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 2px;
}
.debug-subtitle {
  font-size: 11px;
  color: #5b6570;
}
.debug-toggle {
  flex: 0 0 auto;
  min-height: var(--tap);
  min-width: 72px;
  border: 2px solid #9aa4b0;
  border-radius: 10px;
  background: #fff;
  color: #2c333a;
  font: inherit;
  font-weight: 800;
  font-size: 12px;
  letter-spacing: 1px;
}
.debug-toggle:focus-visible { outline: 3px solid var(--gold); outline-offset: 2px; }
.debug-body { padding: 12px; }
.debug-body[hidden] { display: none; }

.debug-group { margin-bottom: 18px; }
.debug-group-title {
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 1.5px;
  color: #45505b;
  margin-bottom: 6px;
}
.debug-note {
  margin: 0 0 8px;
  font-size: 11px;
  line-height: 1.35;
  color: #5b6570;
}
.debug-note-strong { font-weight: 700; color: #7a2f2c; }
.debug-status {
  margin: 0 0 14px;
  min-height: 15px;
  font-size: 12px;
  font-weight: 700;
  color: var(--red);
}

/* Rejilla de botones: se reparten el ancho y nunca bajan de 44 px de alto. */
.debug-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 6px;
}
.debug-btn {
  flex: 1 1 60px;
  min-height: var(--tap);
  padding: 0 8px;
  border: 2px solid #9aa4b0;
  border-radius: 10px;
  background: #fff;
  color: #2c333a;
  font: inherit;
  font-weight: 800;
  font-size: 12px;
  letter-spacing: 0.5px;
}
.debug-btn:focus-visible { outline: 3px solid var(--gold); outline-offset: 2px; }
.debug-btn:disabled { opacity: 0.45; }
.debug-btn.is-active {
  background: #2c333a;
  border-color: #2c333a;
  color: #fff;
}
.debug-btn-wide { flex: 1 1 100%; }
.debug-btn-narrow { flex: 0 0 84px; }
.debug-btn-danger {
  background: var(--red);
  border-color: var(--red-dark);
  color: #fff;
}
.debug-btn-danger.is-armed { background: var(--red-dark); border-color: #2c333a; }

.debug-input {
  flex: 1 1 120px;
  min-height: var(--tap);
  padding: 0 10px;
  border: 2px solid #9aa4b0;
  border-radius: 10px;
  background: #fff;
  color: #2c333a;
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  font-size: 13px;
}
.debug-field {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 6px;
}
.debug-field-label {
  flex: 0 0 68px;
  font-size: 11px;
  color: #5b6570;
}
.debug-select {
  flex: 1 1 auto;
  min-width: 0;
  min-height: var(--tap);
  padding: 0 8px;
  border: 2px solid #9aa4b0;
  border-radius: 10px;
  background: #fff;
  color: #2c333a;
  font: inherit;
  font-size: 13px;
}
.debug-select:disabled { opacity: 0.45; }
/* La casilla y su texto forman un solo objetivo tactil de 44 px. */
.debug-check {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: var(--tap);
  font-size: 12px;
  color: #45505b;
}
.debug-check input { width: 20px; height: 20px; }

/* Inspector: solo lectura, en monoespaciado para que las cifras se alineen. */
.debug-inspector {
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
}
.debug-insp-card {
  padding: 8px 10px;
  margin-bottom: 6px;
  border: 1px solid #c3ccd5;
  border-radius: 8px;
  background: #fff;
}
.debug-insp-name {
  font-weight: 800;
  font-size: 12px;
  margin-bottom: 3px;
}
.debug-insp-line {
  font-size: 11px;
  line-height: 1.5;
  color: #45505b;
  word-break: break-word;
}
.debug-insp-layers {
  font-size: 11px;
  line-height: 1.5;
  color: #2c333a;
  word-break: break-word;
}

/* Aviso persistente de timeScale != 1: flotante sobre cualquier pantalla. */
.timescale-badge {
  position: fixed;
  top: 6px;
  right: 6px;
  z-index: 30;
  padding: 6px 10px;
  border-radius: 8px;
  background: #2c333a;
  color: var(--gold);
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 1px;
  box-shadow: var(--shadow);
  pointer-events: none;
}
.timescale-badge[hidden] { display: none; }

/* --- Accesibilidad: movimiento reducido ------------------------------ */
/* Regla general: fuera todo el movimiento. Lo que sigue se asegura de que, sin
   la animacion, cada aviso siga DICIENDO lo mismo: los elementos cuyo estado
   inicial en los keyframes era `opacity: 0` se quedarian invisibles, y los que
   solo se distinguian por moverse necesitan una señal quieta (012). */
@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }

  /* Avisos efimeros: visibles y quietos durante su vida (los retira un
     setTimeout de ui.js, no la animacion). */
  .floater,
  .level-pop,
  .toast,
  .celebration,
  .celebration-card { opacity: 1; transform: none; }
  /* El de milestone conserva su translateX: no es movimiento, es lo que lo
     centra sobre la tarjeta. */
  .milestone-pop { opacity: 1; transform: translateX(-50%); }

  /* Institucion recien desbloqueada: sin el empujon, el borde dorado durante
     `feedback.unlockEnterMs` es lo que dice "esta es la nueva". */
  .card.is-entering {
    border-color: var(--gold);
    box-shadow: 0 0 0 4px rgba(230, 184, 0, 0.35);
  }

  /* Pestaña EMPIRE recien aparecida y candidatos del mapa: sin latido, se
     quedan con el subrayado y el borde gordo, que ya los distinguen. */
  .tab.is-new { border-bottom-color: var(--gold); }
}
