/* =========================================================================
   NVL HOME HERO — el héroe de marca (components/home-hero.php) y sus dos
   variantes, clásica e inmersiva.

   LO COMPARTEN DOS VISTAS desde el 2026-10-24: templates/home.php y
   templates/category.php. El owner pidió el héroe de la Home en la categoría
   «sin simplificaciones ni cambios visuales», así que no hay una segunda
   versión de nada: es esta hoja, cargada en las dos.

   Salió de nvl-home.css en un CORTE LITERAL —ni una regla cambió de valor—,
   para no arrastrar a la categoría los 11 KB de parrilla y destacados que ahí
   no se usan, y para que mover el héroe no pudiera mover la Home.

   EL PREFIJO `nvl-home-hero` ES HISTÓRICO y se conserva a propósito: son 66
   apariciones entre hojas, plantillas y pruebas, y el encargo decía
   expresamente que no se tocara el héroe de la Home. El nombre dice de dónde
   viene, no dónde se puede usar.

   Depende de nvl-components.css (y esa, de nvl-base.css) — ver inc/assets.php.
   Mobile-first. docs/home-especificacion-visual.md §4.2 es la fuente de cada
   regla.
   ========================================================================= */

/* --- Hero de marca (components/home-hero.php) -----------------------------

   LA BANDA TIENE UNA FUENTE DE LUZ (owner, 2026-10-18). Era tinta sólida de
   borde a borde y, en escritorio, de 100svh de alto: el owner la describió como
   «un texto plano colocado sobre un fondo oscuro». El problema no era la tinta
   del titular —el blanco ya da 17.85:1, el máximo posible sobre esta banda— sino
   el campo, que no tenía ni dirección de luz ni profundidad. El brillo se
   construye DETRÁS, con la misma mezcla de realce que ya usaban la barra
   promocional y la tarjeta de transferencia (ver --nvl-color-tinta-glow).

   El background-color se queda DEBAJO del background-image a propósito: si
   color-mix fallara, la banda sigue siendo tinta legible y el texto no se pierde.
   En forced-colors la imagen se descarta y vuelve Canvas, que es lo correcto:
   esto es campo, nunca información. */

.nvl-home-hero {
    background-color: var(--nvl-color-secondary);
    background-image: var(--nvl-gradient-hero);
    color: var(--nvl-color-surface);
    padding-block: var(--nvl-space-2xl);
}

.nvl-home-hero__inner {
    display: grid;
    gap: var(--nvl-space-xl);
}

.nvl-home-hero__text {
    display: flex;
    flex-direction: column;
    gap: var(--nvl-space-sm);
    text-align: left;
}

/* --- Héroe inmersivo: segunda variante (owner, 2026-10-23) ---------------

   «Un pez en formato PNG que flota con una animación suave de subida y
   bajada, colocado en primer plano», sobre «una imagen que cubra el 100% del
   ancho del Hero». Es el héroe de la landing de referencia, traído a nuestro
   material: mismo bloque de texto, mismas columnas, mismo CTA. LA VARIANTE
   CLÁSICA NO PIERDE NI GANA UNA REGLA — todo lo de aquí abajo cuelga de
   .nvl-home-hero--immersive.

   El fondo va en una capa propia y no de background-image de la sección para
   que pueda ser un <img> con srcset y fetchpriority (ver el componente). Eso
   obliga a posicionarlo, y posicionarlo obliga a que la sección sea su bloque
   contenedor. */

.nvl-home-hero--immersive {
    position: relative;
    /* El pez se desplaza 15px hacia arriba en su animación y el fondo llena la
       caja al milímetro: nada debe asomar por los cantos. */
    overflow: hidden;
    /* La fotografía sustituye al brillo radial. El background-COLOR se queda
       debajo, como en la variante clásica: mientras la foto carga —o si no hay
       ninguna— la banda sigue siendo tinta y el texto se lee igual. */
    background-image: none;
}

.nvl-home-hero__backdrop {
    position: absolute;
    inset: 0;
}

.nvl-home-hero__backdrop-image {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: var(--nvl-media-focus);
}

/* El velo. Va en un pseudo-elemento de la capa de fondo y no como filtro sobre
   la imagen: así no crea capa de composición sobre el elemento LCP. El número
   está calculado contra una foto blanca pura; la cuenta vive con el token. */
