/* ═══════════════════════════════════════════════════════════════════
   Widget de accesibilidad del formulario público de Carroceros — v1
   Cargado desde `base_publico.html`. Coexiste con `theme-config.css`
   y toma sus variables --c-* del :root.

   Portado desde la Plataforma Unificada (proyectos MultisitiosDeportes
   y prototipoUnificacionWordpress — este último es donde vive el
   cursor de lectura y la fuente para dislexia, que MultisitiosDeportes
   todavía no tiene).
   La estructura del FAB/panel (líneas de abajo hasta "TOGGLES") es
   genérica y se reutiliza tal cual. La sección de TOGGLES sí está
   reescrita: la original apuntaba a clases del page builder
   (`.portal-main`, `.portal-navbar`, `footer`...) que acá no existen —
   el layout real de esta página es `.idp-hero` (chrome, columna
   izquierda) + `.idp-form-side`/`.idp-card` (contenido, columna
   derecha). Además, a diferencia del portal, `base_publico.html` no
   consume `--c-bg`/`--c-text` en sus estilos (usa hex fijo con
   fallback), así que los modos de contraste pisan directamente las
   clases `.idp-*` en vez de reasignar variables.

   Las clases de los toggles se aplican en `<html>` (`:root.a11y-*`), no
   en `<body>`: el JS se carga desde el `<head>` y las pinta antes de que
   exista el body, para que no haya un flash de tema claro al recargar.
   ═══════════════════════════════════════════════════════════════════ */

.a11y-widget {
    position: fixed;
    /* Abajo a la IZQUIERDA, igual que en la Plataforma Unificada: la idea
       es que el ciudadano encuentre el botón en el mismo lugar en todos
       los sitios del gobierno, sin tener que reaprender por sitio. */
    left: 1.25rem;
    bottom: 1.25rem;
    /* Debajo del modal del video obligatorio (9999): ese modal no se
       puede cerrar hasta terminar, así que nada del widget debe poder
       taparlo. */
    z-index: 9990;
}

/* ── FAB (botón flotante) ──────────────────────────────────────────
   El costado izquierdo de esta página es el hero, pintado con
   --c-primary (más la foto tratada por encima) — el mismo color que
   usaría el FAB, así que ahí se invierte la pareja: fondo de card e
   ícono primary. Cuando el hero deja de ocupar ese costado (≤992px pasa
   a ser un banner arriba y abajo-izquierda queda el formulario blanco)
   se vuelve a la pareja normal.

   La Plataforma resuelve esto en runtime, midiendo con `elementFromPoint`
   qué color hay realmente detrás del botón en cada scroll, porque en un
   portal armado con bloques cualquier zona puede tener fondo de marca.
   Acá el layout es fijo y el punto de quiebre es conocido, así que
   alcanza una media query: determinista y sin JS.

   Los dos colores viven en variables propias para que el anillo de foco
   los siga automáticamente en ambos estados (ver :focus-visible). */
