/* ============================================================
   FRESHBOX · styles.css
   Hoja única — sin Webflow. Reset base + tipografía + utilidades
   de layout propias + diseño + responsive.
   ============================================================ */

/* ---------- Reset base ---------- */
*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  height: 100%;
  overscroll-behavior: none;
}

body {
  margin: 0;
  min-height: 100%;
  overscroll-behavior: none;
  background-color: #fff;
  font-size: 14px;
  line-height: 20px;
  color: #333;
}

img {
  max-width: 100%;
  vertical-align: middle;
  display: inline-block;
}

/* ---------- Tipografía ---------- */
@font-face {
  font-family: "Neue Montreal";
  src: url("../fonts/NeueMontreal-Light.woff2") format("woff2");
  font-weight: 300;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Neue Montreal";
  src: url("../fonts/NeueMontreal-LightItalic.woff2") format("woff2");
  font-weight: 300;
  font-style: italic;
  font-display: swap;
}

@font-face {
  font-family: "Neue Montreal";
  src: url("../fonts/NeueMontreal-Regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Neue Montreal";
  src: url("../fonts/NeueMontreal-Italic.woff2") format("woff2");
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}

@font-face {
  font-family: "Neue Montreal";
  src: url("../fonts/NeueMontreal-Medium.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Neue Montreal";
  src: url("../fonts/NeueMontreal-MediumItalic.woff2") format("woff2");
  font-weight: 500;
  font-style: italic;
  font-display: swap;
}

@font-face {
  font-family: "Neue Montreal";
  src: url("../fonts/NeueMontreal-Bold.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Neue Montreal";
  src: url("../fonts/NeueMontreal-BoldItalic.woff2") format("woff2");
  font-weight: 700;
  font-style: italic;
  font-display: swap;
}

/* Fallback con métricas ajustadas a Neue Montreal (calculadas desde el .woff2).
   Hace que Arial ocupe exactamente el mismo espacio que Neue → swap sin CLS. */
@font-face {
  font-family: "Neue Fallback";
  src: local("Arial");
  size-adjust: 121.66%;
  ascent-override: 63.70%;
  descent-override: 18.49%;
  line-gap-override: 16.44%;
}

/* ---------- Utilidades de layout (ex-Webflow, reescritas) ---------- */
.container-940 {
  max-width: 940px;
  margin-left: auto;
  margin-right: auto;
}

.inline-block {
  max-width: 100%;
  display: inline-block;
}

.embed::before,
.embed::after {
  content: " ";
  display: table;
  grid-column: 1 / 2;
  grid-row: 1 / 2;
}

.embed::after {
  clear: both;
}

/* ============================================================
   DISEÑO (freshbox.css consolidado)
   ============================================================ */
@keyframes splide-loading {
  0% {
    transform: rotate(0)
  }

  to {
    transform: rotate(1turn)
  }
}

.splide--draggable>.splide__slider>.splide__track,
.splide--draggable>.splide__track {
  -webkit-user-select: none;
  -ms-user-select: none;
  user-select: none
}

.splide--fade>.splide__slider>.splide__track>.splide__list,
.splide--fade>.splide__track>.splide__list {
  display: block
}

.splide--fade>.splide__slider>.splide__track>.splide__list>.splide__slide,
.splide--fade>.splide__track>.splide__list>.splide__slide {
  left: 0;
  opacity: 0;
  position: absolute;
  top: 0;
  z-index: 0
}

.splide--fade>.splide__slider>.splide__track>.splide__list>.splide__slide.is-active,
.splide--fade>.splide__track>.splide__list>.splide__slide.is-active {
  opacity: 1;
  position: relative;
  z-index: 1
}

.splide--rtl {
  direction: rtl
}

.splide--ttb.is-active>.splide__slider>.splide__track>.splide__list,
.splide--ttb.is-active>.splide__track>.splide__list {
  display: block
}

.splide__container {
  box-sizing: border-box;
  position: relative
}

.splide__list {
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
  display: -ms-flexbox;
  display: flex;
  height: 100%;
  margin: 0 !important;
  padding: 0 !important;
  transform-style: preserve-3d
}

.splide.is-initialized:not(.is-active) .splide__list {
  display: block
}

.splide__pagination {
  -ms-flex-align: center;
  align-items: center;
  display: -ms-flexbox;
  display: flex;
  -ms-flex-wrap: wrap;
  flex-wrap: wrap;
  -ms-flex-pack: center;
  justify-content: center;
  margin: 0;
  pointer-events: none
}

.splide__pagination li {
  display: inline-block;
  line-height: 1;
  list-style-type: none;
  margin: 0;
  pointer-events: auto
}

.splide__progress__bar {
  width: 0
}

.splide {
  outline: none;
  position: relative;
  visibility: hidden
}

.splide.is-initialized,
.splide.is-rendered {
  visibility: visible
}

.splide__slide {
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
  box-sizing: border-box;
  -ms-flex-negative: 0;
  flex-shrink: 0;
  list-style-type: none !important;
  margin: 0;
  outline: none;
  position: relative
}

.splide__slide img {
  vertical-align: bottom
}

.splide__slider {
  position: relative
}

.splide__spinner {
  animation: splide-loading 1s linear infinite;
  border: 2px solid #999;
  border-left-color: transparent;
  border-radius: 50%;
  bottom: 0;
  display: inline-block;
  height: 20px;
  left: 0;
  margin: auto;
  position: absolute;
  right: 0;
  top: 0;
  width: 20px
}

.splide__track {
  overflow: hidden;
  position: relative;
  z-index: 0
}

:root {
  /* Alto real de #s3-2 en mobile (ver syncS32S33Background en main.js) —
     usado para que el degradado de fondo de #s3-2/#s3-3 se comporte
     como un único lienzo continuo, sin costura en la unión. 0px de
     entrada evita un salto visual mientras JS aún no corre. */
  --s32-height: 0px;
  --font-family--principal-font: "Neue Montreal", "Neue Fallback", sans-serif;
  --font-secundaria: "Neue Montreal", "Neue Fallback", sans-serif;
  --verde-primario: #3e7319;
  --blanco: #fff;
  --_typography---lucida-grande: "Neue Montreal", "Neue Fallback", sans-serif;
  --negro: #131313;
  --font-family--wix-madefor-text: "Neue Montreal", "Neue Fallback", sans-serif;
  --gris: #bfbfbf;
  --font-family--font-family: "Neue Montreal", "Neue Fallback", sans-serif;
  --amarillo-banana: #fdda3c;
  --background-color: var(--bg-color);
  --bg-color: #ffffff5c;
  --_typography---inter: "Neue Montreal", sans-serif;
  --amarillo-acentos: #f7bd3c;
  --cristal-bg--cristal: #ffffff24;

  /* Escalado proporcional desktop/laptop (ver #scaleWrapper en main.js):
     1 = sin escalar (mobile, y desktop ≥1920px de ancho — el diseño
     nativo). Entre 992-1920px, JS la fija a innerWidth/1920 y aplica
     transform:scale() a #scaleWrapper. Como "vh"/"vw" NUNCA se calculan
     contra el ancho del wrapper (siempre contra el viewport real,
     ignorando cualquier transform de un ancestro), todo valor en vh/vw
     de este archivo debe envolverse en calc(X / var(--page-scale)) —
     si no, quedaría escalado DOS veces (una por su propio vw/vh, otra
     por el transform del wrapper). Los px/rem/em/% no necesitan tocarse:
     transform los escala correctamente sin ayuda. */
  --page-scale: 1;
}

.block-container {
  max-width: 940px;
  margin-left: auto;
  margin-right: auto;
  display: block;
}

.hflex {
  flex-direction: row;
  align-items: flex-start;
  display: flex;
}

@media screen and (max-width: 991px) {
  .block-container {
    max-width: 728px;
  }
}

@media screen and (max-width: 767px) {
  .block-container {
    max-width: none;
  }
}

.body {
  font-family: var(--font-family--principal-font);
}

.nav-menu-content {
  flex-flow: row;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  padding: 10px 40px;
  display: flex;
}

.symbol {
  width: 58px;
  color: var(--blanco);
  transition: color .4s ease;
}

.freshbox-typo {
  color: #fff;
  width: 128px;
  transition: color .4s ease;
}

.logo-link {
  grid-column-gap: 10px;
  grid-row-gap: 10px;
  justify-content: space-between;
  align-items: center;
  display: flex;
  position: relative;
}

.section {
  flex-flow: row;
  justify-content: center;
  align-items: flex-end;
  height: calc(100dvh / var(--page-scale));
  display: flex;
  position: relative;
  top: auto;
  z-index: 1;
  overflow: hidden;
}

/* ── Hero slide background ─────────────────────── */
.hero-bg {
  position: absolute;
  inset: 0;
  z-index: 0;
  contain: paint;
  isolation: isolate;
}

.hero-slide {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  visibility: hidden;
  transition:
    opacity 0.9s linear,
    visibility 0s linear 0.9s;
  z-index: 0;
}

.hero-slide.is-active,
.hero-slide.is-next,
.hero-slide.is-leaving {
  visibility: visible;
  transition-delay: 0s;
  will-change: opacity;
  backface-visibility: hidden;
  transform: translateZ(0);
}

.hero-slide.is-active {
  opacity: 1;
  z-index: 2;
}

.hero-slide.is-next,
.hero-slide.is-leaving {
  z-index: 1;
}

.hero-slide.is-leaving {
  opacity: 1;
  transition: none;
}

.hero-slide-overlay {
  z-index: 6;
  background-color: #0000;
  background-image: linear-gradient(#0009, #00000026 50%, #00000059);
  width: 100%;
  height: 100%;
  position: absolute;
  inset: 0%;
}



.section > .block-container {
  position: relative;
  z-index: 7;
}

.section-2 {
  z-index: 10;
  position: relative;
  top: auto;
}

.container {
  z-index: 10;
  flex-flow: row;
  justify-content: flex-start;
  align-items: flex-start;
  max-width: 100%;
  padding: 40px 40px 20px;
  display: flex;
}

.heading {
  width: 100%;
  font-family: var(--_typography---lucida-grande);
  color: var(--negro);
  text-align: left;
  letter-spacing: 0;
  text-transform: uppercase;
  margin-top: 0;
  padding-top: 0;
  padding-bottom: 20px;
  padding-right: 60px;
  font-size: 80px;
  font-weight: 400;
  line-height: 90px;
}

.container-2 {
  width: 100%;
  max-width: 100%;
}

.section-header {
  z-index: 999;
  padding-top: 10px;
  padding-bottom: 10px;
  position: fixed;
  inset: 0% 0% auto;
  color: #fff;
  transition: transform .4s ease, background-color .4s ease, color .4s ease;
  will-change: transform;
  /* El header es transparente y su fila interna ocupa el ancho completo,
     así que el tramo vacío del medio no debe "robar" clicks a lo que
     esté debajo (p.ej. el logo propio del sidebar) — solo el logo y la
     hamburguesa son realmente interactivos. */
  pointer-events: none;
}
.section-header #logo,
.section-header #navbar {
  pointer-events: auto;
}

/* Tema claro (sobre hero/footer): transparente, texto blanco */
.section-header.is-light {
  background-color: transparent;
  color: #fff;
}

/* Tema sólido (al hacer scroll sobre secciones claras) */
.section-header.is-solid {
  background-color: transparent;
  color: var(--negro);
}

/* Scroll suave + compensación del header fijo para anclas */
html,
body {
  overflow-x: clip;
}

html {
  scroll-behavior: smooth;
  font-size: 20px;
}

/* ── Lenis (scroll suave) ── */
.lenis,
.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }   /* anula el smooth nativo; Lenis lo maneja */
.lenis.lenis-smooth [data-lenis-prevent] { overscroll-behavior: contain; }
.lenis.lenis-stopped { overflow: hidden; }
.lenis.lenis-smooth iframe { pointer-events: none; }

section[id],
footer[id] {
  scroll-margin-top: 80px;
}

/* ============================================================
   PRESENTACIÓN POR SLIDES (#inicio → #s3-2) — ver initPresentation()
   en main.js. El stage es un overlay fijo que mueve sus 4 hijas con
   transform (nunca con scrollTo): JS calcula la suma de alturas reales
   de las slides anteriores y la aplica como transform inline; esta
   transition anima el cambio. El scroll REAL del documento queda
   congelado en 0 mientras el stage está activo (html.fp-frozen) —
   así el resto de la página (#ciencia en adelante, con sus propios
   ScrollTrigger/stepper) no se entera de nada y sigue funcionando igual.
   #ciencia quedó afuera del stage a propósito: es mucho más alta que
   100svh y meterla como slide (con su propia ventana overflow-y:auto)
   generaba espacio muerto al final y una transición hacia #nosotros que
   no se sentía bien resuelta — scroll nativo normal es lo correcto ahí.
   Al salir de la última slide, el transform avanza un paso más allá (no
   hay una 5ª slide real ahí) y el stage completo se desliza fuera de
   pantalla con la MISMA transition de transform — así la salida hacia
   #ciencia se siente parte de la misma secuencia que viene desde el
   hero, no un
   efecto aparte.

   Funciona en desktop (wheel) Y touch (swipe) por igual — ver
   initPresentation() en main.js, que escucha ambos tipos de gesto y
   alimenta la misma lógica de avance/retroceso. El `transform` lo pone
   JS directo por inline style (no un --fp-index + calc()): en mobile
   (≤991px) el hero mide más que 100svh (ver @media 991px más abajo, le
   da min-height:100svh en vez de height:100svh para no recortar su texto
   grande), así que un cálculo a 100svh parejo desalineaba el resto de
   las slides. JS suma la altura REAL de cada una. Esta transition sigue
   animando el cambio igual, sea cual sea el origen del valor.
   ============================================================ */
.fp-stage {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  /* NO "inset:0"/bottom:0: #fp-stage vive dentro de #scaleWrapper, que en
     laptops 992-1919px tiene su propio transform:scale() (ver
     initPageScale en main.js) — eso lo convierte en el "containing
     block" de este position:fixed, así que bottom:0 (via inset:0)
     estiraba el alto de la caja contra el alto de #scaleWrapper
     COMPLETO (todo el resto de la página: #ciencia, #nosotros,
     #cadencia, #marcas, footer — miles de px), no contra un viewport.
     Mientras la presentación recorre sus slides eso no se notaba (con
     el scroll congelado en 0, solo se ve el primer tramo, igual de
     recortado por el viewport real da lo mismo el alto de la caja) —
     pero al salir hacia #ciencia, ese excedente de caja (relleno solo
     con el fondo negro sólido de acá abajo, sin ningún slide real) se
     veía como un destello negro largo antes de revelar #ciencia. Un
     alto explícito evita depender del containing block equivocado. */
  height: calc(100dvh / var(--page-scale));
  z-index: 500; /* debajo del header (999), encima del resto (5) */
  /* Fondo sólido de respaldo: el hero (#inicio) no tiene background-color
     propio, solo la imagen — mientras esta carga/decodifica (los primeros
     ~1-2s, más notorio en hard refresh sin caché), sin esto se veía
     #ciencia transparentando por detrás. */
  background-color: var(--negro);
  /* Misma curva y duración que el deslizamiento Ciencia↔Nosotros (JS,
     easeInOutSine, 1s) — cubic-bezier(0.37,0,0.63,1) es la aproximación
     estándar de easeInOutSine en CSS. Antes 0.7s con una cúbica más
     marcada; se sentía más brusca que el resto de las transiciones. */
  transition: transform 1s cubic-bezier(0.37, 0, 0.63, 1);
  transform: translate3d(0, 0, 0);
  will-change: transform;
}
.fp-stage.is-hidden {
  /* display:none (no solo visibility:hidden): Splide fuerza
     `.splide.is-initialized { visibility: visible }` sobre el propio
     carrusel — una declaración explícita en el descendiente le gana
     a lo heredado del stage, así que el carrusel se veía "flotando"
     encima del resto de la página. display:none no tiene ese problema:
     ningún hijo puede des-ocultarse desde dentro de un ancestro oculto así. */
  display: none;
  visibility: hidden;
}
html.fp-frozen,
html.fp-frozen body {
  overflow: hidden;
  height: calc(100dvh / var(--page-scale));
}

/* Igual que .fp-frozen pero SIN resetear a scrollY=0: #nosotros vive en medio
   del documento, así que se congela exactamente donde el usuario llegó (ver
   initNosotrosSteps en main.js). */
html.s5-frozen,
html.s5-frozen body {
  overflow: hidden;
}

/* Mismo patrón, para el auto-snap de #cadencia/Contacto (ver initContactSnap
   en main.js): frena el scroll nativo mientras dura el deslizamiento de
   alineación, sin resetear la posición (también vive en medio del documento). */
html.snap-frozen,
html.snap-frozen body {
  overflow: hidden;
}

/* Mismo patrón, para el sidebar del menú (ver initMenu en main.js): congela
   el scroll de fondo mientras el panel está abierto. */
html.menu-frozen,
html.menu-frozen body {
  overflow: hidden;
}

/* El logo, los links y la hamburguesa siguen el color del header */
.logo-link {
  color: inherit;
}

.section-header .menu-toggle-btn,
.section-header .text-block {
  color: inherit;
}

/* Sobre fondos claros (is-solid): símbolo en verde Freshbox; tipografía del logo y textos en negro */
.section-header.is-solid .logo-link,
.section-header.is-solid .symbol {
  color: var(--verde-primario);
}

.section-header.is-solid .freshbox-typo {
  color: var(--negro);
}

.herp-text {
  z-index: 1;
  justify-content: space-between;
  align-items: flex-end;
  width: 100%;
  max-width: 100%;
  padding-bottom: 37px;
  display: flex;
  position: static;
}

.heading-2 {
  z-index: 10;
  font-family: var(--_typography---lucida-grande);
  color: var(--blanco);
  letter-spacing: 0;
  text-transform: none;
  margin-bottom: 0;
  font-size: 200px;
  font-weight: 500;
  line-height: 200px;
  position: relative;
}

.flex-block-2 {
  text-align: left;
  justify-content: flex-start;
  align-items: flex-end;
  width: 50%;
  padding-top: 10px;
  padding-left: 40px;
  padding-right: 40px;
}

.flex-block-3 {
  width: 30%;
  height: 100%;
}

/* Ahora solo envuelve el botón trigger del sidebar (la lista de links
   vieja en línea se reemplazó por el panel — ver .site-sidebar). */
.content-nav {
  display: flex;
  justify-content: flex-end;
  align-items: center;
}

.paragraph {
  float: right;
  background-color: #FDDA3C;
  width: 50%;
  height: 200px;
  font-family: var(--font-family--principal-font);
  color: var(--negro);
  text-align: left;
  letter-spacing: 0;
  justify-content: flex-start;
  align-items: center;
  margin-bottom: 0;
  padding: 40px 282px 40px 40px;
  font-size: 15px;
  font-weight: 400;
  line-height: 20px;
  display: flex;
  position: absolute;
  inset: 35% 0% 0% auto;
}

.flex-block-5 {
  flex-flow: column;
  justify-content: flex-start;
  align-items: flex-end;
  width: 100%;
  height: auto;
}

.flex-block-7 {
  grid-column-gap: 40px;
  grid-row-gap: 40px;
  flex-flow: column;
  justify-content: flex-end;
  align-items: flex-end;
  width: 50%;
  padding-bottom: 20px;
  padding-right: 40px;
  position: static;
}

.paragraph-2 {
  z-index: 10;
  width: 400px;
  font-family: var(--font-family--wix-madefor-text);
  color: var(--blanco);
  text-align: right;
  letter-spacing: 0;
  font-size: 22px;
  font-weight: 400;
  line-height: 25px;
  position: relative;
}

.bar-menu {
  flex-flow: row;
  justify-content: center;
  align-items: center;
  width: 50px;
  height: 32px;
  display: flex;
}

.text-block {
  letter-spacing: 0;
}

/* Roll vertical "Menú" ↔ "Cerrar": las dos palabras viven apiladas todo
   el tiempo dentro de una ventana de la altura de una línea; togglear
   .is-open corre la pista un renglón hacia arriba, en vez de cambiar
   el texto de golpe. Alto fijo evita además el salto de ancho que
   tenía el textContent-swap (el contenedor ya se dimensiona al más
   ancho de los dos). */
.menu-label {
  position: relative;
  overflow: hidden;
  height: 20px;
}
.menu-label__track {
  display: flex;
  flex-direction: column;
  transition: transform .45s cubic-bezier(0.65, 0, 0.35, 1);
}
.menu-label.is-open .menu-label__track {
  transform: translateY(-20px);
}
.menu-label__word {
  height: 20px;
  line-height: 20px;
  white-space: nowrap;
}

@media (prefers-reduced-motion: reduce) {
  .menu-label__track {
    transition-duration: .01s;
  }
}

.menu-toggle-btn {
  grid-column-gap: 10px;
  grid-row-gap: 10px;
  color: var(--blanco);
  text-transform: uppercase;
  flex-flow: row;
  justify-content: center;
  align-items: center;
  text-decoration: none;
  display: flex;
  position: relative;
}

.btn-contact-hero {
  color: #fff;
  grid-template-rows: auto auto;
  grid-template-columns: 1fr 1fr;
  grid-auto-columns: 1fr;
  justify-content: flex-start;
  align-items: center;
  width: auto;
  text-decoration: none;
  display: flex;
  overflow: hidden;
}

.arrow-ileft {
  z-index: 1;
  clear: none;
  color: #fff;
  justify-content: center;
  align-items: center;
  width: 50px;
  height: 50px;
  display: flex;
  position: relative;
}

.arrow-ileft:hover {
  border-color: var(--gris);
}

.arrow-ileft._2 {
  background-color: var(--verde-primario);
}

.text-contact-hero {
  font-family: var(--_typography---lucida-grande);
  text-transform: uppercase;
  text-align: center;
  letter-spacing: 0;
  justify-content: flex-start;
  align-self: center;
  align-items: center;
  font-size: 12px;
}

.container-4 {
  width: 100%;
  max-width: 100%;
  height: 1200px;
  font-family: var(--font-family--font-family);
  color: #fff;
  background-image: url('../images/1-2.jpg');
  background-position: 50%;
  background-repeat: no-repeat;
  background-size: cover;
  background-attachment: scroll;
  flex-flow: column;
  justify-content: flex-end;
  align-items: flex-start;
  font-size: 56px;
  line-height: 60px;
  display: flex;
}

.s4-ciencia {
  z-index: 10;
  flex-flow: column;
  padding-bottom: 220px;
  display: flex;
  position: relative;
}

.hero-container {
  background: none;
  justify-content: space-between;
  align-items: flex-end;
  width: 100%;
  max-width: 100%;
  height: 100%;
  padding-left: 0;
  padding-right: 0;
  display: flex;
  position: relative;
}

.s3-cartera {
  background-color: #0d0d0d;
  color: var(--blanco);
  height: 100%;
  padding-top: 0;
  padding-bottom: 220px;
  position: relative;
  overflow: hidden;
}

/* .section-5 — regla consolidada abajo */

.section-6 {
  z-index: 10;
  background-color: var(--blanco);
  height: calc(100svh / var(--page-scale));
  position: relative;
}

.section-7 {
  z-index: 10;
  background-color: var(--negro);
  height: calc(50svh / var(--page-scale));
  position: relative;
}

.section-8 {
  z-index: 10;
  background-color: var(--verde-primario);
  height: calc(100svh / var(--page-scale));
  position: relative;
}

.section-9 {
  z-index: 10;
  background-color: var(--gris);
  height: calc(100svh / var(--page-scale));
  position: relative;
}

.section-10 {
  z-index: 10;
  background-color: var(--amarillo-banana);
  height: calc(50svh / var(--page-scale));
  position: relative;
}

.section-11 {
  z-index: 10;
  background-color: var(--verde-primario);
  height: calc(70svh / var(--page-scale));
  position: relative;
}

.btn-cta-content {
  z-index: 1;
  -webkit-backdrop-filter: blur(5px);
  backdrop-filter: blur(5px);
  background-color: #ffffff5c;
  justify-content: center;
  align-items: center;
  width: 150px;
  height: 50px;
  display: flex;
  position: relative;
}

.btn-cta-content._2 {
  background-color: var(--verde-primario);
}

.arrows-right {
  z-index: 1;
  width: 50px;
  height: 50px;
  color: var(--blanco);
  justify-content: center;
  align-items: center;
  display: block;
  position: relative;
  transform: rotate(180deg);
}

.arrows-right._2 {
  background-color: var(--verde-primario);
}

.btn-motion-pro {
  grid-column-gap: 5px;
  grid-row-gap: 5px;
  flex-flow: row;
  order: 0;
  justify-content: flex-start;
  align-items: center;
  display: flex;
}

.container-science {
  flex-flow: column;
  justify-content: flex-start;
  align-items: flex-start;
  width: 100%;
  max-width: 100%;
  height: 4455px; /* 891px/fila × 5 filas (antes 3564px = 891×4, sin el punto 5) */
  padding-left: 40px;
  padding-right: 40px;
  display: flex;
  position: relative;
  top: 0;
  /* altura fija + contención → el reflow de las filas al crecer la imagen
     se queda DENTRO de S4, no propaga al resto del documento.
     "contain:layout" sola NO recorta el overflow visual (solo aísla el
     layout) — .imagen-item-1 crece en flujo normal (position:relative)
     hasta ~800px y sin overflow:hidden acá ese exceso sí se filtraba y
     estiraba document.documentElement.scrollHeight en tiempo real mientras
     se scrollea S4, desincronizando el pin de S6 (calculado una vez por
     ScrollTrigger.refresh() contra una altura de documento ya vieja). */
  contain: layout;
  overflow: hidden;
}

.heading-3 {
  max-width: 100%;
  font-family: var(--font-family--font-family);
  letter-spacing: 0;
  text-transform: uppercase;
  font-size: 20px;
  font-weight: 400;
}

.tech-list {
  border-top: 1px solid var(--gris);
  flex-flow: row;
  order: -9999;
  justify-content: flex-start;
  align-self: flex-start;
  align-items: flex-start;
  width: 100%;
  min-height: 300px;
  padding-top: 20px;
  padding-bottom: 20px;
  display: flex;
  position: static;
  overflow: visible;
}

.container-7 {
  flex-flow: column;
  justify-content: flex-end;
  align-items: flex-start;
  max-width: 100%;
  height: 400px;
  padding-left: 40px;
  padding-right: 40px;
  display: flex;
}

.title-section-3 {
  width: 60%;
  font-family: var(--font-family--font-family);
  color: var(--negro);
  text-transform: none;
  font-size: 100px;
  font-weight: 400;
  line-height: 0.9;
}

.text-section-3 {
  width: 400px;
  font-family: var(--font-family--principal-font);
  justify-content: flex-start;
  align-items: flex-start;
  display: block;
}

.div-block-2 {
  flex-flow: row;
  justify-content: space-between;
  align-items: flex-end;
  width: 100%;
  display: flex;
  position: sticky;
}

.code-embed-2 {
  width: 100%;
  color: var(--verde-primario);
}

.heading-5 {
  width: 100%;
  font-family: var(--_typography---lucida-grande);
  letter-spacing: 0;
  text-transform: uppercase;
  margin-bottom: 60px;
  font-size: 20px;
  font-weight: 400;
}

.container-8 {
  width: 100%;
  max-width: 100%;
  height: 100%;
  padding-bottom: 220px;
  padding-left: 40px;
  padding-right: 40px;
}

.heading-6 {
  font-family: var(--font-family--font-family);
  text-align: left;
  text-transform: uppercase;
  font-size: 70px;
  font-weight: 400;
  line-height: 90px;
}

.s3-cartera .heading-6,
.s3-cartera .heading-7,
.s3-cartera .paragraph-4 {
  color: var(--blanco);
}

.s3-cartera .cadafruta-eyebrow,
.s3-cartera .cadafruta-title {
  color: var(--blanco);
}

.s3-cartera .cadafruta-subtitle {
  color: #cfcfcf;
}

.s3-cartera .code-embed-2 hr {
  border-top-color: #ffffff24 !important;
}

.heading-7 {
  font-family: var(--font-family--font-family);
  letter-spacing: 0;
  text-transform: uppercase;
  margin-top: 20px;
  margin-bottom: 60px;
  font-size: 20px;
  font-weight: 400;
}

.paragraph-4 {
  width: 600px;
}

.container-9 {
  text-align: center;
  flex-flow: column;
  justify-content: center;
  align-items: center;
  max-width: 100%;
  padding-top: 100px;
  padding-left: 40px;
  padding-right: 40px;
  display: flex;
}

.heading-8 {
  font-family: var(--font-family--font-family);
  letter-spacing: 0;
  text-transform: uppercase;
  justify-content: center;
  align-items: center;
  margin-bottom: 60px;
  font-size: 20px;
  font-weight: 400;
  display: flex;
}

.heading-9 {
  width: 1100px;
  font-family: var(--font-family--font-family);
  text-align: center;
  text-transform: uppercase;
  font-size: 80px;
  font-weight: 400;
  line-height: 90px;
}

.paragraph-5 {
  width: 600px;
}

.container-11 {
  max-width: 100%;
  padding-top: 140px;
  padding-left: 40px;
  padding-right: 40px;
}

.heading-10 {
  font-family: var(--font-family--font-family);
  text-transform: uppercase;
  font-size: 80px;
  font-weight: 400;
  line-height: 90px;
}

.heading-11 {
  font-family: var(--font-family--font-family);
  letter-spacing: 0;
  text-transform: uppercase;
  margin-bottom: 60px;
  font-size: 20px;
  font-weight: 400;
}

.paragraph-6 {
  width: 800px;
}

.cms_carousel .wrapper_general {
  max-width: 100%;
  padding: 220px 40px 96px;
}

.center_headline {
  text-align: center;
  max-width: 1360px;
  margin-left: auto;
  margin-right: auto;
}

.carousel-eyebrow {
  color: var(--blanco);
  letter-spacing: 0;
  text-transform: uppercase;
  margin: 0 0 28px;
  font-family: var(--font-family--font-family);
  font-size: 20px;
  font-weight: 400;
}

.carousel_h2 {
  color: var(--blanco);
  letter-spacing: 0;
  text-transform: none;
  margin: 0;
  font-family: var(--font-family--font-family);
  font-size: 100px;
  font-weight: 400;
  line-height: 0.9;
}

.primary_c {
  color: var(--amarillo-banana);
}

.middle_ch {
  max-width: 620px;
  margin: 28px auto 0;
}

.base_txt {
  color: #d8d8d8;
  font-family: var(--font-family--principal-font);
  font-size: 18px;
  font-weight: 400;
  line-height: 1.55;
}

.div-block-11 {
  justify-content: flex-start;
  align-items: flex-start;
  width: 60%;
  display: flex;
}

.div-block-15 {
  flex-flow: column;
  justify-content: center;
  align-items: flex-end;
  display: flex;
}

.main-image {
  background-color: var(--gris);
  background-image: url('../images/texturas.jpg');
  background-position: 50%;
  background-repeat: no-repeat;
  background-size: cover;
  border-radius: 5px;
  width: 100%;
  height: 800px;
}

.list-item {
  background-color: var(--gris);
  border-radius: 5px;
  width: 130px;
  height: 160px;
  position: relative;
  overflow: hidden;
}

.list {
  grid-column-gap: 10px;
  grid-row-gap: 10px;
  flex-flow: column;
  justify-content: flex-start;
  align-items: center;
  width: 180px;
  padding-left: 0;
  display: flex;
  overflow: hidden;
}

.div-block-17 {
  z-index: 10;
  background-color: #00000070;
  height: 0%;
  display: block;
  position: absolute;
  inset: 0% 0% auto;
}

.thumbnail-1 {
  background-image: url('../images/texturas.jpg');
  background-position: 50%;
  background-size: cover;
  width: 100%;
  height: 100%;
}

.thumbnail-2 {
  background-image: url('../images/tarpless-banana-ripening-room.png');
  background-position: 50%;
  background-size: cover;
  height: 100%;
  position: relative;
}

.thumbnail-3 {
  background-image: url('../images/instalaciones-2.png');
  background-position: 50%;
  background-repeat: no-repeat;
  background-size: cover;
  height: 100%;
}

.thumbnail-4 {
  background-image: url('../images/instalaciones-5.png');
  background-position: 50%;
  background-repeat: no-repeat;
  background-size: cover;
  height: 100%;
}

.cms-carousel-container {
  width: 100%;
  max-width: 100%;
  padding: 0 30px 84px;
}

.cms-carousel-section {
  width: 100%;
}

.slider1 {
  width: 100%;
}

.slider1 .splide__track {
  width: 100%;
  overflow: visible;
}

.slider1 .splide__list {
  align-items: stretch;
}

.carousel_box {
  border-radius: 4px;
  width: 100%;
  height: 670px;
  position: relative;
  overflow: hidden;
}

.wrapper_carousel {
  z-index: 2;
  flex-flow: column;
  justify-content: space-between;
  width: 100%;
  height: 100%;
  padding: 48px;
  display: flex;
  position: absolute;
  inset: 0;
}

.description_carousel {
  color: var(--blanco);
  letter-spacing: 0;
  max-width: 760px;
  font-family: var(--font-family--principal-font);
  font-size: 22px;
  font-weight: 400;
  line-height: 1.28;
}

.title_carousel {
  color: var(--blanco);
  letter-spacing: 0;
  font-family: var(--font-family--font-family);
  font-size: 52px;
  font-weight: 400;
  line-height: 1;
}

.overlay_carousel {
  z-index: 1;
  background: linear-gradient(180deg, #00000082 0%, #00000030 42%, #000000bd 100%);
  position: absolute;
  inset: 0;
}

.image_box,
.carousel_box .image {
  width: 100%;
  height: 100%;
}

.carousel_box .image {
  object-fit: cover;
  display: block;
}

.splide__arrows.project_spec {
  grid-column-gap: 8px;
  justify-content: center;
  align-items: center;
  margin-top: 64px;
  display: flex;
}

.splide__arrow {
  color: var(--amarillo-acentos);
  background-color: #3a2409;
  border: 0;
  border-radius: 6px;
  justify-content: center;
  align-items: center;
  width: 48px;
  height: 48px;
  padding: 0;
  font-size: 28px;
  line-height: 1;
  display: flex;
}

.splide__pagination {
  display: none;
}

.div-block-19 {
  background-color: var(--gris);
  width: 100%;
  height: 100%;
}

.div-block-29 {
  grid-column-gap: 0px;
  grid-row-gap: 0px;
  flex-flow: row;
  justify-content: flex-start;
  align-items: flex-start;
  width: 100%;
  height: 100%;
  display: flex;
  overflow: visible;
}

.heading-13 {
  width: 430px;
  font-family: var(--font-family--principal-font);
  letter-spacing: 0;
  margin-top: 0;
  font-size: 38px;
  font-weight: 400;
  text-transform: none;
}

.text-block-6 {
  border: 1px solid var(--gris);
  text-align: center;
  border-radius: 99px;
  width: 50px;
  height: 50px;
  font-size: 30px;
  line-height: 50px;
}

.div-block-31 {
  width: 5%;
  height: 80px;
}

.item-content {
  flex-flow: column;
  flex: 0 auto;
  justify-content: space-between;
  align-self: stretch;
  align-items: flex-start;
  width: 35%;
  padding-right: 40px;
  display: flex;
  overflow: visible;
}

.paragraph-8 {
  letter-spacing: 0;
  width: 450px;
  font-size: 18px;
  line-height: 24px;
}

.s4-ciencia-header {
  background-color: var(--amarillo-banana);
  margin-bottom: 40px;
  padding: 100px 40px 60px;
}

/* Réplica del referente (IX2 SCROLLING_IN_VIEW): la imagen CRECE animando
   width/height, pero ligada al scroll con suavizado fuerte (su smoothing:82).
   El JS hace gsap.to(width/height) con scrub alto. */
.imagen-item-1 {
  width: 28%;
  height: 16em;
  position: relative;
  overflow: hidden;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  transform: translateZ(0);
  will-change: width, height;
  /* aísla el re-rasterizado del object-fit a su propia capa (no cambia la animación) */
  contain: layout paint;
}

.imagen-item-2,
.imagen-item-3 {
  backface-visibility: hidden;
  will-change: width, height, transform;
  width: 28%;
  height: 16em;
  transform-style: preserve-3d;
  border-radius: 20px;
  position: relative;
  inset: 0;
  overflow: hidden;
  transform: translateZ(0);
}

.imagen-item-4 {
  backface-visibility: hidden;
  will-change: width, height, transform;
  width: 28%;
  height: 16em;
  transform-style: preserve-3d;
  border-radius: 20px;
  position: relative;
  inset: 0;
  transform: translateZ(0);
}

.box-imagen {
  width: 100%;
  height: 100%;
  margin-left: 200px;
  position: relative;
  overflow: hidden;
}

.image {
  vertical-align: middle;
  object-fit: cover;
  width: 100%;
  height: 100%;
}

.image-tech-list {
  object-fit: cover;
  border-radius: 10px;
  width: 100%;
  height: 100%;
  display: block;
  position: absolute;
  overflow: hidden;
}

.image-2 {
  object-fit: cover;
  border-radius: 20px;
  width: 100%;
  height: 100%;
}

.image-3 {
  object-fit: cover;
  width: 100%;
  height: 100%;
}

.image-tech-wrapper {
  will-change: height;
  width: 28%;
  height: 16em;
  transition-property: height;
  transition-duration: .8s;
  transition-timing-function: cubic-bezier(.25, .46, .45, .94);
  position: relative;
  overflow: hidden;
}

.content-arrow {
  background-color: var(--background-color);
  -webkit-backdrop-filter: blur(5px);
  backdrop-filter: blur(5px);
  color: #fff;
  justify-content: center;
  align-items: center;
  display: block;
  overflow: hidden;
}

@media screen and (max-width: 991px) {
  /* Antes forzaba fondo verde sólido + position:sticky, pisando el tema
     is-light/is-solid del header (que ya maneja .section-header en
     position:fixed) — dejaba una franja transparente entre el borde real
     de la pantalla y donde empezaba el verde, y el header siempre se veía
     sólido en vez de respetar el tema real de la sección visible. */
  .nav-menu-content {
    width: 100%;
    padding-left: 15px;
    padding-right: 20px;
    display: flex;
  }

  /* Logo del header en mobile: -40% (58px/128px → 35px/77px) y luego
     +20% sobre ese tamaño (35px/77px → 42px/92px) */
  #logo .symbol {
    width: 42px;
  }

  #logo .freshbox-typo {
    width: 92px;
  }
}

@media screen and (max-width: 767px) {
  .nav-menu-content {
    align-self: center;
  }
}



/* ============================================================
   7 ETAPAS DEL PLÁTANO — Banana Scroll Cinematic
   ============================================================ */

.section-5 {
  position: relative;
  padding: 0;
  margin: 0;
}

.s-banana-intro {
  height: calc(100svh / var(--page-scale));
  background-color: var(--blanco);
}

.s2-banana {
  position: relative;
  height: calc(100dvh / var(--page-scale));
  display: flex;
  align-items: center;
  overflow: hidden;
  background-color: var(--blanco);
  z-index: 3;
}

/* ============================================================
   STACKING ESCALONADO — cortina entre secciones
   Hero z:1 → S2 z:3 → S3/S4/S5/S6 z:5 → Cadencia/Footer z:100
   Dentro de z:5, DOM order decide quién pinta encima.
   ============================================================ */

/* Hero: fluye normal y sale del viewport; z:1 solo durante su pantalla inicial */

/* S3 (cartera) y S4 (ciencia) — z:5 para quedar encima de S2 y Hero; sin sticky */
.section-4,
.section-3 {
  position: relative;
  z-index: 5;
}

/* Fondos sólidos necesarios para cubrir la sección anterior */
.section-4 {
  background-color: #0d0d0d;
}

.section-3 {
  background-color: var(--blanco);
}

/* S5 (pipeline) — position:relative; el pin lo maneja GSAP (.s5-sticky) */
.s5-wrapper {
  position: relative;
  z-index: 5;
}

/* S6 (eco) — hermano de S5, fluye sobre todo lo anterior */
.s6-outer {
  position: relative;
  z-index: 5;
}

/* Cadencia y Footer — siempre encima de todo */
.section-cadencia {
  z-index: 100;
}

/* position:relative definido más abajo */
footer.site-footer {
  position: relative;
  z-index: 100;
}

.banana-header {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: 60px 40px;
  box-sizing: border-box;
}

.banana-scroll-wrapper {
  height: calc(800svh / var(--page-scale));
}

/* ── Fondo de video ────────────────────────────── */
.bi-bg {
  position: absolute;
  inset: 0;
  z-index: 0;
}

.bi-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  /* Sale/entra desenfocado y con un leve zoom (mismo lenguaje que el
     crossfade de S3.1) en vez de un opacity plano — se ve más cuidado. */
  filter: blur(18px);
  transform: scale(1.06);
  transition: opacity 0.9s ease, filter 0.9s ease, transform 0.9s ease;
  will-change: opacity, filter, transform;
}

