/* ============================================================
   1. RESET & VARIABLES
   ============================================================ */
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

/* Paleta y tokens del sitio, unicos lugar donde se definen. Si hay que
   cambiar un color/sombra/radio se toca aqui y se propaga en todo el
   sitio; nunca usar valores sueltos en las reglas. */
:root {
  /* Marca: teal principal, su oscuro para hover/estados y dos cremas
     (uno "claro" y otro suave para fondos de bloques). */
  --brand-teal: #44858f;
  --brand-teal-dark: #356b73;
  --brand-cream: #f6e0c5;
  --brand-cream-soft: #fef5e8;
  /* Texto: tono principal (teal oscuro) y version apagada para detalles. */
  --text-main: #24454b;
  --text-muted: #5a7074;
  /* Sombras: de la mas sutil (tarjetas planas) a la mas marcada
     (tarjetas de producto, video). */
  --shadow-light: 0 6px 18px rgba(0, 0, 0, 0.04);
  --shadow-medium: 0 14px 40px rgba(0, 0, 0, 0.06);
  --shadow-heavy: 0 18px 40px rgba(0, 0, 0, 0.08);
  /* Radios de tarjeta comun y de detalles chicos. */
  --border-radius: 22px;
  --border-radius-small: 12px;
  /* Variantes de uso puntual. */
  --brand-teal-light: rgba(68, 133, 143, 0.1);
  --accent-gold: #d4a373;
  /* Curva ease-out con mas "empuje" que la ease-out nativa del navegador
     (demasiado debil, se siente perezosa) -- usada solo en el splash. */
  --ease-out-strong: cubic-bezier(0.23, 1, 0.32, 1);
  scroll-behavior: smooth;
}

/* ============================================================
   2. BASE STYLES
   ============================================================ */
html {
  overflow-x: hidden;
  width: 100%;
}

body {
  font-family: 'Montserrat', system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  background: #ffffff;
  color: var(--text-main);
  position: relative;
  overflow-x: hidden;
  width: 100%;
}

/* Textura de ruido sutil sobre TODO el sitio: un SVG de fractal (feTurbulence)
   en data URI, fijo sobre la ventana, con opacidad muy baja. Le da al fondo
   blanco un acabado "de papel" sin peso (no es una imagen de red). Con
   pointer-events:none nunca estorba a clicks ni seleccion. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.035'/%3E%3C/svg%3E");
  pointer-events: none;
  z-index: 0;
}

/* Los bloques de contenido quedan por encima del ruido fijo de body::before
   (z-index 0); sin esto el ruido podria taparlos al superponerse. */
header,
.container,
section,
footer {
  position: relative;
  z-index: 1;
}

/* ============================================================
   3. NAVBAR
   ============================================================
   Arranca invisible (opacity:0 + translateY(-20px) + pointer-events:none)
   para no molestar mientras se ve el splash/hero. JS le agrega .visible al
   scrollear (baja deslizandose) y .scrolled para subir el contraste del
   fondo. Sin .visible no es clicable aun estando fija arriba. */
.navbar {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  background: rgba(255, 255, 255, 0.12);
  /* pedido 2026-08-04 (audit de rendimiento): blur(8px) -> blur(4px).
     backdrop-filter es de lo mas caro de componer en pantalla, y este
     elemento es position:fixed (siempre visible) -- el navegador vuelve a
     calcular el difuminado de TODO lo que hay debajo en cada frame,
     mientras dure cualquier otra animacion en pantalla (scroll, carrusel,
     fade-up...). Un radio mas chico sigue leyendose como "vidrio
     esmerilado" pero es bastante mas barato de recomponer. */
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
  z-index: 1000;
  padding: calc(1rem + env(safe-area-inset-top, 0px)) 0 1rem;
  border-bottom: 1px solid rgba(68, 133, 143, 0.1);
  opacity: 0;
  transform: translateY(-20px);
  pointer-events: none;
  transition: opacity 0.4s ease, transform 0.4s ease, background 0.3s ease, box-shadow 0.3s ease;
}

/* Estado con scroll > 50px: fondo mas presente + sombra para despegar la
   barra del contenido. La clase la pone initNavbarEffect() en js/main.js. */
.navbar.scrolled {
  background: rgba(255, 255, 255, 0.2);
  box-shadow: 0 4px 15px rgba(0, 0, 0, 0.06);
}

/* Estado visible (scroll > 0): aparece y vuelve a recibir clicks. */
.navbar.visible {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}

.nav-container {
  max-width: 1200px;
  margin: 0 auto;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 2rem;
}

.nav-logo {
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: 700;
  letter-spacing: 0.1em;
  color: var(--brand-teal);
  text-decoration: none;
  font-size: 1.1rem;
}

.nav-logo-img {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  object-fit: cover;
}

.nav-links {
  list-style: none;
  display: flex;
  gap: 25px;
}

.nav-links a {
  text-decoration: none;
  color: var(--brand-teal);
  font-size: 0.85rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  transition: color 0.3s ease;
}

.nav-links a:hover {
  color: var(--brand-teal);
}

/* Item "Perfect Fit" del menu: solo existe en escritorio (donde los dos
   pantalones estan en fila y se colapsan en un solo destino). En movil se
   oculta; desktop.css lo vuelve a mostrar. */
.nav-links .nav-pc-only {
  display: none;
}

/* Icono hamburguesa: se oculta en escritorio (display:none) y aparece en
   el breakpoint de movil (ver @media max-width:768px). Las tres .bar las
   dibuja/pinta JS (updateBarsColor en js/main.js) segun el estado del menu. */
.menu-toggle {
  display: none;
  flex-direction: column;
  gap: 5px;
  background: none;
  border: none;
  cursor: pointer;
}

.menu-toggle .bar {
  width: 25px;
  height: 3px;
  background-color: #44858f;
  border-radius: 2px;
  transition: 0.3s;
}

/* ============================================================
   4. LAYOUT & COMPONENTES COMUNES
   ============================================================ */
.container {
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 2rem;
  background: none;
  border-radius: 0;
  box-shadow: none;
}

.section-header {
  text-align: center;
  margin-bottom: 3.5rem;
}

/* Oculta visualmente pero mantiene accesible para lectores de pantalla / SEO,
   sin ocupar espacio y sin empujar el carrusel full-bleed (100dvh) hacia abajo. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.section-header h2 {
  font-size: 2.2rem;
  color: #44858f;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  display: block;
  margin-bottom: 8px;
}

.section-header p {
  font-size: 0.95rem;
  color: #5a7074;
  margin-top: 5px;
  font-weight: 500;
  letter-spacing: 0.02em;
}

.pill {
  display: inline-block;
  padding: 0.3rem 0.75rem;
  border-radius: 999px;
  background: var(--brand-teal);
  color: #ffffff;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.15em;
}

/* Separador entre secciones: una simple linea teal translucida con respiro
   vertical. No es el mismo que .brand-footer-line (que va dentro del footer)
   ni el banner teal completo (.perfect-fit-divider-banner). */
.section-divider {
  border: none;
  border-top: 1px solid rgba(68, 133, 143, 0.15);
  margin: 2.5rem 0;
}

/* Banner de transicion entre el video y Perfect Amistad -- el corte era
   demasiado abrupto (video termina y arranca el carrusel sin respiro).
   Solo va aqui, no reemplaza los demas .section-divider del sitio. */
/* Mas delgado y con el logo mas chico (pedido del usuario) para que no
   compita con el "Sweet Harmony" del footer justo debajo. */
.perfect-fit-divider-banner {
  width: 100vw;
  margin: 0 calc(-50vw + 50%);
  background: var(--brand-teal);
  padding: 0.66rem 0;
  text-align: center;
}

.perfect-fit-divider-logo {
  width: min(27%, 120px);
  height: auto;
}

/* Franja superior de la seccion Perfect Amistad (solo movil): version
   invertida del banner divisor (el del video->footer). Ese banner es
   fondo teal + logo crema; este es fondo BLANCO + logo teal, para llevar
   el badge "PERFECT FIT" fuera de la foto (que en movil no queda bien).
   Va ARRIBA de la seccion, ocupando el lugar de la linea gris de separacion
   que habia entre Blusas y Perfect Amistad (esa <hr> se quito del HTML).
   pedido 2026-08-04: sin margen, ni arriba ni abajo -- el usuario pidio
   quitar el espacio en blanco, no reubicarlo. */