.nvl-home-hero__backdrop::after {
    content: "";
    position: absolute;
    inset: 0;
    background: var(--nvl-color-overlay-hero);
}

/* El contenido sube por encima del fondo. Basta con posicionarlo: sin z-index,
   porque un elemento posicionado ya pinta sobre los hermanos que no lo están y
   aquí el orden del DOM hace el resto. */
.nvl-home-hero--immersive .nvl-home-hero__inner {
    position: relative;
}

/* EL PEZ. En móvil va DEBAJO del botón (decisión del owner), así que la
   variante anula las dos reglas que sacan a sangre la foto clásica: el
   `order: -1` que la sube y el margen negativo que rompe el contenedor. No es
   la misma pieza ni cumple la misma función. */
/* El selector lleva las DOS clases a propósito, y no es cosmética: la regla de
   la foto clásica que pone `order: -1` vive más abajo en esta misma hoja y
   tiene la misma especificidad con una sola clase, así que ganaría por orden
   de cascada y el pez volvería a salir por encima del titular en móvil.
   Comprobado en el navegador antes de escribirlo así. */
.nvl-home-hero--immersive .nvl-home-hero__media--fish {
    order: 0;
    margin-inline: 0;
    display: flex;
    justify-content: center;
}

.nvl-home-hero__fish {
    width: 100%;
    max-width: 28rem;
    height: auto;
    /* Seis segundos, ida y vuelta: exactamente la animación de la landing de
       referencia (landing-referencia.md §2.7). Solo transform, así que no
       provoca ni un reflow y corre en el compositor, sin competir con la carga
       del LCP que tiene justo detrás. Se anula entera con movimiento reducido,
       al final de esta hoja. */
    animation: nvl-hero-float 6s ease-in-out infinite;
    /* Una silueta recortada flotando sobre una foto necesita separarse de ella,
       y aquí sí es una sombra oscura la que lo hace: el pez es la figura clara
       y el campo que tiene detrás está al 82% de tinta. Es la misma sombra que
       la referencia da a su pez y el token que ya existía para medios sobre
       banda. */
    filter: var(--nvl-shadow-hero-media);
}

@keyframes nvl-hero-float {
    0%, 100% { transform: translateY(0) scale(1); }
    50%      { transform: translateY(-15px) scale(1.02); }
}

/* En forced-colors la foto y su velo desaparecen y vuelve la tinta plana: el
   modo de alto contraste no negocia con una fotografía debajo del texto. */
@media (forced-colors: active) {
    .nvl-home-hero__backdrop {
        display: none;
    }
}

/* Antetítulo: estático (.nvl-eyebrow sobre banda oscura) o pastilla de
   campaña activa (--campaign) cuando bar_message no está vacío. */
.nvl-home-hero__eyebrow {
    color: var(--nvl-color-accent);
}

.nvl-home-hero__eyebrow--campaign {
    align-self: start;
    background: var(--nvl-color-promo-badge);
    color: var(--nvl-color-surface);
    border-radius: var(--nvl-radius-pill);
    padding: var(--nvl-space-3xs) var(--nvl-space-xs);
}

/* EN MÓVIL BAJA A 32px (owner, 2026-10-22). Pidió ese valor, se midió antes
   de aplicarlo y lo confirmó con el número delante. Medido en staging con el
   titular real:

     ancho   columna   36px        32px        30px
     360     320       3 líneas    3 líneas    2 líneas
     375     335       3 líneas    3 líneas    2 líneas
     390     350       3 líneas    2 líneas    2 líneas
     430     390       2 líneas    2 líneas    2 líneas

   Es decir: POR DEBAJO DE 390px el titular sigue cayendo en tres líneas, con
   una palabra suelta en las dos últimas. A 30px entraba en dos líneas en todos
   los anchos y además era un escalón que ya existía. El owner prefirió los 32
   exactos asumiendo las tres líneas; es su decisión y no se revierte sin él.

   Por eso el valor vive en --nvl-text-hero-mobile y no en la rampa: la escala
   no tiene escalón entre 2xl (30) y 3xl (36). Ver el token en nvl-base.css. */
.nvl-home-hero__title {
    font-size: var(--nvl-text-hero-mobile);
    font-weight: var(--nvl-weight-extrabold);
    line-height: var(--nvl-leading-tight);
    text-wrap: balance;
}

