:root {
  --bg: #000000;
  --ink: #ffffff;
  --pink: #f7c8cd;
  --nav-grey: #ddd9d6;

  /* casi blanco, con una pizca de cálido para que no choque con la tierra */
  --crema: #fbfaf7;

  /* cuánto se redondean las dos esquinas de abajo de la página cuando sube
     como telón sobre el pie (ver «EL TELÓN») */
  --radio-telon: clamp(20px, 3.2vw, 46px);
  --ink-crema: #1a1712;


  /* Tamaño del titular — el tronco y el halo se colocan en relación a él.
     10vw sale del borrador: la línea "HAZ FLORECER TU" mide 6.266em en Anton
     y ahí ocupa el 62.15% del ancho de página → 0.0980vw; la altura de
     mayúscula (0.87em) da 0.1020vw. Se toma el punto medio.
     El tope de 140px era lo que empequeñecía el titular: en una ventana de
     1822px recortaba de 182px a 140px (-24%). Ahora aguanta hasta 2100px. */
  /* Sin tope práctico: 10vw hasta los 384px de un 4K a escala 100%. La
     rama es 72,54vw y no puede capar (capada dejaría de sangrar por la
     izquierda), así que el titular tampoco: la composición del borrador
     —7,25 ramas por titular— se mantiene en cualquier monitor. */
  --fs-hero: clamp(44px, 10vw, 384px);

  /* ---- único mando del tronco: su anchura en pantalla ----
     La rama va tumbada (rotate 90deg), así que este valor es el ancho
     de la IMAGEN, que en pantalla se ve como su altura. El translate x/y
     se deriva solo, de modo que la punta derecha siempre cae en 94vw y la
     copa tapa la parte baja de NEGOCIO, sea cual sea el tamaño de ventana.
     Por debajo de 65.4vw deja de sangrar por la izquierda. */
  --tronco-w: 72.54vw;

  /* Borde inferior de la rama, en coordenadas de página. El alfa del tronco
     desnudo va de x=235 a x=806 de 1024, y al estar tumbada esa franja se ve
     como altura: (806-235)/1024 = 0.5576 del ancho de la imagen.
     Lo usa .section-2 para no colocar texto debajo de la rama. */
  /* ---- el aire sobre el titular ----
     En escritorio, cero: la composición del borrador arranca pegada a la
     cabecera. En el móvil, en cambio, la rama TIENE que entrar más abajo:
     es el único sitio donde el florecer se ve, porque no hay cursor que lo
     revele y quien mira solo tiene el dedo. Todo lo que cuelga del titular
     —la propia rama, el halo, el borde inferior del hero— suma este valor,
     así que moverlo mueve la composición entera de una pieza. */
  --hero-aire: 0px;

  /* La cresta de la rama, en coordenadas de página: el punto del que cuelga
     todo lo demás. */
  --rama-cima: calc(
    var(--cab) + var(--hero-aire) + 2.115 * var(--fs-hero)
  );

  --rama-fondo: calc(var(--rama-cima) + 0.5576 * var(--tronco-w));
  /* Dónde acaba el hero, en coordenadas de página. NO es «una pantalla»:
     es lo que esté más ARRIBA de (a) el borde inferior de la ventana y (b) el
     borde inferior de la rama más un respiro. En un escritorio 16:9 gana (a)
     —la rama se sale por debajo del pliegue y la sección 2 la esquiva—; en
     una tablet vertical o un monitor 4:3 gana (b), y así no queda media
     pantalla de negro vacío entre la rama y el manifiesto (en 912×1368
     eran 1.100 px de nada). El móvil usa la misma regla: allí (b) gana
     siempre. svh = la pantalla con la barra del navegador DESPLEGADA, que
     es la medida que no cambia al hacer scroll. */
  --hero-fondo: min(100vh, calc(var(--rama-fondo) + 24px));

  /* Alto real de la cabecera. Todo lo que se coloca desde arriba —la rama, el
     halo, el hero— cuelga de aquí. Lo remide script.js al cargar y al cambiar
     de tamaño: al plegarse a dos filas pasa de 121px a ~167px, y con el valor
     fijo la rama subía y tapaba «NEGOCIO» entero. */
  --cab: 121px;

  /* El radio del foco del reveal. Se queda en :root porque solo se escribe al
     redimensionar, no en cada fotograma; --mx y --my, que sí van a sesenta
     por segundo, viven en .reveal-layer (ver el comentario de tick() en
     script.js §1: escribirlas aquí invalidaba el estilo del documento
     entero, 4,5 ms de cada fotograma). */
  --spotlight-r: 260px;

  /* ---- zona clara ---- */
  --ink-crema-2: rgba(26, 23, 18, 0.66);   /* texto corrido */
  --ink-crema-3: rgba(26, 23, 18, 0.42);   /* apoyos y notas */
  --linea: rgba(26, 23, 18, 0.11);
  --rosa-hondo: #c2687a;
  --rosa-tinta: #96485a;

  /* La pastilla de la barra de scroll. Este par es el de los fondos oscuros
     —la página entera, el menú del móvil—; la zona clara lo cambia por el
     rosa hondo unas líneas más abajo. */
  --barra: rgba(247, 200, 205, 0.55);
  --barra-viva: rgba(247, 200, 205, 0.9);
  --verde: #7d9068;

  /* ── Escala de pantalla grande ──
     Hasta 1920 px vale 1 y NADA cambia: ese es el diseño aprobado. De ahí
     en adelante sube despacio —1,15 en 2560, 1,36 en 3440, 1,45 en 3840 (el
     tope)— y multiplica los TOPES de los clamp() de toda la página: la
     columna de texto, el ritmo vertical, los titulares, el cuerpo, las
     fichas, la tabla, el pie. Sin esto, en un monitor de 3440 px la web era
     una tira de 1180 px con letra de 16 px en medio de un descampado.

     Es un número sin unidad sacado del ancho de ventana con el truco
     tan(atan2()): atan2 admite dos longitudes y devuelve un ángulo, y la
     tangente de ese ángulo es su cociente, ya sin unidades. El @supports
     de abajo lo enciende solo donde el navegador lo entiende; si no, se
     queda en 1 y la página es la de siempre. */
  --esc: 1;

  --ancho: calc(1180px * var(--esc));
  /* aire vertical de cada sección; un solo mando para todo el ritmo */
  --paso-y: clamp(88px, 11vw, calc(168px * var(--esc)));

}

@supports (width: calc(1px * tan(atan2(100vw, 1px)))) {
  :root {
    --esc: clamp(1, 0.55 + 0.45 * tan(atan2(100vw, 1920px)), 1.45);
  }
}

/* Registrada como número: sin esto, getComputedStyle devuelve la fórmula
   en texto y script.js no puede leerla. Con ella, el radio del foco del
   tronco crece con la pantalla como todo lo demás. */
@property --esc {
  syntax: "<number>";
  inherits: true;
  initial-value: 1;
}

/* ── EL ALTO DE PANTALLA, CONGELADO ──
   `--vh-fijo` es lo que mide la pantalla, EN PÍXELES, medido una sola vez al
   cargar y actualizado solo si cambia el ANCHO (girar el teléfono, cambiar
   de ventana). Todo lo que ocupa sitio en la página —el hero, la franja de
   la pradera, el recorrido de la savia, los huecos del manifiesto— se mide
   con esto y no con la ventana de verdad.

   POR QUÉ, que es lo importante. Aquí antes se usaba `svh`, «la pantalla con
   la barra del navegador desplegada», con la idea de que no cambia mientras
   se hace scroll. En SAFARI es verdad, y por eso Sara no ve saltos ahí. En
   CHROME y BRAVE de iPhone no: esos navegadores no dejan la página quieta
   debajo de su barra, sino que REDIMENSIONAN la ventana entera al esconderla,
   así que svh, lvh y vh cambian los tres a la vez. Y como la savia mide 380
   pantallas de recorrido, 60 px de barra se convertían en ~290 px de
   documento que aparecían y desaparecían en cada cambio de dirección del
   dedo: toda la mitad de abajo de la web dando botes. Medido con
   `barra-navegador.mjs`: 335 px de brinco en el diagnóstico, 395 en el pie.

   Con un número en píxeles no hay nada que recalcular: la barra puede
   esconderse las veces que quiera, que la página mide lo mismo. En Safari y
   en escritorio no cambia nada, porque el número es exactamente el que
   daba svh.

   El valor de aquí abajo es solo la red por si el script no llega a
   escribirlo: entonces la web se comporta como antes. */
:root {
  --vh-fijo: 100vh;
  --vh-plano: 100vh;
}

@supports (height: 100svh) {
  :root {
    --vh-fijo: 100svh;
    --vh-plano: 100lvh;
  }
}

:root {
  --hero-fondo: min(var(--vh-fijo), calc(var(--rama-fondo) + 24px));
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

/* Chrome y Brave en Android INFLAN el texto por su cuenta («font boosting»)
   cuando creen que la página no está adaptada: todo salía enorme y cortado
   en el móvil aunque las medidas fueran correctas. Esto lo apaga: el tamaño
   lo decide esta hoja, no el navegador. */
html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  /* sin el destello azulado del toque: los estados de cada control ya dan su
     propia respuesta, y en la tabla ampliada el destello parecía un recuadro
     roto (móvil de Sara, 1 sep) */
  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
  /* el tirón hacia abajo con la página ya arriba no debe recargar la web:
     en los navegadores de móvil con «tirar para recargar», un salto del
     scroll durante la lectura acababa recargando sin querer */
  overscroll-behavior-y: contain;
}

body {
  background: var(--bg);
  color: var(--ink);
  font-family: "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
  -webkit-font-smoothing: antialiased;
}

html {
  scroll-behavior: smooth;
  /* el nav es fijo en la práctica sobre el hero; deja aire al saltar a un ancla */
  scroll-padding-top: 40px;
  /* el canalón de la barra de scroll se reserva siempre: al abrir una
     ventana Lenis para la página con overflow: clip, la barra desaparecía
     y todo lo de detrás del velo daba un salto de 9px a la derecha */
  scrollbar-gutter: stable;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
}

/* ---------- La barra de scroll ----------

   La de serie es gris de sistema y con sus dos flechitas en las puntas: sobre
   el negro de esta web canta. Aquí es una pastilla fina y redondeada del rosa
   de la marca, a un tercio de opacidad para que acompañe sin gritar, y más
   viva cuando el ratón la toca. El borde transparente hace de margen: la
   pastilla mide 6 px y flota en medio del carril en vez de tocar los bordes.

   El color no está fijo, va en --barra. Los pseudoelementos de la barra
   heredan las variables del elemento que se desplaza, así que con una sola
   regla la pastilla sale pálida sobre los fondos negros (la página, el menú
   del móvil) y oscura sobre los claros (las ventanas legales, la tabla de
   precios), que es donde el rosa pálido no se vería.

   Va por duplicado a propósito. Chrome, Edge, Brave y Safari solo entienden
   los pseudoelementos ::-webkit-scrollbar; Firefox solo entiende las dos
   propiedades estándar. Y no valen las dos a la vez: en cuanto Chromium ve
   un `scrollbar-color`, IGNORA los pseudoelementos y se pierde el redondeo.
   Por eso el @supports pregunta justo eso —«¿entiendes el selector?»— y cada
   navegador se queda solo con su mitad. */

::-webkit-scrollbar {
  width: 12px;
  height: 12px;
}

::-webkit-scrollbar-track {
  background: transparent;
}

::-webkit-scrollbar-thumb {
  border: 3px solid transparent;
  background-clip: content-box;
  background-color: var(--barra);
  border-radius: 999px;
}

@media (hover: hover) {
  ::-webkit-scrollbar-thumb:hover {
    background-color: var(--barra-viva);
  }
}

/* las flechitas de las puntas, fuera */
::-webkit-scrollbar-button {
  display: none;
}

::-webkit-scrollbar-corner {
  background: transparent;
}

@supports (scrollbar-width: thin) and (not selector(::-webkit-scrollbar)) {
  html {
    scrollbar-width: thin;
  }
  /* `scrollbar-color` se hereda ya resuelto, así que la zona clara tiene que
     volver a declararlo para que recoja SU --barra y no la de la raíz. */
  html,
  .claro {
    scrollbar-color: var(--barra) transparent;
  }
}


/* ---------- Lenis ----------
   Las cuatro reglas que la librería necesita para funcionar. Van aquí en vez
   de en un CSS aparte para no pedir un archivo más.
   La primera es la importante: con scroll-behavior: smooth activo, el navegador
   y Lenis se pelean por la posición y el scroll da tirones. */
html.lenis,
html.lenis body {
  height: auto;
}

.lenis:not(.lenis-autoToggle).lenis-smooth {
  scroll-behavior: auto !important;
}

.lenis.lenis-smooth [data-lenis-prevent] {
  overscroll-behavior: contain;
}

/* LA REGLA DE LENIS QUE NO ESTÁ: `.lenis-stopped { overflow: clip }`.

   Viene en la hoja que reparte Lenis y aquí hacía más mal que bien. Al parar
   el scroll —abrir una ventana legal, o cada vez que ScrollTrigger vuelve a
   medir— `overflow: clip` deja de tratar el documento como contenedor de
   scroll: desaparece la barra, el `scrollbar-gutter: stable` de arriba ya no
   reserva nada, y la página entera se ensancha 15 px DE GOLPE. Medido:
   clientWidth 1425 → 1440 al abrir el diálogo y 1440 → 1425 al cerrarlo. Eso
   era el salto y el parpadeo de la enredadera del canalón: no se movía ella,
   se movía la página debajo.

   Y no hace falta. Con la ventana abierta el propio <dialog> modal bloquea el
   scroll de la página (rueda, teclado y barra), y Lenis parado ya se traga
   rueda y dedo por su cuenta. `overflow: clip` solo añadía el salto.

   Se prueba así: abrir una ventana legal, intentar mover la rueda y las
   flechas, y comprobar que scrollY no cambia ni un píxel. */

/* Recorta el tronco, que sobresale por los lados a propósito.
   Tiene que ser `clip` y no `hidden`: `hidden` convierte esta caja en un
   contenedor de scroll, y dentro de un contenedor de scroll el
   `position: sticky` del plano de la savia deja de pegarse — la sección
   entera pasaba de largo sin quedarse fija. `clip` recorta igual pero no
   crea contenedor. El eje vertical se deja visible porque no hay nada que
   recortar ahí y así el navegador no tiene ni que planteárselo. */
.page {
  position: relative;
  overflow-x: clip;
  overflow-y: visible;
}

/* ── RED PARA LOS SAFARI ANTERIORES AL 16, que no entienden `clip` ──
   Ahí la declaración de arriba se cae y la página queda 978 px de ancha en
   un teléfono de 390 (medido quitando el recorte). En los motores que se
   pueden probar hoy eso NO llega a poderse arrastrar de lado, así que el
   fallo no se ha podido reproducir; pero como el respaldo no cuesta nada
   —el @supports es falso en todo lo moderno, así que ni se lee— se deja
   puesto por si acaso.

   Va en <html> a propósito y NO en .page: en .page haría de contenedor de
   scroll y se llevaría por delante el plano fijo de la savia, que es
   justamente lo que se evitó eligiendo `clip`. Comprobado que con esto el
   plano sigue pegado arriba (`clip-respaldo.mjs`). */
@supports not (overflow: clip) {
  html {
    overflow-x: hidden;
  }
}

/* ---------- Header ---------- */

.header {
  position: relative;
  z-index: 3;
  /* 3 columnas: el nav va centrado en la página de verdad, sin que le
     afecte lo que ocupen el logo o el botón. */
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 24px;
  /* El relleno lateral crece solo cuando la ventana es mucho más ancha que
     la columna de texto: hasta 1920 px el segundo término sale por debajo
     de 32 y manda el clamp de siempre; en un monitor de 3440, el logotipo
     y el botón se quedan a 360 px de la columna en vez de pegados a unas
     esquinas que están a medio metro del contenido (el 100% es el ancho
     del bloque contenedor, o sea la página). */
  --canalon-cab: max(clamp(20px, 3vw, 32px), calc((100% - var(--ancho)) / 2 - 360px));
  padding: 34px var(--canalon-cab);
  /* ── LA MUESCA, DE LADO ──
     El <meta viewport> lleva `viewport-fit=cover`, o sea que la página llega
     hasta el borde físico de la pantalla. De pie eso solo afecta arriba, y
     ya está resuelto; TUMBADO, la muesca y el redondeo se ponen a un lado y
     se comen unos 44 px: el logotipo por la izquierda o la hamburguesa por
     la derecha quedaban medio tapados, porque el canalón normal ahí son 25.
     Con el max() el relleno crece solo lo que haga falta, y en un teléfono
     sin muesca env() vale 0 y no cambia nada. */
  padding-left: max(var(--canalon-cab), env(safe-area-inset-left, 0px));
  padding-right: max(var(--canalon-cab), env(safe-area-inset-right, 0px));
}

/* ── La cabecera flotante ──
   El clon que crea script.js §0: fijo, escondido un piso por encima del
   borde, y baja SOLO cuando el scroll va hacia arriba (§10). Fondo casi
   negro con desenfoque: pasa por encima de zonas claras y oscuras y se lee
   en ambas. La original nunca se fija — fijarla desplazaría la página
   entera y descuadraría los disparadores de scroll. */
.header-flotante {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 9;
  background: rgba(8, 7, 6, 0.94);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  padding-block: 14px;
  /* bajo el notch, no detrás de él */
  padding-top: calc(14px + env(safe-area-inset-top, 0px));
  transform: translateY(-102%);
  /* visibility además del transform: escondido solo por posición, sus
     enlaces seguían en el orden del tabulador y el lector de pantalla, y
     su panel de móvil abierto se quedaba huérfano en pantalla al
     retirarse la cabecera. La visibilidad se apaga al TERMINAR de subir
     (el retardo), y se enciende al instante al bajar. */
  visibility: hidden;
  transition: transform 0.45s cubic-bezier(0.22, 1, 0.36, 1),
    visibility 0s 0.45s;
}

.header-flotante.flotante-vista {
  transform: translateY(0);
  visibility: visible;
  transition: transform 0.45s cubic-bezier(0.22, 1, 0.36, 1);
}

/* Una línea de luz bajo la cabecera, encendida en el centro y apagándose
   hacia los lados, con una gota rosa en medio: separa la cabecera del hero
   sin dibujar una caja, que era lo que le faltaba a tanto negro. */
.header::after {
  content: "";
  position: absolute;
  left: clamp(20px, 6vw, 90px);
  right: clamp(20px, 6vw, 90px);
  bottom: 0;
  height: 1px;
  opacity: 1;
  background: linear-gradient(
    90deg,
    transparent 0%,
    rgba(255, 255, 255, 0.14) 22%,
    rgba(247, 200, 205, 0.5) 50%,
    rgba(255, 255, 255, 0.14) 78%,
    transparent 100%
  );
  pointer-events: none;
}

/* Con el menú desplegado, esa línea deja de separar la cabecera del hero y
   pasa a ser una raya suelta entre el logotipo y la lista de secciones —con
   su gota rosa en medio, que ahí no pinta nada—. Fuera mientras el panel
   está abierto; vuelve al cerrarlo. (Sara: «qué mal ahí arriba en el
   menú», 1 sep.) */
.header.menu-abierto::after {
  opacity: 0;
}

/* ── El logotipo ──
   Solo letra: Playfair Display, la serif de moda de contraste fino, con la
   & caligráfica en cursiva y en rosa — siempre en rosa, esté donde esté.
   El color del nombre lo pone el contexto: blanco aquí (fondo negro),
   tinta en el pie (fondo claro). Sin flores ni iconos: la marca ES la
   palabra. */
.logo {
  font-family: "Playfair Display", "Libre Baskerville", Georgia, serif;
  font-weight: 500;
  font-size: calc(23px * var(--esc));
  letter-spacing: 0.01em;
  color: var(--ink);
  text-decoration: none;
  white-space: nowrap;
}

/* La & es de OTRA fuente a propósito: la de Bodoni Moda — lazo pequeño
   arriba, panza grande abajo, cola fina — que es la del logotipo de
   referencia. Se compararon nueve ampersands en vivo y esta era la
   clavada; la de Playfair (cursiva o recta) no se parecía. */
.amp {
  font-family: "Bodoni Moda", "Playfair Display", serif;
  font-style: normal;
  font-weight: 500;
  color: var(--pink);
  padding-inline: 1px;
}

.nav {
  display: flex;
  align-items: center;
  justify-self: center;
  gap: clamp(18px, 3.2vw, calc(56px * var(--esc)));
}

/* El subrayado germina desde la izquierda, como los enlaces del formulario:
   es el mismo gesto de la casa, y llena el hover de algo más que un cambio
   de gris. Va en rosa: sobre el negro es la firma de la marca. */
.nav a {
  font-family: "Oswald", sans-serif;
  font-weight: 300;
  /* Entre 900 y 1300 px la cabecera de escritorio tiene que caber con sus
     cinco palabras y el botón: a 22 px fijos, en una tablet apaisada de
     1024 px la fila iba al límite. Fluida, en 912 px va a 17 y en 1300
     recupera los 22 del diseño. */
  font-size: clamp(17px, 1.75vw, calc(22px * var(--esc)));
  letter-spacing: 0.03em;
  color: var(--nav-grey);
  text-decoration: none;
  background: linear-gradient(var(--pink), var(--pink)) 0 100% / 0 1px
    no-repeat;
  padding-bottom: 3px;
  transition: color 0.25s ease,
    background-size 0.45s cubic-bezier(0.22, 1, 0.36, 1);
}

@media (hover: hover) {
  .nav a:hover {
    color: var(--ink);
    background-size: 100% 1px;
  }
}

/* el Contactar del panel de móvil: en escritorio no existe, ahí ya está el
   botón de la derecha */
.nav-contacto {
  display: none;
}

@media (max-width: 900px) {
  .nav-contacto {
    display: block;
  }
}

/* ---------- La hamburguesa ----------
   Solo existe en móvil (el media de abajo la enseña). Tres rayitas que al
   abrir se convierten en una equis: la de arriba y la de abajo se cruzan y
   la del medio se esfuma. */
/* ---------- La hamburguesa ----------
   Ni caja, ni borde, ni tres rayitas iguales: eso es el icono de todas las
   webs del mundo y aquí la marca es la letra y la planta. Son TRES TRAZOS
   QUE MENGUAN —26, 18 y 10— con el de en medio en rosa: leídos de arriba
   abajo dibujan un tallito con su hoja, y de un vistazo siguen diciendo
   «menú» porque la forma general es la de siempre. Alineados a la derecha,
   contra el canto, como una firma.

   La diana sigue midiendo 44×44 (el mínimo táctil): lo que se ha ido es el
   recuadro pintado, no el sitio donde se puede tocar. */
.menu-btn {
  display: none;
  flex-direction: column;
  align-items: flex-end;
  justify-content: center;
  gap: 6px;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  justify-self: end;
  -webkit-tap-highlight-color: transparent;
}

/* CORTO Y SECO, no lento y elegante. Estos trazos medían 0,45 s con una
   curva de cola larguísima (easeOutQuint): la vuelta empezaba rápida y
   luego se arrastraba, y los dos trazos se pasaban esa cola pareciendo
   rayas horizontales a medio girar. Sara, tres veces: «la raya horizontal
   tarda en irse», «un segundo de más». No era una raya que sobrara: era
   esta animación acabando tarde. 0,24 s y una curva sin cola: la equis se
   hace y se deshace de una vez. */
.menu-btn span {
  display: block;
  height: 1.5px;
  border-radius: 2px;
  background: rgba(255, 255, 255, 0.92);
  transition: width 0.24s cubic-bezier(0.4, 0, 0.2, 1),
    transform 0.24s cubic-bezier(0.4, 0, 0.2, 1),
    background 0.18s ease, opacity 0.14s ease;
}

.menu-btn span:nth-child(1) {
  width: 26px;
}

/* la hoja: el único trazo en color, y el que desaparece al abrir */
.menu-btn span:nth-child(2) {
  width: 18px;
  background: var(--pink);
}

.menu-btn span:nth-child(3) {
  width: 10px;
}

/* Al abrir, los tres se igualan y los extremos se cruzan. Se igualan
   PRIMERO —de ahí que `width` esté en la transición— para que la equis
   salga simétrica y no un aspa coja. */
.menu-btn:focus-visible {
  outline: 2px solid var(--pink);
  outline-offset: 6px;
  border-radius: 4px;
}

.menu-abierto .menu-btn span:nth-child(1) {
  width: 24px;
  transform: translateY(7.5px) rotate(45deg);
}

.menu-abierto .menu-btn span:nth-child(2) {
  width: 24px;
  opacity: 0;
  /* visibility además de opacity: en el WebKit viejo del iPhone de Sara el
     fundido no llegaba a aplicarse y la hoja rosa se quedaba cruzada sobre
     la equis (foto del 1 sep). SIN retraso: con él, la raya se quedaba un
     cuarto de segundo cruzada y se leía como tirón (aviso suyo, mismo día).
     La equis se forma igual de limpia con la hoja fuera desde el primer
     fotograma. */
  visibility: hidden;
  transition: width 0.24s cubic-bezier(0.4, 0, 0.2, 1),
    transform 0.24s cubic-bezier(0.4, 0, 0.2, 1),
    background 0.18s ease, opacity 0.14s ease, visibility 0s;
}

.menu-abierto .menu-btn span:nth-child(3) {
  width: 24px;
  background: rgba(255, 255, 255, 0.92);
  transform: translateY(-7.5px) rotate(-45deg);
}

.btn-contactar {
  font-family: "Oswald", sans-serif;
  font-weight: 400;
  font-size: calc(15px * var(--esc));
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: rgba(255, 255, 255, 0.82);
  text-decoration: none;
  justify-self: end;

  /* cristal muy sutil: casi solo el borde */
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.16);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  border-radius: 999px;
  padding: calc(14px * var(--esc)) clamp(22px, 3vw, calc(42px * var(--esc)));
  white-space: nowrap;
  transition: background 0.25s ease, border-color 0.25s ease, color 0.25s ease,
    transform 0.25s ease;
}

@media (hover: hover) {
  .btn-contactar:hover {
    transform: translateY(-1px);
    background: rgba(255, 255, 255, 0.11);
    border-color: rgba(255, 255, 255, 0.3);
    color: #fff;
  }
}

/* ---------- Hero ---------- */

.hero {
  position: relative;
  z-index: 1;
  /* ni 100vh ni un número: hasta donde diga --hero-fondo (ver :root) */
  min-height: calc(var(--hero-fondo) - var(--cab));
  display: flex;
  align-items: flex-start;
  justify-content: center;
  /* El aire sobre el titular va en em del propio titular, no en px, para que
     la composición del borrador se mantenga al cambiar el ancho de ventana. */
  padding: calc(var(--hero-aire) + 0.415 * var(--fs-hero))
    clamp(20px, 4vw, 48px) 0;
}

/* ---------- Sección 2 — la promesa y el manifiesto ---------- */

.section-2 {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  /* El texto tiene que empezar POR DEBAJO de la rama, y la rama baja bastante
     dentro de esta sección. --rama-fondo es su borde inferior en coordenadas
     de página; restándole el alto del hero se sabe cuánto invade.
     El max(0px, …) cubre el caso de que no invada nada. */
  padding: calc(
      max(0px, var(--rama-fondo) - var(--hero-fondo)) + clamp(48px, 9vh, 110px)
    )
    clamp(24px, 6vw, 80px) clamp(90px, 15vh, 190px);
  /* SVH Y NO VH — la regla que ordena toda esta hoja desde el 1 sep 2026.
     En el móvil, `vh` es la pantalla CON la barra del navegador recogida, y
     esa barra se esconde y asoma con cada cambio de dirección del dedo: cada
     pasada recalculaba estos huecos y toda la página de abajo daba un brinco
     mientras se leía (vídeos de Sara en Brave y Safari). `svh` es la pantalla
     con la barra puesta y NO cambia nunca durante el scroll, así que el
     trazado se queda quieto. En escritorio las dos miden lo mismo: cero
     cambio. La línea de arriba queda de red para navegadores sin svh. */
  padding: calc(
      max(0px, var(--rama-fondo) - var(--hero-fondo)) + clamp(48px, calc(var(--vh-fijo) * 0.09), 110px)
    )
    clamp(24px, 6vw, 80px) clamp(90px, calc(var(--vh-fijo) * 0.15), 190px);
  /* fondo explícito para que el mix-blend-mode del vídeo tenga contra qué
     mezclarse; sin él la mezcla queda sin definir */
  background: var(--bg);
  overflow: hidden;
}

.s2-cuerpo {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(80px, 15vh, 190px);
  gap: clamp(80px, calc(var(--vh-fijo) * 0.15), 190px); /* svh: ver .section-2 */
  width: 100%;
}

/* ---------- La firma ----------
   Sin caja, sin borde, sin sombra y sin resplandor: negro y letra. Lo único
   que hay alrededor es sitio, que es lo que la hace parecer una firma y no
   un logotipo. El trazado del lettering va dentro del SVG en index.html. */

