/* sitio.css — reglas propias del sitio IPCGE. El sistema de diseno vive en
   modernist.css y no se toca. Orden: fuente, comunes, cambios V de color,
   especificas por pagina, piezas nuevas (menu movil, saltar al contenido),
   escalon de tablet. */

/* ---- Fuente autoalojada (cambio V5; reemplaza el @import de Google Fonts) ---- */
@font-face { font-family: 'Archivo'; font-style: normal; font-weight: 400; font-display: swap; src: url('/fuentes/archivo-400.woff2') format('woff2'); }
@font-face { font-family: 'Archivo'; font-style: normal; font-weight: 600; font-display: swap; src: url('/fuentes/archivo-600.woff2') format('woff2'); }
@font-face { font-family: 'Archivo'; font-style: normal; font-weight: 800; font-display: swap; src: url('/fuentes/archivo-800.woff2') format('woff2'); }

/* ---- Comunes: identicas en las 12 paginas del prototipo ---- */
:root[data-theme="dark"] { --color-bg: var(--color-neutral-900); --color-surface: var(--color-neutral-800); --color-text: var(--color-neutral-100); --color-divider: color-mix(in srgb, var(--color-neutral-100) 35%, transparent); }

/* ══════════════════════════════════════════════════════════════════════════
   TOKEN SEMANTICO — "acento a tamano de lectura, sobre el suelo actual"
   ══════════════════════════════════════════════════════════════════════════
   El prototipo escribe `color: var(--color-accent-700)` EN LINEA, 30 veces
   repartidas en las 12 paginas (kickers de seccion, subtitulo del hero). Ese
   paso es el correcto en suelo claro y da 1,96:1 en suelo oscuro: ilegible.

   Poner el paso correcto en un token en lugar de repetir la decision 30 veces
   es lo que el sistema haria: --color-accent-700 sigue siendo lo que dice su
   nombre, un escalon de la rampa, y ESTE token dice para que sirve. Es la
   misma regla de V8 y V14 —el paso del acento sigue al suelo— expresada una
   sola vez.

   En suelo claro resuelve al mismo accent-700 de siempre: el render no cambia
   ni un pixel. El cambio se ve solo en oscuro, donde hoy no se lee.

   EN OSCURO SE ELIGIO accent-400, no accent-300. Los tres pasos candidatos,
   medidos sobre el hero en tema oscuro:

     accent-300   9,28:1   pasa, pero se ve rosa palido: se aleja del rojo
     accent-400   6,71:1   pasa con margen y es lo mas cercano al rojo de marca
     accent-500   4,46:1   NO pasa, por 0,04

   accent-400 es tambien el paso que el readme del sistema nombra para suelo
   oscuro ("accent-400 on a dark one"), asi que no es una eleccion propia.

   El paso "fuerte" es para los estados de hover: mas contraste en los dos
   suelos, oscureciendo en claro y aclarando en oscuro.
   ══════════════════════════════════════════════════════════════════════════ */
:root {
  --ipcge-acento-texto: var(--color-accent-700);
  --ipcge-acento-texto-fuerte: var(--color-accent-800);
}
:root[data-theme="dark"] {
  --ipcge-acento-texto: var(--color-accent-400);
  --ipcge-acento-texto-fuerte: var(--color-accent-300);
}

/* ══════════════════════════════════════════════════════════════════════════
   CAMBIO V15 — Un piso para el texto atenuado
   ══════════════════════════════════════════════════════════════════════════
   El prototipo atenua texto pequeno con --color-text a tres niveles distintos:
   45 % (9 elementos: la numeracion 01-09 de investigacion), 55 % (5: las fechas
   de actualidad y de las paginas legales) y 60 % (5: apoyos de 11 y 13 px).
   Medido, ninguno de los tres llega a 4,5:1 en 11-13 px:

     45 %   2,71:1 en claro   3,87:1 en oscuro
     55 %   3,52:1            5,02:1
     60 %   3,95:1            5,4:1
     65 %   4,94:1  OK        6,37:1  OK     <- el piso

   El minimo exacto es 63 % (4,56:1); se usa 65 % porque es el nivel que el
   diseno YA emplea para el parrafo del pie y el que V12 eligio, asi que no
   agrega un valor nuevo al sistema.

   Consecuencia asumida: los tres niveles colapsan en uno, asi que se pierde
   jerarquia entre "tenue", "mas tenue" y "muy tenue". No hay alternativa: por
   debajo de 63 % nada cumple. Quedan dos escalones legibles —este 65 % y el
   78 % del cuerpo de texto— mas el texto a fuerza plena.
   ══════════════════════════════════════════════════════════════════════════ */
:root { --ipcge-texto-tenue: color-mix(in srgb, var(--color-text) 65%, transparent); }

/* El encabezado de tabla usa el 60 % desde modernist.css, no desde un style en
   linea, asi que la sustitucion del conversor no lo alcanza: da 4,24:1 a 11 px.
   Se corrige aca, como el resto de lo que vive en el archivo del sistema. */
.table th { color: var(--ipcge-texto-tenue); }

/* ══════════════════════════════════════════════════════════════════════════
   CAMBIO V16 — Donde el acento corre como CAMPO, tambien sigue al suelo
   ══════════════════════════════════════════════════════════════════════════
   Sobre --color-accent (luminancia 0,20) NINGUN color de la paleta llega a
   4,5:1 para texto de tamano de lectura. Medido:

     texto --color-bg            3,76:1
     texto --color-neutral-100   3,85:1
     texto --color-text          3,95:1
     texto blanco puro           4,20:1   <- ni el blanco alcanza
     texto negro puro            5,00:1   OK, pero esta fuera de los tokens
                                             y sobre el rojo de marca se ve mal

   Sobre --color-accent-700 el color del suelo da 6,41:1. Es la unica salida
   aritmetica, no una preferencia: el acento base no puede llevar texto chico.

   Ademas unifica el rojo del sitio. Tras V14 habia DOS: accent-700 en los
   botones y el acento base en la banda. Ahora hay uno.

   Alcance: la banda del "poster statement" (4 paginas) y el :hover de las filas
   de investigacion, que tambien pinta acento con texto del suelo (3,76:1 en sus
   4 elementos). Los cuadritos de 10 px de instituto y el borde de .tag-outline
   se quedan en el acento base: son elementos graficos y para eso 1.4.11 pide
   3:1, que cumplen.
   ══════════════════════════════════════════════════════════════════════════ */
/* El texto sobre la banda tambien necesita su token: los dos elementos chicos
   que viven ahi —el kicker de instituto y el enlace de proyectos— traen
   `color:var(--color-bg)` EN LINEA, y un atributo style le gana a cualquier
   regla. En tema oscuro --color-bg es oscuro, asi que sobre el rojo profundo
   quedaban en 1,96:1: peor que antes de V16. El token resuelve al color del
   suelo en claro y al neutro claro en oscuro. */
:root { --ipcge-banda-texto: var(--color-bg); }
:root[data-theme="dark"] { --ipcge-banda-texto: var(--color-neutral-100); }
.ipcge-banda { background: var(--color-accent-700); color: var(--ipcge-banda-texto); }
/* El .btn-ghost de la banda: sin esto, la regla de V8 lo pintaria de acento
   sobre acento (1:1). Es el mismo cuidado que V10 con el boton del menu. */
.ipcge-banda .btn-ghost { color: var(--ipcge-banda-texto); }
.ipcge-nav-links::-webkit-scrollbar { display: none; }
.ipcge-nav-links a { white-space: nowrap; }
@media (max-width: 720px) { .ipcge-footer-grid { grid-template-columns: 1fr 1fr !important; } }
@media (max-width: 480px) { .ipcge-footer-grid { grid-template-columns: 1fr !important; } }

