/* Landing de apertura · /apertura — Fashion Lab Academy.

   RÉPLICA VISUAL de `recursos_visuales/webinar/index.html` (dirección,
   25-08-2026). No es una interpretación: los valores de abajo están
   TRANSCRITOS de la referencia, que es Tailwind compilado, resolviendo cada
   utilidad a su declaración real. Donde se lee `1.5rem` es porque allí pone
   `gap-6`; donde se lee `#0000004d` es porque allí pone `bg-black/30`.

   Puntos de corte de la referencia (Tailwind por defecto), respetados:
     sm = 640px · md = 768px · lg = 1024px
   La referencia es mobile-first: la base es móvil y las medias AMPLÍAN.

   Lo único que NO se transcribe, y por qué:

   · EL ROJO. La referencia usa `#C62828` / `#B71C1C`, que es el color de
     marca de su empresa. Aquí se usa el carmín de Fashion Lab —`--carmine`
     #d01d3f y `--carmine-dark` #ad1532—, que ocupa exactamente el mismo
     papel y está a un tono de distancia. Es la única sustitución cromática:
     todas las opacidades, tamaños y posiciones son las de la referencia.

   · EL CTA. Es el `.primary-cta` real de Fashion Lab (autorizado como pieza
     reutilizada). Se le da la GEOMETRÍA de la referencia —radio, relleno,
     cuerpo, ancho completo en móvil— y se conserva su identidad: degradado,
     borde y sombra propios, más su sistema de atención `wowCtaEffect()`.

   · EL METRAJE del vídeo. El de la referencia es material de un tercero. El
     mecanismo es idéntico (`fixed inset-0`, `object-fit:cover`, opacidad
     .35, velo negro al 50 %); cambia el archivo, que es b-roll de atelier
     del propio Fashion Lab graduado al mismo carácter en el encode.

   Todo va con ámbito `body.apertura-route` y prefijo `.ap-*`: la colisión con
   el resto del sitio es imposible por construcción. El `<dialog>` NO se viste
   aquí — su `.registration-dialog` vive en `landing-production-source.css` y
   sus entrañas en `programa-form-source.css`. */

/* ── Tipografía de la referencia, autohospedada ───────────────────────────
   La referencia carga Antonio + Urbanist desde Google. Aquí se sirven desde
   el propio origen: `tests/fe/dist-servido.test.mjs` prohíbe que el HTML
   servido nombre `fonts.googleapis.com` o `fonts.gstatic.com`, y la política
   de cookies promete cero terceros antes de decidir. Ambas son OFL 1.1 y su
   licencia viaja al lado del binario, igual que Bodoni, Archivo y Manrope. */