.pa-amistad-footer-banner {
  width: 100vw;
  margin: 0 calc(-50vw + 50%);
  background: #ffffff;
  padding: 0.66rem 0;
  text-align: center;
}

.pa-amistad-footer-logo {
  width: min(27%, 120px);
  height: auto;
}

/* ============================================================
   5. PERFECT FIT SECTION
   ============================================================ */
.perfectfit-section {
  text-align: center;
}

.perfectfit-illustration {
  position: relative;
  width: 100vw;
  max-width: 100vw;
  margin: 0 calc(-50vw + 50%);
}

.perfectfit-image {
  display: block;
  width: 100%;
  height: 100vh;
  height: 100dvh;
  object-fit: cover;
  object-position: center;
  background: #ffffff;
  border-radius: 0;
}

/* Ilustraciones de cuerpo completo (no fotos): deben verse enteras, sin
   recortar nada, aunque queden franjas blancas a los lados. */
.perfectfit-image-contain {
  object-fit: contain;
}

/* La foto de hero-02 tiene ~15% de espacio en blanco real arriba para que
   caiga el banner "No existe el cuerpo perfecto" (ver CHANGELOG, commit
   5065776). Con object-position:center, en viewports mas anchos/bajos el
   recorte de object-fit:cover comia parejo de arriba y de abajo, perdiendo
   ese espacio en blanco -- el banner terminaba tapando el pelo de las
   modelos. object-position:top fuerza a que el recorte siempre salga por
   abajo, nunca por arriba, sin importar el aspect ratio del viewport. */
.perfectfit-image-top {
  object-position: top;
}

/* Cover inicial: contenedor recorta el margen que deja el rotate/scale del parallax */
.hero-cover {
  overflow: hidden;
}

.hero-cover-image {
  will-change: transform;
  transform-origin: center center;
}

/* Textos del cover inicial: opacity controlada por JS en scroll (parallax),
   fade-up sigue controlando solo la entrada inicial sincronizada con el splash */
.hero-intro-anim {
  will-change: opacity;
}

/* 5.1 Hero Brand Overlay (SWEET HARMONY) */
.hero-brand-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  pointer-events: none;
  padding-top: 2%;
}

/* Slide 2 del hero ("No existe el cuerpo perfecto"): la franja teal era parte
   de la foto (se recortaba distinto segun el dispositivo, a veces ni se veia).
   Ahora es una barra CSS real, con padding que crece con el texto en vez de
   un alto fijo, para que el texto nunca se salga del fondo en ninguna pantalla. */
.hero-brand-overlay.zoom-in {
  align-items: flex-start;
  padding-top: 0;
}

.brand-title-overlay {
  line-height: 1.05;
  text-align: center;
}

/* Logo real "Sweet Harmony" (archivo entregado por el usuario) en vez de
   texto CSS reimplementado -- reemplaza a .sweet/.harmony en la portada. */
.brand-title-logo {
  width: min(70%, 320px);
  height: auto;
}

.brand-title-overlay .sweet {
  display: block;
  font-size: 2.4rem;
  font-weight: 400;
  letter-spacing: 0.24em;
  color: var(--brand-teal);
}

.brand-title-overlay .harmony {
  display: block;
  font-size: 2.8rem;
  font-weight: 900;
  letter-spacing: 0.18em;
  color: var(--brand-teal);
}

/* 5.2 Hero Bottom Overlay (Toda mujer / Merece / Verse bien) */
.hero-bottom-overlay {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 2%;
  text-align: center;
  pointer-events: none;
}

.hero-bottom-overlay p {
  font-size: 1.5rem;
  font-weight: 400;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--brand-teal);
  line-height: 1.3;
}

.hero-bottom-overlay .merece-line {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  font-weight: 700;
  font-size: 1.8rem;
}

.hero-bottom-overlay .rule {
  width: 34px;
  height: 2px;
  background: var(--brand-teal);
}

/* Pista de scroll del hero-01: mismo glifo/estilo que .carousel-arrow,
   rotado 90deg para apuntar hacia abajo, con rebote continuo para invitar
   a bajar. Solo movil -- desktop.css la oculta (el hero ahi no es
   full-bleed por pantalla, no aplica el gesto de "deslizar").
   Va a la derecha (no centrada, y no a la izquierda -- probado y
   descartado por el usuario) en vez de bottom:4% centrado: medido con
   getBoundingClientRect(), centrada caia DENTRO del bloque de texto
   ".hero-bottom-overlay" (Toda mujer/Merece/Verse bien, bottom:2% y crece
   hacia arriba con 3 lineas) -- se veia la flecha parpadeando encima de
   "Verse bien". No hay hueco libre debajo del texto para moverla mas abajo
   (el texto ya llega casi al borde de pantalla), asi que se corre al
   costado derecho, lejos del texto centrado y del boton de WhatsApp
   (fixed, bottom:140-712px/right:313-373px -- no colisiona con esta
   franja mas baja, y:803-818px). */
.hero-scroll-hint {
  position: absolute;
  right: 8%;
  bottom: 4%;
  transform: rotate(90deg);
  font-size: 1.8rem;
  font-weight: 900;
  line-height: 1;
  color: rgba(255, 255, 255, 0.75);
  filter: blur(1px) drop-shadow(0 1px 3px rgba(0, 0, 0, 0.35));
  pointer-events: none;
  z-index: 2;
  animation: heroScrollHintBounce 1.8s ease-in-out infinite;
}

/* pedido del usuario 2026-08-04: el rebote se veia HORIZONTAL en vez de
   vertical. Causa: el orden de las funciones de transform importa -- cada
   funcion opera dentro del sistema de coordenadas que dejaron las
   anteriores (las de su IZQUIERDA). Con "rotate(90deg) translateY(8px)"
   (el orden que tenia antes), el rotate se aplica primero y gira el eje Y
   local 90 grados, asi que el translateY que viene despues termina
   moviendose sobre ese eje YA ROTADO -- visualmente para el lado, no hacia
   abajo. Se invierte el orden a "translateY(...) rotate(90deg)": ahora el
   translateY corre primero, en el eje Y real de pantalla (vertical), y el
   rotate se aplica despues solo para orientar el glifo, sin heredar el
   desplazamiento. */
@keyframes heroScrollHintBounce {
  0%, 100% { transform: translateY(0) rotate(90deg); }
  50% { transform: translateY(8px) rotate(90deg); }
}

/* 5.3 Textos Imagen 2 */
.cuerpo-perfecto-text {
  font-family: 'Montserrat', sans-serif;
  font-size: 1.7rem;
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  line-height: 1.35;
  text-align: center;
  color: #ffffff;
  width: 100%;
  box-sizing: border-box;
  background: var(--brand-teal);
  padding: 1.3rem 1.5rem;
  margin: 0;
  /* Cubre una linea blanca de sub-pixel que aparecia entre la caja y la
     foto de abajo (redondeo del navegador al escalar la imagen) -- no
     ocupa espacio en el layout, solo pinta 2px de mas hacia abajo. */
  box-shadow: 0 2px 0 var(--brand-teal);
}

@media (max-width: 480px) {
  .cuerpo-perfecto-text {
    font-size: 1.4rem;
    padding: 1.1rem 1rem;
  }
}

/* Logo real (img/logos/pantalon-correcto-teal.svg) en vez de texto CSS
   reimplementado -- reemplaza a la antigua .pantalon-correcto-text. */
.pantalon-correcto-logo {
  width: min(78%, 340px);
  height: auto;
}

/* ============================================================
   5.4 PERFECT FIT DESCRIPTIVA (3ra imagen del hero)
   ============================================================
   Composición sobre hero-03-ilustracion-perfect-fit.webp: badge "Perfect
   Fit", medallón "Ajuste inteligente" y 3 flechas señalando tiro alto,
   piernas y bota. PRIMERA PASADA de posiciones -- no hay mockup de
   referencia a mano todavía, así que estos % son un punto de partida para
   ajustar a ojo contra la ilustración real, no una medición exacta. */
