/* ==========================================================================
   CMCS — Las páginas internas
   --------------------------------------------------------------------------
   Seis páginas armadas por `construir.py` desde el copy aprobado de Manuel.

   CUATRO REGLAS QUE LAS SOSTIENEN:

   a) TODO ENCABEZADO VA AL EJE. Antetítulo, titular, entrada y botones,
      centrados y ocupando el alto de la pantalla. Lo pidió Andrés el 2026-09-08
      para las seis, y por eso existe UN solo bloque `.encabezado` en vez de seis
      variantes: si cada sección se centra por su cuenta, a la tercera hay tres
      medidas distintas de lo mismo.

   b) LOS TITULARES TIENEN CUENTA DE RENGLONES. Cada uno lleva su `--medida` en
      `em`, no en píxeles, para que el punto de corte siga al tamaño de letra.
      Están calibrados: tres renglones el de Admisiones, dos los demás.

   c) EL CONTENIDO NO SE CENTRA. Sólo el encabezado. Las tarjetas, la línea de
      tiempo y los datos conservan su filo izquierdo: es lo que los hace leerse
      como documento y no como cartel.

   d) NADA BLANCO SOBRE CLARO. Los enlaces de acción nacen blancos —vienen de
      secciones marino— y en las bandas claras desaparecían. Cada banda clara
      los repinta. Si añades una sección clara nueva, añádela a esa lista.
   ========================================================================== */

/* ---- El encabezado, común a todas ---------------------------------------- */

.encabezado {
  display: grid;
  justify-items: center;
  text-align: center;
  width: 100%;
  max-width: 68rem;
  margin-inline: auto;
}
/* PARA LOS TITULARES QUE TIENEN QUE CABER EN DOS RENGLONES y no caben en 68rem.
   «Vida Cervantista: la vivencia cotidiana de nuestra comunidad» son sesenta
   caracteres: a la talla de titular necesita unos 1.150 px para partirse en dos,
   y el lienzo da 1.168 a 1440. `--medida` sola no basta —tope contra tope— así
   que lo que se ensancha es la caja, no la medida. Se aplica UNA A UNA, no por
   defecto: los demás encabezados se leen mejor a 68rem. */
.encabezado--ancho { max-width: 76rem; }

/* EL ANTETÍTULO EN CÁPSULA. Para los rótulos que no son un epígrafe sino una
   ETIQUETA: «Ruta 1 · Gestión del colegio» dice de quién depende ese camino, y
   es el dato con el que la familia se reconoce antes de leer el titular. En
   versalitas sueltas se perdía. Va con el radio de los botones porque es lo
   que ya hay en el sistema para una forma cerrada de este tamaño. */
/* LA CÁPSULA LLEVA LOS DOS NOMBRES DE CLASE EN EL SELECTOR, y no es adorno:
   `.es-clara .encabezado__antetitulo` pinta el antetítulo de cerúleo hondo con
   la misma especificidad que `.es-clara .antetitulo--capsula`, así que empatan
   y decide el ORDEN del archivo. La primera vez perdí ese empate y la cápsula
   salió cerúleo sobre cerúleo: invisible, y lo cazó el barrido a 1:1.
   Encadenando las dos clases el selector sube un escalón y gana pase lo que
   pase, que es lo que hay que hacer cuando dos reglas legítimas se disputan la
   misma propiedad. */
.encabezado__antetitulo.antetitulo--capsula {
  padding: 0.4em 1em;
  border-radius: var(--radio-cta);
}
.es-clara .encabezado__antetitulo.antetitulo--capsula {
  background: var(--marino);
  color: #FFF;
}
.es-clara .encabezado__antetitulo.antetitulo--capsula-sem {
  background: var(--ceruleo-hondo);
  color: #FFF;
}
/* En campo marino se invierte: marino sobre marino no se ve. */
.es-marino .encabezado__antetitulo.antetitulo--capsula {
  background: #FFF;
  color: var(--marino);
}
/* Y la de la SEM conserva su cerúleo también en marino. Si cayera en la regla
   de arriba, las dos rutas llevarían la misma cápsula blanca y se perdería lo
   único que dice de un vistazo que no las administra el mismo. */
.es-marino .encabezado__antetitulo.antetitulo--capsula-sem {
  background: #8FD0F0;
  color: var(--marino);
}
.encabezado__antetitulo {
  display: block;
  max-width: none;
  margin: 0 0 var(--e-5);
  color: #8FD0F0;
}
/* LOS TITULARES CON MANCHA NECESITAN MÁS AIRE, y no es cuestión de gusto: son
   geometría. El interlineado de display es 0,94 —cerrado a propósito— pero la
   caja pintada del resaltado no la fija el interlineado sino las MÉTRICAS DE LA
   FUENTE: en Montserrat, ascendente + descendente son 1,21 em, más el relleno.
   Medido a 1440: la mancha ocupaba 95 px en renglones que avanzaban 66. Se
   pisaba 29 px, y por eso «pedagógica» tocaba «desde el preescolar».

   Bajar el relleno no basta —el 1,21 em manda—, así que el interlineado sube
   donde hay mancha y SÓLO donde la hay: los titulares sin resaltar conservan el
   display cerrado, que es la voz de la casa. `:has()` es lo que permite
   distinguirlos, y la clase `tiene-marca` la pone el GENERADOR: se probó con
   `:has()` y Chrome dejó caer la regla —`matches(':has(.marca)')` devolvía
   `true` desde JavaScript pero la regla no llegaba al CSSOM—. Un selector que
   a veces se aplica es peor que ninguno, porque el fallo no se ve. Ver
   `marcar_titulares()` en `construir.py`.

   Y VA ENCADENADA A CADA CLASE DE TITULAR, no suelta: `.tiene-marca` sola
   empata en especificidad con `.encabezado__titulo` y pierde por orden. Es el
   mismo empate que dejó las cápsulas de Admisiones invisibles hace dos horas.
   `.promesa__frase` se queda fuera a propósito: allí la mancha cae en el
   último renglón, no pisa nada, y Andrés dijo que ese interlineado está bien. */
.encabezado__titulo.tiene-marca,
.acto__declaracion.tiene-marca,
.parada__nombre.tiene-marca,
.tramo__nombre.tiene-marca,
.paso__nombre.tiene-marca,
.ruta-ficha__nombre.tiene-marca { line-height: 1.34; }

.encabezado__titulo {
  margin: 0;
  font-family: var(--fuente-titular);
  font-weight: var(--peso-titular);
  font-size: var(--display-2);
  line-height: var(--interlinea-titular);
  letter-spacing: var(--tracking-display);
  /* La medida manda la cuenta de renglones. Va en `em` a propósito. */
  width: min(100%, var(--medida, 17em));
  max-width: none;
  text-wrap: balance;
  color: #FFF;
}
.encabezado__entrada {
  margin: var(--e-6) 0 0;
  max-width: 58ch;
  font-size: var(--t-md);
  line-height: var(--interlinea-lead);
  color: var(--marino-tinte);
  text-wrap: pretty;
}
.encabezado__acciones {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--e-4);
  margin-top: clamp(var(--e-7), 5vw, var(--e-8));
}

/* En campo claro el encabezado cambia de tinta, no de forma. */
.es-clara .encabezado__antetitulo { color: var(--ceruleo-hondo); }
.es-clara .encabezado__titulo { color: var(--marino); }

/* EL CABEZOTE DE INTERNA SE QUEDA EN DISPLAY-2, Y ESTO SE PROBÓ ANTES DE
   DESCARTARLO (2026-09-10) ------------------------------------------------
   Lo natural, al poner orden en la escala, era darle display-1 al `h1` de cada
   interna: es el título de la página y debería ser el mayor. Se hizo, se midió
   a 1440 × 900 y se deshizo. Lo que sale al medir:

     /propuesta-educativa/secundaria/   6 renglones   665 px de titular
     /propuesta-educativa/media-futuro/ 6 renglones   665 px
     /colegio/, /admisiones/, …         5 renglones   532 px

   y tres secciones de Propuesta pasaban de 796 px —lo que se ve— a 891, 991 y
   1.157, o sea que el cabezote dejaba de caber en una pantalla, que es la regla
   que Andrés fijó el 2026-09-10.

   LA CAUSA NO ES EL TAMAÑO, ES EL COPY. El H1 de la portada son cinco palabras
   escritas para ser un enunciado; los cabezotes de interna son FRASES de once
   y trece —«Bienvenido al proceso de admisiones del Colegio Miguel de Cervantes
   Saavedra»—. Una frase así a 99 px no es un titular, es una columna de texto
   de seis renglones.

   Así que la escala se queda en dos tamaños, que es lo que pidió el cliente, y
   display-1 es la voz de la PORTADA. En una interna el rango del cabezote no lo
   marca la talla sino el sitio: pantalla propia, fotografía a sangre y
   antetítulo. Si algún día se quiere el cabezote de interna a escala de
   portada, lo que hay que cambiar es el copy —seis palabras, no trece—, y eso
   es de Manuel, no de la hoja de estilos. Queda anotado en ESTADO.md.        */
.es-clara .encabezado__entrada { color: var(--tinta-suave); }

/* El resaltado de titular: oro como SUPERFICIE con texto marino encima —6,7:1—,
   igual que «humanidad» en la portada. Nunca oro como color de letra. */
.encabezado__titulo .marca { font-weight: 700; }

/* ---- Cada sección ocupa una pantalla -------------------------------------
   Andrés: «cada espacio ocupa una parte en el viewfinder de la pantalla». No es
   `100svh` a secas: una sección con cuatro tarjetas altas debe poder crecer. Es
   un mínimo, y el contenido se centra dentro. */

/* 78svh Y NO 100, desde el 2026-09-10. Andrés marcó en verde el hueco entre la
   cabecera y el antetítulo, y medido a 1440 × 900 eran 202 px arriba y 202
   abajo. La causa no era el relleno: era que el cabezote pedía una pantalla
   ENTERA por debajo de una cabecera de 144 px, así que la primera pantalla
   medía 1.044 px en una ventana de 900. Es decir, 144 px del cabezote no se
   veían nunca y los dos botones quedaban pegados al filo.
   Con 78svh la primera pantalla cabe entera —846 px— y el hueco baja a 103.
   Si alguna vez cambia el alto de la cabecera, este número se vuelve a sacar
   midiendo: lo que se conserva es que el cabezote QUEPA. */
.pliego {
  position: relative;
  display: grid;
  align-content: center;
  /* EXACTAMENTE LO QUE SE VE, ni más ni menos. El 78svh de ayer resolvía que el
     cabezote cupiera, pero dejaba asomando una franja de la sección siguiente:
     Andrés la marcó en verde el 2026-09-10. Restando la cabecera pegajosa, cada
     sección ocupa el hueco visible entero y el paso de una a otra es limpio. */
  min-height: calc(100svh - var(--cabecera));
  padding-block: clamp(var(--e-8), 7vh, 6rem);
  overflow: clip;
}
.pliego--corto { min-height: auto; padding-block: clamp(var(--e-8), 8vh, var(--e-10)); }
/* El claro un paso más hondo. Existe para separar dos secciones claras
   seguidas sin recurrir al marino: en Admisiones, «¿Necesita orientación?» va
   entre las dos rutas —claro— y «El primer paso es conversar» —marino—, y
   pintarla de marino habría fundido las dos últimas en una sola franja oscura. */
.pliego--honda.es-clara { background: var(--campo-cielo-h); --campo-actual: var(--campo-cielo-h); }

.es-marino { background: var(--campo-marino); color: #FFF; }

/* EL COLOR DEL CAMPO, EXPUESTO COMO VARIABLE. Hace falta cuando una pieza tiene
   que TAPAR el fondo en el que está —el claro que abre el texto sobre el hilo
   del recorrido, por ejemplo— y no sabe de antemano en cuál cae. Sin esto habría
   que escribir la pieza dos veces, una por campo, que es justo el patrón que
   este sistema lleva tres correcciones intentando quitarse. */
.es-clara  { --campo-actual: var(--campo-cielo); }
.es-marino { --campo-actual: var(--campo-marino); }

/* ---- El pliego con fotografía al fondo -----------------------------------
   PRUEBA DEL 2026-09-09. Andrés: «está muy plano… una imagen grande de fondo,
   que la imagen caiga sobre el azul, con la opacidad, para que se lean los
   textos». Si funciona aquí, se replica en los demás encabezados de interna.

   EL VELO NO ES UN COLOR PLANO, y esa es toda la diferencia entre que esto se
   vea bien o se vea barato. Un marino al 82 % uniforme apaga la foto por igual
   en todas partes: se pierde el relieve y queda una mancha azul con ruido.
   Lo que hay son DOS capas:

     · un velo de marino que baja del 72 % al 92 % hacia abajo, para que la
       parte alta de la foto respire y el pie —donde caen los botones— sea
       sólido;
     · y una viñeta radial que cierra las esquinas.

   El resultado: la foto se ve donde no hay texto y desaparece donde lo hay, que
   es exactamente el mismo recurso que el plano de Contacto, al revés.

   LAS FOTOS DEL COLEGIO SON DE 1500 × 729. A pantalla completa hay que
   ampliarlas y se ablandan; con el velo encima no canta, pero si algún día el
   colegio entrega fotografía en condiciones, esto mejora solo. Está anotado en
   `assets/espacios/LEEME.md`.                                                */

.pliego--foto { position: relative; isolation: isolate; overflow: clip; }
.pliego__foto {
  position: absolute;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Al 42 % de altura: en las fotos del colegio el interés está por encima del
     centro —techos, ventanales, el fondo del espacio— y un recorte centrado se
     come justo eso. */
  object-position: 50% 42%;
}
.pliego--foto::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  background:
    radial-gradient(120% 88% at 50% 40%, rgba(28, 31, 74, 0.35) 0%, rgba(28, 31, 74, 0.86) 100%),
    linear-gradient(to bottom,
      rgba(42, 46, 104, 0.72) 0%,
      rgba(42, 46, 104, 0.86) 55%,
      rgba(28, 31, 74, 0.94) 100%);
}
/* Todo lo que no sea la foto y el velo sube por encima de los dos. */
.pliego--foto > .lienzo,
.pliego--foto > .urdimbre { position: relative; z-index: 2; }
/* La urdimbre pierde fuerza sobre una fotografía: sobre campo liso son hilos,
   sobre una foto son ruido encima de ruido. */
.pliego--foto > .urdimbre { opacity: 0.4; }

/* SOMBRA EN EL TEXTO, y es un seguro, no un adorno. El velo garantiza el
   contraste con esta foto —el auditorio es oscuro—, pero este componente está
   pensado para replicarse en las demás internas, y algunas fotos del colegio
   son claras: el aula de preescolar tiene una pared blanca a plena luz. Con una
   de ésas debajo, un velo al 72 % en la parte alta ya no bastaría.
   La sombra es lo que hace que el componente sea seguro CON CUALQUIER FOTO, que
   es la condición para poder replicarlo sin revisar una por una. */
.pliego--foto .encabezado__titulo,
.pliego--foto .encabezado__entrada,
.pliego--foto .encabezado__antetitulo { text-shadow: 0 2px 18px rgba(8, 10, 26, 0.55); }

/* EL ANTETÍTULO Y LA ENTRADA SUBEN A BLANCO SOBRE FOTOGRAFÍA, y esto no es
   gusto: es la cuenta del peor caso. Sobre campo marino liso, el antetítulo en
   #8FD0F0 y la entrada en #B3B8DC pasan de sobra. Sobre foto no, porque el velo
   mínimo es del 72 % y hay que suponer que debajo puede haber una zona blanca
   —el aula de preescolar tiene una pared a plena luz—:

     titular blanco        5,28:1   pasa
     antetítulo #8FD0F0    3,13:1   NO PASA
     entrada  #B3B8DC      2,72:1   NO PASA

   En blanco, 5,28:1 y 4,76:1. Es lo que permite replicar el componente en
   veintiún encabezados sin comprobar foto por foto, que era la condición.
   La alternativa —subir el velo al 88 %— apagaba la foto hasta dejarla en nada,
   que es justo lo que veníamos a arreglar. */
.pliego--foto .encabezado__antetitulo { color: #FFF; }
.pliego--foto .encabezado__entrada { color: rgba(255, 255, 255, 0.92); }
/* El resaltado en oro NO lleva sombra: es una superficie sólida con marino
   encima, y una sombra ahí se vería como una mancha sucia bajo la letra. */
.pliego--foto .encabezado__titulo .marca { text-shadow: none; }

@media (prefers-reduced-motion: no-preference) {
  /* Un acercamiento lentísimo mientras se lee: doce segundos para un 4 %. No se
     ve moverse, se nota que está viva. */
  .pliego__foto { animation: respirar-foto 24s ease-in-out infinite alternate; }
}
@keyframes respirar-foto {
  from { scale: 1; }
  to   { scale: 1.04; }
}
.es-clara  { background: var(--campo-cielo);  color: var(--tinta); }

/* d) Nada blanco sobre claro. */
.es-clara .enlace-accion { color: var(--ceruleo-hondo); border-bottom-color: rgba(0, 100, 143, 0.4); }
.es-clara .enlace-accion:hover { color: var(--marino); border-bottom-color: var(--marino); }




/* ---- Bloque de dos columnas: enunciado y explicación --------------------- */

.doble {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
  gap: clamp(var(--e-6), 5vw, var(--e-9));
  align-items: start;
  margin-top: clamp(var(--e-7), 5vw, var(--e-8));
}
.doble__cuerpo {
  margin: 0;
  font-size: var(--t-md);
  line-height: var(--interlinea-lead);
  color: var(--tinta-suave);
  max-width: 56ch;
  text-wrap: pretty;
}
.es-marino .doble__cuerpo { color: var(--marino-tinte); }
.doble__acciones { display: flex; flex-wrap: wrap; gap: var(--e-3) var(--e-6); margin: var(--e-6) 0 0; }

/* ---- Las dos rutas de admisión ------------------------------------------ */

.rutas__duda {
  margin: clamp(var(--e-8), 7vw, var(--e-10)) auto 0;
  padding-top: clamp(var(--e-6), 4vw, var(--e-8));
  border-top: var(--hilo-fino) solid var(--lana-honda);
  max-width: 62ch;
  text-align: center;
}
.rutas__duda-titulo {
  margin: 0 0 var(--e-3);
  font-family: var(--fuente-titular);
  font-weight: var(--peso-titular);
  font-size: var(--t-base);
  letter-spacing: -0.01em;
  color: var(--marino);
}
.rutas__duda-cuerpo { margin: 0 0 var(--e-3); font-size: var(--t-sm); line-height: 1.6; color: var(--tinta-suave); }
.rutas__duda-acciones { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--e-3) var(--e-6); margin: 0; }