.firma {
  width: min(calc(820px * var(--esc)), 100%);
  /* un pelín más abajo que el resto del bloque: la firma tiene que caer
     separada, como se firma al pie de una carta */
  margin-top: clamp(24px, 6vh, 76px);
  margin-top: clamp(24px, calc(var(--vh-fijo) * 0.06), 76px); /* svh: ver .section-2 */
}

.firma-svg {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}

/* Marfil, no blanco puro: sobre negro el blanco puro vibra, y una firma
   tiene que reposar. */
.firma-tinta {
  fill: #ece5d8;
  fill-opacity: 0.9;
}

/* La línea que escribe. Va por delante de la tinta y es la que se ve
   trazando. Como sigue la línea MEDIA de cada letra, en cuanto la tinta la
   alcanza se queda dentro del trazo y desaparece sola: solo se ve por
   delante de la punta, que es donde tiene que verse. */
.firma-pluma {
  fill: none;
  stroke: #f6f1e7;
  /* non-scaling-stroke: el grosor va en píxeles de pantalla, no en unidades
     del dibujo. Sin esto la línea salía de 1,6px en el escritorio y de 0,7
     en el móvil —o sea, medio invisible justo donde más pequeña es. */
  vector-effect: non-scaling-stroke;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Con JS la firma empieza sin escribir, y hasta que script.js reparte las
   longitudes de cada trazo el SVG no se enseña: si no, se vería un
   fotograma con la firma entera antes de borrarse. Sin JS —o si GSAP no
   carga— no hay clase .js y se ve escrita, que es el estado correcto. */
.js .firma-svg {
  opacity: 0;
}

.js .firma-svg.lista {
  opacity: 1;
}

/* Sin JS no hay nada que trazar: la máscara está entera (los trazos no
   llevan dash hasta que los pone script.js) y la firma se ve escrita. La
   línea de la pluma sí sobra, porque se quedaría fija encima. */
html:not(.js) .firma-pluma {
  display: none;
}

/* sin JS nadie escribe --barrido: la rama vestida, puesta */
html:not(.js) .reveal-layer {
  --barrido: 135%;
}

/* La firma mide casi seis de ancho por uno de alto. En el móvil, si respeta
   el padding de la sección se queda en un hilo: aquí se lo come para
   recuperar esos píxeles, que en una firma tan apaisada son un 20% de alto. */
@media (max-width: 700px) {
  .firma {
    width: calc(100% + 32px);
    margin-inline: -16px;
  }
}

.manifiesto {
  position: relative;
  z-index: 1;
  font-family: "Libre Baskerville", Georgia, serif;
  font-weight: 400;
  font-size: clamp(24px, 3.5vw, calc(54px * var(--esc)));
  line-height: 1.42;
  letter-spacing: -0.01em;
  text-align: center;
  max-width: 18em;
  color: rgba(255, 255, 255, 0.94);
  text-wrap: balance;
}

.manifiesto em {
  font-style: italic;
  color: var(--pink);
}

/* Cada línea sube desde detrás de su propia máscara. El overflow del
   envoltorio es lo que hace el efecto: el texto existe siempre, solo que
   empieza fuera de su caja. */
.manifiesto .ln {
  display: block;
  overflow: hidden;
  /* si no, las tildes y las colas de las 'j' se recortan por arriba/abajo */
  padding: 0.06em 0.08em;
  margin: -0.06em -0.08em;
}

.manifiesto .ln > span {
  display: block;
}

/* Sin JS las líneas se ven tal cual. Con JS empiezan escondidas debajo de su
   máscara y las sube GSAP — de ahí que no haya transition: la tendría que
   pelear con el tween. */
.js .manifiesto .ln > span {
  transform: translateY(115%);
  opacity: 0;
}

/* ---------- Pétalos cayendo (sección 2) ---------- */

.petalos {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;

  /* El vídeo solo tiene negro (99.5% de los píxeles) y pétalos. En screen el
     negro es neutro, así que no hay caja ni borde: solo aparecen las flores. */
  mix-blend-mode: screen;
  opacity: 0.85;

  pointer-events: none;
  -webkit-user-select: none;
  user-select: none;
}

/* Solo la tanda de la sección 2 entra con fundido: aparecen justo donde acaba
   el tronco, para que parezca que caen de él. Antes también se apagaban al
   final (88%→100%), y eso, sumado al bloque de tierra sin pétalos, dejaba un
   hueco oscuro largo antes del suelo. Ahora bajan hasta abajo del todo y lo
   que las detiene es la propia tierra. */
/* Dónde termina de aparecer la lluvia de pétalos.

   En pantalla grande, 30vh, que es lo que había y funciona: la rama baja
   mucho dentro de esta sección y para entonces los pétalos ya están cayendo
   de ella.

   En pantalla pequeña, no. Ahí la rama apenas entra —68px en un móvil de
   430px— y esa misma rampa de 280px dejaba los pétalos empezando 210px MÁS
   ABAJO de donde acaba la rama: un descampado negro entre la rama y la
   primera flor que cae. `--rama-fondo` menos `--hero-fondo` es exactamente
   cuánto invade la rama esta sección, así que ahí se planta el final de la
   rampa y los pétalos arrancan pegados a la rama. De ahí siguen cayendo
   hasta abajo del todo, que es donde empieza el suelo que se siembra.

   El max() es por si en algún tamaño la rama no invadiera nada: sin él la
   rampa se quedaría en cero y los pétalos aparecerían de golpe. */
.section-2 {
  --petalos-desde: 30vh;
  --petalos-desde: calc(var(--vh-fijo) * 0.3); /* svh: ver .section-2 */
}

@media (max-width: 900px) {
  .section-2 {
    --petalos-desde: max(48px, calc(var(--rama-fondo) - var(--hero-fondo)));
  }
}

/* Y también se desvanece POR ABAJO, en los últimos 110px. El negro del
   vídeo no es negro puro (la compresión lo deja en un gris de 5-6 sobre
   255, que el modo screen encima aclara), así que donde el vídeo terminaba
   en seco se veía una raya horizontal de lado a lado contra el negro de la
   pradera — y los pétalos que caían por ahí se cortaban por la mitad. Con
   la rampa, el vídeo se apaga antes de llegar al canto y los pétalos se
   desvanecen en vez de cortarse. */
.section-2 > .petalos {
  -webkit-mask-image: linear-gradient(
    180deg,
    transparent 0,
    #000 var(--petalos-desde),
    #000 calc(100% - 110px),
    transparent 100%
  );
  mask-image: linear-gradient(
    180deg,
    transparent 0,
    #000 var(--petalos-desde),
    #000 calc(100% - 110px),
    transparent 100%
  );
}

@media (prefers-reduced-motion: reduce) {
  .petalos {
    display: none;
  }
}

/* ---------- La pradera ---------- */

/* ── La pradera ──
   El separador entre el manifiesto y el diagnóstico. Dos fotos sobre negro
   puro en dos capas.

   La escena entra ENTERA A LO ALTO, no recortada por arriba: las capas se
   dimensionan por altura (un poco más altas que la caja, para que el
   paralaje tenga recorrido) y el ancho sale solo de la proporción de cada
   foto. En una pantalla ancha quedan huecos a los lados — y no se ven,
   porque las fotos ya se funden a negro puro en sus bordes: la escena
   flota centrada en la oscuridad, como un plano de cine. En el móvil pasa
   lo contrario, sobra foto por los lados, y el recorte centrado deja las
   flores en pantalla.

   Las capas se centran con márgenes automáticos (left:0 + right:0 +
   margin auto), NO con transform: el transform es del paralaje —GSAP
   escribe ahí el viaje vertical— y cualquier centrado que viviera en la
   misma propiedad acabaría sumado o pisado. Cada cosa en su sitio y no
   se estorban.

   El alto mira también al ANCHO de la ventana (26vw): la escena crece con
   la pantalla y no se queda en viñeta pequeña en un monitor grande. */
/* La caja NO recorta NI POR ARRIBA NI POR ABAJO — idea de Sara, y es la
   buena: lo que sobresalga de las fotos pasa POR ENCIMA de lo que hay
   alrededor (el vídeo de pétalos arriba, la noche del diagnóstico abajo) en
   vez de cortarse en seco contra el canto de la franja. Solo se cierran los
   lados, que en el móvil sí hay que recortar.

   ESTE ERA EL CORTE. El suelo cerrado era el fallo que Sara veía en TODAS
   las pantallas —monitor grande, portátil, teléfono, cualquier navegador—:
   el paralaje baja las fotos, el suelo de la franja las cortaba a media
   tierra y quedaba una raya recta de luz contra el negro. No era que el
   paralaje bajara «demasiado»; era que había un techo donde cortarse. Sin
   suelo, la tierra sigue bajando y se apaga sola: la foto termina en negro
   puro (medido: el último 8 % de alto no pasa de 8 sobre 255) y ese negro,
   en modo screen, no pinta nada. Nada de velos ni fundidos encima de sus
   fotos: solo quitar la tijera.

   Para que ese sobrante se vea hay que pasar por delante de la zona clara
   (z-index 5 contra su 4). No tapa nada: lo que asoma por debajo son las
   filas negras de la foto, y en modo screen negro sobre negro suma cero.
   Lo que baja más —la tierra iluminada— se queda a 40 px del titular del
   diagnóstico en escritorio y a 31 en el teléfono.

   Y la franja entera va en modo screen, sin fondo propio: todo lo negro se
   vuelve transparente, así que el cielo casi-negro de las fotos no tapa
   los pétalos que caen por detrás —se ven a través— y ningún borde de
   foto puede dibujar una línea, porque un borde de negro sobre negro
   suma cero. No es un filtro sobre las fotos: es la misma mezcla que ya
   traía la capa de flores, aplicada al conjunto. */
.pradera {
  position: relative;
  z-index: 5;
  height: clamp(240px, max(40vh, 26vw), 540px);
  /* svh (ver .section-2): con vh, esta franja crecía y encogía ~50px cada
     vez que la barra del navegador del móvil se escondía, y como está en el
     flujo, TODO lo que hay debajo —diagnóstico, savia, precios, pie— se iba
     con ella. Era el brinco más gordo de la mitad de arriba. */
  height: clamp(240px, max(calc(var(--vh-fijo) * 0.4), 26vw), 540px);
  clip-path: inset(-75% 0 -45% 0);
  mix-blend-mode: screen;
  /* va por delante de la zona clara: que no le robe ni un clic */
  pointer-events: none;
}

.pradera img {
  position: absolute;
  left: 0;
  right: 0;
  bottom: -2%;
  width: auto;
  margin-inline: auto;
  pointer-events: none;
  -webkit-user-select: none;
  user-select: none;
}

/* SIN velos ni fundidos encima de las fotos — decisión de Sara, y con
   razón: apagaban sus flores. El hueco que las separa del vídeo de arriba
   es negro de verdad: sale de que las fotos son más ALTAS que la franja,
   así que su borde de arriba queda siempre fuera de la caja, se muevan lo
   que se muevan. Y por abajo ya no hay nada que cuadrar: la franja no
   tiene suelo (ver .pradera) y lo que sobresale se apaga solo. */
.pradera-fondo {
  height: 116%;
}

/* Las flores son lo cercano. En modo screen: el negro de la foto
   desaparece y el fondo se ve entre los tallos. */
.pradera-flores {
  height: 124%;
  mix-blend-mode: screen;
}

/* Aquí vivía un apaño solo para el teléfono —fotos más altas y ancladas
   más abajo— que perseguía el corte de la raya en vez de su causa. Con la
   franja sin suelo el corte no existe en ninguna pantalla, así que se ha
   quitado: una sola geometría para todas, que es una cosa menos que se
   puede descuadrar. */

.tronco {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 2;
  width: var(--tronco-w);
  height: auto;
  transform-origin: 0 0;
  /* 98vw = punta derecha casi tocando el borde.
     El 0.22949 (= 235/1024, el borde del alfa del tronco DESNUDO, que es la
     capa que se ve por defecto) cancela el término de anchura: la cresta cae
     siempre en 121px + 2.115em, sea cual sea --tronco-w. Como la base de
     NEGOCIO está en 121px + 2.415em, la rama tapa el tercio inferior de la
     palabra (0.30em de los 0.87em de altura de mayúscula) y aún se lee. */
  transform: translate(
      calc(98vw + 0.03711 * var(--tronco-w)),
      calc(var(--rama-cima) - 0.22949 * var(--tronco-w))
    )
    rotate(90deg);
  pointer-events: none;
  -webkit-user-select: none;
  user-select: none;
}

/* ---------- Reveal ---------- */

/* Cubre toda la página; el tronco vestido va dentro con el mismo
   transform, así el foco se dibuja en coordenadas de página y no gira. */
.reveal-layer {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;

  /* el foco nace fuera de pantalla; lo mueve script.js §1 escribiendo AQUÍ
     —no en :root— para no invalidar el estilo de todo el documento */
  --mx: -9999px;
  --my: -9999px;

  --spotlight: radial-gradient(
    circle var(--spotlight-r) at var(--mx) var(--my),
    rgba(0, 0, 0, 1) 0%,
    rgba(0, 0, 0, 1) 40%,
    rgba(0, 0, 0, 0.75) 60%,
    rgba(0, 0, 0, 0.4) 75%,
    rgba(0, 0, 0, 0.12) 88%,
    rgba(0, 0, 0, 0) 100%
  );
  -webkit-mask-image: var(--spotlight);
  mask-image: var(--spotlight);
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
}

/* ── El tronco florece con el scroll donde no hay cursor ──
   El foco que sigue al ratón no existe en una pantalla táctil, y eso no
   va por anchura: un iPad apaisado mide 1024 px y no tiene ratón. Así que
   la cortina (--barrido, la escribe script.js §1) se usa en dos casos: la
   pantalla es estrecha, O el dispositivo no sabe lo que es pasar el ratón
   por encima. En los dos la rama se viste de musgo y flores al bajar.

   VA DESPUÉS de la regla base de .reveal-layer, y no es casualidad: tienen
   la misma especificidad y gana la última. Puesta antes, el foco del ratón
   la pisaba y en todos los móviles la rama se quedaba desnuda (el foco
   espera a -9999px un ratón que nunca llega).

   mask-size: la capa cubre la PÁGINA entera (inset: 0 de .page), y los
   porcentajes de un degradado se miden sobre la caja que lo lleva: sobre
   doce mil píxeles de alto la cortina terminaba en el primer cuarto del
   recorrido y a un ritmo que dependía de lo larga que fuera la página.
   Con la máscara medida a la caja del hero, el 100% es el hero. */
@media (max-width: 900px), (hover: none) {
  .reveal-layer {
    --barrido: 0%;
    --spotlight: linear-gradient(
      100deg,
      #000 0,
      #000 calc(var(--barrido) - 16%),
      transparent var(--barrido)
    );
    -webkit-mask-size: 100% calc(var(--rama-fondo) + 24px);
    mask-size: 100% calc(var(--rama-fondo) + 24px);
  }
}

.hero-title {
  /* por delante del halo (::before va posicionado y si no lo taparía) */
  position: relative;
  z-index: 1;
  font-family: "Anton", "Arial Narrow", sans-serif;
  font-weight: 400;
  text-transform: uppercase;
  font-size: var(--fs-hero);
  /* En el borrador las dos líneas van de ápice a ápice a 1.05em, más
     apretadas que el 1.1 anterior. */
  line-height: 1.05;
  letter-spacing: 0.005em;
  text-align: center;
  /* "HAZ FLORECER TU" mide 6.341em en Anton. En px este tope se quedaba corto
     al crecer la letra y partía la línea en dos; en em nunca lo hace. */
  max-width: 6.6em;

  /* mismo truco en el blanco, pero apenas perceptible: la letra se apaga
     un pelo hacia abajo, como en la referencia */
  background: linear-gradient(180deg, #ffffff 0%, #ffffff 52%, #f0ebe8 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}

/* Halo cálido detrás del titular, como en la referencia.
   Va dentro del stacking context del hero, así que queda detrás del
   texto pero delante del fondo — y siempre por debajo de la rama. */
.hero::before {
  content: "";
  position: absolute;
  left: 50%;
  /* centro vertical del bloque de 2 líneas: la tinta va de 0.495em a
     2.415em DEL HERO (este ::before se coloca dentro del hero, que ya
     empieza bajo la cabecera — sumarle --cab lo mandaba una cabecera
     entera más abajo, detrás de la cresta de la rama en vez de detrás del
     titular) */
  top: calc(var(--hero-aire) + 1.455 * var(--fs-hero));
  width: min(calc(1500px * var(--esc)), 108vw);
  height: calc(2.6 * var(--fs-hero));
  transform: translate(-50%, -50%);
  background: radial-gradient(
    ellipse at 50% 50%,
    rgba(255, 206, 190, 0.12) 0%,
    rgba(224, 143, 126, 0.07) 32%,
    rgba(150, 84, 72, 0.03) 58%,
    rgba(0, 0, 0, 0) 76%
  );
  pointer-events: none;
}

/* El brillo está DENTRO de la letra: un degradado recortado por la propia
   tipografía. El drop-shadow es solo un rescoldo mínimo para que despegue
   del negro — no es el halo de antes. */
.hero-title .accent {
  background: linear-gradient(
    180deg,
    #fff2f3 0%,
    #fadade 30%,
    #f4c3ca 62%,
    #eda9b4 86%,
    #e2919f 100%
  );
  /* La caja de línea de Anton mide 1.5071em pero los glifos solo van de
     0.307em a 1.186em. Sin esto el degradado se reparte por toda la caja
     y los extremos nunca llegan a pintarse sobre la letra. */
  background-size: 100% 0.8786em;
  background-position: 0 0.3071em;
  background-repeat: no-repeat;

  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
  filter: drop-shadow(0 0 14px rgba(247, 190, 200, 0.3))
    drop-shadow(0 0 44px rgba(233, 145, 163, 0.16));
}

/* ══════════════════════════════════════════════════════════════════
   BOTONES
   La «savia» sube desde abajo al pasar el ratón en lugar de aparecer
   de golpe. Va en un ::before con z-index -1 y el botón aislado, así
   el relleno queda por detrás del texto pero por delante del fondo.
   ══════════════════════════════════════════════════════════════════ */

.btn {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: "Oswald", sans-serif;
  font-weight: 400;
  font-size: calc(14px * var(--esc));
  letter-spacing: 0.13em;
  text-transform: uppercase;
  text-decoration: none;
  border: 1px solid transparent;
  border-radius: 999px;
  padding: calc(17px * var(--esc)) calc(42px * var(--esc));
  cursor: pointer;
  white-space: nowrap;
  transition: color 0.35s ease, border-color 0.35s ease, transform 0.35s ease;
}

.btn::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  transform: translateY(101%);
  transition: transform 0.5s cubic-bezier(0.22, 1, 0.36, 1);
}

@media (hover: hover) {
  .btn:hover {
    transform: translateY(-2px);
  }
}

/* Aquí vivían las excepciones del imán —el botón que perseguía al cursor—.
   Fuera el 2 de sep, por decisión de Sara: «no me gusta esa animación,
   parece que hace glitch al poner el ratón muchas veces encima». Sin imán,
   Contactar y Enviar se quedan con el alzado corto de :hover de aquí arriba,
   que ni tiembla ni depende de por dónde ande el ratón. */

@media (hover: hover) {
  .btn:hover::before {
    transform: translateY(0);
  }
}

.btn-solido {
  background: linear-gradient(180deg, #fdeef0 0%, var(--pink) 100%);
  color: #2a1216;
}

.btn-solido::before {
  background: #ffffff;
}

/* ══════════════════════════════════════════════════════════════════
   ZONA CLARA
   ══════════════════════════════════════════════════════════════════ */

/* La primera parte de la zona clara no es clara: el diagnóstico y el plano de
   la savia van sobre negro, y la crema no empieza hasta el portfolio. Así no
   hay ningún corte al entrar en el vídeo.

   Y el negro es var(--bg), o sea #000 exacto, no un negro «bonito» tirando a
   azul. El vídeo llega en negro puro —medido: rgb(0,0,0) en las cuatro
   esquinas—, y cualquier otro negro pegado a él se ve como una raya por muy
   parecido que sea.

   La altura del tramo la mide script.js (--noche) porque depende de lo que
   ocupe el plano, que se calcula en vh. */
.claro {
  position: relative;
  z-index: 4;
  /* sobre el papel crema el rosa pálido no se ve: aquí la barra va en rosa
     hondo (ventanas legales, tabla de precios, cuerpos que se desplazan) */
  --barra: rgba(150, 72, 90, 0.42);
  --barra-viva: rgba(150, 72, 90, 0.72);
  background: linear-gradient(
    180deg,
    var(--bg) 0 var(--noche, 0px),
    var(--crema) var(--noche, 0px)
  );
  color: var(--ink-crema);
}

/* Sin JavaScript nadie escribe --noche, así que la zona nocturna del papel
   no existía y el diagnóstico salía con su tinta clara sobre crema:
   ilegible (batida del 31 ago). Sin JS, las dos secciones nocturnas traen
   su fondo negro puesto de serie. */
html:not(.js) .s-diag,
html:not(.js) .s-savia {
  background: var(--bg);
}

.claro section {
  position: relative;
  z-index: 1;
  padding-block: var(--paso-y);
}

.contenedor {
  width: 100%;
  max-width: var(--ancho);
  margin-inline: auto;
  padding-inline: clamp(22px, 5vw, 44px);
}

.contenedor-estrecho {
  max-width: calc(860px * var(--esc));
}

/* ---------- Tipografía común de la zona clara ---------- */

.cejilla {
  font-family: "Oswald", sans-serif;
  font-weight: 400;
  font-size: calc(12.5px * var(--esc));
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--rosa-tinta);
  margin-bottom: 26px;
  display: flex;
  align-items: center;
  gap: 14px;
}

/* rayita que sale de la palabra, como un tallito */
.cejilla::after {
  content: "";
  flex: 0 0 auto;
  width: clamp(28px, 4vw, 62px);
  height: 1px;
  background: currentColor;
  opacity: 0.4;
}

.titular {
  font-family: "Libre Baskerville", Georgia, serif;
  font-weight: 700;
  font-size: clamp(31px, 4.1vw, calc(62px * var(--esc)));
  line-height: 1.14;
  letter-spacing: -0.018em;
  color: var(--ink-crema);
  text-wrap: balance;
}

.entradilla {
  margin-top: 26px;
  max-width: 46ch;
  font-size: clamp(16px, 1.15vw, calc(19px * var(--esc)));
  line-height: 1.7;
  color: var(--ink-crema-2);
}

.letra-pequena {
  margin-top: 44px;
  max-width: 72ch;
  font-size: calc(13.5px * var(--esc));
  line-height: 1.75;
  color: var(--ink-crema-3);
}

/* ══════════════════ La enredadera ══════════════════
   La dibuja script.js con la altura real de la zona clara en píxeles, para que
   la escala sea 1:1 y ningún grosor de línea salga deformado.

   Aquí solo va el aspecto. La geometría (tramos que adelgazan, hojas con
   nervios, zarcillos, flores) se genera en JS porque depende de la altura
   del documento, que el CSS no conoce. */

/* Vive en el canalón izquierdo, entre el borde de la ventana y la columna de
   texto. Es estrecho a propósito: con más serpenteo o más a la derecha, las
   hojas invadirían el texto en pantallas de 1300-1400px. */
.tallo {
  position: absolute;
  top: 0;
  /* Pegada al canto de la ventana hasta 1920 px (el diseño de siempre: el
     segundo término sale negativo y gana el clamp). En pantallas más
     anchas se queda a 340 px de la columna de texto, viaje con ella: en
     un monitor de 3440 px, clavada al borde flotaba a un metro de todo. */
  left: max(clamp(10px, 1.6vw, 44px), calc(50% - var(--ancho) / 2 - 340px));
  width: 90px;
  height: 100%;

  /* POR ENCIMA DE LAS SECCIONES (antes iba en 0, por debajo).

     El motivo es la franja rosa del vivero, en Precios: cruza la pantalla de
     borde a borde y le pasaba por encima al canalón entero, así que la
     enredadera salía lavada de rosa y con las hojas apagadas justo en esa
     pantalla. Medido: el verde del tallo pasaba de (152,167,135) a
     (170,173,149).

     El truco de .s-prueba —quitarle a la sección su plano propio para que el
     `z-index: -1` de dentro baje al plano de .claro— aquí no sirve: quien
     hace de plano no es la sección, es el propio .vivero, que lleva
     `transform` y `opacity` de la animación de entrada. Mientras esa
     animación exista, la franja no puede salir de ahí.

     Así que sube la enredadera. Y no invade nada: construirEnredadera mide el
     canalón que hay de verdad y encoge la planta (V_E) para que su punto más
     a la derecha quede 22 px ANTES del borde de la columna de texto; si no
     cabe con dignidad, no la dibuja. O sea que por delante de las secciones
     solo se le pone el canalón, que es suyo. */
  z-index: 5;
  overflow: visible;
  pointer-events: none;
}

/* — Tallo — */

.tallo-linea {
  fill: none;
  stroke: var(--verde);
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0.72;
}

/* Trazo más ancho y oscuro por debajo: sin él el tallo es una raya, con él
   tiene volumen. */
.tallo-sombra {
  fill: none;
  stroke: #4d5b3d;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0.16;
}

/* — Hojas — */

.tallo .hoja {
  fill: #6f8259;
  opacity: 0.9;
}

/* Dos verdes mezclados: todas del mismo color es lo que cantaba a plantilla. */
.tallo .hoja-clara {
  fill: #8fa376;
  opacity: 0.82;
}

.tallo .nervios {
  fill: none;
  stroke: #f4efe4;
  stroke-width: 0.7;
  stroke-linecap: round;
  opacity: 0.5;
}

.tallo .peciolo {
  fill: none;
  stroke: var(--verde);
  stroke-width: 1.5;
  stroke-linecap: round;
  opacity: 0.72;
}

/* — Zarcillos — */

.tallo .zarcillo {
  fill: none;
  stroke: var(--verde);
  stroke-width: 1.5;
  stroke-linecap: round;
  opacity: 0.62;
}

/* — Flores —
   Rosa de marca. Los pétalos llevan un borde crema muy fino: es lo que los
   separa entre sí cuando se solapan. */

.tallo .flor-petalo {
  fill: var(--rosa-hondo);
  stroke: #fbf7ef;
  stroke-width: 0.6;
  opacity: 0.78;
}

.tallo .flor-centro {
  fill: #f2c98a;
  stroke: #b98a4a;
  stroke-width: 0.5;
  opacity: 0.95;
}

/* — Margarita blanca —
   Sobre la crema del fondo un pétalo blanco a secas desaparece: lo que la
   dibuja es el contorno, no el relleno. De ahí el trazo cálido más marcado y
   el corazón dorado más grande, que es lo que la ancla. */
.tallo .flor-blanca .flor-petalo {
  fill: #fdfcfa;
  stroke: #c4b9a6;
  stroke-width: 0.7;
  opacity: 0.94;
}

.tallo .flor-blanca .flor-centro {
  fill: #f7d489;
  stroke: #c08f43;
  stroke-width: 0.6;
  opacity: 1;
}

/* Por debajo de esto el canalón ya no da de sí y las hojas tocarían el texto.
   Si cambias --ancho o la geometría de la enredadera, recalcula este umbral.

   Se intentó que en pantallas pequeñas no desapareciera —mudándola al margen
   de la ventana, encogida, con lo que asomara hacia el texto desvanecido— y
   se descartó después de verlo: con los 22px de margen de un móvil o la
   planta sale desproporcionada, o sale un hilo con motas, o hay que apartar
   el texto para hacerle sitio y la página se ve apelotonada y corrida hacia
   la derecha. En el móvil el protagonista es el texto. */
@media (max-width: 1300px) {
  .tallo {
    display: none;
  }
}

/* ══════════════════ 1 · Diagnóstico ══════════════════ */

/* Va sobre negro. No se repinta nada a mano: toda la tipografía de la zona
   clara tira de estas variables, así que redefinirlas aquí recolorea la
   sección entera de una vez. Y no lleva fondo propio a propósito — el negro lo
   pone .claro, que está por DEBAJO de la enredadera; con un fondo aquí la
   enredadera se quedaría escondida detrás. */
.s-diag {
  --ink-crema: #ffffff;
  --ink-crema-2: rgba(255, 255, 255, 0.74);
  --ink-crema-3: rgba(255, 255, 255, 0.48);
  --linea: rgba(255, 255, 255, 0.14);
  --rosa-tinta: var(--pink);
  --rosa-hondo: #f0a8b4;
}

.sintomas {
  list-style: none;
  margin-top: clamp(44px, 5vw, 72px);
  border-top: 1px solid var(--linea);
}

.sintomas li {
  position: relative;
  display: grid;
  grid-template-columns: 1.15fr 1fr;
  gap: clamp(16px, 3vw, 48px);
  align-items: baseline;
  padding: clamp(22px, 2.6vw, 34px) clamp(14px, 2vw, 26px);
  /* el canalón de la semilla */
  padding-left: clamp(30px, 3.4vw, 48px);
  border-bottom: 1px solid var(--linea);
  /* OJO: aquí NO puede haber «transition: transform». GSAP escribe transform en
     estas filas al revelarlas, y una transition encima de un tween se pelea con
     él fotograma a fotograma; peor aún, al refrescar ScrollTrigger releía el
     valor a medio transicionar y lo daba por bueno como destino, así que las
     cinco filas se quedaban 34px corridas a la izquierda para siempre.
     El desplazamiento al pasar el ratón lo hace ahora GSAP (script.js, 5b). */
}

/* ── La semilla del canalón ──
   Una gota rosa —redonda por tres esquinas y en punta por la cuarta, la
   silueta del pétalo de la marca— delante de cada síntoma. Nació en el
   móvil, donde hacía falta para que dos renglones se leyeran como UNA cosa
   al quitar los filetes, y se queda en TODAS las pantallas: en el
   escritorio marca el arranque de cada fila mejor que el filete solo, y de
   paso mete el rosa de la casa en una sección que era blanco sobre negro.

   Va en ::after porque el ::before de la fila ya está ocupado por el lavado
   rosa del hover. Es el único pseudoelemento libre: no hay un tercero. */
.sintomas li::after {
  content: "";
  position: absolute;
  left: clamp(10px, 1.2vw, 18px);
  /* el relleno de arriba de la fila más media línea del texto: así queda a
     la altura del primer renglón de la cita, no del centro de la fila */
  top: calc(clamp(22px, 2.6vw, 34px) + 0.42em);
  width: clamp(7px, 0.62vw, 9px);
  aspect-ratio: 1;
  border-radius: 50% 50% 50% 0;
  transform: rotate(-18deg);
  background: var(--rosa-hondo);
  opacity: 0.8;
  transition: opacity 0.4s ease, transform 0.5s cubic-bezier(0.22, 1, 0.36, 1);
}

/* al regar la fila, la semilla se despierta */
@media (hover: hover) {
  .sintomas li:hover::after {
    opacity: 1;
    transform: rotate(-18deg) scale(1.22);
  }
}

/* el lavado rosa entra desde la izquierda, como si la fila se regara */
.sintomas li::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(
    90deg,
    rgba(247, 200, 205, 0.32),
    rgba(247, 200, 205, 0)
  );
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform 0.5s cubic-bezier(0.22, 1, 0.36, 1);
}

@media (hover: hover) {
  .sintomas li:hover::before {
    transform: scaleX(1);
  }
}

/* Sin JS no hay quien mueva la fila, así que ahí sí lo hace el CSS. */
html:not(.js) .sintomas li {
  transition: transform 0.45s cubic-bezier(0.22, 1, 0.36, 1);
}

@media (hover: hover) {
  html:not(.js) .sintomas li:hover {
    transform: translateX(8px);
  }
}

.sintoma-dice {
  font-family: "Libre Baskerville", Georgia, serif;
  font-style: italic;
  font-size: clamp(17px, 1.5vw, calc(24px * var(--esc)));
  line-height: 1.4;
  color: var(--ink-crema);
}

.sintoma-pasa {
  font-size: clamp(14px, 1vw, calc(16px * var(--esc)));
  line-height: 1.6;
  color: var(--ink-crema-3);
}

.remate {
  margin-top: clamp(56px, 6vw, 92px);
  text-align: center;
  font-family: "Libre Baskerville", Georgia, serif;
  font-size: clamp(22px, 2.6vw, calc(40px * var(--esc)));
  line-height: 1.4;
  color: var(--ink-crema);
}

.remate em {
  font-style: italic;
  color: var(--rosa-tinta);
}

.cifras {
  display: grid;
  /* Cuatro columnas fijas, en todas las pantallas. Con auto-fit, entre 820
     y 1100 px la rejilla caía en tres más una: el «0,05 s» se quedaba solo
     en una segunda fila, huérfano. Son cuatro medidas de la misma regla y
     van en la misma línea; lo que cambia con el ancho es la letra. */
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(14px, 3vw, calc(56px * var(--esc)));
  margin-top: clamp(56px, 6vw, 96px);
  padding-top: clamp(40px, 4vw, 60px);
  border-top: 1px solid var(--linea);
}

.cifra-n {
  display: block;
  font-family: "Anton", "Arial Narrow", sans-serif;
  font-size: clamp(30px, 4.6vw, calc(74px * var(--esc)));
  line-height: 1;
  letter-spacing: -0.01em;
  color: var(--rosa-hondo);
  /* tabular para que al contar no bailen los dígitos */
  font-variant-numeric: tabular-nums;
}

.cifra-txt {
  display: block;
  margin-top: 14px;
  /* un punto más grande y a tinta casi plena: son el argumento de la
     sección, no una nota al pie — al 66% y 14,5px no daban ganas de leer */
  font-size: clamp(12px, 1.25vw, calc(16px * var(--esc)));
  line-height: 1.55;
  color: rgba(255, 255, 255, 0.86);
  max-width: 20ch;
  /* reparte las dos líneas parejas: sin esto quedaba una palabra suelta
     colgando debajo y la frase moría ahí */
  text-wrap: balance;
  /* Dos renglones reservados en las cuatro, los llenen o no. Las frases están
     escritas para ocupar dos, pero basta con que una ventana sea 40px más
     estrecha para que una de ellas pase a tres y la fila se descuadre. Con el
     hueco reservado, los cuatro bloques miden lo mismo siempre. */
  min-height: calc(2 * 1.6em);
}

/* ══════════════════ 2 y 3 · La savia ══════════════════
   Servicios y Proceso comparten un plano fijo con el vídeo avanzando
   fotograma a fotograma. Aquí solo va el aspecto y la colocación; el reloj
   (qué se ve en cada punto del scroll) lo lleva script.js §7.

   Regla que manda en toda esta sección: NADIE escribe `transform` en el CSS
   de un bloque animado. Los centrados van con inset + margin auto, y los
   verticales con flexbox. Si el CSS pusiera un translate, GSAP lo borraría en
   el primer fotograma y el bloque saltaría de sitio. */

.s-savia {
  position: relative;
  /* 480 de alto menos 100 de plano fijo = 380vh de recorrido, unos 3.400px.
     Con los 241 fotogramas del vídeo sale una imagen cada ~14px de scroll.

     Eran 560vh y 17px por fotograma. Acortar el recorrido es la única manera
     honesta de que el vídeo avance más suave: mete más fotogramas en cada
     muesca de rueda sin tocar la imagen. Interpolar el vídeo a 48fps parecía
     el atajo y no lo es —los fotogramas inventados salen borrosos en cuanto
     te paras encima de uno, y con scroll te paras—, así que la suavidad se
     saca de aquí. */
  height: 480vh;
  /* el recorrido (lo que hay que bajar para ver el vídeo entero) con tope:
     en un 4K de 2160 px de alto 380 pantallas eran 8.200 px de scroll para
     241 fotogramas — 34 px por fotograma. Hasta 1200 px de alto no cambia. */
  /* SVH, y aquí es donde más se notaba: esta sección es la más alta de la
     web (unas cinco pantallas). Con lvh, en los navegadores de móvil que
     redimensionan la página al esconder la barra, el documento entero se
     alargaba y encogía ~300px en cada gesto y la mitad baja de la web
     brincaba sin parar (vídeos de Sara, 1 sep). El plano fijo de dentro
     sigue midiendo 100lvh —ese SÍ tiene que tapar la pantalla entera con la
     barra recogida—; lo que cambia es el RECORRIDO, que ahora es un número
     quieto. En escritorio, idéntico. */
  height: calc(var(--vh-fijo) + clamp(2500px, calc(var(--vh-fijo) * 3.8), 4600px));
  color: var(--ink);
  background: var(--bg);
  /* Lo que la barra del navegador del móvil tapa por abajo cuando está
     desplegada: la diferencia entre la pantalla grande (lvh) y la pequeña
     (svh). 0 en escritorio. Lo que va anclado al borde de abajo del plano
     —la pista, el alzado de los pasos— se sube esto para no quedar bajo
     la barra. (Se llama --barra-tapada y no --barra porque --barra ya es
     el COLOR de la barra de scroll, en :root: eran dos cosas distintas
     con el mismo nombre y era cuestión de tiempo que una pisara a la otra.) */
  --barra-tapada: 0px;
}

@supports (height: 100svh) {
  .s-savia {
    --barra-tapada: max(0px, calc(var(--vh-plano) - var(--vh-fijo)));
  }
}

/* .claro section mete padding vertical a todas; aquí sobra, la altura la
   marca el recorrido. */
.claro .s-savia {
  padding-block: 0;
}

/* Ancla invisible del menú: cae donde arranca el segundo acto. */
.savia-ancla {
  position: absolute;
  left: 0;
  top: 62%;
  width: 1px;
  height: 1px;
}

.savia-pin {
  position: sticky;
  top: 0;
  /* lvh: la pantalla del móvil con la barra RECOGIDA, la más alta. El
     plano tiene que cubrirla entera: si midiera la pequeña (svh), en
     cuanto la barra se recoge al bajar asomaría una franja de fondo bajo
     un corte recto del vídeo. Lo que la barra tapa cuando está desplegada
     se descuenta de lo que va anclado abajo (--barra-tapada). */
  height: 100vh;
  height: var(--vh-plano);
  overflow: hidden;
  z-index: 1;
}

.savia-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* el vídeo llega recortado en negro puro: sin esto se ve una costura de un
     píxel entre el borde del vídeo y el fondo de la sección */
  background: var(--bg);
}

