/* =========================================================================
   arkkosoft/accesibilidad — hoja del modulo
   =========================================================================

   ⚠ TODO LLEVA EL PREFIJO la11y-. Es lo unico que garantiza que instalar el
   modulo no cambie ni un pixel del sitio anfitrion. No hay ni una regla suelta
   sobre body, a, button o input: las que tocan el sitio entero cuelgan SIEMPRE
   de una clase en el <html> que pone el visitante (html.la11y-enlaces a { ... }).

   ⚠⚠ LOS VALORES CONFIGURABLES —color, radio— SON var() CON RESPALDO. La hoja
   generada (accesibilidad/tema.css) los declara en :root; sin ella, aqui esta
   el de serie. Asi un public/ sin permisos de escritura deja el widget con el
   color de serie, no roto.

   ⚠⚠⚠ ESTA HOJA NO SE GENERA Y NO SE DEBE EDITAR EN public/. Lo que hay ahi es
   una copia publicada; el original vive en el paquete. Editar la copia hace que
   la siguiente actualizacion la pise sin avisar.

   Orden del archivo:
     1. El boton flotante
     2. El panel
     3. Los controles
     4. Modo oscuro, movil y reduced motion
     5. LAS HERRAMIENTAS (las clases del <html>)
   ========================================================================= */

/* ------------------------------------------------------------------ base -- */

