/* ============================================================================
   Vaucai — Hero cinema (Bloque B · B-03)
   El mockup se CONGELA (GSAP ScrollTrigger pin) y, al hacer scroll, van
   cambiando los TEXTOS — alternando los DOS LADOS del teléfono (desktop) /
   arriba (móvil) — y la "pantalla" del teléfono (4 ranuras = hoy copias del
   mismo render real; se swapean por los Rotato uno a uno). CSP-safe.
   Fallback sin JS: hero normal estático (sin textos, sin solapes).
   ============================================================================ */

.hero.hero-cinema {
    display: block;          /* el padre del pin NO debe ser flex (pin-spacing) */
    overflow: visible;
}

/* Grupo que se congela = teléfono + CTA + textos. fit-content centrado para
   anclar los textos a IZQUIERDA y DERECHA del teléfono; relative = contexto. */
.hero-freeze {
    position: relative;
    width: fit-content;
    margin-left: auto;
    margin-right: auto;
    display: flex;
    flex-direction: column;
    align-items: center;
}

/* ----- 4 ranuras de pantalla (cross-dissolve por opacidad) ----- */
.hero-shot {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    opacity: 0;
    transition: opacity 0.6s var(--ease-cinematic, ease);
    will-change: opacity;
}
.hero-shot.is-active { opacity: 1; }
.hero-shot img { width: 100%; height: auto; display: block; }

/* Base = la conversación. Siempre visible: es el marco/teléfono sobre el que
   se funden las pantallas de cada beat (y la pantalla de la fase del botón).
   Sin JS, también se ve sola (fallback = hero estático con el chat). */
.hero-shot.is-base { opacity: 1; }

/* Capa de pantalla (un beat). Se funde SOBRE la base con un cross-dissolve
   LIMPIO (solo opacidad): como el teléfono y su posición son idénticos a la
   base, la sensación es que SOLO cambia la pantalla, sin que el marco "cambie".
   Sin brillo ni desenfoque (eso hacía que pareciera cambiar todo el mockup). */
.hero-shot.is-screen {
    transition: opacity 0.95s var(--ease-cinematic, ease);
}

/* ----- Modo cinema: tras desaparecer el botón, el teléfono se muestra
   ENTERO (se abre el recorte del 18% inferior) y SIN el difuminado del
   final del mockup. La conversación en reposo (con el botón) mantiene el
   recorte+fade que la funde con "Crear mi asistente". ----- */
/* Cinema: el teléfono se muestra ENTERO a su MISMO tamaño — se abre el
   recorte a la pantalla completa (crece hacia abajo) y se quita el difuminado
   del final. Para que el móvil COMPLETO quede CENTRADO al congelar, el freeze
   se recoloca hacia arriba la mitad de lo que crece (--cinema-shift, lo calcula
   el JS por breakpoint). El alto extra bajo el hero lo reserva el JS
   (padding-bottom) para que la sección siguiente no se monte sobre el mockup. */
.hero-cinema .hero-freeze {
    transition: transform 0.65s var(--ease-cinematic, ease);
}
.hero-cinema .mockup-masked {
    transition: aspect-ratio 0.65s var(--ease-cinematic, ease);
}
.hero-freeze.cinema {
    transform: translateY(calc(-1 * var(--cinema-shift, 0px)));
}
.hero-freeze.cinema .mockup-masked {
    aspect-ratio: 760 / 1155;            /* render completo, MISMO ancho/tamaño */
    -webkit-mask-image: none;
    mask-image: none;
}
/* DESKTOP: la apertura del mockup (recortado → completo) y el recentrado van
   SCROLL-DRIVEN → el móvil se completa Y se centra CONFORME scrolleas, no con un
   salto disparado. El JS fija altura y desplazamiento según el scroll, así que
   AQUÍ se quitan las transiciones (las pondría a destiempo). El ANCHO se bloquea
   (aspect-ratio:auto + width:100%) para que el tamaño NO cambie. Móvil mantiene
   el aspect-ratio + transición (intacto). */
