/* ═══════════════════════════════════════════════════════════════
   PORTADA — el hero en carrusel.

   Cuatro diapositivas apiladas en el mismo sitio; solo cambia cuál
   está visible. No hay una tira que se desplaza: cruzar en opacidad
   con un zoom lento de fondo se ve mejor a pantalla completa y no
   obliga a medir anchos en JavaScript.

   El reset, el header y el footer NO están aquí: viven en base.css,
   header.css y footer.css, que carga toda página.
   ═══════════════════════════════════════════════════════════════ */

/* La portada es solo el hero: ocupa la ventana entera y nada más.
   Sin footer y sin nada debajo, no hay a dónde desplazarse, así que se
   bloquea el scroll del documento y el gesto lo recoge el carrusel para
   pasar de diapositiva. overscroll-behavior corta además el rebote
   elástico de macOS y el pull-to-refresh de Android, que si no
   aparecerían al empujar contra un tope que no existe. */
/* La clase va en el <body>, así que el <html> se alcanza con :has().
   Hacen falta los dos: con overflow:hidden solo en el body, el
   documento sigue pudiendo desplazarse desde el elemento raíz. */
html:has(body.cuerpo-hero) { height: 100%; overflow: hidden; }
body.cuerpo-hero {
  height: 100%;
  overflow: hidden;
  overscroll-behavior: none;
}

.hero {
  position: relative;
  height: 100svh;          /* svh, no vh: en móvil la barra del
                              navegador no recorta el pie del hero */
  min-height: 560px;
  overflow: hidden;
  background: #07070a;
}

/* ── Cada diapositiva ──────────────────────────────────────────── */
/* El cruce entre diapositivas.
   Es ASIMÉTRICO a propósito: la entrante sube de inmediato, y la
   saliente espera un poco antes de irse. Si las dos cruzaran a la vez,
   a mitad del camino ambas estarían al 50% y el conjunto perdería luz
   —un parpadeo oscuro en medio de la transición—. Dejando que la
   saliente aguante, la entrante ya está arriba cuando la otra se va.

   --hero-fundido lo publica el JavaScript, que necesita el mismo
   número para adelantar el cambio y tapar el salto del bucle. */
.hero-slide {
  position: absolute; inset: 0;
  opacity: 0; visibility: hidden;
  transition:
    opacity    calc(var(--hero-fundido, 1100ms) * .8) ease calc(var(--hero-fundido, 1100ms) * .25),
    visibility calc(var(--hero-fundido, 1100ms) * .8) linear calc(var(--hero-fundido, 1100ms) * .25);
}
.hero-slide.is-active {
  opacity: 1; visibility: visible;
  transition: opacity var(--hero-fundido, 1100ms) ease, visibility 0s;
}