.la11y {
    --la11y-p: var(--la11y-primario, #1d4ed8);
    --la11y-p-rgb: var(--la11y-primario-rgb, 29, 78, 216);
    --la11y-p-txt: var(--la11y-primario-texto, #ffffff);
    --la11y-bg: var(--la11y-fondo, #ffffff);
    --la11y-bg-rgb: var(--la11y-fondo-rgb, 255, 255, 255);
    --la11y-fg: var(--la11y-texto, #111827);
    --la11y-fg-rgb: var(--la11y-texto-rgb, 17, 24, 39);
    --la11y-r: var(--la11y-radio, 16px);
    --la11y-fuente: var(--la11y-tipografia, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif);

    --la11y-borde: rgba(var(--la11y-fg-rgb), .14);
    --la11y-suave: rgba(var(--la11y-fg-rgb), .045);
    --la11y-tenue: rgba(var(--la11y-fg-rgb), .62);
    --la11y-sombra: 0 10px 30px rgba(var(--la11y-fg-rgb), .16), 0 2px 8px rgba(var(--la11y-fg-rgb), .08);

    --la11y-lado: 24px;
    --la11y-boton: 56px;

    position: fixed;
    inset: 0;
    z-index: 2147483000;   /* por encima de cualquier cabecera fija del sitio */
    pointer-events: none;  /* el hueco vacio no puede tapar el sitio */
    font-family: var(--la11y-fuente);
    color: var(--la11y-fg);
    line-height: 1.45;
}

.la11y > * { pointer-events: auto; }

.la11y--sombra-ninguna { --la11y-sombra: none; }
.la11y--sombra-suave   { --la11y-sombra: 0 4px 14px rgba(var(--la11y-fg-rgb), .10); }
.la11y--sombra-fuerte  { --la11y-sombra: 0 18px 46px rgba(var(--la11y-fg-rgb), .26), 0 4px 12px rgba(var(--la11y-fg-rgb), .12); }

.la11y--sep-12 { --la11y-lado: 12px; }
.la11y--sep-16 { --la11y-lado: 16px; }
.la11y--sep-24 { --la11y-lado: 24px; }
.la11y--sep-32 { --la11y-lado: 32px; }

/* ⚠ 44px ES EL MINIMO DE WCAG 2.2 (2.5.8) PARA UN OBJETIVO TACTIL, y por eso
   no hay un tamano mas pequeno. Un boton de accesibilidad que no se puede
   pulsar con el dedo es una contradiccion. */
.la11y--pequeno { --la11y-boton: 44px; }
.la11y--medio   { --la11y-boton: 56px; }
.la11y--grande  { --la11y-boton: 64px; }

/* ---------------------------------------------------------- 1. el boton -- */

.la11y-boton {
    position: absolute;
    display: inline-flex;
    align-items: center;
    gap: 10px;
    min-width: var(--la11y-boton);
    height: var(--la11y-boton);
    padding: 0 calc((var(--la11y-boton) - 24px) / 2);
    border: 2px solid transparent;
    border-radius: 999px;
    background: var(--la11y-p);
    color: var(--la11y-p-txt);
    font: inherit;
    font-weight: 600;
    cursor: pointer;
    box-shadow: var(--la11y-sombra);
    transition: transform .18s ease, box-shadow .18s ease;
}

.la11y-boton:hover { transform: translateY(-2px); }
.la11y-boton:active { transform: translateY(0); }

/* ⚠ DOS ANILLOS, UNO CLARO Y UNO OSCURO. El foco tiene que verse sobre
   cualquier fondo del sitio anfitrion, y el paquete no sabe cual es: un solo
   anillo del color primario desaparece en un sitio de ese mismo color. */
.la11y-boton:focus-visible,
.la11y-panel :focus-visible {
    outline: 3px solid #ffffff;
    outline-offset: 0;
    box-shadow: 0 0 0 6px #111827, var(--la11y-sombra);
}

.la11y-boton__icono { width: 24px; height: 24px; flex: none; }
.la11y-boton__texto { padding-right: 6px; white-space: nowrap; font-size: .95rem; }

.la11y--arriba-izquierda  .la11y-boton { top: var(--la11y-lado); left: var(--la11y-lado); }
.la11y--arriba-derecha    .la11y-boton { top: var(--la11y-lado); right: var(--la11y-lado); }
.la11y--centro-izquierda  .la11y-boton { top: 50%; left: var(--la11y-lado); transform: translateY(-50%); }
.la11y--centro-derecha    .la11y-boton { top: 50%; right: var(--la11y-lado); transform: translateY(-50%); }
.la11y--abajo-izquierda   .la11y-boton { bottom: var(--la11y-lado); left: var(--la11y-lado); }
.la11y--abajo-derecha     .la11y-boton { bottom: var(--la11y-lado); right: var(--la11y-lado); }

.la11y--centro-izquierda .la11y-boton:hover,
.la11y--centro-derecha .la11y-boton:hover { transform: translateY(-50%) scale(1.04); }

/* ------------------------------------------------------- el salto al pie -- */

/* Sale del flujo hasta que recibe el foco. Con display:none no lo encontraria
   el tabulador, que es justo para lo que existe. */
.la11y-salto {
    position: absolute;
    top: 0;
    left: 50%;
    transform: translate(-50%, -150%);
    padding: 12px 20px;
    border-radius: 0 0 var(--la11y-r) var(--la11y-r);
    background: var(--la11y-p);
    color: var(--la11y-p-txt);
    font-weight: 600;
    text-decoration: none;
    transition: transform .16s ease;
}

.la11y-salto:focus { transform: translate(-50%, 0); }

/* ----------------------------------------------------------- 2. el panel -- */

.la11y-panel {
    position: absolute;
    width: min(400px, calc(100vw - 2 * var(--la11y-lado)));
    max-height: min(680px, calc(100vh - 2 * var(--la11y-lado) - var(--la11y-boton) - 12px));
    display: flex;
    flex-direction: column;
    border: 1px solid var(--la11y-borde);
    border-radius: var(--la11y-r);
    background: var(--la11y-bg);
    box-shadow: var(--la11y-sombra);
    overflow: hidden;
}

.la11y-panel[hidden] { display: none; }

.la11y--arriba-izquierda  .la11y-panel { top: calc(var(--la11y-lado) + var(--la11y-boton) + 12px); left: var(--la11y-lado); }
.la11y--arriba-derecha    .la11y-panel { top: calc(var(--la11y-lado) + var(--la11y-boton) + 12px); right: var(--la11y-lado); }
.la11y--centro-izquierda  .la11y-panel { top: 50%; left: calc(var(--la11y-lado) + var(--la11y-boton) + 12px); transform: translateY(-50%); }
.la11y--centro-derecha    .la11y-panel { top: 50%; right: calc(var(--la11y-lado) + var(--la11y-boton) + 12px); transform: translateY(-50%); }
.la11y--abajo-izquierda   .la11y-panel { bottom: calc(var(--la11y-lado) + var(--la11y-boton) + 12px); left: var(--la11y-lado); }
.la11y--abajo-derecha     .la11y-panel { bottom: calc(var(--la11y-lado) + var(--la11y-boton) + 12px); right: var(--la11y-lado); }

.la11y-panel__cabecera {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
    padding: 18px 18px 14px;
    border-bottom: 1px solid var(--la11y-borde);
}

.la11y-panel__titulo { margin: 0; font-size: 1.12rem; font-weight: 700; letter-spacing: -.01em; }
.la11y-panel__subtitulo { margin: 4px 0 0; font-size: .82rem; color: var(--la11y-tenue); }

.la11y-cerrar {
    flex: none;
    width: 36px; height: 36px;
    display: grid; place-items: center;
    border: 1px solid var(--la11y-borde);
    border-radius: 10px;
    background: transparent;
    color: inherit;
    cursor: pointer;
}

.la11y-cerrar:hover { background: var(--la11y-suave); }
.la11y-cerrar__icono { width: 18px; height: 18px; }

.la11y-panel__cuerpo { overflow-y: auto; padding: 6px 18px 18px; overscroll-behavior: contain; }

.la11y-grupo { margin-top: 18px; }
.la11y-grupo__titulo {
    margin: 0 0 10px;
    font-size: .72rem;
    font-weight: 700;
    letter-spacing: .09em;
    text-transform: uppercase;
    color: var(--la11y-tenue);
}
.la11y-grupo__cuerpo { display: grid; gap: 10px; }

.la11y-panel__pie {
    padding: 14px 18px 16px;
    border-top: 1px solid var(--la11y-borde);
    background: var(--la11y-suave);
}

.la11y-reiniciar {
    display: inline-flex; align-items: center; gap: 8px;
    width: 100%;
    min-height: 44px;
    padding: 0 16px;
    justify-content: center;
    border: 1px solid var(--la11y-borde);
    border-radius: 12px;
    background: var(--la11y-bg);
    color: inherit;
    font: inherit; font-weight: 600;
    cursor: pointer;
}

.la11y-reiniciar:hover { border-color: var(--la11y-p); color: var(--la11y-p); }
.la11y-reiniciar__icono { width: 18px; height: 18px; }

.la11y-nota { margin: 10px 0 0; font-size: .74rem; color: var(--la11y-tenue); }

/* El aviso para lectores de pantalla: existe, no se ve, no ocupa. */
.la11y-aviso {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* ------------------------------------------------------ 3. los controles -- */

/*
   ⚠⚠ position: relative NO ES DECORACION, Y COSTO UN FALLO MUY FEO.
   Los controles reales (checkbox y radio) van en posicion absoluta y de un
   pixel encima de su etiqueta, que es la forma de esconderlos sin sacarlos del
   tabulador ni del arbol de accesibilidad. Sin esta linea, «absoluta» se
   resuelve contra el ANTEPASADO POSICIONADO MAS CERCANO —que es .la11y-panel—,
   asi que LOS TREINTA Y DOS CONTROLES SE APILAN EN LA ESQUINA SUPERIOR
   IZQUIERDA DEL PANEL, uno encima de otro.

   El sintoma no es que se vean —miden un pixel y son transparentes— sino este:
   al pulsar cualquier interruptor, el navegador desplaza el contenedor para
   «traer a la vista» el control que acaba de recibir el foco, que esta a
   seiscientos pixeles de donde se pulso. El panel se va hacia arriba y se
   queda en blanco. Parece un fallo de los filtros de color, porque es al
   encender uno cuando se nota.

   Lo encontro una comprobacion a mano en el navegador; ninguna prueba de PHP
   puede verlo.
*/
.la11y-item { position: relative; margin: 0; padding: 0; border: 0; }

/* Por lo mismo: la etiqueta del interruptor envuelve al control en el marcado
   pero el control es hermano suyo, asi que el contenedor posicionado tiene que
   ser el item, no la etiqueta. */
.la11y-interruptor, .la11y-opcion { position: relative; }

.la11y-item__icono { width: 20px; height: 20px; flex: none; color: var(--la11y-p); }
.la11y-item__texto { display: grid; gap: 2px; min-width: 0; }
.la11y-item__titulo { font-size: .92rem; font-weight: 600; }
.la11y-item__ayuda { margin: 0; font-size: .76rem; color: var(--la11y-tenue); }

.la11y-item__legend {
    display: flex; align-items: center; gap: 10px;
    padding: 0; margin-bottom: 2px;
    font-size: .92rem; font-weight: 600;
}

/* -- interruptor -- */

/* ⚠ EL CONTROL NO SE ESCONDE CON display:none NI CON visibility. Las dos lo
   sacan del recorrido del tabulador y del arbol de accesibilidad: el
   interruptor dejaria de existir para el teclado y para los lectores, que es
   exactamente lo contrario de lo que se busca. Se deja del tamano de un pixel
   encima de su etiqueta. */
.la11y-interruptor__control,
.la11y-opcion__control {
    position: absolute;
    width: 1px; height: 1px;
    opacity: 0;
    margin: 0;
}

.la11y-interruptor {
    display: flex; align-items: center; gap: 12px;
    min-height: 56px;
    padding: 10px 14px;
    border: 1px solid var(--la11y-borde);
    border-radius: 14px;
    background: var(--la11y-bg);
    cursor: pointer;
    transition: border-color .15s ease, background .15s ease;
}

.la11y-interruptor:hover { background: var(--la11y-suave); }

.la11y-interruptor__pista {
    flex: none;
    margin-left: auto;
    width: 46px; height: 26px;
    border-radius: 999px;
    background: rgba(var(--la11y-fg-rgb), .22);
    transition: background .18s ease;
    display: block;
}

.la11y-interruptor__bola {
    display: block;
    width: 20px; height: 20px;
    margin: 3px;
    border-radius: 50%;
    background: #fff;
    box-shadow: 0 1px 3px rgba(0, 0, 0, .3);
    transition: transform .18s ease;
}

.la11y-interruptor__control:checked + .la11y-interruptor {
    border-color: var(--la11y-p);
    background: rgba(var(--la11y-p-rgb), .08);
}
.la11y-interruptor__control:checked + .la11y-interruptor .la11y-interruptor__pista { background: var(--la11y-p); }
.la11y-interruptor__control:checked + .la11y-interruptor .la11y-interruptor__bola { transform: translateX(20px); }

/* El foco del control se pinta sobre la etiqueta, que es lo que se ve. */
.la11y-interruptor__control:focus-visible + .la11y-interruptor,
.la11y-opcion__control:focus-visible + .la11y-opcion {
    outline: 3px solid #ffffff;
    box-shadow: 0 0 0 6px #111827;
}

/* -- opciones (radios) -- */

.la11y-item--opciones {
    padding: 12px 14px;
    border: 1px solid var(--la11y-borde);
    border-radius: 14px;
    background: var(--la11y-bg);
}

.la11y-opciones {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 10px;
}

.la11y-opcion {
    flex: 1 1 auto;
    min-width: 72px;
    min-height: 44px;
    display: inline-flex; align-items: center; justify-content: center;
    padding: 0 12px;
    border: 1px solid var(--la11y-borde);
    border-radius: 10px;
    font-size: .84rem; font-weight: 600;
    text-align: center;
    cursor: pointer;
    transition: border-color .15s ease, background .15s ease, color .15s ease;
}

.la11y-opcion:hover { background: var(--la11y-suave); }

.la11y-opcion__control:checked + .la11y-opcion {
    border-color: var(--la11y-p);
    background: var(--la11y-p);
    color: var(--la11y-p-txt);
}

/* -- escala del texto -- */

.la11y-item--escala {
    padding: 12px 14px;
    border: 1px solid var(--la11y-borde);
    border-radius: 14px;
    background: var(--la11y-bg);
}

.la11y-escala { display: flex; align-items: center; gap: 8px; margin-top: 10px; }

.la11y-escala__boton {
    width: 48px; height: 44px;
    border: 1px solid var(--la11y-borde);
    border-radius: 10px;
    background: var(--la11y-bg);
    color: inherit;
    font: inherit; font-size: 1.2rem; font-weight: 700;
    cursor: pointer;
}

.la11y-escala__boton:hover { border-color: var(--la11y-p); color: var(--la11y-p); }

/* ⚠ aria-disabled Y NO disabled: un control deshabilitado sale del recorrido
   del tabulador, asi que el foco se quedaria colgado al llegar al maximo. Asi
   se anuncia sin desaparecer. */
.la11y-escala__boton[aria-disabled="true"] { opacity: .45; cursor: default; }
.la11y-escala__boton[aria-disabled="true"]:hover { border-color: var(--la11y-borde); color: inherit; }

.la11y-escala__valor {
    flex: 1;
    text-align: center;
    font-variant-numeric: tabular-nums;
    font-weight: 700;
}

/* -- voz -- */

.la11y-voz {
    margin-top: -4px;
    padding: 12px 14px;
    border: 1px dashed var(--la11y-borde);
    border-radius: 14px;
    display: grid;
    gap: 10px;
}

.la11y-voz[hidden], .la11y-voz__sin-soporte[hidden] { display: none; }

.la11y-voz__ayuda, .la11y-voz__sin-soporte { margin: 0; font-size: .76rem; color: var(--la11y-tenue); }
.la11y-voz__mandos { display: flex; gap: 6px; }

.la11y-voz__boton {
    flex: 1;
    min-height: 44px;
    border: 1px solid var(--la11y-borde);
    border-radius: 10px;
    background: var(--la11y-bg);
    color: inherit;
    font: inherit; font-size: .84rem; font-weight: 600;
    cursor: pointer;
}

.la11y-voz__boton:hover { border-color: var(--la11y-p); color: var(--la11y-p); }

.la11y-voz__ajuste { display: grid; grid-template-columns: 90px 1fr; gap: 10px; align-items: center; font-size: .8rem; }
.la11y-voz__ajuste input[type="range"] { width: 100%; accent-color: var(--la11y-p); }
.la11y-voz__ajuste select {
    min-height: 40px;
    border: 1px solid var(--la11y-borde);
    border-radius: 10px;
    background: var(--la11y-bg);
    color: inherit;
    font: inherit; font-size: .82rem;
    padding: 0 8px;
}

/* -------------------------------------- 4. oscuro, movil, reduced motion -- */

/* ⚠ EL MODO OSCURO DEL WIDGET NO DEPENDE DEL DEL SITIO, y por eso son tres
   modos y no dos. Un sitio claro puede querer el panel oscuro, y al reves.
   «sistema» es el unico que consulta la preferencia del navegador. */
.la11y--modo-oscuro,
.la11y--modo-oscuro .la11y-panel {
    --la11y-bg: var(--la11y-fondo-oscuro, #111827);
    --la11y-bg-rgb: var(--la11y-fondo-oscuro-rgb, 17, 24, 39);
    --la11y-fg: var(--la11y-texto-oscuro, #f3f4f6);
    --la11y-fg-rgb: 243, 244, 246;
}

@media (prefers-color-scheme: dark) {
    .la11y--modo-sistema,
    .la11y--modo-sistema .la11y-panel {
        --la11y-bg: var(--la11y-fondo-oscuro, #111827);
        --la11y-bg-rgb: var(--la11y-fondo-oscuro-rgb, 17, 24, 39);
        --la11y-fg: var(--la11y-texto-oscuro, #f3f4f6);
        --la11y-fg-rgb: 243, 244, 246;
    }
}

/* En un telefono el panel deja de ser un globo pegado al boton y pasa a ser
   una hoja anclada abajo: es lo unico que cabe a 320px sin recortar nada. */
@media (max-width: 520px) {
    .la11y .la11y-panel {
        top: auto;
        right: 8px;
        bottom: 8px;
        left: 8px;
        width: auto;
        max-height: 82vh;
        max-height: 82dvh;
        transform: none;
        border-radius: calc(var(--la11y-r) + 4px);
    }
}

/* ⚠ SE RESPETA LA PREFERENCIA DEL SISTEMA AUNQUE HAYA UNA HERRAMIENTA PARA LO
   MISMO. Quien la lleva puesta en el sistema no tiene por que volver a
   pedirlo en cada sitio que visita. */
@media (prefers-reduced-motion: reduce) {
    .la11y *, .la11y *::before, .la11y *::after {
        animation-duration: .001ms !important;
        transition-duration: .001ms !important;
    }
}

.la11y--sin-animacion *, .la11y--sin-animacion *::before, .la11y--sin-animacion *::after {
    animation-duration: .001ms !important;
    transition-duration: .001ms !important;
}

/* =========================================================================
   5. LAS HERRAMIENTAS — las clases que el guion pone en el <html>
   =========================================================================

   ⚠ NINGUNA REGLA DE AQUI ABAJO SE APLICA SOLA. Todas cuelgan de una clase
   que el visitante enciende, y todas excluyen al propio widget: sin eso, el
   panel de accesibilidad se volveria ilegible justo cuando alguien lo esta
   usando para arreglar la legibilidad.

   ⚠⚠ CADA VALOR POSIBLE TIENE SU REGLA ESCRITA AQUI, y esa es la razon de que
   las escalas sean listas cerradas: el estado viaja como CLASE porque un sitio
   con CSP sin 'unsafe-inline' descarta el atributo style en silencio. Si se
   anade un paso a config('accesibilidad.texto.escalas'), hay que anadirlo
   tambien aqui — hay una prueba que compara las dos listas y falla si no.
   ========================================================================= */

/* ------------------------------------------------- tamano del texto ------ */

/* ⚠ ESCALA EL TAMANO RAIZ, ASI QUE ESCALA LO QUE ESTE EN rem O EN em. Un sitio
   que escriba sus tamanos en px no cambiara, y eso es del sitio: es tambien lo
   que le impide cumplir el criterio 1.4.4 de WCAG con el zoom del navegador.
   El diagnostico no lo detecta y el README lo dice. */
html.la11y-texto-100 { font-size: 100%; }
html.la11y-texto-110 { font-size: 110%; }
html.la11y-texto-120 { font-size: 120%; }
html.la11y-texto-130 { font-size: 130%; }
html.la11y-texto-140 { font-size: 140%; }
html.la11y-texto-150 { font-size: 150%; }
html.la11y-texto-175 { font-size: 175%; }
html.la11y-texto-200 { font-size: 200%; }

/* --------------------------------------------------- espaciado ----------- */

/* Se pone en body y se hereda; el widget lo repone. Los valores son los del
   criterio 1.4.12 de WCAG (Text Spacing) o mas: 0,12em entre letras y 0,16em
   entre palabras en el paso amplio. */
html.la11y-espaciado-medio body  { letter-spacing: .06em; word-spacing: .1em; }
html.la11y-espaciado-amplio body { letter-spacing: .12em; word-spacing: .16em; }
html.la11y-espaciado-medio .la11y,
html.la11y-espaciado-amplio .la11y { letter-spacing: normal; word-spacing: normal; }

html.la11y-altura-linea-media body  { line-height: 1.7 !important; }
html.la11y-altura-linea-amplia body { line-height: 2 !important; }
html.la11y-altura-linea-media .la11y,
html.la11y-altura-linea-amplia .la11y { line-height: 1.45 !important; }

/* --------------------------------------------------- tipografia ---------- */

/* ⚠ NO SE DESCARGA NINGUNA FUENTE. Una tipografia «para dislexia» de verdad
   —Atkinson Hyperlegible, OpenDyslexic— habria que servirla desde el sitio, y
   un paquete que meta una descarga de fuente en cada pagina decide por el
   proyecto su presupuesto de red y su font-src. Se usa la mejor que haya
   instalada; si el proyecto quiere una concreta, la declara y la nombra
   primero en esta pila desde su propia hoja. */
html.la11y-tipografia-legible body,
html.la11y-tipografia-legible body :not(.la11y):not(.la11y *) {
    font-family: "Atkinson Hyperlegible", Verdana, "Segoe UI", Tahoma, sans-serif !important;
}
html.la11y-tipografia-serif body,
html.la11y-tipografia-serif body :not(.la11y):not(.la11y *) {
    font-family: Georgia, "Times New Roman", serif !important;
}
html.la11y-tipografia-paloseco body,
html.la11y-tipografia-paloseco body :not(.la11y):not(.la11y *) {
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif !important;
}

/* ----------------------------------------------- color: los filtros ------ */

/*
   ⚠⚠⚠ LA TRAMPA MAS CARA DE ESTE ARCHIVO, Y ESTA AQUI ESCRITA PARA NO VOLVER
   A PAGARLA: un elemento con «filter» distinto de none SE CONVIERTE EN EL
   BLOQUE CONTENEDOR de sus descendientes con position:fixed. Es decir:
   filtrar <html> o <body> —que es lo obvio— deja el boton flotante pegado al
   documento en vez de a la ventana, y el widget se va hacia arriba al
   desplazar. No da ningun error y parece un fallo de z-index.

   Por eso el filtro se aplica a los HIJOS DIRECTOS de body, excluyendo el
   widget. Un elemento fijo que sea hijo directo de body —una cabecera
   flotante, por ejemplo— sigue funcionando: el filtro propio no cambia como
   se posiciona EL, solo a sus descendientes. Uno fijo metido mas adentro de
   un hijo filtrado si se rompe, y es el limite conocido de esta herramienta.

   ⚠ Y LOS TRES FILTROS SE COMPONEN EN UNA SOLA DECLARACION con var() y
   respaldo vacio. Con una regla por herramienta, la ultima ganaria y encender
   «escala de grises» apagaria «invertir» sin decir nada.

   La clase «la11y-filtros» la pone el guion cuando alguno esta activo: sin
   ella no hay ni una regla de filtro sobre el sitio.
*/
html.la11y-filtros body > *:not(.la11y) {
    filter: var(--la11y-f-invertir, ) var(--la11y-f-grises, ) var(--la11y-f-sat, );
}

html.la11y-invertir { --la11y-f-invertir: invert(1) hue-rotate(180deg); }
html.la11y-grises { --la11y-f-grises: grayscale(1); }
html.la11y-saturacion-baja { --la11y-f-sat: saturate(.45); }
html.la11y-saturacion-alta { --la11y-f-sat: saturate(1.7); }

/* El fondo de body no lo toca el filtro de los hijos: sin esto, invertir deja
   el texto claro sobre el fondo blanco del sitio. */
html.la11y-invertir body { background-color: #0b0b0b !important; }

/* Las imagenes y los videos se vuelven a invertir para que se vean normales.
   Invertir una foto no mejora nada y deja el sitio irreconocible. */
html.la11y-invertir body > *:not(.la11y) :is(img, video, picture, canvas, iframe, svg[data-la11y-foto]) {
    filter: invert(1) hue-rotate(180deg);
}

/* ----------------------------------------------- color: contraste -------- */

/*
   El contraste NO es un filtro: fuerza colores. Un filter: contrast() sube el
   contraste de lo que ya hay —y hunde los grises medios— en vez de garantizar
   una pareja que se lea.

   ⚠ CON !important Y SOBRE «*», QUE ES EL UNICO SITIO DEL ARCHIVO DONDE SE
   HACE. Es lo que pide la herramienta: ganarle a cualquier color del sitio,
   incluidos los que el propio sitio pone con !important. Va excluyendo el
   widget con :not(.la11y, .la11y *).
*/
html.la11y-contraste-alto body,
html.la11y-contraste-alto body *:not(.la11y):not(.la11y *) {
    background-color: #ffffff !important;
    background-image: none !important;
    color: #000000 !important;
    border-color: #000000 !important;
    text-shadow: none !important;
    box-shadow: none !important;
}

html.la11y-contraste-oscuro body,
html.la11y-contraste-oscuro body *:not(.la11y):not(.la11y *) {
    background-color: #000000 !important;
    background-image: none !important;
    color: #ffffff !important;
    border-color: #ffffff !important;
    text-shadow: none !important;
    box-shadow: none !important;
}

html.la11y-contraste-alto body a:not(.la11y *) { color: #0000cc !important; text-decoration: underline !important; }
html.la11y-contraste-oscuro body a:not(.la11y *) { color: #ffff00 !important; text-decoration: underline !important; }
html.la11y-contraste-alto body :is(button, [type="submit"], [type="button"]):not(.la11y *),
html.la11y-contraste-oscuro body :is(button, [type="submit"], [type="button"]):not(.la11y *) {
    border: 2px solid currentColor !important;
}

/* Las imagenes se dejan en paz: pintarlas de un color liso no es contraste. */
html.la11y-contraste-alto body :is(img, video, picture, canvas):not(.la11y *),
html.la11y-contraste-oscuro body :is(img, video, picture, canvas):not(.la11y *) {
    background-color: transparent !important;
}

/* --------------------------------------------------- contenido ----------- */

html.la11y-enlaces body a:not(.la11y *) {
    text-decoration: underline !important;
    text-underline-offset: .18em !important;
    text-decoration-thickness: 2px !important;
    outline: 1px dashed currentColor;
    outline-offset: 2px;
}

/* El nivel se anuncia tambien por texto: un color solo no lo ve todo el mundo
   y no lo lee nadie. El ::before es contenido generado, asi que entra en el
   nombre accesible del encabezado en los navegadores que lo exponen. */
html.la11y-titulos body :is(h1, h2, h3, h4, h5, h6):not(.la11y *) {
    outline: 2px solid currentColor;
    outline-offset: 4px;
    padding-left: .35em;
}
html.la11y-titulos body h1:not(.la11y *)::before { content: "H1 · "; font-size: .7em; opacity: .75; }
html.la11y-titulos body h2:not(.la11y *)::before { content: "H2 · "; font-size: .7em; opacity: .75; }
html.la11y-titulos body h3:not(.la11y *)::before { content: "H3 · "; font-size: .7em; opacity: .75; }
html.la11y-titulos body h4:not(.la11y *)::before { content: "H4 · "; font-size: .7em; opacity: .75; }
html.la11y-titulos body h5:not(.la11y *)::before { content: "H5 · "; font-size: .7em; opacity: .75; }
html.la11y-titulos body h6:not(.la11y *)::before { content: "H6 · "; font-size: .7em; opacity: .75; }

html.la11y-botones body :is(button, [role="button"], [type="submit"], [type="button"], [type="reset"]):not(.la11y *) {
    outline: 3px solid currentColor !important;
    outline-offset: 2px !important;
}

/* ⚠ visibility:hidden Y NO display:none. Con display:none la pagina se
   recompone entera y el texto salta de sitio al encender la herramienta; asi
   el hueco se queda y solo desaparece la imagen. El alt sigue estando para
   quien use un lector. */
html.la11y-imagenes body :is(img, picture, video, svg:not([data-la11y-icono])):not(.la11y *) {
    visibility: hidden !important;
}
html.la11y-imagenes body *:not(.la11y):not(.la11y *) {
    background-image: none !important;
}

/* Detener animaciones. Es lo mismo que hace prefers-reduced-motion, a mano:
   hay gente que no lo lleva puesto en el sistema y lo necesita en este sitio. */
html.la11y-animaciones body *:not(.la11y *),
html.la11y-animaciones body *:not(.la11y *)::before,
html.la11y-animaciones body *:not(.la11y *)::after {
    animation: none !important;
    transition: none !important;
    scroll-behavior: auto !important;
}
html.la11y-animaciones body :is(video, audio):not(.la11y *) { /* el autoplay lo para el guion */ }

/*
   Modo lectura.

   ⚠ ES EL MAS APROXIMADO DE TODOS Y HAY QUE SABERLO: sin entender el sitio,
   «lo principal» solo se puede adivinar por el marcado. Se esconde lo que
   esta declarado como cabecera, pie, navegacion y complemento —con etiqueta o
   con rol—, y se estrecha el resto. Un sitio que no use ni <main> ni roles no
   mejorara mucho, y eso ya era un problema suyo antes de encender esto.
*/
html.la11y-lectura body :is(header, footer, nav, aside, [role="banner"], [role="contentinfo"], [role="navigation"], [role="complementary"], iframe):not(.la11y *) {
    display: none !important;
}
html.la11y-lectura body :is(main, [role="main"], article):not(.la11y *) {
    max-width: 44rem !important;
    margin-inline: auto !important;
    float: none !important;
    padding-inline: 1rem !important;
}
html.la11y-lectura body :is(main, [role="main"], article) :is(p, li):not(.la11y *) {
    font-size: 1.05rem !important;
    line-height: 1.8 !important;
}

/* --------------------------------------------------- navegacion ---------- */

/*
   El cursor. Va como imagen SVG en data:, no como archivo: asi no hay nada
   que publicar ni que pueda faltar, y el tamano lo decide la clase.

   ⚠ EL NUMERO DEL FINAL ES EL PUNTO CALIENTE («8 4»). Sin el, el navegador lo
   pone en la esquina superior izquierda de la imagen y el clic cae a varios
   pixeles de donde apunta la flecha: la gente pulsa al lado del enlace y no
   entiende por que no pasa nada.
*/
html.la11y-cursor-grande body *:not(.la11y *) {
    cursor: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 24 24"><path d="M5 2.5 19 12l-6.2 1.2 3 6-2.9 1.4-3-6L5 19Z" fill="%23ffffff" stroke="%23000000" stroke-width="1.4"/></svg>') 8 4, auto !important;
}
html.la11y-cursor-enorme body *:not(.la11y *) {
    cursor: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="72" height="72" viewBox="0 0 24 24"><path d="M5 2.5 19 12l-6.2 1.2 3 6-2.9 1.4-3-6L5 19Z" fill="%23ffffff" stroke="%23000000" stroke-width="1.4"/></svg>') 12 6, auto !important;
}

/* El foco reforzado. Dos anillos por la misma razon que en el widget: tiene
   que verse sobre cualquier fondo. */
html.la11y-foco body :is(a, button, input, select, textarea, summary, [tabindex]):not(.la11y *):focus,
html.la11y-foco body :is(a, button, input, select, textarea, summary, [tabindex]):not(.la11y *):focus-visible {
    outline: 3px solid #ffffff !important;
    outline-offset: 0 !important;
    box-shadow: 0 0 0 6px #111827 !important;
    border-radius: 2px;
}

/*
   La guia de lectura.

   ⚠ LA POSICION LA ESCRIBE EL GUION CON insertRule, NO CON UN style="". Es la
   misma razon que todo lo demas —la CSP descarta el atributo— pero aqui hace
   falta un valor que cambia con el raton, asi que no puede ser una clase. La
   CSSOM no pasa por la CSP: un <style> vacio creado desde el guion y luego
   rellenado con insertRule es la via limpia. Ver Hoja dinamica en el .js.
*/
/* ⚠ SE ENCIENDEN POR LA CLASE DEL <html> Y NO CON EL ATRIBUTO hidden DESDE EL
   GUION. Asi la herramienta funciona igual que las demas —una clase, una
   regla— y la prueba que comprueba que cada valor tiene su regla escrita
   alcanza tambien a esta. Con [hidden] el estado vivia en dos sitios. */
.la11y-guia,
.la11y-mascara {
    display: none;
    position: fixed;
    left: 0;
    right: 0;
    pointer-events: none;
    z-index: 2147482999;
}

.la11y-guia {
    top: 0;
    height: 3px;
    background: #d40000;
    box-shadow: 0 0 0 1px rgba(255, 255, 255, .85);
}

.la11y-mascara {
    top: 0;
    height: 100vh;
    background: rgba(0, 0, 0, .68);
    /* El hueco lo abre el guion cambiando el clip-path con insertRule. */
    clip-path: polygon(0 0, 100% 0, 100% 0, 0 0);
}

html.la11y-guia-linea .la11y-guia { display: block; }
html.la11y-guia-mascara .la11y-mascara { display: block; }