/* La apertura (alto del masked) + el recentrado (shift del freeze) los conduce
   el JS SEGÚN EL SCROLL, en desktop Y AHORA TAMBIÉN EN MÓVIL → aquí se quitan las
   transiciones CSS (las pondrían a destiempo / con lag al seguir el scroll). */
.hero-cinema .hero-freeze,
.hero-cinema .mockup-masked {
    transition: none;
}
/* Desktop: el masked abre soltando el aspect-ratio + ancho 100% (el JS fija el
   alto). En móvil el masked ya es width/height:100% y el JS fija el alto inline
   (el aspect-ratio del modo cinema queda anulado por las dimensiones explícitas),
   así que esto sólo hace falta en desktop. */
@media (min-width: 901px) {
    .hero-freeze.cinema .mockup-masked {
        aspect-ratio: auto;
        width: 100%;
    }
}

/* ----- CTA: su opacidad la fija el JS SEGÚN EL SCROLL (fundido lento y suave,
   sin transición CSS para que no haya salto ni lag). ----- */

/* ----- "Todo tu mundo" = UNA frase partida que FLANQUEA el móvil: "Todo tu"
   arriba-izquierda (pegado al móvil), "mundo" mucho más grande y centrado a la
   derecha. El teléfono (la Tierra) queda en medio. Misma tipografía; "mundo"
   solo más grande. Aparece ENTERA y a la vez con la pantalla de la Tierra. La
   posición vertical (Y) la fija el JS midiendo el centro real del teléfono
   (top:50% es solo el fallback sin JS). ----- */
.hero-caption {
    position: absolute;
    top: 50%;
    opacity: 0;
    transition:
        opacity 0.7s var(--ease-cinematic, ease),
        transform 0.9s var(--ease-out-expo, cubic-bezier(.16, 1, .3, 1));
    pointer-events: none;
    will-change: opacity, transform;
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
}
/* El render tiene canvas transparente (la sombra) a cada lado del aparato:
   el teléfono ocupa del 15.26% al 83.29% del ancho de la imagen. Para PEGAR el
   texto al borde del TELÉFONO (no al de la imagen) descontamos ese inset. En %
   → escala solo con el ancho del móvil. El + clamp es el huelgo final al borde. */
.hero-caption.side-left {           /* "Todo tu" — pegado al móvil por su derecha */
    right: calc(100% - 15.26% + clamp(6px, 1.1vw, 16px));
    text-align: right;
    transform: translateY(-50%) translateX(-44px);
}
.hero-caption.side-right {          /* "mundo" — a la derecha del móvil */
    left: calc(100% - 16.71% + clamp(6px, 1.1vw, 16px));
    text-align: left;
    transform: translateY(-50%) translateX(44px);
}
.hero-caption.is-active {
    opacity: 1;
    transform: translateY(-50%) translateX(0);
}
.hero-caption h2 {
    font-weight: 800;
    line-height: 1.0;
    letter-spacing: -0.035em;
    color: var(--text);
    margin: 0;
    white-space: nowrap;
}
/* "Todo tu" — el arranque, más pequeño, arriba. */
.hero-caption--lead h2 { font-size: clamp(30px, 3.8vw, 58px); }
/* "mundo" — mucho más grande, MISMA tipografía (sin serif, sin azul). */
.hero-caption--key h2  { font-size: clamp(56px, 8.4vw, 132px); letter-spacing: -0.045em; }
/* Botón DISCRETO para saltar el bloque Modo Negocio (solo desktop). Aparece en el
   beat 20 y desliza suave hasta el beat 31. Píldora translúcida, abajo-centro del
   hero fijado; oculto (sin eventos) salvo cuando lleva .is-shown. */
.hero-skip {
    position: absolute;
    bottom: 14%;
    right: 4.5%;
    left: auto;
    transform: translateY(10px);
    z-index: 6;
    display: inline-flex;
    align-items: center;
    gap: 0.5em;
    white-space: nowrap;
    padding: 10px 20px;
    border-radius: 999px;
    border: 1px solid rgba(255, 255, 255, 0.16);
    background: rgba(255, 255, 255, 0.05);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
    color: rgba(255, 255, 255, 0.66);
    font-family: 'Inter', -apple-system, system-ui, sans-serif;
    font-size: 14px;
    font-weight: 600;
    letter-spacing: -0.01em;
    cursor: pointer;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.55s var(--ease-cinematic, ease),
                transform 0.55s var(--ease-cinematic, ease),
                background 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}
