/* ==========================================
   XELA TORTILLERÍA — CAPA DE ANIMACIONES
   Diseñada para sentir nativo en iOS Safari.
   Solo transform + opacity + backdrop-filter.
   Solo ease-out o spring; nada de ease-in o linear.
   Duraciones 100–400ms (excepción: 800ms counter).
   ========================================== */

:root {
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  --spring: cubic-bezier(0.34, 1.56, 0.64, 1);
  --dur-tap: 100ms;
  --dur-close: 200ms;
  --dur-ui: 300ms;
  --dur-reveal: 350ms;
  --dur-counter: 800ms;
}

/* ==========================================
   3. RESPUESTA AL TOQUE
   ========================================== */
button, a, .btn, .producto-card, .tipo-card, .info-card,
.whatsapp-float, .nav-toggle, .productos-arrow {
  -webkit-tap-highlight-color: transparent;
  -webkit-touch-callout: none;
}

.btn, .nav-links a, .nav-toggle, .productos-arrow {
  transition:
    transform var(--dur-tap) var(--ease-out),
    background-color var(--dur-ui) var(--ease-out),
    color var(--dur-ui) var(--ease-out),
    box-shadow var(--dur-ui) var(--ease-out),
    border-color var(--dur-ui) var(--ease-out);
}

.btn:active,
.nav-links a:active,
.nav-toggle:active,
.productos-arrow:active {
  transform: scale(0.97);
}

/* Cards: mantengo su hover translateY existente, pero agrego :active shrink
   Solo en dispositivos táctiles / donde el hover no aplica el translateY */
@media (hover: none) {
  .producto-card:active,
  .tipo-card:active,
  .info-card:active {
    transform: scale(0.98);
    transition: transform var(--dur-tap) var(--ease-out);
  }
}
/* Amplifica el lift de las cards de producto en desktop:
   más recorrido vertical + sombra más marcada. */
@media (hover: hover) {
  .producto-card {
    transition:
      transform 300ms cubic-bezier(0.34, 1.4, 0.64, 1),
      box-shadow 300ms var(--ease-out),
      border-color 300ms var(--ease-out);
  }
  .producto-card:hover {
    transform: translateY(-10px);
    box-shadow: 0 14px 40px rgba(0, 0, 0, 0.15);
  }
}

/* ==========================================
   4. HEADER VIDRIO ESMERILADO
   Estado inicial: semi-transparente blanco sin blur, sin sombra.
   Al hacer scroll (.is-scrolled): gana saturate+blur y sombra suave.
   ========================================== */
#navbar {
  background: rgba(255, 255, 255, 0.4);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  box-shadow: none;
  transition:
    background-color var(--dur-ui) var(--ease-out),
    backdrop-filter var(--dur-ui) var(--ease-out),
    -webkit-backdrop-filter var(--dur-ui) var(--ease-out),
    box-shadow var(--dur-ui) var(--ease-out);
}

#navbar.is-scrolled {
  background: rgba(255, 255, 255, 0.78);
  backdrop-filter: saturate(200%) blur(28px);
  -webkit-backdrop-filter: saturate(200%) blur(28px);
  box-shadow:
    0 1px 0 rgba(0, 0, 0, 0.08),
    0 4px 16px rgba(0, 0, 0, 0.06);
}

/* ==========================================
   5. HAMBURGUESA CON ORIGEN DE ESQUINA
   Apertura: spring con overshoot ligero (300ms).
   Cierre: ease-out más rápido (200ms).
   ========================================== */
@media (max-width: 768px) {
  #navLinks.nav-links {
    display: flex;
    flex-direction: column;
    position: absolute;
    top: calc(var(--nav-height) + 8px);
    right: 1rem;
    left: auto;
    width: auto;
    min-width: 200px;
    max-width: calc(100vw - 2rem);
    padding: 0.5rem;
    background: rgba(255, 255, 255, 0.85);
    backdrop-filter: saturate(180%) blur(20px);
    -webkit-backdrop-filter: saturate(180%) blur(20px);
    border-radius: 16px;
    box-shadow: 0 8px 30px rgba(0, 0, 0, 0.12);
    transform-origin: top right;
    transform: scale(0.85) translateY(-8px);
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition:
      transform var(--dur-close) var(--ease-out),
      opacity var(--dur-close) var(--ease-out),
      visibility 0s linear var(--dur-close);
  }
  #navLinks.nav-links.open {
    transform: scale(1) translateY(0);
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transition:
      transform var(--dur-ui) var(--spring),
      opacity var(--dur-ui) var(--ease-out),
      visibility 0s linear 0s;
  }
  #navLinks.nav-links a {
    border-bottom: none;
    border-radius: 10px;
    padding: 0.75rem 1rem;
  }
}

