/* ═══════════════════════════════════════════════════════════════════
   Widget de accesibilidad — v1 (5 toggles)
   Cargado desde portal/base.html. Coexiste con el theme institucional
   del tenant (--c-primary, --c-bg, etc.) y los toma del :root.
   ═══════════════════════════════════════════════════════════════════ */

.a11y-widget {
    position: fixed;
    left: 1.25rem;
    bottom: 1.25rem;
    z-index: 9990;          /* arriba de la mayoría del contenido del
                               portal, pero abajo del lightbox (z=10000)
                               para no taparlo cuando un visitante lo
                               abre desde una galería. */
}

/* ── FAB (botón flotante) ──────────────────────────────────────── */

.a11y-fab {
    width: 56px;
    height: 56px;
    border-radius: 50%;
    border: 0;
    background: var(--c-primary, #13304D);
    color: var(--c-text-light, #FFFFFF);
    cursor: pointer;
    box-shadow: 0 .55rem 1.2rem rgba(0, 0, 0, .22);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: transform .15s ease, box-shadow .15s ease,
                background .15s ease;
}
.a11y-fab:hover,
.a11y-fab:focus-visible {
    transform: translateY(-2px) scale(1.03);
    box-shadow: 0 .85rem 1.6rem rgba(0, 0, 0, .28);
    outline: none;
}
.a11y-fab-icono {
    width: 30px;
    height: 30px;
}

/* Cuando el FAB queda visualmente por encima del footer (que está pintado
   con --c-primary), invertimos la pareja de colores: pasamos a accent de
   fondo + primary de ícono. Sin esto, el botón "desaparece" sobre la
   banda institucional del footer porque coincide su navy con el del FAB. */
.a11y-widget.is-over-footer .a11y-fab {
    background: var(--c-accent, #b8860b);
    color: var(--c-primary, #13304D);
}

/* ── Panel ─────────────────────────────────────────────────────── */

.a11y-panel {
    position: absolute;
    bottom: 70px;
    left: 0;
    width: 340px;
    max-height: 75vh;
    background: var(--c-bg-card, #FFFFFF);
    color: var(--c-text, #1f2937);
    border-radius: 14px;
    box-shadow: 0 1.25rem 2.5rem rgba(0, 0, 0, .22);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    animation: a11y-panel-aparecer .18s ease-out;
}
.a11y-panel[hidden] { display: none; }
@keyframes a11y-panel-aparecer {
    from { opacity: 0; transform: translateY(8px); }
    to   { opacity: 1; transform: translateY(0); }
}

.a11y-panel-header {
    background: var(--c-primary, #13304D);
    color: var(--c-text-light, #FFFFFF);
    padding: 1rem 1.15rem;
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-shrink: 0;
}
.a11y-panel-titulo {
    margin: 0;
    font-size: 1.15rem;
    font-weight: 700;
    display: inline-flex;
    align-items: center;
    gap: .55rem;
}
.a11y-panel-titulo-icono {
    background: var(--c-text-light, #FFFFFF);
    color: var(--c-primary, #13304D);
    width: 28px;
    height: 28px;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.a11y-panel-titulo-icono svg { width: 18px; height: 18px; }
.a11y-panel-acciones {
    display: flex;
    gap: .3rem;
}
.a11y-panel-accion {
    background: transparent;
    border: 0;
    color: var(--c-text-light, #FFFFFF);
    width: 32px;
    height: 32px;
    border-radius: 6px;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: background .12s ease;
}
.a11y-panel-accion:hover,
.a11y-panel-accion:focus-visible {
    background: rgba(255, 255, 255, .18);
    outline: none;
}
.a11y-panel-accion svg { width: 18px; height: 18px; }

.a11y-panel-body {
    padding: .85rem 1rem 1rem;
    overflow-y: auto;
    flex: 1 1 auto;
    min-height: 0;
}

.a11y-grupo + .a11y-grupo { margin-top: 1rem; }
.a11y-grupo-titulo {
    margin: 0 0 .55rem;
    font-size: .82rem;
    font-weight: 600;
    color: var(--c-muted, #6b7280);
    text-transform: uppercase;
    letter-spacing: .03em;
}
.a11y-grupo-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: .55rem;
}

.a11y-card {
    background: var(--c-bg-subtle, #f3f4f6);
    border: 1px solid transparent;
    border-radius: 10px;
    padding: .75rem .5rem;
    cursor: pointer;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: .35rem;
    color: var(--c-text, #1f2937);
    text-align: center;
    transition: background .12s ease, border-color .12s ease,
                transform .08s ease;
}
.a11y-card:focus-visible {
    outline: 2px solid var(--c-primary, #13304D);
    outline-offset: 2px;
}
.a11y-card:active {
    transform: scale(.97);
}
.a11y-card.is-activo {
    background: var(--c-primary, #13304D);
    color: var(--c-text-light, #FFFFFF);
    border-color: var(--c-primary, #13304D);
}
.a11y-card-glyph {
    font-size: 1.4rem;
    line-height: 1;
    font-weight: 700;
}
.a11y-card-label {
    font-size: .82rem;
    line-height: 1.25;
    font-weight: 500;
}
.a11y-card-nivel {
    font-size: .72rem;
    opacity: .8;
    font-variant-numeric: tabular-nums;
}

.a11y-panel-footer {
    border-top: 1px solid var(--c-border-light, #e5e7eb);
    padding: .75rem 1rem;
    text-align: center;
    flex-shrink: 0;
}
.a11y-panel-link-decl {
    color: var(--c-primary, #13304D);
    font-size: .85rem;
    text-decoration: underline;
}

/* ═══════════════════════════════════════════════════════════════════
   TOGGLES — reglas que aplican al portal cuando hay una clase
   `a11y-*` en el <body>. Todo usa `:where()` para no inflar la
   especificidad y dejar que el operador siga pudiendo customizar
   bloques sin pelearse con !important.
   ═══════════════════════════════════════════════════════════════════ */

/* 1. Tamaño del texto — NO se maneja con clase. El JS setea
   `document.documentElement.style.fontSize = "110%"` (mismo patrón
   que el slider de gestión, ver `templates/setting.html` +
   `font-scale-overrides.css`). Todo lo que use `rem`/`em` en el
   portal escala automáticamente; lo que use `px` queda fijo. */

/* 2. Altura de línea — tres pasos para texto de lectura larga.
   Apuntamos al cuerpo de contenido (no a títulos ni navbar) para
   no romper el ritmo visual del chrome del sitio. */
body.a11y-lh-150 :where(.portal-main, .portal-texto, .portal-texto-cuerpo,
                       .portal-decl-a11y, .portal-card-descripcion,
                       .portal-acordeon-body-inner) { line-height: 1.5; }
body.a11y-lh-175 :where(.portal-main, .portal-texto, .portal-texto-cuerpo,
                       .portal-decl-a11y, .portal-card-descripcion,
                       .portal-acordeon-body-inner) { line-height: 1.75; }
body.a11y-lh-200 :where(.portal-main, .portal-texto, .portal-texto-cuerpo,
                       .portal-decl-a11y, .portal-card-descripcion,
                       .portal-acordeon-body-inner) { line-height: 2; }

/* 3. Fuente legible — swap a Verdana (universal, espaciado generoso,
   sin serifas finas que confunden a lectores con dislexia). Forzamos
   el override en TODO descendiente con `*` + `inherit` porque muchos
   bloques setean su propia font-family. El widget propio queda en
   su font normal (no aplica el override porque vive fuera de .portal-main). */
body.a11y-readable-font :where(.portal-main, .portal-navbar, .portal-topbar,
                                .portal-decl-a11y, footer) {
    font-family: Verdana, Tahoma, 'Trebuchet MS', Arial, sans-serif !important;
    letter-spacing: 0.02em;
    word-spacing: 0.04em;
}
body.a11y-readable-font :where(.portal-main, .portal-navbar, .portal-topbar,
                                .portal-decl-a11y, footer) :where(*) {
    font-family: inherit !important;
}

/* 4. Contraste — tres modos. Sobrescribimos las variables --c-* del
   tema solo cuando el modo está activo, así afecta a todo el stack
   (bloques, navbar, footer) sin tener que tocar cada CSS individual.

   Cada modo apunta a un usuario distinto:
     - "claro": refuerza WCAG dentro del esquema institucional claro.
     - "oscuro": modo nocturno con alto contraste interno.
     - "alto":  máximo contraste, blanco/negro puro + bordes fuertes.
*/
/* Los tres modos juegan con dos ejes:
     1) Lienzo del contenido (--c-bg / --c-bg-card / --c-bg-subtle):
        cambia entre claro y oscuro.
     2) Texto del cuerpo (--c-text y derivados):
        se invierte para mantener contraste con el lienzo.

   El chrome institucional (hero/navbar/topbar pintado con --c-primary
   y --c-accent) NO se toca: sigue usando --c-text-light para su texto,
   variable que NO cambia entre modos. Por eso ya no hace falta el
   override defensivo sobre navbar/hero que tenía la versión anterior. */

body.a11y-contrast-claro {
    --c-bg:           #FFFFFF;
    --c-bg-card:      #FFFFFF;
    --c-bg-subtle:    #F3F4F6;
    --c-text:         #111111;
    --c-text-on-light:#111111;
    --c-text-soft:    #1F2937;
    --c-text-strong:  #000000;
    --c-muted:        #4B5563;
    --c-border:       #6B7280;
    --c-border-light: #9CA3AF;
    /* En claro mantenemos texto-marca = primary (el patrón institucional
       normal). Solo subimos el contraste del cuerpo, no del branding. */
    --c-text-brand:   var(--c-primary);
}

body.a11y-contrast-oscuro {
    /* Lienzo en gris neutro casi negro — NO navy. Si usáramos un dark
       basado en primary, el navbar/hero (pintado con --c-primary) se
       funde con el fondo del cuerpo y se pierde la separación visual.
       Con un gris neutro muy oscuro el primary institucional sigue
       identificable como "chrome".

       Los tonos siguen la escala Material dark partiendo más profundo
       que el default (#121212) — bajamos a #0d0d0d para abrir más
       contraste con el primary del tenant (que típicamente está en
       el rango #15-25 de luminancia). La diferencia entre
       lienzo/card/subtle es ~6% de luminancia, lo justo para que los
       paneles se despeguen sin pelearse con el chrome. */
    --c-bg:           #0d0d0d;
    --c-bg-card:      #1c1c1c;
    --c-bg-subtle:    #262626;
    /* En oscuro, el "texto del cuerpo" pasa de oscuro a claro. Reusamos
       la variable --c-text-light que ya es la polaridad clara — así no
       inventamos un tercer color, mantenemos la pareja semántica. */
    --c-text:         var(--c-text-light);
    --c-text-on-light:var(--c-text-light);
    --c-text-soft:    #E5E7EB;
    --c-text-strong:  #FFFFFF;
    --c-muted:        #B0B0B0;
    --c-border:       #404040;
    --c-border-light: #2a2a2a;
    /* Texto de marca pasa a text-light (no accent) — la consigna del
       modo oscuro es priorizar contraste WCAG sobre identidad de marca.
       El accent queda reservado SOLO para hover en elementos
       clicleables, como única señal de "esto es interactivo" que
       sobrevive cuando todos los textos son del mismo color. */
    --c-text-brand:   var(--c-text-light);
    background: #0d0d0d;
    color: var(--c-text-light);
}
body.a11y-contrast-oscuro :where(.portal-main, .portal-body, footer) {
    background-color: var(--c-bg) !important;
    color: var(--c-text);
}

/* ── Modo oscuro: forzar todos los textos a text-light ────────────
   El usuario pidió que en dark mode todos los textos abandonen
   primary/text-brand y vayan a text-light, aceptando explícitamente
   que el diseño se vuelva "soso" a cambio de cumplir contraste. Esta
   regla barre el portal completo (main + footer + navbar) y aplica
   text-light a todos los nodos textuales típicos.

   No usamos `:where()` porque necesitamos especificidad para ganarle
   a las reglas de bloque que ya tienen color (ej. `.portal-card-titulo
   { color: var(--c-text-brand) }`). Con
   `body.a11y-contrast-oscuro :is(...) :is(...)` quedamos en (0,2,2) —
   beats todas las reglas de bloque que usan un solo ancestor. */
body.a11y-contrast-oscuro :is(.portal-main, .portal-navbar, footer) :is(
    h1, h2, h3, h4, h5, h6,
    p, a, li, td, th, span, div,
    button, label, small, strong, em, b, i,
    dt, dd, blockquote, summary, figcaption
) {
    color: var(--c-text-light);
}

/* Hover en elementos clicleables → accent. Es la única excepción al
   "todo blanco" y sirve de affordance: si al pasar el mouse el texto
   cambia, el visitante entiende que el elemento es interactivo. */
body.a11y-contrast-oscuro :is(.portal-main, .portal-navbar, footer)
    :is(a, button):hover,
body.a11y-contrast-oscuro :is(.portal-main, .portal-navbar, footer)
    :is(a, button):focus-visible {
    color: var(--c-accent);
}

/* Badges con fondo claro hardcoded (`.portal-material-badge--*`):
   tienen fondos pastel y texto oscuro. El sweep general les pisó el
   texto a blanco, que no contrasta con el fondo pastel. Acá los
   reinvertimos al patrón "fondo oscuro + texto color claro" típico
   de dark themes: mantiene la codificación semántica (rojo=PDF,
   azul=imagen, neutro=otros) y restaura contraste. La especificidad
   `body.<class> .portal-main .portal-material-badge--<x>` queda en
   (0,3,1), gana contra el sweep (0,2,2). */
body.a11y-contrast-oscuro .portal-main .portal-material-badge--pdf {
    background: rgba(220, 38, 38, 0.18);
    color: #fca5a5;
}
body.a11y-contrast-oscuro .portal-main .portal-material-badge--imagen {
    background: rgba(37, 99, 235, 0.20);
    color: #93c5fd;
}
body.a11y-contrast-oscuro .portal-main .portal-material-badge--otro {
    background: rgba(255, 255, 255, 0.10);
    color: var(--c-text-light);
}

body.a11y-contrast-alto {
    --c-bg:           #FFFFFF;
    --c-bg-card:      #FFFFFF;
    --c-bg-subtle:    #FFFFFF;
    --c-text:         #000000;
    --c-text-on-light:#000000;
    --c-text-soft:    #000000;
    --c-text-strong:  #000000;
    --c-muted:        #000000;
    --c-border:       #000000;
    --c-border-light: #000000;
    --c-primary:      #000000;
    --c-primary-dark: #000000;
    --c-primary-light:#FFFFFF;
    --c-primary-lighter:#FFFFFF;
    --c-accent:       #000000;
    /* En alto contraste el primary se vuelve negro puro — entonces el
       texto que iba sobre primary necesita seguir siendo claro para
       contrastar. Forzamos --c-text-light a blanco puro para máximo
       contraste (vs el #f2f2f2 default). */
    --c-text-light:   #FFFFFF;
    /* Texto-marca también negro puro — máximo contraste sobre blanco. */
    --c-text-brand:   #000000;
    background: #FFFFFF !important;
    color: #000000;
}
body.a11y-contrast-alto :where(img, video) {
    /* Aseguramos contraste mínimo de imágenes — sin esto pueden quedar
       lavadas sobre fondo blanco si tenían opacity o mix-blend. */
    filter: contrast(1.2);
}

/* 5. Escala de grises — filter en el wrapper principal. NO en el
   widget mismo, para que el visitante pueda seguir reconociendo el
   estado activo de los toggles por color. */
body.a11y-grayscale :where(.portal-main, .portal-navbar, .portal-topbar, footer) {
    filter: grayscale(1);
}

/* 6. Pausar animaciones — útil para visitantes con vestibular
   sensitivity. Comprime todas las animations/transitions a casi-cero
   (0.001ms — no 0ms, así los listeners de `transitionend` igual
   disparan). Limita las animations infinitas a una sola iteración.
   El JS del widget además pausa los <video> y emite un evento que
   escucha el carrusel para detener su autoplay (setInterval, fuera
   del alcance de CSS). */
body.a11y-pause-animations,
body.a11y-pause-animations *,
body.a11y-pause-animations *::before,
body.a11y-pause-animations *::after {
    animation-duration: .001ms !important;
    animation-delay: 0ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    transition-delay: 0ms !important;
    scroll-behavior: auto !important;
}

/* 6. Resaltar enlaces — subrayado fuerte en accent para todos los
   `<a>` del portal. No tocamos `color` ni `background` (eso rompía
   links sobre fondos de color como acordeón en navy, cinta de
   WhatsApp, botones que son <a>, etc.). Sólo el subrayado, con color
   propio (decoration-color) para que sea visible sobre cualquier
   fondo, sin requerir cambiar el texto. */
body.a11y-highlight-links :where(.portal-main a, .portal-main a:link, .portal-main a:visited) {
    text-decoration: underline solid 2px !important;
    text-decoration-color: var(--c-accent, #fbbf24) !important;
    text-underline-offset: 3px !important;
}

/* 6.b Bloques clicleables (accesos directos, cards, botones, banners,
   acordeón) tienen su propio diseño con fondos/colores propios. Para
   ellos el subrayado del texto interno tampoco sirve (no se entiende
   "todo el bloque es clickeable"). Usamos OUTLINE accent — comunica
   "esto es interactivo" sin disturbar el contenido. */
body.a11y-highlight-links .portal-main :is(
    .portal-acceso,
    .portal-card--clickable,
    .portal-material-card,
    .portal-card--overlay,
    .portal-banner,
    .portal-acordeon-header,
    .portal-cinta-whatsapp,
    button
) {
    outline: 3px solid var(--c-accent, #fbbf24) !important;
    outline-offset: 2px !important;
}

/* 7. Outline de foco — visible tanto en navegación por teclado como
   en click con mouse. Antes solo usaba `:focus-visible` que en la
   mayoría de browsers NO matchea con mouse click (heurística para
   "el foco lo necesitás solo si navegás por teclado"). Para que el
   toggle realmente haga algo cuando el visitante mueve el mouse,
   ampliamos a `:focus` también. */
body.a11y-focus-outline :focus,
body.a11y-focus-outline :focus-visible {
    outline: 3px solid var(--c-primary, #13304D) !important;
    outline-offset: 3px !important;
    border-radius: 3px;
}

/* ═══════════════════════════════════════════════════════════════════
   Página pública de la declaración (/accesibilidad/).
   Hereda layout y tipografía del portal (`portal-texto`, `portal-container`)
   — sólo sumamos los headers institucionales y la grilla de metadata.
   ═══════════════════════════════════════════════════════════════════ */

.portal-decl-a11y {
    padding-block: 2.5rem 3rem;
}
.portal-decl-a11y-header {
    border-bottom: 2px solid var(--c-primary, #13304D);
    padding-bottom: 1rem;
    margin-bottom: 1.5rem;
}
.portal-decl-a11y-header h1 {
    color: var(--c-primary, #13304D);
    font-size: 2rem;
    font-weight: 700;
    margin: 0 0 .25rem;
}
.portal-decl-a11y-subtitulo {
    color: var(--c-muted, #6b7280);
    font-size: 1rem;
    margin: 0;
}
.portal-decl-a11y-cuerpo {
    margin-bottom: 2rem;
}
.portal-decl-a11y-meta {
    background: var(--c-bg-subtle, #f3f4f6);
    border-radius: 10px;
    padding: 1.25rem 1.5rem;
}
.portal-decl-a11y-meta-grid {
    display: grid;
    grid-template-columns: minmax(180px, max-content) 1fr;
    gap: .75rem 1.5rem;
    margin: 0;
}
.portal-decl-a11y-meta-grid dt {
    font-weight: 600;
    color: var(--c-text-strong, #111827);
}
.portal-decl-a11y-meta-grid dd {
    margin: 0;
    color: var(--c-text, #1f2937);
}
.portal-decl-a11y-tel {
    color: var(--c-muted, #6b7280);
    font-size: .9rem;
}
@media (max-width: 600px) {
    .portal-decl-a11y-meta-grid {
        grid-template-columns: 1fr;
        gap: .25rem 0;
    }
    .portal-decl-a11y-meta-grid dt {
        margin-top: .75rem;
    }
    .portal-decl-a11y-meta-grid dt:first-child {
        margin-top: 0;
    }
}

/* ═══════════════════════════════════════════════════════════════════
   Responsive — en mobile el panel ocupa casi todo el ancho.
   ═══════════════════════════════════════════════════════════════════ */
@media (max-width: 480px) {
    .a11y-widget {
        left: .75rem;
        bottom: .75rem;
    }
    .a11y-panel {
        width: calc(100vw - 1.5rem);
        max-width: 360px;
    }
}