.bi-video.is-active {
  opacity: 1;
  filter: blur(0);
  transform: scale(1);
}

/* El fondo del clip del banano mide RGB~240 (medido directamente sobre
   frames extraídos de los 3 videos); palta y mango miden RGB~252 — gris
   neutro en los tres casos, sin tinte de color que corregir, solo falta
   brillo. Factor calculado de esos valores reales: 252/240 ≈ 1.05. */
.bi-video--banano {
  filter: blur(18px) brightness(1.05);
}
.bi-video--banano.is-active {
  filter: blur(0) brightness(1.05);
  /* Toque leve de opacidad (-3%) para que el blanco de fondo se filtre
     un poco a través del clip y ayude a fundirlo con el resto. */
  opacity: 0.97;
}

.bi-overlay {
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse at center, transparent 50%, rgba(0,0,0,0.18) 100%);
  z-index: 1;
}

/* Mobile: el CONTENEDOR sigue exactamente igual (100% del viewport, sin
   achicarlo ni dejar margen alrededor — nada de transform:scale en la caja).
   Lo que cambia es cómo el video encuadra su contenido: object-fit:cover
   (el original) recorta el video para RELLENAR todo el cuadro, así que en
   un viewport angosto/alto corta los costados de la fruta; object-fit:
   contain en cambio encoge el video ENTERO (sin recortarlo) para que quepa
   completo dentro del mismo cuadro de 100% — deja franjas del blanco de
   fondo arriba/abajo (o a los lados, según el video), pero la fruta se ve
   completa y más chica, sin tocar el tamaño real del contenedor. */
@media (max-width: 767px) {
  .bi-bg {
    background-color: var(--blanco);
  }
  .bi-video {
    object-fit: contain;
    /* -15% sobre el resultado anterior (1.8876 * 0.85 = 1.60446) — mismo
       leve zoom de entrada de siempre (1.06→1), reescalado igual. */
    transform: scale(1.7007276);
    /* 50% = centro exacto. Subido 10% más desde 40% → 35%. */
    object-position: center 35%;
    /* El borde recto del video (rectángulo del clip) se notaba contra el
       blanco de fondo — un degradé lineal en el eje vertical no alcanzaba
       a disimular los bordes izq/der. Viñeta radial: centro (donde está
       la fruta, siguiendo el mismo 35% de object-position) queda 100%
       opaco sin perder nada de la fruta; el óvalo se desvanece a
       transparente hacia TODOS los bordes del cuadro por igual, fundiendo
       el rectángulo del clip con el blanco de fondo en vez de cortarlo. */
    -webkit-mask-image: radial-gradient(
      ellipse 68% 62% at 50% 35%,
      black 50%,
      black 72%,
      transparent 100%
    );
    mask-image: radial-gradient(
      ellipse 68% 62% at 50% 35%,
      black 50%,
      black 72%,
      transparent 100%
    );
  }
  .bi-video.is-active {
    transform: scale(1.60446);
  }

  /* La viñeta (mask-image de arriba) depende de calcular en qué punto
     exacto cae el borde real del video, que varía según el aspect ratio
     de cada clip — no siempre calza. Esto es más robusto: un velo con el
     BLANCO real de fondo (no solo opacidad), de transparente a sólido,
     superpuesto sobre el último tramo inferior — funde el borde con lo
     que hay detrás sin importar dónde caiga exactamente. */
  .bi-bg::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 24%;
    background: linear-gradient(to bottom, transparent 0%, var(--blanco) 88%);
    z-index: 1;
    pointer-events: none;
  }
}

/* ── Navegación: mismo sistema que S3 (.s3v-nav/.s3v-tabs__arrow/
   .s3v-progress) — flechas abajo a la izquierda + barra de progreso a
   todo el ancho, sin contenedor, pegada al borde inferior. ─────────── */
.bi-nav {
  position: absolute;
  z-index: 4;
  left: 40px;
  bottom: 100px;
  display: flex;
  align-items: center;
  gap: 6px;
}
.bi-tabs__arrow {
  width: 80px;
  height: 80px;
  border: none;
  border-radius: 50%;
  background: rgba(19, 19, 19, 0.119);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  color: #fff;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: background 0.2s ease;
}
.bi-tabs__arrow:hover { background: rgba(19, 19, 19, 0.65); }
.bi-tabs__arrow svg { display: block; }
.bi-tabs__playpause svg[hidden] { display: none; }

/* Contador + barra de progreso lineal: a diferencia de S3 (duración fija
   --s3v-dur), acá el fill sigue el avance REAL del video activo
   (duración distinta por fruta) — lo mueve initS2Videos() en main.js
   frame a frame (timeupdate), no una animación CSS. */
.bi-progress {
  position: absolute;
  z-index: 3;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 0 40px 14px;
}
.bi-progress__count {
  font-family: var(--font-secundaria);
  font-size: 13px;
  letter-spacing: 1px;
  color: rgba(90, 90, 90, 0.9);
  white-space: nowrap;
}
.bi-progress__track {
  position: relative;
  flex: 1 1 auto;
  height: 2px;
  border-radius: 2px;
  background: rgb(255, 255, 255);
  overflow: hidden;
}
.bi-progress__bar {
  position: absolute;
  inset: 0;
  background: #3e7319;
  transform-origin: left center;
  transform: scaleX(0);
  will-change: transform;
  transition: transform 0.2s linear;
}

@media (max-width: 991px) {
  .bi-nav { left: 20px; bottom: 34px; }
  .bi-progress { padding: 0 20px 10px; }
}
@media (max-width: 600px) {
  .bi-nav { left: 16px; }
  .bi-progress { padding: 0 16px 8px; }
  .bi-progress__count { font-size: 11px; }
}

/* Flechas + play/pause 50% más chicos en mobile — misma estructura
   (círculo con ícono centrado) y misma ubicación (.bi-nav no cambia de
   left/bottom acá), solo la mitad de tamaño. El ícono SVG interno se
   reduce en la misma proporción para no verse desbalanceado dentro del
   círculo más chico. */
@media (max-width: 767px) {
  .bi-tabs__arrow {
    width: 40px;
    height: 40px;
  }
  .bi-tabs__arrow svg {
    width: 22px;
    height: 22px;
  }
}

/* ── Copy encima ───────────────────────────────── */
#bananaIntro {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-columns: 35% 40% 25%;
  align-items: center;
  width: 100%;
  padding: 0 40px;
  box-sizing: border-box;
}

.bi-left {
  display: flex;
  flex-direction: column;
  gap: 20px;
  align-items: flex-start;
}

.bi-spacer {
  /* columna central vacía — el video se ve a través */
}

.bi-right {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

#bananaIntro .bi-eyebrow {
  font-family: var(--_typography---lucida-grande);
  font-size: 1rem;
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 5px;
  color: var(--negro);
  margin: 0;
  line-height: 1.4;
}

#bananaIntro .bi-title {
  font-family: var(--_typography---lucida-grande);
  font-size: clamp(2.4rem, calc(5vw / var(--page-scale)), 4rem);
  font-weight: 400;
  line-height: 0.95;
  letter-spacing: 0;
  text-transform: none;
  text-align: left;
  color: var(--negro);
  margin: 0;
}

#bananaIntro .bi-copy {
  font-family: var(--font-family--principal-font);
  font-size: 18px;
  font-weight: 400;
  color: var(--negro);
  margin: 0;
  text-align: left;
  text-wrap: balance;
  line-height: 1.4;
}

/* Mobile: layout vertical en vez de columnas — título arriba, descripción
   abajo, ocupando el alto completo de la sección entre el header (arriba)
   y las flechas/barra de progreso (abajo), que quedan fuera de este grid
   (son .bi-nav/.bi-progress, position:absolute, hermanos de #bananaIntro). */
@media (max-width: 767px) {
  .s2-banana {
    align-items: stretch;
  }

  #bananaIntro {
    grid-template-columns: none;
    display: flex;
    flex-direction: column;
    /* Título y descripción juntos, ambos pegados al bottom (antes
       space-between los separaba a los extremos) — el video/fruta queda
       visualmente libre en la mitad superior de la sección. */
    justify-content: flex-end;
    gap: 20px;
    align-items: stretch;
    height: 100%;
    padding: 110px 20px 90px;
  }

  .bi-spacer {
    display: none;
  }

  .bi-right {
    align-items: flex-start;
  }

  /* Título -10% adicional en mobile (2.16rem/3.6rem → 1.944rem/3.24rem) */
  #bananaIntro .bi-title {
    font-size: clamp(1.944rem, calc(4.05vw / var(--page-scale)), 3.24rem);
  }
}

.banana-sticky {
  position: sticky;
  /* cubre viewport desde el inicio, antes de que GSAP tome control */
  top: 0;
  z-index: 2;
  /* encima del hero — S2 desliza sobre él */
  width: 100%;
  height: calc(100svh / var(--page-scale));
  background: #080808;
  overflow: hidden;
}

/* Transform stage: centered, GSAP offsets applied here */
.banana-stage {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 0;
  height: 0;
  will-change: transform;
  transform-origin: center center;
}

/* SVG offset by half its rendered size to center it */
.banana-svg {
  position: absolute;
  width: 180px;
  height: auto;
  top: -205px;
  left: -90px;
  display: block;
  overflow: visible;
}

.banana-fill {
  fill: #2d5a1b;
}

.banana-stem {
  fill: #5a3a1a;
}

.banana-ridge {
  fill: none;
  stroke: rgba(255, 255, 255, 0.28);
  stroke-width: 8;
  stroke-linecap: round;
  opacity: 0.75;
}

.banana-spot {
  fill: #8b4513;
  opacity: 0;
}

/* Grade Overlays — flex column, posición horizontal por grado */
.grade-overlay {
  position: absolute;
  inset: 0;
  opacity: 0;
  pointer-events: none;
  z-index: 5;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: 60px 40px;
  box-sizing: border-box;
}

.go-block {
  display: flex;
  flex-direction: column;
  max-width: 480px;
}

.grade-overlay[data-grade="2"] {
  align-items: flex-start;
  padding-left: 6%;
}

.grade-overlay[data-grade="3"] {
  align-items: flex-end;
  padding-right: 6%;
}

.grade-overlay[data-grade="3.5"] {
  align-items: flex-start;
  padding-left: 14%;
}

.grade-overlay[data-grade="4"] {
  align-items: center;
}

.grade-overlay[data-grade="5"] {
  align-items: flex-end;
  padding-right: 12%;
}

.grade-overlay[data-grade="6"] {
  align-items: flex-start;
  padding-left: 6%;
}

.grade-overlay[data-grade="7"] {
  align-items: center;
  padding-left: 8%;
}

.go-eyebrow {
  font-family: var(--_typography---lucida-grande);
  font-size: 1rem;
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 5px;
  color: var(--negro);
  margin: 0;
  line-height: 100px;
}

.go-title-group {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: 24px;
}

.go-title {
  font-family: var(--_typography---lucida-grande);
  font-size: 3.2rem;
  font-weight: 400;
  line-height: 1.04;
  letter-spacing: -.01em;
  text-transform: none;
  color: var(--negro);
  margin: 0;
  text-wrap: balance;
}

.go-subtitle {
  font-family: var(--font-family--principal-font);
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--negro);
  margin: 6px 0 0;
}

.go-copy {
  font-family: var(--font-family--principal-font);
  font-size: 18px;
  font-weight: 500;
  color: var(--negro);
  max-width: 100%;
  margin: 0;
  text-align: left;
  text-wrap: balance;
}

/* Progress dots */
.banana-progress {
  position: absolute;
  bottom: 40px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: 12px;
  align-items: center;
  z-index: 10;
}

.bp-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #d0d0d0;
  transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1),
    background 0.4s cubic-bezier(0.4, 0, 0.2, 1);
  display: block;
}

.bp-dot.active {
  transform: scale(1.75);
  background: #c8e640;
}

@media (max-width: 768px) {
  .banana-svg {
    width: 100px;
    top: -112px;
    left: -50px;
  }

  .grade-overlay {
    padding: 40px 24px;
    align-items: flex-start !important;
    padding-left: 24px !important;
  }
}

/* ============================================================
   SECCIÓN 3 — Header de Cada Fruta, Un Ritmo
   ============================================================ */

.cadafruta-header {
  text-align: center;
  max-width: 720px;
  margin: 0 auto 60px;
  padding: 0 24px;
}

.cadafruta-eyebrow {
  font-family: var(--font-family--principal-font);
  font-size: 13px;
  font-weight: 400;
  letter-spacing: 0;
  text-transform: uppercase;
  color: #1a1a1a;
  margin: 0 0 20px;
}

.cadafruta-title {
  font-family: var(--font-family--font-family);
  font-size: clamp(32px, calc(5vw / var(--page-scale)), 56px);
  font-weight: 400;
  letter-spacing: 0;
  line-height: 1.1;
  color: #1a1a1a;
  margin: 0 0 16px;
}

.cadafruta-subtitle {
  font-family: var(--font-family--principal-font);
  font-size: 18px;
  font-weight: 400;
  color: #555;
  margin: 0;
}

.bt-body {
  font-family: var(--font-family--principal-font);
  font-size: 15px;
  font-weight: 400;
  line-height: 1.65;
  color: rgba(255, 255, 255, 0.5);
  max-width: 320px;
  margin-top: 16px;
}

/* ============================================================
   BORRADOR — SECCIONES NUEVAS
   ============================================================ */

/* ── ROADMAP ── */
.section-roadmap {
  background-color: var(--blanco);
  padding: 120px 0 100px;
  position: relative;
  z-index: 10;
}

.roadmap-container {
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 40px;
}

.roadmap-header {
  margin-bottom: 80px;
}

.roadmap-eyebrow {
  font-size: 11px;
  letter-spacing: 0;
  text-transform: uppercase;
  color: var(--verde-primario);
  margin-bottom: 16px;
}

.roadmap-title {
  font-size: clamp(1.6rem, calc(4vw / var(--page-scale)), 2.56rem);
  font-weight: 400;
  color: var(--negro);
  line-height: 1.1;
  letter-spacing: 0;
}

.roadmap-list {
  display: flex;
  flex-direction: column;
  gap: 0;
}

.roadmap-item {
  display: flex;
  align-items: flex-start;
  gap: 60px;
  padding: 60px 0;
  border-top: 1px solid rgba(0, 0, 0, .1);
}

.roadmap-item__left {
  display: flex;
  gap: 32px;
  flex: 1;
  align-items: flex-start;
}

.roadmap-num {
  font-size: 11px;
  letter-spacing: 0;
  color: rgba(0, 0, 0, .3);
  padding-top: 6px;
  min-width: 28px;
}

.roadmap-item__title {
  font-size: clamp(1.04rem, calc(2.5vw / var(--page-scale)), 1.52rem);
  font-weight: 400;
  color: var(--negro);
  margin-bottom: 16px;
  letter-spacing: 0;
}

.roadmap-item__desc {
  font-size: 15px;
  color: rgba(0, 0, 0, .55);
  line-height: 1.65;
  max-width: 420px;
}

.roadmap-item__right {
  flex: 0 0 42%;
}

.roadmap-img-wrap {
  border-radius: 12px;
  overflow: hidden;
  aspect-ratio: 3/2;
  transition: transform .6s cubic-bezier(.25, .46, .45, .94);
}

.roadmap-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.roadmap-item.is-active .roadmap-img-wrap {
  transform: scale(1.04);
}

.roadmap-item.is-active .roadmap-item__title {
  color: var(--verde-primario);
}

/* ── IMPACTO ECOLÓGICO ── */
.section-6.impacto {
  background-color: var(--blanco);
  padding: 100px 40px 120px;
  position: relative;
  z-index: 10;
}

.impacto__header {
  text-align: center;
  margin-bottom: 80px;
}

.impacto__eyebrow {
  font-size: 11px;
  letter-spacing: 0;
  text-transform: uppercase;
  color: var(--verde-primario);
  margin-bottom: 16px;
  display: block;
}

.impacto__title {
  font-size: clamp(1.44rem, calc(3.5vw / var(--page-scale)), 2.24rem);
  font-weight: 400;
  color: var(--negro);
  line-height: 1.15;
  letter-spacing: 0;
}

.impacto__pin {
  max-width: 1100px;
  margin: 0 auto;
}

.impacto__ruta {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  position: relative;
  padding: 40px 0 60px;
}

.nodo {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  text-align: center;
  flex: 1;
  position: relative;
  z-index: 2;
  opacity: .35;
  transition: opacity .4s ease;
}

.nodo.is-active {
  opacity: 1;
}

.nodo__icono {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  border: 1.5px solid currentColor;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--negro);
  background: var(--blanco);
  transition: background .4s, color .4s, border-color .4s;
}

.nodo.is-active .nodo__icono {
  background: var(--verde-primario);
  color: var(--blanco);
  border-color: var(--verde-primario);
}

.nodo__icono svg {
  width: 20px;
  height: 20px;
}

.nodo__titulo {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: uppercase;
  color: var(--negro);
}

.nodo__texto {
  font-size: 12px;
  color: rgba(0, 0, 0, .5);
  line-height: 1.5;
  max-width: 120px;
}

.impacto__linea {
  position: absolute;
  top: 64px;
  left: 10%;
  width: 80%;
  height: 4px;
  z-index: 1;
}

.linea__base {
  stroke: rgba(0, 0, 0, .1);
  stroke-width: 4;
  fill: none;
}

.linea__progreso {
  stroke: var(--verde-primario);
  stroke-width: 4;
  fill: none;
  stroke-dasharray: 1000;
  stroke-dashoffset: 1000;
  transition: stroke-dashoffset .6s ease;
}

.impacto__cierre {
  text-align: center;
  font-size: clamp(1rem, calc(2vw / var(--page-scale)), 1.3rem);
  font-style: italic;
  color: rgba(0, 0, 0, .45);
  margin-top: 48px;
  letter-spacing: 0;
}

/* ── CLIENTES ── */
.section-clientes {
  background-color: #0d0d0d;
  color: var(--blanco);
  padding: 100px 0 80px;
  position: relative;
  z-index: 10;
}

.clientes__header {
  text-align: center;
  padding: 0 40px;
  margin-bottom: 60px;
}

.clientes__eyebrow {
  font-size: 11px;
  letter-spacing: 0;
  text-transform: uppercase;
  color: rgba(255, 255, 255, .4);
  margin-bottom: 16px;
  display: block;
}

.clientes__title {
  font-size: clamp(1.28rem, calc(3vw / var(--page-scale)), 1.92rem);
  font-weight: 400;
  color: var(--blanco);
  letter-spacing: 0;
  margin-bottom: 12px;
}

.clientes__sub {
  font-size: 14px;
  color: rgba(255, 255, 255, .4);
  font-style: italic;
}

.clientes__carousel-wrap {
  padding: 0 40px;
}

.cliente-card {
  border-radius: 12px;
  overflow: hidden;
  background: #1a1a1a;
  display: flex;
  flex-direction: column;
}

.cliente-card__img {
  height: 240px;
  background-size: cover;
  background-position: center;
}

.cliente-card__body {
  padding: 24px;
}

.cliente-card__nombre {
  font-size: 11px;
  letter-spacing: 0;
  text-transform: uppercase;
  color: rgba(255, 255, 255, .35);
  margin-bottom: 10px;
}

.cliente-card__txt {
  font-size: 14px;
  color: rgba(255, 255, 255, .7);
  line-height: 1.6;
  font-style: italic;
}

/* ── CADENCIA — estilos movidos a bloque S7 más abajo ── */
.section-cadencia-legacy {
  /* regla vaciada — ver bloque S7 */
}

.cadencia__wrap {
  max-width: 680px;
  text-align: center;
}

.cadencia__manifiesto {
  font-size: clamp(0.88rem, calc(2.2vw / var(--page-scale)), 1.2rem);
  font-weight: 400;
  color: rgba(0, 0, 0, .65);
  line-height: 1.8;
  margin-bottom: 40px;
  letter-spacing: 0;
}

.cadencia__declaracion {
  font-size: clamp(1.04rem, calc(2.5vw / var(--page-scale)), 1.52rem);
  font-weight: 400;
  color: var(--negro);
  line-height: 1.3;
  margin-bottom: 40px;
  letter-spacing: 0;
}

.cadencia__cierre {
  font-size: 14px;
  color: rgba(0, 0, 0, .4);
  letter-spacing: 0;
  text-transform: uppercase;
  margin-bottom: 48px;
}

.cadencia__cta-txt {
  font-size: 15px;
  color: rgba(0, 0, 0, .5);
  margin-bottom: 32px;
}

.btn-cadencia {
  display: inline-flex;
  align-items: center;
  padding: 14px 40px;
  background: var(--verde-primario);
  color: var(--blanco);
  border-radius: 100px;
  font-size: 13px;
  letter-spacing: 0;
  text-transform: uppercase;
  text-decoration: none;
  transition: background .3s, transform .3s;
}

.btn-cadencia:hover {
  background: #2f5a12;
  transform: translateY(-2px);
}

/* ── FOOTER — estructura Diamond Rose Sanctuary / 100svh ── */
/* ═══════════════════════════════════════════════════════════
   S8 · FOOTER — layout BRANT-style
   ═══════════════════════════════════════════════════════════ */
.site-footer {
  background: #131313;
  color: rgba(255, 255, 255, .8);
  position: relative;
  z-index: 10;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  /* 50svh exactos (antes min-height:80svh): junto con #marcas en 50svh (ver
     .s6b-marcas), ambas secciones forman una sola "página" de 100svh —
     arriba el carrusel de clientes (fondo blanco), abajo el footer (fondo
     negro). overflow:hidden + el recorte de paddings/gaps de acá abajo
     evitan que el contenido empuje el alto real más allá de los 50svh. */
  height: calc(50svh / var(--page-scale));
  overflow: hidden;
  font-family: var(--font-family--principal-font), sans-serif;
}

/* CUERPO */
.footer__body {
  padding: 32px 40px 0;
}

/* TOP GRID: logo izquierda · columnas menú derecha */
.footer__top-grid {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 80px;
}

/* Etiquetas de columna */
.footer__col-label {
  font-size: 0.6875rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, .4);
  margin: 0 0 20px;
  font-family: var(--font-family--principal-font), sans-serif;
}

/* COL LOGO — lockup horizontal, igual al header (Social se movió a la
   columna Contacto, ver .footer__col-contact) */
.footer__col-logo {
  flex: 0 0 auto;
  display: flex;
  align-items: flex-start;
}

.footer__logo-wrap {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 24px;
  color: rgba(255, 255, 255, .88);
}

.footer__logo-symbol {
  flex-shrink: 0;
}

.footer__logo-symbol svg {
  /* Más presencia (antes 56px, achicado cuando el footer bajó a 50svh y
     Social vivía debajo) — con Social ahora en Contacto, sobra alto para
     que el logo vuelva a ser protagonista. */
  width: 92px;
  height: 92px;
  display: block;
}

.footer__logo-wordmark svg {
  height: 48px;
  width: auto;
  display: block;
}

/* COLUMNAS DE MENÚ — grid 3×1, 60% ancho, empujado a la derecha */
.footer__nav-columns {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-column-gap: 32px;
  width: 60%;
  margin-left: auto;
}

/* COL NAV */
.footer__col-nav {
  display: flex;
  flex-direction: column;
}

