/* ============================================================================
   iron.cat · home-v3.css — capa de composición sobre el sistema compartido.
     0. escena del hero
     1. la sección "El problema" (chasis .kibble reducido a 2 tarjetas)
     2. los tickets compartidos de coste y alimentación
     3. dos ajustes de la sección de Eva (bento podado)
   Los tokens, roles editoriales, botones, chips, tickets y resize viven en sus
   hojas compartidas. Aquí sólo queda la composición propia de Homepage V3.
   ========================================================================== */

.health-home {
  --hv3-section-gutter: var(--ic-page-gutter);
}

.hero-tag__compact { display: none; }

@media (max-width: 480px) {
  .hero--frame .hero-proof-grid {
    flex-wrap: nowrap;
    gap: 4px;
  }

  .hero--frame .hero-tag.ic-chip {
    min-width: 0;
    padding-inline: 8px;
    font-size: 9px;
    letter-spacing: 0.055em;
  }

  .hero-tag__full { display: none; }
  .hero-tag__compact { display: inline; }
}

/* Los botones de contenido viven en button-system.css. Esta hoja conserva
   únicamente adaptadores de composición propios de Homepage V3. */

/* El header ya consume `.ic-button`; esta hoja solo neutraliza el subrayado
   `::after` de v2.css:838 en `currentColor`: sobre el botón se vería como una
   raya carbón de 2 px colgando bajo el borde. */
.health-home .site-header .nav-links {
  font-family: var(--ic-font-body);
  font-size: 14px;
  font-weight: 500;
  letter-spacing: -0.01em;
}

/* Coral queda como indicador, no como texto pequeño sobre petrol: el enlace
   activo conserva contraste AA y el subrayado sigue dando la señal de marca.

   El color se HEREDA de los hermanos en vez de fijarse. Con `--ic-text-inverse`
   el activo era crema fijo, y esta cabecera cambia de fondo con el scroll: sobre
   el pill flotante quedaba crema sobre crema, 1,05:1 —medido con el scroll-spy
   en «Eva», que literalmente desaparecía del nav y dejaba su «+» suelto—. Con
   `inherit` sigue al resto del nav en cada estado y el subrayado coral de
   `v2.css:764` es el que marca la sección. */
.health-home .site-header .nav-links a.is-current {
  color: inherit;
}

.health-home .site-header .nav-links .nav-menu-cta::after {
  display: none;
}

/* El sistema compartido decide el aspecto del botón; la Home solo decide qué
   instancia vive en la barra y cuál dentro del drawer. */
.health-home .site-header .nav-links .nav-menu-cta.ic-button {
  display: none;
}

/* El enlace vive dentro de una navegación inversa que da color a todos sus
   `<a>`. Reponemos únicamente la tinta del contrato coral para que esa regla de
   composición no gane por especificidad al componente compartido. */
.health-home .site-header .nav-links .nav-menu-cta.ic-button--coral {
  color: var(--ic-color-white);
}

.health-home .site-header .nav-links .nav-menu-cta.ic-button--coral:is(:hover, :focus-visible) {
  color: var(--ic-color-sage);
}

.health-home .site-header .nav-end > .ic-button {
  justify-self: end;
}

@media (max-width: 520px) {
  .health-home .site-header .nav-end > .ic-button {
    display: none;
  }

  .health-home .site-header .nav-links .nav-menu-cta.ic-button {
    display: inline-flex;
    width: 100%;
    margin-top: 12px;
  }
}

/* ----- 0 · Escena del hero (estructura de godaylight.com) -----
   Un panel pequeño con el pelo del gato hace de ancla y tres lecturas flotan
   a su alrededor, cada una colgada de un filete fino. El marco, el vídeo y el
   menú del hero son los de siempre: esto solo ocupa el hueco de la ficha. */
.hv3-scene {
  position: absolute;
  right: clamp(52px, 7.5vw, 150px);
  bottom: clamp(150px, 21vh, 232px);
  z-index: 2;
  width: min(186px, 15vw);
  pointer-events: none;
  color: var(--ic-color-cream);
}

/* El vídeo entra muy quemado por la derecha (la ventana) y las lecturas en
   crema se perdían. En vez de un velo alrededor de la escena (se leía como un
   borrón ovalado), un scrim lateral que apaga el borde derecho del marco: da
   contraste a las lecturas y equilibra una composición que estaba desnivelada. */
/* La línea interior del marco comparte geometría con los chips: mismo radio, y
   consumiendo el MISMO token para que no se desincronicen si cambia. En v2.css
   es `clamp(12px, 1.2vw, 18px)`, que se queda solo para index.html y salud.html.
   El marco exterior conserva su radio grande: la esquina viva de la línea dentro
   de la curva del marco es deliberada. */
/* Las DOS líneas del marco al radio del chip. El marco exterior venía en 24 px
   (`--ic-radius-editorial-frame`) y la línea interior en 12 px
   (`--ic-radius-editorial-frame-inner`); ese par sigue siendo el de index.html
   y salud.html, que conservan la hero editorial. Aquí manda la esquina viva.

   Consumen el MISMO token que los chips, no un 2px suelto: si la marca cambia
   el radio de chip, el marco lo sigue. `--ic-chip-radius` está en
   iron-tokens.css:125, que es la fuente de verdad.

   El radio exterior recorta también el vídeo, porque `.hero-frame` lleva
   `overflow: clip`: es justo lo que se busca, esquinas de vídeo a escuadra. */
.hv3-hero .hero-frame,
.hv3-hero .hero-frame-border {
  border-radius: var(--ic-chip-radius, 2px);
}

.hv3-hero .hero-frame::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(
    270deg,
    rgb(var(--ic-petrol-950-rgb) / 0.74),
    rgb(var(--ic-petrol-950-rgb) / 0.42) 22%,
    rgb(var(--ic-petrol-950-rgb) / 0.12) 40%,
    rgb(var(--ic-petrol-950-rgb) / 0) 56%
  );
}

/* ----- Marcas de la casa -----
   El motivo es un GRUPO de cuatro trazos, no un icono individual. Por eso no
   usa `.ic-stroke-icon`: ese componente hace que un único SVG llene al 100 %
   un wrapper ya dimensionado y, aplicado aquí al grid completo, convertía cada
   cruz en un cuadrante de 300 px. La retícula compacta deja una sola firma en
   la esquina, lejos del copy, de la cara de Iron y de la escena de datos. */
.hv3-hero .hero-marks {
  --hv3-mark-size: clamp(28px, 2.15vw, 34px);
  top: clamp(34px, 3.1vw, 48px);
  right: clamp(34px, 3.1vw, 48px);
  z-index: 2;
  grid-template-columns: repeat(2, var(--hv3-mark-size));
  grid-auto-rows: var(--hv3-mark-size);
  width: max-content;
  height: max-content;
  gap: clamp(8px, 0.7vw, 10px);
  color: var(--ic-color-mustard);
  opacity: 0.72;
}

.hv3-hero .hero-marks > svg {
  display: block;
  width: var(--hv3-mark-size);
  height: var(--hv3-mark-size);
  overflow: visible;
  stroke-width: 1.35;
}

.hv3-hero .hero-marks > svg path {
  vector-effect: non-scaling-stroke;
}

/* En tablet se mantiene la firma 2×2, pero pasa a una escala de anotación:
   acompaña al marco y no ocupa el espacio que deja libre la escena de datos. */
@media (min-width: 821px) and (max-width: 1100px) {
  .hv3-hero .hero-marks {
    --hv3-mark-size: 22px;
    top: 26px;
    right: 26px;
    gap: 8px;
    opacity: 0.64;
  }
}

/* Refuerza el contrato móvil después de las hojas de iconos compartidas. */
@media (max-width: 820px) {
  .hv3-hero .hero-marks {
    display: none;
  }
}

/* ----- Tipografía del hero, calibrada sobre godaylight.com -----
   Su escala es CEÑIDA: h1 con line-height 1.16 y letter-spacing -0.02em, y el
   subtítulo también a 1.16 (no a 1.45 como el DS). Los bloques se separan con
   una medida constante (~42px en su escala), no con márgenes heredados. */
.hv3-hero .hero-title {
  margin: 0;
  max-width: 17ch;
  font-size: clamp(3.5rem, 5.55vw, 5rem);
  font-weight: 400;
  line-height: 0.95;
  letter-spacing: -0.035em;
}

.hv3-hero .hero-subclaim {
  margin: clamp(20px, 2.5vw, 34px) 0 0;
  max-width: 34ch;
  font-size: clamp(1rem, 1.3vw, 1.16rem);
  font-weight: 500;
  line-height: 1.26;
  letter-spacing: -0.012em;
}

.hv3-hero .hero-actions {
  margin-top: clamp(22px, 2.7vw, 36px);
}

/* ----- PANEL DE PELO (receta de brand.css:4036-4101) -----
   El pelaje es color de marca, no decoración. La superficie lleva la textura
   fija y encima una segunda capa de la MISMA imagen, más grande, enmascarada en
   diagonal y respirando muy despacio: las fibras se mueven sin que la foto
   viaje. Cambia la variante para cambiar de pelaje. */
/* PELO VIVO: `fur-motion.css` aporta textura, capas y fallback continuo.
   Homepage V3 conserva únicamente la geometría y el velo de cada escena. */
.hv3-fur {
  position: relative;
  margin: 0;
  aspect-ratio: 200 / 280;
  overflow: hidden;
  border-radius: 8px;
  box-shadow:
    0 26px 60px rgb(var(--ic-petrol-950-rgb) / 0.42),
    inset 0 0 0 1px rgb(var(--ic-cream-dim-rgb) / 0.24);
}

/* El panel del hero es CUADRADO porque es donde aterriza el recorte de la intro.
   No lleva nada escrito encima — los datos flotan fuera del panel — así que se
   deja el velo casi al mínimo y el pelaje se ve tal cual. */
.hv3-scene .hv3-fur {
  aspect-ratio: 1 / 1;
  --ic-fur-veil: linear-gradient(180deg, rgb(7 10 10 / 0.16), transparent 55%, rgb(7 10 10 / 0.14));
}

/* ----- lecturas, al modo de daylight -----
   Flotan DESNUDAS: sin filete, sin caja y sin mono. Etiqueta en sans 11px/400 y
   valor en 12px/500, las dos en crema pleno (la jerarquía la hacen el peso y el
   tamaño, no el color). Separación label→valor: 7px. */
.hv3-datum {
  position: absolute;
  display: grid;
  gap: 7px;
}

.hv3-datum-k {
  margin: 0;
  font: 600 0.66rem/1.3 var(--ic-font-mono);
  letter-spacing: 0.065em;
  color: var(--ic-color-cream);
  text-shadow: 0 1px 6px rgb(var(--ic-petrol-950-rgb) / 0.55);
}

.hv3-datum-v {
  margin: 0;
  font: 500 0.72rem/1.35 var(--ic-font-mono);
  letter-spacing: 0.025em;
  color: var(--ic-color-cream);
  text-shadow: 0 1px 7px rgb(var(--ic-petrol-950-rgb) / 0.6);
}

/* arriba, alineada al borde izquierdo del panel */
.hv3-datum--top {
  left: 0;
  bottom: calc(100% + 16px);
  width: max-content;
  max-width: 190px;
}

/* debajo del panel */
.hv3-datum--diag {
  left: 0;
  top: calc(100% + 16px);
  width: max-content;
  max-width: 200px;
}

/* las tres barras van al lado interior del panel: es el bloque más ancho y
   fuera, contra el borde del marco, se salía. */
.hv3-datum--bars {
  right: calc(100% + 24px);
  /* el panel es cuadrado, no 200/280: al 26% las barras se salían por abajo */
  top: 50%;
  translate: 0 -50%;
  width: 158px;
  gap: 12px;
}