/* ── El fondo ──────────────────────────────────────────────────── */
.hero-fondo {
  position: absolute; inset: 0;
  /* Crea contexto de apilado propio. Sin esto, el mix-blend-mode del
     tinte se mezclaría con lo que haya por debajo del fondo —incluido
     el color del <body>— en vez de solo con el vídeo y el poster. */
  isolation: isolate;
  /* Mientras no haya foto, el degradado de la vertical ES el fondo.
     Cuando 'imagen' se rellene en config/hero.php, la foto entra
     encima y esto queda debajo como tinte de reserva. */
  background:
    radial-gradient(120% 90% at 72% 38%, var(--acento-slide) 0%, transparent 62%),
    linear-gradient(150deg, #0d0d16 0%, #14141f 45%, #07070a 100%);
}
.hero-fondo img,
.hero-video {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
}

/* Zoom lento mientras la diapositiva está a la vista: da vida a una
   foto fija sin pedirle nada al procesador. Al vídeo no se le aplica:
   ya tiene su propio movimiento y sumarle otro marea. */
.hero-fondo img {
  transform: scale(1.06);
  transition: transform 9s linear;
}
.hero-slide.is-active .hero-fondo img { transform: scale(1); }
.hero-fondo:has(.hero-video.esta-jugando) img { transform: none; transition: none; }

/* El vídeo entra por encima del poster cuando ya tiene fotogramas que
   mostrar. Antes de eso es transparente y se ve el poster debajo, así
   que no hay parpadeo negro al arrancar. */
.hero-video {
  opacity: 0;
  transition: opacity .5s ease;
  z-index: 1;
}
.hero-video.esta-jugando { opacity: 1; }

/* ── El tinte de color sobre el metraje ────────────────────────────
   El mismo degradado radial que hace de fondo cuando no hay vídeo,
   pero puesto ENCIMA como capa de color. Reutiliza --acento-slide, así
   que cada vertical se tiñe sola con el suyo sin escribir un color más.

   Lo que decide cómo se ve NO es la opacidad: es el modo de mezcla.
   Sobre un píxel de este metraje, que tiene un 6% de luz:

     color       deja la luz EXACTAMENTE donde estaba (6%) y solo le
                 cambia el tono. Los negros siguen negros, y lo que ya
                 tenía luz —los paneles, la figura— se vuelve naranja.
                 Es un viraje de color de verdad, como un LUT de cine.
                 ← el puesto ahora
     hue         igual, pero conserva también la saturación original.
                 Aún más suave.
     screen      lo sube al 51%: eso no es teñir, es ACLARAR el plano.
                 Se ve mucho color, a costa de lavar el vídeo.
     soft-light  lo deja en el 20%. Respeta los negros por diseño, así
                 que sobre metraje oscuro casi no se aprecia.
     overlay     lo deja en el 11%. Sobre negros hace todavía menos.
     multiply    lo baja al 5%. Aquí solo ensucia.

   Los dos diales son --tinte-modo y --tinte-fuerza. Para quitarlo
   entero, borrar este bloque: nada del HTML depende de él. */
.hero-fondo.tiene-media::after {
  content: '';
  position: absolute; inset: 0; z-index: 2;
  pointer-events: none;
  background: radial-gradient(120% 90% at 72% 38%, var(--acento-slide) 0%, transparent 62%);
  mix-blend-mode: var(--tinte-modo, color);
  opacity: var(--tinte-fuerza, .8);
}
/* El velo que hace legible el texto sobre cualquier foto. Es más denso
   a la izquierda, que es donde vive el texto, y se abre hacia la
   derecha para no tapar la imagen. */
.hero-velo {
  position: absolute; inset: 0; z-index: 2;
  background:
    linear-gradient(90deg, rgba(6,6,10,.82) 0%, rgba(6,6,10,.55) 38%, rgba(6,6,10,.10) 72%, transparent 100%),
    linear-gradient(0deg, rgba(6,6,10,.55) 0%, transparent 32%);
}

/* Con foto o vídeo detrás el velo se afloja: estaba calibrado contra un
   degradado plano y de colores vivos. Sobre metraje que ya es casi
   negro, esa misma densidad hunde la mitad izquierda en barro. */
.hero-fondo.tiene-media ~ .hero-velo {
  background:
    linear-gradient(90deg, rgba(6,6,10,.72) 0%, rgba(6,6,10,.42) 40%, rgba(6,6,10,.06) 74%, transparent 100%),
    linear-gradient(0deg, rgba(6,6,10,.62) 0%, transparent 34%);
}

/* ── El texto ──────────────────────────────────────────────────── */
.hero-texto {
  position: relative; z-index: 2;
  display: flex; flex-direction: column; align-items: flex-start;
  justify-content: center;
  height: 100%;
  /* El mismo contenedor que el header: así el rótulo del hero cae
     exactamente bajo el logotipo, no desalineado unos pixeles. */
  max-width: var(--ancho-max);
  margin: 0 auto;
  padding: var(--nav-alto) var(--hd-pad) 150px;
}

.hero-eyebrow {
  font-size: 15px; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; color: #fff;
  margin-bottom: 18px;
}

.hero-titulo {
  /* Enorme a propósito. El clamp va de 58px en un teléfono a 170px en
     un monitor grande; 'Developer', que es la palabra más larga, cabe
     en una línea a partir de 380px de ancho. */
  font-size: clamp(58px, 11.5vw, 170px);
  font-weight: 800; letter-spacing: -.035em; line-height: .88;
  text-transform: uppercase; color: #fff;
  margin-bottom: 30px;
}

.hero-parrafo {
  font-size: clamp(15px, 1.15vw, 17.5px);
  line-height: 1.62; color: rgba(255,255,255,.82);
  max-width: 540px; margin-bottom: 36px;
}

/* ── El botón ──────────────────────────────────────────────────── */
.hero-cta {
  position: relative;
  display: inline-flex; align-items: center; gap: 14px;
  font-size: 17px; color: #fff; text-decoration: none;
  padding-bottom: 6px;
}
.hero-cta-punto {
  width: 7px; height: 7px; border-radius: 50%;
  border: 1px solid rgba(255,255,255,.65);
  flex-shrink: 0;
  transition: background .3s ease, border-color .3s ease;
}
/* El subrayado va bajo el texto, no bajo el punto: por eso el ::after
   arranca donde termina el punto y su hueco. */
.hero-cta::after {
  content: ''; position: absolute; left: 21px; right: 0; bottom: 0;
  height: 1px; background: currentColor;
  transform-origin: left;
  transition: transform .45s cubic-bezier(.16,1,.3,1);
}
.hero-cta:hover .hero-cta-punto { background: #fff; border-color: #fff; }
.hero-cta:hover::after { transform: scaleX(0); transform-origin: right; }

/* Sin sección detrás todavía: se ve, pero no finge ser un enlace. */
.hero-cta-pendiente { cursor: default; opacity: .62; }
.hero-cta-pendiente::after { opacity: .5; }

/* ── Entrada del texto ─────────────────────────────────────────── */
/* Cada pieza sube con un retraso distinto. Solo corre en la
   diapositiva activa, así se repite cada vez que se cambia. */
.hero-slide .hero-eyebrow,
.hero-slide .hero-titulo,
.hero-slide .hero-parrafo,
.hero-slide .hero-cta {
  opacity: 0; transform: translateY(26px);
}
.hero-slide.is-active .hero-eyebrow,
.hero-slide.is-active .hero-titulo,
.hero-slide.is-active .hero-parrafo,
.hero-slide.is-active .hero-cta {
  opacity: 1; transform: none;
  transition: opacity .7s cubic-bezier(.16,1,.3,1),
              transform .7s cubic-bezier(.16,1,.3,1);
}
/* El escalonado cierra a los ~1.0s, no a los 1.25s: la diapositiva
   queda asentada mucho antes de que la barra vaya por la sexta parte. */
.hero-slide.is-active .hero-eyebrow { transition-delay: .08s; }
.hero-slide.is-active .hero-titulo  { transition-delay: .14s; }
.hero-slide.is-active .hero-parrafo { transition-delay: .22s; }
.hero-slide.is-active .hero-cta     { transition-delay: .3s; }

/* ── Los controles de abajo ────────────────────────────────────────
   Antes la fila iba de borde a borde: las flechas en los extremos y
   cuatro líneas estiradas ocupando todo el ancho. Eso contradecía la
   composición, porque el texto del hero vive en una columna a la
   izquierda y el control cruzaba la pantalla ignorándola.

   Ahora es un grupo compacto (~346 px) centrado en la pantalla: sigue
   siendo un control, no un separador que cruza el hero de lado a lado.
   Va centrado y no alineado al texto a propósito —es lo que pidió el
   diseño— así que se lee como una pieza aparte, no como el final de la
   columna de texto. */
.hero-control {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 3;
  display: flex; align-items: center; justify-content: center; gap: 24px;
  /* El grupo se centra dentro del contenedor, y el contenedor ya va
     centrado en la ventana: el resultado es un control centrado en
     pantalla. Lo que NO hace es repartirse el ancho, que es lo que
     antes lo estiraba de borde a borde. */
  max-width: var(--ancho-max); margin: 0 auto;
  padding: 0 var(--hd-pad) 52px;
}

.hero-flecha {
  flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  width: 46px; height: 38px;
  background: none; border: none; padding: 0; cursor: pointer;
  color: rgba(255,255,255,.5);
  transition: color .25s ease, transform .35s cubic-bezier(.16,1,.3,1);
}
.hero-flecha:hover { color: #fff; }
.hero-flecha[data-hero="anterior"]:hover  { transform: translateX(-4px); }
.hero-flecha[data-hero="siguiente"]:hover { transform: translateX(4px); }
/* El viewBox mide 40 unidades y se dibuja a 26 px: todo se encoge a
   0.65. Por eso el grosor sube a 2 en unidades del viewBox —si no, el
   trazo acabaría en 0.9 px reales y se vería deslavado. */
.hero-flecha svg {
  width: 31px; height: 12px;
  fill: none; stroke: currentColor; stroke-width: 1.8;
  stroke-linecap: round; stroke-linejoin: round;
}

/* Sin flex:1. Eso era lo que estiraba el contador hasta llenar la fila. */
.hero-contador {
  flex: none;
  display: flex; align-items: center; gap: 15px;
}
.hero-num {
  font-size: 13.5px; font-variant-numeric: tabular-nums;
  color: rgba(255,255,255,.92); flex-shrink: 0;
}
.hero-num-total { color: rgba(255,255,255,.38); }

/* ── La barra de progreso ──────────────────────────────────────────
   Cuatro tramos cortos y fijos en lugar de cuatro que se repartían el
   ancho de la pantalla. Cada uno sigue siendo un botón: además de
   mostrar en cuál vas, deja saltar a cualquiera. La zona sensible es
   alta aunque la línea mida 2 px, para poder acertar con el dedo. */
.hero-barra { flex: none; display: flex; gap: 6px; }

.hero-pista {
  flex: none; position: relative;
  width: 48px; height: 22px; padding: 0;
  background: none; border: none; cursor: pointer;
}
.hero-pista::before {
  content: ''; position: absolute; left: 0; right: 0; top: 50%;
  height: 2px; margin-top: -1px;
  background: rgba(255,255,255,.24);
  transition: background .25s ease;
}
.hero-pista:hover::before { background: rgba(255,255,255,.45); }

.hero-pista-relleno {
  position: absolute; left: 0; top: 50%;
  height: 2px; width: 100%; margin-top: -1px;
  background: #fff;
  transform: scaleX(0); transform-origin: left;
}
/* La pista activa se rellena en el tiempo que dura la diapositiva. La
   duración la pone el JavaScript desde la propia diapositiva, para que
   el número viva en config/hero.php y no repartido entre CSS y JS. */
.hero-pista.is-active .hero-pista-relleno {
  animation: hero-progreso var(--hero-duracion, 6500ms) linear forwards;
}
/* Las ya vistas se quedan llenas: se ve de un vistazo cuánto queda. */
.hero-pista.is-vista .hero-pista-relleno { transform: scaleX(1); }

@keyframes hero-progreso { from { transform: scaleX(0); } to { transform: scaleX(1); } }

/* En pausa —puntero encima o foco de teclado— el relleno se congela
   donde iba, no vuelve a empezar. */
.hero.esta-en-pausa .hero-pista.is-active .hero-pista-relleno {
  animation-play-state: paused;
}
/* ── Tamaños ───────────────────────────────────────────────────── */
@media (max-width: 860px) {
  .hero-texto  { padding-bottom: 170px; }
  .hero-velo {
    background:
      linear-gradient(90deg, rgba(6,6,10,.88) 0%, rgba(6,6,10,.7) 55%, rgba(6,6,10,.35) 100%),
      linear-gradient(0deg, rgba(6,6,10,.6) 0%, transparent 38%);
  }
  .hero-control { gap: 14px; padding-bottom: 36px; }
  .hero-flecha  { width: 32px; }
  .hero-flecha svg { width: 22px; height: 9px; }
  .hero-contador { gap: 10px; }
  .hero-pista   { width: 32px; }
}
@media (max-width: 560px) {
  /* Con la pantalla estrecha las flechas estorban más de lo que ayudan:
     ahí se pasa deslizando, que el JavaScript ya escucha. */
  .hero-flecha { display: none; }
  .hero-parrafo { font-size: 15px; }
}

/* Quien pidió menos movimiento: sin zoom, sin entrada escalonada y sin
   avance automático —eso último lo corta el JavaScript—. La barra se
   queda llena en la que toca, para que siga informando. */
@media (prefers-reduced-motion: reduce) {
  .hero-fondo img { transform: none; transition: none; }
  .hero-slide .hero-eyebrow,
  .hero-slide .hero-titulo,
  .hero-slide .hero-parrafo,
  .hero-slide .hero-cta { opacity: 1; transform: none; }
  .hero-pista.is-active .hero-pista-relleno { animation: none; transform: scaleX(1); }
}
