/* ===================================================================
   Trading Fácil y Sencillo
   Hoja principal. Los valores de marca están en tokens.css.
   =================================================================== */

/* ---- Reset ------------------------------------------------------- */

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

html {
  scroll-behavior: smooth;
  /* El header fijo no debe tapar el destino de los anclajes. */
  scroll-padding-top: calc(var(--header-h) + 16px);
  -webkit-text-size-adjust: 100%;
}

img,
svg {
  display: block;
  max-width: 100%;
}

button {
  font: inherit;
  color: inherit;
  background: none;
  border: none;
  cursor: pointer;
}

/* Un solo anillo de foco para todo lo que se puede enfocar. Diecinueve
   de las treinta y cuatro paradas del tabulador caían en el de fábrica
   —`1px auto`, que sobre este fondo dibuja un aro casi negro— y las
   otras quince llevaban el naranja del sistema: se veían todas, pero no
   se parecían en nada.

   Va dentro de `:where()` para que el selector no sume especificidad:
   así queda en (0,1,0) y cualquier regla de componente que necesite
   otro desplazamiento o su propio color le sigue ganando sin pelear. */
:where(a, button, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 3px;
}

/* Los enlaces no traen color ni subrayado de fábrica: en esta página
   casi ninguno parece un enlace de texto —son botones, iconos, la
   marca, tarjetas enteras—, y cada componente decide lo suyo. Los
   pocos que sí van dentro de una frase se subrayan a mano, porque el
   color por sí solo no basta para señalar un enlace. */
a {
  color: inherit;
  text-decoration: none;
}

/* ---- Base -------------------------------------------------------- */

body {
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: var(--leading-normal);
  color: var(--color-text);
  background-color: var(--color-surface-bg);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* ---- Contenedores y encabezados de sección ----------------------- */

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

.container--narrow {
  max-width: 760px;
}

.eyebrow {
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--color-text-faint);
  margin-bottom: var(--spacing-md);
}

/* Distintivo del hero: cápsula de borde naranja con letra blanca.
   Va en caja baja y sin el tracking ancho del resto de eyebrows: es
   una frase larga, y en mayúsculas espaciadas se saldría de la
   cápsula en cualquier móvil. */
.eyebrow--badge {
  display: inline-block;
  padding: 7px 16px;
  border: 1px solid var(--color-primary);
  border-radius: var(--radius-pill);
  font-size: var(--text-sm);
  font-weight: 500;
  letter-spacing: 0.01em;
  text-transform: none;
  line-height: 1.3;
  color: var(--color-light);
  margin-bottom: var(--spacing-lg);
}

/* El distintivo del hero baja a un borde gris tenue. Los de sección
   conservan el naranja: allí no hay nada al lado con lo que competir.
   Aquí sí —cae justo encima de dos botones—, y una cápsula de borde
   naranja a esa distancia se lee como un tercer botón. */
.hero .eyebrow--badge {
  border-color: rgba(255, 255, 255, 0.1);
}

.section-title {
  font-size: var(--text-3xl);
  margin-bottom: var(--spacing-md);
}

.section-lede {
  max-width: 54ch;
  font-size: var(--text-lg);
  color: var(--color-text-muted);
  margin-bottom: var(--spacing-2xl);
}

/* ---- Botones -----------------------------------------------------
   El naranja de marca queda reservado para acciones de compra. Si
   apareciera también en iconos y bordes decorativos dejaría de
   señalar dónde hay que hacer click, que es el trabajo del sitio. */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--spacing-sm);
  /* 18px de alto y 14px de cuerpo: la etiqueta se aprieta y el botón
     crece, que es lo que le da el aire de control de sistema. */
  padding: 18px 30px;
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 700;
  letter-spacing: 0.01em;
  white-space: nowrap;
  cursor: pointer;
  transition:
    background-color var(--dur) var(--ease-out),
    border-color var(--dur) var(--ease-out),
    box-shadow var(--dur) var(--ease-out),
    transform var(--dur-fast) var(--ease-out);
}

.btn--primary {
  background-color: var(--color-primary);
  /* Carbón sobre naranja da 8.9:1. El blanco daría 2.1:1 y no cumple. */
  color: var(--color-on-primary);
  box-shadow: var(--glow-primary);
}

.btn--primary:hover {
  background-color: var(--color-primary-hover);
  transform: translateY(-2px);
  box-shadow: 0 0 0 1px rgba(255, 152, 80, 0.4), 0 18px 48px rgba(255, 152, 80, 0.3);
}

.btn--primary:active {
  background-color: var(--color-primary-active);
  transform: translateY(0);
}

/* Contorno de 2px, no de 1: sobre la fotografía del hero un filete de
   un píxel se pierde entre las velas del gráfico. */
.btn--ghost {
  background-color: transparent;
  border-width: 2px;
  border-color: var(--color-border-strong);
  color: var(--color-light);
}

.btn--ghost:hover {
  border-color: var(--color-light);
  background-color: rgba(255, 255, 255, 0.08);
  transform: translateY(-2px);
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.4);
}

.btn--sm {
  padding: 11px 22px;
  font-size: var(--text-xs);
}

/* El de comprar: cuerpo de 16 y 18 de alto. Es el único botón del
   sitio que sube de los 14px, y se lo gana. */
.btn--lg {
  padding: 18px 40px;
  font-size: var(--text-base);
}

.btn--block {
  width: 100%;
}

/* ---- Revelado ---------------------------------------------------- */

/* Entrada por desenfoque: los elementos llegan fuera de foco y 12px
   abajo, y se asientan con el muelle. El desenfoque es lo que
   distingue este movimiento de un desvanecido corriente — el elemento
   parece enfocarse, no aparecer. */
[data-reveal] {
  opacity: 0;
  filter: blur(12px);
  transform: translateY(12px);
  transition:
    opacity var(--dur-spring) var(--ease-spring),
    filter var(--dur-spring) var(--ease-spring),
    transform var(--dur-spring) var(--ease-spring);
}

/* `none`, no `blur(0)`. Un desenfoque de cero sigue obligando al
   navegador a rasterizar el subárbol y a remuestrearlo, y eso se queda
   así para siempre: bajo la galería de testimonios ablandaba el texto
   de las capturas. Interpola igual —medido: 5,99px a mitad de camino—
   y al terminar no deja filtro ninguno. */
[data-reveal].is-visible {
  opacity: 1;
  filter: none;
  transform: none;
}

/* Escalonado dentro de una misma rejilla: los elementos entran uno
   detrás de otro, no todos de golpe. */
.rail__item:nth-child(2) { transition-delay: 90ms; }
.rail__item:nth-child(3) { transition-delay: 180ms; }

/* Las columnas del diagnóstico se revelan con @keyframes en lugar de
   con la transición general, y no por capricho: sus `transition`
   propias gobiernan el paso del cursor, y una sola propiedad
   `transition` no puede servir a dos gestos con duraciones distintas
   sin que uno pise al otro. Separando revelado (animación) de cursor
   (transición), cada uno conserva su tiempo.

   `backwards` mantiene el estado inicial durante el retardo del
   escalonado y, al no rellenar hacia delante, la columna queda libre
   para que el cursor la transforme después. */
.problem__col.is-visible {
  animation: revelar-columna 700ms var(--ease-out) backwards;
}

.problem__col:nth-child(2).is-visible { animation-delay: 120ms; }
.problem__col:nth-child(3).is-visible { animation-delay: 240ms; }
.problem__col:nth-child(4).is-visible { animation-delay: 360ms; }

@keyframes revelar-columna {
  from {
    opacity: 0;
    transform: translate3d(0, 24px, 0);
    filter: blur(6px);
  }
  to {
    opacity: 1;
    transform: translate3d(0, 0, 0);
    filter: blur(0);
  }
}

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

/* `fixed`, no `sticky`. El encargo pide "siempre visible" y las dos lo
   dan, pero `sticky` ocupa sus 72px en el flujo y el hero ya compensa
   la altura de la barra con su propio relleno: al cambiarlo, el hero
   bajaría 72px de golpe. En pantalla el resultado es el mismo. */
.site-header {
  position: fixed;
  inset: 0 0 auto;
  z-index: 100;
  height: var(--header-h);
  background-color: var(--color-surface-bg);
  border-bottom: 1px solid var(--color-border-subtle);
  transition:
    background-color 300ms var(--ease-out),
    box-shadow 300ms var(--ease-out),
    backdrop-filter 300ms var(--ease-out);
}

/* A partir de 10px de scroll: la sombra despega la barra del contenido
   justo cuando este empieza a pasar por debajo. El cristal esmerilado
   ya estaba y se conserva. */
.site-header.is-scrolled {
  background-color: rgba(26, 26, 26, 0.82);
  backdrop-filter: blur(14px) saturate(160%);
  -webkit-backdrop-filter: blur(14px) saturate(160%);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
}

.site-header__inner {
  display: flex;
  align-items: center;
  gap: var(--spacing-xl);
  height: 100%;
  max-width: var(--container);
  margin-inline: auto;
  /* 40 · 30 · 20 de aire lateral. */
  padding-inline: 40px;
}

.brand {
  display: block;
  flex-shrink: 0;
}

/* El logo ya viene con el fondo negro recortado en el propio archivo
   (ver assets/img/logo.webp), así que no necesita mezcla de capas. */
.brand img {
  width: auto;
  height: 54px;
}

.site-nav {
  display: flex;
  align-items: center;
  gap: 40px;
  margin-left: auto;
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--color-text-muted);
}

.site-nav a {
  position: relative;
  padding-block: 4px;
  transition: color 300ms var(--ease-out);
}

/* El botón no lleva el subrayado de los enlaces de texto: ya se
   distingue por su contorno. */
.site-nav__cta::after { content: none; }

/* En blanco, y el naranja se reserva para el gesto: en reposo el botón
   solo se distingue por su contorno, y al pasar el cursor se enciende
   entero. Así la barra no compite con el botón naranja del hero, que
   queda justo debajo.

   Va acotado a `.site-nav__cta` y no a `.btn--ghost`, porque esa clase
   la comparte el botón secundario del hero: allí el relleno naranja lo
   lleva ya el principal de al lado y encenderlo también sería repetir
   la misma llamada dos veces. */
.site-nav__cta {
  border-color: var(--color-light);
  color: var(--color-light);
}

/* `.site-nav a.site-nav__cta:hover` (0,3,1), no `.site-nav__cta:hover`
   (0,2,0): unos renglones más abajo, `.site-nav a:hover` (0,2,1) pinta
   los enlaces de naranja al pasar el cursor, y le ganaba a la clase
   sola. El botón se rellenaba de naranja y el texto se volvía naranja
   también: 1:1, la etiqueta desaparecía. */
.site-nav a.site-nav__cta:hover {
  /* Se rellena de naranja y el texto pasa al fondo oscuro: 8.80:1. El
     blanco sobre naranja habría dado 2.13:1 y no cumpliría AA en un
     cuerpo de 12px. */
  background-color: var(--color-primary);
  border-color: var(--color-primary);
  color: var(--color-surface-deep);
  box-shadow: 0 4px 12px rgba(255, 152, 80, 0.3);
}

.site-nav a::after {
  content: '';
  position: absolute;
  inset: auto 0 0;
  height: 1px;
  background-color: currentColor;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur) var(--ease-out);
}

.site-nav a:hover {
  color: var(--color-primary);
}

.site-nav a:hover::after {
  transform: scaleX(1);
}

.site-nav a:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 6px;
  border-radius: 4px;
  color: var(--color-primary);
}

/* ---- La hamburguesa ------------------------------------------------
   Tres barras que se convierten en una equis. Se giran las de fuera y
   se apaga la del medio: el gesto dice "esto se cierra", que es lo que
   un icono nuevo no diría. */

.hamburguesa {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 44px;
  height: 44px;
  margin-left: auto;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}

.hamburguesa span {
  display: block;
  width: 24px;
  height: 2px;
  margin-inline: auto;
  border-radius: 1px;
  background-color: var(--color-light);
  transition:
    transform 300ms var(--ease-out),
    opacity 200ms var(--ease-out);
}

.hamburguesa[aria-expanded='true'] span:nth-child(1) {
  transform: translateY(7px) rotate(45deg);
}

.hamburguesa[aria-expanded='true'] span:nth-child(2) {
  opacity: 0;
}

.hamburguesa[aria-expanded='true'] span:nth-child(3) {
  transform: translateY(-7px) rotate(-45deg);
}

.hamburguesa:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
  border-radius: 8px;
}

/* ===================================================================
   Hero
   -------------------------------------------------------------------
   Composición: el titular ocupa la izquierda, el retrato del mentor
   sangra por la derecha, y el toro de neón es la única fuente de luz
   de la escena, colocado en la costura entre los dos.
   =================================================================== */

.hero {
  position: relative;
  display: flex;
  align-items: center;
  /* 85vh, no 88: el encargo quiere que el hero ocupe más pantalla y
     que se intuya que hay algo debajo. El relleno superior baja de la
     altura entera del header a 40px por encima de él —el header es
     fijo y sigue tapando sus 72px, así que restarlos del todo metería
     el distintivo por debajo. */
  min-height: 85vh;
  padding-top: calc(var(--header-h) + 40px);
  padding-bottom: var(--spacing-2xl);
  overflow: hidden;
  background-color: var(--color-surface-deep);
  isolation: isolate;
}

/* La fotografía ocupa la escena entera. El mentor queda a la derecha
   y el gráfico de velas detrás; el titular se apoya sobre la zona
   oscura de la izquierda, que en la toma original ya es casi negra. */
.hero__portrait {
  position: absolute;
  inset: 0;
  width: 100%;
  z-index: -2;
}

/* La escena entra elevándose y enfocándose, más lenta que el texto:
   dos segundos de muelle, para que la fotografía se asiente mientras
   el titular todavía se está componiendo encima. */
.hero__portrait {
  animation: hero-foto var(--dur-spring-slow) var(--ease-spring) both;
}

.hero__portrait picture,
.hero__portrait img {
  display: block;
  width: 100%;
  height: 100%;
}

.hero__portrait img {
  object-fit: cover;
  object-position: 72% 34%;
}

/* Velo que protege la lectura del titular sin apagar la escena: denso
   a la izquierda, se abre hacia la derecha para dejar ver las
   pantallas y el rostro. */
.hero__portrait::after {
  content: '';
  position: absolute;
  inset: 0;
  background:
    linear-gradient(
      to right,
      rgba(18, 18, 18, 0.94) 0%,
      rgba(18, 18, 18, 0.82) 26%,
      rgba(18, 18, 18, 0.42) 52%,
      transparent 78%
    ),
    linear-gradient(to top, var(--color-surface-deep) 0%, transparent 26%);
}

.hero__inner {
  position: relative;
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
  padding-block: var(--spacing-3xl);
}

.hero__copy {
  max-width: 660px;
}

.hero__title {
  /* 72px en escritorio, 56 en tableta, 48 en móvil. */
  font-size: var(--text-hero);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.02em;
  /* 600px es la columna que pide el encargo. A 72px caben unos 16
     caracteres por línea, así que los cortes escritos en el marcado
     siguen mandando y ninguna palabra queda sola. */
  max-width: 600px;
  margin-bottom: 32px;
}

/* Cada verso ocupa su renglón. Los cortes están escritos en el marcado
   en lugar de dejarse al reparto automático: ni `balance` ni el
   reparto voraz aciertan en las dos frases a la vez —uno parte
   "No / improvisan.", el otro parte "el mismo / proceso"—, y ninguna
   frase en naranja debe quedar cortada por la mitad. Los cuatro versos
   caben de sobra en la columna de 660px. */
.hero__title span {
  display: block;
}

/* Las palabras que llevan el peso del mensaje. Van en <em> por
   semántica —énfasis real, no color decorativo— y se les quita la
   cursiva, que aquí sobra. */
.hero__title em {
  font-style: normal;
  color: var(--color-primary);
}

.hero__sub {
  max-width: 46ch;
  font-size: var(--text-lg);
  font-weight: 400;
  line-height: var(--leading-lede);
  /* Blanco puro y no gris: va sobre una fotografía, no sobre un fondo
     plano, y ahí el gris pierde. La sombra lo despega de las zonas
     claras de la escena sin necesidad de oscurecer la imagen. */
  color: var(--color-light);
  text-shadow: 0 4px 12px rgba(0, 0, 0, 0.6);
  margin-bottom: var(--spacing-xl);
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--spacing-md);
}

/* ---- Entrada del hero ---------------------------------------------
   Va con @keyframes y no con transiciones, a propósito. Una transición
   necesita un valor previo ya pintado desde el que interpolar, y estos
   elementos cambian de estado a los ~56ms, antes del primer pintado:
   el navegador descarta la transición y el bloque aparece de golpe.
   Una animación por fotogramas clave no depende de eso, arranca sola y
   no necesita JavaScript. */

@keyframes hero-entrada {
  from {
    opacity: 0;
    filter: blur(12px);
    transform: translateY(12px);
  }
  to {
    opacity: 1;
    filter: blur(0);
    transform: none;
  }
}