.hv3-bars {
  display: grid;
  gap: 10px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.hv3-bars li {
  display: grid;
  gap: 6px;
}

.hv3-bars-k {
  font: 500 0.66rem/1.3 var(--ic-font-mono);
  letter-spacing: 0.025em;
  color: var(--ic-color-cream);
  text-shadow: 0 1px 6px rgb(var(--ic-petrol-950-rgb) / 0.55);
}

/* pista de la barra: crema al 30 % sobre el vídeo, como el bg-beige/40 suyo */
.hv3-bars-t {
  display: block;
  height: 5px;
  border-radius: var(--ic-radius-pill);
  background: rgb(var(--ic-cream-dim-rgb) / 0.3);
  overflow: hidden;
}

.hv3-bars-t i {
  display: block;
  width: var(--v, 50%);
  height: 100%;
  border-radius: inherit;
  background: var(--ic-color-mustard);
  /* Se llenan al entrar. `scaleX` y no `width`: animar el ancho recalcula
     layout en cada fotograma; una escala horizontal la resuelve el compositor.
     El origen a la izquierda hace que crezca desde el arranque de la pista. */
  transform-origin: 0 50%;
  animation: hv3-bar-fill 1100ms var(--ic-ease-soft, cubic-bezier(0.22, 1, 0.36, 1)) both;
}

/* Escalonadas: las tres a la vez se leen como un bloque que aparece; una detrás
   de otra se leen como tres lecturas distintas, que es lo que son. */
.hv3-bars li:nth-child(1) .hv3-bars-t i { animation-delay: 120ms; }
.hv3-bars li:nth-child(2) .hv3-bars-t i { animation-delay: 260ms; }
.hv3-bars li:nth-child(3) .hv3-bars-t i { animation-delay: 400ms; }

/* Con intro, esperan a que el telón se haya ido DEL TODO. Con `hero-in` (t=4150)
   se llenaban entre 4270 y 5650 ms, y el overlay no se retira hasta 5900: el
   usuario se perdía las tres. `hero-copy-in` se pone en done(). */
html.has-intro .hv3-bars-t i { animation-play-state: paused; }
html.hero-copy-in .hv3-bars-t i { animation-play-state: running; }

@keyframes hv3-bar-fill {
  from { transform: scaleX(0); }
  to { transform: scaleX(1); }
}

@media (prefers-reduced-motion: reduce) {
  .hv3-bars-t i { animation: none; }
}

/* lo que le falta va en coral: se lee de un golpe qué está corto */
/* Cada fila: etiqueta a la izquierda y el estado a la derecha, con el aviso
   delante. El triángulo va en `currentColor`, así que toma el color del estado
   sin repetirlo. */
.hv3-bars li { display: grid; gap: 6px; }

.hv3-bars-k {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
}

.hv3-bars-k em {
  display: inline-flex;
  align-items: center;
  font-style: normal;
  white-space: nowrap;
}

/* El glifo canónico de alerta del repo: el Lucide `triangle-alert` que ya usan
   formulario.js:57, index.html:922 y salud.html:919. DE TRAZO, no relleno —
   design.html:462 lo prohíbe explícitamente («Nada de iconos rellenos, emojis,
   ni mezclar sets. Un solo lenguaje de trazo»), y sobre este hero una mancha
   sólida de mostaza competiría con el relleno de la barra que va 6 px debajo.

   Se le quita el punto del signo (`M12 17h.01`): a 11 px es sub-píxel y solo
   ensucia. `non-scaling-stroke` es lo que lo hace legible tan pequeño — el
   grosor deja de escalar con el viewBox y se expresa en píxeles finales, la
   misma jugada de `.hero-marks` y `.ds-line-icon svg` (v2.css:311). */
.hv3-warn {
  flex: none;
  width: 11px;
  height: 11px;
  margin-right: 5px;
}

.hv3-warn svg {
  display: block;
  width: 100%;
  height: 100%;
}

/* `vector-effect` va en la FORMA, no en el `<svg>`: no se hereda y en el
   contenedor no aplica. Estaba en el `<svg>` y el `<path>` computaba `none`,
   así que el trazo escalaba con el viewBox y acababa en 0,688 px medidos
   (1,5 × 11 / 24) — exactamente el sub-píxel que este bloque quería evitar. */
.hv3-warn svg path {
  stroke-width: 1.5;
  vector-effect: non-scaling-stroke;
}

/* Dos maneras de estar fuera de rango, con la semántica de color que ya usan
   las señales del chequeo: mostaza para vigilar, coral para lo que falta. */
.hv3-bars li.is-over .hv3-bars-k em { color: var(--ic-color-mustard); }
.hv3-bars li.is-over .hv3-bars-t i { background: var(--ic-color-mustard); }

.hv3-bars li.is-low .hv3-bars-k em { color: var(--ic-color-coral); }
.hv3-bars li.is-low .hv3-bars-t i { background: var(--ic-color-coral); }

/* la escena solo cabe en pantallas anchas: por debajo manda el titular */
@media (max-width: 1100px) {
  .hv3-scene { display: none; }
}

/* ============================================================================
   1 · EL PROBLEMA — la sección USP de godaylight.com, medida y replicada
   ----------------------------------------------------------------------------
   Se midió la página real (tres sondas de Playwright + verificación) y el
   hallazgo que lo cambia todo es que LAS LÍNEAS NO SE ANIMAN: son bordes CSS
   estáticos, idénticos en las 13 posiciones de scroll muestreadas. Todo el
   efecto vive en el texto.

   La mecánica: la celda central lleva `clip-path`, y dentro va un texto
   `position: fixed; inset: 0` clavado al centro del viewport. El texto sólo se
   ve por la ventana de la celda, así que LA LÍNEA HORIZONTAL ACTÚA DE
   GUILLOTINA: al subir, corta el titular en seco a media letra. De ahí que las
   filas tengan que ser CORTAS (~400-500 px). Con filas de un viewport la
   ventana es mayor que la pantalla y no hay recorte — ni efecto.

   Retícula de Daylight a 1440: 20 | 335 | 730 | 335 | 20, derivada de unidades
   vw, así que escala con el ancho. Aquí se capa la banda para que a 2048 no se
   coma la fila (su alto sale del aspect de la banda).
   ========================================================================== */
.hv3-usp {
  --hv3-gutter: max(1.38889vw, 16px);
  --hv3-band: min(23.2639vw, 400px);
  --hv3-line: 1px solid var(--ic-border-soft);
  position: relative;
  overflow: clip;
  background: var(--ic-bg-page);
}

/* Los 180 px de padding de Daylight: los filetes verticales los cruzan, las
   horizontales no llegan. Es lo que deja la sección abierta por arriba y abajo. */
.hv3-usp-track {
  position: relative;
  margin: 0;
  padding: clamp(96px, 12vw, 180px) 0;
  list-style: none;
}

/* Filetes verticales: los cantos interiores de las dos bandas laterales.
   `z-index: 10` NO es decorativo — en Daylight el filete se pinta ENCIMA del
   canto de la imagen (verificado a nivel de píxel). Sin él, el panel lo tapa. */
.hv3-usp-track::before,
.hv3-usp-track::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  z-index: 10;
  width: var(--hv3-band);
  pointer-events: none;
}

.hv3-usp-track::before { left: var(--hv3-gutter); border-right: var(--hv3-line); }
.hv3-usp-track::after { right: var(--hv3-gutter); border-left: var(--hv3-line); }

/* Líneas horizontales A SANGRE: el `li` ocupa el ancho completo y el gutter va
   por dentro (border-box), así que el borde llega de 0 a 100 % mientras el
   contenido respeta el margen de página. Sólo la primera lleva borde superior:
   así no hay líneas dobles en las juntas. */
.hv3-usp-item {
  display: grid;
  grid-template-columns: var(--hv3-band) minmax(0, 1fr) var(--hv3-band);
  padding-inline: var(--hv3-gutter);
  border-bottom: var(--hv3-line);
}

.hv3-usp-item:first-child { border-top: var(--hv3-line); }

/* La celda: su caja es la ventana por la que se ve el texto fijo. */
.hv3-usp-cell {
  grid-column: 2;
  grid-row: 1;
  padding: clamp(40px, 4.4vw, 64px) clamp(16px, 2vw, 28px);
  text-align: center;
}

.hv3-usp-copy {
  display: grid;
  align-content: center;
  justify-items: center;
  gap: clamp(18px, 2.2vw, 28px);
  /* Sin enlaces dentro, así que se puede desactivar del todo: evita que el
     texto invisible capture clics sin pelearse con la interpolación discreta
     de `visibility`. */
  pointer-events: none;
}

.hv3-usp-eyebrow {
  margin: 0;
  font: 600 0.75rem/1.3 var(--ic-font-mono);
  letter-spacing: 0.075em;
  text-transform: uppercase;
  color: rgb(var(--ic-petrol-rgb) / 0.62);
}

/* El `max-width` es funcional, no estético: el copy fijo mide todo el viewport
   y la celda sólo la columna central, así que un titular más ancho que la
   celda saldría recortado por los lados además de por arriba. */
.hv3-usp-title {
  margin: 0;
  max-width: 15ch;
  font-family: var(--ic-font-display);
  font-size: clamp(1.9rem, 3.6vw, 3.1rem);
  font-weight: 400;
  line-height: 1.02;
  letter-spacing: -0.025em;
  color: var(--ic-text-primary);
  text-wrap: balance;
}

/* El visual llena la banda entera, a sangre y sin radio, con los cantos
   alineados al píxel con los filetes. Y es él quien fija el alto de la fila,
   igual que la foto en Daylight: el texto está fuera de flujo y no aporta. */
.hv3-usp-media {
  grid-row: 1;
  margin: 0;
  min-height: min-content;
  aspect-ratio: var(--hv3-ratio, 480 / 727);
}

.hv3-usp-media--right { grid-column: 3; }
.hv3-usp-media--left { grid-column: 1; }

.hv3-usp-media--ticket {
  aspect-ratio: auto;
}

/* El ticket mide LO QUE MIDE, y va CENTRADO en su fila.

   Con `min-height: 100%` se estiraba a la altura de la fila y el de coste —dos
   líneas— quedaba como un marco medio vacío de 622 px. Se le quitó el estirado,
   pero apoyarlo arriba (`align-self: start`) trajo el problema contrario y más
   sutil: los tickets cortos dejaban 223-227 px de hueco DEBAJO, así que el panel
   quedaba entero en pantalla ~225 px de scroll ANTES de que se abriera la
   ventana de recorte de su celda —que sí está centrada en la fila—. De ahí que
   el copy del coste pareciese llegar tarde: no llegaba tarde el texto, llegaba
   pronto el panel.

   Centrado, el panel y su titular comparten el mismo centro y entran juntos.
   Medido: el desfase del coste pasa de +175 px a +25. */
.hv3-usp-media--ticket {
  align-self: center;
}

.hv3-usp-media--ticket .ic-receipt {
  height: auto;
}

/* ----- la guillotina y el reloj -----
   El reloj es UNO SOLO y global, sobre el `<ul>` — no uno por celda. En
   Daylight es `ScrollTrigger{ trigger: ul, start:'top 52%', end:'bottom 50%',
   scrub:true }`; el equivalente exacto e independiente del viewport es
   `cover 48vh` → `cover calc(100% - 50vh)`.

   Que el reloj lo declare el `<ul>` es imprescindible: un elemento `fixed` no
   se mueve nunca respecto al viewport, así que su `view()` propio se quedaría
   plano. Como es descendiente, resuelve el del `<ul>` por nombre.

   `opacity` y `transform` van en DOS animaciones separadas porque sus curvas
   no coinciden: el desplazamiento es una rampa lineal de 200 px que queda
   clampada fuera de su tramo, y el fade son ventanas más cortas recortadas
   encima, con easing cúbico. (Los valores concretos, en los keyframes.) */
@supports (animation-timeline: view()) {
  @media (min-width: 1180px) and (prefers-reduced-motion: no-preference) {
    .hv3-usp-track {
      view-timeline-name: --hv3-usp;
      view-timeline-axis: block;
    }

    /* Las tres celdas, a la MISMA altura.

       El reloj reparte tercios exactos, pero los tres tickets miden distinto
       —542, 394 y 430 px medidos a 1440— así que una celda alta seguía en
       pantalla después de que su ventana hubiera terminado, y dejaba un hueco
       sin copy antes de que entrase la siguiente. `grid-auto-rows: 1fr` iguala
       las filas a la mayor sin fijar ningún número, así que sigue cuadrando a
       cualquier ancho. */
    .hv3-usp-track {
      display: grid;
      grid-auto-rows: 1fr;
    }

    .hv3-usp-cell { clip-path: inset(0); }

    .hv3-usp-copy {
      position: fixed;
      inset: 0;
      animation-timeline: --hv3-usp;
      animation-range: cover 48vh cover calc(100% - 50vh);
      animation-fill-mode: both;
      animation-timing-function: linear;
    }

    /* Una ventana por celda, en TERCIOS. Antes eran mitades porque solo había
       dos celdas; con la de enfermedades delante hay tres y el reparto tenía
       que rehacerse entero, o la segunda y la tercera se pisaban. */
    .hv3-usp-item:nth-child(1) .hv3-usp-copy { animation-name: hv3-usp-op-1, hv3-usp-ty-1; }
    .hv3-usp-item:nth-child(2) .hv3-usp-copy { animation-name: hv3-usp-op-2, hv3-usp-ty-2; }
    .hv3-usp-item:nth-child(3) .hv3-usp-copy { animation-name: hv3-usp-op-3, hv3-usp-ty-3; }
  }
}

/* Cúbica out al entrar, cúbica in al salir (GSAP power2 = exponente 3).

   Tres ventanas de 33,3 puntos: 8 de entrada, 15 de meseta legible y 8 de
   salida, con 2 de respiro. Con 10/10/10 la meseta de las dos primeras se
   quedaba en 270-360 px de scroll, poco para leer un titular. La tercera no
   hace fade-out —en Daylight tampoco existe ese tween—: desaparece porque la
   ventana de su celda se va de la pantalla.

   LOS 8 PUNTOS DE ENTRADA SON NUESTROS, NO DE DAYLIGHT, Y ES DELIBERADO.
   Se leyó su bundle (chunk 7103, módulo `UspMotion`): su timeline dura
   exactamente 1.0 —con un tween vacío que la fija— así que sus posiciones son
   el % del recorrido, y sus fundidos duran 0,15 anclados en .06 / .42 / .72.
   Probado aquí, 15 puntos adelantan la entrada del tercero pero producen SIETE
   posiciones de scroll con dos copys visibles a la vez: nuestras ventanas de
   recorte son más estrechas en proporción al reloj que las suyas, porque
   nuestras filas son iguales (`grid-auto-rows: 1fr`) y las suyas no —miden
   509/391/417 px—. Copiar su duración rompe el relevo. */
@keyframes hv3-usp-op-1 {
  0%, 2% { opacity: 0; animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); }
  10%, 25% { opacity: 1; animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); }
  33%, 100% { opacity: 0; }
}

@keyframes hv3-usp-ty-1 {
  0% { transform: translateY(150px); }
  30%, 100% { transform: translateY(-50px); }
}

@keyframes hv3-usp-op-2 {
  0%, 35% { opacity: 0; animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); }
  43%, 58% { opacity: 1; animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19); }
  66%, 100% { opacity: 0; }
}

@keyframes hv3-usp-ty-2 {
  0%, 27% { transform: translateY(150px); }
  63%, 100% { transform: translateY(-50px); }
}

