/* ds-allow-hardcode:start — los hexadecimales de esta cabecera son la DOCUMENTACIÓN
   de los pares de contraste medidos, no valores aplicados. */
/* ============================================================================
   gpa_portal_2026.css — Portal público de empleo de González Páez Abogados.
   Lo comparten `postular.php` y `vacante.php`.

   ── QUÉ PALETA ES ESTA, Y POR QUÉ ───────────────────────────────────────────
   Identidad Corporativa 2026 (#171D35 / #B18F4D / #926836, Montserrat única), NO
   `gpa_marca()` (#1B2337 / #EBC480), que es la del producto.

   `GUIA_REDISENO_GPA_2026.md` §0 clasifica en dos: vista del sistema ⇒ gpa_marca();
   pieza institucional ⇒ identidad 2026. Una página PÚBLICA no está en ninguna de las
   dos listas, y se resuelve como pieza institucional: no la ve ningún usuario de LHM,
   la ve un candidato, y cumple la misma función que un portafolio. La regla que deja
   escrita es «público ⇒ 2026, interno ⇒ gpa_marca()». Las 7 vistas internas del módulo
   NO migran: eso obliga a repetir su auditoría de accesibilidad y es un alcance propio.

   No hay un tercer conjunto de valores: todo sale del manual.

   ── CONTRASTES MEDIDOS ANTES DE ESCRIBIR ────────────────────────────────────
   #B18F4D sobre #FAF7F2 .... 2,85:1  → PROHIBIDO para texto. Solo filete, fondo, borde
   #926836 sobre #FAF7F2 .... 4,62:1  → el dorado sobre claro va en BRONCE
   #7A6231 sobre #FAF7F2 .... 5,43:1  → cuando hace falta margen
   #C4A25C sobre #171D35 .... 6,9:1   → sobre oscuro el acento es este, no #B18F4D
   #737A8C sobre #FAF7F2 .... 4,02:1  → el --muted del propio manual INCUMPLE su 4,5:1
   #656C7E sobre #FAF7F2 .... 4,53:1  → el sustituto. Mismo criterio que legacy/manual/
   ============================================================================ */
/* ds-allow-hardcode:end */