/* ══════════════════════════════════════════════════════════════════════════
   CAMBIO V8 — El paso del acento sigue al suelo
   ══════════════════════════════════════════════════════════════════════════
   El prototipo usaba `a { color: var(--color-accent) }`, que sobre el fondo da
   3,76:1 en claro y 3,35:1 en oscuro: por debajo del 4,5:1 que WCAG 1.4.3
   exige para texto de lectura. El readme del sistema lo dice: la pareja
   acento-suelo sirve para iconos y texto grande, no para parrafos.

   OJO: --color-accent-700 es la respuesta SOLO en suelo claro (6,41:1). En
   suelo oscuro cae a 1,96:1, peor que lo que reemplaza.

   Por eso estas reglas NO nombran un escalon: usan el token semantico
   --ipcge-acento-texto, definido arriba, que ya resuelve al paso correcto en
   cada suelo. Asi hay UNA decision en lugar de una por regla y por tema, y
   estas cinco reglas dejan de estar duplicadas.

   .btn-ghost, .card-kicker y .nav a[aria-current] viven en modernist.css: se
   sobrescriben ACA, nunca editando el archivo del sistema.
   ══════════════════════════════════════════════════════════════════════════ */
/* Se excluyen los elementos que traen su PROPIO relleno y por lo tanto definen
   su propia etiqueta: los botones y el enlace de saltar al contenido.
   Dos cosas medidas, no supuestas:
     · Sin :not(.btn), `a:hover` (0,1,1) le gana a `.btn-primary` (0,1,0) y la
       etiqueta del boton del hero se pintaba del mismo accent-800 que su
       relleno: 1:1, el mismo defecto que V10 arregla en el menu. El reposo no
       lo sufria, porque `a` solo es (0,0,1) y cualquier clase le gana.
     · Cuidado con el :not(): SUBE la especificidad a (0,1,1). Al agregarlo,
       esta regla empezo a ganarle a `.ipcge-saltar` (0,1,0) y dejo ese enlace
       en 1:1. Por eso va excluido tambien, en lugar de subirle la
       especificidad a el: asi la intencion queda escrita y no depende del
       orden de las reglas. */
a:not(.btn):not(.ipcge-saltar) { color: var(--ipcge-acento-texto); }
a:not(.btn):not(.ipcge-saltar):hover { color: var(--ipcge-acento-texto-fuerte); }

/* ⚠️ CUARTA VEZ QUE MUERDE LA TRAMPA DEL :not(), y la segunda por mano propia.
   La regla de arriba quedo en (0,2,1) por los dos :not(), y con eso le gana a
   `.nav a { color: inherit }` de modernist.css, que es (0,1,1). Resultado medido
   en el sitio PUBLICADO: 6 de los 7 enlaces del menu pasaron a acento cuando
   deben ser tinta. El acento marca SOLO la pagina actual.

   No lo atrapo nada: el barrido de contraste solo informa lo que FALLA y
   accent-700 sobre la superficie da 5,91:1, que pasa; y la prueba de fidelidad
   compara texto, no color. De ahi scripts/comparar-enlaces.mjs.

   Se restituye la intencion de forma explicita, como manda la regla de la casa:
   excluir en el selector en vez de confiar en el orden. (0,3,1) gana sin ambiguedad. */
.nav .ipcge-nav-links a:not([aria-current]) { color: inherit; }
.card-kicker { color: var(--ipcge-acento-texto); }
.btn-ghost { color: var(--ipcge-acento-texto); }
.nav a:hover, .nav a[aria-current="page"] { color: var(--ipcge-acento-texto); }

/* V15, pieza 2: .tag-outline usa el acento base para su texto de 11 px, y eso
   da 3,76:1 en claro y 3,35:1 en oscuro. Son 7 etiquetas, en actualidad y en
   proyectos. El BORDE se queda en el acento a proposito: es un elemento
   grafico, y para eso el 3:1 de 1.4.11 alcanza. Solo cambia el texto. */
.tag-outline { color: var(--ipcge-acento-texto); }

/* V15, pieza 3: el .seg-opt marcado usa relleno de acento con la etiqueta en
   color del suelo: 3,76:1 a 13 px. Es el mismo par que V14 corrigio en los
   botones, asi que se resuelve igual, con el paso profundo del acento. */
.seg-opt:has(input:checked) { background: var(--color-accent-700); color: var(--color-bg); }
:root[data-theme="dark"] .seg-opt:has(input:checked) { color: var(--color-neutral-100); }

/* ══════════════════════════════════════════════════════════════════════════
   CAMBIO V10 — La etiqueta del boton primario se lee como el suelo
   ══════════════════════════════════════════════════════════════════════════
   `.nav a { color: inherit }` (especificidad 0,1,1) le ganaba a
   `.btn-primary { color: var(--color-bg) }` (0,1,0), asi que el boton
   "Contacto" del menu quedaba en tinta sobre rojo: 3,95:1 en claro, 3,85:1 en
   oscuro. Y con aria-current o con el puntero encima, `.nav a[aria-current]` y
   `.nav a:hover` lo pintaban de acento SOBRE acento: 1:1, un rectangulo rojo
   sin texto en /contacto/.

   Tres estados, el mismo defecto. Se cubren los tres con selectores mas
   especificos (0,3,1) para que no dependa del orden de los archivos.

   ⚠️ Estas reglas declaran SOLO `color`, nunca `background`. Cuando llegue V14
   con el relleno, mezclar las dos cosas aca haria que estos selectores (0,4,1)
   le ganaran a `.btn-primary:hover` (0,1,0) tambien para el fondo, y el boton
   del menu se quedaria sin realimentacion al pasar el puntero. Medido: paso.
   ══════════════════════════════════════════════════════════════════════════ */
.nav a.btn-primary,
.nav a.btn-primary:hover,
.nav a.btn-primary[aria-current="page"] { color: var(--color-bg); }
:root[data-theme="dark"] .nav a.btn-primary,
:root[data-theme="dark"] .nav a.btn-primary:hover,
:root[data-theme="dark"] .nav a.btn-primary[aria-current="page"] { color: var(--color-neutral-100); }

/* ══════════════════════════════════════════════════════════════════════════
   CAMBIO V14 — El relleno del boton primario tambien sigue al suelo
   ══════════════════════════════════════════════════════════════════════════
   V10 arreglo la cascada y el contraste SEGUIA fallando: 3,76:1 en claro y
   3,35:1 en oscuro. El motivo es que la pareja del sistema —etiqueta en color
   del suelo sobre relleno de acento base— vale 3,76:1, y la etiqueta mide
   14 px, asi que exige 4,5:1. No hay arreglo posible desde la cascada: hay que
   cambiar el relleno.

   Afecta a TODOS los botones primarios del sitio (los del hero, el del menu y
   el de enviar el formulario). Es el cambio mas visible del proyecto: toca el
   color de accion en las 12 paginas. Julio eligio esta opcion sobre arreglar
   solo el boton del menu, para no dejarlo de un rojo distinto al de los
   botones del hero en la misma pantalla.

   EN TEMA OSCURO hay un detalle que no se puede pasar por alto: ahi
   `--color-bg` es oscuro, asi que `.btn-primary { color: var(--color-bg) }`
   pinta la etiqueta de OSCURO. Sobre un relleno rojo profundo seria ilegible.
   Por eso en oscuro la etiqueta pasa a --color-neutral-100 y el relleno se
   queda en accent-700: el boton sigue leyendose como un boton rojo en los dos
   temas, en vez de volverse rosa palido.

   La direccion del hover es "mas contraste", no "mas claro": el readme del
   sistema dice accent-400 en suelo oscuro, pero eso vale cuando el acento es
   el TEXTO. Aca el acento es el relleno detras de una etiqueta clara, asi que
   oscurecer es lo que aumenta el contraste. Los seis estados estan medidos.
   ══════════════════════════════════════════════════════════════════════════ */
/* Relleno: identico en los dos temas, para que el boton siga leyendose como un
   boton rojo y no como uno rosa palido en oscuro. */
.btn-primary { background: var(--color-accent-700); }
.btn-primary:hover { background: var(--color-accent-800); }
.btn-primary:active { background: var(--color-accent-900); }

/* Etiqueta: en claro el color del suelo; en oscuro el suelo ES oscuro, asi que
   hay que forzar el paso claro del neutro o la etiqueta seria ilegible. */
.btn-primary { color: var(--color-bg); }
:root[data-theme="dark"] .btn-primary { color: var(--color-neutral-100); }

