/* Reset, tipografía, layout primitivo, nav, botones, footer */

*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%}
body{
  background:var(--surface);color:var(--text);
  font-family:var(--font-text);line-height:1.62;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
/* Un tema se aplica como bloque completo y se declara en el marcado, no en la
   hoja: `data-tema` en <html> para el documento y en la <section> para las dos
   superficies que cambian de acto. Esta regla es lo único que hace falta para
   que un tema pinte: la sección toma su propio lienzo y su propia tinta, del
   mismo bloque, y por eso no puede haber una tinta que resuelva al color de su
   fondo. Antes esto eran seis bloques repartidos en cuatro hojas que
   reasignaban --void, --wht y --line a mano; uno de ellos produjo el titular
   invisible de /industrias.
   La banda fotográfica a sangre que cae dentro del acto claro entra aquí por
   posición y no por atributo: tokens.css le aplica el bloque de tema claro
   entero con ese mismo selector, y esta regla le da el lienzo y la tinta del
   acto. Sin ella la banda seguiría siendo el agujero oscuro que partía el acto
   claro en dos. */
[data-tema],
main > [data-tema="claro"] ~ .band{background:var(--surface);color:var(--text)}

/* ---------- LA CONMUTACIÓN: CORTE DURO ----------
   Un documento tiene UN tema y como mucho UNA conmutación: el paso del acto
   narrativo —el film del home, el hero de una interna— al acto de evidencia,
   donde se leen normas, cifras y fuentes. Es un CORTE DURO: la sección clara
   empieza donde acaba el acto oscuro, sin franja de interpolación. Aquí vivía
   una franja de 56vh en degradado de --ink-950 a --ink-50, abierta con margen
   en la primera sección clara de cada tanda; se fue entera —reglas, margen,
   ::after y su token--, y con ella las reglas que devolvían margen y padding a
   la segunda tanda en adelante. Las secciones traen su propio padding y margen
   0 de fábrica, así que el corte no necesita ni una regla. */

/* La sonda del tema de la barra. No se ve, no se lee y no se puede pulsar: es
   una regla de un píxel que cubre cada sección clara de arriba abajo, para que
   un IntersectionObserver pueda decir si lo que hay bajo la barra es el acto
   claro o el oscuro sin escuchar el scroll ni una sola vez. Al ser la conmutación
   un corte duro, la sonda cubre su sección entera: el observador dispara justo
   en el borde. La pone client/pages.ts. */
.tema-sonda{position:absolute;left:0;width:1px;top:0;bottom:0;
  visibility:hidden;pointer-events:none}
/* ---------- grano ----------
   El lienzo era color plano, y un color plano muy oscuro no se lee como
   material: se lee como vacío. El manual ya admite textura —de ahí salía la
   matriz de puntos que el home anterior pintaba con .dotfield—, así que grano
   fino no es una invención ajena al sistema, es la misma idea a otra escala.
   Ruido fractal en un SVG embebido: cero peticiones y cero bytes de red. La CSP
   del sitio permite `img-src 'self' data:`, que es lo que gobierna un
   background-image, así que entra sin tocar cabeceras.
   z-index 100: por encima del contenido (.wrap va a 3, la barra a 80) y por
   debajo del salto al contenido (200), que se queda limpio a propósito.
   Al 4% no mueve el contraste de forma medible —el trabajo AA de --body, --mut
   y --dim se mantiene— pero sí quita la sensación de plástico. */
body::after{
  content:"";position:fixed;inset:0;z-index:100;pointer-events:none;opacity:.04;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}
@media print{ body::after{display:none} }

img,svg{display:block;max-width:100%}
/* height:auto va aparte, sólo para <img>, y no es cosmético: los atributos
   width/height de una imagen entran como propiedades de autor con la prioridad
   más baja, así que en cuanto max-width:100% estrecha la caja el alto del
   atributo se queda quieto y la foto sale aplastada. Con height:auto el alto
   vuelve a salir de la relación de aspecto. Cualquier regla de clase que fije
   el alto (.mosaic img, .band > img, .phero-bg img…) sigue mandando: tiene más
   especificidad que este selector de elemento. No se toca <svg>, que sí se
   dimensiona por atributo en el logo. */
img{height:auto}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
a{color:inherit;text-decoration:none}

@view-transition{navigation:auto}
[data-view-logo]{view-transition-name:wg-logo}
[data-view-title]{view-transition-name:wg-title}
[data-view-media]{view-transition-name:wg-media}
::view-transition-old(root),::view-transition-new(root){animation-duration:260ms}
::view-transition-old(wg-media),::view-transition-new(wg-media){animation-duration:520ms;animation-timing-function:var(--ease)}

/* ---------- salto al contenido ----------
   Vivía duplicado en pages.css y en cinema.css porque el home no carga
   pages.css. Las dos copias declaraban exactamente lo mismo y base.css sí lo
   cargan las dos familias de página, así que la pieza es una sola y está aquí.
   El fondo es el naranja de marca y no el acento del tema: el salto vive fuera
   de toda sección, así que no tiene tema del que heredar. Su tinta es
   --on-brand, el marrón muy oscuro medido para leer sobre ese naranja. */
.skip{position:absolute;left:-9999px;top:0;z-index:200;background:var(--brand-org);
  color:var(--on-brand);font-family:var(--font-display);font-weight:800;padding:var(--s3) 20px;
  border-radius:0 0 var(--r-sm) 0}
.skip:focus{left:0}

h1,h2,h3,h4,.display{font-family:var(--font-display)}
.num{font-variant-numeric:tabular-nums;font-feature-settings:"tnum"}

.wrap{max-width:var(--maxw);margin:0 auto;padding:0 var(--gutter);position:relative;z-index:3}
/* La voz instrumental. El rótulo deja Montserrat y pasa a la pila mono del
   sistema: una etiqueta de instrumento se lee como metadato, no como titular
   pequeño. El tracking baja de .28em a .12em porque el mono ya es ancho por
   diseño; a .28em se deshilacha. El peso baja a 600: los monos del sistema
   traen la negrita más pesada que Montserrat y a 700 mancha.
   Aquí vivían dos variantes, .lbl--br y .kick, y las dos se retiraron con el
   sistema visual §6.1. .lbl--br encorchetaba el rótulo y producía
   `[ 00 · RIESGO EN CARRETERA ]`: numeración de sección, punto medio como
   separador y corchetes decorativos, tres señales de plantilla prohibidas en un
   solo elemento. .kick hacía el mismo trabajo que .lbl con otra forma (guion
   degradado por delante), y dos formas para un mismo papel es lo que convierte
   un rótulo que orienta en un tic que se repite página tras página.
   Queda una sola clase de antetítulo, y su presupuesto lo mide la puerta de
   verify.mts: ceil(secciones / 3) por página. */
.lbl{font-family:var(--font-mono);font-size:10.5px;letter-spacing:.12em;
  text-transform:uppercase;font-weight:600}

/* Los titulares iban en versales. No lo pide el manual: la única mención a
   mayúsculas en toda la documentación es historico/investigacion-motionsites.md:18, y ahí
   se está describiendo lo que hacen OTROS sitios de referencia —«tipografía
   enorme encima, en mayúsculas y peso máximo»—, no una regla de marca. Era una
   tendencia copiada, y es de las señales más fiables de plantilla de agencia.
   El coste real era el texto. Los titulares están escritos en frase y con voz:
   «Se entra al riesgo. Sin correrlo.», «El proceso no termina con horas
   cursadas. Termina con evidencia.» En versales eso deja de ser una frase que
   alguien dice y pasa a ser un rótulo. Se quita el transform y la copia habla
   en la caja en que fue escrita.
   Lo que sigue en versales es lo que semánticamente lo es: .lbl, que es rótulo
   y antetítulo, no prosa.
   Ajustes que pide el cambio de caja: la interlínea sube un punto (en versales
   no hay descendentes y 1.06 valía; en caja mixta se pisan), y la medida de h2
   baja de 19ch a 17ch porque en caja mixta caben más palabras por línea.

   LA ESCALA DEL TITULAR DEJA DE APLANARSE EN EL TRAMO MÓVIL.
   El suelo era un número fijo, 35px, que es lo que vale 4,5vw a 778px de ancho.
   Por debajo de ahí la escala dejaba de responder al ancho: a 390px el h1 seguía
   a 35px sobre una columna de 346px —390 menos los dos gutter de 22— y el
   titular se partía en tres renglones en 41 de las 96 portadas, y en cuatro en
   tres de ellas: /para/entidades-publicas, su espejo inglés y
   /en/industrias/defensa-y-seguridad. La medida de 29ch de pages.css
   no llega a morder ahí: a 35px son 667px y la columna mide 346, así que quien
   parte la línea en móvil es el viewport. Tampoco es la copia: el bloque
   declarado más ancho, «cobertura, trazabilidad, contratación», mide 659px a
   35px y la columna no cambia de tamaño porque se reescriba. Era el cuerpo, que
   no bajaba con el ancho.
   El término nuevo es min(7vw,35px): la ley móvil, proporcional a la columna,
   con el altiplano de 35px como techo. max(4.5vw,…) devuelve la ley de
   escritorio en cuanto la supera. Escrito así, por encima de 500px el valor es
   idéntico al de antes —35px hasta 778, 4,5vw hasta 1400, 63px a partir de ahí—
   y sólo cambia por debajo, que es donde estaba el fallo. Medido después: 768 y
   1440 salen con el mismo cuerpo y el mismo número de renglones que traían.
   El coeficiente es 7vw y no 7,2 para que la rodilla caiga en 400px: así el
   suelo gobierna entero el tramo de teléfono real (320, 360, 375, 390, 393) en
   lugar de dejar 390 medio punto por encima del suelo. Ese medio punto no es
   teórico: con 7,2vw el h1 salía a 28,08px y /en/industrias se partía por 0,9px
   de bloque.
   El suelo baja a 28px y no más abajo. A 28px se cierran 26 de las 41 portadas
   que se partían, y /para/entidades-publicas pasa de cuatro renglones a tres.
   Bajarlo a 25px dejaría sólo 5 portadas de tres renglones, pero 28px es el
   suelo de h2 —clamp(28px,3.6vw,46px)— y por debajo el titular de la página
   pesaría menos que los títulos de sus secciones: eso es cambiar un defecto de
   escala por otro peor. Las 15 portadas que siguen en tres renglones lo hacen
   porque su bloque declarado no cabe en 346px a ningún cuerpo legible: el de
   /para/entidades-publicas mide 659px a 35px y pediría 18,4px para entrar en
   una línea, a dos puntos y medio de la bajada, que va a 16px. Eso ya no es un
   defecto de escala.
   La interlínea se queda en 1.1. No decide cuántos renglones hay, sólo cuánto
   miden, y a 28px ya es la que corresponde a un cuerpo de display. */
h1{font-size:clamp(28px,max(4.5vw,min(7vw,35px)),63px);line-height:1.1;
  letter-spacing:-.018em;font-weight:300}
h1 .b{display:block;font-weight:800}
h2{font-size:clamp(28px,3.6vw,46px);font-weight:300;line-height:1.14;
  letter-spacing:-.018em;max-width:17ch}
h2 b{font-weight:900}
/* El destacado de titular recortado al acento del tema. Toma --accent-grad y no
   --grad por lo mismo que lo tomaba la cifra de `.fignum` mientras existió: sus
   cuatro apariciones servidas
   —el titular del calificador en las dos lenguas— caen dentro del acto claro,
   donde todos los demás `h2 b` van en --accent-soft (.sect h2 b, pages.css).
   Un mismo elemento con dos acentos según la hoja que lo estile es el fallo,
   no el estilo. El color sólido debajo es la red de `background-clip:text`. */
.g-text{color:var(--accent)}
@supports ((background-clip:text) or (-webkit-background-clip:text)){
  .g-text{background:var(--accent-grad);-webkit-background-clip:text;background-clip:text;color:transparent}
}
.ssub{color:var(--text-2);max-width:620px;margin-top:var(--s5);font-size:15.5px}

/* ---------- NAV ----------
   Barra flotante. Era una barra pegada de ancho completo y 78px de alto, con
   fondo opaco y una línea inferior que partía la pantalla en dos.
   El home ya se saltaba eso —`.page--home .nav` la ponía en `fixed` para que el
   film corriera por debajo— así que había dos navegaciones distintas según la
   página. Ahora hay una, y es la del home: flota sobre el contenido en las 88.

   La banda exterior ocupa todo el ancho pero NO recibe el puntero: sin
   `pointer-events:none` un rectángulo invisible de 60px de alto se comería los
   clics de la primera franja de cada página. Quien los recibe es la barra.

   AQUÍ VIVÍA `view-transition-name:wg-nav`, Y ERA LO QUE MATABA EL CRISTAL.
   Un `view-transition-name` distinto de `none` convierte al elemento en RAÍZ DE
   FONDO (backdrop root). El `backdrop-filter` de un descendiente sólo puede
   muestrear lo que se pinta DENTRO de esa raíz, y dentro de esta banda no se
   pinta nada: es transparente. Así que la píldora declaraba
   `blur(20px) saturate(1.25)`, el estilo computado lo decía, y no desenfocaba
   ni un píxel en ninguna de las 99 rutas que el sitio servía entonces —hoy son
   540 páginas—: el titular de la página se leía nítido por debajo del cristal y
   cruzaba la marca denominativa.
   MEDIDO en /industrias a 1440x900, comparando la misma captura con el filtro
   declarado y con `backdrop-filter:none`, que es la prueba que no admite
   interpretación —si el filtro hace algo, las dos capturas difieren—:
     con el nombre aquí   diferencia media 0,005 · 0,5 % de píxeles · máx 1
     con el nombre abajo  diferencia media 3,539 · 65,5 % de píxeles · máx 65
   Nitidez del laplaciano en la franja de la píldora sin contenido propio:
   1591,9 sin desenfoque, 1410,1 con él.
   El nombre no se pierde: baja a `.nav-pill`, que es la pieza que de verdad se
   ve. Un elemento NO es raíz de fondo para su PROPIO `backdrop-filter`, sólo
   para el de sus descendientes, así que ahí conviven. Comprobado también al
   revés: con el nombre en la píldora, `document.getAnimations()` sigue dando
   `::view-transition-group(wg-nav)`, o sea que la barra conserva su
   instantánea propia al cambiar de ruta.
   LA REGLA, que es más estrecha que «no mezclar las dos cosas»: ningún
   ANCESTRO de una superficie con `backdrop-filter` puede llevar
   `view-transition-name`. En el mismo elemento no estorba. */
/* El separador de arriba absorbe el recorte superior por la misma razón que el
   gutter absorbe el lateral en tokens.css. En vertical, y dentro del navegador,
   `env(safe-area-inset-top)` vale 0 y la barra no se mueve ni un píxel: el hueco
   de la muesca ya lo ocupa el cromo de Safari. Donde sí vale es cuando el sitio
   se abre desde la pantalla de inicio, sin cromo, que es donde la barra flotante
   quedaría medio metida bajo el reloj. */
.nav{position:fixed;top:0;left:0;right:0;z-index:80;pointer-events:none;
  padding-top:max(var(--nav-top),env(safe-area-inset-top,0px))}
.nav .wrap{display:flex;justify-content:center}
/* El eje del menú se declara aquí, en la hoja que es dueña de la barra, y no
   sólo en `.page .nav .menu` de pages.css. Es la otra mitad del destello del
   mega menú: mientras pages.css no había aplicado, los seis rótulos de la barra
   caían apilados en columna sobre el hero. Con el eje puesto en base.css la
   barra ya nace en fila. pages.css conserva su regla porque tiene más
   especificidad y es la que la esconde por debajo de 940px. */
.nav .menu{display:flex;align-items:center;gap:2px}
/* La barra deja de ser una píldora. Era la contradicción más visible del
   sitio: un óvalo de 999px arriba y, setecientos píxeles más abajo y dentro del
   mismo viewport, los botones del hero con canto de 4px. El óvalo es el sello
   —.pill, .cert, chips— y la barra no es un sello: es el contenedor de más
   jerarquía de la página, así que toma el radio de contenedor como el mega
   menú, el cajón móvil y las tarjetas. */

/* LA BARRA TIENE DOS ESTADOS, Y ESTA ES LA REGLA QUE LOS SIRVE A LOS DOS.
   Era una superficie fija —--ink-a60, rgba(3,8,13,.60)— con un borde de blanco
   al 8 %. Un solo estado para dos temas: encima de una sección clara quedaba
   una mancha gris con el titular de la sección legible por debajo del cristal,
   que es exactamente lo que un cristal no debe dejar pasar.
   Ahora la superficie y el filete son ROLES —--glass y --hairline-2— y quien
   decide qué tema resuelve esos roles es un `data-tema` escrito en la propia
   barra. Lo escribe un IntersectionObserver en client/pages.ts, según la
   sección que pasa por debajo. NUNCA un listener de scroll: la posición no se
   consulta, se observa.
   El marcado la sirve con `data-tema="oscuro"` puesto, así que sin JavaScript
   la barra es la de antes y el escáner de contraste la mide en ese estado.
   Detalle de cascada, que es lo que hace que esto funcione sin !important:
   `[data-tema]{background:var(--surface)}` de arriba y `.nav-pill` empatan en
   especificidad (0,1,0) y gana la última, o sea esta. El fondo de la barra es
   cristal; el de una sección con el mismo atributo, superficie opaca. */
.nav-pill{pointer-events:auto;display:inline-flex;align-items:center;gap:2px;
  min-height:var(--nav-h);padding:7px 7px 7px calc(var(--s3) + 2px);border-radius:var(--r-lg);
  border:1px solid var(--hairline-2);background:var(--glass);
  /* El nombre de transición de vista es de la píldora y no de la banda que la
     envuelve, y no es una preferencia: en la banda anulaba este desenfoque.
     El porqué, con las cifras, está arriba en la regla de `.nav`.
     LO QUE CUESTA, que es lo único que cuesta: la instantánea con nombre pasa a
     ser la caja de la píldora y no la banda de ancho completo, que era constante
     en todas. Medidos los anchos a 1440 sobre las 99 rutas de entonces —hoy son
     540 páginas—: 1014,75px en 48 rutas en español, 948,67px en las 49 en inglés
     y 952,52px en el home, que sirve un rótulo menos. O sea que un salto home↔interna (62,23px) o español↔inglés
     (66,08px) ahora interpola el ancho de la barra en vez de sostener una caja
     fija y fundir la píldora dentro. Entre las 48 rutas de una misma familia el
     ancho es idéntico y no se mueve nada, que es el 97 % de las navegaciones. */
  view-transition-name:wg-nav;
  backdrop-filter:blur(20px) saturate(1.25);
  box-shadow:0 8px 32px var(--ink-a30);
  transition:border-color var(--t-ui) var(--ease),background var(--t-ui) var(--ease),
    color var(--t-ui) var(--ease)}
.nav-pill:hover{background:var(--glass-2)}
/* Sin JavaScript no hay observador, así que la barra se queda oscura también
   cuando por debajo pasa el acto claro. Medido: el cristal al 70 % sobre
   rgb(244,247,250) compone rgb(75,80,84), y ahí el rótulo del menú —--text-2,
   #a6b7c6, 12px/600— da 3.97:1, por debajo de los 4.5 que pide AA. Subiéndolo
   al 90 % compone rgb(27,32,37) y el mismo rótulo da 7.98:1.
   La clase la pone boot.js antes del primer pintado, así que esta regla sólo
   llega a aplicarse cuando de verdad no hay JavaScript, y no cuesta ni un
   fotograma a quien sí lo tiene. */
html:not(.js) .nav-pill{background:var(--ink-a90)}

.logo{display:flex;align-items:center;gap:8px;text-decoration:none;padding-right:var(--s2)}
/* La W oficial ya no es el recálculo de image3: es el isotipo del manual de
   identidad 2026, y su caja real es 139.71x116.28. Fijar también la altura la
   aplastaría, así que la medida del sistema —26px que pasan a 34px— se aplica
   al ANCHO y la altura la da el trazado (34px de ancho → 28.3 de alto). */
.logo svg{width:34px;height:auto;flex:none}
/* EL WORDMARK LLEVA LA MARCA, como el «logo a color» del manual: WAY en el
   naranja primario y GROUP en el azul secundario. Con un matiz de fondo:
   sobre el cristal oscuro el azul de marca —#004b7e, 1.9:1— no se lee y el
   propio manual manda la versión blanca cuando el fondo no es claro, así que
   ahí GROUP y la bajada quedan en tinta del tema y sólo WAY lleva naranja,
   que sobre el cristal oscuro da 7.4:1. El azul aparece al virar la píldora
   a claro, que es donde el manual pone el lockup a color. El escáner mide el
   estado servido —oscuro— y la píldora no declara data-estado-js: el lockup
   a color es logotipo, exento por WCAG 1.4.3, y lo prescribe el manual. */
.logo b{display:block;font-family:var(--font-display);font-weight:800;font-size:17px;
  letter-spacing:.02em;line-height:1;color:var(--brand-org)}
.logo b i{font-style:normal;font-weight:400;color:var(--text)}
[data-tema="claro"] .logo b i{color:var(--brand-blu)}
/* La bajada «FOR EDUCATION LATAM» vuelve a la barra: el lockup completo es la
   marca nueva (image5) y la W de 34px ya le da aire para leerse. Estuvo
   escondida desde que a 7,5px en una píldora de 46px era un renglón ilegible;
   a 8,5px con la píldora crecida vuelve a ser texto. En oscuro la tinta es
   --text-2, el rol de los rótulos de esta misma barra —un acento de 8,5px no
   pasaría AA sobre el cristal—; en claro la píldora lleva la bajada en el
   azul de marca, igual que GROUP: es el lockup a color del manual. El
   selector es `span span` y no `span` a
   secas porque el marcado anida dos: el de fuera envuelve el wordmark Y la
   bajada. */
.logo span span{display:block;font-family:var(--font-display);font-weight:600;
  font-size:8.5px;letter-spacing:.24em;line-height:1;color:var(--text-2);margin-top:3px}
[data-tema="claro"] .logo span span{color:var(--brand-blu)}
/* El conmutador de idioma es un <a> que apunta a la contraparte, no un par de
   botones con aria-pressed: el bilingüismo es de rutas, no de cliente.
   Es un control, y toma el canto de control como el resto de los enlaces de la
   barra. El padding de 8/11 no cambia: la zona pulsable queda en 26x27, por
   encima de los 24x24 que pide WCAG 2.2 AA 2.5.8 — que es el mismo motivo por
   el que antes llevaba 9/6. */
.lang-link{font:700 10.5px/1 var(--font-display);letter-spacing:.14em;color:var(--text-3);
  display:inline-flex;align-items:center;gap:6px;padding:8px 11px;border-radius:var(--r-md);
  transition:color var(--t-ui) var(--ease),background var(--t-ui) var(--ease)}
/* La bandera ya no es un emoji sino un SVG inline (Nav.astro): el emoji de
   bandera degrada a letras en Windows. La caja conserva la medida que el emoji
   ocupaba (13px de alto) y el filete es el de separación, no el de control: la
   señal de pulsable la da el conjunto bandera+código dentro de `.lang-link`,
   que ya es un control con su propio canto al pasar el cursor. Sin radio: la
   escala de forma no tiene un canto de 2px y 0 es un valor legítimo. */
.lang-flag{width:18px;height:13px;flex:none;display:block;border:1px solid var(--hairline)}
/* El velo del hover es --veil y no blanco al 8 %: sobre la barra clara un velo
   blanco no existe. Mismo cambio en los enlaces del menú, la hamburguesa y las
   filas del desplegable, en pages.css. */
.lang-link:hover,.lang-link:focus-visible{color:var(--accent-soft);background:var(--veil)}

/* ---------- BOTONES ---------- */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:var(--s3);
  /* Era --r-seal (entonces --r-pill). El botón primario lleva el degradado del
     manual, que no se toca, pero la píldora la puso el prototipo y no el
     manual: píldora naranja + halo naranja era la pieza más reconociblemente
     generada del sitio. Con canto mecanizado el degradado sigue mandando y deja
     de parecer una pastilla.
     Y el rol es control, no contenedor: pasó por --r-lg mientras la escala tenía
     tres escalones y no cinco. Un botón dentro de una tarjeta con el mismo canto
     que la tarjeta lee como un recorte de ella; 2 dentro de 4 lee como una pieza
     montada, que es la relación correcta entre lo que contiene y lo contenido. */
  padding:var(--s4) var(--s6);border-radius:var(--r-md);text-decoration:none;
  /* Un botón no puede ser más ancho que la caja que lo contiene. Parece obvio y
     no lo era: .btn es inline-flex y su base es max-content, así que un rótulo
     largo se salía de su columna en vez de partirse. En /contacto @390 el CTA
     medía 338,3px dentro de una columna de 296 y llegaba a 4,7px del borde del
     viewport, con el gutter móvil fijado en 22px. El límite va aquí, en el
     control, y no en cada contenedor que lo hospeda. */
  max-width:100%;text-align:center;
  font-family:var(--font-display);font-size:12.5px;font-weight:700;letter-spacing:.06em;
  text-transform:uppercase;transition:transform var(--t-ui) var(--ease),
  box-shadow var(--t-ui),background var(--t-ui),border-color var(--t-ui)}
