/* ==========================================================================
   IMDH — Selector flotante de contacto por WhatsApp
   ==========================================================================
   Hoja de estilos del widget flotante (`src/components/WhatsAppFloating.astro`).

   Vive en `public/` a propósito: Astro empaqueta toda hoja importada desde
   `src/` en el bundle compartido de todas las páginas, y esta pieza NO debe
   pesar en el build por defecto —donde el widget no existe—. Como archivo
   estático, solo se enlaza cuando la capa de contacto expone alguna línea
   (`<link rel="stylesheet" href="/styles/whatsapp-widget.css">`, condicionado
   en `BaseLayout.astro`). En el build por defecto no se emite markup, ni
   script, ni esta hoja enlazada.

   Dos movimientos y ninguno decorativo: la retirada cuando el botón taparía un
   control, y la escala de pulsación. Los dos viajan por transición, así que
   `reset.css` los deja en 0,01 ms bajo `prefers-reduced-motion` —el estado
   final se aplica igual, solo desaparece el tránsito—. Respeta los márgenes
   seguros del dispositivo.
   ========================================================================== */

.wa-float {
  position: fixed;
  right: max(var(--space-sm), env(safe-area-inset-right, 0px));
  bottom: max(var(--space-sm), env(safe-area-inset-bottom, 0px));
  z-index: var(--z-overlay);
  /* La única animación del widget: la retirada descrita más abajo necesita un
     tránsito para no parpadear durante el desplazamiento. Bajo
     `prefers-reduced-motion` la duración la anula `reset.css`.
     La escala de pulsación viaja en el mismo tránsito: es una
     microconfirmación de 120 ms, del mismo orden que ya tenía el widget, y no
     añade una segunda animación que haya que gobernar aparte. */
  transition: opacity 120ms ease-out;
}

/* El botón se aparta cuando taparía un control.
   Medido en `/productos` a 390×844: el disparador (x 320–374, y 774–828)
   cubría el 31 % del tercer botón del filtro de modalidad (x 255–372, y
   797–841), y un toque dirigido a «Venta (7)» abría WhatsApp: una acción
   equivocada, no una acción lenta. Lo mismo sobre el borde derecho de los
   campos de `/contacto` y `/cotizar`, donde el disco se posa encima del propio
   campo que se está rellenando. La clase la pone el script del componente
   cuando hay un control bajo el botón; sin script, el botón no se retira nunca
   y el comportamiento es el de antes. */
.wa-float--blocked {
  opacity: 0;
  pointer-events: none;
  /* `visibility: hidden` además de la opacidad. Medido: con el botón retirado
     seguía teniendo `tabindex=0`, no estaba `disabled` y no había `inert` en
     ningún ancestro, así que aceptaba el foco —`document.activeElement` era
     `#wa-trigger` con la cadena de opacidades 1 → 0 → 1—: el teclado podía
     aterrizar en un botón 100 % transparente, sin indicador visible, y un
     lector anunciaba un control que nadie ve. `visibility` lo saca del orden de
     tabulación y del árbol de accesibilidad sin tocar el tamaño ni la posición,
     así que no hay salto de composición al retirarlo y volverlo a poner. */
  visibility: hidden;
}

/* Sin JavaScript el widget no existe de verdad: el panel lo abre un script.
   Medido: el disparador se dibujaba con su `aria-label` y no respondía —un
   control anunciado y muerto—. Se retira entero, como ya se hace con el botón
   del panel de navegación. La hoja solo se enlaza cuando hay canales, así que
   esta regla tampoco existe en el build sin canales. */
html.no-js .wa-float {
  display: none;
}

/* El carril del widget no se solapa con la línea inferior del pie. */
body:has(.wa-float) .v1-footer-bottom-inner {
  padding-inline-end: 78px;
}

.wa-trigger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 54px;
  height: 54px;
  padding: 0;
  border: none;
  border-radius: var(--radius-full);
  background-color: var(--color-primary-dark);
  color: #fff;
  cursor: pointer;
  /* Al filete de sombra se le suma un anillo blanco de 2 px. El botón es fijo,
     así que cae sobre fondos que no elige: en las fichas de producto se apoya
     en `.v1-visual-stage`, que es `--color-primary` (#0089DD), y el suyo
     `--color-primary-dark` (#0072B8) mide ahí 1,37:1 —por debajo del 3:1 que
     1.4.11 pide para identificar un componente—. El anillo lo separa en
     cualquier superficie y sobre blanco no se ve, porque es blanco. */
  box-shadow: var(--shadow-md), 0 0 0 2px #fff;
  transition: background-color var(--transition-fast), transform 120ms ease-out;
}

/* Pulsación: la señal al dedo va sobre el propio disparador, no sobre el
   contenedor: si fuera en el contenedor, pulsar cualquier elemento del panel
   abierto —el botón de cierre, un enlace— escalaría la hoja entera. */