/* ---- Especificas por pagina: calificadas para no pisarse entre si ----
   .ipcge-4col se comporta distinto en instituto (1fr) que en servicios y
   transparencia (1fr 1fr). Sin calificar, la ultima regla ganaria para todas. */
/* El plan decia que este margen "existia solo en index". FALSO, medido: esta en
   index Y en instituto. Se detecto porque la pagina construida salia 24 px mas
   baja que el prototipo, con todas las secciones, el nav y el pie identicos al
   pixel. La prueba de fidelidad compara texto, no geometria, asi que no lo veia:
   para eso esta scripts/comparar-geometria.mjs. */
/* Tercera aparicion del margen (2026-07-31): el prototipo de la pagina nueva
   tambien lo traia en linea. El plan original decia "solo en index"; eran tres.

   ⚠️ V34 (2026-08-02) SACA A ciencias-geoespaciales DE ESTA REGLA. Ahi el
   margen dejaba 24 px de fondo entre la banda roja del cierre —que es a
   sangre— y la linea del pie, una franja flotando. Medido, era la unica
   pagina inconsistente: de las TRES que terminan en banda, `proyectos` y
   `servicios` ya daban hueco 0 porque sus prototipos no traen ese margen. La
   diferencia venia del material de origen, no de una decision de diseno.

   La portada e `instituto` LO CONSERVAN: ahi lo ultimo es contenido normal
   sobre el fondo de la pagina y esos 24 px son el respiro antes del pie. El
   margen solo estorba cuando lo que termina es una banda a sangre. */
.pag-inicio footer, .pag-instituto footer { margin-top: 24px; }
@media (max-width: 720px) {
  .pag-inicio .ipcge-cards { grid-template-columns: 1fr !important; }
  .pag-inicio .ipcge-split { grid-template-columns: 1fr !important; }
  .pag-instituto .ipcge-3col, .pag-instituto .ipcge-4col { grid-template-columns: 1fr !important; }
  .pag-instituto .ipcge-feature { grid-template-columns: 1fr !important; }
  .pag-proyectos .ipcge-vtol-feat { grid-template-columns: 1fr !important; }
  .pag-investigacion .ipcge-2col { grid-template-columns: 1fr !important; }
  .pag-investigacion .ipcge-feature { grid-template-columns: 1fr !important; }
  .pag-formacion .ipcge-3col { grid-template-columns: 1fr !important; }
  /* Se quitaron .pag-servicios .ipcge-2col y .ipcge-4col: eran reglas MUERTAS.
     El prototipo de servicios las declaraba en su <style> pero su HTML no usa
     ninguna de las dos, solo .ipcge-proj. La "trampa del CSS" de este plan es
     real entre instituto y transparencia, no entre tres paginas. */
  .pag-transparencia .ipcge-4col { grid-template-columns: 1fr 1fr !important; }
}
@media (max-width: 900px) { .pag-contacto .ipcge-form-grid { grid-template-columns: 1fr !important; } }
@media (max-width: 640px) {
  .pag-contacto .ipcge-field-row { grid-template-columns: 1fr !important; }
  .pag-reclamaciones .ipcge-field-row { grid-template-columns: 1fr !important; }
}
@media (max-width: 560px) { .pag-actualidad .ipcge-article { grid-template-columns: 1fr !important; } }
/* ══════════════════════════════════════════════════════════════════════════
   CAMBIO V3 — Los 6 bloques que nunca tuvieron imagen
   ══════════════════════════════════════════════════════════════════════════
   Las 6 figuras de contenido (home-photo, las 4 de Proyectos y serv-gnss) no
   tenian archivo: eran marcos vacios con un texto de indicacion. Se quito el
   <figure> y su rejilla de dos columnas pasa a UNA, para no dejar la mitad del
   ancho en blanco.

   La "regla de 2 px" del cambio ya existe: estos bloques estan delimitados por
   los <hr class="hr"> del diseno aprobado. V3 dice conservarla, no agregar otra.

   Va con !important porque las columnas estan en un atributo style en linea, y
   es el mismo patron que ya usan las reglas de arriba. Calificado por pagina,
   como manda la trampa del CSS.

   Cuando exista material real del IPCGE, la figura vuelve con el tratamiento de
   §4.1 y estas cuatro reglas se quitan.
   ══════════════════════════════════════════════════════════════════════════ */
.pag-inicio .ipcge-split { grid-template-columns: 1fr !important; }
.pag-servicios .ipcge-proj { grid-template-columns: 1fr !important; }

/* ⚠️ `proyectos` SALIO DE V3 EL 2026-07-30, POR DECISION DE JULIO.
   Sus 4 marcos vuelven vacios, tal como el diseño aprobado, y las fotos reales
   se colocaran despues. Julio lo pidio sabiendo que hoy son rectangulos grises:
   se le midio y se le mostro que las figuras del prototipo son `image-slot` sin
   archivo, o sea descripciones de una foto que nunca se produjo.

   Al volver la figura, la rejilla de dos columnas vuelve a tener sentido —y con
   ella el canal de 32px del texto, que es lo que lo separa de la imagen—. Por eso
   NO se anula ese padding: el desnivel alternado que se veia era consecuencia de
   haber quitado la imagen y dejar el canal, no un defecto del canal.

   `inicio` y `servicios` siguen en V3: sus figuras tampoco tienen archivo, y ahi
   no se pidio revertir. Verificado que no tienen canales de 32px sueltos. */
@media (max-width: 720px) {
  /* Del prototipo aprobado, linea 21. En una columna, la figura del bloque 1 sube
     arriba del texto. ⚠️ Los bloques 2 y 4 ya la tienen arriba porque en el codigo
     la figura va PRIMERO; el 3 la deja abajo, y eso es lo aprobado. */
  .pag-proyectos .ipcge-proj { grid-template-columns: 1fr !important; }
  .pag-proyectos .ipcge-proj-img { order: -1; }
}

.pag-proyectos { scroll-behavior: smooth; }
.pag-investigacion .ipcge-inv-row { transition: background .15s, color .15s; }
/* V16: el hover pintaba acento base con texto del suelo, 3,76:1 en sus 4
   elementos. Pasa al mismo paso profundo que la banda y los botones. */
.pag-investigacion .ipcge-inv-row:hover { background: var(--color-accent-700); }
.pag-investigacion .ipcge-inv-row:hover * { color: var(--color-bg) !important; }
/* ⚠️ SIN espacio entre :root[...] y .pag-: son EL MISMO elemento (la trampa de
   CLAUDE.md §6). Con espacio, esta regla estuvo MUERTA hasta el 2026-07-31 y el
   hover en oscuro quedaba con el texto en --color-bg sobre rojo profundo. */
:root[data-theme="dark"].pag-investigacion .ipcge-inv-row:hover * { color: var(--color-neutral-100) !important; }

/* ══════════════════════════════════════════════════════════════════════════
   /ciencias-geoespaciales/ — la 13.ª pagina (V20-V21, aprobada el 2026-07-31)
   ══════════════════════════════════════════════════════════════════════════
   Todo lo demas de la pagina REUTILIZA lo ya existente: .ipcge-banda (V16),
   .ipcge-hero-velo (V9), los tokens --ipcge-acento-texto y --ipcge-texto-tenue,
   .ipcge-marco (patron de proyectos, commit 8091d05), card/tag/btn/hr del
   sistema. Aca vive SOLO lo que la pagina tiene y ninguna otra: sus rejillas
   de 5 columnas y el hover de las celdas de preguntas.

   Los cortes son los del prototipo (900 y 720), igual que contacto conserva su
   900 y actualidad su 560: la geometria especifica de cada pagina respeta los
   cortes con los que fue disenada. El !important es contra el style en linea
   del marcado aprobado, el mismo patron de todas las reglas de arriba.

   Del <style> del prototipo NO se portaron: `a { color: var(--color-accent) }`
   (V8 ya resuelve los enlaces con el paso segun el suelo), el tema oscuro y
   .ipcge-nav-links (ya globales), y las reglas de .ipcge-disc y .ipcge-cards
   (MUERTAS: su HTML no las usa — el mismo caso que las de servicios en V17). */