@font-face {
  font-family: 'Antonio Apertura';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/assets/fuentes/apertura/antonio-700-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Urbanist Apertura';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/assets/fuentes/apertura/urbanist-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

body.apertura-route {
  /* Papeles cromáticos de la referencia, con el carmín de Fashion Lab. */
  --ap-accent: var(--carmine);
  --ap-accent-dark: var(--carmine-dark);
  --ap-accent-08: rgba(208, 29, 63, 0.08);
  --ap-accent-20: rgba(208, 29, 63, 0.2);
  --ap-accent-30: rgba(208, 29, 63, 0.3);
  --ap-accent-40: rgba(208, 29, 63, 0.4);
  --ap-display: 'Antonio Apertura', 'Arial Narrow', Arial, sans-serif;
  --ap-body: 'Urbanist Apertura', 'Helvetica Neue', Arial, sans-serif;

  /* Alto REAL de la barra superior, derivado de sus propias medidas y no
     medido a ojo: 0.625rem de relleno arriba + 0.625rem abajo + 1.25rem de
     interlínea del texto + 1 px de borde inferior. Si mañana cambia el
     relleno de la barra se cambia aquí, y la geometría del héroe sigue
     cuadrando sola. */
  --ap-topbar-alto: calc(2.5rem + 1px);

  /* `html, body, #root { background-color:#000 }` de la referencia. */
  background: #000;
  color: #fff;
  font-family: var(--ap-body);
}

/* `.min-h-screen.bg-black/40.text-white.relative` de la referencia, servida
   como COLUMNA (26-08-2026).

   POR QUÉ LA COLUMNA. La barra superior es `sticky`, y `sticky` OCUPA sitio
   en el flujo. Con el héroe pidiendo `min-height:100vh` por su cuenta, la
   pila medía `barra + 100vh + pie`: el héroe arrancaba 41 px por debajo del
   borde de la pantalla y su contenido —centrado dentro de esa caja— caía
   otros 41 px por debajo del centro real. En móvil eso dejaba 252 px de nada
   antes del logo (390×844) y empujaba el pie fuera del pliegue. Declarada la
   página como columna con el `main` creciendo, el héroe recibe EXACTAMENTE
   el hueco que dejan barra y pie: no hay que restar nada a mano.

   El `<dialog>` de solicitud también cuelga de aquí y no se ve afectado: con
   `showModal()` vive en la capa superior, fuera del flujo, y cerrado es
   `display:none`. */
body.apertura-route .apertura-page {
  display: flex;
  position: relative;
  flex-direction: column;
  /* `100svh` es el viewport con la barra del navegador DESPLEGADA, que es lo
     que de verdad se ve al abrir la página en un móvil; `100vh` mide el
     viewport grande —el de la barra recogida— y promete alto que aún no
     existe. La primera declaración queda de respaldo para quien no entienda
     `svh`. */
  min-height: 100vh;
  min-height: 100svh;
  background: rgba(0, 0, 0, 0.4);
  color: #fff;
}

/* ── Vídeo de fondo ───────────────────────────────────────────────────────
   Referencia: `<div class="fixed inset-0 z-0 pointer-events-none">` con
   `<video class="w-full h-full object-cover opacity-[0.35]">` y encima
   `<div class="absolute inset-0 bg-black/50">`.

   NINGÚN antepasado puede llevar `transform`, `filter`, `perspective`,
   `will-change` ni `contain`: cualquiera de ellos convertiría a ese elemento
   en bloque contenedor y el `fixed` dejaría de anclarse al viewport. */
body.apertura-route .ap-video {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}

body.apertura-route .ap-video video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* La referencia sirve `opacity-[0.35]` + `bg-black/50`, que sobre SU metraje
     —humo y chispas sobre negro puro— basta para que se vea el movimiento.
     Sobre b-roll de atelier ya graduado en el encode, esa combinación lo
     apagaba casi del todo. Se sube la opacidad y se afloja el velo lo justo
     para que se perciba el ambiente: efectivo 0.35×0.50 = 0.175 → 0.46×0.58 =
     0.267, un 50 % más de presencia. El texto sigue mandando: los titulares
     son marfil pleno y el lead va a rgba(255,255,255,.7) sobre un fondo que
     nunca supera el 27 % del vídeo ya oscurecido. */
  opacity: 0.46;
}

body.apertura-route .ap-video-scrim {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.42);
}

/* Sin movimiento: la referencia desactiva sus animaciones, y un vídeo en
   bucle es la más grande de todas. Queda el póster, ya graduado. */
@media (prefers-reduced-motion: reduce) {
  body.apertura-route .ap-video video {
    display: none;
  }

  body.apertura-route .ap-video {
    background: url('/media/apertura/hero-bg-poster.jpg') center / cover no-repeat;
  }
}

/* ── Barra superior ───────────────────────────────────────────────────────
   `sticky top-0 z-40 w-full bg-[#C62828] border-b border-white/10`, con
   `flex items-center justify-center py-2.5 px-4` dentro. */
body.apertura-route .ap-topbar {
  position: sticky;
  top: 0;
  z-index: 40;
  width: 100%;
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
  background: var(--ap-accent);
}

body.apertura-route .ap-topbar-inner {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0.625rem 1rem;
  text-align: center;
}