.footer__nav {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.footer__nav-link {
  font-size: 0.8rem;
  color: rgba(255, 255, 255, .72);
  text-decoration: none;
  transition: color .2s;
  line-height: 1.2;
}

.footer__nav-link:hover {
  color: #fff;
}

/* COL SEDE */
.footer__col-sede {
  display: flex;
  flex-direction: column;
}

.footer__hq-text {
  font-size: 0.8rem;
  color: rgba(255, 255, 255, .72);
  line-height: 1.5;
  margin: 0;
}

/* COL CONTACTO */
.footer__col-contact {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.footer__contact-link {
  font-size: 0.8rem;
  color: rgba(255, 255, 255, .72);
  text-decoration: none;
  transition: color .2s;
  line-height: 1.2;
}

.footer__contact-link:hover {
  color: #fff;
}

/* SLOGAN GRANDE — ocupa el espacio disponible, texto anclado al fondo */
.footer__slogan-wrap {
  flex: 1;
  min-height: 0; /* deja que flex:1 lo achique de verdad dentro del footer de 50svh, en vez de imponer su alto natural */
  display: flex;
  align-items: flex-end;
  padding: 16px 60px 0;
  overflow: hidden;
}

.footer__slogan {
  /* El tamaño real lo fija fitFooterSlogan() en JS — mide el ancho
     disponible del wrap y el ancho natural del texto (ambos en
     "espacio de diseño", ajenos al transform de #scaleWrapper) y
     calcula el font-size exacto para que quepa siempre, en cualquier
     escala. Este clamp es solo el valor de arranque antes de que JS
     corra (o si JS falla). */
  font-size: clamp(3rem, 18vw, 280px);
  text-align: center;
  font-weight: 400;
  line-height: 0.88;
  letter-spacing: 0.08em;
  color: rgba(255, 255, 255, .22);
  margin: 0;
  text-transform: none;
  white-space: nowrap;
  font-family: var(--font-family--principal-font), sans-serif;
}

/* STRIP INFERIOR */
.footer__strip {
  border-top: 1px solid rgba(255, 255, 255, .1);
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 14px 60px;
  margin-top: 0;
  flex-shrink: 0;
}

.footer__copy {
  font-size: 0.8125rem;
  color: rgba(255, 255, 255, .38);
  margin: 0;
}

.footer__credit {
  font-size: 0.8125rem;
  color: rgba(255, 255, 255, .38);
  margin: 0;
}

.footer__credit-link {
  color: rgba(255, 255, 255, .38);
  text-decoration: none;
  transition: color .2s;
}

.footer__credit-link:hover {
  color: rgba(255, 255, 255, .75);
}

/* El footer comparte con #marcas la regla "50svh cada uno = 100svh
   juntos" en DESKTOP. En mobile eso se probó insuficiente en dos rondas:
   primero se liberó a alto natural (el contenido no entraba ni en
   100svh), y con las tipografías más chicas de esa vuelta tampoco
   entraba en 50svh. Con el menú ahora en 16.2px (ver abajo) el conjunto
   volvió a crecer, así que se vuelve a un molde de 100svh — igual que
   las demás secciones — pero esta vez confirmado por medición real que
   el contenido entra completo (ver comentario en .site-footer). */
@media (max-width: 767px) {
  /* Con el menú/slogan/strip ya reducidos (ver más abajo), el contenido
     natural del footer mide ~655px contra un viewport típico de 664-740px
     — entra completo en un solo 100svh. Se normaliza al mismo molde que
     el resto de las secciones (height:100svh/overflow:hidden) en vez del
     alto libre que tenía antes — a pedido explícito, medido en varios
     tamaños de pantalla (667/664/740px de alto) antes de aplicarlo. */
  .site-footer {
    height: calc(100svh / var(--page-scale));
    overflow: hidden;
  }
  .footer__body {
    padding: 32px 24px 0;
  }
  .footer__top-grid {
    flex-direction: column;
    gap: 48px;
  }
  .footer__nav-columns {
    width: 100%;
    margin-left: 0;
    grid-template-columns: 1fr 1fr;
    gap: 24px 32px;
  }
  .footer__slogan-wrap {
    /* Aire arriba 40px; abajo 20px (-50% respecto a los 40px previos) para
       acercar el slogan a la línea divisoria de .footer__strip — a pedido
       explícito. */
    padding: 40px 24px 20px;
    /* El texto se centra dentro de ESTE ancho, no del suyo propio (ver
       .footer__slogan más abajo: width:100% + text-align:center) */
    justify-content: center;
  }
  .footer__strip {
    padding: 14px 24px;
    flex-direction: column;
    align-items: flex-start;
    gap: 6px;
  }

  /* Logo del footer — mismo tamaño que el del header en mobile (ver
     #logo .symbol/.freshbox-typo, @media 991px: 42px/92px) — a pedido
     explícito, antes era notoriamente más grande (92px/alto:48px). */
  .footer__logo-symbol svg {
    width: 42px;
    height: 42px;
  }
  .footer__logo-wordmark svg {
    width: 92px;
    height: auto;
  }
  .footer__logo-wrap {
    gap: 14px;
  }

  /* -40% (al menos) en la tipografía del footer — a pedido explícito.
     col-label sube después al mismo 16.2px que el menú (nav-link/
     hq-text/contact-link, ver abajo) — la descripción estándar del
     sitio (ver #bananaIntro .bi-copy / .text-section-3 / .s3v-copy__
     desc / #s3-2 .s32-head__note, todas en 16.2px en mobile), con
     font-weight:500 para distinguirse como label. */
  .footer__col-label {
    /* -15% sobre los 16.2px del menú/descripción estándar — a pedido
       explícito, para que el label quede un escalón por debajo de los
       links que agrupa. */
    font-size: 13.8px;
    font-weight: 500;
    margin-bottom: 12px;
  }
  .footer__nav-link,
  .footer__hq-text,
  .footer__contact-link {
    font-size: 16.2px;
    line-height: 1.4;
  }

  /* Slogan: el font-size lo termina fijando fitFooterSlogan() en JS (ver
     main.js) para que "Full Year Fruit" quepa siempre completo y
     centrado dentro del viewport, en vez de desbordarse y recortarse
     contra overflow:hidden — a pedido explícito. Este clamp es solo el
     valor de arranque antes de que corra el JS. */
  .footer__slogan {
    font-size: clamp(2rem, 14vw, 120px);
    width: 100%;
  }

  /* Bottom strip: mucho más chico que el resto del footer para que cada
     línea (copyright y "Website by") entre completa sin envolver — a
     pedido explícito ("mucho más" que el -40% general de arriba). */
  .footer__copy,
  .footer__credit {
    font-size: 0.56rem;
  }
}

/* En móvil, el lockup de marca sustituye al slogan grande. */
.footer__mobile-logo { display: none; }
@media (max-width: 767px) {
  .footer__col-logo,
  .footer__slogan { display: none; }

  .footer__body {
    padding-top: var(--sidebar-header-h, 64px);
  }
  .footer__slogan-wrap {
    justify-content: flex-start;
  }

  .footer__mobile-logo {
    display: flex;
    width: min(100%, 260px);
    gap: 18px;
  }
  .footer__mobile-logo .footer__logo-symbol svg {
    width: 64px;
    height: 64px;
  }
  .footer__mobile-logo .footer__logo-wordmark {
    flex: 1;
    min-width: 0;
  }
  .footer__mobile-logo .footer__logo-wordmark svg {
    width: 100%;
    height: auto;
  }
}

/* ── CONVENCIÓN: Lucida Grande siempre en uppercase ── */
[style*="lucida-grande"],
.heading,
.heading-5,
.text-contact-hero,
.roadmap-title,
.roadmap-item__title {
  text-transform: uppercase;
}

/* ============================================================
   S3.1 / S3.2 — secciones base (tono negro de la paleta root)
   100svh cada una. Estructura lista para llenar de contenido.
   ============================================================ */
.sub-section {
  position: relative;
  z-index: 5;
  min-height: calc(100dvh / var(--page-scale));
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: var(--negro); /* #131313 */
}

.sub-section__inner {
  width: 100%;
  max-width: 1200px;
  padding: 0 80px;
}

.sub-section__tag {
  font-family: var(--font-secundaria);
  font-size: 0.875rem;
  font-weight: 400;
  letter-spacing: 4px;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.35);
}

@media (max-width: 767px) {
  .sub-section__inner { padding: 0 24px; }
}

/* ============================================================
   S3.2 — Titular + carrusel de tarjetas informativas (sin links)
   ============================================================ */
.sub-section--2 {
  /* anula el flex centrado de .sub-section: layout en columna */
  position: relative;
  isolation: isolate;
  display: block;
  height: calc(100dvh / var(--page-scale));
  overflow: hidden;
  /* clamp por vh en vez de un valor fijo: en laptops de poca altura
     (720-900px) 192px fijos no dejaban lugar para el carrusel + ficha
     técnica de abajo (quedaban cortados por el overflow:hidden). Debe
     coincidir con el cálculo de paddingTop en syncCardSize() (main.js). */
  padding: clamp(80px, calc(14svh / var(--page-scale)), 192px) 0 0;
  background:
    linear-gradient(180deg, #f4f4f4 0%, #eeeeee 56%, #e7e7e7 100%);
}

.sub-section--2::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
}
.sub-section--2::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 3;
  opacity: 0;
  background: #fff;
  transition: opacity 0.85s ease;
}
.sub-section--2::before {
  background:
    radial-gradient(ellipse at 10% 88%, rgba(88, 88, 88, 0.26) 0%, rgba(88, 88, 88, 0.13) 26%, rgba(88, 88, 88, 0) 58%),
    radial-gradient(ellipse at 90% 84%, rgba(88, 88, 88, 0.24) 0%, rgba(88, 88, 88, 0.12) 28%, rgba(88, 88, 88, 0) 60%),
    radial-gradient(ellipse at 50% 108%, rgba(88, 88, 88, 0.16) 0%, rgba(88, 88, 88, 0.07) 28%, rgba(88, 88, 88, 0) 62%),
    linear-gradient(90deg, rgba(88, 88, 88, 0.12) 0%, rgba(88, 88, 88, 0) 24%, rgba(88, 88, 88, 0) 76%, rgba(88, 88, 88, 0.12) 100%);
}
.sub-section--2 > * {
  position: relative;
  z-index: 1;
}
.s32.is-ready .s32-head,
.s32.is-ready .s32-stage {
  opacity: 0;
  filter: blur(14px);
  transform: translateY(24px);
  transition:
    opacity 0.95s ease,
    filter 0.95s ease,
    transform 0.95s cubic-bezier(0.22, 1, 0.36, 1);
}
.s32.is-ready.is-inview .s32-head,
.s32.is-ready.is-inview .s32-stage {
  opacity: 1;
  filter: blur(0);
  transform: translateY(0);
}
.s32.is-ready.is-inview .s32-head { transition-delay: 0.52s; }
.s32.is-ready.is-inview .s32-stage { transition-delay: 0.72s; }
.s32.is-exiting .s32-head,
.s32.is-exiting .s32-stage {
  opacity: 0;
  filter: blur(18px);
  transform: translateY(-18px);
  transition:
    opacity 0.62s ease,
    filter 0.62s ease,
    transform 0.62s cubic-bezier(0.65, 0, 0.35, 1);
}
.s32.is-exiting::after {
  opacity: 1;
}

/* El bonus de aire extra en pantallas altas (antes un @media
   (min-height:950px) fijo acá) ahora lo decide JS en syncCardSize()
   (main.js) — necesita saber si la tarjeta YA llega a su tope máximo
   ANTES de repartir el extra, algo que un media query ciego al
   presupuesto de la tarjeta no puede saber (le achicaba la tarjeta sin
   querer en 1920×1080, la resolución nativa más común). */

/* Header full width (gutter global = 40px) · dos columnas 70 / 30 */
.s32-head {
  display: flex;
  align-items: flex-end;
  gap: 48px;
  padding: 10px 40px 12px;
}

/* 85/15 (antes 70/30): con el título al tamaño del hero (S3.1), a 70% de
   columna el segundo renglón envolvía a una 3ª línea de más, lo que subía
   el alto del header y empujaba el carrusel/ficha hacia abajo. */
.s32-head__left  { flex: 75; min-width: 0; }
.s32-head__right {
  flex: 25;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 24px;
}

/* Mismo motivo que .s3v-eyebrow (Cartera de Maduración) — acá en negro,
   porque esta sección vive sobre fondo claro y no sobre foto. */
.s32-eyebrow {
  font-family: var(--_typography---lucida-grande);
  font-size: 1rem;
  font-weight: 400;
  letter-spacing: 5px;
  text-transform: uppercase;
  color: var(--negro);
  margin: 0 0 18px;
}

.s32-title {
  font-family: var(--_typography---lucida-grande);
  /* mismo tamaño que .s3v-title (el head de Cartera de Maduración, la
     section anterior) */
  font-size: clamp(1.944rem, calc(4.05vw / var(--page-scale)), 3.24rem);
  font-weight: 400;
  line-height: 0.95;
  letter-spacing: 0;
  color: var(--negro);
  margin: 0 0 40px;
  max-width: 720px;      /* ancho del título — evita una 3ª línea de más al tamaño del hero */
}

/* Bloque de refuerzo (columna derecha). Antes tenía un -webkit-line-clamp:4
   fijo: a los anchos donde esta columna (flex:25) se angosta más (zona
   laptop, ~992-1400px), el mismo texto envolvía a más de 4 líneas y el
   clamp lo recortaba a mitad de frase. Se quitó el clamp (el texto
   siempre se muestra completo, la columna crece lo alto que necesite) y
   el tamaño de letra pasa a escalar con el mismo patrón clamp()+vw/
   page-scale que usa el resto del sitio (ver .s32-title arriba), en vez
   de un valor fijo. */
.s32-head__note {
  margin: 0;
  font-family: var(--font-family--principal-font);
  font-size: clamp(0.82rem, calc(1.3vw / var(--page-scale)), 1.05rem);
  line-height: 1.5;
  color: rgba(19, 19, 19, 0.7);
}

/* Botón oscuro estilo referente: label arriba-izq, flecha abajo-der */
.s32-cta {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  width: 340px;
  max-width: 100%;
  min-height: 61px;       /* 1/3 menos que los 92px anteriores */
  padding: 11px 18px;
  background: var(--negro);
  color: #fff;
  border-radius: 8px;
  text-decoration: none;
  transition: background 0.3s ease, transform 0.3s ease;
}

.s32-cta:hover {
  background: #000;
}

.s32-cta__label {
  font-family: var(--font-secundaria);
  font-size: 0.95rem;
  letter-spacing: 0.2px;
}

.s32-cta__arrow {
  align-self: flex-end;
  font-size: 1.15rem;
  line-height: 1;
}

/* — Pista del carrusel (full width, gutter izq 40px, bleed a la derecha) — */
.s32-carousel {
  /* full bleed a ambos lados: la tarjeta activa va centrada (focus:center) */
  padding-left: 0;
  padding-right: 0;
}

.s32-carousel .splide__slide {
  height: auto;
}

/* Cursor de "mano" para indicar arrastre manual */
.s32-carousel .splide__list { cursor: grab; }
.s32-carousel.is-dragging .splide__list { cursor: grabbing; }

/* Aire vertical mínimo en el track (overflow:hidden) para que se vea la aureola
   de sombra sin alejar demasiado el tag/ficha de la tarjeta. */
.s32-carousel .splide__track { padding-top: 6px; padding-bottom: 8px; }

/* — Stage: contiene el tag fijo (arriba), el carrusel y la ficha fija (abajo) — */
.s32-stage { position: relative; margin-top: 0px; }

/* — Tarjeta: solo imagen + título; la activa se resalta (opacidad/sombra) — */
.s32-card {
  display: flex;
  flex-direction: column;
  opacity: 0.4;
  /* en paralelo con el desplazamiento (1.3s) · easeInOutQuart (lento-rápido-lento) */
  transition: opacity 1.3s cubic-bezier(0.76, 0, 0.24, 1);
}

.s32-carousel .splide__slide.is-active .s32-card {
  opacity: 1;
}

/* Marco blanco de la tarjeta (imagen + título) */
.s32-card__frame {
  background: #fff;
  border-radius: 16px;
  padding: 10px;
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.05);
  transition: box-shadow 1.3s cubic-bezier(0.76, 0, 0.24, 1);
}

.s32-carousel .splide__slide.is-active .s32-card__frame {
  box-shadow: 0 14px 44px rgba(0, 0, 0, 0.12);
}

/* Imagen (dentro del marco) — proporción ≈ 448 × 434 */
.s32-card__media {
  position: relative;
  border-radius: 9px;
  overflow: hidden;
  aspect-ratio: 448 / 434;
  background: #1c1c1c;
}

.s32-card__bg {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
  filter: brightness(0.9); /* baja un toque la exposición para diferenciar el marco blanco */
}

/* Título bajo la imagen (dentro del marco) */
.s32-card__name {
  font-family: var(--_typography---lucida-grande);
  font-size: 1.15rem;
  font-weight: 400;
  line-height: 1.15;
  color: var(--negro);
  margin: 12px 6px 10px;
  display: none;
}

/* ===== Tag fijo (arriba) y ficha fija (abajo), centrados =====
   No se mueven con el carrusel; solo su copy cambia con blur al cambiar de tarjeta. */
.s32-tagbar,
.s32-panel {
  width: 400px;
  max-width: calc(100% - 48px);
  margin-left: auto;
  margin-right: auto;
  background: #fff;
  box-shadow: 0 6px 22px rgba(0, 0, 0, 0.06);
}

.s32-tagbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: clamp(36px, calc(5svh / var(--page-scale)), 46px);
  padding: 4px 8px;
  margin-bottom: 2px;
  border-radius: 8px;
}

.s32-panel {
  margin-top: 2px;
  padding: clamp(12px, calc(2svh / var(--page-scale)), 18px);
  border-radius: 12px;
}

.s32-tabs__arrow {
  width: clamp(30px, calc(5svh / var(--page-scale)), 38px);
  height: clamp(30px, calc(5svh / var(--page-scale)), 38px);
  border: none;
  border-radius: 8px;
  background: #f0f0f0;
  color: #333;
  font-size: clamp(18px, calc(3svh / var(--page-scale)), 24px);
  line-height: 1;
  padding-bottom: 2px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.2s ease, color 0.2s ease;
}

.s32-tabs__arrow:hover {
  background: #e2e2e2;
  color: var(--negro);
}

.s32-tagbar__fruit {
  font-family: var(--font-secundaria);
  font-size: 1rem;
  color: var(--negro);
  text-align: center;
  padding: 0 12px;
}

.s32-panel__label {
  display: block;
  font-family: var(--font-secundaria);
  font-size: 0.83rem;
  color: rgba(19, 19, 19, 0.5);
  margin-bottom: clamp(4px, calc(1svh / var(--page-scale)), 8px);
}

.s32-panel__section {
  margin: 0;
}
.s32-panel__section + .s32-panel__section {
  margin-top: clamp(6px, calc(1.4svh / var(--page-scale)), 10px);
}

/* Temperatura ideal / HR recomendada en dos columnas lado a lado (cada
   una con su label arriba y dato debajo), separadas por un divisor
   vertical — ahorra alto vs. apilar las dos filas completas. */
.s32-panel__meta-cols {
  display: flex;
  align-items: stretch;
  gap: 16px;
}
.s32-panel__meta-col {
  flex: 1;
  min-width: 0;
}
.s32-panel__meta-vdivider {
  width: 1px;
  background: #e9e9e9;
  flex-shrink: 0;
}

.s32-panel__meta-value {
  font-family: var(--font-secundaria);
  font-size: clamp(0.8rem, calc(1.82svh / var(--page-scale)), 1.05rem);
  color: var(--negro);
}

.s32-panel__divider {
  width: 100%;
  height: 1px;
  background: #e9e9e9;
  margin: clamp(8px, calc(2svh / var(--page-scale)), 16px) 0;
}

.s32-panel__desc {
  margin: 0;
  font-family: var(--font-family--principal-font);
  font-size: 0.83rem;
  font-weight: 400;
  line-height: 1.25;
  color: var(--negro);
}

/* La animación del copy interno la maneja el JS con GSAP + SplitType
   (barrido blur + jump up por líneas). Ver initS32Carousel → animIn(). */
.s32-tagbar__fruit,
.s32-panel__meta-value,
.s32-panel__desc {
  will-change: transform, filter, opacity;
}
/* Las líneas que crea SplitType heredan el estilo de la descripción */
.s32-panel__desc .line { display: block; }

/* Ancho del tag/ficha fijos = ancho de la tarjeta (espejo del fixedWidth del carrusel) */
@media (max-width: 1280px) { .s32-tagbar, .s32-panel { width: 400px; } }
@media (max-width: 991px)  { .s32-tagbar, .s32-panel { width: 340px; } }
/* Debe coincidir con fixedWidth en initS32Carousel (main.js) — ver ahí
   el porqué (58vw/64vw en vez de 76vw/82vw: #s3-3 completa no entraba
   en un viewport de teléfono). */
@media (max-width: 767px)  { .s32-tagbar, .s32-panel { width: calc(88vw / var(--page-scale)); } }
@media (max-width: 479px)  { .s32-tagbar, .s32-panel { width: calc(88vw / var(--page-scale)); } }

/* Tagbar con aire real alrededor de las flechas: su height (clamp hasta
   46px) + el padding de 4px apenas alcanzaba para el botón de 38px, así
   que quedaba literalmente pegado/superpuesto al borde del contenedor.
   height:auto + padding más generoso resuelve eso de raíz. El BOTÓN
   (.s32-tabs__arrow, el círculo) vuelve a su tamaño original — a
   pedido, el pedido de "más grande" era solo para el ÍCONO/flecha en sí
   (font-size), no para el contenedor que lo envuelve. */
@media (max-width: 767px) {
  .s32-tagbar {
    height: auto;
    padding: 6px;
  }
  .s32-tabs__arrow {
    font-size: 30px;
  }
}

@media (max-width: 991px) {
  /* columnas apiladas: título arriba, refuerzo debajo */
  .s32-head {
    flex-direction: column;
    align-items: flex-start;
    gap: 22px;
    padding: 0 40px 36px;
  }
  .s32-head__left,
  .s32-head__right { flex: none; width: 100%; }
  .s32-head__note { max-width: 64ch; }
  /* Título de sección — mismo criterio que el hero: en este rango de
     anchos --page-scale ya da 1, así que se recalibra a los tamaños
     reales medidos en institute of health para un título de sección
     (h2), no a los de escritorio. */
  .s32-title { font-size: clamp(1.8rem, 5vw, 2.3rem); }
}

@media (max-width: 767px) {
  /* padding-bottom achicado (era 56px): a pedido, para acercar más el
     final del bloque de texto de #s3-2 con el arranque de #s3-3 que se
     asoma debajo — menos aire suelto entre ambas secciones. #s3-3 no se
     ve afectada, tiene su propio padding completo más abajo. */
  .sub-section--2 { padding: 88px 0 0; }
  /* #s3-2 ya no fuerza 50dvh — a pedido, el bloque de texto usa los
     MISMOS tamaños de fuente que S2 (#bananaIntro), así que su alto real
     lo decide el contenido (height:auto). min-height:0 anula el
     min-height:100dvh que hereda de ".sub-section" (genérica) — sin
     esto, aun con height:auto la sección no podía achicarse por debajo
     de un viewport completo (min-height siempre le gana a un height más
     chico). Lo que sea que sobre de los 100dvh de la slide (si el texto
     es más bajo que la pantalla) deja asomado el arranque de #s3-3 (el
     carrusel) debajo — la misma ilusión de bloque continuo, ahora
     dependiente del alto real del texto en vez de un 50% fijo. */
  #s3-2 {
    height: auto;
    min-height: 0;
    /* Pizca de aire + sombra interna del mismo tono que el fondo de
       #s3-3 (#e7e7e7, el stop final del degradado compartido, ver
       --s32-height más abajo) — a pedido, para reforzar la ilusión de
       solape entre ambas mitades justo en el borde donde una "se asoma"
       bajo la otra. */
    padding-bottom: 28px;
    box-shadow: inset 0 -30px 26px -20px rgba(231, 231, 231, 0.9);
  }
  /* Fondo continuo entre #s3-2 y #s3-3, sin costura en la unión.
     Primer intento: background-attachment:fixed + mismo background-size
     — en teoría convierte el degradado en un lienzo único, pero WebKit
     (Safari Y Chrome en iOS corren sobre WebKit) NO lo respeta de forma
     confiable dentro de un ancestro con transform (#fpStage, que
     desliza con transform para pasar de slide en slide): el fondo
     terminaba calculándose local a cada sección de todos modos —
     confirmado midiendo el color real de los píxeles a cada lado de la
     unión, con un salto notorio.
     Este es el fix real: --s32-height (ver :root arriba) la fija JS
     (syncS32S33Background en main.js) al alto REAL medido de #s3-2. El
     degradado de AMBAS secciones se dimensiona a la misma altura total
     (alto de #s3-2 + 100dvh de #s3-3, el "lienzo" combinado) — #s3-2 lo
     ancla arriba (position:top, muestra el tramo [0, su-alto]) y #s3-3
     lo desplaza hacia arriba exactamente ese alto (position: 0
     -altoDeS32, muestra el tramo siguiente, [su-alto, su-alto+100dvh]).
     Matemática pura, no depende de que ningún motor soporte un
     attachment particular. */
  #s3-2,
  #s3-3 {
    background-image: linear-gradient(180deg, #f4f4f4 0%, #eeeeee 56%, #e7e7e7 100%);
    background-repeat: no-repeat;
    background-size: 100% calc(var(--s32-height) + (100dvh / var(--page-scale)));
  }
  #s3-2 {
    background-position: 0 top;
  }
  #s3-3 {
    background-position: 0 calc(-1 * var(--s32-height));
  }
  /* Viñeta decorativa (::before, sombras radiales en las esquinas) OFF
     en mobile: a pedido, para que el fondo entre #s3-2 y #s3-3 se vea
     unificado — ya se había resuelto matemáticamente (mismo lienzo
     compartido con --s32-height, igual que el degradado principal) pero
     directamente quitarla es más simple y deja el fondo parejo de
     verdad, sin ningún matiz de sombra que distinga una sección de otra. */
  #s3-2::before,
  #s3-3::before {
    display: none;
  }
  /* Mismo tamaño que el título de S2 (#bananaIntro .bi-title) en mobile */
  #s3-2 .s32-title {
    font-size: clamp(1.944rem, calc(4.05vw / var(--page-scale)), 3.24rem);
  }
  /* Menos espacio entre el bloque título (.s32-head__left) y la
     descripción (.s32-head__right) — a pedido. Era 22px (heredado del
     gap genérico de .s32-head en columnas, pensado para desktop/tablet). */
  #s3-2 .s32-head {
    gap: 2px;
  }
  /* Mismo tamaño que la descripción de S2 (#bananaIntro .bi-copy) en mobile */
  #s3-2 .s32-head__note {
    font-size: 16.2px;
    line-height: 1.4;
  }
  /* padding-bottom quitado del todo (era 28px, luego 12px) — a pedido,
     para acercar el CTA lo más posible al borde donde se asoma #s3-3. */
  .s32-head { padding: 0 24px 0; }
  /* Mismo tamaño que el CTA de S3.1 (.s3v-cta) en mobile, -30% (ver ahí
     el detalle del recorte). El CTA se queda en #s3-2 (a pedido: último
     elemento del bloque de texto, ya lo es de por sí — es el último hijo
     de .s32-head__right) — el gap:24px de ese contenedor (flex-column)
     ya le da su espaciado con la descripción, no necesita margen propio. */
  .s32-cta {
    max-width: 280px;
    min-height: 48px;
    padding: 9px 14px;
  }
  .s32-cta .s32-cta__label {
    font-size: 0.735rem;
  }
  .s32-cta .s32-cta__arrow {
    font-size: 0.875rem;
  }

  /* #s3-3 (solo el carrusel + tag/ficha ahora, sin CTA — ver
     splitS32ForMobile en main.js) es su propia slide de 100dvh, sin
     título arriba. padding-top a la mitad (era 90px, el mínimo real
     para no quedar detrás del header fijo de 86.6px de alto) — a
     pedido explícito, acerca el carrusel al bloque de texto de #s3-2
     para reforzar la ilusión de un solo bloque; el tagbar puede quedar
     parcialmente detrás del header cuando #s3-3 es la slide activa de
     verdad (no solo el "asomo" debajo de #s3-2). NO usar display:flex/
     grid en este selector: se probó justify-content:center para
     centrar mejor y entraba en loop con el ResizeObserver interno de
     Splide, que vive dentro de .s32-stage — la sección colgaba por
     completo (encontrado con bisección). */
  /* padding-top fijo en el valor FINAL (96px, el que necesita el tagbar
     para respirar lejos del header) — ya no anima. Animar padding-top
     directamente crecía el alto real de #s3-3 cuadro a cuadro, y eso
     forzaba layout/reflow de toda la página en cada frame (con Splide
     viviendo dentro, sensible a esto — ver nota de ResizeObserver más
     abajo) → se sentía "trastabillado". El efecto ahora vive en
     transform (ver #s3-3 .s32-stage), que es solo compositor, no layout:
     mucho más fluido. */
  #s3-3 {
    padding: 96px 0 8px;
  }
  /* Efecto tipo parallax vía transform en vez de padding: arranca
     desplazado hacia arriba (-51px, la misma "asomada" compacta bajo
     #s3-2 que antes daba el padding-top chico) y al activarse de verdad
     #s3-3 (fp:slideactivated → .is-settled, ver initS33SettleFx en
     main.js) se traslada a su posición natural (0) con transition. */
  #s3-3 .s32-stage {
    transform: translateY(-51px);
    /* opacity sumada acá mismo (no en una regla aparte): dos reglas con
       la misma especificidad (#s3-3 .s32-stage) que declaren `transition`
       compiten entera por entera — la última en el CSS se queda con TODA
       la lista de propiedades, no las combina. Sumando opacity a esta
       misma transition, el parallax (transform) y el cruce de #s3-2/#s3-3
       (opacity, ver applyS32S33Crossfade en main.js) conviven sin pisarse. */
    transition:
      transform 0.9s cubic-bezier(0.45, 0, 0.15, 1),
      opacity 1s cubic-bezier(0.37, 0, 0.63, 1);
    will-change: transform, opacity;
  }
  #s3-3.is-settled .s32-stage {
    transform: translateY(0);
  }
  /* Cruce de contenido entre #s3-2 y #s3-3 (ver applyS32S33Crossfade en
     main.js): se desvanece el CONTENIDO de cada mitad (.s32-head /
     .s32-stage), nunca la sección — la sección conserva su fondo opaco
     todo el tiempo (el degradado continuo que comparten, ver
     --s32-height más arriba), así que no hay forma de que #ciencia se
     asome de fondo mientras cruzan. El selector con #id le gana en
     especificidad a las reglas is-ready/is-inview de más arriba SOLO
     mientras el contenido trae alguna de estas tres clases — fuera de
     este cruce puntual, el ciclo normal de entrada/salida de #s3-2 no
     se toca.
     is-crossfade-in (no solo confiar en la regla ambiente .is-inview al
     quitar is-crossfade-in-start): #s3-2 .s32-head normalmente entra con
     transition-delay:0.52s (ver .s32.is-ready.is-inview .s32-head más
     arriba, pensado para escalonar el título tras la descripción la
     PRIMERA vez que se entra a la sección) — heredar ese delay acá
     desincroniza el cruce #s3-3→#s3-2 del resto del stage. Esta clase le
     da su propia transition sin delay mientras dura el cruce. */
  #s3-2 .s32-head.is-crossfade-out,
  #s3-2 .s32-head.is-crossfade-in-start,
  #s3-2 .s32-head.is-crossfade-in {
    transition: opacity 1s cubic-bezier(0.37, 0, 0.63, 1);
    transition-delay: 0s;
  }
  #s3-2 .s32-head.is-crossfade-out {
    opacity: 0;
  }
  #s3-2 .s32-head.is-crossfade-in-start {
    transition: none;
    opacity: 0;
  }
  #s3-2 .s32-head.is-crossfade-in {
    opacity: 1;
  }
  #s3-3 .s32-stage.is-crossfade-out {
    opacity: 0;
  }
  #s3-3 .s32-stage.is-crossfade-in-start {
    transition: none;
    opacity: 0;
  }
  #s3-3 .s32-stage.is-crossfade-in {
    transition: opacity 1s cubic-bezier(0.37, 0, 0.63, 1);
    transition-delay: 0s;
    opacity: 1;
  }
  /* Datos de Temperatura ideal / HR recomendada +15% — a pedido */
  .s32-panel__meta-value {
    font-size: clamp(0.92rem, calc(2.093svh / var(--page-scale)), 1.208rem);
  }
}

@media (max-width: 479px) {
  .s32-title { font-size: clamp(1.5rem, 9vw, 2.2rem); }
}