/* El texto era #fff y no pasaba AA en ninguna parte del degradado donde de
   hecho está. auditoria-profunda.md lo midió: 2.95:1 al 48%, que es justo donde
   cae una etiqueta centrada, y no se salva por texto grande porque .btn es de
   12.5px/700 y el umbral empieza en 18.66px en negrita. Afectaba a la acción
   principal del sitio en las 46 páginas.
   El degradado sale del manual y no se toca. Lo que cambia es la tinta, y no es
   invención: #180a00 ya es el patrón de esta casa para «texto sobre el naranja
   de marca» —lo usa .skip más arriba, con ese mismo comentario—.
   Medido sobre los cinco tramos del degradado, ninguna tinta pasa de extremo a
   extremo: #fff sólo cumple en el rojo (4.62) y falla en todo lo demás; #180a00
   cumple de 25% en adelante y cruza el 4.5 al 10%. Lo que decide es dónde está
   el texto de verdad, y eso lo fija el padding lateral de 32px (--s6): la
   etiqueta vive entre el 13% y el 87%, donde el mínimo es 4.64.
   DEPENDENCIA: ese padding es lo que garantiza el contraste. Pero el porcentaje
   no lo fija el padding solo: lo fija el padding DIVIDIDO por el ancho. 32px son
   el 13% de un botón de 246px y sólo de ése; en uno más ancho el mismo padding
   vale menos porcentaje y la etiqueta se mete en el arranque rojo del degradado.
   La nota anterior daba por hecho que en el sitio no había rótulos tan largos y
   se equivocaba: «Preparar mensaje por WhatsApp» mide 274px de rótulo, hacía un
   botón de 338px, arrancaba al 9,5% y daba 4,50 —el umbral AA clavado— en 390 y
   en 1440.
   Por eso el ancho es parte de la garantía y está escrito como tal: el botón del
   degradado no pasa de --s6 / 13%. Un rótulo más largo no lo ensancha; se parte
   en dos líneas y la etiqueta vuelve a su tramo. Si alguien cambia el padding
   lateral, esta fórmula se recalcula sola. */