.hero-skip.is-shown { opacity: 1; pointer-events: auto; transform: translateY(0); }
.hero-skip:hover {
    background: rgba(255, 255, 255, 0.11);
    border-color: rgba(255, 255, 255, 0.3);
    color: #fff;
}
.hero-skip-arrow { font-size: 1.05em; line-height: 1; }
/* Por ahora SOLO en ordenador. */
@media (max-width: 900px) { .hero-skip { display: none; } }
@media (prefers-reduced-motion: reduce) { .hero-skip { transition: opacity 0.3s ease; } }

/* Logo oficial AEAT bajo "Veri*Factu" (beat 25): centrado justo debajo del texto.
   El bloque del caption se dimensiona al texto → margin:auto lo centra bajo él. */
.aeat-badge {
    display: block;
    width: clamp(38px, 4.6vw, 68px);
    height: auto;
    margin: 0.45em auto 0;
}

/* Beat 1 · "Telegram" es más largo que "mundo" → al tamaño del key se sale del
   viewport por la derecha. Lo escalamos para que LLENE el hueco derecho sin
   desbordar a cualquier ancho de desktop. El hueco = 50vw − medio-teléfono(230)
   − margen; el teléfono es fijo (460px) y centrado, así que el hueco encoge
   rápido al estrechar la ventana → el font sigue esa geometría, no el vw a secas.
   Scopeado al beat 1 y a desktop: el beat 0 ("mundo") y el móvil quedan intactos. */
