/* =============================================================================
   NUTRITUPP · cfg-08-a11y.css — capa 08 del configurador, la accesibilidad
   -----------------------------------------------------------------------------
   Va la ULTIMA. No monta nada nuevo: repara lo que ya esta y no se ve.

   TODO lo de aqui esta MEDIDO en el navegador sobre /pedidos, no deducido.
   Cada bloque lleva su criterio WCAG 2.2 y la razon numerica.

   No toca planificador.css, ni pedidos.html, ni ningun fichero de otro agente.
   Donde hace falta cambiar el MARCADO se dice en el informe, no aqui.
   ========================================================================== */


/* =============================================================================
   1 · LOS SEIS TOKENS MUERTOS
   -----------------------------------------------------------------------------
   MEDIDO con getComputedStyle(document.body) en /pedidos:

     --texto      (VACIO)      --rojo       (VACIO)
     --teal       (VACIO)      --teal-osc   (VACIO)
     --linea      (VACIO)      --verde-osc  (VACIO)

   --teal y --linea NO estan sin declarar: estan declarados EN CICLO.
   planificador.css:24 y :27 dicen, sobre `body`:

       --teal:  var(--teal,  #145961);
       --linea: var(--linea, #dcd2c4);

   Una propiedad personalizada que se referencia a si misma entra en ciclo, y
   en un ciclo el respaldo NO se usa: el valor resultante es el invalido
   garantizado. Los otros cuatro nunca se declararon en ninguna hoja.

   Consecuencia real, no teorica. Una declaracion `background: var(--X)` con
   --X invalido no cae al color de antes: la declaracion entera se anula y la
   propiedad vuelve a su valor inicial, que en background es TRANSPARENTE y en
   border-color es currentColor. Siete cosas rotas, todas comprobadas:

     · El chip de alergeno pulsado (planificador.css:259)
         background:var(--rojo) -> transparente
         border-color:var(--rojo) -> currentColor -> #fff
         color:#fff
       = blanco sobre blanco, 1,19:1. PULSAR "Gluten" HACE DESAPARECER "Gluten".
       Es la unica senal de que el filtro de riesgo esta activo, y es
       informacion legal (Reglamento UE 1169/2011).            [1.4.3 / 1.4.11]

     · El filtro activo de la carta (planificador.css:483)
         background:var(--teal) -> transparente, color:#fff -> 1,19:1.  [1.4.3]

     · El brindis, unico aria-live de la pagina (planificador.css:532)
         background:var(--teal-osc) -> transparente, texto blanco. INVISIBLE.
       Y es el unico acuse de recibo del flujo tactil que la propia pagina
       recomienda ("pulsalo primero y luego toca el hueco").         [1.4.3]

     · El pie (planificador.css:538): fondo transparente y texto #cfe3e0 sobre
       crema = 1,12:1. El telefono y el correo del negocio, ilegibles. [1.4.3]

     · La barra de PROTEINAS (planificador.js:368 escribe background:var(--teal)
       en linea) -> transparente. La barra de proteina no se pinta nunca.

     · El semaforo del dia: "ok" (var(--verde-osc)) y "pasado" (var(--rojo))
       caen los dos a heredado = #161915. MEDIDO: un dia de 893 kcal y otro de
       1.423 kcal salen del MISMO negro. El semaforo tiene tres estados y dos
       dibujos, y los dos que se funden son los extremos.       [1.4.1 / 1.3.1]

     · La barra de objetivo en "pasado" (planificador.css:224): desaparece.

   Se arregla en un sitio. Los valores no son inventados: salen de sistema.css
   (--teal #145961, --linea #DCD2C4, --tinta #556354, --teal-hondo #073439),
   de componentes.css (--rojo #a82c2c, el mismo de .chip--rojo) y de
   nueva-06-detalle.css (--verde-osc = su --verde-tinta #2b5115).

   Va sobre `html, body` a proposito: planificador.css declara sobre `body`
   (0,0,1). Un :root (que es <html>) NO gana a una declaracion propia de <body>,
   la hereda y la pierde. Misma especificidad + esta hoja va despues = gana.
   ========================================================================== */

html,
body {
  --teal:      #145961;   /* rompe el ciclo de planificador.css:24 */
  --linea:     #DCD2C4;   /* rompe el ciclo de planificador.css:27 */
  --texto:     #556354;   /* = --tinta. 5,33:1 sobre crema, 7,04:1 sobre blanco */
  --teal-osc:  #073439;   /* = --teal-hondo. Blanco encima: 13,5:1 */
  --rojo:      #a82c2c;   /* 6,81:1 con blanco encima Y 6,81:1 como texto sobre blanco */
  --verde-osc: #2b5115;   /* 9,01:1 sobre blanco, 7,57:1 sobre crema */
}

