/* ==========================================================================
   AFINE · Diagnóstico de cumplimiento — hoja de estilos del widget (Pieza A)
   CSS puro, sin librerías. Primero móvil (base = 375px), con media queries
   hacia arriba para tableta y escritorio. Todo va acotado bajo .af-diagnostico
   para no pisar ni heredar estilos del tema.

   Se edita aquí, en 02-BUILD; la copia de assets/widget/ del complemento la
   genera 04-AUDITORIA/verificacion/generar-copias.py. El porqué de cada
   decisión está en el comentario del bloque donde vive (BLOQUE 0 en
   adelante). Los contrastes citados son la razón WCAG 2.x calculada sobre el
   fondo real; los de las cuatro etiquetas de nivel los comprueba
   04-AUDITORIA/accesibilidad/contraste-niveles.py leyendo este mismo fichero.
   ========================================================================== */

/* ============================================================
   BLOQUE 0 — TIPOGRAFÍA DE MARCA (General Sans, autoalojada)
   El informe en PDF ya usa General Sans (mPDF, vía
   includes/class-afine-diagnostico-generador-pdf.php). El widget NO la
   cargaba: cada @font-face de abajo apunta, con ruta relativa, a
   assets/fuentes/ttf/ — un nivel por encima de assets/widget/, donde vive
   este mismo fichero dentro del complemento. Esa ruta relativa la resuelve
   el NAVEGADOR contra la URL de ESTA hoja de estilos (nunca contra la
   página que la incluye), así que funciona igual en la vista previa del
   editor, en /diagnostico/ o en cualquier otra página donde se incruste el
   bloque — sin tocar el PHP que lo encola.
   Licencia ITF Free Font License 2.0: autoalojar con @font-face está
   permitido de forma expresa (assets/fuentes/LICENCIA-GeneralSans.txt, §01
   y §03). Solo hay 4 pesos reales (400/500/600/700): ningún selector de
   aquí en adelante pide un font-weight por encima de 700, para no forzar al
   navegador a "negritar" sintéticamente un peso que no existe.
   ============================================================ */
