/* ============================================================
   FIDELY · Landing
   Implementación del diseño de Illustrator (Fidely_LandingPage).
   Orden: base → utilidades → secciones en el orden de la página.
   ============================================================ */

/* ── Base ── */
*, *::before, *::after { box-sizing: border-box; }

/* clip y no hidden: recorta el desborde horizontal de las decoraciones
   (blobs, panel sangrado) sin romper position: sticky en el nav. */
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; overflow-x: clip; }

body {
  margin: 0;
  font-family: var(--font);
  font-weight: 400;
  font-size: var(--t-body);
  line-height: 1.55;
  color: var(--texto);
  background: var(--blanco);
  overflow-x: clip;
}

img, svg { max-width: 100%; height: auto; display: block; }
h1, h2, h3 {
  margin: 0; line-height: 1.06; letter-spacing: -.02em; font-weight: 700;
  /* Red de seguridad en pantallas mínimas: si una palabra larga no cabe
     ("Personalizables" a 320 px), se parte antes de desbordar. */
  overflow-wrap: anywhere; min-width: 0;
}
p { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }
a { color: inherit; text-decoration: none; }

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

.salta-al-contenido {
  position: absolute; left: 1rem; top: -100px; z-index: 200;
  background: var(--verde); color: var(--crema);
  padding: .7rem 1.1rem; border-radius: 0 0 12px 12px; font-weight: 600;
}
.salta-al-contenido:focus { top: 0; }

