/* plataforma.css — El cuadro que recrea la plataforma, y sus widgets.
 *
 * Es una VENTANA DE APLICACIÓN dentro de la página, así que tiene tema propio
 * (`--pl-*`) en vez de heredar los tokens de la web: una app con el fondo de la
 * sección no se lee como una app. Lo que sí hereda es la tipografía.
 *
 * ⚠️ LA PALETA DE SERIES ESTÁ VALIDADA, NO ELEGIDA A OJO.
 *   node scripts/validate_palette.js "#0B6FA6,#B4551A,#6B3FA0,#177245" --mode light
 *   → 5/5: banda de luminosidad, suelo de croma, separación con daltonismo
 *     (peor par ΔE 17,0 en deuteranopía), suelo de visión normal y contraste.
 * Antes se probaron el cian y el magenta de la casa: quedan a ΔE 2,6 en
 * deuteranopía, o sea indistinguibles. No volver a proponerlos para series.
 *
 * ⚠️ Y NO ES LA PALETA DE NINGÚN CLIENTE. El granate de una plataforma y el rojo
 * de la otra son su identidad de marca: se copia la ESTRUCTURA —layout, tipos de
 * gráfico, recorrido—, nunca el color, que las haría reconocibles aunque les
 * quitemos el nombre.
 */

.plataforma {
  /* Superficie de la app */
  --pl-fondo: #ffffff;
  --pl-fondo-alt: #f7f8fa;
  --pl-fondo-hondo: #eef1f5;
  --pl-borde: #e2e6ec;
  --pl-texto: #1f2430;
  --pl-tenue: #667084;

  /* ⚠️ EL CROMO NO LLEVA COLOR DE ACENTO. Ninguno.
     Se probó con el teal de la casa a plena saturación, luego apagado al 55 %
     y luego mezclado al 42 % con el gris de texto, y las tres veces seguía
     tirando del ojo más que el gráfico: son muchos elementos pequeños
     repartidos —dieciocho casillas, el paso activo, la pestaña, la barra de
     avance— y sumados pesan más que la figura que hay que mirar.
     (Julio, 2026-09-10: «quita todo el brillo verde del componente».)

     Así que el cromo va en TINTA, y el color se reserva entero para lo que ES
     DATO: las cuatro series validadas. Un cuadro de mando en el que lo único
     de color son los datos se lee mejor, y de paso deja de haber un quinto
     color que validar. */
  --pl-acento: #1f2430;
  --pl-acento-suave: #f1f3f6;

  /* Series categóricas, en orden fijo. NUNCA se reasignan por rango ni se
     reciclan: la serie 3 es la serie 3 aunque se filtre la 2. */
  --pl-s1: #0b6fa6;
  --pl-s2: #b4551a;
  --pl-s3: #6b3fa0;
  --pl-s4: #177245;

  color: var(--pl-texto);
  font-family: var(--tipo-cuerpo);
  /* ⚠️ SIN `background`. Esta clase sólo lleva los tokens; el fondo blanco es
     del `.pl-cuadro`. Pintándolo aquí, el contenedor tapaba el fondo oscuro de
     la sección alrededor del cuadro y dejaba el halo —que es cian— sobre
     blanco, donde no se ve. */
}

.plataforma[data-variante="2"] {
  /* La variante 2 ya no se distingue por color: se distingue por lo que
     enseña —otros pasos, otras cohortes, otro recorrido—, que es la diferencia
     que importa. Se deja el bloque para que se vea que es deliberado y no un
     olvido. */
  --pl-acento: #1f2430;
  --pl-acento-suave: #f1f3f6;
}

/* ── Los widgets ───────────────────────────────────────────────────────── */

.pl-svg {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}

/* Los grosores van en píxeles de pantalla y no del `viewBox`: sin esto, el
   mismo trazo se ve de 2 px en el laboratorio y de 1,3 px en la página, porque
   el lienzo de 1000 se escala a lo que mida el panel. */
.pl-svg line,
.pl-svg path,
.pl-svg polygon,
.pl-svg circle {
  vector-effect: non-scaling-stroke;
}