@font-face {
  font-family: 'General Sans';
  src: url('../fuentes/ttf/GeneralSans-Regular.ttf') format('truetype');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'General Sans';
  src: url('../fuentes/ttf/GeneralSans-Medium.ttf') format('truetype');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'General Sans';
  src: url('../fuentes/ttf/GeneralSans-Semibold.ttf') format('truetype');
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'General Sans';
  src: url('../fuentes/ttf/GeneralSans-Bold.ttf') format('truetype');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

/* ============================================================
   BLOQUE 1 — IDENTIDAD VISUAL
   Paleta de AFINE tal cual la declara su propia web (variables CSS leídas
   en https://lightcoral-sardine-481867.hostingersite.com/ y en sus landings
   /lp/*.html, con capturas en 04-AUDITORIA/web-nueva/): navy de texto, teal
   de acento, celeste claro, verde de botón principal. Sustituye a una paleta
   anterior (navy oscuro y dorado medidos a mano sobre el logotipo) que no
   era de AFINE. --af-navy-2 no es un tono de navy: es el teal oscurecido
   (7,46:1 sobre blanco) que hace de segundo color de marca donde el texto SÍ
   necesita AA —enlaces, etiqueta de progreso, nivel de riesgo "medio"—,
   porque el --af-teal saturado de la marca (#2BA8A0) da solo 2,91:1 sobre
   blanco y no vale como color de texto.
   ============================================================ */
:root {
  --af-navy:        #003145;
  --af-navy-2:      #145F5A;
  --af-teal:        #2BA8A0;
  --af-sky:         #9CDCD9;
  --af-green:       #32D17E;
  /* Estado :hover/:focus del botón verde: mismo verde, un peldaño más
     oscuro y saturado (5,41:1 con texto navy). */
  --af-green-oscuro: #29B96C;
  --af-teal-l:      #E8F7F6;
  --af-bg:          #F7F9FB;
  --af-white:       #FFFFFF;
  /* Superficie de la tarjeta: nunca blanco puro (norma SEMPATIZA de fondo),
     un peldaño por encima del blanco para que la herramienta "empiece en
     algún sitio" incluso sin la cabecera navy — ver BLOQUE 7. */
  --af-superficie:  #FBFCFC;
  --af-border:      #E0F0F3;
  --af-border-dark: rgba(0,49,69,0.14);
  /* Borde con 3,46:1 medido contra --af-superficie, para los bordes que SÍ
     hace falta que se vean por sí solos: los que delimitan un control con el
     que se interactúa (opción, campo de texto).
     --af-border-dark (alfa sobre blanco) no llega ahí — sirve para separar
     bloques de contenido, no para señalar un control. Un borde en --af-sky
     tampoco vale: da solo 1,54:1 sobre blanco, muy por debajo del 3:1 que
     pide un control interactivo (WCAG 1.4.11). */
  --af-borde-visible: #82898C;
  /* Pista neutra del medidor de resultado: gris con un tinte de navy,
     nunca un gris puro, para no sonar a componente de librería genérica. */
  --af-pista:       #E4E7EA;
  --af-text:        #003145;

  --af-font-cuerpo:  'General Sans', sans-serif;

  --af-radio:        12px;
  --af-radio-tarjeta: 20px;
  /* Los botones de AFINE son píldoras (radio ~50% de su alto): ver el verde
     "Empezar diagnóstico" y el hueco "Ver qué incluye" de sus landings. */
  --af-radio-boton:  999px;
  --af-sombra-tarjeta-reposo: 0 1px 2px rgba(0,49,69,0.05), 0 12px 32px rgba(0,49,69,0.08);
  /* Resplandor en el verde de marca, no en navy: es la sombra del botón
     principal, y el botón principal ahora es verde (ver BLOQUE 10). */
  --af-sombra-boton:  0 8px 20px rgba(50,209,126,0.35);
  --af-sombra-foco:   0 0 0 2px var(--af-teal);
}

/* ============================================================
   BLOQUE 2 — TOKENS COMPLEMENTARIOS. Nivel = severidad
   (verde oscuro → teal oscuro → ámbar → rojo). Los cuatro son deliberadamente
   MÁS OSCUROS Y MENOS SATURADOS que --af-green (#32D17E): con la paleta de
   AFINE el botón principal ya es verde brillante, así que el nivel "bajo" no
   puede repetir ese mismo verde saturado sin que una etiqueta de resultado
   se confunda con una llamada a la acción — se aleja a un verde bosque
   oscuro. Los cuatro pares texto/fondo están verificados en AA (>=4.5:1)
   SOBRE EL FONDO YA COMPUESTO, que es lo que pinta el navegador, no sobre
   blanco puro. Lo comprueba 04-AUDITORIA/accesibilidad/contraste-niveles.py.
   Además del color: cada nivel se distingue también por texto (la
   puntuación "X sobre 1" siempre escrita, BLOQUE 11) y en la escala por
   peso, marcador y subrayado — ningún dato depende solo del color.
   ============================================================ */
:root {
  --af-nivel-bajo:           #146845;   /* 6,02:1 sobre su propio fondo */
  --af-nivel-bajo-bg:        rgba(20,104,69,0.08);
  --af-nivel-medio:          var(--af-navy-2);   /* 6,60:1 sobre su propio fondo */
  --af-nivel-medio-bg:       rgba(20,95,90,0.08);
  --af-nivel-medio-alto:     #8A5000;   /* 5,79:1 sobre su propio fondo */
  --af-nivel-medio-alto-bg:  rgba(138,80,0,0.08);
  --af-nivel-alto:           #A02020;   /* 6,73:1 sobre su propio fondo */
  --af-nivel-alto-bg:        rgba(160,32,32,0.08);

  --af-text-secundario:      #3E5865;

  --af-opcion-marcada-bg:    rgba(0,49,69,0.05);

  --af-espacio-1: 4px;
  --af-espacio-2: 8px;
  --af-espacio-3: 12px;
  --af-espacio-4: 16px;
  --af-espacio-5: 24px;
  --af-espacio-6: 32px;

  --af-max-ancho: 800px;
  --af-duracion-transicion: 160ms;
}

/* ============================================================
   BLOQUE 3 — RESET MÍNIMO, SOLO DENTRO DEL WIDGET
   ============================================================ */
.af-diagnostico,
.af-diagnostico *,
.af-diagnostico *::before,
.af-diagnostico *::after {
  box-sizing: border-box;
}

.af-diagnostico {
  font-family: var(--af-font-cuerpo);
  color: var(--af-text);
  /* La alineación no se hereda del sitio: en la web nueva de AFINE el bloque
     va dentro de una sección centrada, y el cuestionario entero salía centrado
     (enunciados, ayudas y las tarjetas de opción). `start` y no `left` para que
     siga valiendo si algún día hay una versión en árabe o hebreo. */
  text-align: start;
  background: var(--af-superficie);
  border-radius: var(--af-radio-tarjeta);
  box-shadow: var(--af-sombra-tarjeta-reposo);
  border: 1px solid rgba(0,49,69,0.08);
  /* overflow:hidden recorta las esquinas de la cabecera navy (full-bleed,
     BLOQUE 7) al radio de la tarjeta: sin esto, la cabecera pintaría un
     rectángulo recto por encima de una tarjeta con esquinas redondeadas. */
  overflow: hidden;
  max-width: var(--af-max-ancho);
  margin: 0 auto;
  line-height: 1.6;
  font-size: 16px;
  /* Reserva de altura para evitar CLS mientras cargan los JSON. */
  min-height: 460px;
}

@media (min-width: 640px) {
  .af-diagnostico {
    min-height: 500px;
  }
}

.af-diagnostico h1,
.af-diagnostico h2,
.af-diagnostico h3,
.af-diagnostico p,
.af-diagnostico fieldset,
.af-diagnostico legend {
  margin: 0;
  padding: 0;
  border: 0;
}

.af-diagnostico a {
  color: var(--af-navy-2);
}

.af-diagnostico a:hover,
.af-diagnostico a:focus-visible {
  color: var(--af-navy);
}

/* BLOQUE 4 — FOCO VISIBLE (WCAG 2.2, contraste no-textual >=3:1). */
.af-diagnostico :focus {
  outline: none;
}

.af-diagnostico :focus-visible {
  outline: 2px solid var(--af-navy);
  outline-offset: 2px;
  box-shadow: var(--af-sombra-foco);
  border-radius: 4px;
}

/* BLOQUE 5 — MOVIMIENTO */
@media (prefers-reduced-motion: reduce) {
  .af-diagnostico,
  .af-diagnostico * {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

/* ============================================================
   BLOQUE 6 — CONTENIDO PRINCIPAL (todo lo que SÍ cambia entre pasos)
   Antes, el padding vivía directamente en .af-diagnostico: eso impedía que
   la cabecera de marca (BLOQUE 7) llegara a los bordes de la tarjeta. Ahora
   el padding vive aquí, en el contenedor que sustituye widget.pintar() en
   cada paso, y la cabecera queda fuera, a sangre.
   ============================================================ */
.af-diagnostico__contenido {
  padding: var(--af-espacio-5) var(--af-espacio-4) var(--af-espacio-6);
}

@media (min-width: 640px) {
  .af-diagnostico__contenido {
    padding: var(--af-espacio-6) var(--af-espacio-6) 40px;
  }
}

/* Esqueleto de carga y mensaje de emergencia si JS no se ejecuta o falla la
   carga (NF10). Vive dentro de .af-diagnostico__contenido. */
.af-cargando {
  display: flex;
  flex-direction: column;
  gap: var(--af-espacio-3);
}

.af-cargando__linea {
  height: 14px;
  border-radius: 4px;
  /* El brillo del hueso de carga pasa por --af-sky (el celeste de marca):
     puramente decorativo, sin texto encima, así que no le aplica ningún
     umbral de contraste — es el sitio idóneo para un toque de celeste. */
  background: linear-gradient(90deg, var(--af-bg) 25%, var(--af-sky) 37%, var(--af-bg) 63%);
  background-size: 400% 100%;
  animation: af-brillo 1.6s ease-in-out infinite;
}

@media (prefers-reduced-motion: reduce) {
  .af-cargando__linea {
    animation: none;
    background: var(--af-bg);
  }
}

@keyframes af-brillo {
  0% { background-position: 100% 50%; }
  100% { background-position: 0 50%; }
}

.af-cargando__linea--ancha { width: 70%; height: 22px; }
.af-cargando__linea--media { width: 90%; }
.af-cargando__linea--corta { width: 55%; }
.af-cargando__linea--opciones { height: 48px; border-radius: var(--af-radio); }

.af-fallback {
  padding: var(--af-espacio-4);
  border: 1px solid var(--af-border-dark);
  border-radius: var(--af-radio);
  background: var(--af-bg);
}

.af-fallback p {
  margin-bottom: var(--af-espacio-2);
}

.af-fallback__contacto {
  display: flex;
  flex-wrap: wrap;
  gap: var(--af-espacio-3);
  font-weight: 600;
  font-size: 1.05em;
}

/* ============================================================
   BLOQUE 7 — CABECERA DE MARCA (persistente, la pone iniciar() UNA vez;
   no se repinta en cada paso, para que no parpadee al avanzar).

   Por qué existe: era el defecto más comentado por AFINE ("ni logo, ni
   color de marca"). Es a sangre (full-bleed) dentro de la tarjeta, en navy
   sólido: es lo primero que toca el ojo, y es la respuesta directa a "la
   tarjeta no empieza en ningún sitio". No lleva NINGÚN texto de título:
   la página que aloja el bloque ya pone su propio H1 y, si el bloque tiene
   activado su título, un H2 casi idéntico justo encima. Añadir aquí un
   tercer título solo empeoraría esa duplicación. El logotipo, con su propio
   texto "Afine Consultoría", ya identifica la pieza sin repetir palabras.
   ============================================================ */
.af-cabecera {
  background: var(--af-navy);
  padding: 14px var(--af-espacio-4);
  display: flex;
  align-items: center;
}

@media (min-width: 640px) {
  .af-cabecera {
    padding: 18px var(--af-espacio-6);
  }
}

/* Marca decorativa: imagen de fondo (no <img>) para que la ruta se
   resuelva siempre relativa a ESTE fichero (ver BLOQUE 0) sin depender de
   ninguna URL que construya PHP. aria-hidden porque es puramente
   decorativa: el texto equivalente para lectores de pantalla va en el
   <span> oculto de al lado, reutilizando .af-visualmente-oculto (BLOQUE
   14) en vez de duplicar esa regla. */
.af-marca {
  /* display:block (o inline-block): un <span> es inline por defecto y un
     elemento inline IGNORA width/height — con solo esta regla el logotipo
     medía 0×0 y no se veía nada en la cabecera aunque la imagen cargara
     bien. Encontrado al mirar la primera captura de la ronda 1. */
  display: block;
  width: 108px;
  height: 28px;
  background-image: url('../marca/logo-afine.webp');
  background-repeat: no-repeat;
  background-position: left center;
  background-size: contain;
  /* El logotipo del complemento es navy sobre transparente (para usarlo
     sobre fondos claros); aquí vive sobre navy sólido, así que se necesita
     en blanco. No hay una segunda versión "en negativo" entre los assets de
     marca, así que se fuerza a blanco por filtro en vez de pedir un fichero
     nuevo: brightness(0) dejaría el trazo en negro puro conservando el
     canal alfa (el fondo transparente sigue transparente), e invert(1)
     convierte ese negro en blanco. */
  filter: brightness(0) invert(1);
}

@media (min-width: 640px) {
  .af-marca {
    width: 128px;
    height: 32px;
  }
}

/* ============================================================
   BLOQUE 8 — TIRA DE PASO (nombre de bloque + progreso), por pregunta.
   Traducción a pantalla del filete del informe: en papel, una sección
   nueva se marca con una línea fina bajo el título; aquí, con un cambio de
   fondo (franja con un tinte de teal, el acento de marca) en vez de una
   regla, que en una interfaz que cambia todo el rato se ve menos como un
   "error de impresión" y más como una franja de estado propia de una
   aplicación — y de paso mete el segundo color de AFINE donde antes solo
   había navy.
   ============================================================ */
.af-paso {
  display: flex;
  flex-direction: column;
  gap: var(--af-espacio-5);
}

.af-paso:focus {
  /* El <div> de paso lleva tabindex="-1" para recibir el foco por guion al
     cambiar de pregunta (ver enfocarPaso() en diagnostico.js), y sin esto el
     navegador dibuja su anillo alrededor de la tarjeta entera. El foco de
     teclado de verdad, el de los controles, sigue visible (BLOQUE 4). */
  outline: none;
}

.af-tira-paso {
  display: flex;
  flex-direction: column;
  gap: var(--af-espacio-2);
  background: var(--af-teal-l);
  border-radius: var(--af-radio);
  padding: var(--af-espacio-3) var(--af-espacio-4);
  margin: calc(-1 * var(--af-espacio-2)) calc(-1 * var(--af-espacio-1)) 0;
}

.af-progreso {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.af-progreso__etiqueta {
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--af-navy-2);
}

.af-progreso__barra {
  height: 5px;
  border-radius: 999px;
  background: rgba(0,49,69,0.12);
  overflow: hidden;
}

.af-progreso__relleno {
  display: block;
  height: 100%;
  /* Teal, no verde: el verde de AFINE (--af-green) queda reservado para el
     botón principal — que es la única llamada a la acción de toda la
     pieza — así que una barra de avance que también fuera verde competiría
     por la misma atención. Es --af-navy-2 (el teal OSCURECIDO, no el
     --af-teal saturado): contra la pista clara da 5,78:1; el --af-teal
     saturado se queda en 2,26:1, por debajo del 3:1 no textual que pide
     un elemento gráfico con significado (WCAG 1.4.11). */
  background: var(--af-navy-2);
  border-radius: 999px;
  transition: width var(--af-duracion-transicion) ease-out;
}

.af-bloque-nombre {
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  /* Etiqueta pequeña en color de marca (teal oscuro, no gris): el mismo
     patrón de "eyebrow" que usa AFINE en sus propias secciones. */
  color: var(--af-navy-2);
}

/* ============================================================
   BLOQUE 9 — PREGUNTAS (fieldset + legend + opciones reales)
   ============================================================ */
.af-pregunta {
  display: flex;
  flex-direction: column;
  gap: var(--af-espacio-3);
}

.af-pregunta legend {
  font-size: 1.25rem;
  font-weight: 600;
  line-height: 1.4;
  color: var(--af-navy);
}

@media (min-width: 640px) {
  .af-pregunta legend {
    font-size: 1.4375rem;
  }
}

.af-ayuda {
  font-size: 0.9375rem;
  color: var(--af-text-secundario);
  line-height: 1.55;
}

.af-opciones {
  display: flex;
  flex-direction: column;
  gap: var(--af-espacio-2);
  margin-top: var(--af-espacio-2);
}

@media (min-width: 560px) {
  .af-opciones--grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--af-espacio-2);
    /* Antes el grid estiraba (stretch, valor por defecto) cada tarjeta a
       la altura de la más alta de su fila: con opciones de texto largo y
       corto mezcladas ("¿Cuál describe mejor la actividad principal?"),
       la tarjeta corta quedaba con el input y el texto pegados arriba y un
       hueco vacío grande debajo — el "descuadre" que AFINE señaló. Con
       align-items: start cada tarjeta mide solo lo que su propio texto
       necesita: la fila deja de tener una altura común, pero ninguna
       tarjeta parece rota o vacía por dentro, que es el error peor de los
       dos. */
    align-items: start;
  }
}

.af-opcion {
  position: relative;
  display: flex;
  align-items: flex-start;
  gap: var(--af-espacio-3);
  /* --af-borde-visible, no --af-border-dark: esta línea SÍ tiene que
     alcanzar 3:1 por sí sola (contraste no textual, WCAG 1.4.11): es lo que
     delimita un control con el que se interactúa, no un simple separador de
     contenido. */
  border: 1.5px solid var(--af-borde-visible);
  border-radius: var(--af-radio);
  background: var(--af-white);
  padding: var(--af-espacio-3) var(--af-espacio-4);
  min-height: 44px;
  cursor: pointer;
  transition: border-color var(--af-duracion-transicion) ease-out,
              background-color var(--af-duracion-transicion) ease-out;
}

.af-opcion input {
  width: 24px;
  height: 24px;
  min-width: 24px;
  min-height: 24px;
  flex-shrink: 0;
  accent-color: var(--af-navy);
}

.af-opcion__texto {
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--af-navy);
  flex: 1;
  padding-top: 2px;
}