/* ==========================================
   6. WHATSAPP FAB
   Entra a los 800ms con spring. Pulso discreto cada 8s.
   Respeta safe-area del iPhone (barra de gestos).
   El estado invisible inicial solo aplica si el JS cargó
   (prefix .js). Sin JS, el botón se ve completo.
   ========================================== */
.whatsapp-float {
  animation: none !important;
  bottom: calc(1.75rem + env(safe-area-inset-bottom, 0px));
  right: calc(1.75rem + env(safe-area-inset-right, 0px));
  transition:
    opacity 400ms var(--ease-out),
    transform 400ms cubic-bezier(0.34, 1.7, 0.64, 1),
    box-shadow var(--dur-ui) var(--ease-out);
}
.js .whatsapp-float {
  opacity: 0;
  transform: scale(0.5);
}
.js .whatsapp-float.wa-ready {
  opacity: 1;
  transform: scale(1);
}
.whatsapp-float.wa-ready:active {
  transform: scale(0.93);
  transition: transform var(--dur-tap) var(--ease-out);
}
.whatsapp-float.wa-pulse {
  animation: wa-pulse 900ms var(--ease-out);
}
@keyframes wa-pulse {
  0%   { transform: scale(1); }
  45%  { transform: scale(1.06); }
  100% { transform: scale(1); }
}

/* ==========================================
   7. STATS — DÍGITOS DE ANCHO FIJO
   ========================================== */
.stat strong {
  font-variant-numeric: tabular-nums;
}

/* ==========================================
   3a. PRECIOS CON DÍGITOS DE ANCHO FIJO
   El count-up se dispara desde JS al entrar al viewport.
   Al terminar el conteo, el JS agrega .xela-bump para
   dar un pulso de escala breve (400ms) que enfatiza el
   valor final.
   ========================================== */
.producto-price {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum";
  transform-origin: left center;
}
.stat strong {
  transform-origin: left center;
  display: inline-block;
}
@keyframes xela-number-bump {
  0%   { transform: scale(1); }
  35%  { transform: scale(1.08); }
  100% { transform: scale(1); }
}
.xela-bump {
  animation: xela-number-bump 400ms cubic-bezier(0.34, 1.56, 0.64, 1);
}

/* ==========================================
   3b. FLOTACIÓN CONTINUA DE ÍCONOS
   Recorrido de 4px, ciclo lento (5s), ease-in-out.
   Cada card recibe un delay negativo distinto (JS) para
   desfasar el arranque y que no floten al unísono.
   Se corta si el usuario prefiere reduced-motion.
   ========================================== */
@keyframes xela-float-y {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-7px); }
}
.producto-icon,
.tipo-emoji {
  animation: xela-float-y 4s ease-in-out infinite;
  will-change: transform;
}
/* .producto-photo: bloque superior de la card para las cards que usan
   foto real de producto (Maíz y Moringa). Reemplaza a .producto-icon (el
   círculo pastel) — sin fondo, sin borde, imagen a ancho completo con
   altura fija y object-fit contain para no recortar ni deformar.
   Hereda la flotación continua. Aviso: hace las cards con foto MÁS
   ALTAS que las cards con emoji. */
.producto-photo {
  width: 100%;
  height: 200px;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 1.25rem;
  animation: xela-float-y 4s ease-in-out infinite;
  will-change: transform;
  /* Fallback: si el <img> falla y JS restituye el emoji con textContent,
     que se lea legible en el espacio de 200px */
  font-size: 3.5rem;
  line-height: 1;
}
.producto-photo img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* ==========================================
   8. HERO ENTRADA — LÍNEAS ENMASCARADAS + CASCADA
   El h1 tiene 2 líneas envueltas en .line/.line-inner:
   la exterior recorta con overflow:hidden, la interior
   empieza translateY(100%) y sube con spring.
   Después entra el resto (eyebrow, slogan, subtitle,
   actions, badges) en cascada con ease-out.
   El estado invisible solo aplica con .js — sin JS
   todo se ve normal.
   ========================================== */
.hero-title .line {
  display: block;
  overflow: hidden;
  padding-bottom: 0.08em; /* evita cortar descenders/subrayado del acento */
}
.hero-title .line-inner {
  display: inline-block;
  will-change: transform;
}

