﻿/* =============================================================================
   sitio.css -- el sitio publico del Congreso Internacional PIV
   Fecha: 2026-08-22

   LA MARCA NO SE INVENTA
   2026-08-23: el evento estreno logo -- el isotipo de atomo/red que viene en el
   banner de la edicion 30. Su verde ya no es el verde puro del engrane viejo
   (#22942E, H=126) sino un verde AZULADO: se muestreo el nucleo del trazo en el
   banner a 6912 px y la mediana del degradado va de #589974 arriba a #5F6964
   abajo, toda en H=146..150. La palabra PIV es gris neutro #4C4C4C.

   ESE VERDE DEL LOGO NO SE PUEDE USAR TAL CUAL PARA TEXTO.
   #589974 sobre blanco da 3.37:1 y el minimo para texto normal es 4.5:1. Asi que
   la paleta conserva el TONO del logo (H=148) y le baja la luminosidad hasta que
   cumple, medido con la formula WCAG, no a ojo:

       --piv-verde        #348258   4.69:1 sobre blanco  -- botones y texto
       --piv-verde-hondo  #266443   7.03:1 sobre blanco  -- enlaces y hover
       --piv-verde-claro  #BDDBCB  12.13:1 sobre el hero -- adorno, NUNCA texto
                                                             sobre blanco
       --piv-verde-lavado #EDF7F2  16.44:1 con la tinta  -- fondos

   De paso esto corrige un defecto que ya traia el sitio: el verde viejo #22942E
   daba 3.93:1 sobre blanco, o sea que .btn--principal (letra blanca sobre verde)
   NO cumplia. Ahora si.

   El claro y el lavado se eligieron a la MISMA luminosidad que los que sustituyen
   (12.40 -> 12.13 y 16.29 -> 16.44) para que ningun equilibrio ya afinado del
   sitio se mueva: cambia el tono, no el peso.

   POR QUE BARLOW
   El congreso lo organiza la Facultad de Ingenieria Mecanica y Electrica y el
   isotipo es tecnico -- antes un engrane, hoy una red de orbitas y nodos de
   circuito. Barlow viene de las grotescas de senializacion
   industrial: es la letra que le corresponde al tema, no una neutral cualquiera.
   La condensada carga los titulos -- tiene el aire de cartel del triptico -- y
   la normal el texto corrido.

   LO QUE ESTE ARCHIVO CORRIGE DEL SITIO VIEJO
   - Maquetacion con <table>, <font> y <center>: aqui es grid y flex.
   - "Responsivo" que en realidad no lo era: aqui se disenia desde el movil.
   - Los 11 evaluadores escondidos en un carrusel donde se veia UNO a la vez:
     aqui es una rejilla y se ven todos.
   ============================================================================= */

/* ---------------------------------------------------------------- tokens -- */
:root {
    /* La marca */
    --piv-verde:        #348258;
    /* El mismo verde, en componentes. Existe SOLO para las transparencias:
       rgba() no acepta un hex adentro, asi que sin esto cada halo y cada
       resaltado acaban con el color copiado a mano -- que es exactamente como
       sobrevivieron dos rgba(34,148,46) del verde viejo despues de cambiar la
       paleta. Con el token, el dia que la marca cambie, cambian con ella. */
    --piv-verde-rgb:    52, 130, 88;
    --piv-verde-hondo:  #266443;
    --piv-verde-claro:  #BDDBCB;
    --piv-verde-lavado: #EDF7F2;
    --piv-negro:        #14180F;

    /* ---- el lateral del panel  (2026-08-24) ----------------------------

       ESTABA EN --piv-negro, QUE NO ES DE LA MARCA: un gris casi neutro con
       una pizca del verde VIEJO. Al lado del verde azulado de hoy se leia como
       suciedad, no como color.

       Ahora es la misma familia del verde de marca -- tono 150, el de #348258
       -- bajado de luminosidad. El lateral deja de ser "la parte oscura" y pasa
       a ser el mismo verde del congreso, en su version honda.

       Van como tokens y no escritos en cada regla POR LA LECCION L1-L6: la vez
       pasada el color estaba copiado en cuatro sitios y cuatro sitios se
       quedaron con el verde viejo cuando cambio la marca.
       ------------------------------------------------------------------- */
    --panel-alto:     #173328;   /* arriba. Es el punto MAS CLARO del lateral,
                                    asi que es donde se mide el peor contraste */
    --panel-fondo:    #12291F;   /* el cuerpo, donde vive casi todo el menu */
    --panel-hondo:    #0E2018;   /* abajo, para que el lateral tenga fondo y no
                                    sea un rectangulo de un solo tono */
    --panel-texto:    #B6D6C4;   /* 9.84:1 sobre --panel-fondo y 8.70:1 sobre
                                    --panel-alto -- las opciones y el pie */
    --panel-apagado:  #7FA891;   /* 5.81:1 y 5.14:1 -- titulos de grupo, las
                                    pantallas pendientes y el menu vacio */
    --panel-realce:   #5FBE8B;   /* el filo del renglon activo -- 6.77:1 */

    /* Los dos de arriba otra vez, en componentes, POR LA MISMA RAZON QUE
       --piv-verde-rgb: rgba() no acepta un hex adentro. Sin esto, el velo del
       hover, el fondo del renglon activo, las lineas y la barra de
       desplazamiento acaban con el color copiado a mano -- que es justo lo que
       le habia pasado a la barra: llevaba #2C5F45 y #3C7A59 escritos, que son
       este mismo verde al 34% y al 55%, y no habrian cambiado con la paleta. */
    --panel-texto-rgb:  182, 214, 196;
    --panel-realce-rgb: 95, 190, 139;
    /* Y --panel-hondo en componentes, por lo mismo: el velo que oscurece el
       contenido detras del cajon de movil es este verde al 50%. Escrito a mano
       serian los tres numeros de #0E2018 sueltos en una regla -- la leccion
       L1-L6 otra vez. */
    --panel-hondo-rgb:  14, 32, 24;
    --panel-linea:    rgba(var(--panel-texto-rgb), .14);

    /* Neutros con una pizca del verde de la marca: un gris puro al lado de
       este verde se ve sucio, no neutro. */
    --tinta:      #14180F;
    --tinta-suave:#4A5145;
    --tenue:      #767D70;
    --regla:      #E2E6DE;
    --regla-tenue:#EFF2EC;
    --fondo:      #FFFFFF;
    --fondo-alt:  #F7F9F5;

    /* Estados. Van aparte del verde de la marca a proposito: si "guardado" y
       "el boton principal" fueran el mismo color, nada resaltaria. */
    /* SE DISTINGUEN POR SATURACION, NO POR TONO. Los de antes -- #1C7926 y su
       fondo -- eran del verde amarillento viejo (H=126), y al lado del verde
       azulado del logo nuevo (H=148) se veian sucios, como si uno de los dos
       estuviera mal impreso. Ahora comparten familia (H=158) y lo que los
       separa del boton es que van mucho mas saturados: 78% contra 43%. Asi
       "guardado" sigue sin confundirse con "el boton principal", que es para
       lo que estos tokens van aparte. 5.35:1 sobre blanco, arriba del 4.5
       que pide AA para texto normal. */
    --ok:      #0F7A52;
    --ok-bg:   #E9F6F0;
    --alerta:  #8A5B00;
    --alerta-bg:#FBF3E2;
    --error:   #A8232A;
    --error-bg:#FBEAEA;
    --info:    #1F5C8B;
    --info-bg: #EAF2F9;

    --sombra:     0 1px 2px rgba(20,24,15,.06), 0 8px 24px -14px rgba(20,24,15,.18);
    --sombra-alta:0 2px 6px rgba(20,24,15,.08), 0 18px 40px -20px rgba(20,24,15,.28);

    --radio:   10px;
    --radio-sm: 6px;

    --f-titulo: "Barlow Condensed", "Arial Narrow", Arial, sans-serif;
    --f-texto:  "Barlow", "Helvetica Neue", Arial, sans-serif;
    --f-dato:   "IBM Plex Mono", ui-monospace, Consolas, monospace;

    /*  ANCHO DEL CONTENIDO.

        Estaba en 1180 y Carlos lo noto: "porque redujiste el width del
        contenido, estaba genial como sacaste la primera version mucho mas
        ancho, asi como el proyecto SPAC".

        1480 deja respirar a las rejillas de cuatro columnas -- los pasos, las
        areas, los evaluadores -- que a 1180 salian apretadas en un monitor
        ancho. Los parrafos NO se estiran con esto: la prosa vive dentro de
        .medida y .seccion__cabeza, que tienen su propio tope en ch. Una linea
        de texto de 1400 pixeles no se lee, se rastrea. */
    --ancho: 1480px;
}

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

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

body {
    margin: 0;
    background: var(--fondo);
    color: var(--tinta);
    font-family: var(--f-texto);
    font-size: 17px;
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
}

/* --------------------------------------------------------------- textos -- */
h1, h2, h3, h4 {
    font-family: var(--f-titulo);
    font-weight: 600;
    line-height: 1.08;
    letter-spacing: .002em;
    margin: 0 0 .5em;
    text-wrap: balance;
}
h1 { font-size: clamp(2.4rem, 6vw, 4rem); font-weight: 700; }
h2 { font-size: clamp(1.9rem, 4vw, 2.7rem); }
h3 { font-size: 1.35rem; }
h4 { font-size: 1.1rem; }

p { margin: 0 0 1rem; }
/* El texto corrido no pasa de ~68 caracteres: mas ancho y el ojo se pierde al
   saltar de renglon. */
.medida { max-width: 68ch; }

a { color: var(--piv-verde-hondo); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { color: var(--piv-verde); }

strong, b { font-weight: 600; }

.dato { font-family: var(--f-dato); font-variant-numeric: tabular-nums; }

.eyebrow {
    font-family: var(--f-titulo);
    font-size: .9rem;
    font-weight: 600;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--piv-verde);
    margin: 0 0 .6rem;
}

/* -------------------------------------------------------------- armazon -- */
.contenedor { width: 100%; max-width: var(--ancho); margin: 0 auto; padding: 0 24px; }

.seccion { padding: 80px 0; }
.seccion--alt { background: var(--fondo-alt); }
.seccion--verde { background: var(--piv-verde-lavado); }

.seccion__cabeza { margin-bottom: 44px; max-width: 62ch; }
.seccion__cabeza p { color: var(--tinta-suave); font-size: 1.08rem; }

@media (max-width: 700px) { .seccion { padding: 56px 0; } }

/* Una regla corta bajo el titulo, del verde de la marca. Es el unico adorno
   del sitio y por eso se puede permitir. */
.filo::after {
    content: "";
    display: block;
    width: 56px; height: 3px;
    background: var(--piv-verde);
    border-radius: 2px;
    margin-top: 14px;
}

/* ----------------------------------------------------------------- nav --- */
.nav {
    position: sticky; top: 0; z-index: 50;
    background: rgba(255,255,255,.94);
    backdrop-filter: saturate(150%) blur(8px);
    border-bottom: 1px solid var(--regla);
}
.nav__caja { display: flex; align-items: center; gap: 24px; min-height: 68px; }
.nav__logo { display: flex; align-items: center; flex: 0 0 auto; }
.nav__logo img { height: 34px; width: auto; display: block; }
.nav__menu { display: flex; align-items: center; gap: 4px; margin-left: auto; list-style: none; padding: 0; }
.nav__menu a {
    display: block;
    font-family: var(--f-titulo);
    font-size: 1.02rem; font-weight: 500;
    letter-spacing: .01em;
    color: var(--tinta-suave);
    text-decoration: none;
    padding: 9px 13px;
    border-radius: var(--radio-sm);
}
.nav__menu a:hover { color: var(--piv-verde-hondo); background: var(--piv-verde-lavado); }
.nav__menu a[aria-current="page"] { color: var(--piv-verde-hondo); font-weight: 600; }

.nav__toggle {
    display: none; margin-left: auto;
    background: none; border: 1px solid var(--regla); border-radius: var(--radio-sm);
    padding: 8px 11px; cursor: pointer; color: var(--tinta);
    font-family: var(--f-titulo); font-size: 1rem;
}

@media (max-width: 940px) {
    .nav__toggle { display: block; }
    .nav__menu {
        display: none; position: absolute; top: 100%; left: 0; right: 0;
        flex-direction: column; align-items: stretch; gap: 0;
        background: #fff; border-bottom: 1px solid var(--regla);
        padding: 8px 16px 16px; box-shadow: var(--sombra);
    }
    .nav__menu.abierto { display: flex; }
    .nav__menu a { padding: 12px 8px; border-radius: 0; border-bottom: 1px solid var(--regla-tenue); }
}

/* --------------------------------------------------------------- botones -- */
/* ============================================================ EL RELIEVE ====

   Carlos, 2026-08-31: "que los botonsitos hagan algun efectito 3d".

   COMO ESTA HECHO, Y POR QUE ASI. El volumen sale de UNA sola propiedad --
   box-shadow con tres capas -- y no de imagenes ni de gradientes:

     inset 0 1px 0 <brillo>   el filo de arriba, donde pegaria la luz
     0 3px 0 <canto>          EL CANTO. Sombra solida, sin desenfoque: es el
                              grueso del boton, lo que hace que se vea como
                              una pieza y no como un rectangulo pintado
     0 5px 12px <difusa>      la sombra que proyecta sobre la pagina

   POR QUE box-shadow Y NO background-image. Cada variante ya define su
   `background` con la forma corta, que borraria cualquier gradiente que se
   pusiera aqui arriba. Con box-shadow no hay que tocar ni una de las siete
   variantes: solo le dicen de que color es su canto.

   EL GESTO AL PULSAR ES EL QUE VENDE EL EFECTO. Al pasar el raton sube un
   pixel y el canto crece; al pulsar BAJA los tres pixeles del canto y el canto
   desaparece -- o sea que el boton se hunde hasta quedar al ras de la pagina,
   que es exactamente lo que hace una tecla de verdad. Sin esa segunda mitad, el
   relieve se ve pegado y muerto.

   LOS APAGADOS NO LO LLEVAN: un boton inerte con relieve invita a pulsarlo.
   ========================================================================== */
.btn {
    display: inline-flex; align-items: center; justify-content: center; gap: 8px;
    font-family: var(--f-titulo);
    font-size: 1.06rem; font-weight: 600; letter-spacing: .015em;
    padding: 12px 26px;
    border: 1px solid transparent; border-radius: var(--radio-sm);
    cursor: pointer; text-decoration: none;

    --btn-canto:  rgba(31, 42, 34, .16);
    --btn-brillo: rgba(255, 255, 255, .16);
    box-shadow: inset 0 1px 0 var(--btn-brillo),
                0 3px 0 var(--btn-canto),
                0 5px 12px rgba(31, 42, 34, .12);

    transition: background .15s ease, border-color .15s ease, color .15s ease,
                transform .12s ease, box-shadow .12s ease;
}
.btn:hover {
    transform: translateY(-1px);
    box-shadow: inset 0 1px 0 var(--btn-brillo),
                0 4px 0 var(--btn-canto),
                0 8px 18px rgba(31, 42, 34, .16);
}
/* Hundido: se va el canto y baja lo que el canto media. */
.btn:active {
    transform: translateY(3px);
    box-shadow: inset 0 1px 2px rgba(31, 42, 34, .22),
                0 0 0 var(--btn-canto),
                0 1px 2px rgba(31, 42, 34, .10);
}