.btn-p{background:var(--grad);color:var(--on-brand);box-shadow:var(--shadow-org);
  max-width:min(100%,calc(var(--s6) / .13))}
/* EL LEVANTE DEL BOTÓN SE CONDICIONA AL PUNTERO, Y NO ES PUREZA: en iOS el
   `:hover` de un elemento pulsado SE QUEDA PUESTO hasta que se toca otra cosa.
   Sin esta guarda, la acción principal del sitio queda 2px más arriba después de
   pulsarla, en la única pantalla donde nadie ha pasado un cursor por encima. Un
   estado de ratón congelado en un teléfono es la señal más barata de que la
   página se diseñó de espaldas al dedo. */
@media (hover:hover){
  .btn-p:hover{transform:translateY(-2px)}
}
/* El canto va con --control-edge y no con --hairline-2 por lo mismo que iba el
   de los campos de /contacto mientras existieron: este botón NO tiene relleno en
   reposo, así que su canto no separa nada, es lo único que dice que ahí hay un
   botón y no una línea de texto con un enlace. WCAG 1.4.11 le pide 3:1 contra lo
   que tiene al lado; medido antes sobre las rutas construidas, daba 1,899:1
   sobre --surface-2 del acto oscuro, 1,984:1 sobre --surface del claro y 2,015:1
   sobre la tarjeta blanca de /contacto, que era el peor caso del sitio. Ninguno
   llegaba.
   No se sube --hairline-2, que es el rol de SEPARACIÓN y pinta las retículas de
   todo el sitio. Este botón fue el segundo consumidor del rol; con /contacto ya
   retirada quedan cuatro declaraciones, y la lista está en tokens.css junto al
   token. */