/* ============================================================
   S5 · NOSOTROS — sticky frame + pipeline inferior
   ============================================================ */
/* ============================================================
   S5 · EL COMIENZO DEL EQUILIBRIO — Pipeline Propuesta B
   ============================================================ */
.s5-wrapper {
  background: #131313;
  /* Antes 400svh de recorrido para el scrub de GSAP; ahora es un stepper
     discreto (ver initNosotrosSteps en main.js) — la sección es 100svh,
     igual que .s5-sticky. */
}

/* Estados — apilados, crossfade por JS */
.s5-state {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 0 80px;
  max-width: 860px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.5s ease;
}

.s5-state.is-active {
  opacity: 1;
  pointer-events: auto;
}

.s5-state--3 {
  max-width: 1200px;
}

/* Fondos full-bleed por estado — independientes del max-width del contenido */
.s5-bg {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
  opacity: 0;
  transition: opacity 0.6s ease;
  z-index: 0;
}
.s5-bg::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to right, rgba(0,0,0,0.78) 0%, rgba(0,0,0,0.50) 50%, rgba(0,0,0,0.20) 100%);
}
/* Los background-image de estos tres (y el de .s6-bg) los asigna el JS al
   acercarse — ver lazyBgOnApproach en main.js. En CSS el navegador los
   descargaba apenas renderizaba el elemento, o sea en la carga inicial,
   robándole ancho de banda a las secciones que el usuario sí está viendo. */

.s5-wrapper[data-paso="0"] .s5-bg--1,
.s5-wrapper[data-paso="1"] .s5-bg--2,
.s5-wrapper[data-paso="2"] .s5-bg--3 { opacity: 1; }

/* contenido de estados por encima del fondo */
.s5-state { z-index: 1; }

/* Tipografía de estados */
.s5-eyebrow {
  font-family: var(--_typography---lucida-grande);
  font-size: 1rem;
  font-weight: 400;
  letter-spacing: 5px;
  text-transform: uppercase;
  color: var(--amarillo-banana);
  margin: 0 0 24px;
}

.s5-headline {
  font-family: var(--_typography---lucida-grande);
  font-size: clamp(2.24rem, calc(5vw / var(--page-scale)), 3.84rem);
  font-weight: 400;
  line-height: 1.05;
  letter-spacing: 0;
  color: #fff;
  margin: 0 0 28px;
}
/* Título de sección más chico en mobile — mismo criterio que el hero:
   --page-scale ya da 1 en este rango de anchos, así que se recalibra a
   los tamaños reales de un título de sección medidos en institute of
   health, no a los de escritorio. */
@media (max-width: 991px) {
  .s5-headline { font-size: clamp(1.8rem, 5vw, 2.3rem); }
}
@media (max-width: 767px) {
  .s5-headline { font-size: clamp(1.6rem, 6vw, 2.5rem); }
}
@media (max-width: 479px) {
  .s5-headline { font-size: clamp(1.5rem, 9vw, 2.2rem); }
}

.s5-copy {
  font-family: var(--font-family--principal-font);
  font-size: 21px;
  line-height: 1.65;
  color: #fff;
  margin: 0 0 32px;
  max-width: 680px;
}

/* Pain list (Estado 1) */
.s5-painlist {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.s5-painlist li {
  font-family: var(--font-family--principal-font);
  font-size: 21px;
  color: #fff;
  display: flex;
  align-items: center;
  gap: 12px;
}

.s5-painlist li::before {
  content: '';
  flex: 0 0 auto;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--amarillo-banana);
}

/* Cap list (Estado 2) */
.s5-caplist {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.s5-caplist li {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.s5-cap__label {
  font-family: var(--_typography---lucida-grande);
  font-size: 0.85rem;
  letter-spacing: 0;
  text-transform: uppercase;
  color: var(--amarillo-banana);
}

.s5-cap__desc {
  font-family: var(--font-family--principal-font);
  font-size: 21px;
  color: #fff;
}

/* Ruta de valor (Estado 3) — estructura tipo timeline (ref. cliente:
   número/título grande arriba, label chico debajo, ticks decorativos,
   columnas separadas por un divisor vertical fino en vez de flechas). */
.s5-ruta {
  display: flex;
  align-items: stretch;
  gap: 28px;
  flex-wrap: wrap;
  margin-top: 80px; /* más aire respecto al párrafo de arriba (.s5-copy) — se veía muy pegado */
}

.s5-ruta__nodo {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 150px;
  flex: 1 1 150px;
  /* Las barritas (.s5-ruta__ticks) YA NO van en flujo normal debajo de
     la descripción — antes, cada fase con una descripción más corta
     "subía" sus barritas respecto a las demás (Freshbox, con menos
     texto, quedaba desalineado del resto). Se sacan del flujo con
     position:absolute, siempre pegadas al borde inferior de LA FILA
     completa (.s5-ruta usa align-items:stretch: las 4 columnas miden
     lo mismo), así quedan alineadas siempre, sin importar cuántas
     líneas ocupe cada descripción. padding-bottom reserva el espacio
     real que ocupan (alto de .s5-ruta__ticks) para que no se les monte
     encima el texto — ver valores en @media 767px más abajo para
     mobile. */
  position: relative;
  padding-bottom: 48px; /* 40px alto de .s5-ruta__ticks + 8px de aire */
}

.s5-ruta__title {
  font-family: var(--_typography---lucida-grande);
  font-size: clamp(1.5rem, calc(3vw / var(--page-scale)), 2.1rem);
  font-weight: 400;
  line-height: 1.05;
  letter-spacing: 0;
  color: #fff;
  /* Entrada con blur (ver [data-paso="2"] más abajo) — arranca invisible
     y desenfocado. */
  opacity: 0;
  filter: blur(10px);
}

.s5-ruta__desc {
  font-family: var(--font-family--principal-font);
  font-size: 0.85rem;
  line-height: 1.35;
  color: rgba(255, 255, 255, 0.75);
  opacity: 0;
  filter: blur(10px);
}

/* Fila de marcas verticales por columna — barras individuales. 14 por
   columna (antes 20, que resultaban un poco densas) con más gap — el
   ancho visual total (hasta el divisor) se mantiene igual, porque cada
   barra sigue creciendo con flex:1 sin tope; solo cambia la relación
   barra/espacio entre ellas. */
.s5-ruta__ticks {
  /* position:absolute (no margin-top: el espacio de separación ya lo
     reserva el padding-bottom de .s5-ruta__nodo, ver arriba) — pegada
     siempre al borde inferior de la columna, igual en las 4 fases. */
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  align-items: flex-end;
  gap: 7px;
  height: 40px;
}

.s5-ruta__tick {
  /* Sin max-width: cada "slot" crece para repartirse TODO el ancho de
     la columna (hasta el divisor) — así, en conjunto, siguen ocupando
     el mismo ancho que tendría una línea de progreso continua. La
     barra VISIBLE en sí es el ::before (ver abajo): un slot invisible +
     una barra centrada adentro con ancho/alto reales (no transform)
     separa "cuánto espacio de fila ocupa" de "qué tan gruesa se ve". */
  flex: 1 1 0;
  height: 100%;
  position: relative;
}

.s5-ruta__tick::before {
  content: "";
  display: block;
  /* position:absolute + bottom:0 (en vez de flex align-items:flex-end +
     height:100% anidado dos niveles) — el punto de apoyo de CADA barra
     queda anclado exactamente al mismo pixel del contenedor
     (.s5-ruta__ticks), sin depender de cómo cada motor/navegador
     resuelve un height:100% dentro de un flex item dentro de otro flex
     item. Es lo que garantiza que Campo/Freshbox/Retail/Consumidor
     arranquen y terminen exactamente a la misma altura, incluso cuando
     Freshbox suma border+padding (ver [data-step="2"] más abajo) — a
     pedido explícito, tras verse desalineadas en dispositivo real. */
  position: absolute;
  left: 50%;
  bottom: 0;
  transform: translateX(-50%);
  width: 56%; /* -20% de grosor respecto a la iteración anterior (70% → 56%) */
  height: 100%;
  border-radius: 0;
  background: rgba(255, 255, 255, 0.18); /* fallback si [data-step] no matchea */
  /* Entrada secuencial (ver [data-paso="2"] más abajo): cada barra
     arranca "cerrada" recortada desde arriba (0% visible) y se revela
     creciendo desde abajo — clip-path en vez de scale/transform para no
     repetir el problema de distorsión que tuvo el marco de Freshbox. */
  clip-path: inset(100% 0 0 0);
}

/* Progreso Campo → Consumidor: verde (más claro que la marca para
   contrastar sobre fondo oscuro) hasta el amarillo banana. Freshbox
   lleva un marco blanco separado del relleno — es el punto que se
   quiere destacar del roadmap: el impacto directo de Freshbox en el
   proceso. */
.s5-ruta__nodo[data-step="1"] .s5-ruta__tick::before {
  background: #8dd45a;
}
.s5-ruta__nodo[data-step="2"] .s5-ruta__tick::before {
  /* outline+outline-offset se veía deforme a este tamaño tan chico
     (el hueco entre marco y relleno no queda parejo — termina
     pareciendo una grapa en vez de un rectángulo). border + padding +
     background-clip:content-box da el mismo efecto ("marco separado
     del relleno") pero como caja real: el padding es el hueco, siempre
     parejo en los 4 lados. Con box-sizing:border-box, width/height
     quedan EXACTOS (mismo tamaño que las demás columnas, sin tener que
     compensar nada por un desborde de pintado). */
  /* Diagnóstico del "no veo el relleno verde": cada barra es MUY chica
     (una de 14 compartiendo el ancho de la columna) — con borde 2px +
     padding 1px por lado, ese marco se comía casi todo el ancho
     disponible y no quedaba área interior para pintar verde. Se baja el
     borde a 1px y se sube el ancho de la barra (56% → 78%) para que
     sobre espacio real adentro; con eso el verde vuelve a ser visible
     sin perder el efecto de marco separado del relleno. */
  background: #8dd45a;
  background-clip: content-box;
  border: 1px solid #fff;
  padding: 1px;
  box-sizing: border-box;
  width: 78%;
  height: 100%;
}
.s5-ruta__nodo[data-step="3"] .s5-ruta__tick::before {
  background: linear-gradient(180deg, #8dd45a 0%, #c5d74b 100%);
}
.s5-ruta__nodo[data-step="4"] .s5-ruta__tick::before {
  background: var(--amarillo-banana);
}

.s5-ruta__divider {
  flex: 0 0 auto;
  width: 2px;
  align-self: stretch;
  background: rgba(255, 255, 255, 0.6);
  /* Estado "cerrado": el corte todavía no cayó — sin alto, colgando
     desde arriba (ver [data-paso="2"] más abajo para el efecto
     checkpoint). */
  transform: scaleY(0);
  transform-origin: top;
}

/* ============================================================
   Secuencia de entrada de "El resultado" — encadenada por ítem:
   cada columna (Campo/Freshbox/Retail/Consumidor) tiene su propio
   "turno" de ITEM_DURATION segundos; el turno del ítem N+1 arranca
   justo cuando termina el del ítem N (relay), no todos a la vez.
   Dentro de cada turno: 1) título+descripción con blur-in, 2) las 14
   barritas de esa columna se revelan en barrido izquierda→derecha,
   3) el divisor "cae" de golpe como un corte/checkpoint marcando el
   paso al siguiente ítem. --i (inline en cada nodo/divisor) ubica el
   turno; --k (inline en cada barra) ubica su posición en el barrido.
   ============================================================ */
/* Toda la cascada de "El resultado" corre 25% más rápida (pedido: "20 o
   30% más de velocidad") — mismos valores de antes × 0.75 en cada
   duración/delay: turno de 0.7s→0.525s, offset inicial 0.5s→0.375s,
   etc. Se mantiene la misma coreografía relativa, solo más ágil. */
.s5-wrapper[data-paso="2"] .s5-ruta__title,
.s5-wrapper[data-paso="2"] .s5-ruta__desc {
  opacity: 1;
  filter: blur(0);
  transition: opacity 0.375s ease-out, filter 0.375s ease-out;
  transition-delay: calc(0.375s + (var(--i, 0) * 0.525s));
}
.s5-wrapper[data-paso="2"] .s5-ruta__desc {
  /* Medio paso detrás del título — el blur se lee de a uno, no los dos a la vez. */
  transition-delay: calc(0.375s + (var(--i, 0) * 0.525s) + 0.075s);
}
.s5-wrapper[data-paso="2"] .s5-ruta__tick::before {
  clip-path: inset(0% 0 0 0);
  transition: clip-path 0.225s cubic-bezier(0.4, 0, 0.2, 1);
  /* Arranca 0.15s después del título de esa misma columna, y cada barra
     sigue a la anterior 0.015s más tarde (barrido izq→der). */
  transition-delay: calc(0.375s + (var(--i, 0) * 0.525s) + 0.15s + (var(--k, 0) * 0.015s));
}
.s5-wrapper[data-paso="2"] .s5-ruta__divider {
  /* El corte cae justo al arrancar el turno del ítem SIGUIENTE (--i del
     divisor coincide con el ítem que queda a su izquierda: divisor 0
     cae al empezar el turno 1, etc.) — como una barrera de checkpoint
     marcando "siguiente parada", no un simple fade. */
  transform: scaleY(1);
  transition: transform 0.135s cubic-bezier(0.83, 0, 0.17, 1);
  transition-delay: calc(0.375s + ((var(--i, 0) + 1) * 0.525s));
}

/* Retroiluminación de "Freshbox" (--i:1, data-step="2") — a pedido
   explícito: un resplandor detrás del nombre de la marca que aparece
   junto con su título.
   AJUSTE (a pedido explícito, tras ver la primera versión: "dejaría
   más tiempo el resplandor... que se desvanezca lentamente y no dé
   corte con el final de la flecha") — antes duraba 2.2s, calculada a
   propósito para apagarse en el MISMO instante en que termina la
   flecha (3.10s) — ese acople exacto es justo lo que se pidió sacar.
   Ahora dura bastante más (4.4s) y su apagado es mucho más lento (el
   40% final de la duración, ~1.76s de fundido, contra los ~0.44s de
   antes) — termina bien DESPUÉS de que la flecha ya terminó su propio
   recorrido (4.4+0.9=5.3s, casi 2s después de la flecha), como una
   cola independiente, no un corte sincronizado con ella.
   text-shadow (no box-shadow/filter): no necesita ninguna caja propia
   para el pseudo-elemento — funciona directo sobre el texto inline.
   Es una @keyframes (no una transition): el pedido es un arco
   aparece→se sostiene→desaparece dentro de UN solo cambio de estado
   (data-paso pasa a "2") — eso solo se arma con keyframes explícitos.
   animation-delay arranca junto con el título (mismo cálculo que su
   transition-delay, arriba).
   fill-mode:backwards aplica el 0% (sin resplandor) durante el delay,
   así no hay ningún destello antes de que el título aparezca. */
.s5-wrapper[data-paso="2"] .s5-ruta__nodo[data-step="2"] .s5-ruta__title {
  animation: s5-freshbox-glow 4.4s ease-out;
  animation-delay: calc(0.375s + (1 * 0.525s)); /* 0.9s — mismo instante que su blur-in */
  animation-fill-mode: backwards;
}
@keyframes s5-freshbox-glow {
  0%   { text-shadow: 0 0 0 rgba(255, 255, 255, 0), 0 0 0 rgba(141, 212, 90, 0); }
  /* Sube rápido (8% de 4.4s ≈ 0.35s, igual de ágil que antes) y se
     SOSTIENE ahí hasta el 60% (≈2.64s) — un buen rato — recién después
     empieza a apagarse, esta vez despacio (el 40% restante, ~1.76s de
     fundido lento, no un corte). */
  8%   { text-shadow: 0 0 18px rgba(255, 255, 255, 0.9), 0 0 42px rgba(141, 212, 90, 0.55); }
  60%  { text-shadow: 0 0 18px rgba(255, 255, 255, 0.9), 0 0 42px rgba(141, 212, 90, 0.55); }
  100% { text-shadow: 0 0 0 rgba(255, 255, 255, 0), 0 0 0 rgba(141, 212, 90, 0); }
}
/* BUG (reportado: "en mobile el destello no se aprecia... al ser tan
   pequeño parece difuminarse") — los radios de blur de arriba (18px/
   42px) son fijos, pensados para el tamaño de escritorio de
   .s5-ruta__title (clamp hasta 2.1rem/33.6px). En mobile ese título
   cae a 0.78rem/12.48px (ver @media 767px más abajo) — el MISMO blur
   fijo, contra una letra tan chica, se extiende mucho más allá de los
   propios trazos: en vez de un resplandor pegado al texto, se ve como
   una mancha difusa suelta. Blur reescalado en la misma proporción que
   el tamaño de letra (18/42 ÷ ~2.6 ≈ 7/16) — mismo carácter visual
   (radio interno ~0.6x el alto de letra, aura externa ~1.3x),
   solo que ajustado a una letra mucho más chica, para que quede
   acoplado al texto en vez de disolverse. */
@media (max-width: 767px) {
  @keyframes s5-freshbox-glow {
    0%   { text-shadow: 0 0 0 rgba(255, 255, 255, 0), 0 0 0 rgba(141, 212, 90, 0); }
    8%   { text-shadow: 0 0 7px rgba(255, 255, 255, 0.95), 0 0 16px rgba(141, 212, 90, 0.65); }
    60%  { text-shadow: 0 0 7px rgba(255, 255, 255, 0.95), 0 0 16px rgba(141, 212, 90, 0.65); }
    100% { text-shadow: 0 0 0 rgba(255, 255, 255, 0), 0 0 0 rgba(141, 212, 90, 0); }
  }
}

/* Flecha de sentido debajo del roadmap (ver .s5-ruta__flow en el HTML,
   justo después de .s5-ruta) — a pedido explícito, refuerza el sentido
   lógico del recorrido (Campo→Freshbox→Retail→Consumidor).
   BUG (reportado: "no se nota la punta, se ve solo como una línea con
   un intento de punta... tiene que verse la punta de flecha
   claramente") — antes la punta era un ::after DENTRO de la línea
   recortada por clip-path: como vivía pegada al borde derecho (el
   último tramo en revelarse), quedaba escondida casi toda la animación
   y solo aparecía en el último instante del recorte — muy chica (8px)
   para notarse en ese momento tan breve. Ahora es un elemento APARTE
   (.s5-ruta__flow-tip, hermano de la línea, no dentro de su
   clip-path), bastante más grande y opaca, con su PROPIA transición
   (scale+opacity) — así tiene un momento de aparición propio y
   deliberado ("pop", con un pequeño rebote) en vez de quedar atada al
   recorte de la línea. */
.s5-ruta__flow {
  position: relative;
  margin-top: 20px;
  height: 20px;
  display: flex;
  align-items: center;
}
.s5-ruta__flow-line {
  display: block;
  /* Dos px menos de lo que mide la punta (16px) para que quede lugar
     real para ella, sin que la línea "se meta" debajo. */
  width: calc(100% - 16px);
  height: 2px;
  background: rgba(255, 255, 255, 0.6); /* mismo tono que .s5-ruta__divider */
  /* Estado cerrado: recortada del todo desde la derecha. */
  clip-path: inset(0 100% 0 0);
}
.s5-ruta__flow-tip {
  /* Triángulo vía border, bastante más grande y opaco que el intento
     anterior (8px→16px de largo, 0.6→0.9 de opacidad) — para que la
     punta de flecha se lea clara, no como un detalle perdido. */
  position: absolute;
  top: 50%;
  right: 0;
  width: 0;
  height: 0;
  border-top: 8px solid transparent;
  border-bottom: 8px solid transparent;
  border-left: 16px solid rgba(255, 255, 255, 0.9);
  /* Estado cerrado: invisible y encogida — "aparece" con un pop, no
     deslizándose ni recortándose. */
  opacity: 0;
  transform: translateY(-50%) scale(0);
  transform-origin: left center;
}
.s5-wrapper[data-paso="2"] .s5-ruta__flow-line {
  clip-path: inset(0 0% 0 0);
  transition: clip-path 0.4s cubic-bezier(0.4, 0, 0.2, 1);
  /* Recién cuando termina TODA la cascada de arriba (la última barrita
     de Consumidor, --i:3, k:13): 0.375 + 3×0.525 + 0.15 + 13×0.015 +
     0.225 = 2.52s. A diferencia del glow de Freshbox (antes acotado a
     su propia columna, ahora extendido), acá sí se espera el roadmap
     completo — la flecha resume el recorrido entero, no un tramo.
     Termina en 2.52+0.4 = 2.92s. */
  transition-delay: calc(0.375s + (3 * 0.525s) + 0.15s + (13 * 0.015s) + 0.225s);
}
.s5-wrapper[data-paso="2"] .s5-ruta__flow-tip {
  opacity: 1;
  transform: translateY(-50%) scale(1);
  /* Rebote leve (overshoot) para que el "pop" se sienta deliberado, no
     un simple fundido. Arranca 0.1s antes de que la línea termine del
     todo (2.92s - 0.1s = 2.82s), para un traspaso fluido entre "la
     línea llega" y "la punta aparece" — termina en 2.82+0.28 = 3.10s,
     el mismo instante en que se apaga el glow de Freshbox de arriba. */
  transition: transform 0.28s cubic-bezier(0.34, 1.56, 0.64, 1), opacity 0.2s ease-out;
  transition-delay: calc(0.375s + (3 * 0.525s) + 0.15s + (13 * 0.015s) + 0.225s + 0.3s);
}

/* ============================================================
   NOSOTROS EN MOBILE — se mantiene el mismo pin/stepper de escritorio
   (crossfade entre 3 estados con swipe/wheel interceptado, ver
   initNosotrosSteps en main.js) — a pedido explícito, NO se simplifica
   a flujo normal. Solo se ajustan tamaños de texto y padding para que
   cada estado entre cómodo en los 100svh pineados, y el roadmap de 4
   fases de "El resultado" se compacta en una fila (como en desktop) en
   vez de apilarse en columna. */
@media (max-width: 767px) {
  .s5-state {
    padding: 0 24px;
  }
  /* Mismo estándar de descripción que el resto del sitio en mobile
     (16.2px) — antes se quedaba en los 18px/21px de escritorio.
     !important en .s5-copy: más abajo (bloque "AJUSTES TIPOGRÁFICOS")
     hay un .s5-copy{font-size:18px} sin media query que, por venir
     después en el archivo y con la misma especificidad, ganaría el
     cascade y pisaría este valor. */
  .s5-copy {
    font-size: 16.2px !important;
    line-height: 1.45;
    margin-bottom: 20px;
  }
  .s5-painlist,
  .s5-caplist {
    gap: 8px;
  }
  .s5-painlist li,
  .s5-cap__desc {
    font-size: 16.2px;
    line-height: 1.35;
  }

  /* Roadmap de "El resultado" (Campo/Freshbox/Retail/Consumidor): en vez
     de apilar las 4 fases en columna (mucho alto, no entraba en el
     100svh pineado), se compacta todo en una fila angosta — igual
     criterio que desktop, escalado más acotado — con la mitad de
     barritas (7 en vez de 14: se ocultan las pares) para que no queden
     hilos ilegibles a este ancho. */
  .s5-ruta {
    flex-direction: row;
    flex-wrap: nowrap;
    gap: 8px;
    margin-top: 28px;
  }
  .s5-ruta__nodo {
    min-width: 0;
    width: auto;
    flex: 1 1 0;
    gap: 4px;
    padding-bottom: 26px; /* 22px alto de .s5-ruta__ticks + 4px de aire */
  }
  .s5-ruta__title {
    font-size: 0.78rem;
    line-height: 1.15;
  }
  .s5-ruta__desc {
    font-size: 0.44rem;
    line-height: 1.25;
  }
  .s5-ruta__ticks {
    height: 22px;
    gap: 3px;
  }
  .s5-ruta__tick:nth-child(even) {
    display: none;
  }
  /* Flecha de sentido — misma proporción más compacta que el resto del
     roadmap en mobile (la punta ahora es .s5-ruta__flow-tip, un
     elemento aparte — ver arriba). */
  .s5-ruta__flow {
    margin-top: 10px;
    height: 12px;
  }
  .s5-ruta__flow-line {
    width: calc(100% - 10px);
  }
  .s5-ruta__flow-tip {
    border-top-width: 5px;
    border-bottom-width: 5px;
    border-left-width: 10px;
  }
}
.s5-sticky {
  position: relative;
  top: 0;
  height: calc(100svh / var(--page-scale));
  width: 100%;
  overflow: hidden;
  background: #131313;
}

.s6-inner-container {
  background: #3e7319;
  min-height: calc(100svh / var(--page-scale));
}

/* Pipeline — fila de "capítulos": el activo crece en ancho. El fondo
   blanco (wipe) es solo una previsualización de :hover — el estado
   activo real se marca con opacidad plena + border-bottom blanco. */
.s5-pipeline {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 10;
  display: flex;
  align-items: stretch;
  gap: 32px;
  height: 30px;
  margin-bottom: 28px; /* separa el border-bottom del borde real de pantalla */
  padding: 0 40px;
}

.s5-pipe__item {
  position: relative;
  flex: 0 0 260px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding: 0;
  overflow: hidden;
  cursor: default;
  border-bottom: 1px solid #fff;
  opacity: .45;
  /* flex-basis ya no cambia de valor (siempre 260px, ver estado activo
     más abajo) — solo flex-grow anima el ancho. OJO: transicionar el
     longhand "flex-grow" solo (en vez del shorthand "flex") no anima
     en absoluto en WebKit/Safari — el ancho salta de golpe al valor
     final en vez de interpolar (confirmado: 84px→126px sin ningún
     frame intermedio). Transicionando "flex" (shorthand) en su lugar,
     sí interpola gradualmente — misma experiencia que ya tenía
     desktop, donde el bug no se notaba. */
  transition: flex .6s cubic-bezier(0.65, 0, 0.35, 1),
              opacity .3s ease,
              padding .45s cubic-bezier(0.65, 0, 0.35, 1);
}

/* Solo en hover: un respiro para que texto/icono no toquen el borde del
   wipe blanco — misma duración/curva que el wipe (.s5-pipe__item-fill),
   para que ambos aparezcan en sincronía. */
.s5-pipe__item:hover {
  opacity: 1;
  padding: 0 6px;
}

/* Wipe blanco: parte colapsado a la izquierda, crece horizontal (no opacidad).
   Solo :hover — el paso activo NO lo usa (ver bloque data-paso más abajo). */
.s5-pipe__item-fill {
  position: absolute;
  inset: 0;
  z-index: 0;
  background: #fff;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform .45s cubic-bezier(0.65, 0, 0.35, 1);
  will-change: transform;
}

.s5-pipe__item:hover .s5-pipe__item-fill {
  transform: scaleX(1);
}

.s5-pipe__item-label,
.s5-pipe__icon {
  position: relative;
  z-index: 1;
}

.s5-pipe__item-label {
  font-family: var(--font-secundaria);
  font-size: 12px;
  font-weight: 400;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: #fff;
  white-space: nowrap;
  transition: color .3s ease;
}

.s5-pipe__item:hover .s5-pipe__item-label {
  color: #131313;
}

/* Icono: símbolo de Freshbox (fill="currentColor") — el color del ícono
   sigue el mismo esquema de estados que el texto (tenue en reposo,
   negro en hover sobre el wipe blanco, blanco pleno en el paso activo). */
.s5-pipe__icon {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: rgba(255, 255, 255, .6);
  transition: color .3s ease;
}

.s5-pipe__icon-svg {
  width: 100%;
  height: 100%;
  display: block;
}

.s5-pipe__item:hover .s5-pipe__icon {
  color: var(--verde-primario);
}

/* ============================================================
   S5 · ESTADOS DISCRETOS POR data-paso — única fuente de verdad
   JS solo escribe data-paso; el CSS resuelve qué se muestra y anima.
   ============================================================ */

/* Panel de texto activo (crossfade) por estación */
.s5-wrapper[data-paso="0"] .s5-state--1,
.s5-wrapper[data-paso="1"] .s5-state--2,
.s5-wrapper[data-paso="2"] .s5-state--3 {
  opacity: 1;
  pointer-events: auto;
}

/* Entrada animada del bloque de texto (eyebrow/título/copy, + la lista
   de puntos en los Estados 1 y 2) de las 3 estaciones — antes, al
   activarse, todo el contenido aparecía junto en un solo fundido plano
   (el mismo transition:opacity 0.5s de .s5-state de arriba, sin nada
   propio por elemento). Mismo recurso de blur-in usado en el resto del
   sitio (opacity:0 + filter:blur() + translateY en reposo, revelado
   por transición al activarse), escalonado elemento por elemento:
   eyebrow → título → copy → (Estados 1/2) cada ítem de la lista. El
   Estado 3 solo tiene eyebrow/título/copy (pasa directo al roadmap, que
   ya tiene su propia coreografía escalonada aparte — ver .s5-ruta más
   abajo, sin tocar acá). Selectores con .s5-state--N (no .s5-eyebrow/
   .s5-headline/etc a secas): esas clases son compartidas entre las 3
   estaciones. Reversible como el resto de esta coreografía: [data-paso]
   deja de matchear al salir del estado, así que la transición corre en
   reversa igual al volver a entrar.
   BUG (reportado: "falta animación para la entrada de Nosotros — solo
   se aprecia cuando retorno al primer pipeline") — [data-paso="0"] es
   el valor por defecto desde que carga la página (antes de que el
   usuario llegue scrolleando) — llegar a Nosotros por primera vez
   desde abajo NO cambia su valor (ya era "0"), así que no hay ninguna
   transición de valor que dispare nada — el Estado 1 aparecía ya
   "resuelto". .is-entered (ver snapFreeze en initNosotrosSteps,
   main.js) es la pieza que faltaba: se agrega recién en el instante
   real de entrada (llegar desde #ciencia O desde S6, siempre pasa por
   ahí) — agregar esa clase SÍ es un cambio real de estado para CSS,
   aunque data-paso no se haya movido, así que dispara la transición
   igual. Se exige en AMBOS estados (no solo el 1) por las dudas /
   consistencia, aunque el Estado 2 nunca se ve "fresco" (siempre se
   llega a él viniendo del 1 o del 3, un cambio de data-paso real que
   ya disparaba bien la transición antes de este fix). */
.s5-state--1 .s5-eyebrow,
.s5-state--1 .s5-headline,
.s5-state--1 .s5-copy,
.s5-state--1 .s5-painlist li,
.s5-state--2 .s5-eyebrow,
.s5-state--2 .s5-headline,
.s5-state--2 .s5-copy,
.s5-state--2 .s5-painlist li,
.s5-state--3 .s5-eyebrow,
.s5-state--3 .s5-headline,
.s5-state--3 .s5-copy {
  opacity: 0;
  filter: blur(10px);
  transform: translateY(14px);
}
.s5-wrapper.is-entered[data-paso="0"] .s5-state--1 .s5-eyebrow,
.s5-wrapper.is-entered[data-paso="0"] .s5-state--1 .s5-headline,
.s5-wrapper.is-entered[data-paso="0"] .s5-state--1 .s5-copy,
.s5-wrapper.is-entered[data-paso="0"] .s5-state--1 .s5-painlist li,
.s5-wrapper.is-entered[data-paso="1"] .s5-state--2 .s5-eyebrow,
.s5-wrapper.is-entered[data-paso="1"] .s5-state--2 .s5-headline,
.s5-wrapper.is-entered[data-paso="1"] .s5-state--2 .s5-copy,
.s5-wrapper.is-entered[data-paso="1"] .s5-state--2 .s5-painlist li,
.s5-wrapper.is-entered[data-paso="2"] .s5-state--3 .s5-eyebrow,
.s5-wrapper.is-entered[data-paso="2"] .s5-state--3 .s5-headline,
.s5-wrapper.is-entered[data-paso="2"] .s5-state--3 .s5-copy {
  opacity: 1;
  filter: blur(0);
  transform: translateY(0);
  transition: opacity 0.45s ease-out, filter 0.45s ease-out, transform 0.45s cubic-bezier(0.22, 1, 0.36, 1);
}
.s5-wrapper.is-entered[data-paso="0"] .s5-state--1 .s5-eyebrow,
.s5-wrapper.is-entered[data-paso="1"] .s5-state--2 .s5-eyebrow,
.s5-wrapper.is-entered[data-paso="2"] .s5-state--3 .s5-eyebrow { transition-delay: 0.1s; }
.s5-wrapper.is-entered[data-paso="0"] .s5-state--1 .s5-headline,
.s5-wrapper.is-entered[data-paso="1"] .s5-state--2 .s5-headline,
.s5-wrapper.is-entered[data-paso="2"] .s5-state--3 .s5-headline { transition-delay: 0.18s; }
.s5-wrapper.is-entered[data-paso="0"] .s5-state--1 .s5-copy,
.s5-wrapper.is-entered[data-paso="1"] .s5-state--2 .s5-copy,
.s5-wrapper.is-entered[data-paso="2"] .s5-state--3 .s5-copy { transition-delay: 0.26s; }
.s5-wrapper.is-entered[data-paso="0"] .s5-state--1 .s5-painlist li:nth-child(1),
.s5-wrapper.is-entered[data-paso="1"] .s5-state--2 .s5-painlist li:nth-child(1) { transition-delay: 0.36s; }
.s5-wrapper.is-entered[data-paso="0"] .s5-state--1 .s5-painlist li:nth-child(2),
.s5-wrapper.is-entered[data-paso="1"] .s5-state--2 .s5-painlist li:nth-child(2) { transition-delay: 0.42s; }
.s5-wrapper.is-entered[data-paso="0"] .s5-state--1 .s5-painlist li:nth-child(3),
.s5-wrapper.is-entered[data-paso="1"] .s5-state--2 .s5-painlist li:nth-child(3) { transition-delay: 0.48s; }
/* Solo el Estado 1 tiene un 4º ítem en su lista (el Estado 2 tiene 3; el
   Estado 3 no tiene lista — pasa directo al roadmap, ver .s5-ruta abajo). */
.s5-wrapper.is-entered[data-paso="0"] .s5-state--1 .s5-painlist li:nth-child(4) { transition-delay: 0.54s; }

/* Item activo: crece y absorbe el ancho sobrante de la fila, y queda a
   opacidad plena (tipografía + icono + border-bottom en blanco total).
   Sin wipe blanco de fondo — eso es exclusivo del :hover.
   flex-basis se mantiene en 260px (igual que en reposo) — antes pasaba
   a "auto", y animar flex-basis DESDE/HACIA "auto" no tiene una
   interpolación bien definida (el navegador puede saltarlo en vez de
   interpolarlo), lo que se sentía como un rebote. Con la misma base
   numérica en ambos estados, solo flex-grow (0→1) anima — un número
   real, sin ese salto. */
.s5-wrapper[data-paso="0"] .s5-pipe__item[data-index="0"],
.s5-wrapper[data-paso="1"] .s5-pipe__item[data-index="1"],
.s5-wrapper[data-paso="2"] .s5-pipe__item[data-index="2"] {
  flex: 1 1 260px;
  opacity: 1;
}

/* Icono activo: símbolo a blanco pleno (igual que la tipografía) */
.s5-wrapper[data-paso="0"] .s5-pipe__item[data-index="0"] .s5-pipe__icon,
.s5-wrapper[data-paso="1"] .s5-pipe__item[data-index="1"] .s5-pipe__icon,
.s5-wrapper[data-paso="2"] .s5-pipe__item[data-index="2"] .s5-pipe__icon {
  color: #fff;
}

/* Al pasar el mouse por el item activo, el ícono también debe pasar al
   verde igual que cualquier otro — sin esto, la regla de arriba (más
   específica por el atributo data-paso) le gana al :hover plano y el
   ícono se queda blanco en vez de invertir. */
.s5-wrapper[data-paso="0"] .s5-pipe__item[data-index="0"]:hover .s5-pipe__icon,
.s5-wrapper[data-paso="1"] .s5-pipe__item[data-index="1"]:hover .s5-pipe__icon,
.s5-wrapper[data-paso="2"] .s5-pipe__item[data-index="2"]:hover .s5-pipe__icon {
  color: var(--verde-primario);
}

@media (max-width: 767px) {
  .s5-pipeline { padding: 0 16px; height: 30px; }
  .s5-pipe__item { flex-basis: 84px; padding: 0; gap: 10px; }
  .s5-pipe__item-label { font-size: 10px; letter-spacing: .8px; }
}

/* ============================================================
   S6b · MARCAS — carrusel horizontal infinito, placeholder
   ============================================================ */
.s6b-marcas {
  position: relative;
  /* 50svh exactos (antes 58svh): junto con el footer en 50svh (ver
     .site-footer) forman una sola "página" de 100svh — arriba el carrusel
     de clientes (fondo blanco), abajo el footer (fondo negro). */
  height: calc(50svh / var(--page-scale));
  min-height: 380px;
  background: #fff;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 24px;
  overflow: hidden;
}

.s6b-marcas__kicker {
  position: relative;
  z-index: 2;
  margin: 0;
  margin-bottom: 40px;
  color: rgba(19, 19, 19, 0.55);
  font-family: var(--font-family--font-family);
  text-transform: uppercase;
  letter-spacing: 3px;
  font-size: 20px;
  font-weight: 400;
}

/* Viñeta: oscurece levemente los extremos + funde el logo del carrusel
   hacia el borde en vez de cortarlo en seco (sirve igual sobre fondo
   blanco: mismo degradé a negro, solo que más sutil). z-index por ENCIMA
   del carril (3, contra 2 de .s6b-marcas__track-wrap) — quedaba debajo,
   así que nunca llegaba a fundir los logos y los de fondo blanco se
   veían con el borde cortado en seco contra el fondo blanco de la
   sección. */
.s6b-marcas__vignette {
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  background:
    linear-gradient(to right, rgba(0, 0, 0, 0.12) 0%, transparent 14%, transparent 86%, rgba(0, 0, 0, 0.12) 100%),
    radial-gradient(ellipse at center, transparent 55%, rgba(0, 0, 0, 0.06) 100%);
}

/* Alto fijo del "slot" de cada marca (el track y sus filas heredan este
   alto vía height:100%) — el <img> solo necesita max-height:100%; width:auto;
   para caer perfecto en el mismo carril, sin tocar el resto de la estructura.
   205px de tope = 256px (tamaño anterior) menos un 20% adicional a pedido
   explícito (256 * 0.8 = 204.8). clamp() en vez de un valor fijo: #marcas
   comparte la mitad del viewport con el footer (50svh cada uno, ver
   .s6b-marcas/.site-footer) — en laptops de poca altura real (ej.
   1366×768) un tope fijo no deja lugar para el kicker "Confían en
   Freshbox" sin desbordar la sección. */
.s6b-marcas__track-wrap {
  position: relative;
  z-index: 2;
  width: 100%;
  height: clamp(90px, calc(21.6svh / var(--page-scale)), 205px);
  overflow: hidden;
}

/* ── Entrada de Marcas (kicker + carrusel) ───────────
   Sin snap-on-approach acá (a diferencia de Impacto/Contacto) —
   initEntranceReveal (main.js) revela apenas asoma, sin esperar. El
   blur-in se aplica al WRAP (.s6b-marcas__track-wrap), nunca a
   .s6b-marcas__track: ese elemento tiene su transform reescrito en
   cada cuadro por el loop rAF del marquee (ver initMarcasMarquee) —
   animar transform ahí competiría con eso y el logo-carril se
   trabaría/saltaría durante la transición. */
.s6b-marcas.is-ready .s6b-marcas__kicker,
.s6b-marcas.is-ready .s6b-marcas__track-wrap {
  opacity: 0;
  filter: blur(14px);
  transform: translateY(20px);
  transition: opacity 0.85s ease, filter 0.85s ease, transform 0.85s cubic-bezier(0.22, 1, 0.36, 1);
}
.s6b-marcas.is-ready.is-inview .s6b-marcas__kicker,
.s6b-marcas.is-ready.is-inview .s6b-marcas__track-wrap {
  opacity: 1;
  filter: blur(0);
  transform: translateY(0);
}
.s6b-marcas.is-ready.is-inview .s6b-marcas__kicker { transition-delay: 0.1s; }
.s6b-marcas.is-ready.is-inview .s6b-marcas__track-wrap { transition-delay: 0.25s; }

.s6b-marcas__track {
  display: flex;
  align-items: center;
  height: 100%;
  width: max-content;
  /* BUG (reportado: "se percibe como un salto/reset... que sea
     infinito, sin saltos ni reinicios") — antes era un @keyframes CSS
     (translateX(0)→translateX(-50%), 55s linear infinite): en teoría
     corre en el compositor, pero sin ninguna garantía dura contra que
     el navegador desaloje esa capa bajo presión de memoria (hay MUCHOS
     otros will-change:transform en esta página) — cuando eso pasaba, se
     sentía como el marquee "pegándose" un instante y saltando para
     recuperar el tiempo perdido. Se reemplazó por initMarcasMarquee()
     en main.js: un loop por requestAnimationFrame que calcula la
     posición desde performance.now() (reloj real) en cada frame — sin
     ningún estado previo del que "recuperarse", así que no hay salto
     posible, ni siquiera bajo un tropiezo de rendimiento real (en el
     peor caso se ve menos fluido un instante, nunca salta). will-change
     se mantiene igual, para que el navegador SIGA intentando promoverlo
     a su propia capa — sigue ayudando, ya no es la única defensa. */
  will-change: transform;
  backface-visibility: hidden;
}

.s6b-marcas__group {
  display: flex;
  align-items: center;
  height: 100%;
  flex-shrink: 0;
  gap: 64px; /* separación entre logos — antes la daban los puntos (ya quitados) */
  padding-right: 64px;
}

/* Logos reales de clientes (ver /images/logos-clients) — cada archivo ya
   viene normalizado a un lienzo cuadrado 1:1 (500x500px, colores originales
   intactos). max-height:100% + width:auto los hace caer en el carril (ver
   .s6b-marcas__track-wrap) sin deformarse, con el ancho real que corresponda
   a la proporción de cada logo dentro de su cuadrado. the-sucseed.png tenía
   fondo gris oscuro de fábrica (necesario cuando el wordmark era blanco);
   el cliente lo reemplazó por una versión con fondo blanco y letras negras,
   consistente con el resto de los logos. */
.s6b-marcas__item {
  display: inline-block;
  max-height: 100%;
  width: auto;
  object-fit: contain;
  flex-shrink: 0;
}

/* El @keyframes que vivía acá (s6b-marcas__track, translateX 0→-50%) y
   su override de prefers-reduced-motion se sacaron — ver initMarcasMarquee()
   en main.js: ahora un loop por JS/rAF maneja el movimiento (y respeta
   prefers-reduced-motion por su cuenta, sin arrancar el loop). */

/* Mobile: los logos (clamp con techo en 205px, pensado para desktop)
   quedaban tan grandes que apenas entraban 2 dentro del viewport — a
   pedido explícito, se ven al menos 3 completos. Alto en vw (escala
   con el ancho real del teléfono, no con la altura) + gap más angosto.
   Como el carril es un marquee infinito en movimiento continuo, la
   cantidad de logos completos varía según el punto exacto del ciclo
   (a veces 2 completos + 2 parciales, a veces 3 completos + 1 parcial)
   — el cálculo apunta a que cada "período" (logo+gap) quepa 4 veces en
   el ancho más angosto realista (320px: 64px logo + 12px gap = 76px,
   320/76 ≈ 4.2), así el peor punto del ciclo nunca baja de 3 completos. */
@media (max-width: 767px) {
  .s6b-marcas__track-wrap {
    height: clamp(60px, 20vw, 100px);
  }
  .s6b-marcas__group {
    gap: 12px;
    padding-right: 12px;
  }
}

/* ============================================================
   EQUIPO (PROPUESTA 2) — layout tipo bento: columna de texto a la
   izquierda + grilla de fotos 2×2 a la derecha, con nombre/cargo en
   franja debajo de cada foto. Segunda propuesta para comparar contra
   ".s-story" (la sección que sigue después) — a pedido explícito.
   ============================================================ */
/* Sección de un solo "pantallazo" (100svh, igual criterio que .s6-outer/
   .s6b-marcas/.site-footer) — a pedido explícito, las 2 filas de
   tarjetas tienen que entrar completas sin scroll. El alto de cada
   tarjeta (.s-leaders__photo) se CALCULA a partir de 100svh en vez de
   por aspect-ratio: 56px de padding arriba/abajo + 28px de gap entre
   filas + 84px fijos de franja de nombre/cargo (.s-leaders__info) por
   tarjeta — lo que sobra, dividido en 2 filas, es el alto real de cada
   foto (ver calc() en .s-leaders__photo más abajo). */
.s-leaders {
  background: #fff;
  height: calc(100svh / var(--page-scale));
  overflow: hidden;
  /* Más aire arriba que abajo (90/40, antes 56/56 parejo) — mismo
     criterio que .s6-content (Impacto: padding-top 100px + headline con
     margin-top 100px propio) — a pedido explícito, "un poco más abajo". */
  padding: calc(90px / var(--page-scale)) 0 calc(40px / var(--page-scale));
}

/* Sin max-width/margin:auto (a diferencia de .s-story__wrapper y
   compañía): esta sección toma como referencia a .s6-content (Impacto),
   que tampoco tiene tope — un wrapper centrado con max-width:1600 deja
   ~105px de margen extra en pantallas de 1440px (el propio centrado +
   el padding), corriendo el título más a la derecha que el resto de
   las secciones "de una sola pantalla". Mismo padding real (80px) que
   .s6-content, para que el título arranque exactamente en el mismo
   punto que el de Impacto — a pedido explícito. */
.s-leaders__wrapper {
  padding: 0 80px;
}

/* Grid explícito 3 columnas × 2 filas (auto-placement): fila 1 = intro,
   card1, card2 — fila 2 = card3, card4, card5(cta). .s-leaders__intro
   es un item de grid más, en la celda (1,1) — al no ser tan alto como
   una tarjeta, queda apoyado arriba con aire debajo dentro de esa
   celda (misma altura que el resto de la fila 1), igual que en la
   referencia. */
.s-leaders__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: calc(28px / var(--page-scale));
}

.s-leaders__intro {
  display: flex;
  flex-direction: column;
  /* Empuja el bloque un poco más abajo dentro de su celda — mismo
     espíritu que el margin-top:100px del headline de Impacto, acotado
     acá porque la celda es bastante más baja que la de esa sección. */
  padding-top: calc(24px / var(--page-scale));
}

.s-leaders__kicker {
  display: flex;
  align-items: center;
  gap: calc(10px / var(--page-scale));
  margin: 0 0 calc(28px / var(--page-scale));
  font-family: var(--_typography---lucida-grande);
  font-size: calc(13px / var(--page-scale));
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--verde-primario);
}

.s-leaders__kicker-dot {
  width: calc(8px / var(--page-scale));
  height: calc(8px / var(--page-scale));
  background: var(--verde-primario);
  flex-shrink: 0;
}

/* Más grande (antes 52px) — al mismo nivel que el resto de los
   títulos de sección del sitio — y siempre pegado al margen
   izquierdo real de la celda (1,1), sin ningún corrimiento. */
.s-leaders__title {
  font-family: var(--_typography---lucida-grande);
  font-size: calc(64px / var(--page-scale));
  line-height: 1.05;
  font-weight: 400;
  letter-spacing: -0.01em;
  color: var(--negro);
  text-align: left;
  margin: 0;
}

/* Animación de entrada EN CASCADA de toda la grilla (título + las 5
   tarjetas), no solo el intro — a pedido explícito ("que implique la
   entrada de las tarjetas también... que se sienta premium").
   initLeadersReveal (main.js) agrega .is-inview a .s-leaders__grid vía
   gateSection, y cada hijo directo (intro, card1..card4, cta) anima con
   el mismo lenguaje visual del resto del sitio (opacity + blur +
   translateY), pero con su propio transition-delay según su posición —
   fila 1 (intro/card1/card2) entra primero, fila 2 (card3/card4/cta) un
   paso detrás, con un pequeño escalonado izquierda→derecha dentro de
   cada fila para que se lea como una coreografía, no un solo bloque. */
.s-leaders__grid > * {
  opacity: 0;
  filter: blur(16px);
  transform: translateY(40px);
  transition: opacity 1s cubic-bezier(0.22, 1, 0.36, 1),
              filter 1s cubic-bezier(0.22, 1, 0.36, 1),
              transform 1s cubic-bezier(0.22, 1, 0.36, 1);
}
.s-leaders__grid.is-inview > * {
  opacity: 1;
  filter: blur(0);
  transform: translateY(0);
}
.s-leaders__grid.is-inview > *:nth-child(1) { transition-delay: 0s; }
.s-leaders__grid.is-inview > *:nth-child(2) { transition-delay: 0.12s; }
.s-leaders__grid.is-inview > *:nth-child(3) { transition-delay: 0.24s; }
.s-leaders__grid.is-inview > *:nth-child(4) { transition-delay: 0.34s; }
.s-leaders__grid.is-inview > *:nth-child(5) { transition-delay: 0.46s; }
.s-leaders__grid.is-inview > *:nth-child(6) { transition-delay: 0.58s; }

.s-leaders__card {
  display: flex;
  flex-direction: column;
  border-radius: calc(4px / var(--page-scale));
  overflow: hidden;
  background: #f4f4f2;
}

/* Alto CALCULADO (no aspect-ratio): 100svh de la sección, menos 130px de
   padding (90 arriba + 40 abajo), menos 28px de gap entre filas, menos
   84px de franja de nombre/cargo — lo que queda se reparte entre las 2
   filas. Con un alto explícito ya no depende del ancho/atributos del
   <img> para no "saltar" antes de cargar la foto (mismo problema que
   resolvía antes el aspect-ratio + height:auto), así que se puede sacar
   toda esa lógica. */
.s-leaders__photo {
  width: 100%;
  height: calc((50svh - 163px) / var(--page-scale));
  object-fit: cover;
  /* Con el alto tan recortado (ver calc arriba), el centrado por
     defecto (50% 50%) dejaba la cabeza cortada arriba y de más espacio
     de hombros/pecho abajo — las fotos originales (900×1126) tienen la
     cara bastante más arriba que el centro geométrico. 22% baja el
     "plano" visible para que la cara quede centrada en la tarjeta. */
  object-position: 50% 22%;
  display: block;
  transition: transform 0.5s ease;
}

.s-leaders__card:hover .s-leaders__photo {
  transform: scale(1.04);
}

.s-leaders__info {
  height: calc(84px / var(--page-scale));
  padding: 0 calc(24px / var(--page-scale));
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.s-leaders__name {
  font-family: var(--font-family--principal-font), sans-serif;
  font-size: calc(19px / var(--page-scale));
  font-weight: 500;
  color: var(--negro);
  margin: 0;
}

.s-leaders__role {
  font-family: var(--font-family--principal-font), sans-serif;
  font-size: calc(14px / var(--page-scale));
  color: rgba(19, 19, 19, 0.6);
  margin: calc(4px / var(--page-scale)) 0 0;
}

/* 5ta tarjeta — sin foto, copy + CTA al formulario (ver #cadencia) en
   vez de un miembro más del equipo, igual criterio que el quinto lugar
   de la referencia. */
.s-leaders__card--cta {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: calc(24px / var(--page-scale));
  min-height: calc(220px / var(--page-scale));
  padding: calc(24px / var(--page-scale));
}

/* Tipografía de título (Lucida Grande), no de párrafo — copy corto y
   con más peso visual en vez del texto de cuerpo anterior, a pedido
   explícito ("algo más potente"). */
.s-leaders__cta-copy {
  font-family: var(--_typography---lucida-grande);
  font-size: calc(26px / var(--page-scale));
  line-height: 1.2;
  font-weight: 400;
  letter-spacing: -0.01em;
  color: var(--negro);
  margin: 0;
}

/* Mismo leitmotiv que .s32-cta (S3.2 "Más información") y compañía:
   ancho completo (no un pill chico que se achica al texto), columna con
   el label arriba y la flecha abajo a la derecha, negro + texto blanco
   — a pedido explícito, para que se sienta consistente con el resto de
   los CTA del sitio en vez de un botón aparte. El verde queda
   reservado para el :hover. */
.s-leaders__cta-link {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  width: 100%;
  min-height: calc(61px / var(--page-scale));
  padding: calc(11px / var(--page-scale)) calc(18px / var(--page-scale));
  border-radius: calc(8px / var(--page-scale));
  background: var(--negro);
  color: #fff;
  text-decoration: none;
  transition: background 0.3s ease, transform 0.3s ease, box-shadow 0.3s ease;
}
.s-leaders__cta-link:hover {
  background: var(--verde-primario);
  transform: translateY(-2px);
  box-shadow: 0 calc(10px / var(--page-scale)) calc(20px / var(--page-scale)) rgba(62, 115, 25, 0.35);
}
.s-leaders__cta-label {
  font-family: var(--font-secundaria);
  font-size: calc(15px / var(--page-scale));
  letter-spacing: 0.2px;
  font-weight: 500;
}
.s-leaders__cta-arrow {
  align-self: flex-end;
  font-size: calc(18px / var(--page-scale));
  line-height: 1;
}

@media (max-width: 767px) {
  /* El alto de 100svh (y el cálculo de .s-leaders__photo/.s-leaders__info
     en base a eso) es SOLO para desktop — acá vuelve a flujo normal:
     con 5 tarjetas apiladas en 2 columnas no entra ni entraba en una
     sola pantalla, y a diferencia de escritorio nadie pidió que
     entrara en mobile. */
  .s-leaders {
    height: auto;
    overflow: visible;
    padding: 70px 0;
  }
  .s-leaders__wrapper {
    padding: 0 24px;
  }
  .s-leaders__photo {
    height: auto;
    aspect-ratio: 4 / 5;
  }
  .s-leaders__info {
    height: auto;
    padding: 14px 16px;
  }
  /* 2 columnas para las tarjetas; el intro y la tarjeta CTA ocupan las
     2 columnas completas (su propia fila), como bloques de ancho
     completo — igual criterio que el resto de las secciones en mobile. */
  .s-leaders__grid {
    grid-template-columns: 1fr 1fr;
    gap: 12px;
  }
  .s-leaders__intro,
  .s-leaders__card--cta {
    grid-column: 1 / -1;
  }
  .s-leaders__intro {
    margin-bottom: 8px;
  }
  .s-leaders__kicker {
    font-size: 0.7rem;
  }
  .s-leaders__title {
    font-size: clamp(1.8rem, 7vw, 2.4rem);
  }
  .s-leaders__card--cta {
    min-height: 0;
    gap: 16px;
    padding: 20px;
  }
  .s-leaders__cta-copy {
    font-size: 21px;
    line-height: 1.25;
  }
  .s-leaders__cta-link {
    min-height: 52px;
    padding: 12px 18px;
  }
  .s-leaders__cta-label {
    font-size: 14px;
  }
  .s-leaders__name {
    font-size: 15px;
  }
  .s-leaders__role {
    font-size: 12px;
  }
}

/* ============================================================
   EQUIPO — réplica adaptada de "Our Story" (REFERENCES team/About •
   Institute of Health, sección .our_story_sec): título gigante
   position:sticky centrado en el viewport (top:50vh) mientras las 4
   tarjetas, con gran separación vertical y desplazadas en zigzag
   izq/der/centro, van "subiendo" por encima al hacer scroll — el efecto
   es pura maquetación (sticky + flujo normal), sin JS ni pin de
   ScrollTrigger. Las proporciones (ancho de tarjeta, salto entre
   tarjetas, tamaño del título) se MIDIERON del render real de la
   referencia a 1440px (no del CSS crudo, que usa una escala local
   fluida) y se reexpresaron con --page-scale, el mismo mecanismo fluido
   que ya usa el resto del sitio en el rango 992-1920px.
   A pedido explícito: la foto de cada persona CUBRE toda la tarjeta
   (no es un inset como en la referencia) — cargo/nombre van superpuestos
   abajo con un scrim para legibilidad.
   CONTENIDO PLACEHOLDER en el HTML: fotos/nombres/cargos son de relleno
   hasta que el cliente entregue el material real.
   ============================================================ */
.s-story {
  background: #f4f4f2;
  padding: calc(140px / var(--page-scale)) 0;
  overflow: clip;
}

.s-story__wrapper {
  max-width: 1600px;
  margin: 0 auto;
  padding: 0 60px;
  position: relative;
}

/* Título "Nuestro Equipo" — se queda centrado en el viewport mientras
   .s-story__cards (mucho más alta) se desplaza por detrás/encima, igual
   que en la referencia. position:sticky NO sirve acá: el sitio escala
   desktop entero con transform en #scaleWrapper (--page-scale), y un
   transform en un ancestro rompe sticky (confirmado: el top avanzaba
   1:1 con el scroll, nunca se quedaba pegado) — el mismo motivo por el
   que S6 tampoco usa pin de ScrollTrigger (ver initS6 más arriba: "no
   hay nada que compensar contra el scale del wrapper" es la razón de
   fondo). Se simula el sticky a mano: position:absolute + un transform
   que initStorySticky (main.js) recalcula en cada scroll a partir de
   medidas reales (getBoundingClientRect), compensando --page-scale. */
.s-story__headline {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 24px;
  position: absolute;
  left: 60px;
  right: 60px;
  /* 50vh se evalúa en el espacio LOCAL (dentro de #scaleWrapper) y ese
     valor se vuelve a escalar visualmente por --page-scale al
     renderizarse — sin compensar, 450px locales (50vh de un viewport de
     900) se veían como 337.5px reales (450×0.75). Mismo patrón que ya
     usa el resto del sitio (.s6-outer, .s-contact, etc: calc(Xsvh /
     var(--page-scale))) para el mismo problema. */
  top: calc(50vh / var(--page-scale));
  transform: translateY(-50%); /* valor de arranque; JS toma el control apenas corre */
  z-index: 1;
  pointer-events: none;
}
.s-story__word {
  font-family: var(--_typography---lucida-grande);
  font-size: calc(150px / var(--page-scale));
  line-height: 0.9;
  letter-spacing: -0.02em;
  font-weight: 400;
  color: var(--negro);
  margin: 0;
}

.s-story__cards {
  list-style: none;
  margin: 0;
  padding: 0;
  position: relative;
  z-index: 2;
}

.s-story__card {
  position: relative;
  display: block;
  width: calc(420px / var(--page-scale));
  aspect-ratio: 3 / 4;
  border-radius: 14px;
  overflow: hidden;
  background: #d8d8d3;
  box-shadow: 0 30px 70px rgba(0, 0, 0, 0.18);
}
/* Zigzag izq/der/centro — mismo criterio que .story_card.is-1..is-5 de
   la referencia, adaptado a 4 tarjetas en vez de 5. */
.s-story__card.is-1 { margin-top: calc(80px / var(--page-scale)); margin-left: 8%; }
.s-story__card.is-2 { margin-top: calc(220px / var(--page-scale)); margin-left: auto; margin-right: 8%; }
.s-story__card.is-3 { margin-top: calc(220px / var(--page-scale)); margin-left: 16%; }
.s-story__card.is-4 { margin-top: calc(220px / var(--page-scale)); margin-left: auto; margin-right: auto; }

.s-story__photo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform .5s ease;
}

/* Overlay con cargo/nombre: oculto por defecto, aparece al pasar el
   mouse por la tarjeta (desktop) — a pedido explícito. En mobile no hay
   hover, así que queda siempre visible (ver @media abajo). */
.s-story__scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, transparent 45%, rgba(0, 0, 0, 0.8) 100%);
  opacity: 0;
  transition: opacity .35s ease;
}