.contenedor {
  width: 100%;
  max-width: var(--ancho);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* ── Botones ── */
.btn {
  --btn-bg: var(--azul);
  --btn-fg: var(--blanco);
  display: inline-flex; align-items: center; justify-content: center;
  gap: .5rem;
  background: var(--btn-bg); color: var(--btn-fg);
  font-weight: 600; font-size: 1rem;
  padding: .8rem 1.6rem;
  border: 0; border-radius: var(--r-pill);
  cursor: pointer;
  text-align: center;
  transition: transform .22s var(--ease), box-shadow .22s var(--ease), background-color .22s var(--ease);
}
.btn:hover { transform: translateY(-2px); box-shadow: 0 12px 26px rgba(1, 54, 46, .22); }
.btn:active { transform: translateY(0); }

/* Los CTA no se parten en dos líneas: a lo ancho se encogen, no envuelven. */
.btn--lg { font-size: clamp(1rem, 1.25vw, 1.2rem); padding: 1.05rem 2.3rem; white-space: nowrap; }
@media (max-width: 400px) {
  .btn--lg { font-size: .92rem; padding: .95rem 1.3rem; }
}
.btn--azul  { --btn-bg: var(--azul);  --btn-fg: #fff; }
.btn--azul:hover  { background: var(--azul-dark); }
.btn--verde { --btn-bg: var(--verde); --btn-fg: var(--crema); }
.btn--verde:hover { background: var(--verde-mid); }
.btn--lima  { --btn-bg: var(--lima);  --btn-fg: var(--verde); }
.btn--menta { --btn-bg: var(--menta); --btn-fg: var(--verde); }

/* ── Reveal al hacer scroll ──
   El ocultado inicial cuelga de .js (que pone el script en línea del head):
   sin JavaScript nada se oculta, así que si el observador nunca corre la
   página sigue legible en lugar de quedarse en blanco.
   :where() mantiene la especificidad en 0 para que las reglas de
   animation-timeline del final del archivo sigan ganando. */
:where(.js) .reveal {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity .7s var(--ease), transform .7s var(--ease);
}
.reveal.is-visible { opacity: 1; transform: none; }

/* ══════════════════════════════════════════════
   Nav
   ══════════════════════════════════════════════ */
.nav {
  position: sticky; top: 0; z-index: 100;
  background: rgba(255, 255, 255, .92);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid rgba(1, 54, 46, .12);
  transition: box-shadow .25s var(--ease);
}
.nav.is-scrolled { box-shadow: 0 6px 24px rgba(1, 54, 46, .09); }

.nav__inner {
  max-width: var(--ancho);
  margin-inline: auto;
  padding: .85rem var(--gutter);
  display: flex; align-items: center; justify-content: space-between;
  gap: 1.5rem;
}

/* El logo es un SVG de dos tonos manejado por variables: aquí va la
   versión para fondo claro (marca azul, palabra verde). */
.nav__logo { --logo-mark: var(--azul); --logo-word: var(--verde); display: block; }
.nav__logo .logo-svg { width: clamp(112px, 11vw, 148px); }

.nav__links { display: flex; align-items: center; gap: clamp(1rem, 2.4vw, 2.6rem); }
.nav__links > a:not(.btn) {
  font-weight: 500; font-size: 1rem; color: var(--verde);
  padding: .3rem 0;
  border-bottom: 2px solid transparent;
  transition: border-color .2s var(--ease), color .2s var(--ease);
}
.nav__links > a:not(.btn):hover { border-bottom-color: var(--azul); color: var(--azul); }
.nav__cta { flex: none; }

.nav__toggle {
  display: none;
  width: 46px; height: 46px;
  background: var(--verde); border: 0; border-radius: 12px;
  cursor: pointer;
  padding: 0;
  place-content: center; gap: 5px;
}
.nav__toggle span {
  display: block; width: 20px; height: 2px; margin-inline: auto;
  background: var(--crema); border-radius: 2px;
  transition: transform .25s var(--ease), opacity .2s var(--ease);
}
.nav__toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav__toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav__toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

@media (max-width: 900px) {
  .nav__toggle { display: grid; }
  .nav__links {
    position: absolute; inset: 100% 0 auto 0;
    flex-direction: column; align-items: stretch;
    gap: 0;
    background: var(--blanco);
    border-bottom: 1px solid rgba(1, 54, 46, .12);
    box-shadow: 0 20px 40px rgba(1, 54, 46, .12);
    padding: .5rem var(--gutter) 1.4rem;
    /* Cerrado: fuera del flujo de tabulación y sin alto. */
    display: none;
  }
  .nav__links.is-abierto { display: flex; }
  .nav__links > a:not(.btn) { padding: .95rem 0; border-bottom: 1px solid rgba(1, 54, 46, .1); }
  .nav__links > a:not(.btn):hover { border-bottom-color: rgba(1, 54, 46, .1); }
  .nav__cta { margin-top: 1rem; }
}

/* ══════════════════════════════════════════════
   1 · Hero
   ══════════════════════════════════════════════ */
.hero { padding-top: clamp(2.5rem, 6vw, 5.5rem); overflow: hidden; }
.hero__texto { text-align: center; }
.hero__titulo {
  font-size: var(--t-hero);
  font-weight: 600;
  color: var(--verde);
  margin-bottom: clamp(1.6rem, 3vw, 2.6rem);
}
.hero__imagen { margin-top: clamp(2rem, 4.5vw, 3.6rem); }
/* En el PDF el bloque teléfono+foto NO va de borde a borde: ocupa ~75 % del
   ancho, centrado, con aire a ambos lados. El PNG ya trae el teléfono y el
   recorte redondeado integrados, así que basta con dimensionar el conjunto. */
.hero__imagen img {
  width: min(75%, 1440px);
  margin-inline: auto;
}

@media (max-width: 640px) {
  .hero__titulo br { display: none; }
  /* En pantallas chicas el 75 % deja la foto ilegible: se recupera ancho. */
  .hero__imagen img { width: 94%; }
}

/* ══════════════════════════════════════════════
   2 · Qué somos
   ══════════════════════════════════════════════ */
.somos {
  position: relative;
  background: var(--crema);
  padding-block: var(--seccion-y);
  margin-top: clamp(2rem, 5vw, 4rem);
  overflow: hidden;
}
/* Cuarto de círculo verde asomando por la izquierda. */
.somos__curva {
  position: absolute; left: 0; top: 0;
  width: clamp(120px, 16vw, 300px); aspect-ratio: 1;
  background: var(--verde);
  border-radius: 0 0 100% 0;
  transform: translateY(-1px);
  pointer-events: none;
}
.somos__inner { position: relative; text-align: center; }
.somos__titulo { font-size: var(--t-h2); font-weight: 600; color: var(--verde); }
.somos__sub {
  margin-top: 1.1rem;
  font-size: clamp(1.05rem, 1.5vw, 1.45rem);
  color: var(--verde);
}

.cifras {
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: clamp(1rem, 2.2vw, 2.2rem);
  margin-top: clamp(2.5rem, 5vw, 4.5rem);
}
.cifra {
  flex: 1 1 200px; max-width: 280px;
  background: var(--azul); color: var(--crema);
  /* Forma de hoja: dos esquinas muy redondeadas en diagonal. */
  border-radius: 4px 46px 4px 46px;
  padding: clamp(1.5rem, 2.4vw, 2.2rem) 1.25rem;
  text-align: center;
}
.cifra__dato {
  display: block;
  font-size: clamp(2.4rem, 4vw, 3.6rem);
  font-weight: 700; line-height: 1;
  color: var(--lima);
}
.cifra__label { display: block; margin-top: .5rem; font-size: 1rem; }

@media (max-width: 860px) {
  /* La curva verde mide más que el padding de la sección, así que en pantallas
     angostas el título centrado le pasaba por debajo. Se encoge y el contenido
     baja lo justo para librarla. */
  .somos__curva { width: clamp(86px, 20vw, 150px); }
  .somos__inner { padding-top: clamp(2.5rem, 14vw, 4.5rem); }
}
@media (max-width: 640px) {
  .somos__titulo br, .somos__sub br { display: none; }
}

/* ══════════════════════════════════════════════
   3 · Personaliza acorde a tu marca
   ══════════════════════════════════════════════ */
.marca {
  position: relative;
  padding-block: var(--seccion-y);
  overflow: hidden;
}
.marca__blob {
  position: absolute; border-radius: 50%;
  background: var(--lima);
  pointer-events: none;
  z-index: 0;
}
.marca__blob--a {
  width: clamp(280px, 42vw, 720px); aspect-ratio: 1;
  top: -12%; right: -12%;
}
.marca__blob--b {
  width: clamp(240px, 38vw, 660px); aspect-ratio: 1;
  bottom: -22%; left: -14%;
}

.marca__inner {
  position: relative; z-index: 1;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  align-items: center;
  gap: clamp(2rem, 5vw, 5rem);
}
.marca__tarjeta { display: flex; justify-content: center; }
.marca__titulo { font-size: var(--t-h2); font-weight: 600; color: var(--verde); }
.marca__texto {
  margin-top: 1.2rem;
  font-size: clamp(1.05rem, 1.4vw, 1.4rem);
  color: var(--verde);
  max-width: 26ch;
}

/* ── Tarjeta viva (sustituye a GIFTarjetas.gif) ── */
.tarjeta-viva {
  position: relative;
  width: min(340px, 78vw);
  aspect-ratio: 340 / 560;
}
.tviva {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center;
  gap: .85rem;
  background: var(--tviva-bg);
  color: var(--crema);
  border-radius: 30px;
  padding: 1.9rem 1.5rem 2.1rem;
  box-shadow: var(--sombra-alta);
  opacity: 0;
  transform: scale(.97);
  transition: opacity .6s var(--ease), transform .6s var(--ease), background-color .6s var(--ease);
  pointer-events: none;
}
.tviva.is-activa { opacity: 1; transform: none; pointer-events: auto; }

.tviva__nombre { font-size: 1.2rem; font-weight: 500; }
.tviva__qr {
  background: var(--blanco);
  border-radius: 14px;
  padding: 12px;
  width: 62%;
}
.tviva__qr img { width: 100%; height: auto; }
.tviva__negocio {
  font-size: 1.5rem; font-weight: 800; letter-spacing: -.01em;
  margin-top: .2rem;
}
.tviva__barra {
  width: 100%; height: 26px;
  border: 2px solid var(--crema);
  border-radius: var(--r-pill);
  padding: 3px;
  margin-top: .3rem;
}
.tviva__relleno {
  display: flex; align-items: center; justify-content: flex-end;
  height: 100%; width: var(--pct);
  background: var(--azul);
  border-radius: var(--r-pill);
}
.tviva__sello {
  width: 14px; height: 14px; margin-right: 4px;
  background: var(--crema);
  border-radius: 3px;
}
.tviva__conteo { align-self: flex-start; font-size: .85rem; opacity: .85; }
.tviva__promo { text-align: center; font-size: 1rem; line-height: 1.4; margin-top: auto; }

@media (max-width: 860px) {
  .marca__inner { grid-template-columns: minmax(0, 1fr); }
  .marca__copy { text-align: center; }
  .marca__texto { max-width: none; }
  .marca__titulo br { display: none; }
}

/* ══════════════════════════════════════════════
   4 · No es una app más
   ══════════════════════════════════════════════ */
.ventaja { padding-block: var(--seccion-y); }
.ventaja__titulo {
  font-size: var(--t-h2); font-weight: 600; color: var(--verde);
  margin-bottom: clamp(2rem, 4vw, 3.5rem);
}
.ventaja__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  gap: clamp(2rem, 4vw, 4rem);
  align-items: center;
}
.ventaja__pantalla {
  width: 100%;
  filter: drop-shadow(0 24px 46px rgba(1, 54, 46, .18));
}
.ventaja__nota {
  background: var(--lima); color: var(--verde);
  font-size: clamp(1.05rem, 1.4vw, 1.35rem);
  font-weight: 500;
  border-radius: 18px;
  padding: 1.15rem 1.4rem;
  max-width: 26rem;
  margin-top: -1.5rem;
  position: relative;
}

.ventaja__cards {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(1rem, 1.6vw, 1.5rem);
}
.vcard {
  border-radius: var(--r-card);
  padding: clamp(1.4rem, 2vw, 1.9rem);
  display: flex; flex-direction: column; gap: .7rem;
}
.vcard--azul  { background: var(--azul);  color: #fff; }
.vcard--verde { background: var(--verde); color: var(--crema); }
.vcard__icono { width: 46px; height: 46px; align-self: center; }
.vcard__titulo { font-size: var(--t-card); font-weight: 700; text-align: center; }
.vcard p { font-size: .98rem; line-height: 1.5; }

@media (max-width: 900px) {
  .ventaja__grid { grid-template-columns: minmax(0, 1fr); }
  .ventaja__nota { margin-top: 1rem; max-width: none; }
}
@media (max-width: 560px) {
  .ventaja__cards { grid-template-columns: 1fr; }
  .ventaja__titulo br { display: none; }
}

/* ══════════════════════════════════════════════
   5 · Notificaciones push
   ══════════════════════════════════════════════ */
.notis {
  background: var(--menta);
  overflow: hidden;
}
.notis__inner {
  display: grid;
  grid-template-columns: minmax(0, .95fr) minmax(0, 1fr);
  gap: clamp(1.5rem, 4vw, 4rem);
  align-items: center;
  /* Sin max-width ni margen automático: la foto tiene que llegar al filo
     izquierdo de la pantalla. El aire de la columna derecha se pone abajo,
     en .notis__copy. */
  width: 100%;
}
/* La foto va pegada al borde izquierdo y al inferior de la sección. */
.notis__visual { position: relative; align-self: end; display: flex; }
/* La foto ya viene con el círculo azul y los chips de notificación (con su
   sombra real) integrados al diseño — ya no se simulan con HTML/CSS.
   `block` + `align-self:end` evita el hueco de un par de píxeles que deja
   una imagen inline sobre la línea base. */
.notis__foto { width: 100%; display: block; }

/* El aire de la derecha vive aquí, porque .notis__inner ya no lo pone: así la
   foto llega al filo izquierdo pero el texto no se pega al derecho. */
.notis__copy {
  padding: var(--seccion-y) max(var(--gutter), calc(50vw - var(--ancho) / 2)) var(--seccion-y) 0;
}
.notis__titulo { font-size: var(--t-h2); font-weight: 600; color: var(--verde); }
.notis__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(1.6rem, 3vw, 2.8rem);
  margin-top: clamp(2rem, 3.5vw, 3.2rem);
}
/* Altura fija, ancho auto: el icono de geolocalización (y varios más) no es
   cuadrado y forzarlo a 40×40 lo estiraba. */
.noti-item img { height: 40px; width: auto; margin-bottom: .7rem; }
.noti-item h3 { font-size: var(--t-card); color: var(--verde); margin-bottom: .5rem; }
.noti-item p { font-size: .98rem; color: var(--texto-suave); }

@media (max-width: 960px) {
  .notis__inner { grid-template-columns: minmax(0, 1fr); }
  .notis__copy { padding: 0 var(--gutter) var(--seccion-y); }
  .notis__visual { order: 2; }
  .notis__titulo { padding-top: var(--seccion-y); }
}
@media (max-width: 560px) {
  .notis__grid { grid-template-columns: 1fr; }
  .notis__titulo br { display: none; }
  /* En móvil se quita la foto: es una imagen alta (retrato) que en pantallas
     chicas empuja demasiado contenido hacia abajo sin aportar información
     nueva — el texto ya explica las 4 notificaciones. */
  .notis__visual { display: none; }
}

/* ══════════════════════════════════════════════
   6 · Para quién es
   ══════════════════════════════════════════════ */
.giros { padding-block: var(--seccion-y); text-align: center; }
.giros__titulo { font-size: var(--t-h2); font-weight: 600; color: var(--azul); }
.giros__sub { margin-top: .9rem; font-size: clamp(1.05rem, 1.4vw, 1.4rem); color: var(--verde); }

.giros__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
  gap: clamp(2rem, 4vw, 4rem);
  align-items: center;
  margin-top: clamp(2.5rem, 4.5vw, 4rem);
  text-align: left;
}
.giros__chips { display: flex; flex-wrap: wrap; gap: .7rem; }
.chip-giro {
  font-family: inherit;
  font-size: clamp(.9rem, 1vw, 1.02rem);
  color: var(--verde);
  background: transparent;
  border: 2px solid var(--lima);
  border-radius: var(--r-pill);
  padding: .6rem 1.15rem;
  cursor: pointer;
  transition: background-color .2s var(--ease), border-color .2s var(--ease), color .2s var(--ease);
}
/* Alternamos el color del borde como en el diseño. */
.giros__chips li:nth-child(even) .chip-giro { border-color: var(--azul); }
.chip-giro:hover { background: var(--crema); }
.chip-giro.is-activo,
.chip-giro.is-activo:hover {
  background: var(--azul); border-color: var(--azul); color: #fff;
}
.giros__mas {
  font-size: clamp(1.6rem, 3vw, 2.6rem);
  font-weight: 600; color: var(--verde);
  margin-top: 1.6rem;
}
.giros__foto img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  /* Recorte asimétrico del diseño: esquina superior izquierda muy suave. */
  border-radius: 180px 22px 22px 22px;
  background: var(--menta);
  transition: opacity .35s var(--ease);
}
.giros__foto img.is-cambiando { opacity: 0; }