@keyframes hv3-usp-op-3 {
  0%, 69% { opacity: 0; animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); }
  77%, 100% { opacity: 1; }
}

@keyframes hv3-usp-ty-3 {
  0%, 61% { transform: translateY(150px); }
  97%, 100% { transform: translateY(-50px); }
}

/* En estrecho, Daylight sirve otro componente: sin líneas, sin retícula y con
   el texto en flujo. Aquí, lo mismo. */
@media (max-width: 1179px) {
  .hv3-usp-track::before,
  .hv3-usp-track::after { display: none; }

  .hv3-usp-track { padding: 0; }

  .hv3-usp-item {
    grid-template-columns: minmax(0, 1fr);
    gap: 32px;
    padding: clamp(56px, 10vw, 88px) var(--hv3-section-gutter);
    border: 0;
  }

  .hv3-usp-item:first-child { border-top: 0; }

  .hv3-usp-cell {
    grid-column: 1;
    padding: 0;
  }

  .hv3-usp-media,
  .hv3-usp-media--left,
  .hv3-usp-media--right {
    grid-column: 1;
    grid-row: auto;
    aspect-ratio: auto;
    width: min(340px, 100%);
    justify-self: center;
  }
}

/* ========================================================================== 
   4 · Las funcionalidades — la mecánica de STEP de godaylight.com
   --------------------------------------------------------------------------
   Medida sobre su página. Dos cosas que no son lo que parecen:

   · El apilado de abajo arriba NO lleva ni un transform. Cada bloque va en
     flujo, muy alto, y su hijo es `sticky top: 0`: el panel siguiente sube por
     flujo normal y tapa al anterior. En 17 muestras de scroll sus `li` y
     `article` dan siempre `transform: none, scale 1`.
   · El marco es el `article`, metido por el padding del bloque anclado.

   El bloque va EN FLUJO y el `sticky` es su hijo (Daylight ancla el `li`
   directamente). Es a propósito: el reloj lo tiene que publicar algo que se
   mueva de verdad, y un `sticky` fijado no sale nunca del viewport, así que su
   `view-timeline` se quedaría plano.
   ========================================================================== */
.hv3-steps {
  --hv3-frame-gap: clamp(10px, 1.4vw, 20px);
  position: relative;
  overflow: clip;
  scroll-margin-top: 96px;
  background: var(--ic-bg-page);
}

/* ----- la portada, anclada un viewport ----- */
.hv3-steps-intro {
  position: sticky;
  top: 0;
  z-index: 1;
  display: grid;
  place-items: center;
  height: 100svh;
  overflow: clip;
}

.hv3-steps-intro-copy {
  position: relative;
  display: grid;
  justify-items: center;
  gap: clamp(16px, 2vw, 26px);
  max-width: min(100%, 46rem);
  padding-inline: var(--hv3-section-gutter);
  text-align: center;
}

.hv3-steps-eyebrow {
  margin: 0;
  font: 600 var(--ic-type-caption-size)/1.3 var(--ic-font-mono);
  letter-spacing: 0.075em;
  text-transform: uppercase;
  color: rgb(var(--ic-cream-dim-rgb) / 0.72);
}

.hv3-steps-title {
  margin: 0;
  font-family: var(--ic-font-display);
  font-size: var(--ic-type-h2-size);
  font-weight: 400;
  line-height: var(--ic-type-h2-line);
  letter-spacing: -0.025em;
  color: var(--ic-color-cream);
  text-wrap: balance;
}

.hv3-steps-lede {
  margin: 0;
  max-width: 34ch;
  font-size: var(--ic-type-body-lg-size);
  line-height: var(--ic-type-body-lg-line);
  color: rgb(var(--ic-cream-dim-rgb) / 0.84);
}

/* ----- la pila ----- */
.hv3-steps-track {
  position: relative;
  z-index: 2;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* El fondo opaco de la PISTA es el que tapa la portada cuando la pila sube. Es
   el plan B: sin animaciones de scroll, en estrecho o con movimiento reducido no
   hay velo, y sin esto la portada asomaría por el canto del marco.

   Donde sí hay velo (ver `.hv3-steps-veil`) este fondo estorba: al viajar con la
   pista mete un canto duro que barre la portada de abajo arriba, que es justo lo
   que Daylight NO hace. Allí se apaga. */
.hv3-steps-track { background: var(--ic-bg-page); }

/* Sin la rama mejorada no existe: no hay reloj que lo funda y se quedaría fijo
   tapando la portada. Ahí el relevo lo hace el fondo opaco de la pista. */
.hv3-steps-veil { display: none; }

.hv3-step-pin {
  position: sticky;
  top: 0;
  height: 100svh;
  padding: var(--hv3-frame-gap);
}

.hv3-step-frame {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  align-items: center;
  gap: clamp(24px, 4vw, 64px);
  height: 100%;
  padding: clamp(28px, 4vw, 64px);
  overflow: clip;
  border-radius: var(--ic-radius-editorial-frame);
  /* un tono por debajo del fondo de página; no hay token para esto y no se
     inventa: se tiñe el propio fondo con el petrol de marca */
  background:
    linear-gradient(rgb(var(--ic-petrol-rgb) / 0.05), rgb(var(--ic-petrol-rgb) / 0.05)),
    var(--ic-bg-page);
}

.hv3-step-copy {
  display: grid;
  justify-items: start;
  align-content: center;
}

.hv3-step-media {
  display: grid;
  place-items: center;
  height: 100%;
  min-height: 0;
}

.hv3-step-num {
  margin: 0 0 clamp(16px, 2vw, 24px);
  font: 600 var(--ic-type-caption-size)/1.3 var(--ic-font-mono);
  letter-spacing: 0.075em;
  text-transform: uppercase;
  color: rgb(var(--ic-petrol-rgb) / 0.62);
}

.hv3-step-title {
  margin: 0;
  max-width: 15ch;
  font-family: var(--ic-font-display);
  font-size: var(--ic-type-h3-size);
  font-weight: 400;
  line-height: var(--ic-type-h3-line);
  letter-spacing: -0.025em;
  color: var(--ic-text-primary);
}


.hv3-step-text {
  margin: clamp(8px, 1vw, 12px) 0 0;
  max-width: 36ch;
  font-size: var(--ic-type-body-size);
  line-height: var(--ic-type-body-line);
  color: var(--ic-text-body);
}

.hv3-step-cta { margin-top: clamp(24px, 3vw, 36px); }

.hv3-step--hero {
  --ic-resize-radius: var(--ic-radius-phone);
}

/* ----- la maqueta de móvil ----- */
.hv3-phone {
  position: relative;
  height: min(100%, 620px);
  aspect-ratio: 780 / 1688;
}

.hv3-phone-screen {
  position: absolute;
  inset: 0;
  overflow: clip;
  border-radius: var(--ic-radius-phone);
  background: var(--ic-color-petrol-950);
  box-shadow: var(--ic-shadow-floating);
  isolation: isolate;
}

/* El fondo de pantalla reutiliza la receta `.hv3-fur` entera (capa base fija +
   capa viva enmascarada en diagonal + velo). Sólo hay que soltarla de la caja
   de panel para la que se escribió. */
.hv3-steps-intro-bg.hv3-fur,
.hv3-phone-wall.hv3-fur {
  position: absolute;
  inset: 0;
  aspect-ratio: auto;
  border-radius: 0;
  box-shadow: none;
}

.hv3-phone-wall.hv3-fur {
  display: grid;
  place-items: center;
}

/* El kit es explícito: el pelo «nunca directamente detrás del logo sin una
   superficie de contraste». En la portada, a pantalla completa, el velo del
   propio kit (0,52) es el que toca. */
/* Donde va un titular grande encima, el velo suave del kit no basta. */
.hv3-steps-intro-bg.hv3-fur {
  --ic-fur-veil: linear-gradient(180deg, rgb(7 10 10 / 0.52), rgb(7 10 10 / 0.26) 54%, rgb(7 10 10 / 0.5));
}

/* Dentro del móvil, en cambio, ese mismo velo apaga el pelo del todo: a 280 px
   de ancho la fibra del grafito es finísima y el panel se lee como un
   rectángulo negro. Se rebaja al mínimo que aún sostiene el wordmark blanco.
   Nada de `filter` en el propio panel: crearía contexto de apilamiento y
   lavaría también el wordmark, que es hijo suyo. */
.hv3-phone-wall.hv3-fur {
  --ic-fur-veil: linear-gradient(180deg, rgb(7 10 10 / 0.34), rgb(7 10 10 / 0.06) 48%, rgb(7 10 10 / 0.3));
}


/* El splash usa el lockup real del sistema, no una aproximación tipográfica. */
.hv3-phone-logo {
  display: block;
  width: min(72%, 150px);
  height: auto;
  object-fit: contain;
  will-change: transform, opacity;
}

/* La pantalla entra DESPUÉS del resize. El picture completo usa el segundo
   reloj del componente compartido y barre el fondo de pelo de arriba abajo. */
.hv3-phone-screen-layer {
  position: absolute;
  z-index: 2;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  overflow: hidden;
}

.hv3-phone-shot {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 0;
}

.hv3-phone-wall.hv3-fur { z-index: 1; }

.hv3-phone-status {
  position: absolute;
  z-index: 3;
  top: 0;
  right: 0;
  left: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 30px;
  padding-inline: 14px;
  font: 500 9px/1 var(--ic-font-body);
  color: var(--ic-color-cream);
}

.hv3-phone-status-icons {
  width: 26px;
  height: 7px;
  border-radius: 2px;
  background: currentColor;
  opacity: 0.62;
}

/* ----- fase 3: la push ----- */
.hv3-phone-push {
  position: absolute;
  z-index: 4;
  top: 38px;
  right: 8px;
  left: 8px;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  border-radius: 12px;
  /* Petrol y no la superficie clara del sistema: la captura de debajo es casi
     blanca y una notificación clara sobre ella no se lee como una capa
     encima — se confunde con la propia interfaz. Es el mismo criterio que el
     aviso contextual del kit (panel petrol, tipografía crema). */
  background: rgb(var(--ic-petrol-950-rgb) / 0.94);
  color: var(--ic-color-cream);
  box-shadow: 0 12px 28px rgb(8 10 10 / 0.34);
  opacity: 0;
}

.hv3-phone-push-avatar img {
  display: block;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  object-fit: cover;
  object-position: 50% 22%;
}

.hv3-phone-push-body {
  display: grid;
  gap: 1px;
  min-width: 0;
}

.hv3-phone-push-body strong {
  font-size: 9.5px;
  font-weight: 600;
  color: var(--ic-color-cream);
}

.hv3-phone-push-body em {
  font-style: normal;
  font-size: 9px;
  color: rgb(var(--ic-cream-dim-rgb) / 0.82);
}

/* ----- fase 4: la push desplegada (el chequeo mensual, dentro del móvil) ----- */
/* Desborda la pantalla a ambos lados y se centra en vertical: dentro del móvil
   la cita de Eva quedaba en cuerpo 9 px e ilegible. Por eso el marcado la saca
   de `.hv3-phone-screen`, cuyo `overflow: clip` la recortaría. */
.hv3-phone-card {
  --hv3-card-x: 0;
  position: absolute;
  z-index: 5;
  top: 50%;
  right: -19%;
  left: -19%;
  display: grid;
  gap: 11px;
  padding: 16px 18px;
  border-radius: 16px;
  background: var(--ic-surface-raised);
  box-shadow: var(--ic-shadow-floating);
}

.hv3-phone-card-head {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: 8px;
}

.hv3-phone-card-head small {
  display: block;
  font: 400 9px var(--ic-font-mono);
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--ic-text-muted);
}

.hv3-phone-card-head strong {
  font-size: 12px;
  font-weight: 600;
  color: var(--ic-text-primary);
}

.hv3-phone-card-signals {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.hv3-phone-card-signals li {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 8px;
  background: rgb(var(--ic-petrol-rgb) / 0.06);
  font-size: 9.5px;
  color: var(--ic-text-body);
}

.hv3-phone-card-signals span {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--ic-color-sage);
}

.hv3-phone-card-signals .is-positive { background: var(--ic-color-mustard); }
.hv3-phone-card-signals .is-watch { background: var(--ic-color-coral); }

.hv3-phone-card blockquote {
  margin: 0;
  font-size: 11.5px;
  line-height: 1.5;
  color: var(--ic-text-body);
}

.hv3-phone-card blockquote p { margin: 0; }

.hv3-phone-card footer {
  display: grid;
  gap: 1px;
  padding-top: 9px;
  border-top: 1px solid var(--ic-border-soft);
  font-size: 9px;
  color: var(--ic-text-muted);
}

.hv3-phone-card footer strong { font-size: 10.5px; color: var(--ic-text-primary); }

/* Reposo (sin scroll-driven, en estrecho y con reduced-motion): la captura y la
   tarjeta de Eva, que es donde vive el copy del antiguo «chequeo mensual». */
.hv3-phone-wall { opacity: 0; }
.hv3-phone-push { opacity: 0; }
.hv3-phone-card { transform: translate(var(--hv3-card-x), -50%); }

/* En escritorio la tarjeta medía 365 px sobre un viewport de 1440 —un 25 %— y el
   cuerpo a 11,5 px. Es el remate de la sección: merece leerse sin acercarse. */
@media (min-width: 1200px) {
  .hv3-phone-card {
    right: -30%;
    left: -30%;
    gap: 13px;
    padding: 20px 22px;
    font-size: 17px;
  }

  .hv3-phone-card blockquote { font-size: 13px; }
}

/* ----- paso 3: los comentarios de Eva ----- */
.hv3-step-bubbles {
  display: grid;
  gap: clamp(12px, 1.4vw, 18px);
  width: min(380px, 100%);
}