@keyframes hero-foto {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@keyframes hero-haces {
  from { opacity: 0; }
  to { opacity: 0.5; }
}

.hero .eyebrow,
.hero__title span,
.hero__sub,
.hero__actions {
  animation: hero-entrada var(--dur-spring) var(--ease-spring) both;
}

/* Escalonado: 80ms entre versos del titular, con el subtítulo y los
   botones entrando cuando el titular ya se está asentando. */
.hero .eyebrow { animation-delay: 120ms; }
.hero__title span:nth-child(1) { animation-delay: 220ms; }
.hero__title span:nth-child(2) { animation-delay: 300ms; }
.hero__title span:nth-child(3) { animation-delay: 380ms; }
.hero__title span:nth-child(4) { animation-delay: 460ms; }
.hero__sub { animation-delay: 620ms; }
.hero__actions { animation-delay: 740ms; }

/* ---- Haces de luz -------------------------------------------------
   Tres degradados radiales girados -45° desde la esquina superior
   izquierda, muy tenues, que se solapan formando un haz. Aportan
   profundidad sin objeto: la escena parece iluminada desde fuera del
   encuadre. Entran con el mismo muelle, pero los últimos. */

.hero__beams {
  position: absolute;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  pointer-events: none;
  contain: strict;
  animation: hero-haces 2.4s var(--ease-out) 240ms both;
}

.hero__beam {
  position: absolute;
  top: 0;
  left: 0;
  display: block;
  height: 80rem;
  transform-origin: top left;
  rotate: -45deg;
}

.hero__beam--ancho {
  width: 35rem;
  translate: 0 -350px;
  border-radius: 50%;
  background: radial-gradient(
    68.54% 68.72% at 55.02% 31.46%,
    hsla(0, 0%, 85%, 0.08) 0,
    hsla(0, 0%, 55%, 0.02) 50%,
    hsla(0, 0%, 45%, 0) 80%
  );
}

.hero__beam--medio {
  width: 14rem;
  translate: 5% -50%;
  border-radius: 50%;
  background: radial-gradient(
    50% 50% at 50% 50%,
    hsla(0, 0%, 85%, 0.06) 0,
    hsla(0, 0%, 45%, 0.02) 80%,
    transparent 100%
  );
}

.hero__beam--fino {
  width: 14rem;
  translate: 0 -350px;
  background: radial-gradient(
    50% 50% at 50% 50%,
    hsla(0, 0%, 85%, 0.04) 0,
    hsla(0, 0%, 45%, 0.02) 80%,
    transparent 100%
  );
}

/* Grano de película: rompe el aspecto plano de los degradados CSS.
   Muy sutil a propósito — se nota si se quita, no si está. */
.hero::after,
.closing::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  opacity: 0.05;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ---- Riel de información ----------------------------------------- */

.rail {
  border-block: 1px solid var(--color-border-subtle);
  background-color: var(--color-surface-deep);
}

.rail__inner {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 80px;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* Icono arriba y texto debajo, centrado. Antes iba en fila porque las
   etiquetas son frases enteras y así se aprovechaba el ancho; con 80px
   de separación entre columnas la pila vertical respira y se lee como
   tres bloques, no como tres renglones. */
.rail__item {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 12px;
  padding: var(--spacing-xl) 0;
}

.rail__item + .rail__item {
  border-left: 1px solid var(--color-border-subtle);
}

/* El icono va en gris, no en naranja: el color de marca sigue
   reservado para los botones de compra. */
.rail__icon {
  position: relative;
  flex-shrink: 0;
  display: grid;
  place-items: center;
  /* 40px de disco, como pide el encargo. Antes eran 44 con el icono a
     21: al apilarlo sobre el texto el disco pasa a ser el ancla visual
     de la columna, así que el trazo sube a 20 para llenarlo. */
  width: 40px;
  height: 40px;
  border: 1px solid var(--color-border-subtle);
  border-radius: 50%;
  background-color: var(--color-surface-card);
  color: var(--color-text);
}

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

.rail__texto {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  min-width: 0;
}

.rail__figure {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: var(--tracking-tight);
  font-variant-numeric: tabular-nums;
  color: var(--color-light);
}

/* 13px: entre el cuerpo y lo pequeño. Es una descripción de apoyo, no
   un dato, pero tiene que leerse de un vistazo bajo la cifra. */
.rail__label {
  max-width: 22ch;
  font-size: 0.8125rem;
  line-height: 1.45;
  color: var(--color-text-muted);
}

/* Punto de emisión en directo. Es el único naranja del riel, y se lo
   gana: señala un estado real, no decora. */
.live-dot {
  position: absolute;
  top: 1px;
  right: 1px;
  width: 9px;
  height: 9px;
  border: 2px solid var(--color-surface-deep);
  border-radius: 50%;
  background-color: var(--color-primary);
  box-shadow: 0 0 0 0 rgba(255, 152, 80, 0.6);
  animation: pulse 2.4s var(--ease-out) infinite;
}

@keyframes pulse {
  70% { box-shadow: 0 0 0 10px rgba(255, 152, 80, 0); }
  100% { box-shadow: 0 0 0 0 rgba(255, 152, 80, 0); }
}

/* ---- El problema real -------------------------------------------- */

/* Toda la cabecera del diagnóstico va centrada: es una pregunta
   dirigida al lector, no un rótulo de sección. */
.problem {
  /* 80px arriba y abajo en escritorio, 70 en tableta y 60 en móvil.
     No usa `--section-y` porque el encargo fija esta sección aparte. */
  padding-block: 80px;
  text-align: center;

  /* Los filetes que separan las columnas, en una variable propia para
     poder retirarlos en móvil sin tocar cuatro reglas. El encargo pide
     0.15; se quedan en 0.12, que es donde ya estaban y es más tenue
     todavía —"ultra sutil" era la intención, y 0.15 los subiría. */
  --filete: rgba(255, 255, 255, 0.12);
}

.problem__badge {
  display: inline-block;
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--color-primary);
  padding: 7px 18px;
}

/* El ancho va en píxeles y no en `ch`: la unidad `ch` se calcula sobre
   el cuerpo del texto, y a 44px un límite de 22ch son 484px — la mitad
   de lo que necesita la segunda línea. */
.problem__title {
  max-width: 900px;
  margin-inline: auto;
  /* 72px, el mismo cuerpo que el titular del hero: esta sección es el
     diagnóstico y el encargo la quiere igual de contundente. */
  font-size: var(--text-5xl);
  line-height: 1.1;
  letter-spacing: -0.02em;
  margin-bottom: 24px;
}

.problem__title em {
  font-style: normal;
  color: var(--color-primary);
}

/* Filete bajo el titular: una línea que se desvanece hacia los
   extremos, con un punto de luz en el centro. */
.problem__division {
  display: block;
  width: min(220px, 60%);
  height: 1px;
  margin: 0 auto var(--spacing-lg);
  background: linear-gradient(90deg, transparent, var(--color-primary-acento), transparent);
  box-shadow: 0 0 12px rgba(var(--color-primary-acento-rgb), 0.5);
}

/* Es la segunda mitad del titular, no un texto de apoyo: va en el
   tono claro y a un cuerpo intermedio. En gris de párrafo se leería
   como un pie y perdería todo el golpe. */
.problem__lede {
  max-width: 62ch;
  margin-inline: auto;
  /* Blanco puro, no gris: es la frase que le dice al lector que está
     dentro del problema, y en gris se leía como una nota al pie. */
  font-size: clamp(0.9375rem, 0.37vw + 0.79rem, 1.125rem);   /* 15 · 16 · 18 */
  font-weight: 400;
  line-height: 1.6;
  letter-spacing: 0;
  color: var(--color-light);
  margin-bottom: 80px;
}

.problem__lede em {
  font-style: normal;
  color: var(--color-primary);
}

/* ===================================================================
   Las cuatro columnas del diagnóstico
   -------------------------------------------------------------------
   Sin caja, sin icono, sin fondo: solo filetes que separan. Lo único
   que sostiene la composición son las líneas y el aire, así que el
   espaciado es el diseño y no un ajuste.

   Todo lo que se anima es `transform`, `opacity` o `color`: ninguna
   propiedad dispara recálculo de maquetación.
   =================================================================== */

/* Más ancha que el resto del sitio, y por eso se sale del contenedor.
   Un `max-width` no bastaba: `.container` la recorta a 1120px, cada
   columna se queda en 196px de texto útil y los titulares se parten en
   tres líneas. El margen negativo la saca y la vuelve a centrar. */
.problem__grid {
  --ancho: min(1280px, calc(100vw - var(--gutter) * 2));

  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  column-gap: 60px;
  list-style: none;
  width: var(--ancho);
  /* El aire antes de las columnas lo pone ahora el margen del
     subtítulo, así que aquí ya no hace falta. */
  margin-block: 0;
  margin-inline: calc((100% - var(--ancho)) / 2);
  border-top: 1px solid var(--filete);
  text-align: left;
}

.problem__col {
  padding: var(--spacing-2xl) clamp(var(--spacing-md), 2.2vw, var(--spacing-2xl));
  border-left: 1px solid var(--filete);
  /* Estado de partida del revelado, más contenido que el general de la
     página: 24px y 6px de desenfoque. */
  opacity: 0;
  filter: blur(6px);
  transform: translate3d(0, 24px, 0);
}

/* El filete de la izquierda separa columnas; delante de la primera no
   hay nada que separar. */
.problem__col:first-child {
  border-left: 0;
  padding-left: 0;
}

.problem__col:last-child {
  padding-right: 0;
}

.problem__num {
  display: block;
  margin-bottom: var(--spacing-lg);
  font-family: var(--font-display);
  /* 64px y blanco al 8%: el número está, pero no se ve. Marca dónde
     empieza cada columna sin llegar a leerse. Va fuera del lector —la
     lista ordenada ya aporta el orden—, así que no le aplica el
     contraste mínimo de la norma. */
  font-size: clamp(3rem, 2.2vw + 2.02rem, 4rem);   /* 48 · 52 · 64 */
  font-weight: 200;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.03em;
  color: rgba(255, 255, 255, 0.08);
  transition: color 400ms var(--ease-out);
}

/* Medido, no elegido a ojo: por encima de 20px el titular más largo
   —"Cada pérdida cambia tu forma de operar"— se parte en tres líneas y
   las cuatro columnas dejan de leerse como un bloque. */
.problem__col h3 {
  margin-bottom: 12px;
  font-size: clamp(1.125rem, 0.46vw + 0.99rem, 1.375rem);   /* 18 · 20 · 22 */
  font-weight: 700;
  line-height: 1.24;
  letter-spacing: -0.012em;
  color: var(--color-light);
  transition: color 400ms var(--ease-out);
}

.problem__col p {
  font-size: clamp(0.875rem, 0.12vw + 0.85rem, 0.9375rem);  /* 14 · 15 */
  line-height: 1.6;
  color: var(--color-text-muted);
}

/* La raya naranja cierra cada columna. Nace corta y se estira con el
   cursor: se escala en vez de cambiar de ancho, que recalcularía la
   maquetación por un adorno de dos píxeles. */
.problem__raya {
  display: block;
  width: 48px;
  height: 2px;
  margin-top: var(--spacing-xl);
  border-radius: 1px;
  background-color: var(--color-primary-acento);
  transform: scaleX(0.54);
  transform-origin: left center;
  transition: transform 450ms var(--ease-out);
}

/* ---- Con el cursor encima ---------------------------------------
   Muy poco, a propósito: esta composición vive de la quietud. La raya
   se completa, la cifra se enciende y el titular pasa a blanco puro.
   Nada se mueve de sitio. */

@media (hover: hover) and (pointer: fine) {
  .problem__col:hover .problem__raya {
    transform: scaleX(1);
    transition-duration: 350ms;
  }

  .problem__col:hover .problem__num {
    color: var(--color-primary);
    transition-duration: 300ms;
  }

  .problem__col:hover h3 {
    color: var(--color-light);
    transition-duration: 300ms;
  }
}

/* ---- Las columnas en pantallas menores ---------------------------
   A cuatro columnas el texto se estrangula mucho antes de llegar al
   móvil: a 1000px cada una baja de 200px y los titulares se parten en
   cuatro líneas. Se pasa a dos columnas, y a una en vertical. */

@media (max-width: 1023px) {
  .problem { padding-block: 70px; }

  .problem__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: 50px;
  }

  /* Con dos columnas, el filete izquierdo sobra en la primera de cada
     fila, no solo en la primera de todas. */
  .problem__col:nth-child(odd) {
    border-left: 0;
    padding-left: 0;
  }

  .problem__col:nth-child(even) {
    padding-right: 0;
  }

  /* La segunda fila necesita su propia línea superior. */
  .problem__col:nth-child(n + 3) {
    border-top: 1px solid var(--filete);
  }
}

@media (max-width: 767px) {
  .problem {
    padding-block: 60px;
    /* Sin filetes: en una sola columna no separan nada que el aire no
       separe ya, y a este tamaño solo añaden ruido. */
    --filete: transparent;
  }

  .problem__lede { margin-bottom: 48px; }

  .problem__grid {
    grid-template-columns: minmax(0, 1fr);
    row-gap: 40px;
    margin-top: 0;
    border-top: 0;
  }

  .problem__col {
    padding: var(--spacing-xl) 0;
    border-left: 0;
    border-top: 1px solid var(--filete);
  }

  .problem__col:first-child {
    border-top: 0;
  }

  /* Los cuatro números suben del 8% al 22% de blanco. Solo aquí: en
     escritorio se quedan como estaban.

     En horizontal el número comparte fila con sus tres hermanos y los
     filetes que separan las columnas, así que se entiende de qué es
     aunque apenas se vea. En vertical va solo sobre negro, sin nada
     alrededor, y al 8% se compone en un gris de 44 sobre 255: en una
     pantalla al sol desaparece. Al 22% queda en 76, visible como marca
     de posición y todavía muy por debajo del titular en blanco puro. */
  .problem__num {
    margin-bottom: var(--spacing-md);
    color: rgba(255, 255, 255, 0.22);
  }
}

/* ---- Cierre del diagnóstico -------------------------------------
   Sin recuadro y en blanco puro. Tras cuatro tarjetas con borde, halo
   e icono, quitarle el marco es lo que hace que esta frase destaque:
   pasa a ser la única voz sin envoltorio de toda la sección. */

/* Mismo tratamiento tipográfico que el texto de entrada de la sección:
   idéntica familia, cuerpo, peso, interlínea y medida de 62ch. Comparten
   ancho a propósito, porque es lo que hace que los dos bloques se lean
   como parte del mismo sistema y no como dos piezas sueltas.

   Lo único que cambia es el color: blanco en lugar de gris. Abre y
   cierra el diagnóstico con la misma voz, y el tono más claro marca
   cuál de las dos es la conclusión. */
/* ---- El cierre, en tres alturas ----------------------------------
   Dos líneas pequeñas que preparan y una grande que remata. La
   jerarquía es el mensaje: lo que estaba en un párrafo plano ahora
   se lee como una cuenta atrás hacia la frase que vende. */

/* 80px de aire por arriba, el mismo que separa el subtítulo de las
   columnas: sin él el cierre arranca pegado a los filetes y se lee
   como una quinta columna en vez de como el remate de la sección. */
.problem__cierre {
  max-width: 900px;
  margin: 80px auto 0;
  text-wrap: balance;
}

.problem__cierre span {
  display: block;
}

.problem__cierre-uno {
  font-size: var(--text-sm);
  line-height: 1.6;
  color: var(--color-text-faint);
}

/* El puente va un punto por debajo de la primera: es la línea que
   menos pesa de la sección. El encargo pedía var(--color-text-min), que da 3.0:1 y
   se cae de AA.

   El alfa está medido, no elegido a ojo: con 0.8 se queda en 4.38:1 y
   sigue suspendiendo por poco; con 0.85 llega a 4.91:1 y el escalón
   respecto a la línea de arriba se sigue viendo igual. */
.problem__cierre-puente {
  margin-top: 6px;
  font-size: var(--text-sm);
  line-height: 1.6;
  color: rgba(153, 153, 153, 0.85);
}

.problem__cierre-remate {
  margin-top: 32px;
  font-family: var(--font-display);
  font-size: clamp(2rem, 1.85vw + 1.33rem, 3rem);   /* 32 · 38 · 48 */
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -0.025em;
  color: var(--color-light);
}

.problem__cierre-remate em {
  font-style: normal;
  color: var(--color-primary);
}

/* Flecha de continuidad. Es un enlace real a la sección siguiente, no
   un adorno: quien la pulsa espera avanzar. */
.problem__seguir {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  margin: var(--spacing-xl) auto 0;
  border-radius: 50%;
  color: var(--color-primary);
  transition: transform var(--dur) var(--ease-out),
    background-color var(--dur) var(--ease-out);
}

.problem__seguir svg {
  width: 22px;
  height: 22px;
  animation: latido-flecha 2.6s var(--ease-in-out) infinite;
}

.problem__seguir:hover {
  background-color: rgba(var(--color-primary-acento-rgb), 0.1);
  transform: translateY(2px);
}

@keyframes latido-flecha {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(4px); }
}

/* ===================================================================
   El proceso
   -------------------------------------------------------------------
   Recorrido de scroll con panel anclado. La columna izquierda son los
   cuatro pasos, que hacen de contenido y a la vez de recorrido: su
   altura define cuánto scroll dura cada paso. La derecha es un panel
   anclado donde las cuatro ilustraciones se relevan.

   El avance del carril lo escribe el JS en `--avance` (0 a 1) y aquí
   solo se consume con `transform`, para no tocar la maquetación.
   =================================================================== */

/* Sin `overflow: hidden`, a propósito. Recortar aquí convertiría a la
   sección en el contenedor de desplazamiento del panel anclado, y un
   contenedor que no se desplaza anula el anclaje por completo: el panel
   se quedaba pegado arriba de la sección en lugar de acompañar al
   scroll. Nada desborda horizontalmente, así que el recorte sobra. */
.proceso {
  position: relative;
  /* 80 / 70 / 60, la escalera del encargo. */
  padding-block: 80px;
  background-color: var(--color-surface-deep);
  border-block: 1px solid var(--color-border-subtle);
}

.proceso__cabecera {
  text-align: center;
  margin-bottom: 0;
}

.proceso__badge {
  display: inline-block;
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--color-primary);
  padding: 7px 18px;
}