@media (max-width: 900px) {
  .giros__grid { grid-template-columns: minmax(0, 1fr); }
  .giros__chips { justify-content: center; }
  .giros__mas { text-align: center; }
  .giros__foto img { border-radius: 100px 22px 22px 22px; }
}

/* ══════════════════════════════════════════════
   7 · Por qué elegir Fidely
   ══════════════════════════════════════════════ */
.porque {
  background: var(--crema);
  padding-block: var(--seccion-y);
  overflow: hidden;
}
.porque__head { text-align: center; margin-bottom: clamp(2rem, 4vw, 3.5rem); }
.porque__titulo { font-size: var(--t-h2); font-weight: 600; color: var(--verde); }
.porque__sub { margin-top: .8rem; font-size: clamp(1.05rem, 1.4vw, 1.4rem); color: var(--verde); }

.porque__cuerpo {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, .92fr);
  gap: clamp(1.5rem, 3.5vw, 3.5rem);
  align-items: center;
  max-width: calc(var(--ancho) + 2 * var(--gutter));
  margin-inline: auto;
  padding-right: var(--gutter);
}
/* El panel azul se sangra al borde izquierdo y cierra con una curva grande. */
.porque__panel {
  background: var(--azul);
  color: #fff;
  border-radius: 0 clamp(90px, 16vw, 260px) clamp(90px, 16vw, 260px) 0;
  padding: clamp(2.2rem, 4.5vw, 4rem) clamp(2rem, 5vw, 5rem);
  /* Sangra hasta el filo de la ventana; el padding izquierdo se dobla para
     compensar la sangría y que el texto no quede pegado al borde. */
  margin-left: calc(-1 * var(--gutter));
  padding-left: calc(2 * var(--gutter));
}
.porque__logo { --logo-mark: var(--lima); --logo-word: var(--crema); margin-bottom: clamp(1.6rem, 3vw, 2.6rem); }
.porque__logo .logo-svg { width: clamp(170px, 20vw, 280px); }
.porque__lista {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(1.2rem, 2.4vw, 2.1rem);
}
.porque__lista li { display: flex; flex-direction: column; gap: .55rem; font-size: clamp(1rem, 1.2vw, 1.2rem); font-weight: 500; }
/* El PNG entra como máscara: se conserva su trazo (el alfa) pero el color lo
   decide la marca, no el archivo. */