.pl-eje {
  font-family: var(--tipo-mono);
  font-size: 15px;
  fill: var(--pl-tenue);
}
/* Rejilla recesiva y CONTINUA: el trazo discontinuo añade ruido y se lee como
   si el propio dato fuera provisional. */
.pl-rejilla {
  stroke: var(--pl-borde);
  stroke-width: 1;
  fill: none;
}
.pl-axis {
  stroke: var(--pl-tenue);
  stroke-width: 1;
  opacity: 0.5;
}

/* El color de serie vive en un solo sitio: estas cuatro clases. */
.pl-s1 { --c: var(--pl-s1); }
.pl-s2 { --c: var(--pl-s2); }
.pl-s3 { --c: var(--pl-s3); }
.pl-s4 { --c: var(--pl-s4); }

.pl-rect { fill: var(--c, var(--pl-s1)); }
.pl-punto { fill: var(--c, var(--pl-s1)); }
.pl-linea {
  fill: none;
  stroke: var(--c, var(--pl-s1));
  stroke-width: 2;
  stroke-linejoin: round;
  stroke-linecap: round;
}
.pl-banda {
  fill: var(--c, var(--pl-s1));
  opacity: 0.14;
  stroke: none;
}
.pl-bigote {
  stroke: var(--c, var(--pl-s1));
  stroke-width: 1.5;
}
.pl-mediana {
  stroke: var(--pl-fondo);
  stroke-width: 2;
}
.pl-error {
  stroke: var(--pl-texto);
  stroke-width: 1.5;
  opacity: 0.55;
}
.pl-densidad {
  fill: none;
  stroke: var(--pl-texto);
  stroke-width: 2;
  opacity: 0.62;
}
/* La curva ajustada va en TINTA y algo más gruesa que una serie: es la lectura
   del gráfico, no una serie más, y en tinta se distingue de los puntos sin
   meter un color nuevo que habría que validar contra los otros cuatro. */
.pl-ajuste {
  fill: none;
  stroke: var(--pl-texto);
  stroke-width: 2.5;
  stroke-linecap: round;
  opacity: 0.85;
}
.pl-ecuacion {
  font-family: var(--tipo-mono);
  font-size: 15px;
  fill: var(--pl-texto);
}
.pl-pieza:not(.pl-ancha) .pl-ecuacion { font-size: 24px; }
@media (max-width: 720px) { .pl-ecuacion { font-size: 28px; } }
.pl-radar {
  fill: var(--c, var(--pl-s1));
  fill-opacity: 0.16;
  stroke: var(--c, var(--pl-s1));
  stroke-width: 2;
  stroke-linejoin: round;
}
/* Diverging con las dos series validadas: azul arriba, naranja abajo. Es el par
   más robusto ante daltonismo, y evita el quinto color. */
.pl-celda { fill: var(--pl-s1); }
.pl-celda.pl-neg { fill: var(--pl-s2); }
/* Texto en tinta, nunca en color de serie: sobre celda saturada el valor tiene
   que leerse igual que sobre celda pálida. */
.pl-celda-txt {
  font-family: var(--tipo-mono);
  font-size: 14px;
  fill: var(--pl-texto);
}
.pl-cinta {
  fill: var(--c, var(--pl-s1));
  opacity: 0.34;
}
.pl-nodo { fill: var(--pl-tenue); }

/* En pantalla estrecha el lienzo de 1000 unidades se comprime a poco más de
   300 px, así que TODO lo que mide en unidades de lienzo se encoge con él: un
   cuerpo de 15 acaba viéndose a 5 px, ilegible. Los trazos no lo sufren porque
   llevan `non-scaling-stroke`, pero el texto no tiene equivalente, así que se
   compensa subiendo el cuerpo dentro del propio lienzo. */
@media (max-width: 900px) {
  .pl-eje { font-size: 30px; }
  .pl-celda-txt { font-size: 26px; }
  /* Al doblar el cuerpo, la etiqueta del eje X se sube contra la línea del eje:
     la separación de 22 unidades estaba calculada para un cuerpo de 15. */
  .pl-eje-x { transform: translateY(14px); }
}

/* ── Leyenda ───────────────────────────────────────────────────────────── */