:root {
    /* ---- Los cuatro corporativos ---- */
    --azul: #171D35;
    --dorado: #B18F4D;
    --bronce: #926836;
    --negro: #111823;

    /* ---- Sistema de apoyo del manual ---- */
    --dorado-luz: #C4A25C;      /* acento SOBRE FONDO OSCURO */
    --dorado-pale: #E3B67F;
    --oro-800: #7A6231;         /* dorado con margen sobre claro */
    --azul-mid: #1B2337;
    --azul-soft: #2E3A5C;
    --azul-pale: #C6CBD8;
    --crema: #FAF7F2;
    --crema-warm: #FDFBF8;
    --crema-deep: #EEE9DF;
    --linea: #E4DFD5;
    --texto: #2A2F3D;
    /* El manual declara --muted:#737A8C y exige 4,5:1; ese par da 4,02:1 sobre crema.
       Se oscurece, igual que hizo legacy/manual/index.html. No es un color nuevo:
       es el mismo neutro corregido para cumplir lo que el propio manual pide. */
    --muted: #656C7E;
    --ok: #4F7A4D;
    --alerta: #B08A2E;
    --riesgo: #8E2A2A;
    --blanco: #FFFFFF;

    /* ---- Degradados: SIEMPRE 135°, coherentes con el chaflán del símbolo ---- */
    --grad-azul: linear-gradient(135deg, #111823 0%, #171D35 45%, #1B2337 100%);

    /* ---- Escala de espaciado con nombre ---- */
    --esp-1: 4px;  --esp-2: 8px;  --esp-3: 14px;
    --esp-4: 22px; --esp-5: 34px; --esp-6: 54px;

    /* ---- Escala tipográfica. El manual la define en puntos para papel; aquí en px,
       porque `rem` NO vale 16 px en este shell y una escala en rem sale aplanada. ---- */
    --tx-eyebrow: 12px;   /* versalitas, 700, +26% de interletrado */
    --tx-etq: 12.5px;     /* etiqueta de campo */
    --tx-mini: 13.5px;    /* pie, cobertura, dato de ficha */
    --tx-sm: 14px;
    --tx-md: 15px;        /* botón, subtítulo de sección */
    --tx-base: 16px;      /* cuerpo */
    --tx-lg: 17px;        /* bajada del hero */

    /* ---- Anchuras ---- */
    --anc-portal: 1080px;   /* rejilla de fichas */
    --anc-lectura: 780px;   /* columna del formulario */
    --alto-marca: 44px;     /* logotipo del hero */
    --alto-marca-pie: 30px;
    --ctrl: 18px;           /* lado de la casilla de verificación */
    --politica-alto: 190px;
    /* En `autorizar.php` el texto NO es un anexo del formulario: es lo único que hay que
       leer antes de decidir. Con 190 px se corta a media línea y parece que falta algo. */
    --politica-alto-extenso: 420px;

    --radio: 12px;
    --radio-sm: 8px;
    --sombra: 0 1px 3px rgba(23,29,53,.07), 0 10px 30px rgba(23,29,53,.06);
    --sombra-alta: 0 2px 6px rgba(23,29,53,.10), 0 18px 40px rgba(23,29,53,.12);

    /* ---- gpa_form.css declara SUS PROPIOS --gpa-* con la paleta ANTERIOR
       (#1B2337 / #EBC480 — ds-allow-hardcode: los documenta, no los aplica). Como esta
       página lo carga para el contador de caracteres,
       esos tokens quedan en ámbito y los `:focus` del componente pintarían el navy
       viejo. Se REDEFINEN aquí: se ajusta el componente compartido a la página, no se
       bifurca el componente. Cargar esta hoja DESPUÉS de gpa_form.css. ---- */
    --gpa-navy: #171D35;
    --gpa-navy-2: #1B2337;
    --gpa-gold: #B18F4D;
    --gpa-gold-soft: rgba(177,143,77,.12);
    --gpa-line: #E4DFD5;
    --gpa-muted: #656C7E;
    --gpa-bg: #FAF7F2;
    /* Y los semánticos, que además arreglan un fallo real: el `--gpa-danger` de
       gpa_form.css es #C24E3A (ds-allow-hardcode: ratio medido, es documentación), que
       sobre blanco da 3,96:1 — o sea que el mensaje
       «el correo no parece válido» NO CUMPLE AA. `axe` no lo atrapa porque
       `.invalid-feedback` está oculto hasta que el campo falla, así que el gate nunca
       llega a medirlo. El #8E2A2A del manual da 8,35:1 (ds-allow-hardcode: documentación).
       Es deuda del componente COMPARTIDO, no de esta página: aquí se corrige para el
       portal y queda anotado en el informe para el resto del sistema. */
    --gpa-danger: #8E2A2A;
    --gpa-success: #4F7A4D;   /* #2E7D5B daba 2,48:1 */
    --gpa-warn: #B08A2E;
    --gpa-info: #1B2337;
}

* { box-sizing: border-box; }

body {
    margin: 0;
    background: var(--crema);
    color: var(--texto);
    /* Montserrat única. Sustituta de sistema Arial/Helvetica, NUNCA una serif. */
    font-family: 'Montserrat', 'Helvetica Neue', Arial, sans-serif;  /* ds-allow-hardcode: ESTA es la declaración de la familia; no puede salir de un token porque es el token */
    font-size: var(--tx-base);
    line-height: 1.65;                 /* interlínea del manual para cuerpo */
    -webkit-font-smoothing: antialiased;
}

/* ---------- Contenedores. El ancho ganado se REPARTE, no se estira: una línea de
   texto por encima de ~75 caracteres deja de leerse. ---------- */
/* ds-allow-hardcode: los px del clamp() son la banda de margen lateral; expresarlos
   en tokens de la escala de espaciado ataría el margen del contenedor al ritmo
   vertical, que son cosas distintas. */
.env { max-width: var(--anc-portal); margin: 0 auto; padding: 0 clamp(18px, 4vw, 48px); }
.env--angosto { max-width: var(--anc-lectura); }

/* ============================================================
   Hero
   ============================================================ */
.hero { background: var(--grad-azul); color: var(--blanco); padding: var(--esp-6) 0 var(--esp-5); }
.hero__marca { display: block; height: var(--alto-marca); width: auto; margin-bottom: var(--esp-4); }

/* Versalitas del manual: 700, +26 % de interletrado. Sobre azul el acento es
   --dorado-luz, no --dorado. */
/* `inline-block` para que la caja se CIÑA al texto. Es una etiqueta de dos palabras;
   con la caja al ancho del contenedor cualquier medidor de ancho de línea la cuenta
   como un párrafo de 164 columnas, y esconde los párrafos que sí lo son. */
.hero__eyebrow {
    display: inline-block;
    margin: 0 0 var(--esp-2);
    color: var(--dorado-luz);
    font-size: var(--tx-eyebrow);
    font-weight: 700;
    letter-spacing: .26em;
    text-transform: uppercase;
}

/* ds-allow-hardcode: los px del clamp() no pueden ser tokens porque `rem` NO vale
   16 px en este shell — `1.9rem` renderiza a 25 px y aplana la jerarquía. Misma
   justificación y mismo patrón que TalentoHumano/css/gth.css. */
.hero h1 {
    margin: 0 0 var(--esp-3);
    font-size: clamp(30px, 3.4vw, 46px);  /* ds-allow-hardcode: `rem` NO vale 16px en este shell — 1.9rem renderiza a 25px y aplana la jerarquía */
    font-weight: 800;
    line-height: 1.15;
    letter-spacing: -.02em;            /* −2 % del manual para titular */
}
.hero h1 .oro { color: var(--dorado-luz); }
.hero__bajada { margin: 0; max-width: 62ch; color: var(--azul-pale); font-size: var(--tx-lg); }

.hero__acciones { margin-top: var(--esp-4); display: flex; flex-wrap: wrap; gap: var(--esp-3); }

/* ============================================================
   Botones
   ============================================================ */
.btn {
    display: inline-block; border-radius: var(--radio-sm); padding: var(--esp-3) 26px;
    font-family: inherit; font-size: var(--tx-md); font-weight: 700; line-height: 1.3;
    text-decoration: none; cursor: pointer; border: 1px solid transparent;
    transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}
/* Dorado de FONDO con texto azul: el par #171D35 sobre #B18F4D da 8,0:1. Es el uso
   autorizado del dorado — como superficie, no como tinta de texto sobre claro. */
.btn--oro { background: var(--dorado); color: var(--azul); border-color: var(--bronce); }
.btn--oro:hover { background: var(--dorado-pale); border-color: var(--bronce); color: var(--azul); }
/* Fondo SÓLIDO, no transparente. Sobre el degradado del hero un botón fantasma tiene
   poca llamada, y además ningún medidor automático puede componer su contraste: el
   gate lo lee sobre el fondo del `body` y reporta un fallo que no existe. Sólido, el
   par es inequívoco — #FFFFFF sobre #1B2337 = 12,87:1 (ds-allow-hardcode: medido). */
.btn--fantasma { background: var(--azul-mid); color: var(--blanco); border-color: var(--dorado-luz); }
.btn--fantasma:hover { background: var(--azul-soft); color: var(--blanco); border-color: var(--dorado-luz); }
.btn--claro { background: var(--blanco); color: var(--azul); border-color: var(--linea); }
.btn--claro:hover { background: var(--crema-deep); color: var(--azul); }
.btn:focus-visible { outline: 3px solid var(--dorado-luz); outline-offset: 2px; }
.hero .btn:focus-visible { outline-color: var(--blanco); }

/* ============================================================
   Secciones y cabeceras
   ============================================================ */
.seccion { padding: var(--esp-6) 0 0; }
.seccion__cab { margin-bottom: var(--esp-4); }
.seccion h2 {
    margin: 0 0 var(--esp-2);
    font-size: clamp(21px, 2.1vw, 28px);   /* ds-allow-hardcode: ver .hero h1 */
    font-weight: 600; line-height: 1.25; color: var(--azul);
}
.seccion__sub { margin: 0; color: var(--muted); font-size: var(--tx-md); max-width: 68ch; }

/* ---------- Ancho de línea ----------
   El contenedor puede ser ancho; la LÍNEA DE TEXTO no. Por encima de ~75 caracteres el
   ojo pierde el renglón al volver. El ancho ganado se reparte entre columnas, no se
   gasta en estirar el párrafo. */
.hero__bajada, .seccion__sub, .cobertura, .prosa, .aviso, .pie p, .politica,
.tarjeta > p, .vac--vacio { max-width: 60ch; }
.ayuda { max-width: 52ch; }
/* 60ch y no 68: la unidad `ch` es el ancho del glifo «0», y en Montserrat ese glifo es
   sensiblemente más ancho que medio em. Un `max-width:68ch` renderiza como ~91 columnas
   de las que cuenta el gate. Se calibró midiendo, no estimando. */

/* La cobertura de un bloque se DICE. Sin ella, quien mira concluye que lo que ve es
   el universo completo — el mismo defecto que tenían los paneles del dashboard. */
.cobertura {
    margin: var(--esp-3) 0 0; padding: 10px 14px;
    background: var(--crema-warm); border: 1px solid var(--linea);
    border-left: 3px solid var(--dorado);
    border-radius: var(--radio-sm); color: var(--muted); font-size: var(--tx-mini);
}

/* ============================================================
   Fichas de vacante
   ============================================================ */
/* ds-allow-hardcode: 280px es el ancho mínimo con el que el título de una vacante no
   parte a media palabra. Es una medida del contenido. */
.vacantes { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: var(--esp-4); }
/* En el LISTADO las fichas se estiran a la misma altura a propósito: son tarjetas
   comparables. En la página de UNA vacante no hay nada que comparar —son dos bloques del
   mismo puesto— y estirarlos deja media tarjeta en blanco cuando uno crece, que es lo que
   pasó al publicar las funciones. */
.vacantes--ficha { align-items: start; }

.vac {
    display: flex; flex-direction: column;
    background: var(--blanco); border: 1px solid var(--linea);
    border-top: 3px solid var(--dorado);          /* el 10 % de dorado, como filete */
    border-radius: var(--radio); padding: var(--esp-4);
    box-shadow: var(--sombra); text-decoration: none; color: inherit;
    transition: box-shadow .16s ease, border-color .16s ease, transform .16s ease;
}
.vac:hover { box-shadow: var(--sombra-alta); border-color: var(--azul-pale); border-top-color: var(--bronce); transform: translateY(-2px); }
.vac:focus-visible { outline: 3px solid var(--bronce); outline-offset: 3px; }

.vac__codigo { color: var(--muted); font-size: var(--tx-eyebrow); font-weight: 700; letter-spacing: .16em; text-transform: uppercase; }
.vac h3 { margin: var(--esp-2) 0 var(--esp-3); font-size: var(--tx-lg); font-weight: 600; line-height: 1.3; color: var(--azul); }
.vac__resumen { margin: 0 0 var(--esp-4); color: var(--texto); font-size: var(--tx-sm);
    display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
/* Las funciones del puesto, en la ficha de una vacante. Van con viñeta propia y no con
   `list-style` del navegador: el punto del sistema se pinta fuera de la caja y se come la
   sangría de la tarjeta. `.vac__datos` de aquí abajo es OTRA cosa —pares dato/valor—, y
   compartir estilos entre las dos acabaría alineando las funciones en dos columnas. */
.vac__subtitulo { margin: var(--esp-4) 0 var(--esp-2); color: var(--texto);
                  font-size: var(--tx-eyebrow); font-weight: 700; letter-spacing: .1em;
                  text-transform: uppercase; }
.vac__funciones { margin: 0 0 var(--esp-4); padding: 0; list-style: none; font-size: var(--tx-sm); }
.vac__funciones li { position: relative; padding: 0 0 var(--esp-2) 16px; color: var(--texto); line-height: 1.55; }
.vac__funciones li::before { content: '·'; position: absolute; left: 2px; top: -2px;
                             color: var(--bronce, #926836); font-weight: 700; font-size: 1.4em; }

.vac__datos { margin: 0 0 var(--esp-4); padding: 0; list-style: none; font-size: var(--tx-mini); }
.vac__datos li { display: flex; gap: var(--esp-2); padding: 5px 0; border-top: 1px solid var(--crema-deep); }
.vac__datos li:first-child { border-top: 0; }
.vac__datos dfn { flex: 0 0 44%; color: var(--muted); font-style: normal; }
.vac__datos span { color: var(--texto); font-weight: 600; }
/* Un hueco se DECLARA. «Sin exigencia» y «No consta» no son lo mismo y ninguno es un
   guion suelto: se escriben con palabras y en el tono neutro del texto secundario. */
.vac__datos .hueco { color: var(--muted); font-weight: 400; font-style: italic; }
.vac__pie { margin-top: auto; padding-top: var(--esp-3); border-top: 1px solid var(--crema-deep);
    color: var(--bronce); font-size: var(--tx-sm); font-weight: 700; }

.vac--vacio { text-align: center; padding: var(--esp-6) var(--esp-4); background: var(--crema-warm);
    border: 1px dashed var(--linea); border-radius: var(--radio); color: var(--muted); }

/* ============================================================
   Tarjetas y avisos
   ============================================================ */
.tarjeta { background: var(--blanco); border: 1px solid var(--linea); border-radius: var(--radio);
    /* ds-allow-hardcode: el relleno de la tarjeta crece con el viewport; un token fijo
       de la escala daría una tarjeta apretada en móvil o desproporcionada en pantalla
       grande. */
    padding: clamp(20px, 3vw, 32px); box-shadow: var(--sombra); }

.aviso { border-radius: var(--radio-sm); padding: var(--esp-3) var(--esp-4); margin-bottom: var(--esp-4); font-size: var(--tx-md); }
.aviso.mal  { background: #FBF0EE; border-left: 4px solid var(--riesgo); }
.aviso.bien { background: #EEF5EF; border-left: 4px solid var(--ok); }
.aviso ul { margin: var(--esp-2) 0 0; padding-left: 20px; }

/* ============================================================
   Formulario
   ============================================================ */
.fila { display: grid; grid-template-columns: 1fr; gap: var(--esp-4); }
/* ds-allow-hardcode: 660px es el punto donde dos campos de formulario dejan de caber
   con holgura; es una medida del contenido, no un valor de la escala. */
@media (min-width: 660px) { .fila.dos { grid-template-columns: 1fr 1fr; } }

.grupo { margin-bottom: var(--esp-4); }
.gpa-form label {
    display: block; margin-bottom: var(--esp-1);
    font-size: var(--tx-etq); font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
    color: var(--muted);
}
.req { color: var(--riesgo); }

.gpa-form input[type=text], .gpa-form input[type=email], .gpa-form input[type=url],
.gpa-form input[type=file], .gpa-form select {
    width: 100%; padding: var(--esp-2) var(--esp-3); border: 1px solid var(--linea);
    border-radius: var(--radio-sm); font-size: var(--tx-base); font-family: inherit;
    background: var(--blanco); color: var(--texto);
}
.gpa-form input:focus, .gpa-form select:focus {
    outline: 3px solid var(--bronce); outline-offset: 1px; border-color: var(--azul-mid);
}
.ayuda { margin-top: var(--esp-1); color: var(--muted); font-size: var(--tx-mini); }

.politica { background: var(--crema); border: 1px solid var(--linea); border-radius: var(--radio-sm);
    padding: var(--esp-3) var(--esp-4); font-size: var(--tx-sm); max-height: var(--politica-alto); overflow-y: auto;
    margin-bottom: var(--esp-3); }
/* La caja alta lleva un velo al pie mientras quede texto por leer: sin él, un párrafo
   cortado en seco no se distingue de uno que ya terminó, y nadie baja a buscar el resto.
   Se hace con dos capas de fondo y `background-attachment: local, scroll`: la primera
   viaja con el contenido y la segunda se queda pegada al borde, así que el velo
   DESAPARECE SOLO al llegar al final. Un degradado fijo mentiría al final del texto. */
.politica--extensa {
    max-height: var(--politica-alto-extenso);
    background-image:
        linear-gradient(to top, var(--crema), var(--crema) 70%, rgba(250, 247, 242, 0)),
        linear-gradient(to top, rgba(23, 29, 53, .10), rgba(23, 29, 53, 0));
    background-position: bottom center;
    background-repeat: no-repeat;
    background-size: 100% 26px, 100% 26px;
    background-attachment: local, scroll;
}
@media (prefers-reduced-motion: reduce) { .politica--extensa { background-image: none; } }
.acepta { display: flex; gap: var(--esp-2); align-items: flex-start; }
.acepta input { margin-top: var(--esp-1); width: var(--ctrl); height: var(--ctrl); flex: 0 0 auto; }
.acepta label { text-transform: none; letter-spacing: 0; font-weight: 400; font-size: var(--tx-md);
    color: var(--texto); margin: 0; }
a { color: var(--bronce); }
a:hover { color: var(--oro-800); }

/* El cebo antirrobot se esconde con visually-hidden, NO con `left:-9999px`: ese
   desplazamiento no se invierte en RTL y estira el documento 9999 px hacia el otro
   lado (lo midió verify_rtl). Este recorta a un píxel sin mover nada. NO TOCAR. */
.cebo { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden;
    clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }

/* ============================================================
   Pie
   ============================================================ */
.pie { margin-top: var(--esp-6); background: var(--azul); color: var(--azul-pale); padding: var(--esp-5) 0; }
.pie__marca { height: var(--alto-marca-pie); width: auto; margin-bottom: var(--esp-3); }
.pie p { margin: 0 0 var(--esp-1); font-size: var(--tx-mini); }
.pie a { color: var(--dorado-luz); }
.pie a:hover { color: var(--blanco); }

/* ============================================================
   Migas
   ============================================================ */
.migas { padding-top: var(--esp-4); font-size: var(--tx-mini); color: var(--muted); }
.migas a { color: var(--bronce); text-decoration: none; }
.migas a:hover { text-decoration: underline; color: var(--oro-800); }

/* El pulso del contador en rojo lo define gpa_form.css sin envolverlo en media query.
   Quien pide menos movimiento no debería recibir una animación infinita. */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after { animation-duration: .001ms !important; animation-iteration-count: 1 !important;
        transition-duration: .001ms !important; }
    .vac:hover { transform: none; }
}

/* ============================================================
   Ficha de detalle (vacante.php): mismo lenguaje visual que la ficha del portal,
   pero no es un enlace — no debe levantarse al pasar el ratón ni sugerir que se
   puede pulsar.
   ============================================================ */
.vac--estatico { cursor: default; }
.vac--estatico:hover { box-shadow: var(--sombra); border-color: var(--linea);
    border-top-color: var(--dorado); transform: none; }

/* Prosa dentro de una ficha: sin recorte de líneas. El recorte lo hace el CSS y aquí
   no se quiere; nunca se corta la cadena en PHP. */
.prosa { display: block; overflow: visible; -webkit-line-clamp: initial; margin: 0 0 var(--esp-3); }
.prosa:last-child { margin-bottom: 0; }

.cta h2 { margin-top: 0; }
.cta p:last-child { margin-bottom: 0; }

/* ── Pieza gráfica de la convocatoria (2026-09-13) ───────────────────────────
 * El cartel que la persona ya vio por WhatsApp. Se muestra a tamaño contenido y centrado:
 * es 900×1600 (9:16) y a pantalla completa empujaría el formulario fuera de la primera
 * pantalla, que es justo lo que no puede pasar en una página cuyo trabajo es que alguien
 * envíe un archivo.
 *
 * `width`/`height` van en el HTML para que el navegador reserve el hueco antes de cargarla:
 * sin ellos, la imagen entra de golpe y desplaza el formulario bajo el cursor.
 */
.portal-pieza {
  margin: 0 auto var(--esp-4, 24px);
  max-width: 320px;
  text-align: center;
}
.portal-pieza img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--radio, 12px);
  box-shadow: 0 10px 34px rgba(27, 35, 55, .18);
}
@media (max-width: 640px) {
  .portal-pieza { max-width: 240px; }
}