.proceso__title {
  /* Sin tope propio: los cuatro verbos van en un solo renglón y para
     eso necesitan el ancho entero de la columna. Con 880px pedían
     1093px a 72px y se partían por "Repite.", que es justo lo que
     rompe la lectura de ciclo. */
  max-width: none;
  margin-inline: auto;
  /* 72px, el mismo cuerpo que el hero y el diagnóstico. */
  font-size: var(--text-5xl);
  line-height: 1.1;
  /* -0.045em, no -0.02: a 72px el interletraje normal sobra, y aquí
     además es lo que hace entrar la frase en los 1040px de la columna.
     A cuerpos así, apretar es lo correcto tipográficamente. */
  letter-spacing: -0.045em;
  margin-bottom: 0;
  /* Los puntos separan cuatro órdenes; que no se parta una palabra. */
  hyphens: none;
  /* Donde no quepa en un renglón —por debajo de 860px—, que se parta en
     mitades iguales: "Analiza. Ejecuta." y "Corrige. Repite." se siguen
     leyendo como un ciclo de dos tiempos. Sin esto quedaba una línea
     larga y una corta. */
  text-wrap: balance;
}

/* A 360px, 48px daban tres renglones y la frase se deshacía. 42 es el
   cuerpo justo para que quepa en dos. Solo aquí: por encima de 430px la
   escala general ya reparte bien. */
@media (max-width: 430px) {
  .proceso__title { font-size: clamp(2.375rem, 3.7vw + 1.63rem, 2.625rem); }
}

.proceso__title em {
  font-style: normal;
  color: var(--color-primary);
}

/* El renglón de prueba social: cuerpo de texto, no de titular. A 18px
   y en blanco se lee como la continuación de la frase de arriba, que es
   lo que es, sin competir con los cuatro verbos. */
.proceso__sub {
  max-width: 46ch;
  margin: 24px auto 0;
  font-size: var(--text-lg);
  font-weight: 400;
  line-height: 1.5;
  color: var(--color-light);
}

.proceso__sub em {
  font-style: normal;
  color: var(--color-primary);
}

.proceso__lede {
  max-width: 58ch;
  /* 24px del subtítulo, 80 hasta el carril: la cabecera se lee como un
     bloque y el proceso empieza claramente después. */
  margin: 24px auto 80px;
  /* 14px y gris: es la aclaración, y por debajo del subtítulo en la
     jerarquía. El blanco los dejaba a los dos al mismo nivel. */
  font-size: var(--text-sm);
  line-height: 1.6;
  color: var(--color-text-muted);
}

/* ===================================================================
   El escenario de pestañas
   -------------------------------------------------------------------
   Los cuatro pasos se eligen pulsando su rótulo, y además avanzan solos
   cada cinco segundos. Antes se recorrían bajando 500vh; el cambio
   ahorra cinco pantallas de scroll sin tocar nada del lenguaje visual.

   El paso activo lo escribe el JS en `--avance` y en una clase, y aquí
   solo se consume con `transform` y `opacity`. Nada obliga a recalcular
   la maquetación.
   =================================================================== */

/* El degradado se queda; el parallax no. Dependía del recorrido de
   scroll, y sin recorrido no tiene de qué depender. */
.proc__fondo {
  position: absolute;
  inset: -10% 0;
  z-index: 0;
  pointer-events: none;
  background: radial-gradient(
    58% 42% at 68% 38%,
    rgba(var(--color-primary-acento-rgb), 0.09) 0%,
    rgba(var(--color-primary-acento-rgb), 0.03) 42%,
    transparent 72%
  );
}

/* Bloque normal, no anclado: la sección mide lo que mide su contenido.
   El recorrido de 500vh se sustituyó por pestañas y ya no hay nada que
   anclar. */
.proc__escenario {
  position: relative;
  display: flex;
  align-items: center;
  padding-block: var(--spacing-2xl);
  overflow: hidden;
}

.proc__grid {
  display: grid;
  /* Barra lateral de 180px fija, no proporcional: el encargo la fija y
     así los cuatro rótulos ocupan siempre lo mismo, con la tarjeta
     quedándose todo lo que sobra. */
  grid-template-columns: 180px minmax(0, 1fr);
  /* `stretch`, no `center`. Con la tarjeta a 450px de alto mínimo, un
     carril centrado dejaba un hueco vacío arriba y otro abajo y las dos
     columnas no se leían como una rejilla. Estirado, los cuatro nodos
     se reparten a lo largo —ya llevan `space-between`— y el riel cubre
     la altura entera. */
  align-items: stretch;
  column-gap: 60px;
  width: 100%;
}

/* ---- Carril ------------------------------------------------------ */

/* Geometría del carril, en una sola variable para que el riel y los
   discos no puedan despegarse: el riel se centra en `--eje` y cada
   disco se posiciona contra su nodo para caer justo encima. */
.proc__carril {
  --eje: 22px;
  --disco: 44px;
  position: relative;
  padding-left: 68px;
  padding-block: var(--spacing-md);
}

.proc__riel {
  position: absolute;
  top: 0;
  bottom: 0;
  left: calc(var(--eje) - 1px);
  width: 2px;
  border-radius: 1px;
  /* 0.2, no 0.5: la línea sostiene la composición, no la anuncia. */
  background-color: rgba(255, 255, 255, 0.2);
}

/* La línea naranja es a la vez indicador de posición y cuenta atrás.

   Mientras el paso automático corre, avanza del nodo actual al
   siguiente a lo largo de los cinco segundos: cuando toca el nodo de
   abajo, el paso cambia. Conserva el gesto del recorrido original —una
   línea que crece— pero atada al reloj en vez de al scroll.

   Con el automático apagado no hay cuenta atrás que enseñar, así que
   se planta en el paso elegido con la misma transición de 600ms del
   relevo de la tarjeta. */
.proc__avance {
  position: absolute;
  inset: 0;
  border-radius: 1px;
  background: linear-gradient(180deg, var(--color-primary-acento), #ffb37d);
  transform: scaleY(var(--avance, 0.25));
  transform-origin: top;
  transition: transform 600ms var(--ease-out);
  will-change: transform;
}

.proc__escenario.esta-contando .proc__avance {
  animation: proc-cuenta 5000ms linear forwards;
  transition: none;
}

.proc__escenario.esta-en-pausa .proc__avance {
  animation-play-state: paused;
}

@keyframes proc-cuenta {
  from { transform: scaleY(var(--desde, 0)); }
  to   { transform: scaleY(var(--avance, 0.25)); }
}

.proc__nodos {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: var(--spacing-2xl);
  list-style: none;
  flex: 1;
}

/* En vertical los cuatro pasos van en fila y por debajo de ~360px el
   cuarto se sale. Se alcanza desplazando, pero nada lo decía: la fila
   parecía terminar en "Corrige".

   La máscara desvanece el borde solo cuando hay algo detrás. Se apoya
   en `animation-timeline: scroll()`, así que donde no exista se queda
   el degradado fijo: se pierde el matiz de que desaparezca al llegar
   al final, no la pista de que hay más. */
@supports (animation-timeline: scroll()) {
  .proc__nodos {
    animation: proc-borde linear both;
    animation-timeline: scroll(self inline);
  }
}

@keyframes proc-borde {
  /* Al principio del recorrido solo se desvanece la derecha; al final,
     solo la izquierda. */
  from {
    mask-image: linear-gradient(to right, #000 80%, transparent 100%);
  }
  to {
    mask-image: linear-gradient(to right, transparent 0%, #000 20%);
  }
}

.proc__nodo {
  position: relative;
}

/* El rótulo es un botón de verdad, pero no debe parecerlo: sin fondo,
   sin borde y sin relleno. Lo único que dice que se puede pulsar es
   que el cursor cambia y que al pasar por encima se aclara. */
.proc__pestana {
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  text-align: left;
  cursor: pointer;
  /* Ya no se atenúa el botón entero. Antes un solo `opacity` bajaba a
     la vez la cifra y el rótulo; ahora cada uno lleva su color, que es
     lo que permite que la cifra baje al 10% y el rótulo se quede en un
     gris legible. */
}

.proc__nodo.is-activo .proc__pestana {
  opacity: 1;
}

@media (hover: hover) and (pointer: fine) {
  .proc__pestana:hover { opacity: 0.72; }
  .proc__nodo.is-activo .proc__pestana:hover { opacity: 1; }
}

.proc__pestana:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 6px;
  border-radius: 8px;
  opacity: 1;
}

/* Disco de cristal. Se enciende solo el del paso activo; los demás se
   quedan en gris. */
.proc__disco {
  position: absolute;
  top: 50%;
  /* Centro del disco justo sobre el eje del riel. */
  left: calc(var(--eje) - 68px - var(--disco) / 2);
  width: 16px;
  height: 16px;
  margin-top: -8px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 50%;
  background-color: var(--color-gris-medio);
  transition:
    width 300ms var(--ease-out),
    height 300ms var(--ease-out),
    margin-top 300ms var(--ease-out),
    left 300ms var(--ease-out),
    background-color 300ms var(--ease-out),
    border-color 300ms var(--ease-out),
    box-shadow 300ms var(--ease-out);
}

.proc__nodo.is-activo .proc__disco {
  width: 28px;
  height: 28px;
  margin-top: -14px;
  left: calc(var(--eje) - 68px - 14px);
  border-color: rgba(var(--color-primary-acento-rgb), 0.6);
  background-color: var(--color-primary);
  box-shadow: 0 4px 12px rgba(255, 157, 89, 0.3);
}

.proc__cifra {
  display: block;
  margin-bottom: 4px;
  font-family: var(--font-display);
  /* 32px y blanco al 10%: está, pero no se ve. Marca el arranque de
     cada rótulo sin competir con él. Va con `aria-hidden`, así que no
     le aplica el contraste mínimo. */
  font-size: clamp(1.5rem, 0.74vw + 1.334rem, 2rem);   /* 24 · 28 · 32 */
  font-weight: 300;
  line-height: 1;
  letter-spacing: -0.02em;
  color: rgba(255, 255, 255, 0.1);
  transition: color 200ms var(--ease-out);
}

/* La cifra NO se enciende al activarse. Si pasara a naranja dejaría
   de ser "casi invisible", que es justo el efecto que pide el
   encargo. El estado ya lo dicen el disco —28px, naranja y con
   sombra— y el rótulo, que pasa de gris a blanco. */

.proc__rotulo {
  display: block;
  font-family: var(--font-display);
  /* 18 · 20 · 22 */
  font-size: clamp(1.125rem, 0.46vw + 0.99rem, 1.375rem);
  font-weight: 700;
  letter-spacing: var(--tracking-tight);
  text-transform: uppercase;
  /* El encargo pide var(--color-text-min) para el rótulo en reposo. Da 3.0:1 y estos
     rótulos son botones con texto, no decoración: se queda en var(--color-text-faint),
     que da 6.1:1 y sigue leyéndose como claramente secundario frente
     al blanco del activo. */
  color: var(--color-text-faint);
  transition: color 200ms var(--ease-out);
}

.proc__nodo.is-activo .proc__rotulo {
  color: var(--color-light);
}

@media (hover: hover) and (pointer: fine) {
  .proc__pestana:hover .proc__rotulo { color: var(--color-text-muted); }
  .proc__nodo.is-activo .proc__pestana:hover .proc__rotulo { color: var(--color-light); }
}

/* ---- Pausa del paso automático -----------------------------------
   Algo que se mueve solo cada cinco segundos tiene que poder pararse,
   y el cursor no sirve en una pantalla táctil. Mismo botón discreto
   que lleva la galería de testimonios.

   Desaparece en cuanto el visitante pulsa un paso: a partir de ahí no
   hay nada corriendo que pausar. */

.proc__reloj {
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  margin-top: var(--spacing-xl);
  margin-left: 4px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background-color: transparent;
  color: var(--color-text-muted);
  cursor: pointer;
  opacity: 0.55;
  transition: opacity 300ms var(--ease-out);
}

.proc__reloj:hover,
.proc__reloj:focus-visible { opacity: 1; }

.proc__reloj:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 3px;
}

.proc__reloj[hidden] { display: none; }

.proc__icono {
  width: 18px;
  height: 18px;
  fill: currentColor;
}

.proc__icono--play { display: none; }
.proc__escenario.esta-en-pausa .proc__icono--pausa { display: none; }
.proc__escenario.esta-en-pausa .proc__icono--play { display: block; }

/* ---- La tarjeta que se transforma --------------------------------
   Las cuatro ocupan el mismo hueco. La entrante gana opacidad, escala
   y foco; la saliente los pierde. 600ms, como pide el encargo. */

/* Las cuatro se apilan en la misma celda de una rejilla. Con posición
   absoluta el contenedor no podía medirlas y había que darle un alto
   fijo, que en vertical dejaba la tarjeta sin altura; así se ajusta
   solo a la más alta de las cuatro y ninguna encoge al relevarse. */
.proc__pasos {
  display: grid;
  list-style: none;
}

.proc__paso {
  grid-area: 1 / 1;
  display: flex;
  flex-direction: column;
  gap: var(--spacing-lg);
  /* 40 de relleno y 450 de alto mínimo: el encargo pide una tarjeta
     más generosa, y con el título a 36px hace falta. */
  padding: 40px;
  min-height: 450px;
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 16px;
  background-color: rgba(255, 255, 255, 0.03);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  box-shadow:
    0 2px 6px rgba(0, 0, 0, 0.36),
    0 30px 70px rgba(0, 0, 0, 0.5);
  opacity: 0;
  transform: scale(0.965);
  filter: blur(8px);
  pointer-events: none;
  transition:
    opacity 600ms var(--ease-out),
    transform 600ms var(--ease-out),
    filter 600ms var(--ease-out),
    border-color 600ms var(--ease-out),
    box-shadow 600ms var(--ease-out);
}

.proc__paso.is-activo {
  opacity: 1;
  transform: none;
  filter: none;
  pointer-events: auto;
  border-color: rgba(var(--color-primary-acento-rgb), 0.26);
  box-shadow:
    0 2px 6px rgba(0, 0, 0, 0.36),
    0 34px 80px rgba(0, 0, 0, 0.55),
    0 0 44px rgba(var(--color-primary-acento-rgb), 0.07);
}

.proc__paso-num {
  font-size: var(--text-sm);
  font-weight: 700;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--color-primary);
  margin-bottom: 16px;
}

.proc__paso-titulo {
  /* 28 · 32 · 36 */
  font-size: clamp(1.75rem, 0.74vw + 1.584rem, 2.25rem);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: var(--tracking-tight);
  text-transform: uppercase;
  color: var(--color-light);
  margin-block: 0 20px;
}

.proc__paso-cuerpo {
  max-width: 52ch;
  font-size: clamp(0.9375rem, 0.19vw + 0.9rem, 1rem);   /* 15 · 16 */
  line-height: 1.6;
  color: var(--color-text-muted);
  margin-bottom: 32px;
}

/* ---- Cristal: reflejo y luz que sigue al cursor ------------------
   Mismo sistema ya medido en las tarjetas del diagnóstico. */

.proc__cristal {
  position: absolute;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  border-radius: inherit;
  pointer-events: none;
}

.proc__lume {
  position: absolute;
  inset: -30%;
  background: radial-gradient(
    40% 40% at 50% 42%,
    rgba(255, 255, 255, 0.06) 0%,
    rgba(var(--color-primary-acento-rgb), 0.045) 45%,
    transparent 72%
  );
  opacity: 0;
  transform: translate3d(var(--lx, 0), var(--ly, 0), 0);
  transition: opacity 450ms var(--ease-out), transform 600ms var(--ease-out);
}

.proc__paso.is-activo .proc__lume {
  opacity: 1;
}

.proc__reflejo {
  position: absolute;
  top: -60%;
  left: 0;
  width: 140px;
  height: 220%;
  background: linear-gradient(
    90deg, transparent 0%, rgba(255, 255, 255, 0.1) 50%, transparent 100%
  );
  filter: blur(7px);
  opacity: 0;
  transform: translate3d(-150px, 0, 0) rotate(18deg);
  pointer-events: none;
}

.proc__paso.is-reflejo .proc__reflejo {
  animation: proc-reflejo 700ms ease-out forwards;
}

@keyframes proc-reflejo {
  0%   { opacity: 0; transform: translate3d(-150px, 0, 0) rotate(18deg); }
  14%  { opacity: 1; }
  86%  { opacity: 1; }
  100% { opacity: 0; transform: translate3d(var(--recorrido, 320px), 0, 0) rotate(18deg); }
}

/* ---- La visual de cada paso -------------------------------------- */