.pl-leyenda {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 20px;
  list-style: none;
  margin: 0 0 10px;
  padding: 0;
  font-size: 13px;
  color: var(--pl-tenue);
}
.pl-leyenda li {
  display: flex;
  align-items: center;
  gap: 7px;
}
.pl-leyenda i {
  width: 10px;
  height: 10px;
  border-radius: 2px;
  background: var(--c, var(--pl-s1));
  flex: 0 0 auto;
}

/* ── Tabla ─────────────────────────────────────────────────────────────── */

.pl-tabla-caja { overflow-x: auto; }
.pl-tabla {
  border-collapse: collapse;
  width: 100%;
  font-size: 13px;
  font-variant-numeric: tabular-nums;
}
.pl-tabla th,
.pl-tabla td {
  padding: 7px 12px;
  text-align: right;
  border-bottom: 1px solid var(--pl-borde);
  white-space: nowrap;
}
.pl-tabla thead th {
  font-family: var(--tipo-mono);
  font-size: 10.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--pl-tenue);
  font-weight: 400;
  border-bottom-color: var(--pl-tenue);
}
.pl-tabla tbody th {
  text-align: left;
  font-weight: 700;
  color: var(--pl-texto);
}
.pl-tabla .pl-destacada { background: var(--pl-acento-suave); }

/* ── Informe ───────────────────────────────────────────────────────────── */

.pl-informe { max-width: 74ch; }
.pl-informe h4 {
  margin: 0 0 12px;
  font-size: 16px;
  font-weight: 700;
}
.pl-informe p {
  margin: 0 0 12px;
  font-size: 13.5px;
  line-height: 1.62;
  color: var(--pl-texto);
}
/* Los términos que el redactor marca: peso y tinta, sin color. En un párrafo
   de tres líneas, cuatro palabras de color son cuatro tirones. */
.pl-marca {
  color: var(--pl-texto);
  font-weight: 700;
}

/* ── Envoltura de cada gráfico ─────────────────────────────────────────── */

.pl-fig {
  margin: 0;
  padding: 16px 18px 14px;
  background: var(--pl-fondo);
  border: 1px solid var(--pl-borde);
  border-radius: 4px;
}
.pl-fig figcaption {
  font-family: var(--tipo-mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--pl-tenue);
  margin-bottom: 12px;
}
.pl-fig h3 {
  margin: 0 0 4px;
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -0.01em;
}
.pl-fig .pl-sub {
  margin: 0 0 16px;
  font-size: 12.5px;
  color: var(--pl-tenue);
  line-height: 1.5;
}

/* ── El cuadro ─────────────────────────────────────────────────────────────
   La ventana de aplicación: cabecera, barra de pasos, panel y cohortes.
   Se lee como una app embebida, no como una sección más de la página, y para
   eso hace falta que tenga marco, cromo y su propio fondo. */

.pl-cuadro {
  border: 1px solid var(--pl-borde);
  border-radius: 11px;
  overflow: hidden;
  background: var(--pl-fondo);
}

/* ── El marco: lo que hace que NO parezca embebido ─────────────────────────
   Sin esto el cuadro se lee como una sección más de la página, con su borde
   fino y su fondo distinto. Lo que lo despega son tres cosas juntas, y hacen
   falta las tres:

     1. El cromo de ventana —las luces y la barra de dirección— dice «esto es
        una aplicación web» de un vistazo. Es lo más barato y lo que más hace.
     2. La sombra en tres capas: una de contacto muy corta, una media y una
        larga y muy difusa. Con una sola capa el cuadro parece pegado con
        cinta; con tres, apoyado.
     3. El halo detrás, del color de acento de la página. Sobre el fondo oscuro
        de «Análisis» es lo que da la sensación de que hay luz alrededor.

   Referencias que trajo Julio: toku.com (cromo de navegador) y la portada de
   Agently (halo y elevación). Cada una hace la mitad; aquí van las dos. */