.btn-g{border:1.5px solid var(--control-edge);color:var(--text)}
.btn-g:hover{border-color:var(--accent-soft);background:var(--org-a10)}
/* LA RESPUESTA A LA PRESIÓN, que el contrato §5.1 pide por su nombre («presión
   en control → respuesta táctil, scale(.98) en :active») y que hasta hoy sólo
   tenía un consumidor en todo el sitio, el filtro de vídeos.
   No es adorno: en un teléfono no hay hover, así que el `:active` es el ÚNICO
   acuse de recibo que existe entre el toque y la navegación. Va después de las
   reglas de hover porque empata con ellas en especificidad y tiene que ganar por
   orden, y antes de `:disabled`, que sigue mandando sobre las dos.
   `transform` es propiedad compuesta: cabe dentro del presupuesto de fotograma
   de §5.4 sin repintar nada. */
.btn:active{transform:scale(.98)}
.btn:disabled{opacity:.35;cursor:not-allowed;transform:none}

/* El recuadro gris que iOS pinta encima de lo que se toca es del sistema, y del
   sistema es también el gris: no sale de esta paleta y no sigue al tema. Se
   sustituye por el mismo velo que ya usa el hover de la barra, que sí es un rol
   y sí cambia con el acto. No se pone `transparent`, que es lo que suele hacerse
   y es peor que dejarlo: quitar el destello sin poner otro deja el toque sin
   acuse en los enlaces que no tienen `:active` propio. */