.hv3-bubble {
  margin: 0;
  padding: 16px 18px;
  border: 1px solid var(--ic-border-default);
  border-radius: var(--ic-radius-lg) var(--ic-radius-lg) var(--ic-radius-lg) var(--ic-radius-xs);
  background: var(--ic-surface-raised);
  box-shadow: var(--ic-shadow-card);
  font-size: 0.92rem;
  line-height: 1.45;
  color: var(--ic-text-body);
}

.hv3-bubble:nth-child(2) { margin-inline-start: clamp(14px, 2.4vw, 34px); }
.hv3-bubble:nth-child(3) { margin-inline-start: clamp(28px, 4.8vw, 68px); }

/* ----- la conversación se escribe con el scroll -----
   Las tres burbujas estaban quietas: aparecían las tres a la vez con el panel,
   y el paso 3 era el único de la sección sin nada que mirar.

   El gesto tiene dos mitades, y la segunda es la que lo hace:

   1) Cada burbuja CRECE DESDE SU PICO. El radio ya declara dónde está la cola
      —`lg lg lg xs`, esquina inferior izquierda viva— así que `transform-origin:
      0 100%` la hace brotar de ahí en vez de escalar desde el centro. Es el
      gesto de un mensaje que llega, no el de una tarjeta que se desvanece.

   2) Cuando entra la siguiente, las anteriores SE REPLIEGAN: bajan a 0,955 y a
      0,92 de escala y pierden algo de tinta. Es lo que hace una conversación de
      verdad cuando se llena, y reusa el mismo verbo que el relevo de paneles
      (`hv3-frame-recede`: escala + opacidad, sin mover nada de sitio). Sin esa
      segunda mitad esto sería un fundido escalonado más.

   El easing es la misma quíntica de salida medida sobre Daylight que usan el
   resto de piezas de la sección. Sin rebote: Daylight no lo usa en ninguna de
   sus ocho piezas y aquí desentonaría.

   El escalonado deja 28 puntos entre burbuja y burbuja, con solape: la tercera
   arranca justo cuando la segunda aterriza, que es lo que da sensación de hilo
   y no de lista. Estirado hasta el 86 % del tramo para que la conversación use
   el recorrido entero del panel: con la primera versión se agotaba al 36 % y
   quedaban dos tercios de scroll sin nada. */
@keyframes hv3-bubble-1 {
  0%, 4% { opacity: 0; transform: translateY(18px) scale(0.86); }
  30% { opacity: 1; transform: translateY(0) scale(1); }
  58% { opacity: 0.9; transform: translateY(0) scale(0.955); }
  86%, 100% { opacity: 0.78; transform: translateY(0) scale(0.92); }
}

@keyframes hv3-bubble-2 {
  0%, 30% { opacity: 0; transform: translateY(18px) scale(0.86); }
  58% { opacity: 1; transform: translateY(0) scale(1); }
  86%, 100% { opacity: 0.9; transform: translateY(0) scale(0.955); }
}

@keyframes hv3-bubble-3 {
  0%, 58% { opacity: 0; transform: translateY(18px) scale(0.86); }
  86%, 100% { opacity: 1; transform: translateY(0) scale(1); }
}

/* El nombre y la cara de Eva llegan un pelín después que su burbuja: primero el
   mensaje, luego quién lo firma. */
@keyframes hv3-bubble-who-in {
  0%, 18% { opacity: 0; transform: translateX(-6px); }
  38%, 100% { opacity: 1; transform: translateX(0); }
}

.hv3-bubble-who {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: -0.01em;
  color: var(--ic-text-muted);
}

.hv3-bubble-who img {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  object-fit: cover;
  object-position: 50% 22%;
}

/* ----- el recorrido -----
   Cada bloque mide 220svh y publica su reloj. La ventana anclada (cuando el
   marco llena el viewport) va de 100svh a 220svh del rango `cover`, que es
   justo lo que se le pide a `animation-range`: así el 0-100 % de los keyframes
   es exactamente el tramo en el que el panel está quieto en pantalla. */
@supports (animation-timeline: view()) {
  @media (min-width: 901px) and (prefers-reduced-motion: no-preference) {
    .hv3-step {
      height: 220svh;
      view-timeline-name: --hv3-frame;
      view-timeline-axis: block;
    }

    /* LA SALIDA DE LA PORTADA. Medido sobre godaylight.com en el relevo de «A new
       way to power your home» → Step 1, que es el mismo momento que este.

       Allí el banner es `absolute inset-0 z-1` y NO tiene salida propia: su
       módulo (`FullscreenBannerMotion`) sólo trae entrada por líneas. Lo que lo
       hace desaparecer es `.hiw-bg`, un `fixed inset-0 z-2 bg-beige` que empieza
       en opacidad 0 y se funde a 1. Ni se mueve ni se encoge: muere tapado.

       El reparto medido (viewport 355, paso de 62 px), en cuánto ha subido ya el
       bloque de Step 1 desde que asomó por abajo:

         subido  65svh → 0      (su canto está al 35 % del viewport: el
                                 `start: "top 35%"` de su ScrollTrigger)
         subido  82svh → 0,51
         subido  99svh → 0,80   (el panel toca el borde superior)
         subido 117svh → 0,93   (ya anclado)
         subido 134svh → 0,98
         subido 152svh → 1

       O sea: el velo se funde MIENTRAS el panel sube, y cierra justo cuando el
       panel lleva medio viewport anclado. El clip de la maqueta no empieza a
       abrirse hasta ese punto — primero muere la portada, después se abre el
       producto. Por eso los dos gestos no se pisan.

       El easing de su código es `power4.out`, pero sobre una ventana distinta de
       la nuestra (su tween dura 0,5 de un reloj de 3,4 que abarca los tres
       bloques). Ajustando la curva OBSERVADA a esta ventana de 87svh, la que
       clava los cinco puntos con error < 0,03 es la cúbica de salida — la misma
       que ya usa el resto de la sección. Con `power4.out` se iba 0,07 alta en
       todo el tramo: el velo cerraba antes de que el panel llegara arriba.

       DÓNDE VIVE. En Daylight es un plano suelto `fixed inset-0 z-2` que, una vez
       en opacidad 1, YA NO SE VA: sigue ahí hasta el final de la página. Se lo
       pueden permitir porque todas sus secciones posteriores van a `z-3`, así que
       el velo les queda debajo de todo, como un fondo permanente.

       Copiarlo literal aquí deja la página en blanco: probado, de la sección de
       precios al footer no se ve nada salvo el header. Nuestras secciones no
       están escalonadas por z-index y no tiene sentido escalonarlas para esto.

       Así que el velo va DENTRO de la portada, que ya está anclada a pantalla
       completa: cubre exactamente lo mismo mientras hace falta y se va con ella
       sin tocar nada de lo que viene después. De regalo, la portada es `sticky`
       con `z-index: 1`, o sea contexto de apilamiento propio: el velo no puede
       pintar por encima de la pista (z-2) ni queriendo. Tapa la portada y sólo
       la portada, que es justo el encargo.

       El reloj no puede ser el `--hv3-frame` del bloque, que no es antepasado
       suyo, así que la sección publica el suyo. Como la portada mide 100svh
       exactos, «el bloque ha subido X» es «la sección ha subido X + 100svh»: los
       65→152svh medidos en Daylight se convierten en 165→252svh. */
    .hv3-steps {
      view-timeline-name: --hv3-cover;
      view-timeline-axis: block;
    }

    .hv3-steps-veil {
      display: block;
      position: absolute;
      inset: 0;
      z-index: 3;
      background: var(--ic-bg-page);
      opacity: 0;
      pointer-events: none;
      animation-name: hv3-steps-veil-in;
      animation-timeline: --hv3-cover;
      animation-range: cover 165svh cover 252svh;
      animation-fill-mode: both;
      animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
    }

    /* Con velo, el fondo de la pista sobra y además hace daño: es el canto duro
       que hoy barre la portada de abajo arriba. */
    .hv3-steps-track { background: none; }

    /* EL RELEVO. Medido sobre godaylight.com con paso de 180 px: el bloque que
       sale se escala de 1 a 0,9 CON ORIGEN ARRIBA y se apaga hasta 0 — no hasta
       un valor intermedio — a lo largo de 1.570 px, mientras el siguiente sube
       por flujo normal sin un solo transform.

       Va sobre el bloque anclado entero (su `li`), no sobre el marco: al
       encogerse desde el borde superior, el canto inferior se levanta y deja ver
       antes al que llega. Ese detalle es la mitad del efecto.

       El rango termina en `cover 320svh`, que es exactamente el instante en que
       el siguiente queda anclado: el saliente llega a 0 justo entonces. */
    /* En Daylight el `li` es a la vez el elemento anclado y mide 220lvh, así que
       su rectángulo de anclado es el `ul` entero y el panel NO se despega: se
       queda quieto encogiendo mientras el siguiente lo tapa (medido: su marco
       sigue en 20..880 durante todo el relevo).

       Aquí el anclado es un hijo, así que su recorrido acaba con el bloque y el
       panel se iba hacia arriba a mitad del relevo. El margen negativo ensancha
       ese rectángulo justo lo que falta —100svh— para que aguante fijado hasta
       que el siguiente queda anclado, que es cuando llega a opacidad 0. */
    .hv3-step-pin { margin-bottom: -100svh; }

    .hv3-step:not(:last-child) .hv3-step-pin {
      transform-origin: 50% 0;
      animation-name: hv3-frame-recede;
      animation-timeline: --hv3-frame;
      animation-range: cover 190svh cover 320svh;
      animation-fill-mode: both;
      animation-timing-function: linear;
    }

    /* El paso 1 retira su panel MÁS TARDE que los otros dos.

       La tarjeta de «Mensaje de Eva» es la última fase de esta maqueta y vive
       en cover 226→280svh, o sea ENTERA dentro del relevo genérico que arranca
       en 190svh y apaga el `.hv3-step-pin` completo. Su propia opacidad sí
       llegaba a 1, pero la efectiva —la suya por la del pin— tenía techo 0,71 y
       solo pasaba de 0,6 durante unos 16svh: 144 px de scroll a 900 de alto. Por
       eso «casi no se ve».

       Retrasando el relevo a 250svh, la tarjeta entra con el panel todavía
       opaco, tiene meseta y decae después. La ventana con opacidad efectiva
       ≥0,6 pasa de ~16svh a ~52svh, y la sección no se alarga ni un píxel: el
       relevo sigue terminando en cover 320svh, que es justo cuando el panel
       siguiente queda anclado.

       Especificidad: hace falta `:not(:last-child)` también aquí. Sin él el
       selector sería (0,2,0) y perdería contra el genérico de arriba, que es
       (0,3,0); con él empatan y gana este por orden. */
    .hv3-step--hero:not(:last-child) .hv3-step-pin {
      animation-range: cover 250svh cover 320svh;
    }

.hv3-step--hero :is(
      .hv3-phone-logo,
      .hv3-phone-status,
      .hv3-phone-wall,
      .hv3-phone-push,
      .hv3-phone-card
    ) {
      animation-timeline: --hv3-frame;
      /* la ventana de anclado del paso alargado: de `cover 100svh` a
         `cover 280svh` */
      animation-range: cover 100svh cover 280svh;
      animation-fill-mode: both;
      animation-timing-function: linear;
    }

    /* El wordmark y la barra de estado YA NO van por aquí: los lleva
       resize-motion.js, que es el reloj de la apertura del clip. Tenerlos en dos
       relojes distintos era el defecto — se medía el fondo de pantalla en
       opacidad 0 durante TODO el recorrido y las piezas llegaban a la vez. */
    .hv3-step--hero .hv3-phone-push { animation-name: hv3-push-in; }
    .hv3-step--hero .hv3-phone-card { animation-name: hv3-card-open; }

    /* Paso 3 · la conversación. Mismo reloj y mismo tramo que la maqueta del
       paso 1 —`cover 100svh cover 220svh`, que es exactamente mientras el panel
       está quieto en pantalla— así que las dos secciones respiran igual. */
    .hv3-step-bubbles .hv3-bubble {
      transform-origin: 0 100%;
      animation-timeline: --hv3-frame;
      animation-range: cover 100svh cover 220svh;
      animation-fill-mode: both;
      animation-timing-function: cubic-bezier(0.22, 1, 0.36, 1);
      animation-timing-function: linear(0 0%, 0.11425 2.397%, 0.21782 4.795%, 0.32077 7.444%, 0.41258 10.094%, 0.49418 12.743%, 0.56646 15.393%, 0.63647 18.321%, 0.69713 21.25%, 0.75178 24.323%, 0.79825 27.395%, 0.84122 30.791%, 0.87654 34.188%, 0.90656 37.755%, 0.93264 41.698%, 0.95254 45.642%, 0.96875 50%, 0.98583 57.313%, 0.99562 66.25%, 0.99939 77.219%, 1 100%);
      will-change: transform, opacity;
    }

    .hv3-step-bubbles .hv3-bubble:nth-child(1) { animation-name: hv3-bubble-1; }
    .hv3-step-bubbles .hv3-bubble:nth-child(2) { animation-name: hv3-bubble-2; }
    .hv3-step-bubbles .hv3-bubble:nth-child(3) { animation-name: hv3-bubble-3; }

    .hv3-step-bubbles .hv3-bubble-who {
      animation-name: hv3-bubble-who-in;
      animation-timeline: --hv3-frame;
      animation-range: cover 100svh cover 220svh;
      animation-fill-mode: both;
      animation-timing-function: cubic-bezier(0.22, 1, 0.36, 1);
    }
  }
}