.pl-marco {
  position: relative;
  isolation: isolate;
}
/* ⚠️ Sobre fondo OSCURO una sombra negra no despega nada: no hay contraste que
   sacarle. Lo que separa aquí es la LUZ.

   Se probó primero con un halo radial DETRÁS del cuadro y no se veía —medido,
   3 unidades sobre el fondo—, porque un radial centrado deja casi toda su
   energía debajo del cuadro, que es opaco y la tapa. El glow que sale del
   propio BORDE sí funciona: 48 unidades a los lados con los mismos valores de
   color. Y la sombra oscura va corta, o se come el glow y el cuadro parece
   hundido en vez de flotando — también medido, salía más oscuro junto al
   cuadro que lejos de él. */
.pl-marco > .pl-cuadro {
  box-shadow:
    0 1px 2px rgb(12 14 20 / 26%),
    0 16px 34px -14px rgb(12 14 20 / 36%),
    0 0 76px -12px color-mix(in srgb, var(--acento) 58%, transparent);
}

/* ── El cromo de ventana ───────────────────────────────────────────────── */

.pl-ventana {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 11px 15px;
  background: var(--pl-fondo-hondo);
  border-bottom: 1px solid var(--pl-borde);
}
.pl-luces { display: flex; gap: 7px; flex: 0 0 auto; }
/* Grises y no el semáforo rojo-ámbar-verde: el semáforo de macOS calcado es un
   cliché, y en gris se lee igual de bien como ventana. */
