/* Landing de una solución (un pilar del ecosistema) con todas sus capacidades
   en una sola página: portada del pilar con índice y, debajo, una sección por
   capacidad. Comparte tipografías y contenedor con base.css; aquí sólo va lo
   propio de estas páginas. Por pilar cambian el atributo data-solucion del
   body, las imágenes y el texto. */
.pagina-capacidad {
  /* Los mismos tres acentos que usa el carrusel del ecosistema en la portada. */
  --acento: var(--azul);
  /* Azul muy oscuro: el negro puro del inicio dejaba las fotos flotando. */
  --fondo-profundo: #050a16;
  /* Las curvas de movimiento (--ease-out, --ease-in-out) vienen de base.css. */

  display: flex;
  min-height: 100vh;
  min-height: 100dvh;
  flex-direction: column;
  background: var(--fondo-profundo);
}

.pagina-capacidad[data-solucion="conectar"],
.pagina-capacidad[data-solucion="mover"] {
  --acento: var(--cian);
}

.pagina-capacidad[data-solucion="pensar"],
.pagina-capacidad[data-solucion="continuar"] {
  --acento: var(--rojo);
}

/* ===== Barra superior ===== */
.barra-capacidad {
  position: sticky;
  z-index: 20;
  top: 0;
  border-bottom: 1px solid rgb(255 255 255 / 10%);
  background: rgb(3 6 14 / 88%);
  /* Debajo hay animación (red de nodos, fotos con profundidad): el
     desenfoque se recalcula en cada cuadro, así que se mantiene corto. */
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

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

.marca-capacidad img {
  width: auto;
  height: 38px;
}

/* "Volver a soluciones" es un botón de cristal, como "Explorar solución" en
   el inicio: js/boton-especular.js pinta en .luz-especular la luz que
   recorre el borde y sigue al cursor. Sin el script queda un borde fino. */
.barra-capacidad .volver {
  position: relative;
  display: inline-flex;
  align-items: center;
  padding: 13px 22px;
  border-radius: 999px;
  gap: 10px;
  background: rgb(255 255 255 / 4%);
  box-shadow: 0 10px 24px -14px rgb(0 0 0 / 45%);
  color: #f5f5f5;
  font-family: inherit;
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  white-space: nowrap;
  isolation: isolate;
  transition: transform 250ms cubic-bezier(0.2, 0.8, 0.2, 1);
}

.barra-capacidad .volver:not(.con-especular) {
  box-shadow:
    inset 0 0 0 1px rgb(255 255 255 / 22%),
    0 10px 24px -14px rgb(0 0 0 / 45%);
}

.barra-capacidad .volver:active {
  transform: scale(0.97);
}

.luz-especular {
  position: absolute;
  z-index: -1;
  display: block;
  width: calc(100% + 48px);
  height: calc(100% + 48px);
  inset: -24px;
  filter: drop-shadow(0 0 3px rgb(255 255 255 / 55%));
  pointer-events: none;
}

/* Las capacidades clave del pilar, siempre a mano bajo el logotipo, en la
   misma cápsula que el menú del inicio. Cada una lleva a su módulo;
   js/capacidad.js marca con aria-current la que se está leyendo y
   js/gotas-nav.js pinta detrás la píldora roja líquida. Si no caben, la
   lista se desliza de lado dentro de la cápsula. */
.menu-capacidades {
  padding-bottom: 12px;
}

.menu-capacidades > .contenedor {
  display: flex;
  justify-content: center;
}

/* Menú de capacidades con el estilo del menú del inicio: una cápsula suelta
   por capacidad, sin cápsula que las envuelva, un círculo rojo que sube y
   gira el rótulo al pasar el cursor, y un punto rojo bajo la capacidad que
   estás leyendo. */
.capsula-capacidades {
  position: relative;
  max-width: 100%;
}

.menu-capacidades ul {
  position: relative;
  display: flex;
  margin: 0;
  padding: 0;
  gap: 6px;
  list-style: none;
  overflow-x: auto;
  scrollbar-width: none;
}

.menu-capacidades ul::-webkit-scrollbar {
  display: none;
}

.menu-capacidades li {
  flex: none;
}

.menu-capacidades a {
  --giro: 360ms cubic-bezier(.22, 1, .36, 1);
  position: relative;
  display: flex;
  align-items: center;
  padding: 10px 17px;
  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%);
  color: var(--texto-suave);
  font-size: 0.74rem;
  font-weight: 500;
  line-height: 1.25;
  white-space: nowrap;
  transition: color var(--giro), background 300ms ease, border-color 300ms ease, transform 160ms ease;
  isolation: isolate;
}

/* El número sobra en la cápsula: el orden ya se lee de izquierda a derecha. */
.numero-menu {
  display: none;
}

/* El círculo nace en el borde inferior y, a escala completa, cubre la
   cápsula con margen. */
.menu-capacidades 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);
}

.menu-capacidades 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. */
.menu-capacidades .rotulo {
  position: relative;
  display: block;
  transition: transform var(--giro);
}

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

.menu-capacidades a[aria-current] {
  border-color: rgb(255 255 255 / 14%);
  background: rgb(255 255 255 / 12%);
  color: #fff;
}

.menu-capacidades a[aria-current]::after {
  transform: translateX(-50%) scale(1);
}

.menu-capacidades a:focus-visible {
  outline: 2px solid #fff;
  outline-offset: -2px;
}

.menu-capacidades a:active {
  transform: scale(.97);
}

/* En pantallas táctiles el círculo sólo acompaña el toque; el giro del
   rótulo queda para el cursor y el teclado. */
.menu-capacidades a:active::before {
  transform: translate(-50%, 50%) scale(1);
}

.menu-capacidades a:active,
.menu-capacidades a:focus-visible {
  color: #fff;
}