.proc__visual {
  flex: 1;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* 01 · Gráfico */

.pv-grafico {
  width: 100%;
  height: 100%;
}

.pv-rejilla line {
  stroke: rgba(255, 255, 255, 0.05);
  stroke-width: 1;
}

.pv-zona rect {
  fill: rgba(var(--color-primary-acento-rgb), 0.07);
  stroke: rgba(var(--color-primary-acento-rgb), 0.28);
  stroke-dasharray: 4 4;
  transition: fill 350ms var(--ease-out), stroke 350ms var(--ease-out);
}

.pv-zona text {
  fill: rgba(var(--color-primary-acento-rgb), 0.75);
  font-family: var(--font-body);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

/* Las zonas reaccionan al cursor, como pide el encargo. */
.pv-zona:hover rect {
  fill: rgba(var(--color-primary-acento-rgb), 0.13);
  stroke: rgba(var(--color-primary-acento-rgb), 0.5);
}

.pv-velas line { stroke: var(--color-text-faint); stroke-width: 1.6; }
.pv-velas rect { fill: var(--color-surface-elevated); stroke: var(--color-text-muted); stroke-width: 1.6; rx: 2; }
.pv-velas .pv-baja line { stroke: rgba(var(--color-primary-acento-rgb), 0.7); }
.pv-velas .pv-baja rect { fill: rgba(var(--color-primary-acento-rgb), 0.14); stroke: rgba(var(--color-primary-acento-rgb), 0.75); }

/* 02 · Panel de orden */

.pv-orden {
  width: 100%;
  max-width: 420px;
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.pv-lados {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 4px;
  margin-bottom: var(--spacing-sm);
}

.pv-lado {
  /* 48px de alto: el encargo los quiere del tamaño de un control real,
     no de una etiqueta. */
  display: grid;
  place-items: center;
  min-height: 48px;
  padding: 16px 11px;
  border: 1.5px solid transparent;
  border-radius: var(--radius-md);
  background-color: rgba(255, 255, 255, 0.03);
  font-size: var(--text-sm);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-align: center;
  color: var(--color-text-faint);
  transition:
    background-color 300ms var(--ease-out),
    border-color 300ms var(--ease-out),
    color 300ms var(--ease-out);
}

/* El lado en el que se está operando. #d87c3b es el naranja apagado
   que pide el encargo: la ficha es un dibujo, no un botón, y con el
   naranja de marca competiría con el CTA de verdad de la sección. */
.pv-lado--activo {
  border-color: rgba(216, 124, 59, 0.5);
  background-color: rgba(216, 124, 59, 0.16);
  color: #e8a273;
}

.pv-fila {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--spacing-md);
  /* 18px entre filas: el encargo pide que respiren más. Se consigue
     con el relleno vertical, que además engorda la fila y hace que el
     valor de 18px no quede pegado al borde. */
  padding: 18px var(--spacing-md);
  border-radius: var(--radius-md);
  background-color: rgba(255, 255, 255, 0.028);
  /* 13px la etiqueta */
  font-size: 0.8125rem;
  color: var(--color-text-faint);
}

/* 18px el valor: es el dato, y tiene que pesar más que su nombre. */
.pv-fila b {
  font-family: var(--font-display);
  font-size: 1.125rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--color-light);
}

.pv-fila--riesgo b { color: var(--color-primary); }

.pv-rr {
  display: flex;
  align-items: center;
  gap: var(--spacing-md);
  margin-top: var(--spacing-sm);
}

.pv-rr-barra {
  flex: 1;
  height: 4px;
  border-radius: 2px;
  background-color: rgba(255, 255, 255, 0.07);
  overflow: hidden;
}

.pv-rr-barra i {
  display: block;
  width: 25%;
  height: 100%;
  border-radius: 2px;
  background-color: var(--color-primary-acento);
}

.pv-rr-texto {
  font-size: var(--text-xs);
  color: var(--color-text-faint);
}

/* 03 · Revisión */

/* La lista y la nota se apilan: en fila la nota estrangula ambas columnas. */
.proc__visual--revision {
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.pv-revision {
  width: 100%;
  max-width: 460px;
  display: flex;
  flex-direction: column;
  gap: 3px;
  list-style: none;
}

.pv-revision li {
  display: flex;
  align-items: center;
  gap: var(--spacing-sm);
  padding: 12px var(--spacing-md);
  border-radius: var(--radius-md);
  background-color: rgba(255, 255, 255, 0.028);
  font-size: var(--text-sm);
  color: var(--color-text);
}

.pv-revision em {
  margin-left: auto;
  padding-left: var(--spacing-sm);
  flex-shrink: 0;
  white-space: nowrap;
  font-style: normal;
  font-size: var(--text-xs);
  color: var(--color-text-faint);
}

.pv-check {
  position: relative;
  flex-shrink: 0;
  width: 17px;
  height: 17px;
  border-radius: 50%;
  background-color: rgba(var(--color-primary-acento-rgb), 0.16);
}

.pv-check::after {
  content: '';
  position: absolute;
  top: 4px;
  left: 6px;
  width: 4px;
  height: 8px;
  border: solid var(--color-primary-acento);
  border-width: 0 1.6px 1.6px 0;
  transform: rotate(45deg);
}

.pv-check--pendiente {
  background-color: rgba(255, 255, 255, 0.08);
}

.pv-check--pendiente::after {
  top: 7px;
  left: 5px;
  width: 7px;
  height: 0;
  border-width: 0 0 1.6px 0;
  border-color: var(--color-text-faint);
  transform: none;
}

.pv-nota {
  width: 100%;
  max-width: 460px;
  margin-top: var(--spacing-md);
  padding: var(--spacing-md);
  border-left: 2px solid rgba(var(--color-primary-acento-rgb), 0.5);
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

.pv-nota span {
  display: block;
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--color-text-faint);
  margin-bottom: 4px;
}

/* 04 · El infinito */

.proc__visual--ciclo { padding-block: var(--spacing-lg); }

.pv-infinito {
  width: min(300px, 80%);
  height: auto;
}

.pv-infinito path {
  fill: none;
  stroke: var(--color-primary-acento);
  stroke-width: 2.5;
  stroke-linecap: round;
  filter: drop-shadow(0 0 14px rgba(var(--color-primary-acento-rgb), 0.45));
}

.proc__paso.is-activo .pv-infinito {
  animation: proc-respira 7s var(--ease-in-out) infinite;
}

@keyframes proc-respira {
  0%, 100% { transform: scale(1); opacity: 0.88; }
  50%      { transform: scale(1.045); opacity: 1; }
}

/* ---- Cierre: el carril se convierte en infinito ------------------ */

.proceso__cierre {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding-inline: var(--gutter);
}

/* La cola es un único trazo: baja recta y se cierra en lemniscata. Al
   dibujarse con `stroke-dashoffset`, la línea no "salta" al infinito
   — sigue siendo la misma línea, que termina anudándose.

   Va centrada, no alineada al carril de la izquierda. Es deliberado:
   el cierre está centrado, y hacer que la línea derive hacia el centro
   lleva la mirada justo donde está la frase final. Alinearla al carril
   obligaría además a sacarla fuera de la pantalla en móviles. */
.proceso__cola {
  width: 150px;
  height: 238px;
  margin-bottom: var(--spacing-2xl);
  /* Respiración: una vez trazado, el símbolo late muy despacio. Es lo
     que lo mantiene vivo mientras se lee la frase, sin pedir atención. */
  animation: respira 7s var(--ease-in-out) infinite;
}

@keyframes respira {
  0%, 100% { transform: scale(1); opacity: 0.9; }
  50%      { transform: scale(1.045); opacity: 1; }
}

.proceso__trazo {
  stroke: var(--color-primary-acento);
  stroke-width: 2;
  stroke-linecap: round;
  fill: none;
  stroke-dasharray: var(--largo, 420);
  stroke-dashoffset: calc(var(--largo, 420) * (1 - var(--avance-cola, 0)));
}

.proceso__nota {
  font-size: var(--text-sm);
  color: var(--color-text-faint);
  margin-bottom: var(--spacing-lg);
}

.proceso__refran {
  max-width: 900px;
  font-family: var(--font-display);
  font-size: var(--text-3xl);
  font-weight: 700;
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
  color: var(--color-text);
  margin-bottom: var(--spacing-2xl);
}

.proceso__refran span {
  display: block;
}

.proceso__refran em {
  font-style: normal;
  color: var(--color-primary);
}

.proceso__cta {
  align-self: center;
}


/* ---- El proceso en vertical --------------------------------------
   Las consultas de medios de esta sección van aquí, junto a sus reglas
   base, y no en el bloque general del final del archivo: son muchas y
   muy acopladas, y separarlas 800 líneas las volvería imposibles de
   mantener sin romper algo.

   Las pestañas se mantienen en vertical, que es justo donde más se
   nota el ahorro de scroll: los cuatro rótulos pasan a una fila
   horizontal encima de la tarjeta, con la línea naranja tumbada
   debajo. */

/* El corte sube de 860 a 1023: el encargo quiere el contenedor en
   columna ya en tableta, y con el carril todavía vertical una barra de
   180px alineada a la izquierda sobre una tarjeta ancha se lee como un
   hueco, no como una navegación. Tableta y móvil comparten patrón. */
@media (max-width: 1023px) {
  .proceso { padding-block: 70px; }

  .proc__escenario {
    padding-block: var(--spacing-md);
  }

  /* `minmax(0, 1fr)` y no `1fr`: el mínimo implícito de una columna de
     rejilla es `auto`, y con él el carril se niega a encoger por debajo
     del ancho de sus cuatro rótulos y se sale de la pantalla a 360px. */
  .proc__grid {
    grid-template-columns: minmax(0, 1fr);
    row-gap: 50px;
  }

  /* El carril se tumba: los discos desaparecen —a este tamaño no
     caben junto al rótulo— y el riel pasa a ser una línea horizontal
     bajo la fila. */
  .proc__carril {
    --eje: 0px;
    --disco: 0px;
    display: flex;
    align-items: center;
    gap: var(--spacing-md);
    padding-left: 0;
    padding-block: 0 var(--spacing-md);
  }

  .proc__riel {
    top: auto;
    bottom: 0;
    left: 0;
    right: 0;
    width: auto;
    height: 2px;
  }

  /* Tumbada, la línea crece a lo ancho. */
  .proc__avance {
    transform: scaleX(var(--avance, 0.25));
    transform-origin: left;
  }

  @keyframes proc-cuenta {
    from { transform: scaleX(var(--desde, 0)); }
    to   { transform: scaleX(var(--avance, 0.25)); }
  }

  /* Si los cuatro rótulos no caben, la fila se desplaza a lo ancho y
     el JS trae el activo a la vista. Sin barra: es navegación de
     cuatro elementos, no una lista larga. */
  /* `min-width: 0` no es opcional: sin él la fila se niega a encoger
     por debajo del ancho de sus cuatro rótulos y desborda el carril
     entero a 360px, en vez de desplazarse por dentro. */
  .proc__nodos {
    flex: 1 1 auto;
    min-width: 0;
    flex-direction: row;
    justify-content: flex-start;
    gap: var(--spacing-lg);
    overflow-x: auto;
    scrollbar-width: none;
    padding-bottom: var(--spacing-md);
  }

  .proc__nodos::-webkit-scrollbar { display: none; }

  .proc__nodo {
    flex: 0 0 auto;
  }

  .proc__disco {
    display: none;
  }

  .proc__cifra {
    margin-bottom: 0;
  }

  /* El rótulo no baja a 16px: el encargo lo quiere en 20 en tableta
     y 18 en móvil, y el clamp de la regla base ya da esa escalera. */
  .proc__rotulo {
    font-size: clamp(1.125rem, 0.46vw + 0.99rem, 1.25rem);
  }

  .proc__reloj {
    flex: 0 0 auto;
    margin: 0;
  }

  .proc__paso {
    padding: var(--spacing-xl);
  }

  .proc__visual {
    min-height: 200px;
  }
}

@media (max-width: 640px) {
  .proc__paso {
    padding: var(--spacing-lg);
  }

  /* 28px, que es lo que pide el encargo para móvil. */
  .proc__paso-titulo {
    font-size: 1.75rem;
  }

  .proc__nodos {
    gap: var(--spacing-md);
  }
}

/* ---- El proceso sin movimiento -----------------------------------
   Sin reloj no hay recorrido, y unas pestañas dejarían tres cuartas
   partes del contenido detrás de un gesto. Se apilan las cuatro
   tarjetas en flujo, todas legibles. */

@media (prefers-reduced-motion: reduce) {
  .proc__escenario {
    display: block;
    overflow: visible;
  }

  .proc__grid {
    grid-template-columns: 1fr;
    row-gap: var(--spacing-2xl);
  }

  /* La navegación sobra si todo está a la vista. */
  .proc__carril {
    display: none;
  }

  .proc__pasos {
    display: flex;
    flex-direction: column;
    gap: var(--spacing-lg);
  }

  /* Fuera de la celda compartida: las cuatro en flujo, una debajo de
     otra. */
  .proc__paso {
    grid-area: auto;
    opacity: 1;
    transform: none;
    filter: none;
    pointer-events: auto;
    padding: var(--spacing-xl);
    border-color: rgba(255, 255, 255, 0.08);
  }

  .proc__paso .proc__lume { opacity: 0; }

  .proceso__trazo { stroke-dashoffset: 0; }
}


/* ---- Resultados: el muro ----------------------------------------- */

.results {
  /* 80 / 70 / 60, la escalera del encargo. */
  padding-block: 80px;
  background-color: var(--color-surface-deep);
  border-block: 1px solid var(--color-border-subtle);
}

/* ---- Cabecera ---------------------------------------------------- */

.results__cabecera {
  text-align: center;
  /* El aire lo pone ahora el margen del subtítulo, que es donde el
     encargo lo mide: 80px entre el texto y el carrusel. */
  margin-bottom: 0;
}

.results__badge {
  display: inline-block;
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--color-primary);
  padding: 7px 18px;
}

.results__title {
  max-width: 900px;
  margin-inline: auto;
  /* 72px, el mismo cuerpo que el hero, el diagnóstico y el proceso. */
  font-size: var(--text-5xl);
  line-height: 1.1;
  letter-spacing: -0.02em;
  margin-bottom: 24px;
}

.results__lede {
  max-width: 650px;
  margin-inline: auto;
  /* Blanco puro: es la frase que dice "esto le pasó a gente como tú",
     y en gris se leía como un pie de foto. 15 · 16 · 18. */
  font-size: clamp(0.9375rem, 0.37vw + 0.79rem, 1.125rem);
  line-height: 1.6;
  color: var(--color-light);
  margin-bottom: 80px;
}

/* En vertical el corte escrito estorba: el ancho ya obliga a partir en
   varias líneas y forzar una más deja un renglón suelto. */
@media (max-width: 640px) {
  .results__lede br { display: none; }
}

/* ---- Galería de historias ----------------------------------------
   Una historia protagonista y las vecinas asomando. El riel se
   traslada con `translate3d` y el paso activo lo marca una clase; lo
   único que se anima es `transform`, `opacity` y `filter`.

   Geometría: la tarjeta sale del alto disponible y de la proporción
   real de las capturas. El escenario mide 1,6 veces el ancho de la
   tarjeta, y de esa relación sale sola la lectura 20 / 60 / 20 sin
   ningún número mágico.
   =================================================================== */

.galeria {
  /* Cuántas capturas se ven de golpe. Es la única palanca: de aquí
     salen el ancho de la tarjeta, el salto del riel y —desde el JS—
     cuántos puntos tiene el indicador. Las consultas de medios de más
     abajo solo cambian este número. */
  --por-pagina: 2;
  --hueco: 60px;
  --ancho-tarjeta: calc(
    (100% - (var(--por-pagina) - 1) * var(--hueco)) / var(--por-pagina)
  );
  /* Larga, con arranque contenido y posada suave. `--ease-out` sirve
     para gestos de 350ms; en 1,2s cubriría casi todo el recorrido en
     la primera mitad y el resto se vería como una espera. */
  --ease-cine: cubic-bezier(0.33, 0.02, 0.16, 1);

  position: relative;
  margin-bottom: var(--spacing-2xl);
}

.galeria__escenario {
  width: min(94vw, 1120px);
  margin-inline: auto;
  overflow: hidden;
  /* Sin máscara de desvanecido: antes tenía sentido porque las vecinas
     asomaban recortadas por el borde. Ahora las tres tarjetas caben
     enteras y justas, y la máscara solo apagaría la primera y la
     última. */
}

/* Cada página avanza el escenario entero más el hueco que la separa de
   la siguiente: así la primera tarjeta de cada página cae siempre en el
   borde izquierdo. El 100% es el ancho del riel, que es el del
   escenario —las tarjetas se desbordan pero no ensanchan su caja. */
.galeria__riel {
  display: flex;
  gap: var(--hueco);
  list-style: none;
  padding-block: var(--spacing-xl);
  transform: translate3d(
    calc(var(--pagina, 0) * (100% + var(--hueco)) * -1), 0, 0
  );
  transition: transform 1200ms var(--ease-cine);
  will-change: transform;
}

.galeria__historia {
  flex: 0 0 auto;
  width: var(--ancho-tarjeta);
}

.galeria__btn {
  display: block;
  width: 100%;
  aspect-ratio: 840 / 1080;
  padding: 0;
  border: 0;
  /* 16px: la misma esquina que las tarjetas de plan y las del proceso,
     que es lo que hace que las tres secciones se lean como un sistema. */
  border-radius: 16px;
  overflow: hidden;
  background-color: var(--color-surface-deep);

  opacity: 0.35;
  transform: scale(0.9);
  filter: blur(2px);
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
  transition:
    opacity 1200ms var(--ease-cine),
    transform 1200ms var(--ease-cine),
    filter 1200ms var(--ease-cine),
    box-shadow 1200ms var(--ease-cine);
}

/* `none`, no `scale(1)` ni `blur(0)`. Esos dos obligan al navegador a
   rasterizar la tarjeta y volver a muestrearla, y sobre el texto
   pequeño del mensaje eso se lee como falta de foco. Es el mismo fallo
   que se midió en el desfile anterior. */
.galeria__historia.is-activa .galeria__btn {
  opacity: 1;
  transform: none;
  filter: none;
  /* La misma sombra que en reposo: 0 8px 32px. Antes la activa se
     elevaba con una sombra mucho mayor, pero con dos tarjetas
     encendidas a la vez esa diferencia ya no distingue nada. */
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
}

.galeria__btn img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.galeria__btn:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 6px;
}

/* ---- Flechas: solo con el cursor encima o con el foco ------------- */

.galeria__flecha {
  position: absolute;
  top: 50%;
  z-index: 2;
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  margin-top: -23px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background-color: rgba(255, 255, 255, 0.06);
  color: var(--color-text);
  cursor: pointer;
  opacity: 0;
  transition: opacity 400ms var(--ease-out), background-color 400ms var(--ease-out);
}

.galeria__flecha svg { width: 22px; height: 22px; }
.galeria__flecha--prev { left: max(var(--gutter), calc(50% - var(--ancho-tarjeta) * 0.95)); }
.galeria__flecha--next { right: max(var(--gutter), calc(50% - var(--ancho-tarjeta) * 0.95)); }

.galeria:hover .galeria__flecha,
.galeria__flecha:focus-visible {
  opacity: 0.45;
}

.galeria__flecha:hover,
.galeria__flecha:focus-visible {
  opacity: 0.9;
  background-color: rgba(255, 255, 255, 0.12);
}

/* ---- Indicador ---------------------------------------------------- */

.galeria__mando {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--spacing-lg);
  margin-top: 40px;
}

/* El hueco se aprieta solo según crece el número de historias: con
   quince segmentos la fila sigue cabiendo sin tocar nada. */