/* El verde de marca es un distintivo, no una tinta: 2,05:1 sobre la crema.
   Donde planificador.css lo usa como RELLENO de un grafico que informa, el
   relleno pasa al verde oscuro. La barra sigue siendo verde a la vista, pero
   la que dice algo se lee.                                          [1.4.11] */
.progreso__barra { background: var(--verde-osc); }   /* 5,90:1 sobre la pista nueva */
/* La pista tambien tenia que separarse del papel: #ece6dc sobre #fff = 1,15:1.
   Un grafico cuyo fondo no se distingue del papel no comunica su escala.
   #d9d0c2 sobre #fff = 1,47:1 de canto, y con el filete interior el borde de
   la pista se ve siempre. */
.progreso,
.macro__pista { background: #d9d0c2; box-shadow: inset 0 0 0 1px rgba(85, 99, 84, .22); }
/* Las tres barras de macro son categoricas y llevan su cifra en gramos al lado
   (planificador.js:376), asi que el color no es el unico portador. Lo que si
   hacia falta es que el EXTREMO de la barra se vea sea cual sea el tono: el
   verde de marca sobre la pista da 1,58:1 y el ambar 2,50:1. Un filete oscuro
   sobre el propio relleno resuelve las tres de una vez.             [1.4.11] */
.macro__relleno { box-shadow: inset 0 0 0 1px rgba(22, 25, 21, .38); }


/* =============================================================================
   2 · EL ANILLO DE FOCO
   -----------------------------------------------------------------------------
   planificador.css:558 pone, para los 79 puntos de tabulacion de la vista
   semanal (120 en la mensual):

       :focus-visible { outline: 3px solid var(--verde); outline-offset: 2px;
                        border-radius: 4px; }

   MEDIDO tabulando de verdad (no con .focus(), que no dispara :focus-visible):
   el anillo sale rgb(116,183,78) en los 14 primeros saltos. Ese verde da
   2,05:1 sobre la crema y 2,43:1 sobre el papel blanco. El criterio 1.4.11
   pide 3:1 para un indicador de foco. NO PASA en ningun sitio de la pagina.
   Es el fallo que mas veces se comete: una vez por cada tecla Tab.

   Se conserva el verde —es suyo— de halo exterior, y el anillo que hace el
   trabajo pasa a teal hondo (11,2:1 sobre crema). Es exactamente lo que ya
   decidio nueva-06-detalle.css:48 para la landing; aqui solo se porta, para
   que las dos paginas se enfoquen igual.

   Esa regla ademas mete un `border-radius: 4px` que cuadra el hueco del
   calendario mientras esta enfocado. Se le devuelve el suyo abajo, uno a uno:
   un `border-radius: unset` global cuadraria TODAS las pildoras, que es peor.
                                                            [1.4.11 / 2.4.13]
   ========================================================================== */

:focus-visible {
  outline: 2px solid var(--teal-osc);
  outline-offset: 3px;
  box-shadow: 0 0 0 6px rgba(116, 183, 78, .45);
}
.hueco:focus-visible  { border-radius: 8px; }
.plato:focus-visible  { border-radius: 14px; }
.opcion:focus-visible { border-radius: 10px; }
.btn:focus-visible    { border-radius: 999px; }
/* Sobre fondo oscuro (brindis, pie) el teal desaparece: se invierte. */
.pie :focus-visible,
.brindis :focus-visible {
  outline-color: var(--crema, #EFEBE1);
  box-shadow: 0 0 0 6px rgba(116, 183, 78, .7);
}
/* La fila de la carta y el hueco del calendario llegan a sus bordes: el anillo
   se dibuja por dentro para que no lo recorte el contenedor con overflow. */
.elegir__lista .opcion:focus-visible { outline-offset: -3px; box-shadow: none; }
.hueco:focus-visible { outline-offset: -2px; }

/* El plato ELEGIDO se marca con `box-shadow: 0 0 0 3px var(--verde)`
   (planificador.css:504): 2,43:1 sobre el papel. Es un estado, no un adorno.
   [1.4.11] */
.plato.elegido {
  box-shadow: 0 0 0 3px var(--verde-osc),
              var(--sombra-encima, 0 16px 32px rgba(7, 52, 57, .1)) !important;
}


/* =============================================================================
   3 · "CONFIRMAR PLAN": EL BOTON QUE COBRA, ILEGIBLE
   -----------------------------------------------------------------------------
   #confirmar es .btn.btn--verde. componentes.css:82 rellena el disco con
   --verde #74B74E y :80 vira el rotulo a crema #EFEBE1 al pasar por encima o
   al enfocarlo: 2,05:1.

   Y componentes.css:191-196, bajo prefers-reduced-motion, deja ese estado
   PUESTO PARA SIEMPRE con !important:
       .btn__circulo { width: 100% !important }
       .btn__texto   { color: var(--crema) !important }

   MEDIDO con reducedMotion:'reduce' y el plan lleno: disco 286 px de los
   294 px del boton, fondo rgb(116,183,78), rotulo rgb(239,235,225). El boton
   principal de conversion es ilegible, de forma permanente, justo para el
   usuario que ha pedido menos movimiento.

   nueva-06-detalle.css:200 ya resolvio esto en la landing con --verde-tinta.
   Aqui se porta el mismo remedio.                                    [1.4.3] */

.btn--verde .btn__circulo { background: var(--verde-osc); }              /* 9,01:1 */
.btn--verde:hover:not(:disabled) .btn__circulo { background: #22400f; }  /* 11,4:1 */
/* El !important de componentes.css solo se puede responder con !important. */
@media (prefers-reduced-motion: reduce) {
  .btn--verde .btn__circulo { background: var(--verde-osc) !important; }
}
.boton--cta { background: var(--verde-osc); border-color: var(--verde-osc); }


/* =============================================================================
   4 · TAMANO DE LA DIANA
   -----------------------------------------------------------------------------
   MEDIDO a 390 px con el plan montado: .ficha__quitar mide 18x18 px. El
   criterio 2.5.8 (AA en WCAG 2.2) pide 24x24 CSS px, y esta es la unica forma
   de sacar un plato de un dia con el dedo.

   No se agranda la cruz: se agranda la CAJA que acepta el toque, que es lo que
   el criterio mide. A la vista queda igual.                          [2.5.8] */

.ficha__quitar {
  width: 24px;
  height: 24px;
  top: 0;
  right: 0;
  display: grid;
  place-items: center;
  font-size: 15px;
}
/* El aviso de alergeno vivia en right:20px y ahora chocaria con esa caja. */
.ficha__alerta { right: 27px; }
/* La cruz esta posicionada ENCIMA del nombre del plato: ya antes se comia la
   ultima letra ("Judias Verdes✕Rehogadas") y con 24 px se come mas. Se le
   reserva el sitio en la primera linea en vez de dejarla pisar el texto.
   Un nombre a medio leer bajo un boton tambien es un fallo de contraste. */
.ficha__nombre { padding-right: 24px; }
.ficha[data-alergeno] .ficha__nombre { padding-right: 46px; }   /* cruz + aviso */
/* La cruz de cerrar del dialogo: 27x27 medidos, justo por debajo. */
.elegir__cerrar { min-width: 28px; min-height: 28px; display: grid; place-items: center; padding: 0; }


/* =============================================================================
   5 · EL SEMAFORO DEL DIA NO PUEDE SER SOLO COLOR
   -----------------------------------------------------------------------------
   Con los tokens del bloque 1 arreglados, los tres estados vuelven a tener tres
   colores distintos y los tres pasan AA sobre el fondo del dia:

       corto   #b4762a   4,58:1      pasado  #a82c2c   5,72:1
       ok      #2b5115   7,57:1

   Pero el criterio 1.4.1 no admite el color como UNICO portador: quien no
   distingue rojo de verde ve tres cifras iguales. Se le anade una flecha.
   El texto equivalente para el lector de pantalla lo pone cfg-08-a11y.js con
   aria-label, que es donde no molesta.                                [1.4.1] */

.dia__kcal[data-estado="corto"]::after  { content: " \2193"; font-size: .9em; }  /* ↓ */
.dia__kcal[data-estado="pasado"]::after { content: " \2191"; font-size: .9em; }  /* ↑ */
.dia__kcal[data-estado="ok"]::after     { content: " \2713"; font-size: .9em; }  /* ✓ */

/* Lo mismo en la carta: "Contiene X" en rojo es la unica marca de choque.
   El borde rojo de la tarjeta tampoco vale solo. Se refuerza con un simbolo
   que ya esta en el texto, y con un canto de 4 px que no depende del tono. */
.plato[data-alergeno="si"] { box-shadow: inset 4px 0 0 0 var(--rojo), 0 0 0 2px rgba(168, 44, 44, .18); }
.plato__alerg--choca::before { content: "\26A0\FE0E "; }   /* ⚠ sin emoji */


/* =============================================================================
   6 · SALTAR LA CARTA
   -----------------------------------------------------------------------------
   MEDIDO: 79 puntos de tabulacion en el plan semanal y 120 en el mensual. Solo
   la carta de abajo son 31 paradas seguidas, y estan DESPUES de todo lo que
   sirve para cerrar la compra. Quien navega con teclado y quiere volver al
   panel tiene que atravesarlas enteras.

   El enlace lo inserta cfg-08-a11y.js (no se puede tocar el marcado); aqui va
   su tratamiento: fuera de la vista hasta que se enfoca.     [2.4.1 / 2.4.11]
   ========================================================================== */

/* :focus y NO :focus-visible a proposito. Un enlace de salto tiene que
   aparecer con cualquier foco, tambien el que llega por programa: MEDIDO, con
   :focus-visible se quedaba en top:-69px al enfocarlo desde el codigo, que es
   como llegan algunas extensiones y algunos lectores de pantalla. */
.cfg-saltar {
  position: fixed;
  left: 12px;
  top: 12px;
  z-index: 100;
  padding: 10px 18px;
  border-radius: 999px;
  background: var(--teal-osc);
  color: #fff;                          /* 13,5:1 sobre el teal hondo */
  font-weight: 600;
  text-decoration: none;
  transform: translateY(-200%);
  transition: transform .18s ease;
}
.cfg-saltar:focus { transform: translateY(0); }

/* Texto solo para el lector de pantalla. clip-path ademas de clip: el clip
   antiguo no lo respetan ya todos los motores. */
.cfg-vh {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}


/* =============================================================================
   7 · EL DIALOGO DE ELEGIR PLATO
   -----------------------------------------------------------------------------
   MEDIDO: 42 paradas de tabulacion dentro del dialogo (31 platos + 9 filtros +
   buscador + cerrar). Y la lista se declara role="listbox" con hijos
   role="option" que ademas son <button> tabulables y no llevan aria-selected:
   ni es un listbox ni se comporta como uno. Eso lo corrige el JS quitando los
   roles; aqui se arregla lo visual.

   El contador de resultados que anade el JS necesita sitio y contraste.
   ========================================================================== */

.cfg-resultados {
  padding: 0 22px 8px;
  margin: 0;
  font-size: .82rem;
  color: var(--texto);
  font-variant-numeric: tabular-nums;
}

/* La fila de alergeno en la lista: #fdf5f5 sobre #fff da 1,04:1. Como unica
   marca de "este plato lleva lo que evitas" no existe. Se le pone canto. */
.opcion[data-alergeno="si"] { box-shadow: inset 3px 0 0 0 var(--rojo); }

/* Al filtrar, la lista se vacia y el aviso aparece: que se lea. */
.elegir__vacio { font-weight: 600; color: var(--titulo); }


/* =============================================================================
   8 · EL CIERRE DE LA VENTA
   -----------------------------------------------------------------------------
   MEDIDO: se envia con el telefono "123", sale el texto correcto —"Ese telefono
   no parece espanol..."— pero:
       role=null   aria-live=null   foco tras el error: #cierreEnviar
       #cierreTelefono: aria-invalid=null, aria-describedby=null
   Es decir: el error se pinta y no lo anuncia nadie, el foco se queda en el
   boton, y el campo culpable no esta marcado. Con lector de pantalla el envio
   simplemente "no hace nada".                              [3.3.1 / 4.1.3]

   El JS pone role="alert", aria-invalid, aria-describedby y lleva el foco al
   campo. Aqui va la marca visible del campo en falta: 3.3.1 tampoco se cumple
   senalando solo con color.
   ========================================================================== */

.campo input[aria-invalid="true"] {
  border-color: var(--rojo);
  border-width: 2px;
  background: #fdf5f5;
}
.campo:has(input[aria-invalid="true"]) > span::after {
  content: " — revisalo";
  color: var(--rojo);
  font-weight: 700;
}


/* =============================================================================
   9 · SIN MOVIMIENTO
   -----------------------------------------------------------------------------
   planificador.css:554 apaga transiciones y animaciones con `* { ... }`, pero
   no toca las TRANSFORMACIONES, que no son animaciones: el brindis nace en
   translateY(120%) y aparece de golpe fuera de la pantalla, y el catalogo usa
   `scale: 1.05` y `translateY(-4px)` en hover, que sin transicion dan un salto
   seco. Sin movimiento significa sin salto, no "el mismo salto mas rapido".
                                                                     [2.3.3] */

@media (prefers-reduced-motion: reduce) {
  .plato:hover,
  .plato:focus-visible { transform: none; }
  .plato:hover .plato__foto { scale: 1; }
  .plan:hover { transform: none; }
  .btn-simple:hover { transform: none; }
  .cfg-saltar { transition: none; }
  /* El brindis deja de deslizarse: aparece y desaparece donde esta.

     Basta con quitarle la transicion. Quien lo esconde ya es la opacidad
     (planificador.css:642), asi que aqui no hay que repetir nada de eso — y
     sobre todo NO hay que reescribir su `transform`: decia
     `translateX(-50%)`, que es el centrado del ESCRITORIO, y en el movil el
     aviso va de lado a lado sin centrar (cfg-03-movil.css:496). Como esta
     hoja carga la ultima, en un movil con el movimiento reducido el aviso se
     iba media pantalla a la izquierda. */
  .brindis, .brindis.visible { transition: none; }
}


/* =============================================================================
   10 · CONTRASTE DE LOS AMBARES Y LOS ROJOS QUE SI ESTABAN CODIFICADOS
   -----------------------------------------------------------------------------
   Estos si pasaban y se dejan como estan, anotados para que nadie los "mejore":
       .aviso--alerta     #8a2b2b sobre #fdf1f1 ....... 7,60:1  OK
       .aviso--pendiente  #8a5a12 sobre #fbf3e2 ....... 5,35:1  OK
       --duda             #8a6d1f sobre #fff .......... 4,95:1  OK
       .etiqueta--nuevo   #8a6d1f sobre #fdf6e3 ....... 4,58:1  OK (justo)

   El unico que no llega es el ambar del semaforo sobre el fondo del dia:
       --amarillo #b4762a sobre --fondo #EFEBE1 ....... 4,58:1  OK a 0,74rem?
   4,58:1 pasa AA como texto normal. Se deja.

   Lo que SI se corrige: .plan__dto es un distintivo con texto blanco sobre
   --verde #74B74E = 2,05:1, y ahi el texto es el numero del descuento, o sea
   el argumento comercial entero.                                     [1.4.3] */

.plan__dto { background: var(--verde-osc); }
.etiqueta--vacia { color: var(--texto); }


/* =============================================================================
   11 · REFLUJO Y MOVIL
   -----------------------------------------------------------------------------
   MEDIDO a 390 y a 320 px: scrollWidth == viewport, cero desbordes. Eso ya
   estaba bien y no se toca.

   Lo que no esta bien es que a 390 px la pagina mide 17.495 px de alto y el
   panel que lleva el precio y el boton de comprar queda enterrado en el medio.
   Eso es trabajo del agente de movil, no mio: aqui solo me aseguro de que la
   barra de navegacion oculta (planificador.css:550 `.barra__nav{display:none}`)
   no deje al teclado sin acceso a la navegacion. Como el enlace del logo sigue
   estando y lleva a la home, el criterio 2.4.5 (mas de un camino) se sostiene
   por el pie... que hasta el bloque 1 era invisible. Ahora se ve.
   ========================================================================== */

@media (max-width: 760px) {
  /* Objetivo, alergenos y filtros son tiras de pildoras: con el dedo hay que
     poder fallar. 2.5.8 pide 24 px; aqui se les da 34 de alto real. */
  .objetivo button,
  .alergenos button,
  .filtros button { min-height: 34px; }
}


/* =============================================================================
   12 · MODO DE CONTRASTE FORZADO (Windows)
   -----------------------------------------------------------------------------
   En modo contraste forzado el sistema repinta colores y fondos, pero NO las
   sombras: todo lo que aqui se marca con box-shadow (plato elegido, canto de
   alergeno, foco de la fila) se evapora. Se le da un borde de verdad, que el
   modo si respeta.                                                  [1.4.11] */

@media (forced-colors: active) {
  .plato.elegido { outline: 3px solid Highlight; outline-offset: -3px; }
  .plato[data-alergeno="si"],
  .opcion[data-alergeno="si"] { border-left: 4px solid LinkText; }
  :focus-visible { outline: 3px solid Highlight; box-shadow: none; }
  .progreso__barra,
  .macro__relleno { background: Highlight !important; forced-color-adjust: none; }
  .hueco { border: 1.5px dashed CanvasText; }
}
