/* ============================================================================
   Core Academy · sistema visual compartido  (dirección "Night Desk")
   ----------------------------------------------------------------------------
   Un solo lugar para colores, tipografía y componentes. Antes cada pantalla
   tenía su propia copia: cambiar un color obligaba a tocar 5 archivos.
   Cada pantalla agrega SOLO lo que es exclusivamente suyo.
   ========================================================================== */

:root{
  /* fondos */
  --void:#06070A; --panel:#0E0D12; --panel-2:#131218;
  /* identidad · AZUL METÁLICO (Fernando, 2026-08-26: "no quiero nada pero nada
     de dorado"). Los NOMBRES de las variables siguen diciendo `gold` a
     propósito: renombrarlas obligaba a tocar ~1.000 usos en 38 archivos, y cada
     uno es una oportunidad de romper algo. El nombre es la etiqueta del frasco;
     lo que importa es el color que hay adentro. */
  --gold:#5AA9D6; --gold-hi:#CFE7F5; --gold-deep:#356F94;
  /* mercado: ACENTO = alcista, PIZARRA = bajista. Antes era "oro vs acero", pero
     el acero ya era azul (#5B8AA8): al pasar el acento a azul, subir y bajar
     quedaban del mismo color y las velas se volvían ilegibles. Por eso bajista
     se mudó a un gris neutro. Se mantiene la idea original: deliberadamente NO
     el verde/rojo genérico de bróker. */
  --steel:#7E8794;
  /* estado del sistema (distinto de mercado: esto es ok/alerta/error) */
  --mint:#4FD8A0; --amber:#E8A33D; --rose:#E8556D;
  /* texto · NEUTROS FRÍOS (2026-08-26). Antes tenían sesgo cálido a propósito,
     para acompañar al oro. Con el acento en azul ese mismo sesgo se lee sucio:
     un blanco amarillento al lado de un azul metálico ensucia los dos. Ahora
     sesgan al frío, que es lo que hace que el conjunto se vea de una pieza. */
  --ink:#EDF1F5; --ash:#8B939C; --dim:#585F67;
  /* líneas */
  --line:rgba(255,255,255,.07); --line-2:rgba(255,255,255,.13);
  /* tipografía */
  --mono:ui-monospace,"SF Mono","JetBrains Mono","Cascadia Code",Menlo,monospace;
  --sans:-apple-system,BlinkMacSystemFont,"Segoe UI",Inter,sans-serif;
  /* espacio reservado para los controles flotantes de Telegram (lo setea log.js) */
  --safe-top:0px; --safe-right:0px;
}

*{box-sizing:border-box;margin:0;padding:0}
/* Anti-desborde horizontal (patrón mobile-first de Core Impulsa, Fernando
   2026-08-05: "que nunca se salga del ancho"). overflow-x:hidden SOLO en body
   NO alcanza -- el que scrollea de lado es <html>: por eso a 320px la app
   paneaba igual. `overflow-x:clip` en html corta el desborde SIN crear un
   contenedor de scroll (a diferencia de :hidden), así no rompe position:sticky.
   Es la red de seguridad; igual se arregla cada driver para que el contenido
   ENTRE, no solo se recorte. */
html{overflow-x:clip}
html,body{background:var(--void);max-width:100%}
body{
  font-family:var(--sans);color:var(--ink);
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;position:relative;
}
/* Medios nunca fuerzan ancho de más. */
img,svg,canvas,video{max-width:100%}
/* Que se sienta una app, no una página: nada de seleccionar texto ni el menú
   nativo (Copiar/Buscar) al tocar y mantener presionado -- eso es lo que
   Fernando veía como un "/" apareciendo por todos lados (2026-07-26). Los
   campos donde SÍ hay que poder escribir/pegar quedan exceptuados abajo. */
*{-webkit-user-select:none;user-select:none;-webkit-touch-callout:none}
input,textarea,[contenteditable]{-webkit-user-select:text;user-select:text;-webkit-touch-callout:default}
button,input,textarea,select{font-family:inherit}
button{background:none;border:none;cursor:pointer;color:inherit}
a{color:inherit;text-decoration:none}