.af-opcion:has(input:checked) {
  border-color: var(--af-navy);
  border-width: 2px;
  background: var(--af-opcion-marcada-bg);
  /* Con border-width creciendo de 1.5 a 2px al marcar, el padding se
     reduce en el mismo pixel de más para que la tarjeta no "salte" de
     tamaño ni desplace a las vecinas del grid. */
  padding: calc(var(--af-espacio-3) - 0.5px) calc(var(--af-espacio-4) - 0.5px);
}

.af-opcion:focus-within {
  border-color: var(--af-navy);
}

.af-opcion input:focus:not(:focus-visible) {
  outline: none;
}

.af-pregunta__error {
  display: flex;
  align-items: center;
  gap: var(--af-espacio-2);
  color: var(--af-nivel-alto);
  background: var(--af-nivel-alto-bg);
  border: 1px solid var(--af-nivel-alto);
  border-radius: var(--af-radio);
  padding: var(--af-espacio-2) var(--af-espacio-3);
  font-size: 0.875rem;
  font-weight: 600;
}

.af-banner-asesoria {
  border-left: 3px solid var(--af-navy-2);
  background: var(--af-teal-l);
  padding: var(--af-espacio-3) var(--af-espacio-4);
  border-radius: 0 var(--af-radio) var(--af-radio) 0;
  font-size: 0.875rem;
  color: var(--af-text);
}

