/* ---------- Fuentes ---------- */
@font-face { font-family: 'Outfit'; src: url('../fonts/outfit.woff2') format('woff2');
             font-weight: 600 700; font-display: swap; }
@font-face { font-family: 'Inter Tight'; src: url('../fonts/inter-tight.woff2') format('woff2');
             font-weight: 400 500; font-display: swap; }

/* ---------- Tokens ---------- */
:root {
  --azul: #3B4CA8;
  --azul-oscuro: #2F3E8C;
  --celeste: #1A74B0;
  --tinta: #1F2937;
  --gris: #5B677D;
  --superficie: #F5F5F5;
  --blanco: #FFFFFF;

  --radio: 16px;
  --sombra: 0 2px 8px rgba(59, 76, 168, 0.08);
  --sombra-alta: 0 12px 28px rgba(59, 76, 168, 0.16);
  --contenedor: 1200px;

  --fuente-titulo: 'Outfit', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --fuente-cuerpo: 'Inter Tight', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --header-alto: 72px;
}

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
body, h1, h2, h3, p, figure, ul { margin: 0; padding: 0; }
ul { list-style: none; }
img { display: block; max-width: 100%; height: auto; }

html { scroll-behavior: smooth; scroll-padding-top: var(--header-alto); }

body {
  font-family: var(--fuente-cuerpo);
  color: var(--tinta);
  background: var(--blanco);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 { font-family: var(--fuente-titulo); font-weight: 700; line-height: 1.15; }
h1 { font-size: clamp(2.25rem, 5vw, 3.5rem); }
h2 { font-size: clamp(1.75rem, 3vw, 2.5rem); }
h3 { font-size: 1.125rem; font-weight: 600; }

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

.contenedor { width: min(100% - 2.5rem, var(--contenedor)); margin-inline: auto; }

.visualmente-oculto {
  position: absolute; width: 1px; height: 1px; margin: -1px;
  padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ---------- Botones ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: .5rem; white-space: nowrap;
  padding: .75rem 1.5rem;
  border: 2px solid transparent; border-radius: var(--radio);
  font-family: var(--fuente-cuerpo); font-size: 1rem; font-weight: 500;
  text-decoration: none; cursor: pointer;
  transition: background-color .2s ease, transform .1s ease, border-color .2s ease;
}
.btn--celeste { background: var(--celeste); color: var(--blanco); }
.btn--celeste:hover { background: var(--azul); }
.btn--linea { background: transparent; color: var(--celeste); border-color: var(--celeste); }
.btn--linea:hover { background: var(--celeste); color: var(--blanco); }
.btn:active { transform: scale(.98); }
/* Tercera aparicion del mismo bug de cascada de origen ya documentado para
   .campo[hidden] (mas abajo) y para .panel-carrito (Task 4, resuelto ahi con
   "inert" en vez de "hidden"): "display: inline-flex" de arriba es CSS de
   autor y le gana por ORIGEN -no por especificidad- a "[hidden] { display:
   none }" de la hoja del navegador, asi que ningun boton con clase .btn
   queda oculto por el solo atributo hidden. #btn-carrito nace con hidden
   (Task 3) para no mostrar un control que no responde mientras tienda.js no
   arranca, pero sin esta regla se veia con "display: flex" -un rectangulo de
   82x40- durante toda la carga, y de forma PERMANENTE si el JavaScript falla
   o esta deshabilitado, con un contador en cero que no hace nada al
   tocarlo. Se agrega esta regla mas especifica (dos clases de especificidad
   contra una) para que [hidden] vuelva a ocultar de verdad. */
.btn[hidden] { display: none; }

/* ---------- Header ---------- */
.header {
  position: sticky; top: 0; z-index: 50;
  background: var(--azul);
}
.header__inner {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1.5rem; min-height: var(--header-alto);
}
/* flex-shrink: 0 evita que .header__marca se aplaste dentro del flex row de
   .header__inner: sin esto, un <img> flex-item con solo "height" fijo (sin
   "width" ni "flex-basis" explicitos) puede encogerse hasta casi 0px de
   ancho cuando el resto del header (.nav, que ahora suma 2 items mas que
   antes de esta rama: "Tienda" y el boton del carrito) no entra en el
   espacio disponible. Regresion medida entre 768 y ~850px: el logo llegaba
   a 0px de ancho -no se veia-. */
.header__marca { flex-shrink: 0; }
.header__marca img { height: 40px; width: auto; object-fit: contain; }

.nav { display: flex; align-items: center; gap: 1.75rem; }
.nav__link {
  position: relative;
  color: var(--blanco); text-decoration: none;
  font-size: .9375rem; font-weight: 500; letter-spacing: .02em;
  padding: .25rem 0;
  /* Sin esto, un link de dos palabras ("Sobre nosotros") se partia en dos
     lineas apenas el nav quedaba corto de espacio (mismo tramo 768-850 de
     la regresion de arriba), desprolijo y con el header mas alto de lo que
     el resto del diseño espera. */
  white-space: nowrap;
}
.nav__link::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: -2px;
  height: 2px; background: var(--blanco);
  transform: scaleX(0); transform-origin: left;
  transition: transform .2s ease;
}
.nav__link:hover::after, .nav__link.is-activo::after { transform: scaleX(1); }
.nav__redes { display: flex; align-items: center; gap: .5rem; }
.nav__red {
  display: inline-flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; flex: 0 0 38px;
  color: var(--blanco); background: rgba(255,255,255,.08);
  border: 1px solid rgba(255,255,255,.38); border-radius: 50%;
  transition: color .2s ease, background-color .2s ease, transform .1s ease;
}
.nav__red svg { width: 19px; height: 19px; fill: currentColor; }
.nav__red:hover { color: var(--azul); background: var(--blanco); }
.nav__red:active { transform: scale(.94); }
.nav__carrito { position: relative; gap: .375rem; padding: .5rem .875rem; font-size: .9375rem; }
.nav__carrito__n {
  min-width: 1.5rem; padding: 0 .375rem;
  background: var(--celeste); color: var(--blanco);
  border-radius: 999px; font-size: .8125rem; font-weight: 600; line-height: 1.5;
}