/* El usuario pidió quitar el fondo teal solido (boton-perfect-fit.webp):
   ahora es solo el logo, sin caja de color detrás -- fondo blanco/transparente. */
.pfd-badge {
  position: absolute;
  top: 3%;
  left: 5%;
  width: 40%;
}

.pfd-badge-logo {
  display: block;
  width: 100%;
  height: auto;
}

.pfd-medallion {
  position: absolute;
  top: 42%;
  left: 19%;
  width: 32%;
  height: auto;
}

.pfd-arrow {
  position: absolute;
  height: auto;
}

/* Contenido real: "Tiro alto favorecedor" (ver comentario en index.html) */
.pfd-arrow-tiro {
  top: 28%;
  left: 57%;
  width: 30%;
}

/* Contenido real: "Piernas largas y definidas" -- pedido del usuario: la
   linea/cota quedaba muy encima del pantalon, se corre un poco a la
   derecha (left 65% -> 70%, mismo width/height/top). Aplica igual en
   escritorio porque desktop.css no sobreescribe left para esta flecha. */
.pfd-arrow-piernas {
  top: 40%;
  left: 70%;
  width: 22%;
  height: 42%;
}

.pfd-arrow-bota {
  top: 83%;
  left: 12%;
  width: 32%;
}

/* Texto horneado en la foto vieja (hero-03-letrero-perfect-fit.webp),
   recreado como HTML real ahora que la ilustración limpia no lo trae.
   Primera pasada de posición -- abajo a la izquierda de la ilustración. */
.pfd-copy {
  position: absolute;
  left: 4%;
  bottom: 62%;
  width: 46%;
  text-align: left;
  pointer-events: none;
}

.pfd-copy p {
  font-family: 'Montserrat', sans-serif;
  font-weight: 400;
  font-size: 0.66rem;
  line-height: 1.4;
  color: var(--brand-teal);
  margin: 0 0 0.5em;
  color: #000000;
}

.pfd-copy strong {
  font-weight: 700;
}

/* ============================================================
   5.5 DIFUMINADO AL PIE DE CADA FOTO (hero, video, carruseles)
   ============================================================
   Franja con degradado en la base de cada foto full-bleed, para que el
   cambio a la siguiente imagen/sección se sienta como transición suave en
   vez de corte seco. Va como ::before (primer hijo) para que quede DETRÁS
   de la imagen y de los overlays (que son hijos posteriores en el DOM) sin
   necesidad de z-index -- no tapa textos/botones que ya están cerca del
   borde inferior (nota de mayoristas, botón de pedido, dots, flechas de
   hero-03).
   Degradado a BLANCO (confirmado por el usuario) -- en los slides donde la
   foto ya es blanca/clara hasta el borde el efecto se nota poco, pero es
   el look pedido para todo el sitio, hero incluido hasta el video. */
.perfectfit-illustration::before,
.carousel-fullscreen .carousel-slide::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 15%;
  background: linear-gradient(to bottom, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.92) 100%);
  pointer-events: none;
}

/* El video pidió explícitamente sin difuminado (el usuario lo señaló como
   el único punto donde no debía ir, a diferencia del resto del sitio). */
#video .perfectfit-illustration::before {
  display: none;
}

/* hero-03 (la ilustración "Perfect Fit descriptiva") tampoco lo lleva: usa
   object-fit:contain, así que no llena el marco completo y el difuminado
   quedaba visible sobre el fondo blanco/vacío cerca de los pies de la
   modelo dibujada -- se notaba como una sombra que no debía estar ahí. */
.perfectfit-illustration:has(.perfectfit-image-contain)::before {
  display: none;
}

/* En los carruseles el degradado blanco se nota poco (fotos ya claras hasta
   el borde) -- más alto y con el blanco lleno antes de llegar arriba, para
   que alcance a notarse. */
.carousel-fullscreen .carousel-slide::before {
  height: 30%;
  background: linear-gradient(to bottom, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.95) 55%, rgba(255, 255, 255, 1) 100%);
}

/* pedido 2026-08-04: esta slide (rack con los pantalones + zapatos abajo)
   pidio el difuminado, pero el ::before de la regla general queda DEBAJO
   de la foto en el orden de pintado (::before siempre pinta antes que los
   hijos reales del elemento, y la foto es hija) -- existe pero es
   invisible, tapado por la foto encima. Solo esta slide sube su ::before
   por encima con z-index; las demas quedan igual (no se toco la regla
   general ni ninguna otra slide). */
.carousel-fullscreen .carousel-slide.pa-entiende-slide::before {
  z-index: 1;
  height: 18%;
}

/* El z-index de arriba tambien subia el difuminado por ENCIMA del texto
   ("Puede estar contigo..."), no solo de la foto -- .carousel-image-frame
   (donde vive ese texto) no tenia z-index propio, asi que quedaba debajo
   del ::before. Se le da z-index mayor para que el difuminado se vea
   sobre la foto pero el texto siga por encima de todo. */
.carousel-fullscreen .carousel-slide.pa-entiende-slide .carousel-image-frame {
  z-index: 2;
}

/* pedido 2026-08-04: esta slide (dos modelos apiladas + franja teal) no
   necesita el difuminado blanco del pie -- cae sobre el cuerpo de la
   segunda modelo (blusa menta) y se ve como una foto mal recortada, no
   como una transicion. */
.carousel-fullscreen .carousel-slide.blusas-sweet-slide::before {
  display: none;
}

/* ============================================================
   6. CARRUSELES
   ============================================================
   Mecanica: el track es una fila de slides de 100% cada uno; JS (initCarousel
   en js/main.js) mueve el track con translateX(-indice*100%) y los dots.
   Cada li.carousel-slide lleva la foto full-bleed (position:absolute dentro
   del slide) y un .carousel-image-frame con los overlays HTML encima.
   ============================================================ */
.carousel {
  position: relative;
  max-width: 420px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

/* Variante full-bleed de los carruseles de producto: sale del contenedor
   (.container max-width:1200px) usando margenes negativos y ocupa los
   100vw reales, como el hero y el video. */
.carousel-fullscreen {
  display: block;
  width: 100vw;
  max-width: 100vw;
  margin: 0 calc(-50vw + 50%);
}

.carousel-viewport {
  flex: 1;
  overflow: hidden;
  border-radius: var(--border-radius);
  box-shadow: var(--shadow-medium);
  background: var(--brand-cream-soft);
  /* Le dice al navegador que el scroll vertical de la pagina se maneja de
     forma nativa aqui (no hay que esperar a ver si el gesto es un swipe
     horizontal del carrusel antes de decidir) -- sin esto, un scroll
     vertical normal sobre el carrusel podia sentirse trabado/a saltos
     porque el navegador dudaba entre paginar y deslizar el track. El
     swipe horizontal lo sigue resolviendo el JS (touchstart/touchend en
     initCarousel), que ademas ahora descarta gestos mayormente verticales. */
  touch-action: pan-y;
}

.carousel-fullscreen .carousel-viewport {
  border-radius: 0;
  box-shadow: none;
  background: none;
}

/* El track se desplaza como bloque: cada slide ocupa el 100% y la
   transicion suaviza el cambio de imagen. */
.carousel-track {
  display: flex;
  list-style: none;
  transition: transform 0.4s ease;
}

.carousel-slide {
  flex: 0 0 100%;
  text-align: center;
  padding: 1.2rem 1.2rem 1.6rem;
  position: relative;
}

/* Contenedor restaurado (existia en landingv1, se habia quitado por error
   al hacer el hero full-bleed): Push Up, Marlene, Blusas y Perfect Amistad
   llevan un pequeño respiro lateral -- el hero y el video no usan esta
   clase, siguen full-bleed sin tocarlos. */
.carousel-fullscreen .carousel-slide {
  padding: 1.1rem;
  height: 100vh;
  height: 100dvh;
}

.carousel-slide img {
  width: 100%;
  max-height: 380px;
  object-fit: contain;
  border-radius: var(--border-radius-small);
}

/* position:absolute + inset:0 (en vez de height:100dvh en flujo normal)
   para que la foto quede exactamente en el mismo cuadro que
   .carousel-image-frame -- antes, el padding empujaba el frame pero la
   foto (en flujo normal) lo ignoraba, dejando una franja en blanco al
   fondo donde los overlays (ej. el texto de mayoristas) caian fuera de
   la foto. */
.carousel-fullscreen .carousel-slide img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  max-height: none;
  object-fit: cover;
  object-position: center;
  background: #ffffff;
  border-radius: 0;
}