.js .hero-title .line-inner {
  transform: translateY(105%);
  transition: transform 600ms cubic-bezier(0.34, 1.7, 0.64, 1);
}
.js body.hero-loaded .hero-title .line-inner {
  transform: translateY(0);
}
.js body.hero-loaded .hero-title .line:nth-child(1) .line-inner { transition-delay: 60ms;  }
.js body.hero-loaded .hero-title .line:nth-child(2) .line-inner { transition-delay: 160ms; }

/* ==========================================
   Títulos de sección con máscara
   Reutilizan .line/.line-inner del hero pero se disparan
   cuando entran al viewport (via .reveal.revealed).
   El h2 con .title-masked no hace su propio translateY
   (para no pisar el mask); solo hace fade. La sub-línea
   sube desde translateY(105%) con spring.
   ========================================== */
.js .title-masked .line {
  display: block;
  overflow: hidden;
  padding-bottom: 0.1em;
}
.js .title-masked .line-inner {
  display: inline-block;
  transform: translateY(105%);
  transition: transform 600ms cubic-bezier(0.34, 1.7, 0.64, 1);
  will-change: transform;
}
.js .title-masked.reveal {
  transform: none;
  transition:
    opacity 400ms var(--ease-out);
}
.js .title-masked.reveal.revealed .line-inner {
  transform: translateY(0);
  transition-delay: 80ms;
}

.js .hero-eyebrow,
.js .hero-slogan,
.js .hero-subtitle,
.js .hero-actions,
.js .hero-badges {
  opacity: 0;
  transform: translateY(12px);
  transition:
    opacity var(--dur-reveal) var(--ease-out),
    transform var(--dur-reveal) var(--ease-out);
}
.js body.hero-loaded .hero-eyebrow  { opacity: 1; transform: none; transition-delay: 0ms;   }
.js body.hero-loaded .hero-slogan   { opacity: 1; transform: none; transition-delay: 260ms; }
.js body.hero-loaded .hero-subtitle { opacity: 1; transform: none; transition-delay: 340ms; }
.js body.hero-loaded .hero-actions  { opacity: 1; transform: none; transition-delay: 420ms; }
.js body.hero-loaded .hero-badges   { opacity: 1; transform: none; transition-delay: 480ms; }

/* ==========================================
   2. CONTADOR DE POSICIÓN DEL CARRUSEL "03 / 07"
   Discreto, alineado a la derecha. Dígitos tabular
   para que no se muevan al cambiar de número.
   ========================================== */
.productos-counter {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 0.15rem;
  font-family: var(--font-body);
  font-size: 0.85rem;
  font-weight: 700;
  color: var(--color-text-light);
  letter-spacing: 0.05em;
  margin: 0 0 1rem 0;
  padding: 0 0.5rem;
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum";
}
.productos-counter #productosIdx {
  color: var(--color-primary);
  transition: opacity var(--dur-tap) var(--ease-out);
}

/* ==========================================
   1. CARRUSEL PRODUCTOS EN MÓVIL — 84vw con peek
   El scroll nativo con snap ya existe en style.css;
   aquí solo ajusto el ancho de card y el padding para
   que se asome la vecina.
   ========================================== */
@media (max-width: 768px) {
  .productos-grid {
    padding-left: 8vw;
    padding-right: 8vw;
    scroll-padding-left: 8vw;
    gap: 0.75rem;
  }
  .producto-card {
    flex: 0 0 84vw;
    width: 84vw;
    max-width: 340px;
    scroll-snap-align: center;
  }
  /* El swipe es la interacción principal en móvil; el indicador estorba */
  .productos-scroll-indicator {
    display: none;
  }
}

/* ==========================================
   2. AJUSTE AL SCROLL REVEAL EXISTENTE
   El sistema .reveal / .revealed vive en style.css.
   Aquí bajo la duración a 350ms y el translate a 16px
   para respetar la regla de 150-400ms.
   ========================================== */
.reveal {
  transform: translateY(28px);
  transition-duration: 400ms;
  transition-timing-function: var(--ease-out);
}

/* ==========================================
   TORTILLAS HERO — PINNED SCROLL "TEATRO"
   Sección de 200vh. Adentro un track sticky de 100vh
   con 2 paneles absolutos superpuestos (Maíz y Moringa).
   El JS calcula el progreso 0-1 dentro de la sección y
   aplica opacity + perspective + rotateX + scale +
   translateY para el cross-fade con sensación 3D.

   Rompe conscientemente la regla anterior "no fijar
   secciones a pantalla completa" — aprobado por el
   product owner para lograr el efecto Apple-style.
   Solo transform + opacity (no width/height animadas).
   ========================================== */