@media (min-width: 901px) {
    /* Beat 2 · "conversación" (12 chars) es aún más largo que "Telegram" →
       divisor mayor para llenar el MISMO hueco derecho sin desbordar. */
    .hero-caption[data-beat="2"].hero-caption--key h2 {
        font-size: clamp(26px, calc((50vw - 290px) / 6.8), 78px);
    }
    /* ===== Bloque MEMORIA (beats 8-12): la tesis "La memoria no es una
       característica del producto. La memoria es el producto." repartida
       pantalla a pantalla. En DESKTOP cada fragmento NO flanquea: se APILA a
       UN lado del móvil (lead arriba pequeño, key debajo grande, pegados a su
       borde), alternando lado en zigzag. Clases reutilizables desk-left /
       desk-right. Móvil hereda el centrado uniforme de más abajo. ===== */
    /* Apilado a la IZQUIERDA: lead y key ambos contra el borde izq del móvil. */
    .hero-caption.desk-left.hero-caption--key {        /* key salta a la izquierda */
        left: auto;
        right: calc(100% - 15.26% + clamp(6px, 1.1vw, 16px));
        text-align: right;
        transform: translateY(0) translateX(-44px);
    }
    .hero-caption.desk-left.hero-caption--key.is-active { transform: translateY(0) translateX(0); }
    .hero-caption.desk-left.hero-caption--lead {       /* lead encima del key */
        transform: translateY(-100%) translateX(-44px);
    }
    .hero-caption.desk-left.hero-caption--lead.is-active { transform: translateY(-100%) translateX(0); }
    /* Apilado a la DERECHA: lead y key ambos contra el borde der del móvil. */
    .hero-caption.desk-right.hero-caption--lead {      /* lead salta a la derecha */
        right: auto;
        left: calc(100% - 16.71% + clamp(6px, 1.1vw, 16px));
        text-align: left;
        transform: translateY(-100%) translateX(44px);
    }
    .hero-caption.desk-right.hero-caption--lead.is-active { transform: translateY(-100%) translateX(0); }
    .hero-caption.desk-right.hero-caption--key {       /* key debajo del lead */
        transform: translateY(0) translateX(44px);
    }
    .hero-caption.desk-right.hero-caption--key.is-active { transform: translateY(0) translateX(0); }
    /* ----- Tamaños del bloque MEMORIA (desktop): juego de jerarquía -----
       "memoria" grande (la idea); "no es una característica" PEQUEÑO (la
       negación, deliberadamente apagada); "producto" del remate, el MÁS grande. */
    .hero-caption[data-beat="8"].hero-caption--key h2,
    .hero-caption[data-beat="11"].hero-caption--key h2 {   /* "memoria" ×2 */
        font-size: clamp(30px, calc((50vw - 300px) / 4.06), 92px);
    }
    .hero-caption[data-beat="9"].hero-caption--lead h2 {   /* "no es una" — apagado */
        font-size: clamp(18px, 2.2vw, 34px);
    }
    .hero-caption[data-beat="9"].hero-caption--key h2 {    /* "característica" (13) — pequeño */
        font-size: clamp(20px, calc((50vw - 300px) / 9), 46px);
        letter-spacing: -0.035em;
    }
    .hero-caption[data-beat="10"].hero-caption--key h2 {   /* "producto" (8) — medio-grande */
        font-size: clamp(28px, calc((50vw - 295px) / 4.6), 84px);
    }
    .hero-caption[data-beat="12"].hero-caption--key h2 {   /* "producto" — el remate, el MÁS grande */
        font-size: clamp(34px, calc((50vw - 290px) / 3.5), 112px);
    }
    /* ===== [Bloque B · estética desktop] Los cinco títulos del hero —
       "Todo tu mundo" (0), "Desde tu Telegram" (1), "Controla tu email" (4),
       "Tu Calendario" (6) y "Controla tus finanzas" (13) — miden TODOS lo
       MISMO: lead y key al mismo tamaño, sin que ninguna palabra (mundo,
       Telegram, Calendario…) destaque sobre el resto. El tamaño único se ata a
       la mitad más larga del conjunto ("Controla tus" / "Calendario") con el
       mismo cálculo geométrico probado para "conversación" (12 chars), así que
       cabe en su hueco a cualquier ancho de desktop. Los beats 2 (la tesis),
       8-12 (bloque memoria) y 16/18 (Investiga/Crea) conservan su jerarquía.
       Beat 21 ("Control total", cuadro de mando) se suma a este conjunto. */
    .hero-caption[data-beat="0"].hero-caption--lead h2,
    .hero-caption[data-beat="0"].hero-caption--key h2,
    .hero-caption[data-beat="1"].hero-caption--lead h2,
    .hero-caption[data-beat="1"].hero-caption--key h2,
    .hero-caption[data-beat="4"].hero-caption--lead h2,
    .hero-caption[data-beat="4"].hero-caption--key h2,
    .hero-caption[data-beat="6"].hero-caption--lead h2,
    .hero-caption[data-beat="6"].hero-caption--key h2,
    .hero-caption[data-beat="13"].hero-caption--lead h2,
    .hero-caption[data-beat="13"].hero-caption--key h2,
    .hero-caption[data-beat="21"].hero-caption--lead h2,
    .hero-caption[data-beat="21"].hero-caption--key h2,
    .hero-caption[data-beat="28"].hero-caption--lead h2,
    .hero-caption[data-beat="28"].hero-caption--key h2,
    .hero-caption[data-beat="29"].hero-caption--lead h2,
    .hero-caption[data-beat="29"].hero-caption--key h2,
    .hero-caption[data-beat="30"].hero-caption--lead h2,
    .hero-caption[data-beat="30"].hero-caption--key h2 {
        font-size: clamp(26px, calc((50vw - 290px) / 6.8), 78px);
        letter-spacing: -0.04em;
    }
    /* Beat 16 · "Investiga" (9 chars, palabra sola a la IZQUIERDA); divisor ≈ 9×0.58. */
    .hero-caption[data-beat="16"].hero-caption--key h2 {
        font-size: clamp(30px, calc((50vw - 300px) / 5.22), 96px);
    }
    /* Beat 19 · "Presenta" (8 chars, palabra sola): sin override caía en el key por
       defecto (132px) y se veía demasiado grande → misma escala que "Investiga". */
    .hero-caption[data-beat="19"].hero-caption--key h2 {
        font-size: clamp(30px, calc((50vw - 300px) / 5.22), 96px);
    }
    /* cap-solo a la IZQUIERDA del móvil en desktop (palabra sola, centrada vertical,
       pegada al borde izq del teléfono). Especificidad 4 clases > side-right base. */
    .hero-caption.side-right.hero-caption--key.cap-solo {
        left: auto;
        right: calc(100% - 15.26% + clamp(6px, 1.1vw, 16px));
        text-align: right;
        transform: translateY(-50%) translateX(-44px);
    }
    .hero-caption.side-right.hero-caption--key.cap-solo.is-active { transform: translateY(-50%) translateX(0); }
    /* Beat 17 "Más" (cap-solo) a la DERECHA del móvil: ancla left contra el borde
       der del teléfono y entra desde la derecha. Especificidad +[data-beat] gana a
       la regla cap-solo base (izquierda). "Crea" (19) vuelve a la izquierda (default). */
    .hero-caption.side-right.hero-caption--key.cap-solo[data-beat="17"],
    .hero-caption.side-right.hero-caption--key.cap-solo[data-beat="23"],
    .hero-caption.side-right.hero-caption--key.cap-solo[data-beat="25"],
    .hero-caption.side-right.hero-caption--key.cap-solo[data-beat="27"] {
        right: auto;
        left: calc(100% - 16.71% + clamp(6px, 1.1vw, 16px));
        text-align: left;
        transform: translateY(-50%) translateX(44px);
    }
    .hero-caption.side-right.hero-caption--key.cap-solo[data-beat="17"].is-active,
    .hero-caption.side-right.hero-caption--key.cap-solo[data-beat="23"].is-active,
    .hero-caption.side-right.hero-caption--key.cap-solo[data-beat="25"].is-active,
    .hero-caption.side-right.hero-caption--key.cap-solo[data-beat="27"].is-active { transform: translateY(-50%) translateX(0); }
    /* Beat 24 "Compatible"(izq) + "con"(der) flanqueando el mockup, y beat 25
       "Veri*Factu"(der) · MISMO tamaño (geometría que hace caber "Compatible"). */
    .hero-caption[data-beat="24"].hero-caption--lead h2,
    .hero-caption[data-beat="24"].hero-caption--key h2,
    .hero-caption[data-beat="25"].hero-caption--key h2 {
        font-size: clamp(26px, calc((50vw - 300px) / 6.4), 80px);
        letter-spacing: -0.03em;
    }
    /* Beats 31/32 · frases partidas flanqueando el mockup ("¿No encuentras"|"lo que
       buscas?" y "Pídeselo a"|"tu asistente"), MISMO tamaño y que quepan los lados. */
    .hero-caption[data-beat="31"].hero-caption--lead h2,
    .hero-caption[data-beat="31"].hero-caption--key h2,
    .hero-caption[data-beat="32"].hero-caption--lead h2,
    .hero-caption[data-beat="32"].hero-caption--key h2 {
        font-size: clamp(24px, calc((50vw - 300px) / 6.8), 76px);
        letter-spacing: -0.03em;
    }
    /* Beat 18 · "Hazlo Mejor" PARTIDO — ambas mitades al MISMO tamaño para que se
       lea como una frase flanqueando el teléfono (igual escala que "Investiga"). */
    .hero-caption[data-beat="18"].hero-caption--lead h2,
    .hero-caption[data-beat="18"].hero-caption--key h2 {
        font-size: clamp(30px, calc((50vw - 300px) / 5.22), 96px);
        letter-spacing: -0.04em;
    }
    /* Beat 20 · "Descubre nuestro" (lead izq, más pequeño, cabe en el hueco) +
       "Modo Negocio" (key der, grande, en DOS filas vía <br>). */
    .hero-caption[data-beat="20"].hero-caption--lead h2 {
        font-size: clamp(20px, calc((50vw - 300px) / 8.2), 44px);
    }
    .hero-caption[data-beat="20"].hero-caption--key h2 {
        font-size: clamp(34px, calc((50vw - 300px) / 4.2), 104px);
        line-height: 0.95;
    }
    /* Beats 22 "Crea" y 23 "Facturas" · MISMO tamaño explícito (cabe "Facturas"
       en el hueco derecho a cualquier ancho). Beat 26 "Crea" (presupuestos) reusa
       la MISMA escala que su gemelo de la factura. */
    .hero-caption[data-beat="22"].hero-caption--key h2,
    .hero-caption[data-beat="23"].hero-caption--key h2,
    .hero-caption[data-beat="26"].hero-caption--key h2 {
        font-size: clamp(40px, calc((50vw - 300px) / 4.4), 110px);
    }
    /* Beat 27 · "Presupuestos" (12 chars, palabra sola a la DERECHA): tamaño que cabe
       en el hueco derecho a cualquier ancho (geometría de "conversación"). */
    .hero-caption[data-beat="27"].hero-caption--key h2 {
        font-size: clamp(26px, calc((50vw - 300px) / 6.8), 82px);
    }
}