/* ============================================================
   BLOQUE 10 — BOTONES
   El verde de AFINE (--af-green) es su color de botón en toda su web (hero,
   diagnóstico embebido, CTA de cierre) y aquí hace el mismo trabajo: es la
   ÚNICA acción que lo lleva. Con texto blanco encima da solo 1,99:1 —lo que
   ya falla en la propia web de referencia si se mide, y aquí no se repite
   el defecto—: el texto va en navy (6,92:1, AA sobrado). Forma de píldora
   (--af-radio-boton) como en sus landings, no el radio de tarjeta.
   ============================================================ */
.af-acciones {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--af-espacio-3);
  margin-top: var(--af-espacio-2);
}

.af-boton {
  font-weight: 700;
  font-size: 0.9375rem;
  /* El interlineado tampoco se hereda: con el de la web nueva de AFINE, el
     botón de enviar crecía hasta parecer un círculo en pantallas de 320 px.
     `normal` es lo que ya aplicaba el navegador a un <button> sin tema
     alrededor, así que aquí no cambia nada. */
  line-height: normal;
  border-radius: var(--af-radio-boton);
  padding: 12px 26px;
  min-height: 44px;
  border: 2px solid transparent;
  cursor: pointer;
  transition: border-color var(--af-duracion-transicion) ease-out,
              background-color var(--af-duracion-transicion) ease-out,
              box-shadow var(--af-duracion-transicion) ease-out,
              transform var(--af-duracion-transicion) ease-out;
}