.porque__lista .ic {
  width: 32px; height: 32px;
  background: var(--lima);
  -webkit-mask: var(--ic) center / contain no-repeat;
  mask: var(--ic) center / contain no-repeat;
}
/* La quinta viñeta ocupa el ancho completo, como en el diseño. */
.porque__lista li:last-child { grid-column: 1 / -1; }

.porque__contra {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(1rem, 2vw, 1.6rem);
}
.contra {
  background: var(--blanco);
  border-radius: 20px;
  overflow: hidden;
  box-shadow: var(--sombra-card);
}
.contra__titulo {
  font-size: clamp(1.05rem, 1.4vw, 1.35rem);
  font-weight: 600; color: var(--verde);
  text-align: center;
  padding: 1.1rem 1rem;
}
.contra__titulo--lima  { background: var(--lima); }
.contra__titulo--menta { background: var(--menta); }
.contra ul { padding: 1.3rem 1.4rem 1.7rem; display: grid; gap: .85rem; }
.contra li {
  font-size: .98rem; color: var(--texto-suave);
  padding-left: 1rem; position: relative;
}
.contra li::before {
  content: "°";
  position: absolute; left: 0; top: 0;
  color: var(--verde);
}

@media (max-width: 980px) {
  .porque__cuerpo { grid-template-columns: minmax(0, 1fr); padding-right: 0; }
  .porque__panel {
    border-radius: 0 0 clamp(60px, 12vw, 140px) clamp(60px, 12vw, 140px);
    /* El padding dobla la sangría, igual que en la versión ancha, para que el
       texto no termine pegado al filo de la pantalla. */
    margin-inline: calc(-1 * var(--gutter));
    padding-inline: calc(2 * var(--gutter));
  }
  .porque__contra { padding-inline: var(--gutter); }
}
@media (max-width: 560px) {
  .porque__lista { grid-template-columns: 1fr; }
  .porque__contra { grid-template-columns: 1fr; }
}

/* ══════════════════════════════════════════════
   8 · Tres pasos
   ══════════════════════════════════════════════ */
.pasos {
  background: var(--verde);
  color: var(--crema);
  padding-top: var(--seccion-y);
  position: relative;
  /* overflow visible a propósito: la mano se asoma por debajo del borde de
     la sección, sobre la sección de planes, como en el diseño. */
}
.pasos__titulo {
  font-size: var(--t-h2); font-weight: 600;
  color: var(--crema);
  text-align: center;
}
.pasos__lista {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1rem, 2.2vw, 2rem);
  margin-top: clamp(3rem, 5vw, 5rem);
}
.paso {
  position: relative;
  background: var(--crema);
  color: var(--verde);
  border-radius: 20px;
  padding: clamp(1.8rem, 2.6vw, 2.4rem) clamp(1.3rem, 2vw, 1.9rem) clamp(1.5rem, 2vw, 2rem);
  text-align: center;
}
.paso__num {
  position: absolute; top: -22px; left: 50%; transform: translateX(-50%);
  width: 44px; height: 44px;
  display: grid; place-content: center;
  background: var(--lima); color: var(--verde);
  border-radius: 50%;
  font-weight: 700; font-size: 1.15rem;
}
.paso__titulo { font-size: var(--t-card); color: var(--verde); margin-bottom: .8rem; }
.paso p { font-size: .98rem; color: var(--texto-suave); }

/* La mano sale del costado IZQUIERDO de la pantalla (el brazo queda cortado
   por el filo del viewport) y el teléfono sobresale hacia la sección
   siguiente. En flujo normal reserva su espacio con el padding de la sección;
   la imagen se ancla absoluta al borde de la sección, no del contenedor. */
.pasos { padding-bottom: clamp(11rem, 22vw, 20rem); }
.pasos__mano {
  position: absolute;
  left: 0;
  /* Dentro de la sección, no colgando por debajo: así el teléfono se ve
     completo cuando la sección se asienta en la pantalla. */
  bottom: clamp(1.5rem, 4vh, 4rem);
  width: clamp(240px, 30vw, 460px);
  display: block;
  pointer-events: none;
}
/* El contenedor NO se mueve ni se esconde. Si se desplazara fuera de la
   pantalla, su área visible caería por debajo del umbral del observador
   (medido: 11 % contra un mínimo de 12 %) y la mano no entraría nunca:
   estaría escondida justo por estar escondida. */
.pasos__mano.reveal { animation: none; opacity: 1; transform: none; }

/* La entrada es temporal y NO enganchada al scroll (a diferencia del resto de
   los reveals): así se siente lenta y continua en lugar de avanzar a saltos
   según cuánto mueva la rueda el visitante. */
.pasos__mano-slide {
  display: block;
  transition: transform 1.7s cubic-bezier(.16, .84, .28, 1), opacity 1.1s var(--ease);
}
:where(.js) .pasos__mano.reveal .pasos__mano-slide {
  transform: translateX(-80%);
  opacity: 0;
}
.pasos__mano.reveal.is-visible .pasos__mano-slide { transform: none; opacity: 1; }

/* El saludo: el brazo pivota sobre el codo, que es justo donde entra a la
   pantalla, así que el giro se lee como un saludo y no como un balanceo de
   toda la imagen. Arranca cuando la mano ya terminó de asomarse. */
/* El PNG corta el brazo en seco en su borde izquierdo e inferior. La máscara
   lo disuelve en degradado, así el brazo se lee como que continúa fuera de
   cuadro en lugar de terminar en una línea recta. Va sobre el <img> (no sobre
   el contenedor) para que el giro del saludo no se recorte en las esquinas. */