.galeria__indicador {
  display: flex;
  align-items: center;
  justify-content: center;
  /* 16px de hueco, no 12: con el punto de 8px, esto deja los centros a
     24px y las áreas de toque se tocan sin solaparse. Con 12 se
     pisaban y se acababa pulsando la página de al lado.

     Y envuelve: en vertical son quince puntos, que a 24px de centro a
     centro piden 360px y no caben en 320. Antes que apretarlos por
     debajo del mínimo, pasan a dos filas. */
  flex-wrap: wrap;
  /* 16px en los dos ejes. En horizontal deja los centros a 24px; en
     vertical hace lo mismo entre filas, que si no las zonas de toque de
     una fila y la siguiente se pisaban y quedaban en 16px de alto. */
  gap: 16px;
}

/* El ancho del segmento activo sí recalcula la maquetación, pero de
   cinco botones de siete píxeles dentro de su propia fila: es una
   invalidación diminuta y aislada, y ocurre una vez cada siete
   segundos. Medido, no cuesta ni un fotograma. */
.galeria__segmento {
  position: relative;
  width: 8px;
  height: 8px;
  padding: 0;
  border: 0;
  border-radius: 4px;
  /* var(--color-gris-hondo), el gris de borde del sistema. */
  background-color: var(--color-gris-hondo);
  cursor: pointer;
  /* El ancho se anima: al activarse el punto se estira en una barra.
     Es el gesto que dice "esta es la página en la que estás" sin
     necesidad de colorear las demás. */
  transition:
    width 300ms var(--ease-out),
    background-color 300ms var(--ease-out);
}

/* El área de toque, invisible y centrada sobre el punto. A 8x8 con 12px
   de hueco los puntos fallaban WCAG 2.5.8: ni llegaban a 24x24 ni les
   valía la excepción por separación, porque los centros quedaban a
   20px y hacen falta 24.

   Va en un pseudo-elemento y no en relleno del propio botón porque el
   punto tiene que seguir viéndose de 8px y redondo: con `padding` más
   `background-clip` el radio se calcula sobre la caja de 24 y el punto
   salía cuadrado. Así el dibujo no se toca y solo crece lo que el dedo
   alcanza. */
.galeria__segmento::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 24px;
  height: 24px;
  transform: translate(-50%, -50%);
}

.galeria__segmento:hover { background-color: rgba(255, 255, 255, 0.4); }

.galeria__segmento:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 4px;
}

/* 24px de largo y 4 de radio, como pide el encargo. La barra de avance
   que corre por dentro va en naranja, así que el punto activo se
   reconoce por el color además de por la forma. */
/* El activo se alarga a 24px y se tiñe de naranja. El fondo va al 30%
   y no al 100% porque por dentro corre la barra de cuenta atrás en
   naranja pleno: con el punto ya opaco no se vería avanzar y se
   perdería la única señal de que la galería va a pasar sola. Al
   completarse el ciclo el punto queda en #ff9d59 entero. */
.galeria__segmento[aria-selected='true'] {
  width: 24px;
  background-color: rgba(255, 157, 89, 0.3);
}

.galeria__relleno {
  position: absolute;
  inset: 0;
  /* Se recorta a sí misma. El botón perdió su `overflow: hidden` —que
     habría cortado también el área de toque— así que el redondeo de la
     barra tiene que salir de aquí. */
  overflow: hidden;
  border-radius: inherit;
  background-color: var(--color-primary);
  transform: scaleX(0);
  transform-origin: left center;
}

.galeria__segmento[aria-selected='true'] .galeria__relleno {
  animation: galeria-avance 7000ms linear forwards;
}

/* En pausa la barra se queda donde está: el propio indicador dice que
   el paso está detenido, sin necesitar un cartel. */
.galeria.esta-en-pausa .galeria__relleno {
  animation-play-state: paused;
}

@keyframes galeria-avance {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}

/* ---- Pausa / reanudar --------------------------------------------- */

.galeria__reloj {
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background-color: transparent;
  color: var(--color-text-muted);
  cursor: pointer;
  opacity: 0.55;
  transition: opacity 300ms var(--ease-out);
}

.galeria__reloj:hover,
.galeria__reloj:focus-visible { opacity: 1; }

.galeria__reloj:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 3px;
}

.galeria__icono {
  width: 18px;
  height: 18px;
  fill: currentColor;
}

.galeria__icono--play { display: none; }
.galeria.esta-en-pausa .galeria__icono--pausa { display: none; }
.galeria.esta-en-pausa .galeria__icono--play { display: block; }

/* ---- Aviso ------------------------------------------------------- */

.results__note {
  max-width: 800px;
  margin: 60px auto 0;
  text-align: center;
  font-size: clamp(0.8125rem, 0.185vw + 0.708rem, 0.875rem);   /* 13 · 14 */
  line-height: 1.5;
  color: var(--color-text-faint);
}

/* ---- La galería en vertical --------------------------------------
   Tres, dos y una. Lo único que cambia es `--por-pagina`: el ancho de
   la tarjeta, el salto del riel y el número de puntos salen solos de
   ahí. Son capturas de mensajes, así que el límite no es estético
   sino de lectura: por debajo de ~300px de tarjeta el texto del chat
   deja de leerse sin abrir el visor.

   El paso automático, el indicador y el gesto de deslizar se mantienen
   igual en los tres tamaños. */

/* La galería ya sale de fábrica en dos: este corte solo existía
   para bajar de tres a dos y ahora no tiene nada que hacer. */


/* Tableta: el hueco entre tarjetas baja a 40 y la seccion a 70. */
@media (max-width: 1023px) {
  .results { padding-block: 70px; }
  .results__lede { margin-bottom: 70px; }
  .galeria { --hueco: 40px; }
}

@media (max-width: 860px) {
  .galeria__flecha { display: none; }
}

/* Movil: una sola tarjeta, sin hueco que repartir. */
@media (max-width: 767px) {
  .results { padding-block: 60px; }
  .results__lede { margin-bottom: 60px; }
  .galeria { --hueco: 0px; }
  .galeria__btn { border-radius: 12px; }
  .results__note { margin-top: 40px; }
}

@media (max-width: 767px) {
  .galeria { --por-pagina: 1; }

  .galeria__btn { border-radius: 24px; }
  .galeria__mando { margin-top: var(--spacing-xl); }
}

/* ---- La galería sin movimiento -----------------------------------
   Sin paso automático no hay historia activa, así que las cinco se
   quedarían atenuadas. El riel pasa a ser una tira que se desplaza a
   mano con todas las capturas legibles. */

@media (prefers-reduced-motion: reduce) {
  .galeria__escenario {
    overflow-x: auto;
    -webkit-mask-image: none;
    mask-image: none;
  }

  /* El anclaje va en el contenedor que se desplaza, no en el riel. */
  .galeria__escenario { scroll-snap-type: x mandatory; }

  .galeria__riel {
    transform: none;
    transition: none;
  }

  .galeria__historia { scroll-snap-align: center; }

  .galeria__btn {
    opacity: 1;
    transform: none;
    filter: none;
    transition: none;
  }

  /* Con la misma especificidad que la regla que la enciende: si no,
     la barra seguiría corriendo —instantánea— y un segmento lleno
     daría a entender que la galería está a punto de avanzar sola,
     que es justo lo que aquí no pasa. */
  .galeria__segmento[aria-selected='true'] .galeria__relleno { animation: none; }

  .galeria__reloj { display: none; }
}

/* ===================================================================
   Esto obtienes

   Tres columnas y un cierre, en una sola pantalla. El encargo pide que
   no haya que bajar para verlo entero, y eso no se consigue con
   tamaños fijos: en un portátil de 1080p el hueco útil ronda los 900px
   y el bloque a tamaño completo pide más. Así que todo lo que ocupa
   alto —el aire, la tipografía y el relleno de las tarjetas— va con
   `clamp()` atado a `vh`: en pantallas altas se ve exactamente a la
   medida pedida, y en pantallas bajas encoge en vez de desbordarse.

   Fondo var(--color-dark), el que pide el encargo. Es el mismo del cuerpo, así
   que esta sección y la de planes quedan unidas: el cierre dice "elige
   tu plan" y lo siguiente son los planes. La separación que importa es
   la de arriba, contra los testimonios, que van en #121212.
   =================================================================== */

/* Ya no ocupa la pantalla entera. El encargo la quiere compacta —un
   puente entre la prueba y el precio, no una sección para detenerse—,
   y eso es incompatible con `min-height: 100vh`: una sección que llena
   la pantalla se lee como principal por definición.

   Al soltar esa atadura desaparecen los dos escalones por `max-height`
   que comprimían la tipografía para hacerla caber. Ahora la escala del
   encargo —72 / 64 / 24— se ve entera en cualquier pantalla. */
.entrena {
  padding-block: 60px 70px;
  padding-inline: 40px;
  background-color: var(--color-surface-bg);
}

/* ---- Cabecera ----------------------------------------------------- */

.entrena__cabecera {
  text-align: center;
  margin-bottom: clamp(32px, 6vh, 64px);
}

.entrena__badge {
  display: inline-block;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--color-primary);
  padding: 7px 18px;
}

/* 900px, no 20ch: a 48px una caja de 20ch parte la frase en cuatro
   líneas y la cabecera sola se come 355px de los 728 útiles de un
   portátil. A este ancho cae en dos. */
.entrena__title {
  /* 1000px, no 900: a 72px la frase cae en cuatro líneas dentro de una
     caja de 900 y el titular solo mide 317px —más que las tarjetas—.
     Con 1000 baja a tres y la sección se acorta 79px, que es justo lo
     que el encargo pide de una sección puente. */
  max-width: 1000px;
  margin-inline: auto;
  margin-top: 20px;
  /* 72px, la misma familia que el hero, el diagnóstico y el proceso. */
  font-size: var(--text-5xl);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--color-light);
  margin-bottom: 24px;
  text-wrap: balance;
  /* "acompañamiento" mide 14 caracteres: a 48px no cabe en la columna
     de un móvil de 390px y se salía 83px, ensanchando el documento
     entero. Se parte con guion —el documento está en español, así que
     el navegador sabe dónde— y `break-word` queda de red por si el
     diccionario de guionado no está disponible. */
  hyphens: auto;
  overflow-wrap: break-word;
}

.entrena__lede {
  max-width: 62ch;
  margin-inline: auto;
  /* Blanco puro. 15 · 16 · 18 según el ancho. */
  font-size: clamp(0.9375rem, 0.37vw + 0.79rem, 1.125rem);
  line-height: 1.6;
  color: var(--color-light);
  /* 60px, no 80: la sección es un puente y el aire de más la haría
     parecer una parada. 60 · 50 · 40. */
  margin-bottom: clamp(40px, 1.905vw + 32.57px, 60px);
  text-wrap: pretty;
}

/* ---- Las tres columnas ---------------------------------------------
   `minmax(0, 1fr)`, no `1fr`: el mínimo implícito de `auto` impide que
   una columna encoja por debajo de su contenido y desborda la rejilla
   en cuanto una descripción es más larga que las otras. */

.entrena__pasos {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  /* 40 · 30 · 24 */
  gap: clamp(24px, 1.85vw + 13.35px, 40px);
  max-width: 1200px;
  margin-inline: auto;
  list-style: none;
}

.entrena__paso {
  display: flex;
  flex-direction: column;
  padding: 32px;
  min-height: 300px;
  /* El filete es el mismo #333 al 15% que pide el encargo: con 40px de
     hueco entre tarjetas, un borde derecho suelto sería redundante —el
     aire ya separa— y dejaría las columnas descuadradas. */
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: 12px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
  transition:
    border-color 300ms var(--ease-out),
    box-shadow 300ms var(--ease-out),
    transform 300ms var(--ease-out);
}

/* Solo donde hay cursor de verdad. En una pantalla táctil el estado se
   queda pegado después de tocar.

   El selector largo no es adorno: la regla que cierra el revelado es
   `.entrena__paso[data-reveal].is-visible` y declara `transform: none`
   con especificidad (0,3,0). Un `:hover` a secas se queda en (0,2,0) y
   pierde, así que el borde se aclaraba pero la tarjeta no subía. */
@media (hover: hover) and (pointer: fine) {
  .entrena__paso:hover,
  .entrena__paso[data-reveal].is-visible:hover {
    border-color: rgba(255, 255, 255, 0.18);
    transform: translate3d(0, -4px, 0);
  }

  /* La cifra se enciende, como en el diagnóstico. Aquí basta el
     selector corto: el pleito de especificidad con el revelado era solo
     por `transform`, y esa regla no toca `color`. (0,3,0) contra la
     base (0,1,0), sin discusión. */
  .entrena__paso:hover .entrena__cifra {
    color: var(--color-primary);
    transition-duration: 300ms;
  }
}

/* La cifra va en flujo y encima del título, nunca detrás: se midió que
   superpuesta se comía la primera línea. Muy tenue a propósito —es
   composición, no información—, y por eso está fuera del lector. */
.entrena__cifra {
  display: block;
  font-family: var(--font-display);
  /* 48 · 52 · 64, en blanco al 8%: está, pero no se ve. Va con
     `aria-hidden`, así que no le aplica el contraste mínimo. */
  font-size: clamp(3rem, 2.22vw + 2rem, 4rem);
  font-weight: 200;
  line-height: 1;
  letter-spacing: -0.03em;
  color: rgba(255, 255, 255, 0.08);
  margin-bottom: 12px;
  /* Se enciende con el cursor, igual que la cifra del diagnóstico.
     400ms al apagarse y 300 al encenderse: entra rápido y se va con
     calma, que es lo que hace que el gesto no se note trabajado. */
  transition: color 400ms var(--ease-out);
}

.entrena__verbo {
  /* 20 · 22 · 24 */
  font-size: clamp(1.25rem, 0.37vw + 1.167rem, 1.5rem);
  font-weight: 700;
  line-height: 1.25;
  letter-spacing: -0.02em;
  color: var(--color-light);
  margin-bottom: 16px;
}

.entrena__cuerpo {
  /* Crece para llenar la tarjeta: así las tres miden lo mismo aunque
     los textos tengan distinta longitud. */
  flex: 1;
  font-size: clamp(0.875rem, 0.19vw + 0.83rem, 0.9375rem);   /* 14 · 15 */
  line-height: 1.6;
  color: var(--color-text-muted);
  text-wrap: pretty;
}

/* ---- El cierre -----------------------------------------------------
   Solo tipografía. Ni imagen, ni botón: el botón está en la sección
   siguiente, a una pantalla de aquí, y repetirlo restaría a los dos. */

.entrena__pausa {
  margin-top: clamp(32px, 4vw + 16px, 56px);
  text-align: center;
}

.entrena__moraleja {
  max-width: 900px;
  margin-inline: auto;
}

.entrena__moraleja span {
  display: block;
}

/* La primera frase prepara y va pequeña. */
.entrena__moraleja-uno {
  font-size: clamp(0.8125rem, 0.185vw + 0.708rem, 0.875rem);   /* 13 · 14 */
  line-height: 1.6;
  color: var(--color-text-faint);
}

/* Las dos siguientes son el argumento, y van grandes: es lo último que
   se lee antes del precio. 22 · 24 · 28. */
.entrena__moraleja-fuerte {
  margin-top: 16px;
  font-family: var(--font-display);
  font-size: clamp(1.375rem, 0.74vw + 1.084rem, 1.75rem);
  font-weight: 700;
  line-height: 1.3;
  letter-spacing: -0.02em;
  color: var(--color-light);
  text-wrap: balance;
}

/* La llamada a la acción, entera en naranja: es lo único de la sección
   que se puede pulsar y lo que empuja a la siguiente. 16 · 16 · 18. */
.entrena__remate {
  margin-top: 24px;
  font-family: var(--font-display);
  font-size: clamp(1rem, 0.37vw + 0.792rem, 1.125rem);
  font-weight: 700;
  color: var(--color-primary);
}

.entrena__remate a {
  color: inherit;
  /* Igual que el salto de planes: es un enlace en prosa. */
  text-decoration: underline;
  text-decoration-color: rgba(255, 152, 80, 0.45);
  text-underline-offset: 5px;
}

.entrena__remate a:hover {
  text-decoration-color: currentColor;
}

/* ---- La entrada ----------------------------------------------------
   Escalonada por columna, con el mismo sistema que el diagnóstico: las
   tres se ven a la vez, así que entran una detrás de otra y no todas
   de golpe. Se anima `transform`, `opacity` y `filter`, nada que
   recalcule la maquetación. */

.entrena__paso[data-reveal] {
  opacity: 0;
  filter: blur(6px);
  transform: translate3d(0, 24px, 0);
}

/* Sin `both`. Una animación con relleno se queda gobernando `transform`
   cuando termina, y las animaciones ganan a las declaraciones normales
   en la cascada: el borde del hover se aclaraba pero la tarjeta no se
   movía nunca. El estado final lo dan estas tres líneas; la animación
   solo cubre el trayecto. */
.entrena__paso[data-reveal].is-visible {
  opacity: 1;
  filter: none;
  transform: none;
  animation: revelar-columna 700ms var(--ease-out);
}

.entrena__paso:nth-child(2)[data-reveal].is-visible { animation-delay: 120ms; }
.entrena__paso:nth-child(3)[data-reveal].is-visible { animation-delay: 240ms; }


/* ---- Tablet: dos columnas ------------------------------------------
   La tercera pasa debajo y ocupa el ancho entero: dejarla a media
   columna, sola y alineada a la izquierda, se lee como un error. */