.pl-luces i {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--pl-tenue) 42%, transparent);
}
.pl-url {
  font-family: var(--tipo-mono);
  font-size: 11px;
  letter-spacing: 0.02em;
  color: var(--pl-tenue);
  background: var(--pl-fondo);
  border: 1px solid var(--pl-borde);
  border-radius: 100px;
  padding: 5px 16px;
  max-width: 46ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

@media (max-width: 720px) {
  /* En móvil el cuadro ocupa el ancho entero: no hay de qué despegarlo, y el
     glow de 76 px cuesta pintura en cada scroll. */
  .pl-marco > .pl-cuadro {
    box-shadow: 0 1px 2px rgb(12 14 20 / 22%), 0 12px 26px -14px rgb(12 14 20 / 38%);
  }
  .pl-url { font-size: 10px; padding: 4px 12px; }
}

.pl-cabecera {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 9px 12px;
  background: var(--pl-fondo-alt);
  border-bottom: 1px solid var(--pl-borde);
}
.pl-toggle { display: flex; gap: 4px; }
.pl-tab {
  font-family: var(--tipo-mono);
  font-size: 10.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 7px 13px;
  border: 1px solid transparent;
  border-radius: 3px;
  background: none;
  color: var(--pl-tenue);
  cursor: pointer;
}
.pl-tab.activa {
  background: var(--pl-fondo);
  border-color: var(--pl-borde);
  color: var(--pl-acento);
}
.pl-resumen {
  flex: 1;
  font-size: 12.5px;
  color: var(--pl-tenue);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.pl-pausa {
  font-family: var(--tipo-mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 7px 12px;
  border: 1px solid var(--pl-borde);
  border-radius: 3px;
  background: var(--pl-fondo);
  color: var(--pl-tenue);
  cursor: pointer;
  flex: 0 0 auto;
}
.pl-pausa:hover { color: var(--pl-acento); border-color: var(--pl-acento); }

.pl-cuerpo {
  display: grid;
  grid-template-columns: 172px minmax(0, 1fr) 208px;
  /* Alto fijo a propósito: si el cuadro creciera y menguara con cada paso, el
     resto de la página daría saltos cada siete segundos. El panel scrollea.
     540 es lo que pide el paso más alto —la tabla de carga y el informe— con
     el gráfico ya compensado; por encima sobraba medio cuadro vacío. */
  height: 566px;
}

/* ── La barra de pasos ─────────────────────────────────────────────────── */

.pl-pasos {
  border-right: 1px solid var(--pl-borde);
  padding: 10px 0;
  overflow-y: auto;
  background: var(--pl-fondo);
}
.pl-paso {
  position: relative;
  display: flex;
  align-items: baseline;
  gap: 9px;
  width: 100%;
  padding: 9px 14px;
  border: 0;
  background: none;
  text-align: left;
  cursor: pointer;
  color: var(--pl-tenue);
}
.pl-paso:hover { background: var(--pl-fondo-alt); }
.pl-paso.activo { background: var(--pl-acento-suave); color: var(--pl-acento); }
.pl-paso-n { font-family: var(--tipo-mono); font-size: 10px; letter-spacing: 0.06em; }
.pl-paso-t { font-size: 13px; }
.pl-paso.activo .pl-paso-t { font-weight: 700; }

/* La barra de avance del paso: dice cuánto queda sin necesidad de un número. */
.pl-paso-barra {
  position: absolute;
  left: 0;
  bottom: 0;
  height: 2px;
  width: 0;
  background: var(--pl-acento);
}
.pl-paso-barra.corriendo { animation: pl-avance linear forwards; }
@keyframes pl-avance { from { width: 0 } to { width: 100% } }

/* ── El panel ──────────────────────────────────────────────────────────── */

/* ⚠️ SIN scroll. Es un requisito, no una preferencia: el paseo va cambiando de
   paso solo, y un panel que scrollea deja al visitante mirando el hueco de lo
   que ya no está. Que quepa lo garantizan los altos; si algo se saliera, se
   vería cortado y lo caza `desborde.mjs`. */
.pl-panel { padding: 20px 24px 24px; overflow: hidden; }
.pl-migas {
  font-family: var(--tipo-mono);
  font-size: 9.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--pl-tenue);
  margin-bottom: 10px;
}
.pl-titular { display: flex; align-items: flex-start; gap: 20px; margin-bottom: 16px; }
.pl-titular h4 { margin: 0 0 5px; font-size: 18px; font-weight: 700; letter-spacing: -0.01em; }
.pl-titular p { margin: 0; font-size: 12.5px; line-height: 1.55; color: var(--pl-tenue); max-width: 64ch; }

.pl-selector { flex: 0 0 auto; display: grid; gap: 4px; }
.pl-selector span {
  font-family: var(--tipo-mono);
  font-size: 9.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--pl-tenue);
}
.pl-selector select {
  font-family: var(--tipo-cuerpo);
  font-size: 13px;
  color: var(--pl-texto);
  background: var(--pl-fondo);
  border: 1px solid var(--pl-borde);
  border-radius: 3px;
  padding: 6px 9px;
  cursor: pointer;
}
/* Los gráficos de un paso, lado a lado y SIEMPRE en dos columnas.
   ⚠️ Con `auto-fit` y `minmax(330px, …)` la rejilla se plegaba a una sola
   columna en cuanto el panel bajaba de 660 px —entre 900 y 1280 px de
   ventana—, mientras el alto del lienzo se seguía compensando como si hubiera
   dos: el gráfico salía tres veces más alto de lo que cabe y aparecía scroll.
   Medido: +580 px de desborde a 1150 px de ventana. Con dos columnas fijas, el
   gráfico encoge con el panel y el alto encoge con él. */
.pl-piezas {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 20px 24px;
  align-items: start;
}
.pl-pieza.pl-ancha { grid-column: 1 / -1; }

/* A media columna el lienzo se comprime a menos de la mitad, y con él todo lo
   que mide en unidades de lienzo: el cuerpo de 15 se ve a 6 px. Mismo remedio
   que en pantalla estrecha — subirlo dentro del propio lienzo. El cálculo del
   radio del radar usa este cuerpo, no el pequeño. */
.pl-pieza:not(.pl-ancha) .pl-eje { font-size: 26px; }
.pl-pieza:not(.pl-ancha) .pl-eje-x { transform: translateY(10px); }
.pl-pieza:not(.pl-ancha) .pl-celda-txt { font-size: 24px; }

/* ── El panel de cohortes y sujetos ────────────────────────────────────── */

.pl-lateral {
  border-left: 1px solid var(--pl-borde);
  background: var(--pl-fondo-alt);
  padding: 16px 14px;
  overflow-y: auto;
}
.pl-lateral-bloque + .pl-lateral-bloque { margin-top: 22px; }
.pl-lateral-rotulo {
  display: block;
  font-family: var(--tipo-mono);
  font-size: 9.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--pl-tenue);
  margin-bottom: 10px;
}
.pl-cohorte,
.pl-sujeto {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12.5px;
  padding: 5px 0;
  cursor: pointer;
}
/* Los sujetos van más apretados que las cohortes: son dieciséis y tienen que
   caber enteros en el alto del cuadro. */