/* `text-white text-sm font-black tracking-widest uppercase` */
body.apertura-route .ap-topbar span {
  color: #fff;
  font-size: 0.875rem;
  font-weight: 900;
  letter-spacing: 0.1em;
  line-height: 1.25rem;
  text-transform: uppercase;
}

/* El `main` es el que crece: se queda con todo el alto que sobra entre la
   barra superior y el pie. `flex-shrink: 0` a propósito —nunca encoge—, para
   que un contenido más alto que la pantalla haga scroll en lugar de
   recortarse contra el `overflow:hidden` del héroe. */
body.apertura-route .ap-main {
  display: flex;
  flex: 1 0 auto;
  flex-direction: column;
}

/* Las secciones van a `relative z-10`, por encima del vídeo fijo. */
body.apertura-route .ap-main section {
  position: relative;
  z-index: 10;
}

/* Titulares: `h1..h6 { font-family: Antonio }` de la referencia.

   ACOTADO al héroe a propósito. La regla genérica por ELEMENTO alcanzaba
   también al `<h2>` del formulario comercial compartido, que vive dentro de
   esta página: el popup salía en Antonio aquí y en Bodoni en /vsl, /replay y
   /programa, siendo el MISMO componente. El diálogo es de captación en su
   lenguaje visual y no lo decide esta ruta. */
body.apertura-route .ap-hero h1 {
  font-family: var(--ap-display);
  font-weight: 900;
  text-wrap: balance;
}

/* El `<span class="text-[#C62828]">` que la referencia mete en cada titular. */
body.apertura-route .ap-accent {
  color: var(--ap-accent);
}

/* ── 1 · Héroe ────────────────────────────────────────────────────────────
   `relative min-h-screen flex flex-col items-center justify-center
    px-4 md:px-6 py-10 md:py-24 text-center overflow-hidden`

   REVISADO 26-08-2026 · el `min-h-screen` se retira en móvil y lo resuelve
   la columna de página. La referencia NO tiene una barra `sticky` ocupando
   flujo encima del héroe, así que allí `100vh` sí era la pantalla; aquí no
   lo era. Ahora el héroe se queda con el hueco entre barra y pie —ni un
   píxel más— y la página entera cabe sin scroll en móvil: vídeo, logo, H1,
   promesa, plazas, CTA y pie legal, que es exactamente lo que la cabecera de
   este fichero dice que es esta página. A partir de `md` el héroe vuelve a
   pedir pantalla completa (menos la barra): allí sí hay alto para el plano
   cinematográfico. */
body.apertura-route .ap-hero {
  display: flex;
  overflow: hidden;
  flex: 1 0 auto;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  /* Aire MÍNIMO garantizado: pase lo que pase con el reparto de abajo, la
     composición nunca se pega a la barra superior. */
  padding: 1.5rem 1rem;
  text-align: center;
}

/* ── Reparto del aire sobrante ────────────────────────────────────────────
   Dos separadores flexibles, uno antes de la pila y otro después, que se
   reparten lo que sobra en proporción 1:2. No es un número mágico: es el
   tercio superior. Centrar geométricamente una pila corta dentro de una
   pantalla alta la deja SIEMPRE demasiado baja —el centro óptico está por
   encima del centro real—, y en móvil ese error se comía casi un tercio de
   la pantalla antes de que apareciera el logo.

   Al ser una PROPORCIÓN y no una medida, se adapta solo a cualquier alto:
   cuanto más alta la pantalla, más aire, siempre en la misma relación. Y el
   sobrante que queda debajo del CTA no es un hueco vacío, es el vídeo. */
body.apertura-route .ap-hero::before,
body.apertura-route .ap-hero::after {
  display: block;
  width: 0;
  content: '';
}

body.apertura-route .ap-hero::before {
  flex: 1 1 0;
}

body.apertura-route .ap-hero::after {
  flex: 2 1 0;
}

/* `absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2
    w-[800px] h-[800px] rounded-full bg-[#C62828]/8 blur-[140px]`,
   dentro de un `absolute inset-0 pointer-events-none`. */