.a11y-fab {
    --a11y-fab-bg: var(--c-bg-card, #ffffff);
    --a11y-fab-fg: var(--c-primary, #13304D);
    width: 56px;
    height: 56px;
    border-radius: 50%;
    border: 0;
    background: var(--a11y-fab-bg);
    color: var(--a11y-fab-fg);
    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;
}
@media (max-width: 992px) {
    /* Mismo breakpoint que usa base_publico.html para colapsar el hero. */
    .a11y-fab {
        --a11y-fab-bg: var(--c-primary, #13304D);
        --a11y-fab-fg: var(--c-text-light, #f2f2f2);
    }
}
.a11y-fab:hover {
    transform: translateY(-2px) scale(1.03);
    box-shadow: 0 .85rem 1.6rem rgba(0, 0, 0, .28);
}
/* Anillo de foco de DOS tonos via box-shadow, no `outline`: el aro
   interno lleva el color del ícono (contrasta contra el fondo del FAB) y
   el externo el color del fondo del FAB (contrasta contra lo que haya
   detrás). Como los dos salen de las variables, la pareja se invierte
   sola junto con el botón y el foco queda visible en los dos estados —
   con un color fijo se perdía en uno de los dos. El aro va antes de la
   sombra de elevación para que esta siga leyéndose. */
.a11y-fab:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px var(--a11y-fab-fg),
                0 0 0 6px var(--a11y-fab-bg),
                0 .85rem 1.6rem rgba(0, 0, 0, .28);
}
.a11y-fab-icono {
    width: 30px;
    height: 30px;
}

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

.a11y-panel {
    position: absolute;
    bottom: 70px;
    left: 0;   /* alineado al FAB, que está anclado a la izquierda */
    width: 340px;
    max-height: 75vh;
    background: var(--c-bg-card, #FFFFFF);
    color: var(--c-text, #212529);
    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, #f2f2f2);
    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, #f2f2f2);
    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, #f2f2f2);
    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 {
    background: rgba(255, 255, 255, .18);
}
/* Estos dos botones viven sobre el header navy, así que un aro claro
   alcanza. Antes solo cambiaban de fondo, que es un indicador de foco
   demasiado sutil para navegación por teclado. */
.a11y-panel-accion:focus-visible {
    background: rgba(255, 255, 255, .18);
    outline: 2px solid var(--c-text-light, #f2f2f2);
    outline-offset: 1px;
}
.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, #6c757d);
    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, #f8f9fa);
    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, #212529);
    text-align: center;
    transition: background .12s ease, border-color .12s ease,
                transform .08s ease;
}
/* El aro cae FUERA de la tarjeta, sobre el fondo claro del panel, así
   que el primary contrasta igual esté la tarjeta activa (navy) o no. */
.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, #f2f2f2);
    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;
}

/* ═══════════════════════════════════════════════════════════════════
   TOGGLES — reglas que aplican cuando hay una clase `a11y-*` en
   `<html>`. Todo apunta a `.idp-*` (el layout real de esta página), no
   a `.portal-*` (page builder de origen).
   ═══════════════════════════════════════════════════════════════════ */

/* 1. Tamaño del texto — escala el font-size raíz, así todo lo que la
   página define en `rem` acompaña (por eso las plantillas públicas
   pasaron de `px` a `rem`). Va en `<html>` porque `rem` siempre se
   resuelve contra la raíz: puesto en el body no tendría ningún efecto. */
:root.a11y-text-110 { font-size: 110%; }
:root.a11y-text-120 { font-size: 120%; }
:root.a11y-text-130 { font-size: 130%; }

/* 2. Altura de línea — apunta al contenido de lectura de la card
   (intro, labels, help-text, alerts) sin tocar el hero (es chrome
   institucional, no prosa). */
:root.a11y-lh-150 .idp-card-body { line-height: 1.5; }
:root.a11y-lh-175 .idp-card-body { line-height: 1.75; }
:root.a11y-lh-200 .idp-card-body { line-height: 2; }

/* 3. Fuente legible — swap a Verdana en toda la página (hero incluido,
   igual la fuente institucional ahí es solo de marca, no de lectura
   extensa). */
:root.a11y-readable-font .idp-split,
:root.a11y-readable-font .idp-split * {
    font-family: Verdana, Tahoma, 'Trebuchet MS', Arial, sans-serif !important;
    letter-spacing: 0.02em;
    word-spacing: 0.04em;
}

/* 3.b Fuente para dislexia (MHF-HU042) — OpenDyslexic real, no una
   sans-serif del sistema como "Fuente legible". El @font-face NO vive
   acá (este CSS se sirve siempre) — lo inyecta el JS bajo demanda,
   solo la primera vez que este toggle se activa
   (`asegurarFuenteDislexia` en accesibilidad-widget.js), así el
   .woff2 nunca se descarga para quien no lo pidió.

   A propósito va DESPUÉS de "Fuente legible" en la hoja: si un
   visitante llegara a activar los dos toggles a la vez, con igual
   especificidad y ambos `!important`, gana la regla que aparece
   último — priorizamos el soporte real de dislexia por sobre el
   ajuste genérico. */
:root.a11y-dyslexic-font .idp-split,
:root.a11y-dyslexic-font .idp-split * {
    font-family: 'OpenDyslexic', Verdana, Tahoma, sans-serif !important;
    letter-spacing: 0.01em;
}

/* 4. Contraste — tres modos, cada uno con un objetivo distinto:
     - "claro": refuerza WCAG dentro del esquema institucional claro
       (texto más oscuro, bordes más marcados), sin tocar el hero.
     - "oscuro": modo nocturno. El hero (chrome, ya es navy con texto
       blanco) queda igual; la card pasa a fondo oscuro y TODO su
       texto pasa a --c-text-light — se acepta perder el color de
       marca en los labels a cambio de contraste garantizado.
     - "alto": máximo contraste, blanco/negro puro en TODA la página,
       hero incluido (ahí sí se sacrifica el branding por completo). */

:root.a11y-contrast-claro .idp-form-side { background: #fff !important; }
:root.a11y-contrast-claro .idp-card { background: #fff !important; }
:root.a11y-contrast-claro .idp-card-header { border-color: #495057 !important; }
:root.a11y-contrast-claro .idp-card-footer { background: #fff !important; color: #000 !important; border-color: #495057 !important; }
:root.a11y-contrast-claro .idp-intro,
:root.a11y-contrast-claro .idp-form .help-text,
:root.a11y-contrast-claro .idp-card-header .subtitle,
:root.a11y-contrast-claro .idp-step-indicator { color: #000 !important; }
:root.a11y-contrast-claro .idp-form input { border-color: #495057 !important; }

/* `color-scheme: dark` le avisa al navegador que pinte de oscuro lo que
   dibuja él y no el CSS: scrollbars, checkboxes, selects nativos y el
   date picker. Gana por especificidad al `html { color-scheme: light }`
   de base_publico.html. Los scrollbars del contenedor que scrollea sí
   están definidos a mano ahí, así que hay que pisarlos aparte. */
:root.a11y-contrast-oscuro { color-scheme: dark; }
:root.a11y-contrast-oscuro .idp-form-side {
    background: #1c1c1c !important;
    scrollbar-color: #4a4a4a #1c1c1c !important;
}
:root.a11y-contrast-oscuro .idp-form-side::-webkit-scrollbar-track { background: #1c1c1c !important; }
:root.a11y-contrast-oscuro .idp-form-side::-webkit-scrollbar-thumb { background: #4a4a4a !important; }
:root.a11y-contrast-oscuro .idp-card { background: #1c1c1c !important; box-shadow: none !important; }
:root.a11y-contrast-oscuro .idp-card-header { border-color: #3a3a3a !important; }
:root.a11y-contrast-oscuro .idp-card-footer { background: #161616 !important; border-color: #3a3a3a !important; }
/* Sweep de texto: todo el cuerpo de la card pasa a text-light, salvo
   los elementos con su propio fondo de color (botón primario, badge)
   que ya contrastan por sí mismos. Con !important: varios labels/textos
   del formulario (ej. "Sin número (S/N)") tienen su color puesto inline
   en el HTML — sin !important, un inline le gana a esta regla y el texto
   queda con su gris claro de siempre sobre el fondo oscuro, invisible. */
:root.a11y-contrast-oscuro .idp-card :is(h1, h2, p, label, span, div, small, strong) {
    color: var(--c-text-light, #f2f2f2) !important;
}
:root.a11y-contrast-oscuro .idp-btn-primary,
:root.a11y-contrast-oscuro .ins-badge,
:root.a11y-contrast-oscuro .idp-btn-primary * { color: #fff !important; }
:root.a11y-contrast-oscuro .idp-btn-secondary {
    background: transparent !important;
    color: var(--c-text-light, #f2f2f2) !important;
    border-color: #3a3a3a !important;
}
:root.a11y-contrast-oscuro .idp-form input,
:root.a11y-contrast-oscuro .idp-form select,
:root.a11y-contrast-oscuro .idp-form textarea {
    background: #262626 !important;
    color: var(--c-text-light, #f2f2f2) !important;
    border-color: #3a3a3a !important;
}
/* select2 (inscripcion.html, y el modal "Editar datos" de gestión): reemplaza
   el <select> nativo por su propio widget (<a class="select2-choice">
   <span class="select2-chosen">). La regla de arriba no lo alcanza (no es un
   <select> real), y el sweep de texto claro de más arriba fuerza el
   <span>/<div> interno a texto claro — sin este override queda texto claro
   sobre el fondo claro que le pone el <style> propio de cada página: invisible. */
:root.a11y-contrast-oscuro .select2-container .select2-choice {
    background: #262626 !important;
    border-color: #3a3a3a !important;
}
:root.a11y-contrast-oscuro .select2-container .select2-choice .select2-arrow {
    background: transparent !important;
}
:root.a11y-contrast-oscuro .select2-drop {
    background: #262626 !important;
    color: var(--c-text-light, #f2f2f2) !important;
    border-color: #3a3a3a !important;
}
:root.a11y-contrast-oscuro .select2-search input {
    background: #1c1c1c !important;
    color: var(--c-text-light, #f2f2f2) !important;
}
:root.a11y-contrast-oscuro .select2-results .select2-highlighted {
    background: var(--c-accent, #e6603a) !important;
    color: #fff !important;
}
:root.a11y-contrast-oscuro .idp-alert-info { background: #1a2a3a !important; }
:root.a11y-contrast-oscuro .idp-alert-error { background: #3a1f1f !important; }
:root.a11y-contrast-oscuro .idp-alert-warning { background: #3a3320 !important; }
/* .ins-info-box (inscripcion.html): la caja con los datos que trae la
   consulta a Nexo (DNI/CUIL/nombre). Tiene su propio fondo claro
   hardcoded — sin este override, el sweep de arriba le pone texto
   claro sobre ese mismo fondo claro y se vuelve ilegible. */
:root.a11y-contrast-oscuro .ins-info-box {
    background: #262626 !important;
    border-color: #3a3a3a !important;
    border-left-color: var(--c-accent, #e6603a) !important;
}
:root.a11y-contrast-oscuro .ins-info-row .lbl { color: #9aa0a6 !important; }
:root.a11y-contrast-oscuro .ins-info-row .val { color: var(--c-text-light, #f2f2f2) !important; }

:root.a11y-contrast-alto .idp-hero { background: #000 !important; background-image: none !important; }
:root.a11y-contrast-alto .idp-hero::before { opacity: 0 !important; }
:root.a11y-contrast-alto .idp-hero::after { background: none !important; }
:root.a11y-contrast-alto .idp-form-side,
:root.a11y-contrast-alto .idp-card,
:root.a11y-contrast-alto .idp-card-header,
:root.a11y-contrast-alto .idp-card-footer { background: #fff !important; }
:root.a11y-contrast-alto .idp-card,
:root.a11y-contrast-alto .idp-card-header,
:root.a11y-contrast-alto .idp-card-footer { border-color: #000 !important; }
:root.a11y-contrast-alto .idp-card :is(h1, h2, p, label, span, div, small, strong, a) {
    color: #000 !important;
}
:root.a11y-contrast-alto .idp-form input,
:root.a11y-contrast-alto .idp-form select,
:root.a11y-contrast-alto .idp-form textarea,
:root.a11y-contrast-alto .select2-container .select2-choice { border: 2px solid #000 !important; }
:root.a11y-contrast-alto .idp-btn-primary,
:root.a11y-contrast-alto a.idp-btn-primary { background: #000 !important; color: #fff !important; border: 2px solid #000 !important; }
:root.a11y-contrast-alto .idp-btn-secondary { background: #fff !important; color: #000 !important; border: 2px solid #000 !important; }
:root.a11y-contrast-alto :where(img, video) { filter: contrast(1.2); }

/* 5. Escala de grises.
   El filtro se aplica al contenido de la página (`.idp-split`) y, POR
   SEPARADO, a cada overlay a pantalla completa (`.idp-overlay`, hoy el
   modal del video de capacitación). No se puede resolver con un solo
   selector que los contenga a los dos: `filter` convierte al elemento
   en containing block de sus descendientes `position: fixed`, así que
   cualquier ancestro filtrado del modal lo desancla del viewport (en
   mobile, donde `.idp-split` mide más que la pantalla, el video se iba
   literalmente fuera de vista). Aplicado sobre el overlay mismo no hay
   problema: un elemento filtrado sigue posicionándose normalmente, solo
   afecta a lo que tenga adentro. Por eso los overlays se renderizan
   como hijos directos de <body> (ver bloque `overlays` en
   base_publico.html) y se listan acá explícitamente: quedan en escala
   de grises igual que el resto, sin perder el anclaje.

   El widget queda fuera de ambos selectores a propósito, para que el
   visitante siga distinguiendo por color qué toggles tiene activos. */
:root.a11y-grayscale .idp-split,
:root.a11y-grayscale .idp-overlay { filter: grayscale(1); }

/* 6. Pausar animaciones — comprime animations/transitions a casi-cero
   (0.001ms, no 0ms, así los listeners de `transitionend` igual
   disparan). El JS del widget además pausa los <video autoplay>; los
   que el visitante arranca a mano (el de la capacitación) no se tocan. */
:root.a11y-pause-animations,
:root.a11y-pause-animations *,
:root.a11y-pause-animations *::before,
:root.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;
}

/* 7. Resaltar botones — esta página es casi toda botones (Confirmar
   inscripción, Comenzar capacitación, Continuar...), varios de ellos
   `<a>` con pinta de botón (`a.idp-btn-*`); subrayarlos como si fueran
   texto de lectura rompía la forma del botón. Un outline grueso
   comunica "esto es interactivo" sin tocar el diseño interno, y
   funciona igual para `<button>` y `<a>`. */
:root.a11y-highlight-buttons .idp-btn {
    outline: 3px solid var(--c-accent, #e6603a) !important;
    outline-offset: 2px !important;
}

/* 8. Cursor de lectura — 3 sub-modos, ciclado por el JS
   (`aplicarCursorAsistido`). A diferencia de todo lo de arriba, acá el
   posicionamiento en tiempo real lo hace JS (`mousemove`); el CSS solo
   define la forma/apariencia de cada modo y el overlay contenedor.
   El JS solo ofrece estos modos en dispositivos con puntero real. */
.a11y-cursor-overlay {
    position: fixed;
    inset: 0;
    /* Arriba del FAB/panel (9990) para que el cursor personalizado no
       desaparezca al pasar sobre el propio widget, pero DEBAJO del modal
       del video obligatorio (9999). pointer-events:none evita que tape
       los clics. */
    z-index: 9995;
    pointer-events: none;
}

/* 8.1 Cursor grande — se oculta el nativo (todo el documento, no solo
   el overlay) y se dibuja uno propio más grande y de alto contraste
   (relleno oscuro + borde claro, visible sobre cualquier fondo).
   La clase la agrega el JS recién cuando el overlay que reemplaza al
   cursor ya está en pantalla, nunca antes. */
:root.a11y-cursor-grande,
:root.a11y-cursor-grande * {
    cursor: none !important;
}
.a11y-cursor-grande-punta {
    position: absolute;
    top: 0;
    left: 0;
    width: 40px;
    height: 40px;
    /* Corrige el origen para que la "punta" (esquina superior
       izquierda de la forma, antes de rotar) quede exactamente en la
       posición real del mouse, no el centro del cuadrado de 40px. */
    margin: -4px 0 0 -4px;
    background: #111;
    border: 3px solid #fff;
    border-radius: 50% 50% 50% 0;
    transform: rotate(-45deg);
    box-shadow: 0 1px 4px rgba(0, 0, 0, .5);
    will-change: transform;
}

/* 8.2 Máscara de lectura — dos paneles oscuros full-width que dejan
   una franja transparente centrada en la posición Y del mouse (~110px
   de alto), oscureciendo el resto de la página para que el visitante
   no pierda la línea que está leyendo. Los bordes en color marcan el
   límite de la franja legible, para distinguirla de la zona oscura. */
.a11y-cursor-mascara-panel {
    position: absolute;
    left: 0;
    right: 0;
    background: rgba(0, 0, 0, .6);
}
.a11y-cursor-mascara-arriba {
    top: 0;
    border-bottom: 3px solid var(--c-accent, #e6603a);
}
.a11y-cursor-mascara-abajo {
    bottom: 0;
    border-top: 3px solid var(--c-accent, #e6603a);
}

/* 8.3 Guía de lectura — franja corta que resalta la línea actual SIN
   oscurecer el resto (más liviana que la máscara). El JS mueve la barra
   siguiendo al mouse en los dos ejes, centrada en él, pero acotada a los
   bordes de la ventana: cuando la barra topa un extremo se queda ahí y el
   que sigue avanzando es el triángulo, deslizándose sobre ella hasta la
   posición real del puntero. Los dos se mueven por `transform` (la barra
   con `translate`, el triángulo con `translateX`), así que ninguno de los
   dos dispara layout mientras se mueve el mouse. */
.a11y-cursor-guia-linea {
    position: absolute;
    top: 0;
    left: 0;
    width: min(700px, 90vw);
    height: 12px;
    border-radius: 6px;
    background: var(--c-accent, #e6603a);
    border: 2px solid rgba(0, 0, 0, .55);
    box-shadow: 0 2px 8px rgba(0, 0, 0, .45);
    will-change: transform;
}
.a11y-cursor-guia-triangulo {
    position: absolute;
    top: -16px;
    left: 0;
    /* El JS reemplaza este transform por
       `translateX(calc(-50% + Npx))`, donde N es la posición del mouse
       dentro de la barra. El -50% centra el triángulo en esa posición. */
    transform: translateX(-50%);
    width: 0;
    height: 0;
    will-change: transform;
    border-left: 12px solid transparent;
    border-right: 12px solid transparent;
    /* Mismo color que la barra (--c-accent), no negro: así el triángulo
       se lee como parte de una sola pieza con la línea. El contorno
       oscuro (mismo tono que el borde de la línea) es lo que le da
       contraste contra fondos claros — no se puede usar `border` real
       en una forma hecha con border-triangle, por eso va como
       drop-shadow apilado en las 4 direcciones cardinales. */
    border-top: 12px solid var(--c-accent, #e6603a);
    filter:
        drop-shadow(1.5px 0 0 #111)
        drop-shadow(-1.5px 0 0 #111)
        drop-shadow(0 1.5px 0 #111)
        drop-shadow(0 -1.5px 0 #111);
}

/* ═══════════════════════════════════════════════════════════════════
   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;
    }
}