.af-boton:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.af-boton--primario {
  background: var(--af-green);
  color: var(--af-navy);
  box-shadow: var(--af-sombra-boton);
  margin-left: auto;
}

.af-boton--primario:hover:not(:disabled),
.af-boton--primario:focus-visible:not(:disabled) {
  background: var(--af-green-oscuro);
  color: var(--af-navy);
}

.af-boton--primario:active:not(:disabled) {
  transform: translateY(1px);
}

.af-boton--secundario {
  background: transparent;
  color: var(--af-navy);
  border-color: var(--af-navy);
}

.af-boton--secundario:hover:not(:disabled),
.af-boton--secundario:focus-visible:not(:disabled) {
  background: var(--af-teal-l);
  border-color: var(--af-teal);
}

.af-boton--grande {
  font-size: 1.0625rem;
  padding: 14px 26px;
}

.af-boton--ancho-completo {
  width: 100%;
  margin-left: 0;
}

/* ============================================================
   BLOQUE 11 — PANTALLA DE RESULTADO
   Nivel de riesgo con su etiqueta ("Riesgo medio-alto", la misma palabra que
   la portada del PDF), un medidor horizontal de dos tonos (relleno hasta la
   puntuación, pista para el resto) con la cifra al lado, los contadores de
   áreas, la conclusión y el cierre que pide el correo (BLOQUE 17).
   ============================================================ */