/* NI BANDAS NI CABEZA CORTADA: EL RECORTE, TODO POR ABAJO.

   El vídeo es 16:9. En una ventana más apaisada que él hay que elegir: o
   `cover`, que llena el ancho y se come altura, o `contain`, que lo deja
   entero y pone banda negra a los lados.

   Se probaron las dos y las dos fallaban, cada una por su lado:

   · `cover` centrado se come la altura A PARTES IGUALES, arriba y abajo. En
     una ventana de 1920x960 —un navegador a pantalla completa en un monitor
     de 1080— son 54 px por arriba, y ahí está la corona de la mujer. Eso es
     lo que vio Sara en su monitor.

   · `contain` deja el vídeo entero, sí, pero las bandas de los lados SE VEN.
     Se midió el vídeo fotograma a fotograma (40 muestras, `perfil-savia.mjs`)
     y el resultado es tajante: a partir del segundo 2,8 el contenido llega a
     los dos cantos laterales —el fondo iluminado del plano de la mano va de
     borde a borde—, así que la banda negra queda al lado de algo encendido y
     canta. De ahí las flechas de Sara.

   La salida es no repartir el recorte: `object-position: 50% 0`. El vídeo
   llena la ventana entera (sin bandas) y toda la altura que sobra se recorta
   POR ABAJO. Por arriba no se le quita ni un píxel nunca, en ninguna
   ventana, así que la cabeza no se puede cortar. Lo que se pierde es el
   canto de abajo del plano —suelo y el arranque del brazo—, que es donde
   menos duele: la escena está construida de la cabeza hacia abajo.

   Los números del vídeo, por si algún día se cambia el archivo: el aire
   negro que tiene por cada lado baja a CERO en casi todo el metraje (arriba
   desde el segundo 0,8; abajo y a los lados, siempre). O sea que cualquier
   recorte quita algo: la decisión no es «cuánto» sino «por dónde», y la
   respuesta es por abajo.

   El respaldo movil es 16:9 (1280x720). El nuevo recorte 608x1080 se usa
   en pantallas estrechas; ambos mantienen el encuadre al ocultar barras. */
.savia-video {
  object-position: 50% 0;
}

.claro .servicios-acceso {
  padding-block: 64px 40px;
  background: var(--crema);
  color: var(--ink-crema);
}
.servicios-acceso-interior {
  display: grid;
  grid-template-columns: 1.1fr 1fr;
  align-items: end;
  gap: 24px 64px;
}
.servicios-acceso .cejilla { margin-bottom: 18px; }
.servicios-acceso h2 {
  font: 700 32px/1.3 "Libre Baskerville", Georgia, serif;
  letter-spacing: 0;
}
.servicios-acceso-interior > p {
  max-width: 54ch;
  font-size: 16px;
  line-height: 1.7;
  color: var(--ink-crema-2);
}
.servicios-resumen { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); column-gap: 36px; margin-top: 36px; }
.servicios-resumen a { position: relative; padding: 20px 20px 22px 0; border-top: 1px solid var(--linea); text-decoration: none; color: var(--ink-crema); }
.servicio-orden { display: block; margin-bottom: 8px; color: var(--rosa-tinta); font: 400 12px/1.4 "Oswald", sans-serif; }
.servicios-resumen strong { display: block; font: 400 22px/1.35 "Oswald", sans-serif; letter-spacing: 0; }
.servicios-resumen p { margin-top: 8px; max-width: 34ch; font-size: 14px; line-height: 1.65; color: var(--ink-crema-2); }
.servicio-flecha { position: absolute; top: 22px; right: 0; color: var(--rosa-tinta); }
.servicios-todos {
  display: inline-flex;
  align-items: center;
  gap: 20px;
  min-height: 44px;
  margin-top: 14px;
  color: var(--rosa-tinta);
  font: 400 15px/1.5 "Inter", sans-serif;
  text-decoration: none;
  border-bottom: 1px solid currentColor;
}
@media (hover: hover) {
  .servicios-resumen a:hover strong { color: var(--rosa-tinta); }
  .servicios-todos:hover { color: var(--ink-crema); }
}
@media (max-width: 900px) {
  .servicios-acceso-interior { grid-template-columns: 1fr; gap: 20px; }
  .servicios-acceso h2 { font-size: 28px; }
  .servicios-resumen { column-gap: 24px; }
}
@media (max-width: 600px) {
  .claro .servicios-acceso { padding-block: 48px 24px; }
  .servicios-acceso h2 { font-size: 25px; }
  .servicios-resumen { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 20px; margin-top: 28px; }
  .servicios-resumen a { padding-right: 0; }
  .servicios-resumen strong { font-size: 19px; }
  .servicios-resumen p { font-size: 13px; }
}

/* Ni el pin ni sus textos dependen de la barra del navegador. Reservamos
   el alto completo y mantenemos la lectura en la zona visible inicial. */
@media (pointer: coarse) {
  .js .s-savia:not(.savia-simple) .savia-pin {
    height: var(--savia-reserva, var(--vh-plano));
  }

  .js .s-savia:not(.savia-simple) .savia-video {
    top: env(safe-area-inset-top, 0px);
    bottom: auto;
    height: calc(var(--savia-reserva, var(--vh-plano)) - env(safe-area-inset-top, 0px));
  }

  .js .s-savia:not(.savia-simple) .savia-escena {
    bottom: auto;
    height: var(--vh-fijo);
  }

  .js .s-savia:not(.savia-simple) .savia-pista {
    bottom: calc(var(--savia-reserva, var(--vh-plano)) - var(--vh-fijo) + clamp(26px, calc(var(--vh-plano) * 0.04), calc(52px * var(--esc))));
  }
}

/* Viñeta de ambiente, suave. La lectura NO depende de ella: de eso se encarga
   la sombra propia de cada bloque (.savia-caja). Esa diferencia importa,
   porque el vídeo hace zoom y a mitad de recorrido la figura ocupa casi todo
   el ancho: una viñeta lo bastante fuerte para tapar eso oscurecería también
   la figura, que es justo lo que hemos venido a enseñar. */
.savia-velo {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    linear-gradient(90deg, rgba(0, 0, 0, 0.62) 0%, rgba(0, 0, 0, 0.26) 14%, rgba(0, 0, 0, 0) 30%),
    linear-gradient(270deg, rgba(0, 0, 0, 0.62) 0%, rgba(0, 0, 0, 0.26) 14%, rgba(0, 0, 0, 0) 30%),
    linear-gradient(0deg, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0) 22%);
}

.savia-escena {
  position: absolute;
  inset: 0;
  z-index: 2;
  /* los bloques se solapan a pantalla completa: dejarlos capturar el ratón
     rompería cualquier cosa que hubiera debajo */
  pointer-events: none;
}

/* Cada bloque es una columna de altura completa. Se centra con flexbox y no
   con translate justo para no pisarle el transform a GSAP. */
.savia-bloque {
  position: absolute;
  top: 0;
  bottom: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  width: min(31vw, calc(400px * var(--esc)));
  will-change: opacity, transform;
}

.js .savia-bloque,
.js .savia-paso {
  opacity: 0;
}

.savia-bloque[data-lado="izq"] {
  left: clamp(26px, 5vw, calc(92px * var(--esc)));
  align-items: flex-start;
  text-align: left;
}

.savia-bloque[data-lado="der"] {
  right: clamp(26px, 5vw, calc(92px * var(--esc)));
  align-items: flex-end;
  text-align: right;
}

/* inset 0 + margin auto centra sin transform */
.savia-bloque[data-lado="centro"] {
  left: 0;
  right: 0;
  margin-inline: auto;
  /* 860 y no 800: «De la semilla a la flor» a 78px mide ~790 — con 800 de
     caja iba al límite y en 3440 (todo ×1,36) el redondeo partía «flor»
     sola en su renglón. La caja solo manda en dónde parte el texto: más
     ancha no mueve nada de sitio, el bloque va centrado. */
  width: min(84vw, calc(860px * var(--esc)));
  align-items: center;
  text-align: center;
}

/* El titular de sección no cabe en la columna estrecha de los bloques de
   servicio: «Hacemos crecer negocios» partía en tres líneas. */
.savia-bloque-titulo {
  width: min(40vw, calc(520px * var(--esc)));
}

.savia-bloque[data-alto="alto"] {
  justify-content: flex-start;
  padding-top: clamp(96px, calc(var(--vh-plano) * 0.16), 190px);
}

/* La sombra que hace legible el texto va PEGADA al texto, no a la pantalla.
   La caja mide justo lo que ocupa su contenido, así que el degradado se
   estira y encoge con cada bloque y no oscurece ni un píxel de más. Anclado
   al lado por el que entra el bloque, para que el borde exterior sea el más
   opaco y el interior se disuelva sobre el vídeo. */
.savia-caja {
  position: relative;
  isolation: isolate;
}

/* Degradado, NO `filter: blur()`.

   El desenfoque quedaba precioso pero era carísimo: el navegador tiene que
   recalcularlo cada vez que cambia la opacidad del bloque, o sea en cada
   fotograma del scroll, y con ocho bloques a la vez ahí se iban los tirones.

   El truco para que un degradado no enseñe el borde de su caja es
   `closest-side`: la elipse toca justo los cuatro lados, así que llega a
   transparente exactamente en el borde y no hay nada que recortar. La caja se
   estira sola con el texto que lleva dentro. */
.savia-caja::before {
  content: "";
  position: absolute;
  inset: -58px -104px;
  z-index: -1;
  background: radial-gradient(
    closest-side,
    rgba(0, 0, 0, 0.93) 0%,
    rgba(0, 0, 0, 0.84) 34%,
    rgba(0, 0, 0, 0.5) 62%,
    rgba(0, 0, 0, 0.16) 84%,
    rgba(0, 0, 0, 0) 100%
  );
}

/* Sobre negro puro el texto fino se come el degradado y se ve gris. Un halo
   corto lo despega de cualquier cosa que pase por detrás. */
.savia-caja {
  text-shadow: 0 1px 20px rgba(0, 0, 0, 0.9), 0 1px 3px rgba(0, 0, 0, 0.7);
}

/* ---------- Tipografía del plano ---------- */

.savia-cejilla {
  font-family: "Oswald", sans-serif;
  font-weight: 400;
  font-size: calc(13px * var(--esc));
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--pink);
  margin-bottom: 22px;
}

.savia-titular {
  font-family: "Libre Baskerville", Georgia, serif;
  font-weight: 700;
  font-size: clamp(28px, 3.2vw, calc(52px * var(--esc)));
  line-height: 1.14;
  letter-spacing: -0.018em;
  color: var(--ink);
}

.savia-titular-xl {
  font-size: clamp(34px, 5vw, calc(78px * var(--esc)));
  line-height: 1.08;
}

.savia-n {
  display: block;
  font-family: "Anton", "Arial Narrow", sans-serif;
  font-size: calc(16px * var(--esc));
  letter-spacing: 0.08em;
  color: var(--pink);
  opacity: 0.95;
}

.savia-bloque h3 {
  margin: 14px 0 14px;
  font-family: "Libre Baskerville", Georgia, serif;
  font-weight: 700;
  font-size: clamp(23px, 2.1vw, calc(34px * var(--esc)));
  line-height: 1.2;
  letter-spacing: -0.012em;
  color: var(--ink);
}

/* :where() deja la especificidad en la de un «p» a secas: las retallas de
   ≤560 (.savia-caja p) y de pantallas bajas (.savia-paso p) no llegaban
   nunca porque este selector con dos :not() pesaba más que ellas, y en un
   móvil de 320 el H2 de la savia salía más pequeño que sus propios H3. */
:where(.savia-bloque) p:where(:not(.savia-cejilla)) {
  font-size: clamp(16px, 1.3vw, calc(21px * var(--esc)));
  line-height: 1.6;
  color: rgba(255, 255, 255, 0.88);
}

.savia-sub {
  display: block;
  margin-top: 4px;
  font-family: "Oswald", sans-serif;
  font-weight: 300;
  font-size: calc(12.5px * var(--esc));
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--pink);
  opacity: 0.85;
}

/* ---------- Los cuatro pasos ----------
   Se acumulan: cuando llega el siguiente, el anterior se queda atenuado en
   vez de irse. Así el fotograma final —la mano con el ramo entero— tiene al
   lado el camino completo.

   Están a la izquierda, colgados de un tallo. Apilados a la derecha se comían
   unos a otros —cuatro bloques de tres líneas separados por 11px son un
   párrafo, no una lista— y encima caían sobre la parte iluminada del plano.
   Aquí hay negro de sobra, así que caben con el triple de aire, el número se
   sale a un canalón propio y el tallo hace de hilo: se ve que es un camino
   antes de leer una sola palabra. */

.savia-bloque-pasos {
  width: min(42vw, calc(540px * var(--esc)));
  /* La escalera se sube sobre el centro óptico. En el fotograma final la mano
     entra por abajo y la palma está iluminada: es el único sitio de este lado
     donde el texto blanco no se lee. Lo que sube el conjunto es este hueco,
     medido para que la última línea —«y la web es tuya»— acabe justo antes de
     los dedos. */
  padding-bottom: calc(clamp(130px, calc(var(--vh-plano) * 0.24), 280px) + var(--barra-tapada, 0px));
}

/* Sin línea vertical. La probé y quedaba fatal: sobre negro un filo rosa de
   1px no se lee como un tallo, se lee como el borde de una tabla, y encima
   los números se le montaban encima. El canalón solo, con los números
   sacados fuera, ya alinea la lista sin dibujar nada. */
.savia-pasos {
  position: relative;
  list-style: none;
  display: grid;
  gap: clamp(26px, calc(var(--vh-plano) * 0.042), 54px);
  padding-left: clamp(38px, 3.4vw, 54px);
}

.savia-paso {
  position: relative;
  will-change: opacity, transform;
}

/* El número sale al canalón y se sienta sobre el tallo: es el nudo del que
   cuelga cada paso. Va con la línea del h3, no encima, para no gastar una
   línea entera en dos cifras. */
.savia-paso .savia-n {
  position: absolute;
  left: calc(clamp(38px, 3.4vw, 54px) * -1);
  top: 0.42em;
  width: clamp(38px, 3.4vw, 54px);
  font-size: calc(13px * var(--esc));
  letter-spacing: 0.06em;
}

.savia-paso h3 {
  margin: 0 0 7px;
  font-size: clamp(21px, 1.85vw, calc(30px * var(--esc)));
}

.savia-paso p {
  max-width: 32ch;
}

/* En portátiles de 720px de alto los cuatro pasos, que se ven a la vez al
   final, se quedan sin sitio y el primero se sale por arriba del plano. Se
   aprietan un punto en vez de recortarse. */
@media (max-height: 800px) {
  :where(html:not(.js)) .savia-bloque-pasos {
    padding-bottom: calc(clamp(60px, calc(var(--vh-plano) * 0.14), 120px) + var(--barra-tapada, 0px));
  }

  :where(html:not(.js)) .savia-pasos {
    gap: clamp(18px, calc(var(--vh-plano) * 0.03), 34px);
  }

  :where(html:not(.js)) .savia-paso h3 {
    margin: 0 0 5px;
    font-size: clamp(19px, 1.75vw, 26px);
  }

  :where(html:not(.js)) .savia-paso p {
    font-size: 15.5px;
    line-height: 1.55;
  }
}

:where(.plano-bajo) .savia-bloque-pasos {
  padding-bottom: calc(clamp(60px, calc(var(--vh-plano) * 0.14), 120px) + var(--barra-tapada, 0px));
}
:where(.plano-bajo) .savia-pasos {
  gap: clamp(18px, calc(var(--vh-plano) * 0.03), 34px);
}
:where(.plano-bajo) .savia-paso h3 {
  margin: 0 0 5px;
  font-size: clamp(19px, 1.75vw, 26px);
}
:where(.plano-bajo) .savia-paso p {
  font-size: 15.5px;
  line-height: 1.55;
}

/* ---------- Pista de scroll ---------- */

.savia-pista {
  position: absolute;
  left: 0;
  right: 0;
  bottom: calc(clamp(26px, calc(var(--vh-plano) * 0.04), calc(52px * var(--esc))) + var(--barra-tapada, 0px));
  z-index: 3;
  text-align: center;
  font-family: "Oswald", sans-serif;
  font-weight: 300;
  font-size: calc(11.5px * var(--esc));
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.5);
  pointer-events: none;
}

.js .savia-pista {
  opacity: 0;
}

.savia-pista::after {
  content: "";
  display: block;
  width: 1px;
  height: 26px;
  margin: 12px auto 0;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.55), transparent);
}

/* El fotograma de cierre solo sale cuando no hay plano fijo. */
.savia-cierre {
  display: none;
}

/* ---------- Sin plano fijo ----------
   Pantalla pequeña, poca altura, movimiento reducido o sin GSAP: la sección
   se desmonta y se lee como una lista normal sobre negro. No se descarga el
   vídeo; cierra el fotograma final, que ya es la imagen que resume todo. */

.s-savia.savia-simple,
html:not(.js) .s-savia {
  height: auto;
}

.savia-simple .savia-pin,
html:not(.js) .s-savia .savia-pin {
  position: static;
  height: auto;
  padding-block: var(--paso-y);
}

.savia-simple .savia-video,
html:not(.js) .s-savia .savia-video,
.savia-simple .savia-velo,
html:not(.js) .s-savia .savia-velo,
.savia-simple .savia-pista,
html:not(.js) .s-savia .savia-pista {
  display: none;
}

.savia-simple .savia-escena,
html:not(.js) .s-savia .savia-escena {
  position: static;
  display: grid;
  gap: clamp(40px, 7vw, 76px);
  width: 100%;
  max-width: var(--ancho);
  margin-inline: auto;
  padding-inline: clamp(22px, 5vw, 44px);
  pointer-events: auto;
}

.savia-simple .savia-bloque,
html:not(.js) .s-savia .savia-bloque {
  position: static;
  display: block;
  width: auto;
  max-width: 58ch;
  padding-top: 0;
  text-align: left;
  opacity: 1;
}

.savia-simple .savia-caja::before,
html:not(.js) .s-savia .savia-caja::before {
  display: none;
}

.savia-simple .savia-caja,
html:not(.js) .s-savia .savia-caja {
  text-shadow: none;
}

.savia-simple .savia-bloque-pasos,
html:not(.js) .s-savia .savia-bloque-pasos {
  width: auto;
  max-width: none;
  /* el alzado óptico es del plano fijo: en lista dejaba media pantalla de
     negro entre el paso 04 y la imagen de cierre */
  padding-bottom: 0;
}

/* el centrado del bloque bisagra también es del plano fijo */
.savia-simple .savia-bloque,
html:not(.js) .s-savia .savia-bloque {
  margin-inline: 0;
}

.savia-simple .savia-pasos,
html:not(.js) .s-savia .savia-pasos {
  gap: clamp(32px, 5vw, 52px);
}

.savia-simple .savia-paso,
html:not(.js) .s-savia .savia-paso {
  opacity: 1;
}

/* La marca repetida del segundo acto solo tiene sentido en el plano fijo,
   donde el bloque centrado ya se ha ido. En lista es una cejilla huérfana. */
.savia-simple .savia-bloque-marca,
html:not(.js) .s-savia .savia-bloque-marca {
  display: none;
}

/* A sangre: enmarcada con márgenes parecía una foto pegada; a todo lo ancho
   cierra la sección igual que el plano fijo cierra en escritorio. */
.savia-simple .savia-cierre,
html:not(.js) .s-savia .savia-cierre {
  display: block;
  width: 100%;
  height: auto;
  margin-top: clamp(40px, 7vw, 76px);
}

/* ══════════════════ 4 · La prueba ══════════════════ */

/* El lienzo de pétalos va en z-index -1, y para que eso lo baje al plano de
   .claro —y no al de la propia sección— esta sección no puede crear contexto
   de apilamiento: así los pétalos quedan POR DEBAJO de la enredadera, que es
   la protagonista del canalón, y ellos son fondo.
   (Desde que la enredadera va en z-index 5 esto ya lo garantiza ella sola,
   pero se queda: la regla dice lo que tiene que pasar y no depende de que la
   enredadera siga donde está hoy.) */
/* Con .s-prueba a secas no basta: «.claro section» tiene más peso y le vuelve
   a poner z-index 1. */