@keyframes hv3-steps-veil-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes hv3-frame-recede {
  0% { opacity: 1; transform: scale(1); animation-timing-function: cubic-bezier(0.45, 0, 0.55, 1); }
  100% { opacity: 0; transform: scale(0.9); }
}

/* ----- el relevo pelo → pantalla -----
   El pelo permanece entero durante TODO el crecimiento. Solo el segundo reloj,
   que empieza cuando el teléfono ya está abierto, lo retira mientras la captura
   avanza. Esta separación es lo que hace legible el resize. */
.hv3-phone-wall {
  opacity: calc(1 - var(--ic-resize-screen-progress, 1));
}

@media (prefers-reduced-motion: reduce) {
  .hv3-phone-wall { opacity: 0; }
}

/* entra, se sostiene, y cede el sitio a la tarjeta */
/* Retrasadas para que NO pisen el relevo del fondo de pantalla, que termina
   sobre el 64 % de este reloj. Antes la push entraba en el 52 %, encima del
   fundido: se veían a la vez la captura, el pelo a media opacidad y el aviso de
   Eva, y el fotograma no se entendía. Daylight deja 85 px limpios entre que la
   maqueta acaba de montarse y empieza lo siguiente; esto es el equivalente.

   El easing es `power4.out`, el mismo con el que entran las piezas de Daylight:
   una desaceleración pura, sin rebote. En CSS, `cubic-bezier(0.22, 1, 0.36, 1)`.
   Antes iba todo `linear`, que es exactamente lo que hacía que se sintiera
   mecánico. */
@keyframes hv3-push-in {
  0%, 40% { opacity: 0; transform: translateY(-30px) scale(0.96); animation-timing-function: cubic-bezier(0.22, 1, 0.36, 1); animation-timing-function: linear(0 0%, 0.11425 2.397%, 0.21782 4.795%, 0.32077 7.444%, 0.41258 10.094%, 0.49418 12.743%, 0.56646 15.393%, 0.63647 18.321%, 0.69713 21.25%, 0.75178 24.323%, 0.79825 27.395%, 0.84122 30.791%, 0.87654 34.188%, 0.90656 37.755%, 0.93264 41.698%, 0.95254 45.642%, 0.96875 50%, 0.98583 57.313%, 0.99562 66.25%, 0.99939 77.219%, 1 100%); }
  54%, 62% { opacity: 1; transform: translateY(0) scale(1); }
  70%, 100% { opacity: 0; transform: translateY(-4px) scale(0.985); }
}

/* La tarjeta arranca en el 70 %, exactamente cuando la push llega a 0. Cero
   solape: antes se cruzaban durante 80 px con las dos a media opacidad, dos
   mensajes de Eva encimados que no se leían como uno sustituyendo al otro.
   Y termina en el 80 %. El panel se retira a partir de cover 250svh,
     retrasado a propósito para que la tarjeta llegue a verse entera. */
@keyframes hv3-card-open {
  0%, 70% { opacity: 0; transform: translate(var(--hv3-card-x), calc(-50% + 12px)) scale(0.94); animation-timing-function: cubic-bezier(0.22, 1, 0.36, 1); animation-timing-function: linear(0 0%, 0.11425 2.397%, 0.21782 4.795%, 0.32077 7.444%, 0.41258 10.094%, 0.49418 12.743%, 0.56646 15.393%, 0.63647 18.321%, 0.69713 21.25%, 0.75178 24.323%, 0.79825 27.395%, 0.84122 30.791%, 0.87654 34.188%, 0.90656 37.755%, 0.93264 41.698%, 0.95254 45.642%, 0.96875 50%, 0.98583 57.313%, 0.99562 66.25%, 0.99939 77.219%, 1 100%); }
  80%, 100% { opacity: 1; transform: translate(var(--hv3-card-x), -50%) scale(1); }
}

/* En estrecho los pasos 2 y 3 pasan a flujo normal. La funcionalidad 1 conserva
   un recorrido sticky propio para que el resize compartido tenga espacio real
   para completar el gesto, también con touch y sin depender del hover. */
@media (max-width: 900px) {
  .hv3-steps-intro {
    position: static;
    height: auto;
    min-height: 62svh;
    padding-block: clamp(64px, 14vw, 120px);
  }

  .hv3-step-pin {
    position: static;
    height: auto;
    padding: 0;
    background: none;
  }

  .hv3-step-frame {
    grid-template-columns: minmax(0, 1fr);
    height: auto;
    gap: 32px;
    padding: clamp(28px, 7vw, 48px) var(--hv3-section-gutter);
    border-radius: 0;
  }

  .hv3-phone { height: auto; width: min(280px, 76%); }

  /* En tablet la tarjeta de Eva se quedaba con la geometría de escritorio
     (`right/left: -19%`, 328 px sobre un móvil de 238) y, peor, VISIBLE DESDE EL
     PRIMER MOMENTO: `hv3-card-open` vive dentro de `@media (min-width: 901px)`,
     así que por debajo no se aplicaba y `animation-fill-mode: both` no tenía
     nada que sostener — mandaba el estado base, opacidad 1. Los overrides que
     sí la encogían estaban detrás de `landscape` + altura corta, o sea que un
     tablet en vertical nunca los veía.

     Aquí se arregla lo uno y lo otro. La entrada cuelga del progreso CRUDO de
     `resize-motion.js`, que sí corre por debajo de 901 px (tiene su propia
     configuración móvil) y que ya gobierna la apertura de la pantalla en este
     mismo paso: así la tarjeta llega cuando la maqueta ya está montada, igual
     que en escritorio, y no antes.

     El umbral es 0,95 y no algo más holgado porque en tablet ese reloj va MUY
     comprimido: arranca ya en 0,5 cuando empieza el paso y se agota al 33 %
     (medido a 768×1024). Con 0,72 la tarjeta entraba a la vez que se retiraba
     el fondo de pantalla —raw 0,87-0,95— y se veían las dos cosas encimadas. */
  .hv3-step--hero .hv3-phone-card {
    --hv3-card-x: -50%;
    right: auto;
    left: 50%;
    width: min(300px, 118%);
    padding: 12px 14px;
    gap: 8px;
    font-size: 10px;
    opacity: clamp(0, calc((var(--ic-resize-raw-progress, 1) - 0.95) * 20), 1);
    transform: translate(
      var(--hv3-card-x),
      calc(-50% + (1 - clamp(0, (var(--ic-resize-raw-progress, 1) - 0.95) * 20, 1)) * 10px)
    );
  }

  @media (prefers-reduced-motion: reduce) {
    .hv3-step--hero .hv3-phone-card {
      opacity: 1;
      transform: translate(var(--hv3-card-x), -50%);
    }
  }

  .hv3-step--hero {
    --hv3-sticky-header-offset: clamp(72px, 10svh, 88px);
    height: 210svh;
  }

  .hv3-step--hero .hv3-step-pin {
    position: sticky;
    top: var(--hv3-sticky-header-offset);
    height: calc(100svh - var(--hv3-sticky-header-offset));
    padding: var(--hv3-frame-gap);
  }

  .hv3-step--hero .hv3-step-frame {
    grid-template-rows: auto minmax(0, 1fr);
    height: 100%;
    gap: clamp(16px, 3.2vh, 28px);
    padding: clamp(24px, 4.5vh, 40px) var(--hv3-section-gutter) clamp(14px, 2.5vh, 24px);
    border-radius: var(--ic-radius-editorial-frame);
  }

  .hv3-step--hero .hv3-step-copy {
    align-content: start;
  }

  .hv3-step--hero .hv3-step-num {
    margin-bottom: 10px;
  }

  .hv3-step--hero .hv3-step-title {
    font-size: clamp(1.8rem, 8vw, 2.5rem);
  }

  .hv3-step--hero .hv3-step-text {
    max-width: 42ch;
    margin-top: 8px;
    font-size: clamp(0.84rem, 3.5vw, 1rem);
    line-height: 1.42;
  }

  .hv3-step--hero .hv3-step-cta {
    display: none;
  }

  .hv3-step--hero .hv3-step-media {
    min-height: 0;
  }

  .hv3-step--hero .hv3-phone {
    width: min(238px, 58vw);
    max-height: 50svh;
  }
}

@media (max-width: 420px) and (max-height: 720px) {
  .hv3-step--hero .hv3-step-frame {
    gap: 12px;
    padding-block: 18px 10px;
  }

  .hv3-step--hero .hv3-step-text {
    display: none;
  }

  .hv3-step--hero .hv3-phone {
    width: min(218px, 56vw);
    max-height: 58svh;
  }
}

/* En horizontal la altura, no la anchura, es el límite. El mismo componente
   se reparte en dos columnas y reduce solo el copy secundario: así el teléfono
   y la tarjeta de Eva permanecen completos dentro del frame sticky. */
@media (max-width: 900px) and (max-height: 600px) and (orientation: landscape) {
  .hv3-step--hero {
    --hv3-sticky-header-offset: 64px;
  }

  .hv3-step--hero .hv3-step-frame {
    grid-template-columns: minmax(0, 0.85fr) minmax(220px, 1fr);
    grid-template-rows: minmax(0, 1fr);
    align-items: center;
    gap: clamp(14px, 3vw, 28px);
    padding: 12px var(--hv3-section-gutter);
  }

  .hv3-step--hero .hv3-step-num {
    margin-bottom: 6px;
  }

  .hv3-step--hero .hv3-step-title {
    font-size: clamp(1.5rem, 4vw, 2rem);
  }

  .hv3-step--hero .hv3-step-text {
    display: none;
  }

  .hv3-step--hero .hv3-step-media {
    overflow: visible;
  }

  .hv3-step--hero .hv3-phone {
    width: auto;
    height: min(68svh, 270px);
    max-height: none;
  }

  .hv3-step--hero .hv3-phone-card {
    --hv3-card-x: -50%;
    right: auto;
    left: 50%;
    width: min(240px, 220%);
    gap: 7px;
    padding: 10px 12px;
    font-size: 9px;
  }

  .hv3-step--hero .hv3-phone-card blockquote {
    font-size: 9.5px;
    line-height: 1.35;
  }
}

@media (max-width: 600px) and (max-height: 340px) and (orientation: landscape) {
  .hv3-step--hero .hv3-step-frame {
    grid-template-columns: minmax(0, 0.76fr) minmax(190px, 1fr);
    gap: 10px;
    padding-block: 8px;
  }

  .hv3-step--hero .hv3-step-title {
    font-size: 1.35rem;
  }

  .hv3-step--hero .hv3-phone {
    height: min(62svh, 206px);
  }

  .hv3-step--hero .hv3-phone-card {
    width: min(220px, 226%);
    gap: 5px;
    padding: 8px 10px;
  }

  .hv3-step--hero .hv3-phone-card blockquote {
    display: none;
  }

  .hv3-step--hero .hv3-phone-card footer {
    padding-top: 5px;
  }
}

/* ==========================================================================
   INTRO DE CARGA — el pelo a pantalla completa se cierra sobre el hero
   --------------------------------------------------------------------------
   Copiado de la intro de godaylight.com, medida sobre su página: un visual a
   pantalla completa con `clip-path: inset(0)` que se cierra hasta un
   rectángulo — allí `inset(30% 15% 30% 67.15%)` en ~2050 ms, con arranque
   lentísimo y cola larga — y el header bajando desde −150 % con expo-out,
   solapando el último tercio del cierre.

   Aquí el destino es CUADRADO y coincide al píxel con el panel de pelo del
   hero, que el script mide en runtime.

   El overlay se funde en los últimos 400 ms en vez de desaparecer en seco: su
   pelo está a tamaño viewport y el del hero es `cover` sobre 186 px, así que
   el encuadre de la textura no es el mismo y un corte limpio se vería como un
   salto. Con las dos capas en grafito, el fundido lo hace invisible.
   ========================================================================== */
.hv3-intro {
  position: fixed;
  inset: 0;
  z-index: 3000;
  display: grid;
  place-items: center;
  overflow: hidden;
  background: var(--ic-color-petrol-950);
  pointer-events: none;
  clip-path: inset(0 round 0);
}

/* el pelo reutiliza la receta del kit; sólo se suelta de la caja de panel */
.hv3-intro-fur.hv3-fur {
  position: absolute;
  inset: 0;
  aspect-ratio: auto;
  border-radius: 0;
  box-shadow: none;
}

/* El pelaje dorado es CLARO justo en el centro, que es donde va el wordmark en
   crema: con el velo lineal del kit (0,24 a media altura) el logotipo se perdía
   del todo. El kit lo advierte literalmente — el pelo «nunca directamente detrás
   del logo sin una superficie de contraste» (brand.html:502).

   Esa superficie es el degradado radial: oscurece una elipse centrada donde cae
   el texto y se disuelve antes del borde, así que el pelaje sigue viéndose
   brillante en las esquinas y el logotipo tiene fondo. El lineal se rebaja para
   que sumados no aplanen la textura. */
.hv3-intro-fur.hv3-fur {
  /* Las DOS capas con la misma textura, y no dorado + topo como el resto de
     superficies. A pantalla completa la capa secundaria tardaba 49-162 ms más
     que el primer pintado en rasterizarse a su escala (1785×1116 px), y entraba
     de golpe al 55 % de opacidad: un escalón medido de 9,72 MAD contra 0,405 de
     mediana entre fotogramas, o sea 24× el ruido. No es la red ni el decode
     —los bytes están cerrados antes del primer pintado y forzar `decode()` no
     cambia nada, verificado— sino la primera rasterización de ESA imagen.
     Con la textura que ya está en pantalla, el escalón baja a ~2,5. */
  --ic-fur-layer: url("assets/iron-cat/textures/fur-golden-illustrated.webp");
  --ic-fur-veil:
    radial-gradient(60% 44% at 50% 50%, rgb(7 10 10 / 0.66), rgb(7 10 10 / 0.3) 58%, rgb(7 10 10 / 0) 82%),
    linear-gradient(180deg, rgb(7 10 10 / 0.44), rgb(7 10 10 / 0.14) 52%, rgb(7 10 10 / 0.42));
}