.btn--principal { background: var(--piv-verde); color: #fff; --btn-canto: #1C4E34; }
.btn--principal:hover { background: var(--piv-verde-hondo); color: #fff; }

.btn--linea {
    background: transparent; color: var(--piv-verde-hondo); border-color: var(--piv-verde);
    --btn-canto: var(--piv-verde-claro); --btn-brillo: transparent;
}
.btn--linea:hover { background: var(--piv-verde-lavado); }

.btn--claro { background: #fff; color: var(--piv-verde-hondo); --btn-canto: #C4D5C9; --btn-brillo: transparent; }
.btn--claro:hover { background: var(--piv-verde-lavado); }

.btn--suave {
    background: var(--fondo-alt); color: var(--tinta); border-color: var(--regla);
    --btn-canto: #D5DCD1; --btn-brillo: transparent;
}
.btn--suave:hover { background: var(--regla-tenue); }

/* Apagado: plano y sin sombra. No hay nada que pulsar. */
.btn[disabled], .btn--inerte {
    background: var(--regla-tenue); color: var(--tenue);
    border-color: var(--regla); cursor: not-allowed; pointer-events: none;
    box-shadow: none; transform: none;
}

.btn--grande { font-size: 1.16rem; padding: 15px 34px; }
/* El chico lleva un canto de dos pixeles: con tres, un boton de 34px de alto
   parece un ladrillo, y en el panel hay filas enteras de estos. */
.btn--chico  {
    font-size: .95rem;  padding: 8px 16px;
    --btn-canto: rgba(31, 42, 34, .14);
    box-shadow: inset 0 1px 0 var(--btn-brillo),
                0 2px 0 var(--btn-canto),
                0 3px 8px rgba(31, 42, 34, .10);
}
.btn--chico:hover {
    box-shadow: inset 0 1px 0 var(--btn-brillo),
                0 3px 0 var(--btn-canto),
                0 5px 12px rgba(31, 42, 34, .14);
}
.btn--chico:active { transform: translateY(2px); }

/* Quien pidio menos movimiento se queda con el relieve, que es informacion --
   dice que eso se puede pulsar --, pero sin el salto ni el hundimiento. */
@media (prefers-reduced-motion: reduce) {
    .btn { transition: background .15s ease, border-color .15s ease, color .15s ease; }
    .btn:hover, .btn:active { transform: none; }
}

/* ---------------------------------------------------------------- hero --- */
.hero {
    position: relative;
    background: var(--piv-negro);
    color: #fff;
    padding: 96px 0 88px;
    overflow: hidden;
}
/* El anillo del isotipo, enorme y apenas visible. El sitio viejo ponia una
   foto de fondo distinta cada anio y el texto encima se volvia ilegible; esto
   es del mismo verde de la marca y nunca compite con la letra. */
.hero::before {
    content: "";
    position: absolute; right: -140px; top: -120px;
    width: 520px; height: 520px;
    border: 74px solid var(--piv-verde);
    border-radius: 50%;
    opacity: .17;
    pointer-events: none;
}
.hero__caja { position: relative; z-index: 1; max-width: 760px; }
.hero .eyebrow { color: var(--piv-verde-claro); }
.hero h1 { color: #fff; margin-bottom: .35em; }
.hero__lema { font-size: 1.24rem; color: #D6DDD2; max-width: 56ch; margin-bottom: 32px; }
.hero__acciones { display: flex; flex-wrap: wrap; gap: 14px; align-items: center; }

/* El estado del registro. Es lo primero que alguien quiere saber al llegar. */
.hero__estado {
    display: inline-flex; align-items: center; gap: 9px;
    font-family: var(--f-titulo); font-size: 1rem; font-weight: 500;
    padding: 7px 15px; border-radius: 999px;
    background: rgba(255,255,255,.10);
    border: 1px solid rgba(255,255,255,.22);
    margin-bottom: 22px;
}
.hero__estado::before {
    content: ""; width: 9px; height: 9px; border-radius: 50%;
    background: var(--tenue); flex: 0 0 auto;
}
/* El punto va claro a proposito -- es un indicador, no texto -- pero tambien
   se paso al verde azulado: en #5FD16E (H=128) se veia de otro sistema. */
.hero__estado--abierto::before { background: #4FC98F; box-shadow: 0 0 0 4px rgba(79,201,143,.24); }
.hero__estado--cerrado::before { background: #D98A8A; }

@media (max-width: 700px) {
    .hero { padding: 64px 0 56px; }
    .hero::before { width: 320px; height: 320px; border-width: 48px; right: -110px; top: -90px; }
}

/* --------------------------------------------------------------- fichas -- */
.rejilla { display: grid; gap: 22px; }
.rejilla--2 { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
.rejilla--3 { grid-template-columns: repeat(auto-fit, minmax(270px, 1fr)); }
.rejilla--4 { grid-template-columns: repeat(auto-fit, minmax(215px, 1fr)); }

.ficha {
    background: #fff;
    border: 1px solid var(--regla);
    border-radius: var(--radio);
    padding: 26px;
    box-shadow: var(--sombra);
}
.ficha h3 { margin-bottom: .4em; }
.ficha p:last-child { margin-bottom: 0; }
.ficha--liga { text-decoration: none; color: inherit; display: block; transition: box-shadow .15s ease, border-color .15s ease; }
.ficha--liga:hover { box-shadow: var(--sombra-alta); border-color: var(--piv-verde-claro); color: inherit; }

/* Los cuatro pasos para participar. El numero SI significa algo aqui: es un
   orden real, no un adorno. */
.paso { position: relative; padding-top: 8px; }
.paso__num {
    font-family: var(--f-titulo);
    font-size: 2.6rem; font-weight: 700; line-height: 1;
    color: var(--piv-verde-claro);
    display: block; margin-bottom: 10px;
}
.paso h3 { font-size: 1.24rem; }
.paso p { color: var(--tinta-suave); font-size: .99rem; margin-bottom: 0; }

/* Evaluadores: rejilla, no carrusel. */
.evaluador { display: flex; flex-direction: column; }
.evaluador__grado {
    font-family: var(--f-dato); font-size: .78rem;
    letter-spacing: .08em; text-transform: uppercase;
    color: var(--piv-verde); margin-bottom: 4px;
}
.evaluador__nombre { font-size: 1.18rem; margin-bottom: .35em; }
.evaluador__inst { color: var(--tenue); font-size: .94rem; margin-bottom: 12px; }
.evaluador__semblanza { font-size: .95rem; color: var(--tinta-suave); line-height: 1.55; }
/* La semblanza mas larga mide 645 caracteres: recortada a cuatro renglones las
   tarjetas quedan parejas, y el resto se abre con el detalle. */
.evaluador__semblanza--corta {
    display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical;
    overflow: hidden;
}
.evaluador details > summary {
    cursor: pointer; color: var(--piv-verde-hondo);
    font-family: var(--f-titulo); font-weight: 600; font-size: .98rem;
    margin-top: 10px; list-style: none;
}
.evaluador details > summary::-webkit-details-marker { display: none; }
.evaluador details > summary::after { content: " +"; }
.evaluador details[open] > summary::after { content: " \2212"; }

/* Contactos */
.contacto { display: flex; flex-direction: column; gap: 2px; padding: 16px 0; border-bottom: 1px solid var(--regla-tenue); }
.contacto__nombre { font-family: var(--f-titulo); font-size: 1.12rem; font-weight: 600; }
.contacto__cargo { color: var(--tenue); font-size: .88rem; }
.contacto a { font-size: .98rem; word-break: break-word; }

/* ------------------------------------------------------------ calendario -- */
.calendario { border-top: 1px solid var(--regla); }
.calendario__fila {
    display: grid; grid-template-columns: minmax(0,1fr) auto;
    gap: 18px; align-items: baseline;
    padding: 18px 0; border-bottom: 1px solid var(--regla);
}
.calendario__que { font-size: 1.02rem; }
.calendario__cuando {
    font-family: var(--f-titulo); font-weight: 600; font-size: 1.06rem;
    color: var(--piv-verde-hondo); text-align: right; white-space: nowrap;
}
/* El renglon de la inscripcion. Es el unico del calendario que todavia se
   puede alcanzar -- los demas cuentan lo que pasa despues --, asi que se
   distingue con un filo de color y un fondo lavado. No lleva negrita extra:
   la columna de la fecha ya va en 600, y subirle el peso al "que" haria que
   compitiera con el h3 de arriba. */
.calendario__fila--clave {
    background: var(--piv-verde-lavado);
    border-left: 3px solid var(--piv-verde);
    padding-left: 14px; padding-right: 14px;
}

@media (max-width: 620px) {
    .calendario__fila { grid-template-columns: 1fr; gap: 4px; }
    .calendario__cuando { text-align: left; }
}

/* --------------------------------------------------------------- avisos -- */
.aviso {
    display: flex; gap: 12px; align-items: flex-start;
    padding: 15px 18px; border-radius: var(--radio-sm);
    border: 1px solid; font-size: .99rem; margin-bottom: 20px;
}
.aviso p:last-child { margin-bottom: 0; }
.aviso--ok     { background: var(--ok-bg);     border-color: var(--piv-verde-claro); color: var(--ok); }
.aviso--error  { background: var(--error-bg);  border-color: #EDC6C6; color: var(--error); }
.aviso--alerta { background: var(--alerta-bg); border-color: #EBDCB8; color: var(--alerta); }
.aviso--info   { background: var(--info-bg);   border-color: #C8DCEC; color: var(--info); }

/* ------------------------------------------------------------- formulario -- */
.forma { display: flex; flex-direction: column; gap: 18px; }
.forma__campo { display: flex; flex-direction: column; gap: 6px; }
.forma__campo label {
    font-family: var(--f-titulo); font-weight: 600; font-size: 1.02rem;
    letter-spacing: .01em;
}
.forma__ayuda { font-size: .87rem; color: var(--tenue); }

.entrada, input[type="text"].entrada, input[type="email"].entrada,
input[type="password"].entrada, input[type="tel"].entrada,
input[type="number"].entrada, select.entrada, textarea.entrada {
    width: 100%;
    font-family: var(--f-texto); font-size: 1rem;
    color: var(--tinta); background: #fff;
    border: 1px solid var(--regla); border-radius: var(--radio-sm);
    padding: 11px 13px;
    transition: border-color .12s ease, box-shadow .12s ease;
}
.entrada:hover { border-color: #CBD2C5; }
.entrada:focus {
    outline: none;
    border-color: var(--piv-verde);
    box-shadow: 0 0 0 3px rgba(var(--piv-verde-rgb), .16);
}
.entrada[aria-invalid="true"] { border-color: var(--error); }
.entrada[aria-invalid="true"]:focus { box-shadow: 0 0 0 3px rgba(168,35,42,.14); }
textarea.entrada { min-height: 140px; resize: vertical; line-height: 1.55; }

/* El texto de la politica de contrasenias sale de Seguridad.REGLA_TEXTO, no se
   teclea en el HTML: si cambia la politica, cambia solo. */
.forma__regla { font-size: .87rem; color: var(--tenue); line-height: 1.45; }

.tarjeta-forma {
    background: #fff; border: 1px solid var(--regla); border-radius: var(--radio);
    padding: 32px; box-shadow: var(--sombra); max-width: 460px; width: 100%;
}
.tarjeta-forma h1 { font-size: 1.9rem; margin-bottom: .25em; }
.tarjeta-forma__pie {
    margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--regla-tenue);
    font-size: .95rem; color: var(--tinta-suave);
}

.centrado-pantalla {
    min-height: calc(100vh - 68px);
    display: flex; align-items: center; justify-content: center;
    padding: 48px 24px; background: var(--fondo-alt);
}

/* -------------------------------------------------------------- etiquetas -- */
.etiqueta {
    display: inline-block;
    font-family: var(--f-titulo); font-size: .82rem; font-weight: 600;
    letter-spacing: .06em; text-transform: uppercase;
    padding: 3px 9px; border-radius: 4px; white-space: nowrap;
}
.etiqueta--ok     { background: var(--ok-bg);     color: var(--ok); }
.etiqueta--espera { background: var(--alerta-bg); color: var(--alerta); }
.etiqueta--no     { background: var(--error-bg);  color: var(--error); }
.etiqueta--neutra { background: var(--regla-tenue); color: var(--tinta-suave); }

/* LOS MISMOS SUFIJOS QUE .aviso--, y por eso existen  (2026-08-24)

   El archivo tenia DOS vocabularios para lo mismo: los avisos usan
   --ok / --alerta / --error / --info, y las etiquetas usaban
   --ok / --espera / --no. Seis pantallas nuevas escribieron
   `etiqueta--alerta` y `etiqueta--error` por costumbre, y esas insignias
   salieron **sin color**, como texto plano: la clase no existia y el CSS
   no protesta por una regla que nadie definio.

   Se agregan con el nombre de la familia de avisos, que es el que la gente
   escribe sola. --espera y --no se quedan por lo que ya los usa; el dia que
   no quede ninguno, se van. */
.etiqueta--alerta { background: var(--alerta-bg); color: var(--alerta); }
.etiqueta--error  { background: var(--error-bg);  color: var(--error); }

/* ------------------------------------------------------------------ pie -- */
.pie { background: var(--piv-negro); color: #B9C0B4; padding: 52px 0 34px; font-size: .95rem; }
.pie a { color: #D6DDD2; }
.pie a:hover { color: #fff; }
.pie__caja { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 32px; }
.pie__logo img { height: 30px; width: auto; filter: brightness(0) invert(1); opacity: .9; }
.pie h4 { color: #fff; font-size: 1rem; margin-bottom: .7em; }
.pie ul { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 7px; }
.pie__legal {
    margin-top: 34px; padding-top: 20px;
    border-top: 1px solid rgba(255,255,255,.12);
    font-size: .88rem; color: #8A9285;
}

/* ------------------------------------------------------------ accesibles -- */
:focus-visible { outline: 2px solid var(--piv-verde); outline-offset: 2px; border-radius: 3px; }

.salta-al-contenido {
    position: absolute; left: -9999px; top: 0;
    background: var(--piv-verde); color: #fff;
    padding: 10px 18px; z-index: 100; border-radius: 0 0 var(--radio-sm) 0;
    font-family: var(--f-titulo); font-weight: 600;
}
.salta-al-contenido:focus { left: 0; color: #fff; }

.solo-lectores {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}

/* ---------------------------------------------------------------- varios -- */
.desbordable { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.mt-0 { margin-top: 0; } .mb-0 { margin-bottom: 0; }
.centrado { text-align: center; }
.pila { display: flex; flex-direction: column; gap: 14px; }
.fila { display: flex; flex-wrap: wrap; gap: 14px; align-items: center; }

img { max-width: 100%; height: auto; }

/* =============================================================================
   AGREGADO 2026-08-23 -- lo que pide la portada.

   Solo se AGREGA: ni una regla de arriba se toco. Estos bloques son los que la
   maqueta de Default.aspx necesita y que la primera version del archivo todavia
   no tenia, porque se escribio antes de que existiera una sola pagina.
   ============================================================================= */

/* --------------------------------------------- el boton de la esquina, nav -- */
.nav__menu li.nav__accion { margin-left: 10px; }

@media (max-width: 940px) {
    .nav__menu li.nav__accion { margin: 12px 0 4px; }
    .nav__menu li.nav__accion .btn { width: 100%; }
}

/* Sobre el fondo oscuro del hero, el boton de linea verde no se lee. */
.btn--linea-claro {
    background: transparent;
    color: #fff;
    border-color: rgba(255,255,255,.45);
    /* Sobre el hero oscuro el canto no puede ser una sombra: no se veria. Es
       un filo de luz, que ahi hace el mismo trabajo. */
    --btn-canto: rgba(255,255,255,.22);
    --btn-brillo: rgba(255,255,255,.10);
}
.btn--linea-claro:hover {
    background: rgba(255,255,255,.12);
    color: #fff;
    border-color: rgba(255,255,255,.72);
}

/* ------------------------------------------------------- hero con banner -- */
/* El banner es OPCIONAL: si la edicion no tiene uno cargado, el hero se queda
   con el fondo liso y el engrane, que ya se ve terminado. Cuando lo hay, la
   imagen va detras con un velo encima -- el sitio viejo ponia la foto a pelo y
   el texto blanco encima desaparecia. */
/* ESTE BLOQUE SE BORRO: era el banner puesto como FONDO del hero -- absoluto,
   recortado con object-fit, al 34% de opacidad y con un velo oscuro en degradado
   encima para que se leyera el titulo blanco.

   Nada de eso corre ya. El banner se pinta entero como lamina (ver el bloque
   "el banner" mas abajo), el titulo salio del hero, y `.hero--conBanner::before,
   ::after { content: none; }` impide que esos dos pseudo-elementos siquiera se
   generen. La regla base de `.hero__banner` tampoco alcanzaba a nada: el <img>
   solo existe dentro de `.hero--conBanner`, y ahi lo pisan tres reglas mas
   especificas.

   Se quitan porque eran cuatro capas de override sobre el mismo selector, y en
   una hoja de 99 KB eso es lo que hace que nadie sepa cual regla manda. */

@media (max-width: 700px) {
    .hero--conBanner { padding: 72px 0 60px; }
}

/* Sede, fecha, ventana de registro y tope de equipo. Es lo que el visitante
   busca antes de decidir si le toca. */
.hero__datos {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(178px, 1fr));
    gap: 22px 30px;
    margin: 38px 0 0;
    padding-top: 26px;
    border-top: 1px solid rgba(255,255,255,.16);
}
.hero__datos dt {
    font-family: var(--f-titulo);
    font-size: .82rem; font-weight: 600;
    letter-spacing: .12em; text-transform: uppercase;
    color: var(--piv-verde-claro);
    margin-bottom: 5px;
}
.hero__datos dd { margin: 0; color: #E7ECE3; font-size: 1.02rem; line-height: 1.4; }

/* --------------------------------------------------------------- avisos --- */
.aviso-zona { padding-top: 28px; }

/* ---------------------------------------------------- fichas de catalogo -- */
/* Areas y categorias: son etiqueta y nombre, no llevan parrafo. */
.ficha--compacta { padding: 20px 22px; }
.ficha--compacta h3 { font-size: 1.06rem; margin-bottom: 0; }

/* ================================== EL SELECTOR DE ICONO, EN EL PANEL =======

   Veintiun dibujos en rejilla, uno marcado. El radio de verdad esta ahi -- el
   teclado y los lectores de pantalla lo necesitan -- pero no se ve: lo que se
   ve es su dibujo, y el :checked del radio es quien lo enciende. Ese es todo
   el truco, y por eso no hace falta una linea de JavaScript.
   ========================================================================== */
.elige-icono {
    display: flex; flex-wrap: wrap; gap: 8px;
    margin-top: 6px;
}
.elige-icono__op { cursor: pointer; line-height: 0; }
/* Fuera de la vista pero NO display:none: asi sigue recibiendo el foco y se
   puede recorrer con el tabulador. */
.elige-icono__op input {
    position: absolute; width: 1px; height: 1px;
    opacity: 0; pointer-events: none;
}
.elige-icono__dibujo {
    display: inline-flex; align-items: center; justify-content: center;
    width: 42px; height: 42px; border-radius: 11px;
    background: #fff; border: 1px solid var(--regla); color: var(--tinta-suave);
    transition: border-color .14s ease, background .14s ease,
                color .14s ease, transform .14s ease;
}
.elige-icono__dibujo svg { width: 22px; height: 22px; display: block; }
.elige-icono__op:hover .elige-icono__dibujo {
    border-color: var(--piv-verde-claro); transform: translateY(-2px);
}
.elige-icono__op input:checked + .elige-icono__dibujo {
    background: var(--piv-verde); border-color: var(--piv-verde); color: #fff;
    box-shadow: inset 0 1px 0 rgba(255,255,255,.28), 0 2px 0 #1C4E34;
}
/* El foco se ve aunque el radio no: sin esto, quien va con el tabulador no
   sabe donde esta parado. */
.elige-icono__op input:focus-visible + .elige-icono__dibujo {
    outline: 2px solid var(--piv-verde-hondo); outline-offset: 2px;
}

/* ====================================================== LAS AREAS EN RELIEVE =

   Carlos, 2026-08-31: "que los botonsitos hagan algun efectito 3d... es en area
   de interes, pero pues en la parte publica".

   SON DIEZ TARJETAS IGUALES EN UNA REJILLA, y esa es justo la seccion donde un
   poco de volumen paga: sin el, la fila se lee como una tabla. El relieve va
   con la misma receta que los botones -- sombra solida para el canto, difusa
   para la elevacion -- para que el sitio tenga UN solo lenguaje de profundidad
   y no dos.

   AL PASAR EL RATON SE LEVANTA CUATRO PIXELES Y EL ICONO SE VOLTEA. El icono
   pasa de la pastilla lavada al verde lleno: es el unico movimiento de color
   de la seccion, asi que la tarjeta que se esta mirando se distingue sin
   necesidad de bordes ni subrayados.

   NO ES UN ENLACE Y NO PRETENDE SERLO. Estas tarjetas no llevan a ningun lado
   -- son el catalogo de areas --, asi que el gesto se queda en el hover: no hay
   :active que las hunda, porque no hay nada que pulsar.
   ========================================================================== */
.ficha--area {
    display: flex; flex-direction: column; align-items: flex-start; gap: 14px;
    box-shadow: 0 3px 0 var(--regla), 0 6px 14px rgba(31, 42, 34, .09);
    transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}
.ficha--area:hover {
    transform: translateY(-4px);
    border-color: var(--piv-verde-claro);
    box-shadow: 0 5px 0 var(--piv-verde-claro), 0 14px 26px rgba(31, 42, 34, .15);
}

/* La pastilla del icono lleva su propio relieve, mas chico: filo de luz arriba
   y dos pixeles de canto abajo. Es lo que hace que se vea como una ficha
   encima de la tarjeta y no como un cuadro pintado sobre ella. */
.area__icono {
    display: inline-flex; align-items: center; justify-content: center;
    width: 48px; height: 48px; border-radius: 15px;
    background: var(--piv-verde-lavado); color: var(--piv-verde-hondo);
    box-shadow: inset 0 1px 0 #fff, 0 2px 0 #CFE4D8;
    transition: transform .18s ease, background .18s ease,
                color .18s ease, box-shadow .18s ease;
}
/* El tamanio del dibujo lo manda el CSS y no el marcado: los svg del catalogo
   no traen width ni height, justamente para esto. */
.area__icono svg { width: 26px; height: 26px; display: block; }

.ficha--area:hover .area__icono {
    background: var(--piv-verde); color: #fff;
    transform: translateY(-2px) rotate(-4deg);
    box-shadow: inset 0 1px 0 rgba(255,255,255,.28), 0 3px 0 #1C4E34;
}

.ficha--area h3 { font-size: 1.06rem; margin: 0; }

/* Con el movimiento reducido se conserva el relieve -- que es informacion, dice
   que las tarjetas son piezas -- y se quita el salto y el giro. */
@media (prefers-reduced-motion: reduce) {
    .ficha--area, .area__icono { transition: background .18s ease, color .18s ease; }
    .ficha--area:hover { transform: none; }
    .ficha--area:hover .area__icono { transform: none; }
}

/* ------------------------------------------------------------ modalidades -- */
/* Los cinco textos de modalidad miden hasta 1,742 caracteres. Puestos uno tras
   otro sepultan el resto de la portada; en desplegables se ven los cinco
   titulos de golpe y se abre el que interesa. El sitio viejo los escondia en
   modales de Bootstrap, que en movil no se podian cerrar. */
.desplegable {
    background: #fff;
    border: 1px solid var(--regla);
    border-radius: var(--radio);
    box-shadow: var(--sombra);
    overflow: hidden;
}
.desplegable + .desplegable { margin-top: 0; }
.desplegable > summary {
    cursor: pointer;
    list-style: none;
    font-family: var(--f-titulo);
    font-weight: 600; font-size: 1.16rem;
    padding: 17px 24px;
    display: flex; align-items: center; justify-content: space-between; gap: 16px;
}
.desplegable > summary::-webkit-details-marker { display: none; }
.desplegable > summary::after {
    content: "+";
    color: var(--piv-verde);
    font-size: 1.5rem; line-height: 1; flex: 0 0 auto;
}
.desplegable[open] > summary::after { content: "\2212"; }
.desplegable > summary:hover { background: var(--piv-verde-lavado); }
.desplegable__cuerpo {
    padding: 2px 24px 20px;
    color: var(--tinta-suave);
    font-size: .99rem;
}

/* -------------------------------------------------------------- descargas -- */
.descarga::before {
    content: "";
    display: block;
    width: 34px; height: 3px;
    background: var(--piv-verde);
    border-radius: 2px;
    margin-bottom: 15px;
}
.descarga h3, .enlace-externo h3 { font-size: 1.1rem; margin-bottom: .3em; }
.descarga__pie, .enlace-externo__host {
    margin: 0;
    color: var(--tenue);
    font-size: .84rem;
    letter-spacing: .04em;
    word-break: break-word;
}

/* ------------------------------------------------------------------- pie -- */
.pie__edicion { margin: 16px 0 0; font-size: .95rem; line-height: 1.5; }

/* Un campo opcional vacio no debe dejar su renglon en blanco. La institucion
   del evaluador viene NULL en los 11 que estan cargados hoy, y sin esto cada
   tarjeta arrastra un hueco que parece un error de maquetacion. */
.evaluador__grado:empty,
.evaluador__inst:empty,
.contacto__cargo:empty { display: none; }

/* ---------------------------------------------------------------- utiles -- */
/* Dos columnas que NO se igualan de alto: cuando una trae tres parrafos y la
   otra uno, estirar la corta deja media tarjeta vacia. */
.rejilla--arriba { align-items: start; }

.mt-8  { margin-top: 8px; }
.mb-24 { margin-bottom: 24px; }


/* =============================================================================
   AGREGADO 2026-08-23 (segunda pasada) -- movimiento, jerarquia y visor de PDF.

   Carlos vio la portada y dijo que estaba correcta y plana: "estan bien
   estaticas la pagina, sin efectos, transiciones... hay partes que deberian
   tener negritas". Esto es lo que cierra eso.

   TRES REGLAS QUE GOBIERNAN TODO EL BLOQUE

   1. NADA SE ESCONDE SIN JAVASCRIPT. Todo lo que se oculta para animarlo
      cuelga de html.js, clase que pone sitio.js en su primera linea. Si ese
      archivo no carga, la clase no existe, la regla no aplica y la pagina se
      ve entera. El error clasico es al reves -- ocultar de entrada y confiar
      en que el JS lo enseniara -- y un 404 deja el sitio en blanco.

   2. prefers-reduced-motion APAGA EL MOVIMIENTO, NO EL CONTENIDO. Con esa
      preferencia activa todo aparece ya visible y sin transiciones. A quien la
      tiene puesta el movimiento le provoca mareo de verdad.

   3. SOLO SE ANIMAN opacity Y transform. Las dos las resuelve el compositor
      del navegador sin recalcular el flujo, asi que no hay salto de
      maquetacion. Animar height, margin o top si lo provocaria.
   ============================================================================= */

/* Un elemento con [hidden] esta oculto, punto. Sin esto, cualquier regla de
   display posterior -- la del boton de menu en su media query, sin ir mas
   lejos -- lo resucita, que es el bug clasico de este atributo. */
[hidden] { display: none !important; }

/* --------------------------------------------------------- nav sin JS ----- */
/* El boton de menu solo sirve si hay JavaScript que lo escuche: nace con
   [hidden] en el marcado y lo enciende sitio.js. Sin JS, en pantalla angosta,
   el menu se queda como lista visible en vez de dejar al visitante sin
   navegacion. */
@media (max-width: 940px) {
    html:not(.js) .nav__menu {
        display: flex;
        position: static;
        padding: 6px 0 14px;
        box-shadow: none;
        border-bottom: 0;
    }
}

/* --------------------------------------------- el encabezado al desplazar -- */
.nav {
    transition: box-shadow .2s ease, background-color .2s ease;
}
.nav__caja { transition: min-height .2s ease; }
.nav__logo img { transition: height .2s ease; }

.nav--compacto {
    box-shadow: 0 1px 0 var(--regla), 0 6px 22px -18px rgba(20,24,15,.5);
    background: rgba(255,255,255,.97);
}
.nav--compacto .nav__caja { min-height: 58px; }
.nav--compacto .nav__logo img { height: 29px; }

/* El nav es sticky: sin esto, saltar a #evaluadores deja el titulo debajo del
   encabezado. Va con scroll-margin y no con un padding falso, que romperia el
   espaciado de la seccion. */
section[id] { scroll-margin-top: 84px; }

/* ------------------------------------------------ aparicion de secciones -- */
/*  SE ESCONDE '.por-revelar', NO '[data-revela]'.

    La clase la pone el JavaScript en el instante en que va a observar el
    bloque. Antes esta regla miraba directamente [data-revela], que viene en el
    HTML: bastaba con que el JS no llegara a correr para que el sitio ENTERO
    quedara invisible -- y paso.

    Regla para lo que se escriba despues: nunca escondas con CSS algo que
    necesita JavaScript para volver a aparecer. */
.js [data-revela].por-revelar {
    opacity: 0;
    transform: translateY(20px);
    transition: opacity .55s cubic-bezier(.22,.61,.36,1),
                transform .55s cubic-bezier(.22,.61,.36,1);
    will-change: opacity, transform;
}
.js [data-revela].visible {
    opacity: 1;
    transform: none;
    will-change: auto;
}

/* El hero es lo primero que se ve: aparece solo, sin esperar al observador. */
.js .hero[data-revela] { transition-delay: .05s; }

/* Dentro de una seccion ya revelada, las tarjetas entran escalonadas. Es el
   unico adorno con retardo del sitio y no pasa de un cuarto de segundo. */
.js [data-revela].visible .rejilla > * {
    animation: piv-entra .45s cubic-bezier(.22,.61,.36,1) both;
}
.js [data-revela].visible .rejilla > *:nth-child(2) { animation-delay: .06s; }
.js [data-revela].visible .rejilla > *:nth-child(3) { animation-delay: .12s; }
.js [data-revela].visible .rejilla > *:nth-child(4) { animation-delay: .18s; }
.js [data-revela].visible .rejilla > *:nth-child(n+5) { animation-delay: .22s; }

@keyframes piv-entra {
    from { opacity: 0; transform: translateY(14px); }
    to   { opacity: 1; transform: none; }
}

/* -------------------------------------------------------- vida al tocar --- */
.ficha {
    transition: box-shadow .18s ease, border-color .18s ease, transform .18s ease;
}
.ficha--liga:hover,
.ficha--liga:focus-visible {
    transform: translateY(-3px);
}
/* Las tarjetas que no son enlace tambien responden, mas discretas: dan la
   sensacion de que la pagina esta viva sin prometer un clic que no existe. */
.ficha--compacta:hover { border-color: var(--piv-verde-claro); }

.calendario__fila { transition: background-color .15s ease; }
.calendario__fila:hover { background: var(--fondo-alt); }

.contacto { transition: border-color .15s ease; }
.contacto:hover { border-bottom-color: var(--piv-verde-claro); }

.desplegable { transition: border-color .18s ease, box-shadow .18s ease; }
.desplegable[open] { border-color: var(--piv-verde-claro); box-shadow: var(--sombra-alta); }

.evaluador details > summary,
.desplegable > summary { transition: color .15s ease, background-color .15s ease; }

/* ================================================== jerarquia y negritas ==

   Los textos llegan de la base como parrafos planos. Si todo pesa igual, el
   ojo no encuentra por donde entrar y la pagina se lee como un documento de
   Word. Se separan por TAMANIO, PESO Y ESPACIO -- los tres --, no solo por
   tamanio.

   Barlow Condensed carga los titulos y los datos; Barlow el texto corrido. Las
   dos ya estaban en el archivo: aqui se les da trabajo.
   ========================================================================= */

/* Los titulos grandes en condensada aguantan -- y piden -- el interletrado
   apretado. A tamanio de cartel, el espacio por omision los desarma. */
h1 { letter-spacing: -.012em; }
h2 { letter-spacing: -.008em; }

/* La entradilla de cada seccion: mas grande que el cuerpo, mas ligera que un
   titulo, y con su propia medida de linea. */
.seccion__cabeza p {
    font-size: 1.12rem;
    line-height: 1.55;
    max-width: 62ch;
}
.seccion__cabeza p:last-child { margin-bottom: 0; }

/* El primer parrafo de un bloque de convocatoria entra como entradilla. */
.entradilla > p:first-child {
    font-size: 1.18rem;
    line-height: 1.5;
    color: var(--tinta);
    font-weight: 500;
}

/* Lo que el administrador marque en negritas tiene que NOTARSE: en Barlow, un
   600 al lado del 400 se distingue; un 500 no. */
strong, b { font-weight: 700; color: var(--tinta); }
.hero strong, .hero b { color: #fff; }

/* --- Las cifras y los datos duros ---------------------------------------- */
/* Fechas, cuotas y tope de equipo son lo que la gente viene a buscar. Se les
   da peso propio y numeros de ancho fijo, para que una columna de cantidades
   quede alineada por la coma y no bailando. */
.calendario__cuando {
    font-size: 1.12rem;
    font-variant-numeric: tabular-nums;
    letter-spacing: .004em;
}
.calendario__que { font-weight: 500; }

.hero__datos dd {
    font-weight: 500;
    font-variant-numeric: tabular-nums;
}

/* La pastilla de estado es el dato mas importante del hero. */
.hero__estado { font-weight: 600; letter-spacing: .01em; }

/* El titulo de una tarjeta pesa mas que su cuerpo, siempre. */
.ficha h3 { font-weight: 600; }
.paso h3 { font-weight: 700; }

/* La etiqueta de area o categoria es un dato, no una decoracion: monoespaciada
   y en su color, para que se lea como codigo de clasificacion. */
.ficha--compacta .etiqueta { font-family: var(--f-dato); font-size: .74rem; }

/* --- Ritmo de las listas -------------------------------------------------- */
/* Los parrafos de un bloque largo respiran entre si; el ultimo no arrastra
   margen y descuadra la tarjeta. */
.desplegable__cuerpo p + p,
.evaluador__semblanza p + p { margin-top: .85rem; }
.desplegable__cuerpo p:last-child,
.evaluador__semblanza p:last-child { margin-bottom: 0; }

.pila > * + * { margin-top: 14px; }

/* ================================================================ visor ===

   El triptico y los formatos se abrian de golpe en otra pestania: el PDF
   crudo, sin el nombre del documento y sin manera de volver salvo el boton de
   atras. Ahora se abren aqui encima, con su titulo y su descarga.

   La capa vive en el DOM solo mientras hace falta; el marcado lo arma
   sitio.js. Si ese archivo no carga, estas reglas no llegan a usarse nunca y
   el enlace abre el PDF como siempre.
   ========================================================================= */
.visor {
    position: fixed;
    top: 0; right: 0; bottom: 0; left: 0;
    z-index: 200;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 32px;
    opacity: 0;
    transition: opacity .2s ease;
}
.visor--abierto { opacity: 1; }

.visor__fondo {
    position: absolute;
    top: 0; right: 0; bottom: 0; left: 0;
    background: rgba(20,24,15,.72);
    backdrop-filter: blur(2px);
}

.visor__caja {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    width: min(1040px, 100%);
    height: min(88vh, 100%);
    background: #fff;
    border-radius: var(--radio);
    box-shadow: var(--sombra-alta);
    overflow: hidden;
    transform: translateY(12px) scale(.99);
    transition: transform .22s cubic-bezier(.22,.61,.36,1);
}
.visor--abierto .visor__caja { transform: none; }

.visor__barra {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 18px;
    padding: 14px 16px 14px 22px;
    border-bottom: 1px solid var(--regla);
    background: var(--fondo-alt);
    flex: 0 0 auto;
}
.visor__titulo {
    margin: 0;
    font-size: 1.24rem;
    font-weight: 600;
    line-height: 1.2;
    /* Un titulo largo no empuja los botones fuera de la caja. */
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.visor__acciones { display: flex; align-items: center; gap: 10px; flex: 0 0 auto; }

.visor__cerrar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 38px; height: 38px;
    font-size: 1.6rem; line-height: 1;
    color: var(--tinta-suave);
    background: transparent;
    border: 1px solid var(--regla);
    border-radius: var(--radio-sm);
    cursor: pointer;
    transition: background-color .15s ease, color .15s ease, border-color .15s ease;
}
.visor__cerrar:hover {
    background: var(--error-bg);
    border-color: #EDC6C6;
    color: var(--error);
}

.visor__marco {
    flex: 1 1 auto;
    width: 100%;
    border: 0;
    background: var(--regla-tenue);
}

/* El fondo no se desplaza mientras el dialogo esta abierto. El ancho de la
   barra que desaparece lo compensa sitio.js con padding, para que la pagina no
   pegue un brinco lateral al abrir. */
body.sin-scroll { overflow: hidden; }

@media (max-width: 760px) {
    .visor { padding: 0; }
    .visor__caja { width: 100%; height: 100%; border-radius: 0; }
    .visor__barra { padding: 12px 12px 12px 16px; }
    .visor__titulo { font-size: 1.08rem; }
}

/* ------------------------------------------------------ menos movimiento -- */
/* Va al final a proposito: tiene que poder anular todo lo de arriba.
   Se apaga el MOVIMIENTO, nunca el contenido. */
@media (prefers-reduced-motion: reduce) {
    .js [data-revela].por-revelar {
        opacity: 1 !important;
        transform: none !important;
        transition: none !important;
    }
    .js [data-revela].visible .rejilla > * {
        animation: none !important;
    }
    .nav, .nav__caja, .nav__logo img,
    .ficha, .calendario__fila, .contacto, .desplegable,
    .visor, .visor__caja, .visor__cerrar {
        transition: none !important;
    }
    .ficha--liga:hover, .ficha--liga:focus-visible { transform: none; }
    .visor__caja { transform: none; }
}

/* =============================================================================
   AGREGADO 2026-08-23 (tercera pasada) -- patrocinadores, botones y cierre.

   Carlos: "donde estan los banner que salian en la pagina principal, son los
   patrocinadores del evento... faltan botones que dejaste en puro texto,
   concluye bien la pagina".

   Las tres cosas se arreglan aqui: la franja de logos, la forma de boton para
   todo lo que sea una accion, y un cierre para que la pagina no termine en
   seco con el ultimo correo de contacto.
   ============================================================================= */

/* ------------------------------------------------------ botones de bloque -- */
/* En una tarjeta de formulario, un boton del ancho de su texto flota suelto en
   el hueco. El principal ocupa el ancho completo y el secundario debajo, del
   mismo ancho: la pila queda alineada y se lee de arriba abajo. */
.btn--bloque { display: flex; width: 100%; }

.tarjeta-forma__nota {
    margin: 0 0 10px;
    font-size: .95rem;
    color: var(--tinta-suave);
    text-align: center;
}
.tarjeta-forma__terciario { margin-top: 16px; font-size: .93rem; }

/* Escribirle a un contacto es una accion. Antes era un correo subrayado que no
   parecia pulsable; ahora tiene su caja, y el correo se sigue leyendo. */
.contacto__btn {
    align-self: flex-start;
    margin-top: 8px;
    max-width: 100%;
    font-family: var(--f-texto);
    font-size: .9rem;
    font-weight: 500;
    letter-spacing: 0;
    /* Un correo largo no puede empujar la tarjeta. */
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.contacto__btn:hover { border-color: var(--piv-verde-claro); background: var(--piv-verde-lavado); }

/* --------------------------------------------------- cabeza centrada ------ */
.seccion__cabeza--centrada { margin-left: auto; margin-right: auto; }
.filo--centrado::after { margin-left: auto; margin-right: auto; }

/* ============================================== franja de patrocinadores ==

   EN ESCALA DE GRISES, Y NO ES UN CAPRICHO. Cinco marcas con cinco paletas --
   el rojo de Coca-Cola, el azul de Telmex -- puestas a todo color a media
   pagina se comen la atencion que le toca a la convocatoria. Apagadas se leen
   como lo que son, un respaldo; y al pasar el mouse cada una recupera su
   color, que es cuando alguien la esta mirando de verdad.
   ======================================================================== */
.cinta {
    position: relative;
    overflow: hidden;
    padding: 10px 0;
}

/* Los logos entran y salen desvanecidos por los costados en vez de cortarse de
   golpe contra el borde. */
.js .cinta--anima::before,
.js .cinta--anima::after {
    content: "";
    position: absolute;
    top: 0; bottom: 0;
    width: 90px;
    z-index: 2;
    pointer-events: none;
}
.js .cinta--anima::before { left: 0;  background: linear-gradient(90deg,  var(--fondo-alt), rgba(247,249,245,0)); }
.js .cinta--anima::after  { right: 0; background: linear-gradient(270deg, var(--fondo-alt), rgba(247,249,245,0)); }

.cinta__pista {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 56px;
    flex-wrap: wrap;
}

/* Solo cuando sitio.js duplico los logos se convierte en cinta continua: con
   una sola copia, la animacion dejaria un hueco al dar la vuelta. */
.js .cinta--anima .cinta__pista {
    flex-wrap: nowrap;
    justify-content: flex-start;
    width: max-content;
    animation: piv-cinta 34s linear infinite;
    /* SIN gap cuando la cinta gira, y la separacion pasa al padding de cada
       logo. Con gap, el ancho total es 2*(logos) + (2n-1)*separacion, asi que
       un translateX(-50%) se queda a media separacion del punto de partida y
       la cinta pega un tironcito en cada vuelta. Metida en el padding, cada
       logo mide siempre lo mismo, el total es el doble exacto y el bucle
       empalma sin costura. */
    gap: 0;
}
.js .cinta--anima .patrocinador { padding-left: 28px; padding-right: 28px; }
/* Se detiene al pasar el mouse: si no, hacer clic en un logo es punteria. */
.js .cinta--anima:hover .cinta__pista,
.js .cinta--anima:focus-within .cinta__pista { animation-play-state: paused; }

@keyframes piv-cinta {
    from { transform: translateX(0); }
    to   { transform: translateX(-50%); }
}

/*  PARCHE, Y HAY QUE QUITARLO CUANDO LLEGUEN LOS LOGOS DE VERDAD.

    Los cinco archivos de img/patrocinadores/ NO son logos: son capturas de
    pantalla verticales de 1287x2579 -- las cinco exactamente del mismo tamanio
    -- con el logo real ocupando como el 22% del alto, centrado, y todo lo
    demas blanco. Puestas con object-fit: contain a 72px de alto, el logo sale
    a 16 pixeles: un sello ilegible. Se ve en la portada.

    Mientras tanto se recortan por CSS: la ventana tiene medida fija, la imagen
    va MUCHO mas grande dentro y lo que sobra se corta. Funciona porque las
    cinco comparten dimension y composicion.

    ESTO ES FRAGIL A PROPOSITO Y ESTA ESCRITO AQUI PARA QUE SE NOTE. El dia que
    alguien suba un PNG recortado de verdad, esta regla se lo va a comer. La
    solucion buena es recortar los archivos; entonces se borra este bloque y se
    vuelve a un simple height + object-fit: contain. */
.patrocinador {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 200px;
    height: 88px;
    /* Aire a los lados para que dos logos anchos seguidos no se toquen. Antes
       era 0 porque la imagen venia recortada por la ventana; ahora cabe entera
       y el relleno es lo que la separa de la de al lado. */
    padding: 6px 10px;
    text-decoration: none;
}
/* EL LOGO SE MUESTRA ENTERO, NO SE RECORTA.

   Aqui habia `height: 310px` con el comentario "~4x la ventana: sube la banda
   del logo a ~68px". Era un recorte a proposito, hecho cuando los archivos eran
   capturas de pantalla de 1287x2579 con el logo perdido en medio de mucho
   blanco: agrandarlos y asomarse por una ventana de 88 px era la manera de
   encuadrarlos sin editar imagen por imagen.

   Esos archivos ya no son esos. Los de ahora vienen recortados a su contenido
   -- el primero mide 967x225 --, asi que estirarlos a 310 px de alto dentro de
   una ventana de 88 los partia por la mitad: se veia una franja horizontal del
   dibujo, sin principio ni final. Un truco que resolvia un problema sobrevivio
   al problema.

   Lo correcto para un conjunto de logos de proporciones distintas es dejar que
   cada uno se acomode dentro de la caja: `contain` respeta su proporcion y no
   recorta nada. El que es ancho toca los lados, el que es alto toca arriba y
   abajo, y los dos se ven completos. */
.patrocinador__logo {
    flex: 0 1 auto;
    max-width: 100%;
    max-height: 100%;
    width: auto;
    height: auto;
    object-fit: contain;
    filter: grayscale(1);
    opacity: .72;
    transition: filter .25s ease, opacity .25s ease, transform .25s ease;
}
.patrocinador:hover .patrocinador__logo,
.patrocinador:focus-visible .patrocinador__logo {
    filter: none;
    opacity: 1;
    transform: scale(1.05);
}

@media (max-width: 700px) {
    .cinta__pista { gap: 34px; }
    .patrocinador { width: 150px; height: 68px; padding: 4px 8px; }
    /* Sin altura forzada: la caja encoge y el logo se acomoda solo dentro. */
}

/* ------------------------------------------- progreso de "como participar" -- */
/* El numero de cada paso ya decia el orden; faltaba VERLO como un recorrido.
   La linea une un paso con el siguiente y se dibuja de izquierda a derecha
   cuando la seccion entra en pantalla. */
.paso__num {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 52px; height: 52px;
    font-size: 1.7rem;
    color: var(--piv-verde-hondo);
    background: var(--piv-verde-lavado);
    border: 2px solid var(--piv-verde-claro);
    border-radius: 50%;
    margin-bottom: 16px;
}

@media (min-width: 941px) {
    .rejilla--4 .paso::after {
        content: "";
        position: absolute;
        top: 34px;
        right: -23px;
        width: 23px;
        height: 2px;
        background: var(--piv-verde-claro);
    }
    .rejilla--4 .paso:last-child::after { display: none; }

    .js [data-revela] .rejilla--4 .paso::after {
        transform: scaleX(0);
        transform-origin: left center;
        transition: transform .45s ease .35s;
    }
    .js [data-revela].visible .rejilla--4 .paso::after { transform: scaleX(1); }
}

/* --------------------------------------------------- profundidad al tocar -- */
/* Las tarjetas se levantan un poco. Tres pixeles y una sombra: lo justo para
   que la pagina responda, no para que salte. */
.ficha:hover { box-shadow: var(--sombra-alta); }
.ficha--liga:hover h3, .ficha--liga:focus-visible h3 { color: var(--piv-verde-hondo); }

/* =================================================================== cierre ==

   La pagina terminaba en el ultimo correo de contacto y de golpe el pie. Quien
   bajo leyendo entero ya esta convencido, y el boton de inscribirse se quedo
   arriba del todo, seis secciones atras.
   ========================================================================== */
.cierre {
    position: relative;
    overflow: hidden;
    background: var(--piv-negro);
    color: #fff;
    padding: 92px 0;
}
/* El mismo engrane del hero, al otro lado: las dos puntas de la pagina se
   cierran con el mismo gesto. */
.cierre::before {
    content: "";
    position: absolute;
    left: -160px; bottom: -180px;
    width: 480px; height: 480px;
    border: 68px solid var(--piv-verde);
    border-radius: 50%;
    opacity: .15;
    pointer-events: none;
}
.cierre__caja {
    position: relative;
    z-index: 1;
    text-align: center;
    max-width: 64ch;
}
.cierre .eyebrow { color: var(--piv-verde-claro); }
.cierre h2 { color: #fff; margin-bottom: .35em; }
.cierre__leyenda {
    font-size: 1.16rem;
    color: #D6DDD2;
    margin-bottom: 30px;
}
.cierre__acciones {
    display: flex;
    gap: 14px;
    flex-wrap: wrap;
    justify-content: center;
}

@media (max-width: 700px) {
    .cierre { padding: 64px 0; }
    .cierre::before { width: 300px; height: 300px; border-width: 44px; left: -120px; bottom: -140px; }
    .cierre__acciones .btn { width: 100%; }
}

/* ------------------------------------------------------- menos movimiento -- */
@media (prefers-reduced-motion: reduce) {
    .js .cinta--anima .cinta__pista {
        animation: none !important;
        flex-wrap: wrap;
        justify-content: center;
        width: auto;
    }
    .js .cinta--anima::before, .js .cinta--anima::after { display: none; }

    .patrocinador__logo { transition: none !important; }
    .patrocinador:hover .patrocinador__logo { transform: none; }

    .js [data-revela] .rejilla--4 .paso::after,
    .js [data-revela].visible .rejilla--4 .paso::after {
        transform: none !important;
        transition: none !important;
    }
}

@media print {
    .nav, .pie, .btn, .hero::before { display: none !important; }
    body { font-size: 12pt; color: #000; }
    /* Un desplegable cerrado no se imprime, y el papel no se despliega. */
    .desplegable__cuerpo { display: block !important; }
}

/* ============================================== enfasis en "como participar" ==

   Los cuatro pasos ya se levantaban con una sombra, pero nada mas. Carlos:
   "los cuadritos, no podrian hacer un efecto un poco mas bonito, como que el
   cuadrito sube un poquito, como cuando das enfasis a leer algo", y "estaria
   bien que los numeritos como que se alumbran en color verde".

   Dos gestos, no cinco. El que se acerca a leer un paso lo ve subir un poco y
   ve su numero encenderse; el resto de la pagina no se mueve. Un efecto que
   compite con el contenido deja de ser enfasis y pasa a ser ruido.
   ========================================================================== */

.paso {
    transition: transform .22s cubic-bezier(.22, .61, .36, 1),
                box-shadow .22s ease,
                border-color .22s ease;
}

/* El cuadrito sube. SEIS pixeles: suficiente para que se sienta, poco para que
   no descuadre la fila. Y la sombra crece con el, porque un objeto que sube sin
   que su sombra cambie se ve pegado al fondo. */
.paso:hover,
.paso:focus-within {
    transform: translateY(-6px);
    box-shadow: var(--sombra-alta);
    border-color: var(--piv-verde-claro);
}

/* El numero se enciende: pasa de contorno a verde solido, y el halo lo separa
   del resto sin necesidad de agrandarlo mucho.

   El :focus-within va junto al :hover a proposito. Quien recorre la pagina con
   el teclado merece el mismo enfasis que quien la recorre con el raton, y
   cuesta una linea. */
.paso__num {
    transition: background-color .22s ease,
                color .22s ease,
                border-color .22s ease,
                box-shadow .22s ease,
                transform .22s cubic-bezier(.22, .61, .36, 1);
}

.paso:hover .paso__num,
.paso:focus-within .paso__num {
    background: var(--piv-verde);
    border-color: var(--piv-verde);
    color: #fff;
    transform: scale(1.06);
    box-shadow: 0 0 0 6px rgba(var(--piv-verde-rgb), .16),
                0 6px 16px -6px rgba(var(--piv-verde-rgb), .55);
}

/* Y el tramo de linea que sale de ese paso se pinta mas fuerte: el recorrido
   avanza con la lectura. */
.paso:hover::after,
.paso:focus-within::after {
    background: var(--piv-verde);
}

/* QUIEN PIDIO QUE NADA SE MUEVA, SIGUE TENIENDO EL ENFASIS.

   Se apagan el desplazamiento y la escala -- que son lo que marea -- y se
   conserva el color. Apagar el efecto entero dejaria a esa persona sin saber
   que paso esta mirando, que es justo lo que el efecto resuelve. */
@media (prefers-reduced-motion: reduce) {
    .paso,
    .paso__num {
        transition: background-color .01ms, color .01ms, border-color .01ms;
    }
    .paso:hover,
    .paso:focus-within {
        transform: none;
    }
    .paso:hover .paso__num,
    .paso:focus-within .paso__num {
        transform: none;
        box-shadow: none;
    }
}

/* =================================================== chispas del evaluador ==

   Carlos: "en los cuadritos de los Evaluadores, estaria bien que al pasar el
   mouse sobre uno se vean como estrellitas que salen del cuadrito de color
   verde algo asi animadillo".

   Seis chispas que brotan del borde y se apagan. Salen HACIA AFUERA -- de ahi
   que la tarjeta no recorte -- y cada una lleva su propio retardo, para que
   parezca un chispazo y no seis luces encendiendose a la vez.

   POR QUE SON <i> VACIOS Y NO PSEUDOELEMENTOS
   Con ::before y ::after solo caben dos, y dos chispas no se leen como
   chispas: se leen como dos puntos. Van en el marcado con aria-hidden, asi
   que para un lector de pantalla la tarjeta sigue teniendo exactamente lo que
   tenia.

   NUNCA ATRAPAN EL RATON: pointer-events none. Un adorno que se coma un clic
   sobre el nombre del evaluador dejaria de ser adorno y pasaria a ser un
   defecto.
   ========================================================================== */

.evaluador { position: relative; overflow: visible; }

.chispas {
    position: absolute;
    inset: 0;
    pointer-events: none;
    z-index: 2;
}

.chispas i {
    position: absolute;
    width: 14px; height: 14px;
    background: var(--piv-verde);
    /* Estrella de cuatro puntas, con la cintura hundida para que brille en vez
       de parecer un rombo. */
    clip-path: polygon(50% 0%, 60% 40%, 100% 50%, 60% 60%,
                       50% 100%, 40% 60%, 0% 50%, 40% 40%);
    opacity: 0;
    transform: scale(0);
}

/*  CADA CHISPA SALE HACIA SU LADO -- ES LO QUE LA VUELVE CELEBRACION.

    La primera version movia las seis en la MISMA direccion (arriba y a la
    derecha) y con retardos escalonados. Carlos: "las estrellitas parecen que
    se caen, mejor como que se expandan como una celebracion". Y es exacto: seis
    cosas moviendose juntas hacia un lado se leen como algo que cae o que arrastra
    el viento. Lo que se lee como festejo es lo contrario -- todas saliendo del
    centro a la vez, cada una hacia afuera.

    Dos cambios, y los dos importan:

    1. LA DIRECCION LA DA SU POSICION. Cada chispa declara su --dx y su --dy
       apuntando hacia AFUERA de la tarjeta desde donde esta: la de arriba a la
       izquierda sale arriba y a la izquierda, la de la derecha sale a la
       derecha. El fotograma es uno solo y usa esas dos variables, asi que
       agregar una septima chispa es agregar un renglon.

    2. LOS RETARDOS SE ACORTAN. Iban de 0 a .78s -- casi un segundo entre la
       primera y la ultima, que es lo que las hacia parecer una fila. Ahora van
       de 0 a .12s: lo justo para que no salgan clonadas, no tanto como para
       que se vean en turnos.

    Repartidas por el contorno, ninguna sobre el centro, que es donde vive el
    texto. */
.chispas i:nth-child(1) { top: -8px;   left: 14%;    --dx: -14px; --dy: -18px; }
.chispas i:nth-child(2) { top: -12px;  right: 22%;   --dx:  12px; --dy: -20px; width: 10px; height: 10px; }
.chispas i:nth-child(3) { top: 28%;    right: -10px; --dx:  22px; --dy:  -6px; }
.chispas i:nth-child(4) { bottom: 24%; left: -11px;  --dx: -22px; --dy:   6px; width: 11px; height: 11px; }
.chispas i:nth-child(5) { bottom: -9px;  left: 34%;  --dx:  -8px; --dy:  20px; width: 9px; height: 9px; }
.chispas i:nth-child(6) { bottom: -12px; right: 16%; --dx:  16px; --dy:  18px; }

/*  EL ESTALLIDO.

    Nace en el centro de su sitio, crece de golpe, sale hacia afuera y se apaga
    mientras se aleja. El pico de tamanio va temprano -- al 30% -- porque asi es
    como se ve algo que estalla: rapido al salir y desacelerando, no a velocidad
    constante.

    El giro es corto (90 grados, no 180): una estrella que gira media vuelta se
    lee como algo que da vueltas cayendo. Un cuarto de vuelta apenas la hace
    brillar. */
@keyframes chispazo {
      0% { opacity: 0;  transform: translate(0, 0) scale(0) rotate(0deg); }
     18% { opacity: 1;  transform: translate(calc(var(--dx) * .25), calc(var(--dy) * .25)) scale(1) rotate(20deg); }
     30% { opacity: 1;  transform: translate(calc(var(--dx) * .45), calc(var(--dy) * .45)) scale(1.25) rotate(35deg); }
     70% { opacity: .8; transform: translate(calc(var(--dx) * .85), calc(var(--dy) * .85)) scale(.9) rotate(70deg); }
    100% { opacity: 0;  transform: translate(var(--dx), var(--dy)) scale(.2) rotate(90deg); }
}

.evaluador:hover .chispas i,
.evaluador:focus-within .chispas i {
    animation: chispazo 1.1s cubic-bezier(.18, .82, .32, 1) infinite;
}

/* Apenas desfasadas: juntas, pero no clonadas. */
.chispas i:nth-child(2) { animation-delay: .04s; }
.chispas i:nth-child(3) { animation-delay: .09s; }
.chispas i:nth-child(4) { animation-delay: .02s; }
.chispas i:nth-child(5) { animation-delay: .12s; }
.chispas i:nth-child(6) { animation-delay: .06s; }

/* La tarjeta acompania: sube un poco y se le enciende el borde, igual que los
   pasos. El gesto es el mismo en toda la pagina. */
.evaluador {
    transition: transform .22s cubic-bezier(.22, .61, .36, 1),
                box-shadow .22s ease,
                border-color .22s ease;
}
.evaluador:hover,
.evaluador:focus-within {
    transform: translateY(-5px);
    box-shadow: var(--sombra-alta);
    border-color: var(--piv-verde-claro);
}

/* Sin movimiento, sin chispas. Aqui SI se apagan del todo: a diferencia del
   numero de los pasos, esto no informa de nada -- es adorno, y un adorno que
   marea es solo un problema. */
@media (prefers-reduced-motion: reduce) {
    .chispas { display: none; }
    .evaluador { transition: border-color .01ms; }
    .evaluador:hover,
    .evaluador:focus-within { transform: none; }
}

/* =============================================================================
   AGREGADO 2026-08-23 (cuarta pasada) -- la tabla de cuotas, el banner como
   lamina, los enlaces con hijos, y el gesto propio de cada seccion.

   Carlos: "donde estan los precios y las fechas???", "aqui que solo sean 2
   cuadritos... y que en la revista muestre el link de los numeros anteriores",
   y "quiero que a los demas cuadritos de las otras secciones, les pongas
   efectos bonitos".

   SOBRE LOS EFECTOS: cada seccion tiene UN gesto y no el mismo. Las chispas de
   los evaluadores no se repiten en ningun otro lado a proposito -- lo que en
   una seccion es un detalle bonito, en seis es ruido. La familia se mantiene
   con lo que SI se comparte: el mismo verde, la misma curva y los mismos
   tiempos.
   ========================================================================== */

/* ================================================== el banner como lamina ==

   El banner de esta edicion -- banner30piv-web.jpg, 1920x960 -- es BLANCO: los
   logos de UANL y FIME arriba, la fecha, los tres numerales del congreso y una
   fila de logos abajo, todo en gris oscuro sobre blanco.

   De fondo del hero no funcionaba de ninguna de las dos maneras posibles:
   recortado a la altura del hero se perdian los logos y la fecha, y bajado de
   opacidad bajo el velo oscuro quedaba una mancha gris donde ya no se leia ni
   el banner ni el titulo encima.

   Asi que va entero, en su propia franja clara arriba del bloque oscuro. Sin
   recorte, sin deformarlo -- la imagen conserva su proporcion sola porque solo
   se le limita el ancho y el alto MAXIMOS, nunca los dos a la vez -- y sin
   nada escrito encima. El titulo y los botones se quedan donde siempre se
   leyeron bien.
   ========================================================================== */

.hero__lamina {
    position: relative;
    z-index: 1;
    background: #fff;
    line-height: 0;
}

/* A TODO LO ANCHO Y ENTERO. Carlos: "el banner que este grande, asi como en la
   pagina anterior". Ancho 100% y alto automatico: la proporcion la decide la
   imagen, asi que no hay manera de deformarla ni de recortarla. El tope de
   1920 es su tamanio real -- estirarla mas alla solo la volveria borrosa. */
.hero--conBanner .hero__banner {
    /* Se anula el fondo de la pasada anterior: ahi la imagen estaba absoluta,
       recortada con object-fit y bajada de opacidad. Aqui vuelve a ser una
       imagen normal, en el flujo, entera y opaca. */
    position: static;
    top: auto; right: auto; bottom: auto; left: auto;
    z-index: auto;
    object-fit: fill;
    opacity: 1;

    display: block;
    width: 100%;
    height: auto;
    max-width: 1920px;
    margin: 0 auto;
}

/* La lamina va pegada al borde de arriba del hero: el relleno del hero empieza
   despues de ella. Y el bloque oscuro se encoge, porque ya no lleva titulo:
   son la pastilla de estado, dos botones y los datos. */
.hero--conBanner { padding: 0 0 54px; }
.hero--conBanner .contenedor { padding-top: 40px; }
.hero--conBanner .hero__caja { max-width: none; }

/* EL BLOQUE OSCURO, RECOMPUESTO. Sin el titulo, la pastilla y los botones
   quedaban uno debajo del otro con medio ancho vacio a la derecha. En un
   renglon -- estado a la izquierda, accion a la derecha -- la franja se lee de
   un vistazo y ya no parece que falte algo. */
.hero__cima {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 18px 30px;
}
.hero__cima .hero__estado { margin-bottom: 0; }

/* Aqui se reposicionaba el engrane del hero cuando habia banner. Se borro por
   la misma razon que el bloque de arriba: `.hero--conBanner::before { content:
   none; }` impide que el pseudo-elemento se genere, asi que estas ocho
   propiedades no podian aplicarse a nada. El anillo verde sobre el blanco del
   banner se veia como un arco palido asomando en la esquina -- suciedad de la
   imagen, no marca de agua --, y por eso se apago. */

@media (max-width: 700px) {
    .hero--conBanner { padding-bottom: 40px; }
    .hero--conBanner .contenedor { padding-top: 30px; }
    .hero__cima { gap: 16px; }
    .hero__cima .hero__acciones { width: 100%; }
    .hero__cima .hero__acciones .btn { flex: 1 1 auto; justify-content: center; }
}

/* ====================================================== calendario y cuotas ==

   Dos columnas DESIGUALES. auto-fit las reparte a partes iguales, y aqui una
   es una lista de cuatro renglones cortos y la otra una tabla de tres columnas
   con importes: darles el mismo ancho aprieta la tabla sin necesidad.
   ========================================================================== */

.rejilla--calendario {
    grid-template-columns: minmax(250px, .78fr) minmax(330px, 1.22fr);
    gap: 40px;
}

@media (max-width: 940px) {
    .rejilla--calendario { grid-template-columns: 1fr; gap: 36px; }
}

/* El calendario se apila SIEMPRE dentro de esta rejilla. A dos columnas la
   fecha va a la derecha sin partirse, y aqui hay fechas de 48 caracteres --
   "Del 12 de Octubre hasta el 17 de Noviembre del 2026" -- que en una columna
   de 430px se comian el ancho y dejaban la descripcion en una palabra por
   renglon. Descripcion arriba, fecha debajo: se lee sin apreturas y la fecha
   sigue destacando por color y peso. */
.rejilla--calendario .calendario__fila {
    grid-template-columns: 1fr;
    gap: 4px;
}
.rejilla--calendario .calendario__cuando {
    text-align: left;
    white-space: normal;
}

/* --------------------------------------------------------- la tabla ------- */
/* El marco existe por si la tabla no cabe en un ancho intermedio -- entre que
   deja de haber dos columnas y que la tabla se desarma en tarjetas. Sin el, la
   tabla empujaria el ancho de la PAGINA y aparecerian barras horizontales en
   todo el sitio, que es el defecto clasico de meter una tabla en una
   maquetacion fluida. */
.cuotas__marco {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

.cuotas__tabla {
    width: 100%;
    border-collapse: collapse;
    font-size: .98rem;
}

.cuotas__tabla thead th {
    vertical-align: bottom;
    padding: 0 0 12px 16px;
    border-bottom: 2px solid var(--piv-verde);
    font-family: var(--f-titulo);
    font-weight: 600;
    text-align: right;
}
.cuotas__tabla thead th.cuotas__quien {
    text-align: left;
    padding-left: 14px;
}

.cuotas__cuando { display: block; font-size: 1.05rem; line-height: 1.15; }
.cuotas__fecha {
    display: block;
    margin-top: 4px;
    font-size: .74rem;
    font-weight: 400;
    letter-spacing: .01em;
    color: var(--tenue);
    white-space: normal;
}

.cuotas__tabla tbody th,
.cuotas__tabla tbody td {
    padding: 13px 0 13px 16px;
    border-bottom: 1px solid var(--regla-tenue);
}
.cuotas__tabla tbody tr:last-child th,
.cuotas__tabla tbody tr:last-child td { border-bottom: 0; }

.cuotas__tabla tbody th.cuotas__quien {
    position: relative;
    padding-left: 14px;
    text-align: left;
    font-family: var(--f-texto);
    font-size: 1rem;
    font-weight: 600;
}

.cuotas__monto {
    text-align: right;
    white-space: nowrap;
    font-family: var(--f-dato);
    font-variant-numeric: tabular-nums;
}
.cuotas__cifra { font-size: 1.04rem; font-weight: 600; }
.cuotas__moneda { font-size: .76rem; color: var(--tenue); }

/* SIN CUOTA ES UNA LEYENDA, NO UN NUMERO.

   FIME no paga. Pintar "0.00" diria que hay un cobro de cero pesos y dejarlo en
   blanco pareceria un dato que falta por capturar; las dos cosas son mentira.
   Va como pastilla verde, que se lee de un vistazo y no se confunde con una
   cifra. */
.cuotas__sin {
    display: inline-block;
    padding: 3px 12px;
    border-radius: 999px;
    background: var(--ok-bg);
    color: var(--ok);
    font-family: var(--f-texto);
    font-size: .76rem;
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
    white-space: nowrap;
}

/* EL GESTO DE ESTA SECCION: el renglon se ilumina y le sale una marca verde al
   margen. Es una tabla de precios -- lo que hace falta es no perder el renglon
   que se esta leyendo, que es distinto de que una tarjeta salte. */
.cuotas__tabla tbody tr { transition: background-color .18s ease; }
.cuotas__tabla tbody tr:hover { background: var(--piv-verde-lavado); }

.cuotas__tabla tbody th.cuotas__quien::before {
    content: "";
    position: absolute;
    left: 0; top: 50%;
    width: 3px; height: 60%;
    border-radius: 2px;
    background: var(--piv-verde);
    transform: translateY(-50%) scaleY(0);
    transition: transform .2s cubic-bezier(.22, .61, .36, 1);
}
.cuotas__tabla tbody tr:hover th.cuotas__quien::before {
    transform: translateY(-50%) scaleY(1);
}

/* ------------------------------------------- la tabla en pantalla angosta -- */
/* Tres columnas no caben en un telefono, y el desplazamiento lateral dentro de
   una pagina que ya se desplaza a lo largo se pierde: nadie lo descubre. Cada
   renglon se vuelve una tarjeta y cada importe se presenta con su rotulo, que
   viene en data-rotulo porque el texto lo pone la base y no se puede escribir
   en el CSS. */
@media (max-width: 560px) {
    .cuotas__tabla,
    .cuotas__tabla tbody,
    .cuotas__tabla tr,
    .cuotas__tabla tbody th,
    .cuotas__tabla tbody td { display: block; width: 100%; }

    .cuotas__tabla thead {
        position: absolute;
        width: 1px; height: 1px;
        overflow: hidden;
        clip: rect(0 0 0 0);
        white-space: nowrap;
    }

    .cuotas__tabla tr {
        margin-bottom: 14px;
        padding: 2px 16px 6px;
        background: #fff;
        border: 1px solid var(--regla);
        border-radius: var(--radio);
        box-shadow: var(--sombra);
    }
    .cuotas__tabla tr:hover { background: #fff; border-color: var(--piv-verde-claro); }

    .cuotas__tabla tbody th.cuotas__quien {
        padding: 12px 0 9px;
        border-bottom: 1px solid var(--regla-tenue);
        font-family: var(--f-titulo);
        font-size: 1.14rem;
    }
    .cuotas__tabla tbody th.cuotas__quien::before { display: none; }

    .cuotas__tabla tbody td.cuotas__monto {
        display: flex;
        align-items: baseline;
        justify-content: space-between;
        gap: 14px;
        padding: 10px 0;
        border-bottom: 1px solid var(--regla-tenue);
        white-space: normal;
    }
    .cuotas__tabla tbody tr td.cuotas__monto:last-child { border-bottom: 0; }

    .cuotas__monto::before {
        content: attr(data-rotulo);
        flex: 1 1 auto;
        text-align: left;
        font-family: var(--f-texto);
        font-variant-numeric: normal;
        font-size: .84rem;
        line-height: 1.35;
        color: var(--tenue);
    }
}

/* ------------------------------------------------------- el texto de pago -- */
/* La cuenta de Banorte, la CLABE, lo del ticket y lo de la factura. Tambien
   estaba escrito a mano en el index.php viejo. Va en un recuadro y no como
   parrafo suelto: son datos que alguien va a copiar. */
.cuotas__pago {
    margin-top: 26px;
    padding: 20px 22px;
    background: var(--piv-verde-lavado);
    border: 1px solid var(--piv-verde-claro);
    border-radius: var(--radio);
    font-size: .95rem;
    color: var(--tinta-suave);
}
.cuotas__pago h4 { margin-bottom: .5em; font-size: 1.08rem; color: var(--tinta); }
.cuotas__pago p { margin-bottom: 0; }
.cuotas__pago p + p { margin-top: .8rem; }
.cuotas__pago strong { color: var(--tinta); }

/* ==================================================== enlaces con hijos ====

   Carlos: "aqui que solo sean 2 cuadritos, recorrido virtual y revista
   electronica, y que en la revista muestre el link de los numeros anteriores".

   La tarjeta dejo de ser un <a>: ahora lleva enlaces DENTRO, y un <a> dentro de
   otro <a> es HTML invalido -- el navegador lo desarma solo y cada uno lo hace
   a su manera. Asi que la tarjeta es un <div> y hay que reponerle a mano el
   hover que traia de .ficha--liga.

   La jerarquia se ve: el principal ocupa la tarjeta entera y es lo que se
   toca; el hijo es un renglon mas chico, en su propia franja, con una flecha
   que avanza. "Numeros anteriores" ya no pesa lo mismo que la revista.
   ========================================================================== */

/* Cada tarjeta mide lo que mide su contenido. Estiradas a la misma altura, la
   que no tiene hijos arrastraba un hueco blanco del tamanio exacto de la
   franja de la otra, y ese hueco se lee como algo que falta. */
#enlaces .rejilla { align-items: start; }

.enlace-externo {
    position: relative;
    display: flex;
    flex-direction: column;
    padding: 0;
    overflow: hidden;
    transition: transform .22s cubic-bezier(.22, .61, .36, 1),
                box-shadow .22s ease,
                border-color .22s ease;
}

/* EL GESTO DE ESTA SECCION: una regla verde que cruza la tarjeta por arriba.
   Es la misma linea del .filo de los titulos, aqui en movimiento. */
.enlace-externo::before {
    content: "";
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 3px;
    background: var(--piv-verde);
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform .3s cubic-bezier(.22, .61, .36, 1);
}
.enlace-externo:hover::before,
.enlace-externo:focus-within::before { transform: scaleX(1); }

.enlace-externo:hover,
.enlace-externo:focus-within {
    transform: translateY(-5px);
    box-shadow: var(--sombra-alta);
    border-color: var(--piv-verde-claro);
}

/* El principal ocupa la tarjeta: se toca en cualquier parte del cuerpo, igual
   que cuando la tarjeta entera era el enlace. */
.enlace-externo__principal {
    display: block;
    flex: 1 1 auto;
    padding: 26px 26px 22px;
    color: inherit;
    text-decoration: none;
}
.enlace-externo__principal h3 { transition: color .18s ease; }
.enlace-externo:hover .enlace-externo__principal h3,
.enlace-externo__principal:focus-visible h3 { color: var(--piv-verde-hondo); }
.enlace-externo__principal:focus-visible {
    outline: 2px solid var(--piv-verde);
    outline-offset: -3px;
}

.enlace-externo__hijos {
    display: flex;
    flex-direction: column;
    padding: 2px 26px 8px;
    background: var(--fondo-alt);
    border-top: 1px solid var(--regla);
}

.enlace-externo__hijo {
    position: relative;
    display: block;
    padding: 10px 0 10px 22px;
    font-size: .93rem;
    line-height: 1.35;
    color: var(--piv-verde-hondo);
    text-decoration: none;
}
.enlace-externo__hijo + .enlace-externo__hijo { border-top: 1px solid var(--regla-tenue); }

.enlace-externo__hijo::before {
    content: "\2192";
    position: absolute;
    left: 0; top: 10px;
    color: var(--piv-verde);
    transition: transform .18s ease;
}
.enlace-externo__hijo:hover,
.enlace-externo__hijo:focus-visible { color: var(--piv-verde); text-decoration: underline; }
.enlace-externo__hijo:hover::before,
.enlace-externo__hijo:focus-visible::before { transform: translateX(4px); }

/* ============================= el boton al final de "como participar" =======

   Centrado y separado de los pasos por aire, no por una linea: la linea diria
   "aqui termina una cosa y empieza otra", y esto es la continuacion de lo que
   se acaba de leer -- el paso que sigue despues de los cuatro pasos.
   ========================================================================== */

.participar__accion {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 16px;
    margin-top: 42px;
}

/* LA PASTILLA DE LAS FECHAS. Va debajo del boton, no dentro: la frase completa
   -- "del 23 de agosto al 22 de septiembre de 2026" -- mide mas que el boton, y
   metida en la etiqueta lo partiria en dos renglones hasta dejar de parecer un
   boton.

   EL ROTULO EN VERSALITA Y LA FECHA EN NUMEROS DE ANCHO FIJO, igual que en el
   calendario y en la tabla de cuotas: son el mismo tipo de dato y se leen
   igual en las tres. */
.fechas-pastilla {
    display: inline-flex; flex-wrap: wrap;
    align-items: baseline; justify-content: center;
    gap: 4px 12px; margin: 0;
    padding: 9px 18px; border-radius: 999px;
    background: var(--piv-verde-lavado);
}
.fechas-pastilla__rotulo {
    font-family: var(--f-titulo); font-weight: 600;
    font-size: .72rem; letter-spacing: .09em; text-transform: uppercase;
    color: var(--piv-verde-hondo);
}
.fechas-pastilla__dato {
    font-weight: 500; font-size: .97rem;
    font-variant-numeric: tabular-nums;
}

/* Con el registro cerrado la pastilla sigue diciendo cuando fue -- el dato
   explica el boton apagado --, pero pierde el verde: en el color de la marca se
   leeria como una invitacion que ya no existe. Mismo criterio que .btn--inerte. */
.fechas-pastilla--inerte { background: var(--fondo-alt); }
.fechas-pastilla--inerte .fechas-pastilla__rotulo { color: var(--tenue); }
.fechas-pastilla--inerte .fechas-pastilla__dato { color: var(--tenue); }

@media (max-width: 560px) {
    .participar__accion { margin-top: 32px; }
    .participar__accion .btn { width: 100%; justify-content: center; }
    .fechas-pastilla { padding: 10px 16px; }
}

/* ========================================== areas, categorias y modalidades ==

   EL GESTO: la etiqueta se rellena. Estas tarjetas son etiqueta y nombre, nada
   mas -- no hay parrafo que enfatizar --, asi que lo que responde es la
   etiqueta, que es lo unico que tienen de propio. Suben cuatro pixeles y no
   seis: son hasta ocho por fila y con mas movimiento la fila entera parece
   temblar.
   ========================================================================== */

.ficha--compacta {
    transition: transform .2s cubic-bezier(.22, .61, .36, 1),
                box-shadow .2s ease,
                border-color .2s ease,
                background-color .2s ease;
}
.ficha--compacta:hover,
.ficha--compacta:focus-within {
    transform: translateY(-4px);
    box-shadow: var(--sombra-alta);
    border-color: var(--piv-verde-claro);
}

.ficha--compacta .etiqueta {
    transition: background-color .2s ease, color .2s ease;
}
.ficha--compacta:hover .etiqueta,
.ficha--compacta:focus-within .etiqueta {
    background: var(--piv-verde);
    color: #fff;
}

/* Las areas ademas se llenan del verde lavado. Van sobre una seccion verde y
   ahi una tarjeta blanca que solo sube se distingue menos; el relleno le da el
   contraste que las categorias consiguen con la sombra. */
#areas .ficha--compacta:hover,
#areas .ficha--compacta:focus-within { background: var(--piv-verde-lavado); }

/* Los desplegables de modalidad: una barra verde que crece por el costado.
   Se queda encendida mientras el desplegable esta abierto -- ahi ya no es un
   efecto, es la senial de cual se esta leyendo. */
.desplegable { position: relative; }
.desplegable::before {
    content: "";
    position: absolute;
    left: 0; top: 0; bottom: 0;
    width: 3px;
    background: var(--piv-verde);
    transform: scaleY(0);
    transform-origin: top center;
    transition: transform .26s cubic-bezier(.22, .61, .36, 1);
}
.desplegable:hover::before,
.desplegable:focus-within::before,
.desplegable[open]::before { transform: scaleY(1); }

.desplegable > summary::after { transition: transform .2s cubic-bezier(.22, .61, .36, 1); }
.desplegable:hover > summary::after { transform: scale(1.22); }

/* ==================================================== descargas ============

   EL GESTO: la regla verde de la ficha se estira de lado a lado, como si el
   documento se subrayara al acercarse. La tarjeta ya sube tres pixeles por ser
   .ficha--liga; no hace falta agregarle mas movimiento, solo esto que es suyo.
   ========================================================================== */

.descarga::before {
    transition: width .3s cubic-bezier(.22, .61, .36, 1);
}
.descarga:hover::before,
.descarga:focus-visible::before { width: 100%; }

/* ==================================================== contactos ============

   EL GESTO: la raya de abajo se pinta de verde de izquierda a derecha y el
   nombre toma color. No suben ni se convierten en tarjeta: son un directorio,
   siete renglones seguidos, y siete cosas levantandose es un temblor.
   ========================================================================== */

.contacto { position: relative; }
.contacto::after {
    content: "";
    position: absolute;
    left: 0; right: 0; bottom: -1px;
    height: 2px;
    background: var(--piv-verde);
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform .32s cubic-bezier(.22, .61, .36, 1);
}
.contacto:hover::after,
.contacto:focus-within::after { transform: scaleX(1); }

.contacto__nombre { transition: color .2s ease; }
.contacto:hover .contacto__nombre,
.contacto:focus-within .contacto__nombre { color: var(--piv-verde-hondo); }

/* ------------------------------------------------------- menos movimiento -- */
/* Se apaga el MOVIMIENTO -- lo que desplaza, escala o crece --, nunca el
   color: el color es lo que dice donde esta parado el cursor, y quitarlo
   dejaria a esa persona sin saberlo. */
@media (prefers-reduced-motion: reduce) {
    .enlace-externo,
    .enlace-externo::before,
    .enlace-externo__hijo::before,
    .ficha--compacta,
    .desplegable::before,
    .descarga::before,
    .contacto::after,
    .cuotas__tabla tbody th.cuotas__quien::before,
    .desplegable > summary::after {
        transition: background-color .01ms, color .01ms, border-color .01ms;
    }

    .enlace-externo:hover,
    .enlace-externo:focus-within,
    .ficha--compacta:hover,
    .ficha--compacta:focus-within { transform: none; }

    .enlace-externo__hijo:hover::before,
    .enlace-externo__hijo:focus-visible::before { transform: none; }

    .desplegable:hover > summary::after { transform: none; }

    /* Las barras y las reglas que crecen se quedan puestas, sin recorrido: se
       ven igual de encendidas, solo que sin animarse. */
    .enlace-externo:hover::before,
    .enlace-externo:focus-within::before { transform: scaleX(1); }

    .desplegable:hover::before,
    .desplegable:focus-within::before,
    .desplegable[open]::before { transform: scaleY(1); }

    .contacto:hover::after,
    .contacto:focus-within::after { transform: scaleX(1); }

    .cuotas__tabla tbody tr:hover th.cuotas__quien::before {
        transform: translateY(-50%) scaleY(1);
    }
}


/* =============================================================================
   EL PANEL  --  agregado 2026-08-23

   Va al FINAL y solo agrega: ni una regla de arriba se toca. El panel usa la
   misma hoja que el sitio publico a proposito -- los mismos tokens, los mismos
   botones, los mismos avisos --, porque es la trastienda del mismo congreso y
   no otro sistema. Lo unico propio es el armazon de dos columnas.

   Todo lo de aqui cuelga de .panel o de .panel-body, asi que nada de esto puede
   alcanzar a una pagina publica.
   ============================================================================= */

.panel-body { background: var(--fondo-alt); }

.panel {
    display: grid;
    grid-template-columns: 252px minmax(0, 1fr);
    min-height: 100vh;
}

/* ------------------------------------------------------------- lateral --- */
.panel__lateral {
    /* De arriba hacia abajo se HUNDE, no se aclara: arriba --panel-alto, en el
       cuerpo --panel-fondo y al final --panel-hondo. Tres paradas y no dos
       porque con dos, al 42%, el 58% de abajo quedaba plano y el cambio se
       amontonaba arriba: en movil -- donde el lateral mide 340 px y no 100vh --
       eso se veia como una franja cortada, no como profundidad. Repartido hasta
       el 100% el degradado no tiene filo en ninguna de las dos formas.

       El extremo CLARO es el de arriba y no cambia, asi que el peor contraste
       del lateral sigue siendo el mismo que ya estaba medido. */
    background: linear-gradient(180deg,
                var(--panel-alto) 0%,
                var(--panel-fondo) 46%,
                var(--panel-hondo) 100%);
    color: var(--panel-texto);
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 20px 0 24px;
    position: sticky;
    top: 0;
    align-self: start;
    max-height: 100vh;
    overflow-y: auto;
}

/* LA MARCA: EL LOGO SOLO, CENTRADO  (2026-08-24)

   Iba con el logo a la izquierda y la palabra "PANEL" al lado. Carlos: "en el
   sistema admin, quitale la palabra PANEL y deja centrado el logo".

   AL QUITAR EL TEXTO, EL AREA DE CLIC SE ENCOGIA A LA IMAGEN -- unos 85 x 28
   px perdidos arriba a la izquierda, que con el dedo es una diana. Por eso el
   enlace se declara `flex` de ancho completo con `min-height`: la franja
   entera del logo lleva al tablero, no solo los pixeles pintados.

   Y EL RELLENO SE REPARTIO. Eran 4 px arriba y 18 abajo, un desnivel pensado
   para que el texto no se pegara al borde; sin texto, el logo quedaba
   descentrado en su franja. Ahora 14 y 16, que a ojo es el mismo aire arriba
   que abajo contando el descuadre optico del logotipo. */
.panel__marca {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 60px;
    padding: 14px 20px 16px;
    text-decoration: none;
    border-bottom: 1px solid var(--panel-linea);
}
.panel__marca img { height: 30px; width: auto; filter: brightness(0) invert(1); opacity: .92; }

.panel__menu { flex: 1 1 auto; padding: 10px 0; }

.panel__grupo + .panel__grupo { margin-top: 22px; }
.panel__grupo h3 {
    font-family: var(--f-titulo);
    font-size: .74rem; font-weight: 600;
    letter-spacing: .16em; text-transform: uppercase;
    color: var(--panel-apagado);
    margin: 0 0 6px;
    padding: 0 20px;
}
.panel__grupo ul { list-style: none; margin: 0; padding: 0; }

/* LA FORMA DE PASTILLA. El fondo del renglon activo y el del hover no llegan
   hasta el filo del lateral: se quedan 12 px antes y rematan redondeados. Un
   bloque que corre de borde a borde se lee como un corte del lateral; una
   pastilla se lee como un renglon senialado.

   El remate redondeado es SOLO del lado derecho. Del izquierdo tiene que quedar
   a escuadra porque ahi va el filo de 3 px, que es la senial que sigue viendose
   cuando el color no se distingue.

   El margen y el radio van en el renglon NORMAL, no en :hover ni en .activo: si
   solo los llevara el resaltado, la caja cambiaria de tamanio al pasar el raton
   y el fondo se veria crecer en vez de aparecer. */
.panel__menu a {
    display: block;
    padding: 8px 20px;
    margin-right: 12px;
    border-radius: 0 999px 999px 0;
    color: var(--panel-texto);
    font-size: .97rem;
    text-decoration: none;
    border-left: 3px solid transparent;
    transition: background .12s, color .12s, border-color .12s;
}

/* El hover tinta de VERDE, no de blanco. Un velo blanco sobre un fondo de color
   lo lava y lo vuelve grisaceo; el mismo velo en el color del texto lo aclara
   sin sacarlo de su familia. */
.panel__menu a:hover {
    background: rgba(var(--panel-texto-rgb), .09);
    color: #FFFFFF;
    border-left-color: rgba(var(--panel-realce-rgb), .45);
}

/* La pantalla en la que se esta. Sin esto, en un panel de veinte pantallas
   nadie sabe donde esta parado. */
.panel__menu a.activo {
    /* Se distingue por TRES seniales a la vez -- fondo, filo y peso -- y no por
       una sola: quien no distingue bien los verdes sigue viendo el filo y la
       negrita. */
    background: rgba(var(--panel-realce-rgb), .16);
    border-left-color: var(--panel-realce);
    color: #FFFFFF;
    font-weight: 600;
}

.panel__menuVacio { padding: 0 20px; font-size: .92rem; color: var(--panel-apagado); }

.panel__lateralPie {
    padding: 14px 20px 0;
    border-top: 1px solid var(--panel-linea);
    font-size: .9rem;
}
.panel__lateralPie a { color: var(--panel-texto); }
.panel__lateralPie a:hover { color: #FFFFFF; }

/* -------------------------------------------------------------- cabeza --- */
.panel__lado { display: flex; flex-direction: column; min-width: 0; }

.panel__cabeza {
    display: flex; align-items: center; gap: 20px; flex-wrap: wrap;
    background: var(--fondo);
    border-bottom: 1px solid var(--regla);
    padding: 14px 30px;
    position: sticky; top: 0; z-index: 5;
}

.panel__edicion { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.panel__edicionRotulo {
    font-family: var(--f-titulo);
    font-size: .72rem; font-weight: 600;
    letter-spacing: .16em; text-transform: uppercase;
    color: var(--tenue);
}
.panel__edicionNombre { font-weight: 600; margin-right: 10px; }

.panel__usuario { display: flex; align-items: center; gap: 14px; margin-left: auto; }
.panel__quien { display: flex; flex-direction: column; text-align: right; line-height: 1.25; }
.panel__nombre { font-weight: 600; font-size: .96rem; }
.panel__rol { font-size: .82rem; color: var(--tenue); }

/* -------------------------------------------------------------- cuerpo --- */
.panel__cuerpo { padding: 28px 30px 60px; min-width: 0; }

.panel__titulo { margin-bottom: 4px; }
.panel__titulo h1 { font-size: 2rem; margin-bottom: .1em; }
.panel__intro { color: var(--tinta-suave); max-width: 74ch; margin-bottom: 24px; }

.tarjeta {
    background: var(--fondo);
    border: 1px solid var(--regla);
    border-radius: var(--radio);
    box-shadow: var(--sombra);
    padding: 24px 26px;
    margin-bottom: 22px;
}
.tarjeta > h2 { font-size: 1.35rem; margin-bottom: .2em; }
.tarjeta > h2 + p { color: var(--tinta-suave); font-size: .96rem; }
.tarjeta__pie {
    display: flex; flex-wrap: wrap; gap: 12px; align-items: center;
    margin-top: 22px; padding-top: 18px;
    border-top: 1px solid var(--regla-tenue);
}

/* Dos columnas de campos en pantalla ancha, una sola en angosta. */
.campos { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 18px; }
.forma__campo--ancho { grid-column: 1 / -1; }

.forma__campo input[type="date"].entrada { max-width: 260px; }
.forma__campo input[type="number"].entrada { max-width: 180px; }

.campo__dato { font-weight: 600; }

/* ------------------------------------------------------------- rejilla --- */
/* Los GridView del panel. Se estiliza el table que pinta el control, sin
   plantillas raras: menos HTML que mantener. */
.tabla { width: 100%; border-collapse: collapse; font-size: .95rem; }
.tabla th, .tabla td {
    text-align: left;
    padding: 10px 12px;
    border-bottom: 1px solid var(--regla-tenue);
    vertical-align: middle;
}
.tabla th {
    font-family: var(--f-titulo);
    font-size: .8rem; font-weight: 600;
    letter-spacing: .1em; text-transform: uppercase;
    color: var(--tenue);
    border-bottom: 1px solid var(--regla);
    white-space: nowrap;
}
.tabla tr:last-child td { border-bottom: 0; }
.tabla tbody tr:hover { background: var(--fondo-alt); }
.tabla__acciones { white-space: nowrap; text-align: right; }
/* Aqui habia `.tabla__acciones .btn + .btn { margin-left: 6px }`, de cuando los
   botones de la fila iban uno al lado del otro. Al apilarlos, ese margen se lo
   quedaban el segundo y el tercero, y el primero salia SEIS PIXELES a la
   izquierda de los demas: la columna se veia torcida sin motivo aparente.

   Ahora la separacion la pone el `gap` del contenedor, que no distingue entre
   el primer hijo y los demas. */
.tabla__inactivo td { opacity: .55; }
.tabla__num { text-align: right; font-family: var(--f-dato); font-variant-numeric: tabular-nums; }

.tabla-vacia { color: var(--tenue); font-size: .95rem; padding: 14px 0; }

/* ------------------------------------------------------- vista previa ---- */
/* La maqueta del hero: imita el bloque de la portada para que el administrador
   vea como va a quedar el banner ANTES de guardarlo. Las proporciones son las
   del hero de verdad, no un cuadro cualquiera. */
.maqueta {
    position: relative;
    aspect-ratio: 2 / 1;
    width: 100%;
    max-width: 720px;
    border-radius: var(--radio);
    overflow: hidden;
    background: var(--piv-negro);
    border: 1px solid var(--regla);
}
.maqueta__img {
    position: absolute; top: 0; right: 0; bottom: 0; left: 0;
    width: 100%; height: 100%;
    object-fit: cover;
    opacity: .34;
}
.maqueta__velo {
    position: absolute; top: 0; right: 0; bottom: 0; left: 0;
    background: linear-gradient(90deg,
                rgba(20,24,15,.94) 0%, rgba(20,24,15,.66) 58%, rgba(20,24,15,.36) 100%);
}
.maqueta__caja {
    position: relative; z-index: 1;
    padding: 7% 8%;
    max-width: 78%;
}
.maqueta__eyebrow {
    font-family: var(--f-titulo);
    font-size: .68rem; font-weight: 600;
    letter-spacing: .18em; text-transform: uppercase;
    color: var(--piv-verde-claro);
    margin-bottom: .5em;
}
.maqueta__titulo {
    font-family: var(--f-titulo);
    font-size: clamp(1.1rem, 3.2vw, 2rem);
    font-weight: 700; line-height: 1.05;
    color: #fff; margin: 0 0 .35em;
}
.maqueta__lema {
    color: #D6DDD2;
    font-size: clamp(.72rem, 1.5vw, .98rem);
    margin: 0 0 1em;
}
.maqueta__btn {
    display: inline-block;
    background: var(--piv-verde); color: #fff;
    font-family: var(--f-titulo); font-weight: 600;
    font-size: clamp(.68rem, 1.3vw, .9rem);
    padding: .5em 1.2em; border-radius: var(--radio-sm);
}
.maqueta__vacia {
    position: absolute; top: 0; right: 0; bottom: 0; left: 0; z-index: 2;
    display: flex; align-items: center; justify-content: center;
    text-align: center; padding: 20px;
    color: #B9C0B4; font-size: .92rem;
    background: rgba(20,24,15,.55);
}

.previa { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 22px; align-items: start; }
.previa__medidas { font-family: var(--f-dato); font-size: .88rem; color: var(--tinta-suave); }

/* --------------------------------------------------------------- movil --- */
@media (max-width: 900px) {
    .panel { grid-template-columns: 1fr; }
    .panel__lateral {
        position: static; max-height: none;
        flex-direction: column;
    }
    /* LA REJILLA DE DOS COLUMNAS ES AHORA EL PLAN B, no el plan A.

       Era lo unico que habia en angosto, y con 24 renglones ocupaba la
       pantalla completa: habia que desplazarse por todo el menu antes de ver
       un dato. Desde el 2026-08-24 el lateral es un cajon que se abre con el
       boton de la cabecera, y el menu va apilado en una sola columna dentro
       del cajon.

       Esto se queda para quien no tenga JavaScript: ahi no hay boton ni cajon,
       el lateral sigue en el flujo, y una rejilla de dos columnas es mejor que
       una lista de 24 renglones. Ver el bloque del cajon al final del archivo. */
    html:not(.js) .panel__menu { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 4px 18px; }
    .panel__cabeza { padding: 12px 18px; }
    .panel__cuerpo { padding: 20px 18px 48px; }
    .panel__usuario { margin-left: 0; }
}

/* La rejilla no cabe en un telefono: se desliza dentro de su caja en vez de
   estirar la pagina entera. */
@media (max-width: 700px) {
    .desbordable .tabla { min-width: 620px; }
}

/* Una pantalla que esta en Config.Menu pero cuyo .aspx todavia no existe. Se
   pinta como texto, no como enlace: un vinculo que contesta 404 se ve igual que
   un sistema roto. */
/* AQUI ESTABA EL UNICO FALLO DE CONTRASTE DEL LATERAL, y lo ponia el `opacity`,
   no el color.

   --panel-apagado da 5.81:1, que pasa AA de sobra. Pero llevaba `opacity: .62`
   encima, y la opacidad no apaga el texto: lo MEZCLA con el fondo. El color que
   acababa pintado era #567866 y su contraste real 3.14:1 -- reprobado. Y el
   `<em>` de "(pendiente)" llevaba ademas `opacity: .8`, que NO reemplaza a la
   del padre sino que se multiplica con ella: .62 x .8 = .496, o sea #486858 y
   2.49:1. Catorce de las veinticuatro entradas del menu son pendientes, asi que
   el menu se veia medio borrado.

   Se apaga con el TOKEN y con el tamanio, que es lo que se puede medir. Contra
   una opcion viva (--panel-texto, 9.84:1) la diferencia se sigue viendo -- son
   casi cuatro puntos de contraste --, pero ahora las dos se leen. */
.panel__menu .pendiente {
    display: block;
    padding: 8px 20px;
    margin-right: 12px;            /* la misma caja que un renglon vivo, para
                                      que la lista no quede desalineada */
    color: var(--panel-apagado);   /* 5.81:1 sobre --panel-fondo */
    font-size: .97rem;
    border-left: 3px solid transparent;
    cursor: default;
}
.panel__menu .pendiente em {
    font-style: normal;
    font-size: .78rem;
    letter-spacing: .04em;         /* secundario por tamanio, no por opacidad */
}

/* =============================================================== el banner ==

   REGLA FIJA, PEDIDA POR CARLOS Y YA DISCUTIDA VARIAS VECES:
   **el banner SIEMPRE se ve al ancho del menu.** No al ancho de la ventana, no
   encogido segun el alto de la pantalla. Al ancho del menu.

   Aqui hubo cuatro intentos y los tres primeros estuvieron mal:

     1. Al 100% de la ventana -> arrancaba pegado al filo del monitor mientras
        el logo y el menu empezaban mas adentro. "se desparrama y se ve
        horrible".
     2. Con marco oscuro arriba y abajo -> lo probo y lo descarto.
     3. Encogiendolo segun el alto de la pantalla (140vh) para que en una
        laptop dejara asomar lo de abajo -> en pantalla normal se despegaba del
        menu. "se ve mas feo ahora, siempre debe de verse al ancho del menu".

   Lo que queda es lo mas simple: la MISMA formula que .contenedor -- misma
   variable, mismo padding -- para que el dia que cambie el ancho del sitio el
   banner lo siga solo. Un 1480 escrito a mano se quedaria desalineado y nadie
   sabria por que.

   Si en una laptop el banner ocupa mucho alto, esa es la consecuencia aceptada
   de mantenerlo alineado. **No se vuelve a tocar sin que Carlos lo pida.**
   ========================================================================== */

.hero--conBanner { padding: 0; }

.hero__lamina {
    width: 100%;
    max-width: var(--ancho);
    margin: 0 auto;
    padding: 0 24px;
    background: #fff;
    line-height: 0;
}

/* La imagen manda su proporcion: ancho completo, alto automatico. Sin
   object-fit y sin tope de alto, que es lo que la despegaba del menu. */
.hero--conBanner .hero__banner {
    display: block;
    width: 100%;
    height: auto;
    max-height: none;
    object-fit: initial;
    margin: 0;
}

@media (max-width: 700px) {
    .hero__lamina { padding: 0 16px; }
}

/* --------------------------------------- la intro del panel, a lo ancho -- */
/*
   .panel__intro tiene 74ch de tope, que es la medida en que se lee comodo un
   parrafo largo. Para la intro de la edicion resulta angosta: son tres frases
   que salian en seis renglones cortos y empujaban el formulario hacia abajo,
   asi que lo primero que se veia al entrar era texto y no campos.

   Con la mitad del ancho del panel cabe en dos o tres renglones y el formulario
   sube. La medida de lectura se respeta igual: 50% de un panel ancho sigue
   estando por debajo de las 90 columnas donde un parrafo empieza a costar.
*/
.panel__intro--ancha {
    max-width: 50%;
    min-width: 46ch;
}

@media (max-width: 900px) {
    /* En angosto, el 50% seria una columna de dos palabras. Manda el ancho. */
    .panel__intro--ancha { max-width: 100%; min-width: 0; }
}

/* ==========================================================================
   LA LAMINA DEL HERO, CON PROFUNDIDAD                        (2026-08-23)

   Carlos pidio "algun efecto 3D" en la portada. Esto es ese efecto, y esta
   escrito al reves de como se suele escribir un efecto de scroll, a proposito.

   POR QUE NO HAY JAVASCRIPT NI UN VIDEO AQUI
   El material que se propuso para el efecto no se puede publicar (ver el
   reporte del 2026-08-23), y de todos modos no hacia falta: el banner de la
   edicion ya es lo primero y lo mas grande que se ve al entrar. La profundidad
   se la da el navegador con `perspective` y `rotateX` reales, no un video.
   Sin JavaScript no hay observador que pueda tronar, no hay un segundo archivo
   que pueda no cargar, y no hay megabytes que descargar.

   EL ESTADO SIN ANIMACION ES EL ESTADO BUENO
   Esta es la parte importante. La animacion arranca en `rotateX(0) scale(1)
   opacity: 1`, que es EXACTAMENTE como se ve el banner hoy. Si el navegador no
   entiende `animation-timeline` -- Firefox y Safari a esta fecha --, si algo
   falla, o si el usuario pide menos movimiento, no se aplica nada y el banner
   se ve completo y derecho. No se esconde nada que dependa de que algo
   funcione para volver a aparecer: es la misma regla de revelaSecciones() en
   js/sitio.js, y aqui se cumple sola porque no hay nada que revelar.

   QUE HACE
   Al bajar, la lamina se acuesta hacia atras desde su borde superior y se
   apaga, como una hoja que se aleja. Se detiene al 70% de la altura de la
   pantalla, que es cuando el banner ya salio. Solo se animan `transform` y
   `opacity`, que el navegador resuelve en la capa de composicion: ni un
   recalculo de maquetacion, ni un salto.

   DE 701 px PARA ARRIBA
   En el telefono el banner ocupa casi toda la pantalla y la inclinacion se
   come los logos de UANL y FIME que vienen dentro de la imagen. Ahi no va.
   ========================================================================== */

/*  EL EFECTO SE SUBIO DE 8 A 18 GRADOS, Y NO ES CAPRICHO.

    La primera version giraba 8 grados con la perspectiva a 1600px, repartidos
    a lo largo de 70vh de scroll. Carlos: "no veo el efecto". Y tenia razon: a
    esa distancia el giro era de un pixel por cada varios de scroll, y encima
    terminaba de aplicarse cuando el banner ya estaba saliendo de pantalla. Un
    efecto que solo se nota comparando dos capturas no es un efecto.

    Tres ajustes:
      - 18 grados en vez de 8, y la perspectiva mas cerca (1100px). Cuanto mas
        cerca esta el punto de fuga, mas pronunciada se ve la misma rotacion.
      - El recorrido baja a 55vh: el gesto entero ocurre MIENTRAS el banner
        todavia se ve.
      - La opacidad se queda en .72 y no en .55. Que se incline es el efecto;
        que se desvanezca solo lo apaga.

    Sigue arrancando en el estado normal -- rotateX(0), scale(1), opacidad 1 --
    a proposito: si el navegador no entiende animation-timeline (Firefox y
    Safari a esta fecha), o si alguien pide menos movimiento, no se aplica nada
    y el banner se ve completo y derecho. Nada escondido esperando que algo
    funcione: esa leccion ya costo una pagina en blanco. */
@keyframes piv-lamina-profundidad {
    from { transform: rotateX(0deg)  scale(1);   opacity: 1;   }
    to   { transform: rotateX(18deg) scale(.88); opacity: .72; }
}

@supports (animation-timeline: scroll()) {
    @media (prefers-reduced-motion: no-preference) and (min-width: 701px) {

        .hero--conBanner .hero__lamina {
            perspective: 1100px;
            perspective-origin: 50% 0%;
        }

        .hero--conBanner .hero__banner {
            transform-origin: 50% 0%;
            animation: piv-lamina-profundidad linear both;
            animation-timeline: scroll(root block);
            animation-range: 0 55vh;
            /* Sin esto, Chrome aplana el resultado y el giro se ve como un
               simple achatamiento en vez de una lamina acostandose. */
            transform-style: preserve-3d;
            backface-visibility: hidden;
        }
    }
}


/* ================================== el fondo del hero del banner, en blanco ==

   Carlos: "si ajustas el fondo negro donde sale el banner, para que sea blanco
   y ver si ayuda al efecto 3D".

   SI AYUDA, Y NO POR GUSTO. El banner de esta edicion es blanco, asi que sobre
   el negro del hero la lamina se recortaba con un filo durisimo: se veia una
   tarjeta pegada sobre un fondo, no una hoja con profundidad. Y sobre todo, un
   objeto que se inclina se lee como tridimensional por su SOMBRA -- y una
   sombra sobre negro es invisible. El giro estaba ahi y no habia con que
   percibirlo.

   Con el fondo claro la lamina proyecta sombra, y esa sombra es la que le dice
   al ojo que la hoja esta despegada de la pagina y que se esta acostando.

   QUE SE APAGA Y POR QUE
   - `::after` era el velo oscuro en degradado que hacia legible el titulo
     blanco encima del banner. Ese titulo ya no existe -- el banner ES el
     bloque de titulo --, asi que el velo solo servia para ensuciar los
     margenes de blanco a los lados de la lamina.
   - `::before` es el anillo del isotipo, verde al 16%. Sobre negro apenas se
     adivina; sobre blanco queda un arco palido asomando en la esquina, que
     parece suciedad de la imagen y no una marca de agua.

   `overflow` pasa a visible: el hero mide exactamente lo que mide la lamina
   -- su relleno es 0 --, asi que con `hidden` la sombra de abajo se cortaba al
   ras y el efecto se perdia justo donde se necesita. Se puede quitar porque el
   anillo, que era lo unico que se salia del marco, ya no se pinta.

   ESTO SOLO APLICA AL HERO CON BANNER. El `.hero` normal -- el de las paginas
   sin imagen cargada -- se queda negro con su anillo y su texto blanco, que es
   como debe verse cuando no hay lamina que ensenar.
   ========================================================================== */

.hero--conBanner {
    background: #fff;
    color: var(--piv-negro);
    overflow: visible;

    /* UN RESPIRO ENTRE EL MENU Y LA LAMINA.

       Carlos, viendo el sitio en otra pantalla: "siento que el banner deberia
       estar un poquito abajo, no tan pegado al header, talvez un espacio
       nadamas".

       POR QUE AHORA SI Y ANTES NO. Esto ya se probo, y se descarto: cuando el
       hero era NEGRO, cualquier separacion se leia como un marco oscuro entre
       el menu y el banner -- "lo probo y lo descarto" quedo escrito arriba, en
       el bloque del banner. Con el fondo en blanco no hay marco que ver: es el
       mismo blanco de la pagina, y lo unico que cambia es que la lamina deja de
       ir pegada al filo del menu.

       Empezo en 28px y Carlos pidio "uno mas" al verlo, asi que quedo en 56:
       dos veces esa medida. Sigue siendo aire y no un hueco -- el banner no
       deja de ser lo primero que se ve al entrar --, pero ahora se despega del
       menu de verdad y no apenas.

       ABAJO NO SE TOCA. Debajo de la lamina viene la seccion de convocatoria
       con su propio relleno; agregarle mas aqui seria sumar dos espacios y
       abrir un hueco donde nadie lo pidio. */
    padding: 56px 0 0;
}

@media (max-width: 700px) {
    /* En el telefono el banner ya ocupa casi toda la pantalla; el espacio
       completo ahi le quitaria altura a lo que importa sin agregar nada. Se
       queda con la mitad. */
    .hero--conBanner { padding-top: 28px; }
}

.hero--conBanner::before,
.hero--conBanner::after { content: none; }

/* LA SOMBRA ES EL EFECTO 3D, tanto como la rotacion.

   Es estatica a proposito: `box-shadow` no se resuelve en la capa de
   composicion, asi que animarla obligaria al navegador a repintar en cada
   cuadro del scroll -- justo lo que el bloque de abajo evita con tanto cuidado
   animando nada mas `transform` y `opacity`. Una sombra fija ya levanta la
   lamina del papel, y al inclinarse la hoja la sombra queda quieta debajo, que
   es exactamente lo que hace una hoja de verdad.

   Va negativa en el desenfoque (-18px de spread) para que no se derrame por
   los lados: se quiere el peso abajo, no un halo alrededor. */
.hero--conBanner .hero__banner {
    box-shadow: 0 18px 44px -18px rgba(20, 24, 15, .38);
}

@media (prefers-reduced-motion: reduce) {
    /* Sin movimiento la sombra no esta contando nada; se deja apenas el filo
       para que la lamina no flote sin apoyo sobre el blanco. */
    .hero--conBanner .hero__banner {
        box-shadow: 0 6px 18px -12px rgba(20, 24, 15, .30);
    }
}


/* ------------------------------------------- el hero SIN banner: no existe --

   Si la edicion no tiene banner cargado -- o la ruta falla --, esta seccion se
   queda sin nada que ensenar: su unico contenido visible era la lamina, porque
   el titulo, los botones y los datos se movieron a Calendario y a Convocatoria.
   El h1 sigue adentro, pero lleva .solo-lectores y no ocupa alto.

   Con la clase base heredaba fondo negro y 96/88 px de relleno: una barra negra
   vacia como primera impresion de la portada. Aqui se apaga entera.

   NO se usa display:none. La seccion tiene que seguir en el arbol para que el
   h1 llegue al lector de pantalla y al buscador; lo que se quita es el fondo,
   el relleno y el anillo, no el elemento.

   El code-behind reemplaza esta clase por `hero hero--conBanner` en cuanto hay
   imagen, asi que el estado por omision -- el que se ve si algo falla -- es el
   discreto. Es la misma regla de siempre: lo que se ve cuando nada funciona
   tiene que ser lo correcto.
   -------------------------------------------------------------------------- */
.hero--sinBanner {
    padding: 0;
    background: none;
    color: inherit;
}
.hero--sinBanner::before,
.hero--sinBanner::after { content: none; }


/* ==================================== los patrocinadores, con profundidad ==

   Carlos: "ponle un efecto 3d tambien".

   ANTES QUE EL EFECTO HUBO QUE ARREGLAR LA FRANJA, y la causa no estaba en el
   CSS: los 17 logos daban HTTP 401. Se copiaron a img/patrocinadores desde
   fuera de wwwroot y conservaron la lista de permisos de su origen, sin
   IIS_IUSRS. La seccion se pintaba entera -- titulo, cinta, huecos del tamanio
   exacto de cada logo -- y adentro no habia nada. Se arreglo con
   `icacls img\patrocinadores /reset /T`.

   Es la segunda vez que pasa (la primera fue con la hoja de estilos, que salio
   sin un solo estilo por lo mismo). LA REGLA: los archivos se escriben o se
   copian YA DENTRO de wwwroot. Mover algo de afuera se lleva su ACL, y un 401
   no se distingue de "la imagen no existe" mirando la pagina.

   ======================= EL EFECTO =======================

   DOS COSAS DISTINTAS, Y NINGUNA PELEA CON LA OTRA:

   1. LA BANDA se acuesta hacia atras al hacer scroll, igual que la lamina del
      banner. Menos grados que alla -- 10 contra 18 -- porque aqui no es lo
      primero que se ve sino una franja de paso: si se inclina igual de fuerte,
      compite con la seccion que la sigue.

   2. CADA LOGO se levanta hacia el lector al pasarle el mouse: sale del gris,
      recupera su color y se ADELANTA en el eje Z. Antes solo crecia con un
      scale, que se lee como zoom y no como profundidad. Con perspectiva en la
      pista y translateZ en el logo, el que se mira esta de verdad mas cerca
      que los demas.

   EL ESTADO SIN ANIMACION ES EL ESTADO BUENO, como en el banner: la animacion
   arranca en rotateX(0) y los logos viven en translateZ(0). Si el navegador no
   entiende animation-timeline -- Firefox y Safari a esta fecha --, o si alguien
   pide menos movimiento, no se aplica nada y la cinta se ve como siempre. No
   hay nada escondido esperando a que algo funcione.

   POR QUE `transform-style: preserve-3d` EN LA PISTA Y NO EN LA CINTA. La pista
   es la que ya lleva la animacion horizontal; poner ahi el contexto 3D deja que
   el desplazamiento y la profundidad convivan en la misma capa. En la cinta, el
   overflow: hidden que recorta los costados aplanaria el resultado.
   ========================================================================== */

/* La perspectiva vive en la pista, que es el padre directo de los logos. Un
   valor grande -- 1400px -- porque la banda es ancha: mas cerca, los logos de
   los extremos se deforman como en un ojo de pez. */
.cinta__pista {
    perspective: 1400px;
    perspective-origin: 50% 50%;
}

/* El logo se adelanta hacia el lector, no crece. El scale se queda tambien,
   pero mas discreto: los dos juntos venden la cercania mejor que cualquiera
   por su cuenta. */
.patrocinador__logo {
    transform: translateZ(0);
    transform-style: preserve-3d;
    will-change: transform;
}

.patrocinador:hover .patrocinador__logo,
.patrocinador:focus-visible .patrocinador__logo {
    transform: translateZ(60px) scale(1.02);
}

/* La sombra va en el contenedor y no en la imagen: los logos son PNG con fondo
   transparente, y una sombra sobre la imagen calcaria la silueta del dibujo en
   vez de apoyar el rectangulo. */
.patrocinador {
    transition: box-shadow .25s ease;
    border-radius: var(--radio-sm);
}
.patrocinador:hover,
.patrocinador:focus-visible {
    box-shadow: 0 14px 30px -16px rgba(20, 24, 15, .30);
}

@keyframes piv-cinta-profundidad {
    from { transform: rotateX(0deg);  }
    to   { transform: rotateX(10deg); }
}

@supports (animation-timeline: view()) {
    @media (prefers-reduced-motion: no-preference) and (min-width: 701px) {

        .cinta {
            perspective: 1200px;
            perspective-origin: 50% 0%;
        }

        /* `view()` y no `scroll(root)`: aqui el recorrido tiene que medirse
           contra la ENTRADA DE ESTA FRANJA en pantalla, no contra el scroll de
           toda la pagina. La cinta esta a seis mil pixeles de la portada; con
           scroll(root) el gesto se habria consumido entero mucho antes de que
           nadie la viera. El banner si usa scroll(root) porque esta arriba del
           todo y ahi las dos medidas coinciden. */
        .cinta__pista {
            transform-origin: 50% 0%;
            transform-style: preserve-3d;
            animation: piv-cinta-profundidad linear both;
            animation-timeline: view(block);
            animation-range: exit 0% exit 90%;
            backface-visibility: hidden;
        }
    }
}

@media (prefers-reduced-motion: reduce) {
    /* Sin movimiento, el logo se queda con su realce de color y su sombra: la
       informacion -- "este es el que estas mirando" -- se conserva, el gesto no. */
    .patrocinador:hover .patrocinador__logo,
    .patrocinador:focus-visible .patrocinador__logo {
        transform: none;
    }
}


/* ============================== el cierre "Te esperamos", con mas aire ==

   Carlos: "esto del footer que abarque mas y poes esta bien centrado, pero
   ahorita se ve amontonado".

   LA CAUSA. La caja tenia `max-width: 64ch`, que es la medida en que se lee
   comodo un PARRAFO. Pero lo que va aqui no es un parrafo: es el nombre
   completo del evento --

       "13 Congreso Internacional, 30 Coloquio de Proyectos Institucionales y
        de Vinculacion y 8 Congreso de la coordinacion de administracion y
        sistemas"

   -- que son casi 150 caracteres. En 64ch cae en cuatro o cinco renglones
   apretados, y como es un titulo va en cuerpo grande y con poco interlineado:
   el resultado es un bloque de letra amontonada donde deberia haber un remate.

   LO QUE SE HACE, Y POR QUE NO ES "ensanchar todo". La caja crece, pero cada
   cosa adentro recupera la medida que le toca:

     - EL TITULO se suelta hasta 20ch mas que antes y se le abre el
       interlineado. Un titulo largo no se lee renglon por renglon como un
       parrafo, se abarca de un vistazo, asi que la regla de las 64 columnas no
       le aplica.
     - LA LEYENDA se queda en 58ch y centrada. Esa SI es una frase que se lee, y
       estirarla al ancho de la caja seria el error contrario: renglones tan
       largos que el ojo pierde de cual venia.

   O sea que la caja abarca mas y el texto respira, pero nada se estira mas alla
   de donde se sigue leyendo bien.
   ========================================================================== */

.cierre__caja {
    /* `min()` para que en una laptop angosta mande el ancho disponible y no las
       92 columnas: sin eso, la caja se saldria del contenedor. */
    max-width: min(100%, 92ch);
    margin-inline: auto;
}

.cierre h2 {
    max-width: 24ch;
    margin-inline: auto;
    line-height: 1.18;
    text-wrap: balance;
}

/* El titulo del cierre sale de la base y puede ser muy largo o muy corto. Con
   `text-wrap: balance` los renglones quedan parejos en vez de dejar una palabra
   sola al final -- que con este nombre pasaba siempre. Donde el navegador no lo
   entienda, simplemente parte como antes. */

.cierre__leyenda {
    max-width: 58ch;
    margin-inline: auto;
    margin-bottom: 34px;
    line-height: 1.6;
}

@media (min-width: 901px) {
    /* En pantalla ancha el titulo se suelta hasta 40 columnas. Con 30 se quedaba
       en 583 px de una caja de 884 -- o sea, dejaba 300 px de negro vacio a cada
       lado y aun asi caia en cinco renglones. Con 40 usa el ancho que ya tenia y
       baja a cuatro.

       No se le quita el tope del todo: sin el, este titulo de 150 caracteres se
       tiraria en dos renglones larguisimos y centrados, que es de lo mas dificil
       de leer que hay -- al volver de un renglon al siguiente, el ojo no tiene
       margen izquierdo donde engancharse. */
    .cierre h2 { max-width: 40ch; }
}

@media (max-width: 700px) {
    /* En el telefono manda el ancho de la pantalla; las medidas en ch aqui
       solo estorbarian. */
    .cierre__caja,
    .cierre h2,
    .cierre__leyenda { max-width: 100%; }
}


/* ================================= el ojito de la contrasenia (2026-08-23) ==

   El boton lo crea js/sitio.js, no el marcado: un boton que solo alterna un
   atributo no tiene nada que hacer si el JavaScript no corrio. Aqui va nada mas
   como se ve.

   LA CAJA ES `position: relative` Y EL BOTON VA ADENTRO, ENCIMA DEL CAMPO. Con
   el boton al lado -- en un flex de dos columnas -- el campo se encogeria, y
   todos los demas campos del formulario quedarian mas anchos que este. Puesto
   encima, el campo conserva su ancho y solo se le reserva relleno a la derecha
   para que el texto no pase por debajo del icono.
   ========================================================================== */

.campo-psw {
    position: relative;
    display: block;
}

/* El relleno se le da al campo DESDE AQUI y no tocando `.entrada`, para que el
   resto de los campos del sitio no cambien. 44px = el ancho del boton mas aire.
   Sin esto, una contrasenia larga se mete debajo del ojo. */
.campo-psw .entrada {
    width: 100%;
    padding-right: 44px;
}

.campo-psw__ojo {
    position: absolute;
    top: 50%;
    right: 6px;
    transform: translateY(-50%);

    display: inline-flex;
    align-items: center;
    justify-content: center;

    /* 34x34 de area tocable. Menos que eso y en un telefono se falla el toque:
       el icono mide 20, pero el boton no es el icono. */
    width: 34px;
    height: 34px;

    padding: 0;
    border: 0;
    border-radius: var(--radio-sm);
    background: transparent;
    color: var(--tenue);
    cursor: pointer;
    transition: color .15s ease, background-color .15s ease;
}

.campo-psw__ojo:hover { color: var(--tinta-suave); background: var(--regla-tenue); }

/* El foco se ve. Es un control que se alcanza con Tab, y sin anillo de foco
   quien navegue con teclado no sabe que lo tiene encima. */
.campo-psw__ojo:focus-visible {
    outline: none;
    color: var(--piv-verde-hondo);
    box-shadow: 0 0 0 3px rgba(var(--piv-verde-rgb), .22);
}

/* Mientras la contrasenia esta a la vista, el ojo se queda en verde: es un
   recordatorio de que hay algo destapado en pantalla. */
.campo-psw__ojo[aria-pressed="true"] { color: var(--piv-verde-hondo); }

.campo-psw__ojo svg { display: block; }


/* ============================== la bandeja de participantes  (2026-08-24) ==

   Lo que hacia falta para Pages/Participantes/Bandeja.aspx: el resumen de
   arriba, la fila de filtros y tres detalles de la tabla.
   ========================================================================== */

/* ---------------------------------------------------- el resumen de cifras --

   AUTO-FIT Y NO CUATRO COLUMNAS FIJAS. Hoy son cinco numeros; maniana pueden
   ser cuatro o seis, y una rejilla fija dejaria un hueco o partiria el ultimo
   solo en su renglon. Con auto-fit se reparten segun quepan.

   El minimo de 150px es el ancho en que "Inscripciones concluidas" cabe en dos
   renglones sin partir una palabra. */
.cifras {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 14px;
    margin-bottom: 18px;
}

.cifra {
    padding: 16px 18px;
    border: 1px solid var(--regla);
    border-left: 4px solid var(--regla);
    border-radius: var(--radio-sm);
    background: var(--fondo-alt);
}

/* El numero manda: es lo unico que se lee de lejos, y esta pantalla se mira
   de lejos -- alguien pasa y pregunta "cuantos van". */
.cifra__numero {
    font-family: var(--f-titulo);
    font-size: 2rem;
    line-height: 1.1;
    margin: 0 0 2px;
    color: var(--tinta);
    font-variant-numeric: tabular-nums;
}

.cifra__que {
    margin: 0;
    font-size: .86rem;
    color: var(--tinta-suave);
    line-height: 1.35;
}

/* Solo dos cifras llevan color, y las dos son las que piden accion: cuantos ya
   cerraron y cuantos siguen a medias. Pintarlas todas seria un semaforo sin
   informacion. */
.cifra--ok     { border-left-color: var(--ok); }
.cifra--ok     .cifra__numero { color: var(--ok); }
.cifra--alerta { border-left-color: var(--alerta); }
.cifra--alerta .cifra__numero { color: var(--alerta); }

/* ------------------------------------------------------------- los filtros --

   Misma idea que las cifras: se acomodan segun quepan. En una laptop angosta
   caen en dos renglones sin que nadie tenga que decidir cual va donde. */
/* LOS FILTROS NO MIDEN TODOS LO MISMO, PORQUE NO CONTIENEN LO MISMO.

   Antes eran cinco columnas iguales de auto-fit. El resultado: la caja de
   busqueda -- donde se teclea un titulo largo o un correo -- media igual que
   "Estado", cuyo contenido mas ancho es la palabra "Concluida". Se escribia a
   ciegas en un hueco de 190 px mientras dos listas desplegables desperdiciaban
   la mitad de su ancho.

   Ahora la busqueda pesa el doble (2fr contra 1fr) y las listas se conforman
   con lo que de verdad ocupan.

   EL MINIMO DE 240 px NO ES ADORNO, ES LO QUE EVITA QUE SE INVIERTA.

   Un `2fr` solo reparte lo que sobra DESPUES de que cada columna se quedo con
   su minimo. Como las listas piden 150 px cada una y la busqueda -- escrita
   como `minmax(0, 2fr)` -- pedia cero, en cuanto la pantalla dejaba de sobrar
   espacio las cuatro listas se servian primero y la busqueda se quedaba con
   las migajas. Medido en esta misma pantalla, con el renglon de filtros en
   738 px de ancho -- que es lo que da una laptop de 1024 -- la caja de
   busqueda salia de 74 px al lado de listas de 150. Justo al reves de lo que
   se pidio, y sin que se notara en un monitor grande.

   Con `minmax(240px, 2fr)` la busqueda cobra primero sus 240 px; si despues de
   eso no alcanza para las cuatro listas, se bajan al siguiente renglon en vez
   de aplastarla. Comprobado de 420 a 1582 px de ancho: la busqueda nunca queda
   mas angosta que una lista y la rejilla nunca se desborda de lado. */
.filtros {
    display: grid;
    grid-template-columns: minmax(240px, 2fr) repeat(auto-fit, minmax(150px, 1fr));
    gap: 12px 16px;
    margin-bottom: 16px;
    align-items: end;
}
.filtros .forma__campo { margin-bottom: 0; }

/* En angosto se apilan: mantener la proporcion en un telefono dejaria las
   listas en una tira de 60 px. */
@media (max-width: 820px) {
    .filtros { grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); }
}

/* Un campo que se lleva el renglon completo, para cuando es el unico. */
.forma__campo--ancho { grid-column: 1 / -1; }

/* ---------------------------------------------- tres detalles de la tabla -- */

/* El correo debajo del nombre, el nombre de la institucion debajo del titulo.
   Van en la misma celda y no en columnas propias: son datos de apoyo, y dos
   columnas mas obligarian a desplazar la tabla de lado para leer lo importante. */
.tabla__secundario {
    display: block;
    font-size: .82rem;
    color: var(--tenue);
    margin-top: 2px;
    word-break: break-word;
}

/* Los conteos y las etiquetas de si/no, centrados: son columnas angostas donde
   un numero alineado a la izquierda se ve suelto. */
.tabla__centrado { text-align: center; }

/* "Sin titulo todavia" y demas texto que NO capturo nadie: se distingue de un
   dato real para que no se lea como si el proyecto se llamara asi. */
.tabla__tenue { color: var(--tenue); font-style: italic; }

/* La etiqueta de lo que falta, sin alarma. Un "Falta" en rojo al lado de
   doscientos proyectos que todavia estan en tiempo convierte la pantalla en una
   lista de problemas que no lo son. */
.etiqueta--tenue {
    background: var(--regla-tenue);
    color: var(--tinta-suave);
    border-color: var(--regla);
}


/* ================================ el panel, que no se acoplaba  (2026-08-24) ==

   Carlos, viendolo en una laptop: "que rollo que paso con el menu lateral, no se
   acopla, se ve bien feo".

   CUATRO COSAS ESTABAN MAL, y las cuatro se notan justo en el rango de 900 a
   1300 px, que es el de una laptop normal. En un monitor grande no se ven, y
   por eso pasaron.

     1. DOS BARRAS DE DESPLAZAMIENTO ANIDADAS. El lateral llevaba
        `max-height: 100vh; overflow-y: auto`, o sea su propia barra ademas de
        la de la pagina. Con veinticuatro renglones de menu y una pantalla de
        800 px de alto, la lista se cortaba a la mitad -- "Enlaces" partido por
        el borde -- y para llegar a lo de abajo habia que descubrir que ese
        pedazo se desplaza aparte.

     2. EL LATERAL NO ENCOGIA. 252 px fijos. En un monitor son el 13% del ancho;
        en una laptop de 1100 son el 23%, y el contenido se queda con lo que
        sobra: la introduccion caia en cinco renglones de tres palabras.

     3. EL ENCABEZADO SE PARTIA EN DOS. El nombre de esta edicion mide casi 150
        caracteres, y con `flex-wrap: wrap` se comia el renglon entero y
        empujaba al usuario y al boton Salir a una segunda linea, pegados a la
        derecha y lejos de todo.

     4. EL SALTO A UNA COLUMNA ERA A 900 px, y entre 900 y 1200 el diseno ya
        estaba apretado sin haber cambiado todavia.
   ========================================================================== */

/* --------------------------------------------- 1 y 2: el lateral, otra vez --

   ANCHO ELASTICO. clamp() le pone piso y techo: nunca menos de 210 px -- donde
   "Calendario y cuotas" todavia cabe en un renglon -- ni mas de 252, que es lo
   que ya se veia bien en monitor. En medio, se acomoda al 19% del ancho.

   LA ALTURA COMPLETA Y **SOLO EL MENU SE DESPLAZA**. Antes se desplazaba el
   lateral entero, asi que el logo se iba con la lista. Ahora la marca se queda
   arriba, fija, y lo unico que corre es la lista de pantallas. Es la diferencia
   entre "esto tiene mas opciones abajo" y "esto se rompio". */
@media (min-width: 901px) {
    .panel {
        grid-template-columns: clamp(210px, 19vw, 252px) minmax(0, 1fr);
    }

    .panel__lateral {
        height: 100vh;
        max-height: 100vh;
        overflow: hidden;          /* el que se desplaza es el menu, no esto */
    }

    .panel__marca { flex: 0 0 auto; }

    .panel__menu {
        flex: 1 1 auto;
        min-height: 0;             /* sin esto, un hijo de flex no encoge y el
                                      overflow no aparece nunca */
        overflow-y: auto;
        overscroll-behavior: contain;   /* al llegar al final del menu no se
                                           arrastra la pagina de atras */
    }

    /* La barra del menu, discreta y del mismo verde. La de Windows por
       omision es un bloque gris claro que sobre el fondo se ve como un error
       de pintado. */
    /* Iba con #2C5F45 y #3C7A59 escritos a mano. Son exactamente
       --panel-realce al 34% y al 55% sobre el fondo, asi que se ve igual que
       antes, pero ahora sigue a la paleta en vez de quedarse atras. */
    .panel__menu { scrollbar-width: thin; scrollbar-color: rgba(var(--panel-realce-rgb), .34) transparent; }
    .panel__menu::-webkit-scrollbar { width: 8px; }
    .panel__menu::-webkit-scrollbar-track { background: transparent; }
    .panel__menu::-webkit-scrollbar-thumb {
        background: rgba(var(--panel-realce-rgb), .34);
        border-radius: 4px;
    }
    .panel__menu:hover::-webkit-scrollbar-thumb { background: rgba(var(--panel-realce-rgb), .55); }
}

/* ------------------------------------------------- 3: el encabezado entero --

   El nombre de la edicion se lleva el espacio que sobre, pero **no empuja a
   nadie**: el bloque del usuario se declara inencogible y el conjunto deja de
   envolver.

   Y el nombre se limita a dos renglones con puntos suspensivos. Cortarlo no es
   perder informacion: el nombre completo esta en el titulo de la pestania, en
   la portada y en la pantalla de la edicion. Aqui su trabajo es recordarte en
   cual estas parado, no que lo leas entero. */
@media (min-width: 901px) {
    .panel__cabeza { flex-wrap: nowrap; }

    .panel__edicion { flex: 1 1 auto; min-width: 0; }

    .panel__edicionNombre {
        display: -webkit-box;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
        overflow: hidden;
        line-height: 1.3;
    }

    .panel__usuario { flex: 0 0 auto; margin-left: auto; }
}

/* ------------------------------------- 4: el rango intermedio, mas holgado --

   Entre 901 y 1200 el lateral ya encogio por el clamp, pero el contenido
   agradece perder relleno: son 24 px que se convierten en texto. */
@media (min-width: 901px) and (max-width: 1200px) {
    .panel__cuerpo { padding: 22px 20px 48px; }
    .panel__cabeza { padding: 12px 20px; }
    .tarjeta { padding: 20px 18px; }
}

/* Las cifras bajan su minimo para que cinco quepan en un renglon mas seguido.
   Con 150 px, en 1100 caben cuatro y la quinta se queda sola abajo, que se lee
   como si fuera de otra categoria. */
.cifras { grid-template-columns: repeat(auto-fit, minmax(132px, 1fr)); }

/* -------------------------------------------------------- y en el telefono --

   El menu en rejilla de dos o tres columnas ya estaba bien resuelto; lo que
   faltaba es que el lateral no herede la altura fija ni el overflow que se le
   acaban de poner arriba. Como esas reglas viven dentro de un min-width, aqui
   no llegan, y esto solo lo deja escrito para quien lea. */
@media (max-width: 900px) {
    .panel__menu { overflow: visible; max-height: none; }
}


/* ------------------------------ la pastilla del estado, a su medida  (2026-08-24) --

   Carlos: "que salga al lado del titulo Edicion vigente y que la etiqueta solo
   abarque el ancho de la frase, que no abarque todo hasta el final".

   POR QUE SE ESTIRABA. `.panel__edicion` es un contenedor flex en columna, y en
   un flex la alineacion transversal por omision es `stretch`: cada hijo crece
   hasta el ancho del contenedor. Un `<span>` que normalmente mide lo que su
   texto, ahi dentro medía mil pixeles. Se veia una barra verde de lado a lado
   para decir dos palabras.

   Con `align-items: flex-start` cada hijo vuelve a medir lo suyo, y la pastilla
   sube a un renglon horizontal junto al rotulo.
   -------------------------------------------------------------------------- */

.panel__edicion { align-items: flex-start; }

.panel__edicionCima {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;      /* en angosto la pastilla baja sola, sin desbordar */
}

/* El rotulo ya no necesita ocupar su propio renglon. */
.panel__edicionCima .panel__edicionRotulo { line-height: 1.2; }

/* La pastilla, por si acaso, tampoco se estira aunque cambie el contenedor. */
.panel__edicionCima .etiqueta { align-self: center; width: auto; flex: 0 0 auto; }


/* ================================= la letra del panel  (2026-08-24) ==

   Carlos: "siento que el tipo de letra no ayuda mucho al sistema admin, ponle
   el tipo de letra que usamos en el sistema admin del proyecto SPAC".

   SPAC usa 'Inter' con 'Segoe UI' y 'Source Sans Pro' de respaldo. Aqui va la
   misma pila, y por la misma razon que alla: **afuera y adentro se leen
   distinto**.

   El sitio publico lo visita alguien una vez, unos minutos, y Barlow -- una
   grotesca de senializacion, condensada en los titulos -- le da caracter a la
   portada. El panel lo mira un administrador ocho horas seguidas, y son tablas,
   formularios y columnas de numeros. Ahi el caracter estorba: lo que se
   agradece es una letra neutra, de altura de x generosa y cifras parejas.

   SE REDEFINEN LOS TOKENS, NO CADA REGLA. Las 25 reglas que usan var(--f-titulo)
   y var(--f-texto) siguen igual; lo unico que cambia es lo que esas variables
   valen dentro de .panel. Por eso el sitio publico no se entera.

   LOS TITULOS TAMBIEN. Podria dejarse Barlow Condensed para los encabezados,
   pero una condensada sobre una neutra se ve como dos sistemas pegados. En un
   panel, la jerarquia la dan el tamanio y el peso, no un cambio de familia.
   ========================================================================== */

.panel {
    --f-titulo: "Inter", "Segoe UI", "Source Sans Pro", system-ui, -apple-system, sans-serif;
    --f-texto:  "Inter", "Segoe UI", "Source Sans Pro", system-ui, -apple-system, sans-serif;
    /* --f-dato se queda: los folios y los importes siguen en monoespaciada, que
       es lo que los alinea en columna. */
}

/* Inter trae numeros de ancho variable por omision. En una tabla eso hace que
   las columnas de cifras bailen renglon a renglon. `tnum` los pone todos del
   mismo ancho, que es para lo que existe. */
.panel .tabla,
.panel .cifra__numero,
.panel .dato { font-variant-numeric: tabular-nums; }

/* Barlow Condensed era estrecha, asi que los titulos podian ir grandes sin
   ocupar de mas. Inter es mas ancha: los mismos tamanios se sienten pesados y
   el interlineado queda suelto. Se ajusta de una vez, en un solo lugar. */
.panel__titulo h1 { font-size: 1.7rem; letter-spacing: -.01em; line-height: 1.2; }
.panel .tarjeta h2 { font-size: 1.12rem; letter-spacing: -.005em; }
/* Aqui iba `.panel__marca span`, la escala de la palabra "PANEL" en Inter. La
   palabra se quito el 2026-08-24 y la regla se fue con ella: una regla que ya
   no tiene a quien aplicarse solo sirve para confundir al siguiente. */
.panel .cifra__numero { font-size: 1.75rem; letter-spacing: -.02em; }


/* ============================ los botones que descargan  (2026-08-24) ==

   Carlos: el de Excel verde, el de los trabajos azul, y los dos con su icono.

   POR QUE COLORES DISTINTOS Y NO DOS VERDES. Bajan cosas que no se parecen: uno
   una lista de renglones, el otro cientos de megabytes de PDF. Y uno respeta el
   filtro de la pantalla y el otro no. Dos botones identicos, pegados, invitan a
   picar el equivocado -- y el equivocado aqui son doscientos archivos.

   EL AZUL NO SALE DE LA PALETA DE LA MARCA A PROPOSITO. Todos los verdes del
   sistema significan "esto es del congreso"; un segundo verde para "otra
   descarga" no distinguiria nada. El azul se toma de --info, que ya existe y ya
   se usa para lo informativo.
   ========================================================================== */

.btn--azul {
    background: var(--info);
    color: #fff;
    border-color: var(--info);
    --btn-canto: #123C5C;
}
.btn--azul:hover,
.btn--azul:focus-visible {
    background: #17456A;      /* el mismo azul, mas hondo */
    border-color: #17456A;
    color: #fff;
}

/* ---------------------------------------------------- el icono del boton --

   El .btn ya es inline-flex, asi que el icono y el texto se alinean solos. Lo
   unico que hace falta es que el SVG no se encoja cuando el texto es largo, y
   que quede opticamente centrado: un icono alineado a la linea base de la letra
   se ve caido, y por eso baja un pixel.  */
.btn__icono {
    flex: 0 0 auto;
    display: block;
    margin-top: -1px;
}

/* En un boton chico el icono tambien. */
.btn--chico .btn__icono { width: 15px; height: 15px; }


/* ================= los contadores, al lado del titulo  (2026-08-24) ==

   Carlos: "quiero que los contadores aparezcan al lado derecho de Participantes
   inscritos, porque siento que esta muy saturada la pantalla".

   Tenia razon y el ahorro es real: la tarjeta del resumen ocupaba tres
   renglones de alto -- encabezado, cifras y nota -- para cinco numeros. Aqui
   caben en el hueco que ya estaba vacio a la derecha del titulo.

   `space-between` y no `margin-left: auto`: con auto, al envolver en angosto
   las cifras se quedarian pegadas al borde derecho en su renglon nuevo. Asi
   arrancan desde la izquierda, alineadas con el titulo.
   ========================================================================== */

.panel__titulo--conCifras {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 12px 28px;
    margin-bottom: 20px;
}

.panel__titulo--conCifras h1 { margin-bottom: 0; }

/* CADA CIFRA EN SU CUADRITO. Carlos: "mejor si enciralos en cuadritos".

   Sin caja, cinco pares de numero y palabra sueltos al lado del titulo se leen
   como una sola frase larga: hay que buscar donde termina uno y empieza el
   otro. El recuadro los separa sin necesidad de mirar.

   Se quedan chicos a proposito: son cuadritos, no las tarjetas de antes. Lo
   que se gano al subirlos junto al titulo -- una tarjeta entera de alto -- no
   se puede devolver ahora en relleno. */
.panel__titulo--conCifras .cifras {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 0;
}

.panel__titulo--conCifras .cifra {
    padding: 7px 14px;
    background: var(--fondo);
    border: 1px solid var(--regla);
    border-left: 3px solid var(--regla);
    border-radius: var(--radio-sm);
    min-width: 88px;
    text-align: center;
}

.panel__titulo--conCifras .cifra__numero {
    display: block;
    font-size: 1.5rem;
    line-height: 1.15;
    margin: 0;
}

/* EL ROTULO HEREDA EL COLOR DE SU NUMERO, no va en gris.

   Carlos lo pidio asi, y ademas amarra las dos mitades: leidas de lejos, el
   numero y su palabra se ven como una sola cosa en vez de un dato con una
   etiqueta suelta debajo. */
.panel__titulo--conCifras .cifra__que {
    display: block;
    font-size: .74rem;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: inherit;
    opacity: .85;      /* el rotulo es mas chico: sin esto pesa igual que el numero */
    margin: 0;
}

.panel__titulo--conCifras .cifra          { color: var(--tinta); }
.panel__titulo--conCifras .cifra--ok      { border-left-color: var(--ok);     color: var(--ok); }
.panel__titulo--conCifras .cifra--alerta  { border-left-color: var(--alerta); color: var(--alerta); }

/* El numero ya no fija su propio color: lo toma del contenedor, y asi el par
   completo cambia con una sola regla. */
.panel__titulo--conCifras .cifra__numero,
.panel__titulo--conCifras .cifra--ok .cifra__numero,
.panel__titulo--conCifras .cifra--alerta .cifra__numero { color: inherit; }

/* En angosto las cifras bajan solas por el flex-wrap del contenedor; aqui solo
   se aprieta el espacio entre ellas para que quepan mas por renglon. */
@media (max-width: 700px) {
    .panel__titulo--conCifras { gap: 12px 0; }
    .panel__titulo--conCifras .cifras { gap: 6px; }
    .panel__titulo--conCifras .cifra { padding: 6px 10px; min-width: 76px; }
    .panel__titulo--conCifras .cifra__numero { font-size: 1.3rem; }
    .panel__titulo--conCifras .cifra__que { font-size: .68rem; }
}


/* ================== la previa del banner, sin disfraz  (2026-08-24) ==

   Carlos: "quitale todo ese texto que tiene adentro del cuadro negro y que no
   sea negro el fondo, que sea invisible".

   POR QUE ERA NEGRO. La previa imitaba el hero de la portada cuando el banner
   iba de FONDO: recortado, al 34% de opacidad y bajo un velo oscuro, con el
   titulo blanco encima. Servia para ver cuanto del banner quedaba tapado.

   YA NO ES ASI. El banner es una lamina completa sobre blanco, entera y sin
   nada escrito encima. La previa que quedaba mostraba algo que el visitante no
   va a ver nunca, y eso es peor que no tener previa: un administrador podria
   descartar una imagen buena creyendo que va a quedar oscurecida.

   Ahora la previa ensenia exactamente lo que se va a publicar.
   ========================================================================== */

.maqueta {
    background: transparent;

    /* EL RECUADRO SE QUEDA GRANDE. Al quitarle el velo lo deje colapsar a
       120 px y quedo un cintillo: Carlos lo pidio "igual grandesito como
       estaba". Un area de previa chica no deja juzgar una imagen, que es
       justo para lo que existe.

       Sin proporcion fija: la lamina conserva la del archivo, y el alto
       minimo solo sostiene la caja mientras no hay imagen elegida. */
    aspect-ratio: auto;
    min-height: 260px;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* Entera y opaca, en el flujo: es lo que se va a ver. */
.maqueta__img {
    position: static;
    width: 100%;
    height: auto;
    object-fit: contain;
    opacity: 1;
}

/* EL ROTULO DE "SIN IMAGEN", SIN CAJA Y EN NEGRO.

   Tenia fondo oscuro al 55% y letra clara, porque iba encima de la maqueta del
   hero que era negra. Sin esa maqueta, ese recuadro gris flotando en medio de
   un area blanca se veia como un error de pintado.

   Ahora es solo texto: dice que ahi va la previa y desaparece en cuanto hay
   imagen. */
.maqueta__vacia {
    position: static;
    background: none;
    color: var(--tinta);
    font-size: .95rem;
}


/* ---------------------------------------- el boton de eliminar  (2026-08-24) --

   En linea y no relleno de rojo. Un boton rojo solido al lado de dos botones
   normales se lee como la accion principal de la fila, y es al reves: eliminar
   es lo que casi nunca se hace y de lo que no se vuelve.

   Se pinta de rojo al pasar el mouse: para entonces la intencion ya esta, y el
   color confirma que eso es lo que se va a hacer. */
.btn--peligro {
    background: transparent;
    color: var(--error);
    border-color: var(--error);
}
.btn--peligro:hover,
.btn--peligro:focus-visible {
    background: var(--error);
    border-color: var(--error);
    color: #fff;
}


/* ========================= el panel, mas apretado  (2026-08-24) ==

   Carlos: "siento que el texto del contenido del sistema admin esta quitando
   mucho espacio, puedes reducir el texto 1 o 2px?" y "los botones tambien, se
   ven muy grandes".

   LO QUE SE MIDIO ANTES DE TOCAR NADA:

     texto del cuerpo   17 px     <- heredado del sitio publico
     titulo h1          27.2 px
     encabezado h2      17.9 px
     celda de tabla     15.2 px con 10/12 de relleno
     boton              15.2 px con 8/16 de relleno
     tarjeta            24/26 de relleno, 22 de separacion
     cuerpo del panel   28/30/60 de relleno

   POR QUE ESTABA ASI. El panel hereda la escala del sitio publico, y alla los
   17 px estan bien: es una pagina que alguien lee una vez, de corrido, quiza en
   el telefono. Un panel es lo contrario -- tablas y formularios que se miran
   horas --, y ahi cada pixel de mas es un renglon menos que cabe en pantalla.

   NO SE TOCA EL SITIO PUBLICO. Todo cuelga de .panel.

   Y NO ES SOLO LA LETRA. Bajar dos pixeles y dejar el relleno igual no se
   habria notado: lo que de verdad se come el espacio son los 24 px de las
   tarjetas y los 22 de separacion entre ellas. Se baja el conjunto, en
   proporcion, para que siga viendose armado y no encogido a la fuerza.
   ========================================================================== */

/* ------------------------------------------------------------- el texto -- */
.panel__cuerpo { font-size: 15px; }

.panel__titulo h1        { font-size: 1.4rem; }
.panel .tarjeta h2       { font-size: 1rem; margin-bottom: 10px; }
.panel__intro            { font-size: .94rem; margin-bottom: 16px; }
.panel .forma__ayuda     { font-size: .82rem; }

/* ---------------------------------------------------------- el espacio -- */
.panel__cuerpo { padding: 20px 24px 40px; }

.panel .tarjeta {
    padding: 16px 18px;
    margin-bottom: 14px;
}

/* ------------------------------------------------------------ la tabla -- */
/* Es donde mas se gana: cada renglon que adelgaza es un proyecto mas visible
   sin desplazar. */
.panel .tabla td { padding: 7px 10px; font-size: .9rem; }
.panel .tabla th { padding: 7px 10px; font-size: .72rem; }
.panel .tabla__secundario { font-size: .78rem; }

/* --------------------------------------------------- encabezados que ordenan
   El GridView con AllowSorting pinta cada titulo como un <a> con un
   __doPostBack adentro. Sin esto salen azules y subrayados en medio de una
   fila de titulos grises en versalitas: parecen enlaces a otra pagina, que es
   justo lo que no son. */
.panel .tabla th a {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: inherit;
    text-decoration: none;
    cursor: pointer;
}
.panel .tabla th a:hover,
.panel .tabla th a:focus { color: var(--tinta); }

/* LA FLECHITA. Tenue en toda columna ordenable -- para que se vea que se puede
   picar antes de picarla -- y solida en la que manda. Es un triangulo de
   bordes, no un caracter: asi hereda el color y no depende de que la fuente
   traiga el simbolo. */
.panel .tabla th a::after {
    content: "";
    width: 0; height: 0;
    border-left: 4px solid transparent;
    border-right: 4px solid transparent;
    border-bottom: 5px solid currentColor;
    opacity: .25;
}
.panel .tabla th.tabla__orden--asc,
.panel .tabla th.tabla__orden--desc { color: var(--tinta); }
.panel .tabla th.tabla__orden--asc a::after,
.panel .tabla th.tabla__orden--desc a::after { opacity: 1; }
.panel .tabla th.tabla__orden--desc a::after {
    border-bottom: 0;
    border-top: 5px solid currentColor;
}

/* ----------------------------------------------------------- controles -- */
.panel .btn {
    font-size: .88rem;
    padding: 7px 14px;
}
.panel .btn--chico  { font-size: .8rem;  padding: 5px 11px; }

/* btn--grande existe para el sitio publico, donde un boton es una llamada a la
   accion. En el panel no hay llamadas a la accion: hay tareas. Se iguala al
   tamanio normal para que una pantalla no salga con botones del doble por
   haber copiado el molde de afuera. */
.panel .btn--grande { font-size: .92rem; padding: 9px 18px; }

.panel .entrada {
    font-size: .9rem;
    padding: 8px 11px;

    /* MISMO ALTO EL CUADRO DE TEXTO Y LAS LISTAS.

       Con el mismo relleno salian de alturas distintas, y en un renglon de
       filtros eso se ve como un escalon. La causa es que un <input> y un
       <select> NO calculan igual su alto de linea cuando nadie se lo dice: el
       input toma "normal" y el select el que le da el sistema, que en Windows
       es mas apretado. Peor todavia: el <select> IGNORA el line-height que se
       le ponga -- la hoja del navegador se lo fija con !important y el autor no
       le puede ganar -- asi que igualarlos "por aritmetica" no es posible.

       Se igualan por piso: los dos se quedan por debajo de 38 px de alto
       natural (1.3 de interlineado deja el input en 36.7 y el select en 37) y
       el min-height los sube a los dos a 38 exactos.

       ES min-height Y NO height A PROPOSITO. Con un alto fijo, el dia que
       alguien tenga el navegador con la letra grande el contenido no cabe y se
       recorta: medido aqui, con la letra base en 24 px el <select> pide 46 px y
       se quedaba encerrado en 38. Con min-height los dos crecen juntos -- a esa
       misma medida salen 46.06 y 46.00 -- y no se recorta nada. */
    line-height: 1.3;
    box-sizing: border-box;
    min-height: 38px;
}

/* EL MISMO JUEGO DE REGLAS, DELETREANDO EL TIPO DEL INPUT.

   No es copia de mas: `.entrada` de arriba viene tambien de un selector con
   `input[type="text"].entrada`, que pesa mas que `.panel .entrada` por llevar
   un selector de atributo. Sin esta segunda regla el cuadro de texto se queda
   con la letra y el relleno del sitio publico (16 px y 11 px) y sale mas alto
   que las listas de su propio renglon: era lo que pasaba antes de medirlo. */
.panel input[type="text"].entrada, .panel input[type="email"].entrada,
.panel input[type="password"].entrada, .panel input[type="tel"].entrada,
.panel input[type="number"].entrada {
    font-size: .9rem;
    padding: 8px 11px;
    line-height: 1.3;
}

/* LA FECHA MIDE UN PELO MAS QUE LAS DEMAS, Y NO ES EL TEXTO.

   Un input de fecha no pinta texto suelto: pinta los tres cuadritos del dia,
   el mes y el anio, mas el boton del calendario, y ese armado del navegador
   pide 20.72 px de alto propio en vez de los 18.72 que da el interlineado. Con
   el relleno de las demas el campo se iba a 38.72 y quedaba un escalon de .72
   px contra la lista de al lado. Se le quita 1 px de relleno arriba y abajo:
   el alto natural baja a 36.72, el min-height lo sube a 38 y la fila queda
   pareja. */
.panel input[type="date"].entrada { padding-top: 7px; padding-bottom: 7px; }

/* El textarea es la excepcion: crece a lo alto a proposito, y conserva el
   interlineado holgado del sitio -- 1.3 es para que un renglon quepa en 38 px,
   no para leer un parrafo. */
.panel textarea.entrada { min-height: 120px; line-height: 1.55; }

.panel .forma__campo { margin-bottom: 12px; }
.panel .forma__campo label { font-size: .84rem; }

/* --------------------------------------------------------- los avisos -- */
.panel .aviso { padding: 10px 14px; font-size: .9rem; margin-bottom: 14px; }

/* ------------------------------------------------------- las etiquetas -- */
.panel .etiqueta { font-size: .7rem; padding: 3px 8px; }


/* ================================ la zona para soltar archivos  (2026-08-24) ==

   Carlos: "el boton de Archivo de imagen ponle un disenio mas bonito, tambien
   en donde el participante sube su trabajo en extenso".

   Sustituye al control gris del navegador en las dos pantallas que suben algo:
   Pages/Web/Galeria.aspx (el banner) y Portal/Trabajo.aspx (el extenso).

   ---------------------------------------------------------------------------
   LO QUE NO SE HIZO, Y ES LO IMPORTANTE
   ---------------------------------------------------------------------------

   El input NO esta escondido. Aqui es facilisimo romper la regla que ya costo
   una pagina en blanco -- *nunca escondas con CSS algo que necesita JavaScript
   para volver a aparecer* --, porque la receta que circula por todos lados es
   `input { display: none }` y un script que reenvia el clic. Con esa receta,
   el dia que sitio.js no cargue, el participante ve un recuadro bonito que no
   hace absolutamente nada y no puede entregar su trabajo.

   Aqui el input esta ENCIMA del recuadro, estirado a toda la caja y con
   opacity 0. Sigue siendo el elemento que recibe el clic, el que recibe el
   archivo que se arrastra y el que se alcanza con Tab. Ademas el recuadro
   entero es un <label for>, que abre el selector por si solo.

   Resultado: sin una linea de JavaScript se puede elegir archivo picando,
   arrastrando o tabulando. El script solo escribe el nombre del archivo y
   pinta el resaltado del arrastre.

   opacity: 0 y NO visibility/display: los dos ultimos sacan el campo del
   recorrido del teclado. Un campo transparente sigue siendo un campo.
   ============================================================================= */

.soltar {
    position: relative;
    display: block;
    padding: 22px 18px;

    border: 2px dashed rgba(var(--piv-verde-rgb), .38);
    border-radius: var(--radio);
    background: var(--fondo-alt);

    cursor: pointer;
    text-align: center;

    transition: border-color .15s ease, background-color .15s ease,
                box-shadow .15s ease;
}

/* `.forma__campo label` viste las etiquetas con la condensada en negrita. Este
   label no es una etiqueta: es una caja. Se le devuelve la tipografia normal
   para que no salga con letra de titulo.

   El selector lleva `label.soltar` a proposito: `.forma__campo label` pesa mas
   que `.soltar` a secas, y el orden en el archivo no le gana a la
   especificidad. Sin el elemento delante, esta regla no aplicaria nunca. */
label.soltar,
.panel .forma__campo label.soltar {
    font-family: var(--f-texto);
    font-weight: 400;
    font-size: 1rem;
    letter-spacing: 0;
}

.soltar:hover {
    border-color: var(--piv-verde);
    background: var(--piv-verde-lavado);
}

/* EL FOCO SE VE. El input es transparente, asi que su propio anillo de foco no
   se nota: lo pinta la caja con :focus-within. Sin esto, quien navega con Tab
   pasa por el campo sin enterarse. */
.soltar:focus-within {
    border-color: var(--piv-verde);
    background: var(--piv-verde-lavado);
    box-shadow: 0 0 0 3px rgba(var(--piv-verde-rgb), .22);
}

/* ------------------------------------------------------------- el campo -- */

.soltar__campo {
    position: absolute;
    top: 0; right: 0; bottom: 0; left: 0;
    width: 100%;
    height: 100%;

    /* Transparente, no ausente. Ver el bloque de arriba. */
    opacity: 0;
    cursor: pointer;

    /* Encima de la cara, para que el archivo que se arrastra caiga en el
       input y no en el adorno. */
    z-index: 2;
}

/* ------------------------------------------------------------- la cara -- */

.soltar__cara {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 5px;

    /* Debajo del input, y sin robarle el puntero: cualquier clic tiene que
       llegar al campo o, en su defecto, al label. */
    position: relative;
    z-index: 1;
    pointer-events: none;
}

.soltar__icono {
    display: block;
    color: var(--piv-verde);
    transition: transform .15s ease, color .15s ease;
}

.soltar__texto {
    font-weight: 600;
    color: var(--tinta);
    line-height: 1.35;
}

.soltar__reglas {
    font-size: .87rem;
    color: var(--tenue);
    line-height: 1.4;
}

/* ------------------------------------------- mientras se arrastra encima -- */

/*  La clase la pone js/sitio.js. Es un aniadido puro: sin ella el archivo se
    suelta igual, solo que sin aviso visual. */
.soltar--encima {
    border-color: var(--piv-verde);
    border-style: solid;
    background: var(--piv-verde-lavado);
    box-shadow: 0 0 0 3px rgba(var(--piv-verde-rgb), .22);
}

.soltar--encima .soltar__icono { transform: translateY(-2px) scale(1.06); }

/* -------------------------------------------------- ya hay algo elegido -- */

/*  Que se NOTE que ya hay archivo. El estado anterior -- "no pasa nada al
    elegir" -- es el que hacia que la gente subiera dos veces el mismo PDF por
    no estar segura de que el primero se hubiera tomado. */
.soltar--lleno {
    border-style: solid;
    border-color: var(--ok);
    background: var(--ok-bg);
}

.soltar--lleno .soltar__icono { color: var(--ok); }

.soltar--lleno .soltar__texto {
    color: var(--ok);
    overflow-wrap: anywhere;
}

/*  Con foco Y con archivo, mandan los colores del archivo: el halo basta para
    decir "aqui esta el teclado", y no hay razon para borrar el "ya hay algo"
    justo cuando alguien esta tabulando por el formulario. Va DESPUES de
    `.soltar:focus-within` a proposito: pesan lo mismo, asi que gana la de
    abajo. */
.soltar--lleno:focus-within {
    border-color: var(--ok);
    background: var(--ok-bg);
}

/* ------------------------------------------------------ menos movimiento -- */

@media (prefers-reduced-motion: reduce) {
    .soltar,
    .soltar__icono { transition: none; }
    .soltar--encima .soltar__icono { transform: none; }
}

/* ------------------------------------------------ la escala del panel -- */

/*  El panel corre en 15 px y con las tarjetas apretadas. Una zona con el
    tamanio del sitio publico se veria de otro sistema. */
.panel .soltar { padding: 16px 14px; }
.panel .soltar__cara { gap: 4px; }
.panel .soltar__texto { font-size: .92rem; }
.panel .soltar__reglas { font-size: .8rem; }


/* ================== el detalle del proyecto  (2026-08-24) ==

   ES UNA CAPA PINTADA POR EL SERVIDOR, no un modal de JavaScript. Se abre
   porque el code-behind pone Visible en true y se cierra con un postback. Sin
   una linea de script funciona igual, que es la regla de no esconder con CSS
   algo que necesita JavaScript para volver.

   `position: fixed` con el fondo oscurecido: lo de atras se ve pero queda
   claro que no se puede tocar. El scroll vive en la caja, no en la pagina, para
   que un resumen largo no arrastre la bandeja de abajo.
   ========================================================================== */

.capa {
    position: fixed;
    inset: 0;
    z-index: 50;
    background: rgba(20, 24, 15, .55);
    display: flex;
    align-items: flex-start;
    justify-content: center;
    /* 24px y no 40: con el visor del PDF adentro, cada pixel de margen es un
       pixel menos de documento visible. */
    padding: 24px 20px;
    overflow-y: auto;
}

.capa__caja {
    background: var(--fondo);
    border-radius: var(--radio);
    box-shadow: 0 24px 60px -20px rgba(20, 24, 15, .5);
    width: 100%;
    max-width: 1100px;
    max-height: calc(100vh - 48px);
    display: flex;
    flex-direction: column;
}

.capa__cima {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
    padding: 18px 20px 14px;
    border-bottom: 1px solid var(--regla);
}
.capa__cima h2 { margin: 0; font-size: 1.06rem; line-height: 1.3; }
.capa__codigo {
    margin: 0 0 3px;
    font-family: var(--f-dato);
    font-size: .78rem;
    color: var(--tenue);
    letter-spacing: .04em;
}

/* La equis: area tocable de 34px, no un caracter suelto de 12. */
.capa__cerrar {
    flex: 0 0 auto;
    display: inline-flex; align-items: center; justify-content: center;
    width: 34px; height: 34px;
    font-size: 1.5rem; line-height: 1;
    color: var(--tenue);
    border: 0; border-radius: var(--radio-sm);
    background: transparent; text-decoration: none;
}
.capa__cerrar:hover { background: var(--regla-tenue); color: var(--tinta); }

.capa__cuerpo { padding: 18px 20px 22px; overflow-y: auto; }

.capa__seccion { margin-top: 20px; padding-top: 16px; border-top: 1px solid var(--regla-tenue); }

/* LA PRIMERA SECCION NO LLEVA SEPARADOR NI HUECO ARRIBA.

   El margen, el relleno y la raya existen para SEPARAR una seccion de la
   anterior. Cuando el modal ensenia una sola -- que es lo que pasa al abrirlo
   desde "Descripcion" o desde "Trabajo Ext." --, no hay anterior de la cual
   separarse, y quedaba un hueco en blanco con una raya suelta debajo del
   titulo. Se veia como un error de pintado. */
.capa__cuerpo > .capa__seccion:first-child {
    margin-top: 0;
    padding-top: 0;
    border-top: 0;
}
.capa__seccion h3 {
    font-size: .78rem; font-weight: 600;
    letter-spacing: .08em; text-transform: uppercase;
    color: var(--tenue);
    margin: 0 0 8px;
}

/* La ficha de datos: rotulo y valor en dos columnas que se apilan en angosto. */
.datos {
    display: grid;
    grid-template-columns: minmax(120px, auto) 1fr;
    gap: 4px 16px;
    margin: 0;
    font-size: .9rem;
}
.datos dt { color: var(--tenue); }
.datos dd { margin: 0; }

@media (max-width: 560px) {
    .datos { grid-template-columns: 1fr; gap: 0 0; }
    .datos dt { margin-top: 8px; }
}

.lista-equipo { list-style: none; margin: 0; padding: 0; }
.lista-equipo li {
    padding: 7px 0;
    border-bottom: 1px solid var(--regla-tenue);
}
.lista-equipo li:last-child { border-bottom: 0; }
.lista-equipo__quien { display: block; font-weight: 500; }

/* --------------------------------------------- lo que se pica en la tabla --

   Un numero y una etiqueta que abren algo tienen que verse pinchables, pero sin
   convertirse en botones: en una tabla de doscientos renglones, doscientos
   botones son ruido. Subrayado punteado, que dice "esto hace algo" sin gritar. */
.enlace-dato {
    color: var(--piv-verde-hondo);
    font-weight: 600;
    text-decoration: none;
    border-bottom: 1px dotted currentColor;
}
.enlace-dato:hover { color: var(--tinta); }

.enlace-etiqueta { text-decoration: none; }
.enlace-etiqueta:hover .etiqueta { filter: brightness(.94); }


/* ------------------------------- el visor del PDF en la capa  (2026-08-24) --

   SE LLAMABA `.visor` Y POR ESO NO SE VEIA NADA. Ese nombre ya estaba tomado
   arriba, en la linea ~904: el lightbox del sitio publico, que es
   `position: fixed`, cubre la ventana entera y arranca con `opacity: 0`.

   Este bloque va despues, asi que ganaba en lo que redefine -- borde, radio,
   fondo -- pero **no redefinia `position`, `inset`, `display` ni `opacity`**.
   Esas seguian llegando del lightbox. Resultado: el recuadro del PDF se salia
   del modal, se pegaba a la ventana completa y quedaba **invisible por el
   `opacity: 0`**. Ni el PDF ni el texto de respaldo. Se veia un hueco en
   blanco y parecia que el archivo estaba roto.

   Por eso ahora es su propio bloque, `vistapdf`, sin nada en comun con el
   lightbox. Si alguien lo vuelve a llamar `visor`, vuelve a desaparecer.

   Alto fijo y no `auto`: un PDF no tiene alto intrinseco que el navegador pueda
   deducir, asi que sin esto el <object> se colapsa a cero y no se ve nada. 460px
   alcanza para leer la primera pagina completa, que es de lo que se trata: mirar
   por encima antes de decidir si vale la pena bajarlo.
   -------------------------------------------------------------------------- */
.vistapdf {
    border: 1px solid var(--regla);
    border-radius: var(--radio-sm);
    overflow: hidden;
    background: var(--fondo-alt);
}
/* ALTO DE VERDAD, no una tira. En SPAC el visor equivalente usa 82vh y esa es
   la referencia. Con 460 px fijos una hoja tamanio carta salia cortada por la
   mitad y habia que desplazar dentro del visor para leer un parrafo.

   El gris es el del propio visor de Chrome: sin el, mientras el PDF carga se
   ve un rectangulo blanco que parpadea. */
.vistapdf__doc {
    display: block;
    width: 100%;
    height: 78vh;
    min-height: 460px;
    border: 0;
    background: #525659;
}
@media (max-height: 700px) { .vistapdf__doc { height: 62vh; min-height: 320px; } }

/* El respaldo solo se ve si el <object> no pudo pintar el PDF. */
.vistapdf__respaldo { margin: 0; padding: 28px 20px; text-align: center; color: var(--tinta-suave); }

@media (max-width: 700px) {
    /* En un telefono, 460px de visor dejan la ficha fuera de pantalla. */
    .vistapdf__doc { height: 300px; }
}


/* ------------------------- los botones de la fila, apilados  (2026-08-24) --

   Carlos: "los quiero hacia abajo, no en lateral".

   Y ademas cabe mejor: tres botones en una fila se llevan doscientos pixeles de
   ancho, que es una columna de datos menos. Apilados, la columna "Ver" mide lo
   que mide el boton mas largo.

   `stretch` para que los tres queden del mismo ancho: tres botones de anchos
   distintos, uno debajo de otro, se ven como un escalon.
   -------------------------------------------------------------------------- */
.tabla__acciones {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 4px;
    min-width: 104px;
}
.tabla__acciones .btn { justify-content: center; width: 100%; }


/* ------------------- los tres botones de la fila, iguales  (2026-08-24) --

   Carlos: "Detalles, Descripcion y Trabajo en extenso, los quiero del mismo
   tamanio y con diferentes colores y su icono".

   MISMO TAMANIO, Y NO ES SOLO ESTETICA. Apilados, tres anchos distintos se ven
   como un escalon y la columna deja de tener un borde recto. Con el icono
   alineado a la izquierda y el texto arrancando en el mismo punto, los tres se
   leen como una lista y no como tres cosas sueltas.

   EL COLOR TAMPOCO. En una tabla de doscientos renglones son seiscientos
   botones: de un vistazo hay que saber cual es cual sin detenerse a leer. El
   azul del trabajo es el MISMO del boton de descarga en lote, porque hacen lo
   mismo -- entregar el PDF --, y eso se aprende una vez.
   -------------------------------------------------------------------------- */

.btn--fila {
    font-size: .78rem;
    padding: 5px 10px;
    width: 100%;
    justify-content: flex-start;   /* el texto arranca donde el de arriba */
    gap: 7px;
}
.btn--fila .btn__icono { width: 15px; height: 15px; }

/* El morado sale de la paleta de estados, no de la marca: los verdes del
   sistema significan "esto es del congreso", y un tercer verde no distinguiria
   nada. */
.btn--morado {
    background: #5B4B8A;
    color: #fff;
    border-color: #5B4B8A;
}
.btn--morado:hover,
.btn--morado:focus-visible {
    background: #473A6E;
    border-color: #473A6E;
    color: #fff;
}


/* ============================ el menu del panel en angosto  (2026-08-24) =====

   Carlos, con el emulador de movil de Chrome: "siento que debes arreglar el
   menu, talvez que sean menu padres e hijos".

   LO QUE PASABA, MEDIDO. En un telefono de 390 px el lateral se volvia una
   rejilla horizontal de dos columnas con las 24 entradas, y el contenido no
   empezaba hasta el pixel 1094 -- mas de pantalla y media de menu antes del
   primer dato. En la tablet de 800, hasta el 826.

   LO QUE SE HACE, Y POR QUE ASI:

   1. EL CONTENIDO ES LO PRIMERO. El lateral sale del flujo y se vuelve un
      cajon fijo que se abre con el boton de la cabecera. El menu deja de
      empujar al contenido: empieza debajo del encabezado y ya.

   2. LOS GRUPOS SE PLIEGAN, y son <details> de verdad. La jerarquia ya estaba
      en Config.Menu; aqui solo se deja de aplanar. El navegador hace el
      plegado, el teclado lo abre con Enter y el lector de pantalla lo anuncia
      sin una linea de JavaScript. En un telefono se ven CINCO renglones en vez
      de veinticuatro.

   3. EL CORTE SIGUE EN 900 px, y no se movio a proposito. A 1024 -- tablet en
      horizontal -- el lateral mide 210 px por el clamp y deja 814 para la
      tabla: cabe, y tenerlo siempre a la vista vale mas que ganar 210 px. A
      820 -- la misma tablet en vertical -- dejaria 568 px para nueve columnas,
      que es justo donde la tabla empieza a desplazarse dentro de su caja. Asi
      que la tablet vertical se lleva el cajon y la horizontal el lateral de
      siempre, que es lo que cada una aguanta.

   4. EN ESCRITORIO NO CAMBIA NADA. Es un panel que se mira ocho horas al dia:
      cualquier cambio ahi es costo sin beneficio. Todo lo de este bloque
      cuelga de @media (max-width: 900px), y de los grupos plegables se
      neutraliza hasta el detalle -- ver la nota de mas abajo.
   ========================================================================== */

/* ---------------------------------------------- 1. los grupos, en cualquier
   ancho. Un <summary> es `display: list-item` y trae su triangulito propio;
   aqui se apaga en los dos dialectos porque WebKit todavia usa el pseudo
   elemento viejo. El nuestro se dibuja abajo, y solo en angosto. */
.panel__grupo > summary {
    display: block;
    list-style: none;
    cursor: default;
}
.panel__grupo > summary::-webkit-details-marker { display: none; }

/* EN ESCRITORIO EL TITULO NO SE PICA. Los grupos llegan abiertos desde el
   servidor y sitio.js los deja abiertos arriba de 900; falta impedir que un
   clic los cierre, porque eso SI seria un cambio en escritorio. Con el raton
   lo resuelve `pointer-events`; con el tabulador lo resuelve sitio.js, que le
   pone tabindex="-1" al <summary> -- antes era un <h3> y tampoco recibia foco.
   Las dos mitades juntas dejan el titulo exactamente igual de inerte que ayer.

   No se intento forzarlo con `details[open]` desde el CSS: el contenido de un
   <details> cerrado lo esconde el motor en su shadow DOM, y no hay una regla
   de fuera que lo vuelva a ensenar en todos los navegadores. */
@media (min-width: 901px) {
    .panel__grupo > summary { pointer-events: none; }
}

/* ------------------------------------------- 2. el boton de la cabecera ---
   NACE `hidden` desde la master y lo enciende sitio.js. El `:not([hidden])`
   no es adorno: sin el, este `display` le ganaria al del atributo y el boton
   se veria aunque el JavaScript no hubiera cargado -- un control que no hace
   nada es peor que no tenerlo. */
.panel__menuBtn {
    display: none;
    align-items: center;
    gap: 10px;
    min-height: 44px;
    padding: 8px 14px;
    background: var(--fondo-alt);
    color: var(--tinta);
    border: 1px solid var(--regla);
    border-radius: var(--radio-sm);
    font-family: var(--f-titulo);
    font-size: .78rem;
    font-weight: 600;
    letter-spacing: .1em;
    text-transform: uppercase;
    cursor: pointer;
}
.panel__menuBtn:hover,
.panel__menuBtn:focus-visible {
    background: var(--piv-verde-lavado);
    border-color: var(--piv-verde);
    color: var(--piv-verde-hondo);
}

/* Las tres barras: una caja y sus dos pseudoelementos. Un SVG habria sido lo
   mismo con mas bytes. */
.panel__menuBtnBarras {
    position: relative;
    display: block;
    width: 18px; height: 2px;
    background: currentColor;
    border-radius: 2px;
}
.panel__menuBtnBarras::before,
.panel__menuBtnBarras::after {
    content: "";
    position: absolute;
    left: 0;
    width: 18px; height: 2px;
    background: currentColor;
    border-radius: 2px;
}
.panel__menuBtnBarras::before { top: -6px; }
.panel__menuBtnBarras::after  { top: 6px; }

/* El velo y la X de cerrar solo existen en angosto. En escritorio ni se
   pintan: ahi no hay cajon que velar ni que cerrar. */
.panel__velo { display: none; }
.panel__cerrar { display: none; }

/* ------------------------------------------------------- 3. y el cajon --- */
@media (max-width: 900px) {

    .panel__menuBtn:not([hidden]) { display: inline-flex; }

    /* EL ENCABEZADO SE REACOMODA PARA NO PAGAR EL BOTON CON UN RENGLON.

       El boton mide 44 px de alto y, si se quedaba solo en su linea, se comia
       64 px de la primera pantalla -- justo lo que se vino a recuperar. En un
       telefono de 390 px caben el boton y el bloque del usuario en el mismo
       renglon (101 + 150 y sobra), y el nombre de la edicion baja al segundo,
       que es donde tiene sitio para leerse. */
    html.js .panel__menuBtn:not([hidden]) { order: 0; }
    html.js .panel__cabeza .panel__usuario { order: 1; margin-left: auto; }
    html.js .panel__cabeza .panel__edicion { order: 2; flex: 1 0 100%; }
    html.js .panel__cabeza { row-gap: 10px; }

    /* Y EL NOMBRE SE CORTA A DOS RENGLONES, igual que en escritorio y por la
       misma razon: el de esta edicion mide 150 caracteres y en 390 px se
       reparte en SIETE lineas, que son 130 px de encabezado para un dato que
       solo sirve de recordatorio. El nombre completo esta en la portada, en la
       pestania y en la pantalla de la edicion. */
    .panel__edicionNombre {
        display: -webkit-box;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
        overflow: hidden;
        line-height: 1.3;
    }

    /* EL LATERAL SALE DEL FLUJO. `visibility: hidden` -- y no solo el
       translate -- porque un cajon cerrado tampoco debe recibir el tabulador
       ni salir en el lector de pantalla. Se transiciona junto con el
       transform para que no desaparezca antes de terminar de salir. */
    html.js .panel__lateral {
        position: fixed;
        top: 0; bottom: 0; left: 0;
        z-index: 60;

        /* EL MISMO ANCHO EN LOS DOS APARATOS. Con un porcentaje suelto el
           cajon se comia el 75% del telefono y el 28% de la tablet: se veian
           como dos disenios distintos. Con el techo de 320 px, en la tablet es
           un cajon y en el telefono deja asomar una franja del contenido por
           la derecha -- que es justo la senial de "esto se cierra". */
        width: min(86vw, 320px);

        /* ALTO COMPLETO, Y EN dvh. Con `100vh` un telefono NO descuenta la
           barra del navegador y el cajon queda cortado por abajo. El `100%`
           que va antes es el respaldo para quien no conozca dvh.

           Y no basta con top:0 + bottom:0: el lateral es hijo de `.panel`, que
           es una rejilla, y arrastra el `align-self: start` que necesita en
           escritorio. Con el, Chrome dejaba el cajon del alto de su contenido
           -- 547 px medidos -- y por debajo reaparecia la pagina de atras: se
           veia como un error de pintado, no como una decision. */
        height: 100%;
        height: 100dvh;
        max-height: none;

        /* LA HOJA ENCIMA. La esquina redondeada del lado derecho y la sombra
           son lo que hace que se lea como algo puesto sobre la pantalla y no
           como un recorte de la pagina. */
        border-radius: 0 var(--radio) var(--radio) 0;

        overflow-y: auto;
        overscroll-behavior: contain;   /* al llegar al final del menu no se
                                           arrastra la tabla de atras */
        transform: translateX(-100%);
        visibility: hidden;

        /* LA VISIBILIDAD NO SE INTERPOLA, SE CONMUTA -- y el cuando importa.
           Al ABRIR tiene que pasar a visible en el instante cero, si no el
           cajon se desliza sin verse y aparece a medio camino; ademas
           lateral.focus() no agarra un elemento con visibility:hidden, y el
           foco se quedaba en el <body>. Al CERRAR se retrasa los mismos .2s
           que dura el deslizamiento, para que no se esfume antes de salir. */
        transition: transform .2s ease, visibility 0s linear .2s;
    }
    html.js .panel-body--menu .panel__lateral {
        transform: none;
        visibility: visible;
        box-shadow: 8px 0 32px rgba(var(--panel-hondo-rgb), .5);
        transition: transform .2s ease, visibility 0s;
    }

    /* EL VELO ES LO QUE MAS ARREGLA DE TODO ESTO. Sin el, el menu flota sobre
       la tabla a plena luz y el ojo no sabe si esta encima o incrustado; con
       el, el cajon es lo unico que se lee y lo de atras es "lo de atras". Y se
       cierra picandolo, que es lo primero que intenta cualquiera. */
    html.js .panel__velo {
        display: block;
        position: fixed;
        top: 0; right: 0; bottom: 0; left: 0;
        z-index: 55;
        background: rgba(var(--panel-hondo-rgb), .5);
        opacity: 0;
        visibility: hidden;
        transition: opacity .2s ease, visibility 0s linear .2s;
    }
    html.js .panel-body--menu .panel__velo {
        opacity: 1;
        visibility: visible;
        transition: opacity .2s ease, visibility 0s;
    }

    /* Con el cajon abierto, lo de atras no se desplaza: es la diferencia entre
       "hay un menu encima" y "la pagina se movio sola". */
    html.js .panel-body--menu { overflow: hidden; }

    /* LA CABECERA DEL CAJON: el logo y la X, con su linea debajo.

       El logo suelto arriba se veia como una imagen olvidada. Con la X a la
       derecha y la regla debajo, la franja se lee como la cabecera de un
       panel que se puede cerrar, que es lo que es. El aire se aprieta un poco
       respecto a escritorio: en 657 px de alto, cada pixel de arriba es un
       renglon menos de menu. */
    html.js .panel__lateral { gap: 0; padding: 0 0 16px; }
    html.js .panel__marca { min-height: 56px; padding: 12px 56px; }

    html.js .panel__cerrar:not([hidden]) {
        display: block;
        position: absolute;
        top: 6px; right: 8px;
        width: 44px; height: 44px;      /* el area de toque, no el dibujo */
        padding: 0;
        background: none;
        border: 0;
        border-radius: 50%;
        cursor: pointer;
    }
    html.js .panel__cerrar:hover { background: rgba(var(--panel-texto-rgb), .1); }

    /* La X, dos rayas cruzadas. Se dibujan con los pseudoelementos del propio
       boton para no meter un <span> que no dice nada. */
    html.js .panel__cerrar::before,
    html.js .panel__cerrar::after {
        content: "";
        position: absolute;
        top: 50%; left: 50%;
        width: 17px; height: 2px;
        margin: -1px 0 0 -8.5px;
        background: var(--panel-texto);
        border-radius: 2px;
    }
    html.js .panel__cerrar::before { transform: rotate(45deg); }
    html.js .panel__cerrar::after  { transform: rotate(-45deg); }

    /* Una sola columna dentro del cajon: la rejilla de dos que se usa sin
       JavaScript no cabe en 320 px. */
    html.js .panel__menu { display: block; padding: 4px 0 8px; }

    /* Los grupos, pegados uno a otro y separados por una linea. Con los 22 px
       de aire de escritorio entre cinco cabeceras cerradas, el cajon se veia
       vacio y aun asi no cabia todo. */
    html.js .panel__grupo + .panel__grupo { margin-top: 0; }
    html.js .panel__grupo + .panel__grupo > summary { border-top: 1px solid var(--panel-linea); }

    /* EL TITULO DE GRUPO ES EL CONTROL PRINCIPAL DE ESTA PANTALLA, y tiene que
       verse asi. En escritorio es un rotulo decorativo -- pequenio, apagado,
       muy espaciado -- porque ahi no se pica; aqui se pica, y con ese aspecto
       nadie lo intentaba.

       Cambia a color de texto vivo, pierde parte del espaciado de letra, gana
       sus 44 px de alto completos y la flecha se le pega AL LADO. Perdida en
       la orilla derecha, a 250 px del texto, la flecha no se leia como parte
       del mismo control. */
    html.js .panel__grupo > summary {
        display: flex;
        align-items: center;
        justify-content: flex-start;
        gap: 8px;
        min-height: 44px;
        padding: 9px 20px;
        cursor: pointer;
    }
    html.js .panel__grupo > summary h3 {
        margin: 0;
        padding: 0;
        font-size: .8rem;
        letter-spacing: .1em;
        color: var(--panel-texto);
    }
    html.js .panel__grupo[open] > summary h3 { color: var(--panel-realce); }
    html.js .panel__grupo > summary:hover { background: rgba(var(--panel-texto-rgb), .07); }

    /* La flecha. Apunta abajo cerrado y arriba abierto: es la unica senial que
       dice "esto se abre" antes de tocarlo. */
    html.js .panel__grupo > summary::after {
        content: "";
        flex: 0 0 auto;
        width: 7px; height: 7px;
        border-right: 2px solid var(--panel-apagado);
        border-bottom: 2px solid var(--panel-apagado);
        transform: translateY(-2px) rotate(45deg);
        transition: transform .15s ease;
    }
    html.js .panel__grupo[open] > summary::after {
        border-color: var(--panel-realce);
        transform: translateY(2px) rotate(-135deg);
    }

    /* Y EL AREA DE TOQUE DE CADA HIJO, tambien 44 -- con los 8 px de relleno
       de escritorio median 41, y tres pixeles de menos se notan con el pulgar
       en el camion. Son 10 y no 12 porque 12 daban 49: cuatro renglones de
       menu se comian una opcion entera de las que caben en pantalla. */
    html.js .panel__menu a,
    html.js .panel__menu .pendiente { padding: 10px 20px; }
    html.js .panel__grupo > ul { padding-bottom: 4px; }

    html.js .panel__lateralPie { margin-top: 8px; padding-top: 12px; }
}

/* A quien tiene el movimiento apagado, el cajon le aparece y desaparece.

   LOS SELECTORES SE REPITEN CON LA CLASE DEL CAJON ABIERTO A PROPOSITO, y no
   por copiar de mas: `html.js .panel-body--menu .panel__lateral` pesa mas que
   un `.panel__lateral` suelto, asi que un `transition: none` escrito corto lo
   habria apagado al cerrar pero NO al abrir -- que es justo el movimiento que
   marea. Igualando el selector, el ultimo que se lee es este. */
@media (prefers-reduced-motion: reduce) {
    html.js .panel__lateral,
    html.js .panel-body--menu .panel__lateral,
    html.js .panel__velo,
    html.js .panel-body--menu .panel__velo,
    .panel__grupo > summary::after { transition: none; }
}


/* ================================ los avisos que flotan  (2026-08-24) ==

   Ver la nota larga de js/sitio.js sobre por que no se trajo toastr y por que
   solo flotan los avisos de accion.

   ARRIBA A LA DERECHA Y NO ABAJO. Abajo compite con la barra del navegador en
   movil y con la del sistema en escritorio; arriba a la derecha es donde la
   gente ya aprendio a buscar una confirmacion, y no tapa el boton que se acaba
   de picar -- que suele estar abajo a la izquierda de una tarjeta.
   -------------------------------------------------------------------------- */

.avisos {
    position: fixed;
    top: 16px;
    right: 16px;
    z-index: 90;            /* encima del contenido, DEBAJO de .capa (50) no:
                               una capa modal tapa la pagina entera, y un aviso
                               que quedara detras no se leeria. Va encima. */
    display: flex;
    flex-direction: column;
    gap: 10px;
    width: min(92vw, 380px);

    /* La pila no intercepta el raton: solo sus hijos. Sin esto, la columna
       invisible de arriba a la derecha se comeria los clics de lo que hay
       debajo aunque no haya ningun aviso puesto. */
    pointer-events: none;
}

.avisos__uno {
    pointer-events: auto;
    display: flex;
    align-items: flex-start;
    gap: 10px;

    padding: 12px 12px 12px 14px;
    border-radius: var(--radio-sm);
    border-left: 4px solid currentColor;
    background: #fff;
    box-shadow: 0 10px 30px -8px rgba(20, 24, 15, .28);

    font-size: .93rem;
    line-height: 1.45;

    animation: avisoEntra .18s ease-out;
    transition: opacity .18s ease, transform .18s ease;
}

/* El borde y el icono toman `currentColor`, asi que basta con dar el color del
   texto: el resto se tinta solo. Un color, no cuatro reglas. */
.avisos__uno--ok     { color: var(--ok); }
.avisos__uno--error  { color: var(--error); }
.avisos__uno--alerta { color: #8A5A00; }
.avisos__uno--info   { color: var(--piv-verde-hondo); }

/* El TEXTO se lee en tinta normal: el color del tipo esta en el filo, y un
   parrafo entero en rojo cansa y baja el contraste. */
.avisos__texto {
    margin: 0;
    flex: 1 1 auto;
    color: var(--tinta);
}

.avisos__cerrar {
    flex: 0 0 auto;
    width: 26px; height: 26px;
    display: flex; align-items: center; justify-content: center;
    border: 0; border-radius: 50%;
    background: transparent;
    color: var(--tenue);
    font-size: 1.2rem; line-height: 1;
    cursor: pointer;
}
.avisos__cerrar:hover { background: var(--regla-tenue); color: var(--tinta); }
.avisos__cerrar:focus-visible {
    outline: 2px solid var(--piv-verde);
    outline-offset: 1px;
}

.avisos__uno--sale {
    opacity: 0;
    transform: translateX(12px);
}

@keyframes avisoEntra {
    from { opacity: 0; transform: translateX(16px); }
    to   { opacity: 1; transform: translateX(0); }
}

/* En un telefono va de lado a lado: 380 px en una pantalla de 390 deja dos
   margenes de cinco pixeles que se ven como un error de alineacion. */
@media (max-width: 480px) {
    .avisos { left: 12px; right: 12px; top: 12px; width: auto; }
}

/* Quien pidio menos movimiento no lo recibe. El aviso sigue apareciendo y
   desapareciendo, sin deslizarse. */
@media (prefers-reduced-motion: reduce) {
    .avisos__uno { animation: none; transition: opacity .18s ease; }
    .avisos__uno--sale { transform: none; }
}

/* ------------------ la vista previa de un texto del sitio  (2026-08-24) --

   Lo que se ensenia aqui lo genera `TextoWeb.Parrafos`, el MISMO codigo que
   usa el sitio publico. Por eso hereda su tipografia y su ancho de lectura en
   vez de la del panel: una vista previa que se ve distinta a la pagina real no
   sirve para decidir si el texto quedo bien.

   El ancho maximo es el de un parrafo comodo de leer. Sin el, en un monitor
   ancho el texto sale en renglones de doscientos caracteres y no se parece en
   nada a como lo va a ver el visitante.
   -------------------------------------------------------------------------- */
.previa__texto {
    font-family: var(--f-texto);
    font-size: 1rem;
    line-height: 1.65;
    color: var(--tinta);
    max-width: 68ch;
}
.previa__texto p { margin: 0 0 1em; }
.previa__texto p:last-child { margin-bottom: 0; }
.previa__texto:empty::before {
    content: "Escribe algo arriba para verlo aqui.";
    color: var(--tenue);
    font-style: italic;
}