.claro .s-prueba {
  z-index: auto;
  padding-top: 64px;
  /* Menos aire por abajo del que le da --paso-y. Entre el final del
     manifiesto y la cejilla de Precios había 347px: el aire de esta sección,
     más el de la siguiente, más el margen del propio manifiesto, los tres
     sumados. Tres respiros seguidos no son respiro, son un descampado, y la
     página se leía como si se hubiera acabado ahí. */
  padding-bottom: clamp(56px, 6vw, 100px);
}

.proyecto-racu { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 2fr); gap: 48px; align-items: center; margin-top: 44px; padding-top: 28px; border-top: 1px solid var(--linea); }
.proyecto-numero { color: var(--rosa-tinta); font: 400 12px/1.5 "Oswald", sans-serif; text-transform: uppercase; margin-bottom: 16px; }
.proyecto-ficha h3 { font: 700 23px/1.4 "Libre Baskerville", Georgia, serif; letter-spacing: 0; }
.proyecto-logo { display: block; width: 106px; height: auto; margin-block: 20px; }
.proyecto-relato { font-size: 15px; line-height: 1.75; color: var(--ink-crema-2); }
.proyecto-alcance { margin-top: 20px; font: 400 12px/1.7 "Oswald", sans-serif; color: var(--rosa-tinta); }
.proyecto-portada { display: block; min-width: 0; color: var(--ink-crema); text-decoration: none; border-radius: 0; }
.proyecto-portada img { display: block; width: 100%; height: auto; aspect-ratio: 1440 / 1000; }
.proyecto-dominio { display: flex; justify-content: space-between; align-items: center; min-height: 40px; font: 400 12px/1.5 "Inter", sans-serif; color: var(--ink-crema-2); }
.proyecto-visitar { display: inline-flex; align-items: center; gap: 22px; min-height: 44px; margin-top: 24px; color: var(--rosa-tinta); text-decoration: none; font-size: 15px; }
.proyecto-visitar > span:first-child { border-bottom: 1px solid currentColor; padding-block: 4px; }
@media (max-width: 1000px) {
  .proyecto-racu { gap: 32px; grid-template-columns: minmax(0, 1fr) minmax(0, 1.7fr); }
}
@media (max-width: 600px) {
  .proyecto-racu { grid-template-columns: 1fr; gap: 24px; margin-top: 28px; padding-top: 20px; }
  .proyecto-ficha { display: grid; grid-template-columns: 1fr 84px; column-gap: 16px; }
  .proyecto-numero, .proyecto-relato, .proyecto-alcance, .proyecto-visitar { grid-column: 1 / -1; }
  .proyecto-ficha h3 { font-size: 22px; align-self: center; }
  .proyecto-logo { width: 84px; margin: 0 0 18px; }
  .proyecto-visitar { margin-top: 12px; justify-self: start; }
}

.petalos-fondo {
  position: absolute;
  inset: 0;
  z-index: -1;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

/* Una sola columna de texto y nada más. Sin caja, sin fondo blanco: lo que
   tiene que verse detrás son los pétalos, así que aquí no se pone nada que
   los tape. */
.prueba-manifiesto {
  position: relative;
  margin-top: clamp(40px, 5vw, 68px);
  max-width: 60ch;
  padding-left: clamp(22px, 2.6vw, 34px);
}

/* El tallito de la izquierda se desvanece hacia abajo, como los de la
   enredadera. Con un border-left plano quedaba un palo cortado a hachazos. */
.prueba-manifiesto::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.42em;
  bottom: 0.2em;
  width: 2px;
  background: linear-gradient(
    180deg,
    var(--rosa-hondo) 0%,
    var(--rosa-hondo) 38%,
    transparent 100%
  );
}

/* La primera frase es la tesis de la sección: va en serif y a cuerpo mayor
   que el resto, pero en cursiva para que no le dispute el sitio al titular. */
.pm-lema {
  font-family: "Libre Baskerville", Georgia, serif;
  font-style: italic;
  font-size: clamp(19px, 1.85vw, calc(27px * var(--esc)));
  line-height: 1.45;
  letter-spacing: -0.01em;
  color: var(--ink-crema);
  text-wrap: balance;
}

.pm-p {
  margin-top: clamp(22px, 2.2vw, 30px);
  font-size: clamp(16px, 1.15vw, calc(18.5px * var(--esc)));
  line-height: 1.75;
  color: var(--ink-crema-2);
}

/* La última frase se queda sola en su renglón: es el remate, y suelta pega
   más que metida en el párrafo. */
.pm-cierre {
  display: block;
  margin-top: 12px;
  font-family: "Libre Baskerville", Georgia, serif;
  font-style: italic;
  color: var(--rosa-tinta);
}

/* ---- desplegables (los de la FAQ) ---- */

/* Cada pregunta lleva su número delante, pequeño y rosa, como los pasos de
   la savia: convierte la lista en un recorrido y da un punto de apoyo al ojo
   al escanear. Lo pone un contador de CSS: si se añade o quita una pregunta,
   la numeración se rehace sola. */
.faq {
  counter-reset: pregunta;
}

.faq details {
  border-top: 1px solid var(--linea);
}

.faq details:last-child {
  border-bottom: 1px solid var(--linea);
}

.faq summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding: clamp(20px, 2.2vw, 28px) 4px;
  font-family: "Libre Baskerville", Georgia, serif;
  font-weight: 700;
  font-size: clamp(16px, 1.35vw, calc(21px * var(--esc)));
  letter-spacing: -0.01em;
  color: var(--ink-crema);
  transition: color 0.3s ease;
}

.faq summary::before {
  counter-increment: pregunta;
  content: "0" counter(pregunta);
  flex: 0 0 auto;
  font-family: "Oswald", sans-serif;
  font-weight: 300;
  font-size: calc(12px * var(--esc));
  letter-spacing: 0.14em;
  color: var(--rosa-hondo);
  opacity: 0.8;
}

/* la pregunta ocupa el sitio entre el número y la cruz */
.faq summary span {
  flex: 1 1 auto;
}

.faq summary::-webkit-details-marker {
  display: none;
}

/* la crucecita: dos trazos, y al abrir el vertical se tumba */
.faq summary::after {
  content: "";
  flex: 0 0 auto;
  width: 15px;
  height: 15px;
  background: linear-gradient(currentColor, currentColor) center/100% 1.5px
      no-repeat,
    linear-gradient(currentColor, currentColor) center/1.5px 100% no-repeat;
  color: var(--rosa-hondo);
  transition: transform 0.45s cubic-bezier(0.22, 1, 0.36, 1);
}

.faq details[open] summary::after {
  transform: rotate(135deg);
}

@media (hover: hover) {
  .faq summary:hover {
    color: var(--rosa-tinta);
  }
}

.faq-cuerpo {
  /* alineado con la pregunta, no con el número: el sangrado deja claro qué
     responde a qué */
  padding: 0 4px clamp(24px, 2.6vw, 34px) clamp(30px, 3vw, 42px);
  max-width: 68ch;
}

/* La respuesta entra, no aparece: un deslizamiento corto al abrir. Es una
   animación de CSS y no un tween porque un <details> abre de golpe por
   definición — lo único animable sin secuestrar el elemento es el contenido
   recién mostrado. */
.faq details[open] .faq-cuerpo {
  animation: faq-abre 0.5s cubic-bezier(0.22, 1, 0.36, 1) both;
}

@keyframes faq-abre {
  from {
    opacity: 0;
    transform: translateY(-8px);
  }
}

.faq-cuerpo p {
  font-size: calc(15.5px * var(--esc));
  line-height: 1.75;
  color: var(--ink-crema-2);
}

/* Hay respuestas de tres párrafos —el plazo y el mantenimiento— y sin esto
   salían pegadas en un solo bloque. */
.faq-cuerpo p + p {
  margin-top: 0.9em;
}

/* ══════════════════ 5 · Precios ══════════════════

   Dos momentos de lo mismo: lo que se planta (Semilla, Brote, Flor) y lo que
   se riega (Riego, Impulso). Las cinco fichas son el mismo objeto.

   Lo que cambia respecto a la versión anterior, y por qué:

   · EL VIVERO. Antes la sección no tenía fondo propio y el color lo ponía un
     aura rosa con 40px de desenfoque. Sobre la crema de la zona clara eso no
     es contraste, es niebla: la sección entera se leía descolorida. Ahora las
     fichas se apoyan en un panel verde profundo. No es negro —de negro
     venimos, el diagnóstico y la savia lo son— y no es un color traído de
     fuera: es el verde de la enredadera llevado a su tono más hondo. Blanco
     sobre verde sobre crema son tres escalones de claridad donde antes había
     uno.

   · EL PANEL NO VA A SANGRE. Mide lo que el contenedor, no lo que la
     ventana, y eso es a propósito: por el canalón de la izquierda sigue
     subiendo la enredadera, que va por DEBAJO de las secciones. Un panel de
     borde a borde la habría cortado en seco durante toda la sección.

   · EL PRECIO ESTÁ EN LA FICHA. Antes vivía escondido en el cajón y el centro
     de la ficha quedaba vacío. Puesto arriba a la derecha, en la línea del
     nombre, da peso a la cabecera y deja la mitad de abajo entera para la
     planta, que ahora puede ser grande.

   · EL DETALLE ABRE EN UNA VENTANA. El cajón que se desplegaba debajo
     empujaba media página y te dejaba leyendo con la ficha ya fuera de la
     vista. Un <dialog> centrado se lleva el foco, se cierra con Escape y no
     mueve nada de sitio.

   · LA TABLA. Las ventanas cuentan cada plan por separado, y comparar tres
     cosas de una en una no se puede. La tabla dice lo mismo en rejilla, que
     es donde se ve la diferencia. */

.s-precios {
  position: relative;
}

/* La otra mitad del descampado: los precios suben a buscar al portfolio.
   Va con `.claro` delante y no en `.s-precios` a secas porque `.claro section`
   —una clase y un tipo— pesa más que una clase sola y le devolvía el
   `--paso-y`. Es la misma trampa que obliga al `!important` del contacto. */
.claro .s-precios {
  padding-top: clamp(48px, 5vw, 84px);
  /* y menos por abajo: entre la tabla y las dudas quedaba un descampado */
  padding-bottom: clamp(48px, 5vw, 84px);
}

/* Las tarjetas descansan sobre el mismo fondo crema que la pagina. */
.vivero {
  position: relative;
  margin-top: clamp(40px, 4.4vw, 68px);
  padding: clamp(22px, 2.9vw, 46px) clamp(10px, 1.2vw, 20px);
}

/* ── La fila ──

   Dónde va la perspectiva, que es de donde venía que las fichas se vieran
   PLANAS: la tenía la fila, y la perspectiva de un elemento solo alcanza a sus
   HIJOS DIRECTOS. El que gira es el botón, que es nieto; para que la
   perspectiva bajara hasta él haría falta `preserve-3d` en todos los eslabones
   de en medio, y no lo había. O sea que los grados de inclinación se aplicaban
   sin punto de fuga: una deformación plana, sin canto ni volumen.

   La solución no es encadenar `preserve-3d` sino poner la perspectiva justo
   encima de lo que gira: en el <h3> que envuelve a cada botón. Cada ficha se
   inclina con su propio ojo, que es lo que hay que hacer cuando los objetos
   están separados: con un ojo compartido las de los lados se ven torcidas
   aunque no las toques. */

.siembra {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(12px, 1.4vw, 20px);
  align-items: stretch;
}

.siembra-dos {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  /* dos huecos y un hueco de la misma rejilla de tres: Riego e Impulso
     miden EXACTAMENTE lo que Semilla, Brote y Flor, a cualquier ancho. Con
     el tope de 760px fijo salían un 10% más anchas en escritorio y un 43%
     en una tablet apaisada. */
  --hueco: clamp(12px, 1.4vw, 20px);
  width: calc((200% - var(--hueco)) / 3);
  max-width: none;
  margin-inline: auto;
}

/* ── La carta y sus dos caras ──

   La ficha es una carta que se da la vuelta. Tres piezas y el papel de cada
   una:

   · .brote        — el OJO: pone la perspectiva. No gira nunca.
   · .brote-carta  — lo que GIRA: media vuelta sobre su eje vertical cuando
                     el artículo lleva .volteada. Es una rejilla con las dos
                     caras apiladas en la misma celda, así la carta mide lo
                     que la cara más alta y ninguna se desborda.
   · las dos caras — la delantera (el h3 con el botón) y el dorso, cada una
                     con backface-visibility: hidden: cuando la carta está de
                     espaldas, la cara que no toca no se pinta.

   El giro es una transición de CSS y no un tween: es un solo transform, la
   GPU lo compone sola, y script.js solo pone y quita la clase. */
.brote {
  position: relative;
  display: flex;
  perspective: 1050px;
}

/* ── La sombra: una mancha, no un box-shadow ──

   Dos intentos fallidos antes de esto, y los dos explican el resultado:

   1. `box-shadow` en el botón. Parpadeaba. Una sombra con desenfoque pintada
      sobre un elemento que gira en 3D se RE-RASTERIZA en cada fotograma del
      giro; ese redibujado constante es el parpadeo.
   2. `box-shadow` en una capa quieta del tamaño de la ficha. Se acabó el
      parpadeo, pero al pasar el ratón la carta se adelanta 30px hacia el ojo
      y con la perspectiva se ve MÁS GRANDE — así que la capa de debajo
      asomaba por los cuatro lados como un segundo borde.

   La solución es no usar sombra: es un óvalo difuminado dibujado con un
   degradado, más estrecho que la ficha y metido debajo de ella. Un degradado
   se pinta UNA vez y no se vuelve a tocar; lo único que cambia al pasar el
   ratón son `transform` y `opacity`, que la tarjeta gráfica compone sin
   repintar nada. No puede parpadear, y al ser más estrecha que la carta no
   puede asomar por ningún lado por mucho que la carta crezca. */
.brote::before {
  content: "";
  position: absolute;
  left: 9%;
  right: 9%;
  bottom: -10px;
  height: 46px;
  border-radius: 50%;
  background: radial-gradient(
    closest-side,
    rgba(96, 42, 55, 0.3),
    rgba(96, 42, 55, 0.14) 55%,
    transparent 100%
  );
  opacity: 0.85;
  pointer-events: none;
  transition: transform 0.55s ease, opacity 0.55s ease;
}

@media (hover: hover) {
  .brote:hover::before {
    opacity: 1;
    transform: translateY(9px) scale(1.1, 1.35);
  }
}

.brote-carta {
  position: relative;
  display: grid;
  width: 100%;
  transform-style: preserve-3d;
  will-change: transform;
  transition: transform 0.85s cubic-bezier(0.32, 0, 0.18, 1);
}

.brote.volteada .brote-carta {
  transform: rotateY(180deg);
}

/* El nombre sigue siendo un h3 y envuelve al botón: así la página no pierde
   su esquema de títulos. preserve-3d porque está en medio del sándwich: sin
   él, el botón quedaría aplanado y su inclinación de hover perdería el punto
   de fuga (la perspectiva solo baja por eslabones con preserve-3d). */
.brote-titulo {
  grid-area: 1 / 1;
  display: flex;
  width: 100%;
  font: inherit;
  transform-style: preserve-3d;
  /* La cara delantera se declara ella misma en el espacio 3D (rotateY(0))
     y esconde su propio dorso. En los iPhone con WebKit anterior,
     backface-visibility solo se respeta en hijos directos del que gira y
     con transform propio: sin estas líneas, la carta volteada enseñaba la
     delantera EN ESPEJO hasta que el motor volvía a rasterizar (vídeo de
     Sara, 31 ago). En navegadores al día no cambia nada: rotateY(0) es no
     girar. */
  transform: rotateY(0deg);
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  /* AL VOLVER, LA CARA REAPARECE ANTES DEL CANTO (0,23 de 0,85). Ver el
     porqué de los dos números en el bloque de abajo. */
  transition: visibility 0s linear 0.23s;
}

/* CINTURÓN para los WebKit donde backface-visibility no siempre se respeta:
   pasada la mitad del giro, la cara delantera se esconde por las bravas, y
   así es imposible verla en espejo haciendo de dorso (móvil de Sara,
   31 ago).

   EL CANTO NO CAE A MITAD DE TIEMPO, Y AHÍ ESTABA EL FALLO. La media vuelta
   dura 0,85s, pero la curva que la mueve —cubic-bezier(.32,0,.18,1)— arranca
   rápida: la carta llega al perfil (90°, ancho cero) al 31% del tiempo, o
   sea a los 0,266s, no a los 0,425s. Medido leyendo el propio transform,
   no calculado a ojo.

   Alrededor de ese instante van los dos relojes, y NO son iguales a
   propósito: la cara se esconde a los 0,30 (un pelo DESPUÉS del canto) y
   vuelve a los 0,23 (un pelo ANTES). Así siempre hay un solapamiento
   pequeño y nunca un hueco. El solapamiento no se ve, porque cae donde la
   carta está de perfil y el dorso —blanco opaco— la tapa entera.

   Con los relojes puestos a 0,42 (creyendo que el canto caía a la mitad)
   pasaba justo lo contrario: al volver quedaban ~150 ms con la delantera ya
   escondida y el dorso ya de espaldas, y la ficha se veía VACÍA. Eso es lo
   que Sara vio en Safari («desaparecen un segundo»). */
.brote.volteada .brote-titulo {
  visibility: hidden;
  transition: visibility 0s linear 0.3s;
}

.brote-btn {
  /* La ficha es papel blanco DENTRO del vivero, así que no puede heredar el
     claro del panel: vuelve a poner las variables en oscuro. */
  --ink-crema: #1a1712;
  --ink-crema-2: rgba(26, 23, 18, 0.66);
  --ink-crema-3: rgba(26, 23, 18, 0.42);
  --linea: rgba(26, 23, 18, 0.11);

  /* Cinco filas, y la cuarta a 1fr: esa fila hueca es donde vive la planta y
     lo que alinea el «Abrir para más información» de las cinco a la misma
     altura, midan lo que midan las frases.

     Todo va centrado. La ficha ya no tiene dos carriles —texto a la izquierda,
     planta a la derecha— porque ya no tiene que meter un precio en la esquina:
     ahora es una columna sola, nombre arriba y planta en medio. */
  position: relative;
  display: grid;
  grid-template-rows: auto auto auto 1fr auto;
  align-content: start;
  justify-items: center;
  flex: 1 1 auto;
  width: 100%;
  min-height: clamp(350px, 29vw, calc(452px * var(--esc)));
  padding: clamp(22px, 2.3vw, 32px);
  /* hueco arriba para el sello. Lo llevan las tres, lo tengan o no, para que
     los nombres queden a la misma altura */
  padding-top: clamp(48px, 4.6vw, 64px);
  border: 1px solid rgba(26, 23, 18, 0.08);
  border-radius: clamp(16px, 1.7vw, 24px);
  /* BLANCO OPACO, y esto no es una preferencia: la ficha ES la hoja blanca
     sobre la que crece la planta. El vídeo viene con fondo blanco puro y se
     pone encima sin marco; si la ficha fuera translúcida, el vídeo dibujaría
     un recuadro más claro y volveríamos a tener un cuadrado dentro de otro.
     Con el mismo blanco, el canto del vídeo no existe. */
  background: #ffffff;
  /* Solo la línea de luz del canto: la sombra exterior vive en .brote::before
     (ver arriba) porque pintada aquí, sobre el elemento que gira, parpadea. */
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9);
  /* La esquina de abajo a la derecha NO existe: el papel está levantado ahí
     (la solapa), así que la carta acaba en diagonal. Es un recorte de
     verdad — por el hueco se ve el fondo de la página—, no un triángulo
     pintado. Los 40px son los de .brote-solapa: si cambia uno, cambia el
     otro. El polígono deja pasar los otros tres picos enteros, así que el
     border-radius de esas esquinas sigue mandando. */
  /* El tamaño de la esquina levantada vive en UNA variable: la usa este
     recorte y la solapa de .brote-solapa, que tienen que medir lo mismo. En
     el móvil la ficha la reduce con su propio ancho (cqw). */
  --solapa: 40px;
  clip-path: polygon(
    0 0,
    100% 0,
    100% calc(100% - var(--solapa)),
    calc(100% - var(--solapa)) 100%,
    0 100%
  );
  font: inherit;
  color: inherit;
  text-align: center;
  cursor: pointer;
  transform-style: preserve-3d;
  /* de espaldas no se pinta: es la mitad del truco de la carta */
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  /* el transform lo escribe SOLO GSAP (aparición, hover e inclinación); este
     aviso deja la capa lista en la GPU para que el giro no estrene rasterizado */
  will-change: transform;
  transition: box-shadow 0.55s ease, border-color 0.55s ease,
    opacity 0.45s ease;
}

/* De espaldas sigue ocupando su sitio y CAZARÍA los clics del dorso: los
   backface ocultos se pintan invisibles pero siguen recibiendo el ratón. */
.brote.volteada .brote-btn {
  pointer-events: none;
}

@media (hover: hover) {
  .brote-btn:hover {
    border-color: rgba(26, 23, 18, 0.14);
    box-shadow: inset 0 1px 0 #ffffff;
  }
}

.brote-btn:focus-visible {
  outline: 2px solid var(--rosa-tinta);
  outline-offset: 5px;
}

.brote-elegido .brote-btn {
  border-color: rgba(194, 104, 122, 0.45);
}

/* La luz del papel. FIJA, cayendo desde arriba: antes seguía al cursor con
   dos variables que script.js escribía en cada mousemove, y cada escritura
   era repintar el degradado —o sea la ficha entera— a sesenta por segundo.
   Era la otra mitad del retardo del hover. Encendida con el ratón y quieta,
   solo anima su opacidad, que es composición pura.

   Va en ::before y no en ::after por orden de pintado: los pseudoelementos
   posicionados se pintan en el orden del DOM, así que ::after caería POR
   ENCIMA de la planta y le echaría un velo blanco. En ::before queda debajo, y
   la planta —que va en multiply— se multiplica sobre la luz. Que es lo que
   hace la tinta sobre un papel iluminado. */
.brote-btn::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  border-radius: inherit;
  pointer-events: none;
  opacity: 0;
  background: radial-gradient(
    62% 52% at 50% 0%,
    rgba(255, 246, 232, 0.9),
    rgba(255, 240, 228, 0.3) 44%,
    transparent 74%
  );
  transition: opacity 0.5s ease;
}

@media (hover: hover) {
  .brote-btn:hover::before {
    opacity: 0.9;
  }
}

/* El texto por encima de todo. La planta NO lleva z-index a propósito: darle
   uno la convertiría en contexto de apilamiento propio, y entonces el
   `multiply` del vídeo se mezclaría solo consigo mismo —o sea, contra nada— y
   volvería a verse el recuadro blanco. Sin z-index se mezcla con el fondo de
   la ficha, que es lo que tiene que hacer. */
.brote-nombre,
.brote-raya,
.brote-frase,
.brote-accion {
  position: relative;
  z-index: 1;
}

/* ── El sello ──
   «La más elegida» dicho arriba, donde se lee antes que nada, y no colgando
   bajo la frase como una nota a pie. Centrado, como todo lo demás. */
.brote-sello {
  position: absolute;
  top: clamp(14px, 1.3vw, 19px);
  left: 50%;
  transform: translateX(-50%);
  z-index: 2;
  padding: 5px 11px 4px;
  border-radius: 999px;
  background: var(--rosa-tinta);
  font-family: "Oswald", sans-serif;
  font-weight: 400;
  font-size: calc(9.5px * var(--esc));
  letter-spacing: 0.17em;
  text-transform: uppercase;
  color: #fff5f6;
  white-space: nowrap;
}

/* El sello lleva el texto dos veces: la frase entera y una corta («La más
   elegida», la misma que usa la tabla). En escritorio y en fichas anchas
   se ve la larga; en una ficha de bolsillo de 140 px la larga no cabe ni
   a 8 px y desbordaba la carta — ahí sale la corta (ver el traje de móvil). */
.sello-corta {
  display: none;
}

/* ── El nombre ──
   Solo. El precio ya no va en la ficha: quien mira los planos no tiene que
   empezar por el número, tiene que empezar por qué es cada uno. La cifra vive
   en la ventana que se abre y en la tabla comparativa, o sea a un clic y a un
   scroll — puesta donde ya se está comparando, no donde se está mirando. */
.brote-nombre {
  grid-row: 1;
  font-family: "Anton", "Arial Narrow", sans-serif;
  font-weight: 400;
  font-size: clamp(20px, 1.85vw, calc(29px * var(--esc)));
  line-height: 1;
  text-transform: uppercase;
  letter-spacing: 0.025em;
  color: var(--ink-crema);
}

/* La línea bajo el nombre. Corta y centrada: de canto a canto de la ficha
   partía la columna en dos mitades y con el nombre centrado encima se leía
   como el filo de una tabla. Al pasar el ratón crece desde el centro hacia
   los dos lados, que es el gesto que corresponde a algo centrado. */
.brote-raya {
  grid-row: 2;
  position: relative;
  display: block;
  width: clamp(34px, 3.4vw, 52px);
  height: 1px;
  margin: 15px 0 17px;
  background: rgba(26, 23, 18, 0.16);
}

.brote-raya::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--rosa-hondo);
  opacity: 0.75;
  transform: scaleX(0);
  transform-origin: center center;
  transition: transform 0.65s cubic-bezier(0.22, 1, 0.36, 1);
}

@media (hover: hover) {
  .brote-btn:hover .brote-raya::after {
    transform: scaleX(1);
  }
}

.brote-frase {
  grid-row: 3;
  /* ya no hay carril de la derecha que respetar, pero sigue con tope: una
     frase de una línea larguísima no se lee, se barre */
  max-width: 25ch;
  font-family: "Libre Baskerville", Georgia, serif;
  font-size: calc(14px * var(--esc));
  line-height: 1.62;
  color: var(--ink-crema-2);
  text-wrap: balance;
}

.brote-accion {
  grid-row: 5;
  align-self: end;
  justify-self: center;
  margin-top: clamp(20px, 2.2vw, 30px);
  font-family: "Oswald", sans-serif;
  font-weight: 400;
  font-size: calc(11px * var(--esc));
  letter-spacing: 0.19em;
  text-transform: uppercase;
  color: var(--ink-crema);
}

/* ── La esquina levantada ──
   La de abajo a la derecha, doblada como la de un folio: es la señal de que
   la carta tiene dorso, dicha con papel y no con un icono.

   La esquina de la carta NO ESTÁ: el papel se ha levantado, así que ahí no
   queda nada — la carta acaba en diagonal y por el hueco se ve el fondo de
   la página de verdad, porque el corte es un recorte real (el clip-path del
   botón, ver .brote-btn), no un triángulo pintado del color del fondo. Se
   probó pintar ese hueco con sombra dentro y quedaba una mancha oscura, como
   si la esquina siguiera ahí pero sucia.

   Lo único que se dibuja es la solapa: el trozo doblado hacia dentro, o sea
   el REVERSO del folio, apagado junto al pliegue y blanco en la punta
   suelta — ese degradado en diagonal es todo el volumen. La punta va
   achaflanada, no en pico: el papel de verdad se curva. Su hipotenusa cae
   sobre la misma diagonal del recorte, así que la línea del doblez y el
   canto de la carta son la misma línea. */
.brote-solapa {
  position: absolute;
  right: 0;
  bottom: 0;
  width: var(--solapa, 40px);
  height: var(--solapa, 40px);
  pointer-events: none;
}

.brote-solapa::after {
  content: "";
  position: absolute;
  inset: 0;
  clip-path: polygon(0 100%, 100% 0, 9% 3%, 3% 9%);
  background: linear-gradient(
    315deg,
    #e2d5c8 0%,
    #f0e8df 26%,
    #fbf7f2 58%,
    #ffffff 100%
  );
}

/* ── El dorso ──
   La otra cara del folio: mismo papel, la información del plan bien
   ordenada de arriba abajo. Nace ya girado 180°: cuando la carta da la
   media vuelta, él queda de frente.

   Todo el dorso se puede pulsar para volver (script.js §5d), pero además
   lleva el «Voltear de vuelta» escrito abajo, porque un gesto que no se
   anuncia no existe. */
.brote-dorso {
  --ink-crema: #1a1712;
  --ink-crema-2: rgba(26, 23, 18, 0.66);
  --ink-crema-3: rgba(26, 23, 18, 0.42);
  --linea: rgba(26, 23, 18, 0.11);

  grid-area: 1 / 1;
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: clamp(26px, 2.8vw, 38px) clamp(20px, 2.2vw, 30px);
  border: 1px solid rgba(26, 23, 18, 0.08);
  border-radius: clamp(16px, 1.7vw, 24px);
  background: #ffffff;
  /* sin sombra exterior: la pone .brote::before, que no gira */
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9);
  color: var(--ink-crema-2);
  cursor: pointer;
  transform: rotateY(180deg);
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  /* como en la carta y el botón: la capa lista en la GPU desde el principio.
     En el iPhone con WebKit viejo el dorso tardaba en pintarse al voltear y
     el hueco se veía vacío un instante (vídeo de Sara, 31 ago). */
  will-change: transform;
  /* de frente no debe cazar clics ni tabulaciones */
  pointer-events: none;
  outline: none;
}