a,button,summary,[role="button"]{-webkit-tap-highlight-color:var(--veil)}

/* El anillo de foco es el acento del tema y no un color fijo: en el acto
   oscuro es el naranja, en el claro el azul. Antes esta regla decía ámbar y
   la de pages.css decía naranja para lo mismo, y las secciones claras se lo
   volvían a pisar con --section-focus. Un solo origen.
   El radio era un 4 literal escrito dos veces —aquí y en pages.css— y no es el
   canto de un contenedor: es el del anillo, que tiene su propio rol.
   La unificación se dejó una copia viva: pages.css repetía el mismo cuerpo con
   una lista de selectores llana, que a igual valor GANABA a este `:where()` por
   especificidad. Se fue en la poda de septiembre de 2026, y con ella entran aquí
   `textarea` y `summary`, que eran los dos elementos que aquella lista cubría y
   ésta no. `summary` es enfocable sin `tabindex`, así que no lo cubría la rama
   del atributo. Todos van dentro del `:where()`: el anillo es un suelo, y lo que
   quiera separarse de él tiene que poder hacerlo con un selector de clase. */
:where(a,button,input,select,textarea,summary,[tabindex]):focus-visible{
  outline:2px solid var(--accent);outline-offset:3px;border-radius:var(--r-focus)}