/* ---- Los valores --------------------------------------------------------- */


/* ---- LOS SIGNOS DE LOS TRES VALORES (2026-09-10) ------------------------
   Andrés pidió «un ícono bien bonito» para cada uno. No se trajo un juego de
   iconos de fuera, y ésa es la decisión que importa: este sistema entero está
   hecho de DOS FORMAS —el círculo y el hilo recto—, así que los tres signos se
   dibujan con esas dos y nada más. Un juego comprado, por bonito que fuera,
   metería una tercera mano de dibujo en la única página donde ya conviven las
   ilustraciones de Andrés.

   Y cada uno dice lo que nombra, no lo decora:
     · Rectitud    — el hilo A PLOMO cruzando el círculo. Rectitud es urdimbre.
     · Sabiduría   — la lente: un círculo que mira DENTRO de otro.
     · Humanidad   — dos círculos que se cruzan y comparten un trozo. Es el
                     mismo par de aros de la senda, dos que se encuentran.

   Se trazan con el scroll, como los aros de la senda y los anillos de la Home.
   `pathLength="1"` en el marcado permite que el mismo `dasharray: 1` valga para
   círculos y rectas de longitudes muy distintas. */
.eje__signo { display: block; margin-bottom: var(--e-5); }
/* Los valores y los documentos usan ahora la tarjeta en claro (`.puerta--clara`),
   así que de aquí sólo queda el eje. El signo de un eje hereda el cerúleo del bloque; en campo marino aclara,
   porque el cerúleo sobre marino se apaga. */
.eje__signo .signo { color: var(--ceruleo); }
.es-marino .eje__signo .signo { color: #8FD0F0; }
.signo {
  display: block;
  width: clamp(2.6rem, 4.4vw, 3.4rem);
  height: auto;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.4;
  stroke-linecap: round;
  overflow: visible;
}
.signo__aro--menor { stroke-width: 2; }

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .eje, .paso { view-timeline-name: --signo; }
    .signo__aro, .signo__hilo {
      stroke-dasharray: 1;
      animation: trazar-signo linear both;
      animation-timeline: --signo;
      animation-range: entry 25% entry 85%;
    }
    /* El aro grande primero y lo que va dentro después: dibujados a la vez, los
       tres signos se leen como un parpadeo en vez de como un trazo. */
    .signo__hilo, .signo__aro--menor { animation-range: entry 45% cover 8%; }
    .signo__aro { transform: rotate(-90deg); transform-box: fill-box; transform-origin: 50% 50%; }
  }
}
@keyframes trazar-signo { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }

/* ---- El signo de un paso (2026-09-14) ------------------------------------
   Encima del título, dentro del dicho, así que hereda su alineación: en los
   pasos impares queda pegado a la línea por la derecha, en los pares por la
   izquierda. El nudo con la cifra no se toca. */