.wa-trigger:active {
  transform: scale(0.94);
}

/* En un dispositivo táctil `:hover` se queda pegado tras el toque: el botón
   se veía pulsado hasta que se tocaba otra cosa. Las reglas de hover del widget
   viven solo donde hay puntero. */
@media (hover: hover) {
  .wa-trigger:hover {
    background-color: var(--color-primary-deep);
  }

  .wa-option-link:hover {
    color: var(--color-primary-dark);
    text-decoration: underline;
  }
}

/* Anillo doble: legible sobre CUALQUIER fondo, no solo sobre el botón azul y
   el blanco del pie.
   El botón es fijo y, al desplazarse, cae sobre las fotografías de producto de
   las fichas, que pueden ser oscuras: un anillo de un solo color depende de
   esos píxeles y no se puede garantizar. Con tinta por fuera y un halo blanco
   por dentro, para cualquier luminancia de fondo L se cumple al menos una de
   las dos: la tinta da 3:1 o más cuando L ≥ 0,126 y el blanco cuando L ≤ 0,30,
   de modo que todo fondo posible queda cubierto por al menos uno de los dos
   —y los intermedios, por ambos—. Medido: anillo de tinta sobre el azul de
   marca 4,78:1 y sobre blanco 17,85:1. */
.wa-trigger:focus-visible {
  outline: 2px solid var(--color-ink);
  outline-offset: 3px;
  /* El halo se SUMA al filete de sombra del botón, no lo sustituye: `box-shadow`
     es una sola propiedad y una declaración sin `var(--shadow-md)` dejaba al
     botón sin elevación mientras tuviera el foco. El halo tapa exactamente el
     hueco de 3 px que abre `outline-offset` —el anillo blanco de reposo mide 2—
     y así el foco se lee como un filete continuo de dos tonos. */
  box-shadow: var(--shadow-md), 0 0 0 3px #fff;
}

.wa-panel {
  position: absolute;
  right: 0;
  bottom: calc(100% + 10px);
  width: min(340px, calc(100vw - 2 * var(--space-sm)));
  /* El panel se ancla por encima del disparador y crece hacia arriba. Medido en
     un teléfono en horizontal (844×390): medía 465,2 px de alto con su borde
     superior en −157,3 —el título y LAS DOS líneas marcables quedaban fuera de
     la pantalla, sin nada que desplazar y sin control de cierre, porque el
     tratamiento de hoja solo existía por debajo de 560 px de ancho—. Con el
     tope de alto y el desplazamiento propio, el panel no puede exceder nunca la
     ventana: lo que no cabe se desliza. La hoja de teléfono (más abajo)
     sustituye esto por su propio alto. */
  max-height: calc(100vh - 88px);
  max-height: calc(100dvh - 88px);
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: var(--space-sm);
  background-color: var(--color-surface);
  border: 1px solid var(--color-line);
  border-top: 3px solid var(--color-primary);
  box-shadow: var(--shadow-md);
}

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

/* El control de cierre solo se muestra en la hoja inferior (móvil); en
   escritorio el disparador sigue visible y hace de cierre. */
.wa-panel-close {
  display: none;
}

.wa-panel-title {
  margin: 0 0 var(--space-2xs);
  font-family: var(--font-display);
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-bold);
  color: var(--color-ink);
}

.wa-options {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin: 0 0 var(--space-2xs);
  padding: 0;
  list-style: none;
}

.wa-option {
  display: flex;
  flex-direction: column;
  gap: 2px;
  border-top: 1px solid var(--color-line);
  padding-block: 8px;
}

.wa-option:first-child {
  border-top: none;
}

.wa-option-link {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-size: var(--font-size-sm);
  font-weight: var(--font-weight-semibold);
  color: var(--color-ink);
  text-decoration: none;
}

.wa-option-pending {
  padding-left: 28px;
  /* Suelo tipográfico: 12 px, no los 11 fijos que declaraba. El marcador se ve
     en la hoja inferior del teléfono, donde un cuerpo por debajo de 12 px deja
     de leerse con comodidad —y es un dato, no una decoración—. */
  font-size: var(--font-size-xs);
  color: var(--color-muted);
}

.wa-panel-note {
  margin: 0;
  padding-top: var(--space-2xs);
  border-top: 1px solid var(--color-line);
  font-size: var(--font-size-xs);
  color: var(--color-muted);
  line-height: var(--line-height-normal);
}

/* ---- QR por línea ---------------------------------------------------------
   Activo estático negro sobre blanco opaco, generado una sola vez y verificado
   por decodificación. 132 px de lado: con 25 módulos por lado son ~5 px por
   módulo, lectura cómoda a la distancia de un teléfono. Se envuelve solo: en
   pantallas estrechas los dos códigos se apilan, nunca se reducen de tamaño. */