.s-story__caption {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 24px 28px 28px;
  color: #fff;
  opacity: 0;
  transform: translateY(10px);
  transition: opacity .35s ease, transform .35s ease;
}

.s-story__card:hover .s-story__photo {
  transform: scale(1.045);
}
.s-story__card:hover .s-story__scrim {
  opacity: 1;
}
.s-story__card:hover .s-story__caption {
  opacity: 1;
  transform: translateY(0);
}

/* Estructura invertida respecto a la referencia (REFERENCES team/Our
   Story): ahí el header chico + línea divisoria van ARRIBA de la
   tarjeta y el título abajo — acá, con la foto a página completa, ese
   mismo bloque (header + divisor + título) se invierte al fondo de la
   tarjeta. El cargo hace de "header" (chico, con la línea divisoria
   debajo, como caption_story) y el nombre hace de "título" (grande,
   como title_card_story). */
.s-story__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding-bottom: 12px;
  margin-bottom: 14px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.3);
}
.s-story__role {
  font-family: var(--font-secundaria);
  font-size: 0.75rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: rgba(255, 255, 255, 0.85);
  margin: 0;
}
.s-story__dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.6);
  flex-shrink: 0;
}
.s-story__name {
  font-family: var(--font-family--principal-font), sans-serif;
  font-size: 1.6rem;
  font-weight: 500;
  line-height: 1.1;
  margin: 0;
}

/* Mobile: igual que la referencia en su propio quiebre más chico (ahí
   479px, acá el estándar del sitio, 767px) — se abandona el sticky/
   zigzag y las tarjetas pasan a ser una lista vertical normal, a ancho
   completo, título estático arriba — a pedido explícito ("tarjetas
   normales en vista mobile"). */
@media (max-width: 767px) {
  .s-story {
    /* Más aire arriba (antes 70px parejo) — a pedido explícito. */
    padding: 100px 0 70px;
  }
  .s-story__wrapper {
    padding: 0 24px;
  }
  .s-story__headline {
    position: static;
    transform: none;
    justify-content: flex-start;
    align-items: baseline;
    gap: 0.35em;
    margin-bottom: 32px;
  }
  /* "Nuestro Equipo" en una sola línea — el ancho de línea manda: vw puro
     (sin piso/techo en rem) para que siempre entre completo, incluso en
     los viewports más angostos (320-360px), a pedido explícito. */
  .s-story__word {
    font-size: 8.6vw;
    white-space: nowrap;
  }
  .s-story__cards {
    display: flex;
    flex-direction: column;
    gap: 20px;
  }
  .s-story__card,
  .s-story__card.is-1,
  .s-story__card.is-2,
  .s-story__card.is-3,
  .s-story__card.is-4 {
    width: 100%;
    aspect-ratio: 4 / 5;
    margin: 0;
  }
  /* Sin mouse en touch: el overlay de cargo/nombre queda siempre visible. */
  .s-story__scrim,
  .s-story__caption {
    opacity: 1;
    transform: none;
  }
  /* Animación de entrada reversible (mismo criterio que .s32.is-ready/
     is-inview de S3.2: opacity + blur + translateY) — a pedido
     explícito, las tarjetas aparecen al bajar y VUELVEN a ocultarse si
     el usuario sube el scroll (initStoryCardReveal en main.js usa
     gateSection, que dispara enter/leave con cada cruce del viewport
     en cualquier dirección, no solo una vez). */
  .s-story__card {
    opacity: 0;
    transform: translateY(36px);
    filter: blur(6px);
    transition: opacity .7s cubic-bezier(0.22, 1, 0.36, 1),
                transform .7s cubic-bezier(0.22, 1, 0.36, 1),
                filter .7s cubic-bezier(0.22, 1, 0.36, 1);
  }
  .s-story__card.is-inview {
    opacity: 1;
    transform: translateY(0);
    filter: blur(0);
  }
}

/* ============================================================
   S6 · MADURAR BIEN TAMBIÉN ES CUIDAR
   ============================================================ */

.s6-outer {
  background: #131313;
  height: calc(100svh / var(--page-scale));
  padding: 0;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}

.s6-inner-container {
  position: relative;
  width: calc(100vw / var(--page-scale));
  height: calc(100svh / var(--page-scale));
  margin: 0;
  overflow: hidden;
  flex-shrink: 0;
  background-color: #1b3020; /* fallback mientras carga la capa de fondo */
}

/* Capa de fondo dedicada: más alta que el contenedor para parallax por translateY
   (GPU, sin repaint → sin trastabilleo). La mueve el JS en initS6. */
.s6-bg {
  position: absolute;
  top: -6%;
  left: 0;
  width: 100%;
  height: 112%;
  /* background-image lo asigna lazyBgOnApproach (main.js) al acercarse */
  background-color: #1b3020; /* fallback mientras baja la foto */
  background-size: cover;
  background-position: center;
  z-index: 0;
  will-change: transform;
}

.s6-bg-overlay {
  position: absolute;
  inset: 0;
  /* Overlay tenue (degradado suave, un poco más oscuro abajo) para que el texto destaque */
  background: linear-gradient(180deg, rgba(0, 0, 0, 0.22) 0%, rgba(0, 0, 0, 0.42) 100%);
  z-index: 1;
}