/* V24 (2026-07-31) vivia aca: los 3 botones del cierre median 37 px, bajo la
   convencion de 44 del §7. ABSORBIDO POR V36 (final del archivo), que puso el
   minimo en `.btn` y volvio innecesaria esta regla calificada. */

/* V26 (2026-07-31, pedido de Julio sobre el sitio publicado): las lineas del
   flujo «Del dato al territorio». El diseno traia border-right en las 4 celdas
   con gap:0: cada linea quedaba PEGADA al texto de la columna siguiente y la
   4.a era una linea suelta en el extremo derecho. Ahora son 3 (`div + div`
   excluye a la primera sin subirle la especificidad a nadie) y van CENTRADAS
   en el canal de 28 px: absolutas, asi que no tocan ni el flujo del texto ni
   las alturas — la paridad geometrica con el prototipo se mantiene en 0. */
/* ⚠️ V32 (2026-08-02) REEMPLAZA EL MODELO DE V26, no lo retoca. Las lineas
   dejan de SEPARAR columnas y pasan a MARCAR cada paso: las cuatro celdas
   llevan la suya a la izquierda, incluida la primera. Julio lo pidio asi y
   eligio esta variante entre tres.

   ⚠️ LA LINEA DE LA CELDA 1 VA EN EL EJE DEL SITIO, NO A -15 px. Medido a
   1440: el h1, el rotulo de la banda, los h2 de todas las secciones y la
   celda 1 estan TODOS en x=192. Una linea a -15 px caeria en x=177 y seria
   el unico elemento de la pagina fuera de ese eje — el sistema Modernist se
   sostiene sobre esa alineacion. Por eso el riel se apoya en x=192 y es el
   TEXTO el que se corre.

   Consecuencia: las cuatro celdas ganan 15 px de relleno izquierdo, asi que
   los cuatro rieles quedan a la MISMA distancia de su texto (15 px). Sin eso,
   la celda 1 tendria su linea a 28 px del texto y las otras a 15: consistencia
   aparente, no real. El !important es contra el `padding:0 28px 0 0` en linea
   del prototipo, el unico caso donde la casa lo admite.

   En 2 columnas las cuatro conservan su riel —con el modelo nuevo la celda que
   abre fila tambien es un paso—, y en una sola columna no hay riel ni sangria:
   apilados, los pasos ya se leen como lista. */
.pag-ciencias-geoespaciales .ipcge-flow > div { position: relative; padding-left: 15px !important; }
.pag-ciencias-geoespaciales .ipcge-flow > div::before {
  content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 2px;
  background: color-mix(in srgb, var(--ipcge-banda-texto) 35%, transparent);
}
@media (max-width: 900px) {
  /* Al envolverse en filas, el `gap:0` en linea las deja PEGADAS: el ultimo
     renglon de un paso toca la etiqueta del siguiente. En 4 columnas hay una
     sola fila y no se nota; medido en tablet y movil, si. Y con los rieles de
     V32 era peor: los de 01 y 03 se fundian en uno solo y los dos pasos se
     leian como un bloque. Un canal de 32 px devuelve cuatro pasos distintos.
     Solo el canal de FILAS: entre columnas sigue en 0, que es donde viven los
     rieles. */
  .pag-ciencias-geoespaciales .ipcge-flow { row-gap: 32px !important; }
}
@media (max-width: 720px) {
  /* Apilados no hay nada que marcar: sin riel, y sin la sangria que lo
     acompana (dejarla sola indentaria el texto contra ningun riel). */
  .pag-ciencias-geoespaciales .ipcge-flow > div { padding-left: 0 !important; }
  .pag-ciencias-geoespaciales .ipcge-flow > div::before { content: none; }
}

/* V27 (2026-07-31): los iconos de las 5 preguntas y el rollover explicativo.

   El display:block del svg es la leccion de `.btn svg` del sistema: un SVG en
   linea deja un canal de linea de base abajo y el icono no queda donde uno
   cree. Declarado aca, calificado, y no confiando en herencias.

   Los 6 parrafos (Naciones Unidas + 5 explicaciones) se apilan en la MISMA
   celda de una rejilla de 1x1: el bloque mide siempre como el mas alto y el
   intercambio no mueve nada de lo que hay debajo. Con el puntero sobre la
   pregunta N, la explicacion N reemplaza al parrafo base. `:has()` tiene
   soporte MAS VIEJO que el color-mix() que este sitio usa en todas partes; si
   un navegador no lo entiende, se queda el parrafo base — nada se rompe.
   En tactil no hay puntero: se ve el parrafo base, y las 5 explicaciones
   siguen en el HTML para lectores de pantalla y rastreadores (§7). */
.pag-ciencias-geoespaciales .ipcge-qa-mark svg { display: block; }
.pag-ciencias-geoespaciales .ipcge-qa-expl { display: grid; }
.pag-ciencias-geoespaciales .ipcge-qa-expl > p { grid-area: 1 / 1; transition: opacity 0.15s; }
.pag-ciencias-geoespaciales .ipcge-qa-expl > .ipcge-qa-expl-item { opacity: 0; }
.pag-ciencias-geoespaciales .ipcge-qa-grid:has(.ipcge-qa:hover) + .ipcge-qa-expl > .ipcge-qa-expl-base { opacity: 0; }
.pag-ciencias-geoespaciales .ipcge-qa-grid:has(.ipcge-qa:nth-child(1):hover) + .ipcge-qa-expl > .ipcge-qa-expl-item:nth-child(2) { opacity: 1; }
.pag-ciencias-geoespaciales .ipcge-qa-grid:has(.ipcge-qa:nth-child(2):hover) + .ipcge-qa-expl > .ipcge-qa-expl-item:nth-child(3) { opacity: 1; }
.pag-ciencias-geoespaciales .ipcge-qa-grid:has(.ipcge-qa:nth-child(3):hover) + .ipcge-qa-expl > .ipcge-qa-expl-item:nth-child(4) { opacity: 1; }
.pag-ciencias-geoespaciales .ipcge-qa-grid:has(.ipcge-qa:nth-child(4):hover) + .ipcge-qa-expl > .ipcge-qa-expl-item:nth-child(5) { opacity: 1; }
.pag-ciencias-geoespaciales .ipcge-qa-grid:has(.ipcge-qa:nth-child(5):hover) + .ipcge-qa-expl > .ipcge-qa-expl-item:nth-child(6) { opacity: 1; }

/* El hover de las celdas de preguntas pintaba acento BASE con texto del suelo:
   3,76:1. Tratamiento V16, identico a las filas de investigacion de arriba. */
.pag-ciencias-geoespaciales .ipcge-qa:hover { background: var(--color-accent-700); }
.pag-ciencias-geoespaciales .ipcge-qa:hover * { color: var(--color-bg) !important; }
:root[data-theme="dark"].pag-ciencias-geoespaciales .ipcge-qa:hover * { color: var(--color-neutral-100) !important; }

/* V23 (2026-07-31) vivia aca: los 3 botones del hero de la portada median 35 px,
   bajo la convencion de 44 del §7. Estaba calificada al hero para NO alcanzar al
   boton de la tarjeta GNSS ni al «Contacto» del menu — que era justamente el
   problema: esos tambien median 35. ABSORBIDO POR V36 (final del archivo). */

@media (max-width: 900px) {
  .pag-ciencias-geoespaciales .ipcge-flow,
  .pag-ciencias-geoespaciales .ipcge-sectors,
  .pag-ciencias-geoespaciales .ipcge-taxo { grid-template-columns: 1fr 1fr !important; }
  .pag-ciencias-geoespaciales .ipcge-qa-grid { grid-template-columns: 1fr !important; }
}
@media (max-width: 720px) {
  .pag-ciencias-geoespaciales .ipcge-split { grid-template-columns: 1fr !important; }
  .pag-ciencias-geoespaciales .ipcge-flow,
  .pag-ciencias-geoespaciales .ipcge-sectors,
  .pag-ciencias-geoespaciales .ipcge-taxo { grid-template-columns: 1fr !important; }
}