.pasos__mano-img {
  display: block;
  width: 100%;
  transform-origin: 4% 92%;
  --disolver:
    linear-gradient(to right, transparent 0, #000 11%),
    linear-gradient(to top, transparent 0, #000 9%);
  -webkit-mask-image: var(--disolver);
          mask-image: var(--disolver);
  -webkit-mask-composite: source-in;
          mask-composite: intersect;
}

@keyframes saludo {
  0%   { transform: rotate(0deg); }
  14%  { transform: rotate(-8deg); }
  30%  { transform: rotate(5.5deg); }
  46%  { transform: rotate(-6.5deg); }
  62%  { transform: rotate(4deg); }
  78%  { transform: rotate(-3deg); }
  90%  { transform: rotate(1.5deg); }
  100% { transform: rotate(0deg); }
}
.pasos__mano.is-visible .pasos__mano-img {
  animation: saludo 3.2s cubic-bezier(.37, 0, .63, 1) 1.5s 2 both;
}

@media (max-width: 860px) {
  .pasos__lista { grid-template-columns: 1fr; gap: 3rem; }
  .pasos { padding-bottom: clamp(9rem, 40vw, 13rem); }
  .pasos__mano { width: clamp(200px, 46vw, 260px); }
}

/* ══════════════════════════════════════════════
   9 · Planes
   ══════════════════════════════════════════════ */
.planes { padding-block: var(--seccion-y); text-align: center; }
.planes__titulo { font-size: var(--t-h2); font-weight: 600; color: var(--azul); }
.planes__sub {
  margin-top: 1rem; font-size: clamp(1.02rem, 1.3vw, 1.3rem); color: var(--verde);
  max-width: 46rem; margin-inline: auto;
}
/* Flex en vez de grid de 3 columnas fijas: con menos de 3 planes activos
   (activo=0 desde el CRUD) las tarjetas se centran como grupo en vez de
   quedar pegadas a la izquierda con una columna vacía. */
.planes__grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: clamp(1.2rem, 2.6vw, 2.4rem);
  margin-top: clamp(2.5rem, 5vw, 4.5rem);
  align-items: start;
}
.plan {
  position: relative;
  background: var(--crema);
  border-radius: var(--r-card);
  padding: clamp(2.2rem, 3vw, 2.8rem) clamp(1.4rem, 2.2vw, 2rem) clamp(1.8rem, 2.4vw, 2.2rem);
  text-align: left;
  display: flex; flex-direction: column;
  flex: 1 1 320px;
  max-width: 380px;
  height: 100%;
}
/* Cinta de color que sobresale por arriba de la tarjeta. */
.plan__cinta {
  position: absolute; top: -14px; left: 50%; transform: translateX(-50%);
  width: 46%; height: 28px;
  border-radius: 6px 6px 0 0;
}
.plan__cinta--menta { background: var(--menta); }
.plan__cinta--lima  { background: var(--lima); }
.plan__cinta--azul  { background: var(--azul); }

.plan__nombre {
  font-size: clamp(1.1rem, 1.3vw, 1.3rem);
  font-weight: 700; letter-spacing: .04em;
  color: var(--verde);
  text-align: center;
}
.plan__nombre--azul { color: var(--azul); }
.plan__precio {
  display: flex; align-items: baseline; justify-content: center; gap: .4rem;
  margin: .9rem 0 1.6rem;
}
.plan__monto { font-size: clamp(2.4rem, 3.6vw, 3.3rem); font-weight: 800; color: var(--verde); line-height: 1; }
.plan__moneda { font-size: .82rem; font-weight: 500; color: var(--verde); line-height: 1.25; }

.plan__periodo {
  text-align: center;
  font-size: .78rem;
  font-weight: 600;
  color: var(--verde);
  opacity: .6;
  line-height: 1.4;
  margin: -1rem 0 1.4rem;
}
.plan__periodo-nota { font-weight: 400; }

.plan__lista { display: grid; gap: .65rem; margin-bottom: 1.8rem; }
.plan__lista li { position: relative; padding-left: 1.1rem; font-size: 1rem; color: var(--verde); }
.plan__lista li::before {
  content: ""; position: absolute; left: 0; top: .55em;
  width: 7px; height: 7px; border-radius: 50%;
}
.plan__lista--menta li::before { background: var(--menta); }
.plan__lista--lima  li::before { background: var(--lima); }
.plan__lista--azul  li::before { background: var(--azul-soft); }

.plan__btn { margin-top: auto; width: 100%; }

@media (max-width: 900px) {
  .planes__grid { flex-direction: column; align-items: center; max-width: 26rem; margin-inline: auto; }
  .plan { max-width: 100%; width: 100%; }
}

/* ══════════════════════════════════════════════
   10 · Contacto
   ══════════════════════════════════════════════ */
.contacto { padding-block: var(--seccion-y); overflow-x: clip; overflow-y: visible; }
.contacto__inner {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr);
  gap: clamp(2rem, 4vw, 4rem);
  align-items: start;
}
.contacto__titulo { font-size: var(--t-h2); font-weight: 600; color: var(--verde); }
.contacto__texto { margin-top: 1.3rem; max-width: 44ch; color: var(--texto-suave); }
.contacto__datos { display: grid; gap: .55rem; margin-top: 1.6rem; font-size: 1rem; }
.contacto__datos a { color: var(--azul); font-weight: 500; }
.contacto__datos a:hover { text-decoration: underline; }

/* Pila de tarjetas girada + la mano con el auricular. */
.contacto__visual { position: relative; display: grid; justify-items: center; }
.contacto__cards { position: relative; display: block; width: min(100%, 380px); aspect-ratio: 1.12; }
.ccard {
  position: absolute; inset: 0;
  border-radius: 26px;
}
.ccard--lima  { background: var(--lima);  transform: rotate(-11deg) translate(-6%, 4%); }
.ccard--menta { background: var(--menta); transform: rotate(-5deg) translate(-1%, 2%); }
.ccard--verde {
  background: var(--verde);
  display: grid; place-content: center;
  padding: 2rem;
  --logo-mark: var(--lima); --logo-word: var(--crema);
}
.ccard--verde .logo-svg { width: min(72%, 230px); }
.contacto__mano {
  width: clamp(120px, 18vw, 200px);
  margin-top: -18%;
  margin-left: 42%;
  position: relative;
}

@media (max-width: 900px) {
  .contacto__inner { grid-template-columns: minmax(0, 1fr); }
  .contacto__visual { order: -1; }
  .contacto__texto { max-width: none; }
}