/* UNA SOLA IMAGEN DE PELO, y que no se sustituya por otra a media carga.

   Dos problemas encadenados, los dos medidos.

   1) La receta del kit apila TRES copias del mismo dibujo a magnificaciones
      distintas —el fondo del elemento a 1,00×, el `::before` a ~1,30% (inset -7%
      + scale 1.14) y el hijo `<i>` a ~1,43× (inset -12% + scale 1.15)—, las dos
      últimas enmascaradas y derivando en sentidos opuestos con periodos de 14 s
      y 21 s. El mismo dibujo reconocible a tres tamaños deslizándose: eso es la
      doble exposición.

   2) Aunque se deje una sola capa CSS, sigue habiendo un cambio de imagen: la
      textura CSS es el JPG nítido y el lienzo WebGL es un render pictórico,
      MUY distintos entre sí. Al llegar el lienzo se cruzaban y eso es lo que se
      ve como parpadeo. No lo cazaba la métrica de brillo —el salto entre
      fotogramas era de solo 2,76 sobre una mediana de 0,65— porque lo que cambia
      no es la luminancia sino la ESTRUCTURA.

   La solución es que la intro no llegue a enseñar nunca la versión CSS. Arranca
   como un plano de color y el lienzo entra encima: una sola imagen, que aparece
   una vez.

   El color no es decorativo. Calibrado a dos puntos contra el velo (con fondo
   negro el resultado es rgb(2,9 4,1 4,1) y con blanco rgb(153,5 154,7 154,7),
   o sea una transmitancia de 0,591): `rgb(129 110 90)` se ve como
   rgb(79,0 69,1 57,3), que es EXACTAMENTE el color medio del render final,
   rgb(79 69 57). Así el lienzo solo añade textura, no un escalón de brillo. */
.hv3-intro-fur.hv3-fur {
  background-color: rgb(129 110 90);
  background-image: none;
}

.hv3-intro-fur.hv3-fur > i {
  display: none;
}

.hv3-intro-fur.hv3-fur::before {
  inset: 0;
  opacity: 0;
  -webkit-mask-image: none;
  mask-image: none;
}

/* RED DE SEGURIDAD, sin JS. Si a los 900 ms no ha llegado el lienzo —WebGL no
   disponible, contexto perdido, `prefers-reduced-motion`— entra la textura CSS
   para que la intro no se quede en un plano liso. Y si el lienzo llega antes,
   el selector deja de casar, la animación desaparece y ese fundido no se ve
   nunca: no hace falta coordinarlo desde JS. */
.hv3-intro-fur.hv3-fur:not(.fur-field-ready)::before {
  animation-name: ic-fur-primary-flow, hv3-intro-fallback-in;
  animation-duration: 14s, 700ms;
  animation-timing-function: linear, linear;
  animation-iteration-count: infinite, 1;
  animation-delay: -7s, 900ms;
  animation-fill-mode: none, forwards;
}

/* Con lienzo, la capa CSS se queda a cero y no se toca.

   Hay que declararlo: la regla genérica `.ic-fur-live.fur-field-ready::before`
   (fur-motion.css:86-95) le pondría `fur-field-layer-out`, que funde DESDE 0,82
   —el valor de la receta del kit—, así que la capa saltaría a 0,82 y se haría
   visible justo cuando ya no debe. Dejando solo el ciclo de deriva, la opacidad
   declarada manda porque ninguna animación la toca. */
.hv3-intro-fur.hv3-fur.fur-field-ready::before {
  animation-name: ic-fur-primary-flow;
  opacity: 0;
}

@keyframes hv3-intro-fallback-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

/* EL VELO, POR ENCIMA DEL LIENZO.

   Aquí estaba el parpadeo de verdad. `.ic-fur-live::after` —la elipse oscura
   que da fondo al wordmark— va a `z-index: -1`, y el `<canvas>` a `0`
   (fur-motion.css:49). O sea que al llegar el lienzo, el velo DESAPARECE
   debajo. Visto en la tira de contactos: a 397 ms hay una elipse oscura
   centrada y a 549 ms ya no está. Un cambio de composición en mitad de la
   pantalla, justo detrás del logotipo, que es donde está mirando el usuario.

   Subiéndolo a `z-index: 1` el velo queda sobre el lienzo y por debajo del
   wordmark —que es hermano del panel, no hijo, así que no entra en este
   contexto de apilamiento—. La elipse ya no se mueve en toda la intro, y de
   paso se cumple lo que exige el kit: el pelo nunca directamente detrás del
   logo sin superficie de contraste (brand.html:502). */
.hv3-intro-fur.hv3-fur::after {
  z-index: 1;
}

/* Y el lienzo entra LINEAL, no con `ease-soft`.

   La curva compartida (cubic-bezier(0.22, 1, 0.36, 1)) está pensada para
   movimiento: a un 20 % del tiempo ya ha recorrido el 80 % del recorrido. En
   una opacidad eso convierte un fundido nominal de 760 ms en un pop de ~150 ms,
   que es como se veía el pelo entrar de golpe. Lineal y algo más largo, la
   textura se resuelve poco a poco sobre el plano —que ya está en el color
   final, así que no hay salto de brillo, solo detalle que aparece—. */
.hv3-intro-fur.hv3-fur.fur-field-ready > .fur-field-canvas {
  animation-duration: 1200ms;
  animation-timing-function: linear;
}

/* No hay clase de logotipo en el kit: el único precedente de «iron.cat» en
   tipografía es el h1 del hero de brand.css (Fraunces 400, -0.02em). */
.hv3-intro-word {
  position: relative;
  margin: 0;
  font-family: var(--ic-font-display);
  font-size: clamp(2.6rem, 6.4vw, 5rem);
  font-weight: 400;
  letter-spacing: -0.02em;
  line-height: 1;
  color: var(--ic-color-cream);
  opacity: 0;
  transform: translateY(14px);
  transition:
    opacity 260ms linear,
    transform 760ms var(--ic-ease-soft);
}

.hv3-intro.is-in .hv3-intro-word {
  opacity: 1;
  transform: translateY(0);
}

/* el wordmark se va ANTES de que el recuadro empiece a cerrarse */
.hv3-intro.is-word-out .hv3-intro-word {
  opacity: 0;
  transform: translateY(-10px);
  transition:
    opacity 320ms linear,
    transform 420ms var(--ic-ease-soft);
}

/* El cierre. La curva reproduce la de Daylight: casi inmóvil al principio,
   tramo rápido en medio y cola larguísima — una expo in-out. El `clip-path`
   de destino lo escribe el script en línea. */
.hv3-intro.is-closing {
  opacity: 0;
  transition:
    clip-path var(--ic-duration-page-intro) var(--ic-ease-page-intro),
    opacity 350ms linear 1700ms;
}

/* Sin panel donde aterrizar (bajo 1100px la escena del hero no existe) no hay
   recorte: la intro se limita a irse. */
.hv3-intro.is-fading {
  opacity: 0;
  transition: opacity 620ms var(--ic-ease-soft);
}

/* ----- el header entra desde arriba -----
   En v2.css el header está visible desde el primer frame (`transform: none`) y
   sólo la marca espera al FLIP del logo. Aquí entra entero, como en Daylight:
   arranca fuera por arriba y baja con expo-out cuando el cierre ya va por su
   último tercio. */
html.has-intro .site-header--flat {
  transform: translateY(-150%);
  transition: transform var(--ic-duration-header-enter) var(--ic-ease-page-enter);
}

html.has-intro.intro-header-in .site-header--flat {
  transform: translateY(0);
}

/* Sin FLIP no hay logo que aterrice, así que la marca no tiene por qué esperar:
   v2.css:5742 la deja a opacidad 0 mientras exista el overlay, y aquí nunca se
   le pondría `.intro--leaving` para devolvérsela. */
html.has-intro body:has(.hv3-intro) .site-header--flat .brand { opacity: 1; }

/* El frame del hero ya NO sube desde abajo: la intro se cierra SOBRE él, así
   que tiene que estar en su sitio desde el primer frame o el recorte revelaría
   una página vacía. (v2.css:5745-5752 lo sigue animando para index.html y
   salud.html, que conservan la intro anterior.) */
html.has-intro .hv3-hero .hero-frame { animation: none; }

.health-billing-toggle button { min-height: 44px; }

@media (max-width: 640px) {
  .health-plan-list { grid-template-columns: minmax(0, 1fr); }
  .health-plan-list li:nth-child(2) { border-top: 1px dashed var(--ic-border-default); }
  .health-plan-list small { display: block; }
}

@media (prefers-reduced-motion: reduce) {
  .hv3-intro { display: none; }
  html.has-intro .site-header--flat { transform: translateY(0); transition: none; }
}

/* Con lienzo, la segunda capa de pelaje sobra: la retira, pero FUNDIDA y al
   mismo ritmo con el que entra el lienzo (fur-motion.css). Apagarla de golpe
   era la otra mitad del tirón — 0,55 de opacidad a 0 en un fotograma, sobre
   pantalla completa. */
.hv3-fur > i {
  transition: opacity 520ms var(--ic-ease-soft, cubic-bezier(0.22, 1, 0.36, 1));
}

.hv3-fur.fur-field-ready > i { opacity: 0 !important; }

@media (prefers-reduced-motion: reduce) {
  .hv3-fur > i { transition: none; }
}

/* El velo y el wordmark tienen que quedar POR ENCIMA del lienzo. El velo de
   `.hv3-fur` vive en z-index -1 (funciona sobre el fondo del elemento), así que
   con lienzo hay que subirlo. */
.hv3-fur.fur-field-ready::after { z-index: 1; }
.hv3-intro-word,
.hv3-steps-intro-copy,
.hv3-phone-logo {
  position: relative;
  z-index: 2;
}

/* ----- la entrada del hero -----
   Hasta ahora el contenido del hero aparecía de golpe al retirarse la intro.
   Ahora se monta pieza a pieza mientras el recorte se cierra, como en Daylight.

   El titular entra con un barrido de IZQUIERDA A DERECHA. No es un invento:
   es el mismo idioma que ya usaba el lockup de la intro anterior en
   v2.css:5715 — `clip-path: inset(0 100% 0 0)` abriéndose a `inset(0)`.

   Todo cuelga de `html.has-intro`, así que sin intro (reduced-motion, llegada
   con ancla, o si el navegador no la reproduce) el hero está visible desde el
   primer fotograma y no hay nada que esperar. */
html.has-intro .hv3-hero :is(.hero-eyebrow, .hero-subclaim, .hero-actions) {
  opacity: 0;
  transform: translateY(14px);
}

html.has-intro .hv3-hero .hero-title {
  clip-path: inset(0 100% 0 0);
}

html.has-intro .hv3-hero .hero-tag {
  opacity: 0;
  transform: translateY(10px);
}

html.has-intro .hv3-hero .hv3-scene {
  opacity: 0;
}

/* EL REPARTO DEL COPY, con su propio gate.

   Antes colgaba de `hero-in` (t=4150 ms) junto con la escena, y ahí estaba el
   fallo: medido con ?intro=1, la entrada entera corría de 4457 a 5197 ms
   mientras el telón no empieza a fundirse hasta 5450 y no se retira hasta 5900.
   Toda la coreografía terminaba 413 ms ANTES de que la cortina se moviera; a
   4600 ms el overlay tapaba el 92 % de la pantalla y ya se veía la «S» del
   titular barrida por detrás.

   No basta con retrasar `hero-in`: esa misma clase revela `.hv3-scene`, que es
   el panel de pelo sobre el que ATERRIZA el recorte de la intro. Si llega a
   opacidad 0, el telón se disuelve sobre un hueco. Así que `hero-in` se queda
   donde estaba para la escena, y el copy pasa a `hero-copy-in`, que se pone en
   done() —el único punto que marca «intro terminada» por las tres vías: salida
   inmediata, temporizador de 5900 ms y red de seguridad de 7600. */
html.has-intro.hero-copy-in .hv3-hero .hero-eyebrow,
html.has-intro.hero-copy-in .hv3-hero .hero-subclaim,
html.has-intro.hero-copy-in .hv3-hero .hero-actions {
  opacity: 1;
  transform: translateY(0);
  transition:
    opacity 620ms linear,
    transform 900ms var(--ic-ease-soft);
}

html.has-intro.hero-copy-in .hv3-hero .hero-eyebrow { transition-delay: 0ms; }
html.has-intro.hero-copy-in .hv3-hero .hero-subclaim { transition-delay: 620ms; }
html.has-intro.hero-copy-in .hv3-hero .hero-actions { transition-delay: 860ms; }

html.has-intro.hero-copy-in .hv3-hero .hero-title {
  clip-path: inset(0 0 0 0);
  transition: clip-path 1150ms var(--ic-ease-soft) 140ms;
}

html.has-intro.hero-copy-in .hv3-hero .hero-tag {
  opacity: 1;
  transform: translateY(0);
  transition:
    opacity 560ms linear,
    transform 720ms var(--ic-ease-soft);
}

/* los chips entran escalonados, de izquierda a derecha */
html.has-intro.hero-copy-in .hv3-hero .hero-tag:nth-child(1) { transition-delay: 1020ms; }
html.has-intro.hero-copy-in .hv3-hero .hero-tag:nth-child(2) { transition-delay: 1160ms; }
html.has-intro.hero-copy-in .hv3-hero .hero-tag:nth-child(3) { transition-delay: 1300ms; }