/* ══════════════════════════════════════════════════════════════════════════
   CAMBIO V12 — El pie: rotulos legibles y objetivos tactiles
   ══════════════════════════════════════════════════════════════════════════
   Los rotulos de columna (11 px) y el copyright (12 px) estaban en
   `--color-text` al 55 %, que da 3,65:1 en claro. Suben al 65 %, el mismo paso
   que ya usaba el parrafo del pie: 4,94:1 en claro y 6,37:1 en oscuro.

   Los enlaces del pie median 192x20 px. V1 le da 44 px de alto a los del menu
   en movil y el pie no lo arreglaba nadie; aca reciben el mismo trato, solo
   bajo el breakpoint donde se navega con el dedo.

   Estas tres reglas venian en `style` en linea dentro del partial. Se pasaron a
   clases porque un atributo `style` no puede llevar media queries, y de paso el
   pie deja de repetir la misma declaracion tres veces. El resultado visual es
   identico salvo el 55 % -> 65 % que es el cambio autorizado.
   ══════════════════════════════════════════════════════════════════════════ */
.ipcge-pie-rotulo {
  display: block; font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase;
  color: color-mix(in srgb, var(--color-text) 65%, transparent); margin-bottom: 10px;
}
.ipcge-pie-enlaces { display: flex; flex-direction: column; gap: 8px; font-size: 13px; }
.ipcge-pie-copyright {
  max-width: 1200px; margin: 0 auto; padding: 0 clamp(20px, 5vw, 72px) 32px;
  font-size: 12px; color: color-mix(in srgb, var(--color-text) 65%, transparent);
}
@media (max-width: 1023px) {
  .ipcge-pie-enlaces { gap: 0; }
  .ipcge-pie-enlaces a { min-height: 44px; display: flex; align-items: center; }
}

/* ---- Saltar al contenido (accesibilidad) ----
   El relleno es accent-700 y no el acento base: con el acento base, la etiqueta
   en color del suelo daria 3,76:1 a 14 px, por debajo de 4,5:1. Con accent-700
   da 6,42:1. Es codigo nuevo de este proyecto, asi que se escribe cumpliendo
   desde el principio en vez de heredar el problema. */
.ipcge-saltar { position: absolute; left: -9999px; top: 0; z-index: 100; background: var(--color-accent-700); color: var(--color-bg); padding: 10px 16px; font-size: 14px; }
.ipcge-saltar:focus { left: 0; color: var(--color-bg); }
:root[data-theme="dark"] .ipcge-saltar { background: var(--color-accent-300); color: var(--color-neutral-900); }

/* ---- Menu movil (cambio V1) e iconos del boton de tema ----
   ⚠️ TRAMPA: modernist.css trae `.btn svg { display: block }`, con
   especificidad (0,1,1). Una clase sola como `.ipcge-icono-sol` es (0,1,0) y
   PIERDE, asi que el icono que se queria ocultar se sigue viendo. Medido: con
   selectores de una clase, en tema claro se veian el sol y la luna a la vez, y
   el boton de menu mostraba la hamburguesa y la X juntas.

   Por eso todas las reglas de iconos van calificadas con `.btn svg` (0,2,1):
   le ganan al sistema sin depender del orden de los archivos y sin !important.

   Es el mismo patron que obligo a V10: un selector descendiente del sistema le
   gana a una clase propia. En este proyecto ya aparecio tres veces. */
.ipcge-menu-btn { display: none; }
.btn svg.ipcge-icono-cerrar { display: none; }
.ipcge-menu-btn[aria-expanded="true"] svg.ipcge-icono-abrir { display: none; }
.ipcge-menu-btn[aria-expanded="true"] svg.ipcge-icono-cerrar { display: block; }
.btn svg.ipcge-icono-sol { display: none; }
.btn svg.ipcge-icono-luna { display: block; }
:root[data-theme="dark"] .btn svg.ipcge-icono-sol { display: block; }
:root[data-theme="dark"] .btn svg.ipcge-icono-luna { display: none; }

@media (max-width: 1023px) {
  .ipcge-menu-btn { display: inline-flex; min-width: 44px; min-height: 44px; align-items: center; justify-content: center; }
  .nav { position: relative; flex-wrap: wrap; }
  .ipcge-nav-links {
    display: none !important; position: absolute; top: 100%; left: 0; right: 0;
    background: var(--color-surface); border-top: 2px solid var(--color-divider);
    flex-direction: column !important; align-items: stretch !important;
    gap: 0 !important; margin: 0 !important; overflow: visible !important; z-index: 50;
  }
  .ipcge-nav-links[data-abierto] { display: flex !important; }
  .ipcge-nav-links a {
    padding: 14px clamp(20px, 5vw, 72px); min-height: 44px; display: flex; align-items: center;
    border-bottom: 1px solid var(--color-divider); font-size: 15px;
  }
}

/* ---- Escalon de tablet (cambio V2): las rejillas de 4 pasan a 2, no a 1 ---- */
@media (min-width: 641px) and (max-width: 1023px) {
  .ipcge-cards { grid-template-columns: 1fr 1fr !important; }
  .pag-instituto .ipcge-4col { grid-template-columns: 1fr 1fr !important; }
  /* V17: transparencia tenia su propia regla solo hasta 720 px y V2 no la
     incluia, asi que entre 721 y 1023 px saltaba a 4 columnas. Medido:
     2 -> 2 -> 4 -> 4 a 600/700/800/1000 px. Es justo el apretujamiento que V2
     vino a resolver. */
  .pag-transparencia .ipcge-4col { grid-template-columns: 1fr 1fr !important; }
}

/* ══════════════════════════════════════════════════════════════════════════
   CAMBIO V11 — Los 8 radios como grupo real
   ══════════════════════════════════════════════════════════════════════════
   El rotulo "Tipo de consulta" era un <span> suelto: un lector de pantalla
   anunciaba ocho opciones sin decir de que grupo eran (WCAG 1.3.1 y 3.3.2).
   Pasa a <fieldset> + <legend>.

   El <fieldset> y el <legend> traen estilos propios del navegador —borde,
   relleno, y el legend recorta el borde superior—, asi que hay que anularlos
   TODOS para que el resultado sea identico al <span> que reemplaza. El legend
   copia exactamente las declaraciones que tenia ese span.

   Delta visual cero, verificado con comparar-geometria.mjs.
   ══════════════════════════════════════════════════════════════════════════ */
.ipcge-tipo-consulta { border: 0; padding: 0; margin: 0; min-width: 0; }
.ipcge-tipo-consulta > legend {
  display: block; padding: 0; margin-bottom: 14px; float: none; width: auto;
  font-size: 13px; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--ipcge-acento-texto);
}

/* Campo senuelo del anti-spam: fuera de la pantalla, nunca oculto con
   display:none. Un robot que ignora el CSS lo ve y lo llena; ocultarlo con
   display:none haria que algunos ni lo envien, y el senuelo dejaria de servir. */