/* ── Formulario ── */
.form { margin-top: clamp(2rem, 3.5vw, 2.8rem); display: grid; gap: 1rem; max-width: 40rem; }
.form__trampa { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.form__fila { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1rem; }
.campo { display: grid; gap: .4rem; }
.campo__label { font-size: .92rem; font-weight: 600; color: var(--verde); }
.campo__input {
  font-family: inherit; font-size: 1rem; color: var(--verde);
  background: var(--crema);
  border: 2px solid transparent;
  border-radius: 14px;
  padding: .85rem 1rem;
  width: 100%;
  transition: border-color .2s var(--ease), background-color .2s var(--ease);
}
.campo__input::placeholder { color: rgba(1, 54, 46, .45); }
.campo__input:focus {
  outline: none;
  border-color: var(--azul);
  background: var(--blanco);
}
.campo__input--area { resize: vertical; min-height: 7rem; line-height: 1.5; }
.form__enviar { justify-self: start; }
.form__nota { font-size: .88rem; color: var(--texto-suave); }
.form__aviso {
  border-radius: 14px; padding: .9rem 1.1rem; font-weight: 500;
}
.form__aviso--ok    { background: var(--lima);  color: var(--verde); }
.form__aviso--error { background: #FFE2E2; color: #8A1F1F; }

@media (max-width: 560px) { .form__fila { grid-template-columns: 1fr; } }

/* ══════════════════════════════════════════════
   Pie de página
   ══════════════════════════════════════════════ */
/* Proporciones medidas del PDF (página 2): el pie mide 0.846 × el ancho de
   página; el starburst de la foto abarca del 44.3 % al 86.4 % del ancho y del
   4.7 % al 60.5 % del alto; la tarjeta lima va del 10 % al 44.3 % del ancho,
   arrancando al 22 % del alto. */
.pie {
  /* Fondo_Final.png trae el verde y la foto con la máscara de estrella. Su
     verde es exactamente --verde, así que la imagen puede sobresalir del
     encuadre sin que se note la costura: solo se ve el starburst.
     El PNG lleva mucho verde de relleno alrededor del starburst (este ocupa
     del 46 % al 90.5 % de su ancho y del 6.3 % al 63.5 % de su alto). De ahí
     sale el tamaño: 0.46·105 = 48 % marca el borde izquierdo de la foto y
     0.905·105 = 95 % el derecho, que es donde el PDF los pone.

     Se usa vw y NO % en background-position a propósito: los porcentajes ahí
     no son un desplazamiento, se resuelven contra (contenedor − imagen), así
     que con una imagen más ancha que el contenedor el signo se invierte y la
     foto se va fuera de cuadro. Una longitud sí desplaza de forma directa. */
  background: var(--verde) url('/assets/img/Fondo_Final.png') no-repeat;
  background-size: 105vw auto;
  background-position: -1vw -1vw;
  color: var(--crema);
  padding-top: 0;
}
/* La banda superior reserva la altura del bloque tarjeta + foto con la misma
   proporción del diseño, para que la foto no pise las columnas de abajo. */
.pie__cta {
  position: relative;
  width: 100%;
  aspect-ratio: 1920 / 1075;
}
.pie__tarjeta {
  position: absolute;
  left: 10%;
  top: 28.5%;
  width: 34%;
  transform: rotate(-3.5deg);
  filter: drop-shadow(0 24px 45px rgba(0, 0, 0, .28));
}

.pie__cuerpo {
  max-width: var(--ancho);
  margin-inline: auto;
  width: 100%;
  padding: clamp(1.5rem, 3vw, 3rem) var(--gutter) clamp(2rem, 4vw, 3.5rem);
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr) minmax(0, .8fr) minmax(0, 1.4fr);
  gap: clamp(1.8rem, 3vw, 3rem);
  align-items: start;
}
.pie__logo { --logo-mark: var(--lima); --logo-word: var(--crema); }
.pie__logo .logo-svg { width: clamp(180px, 22vw, 300px); }

.pie__col--links { display: grid; gap: .8rem; font-size: 1.02rem; }
.pie__col--links a:hover { color: var(--lima); }

/* Rejilla 2×2, como en el diseño: Facebook e Instagram arriba, X y TikTok
   abajo. Antes iban en una sola fila de cuatro. */
.pie__col--redes {
  display: grid;
  grid-template-columns: repeat(2, auto);
  justify-content: start;
  gap: .7rem;
}
.red {
  width: 42px; height: 42px;
  display: grid; place-content: center;
  background: var(--crema); border-radius: 50%;
  transition: background-color .2s var(--ease), transform .2s var(--ease);
}
.red svg { width: 22px; height: 22px; fill: var(--verde); }
.red:hover { background: var(--lima); transform: translateY(-2px); }

.pie__col--datos {
  font-style: normal;
  display: grid; gap: .5rem;
  text-align: right;
  font-size: .98rem;
}
.pie__col--datos a:hover { color: var(--lima); }

.pie__legal {
  max-width: var(--ancho);
  margin-inline: auto;
  padding: 1.5rem var(--gutter) 2.5rem;
  display: flex; flex-wrap: wrap; align-items: center;
  gap: 1rem clamp(1.5rem, 5vw, 5rem);
  font-size: .95rem;
}
.pie__legal a:hover { color: var(--lima); }
.pie__copy { margin-left: auto; font-weight: 700; }

@media (max-width: 900px) {
  /* En pantallas angostas la banda se estira de alto (la tarjeta necesita más
     sitio en proporción) y las columnas pasan por debajo. */
  /* En angosto el starburst se lleva casi todo el ancho (del 25 % al 95 %),
     de ahí el 157vw de tamaño: 0.70 / 0.446. */
  .pie { background-size: 157vw auto; background-position: -47vw -1vw; }
  /* En angosto no caben lado a lado: se apilan —foto arriba, tarjeta debajo—
     en lugar de que la tarjeta le tape las caras a la foto. */
  .pie__cta { aspect-ratio: 3 / 4; }
  .pie__tarjeta { left: 6%; top: 62%; width: 60%; }
  .pie__cuerpo { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); text-align: left; }
  .pie__col--datos { text-align: left; }
}
@media (max-width: 560px) {
  .pie__cuerpo { grid-template-columns: minmax(0, 1fr); }
  .pie__copy { margin-left: 0; }
  .pie__tarjeta { top: 58%; width: 68%; }
}

/* ══════════════════════════════════════════════
   Páginas de texto (legales, 404)
   ══════════════════════════════════════════════ */
.doc { padding-block: clamp(3rem, 7vw, 6rem); }
.doc__inner { max-width: 46rem; }
.doc h1 { font-size: var(--t-h2); font-weight: 600; color: var(--verde); margin-bottom: 1.5rem; }
.doc h2 { font-size: clamp(1.3rem, 2vw, 1.7rem); color: var(--verde); margin: 2.4rem 0 .8rem; }
.doc p, .doc li { color: var(--texto-suave); margin-bottom: .9rem; }
.doc ul { list-style: disc; padding-left: 1.4rem; }
.doc__meta { font-size: .92rem; color: var(--texto-suave); }
.doc__pendiente {
  background: var(--crema); border-left: 4px solid var(--lima);
  border-radius: 0 14px 14px 0; padding: 1rem 1.2rem; margin-bottom: 2rem;
  color: var(--verde);
}