/* ---------- FOOTER ---------- */
/* El separador de abajo SUMA el recorte inferior en vez de tomar el mayor de los
   dos, y la diferencia importa: el indicador de inicio del iPhone no es una zona
   que haya que evitar pisar, es una barra que se dibuja ENCIMA. Con `max()` los
   34px del indicador se comerían 34 de los 44 de aire y la última línea del pie
   quedaría pegada debajo de él; sumando, el aire declarado se conserva entero
   por encima de la barra. */
.foot{border-top:1px solid var(--hairline);
  /* El sello y Edu necesitan una franja libre al final para no tapar enlaces. */
  padding:var(--s8) 0 calc(var(--s9) + env(safe-area-inset-bottom,0px));
  background:linear-gradient(180deg,transparent,var(--blu-a15));color:var(--text-3);font-size:13px}
/* La firma. El wordmark a escala de cierre, en trazo y no en relleno: un
   sello enorme que pesa poco. El tope de 168px está medido contra la caja
   real: WAYGROUP en 900 con .04em son ~6.2em de ancho, y 6.2 × 168px ≈
   1042px, dentro de los 1252 útiles de --maxw menos gutters. El fallback
   de @supports existe porque un trazo sin soporte sería texto transparente:
   mejor tinta tenue que nada. */
.foot-mark{padding-bottom:var(--s8);text-align:center}
.foot-mark b{display:block;font-family:var(--font-display);font-weight:900;
  font-size:clamp(36px,12.5vw,168px);line-height:.92;letter-spacing:.04em;
  margin-top:var(--s4);color:transparent;-webkit-text-stroke:1px var(--hairline-2)}
/* La segunda línea de la rúbrica (image28 de los ajustes): el reposicionamiento
   «WayGroup For Education LATAM» se firma entero también al pie. En tinta y no
   en trazo —un trazo de 1px a este tamaño se desharía—, y en --text-3, el rol
   de la prosa de este pie: la firma grande ya tiene su jerarquía. */
.foot-mark-latam{display:block;font-family:var(--font-display);font-weight:700;
  font-size:clamp(13px,2.4vw,26px);letter-spacing:.34em;line-height:1.2;
  margin-top:var(--s3);color:var(--text-3)}
@supports not (-webkit-text-stroke:1px currentColor){
  .foot-mark b{color:var(--surface-4)}
}
.foot a{text-decoration:none;transition:color var(--t-ui)}
.foot a:hover{color:var(--accent-soft)}
.foot-bot{display:flex;justify-content:center;gap:20px;flex-wrap:wrap;text-align:center;
  padding-top:var(--s5);border-top:1px solid var(--hairline);
  font-family:var(--font-mono);font-size:10.5px;letter-spacing:.04em;color:var(--text-3)}