.af-resultado {
  display: flex;
  flex-direction: column;
  gap: var(--af-espacio-6);
}

.af-resultado__titulo {
  font-size: 0.8125rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--af-navy-2);
}

.af-resultado__nivel {
  display: flex;
  flex-direction: column;
  gap: var(--af-espacio-3);
}

.af-resultado__etiqueta-nivel {
  font-size: 1.75rem;
  font-weight: 700;
  line-height: 1.2;
}

@media (min-width: 640px) {
  .af-resultado__etiqueta-nivel {
    font-size: 2.125rem;
  }
}

/* Medidor: pista neutra + relleno del color del propio nivel + cifra. El
   color NUNCA es el único portador del dato: el número "X sobre 1" va
   siempre escrito al lado, así que en blanco y negro (o para quien no
   distingue los cuatro tonos de severidad) el dato sigue estando completo
   por escrito, no solo por la longitud de la barra. */
.af-medidor {
  display: flex;
  align-items: center;
  gap: var(--af-espacio-3);
}

.af-medidor__pista {
  flex: 1;
  height: 10px;
  border-radius: 999px;
  background: var(--af-pista);
  overflow: hidden;
}

.af-medidor__relleno {
  display: block;
  height: 100%;
  border-radius: 999px;
}

.af-medidor__cifra {
  /* Sin esto la cifra queda a cero pixeles del borde de la tarjeta: no se
     recorta, pero se lee como si fuera a recortarse. */
  padding-right: 2px;
  font-size: 0.9375rem;
  font-weight: 700;
  color: var(--af-text-secundario);
  white-space: nowrap;
}

/* Escala textual bajo el medidor: cuatro paradas de "bajo" a "alto". El
   nivel activo no se distingue solo por su color: lleva más peso
   tipográfico, un punto lleno delante (●, un carácter, no un emoji) y un
   subrayado de 2px; los otros tres llevan un punto hueco (○) y color
   apagado. Las cuatro señales (peso, marcador, subrayado, color) sirven
   para que la caja que antes eran "cuatro cajas grises iguales" no vuelva
   a repetirse: ahora la activa se lee primero aunque se quite el color. */
.af-escala {
  display: flex;
  flex-wrap: wrap;
  gap: var(--af-espacio-4);
}

.af-escala__tramo {
  font-size: 0.8125rem;
  font-weight: 500;
  /* --af-text-secundario (7,53:1) para el tramo que NO está activo: un gris
     de marca más claro no llega a AA en texto de este tamaño (no cuenta
     como "texto grande" para WCAG). Se lee perfectamente, solo que sin el
     peso del tramo que sí está activo. */
  color: var(--af-text-secundario);
  padding-bottom: 3px;
  border-bottom: 2px solid transparent;
}

.af-escala__tramo::before {
  content: '○ ';
}

.af-escala__tramo[aria-current="true"] {
  font-weight: 700;
  color: currentColor;
  border-bottom-color: currentColor;
}

.af-escala__tramo[aria-current="true"]::before {
  content: '● ';
}

.af-contadores {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--af-espacio-3);
}

@media (min-width: 560px) {
  .af-contadores {
    grid-template-columns: repeat(3, 1fr);
  }
}

.af-contador {
  border: 1px solid var(--af-border-dark);
  border-radius: var(--af-radio);
  padding: var(--af-espacio-4) var(--af-espacio-3);
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.af-contador__numero {
  font-size: 2rem;
  font-weight: 700;
  line-height: 1;
}

.af-contador__etiqueta {
  font-size: 0.8125rem;
  color: var(--af-text-secundario);
  font-weight: 600;
  margin-top: 6px;
}

/* Pie con el denominador: antes la barra bajo cada número no llevaba
   ninguna cifra de referencia ("decoración con forma de dato"). El reparto
   (numero/total) ya se calculaba en diagnostico.js — el defecto era que no
   se veía en ningún sitio qué era "el 100%" de esa barra. Esta línea, común
   a las tres tarjetas, expone el mismo total que ya existía. */
.af-contadores__total {
  font-size: 0.8125rem;
  color: var(--af-text-secundario);
  grid-column: 1 / -1;
}

.af-resumen {
  display: flex;
  flex-direction: column;
  gap: var(--af-espacio-2);
  padding-top: var(--af-espacio-4);
  border-top: 1px solid var(--af-border-dark);
}

.af-resumen__etiqueta {
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--af-navy-2);
}