.error404 { text-align: center; padding-block: clamp(4rem, 12vw, 9rem); }
.error404 h1 { font-size: var(--t-hero); color: var(--verde); }
.error404 p { margin: 1.2rem 0 2rem; color: var(--texto-suave); }

/* ══════════════════════════════════════════════
   Cifras animadas (sección "Qué somos")
   Cada dato cuenta su propia historia al entrar en pantalla:
   0 = sacudida de sorpresa · 1 QR = rueda 0→1 muy lento · +30% = sube rápido.
   ══════════════════════════════════════════════ */
.cifra__dato { display: inline-block; }

@keyframes cifra-sacudida {
  0%, 100% { transform: none; }
  12% { transform: translateX(-7px) rotate(-4deg); }
  28% { transform: translateX(6px)  rotate(3deg); }
  44% { transform: translateX(-5px) rotate(-2deg); }
  60% { transform: translateX(4px)  rotate(1.5deg); }
  76% { transform: translateX(-2px); }
}
.cifra__dato.is-sacudido { animation: cifra-sacudida .8s var(--ease) 1; }

/* Odómetro del "1": una columna con 0 arriba y 1 abajo que se desplaza una
   línea, muy despacio, dentro de una ventana de una línea de alto.
   inline-block y no inline-flex: en un contenedor flex de columna el hijo
   se encoge para caber en 1em y el odómetro deja de tener a dónde rodar.
   El vertical-align negativo compensa que overflow:hidden mueve la línea
   base del inline-block a su borde inferior, lo que subía el dígito
   respecto al " QR" de al lado. */
.rodillo {
  display: inline-block;
  height: 1em; overflow: hidden;
  vertical-align: -.2em;
}
.rodillo__col { display: block; transition: transform 2.8s cubic-bezier(.2, .7, .2, 1); }
.rodillo__col span { display: block; height: 1em; line-height: 1em; }
.rodillo.is-rodado .rodillo__col { transform: translateY(-1em); }

/* ══════════════════════════════════════════════
   Presentación: cada sección cubre la pantalla
   Cada sección ocupa al menos el alto de la ventana y centra su contenido,
   así que al hacer scroll el visitante siempre tiene una sola sección
   delante. El scroll se "asienta" en la siguiente con scroll-snap.
   Se usa `proximity` y no `mandatory`: con mandatory, las secciones más
   altas que la pantalla (planes, contacto) atrapan al visitante y no lo
   dejan leer el contenido de en medio. Proximity da la sensación de
   presentación sin secuestrar el scroll.
   Solo desde 1024 px: en móvil el contenido es mucho más alto que la
   ventana y el snap pelearía con el dedo.
   ══════════════════════════════════════════════ */
@media (min-width: 1024px) and (prefers-reduced-motion: no-preference) {
  /* mandatory + snap-stop: cada gesto de scroll avanza UNA sección, ni más ni
     menos. Es lo que da la sensación de empujar una sección para descubrir la
     siguiente. Solo es seguro porque abajo se compacta todo para que ninguna
     sección sea más alta que la pantalla: con una sección más alta, mandatory
     dejaría contenido inalcanzable.
     Va en body.pagina-inicio y NO en `html` a secas: `html` es global a
     TODAS las páginas que cargan landing.css (checkout-exito, 404,
     contacto...), y esas no tienen `main > section` — el snap mandatory
     ahí no tenía dónde reposar y producía saltos/artefactos de scroll en
     vez de simplemente no hacer nada. */
  body.pagina-inicio { scroll-snap-type: y mandatory; }
  body.pagina-inicio .pie { scroll-snap-align: end; }

  /* El pie no se fuerza a una pantalla (encogía la foto hasta despegarse del
     diseño), pero SÍ necesita su punto de anclaje: con snap mandatory el
     navegador solo puede reposar sobre áreas de snap, y sin esta regla el pie
     no era una — al intentar bajar te devolvía al formulario. Como el pie es
     más alto que la ventana, la spec permite reposar en cualquier posición
     mientras lo cubra, así que se recorre completo con libertad. */
  body.pagina-inicio .pie { scroll-snap-align: start; }
  body.pagina-inicio main > section {
    /* grid + align-content en vez de flex: cada sección conserva el layout
       interno de sus hijos y solo se centra el conjunto. */
    display: grid;
    align-content: center;
    min-height: 100svh;
    scroll-snap-align: start;
    scroll-snap-stop: always;
    /* El padding vertical grande sobra cuando la sección ya mide una pantalla,
       y era justo lo que impedía que el contenido cupiera. */
    --seccion-y: clamp(1.25rem, 3vh, 2.75rem);

    /* Los titulares pasan a depender también del ALTO de la ventana. Escalados
       solo por ancho, en una laptop de 700 px de alto un título de 84 px se
       comía media pantalla y empujaba el contenido fuera de cuadro. */
    --t-hero: clamp(2.2rem, min(6.2vw, 9.5vh), 5.25rem);
    --t-h2:   clamp(1.7rem, min(4.6vw, 7vh),   3.9rem);
    --t-h3:   clamp(1.35rem, min(2.6vw, 4vh),  2.4rem);
  }

  /* ── Compactaciones para que el contenido quepa completo ── */

  /* La barra se adelgaza. Con las secciones centradas a pantalla completa, el
     hueco que queda sobre el título es de ~67-76 px; una barra de 79 px se le
     montaba encima. Adelgazarla cuesta cero espacio de contenido, mientras que
     reservar su alto en cada sección sí sacaría contenido de cuadro. */
  :root { --nav-h: 50px; }
  .nav__inner { padding-block: .45rem; }
  .nav__logo .logo-svg { width: clamp(92px, 8.5vw, 118px); }
  .nav__links > a:not(.btn) { font-size: .95rem; }
  .nav__cta { padding: .58rem 1.2rem; font-size: .95rem; }

  /* Hero: el bloque de la foto es lo más alto; se recorta un poco. */
  .hero__titulo { margin-bottom: clamp(1rem, 2vh, 1.8rem); }
  .hero__imagen { margin-top: clamp(1rem, 2.5vh, 2rem); }
  /* width auto + los dos topes: la imagen se ajusta a lo que sea más
     restrictivo (ancho o alto) conservando su proporción. */
  .hero__imagen img {
    width: auto;
    max-width: min(72%, 1250px);
    max-height: 40svh;
    margin-inline: auto;
  }

  /* "No es una app más": la nota lima y el grid de tarjetas se aprietan. */
  .ventaja__titulo { margin-bottom: clamp(1rem, 2.5vh, 2rem); }
  .ventaja__nota { padding: .85rem 1.15rem; margin-top: -1rem; }

  /* Planes: tarjetas más compactas sin perder legibilidad. */
  .planes__grid { margin-top: clamp(1.25rem, 3vh, 2.5rem); }
  .plan { padding: clamp(1.6rem, 2.4vh, 2.2rem) clamp(1.2rem, 1.8vw, 1.7rem) clamp(1.2rem, 2vh, 1.7rem); }
  .plan__precio { margin: .6rem 0 1rem; }
  .plan__periodo { margin: -.6rem 0 1rem; }
  .plan__lista { gap: .45rem; margin-bottom: 1.1rem; }

  /* Contacto: la visual pasa a absoluta al fondo para que la mano
     arranque desde el borde inferior de la pantalla. El inner
     colapsa a una sola columna para que el copy+form tomen el ancho libre.
     El contenido del lado izquierdo se escala para que quepa cómodamente
     con margen generoso arriba y abajo. */
  .contacto {
    position: relative;
    padding-block: clamp(3rem, 6vh, 5rem);
  }
  /* El copy+form se limitan al 56% del ancho para no solaparse con la mano
     absoluta. El aire entre título → texto → datos → formulario es generoso a
     propósito: la sección centra su contenido y el espacio sobrante se
     reparte en los huecos en lugar de acumularse todo abajo. */
  .contacto__titulo { font-size: clamp(1.9rem, min(4.2vw, 6vh), 3.2rem); }
  .contacto__inner { grid-template-columns: minmax(0, 1fr); }
  .contacto__copy { max-width: 56%; }
  .contacto__texto { font-size: .98rem; margin-top: clamp(1.1rem, 2.4vh, 1.7rem); max-width: 46ch; }
  .contacto__datos { font-size: .95rem; gap: .55rem; margin-top: clamp(1.2rem, 2.6vh, 1.8rem); }
  .form { margin-top: clamp(1.4rem, 3.2vh, 2.4rem); gap: .85rem; max-width: 100%; }
  .form__fila { gap: .85rem; }
  .campo__input { padding: .7rem 1rem; border-radius: 12px; font-size: .95rem; }
  .campo__input--area { min-height: clamp(3.2rem, 9vh, 5.2rem); }
  .campo { gap: .3rem; }
  .campo__label { font-size: .88rem; }
  .form__nota { font-size: .82rem; }
  /* La pila de tarjetas y la mano se posicionan absolutos al fondo-derecha
     para que la mano arranque exactamente desde el borde inferior. */
  .contacto__visual {
    position: absolute;
    bottom: 0;
    right: clamp(2rem, calc((100vw - var(--ancho)) / 2 + 2vw), 10vw);
    width: clamp(300px, 26vw, 430px);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-end;
  }
  .contacto__cards { width: 100%; }
  /* La mano crece hasta acercarse a la escala del PDF: el auricular sube
     junto al costado derecho de la tarjeta y la muñeca muere en el borde
     inferior de la pantalla. */
  .contacto__mano {
    width: clamp(150px, 23svh, 300px);
    margin-top: -38%;
    margin-left: 34%;
  }
  .porque__panel { padding-block: clamp(1.5rem, 4vh, 3.5rem); }
  .porque__logo { margin-bottom: clamp(1rem, 2.5vh, 2.2rem); }
  .porque__lista { gap: clamp(.8rem, 2vh, 1.8rem); }
  .porque__head { margin-bottom: clamp(1rem, 2.5vh, 2.5rem); }

  /* Al volverse grid la sección, los hijos con `margin-inline: auto` se
     encogen a su contenido en lugar de ocupar el ancho disponible.
     width:100% lo restituye. */
  .porque__cuerpo { width: 100%; }

  /* Notis: la foto tiene que tocar el borde inferior de la sección, así que
     esta sección no centra su contenido: lo estira. */
  .notis { align-content: stretch; }
  .notis__inner { height: 100%; }
  .notis__copy { align-self: center; }

}