@media (max-width: 1023px) {
  .entrena { padding-block: 50px; }

  .entrena__pasos { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .entrena__paso:nth-child(3) { grid-column: 1 / -1; }
}

/* ---- Móvil: una columna ------------------------------------------- */

@media (max-width: 767px) {
  .entrena {
    padding-block: 50px;
    padding-inline: 20px;
  }

  .entrena__pasos { grid-template-columns: minmax(0, 1fr); }
  .entrena__paso:nth-child(3) { grid-column: auto; }

  /* Sin alto mínimo: con una tarjeta por fila, 300px de suelo dejaría
     un hueco vacío bajo los textos cortos.

     Y la tarjeta se despega del fondo: filete del 15% al 26% y un
     relleno propio muy tenue. En horizontal son tres en fila y el hueco
     entre ellas ya dice dónde acaba cada una; en vertical van apiladas
     sobre negro y, sin fondo, el filete de 1px al 15% era lo único que
     las delimitaba. Ese relleno no llega a leerse como caja gris: sube
     el fondo de 26 a 32 sobre 255, lo justo para que el borde se apoye
     en algo. */
  .entrena__paso {
    min-height: 0;
    border-color: rgba(255, 255, 255, 0.26);
    background-color: rgba(255, 255, 255, 0.025);
  }

  /* Las tres cifras, del 8% al 22% de blanco. Mismo motivo y mismo
     valor que las del diagnóstico: solas sobre negro, al 8% se componen
     en un gris de 44 sobre 255 y desaparecen al sol. Al 22% quedan en
     76, visibles y todavía muy por debajo del titular.

     El naranja del cursor no se toca: vive en un bloque
     `@media (hover: hover)` y aquí no llega. */
  .entrena__cifra {
    color: rgba(255, 255, 255, 0.22);
  }
}

/* ---- Sin movimiento ------------------------------------------------ */

@media (prefers-reduced-motion: reduce) {
  .entrena__paso[data-reveal],
  .entrena__paso[data-reveal].is-visible {
    opacity: 1;
    filter: none;
    transform: none;
    animation: none;
  }

  .entrena__paso { transition: none; }
}

/* ===================================================================
   Planes — la puerta de entrada, no una tabla de precios
   -------------------------------------------------------------------
   Las tres tarjetas miden exactamente igual y llevan las mismas seis
   líneas. Lo único que cambia es la jerarquía: etiqueta, borde,
   resplandor y el peso del botón.

   Aquí no aparece ningún porcentaje de ahorro ni etiqueta de precio: la
   sección vende permanencia, no descuento.
   =================================================================== */

.pricing {
  position: relative;
  isolation: isolate;
  padding-block: var(--section-y);
  overflow: hidden;
}

/* ---- El fondo, en tres capas casi invisibles --------------------- */

.pricing__fondo {
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
}

/* Rejilla al 2%, desvanecida hacia los bordes con una máscara radial
   para que no se corte en seco contra las secciones vecinas. */
.pricing__rejilla {
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(rgba(255, 255, 255, 0.02) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, 0.02) 1px, transparent 1px);
  background-size: 76px 76px;
  -webkit-mask-image: radial-gradient(72% 62% at 50% 42%, #000 0%, transparent 78%);
  mask-image: radial-gradient(72% 62% at 50% 42%, #000 0%, transparent 78%);
}

/* Halo oscuro: hunde las esquinas y empuja las tarjetas hacia delante. */
.pricing__halo {
  position: absolute;
  inset: -20% -10%;
  background: radial-gradient(
    58% 48% at 50% 46%,
    transparent 0%,
    rgba(0, 0, 0, 0.35) 62%,
    rgba(0, 0, 0, 0.6) 100%
  );
}

/* Luz difusa detrás de la tarjeta protagonista. Muy tenue: si se nota
   como una mancha, sobra. */
.pricing__luz {
  position: absolute;
  top: 42%;
  left: 50%;
  width: min(760px, 78vw);
  height: 420px;
  transform: translate(-50%, -50%);
  background: radial-gradient(
    50% 50% at 50% 50%,
    rgba(255, 152, 80, 0.055) 0%,
    rgba(255, 152, 80, 0.018) 46%,
    transparent 72%
  );
  filter: blur(30px);
}

/* ---- Cabecera ---------------------------------------------------- */

.pricing__cabecera {
  text-align: center;
  margin-bottom: var(--spacing-4xl);
}

.pricing__badge {
  display: inline-block;
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--color-primary);
  padding: 7px 18px;
}

.pricing__title {
  max-width: 20ch;
  margin-inline: auto;
  margin-bottom: var(--spacing-lg);
  font-size: var(--text-4xl);
  line-height: 1.08;
  letter-spacing: -0.02em;
}

.pricing__lede {
  max-width: 58ch;
  margin-inline: auto;
  font-size: var(--text-lg);
  color: var(--color-text-muted);
}

/* ---- Las tres tarjetas -------------------------------------------
   `stretch` y las seis líneas fijas hacen que las tres midan
   exactamente igual, con los botones alineados. */

.plans {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  align-items: stretch;
  gap: var(--spacing-lg);
  margin-bottom: var(--spacing-4xl);
}

.plan {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--spacing-lg);
  /* 48 de relleno y 600 de alto mínimo: el encargo pide tarjetas más
     generosas, y con el precio a 64px hacen falta. */
  padding: 48px;
  min-height: 600px;
  border: 1px solid var(--color-border-subtle);
  border-radius: 16px;
  background-color: rgba(255, 255, 255, 0.022);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
  opacity: 0;
  --escala: 1;
  transition:
    transform 420ms var(--ease-out),
    border-color 420ms var(--ease-out),
    background-color 420ms var(--ease-out),
    box-shadow 420ms var(--ease-out);
}

/* El selector doble no es adorno. Las tarjetas llevan `data-reveal`, y
   la regla global `[data-reveal].is-visible` declara `transform: none`
   con especificidad (0,2,0). Un `.plan` a secas se queda en (0,1,0) y
   pierde: la protagonista se quedaba sin su escala. */
.plan,
.plan[data-reveal].is-visible {
  transform: scale(var(--escala));
}

/* La entrada va con @keyframes y no con la transición general: esa
   gobierna el paso del cursor, y una sola propiedad `transition` no
   puede servir a dos gestos con duraciones distintas. */
.plan.is-visible {
  animation: entrar-plan 800ms var(--ease-out) backwards;
  animation-delay: calc(var(--orden, 0) * 120ms);
}

@keyframes entrar-plan {
  from {
    opacity: 0;
    transform: translate3d(0, 24px, 0) scale(var(--escala));
    filter: blur(8px);
  }
  to {
    opacity: 1;
    transform: scale(var(--escala));
    filter: none;
  }
}

@media (hover: hover) and (pointer: fine) {
  .plan:hover,
  .plan[data-reveal].is-visible:hover {
    transform: translate3d(0, -8px, 0) scale(var(--escala));
    border-color: rgba(255, 255, 255, 0.16);
    background-color: rgba(255, 255, 255, 0.035);
    box-shadow: 0 18px 48px rgba(0, 0, 0, 0.42);
  }
}

/* ---- La protagonista ---------------------------------------------
   Mismo tamaño que las otras dos. Se distingue por el borde, una sombra
   apenas mayor y un resplandor difuso por detrás. */

.plan--destacado {
  /* 1.02, no 1.05: con 600px de alto un 5% saca la tarjeta 30px por
     arriba y por abajo de la fila y empieza a pisar lo que hay
     alrededor. Un 2% se nota y no descuadra. */
  --escala: 1.02;
  border: 3px solid var(--color-primary);
  padding: 45px;
  background-color: #222222;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
  z-index: 1;
}

@media (hover: hover) and (pointer: fine) {
  .plan--destacado:hover {
    border-color: var(--color-primary-hover);
    box-shadow: 0 28px 76px rgba(0, 0, 0, 0.45);
  }
}

/* ---- Cada plan con su color ----------------------------------------
   Los tres empiezan iguales y solo el Trimestral llevaba color. Ahora
   el Mensual se separa por la luz y el Anual por el tono, y el
   Trimestral se queda exactamente como estaba: sigue siendo el
   destacado y no se le toca ni un valor.

   Van por `id` —`plan-mensual`, `plan-anual`, que pone el JS al pintar
   cada tarjeta— porque un `id` (1,0,0) gana a `.plan:hover` (0,2,0) y a
   `.plan[data-reveal].is-visible:hover` (0,4,0). Por eso el estado con
   el cursor encima hay que volver a declararlo aquí: si no, la regla
   general dejaría de aplicarse y la tarjeta se quedaría sin reacción. */

/* El Mensual: sombra blanca en vez de negra. La negra hundía la tarjeta
   contra un fondo ya oscuro y no se veía; la blanca la despega. Se
   conserva debajo la sombra de profundidad, que es la que le da cuerpo:
   sin ella la tarjeta flota plana. */
#plan-mensual {
  box-shadow:
    0 2px 8px rgba(0, 0, 0, 0.3),
    /* Dos capas: una ceñida al borde, que dibuja el filo, y otra abierta
       que lo separa del fondo. A 0.10 en una sola capa el resplandor
       medía ocho niveles de brillo sobre 255 y no se distinguía. */
    0 0 0 1px rgba(255, 255, 255, 0.10),
    0 0 26px rgba(255, 255, 255, 0.22);
}

@media (hover: hover) and (pointer: fine) {
  #plan-mensual:hover {
    border-color: rgba(255, 255, 255, 0.16);
    background-color: rgba(255, 255, 255, 0.035);
    box-shadow:
      0 18px 48px rgba(0, 0, 0, 0.42),
      0 0 44px rgba(255, 255, 255, 0.16);
  }
}

/* El Anual en azul: borde, resplandor, recuadro de ahorro y marcas de la
   lista —lo mismo que el Trimestral lleva en naranja—. El titular, el
   precio y el cuerpo se quedan en blanco y gris en las tres.

   Borde de 2px, no de 3: el Trimestral sigue siendo el destacado y se
   distingue por tener el borde más grueso, la etiqueta, la escala y el
   fondo relleno. El Anual se marca, pero un escalón por debajo.

   El relleno baja a 47 para compensar el píxel de más del borde: con
   `border-box`, engordar el borde comería ancho al contenido y las
   tarjetas dejarían de alinearse por dentro. 2 + 47 = 49, el mismo
   desplazamiento que el Mensual con su 1 + 48. */
#plan-anual {
  border: 2px solid var(--color-anual);
  padding: 47px;
}

/* El resplandor, calcado del de la protagonista pero en azul. Va en un
   pseudo-elemento y no en `.plan__aura` porque esa capa la pinta el JS
   solo para el plan destacado; aquí no hace falta tocar el marcado. */
#plan-anual::before {
  content: '';
  position: absolute;
  z-index: -1;
  inset: -22px -18px -26px;
  border-radius: 40px;
  background: radial-gradient(
    58% 52% at 50% 50%,
    rgba(var(--color-anual-rgb), 0.16) 0%,
    rgba(var(--color-anual-rgb), 0.05) 48%,
    transparent 74%
  );
  filter: blur(20px);
  pointer-events: none;
}

@media (hover: hover) and (pointer: fine) {
  #plan-anual:hover {
    border-color: #8cc6ff;
    background-color: rgba(255, 255, 255, 0.035);
    box-shadow:
      0 18px 48px rgba(0, 0, 0, 0.42),
      0 0 40px rgba(var(--color-anual-rgb), 0.18);
  }
}

#plan-anual .plan__ahorro {
  border-left-color: var(--color-anual);
  background-color: rgba(var(--color-anual-rgb), 0.1);
  color: var(--color-anual);
}

#plan-anual .plan__check {
  color: var(--color-anual);
}

/* El resplandor vive detrás y desenfocado: no es un borde encendido ni
   un naranja intenso, solo profundidad. */
.plan__aura {
  position: absolute;
  z-index: -1;
  inset: -22px -18px -26px;
  border-radius: 40px;
  background: radial-gradient(
    58% 52% at 50% 50%,
    rgba(255, 152, 80, 0.13) 0%,
    rgba(255, 152, 80, 0.04) 48%,
    transparent 74%
  );
  filter: blur(20px);
  pointer-events: none;
}

/* ---- Cabecera de la tarjeta -------------------------------------- */

.plan__head {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

/* El periodo es lo que se compra —un mes, tres, doce—; el nombre es
   cómo se llama. Van juntos y en ese orden: primero el hecho. */
.plan__periodo {
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--color-text-faint);
}

/* Dos líneas reservadas aunque el nombre ocupe una. "Crea tu rutina
   ganadora" no cabe en un renglón y sin esta reserva su precio caería
   más abajo que el de las otras dos: las tres cifras tienen que
   alinearse para poder compararse de un vistazo. */
.plan__name {
  min-height: calc(2 * 1.2em);
  font-size: var(--text-xl);
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -0.01em;
  color: var(--color-light);
}

/* La etiqueta va arriba del todo, cruzando el borde de la tarjeta:
   es un rótulo puesto encima, no una línea más del contenido. */
.plan__tag {
  position: absolute;
  top: 0;
  left: 50%;
  transform: translate(-50%, -50%);
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 16px;
  border-radius: var(--radius-pill);
  background-color: var(--color-primary);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-dark);
  white-space: nowrap;
  box-shadow: 0 6px 18px rgba(255, 152, 80, 0.32);
}

.plan__estrella {
  font-size: 1.05em;
  line-height: 1;
}

/* ---- Precio ------------------------------------------------------ */

.plan__price {
  padding-bottom: var(--spacing-lg);
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.plan__amount {
  display: flex;
  align-items: baseline;
  gap: 8px;
}

.plan__figure {
  font-family: var(--font-display);
  /* 64px en escritorio. Es la cifra más grande de la página después
     del titular del hero, y esa es exactamente la jerarquía que pide
     una sección de precios. */
  font-size: clamp(3rem, 2.4vw + 2.1rem, 4rem);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.04em;
  font-variant-numeric: tabular-nums;
  color: var(--color-light);
}

.plan__unit {
  font-size: var(--text-sm);
  font-weight: 500;
  letter-spacing: 0.08em;
  color: var(--color-text-faint);
}

/* Dato sobre el compromiso, no un descuento: aquí no hay porcentajes. */
.plan__equiv {
  margin-top: 10px;
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

/* El ahorro sí lleva color: es el argumento del plan, no un adorno.
   Va en naranja y en negrita porque es lo único de la tarjeta que
   compara con otra cosa. */
.plan__ahorro {
  margin-top: 12px;
  padding: 12px 16px;
  border-left: 3px solid var(--color-primary);
  border-radius: 0 6px 6px 0;
  background-color: rgba(255, 157, 89, 0.1);
  font-size: var(--text-sm);
  font-weight: 700;
  line-height: 1.45;
  color: var(--color-primary);
}

.plan__summary {
  font-size: var(--text-base);
  line-height: var(--leading-lede);
  /* Sube de terciario a secundario: es la frase que explica para quién
     es el plan y se estaba leyendo como letra pequeña. */
  color: var(--color-text-muted);
}

/* ---- Lo que incluye cada plan ------------------------------------
   Cada plan lleva su propia lista, de cinco a siete líneas. Ya no hay
   líneas atenuadas: si algo no está, no se enseña. Las tarjetas siguen
   midiendo lo mismo porque la rejilla las estira y el botón se pega
   abajo. */

.plan__features {
  display: grid;
  gap: 12px;
  list-style: none;
}

.plan__features li {
  display: grid;
  grid-template-columns: 18px 1fr;
  gap: 10px;
  align-items: start;
  font-size: var(--text-sm);
  line-height: 1.5;
  color: var(--color-text);
}

/* De la cuarta en adelante, un punto por debajo. Las tres primeras son
   las que todo el mundo compara; el resto acompaña.

   Se baja el color, no la opacidad. Bajar la opacidad al 0.6 sobre un
   gris ya tenue deja el texto en 3.2:1 y se cae de AA; con var(--color-text-faint) a
   opacidad entera el escalón se ve igual y el contraste se queda en
   6.1:1. El tamaño tampoco baja a 13px por lo mismo. */
.plan__features li:nth-child(n + 4) {
  color: var(--color-text-faint);
}

.plan__features li:nth-child(n + 4) .plan__check {
  color: rgba(255, 152, 80, 0.6);
}

.plan__check {
  font-size: var(--text-sm);
  line-height: 1.5;
  color: var(--color-primary);
}

/* El estado también en palabras: un símbolo no se lee en voz alta sin
   ambigüedad. */
.plan__oculto {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ---- El botón ----------------------------------------------------
   Pegado al fondo aunque el resumen ocupe distinto. */

.plan__cta {
  margin-top: auto;
  align-self: stretch;
  /* 16px de cuerpo y 18 de alto: es el botón que cierra la venta. */
  font-size: var(--text-base);
  padding-block: 18px;
}

.plan:not(.plan--destacado) .plan__cta {
  background-color: transparent;
  border: 1px solid rgba(255, 255, 255, 0.2);
  color: var(--color-light);
  box-shadow: none;
}

@media (hover: hover) and (pointer: fine) {
  .plan:not(.plan--destacado) .plan__cta:hover {
    border-color: rgba(255, 255, 255, 0.42);
    background-color: rgba(255, 255, 255, 0.05);
  }
}

/* Sin enlace de pago el botón no lleva a ninguna parte, así que no se
   pinta como si lo hiciera: apagado, sin cursor de mano y sin sombra.
   Es un estado temporal —falta crear el plan en Whop— y por eso lleva
   un aviso debajo en vez de desaparecer. */
.plan__cta--sin-enlace {
  background-color: rgba(255, 255, 255, 0.06);
  border: 1px dashed rgba(255, 255, 255, 0.28);
  color: var(--color-text-faint);
  box-shadow: none;
  cursor: not-allowed;
}

@media (hover: hover) and (pointer: fine) {
  .plan__cta--sin-enlace:hover {
    transform: none;
    background-color: rgba(255, 255, 255, 0.06);
  }
}

/* Va justo encima del botón apagado, empujado al fondo con él. */
.plan__aviso {
  margin-top: auto;
  margin-bottom: 10px;
  font-size: var(--text-xs);
  line-height: 1.5;
  text-align: center;
  color: var(--color-primary);
}

/* ---- El cierre: cuál elegir --------------------------------------
   Para quien ha leído las tres tarjetas y sigue dudando. Las tres
   primeras líneas llevan al ancla de su tarjeta: la duda se resuelve
   con un clic, no volviendo a subir a comparar. */

.eleccion {
  max-width: 900px;
  margin: var(--spacing-4xl) auto 0;
  padding-top: var(--spacing-3xl);
  border-top: 1px solid var(--color-border-subtle);
}

.eleccion__titulo {
  margin-bottom: var(--spacing-xl);
  font-size: var(--text-2xl);
  font-weight: 700;
  letter-spacing: var(--tracking-tight);
  text-align: center;
  color: var(--color-light);
}

.eleccion__guia {
  display: grid;
  gap: 10px;
  list-style: none;
  margin-bottom: var(--spacing-3xl);
}

.eleccion__guia li {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px 12px;
  padding: 14px 18px;
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--radius-md);
  font-size: var(--text-base);
}

.eleccion__mayoria {
  border-color: rgba(255, 152, 80, 0.3);
  background-color: rgba(255, 152, 80, 0.05);
}

.eleccion__caso {
  color: var(--color-text-muted);
}

/* La flecha va en el pseudoelemento y no en el texto: es puntuación
   visual, y un lector de pantalla no debe deletrear "flecha derecha"
   entre el caso y el plan. */
.eleccion__caso::after {
  content: '→';
  margin-left: 10px;
  color: var(--color-text-faint);
}

.eleccion__salto {
  font-weight: 700;
  color: var(--color-light);
  /* Va dentro de una frase: el subrayado es lo que lo señala. */
  text-decoration: underline;
  text-decoration-color: rgba(255, 255, 255, 0.28);
  text-underline-offset: 4px;
}

.eleccion__salto:hover {
  text-decoration-color: currentColor;
}

.eleccion__mayoria .eleccion__salto { color: var(--color-primary); }

.eleccion__sello {
  margin-left: auto;
  padding: 3px 10px;
  border-radius: var(--radius-pill);
  background-color: rgba(255, 152, 80, 0.14);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-primary);
  white-space: nowrap;
}

.eleccion__reparto {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--spacing-2xl);
  margin-bottom: var(--spacing-2xl);
}