.brote.volteada .brote-dorso {
  pointer-events: auto;
}

.dorso-quien {
  font-family: "Oswald", sans-serif;
  font-size: calc(10px * var(--esc));
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--rosa-tinta);
}

.dorso-titulo {
  margin-top: 12px;
  max-width: 24ch;
  font-family: "Libre Baskerville", Georgia, serif;
  font-size: clamp(14px, 1.15vw, calc(16.5px * var(--esc)));
  line-height: 1.5;
  color: var(--ink-crema);
  text-wrap: balance;
}

/* Dos párrafos y ya: para quién es este plan, y lo esencial de lo que trae.
   Hubo una lista de tres puntos, y luego además la línea del plazo y las
   rondas, y sobraban — el detalle fino ya lo da la tabla comparativa de
   abajo, y repetirlo aquí convertía el dorso en otra ficha técnica. El dorso
   responde a la única pregunta que la tabla no responde: «¿este es el mío?». */
.dorso-para {
  margin-top: clamp(16px, 1.8vw, 24px);
  max-width: 26ch;
  font-size: calc(13.5px * var(--esc));
  line-height: 1.65;
  color: var(--ink-crema-2);
  text-wrap: pretty;
}

.dorso-incluye {
  margin-top: clamp(14px, 1.5vw, 20px);
  padding-top: clamp(14px, 1.5vw, 20px);
  border-top: 1px solid var(--linea);
  max-width: 26ch;
  font-size: calc(12.5px * var(--esc));
  line-height: 1.6;
  color: var(--ink-crema-3);
  text-wrap: pretty;
}

.dorso-plazo {
  margin-top: clamp(12px, 1.4vw, 18px);
  font-size: calc(12px * var(--esc));
  color: var(--ink-crema-3);
}

/* El precio es lo último que se lee antes de la llamada: aquí sí, en grande.
   El margin-top AUTO es lo que cuadra las tres cartas: el texto de arriba
   mide lo que mida en cada una, y el bloque precio + botón + volver se va
   siempre al fondo — los tres botones quedan a la misma altura aunque una
   frase ocupe dos líneas y otra tres. */
.dorso-precio {
  display: flex;
  align-items: baseline;
  gap: 7px;
  margin-top: auto;
  padding-top: clamp(16px, 1.8vw, 24px);
}

.dorso-precio span {
  font-family: "Oswald", sans-serif;
  font-size: calc(10px * var(--esc));
  letter-spacing: 0.19em;
  text-transform: uppercase;
  color: var(--ink-crema-3);
}

.dorso-precio b {
  font-family: "Anton", "Arial Narrow", sans-serif;
  font-weight: 400;
  font-size: clamp(22px, 2vw, calc(30px * var(--esc)));
  line-height: 1;
  color: var(--rosa-tinta);
  font-variant-numeric: tabular-nums;
}

.dorso-precio b em {
  font-style: normal;
  font-size: 0.62em;
  margin-left: 2px;
}

.dorso-cta {
  margin-top: clamp(12px, 1.4vw, 18px);
  padding: 9px 18px;
  border-radius: 999px;
  background: var(--rosa-tinta);
  font-family: "Oswald", sans-serif;
  font-size: calc(11px * var(--esc));
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: #fff5f6;
  text-decoration: none;
  transition: transform 0.35s ease, background 0.35s ease;
}

@media (hover: hover) {
  .dorso-cta:hover {
    transform: translateY(-2px);
    background: #7d3a4a;
  }
}

/* Lucide ArrowUpRight / ArrowRight: avoid platform emoji substitution. */
.icono-flecha {
  display: inline-block;
  width: 1em;
  height: 1em;
  vertical-align: -0.125em;
  flex-shrink: 0;
  pointer-events: none;
}

.dorso-cta i {
  font-style: normal;
}

.dorso-volver {
  margin-top: clamp(12px, 1.4vw, 18px);
  padding: 0;
  border: 0;
  background: none;
  font-family: "Oswald", sans-serif;
  font-size: calc(10px * var(--esc));
  letter-spacing: 0.19em;
  text-transform: uppercase;
  color: var(--ink-crema-3);
  cursor: pointer;
  transition: color 0.3s ease;
}

@media (hover: hover) {
  .brote-dorso:hover .dorso-volver,
  .dorso-volver:hover {
    color: var(--ink-crema);
  }
}

.dorso-volver:focus-visible,
.brote-dorso:focus-visible {
  outline: 2px solid var(--rosa-tinta);
  outline-offset: 3px;
  border-radius: 4px;
}

/* Sin JS la carta no puede girar: el dorso se muestra debajo de la cara,
   sin rotación, y la solapa y la invitación a voltear se esconden. */
html:not(.js) .brote-carta {
  display: block;
}

html:not(.js) .brote-dorso {
  transform: none;
  pointer-events: auto;
  cursor: default;
  margin-top: 12px;
}

html:not(.js) .brote-solapa,
html:not(.js) .brote-accion,
html:not(.js) .dorso-volver {
  display: none;
}

/* ── La planta ──
   NO es una lámina metida en la ficha. La ficha es la hoja blanca y la planta
   crece sobre ella, en la esquina de abajo a la derecha: sin marco, sin borde,
   sin fondo propio y sin recorte. Un recuadro dentro del recuadro es
   exactamente lo que había que quitar.

   Lo que lo hace posible es que la ficha sea blanco opaco y el vídeo venga con
   fondo blanco puro: el canto del vídeo cae sobre el mismo blanco y deja de
   existir. Y por si el blanco del archivo no sale exacto —de un generador de
   vídeo nunca sale exacto— va además en `multiply`, que convierte cualquier
   blanco en transparente y solo deja pasar lo oscuro. Es la manera de que un
   vídeo rectangular se comporte como tinta sobre papel.

   Tres capas sobre el mismo hueco, en este orden de respaldo: el dibujo
   vectorial está siempre puesto y es lo que se ve mientras no haya nada más;
   si la fotografía carga, tapa al dibujo; si además hay vídeo y el ratón está
   encima, el vídeo tapa a la fotografía. Así la sección funciona entera sin un
   solo archivo en assets/precios/ y se va enriqueciendo sola.

   Los nombres de archivo van en data- y no en src: un <img src> que no existe
   descarga un 404 y pinta el icono roto aunque esté oculto.

   El hueco no puede salirse de la ficha ni un píxel, y esto es la otra cara
   del truco del `multiply`: la mezcla solo ocurre DENTRO del contexto de
   apilamiento de la ficha, o sea sobre su fondo blanco. Lo que asome por fuera
   del canto ya no tiene fondo contra el que multiplicarse, y ahí el blanco del
   vídeo vuelve a ser blanco: un recuadro asomando por la esquina, que es justo
   lo que se venía a quitar. Y no se puede recortar con overflow, porque
   overflow aplasta el 3D de los hijos y se pierde el relieve.

   Ya no va colocada a mano con cuatro coordenadas: **es la fila 4 de la
   rejilla**, la que vale 1fr. Antes ocupaba el carril derecho y su borde de
   arriba era un `top` en clamp() calculado a ojo contra lo que midieran el
   nombre y la frase; con el texto centrado esa cuenta se rompía en cuanto una
   frase pasaba de una línea a dos. Siendo una celda, el hueco lo reparte la
   propia rejilla: la planta ocupa exactamente lo que sobra entre la frase y el
   «Abrir para más información», y no puede pisar a ninguno de los dos.

   `justify-self: stretch` porque el contenedor lleva `justify-items: center`,
   que si no le encogería la caja a su contenido. */
.brote-lienzo {
  grid-row: 4;
  position: relative;
  justify-self: stretch;
  width: 100%;
  margin-top: clamp(10px, 1.2vw, 18px);
  pointer-events: none;
  transform-origin: center bottom;
  transition: transform 0.9s cubic-bezier(0.22, 1, 0.36, 1);
}

/* Al pasar el ratón la planta se acerca un punto. Es lo único que se mueve
   además de la propia animación del vídeo: más sería competir con ella. */
@media (hover: hover) {
  .brote-btn:hover .brote-lienzo {
    transform: scale(1.06);
  }
}

.brote-marca {
  position: absolute;
  inset: 0;
  line-height: 0;
  transition: opacity 0.6s ease;
}

/* El dibujo llena el hueco entero y quien lo encaja es `preserveAspectRatio`,
   que es lo que un SVG tiene en vez de `object-fit`. Con `xMaxYMax meet` el
   contenido se escala hasta caber por los dos lados y se ancla abajo al
   centro: literalmente el mismo comportamiento que `object-fit: contain` +
   `object-position: center bottom` de la fotografía. Por eso el dibujo y la
   foto ocupan lo mismo, y el día que se cambie uno por otro la planta no da
   un salto.

   Se llegó aquí después de dos intentos fallidos, y los dos por lo mismo: un
   <svg> con viewBox y sin width/height propios no tiene tamaño, solo
   proporción, así que **cualquier porcentaje de alto que se le ponga es
   inestable**. Con `height: 92%` el navegador acababa resolviéndolo contra el
   ancho, y con `max-height: 92%` ni siquiera lo resolvía, porque el SVG era
   además elemento de una rejilla y ahí el porcentaje contra un área sin alto
   definido se descarta. Se salía 74px por debajo de la ficha en pantallas
   estrechas. Dándole 100% y 100% no hay porcentaje que resolver: el tamaño lo
   pone la caja y la proporción la respeta el propio SVG. */
.brote-marca svg {
  width: 100%;
  height: 100%;
  overflow: visible;
  /* SIN `filter: drop-shadow`, y esto es una lección cara.

     Le daba a la planta una sombra propia preciosa y la animación de
     crecimiento pasó a ir a trompicones. El motivo: un filtro CSS obliga al
     navegador a RE-RASTERIZAR el elemento entero en cada fotograma en el que
     algo de dentro cambia — y aquí lo que cambia es el dasharray del tallo,
     o sea que cambia en los sesenta fotogramas del crecimiento. Sombra
     recalculada sesenta veces sobre un SVG que además va en `multiply`
     dentro de una tarjeta en 3D.

     El volumen se queda —viene de los degradados, que son gratis: se
     resuelven una vez al pintar—; lo que se va es el filtro. */
}

/* El almacén de degradados: no pinta, solo guarda. Sin sacarlo del flujo, un
   <svg> vacío ocupa su tamaño por defecto (300×150) y abre un hueco en medio
   de la página. */
.tinta-plantas {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
  pointer-events: none;
}

.bl-foto,
.bl-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: center bottom;
  /* el blanco del archivo se vuelve transparente y solo pasa la planta */
  mix-blend-mode: multiply;
  opacity: 0;
  transition: opacity 0.5s ease;
}

.brote-lienzo.con-foto .bl-foto {
  opacity: 1;
}

/* con fotografía puesta el dibujo sobra, pero se queda en el DOM: si el vídeo
   no llega a cargar nunca, sigue siendo el respaldo */
.brote-lienzo.con-foto .brote-marca {
  opacity: 0;
}

/* El relevo entre foto y vídeo va sin fundido: los dos empiezan por el mismo
   fotograma, así que cruzarlos con opacidad solo produce un parpadeo gris. */
.brote-lienzo.con-video .bl-video {
  opacity: 1;
  transition: none;
}

.brote-lienzo.con-video .bl-foto {
  opacity: 0;
  transition: none;
}

/* La guía solo existe donde hay raíl (móvil). */
.siembra-guia {
  display: none;
}

/* ── El empalme ──
   Sin raya. Se probó un tallo vertical de 1px y sobre el verde no se lee como
   un tallo: se lee como el canto de una tabla. El aire ya separa. */
/* ── La línea de los extras ──
   Debajo de la tabla quedan dos párrafos seguidos, este y la letra pequeña del
   IVA, y tienen que estar CUADRADOS: mismo canto izquierdo y misma medida.
   Se probó este centrado y la letra pequeña a bandera —para que no se
   confundieran— y lo que se veía era un desajuste (petición de Sara, 8 sep).
   Se distinguen igual, pero por la tinta y no por la posición: este lleva la
   del texto corrido y el de abajo la de las notas, que es más apagada.
   Ni borde, ni fondo, ni caja: no compite con nada. El «Ver ejemplos»
   reaprovecha .vl-enlace, el botón con pinta de enlace de las ventanas. */
.extra {
  margin-top: clamp(34px, 3.8vw, 54px);
  /* EXACTAMENTE la misma medida que .letra-pequena, que es la que va justo
     debajo. No vale copiarle el «72ch»: la ch es el ancho de un cero en la
     letra del propio párrafo, y este va a 14,5 px y el de abajo a 13,5, así
     que los mismos 72ch daban 45 px más de largo y el canto derecho no
     cuadraba. Corrigiendo por la proporción de los dos cuerpos, la cuenta sale
     idéntica y sigue saliendo idéntica cuando --esc estira la letra en las
     pantallas grandes, porque estira las dos igual. */
  max-width: calc(72ch * 13.5 / 14.5);
  font-size: calc(14.5px * var(--esc));
  line-height: 1.75;
  color: var(--ink-crema-2);
  text-wrap: pretty;
}

.entre {
  margin: clamp(38px, 4.2vw, 64px) auto clamp(26px, 2.8vw, 42px);
  text-align: center;
}

.entre-titulo {
  font-family: "Libre Baskerville", Georgia, serif;
  font-style: italic;
  font-size: clamp(19px, 1.85vw, calc(27px * var(--esc)));
  line-height: 1.3;
  color: var(--ink-crema);
}

.entre-texto {
  margin: 13px auto 0;
  max-width: 46ch;
  font-size: calc(14.5px * var(--esc));
  line-height: 1.7;
  color: var(--ink-crema-2);
  text-wrap: pretty;
}

/* ══ La ventana ══

   Un <dialog> de verdad, no un div con aspecto de ventana: al abrirse con
   showModal() el navegador la sube a la capa superior, atrapa el foco dentro,
   deja el resto de la página inerte y cierra con Escape él solo. Todo eso
   escrito a mano son cien líneas y media docena de maneras de dejar el foco
   perdido detrás del velo. */
.ventana {
  width: min(calc(940px * var(--esc)), calc(100vw - 32px));
  max-height: calc(100vh - 40px);
  /* dvh: lo que se ve de verdad en el móvil, con la barra como esté */
  max-height: calc(100dvh - 40px);
  margin: auto;
  padding: 0;
  border: 0;
  background: none;
  overflow: visible;
  color: var(--ink-crema-2);
}

.ventana::backdrop {
  background: rgba(22, 16, 13, 0.62);
  backdrop-filter: blur(7px);
  -webkit-backdrop-filter: blur(7px);
  opacity: 0;
}

/* El velo no se puede animar con GSAP —es un pseudoelemento, no está en el
   DOM— así que va con animación de CSS, que es lo único que lo alcanza. */
.ventana[open]::backdrop {
  animation: velo 0.5s cubic-bezier(0.22, 1, 0.36, 1) forwards;
}

.ventana.cerrando::backdrop {
  animation: velo-fuera 0.3s ease forwards;
}

@keyframes velo {
  to {
    opacity: 1;
  }
}

@keyframes velo-fuera {
  from {
    opacity: 1;
  }
  to {
    opacity: 0;
  }
}

/* La hoja se mide contra el <dialog>, no contra la ventana del navegador. Con
   `max-height: 100vh` en las dos, la caja del dialog acababa 35px más corta
   que su contenido y salía una barra de scroll dentro de una hoja que cabía
   entera. Con el dialog en flex, la hoja hereda su alto y solo desborda
   cuando de verdad no cabe. */
.ventana[open] {
  display: flex;
}

.ventana-hoja {
  position: relative;
  flex: 0 1 auto;
  width: 100%;
  /* El tope va en medidas de la PANTALLA, no en el 100% del dialog: en los
     iPhone con WebKit anterior, un porcentaje contra una caja que solo
     tiene max-height se resuelve como nada, la fila del cuerpo (1fr) se
     quedaba en cero y la ventana entera salía aplastada como una pastilla
     al fondo (vídeo de Sara, 31 ago). Con el mismo valor que ya tiene el
     dialog, en navegadores al día no cambia nada. */
  max-height: calc(100vh - 40px);
  max-height: calc(100dvh - 40px);
  /* La hoja NO desliza entera: es una rejilla con la cabecera (cejilla y
     título) quieta y el cuerpo deslizando debajo. Así el botón de cerrar
     —que es absoluto dentro de la hoja— se queda a la vista en el móvil;
     antes, en un texto legal de tres pantallas, se iba con el primer
     gesto y solo quedaba la franja del velo para cerrar. */
  display: grid;
  grid-template-rows: auto auto minmax(0, 1fr);
  overflow: hidden;
  /* en un móvil de 360 px, 28 px por lado eran un sexto de la hoja */
  padding: clamp(20px, 5vw, calc(52px * var(--esc)));
  border-radius: clamp(18px, 1.8vw, 28px);
  background: linear-gradient(172deg, #ffffff, #fbf6f1);
  box-shadow: 0 60px 120px -50px rgba(30, 20, 16, 0.75),
    inset 0 1px 0 #ffffff;
}

/* recibe el foco al abrir, pero sin dibujar un cerco alrededor de la hoja
   entera: quien la abrió con el ratón no espera ver un recuadro */
.ventana-hoja:focus {
  outline: none;
}

.ventana-cerrar {
  position: absolute;
  top: clamp(14px, 1.5vw, 22px);
  right: clamp(14px, 1.5vw, 22px);
  z-index: 2;
  width: 40px;
  height: 40px;
  padding: 0;
  border: 1px solid var(--linea);
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.8);
  cursor: pointer;
  transition: border-color 0.4s ease, background 0.4s ease;
}

@media (hover: hover) {
  .ventana-cerrar:hover {
    border-color: rgba(26, 23, 18, 0.28);
    background: #ffffff;
  }
}

.ventana-cerrar span {
  position: absolute;
  inset: 0;
}

.ventana-cerrar span::before,
.ventana-cerrar span::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 13px;
  height: 1px;
  background: var(--ink-crema);
}

.ventana-cerrar span::before {
  transform: translate(-50%, -50%) rotate(45deg);
}

.ventana-cerrar span::after {
  transform: translate(-50%, -50%) rotate(-45deg);
}

.v-quien {
  position: relative;
  font-family: "Oswald", sans-serif;
  font-size: 10.5px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--rosa-tinta);
}

.v-titulo {
  position: relative;
  margin: 12px 0 clamp(24px, 2.6vw, 34px);
  max-width: 30ch;
  font-family: "Libre Baskerville", Georgia, serif;
  font-weight: 400;
  font-size: clamp(20px, 2vw, calc(30px * var(--esc)));
  line-height: 1.34;
  color: var(--ink-crema);
  text-wrap: pretty;
}

/* ── Las tres ventanas legales ──
   Reaprovechan entera la máquina de las fichas de precios: mismo <dialog>,
   mismo velo, mismo cierre y el mismo `autofocus` en la hoja. Lo único suyo es
   que son texto corrido, así que la hoja se estrecha —una línea de 940px no se
   lee— y no llevan marca de agua detrás.

   Y son texto largo de verdad, así que casi siempre habrá que hacer scroll
   dentro de la hoja. Eso ya lo trae `.ventana-hoja` (`overflow: hidden auto` y
   `overscroll-behavior: contain`), que además impide que la rueda se escape a
   la página de detrás al llegar al final. */
.ventana-legal {
  width: min(calc(680px * var(--esc)), calc(100vw - 32px));
}

/* Las filas que suben y bajan: el cuerpo del texto legal, y el MARCO de la
   tabla —no la tabla, que esa va de lado (ver .vt-marco / .vt-cuerpo). */
.vl-cuerpo,
.vt-marco {
  min-height: 0;
  overflow: hidden auto;
  overscroll-behavior: contain;
  /* Aquí iba -webkit-overflow-scrolling: touch. FUERA: es una reliquia que
     en los iPhone con WebKit anterior mete el contenido en una capa aparte
     que a veces no se pinta hasta que tocas — la mitad del «no se muestra»
     de las ventanas. El scroll con inercia es el de serie desde iOS 13. */
}

/* LA CAJA DE DENTRO SOLO VA DE LADO. Cuando los dos sentidos vivían en la
   misma caja, el dedo nunca arrastra recto: cada gesto lateral se llevaba la
   tabla un poco hacia arriba, la cabecera de los planes se iba de vista y la
   ventana parecía moverse sola. Con un sentido en cada caja, el navegador
   engancha una u otra según cómo empiece el gesto y ya no las mezcla. */
.vt-cuerpo {
  overflow: auto hidden;
  overscroll-behavior-x: contain;
}

/* El foco va a estos cuerpos al abrirse la ventana, y en el iPhone cada
   toque dentro volvía a marcarlo: el anillo azul de serie enmarcaba la
   tabla entera como si estuviera rota (foto de Sara, 1 sep). Fuera del
   todo — también el de :focus-visible, que hay WebKit que lo encienden
   con el dedo: dentro de una ventana modal la propia hoja ya dice dónde
   está el foco, y las flechas y el AvPág siguen moviendo el texto igual. */
.vl-cuerpo:focus,
.vl-cuerpo:focus-visible,
.vt-cuerpo:focus,
.vt-cuerpo:focus-visible {
  outline: none;
}

.vl-cuerpo {
  position: relative;
  padding-top: clamp(22px, 2.4vw, 30px);
  border-top: 1px solid var(--linea);
  font-size: calc(14.5px * var(--esc));
  line-height: 1.72;
  color: var(--ink-crema-2);
  /* Este es el que se desplaza de verdad dentro de la ventana. Al llegar al
     final, el gesto NO se contagia a la página de detrás: sin esto, seguir
     bajando movía la web por debajo del velo. */
  overscroll-behavior: contain;
}

/* Recibe el foco al abrir la ventana (script.js le pone tabindex), y no tiene
   por qué enseñar el aro por ello: no es un control, es una zona de lectura.
   El aro del teclado sigue saliendo en los enlaces y en el botón de cerrar. */
.vl-cuerpo:focus,
.vl-cuerpo:focus-visible {
  outline: none;
}

/* El resumen en una línea, antes de la letra pequeña: quien abre esto quiere
   saber qué le hacen con sus datos, no leerse ocho epígrafes. */
.vl-entrada {
  margin-bottom: clamp(22px, 2.4vw, 30px);
  padding: 16px 20px;
  border-left: 2px solid var(--rosa-hondo);
  border-radius: 0 10px 10px 0;
  background: rgba(247, 200, 205, 0.2);
  font-family: "Libre Baskerville", Georgia, serif;
  font-size: calc(15px * var(--esc));
  line-height: 1.62;
  color: var(--ink-crema);
}

.vl-cuerpo h5 {
  margin: clamp(24px, 2.6vw, 34px) 0 8px;
  font-family: "Oswald", sans-serif;
  font-weight: 400;
  font-size: calc(11.5px * var(--esc));
  letter-spacing: 0.19em;
  text-transform: uppercase;
  color: var(--ink-crema);
}

.vl-cuerpo h5:first-child {
  margin-top: 0;
}

/* ── Los titulares de la ventana de extras ──
   Los textos legales son un documento y sus titulillos tienen que pasar
   desapercibidos; esta ventana es una LISTA de cosas que se pueden pedir, y
   ahí cada titular es la cosa. Se le da presencia por tres sitios y ninguno es
   la negrita: de Oswald solo hay un grosor cargado —el 400 apunta al mismo
   archivo que el 300—, así que pedir negrita solo consigue que el navegador
   la finja engordando los trazos, y a 13 px en versalitas eso emborrona.
   Se sube el cuerpo, se aprieta un poco el espaciado (a más tamaño, menos
   falta) y se le pone delante el pétalo de la casa: el mismo que marca cada
   síntoma del diagnóstico, misma forma y mismo rosa. */
#v-extras .vl-cuerpo h5 {
  position: relative;
  margin-top: clamp(28px, 3vw, 38px);
  font-size: calc(13px * var(--esc));
  letter-spacing: 0.15em;
}

/* el pétalo cuelga a la izquierda y el bloque entero —titular y párrafo—
   se mete hacia dentro, que es como se lee una lista y no una sangría suelta */
#v-extras .vl-cuerpo h5,
#v-extras .vl-cuerpo h5 + p {
  padding-left: 23px;
}

#v-extras .vl-cuerpo h5::before {
  content: "";
  position: absolute;
  left: 0;
  /* media línea del renglón, para que se pose en la primera letra */
  top: 0.3em;
  width: 9px;
  aspect-ratio: 1;
  border-radius: 50% 50% 50% 0;
  transform: rotate(-18deg);
  background: var(--rosa-hondo);
}

.vl-cuerpo p + p {
  margin-top: 0.85em;
}

.vl-cuerpo ul {
  margin: 10px 0 0;
  padding: 0;
  list-style: none;
}

.vl-cuerpo li {
  position: relative;
  padding-left: 18px;
  margin-top: 7px;
}

.vl-cuerpo li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.72em;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--rosa-hondo);
  opacity: 0.55;
}

.vl-cuerpo strong {
  font-weight: 600;
  color: var(--ink-crema);
}

.vl-cuerpo a,
.vl-enlace {
  color: var(--rosa-tinta);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
  text-decoration-color: rgba(150, 72, 90, 0.4);
  transition: text-decoration-color 0.35s ease;
}

@media (hover: hover) {
  .vl-cuerpo a:hover,
  .vl-enlace:hover {
    text-decoration-color: var(--rosa-tinta);
  }
}

/* El salto de cookies a privacidad. Es un <button> con pinta de enlace porque
   no navega a ninguna parte: cierra una ventana y abre la otra. */
.vl-enlace {
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  cursor: pointer;
}

.vl-fecha {
  margin-top: clamp(28px, 3vw, 40px);
  padding-top: 16px;
  border-top: 1px solid var(--linea);
  font-size: 12.5px;
  color: var(--ink-crema-3);
}

/* ── La tabla ──
   El resumen visual. Va fuera del vivero y sobre la crema: después del panel
   oscuro, volver a la luz es lo que le da respiro a la sección. */
.tabla-planes {
  margin-top: clamp(56px, 6vw, 96px);
}

.tp-cejilla {
  font-family: "Oswald", sans-serif;
  font-size: calc(10.5px * var(--esc));
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--rosa-tinta);
}

.tp-titulo {
  margin-top: 11px;
  font-family: "Libre Baskerville", Georgia, serif;
  font-style: italic;
  font-weight: 400;
  font-size: clamp(21px, 2.1vw, calc(32px * var(--esc)));
  line-height: 1.3;
  color: var(--ink-crema);
}

/* La tabla no se reordena en móvil: se desliza. Una comparativa que se apila
   en columnas deja de ser una comparativa. */
.tp-marco {
  margin-top: clamp(22px, 2.4vw, 34px);
  overflow-x: auto;
  border-radius: clamp(14px, 1.4vw, 22px);
  box-shadow: 0 34px 66px -48px rgba(96, 42, 55, 0.55);
  -webkit-overflow-scrolling: touch;
}

.tabla-planes table {
  width: 100%;
  min-width: 680px;
  border-collapse: collapse;
  background: #ffffff;
  font-size: calc(13.5px * var(--esc));
}

.tabla-planes thead th,
.tabla-planes thead td {
  padding: clamp(18px, 2vw, 26px) 16px clamp(14px, 1.5vw, 18px);
  vertical-align: bottom;
  text-align: center;
}

.tabla-planes thead th {
  font-family: "Anton", "Arial Narrow", sans-serif;
  font-weight: 400;
  font-size: clamp(16px, 1.5vw, calc(22px * var(--esc)));
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--ink-crema);
}

/* El sello «La más elegida» va ENCIMA del nombre, no debajo: así los tres
   nombres de plan caen a la misma altura (las celdas van alineadas abajo) y
   la columna marcada se anuncia antes de decir cómo se llama. Por eso el aire
   va por debajo del sello y no por encima. */
.tabla-planes thead th span {
  display: block;
  margin-bottom: 6px;
  font-family: "Oswald", sans-serif;
  font-size: calc(10.5px * var(--esc));
  letter-spacing: 0.17em;
  color: var(--rosa-tinta);
}

/* La columna de en medio va marcada de arriba abajo. Es la que queremos que
   se elija, y en una tabla eso se dice con un fondo, no con un adjetivo. */
.tabla-planes th:nth-child(3),
.tabla-planes td:nth-child(3) {
  background: rgba(247, 200, 205, 0.16);
}

.tabla-planes thead .tp-destacada {
  border-radius: 14px 14px 0 0;
  box-shadow: inset 0 2px 0 var(--rosa-hondo);
}

/* Los dos colores de la tabla son propios y no las variables de apoyo de la
   página. `--ink-crema-3` es tinta al 42 % y está pensado para una nota suelta
   al pie, no para una columna entera de texto de 13px: en la tabla no se leía.
   La primera columna sube a 0,78 y pasa a seminegrita —es la pregunta de cada
   fila, tiene que sostener la lectura—, y las celdas van a tinta casi plena.
   No es un capricho de contraste: si esta tabla no se lee, no compara nada. */
.tabla-planes tbody th {
  padding: clamp(13px, 1.4vw, 17px) 20px;
  width: 34%;
  text-align: left;
  font-family: "Inter", system-ui, sans-serif;
  font-weight: 500;
  font-size: calc(13.5px * var(--esc));
  line-height: 1.5;
  color: rgba(26, 23, 18, 0.78);
  border-top: 1px solid var(--linea);
}