.paso__signo { display: block; margin-bottom: var(--e-2); }
.paso__signo .signo { color: var(--ceruleo); }
.es-marino .paso__signo .signo { color: #8FD0F0; }

/* ---- La entrada sola en su pantalla ---------------------------------------
   Cuando el párrafo de entrada es lo único que hay en la sección, a la talla
   de subtítulo se pierde. Sube a lead y va en marino, que es la voz del sitio. */
.encabezado__entrada.encabezado__entrada--sola {
  margin-top: 0;
  max-width: 40ch;
  font-size: clamp(1.3rem, 2.2vw, 1.75rem);
  line-height: 1.45;
  color: var(--marino);
  text-wrap: balance;
}


/* ---- EL ÍNDICE DEL AÑO (Familias) ----------------------------------------
   Aquí había cuatro tarjetas blancas. Fuera el 2026-09-08, por pedido de Andrés
   y con razón: la página YA es campo claro, así que cuatro cajas blancas encima
   añadían un segundo nivel de superficie sin decir nada nuevo, y las cuatro
   pesaban lo mismo, que es lo que una tarjeta hace mal cuando hay que ordenar.

   Lo que sostiene esta versión no es la forma sino EL ORDEN: los cuatro
   renglones van de lo que más cambia —una circular, toda la semana— a lo que no
   cambia nunca —el uniforme—, y cada uno lo dice. Eso es lo que le ahorra a una
   madre la llamada al colegio, y es lo que convierte un directorio en un
   consejo.

   La cifra va EN CONTORNO y se rellena al señalarla. Es el mismo gesto que el
   anillo que se traza en la ruta o el hilo de oro que se dibuja bajo un nombre:
   una forma vacía que se completa. Y el renglón entero es el enlace, no un
   «ver más» de 90 px al pie.                                                  */

.indice-anio {
  margin: clamp(var(--e-7), 5vw, var(--e-8)) 0 0;
  padding: 0;
  list-style: none;
  /* El hilo de arriba cierra el índice por su borde superior; los de abajo los
     pone cada entrada. Así el bloque se lee como una tabla y no como cuatro
     párrafos sueltos. */
  border-top: var(--hilo-fino) solid rgba(42, 46, 104, 0.18);
}

/* ---- EL MISMO ÍNDICE, SIN ENLACE Y EN CAMPO MARINO (2026-09-18) ----------
   Andrés, viendo «Proyectos pedagógicos institucionales»: que se lea como «Qué
   consultar, y cada cuánto cambia» de Familias —uno debajo de otro, a lo largo—
   pero sobre el marino de esa sección. Y tiene razón: cuatro proyectos en dos
   columnas se leen como cuatro fichas sueltas; en renglones se leen como lo que
   son, un REGISTRO.

   LOS PROYECTOS NO LLEVAN A NINGUNA PÁGINA, así que la fila NO es un enlace:
   `.entrada__fila` es la misma rejilla sin nada que prometa un destino —sin
   flecha, sin relleno al pasar el ratón, sin foco—. Prometer un clic que no
   existe es el error que este sistema ya evitó en las tarjetas de Cobertura. */
.indice-anio--registro { border-top-color: rgba(255, 255, 255, 0.22); }
.entrada__fila {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: clamp(var(--e-5), 3vw, var(--e-7));
  align-items: center;
  padding: clamp(var(--e-5), 2.6vw, var(--e-6)) 0;
  border-bottom: var(--hilo-fino) solid rgba(255, 255, 255, 0.22);
}
/* Sobre marino, las tintas del índice cambian y nada más: la cifra en contorno
   pasa al cerúleo claro —el cerúleo hondo se apaga contra el marino— y el
   nombre a blanco. */
.es-marino .entrada__cifra { -webkit-text-stroke-color: #8FD0F0; }
@supports not (-webkit-text-stroke: 1px currentColor) {
  .es-marino .entrada__cifra { color: #8FD0F0; }
}
/* Aquí el nombre es un `<h3>` de verdad —cuatro proyectos son cuatro
   encabezados, no cuatro frases sueltas— y hay que quitarle el margen que la
   base le da a los titulares. */
.entrada__fila .entrada__nombre { margin: 0; }
.es-marino .entrada__nombre { color: #FFF; }
.es-marino .entrada__texto { color: var(--marino-tinte); }
.es-marino .entrada__rotulo { color: #8FD0F0; }
.es-marino .entrada__cadencia { color: #FFF; }

.entrada__enlace {
  position: relative;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto auto;
  gap: clamp(var(--e-5), 3vw, var(--e-7));
  align-items: center;
  padding: clamp(var(--e-5), 2.6vw, var(--e-6)) 0;
  border-bottom: var(--hilo-fino) solid rgba(42, 46, 104, 0.18);
  color: inherit;
  text-decoration: none;
  transition: background var(--dur-media) var(--sale);
}
/* El hilo que se teje: se dibuja de izquierda a derecha sobre el filete gris,
   igual que el orillo de oro bajo la ficha de un docente. */
.entrada__enlace::after {
  content: '';
  position: absolute;
  inset: auto auto -1px 0;
  width: 100%;
  height: var(--hilo-trama);
  background: var(--ceruleo);
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform 620ms var(--sale);
}
.entrada__enlace:hover,
.entrada__enlace:focus-visible {
  /* A sangre por los dos lados: el campo entra por debajo del canal del lienzo,
     así el renglón señalado se lee como una franja y no como un rectángulo
     metido dentro de la retícula —que es la caja que acabamos de quitar—. */
  background: var(--campo-cielo-h);
  box-shadow: calc(-1 * var(--canal)) 0 0 var(--campo-cielo-h),
              var(--canal) 0 0 var(--campo-cielo-h);
}
.entrada__enlace:hover::after,
.entrada__enlace:focus-visible::after { transform: scaleX(1); }
.entrada__enlace:focus-visible { outline: var(--hilo-trama) solid var(--oro); outline-offset: 2px; }

.entrada__cifra {
  font-family: var(--fuente-titular);
  font-weight: var(--peso-titular);
  font-size: clamp(2.4rem, 5vw, 4.2rem);
  line-height: 0.9;
  letter-spacing: var(--tracking-display);
  /* Contorno, no relleno: la cifra ordena pero no debe pesar más que el nombre
     de lo que ordena. Al señalar el renglón se rellena. */
  color: transparent;
  -webkit-text-stroke: 2px var(--ceruleo);
  font-variant-numeric: tabular-nums lining-nums;
  transition: color var(--dur-media) var(--sale);
}
/* RESPALDO, y no es teórico: `-webkit-text-stroke` no es propiedad estándar. En
   un navegador que no la traiga, `color: transparent` se queda solo y las cuatro
   cifras del índice DESAPARECEN — no se ven mal, no se ven. Con `@supports` en
   negativo, ahí van rellenas y el índice sigue numerado.
   Lo cazó el barrido de contraste del 2026-09-09, que las marcó a 1:1 contra el
   fondo. Era un falso positivo suyo —el contorno sí se ve— pero apuntaba a un
   riesgo verdadero, así que la señal era buena aunque el motivo no. */
@supports not (-webkit-text-stroke: 1px currentColor) {
  .entrada__cifra { color: var(--ceruleo); }
}
.entrada__enlace:hover .entrada__cifra,
.entrada__enlace:focus-visible .entrada__cifra { color: var(--ceruleo); }

.entrada__cuerpo { display: grid; gap: var(--e-2); }
.entrada__nombre {
  font-family: var(--fuente-titular);
  font-weight: var(--peso-titular);
  font-size: clamp(1.15rem, 1.9vw, 1.6rem);
  line-height: 1.14;
  letter-spacing: var(--tracking-titular);
  color: var(--marino);
  text-wrap: balance;
}
.entrada__texto {
  font-size: var(--t-sm);
  line-height: 1.5;
  color: var(--tinta-suave);
  max-width: 52ch;
}

/* El ritmo va al filo derecho, alineado a la derecha: los cuatro forman una
   columna que se lee de un vistazo, que es de lo que trata la seccion. */
.entrada__ritmo { display: grid; gap: var(--e-1); text-align: right; }
.entrada__rotulo { color: var(--ceruleo-hondo); }
.entrada__cadencia {
  font-size: var(--t-sm);
  line-height: 1.3;
  color: var(--marino);
  font-weight: 700;
}

.entrada__flecha {
  display: grid;
  place-items: center;
  width: 1.4rem;
  color: var(--ceruleo-hondo);
  transition: transform var(--dur-media) var(--sale);
}
.entrada__flecha svg { width: 1.1rem; height: 1.1rem; }
.entrada__enlace:hover .entrada__flecha,
.entrada__enlace:focus-visible .entrada__flecha { transform: translateX(0.4rem); }

@media (prefers-reduced-motion: reduce) {
  .entrada__enlace::after, .entrada__flecha, .entrada__cifra { transition: none; }
}

.plataforma__aviso { display: grid; gap: var(--e-4); justify-items: start; margin: var(--e-6) 0 0; }
.plataforma__nota { margin-top: var(--e-5); color: var(--marino-tinte); }

/* ---- Ubicación y canales: el plano, y los datos encima ------------------
   REHECHO EL 2026-09-09. Antes había un rayado tenue de fondo y tres tarjetas
   blancas encima. Andrés pidió las dos cosas al revés: que el plano se vea de
   verdad y que los datos caigan sobre él, sin caja.

   EL PLANO NO ES UN MAPA, y por eso no lleva nombres, ni norte, ni escala: las
   tres cosas invitarían a orientarse con él y no se puede. Es la idea de una
   trama urbana —manzanas, vías, una troncal en diagonal, un parque— dibujada
   con los mismos hilos del sistema, con un nudo de oro donde está el colegio.
   El mapa de verdad está a un clic, en «Cómo llegar».

   EL PROBLEMA DE QUITAR LA CAJA es que la caja era lo que garantizaba que el
   texto se leyera. Sin ella hay dos maneras de resolverlo, y sólo una es buena:

     · Bajar el plano hasta que no estorbe. Entonces no se ve, y volvemos al
       rayado de antes.
     · DESVANECER EL PLANO SÓLO DONDE CAE EL TEXTO. El plano vive fuerte en los
       bordes y se apaga por el centro, con una máscara. Se ve el mapa, se lee
       el dato, y no hay ni una caja.

   Va la segunda. La máscara es la misma herramienta que apaga el aura del
   tablón por los bordes; aquí se usa al revés.                               */

/* ONDAS DESDE UN PUNTO, no un plano (2026-09-10, segunda pasada).
   El cliente pidió que el fondo fuera menos notorio. La primera respuesta fue
   tumbar el plano en perspectiva y bajarle el tono; se veía mejor pero el
   problema de fondo seguía: era una trama de calles INVENTADA —el colegio no
   nos ha dado coordenadas— en la página cuyo trabajo es decir dónde estamos.
   Un mapa que no se puede seguir no es un mapa discreto, es un mapa falso.

   Lo que hay ahora son aros que salen del nudo de oro y se van por los bordes.
   Dice «aquí estamos, y desde aquí se llega» sin dibujar una sola calle que no
   exista, y usa la forma que manda en toda la web. De paso, Contacto deja de
   ser la única página con vocabulario gráfico propio.

   TRES DECISIONES QUE SOSTIENEN ESTO:
     · Los aros están CORTADOS por los bordes. Completos y concéntricos serían
       una diana; cortados, un campo.
     · Se trazan con el scroll y escalonados por `--turno`, de dentro afuera:
       es la onda saliendo, no ocho círculos apareciendo.
     · El nudo conserva su latido. Es lo único que se mueve solo en la página y
       es donde queremos que se mire.

   Si algún día el colegio da coordenadas, aquí entra un mapa de verdad. */

.canales-suelo {
  position: absolute;
  inset: 0;
  overflow: clip;
  pointer-events: none;
  /* Apagado en la banda central, donde caen el titular y los tres datos. Sin
     esto habría que ponerles una caja debajo, que es lo que se quitó el 09. */
  -webkit-mask-image: radial-gradient(78% 50% at 50% 50%,
              transparent 0%, transparent 26%, #000 82%);
  mask-image: radial-gradient(78% 50% at 50% 50%,
              transparent 0%, transparent 26%, #000 82%);
}
.canales-fondo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  color: var(--ceruleo);
}
.canales-fondo .onda-aro {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.4;
  /* Los de fuera, más tenues: es lo que convierte ocho circunferencias iguales
     en una onda que se va apagando al alejarse. */
  stroke-opacity: calc(0.3 - var(--turno) * 0.028);
}

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .canales-suelo { view-timeline-name: --ondas; }
    .canales-fondo .onda-aro {
      stroke-dasharray: 1;
      animation: trazar-onda linear both;
      animation-timeline: --ondas;
      /* Cada aro arranca un 6 % después del anterior: de dentro afuera, que es
         como se propaga una onda. Ocho a la vez serían un parpadeo. */
      animation-range: calc(var(--turno) * 6%) calc(60% + var(--turno) * 5%);
    }
  }
}
@keyframes trazar-onda { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }

/* El nudo, en su propia capa y sin máscara: se coloca en el mismo punto del
   que salen los aros —19 % y 65 %—, así que si alguien mueve el centro de las
   ondas tiene que mover estos dos números con él. Van juntos. */
.canales-nudo {
  position: absolute;
  left: 8%;
  top: 26%;
  width: clamp(5rem, 9vw, 7.5rem);
  height: auto;
  translate: -50% -50%;
  overflow: visible;
}
.canales-fondo .plano__nudo,
.canales-nudo .plano__nudo { fill: var(--oro); }
.canales-nudo .plano__onda { fill: none; stroke: var(--oro); stroke-width: 2.4; opacity: 0.5; }
/* El nudo se queda como estaba de fuerte: es lo único que el plano tiene que
   decir —«el colegio está aquí»— y apagarlo con lo demás lo habría borrado. */
.canales-fondo .plano__onda { fill: none; stroke: var(--oro); stroke-width: 2.2; opacity: 0.55; }

@media (prefers-reduced-motion: no-preference) {
  /* Las dos ondas del nudo laten muy despacio y desacompasadas: es lo único que
     se mueve en toda la página, y es donde queremos que se mire. */
  .canales-nudo .plano__onda { animation: latir-nudo 4.5s ease-in-out infinite; transform-origin: center; }
  .canales-nudo .plano__onda:nth-child(2) { animation-delay: -2.2s; }
}
@keyframes latir-nudo {
  0%, 100% { opacity: 0.5;  scale: 1; }
  50%      { opacity: 0.14; scale: 1.16; }
}

/* ---- Los tres datos, sin caja ------------------------------------------- */

.canales {
  position: relative;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: 0;
  margin: clamp(var(--e-8), 6vw, var(--e-9)) 0 0;
  padding: 0;
  list-style: none;
}
/* Lo que separa un dato del siguiente es un HILO, no un borde de tarjeta. Y el
   filete de oro que remataba cada caja se convierte en uno solo, continuo,
   sobre los tres: es el mismo gesto de «Indicadores». */
.canal {
  padding: var(--e-6) clamp(var(--e-4), 2.4vw, var(--e-6)) var(--e-5);
  border-top: var(--hilo-orillo) solid var(--oro);
}
.canal + .canal { border-left: var(--hilo-fino) solid rgba(42, 46, 104, 0.16); }
.canal:first-child { padding-left: 0; }
.canal:last-child  { padding-right: 0; }

.canal__icono { width: 2.2rem; height: 2.2rem; margin-bottom: var(--e-4); color: var(--ceruleo-hondo); }
.canal__rotulo { display: block; margin: 0 0 var(--e-3); color: var(--tinta-suave); }
.canal__valor {
  margin: 0 0 var(--e-3);
  max-width: none;
  font-family: var(--fuente-titular);
  font-weight: var(--peso-titular);
  font-size: var(--t-md);
  line-height: 1.24;
  letter-spacing: -0.02em;
}
.canal__valor a { color: var(--marino); text-decoration: none; }
.canal__valor a:hover { color: var(--ceruleo-hondo); }
.canal__coda {
  margin: 0;
  color: var(--ceruleo-hondo);
  padding-bottom: 2px;
  border-bottom: var(--hilo-fino) solid rgba(0, 100, 143, 0.4);
  display: inline-block;
}

/* NOTA DE COLOCACIÓN (2026-09-10): este bloque va AQUÍ, delante de las
   consultas de medios, y no al final del archivo. Se restauró pegándolo al
   final y las reglas base ganaban a los ajustes de móvil que viven más arriba:
   los cuatro pasos seguían en tres columnas a 390 px, con el texto en cuchillas
   de 131 px. En CSS el orden ES la regla; un bloque de bases por debajo de sus
   propios overrides los anula en silencio. */

/* ==========================================================================
   RESTAURADO EL 2026-09-10 — LEER ANTES DE TOCAR
   --------------------------------------------------------------------------
   Todo lo que sigue existía y DESAPARECIÓ el 2026-09-09 en el commit 1f24dc0:
   537 líneas borradas de un archivo al que se le añadían 200. Fue una edición
   con `s.index()` mal acotada que en vez de sustituir una región se llevó por
   delante el bloque entero de la segunda tanda.

   El síntoma no era visible desde el CSS: las páginas seguían abriendo. Lo que
   quedó vivo fueron sólo las CONSULTAS DE MEDIOS de estas piezas —los ajustes
   de móvil— sin las reglas base que corregían, así que en el escritorio los
   pasos, los documentos, las preguntas y los avales salían como HTML crudo:
   viñetas del navegador, «1. 01», titulares a tamaño de sistema. Andrés lo fue
   encontrando página por página durante dos días.

   LA LECCIÓN, que vale más que el arreglo: un borrado masivo en un archivo que
   nadie lee entero no lo caza ninguno de los barridos que tenemos. Ni el de
   contraste ni el de desbordes miran si una regla EXISTE. Lo que sí lo habría
   cazado es lo que se hizo hoy para encontrarlo: contar las clases del marcado
   y comprobar cuáles no tienen ni una regla. Está en ESTADO.md como paso fijo
   antes de dar por terminada una sesión.

   No se restauró `.telar-vida` ni `.hito`/`.linea` —son la sección de Vida
   Cervantista que ya sustituyó la senda— ni `.nomina-larga`/`.perfil`, que se
   rehicieron hoy en reja y no en renglones.
   ========================================================================== */

/* ==========================================================================
   LOS PATRONES DE LA SEGUNDA TANDA (2026-09-08)
   --------------------------------------------------------------------------
   Quince páginas nuevas, y NINGUNA lleva tarjeta blanca. Andrés lo pidió el
   2026-09-08 —«algo que no esté metido en cards»— y a estas alturas es una
   regla del sistema, no una preferencia: estas páginas viven casi todas sobre
   campo cielo, que YA es una superficie. Poner cajas blancas encima añade un
   segundo nivel de superficie para no decir nada nuevo, y hace que seis piezas
   pesen exactamente lo mismo cuando lo que había que hacer era ordenarlas.

   Lo que separa una pieza de otra en todo lo que sigue es EL HILO, que es como
   este tejido separa las cosas desde el primer día.
   ========================================================================== */

/* ---- Ejes: bloques de igual rango ---------------------------------------
   Para listas donde ninguna pieza manda sobre las otras: los ejes de una etapa,
   los órganos de gobierno, los tres papeles de la cobertura. Cada uno lleva un
   remate de trama arriba —el mismo orillo de «Indicadores»— y nada más.        */

.ejes {
  display: grid;
  grid-template-columns: repeat(var(--columnas, 2), minmax(0, 1fr));
  gap: 0;
  margin: clamp(var(--e-7), 5vw, var(--e-8)) 0 0;
  padding: 0;
  list-style: none;
}
.eje {
  display: grid;
  align-content: start;
  gap: var(--e-3);
  padding: var(--e-6) clamp(var(--e-4), 2.4vw, var(--e-6)) var(--e-5);
  border-top: var(--hilo-orillo) solid var(--ceruleo);
}
/* Sin hueco entre columnas: los remates se tocan y forman una sola línea sobre
   toda la fila, igual que en «Indicadores». Lo que divide es el hilo vertical. */
.eje + .eje { border-left: var(--hilo-fino) solid rgba(42, 46, 104, 0.16); }
.es-marino .eje + .eje { border-left-color: rgba(255, 255, 255, 0.2); }
/* La primera de cada fila no lleva hilo a la izquierda: sería un filo suelto
   contra el margen. Se apaga por columna, no por posición en la lista, para que
   funcione igual con dos, tres o cuatro columnas. */
.ejes[style*="--columnas: 2"] .eje:nth-child(2n+1),
.ejes[style*="--columnas: 3"] .eje:nth-child(3n+1),
.ejes[style*="--columnas: 4"] .eje:nth-child(4n+1) { border-left: 0; padding-left: 0; }

.eje__marca { color: var(--ceruleo-hondo); }
.es-marino .eje__marca { color: #8FD0F0; }
.eje__nombre {
  margin: 0;
  font-family: var(--fuente-titular);
  font-weight: var(--peso-titular);
  font-size: var(--t-md);
  line-height: 1.16;
  letter-spacing: -0.025em;
  color: var(--marino);
  text-wrap: balance;
}
.es-marino .eje__nombre { color: #FFF; }
.eje__cuerpo { margin: 0; font-size: var(--t-sm); line-height: 1.6; color: var(--tinta-suave); }
.es-marino .eje__cuerpo { color: var(--marino-tinte); }

/* ---- Pasos: un proceso, con su hilo ------------------------------------
   Los pasos SÍ tienen orden, y por eso no son ejes: llevan cifra y un hilo
   vertical que los enhebra. Es la línea de tiempo de las internas puesta de
   pie, y el hilo se corta en el último paso —no sigue hacia abajo hacia nada—. */

.pasos {
  display: grid;
  gap: 0;
  margin: clamp(var(--e-7), 5vw, var(--e-8)) 0 0;
  padding: 0;
  list-style: none;
  counter-reset: paso;
}
/* ---- LA LÍNEA DEL TIEMPO, ALTERNADA (2026-09-10) ------------------------
   Andrés lo pidió así: el paso 01 a la izquierda, el 02 a la derecha, el 03 a
   la izquierda, el 04 a la derecha, y las cifras EN LA MITAD de los dos.
   «Para que cuente como una historia», y tiene razón: en una sola columna los
   cuatro pasos se leen como una lista de requisitos; alternando, el ojo baja en
   zigzag y el recorrido se nota. Es el mismo gesto que la senda de Vida
   Cervantista —lo que enhebra allí una ilustración aquí enhebra un paso—, sólo
   que aquí el hilo va recto porque un proceso administrativo no serpentea.

   TRES COLUMNAS y el nudo siempre en la del medio. El texto cambia de columna
   con `:nth-child(even)`, y con él la alineación: en los impares el párrafo se
   alinea a la DERECHA para quedar pegado al hilo, y en los pares a la
   izquierda. Un texto alineado al lado contrario dejaría un río blanco entre él
   y la línea, y la línea dejaría de leerse como el eje de la historia. */
.paso {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: start;
  gap: clamp(var(--e-5), 3vw, var(--e-7));
  padding: 0 0 clamp(var(--e-7), 5vw, var(--e-9));
}
.paso__cifra { grid-column: 2; grid-row: 1; }
.paso__dicho { grid-column: 3; grid-row: 1; }
.paso:nth-child(odd) .paso__dicho {
  grid-column: 1;
  text-align: right;
  justify-items: end;
}

/* El hilo baja por el eje del nudo, que ahora es el eje de la sección entera.
   Arranca bajo el nudo y termina en el siguiente; el último no lo lleva. */
.paso:not(:last-child)::before {
  content: '';
  position: absolute;
  left: 50%;
  translate: -50% 0;
  top: var(--nudo, 2.9rem);
  bottom: 0;
  width: var(--hilo-trama);
  background: var(--ceruleo);
  opacity: 0.45;
}
.es-marino .paso:not(:last-child)::before { background: #8FD0F0; }

.paso__cifra {
  --nudo: clamp(2.4rem, 4vw, 2.9rem);
  display: grid;
  place-items: center;
  width: var(--nudo);
  height: var(--nudo);
  border-radius: 50%;
  border: var(--hilo-trama) solid var(--ceruleo);
  color: var(--ceruleo-hondo);
  font-family: var(--fuente-codigo);
  font-size: var(--t-xs);
  font-weight: 700;
  letter-spacing: 0.06em;
  font-variant-numeric: tabular-nums;
}
.es-marino .paso__cifra { border-color: #8FD0F0; color: #FFF; }
.paso__dicho { display: grid; gap: var(--e-3); align-content: start; padding-top: 0.2rem; }
.paso__nombre {
  margin: 0;
  font-family: var(--fuente-titular);
  font-weight: var(--peso-titular);
  font-size: var(--t-md);
  line-height: 1.16;
  letter-spacing: -0.025em;
  color: var(--marino);
  text-wrap: balance;
}
.es-marino .paso__nombre { color: #FFF; }
.paso__cuerpo { margin: 0; max-width: 46ch; font-size: var(--t-base); line-height: 1.6; color: var(--tinta-suave); }
.es-marino .paso__cuerpo { color: var(--marino-tinte); }
/* El nudo, más grande y con la cifra dentro: es lo único que se ve en el eje y
   tiene que sostener la mirada mientras se baja. */
.paso__cifra { background: var(--campo-actual, transparent); z-index: 1; }
.es-marino .paso__cuerpo { color: var(--marino-tinte); }

/* ---- El banco de preguntas ---------------------------------------------
   `<details>` nativo y no un acordeón de guion: el navegador ya trae la
   apertura, el cierre, el teclado y el anuncio al lector de pantalla. Y sin
   JavaScript las cinco respuestas siguen ahí, que es lo que importa cuando
   alguien cae en esta página desde un buscador.                              */

.banco {
  margin: clamp(var(--e-7), 5vw, var(--e-8)) 0 0;
  border-top: var(--hilo-fino) solid rgba(42, 46, 104, 0.18);
}
.pregunta { border-bottom: var(--hilo-fino) solid rgba(42, 46, 104, 0.18); }
.pregunta__enunciado {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--e-5);
  align-items: center;
  padding: clamp(var(--e-4), 2.4vw, var(--e-5)) 0;
  font-family: var(--fuente-titular);
  font-weight: var(--peso-titular);
  font-size: clamp(1.05rem, 1.6vw, 1.3rem);
  line-height: 1.24;
  letter-spacing: -0.02em;
  color: var(--marino);
  cursor: pointer;
  list-style: none;
  transition: color var(--dur-corta) var(--sale);
}
.pregunta__enunciado::-webkit-details-marker { display: none; }
.pregunta__enunciado:hover { color: var(--ceruleo-hondo); }
.pregunta__enunciado:focus-visible { outline: var(--hilo-trama) solid var(--oro); outline-offset: 2px; }
/* La cruz que se vuelve raya: es un signo de más girando 45°, no una flecha.
   Dos hilos cruzados, que es de lo que está hecho todo lo demás. */
.pregunta__enunciado::after {
  content: '';
  width: 1rem;
  height: 1rem;
  background:
    linear-gradient(var(--ceruleo), var(--ceruleo)) center / 100% var(--hilo-trama) no-repeat,
    linear-gradient(var(--ceruleo), var(--ceruleo)) center / var(--hilo-trama) 100% no-repeat;
  transition: transform var(--dur-media) var(--sale);
}
.pregunta[open] .pregunta__enunciado::after { transform: rotate(45deg); }
.pregunta[open] .pregunta__enunciado { color: var(--ceruleo-hondo); }
.pregunta__respuesta {
  margin: 0 0 var(--e-6);
  max-width: 68ch;
  font-size: var(--t-base);
  line-height: var(--interlinea-texto);
  color: var(--tinta-suave);
}

/* ---- Papeles: documentos que todavía no se pueden enlazar ---------------- */

.papeles {
  margin: clamp(var(--e-7), 5vw, var(--e-8)) 0 0;
  padding: 0;
  list-style: none;
  border-top: var(--hilo-fino) solid rgba(255, 255, 255, 0.22);
}
.papel {
  display: grid;
  grid-template-columns: minmax(0, 16rem) minmax(0, 1fr) auto;
  gap: var(--e-3) clamp(var(--e-5), 3vw, var(--e-7));
  align-items: baseline;
  padding: clamp(var(--e-5), 2.6vw, var(--e-6)) 0;
  border-bottom: var(--hilo-fino) solid rgba(255, 255, 255, 0.22);
}
.papel__marca { grid-column: 1; color: #8FD0F0; }
.papel__nombre {
  grid-column: 2;
  margin: 0;
  font-family: var(--fuente-titular);
  font-weight: var(--peso-titular);
  font-size: var(--t-md);
  line-height: 1.16;
  letter-spacing: -0.025em;
  color: #FFF;
  text-wrap: balance;
}
.papel__cuerpo {
  grid-column: 2;
  margin: 0;
  max-width: 62ch;
  font-size: var(--t-sm);
  line-height: 1.6;
  color: var(--marino-tinte);
}
.papel__estado {
  grid-column: 3;
  grid-row: 1;
  color: var(--oro);
  text-align: right;
}

/* ---- Avales: los indicadores, sin caja ---------------------------------- */

.avales {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: 0;
  margin: clamp(var(--e-7), 5vw, var(--e-8)) 0 clamp(var(--e-6), 4vw, var(--e-7));
  padding: 0;
  list-style: none;
}
.aval {
  display: grid;
  align-content: start;
  gap: var(--e-3);
  padding: var(--e-6) clamp(var(--e-4), 2.6vw, var(--e-7)) var(--e-4);
  /* El oro aquí es SUPERFICIE, no texto: sobre campo claro da 1,65:1 y sería
     ilegible. Lo que se lee en color es el código, en cerúleo hondo (5,3:1). */
  border-top: var(--hilo-orillo) solid var(--oro);
}
.aval + .aval { border-left: var(--hilo-fino) solid rgba(42, 46, 104, 0.16); }
.aval:first-child { padding-left: 0; }
.aval:last-child { padding-right: 0; }
.aval__sello { display: flex; align-items: center; min-height: 2.9rem; margin-bottom: var(--e-2); }
.aval__cifra {
  margin: 0;
  font-family: var(--fuente-titular);
  font-size: clamp(3rem, 5.6vw, 4.6rem);
  font-weight: var(--peso-titular);
  line-height: 0.84;
  letter-spacing: var(--tracking-display);
  color: var(--marino);
  font-variant-numeric: tabular-nums lining-nums;
}
.aval__nombre {
  margin: 0;
  font-size: var(--t-base);
  font-weight: var(--peso-titular);
  line-height: 1.24;
  letter-spacing: 0;
  color: var(--marino);
  text-wrap: balance;
}
.aval__cuerpo { margin: 0; max-width: 36ch; font-size: var(--t-sm); line-height: 1.55; color: var(--tinta-suave); }
.aval__codigo {
  margin: var(--e-3) 0 0;
  padding-top: var(--e-3);
  border-top: var(--hilo-fino) solid var(--lana-honda);
  color: var(--ceruleo-hondo);
}
.avales__cierre { display: flex; justify-content: center; }

/* ---- El vacío declarado -------------------------------------------------
   Tres de las páginas nuevas son repositorios que el colegio todavía no ha
   surtido: circulares, calendario y listas. La tentación es maquetarlas con
   ejemplos. Sería mentir justo en la página donde una familia viene a saber qué
   comprar o cuándo empiezan las clases. Así que el vacío se declara, con su
   código de gobierno al lado para que se vea que está previsto y no olvidado. */

.sin-piezas {
  display: grid;
  gap: var(--e-3);
  justify-items: center;
  margin: clamp(var(--e-7), 5vw, var(--e-8)) auto 0;
  max-width: 46rem;
  padding: clamp(var(--e-6), 4vw, var(--e-7)) var(--e-5);
  text-align: center;
  /* Hilo punteado: es el mismo aviso que la marca de destino pendiente, en
     grande. Un borde continuo lo haría parecer una caja de contenido. */
  border: var(--hilo-fino) dashed rgba(42, 46, 104, 0.3);
}
.es-marino .sin-piezas { border-color: rgba(255, 255, 255, 0.3); }
.sin-piezas__marca { color: var(--ceruleo-hondo); }
.es-marino .sin-piezas__marca { color: var(--oro); }
.sin-piezas__cuerpo {
  margin: 0;
  max-width: 56ch;
  font-size: var(--t-base);
  line-height: 1.6;
  color: var(--tinta-suave);
}
.es-marino .sin-piezas__cuerpo { color: var(--marino-tinte); }

/* ---- La vista: el espacio de cada etapa --------------------------------- */

.vista {
  margin: clamp(var(--e-7), 5vw, var(--e-8)) auto 0;
  display: grid;
  justify-items: center;
  gap: var(--e-4);
}
/* En disco, como las fotos de la ruta pedagógica y los medallones del equipo.
   Es la misma figura de todo el sitio; una fotografía rectangular aquí sería la
   única esquina viva de la página. */
.vista__disco {
  display: block;
  width: clamp(13rem, 26vw, 22rem);
  aspect-ratio: 1;
  border-radius: 50%;
  overflow: clip;
  box-shadow: 0 26px 60px rgba(8, 10, 22, 0.24);
}
.vista__disco img { width: 100%; height: 100%; object-fit: cover; display: block; }
.vista__pie { color: var(--ceruleo-hondo); }

@media (max-width: 62rem) {
  .canales { grid-template-columns: 1fr; }
  .canal { padding-inline: 0; }
  /* A una columna el hilo se pone de pie: el mismo hilo, girado. */
  .canal + .canal { border-left: 0; }
  .canal { border-top: var(--hilo-fino) solid rgba(42, 46, 104, 0.16); }
  .canal:first-child { border-top: var(--hilo-orillo) solid var(--oro); }
}

/* ---- El formulario ------------------------------------------------------- */

/* ---- LOS FORMULARIOS, EN LOS DOS CAMPOS ---------------------------------
   EL FALLO QUE ESTO ARREGLA, PARA QUE NO SE REPITA. Este bloque nació escrito
   SÓLO para campo marino —texto blanco, fondo translúcido blanco, filete blanco
   al 28 %— porque el único formulario que existía, el de Contacto, vive sobre
   marino. El 2026-09-08 se armaron dos formularios más, en secciones claras, y
   heredaron esos colores: lo que escribiera una familia salía en BLANCO SOBRE
   AZUL CLARO. Ilegible. Andrés lo vio en pantalla antes que yo en el código.

   Es el mismo error que ya cometí con `.enlace-accion` —blanco fijo, invisible
   al caer en una banda clara— y la lección es la misma y hay que dejarla dicha:

     NINGÚN COMPONENTE DE ESTE SISTEMA PUEDE TENER UN SOLO JUEGO DE COLOR.
     Hay dos campos, marino y claro, y cualquier pieza puede acabar en
     cualquiera de los dos. Si al escribir una pieza sólo se piensa en el campo
     donde va hoy, se rompe el día que alguien la mueva.

   Por eso lo que sigue define el juego neutro y luego el de cada campo, en vez
   de dar por hecho el marino.                                                */

.forma {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--e-5);
  /* LA MEDIDA VIVE AQUÍ, no en un `style` en línea. Estaba incrustada en el
     formulario de Contacto, y al generar los otros dos no viajó con ellos: los
     nuevos corrían los 1.280 px del lienzo y quedaban pegados al encabezado.
     Un formulario de 1.280 px de ancho tampoco se llena: el ojo pierde el
     renglón entre el rótulo y su campo. */
  max-width: 52rem;
  margin-inline: auto;
  margin-top: clamp(var(--e-7), 5vw, var(--e-8));
}
/* `max-width: none` PORQUE CADA CAMPO ES UN <p>, y `base.css` le pone a todo
   párrafo el tope de la medida de lectura. Los de media columna nunca llegaban
   a ese tope; el de ancho completo sí, y el cuadro del mensaje se quedaba corto
   del filo derecho. Andrés lo marcó en verde el 2026-09-14. */
.campo { display: grid; gap: var(--e-2); margin: 0; max-width: none; }
.campo--ancho { grid-column: 1 / -1; }
/* El mensaje se estira hacia abajo, no hacia los lados: tirar de la esquina
   hacia la derecha rompería el filo que se acaba de alinear. */
textarea.campo__caja { resize: vertical; min-height: 8rem; }

.campo__caja {
  padding: var(--e-3) var(--e-4);
  border-radius: var(--radio-0);
  font: inherit;
  font-size: var(--t-base);
}
.campo__caja:focus-visible { outline: var(--hilo-trama) solid var(--oro); outline-offset: 2px; }

/* Sobre marino */
.es-marino .campo__rotulo { color: var(--marino-tinte); }
.es-marino .campo__caja {
  background: rgba(255, 255, 255, 0.06);
  border: var(--hilo-fino) solid rgba(255, 255, 255, 0.28);
  color: #FFF;
}
.es-marino .campo__caja::placeholder { color: rgba(255, 255, 255, 0.55); }
.es-marino .campo__caja:hover { border-color: rgba(255, 255, 255, 0.5); }

/* Sobre claro. El campo va en blanco puro y no en el cielo del fondo: lo que
   distingue un campo rellenable de la página es que se hunde, y sobre un fondo
   ya claro eso sólo se consigue con blanco y un filete que se vea. */
.es-clara .campo__rotulo { color: var(--ceruleo-hondo); }
.es-clara .campo__caja {
  background: #FFF;
  border: var(--hilo-fino) solid rgba(42, 46, 104, 0.32);
  color: var(--tinta);
}
.es-clara .campo__caja::placeholder { color: var(--tinta-suave); }
.es-clara .campo__caja:hover { border-color: var(--ceruleo-hondo); }

/* El pie: el botón NO ocupa todo el ancho. `display: grid` lo estiraba a los
   52rem del formulario, y un botón de medio metro no se lee como un botón, se
   lee como una franja.

   AL EJE desde el 2026-09-10, por petición de Andrés. Y el aviso va con él:
   el botón centrado con la letra pequeña pegada a la izquierda dejaba el pie
   descuadrado. Los dos al eje o los dos al filo; a medias, no. */
.forma__pie {
  grid-column: 1 / -1;
  display: grid;
  justify-items: center;
  gap: var(--e-4);
}
.forma__aviso {
  margin: 0;
  max-width: 62ch;
  font-size: var(--t-sm);
  line-height: 1.6;
  text-align: center;
}
.es-marino .forma__aviso { color: var(--marino-tinte); }
.es-clara  .forma__aviso { color: var(--tinta-suave); }
.forma__marca {
  display: inline-block;
  margin-right: var(--e-2);
  padding: 0.1em 0.5em;
  background: var(--oro);
  color: var(--marino);
}

@media (max-width: 52rem) {
  .forma { grid-template-columns: 1fr; }
  .forma__pie .boton { width: 100%; justify-content: center; }
}

/* ---- La galería de espacios ---------------------------------------------
   Las fotos del colegio son panorámicas de 1500 × 729, todas iguales de
   proporción. Una parrilla de rectángulos idénticos se lee como catálogo, así
   que la primera va a todo lo ancho y el resto se reparte.                   */

.espacios {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: var(--e-4);
  margin: clamp(var(--e-7), 5vw, var(--e-8)) 0 0;
  padding: 0;
  list-style: none;
}
.espacio { grid-column: span 2; }
.espacio:nth-child(1) { grid-column: span 6; }
.espacio:nth-child(2),
.espacio:nth-child(3),
.espacio:nth-child(10),
.espacio:nth-child(11) { grid-column: span 3; }

.espacio__figura { position: relative; margin: 0; overflow: clip; background: var(--marino-hondo); }
.espacio__foto {
  display: block; width: 100%; height: 100%;
  aspect-ratio: 1500 / 729;
  object-fit: cover;
  transition: transform 700ms var(--sale);
}
.espacio__figura:hover .espacio__foto { transform: scale(1.03); }
.espacio__rotulo {
  position: absolute;
  inset: auto 0 0 0;
  padding: var(--e-6) var(--e-4) var(--e-4);
  background: linear-gradient(to top, rgba(16, 18, 46, 0.92), rgba(16, 18, 46, 0));
  color: #FFF;
}
.espacios__nota { margin: var(--e-6) 0 0; font-size: var(--t-sm); color: var(--tinta-suave); text-align: center; }

/* ==========================================================================
   ETAPA POR ETAPA — EL RECORRIDO HORIZONTAL
   --------------------------------------------------------------------------
   La sección se clava en pantalla y las cuatro etapas pasan de derecha a
   izquierda mientras se baja. En la Home los paneles SE APILAN; aquí SE
   RECORREN. Son dos gestos distintos, y por eso las dos secciones dejaron de
   parecerse, que era el problema.

   LA CUENTA, que es lo único delicado:

     alto de la sección = una pantalla por etapa       (4 × 100svh)
     el marco es pegajoso y mide UNA pantalla
     la pista mide 4 anchos de marco y se desplaza -75 %

   El −75 % no es arbitrario: la pista son cuatro tramos, y mover tres de los
   cuatro es 3/4 de su propio ancho. Con N tramos sería −(N−1)/N. Si algún día
   entra una quinta etapa hay que tocar TRES sitios —el alto, el ancho de tramo
   y ese porcentaje—, así que los tres salen de `--tramos` y basta cambiarlo ahí.

   EL RELOJ. `view-timeline-name` va en la sección y la pista lo usa: un tiempo
   nombrado es visible para los descendientes del elemento que lo declara, así
   que aquí no hace falta `timeline-scope`. El rango es `contain`, que para un
   sujeto MÁS ALTO que la pantalla es exactamente el tramo en que la sección la
   cubre entera — o sea, mientras el marco está clavado. Ni antes ni después.  */

/* LA SECCIÓN DECLARA SU CAMPO CON `es-clara` EN EL MARCADO, y el fondo y los
   colores de todo lo que caiga dentro vienen de ahí. No es un detalle: al
   escribir esta sección puse el fondo claro a mano y me dejé los colores del
   encabezado, que por defecto son los de campo marino. Resultado: el antetítulo
   a 1,49:1 y el titular a 1,13:1 — blanco sobre azul claro.

   Es el MISMO fallo que había arreglado dos horas antes en el telar que esta
   sección sustituye, y con la regla ya escrita en ESTADO.md. Lo cazó
   `revisar-contraste.js`, no el ojo, y es la razón de que esa herramienta
   exista: la regla se olvida, el barrido no. */
.recorrido {
  --tramos: 4;
  position: relative;
  height: calc(100svh * var(--tramos));
  border-top: var(--hilo-trama) solid var(--ceruleo);
  view-timeline-name: --paso-etapas;
}
.recorrido__marco {
  position: sticky;
  top: 0;
  height: 100svh;
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
  align-content: center;
  gap: clamp(var(--e-5), 3vw, var(--e-7));
  padding-block: clamp(var(--e-7), 6vh, var(--e-9));
  overflow: clip;
}
.recorrido__encabezado { text-align: center; }
.recorrido__encabezado .encabezado { margin-inline: auto; }

.recorrido__pista {
  display: grid;
  grid-auto-flow: column;
  /* UNA CUARTA PARTE DE LA PISTA, NO EL 100 %. El porcentaje de
     `grid-auto-columns` se resuelve contra la PISTA —que mide cuatro
     pantallas—, no contra la pantalla. Con `100%` cada columna medía 5.540 px y
     el primer tramo, centrado dentro de la suya, empezaba a 2.074 px: fuera de
     la vista. Sale en la medición, no a ojo. */
  grid-auto-columns: calc(100% / var(--tramos));
  width: calc(100% * var(--tramos));
  margin: 0;
  padding: 0;
  list-style: none;
  align-items: center;
}
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .recorrido__pista {
      animation: recorrer-etapas linear both;
      animation-timeline: --paso-etapas;
      animation-range: contain 0% contain 100%;
    }
  }
}
@keyframes recorrer-etapas {
  to { transform: translateX(calc(-100% * (var(--tramos) - 1) / var(--tramos))); }
}

/* ---- Cada tramo ---------------------------------------------------------- */

.tramo {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(var(--e-6), 5vw, var(--e-9));
  align-items: center;
  /* El canal a los dos lados: sin él, el texto del tramo tocaría el borde de la
     pantalla justo cuando entra. */
  padding-inline: var(--canal);
  max-width: calc(var(--ancho-max) + var(--canal) * 2);
  margin-inline: auto;
}

/* EL HILO. Aquí es donde el degradado que le gustó al cliente pasa a hacer lo
   que decía: en la primera versión cruzaba una línea de tiempo quieta; ahora
   atraviesa las cuatro etapas y el visitante lo RECORRE. Cada tramo pinta su
   segmento y su nudo, así que los cuatro juntos son una sola línea continua. */
.tramo::before {
  content: '';
  position: absolute;
  left: 0; right: 0; top: 50%;
  height: var(--hilo-trama);
  background: linear-gradient(to right, var(--hilo-desde), var(--hilo-hasta));
  opacity: 0.5;
  z-index: 0;
}
.tramo::after {
  content: '';
  position: absolute;
  left: var(--canal); top: 50%;
  width: 0.95rem; height: 0.95rem;
  background: var(--hilo-desde);
  translate: -50% -50%;
  rotate: 45deg;
  z-index: 1;
}
/* El oro llega en la cuarta, que es donde termina el colegio. Es la misma regla
   de siempre: el oro marca el final del recorrido, no se reparte. */
.tramo:nth-child(1), .tramo:nth-child(2), .tramo:nth-child(3) {
  --hilo-desde: var(--ceruleo);
  --hilo-hasta: var(--ceruleo);
}
.tramo:nth-child(4) {
  --hilo-desde: var(--ceruleo);
  --hilo-hasta: var(--oro);
}
.tramo:nth-child(4)::after { background: var(--oro); }

/* EL HILO SE INTERRUMPE EN EL TEXTO, y no al revés. Andrés lo vio el 2026-09-09:
   cuando el titular cae en dos renglones, el hilo cruza por el segundo y el
   titular se lee TACHADO. Su idea era subir el texto, pero eso sólo mueve el
   problema: con un titular de un renglón el hilo cruzaría por otro sitio, y con
   uno de tres volvería a tachar.

   Lo que hay es lo que se hace en cualquier plano rotulado: la línea se corta
   donde va la etiqueta. El bloque de texto lleva el color del campo, así que
   abre un claro y el hilo entra por la izquierda, se interrumpe y sale por la
   derecha hacia el disco. Sigue siendo continuo entre tramos y ya no pisa nada,
   mida lo que mida el titular.

   El `margin-left` es lo que deja ver el hilo ENTRE el nudo y el claro: sin él
   el bloque taparía su propio nudo. */
.tramo__dicho {
  position: relative;
  z-index: 2;
  display: grid;
  gap: var(--e-3);
  margin-left: clamp(var(--e-5), 3vw, var(--e-7));
  padding: var(--e-4) clamp(var(--e-4), 2.5vw, var(--e-6)) var(--e-4) 0;
  /* El claro se pinta con el color del campo en el que cae, sea el que sea. */
  background: var(--campo-actual, var(--campo-cielo));
}
.tramo__orden { margin: 0; max-width: none; color: var(--ceruleo-hondo); }
.tramo__nombre {
  margin: var(--e-2) 0 0;
  font-family: var(--fuente-titular);
  font-weight: var(--peso-titular);
  font-size: clamp(1.9rem, 3.6vw, 3.2rem);
  line-height: 1.04;
  letter-spacing: var(--tracking-titular);
  color: var(--marino);
  text-wrap: balance;
}
.tramo__texto {
  margin: var(--e-4) 0 0;
  max-width: 38ch;
  font-size: var(--t-base);
  line-height: var(--interlinea-lead);
  color: var(--tinta-suave);
}

/* En disco, como todo lo demás del sitio. Un rectángulo aquí sería la única
   esquina viva de la sección. */
.tramo__lamina {
  position: relative;
  z-index: 2;
  margin: 0;
  justify-self: center;
  width: min(100%, clamp(13rem, 26vw, 24rem));
  aspect-ratio: 1;
  border-radius: 50%;
  overflow: clip;
  box-shadow: 0 26px 60px rgba(8, 10, 22, 0.26);
}
.tramo__lamina img {
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: 50% 40%;
  display: block;
}

/* El aviso se apaga cuando ya no queda recorrido: dejarlo diciendo «siga
   bajando» en la última etapa sería mentirle al visitante. Va en el mismo reloj
   que la pista, pero en el último cuarto del rango. */
/* ---- El recorrido sobre campo marino -------------------------------------
   El componente nació claro. Traerlo a Propuesta Educativa no pidió duplicarlo:
   sólo el segundo juego de color que le faltaba. Es la regla del sistema, y la
   prueba de que esta vez está bien escrito. */
.es-marino .tramo__orden  { color: #8FD0F0; }
.es-marino .tramo__nombre { color: #FFF; }
.es-marino .tramo__texto  { color: var(--marino-tinte); }
.es-marino .tramo::before { opacity: 0.65; }
.es-marino .recorrido__pista-aviso { color: #8FD0F0; }
/* El enlace de cada tramo, que sólo existe en esta página: cada etapa es la
   puerta de la suya. */
.tramo__ir { margin-top: var(--e-4); justify-self: start; }

.recorrido__pista-aviso {
  justify-self: center;
  color: var(--ceruleo-hondo);
  opacity: 0.7;
}
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .recorrido__pista-aviso {
      animation: apagar-aviso linear both;
      animation-timeline: --paso-etapas;
      animation-range: contain 72% contain 92%;
    }
  }
}
@keyframes apagar-aviso {
  from { opacity: 0.7; }
  to   { opacity: 0; }
}

/* ---- Estrechando ---------------------------------------------------------
   POR DEBAJO DE 52rem NO HAY RECORRIDO. Un desplazamiento horizontal dirigido
   por scroll vertical en un teléfono pelea con el gesto del pulgar y con el
   «tirar para recargar» del navegador. Las cuatro etapas se apilan y se bajan,
   que es lo que un teléfono hace bien. El hilo se pone de pie con ellas.      */
@media (max-width: 52rem) {
  .recorrido { height: auto; }
  .recorrido__marco {
    position: static;
    height: auto;
    padding-block: clamp(var(--e-8), 10vh, var(--e-9));
  }
  .recorrido__pista {
    grid-auto-flow: row;
    grid-auto-columns: auto;
    width: 100%;
    gap: clamp(var(--e-8), 9vw, var(--e-9));
    animation: none;
    transform: none;
  }
  .tramo {
    grid-template-columns: 1fr;
    gap: var(--e-6);
    padding-inline: 0;
  }
  .tramo__lamina { order: -1; width: min(72%, 15rem); }
  /* El hilo, de pie: baja por el filo izquierdo en vez de cruzar. */
  .tramo::before {
    left: -1px; right: auto; top: 0; bottom: 0;
    width: var(--hilo-trama); height: auto;
    background: linear-gradient(to bottom, var(--hilo-desde), var(--hilo-hasta));
  }
  .tramo::after { left: 0; top: 0; translate: -50% 0; }
  .tramo__dicho {
    margin-left: 0;
    padding: 0 0 0 var(--e-5);
    background: none;
  }
  .recorrido__pista-aviso { display: none; }
}

/* Sin `animation-timeline` —o con movimiento reducido— la pista no se desplaza
   y las cuatro se leen apiladas, igual que en el teléfono. */
@supports not (animation-timeline: view()) {
  .recorrido { height: auto; }
  .recorrido__marco { position: static; height: auto; overflow: visible; }
  .recorrido__pista { grid-auto-flow: row; grid-auto-columns: auto; width: 100%; gap: var(--e-9); }
  .recorrido__pista-aviso { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .recorrido { height: auto; }
  .recorrido__marco { position: static; height: auto; overflow: visible; }
  .recorrido__pista { grid-auto-flow: row; grid-auto-columns: auto; width: 100%; gap: var(--e-9); }
  .recorrido__pista-aviso { display: none; }
}

/* ---- Destinos que todavía no existen -------------------------------------
   Las 19 páginas de la segunda tanda ya están enlazadas con su ruta canónica.
   Hasta que se construyan, `construir.py` les pone `data-pendiente` y aquí se
   ven. Un enlace muerto sin aviso deja mal a quien enseñe el prototipo.
   Cuando una se construya, entra en `PAGINAS` de `construir.py`, el enlace se
   resuelve solo y la marca desaparece sin tocar este archivo.                */

[data-pendiente] {
  text-decoration: underline dotted currentColor;
  text-underline-offset: 0.25em;
  cursor: not-allowed;
}
/* SALVO EN LOS TITULARES DE DISPLAY. Andrés señaló el 2026-09-08 «unos punticos»
   bajo «Preescolar», «Primaria», «Secundaria» y «Media y Futuro» que había que
   quitar: eran esta marca. A tamaño de texto se lee como lo que es —un destino
   que aún no existe—, pero bajo un titular de 6rem el punteado mide medio metro
   y deja de leerse como aviso para leerse como adorno. El aviso sigue vivo donde
   sirve; aquí basta el `title` que pone `construir.py`. */
.etapa__nombre[data-pendiente],
.encabezado__titulo [data-pendiente] {
  text-decoration: none;
  cursor: pointer;
}

/* ---- Estrechando ---------------------------------------------------------- */

/* El índice, estrechando: la cifra pasa a ser un rótulo pequeño junto al ritmo
   y el nombre se queda con todo el ancho. Cuatro columnas en 390px dejaban el
   nombre en dos palabras por renglón. */
@media (max-width: 52rem) {
  .entrada__enlace,
  .entrada__fila {
    grid-template-columns: auto minmax(0, 1fr);
    gap: var(--e-3) var(--e-5);
    align-items: start;
  }
  .entrada__cifra { font-size: 2rem; -webkit-text-stroke-width: 1.5px; }
  .entrada__ritmo { grid-column: 2; text-align: left; }
  .entrada__flecha { grid-column: 2; justify-self: start; }
  .entrada__enlace:hover .entrada__flecha { transform: none; }
}

/* Los patrones de la segunda tanda, a una columna. El hilo que separaba
   columnas pasa a separar filas: es el mismo hilo, girado. */
@media (max-width: 64rem) {
  .ejes { grid-template-columns: 1fr !important; }
  .eje { padding-inline: 0; }
  .eje + .eje {
    border-left: 0;
    border-top: var(--hilo-fino) solid rgba(42, 46, 104, 0.16);
    padding-top: var(--e-5);
  }
  .es-marino .eje + .eje { border-top-color: rgba(255, 255, 255, 0.2); }
  .avales { grid-template-columns: 1fr; }
  .aval { padding-inline: 0; }
  .aval + .aval { border-left: 0; }
  .ruta-ficha { padding-inline: 0; }
  .ruta-ficha + .ruta-ficha { border-left: 0; }
  .papel { grid-template-columns: minmax(0, 1fr) auto; }
  .papel__marca, .papel__nombre, .papel__cuerpo { grid-column: 1; }
  .papel__estado { grid-column: 2; grid-row: 1; }
}

@media (max-width: 64rem) {
  .doble { grid-template-columns: 1fr; }
  .espacios { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .espacio, .espacio:nth-child(n) { grid-column: span 1; }
  .espacio:nth-child(1) { grid-column: span 2; }

  .PURGAR-LINEA { grid-template-columns: 1fr; gap: 0; }
  .PURGAR-LINEA::before {
    top: 0.45rem; bottom: 0.45rem; left: 0.45rem; right: auto;
    width: var(--hilo-trama); height: auto;
    background: linear-gradient(to bottom, var(--ceruleo), var(--ceruleo) 66%, var(--oro));
  }
  .hito { padding: 0 0 var(--e-7) var(--e-7); }
  .hito::before { left: 0.45rem; top: 0.2rem; }
}

@media (max-width: 48rem) {
  /* En el teléfono la sección también ocupa lo que se ve, como pidió Andrés el
     2026-09-10. Antes iba a `auto` para no dejar pantallas medio vacías, pero
     `min-height` sólo AÑADE: una sección con contenido alto crece igual, así
     que lo único que cambia es que las cortas dejan de quedarse a medias. */
  .pliego { min-height: calc(100svh - var(--cabecera)); padding-block: clamp(var(--e-7), 6vh, var(--e-9)); }
  .rutas__lista { grid-template-columns: 1fr; }
  .forma { grid-template-columns: 1fr; }
  .espacios { grid-template-columns: 1fr; }
  .espacio, .espacio:nth-child(n) { grid-column: span 1; }
  .encabezado__acciones { flex-direction: column; align-items: stretch; width: 100%; }
  .encabezado__acciones .boton { justify-content: center; }

  .papel { grid-template-columns: 1fr; }
  .papel__estado { grid-column: 1; grid-row: auto; text-align: left; }
  /* En el teléfono la alternancia no cabe: dos columnas de 150 px dejan el
     texto en una cuchilla. Vuelve a una sola con el nudo encima, y el hilo se
     retira porque sin dos lados que enhebrar ya no une nada. */
  .paso { grid-template-columns: 1fr; gap: var(--e-4); }
  .paso__cifra, .paso__dicho { grid-column: 1; grid-row: auto; }
  .paso:nth-child(odd) .paso__dicho { text-align: left; justify-items: start; }
  .paso__cuerpo { max-width: none; }
  .paso:not(:last-child)::before { display: none; }
}

/* ==========================================================================
   LA SENDA — «El desarrollo del estudiante» (Vida Cervantista)
   --------------------------------------------------------------------------
   Cuarta forma de esta sección. Las tres anteriores y por qué cayeron están en
   el comentario de `paginas/vida-cervantista.html`; lo que importa aquí es la
   última: la tercera —un recorrido horizontal fijado— acabó siendo la MISMA
   pieza que «El recorrido, etapa por etapa» de Propuesta Educativa. Resolver
   un parecido creando otro no es resolverlo.

   Ésta no se parece a nada del sitio porque su gesto es nuevo: no hay paneles
   que se apilan ni un carril que se recorre; hay UN HILO que se traza con el
   scroll y va enhebrando las cuatro etapas. Referencias que trajo Andrés:
   `le-mugs.com` y la sección de proceso de `cafe-concentral.vercel.app`.

   CÓMO ENCAJAN LOS NÚMEROS, que es lo único delicado:
   el hilo vive en un `viewBox` de 1200 × 3600 estirado sobre el campo entero.
   Sus cuatro codos caen en y = 450, 1350, 2250 y 3150, o sea en el centro de
   cuatro filas iguales; y en x = 840 y 360, o sea al 70 % y al 30 %. La lista
   de paradas tiene exactamente cuatro filas iguales y sus estampas van
   centradas al 70 % y al 30 %. Por eso el hilo entra por detrás de cada
   ilustración y sale por el otro lado —enhebra, que es lo que se le pidió— sin
   una sola medida escrita dos veces.

   Si alguien cambia el número de paradas hay que cambiar el `d` del hilo: no se
   ajusta solo. */

.senda { padding-block: clamp(var(--e-9), 12vh, 8rem); overflow: clip; }
.senda__encabezado { margin-bottom: clamp(var(--e-8), 9vh, 7rem); }

.senda__campo { position: relative; }

/* `preserveAspectRatio="none"` estira el hilo a lo que mida el campo, y
   `vector-effect: non-scaling-stroke` (en el marcado) mantiene el grosor: sin
   lo segundo el hilo engordaría al ensanchar la ventana. */
.senda__hilo {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  translate: -50% 0;
  z-index: 0;
  /* EXACTAMENTE la caja de contenido de una parada —el mismo tope y el mismo
     canal—, no el ancho del campo. Es lo que hace que el 70 % del `viewBox`
     caiga en el 70 % de la reja y el hilo pase por el centro de la ilustración.
     Con `inset: 0` el hilo se iba dos puntos porcentuales, que a 1440 son 28 px:
     lo justo para que dejara de enhebrar y pasara rozando. */
  width: min(100% - var(--canal) * 2, calc(var(--ancho-max) - var(--canal) * 2));
  height: 100%;
  pointer-events: none;
}
/* CADA SENDA APUNTA A SU PROPIO DEGRADADO, y esto no es una redundancia: un
   `url(#…)` que no existe en la página NO se pinta de un color por defecto, no
   se pinta en absoluto. El hilo de Propuesta Educativa estuvo invisible desde
   que se creó por apuntar al degradado de Vida Cervantista, que allí no existe.
   No dio error, no salió en ningún barrido: simplemente no había línea.
   Si mañana hay una tercera senda, su `<path>` necesita su clase y su regla. */
.hilo__trazo {
  fill: none;
  stroke: url(#hilo-senda);
  stroke-width: 3;
  stroke-linecap: round;
}
/* Un pelo más grueso en campo marino: el celeste sobre azul oscuro pierde
   presencia frente al mismo trazo sobre campo claro. Es el trazo el que tiene
   que verse igual, no el número. */
.hilo__trazo--recorrido { stroke: url(#hilo-recorrido); }
.hilo__trazo--app { stroke: url(#hilo-app); }
.es-marino .hilo__trazo { stroke-width: 3.4; }

.senda__paradas {
  position: relative;
  z-index: 1;
  display: grid;
  list-style: none;
  margin: 0;
  padding: 0;
}

.parada {
  display: grid;
  align-items: center;
  --hueco: clamp(var(--e-5), 3vw, var(--e-8));
  gap: var(--hueco);
  min-height: 86svh;
  width: 100%;
  max-width: var(--ancho-max);
  margin-inline: auto;
  padding-inline: var(--canal);
}
/* EL CENTRO DE LA COLUMNA ANCHA TIENE QUE CAER AL 70 % Y AL 30 %, que es por
   donde pasa el hilo. De ahí sale el reparto, y de ahí sale también el `- var(--hueco)`,
   que no es un ajuste fino: la separación entre columnas EMPUJA la segunda, así
   que un 40 %/60 % limpio deja su centro en el 70 % más medio hueco. A 1440 eso
   eran 43 px, lo justo para que el hilo dejara de enhebrar la ilustración y
   pasara rozándola. Restándole el hueco a la primera columna, la segunda vuelve
   a medir 60 % y su centro cae donde tiene que caer. */
.parada--der { grid-template-columns: calc(40% - var(--hueco)) minmax(0, 1fr); }
.parada--izq { grid-template-columns: 60% minmax(0, 1fr); }
/* El orden del MARCADO es siempre texto → estampa, que es como hay que leerlo.
   Aquí sólo cambia de sitio en pantalla. */
.parada--izq .parada__estampa { grid-area: 1 / 1; }
.parada--izq .parada__dicho   { grid-area: 1 / 2; }

.parada__dicho { max-width: 30rem; }
.parada--der .parada__dicho { justify-self: end; }

.parada__etapa { color: var(--ceruleo-hondo); }
/* La senda también vive en campo marino (Propuesta Educativa). Ni un color
   suelto: el contenedor declara el campo y las piezas heredan, que es la regla
   que ya costó cuatro arreglos. */
.es-marino .parada__etapa  { color: #8FD0F0; }
.es-marino .parada__nombre { color: #FFF; }
.es-marino .parada__texto  { color: var(--marino-tinte); }
.parada__ir { margin-top: var(--e-5); }
.parada--der .parada__ir { justify-self: end; }
.parada__nombre {
  margin: var(--e-3) 0 0;
  font-family: var(--fuente-titular);
  font-weight: var(--peso-titular);
  font-size: clamp(1.7rem, 3.2vw, 2.6rem);
  line-height: 1.06;
  letter-spacing: var(--tracking-display);
  color: var(--marino);
  text-wrap: balance;
}
.parada__texto {
  margin: var(--e-5) 0 0;
  font-size: var(--t-base);
  line-height: var(--interlinea-lead);
  color: var(--tinta-suave);
  max-width: 36ch;
}

/* ---- La estampa: los dos aros de Andrés, redibujados ---------------------
   Los aros NO son la imagen que él exportó: son `<circle>` con el centro, el
   radio y el grosor sacados uno a uno de `<etapa> circulos.svg`. Se redibujan
   por una razón concreta: así pueden TRAZARSE con el scroll, como los anillos
   de la Home. Pegados como imagen sólo podrían aparecer y desaparecer.
   `pathLength="1"` en el marcado es lo que permite que el mismo `dasharray: 1`
   valga para los dos aros aunque midan distinto. */
.parada__estampa {
  position: relative;
  margin: 0 auto;
  width: min(100%, 30rem);
  aspect-ratio: var(--caja);
}
.estampa__aros {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}
.aro { fill: none; }
.aro--oro    { stroke: var(--oro); }
.aro--marino { stroke: var(--marino); }
/* En Propuesta el juego va al revés: el grande cerúleo y el pequeño de oro. Es
   lo que Andrés le dio a cada sección en Figma, y es lo que impide que las dos
   sendas se lean como la misma pieza repetida en dos páginas. */
.aro--ceruleo { stroke: var(--ceruleo); }
.es-marino .aro--ceruleo { stroke: #2A9FD8; }

/* El dibujo va ENCIMA de los aros y en su sitio exacto dentro de la caja: las
   tres medidas salieron de localizar la ilustración dentro del compuesto que
   Andrés exportó, no de colocarla a ojo. Están en `assets/vida/LEEME.md`. */
.estampa__dibujo {
  position: absolute;
  left: var(--dx);
  top: var(--dy);
  width: var(--dw);
  height: auto;
  max-width: none;
}
.estampa--preescolar { --caja: 431 / 469; --dx: 8.353%;  --dy: 17.910%; --dw: 89.095%; }
.estampa--primaria   { --caja: 456 / 442; --dx: 0;       --dy: 34.389%; --dw: 100%; }
.estampa--secundaria { --caja: 549 / 443; --dx: 0;       --dy: 49.661%; --dw: 100%; }
.estampa--media      { --caja: 514 / 498; --dx: 9.339%;  --dy: 36.948%; --dw: 90.272%; }

/* Las cuatro de Propuesta Educativa. Mismo mecanismo, otras medidas: son
   dibujos distintos y cada uno cae en un sitio distinto de su caja. */
.estampa--pe-preescolar { --caja: 430 / 471; --dx: 19.535%; --dy: 22.930%; --dw: 62.093%; }
.estampa--pe-primaria   { --caja: 435 / 467; --dx: 0;       --dy: 0;       --dw: 100%; }
.estampa--pe-secundaria { --caja: 472 / 479; --dx: 0;       --dy: 14.196%; --dw: 100%; }
.estampa--pe-media      { --caja: 543 / 506; --dx: 0;       --dy: 35.573%; --dw: 100%; }

/* Las tres de la landing de la app (2026-09-18). Mismas medidas de aro que las
   otras dos sendas —r 170,4 y 81,5— y la posición del dibujo leída de los
   compuestos que exportó Andrés con `getBBox`, no a ojo: la escala salió 1,000
   en las tres, así que el dibujo entra en su caja sin tocarlo.
   La tabla está en `assets/app/LEEME.md`. */
.estampa--app-instalar       { --caja: 430 / 485; --dx: 25.814%; --dy: 8.866%;  --dw: 67.674%; }
.estampa--app-acceso         { --caja: 434 / 466; --dx: 0;       --dy: 7.940%;  --dw: 86.175%; }
.estampa--app-notificaciones { --caja: 390 / 473; --dx: 13.077%; --dy: 13.319%; --dw: 71.538%; }

/* ---- Lo que hace el scroll ---------------------------------------------- */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .senda__campo    { view-timeline-name: --senda; }
    .parada          { view-timeline-name: --parada; }
    .parada__estampa { view-timeline-name: --estampa; }

    .hilo__trazo {
      stroke-dasharray: 1;
      animation: trazar-hilo linear both;
      animation-timeline: --senda;
      /* El campo mide más de tres pantallas, así que `cover` va casi todo por
         dentro. El 6 %–86 % hace que el hilo empiece cuando entra la primera
         parada y cierre cuando la cuarta está centrada, no cuando la sección
         termina de salir: si no, el último tramo se dibujaría con la sección ya
         medio fuera y nadie lo vería. */
      animation-range: cover 6% cover 88%;
    }

    /* Los aros se trazan desde arriba —de ahí el giro de −90°— y el pequeño
       entra después del grande: los dos a la vez se leen como un parpadeo. */
    .aro {
      stroke-dasharray: 1;
      transform: rotate(-90deg);
      transform-box: fill-box;
      transform-origin: 50% 50%;
      animation: trazar-aro linear both;
      animation-timeline: --estampa;
    }
    .aro--oro    { animation-range: entry 28% entry 96%; }
    .aro--marino { animation-range: entry 46% cover 10%; }

    .estampa__dibujo {
      animation: llegar-dibujo linear both;
      animation-timeline: --estampa;
      animation-range: entry 34% entry 92%;
    }
    .parada__dicho {
      animation: llegar-dicho linear both;
      animation-timeline: --parada;
      animation-range: entry 22% entry 62%;
    }
  }
}
@keyframes trazar-hilo  { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
@keyframes trazar-aro   { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
@keyframes llegar-dibujo { from { opacity: 0; scale: 0.94; } to { opacity: 1; scale: 1; } }
@keyframes llegar-dicho  { from { opacity: 0; translate: 0 1.8rem; } to { opacity: 1; translate: 0 0; } }

@media (max-width: 52rem) {
  /* Una sola columna, y la estampa PRIMERO: en el teléfono la ilustración es
     lo que ancla cada etapa. El hilo sigue: estirado sobre una columna
     estrecha, la curva se vuelve un serpenteo suave y sigue leyéndose como un
     hilo, que es de lo que se trata. */
  .parada,
  .parada--der,
  .parada--izq { grid-template-columns: 1fr; min-height: auto; padding-block: clamp(var(--e-8), 9vh, 5rem); }
  .parada--izq .parada__estampa,
  .parada--der .parada__estampa { grid-area: auto; order: -1; }
  .parada--izq .parada__dicho,
  .parada--der .parada__dicho { grid-area: auto; justify-self: start; max-width: none; }
  .parada__estampa { width: min(100%, 20rem); }

  /* EL HILO SE VA AL MARGEN. En una sola columna la curva cruzaba el titular y
     el párrafo —se veía pasar por encima de «Acogida y adaptación»—, y un hilo
     que tacha el texto no es un hilo conductor, es un tachón. Aquí se recoge en
     una banda estrecha a la izquierda y se lee como el raíl de una línea de
     tiempo: sigue siendo lo mismo —una sola línea que recorre las cuatro
     etapas y se traza con el scroll—, contado como cabe en un teléfono.
     El relleno de las paradas es lo que le deja ese sitio: sin él, volvería a
     pasar por encima. Las dos medidas van juntas. */
  .senda__hilo { left: 0; translate: none; width: 3.5rem; }
  .parada,
  .parada--der,
  .parada--izq { padding-left: calc(var(--canal) + 3.25rem); }
}

/* ==========================================================================
   LA NÓMINA — `/colegio/equipo/`
   --------------------------------------------------------------------------
   ESTA SECCIÓN NO TENÍA NI UNA LÍNEA DE CSS. El marcado se escribió el
   2026-09-08 y nadie le puso estilo, así que los veintitrés retratos salían a
   su tamaño natural —640 × 800— uno debajo de otro: una página de tres metros
   con una cara por pantalla. Andrés lo vio el 2026-09-10 («se está viendo
   extremadamente grande»). No era un problema de talla: era que no existía.

   LOS DOS GRUPOS SE DIAGRAMAN DISTINTO Y ES A PROPÓSITO. Tres directivos en la
   misma reja que veinte docentes se leen como veintitrés iguales, y no lo son:
   el rector, la coordinadora y la secretaria académica son a quienes una familia
   busca por su nombre. Van en tres columnas anchas, con el disco más grande y
   los datos completos. Los veinte docentes van en una reja densa de cinco, que
   es como se lee una nómina: de un vistazo, buscando un nombre.

   EL DISCO, NO EL RECTÁNGULO. Es la misma figura que manda en toda la web —los
   anillos, los medallones de la Home, los rostros del pórtico— y aquí además
   resuelve un problema real: los retratos son 4:5 con fondo de estudio, y en
   círculo el fondo deja de leerse como un recorte y pasa a ser parte del disco. */

.nomina-larga {
  display: grid;
  margin: clamp(var(--e-7), 5vw, var(--e-9)) 0 0;
  padding: 0;
  list-style: none;
}
/* Tres, y con tope: `auto-fit` dejaba las tres fichas estiradas a 360 px de
   ancho en pantallas grandes y el bloque perdía el centro de la página. */
.nomina-larga--direccion {
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: clamp(var(--e-6), 4vw, var(--e-8)) clamp(var(--e-5), 3vw, var(--e-7));
  max-width: 62rem;
  margin-inline: auto;
  --disco: clamp(7rem, 11vw, 9.5rem);
}
/* Cinco columnas a 1.088 px de lienzo: veinte docentes caen en cuatro filas
   exactas. Si algún día son 21, la última fila queda coja y hay que decidir —no
   se arregla solo—. */
.nomina-larga--docentes {
  grid-template-columns: repeat(auto-fill, minmax(12rem, 1fr));
  gap: clamp(var(--e-6), 3.4vw, var(--e-7)) clamp(var(--e-4), 2.4vw, var(--e-6));
  --disco: clamp(5.5rem, 8vw, 7rem);
}

/* `1fr` en la segunda fila y `margin-top: auto` en el horario: es lo que hace
   que los cinco horarios de una fila queden A LA MISMA ALTURA aunque los
   nombres ocupen uno o dos renglones. Sin eso, la reja se lee como veinte
   fichas sueltas en vez de como una nómina; con eso, el hilo del horario cruza
   la fila entera. (Se resolvió así y no con `subgrid` porque en subgrid el
   hueco entre filas de la ficha y el hueco ENTRE fichas son el mismo número, y
   aquí tienen que ser distintos.) */
.perfil {
  display: grid;
  grid-template-rows: auto 1fr;
  gap: var(--e-4);
  text-align: center;
  justify-items: center;
}
.perfil__disco {
  display: block;
  width: var(--disco);
  aspect-ratio: 1;
  border-radius: 50%;
  overflow: clip;
  background: var(--campo-cielo-h);
  /* Aro por sombra extendida y no por `border`: un borde metería su grosor
     DENTRO del disco y encogería la cara. Es la misma razón que en los
     medallones de la Home. */
  box-shadow: 0 0 0 var(--hilo-trama) rgba(0, 134, 192, 0.28),
              0 10px 26px rgba(8, 10, 26, 0.12);
}
.perfil__disco img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Al 22 %, igual que los medallones: el retrato normalizado es 4:5 y un
     recorte cuadrado por el centro le corta la barbilla. */
  object-position: 50% 22%;
  display: block;
}

.perfil__dicho {
  display: flex;
  flex-direction: column;
  width: 100%;
}
.perfil__cargo { color: var(--ceruleo-hondo); }
.perfil__nombre {
  margin: var(--e-2) 0 0;
  font-family: var(--fuente-titular);
  font-weight: var(--peso-titular);
  font-size: clamp(0.98rem, 1.25vw, 1.18rem);
  line-height: 1.16;
  letter-spacing: -0.01em;
  color: var(--marino);
  text-wrap: balance;
}
.perfil__titulo {
  margin: var(--e-2) 0 0;
  font-size: var(--t-sm);
  line-height: 1.32;
  color: var(--tinta);
  max-width: none;
}
.perfil__casa {
  margin: 0;
  font-size: 0.8rem;
  line-height: 1.3;
  color: var(--tinta-suave);
  max-width: none;
}
/* El horario va detrás de un hilo: es el dato que una familia viene a buscar y
   tiene que separarse de la formación, que es contexto. */
.perfil__atiende {
  margin-top: auto;
  padding-top: var(--e-3);
  border-top: var(--hilo-fino) solid rgba(42, 46, 104, 0.16);
  display: grid;
  gap: var(--e-1);
}
.perfil__rotulo { color: var(--ceruleo-hondo); }
/* Las que el colegio todavía no ha confirmado no se disimulan: se dicen. Un
   horario inventado sería peor que un hueco, y un hueco sin rótulo parecería un
   descuido nuestro. Está anotado en ESTADO.md. */
.perfil__atiende--falta .perfil__rotulo { color: var(--tinta-suave); }
.perfil__horario {
  margin: 0;
  font-size: 0.85rem;
  line-height: 1.3;
  color: var(--marino);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  max-width: none;
}

.nomina-larga__nota {
  margin: clamp(var(--e-7), 5vw, var(--e-8)) auto 0;
  max-width: 62ch;
  text-align: center;
  font-size: var(--t-sm);
  line-height: 1.5;
  color: var(--tinta-suave);
}

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    /* Cada ficha entra por su cuenta al asomar. No hay escalonado por guion: con
       veintitrés en una reja, el propio orden de lectura ya escalona. */
    .perfil {
      animation: llegar-perfil linear both;
      animation-timeline: view();
      animation-range: entry 10% entry 55%;
    }
  }
}
@keyframes llegar-perfil {
  from { opacity: 0; translate: 0 1.4rem; }
  to   { opacity: 1; translate: 0 0; }
}

@media (max-width: 34rem) {
  /* Dos columnas y no una: veintitrés fichas en columna vuelven a ser una
     página interminable, que es justo lo que se acaba de arreglar. */
  .nomina-larga--docentes { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .nomina-larga--direccion { grid-template-columns: minmax(0, 1fr); }
}

/* ==========================================================================
   LAS CUATRO PUERTAS — «Cuatro maneras de conocer el colegio»
   --------------------------------------------------------------------------
   TERCERA VERSIÓN, y las dos anteriores están contadas porque explican ésta:

     1 · cuatro bloques de texto con un filete   → «no cobra vida»
     2 · cuatro fotografías con velo marino      → el cliente, 2026-09-10:
                                                    no más fotos de fondo
     3 · esto

   Con la fotografía fuera quedaban tres salidas y dos se descartan solas:

     · TARJETA BLANCA sobre campo claro. Rechazada ya dos veces en este
       proyecto —el índice de Familias y las fichas de rutas— y por la misma
       razón: la página YA es una superficie clara, así que una caja blanca
       encima añade un segundo nivel de superficie que no dice nada nuevo.
     · CARRUSEL, que era la referencia que trajo Andrés. Esconde tres de cada
       cuatro detrás de un gesto, y aquí hay que verlas TODAS para elegir. Y ya
       hay uno en la portada; repetirlo fundiría las dos secciones en una.

   Lo que queda es lo que el sistema ya sabía hacer, y por eso no parece un
   parche: la tarjeta es un BLOQUE MARINO sobre el campo claro —la misma
   inversión de campo que usan el pie y el acto del equipo—, y lo que la llena
   son las DOS FORMAS de las que está hecho el sitio entero, el círculo y el
   hilo recto. Un aro grande cortado por la esquina hace de peso visual donde
   antes iba la foto, y el signo de cada puerta se traza con el scroll igual
   que los tres valores de Vida Cervantista y los anillos de la portada.

   EL ORO DE LA TERCERA NO ES VARIEDAD. La ley del oro dice que sólo se pinta
   de oro lo que tiene un documento detrás; «Resultados y evidencia» es esa
   puerta y ninguna otra. Si mañana alguien reparte el oro entre las cuatro
   «para que combinen», la ley se rompe y el oro deja de significar nada.     */

.puertas {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(var(--e-4), 1.6vw, var(--e-6));
  margin: clamp(var(--e-7), 5vw, var(--e-8)) 0 0;
  padding: 0;
  list-style: none;
}

/* `.puerta__tarjeta` es la misma pieza SIN ENLACE (2026-09-14): los papeles de
   Cobertura Contratada y las funciones de App Cervantes. Comparte todo el
   aspecto; lo que no hereda son las reglas de :hover, que van sólo sobre el
   enlace, porque una tarjeta que se levanta promete un clic. */
.puerta__enlace,
.puerta__tarjeta {
  position: relative;
  display: grid;
  /* El signo arriba y el texto abajo, con TODO el aire en medio. Es lo que
     hace que la tarjeta se lea como un espacio y no como un bloque lleno. */
  grid-template-rows: auto 1fr auto;
  isolation: isolate;
  overflow: clip;
  min-height: clamp(17rem, 30vw, 25rem);
  padding: clamp(var(--e-5), 2.4vw, var(--e-7));
  border-radius: var(--radio-naipe, 1.4rem);
  color: #FFF;
  text-decoration: none;
  background: var(--campo-marino);
  transition: transform var(--dur-media) var(--sale),
              box-shadow var(--dur-media) var(--sale),
              background-color var(--dur-media) var(--sale);
}

/* EL ARO CORTADO POR LA ESQUINA. Es el peso visual que antes ponía la
   fotografía, y no es un adorno traído de fuera: es el mismo aro de la ruta
   pedagógica y de la senda, a otra escala y sin color propio. Sale por la
   esquina superior derecha a propósito —hacia donde no hay texto— y el `clip`
   del enlace lo corta: un círculo entero centrado sería una diana. */
.puerta__aro {
  position: absolute;
  z-index: -1;
  top: -38%;
  right: -14%;
  width: 78%;
  aspect-ratio: 1;
  border-radius: 50%;
  border: clamp(1rem, 2.6vw, 2rem) solid rgba(255, 255, 255, 0.055);
  pointer-events: none;
  transition: scale 720ms var(--sale), border-color var(--dur-media) var(--sale);
}

.puerta__enlace:hover,
.puerta__enlace:focus-visible {
  transform: translateY(-4px);
  background: #33377A;                       /* el marino un punto más vivo */
  box-shadow: 0 22px 48px rgba(8, 10, 26, 0.28);
}
.puerta__enlace:hover .puerta__aro,
.puerta__enlace:focus-visible .puerta__aro { scale: 1.09; border-color: rgba(143, 208, 240, 0.20); }
.puerta__enlace:focus-visible { outline: var(--hilo-trama) solid var(--oro); outline-offset: 3px; }

/* ---- La cima: el disco a un lado y el rótulo al otro ---------------------
   Van en la MISMA fila y no uno debajo del otro, y eso arregla lo que se veía
   mal en la primera prueba: con el signo suelto arriba a la izquierda quedaba
   un hueco muerto en diagonal, y la tarjeta se leía vacía por el centro. Con
   los dos anclados a los extremos, la fila de arriba es una fila y no un
   objeto perdido.                                                            */
.puerta__cima {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--e-4);
  grid-row: 1;
}

/* EL DISCO. El signo va DENTRO de un círculo, y esa es la pieza que hace que
   esta tarjeta pertenezca a este sitio y no a una plantilla: es el mismo disco
   de las caras del pórtico y de las fotos de las etapas, vacío y en pequeño.
   Sin él, el signo flotaba. */
.puerta__disco {
  display: grid;
  place-items: center;
  flex: none;
  width: clamp(4.4rem, 7vw, 5.8rem);
  aspect-ratio: 1;
  border-radius: 50%;
  border: var(--hilo-trama) solid rgba(143, 208, 240, 0.34);
  background: rgba(255, 255, 255, 0.05);
  transition: border-color var(--dur-media) var(--sale),
              background-color var(--dur-media) var(--sale),
              scale var(--dur-media) var(--sale);
}
.puerta--oro .puerta__disco { border-color: rgba(240, 180, 41, 0.40); }
.puerta__enlace:hover .puerta__disco,
.puerta__enlace:focus-visible .puerta__disco {
  scale: 1.06;
  border-color: #8FD0F0;
  background: rgba(143, 208, 240, 0.12);
}
.puerta--oro .puerta__enlace:hover .puerta__disco { border-color: var(--oro); }

/* Reutiliza `.signo` de los valores —mismo trazo, mismo `pathLength`, misma
   animación— y sólo cambia de talla y de color. Que sean el mismo componente
   es la mitad del argumento: dos juegos de iconos distintos en el mismo sitio
   web es lo que hace que un sitio parezca ensamblado. */
.puerta__disco .signo {
  width: 52%;
  color: #8FD0F0;
  stroke-width: 2.4;
}
.puerta--oro .puerta__disco .signo { color: var(--oro); }

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .puerta { view-timeline-name: --signo-puerta; }
    .puerta__disco .signo__aro,
    .puerta__disco .signo__hilo {
      stroke-dasharray: 1;
      animation: trazar-signo linear both;
      animation-timeline: --signo-puerta;
      animation-range: entry 22% entry 80%;
    }
  }
}

.puerta__dicho { display: grid; gap: var(--e-2); align-content: end; grid-row: 3; }
.puerta__marca {
  padding: 0.4em 0.95em;
  border-radius: var(--radio-cta);
  background: rgba(255, 255, 255, 0.10);
  border: var(--hilo-fino) solid rgba(255, 255, 255, 0.22);
  color: #CFE6F6;
  text-align: center;
}
.puerta__nombre {
  font-family: var(--fuente-titular);
  font-weight: var(--peso-titular);
  font-size: clamp(1.5rem, 2.8vw, 2.3rem);
  line-height: 1.06;
  letter-spacing: var(--tracking-display);
  text-wrap: balance;
}
.puerta__cuerpo {
  font-size: var(--t-sm);
  line-height: 1.5;
  color: rgba(255, 255, 255, 0.86);
  max-width: 44ch;
}
/* La retención se dice, no se disimula: dos de las cuatro esperan copy de
   Manuel y el visitante interno tiene que verlo. */
.puerta__estado { color: #8FD0F0; margin-top: var(--e-2); }
.puerta__ir {
  display: inline-flex;
  align-items: center;
  gap: var(--e-2);
  margin-top: var(--e-4);
  font-family: var(--fuente-titular);
  font-weight: 700;
  font-size: var(--t-xs);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding-bottom: 3px;
  border-bottom: var(--hilo-trama) solid var(--ceruleo);
  justify-self: start;
}
.puerta--oro .puerta__ir { border-bottom-color: var(--oro); }
.puerta__ir svg { width: 1em; height: 1em; flex: none; transition: translate var(--dur-media) var(--sale); }
.puerta__enlace:hover .puerta__ir svg,
.puerta__enlace:focus-visible .puerta__ir svg { translate: 0.35rem 0; }

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .puerta {
      animation: llegar-puerta linear both;
      animation-timeline: view();
      animation-range: entry 12% entry 58%;
    }
  }
}
@keyframes llegar-puerta {
  from { opacity: 0; translate: 0 2rem; }
  to   { opacity: 1; translate: 0 0; }
}

@media (prefers-reduced-motion: reduce) {
  .puerta__enlace, .puerta__aro, .puerta__ir svg { transition: none; }
}

@media (max-width: 48rem) {
  .puertas { grid-template-columns: minmax(0, 1fr); }
  .puerta__enlace, .puerta__tarjeta { min-height: auto; }
}

/* La tarjeta sin enlace lleva `<h3>` y `<p>` de verdad —en el enlace eran
   `<span>`, porque un enlace no puede contener un titular—, así que se les
   quitan el margen y la tinta que les da la base. */
.puerta__tarjeta .puerta__nombre { margin: 0; color: #FFF; }
.puerta__tarjeta .puerta__cuerpo { margin: 0; }

/* TRES COLUMNAS. Con tres, el titular de dos columnas —hasta 2,3rem— partía
   «Secretaría de Educación Municipal de Soacha» en cinco renglones. Se baja
   un escalón, y la tarjeta pide menos alto porque ya no hay tanto aire que
   llenar. Por debajo de 62rem pasa directo a una columna: en dos quedaría una
   tarjeta sola en la segunda fila. */
.puertas--tres { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.puertas--tres .puerta__tarjeta { min-height: clamp(20rem, 30vw, 26rem); }
.puertas--tres .puerta__nombre { font-size: clamp(1.35rem, 1.9vw, 1.8rem); }
.puertas--tres .puerta__disco { width: clamp(4rem, 5.6vw, 5rem); }
@media (max-width: 62rem) {
  .puertas--tres { grid-template-columns: minmax(0, 1fr); }
  .puertas--tres .puerta__tarjeta { min-height: auto; }
  .puertas--tres .puerta__dicho { margin-top: var(--e-6); }
}

/* ---- LA MISMA TARJETA, EN CLARO SOBRE CAMPO MARINO (2026-09-18) ----------
   Andrés: «quiero ese estilo de cartas» —las de «Cuatro maneras de conocer el
   colegio»— en los tres valores de Vida Cervantista y en los dos bloques de
   documentos y costos de Admisión Particular. Allí la tarjeta es marina porque
   el campo es claro; aquí el campo es marino, así que la tarjeta se invierte y
   todo lo demás se queda: el aro cortado por la esquina, el disco con su signo
   trazado al bajar, el rótulo en cápsula y el texto abajo.

   LAS TINTAS NO SE INVIERTEN SOLAS. Sobre blanco, el cerúleo claro del disco
   —#8FD0F0, que es el que se usa sobre marino— da 1,6:1 y desaparece; el oro,
   1,8:1. Por eso el signo pasa al cerúleo hondo, que sobre blanco da 5,3:1 y
   cumple de sobra el 3:1 que pide un gráfico.

   Y el aro de fondo baja al 7 % de marino: sobre blanco, la misma opacidad que
   se usa en la tarjeta oscura se veía como una mancha sucia.                */
.puerta--clara .puerta__tarjeta {
  background: #FFF;
  color: var(--tinta);
  box-shadow: 0 26px 52px -34px rgba(8, 10, 26, 0.65);
}
.puerta--clara .puerta__aro { border-color: rgba(42, 46, 104, 0.07); }
.puerta--clara .puerta__disco {
  border-color: rgba(0, 134, 192, 0.34);
  background: rgba(0, 134, 192, 0.06);
}
.puerta--clara .puerta__disco .signo { color: var(--ceruleo-hondo); }
.puerta--clara .puerta__marca {
  background: rgba(42, 46, 104, 0.06);
  border-color: rgba(42, 46, 104, 0.18);
  color: var(--ceruleo-hondo);
}
.puerta--clara .puerta__nombre { color: var(--marino); }
.puerta--clara .puerta__cuerpo { color: var(--tinta-suave); }


/* ==========================================================================
   APP CERVANTES — la landing de prueba (2026-09-14)
   ==========================================================================
   Una portada partida en dos: a la izquierda qué es y qué pasa ahora
   («próximamente»), a la derecha el teléfono. Todo lo demás de la página son
   piezas que ya existían —las tarjetas de /colegio/, los pasos con signo, el
   encabezado—; lo único nuevo es el teléfono, y está dibujado con los mismos
   colores y el mismo aro que el resto del sitio para que no parezca pegado.  */

.app__rejilla {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  align-items: center;
  gap: clamp(var(--e-7), 5vw, var(--e-10));
}
.app__dicho { display: grid; justify-items: start; }
.app__antetitulo { color: #8FD0F0; }
.app__titulo {
  margin: var(--e-4) 0 0;
  font-size: var(--display-2);
  line-height: 1;
  letter-spacing: var(--tracking-display);
  color: #FFF;
}
.app__lema {
  margin: var(--e-5) 0 0;
  font-family: var(--fuente-titular);
  font-weight: var(--peso-titular);
  font-size: clamp(1.3rem, 2.2vw, 1.75rem);
  line-height: 1.2;
  color: #8FD0F0;
  text-wrap: balance;
}
.app__entrada {
  margin: var(--e-4) 0 0;
  max-width: 44ch;
  font-size: var(--t-md);
  line-height: var(--interlinea-lead);
  color: var(--marino-tinte);
}
/* El aviso de «próximamente» en cápsula, con un punto de oro que late: dice
   que la cosa está viva y en camino sin prometer una fecha que nadie ha dado. */
.app__aviso {
  display: flex;
  align-items: center;
  gap: var(--e-3);
  margin: var(--e-6) 0 0;
  padding: 0.7em 1.2em;
  border-radius: var(--radio-cta);
  background: rgba(255, 255, 255, 0.08);
  border: var(--hilo-fino) solid rgba(255, 255, 255, 0.22);
  color: #FFF;
  font-size: var(--t-sm);
  line-height: 1.4;
}
.app__pulso {
  flex: none;
  width: 0.6rem;
  height: 0.6rem;
  border-radius: 50%;
  background: var(--oro);
}
@media (prefers-reduced-motion: no-preference) {
  .app__pulso { animation: latir-pulso 2.4s ease-out infinite; }
}
@keyframes latir-pulso {
  0%   { box-shadow: 0 0 0 0 rgba(240, 180, 41, 0.55); }
  70%  { box-shadow: 0 0 0 0.7rem rgba(240, 180, 41, 0); }
  100% { box-shadow: 0 0 0 0 rgba(240, 180, 41, 0); }
}
.app__acciones { justify-content: flex-start; margin-top: var(--e-7); }

/* ---- La escena ------------------------------------------------------------ */
.app__escena {
  position: relative;
  display: grid;
  place-items: center;
  min-height: clamp(30rem, 50vw, 42rem);
}
.app__aro {
  position: absolute;
  width: min(36rem, 100%);
  aspect-ratio: 1;
  border-radius: 50%;
  border: clamp(1rem, 2.6vw, 2rem) solid rgba(143, 208, 240, 0.12);
  pointer-events: none;
}
.app__aro--oro {
  width: clamp(5.5rem, 10vw, 8.5rem);
  top: 6%;
  right: 4%;
  border-width: clamp(0.5rem, 1vw, 0.8rem);
  border-color: var(--oro);
}
/* EL OSO VA DETRÁS DEL TELÉFONO, asomado por la izquierda con la pata en
   alto: la misma postura que tiene junto al botón de WhatsApp, así que se
   reconoce como el mismo personaje y no como un adorno más. */
/* DÓNDE CAE EL OSO, MEDIDO Y NO A OJO (2026-09-18). Andrés: «el celular le
   está tapando la cara». Y era literal: a 1.336 px el teléfono ocupa de 837 a
   1.131, y la cabeza del oso caía en 847 —diez píxeles dentro del filo—, así que
   asomaba el cuerpo y la pata pero no la cara, que es lo único que hace que se
   reconozca al personaje.
   Sale hacia la izquierda hasta que la CABEZA queda entera fuera del teléfono, y
   sube un punto: se sigue leyendo que está detrás —el hombro derecho y la pata
   siguen tapados— pero mira de frente. Crece un poco, porque un personaje que
   sólo asoma la cabeza pide algo más de cuerpo para no parecer un recorte. */
.app__oso {
  position: absolute;
  z-index: 0;
  left: -13%;
  bottom: 9%;
  height: 52%;
  width: auto;
  rotate: -6deg;
  filter: drop-shadow(0 16px 22px rgba(8, 10, 26, 0.45));
}

/* Entre 62 y 80 rem la escena se estrecha y el oso, que sale un 13 % por su
   izquierda, empezaba a montarse sobre la columna de texto —medido: 16 px a
   1.024 y 19 px a 1.180—. Sale menos; la cabeza sigue quedando fuera del
   teléfono, que es lo que hay que conservar. */
@media (min-width: 62.01rem) and (max-width: 80rem) {
  .app__oso { left: -5%; height: 49%; }
}

/* ---- El teléfono -----------------------------------------------------------
   Todo lo de dentro va en `em`, y la `em` sale del ancho del teléfono con
   `cqi`: la pantalla entera escala como una imagen y no se descuadra cuando el
   teléfono se achica en móvil. */
.telefono {
  position: relative;
  z-index: 1;
  container-type: inline-size;
  width: clamp(14.5rem, 22vw, 19rem);
  aspect-ratio: 9 / 19;
  padding: 0.65rem;
  border-radius: 2.7rem;
  background: #0E1030;
  box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.14),
              0 44px 80px -24px rgba(8, 10, 26, 0.75);
}
@media (prefers-reduced-motion: no-preference) {
  .telefono { animation: flotar-telefono 7s ease-in-out infinite alternate; }
}
@keyframes flotar-telefono {
  from { translate: 0 0; }
  to   { translate: 0 -0.8rem; }
}
.telefono__pantalla {
  position: relative;
  display: flex;
  flex-direction: column;
  height: 100%;
  overflow: hidden;
  border-radius: 2.1rem;
  background: var(--campo-cielo);
  color: var(--tinta);
  font-size: 0.72rem;
  font-size: 4cqi;
  line-height: 1.3;
  text-align: left;
}
.telefono__pantalla p { margin: 0; max-width: none; }
.pantalla__isla {
  position: absolute;
  z-index: 2;
  top: 0.7em;
  left: 50%;
  translate: -50% 0;
  width: 7em;
  height: 1.9em;
  border-radius: 1em;
  background: #0E1030;
}
.pantalla__cabeza {
  position: relative;
  overflow: hidden;
  padding: 3.1em 1.4em 1.5em;
  background: var(--marino);
  color: #FFF;
}
.pantalla__cabeza::after {
  content: '';
  position: absolute;
  top: -3.5em;
  right: -3.5em;
  width: 10em;
  aspect-ratio: 1;
  border-radius: 50%;
  border: 1.3em solid rgba(143, 208, 240, 0.1);
}
.pantalla__estado {
  position: absolute;
  top: 1em;
  left: 1.9em;
  right: 1.9em;
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 0.92em;
  font-weight: 600;
}
.pantalla__pila {
  position: relative;
  width: 1.9em;
  height: 0.95em;
  border: 1.5px solid #FFF;
  border-radius: 0.3em;
}
.pantalla__pila::after {
  content: '';
  position: absolute;
  inset: 1.5px;
  right: 30%;
  border-radius: 0.1em;
  background: #FFF;
}
.pantalla__marca {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.pantalla__marca img { display: block; height: 1.9em; width: auto; }
.pantalla__campana {
  position: relative;
  display: grid;
  place-items: center;
  width: 2.5em;
  height: 2.5em;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.1);
}
.pantalla__campana svg { width: 1.35em; height: 1.35em; }
.pantalla__punto {
  position: absolute;
  top: 0.5em;
  right: 0.55em;
  width: 0.55em;
  height: 0.55em;
  border-radius: 50%;
  background: var(--oro);
}
.pantalla__hola {
  position: relative;
  margin-top: 1.3em !important;
  font-family: var(--fuente-titular);
  font-weight: 700;
  font-size: 1.6em;
  line-height: 1.1;
}
.pantalla__fecha { position: relative; margin-top: 0.3em !important; font-size: 0.95em; color: var(--marino-tinte); }

.pantalla__cuerpo {
  flex: 1;
  display: grid;
  align-content: start;
  gap: 0.75em;
  padding: 1.1em 1em 0;
}
.pantalla__ficha {
  display: flex;
  align-items: center;
  gap: 0.9em;
  padding: 0.95em 1em;
  border-radius: 1em;
  background: #FFF;
  box-shadow: 0 0.5em 1.2em -0.8em rgba(42, 46, 104, 0.4);
}
.pantalla__ficha > div { min-width: 0; }
.pantalla__ficha--suelta { display: block; }
.pantalla__rotulo {
  display: flex;
  align-items: center;
  gap: 0.6em;
  font-size: 0.72em;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ceruleo-hondo);
}
.pantalla__chip {
  padding: 0.15em 0.65em;
  border-radius: 1em;
  background: var(--oro);
  color: var(--marino);
  letter-spacing: 0.04em;
}
.pantalla__titulo {
  margin-top: 0.3em !important;
  font-family: var(--fuente-titular);
  font-weight: 600;
  font-size: 1.02em;
  line-height: 1.25;
  color: var(--marino);
}
.pantalla__meta { margin-top: 0.35em !important; font-size: 0.82em; color: var(--tinta-suave); }
.pantalla__dia {
  flex: none;
  display: grid;
  place-content: center;
  gap: 0.2em;
  width: 3.3em;
  height: 3.5em;
  border-radius: 0.75em;
  background: var(--campo-cielo);
  color: var(--marino);
  text-align: center;
  line-height: 1;
}
.pantalla__dia b { font-size: 1.4em; font-weight: 700; }
.pantalla__dia span { font-size: 0.64em; font-weight: 700; letter-spacing: 0.08em; color: var(--ceruleo-hondo); }
/* El avance es el mismo aro del sistema, lleno hasta donde va el periodo. */
.pantalla__avance {
  flex: none;
  display: grid;
  place-items: center;
  width: 3.3em;
  aspect-ratio: 1;
  border-radius: 50%;
  background: conic-gradient(var(--ceruleo) calc(var(--avance, 0.5) * 1turn), var(--campo-cielo) 0);
}
.pantalla__avance::after {
  content: '';
  width: 68%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: #FFF;
}
.pantalla__pestanas {
  display: flex;
  justify-content: space-around;
  padding: 0.85em 0.5em 1.7em;
  background: #FFF;
  border-top: 1px solid rgba(42, 46, 104, 0.1);
}
.pantalla__pestana {
  display: grid;
  justify-items: center;
  gap: 0.3em;
  font-size: 0.68em;
  font-weight: 600;
  color: var(--tinta-suave);
}
.pantalla__pestana svg { width: 2.3em; height: 2.3em; }
.pantalla__pestana--activa { color: var(--ceruleo-hondo); }

/* En una columna el texto va primero y centrado, y el teléfono debajo. */
@media (max-width: 62rem) {
  .app__rejilla { grid-template-columns: minmax(0, 1fr); }
  .app__dicho { justify-items: center; text-align: center; }
  .app__entrada { margin-inline: auto; }
  .app__aviso { text-align: left; }
  .app__acciones { justify-content: center; }
  /* EN EL TELÉFONO LA ESCENA SE REPARTE, no se apila: centrado, el celular
     dejaba 59 px a cada lado y la cabeza del oso volvía a caer detrás de él.
     El celular se va al filo derecho y el oso se planta a su izquierda, con el
     hombro tapado y la cara entera fuera. */
  .app__escena { min-height: auto; padding-block: var(--e-6); place-items: center end; }
  .telefono { width: clamp(11.5rem, 52vw, 15rem); }
  .app__oso { left: 0; bottom: 6%; height: 44%; rotate: -5deg; }
}


/* ==========================================================================
   EL TELAR DE INTERNA — pantallas que se apilan
   --------------------------------------------------------------------------
   Andrés, 2026-09-10, con la referencia en la mano
   (https://demos.gsap.com/demo/pinned-panels-with-overscroll/): «como hicimos
   en la parte del home donde están preescolar, primaria, secundaria y media».

   ES LA MISMA PIEZA QUE `.ruta-telar` DE LA PORTADA y a propósito no se
   comparte el código, así que conviene decir por qué antes de que alguien lo
   «arregle» fundiéndolos: allí cada panel lleva su anillo trazándose, su
   lámina entrando y su disco brotando, y toda esa maquinaria cuelga de dos
   líneas de tiempo por panel. Aquí los paneles son TEXTO. Generalizar el de la
   portada habría obligado a arrastrar hasta Admisiones cinco relojes que no
   usa. Lo que se comparte es lo que de verdad se comparte: la cuenta.

   LA CUENTA, que es lo único delicado:

     alto de la hoja = 100svh (sube y cubre) + REPOSO + 100svh (la tapan)
     margen superior = -100svh, para montarse sobre la anterior

   Dentro, el `.pliego` es pegajoso y mide exactamente una pantalla, así que se
   queda clavado arriba mientras su hoja recorre esos tres tramos. La última
   hoja no tiene quien la tape, así que se le quitan esos 100svh finales: sin
   eso quedaba una pantalla de scroll en la que no pasaba nada antes del cierre.

   `--reposo` es la perilla del ritmo y aquí vale menos que en la portada
   —45svh contra 85— porque allí el reposo existe para que dé tiempo a
   dibujarse un anillo. Aquí sólo hay que leer cuatro renglones.

   Y EL CANTO SE TIENE QUE VER. Dos pantallas claras seguidas montándose una
   sobre otra no se leen como superposición si no hay un borde: por eso el
   filete de trama arriba y la sombra hacia arriba. Es la misma lección que
   dejó el cierre de la Home, donde el gesto NO funcionaba —14svh de recorrido
   no dan para leer nada— y por eso se retiró el mismo día que se puso éste.
   Aquí hay una pantalla entera de recorrido por panel: sobra.               */

.telar {
  position: relative;
  --reposo: 45svh;
  timeline-scope: --hoja-1, --hoja-2, --hoja-3, --hoja-4;
}

.telar__hoja { position: relative; min-height: calc(200svh + var(--reposo)); }
.telar__hoja + .telar__hoja { margin-top: -100svh; }
.telar__hoja:last-child { min-height: calc(100svh + var(--reposo)); }

.telar__hoja > .pliego {
  position: sticky;
  top: 0;
  /* `height` y no `min-height`: pegajoso sólo funciona si la caja mide
     exactamente lo que se ve. `min-height` la dejaría crecer con el contenido
     y el panel dejaría de clavarse. El `--cabecera` no se descuenta aquí —al
     revés que en un `.pliego` suelto— porque el panel tiene que TAPAR al
     anterior de borde a borde; el contenido va centrado y la cabecera flota
     encima, igual que en el telar de la portada. */
  height: 100svh;
  min-height: 0;
  border-top: var(--hilo-trama) solid var(--ceruleo);
  box-shadow: 0 -26px 70px rgba(16, 22, 48, 0.22);
  transform-origin: 50% 42%;
}
/* La primera no se monta sobre nada: sin filete, o se lee como una costura. */
.telar__hoja:first-child > .pliego { border-top: 0; box-shadow: none; }

.telar__hoja:nth-child(1) > .pliego { view-timeline-name: --hoja-1; }
.telar__hoja:nth-child(2) > .pliego { view-timeline-name: --hoja-2; }
.telar__hoja:nth-child(3) > .pliego { view-timeline-name: --hoja-3; }
.telar__hoja:nth-child(4) > .pliego { view-timeline-name: --hoja-4; }

/* EL RETROCESO LO DISPARA LA HOJA SIGUIENTE. Su fase `entry` dura exactamente
   una pantalla, que es justo el tramo en el que sube desde el borde inferior
   hasta cubrir del todo. La que retrocede lee el reloj de la que la tapa. */
@supports (timeline-scope: --a) {
  @media (prefers-reduced-motion: no-preference) {
    .telar__hoja:nth-child(1) > .pliego { animation-timeline: --hoja-2; }
    .telar__hoja:nth-child(2) > .pliego { animation-timeline: --hoja-3; }
    .telar__hoja:nth-child(3) > .pliego { animation-timeline: --hoja-4; }
    .telar__hoja:nth-child(-n+3) > .pliego {
      animation-name: recular-hoja;
      animation-timing-function: linear;
      animation-fill-mode: both;
      animation-range: entry 0% entry 100%;
    }
    /* La cuarta no retrocede: no tiene quien la cubra. */

    /* El contenido entra mientras el panel SUBE, con su propio reloj —el de la
       hoja que lo lleva—, para que no aparezca ya puesto al descubrirse. */
    .telar__hoja:nth-child(1) .encabezado { animation-timeline: --hoja-1; }
    .telar__hoja:nth-child(2) .encabezado { animation-timeline: --hoja-2; }
    .telar__hoja:nth-child(3) .encabezado { animation-timeline: --hoja-3; }
    .telar__hoja:nth-child(4) .encabezado { animation-timeline: --hoja-4; }
    .telar__hoja .encabezado {
      animation-name: entrar-hoja;
      animation-timing-function: linear;
      animation-fill-mode: both;
      animation-range: entry 25% entry 92%;
    }
  }
}
@keyframes recular-hoja {
  0%   { transform: scale(1);    opacity: 1; }
  86%  { transform: scale(0.92); opacity: 0.55; }
  100% { transform: scale(0.90); opacity: 0; }
}
@keyframes entrar-hoja {
  from { opacity: 0; translate: 0 1.8rem; }
  to   { opacity: 1; translate: 0 0; }
}

/* ---- LOS AROS DE CADA HOJA ----------------------------------------------
   Andrés, viendo las cuatro puertas de `/colegio/`: «quiero que tengan ese
   mismo estilo, el circulito así con opacidad, y alguna animación».

   NO ES UN ARO NUEVO: es `.anillo`, la misma pieza que traza los círculos de
   la ruta pedagógica y de la promesa en la portada —el mismo `@property
   --trazo`, la misma máscara cónica y el mismo `trazar-anillo`—, sólo que fino
   y casi transparente. Reutilizarlo en vez de dibujar otro círculo es lo que
   hace que Admisiones se lea como la misma casa que la portada.

   Dos por hoja, en esquinas OPUESTAS y cambiando el reparto de una a otra: si
   los ocho cayeran en el mismo sitio, cuatro pantallas apiladas se leerían como
   una plantilla repetida cuatro veces en vez de como cuatro momentos.

   Y SE TRAZAN MIENTRAS EL PANEL SUBE, no cuando ya está quieto: el gesto tiene
   que coincidir con la llegada. El menor entra corrido respecto al mayor, que
   es lo mismo que hacen los cinco discos del pórtico. */

.telar__hoja > .pliego > .lienzo,
.montaje__hoja > .lienzo { position: relative; z-index: 1; }

.hoja__aro {
  /* Fino, no macizo: los de la portada son de 2,6rem porque allí el aro ES la
     pieza; aquí es el fondo y tiene que quedarse detrás del texto. */
  --grosor-anillo: clamp(0.7rem, 1.6vw, 1.4rem);
  color: rgba(42, 46, 104, 0.10);
}
.es-marino .hoja__aro { color: rgba(255, 255, 255, 0.075); }
/* EL ARO DE ORO — sólido, no translúcido (2026-09-10) ---------------------
   Andrés: «coloca uno de ellos amarillo en las partes azules, ya no en
   opacidad, sino que se vea el amarillo; y uno en las partes claras también».
   Es el mismo aro, el mismo trazado con el scroll; lo único que cambia es que
   deja de ser un fondo y pasa a ser una PIEZA.

   Y HAY QUE DECIR QUÉ CUESTA, para que la regla siga siendo una regla. La ley
   del oro de este sistema dice que el oro es la marca de lo comprobable, y un
   aro decorativo no comprueba nada. Lo que la mantiene en pie es dónde se
   traza la raya, y la raya ya estaba trazada antes de hoy: los botones
   primarios llevan oro de relleno desde el principio y nadie los lee como
   evidencia, porque el oro que significa PRUEBA es el del texto y la cifra
   —«Resolución 0024», el 298 de Saber 11, el filete de `.aval`—, no el de una
   superficie.

   Así que la ley se afina, no se rompe:
     · oro en TEXTO, CIFRA o FILETE de dato  → sólo con documento detrás
     · oro como SUPERFICIE o TRAZO           → puede ser gesto (botón, aro)
   Lo que no puede pasar nunca es que un número o un rótulo se pinten de oro
   sin resolución que lo respalde. Si alguien mañana usa este aro como fondo
   de una cifra, ahí sí se rompe.

   Uno por pantalla y ni uno más: es el acento, y dos acentos no son acento.

   LAS DOS CLASES VAN ENCADENADAS, y no es un tic: `.es-marino .hoja__aro` vale
   0,2,0 y `.hoja__aro--oro` a secas valdría 0,1,0, así que el campo ganaba y el
   aro salía blanco al 7,5 % —comprobado en pantalla—. Es el MISMO empate que ya
   dejó invisibles las cápsulas de antetítulo y los titulares con mancha en este
   mismo proyecto. Cuando dos reglas legítimas se disputan una propiedad, se
   encadena; confiar en el orden del archivo es lo que rompe al siguiente que
   mueva un bloque. */
.hoja__aro.hoja__aro--oro { color: var(--oro); }

.hoja__aro--mayor { width: clamp(20rem, 42vw, 42rem); }
.hoja__aro--menor {
  width: clamp(7rem, 14vw, 14rem);
  --grosor-anillo: clamp(0.45rem, 0.95vw, 0.9rem);
}

.hoja__aro--arriba-der  { top: -19%;    right: -9%; }
.hoja__aro--arriba-izq  { top: -21%;    left:  -11%; }
.hoja__aro--abajo-izq   { bottom: -23%; left:  -12%; }
.hoja__aro--abajo-der   { bottom: -17%; right: -8%; }
/* Los menores no salen tanto: un aro pequeño cortado por la mitad no se lee
   como un aro, se lee como una mancha. */
.hoja__aro--menor.hoja__aro--arriba-der { top: 9%;  right: 5%; }
.hoja__aro--menor.hoja__aro--arriba-izq { top: 11%; left:  5%; }
.hoja__aro--menor.hoja__aro--abajo-izq  { bottom: 10%; left:  6%; }
.hoja__aro--menor.hoja__aro--abajo-der  { bottom: 9%;  right: 6%; }

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .telar__hoja:nth-child(1) .hoja__aro { animation-timeline: --hoja-1; }
    .telar__hoja:nth-child(2) .hoja__aro { animation-timeline: --hoja-2; }
    .telar__hoja:nth-child(3) .hoja__aro { animation-timeline: --hoja-3; }
    .telar__hoja:nth-child(4) .hoja__aro { animation-timeline: --hoja-4; }
    .telar__hoja .hoja__aro {
      animation-name: trazar-anillo;      /* vive en actos.css */
      animation-timing-function: linear;
      animation-fill-mode: both;
      animation-range: entry 18% entry 90%;
    }
    .telar__hoja .hoja__aro--menor { animation-range: entry 42% entry 100%; }
  }
}

/* ==========================================================================
   EL MONTAJE — una sola pantalla que sube y tapa a la anterior
   --------------------------------------------------------------------------
   Andrés, sobre el cierre de Propuesta Educativa: «que se superpusiera al
   último slide de la etapa cuatro, que lo tapara, como en las otras
   secciones». Es el gesto del telar, pero aquí sube UNA sola pantalla, así que
   no hacen falta hojas ni relojes cruzados.

   CÓMO SE MONTA SIN DEJAR HUECO. El margen negativo y el desplazamiento se
   cancelan al principio y se suman al final:

     `margin-top: -100svh`   el flujo YA cuenta con que sube; sin esto quedaría
                             un agujero de una pantalla mientras dura el gesto
     `translateY: 100svh→0`  al empezar compensa el margen —la sección está en
                             su sitio natural, justo después de la senda— y al
                             terminar sube y cubre la última etapa

   POR QUÉ AQUÍ SÍ Y EN LA HOME NO. El cierre de la Home hacía esto mismo con
   14svh y el cliente lo vio: «hay un salto, no se nota la animación». Se
   retiró esta misma mañana. La diferencia no es el código, es el RECORRIDO:
   una pantalla entera da tiempo a leer el gesto; 14svh sólo dan el tirón.

   Y el canto se tiene que ver —marino subiendo sobre marino no se lee solo—,
   de ahí el filete de trama y la sombra hacia arriba.                        */

/* LA COLA QUE SE DEJA TAPAR. Sin esto el gesto se come una pantalla entera de
   la sección de arriba, y en Propuesta esa pantalla era la etapa 04 completa:
   medido, la parada iba de 4293 a 5049 y el cierre empezaba a taparla en 4275,
   o sea desde su primer píxel. El lector no llegaba a verla.

   La cola vale «una pantalla MENOS 6rem», y esa resta en píxeles fijos —no
   en svh— es lo único delicado de la cuenta. Con la resta en svh el margen se
   iba a negativo en ventanas altas: a 880 sobraban 21 px y a 1000 faltaban 10,
   o sea que la ilustración se cortaba en un portátil grande y no en el mío.
   En píxeles, lo que el cierre se come es SIEMPRE lo mismo y el margen no
   depende del alto de la ventana.

   LA CUENTA, para quien tenga que rehacerla:

     línea de tapado = fin del contenido de la senda + `--e-9` − 6rem

   y hay que comprobar que quede POR DEBAJO de lo último que se ve de la parada
   04. Medido en cuatro ventanas —1400×880, 1440×1000, 1280×700 y 1024×800—
   sobran entre 77 y 206 px. Con 13rem, que era el primer número, a 1280×700
   faltaban 35 y el dibujo se cortaba: el alto de la parada depende del ancho
   de la ventana, así que no basta con medir en una. Si se toca el recorrido de
   `.montaje`, esta resta se rehace y se vuelve a medir en las cuatro. */
.senda--montada { padding-bottom: calc(var(--e-9) + 100svh - 6rem); }

.montaje { position: relative; z-index: 3; }
.montaje__hoja { border-top: var(--hilo-trama) solid var(--ceruleo); }

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .montaje {
      --monta: 100svh;
      margin-top: calc(-1 * var(--monta));
    }
    .montaje__hoja {
      box-shadow: 0 -30px 80px rgba(6, 8, 20, 0.5);
      animation: montar-hoja linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 100%;
    }
  }
}
@keyframes montar-hoja {
  from { translate: 0 var(--monta); }
  to   { translate: 0 0; }
}

/* Los aros de esta pantalla leen SU PROPIO reloj. Va con nombre y no con
   `view()` suelto en cada aro por una razón práctica: así los dos se trazan
   contra la misma referencia —la llegada del panel— y no cada uno contra su
   propia caja, que está en otro sitio dentro de la pantalla. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .montaje__hoja { view-timeline-name: --monta-hoja; }
    .montaje__hoja .hoja__aro {
      animation-name: trazar-anillo;      /* vive en actos.css */
      animation-timing-function: linear;
      animation-fill-mode: both;
      animation-timeline: --monta-hoja;
      animation-range: entry 22% entry 88%;
    }
    .montaje__hoja .hoja__aro--menor { animation-range: entry 45% entry 100%; }
  }
}

/* En teléfono no se monta nada: una pantalla que tapa a otra en un móvil es
   una pantalla que el pulgar no consigue dejar atrás. Es la misma decisión que
   toma el telar por debajo de 52rem. */
@media (max-width: 52rem) {
  .montaje { margin-top: 0; }
  .montaje__hoja { animation: none; translate: none; box-shadow: none; }
  /* Y sin gesto, la cola no tiene a quién dejarse tapar: sería una pantalla
     de nada al final de la senda. */
  .senda--montada { padding-bottom: clamp(var(--e-9), 12vh, 8rem); }
}

/* ---- Teléfono: sin apilado, sin reposo, sin retroceso --------------------
   Lo mismo que hace el telar de la portada por debajo de 52rem, y por la misma
   razón: cuatro pantallas clavadas en un móvil son cuatro pantallas en las que
   el pulgar no consigue avanzar. Aquí las cuatro vuelven a ser cuatro
   secciones normales, una detrás de otra. */
@media (max-width: 52rem) {
  .telar__hoja,
  .telar__hoja + .telar__hoja,
  .telar__hoja:last-child { min-height: auto; margin-top: 0; }
  .telar__hoja > .pliego {
    /* `relative` y no `static`: basta para desactivar el pegajoso, y hace
       falta porque los aros van `absolute`. Con `static` el pliego deja de ser
       su bloque contenedor, los aros se cuelgan de `.telar` —que no recorta— y
       el documento se desbordaba 31 px a 390. Lo cazó el barrido de desbordes. */
    position: relative;
    height: auto;
    min-height: calc(100svh - var(--cabecera));
    animation: none;
    opacity: 1;
    transform: none;
    box-shadow: none;
  }
  .telar__hoja .encabezado { animation: none; opacity: 1; translate: none; }
  /* Los aros se quedan —son el fondo— pero sin trazarse: sin apilado no hay
     llegada que acompañar. El menor se va: en 390 px cae encima del titular. */
  .telar__hoja .hoja__aro { animation: none; }
  .telar__hoja .hoja__aro--menor { display: none; }
  .hoja__aro--mayor { width: clamp(16rem, 62vw, 24rem); }
}