/* ----- Móvil: NO caben los lados → "Todo tu" y "mundo" APILADOS y centrados
   SOBRE el teléfono, entrando desde arriba. ----- */
@media (max-width: 900px) {
    /* Móvil: el mockup del hero NO hace la entrada (phonePlace). En DESKTOP esa
       entrada se reproduce UNA vez (el script crea el pin —y reparenta el nodo—
       ANTES de que la animación arranque, durante su delay de 0.45s). En MÓVIL, y
       SOLO en la primera visita (caché FRÍA: GSAP + el script tardan más en bajar
       y ejecutar), el reparent del pin cae a MEDIA animación y la REINICIA → el
       teléfono "se carga dos veces". Al recargar en caliente el script va rápido y
       entra durante el delay → no se nota; por eso el doble solo pasa la 1ª vez.
       Al quitar la entrada SOLO en móvil, el mockup simplemente está presente (su
       imagen base es eager) → entrada limpia, sin doble. Los títulos (h1/subtítulo)
       van FUERA del pin → conservan su rise. Desktop: intacto (este @media no le toca).

       IMPRESCINDIBLE el prefijo `.hero-cinema`: la regla inline de index.html
       (`.mockup-container.reveal { animation: phonePlace }`) carga DESPUÉS de este
       fichero y tiene la MISMA especificidad (0,2,0) → ganaba por orden de cascada
       y la animación volvía (este override quedaba muerto). Con `.hero-cinema`
       subimos a (0,3,0) y este `animation: none` gana siempre, sin depender del
       orden de carga. */
    .hero-cinema .mockup-container.reveal { opacity: 1; animation: none; }

    /* Móvil: anular el will-change PERMANENTE. En DESKTOP (intacto) promociona las
       34 capas (.hero-shot) + los textos a capas GPU permanentes; allí sobra memoria
       de texturas → nítidas. En MÓVIL esa memoria es limitada: 34 imágenes grandes
       en capas permanentes hacen que el compositor las SUBMUESTREE → mockups borrosos
       al scrollear. Con will-change:auto el navegador solo promociona la capa que
       está en transición (breve) y pinta el resto a resolución NATIVA → nítido. El
       cross-dissolve sigue igual. Solo móvil; desktop no se toca (este @media no le aplica). */
    .hero-shot,
    .hero-caption { will-change: auto; }

    .hero-caption,
    .hero-caption.side-right,
    .hero-caption.side-left {
        left: 50%;
        right: auto;
        top: auto;
        width: max-content;
        max-width: 92vw;
        text-align: center;
        transform: translateX(-50%) translateY(18px);
    }
    /* Título en UNA sola línea (móvil, "por ahora"). Las dos mitades (lead + key,
       separadas en el HTML porque en DESKTOP flanquean el móvil) se colocan AQUÍ en
       la MISMA fila — el lead a la izquierda del centro, el key a la derecha — con
       el MISMO tamaño, leyéndose como una frase ("Todo tu mundo"). Quedan justo
       sobre el teléfono. Cualquier beat futuro hereda esto (clases genéricas). */
    .hero-caption--lead,
    .hero-caption--key {
        top: auto;
        bottom: calc(100% + clamp(14px, 3.6vw, 26px));
        max-width: 50vw;
    }
    /* El punto de unión lead|key se ancla al centro y luego se DESPLAZA media
       diferencia de anchos (--cap-shift, lo fija el JS midiendo cada mitad) para
       que la FRASE ENTERA quede centrada aunque el reparto sea desigual. */
    .hero-caption.side-left.hero-caption--lead {
        left: auto; right: calc(50% + var(--cap-shift, 0px)); text-align: right;
        padding-right: 0.15em;
        transform: translateY(18px);
    }
    .hero-caption.side-right.hero-caption--key {
        left: calc(50% - var(--cap-shift, 0px)); right: auto; text-align: left;
        padding-left: 0.15em;
        transform: translateY(18px);
    }
    .hero-caption.side-left.hero-caption--lead.is-active,
    .hero-caption.side-right.hero-caption--key.is-active {
        transform: translateY(0);
    }
    /* Título de UNA palabra (cap-solo): sin mitad lead que lo balancee, el JS no le
       fija --cap-shift → centrarlo a mano sobre el teléfono. Especificidad ≥ la regla
       side-right (4 clases) para ganarle el left/transform. */
    .hero-caption.side-right.hero-caption--key.cap-solo {
        left: 50%; right: auto; text-align: center;
        transform: translateX(-50%) translateY(18px);
    }
    .hero-caption.side-right.hero-caption--key.cap-solo.is-active { transform: translateX(-50%) translateY(0); }
    /* Beat 20 móvil · "Descubre nuestro" (arriba) sobre "Modo Negocio" (2 filas),
       TODO centrado y APILADO sobre el teléfono (no en una fila como los demás:
       el <br> de "Modo Negocio" rompería el reparto lead|key). 4 clases-nivel
       (incl. [data-beat]) ganan a las reglas genéricas de arriba. */
    .hero-caption[data-beat="20"].hero-caption--lead,
    .hero-caption[data-beat="20"].hero-caption--key,
    .hero-caption[data-beat="31"].hero-caption--lead,
    .hero-caption[data-beat="31"].hero-caption--key,
    .hero-caption[data-beat="32"].hero-caption--lead,
    .hero-caption[data-beat="32"].hero-caption--key {
        left: 50%; right: auto; padding: 0; text-align: center; max-width: 92vw;
        transform: translateX(-50%) translateY(18px);
    }
    /* "Modo Negocio" en móvil = UNA línea (el <br> es solo de desktop) → título en
       DOS líneas: "Descubre nuestro" sobre "Modo Negocio". */
    .brk-desk { display: none; }
    .hero-caption[data-beat="20"].hero-caption--key,
    .hero-caption[data-beat="31"].hero-caption--key,
    .hero-caption[data-beat="32"].hero-caption--key  { bottom: calc(100% + clamp(10px, 2.6vw, 18px)); }
    .hero-caption[data-beat="20"].hero-caption--lead,
    .hero-caption[data-beat="31"].hero-caption--lead,
    .hero-caption[data-beat="32"].hero-caption--lead { bottom: calc(100% + clamp(10px, 2.6vw, 18px) + 1.6em); }
    .hero-caption[data-beat="20"].hero-caption--lead.is-active,
    .hero-caption[data-beat="20"].hero-caption--key.is-active,
    .hero-caption[data-beat="31"].hero-caption--lead.is-active,
    .hero-caption[data-beat="31"].hero-caption--key.is-active,
    .hero-caption[data-beat="32"].hero-caption--lead.is-active,
    .hero-caption[data-beat="32"].hero-caption--key.is-active { transform: translateX(-50%) translateY(0); }
    /* Mismo tamaño en ambas mitades; lo marca la frase más larga ("En una sola
       conversación") para que SIEMPRE quepa en UNA línea a cualquier ancho. */
    .hero-caption--lead h2,
    .hero-caption--key h2 {
        font-size: clamp(22px, 7vw, 36px);
        font-weight: 800;
        letter-spacing: -0.03em;
        line-height: 1.0;
    }
}

/* ----- reduced-motion: sin transiciones ----- */
@media (prefers-reduced-motion: reduce) {
    .hero-shot, .hero-caption, .hero .hero-cta { transition: none; }
    .hero-shot.is-screen { filter: none; }
    .hero-cinema .hero-freeze, .hero-cinema .mockup-masked { transition: none; }
}