.tabla-planes tbody td {
  padding: clamp(13px, 1.4vw, 17px) 16px;
  text-align: center;
  line-height: 1.5;
  color: rgba(26, 23, 18, 0.86);
  border-top: 1px solid var(--linea);
}

/* La fila de la animación es el eje de la comparación: es lo que de verdad
   separa un plan del siguiente, así que se lee más fuerte que las demás. */
.tabla-planes tr.tp-eje th,
.tabla-planes tr.tp-eje td {
  background: rgba(26, 23, 18, 0.035);
  color: var(--ink-crema);
}

.tabla-planes tr.tp-eje td:nth-child(3) {
  background: rgba(247, 200, 205, 0.24);
}

.tabla-planes tr.tp-precio th,
.tabla-planes tr.tp-precio td {
  border-top: 1px solid rgba(26, 23, 18, 0.2);
}

.tabla-planes tr.tp-precio td {
  font-family: "Anton", "Arial Narrow", sans-serif;
  font-size: clamp(17px, 1.6vw, calc(23px * var(--esc)));
  letter-spacing: 0.01em;
  color: var(--rosa-tinta);
  font-variant-numeric: tabular-nums;
}

/* ── Las dos tallas de cada celda ──
   La misma frase escrita dos veces: entera y en corto. El navegador enseña
   una y esconde la otra con display:none, que además la saca del árbol de
   accesibilidad — quien usa lector de pantalla oye una sola, no las dos.
   Por defecto manda la larga; el bolsillo enciende la corta más abajo. */
.tp-corta {
  display: none;
}

/* Dentro de la ventana de ampliar SIEMPRE la larga, mida lo que mida la
   pantalla: para eso se amplía. */
.vt-cuerpo .tp-larga {
  display: inline;
}

.vt-cuerpo .tp-corta {
  display: none;
}

/* ── La tabla en el móvil: pista + ampliar ──
   La tabla es más ancha que la pantalla y se desliza, pero deslizarse no se
   anuncia solo: la pista lo dice y el botón la abre en su ventana
   (data-legal="v-tabla" — la abre la máquina de las legales). En escritorio
   este par no existe. */
.tp-movil {
  display: none;
}

/* Solo cuando la tabla no cabe: por debajo de 760 px la columna interior
   baja de los 680 px que mide la tabla y empieza a deslizar. Entre 760 y
   900 cabe entera, y decir «desliza» ahí era mentir. */
@media (max-width: 760px) {
  /* ── LA TABLA CABE ENTERA ──
     Antes medía 680px de mínimo y se arrastraba de lado: comparar tres
     planes empujando con el dedo no es comparar, es adivinar. Lo que
     sobraba no eran columnas, era LITERATURA: «Animaciones sencillas y una
     escena que se mueve con el scroll» ocupa cuatro veces lo que «Sencilla
     y una escena», y dice lo mismo cuando al lado están las otras dos. Con
     las celdas en corto la tabla mide lo que la pantalla, desaparece el
     arrastre y con él la columna fija, la pista y el recorte lateral. El
     texto completo sigue estando a un toque, en la ventana de ampliar. */
  .tp-corta {
    display: inline;
  }

  .tp-larga {
    display: none;
  }

  .tp-marco table,
  .tabla-planes table {
    min-width: 0;
    width: 100%;
    table-layout: fixed;
    font-size: 12px;
  }

  /* La columna de las preguntas se lleva el 37%: lo justo para que las tres
     respuestas queden iguales y ninguna baje de 60px. */
  .tabla-planes tbody th {
    width: 37%;
    padding: 10px 10px;
    font-size: 11.5px;
    line-height: 1.35;
  }

  .tabla-planes tbody td {
    padding: 10px 4px;
    line-height: 1.35;
  }

  .tabla-planes thead th,
  .tabla-planes thead td {
    padding: 14px 4px 10px;
  }

  .tabla-planes thead th {
    font-size: 13px;
  }

  .tabla-planes thead th span {
    font-size: 7.5px;
    letter-spacing: 0.1em;
  }

  .tabla-planes tr.tp-precio td {
    font-size: 15px;
  }

  /* el marco ya no desliza nada */
  .tp-marco {
    overflow-x: visible;
  }

  .tp-movil {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 14px;
    margin-top: 14px;
  }

  .tp-ampliar {
    flex: 0 0 auto;
    padding: 8px 18px;
    border: 1px solid rgba(150, 72, 90, 0.4);
    border-radius: 999px;
    background: none;
    font-family: "Oswald", sans-serif;
    font-size: 12px;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--rosa-tinta);
    cursor: pointer;
  }
}

/* La ventana de la tabla: hereda toda la máquina de .ventana-legal y solo
   cambia la talla — ancha hasta donde dé la pantalla, y el cuerpo desliza
   en horizontal por dentro (la hoja ya pone el scroll vertical). */
.ventana-tabla {
  width: min(calc(100vw - 16px), calc(960px * var(--esc)));
}

/* El filete y el aire bajo el título van en el MARCO, que es lo que está
   quieto: en la caja de dentro se iban hacia arriba con la tabla. */
.vt-marco {
  padding-top: clamp(14px, 1.6vw, 22px);
  border-top: 1px solid var(--linea);
}

/* (sin -webkit-overflow-scrolling: touch — la misma reliquia que dejaba las
   ventanas sin pintar en los iPhone con WebKit anterior; ver §ventanas) */
.vt-cuerpo {
  /* pisa el margin-top de .tabla-planes, que aquí no pinta nada */
  margin-top: 0;
}

.vt-cuerpo table {
  width: 100%;
  border-collapse: collapse;
  background: #ffffff;
  /* más grande que la de la página, que para eso se amplía */
  font-size: 14px;
  min-width: 760px;
}

/* ── La barra de deslizar de la ventana ──
   La del navegador no vale: en el iPhone solo asoma mientras el dedo se
   mueve, así que la ventana se abría sin ninguna señal de que aquello se
   arrastra y no se sabía por dónde ibas (Sara, 1 sep). Esta se ve siempre y
   es la misma pieza que la guía del raíl de cartas, para que las dos cosas
   que se deslizan a lo ancho se anuncien igual. El tramo lo mueve
   script.js; si la tabla cabe entera, la barra se esconde sola. */
.vt-guia {
  position: relative;
  width: min(240px, 60%);
  height: 5px;
  margin: 14px auto 0;
  border-radius: 999px;
  background: rgba(26, 23, 18, 0.11);
  overflow: hidden;
}

.vt-guia[hidden] {
  display: none;
}

/* sin transición, por lo mismo que la guía del raíl: el tramo va pegado al
   dedo y no persiguiéndolo */
.vt-guia span {
  position: absolute;
  inset-block: 0;
  left: 0;
  width: 34%;
  border-radius: inherit;
  background: var(--rosa-hondo);
}

/* La palomita, dibujada con dos bordes: un carácter ✓ cambia de forma en cada
   sistema y en algunos sale de otro color. */
.tp-si {
  display: inline-block;
  width: 13px;
  height: 7px;
  border-left: 1.5px solid var(--rosa-tinta);
  border-bottom: 1.5px solid var(--rosa-tinta);
  transform: rotate(-45deg) translate(1px, -2px);
}

.tp-no {
  display: inline-block;
  width: 13px;
  height: 1px;
  background: rgba(26, 23, 18, 0.22);
  vertical-align: middle;
}

/* Lo que solo se dice en voz alta: el lector de pantalla necesita oír «sí» o
   «no», y una palomita dibujada con bordes no la lee nadie. */
