/* ui.css — utilidades y componentes transversales que el CSS heredado del
 * prototipo no traía: accesibilidad, variantes de botón, navegación móvil y
 * la región de avisos. Se carga en todas las rutas, después de components.css.
 */

/* ── Accesibilidad ───────────────────────────────────────────────────────── */

.screen-reader-text {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

.skip-link:focus {
    position: fixed;
    top: 12px; left: 12px;
    z-index: 10000;
    width: auto; height: auto;
    padding: 12px 20px;
    clip: auto; clip-path: none;
    background: var(--color-primary);
    color: #fff;
    border-radius: 8px;
    font-weight: 700;
}

/* Foco visible y consistente en todo lo interactivo. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
    outline: 3px solid var(--color-accent);
    outline-offset: 2px;
    border-radius: 4px;
}

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

/* ══════════════════════════════════════════════════════════════════════════
 * BOTONES — pedido del 2026-09-16: «los botones deben verse como botones,
 * tomá catalogo.html para ello» y «los textos en su mayoría parecen flotar».
 *
 * Había dos sistemas de botones conviviendo:
 *
 * 1. `.ds-btn` — el del prototipo, portado entero desde el catálogo de diseño
 *    (cipdh/_assets/prototipos/catalogo.html). Completo: base, siete variantes,
 *    cuatro tamaños, estados hover/active/focus/disabled.
 * 2. `.btn` — el que usan las 41 plantillas del tema, 71 veces sin variante.
 *
 * Y `.btn` no tenía NI `display` NI `background` declarados en ninguna hoja:
 * sus únicas definiciones eran dos bloques sueltos heredados de prototipos
 * viejos (components.css, «FROM: admin-publicaciones.html») que solo ponían
 * padding y tipografía. Un <a class="btn"> se renderizaba como texto en línea
 * con espacio alrededor — de ahí la sensación de que los textos flotaban.
 *
 * En vez de escribir un tercer sistema, `.btn` pasa a ser un ALIAS de `.ds-btn`.
 * El diseño es el del prototipo, que es el que vale; las plantillas no cambian
 * una sola clase; y queda un único lugar donde se decide cómo se ve un botón.
 * ═══════════════════════════════════════════════════════════════════════════ */

/*
 * Solo `.btn`, sin `button.btn` ni `a.btn` — corregido el 2026-09-16.
 *
 * Calificar la base con el tag la subía a especificidad (0,1,1), por encima de
 * TODAS las variantes, que son (0,1,0). Resultado: en un
 * <button class="btn btn-gold"> ganaba `background: transparent` de la base y
 * el botón de «Ingresar» se veía como texto suelto — el mismo síntoma que
 * P-22, ahora por especificidad y no por falta de declaración.
 *
 * El tag no hace falta: los estilos por defecto del navegador para <button> y
 * la regla `a { color }` del tema son (0,0,1) y (0,0,1), así que `.btn` sola
 * ya les gana. No vuelvas a agregar el tag para «asegurarte».
 */
.btn {
    display: inline-flex;
    gap: 8px;
    align-items: center;
    justify-content: center;
    padding: 11px 22px;
    border: 2px solid transparent;
    border-radius: var(--radius-sm, 8px);
    background: transparent;
    font-family: var(--font-main);
    font-size: var(--fs-sm, .9375rem);
    font-weight: 700;
    line-height: 1;
    text-align: center;
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
    transition: background .25s, color .25s, border-color .25s, transform .15s, box-shadow .25s;
}

/* Un .btn sin variante es la acción secundaria —«Volver», «Cancelar», «Ver»—.
   Contorno, no relleno: si todos los botones pesaran igual, ninguno guiaría. */
.btn {
    border-color: var(--color-border);
    color: var(--color-text);
}

.btn:hover {
    border-color: var(--color-primary);
    color: var(--color-primary);
    background: var(--color-bg-alt);
}

.btn:active { transform: translateY(1px); }
.btn:focus-visible { outline: 3px solid rgba(231, 186, 97, .5); outline-offset: 2px; }

.btn:disabled,
.btn.is-disabled {
    opacity: .5;
    cursor: not-allowed;
    transform: none;
}

/* La acción principal de la pantalla. */
.btn-primary {
    background: var(--color-primary);
    border-color: var(--color-primary);
    color: #fff;
}

.btn-primary:hover {
    background: var(--color-accent);
    border-color: var(--color-accent);
    color: #fff;
    transform: translateY(-2px);
    box-shadow: var(--shadow-md);
}

/* Dorado: la acción decisiva, una por pantalla. Ver el criterio del dorado en
   PEDIDOS.md → P-19. */
.btn-gold {
    background: var(--color-gold);
    border-color: var(--color-gold);
    color: var(--color-primary);
}

.btn-gold:hover,
.btn-gold:focus-visible {
    background: var(--color-gold-dark);
    border-color: var(--color-gold-dark);
    transform: translateY(-2px);
    box-shadow: var(--shadow-md);
}

.btn-danger {
    background: var(--error);
    border-color: var(--error);
    color: #fff;
}

.btn-danger:hover { background: #9c2c20; border-color: #9c2c20; transform: translateY(-2px); }

.btn-sm { padding: 7px 14px; font-size: var(--fs-xs, .8125rem); }
.btn-lg { padding: 15px 30px; font-size: var(--fs-base, 1rem); }
.btn-block { display: flex; width: 100%; }

/* Un botón que es solo un icono tiene que ser cuadrado, no un rectángulo con
   un icono perdido en el medio. */
.btn-icon { width: 42px; height: 42px; padding: 11px; }
.btn-icon.btn-sm { width: 34px; height: 34px; padding: 8px; }

/* Grupos de acciones en una celda de tabla o al pie de un formulario. */
.esc-acciones-celda,
.esc-form__acciones {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    align-items: center;
}

/* ── Tarjeta de acceso, usada por los tres hubs de rol ───────────────────── */

.esc-cat-item {
    display: block;
    padding: 24px;
    background: var(--color-bg);
    border: var(--card-bd);
    border-radius: var(--card-radius);
    box-shadow: var(--card-shadow);
    transition: var(--card-transition);
}

.esc-cat-item:hover,
.esc-cat-item:focus-visible {
    transform: var(--card-lift);
    box-shadow: var(--card-shadow-hover);
    border-color: var(--color-accent);
}

.esc-cat-item h3 { margin: 0 0 8px; font-size: 1.125rem; }
.esc-cat-item p  { margin: 0; font-size: .9rem; color: var(--color-text-muted); }

.esc-lead { font-size: 1.125rem; line-height: 1.6; color: var(--color-text-muted); }

/* ── Navegación móvil (la construye app.js) ──────────────────────────────── */

.nav-toggle {
    display: none;
    align-items: center;
    justify-content: center;
    width: 44px; height: 44px;
    font-size: 22px;
    color: inherit;
    background: none;
    border: 0;
    cursor: pointer;
}

.nav-overlay {
    position: fixed;
    inset: 0;
    z-index: 998;
    background: rgba(35, 45, 79, .55);
}

@media (max-width: 980px) {
    .nav-toggle { display: inline-flex; }

    .main-navigation {
        position: fixed;
        top: 0; right: 0; bottom: 0;
        z-index: 999;
        width: min(320px, 84vw);
        padding: 88px 24px 24px;
        background: var(--color-primary);
        transform: translateX(100%);
        /* visibility, además del transform (2026-10-07, P-114): cerrado, el
           panel no se alcanza con Tab ni lo lee un lector de pantalla. Se
           oculta recién cuando termina de salir, para que se vea deslizar. */
        visibility: hidden;
        transition: transform .25s ease, visibility 0s linear .25s;
        overflow-y: auto;
        overscroll-behavior: contain;
        padding-bottom: calc(24px + env(safe-area-inset-bottom));
    }

    body.nav-abierto .main-navigation {
        transform: translateX(0);
        visibility: visible;
        transition: transform .25s ease, visibility 0s;
    }
    body.nav-abierto { overflow: hidden; }

    /* El botón queda por encima del panel abierto y pasa a ser la cruz de
       cerrar. Antes el panel lo tapaba y solo se salía tocando el velo. */
    .nav-toggle { position: relative; z-index: 1000; flex: 0 0 44px; }
    body.nav-abierto .nav-toggle { color: #fff; }

    .main-navigation .nav-menu { flex-direction: column; gap: 4px; }
    .main-navigation .nav-menu a { display: flex; align-items: center; min-height: 44px; padding: 10px 8px; color: #fff; }
}

/*
 * Cabecera en teléfonos — 2026-10-07 (P-114, C-02).
 *
 * El lockup (logo + «Educación CIPDH») medía 249 px fijos y no encogía, y la
 * fila no hace wrap: con el botón «Ingresar» o la ficha de usuario, el botón
 * de menú quedaba en x = 493 px en un teléfono de 390. Fuera de pantalla, y
 * comprimido a 22 px por flex-shrink. Ahora el lockup cede ancho (el texto se
 * recorta con puntos suspensivos) y el botón conserva sus 44×44.
 */
@media (max-width: 480px) {
    /* Con .site-header.esc-header a propósito: «.site-header .site-branding
       { flex: none }», más abajo en esta hoja, tiene la misma especificidad
       que .esc-header .site-branding y le ganaba por orden. */
    .site-header.esc-header .header-inner { gap: 10px; }
    .site-header.esc-header .site-branding { min-width: 0; flex: 0 1 auto; gap: 8px; }
    .site-header.esc-header .site-branding > a:first-child { flex: none; }
    .site-header.esc-header .site-branding img.custom-logo,
    .site-header.esc-header.is-scrolled .site-branding img.custom-logo,
    body.cipdh-nav-compacta .site-header.esc-header.is-scrolled .site-branding img { height: 40px; width: auto; }
    .site-header.esc-header .esc-logo-text { min-width: 0; }
    /* En dos líneas («EDUCACIÓN» / «CIPDH») en vez de recortar con puntos
       suspensivos: recortado se leía «EDUCACIÓN CIP…» y se perdía la marca. */
    .site-header.esc-header .esc-logo-text .esc-logo-main { font-size: 13px; line-height: 1.1; white-space: normal; }
    .site-header.esc-header .esc-logo-text .esc-logo-eyebrow { display: none; }
    .site-header.esc-header .header-tools { flex: none; gap: 8px; margin-left: auto; }
    .esc-btn-login { min-height: 44px; padding: 10px 14px; }
    .esc-userchip__meta { display: none; }
}

/* Por debajo de 360 px el texto del lockup no entra junto al logo: queda el
   logo solo, que ya dice CIPDH. */
@media (max-width: 359px) {
    .esc-logo-text { display: none; }
}

/* ── Avisos accesibles (región aria-live) ────────────────────────────────── */

.cipdh-avisos {
    position: fixed;
    right: 20px; bottom: 20px;
    z-index: 10000;
    display: flex;
    flex-direction: column;
    gap: 10px;
    max-width: 380px;
}

.cipdh-aviso {
    padding: 14px 18px;
    border-radius: 10px;
    box-shadow: var(--card-shadow-hover);
    background: var(--color-primary);
    color: #fff;
    font-size: .9rem;
    border: 1px solid rgba(255, 255, 255, .18);
}

.cipdh-aviso--error { background: var(--error);   border-color: var(--error); }
.cipdh-aviso--ok    { background: var(--success); border-color: var(--success); }

/* ── Cabecera en vistas internas ──────────────────────────────────────────
 * El encabezado del prototipo está calibrado para el sitio público: logo de
 * 120 px y cuatro entradas de menú. Dentro de la plataforma el menú llega a
 * siete entradas y compite con la ficha de usuario, así que la cabecera se
 * compacta y nada se apila. */

/* Acá vivía «body.cipdh-nav-compacta { --header-h: 88px }». Se eliminó el
   2026-09-16: declaraba el alto en el <body>, que es más específico que el
   :root de la consulta de medios de layout.css, así que en un teléfono las
   vistas internas seguían usando el valor de escritorio. Y además decía 88
   cuando el header medía 96. El alto ahora sale solo de tokens.css. Lo que
   esta clase sí hace —y sigue haciendo— es compactar el logo y el menú. */

body.cipdh-nav-compacta .site-header {
    background: var(--color-primary);
    box-shadow: var(--shadow-sm);
}

body.cipdh-nav-compacta .site-header .site-branding img,
body.cipdh-nav-compacta .site-header.is-scrolled .site-branding img { height: 46px; }

body.cipdh-nav-compacta .esc-logo-text .esc-logo-main { font-size: 15px; }
body.cipdh-nav-compacta .esc-logo-text .esc-logo-eyebrow { display: none; }

.site-header .site-branding {
    display: flex;
    align-items: center;
    gap: 14px;
    flex: none;
}

.esc-logo-text .esc-logo-main { white-space: nowrap; }

body.cipdh-nav-compacta .main-navigation ul.nav-menu { gap: 18px; flex-wrap: nowrap; }
body.cipdh-nav-compacta .main-navigation ul.nav-menu .menu-item a { white-space: nowrap; }

.site-header .header-tools { flex: none; }

@media (max-width: 1180px) {
    body.cipdh-nav-compacta .main-navigation ul.nav-menu { gap: 13px; }
    body.cipdh-nav-compacta .esc-userchip__meta { display: none; }
}

/* ── Cabecera de sección (vistas internas) ────────────────────────────────
 * Sustituye al .page-hero de 550 px, que existe para las páginas públicas
 * con imagen de fondo y acá dejaba media pantalla vacía. */

.esc-pagehead {
    padding: 40px 0 32px;
    background: var(--color-primary);
    color: #fff;
}

.esc-pagehead .esc-eyebrow {
    margin: 0 0 8px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 1.4px;
    text-transform: uppercase;
    color: var(--color-accent-light);
}

.esc-pagehead h1 {
    margin: 0;
    font-size: 2.5rem;
    line-height: 1.1;
    letter-spacing: -1px;
    color: #fff;
}

.esc-pagehead .page-subtitle {
    margin: 10px 0 0;
    font-size: 1rem;
    color: rgba(255, 255, 255, .82);
}

@media (max-width: 760px) {
    .esc-pagehead { padding: 28px 0 24px; }
    .esc-pagehead h1 { font-size: 1.875rem; }
}

/* ── Rejilla de accesos de los hubs ───────────────────────────────────────
 * Propia, no .esc-dash-grid: aquella es el layout 2fr/1fr del campus del
 * prototipo (contenido + barra lateral), no una grilla de tarjetas. */

.esc-tiles {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
    gap: 20px;
}

/* Dentro de la plataforma las secciones respiran menos: los 120 px de
   .esc-sec están calibrados para las páginas públicas de presentación. */
body.cipdh-interno .esc-sec { padding: 52px 0 44px; }
body.cipdh-interno .esc-sec + .esc-sec { padding-top: 44px; }
body.cipdh-interno .esc-sec-head { margin-bottom: 24px; }
body.cipdh-interno .esc-sec-head h2 { font-size: 1.5rem; }

/* La barra de administración de WordPress (solo la ve el administrator
   técnico) se superpone a la cabecera, que es position:fixed en top:0. */
body.admin-bar .site-header { top: 32px; }

@media screen and (max-width: 782px) {
    body.admin-bar .site-header { top: 46px; }
}

/* Hero público sin imagen de fondo: el .page-hero heredado mide 550 px porque
   está pensado para llevar una, y vacío deja media pantalla en blanco. */
.page-hero--plano {
    height: auto;
    min-height: 0;
    padding: 56px 0 48px;
    background: var(--color-primary);
    color: #fff;
    align-items: flex-start;
}

.page-hero--plano h1 { margin: 0; font-size: 3rem; line-height: 1.08; color: #fff; }
.page-hero--plano .esc-eyebrow { color: var(--color-accent-light); }
.page-hero--plano .page-subtitle { color: rgba(255, 255, 255, .85); }

@media (max-width: 760px) {
    .page-hero--plano { padding: 32px 0 32px; }
    .page-hero--plano h1 { font-size: 2rem; }
}

/* ── Formularios y alertas ────────────────────────────────────────────────
 * Compartidos por el catálogo, la gestión, el aula y el acceso. */

/* ── Formularios ─────────────────────────────────────────────────────────── */

.esc-field { margin-bottom: 18px; }

.esc-field label {
    display: block;
    margin-bottom: 6px;
    font-size: .875rem;
    font-weight: 600;
}

/*
 * Lista negra, no lista blanca — corregido el 2026-09-16.
 *
 * Acá había siete `input[type=…]` enumerados a mano, y las plantillas ya
 * usaban tres tipos que no estaban en la lista: `datetime-local` (siete veces,
 * en las fechas de apertura del constructor de cursos), `search` (el buscador
 * del catálogo y el del padrón) y `file`. Esos campos salían con el estilo por
 * defecto del navegador —Arial 13px, borde `inset` gris— en medio de un
 * formulario Montserrat con borde redondeado. Se veía roto y no era obvio por
 * qué.
 *
 * Con la forma negativa, un tipo de campo nuevo queda estilado solo,
 * y hay que acordarse de agregarlo únicamente cuando NO se lo quiere estilar.
 */
.esc-field input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="submit"]):not([type="button"]):not([type="image"]):not([type="range"]):not([type="hidden"]),
.esc-field select,
.esc-field textarea {
    width: 100%;
    padding: 12px 14px;
    font: inherit;
    font-size: 1rem;
    color: var(--color-text);
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: 8px;
    transition: border-color .2s, box-shadow .2s;
}

.esc-field input:focus-visible,
.esc-field select:focus-visible,
.esc-field textarea:focus-visible {
    outline: none;
    border-color: var(--color-accent);
    box-shadow: 0 0 0 3px rgba(62, 90, 126, .18);
}

.esc-field--inline label {
    display: flex;
    align-items: center;
    gap: 8px;
    font-weight: 500;
}

.esc-field--inline input[type="checkbox"] { width: auto; margin: 0; }

/* ── Alertas ─────────────────────────────────────────────────────────────── */

.esc-alert {
    margin-bottom: 20px;
    padding: 14px 16px;
    border-radius: 10px;
    font-size: .9rem;
    /* Sin barra a la izquierda (2026-09-17): fondo suave del color y un borde
       de un píxel del mismo tono, apenas visible. */
    border: 1px solid var(--glass-border);
    background: var(--glass-bg-tint);
}

.esc-alert--error { background: var(--error-soft);   border-color: rgba(192, 57, 43, .25);  color: var(--error); }
.esc-alert--ok    { background: var(--success-soft); border-color: rgba(39, 174, 96, .25);  color: var(--success); }
.esc-alert--aviso { background: var(--warning-soft); border-color: rgba(230, 126, 34, .25); color: var(--warning); }

/* ── Pie siempre al fondo ──────────────────────────────────────────────────
 * En páginas cortas —un 404, un panel vacío, el detalle de un ticket— el pie
 * quedaba flotando a media pantalla. Con el cuerpo como columna flexible y el
 * contenido creciendo, el pie se apoya siempre en el borde inferior sin
 * superponerse cuando la página sí es larga. */

body {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    min-height: 100svh; /* descuenta la barra del navegador en móviles */
}

/* El header es position:fixed, así que no ocupa lugar en el flujo y el
 * contenido le pasa por debajo. Hasta el 2026-09-16 cada vista se defendía
 * sola sumando calc(var(--header-h) + N) a su primer bloque —nueve hojas, seis
 * valores distintos—, y la vista que se olvidaba escondía su título bajo la
 * barra. Es exactamente lo que pasó al reescribir el inicio del campus.
 *
 * Ahora el espacio lo reserva <main>, una vez, y ninguna vista necesita saber
 * que el header existe. Los heroes y cabeceras de abajo llevan padding propio
 * y nada más. Lo único que sigue leyendo --header-h son los elementos
 * position:sticky, que se posicionan contra el viewport y no contra <main>. */
.site-main {
    flex: 1 0 auto;
    padding-top: var(--header-h);
}

/* Los nombres de pie que existen. Se listan todos para que agregar una
   plantilla con otro pie no reabra el problema. */
.site-footer,
.esc-pie,
.esc-footer-compact { flex-shrink: 0; margin-top: auto; }

/* ══════════════════════════════════════════════════════════════════════════
 * Pie universal — pedido del 2026-09-16.
 *
 * Reemplaza al pie compacto de cuatro enlaces. El mapa del sitio lo arma
 * CIPDH\Core\Pie según lo que cada persona puede abrir, así que esta hoja no
 * sabe cuántas columnas van a venir: entre dos (visitante) y cinco (alguien de
 * administración). Por eso la grilla se declara con auto-fit y no con un
 * número fijo — con tres columnas fijas, el visitante vería dos huecos.
 *
 * Jerarquía, de más a menos peso: marca → títulos de columna → enlaces →
 * línea legal. Cada nivel baja de tamaño y de contraste, y las columnas se
 * separan con líneas finas para que se lean como bloques y no como una masa
 * de enlaces.
 * ═══════════════════════════════════════════════════════════════════════════ */

.esc-pie {
    padding: 56px 0 0;
    background: var(--color-primary);
    color: rgba(255, 255, 255, .78);
    font-size: .875rem;
}

.esc-pie__grid {
    display: grid;
    grid-template-columns: minmax(240px, 1.4fr) minmax(0, 3fr);
    gap: 44px;
    padding-bottom: 40px;
}

/* ── Bloque de marca ─────────────────────────────────────────────────────── */

.esc-pie__logo { height: 84px; width: auto; margin-bottom: 16px; }

.esc-pie__nombre {
    margin: 0 0 8px;
    color: #fff;
    font-size: 1.05rem;
    font-weight: 800;
    letter-spacing: -.01em;
}

.esc-pie__desc {
    margin: 0 0 18px;
    max-width: 34ch;
    font-size: .8125rem;
    line-height: 1.6;
}

.esc-pie__contacto { margin: 0; padding: 0; list-style: none; }

.esc-pie__contacto li {
    display: flex;
    gap: 9px;
    align-items: flex-start;
    margin-bottom: 9px;
    font-size: .8125rem;
    line-height: 1.5;
}

.esc-pie__contacto .icon { flex: none; margin-top: 3px; color: var(--color-accent); }
.esc-pie__contacto a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }
.esc-pie__contacto a:hover { color: #fff; }

/* ── Mapa del sitio ──────────────────────────────────────────────────────── */

.esc-pie__mapa {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
    gap: 0;
}

/* La línea divisoria va a la izquierda de cada columna y se le quita a la
   primera. Con border-right, la última columna quedaba con una línea colgando
   contra el borde del contenedor. */
.esc-pie__col { padding: 0 22px; border-left: 1px solid rgba(255, 255, 255, .14); }
.esc-pie__col:first-child { padding-left: 0; border-left: 0; }

.esc-pie__titulo {
    margin: 0 0 14px;
    padding-bottom: 10px;
    border-bottom: 2px solid var(--color-accent);
    color: #fff;
    font-size: .6875rem;
    font-weight: 800;
    letter-spacing: .1em;
    text-transform: uppercase;
}

.esc-pie__col ul { margin: 0; padding: 0; list-style: none; }
.esc-pie__col li { margin-bottom: 9px; }

.esc-pie__col a {
    display: inline-flex;
    gap: 6px;
    align-items: center;
    color: rgba(255, 255, 255, .8);
    font-size: .8125rem;
    line-height: 1.45;
    transition: color var(--transition), transform var(--transition);
}

.esc-pie__col a:hover { color: #fff; transform: translateX(2px); }
.esc-pie__col a .icon { font-size: .7em; opacity: .6; }

/* ── Línea legal ─────────────────────────────────────────────────────────── */

.esc-pie__legal {
    padding: 18px 0 22px;
    border-top: 1px solid rgba(255, 255, 255, .14);
}

.esc-pie__legal p { margin: 0; font-size: .75rem; opacity: .65; }

@media (max-width: 900px) {
    .esc-pie { padding-top: 40px; }
    .esc-pie__grid { grid-template-columns: 1fr; gap: 32px; }

    /* En una columna, las líneas verticales no separan nada: pasan a
       horizontales, que es lo que sí divide cuando los bloques se apilan. */
    .esc-pie__mapa { gap: 0; }
    .esc-pie__col {
        padding: 20px 0 0;
        border-left: 0;
        border-top: 1px solid rgba(255, 255, 255, .14);
    }
    .esc-pie__col:first-child { padding-top: 0; border-top: 0; }
}

/* ══════════════════════════════════════════════════════════════════════════
 * MENÚ DE CUENTA — pedido del 2026-09-16.
 *
 * La ficha de usuario del header pasó de llevar un botón de salir suelto a ser
 * un desplegable. Motivo: «Cerrar sesión» estaba a un clic del avatar, y la
 * gente cerraba la sesión sin querer al ir a su perfil. Ahora hay que abrir el
 * menú, y salir está al final, separado por una línea.
 *
 * Los estilos de .esc-userchip vienen del prototipo (components.css) y no se
 * tocan: acá solo se lo hace comportarse como botón y se agrega el panel.
 * ═══════════════════════════════════════════════════════════════════════════ */

.esc-cuenta { position: relative; }

.esc-userchip--boton {
    padding: 5px 8px 5px 5px;
    border: 1px solid transparent;
    border-radius: 99px;
    background: transparent;
    font: inherit;
    color: inherit;
    cursor: pointer;
    transition: background var(--transition), border-color var(--transition);
}

.esc-userchip--boton:hover { background: rgba(255, 255, 255, .1); border-color: rgba(255, 255, 255, .18); }
.esc-userchip--boton:focus-visible { outline: 3px solid var(--color-accent-light); outline-offset: 2px; }
.esc-userchip--boton[aria-expanded="true"] { background: rgba(255, 255, 255, .14); border-color: rgba(255, 255, 255, .24); }

.esc-userchip__flecha {
    font-size: .6rem;
    color: rgba(255, 255, 255, .6);
    transition: transform var(--transition);
}

.esc-userchip--boton[aria-expanded="true"] .esc-userchip__flecha { transform: rotate(180deg); }

.esc-cuenta__menu {
    position: absolute;
    top: calc(100% + 10px);
    right: 0;
    z-index: 1100;
    min-width: 248px;
    padding: 6px;
    border: 1px solid var(--color-border);
    border-radius: 12px;
    background: var(--color-bg);
    box-shadow: 0 18px 44px rgba(35, 45, 79, .22);
}

.esc-cuenta__menu[hidden] { display: none; }

.esc-cuenta__quien {
    margin: 0 0 6px;
    padding: 10px 12px;
    border-bottom: 1px solid var(--color-border);
    line-height: 1.35;
}

.esc-cuenta__quien strong { display: block; font-size: .875rem; color: var(--color-text); }

.esc-cuenta__quien span {
    display: block;
    overflow: hidden;
    color: var(--color-text-muted);
    font-size: .75rem;
    text-overflow: ellipsis;
}

.esc-cuenta__item {
    display: flex;
    gap: 10px;
    align-items: center;
    padding: 9px 12px;
    border-radius: 8px;
    color: var(--color-text);
    font-size: .875rem;
    text-decoration: none;
    transition: background var(--transition), color var(--transition);
}

/* Con el prefijo .header-tools a propósito (2026-09-17): base.css declara
   `.header-tools a { color: inherit }` (0,1,1), que le ganaba a
   `.esc-cuenta__item` (0,1,0) y el menú heredaba el blanco del header: los
   ítems se veían como iconos sueltos sin texto. */
.header-tools .esc-cuenta__item { color: var(--color-text); }
.header-tools .esc-cuenta__item--salir { color: var(--error); }

.esc-cuenta__item .icon { width: 16px; flex: none; color: var(--color-text-muted); text-align: center; }
.esc-cuenta__item:hover { background: var(--color-bg-alt); color: var(--color-primary); }
.esc-cuenta__item:hover .icon { color: var(--color-primary); }
.esc-cuenta__item:focus-visible { outline: 2px solid var(--color-primary); outline-offset: -2px; }

/* Salir va separado del resto: es la única acción del menú que no se deshace. */
.esc-cuenta__item--salir {
    margin-top: 6px;
    padding-top: 13px;
    border-top: 1px solid var(--color-border);
    border-radius: 0 0 8px 8px;
    color: var(--error);
}

.esc-cuenta__item--salir .icon { color: var(--error); }
.esc-cuenta__item--salir:hover { background: var(--error-soft); color: var(--error); }
.esc-cuenta__item--salir:hover .icon { color: var(--error); }

@media (max-width: 1180px) {
    /* Con el nombre oculto, el menú se ancla al avatar y no se sale de la
       pantalla por la derecha. */
    .esc-cuenta__menu { right: -6px; min-width: 220px; }
}

/* ══════════════════════════════════════════════════════════════════════════
 * BARRAS DE PROGRESO — pedido del 2026-09-16: «barras de progreso con detalles
 * que no las hagan ver flotar».
 *
 * La barra era un riel plano del color de fondo con una barra dorada encima:
 * sin borde ni profundidad, parecía pegada sobre la página. Se le agrega un
 * borde interior sutil y un hundido, que es lo que hace leer el riel como una
 * canaleta y la barra como algo que la llena.
 * ═══════════════════════════════════════════════════════════════════════════ */

.esc-progreso {
    position: relative;
    border: 1px solid var(--color-border);
    box-shadow: inset 0 1px 2px rgba(35, 45, 79, .08);
}

.esc-progreso__barra {
    position: relative;
    box-shadow: 0 1px 2px rgba(35, 45, 79, .18);
}

/* Un progreso en cero tiene que verse como cero, no como «no hay barra». */
.esc-progreso__barra[style*="width:0%"],
.esc-progreso__barra[style*="width: 0%"] { box-shadow: none; }

/* En el carril y en las tablas la barra es finita: el borde de 1px se comería
   la mitad del alto, así que ahí se apoya solo en el hundido. */
.esc-progreso--fino { border: 0; box-shadow: inset 0 1px 2px rgba(35, 45, 79, .12); }

/* Honeypot: fuera de la pantalla, no display:none, para que un bot lo «vea». */
.esc-hp { position: absolute; left: -10000px; top: auto; width: 1px; height: 1px; overflow: hidden; }

/* ── Armonía de formularios (pedido 2026-09-25) ────────────────────────────
 * «Que todos los inputs se ordenen adecuadamente para la armonía de todo.»
 * Tres causas comunes a todos los formularios, resueltas acá una sola vez:
 * 1. La grilla usaba auto-fit: según el ancho salían 1, 2 o 3 columnas y un
 *    campo quedaba huérfano. Ahora son dos columnas fijas (una en móvil).
 * 2. Cada campo sumaba su margin-bottom al gap de la grilla: espaciado doble
 *    y desparejo. Dentro de la grilla el espacio lo da solo el gap.
 * 3. Inputs y selects tenían alturas distintas y los rótulos de dos líneas
 *    desalineaban la fila. Ahora todos miden lo mismo y el campo alinea al pie. */
.esc-grid-campos { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px 24px; align-items: end; }
.esc-grid-campos > .esc-field { margin-bottom: 0; }
.esc-grid-campos > .esc-field--ancho,
.esc-grid-campos > fieldset,
.esc-grid-campos > .esc-field--inline { align-self: start; }
.esc-field { display: flex; flex-direction: column; }
.esc-field label { margin-bottom: 7px; font-size: .8125rem; font-weight: 600; color: var(--color-text-muted); line-height: 1.35; }
.esc-field--inline label { color: var(--color-text); font-size: .875rem; }
.esc-field input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="submit"]):not([type="button"]):not([type="image"]):not([type="range"]):not([type="hidden"]),
.esc-field select { height: 46px; padding: 0 14px; font-size: .9375rem; }
.esc-field textarea { padding: 12px 14px; font-size: .9375rem; line-height: 1.55; resize: vertical; min-height: 110px; }
.esc-field select { appearance: none; padding-right: 38px; background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'><path fill='none' stroke='%2394a3b8' stroke-width='1.6' d='M1 1.5l5 5 5-5'/></svg>"); background-repeat: no-repeat; background-position: right 14px center; background-size: 12px 8px; }
.esc-field input:disabled, .esc-field select:disabled, .esc-field textarea:disabled { background-color: var(--color-bg-alt); color: var(--color-text-muted); cursor: not-allowed; }
.esc-field input[type="file"] { padding: 10px 12px; border: 1px dashed var(--color-border); border-radius: 8px; background: var(--color-bg-alt); font-size: .8125rem; }
.esc-field .esc-hint, .esc-field .text-xs { margin-top: 6px; }
.esc-form__acciones { justify-content: flex-end; margin-top: 24px; padding-top: 20px; border-top: 1px solid var(--color-border); }
@media (max-width: 720px) {
    .esc-grid-campos { grid-template-columns: 1fr; }
    .esc-form__acciones { justify-content: stretch; }
    .esc-form__acciones .btn { flex: 1; justify-content: center; }
}

/* Página legal oculta hasta la aprobación de Jurídicos (solo la ve Administración). */
.esc-legal-oculta { margin: 0 0 24px; padding: 12px 16px; border-radius: var(--radius); background: var(--warning-soft); color: var(--warning); font-size: .875rem; font-weight: 600; }
.esc-acceso__nota a { color: inherit; text-decoration: underline; }

/* Portada mínima (2026-09-25): el héroe ocupa la pantalla. */
.esc-hero--portada { min-height: calc(100vh - 160px); min-height: calc(100svh - 160px); display: flex; align-items: center; padding-top: 0; }
.esc-hero--portada > .container { width: 80%; max-width: none; margin-inline: auto; } /* 80 % del ancho (2026-09-25) */
@media (max-width: 760px) {
    .esc-hero--portada { min-height: 0; }
        }

/* Portada: la foto es protagonista; el velo azul queda solo detrás del texto. */
.esc-hero--portada .esc-hero__bg { opacity: 1; background-position: center right; }
.esc-hero--portada .esc-hero__overlay {
    background: linear-gradient(90deg, rgba(35,45,79,.94) 0%, rgba(35,45,79,.82) 34%, rgba(35,45,79,.35) 62%, rgba(35,45,79,.08) 100%);
}
@media (max-width: 760px) {
    .esc-hero--portada .esc-hero__overlay { background: linear-gradient(180deg, rgba(35,45,79,.55) 0%, rgba(35,45,79,.9) 100%); }
}

/*
 * Estados vacíos (2026-09-25): «todos estos mensajes parecen no tener los
 * márgenes óptimos». Los párrafos iban pegados (margin: 0) y el botón quedaba
 * encima del texto. Ahora son una caja suave con aire y separación pareja.
 */
.esc-empty {
    display: flex; flex-direction: column; align-items: center; gap: 16px;
    margin: 8px 0 24px; padding: 44px 28px;
    background: var(--color-bg-alt); border: 1px dashed var(--color-border); border-radius: var(--card-radius);
    text-align: center; color: var(--color-text-muted);
}
.esc-empty > * { margin: 0; }
.esc-empty i { margin: 0 0 4px; }
.esc-empty p { max-width: 52ch; font-size: .9375rem; line-height: 1.6; }
.esc-empty p:has(> .btn:only-child), .esc-empty p:has(> .ds-btn:only-child) { margin-top: 4px; }
.esc-empty .btn, .esc-empty .ds-btn { margin: 0; }

/* /cursos/: foto del slider de cipdh.gob.ar; los rostros quedan arriba del título. */
.page-hero--cursos .page-hero__bg { background-position: center 28%; }
.page-hero--cursos .page-hero__overlay { background: linear-gradient(to bottom, rgba(35,45,79,.05) 0%, rgba(35,45,79,.25) 45%, rgba(35,45,79,.88) 100%); }
/* Héroe de /cursos/ más corto (2026-09-25). */
.page-hero--cursos { height: 400px; }
@media (max-width: 760px) { .page-hero--cursos { height: 300px; } }

/* Fichas de docentes con «Leer más» en popup (2026-09-25). */
.au-person--texto.is-abrible { cursor: pointer; }
.au-person--texto.is-abrible:hover,
.au-person--texto.is-abrible:focus-visible { transform: translateY(-3px); box-shadow: var(--shadow-2); border-color: var(--color-accent); }
.au-person__bio.is-recortada { display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.au-person__bio.is-recortada p + p { display: none; }
.au-person__mas { display: inline-flex; align-items: center; gap: 6px; margin-top: 10px; font-size: .75rem; font-weight: 800; text-transform: uppercase; letter-spacing: .05em; color: var(--color-accent); }
.au-person__mas i { font-size: .7rem; transition: transform .2s; }
.au-person--texto.is-abrible:hover .au-person__mas i { transform: translateX(3px); }
.esc-teacher-modal[hidden] { display: none; }
.esc-teacher-modal { z-index: 10050; }
.esc-teacher-modal__card { max-height: calc(100vh - 40px); max-height: calc(100dvh - 40px); overflow-y: auto; overscroll-behavior: contain; } /* dvh: en iPhone el botón de abajo quedaba tapado por la barra (P-114, A-07) */
.esc-teacher-modal__bio p { margin: 0 0 12px; }
.esc-teacher-modal__bio p:last-child { margin-bottom: 0; }

/* Tablas con scroll horizontal (2026-09-25): los textos para lectores de
   pantalla (posición absoluta) de los interruptores se salían del contenedor
   y estiraban la página en el celular (Roles y permisos medía 700 px). */
.esc-tabla-scroll { position: relative; }
.esc-switch { position: relative; }

@media (max-width: 760px) { .esc-hero--portada > .container { width: auto; margin-inline: 16px; } }

/* ═══════════════════════════════════════════════════════════════════════════
 * Auditoría móvil y Safari — 2026-10-07 (P-114)
 * Cada bloque cita el punto del informe (docs/recomendaciones-educacioncipdh.txt).
 * ═══════════════════════════════════════════════════════════════════════════ */

/*
 * C-04 — Sin zoom automático de iOS al escribir.
 *
 * Safari de iPhone amplía la página al enfocar un campo con letra menor a
 * 16 px y no la devuelve al salir. Había campos de 15 px (.esc-field, el
 * usuario y la contraseña de /acceso/), 14 px (buscador de mensajes) y 13 px
 * (buscador del catálogo). Se resuelve acá una vez, con !important a
 * propósito: las hojas de vista se cargan después de ui.css y cualquier
 * regla nueva con .875rem volvería a provocar el zoom.
 *
 * Descartado: «maximum-scale=1» o «user-scalable=no» en el viewport. Quitan
 * el zoom a quien lo necesita para leer.
 */
@media (max-width: 980px) {
    input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="file"]):not([type="hidden"]):not([type="submit"]):not([type="button"]):not([type="image"]),
    select,
    textarea { font-size: 16px !important; }
}

/* A-01 — Aviso de sesión vencida (lo arma app.js): fijo abajo, con botón
   «Recargar», hasta que la persona recarga. No se cierra solo como los avisos
   comunes porque sin recargar nada de lo que haga se va a guardar. */
.cipdh-sesion {
    position: fixed;
    left: 50%;
    bottom: calc(20px + env(safe-area-inset-bottom));
    z-index: 10070;
    display: flex;
    align-items: center;
    gap: 14px;
    width: min(560px, calc(100% - 32px));
    padding: 14px 16px;
    border-radius: 12px;
    background: var(--color-primary);
    color: #fff;
    box-shadow: var(--card-shadow-hover);
    transform: translateX(-50%);
}
.cipdh-sesion p { margin: 0; flex: 1; font-size: .9375rem; line-height: 1.45; }
.cipdh-sesion .btn { flex: none; }
.cipdh-avisos { bottom: calc(20px + env(safe-area-inset-bottom)); }
@media (max-width: 480px) {
    .cipdh-avisos { left: 16px; right: 16px; max-width: none; }
}

/* M-03 — Botones de al menos 44 px de alto en pantallas táctiles. */
@media (max-width: 980px) {
    .btn { min-height: 44px; }
}

/* M-05c — Que el fondo no se desplace al llegar al final de un modal. */
.esc-teacher-modal,
.esc-encuesta-modal { overscroll-behavior: contain; }

/* M-03 — Enlaces del pie en pantallas táctiles: medían 20 px de alto y
   quedaban a 9 px uno de otro. 36 px de alto, sin margen entre filas, supera
   el mínimo de WCAG 2.2 (24 px) sin estirar el pie al doble con 27 enlaces. */
@media (max-width: 900px) {
    .esc-pie__col li { margin-bottom: 0; }
    .esc-pie__col a { min-height: 36px; }
}

/* «Mostrar contraseña» (P-114): el botón va dentro del campo, a la derecha,
   con 44×44 de zona táctil. El campo reserva ese lugar con padding-right. */
.esc-pass { position: relative; display: block; width: 100%; }
.esc-pass > input { width: 100%; padding-right: 52px !important; }
.esc-pass__ver {
    position: absolute;
    top: 50%;
    right: 2px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    border: 0;
    border-radius: 8px;
    background: transparent;
    color: var(--color-secondary);
    cursor: pointer;
    transform: translateY(-50%);
}
.esc-pass__ver:hover,
.esc-pass__ver[aria-pressed="true"] { color: var(--color-primary); }
.esc-pass__ver:focus-visible { outline: 3px solid var(--color-accent-light); outline-offset: -3px; }
/* Edge dibuja su propio ojo: con el nuestro, sobra. El botón de Llavero de
   Safari (::-webkit-credentials-auto-fill-button) NO se oculta: es el que
   completa la contraseña guardada en el iPhone. */
.esc-pass > input::-ms-reveal { display: none; }

/* M-01c — Héroe de /cursos/ con dos tamaños de imagen (los pasa la plantilla
   en variables): 64 KB en el teléfono en vez de 128 KB. */
.page-hero__bg[style*="--hero-chica"] { background-image: var(--hero-grande); }
@media (max-width: 760px) {
    .page-hero__bg[style*="--hero-chica"] { background-image: var(--hero-chica); }
}

/* Tabletas en horizontal (981–1100 px): con el menú completo (páginas sin
   carril, como el examen) la ficha de usuario se salía 5 px. */
@media (min-width: 981px) and (max-width: 1100px) {
    .site-header.esc-header .header-inner { gap: 16px; }
}

/* ═══ «Ver como» (P-123, 2026-10-14): franja fija abajo mientras el administrador mira como otra persona. */
.esc-ver-como { position: fixed; left: 0; right: 0; bottom: 0; z-index: 9999; display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 10px 16px; padding: 10px 16px; background: var(--color-primary); color: #fff; font-size: .875rem; font-weight: 600; box-shadow: var(--card-shadow); }
.esc-ver-como .icon { width: 18px; height: 18px; color: var(--color-gold); }
body.es-ver-como { padding-bottom: 64px; }