.menu-capacidades a:focus-visible::before {
  transform: translate(-50%, 50%) scale(1);
}

.menu-capacidades a:focus-visible .rotulo {
  transform: translateY(calc(-100% - 12px));
}

.menu-capacidades a:is(:active, :focus-visible)::after {
  background: #fff;
}

@media (hover: hover) and (pointer: fine) {
  .menu-capacidades a:hover {
    border-color: transparent;
    color: #fff;
  }

  .menu-capacidades a:hover::before {
    transform: translate(-50%, 50%) scale(1);
  }

  .menu-capacidades a:hover .rotulo {
    transform: translateY(calc(-100% - 12px));
  }

  .menu-capacidades a:hover::after {
    background: #fff;
  }
}

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

  .menu-capacidades a:is(:hover, :active, :focus-visible)::before {
    opacity: 1;
  }

  .menu-capacidades a:is(:hover, :focus-visible) .rotulo {
    transform: none;
  }
}

/* ===== Portada ===== */
.portada-capacidad {
  position: relative;
  display: flex;
  min-height: 78vh;
  align-items: center;
  padding: 90px 0;
  isolation: isolate;
}

.fondo-portada {
  position: absolute;
  z-index: -1;
  overflow: hidden;
  inset: 0;
}

.fondo-portada img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* La cámara vive en la mitad derecha de la foto: al recortar se conserva. */
  object-position: 70% 50%;
}

/* El velo abre paso al texto por la izquierda sin tapar la cámara. */
.fondo-portada::after {
  content: "";
  position: absolute;
  background:
    linear-gradient(95deg, rgb(3 6 14 / 92%) 0%, rgb(3 6 14 / 74%) 30%, rgb(3 6 14 / 18%) 58%, transparent 78%),
    linear-gradient(to bottom, transparent 62%, var(--fondo-profundo) 100%);
  inset: 0;
}

.contenido-portada-capacidad {
  max-width: 760px;
}

/* Cinta del color de la solución, hermana de la que llevan las tarjetas. */
.contenido-portada-capacidad::before {
  content: "";
  display: block;
  width: 54px;
  height: 3px;
  margin-bottom: 22px;
  border-radius: 2px;
  background: var(--acento);
  box-shadow: 0 0 16px color-mix(in srgb, var(--acento) 65%, transparent);
}

.ruta-capacidad {
  margin: 0 0 12px;
  color: var(--acento);
  font-family: var(--mono);
  font-size: 0.78rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
}

/* Los títulos largos de las soluciones se parten sin desbordar. */
.portada-capacidad :is(h1, h2) {
  margin: 0 0 16px;
  font-size: clamp(1.65rem, 4.6vw, 3.6rem);
  line-height: 1.02;
  text-transform: uppercase;
  overflow-wrap: break-word;
}

.lema-capacidad {
  max-width: 32ch;
  margin: 0;
  color: #fff;
  font-family: var(--titulos);
  font-size: clamp(1.15rem, 2.6vw, 1.6rem);
  font-weight: 400;
  letter-spacing: -0.015em;
  line-height: 1.3;
}

/* ===== Botón de vídeo ===== */
.reproducir {
  display: flex;
  align-items: center;
  margin-top: 40px;
  padding: 0;
  border: 0;
  gap: 18px;
  background: none;
  color: #fff;
  cursor: pointer;
}

.icono-reproducir {
  display: grid;
  width: 58px;
  height: 58px;
  border: 1px solid color-mix(in srgb, var(--acento) 70%, transparent);
  border-radius: 50%;
  background: rgb(3 6 14 / 45%);
  color: var(--acento);
  place-items: center;
  transition: background 200ms ease, box-shadow 200ms ease, transform 160ms var(--ease-out);
}

.icono-reproducir svg {
  width: 22px;
  height: 22px;
  /* El triángulo pesa a la izquierda: se recentra a ojo dentro del círculo. */
  margin-left: 3px;
}

.texto-reproducir {
  position: relative;
  padding-bottom: 9px;
  font-size: 0.95rem;
  font-weight: 400;
}

/* Subrayado que se alarga al pasar el ratón, como en la maqueta. */
.texto-reproducir::after {
  content: "";
  position: absolute;
  right: 0;
  bottom: 0;
  left: 0;
  height: 1px;
  background: rgb(255 255 255 / 45%);
  transition: background 260ms ease;
}

.reproducir:focus-visible .icono-reproducir {
  background: color-mix(in srgb, var(--acento) 22%, transparent);
  box-shadow: 0 0 26px color-mix(in srgb, var(--acento) 45%, transparent);
  transform: scale(1.06);
}

@media (hover: hover) and (pointer: fine) {
  .reproducir:hover .icono-reproducir {
    background: color-mix(in srgb, var(--acento) 22%, transparent);
    box-shadow: 0 0 26px color-mix(in srgb, var(--acento) 45%, transparent);
    transform: scale(1.06);
  }
}

/* Al presionar, el círculo cede un poco: confirma el clic. */
.reproducir:active .icono-reproducir {
  transform: scale(0.97);
}

.reproducir:hover .texto-reproducir::after,
.reproducir:focus-visible .texto-reproducir::after {
  background: var(--acento);
}

/* ===== Capacidades ===== */
.seccion-capacidades {
  padding: 92px 0 104px;
}

.seccion-capacidades h3 {
  margin: 0 0 46px;
  font-size: clamp(1.9rem, 4.4vw, 2.7rem);
}

.seccion-capacidades h3::after {
  content: "";
  display: block;
  width: 62px;
  height: 3px;
  margin-top: 16px;
  border-radius: 2px;
  background: var(--acento);
  box-shadow: 0 0 16px color-mix(in srgb, var(--acento) 55%, transparent);
  transform-origin: left;
}