/* EL TITULAR TOPA EN 48px (owner, 2026-10-22). Subía a --nvl-text-5xl (56px)
   desde 1280 y el owner lo reportó: «hace que las palabras se desborden y se
   distribuyan de forma poco equilibrada… pueden quedar dos palabras en una
   línea y tres en la siguiente, o incluso una sola». La columna de texto del
   héroe mide ~545px a 1440 —es la pista pequeña del 1fr/1.25fr—, así que a
   56px apenas caben dos palabras por línea y `text-wrap: balance`, que ya
   estaba puesto, no tiene con qué repartir: equilibra el número de líneas, no
   inventa ancho. A 48px entra una palabra más por línea y el reparto deja de
   depender de la longitud de cada una.
   El escalón de 1280 se RETIRA en vez de redeclararse: el titular se queda en
   la escalera 36 → 48 y no hay un tercer tramo que mantener.
   CONSECUENCIA: --nvl-text-5xl queda sin usar. Se deja en el :root porque es
   un escalón de la escala tipográfica, no una regla muerta. */
@media (min-width: 768px) {
    .nvl-home-hero__title {
        font-size: var(--nvl-text-4xl);
    }
}

.nvl-home-hero__subtitle {
    max-width: var(--nvl-measure);
    color: var(--nvl-color-text-inverse-muted);
    font-size: var(--nvl-text-base);
    line-height: var(--nvl-leading-relaxed);
}

/* UN SOLO BOTÓN desde el 2026-10-20 (owner): el contenedor ya no reparte dos,
   así que pierde el `gap` y el `flex-wrap`, que con un hijo no hacían nada. Se
   conserva porque sigue siendo el ancla del ancho completo en móvil. */
.nvl-home-hero__ctas {
    display: flex;
    flex-direction: column;
}

.nvl-home-hero__ctas .nvl-button {
    width: 100%;
}

/* EN MÓVIL LA IMAGEN ABRE EL HÉROE, A SANGRE (owner, 2026-10-18). El orden del
   DOM NO cambia —antetítulo, H1, texto, botones y la media al final— y el orden
   visual lo pone `order`. Son cuatro razones, y la segunda es la que decide:

   1. La imagen no es enfocable, así que reordenarla visualmente no afecta al
      orden de foco (WCAG 2.4.3). Esa es la única objeción real contra `order`.
   2. home-hero.php usa EL PROPIO TÍTULO del héroe como alt de respaldo cuando
      la mediateca no trae uno. Con la imagen primero en el DOM, un lector de
      pantalla diría «imagen: Tu tienda de…» y acto seguido «encabezado 1: Tu
      tienda de…». El orden actual del DOM es el bueno para voz.
   3. El H1 debe seguir siendo el primer contenido textual del <main> (1.3.1).
   4. Un solo render de servidor para todos los anchos: condicionar por ancho en
      PHP obligaría a duplicar el marcado. */
.nvl-home-hero__media {
    display: block;
    order: -1;
    /* Rompe el padding del contenedor y llega a los dos bordes del viewport.
       NO se usa 100vw: incluiría la barra de scroll y abriría desplazamiento
       horizontal. Este cálculo es exacto, porque por debajo de 1320 el
       contenedor mide el 100% del body. */
    margin-inline: calc(var(--nvl-container-pad) * -1);
}

.nvl-home-hero__image {
    width: 100%;
    aspect-ratio: var(--nvl-ratio-hero);
    object-fit: cover;
    /* El encuadre, que faltaba. El token está escrito para esta fotografía: el
       sustrato ocupa el tercio inferior y el pez nada por encima de la mitad,
       así que recortar simétricamente se come aleta dorsal y no se come grava.
       Con la caja a sangre el recorte es mayor que antes: importa más que nunca. */
    object-position: var(--nvl-media-focus);
    /* A sangre no hay margen que revele un radio: 24px en las esquinas dejarían
       dos muescas de banda contra la cabecera y se leerían como un error de
       recorte. El radio vuelve en ≥768, donde la imagen tiene aire alrededor. */
    border-radius: 0;
}

/* El protagonista no se anuncia con 40px de azul vacío por encima. Guardado con
   :has() porque sin imagen (image_id = 0) el antetítulo quedaría pegado a la
   cabecera. El padding de abajo se conserva, y la separación con el antetítulo
   es el gap de 32px que el inner ya tenía: no se añade ningún margen. */