.solo-voz {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ── El herbario ──
   Mismos verdes, mismo rosa y mismo corazón dorado que la enredadera del
   margen. No son iconos: es la misma planta en cinco momentos, y las cinco
   comparten la línea del suelo a la misma altura. */

.marca-suelo {
  fill: none;
  stroke: var(--ink-crema);
  stroke-width: 1;
  stroke-linecap: round;
  opacity: 0.16;
}

/* El tallo quieto sí lleva degradado; el que se dibuja al crecer, NO.

   La diferencia es qué se repinta. Un degradado se resuelve una vez y ya
   está... mientras el trazo no cambie. La traza que crece cambia su
   `stroke-dashoffset` en cada uno de los sesenta fotogramas de la animación,
   y con un degradado encima hay que volver a resolver el degradado a lo largo
   del trazo sesenta veces. Con un color plano no hay nada que resolver.

   Se pierde poco: en un trazo de 1,6px de grosor el degradado casi no se ve.
   Donde sí se nota el volumen es en las hojas, los pétalos y la semilla, que
   están quietas y lo conservan. */
.marca-tallo {
  fill: none;
  stroke: url(#t-tallo);
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 1;
}

.marca-traza {
  fill: none;
  stroke: #6f8259;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0.85;
}

/* las raíces de Brote: dorado de tierra, no verde — bajo el suelo no hay
   clorofila. El mismo oro apagado del corazón de las flores. */
.marca-raiz {
  stroke: #c9a35c;
}

.marca-rama {
  stroke-width: 1.2;
  opacity: 0.7;
}

.marca-traza {
  stroke-width: 1.2;
  opacity: 0.62;
  /* Punta cuadrada, y no es estético: con punta REDONDA un trazo de longitud
     cero se pinta igual, como un punto. Los trazos que aún no han crecido
     están a longitud cero, y dejaban puntitos sueltos por toda la marca. */
  stroke-linecap: butt;
}

.marca-hoja {
  fill: url(#t-hoja);
  opacity: 0.92;
}

.marca-hoja-clara {
  fill: url(#t-hoja-clara);
  opacity: 0.88;
}

.marca-semilla {
  fill: url(#t-semilla);
  stroke: #6d5738;
  stroke-width: 0.5;
  opacity: 1;
}

.marca-petalo {
  fill: url(#t-petalo);
  stroke: rgba(255, 255, 255, 0.55);
  stroke-width: 0.4;
  opacity: 0.9;
}

.marca-centro {
  fill: url(#t-centro);
  stroke: #b98a4a;
  stroke-width: 0.35;
}

.marca-gota {
  fill: url(#t-gota);
  stroke: rgba(255, 255, 255, 0.5);
  stroke-width: 0.35;
  opacity: 1;
}

/* Sin JS no hay ventana que abrir, así que las ventanas se quedan puestas en
   la página una detrás de otra y las fichas dejan de invitar a pulsar. */
html:not(.js) .siembra {
  display: block;
}

html:not(.js) .brote + .brote {
  margin-top: 14px;
}

html:not(.js) .brote-elegido .brote-titulo {
  margin-block: 0;
}

html:not(.js) .brote-accion {
  display: none;
}

/* Sin JS las fichas van a todo lo ancho, y el 66% de mil píxeles es una planta
   de 700px. Aquí se queda del tamaño de una viñeta. */
html:not(.js) .brote-lienzo {
  left: auto;
  width: clamp(140px, 18vw, 210px);
  top: auto;
  bottom: 0;
  height: 100%;
}

html:not(.js) .brote-btn {
  min-height: 0;
  padding-top: clamp(22px, 2.3vw, 32px);
  padding-right: clamp(160px, 20vw, 240px);
}

html:not(.js) .brote-sello {
  position: static;
  display: inline-block;
  margin-bottom: 12px;
}

/* Un <dialog> sin el atributo `open` lo esconde el navegador. Aquí se le
   devuelve al flujo de la página: es la única manera de que el detalle de los
   cinco planes siga estando escrito. */
html:not(.js) .ventana {
  display: block;
  position: static;
  /* las ventanas van fuera del .contenedor, así que sin esto se irían de
     borde a borde de la pantalla */
  width: 100%;
  max-width: var(--ancho);
  max-height: none;
  margin: clamp(18px, 2vw, 28px) auto 0;
  padding-inline: clamp(22px, 5vw, 44px);
}

html:not(.js) .ventana-hoja {
  max-height: none;
  display: block;
}

/* la ventana de la tabla la rellena script.js: sin JS es una caja vacía */
html:not(.js) #v-tabla {
  display: none;
}

html:not(.js) .ventana-cerrar {
  display: none;
}

/* ══════════════════ 7 · FAQ ══════════════════ */

.faq {
  margin-top: clamp(40px, 4vw, 62px);
}

/* ══════════════════ 7c · Las manos ══════════════════ */

/* El puente entre las dudas y el formulario. El vídeo VIAJA con la página
   —nada de plano fijo: se probó pegado (sticky) dos pantallas y paraba el
   scroll en seco, como un peaje— y la flor se abre mientras la banda cruza
   la pantalla: quien la mueve fotograma a fotograma es script.js §6c.

   Los márgenes negativos se comen parte del aire de las secciones de al
   lado: el vídeo ya trae su propio respiro dentro (el fondo blanco sobre
   la copa y bajo las manos) y sumarle el paso normal de sección lo dejaba
   flotando en un descampado. */
.claro .s-manos {
  position: relative;
  padding-block: 0;
  margin-top: calc(var(--paso-y) * -0.5);
}

/* A sangre, de borde a borde: los brazos del vídeo entran por los dos
   cantos de la pantalla, que es todo el chiste del encuadre.

   El fondo del archivo viene igualado a la crema en el encode (receta en
   CONTENIDO.md §9b), pero eso NO basta solo: los colores CSS y los de
   vídeo viajan por tuberías de color distintas y en según qué pantalla no
   aterrizan exactamente iguales — en un monitor se veía perfecto y en otro
   salía una raya horizontal donde empezaba el vídeo. La máscara remata el
   problema por construcción: los cantos de arriba y abajo se funden en
   32px de degradado, así que aunque los dos colores difieran un pelo, no
   existe ninguna LÍNEA recta donde el ojo pueda compararlos. Una
   transición gradual de 2 puntos de color es invisible; un canto recto con
   esos mismos 2 puntos, no. */
.manos-video {
  display: block;
  width: 100%;
  height: auto;
  /* La banda es 2,28:1. A todo lo ancho de un móvil de 390 px eso son 170
     px de alto: la flor abriéndose cabía en una uña. Aquí se le da su
     proporción natural y más abajo, en pantallas estrechas, se recorta
     por los lados (object-fit) para que crezca: las manos entran por los
     cantos igual, solo que se ve menos brazo y más flor. */
  aspect-ratio: 1764 / 774;
  object-fit: cover;
  /* en un monitor 21:9 la banda a todo lo ancho era más alta que la
     pantalla y la flor nunca se veía entera: tope de alto, y cover recorta
     crema por arriba y por abajo */
  max-height: calc(var(--vh-fijo) * 0.88);
  -webkit-mask-image: linear-gradient(
    180deg,
    transparent 0,
    #000 32px,
    #000 calc(100% - 32px),
    transparent 100%
  );
  mask-image: linear-gradient(
    180deg,
    transparent 0,
    #000 32px,
    #000 calc(100% - 32px),
    transparent 100%
  );
}

/* ══════════════════ 8 · Contacto ══════════════════ */

/* Sin caja. Fue un bloque oscuro flotando sobre la crema, con su vídeo de
   pétalos dentro; ahora el formulario vive directamente sobre la página.
   El peso visual del cierre lo pone la sección de las manos de arriba —
   una caja oscura después de eso era contar dos finales.

   Menos aire por arriba del que da --paso-y: el titular tiene que leerse
   como la continuación de la flor, no como otra parada.

   El padding lateral es el del .contenedor, puesto aquí a mano: el cuerpo
   del contacto no va dentro de un .contenedor (le basta su max-width de
   760px), pero sin sangrado propio el formulario tocaba los dos cantos de
   la pantalla en el móvil. */
.claro .s-contacto {
  position: relative;
  padding-top: clamp(30px, 3vw, 52px);
  padding-inline: clamp(22px, 5vw, 44px);
  /* menos que el --paso-y general: entre el Enviar y el pie había casi
     media pantalla de nada */
  padding-bottom: clamp(44px, 4.5vw, 72px);
}

.contacto-cuerpo {
  position: relative;
  z-index: 1;
  max-width: calc(760px * var(--esc));
  margin-inline: auto;
  text-align: center;
}

.s-contacto .cejilla {
  justify-content: center;
}

.s-contacto .cejilla::before {
  content: "";
  width: clamp(28px, 4vw, 62px);
  height: 1px;
  background: currentColor;
  opacity: 0.4;
}

.accent-rosa {
  font-style: italic;
  color: var(--rosa-hondo);
}

.s-contacto .entradilla {
  margin-inline: auto;
}

/* Sin caja alrededor: los campos flotan sobre la crema, como siempre. Lo
   que los viste es su propio color — rosa empolvado en vez de blanco, el
   tono de la franja del vivero llevado a relleno. Se probó meter el
   formulario en una hoja de papel blanco y se descartó: otra caja más. */
.formulario {
  margin-top: clamp(40px, 4.5vw, 62px);
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 18px;
  text-align: left;
}

.campo-ancho {
  grid-column: 1 / -1;
}

/* Los campos, en claro: papel blanco sobre la crema, como las fichas de
   precios — es la misma familia de objeto. Antes eran cristal oscuro porque
   la sección era de noche. */
.campo span {
  display: block;
  font-family: "Oswald", sans-serif;
  font-weight: 400;
  font-size: calc(11.5px * var(--esc));
  letter-spacing: 0.18em;
  text-transform: uppercase;
  /* negros: son el nombre de cada campo, no una nota al pie */
  color: var(--ink-crema);
  margin-bottom: 10px;
}

.campo input,
.campo textarea {
  width: 100%;
  font-family: inherit;
  /* 16 px es el mínimo en todas las pantallas: por debajo, iOS hace zoom
     al entrar en el campo y descoloca la página */
  font-size: calc(16px * var(--esc));
  color: var(--ink-crema);
  /* blancos con el borde rosa de la casa, bien presente: el campo se ve
     como un objeto propio sin necesidad de relleno */
  background: #ffffff;
  border: 1.5px solid rgba(194, 104, 122, 0.5);
  border-radius: 12px;
  padding: 15px 18px;
  resize: vertical;
  transition: border-color 0.3s ease, box-shadow 0.3s ease;
}

.campo input::placeholder,
.campo textarea::placeholder {
  color: rgba(26, 23, 18, 0.32);
}

.campo input:focus,
.campo textarea:focus {
  outline: none;
  border-color: var(--rosa-hondo);
  box-shadow: 0 0 0 3px rgba(194, 104, 122, 0.14);
}

.campo input:user-invalid,
.campo textarea:user-invalid {
  border-color: rgba(178, 70, 70, 0.55);
}

.formulario-pie {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 18px 28px;
  margin-top: 8px;
}

.form-nota {
  font-size: calc(14px * var(--esc));
  color: var(--ink-crema-3);
}

.form-nota a,
.pie-mail a {
  color: var(--rosa-tinta);
  text-decoration: none;
  /* el subrayado germina desde la izquierda en vez de aparecer de golpe */
  background: linear-gradient(currentColor, currentColor) 0 100% / 0 1px
    no-repeat;
  padding-bottom: 2px;
  transition: background-size 0.45s cubic-bezier(0.22, 1, 0.36, 1);
}

@media (hover: hover) {
  .form-nota a:hover,
  .pie-mail a:hover {
    background-size: 100% 1px;
  }
}

.form-aviso {
  grid-column: 1 / -1;
  font-size: 14px;
  line-height: 1.6;
  color: var(--rosa-tinta);
  min-height: 1.2em;
}

/* Cuando el envío ha fallado de verdad. Más oscuro, no rojo de alarma: el
   mensaje ya dice qué hacer y no hace falta asustar a nadie. */
.form-aviso-mal {
  color: #8a2f3f;
  font-weight: 500;
}

/* La trampa para robots: una casilla que una persona no ve nunca, así que si
   llega marcada es que la ha rellenado una máquina y Web3Forms lo descarta.

   Va con `display: none`, que es lo que recomienda el propio servicio. Se
   probó a sacarla de la pantalla con `left: -9999px` —que en teoría engaña a
   más robots— y salía en la auditoría como una diana táctil de 1px y como un
   elemento fuera de sitio: ensuciaba la medición de todo lo demás a cambio de
   nada. */
.trampa-bot {
  display: none;
}

/* El botón, mientras el mensaje va de camino. */
.formulario button[type="submit"]:disabled {
  opacity: 0.62;
  cursor: progress;
}

/* El Enviar, con la tinta del dorso de las cartas: el degradado rosa pálido
   de la zona oscura se quedaba lavado sobre la crema. */
.s-contacto .btn-solido {
  background: var(--rosa-tinta);
  color: #fff5f6;
}

/* ENVIAR NO LLEVA LA CORTINILLA DE LOS DEMÁS BOTONES.

   El resto de botones se rellenan con una capa que sube desde abajo, y ahí
   funciona porque el color que entra contrasta con el de partida: se lee como
   que el botón se llena. Aquí no: vino oscuro sobre vino, dos tonos casi
   iguales, así que lo único que se veía era la RAYA del borde de la capa
   cruzando el botón de abajo arriba. Una persiana, no una floración.

   Se queda el mismo color, pero entrando por fundido: el botón se oscurece
   entero a la vez, sin costura. Y el brillo de al lado le da el relieve que
   antes ponía la raya. */
.s-contacto .btn-solido::before {
  background: #7d3a4a;
  transform: none;
  opacity: 0;
  transition: opacity 0.38s ease;
}

@media (hover: hover) {
  .s-contacto .btn-solido:hover::before {
    transform: none;
    opacity: 1;
  }
}

.s-contacto .btn-solido {
  transition: color 0.35s ease, transform 0.35s ease, box-shadow 0.38s ease;
}

@media (hover: hover) {
  .s-contacto .btn-solido:hover {
    box-shadow: 0 10px 26px -12px rgba(125, 58, 74, 0.55);
  }
}

/* ══════════════════ EL TELÓN ══════════════════

   Lo último de la web no es una sección más: es una cortina que se levanta.

   El pie está CLAVADO al fondo de la ventana desde el primer píxel de la
   página, quieto, esperando. Encima pasa la web entera —.page—, que es opaca
   y lo tapa. Cuando el scroll llega al final, la web se sigue yendo hacia
   arriba y va destapando el pie que ya estaba puesto. No se mueve el pie: se
   retira el telón. Por eso el pie no arrastra ni un fotograma de scroll.

   Las tres piezas, y ninguna sobra:

   1. El hueco. Se le añade al <body> un colchón por abajo exactamente igual
      de alto que el pie (--alto-pie, lo mide script.js §12d). Sin ese hueco no
      hay recorrido que dé para destapar nada: la página terminaría justo
      donde termina el telón.

   2. El orden de capas. .page pasa a ser su propio plano (z-index: 1) y el
      pie se queda en el 0, debajo. Sin esto el pie —que en el HTML va
      DESPUÉS— se pintaría por encima de la página entera.

   3. Las esquinas. Las dos de abajo de la zona clara van redondeadas: es lo
      que convierte «una sección que se acaba» en «una hoja que se levanta».
      Van en .claro y no en .page porque el fondo crema lo pinta .claro, y
      un redondeo solo recorta el fondo del elemento que lo lleva.

   Se apaga solo cuando el pie no cabe entero en la ventana (móviles bajos):
   sin la clase, todo vuelve al flujo normal y el pie va detrás de la página
   de toda la vida. Lo decide script.js §12d. */

html.con-telon body {
  padding-bottom: var(--alto-pie, 0px);
}

html.con-telon .page {
  z-index: 1;
  /* Y opaca. El pie está puesto desde el primer píxel de la página, así que
     si la envoltura no pinta fondo propio se le ve DEBAJO del hero: medido,
     el pie asomaba entero por el manifiesto porque ahí el negro lo ponía el
     lienzo del navegador, que va por detrás de todo lo colocado. Con el
     fondo aquí, la página tapa lo que tiene que tapar. (Comprobado que no
     esconde nada: los elementos que van en capa -1 cuelgan de las secciones,
     no de esta caja — dos capturas de la página entera, con fondo y sin él,
     salen idénticas salvo un nivel de redondeo.) */
  background: var(--bg);
  /* y el mismo redondeo que la zona clara: si la envoltura se quedara
     cuadrada, sus esquinas rellenarían de negro justo la muesca que acaba
     de abrir la curva. */
  border-bottom-left-radius: var(--radio-telon);
  border-bottom-right-radius: var(--radio-telon);
}

html.con-telon .claro {
  border-bottom-left-radius: var(--radio-telon);
  border-bottom-right-radius: var(--radio-telon);
  /* La hoja tiene que separarse del fondo o el redondeo no se lee: una
     sombra larga y suave por debajo, y un filo claro de un píxel en el canto
     para que la curva tenga borde propio. */
  box-shadow: 0 40px 60px -20px rgba(0, 0, 0, 0.75),
    0 2px 0 rgba(255, 255, 255, 0.06);
}

html.con-telon .pie {
  position: fixed;
  inset: auto 0 0;
  z-index: 0;
  margin-top: 0;
}

/* ══════════════════ Pie ══════════════════ */

/* Un pequeño jardín rosa para despedir: la flor de la marca plantada en el
   centro, el nombre debajo, el lema, el correo y los caminos legales. Todo
   centrado — aquí ya no se decide nada.

   El rosa es una banda que cruza de borde a borde, hermana de la franja del
   vivero pero un punto más presente, y se funde por arriba: la página no
   TERMINA en el pie, se va posando en él. */
.pie {
  position: relative;
  margin-top: clamp(24px, 3vw, 48px);
  /* A SANGRE: de borde a borde y hasta abajo, sin caja flotando — un
     cierre, no una tarjeta. Se probó como recuadro redondeado y parecía
     un elemento más en vez del final de la página. */
  /* sin relleno lateral propio: el canalón lo pone su .contenedor, el
     mismo de todas las secciones, así la columna del pie cae EXACTAMENTE
     sobre la de la página (con dos canalones sumados quedaba un 9-17% más
     estrecha y desplazada entre 900 y 1300) */
  padding: clamp(44px, 4.6vw, 72px) 0 clamp(26px, 2.6vw, 40px);
  background: #0a0908;
  color: var(--ink);
}

/* La entrada al jardín: raya — flor — raya. Es el umbral que le faltaba al
   fundido para tener un punto de contraste con la sección de arriba sin
   cortarla: la línea marca dónde empieza el pie, y el degradado sigue
   haciendo su fundido por detrás. */
.pie-adorno {
  position: relative;
  display: flex;
  align-items: center;
  gap: 20px;
  margin-bottom: clamp(30px, 3.4vw, 50px);
}

.pie-adorno::before,
.pie-adorno::after {
  content: "";
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.22));
}

.pie-adorno::after {
  background: linear-gradient(270deg, transparent, rgba(255, 255, 255, 0.22));
}

.pie-adorno svg {
  width: 21px;
  height: 21px;
  flex: 0 0 auto;
}

.pa-petalo {
  fill: var(--pink);
  opacity: 0.9;
}

.pa-centro {
  fill: #f2c98a;
}

/* ── EL PIE ES DE NOCHE ──
   La página abre en negro (el hero) y cierra en negro: un bloque oscuro
   con las esquinas redondeadas flotando sobre la crema — el círculo se
   cierra. Sobre ese fondo el logotipo blanco con la & rosa tiene la
   presencia que sobre el rosa lavado nunca tuvo. Se probaron tres fondos
   claros (banda tenue, degradado con cuerpo, columnas) y todos morían
   pálidos: el pie necesitaba CONTRASTE, no más rosa.

   Dos plantas: arriba la marca EN GRANDE a la izquierda con las secciones
   enfrente; abajo la barra de servicio — © a la izquierda, legal a la
   derecha. */
.pie-arriba {
  position: relative;
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: clamp(32px, 5vw, 90px);
}

/* El mismo logotipo que la cabecera, en GRANDE y en blanco sobre la noche:
   la firma de la página entera. La & en el rosa pálido, como arriba. */
.pie-marca {
  font-family: "Playfair Display", "Libre Baskerville", Georgia, serif;
  font-weight: 500;
  font-size: clamp(30px, 3.2vw, calc(48px * var(--esc)));
  letter-spacing: 0.01em;
  line-height: 1.1;
  color: var(--ink);
}

.pie-marca .amp {
  color: var(--pink);
}

.pie-lema {
  margin-top: 12px;
  font-family: "Libre Baskerville", Georgia, serif;
  font-style: italic;
  font-size: calc(15px * var(--esc));
  color: rgba(255, 255, 255, 0.6);
}

.pie-mail {
  margin-top: clamp(18px, 2vw, 28px);
}

.pie-mail a {
  color: var(--pink);
  font-size: calc(15px * var(--esc));
}

/* las secciones, en columna alineada a la derecha, con el subrayado que
   germina de la casa */
.pie-secciones {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 12px;
  padding-top: 6px;
}

.pie-secciones a {
  font-size: calc(14.5px * var(--esc));
  color: rgba(255, 255, 255, 0.66);
  text-decoration: none;
  background: linear-gradient(var(--pink), var(--pink)) 100% 100% / 0 1px
    no-repeat;
  padding-bottom: 2px;
  transition: color 0.3s ease,
    background-size 0.45s cubic-bezier(0.22, 1, 0.36, 1);
}

@media (hover: hover) {
  .pie-secciones a:hover {
    color: var(--ink);
    background-size: 100% 1px;
  }
}

/* la barra de servicio: copy a la izquierda, legal a la derecha */
.pie-abajo {
  position: relative;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 18px 32px;
  flex-wrap: wrap;
  margin-top: clamp(38px, 4.4vw, 64px);
  padding-top: clamp(16px, 1.8vw, 24px);
  border-top: 1px solid rgba(255, 255, 255, 0.1);
}

.pie-copy {
  font-size: calc(12px * var(--esc));
  color: rgba(255, 255, 255, 0.4);
}

.pie-legal {
  display: flex;
  flex-wrap: wrap;
  gap: 22px;
}

/* Son <button> y no <a>: abren una ventana, no llevan a otra página. Hay que
   desvestirlos, porque un botón trae de fábrica su propio tipo, su fondo y su
   borde y ninguno de los tres se hereda. Vestidos igual que los enlaces de
   la columna de al lado: son la misma familia de camino. */
.pie-legal button {
  padding: 0;
  border: 0;
  background: none;
  font-family: inherit;
  font-size: calc(12.5px * var(--esc));
  /* blanco velado: el pie es de noche — con la tinta de la zona clara
     desaparecían sobre el negro */
  color: rgba(255, 255, 255, 0.52);
  cursor: pointer;
  transition: color 0.3s ease;
}

@media (hover: hover) {
  .pie-legal button:hover {
    color: var(--ink);
  }
}

.pie-legal button:focus-visible {
  outline: 2px solid var(--rosa-tinta);
  outline-offset: 4px;
  border-radius: 3px;
}

/* ══════════════════════════════════════════════════════════════════
   Aparición por scroll

   Todo cuelga de la clase .js, que pone el <head> antes de pintar nada. Si
   GSAP no carga, script.js la quita y la página se ve entera y estática: nunca
   en blanco. El escalonado ya no se hace con transition-delay encadenados —
   lo lleva el stagger de GSAP, que además lo calcula sobre la línea de tiempo
   real del grupo.
   ══════════════════════════════════════════════════════════════════ */

.js [data-revelar] {
  opacity: 0;
}

.js [data-revelar].visto {
  opacity: 1;
}

/* ---------- Titulares partidos en palabras ----------
   La caja recorta; el span de dentro es el que se mueve. El padding negativo
   compensa el recorte de tildes y colas de 'j'. */

.pal {
  display: inline-block;
  overflow: hidden;
  vertical-align: top;
  padding: 0.12em 0.02em 0.18em;
  margin: -0.12em -0.02em -0.18em;
}

.pal > span {
  display: inline-block;
  will-change: transform;
}

/* Los titulares no se esconden con opacity: sus palabras ya nacen fuera de la
   máscara, y bajar además la opacidad del bloque hace que el efecto se lea
   como un fundido en vez de como algo que sube. */
.js .titular[data-revelar],
.js .hero-title {
  opacity: 1;
}

/* ---------- El titular del hero, partido ----------
   El titular se pinta con un degradado recortado a la forma de la letra
   (background-clip: text). Ese recorte lo hace el elemento que TIENE el
   degradado sobre el texto de sus descendientes... salvo que un descendiente
   lleve un transform: entonces se pinta aparte y el degradado no le llega.
   Al partir el titular en palabras, la que se mueve es justo ese descendiente,
   y el resultado era un titular invisible sobre fondo negro.

   La solución es bajar el degradado hasta la palabra que se mueve.

   OJO CON LA CAJA, que aquí ya se perdió media palabra una vez: .accent es un
   elemento EN LÍNEA y su fondo se pinta sobre el área de contenido de la
   fuente (ascendente + descendente = 1.5071em en Anton). Pero .pal > span es
   inline-block, y ahí el fondo se pinta sobre la caja de borde, que mide
   exactamente el interlineado: 1.05em. Las medidas afinadas de .accent NO
   valen aquí — con ellas la banda empezaba 32px por debajo del alto de la
   letra y el cuarto de arriba de «FLORECER» salía transparente.

   Así que aquí no se usa banda: el degradado cubre la caja entera y las
   paradas van en % de esa caja. Dentro de 1.05em los glifos de Anton ocupan
   del 7.67% al 91.01% (medido con TextMetrics), y sobre ese tramo se reparten
   los colores. Los extremos se dejan planos: si alguna vez cambia el
   interlineado, lo peor que puede pasar es que la letra salga de un color
   liso — nunca invisible. */
.js .hero-title .pal > span {
  background-image: linear-gradient(
    180deg,
    #ffffff 0%,
    #ffffff 51%,
    #f0ebe8 91.01%,
    #f0ebe8 100%
  );
  background-size: auto;
  background-position: 0 0;
  background-repeat: repeat;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}

.js .hero-title .accent .pal > span {
  /* mismos colores que .accent, con las paradas remapeadas al tramo de glifo:
     0→7.67, 30→32.67, 62→59.34, 86→79.34, 100→91.01 */
  background-image: linear-gradient(
    180deg,
    #fff2f3 0%,
    #fff2f3 7.67%,
    #fadade 32.67%,
    #f4c3ca 59.34%,
    #eda9b4 79.34%,
    #e2919f 91.01%,
    #e2919f 100%
  );
  background-size: auto;
  background-position: 0 0;
  background-repeat: repeat;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}

/* ---------- Las letras de «FLORECER» ----------
   script.js §5 parte la palabra del acento en letras para que FLOREZCA: cada
   letra crece desde su base al cargar. Y aquí LA MISMA TRAMPA de arriba, un
   escalón más abajo: las letras llevan transform, así que el degradado del
   padre no las alcanza — cada letra carga con su propio degradado, calcado
   al del padre. Como todas comparten la misma caja de línea (1.05em), las
   paradas en % caen igual en todas y la palabra se ve de una pieza. */
.js .hero-title .accent .letra {
  display: inline-block;
  background-image: linear-gradient(
    180deg,
    #fff2f3 0%,
    #fff2f3 7.67%,
    #fadade 32.67%,
    #f4c3ca 59.34%,
    #eda9b4 79.34%,
    #e2919f 91.01%,
    #e2919f 100%
  );
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}

/* ---------- El fantasma de la F ----------
   EL QUE DELEGA, NO PINTA. Es la otra mitad —la que faltaba— de la regla de
   arriba: si un antepasado le pasa el degradado a su descendiente porque el
   descendiente lleva transform, el antepasado tiene que DEJAR de pintarlo.

   Qué pasaba si no. `background-clip: text` recorta el degradado a la forma
   de las letras que hay dentro. Cuando las letras llevan transform se pintan
   en su propia capa, así que al envoltorio no le queda ni un glifo al que
   recortarse — y en Chromium (Brave, Chrome, Edge) el recorte vacío no pinta
   nada: pinta el degradado ENTERO, sin recortar. Un rectángulo rosa macizo de
   70×140 px justo encima de la F. Con la F clara por delante, la palabra se
   leía «BLORECER». Solo mientras dura la animación de entrada: al terminar,
   el clearProps quita los transforms, el recorte vuelve a encontrar sus
   glifos y el titular se arregla solo. De ahí que se viera «al recargar».

   Medido en Brave, recargando y fotografiando la carga entera: lo dispara
   CUALQUIER cosa que mande la letra a su propia capa —un transform 2D, uno
   3D, `will-change`—, no la animación concreta. Y el rectángulo no cambia de
   tamaño aunque las letras encojan, que fue la pista de que no lo pintaba
   ninguna letra. Firefox y WebKit no lo hacen; a las palabras del titular
   (HAZ / TU / NEGOCIO) tampoco les pasa: se comprobó y la diferencia entre
   pintar el degradado del h1 y no pintarlo es de CERO píxeles.

   El data-letras lo pone script.js §5 al partir la palabra: así esta regla
   solo entra cuando las letras existen de verdad. Sin JS o sin GSAP no se
   parte nada, el envoltorio sigue pintando y el titular sale igual. */
.js .hero-title[data-letras] .accent .pal > span {
  background-image: none;
}

/* ---------- El velo de los saltos ----------
   Los enlaces de la cabecera saltan en seco: quien elige «Precios» quiere
   estar en Precios, no ver desfilar media web. Pero un corte seco se lee como
   un fallo, así que el salto va tapado — entra el negro, se salta, se va el
   negro. Lo pinta y lo apaga script.js §0.

   Por encima de la píldora (40) y por debajo de las ventanas legales, que van
   en la capa superior del navegador por ser <dialog> abiertos con showModal.
   No captura clics NUNCA: el guardián de §0 ya impide encadenar saltos. */
.velo-salto {
  position: fixed;
  inset: 0;
  z-index: 60;
  background: #0b0908;
  opacity: 0;
  pointer-events: none;
}

/* ---------- Píldora flotante ----------
   Aparece al pasar el hero: a partir de ahí el botón de contactar de la
   cabecera ya está fuera de pantalla y quedan 10.000px de página por delante. */

.pildora {
  position: fixed;
  /* env(): en un iPhone con barra de inicio, la píldora no se monta sobre
     ella (hace falta viewport-fit=cover en el <meta viewport>) */
  right: calc(clamp(16px, 2.4vw, 34px) + env(safe-area-inset-right, 0px));
  bottom: calc(clamp(16px, 2.4vw, 34px) + env(safe-area-inset-bottom, 0px));
  z-index: 40;

  font-family: "Oswald", sans-serif;
  font-weight: 400;
  font-size: calc(14px * var(--esc));
  text-transform: uppercase;
  letter-spacing: 0.11em;
  color: #fff;
  text-decoration: none;

  padding: calc(15px * var(--esc)) calc(30px * var(--esc));
  border-radius: 999px;
  background: var(--rosa-tinta);
  border: 1px solid rgba(255, 255, 255, 0.24);
  box-shadow: 0 18px 40px -16px rgba(96, 42, 55, 0.6);

  opacity: 0;
  transform: translateY(24px) scale(0.92);
  pointer-events: none;
  /* visibility, además de opacity: un enlace solo transparente sigue
     entrando en el orden del tabulador, y quien navega con teclado se
     encontraba un foco invisible entre el pie y el formulario. El retraso
     de 0.45s deja terminar el fundido antes de esconderla del todo. */
  visibility: hidden;
  transition: opacity 0.45s ease, transform 0.45s cubic-bezier(0.34, 1.4, 0.64, 1),
    background 0.25s ease, visibility 0s linear 0.45s;
}

.pildora.pildora-visible {
  opacity: 1;
  transform: none;
  pointer-events: auto;
  visibility: visible;
  /* al aparecer, sin retraso: visible desde el primer fotograma del fundido */
  transition-delay: 0s;
}

/* Mientras las preguntas cruzan la esquina del globo, el globo se aparta
   (script.js §10, solo en pantalla estrecha): su rincón es el mismo donde
   viven las cruces de la FAQ y les robaba el toque. Antes se corrían las
   cruces 62px hacia dentro y quedaban flotando a mitad de fila — lo que se
   veía «mal» en el móvil (foto de Sara, 1 sep). Va DESPUÉS de
   .pildora-visible para ganarle: mismas dos clases, el orden decide. */
.pildora.pildora-aparta {
  opacity: 0;
  transform: translateY(24px) scale(0.92);
  pointer-events: none;
  visibility: hidden;
  transition: opacity 0.45s ease, transform 0.45s cubic-bezier(0.34, 1.4, 0.64, 1),
    background 0.25s ease, visibility 0s linear 0.45s;
}

@media (hover: hover) {
  .pildora:hover {
    background: var(--rosa-hondo);
  }
}

/* El globo solo existe en pantallas pequeñas; en grande manda el texto. */
.pildora-globo {
  display: none;
  width: 26px;
  height: 26px;
  color: #fff;
}

/* En móviles y tablets la píldora con palabra ocupaba demasiado (petición
   de Sara, 31 ago): se vuelve un botón redondo con un globo de conversación
   minimalista. Mismo sitio, mismo color, mismo destino (#contacto). */
@media (max-width: 900px) {
  .pildora {
    width: 56px;
    height: 56px;
    padding: 0;
    display: grid;
    place-items: center;
  }

  .pildora-texto {
    display: none;
  }

  .pildora-globo {
    display: block;
  }

}

/* Con un menú abierto la píldora se aparta: en un móvil apaisado el panel
   llega hasta abajo y la píldora (más alta en el apilado) se le montaba
   encima, con su «Contactar» y este «Hablamos» a dos dedos. */
/* La clase la pone script.js; el `:has()` se queda de acompañante para los
   raros casos sin JavaScript. Con `:has()` a secas, los iPhone anteriores a
   2022 tiraban la regla entera y el globo se quedaba encima del menú. */
body.con-menu .pildora,
body:has(.header.menu-abierto) .pildora {
  opacity: 0;
  pointer-events: none;
}

/* ══════════════════════════════════════════════════════════════════
   Movimiento reducido
   Si el sistema lo pide, la web se queda quieta y perfectamente
   legible: nada depende de una animación para poder leerse.
   ══════════════════════════════════════════════════════════════════ */

@media (prefers-reduced-motion: reduce) {
  .js [data-revelar],
  .js [data-revelar].visto,
  .js .manifiesto .ln > span,
  .js .pal > span,
  .tallo .adorno {
    opacity: 1 !important;
    transform: none !important;
    transition: none;
  }

  /* Las preguntas se habían quedado fuera: la respuesta seguía entrando
     deslizándose y la crucecita seguía girando media vuelta. Quien pide que
     nada se mueva también abre preguntas. */
  .faq details[open] .faq-cuerpo {
    animation: none;
  }

  .faq summary::after {
    transition: none;
  }

  /* La enredadera sale entera y quieta: sigue decorando, ya no se mueve.
     script.js tampoco arranca Lenis ni los tweens cuando esto está activo. */
  .tallo-linea,
  .tallo-sombra {
    stroke-dasharray: none !important;
    stroke-dashoffset: 0 !important;
  }

  /* y la cortina del tronco, abierta: sin tween nadie escribe --barrido y
     la rama se quedaba desnuda para siempre en móvil y tablet */
  .reveal-layer {
    --barrido: 135%;
  }

  .pildora {
    transition: none;
  }

  .btn::before,
  .sintomas li,
  .sintomas li::before,
  .brote-btn,
  .brote-btn::before,
  .brote-lienzo,
  .brote-marca,
  .bl-foto,
  .bl-video,
  .brote-nombre,
  .brote-raya,
  .brote-raya::after,
  .brote-frase,
  .brote-accion,
  .brote-carta,
  .brote-solapa,
  .brote::before,
  .ventana-cerrar,
  .dorso-cta {
    transition: none;
  }

  /* Sin transición, los planos que se levantan darían un salto seco de tamaño
     al entrar y salir el ratón. Aquí la ficha se queda plana: el hover cambia
     el borde y la sombra, y nada más. script.js tampoco inclina ni reproduce
     el vídeo cuando esto está activo. */
  @media (hover: hover) {
    .brote-btn:hover .brote-lienzo,
    .brote-btn:hover .brote-marca,
    .brote-btn:hover .bl-foto,
    .brote-btn:hover .brote-nombre,
    .brote-btn:hover .brote-raya,
    .brote-btn:hover .brote-frase,
    .brote-btn:hover .brote-accion {
      transform: none;
    }
  }

  @media (hover: hover) {
    .brote-btn:hover::before {
      opacity: 0;
    }
  }

  /* La ventana aparece puesta: sin velo que se funde ni hoja que sube. */
  .ventana[open]::backdrop,
  .ventana.cerrando::backdrop {
    animation: none;
    opacity: 1;
  }

  /* El plano de la savia no se pinta: script.js le pone .savia-simple y la
     sección se lee como una lista. Esto es solo el cinturón por si el JS no
     llegara a correr. */
  .js .savia-bloque,
  .js .savia-paso {
    opacity: 1 !important;
    transform: none !important;
  }

  .js .savia-pista {
    display: none;
  }
}

/* ══════════════════════════════════════════════════════════════════
   Adaptación a pantallas pequeñas
   ══════════════════════════════════════════════════════════════════ */

@media (max-width: 980px) {
  .sintomas li {
    grid-template-columns: 1fr;
    gap: 8px;
  }
}

@media (max-width: 900px) {
  /* La cabecera de móvil: logo a la izquierda, hamburguesa a la derecha, y
     el nav plegado en un panel que cae de debajo. El botón de contactar de
     escritorio se esconde — dentro del panel hay un Contactar propio. */
  .header {
    grid-template-columns: 1fr auto;
    padding: 16px clamp(14px, 4vw, 24px);
  }

  /* el shorthand de arriba pisaba el padding-top con zona segura del clon */
  .header-flotante {
    padding-top: calc(16px + env(safe-area-inset-top, 0px));
  }

  .logo {
    font-size: 19px;
  }

  .btn-contactar {
    display: none;
  }

  .menu-btn {
    display: flex;
  }

  /* La cabecera clonada, opaca y sin cristal en el móvil: el desenfoque de
     fondo se rehace en CADA fotograma, y esta cabecera aparece justo
     cuando se sube con el dedo — el momento de más trabajo del teléfono.
     Con el fondo ya casi opaco no se distinguía, y sin él la cabecera
     entra fina. (Lo mismo que se hizo con el panel del menú.) */
  .header-flotante {
    background: rgb(10, 9, 8);
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }

  /* El panel. Cerrado no existe para el ratón ni para el lector de
     tabulaciones (visibility se encarga); abierto cae con un deslizamiento
     corto. Fondo casi negro con desenfoque: se lee sobre lo que sea. */
  .nav {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    /* sin esto, el justify-self: center de la rejilla lo encoge a su
       contenido y el panel salía como una columna suelta en el aire */
    width: 100%;
    z-index: 5;
    flex-direction: column;
    /* stretch: cada enlace ocupa la fila ENTERA y se pulsa en cualquier
       punto de ella; centrados, «Dudas» era una diana de 45 px de ancho */
    align-items: stretch;
    gap: 4px;
    padding: 18px clamp(14px, 4vw, 24px) 26px;
    /* Opaco del todo y SIN desenfoque de cristal: con el fondo al 96% el
       blur no se veía, pero re-desenfoca cada fotograma del despliegue y
       en los iPhone viejos el panel abría a tirones (aviso de Sara,
       1 sep). Un panel opaco se compone en la GPU y va fino en todo. */
    background: rgb(10, 9, 8);
    border-bottom: 1px solid rgba(255, 255, 255, 0.09);
    /* En un móvil apaisado (844×390) el panel medía 367 px bajo una
       cabecera de 74: se salía por abajo y «Contactar» no se alcanzaba.
       Tope = pantalla menos la cabecera (el 100% es la altura del header,
       que es su bloque contenedor), y lo que no quepa se desliza dentro. */
    max-height: calc(100vh - 100%);
    max-height: calc(100dvh - 100%);
    overflow-y: auto;
    overscroll-behavior: contain;

    /* ── SE DESCUELGA COMO UNA PERSIANA, NO SE FUNDE ──
       Antes entraba y salía con opacidad, y durante ese tercio de segundo
       se veían A LA VEZ los enlaces del menú y la página de debajo: dos
       cosas superpuestas y medio transparentes, que es lo que Sara llama
       «qué mal ahí arriba». Ahora el panel es opaco de principio a fin y
       lo que cambia es CUÁNTO se ve de él: se descuelga desde la cabecera
       y se recoge hacia ella. Nunca se transparenta, así que no hay
       fantasma. Y 0,24 s en vez de 0,35: el menú tiene que sentirse
       instantáneo, no coreografiado. */
    -webkit-clip-path: inset(0 0 100% 0);
    clip-path: inset(0 0 100% 0);
    visibility: hidden;
    pointer-events: none;
    transition: -webkit-clip-path 0.24s cubic-bezier(0.4, 0, 0.2, 1),
      clip-path 0.24s cubic-bezier(0.4, 0, 0.2, 1), visibility 0s 0.24s;
  }

  .menu-abierto .nav {
    -webkit-clip-path: inset(0 0 0 0);
    clip-path: inset(0 0 0 0);
    visibility: visible;
    pointer-events: auto;
    transition: -webkit-clip-path 0.24s cubic-bezier(0.4, 0, 0.2, 1),
      clip-path 0.24s cubic-bezier(0.4, 0, 0.2, 1);
  }

  .nav a {
    font-size: 19px;
    letter-spacing: 0.05em;
    padding: 10px 16px 11px;
    text-align: center;
    background-position: 50% 100%;
  }

  /* sin subrayado de hover en el panel: a lo ancho de la fila sería una
     raya de lado a lado, y aquí no hay ratón que lo pida */
  @media (hover: hover) {
    .nav a:hover {
      background-size: 0 1px;
    }
  }

  /* el Contactar del panel, vestido de píldora rosa */
  .nav .nav-contacto {
    align-self: center;
    margin-top: 14px;
    padding: 11px 26px;
    border-radius: 999px;
    background: var(--rosa-tinta);
    color: #fff5f6;
    font-size: 14px;
    letter-spacing: 0.14em;
    text-transform: uppercase;
  }

  /* El alto del hero ya no se calcula aquí: --hero-fondo (en :root) es
     «donde acaba la rama más un respiro» o la pantalla, lo que esté más
     arriba, y en el móvil gana siempre la rama. Solo queda el aire de
     arriba, más corto que en escritorio. */
  /* El aire de entrada del móvil. El hero deja de ser «la rama pegada a la
     cabecera» y pasa a ser una PORTADA: cabecera, respiro, titular, y la
     rama cruzando por debajo a media pantalla. Ese respiro es lo que hace
     que al bajar con el dedo la rama siga en pantalla mientras florece —
     antes se iba por arriba con la cortina a medio camino. */
  /* El padding del hero NO se redeclara aquí: la regla base ya es
     «aire + 0.415em del titular», y el aire lo pone el token de arriba. Con
     un padding propio, el titular se quedaba pegado a la cabecera y la rama
     —que sí cuelga del token— se iba sola media pantalla más abajo. */

  .formulario {
    grid-template-columns: 1fr;
  }
}

/* ══════════════════════════════════════════════════════════════════
   El resto del traje de móvil
   ══════════════════════════════════════════════════════════════════ */

@media (max-width: 900px) {
  /* Menos aire entre secciones: el paso de escritorio (88-168px) en una
     pantalla de bolsillo se leía como descampados. Un solo mando. */
  :root {
    /* lo que mide la cabecera de móvil (16 + 44 + 16); script.js la remide,
       pero hasta entonces el valor de escritorio (121) dibujaba la rama
       47px demasiado baja y luego saltaba */
    --cab: 76px;
    --paso-y: clamp(34px, 6.5vw, 56px);

    /* ── LA PORTADA DEL MÓVIL ──
       El problema de fondo, medido: en un escritorio de 1440×900 la banda
       de madera ocupa el 65 % del alto de la pantalla; en un teléfono de
       390×844 ocupaba el 19 %. La misma composición se cae porque la
       pantalla pasa de apaisada a vertical: la rama se mide contra el ANCHO
       (72,54vw) y el alto disponible se ha duplicado. De ahí las dos cosas
       que se veían a la vez —«sobra negro arriba» y «la rama pierde
       potencia»—: son la misma.

       No se arregla subiéndolo todo contra la cabecera, que ya se probó y
       quedaba fatal. Se arregla al revés: la rama y el titular CRECEN hasta
       llenar el hueco, y el aire de arriba baja a la mitad porque ya no
       tiene que rellenar nada.

         · la rama pasa de 72,54vw a 100vw → la banda sube del 19 % al 26 %
           del alto en un 390 (de 158 a 217 px), y del 23 % al 31 % en un
           320. No se sube más: tumbada, su ancho en pantalla es 1,499 × este
           valor, y pasado el 100vw empiezan a irse fuera las dos puntas
           afiladas, que son la silueta. A 118vw se probó y la rama se lee
           como un tronco recto cruzando.
         · el titular pasa de 9vw a 11vw (43 px en un 390, era 35). Todo
           cuelga de él —la cresta va en em del titular—, así que agrandarlo
           sube la rama y mantiene la proporción del borrador. «HAZ FLORECER
           TU» mide 6,341em: a 11vw son 273 px de los 350 disponibles, así
           que sigue entrando en una línea.
         · el aire baja de 18svh a 10svh: 78 px de negro entre la línea de la
           cabecera y el titular en un 390, donde había 142. Sigue habiendo
           entrada; lo que ya no hay es descampado.

       Y las dos medidas llevan TOPE POR ALTURA además de por anchura. Un
       móvil tumbado mide 844×390: con 11vw el titular salía a 93 px —dos
       líneas, 211, más de media pantalla— y con 100vw la banda de madera
       salía a 471 px, o sea MÁS ALTA QUE LA PANTALLA. El `min()` con svh es
       el que dice «pero nunca más de esto de alto», y en vertical no manda
       nunca: en un 390×844, 13svh son 110 px contra los 43 de 11vw. */
    --fs-hero: clamp(36px, min(11vw, calc(var(--vh-fijo) * 0.13)), 84px);
    --hero-aire: clamp(46px, calc(var(--vh-fijo) * 0.1), 120px);
    /* Y SUELO en el valor de escritorio, 72,54vw. Por debajo de 65,4vw la
       rama deja de sangrar por la izquierda y se queda flotando desde el
       canto derecho, como pegada con celo — en un móvil tumbado, el tope
       por altura la dejaba justo ahí. Con este suelo, el apaisado vuelve
       EXACTAMENTE a lo que hacía antes de todo esto: cruzar la pantalla
       entera aunque se salga por debajo del pliegue. */
    --tronco-w: clamp(72.54vw, calc(var(--vh-fijo) * 0.8), 100vw);
  }

  /* La cortina del tronco (--barrido) ya no vive aquí: está más arriba,
     en el media «estrecho O sin ratón», porque las tablets la necesitan
     aunque midan más de 900 px. */

  /* — El hueco ultra negro entre la rama y el manifiesto —
     El padding de escritorio reservaba sitio para una rama mucho más
     grande. Aquí la rama invade poco y el respiro va corto: los pétalos
     caen justo donde arranca el texto. */
  .section-2 {
    padding-top: calc(
      max(0px, var(--rama-fondo) - var(--hero-fondo)) + clamp(28px, 6vh, 56px)
    );
    /* svh: ver .section-2 de escritorio */
    padding-top: calc(
      max(0px, var(--rama-fondo) - var(--hero-fondo)) + clamp(28px, calc(var(--vh-fijo) * 0.06), 56px)
    );
    padding-bottom: clamp(56px, 10vh, 110px);
    padding-bottom: clamp(56px, calc(var(--vh-fijo) * 0.1), 110px);
  }

  .s2-cuerpo {
    gap: clamp(56px, 10vh, 110px);
    gap: clamp(56px, calc(var(--vh-fijo) * 0.1), 110px);
  }

  /* — La savia, centrada sobre el vídeo —
     En móvil no hay márgenes donde poner los bloques: van centrados encima
     del plano, con el velo repartido en vez de pegado a los lados. */
  /* :not(.savia-simple): el centrado sobre el vídeo es del plano fijo. En
     modo lista (móvil apaisado) estas reglas ganaban a las de la lista por
     ir después, y salían bloques estrechos centrados con los números de los
     pasos colgando en el margen. */
  .s-savia:not(.savia-simple) .savia-bloque,
  .s-savia:not(.savia-simple) .savia-bloque[data-lado="izq"],
  .s-savia:not(.savia-simple) .savia-bloque[data-lado="der"] {
    left: 0;
    right: 0;
    margin-inline: auto;
    width: min(86vw, 430px);
    align-items: center;
    text-align: center;
  }

  .s-savia:not(.savia-simple) .savia-bloque-titulo,
  .s-savia:not(.savia-simple) .savia-bloque[data-lado="centro"] {
    width: min(88vw, 460px);
  }

  /* La cejilla repetida del segundo acto rotula la columna derecha mientras
     los pasos van en la izquierda. Con todo centrado no hay columna que
     rotular, y caía justo encima del paso 01. */
  .savia-bloque-marca {
    display: none;
  }

  /* y los H3 de la savia por debajo de su H2, que en 320-380 se daban la
     vuelta */
  .savia-bloque h3 {
    font-size: clamp(18px, 5vw, 22px);
  }

  /* ── La sombra que hacía legible el texto, y que en el móvil era una
     MANCHA ──
     En escritorio es un óvalo que se apaga en sus cuatro lados y nadie ve
     dónde acaba, porque el bloque es una columna estrecha en un margen.
     Centrado sobre el vídeo, ese mismo óvalo mide 638px de ancho en una
     pantalla de 390: sus lados —justo donde el degradado va por la mitad—
     caen FUERA de la pantalla, así que no se apagan, se CORTAN. El
     resultado eran dos cantos verticales oscuros de arriba abajo, y con
     los cuatro pasos acumulados, un pegote negro sobre la mano.

     Aquí el velo cruza de canto a canto (−50vw a cada lado, lo recorta el
     overflow de .page) y solo se desvanece por arriba y por abajo: no
     existe ningún borde lateral que se pueda ver. Y va a la mitad de tinta
     que el óvalo, porque ya no tiene que tapar nada — la lectura la
     sostienen la sombra del texto y este apoyo juntos. */
  /* La rampa iba de 0 a 0,46 en un 15% del alto y luego se quedaba plana:
     ese codo tan brusco se VE — dos rayas horizontales donde el velo
     empieza y acaba. Ahora la caja respira más (-52px) y la tinta sube y
     baja en campana, con muchos escalones pequeños en vez de dos grandes:
     no hay ningún punto donde el ojo pueda clavar un borde. De paso baja
     la tinta máxima (0,54 → 0,44): la sombra del propio texto ya sostiene
     la lectura y el velo solo acompaña. */
  .s-savia:not(.savia-simple) .savia-caja::before {
    inset: -52px -50vw;
    background: linear-gradient(
      180deg,
      rgba(0, 0, 0, 0) 0%,
      rgba(0, 0, 0, 0.05) 9%,
      rgba(0, 0, 0, 0.16) 20%,
      rgba(0, 0, 0, 0.3) 33%,
      rgba(0, 0, 0, 0.42) 45%,
      rgba(0, 0, 0, 0.44) 50%,
      rgba(0, 0, 0, 0.42) 55%,
      rgba(0, 0, 0, 0.3) 67%,
      rgba(0, 0, 0, 0.16) 80%,
      rgba(0, 0, 0, 0.05) 91%,
      rgba(0, 0, 0, 0) 100%
    );
  }

  /* Los números de los pasos vuelven a la columna. Su sitio es un canalón
     a la izquierda del texto, y con todo centrado ese canalón no existe:
     quedaban cuatro cifras sueltas contra el borde de la pantalla, sin
     nada que numerar. Aquí van encima de cada título, centrados, como la
     cejilla de una sección. */
  .s-savia:not(.savia-simple) .savia-pasos {
    padding-left: 0;
    gap: clamp(22px, calc(var(--vh-plano) * 0.036), 38px);
  }

  .s-savia:not(.savia-simple) .savia-paso .savia-n {
    position: static;
    display: block;
    width: auto;
    margin-bottom: 3px;
  }

  /* y el alzado óptico se acorta: en el fotograma final la mano entra por
     abajo, pero en vertical ocupa mucho menos que en apaisado */
  .s-savia:not(.savia-simple) .savia-bloque-pasos {
    padding-bottom: clamp(60px, calc(var(--vh-plano) * 0.14), 150px);
  }

  /* El velo, casi nada: la capa plana de antes tapaba el vídeo entero y se
     veía sucio. Solo un apoyo por abajo; la lectura la ponen la sombra del
     texto y el halo de cada caja, que ya existen. */
  .savia-velo {
    background: linear-gradient(
      0deg,
      rgba(0, 0, 0, 0.42) 0%,
      rgba(0, 0, 0, 0) 24%
    );
  }

  /* — El cierre de la página, sin descampados — */
  .pie {
    padding-top: clamp(40px, 8vw, 64px);
  }

  /* el pie en columna, centrado: dos plantas no caben en fila */
  .pie-arriba {
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 26px;
  }

  .pie-secciones {
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    gap: 10px 18px;
    padding-top: 0;
  }

  .pie-abajo {
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 12px;
  }


  /* — El manifiesto y su tramo: menos negro vacío — */
  .section-2 {
    padding-bottom: clamp(44px, 8vh, 80px);
    padding-bottom: clamp(44px, calc(var(--vh-fijo) * 0.08), 80px); /* svh: ver .section-2 */
  }

  .s2-cuerpo {
    gap: clamp(40px, 8vh, 80px);
    gap: clamp(40px, calc(var(--vh-fijo) * 0.08), 80px);
  }

  /* — Las cartas de precios, de dos en dos —
     En columna eran cinco pantallas de tarjetas; a pares se comparan de un
     vistazo, que es su trabajo. La tercera (Flor) cierra la fila sola a lo
     ancho. */
  .siembra,
  .siembra-dos {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px;
    /* el ancho «dos huecos de tres» de escritorio no vale aquí: las dos
       fichas van a pares a todo lo ancho, como las otras */
    width: 100%;
    max-width: 560px;
    margin-inline: auto;
  }

  .siembra > .brote:nth-child(3) {
    grid-column: 1 / -1;
  }

  /* — La ficha se mide A SÍ MISMA —
     Todo lo de dentro va en cqw: centésimas del ancho de la propia carta,
     no de la pantalla. Es la diferencia entre una ficha de 143 px en un
     móvil y una de 275 en una tablet: antes las dos llevaban la misma letra
     de 11,5 px (y el «voltear» a 8,5), pensada para la pequeña, y en la
     tablet sobraba media carta de blanco. Ahora cada una habla al volumen
     de su tamaño, con suelo (nada baja de 12 px en cuerpo ni de 9,5 en
     etiquetas) y techo (los valores de escritorio).

     Cada propiedad lleva primero su valor en px: es el respaldo para un
     navegador que no entienda cqw, que entonces se queda con la talla de
     bolsillo. */
  .brote {
    container-type: inline-size;
  }

  .brote-btn {
    --solapa: 28px;
    --solapa: clamp(26px, 14cqw, 40px);
    min-height: clamp(210px, 58vw, 280px);
    min-height: clamp(210px, 150cqw, 330px);
    padding: 14px 10px;
    padding: clamp(12px, 6cqw, 22px) clamp(10px, 5cqw, 20px);
    padding-top: 40px;
    padding-top: clamp(40px, 18cqw, 54px);
  }

  /* la tercera (Flor) va sola a todo lo ancho: más baja, que no es más
     importante por ser más ancha */
  .siembra > .brote:nth-child(3) .brote-btn {
    min-height: clamp(190px, 50vw, 250px);
    min-height: clamp(190px, 70cqw, 260px);
  }

  .brote-nombre {
    font-size: 17px;
    font-size: clamp(16px, 10cqw, 24px);
  }

  .brote-frase {
    font-size: 12px;
    font-size: clamp(12px, 6cqw, 14px);
    max-width: 22ch;
  }

  .brote-accion {
    font-size: 10px;
    font-size: clamp(10px, 4.6cqw, 11px);
    letter-spacing: 0.13em;
  }

  .brote-lienzo {
    min-height: 74px;
    min-height: clamp(74px, 38cqw, 120px);
  }

  .brote-sello {
    font-size: 9px;
    font-size: clamp(9px, 4cqw, 9.5px);
    padding: 4px 9px 3px;
    top: 10px;
    white-space: nowrap;
  }

  /* en bolsillo, la versión corta del sello; la larga vuelve en cuanto la
     carta pasa de 200 px (más abajo, en el @container) */
  .sello-larga {
    display: none;
  }

  .sello-corta {
    display: inline;
  }

  /* el dorso, a la misma escala que la cara */
  .brote-dorso {
    padding: 16px 10px;
    padding: clamp(14px, 7cqw, 26px) clamp(10px, 5cqw, 20px);
  }

  .dorso-quien {
    font-size: 9px;
    font-size: clamp(9px, 4cqw, 10px);
  }

  .dorso-titulo {
    font-size: 12.5px;
    font-size: clamp(12.5px, 6cqw, 15px);
    margin-top: 8px;
  }

  .dorso-para {
    font-size: 12px;
    font-size: clamp(12px, 5.6cqw, 13.5px);
    margin-top: 10px;
  }

  .dorso-incluye {
    font-size: 11.5px;
    font-size: clamp(11.5px, 5cqw, 12.5px);
    margin-top: 8px;
    padding-top: 8px;
  }

  .dorso-plazo {
    font-size: 11px;
    font-size: clamp(11px, 4.6cqw, 12px);
    margin-top: 8px;
  }

  .dorso-precio b {
    font-size: 22px;
    font-size: clamp(22px, 11cqw, 30px);
  }

  .dorso-cta {
    font-size: 11px;
    font-size: clamp(11px, 4.4cqw, 11.5px);
    padding: 9px 14px;
    margin-top: 10px;
  }

  .dorso-volver {
    font-size: 10.5px;
    font-size: clamp(10.5px, 4cqw, 11px);
    margin-top: 10px;
  }

  /* La primera columna fija (sticky) ya no hace falta en la tabla de la
     página —cabe entera, no se arrastra—, pero SÍ dentro de la ventana de
     ampliar, que sigue deslizando porque ahí van los textos largos. */
  .vt-cuerpo {
    container-type: inline-size;
    /* cada arrastre aterriza con un plan encajado tras la columna fija:
       deslizar deja de ser «a ojo» (petición de Sara, 1 sep). `proximity`
       y no `mandatory`: en los móviles más estrechos la columna es más
       ancha que el hueco y el imán duro dejaría el borde derecho sin poder
       leerse nunca. */
    scroll-snap-type: x proximity;
  }

  /* el imán de cada plan: su cabecera, corrida el ancho de la columna fija */
  .vt-cuerpo thead th {
    scroll-snap-align: start;
    scroll-margin-left: clamp(108px, 36cqw, 150px);
  }

  /* La pista de que hay más planes a la derecha, quieta mientras la tabla
     desliza por debajo. Solo aquí dentro: la tabla de la página ya trae la
     suya. */
  .vt-cuerpo::before {
    content: "Desliza para comparar →";
    position: sticky;
    left: 2px;
    display: inline-block;
    font-family: "Oswald", sans-serif;
    font-weight: 300;
    font-size: 10.5px;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--rosa-hondo);
    padding-bottom: 10px;
  }

  /* La de serie, fuera. En el iPhone solo asoma mientras el dedo se mueve
     —o sea, justo cuando ya sabes que se desliza— y el resto del rato deja
     una rayita rosa suelta que parece un fallo. La barra de esta ventana la
     pinta .vt-guia, que se ve siempre y dice por dónde vas. */
  .vt-cuerpo {
    scrollbar-width: none;
  }

  .vt-cuerpo::-webkit-scrollbar {
    display: none;
  }

  .vt-cuerpo .tabla-planes tbody th,
  .vt-cuerpo tbody th {
    position: sticky;
    left: 0;
    z-index: 1;
    --th-w: clamp(108px, 36cqw, 150px);
    width: var(--th-w);
    min-width: var(--th-w);
    padding-inline: 14px;
    background: #ffffff;
  }

  .vt-cuerpo thead td:first-child {
    position: sticky;
    left: 0;
    z-index: 1;
    background: #ffffff;
    /* En reparto automático, la tabla le regalaba a esta columna el ancho
       sobrante del min-width (salían 190px en un móvil de 320) y los tres
       planes quedaban en una rendija de 30-50px: letras sueltas. Con el
       reparto FIJO de abajo, esta celda —que por ser de la primera fila
       manda sobre su columna entera— se queda en su clamp y los tres
       planes se reparten el resto a partes iguales (~200px cada uno). */
    width: clamp(108px, 36cqw, 150px);
  }

  .vt-cuerpo table {
    table-layout: fixed;
  }

  .vt-cuerpo tr.tp-eje th {
    background: #f7f7f6;
  }
}

/* La ficha ancha (tablet a pares, o una sola columna): vuelve el sello
   entero. Va en su propio @container porque depende del ancho de la carta,
   no de la pantalla: anidado dentro del media de arriba para que en
   escritorio, donde el sello largo ya es el de serie, no pinte nada. */
@media (max-width: 900px) {
  @container (min-width: 200px) {
    .sello-larga {
      display: inline;
    }

    .sello-corta {
      display: none;
    }
  }
}

/* ── Tablet entre 700 y 900: las tres fichas en fila ──
   A pares con la tercera sola debajo era el esquema del móvil estirado: en
   una tablet de 768 caben las tres en una fila de 215 px cada una, que es
   la composición del escritorio. Las dos de riego se quedan a pares. */
@media (min-width: 700px) and (max-width: 900px) {
  .siembra {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    max-width: 720px;
  }

  .siembra > .brote:nth-child(3) {
    grid-column: auto;
  }

  .siembra > .brote:nth-child(3) .brote-btn {
    min-height: clamp(210px, 150cqw, 330px);
  }

  /* .siembra-dos también ES .siembra: sin esto heredaba las tres columnas
     de arriba y sus dos fichas salían de un tercio */
  .siembra-dos {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    max-width: 480px;
  }
}

/* ── Por debajo de 360: una ficha por fila ──
   A 320 px de pantalla las dos columnas dejaban cartas de 123 px: el sello
   no cabía y la frase iba a cuatro líneas. Es el único ancho donde los
   pares no funcionan; una sola columna de 236 px lee mejor que dos de
   bolsillo. */
@media (max-width: 359px) {
  .siembra,
  .siembra-dos {
    grid-template-columns: minmax(0, 1fr);
  }

  .siembra > .brote:nth-child(3) {
    grid-column: auto;
  }

  .siembra > .brote:nth-child(3) .brote-btn {
    min-height: clamp(210px, 150cqw, 330px);
  }
}

/* ══════════════════════════════════════════════════════════════════
   EL DIAGNÓSTICO, UNA LETANÍA (≤699)

   Siete fichas de 120 px seguidas se leen como un formulario: se ve el
   LARGO antes que las frases, y quien mira baja pasando. La queja no era
   de las frases —hacen falta las siete, el visitante tiene que
   reconocerse en alguna—, era del largo.

   Y el largo no estaba en el texto. Midiendo: unos 450 px de letra
   contra 371 px de CHROME —44 de relleno, 8 de hueco y 1 de filete,
   repetidos siete veces—. Más de un tercio del bloque era relleno.

   Así que no se quita ninguna frase: se quita el chrome. Fuera los siete
   filetes horizontales (que son justo lo que dice «esto es una tabla»),
   fuera el relleno, y el interlineado pasa a marcar el ritmo. En el
   canalón de la izquierda, una semilla rosa por estrofa: es lo que hace
   que dos renglones se lean como UNA cosa y no como dos frases sueltas,
   el papel que hacían los filetes pero sin cortar la página en siete.

   Lo que queda es un poema de once renglones. Mismas siete citas, mismas
   siete consecuencias, nada plegado ni escondido: de ~860 px a ~560.
   ══════════════════════════════════════════════════════════════════ */
@media (max-width: 699px) {
  .s-diag .sintomas {
    margin-top: clamp(22px, 6vw, 30px);
  }

  .s-diag .sintomas li {
    display: block;
    padding: 0 0 0 21px;
    border-bottom: 0;
    /* el aire entre estrofas, que ya no es «una fila más» */
    margin-top: 17px;
  }

  .s-diag .sintomas li:first-child {
    margin-top: 15px;
  }

  /* La semilla ya está definida arriba, para todas las pantallas. Aquí solo
     se recoloca: sin relleno de fila que descontar, se sube a la altura del
     primer renglón de la cita. */
  .s-diag .sintomas li::after {
    left: 2px;
    top: 0.52em;
    width: 7px;
  }

  .s-diag .sintoma-dice {
    display: block;
    font-size: clamp(15.5px, 4.3vw, 17.5px);
    line-height: 1.33;
  }

  .s-diag .sintoma-pasa {
    display: block;
    margin-top: 3px;
    font-size: clamp(12.5px, 3.4vw, 13.5px);
    line-height: 1.42;
    /* Sube del 48 % al 62 % de blanco (de 4,9:1 a 7,8:1 de contraste). En
       escritorio el 48 % es correcto: es una nota al margen en la segunda
       columna, compitiendo con seis más. Aquí es la única letra pequeña de
       su estrofa y hay que poder leerla del tirón. */
    color: rgba(255, 255, 255, 0.62);
  }

  /* el remate ya no necesita separarse de una lista larga */
  .s-diag .remate {
    margin-top: clamp(34px, 8vw, 52px);
  }
}

/* ══════════════════════════════════════════════════════════════════
   EL VIVERO SE RECORRE DE LADO (≤699)

   La queja era «demasiado compactado», y era literal: 158 px de papel
   para meter el sello, el nombre, la frase, la planta y —por detrás— un
   dorso entero. La alternativa contraria ya se había probado y
   descartado: una columna, cinco pantallas de tarjetas.

   La tercera vía no es cambiar la rejilla, es cambiar el GESTO. Las
   fichas dejan de ser una cuadrícula que se abarca de un vistazo y pasan
   a ser un RAÍL que empuja el pulgar: se ve una carta entera y el canto
   de la siguiente asomando, que es lo que invita a seguir. Y esa carta
   mide 296 px en un teléfono de 390 en vez de 158.

   Lo bueno es que no hay que tocar el sistema de §12b: como todo lo de
   dentro de la ficha va en cqw, al doblar el ancho TODOS los clamp()
   tocan su techo solos. El nombre vuelve a 24 px, la frase a 14, el
   título del dorso a 15, el precio a 30, y el `@container (min-width:
   200px)` que ya existe devuelve el sello largo entero. La ficha de
   bolsillo recupera la tipografía de escritorio sin una escala nueva.

   DOS RAÍLES y no uno: la sección cuenta que primero se planta —Semilla,
   Brote, Flor— y que después, si se quiere, se riega. El HTML ya son dos
   .siembra; cada una se vuelve su raíl y el relato queda intacto.

   Y el volteo no se toca: es lo que más gana. El dorso que hoy se lee a
   12,5 px porque no cabe, a 296 px se lee como en un portátil.
   ══════════════════════════════════════════════════════════════════ */
@media (max-width: 699px) {
  .vivero {
    /* el raíl trae su propio aire arriba y abajo; el del vivero sumaba
       44 px de nada */
    padding-block: 0;
    padding-inline: 0;
  }

  .siembra,
  .siembra-dos {
    /* Sigue siendo una rejilla —así hereda el gap y el estirado— pero de
       UNA fila y columnas implícitas. El `grid-template-columns: none` es
       lo que mata las dos columnas del bloque de ≤900 y la columna única
       del de ≤359. */
    display: grid;
    grid-auto-flow: column;
    /* La carta SÍ va en vw, y tiene que ir: en porcentaje se muerde la cola
       —`grid-auto-columns` resuelve los porcentajes contra la caja de
       contenido, que es el ancho menos el relleno, y el relleno se calcula a
       partir de la carta—. Con barra clásica sale unos píxeles ancha, que no
       se nota; lo que no puede fallar es el CENTRADO, y ese lo da el relleno
       de aquí abajo, que sí está medido sin barra. */
    --carta: min(76vw, 340px);
    grid-auto-columns: var(--carta);
    grid-template-columns: none;
    gap: 12px;
    width: auto;
    max-width: none;

    /* A SANGRE, y medido SIN vw. El raíl empieza y acaba en los cantos de la
       pantalla: una carta que asoma cortada por el borde se lee como «hay
       más»; cortada por un margen interior, como un fallo de maquetación.

       Y aquí `100vw` no vale, aunque sea lo obvio: incluye la barra de
       desplazamiento y el ancho visible no. En un navegador de escritorio
       con barra clásica —la ventana estrechada a modo móvil— eran 15 px de
       más, o sea la carta 7,5 px descentrada al soltar el dedo. Se mide
       desde el canalón del contenedor, que es un número exacto: el ancho
       propio (100 %, ya sin barra) más los dos canalones ES la pantalla. */
    --canal: clamp(22px, 5vw, 44px);
    margin-inline: calc(-1 * var(--canal));
    /* Lo que sobra a cada lado de una carta centrada: (pantalla − carta) / 2.
       Esta cuenta es la que permite que el imán centre de verdad, incluidas
       la primera y la última — con un relleno cualquiera, la primera no
       puede llegar al centro (haría falta un scroll negativo) y se queda
       descuadrada. Y de paso las dos vecinas asoman lo mismo por los dos
       lados. */
    padding-inline: calc((100% + 2 * var(--canal) - var(--carta)) / 2);

    /* Arriba y abajo, sitio para dos cosas que se salen de la carta: la
       mancha de sombra (.brote::before, 36 px por debajo) y el canto que
       se acerca al ojo a mitad de giro, que con perspectiva de 1050 px
       crece unos 28. Un contenedor que desborda RECORTA, y sin este aire
       el giro se vería cortado por arriba. */
    padding-block: 30px 40px;

    /* Un solo eje no se puede desbordar: por especificación, en cuanto uno
       deja de ser `visible` el otro pasa de `visible` a `auto`. O sea que
       el raíl RECORTA también por arriba y por abajo, y lo que salva el
       giro es el padding de aquí arriba, que forma parte del scrollport.
       No es relleno decorativo: si se quita, el volteo sale cortado. */
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    /* que el gesto no arrastre la página ni dispare el «atrás» */
    overscroll-behavior-x: contain;
    scrollbar-width: none;
  }

  .siembra::-webkit-scrollbar,
  .siembra-dos::-webkit-scrollbar {
    display: none;
  }

  /* Con ratón, el raíl se anuncia como algo de lo que se puede tirar. */
  .siembra,
  .siembra-dos {
    cursor: grab;
  }

  .siembra.tirando,
  .siembra-dos.tirando {
    cursor: grabbing;
    /* mientras se tira, nada de seleccionar texto ni de que las fichas
       reaccionen al puntero: se está moviendo el raíl, no leyendo */
    -webkit-user-select: none;
  user-select: none;
  }

  .siembra.tirando .brote-btn,
  .siembra-dos.tirando .brote-btn {
    pointer-events: none;
  }

  .siembra > .brote,
  .siembra-dos > .brote {
    /* AL CENTRO, no al canto. Con `start` la carta se pegaba al borde
       izquierdo y al soltar el dedo te quedabas a medias entre dos; con
       `center` cada ficha aterriza en mitad de la pantalla, que es donde el
       ojo la estaba buscando. */
    scroll-snap-align: center;
    /* el imán para EN CADA carta: sin esto un manotazo se salta Brote
       entera, que es justo la del sello «La elección más habitual» */
    scroll-snap-stop: always;
  }

  /* la tercera dejaba de ser fila entera: aquí es una carta más del raíl */
  .siembra > .brote:nth-child(3) {
    grid-column: auto;
  }

  .siembra > .brote:nth-child(3) .brote-btn,
  .brote-btn {
    /* la carta ya es ancha: el alto se mide contra su propio ancho */
    min-height: clamp(300px, 118cqw, 420px);
  }

  /* ── La guía ──
     Una barrita con un tramo rosa que avanza: dice cuántas cartas hay y por
     dónde vas, sin puntitos de aplicación. La posición la escribe script.js
     en --p (de 0 a 1) y el ancho del tramo en --n (una fracción por carta).

     Medía 1,5 px y era un error: a ese grosor no se leía como un mando, se
     leía como una raya rosa que no debería estar ahí —«deja un footprint al
     deslizar», Sara, 1 sep—. Una barra de deslizar tiene que parecer una
     barra de deslizar: 5 px, redondeada, con su carril visible. Es la misma
     pieza que ahora lleva la ventana de la tabla, para que las dos cosas
     que se deslizan a lo ancho en el teléfono se anuncien igual. */
  .siembra-guia {
    display: block;
    position: relative;
    width: min(190px, 56vw);
    height: 5px;
    margin: 6px auto 0;
    border-radius: 999px;
    background: rgba(26, 23, 18, 0.11);
    overflow: hidden;
  }

  /* SIN transición. La tenía de 0,18 s y era el motivo de que la barrita no
     fuera fluida (Sara, 1 sep): el dedo mueve el raíl y el tramo salía
     persiguiéndolo con dos décimas de retraso, y como la posición se
     reescribe en CADA fotograma, la transición volvía a empezar cada vez y
     nunca llegaba. Escrita en crudo, el tramo va pegado al dedo. */
  .siembra-guia span {
    position: absolute;
    inset-block: 0;
    left: 0;
    width: calc(100% * var(--n, 0.34));
    border-radius: inherit;
    background: var(--rosa-hondo);
    transform: translateX(calc(var(--p, 0) * (100% / var(--n, 0.34) - 100%)));
  }
}

@media (max-width: 560px) {
  .btn {
    width: 100%;
  }

  /* ── La letra, un escalón entero más pequeña ──
     Los clamp() de escritorio tocan suelo demasiado alto para un teléfono:
     el titular de 31px que en un portátil respira, en 375px es un cartel.
     Aquí se re-tara TODA la tipografía grande de la página. */
  .titular {
    font-size: clamp(23px, 6.4vw, 28px);
  }

  .entradilla {
    font-size: 14.5px;
    margin-top: 16px;
  }

  .manifiesto {
    font-size: clamp(18px, 5.2vw, 22px);
  }

  .remate {
    font-size: clamp(17px, 4.8vw, 21px);
  }

  .sintoma-dice {
    font-size: 15.5px;
  }

  .sintoma-pasa {
    font-size: 13px;
  }

  .savia-titular {
    font-size: clamp(21px, 6vw, 26px);
  }

  .savia-titular-xl {
    font-size: clamp(24px, 7vw, 31px);
  }

  .savia-cejilla {
    font-size: 11px;
    margin-bottom: 12px;
  }

  .savia-caja p {
    font-size: 14px;
  }

  .faq summary {
    font-size: 15px;
    padding-block: 16px;
  }

  .faq-cuerpo p {
    font-size: 14px;
  }

  .campo input,
  .campo textarea {
    /* 16 y no 15: por debajo de 16 px iOS hace zoom al tocar el campo */
    font-size: 16px;
    padding: 12px 14px;
  }

  .letra-pequena {
    font-size: 12px;
  }

  /* Las cuatro cifras EN UNA FILA, como una regla de medir: el número
     grande y su letrero debajo, apretados pero juntos. En columna eran
     cuatro paradas de un metro cada una. minmax(0,1fr): sin el 0, el
     contenido mínimo de una celda puede empujar a las demás fuera de la
     pantalla, que es justo lo que pasaba con la cuarta cifra. */
  .cifras {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 6px;
    text-align: center;
  }

  .cifra-n {
    font-size: clamp(20px, 6vw, 26px);
  }

  .cifra-txt {
    font-size: clamp(10.5px, 2.9vw, 12px);
    line-height: 1.4;
  }

  /* Un punto menos de letra en la tabla: a 320 px las columnas de respuesta
     miden 57 px y «3 o 4 semanas» necesita partirse sin que la fila crezca
     el doble. */
  .tp-marco table {
    /* fluida entre 320 y 390: los 11 px son el precio de que quepa entera
       en el teléfono más estrecho, no una talla para todos */
    font-size: clamp(11px, 3.1vw, 12px);
  }

  .tabla-planes tbody th {
    font-size: clamp(11px, 3vw, 11.5px);
    padding-inline: 8px;
  }

  .tabla-planes tbody td {
    padding-inline: 3px;
  }

  /* el título de la ventana no se mete bajo el botón de cerrar */
  .v-titulo {
    padding-right: 44px;
  }
}

/* Sin ratón no hay hover: en una pantalla táctil el navegador deja el
   estado :hover puesto tras un toque, y el Enviar se quedaba levantado y
   en blanco, la pregunta de la FAQ en rosa y la píldora clara. Aquí se
   neutralizan los que se notan. */
@media (hover: none) {
  .btn:hover {
    transform: none;
  }

  .btn:hover::before {
    transform: translateY(101%);
  }

  .btn-solido:hover,
  .s-contacto .btn-solido:hover {
    color: inherit;
  }

  .faq summary:hover {
    color: var(--ink-crema);
  }

  .pildora:hover {
    background: var(--rosa-tinta);
  }

  .ventana-cerrar:hover {
    background: rgba(255, 255, 255, 0.8);
    border-color: var(--linea);
  }
}

/* ══════════════════════════════════════════════════════════════════
   Dedos, no cursores
   Donde el puntero es grueso (pantallas táctiles, de cualquier tamaño),
   los enlaces y botones pequeños ganan zona de pulsado sin cambiar de
   aspecto: relleno hacia fuera y margen negativo que lo compensa, así el
   texto no se mueve ni un píxel y la diana pasa de 15 a 40 px de alto.
   En escritorio no existe nada de esto.
   ══════════════════════════════════════════════════════════════════ */
@media (pointer: coarse) and (min-width: 901px) {
  /* la cabecera de escritorio en una tablet táctil: las palabras del menú
     miden 36 px de alto; relleno hacia fuera y margen que lo anula */
  .nav a {
    padding-block: 10px;
    margin-block: -10px;
  }
}

@media (pointer: coarse) {
  .pie-legal button,
  .pie-secciones a,
  .pie-mail a,
  .form-nota a {
    display: inline-block;
    padding-block: 13px;
    margin-block: -13px;
  }

  .dorso-volver {
    padding: 13px 16px;
    margin: -3px -16px -13px;
  }

  .dorso-cta {
    padding-block: 12px;
  }

  .tp-ampliar {
    padding-block: 12px;
  }

  .ventana-cerrar {
    width: 44px;
    height: 44px;
  }

  .faq summary {
    min-height: 48px;
  }

  /* los enlaces del pie, en fila en el móvil: con el relleno de arriba se
     tocarían unos a otros en vertical; el hueco de la rejilla lo absorbe */
  .pie-secciones {
    row-gap: 14px;
  }
}

/* ── Las manos en pantallas estrechas ──
   Recortado por los lados (object-fit: cover sobre el aspect-ratio): en
   16:9 a 390 px la flor pasa de 170 a 220 px de alto; en 3:2, por debajo de
   600, a 260. Los dedos de las dos manos siguen dentro del encuadre —medido
   sobre el fotograma—; lo que se pierde es brazo, que entra por el canto
   igual. */
@media (max-width: 900px) {
  .manos-video {
    aspect-ratio: 16 / 9;
  }
}

@media (max-width: 600px) {
  .manos-video {
    aspect-ratio: 3 / 2;
  }
}
