/* Design plan
Color: bg #080b0d, surface #10151a, surface-2 #161d23, border #212a31,
       text #d9e2e1, muted #6f7d7c, compute #52e0c4, energy #e8a33d, research #9a86e6,
       data #5aa9ff, risk #e0525a
Type: IBM Plex Mono for readouts/headings, IBM Plex Sans for body.
Layout: one-screen console app — header + evolving skyline, resource meters, tabbed body
        (Núcleo / Construir / Red / Investigar / Anclas), fixed bottom tab bar, overlays.
*/
  :root{
    /* A2 (look & feel ronda 2): fondo un punto más oscuro y superficies/bordes un punto más claros
       para que las tarjetas tengan relieve — antes tarjeta (#10151a) y fondo (#080b0d) casi no se
       distinguían. */
    --bg:#070a0c; --surface:#121a21; --surface-2:#1a2430; --surface-3:#22303a; --border:#263139;
    --text:#eaf1f0; --muted:#a6b2b0; --muted-2:#818e8b;
    --compute:#52e0c4; --compute-dim:#1f5a4f;
    --energy:#e8a33d; --energy-dim:#6a4a1c;
    --research:#9a86e6; --research-dim:#3f3770;
    --data:#5aa9ff; --data-dim:#22497a;
    --risk:#e0525a; --risk-dim:#5a2226; --risk-bg:#1b1113;
    --sky-top:#0b1116; --sky-bot:#121a21;
  }
  @media (prefers-color-scheme: light){ :root:not([data-theme="light"]){ --bg:#070a0c; } }
  :root[data-theme="dark"]{ --bg:#070a0c; }
  :root[data-theme="light"]{ --bg:#070a0c; }
  *{ box-sizing:border-box; }
  [hidden]{ display:none !important; }
  html,body{ height:100%; }
  body{
    margin:0; background:var(--bg); color:var(--text);
    font-family:"IBM Plex Sans", system-ui, sans-serif; font-size:15px;
    padding-inline:0; padding-block:0; overflow:hidden;
    -webkit-tap-highlight-color:transparent; user-select:none; -webkit-user-select:none;
  }
  .num{ font-family:"IBM Plex Mono", ui-monospace, monospace; font-variant-numeric:tabular-nums; }
  .mono{ font-family:"IBM Plex Mono", ui-monospace, monospace; }

  /* Splash de carga (D2): cubre toda la pantalla desde antes de que corra ningún script (ver
     index.html), boot.js la retira con un fundido al terminar de arrancar, garantizando un
     mínimo de tiempo visible para que no sea un parpadeo en dispositivos rápidos. */
  #splashScreen{
    position:fixed; inset:0; z-index:500; background:#040607;
    display:flex; flex-direction:column; align-items:center; justify-content:center; gap:14px;
    transition:opacity .5s ease;
  }
  #splashScreen.hide{ opacity:0; pointer-events:none; }
  #splashScreen .splash-img{ width:min(56vw, 220px); height:auto; }
  #splashScreen .splash-title{ font-family:"IBM Plex Mono"; font-weight:700; letter-spacing:.1em; font-size:1.05rem; color:var(--text); }
  #splashScreen .splash-tag{ font-family:"IBM Plex Mono"; font-size:.8rem; color:var(--muted); }
  @media (prefers-reduced-motion: reduce){ #splashScreen{ transition:none; } }

  .app{ height:100%; max-width:520px; margin:0 auto; display:flex; flex-direction:column; position:relative; }

  header{
    padding:10px 16px 6px; display:flex; align-items:flex-end; justify-content:space-between; gap:10px;
    position:relative; z-index:2;
  }
  header h1{ margin:0; font-family:"IBM Plex Mono"; font-weight:700; font-size:1rem; letter-spacing:.06em; white-space:nowrap; }
  header .chip{ max-width:46%; overflow:hidden; text-overflow:ellipsis; }
  header > div:first-child{ min-width:0; }
  /* pedido explícito del usuario: el icono de "racha y objetivos" (progressBtn) va justificado a
     la derecha de la cabecera, pero a la izquierda del de ajustes (settingsBtn siempre el que más
     a la derecha queda) — un contenedor propio para que "space-between" de header trate a los dos
     como un solo bloque anclado a la esquina, en vez de cada uno flotando por su lado. */
  .iconGroup{ display:flex; align-items:center; gap:8px; flex:none; }
  header .phase{ font-size:.78rem; color:var(--muted); letter-spacing:.08em; text-transform:uppercase; margin-top:2px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
  .chip{
    font-family:"IBM Plex Mono"; font-size:.78rem; letter-spacing:.06em; padding:4px 8px; border-radius:6px;
    border:1px solid var(--border); background:var(--surface); color:var(--muted); white-space:nowrap;
  }
  .chip.model{ color:var(--research); border-color:var(--research-dim); }
  button.chip{ cursor:pointer; }
  button.chip:active{ transform:scale(.95); }
  .chip.driftmod{ color:var(--energy); border-color:var(--energy-dim); }
  /* botón de ajustes: saca Borrar partida de las pestañas de juego (demasiado accesible ahí,
     pedido explícito del usuario) a un sitio deliberadamente aparte — la cabecera, fuera de
     cualquier flujo de juego, con su propio modal (#settingsOverlay). */
  .iconbtn{ appearance:none; width:26px; height:26px; border-radius:50%; border:1px solid var(--border); background:var(--surface); color:var(--muted); display:flex; align-items:center; justify-content:center; padding:0; cursor:pointer; flex:none; position:relative; }
  .iconbtn:active{ transform:scale(.9); }
  .iconbtn svg{ width:15px; height:15px; }
  /* mismo lenguaje que nav.tabs button .badge (punto de "hay algo nuevo"), aplicado a un icono de
     cabecera en vez de una pestaña — se enciende cuando hay racha o algún objetivo semanal listos
     para reclamar, para que el icono en sí ya avise sin tener que abrir el modal a mirar. */
  .iconbtn .badge{ position:absolute; top:-2px; right:-2px; width:9px; height:9px; border-radius:50%; background:var(--energy); border:2px solid var(--bg); display:none; }
  .iconbtn.has-badge .badge{ display:block; }

  .skyline{ height:64px; position:relative; overflow:hidden; background:linear-gradient(var(--sky-top), var(--sky-bot)); border-bottom:1px solid var(--border); }
  .skyline svg{ position:absolute; inset:0; width:100%; height:100%; display:block; }

  /* columnas automáticas: los marcadores aún no nacidos (reveal.js) no dejan hueco */
  .meters{ display:grid; grid-auto-flow:column; grid-auto-columns:1fr; gap:6px; padding:8px 16px 0; }
  /* min-width:0 en .meter no bastaba por sí solo: el nombre del recurso vive en un span sin su
     propio overflow:hidden, así que su ancho de contenido mínimo (nowrap, no puede encogerse) se
     propagaba a la columna del grid entero y podía empujar TODA la página a desbordar en
     horizontal en móvil — bug real reportado por el usuario con los nombres largos que tenían
     antes los materiales exóticos ("Resonancia inestable", "Aleación densa"; ver core/index.js,
     COLONY_BONUSES, ahora acortados a Criogel/Ferrita/Baliza/Vórtice para caber igual que el
     resto). Se deja overflow:hidden + ellipsis como red de seguridad aunque ya no haga falta con
     los nombres actuales, por si algún nombre futuro vuelve a ser largo. .value y .rate ya se
     recortaban así; el nombre no. */
  .meter{ background:var(--surface); border:1px solid var(--border); border-radius:8px; padding:6px 5px; min-width:0; overflow:hidden; display:flex; flex-direction:column; gap:1px; }
  .meter .label{ font-size:.75rem; letter-spacing:.04em; text-transform:uppercase; color:var(--muted); display:flex; align-items:center; gap:3px; white-space:nowrap; min-width:0; }
  .meter .label .ri{ width:12px; height:12px; flex:none; margin:0; }
  .meter .label span:not(.dot){ overflow:hidden; text-overflow:ellipsis; min-width:0; }
  .meter .dot{ width:5px; height:5px; border-radius:50%; flex:none; }
  .meter .value{ font-size:1rem; font-weight:600; line-height:1.15; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
  .meter .rate{ font-size:.75rem; color:var(--muted-2); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
  /* Rayo tachado: va delante del propio ritmo ("+0/s"), así que nunca lo recorta la elipsis. Lo
     usan los medidores de recurso y el ritmo de riesgo (máquinas paradas por falta de energía). */
  .noenergy{ position:relative; display:inline-block; width:11px; height:11px; margin-right:3px; vertical-align:-1px; }
  .noenergy svg{ width:11px; height:11px; display:block; }
  .noenergy::after{ content:""; position:absolute; left:-1px; right:-1px; top:50%; height:1.5px; background:var(--risk); transform:rotate(-45deg); border-radius:2px; }
  .riskrow{ padding:6px 16px 0; display:flex; align-items:center; gap:8px; }
  .riskrow .label{ font-size:.75rem; letter-spacing:.08em; text-transform:uppercase; color:var(--muted); white-space:nowrap; }
  .risk-track{ flex:1; height:7px; border-radius:4px; background:var(--risk-bg); border:1px solid var(--border); overflow:hidden; }
  .risk-fill{ height:100%; width:0%; background:linear-gradient(90deg,var(--energy),var(--risk)); transition:width .25s; }
  .riskrow .value{ font-size:.82rem; color:var(--muted); min-width:34px; text-align:right; }
  .riskrow.hot .value{ color:var(--risk); }
  .riskrow .rrate{ font-size:.75rem; color:var(--muted-2); min-width:44px; text-align:right; }
  /* previsualización del riesgo con una opción de dilema marcada (5-C): tramo rayado entre el
     riesgo actual y a donde iría — rojo si sube, verde-cómputo si baja. */
  .risk-track{ position:relative; }
  .risk-ghost, .strip .sghost{ position:absolute; top:0; bottom:0; left:0; width:0; background:repeating-linear-gradient(45deg, var(--risk) 0 3px, transparent 3px 6px); }
  .risk-ghost.down, .strip .sghost.down{ background:repeating-linear-gradient(45deg, var(--compute) 0 3px, transparent 3px 6px); }

  /* cabecera compacta fuera del Núcleo (feedback beta, 7.1): una sola línea con los cuatro recursos
     y la barra de riesgo en miniatura en lugar de skyline + 4 medidores + fila de riesgo (~250px de
     812 en móvil). Tocarla despliega los medidores completos; cambiar de pestaña los recoge. */
  .strip{ display:none; width:100%; border-bottom:1px solid var(--border); background:var(--surface); color:var(--text); padding:6px 16px 7px; align-items:center; gap:8px; box-sizing:border-box; }
  .strip .stripbtn{ flex:1; min-width:0; overflow:hidden; appearance:none; border:0; background:none; color:var(--text); padding:2px 0; display:flex; align-items:center; gap:5px; font-family:"IBM Plex Mono"; font-size:.75rem; cursor:pointer; text-align:left; }
  .strip .sr{ display:inline-flex; align-items:center; gap:3px; min-width:0; }
  .strip .sr svg{ width:12px; height:12px; }
  .strip .sr b{ font-weight:600; white-space:nowrap; color:var(--text); }
  .strip .srisk{ margin-left:auto; display:inline-flex; align-items:center; gap:4px; color:var(--muted); font-size:.75rem; white-space:nowrap; flex:none; }
  .strip .srisk .ri{ width:14px; height:14px; margin-right:-1px; color:var(--risk); }
  .riskrow .label{ display:inline-flex; align-items:center; gap:5px; }
  .riskrow .label .ri{ width:13px; height:13px; color:var(--risk); }
  /* con el chip de flota visible no cabe el ritmo: se oculta (el color del porcentaje ya dice si sube) */
  .strip.withfleet #sRiskRate{ display:none; }
  /* B8a: el porcentaje se colorea por ritmo — naranja si sube, rojo a partir del 70% */
  .strip .srisk.up{ color:var(--energy); } .strip .srisk.hot{ color:var(--risk); }
  /* B4a: chip de "cosas en marcha" (naves, fabricación): toca para ir a Red */
  .fleetchip{ appearance:none; flex:none; display:inline-flex; align-items:center; gap:4px; font-family:"IBM Plex Mono"; font-size:.75rem; color:var(--research); border:1px solid var(--research-dim); background:color-mix(in srgb, var(--research) 10%, var(--surface)); padding:3px 7px; border-radius:6px; cursor:pointer; }
  .fleetchip svg{ width:12px; height:12px; fill:none; stroke:currentColor; stroke-width:1.8; }
  .strip .strack{ position:relative; width:30px; height:5px; border-radius:3px; background:var(--risk-bg); border:1px solid var(--border); overflow:hidden; display:block; flex:none; }
  .strip .sfill{ position:absolute; left:0; top:0; bottom:0; width:0; background:linear-gradient(90deg,var(--energy),var(--risk)); }
  /* la cabecera compacta (ronda 2) quedó descartada: la tira y la fila de ritmos no se muestran nunca;
     el skyline decorativo solo en Núcleo */
  .strip, .raterow{ display:none !important; }
  body:not([data-tab="core"]) .skyline{ display:none; }
  /* ---------- Pantallas bajas (2026-09-28, pedido del usuario tras probar en un iPhone 14 Pro) ----------
     La cabecera fija (título + skyline + medidores + materiales + riesgo) mide 259 px; en un móvil
     con las barras del navegador (≈ 660-760 px de alto útil) al Núcleo le quedaban 350-440 px y el
     bloque del núcleo (≈ 350 px) no entraba entero. Por altura, no por anchura:
     - ≤ 760 px: fuera el skyline decorativo (64 px) y cabecera más apretada. En un iPhone 14 Pro
       en Safari o dentro de Telegram se está en este caso; como app instalada (852 px) se ve entero.
     - ≤ 700 px (iPhone SE, Safari con barras): además el núcleo se dibuja más pequeño (190 px). */
  @media (max-height: 760px){
    .skyline{ display:none; }
    header{ padding:8px 16px 4px; }
    .meters{ padding-top:6px; }
  }
  @media (max-height: 700px){
    #core, .corewrap{ width:190px; height:190px; }
    .corebox{ padding:10px 12px 8px; gap:5px; }
    main{ padding-top:8px; }
  }
  /* Móviles estrechos (≤ 370 px, Android pequeños): la etiqueta "CÓMPUTO" se cortaba a "CÓMPU…". */
  @media (max-width: 370px){
    .meter .label{ font-size:.75rem; letter-spacing:.02em; }
    .mat .mn{ font-size:.75rem; letter-spacing:.04em; }
  }
  body.chrome-compact:not(.chrome-open) .app > .meters, body.chrome-compact:not(.chrome-open) .app > .mats, body.chrome-compact:not(.chrome-open) .riskrow{ display:none; }
  /* B8c: a partir del 70% la fila de riesgo se despliega sola aunque la cabecera esté contraída (va después para ganar al display:none) */
  body.chrome-compact.risk-high:not(.chrome-open) .riskrow{ display:flex; }
  .mats[hidden]{ display:none; }
  body.chrome-compact.chrome-open .strip{ border-bottom-color:transparent; }

  /* Deriva en pausa mientras se decide un dilema (5-A): chip en la cabecera en lugar de la fase, y
     medidores atenuados — nada de lo que se ve arriba cambia hasta confirmar. */
  .pausechip{ display:none; align-items:center; gap:6px; margin-top:2px; font-family:"IBM Plex Mono"; font-size:.75rem; letter-spacing:.1em; text-transform:uppercase; color:var(--energy); border:1px solid var(--energy-dim); background:color-mix(in srgb, var(--energy) 10%, var(--surface)); padding:2px 8px; border-radius:6px; white-space:nowrap; width:max-content; }
  .pausechip .pi{ width:8px; height:9px; border-left:2.5px solid var(--energy); border-right:2.5px solid var(--energy); box-sizing:border-box; }
  body.paused header .phase{ display:none; }
  body.paused .pausechip{ display:inline-flex; }
  body.paused .meters, body.paused .strip, body.paused .riskrow{ opacity:.6; }

  /* ganas / pierdes dentro de cada opción del dilema (5-B) */
  /* bloques "ganas" / "pierdes": etiqueta a la izquierda una vez, y sus líneas en columna */
  .fxg{ display:flex; flex-direction:column; gap:3px; padding:5px 7px; border-radius:7px; background:var(--surface-3); }
  .fxg .fxp{ font-family:"IBM Plex Mono"; font-size:.75rem; letter-spacing:.06em; text-transform:uppercase; color:var(--muted); }

  /* pedido explícito del usuario: la barra de scroll de main (la única que se ve a menudo, ya que
     el contenido de cada pestaña suele ser más alto que la pantalla) usaba la barra gris nativa del
     navegador — no pegaba nada con el resto del tema oscuro. Mismo estilo fino que ya usaban los
     modales (.card, más abajo): color del borde en vez de gris del sistema, prácticamente invisible
     hasta que hace falta. */
  main{ flex:1; overflow-y:auto; overflow-x:hidden; padding:10px 16px 16px; -webkit-overflow-scrolling:touch; scrollbar-width:thin; scrollbar-color:var(--border) transparent; }
  main::-webkit-scrollbar{ width:6px; }
  main::-webkit-scrollbar-track{ background:transparent; }
  main::-webkit-scrollbar-thumb{ background:var(--border); border-radius:3px; }
  main > section{ display:none; flex-direction:column; gap:12px; }
  /* animation, no transition: un transition no arranca al pasar de display:none a flex en el mismo
     frame, pero una animation sí se reproduce igual — entrada breve al cambiar de pestaña en vez de
     un corte seco, sin tocar el "display:none" que ya evita renderizar pestañas ocultas. */
  main > section.active{ display:flex; animation:tabIn .16s ease; }
  @keyframes tabIn{ from{ opacity:0; transform:translateY(4px); } to{ opacity:1; transform:none; } }
  @media (prefers-reduced-motion: reduce){ main > section.active{ animation:none; } }
  /* aviso de desbloqueo de pestaña: antes era un toast fijo arriba del todo que se solapaba con la
     cabecera (título/fase quedaban tapados, parecía un glitch) — ahora es un bloque normal dentro
     de <main>, visible encima de la sección activa sea cual sea, sin pisar nada de la cabecera fija. */
  .unlock-banner{ background:color-mix(in srgb, var(--energy) 16%, var(--surface)); border:1px solid var(--energy); border-radius:10px; padding:10px 12px; margin-bottom:12px; color:var(--energy); font-weight:700; font-size:.86rem; line-height:1.35; box-shadow:0 4px 18px -4px rgba(232,163,61,.5); animation:bannerIn .3s ease; }
  @keyframes bannerIn{ from{ opacity:0; transform:translateY(-6px); } to{ opacity:1; transform:none; } }
  /* un <div> normal sin display:flex no reparte el ritmo de 12px del resto de la app entre sus
     propios hijos — bug real reportado por el usuario. */
  #netContent, #anclasContent{ display:flex; flex-direction:column; gap:12px; }
  #convoyFleetSection{ display:flex; flex-direction:column; gap:12px; }
  h2{ margin:0; font-family:"IBM Plex Mono"; font-size:.82rem; letter-spacing:.12em; text-transform:uppercase; color:var(--muted); display:flex; align-items:center; gap:8px; }
  h2::after{ content:""; flex:1; height:1px; background:var(--border); }
  .group{ display:flex; flex-direction:column; gap:7px; }

  nav.tabs{
    display:grid; grid-template-columns:repeat(5,1fr); border-top:1px solid var(--border); background:var(--surface);
    padding-bottom:env(safe-area-inset-bottom,0px);
  }
  /* A9: etiqueta en minúscula, la activa con pastilla rellena, y el aviso como anillo alrededor del
     icono en vez de un punto suelto. */
  nav.tabs button{
    appearance:none; background:none; border:0; color:var(--muted); font-family:"IBM Plex Mono"; font-size:.75rem; letter-spacing:0;
    padding:7px 2px 6px; margin:5px 4px 7px; border-radius:10px; cursor:pointer; position:relative; display:flex; flex-direction:column; align-items:center; gap:3px;
  }
  nav.tabs button svg{ width:18px; height:18px; fill:none; stroke:currentColor; stroke-width:1.6; stroke-linecap:round; stroke-linejoin:round; }
  nav.tabs button.active{ color:var(--compute); background:var(--surface-2); }
  /* la barra de navegación es lo que más se toca en todo el juego y era de las pocas cosas sin
     ningún feedback al pulsar — auditoría de consistencia de microinteracciones. */
  nav.tabs button:active{ transform:scale(.9); }
  /* El aviso de "hay algo nuevo" en Red/Investigar/Anclas usa el MISMO pulso que Construir e
     Investigar (.tab-armed más abajo); el anillo alrededor del icono se descartó porque era un
     lenguaje distinto para lo mismo (pedido del usuario, 2026-09-28). El <span class="badge">
     queda en el HTML sin pintar. */
  nav.tabs button .badge{ display:none; }
  nav.tabs button.has-badge{ color:var(--energy); animation:tabPulse 1.4s ease-in-out infinite; border-radius:8px; }
  @media (prefers-reduced-motion: reduce){ nav.tabs button.has-badge{ animation:none; box-shadow:inset 0 0 0 2px var(--energy-dim); } }

  /* core */
  .corebox{ background:var(--surface); border:1px solid var(--border); border-radius:14px; padding:12px 12px 10px; display:flex; flex-direction:column; align-items:center; gap:6px; position:relative; overflow:hidden; }
  /* A10: fondo de fase como dos capas que se funden (1,5 s) en vez de cambiar de golpe */
  .corebox .corebg{ position:absolute; inset:0; background-size:cover; background-position:center; opacity:0; transition:opacity 1.5s ease; z-index:0; }
  .corebox .corebg.on{ opacity:1; }
  .corebox > :not(.corebg){ position:relative; z-index:1; }
  @media (prefers-reduced-motion: reduce){ .corebox .corebg{ transition:none; } }
  /* guía de primeros pasos (ver guide.js), primer paso: resalta el propio núcleo mientras el
     jugador todavía no ha tocado ni una vez — mismo lenguaje que el resto de la guía. */
  .corebox.guide-armed{ border-color:var(--energy-dim); box-shadow:0 0 0 3px color-mix(in srgb, var(--energy) 30%, transparent); animation:calloutIn .6s ease-out 1; }
  /* el ::before pinta un velo semitransparente del color de fondo por encima de la ilustración de
     fase (si hay una puesta en background-image), para que el texto/canvas encima siga legible */
  .corebox::before{ content:""; position:absolute; inset:0; background:repeating-linear-gradient(0deg, transparent 0 3px, rgba(255,255,255,.012) 3px 4px), color-mix(in srgb, var(--surface) 34%, transparent); pointer-events:none; }
  /* G1 · foco y viñeta (2026-10-09): el velo uniforme de arriba baja del 62% al 34% y, encima, una
     viñeta que deja la sala en penumbra hacia los bordes y un círculo oscuro detrás del núcleo.
     Así la ilustración se ve, pero no compite con la figura. */
  .corebox .corevig{ position:absolute; inset:0; z-index:0; pointer-events:none;
    background:radial-gradient(ellipse 60% 56% at 50% 46%, rgba(7,10,12,.30) 0, rgba(7,10,12,.62) 55%, rgba(7,10,12,.94) 100%); }
  /* G2 · peana y luz en el suelo (2026-10-09): el núcleo descansa sobre una peana con sombra de
     contacto y tiñe el suelo con su color de estado (--corecol, la pone core-canvas.js: verde en
     calma, ámbar en Sobrecarga, rojo con riesgo alto, gris en apagón). Va detrás de los dos
     lienzos (z-index -1 dentro del contexto de .corewrap) y delante de la ilustración. */
  .corewrap .peana{ position:absolute; left:50%; bottom:3%; width:54%; height:13%; transform:translateX(-50%); z-index:-1; pointer-events:none; --cc:var(--corecol, 82,224,196); }
  .corewrap .peana i{ position:absolute; display:block; border-radius:50%; }
  .corewrap .peana .pool{ left:-45%; right:-45%; top:-30%; bottom:-40%; background:radial-gradient(ellipse at 50% 50%, rgba(var(--cc),.45) 0, rgba(var(--cc),.16) 45%, rgba(var(--cc),0) 72%); mix-blend-mode:screen; transition:background .8s ease; }
  .corewrap .peana .cone{ left:18%; right:18%; top:-300%; bottom:40%; border-radius:45% 45% 50% 50% / 30% 30% 50% 50%; background:linear-gradient(to top, rgba(var(--cc),.30), rgba(var(--cc),.08) 55%, rgba(var(--cc),0) 90%); transition:background .8s ease; }
  .corewrap .peana .shadow{ left:-6%; right:-6%; top:34%; bottom:-26%; background:rgba(0,0,0,.62); filter:blur(3px); }
  .corewrap .peana .side{ left:0; right:0; top:32%; bottom:0; border-radius:0 0 50% 50% / 0 0 100% 100%; background:linear-gradient(to bottom, #131c23, #0b1115); }
  .corewrap .peana .top{ left:0; right:0; top:0; bottom:38%; background:radial-gradient(ellipse at 50% 40%, #223040, #151f28 70%); box-shadow:inset 0 0 0 1.5px rgba(var(--cc),.75), inset 0 0 8px rgba(var(--cc),.35); transition:box-shadow .8s ease; }
  @media (prefers-reduced-motion: reduce){ .corewrap .peana .pool, .corewrap .peana .cone, .corewrap .peana .top{ transition:none; } }
  /* ::before es positioned y pintaría por encima de los hijos normales (sin posición) del corebox
     — se sube el resto del contenido a su propio contexto de apilamiento para que quede legible */
  .corebox > *{ position:relative; z-index:1; }
  .corebox .readout{ font-size:.78rem; color:var(--text); letter-spacing:.1em; text-transform:uppercase; background:rgba(7,10,12,.72); border:1px solid rgba(38,49,57,.8); border-radius:999px; padding:4px 11px; backdrop-filter:blur(2px); text-align:center; max-width:100%; box-sizing:border-box; }
  #core{ width:230px; height:230px; max-width:100%; cursor:pointer; touch-action:manipulation; border-radius:50%; }
  #core:active{ transform:scale(.97); }
  .corebox .pill, .clickval, .ritmo{ background:rgba(7,10,12,.72); border:1px solid rgba(38,49,57,.8); border-radius:999px; padding:4px 11px; backdrop-filter:blur(2px); box-sizing:border-box; }
  .clickval{ font-family:"IBM Plex Mono"; font-size:.78rem; color:var(--compute); }
  .clickval small{ color:var(--muted-2); font-size:.78rem; }
  .ritmo{ display:flex; align-items:center; gap:8px; width:220px; max-width:100%; }
  .ritmo .rl{ font-size:.75rem; letter-spacing:.1em; text-transform:uppercase; color:var(--muted-2); }
  .ritmo .rt{ flex:1; height:4px; border-radius:2px; background:var(--surface-3); overflow:hidden; }
  .ritmo .rt > div{ height:100%; width:0; background:var(--compute); transition:width .12s linear; }
  .ritmo .rv{ font-size:.76rem; color:var(--muted); min-width:30px; text-align:right; }
  .fleet{ display:flex; flex-wrap:wrap; gap:6px; justify-content:center; }
  .fleet:empty{ display:none; }
  .fleet .fc{ display:inline-flex; align-items:center; gap:5px; padding:4px 8px 4px 5px; border-radius:7px; background:var(--surface); border:1px solid var(--border); font-family:"IBM Plex Mono"; font-size:.8rem; color:var(--muted); }
  .fleet .fc svg{ width:16px; height:16px; }
  .fleet .fc b{ color:var(--text); font-weight:600; }
  .goal{ font-size:.88rem; color:var(--muted); text-align:center; line-height:1.4; }
  .goal b{ color:var(--text); font-weight:600; }

  .abilities{ display:grid; grid-template-columns:1fr 1fr; gap:7px; }
  .ability{ background:var(--surface); border:1px solid var(--border); border-radius:10px; padding:9px 10px; display:flex; flex-direction:column; gap:3px; cursor:pointer; position:relative; overflow:hidden; }
  .ability .an{ font-weight:600; font-size:.8rem; display:flex; align-items:center; gap:6px; }
  .ability .an svg{ width:16px; height:16px; }
  .ability .ad{ font-size:.8rem; color:var(--muted); line-height:1.35; }
  .ability .cd{ position:absolute; left:0; bottom:0; height:3px; background:var(--compute); width:0; }
  .ability.disabled{ opacity:.45; cursor:not-allowed; }
  .ability.on{ border-color:var(--compute-dim); box-shadow:inset 0 0 0 1px var(--compute-dim); }

  .traincard{ background:var(--surface); border:1px solid var(--research-dim); border-radius:10px; padding:10px 12px; display:flex; flex-direction:column; gap:6px; }
  .traincard .tn{ font-family:"IBM Plex Mono"; font-size:.78rem; color:var(--research); }
  .traincard .tr-head{ display:flex; align-items:center; gap:8px; }
  .traincard .tr-thumb{ width:40px; height:40px; border-radius:8px; object-fit:cover; flex-shrink:0; }
  .bar{ height:6px; border-radius:3px; background:var(--surface-3); overflow:hidden; }
  .bar > div{ height:100%; width:0; background:var(--research); transition:width .2s linear; }

  /* rows */
  .row{ background:var(--surface); border:1px solid var(--border); border-radius:10px; padding:9px 10px; display:flex; align-items:center; gap:10px; }
  .row .icon{ width:38px; height:38px; border-radius:9px; flex:none; display:flex; align-items:center; justify-content:center; background:var(--surface-2); border:1px solid var(--border); overflow:hidden; }
  .row .icon svg{ width:24px; height:24px; }
  .row .icon img{ width:100%; height:100%; object-fit:cover; }
  .row .info{ flex:1; min-width:0; }
  .row .name{ font-family:"IBM Plex Mono"; font-size:.9rem; font-weight:600; display:flex; align-items:center; gap:6px; }
  /* A3: fila compacta de edificio — una línea "1,5/u → +21 ⬡/s"; tocar la fila (no los botones)
     despliega el detalle de siempre (por unidad completo, producción total con bonus). */
  .row .line{ display:flex; align-items:center; gap:5px; font-family:"IBM Plex Mono"; font-size:.76rem; color:var(--muted-2); margin-top:3px; flex-wrap:wrap; }
  .row .line .arrow{ color:var(--muted-2); }
  .row .line .tot{ font-weight:600; }
  .row .line .tot.compute{ color:var(--compute); } .row .line .tot.research{ color:var(--research); } .row .line .tot.data{ color:var(--data); } .row .line .tot.energy{ color:var(--energy); } .row .line .tot.risk{ color:var(--risk); }
  .row .details{ margin-top:5px; padding-top:5px; border-top:1px dashed var(--border); animation:coldetailIn .16s ease; }
  .row .info.tappable{ cursor:pointer; }
  .row .chev{ width:9px; height:9px; border-right:1.5px solid var(--muted-2); border-bottom:1.5px solid var(--muted-2); transform:rotate(45deg); margin-left:auto; margin-right:4px; transition:transform .15s; flex:none; }
  .row.open .chev{ transform:rotate(-135deg); }
  /* A1: glifo de recurso (currentColor) para sustituir "cómp · ene · inv · dat" */
  .ri{ width:11px; height:11px; vertical-align:-1px; margin-right:2px; fill:none; stroke:currentColor; stroke-width:2; stroke-linecap:round; stroke-linejoin:round; display:inline-block; }
  .ri.f{ fill:currentColor; stroke:none; }
  .ri.mi{ width:12px; height:12px; stroke-width:3; }
  /* chip de material: icono + cantidad + nombre, en el color de su tipo de colonia */
  .matc{ display:inline-flex; align-items:center; gap:4px; font-family:"IBM Plex Mono"; white-space:nowrap; }
  .matc i{ font-style:normal; font-weight:600; }
  .row button .eta{ display:block; font-size:.75rem; color:var(--muted-2); font-weight:400; margin-top:1px; }
  .row .name .cnt{ font-family:"IBM Plex Mono"; font-size:.82rem; color:var(--compute); }
  /* botón de vender: deliberadamente discreto (un "−" pequeño junto al contador, no un botón grande
     al lado de comprar) — pedido explícito del usuario tras encontrar la versión anterior demasiado
     presente. Ajustado dos veces desde entonces: (1) algún jugador casi no lo veía — la opacity:.65
     original dejaba el contraste real en ~2,7:1 contra el fondo, muy por debajo del mínimo de
     4,5:1 — así que se quitó la opacity y se rellenó el círculo con --risk-bg; (2) ese relleno
     resultó ser DEMASIADO llamativo ("ahora es demasiado visible", pedido explícito). Punto medio
     final: sin opacity (eso sí que hacía falta) pero sin relleno (vuelve a transparent) y con el
     borde en el tono apagado --risk-dim en vez del rojo a todo color — solo el propio "−" queda a
     todo color y en semi-negrita, así se distingue de verdad sin ser un círculo sólido llamativo.
  */
  .sellmini{ appearance:none; width:19px; height:19px; border-radius:50%; border:1px solid var(--risk-dim); background:transparent; color:var(--risk); font-family:"IBM Plex Mono"; font-weight:600; font-size:.85rem; line-height:1; padding:0; cursor:pointer; flex:none; }
  .sellmini:active{ transform:scale(.9); }
  /* botón de información: pedido explícito para explicar mecánicas (p.ej. qué son las colonias,
     que pueden mandar recursos solas al núcleo) sin llenar la pantalla de texto permanente */
  .infobtn{ appearance:none; width:16px; height:16px; border-radius:50%; border:1px solid var(--muted-2); background:transparent; color:var(--muted-2); font-family:"IBM Plex Mono"; font-style:italic; font-size:.68rem; line-height:1; padding:0; cursor:pointer; flex:none; }
  .infobtn:active{ transform:scale(.9); }
  .row .desc{ font-size:.8rem; color:var(--muted); margin-top:1px; line-height:1.35; }
  /* motivo de bloqueo (sin recursos locales / sin huecos): ni gris neutro (se confunde con la
     descripción) ni rojo de riesgo (no es un error, es una guía) — tono cálido intermedio. */
  .row .desc.reason{ color:var(--energy); margin-top:3px; }
  .row .own{ font-size:.78rem; color:var(--muted-2); margin-top:2px; }
  .row .rowlbl{ font-family:"IBM Plex Mono"; font-size:.75rem; letter-spacing:.07em; text-transform:uppercase; margin-right:6px; opacity:.75; }
  .row .desc .rowlbl{ color:var(--muted); }
  .row .own .rowlbl{ color:var(--muted-2); }
  /* :not(.sellmini) porque ".row button" (clase+elemento) tiene más especificidad que ".sellmini"
     (una sola clase) y le pisaba el tamaño: el "−" de vender salía como una píldora de 78px en vez
     del círculo pequeño de 18px que dice su propia regla — bug real reportado por el usuario
     ("botón demasiado grande, no se entiende para qué sirve"). */
  .row button:not(.sellmini){
    appearance:none; border:1px solid var(--border); background:var(--surface-2); color:var(--text);
    font-family:"IBM Plex Mono"; font-size:.84rem; font-weight:600; border-radius:8px; padding:7px 8px; min-width:78px; text-align:center; cursor:pointer; flex:none; line-height:1.3;
  }
  .row button .c{ display:block; }
  .row button .c.compute{ color:var(--compute); } .row button .c.research{ color:var(--research); } .row button .c.data{ color:var(--data); } .row button .c.energy{ color:var(--energy); }
  .row button:disabled{ opacity:.38; cursor:not-allowed; }
  .row button:not(.sellmini):not(:disabled):active{ transform:scale(.96); }
  .row.new{ border-color:var(--compute-dim); }
  .row.done{ opacity:.55; }
  .row.done .icon{ border-color:var(--compute-dim); }
  /* guía de primeros pasos (ver guide.js): la fila recomendada se resalta con el mismo lenguaje
     que el recuadro de Doctrina (--energy, "mira aquí"), y el resto de filas de Construir se
     atenúa mientras la guía está activa para que solo haya una cosa que hacer a la vez — pedido
     explícito del usuario tras ver que un jugador nuevo no sabía cuál de las 3 comprar primero. */
  #tab-build.guiding .row:not(.guide-armed){ opacity:.5; }
  .row.guide-armed{ border-color:var(--energy); background:color-mix(in srgb, var(--energy) 12%, var(--surface)); box-shadow:0 0 0 2px color-mix(in srgb, var(--energy) 25%, transparent); animation:calloutIn .6s ease-out 1; }
  .flash-new{ animation:flashNew 1.2s ease-out 1; }
  @keyframes flashNew{ 0%{ box-shadow:0 0 0 0 rgba(232,163,61,.7); } 100%{ box-shadow:0 0 0 14px rgba(232,163,61,0); } }
  .callout.tap{ cursor:pointer; position:relative; }
  .callout .see{ position:absolute; right:14px; top:12px; font-family:"IBM Plex Mono"; font-size:.75rem; color:var(--energy); }

  .qty{ display:flex; gap:4px; }
  .qty button{ appearance:none; border:1px solid var(--border); background:var(--surface); color:var(--muted); font-family:"IBM Plex Mono"; font-size:.78rem; padding:4px 9px; border-radius:6px; cursor:pointer; }
  .qty button.active{ color:var(--compute); border-color:var(--compute-dim); }
  .qty button:active{ transform:scale(.92); }
  .subhead{ display:flex; align-items:center; justify-content:space-between; gap:8px; }
  .subhead h2{ flex:1; }

  /* recuadro de Doctrina: antes era un <h2> igual que cualquier otro título de sección, y el
     usuario reportó que "no se sabe que hay que hacer click ahí" — es la primera decisión
     importante del juego (permanente para la Deriva) y no destacaba nada. Mismo lenguaje visual
     que ya usa el juego para "esto importa, mira aquí" (--energy: banner de desbloqueo de
     pestaña, botón de Fusión). Entrada con fundido + deslizamiento (mismo patrón que
     .unlock-banner/bannerIn), no un destello de box-shadow: con la guía de primeros pasos este
     recuadro aparece y desaparece de golpe (vía `hidden`) cada vez que se cambia de pestaña, y el
     destello anterior hacía que la transición se sintiera brusca/rara — pedido explícito del
     usuario tras probarlo. */
  .callout{ border:1px solid var(--energy-dim); border-radius:12px; padding:12px 14px; margin-bottom:14px; background:color-mix(in srgb, var(--energy) 10%, var(--surface)); animation:calloutIn .3s ease; }
  .callout .eyebrow{ font-family:"IBM Plex Mono"; font-size:.78rem; letter-spacing:.12em; text-transform:uppercase; color:var(--energy); }
  .callout h2{ margin:2px 0 4px; }
  .callout .callout-cta{ font-size:.86rem; color:var(--text); margin:0 0 10px; }
  @keyframes calloutIn{ from{ opacity:0; transform:translateY(-6px); } to{ opacity:1; transform:none; } }
  @media (prefers-reduced-motion: reduce){ .callout{ animation:none; } }

  .branches{ display:flex; flex-direction:column; gap:8px; }
  .branch{ background:var(--surface); border:1px solid var(--border); border-radius:10px; padding:11px 12px; display:flex; gap:10px; cursor:pointer; align-items:center; }
  .branch:active{ transform:scale(.985); }
  .branch .icon{ width:36px; height:36px; flex:none; border-radius:9px; background:var(--surface-2); border:1px solid var(--border); display:flex; align-items:center; justify-content:center; overflow:hidden; }
  .branch .icon svg{ width:22px; height:22px; }
  .branch .icon img{ width:100%; height:100%; object-fit:cover; }
  .branch .binfo{ flex:1; min-width:0; }
  .branch .bn{ font-weight:700; font-size:.84rem; }
  .branch .bd{ font-size:.84rem; color:var(--muted); line-height:1.4; margin-top:2px; }
  /* chip "Elegir ›": única pista visual explícita de que la tarjeta entera es pulsable, no solo
     una ficha informativa — ver nota de arriba sobre por qué hacía falta. */
  .branch .bchoose{ flex:none; align-self:center; font-family:"IBM Plex Mono"; font-size:.75rem; letter-spacing:.03em; text-transform:uppercase; color:var(--energy); border:1px solid var(--energy-dim); border-radius:6px; padding:4px 8px; white-space:nowrap; }
  .branch.militar{ border-color:var(--risk-dim); } .branch.cientifica{ border-color:var(--research-dim); } .branch.social{ border-color:var(--compute-dim); }
  .note{ font-size:.86rem; color:var(--muted); line-height:1.45; }
  .note.warn{ color:var(--risk); }
  /* fuera de <main> (junto a .meters/.riskrow, que también se pintan por encima de las pestañas),
     así que necesita su propio padding lateral — dentro de main lo hereda del contenedor, aquí no.
     Pedido explícito del usuario: visible desde cualquier pantalla, no solo Núcleo. */
  #energyNoteCore{ padding:4px 16px 0; }

  /* árbol de Anclas */
  /* Antes un único texto centrado "N Anclas disponibles" — pedido explícito del usuario para
     mejorar esta UI: ahora dos cifras lado a lado, mismo lenguaje visual que los medidores de
     recurso de Núcleo (.meter), para que "ganadas en total" (nunca baja al gastar) conviva con el
     saldo gastable en vez de quedar invisible en unas estadísticas que ya nadie ve. */
  .anclas-balance{ display:flex; gap:8px; margin-bottom:12px; }
  .anclas-balance .ab-stat{ flex:1; min-width:0; background:var(--surface); border:1px solid var(--border); border-radius:10px; padding:9px 8px; text-align:center; }
  /* Segunda pasada pedida por el usuario: mismo color que ya tenían (--compute), pero sin negrita y
     con la etiqueta también en ese color (antes gris apagado) — "para que se vieran mejor". */
  .anclas-balance .ab-n{ display:block; font-family:"IBM Plex Mono"; font-size:1.1rem; font-weight:400; color:var(--compute); }
  .anclas-balance .ab-label{ display:block; font-size:.75rem; color:var(--compute); text-transform:uppercase; letter-spacing:.04em; margin-top:2px; }
  .anclas-branch{ margin-bottom:18px; }
  .anclas-branch .branch-head{ margin-bottom:8px; }
  .anclas-branch.militar .branch-head{ border-left:3px solid var(--risk); }
  .anclas-branch.cientifica .branch-head{ border-left:3px solid var(--research); }
  .anclas-branch.social .branch-head{ border-left:3px solid var(--compute); }
  .anclas-branch .branch-head{ padding-left:8px; display:flex; align-items:baseline; gap:8px; flex-wrap:wrap; }
  .anclas-branch .branch-emblem{ width:26px; height:26px; flex:none; object-fit:contain; }
  .anclas-branch .branch-name{ font-weight:700; font-size:.98rem; }
  /* qué doctrina desbloquea esta rama (Guerra=Militar, Método=Científica, Red=Social) — antes no
     se veía en ningún sitio, pedido explícito del usuario. Mono/mayúsculas para leerse como una
     etiqueta de origen, distinta del nombre en-ficción y del lema. */
  .anclas-branch .branch-doctrine{ font-family:"IBM Plex Mono"; font-size:.75rem; letter-spacing:.04em; text-transform:uppercase; color:var(--muted-2); }
  .anclas-branch .branch-tag{ font-size:.78rem; color:var(--muted); }
  .anclas-nodes{ display:flex; flex-direction:column; gap:6px; }
  .anode.bought{ opacity:.6; }
  .anode.bought .icon{ border-color:var(--compute-dim); }
  .anode .cnt.bought-tag{ color:var(--compute); font-family:"IBM Plex Mono"; font-size:.75rem; text-transform:uppercase; letter-spacing:.05em; }
  .anode .cnt.capstone-tag{ color:var(--energy); font-family:"IBM Plex Mono"; font-size:.75rem; text-transform:uppercase; letter-spacing:.05em; }
  /* Resaltada en el mismo amarillo/ámbar que el resto de avisos "toca decidir algo aquí" del
     juego (tab-armed, guide-armed, .callout) — pedido explícito del usuario: antes era una caja
     sin ningún color propio, se perdía entre el resto de filas de la rama. */
  .waychoice{ display:flex; flex-direction:column; gap:7px; margin:4px 0 8px; padding:12px 14px; border:1px solid var(--energy-dim); border-radius:12px; background:color-mix(in srgb, var(--energy) 10%, var(--surface)); }
  .waychoice .wc-label{ color:var(--energy); }
  /* sin ".waychoice" delante: ya se usaba también dentro de .legado-box (Reliquias) sin que esta
     regla llegara a aplicarse ahí (texto plano sin estilo) — se ensancha para que funcione en
     cualquier sitio que la use. */
  .wc-label{ font-family:"IBM Plex Mono"; font-size:.75rem; letter-spacing:.08em; text-transform:uppercase; color:var(--muted); }
  .wcbtn{
    appearance:none; text-align:left; background:var(--surface-2); border:1px solid var(--border); color:var(--text);
    border-radius:10px; padding:10px 12px; cursor:pointer; display:flex; flex-direction:column; gap:3px; font-family:inherit; width:100%;
  }
  .wcbtn:active{ transform:scale(.985); }
  .wcbtn .wcn{ font-weight:700; font-size:.9rem; }
  .wcbtn .wct{ font-size:.78rem; color:var(--muted); }
  .wcbtn .wcperm{ font-family:"IBM Plex Mono"; font-size:.75rem; letter-spacing:.02em; color:var(--muted-2); }
  .waylocked{ font-size:.82rem; color:var(--muted-2); padding:6px 2px; }

  /* Legado */
  .legado-box{ background:var(--surface); border:1px solid var(--energy-dim, var(--border)); border-radius:12px; padding:12px 14px; margin-bottom:14px; }
  .legado-head{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
  .legado-count{ font-family:"IBM Plex Mono"; font-weight:700; color:var(--energy); }
  .legado-tag{ font-family:"IBM Plex Mono"; font-size:.75rem; letter-spacing:.05em; text-transform:uppercase; color:var(--energy); background:var(--energy-bg,transparent); border:1px solid var(--energy-dim,var(--border)); border-radius:5px; padding:2px 7px; }
  /* Reliquias: antes chips pequeños con la descripción solo en el title (invisible en móvil, sin
     hover) — ahora una fila por Reliquia con la descripción siempre visible como texto, igual que
     el resto de filas de edificio/tecnología del juego, para que se entienda qué hace cada una sin
     tener que adivinarlo (queja real del usuario). Las 6 se listan siempre, no solo las
     desbloqueadas, para que el jugador sepa qué le queda por delante. */
  .legado-reliquias{ display:flex; flex-direction:column; gap:6px; margin-top:6px; }
  /* .55 de opacidad sobre un texto que YA era --muted componía las dos atenuaciones y bajaba el
     contraste real a ~3,4:1 contra el fondo — por debajo del mínimo de 4,5:1 que ya es norma en
     este proyecto para legibilidad en móvil. .7 mantiene la distinción visual de "bloqueado" con
     ~4,9:1, dentro del mínimo. */
  .reliquia-row.locked{ opacity:.7; }
  .reliquia-row.locked .name{ color:var(--muted); }
  .reliquia-row.equipped{ border-color:var(--energy-dim); }
  .legado-archivo{ margin-top:10px; padding-top:8px; border-top:1px solid var(--border); }
  .archivo-row{ font-size:.8rem; color:var(--muted); padding:2px 0; }

  .modelcard{ background:var(--surface); border:1px solid var(--border); border-radius:10px; padding:11px 12px; display:flex; flex-direction:column; gap:6px; }
  .modelcard.next{ border-color:var(--research-dim); }
  /* siguiente objetivo tras la guía de primeros pasos (ver guide.js): mismo lenguaje que el resto
     de resaltados guiados (--energy), para que el Modelo v1 destaque incluso por encima del
     borde violeta normal de "próximo modelo". */
  .modelcard.guide-armed{ border-color:var(--energy-dim); background:color-mix(in srgb, var(--energy) 12%, var(--surface)); animation:calloutIn .3s ease; }
  /* Modelo ya entrenado: mismo lenguaje visual que un logro conseguido (borde/acento en --compute)
     más un tinte de fondo, para que de un vistazo se distinga de la tarjeta del siguiente modelo,
     que va en violeta (--research). */
  .modelcard.done{ background:color-mix(in srgb, var(--compute) 12%, var(--surface)); border-color:var(--compute-dim); }
  .modelcard.done .mn .lvl{ color:var(--compute); }
  .modelcard .mn{ font-family:"IBM Plex Mono"; font-weight:600; font-size:.82rem; display:flex; justify-content:space-between; align-items:center; gap:8px; }
  .modelcard .mn .lvl{ color:var(--research); font-size:.82rem; }
  .modelcard .md{ font-size:.84rem; color:var(--muted); line-height:1.4; }
  .costs{ display:flex; flex-wrap:wrap; gap:6px; }
  .cost{ font-family:"IBM Plex Mono"; font-size:.8rem; padding:3px 7px; border-radius:6px; background:var(--surface-2); border:1px solid var(--border); }
  .cost.ok{ color:var(--text); } .cost.no{ color:var(--risk); }
  .cost.no .matc{ color:var(--risk) !important; }
  .btn{ appearance:none; border:1px solid var(--research-dim); background:var(--surface-2); color:var(--research); font-family:"IBM Plex Mono"; font-weight:600; font-size:.88rem; padding:9px 12px; border-radius:8px; cursor:pointer; }
  .btn:disabled{ opacity:.4; cursor:not-allowed; }
  /* faltaba en .btn "a secas" (Guardar, Borrar partida, Fondos infinitos, Ver códice, Entrenar,
     Equipar/Quitar Reliquia...) — solo la variante .legend tenía este toque; el resto de botones
     del juego sí lo tienen, auditoría de consistencia de microinteracciones. */
  .btn:not(:disabled):active{ transform:scale(.96); }
  .btn.ghost{ color:var(--muted); border-color:var(--border); }
  .btn.danger{ color:var(--risk); border-color:var(--risk-dim); }
  /* botón de fusión permanente en el Núcleo: pedido explícito porque si el jugador dice "no" al
     terminar el Modelo v6 no tenía forma de volver a fusionar luego — color propio (dorado, el
     mismo tono que los toasts de logro) para que destaque de cualquier otro botón de la pantalla */
  .btn.legend{ color:var(--energy); border-color:var(--energy-dim); background:color-mix(in srgb, var(--energy) 14%, var(--surface)); font-weight:600; }
  .btn.legend:active{ transform:scale(.98); }

  /* ---------- sistema de botones (feedback beta, 7.6): cuatro y siempre los mismos ----------
     primaria = la acción que hace avanzar; secundaria = el resto; peligro = perder algo;
     atención (naranja) = "mira aquí" (siguiente paso, guía, anuncio). Se aplica pantalla a
     pantalla; el resto de botones antiguos siguen existiendo hasta que les toque. */
  .btn-p, .btn-s, .btn-d, .btn-a{ appearance:none; font-family:"IBM Plex Mono"; font-weight:700; font-size:.84rem; padding:11px 14px; border-radius:10px; cursor:pointer; border:1px solid transparent; line-height:1.2; }
  .btn-p{ background:var(--compute); color:#062b24; }
  .btn-s{ background:var(--surface-2); border-color:var(--border); color:var(--text); font-weight:600; }
  .btn-d{ background:transparent; border-color:var(--risk-dim); color:var(--risk); font-weight:600; }
  .btn-a{ background:var(--energy); color:#3a2405; }
  .btn-p:disabled, .btn-s:disabled, .btn-d:disabled, .btn-a:disabled{ opacity:.45; cursor:not-allowed; }
  .btn-p:not(:disabled):active, .btn-s:not(:disabled):active, .btn-d:not(:disabled):active, .btn-a:not(:disabled):active{ transform:scale(.97); }
  .btn-back{ appearance:none; border:1px solid var(--border); background:rgba(8,11,13,.7); color:var(--muted); font-family:"IBM Plex Mono"; font-size:.75rem; padding:6px 10px; border-radius:8px; cursor:pointer; }
  .ghostlink{ background:none; border:none; text-decoration:underline; color:var(--muted-2); font-size:.75rem; align-self:center; padding:6px; }
  h2.plain{ text-transform:none; letter-spacing:0; color:var(--text); font-size:1.2rem; font-weight:600; }
  h2.plain::after{ display:none; }

  /* ---------- Red: mapa ---------- */
  .netmap{ background:#0d1216; border:1px solid var(--border); border-radius:14px; overflow:hidden; }
  .netmap svg{ display:block; width:100%; height:auto; }
  /* diseño A de Red: fila de la nave de despliegue + tecnología, y "siguiente paso" como línea tocable */
  .shiprow{ background:var(--surface); border:1px solid var(--border); border-radius:12px; padding:10px 12px; display:flex; align-items:center; gap:10px; }
  .shiprow .icon{ width:38px; height:38px; border-radius:10px; flex:none; display:flex; align-items:center; justify-content:center; background:color-mix(in srgb, var(--compute) 10%, var(--surface)); color:var(--compute); }
  .shiprow .icon svg{ width:20px; height:20px; fill:none; stroke:currentColor; stroke-width:1.6; stroke-linecap:round; stroke-linejoin:round; }
  .shiprow.tech .icon{ background:var(--surface-2); color:var(--research); }
  .shiprow .info{ flex:1; min-width:0; }
  .shiprow .name{ font-size:.88rem; font-weight:600; }
  .shiprow .name .st{ font-family:"IBM Plex Mono"; font-size:.75rem; color:var(--muted); font-weight:500; }
  .shiprow .bar{ height:5px; border-radius:3px; background:var(--bg); overflow:hidden; margin-top:5px; }
  .shiprow .bar > div{ height:100%; width:0; background:var(--compute); transition:width .3s linear; }
  .shiprow .own{ font-size:.75rem; color:var(--muted); margin-top:3px; line-height:1.35; }
  .shiprow .own .c{ font-family:"IBM Plex Mono"; font-weight:600; margin-right:4px; }
  .shiprow .btn-s{ flex:none; padding:8px 10px; font-size:.78rem; }
  .shiprow .btn-s .c{ margin-left:2px; }
  .shiprow.launch-armed{ border-color:var(--compute-dim); background:color-mix(in srgb, var(--compute) 8%, var(--surface)); }
  .nextline{ appearance:none; width:100%; text-align:left; font-family:inherit; display:flex; align-items:center; gap:8px; padding:9px 11px; border-radius:10px; background:color-mix(in srgb, var(--energy) 8%, var(--surface)); border:1px solid var(--energy-dim); color:var(--text); font-size:.82rem; line-height:1.35; cursor:default; }
  .nextline svg{ width:15px; height:15px; flex:none; color:var(--energy); }
  .nextline .chev{ display:none; margin-left:auto; color:var(--energy); font-size:1.1rem; line-height:1; }
  .nextline.act{ cursor:pointer; } .nextline.act .chev{ display:block; }
  .nextline b, .nextline .mat-name{ color:var(--energy); font-weight:600; }
  .netsum{ display:flex; justify-content:space-between; align-items:center; padding:8px 12px 10px; font-family:"IBM Plex Mono"; font-size:.75rem; color:var(--muted); border-top:1px solid #1a2228; }
  /* siguiente paso y primera colonia */
  .nextstep{ background:color-mix(in srgb, var(--energy) 8%, var(--surface)); border:1px solid var(--energy-dim); border-radius:14px; padding:12px 14px; display:flex; flex-direction:column; gap:8px; }
  .nextstep .eyebrow{ font-family:"IBM Plex Mono"; font-size:.75rem; letter-spacing:.12em; text-transform:uppercase; color:var(--energy); }
  .nextstep p{ margin:0; font-size:.88rem; line-height:1.45; }
  .nextstep .btn-s, .firstcol .btn-s{ display:flex; justify-content:space-between; }
  .firstcol{ background:var(--surface); border:1px solid var(--compute-dim); border-radius:14px; padding:14px; display:flex; flex-direction:column; gap:8px; }
  .firstcol .eyebrow{ font-family:"IBM Plex Mono"; font-size:.75rem; letter-spacing:.12em; text-transform:uppercase; color:var(--compute); }
  .firstcol h2{ margin:0; font-size:1.05rem; }
  .firstcol p{ margin:0; font-size:.86rem; line-height:1.5; color:var(--muted); }
  .steps{ display:flex; flex-direction:column; gap:8px; margin:4px 0; }
  .step{ display:flex; gap:10px; align-items:flex-start; font-size:.84rem; line-height:1.4; color:var(--muted); }
  .step .n{ width:22px; height:22px; border-radius:50%; flex:none; display:flex; align-items:center; justify-content:center; font-family:"IBM Plex Mono"; font-size:.75rem; font-weight:700; border:1px solid var(--border); color:var(--muted-2); background:var(--surface-2); }
  .step.now{ color:var(--text); } .step.now .n{ background:var(--compute); color:#062b24; border-color:var(--compute); }
  .step .t b{ font-weight:600; color:var(--text); }
  .step .t span{ display:block; font-family:"IBM Plex Mono"; font-size:.75rem; color:var(--muted-2); margin-top:1px; }
  .firstcol .why{ font-size:.8rem; line-height:1.5; color:var(--muted); margin-top:2px; }
  .firstcol .why .l{ display:flex; gap:6px; flex-wrap:wrap; margin-top:6px; }
  .firstcol .why .l span{ font-family:"IBM Plex Mono"; font-size:.75rem; padding:3px 8px; border-radius:6px; border:1px solid var(--border); background:var(--surface-2); }
  /* tarjeta de colonia (lista) */
  .colc{ width:100%; text-align:left; font-family:inherit; color:var(--text); background:var(--surface); border:1px solid var(--border); border-radius:14px; padding:11px 12px 11px 14px; display:block; position:relative; overflow:hidden; cursor:pointer; }
  .colc::before{ content:""; position:absolute; left:0; top:0; bottom:0; width:4px; background:var(--cc); }
  .colc:active{ transform:scale(.99); }
  .colc .m{ flex:1; min-width:0; }
  .colc .nm{ font-family:"IBM Plex Mono"; font-weight:600; font-size:.9rem; display:flex; gap:6px; align-items:baseline; flex-wrap:wrap; }
  .colc .nm .sz{ font-size:.75rem; color:var(--muted-2); letter-spacing:.05em; text-transform:uppercase; font-weight:400; }
  .colc .ch{ display:flex; align-items:center; justify-content:space-between; gap:8px; }
  .colc .go{ flex:none; font-family:"IBM Plex Mono"; font-size:.75rem; color:var(--muted); border:1px solid var(--border); border-radius:7px; padding:4px 9px; background:var(--surface-2); }
  .colc .cs{ display:grid; grid-template-columns:1.15fr .9fr 1.15fr; gap:6px; margin-top:8px; }
  .colc .cs[hidden]{ display:none; }
  .colc .cell{ min-width:0; display:flex; flex-direction:column; gap:2px; background:var(--bg); border:1px solid var(--border); border-radius:8px; padding:5px 7px; font-family:"IBM Plex Mono"; }
  .colc .cell small{ font-size:.75rem; color:var(--muted); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
  .colc .cell b{ font-size:.84rem; font-weight:600; color:var(--text); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
  .colc .cell b.mt{ color:var(--cc); }
  .colc .cell b.mt .matc i{ display:none; }
  .colc .cell .ce{ display:flex; align-items:center; justify-content:space-between; gap:4px; }
  .colc .cbar{ display:block; height:4px; border-radius:2px; background:var(--bg); position:relative; overflow:hidden; margin-top:6px; }
  .colc .cbar[hidden]{ display:none; }
  .colc .cbar > b{ position:absolute; left:0; top:0; bottom:0; width:0; background:var(--cc); }
  .colc .hint{ margin-top:6px; font-family:"IBM Plex Mono"; font-size:.75rem; color:var(--energy); }
  .colc .warn{ display:inline-block; margin-top:6px; font-family:"IBM Plex Mono"; font-size:.75rem; letter-spacing:.05em; text-transform:uppercase; color:var(--risk); border:1px solid var(--risk-dim); border-radius:5px; padding:2px 6px; }
  .colc .chev{ width:26px; height:26px; border-radius:50%; border:1px solid var(--border); background:var(--surface-2); display:flex; align-items:center; justify-content:center; flex:none; }
  .colc .chev svg{ width:12px; height:12px; color:var(--muted-2); }
  .colc.col-new{ border-color:var(--compute-dim); animation:colNewGlow 2s ease-out 1; }
  /* astillero (fila resumen) */
  /* ---------- colonia como pantalla propia (ritmo de espacios B3: 12 entre bloques, 8 dentro de
     listas, títulos con 18 arriba / 6 abajo) ---------- */
  #colonyScreen{ display:flex; flex-direction:column; gap:12px; }
  #colonyScreen h2{ margin-top:4px; }
  #colonyScreen > div:has(> .seg){ display:flex; flex-direction:column; }
  #colAbandonBtn{ align-self:flex-start; margin:4px 0 8px; }
  .colhead{ position:relative; display:flex; flex-direction:column; gap:8px; padding:12px 14px 14px; border-radius:14px; border:1px solid var(--border); background:radial-gradient(circle at 85% 10%, color-mix(in srgb, var(--cc) 20%, transparent), transparent 55%), var(--surface); }
  .colhead .btn-back{ align-self:flex-start; }
  .colhead{ align-items:stretch; }
  .colhead .coltitle{ position:static; width:100%; text-align:left; }
  .colhero{ position:relative; height:204px; border-radius:14px; overflow:hidden; border:1px solid var(--border); background:radial-gradient(circle at 70% 20%, color-mix(in srgb, var(--cc) 22%, transparent), transparent 60%), linear-gradient(var(--sky-top), var(--sky-bot)); }
  .colhero svg{ position:absolute; left:0; right:0; bottom:0; width:100%; height:64px; }
  .colhero .btn-back{ position:absolute; top:10px; left:10px; }
  .coltitle{ position:absolute; left:14px; top:44px; right:14px; }
  .coltitle .eyebrow{ font-family:"IBM Plex Mono"; font-size:.75rem; letter-spacing:.12em; text-transform:uppercase; color:var(--cc); }
  .coltitle h2{ margin:2px 0 0; font-size:1.25rem; }
  .coltitle .sub{ font-size:.75rem; color:var(--muted); margin-top:2px; line-height:1.35; display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
  .coltitle .own{ font-size:.75rem; color:var(--muted-2); margin-top:4px; }
  /* B7b se decidió como c (bonus por tamaño); mientras tanto los huecos se enseñan como cuadraditos */
  .szb{ color:var(--cc); font-weight:600; }
  .colmeters{ padding:0; grid-template-columns:repeat(5, minmax(0,1fr)); gap:5px; }
  .colmeters .meter{ padding:6px 4px; }
  .colmeters .meter .value{ font-size:.86rem; }
  .colmeters .meter .rate{ font-size:.75rem; }
  .colmeters .meter .label{ font-size:.75rem; letter-spacing:.02em; }
  .colmeters .meter .label .ri{ width:11px; height:11px; }
  #cmMatLabel .ri.mi{ width:11px; height:11px; }
  .seg{ display:flex; border:1px solid var(--border); border-radius:10px; overflow:hidden; }
  .seg.open{ border-radius:10px 10px 0 0; }
  .seg button{ flex:1; appearance:none; border:0; background:var(--surface-2); color:var(--muted); font-family:"IBM Plex Mono"; font-weight:600; font-size:.78rem; padding:10px; text-align:left; cursor:pointer; }
  .seg button + button{ border-left:1px solid var(--border); }
  .seg button span{ display:block; font-size:.75rem; color:var(--muted-2); font-weight:400; margin-top:2px; }
  .seg button.on{ background:var(--surface-3); color:var(--compute); }
  .seg button.hint{ color:var(--energy); }
  .convoybox.attached{ border-radius:0 0 10px 10px; border-top:0; margin-top:0; background:var(--surface-3); }
  /* B7: convoy automático de material — cuenta atrás por colonia */
  .autosend{ padding:8px 10px; border:1px solid var(--border); border-radius:10px; background:var(--surface-2); cursor:pointer; }
  .autosend .track{ display:flex; align-items:center; gap:10px; padding:2px 2px 4px; }
  .autosend .end{ display:flex; flex-direction:column; align-items:center; gap:2px; flex:none; color:var(--cc, var(--compute)); }
  .autosend .end svg{ width:26px; height:26px; padding:4px; box-sizing:border-box; border-radius:50%; border:1px solid var(--border); background:var(--surface); }
  .autosend .end small{ font-family:"IBM Plex Mono"; font-size:.75rem; letter-spacing:.08em; text-transform:uppercase; color:var(--muted); }
  .autosend .rail{ flex:1; position:relative; height:2px; margin-bottom:12px; background:repeating-linear-gradient(90deg, var(--border) 0 6px, transparent 6px 10px); }
  .autosend .rail i{ position:absolute; top:-4px; left:0; width:10px; height:10px; margin-left:-5px; border-radius:50%; background:var(--cc, var(--compute)); box-shadow:0 0 8px var(--cc, var(--compute)); transition:left .3s linear; }
  .autosend .rail b{ position:absolute; left:50%; top:8px; transform:translateX(-50%); font-family:"IBM Plex Mono"; font-size:.75rem; font-weight:600; color:var(--cc, var(--compute)); }
  .autosend .foot{ display:flex; align-items:flex-start; gap:8px; }
  .autosend .s{ flex:1; font-size:.76rem; color:var(--muted); line-height:1.4; }
  .autosend .foot .infobtn{ margin-top:2px; }
  .autosend .s .matc{ font-size:.75rem; }
  .autosend.idle .rail i{ box-shadow:none; opacity:.5; }
  .autosend.idle .end{ color:var(--muted); }
  .shiprow .name .infobtn{ margin-left:4px; vertical-align:middle; }
  .qbtn.on{ border-color:var(--compute); color:var(--compute); background:color-mix(in srgb, var(--compute) 10%, var(--surface-2)); }
  .alert{ background:color-mix(in srgb, var(--risk) 8%, var(--surface)); border:1px solid var(--risk-dim); border-radius:12px; padding:10px 12px; font-size:.84rem; line-height:1.45; }
  .alert b{ color:var(--risk); font-weight:600; }
  /* fila del extractor dentro de Infraestructura: especial pero de la misma familia que el resto */
  .row.extrow{ border-color:color-mix(in srgb, var(--mc) 55%, var(--border)); background:color-mix(in srgb, var(--mc) 6%, var(--surface)); }
  .row.extrow .icon{ color:var(--mc); border-color:color-mix(in srgb, var(--mc) 40%, var(--border)); }
  .row.extrow .xb{ font-family:"IBM Plex Mono"; font-size:.75rem; letter-spacing:.08em; text-transform:uppercase; color:var(--mc); border:1px solid color-mix(in srgb, var(--mc) 50%, transparent); border-radius:5px; padding:1px 5px; }
  .row.extrow .xsub{ margin-top:6px; }
  .row.extrow.locked{ opacity:.7; border-color:var(--border); background:var(--surface); }
  .row.extrow.locked .xsub, .row.extrow.locked .xbuy, .row.extrow.locked .chev, .row.extrow.locked .details{ display:none; }
  .row.extrow.locked .info{ cursor:default; }
  .row.extrow.locked .line .lk{ flex-basis:100%; color:var(--energy); }
  .row.extrow .xbuy .xcosts{ display:grid; grid-template-columns:auto auto; gap:2px 6px; font-size:.75rem; }
  .row.extrow .xbuy .eta{ white-space:normal; max-width:96px; line-height:1.2; }
  .row.extrow .xbuy .xcosts .c{ display:inline-flex; align-items:center; gap:1px; }
  .row.extrow .xbar{ height:5px; border-radius:3px; background:var(--bg); position:relative; overflow:hidden; }
  .row.extrow .xbar b{ position:absolute; left:0; top:0; bottom:0; width:0; background:var(--mc); transition:width .3s; }
  .row.extrow .xst{ display:flex; align-items:center; gap:8px; margin-top:5px; font-family:"IBM Plex Mono"; font-size:.75rem; color:var(--muted); flex-wrap:wrap; }
  .row.extrow .xst .xtag{ color:var(--mc); margin-left:auto; }
  .extcard{ background:var(--surface); border:1px solid var(--energy-dim); border-radius:14px; padding:12px 14px; display:flex; flex-direction:column; gap:7px; }
  .extcard .nm{ font-family:"IBM Plex Mono"; font-weight:600; font-size:.9rem; display:flex; flex-direction:column; align-items:flex-start; gap:2px; }
  .extcard .nm span:last-child{ font-size:.75rem; color:var(--energy); font-weight:400; letter-spacing:.04em; }
  .extcard .bar{ height:7px; border-radius:4px; background:var(--surface-2); border:1px solid var(--border); position:relative; overflow:hidden; }
  .extcard .bar b{ position:absolute; left:0; top:0; bottom:0; width:0; background:var(--energy); transition:width .3s; }
  .extcard .st{ font-family:"IBM Plex Mono"; font-size:.75rem; color:var(--muted); display:flex; justify-content:space-between; gap:8px; flex-wrap:wrap; }
  .extcard .foot{ display:flex; justify-content:space-between; align-items:center; gap:8px; font-size:.8rem; color:var(--muted); margin-top:2px; }
  .extcard .foot .desc{ flex:1; min-width:0; font-size:.76rem; }
  .extcard .foot button:not(.sellmini){ appearance:none; border:1px solid var(--border); background:var(--surface-2); color:var(--text); font-family:"IBM Plex Mono"; font-size:.84rem; font-weight:600; border-radius:8px; padding:7px 8px; min-width:78px; text-align:center; cursor:pointer; flex:none; line-height:1.3; }
  .extcard .foot button:not(.sellmini):disabled{ opacity:.38; }
  .extcard .foot button .c{ display:block; color:var(--compute); }
  .extcard .foot button .eta{ display:block; font-size:.75rem; color:var(--muted-2); font-weight:400; }
  .extcard .foot .sellmini{ margin-right:4px; flex:none; }

  /* ---------- A4/A8: cabeceras ilustradas por pestaña y estados vacíos con acción ---------- */
  .tabhero{ position:relative; height:150px; border-radius:14px; overflow:hidden; border:1px solid var(--border); background:var(--surface); }
  .tabhero img{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; }
  .tabhero .scrim{ position:absolute; inset:0; background:linear-gradient(180deg, rgba(7,10,12,.1) 20%, rgba(7,10,12,.95) 100%); }
  .tabhero .cap{ position:absolute; left:16px; right:16px; bottom:12px; }
  .tabhero .ey{ font-family:"IBM Plex Mono"; font-size:.75rem; letter-spacing:.12em; text-transform:uppercase; color:var(--research); }
  .tabhero.anclas .ey{ color:var(--energy); }
  .tabhero h2{ margin:2px 0 0; }
  .tabhero .s{ font-size:.78rem; color:var(--muted); margin-top:2px; }
  .skyhero{ position:relative; height:150px; border-radius:14px; overflow:hidden; border:1px solid var(--border); background:linear-gradient(180deg, #0a1116 0%, #0d161d 55%, #0b1116 100%); }
  .skyhero svg{ position:absolute; inset:0; width:100%; height:100%; }
  .skyhero .cap{ position:absolute; left:14px; top:10px; font-family:"IBM Plex Mono"; font-size:.75rem; letter-spacing:.12em; text-transform:uppercase; color:var(--muted); }
  .skyhero .cap b{ display:block; font-size:.9rem; letter-spacing:.02em; text-transform:none; color:var(--text); font-weight:600; margin-top:1px; }
  /* fila de ritmos bajo la cabecera de Construir */
  .raterow{ display:none; align-items:center; gap:6px; margin:0; padding:5px 16px 6px; background:var(--surface); border-bottom:1px solid var(--border); }
  body.chrome-compact:not(.chrome-open) .raterow{ display:flex; }
  body.chrome-compact:not(.chrome-open) .strip{ border-bottom-color:transparent; }
  .raterow .rl{ font-family:"IBM Plex Mono"; font-size:.75rem; letter-spacing:.1em; text-transform:uppercase; color:var(--muted); flex:none; margin-right:2px; }
  .raterow .rchip{ flex:1; display:inline-flex; align-items:center; justify-content:center; gap:3px; font-family:"IBM Plex Mono"; font-size:.75rem; font-weight:600; min-width:0; white-space:nowrap; }
  .raterow .rchip svg{ width:11px; height:11px; }
  /* B9-5: la silueta nueva entra con un "pop" */
  .skyhero .pop, .colhero .pop{ transform-box:fill-box; transform-origin:center bottom; animation:skyPop .35s ease-out; }
  @keyframes skyPop{ from{ transform:scaleY(0); } to{ transform:scaleY(1); } }
  .emptycard{ background:var(--surface); border:1px solid var(--border); border-radius:14px; overflow:hidden; }
  .emptycard img{ display:block; width:100%; height:150px; object-fit:cover; }
  .emptycard .b{ padding:14px; display:flex; flex-direction:column; gap:6px; }
  .emptycard .ey{ font-family:"IBM Plex Mono"; font-size:.75rem; letter-spacing:.12em; text-transform:uppercase; color:var(--compute); }
  .emptycard p{ margin:0 0 6px; font-size:.86rem; line-height:1.5; color:var(--muted); }
  .emptycard .lockline{ display:flex; align-items:flex-start; gap:9px; padding:9px 11px; background:var(--surface-2); border:1px solid var(--border); border-radius:10px; font-size:.8rem; color:var(--muted); line-height:1.4; }
  .emptycard .lockline svg{ width:16px; height:16px; flex:none; fill:none; stroke:var(--muted); stroke-width:1.8; margin-top:2px; }
  .emptycard .lockline b{ display:block; color:var(--text); font-weight:600; }
  .emptycard .lockline > div > span{ display:block; font-family:"IBM Plex Mono"; font-size:.75rem; margin-top:2px; }
  .emptycard .lockline .c{ display:inline; margin-right:8px; }

  /* ---------- A6: un solo naranja de atención en pantalla (prioridad: guía > siguiente paso > novedad) ---------- */
  body.attn-guide .nextstep{ border-color:var(--border); background:var(--surface); }
  body.attn-guide .nextstep .eyebrow{ color:var(--muted); }
  body.attn-guide #newBuildingsNote, body.attn-guide #newTechsNote, body.attn-next #newBuildingsNote, body.attn-next #newTechsNote{ border-color:var(--border); background:var(--surface); }
  body.attn-guide #newBuildingsNote .eyebrow, body.attn-guide #newTechsNote .eyebrow, body.attn-next #newBuildingsNote .eyebrow, body.attn-next #newTechsNote .eyebrow{ color:var(--muted); }
  body.attn-guide nav.tabs button.tab-pulse:not(.tab-armed), body.attn-guide nav.tabs button.has-badge:not(.tab-armed){ animation:none; box-shadow:none; color:var(--muted); }

  /* ---------- A7: números que cuentan y medidor que parpadea en su color ---------- */
  .meter{ position:relative; transition:box-shadow .35s, border-color .35s; }
  .meter.flash{ border-color:var(--fc); box-shadow:0 0 0 2px color-mix(in srgb, var(--fc) 30%, transparent); }
  .meter.flash.bad{ --fc:var(--risk); }
  .mfloat{ position:absolute; right:6px; top:-2px; font-family:"IBM Plex Mono"; font-size:.78rem; font-weight:700; pointer-events:none; animation:mfloat .8s ease-out forwards; }
  @keyframes mfloat{ from{ opacity:1; transform:translateY(0); } to{ opacity:0; transform:translateY(-18px); } }
  /* B5b: materiales raros como chips hexagonales pequeños, discretos, con un brillo lento */
  /* cuatro chips iguales en una fila: icono a la izquierda y, a la derecha, cifra (con ritmo) y el
     NOMBRE debajo — antes solo había icono y cifra y nadie sabía cuál era cuál (auditoría 2026-09-25) */
  .mats{ display:flex; gap:6px; padding:6px 16px 0; flex-wrap:nowrap; }
  .mat{ flex:1; min-width:0; display:flex; flex-direction:column; gap:1px; font-family:"IBM Plex Mono"; background:var(--surface); border:1px solid var(--border); border-radius:8px; padding:4px 6px; }
  /* icono y nombre en el color del material (el usuario los quiere así); la cifra en blanco */
  .mat .mn{ display:flex; align-items:center; gap:4px; font-size:.75rem; letter-spacing:.06em; text-transform:uppercase; color:var(--mc, var(--muted)); white-space:nowrap; min-width:0; }
  .mat .mn span{ overflow:hidden; text-overflow:ellipsis; }
  .mat .mn svg{ width:13px; height:13px; flex:none; animation:matShine 3s ease-in-out infinite; }
  .mat .mv{ display:flex; align-items:baseline; gap:4px; line-height:1.15; min-width:0; }
  .mat b{ color:var(--text); font-weight:600; font-size:.82rem; }
  .mat .mv span{ font-size:.75rem; color:var(--mc, var(--muted-2)); opacity:.85; white-space:nowrap; }
  .mat.zero{ opacity:.5; }
  @keyframes matShine{ 0%,100%{ opacity:.7; } 50%{ opacity:1; } }

  /* ---------- B9: momentos que se ven pasar ---------- */
  .risk-track .sweep{ position:absolute; top:-2px; bottom:-2px; width:3px; background:var(--compute); box-shadow:0 0 10px var(--compute); animation:sweep .6s linear forwards; }
  @keyframes sweep{ from{ left:var(--from); } to{ left:var(--to); } }
  .risk-fill{ transition:width .6s ease-out; }
  .corebox.flash-good{ animation:flashGood .5s ease; }
  @keyframes flashGood{ 0%{ box-shadow:0 0 0 0 rgba(82,224,196,.6); } 100%{ box-shadow:0 0 0 18px rgba(82,224,196,0); } }
  .row.shake{ animation:shake .5s ease; border-color:var(--risk-dim); }
  @keyframes shake{ 0%,100%{ transform:translateX(0); } 20%{ transform:translateX(-4px); } 40%{ transform:translateX(4px); } 60%{ transform:translateX(-3px); } 80%{ transform:translateX(3px); } }
  .fusionfx{ position:fixed; inset:0; z-index:70; background:#000; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:8px; opacity:0; transition:opacity .5s; pointer-events:none; }
  .fusionfx.on{ opacity:1; pointer-events:auto; }
  .fusionfx .fx-n{ font-family:"IBM Plex Mono"; font-size:2.4rem; font-weight:700; color:var(--energy); }
  .fusionfx .fx-t{ font-family:"IBM Plex Mono"; font-size:.78rem; letter-spacing:.14em; text-transform:uppercase; color:var(--muted); }
  .iconbtn.stamp{ animation:stamp .5s ease; border-color:var(--energy-dim); color:var(--energy); }
  @keyframes stamp{ 0%{ transform:scale(1.35); } 100%{ transform:scale(1); } }
  .stampLbl{ position:absolute; top:28px; right:-4px; font-family:"IBM Plex Mono"; font-size:.75rem; color:var(--energy); background:var(--surface-2); border:1px solid var(--energy-dim); border-radius:5px; padding:1px 5px; white-space:nowrap; animation:mfloat 2.4s ease-out forwards; }
  /* B9-10: la doctrina elegida tiñe sutilmente las líneas de sección y la pestaña activa */
  body.doc-militar h2::after{ background:var(--risk-dim); } body.doc-militar nav.tabs button.active{ box-shadow:inset 0 0 0 1px var(--risk-dim); }
  body.doc-cientifica h2::after{ background:var(--research-dim); } body.doc-cientifica nav.tabs button.active{ box-shadow:inset 0 0 0 1px var(--research-dim); }
  body.doc-social h2::after{ background:var(--compute-dim); } body.doc-social nav.tabs button.active{ box-shadow:inset 0 0 0 1px var(--compute-dim); }
  @media (prefers-reduced-motion: reduce){ .mfloat, .risk-track .sweep, .corebox.flash-good, .row.shake, .skyhero .pop, .iconbtn.stamp, .mat svg{ animation:none; } .fusionfx{ transition:none; } }
  /* B6: fundación con tres barridos, uno por dato */
  .fnd-scan.s2{ background:var(--fnd-c2); box-shadow:0 0 12px var(--fnd-c2); }
  .fnd-scan.s3{ background:var(--fnd-c3); box-shadow:0 0 12px var(--fnd-c3); }
  .fnd-line.now{ border-color:var(--compute); }
  /* ---------- fundación en tres pasos ---------- */
  .fnd-hero{ position:relative; margin:-16px -16px 2px -16px; }
  .fnd-hero img.card-hero{ margin:0; width:100%; }
  .fnd-scan{ position:absolute; left:0; right:0; top:20%; height:2px; background:var(--compute); box-shadow:0 0 12px var(--compute); animation:fndScan 2s linear infinite; opacity:.85; }
  @keyframes fndScan{ from{ top:8%; } to{ top:92%; } }
  .fnd-tag{ position:absolute; left:12px; top:12px; font-family:"IBM Plex Mono"; font-size:.75rem; letter-spacing:.12em; text-transform:uppercase; color:var(--compute); background:rgba(8,11,13,.7); border:1px solid var(--compute-dim); padding:3px 8px; border-radius:6px; }
  .fnd-typing::after{ content:"▌"; color:var(--compute); animation:fndBlink 1s steps(2) infinite; }
  @keyframes fndBlink{ to{ opacity:0; } }
  .fnd-prog{ height:5px; border-radius:3px; background:var(--surface-2); border:1px solid var(--border); position:relative; overflow:hidden; }
  .fnd-prog b{ position:absolute; left:0; top:0; bottom:0; width:0; background:var(--compute); transition:width 1.4s linear; }
  .fnd-lines{ display:flex; flex-direction:column; gap:6px; }
  .fnd-line{ display:flex; justify-content:space-between; align-items:center; gap:10px; padding:8px 10px; border-radius:9px; background:var(--surface-2); border:1px solid var(--border); font-family:"IBM Plex Mono"; font-size:.82rem; }
  .fnd-line .k{ color:var(--muted-2); font-size:.75rem; letter-spacing:.06em; text-transform:uppercase; }
  .fnd-line .v{ font-weight:600; text-align:right; min-width:0; overflow-wrap:anywhere; }
  .fnd-line{ min-width:0; }
  .fnd-line.pend .v{ color:var(--muted-2); font-weight:400; }
  .fnd-line.hot{ border-color:var(--energy-dim); background:color-mix(in srgb, var(--energy) 8%, var(--surface-2)); }
  .fnd-line.hot .v{ color:var(--energy); }
  @media (prefers-reduced-motion: reduce){ .fnd-scan, .fnd-typing::after{ animation:none; } .fnd-prog b{ transition:none; } }

  .colhead{ background:var(--surface); border:1px solid var(--border); border-radius:10px; padding:9px 10px; display:flex; align-items:center; gap:10px; cursor:pointer; }
  .colhead .icon{ width:38px; height:38px; border-radius:9px; flex:none; display:flex; align-items:center; justify-content:center; background:var(--surface-2); border:1px solid var(--border); }
  .colhead .icon svg{ width:24px; height:24px; }
  .colhead .info{ flex:1; min-width:0; }
  .colhead .name{ font-size:.92rem; font-weight:600; display:flex; align-items:center; gap:6px; }
  .colhead .name .cnt{ font-family:"IBM Plex Mono"; font-size:.78rem; color:var(--research); }
  /* material exótico de la colonia, en el título: mismo naranja que los botones de anuncio
     (--energy), pedido explícito del usuario tras ver que el amarillo quedaba feo */
  .colhead .name .material-tag{ font-family:"IBM Plex Mono"; font-size:.78rem; color:var(--energy); }
  /* mismo naranja (--energy) para nombrar un recurso raro dentro de texto normal (leyenda de tipos,
     momento narrativo de colonia fundada, selector de destino) — sin tocar fuente ni tamaño, a
     diferencia de .material-tag de arriba, que es una "pastilla" compacta solo para la cabecera. */
  .mat-name{ color:var(--energy); }
  .colhead .desc{ font-size:.8rem; color:var(--muted); margin-top:1px; }
  .colhead .own{ font-size:.78rem; color:var(--muted-2); margin-top:2px; }
  .colhead .rate{ font-family:"IBM Plex Mono"; font-size:.75rem; color:var(--compute); margin-top:2px; }
  /* colonia recién fundada: destello de entrada una sola vez (no en bucle, para no acabar
     pareciendo una alarma) + borde en verde-cómputo que se queda hasta que el jugador la abre —
     pedido explícito del usuario tras fundar una colonia sin darse cuenta estando en otra pestaña. */
  .new-tag{ font-family:"IBM Plex Mono"; font-size:.75rem; letter-spacing:.05em; text-transform:uppercase; color:var(--compute); border:1px solid var(--compute-dim); border-radius:5px; padding:1px 6px; }
  .col-new .colhead{ border-color:var(--compute-dim); animation:colNewGlow 2s ease-out 1; }
  @keyframes colNewGlow{ from{ box-shadow:0 0 0 3px color-mix(in srgb, var(--compute) 35%, transparent); } to{ box-shadow:0 0 0 0 transparent; } }
  /* nave de despliegue lista para lanzar por primera vez: mismo lenguaje que una colonia recién
     fundada (col-new) — destello de entrada + borde que se queda mientras siga habiendo una nave
     lista, se apaga solo en cuanto se lanza (canLaunchDeploy vuelve a false, ver badgeArm en
     refresh.js) y puede volver a encenderse si se construye otra más tarde. Selector ".row
     button.launch-armed" (no ".btn.launch-armed") a propósito: iguala en especificidad a ".row
     button:not(.sellmini)" (línea ~194), que si no le gana y el borde/fondo no se ven, solo
     queda la animación. */
  .row button.launch-armed{ border-color:var(--compute-dim); background:color-mix(in srgb, var(--compute) 14%, var(--surface)); animation:colNewGlow 2s ease-out 1; }
  /* se crea de golpe cada vez que se abre una colonia (nodo nuevo, no reutilizado — ver
     ensureColonyDom), así que una animation de entrada aquí se reproduce en cada apertura sin
     tocar el patrón de reconstruir solo cuando cambia de verdad. */
  .coldetail{ display:flex; flex-direction:column; gap:7px; padding:9px 0 4px 10px; border-left:2px solid var(--border); margin-left:9px; animation:coldetailIn .16s ease; }
  @keyframes coldetailIn{ from{ opacity:0; transform:translateY(-4px); } to{ opacity:1; transform:none; } }
  @media (prefers-reduced-motion: reduce){ .coldetail{ animation:none; } }
  .qtyrow{ display:flex; align-items:center; gap:6px; flex-wrap:wrap; }
  .qtyrow .qlabel{ font-family:"IBM Plex Mono"; font-size:.75rem; color:var(--muted-2); min-width:58px; }
  .qbtn{ appearance:none; border:1px solid var(--border); background:var(--surface-2); color:var(--text); font-family:"IBM Plex Mono"; font-size:.75rem; padding:6px 8px; border-radius:7px; cursor:pointer; }
  .qbtn:disabled{ opacity:.35; cursor:not-allowed; }
  .qbtn:not(:disabled):active{ transform:scale(.95); }
  /* caja de convoy: antes eran filas sueltas indistinguibles del resto de la ficha de colonia
     (queja real: "se presenta al final de la sección y con un diseño muy pobre") — ahora un bloque
     con borde y cabecera propios, y las dos filas de dirección (enviar/traer) resaltadas por separado */
  .convoybox{ background:var(--surface-2); border:1px solid var(--border); border-radius:9px; padding:8px 9px; display:flex; flex-direction:column; gap:6px; margin-top:2px; }
  .convoy-head{ display:flex; flex-direction:column; gap:2px; }
  .convoy-title{ font-size:.82rem; font-weight:600; }
  .convoy-dir{ background:var(--surface-3); border-radius:7px; padding:5px 6px; }
  .convoy-dir .qlabel{ min-width:auto; color:var(--text); font-weight:600; }
  .missrow{ background:var(--surface); border:1px solid var(--border); border-radius:10px; padding:9px 10px; display:flex; align-items:center; gap:10px; }
  .missrow .icon{ width:36px; height:36px; border-radius:9px; flex:none; display:flex; align-items:center; justify-content:center; background:var(--surface-2); border:1px solid var(--border); }
  .missrow .icon svg{ width:22px; height:22px; }
  .missrow .info{ flex:1; min-width:0; }
  .missrow .name{ font-size:.84rem; font-weight:600; }
  .missrow .bar{ margin-top:5px; }
  .missrow .own{ font-size:.76rem; color:var(--muted-2); margin-top:3px; }
  .adbtn{ appearance:none; border:1px solid var(--energy-dim); background:var(--surface-2); color:var(--energy); font-family:"IBM Plex Mono"; font-size:.75rem; font-weight:600; padding:7px 8px; border-radius:8px; cursor:pointer; flex:none; }
  .adbtn:disabled{ opacity:.35; cursor:not-allowed; }
  .card.ad{ align-items:center; text-align:center; }
  .card.ad .bar{ width:100%; }

  .log{ background:#000; border:1px solid var(--border); border-radius:10px; padding:10px 11px; height:220px; overflow-y:auto; display:flex; flex-direction:column; gap:3px; }
  .log .line{ font-family:"IBM Plex Mono"; font-size:.82rem; color:var(--muted); line-height:1.5; }
  .log .line .t{ color:var(--muted-2); margin-right:6px; }
  .log .line.warn{ color:var(--risk); } .log .line.good{ color:var(--compute); } .log .line.info{ color:var(--research); }
  .stats{ display:grid; grid-template-columns:1fr 1fr; gap:6px; }
  .stat{ background:var(--surface); border:1px solid var(--border); border-radius:8px; padding:7px 9px; }
  .stat .k{ font-size:.75rem; letter-spacing:.08em; text-transform:uppercase; color:var(--muted); }
  .stat .v{ font-size:.82rem; font-weight:600; }
  .achs{ display:grid; grid-template-columns:repeat(3,1fr); gap:6px; }
  .ach{ background:var(--surface); border:1px solid var(--border); border-radius:8px; padding:7px 8px; font-size:.78rem; color:var(--muted-2); line-height:1.3; }
  .ach.got{ color:var(--text); border-color:var(--compute-dim); }
  .ach .an{ font-weight:600; font-size:.82rem; display:block; }

  .overlay{ position:fixed; inset:0; background:rgba(4,6,8,.78); display:flex; align-items:center; justify-content:center; padding:20px 16px; z-index:50; backdrop-filter:blur(3px); }
  .card{ background:var(--surface); border:1px solid var(--border); border-radius:14px; padding:16px; width:100%; max-width:440px; display:flex; flex-direction:column; gap:10px; max-height:90vh; overflow-y:auto; overflow-x:hidden; position:relative; scrollbar-width:thin; scrollbar-color:var(--border) transparent; }
  /* algún modal con mucho texto (ej. el de Fusionar núcleo) puede seguir necesitando scroll interno
     en pantallas de móvil muy bajas incluso con la cabecera ilustrada ya recortada a 170px — si pasa,
     que la barra sea del propio tema en vez de la gris nativa del navegador, para que no desentone. */
  .card::-webkit-scrollbar{ width:6px; }
  .card::-webkit-scrollbar-track{ background:transparent; }
  .card::-webkit-scrollbar-thumb{ background:var(--border); border-radius:3px; }
  .card .close-x{ position:absolute; top:10px; right:10px; width:26px; height:26px; border-radius:50%; border:1px solid var(--border); background:var(--surface-2); color:var(--muted); font-family:"IBM Plex Mono"; font-size:.9rem; line-height:1; cursor:pointer; display:flex; align-items:center; justify-content:center; padding:0; }
  .card .close-x:active{ transform:scale(.92); }
  .card .eyebrow{ font-family:"IBM Plex Mono"; font-size:.78rem; letter-spacing:.12em; text-transform:uppercase; color:var(--energy); }
  /* cabecera ilustrada de un modal (mapa de colonización, bienvenida, doctrina, incidente,
     fusión, reinicio de linaje...) — a sangre hasta el borde de la tarjeta (margen negativo para
     comerse el padding), solo las esquinas superiores redondeadas para no romper el borde de .card.
     Altura fija en vez de dejar que la imagen cuadrada mande: a sangre y sin límite, el cuadrado
     entero (~470px en una tarjeta de 440px) empujaba el contenido por encima del max-height:90vh
     de .card y obligaba a un scroll interno que tapaba hasta los botones de decisión en móvil — fallo
     real visto por el usuario ("un scroll que no tiene nada que ver con el juego"). object-fit:cover
     recorta la imagen cuadrada a una tira central, igual que ya hacemos al preparar los archivos. */
  .card img.card-hero{ width:calc(100% + 32px); height:170px; object-fit:cover; object-position:center; margin:-16px -16px 2px -16px; border-radius:14px 14px 0 0; display:block; max-width:none; }
  /* Encuadre: las ilustraciones son cuadradas (o 16:9) y se muestran a ~2,25:1; sin esto se ve la
     franja central y el motivo (el núcleo, la nave, la base) queda cortado. Punto de interés
     vertical por fichero, decidido mirando cada imagen (feedback del usuario 2026-09-25). */
  img[src$="g1-bienvenida.jpg"]{ object-position:50% 45%; }
  img[src$="g2-doctrina.jpg"]{ object-position:50% 40%; }
  img[src$="g3-incidente.jpg"]{ object-position:50% 42%; }
  img[src$="g4-fusion.jpg"]{ object-position:50% 34%; }
  img[src$="g5-reinicio-linaje.jpg"]{ object-position:50% 48%; }
  img[src$="g6-entrenar-modelo.jpg"]{ object-position:50% 50%; }
  img[src$="g7-convoy.jpg"]{ object-position:50% 42%; }
  img[src$="g8-lanzamiento.jpg"]{ object-position:50% 42%; }
  img[src$="g9-fundacion.jpg"]{ object-position:50% 56%; }
  img[src$="g10-logro.jpg"]{ object-position:50% 45%; }
  img[src$="h1-escaneo-tamano.jpg"]{ object-position:50% 38%; }
  img[src$="h2-escaneo-tipo.jpg"]{ object-position:50% 35%; }
  img[src$="h3-escaneo-recurso.jpg"]{ object-position:50% 45%; }
  img[src$="core-f0-garaje.jpg"]{ object-position:50% 38%; }
  img[src$="core-f1-automatizacion.jpg"]{ object-position:50% 38%; }
  img[src$="core-f2-expansion.jpg"]{ object-position:50% 40%; }
  img[src$="core-f3-autonomia.jpg"]{ object-position:50% 42%; }
  img[src$="core-f4-control.jpg"]{ object-position:50% 40%; }
  img[src$="core-f5-umbral.jpg"]{ object-position:50% 40%; }
  img[src$="core-f6-singularidad.jpg"]{ object-position:50% 42%; }
  img[src$="core-legado.jpg"]{ object-position:50% 42%; }
  img[src$="e4-mapa-colonizacion.jpg"]{ object-position:50% 45%; }
  img[src$="d2-splash.jpg"]{ object-position:50% 68%; }
  .card h3{ margin:0; font-family:"IBM Plex Mono"; font-size:1rem; text-wrap:balance; }
  .card p{ margin:0; font-size:.92rem; line-height:1.5; color:var(--text); }
  .card .opts{ display:flex; flex-direction:column; gap:7px; margin-top:4px; }
  .opt{ appearance:none; text-align:left; background:var(--surface-2); border:1px solid var(--border); color:var(--text); border-radius:10px; padding:10px 12px; cursor:pointer; display:flex; flex-direction:column; gap:3px; font-family:inherit; }
  .opt:active{ transform:scale(.985); }
  .opt .ol{ font-weight:600; font-size:.92rem; }
  .opt .oe{ font-family:"IBM Plex Mono"; font-size:.78rem; color:var(--muted); }
  /* filas de la modal de Racha y objetivos: apiladas (info arriba, botón de reclamar debajo a todo
     lo ancho) en vez de en fila — con la pista de dos líneas del botón ("Reclamar" + a qué sube),
     no cabía a la vez que el texto de la fila en el ancho de la tarjeta (440px), se atropellaban. */
  .progrow{ background:var(--surface); border:1px solid var(--border); border-radius:10px; padding:9px 10px; display:flex; flex-direction:column; gap:8px; margin-bottom:7px; }
  .progrow .info{ min-width:0; }
  .progrow .name{ font-size:.88rem; font-weight:600; display:flex; align-items:center; gap:6px; flex-wrap:wrap; }
  .progrow .desc{ font-size:.8rem; color:var(--muted); margin-top:2px; }
  /* qué se consigue (antes de reclamar) o qué se ha conseguido (después) — pedido explícito del
     usuario, antes solo se veía el progreso, nunca el premio en sí. */
  .progrow .reward{ font-size:.78rem; color:var(--muted-2); margin-top:1px; }
  /* Modal "Racha y objetivos", diseño B (tablero): anillo + fichas */
  .pg-head{ display:flex; justify-content:space-between; align-items:center; padding-right:36px; }
  .pg-head .num{ font-size:.75rem; color:var(--muted); white-space:nowrap; }
  .pg-streak{ display:flex; gap:14px; align-items:center; background:var(--surface-2); border:1px solid var(--border); border-radius:12px; padding:12px 14px; }
  .pg-ring{ position:relative; width:104px; height:104px; flex:none; }
  .pg-ring svg{ width:100%; height:100%; display:block; }
  .pg-ring .bg{ fill:none; stroke:var(--bg); stroke-width:9; }
  .pg-ring .fg{ fill:none; stroke:var(--compute); stroke-width:9; stroke-linecap:round; stroke-dasharray:0 276.5; transition:stroke-dasharray .6s ease; }
  .pg-ring .dot{ fill:var(--energy); }
  .pg-ringtxt{ position:absolute; inset:0; display:flex; flex-direction:column; align-items:center; justify-content:center; }
  .pg-ringtxt b{ font-size:2.1rem; font-weight:700; line-height:1; color:var(--compute); }
  .pg-ringtxt span{ font-family:"IBM Plex Mono"; font-size:.75rem; letter-spacing:.1em; text-transform:uppercase; color:var(--muted); margin-top:3px; }
  .pg-ring.sm{ width:44px; height:44px; }
  .pg-ring.sm .bg{ stroke-width:5; }
  .pg-ring.sm .fg{ stroke:var(--energy); stroke-width:5; stroke-dasharray:0 113.1; }
  .pg-ring.sm b{ position:absolute; inset:0; display:flex; align-items:center; justify-content:center; font-size:.75rem; font-weight:700; color:var(--energy); }
  .pg-sinfo{ flex:1; min-width:0; display:flex; flex-direction:column; gap:5px; }
  .pg-sinfo .name{ font-size:.92rem; font-weight:600; display:flex; align-items:center; gap:6px; flex-wrap:wrap; }
  .pg-sinfo .pct{ display:flex; align-items:baseline; gap:6px; flex-wrap:wrap; }
  .pg-sinfo .pct b{ font-size:1.3rem; font-weight:700; color:var(--compute); }
  .pg-sinfo .pct .what{ display:inline-flex; gap:5px; align-items:center; }
  .pg-sinfo .pct .what .ri{ width:14px; height:14px; margin:0; }
  .pg-sinfo .pct .what .ri:nth-child(1){ color:var(--compute); } .pg-sinfo .pct .what .ri:nth-child(2){ color:var(--research); } .pg-sinfo .pct .what .ri:nth-child(3){ color:var(--data); }
  .pg-sinfo .desc{ font-size:.75rem; color:var(--muted); line-height:1.35; }
  .pg-sinfo .desc i{ font-style:normal; color:var(--energy); }
  /* Reclamar: se nota que es un botón (borde y fondo teal suaves) sin ser el verde sólido que el usuario descartó */
  .pg-claim{ align-self:flex-start; padding:9px 14px; font-size:.8rem; font-weight:700; color:var(--compute); border-color:var(--compute); background:color-mix(in srgb, var(--compute) 14%, var(--surface-2)); box-shadow:0 0 0 2px color-mix(in srgb, var(--compute) 18%, transparent); }
  .pg-sinfo .desc b{ color:var(--compute); font-weight:600; }
  .claimed-tag.left{ text-align:left; padding:4px 0 0; font-size:.75rem; }
  .pg-sub{ display:flex; justify-content:space-between; align-items:baseline; margin-top:4px; }
  .pg-sub .num{ font-size:.75rem; color:var(--muted); }
  .pg-grid{ display:grid; grid-template-columns:repeat(3, minmax(0,1fr)); gap:8px; }
  .pg-tile{ background:var(--surface-2); border:1px solid var(--border); border-radius:12px; padding:11px 9px; display:flex; flex-direction:column; gap:7px; min-height:168px; box-sizing:border-box; }
  .pg-tile.ready{ border-color:var(--compute); }
  .pg-tile.done{ background:var(--surface); }
  .pg-tile .ic{ width:22px; height:22px; }
  .pg-tile .ic svg{ width:22px; height:22px; }
  .pg-tile .big{ font-size:1.3rem; font-weight:700; line-height:1; }
  .pg-tile .big span{ font-size:.78rem; color:var(--muted); font-weight:500; }
  .pg-tile.ready .big{ color:var(--compute); }
  .pg-tile.done .big, .pg-tile.done .lbl{ color:var(--muted); }
  .pg-tile .lbl{ font-size:.75rem; line-height:1.3; flex:1; }
  .pg-tile .bar{ height:5px; border-radius:3px; background:var(--bg); overflow:hidden; }
  .pg-tile .bar > div{ height:100%; width:0; background:var(--research); }
  .pg-tile .left{ font-size:.75rem; color:var(--muted); }
  .pg-tile .pg-claim{ align-self:stretch; padding:8px 4px; text-align:center; }
  .pg-tile .claimed-tag{ padding:0; text-align:left; font-size:.75rem; display:flex; align-items:center; gap:4px; }
  .pg-tile .claimed-tag svg{ width:12px; height:12px; }
  .pg-foot{ display:flex; align-items:center; gap:12px; background:var(--surface-2); border:1px dashed var(--border); border-radius:12px; padding:10px 12px; }
  .pg-foot .t{ font-size:.78rem; color:var(--muted); line-height:1.35; }
  .pg-foot .t b{ color:var(--text); font-weight:600; }
  /* Una vez reclamado, deja de ser un botón (ni siquiera deshabilitado): texto plano en el mismo
     ámbar de "esto ya está resuelto" que usa el resto del juego (p.ej. legado-tag) — pedido
     explícito del usuario. */
  .claimed-tag{ text-align:center; font-family:"IBM Plex Mono"; font-weight:600; font-size:.82rem; letter-spacing:.06em; text-transform:uppercase; color:var(--energy); padding:8px 0; }
  /* decisión en dos pasos: la opción marcada se ve marcada y la decisión se aplica desde la fila de
     confirmar (separada por una línea y con retardo de armado), así un toque perdido no decide nada */
  .opt.sel{ border-color:var(--compute); background:color-mix(in srgb, var(--compute) 12%, var(--surface-2)); }
  .opt.sel .ol{ color:var(--compute); }
  .opts.confirm-row{ margin-top:2px; padding-top:9px; border-top:1px solid var(--border); }
  .opt.confirm{ align-items:center; text-align:center; border-color:var(--compute-dim); }
  .opt.confirm .ol{ color:var(--compute); }
  .opt.confirm .oe{ text-align:center; }
  .opt.confirm:disabled{ opacity:.45; cursor:not-allowed; }
  .opt.confirm:disabled .ol{ color:var(--muted); }
  /* resultado del dilema: lista de consecuencias, en verde lo que suma y en rojo lo que resta */
  .fx-label{ font-family:"IBM Plex Mono"; font-size:.75rem; letter-spacing:.08em; text-transform:uppercase; color:var(--muted); }
  .card.ending{ border-color:var(--research-dim); }
  .card.ending h3{ color:var(--research); font-size:1.3rem; }
  .onboard-dots{ display:flex; gap:6px; justify-content:center; margin-top:2px; }
  .onboard-dots span{ width:6px; height:6px; border-radius:50%; background:var(--border); }
  .onboard-dots span.on{ background:var(--compute); }
  .card.incident{ border-color:var(--risk-dim); }
  .card.incident h3{ color:var(--risk); }
  .card.incident .eyebrow{ color:var(--risk); }
  /* Reinicio de linaje reutilizaba .card.incident (rojo, pensado para avisos malos): es una acción
     buena — gana Legado — así que lleva el mismo naranja que ya usa el resto de la sección Legado. */
  .card.legend{ border-color:var(--energy-dim); }
  .card.legend h3{ color:var(--energy); }
  .card.legend .eyebrow{ color:var(--energy); }

  /* A12: los avisos salen justo encima de la barra de pestañas (antes tapaban la cabecera) y como
     mucho dos a la vez (ver toast() en state.js). */
  .toasts{ position:fixed; bottom:calc(env(safe-area-inset-bottom,0px) + 74px); left:0; right:0; display:flex; flex-direction:column; align-items:center; gap:6px; pointer-events:none; z-index:60; padding-inline:16px; }
  .toast{ background:var(--surface-3); border:1px solid var(--border); border-radius:8px; padding:8px 12px; font-size:.88rem; font-family:"IBM Plex Mono"; color:var(--text); box-shadow:0 6px 20px rgba(0,0,0,.4); animation:tin .25s ease; max-width:100%; }
  .toast.good{ border-color:var(--compute-dim); color:var(--compute); } .toast.warn{ border-color:var(--risk-dim); color:var(--risk); } .toast.ach{ border-color:var(--energy-dim); color:var(--energy); }
  /* voz del modelo (voice.js): único toast con avatar, para darle cara a sus frases en vez de
     texto anónimo — violeta (--research) porque es "pensamiento" del modelo, no un recurso. */
  .toast.voice{ display:flex; align-items:center; gap:9px; border-color:var(--research-dim); text-align:left; }
  .toast-avatar{ width:30px; height:30px; border-radius:50%; object-fit:cover; flex:none; }
  @keyframes tin{ from{ opacity:0; transform:translateY(-8px);} to{ opacity:1; transform:none; } }
  @keyframes tabPulse{ 0%,100%{ box-shadow:0 0 0 0 rgba(232,163,61,.6); } 50%{ box-shadow:0 0 0 7px rgba(232,163,61,0); } }
  /* Antes 3 pulsos durante 1s y se paraba sola — pedido explícito del usuario: duraba tan poco que
     mucha gente no llegaba a verla. Ahora persiste (igual que .tab-armed de abajo) hasta que el
     jugador entra de verdad en la pestaña señalada (ver showTab() en tabs.js, que le quita esta
     clase en cuanto eso pasa) — nunca se apaga sola por tiempo. */
  .tab-pulse{ color:var(--energy); animation:tabPulse 1.4s ease-in-out infinite; border-radius:8px; }
  @media (prefers-reduced-motion: reduce){ .tab-pulse{ animation:none; box-shadow:inset 0 0 0 2px var(--energy-dim); } }
  /* guía de primeros pasos (ver guide.js): misma animación persistente que .tab-pulse de arriba,
     mientras el paso activo del tutorial esté en otra pestaña — pedido explícito del usuario para
     que nunca haya un hueco sin nada resaltado durante estos primeros pasos. Se apaga en cuanto el
     jugador entra de verdad en la pestaña señalada. */
  nav.tabs button.tab-armed{ color:var(--energy); animation:tabPulse 1.4s ease-in-out infinite; border-radius:8px; }
  @media (prefers-reduced-motion: reduce){ nav.tabs button.tab-armed{ animation:none; box-shadow:inset 0 0 0 2px var(--energy-dim); } }

  .flash{ animation:flash .5s ease; }
  @keyframes flash{ 0%{ box-shadow:0 0 0 0 rgba(224,82,90,.7);} 100%{ box-shadow:0 0 0 18px rgba(224,82,90,0);} }
  @media (prefers-reduced-motion: reduce){ .toast{ animation:none; } .flash{ animation:none; } }
  button:focus-visible, .opt:focus-visible, .branch:focus-visible{ outline:2px solid var(--compute); outline-offset:2px; }

  /* ---------- El Núcleo en una pantalla (2026-10-01) ----------
     Pedido del usuario: en un móvil mediano, todo lo que se puede hacer en el Núcleo tiene que
     verse sin desplazar; en uno pequeño se tiene que poder jugar. Cuentas en un móvil de 393x852
     (iPhone 14 Pro): cabecera 195 + pestañas 61 dejan 596 px. Antes el Núcleo pedía unos 720.
     Qué se ha hecho, de más a menos ahorro:
      - El skyline decorativo solo sale a partir de 900 px de alto (tabletas). 64 px.
      - Los chips con los edificios que tienes salen de esta pantalla: ya están en Construir. 40 px.
      - Las tres habilidades van en una fila, con el estado en corto. La explicación larga está en
        su botón de información. De unos 170 px a 60.
      - "Vale por toque" y "ritmo" comparten fila dentro del núcleo. 32 px.
      - Los contratos solo ocupan fila con encargos por elegir o uno en curso (fx-quests.js).
      - Entrenando, la tarjeta de entrenamiento sustituye al texto de objetivo en vez de sumarse.
     El núcleo se dibuja al tamaño que sobra (--core): 230 px si cabe, y encoge hasta 150 en
     pantallas bajas. El canvas 2D y el 3D escalan solos con su contenedor. */
  /* 2026-10-02 (prueba en móvil: "el núcleo es minúsculo"): el núcleo se queda con TODO el alto que
     sobra tras la cabecera, el hueco fijo, su pie y una fila de contenido debajo (las respuestas de la
     apertura, una habilidad o la voz); lo demás se alcanza desplazando. Tope en el ancho. */
  :root{ --core:clamp(170px, calc(100vh - 476px), min(320px, calc(100vw - 56px))); }
  @supports (height:100dvh){ :root{ --core:clamp(170px, calc(100dvh - 476px), min(320px, calc(100vw - 56px))); } }
  @media (max-height: 899px){ .skyline{ display:none; } }
  .corewrap, #core{ width:var(--core); height:var(--core); }
  .corewrap #core{ width:100%; height:100%; }
  .corebox{ padding:9px 10px 9px; gap:5px; }
  .corebox .readout{ font-size:.75rem; letter-spacing:.06em; padding:3px 10px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
  .corefoot{ display:flex; align-items:stretch; justify-content:center; gap:6px; width:100%; }
  .corefoot .clickval{ flex:none; display:flex; align-items:center; gap:4px; white-space:nowrap; font-size:.78rem; }
  .corefoot .clickval .ri{ width:12px; height:12px; margin:0; }
  .corefoot .ritmo{ flex:1; min-width:0; width:auto; max-width:230px; }
  #tab-core{ gap:9px; }
  #tab-core .goal .gtxt{ font-size:.84rem; line-height:1.35; }
  #tab-core .fleet{ display:none; }
  /* habilidades: una fila, tarjetas iguales, y el botón de información al final */
  .abilities{ display:flex; gap:6px; align-items:stretch; }
  .ability, .ability.wide{ flex:1 1 0; min-width:0; padding:7px 8px 8px; gap:1px; grid-column:auto; }
  .ability[hidden]{ display:none; }
  .ability .an{ font-size:.78rem; gap:4px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
  .ability .an svg{ width:14px; height:14px; flex:none; }
  .ability .ad{ font-family:"IBM Plex Mono"; font-size:.75rem; line-height:1.3; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
  .abilities .abinfo{ align-self:center; flex:none; }
  .abilities:not(:has(.ability:not([hidden]))) .abinfo{ display:none; }
  /* entrenamiento: una franja, no una tarjeta */
  .traincard{ display:grid; grid-template-columns:minmax(0,1fr) auto; gap:4px 10px; padding:8px 10px; align-items:center; }
  .traincard .tr-head{ grid-column:1; } .traincard .tr-thumb{ display:none; }
  .traincard .bar{ grid-column:1; } .traincard .note{ grid-column:1; font-size:.75rem; }
  .traincard .adbtn{ grid-column:2; grid-row:1 / span 3; align-self:center !important; }
  #contractRow{ padding:7px 9px; }
  /* móviles bajos (iPhone SE, Safari con las barras a la vista): cabecera todavía más apretada */
  @media (max-height: 700px){
    header{ padding:6px 16px 2px; }
    .meter{ padding:4px 5px; } .meter .value{ font-size:.94rem; }
    main{ padding:6px 16px 10px; }
    #tab-core{ gap:7px; }
  }
  /* móviles estrechos (320 a 350 px): las tres habilidades siguen en fila, con menos relleno */
  @media (max-width: 350px){
    main{ padding-inline:12px; } .meters, .mats, .riskrow{ padding-inline:12px; } header{ padding-inline:12px; }
    .ability, .ability.wide{ padding:6px 6px 7px; } .ability .an svg{ display:none; }
    .corefoot .ritmo .rl{ display:none; }
  }
  /* el título ya no se mete debajo del chip del Modelo: si no cabe, se recorta con puntos */
  header h1{ overflow:hidden; text-overflow:ellipsis; }
  header .chip{ flex:0 1 auto; min-width:0; max-width:42%; }

  /* ---------- Historia: registro del modelo, desviación y apertura (2026-10-02) ----------
     A2a: el chip del Modelo es un botón que abre el registro. El punto avisa de frases sin leer.
     A3a: la desviación son tres tramos y una marca; en los dilemas, un texto corto por opción. */
  .chip.model{ position:relative; }
  .chip.model.has-new{ padding-right:16px; }
  .chip.model.has-new::after{ content:""; position:absolute; right:6px; top:50%; width:6px; height:6px; margin-top:-3px; border-radius:50%; background:var(--research); }
  .vq{ display:flex; gap:9px; align-items:flex-start; background:var(--surface-2); border:1px solid var(--research-dim); border-radius:10px; padding:9px 10px; }
  .vq img{ width:30px; height:30px; border-radius:50%; object-fit:cover; flex:none; }
  .vq .vqb{ display:flex; flex-direction:column; gap:2px; min-width:0; }
  .vq .vqw{ font-family:"IBM Plex Mono"; font-size:.75rem; letter-spacing:.08em; text-transform:uppercase; color:var(--research); }
  .vq .vqt{ font-family:"IBM Plex Mono"; font-size:.84rem; line-height:1.45; color:var(--text); }
  .driftbox{ --dc:var(--energy); display:flex; flex-direction:column; gap:6px; border:1px solid var(--border); border-radius:10px; padding:10px; background:var(--surface-2); }
  .driftbox.tier0{ --dc:var(--compute); } .driftbox.tier2{ --dc:var(--risk); }
  .driftbox .vq{ background:var(--surface); }
  .dr-head{ display:flex; align-items:center; gap:6px; }
  .dr-k{ font-family:"IBM Plex Mono"; font-size:.75rem; letter-spacing:.1em; text-transform:uppercase; color:var(--muted); }
  .dr-tier{ margin-left:auto; font-family:"IBM Plex Mono"; font-size:.84rem; color:var(--dc); }
  .dr-bar{ position:relative; display:flex; gap:3px; height:8px; margin-top:2px; }
  .dr-seg{ flex:1; border-radius:3px; background:var(--compute-dim); }
  .dr-seg:nth-child(2){ background:var(--energy-dim); } .dr-seg:nth-child(3){ background:var(--risk-dim); }
  .dr-mark{ position:absolute; top:-3px; width:4px; height:14px; margin-left:-2px; border-radius:2px; background:var(--text); box-shadow:0 0 0 2px var(--surface-2); }
  .dr-ends{ display:flex; justify-content:space-between; font-family:"IBM Plex Mono"; font-size:.75rem; color:var(--muted); }
  .dr-say{ margin:0; font-size:.84rem; line-height:1.4; color:var(--text); }
  .dr-now{ font-family:"IBM Plex Mono"; font-size:.75rem; letter-spacing:.08em; text-transform:uppercase; color:var(--muted); margin-top:2px; }
  .reg-g{ border-top:1px solid var(--border); padding-top:6px; display:flex; flex-direction:column; gap:6px; }
  .reg-h{ appearance:none; background:none; border:0; padding:4px 0; display:flex; align-items:baseline; justify-content:space-between; gap:8px; width:100%; cursor:pointer; color:inherit; text-align:left; }
  .reg-n{ font-family:"IBM Plex Mono"; font-size:.84rem; color:var(--research); }
  .reg-c{ font-family:"IBM Plex Mono"; font-size:.75rem; color:var(--muted); }
  .reg-l{ display:flex; flex-direction:column; gap:2px; padding:2px 0 4px; }
  .reg-m{ font-family:"IBM Plex Mono"; font-size:.75rem; color:var(--muted); }
  .reg-m b{ color:var(--research); font-weight:500; }
  .reg-t{ font-family:"IBM Plex Mono"; font-size:.84rem; line-height:1.45; color:var(--text); }
  .driftchip{ align-self:flex-start; font-family:"IBM Plex Mono"; font-size:.75rem; letter-spacing:.04em; padding:2px 7px; border-radius:5px; border:1px solid var(--border); margin-top:2px; }
  .driftchip.away{ color:var(--energy); border-color:var(--energy-dim); }
  .driftchip.near{ color:var(--compute); border-color:var(--compute-dim); }
  .driftres{ display:flex; flex-wrap:wrap; align-items:center; gap:6px 8px; }
  .driftres .dr-note{ font-size:.8rem; color:var(--muted); }

  /* ---------- Novedades y ajustes (2026-10-02) ---------- */
  .nov-prize{ display:flex; align-items:baseline; gap:8px; border:1px solid var(--energy-dim); border-radius:8px; padding:8px 10px; }
  .nov-prize span{ font-family:"IBM Plex Mono"; font-size:.75rem; letter-spacing:.1em; text-transform:uppercase; color:var(--energy); flex:none; }
  .nov-prize b{ font-size:.88rem; font-weight:600; color:var(--text); }
  /* Ajustes: filas con su opción a la derecha. Botones de contorno, nunca sólidos. */
  .prefs{ display:flex; flex-direction:column; gap:8px; }
  .prow{ display:flex; align-items:center; justify-content:space-between; gap:10px; padding-top:8px; border-top:1px solid var(--border); }
  .prow:first-child{ border-top:0; padding-top:0; }
  .prow .pt{ display:flex; flex-direction:column; gap:1px; min-width:0; }
  .prow .pt b{ font-size:.92rem; font-weight:600; }
  .prow .pt span{ font-size:.78rem; color:var(--muted); line-height:1.3; }
  .seg{ display:flex; flex-wrap:wrap; gap:5px; flex:none; }
  .seg button{ appearance:none; background:transparent; border:1px solid var(--border); color:var(--muted); font-family:"IBM Plex Mono"; font-size:.78rem; padding:7px 10px; border-radius:7px; cursor:pointer; min-height:34px; }
  .seg button[aria-pressed="true"]{ color:var(--compute); border-color:var(--compute-dim); background:var(--surface-2); }
  .seg button:active{ transform:scale(.96); }
  .pchips{ display:flex; flex-direction:column; gap:5px; }
  .pchips .seg{ flex:1; }
  .pnote{ margin:0; font-size:.78rem; line-height:1.35; color:var(--muted); }
  /* C4a · nivel Mínimo: ninguna animación ni transición, igual que con movimiento reducido */
  body.fx-min *, body.fx-min *::before, body.fx-min *::after{ animation-duration:.01ms !important; animation-iteration-count:1 !important; transition-duration:.01ms !important; }

  /* ---------- Consejos (2026-10-03): qué hacer ahora ---------- */
  .tip{ display:flex; align-items:center; gap:10px; border:1px solid var(--border); border-radius:10px; padding:9px 10px; background:var(--surface-2); }
  .tip .tn{ flex:none; width:22px; height:22px; border-radius:50%; border:1px solid var(--energy-dim); color:var(--energy); font-family:"IBM Plex Mono"; font-size:.78rem; display:flex; align-items:center; justify-content:center; }
  .tip .tt{ flex:1; min-width:0; display:flex; flex-direction:column; gap:2px; }
  .tip .tt b{ font-size:.9rem; font-weight:600; line-height:1.3; }
  .tip .tt span{ font-size:.8rem; line-height:1.35; color:var(--muted); }
  .tip .btn-s{ flex:none; padding:8px 10px; font-size:.78rem; }
  /* material raro en camino: se ve en el Núcleo antes de que llegue el convoy */
  .mat .mv span.way{ opacity:1; }
  .mat .mv{ flex-wrap:wrap; }
  /* cabecera con tres iconos: en móviles estrechos el título cede sitio al chip del Modelo, que
     es el que se toca */
  @media (max-width: 400px){
    header{ gap:8px; }
    header h1{ font-size:.86rem; letter-spacing:0; }
    /* el título no se corta nunca; si el nombre del Modelo es largo, el que se acorta es el chip */
    header > div:first-child{ flex:none; }
    header .chip.model{ letter-spacing:0; padding-inline:6px; max-width:none; flex:0 1 auto; min-width:0; }
    header .chip.model.has-new{ padding-right:15px; }
    .iconGroup{ gap:6px; }
  }
  .tipnext{ display:flex; flex-wrap:wrap; align-items:baseline; gap:4px 8px; border-top:1px solid var(--border); padding-top:9px; font-family:"IBM Plex Mono"; }
  .tipnext span{ font-size:.75rem; letter-spacing:.1em; text-transform:uppercase; color:var(--energy); }
  .tipnext b{ font-size:.86rem; font-weight:600; color:var(--text); }
  .tipnext em{ font-style:normal; font-size:.78rem; color:var(--muted); flex-basis:100%; }
  /* franja que da seguro el material que falta */
  #destCard .opt.sure{ border-color:var(--energy-dim); }
  #destCard .opt.sure .oe{ color:var(--energy); }

  /* ---------- Legibilidad (2026-10-04): ningún texto por debajo de 12 px ----------
     Había 91 reglas con letra de 9 a 11,8 px. Todas suben a 12 px (.75rem). En las casillas más
     estrechas (medidores de la cabecera, materiales, medidores de colonia, etiquetas ganas y
     pierdes) se quita el espaciado entre letras para que el texto siga cabiendo. */
  .meter .label, .mat .mn, .colmeters .meter .label, .fxb .fxtag, .fxline .fxtag, .raterow .rl, .autosend .end small{ letter-spacing:0; }
  .meter .label{ gap:3px; }
  /* a 12 px y en mayúsculas "CRIOGEL" y "CÓMPUTO" no caben en un móvil de 360: van en minúsculas */
  .meter .label, .mat .mn{ text-transform:none; }
  .mat{ padding:4px 5px; } .mat .mn{ gap:3px; }
  /* en móviles estrechos el nombre del material, que ya va en su color, vale más que su icono */
  @media (max-width: 400px){ .mat .mn svg{ display:none; } }
  .meter .label span, .mat .mn span{ overflow:hidden; text-overflow:ellipsis; min-width:0; }
  .colmeters .meter{ padding-inline:4px; }
  .colmeters .meter .label .ri{ display:none; }

  /* ---------- Cabecera en dos filas en móviles estrechos (2026-10-04) ----------
     Con un Modificador de Deriva activo (todas las Derivas menos la primera) la cabecera llevaba
     título, dos chips y tres iconos en una sola fila, y los dos chips quedaban en "v2…" y "Pi…".
     Ahora el modificador baja a la segunda fila, a la altura de la fase. */
  @media (max-width: 400px){
    header{ display:grid; grid-template-columns:auto minmax(0,1fr) auto; grid-template-rows:auto auto; column-gap:8px; row-gap:2px; align-items:center; }
    header > div:first-child{ grid-row:1 / span 2; grid-column:1; min-width:0; }
    header .chip.model{ grid-row:1; grid-column:2; justify-self:end; max-width:100%; }
    header .iconGroup{ grid-row:1; grid-column:3; }
    /* la fase, debajo del título, ya dice el número: el chip enseña solo el nombre del Modelo */
    header .chip.model .cv{ display:none; }
    /* la fase no ensancha la columna del título: si es larga ("automatización") se acorta ella */
    header .phase{ width:0; min-width:100%; letter-spacing:0; }
  }
  @media (max-width: 370px){
    header{ column-gap:6px; padding-inline:10px; }
    header h1{ font-size:.8rem; }
    .iconGroup{ gap:4px; }
    header .chip.model{ padding-inline:5px; }
  }

  /* ---------- P1 y P2 (2026-10-05): mandato en el Núcleo y opciones en la pantalla de fusión ---------- */
  .mandaterow{ display:flex; align-items:center; justify-content:center; gap:8px; min-height:18px; font-family:"IBM Plex Mono"; font-size:.75rem; color:var(--energy); }
  .mandaterow[hidden]{ display:none; }
  .mandaterow.broken{ color:var(--muted); text-decoration:line-through; }
  .mandaterow .infobtn{ text-decoration:none; }
  .endline{ display:flex; flex-wrap:wrap; align-items:center; gap:6px 10px; border:1px solid var(--border); border-radius:10px; padding:9px 11px; }
  .endline .k{ font-family:"IBM Plex Mono"; font-size:.75rem; letter-spacing:.1em; text-transform:uppercase; color:var(--energy); }
  .endline b{ font-size:.9rem; font-weight:600; }
  .endline .ok{ color:var(--compute); font-family:"IBM Plex Mono"; font-size:.8rem; }
  .endline .no{ color:var(--muted); font-family:"IBM Plex Mono"; font-size:.8rem; }
  .endline .note{ flex-basis:100%; font-size:.8rem; color:var(--muted); line-height:1.35; }
  .mbonus{ font-family:"IBM Plex Mono"; font-size:.75rem; color:var(--energy); font-weight:400; margin-left:6px; }

  /* ---------- pisos del árbol de Anclas (2026-10-05) ---------- */
  .floorhead{ display:flex; align-items:center; gap:8px; margin:8px 0 2px; }
  .floorhead .wc-label{ color:var(--energy); }
  .anode.locked{ opacity:.45; }
  .anode.locked .icon{ filter:grayscale(1); }
  .floorlock{ font-family:"IBM Plex Mono"; font-size:.75rem; color:var(--muted); margin:-2px 0 4px 2px; }
  .row.beca button .c::after{ content:" · beca"; color:var(--energy); }

  /* ---------- final y epílogo (2026-10-05) ---------- */
  .epi{ display:flex; flex-direction:column; gap:6px; }
  .epi-row{ display:grid; grid-template-columns:22px minmax(0,1fr); gap:2px 8px; align-items:baseline; border-bottom:1px solid var(--border); padding-bottom:6px; }
  .epi-row .n{ font-family:"IBM Plex Mono"; font-size:.75rem; color:var(--energy); grid-row:1 / span 2; }
  .epi-row b{ font-size:.92rem; }
  .epi-row .m{ grid-column:2; font-family:"IBM Plex Mono"; font-size:.75rem; color:var(--muted); }

  /* ---------- aviso de la bombilla de consejos (2026-10-07) ---------- */
  .tipshint{ display:flex; align-items:center; gap:10px; margin:6px 16px 0; padding:9px 11px; border:1px solid var(--energy-dim); border-radius:10px; background:var(--surface); font-size:.86rem; line-height:1.35; color:var(--text); }
  .tipshint[hidden]{ display:none; }
  .tipshint span{ flex:1; min-width:0; }
  .tipshint .btn-s{ flex:none; padding:7px 10px; font-size:.78rem; }
  .iconbtn.attn{ border-color:var(--energy); color:var(--energy); animation:tipsPulse 1.6s ease-in-out infinite; }
  @keyframes tipsPulse{ 0%,100%{ box-shadow:0 0 0 0 rgba(232,163,61,.0); } 50%{ box-shadow:0 0 0 5px rgba(232,163,61,.28); } }
  @media (prefers-reduced-motion: reduce){ .iconbtn.attn{ animation:none; } }
  /* la vía de convoyes: un punto por convoy en vuelo (2026-10-08) */
  .autosend .rail i[hidden]{ display:none; }
  .autosend .rail b{ white-space:nowrap; font-weight:500; color:var(--muted); }

  /* ---------- de qué va el juego (2026-10-01): ficha de cuatro líneas y marcadores explicables ---------- */
  .howto{ list-style:none; margin:4px 0 0; padding:0; display:flex; flex-direction:column; gap:7px; }
  .howto li{ display:flex; flex-direction:column; gap:1px; padding:6px 10px; border-left:3px solid var(--border); background:var(--surface-2); border-radius:0 8px 8px 0; font-size:.86rem; line-height:1.4; }
  .howto li b{ font-size:.8rem; letter-spacing:.04em; text-transform:uppercase; }
  .howto .h-goal{ border-color:var(--text); } .howto .h-compute{ border-color:var(--compute); } .howto .h-compute b{ color:var(--compute); }
  .howto .h-energy{ border-color:var(--energy); } .howto .h-energy b{ color:var(--energy); }
  .howto .h-later{ border-color:var(--research); } .howto .h-later b{ color:var(--research); }
  .howto .h-risk{ border-color:var(--risk); } .howto .h-risk b{ color:var(--risk); }
  .howtobtn{ margin-top:10px; width:100%; }
  .meters .meter[data-info]{ cursor:pointer; }
  .meters .meter:focus-visible{ outline:2px solid var(--compute); outline-offset:1px; }
  .meters .meter.locked{ opacity:.55; }
  .meters .meter.locked .value::after{ content:" ·"; color:var(--muted-2); }

  /* ---------- A1 · apertura: la voz del núcleo (onboarding.js, 2026-10-01) ----------
     Panel de conversación encima del núcleo real; mientras dura, la guía de primeros pasos no se
     muestra (toma el relevo al cerrar) y el núcleo late en verde cuando pide que lo toquen. */
  .intropanel{ margin:0 0 12px; padding:12px 14px; border:1px solid var(--compute-dim); border-radius:12px; background:var(--surface); display:flex; flex-direction:column; gap:9px; animation:calloutIn .5s ease-out 1; }
  body.intro-on .corebox.guide-armed{ border-color:var(--border); box-shadow:none; animation:none; }
  .intropanel .introsay{ background:var(--surface-2); border:1px solid var(--compute-dim); border-radius:10px; padding:10px 12px; min-height:84px; font-size:.98rem; line-height:1.45; }
  .intropanel .introsay .who{ font-family:"IBM Plex Mono"; font-size:.72rem; letter-spacing:.1em; text-transform:uppercase; color:var(--compute); margin-bottom:3px; }
  .intropanel .introsay .cur{ display:inline-block; width:7px; height:.95em; background:var(--compute); vertical-align:-2px; margin-left:2px; animation:introBlink 1s steps(2) infinite; }
  .intropanel .introtap{ text-align:center; font-family:"IBM Plex Mono"; font-size:.84rem; letter-spacing:.06em; color:var(--compute); }
  .intropanel .opts{ display:flex; flex-direction:column; gap:6px; }
  .intropanel .opts .opt{ margin:0; }
  body.intro-on #coreGuide, body.intro-on #pulseHint, body.intro-on #tipsHint{ display:none !important; }
  .corebox.ask{ border-color:var(--compute); animation:introAsk 1.2s ease-in-out infinite; }
  @keyframes introAsk{ 0%,100%{ box-shadow:0 0 0 0 rgba(82,224,196,.0); } 50%{ box-shadow:0 0 0 4px rgba(82,224,196,.35); } }
  @keyframes introBlink{ to{ opacity:0; } }
  @media (prefers-reduced-motion: reduce){ .corebox.ask, .intropanel .introsay .cur, .intropanel{ animation:none; } }

  /* ---------- A4 · la interfaz nace cuando toca (reveal.js, 2026-10-01) ---------- */
  .unborn{ display:none !important; }
  .born-in{ animation:bornIn .7s cubic-bezier(.2,1,.3,1); }
  @keyframes bornIn{ from{ opacity:0; transform:translateY(-6px) scale(.96); } to{ opacity:1; transform:none; } }
  @media (prefers-reduced-motion: reduce){ .born-in{ animation:none; } }

  /* ---------- Sprint (sprint.js, 2026-10-01): todo lo del Sprint es ámbar ---------- */
  .sprintstrip{ margin:6px 16px 0; padding:8px 11px; border:1px solid var(--energy-dim); border-radius:10px; background:#1f160a; display:flex; flex-direction:column; gap:5px; font-family:"IBM Plex Mono"; }
  .sprintstrip[hidden]{ display:none; }
  .sprintstrip .sps{ display:flex; justify-content:space-between; align-items:baseline; gap:8px; font-size:.86rem; }
  .sprintstrip .sps b{ color:var(--energy); letter-spacing:.1em; font-size:.78rem; }
  .sprintstrip .sps.s{ font-size:.75rem; color:var(--muted); }
  .sprintstrip .sbar{ height:5px; border-radius:3px; background:var(--border); overflow:hidden; }
  .sprintstrip .sbar i{ display:block; height:100%; width:0; background:var(--energy); transition:width .3s; }
  .sprintstrip button.lnk{ background:none; border:0; padding:0; margin:0; min-height:0; height:auto; color:var(--muted); font:inherit; font-size:.75rem; text-decoration:underline; cursor:pointer; box-shadow:none; }
  .sprintstrip .lnk[data-arm="1"]{ color:var(--risk); }
  body.sprint-on #progressBtn, body.sprint-on #tipsBtn, body.sprint-on .adbtn, body.sprint-on #tipsHint{ display:none !important; }
  .pg-sprint{ border:1px solid var(--energy-dim); border-radius:12px; padding:10px 12px; display:flex; flex-direction:column; gap:7px; background:color-mix(in srgb, var(--energy) 6%, var(--surface)); }
  .pg-sprint:empty{ display:none; }
  .pg-sprint-head{ display:flex; align-items:center; gap:8px; }
  .pg-sprint .ey{ font-family:"IBM Plex Mono"; font-size:.74rem; letter-spacing:.1em; text-transform:uppercase; color:var(--energy); }
  .pg-sprint .t{ font-weight:600; font-size:.95rem; }
  .pg-sprint-rows{ display:flex; flex-direction:column; gap:3px; font-size:.86rem; }
  .pg-sprint-rows .spr{ display:flex; justify-content:space-between; gap:8px; }
  .pg-sprint-rows .spr > span:first-child{ color:var(--muted); }
  .pg-sprint .a, .spbig.num, .spruns .a{ color:var(--energy); }
  .pg-sprint-btns{ display:flex; gap:6px; flex-wrap:wrap; align-items:center; }
  .pg-sprint-btns .btn-s.sp{ color:var(--energy); border-color:var(--energy-dim); flex:1; }
  .pg-sprint-btns .done{ font-size:.84rem; color:var(--muted); flex:1; }
  .overlay.sprint .card{ border-color:var(--energy-dim); }
  .overlay.sprint .eyebrow{ color:var(--energy); }
  .sprows{ display:flex; flex-direction:column; gap:6px; }
  .sprow{ display:flex; flex-direction:column; gap:2px; text-align:left; width:100%; padding:9px 12px; border:1px solid var(--border); border-radius:10px; background:var(--surface-2); color:var(--text); font:inherit; cursor:pointer; }
  .sprow b{ color:var(--energy); font-size:.92rem; }
  .sprow span{ font-size:.86rem; color:var(--muted); line-height:1.35; }
  .sprow:focus-visible, .sprow:active{ border-color:var(--energy); }
  .spbig{ font-size:2.2rem; font-weight:600; line-height:1.1; }
  .spruns{ display:flex; flex-direction:column; gap:4px; font-size:.88rem; max-height:40vh; overflow-y:auto; }
  .spruns .spr{ display:flex; justify-content:space-between; gap:8px; padding:4px 0; border-bottom:1px solid var(--border); }
  .spruns .m{ color:var(--muted); }
  .pg-sprint .mut{ font-size:.84rem; color:var(--muted); line-height:1.35; }
  .pg-sprint .mut b{ color:var(--energy); font-weight:600; }
  .sprintstrip .mutn{ color:var(--energy); }
  .spruns .spr small{ display:block; font-size:.74rem; color:var(--muted); }
  .spruns .spv{ display:flex; align-items:center; gap:8px; }
  .spruns .spv .btn-s{ padding:4px 8px; font-size:.74rem; }
  /* la cuenta atrás de los objetivos semanales va junto a su rótulo (antes, junto al título "Hoy", no se entendía) */
  .pg-sub .num{ font-size:.75rem; color:var(--muted); white-space:nowrap; }
  .pg-sub2{ font-size:.75rem; color:var(--muted); margin-top:-4px; }

  /* ---------- Pantalla principal, dirección C+A+B (2026-10-02) ----------
     Marcadores más compactos con la tasa en su color; riesgo en una línea fina con marcas en 50 y
     85; el Siguiente Modelo como tarjeta con barra y fichas; el pie del núcleo como una sola barra;
     atajos bajo el núcleo; la voz del núcleo en un sitio fijo. */
  .meter .value{ font-size:1.05rem; }
  .meters .meter:nth-child(1) .rate{ color:var(--compute); } .meters .meter:nth-child(2) .rate{ color:var(--energy); }
  .meters .meter:nth-child(3) .rate{ color:var(--research); } .meters .meter:nth-child(4) .rate{ color:var(--data); }
  .riskrow{ padding-top:8px; }
  .riskrow .label{ font-size:.72rem; }
  .riskrow .label span{ display:none; } /* el icono y la barra ya dicen qué es; el texto va en la ficha (i) */
  .riskrow .label::after{ content:"riesgo"; }
  .risk-track{ height:6px; overflow:visible; }
  .risk-track .mk{ position:absolute; top:-3px; width:1px; height:12px; background:var(--muted-2); }
  .risk-track .mk.hot{ background:var(--risk); }
  .riskrow .value{ color:var(--text); }
  /* siguiente Modelo */
  #tab-core .goal{ text-align:left; background:var(--surface); border:1px solid var(--border); border-radius:12px; padding:8px 12px; margin-bottom:8px; display:flex; flex-direction:column; gap:7px; color:var(--text); }
  #tab-core .goal:empty{ display:none; }
  .goal .gl{ display:flex; justify-content:space-between; align-items:baseline; gap:8px; font-size:.86rem; }
  .goal .gl b{ font-weight:600; }
  .goal .gk{ color:var(--muted); }
  .goal .geta{ font-size:.74rem; color:var(--muted); white-space:nowrap; }
  .goal .gbar{ height:6px; border-radius:3px; background:var(--surface-3); overflow:hidden; }
  .goal .gbar i{ display:block; height:100%; border-radius:3px; background:linear-gradient(90deg, var(--compute), var(--research), var(--data)); transition:width .4s; }
  .goal .gchips{ display:flex; flex-wrap:wrap; gap:4px; }
  .goal .gc{ font-family:"IBM Plex Mono"; font-size:.72rem; padding:2px 6px; border-radius:7px; border:1px solid var(--border); background:var(--surface-2); color:var(--muted); display:inline-flex; align-items:center; gap:4px; }
  .goal .gc .ri{ width:11px; height:11px; }
  .goal .gc.compute{ color:var(--compute); } .goal .gc.research{ color:var(--research); } .goal .gc.data{ color:var(--data); }
  .goal .gtip{ font-size:.76rem; color:var(--muted); align-self:center; }
  /* pie del núcleo */
  .corefoot{ flex-direction:column; align-items:stretch; gap:4px; background:rgba(7,10,12,.72); border:1px solid rgba(38,49,57,.8); border-radius:10px; padding:7px 10px; backdrop-filter:blur(3px); }
  .corefoot .cf-top{ display:flex; justify-content:space-between; align-items:center; gap:8px; }
  .corefoot .clickval, .corefoot .ritmo{ background:none; border:0; padding:0; backdrop-filter:none; width:auto; max-width:none; }
  .corefoot .clickval{ font-size:.82rem; }
  .corefoot .ritmo{ gap:6px; }
  .corefoot .ritmo .rl{ display:inline; font-size:.72rem; }
  .corefoot .rt{ height:5px; border-radius:3px; background:var(--surface-3); overflow:hidden; }
  .corefoot .rt > div{ height:100%; background:var(--compute); width:0; transition:width .15s; }
  .corefoot .rh{ font-size:.7rem; color:var(--muted-2); white-space:nowrap; }
  @media (max-width:400px){ .corefoot .ritmo .rl{ display:none; } }
  .tapbig{ position:absolute; left:50%; top:16%; transform:translateX(-50%); font-size:1.9rem; font-weight:700; color:var(--compute); text-shadow:0 0 18px rgba(82,224,196,.65); pointer-events:none; opacity:0; z-index:2; }
  .tapbig.go{ animation:tapBig .7s ease-out forwards; }
  .tapbig.hot{ color:var(--energy); text-shadow:0 0 18px rgba(232,163,61,.7); }
  @keyframes tapBig{ 0%{ opacity:0; transform:translate(-50%,10px) scale(.8); } 15%{ opacity:1; transform:translate(-50%,0) scale(1.08); } 100%{ opacity:0; transform:translate(-50%,-34px) scale(1); } }
  /* la voz del núcleo */
  .voiceline{ display:flex; align-items:center; gap:10px; margin-top:8px; background:var(--surface); border:1px solid var(--research-dim); border-radius:12px; padding:6px 12px; font-size:.84rem; color:var(--muted); line-height:1.35; }
  .voiceline[hidden]{ display:none; }
  .voiceline img{ width:28px; height:28px; border-radius:50%; flex:none; object-fit:cover; }
  .voiceline span{ min-width:0; }
  .voiceline.fresh{ animation:calloutIn .5s ease-out 1; }
  @media (prefers-reduced-motion: reduce){ .tapbig.go, .voiceline.fresh{ animation:none; } .tapbig.go{ opacity:1; } }

  /* ---------- cabecera como en la maqueta C (2026-10-02): "ALIGNMENT DRIFT · v2" en una línea ---------- */
  header .titlerow{ display:flex; align-items:baseline; gap:7px; }
  header .chip.model.inline{ background:none; border:0; padding:0; margin:0; font:inherit; font-family:"IBM Plex Mono"; font-size:.86rem; letter-spacing:0; color:var(--muted); cursor:pointer; max-width:none; min-width:0; flex:none; }
  header .chip.model.inline.has-new{ padding-right:11px; color:var(--research); }
  header .chip.model.inline.has-new::after{ right:0; }
  header .phase{ display:none; } /* la fase ya se ve en el arte del núcleo; la cabecera se queda en una línea */
  /* ---------- contadores en las pestañas ---------- */
  nav.tabs button{ position:relative; }
  nav.tabs button.has-count .badge{ display:flex; align-items:center; justify-content:center; position:absolute; top:3px; left:calc(50% + 7px); min-width:16px; height:16px; padding:0 4px; border-radius:8px; background:var(--energy); color:#1a1004; font-family:"IBM Plex Mono"; font-size:.68rem; font-weight:600; line-height:1; border:2px solid var(--bg); box-sizing:content-box; }

  /* ---------- una sola cosa debajo del núcleo (2026-10-02) ----------
     Debajo del núcleo caben, a 375×812, una tarjeta y la voz. Prioridad de arriba abajo; lo de
     menos prioridad se esconde, nunca se amontona:
       1. fusionar  2. entrenamiento  3. aviso del pulso  4. encargos por elegir  5. mandato
     El contrato EN CURSO ya se ve en la franja de arriba, así que su fila no se repite aquí. */
  #contractRow.running{ display:none; }
  #tab-core:has(#fuseBtn:not([hidden])) :is(#trainWrap, #pulseHint, #contractRow, #mandateRow),
  #tab-core:has(#trainWrap:not([hidden])) :is(#pulseHint, #contractRow, #mandateRow),
  #tab-core:has(#pulseHint:not([hidden])) :is(#contractRow, #mandateRow),
  #tab-core:has(#contractRow.armed:not([hidden])) #mandateRow{ display:none; }
  .mandaterow{ white-space:nowrap; overflow:hidden; }
  .mandaterow > span{ overflow:hidden; text-overflow:ellipsis; min-width:0; }
  /* la voz: dos líneas como mucho; el resto se lee en el registro (tocar la frase lo abre) */
  .voiceline{ cursor:pointer; }
  .voiceline span{ display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }
  /* con la franja de contrato en curso arriba, el núcleo cede su alto para que la voz no se salga */
  /* objetivo: material raro que falta, con acceso a Red */
  .goal .gc.mat{ color:var(--energy); border-color:var(--energy-dim); }
  .goal .gmat{ display:flex; align-items:center; justify-content:space-between; gap:8px; font-size:.8rem; color:var(--muted); line-height:1.3; }
  .goal .gmat .btn-s{ flex:none; padding:5px 10px; font-size:.76rem; }

  /* ---------- Investigar, dirección C (research.js, 2026-10-02) ---------- */
  #tab-research .tabhero{ display:none; } /* sin imagen: la pantalla va directa a lo que se puede hacer */
  .rline{ display:flex; align-items:center; justify-content:space-between; gap:10px; margin-bottom:8px; font-family:"IBM Plex Mono"; }
  .rline .dots{ display:flex; align-items:center; }
  .rline .dots i{ width:20px; height:20px; border-radius:50%; border:1.5px solid var(--border); display:flex; align-items:center; justify-content:center; font-style:normal; font-size:.72rem; color:var(--muted-2); background:var(--bg); }
  .rline .dots i.ok{ border-color:var(--compute); color:var(--compute); }
  .rline .dots i.now{ border-color:var(--compute); background:var(--compute); color:#06231e; font-weight:600; }
  .rline .dots i.nx{ border-color:var(--research); color:var(--research); }
  .rline .dots u{ width:14px; height:1.5px; background:var(--border); text-decoration:none; }
  .rline .dots u.ok{ background:var(--compute); }
  .rline .doc{ font-size:.74rem; color:var(--data); border:1px solid var(--data-dim); border-radius:7px; padding:2px 8px; white-space:nowrap; }
  .rline .doc.none{ color:var(--muted-2); border-color:var(--border); }
  /* el siguiente Modelo: una fila con barra por recurso */
  .modelcard.next .costs{ display:block; width:100%; }
  .modelcard .mrows{ display:flex; flex-direction:column; gap:5px; width:100%; }
  .modelcard .mrow{ display:flex; align-items:center; gap:8px; font-family:"IBM Plex Mono"; font-size:.74rem; color:var(--muted); }
  .modelcard .mrow .k{ width:66px; flex:none; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
  .modelcard .mrow .bar{ flex:1; min-width:40px; height:6px; border-radius:3px; background:var(--surface-3); overflow:hidden; }
  .modelcard .mrow .bar i{ display:block; height:100%; border-radius:3px; }
  .modelcard .mrow .v{ width:104px; flex:none; text-align:right; white-space:nowrap; }
  .modelcard .mrow.ok .v{ color:var(--compute); }
  .modelcard .mtime{ font-family:"IBM Plex Mono"; font-size:.72rem; color:var(--muted-2); }
  /* filtros */
  .tfilters{ display:flex; gap:5px; margin:12px 0 2px; overflow-x:auto; scrollbar-width:none; }
  .tfilters::-webkit-scrollbar{ display:none; }
  .tfilters button{ flex:none; font-family:"IBM Plex Mono"; font-size:.75rem; padding:5px 10px; border-radius:999px; border:1px solid var(--border); background:none; color:var(--muted); cursor:pointer; }
  .tfilters button.on{ color:var(--text); border-color:var(--muted-2); background:var(--surface-2); }
  .tfilters:empty{ display:none; }
  /* la lista: un solo contenedor en columna; las cabeceras y las filas se ordenan con order */
  .techlist{ display:flex; flex-direction:column; }
  .techlist .tsec{ display:flex; justify-content:space-between; align-items:baseline; gap:8px; margin:10px 0 2px; font-family:"IBM Plex Mono"; font-size:.74rem; letter-spacing:.1em; text-transform:uppercase; color:var(--muted); background:none; border:0; padding:0; text-align:left; width:100%; }
  .techlist .tsec b{ font-weight:500; letter-spacing:0; text-transform:none; color:var(--compute); }
  .techlist .tsec.soon b, .techlist .tsec.later b{ color:var(--muted); }
  .techlist button.tsec{ cursor:pointer; }
  .techlist .tsec[hidden], .techlist .tnone[hidden]{ display:none; }
  .techlist .tnone{ font-size:.84rem; color:var(--muted-2); padding:4px 0; }
  .techlist .tlatersum{ font-size:.8rem; color:var(--muted); border:1px dashed var(--border); border-radius:10px; padding:8px 11px; line-height:1.35; }
  .techlist .tlatersum[hidden]{ display:none; }
  .techrow .name{ font-family:"IBM Plex Sans"; font-size:.9rem; font-weight:600; line-height:1.25; }
  .techrow .desc{ font-family:"IBM Plex Mono"; font-size:.74rem; color:var(--muted); }
  .techrow .icon{ border:1px solid var(--border); }
  .techrow.cat-compute .icon{ color:var(--compute); border-color:var(--compute-dim); }
  .techrow.cat-energy .icon{ color:var(--energy); border-color:var(--energy-dim); }
  .techrow.cat-research .icon{ color:var(--research); border-color:var(--research-dim); }
  .techrow.cat-data .icon{ color:var(--data); border-color:var(--data-dim); }
  .techrow.cat-risk .icon{ color:var(--risk); border-color:var(--risk-dim); }
  .techrow.g-now{ border-color:var(--compute-dim); }
  .techrow.g-later{ opacity:.7; }
  .techrow .tprog{ display:flex; align-items:center; gap:6px; margin-top:4px; font-size:.72rem; color:var(--muted-2); }
  .techrow .tprog[hidden]{ display:none; }
  .techrow .tprog .bar{ flex:1; height:4px; border-radius:2px; background:var(--surface-3); overflow:hidden; }
  .techrow .tprog .bar > div{ height:100%; background:var(--research); border-radius:2px; }

  /* ---------- Construir, ajustes de la revisión (2026-10-02) ----------
     El usuario deja la pantalla como está y toma de la dirección A: botón de compra de una línea
     con el coste, filas de 56 px con el nombre sin partir, la ciudad a 104 px con el recuento, la
     energía en una barra bajo ella y el selector ×1/×10/máx como control segmentado. */
  #buildHero{ height:104px; }
  #buildHero .cap{ top:8px; }
  #buildHero .cap > span{ display:none; }
  #buildHero .cap b{ font-size:.84rem; margin-top:0; }
  /* selector de cantidad: un solo control segmentado */
  .qty{ gap:0; border:1px solid var(--border); border-radius:8px; overflow:hidden; }
  .qty button{ border:0; border-left:1px solid var(--border); border-radius:0; background:none; padding:5px 10px; }
  .qty button:first-child{ border-left:0; }
  .qty button.active{ background:color-mix(in srgb, var(--compute) 12%, transparent); }
  /* filas de una línea */
  #buildings .row{ padding:7px 10px; min-height:56px; }
  #buildings .row .icon{ width:34px; height:34px; }
  #buildings .row{ gap:8px; }
  #buildings .row .name{ font-family:"IBM Plex Sans"; font-size:.88rem; gap:4px; white-space:nowrap; min-width:0; }
  #buildings .row .name .sellmini{ width:18px; height:18px; flex:none; }
  #buildings .row .chev{ margin-right:2px; }
  #buildings .row .name .nm{ min-width:0; overflow:hidden; text-overflow:ellipsis; }
  #buildings .row .name .cnt{ flex:none; }
  #buildings .row .line{ flex-wrap:nowrap; white-space:nowrap; overflow:hidden; margin-top:2px; font-size:.74rem; }
  #buildings .row.open .line{ flex-wrap:wrap; white-space:normal; }
  /* botón de compra: una línea con el coste, teñido cuando se puede pagar */
  #buildings .row button[data-f=buy]{ display:flex; align-items:center; justify-content:center; gap:6px; min-width:70px; padding:8px 9px; border-color:var(--compute-dim); background:color-mix(in srgb, var(--compute) 7%, var(--surface)); }
  #buildings .row button[data-f=buy]:disabled{ border-color:var(--border); background:var(--surface-2); }
  #buildings .row button[data-f=buy] .c{ display:inline-flex; align-items:center; gap:3px; }
  #buildings .row button[data-f=buy] .q{ font-size:.72rem; font-weight:400; color:var(--muted); }
  #buildings .row button[data-f=buy] .q:empty{ display:none; }
  #buildings .row button[data-f=buy]:has(.c.research){ border-color:var(--research-dim); background:color-mix(in srgb, var(--research) 7%, var(--surface)); }
  /* cantidad en el botón del extractor de colonia */
  .xbuy .xq{ font-family:"IBM Plex Mono"; font-size:.72rem; color:var(--muted); margin-left:4px; }

  /* ---------- Red, dirección A (2026-10-02) ----------
     Mapa más bajo, el aviso de lo que falta justo debajo, las tres acciones de flota en una sola
     tarjeta con sus costes a la vista, las colonias en dos líneas y los materiales raros en una
     tira fina (en su color solo cuando tienes existencias). */
  .netmap #netMapCv{ height:176px; }
  @media (max-height: 700px){ .netmap #netMapCv{ height:160px; } }
  .netsum{ display:none; }
  #netContent > .nextline{ margin:8px 0 0; }
  .fleetcard{ background:var(--surface); border:1px solid var(--border); border-radius:12px; margin-top:8px; overflow:hidden; }
  .fleetcard .shiprow{ background:none; border:0; border-radius:0; border-top:1px solid var(--border); padding:9px 11px; }
  .fleetcard .shiprow:first-child, .fleetcard .shiprow[hidden] + .shiprow:not([hidden]):first-of-type{ border-top:0; }
  .fleetcard .shiprow[hidden]{ display:none; }
  .fleetcard .shiprow .info{ min-width:0; flex:1; }
  .fleetcard .shiprow .icon{ width:34px; height:34px; }
  .shiprow .own .need{ display:flex; align-items:center; flex-wrap:wrap; gap:4px 8px; margin-top:3px; font-family:"IBM Plex Mono"; font-size:.76rem; }
  .shiprow .own .need .k{ color:var(--muted-2); letter-spacing:.06em; text-transform:uppercase; font-size:.68rem; }
  .shiprow .own .need .c{ display:inline-flex; align-items:center; gap:3px; margin:0; font-weight:600; }
  .shiprow .own .need .c.compute{ color:var(--compute); } .shiprow .own .need .c.energy{ color:var(--energy); } .shiprow .own .need .c.research{ color:var(--research); } .shiprow .own .need .c.data{ color:var(--data); }
  .shiprow .own .need .c.no{ color:var(--risk); }
  .shiprow .own .need .c .ri{ width:12px; height:12px; }
  .shiprow .own .need .tm{ color:var(--muted); }
  .shiprow .own .cols{ display:block; margin-top:2px; font-family:"IBM Plex Mono"; font-size:.72rem; color:var(--muted-2); }
  /* colonias: nombre y "Entrar" arriba; debajo, almacén, extracción y próxima salida en una línea */
  .colc{ padding:9px 11px 9px 13px; border-radius:11px; }
  .colc .cs{ display:flex; align-items:center; gap:10px; margin-top:3px; }
  .colc .cell{ background:none; border:0; padding:0; flex-direction:row; align-items:baseline; gap:4px; }
  .colc .cell small{ font-size:.72rem; color:var(--muted-2); }
  .colc .cell:first-child small{ display:none; }
  .colc .cell b{ font-size:.8rem; }
  .colc .cell b.mt .matc i{ display:inline; font-style:normal; }
  .colc .cell .ce{ gap:5px; }
  .colc .cbar{ height:3px; margin-top:5px; }
  .colc .hint{ margin-top:3px; }
  /* materiales raros: una tira fina; en su color solo si tienes */
  .mats{ gap:5px; }
  .mat{ flex:1 1 auto; flex-direction:row; align-items:center; justify-content:space-between; gap:6px; padding:3px 7px; }
  .mat .mn svg{ display:none; }
  .mat .mn{ flex:none; }
  .mat .mn span{ overflow:visible; }
  .mat:not(.has) b{ display:none; } /* sin existencias: solo el nombre, en gris */
  .mat .mv{ flex-wrap:nowrap; white-space:nowrap; }
  .mat .mn{ color:var(--muted-2); letter-spacing:.02em; font-size:.72rem; }
  .mat .mn svg{ animation:none; opacity:.6; }
  .mat b{ color:var(--muted-2); font-size:.78rem; }
  .mat .mv{ gap:3px; }
  .mat .mv span{ font-size:.68rem; }
  .mat.zero{ opacity:.7; }
  .mat.has{ border-color:color-mix(in srgb, var(--mc) 45%, var(--border)); }
  .mat.has .mn, .mat.has b{ color:var(--mc); }
  .mat.has .mn svg{ opacity:1; }
  /* la ficha con existencias no encoge; las que están a cero ceden sitio y recortan el nombre */
  .mat.has{ flex:0 0 auto; }
  .mat:not(.has){ min-width:0; }
  .mat:not(.has) .mn{ flex:1 1 auto; min-width:0; }
  .mat:not(.has) .mn span{ overflow:hidden; text-overflow:ellipsis; }

  /* ---------- El núcleo no se mueve de sitio (2026-10-02) ----------
     Feedback de un probador: tocando a toda velocidad, un aviso salía encima y bajaba el núcleo
     60 px; los toques dejaban de caer en él. Reglas:
       - Los avisos que van y vienen (contrato, energía, bombilla) viven en .dock, sobre las pestañas.
       - En el Núcleo, lo que cambia de alto (apertura, guía) va debajo del núcleo.
       - Los marcadores y el riesgo reservan su sitio desde el principio: nacen "en su hueco".
       - La tarjeta del objetivo tiene alto fijo: que desaparezca una ficha no la encoge.
       - El rótulo de estado del núcleo flota sobre el arte en vez de ocupar una fila. */
  .dock{ flex:none; display:flex; flex-direction:column; }
  .dock > :not([hidden]):last-child{ margin-bottom:6px; }
  .dock #energyNoteCore{ padding:6px 16px 0; }
  .meters .meter.unborn{ display:flex !important; visibility:hidden; }
  .riskrow.unborn{ display:flex !important; visibility:hidden; }
  #coreBox .readout{ position:absolute; top:9px; left:50%; transform:translateX(-50%); z-index:2; max-width:calc(100% - 24px); }
  /* pie del núcleo: tercera línea */
  /* la apertura señala el marcador del que habla */
  .meters .meter.point{ border-color:var(--compute); animation:meterPoint 1.1s ease-in-out infinite; z-index:1; }
  @keyframes meterPoint{ 0%,100%{ box-shadow:0 0 0 0 rgba(82,224,196,0); } 50%{ box-shadow:0 0 0 5px rgba(82,224,196,.38); } }
  @media (prefers-reduced-motion: reduce){ .meters .meter.point{ animation:none; box-shadow:0 0 0 3px rgba(82,224,196,.38); } }
  /* el "+N" grande flota sobre el arte: sin esto heredaba position:relative de ".corebox > *" y dejaba
     un hueco de 50 px bajo el pie del núcleo */
  #coreBox .tapbig{ position:absolute; }
  /* el pie del núcleo reserva su sitio antes de nacer, para que la caja no crezca con el primer toque */
  .corefoot.unborn{ display:flex !important; visibility:hidden; }
  /* Hueco fijo sobre el núcleo: mide siempre lo mismo. Dentro, la voz de la apertura, el paso de la
     guía o el siguiente Modelo; lo que no cabe se recorta, nunca empuja. El núcleo tampoco cambia
     de tamaño (antes encogía 56 px cuando la tarjeta crecía). */
  .coreslot{ flex:none; height:112px; display:flex; flex-direction:column; }
  .coreslot > *{ flex:1 1 auto; min-height:0; overflow:hidden; }
  #tab-core .coreslot .goal{ margin:0; justify-content:center; gap:6px; }
  .coreslot .goal .gchips{ max-height:48px; overflow:hidden; }
  .coreslot .goal .gchips.one{ flex-wrap:nowrap; }
  .coreslot .goal > *{ flex:none; }
  .coreslot .goal .gl > span:first-child{ white-space:nowrap; overflow:hidden; text-overflow:ellipsis; min-width:0; }
  .coreslot .goal .gtip{ white-space:nowrap; overflow:hidden; text-overflow:ellipsis; min-width:0; }
  .coreslot .goal .gc{ white-space:nowrap; flex:none; }
  .coreslot .goal .gc.mat{ flex:0 1 auto; min-width:0; overflow:hidden; text-overflow:ellipsis; display:block; }
  .coreslot .goal .gmat{ justify-content:flex-start; gap:4px; }
  .coreslot .goal .gmat > span:not(.gc){ flex:1 1 0; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; min-width:0; padding-left:3px; }
  .coreslot .goal .gmat .btn-s{ margin-left:auto; }
  .coreslot .goal .gtxt{ text-align:center; }
  /* la voz del núcleo en la apertura */
  .coreslot .introsay{ background:var(--surface); border:1px solid var(--compute-dim); border-radius:12px; padding:7px 12px; font-size:.9rem; line-height:1.36; color:var(--text); animation:calloutIn .5s ease-out 1; }
  @media (max-width: 359px){ .coreslot .introsay{ font-size:.84rem; } }
  .coreslot .introsay .who{ display:flex; justify-content:space-between; gap:8px; font-family:"IBM Plex Mono"; font-size:.72rem; letter-spacing:.06em; text-transform:uppercase; color:var(--compute); margin-bottom:2px; }
  .coreslot .introsay .cur{ display:inline-block; width:7px; height:.95em; background:var(--compute); vertical-align:-2px; margin-left:2px; animation:introBlink 1s steps(2) infinite; }
  @media (prefers-reduced-motion: reduce){ .coreslot .introsay, .coreslot .introsay .cur{ animation:none; } }
  /* las respuestas, bajo el núcleo: sin caja, solo los botones y una fila con el paso y "Saltar" */
  #tab-core .intropanel{ margin:0; padding:0; border:0; background:none; gap:6px; }
  #tab-core .intropanel .opts .opt{ padding-block:9px; }
  #tab-core .intropanel .introtap{ padding:10px 0; }
  /* guía de primeros pasos: título, barra y explicación van juntos en el hueco de arriba */
  #tab-core #coreGuide{ display:none !important; }
  .coreslot .goal .gdesc{ font-size:.82rem; line-height:1.32; color:var(--text); display:-webkit-box; -webkit-line-clamp:3; -webkit-box-orient:vertical; overflow:hidden; }
  /* el marco de la guía se enciende sin desplazarse (calloutIn lo movía 6 px, y con él el núcleo) */
  #coreBox.guide-armed{ animation:none; }
  /* durante la apertura la frase ya está escrita arriba: la línea de voz de abajo sería repetirla */
  body.intro-on #voiceLine{ display:none !important; }

  /* ---------- Prueba en móvil (2026-10-02) ---------- */
  /* pie del núcleo en dos filas: valor del toque y ritmo; barra y cuánto falta */
  .corefoot .cf-mid{ display:flex; align-items:center; gap:8px; }
  .corefoot .cf-mid .rt{ flex:1; }
  .corefoot #clickPct{ font-family:"IBM Plex Mono"; font-size:.7rem; color:var(--muted-2); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
  .corefoot #clickPct:empty{ display:none; }
  /* apertura: "Saltar" en la cabecera; el paso, en la esquina de la frase; respuestas lado a lado */
  .introskip{ padding:5px 11px; font-size:.75rem; color:var(--muted); }
  .introskip[hidden]{ display:none; }
  .coreslot .introsay .who .step{ color:var(--muted); text-transform:none; letter-spacing:0; }
  #tab-core .intropanel .opts{ flex-direction:row; }
  #tab-core .intropanel .opts .opt{ flex:1 1 0; min-width:0; padding-inline:9px; justify-content:center; }
  #tab-core .intropanel .opts .opt .ol{ font-size:.84rem; }
  /* el rótulo "toca el núcleo" solo se ve en la apertura cuando de verdad se pide tocar */
  body.intro-on #coreBox:not(.ask) .readout{ visibility:hidden; }
  /* "toca el núcleo": el núcleo late (halo y anillo) para que se vea qué hay que tocar */
  #coreBox.ask .corewrap::before, body:not(.intro-on) #coreBox.tapme .corewrap::before{ content:""; position:absolute; inset:6%; border-radius:50%; pointer-events:none; z-index:2;
    background:radial-gradient(circle, rgba(82,224,196,.42) 0, rgba(82,224,196,.16) 45%, rgba(82,224,196,0) 68%); animation:tapGlow 1.3s ease-in-out infinite; }
  #coreBox.ask .corewrap::after, body:not(.intro-on) #coreBox.tapme .corewrap::after{ content:""; position:absolute; inset:10%; border-radius:50%; pointer-events:none; z-index:2;
    border:2px solid rgba(82,224,196,.95); animation:tapRing 1.3s ease-out infinite; }
  @keyframes tapGlow{ 0%,100%{ opacity:.15; } 50%{ opacity:1; } }
  @keyframes tapRing{ from{ transform:scale(.55); opacity:1; } to{ transform:scale(1.2); opacity:0; } }
  @media (prefers-reduced-motion: reduce){
    #coreBox.ask .corewrap::before, #coreBox.tapme .corewrap::before{ animation:none; opacity:.7; }
    #coreBox.ask .corewrap::after, #coreBox.tapme .corewrap::after{ animation:none; opacity:.8; transform:none; }
  }
  /* guía de Construir: botón que lleva a la fila */
  #buildGuideGo{ margin-top:8px; }
  #buildGuideGo[hidden]{ display:none; }
  /* objetivo: etiqueta "faltan" antes de las fichas */
  .goal .gfl{ font-size:.74rem; color:var(--muted); align-self:center; margin-right:2px; }
  /* Investigar: el precio del Modelo. "siguiente modelo" es un rótulo gris encima del nombre (antes,
     una palabra morada a la derecha que parecía un botón) */
  .modelcard .mn{ flex-direction:column-reverse; align-items:flex-start; gap:1px; }
  .modelcard .mn .lvl{ color:var(--muted-2); font-size:.7rem; letter-spacing:.1em; text-transform:uppercase; font-weight:500; }
  .modelcard.done .mn .lvl{ color:var(--compute); }
  .modelcard .mhead{ display:flex; justify-content:space-between; font-family:"IBM Plex Mono"; font-size:.7rem; letter-spacing:.1em; text-transform:uppercase; color:var(--muted-2); margin:2px 0 4px; }
  .modelcard .mrow{ font-size:.8rem; }
  .modelcard .mrow .k{ width:auto; min-width:118px; display:inline-flex; align-items:center; gap:4px; font-weight:600; overflow:visible; }
  .modelcard .mrow .k .ri{ width:13px; height:13px; margin:0; }
  .modelcard .mrow .v{ width:auto; min-width:52px; color:var(--text); }
  .modelcard .mneed{ font-size:.84rem; color:var(--text); line-height:1.4; margin-top:6px; }
  .modelcard .mtime{ margin-top:2px; }
  /* Investigar sin Laboratorio: en vez de la lista, de dónde sale la investigación */
  .techlist .tnolab{ order:0; font-size:.86rem; line-height:1.4; color:var(--text); background:var(--surface); border:1px solid var(--research-dim); border-radius:10px; padding:10px 12px; }
  .techlist .tnolab[hidden]{ display:none; }

  /* ---------- Dilema, dirección A (2026-10-02) ----------
     Misma ventana, más oficio: cabecera con el rótulo de pausa, opciones con punto de selección y la
     desviación junto al nombre, consecuencias como fichas en el color de su recurso, el riesgo como
     barra con el tramo que cambia rayado, y un botón que dice qué confirma. Sin flechas. */
  #eventCard{ gap:10px; }
  #eventCard .dhead{ display:flex; justify-content:space-between; align-items:center; gap:8px; }
  #eventCard .dpause{ display:inline-flex; align-items:center; gap:6px; font-family:"IBM Plex Mono"; font-size:.75rem; letter-spacing:.06em; text-transform:uppercase; color:var(--muted); white-space:nowrap; }
  #eventCard .dpause i{ width:7px; height:9px; border-left:2.5px solid currentColor; border-right:2.5px solid currentColor; display:block; box-sizing:border-box; }
  #eventCard .opt[data-opt]{ gap:8px; padding:10px 12px; }
  #eventCard .oh{ display:flex; align-items:flex-start; gap:9px; }
  #eventCard .oh .rd{ width:16px; height:16px; border-radius:50%; border:1.5px solid var(--muted-2); flex:none; display:block; box-sizing:border-box; margin-top:2px; }
  #eventCard .ohc{ flex:1; min-width:0; display:flex; flex-wrap:wrap; align-items:center; gap:4px 9px; }
  #eventCard .ohc .ol{ flex:1 1 auto; min-width:0; font-size:.95rem; }
  #eventCard .ohc .driftchip{ align-self:center; margin:0; flex:none; letter-spacing:0; }
  #eventCard.dstack .ohc .ol{ flex-basis:100%; }
  #eventCard .opt.sel .rd{ border-color:var(--compute); background:radial-gradient(circle, var(--compute) 0 4px, transparent 5px); }
  .dfx{ display:flex; flex-wrap:wrap; align-items:center; gap:5px 8px; }
  .dfxp{ display:inline-flex; align-items:center; flex-wrap:wrap; gap:3px 7px; min-width:0; }
  .dfxp small{ font-family:"IBM Plex Mono"; font-size:.75rem; color:var(--muted); }
  .dchip{ font-family:"IBM Plex Mono"; font-size:.75rem; line-height:1.2; padding:4px 8px; border-radius:7px; border:1px solid var(--border); display:inline-flex; align-items:center; gap:5px; white-space:nowrap; text-align:left; }
  .dchip .ri{ width:12px; height:12px; margin:0; flex:none; }
  .dchip.gain, .dchip.compute{ color:var(--compute); border-color:var(--compute-dim); background:color-mix(in srgb, var(--compute) 8%, transparent); }
  .dchip.research{ color:var(--research); border-color:var(--research-dim); background:color-mix(in srgb, var(--research) 9%, transparent); }
  .dchip.data{ color:var(--data); border-color:var(--data-dim); background:color-mix(in srgb, var(--data) 9%, transparent); }
  .dchip.energy{ color:var(--energy); border-color:var(--energy-dim); background:color-mix(in srgb, var(--energy) 8%, transparent); }
  .dchip.loss{ color:var(--risk); border-color:var(--risk-dim); background:color-mix(in srgb, var(--risk) 8%, transparent); }
  .dfx .fxnone{ font-family:"IBM Plex Mono"; font-size:.75rem; color:var(--muted); }
  .drisk{ display:flex; align-items:center; gap:8px; font-family:"IBM Plex Mono"; font-size:.75rem; color:var(--muted); }
  .drisk .rb{ flex:1; min-width:40px; height:6px; border-radius:3px; background:var(--surface-3); position:relative; overflow:hidden; }
  .drisk .rb i{ position:absolute; left:0; top:0; bottom:0; background:linear-gradient(90deg, var(--energy), var(--risk)); border-radius:3px; }
  .drisk .rb u{ position:absolute; top:0; bottom:0; text-decoration:none; }
  .drisk .rb u.up{ background:repeating-linear-gradient(45deg, var(--risk) 0 3px, transparent 3px 6px); }
  .drisk .rb u.dn{ background:repeating-linear-gradient(45deg, var(--compute) 0 3px, var(--bg) 3px 6px); }
  .drisk b{ font-weight:500; white-space:nowrap; color:var(--text); }
  .drisk b.up{ color:var(--risk); } .drisk b.dn{ color:var(--compute); }
  #eventCard .fxg{ gap:6px; padding:7px 9px; }
  #eventCard .fxg .drisk .rb{ background:var(--bg); }
  #eventCard .dchose{ display:flex; flex-direction:column; gap:1px; }
  #eventCard .dchose b{ font-size:1rem; font-weight:600; }
  #eventCard .dgamble{ font-family:"IBM Plex Mono"; font-size:.8rem; }
  #eventCard .dgamble.pos{ color:var(--compute); } #eventCard .dgamble.neg{ color:var(--risk); }
  #eventCard .opt.dok{ align-items:center; text-align:center; padding-block:12px; }
  /* Confirmar siempre a la vista: si la tarjeta no cabe (pantallas bajas, apuestas), se desplaza lo
     de arriba y el botón se queda pegado abajo */
  #eventCard .confirm-row{ position:sticky; bottom:0; z-index:1; background:var(--surface); padding-bottom:12px; margin-bottom:-12px; box-shadow:0 -12px 12px -8px var(--surface); }
  @media (max-height: 700px){
    #eventCard{ padding:14px; gap:8px; }
    #eventCard p{ font-size:.86rem; line-height:1.4; }
    #eventCard .opt[data-opt]{ padding:8px 10px; gap:6px; }
    #eventCard .opt.confirm{ padding-block:8px; }
  }

  /* ---------- Núcleo: voz de paso y contrato a la vista (2026-10-02) ----------
     Ninguno de los dos ocupa sitio propio (el núcleo no se mueve ni encoge):
       - la frase del núcleo sale SOBRE el objetivo, en el hueco fijo, 5-10 s, con × para quitarla
       - el contrato en curso es una franja sobre el arte, arriba de la caja del núcleo */
  .coreslot{ position:relative; }
  .coreslot .voiceline{ position:absolute; inset:0; z-index:3; margin:0; padding:8px 4px 8px 12px; background:var(--surface); color:var(--text); font-size:.86rem; line-height:1.36; cursor:pointer; }
  .coreslot .voiceline span{ -webkit-line-clamp:4; flex:1; }
  .voiceline .vx{ appearance:none; flex:none; align-self:flex-start; width:32px; height:32px; border:0; background:none; color:var(--muted); font-size:1.2rem; line-height:1; border-radius:8px; cursor:pointer; font-family:inherit; }
  .voiceline .vx:active{ background:var(--surface-2); }
  #coreBox .ccore{ position:absolute; left:10px; right:10px; top:9px; z-index:2; pointer-events:none; padding:5px 10px 6px; border-radius:9px; border:1px solid var(--research-dim); background:rgba(7,10,12,.78); backdrop-filter:blur(3px); display:flex; flex-direction:column; gap:4px; }
  .ccore[hidden]{ display:none; }
  .ccore .l{ display:flex; align-items:baseline; gap:8px; font-size:.8rem; min-width:0; }
  .ccore .l b{ font-family:"IBM Plex Mono"; font-size:.75rem; letter-spacing:.06em; text-transform:uppercase; color:var(--research); flex:none; }
  .ccore .l span{ white-space:nowrap; overflow:hidden; text-overflow:ellipsis; min-width:0; }
  .ccore .l .p{ margin-left:auto; color:var(--muted); font-size:.76rem; flex:none; }
  .ccore .bar{ height:4px; border-radius:2px; background:var(--surface-3); overflow:hidden; }
  /* con contrato, el rótulo de estado del núcleo baja para no pisarlo */
  #coreBox:has(.ccore:not([hidden])) .readout{ top:50px; }

  /* ---------- Materiales raros: cuatro casillas de dos líneas (2026-10-02) ----------
     "Criogel 3,00K llegan 300" en una línea no cabía con cuatro materiales. Ahora: nombre arriba,
     cifra abajo; un punto junto al nombre si hay convoy en camino y, si cabe, "+300" tras la cifra. */
  .mats{ display:grid; grid-template-columns:repeat(4, minmax(0, 1fr)); gap:5px; }
  .mats[hidden]{ display:none; }
  .mat, .mat.has, .mat:not(.has){ flex:none; min-width:0; flex-direction:column; align-items:stretch; justify-content:flex-start; gap:0; padding:3px 7px 4px; }
  .mat .mn{ flex:none; display:flex; align-items:center; justify-content:space-between; gap:4px; font-size:.75rem; letter-spacing:0; }
  .mat .mn span, .mat:not(.has) .mn span{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; min-width:0; }
  .mat .mn::after{ content:""; flex:none; width:6px; height:6px; border-radius:50%; background:var(--mc); opacity:0; }
  .mat.way .mn::after{ opacity:1; animation:matWay 1.4s ease-in-out infinite; }
  @keyframes matWay{ 0%,100%{ opacity:.35; } 50%{ opacity:1; } }
  @media (prefers-reduced-motion: reduce){ .mat.way .mn::after{ animation:none; } }
  .mat .mv{ display:flex; flex-wrap:wrap; align-items:baseline; column-gap:5px; row-gap:8px; height:1.25em; overflow:hidden; line-height:1.25; font-size:.82rem; }
  .mat b, .mat:not(.has) b{ display:inline; font-size:.82rem; flex:none; }
  .mat .mv span{ font-size:.75rem; flex:none; opacity:1; color:var(--mc); }
  /* con la fila de materiales a la vista, el núcleo cede su alto para que quepa lo de debajo */
  body.has-mats{ --core:clamp(170px, calc(100vh - 522px), min(320px, calc(100vw - 56px))); }
  @supports (height:100dvh){ body.has-mats{ --core:clamp(170px, calc(100dvh - 522px), min(320px, calc(100vw - 56px))); } }