/* ── Contenido ───────────────────────────────────── */
.s6-content {
  position: relative;
  z-index: 2;
  display: grid;
  grid-template-rows: 1fr auto;
  height: calc(100svh / var(--page-scale));
  padding: 100px 80px 80px;
  box-sizing: border-box;
}

/* ── Headline con texto fantasma ─────────────────── */
.s6-headline-wrap {
  position: relative;
  flex: 1;
}

.s6-headline {
  font-family: var(--_typography---lucida-grande), serif;
  font-size: clamp(2.2rem, calc(5.2vw / var(--page-scale)), 4.2rem);
  font-weight: 400;
  line-height: 0.95;
  letter-spacing: 0;
  margin: 0;
  max-width: none;
  margin-top: 100px;
}
/* Título de sección más chico en mobile — mismo criterio que el hero:
   --page-scale ya da 1 en este rango de anchos, así que se recalibra a
   los tamaños reales de un título de sección medidos en institute of
   health, no a los de escritorio. */
@media (max-width: 991px) {
  .s6-headline { font-size: clamp(1.8rem, 5.2vw, 2.3rem); }
}
@media (max-width: 767px) {
  .s6-headline { font-size: clamp(1.6rem, 6.2vw, 2.5rem); }
  /* padding de escritorio (80px por lado) dejaba solo ~230px de ancho
     útil en un teléfono — el título (3 líneas reales) se envolvía a 5
     visualmente, y sumado al margin-top:100px (pensado para el aire
     extra del grid en desktop, donde sobra alto) empujaba todo hacia
     el borde inferior del frame de 100svh — a pedido, se sentía
     recortado abajo. */
  .s6-content { padding: 100px 24px 28px; }
  .s6-headline { margin-top: 0; }
}
@media (max-width: 479px) {
  .s6-headline { font-size: clamp(1.5rem, 9.2vw, 2.2rem); }
}

/* Capa base — todo el párrafo en fantasma */
.s6-headline--ghost {
  color: rgba(255, 255, 255, 0.28);
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}

/* Líneas — display block para que cada span ocupe su propia fila */
.s6-line {
  display: block;
}

/* Capa fill — sin clip en el bloque, el clip va línea a línea */
.s6-headline--fill {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  color: #fff;
  pointer-events: none;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}

/* Mientras S6 está activa (timeline en curso) promovemos la capa de relleno
   a su propia capa de composición → el repaint del clip-path queda AISLADO
   del fantasma/fondo/overlay. `will-change` solo durante la animación (lo
   alterna initS6 vía .is-animating) para no dejar la capa permanente. */
.s6-headline-wrap.is-animating .s6-headline--fill {
  will-change: transform;
  transform: translateZ(0);
}

.s6-headline--fill .s6-line {
  /* TEMPORAL: franja desactivada → texto blanco fijo.
     Restaurar efecto: clip-path: inset(0 100% 0 0); */
  clip-path: none;
}

/* ── Microbloque copy ────────────────────────────── */
.s6-micro {
  font-family: var(--font-family--principal-font), sans-serif;
  font-size: 21px;
  line-height: 1.2;
  color: #fff;
  max-width: 336px;
  margin: 0 0 0 auto;
  align-self: end;
  justify-self: end;
  text-align: left;
}
@media (max-width: 767px) {
  .s6-micro { font-size: 15px; line-height: 1.45; max-width: 100%; }
}

/* ── Entrada de Impacto (fondo + textos) ─────────────
   .s6-outer también tiene su propio scroll-snap al acercarse (ver
   initSnapOnApproach en main.js, aplicado a ".s6-outer") — la
   revelación NO se dispara por IntersectionObserver (que dispararía
   ANTES de que el snap se active, corriendo la transición en paralelo
   con ese scroll programático y terminando casi al mismo tiempo que se
   asienta, sin notarse — mismo bug ya resuelto en Nosotros). En vez de
   eso, initEntranceReveal (main.js) exige que la sección esté CASI del
   todo asentada arriba antes de revelar, así nunca se adelanta al
   snap. .s6-bg NO lleva transform acá (solo opacity/blur): ya tiene su
   propio parallax por GSAP (yPercent, ver initS6) que reescribe
   transform en cada scroll — animar transform acá por CSS competiría
   con eso. Mismo lenguaje de "blur intenso + leve zoom" ya usado en el
   crossfade de fondo de video (ver .bi-video), pero solo blur+opacity
   para no pisar el parallax. */
.s6-outer.is-ready .s6-bg {
  opacity: 0;
  filter: blur(18px);
  transition: opacity 0.9s ease, filter 0.9s ease;
}
.s6-outer.is-ready.is-inview .s6-bg {
  opacity: 1;
  filter: blur(0);
}
.s6-outer.is-ready .s6-headline-wrap,
.s6-outer.is-ready .s6-micro {
  opacity: 0;
  filter: blur(14px);
  transform: translateY(24px);
  transition: opacity 0.9s ease, filter 0.9s ease, transform 0.9s cubic-bezier(0.22, 1, 0.36, 1);
}
.s6-outer.is-ready.is-inview .s6-headline-wrap,
.s6-outer.is-ready.is-inview .s6-micro {
  opacity: 1;
  filter: blur(0);
  transform: translateY(0);
}
.s6-outer.is-ready.is-inview .s6-headline-wrap { transition-delay: 0.15s; }
.s6-outer.is-ready.is-inview .s6-micro { transition-delay: 0.35s; }

/* ============================================================
   S7 · LA CADENCIA FRESHBOX
   ============================================================ */

.section-cadencia {
  position: relative;
  background-color: #0a0f0d;
  background-image: url('../images/PLANTA-FRESHBOX/FRESHBOX-0 8-cadencia.jpg');
  background-size: cover;
  background-position: center;
  height: 90em;
  min-height: unset;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

.section-cadencia::before {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
  z-index: 0;
}

.section-cadencia > * {
  position: relative;
  z-index: 1;
}

/* Punto de luz sutil animado */
.s7-glow {
  position: absolute;
  width: calc(60vw / var(--page-scale));
  height: calc(60vw / var(--page-scale));
  border-radius: 50%;
  background: radial-gradient(circle, rgba(100, 160, 60, 0.07) 0%, transparent 70%);
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  animation: s7-drift 10s ease-in-out infinite alternate;
  pointer-events: none;
  z-index: 0;
}

@keyframes s7-drift {
  from {
    transform: translate(-55%, -55%);
  }

  to {
    transform: translate(-45%, -45%);
  }
}

/* Contenido alineado a la izquierda */
.s7-content {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  text-align: left;
  max-width: none;
  width: 100%;
  padding: 80px 80px;
  box-sizing: border-box;
}

/* ── Headline text fill ──────────────────────────── */
.s7-headline-wrap {
  position: relative;
  margin: 0 0 36px;
}

.s7-headline {
  font-family: var(--_typography---lucida-grande), serif;
  font-size: clamp(2.08rem, calc(5.5vw / var(--page-scale)), 4.4rem);
  font-weight: 400;
  line-height: 1.1;
  letter-spacing: 0;
  margin: 0;
}

.s7-headline--ghost {
  color: rgba(255, 255, 255, 0.12);
}

.s7-headline--fill {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  color: #fff;
  text-align: left;
  clip-path: none;
  pointer-events: none;
}

/* ── Subtext text fill ───────────────────────────── */
.s7-subtext-wrap {
  position: relative;
  margin: 0 0 48px;
}

.s7-subtext {
  font-family: var(--font-family--principal-font), sans-serif;
  font-size: clamp(1rem, calc(1.4vw / var(--page-scale)), 1.2rem);
  line-height: 1.65;
  font-weight: 400;
  margin: 0;
}

.s7-subtext--ghost {
  color: rgba(255, 255, 255, 0.12);
}

.s7-subtext--fill {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  color: rgba(255, 255, 255, 0.70);
  clip-path: inset(0 100% 0 0);
  pointer-events: none;
}

/* ── Firma ───────────────────────────────────────── */
.s7-firma {
  font-family: var(--font-family--principal-font), sans-serif;
  font-size: 0.85rem;
  font-style: italic;
  color: rgba(255, 255, 255, 0.45);
  margin: 0 0 52px;
  opacity: 0;
}

/* ── CTA ─────────────────────────────────────────── */
.s7-cta {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 18px;
  opacity: 0;
  transform: translateY(20px);
}

.s7-btn {
  display: inline-block;
  padding: 15px 52px;
  border: 1.5px solid rgba(255, 255, 255, 0.85);
  border-radius: 40px;
  color: #fff;
  background: transparent;
  font-family: var(--font-family--principal-font), sans-serif;
  font-size: 0.95rem;
  letter-spacing: 0;
  text-decoration: none;
  transition: background 0.3s ease, color 0.3s ease, box-shadow 0.3s ease;
}

.s7-btn:hover {
  background: #fff;
  color: #0a0f0d;
  box-shadow: 0 0 28px rgba(180, 210, 80, 0.40);
}

.s7-link {
  font-family: var(--font-family--principal-font), sans-serif;
  font-size: 0.85rem;
  color: rgba(255, 255, 255, 0.40);
  text-decoration: none;
  transition: color 0.3s ease;
}

.s7-link:hover {
  color: rgba(255, 255, 255, 0.70);
}

/* ============================================================
   S-CONTACT · SECCIÓN CONTACTO (reemplaza Cadencia)
   ============================================================ */

/* ── Entrada de Contacto (título + columnas, incl. el formulario) ───
   Igual que Impacto: #cadencia TAMBIÉN tiene su propio scroll-snap al
   acercarse (ver initSnapOnApproach en main.js) — mismo criterio,
   initEntranceReveal exige que la sección esté casi del todo asentada
   arriba antes de revelar, para no adelantarse al snap y que la
   transición no quede "ya resuelta" cuando el usuario puede fijarse. */
.s-contact.is-ready .s-contact__header,
.s-contact.is-ready .s-contact__rule,
.s-contact.is-ready .s-contact__left,
.s-contact.is-ready .s-contact__right {
  opacity: 0;
  filter: blur(14px);
  transform: translateY(24px);
  transition: opacity 0.9s ease, filter 0.9s ease, transform 0.9s cubic-bezier(0.22, 1, 0.36, 1);
}
.s-contact.is-ready.is-inview .s-contact__header,
.s-contact.is-ready.is-inview .s-contact__rule,
.s-contact.is-ready.is-inview .s-contact__left,
.s-contact.is-ready.is-inview .s-contact__right {
  opacity: 1;
  filter: blur(0);
  transform: translateY(0);
}
.s-contact.is-ready.is-inview .s-contact__header { transition-delay: 0.1s; }
.s-contact.is-ready.is-inview .s-contact__rule { transition-delay: 0.22s; }
.s-contact.is-ready.is-inview .s-contact__left { transition-delay: 0.3s; }
.s-contact.is-ready.is-inview .s-contact__right { transition-delay: 0.38s; }

.s-contact {
  background-color: #e6e6e1;
  color: #131313;
  height: calc(100svh / var(--page-scale));
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  padding-top: 110px;
  overflow: hidden;
}

/* Cabecera */
.s-contact__header {
  padding: 40px 60px 24px;
  flex-shrink: 0;
}
.s-contact__title {
  font-family: var(--font-family--principal-font), sans-serif;
  font-size: clamp(2.4rem, calc(5vw / var(--page-scale)), 4rem);
  font-weight: 500;
  line-height: 1.05;
  margin: 0;
  color: #131313;
}
/* Título de sección más chico en mobile — mismo criterio que el hero:
   --page-scale ya da 1 en este rango de anchos, así que se recalibra a
   los tamaños reales de un título de sección medidos en institute of
   health, no a los de escritorio. */
@media (max-width: 991px) {
  .s-contact__title { font-size: clamp(1.8rem, 5vw, 2.3rem); }
}
@media (max-width: 767px) {
  .s-contact__title { font-size: clamp(1.6rem, 6vw, 2.5rem); }
}
@media (max-width: 479px) {
  .s-contact__title { font-size: clamp(1.5rem, 9vw, 2.2rem); }
}

/* Línea divisoria */
.s-contact__rule {
  height: 1px;
  background: rgba(19,19,19,0.15);
  margin: 0 60px 0;
}

/* Cuerpo 2 columnas */
.s-contact__body {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0;
  padding: 32px 60px 40px;
  flex: 1;
  min-height: 0;
}

/* — Columna izquierda — */
.s-contact__left {
  display: flex;
  flex-direction: column;
  gap: 24px;
  padding-right: 48px;
  border-right: 1px solid rgba(19,19,19,0.12);
  align-self: stretch;
  min-height: 0;
}
.s-contact__info {
  display: flex;
  flex-direction: row;
  gap: 48px;
}
.s-contact__info-group {
  display: flex;
  flex-direction: column;
  gap: 6px;
  flex: 0 0 38%;
}
.s-contact__info-group:last-child {
  flex: 1;
}
.s-contact__info-label {
  font-family: var(--font-secundaria);
  font-size: 11.2px; /* -20% del cuerpo (14px) — títulos sin cambio */
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: #131313;
  margin: 0 0 8px;
}
.s-contact__info-link {
  font-family: var(--font-family--principal-font), sans-serif;
  font-size: 0.8rem; /* -20% del cuerpo (1rem) — títulos sin cambio */
  color: #131313;
  text-decoration: none;
  transition: color 0.25s ease;
}
.s-contact__info-link:hover { color: var(--verde-primario); }
.s-contact__info-text {
  font-family: var(--font-family--principal-font), sans-serif;
  font-size: 0.8rem; /* -20% del cuerpo (1rem) — títulos sin cambio */
  color: #131313;
  margin: 0;
  line-height: 1.5;
}

/* Mapa */
.s-contact__map {
  flex: 1;
  min-height: 200px;
  border-radius: 8px;
  overflow: hidden;
  background: rgba(19,19,19,0.06);
  display: flex;
  flex-direction: column;
}
.s-contact__map iframe {
  display: block;
  width: 100%;
  flex: 1;
  min-height: 200px;
}

/* — Columna derecha: formulario — */
.s-contact__right {
  padding-left: 48px;
  padding-top: 12px; /* evita que overflow-y:auto recorte el ascender de "Conectemos" pegado al borde */
  display: flex;
  flex-direction: column;
  align-self: stretch;
  min-height: 0;
  overflow-y: auto; /* colchón de seguridad: si el formulario sigue sin caber en viewports muy bajos, scrollea internamente en vez de recortarse */
}
.s-contact__form-title {
  font-family: var(--font-family--principal-font), sans-serif;
  font-size: clamp(2rem, calc(3.5vw / var(--page-scale)), 3rem);
  font-weight: 500;
  margin: 0 0 4px;
  color: #131313;
  flex-shrink: 0;
}
/* "Visítanos" — solo aparece en mobile (ver @media 767px), marca el
   inicio del bloque de contacto+mapa una vez invertido el orden. */
.s-contact__visit-title {
  display: none;
}
.s-contact__visit-rule {
  display: none;
}
.s-contact__mandatory {
  font-family: var(--font-secundaria);
  font-size: 8.8px; /* -20% del cuerpo (11px) — títulos sin cambio */
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgba(19,19,19,0.4);
  margin: 0 0 12px;
  text-align: right;
  flex-shrink: 0;
}
.s-contact__form {
  display: flex;
  flex-direction: column;
  flex: 1;
  justify-content: space-between;
  gap: 16px;
  min-height: 0;
}
.s-contact__row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 32px;
}
.s-contact__field {
  display: flex;
  flex-direction: column;
}
.s-contact__field--grow {
  flex: 1;
  display: flex;
  flex-direction: column;
}
.s-contact__field--grow .s-contact__input {
  flex: 1;
}
.s-contact__label {
  font-family: var(--font-secundaria);
  font-size: 11.2px; /* -20% del cuerpo (14px) — títulos sin cambio */
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: #131313;
  margin-bottom: 8px;
}
.s-contact__hint {
  opacity: 0.65;
  text-transform: none;
  letter-spacing: 0;
}
.s-contact__input {
  font-family: var(--font-family--principal-font), sans-serif;
  font-size: clamp(0.792rem, calc(1.152vw / var(--page-scale)), 1.08rem); /* -20% del cuerpo — títulos sin cambio */
  color: #131313;
  background: transparent;
  border: none;
  border-bottom: 1px solid rgba(19,19,19,0.2);
  padding: 12px 0;
  outline: none;
  transition: border-color 0.25s ease;
  width: 100%;
  box-sizing: border-box;
  line-height: 1.2;
}
.s-contact__input::placeholder { color: rgba(19,19,19,0.3); }
.s-contact__input:focus { border-color: var(--verde-primario); }
.s-contact__textarea {
  resize: none;
  flex: 1;
  min-height: 90px;
  border-bottom: none;
}

/* Privacidad + submit — fila inferior */
.s-contact__privacy {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding-top: 16px;
  border-top: 1px solid rgba(19,19,19,0.15);
  flex-shrink: 0;
}
.s-contact__form-status {
  font-family: var(--font-secundaria);
  font-size: 0.72rem;
  color: rgba(19,19,19,0.65);
  text-align: right;
  margin: 8px 0 0;
}
.s-contact__form-status[hidden] { display: none; }
.s-contact__privacy-label {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  font-family: var(--font-family--principal-font), sans-serif;
  font-size: 0.72rem; /* -20% del cuerpo (0.9rem) — títulos sin cambio */
  color: rgba(19,19,19,0.65);
  cursor: pointer;
  flex: 1;
  line-height: 1.45;
}
/* Ocultar checkbox nativo */
.s-contact__checkbox { position: absolute; opacity: 0; width: 0; height: 0; }
/* Checkbox custom */
.s-contact__checkbox-custom {
  flex-shrink: 0;
  width: 20px;
  height: 20px;
  border: 1.5px solid rgba(19,19,19,0.35);
  border-radius: 3px;
  background: transparent;
  transition: border-color 0.2s ease, background 0.2s ease;
  margin-top: 2px;
  position: relative;
}
.s-contact__checkbox:checked + .s-contact__checkbox-custom {
  background: #131313;
  border-color: #131313;
}
.s-contact__checkbox:checked + .s-contact__checkbox-custom::after {
  content: '';
  position: absolute;
  left: 5px; top: 2px;
  width: 6px; height: 10px;
  border: 2px solid #fff;
  border-top: none; border-left: none;
  transform: rotate(45deg);
}
.s-contact__privacy-link {
  color: #131313;
  text-decoration: underline;
  text-underline-offset: 2px;
  transition: color 0.2s ease;
}
.s-contact__privacy-link:hover { color: var(--verde-primario); }

/* CTA — mismo patrón que .s32-cta / .s3v-cta */
.s-contact__submit {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-self: flex-end;
  width: 340px;
  max-width: 100%;
  min-height: 61px;
  padding: 11px 18px;
  background: var(--negro);
  color: #fff;
  border-radius: 8px;
  border: none;
  cursor: pointer;
  text-align: left;
  margin-top: 8px;
  transition: background 0.3s ease;
}
.s-contact__submit:hover { background: var(--verde-primario); }
.s-contact__submit-label {
  font-family: var(--font-secundaria);
  font-size: 0.76rem; /* -20% del cuerpo (0.95rem) — títulos sin cambio */
  letter-spacing: 0.2px;
}
.s-contact__submit-arrow {
  align-self: flex-end;
  font-size: 1.15rem;
  line-height: 1;
  transition: transform 0.3s ease;
}
.s-contact__submit:hover .s-contact__submit-arrow { transform: translate(3px, -3px); }

/* Responsive */
@media (max-width: 900px) {
  .s-contact__body { grid-template-columns: 1fr; }
  .s-contact__left { border-right: none; border-bottom: 1px solid rgba(19,19,19,0.12); padding-right: 0; padding-bottom: 36px; }
  .s-contact__right { padding-left: 0; padding-top: 36px; }
}
@media (max-width: 600px) {
  .s-contact__header { padding: 40px 24px 28px; }
  .s-contact__rule { margin: 0 24px; }
  .s-contact__body { padding: 32px 24px 0; }
  .s-contact__row { grid-template-columns: 1fr; }
}

/* A diferencia de S2/S3/S5/S6, Contacto NO es una slide de la
   presentación (sin animación tipo diapositiva) — es una sección de
   scroll normal, pero heredaba el mismo molde height:100svh +
   overflow:hidden pensado para esas otras. En mobile, con el body
   apilado en una sola columna (info+mapa arriba, formulario completo
   abajo), ese contenido es mucho más alto que un viewport — quedaba
   comprimido dentro de #s-contact__right con su propio scroll interno.
   Se deja crecer en alto natural y scrollear con la página, como
   corresponde a una sección sin pin/freeze — a pedido explícito. */
@media (max-width: 767px) {
  .s-contact {
    height: auto;
    overflow: visible;
  }
  /* min-width:0 rompe la cadena grid/flex "auto se expande al min-content
     del hijo": .s-contact__body es grid de una sola columna (1fr) sin
     minmax(0,1fr) — antes el overflow-x resultante quedaba oculto por el
     overflow:hidden/auto que se acaba de quitar arriba; visible de
     verdad, .s-contact__right (y todo lo de adentro: form/row/field/
     input) se salía más ancho que la pantalla. */
  .s-contact__right {
    overflow-y: visible;
    min-width: 0;
  }
  /* Regla general en mobile: TODO el formulario en vertical, sin
     columnas (a pedido explícito). Antes solo se apilaba bajo 600px, así
     que entre 601 y 767px los pares nombre/apellido y correo/teléfono
     seguían compartiendo fila y quedaban estrechos. El bloque de datos
     (Contacto / Planta) sigue el mismo criterio: en dos columnas la
     dirección se partía en 5 líneas de dos palabras. */
  .s-contact__row {
    grid-template-columns: 1fr;
    /* era "gap: 0 32px" (0 vertical, pensado para columnas lado a lado) —
       al apilar en 1fr el segundo campo de cada fila (ej. Apellido) quedaba
       pegado al de arriba, sin el mismo aire que separa una fila de la
       siguiente (.s-contact__form ya usa gap:16px entre filas). */
    gap: 16px;
  }
  .s-contact__info {
    flex-direction: column;
    gap: 28px;
  }
  .s-contact__info-group,
  .s-contact__info-group:last-child {
    flex: 0 0 auto;
  }
  /* El body no tenía padding inferior (0) — el botón "Enviar solicitud"
     quedaba pegado al borde de la sección. */
  .s-contact__body {
    padding-bottom: 56px;
  }
  /* Checkbox de privacidad + botón "Enviar solicitud" en bloques
     apilados (antes flex-row + space-between: quedaban aplastados uno
     junto al otro) — a pedido explícito. */
  .s-contact__privacy {
    flex-direction: column;
    align-items: stretch;
    gap: 20px;
  }
  .s-contact__submit {
    width: 100%;
    align-self: stretch;
    margin-top: 0;
  }
  /* Orden invertido solo en mobile: el formulario primero, los datos de
     contacto + mapa después — a pedido explícito. Cambia solo el orden
     VISUAL (el DOM/orden de tabulado sigue siendo info→form); .s-contact
     __body sigue siendo el mismo grid de 1 columna (ver @media 900px). */
  .s-contact__right {
    order: -1;
  }
  /* "Conectemos" ~30% más chico (era clamp con techo 3rem/48px, clampeaba
     al piso 2rem/32px en este ancho) — a pedido explícito. Como
     .s-contact__visit-title comparte la misma clase, hereda el mismo
     tamaño reducido: "las mismas características que Conectemos". */
  .s-contact__form-title {
    font-size: 1.4rem;
  }
  /* Con el orden invertido (ver .s-contact__right { order:-1 } arriba),
     .s-contact__body queda con gap:0 entre bloques — el padding que
     antes los separaba (36px, ver @media 900px) terminó en los extremos
     equivocados. La línea divisoria + el padding de ambos son lo que
     separa visualmente el bloque de "Visítanos" del form de arriba —
     a pedido explícito, un toque más de aire que la primera versión. */
  .s-contact__visit-rule {
    display: block;
    height: 1px;
    background: rgba(19, 19, 19, 0.15);
    margin-top: 56px;
  }
  .s-contact__visit-title {
    display: block;
    padding-top: 32px;
  }
}

/* ============================================================
   S3 · CARTERA DE MADURACIÓN — fondo negro Freshbox
   ============================================================ */
#cartera {
  background-color: #080808;
}

/* ====== RESPONSIVE ====== */
/* ==========================================================================
   FRESHBOX — Mejoras responsive
   Capa adicional sobre el CSS base. Solo añade media queries; no toca
   selectores ni rompe interacciones del engine.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Hero — quiebres alineados al planteamiento de institute of health
   (referencia): 991/767/479 en vez del patchwork anterior (1280/991/767/480
   + parches por altura). El titular escala con la MISMA lógica en cada
   quiebre (clamp con piso/techo propios, no un solo valor fijo — acá no
   alcanza con un único clamp para todo el rango como en la referencia,
   porque nuestro --page-scale ya compensa por alto+ancho a la vez, no
   solo por ancho como el 1vw de ellos); lo que sí se replica tal cual es
   que el texto SECUNDARIO (párrafo) escala hacia ARRIBA en cada quiebre
   mobile en vez de achicarse — antes hacía lo contrario (1.15rem escritorio
   → 1.0625rem en mobile, al revés que la referencia).
   -------------------------------------------------------------------------- */

/* --------------------------------------------------------------------------
   2. Tablet — ≤ 991px
   -------------------------------------------------------------------------- */
@media (max-width: 991px) {

  /* Hero — apilar texto izquierdo y aside derecho */
  .section {
    height: auto;
    min-height: calc(100dvh / var(--page-scale));
    padding-top: 120px;
  }

  .hero-container {
    flex-flow: column;
    height: auto;
    padding-bottom: 24px;
  }

  /* "Scroll to Discover" es un hint pensado para el mouse/wheel de
     desktop — en mobile es redundante (el usuario ya sabe deslizar) y,
     al ser un pill ancho fijo en la esquina inferior derecha, con la
     tipografía correcta del hero (antes quedaba chica por un bug de
     cascada, ver .heading-2/.paragraph-2 más abajo) termina solapado
     con el CTA de video, que en mobile ocupa casi todo el ancho. */
  .hero-scroll-label {
    /* !important: .hero-info-btn (declarado más abajo en el archivo,
       sin media query) fija display:inline-flex y le gana a esta regla
       por orden de cascada — mismo problema estructural que
       .flex-block-2/.heading-2/.paragraph-2 de más arriba. */
    display: none !important;
  }

  .herp-text {
    flex-flow: column;
    align-items: flex-start;
    gap: 2.5rem;
    margin-bottom: 2rem;
    padding-bottom: 0;
  }

  .flex-block-2,
  .flex-block-7 {
    width: 100%;
    padding-inline: 40px;
  }

  .flex-block-7 {
    align-items: flex-start;
    padding-bottom: 0;
  }

  /* Tamaños medidos directo de institute-of-health-test.webflow.shared
     (sirviéndolo por http, no file://) en este mismo ancho: h1≈50px,
     párrafo≈15px — bastante más chicos que lo que veníamos usando (que
     todavía conservaba proporciones de escritorio). --page-scale ya da
     1 en todo este rango de anchos, así que el vw de acá corre libre. */
  .heading-2 {
    font-size: clamp(2rem, 5.5vw, 2.5rem);
    line-height: 0.95;
    letter-spacing: 0;
  }

  .paragraph-2 {
    width: 100%;
    max-width: 600px;
    text-align: left;
    font-size: clamp(0.6rem, 1.5vw, 0.8rem);
    /* ver los quiebres siguientes para el resto de la rampa (más chica
       en cada uno, siguiendo los tamaños reales medidos en la
       referencia — acá la sección es una slide de 100svh sin scroll
       interno, así que no hay margen para agrandar tanto como ellos). */
  }

  /* Sección 2 — propuesta de valor */
  .container-7 {
    height: auto;
    padding-block: 60px 40px;
  }

  .container {
    padding-block: 32px 20px;
  }

  .flex-block-5 {
    flex-flow: column;
    align-items: flex-start;
  }

  .heading {
    font-size: clamp(2.25rem, calc(6vw / var(--page-scale)), 80px);
    line-height: 1.05;
    padding-right: 0;
  }

  .paragraph {
    position: relative;
    inset: auto;
    float: none;
    width: 100%;
    height: auto;
    padding: 32px 40px;
  }

  .section-5 .banana-header {
    padding: 60px 40px 40px;
  }

  .section-5 .banana-header-content {
    flex-flow: column;
    align-items: flex-start;
    gap: 1.5rem;
  }

  .section-5 .banana-title,
  .section-5 .banana-copy {
    width: 100%;
    max-width: 100%;
  }

  .container-4 {
    height: 700px;
    background-attachment: scroll;
    /* fallback iOS */
  }

  /* Sección 3 — La ciencia */
  .header-section-3 {
    padding: 60px 40px 40px;
  }

  .heading-5 {
    margin-bottom: 32px;
  }

  .div-block-2 {
    flex-flow: column;
    align-items: flex-start;
    gap: 1.5rem;
  }

  .title-section-3 {
    width: 100%;
    /* Recalibrado a los tamaños reales de un título de sección medidos
       en institute of health (--page-scale ya da 1 en este rango de
       anchos) — antes seguía usando escala de escritorio (techo 80px). */
    font-size: clamp(1.8rem, 5vw, 2.3rem);
    line-height: 1.05;
  }

  .text-section-3 {
    width: 100%;
    max-width: 100%;
  }

  /* Tech list — apilar verticalmente */
  .container-science {
    height: auto;
    padding-bottom: 80px;
  }

  .tech-list {
    flex-flow: column;
    min-height: auto;
    gap: 1.5rem;
    padding-block: 28px;
  }

  .div-block-29 {
    flex-flow: column;
    gap: 1.5rem;
    height: auto;
  }

  .item-content {
    width: 100%;
    padding-right: 0;
  }

  .heading-13,
  .paragraph-8 {
    width: 100%;
    max-width: 100%;
  }

  .box-imagen {
    margin-left: 0;
    height: auto;
  }

  /* Relación 4:3 (era height fijo en px, no seguía una proporción real
     al cambiar el ancho) — a pedido */
  .imagen-item-1,
  .imagen-item-2,
  .imagen-item-3,
  .imagen-item-4 {
    width: 100%;
    height: auto;
    aspect-ratio: 4 / 3;
  }

  /* Análisis cromático */
  .section-5 {
    height: auto;
    padding-block: 60px calc(22svh / var(--page-scale));
  }

  .container-9 {
    padding-top: 40px;
  }

  .heading-9 {
    width: 100%;
    max-width: 100%;
    font-size: clamp(2.25rem, calc(6vw / var(--page-scale)), 80px);
    line-height: 1.05;
  }

  .paragraph-5,
  .paragraph-4,
  .paragraph-6 {
    width: 100%;
    max-width: 600px;
  }

  /* Algoritmo */
  .section-4 {
    padding-block: 0 160px;
  }

  .heading-6 {
    font-size: clamp(2rem, calc(5vw / var(--page-scale)), 70px);
    line-height: 1.15;
  }

  .cms_carousel .wrapper_general {
    padding: 150px 40px 72px;
  }

  .carousel_h2 {
    font-size: clamp(2.25rem, calc(6vw / var(--page-scale)), 80px);
    line-height: 1.05;
  }

  .carousel_box {
    height: 540px;
  }

  .wrapper_carousel {
    padding: 36px 32px;
  }

  .description_carousel {
    font-size: 22px;
    font-weight: 400;
  }

  .title_carousel {
    font-size: 42px;
  }

  /* Sostenibilidad */
  .section-6 {
    height: auto;
    padding-block: 0 80px;
  }

  .container-11 {
    padding-top: 80px;
  }

  .heading-10 {
    font-size: clamp(2.25rem, calc(6vw / var(--page-scale)), 80px);
    line-height: 1.05;
  }

  /* Bloques de color del final */
  .section-7 {
    height: calc(40svh / var(--page-scale));
  }

  .section-8,
  .section-9 {
    height: calc(70svh / var(--page-scale));
  }

  .section-10 {
    height: calc(35svh / var(--page-scale));
  }

  .section-11 {
    height: calc(50svh / var(--page-scale));
  }
}

/* --------------------------------------------------------------------------
   3. Mobile — ≤ 767px
   -------------------------------------------------------------------------- */