.tortillas-hero {
  position: relative;
  height: 200vh;
  background: linear-gradient(180deg, #FFFFFF 0%, #F9F9F9 100%);
}
.th-track {
  position: sticky;
  top: 0;
  height: 100vh;
  overflow: hidden;
  perspective: 1200px;
  perspective-origin: center 40%;
}
.th-panel {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem 1.5rem;
  transform-style: preserve-3d;
  will-change: transform, opacity;
}
.th-panel[data-panel="2"] {
  /* Estado inicial: totalmente fuera hasta que el JS empiece a mostrarlo */
  opacity: 0;
}
.th-panel-inner {
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: auto auto;
  gap: 1.5rem;
  align-items: center;
  justify-items: center;
  width: 100%;
  max-width: 1100px;
  text-align: center;
}
.th-photo {
  width: min(85vw, 380px);
  aspect-ratio: 1 / 1;
  display: flex;
  align-items: center;
  justify-content: center;
}
.th-photo img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
  filter: drop-shadow(0 20px 40px rgba(0, 0, 0, 0.15));
}
.th-text {
  max-width: 500px;
}
.th-eyebrow {
  font-size: 0.85rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 3px;
  color: var(--color-accent);
  margin-bottom: 0.75rem;
}
.th-title {
  font-family: var(--font-heading);
  font-size: clamp(2.4rem, 6vw, 4rem);
  line-height: 1.05;
  color: var(--color-primary);
  margin-bottom: 1rem;
}
.th-desc {
  font-size: clamp(1rem, 2vw, 1.15rem);
  color: var(--color-text-light);
  line-height: 1.6;
  margin-bottom: 1.25rem;
}
.th-price {
  font-family: var(--font-heading);
  font-size: 2.2rem;
  font-weight: 700;
  color: var(--color-primary);
  margin-bottom: 1.5rem;
}
.th-price span {
  font-size: 1rem;
  font-weight: 400;
  color: var(--color-text-light);
}

/* Layout de escritorio: foto a un lado, texto al otro */
@media (min-width: 900px) {
  .th-panel-inner {
    grid-template-columns: 1fr 1fr;
    grid-template-rows: 1fr;
    gap: 4rem;
    text-align: left;
    justify-items: stretch;
  }
  .th-panel[data-panel="1"] .th-panel-inner {
    /* Maíz: foto izquierda, texto derecha */
  }
  .th-panel[data-panel="2"] .th-panel-inner {
    /* Moringa: texto izquierda, foto derecha (para variar el ritmo visual) */
    direction: rtl;
  }
  .th-panel[data-panel="2"] .th-text {
    direction: ltr;
  }
  .th-photo {
    width: min(45vw, 500px);
    justify-self: center;
  }
  .th-text {
    align-self: center;
    justify-self: center;
    max-width: 480px;
  }
}

/* Indicador visual de scroll (chevron discreto abajo) */
.tortillas-hero::after {
  content: '';
  position: absolute;
  left: 50%;
  bottom: 24px;
  width: 24px;
  height: 24px;
  border-right: 2px solid rgba(0, 0, 0, 0.25);
  border-bottom: 2px solid rgba(0, 0, 0, 0.25);
  transform: translateX(-50%) rotate(45deg);
  opacity: 0;
  animation: th-chevron 2s ease-in-out infinite;
  pointer-events: none;
}
@keyframes th-chevron {
  0%   { opacity: 0; transform: translateX(-50%) translateY(-6px) rotate(45deg); }
  50%  { opacity: 0.8; }
  100% { opacity: 0; transform: translateX(-50%) translateY(6px) rotate(45deg); }
}

/* Con reduced-motion no queremos que el track sea sticky ni que use 3D:
   colapsar a un layout normal donde los 2 paneles se ven uno abajo del otro. */
@media (prefers-reduced-motion: reduce) {
  .tortillas-hero { height: auto; }
  .th-track { position: static; height: auto; perspective: none; }
  .th-panel { position: static; opacity: 1 !important; transform: none !important; min-height: 60vh; }
  .th-panel[data-panel="2"] { opacity: 1; }
  .tortillas-hero::after { display: none; }
}

/* ==========================================
   REDUCED MOTION
   Anula toda animación cuando el usuario prefiere menos motion.
   Los elementos con opacidad/transform quedan en su estado final.
   ========================================== */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-delay: 0ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    transition-delay: 0ms !important;
    scroll-behavior: auto !important;
  }
  .hero-eyebrow, .hero-title, .hero-slogan,
  .hero-subtitle, .hero-actions, .hero-badges,
  .whatsapp-float, .reveal {
    opacity: 1 !important;
    transform: none !important;
  }
}