/* Los percheros (blusas-05/06) son fotos retrato igual que el resto del
   carrusel (880x1759 y 888x1776, ratio ~0.5), asi que NO llevan tratamiento
   especial: usan la regla full-bleed de arriba (object-fit:cover). El
   intento previo con contain + scale(1.22) dejaba la foto flotando en una
   caja blanca, recortaba el pie (fila de puntos de color) y empujaba la
   nota de mayoristas fuera de pantalla -- todo revertido. */

/* Slides de "Material" (texturas Drill/Twill): tarjeta chica centrada,
   no full-bleed como el resto del carrusel. */
.carousel-fullscreen .carousel-slide.material-slide {
  display: flex;
  align-items: center;
  justify-content: center;
  background: #ffffff;
}

.carousel-fullscreen .carousel-slide.material-slide img {
  position: static;
  width: min(64vw, 380px);
  height: min(46vh, 380px);
  object-fit: cover;
  border-radius: 0;
  box-shadow: var(--shadow-medium);
}

/* Descripción del material (Drill/Twill), centrada abajo en la franja
   blanca del slide -- lo que va en negrita lo marca el <strong>. */
.material-description {
  position: absolute;
  left: 9%;
  right: 9%;
  bottom: 9%;
  text-align: center;
  font-family: 'Montserrat', sans-serif;
  font-weight: 400;
  font-size: 0.8rem;
  line-height: 1.45;
  color: var(--text-main);
  pointer-events: none;
}

.material-description strong {
  font-weight: 700;
}

/* Carrusel flechas: glifo grueso semitransparente, sin burbuja circular */
.carousel-arrow {
  -webkit-appearance: none;
  appearance: none;
  flex: 0 0 auto;
  width: auto;
  height: auto;
  padding: 6px 4px;
  border-radius: 6px;
  border: none;
  background: none;
  color: rgba(255, 255, 255, 0.6);
  font-size: 2rem;
  font-weight: 900;
  line-height: 1;
  cursor: pointer;
  filter: blur(1px) drop-shadow(0 1px 3px rgba(0, 0, 0, 0.35));
  transition: transform 0.2s ease, opacity 0.2s ease;
}

.carousel-fullscreen .carousel-arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 5;
}

.carousel-fullscreen .carousel-prev { left: 16px; }
.carousel-fullscreen .carousel-next { right: 16px; }

.carousel-arrow:hover {
  transform: scale(1.08);
}

.carousel-fullscreen .carousel-arrow:hover {
  transform: translateY(-50%) scale(1.08);
}

/* Aviso de "hay mas contenido a los lados": JS (initCarousel) agrega
   .carousel-swipe-hint al carrusel la primera vez que entra en pantalla.
   Las flechas hacen un vaiven horizontal corto (3 veces) para que quede
   claro que la seccion se desliza -- combina con translateY(-50%), que ya
   las centra verticalmente (mismo patron de "combinar transforms" del
   resto del sitio: si no, la animacion pisaria el centrado). */
.carousel-swipe-hint .carousel-prev {
  animation: carouselArrowHintPrev 1s ease-in-out 3;
}

.carousel-swipe-hint .carousel-next {
  animation: carouselArrowHintNext 1s ease-in-out 3;
}

/* pedido del usuario 2026-08-04: en computador se sentia "en dos tiempos"
   -- el keyframe original metia DOS idas-y-vueltas completas dentro de un
   solo ciclo de animation-duration (0%->20%->40%->60%->80%->100%), asi que
   cada ida-y-vuelta real ocupaba solo la mitad del tiempo declarado. Se
   simplifica a UNA sola ida-y-vuelta por ciclo (0%->50%->100%), igual que
   ya hace .heroScrollHintBounce -- mismo patron ya usado en la pagina, en
   vez de uno inventado aparte. Con esto cada ida-y-vuelta pasa a ocupar el
   1s completo (el doble de lo que ocupaba antes), sin tocar la duracion ni
   el numero de repeticiones (1s ease-in-out 3, sin cambios). */
@keyframes carouselArrowHintPrev {
  0%, 100% { transform: translateY(-50%) translateX(0); }
  50% { transform: translateY(-50%) translateX(-8px); }
}

@keyframes carouselArrowHintNext {
  0%, 100% { transform: translateY(-50%) translateX(0); }
  50% { transform: translateY(-50%) translateX(8px); }
}

/* Carrusel dots */
.carousel-dots {
  position: absolute;
  bottom: -1.6rem;
  left: 0;
  right: 0;
  display: flex;
  justify-content: center;
  gap: 8px;
}

.carousel-fullscreen .carousel-dots {
  bottom: 3px;
  z-index: 5;
}

.carousel-dot {
  -webkit-appearance: none;
  appearance: none;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: rgba(68, 133, 143, 0.3);
  border: none;
  cursor: pointer;
  padding: 0;
  transition: background 0.2s ease;
}

.carousel-dot.active {
  background: var(--brand-teal);
}

/* Frame para overlays dentro del carrusel */
.carousel-image-frame {
  /* Antes tenia aspect-ratio:1/2.01, calibrado para cuando la imagen usaba
     object-fit:contain (se letterboxeaba a esa proporcion exacta). Ahora que
     la imagen es object-fit:cover y llena TODO el viewport del slide, el
     frame tiene que ser el viewport completo -- si no, en dispositivos con
     una proporcion de pantalla distinta a 1:2.01 los overlays (precio, boton,
     nombre de referencia) quedan desplazados o superpuestos, porque los % de
     cada overlay se miden contra este frame, no contra la imagen visible. */
  position: absolute;
  inset: 0;
  pointer-events: none;
}

/* ============================================================
   6.1 CARRUSEL PUSH UP & MARLENE
   ============================================================ */
.pf-badge {
  position: absolute;
  top: 6%;
  left: 6%;
  pointer-events: none;
}

/* Logo real (img/logos/perfect-fit-teal.svg) en vez de texto CSS
   reimplementado -- reemplaza a las antiguas .pf-perfect/.pf-fit/.pf-t. */
.carousel-fullscreen .carousel-slide img.pf-badge-logo {
  position: static;
  width: 180px;
  height: auto;
  max-height: none;
  object-fit: contain;
  background: transparent;
}

.pf-order-btn {
  position: absolute;
  left: 50%;
  bottom: 10%;
  transform: translateX(-50%);
  display: inline-block;
  padding: 0.7rem 3.8rem;
  border-radius: 999px;
  background: var(--brand-teal);
  color: #ffffff;
  font-family: 'Montserrat', sans-serif;
  font-weight: 700;
  font-size: 1rem;
  text-decoration: none;
  text-align: center;
  white-space: nowrap;
  box-shadow: var(--shadow-medium);
  pointer-events: auto;
  cursor: pointer;
  transition: background 0.2s ease, transform 0.2s ease;
}

.pf-order-btn:hover {
  background: var(--brand-teal-dark);
  transform: translateX(-50%) scale(1.05);
}

/* Texto de mayoristas: existia horneado en las fotos originales de Push
   Up/Marlene, se perdio al recortar "Tallas" de esas fotos y nunca se
   repuso como texto real. Posicion medida contra IMAGEN PUSH UP 3.png. */
.pf-wholesale-note {
  position: absolute;
  left: 50%;
  bottom: 3%;
  transform: translateX(-50%);
  width: 66%;
  text-align: center;
  pointer-events: none;
  font-family: 'Montserrat', sans-serif;
  font-style: italic;
  font-weight: 500;
  font-size: 0.85rem;
  line-height: 1.3;
  color: var(--brand-teal);
}

/* pedido 2026-08-05: revertido el ancho especial de 72% -- partia la
   frase en un punto distinto al resto del sitio (todas las demas notas de
   mayoristas usan el width:66% base y cortan en "al por"). Usa el mismo
   66% que todas las demas para que envuelva igual en los dos percheros. */