/* Todo número que se lea como dato va en tabular: las columnas no bailan */
.num{font-family:var(--mono);font-variant-numeric:tabular-nums}

/* ---------- contenedor: de desktop para arriba EXPANDE (regla Core) ---------- */
.wrap{position:relative;z-index:2;max-width:1200px;margin:0 auto;padding:0 clamp(16px,4vw,30px)}
@media(min-width:1440px){.wrap{max-width:1340px}}
@media(min-width:1601px){.wrap{max-width:1520px;padding:0 clamp(30px,4vw,56px)}}

/* ---------- fondo: grilla + barrido ---------- */
canvas#bg{position:fixed;inset:0;z-index:0;pointer-events:none;opacity:.6}

/* ---------- card con luz que sigue el cursor + esquinas HUD ---------- */
.card{
  position:relative;background:var(--panel);
  border:1px solid var(--line);border-radius:16px;
  transition:border-color .3s;
  overflow:hidden;   /* el halo del cursor nunca se escapa de su tarjeta */
}
.card:hover{border-color:var(--line-2)}
.card>.glow{
  position:absolute;inset:0;opacity:0;transition:opacity .35s;pointer-events:none;border-radius:inherit;
  background:radial-gradient(340px circle at var(--mx,50%) var(--my,50%),rgba(90,169,214,.07),transparent 62%);
}
.card:hover>.glow{opacity:1}
.card>.brk{position:absolute;width:13px;height:13px;border:1.5px solid rgba(90,169,214,.42);pointer-events:none;z-index:2}
.card>.brk.tl{top:9px;left:9px;border-right:0;border-bottom:0;border-radius:4px 0 0 0}
.card>.brk.br{bottom:9px;right:9px;border-left:0;border-top:0;border-radius:0 0 4px 0}

/* ---------- etiqueta superior ---------- */
/* ⚠️ MÓVIL PRIMERO: ESTA PÍLDORA ROMPÍA EL ANCHO DEL TELÉFONO (2026-08-25).
   `inline-flex` sin `flex-wrap` NO deja envolver su contenido, así que su ancho
   mínimo es la frase entera en una sola línea. Con un texto largo —"Cohorte 1 ·
   abre el 4 de septiembre"— medía 347px, y como es hija de una grilla con
   `min-width:auto`, empujaba la columna entera: a 320px la portada se salía 58px
   y el teléfono paneaba de lado.
   Se arregla en los dos frentes: `flex-wrap` para que pueda caer a dos líneas, y
   `max-width:100%` para que jamás pase del ancho de su padre. Va acá, en el CSS
   compartido, porque la píldora la usan varias pantallas y el bug era de todas.
   `line-height` sube de 1 a 1.35: con dos líneas, a 1 se tocaban. */
.eyebrow{
  display:inline-flex;align-items:center;gap:8px;flex-wrap:wrap;max-width:100%;
  font:600 10px/1.35 var(--mono);letter-spacing:.14em;text-transform:uppercase;
  color:#8FBBD4;background:rgba(90,169,214,.07);
  border:1px solid rgba(90,169,214,.18);border-radius:999px;padding:7px 13px;
}
.pulse{width:6px;height:6px;background:var(--mint);border-radius:50%;
  box-shadow:0 0 0 0 rgba(79,216,160,.55);animation:pulse 2.4s infinite;flex:none}
@keyframes pulse{
  0%{box-shadow:0 0 0 0 rgba(79,216,160,.5)}
  70%{box-shadow:0 0 0 7px rgba(79,216,160,0)}
  100%{box-shadow:0 0 0 0 rgba(79,216,160,0)}
}