/* Regresion medida entre 768 y ~875px (revision final de la rama): con el
   logo fijo (flex-shrink: 0, arriba) y los links sin partirse en dos
   lineas (white-space: nowrap, arriba), el nav -que ahora suma "Tienda" y
   el boton del carrito, dos items mas que antes de esta rama- ya no cabe
   en el ancho disponible con su gap de escritorio (1.75rem x 6 huecos) y
   el header desborda. Achicar el gap solo en este tramo angosto alcanza
   para que todo entre sin tocar el gap de escritorio habitual (1024px+,
   donde ya entraba justo). */
@media (min-width: 768px) and (max-width: 899px) {
  .nav { gap: .75rem; }
}

.header__toggle {
  display: none;
  flex-direction: column; gap: 5px; justify-content: center;
  width: 44px; height: 44px; padding: 10px;
  background: none; border: 0; cursor: pointer;
}
.header__toggle span {
  display: block; height: 2px; width: 100%;
  background: var(--blanco); border-radius: 2px;
  transition: transform .25s ease, opacity .2s ease;
}
.header__toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.header__toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.header__toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

@media (max-width: 767px) {
  :root { --header-alto: 64px; }
  .header__marca img { height: 34px; }
  .header__toggle { display: flex; }
  .nav {
    position: fixed; inset: var(--header-alto) 0 auto 0;
    flex-direction: column; align-items: stretch; gap: 0;
    background: var(--azul);
    padding: 1rem 1.25rem 2rem;
    border-top: 1px solid rgba(255,255,255,.15);
    transform: translateY(-120%);
    transition: transform .28s ease;
  }
  .nav.is-abierto { transform: translateY(0); }
  .nav__link { padding: .875rem 0; font-size: 1.0625rem; }
  .nav__link::after { display: none; }
  .nav__redes {
    margin-top: .75rem; padding-top: 1rem;
    border-top: 1px solid rgba(255,255,255,.15);
  }
}

/* ---------- Hero ---------- */
.hero {
  min-height: 88dvh; display: flex; align-items: flex-start;
  padding: 0 0 4rem; background: #F7F7F7;
}
.hero__inner {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: 3rem; align-items: center;
  width: 100%; margin-inline: 0;
  padding-left: max(1.25rem, calc((100vw - var(--contenedor)) / 2));
}
.hero__sub {
  margin-top: 1rem; margin-bottom: 2rem;
  font-size: clamp(1rem, 1.5vw, 1.25rem);
  color: var(--gris); text-transform: uppercase; letter-spacing: .08em;
}
.hero__figura { margin: 0; overflow: hidden; }
.hero__figura img {
  width: 104%; max-width: none; aspect-ratio: 1; object-fit: cover;
}

@media (min-width: 1240px) {
  .hero__inner {
    grid-template-columns: minmax(0, calc(var(--contenedor) / 2 - 1.5rem)) minmax(0, 1fr);
  }
}

@media (max-width: 900px) {
  .hero { min-height: auto; padding: 0 0 3rem; }
  .hero__inner { grid-template-columns: 1fr; gap: 2.5rem; padding-left: 1.25rem; }
  .hero__texto { padding-right: 1.25rem; }
  .hero__figura { order: -1; }
}

/* ---------- Franja de confianza ---------- */
.confianza { border-block: 1px solid rgba(59, 76, 168, .14); background: var(--superficie); }
.confianza__grid {
  display: grid; grid-template-columns: repeat(3, 1fr);
}
.confianza__item {
  display: flex; flex-direction: column; gap: .25rem;
  padding: 2rem 1.5rem; text-align: center;
  border-left: 1px solid rgba(59, 76, 168, .14);
}
.confianza__item:first-child { border-left: 0; }
.confianza__dato {
  font-family: var(--fuente-titulo); font-weight: 700;
  font-size: 1.5rem; color: var(--azul);
}
.confianza__texto { font-size: .9375rem; color: var(--gris); }

@media (max-width: 767px) {
  .confianza__grid { grid-template-columns: 1fr; }
  .confianza__item { border-left: 0; border-top: 1px solid rgba(59, 76, 168, .14); padding: 1.5rem 1rem; }
  .confianza__item:first-child { border-top: 0; }
}

/* ---------- Títulos de sección ---------- */
/* font-size explícito (antes heredaba el tamaño por defecto de h1/h2, arriba):
   tienda.html usa esta misma clase en su <h1> (tiene que ser h1 -único por
   página-, a diferencia del resto de los títulos de sección que son h2), y
   sin este valor propio se hereda clamp(2.25rem, 5vw, 3.5rem) de la regla
   "h1" en vez de clamp(1.75rem, 3vw, 2.5rem) de "h2": el título de la tienda
   quedaría visualmente más grande que el resto pese a ser el mismo diseño. */
.seccion__titulo { text-align: center; margin-bottom: 3rem; font-size: clamp(1.75rem, 3vw, 2.5rem); }

/* ---------- Productos ---------- */
.productos { padding: 5rem 0; }
.productos__grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.75rem; }

.producto {
  display: flex; flex-direction: column;
  background: var(--blanco);
  border: 1px solid rgba(59, 76, 168, .14); border-radius: var(--radio);
  padding: 1.25rem 1.25rem 1.5rem;
  box-shadow: var(--sombra);
  transition: transform .2s ease, box-shadow .2s ease;
}
.producto__foto {
  background: var(--superficie);
  border-radius: calc(var(--radio) - 4px);
  padding: 1rem; margin-bottom: 1.25rem;
}
.producto__foto img {
  width: 100%; aspect-ratio: 1; object-fit: contain;
}
.producto__nombre { margin-bottom: .5rem; }
.producto__desc { font-size: .9375rem; color: var(--gris); margin-bottom: 1.25rem; }
@media (min-width: 901px) {
  .producto:last-child:nth-child(3n + 1) { grid-column: 2; }
}
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .producto:hover { transform: translateY(-4px); box-shadow: var(--sombra-alta); }
}

