/* El parche del cromo, común a las diez. Va SIEMPRE al final de lo común.
   Trasladado de la maqueta aprobada (portada-con-servicios.html) por
   herramientas/trasladar-portada.mjs. No se edita a mano: se cambia la maqueta
   y se vuelve a trasladar. */

/* ══ EL ENLACE A LA POLÍTICA, EN EL RENGLÓN LEGAL DEL PIE ══════════════
   El renglón legal del pie heredado no tenía ningún enlace, así que la hoja
   no tenía ninguna regla para uno. El primero que se puso —el 20-09— salió
   con el azul de fábrica del navegador, #0000EE, sobre la banda negra:
   **1,98 contra un mínimo de 4,5**. Medido, no supuesto, y es justo la
   clase de fallo que no se ve mirando —el enlace se lee, sólo que mal—.

   Va en --banda-tinta, que es lo que usan los demás enlaces del pie, y
   subrayado, que es lo que lo distingue del texto legal que tiene al lado.
   En papel el parche redefine --banda-tinta a tinta oscura, así que este
   enlace se imprime negro sobre blanco sin regla aparte. */
.ep-pie__priv{color:var(--banda-tinta);text-decoration:underline;
  text-underline-offset:2px}
.ep-pie__priv:hover{color:var(--banda-acento)}
.ep-pie__priv:focus-visible{outline:var(--marca) solid var(--banda-tinta);outline-offset:2px}
/* En su propia página va como <span>: ni subrayado ni color de enlace. */
span.ep-pie__priv{color:var(--banda-gris);text-decoration:none}

/* ══ EL PANEL LATERAL · SIN FILETES DOBLES ══════════════════════════════
   Visto por el Director el 21-09: el panel dibujaba DOS rayas paralelas,
   separadas 40 px, en dos sitios. Arriba, la de debajo de la cabecera
   —logo y «Cerrar»— y la de encima del primer renglón de la lista. Abajo,
   la de debajo del último renglón y la de encima del bloque de contacto.
   Cada pareja hacía el mismo trabajo dos veces, y el hueco entre las dos se
   leía como un renglón vacío.

   Se queda la de la lista, que es la que define los renglones, y se van las
   otras dos. El bloque de contacto pierde también el relleno que tenía
   para separarse de su raya: sin raya, sólo añadía hueco. */
.ep-menu__top{border-bottom:0}
[data-menu=lateral] .ep-menu__lado{border-top:0;padding-top:0}

/* ══ «SERVICIOS», BOTÓN EN SUS TRES SITIOS · 21-09 ══════════════════════
   Visten exactamente como los enlaces a los que sustituyen: un botón con
   la cara de un enlace de menú, para que nadie note el cambio salvo el
   teclado y el lector de pantalla. Ver parcheMenu. */
.ep-nav__menu .ep-nav__desp{display:inline-flex;align-items:center;min-height:44px;padding:0 2px;
  font:inherit;font-size:var(--txt-m);color:var(--tinta);background:none;border:0;
  border-bottom:var(--marca) solid transparent;cursor:pointer;transition:border-color .2s,color .2s}
.ep-nav__menu .ep-nav__desp:hover,.ep-nav__menu>li[data-abierto]>.ep-nav__desp{
  border-bottom-color:var(--acento);color:var(--acento-fuerte)}
.ep-nav__menu .ep-nav__desp:focus-visible{outline:var(--marca) solid var(--tinta);outline-offset:2px}
.ep-nav__menu>li[data-abierto]>.ep-nav__sub{opacity:1;visibility:visible;transform:none}

/* ══ EL BOTÓN MANDA: LA LLAVE QUE CIERRA · 05-10-2026 ═══════════════════
   Hallazgo del Director usando el sitio: el desplegable «Servicios» NO se
   cerraba al volver a pulsar el botón. Sólo se cerraba pulsando en otro
   sitio. Medido con clics de ratón de verdad: abierto, abierto, abierto,
   abierto — nunca se cerraba, y «al bajar» no tenía nada que ver.

   La causa: el submenú lo abren TRES llaves, y el botón sólo tenía una. Las
   dos de la base (base.css:80) son «:hover» y «:focus-within» sobre el <li>;
   la tercera es el «data-abierto» que pone el guion, aquí arriba. Pulsar con
   el ratón ENFOCA el botón, y el botón vive dentro del <li>: así que apagar
   «data-abierto» no cerraba nada, porque «:focus-within» seguía abriendo. El
   atributo alternaba; lo que se veía, no. Viene de antes de esta rama.

   El arreglo es una CUARTA llave, y ésta cierra: «data-cerrado». La pone el
   botón al cerrar —y la tecla Escape—, y la quita cualquier gesto nuevo que
   de verdad quiera abrir: el puntero entrando en el <li>, el foco llegando
   de fuera, o el propio botón al abrir. Va DESPUÉS de las reglas que abren,
   que es lo que la hace ganar: misma especificidad, y la última manda
   (REGLAS-DEL-SITIO §6.1). Deja el submenú en su estado cerrado de siempre,
   el de «.ep-nav__sub» en base.css, transición incluida.

   SIN JAVASCRIPT NO CAMBIA NADA, y era la condición del encargo: nadie pone
   «data-cerrado» si el guion no corre, así que esta regla se queda inerte y
   el submenú sigue abriéndose con el ratón y con el teclado, por CSS puro.
   Por eso la llave es un atributo que pone el guion y NO «html[data-js]»:
   colgada de «data-js» la regla se activaría con la marca del <head>, y si
   «menu.js» no llegara a cargarse el submenú no se abriría de ninguna
   manera. Así, lo que apaga el CSS y lo que lo vuelve a encender viajan
   juntos. Y «base.css» no se toca (invariante de la Tarea 9). */
.ep-nav__menu>li[data-cerrado]>.ep-nav__sub{opacity:0;visibility:hidden;transform:translateY(-4px)}
.ep-nav__corto button{display:inline-flex;align-items:baseline;gap:var(--e-1);min-height:44px;
  padding:0;font:inherit;font-size:var(--txt-m);font-weight:600;color:var(--tinta);
  background:none;border:0;cursor:pointer;transition:color .2s}
.ep-nav__corto button:hover{color:var(--acento-fuerte)}
.ep-nav__corto button:hover i{color:var(--acento)}
.ep-nav__corto button:focus-visible{outline:var(--marca) solid var(--tinta);outline-offset:2px}

/* En el panel: el renglón 02 se abre y cierra, con un «+» a la derecha que
   gira a «×» cuando está abierto. Las tres líneas van debajo, sangradas a
   la altura del texto —no del número—, sin filete propio y en tamaño de
   enlace, no de titular: son hijas del renglón, no renglones nuevos. */
.ep-menu__desp{display:flex;align-items:baseline;gap:var(--e-3);width:100%;min-height:56px;
  padding:var(--e-1) 0;font:inherit;font-size:var(--txt-xl);font-weight:700;letter-spacing:-.02em;
  color:var(--tinta);background:none;border:0;text-align:left;cursor:pointer;transition:color .2s}
.ep-menu__desp:hover{color:var(--azul-texto)}
.ep-menu__desp:focus-visible{outline:var(--marca) solid var(--tinta);outline-offset:-4px}
.ep-menu__flecha{margin-left:auto;align-self:center;padding:0 var(--e-1);font-family:var(--f-mono);
  font-size:var(--txt-l);font-weight:400;line-height:1;color:var(--acento);transition:transform .2s}
.ep-menu__desp[aria-expanded=true] .ep-menu__flecha{transform:rotate(45deg)}
.ep-menu__nav .ep-menu__sub{list-style:none;margin:0 0 var(--e-2);
  padding:0 0 0 calc(var(--e-3) + 1.2 * var(--mono))}
.ep-menu__nav .ep-menu__sub li,.ep-menu__nav .ep-menu__sub li:last-child{border:0}
[data-menu=lateral] .ep-menu__nav .ep-menu__sub a,.ep-menu__nav .ep-menu__sub a{display:flex;
  align-items:center;min-height:44px;padding:0;font-size:var(--txt-m);font-weight:600;
  letter-spacing:0;color:var(--tinta);text-decoration:none}
.ep-menu__nav .ep-menu__sub a:hover{color:var(--azul-texto);transform:none}
.ep-menu__nav .ep-menu__sub a:focus-visible{outline:var(--marca) solid var(--tinta);outline-offset:2px}
@media (prefers-reduced-motion:reduce){.ep-menu__flecha{transition:none}}

/* El panel abierto es un diálogo: la página de detrás no se desplaza. */
html[data-panel=abierto]{overflow:hidden}

/* ══ 1 · EL PIE, EN PAPEL ══════════════════════════════════════════════
   Chrome imprime SIN fondos por omisión. El pie es una banda oscura con
   texto claro, y sus colores viven en una familia propia —--banda-*— que
   los bloques @media print de las pantallas no redefinían: redefinían
   --tinta, --gris, --fondo y siete más, y se dejaban ésta.

   Resultado medido el 20-09: los enlaces, los dos correos y el teléfono
   salían a **2,75 sobre 4,5**. Un documento corporativo que se imprime sin
   sus datos de contacto.

   Se redefine la familia entera, en los dos temas: en papel no hay tema
   oscuro que valga. */