/* Pantallas bajas (laptops de 700–860 px de alto): la sección de contacto es
   la única que seguía sin caber, y el culpable era el rows="4" del área de
   texto — define el alto real y min-height no lo reduce, así que aquí se fija
   con `height`. */
@media (min-width: 1024px) and (max-height: 860px) and (prefers-reduced-motion: no-preference) {
  /* Pantallas bajas: se aprieta más aún pero se preserva el aire. */
  .contacto { padding-block: clamp(2rem, 4vh, 3.5rem); }
  .contacto__titulo { font-size: clamp(1.4rem, 4vh, 2.2rem); }
  .contacto__texto  { font-size: .88rem; margin-top: .8rem; }
  .contacto__datos  { font-size: .86rem; gap: .28rem; margin-top: .9rem; }
  .form { margin-top: .9rem; gap: .5rem; }
  .form__fila { gap: .5rem; }
  .campo { gap: .2rem; }
  .campo__input { padding: .48rem .85rem; }
  .campo__input--area { height: clamp(2.5rem, 7vh, 3.8rem); min-height: 0; }
  .campo__label { font-size: .78rem; }
  .form__nota { font-size: .74rem; }
  .contacto__mano { width: clamp(120px, 19svh, 220px); }
}

/* ══════════════════════════════════════════════
   Presentación guiada por scroll
   Donde el navegador soporta animation-timeline, los reveals dejan de ser
   un disparo único y pasan a estar "scrubbed": el scroll dicta cuánto del
   contenido se muestra, como una presentación. Los delays escalonados se
   traducen a rangos de entrada progresivos. El observer de JS sigue
   funcionando por debajo como fallback (Safari viejo, etc.).
   ══════════════════════════════════════════════ */
@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {
    @keyframes presentacion-entrada {
      from { opacity: 0; transform: translateY(34px); }
      to   { opacity: 1; transform: none; }
    }
    .reveal {
      opacity: 1; transform: none; transition: none;
      animation: presentacion-entrada linear both;
      animation-timeline: view();
      animation-range: entry 8% entry 42%;
    }
    .reveal[data-reveal-delay="1"] { animation-range: entry 16% entry 52%; }
    .reveal[data-reveal-delay="2"] { animation-range: entry 24% entry 62%; }
    .reveal[data-reveal-delay="3"] { animation-range: entry 32% entry 72%; }
    .reveal[data-reveal-delay="4"] { animation-range: entry 40% entry 80%; }

    /* Los chips salen de atrás de la persona: recorrido horizontal. */
    @keyframes presentacion-chip {
      from { opacity: 0; transform: translateX(-45%); }
      to   { opacity: 1; transform: none; }
    }
    .chip-noti.reveal { animation-name: presentacion-chip; }

    /* La mano queda fuera del scrubbing a propósito: su entrada y su saludo
       son temporales (ver la regla .pasos__mano.reveal más arriba). */
  }
}

/* ══════════════════════════════════════════════
   Movimiento reducido
   ══════════════════════════════════════════════ */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
  .reveal { opacity: 1; transform: none; }
}