.pl-sujeto { padding: 2.5px 0; }
.pl-cohorte i {
  width: 9px;
  height: 9px;
  border-radius: 2px;
  background: var(--c, var(--pl-s1));
  flex: 0 0 auto;
}
.pl-cohorte span { flex: 1; }
.pl-cohorte b { font-family: var(--tipo-mono); font-size: 11px; color: var(--pl-tenue); font-weight: 400; }
/* Sin scroll y los dieciséis a la vista: el sentido de la lista es ver cuál se
   quita y cuál se pone, y con scroll la coreografía del paseo tira sujetos que
   quedan fuera de cuadro. Para que quepan, la fila se compacta. */
.pl-sujetos { display: grid; gap: 0; }
.pl-sujeto span { flex: 1; font-family: var(--tipo-mono); font-size: 11px; }
.pl-sujeto em {
  font-style: normal;
  font-family: var(--tipo-mono);
  font-size: 9.5px;
  letter-spacing: 0.06em;
  color: var(--pl-tenue);
}
/* ⚠️ Las casillas NO llevan el acento a plena saturación.
   Son dieciocho —dos cohortes y dieciséis sujetos— apiladas en una columna
   estrecha, así que a todo color se convierten en una mancha que tira del ojo
   más que el propio gráfico. Apagadas hacia el gris de texto siguen leyéndose
   como marcadas y dejan el acento para lo que de verdad llama: el botón del
   agente y el paso activo. (Julio, 2026-09-10: «dentro deslumbra».) */
.pl-cuadro input[type="checkbox"] {
  accent-color: var(--pl-acento);
  margin: 0;
  opacity: 0.85;
}

/* ── El agente redactor ────────────────────────────────────────────────────
   Caja de petición, botón, y el sitio donde escribe. Es una demo declarada: el
   texto viene del guion y se pinta letra a letra. */

.pl-agente { max-width: 78ch; }
.pl-agente-caja { display: flex; gap: 10px; flex-wrap: wrap; }
.pl-agente-campo {
  flex: 1 1 320px;
  min-width: 0;
  font-family: var(--tipo-cuerpo);
  font-size: 13.5px;
  color: var(--pl-texto);
  background: var(--pl-fondo);
  border: 1px solid var(--pl-borde);
  border-radius: 3px;
  padding: 10px 13px;
}
.pl-agente-campo:focus-visible { outline: 2px solid var(--pl-s1); outline-offset: 1px; }
.pl-agente-boton {
  font-family: var(--tipo-mono);
  font-size: 10.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--pl-fondo);
  background: var(--pl-acento);
  border: 1px solid var(--pl-acento);
  border-radius: 3px;
  padding: 10px 18px;
  cursor: pointer;
  flex: 0 0 auto;
}
.pl-agente-boton:hover { background: color-mix(in srgb, var(--pl-acento) 84%, var(--pl-texto)); }

.pl-agente-salida { margin-top: 16px; }
.pl-agente-salida:empty { margin-top: 0; }
.pl-agente-salida h5 {
  margin: 0 0 10px;
  font-size: 15px;
  font-weight: 700;
}
.pl-agente-salida p {
  margin: 0 0 11px;
  font-size: 13.5px;
  line-height: 1.62;
}
.pl-agente-salida.pensando {
  display: flex;
  align-items: center;
  gap: 12px;
  font-family: var(--tipo-mono);
  font-size: 10.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--pl-tenue);
}
/* El isotipo trae la paleta de los componentes del repo —azules grisáceos
   claros— y sobre el blanco de la app se pierde. Se oscurece aquí, igual que en
   la caja de consulta de «Protocolos». Ver wiki/marca.md. */
.pl-agente-salida .isotipo { filter: brightness(0.58) saturate(1.2); }