@media print{
  :root,:root[data-tema=oscuro]{
    --banda:#fff;--banda-tinta:#121315;--banda-gris:#3f434a;
    --banda-acento:#121315;--banda-linea:#c8ccd2}
  .ep-pie{border-top:var(--marca) solid #121315}
  /* Los iconos de redes son PNG blancos: sobre papel blanco no existen.
     Dos de los tres desaparecían. En vez de invertirlos —el de Facebook sí
     tiene color y saldría de otro color— se cambian por su propio nombre,
     que es lo que el <a> ya lleva escrito para los lectores de pantalla. */
  .ep-pie__redes{gap:var(--e-2)}
  .ep-pie__redes img{display:none}
  .ep-pie__redes a{padding:0;min-width:0;min-height:0}
  .ep-pie__redes a::after{content:attr(aria-label);
    font-family:var(--f-mono);font-size:10px;letter-spacing:.06em;color:#3f434a}
  /* Y el conmutador de tema es un mando muerto en una hoja de papel. */
  .ep-pie__conmut,.ep-pie__tema{display:none}
  /* La columna de contacto se ensancha sólo en papel. En pantalla el correo
     cabe; impreso, con los márgenes de la hoja comiéndose el ancho, partía
     en «eprojectperu.​com» — y un correo partido se copia mal a mano.
     Es el reparto de siempre, sólo que contando con el margen del papel. */
  .ep-pie__grid{grid-template-columns:minmax(0,1.2fr) minmax(0,1fr) minmax(0,1.1fr) minmax(0,1.7fr)}
}

/* ══ 2 · EL MANDO FLOTANTE, INVISIBLE PERO ENFOCABLE ═══════════════════
   `.ep-nav__flotante` se ocultaba con `opacity:0` y `pointer-events:none`.
   Eso lo quita del ratón y de la vista, **pero no del teclado**: seguía en
   el orden de tabulación. La SEGUNDA tabulación de cualquier página llevaba
   el foco a un sitio que no se ve.

   `visibility:hidden` sí lo saca del orden de tabulación. La transición
   lleva `visibility 0s linear .25s` para que se esconda cuando el fundido
   ya terminó, y no de golpe al empezar. */
.ep-nav__flotante{visibility:hidden;
  transition:opacity .25s ease,transform .25s ease,visibility 0s linear .25s}
[data-fijo=si] .ep-nav__flotante{visibility:visible;transition-delay:0s,0s,0s}
@media (prefers-reduced-motion:reduce){
  .ep-nav__flotante{transition:none}}

/* ══ 3 · EL DESBORDE CON LA LETRA GRANDE DEL SISTEMA ═══════════════════
   Medido el 20-09 con la raíz a 32 px —el 200 % que exige WCAG 1.4.4—:
   **+389 px a 1280 y +219 a 390**. Había que arrastrar la página de lado
   para leerla. Son dos causas distintas y las dos están aquí.

   ── 3a · La barra no se doblaba ──
   `.ep-nav__fila` es un flex de una sola línea. A 1280 con letra grande,
   el botón de «Consultar un certificado» y el de MENÚ se salían 389 px.
   Con `flex-wrap:wrap` la barra crece hacia abajo en vez de hacia fuera, y
   con letra normal no cambia nada porque ahí sobra sitio. */
.ep-nav__fila{flex-wrap:wrap;row-gap:var(--e-2)}
.ep-nav__menu{flex-wrap:wrap;min-width:0}

/*   ── 3b · Los suelos de clamp() crecían sin techo ──
   Los tres titulares grandes usan `clamp(SUELO, Ncqi, TECHO)` con el suelo
   en `rem`. El suelo es lo que manda cuando la columna es estrecha, y un
   `rem` sigue a la letra del usuario: a 32 px de raíz, el H1 computaba
   **68 px en una pantalla de 390**, y «cumplimiento» no cabe.

   El suelo pasa a `min(SUELO, Xvw)`: no puede pasar de una fracción del
   ancho de la ventana. Los factores NO son de gusto — están elegidos para
   que a **320 px, con letra normal, el min() no muerda**: 11vw de 320 son
   35,2 y el suelo es 34; 14vw son 44,8 y el suelo 44; 8vw son 25,6 y el
   suelo 24. Es decir: **con letra normal, en ningún ancho soportado cambia
   nada**; sólo actúa cuando la raíz crece. Si alguien toca estos números,
   hay que rehacer esa cuenta contra el ancho más estrecho de la lista.

   El cuerpo del texto sigue en rem y sin tope: lo que se limita es cuánto
   crece un titular, no cuánto crece lo que hay que leer. */
:root{
  --tit-m:min(2.125rem,11vw);
  --tit-l:clamp(min(2.125rem,11vw),5cqi,3.25rem);
  --tit-xl:clamp(min(2.75rem,14vw),12cqi,7rem);
  --cifra-m:clamp(min(1.5rem,8vw),3cqi,2rem);
}

/*   ── 3c · Las rejas de fr sin minmax(0,…) ──
   Ésta es la que costó encontrar, y la que de verdad desbordaba: una pista
   `1.3fr` **no puede encogerse por debajo de su contenido**, porque el
   mínimo implícito de un `fr` es `auto`, no cero. Con la letra a 32 px el
   titular de «Hablemos» pedía 569 px dentro de una columna de 310, y la
   reja se lo daba: la página crecía a lo ancho en vez de partir la palabra.

   `minmax(0,…)` le devuelve a la pista el derecho a encogerse. Es el
   arreglo de una línea que más veces se olvida en CSS Grid, y estaba en las
   dos rejas del cromo: la de «Hablemos» y la de las cuatro columnas del pie.
   El `overflow-wrap` es el cinturón: cuando ni encogiendo cabe la palabra,
   se parte en vez de salirse. */
.ep-contacto{grid-template-columns:minmax(0,1.3fr) minmax(0,1fr)}
@media (max-width:760px){.ep-contacto{grid-template-columns:minmax(0,1fr)}}
.ep-contacto__texto,.ep-contacto__datos{min-width:0}

/*   ── 3d · Lo que ni encogiendo cabe: el correo ──
   Con la pista ya libre de encogerse, quedaba dentro algo que no encoge:
   `informes@eprojectperu.com` a 32 px mide 455 px y no tiene un solo sitio
   por donde partir. Dos cosas hacían falta a la vez, y las dos son la misma
   lección que dio el bloque de datos de Contacto el 20-09:

   **`overflow-wrap:anywhere` y no `break-word`.** Sólo `anywhere` cuenta
   para el ancho mínimo de la caja; con `break-word` la pista sigue pidiendo
   el ancho de la palabra entera y la reja se lo da.

   **Y el enlace deja de ser `inline-flex`.** Un contenedor flex no parte el
   texto de dentro, así que el correo salía igual. `inline-block` conserva
   el objetivo táctil de 24 px y deja partir. */
.ep-contacto__tit,.ep-contacto__datos dd,.ep-pie__col a,
.ep-pie__contacto li,.ep-pie__lema{overflow-wrap:anywhere}
.ep-pie__contacto a{display:inline-block;overflow-wrap:anywhere}
/*   Y aquí una trampa que este parche pisó la primera vez, y que vale para
   cualquier cosa que se emita al final de una hoja: **una regla sin @media
   puesta abajo anula las @media de arriba**. El pie se reparte en cuatro
   columnas, baja a dos por debajo de 900 y a una por debajo de 560, con dos
   medias heredadas. Un `grid-template-columns` suelto al final se las comió
   las dos: el pie se quedó en cuatro columnas a 320 px y el desborde pasó de
   175 a 398. Cada corrección viaja con el mismo corte que corrige. */
/*   Y van con `screen`, no sueltas: al imprimir, la hoja mide más de 901 px
   y este reparto le ganaba al de @media print unas líneas más arriba, que es
   justamente el que hace que el correo no se parta. Dos medias que se pisan
   sin que ninguna esté mal por su cuenta — la misma forma de error que el
   corte por ventana contra el corte por contenedor. */
@media screen and (min-width:901px){
  .ep-pie__grid{grid-template-columns:minmax(0,1.7fr) minmax(0,1fr) minmax(0,1fr) minmax(0,1.2fr)}}
@media screen and (max-width:900px){.ep-pie__grid{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}}
@media screen and (max-width:560px){.ep-pie__grid{grid-template-columns:minmax(0,1fr)}}
/* ══ LA LETRA GRANDE · 21-09, para TODAS las pantallas ═════════════════
   Con la letra del navegador al doble (32 px de raíz) nueve de las diez
   pantallas se salían de lado —hasta 405 px— en algún ancho: palabras largas
   sin punto de corte, campos de formulario con ancho propio. La regla que
   el proyecto ya había aplicado caso a caso (REGLAS §4: «anywhere» y no
   «break-word», porque solo «anywhere» reduce el ancho mínimo) va ahora para
   todo, con :where() para no ganarle a ninguna regla de página.
   Medido antes de ponerla: con letra 16 la geometría de las diez pantallas
   no cambia, salvo lo que se mueve solo (carruseles). Los glifos de pausa
   quedan fuera: «❙❙» se partía en dos renglones. */
body :where(*){overflow-wrap:anywhere}
body :where([class*="glifo"],[class*="pausa"]){overflow-wrap:normal;white-space:nowrap}
body :where(input,select,textarea,img,video){max-width:100%}
/* EL PIE, IGUAL EN TODAS LAS PANTALLAS · 22-09, Director. Cinco pantallas lo
   llevaban con el logotipo a 56 px y la letra mono Chivo (portada, las tres
   líneas y Nosotros) y cinco con el logotipo a 34 y la mono del sistema
   (Contacto, Postula, la convocatoria, Privacidad y 404). Manda el de la
   portada, y vive aquí para que ninguna pantalla lo pierda. */
.ep-pie{--f-mono:'Chivo Mono',ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}
/* LA LETRA MONO DE LA CASA, EN LAS DIEZ · 02-10, Director. El 22-09 se unificó el
   pie pero no la raíz: portada, Nosotros y las tres de Servicios declaraban
   Chivo Mono en :root y 404, Contacto, Postula, la convocatoria y Privacidad solo
   en el pie, así que sus rótulos pequeños (MENÚ, 01-05 del panel, CONTACTO…)
   salían en la mono del sistema (el botón «Menú» medía 98,59 px frente a 100,81).
   Las diez incrustan las dos caras; solo faltaba declararla. Misma pila de reserva
   que el pie. La demostración aprobada está hecha sobre la portada, que ya la llevaba. */
:root{--f-mono:'Chivo Mono',ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}
.ep-pie__logo svg{height:56px}

/* ══ EL ICONO DEL MENÚ · TRES RAYAS QUE SE ABREN EN ASPA · 28 al 30-09 ════
   Aprobado por el Director sobre la demostración, a partir de olympiatrust.com.
   Los dos botones que de verdad abren el panel en estas diez pantallas son
   .ep-nav__mas2 (en la barra) y .ep-nav__flotante (al desplazar); los dos
   dibujan su icono con ::before/::after sobre un <span> vacío (base.css:235-236
   y :257-258). Aquí se reposicionan esas dos rayas y se gira cada una cuando su
   propio botón llega a aria-expanded=true —lo pone el guion del menú, no esta
   hoja—, así que sigue siendo el mismo <button>, con su aria-label y su
   aria-expanded intactos, y con teclado funciona igual que hoy.
   LA TERCERA RAYA, SIN GUION (G10 de la auditoría del 29-09): un <span> no
   admite un tercer pseudoelemento, pero sí admite su propio fondo. La raya del
   medio se pinta con linear-gradient(currentColor,currentColor) recortado a
   2 px en el centro: existe en el HTML servido con guion o sin él. Al abrirse,
   el fondo se quita y quedan las dos rayas ya giradas en aspa. */
.ep-nav__mas2 > span,
.ep-nav__flotante > span{position:relative;height:16px;
  background:linear-gradient(currentColor,currentColor) center/100% 2px no-repeat}
.ep-nav__mas2[aria-expanded=true] > span,
.ep-nav__flotante[aria-expanded=true] > span{background:none}
.ep-nav__mas2 > span::before,.ep-nav__mas2 > span::after,
.ep-nav__flotante > span::before,.ep-nav__flotante > span::after{
  position:absolute;left:0;right:0;margin:0;
  transition:top .22s ease,transform .22s ease}
.ep-nav__mas2 > span::before,.ep-nav__flotante > span::before{top:0}
.ep-nav__mas2 > span::after,.ep-nav__flotante > span::after{
  top:100%;transform:translateY(-100%)}
.ep-nav__mas2[aria-expanded=true] > span::before,
.ep-nav__flotante[aria-expanded=true] > span::before{
  top:50%;transform:translateY(-50%) rotate(45deg)}
.ep-nav__mas2[aria-expanded=true] > span::after,
.ep-nav__flotante[aria-expanded=true] > span::after{
  top:50%;transform:translateY(-50%) rotate(-45deg)}
@media (prefers-reduced-motion:reduce){
  .ep-nav__mas2 > span::before,.ep-nav__mas2 > span::after,
  .ep-nav__flotante > span::before,.ep-nav__flotante > span::after{transition:none}
}

/* ══ EL RELEVO DEL ASPA · G2 + G3 de la auditoría, y revisión 20 ══════════
   El aspa que queda abierta es la de la CABECERA DEL PANEL, no la de la barra.
   Se probó al contrario y la auditoría lo tumbó por dos defectos: al abrir con
   teclado salían dos aspas superpuestas 69,2 px (menu.js manda el foco a
   .ep-menu__cerrar nada más abrir, sin importar el camino), y al rodar el panel
   el aspa de la barra se quedaba clavada encima de «Nosotros» (el panel rueda
   por el overflow-y:auto de .ep-nav__panel; el logotipo rueda con él porque
   vive dentro, la barra no).
   Y el relevo no puede hacerse con display:none: display no es animable, así
   que el botón de la barra desaparecía en el mismo fotograma en que
   aria-expanded pasaba a true y la rotación de las rayas no llegaba a pintarse
   —ni un fotograma del aspa formándose, que es justo lo que el Director
   aprobó—. Se usa visibility, que SÍ admite retraso: el botón de la barra se
   queda visible hasta que su propia rotación termina (.22s) y el aspa de la
   cabecera no aparece hasta ese mismo instante. Medido fotografiando apertura
   y cierre a 8, 72, 136, 216, 309 y 514 ms: siempre un aspa, nunca dos ni
   ninguna.
   Al cerrar, menu.js devuelve el foco al botón de la barra en el mismo instante
   en que quita data-abierto, así que su visibilidad vuelve de golpe, sin
   retraso: el retraso vive solo en esta regla, que deja de aplicar al cerrarse.
   El aspa salta unos 15 px en el relevo (hasta 46 a 320 px, donde la barra se
   parte en dos líneas de verdad, medido en pasos de 10 px: el salto ocurre
   entre 340 y 350). El Director lo aceptó: eliminarlo exigía devolver los dos
   defectos de arriba. Para que el salto no se note también por el texto, el
   aspa de la cabecera rotula «Menú», igual que la de la barra (ver parcheMenu);
   su nombre para lectores de pantalla sigue diciendo que cierra. */
.ep-nav:has(#panel-nav[data-abierto]) .ep-nav__mas2,
.ep-nav:has(#panel-nav[data-abierto]) .ep-nav__flotante{
  visibility:hidden;transition:visibility 0s linear .22s}
/* El aspa del panel no puede aparecer con una transition: vive dentro de
   #panel-nav, que es display:none hasta este mismo instante (base.css:104), y
   una transition necesita un «antes» ya pintado para interpolar. Comprobado con
   una página mínima: sobre un elemento ya pintado respeta el retraso al pixel;
   sobre uno que acaba de pasar de display:none a block salta a opacity:1 sin
   esperar nada. Una @keyframes sí arranca en cuanto el elemento entra al árbol
   de render —la misma razón por la que la animación de entrada del panel
   funciona—.
   EL ÁMBITO DE `opacity:0` NO ES DECORACIÓN (ronda de revisión del 01-10,
   hallazgo 3): va acotado a `#panel-nav .ep-menu__cerrar`, el mismo ámbito
   que su único antídoto de abajo, y no a `.ep-menu__cerrar` suelo. Si fuera
   suelto, el botón quedaría invisible SIEMPRE y lo único que lo revierte
   sería `#panel-nav[data-abierto] .ep-menu__cerrar{animation:…forwards}` —
   dos reglas que dependen del mismo `id`, pero una de ellas sin saberlo. La
   Tarea 10 reescribe este marcado en PanelMenu.tsx; si ese `id` dejara de
   llamarse `panel-nav` el día de mañana, con el ámbito suelto el botón de
   cerrar degradaría a INVISIBLE PARA SIEMPRE —enfocado por el guion del
   menú, sin ningún anillo que mostrar, con el panel abierto de verdad—, y
   `compruebaMenu` no lo vería porque mira el botón, no el `id` del
   contenedor. Con el ámbito igualado, si el `id` cambiara NINGUNA de las dos
   reglas casaría, y el botón degrada a «visible siempre, sin entrada
   animada» — mucho peor sería lo otro. Comprobado que no cambia el relevo: en
   las 96 muestras de la comprobación 3 del paso 6 (8 escenarios × 12
   instantes), repetida tras este cambio, siempre exactamente un aspa
   visible, igual que antes (docs/superpowers/mediciones/2026-10-01-tarea-2-icono-tres-rayas.md, ronda de arreglos 1, punto 3,
   «Medición que lo cubre»). Lo de «a los 220 ms y no antes» NO lo midió
   ese informe: no lo afirmo. Especificidad:
   `#panel-nav .ep-menu__cerrar` es 1-1-0 contra el 1-2-0 del antídoto — el
   `animation…forwards` lo sigue ganando igual que antes. */
#panel-nav .ep-menu__cerrar{opacity:0}
@keyframes cerrarAparece{to{opacity:1}}
#panel-nav[data-abierto] .ep-menu__cerrar{animation:cerrarAparece .01s linear .22s forwards}
@media (prefers-reduced-motion:reduce){
  .ep-nav:has(#panel-nav[data-abierto]) .ep-nav__mas2,
  .ep-nav:has(#panel-nav[data-abierto]) .ep-nav__flotante{transition:none}
  #panel-nav[data-abierto] .ep-menu__cerrar{animation:none;opacity:1}
}
.ep-menu__cerrar:focus-visible{outline:2px solid var(--acento);outline-offset:2px}
/* EL FOCO NO PUEDE ESTAR EN UN ELEMENTO INVISIBLE · auditoría del 02-10, M1
   (WCAG 2.4.7). Al abrir con teclado el guion del menú manda el foco al aspa del
   panel en el instante 0, y esa aspa no sube de opacity:0 hasta los 220 ms: ~220 ms
   sin ningún anillo de foco en toda la página (quitar los outline a los 100 ms
   cambiaba 0 píxeles). Cuando el foco es «visible» —o sea, de teclado— el aspa
   se pinta desde el primer instante, y la de la barra, que solo seguía viva para
   el relevo, se esconde también desde el primer instante: sigue habiendo UNA sola
   aspa en cada momento. Con ratón o dedo :focus-visible no casa y el relevo es
   el aprobado, al pixel. */
#panel-nav .ep-menu__cerrar:focus-visible{opacity:1}

/* ══ «ESTÁS AQUÍ», UNA SOLA FORMA EN LAS DIEZ · Director, 02-10, M2 ═══════
   Había cuatro maneras entre las diez, y en el panel del menú ninguna se veía:
   la entrada de la página actual se pintaba igual que sus hermanas aunque
   llevara aria-current. La forma que ya usaba la mayoría de las pantallas con
   marca es la de la barra —Nosotros, Contacto y Postula—: el FILETE DE ACENTO
   DE 2 PX bajo la entrada (la hoja base lo escribe como border-bottom) y el peso
   600. Aquí se extiende a todo lo demás sin cambiar esa: el desplegable de la
   barra, el padre «Servicios» cuando se está en una de sus tres líneas, las
   entradas del panel (donde el peso no sirve, que ya van a 700, y por eso el
   filete es la señal que vale en todas partes: la que no depende del color
   solo) y el enlace de política del pie. aria-current="true" es la barra de
   una página hija (la convocatoria marca «Postula», su sección). En el panel el
   filete va como sombra interior para no mover ni un píxel de altura.

   CAMBIADO POR EL DIRECTOR EL 07-10-2026, al revisar Capacitación sobre un
   borrador (BORRADORES/capacitacion-cristal.html). En el DESPLEGABLE de la
   barra y en el PANEL de menú, «estás aquí» deja de ser el filete: la entrada
   queda como una ficha de cristal azulado —el azul de texto al 12 % y el
   fondo desenfocado— con las letras en ese azul. «Quítale el subrayado tanto
   en el menú como en el desplegable, que quede el glass y las letras de
   color.» Se le enseñó la ficha en el gris del fondo de pantalla y prefirió
   el azul. El padre «Servicios» del panel ya no lleva filete. LA BARRA NO
   CAMBIA: sus entradas, y su «Servicios», siguen con el filete de 2 px.
   Queda dicho lo que se pierde: en el panel la señal ya no es una raya sino
   un fondo y un color. El contraste de la letra azul sobre la ficha NO está
   medido. */
.ep-nav__menu a[aria-current=true]{border-bottom-color:var(--acento);font-weight:600}
.ep-nav__menu>li:has(.ep-nav__sub a[aria-current=page])>.ep-nav__desp{
  border-bottom-color:var(--acento);font-weight:600}
.ep-nav__sub a[aria-current=page],
.ep-menu__nav a[aria-current=page],.ep-menu__nav a[aria-current=true],
.ep-menu__nav .ep-menu__sub a[aria-current=page]{border-radius:3px;color:var(--azul-texto);
  background:color-mix(in srgb,var(--azul-texto) 12%,transparent);
  backdrop-filter:blur(14px) saturate(1.4);-webkit-backdrop-filter:blur(14px) saturate(1.4)}
/* En el panel, la ficha de una línea de servicio respira un poco a los lados
   sin mover el texto: lo que entra de relleno sale de margen. */
.ep-menu__nav .ep-menu__sub a[aria-current=page]{padding-inline:var(--e-1);
  margin-inline:calc(var(--e-1) * -1)}
/* LA BARRITA DEL PANEL · Director, 08-10-2026. Con el panel abierto en Contacto
   vio que la ficha de «estás aquí» «se ve como cortada al inicio» y pidió «una
   barrita del mismo azul al lado izquierdo de la palabra». Va en el canto
   izquierdo de la ficha, de 4 px, en el azul de texto, y como sombra interior
   para no mover ni un píxel. Solo en el PANEL de menú: el desplegable de la
   barra queda como estaba. */
.ep-menu__nav a[aria-current=page],.ep-menu__nav a[aria-current=true],
.ep-menu__nav .ep-menu__sub a[aria-current=page]{box-shadow:inset 4px 0 0 var(--azul-texto)}
/* «Dale aire al número» (Director, el mismo día): la barrita caía encima del
   «05». La ficha se abre 16 px a cada lado sin mover el texto —lo que entra de
   relleno sale de margen, como ya hacía la de las líneas de servicio con 8—,
   así que el número queda a 12 px de la barrita y sigue alineado con los demás. */
.ep-menu__nav a[aria-current=page],.ep-menu__nav a[aria-current=true],
.ep-menu__nav .ep-menu__sub a[aria-current=page]{padding-inline:var(--e-2);
  margin-inline:calc(var(--e-2) * -1)}
.ep-pie__priv[aria-current=page]{font-weight:600;text-decoration:underline;
  text-decoration-thickness:var(--marca);text-decoration-color:var(--banda-acento);
  text-underline-offset:.3em}
.ep-nav:has(#panel-nav[data-abierto] .ep-menu__cerrar:focus-visible) .ep-nav__mas2,
.ep-nav:has(#panel-nav[data-abierto] .ep-menu__cerrar:focus-visible) .ep-nav__flotante{
  visibility:hidden;transition:none}
/* N1 de la segunda auditoría, VERIFICADO EN LA TAREA 3 (01-10): a ≤760 px al
   anillo de foco le faltaba el trazo derecho. En la Tarea 2 esto quedó
   pendiente de comprobar —el bloque del panel, el único que pone
   .ep-menu{right:0} contra la ventana, no existía todavía en esta hoja—.
   Verificado ahora que sí existe: con el panel abierto y el aspa enfocada
   CON TECLADO DE VERDAD (Enter real, el mismo Input.dispatchKeyEvent de
   medidas.mjs), medido el lado DERECHO en 320, 390, 600, 740, 760, 780 y
   900 px, en los dos temas — el trazo derecho NO se recorta EN NINGÚN ANCHO
   de los siete, ni con el outline-offset:2px de fábrica (el de arriba) ni
   con el -4px de abajo: el hueco entre el botón y el borde derecho de la
   ventana mide 16 px a 320/390/600 y 40 px a 740/760/780/900, siempre
   varias veces mayor que los 4 px que el anillo necesita para asomar
   (outline-width 2px + outline-offset 2px). Los números, en la tabla de
   docs/superpowers/mediciones/2026-10-01-tarea-3-panel.md §2.3 punto 3. CORREGIDO en la Tarea 4: este comentario
   decía «los cuatro trazos»; esa tabla mide la GEOMETRÍA del lado derecho
   (hueco contra borde de ventana), no los píxeles de los cuatro lados. Los
   cuatro trazos, de los enfocables del panel y por píxeles, se midieron
   después, a 390, 768 y 1280 (no en los siete anchos): docs/superpowers/mediciones/2026-10-01-tarea-4-botones-ovalados.md,
   pendiente B. Y ESA MEDICIÓN POR PÍXELES CONTRADICE EN PARTE LO DE ARRIBA,
   así que se deja dicho aquí: a 390, con la raíz a 16 y a 32 px, el trazo
   derecho de 10 de los 12 enfocables del panel (los cuatro enlaces
   «Nosotros», «Aula Virtual», «Postula» y «Contacto», los tres del submenú de
   «Servicios» desplegado, los dos datos de contacto y «Consultar un
   certificado»; un primer barrido con el submenú plegado vio 7 de 9 y se
   quedó corto) NO se pinta, en los dos temas y en
   las diez pantallas: sus bordes derechos están a 374 px y el trazo, con
   offset de +2 y 3 px de grosor, ocuparía de 376 a 379 px, y a partir de
   375 px —el ancho de document.body, 390 menos los 15 px de
   scrollbar-gutter:stable— este entorno no pinta nada del panel (tampoco
   el velo oscuro de detrás, medido sobre la maqueta y sobre la
   demostración, que se comporta igual). Con html{scrollbar-gutter:auto}
   inyectado, el trazo aparece; con overflow:visible en .ep-menu, en
   .ep-nav__panel o en los dos, NO (probado sobre 404.html, a 390 px y raíz
   a 16). Es decir: la franja del
   gutter, la hipótesis original del auditor, sí recorta el trazo AQUÍ, y lo
   que decía este comentario («el hueco de 16 px es mayor que los 4 px del
   anillo») miraba el borde de la ventana y no el borde de lo que se pinta.
   El aspa (a ≤760 px, offset -4px) y «Servicios» (-4px) no se ven
   afectados: llevan el trazo por dentro y se midieron al 100 % en los cuatro
   lados. Si en un navegador de verdad con barra
   clásica ocurre lo mismo, no lo sé: este entorno arranca con
   --hide-scrollbars. El umbral y la regla de abajo NO se han tocado:
   decide el Director.
   EL UMBRAL QUE RESPALDA LA MEDICIÓN ES 640, NO 760 (revisión de la ronda de
   arreglos 1 de la Tarea 4; el 640 lo midió el revisor, yo solo medí 390,
   768 y 1280): el recorte aparece donde el margen lateral es de 16 px, y eso
   empieza a ≤640 px (base.css:804-806, --pad-pagina:var(--e-2)). Entre 641 y
   760 el margen es de 40 px y el trazo cae lejos del borde —en mi medida a
   768, la holgura mínima entre el anillo y el borde visible de .ep-menu es de
   35 px, más que los 15 px de la franja—. Un arreglo escrito a ≤760 se
   aplicaría 120 px de ancho de más, donde no hay defecto: cuando se escriba,
   que sea con el umbral medido. OJO con la causa: «la franja es necesaria»
   está probado (con scrollbar-gutter:auto el trazo aparece; con overflow
   visible no), pero «la franja es el agente» está deducido: queda sin aislar
   el tercer candidato, html[data-panel=abierto]{overflow:hidden}
   (cromo.css:79), que también cambia al abrir el panel.
   LA CAUSA QUE AISLÓ EL AUDITOR YA NO ES LA QUE MANDA (y puede que nunca lo
   fuera, pero eso no se puede comprobar: ver más abajo): ese hueco de 16-40
   px es `var(--pad-pagina)` —el margen lateral de TODO el sitio, 40 px de
   fábrica y 16 px por debajo de 640 px, base.css:805-806—, no la franja de
   scrollbar-gutter que citaba la hipótesis original.
   CORREGIDO (ronda de arreglos 1, revisión independiente, 01-10): esto NO
   decía que «el gutter no les quita nada a `.ep-nav__panel`/`.ep-menu`» —
   eso era falso, y la demostración ya lo tenía medido al revés
   (demo-mejoras.mjs:1569-1577). El gutter SÍ le quita 15px al envoltorio:
   `.ep-nav__panel[data-abierto]` es `position:fixed;inset:0` (base.css:105),
   y ese `inset:0` por sí solo dimensiona el elemento contra el viewport YA
   reducido por `scrollbar-gutter:stable` —el mismo `documentElement.
   clientWidth` de 1280 esconde que el `inset` fijo, sin ancho explícito,
   se queda en 1265—. Lo que de verdad devuelve esos 15px es el
   `width:100vw` del primer selector de este mismo bloque
   ([data-menu=lateral] .ep-nav__panel[data-abierto]{…width:100vw}):
   `100vw` se define contra el viewport inicial completo y NO resta la
   franja reservada, a diferencia de un `width:100%` heredado del `inset`.
   Sin ese `100vw`, el panel —y `.ep-menu` dentro de él, con `right:0`—
   se quedarían 15px cortos del borde derecho de verdad, y G4 (más abajo en
   este mismo bloque) volvería a fallar. Los NÚMEROS de este umbral no
   cambian por esta corrección —`.ep-menu` sigue llegando exactamente al
   borde del viewport, confirmado midiendo el borde derecho (0,00px de
   diferencia con `.ep-nav__panel`, docs/superpowers/mediciones/2026-10-01-tarea-3-panel.md §2.3 punto 2, tabla)—; lo que
   cambiaba era SÓLO la explicación de por qué llega ahí, no el hecho de que
   llega.
   Con esto delante, EL UMBRAL DE 760 PX SE QUEDA TAL CUAL ESTABA, por dos
   motivos y no por descuido:
   1) no hay otro ancho que proponer: medido en los siete puntos de la lista,
      el trazo nunca se recorta ni con 2px ni con -4px, así que no hay un
      «donde empieza a cortarse» que mover al número 760.
   2) este entorno de medición NO PUEDE comprobar el caso que de verdad le
      preocupaba al auditor —un navegador con barra de desplazamiento clásica
      de verdad, tapando el trazo por fuera—: arranca con --hide-scrollbars
      (instrucciones de la Tarea 3; no es un defecto de esta herramienta), así
      que un «no se recorta aquí» no prueba «no se recorta nunca». Tocar una
      regla puesta por un auditor, por una causa que no se puede refutar del
      todo en este entorno, sin que la demostración —lo único que el Director
      vio y aprobó, con este mismo @media tal cual— lo haya visto cambiar,
      es más riesgo que beneficio: se preserva la correspondencia exacta con
      la demostración, que sigue en pie.
   La pista que dejó la Tarea 2 —que si la causa es geométrica, como en
   .ep-menu__desp (línea 99, el vecino de esta misma cabecera, que dibuja el
   anillo por dentro A TODOS LOS ANCHOS por width:100%), el @media podría
   sobrar y el anillo ir por dentro siempre— queda CONFIRMADA EN PARTE: la
   causa medible (var(--pad-pagina)) sí es geométrica. Pero «podría sobrar»
   no es lo mismo que «sobra»: no sobra mientras quede, sin poder comprobarse
   aquí, el caso de la barra de desplazamiento clásica que motivó la regla.
   Si alguna vez se mide esto en un navegador de verdad, con su barra
   clásica, y el trazo tampoco se recorta nunca por encima de 760, esta regla
   sí podría simplificarse al patrón de .ep-menu__desp. Por ahora, medido lo
   que se puede medir aquí, queda como estaba. */
@media (max-width:760px){
  .ep-menu__cerrar:focus-visible{outline-offset:-4px}
}

/* ══ EL PANEL CUELGA DE LA BARRA Y BAJA · 28 al 30-09, ocho rondas ════════
   Idea del Director a partir de olympiatrust.com, afinada mirando la
   demostración. Las medidas no son gusto: están medidas.
   · 490 px de ancho: lo quería en 480-500 («su marca ocupa unos 490, con la
     página al 125 %»). Probados 460/480/490/500: «Servicios» —el único
     subtítulo que partía en dos renglones a 360— deja de partirse ya desde
     460, así que dentro de ese entorno el número no lo decide el subtítulo; se
     toma el punto medio de lo que él dibujó sobre su captura.
   · right:0 contra la ventana, no contra el área de contenido: lo pidió
     explícitamente («el panel se vería mejor pegado al lado derecho»).
   · sin desplazamiento interno A LETRA NORMAL: pidió que no hubiera scroll
     dentro del menú («entra fácilmente en una sola vista»). El contenido
     natural mide 747 px y cabe con 21 px de margen a 768 —su suelo real, el
     que usa— y con más a 800 y 900. A 700 no cabría, y no se apunta a 700:
     él mismo retiró ese objetivo («era mío, no suyo»).
     DECISIÓN DEL DIRECTOR, 01-10-2026, ronda de arreglos 1 de la Tarea 3: con
     la letra del navegador al doble (raíz a 32px, WCAG 1.4.4), el contenido
     natural sube a 1334px y NO cabe en ningún tamaño de portátil razonable
     —medido: 768 y 900px de alto, docs/superpowers/mediciones/2026-10-01-tarea-3-panel.md §2.3 punto 1, tabla—.
     Sobre esa medición,
     decidió que el panel SÍ se desplace, pero SÓLO cuando de verdad no cabe:
     a letra normal no cambia nada —sigue sin aparecer ninguna barra, tal
     como lo aprobó—; a letra doble aparece una barra y el menú se puede
     recorrer entero, en vez de perder el botón de «Consultar un certificado»
     por debajo del borde de la ventana, inalcanzable. El motivo es de
     accesibilidad: el texto tiene que poder agrandarse al 200% sin perder
     contenido ni funcionalidad. Se implementa con max-height:100% —atado al
     envoltorio de verdad, .ep-nav__panel, que ya mide el alto de la ventana
     por su propio inset:0— y overflow-y:auto, que no pinta barra cuando el
     contenido entra solo: a letra normal, scrollHeight===clientHeight y
     overflow-y calculado sigue siendo el que no se ve (sin recorte, sin
     barra); a letra doble, aparece de verdad y el último elemento del panel
     queda alcanzable con teclado (medido tabulando hasta el final).
   · la cabecera pegada arriba (position:sticky): G3 de la auditoría. El panel
     rueda de verdad —por el overflow-y:auto de .ep-nav__panel— en cinco de las
     ocho combinaciones probadas, y sin esto la pareja logotipo+aspa se quedaba
     fuera de la vista.
   · la animación solo desvanece, sin desplazamiento: con translateY(-10px) el
     Director vio el logotipo 10 px más abajo que el aspa en algunos fotogramas
     del arranque —el offset era exactamente el del propio translateY—. Sin
     transform no hay nada que asentar.
   «Consultar un certificado» de la barra se oculta mientras el panel está
   abierto —su sitio en la cabecera lo ocupa el logotipo— y sigue alcanzable
   dentro del panel, donde ya vivía. Nada se mueve del DOM: moverlo de verdad
   fue lo que causó el parpadeo de las primeras rondas y los dos defectos que
   tumbó la auditoría. */
[data-menu=lateral] .ep-nav__panel[data-abierto]{background:rgba(8,10,12,.28);width:100vw}
[data-menu=lateral] .ep-menu{
  position:absolute;top:0;right:0;left:auto;margin:0;
  padding-top:0;padding-bottom:var(--e-4);
  width:490px;max-width:94vw;transform-origin:top right;
  min-height:0;height:auto;max-height:100%;overflow-y:auto;
  box-shadow:0 24px 48px -12px rgba(6,7,9,.35);will-change:opacity;
  animation:panelBrota .22s ease-out}
@keyframes panelBrota{from{opacity:0}to{opacity:1}}
/* SIN !IMPORTANT (RONDA DE ARREGLOS 1, revisión independiente, 01-10):
   la primera versión de esta regla lo llevaba, por una medición mal leída.
   contra-la-demo.mjs --bloque=panel daba animation-name «none» en las seis
   combinaciones, contra «demoBrota» de la demostración, y la conclusión de
   entonces fue que panelDesliza (base.css) ganaba y hacía falta !important
   para vencerlo. Las dos partes de esa conclusión eran incorrectas:
   1) panelDesliza NUNCA ganaba. Comprobado con un clic real sobre la
      maqueta ya generada, sin el medidor de por medio: esta regla, SIN
      !important, ya leía animation-name «panelBrota» (misma especificidad
      que panelDesliza, y ésta va después en la hoja — el orden decide, como
      en el resto del parche).
   2) la medición que decía «none» no estaba midiendo la cascada del sitio:
      medir() (medidas.mjs) inyecta, antes de leer CUALQUIER propiedad, una
      hoja QUIETO con *,*::before,*::after{animation:none!important}, para
      congelar toda animación y medir la geometría ya asentada. Pedirle a esa
      misma lectura animation-name no medía «qué regla gana»: medía «qué dice
      QUIETO», siempre, sea cual sea la regla del sitio. El !important que se
      puso aquí no vencía a panelDesliza —eso ya lo hacía solo—: vencía a
      QUIETO, y sólo durante la medición, nunca en la navegación real.
   Arreglado donde tenía que arreglarse, en el instrumento (medidas.mjs: las
   propiedades que QUIETO sobreescribe se leen ANTES de inyectarla), este
   !important sobraba — y, sobrando, era activamente dañino: ver el bloque de
   «reducir movimiento» tres líneas más abajo, que es la regresión que costó
   encontrar este error. Detalle, con el medidor viejo y el nuevo medidos
   uno junto al otro y las cifras del revisor con su procedencia, en
   docs/superpowers/mediciones/2026-10-01-tarea-3-panel.md, sección «Ronda de arreglos 1 — puntos 1 a 5», puntos 1
   y 2. */
@media (prefers-reduced-motion:reduce){
  /* REGRESIÓN DE ACCESIBILIDAD, encontrada por la revisión independiente del
     01-10 y corregida en la misma ronda: con el !important de arriba puesto,
     esta regla competía con la de base.css:110-111
     (.ep-nav__panel[data-abierto],[data-menu=lateral] .ep-menu
     {animation:none!important}) en igualdad de especificidad y de
     !important — las dos condiciones que hacen que decida el ORDEN, y el
     parche se emite 1.200 líneas después. Ganaba el panel, no el antídoto:
     con «reducir movimiento» activado, el panel seguía animando. Medido
     sobre docs/diseno/404.html con prefers-reduced-motion:reduce emulado:
     animation-name «panelBrota», duration 0.22s, getAnimations() listaba
     «panelBrota» corriendo, antes de este arreglo.
     Quitado el !important de arriba, el antídoto de base.css ya gana solo
     —no hace falta nada más—. Esta regla, sin !important, es puro cinturón:
     deja el comportamiento correcto escrito EN EL MISMO BLOQUE que lo puede
     romper, para que no dependa de un archivo a 1.200 líneas de distancia.
     Si algún día deja de haber conflicto de especificidad, esta línea sigue
     sin sobrar: documenta la intención donde vive la regla que la pondría en
     riesgo. */
  [data-menu=lateral] .ep-menu{animation:none}
}
@media (max-width:760px){
  /* G4 de la auditoría: a 320 y 390 el panel no llegaba al borde derecho
     (19,2 y 23,4 px de velo, medidos). CITA CORREGIDA (ronda de arreglos 1,
     revisión independiente, 01-10): el max-width:94vw que seguía aplicando
     no es de base.css —ahí, línea 114, vive width:min(500px,94vw), de la
     regla vieja del panel lateral de toda la vida, y en ninguna parte de
     base.css hay un max-width:94vw suelto—. Es el max-width:94vw del propio
     bloque de esta tarea, tres líneas más arriba
     ([data-menu=lateral] .ep-menu{…width:490px;max-width:94vw;…}): esta
     consulta sólo tocaba right/left/width, así que ese max-width seguía
     vigente y ganándole al width:auto de aquí abajo. */
  [data-menu=lateral] .ep-menu{right:0;left:0;width:auto;max-width:none}
}
[data-menu=lateral] .ep-menu__top{
  border-bottom:0;padding:var(--e-2) 0;align-items:center;
  position:sticky;top:0;z-index:2;background:var(--fondo)}
/* LO QUE SE PUEDE TAPAR BAJO LA CABECERA PEGADA · ronda de arreglos 1, 01-10.
   La cabecera de arriba es sticky y opaca, y desde la decisión del Director el
   panel rueda cuando no cabe (letra al doble). Medido sobre 404.html servida,
   panel abierto, tabulando con teclado de verdad hasta el final del panel y de
   vuelta, SIN esta regla:
   · hacia delante (Tab), a 1280×768, 1920×900 y 390×800 con la raíz a 32 px:
     ningún enfocable quedó bajo la cabecera (la más alta, 80 px: el primero,
     «Nosotros», queda a 97 px).
   · hacia atrás (Mayús+Tab) SÍ: a 1280×768 «Postula» (borde superior a 56 px)
     y «Aula Virtual» (a 0 px) quedaron bajo la cabecera, y a 1920×900 «Aula
     Virtual» (13 px) y «Servicios» (0 px); a 390×800, «Aula Virtual» (0 px).
     Al enfocar hacia arriba el navegador deja el elemento pegado al borde
     superior del panel, que es justo donde está la cabecera —eso lo medí; por
     qué elige ese borde lo deduzco, no lo medí—. A letra normal (16 px), donde
     el panel no rueda, no se tapó ninguno en ninguna dirección.
   Es, pues, una corrección y no solo prevención, pero solo hacia atrás.
   El valor: la cabecera mide 80 px a raíz 16 y a raíz 32 (medido: 48 px del
   aspa más 2 × --e-2 de relleno, que son px fijos, no rem), y 80 = --e-5 +
   --e-2. Se usa --e-5 + --e-3 = 88 px: los 80 de la cabecera más 8 px de aire
   para que el anillo de foco (2 px de trazo, 2 de separación en los enlaces) no
   quede pegado a ella. El aspa se excluye: vive dentro de la cabecera. */
[data-menu=lateral] .ep-menu :is(a,button):not(.ep-menu__cerrar){
  scroll-margin-top:calc(var(--e-5) + var(--e-3))}
.ep-nav:has(#panel-nav[data-abierto]) .ep-nav__cta{display:none}
/* El reparto de dentro, con los seis tokens del sitio y ningún número suelto.
   Octava ronda del Director, viéndolo ya sin «Síguenos»: «el botón y la sección
   de contacto no respiran». Medido con medir-alturas, no sumado a mano: el
   contenido natural sube de 675 a 747 px, y cabe con 21 px de margen a 768. */
[data-menu=lateral] .ep-menu__cuerpo{padding-top:var(--e-2);row-gap:var(--e-2)}
.ep-menu__nav a{padding:var(--e-1) 0}
.ep-menu__lado{row-gap:var(--e-3)}
.ep-menu__rot{margin-bottom:var(--e-3)}
.ep-menu__dato{margin-bottom:var(--e-2)}

/* ══ LA PÁGINA NO SALTA AL ABRIR EL MENÚ · deuda 32 ══════════════════════
   Sospecha del Director, confirmada por código: al abrir, el sitio bloquea el
   desplazamiento del fondo (html[data-panel=abierto]{overflow:hidden}), la
   barra de desplazamiento desaparece, la zona visible se ensancha y el
   contenido se recoloca de golpe.
   CORREGIDO (ronda de arreglos 1, revisión independiente, 01-10): esto NO
   decía que la franja mide 0 — eso era falso, y la demostración ya lo tenía
   medido al revés (demo-mejoras.mjs:1569-1577). Medido aquí también: a 1280,
   document.body.clientWidth da 1265 contra document.documentElement.
   clientWidth 1280 — los 15px de scrollbar-gutter:stable SÍ se reservan en
   este entorno, con --hide-scrollbars y todo, porque reservar la franja es
   un cálculo de layout (dentro del padding de html), no depende de que haya
   una barra pintada encima. Esos mismos 15px son los que el width:100vw de
   [data-menu=lateral] .ep-nav__panel[data-abierto], al principio de este
   bloque, le devuelve al panel — sin ese 100vw, el panel se quedaría 15px
   corto del borde derecho y G4 (más arriba) volvería a fallar a 320/390.
   Lo que de verdad NO se puede medir aquí es EL SALTO: sin una barra
   pintada de verdad que aparezca y desaparezca, no hay nada que dé el
   tirón visual al abrir el panel, exista o no esa franja detrás. Franja
   reservada y salto visible son dos cosas distintas, y sólo la segunda es
   la que este entorno no puede reproducir. Los tres hechos que producen el
   salto son del sitio, no de esta herramienta ni de una demostración.
   Arreglo estándar, una línea. Le pasa también al sitio de hoy: queda
   anotado en la deuda 32. */
html{scrollbar-gutter:stable}
/* ══ LA BARRA DE DESPLAZAMIENTO, UN FILETE · Director, 09-10-2026 ═════════
   Decidido sobre un borrador (residuo/BORRADORES/barra-desplazamiento-*.html),
   entre cinco: la del sistema, una píldora del color de acento, una discreta,
   un filete y una con los tres colores del logotipo. Quedó EL FILETE: un
   trazo recto de 3 px, sin redondear y SIN RIEL —lo pidió aparte: «pareciera
   que tiene un riel, quítale eso»—, en el color de acento a media fuerza
   (el 55 %): azul en el tema claro y naranja en el oscuro, porque --acento
   ya cambia con el tema. Con el cursor encima o arrastrándolo se ensancha a
   5 px y toma el acento pleno.
   La franja mide 15 px a propósito: son los que este navegador ya reservaba
   con scrollbar-gutter:stable, así que el ancho útil de las páginas no se
   mueve ni un píxel (medido: herramientas/mediciones/barra-desplazamiento.mjs).
   El trazo son esos 15 menos 6 de borde transparente a cada lado.
   No se puede hacer en cristal: el navegador no deja desenfocar lo que hay
   detrás de una barra de desplazamiento, sólo darle color y forma.
   Vale para TODAS las barras del sitio —la de la página, las ventanas de
   Ejecución, el panel de menú, las cajas de texto—. En teléfonos y en Mac la
   barra es la del sistema y esto no cambia nada. Firefox no entiende estas
   reglas: recibe sólo el color, por la vía estándar, con su propia forma. */
::-webkit-scrollbar{width:15px;height:15px}
::-webkit-scrollbar-track,::-webkit-scrollbar-corner{background:transparent}
::-webkit-scrollbar-thumb{background:color-mix(in srgb,var(--acento) 55%,transparent);background-clip:content-box;
  border:solid transparent;border-width:0 6px;min-height:48px}
::-webkit-scrollbar-thumb:horizontal{border-width:6px 0;min-width:48px}
::-webkit-scrollbar-thumb:hover,::-webkit-scrollbar-thumb:active{background-color:var(--acento);border-width:0 5px}
::-webkit-scrollbar-thumb:horizontal:hover,::-webkit-scrollbar-thumb:horizontal:active{border-width:5px 0}
@supports not selector(::-webkit-scrollbar){html{scrollbar-color:color-mix(in srgb,var(--acento) 55%,transparent) transparent}}
/* ══ EL PANEL DE MENÚ SE CIERRA ARRASTRÁNDOLO HACIA ARRIBA · Director, 10-10-2026 ══
   Lo mueve el guion del menú (más abajo, en JS_MENU). Aquí sólo va lo que el guion necesita de la
   hoja: mientras el dedo arrastra la caja no hay animación ni transición; al soltar, vuelve a su
   sitio o sale por arriba con una transición corta. Con «menos movimiento», sin transición. */
.ep-menu[data-arrastre]{animation:none!important;transition:none!important}
.ep-menu[data-vuelve]{animation:none!important;transition:transform .22s ease}
.ep-menu[data-sale]{animation:none!important;transition:transform .18s ease-in}
@media (prefers-reduced-motion:reduce){.ep-menu[data-vuelve],.ep-menu[data-sale]{transition:none}}
/* LA RAYITA (Director, 10-10-2026: «ponerle una rayita en la parte inferior del menú para que se
   entienda que se puede mover con gestos, tipo persiana»). Un tirador al pie de la caja, sólo en
   pantallas táctiles, que es donde el gesto existe. Va dentro del relleno inferior de la caja —18 px
   de aire, 4 de raya y un margen negativo que devuelve los 22—, así que la caja mide lo mismo que
   sin ella. Si la caja no cabe en la pantalla, la rayita queda al final, que es justo donde el
   gesto empieza a cerrar. Es un adorno: no se anuncia ni se enfoca. */
@media (hover:none) and (pointer:coarse){
  .ep-menu::after{content:"";flex:none;align-self:center;width:44px;height:4px;border-radius:999px;
    margin:18px 0 -22px;background:color-mix(in srgb,var(--tinta) 40%,transparent)}
  .ep-menu[data-arrastre]::after{background:var(--acento)}
}
/* ══ BOTONES OVALADOS, EN TODO EL SITIO · Director, 28-09 ═════════════════
   Al ver el óvalo de .ep-nav__flotante (base.css:253), que hasta hoy era la
   única excepción: el resto del sistema usa 2 px. Esto toca las diez
   pantallas, no solo la portada. No cambia la caja ni el relleno: solo la
   esquina. MEDIDO en la Tarea 4, sobre las diez maquetas a 320/390/768/
   1280/1920 con letra normal y al doble, 266 botones: ninguna caja baja de
   44 px de alto (mínimo 44,00, el .ep-nav__cta) ni de ancho (mínimo 116,23,
   un .ep-btn; los .ep-btn miden 48 de alto como mínimo). La esquina redonda
   SÍ recorta la zona pulsable en las puntas: con elementFromPoint sobre una
   rejilla de 1 px, el peor botón conserva el 90,67 % de su caja (un .ep-btn
   de 225×115 a 320 con letra doble) y con la esquina de 2 px el peor
   conserva el 99,98 %. El control de 2 px sirve de prueba de que la rejilla
   detecta la diferencia. Qué ancho de zona pulsable a la altura entera
   queda entre las dos puntas (ancho menos alto, en un óvalo) lo deduzco de
   la geometría, no lo medí por separado. Detalle en docs/superpowers/mediciones/2026-10-01-tarea-4-botones-ovalados.md. */
.ep-btn,.ep-nav__cta,.ep-nav__pbtn{border-radius:999px}

/* ══ EL ANILLO DE FOCO DEL PANEL, COMPLETO · 02-10-2026 · Tarea 4 bis ═════
   La auditoría de la Tarea 2 (hallazgo N1) encontró que al aspa le faltaba el
   trazo derecho del anillo en anchos pequeños y se arregló dibujándolo por
   dentro. Se arregló SOLO el aspa, porque era el único enfocable que el
   auditor miró. Medido en la Tarea 4 —1.440 medidas, 120 configuraciones,
   docs/superpowers/mediciones/2026-10-01-tarea-4-botones-ovalados.md, sección
   «Pendiente B»—: a 390 px, en las diez pantallas, los dos temas y las dos
   letras, falta el trazo derecho en 10 de los 12 enfocables del panel.
   Lo que sigue está medido con herramientas/mediciones/trazos-del-anillo.mjs,
   y las tablas están en
   docs/superpowers/mediciones/2026-10-02-tarea-4-bis-anillo-de-foco.md
   (§2 las mediciones previas a escribir esta regla, §6 la comprobación final).

   LA CAUSA, hasta donde está probada: con scrollbar-gutter:auto el trazo
   aparece, así que la franja de 15 px es NECESARIA para el defecto. Lo que NO
   está aislado es si la franja es el agente que recorta o si lo es
   html[data-panel=abierto]{overflow:hidden} (cromo.css:79), que recorta el
   pintado al borde del hueco reservado. Es deducción, no hecho. No hace falta
   saberlo para arreglarlo: un anillo por dentro es inmune a las dos.

   1 · EL UMBRAL ES 640, NO 760 (§2.1). Medido en 320, 360, 390, 600, 630, 640,
   641, 645, 650, 700, 760 y 800 px (404 y portada, los dos temas, las dos
   letras; 641 y 645 solo en la 404): el trazo derecho se recorta en todos los
   anchos de 320 a 640 y en ninguno de 641 a 800. Es el ancho donde
   --pad-pagina baja a 16 px (base.css:804-806). El número que manda es el
   medido, y coincide con el que ya había deducido la revisión de la Tarea 4.
   SALVEDAD DEL ENTORNO, la misma del bloque del aspa más arriba: todo esto se
   midió con Chrome arrancado con --hide-scrollbars, así que un navegador con
   barra de desplazamiento clásica pintada de verdad podría recortar a otros
   anchos o de otra manera, y este entorno no puede comprobarlo. El 640 es el
   umbral medido AQUÍ, no una garantía general.

   2 · EL ANILLO POR DENTRO, A -4px (§2.3, §6). El selector casa con los doce
   enfocables del panel y con ningún otro enlace o botón (§1: 12 de 12 en las
   diez pantallas, a 390 y a 1280). Dos costes medidos que se aceptan, dichos
   aquí para que nadie los descubra después:
   · el trazo izquierdo cae sobre el primer carácter de las filas, que arrancan
     pegadas al borde de su caja: la tinta empieza a 0-2 px del borde en los
     cuatro enlaces, en «Servicios», en los tres del submenú y en los dos datos
     de contacto, y el trazo ocupa de 1 a 4 px. No es nuevo: «Servicios» ya lo
     hacía a todos los anchos (línea 99, aprobado en la demostración) y su
     numeral «02» ya queda tocado por el anillo; esto lo extiende a «01»,
     «03», «04» y «05», al «+» del teléfono y a la primera letra del submenú.
   · en vertical NO muerde: en los datos de contacto, que son los de caja más
     baja (30 px a letra normal), la tinta empieza a 8-9 px del borde por
     arriba y a 6-8 por abajo, y el trazo llega a 4 px.

   3 · «CONSULTAR UN CERTIFICADO» NECESITA OTRO COLOR Y OTRO VALOR (§2.2). Aquí
   la previsión del plan era otra y la medición la desmiente. Se temía que el
   anillo por dentro cayera junto al filete del botón y dibujara dos curvas
   concéntricas muy juntas. Lo que pasa es peor: ese botón es azul
   (--marca-azul, rgb 12 120 180) y el anillo por defecto también (--azul-texto,
   rgb 11 115 172 en claro y 15 153 229 en oscuro). Por dentro es azul sobre
   azul, con contraste 1,07:1 en claro y 1,54:1 en oscuro, calculados con la
   fórmula de WCAG sobre esos colores medidos: el anillo NO SE VE (el medidor
   da 0 % de trazo en los cuatro lados). Por fuera, sobre el fondo del panel,
   contrasta 4,77:1 en claro y 5,94:1 en oscuro, y por eso nadie lo había
   notado. Se pinta en blanco (--sobre-marca, 4,82:1 contra el azul del botón).
   Y a -4 el anillo queda a 1 px del borde de la forma —menos de los 2 px que
   fija el plan—, así que se usa -6: el trazo ocupa de 3 a 6 px por dentro y
   deja 3 px de azul. Se miró la captura de los dos temas con -4, -5 y -6. El
   filete del botón es transparente (border-color:transparent en --fuerte), así
   que no hay dos curvas visibles, sino la forma y un anillo concéntrico a 3 px.
   Por encima de 640 el anillo de este botón sigue fuera, en su azul de siempre.

   4 · EL TRAZO INFERIOR NO ES COSA DEL ANCHO (§2.4). El plan lo situaba a 390
   px con la letra al doble. Medido, aparece también a 641, 645, 650, 700, 760,
   800 y 1280 con la letra al doble (no apareció en 600, 630 ni 640). No es el
   gutter: el panel se desplaza (overflow-y:auto, Tarea 3) y, al enfocar con
   teclado, el navegador alinea el borde de la CAJA con el borde visible del
   panel, de modo que el anillo, que asoma 5 px por fuera, queda del lado
   recortado (el mecanismo exacto lo deduzco, no lo medí por separado). Un
   anillo por dentro a ≤640 no lo cura a 650 ni a 1280, y ponerlo por dentro a
   todos los anchos cambiaría el panel de escritorio por un defecto de
   desplazamiento. Lo cura una línea que no cambia nada de lo que se ve: que
   el desplazamiento por foco deje 8 px de aire abajo (scroll-padding-bottom).
   Medido con el submenú desplegado y la letra al doble en 390, 700 y 1280: de
   5 trazos inferiores recortados a 0. Hacia atrás (Mayús+Tab) no se recortó
   ningún trazo superior ni inferior. Esta línea NO estaba en el plan: es una
   decisión del implementador, está declarada en DIFERENCIAS y se revierte
   borrándola.

   5 · .ep-menu__cerrar SE QUEDA CON SU ≤760 (§2.5). Mantener los 760 del aspa
   y poner 640 al resto deja dos números para el mismo fenómeno, que es lo que
   hizo que este defecto sobreviviera cuatro tareas, así que se explica:
   medido con el offset de fábrica (+2) forzado en 641, 650, 700 y 760 px, el
   aspa no se recorta en ninguna de las 32 medidas. Los 120 px de más no le
   estorban, pero tampoco le hacen falta. Se deja como está porque quitárselos
   cambiaría un botón que el Director aprobó en la demostración sin ganar nada.
   Si algún día se unifican, que sea a 640. */
@media (max-width:640px){
  [data-menu=lateral] #panel-nav :is(a,button){outline-offset:-4px}
  [data-menu=lateral] #panel-nav .ep-nav__pbtn--fuerte{outline-color:var(--sobre-marca);outline-offset:-6px}
}
[data-menu=lateral] .ep-menu{scroll-padding-bottom:var(--e-1)}

/* ══ «VOLVER ARRIBA» · Director, 01-10-2026, en las diez ══════════════════
   G6 de la auditoría del 29-09: en reposo llevaba opacity:0 y
   pointer-events:none, pero seguía en el recorrido de tabulación —quien navega
   con teclado aterrizaba en un control que no ve, sin ningún anillo visible
   (WCAG 2.4.7)—. Lleva visibility, que sí lo saca del recorrido, y
   «visibility» va en la lista de propiedades con transición: sin eso el cambio
   sería instantáneo y cortaría el fundido de opacity a medias. Es el mismo
   arreglo que ya tuvo el mando flotante (más arriba en esta hoja).

   Todo lo que sigue se midió el 02-10-2026 con
   herramientas/mediciones/volver-arriba.mjs sobre las diez pantallas, a 320,
   390, 640, 641, 768 y 1280 px, en los dos temas y con la letra del navegador a
   16 y a 32 px (240 configuraciones), y está en
   docs/superpowers/mediciones/2026-10-02-tarea-5-volver-arriba.md:
   · NO SE ENFOCA MIENTRAS NO SE VE: 0 de 240. Con la página arriba del todo se
     enfoca el último enfocable visible y se pulsa UN Tab de teclado de verdad;
     nunca aterriza en el botón. Con 25 Tab desde la carga tampoco (0 de 240),
     pero esa prueba por sí sola no vale: una pantalla con más de 25 enfocables
     (hay de 27 a 48) no llegaría al botón ni siendo enfocable. La que cuenta es
     la primera, y su control es que a 400 px, con el botón visible, esa misma
     prueba SÍ aterriza en él (240 de 240).
   · EL ANILLO VA POR DENTRO (outline-offset:-4px; la demostración lo tenía por
     fuera, a +2px, y la diferencia está declarada en medidas.mjs). Es el mismo
     mecanismo del panel (Tarea 4 bis), aplicado a todos los anchos porque el
     botón no tiene media query. Historia, y no estado actual: con el anillo
     por fuera su vecino era la página, y el contraste del trazo contra lo de
     detrás cayó a 1,01:1 en claro (un píxel del borde de una letra) y 1,02:1 en
     oscuro, y a 1,15:1 y 1,07:1 mirando la mediana de un arco de 40 grados,
     ambos en «Nosotros» a 390 px con una foto detrás: un anillo de un solo color
     no puede garantizar 3:1 contra lo que le toque detrás.
   · CONTRASTE, con el anillo ya dentro (volver-arriba.mjs --contraste,
     calibrado antes contra 21,00 y 4,48; 20 configuraciones por tema, 211
     paradas bajando la página, porque el fondo del botón es un 85 % de --panel
     y deja pasar un 15 % de lo de detrás): icono, 13,44:1 como peor caso en
     claro y 8,86:1 en oscuro; anillo contra el fondo del botón, 3,74:1 en claro
     (con el pie oscuro detrás) y 4,04:1 en oscuro (con blanco detrás); en
     «Nosotros» a 390 px, 3,74:1 y 4,80:1. Los dos extremos coinciden con lo que
     da la cuenta de mezclar un 85 % de --panel con negro o con blanco, lo que
     deduzco, no medí por separado, para decir que no hay un peor caso más
     adelante.
   · SEPARACIÓN CON EL ICONO (volver-arriba.mjs --separacion): la tinta de la
     flecha llega a 5,5 px del centro y el anillo cambia de 17,5 a 20,4 px, así
     que quedan 12,0 px entre el borde interior del anillo y el icono (medido en
     6 configuraciones: 3 pantallas, 2 temas, 390 px). No se tocan.
   · EL ANILLO SE PINTA ENTERO: 960 de 960 trazos al 100 % (240 configuraciones
     por 4 lados), y el control (clip-path:inset(5px round 999px), que recorta lo
     que queda a menos de 5 px del borde) da 0 %. Con el anillo por fuera habían
     salido dos al 90,6 % y 87,5 % en la portada con tema claro, que el anillo en
     rojo explicaba como tinta del mismo color debajo; ya no aparecen. El recorte
     del panel (docs/superpowers/mediciones/2026-10-02-tarea-4-bis-anillo-de-foco.md)
     no podía darse: el trazo ocupa de 2 a 4 px por dentro del borde del botón.
     Detalle en el informe de la ronda de arreglos 2.
   Salvedad del entorno, la de siempre: Chrome arranca con --hide-scrollbars, y
   un navegador con barra clásica pintada podría dar otra cosa. */
:root{--disco-arriba:44px}
.ep-arriba{display:inline-flex;align-items:center;justify-content:center;
  position:fixed;right:var(--pad-pagina);bottom:var(--e-3);z-index:45;
  width:var(--disco-arriba);height:var(--disco-arriba);
  border-radius:999px;border:var(--borde) solid var(--linea);
  color:var(--tinta);background:color-mix(in srgb,var(--panel) 85%,transparent);
  text-decoration:none;opacity:0;visibility:hidden;transform:translateY(8px);
  pointer-events:none;
  transition:opacity .25s ease,transform .25s ease,border-color .2s ease,visibility .25s}
[data-fijo=si] .ep-arriba{opacity:1;visibility:visible;transform:translateY(0);
  pointer-events:auto}
.ep-arriba:hover,.ep-arriba:focus-visible{border-color:var(--acento)}
.ep-arriba:focus-visible{outline:2px solid var(--acento);outline-offset:-4px}
@media (prefers-reduced-motion:reduce){.ep-arriba{transition:none}}
/* En papel no hay a dónde volver. Esto no estaba en la demostración —allí lo
   escondía el panel de la herramienta—; aquí hace falta, y esta hoja ya
   esconde en papel el conmutador de tema por la misma razón. */
@media print{.ep-arriba{display:none}}

/* ══ Y EL DISCO NO TAPA EL CONMUTADOR DE TEMA ══════════════════════════
   Auditoría independiente del sitio construido (05-10-2026), hallazgo GRAVE:
   con la página al final, el disco de «volver arriba» se montaba encima del
   botón «Oscuro» del pie. Medido en la portada y en la 404, en los dos
   temas, a 1100, 1180, 1280, 1366, 1440 y 1920 px: 43 × 26,5-27 px de cruce,
   el 42-43 % del área del botón, las 24 veces. A 768, 900, 1000, 1024 y
   1025 px no pasaba, porque ahí el renglón legal del pie ya se parte en dos
   filas y el conmutador baja a la izquierda.

   DECISIÓN DEL DIRECTOR: se corre el conmutador, no el disco. Sólo CSS.

   EL VALOR NO ES A OJO, Y NO ES UN NÚMERO A MANO. El disco está fijo a
   right:var(--pad-pagina) y el renglón del pie acaba justo en ese mismo
   borde (medido: los dos a 55 px del canto a 1280 px — 40 de --pad-pagina
   más los 15 que el sitio reserva para la barra de desplazamiento). Así que
   el hueco que hay que dejar es EXACTAMENTE el ancho del disco más holgura:
   --disco-arriba, el mismo token con el que el disco se dibuja tres reglas
   más arriba, más --e-1, el escalón más pequeño del proyecto. Quedan 8 px
   entre el canto izquierdo del disco y el derecho del conmutador.

   VA EN margin-right DEL CONMUTADOR Y NO EN padding-right DEL RENGLÓN: el
   renglón lleva su border-top a todo lo ancho —la raya que lo separa de lo
   de arriba— y un relleno a la derecha la habría acortado 52 px. Un margen
   en el conmutador no toca la raya.

   LO QUE SÍ CAMBIA, Y HAY QUE SABERLO: el renglón del pie se parte en dos
   filas 52 px antes que hoy. Medido: antes se partía entre 1025 y 1100 px
   (a 1025 ya en dos filas, a 1100 en una); ahora, entre 1100 y 1180. En esa
   franja el pie se ve como ya se veía más estrecho: la misma disposición
   aprobada, empezando un poco más ancho. */
.ep-pie__tema{margin-right:calc(var(--disco-arriba) + var(--e-1))}

/* ══ EL BOTÓN DE PAUSA DEL MURO SALE DE DEBAJO DEL DESVANECIDO ═════════
   Auditoría independiente del 05-10-2026, hallazgo MEDIO, y CAUSA DE LA
   DEUDA 25, abierta desde la Tarea 7 sin explicación.

   QUÉ PASABA. .ep-muro (base.css) difumina los dos cantos de la cinta de
   logotipos con una máscara —mask-image, transparente en el canto, opaca al
   8 %—. Y .ep-muro__pausa es HIJO de .ep-muro, así que la máscara se lo
   llevaba por delante: el botón se pinta a 16 px del canto derecho, o sea
   dentro del desvanecido, y ahí la máscara deja pasar entre el 15 % y el
   45 % de lo que se dibuja (medido columna a columna, y cuadra con la cuenta
   del degradado: medido columna a columna, 0,08 a 0,88 según el ancho y el
   tema). De ahí el filete de 1,38 y 1,32 de contraste de la deuda 25 y el
   anillo de foco de 1,09-1,20 contra un mínimo de 3: no era el color, era
   que el botón se pintaba medio borrado.

   LO QUE EL DIRECTOR APROBÓ, Y POR QUÉ NO SE HACE LITERAL. La decisión fue
   «mover la máscara del contenedor a la cinta que se mueve». SE PROBÓ Y SE
   FOTOGRAFIÓ: no sirve, y el informe lleva las fotos. La cinta
   (.ep-muro__pista) es MÁS ANCHA que el contenedor (width:max-content, dos
   juegos de tarjetas) y además SE DESPLAZA; la máscara se mide sobre su caja,
   no sobre la ventana que recorta, así que el desvanecido deja de estar en
   los cantos del muro, se mete en medio de la cinta y viaja con ella. Medido
   contra la foto de hoy: 15.733 de 16.800 píxeles distintos en el canto
   izquierdo en claro y 16.796 en oscuro, con el peor canal a 186. Igual con
   la máscara también en .ep-muro__set. Es el riesgo que el encargo mandaba
   comprobar con una foto.

   LO QUE SÍ SE HACE, Y DA LA MISMA IMAGEN. El desvanecido se consigue con el
   mismo degradado, pero PINTADO ENCIMA en lugar de recortando: un ::after del
   contenedor, del color de la página (--fondo, que es el fondo del <body> en
   los dos temas), opaco en el canto y transparente al 8 %. El resultado es el
   mismo píxel —recortar la cinta para ver el fondo, o tapar la cinta con el
   fondo, dan el mismo color— y se comprobó así: fotografiando los dos cantos
   del muro con el botón escondido, antes y después, en los dos temas y a tres
   anchos. NINGÚN píxel de los 100.800 se mueve más de 15 sobre 255, y de los
   que se mueven, el 99,8 % lo hace 1 o 2.

   Y el botón queda FUERA: el ::after lleva z-index:1 y el botón z-index:2, así
   que el degradado pasa por debajo de él y ya no lo borra.

   Esto NO toca d2-portada-limpia.html ni, por tanto, base.css: la regla de
   .ep-muro de la base sigue ahí y este parche la anula por ir después, que es
   para lo que este módulo existe. El invariante de la Tarea 9 se conserva. */
.ep-muro{-webkit-mask-image:none;mask-image:none}
.ep-muro::after{content:"";position:absolute;inset:0;z-index:1;pointer-events:none;
  background:linear-gradient(to right,var(--fondo),transparent 8%,
    transparent 92%,var(--fondo))}

/* ══ LOS BOTONES AZULES, EN CRISTAL · decisión del Director, 07-10-2026 ══
   Nació en Privacidad, con su botón «Volver»: pidió «azul y glass». Lo vio
   después sobre una copia de la portada (BORRADORES/portada-botones-cristal.html),
   lo aprobó para la portada y Nosotros y, acto seguido, para la 404 y para
   «todos los botones de las maquetas que faltan construir». Por eso vive
   aquí, en lo común, y no en cada página.

   Son los dos botones azules de la base: .ep-btn--solido y el botón fuerte
   del panel de menú. El azul de marca translúcido no sirve —calculado, el
   texto blanco baja de 4,82 a 3,49 al 80 % sobre el fondo claro—, así que el
   cristal se hace con el azul FUERTE, el del propio botón al pasar el cursor,
   al 80 %: 5,15 sobre el fondo liso claro y 10,04 sobre el oscuro.
   SOBRE LAS FOTOGRAFÍAS NO ESTÁ MEDIDO: el Director lo dio por bueno a la
   vista y pidió no medirlo (deuda 53).

   Al pasar el cursor vuelven al sólido: esas reglas de la base pesan más y no
   se tocan. Donde una página ya les daba otro color —la portada en tema
   oscuro los pinta blancos— manda esa regla, que también pesa más. Va en
   «screen» para que el papel siga como estaba. base.css NO se toca. */
@media screen{
  .ep-btn--solido,.ep-nav__pbtn--fuerte{background:color-mix(in srgb,var(--marca-azul-fuerte) 80%,transparent);
    backdrop-filter:blur(14px) saturate(1.4);-webkit-backdrop-filter:blur(14px) saturate(1.4)}
  /* Y los de CONTORNO (Director, 07-10-2026, visto en el borrador de
     Capacitación y aprobado «para las otras pantallas»): la receta del botón
     «Menú», el panel al 45 % y el fondo desenfocado. Al pasar el cursor
     vuelven al panel sólido: esa regla de la base pesa más. */
  .ep-btn--contorno{background:color-mix(in srgb,var(--panel) 45%,transparent);
    backdrop-filter:blur(14px) saturate(1.4);-webkit-backdrop-filter:blur(14px) saturate(1.4)}
}

/* ══ EL DESPLEGABLE «SERVICIOS», SIN AIRE Y CON EL TEXTO QUE SE CORRE ═════
   Hallazgo del Director, 07-10-2026, con dos capturas. La caja del
   desplegable traía 8 px de aire arriba y abajo (base.css); con la última
   fila marcada, ese aire quedaba como una franja blanca debajo y «le quita
   armonía». Se quita: las filas llegan de canto a canto.
   Y al pasar el cursor el texto se corre 8 px a la derecha, como las
   entradas del panel de menú (que se corren 16: su letra es más grande). El
   sombreado gris de la base se conserva: se probó sin él y lo pidió de
   vuelta. La raya que se dibujaba de izquierda a derecha se probó y SALIÓ.
   base.css NO se toca: estas reglas empatan con las suyas y ganan por ir
   después. */
.ep-nav__sub{padding:0}
.ep-nav__sub a{transition:color .2s,padding-left .2s}
.ep-nav__sub a:hover{padding-left:calc(var(--e-2) + var(--e-1))}
@media (prefers-reduced-motion:reduce){
  .ep-nav__sub a{transition:none}
  .ep-nav__sub a:hover{padding-left:var(--e-2)}
}

/* ══ LO ELÁSTICO · Director, 08-10-2026 ═══════════════════════════════════
   El gesto vive en el guion del menú (JS_MENU, más abajo en este archivo):
   botones, tarjetas, cristal y fotografías de cabecera se dejan correr 14 px
   mientras se mantienen pulsados. Aquí solo va lo que el guion necesita de la
   hoja: mientras algo cede, no se selecciona el texto de la página ni sale el
   globo de «mantener pulsado» de iOS. */
html[data-arrastrando]{-webkit-user-select:none;user-select:none;-webkit-touch-callout:none}