.ipcge-senuelo { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* Aviso de error del formulario. Usa el token del acento, no el acento base:
   es texto de 13 px y el acento base daria 3,76:1. */
.ipcge-error {
  margin: 6px 0 0; font-size: 13px; line-height: 1.5;
  color: var(--ipcge-acento-texto);
}
.input[aria-invalid="true"] { border-color: var(--ipcge-acento-texto); }

/* ---- Imagenes de hero: <img> real en lugar de <image-slot> (cambio V4) ---- */
.ipcge-hero-img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* ══════════════════════════════════════════════════════════════════════════
   CAMBIO V9 — El velo del hero, para que el texto no se apoye en la ilustracion
   ══════════════════════════════════════════════════════════════════════════
   El degradado era IDENTICO en las 12 paginas (verificado con grep), asi que
   vive aca una sola vez en lugar de repetido pagina por pagina.

   El original iba de 10 % de suelo arriba a 92 % al 80 % de la altura. En tema
   claro eso deja el texto —que esta en el primer 20 % del hero— apoyado sobre
   la parte MAS oscura del velo, o sea casi la ilustracion cruda. Medido: el
   kicker quedaba en 1,11:1 y el h1 de la portada en 2,86:1.

   EL VELO SOLO CAMBIA EN SUELO CLARO, y eso importa. Medido en el navegador,
   probando nueve valores de tope en los dos temas:

     tope   kicker en claro   kicker en oscuro
      10%       1,11:1            2,11:1     <- el prototipo
      45%       2,43:1            2,05:1
      70%       3,86:1            2,02:1
      80%       4,56:1  OK        2,02:1
      85%       4,94:1            2,00:1

   En oscuro subir el velo lo EMPEORA, porque el velo es el suelo oscuro y el
   kicker era rojo oscuro: mas velo = fondo mas oscuro. No hay valor que sirva.
   Eso lo resuelve el token semantico de arriba, no el velo: con el token el
   kicker en oscuro pasa a 9,72:1 con el velo original de 10 %.

   Asi que en oscuro el velo se queda en 10 % y la ilustracion se ve completa;
   en claro sube a 80 %, el minimo medido que hace pasar el kicker de 13 px.
   Es la misma regla que el acento: el velo tambien sigue al suelo.

   COSTO, dicho sin adornos: en tema claro la ilustracion pasa de dibujo a
   textura tenue. El texto ocupa del 17 % al 90 % del hero —medido—, asi que no
   existe una banda libre donde poner el texto y dejar la ilustracion visible:
   son incompatibles en el mismo espacio. Se eligio la legibilidad.
   ══════════════════════════════════════════════════════════════════════════ */
:root { --ipcge-velo-tope: 80%; }
:root[data-theme="dark"] { --ipcge-velo-tope: 10%; }
.ipcge-hero-velo {
  position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--color-bg) var(--ipcge-velo-tope), transparent) 0%,
    color-mix(in srgb, var(--color-bg) 92%, transparent) 80%);
}

/* ══════════════════════════════════════════════════════════════════════════
   V19 · «PROYECTOS» — los cuatro accesos del hero pasan a ser botones de verdad
   Aprobado por Julio el 2026-07-30.

   QUE PASABA. Los cuatro enlaces a los proyectos fundacionales eran
   `.tag .tag-outline`: sin relleno, peso 400, 11 px y 25 px de alto. Medido en el
   sitio publicado, el `:hover` solo oscurecia el texto de #ae1800 a #7c1405 —un
   cambio que casi no se ve— y en tema oscuro el conjunto se desvanecia.

   Dos motivos, y el segundo no es de gusto:
     · No se leian como clickeables, siendo la navegacion principal de la pagina.
     · 25 px de alto INCUMPLE la convencion del propio proyecto (CLAUDE.md §7):
       «objetivos tactiles >= 44x44 px». Con el relleno nuevo llegan a 44.

   ⚠️ VA CALIFICADO A LOS ENLACES, Y NO A LA CLASE. `.tag-outline` la usan tambien
   3 elementos de `/actualidad/`, pero ahi son <span>: ETIQUETAS QUE NO SE PUEDEN
   CLICKEAR. Pintarlas de rojo las haria parecer botones que no llevan a ningun
   lado. Por eso el selector empieza en `.pag-proyectos a`.

   ⚠️ Y VA CALIFICADO DE MAS, POR LA TRAMPA QUE YA MORDIO CUATRO VECES:

       a:not(.btn):not(.ipcge-saltar)      (0,2,1)   <- ya existe, mas arriba
       a.tag-outline                       (0,1,1)   <- perderia
       .pag-proyectos a.tag.tag-outline    (0,3,1)   <- gana, y sin tocar nada

   Sin el tercer nivel, la regla de arriba pintaria la etiqueta del MISMO rojo que
   el relleno: rectangulos rojos sin texto, 1:1. Es el defecto exacto que aparecio
   en el boton del hero, en el menu, en el enlace de saltar y en la banda. Se
   resuelve calificando esta regla, NO agregandole otro `:not()` a la de arriba:
   un `:not()` sube la especificidad y arrastra cosas que nadie estaba mirando.

   COLORES: los mismos de `.btn-primary`, ya medidos en V14 — reposo 6,41:1,
   con el puntero 9,59:1, apretado 13,01:1. No se inventa ninguna pareja nueva.
   Sobre el acento BASE ni el blanco puro llega a 4,5:1 (da 4,20:1), por eso el
   relleno es `accent-700` y no el rojo vivo.
   ══════════════════════════════════════════════════════════════════════════ */
.pag-proyectos a.tag.tag-outline {
  background: var(--color-accent-700);
  border-color: var(--color-accent-700);

  /* ⚠️ TIPOGRAFIA DE BOTON, TOMADA DEL SISTEMA — no son numeros elegidos a ojo.
     `.btn` de modernist.css define que un boton es 14px, peso de titular y sin
     subrayado. Estos LLEVAN A LOS CUATRO PROYECTOS FUNDACIONALES, asi que tienen
     que leerse como botones y no como etiquetas.

     El subrayado era un defecto: es el que traen los enlaces por omision, y la
     clase `.tag` nunca lo quito porque las etiquetas NUNCA HABIAN SIDO ENLACES.
     Aca es la primera vez que un `.tag` es un `<a>`, y el defecto salio con el. */
  font-family: var(--font-heading);
  font-size: 14px;
  font-weight: var(--font-heading-weight);
  line-height: 1.2;
  text-decoration: none;

  padding: 12px 18px;
  /* ⚠️ EL RELLENO SOLO NO ALCANZA: con 14px de letra da 12+16,8+12 y 2 de borde,
     o sea 42,8 px. Se fija el piso a mano en lugar de calcularlo desde la
     interlinea, que cambia si algun dia cambia la fuente. */
  min-height: 44px;
}
.pag-proyectos a.tag.tag-outline:hover,
.pag-proyectos a.tag.tag-outline:focus-visible {
  background: var(--color-accent-800);
  border-color: var(--color-accent-800);
}
.pag-proyectos a.tag.tag-outline:active {
  background: var(--color-accent-900);
  border-color: var(--color-accent-900);
}

/* La etiqueta sigue al suelo, como en V14: en claro el color del fondo; en oscuro
   `--color-bg` ES oscuro, asi que ahi seria tinta sobre rojo.

   ⚠️ SIN ESPACIO ENTRE `:root[data-theme]` Y `.pag-proyectos`, Y ESTO YA FALLO.
   La construccion estampa la clave de la pagina en el <html>, o sea EN EL MISMO
   elemento que `:root`. Escrito con espacio —`:root[data-theme="dark"]
   .pag-proyectos`— el selector pide un `.pag-proyectos` DENTRO de `:root`, que no
   existe: la regla no le pega a nada y no se queja. Medido antes de corregirlo:
   la etiqueta quedaba en `--color-bg` oscuro sobre el rojo, 1,96:1 en reposo y
   1,31:1 con el puntero. Van pegados porque son el mismo elemento. */
.pag-proyectos a.tag.tag-outline,
.pag-proyectos a.tag.tag-outline:hover,
.pag-proyectos a.tag.tag-outline:focus-visible,
.pag-proyectos a.tag.tag-outline:active { color: var(--color-bg); }
:root[data-theme="dark"].pag-proyectos a.tag.tag-outline,
:root[data-theme="dark"].pag-proyectos a.tag.tag-outline:hover,
:root[data-theme="dark"].pag-proyectos a.tag.tag-outline:focus-visible,
:root[data-theme="dark"].pag-proyectos a.tag.tag-outline:active { color: var(--color-neutral-100); }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; scroll-behavior: auto !important; }
}

/* V30: los datos registrales de /transparencia/. Tres columnas en escritorio,
   una en movil — el corte de 640 es la convencion del §7. Calificado por
   pagina, como manda la trampa del CSS. */
@media (max-width: 640px) {
  .pag-transparencia .ipcge-registro { grid-template-columns: 1fr !important; }
}