.seccion-capacidades h3.revelar::after {
  transform: scaleX(0);
}

.seccion-capacidades h3.revelar.visible::after {
  transform: scaleX(1);
  transition: transform 900ms var(--ease-in-out) 450ms;
}

/* ===== Red de nodos de fondo ===== */
/* Las secciones de capacidades llevan detrás una red de nodos en movimiento
   (js/capacidad.js la dibuja en el canvas .red-nodos) y un resplandor del
   acento; ambos se encienden cuando aparece el título de la sección. */
.con-red-nodos {
  position: relative;
  /* clip y no hidden: hidden la volvería contenedor de desplazamiento y el
     monitor fijo (position: sticky) dejaría de acompañar a la lista. */
  overflow: hidden;
  overflow: clip;
  isolation: isolate;
}

.con-red-nodos::before {
  content: "";
  position: absolute;
  z-index: -1;
  /* Lejos del borde superior, para que ninguno quede cortado en seco. */
  background:
    radial-gradient(ellipse 50% 50% at 10% 40%, color-mix(in srgb, var(--acento) 14%, transparent), transparent 70%),
    radial-gradient(ellipse 45% 50% at 92% 90%, color-mix(in srgb, var(--cian) 10%, transparent), transparent 70%);
  inset: 0;
  opacity: 0;
  pointer-events: none;
  transition: opacity 1600ms ease;
}