.eleccion__bloque h4 {
  margin-bottom: var(--spacing-md);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-text-faint);
}

.eleccion__bloque ul {
  display: grid;
  gap: 8px;
  list-style: none;
  font-size: var(--text-sm);
  line-height: 1.5;
  color: var(--color-text);
}

/* Marca distinta en cada columna: la de la izquierda enumera lo que
   está garantizado y la de la derecha lo que depende del plan. Con la
   misma viñeta las dos listas se leerían como una sola. */
.eleccion__bloque li::before {
  content: '✓';
  margin-right: 10px;
  color: var(--color-primary);
}

.eleccion__bloque--cambia li::before {
  content: '→';
  color: var(--color-text-faint);
}

.eleccion__final {
  padding-top: var(--spacing-xl);
  border-top: 1px solid var(--color-border-subtle);
  font-size: var(--text-base);
  text-align: center;
  color: var(--color-text-muted);
}

@media (max-width: 640px) {
  .eleccion__reparto { grid-template-columns: minmax(0, 1fr); }
  .eleccion__sello { margin-left: 0; }
}

.pricing__nota {
  max-width: 62ch;
  margin-inline: auto;
  text-align: center;
  font-size: var(--text-xs);
  line-height: 1.6;
  color: var(--color-text-faint);
}

.plans-fallback {
  display: grid;
  gap: var(--spacing-sm);
  list-style: none;
  padding: var(--spacing-lg);
  border: 1px solid var(--color-border-default);
  border-radius: var(--radius-lg);
  margin-bottom: var(--spacing-lg);
}

.plans-fallback a {
  color: var(--color-primary);
  text-decoration: underline;
}

/* ---- Preguntas frecuentes ---------------------------------------- */

.faq {
  /* 80 · 70 · 60, la escalera del encargo. */
  padding-block: 80px;
  padding-inline: 40px;
  background-color: var(--color-surface-deep);
  border-block: 1px solid var(--color-border-subtle);
}

/* 900px, no los 760 del contenedor estrecho: con diez preguntas la
   columna necesita algo más de aire sin llegar a ancho de lectura
   incómodo. */
.faq .container--narrow {
  max-width: 900px;
}

/* Su propia escalera: 42 en móvil, no los 48 de la escala global.
   El corte de tableta la fija en 56 porque interpolando cae en 57. */
/* La cabecera va centrada entera. El subtítulo lo pedía centrado y
   dejar el distintivo y el titular a la izquierda hacía que el bloque
   se leyera como un descuadre, no como una decisión. */
.faq .eyebrow,
.faq__title {
  text-align: center;
}

.faq__title {
  font-size: clamp(2.625rem, 2.86vw + 1.928rem, 4.5rem);
  line-height: 1.1;
  letter-spacing: -0.02em;
  margin-bottom: 24px;
}

.faq__lede {
  max-width: 600px;
  margin: 0 auto;
  /* 14 · 15 · 16 */
  font-size: clamp(0.875rem, 0.185vw + 0.833rem, 1rem);
  line-height: 1.5;
  text-align: center;
  color: var(--color-text-muted);
  /* 40 · 50 · 60 */
  margin-bottom: clamp(40px, 1.905vw + 32.57px, 60px);
}

/* ---- El acordeón -------------------------------------------------- */

.faq__list {
  display: grid;
  /* 16 · 16 · 20 */
  gap: clamp(16px, 0.74vw + 9.34px, 20px);
}

.faq__item {
  border: 1px solid var(--color-border-subtle);
  border-radius: 12px;
  background-color: rgba(30, 30, 30, 0.8);
  transition:
    border-color 300ms var(--ease-out),
    background-color 300ms var(--ease-out),
    box-shadow 300ms var(--ease-out);
}

@media (hover: hover) and (pointer: fine) {
  .faq__item:hover {
    border-color: var(--color-gris-medio);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
  }
}

/* Abierto: el fondo se tiñe apenas de naranja y el filete se aclara.
   Un 3% es casi nada, y es justo lo que hace que la pregunta abierta
   se distinga sin encender la caja. */
.faq__item[open] {
  border-color: var(--color-gris-medio);
  background-color: rgba(255, 157, 89, 0.03);
}

.faq__q {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--spacing-md);
  /* 24px 20px · 28px · 32px */
  padding: clamp(24px, 0.74vw + 21.34px, 32px);
  font-family: var(--font-display);
  /* 16 · 17 · 18 */
  font-size: clamp(1rem, 0.185vw + 0.958rem, 1.125rem);
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: -0.02em;
  color: var(--color-light);
  cursor: pointer;
  list-style: none;
}

.faq__q::-webkit-details-marker {
  display: none;
}

/* ---- El signo más -------------------------------------------------
   Dos barras cruzadas. Al abrir gira el conjunto 45°, no una de las
   barras: así el + se convierte en × y el gesto se lee como "esto se
   cierra", no como "esto cambió de icono". */

.faq__icon {
  position: relative;
  flex-shrink: 0;
  /* 28 · 28 · 32 */
  width: clamp(28px, 0.74vw + 21.34px, 32px);
  height: clamp(28px, 0.74vw + 21.34px, 32px);
  transition: transform 300ms ease;
}

.faq__icon::before,
.faq__icon::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 15%;
  width: 70%;
  height: 2px;
  margin-top: -1px;
  border-radius: 1px;
  background-color: var(--color-primary);
}

.faq__icon::after {
  transform: rotate(90deg);
}

.faq__item[open] .faq__icon {
  transform: rotate(45deg);
}

/* ---- La respuesta -------------------------------------------------
   `<details>` nativo enseña y esconde su contenido de golpe. Las dos
   propiedades de abajo son lo que permite animarlo sin JavaScript:
   `interpolate-size` deja interpolar hacia `auto` y
   `transition-behavior: allow-discrete` permite transicionar
   `content-visibility`. Donde el navegador no las soporte el acordeón
   funciona igual, solo que sin animación. */

:root {
  interpolate-size: allow-keywords;
}

.faq__item::details-content {
  height: 0;
  opacity: 0;
  overflow: hidden;
  transition:
    height 300ms var(--ease-out),
    opacity 300ms var(--ease-out),
    content-visibility 300ms allow-discrete;
}

.faq__item[open]::details-content {
  height: auto;
  opacity: 1;
}

.faq__a {
  /* 24px de aire sobre la respuesta y 8 debajo: el resto del hueco lo
     pone el relleno del propio acordeón. */
  margin-inline: clamp(24px, 1.48vw + 17.3px, 32px);
  padding-block: 24px 8px;
  border-top: 1px solid var(--color-border-subtle);
}

.faq__a p {
  max-width: 64ch;
  /* 14 · 15 · 15 */
  font-size: clamp(0.875rem, 0.185vw + 0.833rem, 0.9375rem);
  line-height: 1.6;
  color: var(--color-text-muted);
}

/* ---- El acordeón en pantallas menores ----------------------------- */

@media (max-width: 1023px) {
  .faq {
    padding-block: 70px;
    padding-inline: 30px;
  }

  .faq .container--narrow { max-width: none; }
  .faq__title { font-size: 56px; }
}

@media (max-width: 767px) {
  .faq {
    padding-block: 60px;
    padding-inline: 20px;
  }

  /* El corte de tableta fija 56px y también alcanza aquí: se
     devuelve a los 42 que pide el encargo para móvil. */
  .faq__title { font-size: 42px; }

  .faq__item { border-radius: 10px; }
  .faq__q { padding: 24px 20px; }
  .faq__a { margin-inline: 20px; }
}

@media (prefers-reduced-motion: reduce) {
  .faq__icon,
  .faq__item,
  .faq__item::details-content {
    transition: none;
  }
}

/* ---- Cierre ------------------------------------------------------ */

.closing {
  position: relative;
  overflow: hidden;
  padding-block: calc(var(--section-y) * 1.15);
  text-align: center;
  background-color: var(--color-surface-deep);
  isolation: isolate;
}

/* Mismo criterio que en el hero: el toro es atmósfera, no ilustración.
   Nítido y detrás del titular competía con el texto en vez de
   sostenerlo. */
.closing__glow {
  position: absolute;
  z-index: -1;
  top: 52%;
  left: 50%;
  width: min(1000px, 108vw);
  height: auto;
  transform: translate(-50%, -50%);
  opacity: 0.1;
  filter: blur(6px);
  mix-blend-mode: screen;
  pointer-events: none;
}

/* El cierre necesita algo más de ancho que el resto de la columna
   estrecha para que el titular no parta en tres líneas. */
.closing .container--narrow {
  max-width: 860px;
}

.closing__title {
  font-size: var(--text-3xl);
  margin-bottom: var(--spacing-md);
}

.closing__sub {
  font-size: var(--text-lg);
  color: var(--color-text-muted);
  margin-bottom: var(--spacing-xl);
}

/* ---- Footer ------------------------------------------------------ */

.site-footer {
  padding-block: var(--spacing-2xl) var(--spacing-xl);
  border-top: 1px solid var(--color-border-subtle);
}

.site-footer__top {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--spacing-lg);
  padding-bottom: var(--spacing-lg);
}

.site-footer__logo {
  width: auto;
  height: 72px;
}

.site-footer__nav {
  display: flex;
  flex-wrap: wrap;
  gap: var(--spacing-lg);
  font-size: var(--text-sm);
  color: var(--color-text-muted);
}

.site-footer__link {
  transition: color var(--dur) var(--ease-out);
}

.site-footer__link:hover {
  color: var(--color-primary);
}

.disclaimer {
  max-width: 82ch;
  padding-top: var(--spacing-lg);
  border-top: 1px solid var(--color-border-subtle);
  font-size: var(--text-xs);
  line-height: 1.7;
  color: var(--color-text-faint);
}

.disclaimer strong {
  color: var(--color-text-muted);
}

.site-footer__legal {
  margin-top: var(--spacing-lg);
  font-size: var(--text-xs);
  color: var(--color-text-faint);
}

/* ---- Barra de compra ----------------------------------------------
   RETIRADA DE TODOS LOS TAMAÑOS. La regla de abajo la apaga en bloque y
   gana a los dos `display: flex` que la encendían más adelante, en los
   cortes de 769px y 1024px.

   El resto de las reglas se conservan a propósito: describen una pieza
   terminada y medida —70/75/80px de alto, botón de 45 a 47, respeto al
   safe area— y volver a encenderla es quitar esta regla. Si la decisión
   es definitiva, se puede borrar todo el bloque junto con el marcado y
   `activarBarraMovil()` en `js/main.js`. */

.mobile-cta {
  display: none !important;
}

.mobile-cta {
  position: fixed;
  inset: auto 0 0;
  z-index: 90;
  display: none;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  /* 70px de alto en vertical. El relleno de abajo se suma al hueco que
     reserva el sistema para el indicador de inicio del iPhone; con
     `max()` nunca baja de los 12px, esté o no ese hueco. */
  min-height: 70px;
  padding: 12px 16px max(12px, env(safe-area-inset-bottom));
  padding-left: max(16px, env(safe-area-inset-left));
  padding-right: max(16px, env(safe-area-inset-right));
  background-color: rgba(18, 18, 18, 0.94);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-top: 1px solid var(--color-border-default);
  transform: translateY(100%);
  transition: transform var(--dur) var(--ease-out);
}

.mobile-cta.is-visible {
  transform: translateY(0);
}

/* En fila, no en columna: el alto de la barra lo manda el botón, así
   que apilar "Desde" sobre el precio no ahorraba nada y dejaba dos
   renglones muy juntos. En línea se lee de un vistazo. */
.mobile-cta__text {
  display: flex;
  align-items: baseline;
  gap: 6px;
  line-height: 1.2;
  min-width: 0;
}

.mobile-cta__from {
  font-size: var(--text-xs);
  color: var(--color-text-faint);
}

.mobile-cta__price {
  font-family: var(--font-display);
  font-size: 1rem;
  font-weight: 700;
  color: var(--color-light);
  white-space: nowrap;
}

.mobile-cta__price span {
  font-size: var(--text-xs);
  font-weight: 500;
  color: var(--color-text-muted);
}

/* El botón general mide 18px de relleno arriba y abajo: 63px de alto,
   que en una barra de 70 no cabe. Aquí se aprieta a 45, por encima de
   los 44 que necesita un objetivo táctil.

   `line-height: 1` no es cosmético: el 1.8 que hereda del cuerpo daba
   21.6px de renglón y el contenido acababa midiendo 47.6, por encima
   del mínimo. Atado a 1, el que manda es `min-height` y el alto sale
   exacto: 45 + 24 de relleno + 1 de filete = 70. */
.mobile-cta .btn {
  min-height: 45px;
  padding: 10px 20px;
  font-size: var(--text-xs);
  line-height: 1;
  flex-shrink: 0;
}


/* ===================================================================
   Adaptación a pantallas menores
   =================================================================== */

@media (max-width: 860px) {
  :root {
    --header-h: 64px;
  }

  /* En vertical el retrato ocupa la banda superior y el titular se
     apoya sobre su tercio inferior, ya oscurecido por el velo. Dejar
     el texto enteramente por debajo de la foto empujaba el botón de
     compra fuera de la primera pantalla en todos los móviles, que es
     justo lo que no puede pasar en una página de venta. */
  .hero {
    min-height: auto;
    padding-block: calc(var(--header-h) + 24px) var(--spacing-2xl);
  }

  .hero__portrait {
    inset: 0 0 auto 0;
    width: 100%;
    height: 46vh;
    min-height: 260px;
  }

  .hero__portrait img {
    object-position: 62% 22%;
  }

  .hero__portrait::after {
    background: linear-gradient(
      to bottom,
      rgba(18, 18, 18, 0.2) 0%,
      rgba(18, 18, 18, 0.5) 46%,
      rgba(18, 18, 18, 0.92) 76%,
      var(--color-surface-deep) 100%
    );
  }

  .hero__copy {
    max-width: none;
    padding-top: max(150px, calc(34vh - var(--header-h)));
  }

  /* Los haces nacen en la esquina superior izquierda; en vertical esa
     esquina la ocupa el rostro del mentor y el titular. */
  .hero__beams {
    display: none;
  }

  /* En vertical no caben los cortes de línea escritos: "Aprende con
     una comunidad" necesitaría un cuerpo de 25px para entrar en 335px.
     El texto pasa a fluir y se reparte solo, conservando el naranja
     en las mismas palabras. Al ser en línea, el revelado se queda en
     desvanecido —el desplazamiento no aplica a cajas en línea—, que
     es justo lo que conviene en una pantalla pequeña. */
  .hero__title span {
    display: inline;
  }

  /* Los planes pasan a carrusel con ajuste de desplazamiento. */
  .plans {
    display: flex;
    grid-template-columns: none;
    gap: var(--spacing-md);
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    /* El desbordamiento se saca al ancho completo para que las
       tarjetas puedan asomar por los bordes de la pantalla. */
    margin-inline: calc(var(--gutter) * -1);
    padding-inline: var(--gutter);
    padding-block: var(--spacing-sm) var(--spacing-lg);
    scrollbar-width: none;
  }

  .plans::-webkit-scrollbar {
    display: none;
  }

  .plan {
    flex: 0 0 min(310px, 82vw);
    scroll-snap-align: center;
  }

  /* La etiqueta vuelve al interior de la tarjeta. En escritorio va
     montada sobre el borde superior, pero aquí el carrusel lleva
     `overflow-x` y eso recorta también en vertical: la píldora quedaba
     cortada por la mitad y sin texto. */
  .plan__tag {
    position: static;
    transform: none;
    align-self: center;
    margin-bottom: var(--spacing-xs);
  }

  /* Sin escalar dentro del carrusel: un 5% más ancha descuadra el
     ajuste de desplazamiento y la tarjeta no llega a centrarse. */
  .plan--destacado { --escala: 1; }

  /* En el carrusel la tarjeta no se eleva: el desplazamiento lateral y
     un salto vertical a la vez se pisan. */
  .plan:hover,
  .plan--destacado:hover {
    transform: none;
  }

  /* El resplandor se recorta contra el borde del carrusel; sin él la
     protagonista sigue distinguiéndose por etiqueta y borde. */
  .plan__aura {
    display: none;
  }

  .pricing__cabecera {
    margin-bottom: var(--spacing-3xl);
  }

  .plans {
    margin-bottom: var(--spacing-3xl);
  }

}