@media (max-width: 767px) {

  /* Contenedores: márgenes más ajustados */
  .flex-block-2,
  .flex-block-7,
  .container-7,
  .container-8,
  .container-9,
  .container-11,
  .container-science,
  .header-section-3 {
    padding-inline: 20px;
  }

  /* Mismo leitmotiv que S2 (#bananaIntro .bi-title) — igual que se hizo
     con el título de S3.2 (.s32-title), a pedido. */
  .title-section-3 {
    font-size: clamp(1.944rem, calc(4.05vw / var(--page-scale)), 3.24rem);
  }

  .heading-13 {
    font-size: clamp(1.25rem, 4.5vw, 1.9rem);
  }

  .container {
    padding-inline: 20px;
  }

  .nav-menu-content {
    padding-inline: 16px;
  }

  /* Hero ajustes finos */
  .section {
    padding-top: 100px;
    /* Era 90dvh: el hero es una slide del fp-stage (initPresentation en
       main.js), que necesita que cada slide mida EXACTAMENTE el viewport
       real — con 90% quedaba 10% más corto, y el inicio de la sección
       siguiente (S2) asomaba en ese margen al pie del hero. */
    min-height: calc(100dvh / var(--page-scale));
  }

  .heading-2 {
    font-size: clamp(1.7rem, 7vw, 2.7rem);
    letter-spacing: 0;
    line-height: 0.95;
  }

  .paragraph-2 {
    font-size: clamp(0.55rem, 2.2vw, 0.85rem);
    line-height: 1.3;
  }

  .btn-cta-content,
  .arrow-ileft,
  .arrows-right {
    width: auto;
    min-width: 46px;
    height: 46px;
  }

  .btn-cta-content {
    width: 130px;
  }

  /* Sección 2 */
  .paragraph {
    padding: 24px 20px;
  }

  .section-5 .banana-header {
    padding: 48px 20px 28px;
  }

  .container-4 {
    height: 480px;
  }

  /* Sección 3 — header amarillo. padding-top subido (era 48px): el
     header fijo del sitio (~86.6px de alto) tapaba el eyebrow
     "PRECISIÓN EN CADA ETAPA" — a pedido. */
  .header-section-3 {
    padding-block: 100px 28px;
  }

  /* Mismo espacio que entre los textos de S3.2 (.s32-head, gap:2px) —
     a pedido. Era 1.5rem (24px), heredado de .div-block-2 en el
     breakpoint de 991px, luego bajado a 10px, ahora igualado del todo. */
  .div-block-2 {
    gap: 2px;
  }

  /* Ídem para el espacio entre el subtítulo/eyebrow (heading-5) y el
     título hero — era 32px (heredado de 991px). */
  .heading-5 {
    margin-bottom: 2px;
  }

  /* Tech items */
  .text-block-6 {
    width: 44px;
    height: 44px;
    font-size: 24px;
    line-height: 44px;
  }

  .div-block-31 {
    width: auto;
    height: auto;
  }


  /* Slider más compacto */
  .cms_carousel .wrapper_general {
    padding: 112px 20px 52px;
  }

  .cms-carousel-container {
    padding-inline: 20px;
    padding-bottom: 64px;
  }

  .carousel_box {
    height: 460px;
  }

  .wrapper_carousel {
    padding: 28px 24px;
  }

  .description_carousel {
    font-size: 22px;
    font-weight: 400;
    line-height: 1.25;
  }

  .title_carousel {
    font-size: 36px;
  }

  .splide__arrow {
    width: 48px;
    height: 48px;
    font-size: 28px;
  }

  /* Bloques de color del final */
  .section-7,
  .section-10 {
    height: calc(30svh / var(--page-scale));
  }

  .section-8,
  .section-9 {
    height: calc(60svh / var(--page-scale));
  }

  .section-11 {
    height: calc(45svh / var(--page-scale));
  }
}

/* --------------------------------------------------------------------------
   4. Small mobile — ≤ 480px
   -------------------------------------------------------------------------- */
@media (max-width: 480px) {

  .heading-2 {
    font-size: clamp(1.65rem, 10.2vw, 2.45rem);
  }

  .paragraph-2 {
    font-size: clamp(0.65rem, 4vw, 0.95rem);
    line-height: 1.28;
  }

  .heading,
  .heading-6,
  .heading-9,
  .heading-10,
  .title-section-3 {
    letter-spacing: 0;
  }

  /* Mismo leitmotiv que S2 (#bananaIntro .bi-title, que no se achica más
     en este breakpoint) — antes tenía su propio clamp más chico. */
  .title-section-3 {
    font-size: clamp(1.944rem, calc(4.05vw / var(--page-scale)), 3.24rem);
  }

  .carousel_h2 {
    letter-spacing: 0;
  }

  /* Ocultar la etiqueta "Menú" en pantallas pequeñas para ganar espacio */
  .menu-toggle-btn .text-block {
    display: none;
  }
}

/* --------------------------------------------------------------------------
   4b. Poca altura — el hero es una "slide" de la presentación por
   transform (initPresentation en main.js), que no permite scroll
   interno: si el contenido no entra en el alto real de la pantalla, la
   parte de abajo (CTA de video, "Scroll to Discover") queda
   inalcanzable. Se compacta en vez de solo achicar por ANCHO — dos
   niveles: uno moderado (celulares "cortos" en portrait, ej. iPhone
   SE/8 a 375×667) y uno agresivo (celulares en landscape, ej. 667×375).
   -------------------------------------------------------------------------- */
@media (max-height: 700px) {
  .section { padding-top: 72px; }
  .heading-2 { font-size: clamp(2rem, calc(13vw / var(--page-scale)), 5rem); }
  .paragraph-2 { font-size: 0.95rem; line-height: 1.25; }
  .herp-text { gap: 1rem; margin-bottom: 0.75rem; }
  .hero-container { padding-bottom: 8px; }
  .hero-info-btn { height: auto; padding: 10px 12px 8px; }
}
@media (max-height: 500px) {
  .section { padding-top: 24px; min-height: calc(100dvh / var(--page-scale)); }
  .heading-2 { font-size: clamp(1.3rem, calc(5svh / var(--page-scale)), 2.5rem); line-height: 1; }
  /* max-width acotado: en este modo el párrafo y "Scroll to Discover"
     (absoluto, abajo a la derecha) quedan a la misma altura — sin esto
     el texto corre por debajo del botón. */
  .paragraph-2 { font-size: 0.8rem; line-height: 1.2; max-width: 65%; }
  .herp-text { gap: 0.4rem; margin-bottom: 0.2rem; }
  .hero-video-cta { padding: 4px 10px; }
  .hero-video-cta__label { font-size: 13px; }
  /* .hero-info-btn ("Scroll to Discover") tenía height:90px fijo — el
     mayor bloque suelto en este modo compacto. */
  .hero-info-btn { height: auto; width: auto; max-width: 220px; padding: 4px 10px 3px; gap: 2px; }
  .hero-info-btn__label { font-size: 12px; }
  .hero-scroll-label { bottom: 2px; }
  .hero-container { padding-bottom: 0; }
}

/* --------------------------------------------------------------------------
   5. Touch devices — desactivar parallax fixed (no funciona en iOS Safari)
   -------------------------------------------------------------------------- */
@media (hover: none) and (pointer: coarse) {

  .hero-container,
  .container-4 {
    background-attachment: scroll;
  }
}

/* ============================================================
   NAVEGACIÓN / HAMBURGUESA  (reescrito sin Webflow IX2)
   ============================================================ */
.nav_btn_main {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 28px;
  cursor: pointer;
}

.nav_btn_line {
  position: absolute;
  left: 50%;
  width: 36px;
  height: 2px;
  background-color: currentColor;
  transform-origin: center;
  transition: transform .35s cubic-bezier(.77, 0, .175, 1),
    opacity .35s ease,
    background-color .35s cubic-bezier(.77, 0, .175, 1);
}

.nav_btn_line.is-top {
  transform: translate(-50%, -6px);
}

.nav_btn_line.is-middle {
  transform: translate(-50%, 0);
}

.nav_btn_line.is-bottom {
  transform: translate(-50%, 6px);
}

/* Estado abierto (click en el trigger) — la lista de links en línea se
   reemplazó por el panel (.site-sidebar); esto solo mueve la hamburguesa
   a una X. */
#navbar.is-open .nav_btn_line.is-top {
  transform: translate(-50%, 0) rotate(45deg) scale(.6, 1);
}

#navbar.is-open .nav_btn_line.is-bottom {
  transform: translate(-50%, 0) rotate(-45deg) scale(.6, 1);
}

#navbar.is-open .nav_btn_line.is-middle {
  opacity: 0;
  visibility: hidden;
}

/* ============================================================
   SIDEBAR DEL MENÚ (reemplaza el dropdown/expansión en línea de arriba)
   Estructura y estilo replicados de la referencia (Nabil Issa, ver
   sidebar-menu.png): overlay claro a pantalla completa, filas
   numeradas "Capítulo I..VI" + título grande delgado, separadas por
   líneas finas, y un bloque de footer con contacto/social/legal.
   El trigger (hamburguesa + "Menú"/"Cerrar") vive en el header, que
   tiene z-index más alto — por eso queda siempre visible por encima
   del panel abierto, sin duplicarlo acá dentro. Como el panel es claro,
   el header se fuerza a texto oscuro mientras está abierto (más abajo,
   `html.menu-frozen .section-header`) para que la hamburguesa/label
   nunca pierda contraste sea cual sea el tema de la sección de fondo.

   El panel NUNCA usa display:none — display:none rompe la transición
   (el navegador no anima desde un estado sin caja generada), que era
   justo el bug: el panel aparecía de golpe, sin movimiento. La
   visibilidad se maneja 100% con translate/scale + pointer-events/inert;
   initMenu() en main.js anima translate y scale por separado vía Web
   Animations API (element.animate()), cada uno con su propio easing —
   son propiedades CSS independientes entre sí (a diferencia del atajo
   `transform`), así que no compiten por una sola transition. ============================================================ */
.site-sidebar-wrap {
  position: fixed;
  inset: 0;
  /* height explícito (ver .site-sidebar más abajo para el porqué
     completo): sin esto, este wrap depende de cómo cada navegador resuelva
     el alto real de un position:fixed con inset:0 — en Chrome/Safari
     mobile eso puede no coincidir pixel a pixel con el alto explícito que
     usa .site-sidebar (el panel en sí), dejando un borde del fondo
     desenfocado (este wrap) asomando donde el panel ya terminó. Mismo
     valor que el panel para que ambos midan SIEMPRE exactamente lo mismo,
     sea cual sea el criterio de alto que el navegador use por defecto acá. */
  height: var(--sidebar-vh, 100lvh);
  z-index: 900; /* debajo del header (999), siempre visible por encima */
  pointer-events: none;
}
.site-sidebar-wrap.is-open { pointer-events: auto; }

.site-sidebar-blur {
  position: absolute;
  inset: 0;
  background: rgba(19, 19, 19, .55);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  opacity: 0;
  transition: opacity .5s ease;
  /* Fix parpadeo en iOS/Safari: sin esto, el navegador promueve/degrada
     esta capa a su propio compositing layer justo al togglear opacity
     (que es cuando entra/sale un backdrop-filter animado), y ese cambio
     de capa a mitad de la transición se ve como un destello del fondo.
     will-change + transform la deja SIEMPRE en su propia capa, promovida
     de antemano, así abrir/cerrar el panel no dispara esa repromoción. */
  will-change: opacity;
  transform: translateZ(0);
}
.site-sidebar-wrap.is-open .site-sidebar-blur { opacity: 1; }

.site-sidebar {
  position: absolute;
  top: 0;
  right: 0;
  /* Vuelve a cubrir el viewport completo (a pedido explícito, replicando
     además cantor8.io: su .mobile_menu mide 100dvh fijo, NO se ajusta a
     su contenido — ver REFERENCE CANTOR8/…). Antes se probó achicar el
     panel a la altura real del contenido (--sidebar-panel-h, medido con
     JS) para eliminar el aire de sobra entre secciones — pero esa causa
     ya se resolvió distinto (.site-sidebar__footer pasó de
     margin-top:auto a un margin-top fijo, ver ahí — el hueco grande e
     impredecible desapareció sin necesidad de achicar el panel entero).
     --sidebar-vh la fija JS con window.innerHeight (ver syncSidebarHeight
     en initMenu, main.js) — no una unidad CSS que el motor aproxima
     (svh/lvh se probaron antes y no bastaban: no garantizan estar
     sincronizadas con el estado real de la barra de Chrome en el
     instante exacto de abrir, más probable recién después de un scroll
     largo como recorrer #ciencia). 100lvh queda como último fallback,
     para el primer paint antes de que JS corra.
     SIN dividir por --page-scale (a diferencia de la mayoría de los vh/vw
     del sitio, ver la nota grande al inicio de initPageScale en main.js):
     esa división existe para compensar el doble-escalado de elementos que
     viven DENTRO de #scaleWrapper (que además aplica su propio
     transform:scale()) — el sidebar, como el header, queda EXPLÍCITAMENTE
     fuera de #scaleWrapper (pegado al viewport real, ver el comentario de
     initPageScale), así que no hay ningún transform de ancestro que
     compensar acá. El ANCHO sí multiplica por --page-scale (ver más
     abajo) — ahí es una elección de diseño directa (angostar el panel en
     laptops chicos), no una compensación de doble-escalado; no hay que
     igualar ambos criterios. */
  height: var(--sidebar-vh, 100lvh);
  /* El panel en sí es la "caja" — su ancho tiene que achicarse junto con
     el resto del sitio en laptops chicos (992-1920px), igual que su
     CONTENIDO (ver #sidebarScaleInner más abajo), si no la caja se ve
     de tamaño completo con el contenido flotando más chico adentro. */
  width: calc(640px * var(--page-scale));
  max-width: calc(92vw / var(--page-scale));
  background: #f2f1ee;
  color: var(--negro);
  /* NO overflow-y:auto acá — el scroll interno vive en #sidebarScaleInner
     (ver más abajo). Este mismo elemento es el que anima translate+scale
     vía WAAPI en cada apertura, y animar transform sobre un elemento que
     ADEMÁS es su propio scroll container (overflow:auto/scroll) es un bug
     conocido de Safari/iOS: repinta mal a mitad de la animación y el
     fondo del panel parpadea entre transparente y su color real. Mover el
     overflow a un hijo no animado (que no cambia de tamaño/posición)
     saca al panel de ese caso. */
  overflow: hidden;
  /* SIN transform-origin propio (el default de CSS, centro/50% 50%) —
     a propósito: replicando a fondo el código real de cantor8.io (ver
     REFERENCE CANTOR8/…) se confirmó que su .mobile_menu tampoco declara
     transform-origin — el "estiramiento desde el centro" que tenía este
     comentario antes (antes se ancló a "top right" para eliminarlo) es
     el mismo comportamiento que tiene la referencia real, no un defecto
     — para replicar la animación a precisión hay que dejarlo tal cual,
     sin anclarlo a ninguna esquina. */
  /* Estado cerrado de reposo — initMenu() anima `transform` desde/hacia
     este mismo valor vía WAAPI (antes translate+scale por separado, ver
     abajo); esta declaración es lo que se ve antes de que JS corra (o si
     JS falla) y a lo que vuelve tras cerrar. */
  transform: translate(100%, 0) scale(0.78);
  /* Promoción de capa DE ANTEMANO (evita que el navegador cree/destruya
     la capa compuesta justo al arrancar la animación, que es la otra
     mitad del parpadeo de fondo en WebKit/iOS — ver animatePanel() en
     main.js, que ahora anima este mismo `transform` clásico en vez de
     las propiedades `translate`/`scale` individuales). */
  will-change: transform;
  backface-visibility: hidden;
}

/* Contenido del panel — SOLO esto se escala (transform, vía CSS puro con
   --page-scale, sin JS). Ancho de diseño fijo = 640px, igual al de
   .site-sidebar sin escalar, para que ambos coincidan siempre.
   height:100% (.site-sidebar vuelve a medir el viewport completo, ver
   ahí) — este div se estira a llenarlo; lo que sobre entre el contenido
   y el borde inferior queda como aire del mismo fondo del panel
   (#f2f1ee), no como el fondo oscurecido detrás asomando. */
#sidebarScaleInner {
  width: 640px;
  height: 100%;
  box-sizing: border-box;
  transform: scale(var(--page-scale));
  transform-origin: top left;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  padding: 24px clamp(24px, calc(4vw / var(--page-scale)), 56px) 40px;
  /* Scroll interno del panel — ver .site-sidebar (overflow:hidden) para
     el porqué se movió acá: este wrapper no es el elemento que anima
     translate/scale por WAAPI, así que puede tener su propio scroll
     container sin heredar el bug de repintado de Safari/iOS. */
  overflow-y: auto;
}

/* Logo propio del panel, alineado en altura con la hamburguesa/"Cerrar"
   del header real (que sigue encima, con z-index más alto) — mismo
   tamaño y estructura (.logo-link/.symbol/.freshbox-typo) que el header,
   pero SIEMPRE en verde+negro (no seguía el tema light/solid del header,
   porque el panel en sí siempre es claro). */
.site-sidebar__brand {
  /* .logo-link trae justify-content:space-between (pensado para su fila
     completa en el header) — acá hay que anularlo, si no separa el
     símbolo y el wordmark a los extremos del panel entero. */
  justify-content: flex-start;
  gap: 10px;
  align-self: flex-start;
  flex: 0 0 auto;
  margin-top:10px;
  margin-bottom: 64px;
  text-decoration: none;
}
/* 30% más chico que el logo del header (.symbol 58px / .freshbox-typo 128px) */
.site-sidebar__brand .symbol { width: 41px; color: var(--verde-primario); }
.site-sidebar__brand .freshbox-typo { width: 90px; color: var(--negro); }

.site-sidebar__list {
  display: flex;
  flex-direction: column;
}

.site-sidebar__row {
  display: flex;
  align-items: center;
  gap: clamp(16px, calc(3vw / var(--page-scale)), 32px);
  padding: clamp(12px, calc(2.2vw / var(--page-scale)), 24px) 0;
  border-bottom: 1px solid rgba(19, 19, 19, .15);
  opacity: 0;
  transform: translateY(24px);
  transition: opacity .5s ease, transform .5s cubic-bezier(0.65, 0, 0.35, 1);
}
.site-sidebar-wrap.is-open .site-sidebar__row {
  opacity: 1;
  transform: translateY(0);
}
.site-sidebar__row:nth-child(1) { transition-delay: .05s; }
.site-sidebar__row:nth-child(2) { transition-delay: .1s; }
.site-sidebar__row:nth-child(3) { transition-delay: .15s; }
.site-sidebar__row:nth-child(4) { transition-delay: .2s; }
.site-sidebar__row:nth-child(5) { transition-delay: .25s; }
.site-sidebar__row:nth-child(6) { transition-delay: .3s; }

.site-sidebar__chapter {
  flex: 0 0 auto;
  width: 32px;
  font-family: var(--font-secundaria);
  font-size: 14px;
  font-weight: 400;
  letter-spacing: 0;
  color: var(--negro);
  opacity: .4;
}

/* Misma tipografía que .heading (el sistema de títulos del resto del
   sitio): Neue Montreal, peso 400, sin tracking extra — el sidebar
   debe verse como parte del mismo sistema, no con una voz aparte. */
.site-sidebar__item {
  font-family: var(--font-family--font-family);
  font-size: clamp(26px, calc(3.6vw / var(--page-scale)), 22px);
  font-weight: 400;
  line-height: 1.1;
  letter-spacing: 0;
  text-transform: uppercase;
  color: var(--negro);
  text-decoration: none;
  transition: color .3s ease;
}
.site-sidebar__item:hover { color: var(--verde-primario); }

.site-sidebar__footer {
  display: flex;
  flex-wrap: wrap;
  gap: 32px;
  /* BUG (reportado: "no quiero que aparezcan esos sobrantes blancos" — ver
     la captura de mitad de apertura, con un hueco grande y vacío entre
     "CONTACTO" y "Teléfono") — margin-top:auto empujaba el footer al
     fondo del panel usando TODO el espacio libre que sobrara entre la
     lista y él, que en el panel (100lvh/100% real) suele ser mucho más
     de lo que hace falta — un hueco que se lee como "de sobra", no como
     diseño. Reemplazado por un margin-top FIJO (antes era padding-top
     acá + margin-top:auto — dos declaraciones para lo mismo; ahora solo
     una): el footer queda a una distancia constante y predecible de la
     lista sea cual sea el alto del panel. Lo que sobre (si el panel es
     más alto que el contenido) queda como aire abajo del todo, después
     del copyright — un margen de cierre normal, no un hueco en medio del
     contenido. */
  margin-top: 40px;
}

.site-sidebar__footer-col {
  display: flex;
  flex-direction: column;
  min-width: 190px;
}

.site-sidebar__footer-label {
  margin: 16px 0 2px;
  font-family: var(--font-secundaria);
  font-size: 13px;
  font-weight: 400;
  color: var(--negro);
  opacity: .55;
}
.site-sidebar__footer-col > .site-sidebar__footer-label:first-child { margin-top: 0; }

.site-sidebar__footer-link,
.site-sidebar__footer-text {
  font-family: var(--font-family--font-family);
  font-size: 16px;
  font-weight: 500;
  color: var(--negro);
  text-decoration: none;
  line-height: 1.5;
}
.site-sidebar__footer-link:hover { color: var(--verde-primario); }
.site-sidebar__footer-note { font-weight: 400; opacity: .6; }

.site-sidebar__legal {
  padding-top: 20px;
  margin-top: 20px;
  border-top: 1px solid rgba(19, 19, 19, .15);
}
.site-sidebar__copy {
  font-family: var(--font-secundaria);
  font-size: 12px;
  color: var(--negro);
  opacity: .55;
}

/* El color del trigger (blanco → negro) y, en mobile, del header entero
   (ver @media abajo) ya NO se fuerza por CSS: lo anima animateHeaderColor()
   en initMenu() (main.js) vía Web Animations API, con la MISMA duración y
   easing que el translate del panel — así el texto se oscurece al mismo
   ritmo real en que el fondo blanco pasa por debajo, en vez de esperar a
   que termine toda la animación para recién ahí cambiar de golpe. Al
   cerrar, esa animación se cancela de entrada (no se anima "al revés"):
   el CSS is-light/is-solid de siempre retoma el control al instante,
   porque el color correcto al cerrar depende de qué sección hay detrás
   en ese momento, no de un blanco fijo.

   El logo real queda por encima del overlay con blur del sidebar (el
   header es position:fixed, que SIEMPRE forma su propio stacking
   context — un z-index en el logo no alcanza para bajarlo por debajo
   del overlay sin sacarlo de ese contexto). Como el panel ya trae su
   propio logo (ver .site-sidebar__brand), en desktop directamente se
   oculta el del header mientras el menú está abierto, en vez de dejarlo
   nítido flotando sobre el fondo desenfocado. En mobile NO se oculta:
   el panel no tiene logo propio ahí (ver @media abajo) y depende de este. */
@media (min-width: 992px) {
  html.menu-frozen #logo {
    opacity: 0;
    pointer-events: none;
    transition: opacity .3s ease;
  }
}

/* En mobile el logo del header NO se oculta (ver comentario arriba) —
   sigue siendo el único logo visible mientras el panel está abierto, así
   que tiene que verse en sus colores de marca (símbolo verde, texto
   negro — igual que .site-sidebar__brand en desktop), no heredando el
   color de tema (is-light/is-solid) de la sección que quedó detrás. El
   texto (.freshbox-typo) ya lo anima animateHeaderColor() en initMenu()
   (main.js) hacia negro; el símbolo no participaba de esa animación y
   quedaba siguiendo el tema (blanco/negro) en vez de su verde de marca. */
@media (max-width: 991px) {
  html.menu-frozen #logo .symbol {
    color: var(--verde-primario);
  }
}

/* En mobile, el contenido ya viaja resuelto dentro del panel (sin fade/
   stagger propio por fila) — el "golpe" de apertura se siente entero en
   el translate+scale del panel (ver initMenu en main.js), no en una
   coreografía de textos apareciendo por separado. */
@media (max-width: 991px) {
  .site-sidebar {
    width: 100%;
    max-width: calc(100vw / var(--page-scale));
    /* El panel es full-bleed en mobile: el header real (con su propio
       logo, ya forzado a oscuro más arriba) queda literalmente encima
       en el mismo punto, así que el logo propio del panel sobra acá
       (ver .site-sidebar__brand más abajo) — este padding-top vuelve a
       reservar el espacio para no tapar el header real. Se achicó junto
       con el logo del header (58px→35px, ver @media 991px más arriba):
       con el logo más chico el header ocupa menos alto, así que hace
       falta menos aire reservado antes del primer item. Bottom 32px→24px
       (ver el bloque de más abajo sobre el recorte de padding duplicado):
       ese último tramo de aire es el que decidía si el copyright entraba
       entero o quedaba con la última línea cortada por un puñado de px. */
    padding: 96px 24px 24px;
    /* Ya NO se pisa el transform de reposo acá (antes forzaba solo
       translate, sin scale, en mobile) — se restauró el scale también en
       mobile (ver animatePanel en initMenu, main.js) replicando a
       precisión la animación real de cantor8.io, así que hereda tal
       cual el transform base de .site-sidebar de más arriba
       (translate(100%,0) scale(0.78)), igual que en desktop. */
  }
  /* Duplicaría el logo del header real, que en mobile queda siempre
     visible por encima del panel (position:fixed, z-index más alto) y
     ya funciona como el logo del menú abierto — ver comentario arriba. */
  .site-sidebar__brand { display: none; }
  /* BUG (reportado: "el sidebar queda cortado, no se ve el copyright") —
     medido: en un viewport de 664px de alto, el contenido real (lista +
     footer + legal) necesita 685px, 149px de sobra. #sidebarScaleInner
     trae su PROPIO padding (24px arriba / 40px abajo, pensado para
     desktop, donde separa el contenido del borde del panel) que en
     mobile se suma al padding de .site-sidebar de arriba (96px/32px,
     reservado para no tapar el header real) — dos capas de aire
     apilándose sin necesidad, ya que en mobile no hay .site-sidebar__brand
     (oculto arriba) que ese padding interno tuviera que separar. Se
     recorta acá para reclamar ese espacio — el scroll interno propio
     (#sidebarScaleInner, overflow-y:auto) se queda como red de seguridad
     para pantallas más chicas o con más ítems en el futuro, pero ya no
     hace falta para el contenido actual en la mayoría de los celulares. */
  #sidebarScaleInner {
    padding-top: 0;
    padding-bottom: 12px;
  }
  /* Mismo ajuste, incluso después de lo anterior seguía sobrando ~97px en
     un iPhone 13 (664px de alto real): .footer tenía 40px de gap antes de
     la lista (ver margin-top más arriba, ya recortado a la mitad acá para
     mobile) y .legal duplicaba lo mismo (margin-top:20px + padding-top:20px,
     40px combinados solo para un separador de 1px). Se recorta a la mitad
     en mobile — el borde-top de cada uno sigue dando la separación
     visual, solo con menos aire de sobra alrededor. */
  .site-sidebar__footer { margin-top: 20px; }
  .site-sidebar__legal { margin-top: 12px; padding-top: 12px; }
  /* Último tramo: con todo lo anterior, en un iPhone 13 (664px reales)
     solo quedaban ~5px de la línea del copyright tapados por el borde
     del panel — la columna de contacto (3 labels: Teléfono/Mail/Sede)
     es la más alta del footer y decide su alto total. Un margin-top más
     chico entre cada label (16px→10px) cierra ese último resto. */
  .site-sidebar__footer-label { margin-top: 10px; }
  .site-sidebar__item { font-size: clamp(15px, calc(4.5vw / var(--page-scale)), 22px); }
  .site-sidebar__chapter { width: 28px; font-size: 13px; }
  .site-sidebar__footer { gap: 32px; }

  .site-sidebar__row {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* El panel en sí ya no tiene transition CSS (lo anima initMenu() vía WAAPI,
   que consulta este mismo media query en JS para acortar su duración) —
   acá solo quedan las piezas que sí siguen animando por CSS. */
@media (prefers-reduced-motion: reduce) {
  .site-sidebar-blur,
  .site-sidebar__row {
    transition-duration: .15s;
    transition-delay: 0s !important;
  }
  .site-sidebar__row { transform: none; }
}

/* ============================================================
   AJUSTES TIPOGRÁFICOS — refinamiento de marca
   1. Subtítulos h3 (Lucida) → letter-spacing 5px
   2. Texto Neue Montreal → letter-spacing 0
   3. Copys de descripción (Neue) unificados a la referencia S4
   4. heading-13 → line-height (evita solape de líneas)
   ============================================================ */

/* 1 · Subtítulos de sección h3 en Lucida → tracking 5px (go-eyebrow y bi-eyebrow ya lo tienen) */
.heading-5,
.carousel-eyebrow,
.s5-eyebrow {
  letter-spacing: 5px;
}

/* 2 · Todo el texto Neue Montreal sin tracking */
.heading-13,
.go-copy,
.s5-copy,
.base_txt,
.text-section-3,
.s6-micro,
#bananaIntro .bi-copy {
  letter-spacing: 0;
}

/* 3 · Copys de descripción (Neue) — mismo tamaño/peso/interlineado (ref. S4 .paragraph-8) */
.paragraph-8,
.go-copy,
.s5-copy,
.base_txt,
.text-section-3,
#bananaIntro .bi-copy {
  font-size: 18px;
  font-weight: 400;
  line-height: 1.5;
}

/* Descripción de S2 en mobile: -10% sobre el 18px de arriba (16.2px).
   Mismo leitmotiv aplicado a la descripción de #ciencia (.text-section-3)
   — a pedido, igual que se hizo con S3.2. */
@media (max-width: 767px) {
  #bananaIntro .bi-copy,
  .text-section-3 {
    font-size: 16.2px;
    line-height: 1.4;
  }
}

/* 4 · Solape de líneas en los títulos de los ítems de S4 */
.heading-13 {
  line-height: 1.15;
}

/* ============================================================
   BOTONES
   ============================================================ */

/* cubic-button-pro — animación recuperada de V2 (IX2 "in/out-btn-arrows").
   Reposo: flecha a la IZQUIERDA del texto.  Hover: la flecha "salta" a la
   DERECHA con deslizamiento vertical (la caja izq. colapsa, la der. crece). */
.btn-contact-hero {
  cursor: pointer;
}

.btn-contact-hero .content-arrow {
  width: 50px;
  height: 50px;
  transition: width 0.45s cubic-bezier(0.77, 0, 0.175, 1);
}

.btn-contact-hero .content-arrow:last-child {
  width: 0;
}

/* derecha oculta en reposo */
.btn-contact-hero:hover .content-arrow:first-child {
  width: 0;
}

/* izquierda colapsa al hover */
.btn-contact-hero:hover .content-arrow:last-child {
  width: 50px;
}

/* derecha aparece */

.arrow-ileft,
.arrows-right {
  transition: transform 0.3s ease;
}

.arrows-right {
  transform: translateY(-50px) rotate(180deg);
}

/* derecha arranca arriba, fuera de vista */
.btn-contact-hero:hover .arrow-ileft {
  transform: translateY(50px);
}

/* izquierda sale por abajo */
.btn-contact-hero:hover .arrows-right {
  transform: translateY(0) rotate(180deg);
}

/* derecha entra desde arriba */

/* Botón del hero — estilo referencia IOH (contenedor blur + opacidad) */
.hero-info-btn {
  display: inline-flex;
  flex-flow: column;
  align-items: flex-start;
  justify-content: space-between;
  gap: 6px;
  width: 280px;
  height: 90px;
  padding: 12px 12px 8px;
  color: var(--blanco);
  background-color: #f1f1f114;
  border: 1px solid #f1f1f10d;
  border-radius: 4px;
  -webkit-backdrop-filter: blur(20px);
  backdrop-filter: blur(20px);
  font-family: var(--font-family--principal-font), sans-serif;
  font-size: 16px;
  text-decoration: none;
  overflow: hidden;
  transition: background-color 0.3s ease, border-color 0.3s ease;
}

.hero-info-btn:hover {
  background-color: #f1f1f124;
  border-color: #f1f1f126;
}

.hero-info-btn__label {
  font-size: 16px;
  font-weight: 400;
  line-height: 1.2;
}