/* la escena (el cuadrado de pelo y sus datos) es lo último: aparece justo
   después de que el recorte de la intro aterrice encima de ella */
html.has-intro.hero-in .hv3-hero .hv3-scene {
  opacity: 1;
  transition: opacity 700ms linear 900ms;
}

@media (prefers-reduced-motion: reduce) {
  html.has-intro .hv3-hero :is(.hero-eyebrow, .hero-subclaim, .hero-actions, .hero-tag, .hv3-scene) {
    opacity: 1;
    transform: none;
  }
  html.has-intro .hv3-hero .hero-title { clip-path: none; }
}

/* ============================================================================
   EVA · VERSIÓN B — el retrato manda y el texto vive sobre su propio cielo
   ----------------------------------------------------------------------------
   LA ZONA TRANQUILA ESTÁ MEDIDA, NO SUPUESTA
   Mapa de contraste de fotoEva.png (1672×941) contra petróleo #193C43, leído
   celda a celda sobre los píxeles reales:

              0%   10%   20%   30%   40%   50%   60%   70%   80%
       0%    8.5   8.7   8.9   9.5   9.4   9.3   9.3   9.3   9.4
      20%    9.2   9.5   9.9  10.0   9.9   9.7   9.6   1.1   1.0
      40%    8.6   9.0   9.3   9.5   9.5   9.9   2.5   1.0   1.0
      60%    6.4   7.5   8.0   8.0   8.4   8.2   1.0   1.0   1.0
      80%    5.0   6.2   6.9   7.4   7.5   4.4   1.4   5.0   1.1

   Conclusión: el cuadrante izquierdo por encima del 70 % de alto aguanta texto
   OSCURO con 7,4-10:1. A partir del 60 % horizontal el contraste cae a 1,0 —ahí
   está ella—. Por eso aquí no hay ningún campo de color inventado sobre la
   foto: el texto se apoya en el cielo que la foto ya trae, que es justo lo que
   se pedía.

   EL GESTO: EL ENCUADRE ABRE
   Empieza cerrado sobre Eva y el gato y se va soltando hasta revelar el cielo.
   El origen de la escala está en la CARA de ella, así que Eva no se mueve: lo
   que crece es el aire a su izquierda. El texto entra en el hueco que acaba de
   aparecer, línea a línea. No es un zoom decorativo — es la sección contando
   por qué hay sitio para el texto.

   Lo que NO se hizo, por haberlo medido: un filete alineado con el horizonte.
   El horizonte de esta foto es hazy —el mayor salto de luminancia en el tercio
   izquierdo es de 1,07 sobre 255— así que una línea «sobre el horizonte» se
   leería como arbitraria en vez de como intencionada.
   ========================================================================== */
.hv3-portrait {
  position: relative;
  overflow: clip;
  background: var(--ic-color-cream);
  color: var(--ic-color-petrol-950);
}

.hv3-portrait-pin {
  position: relative;
  display: grid;
  min-height: 100svh;
  align-items: center;
}

.hv3-portrait-media {
  position: absolute;
  inset: 0;
  z-index: 0;
  margin: 0;
  overflow: hidden;
}

.hv3-portrait-media picture { display: contents; }

/* `object-position` anclado a la derecha: la foto es 16:9 y casi ningún
   viewport lo es, así que `cover` recorta de ancho. Recortando por la IZQUIERDA
   se pierde cielo, que sobra; anclando al centro se le comería el hombro. */
.hv3-portrait-media img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 88% 50%;
  /* la cara de Eva, medida sobre el archivo: x 80 %, y 30 % */
  transform-origin: 80% 30%;
  will-change: transform;
}

/* Un velo de crema muy tenue y solo por la izquierda. El mapa dice que el
   cielo aguanta de sobra, pero el recorte cambia con cada viewport y esto pone
   un suelo al contraste sin que se lea como una capa: en el centro ya es
   transparente y la foto llega intacta a la mitad derecha. */
.hv3-portrait-scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    92deg,
    rgb(var(--ic-cream-rgb, 247 239 226) / 0.62) 0%,
    rgb(var(--ic-cream-rgb, 247 239 226) / 0.34) 26%,
    rgb(var(--ic-cream-rgb, 247 239 226) / 0.08) 46%,
    transparent 58%
  );
}

.hv3-portrait-field {
  position: relative;
  z-index: 1;
  width: min(520px, 42vw);
  padding-block: clamp(48px, 7vh, 96px);
  padding-inline: var(--ic-page-gutter) 0;
  margin-inline-start: max(0px, calc((100vw - var(--ic-container-max, 1400px)) / 2));
}

.hv3-portrait-copy { display: grid; gap: 0; }

.hv3-portrait-kicker {
  margin: 0 0 14px;
  color: rgb(var(--ic-petrol-rgb) / 0.78);
}

.hv3-portrait-title {
  margin: 0 0 clamp(22px, 3vh, 34px);
  color: var(--ic-color-petrol-950);
  text-wrap: balance;
}

.hv3-portrait-name {
  margin: 0;
  font-family: var(--ic-font-display);
  font-size: clamp(1.3rem, 2vw, 1.7rem);
  font-weight: 500;
  letter-spacing: -0.02em;
  line-height: 1.1;
}

.hv3-portrait-role {
  margin: 4px 0 clamp(20px, 2.6vh, 28px);
  font-size: 0.88rem;
  line-height: 1.4;
  color: rgb(var(--ic-petrol-rgb) / 0.8);
}

.hv3-portrait-creds {
  display: grid;
  gap: 12px;
  margin: 0 0 clamp(24px, 3vh, 34px);
  padding: 0;
  list-style: none;
}

.hv3-portrait-creds li {
  display: flex;
  align-items: center;
  gap: 11px;
  font-size: 0.92rem;
  line-height: 1.35;
  color: var(--ic-color-petrol-950);
}

/* Los iconos en coral y no en mostaza: sobre el cielo claro la mostaza se
   evapora (queda en ~1,8:1), el coral de acción aguanta. */
.hv3-portrait-cred-icon {
  flex: none;
  width: 19px;
  height: 19px;
  color: var(--ic-color-coral-action, #9f453a);
}

.hv3-portrait-cred-icon svg { display: block; width: 100%; height: 100%; }

/* La firma ya viene en tinta petrol sobre transparente: sin filtros. */
.hv3-portrait-sign {
  width: clamp(150px, 16vw, 196px);
  height: auto;
  margin-bottom: clamp(22px, 3vh, 32px);
  opacity: 0.94;
}

.hv3-portrait-cta { justify-self: start; }

/* ----- el motor de scroll -----
   El reloj lo publica el bloque EN FLUJO: un `sticky` fijado no se mueve
   respecto al viewport y su `view()` se queda plano. */
@supports (animation-timeline: view()) {
  /* La composición a sangre —foto llenando la pantalla y el texto encima— pide
     ANCHO Y ALTO. A 1024×768 el bloque de texto necesita ~560 px y, con el
     header, no caben: se veía el titular y nada más; nombre, credenciales,
     firma y CTA quedaban fuera de cuadro. Por debajo de 820 px de alto manda la
     composición apilada, que ya funciona en móvil y muestra todo. */
  @media (min-width: 901px) and (min-height: 640px) and (prefers-reduced-motion: no-preference) {
    .hv3-portrait {
      height: 220svh;
      view-timeline-name: --hv3-portrait;
      view-timeline-axis: block;
    }

    .hv3-portrait-pin {
      position: sticky;
      top: 0;
      height: 100svh;
    }

    .hv3-portrait :is(
        .hv3-portrait-media img,
        .hv3-portrait-scrim,
        .hv3-portrait-kicker,
        .hv3-portrait-title,
        .hv3-portrait-name,
        .hv3-portrait-role,
        .hv3-portrait-creds li,
        .hv3-portrait-sign,
        .hv3-portrait-cta
      ) {
      animation-timeline: --hv3-portrait;
      /* EXACTAMENTE la ventana de anclado: la sección mide 220svh y el bloque
         anclado 100svh, así que se queda fijo de `cover 100svh` a `cover
         220svh`. Con un rango más largo, las últimas piezas entrarían cuando el
         panel ya se está yendo hacia arriba. */
      animation-range: cover 100svh cover 220svh;
      animation-fill-mode: both;
      animation-timing-function: linear(0 0%, 0.11425 2.397%, 0.21782 4.795%, 0.32077 7.444%, 0.41258 10.094%, 0.49418 12.743%, 0.56646 15.393%, 0.63647 18.321%, 0.69713 21.25%, 0.75178 24.323%, 0.79825 27.395%, 0.84122 30.791%, 0.87654 34.188%, 0.90656 37.755%, 0.93264 41.698%, 0.95254 45.642%, 0.96875 50%, 0.98583 57.313%, 0.99562 66.25%, 0.99939 77.219%, 1 100%);
    }

    .hv3-portrait .hv3-portrait-media img {
      animation-name: hv3-portrait-open;
      animation-timing-function: linear(0 0%, 0.00176 15.905%, 0.01061 24.469%, 0.0196 27.871%, 0.03277 30.948%, 0.0507 33.732%, 0.07385 36.25%, 0.10263 38.533%, 0.13722 40.598%, 0.17772 42.466%, 0.22413 44.156%, 0.2794 45.767%, 0.3411 47.224%, 0.41672 48.682%, 0.5 50%, 0.58328 51.318%, 0.6589 52.776%, 0.7206 54.233%, 0.77587 55.844%, 0.82228 57.534%, 0.86278 59.402%, 0.89737 61.467%, 0.92615 63.75%, 0.9493 66.268%, 0.96723 69.052%, 0.9804 72.129%, 0.98939 75.531%, 0.99824 84.095%, 1 100%);
    }

    .hv3-portrait .hv3-portrait-scrim { animation-name: hv3-portrait-scrim-in; }
    .hv3-portrait .hv3-portrait-kicker { animation-name: hv3-portrait-kicker-in; }
    .hv3-portrait .hv3-portrait-title { animation-name: hv3-portrait-title-in; }
    .hv3-portrait .hv3-portrait-name { animation-name: hv3-portrait-name-in; }
    .hv3-portrait .hv3-portrait-role { animation-name: hv3-portrait-role-in; }
    .hv3-portrait .hv3-portrait-creds li:nth-child(1) { animation-name: hv3-portrait-cred-1; }
    .hv3-portrait .hv3-portrait-creds li:nth-child(2) { animation-name: hv3-portrait-cred-2; }
    .hv3-portrait .hv3-portrait-creds li:nth-child(3) { animation-name: hv3-portrait-cred-3; }
    .hv3-portrait .hv3-portrait-sign { animation-name: hv3-portrait-sign-in; }
    .hv3-portrait .hv3-portrait-cta { animation-name: hv3-portrait-cta-in; }
  }
}

/* El encuadre se abre. Origen en la cara de Eva: ella se queda donde está y lo
   que aparece es el cielo por la izquierda. */
@keyframes hv3-portrait-open {
  from { transform: scale(1.2); }
  to { transform: scale(1); }
}

/* El velo entra ANTES que el texto, no a la vez: cuando llega el titular el
   suelo de contraste ya está puesto. */
@keyframes hv3-portrait-scrim-in {
  0%, 6% { opacity: 0; }
  26%, 100% { opacity: 1; }
}

@keyframes hv3-portrait-kicker-in {
  0%, 14% { opacity: 0; transform: translateY(12px); }
  30%, 100% { opacity: 1; transform: translateY(0); }
}

/* El titular barre de izquierda a derecha, el mismo idioma con el que se
   presenta el h1 del hero. */
@keyframes hv3-portrait-title-in {
  0%, 20% { opacity: 0; clip-path: inset(0 100% 0 0); }
  24% { opacity: 1; }
  46%, 100% { opacity: 1; clip-path: inset(0 -6% 0 0); }
}

@keyframes hv3-portrait-name-in {
  0%, 38% { opacity: 0; transform: translateY(14px); }
  54%, 100% { opacity: 1; transform: translateY(0); }
}

@keyframes hv3-portrait-role-in {
  0%, 42% { opacity: 0; transform: translateY(12px); }
  58%, 100% { opacity: 1; transform: translateY(0); }
}

@keyframes hv3-portrait-cred-1 {
  0%, 48% { opacity: 0; transform: translateX(-14px); }
  64%, 100% { opacity: 1; transform: translateX(0); }
}

@keyframes hv3-portrait-cred-2 {
  0%, 54% { opacity: 0; transform: translateX(-14px); }
  70%, 100% { opacity: 1; transform: translateX(0); }
}

@keyframes hv3-portrait-cred-3 {
  0%, 60% { opacity: 0; transform: translateX(-14px); }
  76%, 100% { opacity: 1; transform: translateX(0); }
}

/* La firma se escribe: el mismo barrido, que es lo que hace una firma. */
@keyframes hv3-portrait-sign-in {
  0%, 66% { opacity: 0; clip-path: inset(0 100% 0 0); }
  70% { opacity: 0.94; }
  84%, 100% { opacity: 0.94; clip-path: inset(0 0 0 0); }
}

@keyframes hv3-portrait-cta-in {
  0%, 74% { opacity: 0; transform: translateY(14px); }
  90%, 100% { opacity: 1; transform: translateY(0); }
}

/* ----- estrecho y reducción de movimiento -----
   La foto NO se recorta a vertical: se sirve entera en su 16:9 y el texto pasa
   debajo. Recortarla a 9:19 mataría justo lo que la hace funcionar —el cielo
   vacío— y dejaría el texto sobre la cara. */
@media (max-width: 900px), (max-height: 639px), (prefers-reduced-motion: reduce) {
  .hv3-portrait { height: auto; }

  .hv3-portrait-pin {
    position: static;
    height: auto;
    min-height: 0;
    display: block;
  }

  .hv3-portrait-media {
    position: relative;
    aspect-ratio: 1672 / 941;
  }

  .hv3-portrait-media img {
    object-position: 74% 50%;
    transform: none;
  }

  .hv3-portrait-scrim { display: none; }

  .hv3-portrait-field {
    width: auto;
    margin-inline: 0;
    padding-inline: var(--ic-page-gutter);
    padding-block: clamp(30px, 6vw, 48px) clamp(48px, 9vw, 72px);
  }
}

/* ============================================================================
   «NO VENDEMOS COMIDA» — traída al idioma de V3
   ----------------------------------------------------------------------------
   La sección la comparten index.html, salud.html, dieta.html y ca/index.html,
   así que todo esto cuelga de `.nc--fur`, que solo lleva home-v3.

   Se sentía pegada con cinta adhesiva por tres motivos concretos, y ninguno
   era el color:

     1. RADIO. 30-56 px arriba, cuando en V3 el marco del hero va a 2 px y los
        paneles de pelo a 8. Era la única esquina de ese tamaño en la página.
     2. MOTOR. Entraba por tiempo — `.in-view` de script-v2.js más
        `transition-delay` escalonado — mientras el resto de V3 va scrubbeado al
        scroll. Dos modelos de movimiento distintos en la misma página se notan
        aunque no se sepa por qué.
     3. FONDO. Liso, cuando las otras cuatro superficies oscuras de la página
        (intro, cuadrado del hero, portada de pasos y fondo del móvil) son pelo.

   Aquí se corrigen las tres.
   ========================================================================== */
.nc--fur {
  position: relative;
  isolation: isolate;
  /* el radio de los paneles de pelo, no el de la home antigua */
  border-radius: var(--ic-radius-sm) var(--ic-radius-sm) 0 0;
  /* el degradado radial de v2.css sobra: debajo ya hay pelo */
  background: var(--ic-color-petrol-950);
}

.nc--fur .nc-fur {
  position: absolute;
  z-index: 0;
  inset: 0;
  aspect-ratio: auto;
  border-radius: inherit;
  box-shadow: none;
  /* Calibrado contra el suelo de contraste, no a ojo. El texto es crema
     (L=0,83); para 4,5:1 el fondo puede subir hasta L≈0,145, que deja margen
     para que el pelaje SE VEA — que es todo el objetivo de traerlo aquí. */
  --ic-fur-veil: linear-gradient(
    172deg,
    rgb(7 10 10 / 0.66) 0%,
    rgb(7 10 10 / 0.56) 42%,
    rgb(7 10 10 / 0.64) 100%
  );
}

.nc--fur .nc-panel-wrap {
  position: relative;
  z-index: 1;
}

/* El bol se queda: es la única ilustración de producto de la página y aquí sí
   viene a cuento. Pero sobre pelo necesita despegarse, que antes se lo daba el
   fondo liso. */
.nc--fur .bowl-embed { filter: drop-shadow(0 18px 34px rgb(7 10 10 / 0.5)); }

/* ----- tipografía: los dos lados al mismo peso -----
   El lado de la marca iba a 2,15 rem y el nuestro a 2,75. Esa diferencia no es
   jerarquía, es poner el pulgar en la balanza: la comparación se lee más
   honesta —y golpea más— si las dos frases pesan lo mismo y lo único que
   cambia es la tinta y el subrayado mostaza. */
.nc--fur .nc-side-brand .nc-side-copy,
.nc--fur .nc-side-iron .nc-side-copy {
  font-size: clamp(1.72rem, 2.8vw, 2.5rem);
}

.nc--fur .nc-side-brand .nc-side-copy { color: rgb(var(--ic-cream-dim-rgb) / 0.6); }

/* El titular, en crema y no en mostaza.

   `v2.css:8944-8949` lo pinta con `--ic-color-mustard`, que es el tratamiento de
   la sección compartida (`nc--panel`). En V3 la mostaza ya trabaja como acento
   puntual —el punto del claim del hero, el subrayado de la marca, la etiqueta
   «iron.cat» de esta misma comparación— y un titular entero en mostaza le quita
   ese papel además de competir con el pelaje dorado del fondo. El punto final sí
   se queda en mostaza: ahí el acento sigue siendo acento. */
.nc--fur .nc-title {
  color: var(--ic-color-cream);
}

/* ----- el motor: del tiempo al scroll -----
   Se anula la entrada por `.in-view` de v2.css y las palabras pasan a colgar
   del recorrido de la sección, como todo lo demás en V3. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .nc--fur .nc-panel-wrap .ncw {
      transition: none;
      opacity: 1;
      translate: none;
      animation-name: hv3-nc-word;
      animation-timeline: view();
      /* Dos correcciones, las dos medidas:

         1. El escalonado va en el RANGO, no en `animation-delay`: en una
            animación ligada al scroll el retardo se ignora por completo. Con
            delays, las doce palabras entraban en el mismo fotograma.
         2. El rango es `cover` y no `entry`. Con `entry` el reparto entero
            cabía en 100 px de scroll —dos o tres fotogramas, imperceptible—
            porque para un bloque alto esa fase es cortísima. `cover` abarca
            toda la travesía del bloque por la pantalla y da recorrido real.

         Cada palabra arranca 3 puntos después que la anterior, con el índice
         que el marcado ya trae en `--wi`. */
      animation-range:
        cover calc(6% + var(--wi, 0) * 3%)
        cover calc(24% + var(--wi, 0) * 3%);
      animation-fill-mode: both;
      animation-timing-function: linear(0 0%, 0.11425 2.397%, 0.21782 4.795%, 0.32077 7.444%, 0.41258 10.094%, 0.49418 12.743%, 0.56646 15.393%, 0.63647 18.321%, 0.69713 21.25%, 0.75178 24.323%, 0.79825 27.395%, 0.84122 30.791%, 0.87654 34.188%, 0.90656 37.755%, 0.93264 41.698%, 0.95254 45.642%, 0.96875 50%, 0.98583 57.313%, 0.99562 66.25%, 0.99939 77.219%, 1 100%);
    }

    /* Nuestro lado entra DESPUÉS: primero el argumento de la marca, luego la
       respuesta. Ese orden es el chiste de la sección, y con el reparto por
       rango hay que desplazarlo entero. */
    .nc--fur .nc-side-iron .ncw {
      animation-range:
        cover calc(30% + var(--wi, 0) * 3%)
        cover calc(48% + var(--wi, 0) * 3%);
    }
  }
}