/* ══════════════════════════════════════════════════════════════════════════
   V31 — Las etiquetas de /ciencias-geoespaciales/ son CONTENIDO, no metadato
   ══════════════════════════════════════════════════════════════════════════
   `.tag` es el componente de METADATO del sistema: la anotacion chica y
   callada que dice «Institucional» al lado de una noticia. Ahi 11-13 px esta
   bien, porque etiqueta algo. Pero en esta pagina las 37 etiquetas SON la
   enumeracion que cada seccion entrega —las 11 tecnologias, las 14 entidades,
   los 8 retos, los 12 usos cotidianos—, y quedaban en 13,5 px debajo de un
   cuerpo de 16 y un titular de 32: la jerarquia visual iba al reves del
   significado. De las 67 etiquetas del sitio, 37 estan aca.

   Tres palancas, no una: tamano (16 px, IGUAL que el cuerpo de texto, que es
   el mensaje correcto — esto es contenido, leelo), peso (600) y respiracion
   (8/14 px). El recuadro pasa de 29 a 43 px de alto: +48 %.

   ⚠️ SE DESCARTARON LOS 20 px que se propusieron primero. Medido en maqueta: a
   ese tamano los recuadros se leen como BOTONES y prometen un clic que no
   existe —son <span>, no enlaces—, ademas de empujar las secciones a cuatro
   filas donde hoy hay dos. En un sitio institucional, prometer una interaccion
   que no existe es peor defecto que la letra chica.

   ⚠️ CALIFICADO A ESTA PAGINA. En /actualidad/ las mismas etiquetas SI son
   metadato («Institucional», «Lanzamiento») y agrandarlas seria el error
   inverso; en /transparencia/ los principios funcionan igual.

   El `!important` va SOLO en font-size, y es contra un `style` EN LINEA del
   prototipo (13,5 px), que es el unico caso donde la casa lo admite. El peso y
   el relleno ganan por especificidad (0,2,0 contra 0,1,0) y no lo necesitan.
   ══════════════════════════════════════════════════════════════════════════ */
.pag-ciencias-geoespaciales .tag {
  font-size: 16px !important;
  font-weight: 600;
  padding: 8px 14px;
}

/* V33: el marco de «Por qué importa en el Perú» es 2/3 (vertical) porque ahi
   acompana a una columna de texto que con los 3 parrafos mide 722 px — a 4/3
   quedaban 410 px de vacio repartidos arriba y abajo, con la figura flotando.
   Medido a 1440: 2/3 deja 97 px, que se lee como desfase editorial.

   ⚠️ PERO EN UNA SOLA COLUMNA LA FIGURA OCUPA TODO EL ANCHO, y ahi lo vertical
   se vuelve un problema: medido a 700 px daba 630x945, un rectangulo enorme
   antes del texto. Cuando es ancho completo vuelve al 4/3 del diseno aprobado,
   que es la proporcion de una foto apaisada. El !important es contra el
   `aspect-ratio` en linea que pone la cadena de conversion. */
@media (max-width: 720px) {
  .pag-ciencias-geoespaciales .ipcge-split .ipcge-marco { aspect-ratio: 4/3 !important; }
}

/* V31, segunda parte (2026-08-02): las 8 etiquetas de la banda «Un motor para
   Latinoamerica» quedaron chicas y Julio lo detecto en el sitio publicado.
   La causa no fue el alcance de la regla: el prototipo las escribio como
   <span> SIN CLASE y con todo en linea —13,5 px, peso 400, relleno 6/12—
   porque sobre el rojo los colores de .tag-outline no sirven, asi que
   `.pag-ciencias-geoespaciales .tag` no podia verlas. Se les dio clase propia
   en la cadena de conversion y aca reciben el mismo tratamiento: mismo tamano,
   mismo peso, mismo relleno. El color lo siguen poniendo sus estilos en linea,
   que ya usan el token de la banda. */
.pag-ciencias-geoespaciales .ipcge-tag-banda {
  font-size: 16px !important;
  font-weight: 600;
  padding: 8px 14px !important;
}

/* ══════════════════════════════════════════════════════════════════════════
   V35 — Un boton de contorno que funciona sobre CUALQUIER superficie
   ══════════════════════════════════════════════════════════════════════════
   Pedido de Julio: «los botones deben tener la suficiente calidad de diseno
   para que se ajusten a cualquier fondo, hoy y en el futuro». El principio que
   lo cumple: EL BOTON NO SABE SOBRE QUE FONDO ESTA. La superficie declara su
   par de colores y el boton los usa. Para poner uno sobre una superficie nueva
   basta con que esa superficie declare las dos variables.

   Tres defectos MEDIDOS que esto cierra, los tres de la misma familia — una
   regla pensada para fondo claro, aplicada sobre una banda de color:

   1. EL BORDE DESAPARECIA EN OSCURO. Dos botones escribian
      `border:2px solid var(--color-bg)`, y --color-bg cambia con el tema: en
      oscuro daba 1,96:1 sobre el rojo, contra el 3:1 que WCAG 1.4.11 exige al
      limite de un control. Es la trampa de V16 en su forma abreviada, que la
      conversion no cubria.
   2. EL HOVER DEL SISTEMA ROMPIA EL CONTRASTE, y en los TRES botones de banda
      del sitio, incluido el de /proyectos/. `.btn-ghost:hover` pinta un lavado
      de acento al 10 %: sobre la banda es rojo sobre rojo y el texto caia de
      6,41 a 3,76:1 en claro y de 6,56 a 3,85:1 en oscuro. Ahora el hover
      INVIERTE —relleno claro, letra del color de la superficie—, que es lo que
      Julio pidio y ademas sube el contraste en vez de bajarlo.
   3. EL RELLENO LATERAL ERA DE 4 px. `.btn-ghost` del sistema es un boton DE
      TEXTO, sin borde, y por eso casi no tiene aire; con borde, ese borde
      quedaba pegado a las letras. Pasa a los 14,4 px de los demas botones.

   ⚠️ Los estilos en linea se QUITARON del marcado (en la cadena de conversion,
   no solo en las paginas): un atributo style le gana a cualquier regla, y con
   el `color` en linea el hover no podia invertir la letra.
   ══════════════════════════════════════════════════════════════════════════ */
.ipcge-banda {
  --ipcge-btn-tinta: var(--ipcge-banda-texto);        /* legible SOBRE esta superficie */
  --ipcge-btn-suelo: var(--color-accent-700);         /* el color DE esta superficie */
  --ipcge-btn-suelo-fuerte: var(--color-accent-900);  /* su paso profundo, para apretado */
}
.ipcge-banda .btn-ghost {
  color: var(--ipcge-btn-tinta);
  border: 1px solid var(--ipcge-btn-tinta);
  background: transparent;
  padding-inline: 14.4px;
  transition: background 0.15s, color 0.15s;
}
/* El puntero y el foco de teclado se tratan igual: quien navega con tabulador
   ve exactamente lo que ve quien usa el raton. */
.ipcge-banda .btn-ghost:hover,
.ipcge-banda .btn-ghost:focus-visible {
  background: var(--ipcge-btn-tinta);
  color: var(--ipcge-btn-suelo);
}
.ipcge-banda .btn-ghost:active {
  background: var(--ipcge-btn-tinta);
  color: var(--ipcge-btn-suelo-fuerte);
}

/* ══════════════════════════════════════════════════════════════════════════
   V36 — Los botones del sitio llegan al objetivo tactil, de una vez
   ══════════════════════════════════════════════════════════════════════════
   Censo del 2026-08-02, contando solo los `.btn` VISIBLES (el de menu existe en
   las 15 paginas y se oculta en escritorio: un elemento invisible no tiene
   objetivo tactil, asi que sumarlo mentiria en los dos sentidos):

     en movil (390 px)       68 botones · 21 cumplian · 32 median 35, 15 median 36
     en escritorio (1440)    53 botones ·  6 cumplian · 32 median 35, 15 median 36

   Los 6 de escritorio eran EXACTAMENTE los que ya se habian corregido de a uno
   (3 de V23 + 3 de V24); en movil se sumaban los 15 botones de menu, que V1 ya
   habia puesto en 44x44. O sea: ningun boton llego a 44 px por la regla base.

   Se venia tratando el sintoma. Cada vez que Julio miraba una pagina nueva
   aparecia otro boton chico, porque la regla base nunca se toco. Esta lo
   arregla en el origen y vuelve innecesarias las de V23 y V24, que se
   eliminaron: una sola declaracion en lugar de tres.

   Impacto medido comparando el sitio construido contra si mismo, con la regla
   y sin ella — no contra el prototipo, que ya arrastra todo lo aprobado desde
   entonces y no permitiria aislar este cambio:
     cabecera en escritorio   62 -> 70 px   (+8: la altura que ya tenia en movil)
     cabecera en movil        70 -> 70 px   (sin cambio)
     alto del hero            sin cambio en ninguna pagina ni ancho
     pie                      sin cambio
     portada completa         +27 px en escritorio, +46 en movil
     /contacto/               +27 px en los dos anchos
     6 de las 30 combinaciones pagina x ancho quedan EXACTAMENTE igual

   ⚠️ LOS BOTONES DE ICONO NECESITAN LAS DOS MEDIDAS. Miden 36x36; subir solo
   el alto los dejaria rectangulares —44 de alto y 36 de ancho—, que se ve peor
   que el defecto que se venia a corregir. Un objetivo tactil es un area, no
   una altura.
   ══════════════════════════════════════════════════════════════════════════ */