/* El cursor mientras escribe, en el último párrafo y sólo mientras dura. */
.pl-agente-salida.escribiendo .pl-agente-texto p:last-child::after {
  content: "";
  display: inline-block;
  width: 7px;
  height: 1em;
  margin-left: 2px;
  vertical-align: -2px;
  background: var(--pl-acento);
  animation: pl-cursor 1s steps(2) infinite;
}
@keyframes pl-cursor { 50% { opacity: 0 } }
@media (prefers-reduced-motion: reduce) {
  .pl-agente-salida.escribiendo .pl-agente-texto p:last-child::after { animation: none; }
}

.pl-pie {
  margin: 0;
  padding: 9px 14px;
  border-top: 1px solid var(--pl-borde);
  background: var(--pl-fondo-alt);
  font-family: var(--tipo-mono);
  font-size: 9.5px;
  letter-spacing: 0.06em;
  color: var(--pl-tenue);
  line-height: 1.5;
}

/* El foco SÍ va en color, y es la excepción a propósito: es lo único que le
   dice a quien navega con teclado dónde está, y en tinta sobre tinta no se
   vería. */
.pl-cuadro :focus-visible { outline: 2px solid var(--pl-s1); outline-offset: -2px; }

/* Con movimiento reducido la barra de avance no corre: el paseo tampoco
   arranca, así que una barra animada estaría mintiendo. */
@media (prefers-reduced-motion: reduce) {
  .pl-paso-barra.corriendo { animation: none; width: 100%; }
}

/* ── El cuadro, estrecho ───────────────────────────────────────────────── */

@media (max-width: 900px) {
  /* Tres columnas no caben. Los pasos pasan a tira horizontal arriba y las
     cohortes bajan al pie: el panel se queda con todo el ancho, que es lo
     único que de verdad necesita el sitio. */
  /* 840 y no 800: en esta franja el titular pasa a columna y las piezas se
     apilan, y las dos cosas juntas piden más alto del que había. Medido paso a
     paso de 360 a 900 px — por debajo de 800 sobra sitio (0 px de exceso) y el
     peor caso es «Estadística» de la segunda plataforma a 899 px, con +40. El
     panel va con `overflow: hidden`, así que lo que no cabía no asomaba: se
     recortaba en silencio. Lo caza `verificar-sin-scroll.mjs`, que desde el
     2026-09-12 mira también tableta y móvil. */
  .pl-cuerpo { grid-template-columns: 1fr; grid-template-rows: auto minmax(0, 1fr) auto; height: 840px; }
  .pl-pasos {
    display: flex;
    overflow-x: auto;
    border-right: 0;
    border-bottom: 1px solid var(--pl-borde);
    padding: 0;
  }
  .pl-paso { width: auto; flex: 0 0 auto; padding: 11px 14px; }
  .pl-lateral { border-left: 0; border-top: 1px solid var(--pl-borde); }
  /* Las cohortes en fila —son dos y caben— y los sujetos en rejilla de tres
     columnas con su propio scroll. En fila se salían del cuadro: dieciséis
     casillas no caben a lo ancho de un móvil por mucho `gap` que se les quite. */
  /* Rótulo en su línea y las dos cohortes en fila. Metiendo el rótulo en el
     mismo flex, la primera cohorte se le pegaba al lado y la segunda caía
     debajo: quedaban a distinta altura sin motivo. */
  .pl-lateral-bloque:first-child .pl-cohorte { display: inline-flex; margin-right: 22px; }
  .pl-lateral-bloque + .pl-lateral-bloque { margin-top: 14px; }
  .pl-sujetos { grid-template-columns: repeat(3, 1fr); gap: 0 12px; }
  .pl-sujeto em { display: none; } /* el grupo no cabe y no es lo que se toca */
  .pl-cohorte span { white-space: nowrap; }
  /* `minmax(0, 1fr)` y no `1fr`: el `min-width: auto` que traen los ítems de
     grid les impide encoger por debajo de su contenido, así que la pieza ancha
     se quedaba en 567px dentro de un hueco de 300 y el panel —que va con
     `overflow: hidden`— le cortaba casi la mitad. La rejilla de dos columnas ya
     lo hacía bien; este override se lo comía. Medido a 390px. */
  .pl-piezas { grid-template-columns: minmax(0, 1fr); }
  .pl-titular { flex-direction: column; gap: 12px; }
}