/* ---- La barra de compra: de la tableta hacia arriba ------------------
   En el móvil no se pinta nunca. En una pantalla de 390px la barra se
   come el 8% del alto durante toda la lectura y pone el precio delante
   antes de que nadie haya visto qué se compra. En vertical el recorrido
   es largo y sin atajos: quien llega abajo ha leído. Ahí el precio se
   presenta solo, en su sección, y no hace falta acompañarlo.

   De 769px en adelante hay alto de sobra para que la barra no estorbe,
   y el recorrido se hace con más salto que arrastre: tener la llamada a
   mano compensa.

   El nombre `mobile-cta` es histórico: nació como barra de móvil y ahora
   es justo lo contrario. Se conserva porque lo apuntan el JS, el `:has()`
   del botón de WhatsApp y los bancos de pruebas; renombrarlo sería mucho
   ruido para arreglar una palabra. */

@media (min-width: 769px) {
  .mobile-cta {
    display: flex;
    min-height: 75px;
    gap: 20px;
    padding-top: 14px;
    padding-bottom: max(14px, env(safe-area-inset-bottom));
    padding-left: max(20px, env(safe-area-inset-left));
    padding-right: max(20px, env(safe-area-inset-right));
  }

  .mobile-cta__from { font-size: var(--text-sm); }
  .mobile-cta__price { font-size: 1.0625rem; }
  .mobile-cta__price span { font-size: var(--text-sm); }

  /* 46 + 28 de relleno + 1 de filete = 75. */
  .mobile-cta .btn {
    min-height: 46px;
    padding: 10px 22px;
    font-size: var(--text-sm);
  }

  /* Los 96px de relleno que reservaban sitio a la barra se retiran con
     ella: sin barra que tapara el aviso de riesgo, dejaban 96px de
     vacío al final de la página. Medido a 900, 1024, 1440 y 1920. */
}

/* Escritorio: 80px y el relleno de la columna. */
@media (min-width: 1024px) {
  .mobile-cta {
    min-height: 80px;
    gap: 24px;
    padding-top: 16px;
    padding-bottom: max(16px, env(safe-area-inset-bottom));
    padding-left: max(40px, env(safe-area-inset-left));
    padding-right: max(40px, env(safe-area-inset-right));
  }

  /* 47 + 32 de relleno + 1 de filete = 80. */
  .mobile-cta .btn {
    min-height: 47px;
    padding: 10px 24px;
  }
}

/* Pantallas cortas (iPhone SE, Android de 360×740 y similares). El
   botón de compra tiene que verse sin hacer scroll: se recorta la
   banda de foto y se sube el bloque de texto sobre ella. El límite
   está en 780px de alto porque a 740px el titular de cuatro líneas
   dejaba el botón 12px por debajo del pliegue. */
@media (max-width: 860px) and (max-height: 780px) {
  .hero__portrait {
    height: 36vh;
    min-height: 200px;
  }

  /* Geist compone más ancho que la cara anterior y el titular gana un
     renglón en pantallas estrechas, lo que dejaba el botón 5px por
     debajo del pliegue. Subir el bloque 12px lo recupera con margen. */
  .hero__copy {
    padding-top: 76px;
  }

  .hero__sub {
    margin-bottom: var(--spacing-lg);
  }
}

/* Con el texto actual la cápsula mide 302px y entraría en 320px, pero
   por muy poco. Bajar el cuerpo en pantallas estrechas deja margen
   para que un texto algo más largo no la parta en dos líneas, que es
   justo lo que una cápsula no debe hacer. */
@media (max-width: 420px) {
  .eyebrow--badge {
    padding: 6px 14px;
    font-size: var(--text-xs);
  }
}

@media (max-width: 640px) {
  .brand img {
    height: 44px;
  }

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

  .rail__item {
    align-items: center;
    padding: var(--spacing-lg) 0;
  }

  .rail__item + .rail__item {
    border-left: none;
    border-top: 1px solid var(--color-border-subtle);
  }

}

/* ---- Movimiento reducido -----------------------------------------
   El contenido queda completamente visible; solo desaparece el
   movimiento, nunca la información. */

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

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    transition-delay: 0ms !important;
    scroll-behavior: auto !important;
  }

  /* Sin retirar el desenfoque explícitamente, el texto se quedaría
     fuera de foco: la transición está anulada y nada lo devolvería a
     cero. Y va `none`, no `blur(0)`, por lo mismo que la regla de
     revelado: un desenfoque de cero deja el subárbol rasterizado. */
  [data-reveal] {
    opacity: 1;
    filter: none;
    transform: none;
  }

  /* Las animaciones del hero quedan reducidas a 0.01ms por la regla
     de arriba y, al llevar `both`, se posan directamente en su estado
     final. No hace falta anularlas una por una. */
}

/* ===================================================================
   Responsividad global — los tres puntos de corte del encargo

   Móvil hasta 767px · tableta de 768 a 1023 · escritorio desde 1024.

   Las reglas de arriba siguen usando los cortes históricos del sitio
   (860, 640, 1000) porque están atadas a la geometría de cada pieza:
   el carrusel de planes salta cuando tres tarjetas dejan de caber, no
   cuando el encargo dice "tableta". Este bloque va al final, gana por
   orden y unifica lo que sí depende del dispositivo y no de la pieza.
   =================================================================== */

/* ---- Tableta: 768 a 1023 ------------------------------------------ */

@media (min-width: 768px) and (max-width: 1023px) {
  /* El diagnóstico ya tiene su propio corte en 1023 con su hueco de
     50px: si se repitiera aquí, este bloque lo pisaría por ir después. */
  .rail__inner { gap: 60px; }
}

/* ---- Móvil: hasta 767px ------------------------------------------- */

@media (max-width: 767px) {
  /* El espaciado baja un 25-30%, que es lo que pide el encargo. Se
     hace sobre los tokens y no regla a regla: así lo hereda todo. */
  :root {
    --section-y: clamp(56px, 12vw, 88px);
    --spacing-3xl: 48px;
    --spacing-4xl: 64px;
  }

  .problem__grid {
    grid-template-columns: minmax(0, 1fr);
    column-gap: 0;
    margin-block: 56px 0;
  }

  .rail__inner {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--spacing-xl);
  }

  /* Sin filete lateral en una sola columna: separa el aire. */
  .rail__item + .rail__item { border-left: 0; }

  /* Los botones ocupan el ancho entero. En una pantalla estrecha un
     botón a medias invita a dudar de si hay algo más a su lado, y
     además el área de toque crece hasta el borde. */
  .hero__actions { flex-direction: column; }

  .hero__actions .btn,
  .proceso__cta,
  .closing .btn {
    width: 100%;
  }

  /* El titular del hero deja de tener columna propia: a 390px de
     pantalla 600px de límite no recorta nada y solo estorba. */
  .hero__title { max-width: none; }
}

/* ---- El proceso en móvil ------------------------------------------
   Último bloque del archivo: gana por orden a los cortes de arriba,
   que están atados a la geometría del carril y no al dispositivo. */

@media (max-width: 767px) {
  .proceso { padding-block: 60px; }

  .proceso__lede { margin-bottom: 48px; }

  .proc__grid { row-gap: 30px; }

  .proc__paso {
    padding: 24px;
    min-height: 0;
  }

  /* Los dos lados de la ficha, a ancho completo cada uno: en una
     pantalla estrecha dos columnas de 48px de alto se quedan sin sitio
     para su propia etiqueta. */
  .pv-lados {
    grid-template-columns: minmax(0, 1fr);
    gap: 8px;
  }

  .pv-fila { padding: 14px var(--spacing-sm); }

  /* A 18px los cuatro rotulos no caben en 390px y la fila se
     desplaza. Se llega a los cuatro, pero el ultimo cortado a media
     palabra se lee como un fallo. La mascara lo desvanece contra el
     borde, y eso si se lee como que hay mas a la derecha. */
  .proc__nodos {
    -webkit-mask-image: linear-gradient(90deg, #000 82%, transparent 100%);
    mask-image: linear-gradient(90deg, #000 82%, transparent 100%);
  }
}

/* ===================================================================
   Redes sociales y WhatsApp flotante
   -------------------------------------------------------------------
   Los iconos van en SVG dentro del documento, no desde una fuente de
   iconos externa: pesan menos de 1 KB entre los tres, no añaden una
   petición que bloquee el pintado y heredan el color desde aquí.
   =================================================================== */

.redes {
  padding: 60px 40px;
  background-color: var(--color-surface-bg);
  border-top: 1px solid var(--color-border-subtle);
  text-align: center;
}

.redes__titulo {
  /* 16px en versalitas: es un rótulo, no un titular de sección. Va en
     `h2` por jerarquía del documento, no por tamaño. */
  font-family: var(--font-body);
  font-size: 1rem;
  font-weight: 500;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--color-text-muted);
  margin-bottom: 32px;
}

.redes__iconos {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 24px;
  flex-wrap: wrap;
}

/* Cada red en su color oficial. Va por variable y no directamente en
   `color` para que el cursor y el foco la hereden sin repetirla: el
   rojo de YouTube se toca en un solo sitio.

   Las redes sin color declarado —telegram y whatsapp, que todavía no
   se pintan— caen en el gris de siempre por el valor de respaldo. */
.redes__icono--youtube { --marca: #ff0000; }
.redes__icono--instagram { --marca: #e4405f; }

.redes__icono {
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  color: var(--marca, var(--color-text-faint));
  transition:
    color 300ms var(--ease-out),
    opacity 300ms var(--ease-out),
    transform 300ms var(--ease-out),
    background-color 300ms var(--ease-out);
}

.redes__icono svg {
  width: 24px;
  height: 24px;
}

@media (hover: hover) and (pointer: fine) {
  .redes__icono:hover {
    /* La que tiene color oficial lo conserva: teñirla de naranja
       borraría justo lo que la hace reconocible de un vistazo. Se
       atenúa y crece, nada más. El halo se tiñe de su propio color en
       vez del naranja fijo, por la misma razón. */
    color: var(--marca, var(--color-primary));
    background-color: color-mix(
      in srgb, var(--marca, var(--color-primary)) 8%, transparent);
    opacity: 0.8;
    transform: scale(1.15);
  }
}

/* El anillo de foco tiene que verse: son enlaces sin texto visible. */
.redes__icono:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 4px;
  color: var(--marca, var(--color-primary));
}

/* ---- El botón flotante -------------------------------------------- */

.wa {
  position: fixed;
  right: 32px;
  bottom: 32px;
  z-index: 999;
  display: flex;
  align-items: center;
  /* Aparece pasado el hero, no de entrada: ahí el botón se sienta
     encima del subtítulo. Sale desde abajo y con un punto de escala,
     que es lo que hace que se lea como que llega, no como que ya
     estaba y no lo habías visto. */
  opacity: 0;
  transform: translateY(12px) scale(0.9);
  pointer-events: none;
  transition:
    opacity 300ms var(--ease-out),
    transform 300ms var(--ease-out);
}

.wa.is-visible {
  opacity: 1;
  transform: none;
  pointer-events: auto;
}

.wa__boton {
  display: grid;
  place-items: center;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background-color: #25d366;
  /* Carbón sobre el verde da 9.4:1; el blanco se quedaría en 2.1 y no
     cumpliría. Mismo criterio que el botón naranja de comprar. */
  color: #0b2e17;
  box-shadow: 0 4px 12px rgba(37, 211, 102, 0.3);
  animation: wa-pulso 2s ease-in-out infinite;
  transition:
    transform 300ms var(--ease-out),
    box-shadow 300ms var(--ease-out);
}

.wa__boton svg {
  width: 30px;
  height: 30px;
}

@media (hover: hover) and (pointer: fine) {
  .wa__boton:hover {
    transform: scale(1.1);
    box-shadow: 0 8px 24px rgba(37, 211, 102, 0.4);
    /* El pulso se detiene con el cursor encima: ya tiene la atención,
       y seguir latiendo bajo el puntero distrae. */
    animation-play-state: paused;
  }

  .wa:hover .wa__globo {
    opacity: 1;
    transform: translateX(0);
  }
}

.wa__boton:focus-visible {
  outline: 2px solid var(--color-light);
  outline-offset: 4px;
}

.wa__globo {
  margin-right: 12px;
  padding: 8px 12px;
  border-radius: 6px;
  background-color: rgba(0, 0, 0, 0.78);
  font-size: var(--text-xs);
  /* #999 sobre negro al 78% se queda en 4.1:1 y no cumple. En blanco
     roto da 12:1 y sigue leyéndose como un globo discreto. */
  color: #e8e8e8;
  white-space: nowrap;
  opacity: 0;
  transform: translateX(6px);
  pointer-events: none;
  transition:
    opacity 300ms var(--ease-out),
    transform 300ms var(--ease-out);
}

@keyframes wa-pulso {
  0%, 100% { box-shadow: 0 4px 12px rgba(37, 211, 102, 0.3); }
  50% { box-shadow: 0 4px 20px rgba(37, 211, 102, 0.5); }
}

/* ---- Redes y WhatsApp en pantallas menores ------------------------ */

@media (max-width: 1023px) {
  .redes { padding: 50px 30px; }
  .redes__iconos { gap: 20px; }
  .redes__icono { width: 44px; height: 44px; }

  .wa { right: 28px; bottom: 28px; }
  .wa__boton { width: 52px; height: 52px; }
  .wa__boton svg { width: 28px; height: 28px; }
}

@media (max-width: 767px) {
  .redes { padding: 40px 20px; }
  .redes__iconos { gap: 16px; }
  .redes__icono { width: 40px; height: 40px; }
  .redes__icono svg { width: 20px; height: 20px; }

  /* `max()` para que el botón no caiga sobre el indicador de inicio del
     iPhone ni bajo la curva de la pantalla: donde el sistema reserva
     hueco, se respeta; donde no, se queda en los 24px de siempre.
     Cuando la barra de compra está visible manda la regla de abajo, que
     lo sube por encima de ella. */
  .wa {
    right: max(24px, env(safe-area-inset-right));
    bottom: max(24px, env(safe-area-inset-bottom));
  }

  .wa__boton { width: 50px; height: 50px; }
  .wa__boton svg { width: 27px; height: 27px; }

  /* Sin globo: no hay cursor que lo dispare y ocuparía la mitad del
     ancho de la pantalla. */
  .wa__globo { display: none; }
}

/* Aquí subía el botón de WhatsApp para no chocar con la barra de compra.
   Se retira con ella.

   No bastaba con apagar la barra: `:has()` mira la estructura del
   documento, no lo que se pinta. El JavaScript le sigue poniendo la
   clase `is-visible`, así que la regla seguía disparando y el botón
   flotaba 104px por encima de su esquina —medido a 900, 1024, 1440 y
   1920— apartándose de algo que ya no estaba. */

@media (prefers-reduced-motion: reduce) {
  .wa__boton { animation: none; }
  .redes__icono,
  .wa__boton,
  .wa__globo { transition: none; }

  /* El botón sigue apareciendo pasado el hero, pero sin deslizarse:
     aparece y ya. Se le quita el desplazamiento también al estado de
     partida, que si no daría un salto seco de 12px. */
  .wa {
    transform: none;
    transition: opacity 1ms linear;
  }
}

/* ===================================================================
   La cabecera en los tres anchos
   -------------------------------------------------------------------
   El mismo <nav> cambia de papel: fila a la derecha en escritorio y
   tableta, panel desplegable en vertical. Un solo juego de enlaces en
   el DOM, así que un lector no oye los destinos dos veces.
   =================================================================== */

@media (min-width: 768px) and (max-width: 1023px) {
  .site-header__inner { padding-inline: 30px; }
  .site-nav { gap: 32px; font-size: var(--text-xs); }
}

@media (max-width: 767px) {
  .site-header__inner { padding-inline: 20px; }

  .hamburguesa { display: flex; }

  /* El panel cuelga de la barra y ocupa el ancho entero. Se anima el
     recorte y la opacidad, no la altura: así no recalcula nada. */
  .site-nav {
    position: absolute;
    inset: var(--header-h) 0 auto;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    margin-left: 0;
    padding: var(--spacing-sm) 20px var(--spacing-lg);
    background-color: var(--color-surface-bg);
    border-bottom: 1px solid var(--color-border-subtle);
    box-shadow: 0 12px 28px rgba(0, 0, 0, 0.4);
    font-size: var(--text-sm);

    opacity: 0;
    transform: translateY(-8px);
    visibility: hidden;
    transition:
      opacity 300ms var(--ease-out),
      transform 300ms var(--ease-out),
      visibility 300ms;
  }

  .site-header.menu-abierto .site-nav {
    opacity: 1;
    transform: none;
    visibility: visible;
  }

  /* Cada destino ocupa su renglón entero: el área de toque llega de
     borde a borde y no hay que apuntar a un texto de 14px. */
  .site-nav a {
    padding-block: 16px;
    border-bottom: 1px solid var(--color-border-subtle);
  }

  /* En vertical el subrayado del cursor no aporta: no hay cursor. */
  .site-nav a::after { content: none; }

  /* `.site-nav a.site-nav__cta`, no `.site-nav__cta` a secas: el
     separador de arriba es `.site-nav a` (0,1,1) y le ganaba a la clase
     sola (0,1,0), así que el botón salía con tres lados de 2px blancos
     y el de abajo de 1px translúcido. */
  .site-nav a.site-nav__cta {
    margin-top: var(--spacing-md);
    border-bottom-width: 2px;
    border-bottom-color: var(--color-light);
    text-align: center;
  }

  .site-nav a.site-nav__cta:hover {
    border-bottom-color: var(--color-primary);
  }
}

@media (prefers-reduced-motion: reduce) {
  .site-nav,
  .hamburguesa span { transition: none; }
}