/* Se desvanece hacia los bordes para fundirse con las franjas vecinas. */
.red-nodos {
  position: absolute;
  z-index: -1;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  -webkit-mask-image: radial-gradient(ellipse 90% 85% at 50% 50%, #000 45%, transparent 100%);
  mask-image: radial-gradient(ellipse 90% 85% at 50% 50%, #000 45%, transparent 100%);
  opacity: 0;
  pointer-events: none;
  transition: opacity 1800ms ease 300ms;
}

.con-red-nodos:has(h3.visible)::before {
  opacity: 1;
}

/* Línea de luz que marca el paso de la portada del módulo a sus
   capacidades: se traza desde el centro al aparecer el título y un destello
   la recorre cada pocos segundos. */
.con-red-nodos::after {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  left: 0;
  height: 140px;
  /* De arriba abajo: el destello, la línea, su brillo pegado y el halo que
     baja sobre la sección. */
  background:
    linear-gradient(90deg, transparent, rgb(255 255 255 / 95%), transparent) -20% 0 / 14% 2px no-repeat,
    linear-gradient(90deg, transparent 0%, var(--acento) 22%, var(--cian) 50%, var(--acento) 78%, transparent 100%) 0 0 / 100% 2px no-repeat,
    linear-gradient(to bottom, color-mix(in srgb, var(--acento) 45%, transparent), transparent) 0 0 / 100% 26px no-repeat,
    radial-gradient(50% 100% at 50% 0%, color-mix(in srgb, var(--acento) 24%, transparent), transparent 100%);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
  pointer-events: none;
  transform-origin: 50% 0;
  transition: transform 1400ms var(--ease-in-out);
  animation: destello-linea 6s ease-in-out 1.6s infinite;
}

.con-red-nodos:has(h3.revelar:not(.visible))::after {
  transform: scaleX(0);
}

@keyframes destello-linea {
  0% {
    background-position: -20% 0, 0 0, 0 0, 0 0;
  }

  45%,
  100% {
    background-position: 120% 0, 0 0, 0 0, 0 0;
  }
}

.con-red-nodos:has(h3.visible) .red-nodos {
  opacity: 0.9;
}

/* ===== Lista de capacidades ===== */
/* Las capacidades de un módulo sólo como texto: número, título y
   descripción, sin fotos. Al entrar en pantalla cada capacidad aparece en
   cascada (el turno --orden lo pone js/capacidad.js): sube desenfocada, se traza su
   línea, se barre el título y se enciende el acento. */
.lista-capacidades {
  display: grid;
  margin: 0;
  padding: 0;
  gap: 38px 40px;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  list-style: none;
}

/* La lista no entra entera como los demás bloques con data-revelar: entran
   sus capacidades una a una. Lo mismo la portada de cada módulo (ver
   "Entrada de las portadas"). */
.lista-capacidades.revelar,
.contenido-portada-capacidad.revelar {
  opacity: 1;
  transform: none;
  animation: none;
}

/* El fondo que asoma al pasar el ratón desborda 16 px a cada lado para que el
   texto siga alineado con el título. */
.lista-capacidades li {
  position: relative;
  margin: 0 -16px;
  padding: 20px 16px 24px;
  border-radius: 0 0 8px 8px;
  background: linear-gradient(to bottom, color-mix(in srgb, var(--acento) 13%, transparent), transparent) no-repeat top / 100% 0%;
  transition: background-size 220ms var(--ease-out), transform 220ms var(--ease-out);
}

/* Línea de cada capacidad. */
.lista-capacidades li::after {
  content: "";
  position: absolute;
  top: 0;
  right: 16px;
  left: 16px;
  height: 1px;
  background: rgb(255 255 255 / 14%);
  transform-origin: left;
}

/* Trazo de acento sobre la línea; al pasar el ratón la recorre entera. Ocupa
   toda la línea y un recorte deja ver sólo sus primeros 34 px: así crece sin
   animar el ancho. El margen vertical del recorte deja respirar el brillo. */
.lista-capacidades li::before {
  content: "";
  position: absolute;
  z-index: 1;
  top: 0;
  right: 16px;
  left: 16px;
  height: 2px;
  background: var(--acento);
  box-shadow: 0 0 12px var(--acento);
  clip-path: inset(-12px calc(100% - 34px) -12px 0);
  transform-origin: left;
  transition: clip-path 260ms var(--ease-out);
}

.numero-capacidad {
  display: block;
  color: var(--acento);
  font-family: var(--mono);
  font-size: 0.7rem;
  letter-spacing: 0.14em;
  transition: text-shadow 200ms ease;
}

.lista-capacidades h4 {
  margin: 10px 0 8px;
  font-size: 1.05rem;
  font-weight: 600;
  line-height: 1.3;
}

.lista-capacidades p {
  margin: 0;
  color: var(--texto-suave);
  font-size: 0.9rem;
  font-weight: 300;
  line-height: 1.6;
  transition: color 200ms ease;
}

@media (hover: hover) and (pointer: fine) {
  .lista-capacidades li:hover {
    background-size: 100% 100%;
    transform: translateY(-4px);
  }

  .lista-capacidades li:hover::before {
    clip-path: inset(-12px 0 -12px 0);
  }

  .lista-capacidades li:hover .numero-capacidad {
    text-shadow: 0 0 12px var(--acento);
  }

  .lista-capacidades li:hover p {
    color: #c3cad6;
  }
}

/* Entrada en cascada. Las animaciones sólo rellenan hacia atrás (backwards):
   al terminar no fijan nada y el paso del ratón sigue funcionando. */
.lista-capacidades.revelar:not(.visible) li {
  opacity: 0;
}

.lista-capacidades.visible li {
  --retraso: calc(var(--orden, 0) * 110ms + 120ms);

  animation: capacidad-entra 1000ms var(--ease-out) var(--retraso) backwards;
}

.lista-capacidades.visible li::after {
  animation: linea-se-traza 900ms var(--ease-in-out) calc(var(--retraso) + 200ms) backwards;
}

.lista-capacidades.visible li::before {
  animation: acento-se-enciende 700ms ease calc(var(--retraso) + 750ms) backwards;
}

.lista-capacidades.visible .numero-capacidad {
  animation: numero-entra 900ms var(--ease-out) calc(var(--retraso) + 250ms) backwards;
}

.lista-capacidades.visible h4 {
  animation: titulo-se-barre 800ms var(--ease-in-out) calc(var(--retraso) + 380ms) backwards;
}

@keyframes capacidad-entra {
  from {
    opacity: 0;
    filter: blur(8px);
    transform: translateY(40px);
  }
}

@keyframes linea-se-traza {
  from {
    transform: scaleX(0);
  }
}

@keyframes acento-se-enciende {
  from {
    opacity: 0;
    transform: scaleX(0);
  }
}

@keyframes numero-entra {
  from {
    opacity: 0;
    letter-spacing: 0.7em;
  }
}

@keyframes titulo-se-barre {
  from {
    clip-path: inset(-20% 100% -20% 0);
  }

  to {
    clip-path: inset(-20% 0 -20% 0);
  }
}

/* ===== Portada del pilar e índice ===== */
.portada-solucion {
  min-height: 88vh;
}

.detalle-solucion {
  max-width: 48ch;
  margin: 18px 0 0;
  color: #c3cad6;
  font-size: clamp(0.95rem, 1.4vw, 1.05rem);
  font-weight: 300;
  line-height: 1.7;
}

/* ===== Secciones de cada capacidad ===== */
/* La barra superior es fija: sin este margen, al llegar por un ancla (#videovigilancia…) el
   título de la sección quedaría tapado por ella. js/capacidad.js guarda su
   alto en --alto-barra. */
.modulo {
  scroll-margin-top: var(--alto-barra, 120px);
}

.portada-capacidad.portada-modulo {
  min-height: 64vh;
  border-top: 1px solid rgb(255 255 255 / 8%);
}

/* ===== Vídeo ===== */
/* Entra con un leve acercamiento desde el 96 % y sale más rápido de lo que
   entró. display y overlay con allow-discrete dejan animar también el cierre;
   @starting-style da el punto de partida al abrir. */
.modal-video {
  width: min(100% - 40px, 1040px);
  padding: 0;
  border: 1px solid rgb(255 255 255 / 14%);
  border-radius: 8px;
  background: #000;
  opacity: 0;
  transform: scale(0.96);
  transition:
    opacity 180ms ease,
    transform 180ms var(--ease-out),
    overlay 180ms allow-discrete,
    display 180ms allow-discrete;
}

.modal-video[open] {
  opacity: 1;
  transform: none;
  transition:
    opacity 250ms ease,
    transform 250ms var(--ease-out),
    overlay 250ms allow-discrete,
    display 250ms allow-discrete;
}

@starting-style {
  .modal-video[open] {
    opacity: 0;
    transform: scale(0.96);
  }
}

.modal-video::backdrop {
  background: rgb(2 4 10 / 88%);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  opacity: 0;
  transition:
    opacity 180ms ease,
    overlay 180ms allow-discrete,
    display 180ms allow-discrete;
}

.modal-video[open]::backdrop {
  opacity: 1;
  transition:
    opacity 250ms ease,
    overlay 250ms allow-discrete,
    display 250ms allow-discrete;
}

@starting-style {
  .modal-video[open]::backdrop {
    opacity: 0;
  }
}

.modal-video video {
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  background: #000;
}

.cerrar-modal {
  position: absolute;
  z-index: 2;
  top: 12px;
  right: 12px;
  display: grid;
  width: 38px;
  height: 38px;
  border: 1px solid rgb(255 255 255 / 22%);
  border-radius: 50%;
  background: rgb(3 6 14 / 72%);
  color: #fff;
  cursor: pointer;
  place-items: center;
  transition: background 200ms ease, border-color 200ms ease;
}

.cerrar-modal:hover {
  border-color: var(--acento);
  background: rgb(3 6 14 / 95%);
}

.cerrar-modal svg {
  width: 17px;
  height: 17px;
}

/* ===== Pie ===== */
.pie-capacidad {
  padding: 30px 0;
  border-top: 1px solid rgb(255 255 255 / 10%);
  color: var(--texto-suave);
  font-size: 0.76rem;
}

.pie-capacidad .contenedor {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.pie-capacidad p {
  margin: 0;
}

.pie-capacidad a {
  color: var(--texto-suave);
  transition: color 200ms ease;
}

.pie-capacidad a:hover {
  color: #fff;
}

/* ===== Efectos ligados al scroll ===== */
/* Los mueve el propio desplazamiento (animation-timeline), sin JavaScript y
   fuera del hilo principal. En navegadores sin soporte o con movimiento
   reducido la página queda igual, sólo sin estos efectos. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    /* Barra de progreso de lectura en el borde superior del encabezado (el
       inferior es del indicador del menú). */
    .barra-capacidad::after {
      content: "";
      position: absolute;
      top: 0;
      right: 0;
      left: 0;
      height: 2px;
      background: linear-gradient(90deg, var(--acento), var(--cian));
      box-shadow: 0 0 10px color-mix(in srgb, var(--acento) 70%, transparent);
      transform-origin: left;
      animation: progreso-lectura linear both;
      animation-timeline: scroll(root);
    }

    /* Profundidad: la foto de cada portada se desplaza más despacio que el
       texto. La escala evita que asomen sus bordes. */
    .fondo-portada img {
      animation: paralaje-portada linear both;
      animation-timeline: view();
      animation-range: cover;
    }

    /* El texto de la portada se despide suavemente al salir por arriba. Va
       en el .contenedor y no en el bloque con data-revelar para no pisar su
       entrada. */
    .portada-capacidad > .contenedor {
      animation: salida-portada linear both;
      animation-timeline: view();
      animation-range: exit 5% exit 85%;
    }
  }
}

@keyframes progreso-lectura {
  from {
    transform: scaleX(0);
  }

  to {
    transform: scaleX(1);
  }
}

@keyframes paralaje-portada {
  from {
    transform: translateY(-7%) scale(1.16);
  }

  to {
    transform: translateY(7%) scale(1.16);
  }
}

@keyframes salida-portada {
  to {
    opacity: 0.1;
    transform: translateY(-60px) scale(0.98);
  }
}

@media (max-width: 1100px) {
  .lista-capacidades {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 620px) {
  .marca-capacidad img {
    height: 32px;
  }

  .barra-capacidad .volver {
    padding: 10px 14px;
    gap: 6px;
    font-size: 0.6rem;
    letter-spacing: 0.08em;
  }

  .portada-capacidad {
    min-height: 0;
    padding: 64px 0 72px;
  }

  /* De pie, la foto luce mejor centrada en la cámara que recortada al 70%. */
  .fondo-portada img {
    object-position: 62% 40%;
  }

  .portada-capacidad.portada-modulo {
    min-height: 0;
  }

  .reproducir {
    margin-top: 32px;
    gap: 14px;
  }

  .icono-reproducir {
    width: 50px;
    height: 50px;
  }

  .seccion-capacidades {
    padding: 58px 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .lista-capacidades.visible li,
  .lista-capacidades.visible li::before,
  .lista-capacidades.visible li::after,
  .lista-capacidades.visible .numero-capacidad,
  .lista-capacidades.visible h4,
  .con-red-nodos::after {
    animation: none;
  }

  .icono-reproducir {
    transition: none;
  }
}

/* ===== Base táctil ===== */
/* Sin el destello gris que pinta el navegador al tocar: cada control ya tiene
   su propia respuesta al presionar. manipulation quita la espera del doble
   toque, así que el toque responde en cuanto se levanta el dedo. */
html {
  -webkit-tap-highlight-color: transparent;
}

.pagina-capacidad :is(a, button) {
  touch-action: manipulation;
}

.reproducir,
.menu-capacidades a {
  -webkit-user-select: none;
  user-select: none;
}

/* Las portadas no deben quedar cortadas con la barra de direcciones visible:
   svh es el alto más pequeño que alcanza la pantalla y no salta al
   desplazarse. En el móvil las portadas miden lo que su texto (ver más
   arriba), así que esto sólo aplica a partir de tableta. */
@media (min-width: 621px) {
  .portada-solucion {
    min-height: 88svh;
  }

  .portada-capacidad.portada-modulo {
    min-height: 64svh;
  }
}

/* ===== Entrada de las portadas ===== */
/* El bloque no entra entero: la cinta se traza y cada línea sube en cascada,
   el título emergiendo de su propia línea base. Así el ojo recorre la portada
   en el orden en que se lee. Anula la entrada del bloque entero junto con la
   lista de capacidades (más arriba). */
.contenido-portada-capacidad.revelar:not(.visible)::before,
.contenido-portada-capacidad.revelar:not(.visible) > * {
  opacity: 0;
}

.contenido-portada-capacidad::before {
  transform-origin: left;
}

.contenido-portada-capacidad.visible::before {
  animation: cinta-se-traza 800ms var(--ease-in-out) backwards;
}

.contenido-portada-capacidad > :nth-child(1) { --paso: 0; }
.contenido-portada-capacidad > :nth-child(2) { --paso: 1; }
.contenido-portada-capacidad > :nth-child(3) { --paso: 2; }
.contenido-portada-capacidad > :nth-child(4) { --paso: 3; }
.contenido-portada-capacidad > :nth-child(5) { --paso: 4; }

.contenido-portada-capacidad.visible > * {
  animation: portada-sube 900ms var(--ease-out) calc(var(--paso, 0) * 90ms + 180ms) backwards;
}

.contenido-portada-capacidad.visible > :is(h1, h2) {
  animation-name: titulo-emerge;
}

@keyframes cinta-se-traza {
  from {
    transform: scaleX(0);
  }
}

@keyframes portada-sube {
  from {
    opacity: 0;
    filter: blur(6px);
    transform: translateY(22px);
  }
}

@keyframes titulo-emerge {
  from {
    clip-path: inset(0 -5% 100% -5%);
    transform: translateY(0.4em);
  }

  to {
    clip-path: inset(-10% -5% -10% -5%);
    transform: none;
  }
}

/* La foto de cada capacidad se abre como una ventana mientras entra en
   pantalla: parte de un marco redondeado y termina a sangre. Va en el
   contenedor y no en la imagen para no pisar el paralaje. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .portada-modulo .fondo-portada {
      animation: ventana-foto linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 85%;
    }
  }
}

@keyframes ventana-foto {
  from {
    clip-path: inset(9% 5% 0 5% round 18px);
  }

  to {
    clip-path: inset(0 0 0 0 round 0);
  }
}

/* ===== Capacidades deslizables en el móvil ===== */
/* La pista que acompaña a cada lista: en qué capacidad va y cuánto falta.
   La crea js/capacidad.js y sólo se ve en pantallas estrechas. */
.pista-capacidades {
  display: none;
}

@media (max-width: 620px) {
  /* En una columna las 54 capacidades sumaban más de diez pantallas de
     desplazamiento. Cada módulo es ahora una tira de tarjetas que se desliza
     de lado y se detiene en cada una; la siguiente asoma para invitar a
     seguir. */
  .lista-capacidades {
    display: grid;
    margin: 0 -24px;
    padding: 6px 24px 4px;
    gap: 12px;
    grid-auto-columns: 84%;
    grid-auto-flow: column;
    grid-template-columns: none;
    overflow-x: auto;
    /* Sin esto la subida de entrada de las tarjetas haría desplazable la
       tira también en vertical. */
    overflow-y: hidden;
    overscroll-behavior-x: contain;
    scroll-padding-inline: 24px;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
  }

  .lista-capacidades::-webkit-scrollbar {
    display: none;
  }

  .lista-capacidades li {
    display: flex;
    min-height: 196px;
    flex-direction: column;
    margin: 0;
    padding: 26px 22px 24px;
    border: 1px solid rgb(255 255 255 / 9%);
    border-radius: 12px;
    background: linear-gradient(160deg, color-mix(in srgb, var(--acento) 13%, rgb(8 14 30 / 85%)), rgb(5 10 22 / 75%));
    scroll-snap-align: start;
  }

  .lista-capacidades li::after {
    display: none;
  }

  /* Las tarjetas llegan por el mismo eje en que se deslizan. */
  .lista-capacidades.visible li {
    animation-name: capacidad-entra-lado;
  }

  .lista-capacidades li::before {
    right: 22px;
    left: 22px;
    border-radius: 0 0 2px 2px;
  }

  .lista-capacidades h4 {
    margin-top: 14px;
    font-size: 1.08rem;
  }

  .pista-capacidades {
    display: flex;
    align-items: center;
    margin-top: 20px;
    gap: 14px;
    color: var(--texto-suave);
    font-family: var(--mono);
    font-size: 0.68rem;
    letter-spacing: 0.14em;
  }

  .pista-capacidades b {
    color: #fff;
    font-weight: 500;
  }

  .riel-capacidades {
    position: relative;
    overflow: hidden;
    height: 2px;
    flex: 1;
    border-radius: 2px;
    background: rgb(255 255 255 / 12%);
  }

  .avance-capacidades {
    position: absolute;
    inset: 0;
    background: var(--acento);
    box-shadow: 0 0 10px var(--acento);
    transform: scaleX(var(--avance, 0));
    transform-origin: left;
    transition: transform 300ms var(--ease-out);
  }
}

@keyframes capacidad-entra-lado {
  from {
    opacity: 0;
    filter: blur(6px);
    transform: translateX(56px);
  }
}

@media (prefers-reduced-motion: reduce) {
  .contenido-portada-capacidad.visible::before,
  .contenido-portada-capacidad.visible > * {
    animation: none;
  }
}

/* ===== Monitor de cámara ===== */
/* Junto a cada lista de capacidades, la foto del módulo vista como el monitor
   de una sala de control. Al elegir una capacidad (ratón, teclado, scroll o,
   en el móvil, deslizando la tira) la cámara hace un paneo y acercamiento a
   una zona y un recuadro de detección la fija. Lo arma js/capacidad.js; sin
   JavaScript la lista queda como siempre. Es decorativo (aria-hidden): el
   texto vive en la lista. */
.monitor {
  position: relative;
  overflow: hidden;
  margin: 0 0 36px;
  /* Las proporciones de la foto (--proporcion, de js/capacidad.js): la vista
     general la muestra completa, sin recortes. */
  aspect-ratio: var(--proporcion, 16 / 9);
  border: 1px solid rgb(255 255 255 / 12%);
  border-radius: 14px;
  background: #02050c;
  box-shadow:
    0 30px 80px rgb(0 0 0 / 55%),
    inset 0 1px 0 rgb(255 255 255 / 6%);
  isolation: isolate;
}

.monitor-imagen {
  position: absolute;
  inset: 0;
}

/* La foto a sus proporciones reales, al tamaño que cubre el monitor (--iw y
   --ih, los calcula js/capacidad.js). El encuadre de cada capacidad es sólo
   un transform desde la esquina: desplazar y ampliar. */
.monitor-imagen img {
  position: absolute;
  top: 0;
  left: 0;
  width: var(--iw, 100%);
  max-width: none;
  height: var(--ih, 100%);
  filter: saturate(0.82) contrast(1.06) brightness(0.86);
  transform: translate(var(--tx, 0), var(--ty, 0)) scale(var(--zoom, 1));
  transform-origin: 0 0;
  /* Un PTZ arranca y frena suave, no salta. */
  transition: transform 1100ms var(--ease-in-out);
}

/* Módulo que aún no tiene foto: un plano cuadriculado en el tono del acento
   ocupa su lugar y se mueve igual que ella, así el monitor funciona completo
   mientras llega la imagen. */
.monitor-sin-foto {
  position: absolute;
  top: 0;
  left: 0;
  width: var(--iw, 100%);
  height: var(--ih, 100%);
  background:
    radial-gradient(ellipse 60% 55% at 50% 45%, color-mix(in srgb, var(--acento) 16%, transparent), transparent 70%),
    linear-gradient(color-mix(in srgb, var(--acento) 13%, transparent) 1px, transparent 1px) 0 0 / 44px 44px,
    linear-gradient(90deg, color-mix(in srgb, var(--acento) 13%, transparent) 1px, transparent 1px) 0 0 / 44px 44px,
    #040a17;
  transform: translate(var(--tx, 0), var(--ty, 0)) scale(var(--zoom, 1));
  transform-origin: 0 0;
  transition: transform 1100ms var(--ease-in-out);
}

/* Viñeta y tinte del acento: aire de pantalla de vigilancia. */
.monitor::before {
  content: "";
  position: absolute;
  z-index: 1;
  background:
    radial-gradient(ellipse 80% 75% at 50% 50%, transparent 55%, rgb(2 5 12 / 70%) 100%),
    linear-gradient(color-mix(in srgb, var(--acento) 10%, transparent), transparent 40%);
  inset: 0;
  pointer-events: none;
}

/* Líneas de exploración muy finas. */
.monitor::after {
  content: "";
  position: absolute;
  z-index: 1;
  background: repeating-linear-gradient(to bottom, rgb(255 255 255 / 3%) 0 1px, transparent 1px 3px);
  inset: 0;
  pointer-events: none;
}

/* Barrido que recorre la imagen de arriba abajo, como un refresco de señal.
   Sólo corre mientras el monitor está en pantalla. */
.monitor-barrido {
  position: absolute;
  z-index: 2;
  top: 0;
  right: 0;
  left: 0;
  height: 22%;
  background: linear-gradient(to bottom, transparent, color-mix(in srgb, var(--acento) 14%, transparent) 85%, color-mix(in srgb, var(--acento) 50%, transparent));
  opacity: 0.5;
  pointer-events: none;
  transform: translateY(-100%);
  animation: barrido-monitor 5.5s linear infinite;
  animation-play-state: paused;
}

.monitor.en-pantalla .monitor-barrido {
  animation-play-state: running;
}

@keyframes barrido-monitor {
  to {
    transform: translateY(560%);
  }
}

/* Esquinas de encuadre de la cámara. */
.monitor-esquinas {
  --l: 22px;

  position: absolute;
  z-index: 3;
  background:
    linear-gradient(#fff, #fff) top left / var(--l) 1.5px,
    linear-gradient(#fff, #fff) top left / 1.5px var(--l),
    linear-gradient(#fff, #fff) top right / var(--l) 1.5px,
    linear-gradient(#fff, #fff) top right / 1.5px var(--l),
    linear-gradient(#fff, #fff) bottom left / var(--l) 1.5px,
    linear-gradient(#fff, #fff) bottom left / 1.5px var(--l),
    linear-gradient(#fff, #fff) bottom right / var(--l) 1.5px,
    linear-gradient(#fff, #fff) bottom right / 1.5px var(--l);
  background-repeat: no-repeat;
  inset: 16px;
  opacity: 0.55;
  pointer-events: none;
}

.monitor-cabecera {
  position: absolute;
  z-index: 4;
  top: 28px;
  right: 32px;
  left: 32px;
  display: flex;
  align-items: center;
  gap: 18px;
  color: rgb(255 255 255 / 82%);
  font-family: var(--mono);
  font-size: 0.66rem;
  letter-spacing: 0.16em;
  text-shadow: 0 1px 6px rgb(0 0 0 / 80%);
}

.monitor-rec {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  color: #fff;
}

.monitor-rec::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--rojo);
  box-shadow: 0 0 8px var(--rojo);
  animation: parpadeo-rec 1.6s steps(1, end) infinite;
}

@keyframes parpadeo-rec {
  50% {
    opacity: 0.15;
  }
}

.monitor-hora {
  margin-left: auto;
  font-variant-numeric: tabular-nums;
}

/* El recuadro de detección. La capa se traslada hasta el centro del sujeto
   (--mx, --my) y el recuadro, centrado en su esquina, toma el tamaño del
   sujeto (--bw, --bh). Cambiar ese tamaño es cambiar width y height, pero de
   un solo elemento pequeño y sin nada que dependa de él. */
.monitor-mira {
  position: absolute;
  z-index: 3;
  top: 0;
  left: 0;
  pointer-events: none;
  transform: translate(var(--mx, 50%), var(--my, 50%));
  transition: transform 1100ms var(--ease-in-out), opacity 450ms ease;
}

/* En la vista general no hay objetivo: el recuadro espera oculto. */
.monitor.vista-general .monitor-mira {
  opacity: 0;
}

.monitor-recuadro {
  position: absolute;
  top: 0;
  left: 0;
  width: var(--bw, 120px);
  height: var(--bh, 120px);
  transition: width 1100ms var(--ease-in-out), height 1100ms var(--ease-in-out);
  border: 1.5px solid var(--acento);
  border-radius: 4px;
  background: color-mix(in srgb, var(--acento) 8%, transparent);
  box-shadow:
    0 0 0 1px rgb(0 0 0 / 35%),
    0 0 22px color-mix(in srgb, var(--acento) 45%, transparent),
    inset 0 0 18px color-mix(in srgb, var(--acento) 18%, transparent);
  translate: -50% -50%;
}

.monitor-recuadro::before {
  content: attr(data-etiqueta);
  position: absolute;
  bottom: calc(100% + 6px);
  left: -1.5px;
  padding: 3px 7px;
  border-radius: 3px;
  background: var(--acento);
  color: #fff;
  font-family: var(--mono);
  font-size: 0.6rem;
  letter-spacing: 0.12em;
  white-space: nowrap;
}

.monitor-recuadro[data-abajo]::before {
  top: calc(100% + 6px);
  bottom: auto;
}

/* Pie del monitor: la capacidad elegida. */
.monitor-pie {
  position: absolute;
  z-index: 4;
  right: 0;
  bottom: 0;
  left: 0;
  display: flex;
  align-items: baseline;
  padding: 64px 32px 26px;
  gap: 14px;
  background: linear-gradient(to top, rgb(2 5 12 / 92%), rgb(2 5 12 / 60%) 55%, transparent);
}

.monitor-numero {
  flex: none;
  color: var(--acento);
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.14em;
}

.monitor-titulo {
  color: #fff;
  font-family: var(--titulos);
  font-size: clamp(1rem, 1.6vw, 1.3rem);
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.25;
  text-wrap: balance;
}

/* La capacidad elegida en la lista se ve igual que al pasar el ratón. */
.con-monitor .lista-capacidades li.activa {
  background-size: 100% 100%;
}

.con-monitor .lista-capacidades li.activa::before {
  clip-path: inset(-12px 0 -12px 0);
}

.con-monitor .lista-capacidades li.activa .numero-capacidad {
  text-shadow: 0 0 12px var(--acento);
}

.con-monitor .lista-capacidades li.activa p {
  color: #c3cad6;
}

.con-monitor .lista-capacidades li:focus-visible {
  outline: 2px solid var(--acento);
  outline-offset: -2px;
}

/* En escritorio, consola de dos columnas: la lista a la izquierda, en una
   sola columna, y el monitor a la derecha acompañando mientras se recorre. */
@media (min-width: 1101px) {
  .con-monitor > .contenedor {
    display: grid;
    align-items: start;
    column-gap: clamp(40px, 5vw, 80px);
    grid-template-areas:
      "titulo monitor"
      "lista monitor";
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
    grid-template-rows: auto 1fr;
  }

  .con-monitor h3 {
    grid-area: titulo;
  }

  .con-monitor .lista-capacidades {
    gap: 4px;
    grid-area: lista;
    grid-template-columns: 1fr;
  }

  .con-monitor .lista-capacidades li {
    padding: 18px 16px;
  }

  .con-monitor .lista-capacidades h4 {
    margin: 6px 0 4px;
  }

  .con-monitor .monitor {
    position: sticky;
    top: calc(var(--alto-barra, 120px) + 28px);
    max-height: calc(100svh - var(--alto-barra, 120px) - 56px);
    margin: 0;
    grid-area: monitor;
  }
}

@media (max-width: 620px) {
  .monitor {
    margin-bottom: 22px;
    border-radius: 12px;
  }

  .monitor-cabecera {
    top: 18px;
    right: 20px;
    left: 20px;
    gap: 12px;
    font-size: 0.58rem;
  }

  .monitor-esquinas {
    --l: 16px;

    inset: 10px;
  }

  .monitor-pie {
    padding: 40px 20px 16px;
  }

  .monitor-recuadro::before {
    font-size: 0.54rem;
  }
}

@media (prefers-reduced-motion: reduce) {
  .monitor-imagen img,
  .monitor-sin-foto,
  .monitor-mira,
  .monitor-recuadro {
    transition: none;
  }

  .monitor-rec::before {
    animation: none;
  }

  .monitor-barrido {
    display: none;
  }
}

/* ===== Partículas de la portada ===== */
/* El fondo de la portada es una foto quieta. Antes se rehacía en partículas
   animadas, pero hacían lenta la página. Ocupa la portada entera y se
   desvanece en el borde de abajo para pasar suave al primer módulo. */
.foto-portada {
  position: absolute;
  z-index: -1;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  -webkit-mask-image: linear-gradient(to bottom, #000 80%, transparent);
  mask-image: linear-gradient(to bottom, #000 80%, transparent);
  object-fit: cover;
  pointer-events: none;
}

/* Foto panorámica con el motivo pegado al borde derecho (la torre de
   Conectar, la cámara de Ver): al recortarla se ancla a la derecha para
   no perderlo. */
.foto-portada-derecha {
  object-position: right center;
}

/* Velo a la izquierda, sobre la foto y bajo el texto, para que el
   título se lea aunque la escena tenga luz detrás. */
.portada-solucion::after {
  content: "";
  position: absolute;
  z-index: -1;
  background: linear-gradient(95deg, rgb(3 6 14 / 62%) 0%, rgb(3 6 14 / 32%) 30%, transparent 55%);
  inset: 0;
  pointer-events: none;
}

@media (max-width: 620px) {
  .portada-solucion::after {
    background: linear-gradient(to bottom, rgb(3 6 14 / 35%), rgb(3 6 14 / 78%) 45%, rgb(3 6 14 / 78%));
  }
}

/* ===== Ventana ancha pero vertical =====
   El "modo computadora" de un navegador móvil declara unos 980px de ancho con
   la pantalla todavía vertical: 88svh pasaba de 1800px y cada portada era una
   foto gigante con el texto perdido en medio. Como en la portada de inicio
   (encabezado-portada.css), la altura pasa a depender del ancho sin superar
   nunca la de la pantalla. Un monitor es apaisado y nunca entra aquí. */
@media (min-width: 901px) and (max-aspect-ratio: 1 / 1) {
  .portada-capacidad {
    min-height: min(78svh, 56vw);
  }

  .portada-solucion {
    min-height: min(88svh, 60vw);
  }

  .portada-capacidad.portada-modulo {
    min-height: min(64svh, 44vw);
  }
}