@media (max-width: 767px) {
    /* ACOTADA A LA VARIANTE CLÁSICA el 2026-10-23, y es lo único que esta
       tanda le toca al héroe de siempre: el comportamiento no cambia, solo
       deja de alcanzar a la inmersiva. Allí la portada es el fondo, que ya
       llega a los dos bordes por su cuenta, y el titular necesita su aire por
       arriba como cualquier otro. Sin el :not() ganaba esta regla —misma
       especificidad y va después—, y el héroe inmersivo abría pegado a la
       cabecera; comprobado en el navegador. */
    .nvl-home-hero:not(.nvl-home-hero--immersive):has(.nvl-home-hero__media) {
        padding-block-start: 0;
    }
}

@media (min-width: 768px) {
    /* El foco de luz sube al hueco entre las dos columnas: el mismo brillo
       levanta el flanco del titular y el filo de la fotografía. Se redefine el
       punto, nunca el gradiente. */
    .nvl-home-hero {
        --nvl-hero-glow-at: var(--nvl-hero-glow-at-wide);
    }

    .nvl-home-hero__inner {
        grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
        gap: var(--nvl-space-3xl);
        align-items: center;
    }

    .nvl-home-hero__media {
        order: 0;
        margin-inline: 0;
    }

    .nvl-home-hero__image {
        border-radius: var(--nvl-radius-xl);
        /* Filo luminoso, no sombra: sobre tinta una sombra oscura es invisible
           porque el objeto ya es más oscuro que ella. Spread de 1px y blur 0,
           así que sigue el radio exacto sin envoltura ni overflow: hidden, y
           sin crear capa de composición sobre el elemento LCP. */
        box-shadow: var(--nvl-shadow-tinta-edge);
    }

    .nvl-home-hero__ctas {
        flex-direction: row;
    }

    .nvl-home-hero__ctas .nvl-button {
        width: auto;
    }
}

/* LA IMAGEN PASA A SER LA COLUMNA GRANDE (owner, 2026-10-18). Era 1.1fr/1fr: a
   1320px, 662px de texto contra 602px de media — la rejilla le daba la mitad
   grande al texto justo donde se pide protagonismo para la foto. La media gana
   +22% a 1024, +16% a 1280 y +11% desde 1320. Ninguna sombra arregla una
   proporción que le quita la mitad grande al protagonista.

   Bloque propio, FUERA de la guarda `and (min-height: 640px)` de abajo: la
   proporción no depende del alto de la ventana. Entre 768 y 1023 no se toca,
   porque a esos anchos una columna de imagen mayor deja el H1 de 48px en cuatro
   líneas. */
@media (min-width: 1024px) {
    .nvl-home-hero__inner {
        grid-template-columns: minmax(0, 1fr) minmax(0, 1.25fr);
    }
}

/* Asomo de la parrilla de categorías sobre el pliegue en escritorio: la
   guarda de altura evita aplastar el hero en portátiles de pantalla corta.
   Descuenta también la barra promocional superior (--nvl-promo-bar-h: 0px
   sin barra o cerrada; con ella, su alto constante de una línea, que define
   nvl-base.css). */
@media (min-width: 1024px) and (min-height: 640px) {
    .nvl-home-hero {
        min-height: calc(100svh - var(--nvl-promo-bar-h) - var(--nvl-header-h) - var(--nvl-peek));
        display: flex;
        align-items: center;
    }

    .nvl-home-hero__inner {
        width: 100%;
    }
}

/* --- Movimiento reducido ---------------------------------------------------
   Va al final de ESTA hoja, con la animación que cancela: una anulación solo
   funciona si llega después de lo que anula, y las dos viven aquí. */

@media (prefers-reduced-motion: reduce) {
    /* .nvl-home-hero__image sigue sin aparecer aquí: la foto de la variante
       clásica no anima nada, ni el brillo de la banda, que es estático.
       EL PEZ DE LA VARIANTE INMERSIVA SÍ (alta del 2026-10-23). Flota en bucle
       y sin fin, que es justo el movimiento del que protege esta preferencia:
       se queda quieto en su sitio, sin desplazamiento y sin escala. La imagen
       no pierde nada por estar parada — es un adorno, no información. */
    .nvl-home-hero__fish {
        animation: none;
    }
}