@media (max-width: 900px) {
  .productos__grid { grid-template-columns: repeat(2, 1fr); }
  .producto:last-child:nth-child(odd) {
    grid-column: 1 / -1; width: calc((100% - 1.75rem) / 2); justify-self: center;
  }
}
@media (max-width: 600px) {
  .productos__grid { grid-template-columns: 1fr; }
  .producto:last-child:nth-child(odd) { grid-column: auto; width: 100%; }
}

/* ---------- ¿Por qué elegirnos? ---------- */
.elegirnos {
  display: grid; grid-template-columns: 1fr 1fr; gap: 3.5rem; align-items: center;
  padding: 5rem max(1.25rem, calc((100vw - var(--contenedor)) / 2)) 5rem 0;
  background: #F7F7F7;
}
.elegirnos__imagen {
  display: block; width: 112%; max-width: none; margin-left: -12%;
  aspect-ratio: 1; object-fit: cover; filter: brightness(1.02);
}
.elegirnos__intro { margin: 1rem 0 2rem; color: var(--gris); max-width: 60ch; }

.beneficios { display: grid; gap: 1.5rem; }
.beneficio { display: flex; gap: 1rem; align-items: flex-start; }
.beneficio__icono { flex: 0 0 28px; width: 28px; height: 28px; fill: var(--celeste); }
.beneficio h3 { margin-bottom: .125rem; }
.beneficio p { font-size: .9375rem; color: var(--gris); }

@media (min-width: 1240px) {
  .elegirnos {
    grid-template-columns: minmax(0, 1fr) minmax(0, calc(var(--contenedor) / 2 - 1.75rem));
  }
}

/* ---------- Sobre nosotros ---------- */
.nosotros { padding: 5rem 0; }
.nosotros__inner {
  display: grid; grid-template-columns: 1fr 1fr; gap: 3.5rem; align-items: center;
}
.nosotros__lead {
  margin: 1rem 0 1.25rem;
  font-size: 1.25rem; font-weight: 500; color: var(--tinta);
}
.nosotros__texto p:last-child { color: var(--gris); max-width: 62ch; }
.nosotros__figura {
  margin: 0; display: grid; place-items: center;
  aspect-ratio: 1; border-radius: 50%; background: var(--azul);
}
.nosotros__figura img {
  width: 62%; height: auto;
}

@media (max-width: 900px) {
  .elegirnos { grid-template-columns: 1fr; gap: 2.5rem; padding: 3rem 1.25rem 3rem 0; }
  .nosotros__inner { grid-template-columns: 1fr; gap: 2.5rem; }
  .elegirnos__texto { padding-left: 1.25rem; }
  /* .nosotros__figura necesita un ancho propio, no dependiente de su hijo: con
     margin-inline: auto el margen automático desactiva el stretch de grid y el
     contenedor pasa a medirse por su contenido (la <img> lazy, que no aporta
     tamaño intrínseco hasta decodificar) y queda en 0x0 hasta que la imagen carga. */
  .nosotros__figura { width: min(100%, 420px); justify-self: center; }
  .nosotros__figura { order: -1; }
}