.af-conclusion {
  font-size: 1rem;
  line-height: 1.65;
}

.af-descargo {
  font-size: 0.8125rem;
  color: var(--af-text-secundario);
  font-style: italic;
  line-height: 1.5;
}

/* ============================================================
   BLOQUE 12 — FORMULARIO DE CONTACTO
   ============================================================ */
.af-formulario {
  display: flex;
  flex-direction: column;
  gap: var(--af-espacio-4);
}

.af-campo {
  display: flex;
  flex-direction: column;
  gap: var(--af-espacio-1);
}

.af-campo label {
  font-weight: 700;
  font-size: 0.9375rem;
  color: var(--af-navy);
}

.af-campo input[type="text"],
.af-campo input[type="email"] {
  font: inherit;
  padding: 11px 14px;
  border-radius: var(--af-radio);
  border: 1.5px solid var(--af-borde-visible);
  background: var(--af-white);
  color: var(--af-text);
  min-height: 44px;
}

.af-campo input[aria-invalid="true"] {
  border-color: var(--af-nivel-alto);
}

.af-campo__error {
  font-size: 0.8125rem;
  color: var(--af-nivel-alto);
  font-weight: 600;
}

.af-consentimiento {
  display: flex;
  gap: var(--af-espacio-3);
  align-items: flex-start;
  font-size: 0.875rem;
  line-height: 1.5;
  background: var(--af-teal-l);
  border-radius: var(--af-radio);
  padding: var(--af-espacio-3);
}

.af-consentimiento input {
  width: 24px;
  height: 24px;
  min-width: 24px;
  min-height: 24px;
  flex-shrink: 0;
  accent-color: var(--af-navy);
}

.af-trampa {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.af-formulario__error-general {
  display: none;
  color: var(--af-nivel-alto);
  background: var(--af-nivel-alto-bg);
  border: 1px solid var(--af-nivel-alto);
  border-radius: var(--af-radio);
  padding: var(--af-espacio-3);
  font-size: 0.875rem;
  font-weight: 600;
}

.af-formulario__error-general[data-visible="true"] {
  display: block;
}

/* ============================================================
   BLOQUE 13 — PANTALLAS FINALES (éxito y fallo visible)
   ============================================================ */
.af-final {
  display: flex;
  flex-direction: column;
  gap: var(--af-espacio-4);
  text-align: left;
}

.af-final h2 {
  font-size: 1.5rem;
  font-weight: 700;
  color: var(--af-navy);
}

.af-final p {
  font-size: 0.9375rem;
  line-height: 1.55;
}

.af-final--fallo {
  border-left: 4px solid var(--af-nivel-alto);
  padding-left: var(--af-espacio-4);
}

.af-final--exito {
  border-left: 4px solid var(--af-nivel-bajo);
  padding-left: var(--af-espacio-4);
}

.af-contacto-grande {
  display: flex;
  flex-direction: column;
  gap: var(--af-espacio-3);
  margin-top: var(--af-espacio-2);
}

@media (min-width: 480px) {
  .af-contacto-grande {
    flex-direction: row;
  }
}

.af-contacto-grande a {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--af-espacio-2);
  font-weight: 700;
  font-size: 1.0625rem;
  padding: 14px 20px;
  border-radius: var(--af-radio-boton);
  /* Mismo verde que el botón principal: es la misma familia de acción
     (seguir la conversación), así que lleva el mismo color, no uno nuevo. */
  background: var(--af-green);
  color: var(--af-navy);
  text-decoration: none;
  min-height: 44px;
  flex: 1;
}

.af-contacto-grande a:hover,
.af-contacto-grande a:focus-visible {
  background: var(--af-green-oscuro);
}

.af-resumen-repetido {
  background: var(--af-teal-l);
  border-radius: var(--af-radio);
  padding: var(--af-espacio-4);
}

/* BLOQUE 14 — región viva y textos para lector de pantalla, ocultos solo
   visualmente */