body.apertura-route .ap-hero-glow {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

body.apertura-route .ap-hero-glow::before {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 800px;
  height: 800px;
  border-radius: 9999px;
  background: var(--ap-accent-08);
  content: '';
  filter: blur(140px);
  translate: -50% -50%;
}

/* Bloque de marca: `mb-6 md:mb-8`. En la referencia es el wordmark
   «NEXIA PROGRAM» + «by Charly Creator»; aquí, el logo real. */
body.apertura-route .ap-brand {
  margin-bottom: 1.5rem;
}

body.apertura-route .ap-logo {
  display: block;
  width: 168px;
  max-width: 60vw;
  height: auto;
}

/* `text-[2rem] sm:text-5xl md:text-6xl lg:text-7xl font-black
    leading-[1.05] mb-4 md:mb-6 max-w-5xl` */
body.apertura-route .ap-hero h1 {
  max-width: 64rem;
  margin: 0 0 1rem;
  font-size: 2rem;
  line-height: 1.05;
}

/* `text-white/70 text-base md:text-xl mb-8 md:mb-12 max-w-3xl mx-auto
    leading-relaxed`

   El `mb` es MENOR que el de la referencia porque aquí, entre la promesa y
   el botón, va la placa de plazas: el aire que la referencia pone antes del
   CTA se reparte ahora entre promesa→placa (pequeño: van juntas) y
   placa→CTA (moderado). Antes esto se conseguía con un margen superior
   NEGATIVO en la placa que descontaba el de aquí; el resultado era el mismo
   y la lectura, peor. */
body.apertura-route .ap-lead {
  max-width: 48rem;
  margin: 0 auto 1rem;
  color: rgba(255, 255, 255, 0.7);
  font-size: 1rem;
  line-height: 1.625;
}

/* ── Etiqueta de capacidad ────────────────────────────────────────────────
   Añadido de dirección (26-08-2026): la referencia no la tiene. Va JUSTO bajo
   el subtítulo, antes del CTA.

   NO ESTRENA LENGUAJE. Es la misma voz de la barra superior —Urbanist, peso
   máximo, versalitas, tracking ancho— reencuadrada como placa sobre el carmín
   en lugar de barra sólida a sangre. Ni una fuente nueva, ni un color nuevo:
   `--ap-body` y la escala `--ap-accent-*` que ya existen arriba.

   POR QUÉ EL CARMÍN VA EN LA CAJA Y NO EN EL TEXTO. `--carmine` (#d01d3f)
   sobre negro da 3,93:1: pasa el umbral de elemento no textual (3:1) pero no
   el de texto normal (4,5:1), y esto es texto pequeño. Así que el carmín viste
   la placa —lavado, borde y halo— y el texto va en blanco pleno. Sobre el peor
   fotograma posible del vídeo (el más claro, ya al 46 % y bajo velo del 42 %)
   la placa compuesta se queda en rgb(77,31,39) y el blanco da ~13,6:1. El
   contraste no depende del metraje, que es justo lo que hacía falta.

   EL RITMO. La placa se pega a la promesa (16 px arriba en móvil, 24 en
   escritorio) y se despega del botón (28 y 36): pertenece a lo que se
   promete, no a lo que se pulsa. Esos huecos salen ahora del `mb` del
   subtítulo y del suyo propio —ya no hay margen negativo que descontar—, y
   el CTA sigue entero en pantalla en 360, 375, 390, 430, 768, 1024 y 1440,
   medido en Chrome. */
body.apertura-route .ap-capacidad {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  max-width: 100%;
  margin: 0 auto 1.75rem;
  padding: 0.45rem 1rem;
  /* El borde va por encima de `--ap-accent-40`: el fondo de esta ruta NO es
     negro, es b-roll ya teñido de rojo, y a 0,4 el filo se disolvía dentro del
     propio metraje. Medido sobre captura: a 0,6 la placa se lee como pieza
     recortada en los cinco anchos. */
  border: 1px solid rgba(208, 29, 63, 0.6);
  border-radius: 9999px;
  background:
    linear-gradient(135deg, rgba(208, 29, 63, 0.26), rgba(173, 21, 50, 0.34)),
    rgba(0, 0, 0, 0.55);
  color: #fff;
  font-family: var(--ap-body);
  /* Se escala con el viewport para que las 26 letras quepan en UNA línea desde
     390 px sin llegar nunca a gritar en escritorio: 11 px a 390, 12 px a 430,
     13 px de tope a partir de 449. */
  font-size: clamp(0.6875rem, 2.9vw, 0.8125rem);
  font-weight: 900;
  letter-spacing: 0.14em;
  line-height: 1.15;
  text-align: center;
  text-transform: uppercase;
  text-wrap: balance;
  /* Reposo: halo carmín tenue, sin anillo. Es también el estado que queda
     congelado con `prefers-reduced-motion`, y por eso ya es legible solo. */
  box-shadow: 0 0 18px var(--ap-accent-20);
  animation: ap-capacidad-latido 2.6s ease-in-out infinite;
}

/* Respiración, no parpadeo. Recrea —aislado, sin tocar nada de captación— el
   gesto de `cta-double-pulse` de `landing-production-source.css`: anillo que
   se abre desde 0, halo que se abre con él y micro escala. Se le quita lo que
   allí es propio del botón (el destello `cta-idle-glint` y el rebote de dos
   tiempos) y se le pone un solo latido lento.

   La opacidad NUNCA baja de 0,94: el texto no desaparece en ningún fotograma,
   que es la diferencia entre respirar y parpadear. */
@keyframes ap-capacidad-latido {
  0%,
  100% {
    opacity: 0.94;
    box-shadow:
      0 0 0 0 var(--ap-accent-30),
      0 0 16px rgba(208, 29, 63, 0.22),
      inset 0 0 0 rgba(208, 29, 63, 0);
    scale: 1;
  }

  50% {
    opacity: 1;
    box-shadow:
      0 0 0 6px var(--ap-accent-20),
      0 0 40px rgba(208, 29, 63, 0.55),
      inset 0 0 14px rgba(208, 29, 63, 0.4);
    scale: 1.02;
  }
}

/* `w-full md:w-auto flex flex-col items-center gap-3` */
body.apertura-route .ap-cta-wrap {
  display: flex;
  width: 100%;
  flex-direction: column;
  align-items: center;
  gap: 0.75rem;
}

/* ── CTA ──────────────────────────────────────────────────────────────────
   Pieza de Fashion Lab (`.primary-cta`) con la geometría de la referencia:
   `w-full py-5 rounded-xl text-lg tracking-widest uppercase` en móvil y
   `px-10 py-5 text-lg md:text-xl` en línea a partir de md. Se conservan su
   degradado, su borde y su sombra, que son su identidad.

   UN solo nodo: la referencia sirve dos botones (`md:hidden` + `hidden
   md:block`) y duplicarlo aquí duplicaría `data-application-open` y
   ensuciaría `cta_click`. */
body.apertura-route .ap-cta {
  position: relative;
  width: 100%;
  min-width: 0;
  min-height: 0;
  padding: 1.25rem 2.5rem;
  border: 0;
  border-radius: 0.75rem;
  font-size: 1.125rem;
  font-weight: 900;
  letter-spacing: 0.1em;
  line-height: 1.75rem;
  text-decoration: none;
  /* `shadow-[0_0_30px_rgba(198,40,40,0.4)]` de la referencia. La sombra
     propia de `.primary-cta` es mucho más densa (cuatro capas, con halo
     de 52 px y dos `inset`) y sobre este fondo florecía hasta comerse el
     texto. Se cambia SOLO la sombra y el borde: el degradado, la caja y el
     sistema de atención de Fashion Lab siguen intactos. */
  box-shadow: 0 0 30px var(--ap-accent-40);
}

body.apertura-route .ap-cta:hover {
  /* `hover:shadow-[0_0_50px_rgba(198,40,40,0.5)]` */
  transform: none;
  box-shadow: 0 0 50px rgba(208, 29, 63, 0.5);
}

body.apertura-route .ap-cta:focus-visible {
  box-shadow:
    0 0 0 3px #000,
    0 0 0 5px #fff,
    0 0 50px rgba(208, 29, 63, 0.5);
}

/* Halo pulsante del CTA. En la referencia es un `<span class="cta-halo">`
   animado con `@keyframes cta-ping` (escala 1 → 1.45 mientras la opacidad
   cae de .30 a 0, 2 s). Aquí es un pseudoelemento: mismo efecto, sin nodo
   extra que pudiera capturar el clic del modal.

   SOLO a partir de md, como en la referencia: allí el halo vive únicamente
   en el botón en línea de escritorio (`hidden md:block`); el botón a ancho
   completo de móvil no lo lleva. */
body.apertura-route .ap-cta::after {
  content: none;
}

@media (min-width: 768px) {
  body.apertura-route .ap-cta::after {
    position: absolute;
    z-index: -1;
    border-radius: 0.75rem;
    background: var(--ap-accent);
    animation: ap-cta-ping 2s cubic-bezier(0, 0, 0.2, 1) infinite;
    content: '';
    inset: 0;
    pointer-events: none;
  }
}

@keyframes ap-cta-ping {
  0% {
    opacity: 0.3;
    scale: 1;
  }

  100% {
    opacity: 0;
    scale: 1.45;
  }
}

/* ── Pie ──────────────────────────────────────────────────────────────────
   `border-t border-white/5 py-8 bg-black` con `max-w-5xl mx-auto px-6
    text-center` dentro. */
body.apertura-route .ap-footer {
  position: relative;
  z-index: 10;
  /* En móvil el pie ya entra en el pliegue, así que es lo último de la
     pantalla y el indicador de inicio de iOS le pasa por encima: la reserva
     de seguridad se suma al relleno inferior. En escritorio `env()` vale 0 y
     no cambia nada. */
  padding: 2rem 0 calc(2rem + env(safe-area-inset-bottom, 0px));
  border-top: 1px solid rgba(255, 255, 255, 0.05);
  background: #000;
}

body.apertura-route .ap-footer-inner {
  display: grid;
  max-width: 64rem;
  justify-items: center;
  margin-inline: auto;
  padding-inline: 1.5rem;
  gap: 0.75rem;
  text-align: center;
}

body.apertura-route .ap-footer-legal {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.5rem;
  justify-content: center;
}

/* `text-gray-600 text-sm` */
body.apertura-route .ap-footer p {
  margin: 0;
  color: #4b5563;
  font-size: 0.875rem;
}

body.apertura-route .ap-footer a {
  color: rgba(255, 255, 255, 0.4);
  font-size: 0.875rem;
  text-decoration: none;
}

body.apertura-route .ap-footer a:hover,
body.apertura-route .ap-footer a:focus-visible {
  color: #fff;
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ── Reveals ──────────────────────────────────────────────────────────────
   La referencia usa `.reveal` + IntersectionObserver + `--r-y` con una
   transición de .6s y curva (.22,.61,.36,1). Fashion Lab ya tiene ese
   mecanismo montado —`revealEffect()` marca `[data-reveal]` con
   `.is-inview`—, así que se REUTILIZA el JS y aquí solo se ajusta el tiempo
   y la curva a los de la referencia. Ningún observador nuevo.

   `revealEffect()` ni siquiera arranca con `prefers-reduced-motion`, así que
   el elemento queda visible: mismo resultado que la media de la referencia. */
html[data-reveal-ready] body.apertura-route [data-reveal]:not([data-reveal='fill']) {
  transition:
    opacity 0.6s cubic-bezier(0.22, 0.61, 0.36, 1),
    translate 0.6s cubic-bezier(0.22, 0.61, 0.36, 1);
  translate: 0 20px;
}


@media (prefers-reduced-motion: reduce) {
  body.apertura-route .ap-cta::after {
    animation: none;
    opacity: 0.15;
    scale: 1;
  }

  /* La placa se queda quieta y ENTERA: opacidad plena, escala 1 y el halo de
     reposo de su regla base. Se declara aquí aunque
     `landing-production-source.css` ya recorta la duración de toda animación
     con `!important`: aquello acorta el tiempo, esto retira la animación. Que
     el resultado dependiera del orden de dos hojas sería una casualidad, no
     una decisión. */
  body.apertura-route .ap-capacidad {
    animation: none;
    opacity: 1;
    scale: 1;
  }
}

/* ── sm · 640px ───────────────────────────────────────────────────────── */
@media (min-width: 640px) {
  /* `sm:text-5xl` */
  body.apertura-route .ap-hero h1 {
    font-size: 3rem;
    line-height: 1;
  }
}

/* ── md · 768px ───────────────────────────────────────────────────────── */
@media (min-width: 768px) {
  /* `md:px-6 md:py-24`. A partir de tableta el héroe vuelve a pedir pantalla
     completa MENOS la barra superior —que es justo lo que antes no se
     restaba—, así que el pie vuelve a quedar bajo el pliegue y el plano
     cinematográfico se conserva. */
  body.apertura-route .ap-hero {
    min-height: calc(100vh - var(--ap-topbar-alto));
    min-height: calc(100svh - var(--ap-topbar-alto));
    padding: 6rem 1.5rem;
  }

  /* `md:mb-8` */
  body.apertura-route .ap-brand {
    margin-bottom: 2rem;
  }

  body.apertura-route .ap-logo {
    width: 208px;
  }

  /* `md:text-6xl md:mb-6` */
  body.apertura-route .ap-hero h1 {
    margin-bottom: 1.5rem;
    font-size: 3.75rem;
    line-height: 1;
  }

  /* `md:text-xl md:mb-12`, recortado por el mismo motivo que en móvil: la
     placa de plazas se lleva parte de ese aire. */
  body.apertura-route .ap-lead {
    margin-bottom: 1.5rem;
    font-size: 1.25rem;
    line-height: 1.75rem;
  }

  /* Mismo agarre que en móvil, un punto más ancho: 24 px arriba, 36 px
     abajo, y algo más de aire dentro de la placa. */
  body.apertura-route .ap-capacidad {
    margin: 0 auto 2.25rem;
    padding: 0.5rem 1.25rem;
    letter-spacing: 0.18em;
  }

  /* `md:w-auto` — el CTA deja de ocupar el ancho completo. */
  body.apertura-route .ap-cta-wrap {
    width: auto;
  }

  body.apertura-route .ap-cta {
    width: auto;
    /* `md:text-xl` */
    font-size: 1.25rem;
  }



}

/* ── lg · 1024px ──────────────────────────────────────────────────────── */
@media (min-width: 1024px) {
  /* Del portátil en adelante el reparto casi vuelve al centro: 5:6 corrige el
     centro óptico y nada más. Aquí la pantalla es ANCHA y baja, la pila ocupa
     buena parte del alto y el desequilibrio se nota mucho antes de llegar a
     un tercio; el tercio superior es la corrección de las pantallas altas y
     estrechas —móvil y tableta en vertical—, no la de esta. */
  body.apertura-route .ap-hero::before {
    flex: 5 1 0;
  }

  body.apertura-route .ap-hero::after {
    flex: 6 1 0;
  }

  /* `lg:text-7xl` */
  body.apertura-route .ap-hero h1 {
    font-size: 4.5rem;
    line-height: 1;
  }
}
/* ── Pantallas anchas pero BAJAS ──────────────────────────────────────────
   Móvil en horizontal y portátiles de ventana corta. A partir de `md` el
   héroe pide `6rem` de relleno arriba y abajo: 192 px que solo caben si la
   pantalla pasa de ~670 px de alto (192 de relleno + ~438 de pila + la barra
   superior). Por debajo de eso, ese relleno es justo lo que echa el CTA
   fuera del pliegue, así que el héroe vuelve al aire mínimo del móvil. El
   umbral no es un gusto: es la suma de arriba, redondeada. */
@media (min-width: 768px) and (max-height: 700px) {
  body.apertura-route .ap-hero {
    padding-block: 1.5rem;
  }
}