@keyframes hv3-nc-word {
  from { opacity: 0; translate: 0 0.38em; }
  to { opacity: 1; translate: 0 0; }
}

@media (max-width: 900px) {
  .nc--fur .nc-fur {
    --ic-fur-veil: linear-gradient(172deg, rgb(7 10 10 / 0.7), rgb(7 10 10 / 0.66) 100%);
  }
}


/* ============================================================================
   REMATES DEL CIERRE — radios y centrado
   ========================================================================== */

/* El panel de cierre y las FAQ venían con 24-36 px y 12 px de radio, del
   vocabulario de la home antigua. V3 se mueve entre 2 px (el marco del hero) y
   8 px (los paneles de pelo); esos radios grandes eran los únicos que
   desentonaban al final del recorrido. */
.health-home .final-cta {
  border-radius: var(--ic-radius-sm);
}

.health-home .faq-item {
  border-radius: var(--ic-radius-xs);
}

/* CENTRADO DEL CIERRE — el `text-align` solo centra el TEXTO, no la CAJA.

   `.final-cta-inner` es un grid (`.ic-section-head`, editorial-system.css:96) sin
   `justify-items`, o sea `stretch`. `stretch` solo estira los ítems de tamaño
   automático: en cuanto uno tiene `max-width` se degrada a `start` y su caja se
   pega al borde izquierdo de la columna. Le pasa justo a los dos hijos con tope
   —el titular (20ch) y la entradilla (42rem)— y a nadie más, que es exactamente
   lo que se veía descolocado.

   v2.css ya les daba `margin: 0 auto` (6998 y 7014), pero `.ic-heading` y
   `.ic-lede` lo resetean con `margin: 0` (editorial-system.css:52 y :81): misma
   especificidad (0,1,0) y hoja cargada después, y el shorthand arrastra también
   el eje inline. Se repone solo ese eje, sin tocar el vertical.

   Medido a 2000 px antes del arreglo: eyebrow, botón y nota centrados en 1000;
   titular en 712 y entradilla en 656.

   Se repone con `margin-inline` y no con `justify-items: center` en el grid
   porque eso último encogería a `fit-content` TODOS los hijos, incluidos el
   eyebrow y la nota, que hoy se estiran a la columna entera. */
.health-home .final-cta-inner > .ic-button,
.health-home .final-cta-title,
.health-home .final-cta-sub {
  margin-inline: auto;
}

/* ============================================================================
   MENÚ DE TABLET Y MÓVIL — con la hoja de godaylight.com
   ----------------------------------------------------------------------------
   La base ya baja como hoja crema con 8 px de radio y filetes, que es el gesto
   correcto. Le faltaban las tres cosas que hacen que la de Daylight se sienta
   acabada, medidas sobre su página a 768 px:

     · un VELO oscuro detrás (ellos: rgba(10,8,4,0.5)); sin él la página sigue
       a plena luz y la hoja no se lee como una capa por encima
     · el CTA DENTRO de la hoja, a ancho completo, cerrando la lista. El nuestro
       solo aparecía por debajo de 520 px, así que en tablet el menú abierto no
       ofrecía la acción principal
     · un chevron por fila, que es lo que dice que la fila entera es pulsable

   Filas a 64 px, como las suyas, que además resuelve el objetivo táctil.
   ========================================================================== */
@media (max-width: 960px) {
  /* El velo, con el truco de apilamiento que hace falta aquí.
     `z-index: -1` NO sirve: `.site-header` es `position: fixed` con `z-index: 20`,
     o sea que crea contexto de apilamiento propio y un valor negativo se queda
     atrapado dentro, detrás del header pero sin poder cubrir la página.
     Con `z-index: 0` el velo sigue dentro de ese contexto —y por tanto por
     encima de todo lo que hay por debajo del 20— y basta con levantar la barra
     y la hoja por encima de él. */
  .health-home .site-header::after {
    content: "";
    position: fixed;
    z-index: 0;
    inset: 0;
    background: rgb(var(--ic-petrol-950-rgb) / 0.52);
    opacity: 0;
    pointer-events: none;
    transition: opacity 320ms var(--ic-ease-soft, cubic-bezier(0.22, 1, 0.36, 1));
  }

  /* `.health-home` ES la clase del body, no un descendiente: el selector tiene
     que ser `body.health-home.menu-open`, no `body.menu-open .health-home`. */
  body.health-home.menu-open .site-header::after {
    opacity: 1;
    pointer-events: auto;
  }

  /* La barra, por encima del velo. La hoja NO entra aquí: ya lleva
     `position: fixed; z-index: 30` en `v2.css:3540`, así que sobra por encima
     del velo, y meterle un `position: relative` le anulaba el `inset: 76px 16px`
     —se convertía en un item más de la barra y colapsaba a 170 px de ancho. */
  .health-home .site-header .nav-shell {
    position: relative;
    z-index: 1;
  }

  /* La barra, sobre el velo, pide la paleta invertida. Medido con el menú
     abierto: el petrol de `--flat` contra el velo daba 1,19:1, o sea el logo y
     el selector de idioma prácticamente desaparecían. El lockup ya viene en dos
     copias superpuestas que se relevan por opacidad (`v2.css:5724`), así que
     basta con pedir la reversa. */
  .health-home.menu-open .site-header--flat .brand-logo--light { opacity: 1; }
  .health-home.menu-open .site-header--flat .brand-logo--dark { opacity: 0; }

  .health-home.menu-open .site-header--flat .nav-shell,
  .health-home.menu-open .site-header--flat .nav-end {
    color: var(--ic-color-cream);
  }

  /* Inset de 12 px, como el suyo, y el top justo bajo la barra: con el
     `inset: 76px` heredado la hoja arrancaba 10 px por dentro de la barra
     (que acaba en 86) y las dos cajas se pisaban en la esquina. */
  .health-home .site-header .nav-links {
    inset: 94px 12px auto;
  }

  .health-home .site-header .nav-links a {
    min-height: 64px;
  }

  /* El chevron: pseudo-elemento en el propio enlace, así no toca el marcado y
     no aparece en el lector de pantalla. Va en `::before` porque el `::after`
     ya lo ocupa la línea divisoria de la fila.
     `.nav-links` es un `<div>` con `<a>` directos, sin `<li>`. */
  .health-home .site-header .nav-links > a:not(.ic-button)::before {
    content: "";
    /* Obligatorio: `v2.css:3574` apaga con `display: none` los dos pseudos de
       `.nav-links a` en este mismo ancho. Sin reponerlo aquí, la caja del
       chevron no llega a generarse por mucha especificidad que tenga el resto. */
    display: block;
    position: absolute;
    top: 50%;
    right: 4px;
    width: 7px;
    height: 7px;
    border-top: 1.5px solid currentColor;
    border-right: 1.5px solid currentColor;
    opacity: 0.42;
    transform: translateY(-50%) rotate(45deg);
  }

  .health-home .site-header .nav-links > a:not(.ic-button) {
    position: relative;
    padding-right: 26px;
  }

  /* El CTA cierra la hoja a ancho completo, en tablet también y no solo en
     móvil, que era donde se quedaba antes. */
  .health-home .site-header .nav-links .nav-menu-cta.ic-button {
    display: inline-flex;
    width: 100%;
    margin-top: 14px;
    justify-content: center;
  }
}