.af-visualmente-oculto {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ============================================================
   BLOQUE 15 — SEMILLA SERVIDA POR PHP
   La primera pregunta que el bloque pinta en el HTML antes de que llegue el
   JavaScript (ver renderizar() en class-afine-diagnostico-bloque-gutenberg.php).
   Es texto para leer, sin controles: el widget la sustituye al arrancar.
   ============================================================ */
.af-semilla {
  display: flex;
  flex-direction: column;
  gap: var(--af-espacio-2);
  padding: var(--af-espacio-5) var(--af-espacio-4);
}

.af-semilla__opciones {
  margin: 0;
  padding-left: 1.25em;
  color: var(--af-text-secundario);
}

.af-semilla__opciones li {
  margin-bottom: var(--af-espacio-1);
}

/* ============================================================
   BLOQUE 16 — ENTRADILLA DE LA PÁGINA
   Va FUERA del widget: es un párrafo de la página (clase af-entradilla en un
   bloque de párrafo), no una pieza del cuestionario. Se estiliza aquí porque
   el complemento es quien trae la tipografía de marca, y sin esto heredaría
   el cuerpo del tema y quedaría del mismo peso que el titular: tres frases
   diciendo lo mismo, las tres del mismo tamaño, sin jerarquía.

   El H1 manda; esto acompaña. De ahí el cuerpo mayor que el texto corriente
   pero el color más suave y el grosor normal.
   ============================================================ */
.af-entradilla {
  max-width: 62ch;
  margin-bottom: var(--af-espacio-6);
  font-family: var(--af-font-cuerpo);
  font-size: clamp(1.05rem, 0.98rem + 0.35vw, 1.25rem);
  font-weight: 400;
  line-height: 1.55;
  color: var(--af-text-secundario);
}

/* ============================================================
   BLOQUE 17 — EL CIERRE DE LA PANTALLA DE RESULTADO: DONDE SE DECIDE
   Va todo en un bloque —promesa, contenido, botón y motivo para fiarse—
   porque es una sola decisión, no cuatro. Y con MENOS peso que la
   conclusión: la conclusión es el diagnóstico y manda; esto la sostiene.
   ============================================================ */
.af-cierre {
  margin-top: var(--af-espacio-6);
  padding: var(--af-espacio-5);
  background: var(--af-teal-l);
  border: 1px solid var(--af-border);
  border-radius: var(--af-radio);
}

.af-cierre__promesa {
  margin: 0 0 var(--af-espacio-3);
  font-family: var(--af-font-cuerpo);
  font-size: 1.12rem;
  font-weight: 600;
  line-height: 1.3;
  color: var(--af-navy);
}

.af-cierre__lista {
  margin: 0 0 var(--af-espacio-4);
  padding: 0;
  list-style: none;
  display: grid;
  gap: 6px;
}

.af-cierre__lista li {
  position: relative;
  padding-left: 1.1em;
  font-size: .94rem;
  line-height: 1.45;
  color: var(--af-text-secundario);
}

.af-cierre__lista li::before {
  /* Un filete, no un punto ni un icono: marca sin llamar la atención sobre sí
     mismo, y se ve igual impreso y en blanco y negro. */
  content: "";
  position: absolute;
  left: 0;
  top: .62em;
  width: .55em;
  height: 1px;
  background: var(--af-text-secundario);
  opacity: .5;
}

.af-cierre__confianza {
  margin: var(--af-espacio-3) 0 0;
  font-size: .85rem;
  line-height: 1.45;
  text-align: center;
  color: var(--af-text-secundario);
}

/* ============================================================
   BLOQUE 18 — SITIO PARA LOS ELEMENTOS FLOTANTES DE LA PÁGINA
   diagnostico.js mide el botón de subir del tema o la burbuja de chat que
   flota en la esquina inferior (alturaDeFlotantes) y lo escribe aquí; sin
   nada flotando vale 0 y no cambia nada. La reserva va dentro del último
   bloque de cada pantalla, bajo su contenido: con el bloque entero a la vista,
   la capa cae sobre el hueco. En la caja de cierre sustituye a su margen
   interior si es mayor. scroll-margin-bottom hace lo mismo cuando desplaza el
   navegador, al llegar con el tabulador (WCAG 2.4.11).

   Y por arriba, donde vive la cabecera fija del tema: al enfocar el paso nuevo
   el navegador lo sube al borde de la ventana, y la cabecera le tapaba entera
   la tira de "Pregunta N de M" (medido en la web de AFINE). Ese alto lo mide
   altoDeCabeceraFija() justo antes de enfocar.
   ============================================================ */
.af-diagnostico {
  --af-reserva-flotantes: 0px;
  --af-reserva-cabecera: 0px;
}

.af-acciones,
.af-contacto-grande {
  padding-bottom: var(--af-reserva-flotantes);
}

.af-cierre {
  padding-bottom: max(var(--af-espacio-5), var(--af-reserva-flotantes));
}

.af-diagnostico a,
.af-diagnostico button,
.af-diagnostico input {
  scroll-margin-bottom: var(--af-reserva-flotantes);
}

.af-paso,
.af-resultado,
.af-final {
  scroll-margin-top: var(--af-reserva-cabecera);
}