/* pedido 2026-08-05: el "re-scroll" del encuadre (object-position hacia
   abajo) es SOLO para escritorio -- ver css/desktop.css. En movil los
   percheros usan fotos dedicadas (blusas-05/06-mobile.webp, ver <picture>
   en index.html) que ya estaban bien encuadradas, sin este problema. */

/* Difuminado a lo ancho de todo el contenedor, detras de la nota de
   mayoristas: sobre fotos con fondo oscuro/con textura (piernas, zapatos,
   telas) el texto no tenia contraste. Intenso abajo (base de la foto) y se
   va desvaneciendo hacia arriba hasta justo despues del texto -- ancho
   completo del slide (no solo el bloque del texto), para que no se vea una
   franja angosta con bordes sin difuminar a los lados.
   Va como ::before de .carousel-image-frame (no de .pf-wholesale-note ni
   del propio .carousel-slide): el frame ya pinta ENCIMA de la foto (es
   hermano posterior del <img> en el DOM) y ::before es siempre el primer
   hijo pintado dentro de el, asi que queda detras de los demas overlays
   (precio, tallas, boton, nota) sin taparlos.
   :has() limita esto a los slides que realmente tienen la nota de
   mayoristas (pantalones/blusas), sin afectar Material, Tallas, "10
   colores" ni las demas slides que no la llevan. */
.carousel-image-frame:has(.pf-wholesale-note)::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 22%;
  background: linear-gradient(to top, rgba(255, 255, 255, 0.95) 0%, rgba(255, 255, 255, 0.75) 45%, rgba(255, 255, 255, 0) 100%);
  pointer-events: none;
}

/* pedido 2026-08-04: en los percheros (blusas-05/06) este difuminado cae
   justo sobre las etiquetas de color horneadas en la foto (PALO ROSA,
   MENTA, etc.) y las lava/desvanece -- ahi no hace falta, el texto de
   mayoristas ya tiene suficiente contraste sobre el fondo casi blanco de
   la foto sin necesidad de este refuerzo. */
.blusas-rack-slide .carousel-image-frame:has(.pf-wholesale-note)::before {
  display: none;
}

/* Combina el centrado con .fade-up (mismo motivo que .pf-order-btn.zoom-in):
   sin esto, .fade-up pisa el translateX(-50%) por completo y el elemento
   queda pegado a la izquierda en vez de centrado. */
.pf-wholesale-note.fade-up {
  transform: translateX(-50%) translateY(40px);
}

.pf-wholesale-note.fade-up.show {
  transform: translateX(-50%) translateY(0);
}

/* Tallas: texto real en vez de depender del "Tallas + rango" horneado en la
   foto, para que nunca se corte sin importar el recorte de object-fit:cover
   en cada dispositivo. */
.pf-tallas-overlay {
  position: absolute;
  left: 50%;
  bottom: 17.5%;
  transform: translateX(-50%);
  text-align: center;
  pointer-events: none;
  width: 88%;
}

.pf-tallas-overlay.fade-up {
  transform: translateX(-50%) translateY(40px);
}

.pf-tallas-overlay.fade-up.show {
  transform: translateX(-50%) translateY(0);
}

.pf-tallas-label {
  font-family: 'Montserrat', sans-serif;
  font-weight: 700;
  font-style: italic;
  font-size: 1.3rem;
  color: #000000;
  margin: 0 0 8px;
}

/* Ancho medido en pixeles contra la referencia con diseño (IMAGEN PUSH UP 3.png):
   la pildora ocupa ~84% del frame, no solo el ancho del texto. */
.pf-tallas-pill {
  display: block;
  width: 100%;
  box-sizing: border-box;
  border: 2px solid #000000;
  border-radius: 999px;
  padding: 0.55rem 1.6rem;
  font-family: 'Montserrat', sans-serif;
  font-weight: 700;
  font-size: 1.15rem;
  color: #000000;
  background: rgba(255, 255, 255, 0.85);
  text-align: center;
}

/* Precio y color: mismo criterio que Tallas -- texto real en vez de
   horneado en la foto, para que no dependa de donde caiga el recorte
   de object-fit:cover en cada dispositivo.
   Posicion medida en pixeles contra IMAGEN PUSH UP 3.png (referencia con
   diseño ya aplicado): precio y bolita de color comparten el mismo eje
   central (~81% del ancho del frame), por eso van en un solo contenedor
   centrado en vez de dos overlays anclados a la derecha por separado. */
/* Anclado por la derecha (antes left:81% + translateX(-50%)) -- ese anclaje
   por centro podia desbordar el borde derecho del frame segun el ancho real
   de la pildora ($139.900 vs otros precios/nombres de color mas largos).
   right:6% garantiza que nunca se salga sin importar el ancho. */
.pf-price-color-overlay {
  position: absolute;
  right: 6%;
  top: 20%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  pointer-events: none;
}

.pf-price-pill {
  display: inline-block;
  background: var(--brand-teal);
  color: #ffffff;
  font-family: 'Montserrat', sans-serif;
  font-weight: 700;
  font-style: italic;
  font-size: 1.2rem;
  padding: 0.5rem 1.3rem;
  border-radius: 999px;
  white-space: nowrap;
}

.pf-color-swatch {
  display: block;
  width: 2.8rem;
  height: 2.8rem;
  border-radius: 50%;
  border: 1px solid rgba(0, 0, 0, 0.15);
}

.pf-color-name {
  font-family: 'Montserrat', sans-serif;
  font-weight: 500;
  font-size: 0.95rem;
  color: #000000;
  margin: 0;
}