/* ---------- Clientes ---------- */
.clientes { background: #36499F; padding: 3.5rem 0; overflow: hidden; }
.clientes__header {
  display: flex; flex-direction: column; align-items: center; gap: 1.25rem;
  margin-bottom: 2.5rem;
}
.clientes__titulo { color: var(--blanco); text-align: center; font-size: 1.5rem; }

/* El carrusel se detiene con hover o al recibir foco de teclado. */
.marquee { display: flex; width: max-content; }
.marquee__pista {
  display: flex; align-items: center; gap: 4rem;
  padding-right: 4rem; flex-shrink: 0;
}
/* Los archivos ya traen el azul de la banda horneado como fondo (ver Task 6,
   ronda de corrección 1): sin opacity, ese fondo queda idéntico al de la banda. */
.marquee__pista img { width: 120px; height: auto; }
.marquee__pista .cliente-logo--ypf { filter: brightness(1.14) saturate(.85); }

@media (prefers-reduced-motion: no-preference) {
  .marquee__pista { animation: marquee 40s linear infinite; }
  .marquee:hover .marquee__pista,
  .marquee:focus-within .marquee__pista { animation-play-state: paused; }
}
@keyframes marquee { to { transform: translateX(-100%); } }

/* ---------- Footer ---------- */
.footer { background: var(--azul); color: var(--blanco); padding: 3rem 0 1.5rem; }
.footer__inner {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 2rem;
}
/* El isotipo del bloque "Sobre nosotros" se reutiliza en header y footer: se fija
   la altura y se deja el ancho automático para no deformarlo. */
.footer__marca img { height: 48px; width: auto; }
.footer__nav { display: flex; flex-wrap: wrap; gap: 1.5rem; }
.footer__nav a {
  color: var(--blanco); text-decoration: none;
  font-size: .9375rem; opacity: .9;
}
.footer__nav a:hover { opacity: 1; text-decoration: underline; }
.footer__redes a { color: var(--blanco); display: inline-flex; }
.footer__redes svg { fill: currentColor; }
.footer__copy {
  margin-top: 2.5rem; padding-top: 1.5rem;
  border-top: 1px solid rgba(255,255,255,.18);
  text-align: center; font-size: .875rem; opacity: .8;
}

@media (max-width: 767px) {
  .footer__inner { flex-direction: column; text-align: center; }
  /* padding-left: 120px (fix mobile, ronda de correccion 2) — con
     .carrito-flotante/.fab-wa movidos a la izquierda (mas arriba en este
     archivo), el pie de pagina quedo con el mismo problema que las filas de
     la tienda: align-items:center (heredado de la regla base, sin pisar en
     este media query) centra cada bloque -footer__marca, footer__nav,
     footer__redes- COMO UNIDAD dentro de footer__inner, pero eso no
     garantiza despeje del borde izquierdo. Se probo "justify-content:
     center" directo en .footer__nav y no alcanzo: cuando .footer__nav
     necesita ajustar mas de una linea (5 links no entran en una a este
     ancho), cada linea wrappeada se centra POR SU CUENTA dentro del ancho
     ya ocupado por .footer__nav -que a su vez ocupa el ancho disponible
     completo por el propio wrap, no el de su contenido-, y una linea corta
     (p. ej. "Inicio" solo, 33px, centrada en 280px) puede seguir cayendo
     entera dentro de la columna de 20-140px de los flotantes (medido con
     CDP: "Inicio" en x=64.5-97.5, adentro de esa columna). Reservar el
     padding directo en el contenedor evita el problema en la raiz: nada
     -marca, nav en una o varias lineas, redes- puede empezar antes de
     footer__inner.left + 120px, sin importar cuanto contenido entre en cada
     linea. Mismo numero que .t-item__acciones (mas arriba): la misma
     columna de flotantes, la misma cuenta.

     padding-right: 76px (ajuste "WhatsApp vuelve a la derecha"): el FAB
     vuelve a la esquina inferior derecha (ver la seccion de .fab-wa mas
     abajo en este archivo) y el carrito flotante se queda solo en la
     izquierda -dos columnas, no una-, asi que el pie tiene que reservar de
     los dos lados.
     Medido con CDP: el contenido real de este pie (marca, nav, redes) nunca
     se acerca a ningun borde a 320-375px -sigue OK incluso con
     padding-right:0-, asi que 76px no es un minimo forzado sino el tamaño
     real de la columna del FAB desde el borde (56px de ancho + 1.25rem/20px
     de "right"): reservar lo que hay, misma logica que el padding-left de
     arriba, con margen de sobra para cualquier contenido futuro del pie. */
  .footer__inner { padding-left: 120px; padding-right: 76px; }
  /* .footer__copy reserva la MISMA columna (no hereda el padding de
     .footer__inner: es un hermano suyo, no un hijo -ver el HTML del footer-,
     asi que necesita su propia regla). Sin esto el parrafo de copyright, que
     ocupa el ancho completo del pie con "text-align: center" y sin padding
     propio, quedaba con su texto renderizado (medido con Range, no con el
     bounding box del <p> -ese siempre da el ancho completo del bloque,
     tenga o no padding- porque el texto centrado adentro es lo que un
     humano ve) superpuesto al FAB en la posicion de scroll final: no es un
     control interactivo asi que no violaba el requisito no-negociable de
     esta tarea, pero seguia siendo una superposicion visual real,
     documentada como concern #1 en la ronda anterior de este mismo fix.
     Confirmado con CDP en las 4 combinaciones (landing/tienda x 320/375px)
     que 120px/76px la despeja de las dos columnas -76px sin acompañar el
     120px del otro lado alcanzaba para el FAB pero no para el carrito a
     320px-. No estaba pedido por el encargo de esta ronda (que solo pedia
     "fijate si queda resuelto de paso"), pero el costo es una regla mas en
     el mismo media query que ya se estaba tocando: se resuelve en vez de
     dejarla pendiente. */
  .footer__copy { padding-left: 120px; padding-right: 76px; }
}

/* ---------- Botón flotante WhatsApp ---------- */
/* #128C7E es el verde oscuro de marca de WhatsApp (no #25D366): el ícono blanco
   sobre #25D366 medía 1.98:1, por debajo del 3:1 que pide WCAG 1.4.11 para
   componentes no textuales. #128C7E da ~4.1:1 sin perder identidad de marca. */
.fab-wa {
  position: fixed; right: 1.25rem; bottom: 1.25rem; z-index: 60;
  display: grid; place-items: center;
  width: 56px; height: 56px; border-radius: 50%;
  background: #128C7E; color: var(--blanco);
  box-shadow: 0 6px 16px rgba(0,0,0,.22);
  transition: transform .2s ease;
}
.fab-wa svg { fill: currentColor; }
.fab-wa:hover { transform: scale(1.06); }

/* ---------- Carrito flotante (mobile, Plan B del spec) ---------- */
/* Por debajo de 768px .nav se convierte en el panel de la hamburguesa y se
   lleva a #btn-carrito adentro: sin este botón, el visitante agrega un
   producto y no ve ningún cambio en pantalla ni tiene forma visible de
   llegar al pedido (hallazgo CRITICAL de la revisión final). No es el mismo
   botón reposicionado por CSS: un descendiente de .nav no puede ser
   position:fixed respecto del viewport mientras .nav tenga "transform" (la
   animación de apertura/cierre en @media max-width:767px, más arriba) -
   cualquier valor de transform en un ancestro, incluso translateY(0), crea
   su propio containing block para los descendientes fixed, así que quedaría
   fijo respecto de .nav y se iría fuera de pantalla junto con el menú
   cerrado-. Por eso vive fuera de .nav, en su propia esquina fija (ver mas
   abajo: ya no comparte lado con el FAB de WhatsApp).

   "left", no "right" (fix mobile, ronda de correccion 2): en mobile
   .t-item__acciones tiene "justify-content: flex-end" (mas abajo, dentro de
   @media max-width:700px) -el boton "Agregar"/selector de cantidad de CADA
   fila queda pegado al borde derecho de la pantalla-. Con este boton fijo
   tambien a la derecha, cualquier fila que cayera bajo su franja quedaba
   tapada: un tap en "Agregar" en esa posicion de scroll abria el panel del
   carrito en vez de agregar el producto (bug real, reproducido con click en
   coordenadas reales sobre Botella 1LT a 375px con scroll en cero -un
   .click() por selector no lo hubiera detectado-). La columna "foto" (64px,
   una imagen sin interaccion) y el tramo izquierdo -vacio- de la fila de
   acciones nunca tienen un control real, en ningun ancho de mobile: moverse
   a la izquierda saca al boton de la unica franja donde si hay controles con
   los que superponerse.

   Ajuste "WhatsApp vuelve a la derecha": en la ronda anterior el FAB se
   habia sumado a este mismo lado (ver el commit cce11fd) porque moverlo
   dejaba de estar en la esquina inferior derecha -la posicion casi
   universal de ese boton, incluida la propia app de WhatsApp-, un costo de
   descubribilidad que el dueño del sitio decidio que no valia la pena. El
   FAB vuelve a la derecha (media query de mobile mas abajo, junto a
   .fab-wa: ya no tiene override de lado ahi) y el carrito se queda solo en
   esta esquina. Ya no hace falta que los dos compartan lado para evitar que
   tapen "Agregar": ahora es .t-item__acciones (y .footer__inner) quien
   reserva columna de LOS DOS lados -ver esas reglas-, asi que cada
   flotante queda protegido por separado sin importar en que esquina
   este. */
.carrito-flotante {
  display: none;
  position: fixed; left: 1.25rem; z-index: 60;
  /* bottom: 1.25rem, no calc(...56px...): antes se apilaba arriba del FAB
     porque los dos vivian en la esquina izquierda. Con el FAB de vuelta a
     la derecha (ajuste "WhatsApp vuelve a la derecha", ver el comentario
     largo arriba) el carrito queda solo en su esquina, mismo bottom que el
     FAB siempre tuvo, sin nada que despejar por encima. */
  bottom: 1.25rem;
  height: 56px; padding-inline: 1.125rem;
  box-shadow: 0 6px 16px rgba(0,0,0,.22);
}
/* Neutraliza la cascada de origen para el atributo hidden (mismo patrón que
   .btn[hidden]/.campo[hidden]/.panel-carrito ya documentado en este
   archivo): sin esto, un elemento .btn con "hidden" quedaría oculto por
   .btn[hidden] igual, pero el barrido genérico de check.ps1 exige la regla
   propia de la clase con su propio display no-none (la del media query de
   abajo), no solo la heredada de .btn. */
.carrito-flotante[hidden] { display: none; }
/* El badge del contador es celeste sobre blanco en el header (fondo blanco);
   acá el botón entero ES celeste, así que el badge se invierte -blanco
   sobre celeste- para no perderse contra su propio fondo. */
.carrito-flotante .nav__carrito__n { background: var(--blanco); color: var(--celeste); }

@media (max-width: 767px) {
  .carrito-flotante { display: inline-flex; }
  /* Ajuste "WhatsApp vuelve a la derecha": este media query tenia un
     override que movia .fab-wa a la izquierda (ver el comentario largo
     junto a .carrito-flotante, mas arriba). Se retira: sin el override,
     .fab-wa hereda la regla base (right: 1.25rem; bottom: 1.25rem, arriba
     en este archivo) tambien en mobile -mismo lugar que en desktop, cero
     reglas nuevas necesarias-. La proteccion contra que vuelva a tapar
     "Agregar" ya no depende de compartir lado con el carrito: la reserva
     ahora vive en .t-item__acciones (columna de los dos lados, ver esa
     regla mas abajo en este archivo). */
}

/* ---------- Contacto ---------- */
.contacto { padding: 5rem 0; background: var(--superficie); }
.contacto__bajada {
  text-align: center; color: var(--gris);
  margin-top: -2rem; margin-bottom: 3rem;
}
.contacto__grid { display: grid; grid-template-columns: 1fr 1.2fr; gap: 3.5rem; }

.datos { display: grid; gap: 1.5rem; margin-bottom: 2rem; }
.dato { display: flex; gap: .875rem; align-items: flex-start; }
.dato__icono { flex: 0 0 22px; width: 22px; height: 22px; fill: var(--celeste); margin-top: .2rem; }
.dato__titulo { font-size: .8125rem; font-weight: 500; color: var(--gris); text-transform: uppercase; letter-spacing: .06em; }
.dato__valor { color: var(--tinta); }
.dato__valor a { color: var(--tinta); text-decoration: none; }
.dato__valor a:hover { color: var(--celeste); text-decoration: underline; }

.formulario {
  background: var(--blanco);
  border: 1px solid rgba(59, 76, 168, .14); border-radius: var(--radio);
  padding: 2rem; box-shadow: var(--sombra);
}
.campo { display: grid; gap: .5rem; margin-bottom: 1.25rem; }
/* Mismo bug de cascada ya documentado mas abajo para .panel-carrito (Task 4):
   "display: grid" de arriba es CSS de autor y le gana por ORIGEN (no por
   especificidad) a "[hidden] { display: none }" de la hoja del navegador, asi
   que un elemento con clase .campo nunca queda oculto por el solo atributo
   hidden. #campo-direccion (el campo de direccion del pedido, Task 5) es
   exactamente ese caso: nace con el atributo hidden pero display:grid lo
   ganaba y quedaba visible siempre, con retiro como entrega por defecto.
   Ronda de correccion 1: se agrega esta regla mas especifica (dos clases de
   especificidad contra una) para que [hidden] vuelva a ocultar de verdad. */
.campo[hidden] { display: none; }
.campo label { font-size: .9375rem; font-weight: 500; color: var(--tinta); }
.campo label span { color: #DC2626; }
.campo input, .campo textarea {
  /* min-width: 0 anula el ancho minimo por defecto de los controles de formulario
     dentro de un contenedor grid (.campo): sin esto, el input no puede achicarse
     por debajo de su ancho intrinseco y desborda el contenedor en mobile angosto
     (320px), aunque .campo lo estire con justify-items: stretch. */
  min-width: 0;
  font-family: var(--fuente-cuerpo); font-size: 1rem; color: var(--tinta);
  padding: .75rem 1rem;
  background: var(--blanco);
  /* .34 (usado en los marcos decorativos de .formulario/.producto/.confianza) da 1.75:1
     contra blanco: por debajo del 3:1 que exige WCAG 1.4.11 para el limite de un
     componente operable. .62 da 3.07:1 — ronda de correccion 1. */
  border: 1px solid rgba(59, 76, 168, .62); border-radius: var(--radio);
  transition: border-color .2s ease;
}
.campo input:hover, .campo textarea:hover { border-color: var(--gris); }
.campo textarea { resize: vertical; min-height: 120px; }
.campo__error { font-size: .875rem; color: #DC2626; min-height: 0; }
.campo__error:empty { display: none; }
.campo input[aria-invalid="true"], .campo textarea[aria-invalid="true"] { border-color: #DC2626; }
.formulario__nota { margin-top: .875rem; font-size: .875rem; color: var(--gris); }

/* Formulario del pedido, dentro del panel del carrito (Tienda Fase 1, Task 5):
   reutiliza .formulario/.campo/.campo__error del formulario de contacto, pero
   sin su marco propio -el panel-carrito__pie ya tiene el suyo-. */
.formulario--pedido { background: none; border: 0; padding: 0; box-shadow: none; }
.formulario--pedido .campo { margin-bottom: 1rem; }
.campo--opciones { border: 0; padding: 0; margin-bottom: 1rem; }
.campo--opciones legend {
  font-size: .9375rem; font-weight: 500; color: var(--tinta); margin-bottom: .5rem; padding: 0;
}
.opcion { display: flex; align-items: center; gap: .5rem; font-size: .9375rem; padding: .25rem 0; }
.opcion input { accent-color: var(--celeste); width: 18px; height: 18px; }
.panel-carrito__enviar { width: 100%; }
.panel-carrito__enviar:disabled { opacity: .5; cursor: not-allowed; }

@media (max-width: 900px) {
  .contacto__grid { grid-template-columns: 1fr; gap: 2.5rem; }
}

/* ---------- Scroll reveal ---------- */
/* Selector prefijado con .js (agregada por un script inline sincrónico en el
   <head>, ver index.html): si JavaScript está deshabilitado o falla antes de
   correr, esa clase nunca se agrega y esta regla de opacity:0 nunca aplica,
   así que el contenido queda visible por default en vez de oculto para
   siempre. Fuera de este media query no hay regla: con movimiento reducido
   el contenido también está visible desde el principio, sin depender del JS. */
@media (prefers-reduced-motion: no-preference) {
  .js [data-reveal] {
    opacity: 0;
    transform: translateY(16px);
    transition: opacity .5s ease, transform .5s ease;
  }
  .js [data-reveal].es-visible { opacity: 1; transform: none; }
}

/* ---------- Tienda ---------- */
.tienda { padding: 5rem 0; }
.tienda__bajada {
  text-align: center; color: var(--gris);
  margin-top: -2rem; margin-bottom: 2rem;
}
.tienda__aviso {
  max-width: 60ch; margin: 0 auto 2rem; padding: 1rem 1.25rem;
  background: var(--superficie); border-radius: var(--radio);
  color: var(--tinta); text-align: center;
}

.tienda__anclas {
  display: flex; flex-wrap: wrap; justify-content: center; gap: .5rem;
  margin-bottom: 3rem;
}
.tienda__anclas a {
  padding: .5rem 1rem;
  /* .34 (marcos decorativos) da 1.75:1 contra blanco: por debajo del 3:1 que exige
     WCAG 1.4.11 para el limite de un control operable — estos chips se clickean
     para saltar de categoria. .62 (el mismo valor ya usado en .campo input/textarea)
     da 3.07:1 — ronda de correccion 1. */
  border: 1px solid rgba(59, 76, 168, .62); border-radius: var(--radio);
  color: var(--tinta); text-decoration: none; font-size: .9375rem;
}
.tienda__anclas a:hover { background: var(--celeste); border-color: var(--celeste); color: var(--blanco); }

.t-categoria { margin-bottom: 3rem; scroll-margin-top: calc(var(--header-alto) + 1rem); }
.t-categoria__titulo {
  margin-bottom: 1.25rem; padding-bottom: .5rem;
  border-bottom: 1px solid rgba(59, 76, 168, .14);
}

.t-lista { display: grid; gap: .75rem; }

.t-item {
  display: grid;
  grid-template-columns: 64px 1fr auto auto;
  align-items: center; gap: 1rem;
  padding: .75rem 1rem;
  background: var(--blanco);
  border: 1px solid rgba(59, 76, 168, .14); border-radius: var(--radio);
}
.t-item__foto {
  width: 64px; height: 64px; object-fit: contain;
  background: var(--superficie); border-radius: calc(var(--radio) - 6px);
  padding: .25rem;
}
.t-item__nombre { font-size: 1rem; font-weight: 600; }
.t-item__desc { font-size: .875rem; color: var(--gris); margin-top: .125rem; }
.t-item__precio {
  font-family: var(--fuente-titulo); font-weight: 600; font-size: 1.0625rem;
  color: var(--tinta); white-space: nowrap;
}
.t-item__precio--consultar { font-size: .875rem; font-weight: 400; color: var(--gris); }
.t-item__acciones { display: flex; align-items: center; gap: .5rem; }

.cantidad { display: inline-flex; align-items: center; }
.cantidad__b {
  width: 32px; height: 32px; font-size: 1.125rem; line-height: 1;
  background: var(--blanco); color: var(--tinta); cursor: pointer;
  border: 1px solid rgba(59, 76, 168, .62);
}
.cantidad__b:first-child { border-radius: var(--radio) 0 0 var(--radio); }
.cantidad__b:last-child  { border-radius: 0 var(--radio) var(--radio) 0; }
.cantidad__b:hover { background: var(--superficie); }
.cantidad__n {
  width: 48px; height: 32px; text-align: center;
  font-family: var(--fuente-cuerpo); font-size: .9375rem; color: var(--tinta);
  border: 1px solid rgba(59, 76, 168, .62); border-inline: 0; background: var(--blanco);
}
.cantidad__n::-webkit-outer-spin-button,
.cantidad__n::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.cantidad__n { -moz-appearance: textfield; }

@media (max-width: 700px) {
  /* Ronda de correccion 1 de Task 3: "precio" tenia su propia columna de
     56px (misma pista que "foto") en la misma fila que "acciones", y como
     .t-item__precio usa white-space: nowrap con overflow visible, un texto
     largo como "Consultar precio" pintaba fuera de esa columna angosta y
     se superponia al boton "-" de al lado (medido con Range: el texto
     llegaba a x=141.4 mientras el boton arrancaba en x=109.4). Ahora
     "precio" ocupa su propia fila de ancho completo, arriba de "acciones"
     (tambien de ancho completo): ya no comparte fila con ningun control,
     asi que no hay con que superponerse sin importar cuan largo sea el
     texto. */
  .t-item {
    grid-template-columns: 56px 1fr;
    grid-template-areas: "foto texto" "precio precio" "acciones acciones";
    row-gap: .75rem;
  }
  .t-item__foto    { grid-area: foto; width: 56px; height: 56px; }
  .t-item__texto   { grid-area: texto; }
  .t-item__precio  { grid-area: precio; }
  /* min-width: 0 evita que este item de grid rehuse encoger por debajo del
     ancho minimo de contenido de sus hijos (comportamiento por defecto de
     grid/flex), que a 320px empujaba todo el .t-item -y la pagina entera-
     mas alla del viewport. flex-wrap deja que el boton Agregar caiga a una
     segunda linea si el selector de cantidad ya usa el ancho disponible.

     padding-left: 120px (fix mobile, ronda de correccion 2) — con
     justify-content:flex-end el grupo entero (selector de cantidad +
     "Agregar") se empaqueta contra el borde DERECHO de esta fila, pero eso
     no dice nada de donde queda su borde IZQUIERDO: a 320-390px el grupo
     completo (~228px) casi llena el ancho disponible (~246px a 320px), asi
     que el boton "−" del selector -el primero del grupo- terminaba a solo
     ~17px del borde izquierdo de la fila (medido con CDP, Input.dispatch-
     MouseEvent real: en (70,684) tocaba #btn-carrito-movil, no el "−"). Con
     .carrito-flotante/.fab-wa movidos a la izquierda (mas arriba en este
     archivo) esos 17px no alcanzan para despejar su columna (~94-140px de
     ancho segun cuantos digitos tenga el contador del carrito). Este
     padding reduce el ancho util de la fila: por debajo de ~420px ya no
     entran juntos en una linea y el selector de cantidad cae SOLO a su
     propia linea, tambien empaquetado contra el borde derecho -queda a
     accionesRight-112px, verificado con CDP en 320px: x=171, >55px de
     margen real contra la columna de los flotantes (hasta ~140px)-. Por
     encima de ese ancho hay slack de sobra sin el padding (nunca se activa
     el wrap) y el layout de una sola linea de siempre queda igual.

     padding-right: 48px (ajuste "WhatsApp vuelve a la derecha"): con el FAB
     de vuelta en la esquina inferior derecha, la misma fila que ya reservaba
     el borde izquierdo para el carrito necesita reservar TAMBIEN el derecho
     para el FAB -las dos filas de "acciones" (selector de cantidad arriba,
     "Agregar" abajo, por el wrap de arriba) pasan por esa franja en algun
     scroll, para cualquier producto de la lista-. Esto es mas ajustado que
     el padding-left: a 320px la fila mide 246px de ancho total y el
     selector de cantidad (tres controles de ancho fijo: 32+48+32=112px, no
     puede encogerse) ya usa la mayor parte de lo que queda tras los 120px
     de la izquierda.

     Dos formas distintas de medir "margen" dan numeros MUY distintos aca, y
     importa no confundirlas: el barrido de
     tools/verificar-mobile-flotante.js -la verificacion real de esta tarea-
     chequea el CENTRO de la porcion visible de cada control (el mismo gesto
     que un dedo hace), no sus bordes; ese margen de centro es comodo en casi
     toda la ventana medida (30-75px de padding-right, sondeada con CDP
     variando el valor en vivo sobre la fila real). Pero el margen de BORDE
     -si el rectangulo del boton llega a tocar visualmente el circulo del
     FAB, que es el sentido de "encimado" que pidio chequear el encargo- es
     mucho mas angosto: por debajo de ~39px de padding-right el boton "+" ya
     se solapa en el borde con el FAB (aunque su CENTRO siga libre, asi que
     el barrido no lo marca como tapado), y por encima de ~57px pasa lo
     mismo del lado del "−" contra el carrito. 48px es el punto medio exacto
     de esa ventana de borde (39 a 57): deja ~9px reales de aire de cada
     lado en el caso normal (contador de 1-2 digitos), verificado con CDP
     sobre la fila real -no una formula- despues de fijar el numero. Con
     un contador de 3+ digitos (pedido de decenas de unidades en varios
     productos a la vez, no lo que ejercita el barrido pero si algo que un
     cliente real podria hacer) el margen del lado del carrito se angosta y
     en el extremo (varios miles de unidades) podria volver a tocar en el
     borde -el margen de CENTRO, que es lo que de verdad determina si un tap
     falla, se mantiene comodo incluso ahi-. Con los dos paddings juntos
     (168px de 246px totales a 320px) el selector de cantidad, que no puede
     encogerse por debajo de sus 112px, excede el hueco que le queda (78px):
     se desborda hacia la izquierda contra el propio borde de contenido
     (comportamiento de "overflow seguro" de flexbox con justify-content:
     flex-end) en vez de encogerse o solaparse con nada clickeable. Es la
     situacion que el encargo pedia reportar si no entraba comodo: entra,
     con ~9px de aire real de cada lado en el caso normal -mas justo que el
     ~55px del padding-left original de un solo lado, pero sin solape de
     borde en el uso real- ver el reporte de esta ronda para las mediciones
     completas del ancho disponible a 320px. */
  .t-item__acciones {
    grid-area: acciones; justify-content: flex-end;
    flex-wrap: wrap; min-width: 0; padding-left: 120px; padding-right: 48px;
  }
}

/* ---------- Panel del carrito ---------- */
.carrito-fondo {
  position: fixed; inset: 0; z-index: 70;
  background: rgba(31, 41, 55, .5);
}
/* El panel usa "inert" (atributo/propiedad, no CSS) para su estado
   cerrado/abierto, no el atributo "hidden": "display: flex" de abajo es CSS
   de autor y le gana por origen (no por especificidad) a la regla
   "[hidden] { display: none }" de la hoja del navegador, asi que un
   elemento con display propio nunca queda oculto por el solo atributo
   hidden -con prefers-reduced-motion: reduce (sin el transform de mas
   abajo, que solo corre con motion normal) el panel "cerrado" habria
   quedado total y permanentemente visible, tapando el borde derecho del
   sitio-. "inert" no tiene ese problema (no es una propiedad de CSS
   transicionable: sacar o poner el atributo saca o pone al panel y a sus
   hijos de la tabulacion y de lectores de pantalla de forma sincronica,
   sin depender de ninguna transicion ni de la preferencia de movimiento),
   asi que initPanel() alterna panel.inert en vez de panel.hidden. La
   posicion cerrada (fuera de pantalla) tambien es incondicional -no una
   animacion-: translateX(100%) es el estado por defecto y .is-abierto lo
   lleva a translateX(0); lo unico condicionado a prefers-reduced-motion es
   la transicion entre esos dos estados, mas abajo. */
.panel-carrito {
  position: fixed; top: 0; right: 0; bottom: 0; z-index: 71;
  width: min(420px, 100vw);
  display: flex; flex-direction: column;
  background: var(--blanco);
  box-shadow: var(--sombra-alta);
  transform: translateX(100%);
}
.panel-carrito.is-abierto { transform: translateX(0); }
.panel-carrito__cab {
  display: flex; align-items: center; justify-content: space-between;
  padding: 1.25rem 1.25rem 1rem;
  border-bottom: 1px solid rgba(59, 76, 168, .14);
}
.panel-carrito__titulo { font-size: 1.25rem; }
.panel-carrito__cerrar {
  width: 40px; height: 40px; font-size: 1.5rem; line-height: 1;
  background: none; border: 0; color: var(--tinta); cursor: pointer;
  border-radius: var(--radio);
}
.panel-carrito__cerrar:hover { background: var(--superficie); }
.panel-carrito__cuerpo { flex: 1; overflow-y: auto; padding: 1rem 1.25rem; }
.panel-carrito__pie {
  padding: 1.25rem; border-top: 1px solid rgba(59, 76, 168, .14);
}
.panel-carrito__total {
  display: flex; justify-content: space-between; align-items: baseline;
  font-size: 1.0625rem; margin-bottom: 1rem;
}
.panel-carrito__total strong { font-family: var(--fuente-titulo); font-size: 1.375rem; }

.c-linea {
  display: grid; grid-template-columns: 48px 1fr auto; gap: .75rem;
  align-items: center; padding: .75rem 0;
  border-bottom: 1px solid rgba(59, 76, 168, .14);
}
.c-linea__foto {
  width: 48px; height: 48px; object-fit: contain;
  background: var(--superficie); border-radius: 8px; padding: .125rem;
}
/* min-width: 0 evita que esta celda de grid rehuse encoger por debajo del
   ancho minimo de contenido de sus hijos (mismo motivo que .t-item__acciones
   en el layout mobile de la grilla, mas arriba): sin esto, el selector de
   cantidad podia forzar desborde horizontal del panel a 320-375px. */
.c-linea__info { min-width: 0; }
.c-linea__nombre { font-size: .9375rem; font-weight: 500; }
/* Fila de controles de la linea: cantidad a la izquierda, precio a la
   derecha. flex-wrap dejar caer el precio a una segunda linea si el ancho
   angosto del panel (320-375px) no alcanza para los dos lado a lado -en vez
   de desbordar u obligar a comprimir el selector de cantidad, que ya usa el
   mismo tamano de touch target que en la grilla-. */
.c-linea__controles {
  display: flex; align-items: center; flex-wrap: wrap;
  gap: .375rem .75rem; margin-top: .375rem;
}
.c-linea__precio { font-size: .875rem; color: var(--gris); margin: 0; }
.c-linea__quitar {
  background: none; border: 0; color: var(--gris); cursor: pointer;
  font-size: 1.25rem; line-height: 1; padding: .25rem .5rem; border-radius: var(--radio);
}
.c-linea__quitar:hover { color: #DC2626; background: var(--superficie); }
.carrito-vacio { text-align: center; color: var(--gris); padding: 2rem 0; }
/* #1A74B0 sobre blanco da 5.04:1, AA para texto normal (mismo tono que
   .btn--linea, ya usado como color de texto en el sitio). */
.carrito-vacio a { color: var(--celeste); font-weight: 500; }

@media (prefers-reduced-motion: no-preference) {
  /* Solo la animacion esta condicionada a la preferencia de movimiento: la
     posicion (translateX(100%)/(0), arriba) es la misma con o sin motion
     reducido, lo unico que cambia es si el paso de una a otra se ve
     interpolado o instantaneo. */
  .panel-carrito { transition: transform .28s ease; }
}