.wa-qr-block {
  margin-top: var(--space-2xs);
  padding-top: var(--space-2xs);
  border-top: 1px solid var(--color-line);
}

.wa-qr-title {
  margin: 0 0 var(--space-2xs);
  font-family: var(--font-display);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-bold);
  color: var(--color-ink);
}

.wa-qr-list {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-2xs);
  margin: 0;
  padding: 0;
  list-style: none;
}

.wa-qr {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  margin: 0;
}

.wa-qr picture {
  display: block;
  background-color: #fff;
}

.wa-qr img {
  display: block;
  width: 132px;
  height: 132px;
  background-color: #fff;
}

.wa-qr-caption {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--color-body);
  font-variant-numeric: tabular-nums;
}

.wa-qr-note {
  margin: var(--space-2xs) 0 0;
  /* Mismo suelo que el resto de metadatos: 12 px, no 11. */
  font-size: var(--font-size-xs);
  color: var(--color-muted);
  line-height: var(--line-height-normal);
  text-align: center;
}

/* Teléfono: en vertical por ancho (≤560) y en horizontal por ALTO más puntero.
   Medido en horizontal a 844×390: la tarjeta anclada al disparador medía 465,2
   px de alto con su borde superior en −157,3 —el título y las dos líneas
   marcables fuera de la pantalla, sin nada que desplazar y sin control de
   cierre, porque el tratamiento de hoja solo existía por ancho—.
   La condición de alto se apoya en `pointer: coarse` y no en un ancho máximo:
   los teléfonos grandes en horizontal miden 915 (Pixel 7/8) y 932 (iPhone Pro
   Max), y con un tope de 900 quedaban fuera —medido: en 932×430 el panel se
   dibujaba entero dentro de la ventana pero 305 de sus 342 px quedaban tapados
   por la cabecera opaca, con el título y las dos líneas inalcanzables—. Un
   ratón en una ventana baja sigue viendo la tarjeta, que es para lo que estaba
   el tope de ancho. */
@media (max-width: 560px), (max-height: 500px) and (pointer: coarse) {
  /* En un teléfono el panel deja de ser una tarjeta anclada al disparador y
     pasa a ser una hoja inferior a ancho completo: patrón de la plataforma,
     objetivos táctiles grandes y control de cierre propio, porque la hoja
     cubre el disparador. El QR se oculta: un QR en la pantalla del propio
     dispositivo no se puede escanear con ese dispositivo. */
  .wa-panel {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    width: auto;
    /* `vh` en un teléfono mide el viewport con la barra retraída: la hoja podía
       declararse más alta que el hueco real y dejar su último renglón —la nota
       que explica que usted decide si envía el mensaje— fuera de alcance.
       `dvh` sigue al viewport visible; la línea anterior queda de respaldo. */
    max-height: calc(100vh - 88px);
    max-height: calc(100dvh - 88px);
    overflow-y: auto;
    /* El desplazamiento de la hoja no se encadena al del documento. */
    overscroll-behavior: contain;
    border-left: none;
    border-right: none;
    padding: 14px 16px calc(14px + env(safe-area-inset-bottom, 0px));
    box-shadow: 0 -10px 30px -12px rgba(15, 23, 42, 0.3);
  }
  /* Cuando la hoja inferior está abierta en móvil, cubre por completo el
     disparador. Para no dejar el foco en un control 100 % oculto (WCAG 2.4.11
     Foco no oscurecido, AA), se oculta con `visibility: hidden` mientras la
     hoja está abierta, sacándolo del orden de tabulación y del árbol accesible.
     Al cerrar, el script retira la clase antes de llamar a `trigger.focus()`. */
  .wa-float--open .wa-trigger {
    visibility: hidden;
  }


  .wa-panel-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
  }

  .wa-panel-close {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    margin: -6px -6px 0 0;
    border: 1px solid var(--color-line-strong);
    background-color: var(--color-surface);
    color: var(--color-ink);
    cursor: pointer;
  }

  .wa-option {
    border-top: 1px solid var(--color-line);
    padding-block: 6px;
  }

  /* Objetivo táctil ≥ 44 px por línea. */
  .wa-option-link {
    min-height: 48px;
    padding-block: 8px;
  }

  .wa-qr-block {
    display: none;
  }

  /* La hoja cubre el pie del documento mientras está abierta: se reserva, al
     final de la línea inferior del pie, el alto real de la hoja (lo publica el
     script en `--wa-sheet-h`), de modo que la línea de copyright y la de
     localidad quedan por encima de la hoja y siguen visibles. La reserva
     desaparece al cerrar: solo existe con `hidden` retirado. */
  body:has(.wa-panel:not([hidden])) .v1-footer-bottom-inner {
    padding-bottom: var(--wa-sheet-h, 264px);
  }
}