/* Los dos enlaces legales medían 12px de alto —el interlineado del mono a
   10,5px— en las 493 páginas, y son los ÚNICOS enlaces del pie que no llegaban a
   los 24x24 de WCAG 2.2 AA 2.5.8: los tres de contacto ya declaran
   `min-height:44px` en pages.css. No cabe la excepción de «enlace en línea»,
   que ampara al que va dentro de una frase: éstos son una fila de navegación de
   dos elementos separados por un punto medio. El alto se gana con caja y no con
   padding para no mover el punto medio que los separa. */
.foot-bot a{display:inline-flex;align-items:center;min-height:24px}

/* ---------- PLACA ISO FLOTANTE ---------- */
/* El sello negro ISO ocupa la esquina inferior izquierda, en pareja con Edu a
   la derecha. Conserva su destino de calidad y el nivel del lanzador de Edu. */
.iso-placa{position:fixed;z-index:70;
  left:max(24px,env(safe-area-inset-left,0px));
  bottom:max(24px,env(safe-area-inset-bottom,0px));
  display:block;width:56px;box-sizing:border-box;padding:6px;
  background:var(--ink-900);border-radius:var(--r-sm);line-height:0;
  transition:transform var(--t-ui) var(--ease),opacity var(--t-ui) var(--ease),visibility var(--t-ui)}
.iso-placa[data-apartado]{opacity:0;visibility:hidden}
.iso-placa img{display:block;width:100%;height:auto}
.iso-placa:focus-visible{outline:2px solid var(--brand-blu-2);outline-offset:4px}
@media (hover:hover){
  .iso-placa:hover{transform:translateY(-2px)}
}
/* ---------- EDU ---------- */
/* El robot que lleva a WhatsApp (`ui/shell/Edu.astro`). El lanzador ocupa la
   esquina con el z-index que tenía la placa, 70: por debajo de la barra y del
   cajón móvil. El panel es un `popover` y vive en la capa superior, así que no
   pide ninguno. Mientras hay otra ruta a WhatsApp en pantalla `pages.ts`
   escribe `data-apartado` y el lanzador se desvanece: la visibilidad transita
   con duración y no con retraso, que es lo que la deja visible mientras dura
   el fundido y la saca del orden de tabulación al acabar. */
.edu-lanzador{position:fixed;z-index:70;
  right:max(24px,env(safe-area-inset-right,0px));
  bottom:max(24px,env(safe-area-inset-bottom,0px));
  display:flex;align-items:center;gap:var(--s2);padding:5px 16px 5px 5px;
  border:1px solid var(--edu-luz-a45);color:var(--text);cursor:pointer;
  background:color-mix(in oklab,var(--surface-3) 82%,transparent);
  backdrop-filter:blur(16px) saturate(1.2);box-shadow:0 10px 30px var(--ink-a60);
  font:700 12px/1 var(--font-display);letter-spacing:.06em;text-transform:uppercase;
  transition:transform var(--t-ui) var(--ease),border-color var(--t-ui),
    opacity var(--t-ui) var(--ease),visibility var(--t-ui)}
@media (hover:hover){
  .edu-lanzador:hover{transform:translateY(-2px);border-color:var(--edu-luz)}
}
.edu-lanzador:active{transform:scale(.98)}
/* verify: forma — el botón «Habla con Edu» es una píldora con la cara redonda del robot, igual que el lanzador flotante */
.edu-cta{display:inline-flex;align-items:center;gap:var(--s2);padding:5px 16px 5px 5px;border:1px solid var(--edu-luz-a45);border-radius:var(--r-seal);background:transparent;color:inherit;cursor:pointer;white-space:nowrap;font:700 12px/1 var(--font-display);letter-spacing:.06em;text-transform:uppercase}
.edu[data-apartado] .edu-lanzador{opacity:0;visibility:hidden}

/* La cara: la foto recortada del robot, con su anillo y un halo que respira.
   El halo sólo mueve opacidad, y el bloque de movimiento reducido de abajo lo
   deja quieto. */
.edu-cara{position:relative;flex:none;width:40px;height:40px;
  background:var(--ink-950);box-shadow:0 0 0 1.5px var(--edu-luz-a45)}
.edu-cara--lg{width:48px;height:48px}
.edu-cara picture{display:block;width:100%;height:100%}
.edu-cara img{display:block;width:100%;height:100%;object-fit:cover}
.edu-cara::after{content:"";position:absolute;inset:0;pointer-events:none;
  box-shadow:0 0 18px 2.5px var(--edu-luz-a45);opacity:.45;
  animation:edu-respira 3.6s var(--ease) infinite alternate}
@keyframes edu-respira{from{opacity:.25}to{opacity:.85}}
/* verify: forma — la cara de Edu es redonda por lo que es: el anillo de luz del robot */
.edu-lanzador,.edu-cara,.edu-cara img,.edu-cara::after{border-radius:var(--r-seal)}

/* El panel. `display` sólo en el estado abierto: la hoja del navegador oculta
   el popover cerrado con `display:none`, y una regla de autor sin
   `:popover-open` le ganaría y lo dejaría siempre a la vista. Abre con
   `@starting-style`; cierra en seco. El tope de alto es para cuando no hay
   JavaScript y las cinco preguntas se ven seguidas: el popover ya trae
   `overflow:auto` y el panel se desplaza por dentro. Los 52px del `bottom` son el alto del
   lanzador (40 de cara, 5 + 5 de relleno, 1 + 1 de filete): si cambia, cambian. */
.edu-panel{position:fixed;inset:auto;margin:0;
  right:max(24px,env(safe-area-inset-right,0px));
  bottom:calc(max(24px,env(safe-area-inset-bottom,0px)) + 52px + var(--s3));
  width:312px;max-width:calc(100vw - 48px);padding:var(--s4);
  max-height:calc(100dvh - 2 * max(24px,env(safe-area-inset-bottom,0px)) - 52px - var(--s3));
  border:1px solid var(--hairline-2);border-radius:var(--r-lg);
  background:var(--surface-3);color:var(--text);box-shadow:0 24px 60px var(--ink-a80);
  font-family:var(--font-text);transform-origin:100% 100%;
  transition:opacity 180ms var(--ease),transform 220ms var(--ease-out)}