.hero-info-btn__icon {
  align-self: flex-end;
  line-height: 1;
  font-size: 1.1em;
  display: inline-block;
  transform: rotate(90deg);
}

/* Scroll to Discover — posición absoluta esquina inferior derecha */
.hero-scroll-label {
  position: absolute;
  bottom: 36px;
  right: 40px;
  z-index: 7;
}

/* Hero: CTA de video — estructura gemela a .s3v-cta / .s32-cta */
.hero-video-cta {
  display: inline-flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  width: 320px;
  max-width: 100%;
  padding: 12px 18px;
  background-color: rgba(0, 0, 0, 0.35);
  border: none;
  color: #fff;
  border-radius: 8px;
  text-decoration: none;
  cursor: pointer;
  -webkit-backdrop-filter: blur(20px);
  backdrop-filter: blur(20px);
  transition: background-color 0.3s ease;
}
.hero-video-cta:hover {
  background-color: rgba(0, 0, 0, 0.50);
}
.hero-video-cta__label {
  font-family: var(--font-secundaria);
  font-size: 16px;
  letter-spacing: 0.2px;
  line-height: 1.3;
  white-space: nowrap;
}
.hero-video-cta__play {
  display: flex;
  align-items: center;
  flex-shrink: 0;
  transition: transform 0.3s ease;
}
.hero-video-cta:hover .hero-video-cta__play { transform: scale(1.15); }

/* ============================================================
   HERO — bloque de texto abajo-izquierda (copy del wireframe Notion)
   Titular + subtítulo apilados a la izquierda; botón a la derecha.
   ============================================================ */
.flex-block-2 {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  text-align: left;
}

/* Ancho de columna del titular — SOLO desktop. Sin este min-width, esta
   regla (sin media query) le ganaba en el cascade a la de mobile de más
   arriba (@media max-width:991px .flex-block-2{width:100%}) por venir
   después en el archivo con la misma especificidad — dejaba el hero con
   una columna de 234px en un iPhone de 390px de ancho, forzando al
   párrafo a envolver en ~15 líneas y haciendo que la sección completa
   creciera muy por encima de 100svh (el CTA de video y "Scroll to
   Discover" quedaban fuera de la pantalla, sin forma de llegar a ellos
   porque la presentación de slides no permite scroll interno). */
/* .heading-2 y .paragraph-2 de acá abajo tenían el mismo problema que
   .flex-block-2 arriba: al no tener @media, le ganaban en el cascade a
   TODOS los tamaños de fuente responsive definidos más arriba en el
   archivo (los de @media max-width:1280/767/480px, y los de
   max-height:700/500px agregados para landscape) — quedaban muertos
   sin que se notara, porque esta regla los pisaba siempre por venir
   después con la misma especificidad. */
@media (min-width: 992px) {
  .flex-block-2 { width: 60%; }

  .heading-2 {
    font-size: clamp(2.25rem, calc(4.6vw / var(--page-scale)), 4rem);
    line-height: 1.05;
    font-weight: 500;
  }

  .paragraph-2 {
    width: auto;
    max-width: 600px;
    text-align: left;
    font-size: 1.15rem;
    line-height: 1.45;
  }
}

.flex-block-7 {
  width: auto;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-self: stretch;
  padding-right: 40px;
}

/* ============================================================
   S3 – SERVICIOS FRESHBOX
   Reemplaza section-cartera/carousel. Fondo blanco, header solid.
   ============================================================ */


.s3-servicios {
  position: relative;
  z-index: 5;
  background-color: #fff;
  padding: 0 0 80px;
}

/* Encabezado de sección */
.s3-hdr {
  max-width: 1360px;
  margin: 0 auto;
  padding: 120px 40px 80px;
  text-align: center;
}

.s3-eyebrow {
  display: inline-block;
  font-family: var(--font-family--principal-font);
  font-size: 13px;
  font-weight: 400;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--verde-primario);
  margin-bottom: 24px;
}

.s3-title {
  font-family: var(--font-family--font-family);
  font-size: clamp(52px, calc(7vw / var(--page-scale)), 96px);
  font-weight: 400;
  line-height: 0.92;
  color: var(--negro);
  text-transform: none;
  margin: 0 0 32px;
  letter-spacing: -0.01em;
}

.s3-title em {
  font-style: italic;
  color: var(--verde-primario);
}

.s3-lead {
  font-family: var(--font-family--principal-font);
  font-size: 18px;
  color: #666;
  max-width: 520px;
  margin: 0 auto;
  line-height: 1.6;
}

/* Grid de pilares */
.s3-pillars {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
  max-width: 1360px;
  margin: 0 auto;
  padding: 0 40px;
}

/* Tarjeta de pilar individual */
.s3-pillar {
  position: relative;
  border-radius: 16px;
  overflow: hidden;
  height: 560px;
  background: #0d0d0d;
}

.s3-pillar__img {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
  transition: transform 0.8s cubic-bezier(0.4, 0, 0.2, 1);
}

.s3-pillar:hover .s3-pillar__img {
  transform: scale(1.06);
}

.s3-pillar__overlay {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to top,
    rgba(0, 0, 0, 0.93) 35%,
    rgba(0, 0, 0, 0.4) 65%,
    rgba(0, 0, 0, 0.15) 100%
  );
  z-index: 1;
}

.s3-pillar__overlay--cold {
  background: linear-gradient(
    to top,
    rgba(8, 18, 48, 0.95) 35%,
    rgba(8, 18, 48, 0.45) 65%,
    rgba(8, 18, 48, 0.15) 100%
  );
}

.s3-pillar__body {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: 24px;
}

.s3-pillar__top {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
}

.s3-pillar__num {
  font-family: var(--font-family--principal-font);
  font-size: 13px;
  font-weight: 400;
  color: rgba(255, 255, 255, 0.35);
  letter-spacing: 0.08em;
}

.s3-pillar__temp {
  font-family: var(--font-family--principal-font);
  font-size: 11px;
  font-weight: 400;
  color: rgba(255, 255, 255, 0.75);
  background: rgba(255, 255, 255, 0.1);
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: 40px;
  padding: 4px 12px;
  letter-spacing: 0.04em;
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
}

.s3-pillar__main {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.s3-pillar__name {
  font-family: var(--font-family--font-family);
  font-size: clamp(26px, calc(2.2vw / var(--page-scale)), 34px);
  font-weight: 400;
  color: #fff;
  margin: 0;
  line-height: 1.1;
  text-transform: none;
  letter-spacing: -0.01em;
}

.s3-pillar__desc {
  font-family: var(--font-family--principal-font);
  font-size: 13.5px;
  color: rgba(255, 255, 255, 0.6);
  margin: 0;
  line-height: 1.6;
}

.s3-pillar__fruits {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.s3-pfruit {
  font-family: var(--font-family--principal-font);
  font-size: 12px;
  color: rgba(255, 255, 255, 0.8);
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 40px;
  padding: 3px 11px;
  white-space: nowrap;
}

.s3-pfruit--more {
  color: rgba(255, 255, 255, 0.4);
  border-color: rgba(255, 255, 255, 0.08);
}

.s3-pillar__cta {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-family--principal-font);
  font-size: 13px;
  font-weight: 500;
  color: #fff;
  text-decoration: none;
  border: 1px solid rgba(255, 255, 255, 0.3);
  border-radius: 40px;
  padding: 9px 20px;
  align-self: flex-start;
  transition: background 0.25s ease, border-color 0.25s ease;
  letter-spacing: 0.02em;
}

.s3-pillar__cta::after {
  content: "→";
  display: inline-block;
  transition: transform 0.2s ease;
}

.s3-pillar__cta:hover {
  background: rgba(255, 255, 255, 0.12);
  border-color: rgba(255, 255, 255, 0.55);
}

.s3-pillar:hover .s3-pillar__cta::after {
  transform: translateX(4px);
}

/* Portfolio de frutas */
.s3-portfolio {
  max-width: 1360px;
  margin: 0 auto;
  padding: 56px 40px 0;
}

.s3-portfolio__hdr {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
  padding-bottom: 16px;
  border-bottom: 1px solid #e4e4e4;
}

.s3-portfolio__label {
  font-family: var(--font-family--principal-font);
  font-size: 12px;
  font-weight: 400;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: #999;
}

.s3-portfolio__hint {
  font-family: var(--font-family--principal-font);
  font-size: 12px;
  color: #bbb;
}

.s3-fruits-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

/* Chip de fruta */
.s3-fi {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  font-family: var(--font-family--principal-font);
  border: 1px solid #e0e0e0;
  border-radius: 40px;
  padding: 7px 18px 8px;
  cursor: default;
  background: #fff;
  transition:
    background 0.22s ease,
    border-color 0.22s ease,
    transform 0.18s ease,
    box-shadow 0.22s ease;
  user-select: none;
}

.s3-fi__n {
  font-size: 14px;
  color: #333;
  transition: color 0.22s ease;
  line-height: 1.2;
}

.s3-fi__s {
  font-size: 10px;
  color: transparent;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  line-height: 1;
  max-height: 0;
  overflow: hidden;
  transition:
    color 0.22s ease,
    max-height 0.22s ease;
}

/* Hover: Maduración controlada → verde primario */
.s3-fi.is-mad:hover {
  background: var(--verde-primario);
  border-color: var(--verde-primario);
  transform: translateY(-2px);
  box-shadow: 0 6px 16px rgba(62, 115, 25, 0.25);
}
.s3-fi.is-mad:hover .s3-fi__n { color: #fff; }
.s3-fi.is-mad:hover .s3-fi__s { color: rgba(255,255,255,0.75); max-height: 16px; }

/* Hover: Almacenamiento frescos → verde azulado */
.s3-fi.is-fre:hover {
  background: #1a6b5a;
  border-color: #1a6b5a;
  transform: translateY(-2px);
  box-shadow: 0 6px 16px rgba(26, 107, 90, 0.25);
}
.s3-fi.is-fre:hover .s3-fi__n { color: #fff; }
.s3-fi.is-fre:hover .s3-fi__s { color: rgba(255,255,255,0.75); max-height: 16px; }

/* Hover: Almacenamiento congelados → azul profundo */
.s3-fi.is-con:hover {
  background: #1a3d6b;
  border-color: #1a3d6b;
  transform: translateY(-2px);
  box-shadow: 0 6px 16px rgba(26, 61, 107, 0.25);
}
.s3-fi.is-con:hover .s3-fi__n { color: #fff; }
.s3-fi.is-con:hover .s3-fi__s { color: rgba(255,255,255,0.75); max-height: 16px; }

/* Responsive pilares */
@media (max-width: 991px) {
  .s3-pillars {
    grid-template-columns: 1fr;
    gap: 12px;
    padding: 0 24px;
  }
  .s3-pillar {
    height: 440px;
  }
  .s3-hdr {
    padding: 80px 24px 60px;
  }
  .s3-portfolio {
    padding: 48px 24px 0;
  }
}

@media (max-width: 767px) {
  .s3-hdr {
    padding: 60px 20px 48px;
  }
  .s3-pillars {
    padding: 0 16px;
  }
  .s3-pillar {
    height: 400px;
    border-radius: 12px;
  }
  .s3-pillar__body {
    padding: 20px;
  }
  .s3-portfolio {
    padding: 40px 16px 0;
  }
  .s3-portfolio__hint {
    display: none;
  }
}

/* ============================================================
   S3 · CADA FRUTA, UN RITMO — foto full-bleed en crossfade con viñeta.
   Título hero (eyebrow + nombre + subtítulo) debajo del logo del
   header. Flechas abajo a la izquierda; descripción + CTA abajo a la
   derecha (sin tarjeta, directo sobre la foto). Barra de progreso a
   todo el ancho, pegada al borde inferior de la sección, sin
   contenedor propio.
   ============================================================ */
.s3v {
  --s3v-dur: 4.5s;
  position: relative;
  height: calc(100dvh / var(--page-scale));
  overflow: hidden;
  z-index: 5;
  background-color: #131313;
}

/* Fondo full-bleed. */
.s3v-bg {
  position: absolute;
  inset: 0;
  z-index: 0;
  transform-origin: center center;
}
.s3v-slide {
  position: absolute;
  inset: 0;
  opacity: 0;
  z-index: 0;
  background-size: cover;
  background-position: center;
  transform: scale(1);
  transform-origin: center center;
}
.s3v-slide.is-active { opacity: 1; z-index: 1; }
/* Crossfade real: la entrante sube de opacity 0→1 (z-index propio puesto
   por JS, gana por encima de la saliente sin importar el orden en el
   DOM — ver paint() en main.js) mientras la saliente hace un zoom+blur
   leve por debajo (mismo rAF/easing de siempre). */
.s3v-slide { transition: opacity 0.45s ease; }
.s3v.is-live .s3v-slide.is-active {
  animation: s3vKenburns var(--s3v-dur) ease-out forwards;
}
@keyframes s3vKenburns {
  from { transform: scale(1); }
  to { transform: scale(1.065); }
}

@media (prefers-reduced-motion: reduce) {
  .s3v-slide { transition: opacity 0.2s ease; }
  .s3v.is-live .s3v-slide.is-active { animation: none; }
}

/* Mobile: mismo tratamiento que los clips de video de S2 — el fondo
   (acá fotos, no <video>) se encoge para no recortar la fruta y se
   desplaza hacia arriba. background-size:contain es el equivalente de
   object-fit:contain para un elemento con background-image en vez de
   <video>/<img>. La animación Ken Burns (scale 1→1.065) se reescala
   dentro de este mismo factor en vez de perderse. */
@media (max-width: 767px) {
  .s3v-slide {
    background-size: contain;
    background-repeat: no-repeat;
    /* 50% = centro exacto. 15% más arriba desde 35% → 27.5%
       (50 * 0.15 = 7.5pp de desplazamiento). */
    background-position: center 27.5%;
    /* -20% sobre el resultado anterior (1.60446 * 0.8 = 1.283568) */
    transform: scale(1.283568);
  }
  .s3v.is-live .s3v-slide.is-active {
    animation-name: s3vKenburnsMobile;
  }
  @keyframes s3vKenburnsMobile {
    from { transform: scale(1.283568); }
    to { transform: scale(1.36696); }
  }

  /* Viñeta radial (mismo cálculo que .bi-video en S2): centro 100% opaco
     donde está la fruta, desvanece a transparente hacia los bordes del
     cuadro — funde el rectángulo de la foto con el fondo oscuro de la
     sección en vez de cortar en seco. Va en CADA .s3v-slide, no en
     .s3v-bg: .s3v-overlay (la viñeta oscura que le da contraste al
     texto) vive dentro de .s3v-bg — enmascarar ese contenedor completo
     también desvanecería el overlay justo en los bordes, que es donde
     más falta hace para el contraste. */
  .s3v-slide {
    -webkit-mask-image: radial-gradient(
      ellipse 68% 62% at 50% 27.5%,
      black 50%,
      black 72%,
      transparent 100%
    );
    mask-image: radial-gradient(
      ellipse 68% 62% at 50% 27.5%,
      black 50%,
      black 72%,
      transparent 100%
    );
  }
  /* El letterbox detrás de la fruta (donde background-size:contain no
     llena el cuadro) debe verse igual que en S2: blanco, no el negro de
     la sección — a pedido explícito, aunque el resto de S3 (texto,
     viñeta) se queda oscuro como siempre. */
  .s3v-bg {
    background-color: var(--blanco);
  }
  /* Velo de transparente a sólido en el último tramo inferior, mismo
     blanco que S2 — robusto sin importar dónde caiga exactamente el
     borde real de cada foto. */
  .s3v-bg::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 24%;
    background: linear-gradient(to bottom, transparent 0%, var(--blanco) 88%);
    z-index: 2;
    pointer-events: none;
  }
}

/* Viñeta: arriba/abajo + ambos costados — el título hero (arriba-izq),
   la tarjeta (abajo-izq), las flechas (abajo-der) y la barra de
   progreso (borde inferior) vuelven a vivir directo sobre la foto, sin
   fondo propio que garantice contraste por sí solo. */
.s3v-overlay {
  position: absolute;
  inset: 0;
  z-index: 3;
  background:
    linear-gradient(
      to bottom,
      rgba(0, 0, 0, 0.12) 0%,
      rgba(0, 0, 0, 0) 30%,
      rgba(0, 0, 0, 0) 70%,
      rgba(0, 0, 0, 0.22) 100%
    ),
    linear-gradient(
      to right,
      rgba(0, 0, 0, 0.48) 0%,
      rgba(0, 0, 0, 0.2) 22%,
      rgba(0, 0, 0, 0) 46%
    ),
    linear-gradient(
      to left,
      rgba(0, 0, 0, 0.48) 0%,
      rgba(0, 0, 0, 0.2) 22%,
      rgba(0, 0, 0, 0) 46%
    );
}

/* Mobile: costados menos pronunciados (abren el centro, antes tapaban
   casi hasta la mitad en pantallas angostas) + degradado inferior propio
   y más fuerte — de gris oscuro (abajo) a transparente (arriba), fondo
   de contraste dedicado para el bloque de texto que ahora vive ahí. */
@media (max-width: 767px) {
  .s3v-overlay {
    background:
      linear-gradient(
        to top,
        rgba(19, 19, 19, 0.85) 0%,
        rgba(19, 19, 19, 0.55) 35%,
        rgba(19, 19, 19, 0) 70%
      ),
      linear-gradient(
        to right,
        rgba(0, 0, 0, 0.16) 0%,
        rgba(0, 0, 0, 0) 14%
      ),
      linear-gradient(
        to left,
        rgba(0, 0, 0, 0.16) 0%,
        rgba(0, 0, 0, 0) 14%
      );
  }
}

.s3v.is-ready .s3v-bg {
  opacity: 0;
  filter: blur(20px);
  transform: scale(1.06);
  transition:
    opacity 1.15s ease,
    filter 1.2s ease,
    transform 1.35s cubic-bezier(0.22, 1, 0.36, 1);
}
.s3v.is-ready .s3v-overlay {
  opacity: 0;
  transition: opacity 0.9s ease;
}
.s3v.is-ready .s3v-head,
.s3v.is-ready .s3v-foot,
.s3v.is-ready .s3v-progress {
  opacity: 0;
  filter: blur(14px);
  transform: translateY(24px);
  transition:
    opacity 0.95s ease,
    filter 0.95s ease,
    transform 0.95s cubic-bezier(0.22, 1, 0.36, 1);
}
.s3v.is-ready .s3v-foot {
  transform: translateY(30px);
}
.s3v.is-ready .s3v-progress {
  transform: translateY(12px);
}
/* .s3v-head parte de translateY(-50%) (centrado vertical) — el offset de
   entrada se suma a eso, no lo reemplaza. */
.s3v.is-ready .s3v-head {
  transform: translateY(calc(-50% + 24px));
}
.s3v.is-ready.is-inview .s3v-bg {
  opacity: 1;
  filter: blur(0);
  transform: scale(1);
  transition-delay: 0.5s;
}
.s3v.is-ready.is-inview .s3v-overlay {
  opacity: 1;
  transition-delay: 0.78s;
}
.s3v.is-ready.is-inview .s3v-head,
.s3v.is-ready.is-inview .s3v-foot,
.s3v.is-ready.is-inview .s3v-progress {
  opacity: 1;
  filter: blur(0);
  transform: translateY(0);
}
.s3v.is-ready.is-inview .s3v-head {
  transform: translateY(-50%);
  transition-delay: 1.02s;
}
.s3v.is-ready.is-inview .s3v-foot { transition-delay: 1.2s; }
.s3v.is-ready.is-inview .s3v-progress { transition-delay: 1.4s; }

/* Título hero: eyebrow + nombre de fruta + subtítulo, todo junto —
   contenedor independiente de .s3v-nav, centrado verticalmente en la
   sección. */
.s3v-head {
  position: absolute;
  z-index: 4;
  top: 50%;
  left: 40px;
  transform: translateY(-50%);
  width: min(520px, calc(calc(100vw / var(--page-scale)) - 80px));
  display: flex;
  flex-direction: column;
  gap: 18px;
}

/* Esquina inferior derecha: descripción + CTA, sin tarjeta — directo
   sobre la foto, con la viñeta (.s3v-overlay) dando el contraste. */
.s3v-foot {
  position: absolute;
  z-index: 4;
  right: 40px;
  bottom: 100px;
  max-width: 350px;
  display: flex;
  flex-direction: column;
  gap: 26px;
}

/* Título propio (ya no el kicker uppercase) — mismo tamaño que tenía
   antes, conservando el color amarillo. */
.s3v-eyebrow {
  font-family: var(--_typography---lucida-grande);
  font-size: 1rem;
  font-weight: 400;
  letter-spacing: 5px;
  text-transform: uppercase;
  color: var(--amarillo-banana);
  margin: 0;
}

/* ============================================================
   EYEBROWS / KICKERS — el pequeño label en mayúsculas que precede al
   título grande de cada sección ("Expertos en mantención de:",
   "Expertos en maduración de:", "PRECISIÓN EN CADA ETAPA", "El
   propósito", "Maduración controlada"). Todos miden 1rem (20px) en
   escritorio; a pedido explícito, en smartphone (≤767px) TODOS bajan
   al mismo tamaño: 14px, sin excepción entre secciones.
   ============================================================ */
@media (max-width: 767px) {
  .s32-eyebrow,
  .s3v-eyebrow,
  .s5-eyebrow,
  #bananaIntro .bi-eyebrow,
  .heading-5,
  .s6b-marcas__kicker {
    font-size: 0.7rem;
  }
}

/* Ahora el H1 real de la sección: el nombre de la fruta activa (antes era
   el texto intro estático, y antes de eso el kicker leitmotiv de S2 — ese
   rol de "intro" quedó absorbido por el nombre de fruta, que pasa a ser
   el elemento más prominente). */
.s3v-title {
  font-family: var(--font-family--font-family);
  font-size: clamp(2.4rem, calc(5vw / var(--page-scale)), 4rem);
  font-weight: 400;
  line-height: 0.95;
  letter-spacing: -0.015em;
  color: #fff;
  margin: 0;
}
.s3v-title em { font-style: normal; }
/* Nombre de fruta más chico en mobile — mismo criterio que el hero:
   --page-scale ya da 1 en este rango de anchos, así que se recalibra a
   los tamaños reales de un título de sección medidos en institute of
   health, no a los de escritorio. */
@media (max-width: 991px) {
  .s3v-title { font-size: clamp(1.8rem, 5vw, 2.3rem); }
}
@media (max-width: 767px) {
  /* Mismo tamaño que el título de S2 (#bananaIntro .bi-title) en mobile */
  .s3v-title { font-size: clamp(1.944rem, calc(4.05vw / var(--page-scale)), 3.24rem); }
}
@media (max-width: 479px) {
  .s3v-title { font-size: clamp(1.5rem, 9vw, 2.2rem); }
}

.s3v-copy__title {
  font-family: var(--font-family--font-family);
  font-size: clamp(26px, calc(3vw / var(--page-scale)), 42px);
  font-weight: 400;
  line-height: 1.05;
  letter-spacing: -0.015em;
  color: #fff;
  margin: 0;
  text-wrap: balance;
}
.s3v-copy__desc {
  font-family: var(--font-family--principal-font);
  font-size: 21px;
  font-weight: 400;
  line-height: 1.2;
  color: rgba(255, 255, 255, 0.82);
  margin: 0;
}

/* Mismo tamaño que la descripción de S2 (#bananaIntro .bi-copy) en mobile */
@media (max-width: 767px) {
  .s3v-copy__desc {
    font-size: 16.2px;
  }
}


/* CTA claro, directo sobre la foto (ancho máximo 340px). */
.s3v-cta {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  width: 100%;
  max-width: 340px;
  min-height: 61px;
  padding: 11px 18px;
  background: #fff;
  color: var(--negro);
  border-radius: 8px;
  text-decoration: none;
  transition: background 0.3s ease, transform 0.3s ease;
}
.s3v-cta:hover { background: var(--amarillo-acentos); }
.s3v-cta__label {
  font-family: var(--font-secundaria);
  font-size: 0.95rem;
  letter-spacing: 0.2px;
}
.s3v-cta__arrow {
  align-self: flex-end;
  font-size: 1.15rem;
  line-height: 1;
}
.s3v-cta:hover .s3v-cta__arrow { transform: translate(3px, -3px); }

/* Flechas: contenedor independiente de .s3v-head (hermano dentro de
   .s3v, no descendiente) — así uno se puede mover sin arrastrar al
   otro. Ancladas justo encima del contador (.s3v-progress), a la misma
   altura que el CTA de la derecha (.s3v-foot, bottom: 100px). */
.s3v-nav {
  position: absolute;
  z-index: 4;
  left: 40px;
  bottom: 100px;
  display: flex;
  align-items: center;
  gap: 6px;
}
/* Fondo oscuro translúcido (no blanco): los deslizadores viven directo
   sobre la foto — sin esto, sobre zonas claras de la imagen (blancos de
   estudio) quedaban prácticamente invisibles. */
.s3v-tabs__arrow {
  width: 80px;
  height: 80px;
  border: none;
  border-radius: 50%;
  background: rgba(19, 19, 19, 0.119);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  color: #fff;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: background 0.2s ease;
}
.s3v-tabs__arrow svg {
  width: 28px;
  height: 28px;
}
.s3v-tabs__arrow:hover { background: rgba(19, 19, 19, 0.65); }
.s3v-tabs__arrow svg { display: block; }
.s3v-tabs__playpause svg[hidden] { display: none; }

/* Contador + barra de progreso lineal: timer visual del autoplay. Sin
   contenedor propio (la viñeta ya se encarga del contraste) — a todo
   el ancho, pegada al borde inferior de la sección. */
.s3v-progress {
  position: absolute;
  z-index: 4;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 0 40px 14px;
}
.s3v-progress__count {
  font-family: var(--font-secundaria);
  font-size: 13px;
  letter-spacing: 1px;
  color: rgba(218, 218, 218, 0.9);
  white-space: nowrap;
}
.s3v-progress__track {
  position: relative;
  flex: 1 1 auto;
  height: 2px;
  border-radius: 2px;
  background: rgb(136, 136, 136);
  overflow: hidden;
}
.s3v-progress__bar {
  position: absolute;
  inset: 0;
  background: rgb(255, 255, 255);
  transform-origin: left center;
  transform: scaleX(0);
  will-change: transform;
}
/* Igual patrón que usaba el fill de thumbnails: animación CSS atada a
   --s3v-dur, reiniciada en JS (restartProgress) apagando/prendiendo
   style.animation en vez de tocar clases. */
.s3v.is-live .s3v-progress__bar {
  animation: s3vProgress var(--s3v-dur) linear forwards;
}
.s3v.is-paused .s3v-progress__bar,
.s3v.is-offscreen .s3v-progress__bar {
  animation-play-state: paused;
}
@keyframes s3vProgress {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}

/* swap con blur+zoom — arranca cuando el fondo YA terminó de crecer (ver
   JS), no a la mitad; duración acorde al ritmo medido del video. El
   transform:scale acompaña al mismo zoom que hace el fondo saliente (ver
   paint() en main.js) — en el video de referencia, el bloque de texto
   entero "retrocede" junto con la foto, no se queda quieto mientras solo
   se desenfoca. El eyebrow ("Cartera de maduración") queda afuera: es
   fijo, no cambia entre frutas, así que se queda quieto en vez de
   animar en cada swap. */
.s3v-title,
.s3v-copy__desc {
  transition: filter 0.3s ease, opacity 0.3s ease, transform 0.3s ease;
}
.s3v.is-swapping .s3v-title,
.s3v.is-swapping .s3v-copy__desc {
  filter: blur(8px);
  opacity: 0;
  transform: scale(1.06);
}

/* Subtítulo por fruta: cada línea (<br> en el dato, ver JS) revela por
   separado, no las dos juntas — visto en el video de referencia
   ("NAGANO" aparece, ~120ms después "PREFECTURE"). */
.s3v-copy__title-line {
  display: block;
  transition: filter 0.3s ease, opacity 0.3s ease, transform 0.3s ease;
}
.s3v-copy__title-line:nth-child(2) {
  transition-delay: 0.12s;
}
/* Mobile: el corte de línea forzado (display:block) se ve como un salto
   raro en el ancho angosto del bloque de texto agrupado — que fluya
   natural como texto normal. El espacio entre líneas ahora es un
   carácter de texto real entre los <span> (ver el HTML y el join(" ")
   en main.js) — así el navegador lo colapsa solo si el salto de línea
   cae justo ahí, en vez de quedar como sangría (lo que pasaba con un
   margin-left). inline-block (no "inline" puro) sigue haciendo falta
   porque sí soporta el transform del efecto de swap entre frutas. */
@media (max-width: 767px) {
  .s3v-copy__title-line {
    display: inline-block;
  }
}
.s3v.is-swapping .s3v-copy__title-line {
  filter: blur(8px);
  opacity: 0;
  transform: scale(1.06);
  transition-delay: 0s; /* ocultar ambas líneas al instante — el escalonado es solo al revelar */
}

@media (prefers-reduced-motion: reduce) {
  .s3v.is-ready .s3v-bg,
  .s3v.is-ready .s3v-overlay,
  .s3v.is-ready .s3v-head,
  .s3v.is-ready .s3v-foot,
  .s3v.is-ready .s3v-progress {
    opacity: 1;
    filter: none;
    transform: none;
    transition: none;
  }
  .s3v-title,
  .s3v-copy__desc,
  .s3v-copy__title-line {
    transition: opacity 0.2s ease;
    transition-delay: 0s !important;
  }
  .s3v.is-swapping .s3v-title,
  .s3v.is-swapping .s3v-copy__desc,
  .s3v.is-swapping .s3v-copy__title-line {
    filter: none;
    transform: none;
  }
}

/* Entrada (GSAP fija opacity:1; fallback visible si no hay JS) */
.s3v-head, .s3v-foot, .s3v-nav, .s3v-progress { opacity: 1; }

/* ---- Responsive ---- */
/* Mismo criterio que S2 (#bananaIntro): en mobile el título y la
   descripción+CTA se agrupan en un solo bloque flex pegado al bottom, en
   vez de vivir cada uno en su propia esquina (título arriba-izq fijo,
   pie abajo-der) como en desktop — el orden visual queda foto > texto >
   flechas > barra de progreso. .s3v-head/.s3v-foot pasan a position:static
   para apilarse dentro de .s3v-text-group (ver el wrapper nuevo en el
   HTML); en desktop, sin este @media, siguen con su position:absolute de
   siempre — el wrapper (static, sin containing block propio) no les
   afecta ahí. */
@media (max-width: 991px) {
  .s3v-text-group {
    position: absolute;
    z-index: 4;
    left: 20px;
    right: 20px;
    bottom: 100px;
    display: flex;
    flex-direction: column;
    gap: 8px;
  }
  .s3v-head {
    position: static;
    top: auto;
    left: auto;
    width: auto;
    transform: none;
  }
  .s3v.is-ready .s3v-head { transform: translateY(24px); }
  .s3v.is-ready.is-inview .s3v-head { transform: translateY(0); }

  .s3v-foot {
    position: static;
    left: auto;
    right: auto;
    bottom: auto;
    max-width: none;
  }

  /* Flechas: mismo tratamiento que .bi-nav en S2 — 50% más chicas,
     ancladas abajo a la izquierda, encima de la barra de progreso. */
  .s3v-nav { position: absolute; left: 20px; bottom: 34px; top: auto; }
  .s3v-tabs__arrow { width: 40px; height: 40px; }

  /* CTA: vuelve al flujo normal del bloque de texto, debajo de la
     descripción (dentro de .s3v-foot, que sigue en flex-column con
     gap:26px) y antes de las flechas/progreso — como estaba antes de
     las pruebas de achicarlo/moverlo junto a las flechas. -30% sobre el
     tamaño anterior (400px/68px), para que quede igual de chico que el
     de S3.3 (.s32-cta, mismo recorte). */
  .s3v-cta {
    max-width: 280px;
    min-height: 48px;
    padding: 9px 14px;
  }
  .s3v-cta .s3v-cta__label {
    font-size: 0.735rem;
  }
  .s3v-cta .s3v-cta__arrow {
    font-size: 0.875rem;
  }

  .s3v-progress { padding: 0 20px 10px; }
}

@media (max-width: 600px) {
  .s3v-text-group { left: 16px; right: 16px; }
  .s3v-nav { left: 16px; }
  .s3v-progress { padding: 0 16px 8px; }
  .s3v-progress__count { font-size: 11px; }
}
