/* ===== Encabezado fijo ===== */
header {
  position: fixed;
  top: 0;
  z-index: 1000;
  width: 100%;
  border-bottom: 1px solid transparent;
  background: transparent;
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  transition: background 500ms ease, border-color 500ms ease;
}

header.desplazado {
  border-bottom-color: rgb(255 255 255 / 12%);
  background: rgb(0 0 0 / 88%);

  /* Un backdrop-filter en una barra fija obliga a recomponer todo lo que queda
     detrás en cada cuadro del scroll, y es de lo más caro en móvil. Ya
     desplazado el fondo es negro al 88%, así que el desenfoque no llega a
     notarse: se quita y se recupera la fluidez. Arriba del todo, sobre el
     video, sí se conserva. */
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

html {
  /* --alto-barra lo mide js/navegacion.js; 78px es la reserva sin JS. */
  scroll-padding-top: var(--alto-barra, 78px);
  /* Los atajos del menú llevan directo a su sección. Con el desplazamiento
     suave de base.css la página recorría todos los módulos intermedios. */
  scroll-behavior: auto;
}

.barra {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 32px;
  padding: 18px 0;
}

.marca img {
  width: auto;
  height: 38px;
  transition: transform 300ms ease;
}

.marca:hover img {
  transform: scale(1.03);
}

nav {
  display: flex;
  gap: 36px;
}

nav a {
  color: var(--texto-suave);
  font-size: 0.8rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  transition: color 300ms ease, transform 300ms ease;
}

nav a:hover,
nav a.activo {
  transform: translateY(-1px);
  color: #fff;
}

/* La copia del rótulo sólo sirve al giro del menú de escritorio. */
.rotulo > span + span {
  display: none;
}

.boton-barra {
  position: relative;
  padding: 13px 24px;
  border: 0;
  box-shadow: 0 4px 14px rgb(225 29 42 / 30%);
  white-space: nowrap;
  isolation: isolate;

  /* js/boton-especular.js le pinta la luz que recorre el borde, como a
     "Explorar solución" (.luz-especular, en contenido.css). Sobre el rojo, la
     línea fina de base va en un rojo claro en lugar de gris. */
  --base-especular: 255, 128, 136;
}

/* Botón hamburguesa (solo móvil) */
.boton-menu {
  display: none;
  width: 44px;
  height: 40px;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  padding: 0 10px;
  border: 1px solid rgb(255 255 255 / 18%);
  border-radius: 3px;
  background: rgb(255 255 255 / 5%);
  cursor: pointer;
}

.boton-menu span {
  display: block;
  height: 2px;
  border-radius: 2px;
  background: #fff;
  transition: transform 260ms ease, opacity 200ms ease;
}

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

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

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

/* ===== Portada ===== */
.portada {
  position: relative;
  display: flex;
  min-height: 100svh;
  align-items: center;
  overflow: hidden;
  padding: 76px 0 24px;
  background: #000;
}

/* Viñeta oscura: da contraste al texto sin tapar el video.
   Son dos capas en un mismo pseudo-elemento (una sola capa de composición, no
   cuesta más que la de antes). La lineal oscurece la columna izquierda, que es
   donde va el texto y donde el video tiene los monitores encendidos; se apaga
   antes del 75% para no ensuciar la parte derecha del encuadre. La radial que
   ya estaba baja de intensidad porque ahora no trabaja sola.

   El 66% de arranque salió de medir sobre cuadros del propio video: deja el
   fondo bajo el texto en 49/255 de percentil 95, o sea 11.8:1 de contraste
   contra el texto blanco, cuando el mínimo exigible es 4.5:1. Antes estaba en
   88%, que daba 14.5:1 (margen que no hacía falta) a cambio de aplastar el muro
   de monitores casi a negro justo donde es más interesante. */
.portada::after {
  position: absolute;
  inset: 0;
  z-index: 2;
  background:
    linear-gradient(100deg, rgb(0 0 0 / 66%) 0%, rgb(0 0 0 / 42%) 38%, rgb(0 0 0 / 10%) 62%, transparent 78%),
    radial-gradient(90% 90% at 30% 50%, rgb(0 0 0 / 40%) 0%, rgb(0 0 0 / 24%) 55%, rgb(0 0 0 / 10%) 100%);
  content: "";
  pointer-events: none;
}

.portada video {
  position: absolute;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
  filter: brightness(0.95) contrast(1.05);
  object-fit: cover;
  /* El logotipo del video llega hasta el borde derecho del cuadro. Centrado,
     el recorte de `cover` le cortaba la última letra. Anclado a la derecha,
     todo lo que sobra se recorta por la izquierda, que es fondo oscuro. */
  object-position: right center;
  pointer-events: none;
}

.niebla {
  position: absolute;
  z-index: 1;
  inset: -15%;
  overflow: hidden;
  opacity: 0.35;
  pointer-events: none;
}

/* Las nubes ya son degradados radiales suaves: 18px de desenfoque bastan para
   fundir el borde. Eran 55px, y el coste del blur crece con el cuadrado del
   radio en cada cuadro de la animación. */
.nube {
  position: absolute;
  border-radius: 50%;
  filter: blur(18px);
  will-change: transform, opacity;
}

.nube-1 {
  top: -10%;
  left: -5%;
  width: 950px;
  height: 950px;
  background: radial-gradient(circle, rgb(255 255 255 / 22%) 0%, rgb(225 29 42 / 28%) 35%, rgb(10 10 15 / 75%) 65%, transparent 80%);
}

.nube-2 {
  bottom: -10%;
  left: 15%;
  width: 1050px;
  height: 1050px;
  background: radial-gradient(circle, rgb(0 0 0 / 95%) 0%, rgb(15 15 22 / 85%) 50%, transparent 80%);
}

.nube-3 {
  top: 10%;
  left: 30%;
  width: 850px;
  height: 850px;
  background: radial-gradient(circle, rgb(59 130 246 / 22%) 0%, rgb(10 10 15 / 65%) 55%, transparent 75%);
}

.contenido-portada {
  position: relative;
  z-index: 3;
  /* Desplazamiento del bloque respecto al centro de la portada. Era de 50px,
     pero con los botones el contenido creció y se salía del primer pantallazo
     en portátiles; centrado cabe completo. Es el único número a mover si se
     quiere más arriba o más abajo. */
  top: 0;
}

.contenido-portada h1 {
  /* 780px deja el titular en tres renglones en escritorio. `balance` reparte
     las palabras entre ellos para que no quede uno con dos palabras sueltas;
     donde no esté soportado simplemente se ignora y parte por ancho. */
  max-width: 780px;
  margin: 0;
  font-size: clamp(2.1rem, 3.8vw, 3.5rem);
  font-weight: 700;
  line-height: 1.06;
  text-wrap: balance;
}

/* El mismo rojo en degradado lo usa .respuesta-continuidad (contenido.css). */
.contenido-portada h1 span:not(.palabra),
.respuesta-continuidad span {
  background: linear-gradient(135deg, var(--rojo), #ff4d5a);
  -webkit-background-clip: text;
  background-clip: text;
  color: var(--rojo);
  -webkit-text-fill-color: transparent;
}

.entrada-portada {
  max-width: 580px;
  margin: 16px 0 0;
  color: #c2c7d0;
  font-size: 1rem;
  line-height: 1.68;
}

/* La acción principal de toda la página. Antes el único botón vivía en el
   encabezado y la portada no ofrecía ningún camino. */
.acciones-portada {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  margin-top: 30px;
}

/* Métricas de portada (propuesta 4).
   Rejilla de cuatro columnas en vez de flex: con `flex-wrap` la cuarta métrica
   se caía sola a un segundo renglón y arrastraba un separador huérfano. */
.metricas-portada {
  display: grid;
  max-width: 760px;
  /* Anclado arriba, no centrado: en pantallas angostas hay etiquetas que se
     parten en dos renglones y, centradas, las cifras de una misma fila
     quedaban a distinta altura. */
  align-items: start;
  justify-content: start;
  grid-template-columns: repeat(4, auto);
  margin-top: 30px;
  padding-top: 20px;
  border-top: 1px solid rgb(255 255 255 / 14%);
}

.metrica {
  padding: 0 22px;
  border-left: 1px solid rgb(255 255 255 / 15%);
}

.metrica:first-child {
  padding-left: 0;
  border-left: 0;
}

.cifra {
  display: block;
  font-family: var(--titulos);
  font-size: 1.65rem;
  font-weight: 700;
  /* Ancho fijo por dígito: evita que la cifra se mueva mientras cuenta */
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

.cifra.rojo {
  color: var(--rojo);
  text-shadow: 0 0 12px rgb(225 29 42 / 40%);
}

.cifra.azul {
  color: var(--azul);
  text-shadow: 0 0 12px rgb(59 130 246 / 40%);
}

.detalle {
  display: block;
  margin-top: 2px;
  color: var(--texto-suave);
  font-family: var(--mono);
  font-size: 0.62rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

/* ===== Encabezado de escritorio =====
   El texto y los botones de la portada usan la composición base: titular,
   entrada, botones lado a lado y las cuatro cifras en fila, a la izquierda.
   Aquí sólo cambia el encabezado, que flota sobre el video. */
@media (min-width: 901px) {
  /* Sobre el video la barra no lleva fondo: sólo flotan la marca, las
     cápsulas del menú y el botón. */
  header:not(.desplazado) {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }

  /* Menú de cápsulas sueltas, sin cápsula que las envuelva. Al pasar el
     cursor sube un círculo rojo desde abajo y el rótulo gira hacia arriba;
     la sección en la que estás lleva un punto. */
  nav {
    gap: 6px;
  }

  nav a {
    --giro: 360ms cubic-bezier(.22, 1, .36, 1);
    position: relative;
    padding: 10px 18px;
    overflow: hidden;
    border: 1px solid rgb(255 255 255 / 12%);
    border-radius: 999px;
    background: rgb(12 12 16 / 62%);
    box-shadow: inset 0 1px 0 rgb(255 255 255 / 6%), 0 8px 20px rgb(0 0 0 / 30%);
    line-height: 1.2;
    transition: color var(--giro), background 300ms ease, border-color 300ms ease, transform 160ms ease;
    isolation: isolate;
  }

  /* El círculo nace en el borde inferior y, a escala completa, cubre la
     cápsula más ancha (Ubicación) con margen. */
  nav a::before {
    position: absolute;
    bottom: 0;
    left: 50%;
    z-index: -1;
    width: calc(100% + 48px);
    aspect-ratio: 1;
    border-radius: 50%;
    background: var(--rojo);
    content: "";
    transform: translate(-50%, 50%) scale(0);
    transition: transform var(--giro);
  }

  nav a::after {
    position: absolute;
    bottom: 4px;
    left: 50%;
    width: 4px;
    height: 4px;
    border-radius: 50%;
    background: var(--rojo);
    content: "";
    transform: translateX(-50%) scale(0);
    transition: transform 300ms cubic-bezier(.22, 1, .36, 1), background 200ms ease;
  }

  /* El rótulo y su copia van uno sobre otro; la copia espera debajo, fuera
     de la cápsula, hasta que el giro la sube. */
  .rotulo {
    position: relative;
    display: block;
    transition: transform var(--giro);
  }

  .rotulo > span + span {
    position: absolute;
    top: calc(100% + 12px);
    left: 0;
    display: block;
  }

  nav a:hover,
  nav a.activo {
    transform: none;
  }

  nav a.activo {
    border-color: rgb(255 255 255 / 14%);
    background: rgb(255 255 255 / 12%);
    color: #fff;
  }

  nav a.activo::after {
    transform: translateX(-50%) scale(1);
  }

  nav a:hover,
  nav a:focus-visible {
    border-color: transparent;
    color: #fff;
  }

  nav a:hover::before,
  nav a:focus-visible::before {
    transform: translate(-50%, 50%) scale(1);
  }

  nav a:hover .rotulo,
  nav a:focus-visible .rotulo {
    transform: translateY(calc(-100% - 12px));
  }

  /* Sobre el rojo, el punto pasa a blanco para no perderse. */
  nav a:hover::after,
  nav a:focus-visible::after {
    background: #fff;
  }

  nav a:active {
    transform: scale(.97);
  }

  nav a:focus-visible {
    outline: 2px solid #fff;
    outline-offset: 2px;
  }

  @media (prefers-reduced-motion: reduce) {
    nav a::before {
      transform: translate(-50%, 50%) scale(1);
      opacity: 0;
      transition: opacity 200ms ease;
    }

    nav a:hover::before,
    nav a:focus-visible::before {
      opacity: 1;
    }

    nav a:hover .rotulo,
    nav a:focus-visible .rotulo {
      transform: none;
    }
  }

  .boton-barra {
    border-radius: 999px;
  }
}

/* ===== Entrada de la información de la portada =====
   Sin el script, en móvil o con movimiento reducido no existe: la portada es
   la de siempre y todo su contenido aparece de una vez.

   Con .con-escenas el video arranca solo al cargar la página, sin texto, y
   el primer giro de la rueda hace entrar la información. js/escenas-portada.js
   le da a cada pieza una variable --p, de 0 (aún no entra) a 1 (ya está). Las
   piezas se acumulan: al terminar la entrada la portada queda completa.

   Se usa `translate` y no `transform` para no pisar el transform que los
   botones ya usan al pasar el cursor y al pulsarlos. */
.palabra {
  display: inline-block;
}

/* Misma condición que js/escenas-portada.js: escritorio o teléfono vertical. */
@media (min-width: 901px) and (prefers-reduced-motion: no-preference),
  (max-width: 900px) and (orientation: portrait) and (prefers-reduced-motion: no-preference) {
  /* revelar.js hace entrar estos bloques con un fundido al cargar. Aquí manda
     la entrada por scroll, así que el fundido se anula. */
  .con-escenas .contenido-portada > .revelar {
    opacity: var(--p, 1);
    transform: none;
    animation: none;
    translate: 0 calc((1 - var(--p, 1)) * 26px);
  }

  .con-escenas :is(.palabra, .contenido-portada h1 span:not(.palabra), .metrica, .acciones-portada .boton) {
    opacity: var(--p, 1);
    translate: 0 calc((1 - var(--p, 1)) * 24px);
  }

  /* Una pieza que todavía no entra no debe recibir clics ni foco. */
  .con-escenas .pendiente {
    visibility: hidden;
  }

  /* Mientras llega escenas-portada.js (la clase la pone un script en el <head>
     de index.html y la quita el propio escenas-portada.js). */
  .escenas-pendientes .contenido-portada {
    visibility: hidden;
  }
}

/* En el teléfono la entrada abre a pantalla completa con el video limpio: el
   velo sólo aparece cuando entra la información, que es a quien sirve. */
@media (max-width: 900px) and (orientation: portrait) and (prefers-reduced-motion: no-preference) {
  .portada.con-escenas {
    min-height: 100svh;
  }

  .con-escenas::after {
    opacity: 0;
    transition: opacity 600ms var(--ease-out, ease-out);
  }

  .con-escenas.informacion-visible::after {
    opacity: 1;
  }
}

/* ===== Franja de clientes ===== */
.clientes {
  overflow: hidden;
  /* 40 + los 6 de relleno del visor = los 46 de siempre. */
  padding: 40px 0;
  border-top: 1px solid rgb(255 255 255 / 8%);
  border-bottom: 1px solid rgb(255 255 255 / 8%);
  background: #000;
}

.cuadricula-clientes {
  display: grid;
  align-items: center;
  gap: 48px;
  grid-template-columns: minmax(0, 220px) 1fr;
}

.titulo-clientes {
  margin: 0;
  color: #5c626e;
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.2em;
  line-height: 1.7;
  text-transform: uppercase;
}

.titulo-clientes span {
  color: var(--rojo);
}

/* El difuminado de los bordes se hacía con mask-image. Una máscara obliga al
   navegador a rehacer un pase de composición fuera de pantalla en cada cuadro
   mientras la pista se desplaza por debajo, y eso trababa el scroll en móvil
   justo al pasar por esta franja. Como el fondo de .clientes es negro sólido,
   dos degradados hacia ese mismo negro dan el mismo resultado a la vista y solo
   cuestan dos capas superpuestas. */
/* El visor mide justo lo que mide un logotipo, así que al agrandarse con el
   :hover se salía por arriba y por abajo y `overflow: hidden` le rebanaba el
   borde: en los logotipos redondos el corte se veía como un círculo aplanado.
   Este relleno le deja el margen que necesita el zoom (52px * 1.06 = 55.1,
   o sea 1.6px por lado) y se descuenta del relleno de .clientes para que la
   franja siga midiendo lo mismo. `overflow` no se puede abrir solo en vertical:
   en cuanto un eje es visible el otro pasa a auto y aparecería una barra. */
.visor-logos {
  position: relative;
  padding: 6px 0;
  overflow: hidden;
}

.visor-logos::before,
.visor-logos::after {
  position: absolute;
  z-index: 1;
  top: 0;
  width: 8%;
  height: 100%;
  content: "";
  pointer-events: none;
}

.visor-logos::before {
  left: 0;
  background: linear-gradient(90deg, #000, transparent);
}

.visor-logos::after {
  right: 0;
  background: linear-gradient(270deg, #000, transparent);
}

.pista-logos {
  --separacion-logos: 80px;
  --altura-logo: 52px;
  display: flex;
  width: max-content;
  /* Con la igualación óptica de más abajo ya casi ningún logotipo mide los
     --altura-logo completos, así que sin este mínimo la pista se encogería hasta
     su pieza más alta y las dos franjas dejarían de medir lo mismo: la de
     partners, que no tiene ningún escudo a tamaño completo, quedaba 7px más baja
     que la de clientes. Fijado el alto, los logotipos se centran dentro. */
  min-height: var(--altura-logo);
  align-items: center;
  gap: var(--separacion-logos);
  /* Capa propia: el navegador rasteriza la tira una sola vez (con los filtros
     de los logotipos ya aplicados) y después solo la desliza. La duración va
     con el largo de la pista: son 15 logotipos por vuelta, a 2s cada uno. A 6s
     se veía demasiado lenta. */
  animation: desplazar-logos 30s linear infinite;
  will-change: transform;
}

/* La franja de partners lleva doce logotipos en vez de quince: con los mismos
   2s por logotipo, la vuelta dura 24s y la tira se desplaza a la misma
   velocidad que la de clientes. */
.pista-partners {
  animation-duration: 24s;
}

.pista-logos.detenida {
  animation-play-state: paused;
}

.pista-logos img {
  width: auto;
  height: calc(var(--altura-logo) * var(--escala-optica, 1));
  filter: grayscale(1) brightness(2.2);
  object-fit: contain;
  opacity: 0.55;
  transition: opacity 400ms ease, filter 400ms ease, transform 400ms ease;
}

/* ===== Igualación óptica de los logotipos =====
   Los 27 archivos están recortados al contenido y miden todos 104px de alto, así
   que darles la misma altura CSS los deja del mismo tamaño de caja pero no del
   mismo tamaño aparente: un escudo redondo ocupa esos 52px con toda su forma,
   mientras que un logotipo de una sola línea de texto los ocupa con la altura de
   las letras. Medida la superficie de tinta de cada archivo (píxeles opacos,
   escalados al tamaño de dibujo), los partners salían a 60 de media y los
   clientes a 38: por eso la segunda franja se veía bastante más grande que la
   primera aunque las dos usaran la misma regla. Después de la corrección las dos
   medianas quedan en 38.

   --escala-optica corrige eso: es 52 * 38 / (tinta del logotipo), o sea el factor
   que iguala la superficie de tinta de cada pieza a la del cliente promedio.
   Queda acotado entre 0.58 y 1 para que ningún logotipo se salga de la franja ni
   se quede tan bajo que se pierda: los que ya estaban por debajo de la media
   (escudos pequeños como Irapuato o Fragaria) se quedan en 1 y los muy anchos
   (Avigilon, Genetec, Pelco, Cambium) tocan el suelo de 0.58. El valor es un
   factor y no una altura fija para que el corte de móvil, que solo cambia
   --altura-logo, siga funcionando sin repetir estos números. */
.logo-guanajuato,
.logo-procter-gamble {
  --escala-optica: 0.82;
}

.logo-c5i {
  --escala-optica: 0.86;
}

.logo-holiday-inn {
  --escala-optica: 0.71;
}

.logo-aloft {
  --escala-optica: 0.97;
}

.logo-gigante-verde {
  --escala-optica: 0.77;
}

.logo-pagobus {
  --escala-optica: 0.72;
}

.logo-axis {
  --escala-optica: 0.70;
}

.logo-avigilon,
.logo-genetec,
.logo-pelco,
.logo-cambium {
  --escala-optica: 0.58;
}

.logo-hanwha {
  --escala-optica: 0.85;
}

.logo-unv {
  --escala-optica: 0.87;
}

.logo-flir {
  --escala-optica: 0.69;
}

.logo-notifier {
  --escala-optica: 0.79;
}

.logo-ciscou {
  --escala-optica: 0.61;
}

.logo-astra {
  --escala-optica: 0.82;
}

.logo-lightera {
  --escala-optica: 0.80;
}

/* Al pasar por encima, el logotipo recupera su color y se agranda un poco.
   Se llegó a restringir a dispositivos con ratón por sospecha de que el :hover
   accidental del dedo trababa el scroll aquí. Medida la grabación cuadro a
   cuadro, el culpable resultó ser otro (arrancar y detener el video de la
   portada), así que el efecto vuelve a estar activo en todos los dispositivos. */
.pista-logos img:hover,
.pista-logos img:focus-visible {
  transform: scale(1.06);
  filter: none;
  opacity: 1;
}


/* El recorrido avanza medio ancho de la pista más medio hueco: así el primer
   logotipo de la copia queda exactamente donde arrancó el original y el ciclo
   se reinicia sin salto visible. */
@keyframes desplazar-logos {
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(calc(-50% - var(--separacion-logos) / 2));
  }
}

@media (max-width: 1100px) {
  nav a {
    padding: 9px 13px;
    font-size: 0.72rem;
  }
}

@media (max-width: 900px) {
  /* El backdrop-filter del header se quita en cuanto se hace scroll (arriba,
     header.desplazado), pero justo al inicio, sobre el video, sigue activo a
     propósito para el efecto de vidrio. En móvil eso cae exactamente en la
     franja donde ya se recortaron otros filtros por el mismo motivo, así que
     se apaga también aquí y el header arranca con fondo sólido. */
  header {
    background: rgb(0 0 0 / 55%);
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }

  /* Mismo razonamiento que el zoom y las nubes: recalcular brightness/contrast
     sobre cada fotograma decodificado del video es un costo continuo que no
     depende del scroll, y en una pantalla de teléfono el ajuste de color casi
     no se nota. Se quita para dejarle más margen a la GPU en esa franja. */
  /* En vertical sólo cabe una franja del video: se centra sobre el emblema y
     el centro del logotipo, que caen hacia el 72% del ancho del cuadro. */
  .portada video {
    filter: none;
    object-position: 72% center;
  }

  .portada {
    min-height: auto;
    padding: 95px 0 40px;
  }

  /* En pantallas pequeñas la portada ya no sobra espacio: sin desplazamiento */
  .contenido-portada {
    top: 0;
  }

  .contenido-portada h1 {
    font-size: clamp(1.8rem, 6.8vw, 3.1rem);
  }

  /* Va por clase y no por `.contenido-portada > p`, para no arrastrar a
     cualquier otro párrafo que se agregue después al bloque de portada. */
  .entrada-portada {
    font-size: 0.95rem;
  }

  /* Aquí el texto ocupa todo el ancho, así que el degradado deja de venir del
     lado izquierdo y pasa a ser de arriba abajo. */
  .portada::after {
    background:
      linear-gradient(180deg, rgb(0 0 0 / 78%) 0%, rgb(0 0 0 / 55%) 45%, rgb(0 0 0 / 72%) 100%),
      radial-gradient(90% 90% at 50% 50%, rgb(0 0 0 / 30%) 0%, rgb(0 0 0 / 15%) 100%);
  }

  .boton-menu {
    display: flex;
    order: 3;
  }

  .boton-barra {
    display: none;
  }

  /* Sólo la colocación del desplegable; su aspecto, la apertura y los enlaces
     los define navegacion-movil.css. */
  nav {
    position: absolute;
    top: 100%;
    right: 0;
    left: 0;
    display: grid;
    border-bottom: 1px solid rgb(255 255 255 / 10%);
  }

  .cuadricula-clientes {
    gap: 26px;
    grid-template-columns: 1fr;
    text-align: center;
  }
}

/* Teléfono vertical: aquí corre la versión 9:16 del video (ver index.html),
   que ya trae el logotipo completo al centro. El velo se aclara en la parte
   media para que se vea; arriba y abajo, bajo el titular y las cifras, sigue
   oscuro. */
@media (max-width: 900px) and (orientation: portrait) {
  .portada video {
    object-position: center;
  }

  .portada::after {
    background: linear-gradient(180deg, rgb(0 0 0 / 66%) 0%, rgb(0 0 0 / 38%) 48%, rgb(0 0 0 / 66%) 100%);
  }
}

/* Las cuatro columnas dejan de caber antes que el resto del bloque, así que
   pasan a 2x2 en su propio corte. */
@media (max-width: 780px) {
  .metricas-portada {
    max-width: 420px;
    grid-template-columns: repeat(2, 1fr);
    row-gap: 22px;
  }

  .metrica:nth-child(odd) {
    padding-left: 0;
    border-left: 0;
  }
}

@media (max-width: 600px) {
  .acciones-portada .boton {
    flex: 1 1 100%;
  }

  .cifra {
    font-size: 1.4rem;
  }

  .pista-logos {
    --separacion-logos: 52px;
    --altura-logo: 42px;
  }
}

/* ===== Portada en ventana ancha pero vertical =====
   Es el caso del "modo computadora" de un navegador móvil: declara unos 980px
   de ancho pero la pantalla sigue siendo vertical, así que 100svh estiraba la
   portada por encima de 2000px y el texto quedaba flotando en medio de un mar
   de video vacío. La altura pasa a depender del ancho, que es lo que da una
   proporción razonable, sin superar nunca la pantalla.

   Un monitor de escritorio es apaisado y jamás cumple max-aspect-ratio: 1/1,
   de modo que ahí no cambia absolutamente nada. */
@media (min-width: 901px) and (max-aspect-ratio: 1 / 1) {
  .portada {
    min-height: min(100svh, 68vw);
  }

  /* Con la portada ya compacta, el desplazamiento hacia abajo del bloque de
     texto deja de hacer falta y lo descentraría. */
  .contenido-portada {
    top: 0;
  }
}