/* Alto de su contenido y filas sin estirar: con un alto fijado desde fuera
   (la hoja del teléfono llegó a medir el 85dvh entero) el `align-content` por
   defecto repartía el sobrante entre las filas y estiraba globo, fichas y botón. */
.edu-panel:popover-open{display:grid;gap:var(--s3);height:fit-content;align-content:start}
@starting-style{
  .edu-panel:popover-open{opacity:0;transform:translateY(8px) scale(.98)}
}
.edu-panel::backdrop{background:transparent}
.edu-cab{display:flex;align-items:center;gap:var(--s3)}
.edu-nombre{margin:0;font:800 17px/1.1 var(--font-display);letter-spacing:-.01em}
.edu-rol{margin:2px 0 0;font-size:12px;color:var(--text-3)}
.edu-cerrar{margin-left:auto;align-self:flex-start;width:28px;height:28px;
  display:grid;place-items:center;border:0;border-radius:var(--r-md);
  background:transparent;color:var(--text-2);cursor:pointer;font-size:18px;line-height:1;
  transition:background-color var(--t-ui),color var(--t-ui)}
.edu-cerrar:hover{background:var(--hairline);color:var(--text)}
.edu-globo{margin:0;padding:var(--s2) var(--s3);border:1px solid var(--hairline);
  border-radius:var(--r-sm) var(--r-md) var(--r-md) var(--r-md);
  background:var(--surface-4);font-size:14px;line-height:1.5}
/* Las opciones de cada pregunta son radios nativos vestidos de ficha: la
   flecha del teclado, el estado elegido y el nombre accesible vienen de
   fábrica. Son opcionales: lo que no se contesta no viaja en el mensaje. Sin relleno en reposo,
   así que su canto es --control-edge. */
.edu-temas{display:flex;flex-wrap:wrap;gap:var(--s2);margin:0;padding:0;border:0}
.edu-temas legend{margin-bottom:var(--s2);padding:0;font-size:12px;color:var(--text-2)}
.edu-chip{position:relative;display:inline-flex}
.edu-chip input{position:absolute;inset:0;margin:0;opacity:0;cursor:pointer}
.edu-chip span{display:inline-flex;padding:7px 12px;
  border:1.5px solid var(--control-edge);border-radius:var(--r-md);
  font:600 13px/1.2 var(--font-text);
  transition:border-color var(--t-ui),background-color var(--t-ui)}
.edu-chip input:checked+span{border-color:var(--accent);background:var(--accent-wash)}
.edu-chip input:focus-visible+span{outline:2px solid var(--accent);outline-offset:3px}
/* El botón es el `.btn-p` de la casa, con su tope de ancho medido: se centra en
   vez de estirarse, porque la tinta sobre el degradado depende de dónde cae
   el rótulo. En el panel sólo adelgaza en vertical: el relleno lateral y el
   tope son esa garantía, y no se tocan. */
.edu-ir{justify-self:center;padding-block:var(--s3)}
.edu-ayuda{margin:calc(var(--s1) * -1) 0 0;font-size:12px;color:var(--text-3);text-align:center;text-wrap:balance}

/* En el teléfono Edu es sólo la cara, un poco más grande (el nombre lo sigue
   dando el `aria-label`), y el panel sube como hoja desde abajo, con velo. */
@media (max-width:899px){
  .edu-lanzador{padding:0}
  .edu-lanzador .edu-cara{width:48px;height:48px}
  .edu-rotulo{display:none}
  .edu-panel{left:0;right:0;bottom:0;width:auto;max-width:none;max-height:85dvh;
    border-radius:var(--r-lg) var(--r-lg) 0 0;
    padding-bottom:calc(var(--s4) + env(safe-area-inset-bottom,0px));transform-origin:50% 100%}
  @starting-style{
    .edu-panel:popover-open{transform:translateY(24px)}
  }
  .edu-panel::backdrop{background:var(--ink-a60)}
  .edu:has(.edu-panel:popover-open) .edu-lanzador{opacity:0;visibility:hidden}
}
/* Sin popover el panel se pintaría abierto dentro de la página. Mejor sin Edu:
   el calificador y la banda de /simuladores siguen llevando a WhatsApp. */
@supports not selector(:popover-open){
  .edu{display:none}
}

/* ---------- EDU: LAS CINCO PREGUNTAS ---------- */
/* Edu hace las preguntas del calificador de una en una (`pages.ts` oculta las
   demás con `hidden`) y deja lo contestado arriba, en fichas que devuelven a
   su pregunta. Aquí sólo hay maquetación: las preguntas son `.edu-temas` y las
   fichas `.edu-chip`, con su tamaño de siempre.
   `hidden` necesita regla propia porque `.edu-temas` y `.edu-chip` declaran
   `display`, y cualquier `display` de autor le gana al de la hoja del
   navegador: sin esto, las cinco preguntas seguirían a la vista. */
.edu [hidden]{display:none}
.edu-hechas{display:flex;flex-wrap:wrap;gap:var(--s2)}
/* La ficha es un botón con la cara de la opción elegida: fuera el relleno, el
   canto y el fondo del botón nativo, y dentro el acento del radio marcado. */
.edu-hecha{padding:0;border:0;background:none;color:inherit;cursor:pointer}
.edu-hecha span{border-color:var(--accent);background:var(--accent-wash)}

/* ---------- MOVIMIENTO REDUCIDO ---------- */
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{animation-duration:.01ms !important;animation-iteration-count:1 !important;
    transition-duration:120ms !important}
  /* .reveal, que es el que existe hoy, ya se neutraliza donde se define
     (pages.css:239). Aquí quedaba .rv, su antecesor, sin marcado que lo use. */
}