/* ---------- botones ---------- */
.btn{
  font:600 12px/1 var(--sans);padding:12px 21px;border-radius:11px;cursor:pointer;
  white-space:nowrap;border:1px solid transparent;transition:.25s;
  display:inline-flex;align-items:center;gap:7px;
}
.btn.ghost{border-color:var(--line-2);color:#D2D7DD;background:rgba(255,255,255,.02)}
.btn.ghost:hover{background:rgba(255,255,255,.05);border-color:rgba(255,255,255,.2)}
.btn.gold{background:linear-gradient(180deg,var(--gold-hi),#3D8FC4);color:#071119;
  box-shadow:0 10px 26px -12px rgba(61,143,196,.6)}
.btn.gold:hover{transform:translateY(-1px);box-shadow:0 14px 32px -12px rgba(61,143,196,.75)}
.btn:disabled{opacity:.55;cursor:default;transform:none!important}

/* ---------- cabecera común ---------- */
.nav{display:flex;align-items:center;justify-content:space-between;gap:14px;flex-wrap:wrap;
  padding-top:calc(18px + var(--safe-top))}
.brand{display:flex;align-items:center;gap:11px}
.sigil{width:36px;height:36px;border-radius:10px;flex:none;
  background-image:url("assets/logo-core-academy-256.png");background-size:cover;background-position:center}
.brand b{font:600 14.5px/1 var(--mono);letter-spacing:-.01em;color:var(--ink)}
.nav-r{display:flex;align-items:center;gap:11px}

/* selector de idioma (trilingüe: regla no negociable) */
.lang{display:flex;gap:1px;font:600 10px/1 var(--mono)}
.lang button{padding:6px 8px;border-radius:6px;color:var(--dim);transition:.2s}
.lang button:hover{color:var(--ash)}
.lang button.on{color:var(--gold-hi);background:rgba(90,169,214,.1)}

/* En móvil el header se compacta: 5 elementos no entran en 375px */
@media(max-width:560px){
  .nav{gap:9px}
  .brand b{display:none}          /* queda solo el sigilo */
  .lang button{padding:5px 4px}
}

/* ---------- pie común ---------- */
.mini-foot{margin-top:52px;text-align:center;padding:28px 0 34px;border-top:1px solid var(--line)}
.mini-foot .lines{display:flex;justify-content:center;gap:20px;flex-wrap:wrap;
  font:600 10.5px/1 var(--mono);color:var(--ash);margin-bottom:13px}
.mini-foot .lines a{cursor:pointer;transition:.2s}
.mini-foot .lines a:hover{color:var(--gold)}
.mini-foot p{font-size:10px;color:var(--dim);max-width:400px;margin:0 auto;line-height:1.65}

/* ---------- entrada escalonada ---------- */
.rise{opacity:0;transform:translateY(14px);
  transition:opacity .7s cubic-bezier(.2,.7,.2,1),transform .7s cubic-bezier(.2,.7,.2,1)}
.rise.in{opacity:1;transform:none}

/* ---------- accesibilidad ---------- */
:focus-visible{outline:2px solid var(--gold);outline-offset:2px;border-radius:4px}
@media(prefers-reduced-motion:reduce){
  *{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}
  .rise{opacity:1;transform:none}
}

/* ═══ LA ENTRADA — el briefing de 3 pasos ══════════════════════════════════
   La auditoría del 09-ago encontró la raíz de que las actividades se sintieran
   secas: el alumno entra a practicar algo que nadie le explicó. Esta pieza es
   la que lo arregla, y vive acá —en el chasis— para que las 20 la hereden.

   NO es un carrusel de onboarding (eso sería exactamente lo genérico que hay
   que evitar): los tres pasos SE ACUMULAN. Cada uno que avanzás se pliega a
   una línea arriba y el siguiente se abre debajo, así que al final el alumno
   tiene el briefing entero a la vista antes de entrar -- y puede releer el
   paso 1 mientras lee el 3. Un carrusel te obliga a elegir entre avanzar y
   recordar; esto no. */
.ent{position:fixed;inset:0;z-index:250;display:grid;place-items:safe center;overflow-y:auto;
 padding:clamp(20px,5vw,40px) clamp(16px,4vw,26px);
 background:radial-gradient(120% 85% at 50% 0%,rgba(90,169,214,.09),rgba(6,7,10,.985) 58%);
 -webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);
 transition:opacity .55s ease,visibility .55s}
.ent.fuera{opacity:0;visibility:hidden;pointer-events:none}
.ent .hoja{width:100%;max-width:520px;margin:auto}
@media(min-width:1025px){.ent .hoja{max-width:600px}}

.ent .k{display:flex;align-items:center;gap:10px;font:700 9px/1 var(--mono);letter-spacing:.24em;
 text-transform:uppercase;color:var(--gold-deep);margin-bottom:16px}
.ent .k:after{content:"";flex:1;height:1px;background:linear-gradient(90deg,rgba(90,169,214,.3),transparent)}
.ent h2{font:600 clamp(20px,4.8vw,26px)/1.18 var(--sans);letter-spacing:-.032em;color:var(--ink);
 margin-bottom:22px;text-wrap:balance}

/* cada paso: número grabado + rótulo fijo + el texto */
.ent .paso{display:grid;grid-template-columns:auto 1fr;gap:14px;padding:16px 0;
 border-top:1px solid var(--line);opacity:0;transform:translateY(10px);
 transition:opacity .5s cubic-bezier(.16,1,.3,1),transform .5s cubic-bezier(.16,1,.3,1),padding .45s ease}
.ent .paso.vis{opacity:1;transform:none}
.ent .paso:first-child{border-top:0}
.ent .paso .num{font:700 10px/1 var(--mono);letter-spacing:.1em;color:var(--gold-deep);
 padding-top:4px;transition:color .4s}
.ent .paso .rot{display:block;font:700 8.5px/1 var(--mono);letter-spacing:.18em;text-transform:uppercase;
 color:var(--ash);margin-bottom:8px;transition:color .4s}
.ent .paso p{font:400 14px/1.68 var(--sans);color:var(--ink);letter-spacing:-.008em;
 max-height:340px;overflow:hidden;transition:max-height .45s ease,opacity .35s ease,font-size .35s ease}
/* plegado: el paso ya leído se achica a su rótulo, sin desaparecer */
.ent .paso.plegado{padding:11px 0}
.ent .paso.plegado .num{color:var(--dim)}
.ent .paso.plegado .rot{color:var(--dim)}
.ent .paso.plegado p{max-height:0;opacity:0}
/* el paso activo lleva el único acento dorado de la hoja */
.ent .paso.activo .num{color:var(--gold-hi)}
.ent .paso.activo .rot{color:var(--gold-hi)}

.ent .pie{display:flex;align-items:center;gap:12px;margin-top:24px;padding-top:20px;border-top:1px solid var(--line)}
.ent .pie button{font:700 12.5px/1 var(--sans);border:0;border-radius:12px;cursor:pointer;transition:.22s}
.ent .pie .ir{flex:1;color:#071119;padding:16px 22px;
 background:linear-gradient(180deg,var(--gold-hi),#3D8FC4);
 box-shadow:0 14px 32px -16px rgba(61,143,196,.9)}
.ent .pie .ir:hover{transform:translateY(-1px)}
.ent .pie .ir:active{transform:scale(.99)}
.ent .pie .sk{background:none;color:var(--dim);padding:16px 6px;font-weight:600;font-size:11px}
.ent .pie .sk:hover{color:var(--ash)}
.ent button:focus-visible{outline:2px solid var(--gold);outline-offset:3px}
/* puntitos de avance: 3 marcas, no una barra de progreso genérica */
.ent .marcas{display:flex;gap:5px;margin-left:auto}
.ent .marcas i{width:16px;height:2px;border-radius:2px;background:rgba(255,255,255,.13);transition:.4s}
.ent .marcas i.on{background:var(--gold-hi);box-shadow:0 0 8px rgba(90,169,214,.5)}
@media(prefers-reduced-motion:reduce){
 .ent,.ent .paso,.ent .paso p{transition:none}
 .ent .paso{opacity:1;transform:none}
}

/* ═══════════════════════════════════════════════════════════════════════════
   SELECTOR DE IDIOMA  ·  lo inyecta i18n.js en cualquier [data-lang-switch]
   ---------------------------------------------------------------------------
   POR QUÉ VIVE ACÁ Y NO EN CADA PANTALLA (Fernando, 2026-08-12)
   El CSS de este selector estaba copiado a mano en 7 archivos, con DOS nombres
   de variable distintos (--goldhi en cinco, --gold-hi en dos). Y el mapa del
   módulo y modulo.html no lo tenían en ninguna forma: ahí el selector salía
   como tres botones desnudos, pegados uno al otro. Eso era el "ESENPT" que
   Fernando venía viendo y llamaba "feo".
   Es la misma enfermedad que causó el bug de la identidad de Telegram: el
   mismo código repetido N veces, así que arreglarlo era arreglarlo N veces —
   y bastaba olvidarse de uno para que quedara roto en silencio.

   EL TAMAÑO ERA EL PROBLEMA REAL, no el gusto: medido, el selector daba
   45 × 21 px para TRES botones. Unos 15 px por botón, contra los ~44 px que
   necesita un objetivo táctil para poder tocarse sin errar. No se veía feo:
   era difícil de usar, y por eso se sentía mal.

   LA SOLUCIÓN, distinta por dispositivo:
   · Escritorio → los tres idiomas visibles. Hay lugar de sobra y un clic es
     preciso, así que mostrarlos es más rápido que esconderlos.
   · Móvil → UN solo botón con el idioma actual, que abre una hoja con los
     tres. Un objetivo grande en vez de tres diminutos.
   ═════════════════════════════════════════════════════════════════════════ */
.ca-lang{position:relative;flex:none;font:600 10px/1 var(--mono);z-index:20}
.ca-lang button{font:inherit;border:0;background:none;color:inherit;cursor:pointer;
 -webkit-tap-highlight-color:transparent}
.ca-lang button:focus-visible{outline:2px solid var(--gold);outline-offset:2px;border-radius:8px}

/* el botón que muestra el idioma actual: solo existe en móvil */
.ca-lang .ca-lang-hoy{display:none;align-items:center;gap:6px;min-height:40px;padding:0 12px;
 border-radius:10px;border:1px solid var(--line-2);background:rgba(255,255,255,.03);
 color:var(--ash);letter-spacing:.1em;transition:.2s}
.ca-lang .ca-lang-hoy:hover{color:var(--ink);border-color:rgba(90,169,214,.4)}
.ca-lang .ca-lang-hoy svg{width:9px;height:9px;fill:none;stroke:currentColor;stroke-width:2.4;
 stroke-linecap:round;stroke-linejoin:round;transition:transform .25s}
.ca-lang.abierto .ca-lang-hoy{color:var(--gold-hi);border-color:rgba(90,169,214,.45);
 background:rgba(90,169,214,.08)}
.ca-lang.abierto .ca-lang-hoy svg{transform:rotate(180deg)}

/* las tres opciones */
.ca-lang .ca-lang-ops{display:flex;gap:2px}
.ca-lang .ca-lang-ops button{min-height:34px;padding:0 11px;border-radius:8px;color:var(--dim);
 letter-spacing:.08em;transition:.2s}
.ca-lang .ca-lang-ops button:hover{color:var(--ash);background:rgba(255,255,255,.04)}
.ca-lang .ca-lang-ops button.on{color:var(--gold-hi);background:rgba(90,169,214,.1)}

/* ── MÓVIL: un botón grande + hoja desplegable ── */
@media(max-width:640px){
 .ca-lang .ca-lang-hoy{display:inline-flex}
 .ca-lang .ca-lang-ops{position:absolute;top:calc(100% + 6px);right:0;flex-direction:column;gap:0;
  min-width:132px;padding:5px;border-radius:12px;border:1px solid var(--line-2);
  background:linear-gradient(170deg,#15131A,#0B0A0E);
  box-shadow:0 18px 40px -16px rgba(0,0,0,.92);
  opacity:0;visibility:hidden;transform:translateY(-6px) scale(.97);transform-origin:top right;
  transition:opacity .2s ease,transform .2s ease,visibility .2s}
 .ca-lang.abierto .ca-lang-ops{opacity:1;visibility:visible;transform:none}
 /* 44px: el mínimo para que un dedo acierte sin pensarlo */
 .ca-lang .ca-lang-ops button{min-height:44px;width:100%;justify-content:flex-start;text-align:left;
  padding:0 14px;border-radius:9px;font-size:11.5px}
 .ca-lang .ca-lang-ops button.on:after{content:"✓";margin-left:auto;padding-left:10px;font-size:11px}
 .ca-lang .ca-lang-ops button.on{display:flex;align-items:center}
}
@media(prefers-reduced-motion:reduce){
 .ca-lang .ca-lang-hoy svg,.ca-lang .ca-lang-ops{transition:none}
}

/* ── EL HILO ───────────────────────────────────────────────────────────────
   Dos renglones que cosen la actividad con la anterior y la siguiente. Van
   discretos a propósito: orientan, no compiten con el trabajo. Ver el porqué
   largo en hilo.js. */
.hilo{display:grid;grid-template-columns:1fr;gap:8px;margin-top:16px;padding-top:14px;
 border-top:1px solid rgba(255,255,255,.07)}
@media(min-width:768px){.hilo{grid-template-columns:1fr 1fr;gap:14px}}
.hilo .hi{display:flex;flex-direction:column;gap:4px;min-width:0}
.hilo .hk{font:700 8px/1 var(--mono);letter-spacing:.18em;text-transform:uppercase;color:var(--dim)}
.hilo .hi.va .hk{color:var(--gold-deep)}
.hilo p{font:400 11.2px/1.6 var(--sans);color:var(--ash)}
.hilo p b{color:var(--ink);font-weight:600}
/* la flecha marca la dirección sin gastar una palabra */
.hilo .hi.de .hk:before{content:"← "}
.hilo .hi.va .hk:after{content:" →"}


/* ══ MÓVIL PRIMERO · LOS BLANCOS QUE QUEDABAN CHICOS (2026-08-26) ══════════
   La auditoría (scripts/auditar-responsive.py) encontró botones de 24 a 38px.
   Con el pulgar eso se falla, y al alumno le queda la sensación de que la
   pantalla no responde -- peor que un error, porque no sabe si tocó mal o si
   está rota. 40px es el mínimo con el que un pulgar acierta.

   Los de idioma eran los peores: 24x25px. Se les da alto y ancho mínimos SIN
   agrandar la letra, con `display:grid;place-items:center` -- así el blanco
   crece pero el diseño del header se ve igual.

   Solo hasta 1024px: de tablet para arriba hay mouse, y apretar el diseño ahí
   no le sirve a nadie. */
@media (max-width:1024px){
  .lang button{min-height:40px;min-width:40px;display:grid;place-items:center;padding:0 6px}
  .btn{min-height:40px}
}

/* Los enlaces del pie median 29px. Se les da alto de dedo sin cambiar la
   tipografia ni el aire: el ancla pasa a caja con el texto centrado. */
@media (max-width:1024px){
  /* El alto ya estaba; faltaba el ANCHO. «Hub» medía 19px de ancho: alto de
     dedo y ancho de alfiler. Con 44 de mínimo y el texto centrado se ve igual
     (los cuatro enlaces caben de sobra en 320px: 4×44 + 3×20 de aire = 236). */
  .mini-foot .lines a,.site-foot a{min-height:40px;min-width:44px;
    display:inline-flex;align-items:center;justify-content:center}
}

/* Enlaces-ícono que medían 19px de ancho: crece el blanco, no el ícono. */
@media (max-width:1024px){
  a:has(> svg:only-child){min-width:40px;min-height:40px;
    display:inline-grid;place-items:center}
}

/* ── BLANCOS PARA EL DEDO · EN TODAS LAS PANTALLAS ────────────────────────
   Estas reglas estaban solo en actividad.css, y el perfil y las 4 actividades
   SUELTAS no lo cargan: ahí seguían midiendo 30-37px. Van acá, en el CSS que
   carga todo, para que no dependa de qué archivo incluye cada pantalla.
   Crece la caja que responde al dedo, nunca la tipografía. */
@media (max-width:1024px){
  #ir-hub,#btn-editar,#bHora,#cur-b,.secK{min-height:40px}
  #xb,#btnBack{min-width:40px;min-height:40px;display:inline-grid;place-items:center}
  /* notas que quedaban en 9,5-10,5px: texto para leer con tamaño de etiqueta */
  #ahora,.pnota,.nota-min{font-size:11.5px}
}
@media (max-width:1024px){
  #sideNote,#cupPie{font-size:11.5px}
}
@media (max-width:1024px){
  #pmNote,#riscoMax,#sideNote{font-size:11.5px}
}