.btn { min-height: 44px; }
.btn-icon { min-width: 44px; }

/* ══════════════════════════════════════════════════════════════════════════
   V37 — El subtitulo del hero de la portada corta en 2 lineas
   ══════════════════════════════════════════════════════════════════════════
   Pedido de Julio: que «Ciencia, tecnologia e infraestructura geoespacial /
   para el desarrollo del Peru.» se lea en dos lineas, cortando despues de
   «geoespacial». Hoy corta en TRES en los cinco anchos, porque el prototipo
   le puso `max-width:22ch` en linea: 316 px de los 1056 disponibles a 1440.

   ⚠️ EN CELULAR LAS DOS LINEAS NO SON POSIBLES, y no es una decision. La
   primera pide 416 px a 19 px de fuente, y a 360 px de pantalla hay 320
   utiles: faltan 96. A 390 faltan 66. De 768 para arriba sobra.

   LA VENTANA DEL VALOR ES ANGOSTA Y HUBO QUE MEDIRLA. La cuenta de `ch`
   sugeria que servia cualquier valor entre 39 y 59 —la frase entera mide
   59,1ch—, y es FALSO: el corte no lo decide el largo total sino si entra la
   palabra SIGUIENTE. Barrido de 36 a 46ch de a 0,5:

     hasta 38ch     corta antes, en «infraestructura»
     38,5 a 41,5ch  ✔ el corte pedido
     42ch en mas    ya entra «para» y despues «el»

   Son 3ch de ventana. Se elige 40ch por estar en el CENTRO exacto, que deja
   ~22 px de margen a cada lado.

   EL CORTE EN 640 px NO ES INVENTADO: es el breakpoint movil/tablet que el
   §7 ya declara. Debajo NO se toca nada — la portada en celular queda como
   esta hoy, y eso importa: con 40ch a 360 px la frase termina en «Peru.»
   SOLA en su linea, una viuda tipografica. El valor que arregla escritorio
   rompe el telefono, asi que la regla se acota al ancho donde sirve.

   Verificado en 16 anchos de 320 a 1920: ninguna viuda, ningun desborde, y
   el corte pedido en los 9 que estan sobre 640.

   El `!important` es obligatorio y es el caso que el §6 admite: el
   `max-width` vive en un `style` EN LINEA del diseno aprobado, y ninguna
   especificidad de hoja de estilo le gana. Se deja el valor del prototipo
   intacto y se lo pisa solo donde hace falta.

   `h1 + p` es estable: la casa exige un solo `h1` por pagina (§7), asi que
   el selector no puede alcanzar otro parrafo.
   ══════════════════════════════════════════════════════════════════════════ */
@media (min-width: 640px) {
  .pag-inicio h1 + p { max-width: 40ch !important; }
}

/* ══════════════════════════════════════════════════════════════════════════
   V38 — Los dos listados con filas dejan de estar ENMARCADOS
   ══════════════════════════════════════════════════════════════════════════
   Pedido de Julio sobre /investigacion/, extendido a /instituto/ porque el
   motivo vale igual en los dos. Se van la primera linea y la ultima; quedan
   solo las que SEPARAN filas.

     /investigacion/  «Areas de investigacion aplicada»   10 lineas -> 8
     /instituto/      «Lineas estrategicas»                6 lineas -> 4

   Las que se van son las que ENMARCAN, no las que separan. Tres cosas salieron
   de medirlo:

   1. LA ULTIMA DUPLICA UNA LINEA QUE YA ESTABA. 48 px mas abajo hay un
      <hr class="hr"> —el separador de seccion— del mismo grosor y el mismo
      color. El listado cerraba con DOS lineas horizontales a 48 px una de
      otra. Sin la del contenedor, el <hr> cierra solo.
   2. LA PRIMERA hacia leer el listado como una TABLA: el rotulo de seccion
      queda justo encima, asi que esa linea parecia separar un encabezado de
      su cuerpo.
   3. El :hover de V16 pinta las filas de investigacion en accent-700 y el
      borde sigue gris (2px al 40 % sobre rgb(174,24,0)): una linea gris
      cruzando el bloque rojo. Pasa en LAS 9 FILAS, no solo en la primera, asi
      que esto lo arregla solo para la 01. Mejora parcial, no el motivo.

   ⚠️ `:first-child` NO SIRVE EN /instituto/, Y HABRIA FALLADO EN SILENCIO.
   Medido: `.ipcge-feature:first-child` coincide con CERO elementos, porque las
   filas son hermanas del rotulo y del <h2> y la primera fila es el TERCER
   hijo de la seccion. La regla habria existido, no habria hecho nada y no se
   habria quejado — la trampa del §6.

   `:not(.X ~ .X)` dice literalmente «la que no tiene otra igual antes», que es
   lo que se quiere. Se eligio sobre `:first-of-type` —que tambien funciona
   hoy— porque ese significa «el primer div»: si alguien mete un div adelante,
   vuelve a fallar callado.

   ⚠️ Ese `:not()` SUBE LA ESPECIFICIDAD a (0,4,0), y el §6 avisa que eso roba
   reglas ajenas. Revisado: estas reglas solo tocan `border-top`/`border-bottom`
   y ninguna otra regla del sitio ni del sistema los declara para estas dos
   clases. No hay nada que superar.

   El !important es contra los `style` en linea del diseno aprobado, el unico
   caso que el §6 admite. El marcado no se toca, como en V26 y V32.
   ══════════════════════════════════════════════════════════════════════════ */
.pag-investigacion .ipcge-inv-row:not(.ipcge-inv-row ~ .ipcge-inv-row) { border-top: 0 !important; }
.pag-investigacion section > div:has(> .ipcge-inv-row) { border-bottom: 0 !important; }
.pag-instituto .ipcge-feature:not(.ipcge-feature ~ .ipcge-feature) { border-top: 0 !important; }
.pag-instituto .ipcge-feature:last-child { border-bottom: 0 !important; }

/* ══════════════════════════════════════════════════════════════════════════
   V39 — REVOCADO el 2026-08-03, el mismo dia, a pedido de Julio
   ══════════════════════════════════════════════════════════════════════════
   V39 le puso `max-width: 52ch` a las descripciones de «Areas de
   investigacion aplicada», copiando el valor del listado hermano de
   /instituto/. Julio lo vio publicado y pidio que el texto fluya libre.

   TENIA RAZON, Y EL ERROR FUE MIO: copie el NUMERO en vez del RESULTADO. En
   /instituto/ las filas son una rejilla de 3 columnas
   (numero | titulo | descripcion) y 52ch LLENA su columna. Aca la rejilla es
   de 2 (numero | bloque de texto), asi que el bloque dispone de 972 px a
   1440 y 52ch ocupaba 402: sobraban 570 px vacios a la derecha. Mismo
   numero, resultado opuesto.

   La consecuencia asumida esta medida y dicha: sin limite, la linea corre a
   ~126 caracteres a 1440 px, sobre los 45-75 de lectura comoda. La salida
   que llenaria el ancho SIN lineas largas es pasar la fila a 3 columnas como
   /instituto/, y eso es un cambio de maqueta que Julio no pidio.

   No hace falta un cambio V para revocarlo: el diseno aprobado NO declaraba
   max-width, asi que quitarlo devuelve la pagina a su estado original.
   ══════════════════════════════════════════════════════════════════════════ */