.pf-color-swatch.color-arena { background: #c8a877; }
.pf-color-swatch.color-beige { background: #e6dbc7; }
.pf-color-swatch.color-negro { background: #111111; }
.pf-color-swatch.color-palo-rosa { background: #f2d2d8; }
.pf-color-swatch.color-rojo-carmin { background: #cc142c; }
.pf-color-swatch.color-menta { background: #c7e0da; }
.pf-color-swatch.color-mandarina { background: #f2a97a; }
/* Mapa de colores de las referencias: cada clase .color-<nombre> pintada
   con el color real de la tela, para no horneado en la foto. Si un nuevo
   color entra a catalogo se agrega su clase aqui. */

/* .zoom-in comparte la propiedad "transform" con el centrado de arriba;
   sin combinarlas explicitamente, la animacion pisa el translateX(-50%)
   por completo (transform no se combina solo, gana la regla que va despues
   en el archivo) y el boton queda pegado a la derecha en vez de centrado. */
.pf-order-btn.zoom-in {
  transform: translateX(-50%) scale(0.7);
}

.pf-order-btn.zoom-in.show {
  transform: translateX(-50%) scale(1);
}

.product-ref-overlay {
  position: absolute;
  right: 6%;
  bottom: 8%;
  display: inline-flex;
  flex-direction: column;
  align-items: flex-end;
  text-align: right;
  pointer-events: none;
}

.ref-label {
  font-family: 'Montserrat', sans-serif;
  font-style: italic;
  font-weight: 500;
  font-size: 1.15rem;
  color: var(--accent-gold);
  margin-bottom: 4px;
}

.ref-rule {
  display: block;
  width: 100%;
  height: 3px;
  background: var(--accent-gold);
  margin-bottom: 6px;
}

.ref-name {
  font-family: 'Montserrat', sans-serif;
  font-weight: 200;
  font-size: 3.4rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--accent-gold);
  line-height: 1;
}

/* Blusas (LILI/GRACE): mismo criterio de "Ref." + nombre que Push Up/Marlene
   (.ref-label/.ref-name) pero centrado arriba en vez de abajo a la derecha
   -- posicion pedida por el usuario, medida contra su referencia. */
.bl-ref-overlay {
  position: absolute;
  top: 4%;
  left: 0;
  right: 0;
  text-align: center;
  pointer-events: none;
}

.bl-ref-label {
  font-family: 'Montserrat', sans-serif;
  font-style: italic;
  font-weight: 500;
  font-size: 1.1rem;
  letter-spacing: 0.3em;
  color: var(--brand-teal);
  margin: 0 0 2px;
}

.bl-ref-name {
  font-family: 'Montserrat', sans-serif;
  font-weight: 700;
  font-size: 2.2rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--brand-teal);
  margin: 0;
}

.bl-price-overlay {
  position: absolute;
  top: 32%;
  left: 6%;
  pointer-events: none;
}

.material-centered-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  pointer-events: none;
}

.material-label-black {
  font-family: 'Montserrat', sans-serif;
  font-weight: 200;
  font-size: 1.1rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: #000000;
  margin-bottom: 6px;
}

.material-name-black {
  font-family: 'Montserrat', sans-serif;
  font-weight: 200;
  font-size: 3.4rem;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: #000000;
  line-height: 1;
}

/* ============================================================
   6.2 CARRUSEL BLUSAS
   ============================================================ */
.blusas-title-overlay {
  position: absolute;
  top: 8%;
  left: 0;
  right: 0;
  text-align: center;
  pointer-events: none;
}

.blusas-title-overlay p {
  font-family: 'Montserrat', sans-serif;
  font-size: 2.2rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--brand-teal);
  line-height: 1.25;
}

/* Posicion medida contra la franja teal horneada en Blusas esenciales 2.png
   (39%-50% de alto) -- el logo real reemplaza el texto CSS reimplementado. */
.blusas-sweet-overlay {
  position: absolute;
  top: 44.5%;
  left: 0;
  right: 0;
  transform: translateY(-50%);
  text-align: center;
  pointer-events: none;
}

/* Combina el centrado con la animacion .zoom-in (misma razon que .pf-order-btn) */
.blusas-sweet-overlay.zoom-in {
  transform: translateY(-50%) scale(0.7);
}

.blusas-sweet-overlay.zoom-in.show {
  transform: translateY(-50%) scale(1);
}

.carousel-fullscreen .carousel-slide img.blusas-sweet-logo {
  position: static;
  width: min(60%, 260px);
  height: auto;
  max-height: none;
  object-fit: contain;
  background: transparent;
}

.blusas-figura-overlay {
  position: absolute;
  top: 68%;
  left: 6%;
  transform: translateY(-50%);
  text-align: left;
  pointer-events: none;
}

/* Combina el centrado con la animacion .fade-up (misma razon que .pf-order-btn) */
.blusas-figura-overlay.fade-up {
  transform: translateY(-50%) translateY(40px);
}

.blusas-figura-overlay.fade-up.show {
  transform: translateY(-50%) translateY(0);
}

.blusas-figura-overlay p {
  font-family: 'Montserrat', sans-serif;
  font-size: 2.0rem;
  font-weight: 400;
  text-transform: uppercase;
  color: var(--brand-teal);
  line-height: 1.3;
}

@media (max-width: 768px) {
  .blusas-figura-overlay p {
    font-size: 1.6rem;
  }
}

.blusas-figura-overlay strong {
  font-weight: 700;
}

.blusas-colores-overlay {
  position: absolute;
  top: 8%;
  left: 0;
  right: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  pointer-events: none;
}

.colores-numero {
  font-family: 'Montserrat', sans-serif;
  font-weight: 900;
  font-size: 7.8rem;
  color: var(--brand-teal);
  line-height: 1;
}

.colores-texto {
  font-family: 'Montserrat', sans-serif;
  font-weight: 700;
  font-size: 3rem;
  text-transform: uppercase;
  color: var(--brand-teal);
  line-height: 1.2;
  text-align: left;
}

.colores-porref {
  font-weight: 500;
}

.blusas-brand-overlay {
  position: absolute;
  top: 8%;
  left: 0;
  right: 0;
  text-align: center;
  pointer-events: none;
}

/* Logo real en vez de .bb-sweet/.bb-harmony (texto CSS reimplementado).
   position:static explicito porque el selector generico de fotos de fondo
   (.carousel-fullscreen .carousel-slide img, descendiente no directo)
   tambien le pega a este img anidado -- mismo gotcha que otros logos. */
.carousel-fullscreen .carousel-slide img.bb-logo {
  position: static;
  width: min(60%, 260px);
  height: auto;
  max-height: none;
  object-fit: contain;
  background: transparent;
}

/* ============================================================
   6.3 CARRUSEL PERFECT AMISTAD
   ============================================================ */
.pa-bottom-mid-overlay {
  position: absolute;
  top: 75%;
  left: 0;
  right: 0;
  transform: translateY(-50%);
  text-align: center;
  pointer-events: none;
}

/* Imagen 1: "Es como una buena Amistad" -- estaba horneado en la foto
   original, se perdio al reemplazarla por la version limpia.
   Posicion: el texto vivia abajo (bottom:4%) y solo habia que subirlo un
   poco para que no quedara pegado/cortado contra el borde inferior --
   NO moverlo al centro de la slide en vertical (quedo demasiado arriba la
   primera pasada). En horizontal SI va centrado (el usuario pidio que no
   quedara tirado a la derecha). El centrado usa translateX(-50%), que
   comparte el eje transform con .fade-up: las reglas combinadas de abajo
   (mismo patron que .pf-tallas-overlay.fade-up) evitan que la animacion
   pise el centrado. */
.pa-intro-overlay {
  position: absolute;
  left: 50%;
  bottom: 10%;
  transform: translateX(-50%);
  text-align: center;
  pointer-events: none;
}

.pa-intro-overlay.fade-up {
  transform: translateX(-50%) translateY(40px);
}

.pa-intro-overlay.fade-up.show {
  transform: translateX(-50%) translateY(0);
}

/* Badge "PERFECT FIT": en movil NO va dentro de la foto -- va como franja
   inferior invertida al final de la seccion (.pa-amistad-footer-banner).
   Se vuelve a mostrar en escritorio con posicion centrada en
   css/desktop.css. */
.pa-intro-badge {
  display: none;
  position: absolute;
  left: 50%;
  top: 46%;
  transform: translate(-50%, -50%);
  text-align: center;
  pointer-events: none;
}

.carousel-fullscreen .carousel-slide img.pa-intro-badge-logo {
  position: static;
  width: 180px;
  height: auto;
  max-height: none;
  object-fit: contain;
  background: transparent;
}

.pa-intro-es-como {
  font-family: 'Montserrat', sans-serif;
  font-weight: 500;
  font-size: 1.6rem;
  color: var(--brand-teal);
  margin: 0;
  line-height: 1.2;
}

.pa-intro-una-buena {
  font-family: 'Montserrat', sans-serif;
  font-weight: 700;
  font-size: 2.6rem;
  color: var(--brand-teal);
  margin: 0;
  line-height: 1.15;
}

.pa-intro-amistad {
  font-family: 'Montserrat', sans-serif;
  font-weight: 700;
  font-size: 2.6rem;
  text-transform: uppercase;
  letter-spacing: 0.35em;
  color: var(--brand-teal);
  margin: 0;
  line-height: 1.15;
}

@media (max-width: 480px) {
  .pa-intro-una-buena,
  .pa-intro-amistad {
    font-size: 2.1rem;
  }
}

/* Imagen 2: "Te entiende" */
.pa-title-entiende {
  font-family: 'Montserrat', sans-serif;
  font-weight: 700;
  font-size: 5rem;
  text-transform: uppercase;
  color: var(--brand-teal);
  line-height: 1.15;
  text-align: left;
  padding-left: 30px;
}

@media (max-width: 768px) {
  .pa-title-entiende {
    font-size: 4rem;
  }
}

.pa-copy-entiende {
  margin-top: 12rem;
  font-family: 'Montserrat', sans-serif;
  font-weight: 400;
  font-size: 1.1rem;
  color: var(--brand-teal);
  line-height: 1.4;
}

@media (max-width: 768px) {
  .pa-copy-entiende {
    margin-top: 6rem;
  }
}

.pa-copy-entiende strong {
  font-weight: 700;
}

/* Imagen 3: "Te sostiene" */
.pa-title-sostiene {
  font-family: 'Montserrat', sans-serif;
  font-weight: 900;
  font-size: 4.6rem;
  text-transform: uppercase;
  color: var(--brand-teal);
  line-height: 1.15;
  text-align: left;
  padding-left: 30px;
}

.pa-top-right-overlay {
  position: absolute;
  top: 8%;
  right: 6%;
  text-align: left;
  pointer-events: none;
}

.pa-top-right-overlay p {
  font-family: 'Montserrat', sans-serif;
  font-weight: 400;
  font-size: 1.15rem;
  color: var(--brand-teal);
  line-height: 1.3;
}

.pa-top-right-overlay strong {
  font-weight: 700;
}

/* Imagen 4: "Te hace sentir bien" */
.pa-bottom-right-stack {
  position: absolute;
  top: 35%;
  right: 6%;
  max-width: 55%;
  text-align: left;
  pointer-events: none;
}

.pa-title-sentirbien {
  font-family: 'Montserrat', sans-serif;
  font-weight: 900;
  font-size: 2.4rem;
  text-transform: uppercase;
  color: var(--brand-teal);
  line-height: 1.0;
  text-align: left;
  padding-left: 90px;
}

.pa-subtitle {
  margin-top: 4px;
  font-family: 'Montserrat', sans-serif;
  font-weight: 500;
  font-size: 1.9rem;
  color: var(--brand-teal);
  line-height: 1.2;
  text-align: left;
  padding-left: 90px;
}

.pa-copy-adapta {
  margin-top: 2rem;
  font-family: 'Montserrat', sans-serif;
  font-weight: 400;
  font-size: 1.2rem;
  color: var(--brand-teal);
  line-height: 1.0;
  padding-left: 90px;
}

.pa-copy-adapta strong {
  font-weight: 700;
}

.pa-bottom-right-overlay {
  position: absolute;
  bottom: 6%;
  right: 6%;
  max-width: 55%;
  text-align: right;
  pointer-events: none;
}

.pa-bottom-right-overlay p {
  font-family: 'Montserrat', sans-serif;
  font-weight: 500;
  font-size: 1rem;
  color: var(--brand-teal);
  line-height: 1.4;
}

.pa-bottom-right-overlay strong {
  font-weight: 700;
}

/* Imagen 5: "Un pantalón que te acompaña" */
.pa-acompana-overlay {
  position: absolute;
  top: 85%;
  left: 0;
  right: 0;
  transform: translateY(-50%);
  text-align: center;
  pointer-events: none;
}

.pa-title-acompana {
  font-family: 'Montserrat', sans-serif;
  font-weight: 900;
  font-size: 1.5rem;
  color: var(--brand-teal);
  line-height: 1.3;
  text-align: center;
}

/* ============================================================
   7. ANIMACIONES
   ============================================================ */
.fade-up {
  opacity: 0;
  transform: translateY(40px);
  transition: opacity 1.5s ease, transform 1.5s ease;
}

.fade-up.show {
  opacity: 1;
  transform: translateY(0);
}

.slide-in-left {
  opacity: 0;
  transform: translateX(-80px);
  transition: opacity 1.5s ease, transform 1.5s ease;
}

.slide-in-left.show {
  opacity: 1;
  transform: translateX(0);
}

.slide-in-right {
  opacity: 0;
  transform: translateX(80px);
  transition: opacity 1.5s ease, transform 1.5s ease;
}

.slide-in-right.show {
  opacity: 1;
  transform: translateX(0);
}

.zoom-in {
  opacity: 0;
  transform: scale(0.7);
  transition: opacity 0.8s ease, transform 0.8s ease;
}

.zoom-in.show {
  opacity: 1;
  transform: scale(1);
}

.slide-in-bottom {
  opacity: 0;
  transform: translateY(80px);
  transition: opacity 1s ease, transform 1s ease;
}

.slide-in-bottom.show {
  opacity: 1;
  transform: translateY(0);
}

/* ============================================================
   8. WHATSAPP BUTTON
   ============================================================ */
/* Boton flotante fijo abajo a la derecha. bottom:140px deja espacio para el
   contenido que puede quedar al pie de pantalla (nota de mayoristas).
   La animacion pulse (loop infinito) lo hace notar sin ser molesto: un anillo
   teal que se expande y desvanece. */
.whatsapp-btn {
  position: fixed;
  bottom: calc(140px + env(safe-area-inset-bottom, 0px));
  right: calc(20px + env(safe-area-inset-right, 0px));
  background: var(--brand-teal);
  color: #ffffff;
  width: 60px;
  height: 60px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
  z-index: 100;
  animation: pulse 2s infinite;
}

/* Anillo expansivo: la caja-shadow pasa de cubrir el boton a un halo de 12px
   que va desvaneciendo su alpha -- crea la sensacion de "latido" suave. */
@keyframes pulse {
  0% { transform: scale(1); box-shadow: 0 0 0 0 rgba(68, 133, 143, 0.35); }
  70% { transform: scale(1.07); box-shadow: 0 0 0 12px rgba(68, 133, 143, 0); }
  100% { transform: scale(1); box-shadow: 0 0 0 0 rgba(68, 133, 143, 0); }
}

/* ============================================================
   9. VIDEO REELS
   ============================================================ */
.reels-tagline {
  font-size: 1.6rem;
  margin-top: 0.4rem;
}

.reels-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.6rem;
  max-width: 340px;
  margin: 0 auto;
}

.reel-card {
  position: relative;
  aspect-ratio: 9 / 16;
  border-radius: var(--border-radius);
  overflow: hidden;
  box-shadow: var(--shadow-heavy);
  background: #000;
}

.reel-video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.reel-overlay-top {
  position: absolute;
  top: 14px;
  left: 14px;
  right: 14px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.reel-logo {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  box-shadow: var(--shadow-light);
}

.reel-pill {
  font-size: 0.62rem;
  padding: 0.3rem 0.7rem;
  background: rgba(68, 133, 143, 0.85);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
}

.reel-ref {
  position: absolute;
  bottom: 14px;
  left: 14px;
  right: 14px;
  padding: 0.5rem 0.8rem;
  background: rgba(36, 69, 75, 0.6);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
  color: #fff;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  border-radius: var(--border-radius-small);
  text-align: center;
}

/* ============================================================
   10. FOOTER
   ============================================================ */
/* Sin margin-top: el banner "PERFECT FIT" (fondo teal) queda justo antes
   del footer en el HTML -- con margen quedaba una franja blanca entre el
   teal y el fondo crema del footer, visible en mobile y escritorio. */
.brand-footer {
  padding: 3rem 1.5rem 2.5rem;
  background: var(--brand-cream-soft);
  text-align: center;
}

.brand-footer-content {
  max-width: 520px;
  margin: 0 auto;
}

.brand-footer-title {
  line-height: 1.05;
  margin-bottom: 0.6rem;
}

/* Lockup "SWEET HARMONY": en el footer se respeta el patron de pesos del
   resto del sitio (SWEET mas liviano arriba, HARMONY mas pesado abajo),
   aunque aqui se usan 500/700 en vez del 400/900 de los logos SVG de la
   portada. Ver docs/TIPOGRAFIA-MAPA.md. */
.brand-footer-title .sweet {
  display: block;
  font-family: 'Montserrat', sans-serif;
  font-size: 1.8rem;
  font-weight: 500;
  letter-spacing: 0.22em;
  color: var(--text-main);
}

.brand-footer-title .harmony {
  display: block;
  font-family: 'Montserrat', sans-serif;
  font-size: 1.9rem;
  font-weight: 700;
  letter-spacing: 0.22em;
  color: var(--text-main);
}

.brand-footer-line {
  border: none;
  border-top: 2px solid var(--brand-teal);
  width: 160px;
  margin: 0.8rem auto 0.9rem;
  opacity: 0.6;
}

.brand-footer-studio {
  font-size: 0.8rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: 1.4rem;
}

.brand-footer-contact {
  display: flex;
  justify-content: center;
  gap: 1.2rem;
  flex-wrap: wrap;
}

.brand-footer-contact a {
  font-size: 0.8rem;
  text-decoration: none;
  letter-spacing: 0.12em;
  color: var(--brand-teal);
  transition: opacity 0.2s ease, transform 0.2s ease;
}

.brand-footer-contact a:hover {
  opacity: 0.7;
  transform: translateY(-1px);
}

.brand-footer-location a {
  font-size: 0.75rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  opacity: 0.7;
  text-decoration: none;
  color: inherit;
  transition: opacity 0.2s ease;
}

.brand-footer-location a:hover {
  opacity: 1;
}

.brand-footer-legal {
  font-size: 0.75rem;
  opacity: 0.7;
  margin-top: 1rem;
}

.brand-footer-credits {
  font-size: 0.7rem;
  opacity: 0.55;
  margin-top: 0.4rem;
  letter-spacing: 0.4px;
}

.brand-footer-signature {
  margin-top: 0.8rem;
  font-size: 0.65rem;
  letter-spacing: 0.35em;
  text-transform: uppercase;
  opacity: 0.45;
  font-family: 'Montserrat', system-ui, sans-serif;
}

@media (max-width: 480px) {
  .brand-footer {
    padding: 2.4rem 1rem 2rem;
  }

  .brand-footer-title .sweet {
    font-size: 1.5rem;
  }

  .brand-footer-title .harmony {
    font-size: 1.6rem;
  }
}

/* ============================================================
   11. PRELOADER / INTRO
   ============================================================ */
/* Splash que tapa todo (z-index 9999) mientras carga la pagina.
   initPreloader() en js/main.js le agrega .hide (ahora a los 1.4s, antes
   2s -- se sentia lento). El estado .hide se difumina (blur) en vez de
   solo desvanecerse: la tecnica "blur para disimular transiciones" hace
   que el corte entre el splash y el hero se sienta como una sola
   transformacion continua, no dos capas superpuestas apagandose. */
.preloader {
  position: fixed;
  inset: 0;
  z-index: 9999;
  background: #ffffff;
  display: flex;
  align-items: center;
  justify-content: center;
  filter: blur(0);
  will-change: opacity, filter;
  transition: opacity 400ms var(--ease-out-strong), filter 400ms var(--ease-out-strong), visibility 400ms var(--ease-out-strong);
}

.preloader.hide {
  opacity: 0;
  /* 8px en vez de 14px: un blur grande en un elemento full-viewport es de
     lo mas caro de componer en pantalla, sobre todo en iOS -- justo en el
     momento (letras recien terminando de entrar) donde mas se nota un
     frame perdido. 8px sigue leyendose como difuminado real. */
  filter: blur(8px);
  visibility: hidden;
  pointer-events: none;
}

/* Wordmark chiquito abajo del splash -- firma de marca discreta, no
   compite con el logo principal "Sweet Harmony". */
.preloader-subbrand {
  position: absolute;
  bottom: 8%;
  left: 50%;
  transform: translateX(-50%);
  width: 72px;
  height: auto;
  opacity: 0;
  animation: preloaderSubbrandIn 0.5s ease-out forwards;
  animation-delay: 1s;
}

@keyframes preloaderSubbrandIn {
  from { opacity: 0; transform: translateX(-50%) translateY(6px); }
  to { opacity: 0.55; transform: translateX(-50%) translateY(0); }
}

.preloader-text {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

.pl-sweet,
.pl-harmony {
  display: flex;
  justify-content: center;
  font-family: 'Montserrat', sans-serif;
  letter-spacing: 0.1em;
  color: var(--brand-teal);
}

.pl-sweet {
  font-weight: 500;
  font-size: 2rem;
}

.pl-harmony {
  font-weight: 700;
  font-size: 2.6rem;
}

/* Letras del splash: cada <span> arranca invisible (opacity:0) y entra con
   una animacion distinta y un delay escalonado de ~80ms -- la secuencia
   completa de "SWEET" y luego "HARMONY" se siente como un titileo en
   cascada mientras el splash esta visible. */
.preloader-text span {
  display: inline-block;
  opacity: 0;
}

/* Entradas de letras del splash: cada keyframe cubre un movimiento distinto
   (caer, subir, hacer zoom, girar, deslizarse) para que las letras no
   entren todas igual. */

@keyframes plFall {
  from { opacity: 0; transform: translateY(-40px); }
  to { opacity: 1; transform: translateY(0); }
}

@keyframes plRise {
  from { opacity: 0; transform: translateY(40px); }
  to { opacity: 1; transform: translateY(0); }
}

@keyframes plZoom {
  from { opacity: 0; transform: scale(0.2); }
  to { opacity: 1; transform: scale(1); }
}

@keyframes plSpin {
  from { opacity: 0; transform: rotate(180deg) scale(0.4); }
  to { opacity: 1; transform: rotate(0) scale(1); }
}

@keyframes plSlideLeft {
  from { opacity: 0; transform: translateX(-40px); }
  to { opacity: 1; transform: translateX(0); }
}

@keyframes plSlideRight {
  from { opacity: 0; transform: translateX(40px); }
  to { opacity: 1; transform: translateX(0); }
}

.pl-sweet span:nth-child(1) { animation: plFall 0.5s ease forwards;      animation-delay: 0.05s; }
.pl-sweet span:nth-child(2) { animation: plRise 0.5s ease forwards;      animation-delay: 0.13s; }
.pl-sweet span:nth-child(3) { animation: plZoom 0.5s ease forwards;      animation-delay: 0.21s; }
.pl-sweet span:nth-child(4) { animation: plSpin 0.5s ease forwards;      animation-delay: 0.29s; }
.pl-sweet span:nth-child(5) { animation: plSlideLeft 0.5s ease forwards; animation-delay: 0.37s; }

.pl-harmony span:nth-child(1) { animation: plSlideRight 0.5s ease forwards; animation-delay: 0.45s; }
.pl-harmony span:nth-child(2) { animation: plFall 0.5s ease forwards;       animation-delay: 0.53s; }
.pl-harmony span:nth-child(3) { animation: plRise 0.5s ease forwards;       animation-delay: 0.61s; }
.pl-harmony span:nth-child(4) { animation: plZoom 0.5s ease forwards;       animation-delay: 0.69s; }
.pl-harmony span:nth-child(5) { animation: plSpin 0.5s ease forwards;       animation-delay: 0.77s; }
.pl-harmony span:nth-child(6) { animation: plSlideLeft 0.5s ease forwards;  animation-delay: 0.85s; }
.pl-harmony span:nth-child(7) { animation: plSlideRight 0.5s ease forwards; animation-delay: 0.93s; }

/* ============================================================
   12. RESPONSIVE
   ============================================================ */
@media (max-width: 900px) {
  .hero-image-card {
    padding: 1rem 0.5rem;
  }
}

/* Breakpoint movil (<=768px): aqui aparece la hamburguesa y la lista de
   enlaces pasa a panel desplegable. El background teal del panel obliga a
   que los links sean blancos (de ahi los !important, el color teal de la
   regla base ya no sirve sobre teal). */
@media (max-width: 768px) {
  body {
    background: #ffffff;
  }
  
  .menu-toggle {
    display: flex;
    z-index: 1001;
  }

  .nav-links {
    display: none;
    flex-direction: column;
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: auto;
    background: #44858f;
    padding: 80px 20px 40px;
    box-shadow: 0 10px 30px rgba(0,0,0,0.2);
    text-align: center;
    z-index: 1000;
    border-bottom-left-radius: 20px;
    border-bottom-right-radius: 20px;
  }

  .nav-links.active {
    display: flex;
    animation: slideDown 0.4s ease forwards;
  }

  .nav-links li a {
    color: #ffffff !important;
    font-size: 1.3rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    display: block;
    padding: 15px;
    border-bottom: 1px solid rgba(255, 255, 255, 0.1);
  }

  .nav-links li:last-child a {
    border-bottom: none;
  }

  @keyframes slideDown {
    from { transform: translateY(-100%); opacity: 0; }
    to { transform: translateY(0); opacity: 1; }
  }
}

@media (max-width: 480px) {
  header {
    padding: 2rem 1rem !important;
  }

  .brand-title .sweet { font-size: 1.2rem; }
  .brand-title .harmony { font-size: 1.4rem; }
  
  .container {
    padding: 0 1rem;
    margin: 0 auto;
  }

  .hero-image-card {
    padding: 0.5rem;
    margin: 0 -0.5rem;
  }

  .section-header h2 {
    font-size: 1.6rem;
    padding: 0 10px;
  }
}