/* =============================================================
   El Podcast de Webpositer — base iterable (base.html)
   Estructura: el boceto a mano del cliente (hero · métricas ·
   invitados · propuestas · newsletter).
   Estética: composiciones Subframe (prueba/subframe-composiciones.html).

   Es un archivo AUTOCONTENIDO a propósito: no depende de styles.css
   para que tocar esta base nunca pueda romper index.html, ni al revés.
   Solo lleva lo que la página usa; no hay reglas muertas.

   Reglas heredadas del sistema:
     · Naranja SOLO en detalle: un número, un icono, un hover, una palabra.
     · Cero mayúsculas. Cero degradados, glows, scrims ni tilt.
     · Superficie #141414 + borde 1px #2A2A2A + radio 14.
   Nota: var(--mono) aparece en el banco de pruebas pero NO existe en
   los tokens del proyecto. Todo va en var(--sans).
   ============================================================= */

/* ---------- 1. FUENTES -------------------------------------- */
/* PENDIENTE (tarea de assets, no de esta hoja): los .otf suman ~650 KB y son
   el activo más pesado de la página. Convertir a .woff2 subseteado a latin
   (+ º ñ tildes · —) deja los cuatro pesos en 40-60 KB, y el hero deja de
   recomponerse al cargar si además se precargan Light y Semibold desde el
   <head>. Hay que hacerlo también en styles.css y confirmar antes que la
   licencia de FT Regola Neue permite conversión y subsetting. */
@font-face{font-family:"Regola";src:url("../assets/fonts/FTRegolaNeue-Semibold.otf") format("opentype");font-weight:600;font-style:normal;font-display:swap}
@font-face{font-family:"Regola";src:url("../assets/fonts/FTRegolaNeue-Medium.otf") format("opentype");font-weight:500;font-style:normal;font-display:swap}
@font-face{font-family:"Regola";src:url("../assets/fonts/FTRegolaNeue-Regular.otf") format("opentype");font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:"Regola";src:url("../assets/fonts/FTRegolaNeue-Light.otf") format("opentype");font-weight:300;font-style:normal;font-display:swap}

/* ---------- 2. TOKENS --------------------------------------- */
:root{
  --bg:#000000; --surface:#141414; --border:#2A2A2A;
  --text:#FFFFFF; --text-2:#CCCCCC; --text-mut:#888888;
  --accent:#FF6633; --accent-2:#D4340F;
  --sans:"Regola",-apple-system,BlinkMacSystemFont,"Segoe UI",system-ui,sans-serif;
  --r:14px;
  --maxw:1120px;
  --gutter:clamp(1.5rem,7vw,6rem);
  /* Topes de tamaño. Están aquí y no cableados en cada regla para poder
     subirlos de golpe en monitores grandes: con los valores de portátil, a
     1920 la página se queda en una tira estrecha en mitad de la pantalla. */
  --fs-hero:7rem;
  --fs-statement:5.2rem;
  --fs-cifra:3.5rem;
  --fs-h2:3.8rem;
  --tile:13rem;
  --col-ep:19rem;
  /* Separación única entre secciones: cada sección pone la mitad arriba y
     la mitad abajo, así que entre el final de una y el principio de la
     siguiente hay siempre --gap. Se cambia aquí y cambia en toda la página. */
  --gap:clamp(12.5rem,34vh,20rem);
  --ease:cubic-bezier(.4,0,.2,1);
  --ease-out:cubic-bezier(.22,1,.36,1);
}

/* ---------- 3. RESET / BASE --------------------------------- */
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%}
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{animation-duration:.001ms!important;transition-duration:.001ms!important}
}
body{background:var(--bg);color:var(--text);font-family:var(--sans);font-weight:400;
  font-size:17px;line-height:1.6;-webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;overflow-x:clip}
/* El muro a sangre mide 100vw, que incluye la barra de scroll: sin recortar
   aquí, ese sobrante abre un scroll horizontal de unos pocos píxeles.
   clip y no hidden en los dos: hidden convierte el elemento en contenedor de
   scroll, y entonces el sticky del hero se pegaría a esa caja en vez de a la
   ventana, que es justo lo que no queremos. */
html{overflow-x:clip}
img{max-width:100%;display:block;height:auto}
svg{display:block}
a{color:inherit;text-decoration:none}
button{font:inherit;color:inherit;cursor:pointer;background:none;border:none}
ul{list-style:none}
::selection{background:var(--accent);color:#0A0A0A}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0,0,0,0);white-space:nowrap;border:0}
:focus-visible{outline:2px solid var(--accent);outline-offset:3px;border-radius:4px}

/* ---------- 4. LAYOUT --------------------------------------- */
.wrap{width:100%;max-width:var(--maxw);margin-inline:auto;padding-inline:var(--gutter)}
/* El relleno se ata al alto además de al ancho: con solo 11vw, en una ventana
   ancha y baja salían 158px arriba y abajo y el contenido de una sección de
   pantalla completa dejaba de caber. */
section{padding-block:calc(var(--gap) / 2)}

/* ---------- 5. TIPOGRAFÍA COMPARTIDA ------------------------ */
/* balance: si el antetítulo parte en dos líneas, que no deje una palabra
   suelta en la segunda. */
.kicker{display:block;color:var(--text-mut);font-size:1.35rem;font-weight:300;margin-bottom:1.4rem;text-wrap:balance}
/* Misma escala grande que el resto de títulos de sección: .bigline /
   .trip h2 / .listen h2 de subframe-composiciones.html. */
.h2{font-weight:300;letter-spacing:-.03em;line-height:1.05;
  font-size:clamp(2.2rem,5.6vw,var(--fs-h2));color:var(--text);max-width:16ch}
/* Para titulares con los saltos puestos a mano: el tope de 16ch los partiría
   por su cuenta y saldrían más líneas de las escritas. */
.h2--libre{max-width:none}
.lead{color:var(--text-2);font-weight:300;font-size:clamp(1.05rem,1.8vw,1.3rem);
  line-height:1.45;max-width:36rem}

/* ---------- 6. COMPONENTES ---------------------------------- */
.pill{
  --pill-bg:#FFFFFF;--pill-fg:#0A0A0A;
  display:inline-flex;align-items:center;gap:.85rem;
  background:var(--pill-bg);color:var(--pill-fg);
  padding:.5rem .5rem .5rem 1.35rem;border-radius:999px;border:1px solid transparent;
  font-weight:600;font-size:.98rem;letter-spacing:-.01em;white-space:nowrap;
  transition:border-color .3s var(--ease)}
.pill:hover{border-color:var(--accent)}
.pill__ico{width:34px;height:34px;border-radius:50%;background:var(--accent);
  display:grid;place-items:center;flex:none;transition:transform .35s var(--ease)}
.pill__ico svg{width:15px;height:15px;stroke:#0A0A0A;stroke-width:2.4;fill:none}
.pill:hover .pill__ico{transform:translate(3px,-3px)}
.pill--ghost{--pill-bg:transparent;--pill-fg:#FFFFFF;border-color:var(--border)}
.pill--ghost:hover{border-color:var(--accent)}

/* ---------- 7. NAV ------------------------------------------ */
/* Sin burger ni menú móvil: por debajo de 760px solo queda la marca. */
/* La barra arranca transparente y se vuelve negra en los primeros 90px de
   scroll. Va ligada al scroll, sin JS: el negro de la regla base es el estado
   de reserva para navegadores sin animaciones de scroll, que es el seguro
   (barra legible) y no el arriesgado (barra invisible sobre el contenido). */
.nav{position:fixed;top:0;left:0;right:0;z-index:100;
  background:var(--bg);border-bottom:1px solid var(--border)}
@supports (animation-timeline:scroll()){
  .nav{animation:nav-opaca linear both;
    animation-timeline:scroll(root);animation-range:0 90px}
}
@keyframes nav-opaca{
  from{background-color:transparent;border-bottom-color:transparent}
  to{background-color:var(--bg);border-bottom-color:var(--border)}}
.nav__in{display:flex;align-items:center;justify-content:space-between;gap:2rem;height:74px}
/* El logotipo oficial, recortado al dibujo: el SVG original venía con mucho
   aire alrededor y a 26px de alto la marca habría quedado diminuta. La versión
   usada es la de marca naranja + "podcast" en blanco, que es la que pide un
   fondo negro. */
.brand{display:flex;align-items:center;flex:none}
/* Logo antiguo (auriculares + "El Podcast de Webpositer"), montado en
   horizontal para la barra a partir del logo cuadrado. Va más alto que el
   logotipo nuevo porque lleva dos líneas de texto: a 27px no se leían. El
   nuevo sigue en assets/img/logo-podcast.svg por si se quiere volver. */
.brand img{display:block;height:clamp(34px,3.2vw,44px);width:auto}
.nav__links{display:flex;align-items:center;gap:clamp(1.25rem,2.5vw,2rem)}
/* En blanco, no en gris: sobre el hero transparente el gris se perdía.
   Bajo el cursor no cambia de color: se subraya en blanco. El subrayado ya
   está puesto en reposo pero transparente, así solo se transiciona el color y
   el texto no se mueve ni un píxel al encenderse. */
.nav__links a{color:var(--text);font-weight:300;font-size:.92rem;
  text-decoration:underline;text-decoration-color:transparent;
  text-decoration-thickness:1px;text-underline-offset:.4em;
  transition:text-decoration-color .3s var(--ease)}
.nav__links a:hover{text-decoration-color:var(--text)}
.nav__menu,.menu{display:none}

/* Todo lo que hay tras el hero sube por encima de él al hacer scroll. El
   fondo va en las capas de ancho completo, no en cada sección: las secciones
   son .wrap y su fondo no llegaría a los bordes de la pantalla.
   .after-metricas es el mismo mecanismo un piso más abajo: métricas se queda
   clavada y esto le pasa por encima. */
.after-hero,.after-metricas{position:relative;z-index:1;
  --fade:clamp(7rem,16vh,13rem);padding-top:var(--fade);
  /* El fundido es la franja de ARRIBA DE LA PROPIA CAPA, no una banda por
     encima de ella. Puesto por fuera (como estaba antes) el negro invadía la
     sección anterior y bastaba mover un poco la rueda para dejar de verla
     entera; puesto por dentro, la capa no tapa nada hasta que de verdad
     empieza a entrar, y aun entonces lo hace desde transparente. */
  background:
    linear-gradient(to bottom,transparent,var(--bg)) top/100% var(--fade) no-repeat,
    linear-gradient(var(--bg),var(--bg)) bottom/100% calc(100% - var(--fade)) no-repeat}
.foot{position:relative;z-index:1;background:var(--bg)}

/* Remate: mientras el bloque de abajo sube, el hero se despide — el texto se
   va un poco hacia arriba y se apaga, y el fondo baja de intensidad. Es un
   extra; donde no haya animaciones ligadas al scroll (Firefox), el hero
   simplemente se queda quieto y queda tapado, que ya es el efecto. */
@supports (animation-timeline:scroll()){
  @media (prefers-reduced-motion:no-preference){
    /* El titular se va desde el primer píxel de scroll y ya no está a los
       30vh. Medido: el titular del segundo bloque asoma por abajo a los 175px
       (0.19vh de 900), así que a 270px el hero ya se ha ido y no llegan a
       convivir en pantalla. El fondo aguanta un poco más para que el hueco
       que queda por encima del bloque que sube no se vea muerto. */
    /* Arranca a los 12vh, no en el píxel cero: si empieza de inmediato, al
       mover un poco la rueda el titular ya se está yendo y da la sensación de
       que el hero no aguanta nada. */
    /* Las dos van 25vh más tarde que antes, lo mismo que se alargó el hero
       (115vh → 140vh): así el titular se sigue yendo justo cuando sube el
       bloque de suscriptores, y no se queda un hero vacío esperando. */
    /* El texto del hero ya no va aquí: lo mueve base.js (apartado 10),
       enganchado a la posición real de la capa que sube, para que arranque
       justo cuando asoma la sombra y en cualquier navegador. */
    .hero__bg{animation:hero-apaga linear both;
      animation-timeline:scroll(root);animation-range:37vh 90vh}
  }
}
@keyframes hero-apaga{to{opacity:.2}}

/* ---------- 8. REVEAL --------------------------------------- */
/* Movimiento de entrada: escalonado en el H1, suelto en el resto de secciones.
   Va detrás de .js-reveal, que base.js pone en <html> al arrancar y se quita a
   sí mismo si algo falla: sin esa clase el contenido se ve, nunca en negro. */
.js-reveal .reveal{opacity:0;transform:translateY(12px);
  transition:opacity .7s var(--ease),transform .7s var(--ease)}
.js-reveal .reveal.in{opacity:1;transform:none}
.reveal[data-d="1"]{transition-delay:.07s}
.reveal[data-d="2"]{transition-delay:.14s}
.reveal[data-d="3"]{transition-delay:.21s}

/* ---------- 9. HERO ----------------------------------------- */
/* Ocupa la pantalla completa: min-height 100vh (con svh de refuerzo en
   móvil) + el contenido centrado verticalmente con flex, en vez de vivir
   del padding-top/bottom para encajar en la altura. Así el fondo WebGL
   tiene toda la pantalla para respirar. El padding que queda es solo
   para no pegar el texto a los bordes en pantallas muy bajas/altas. */
/* Sin overflow:hidden: recortaría el desplegable de "Escúchanos" cuando el
   hero es bajo. Quien recorta el canvas es .hero__bg, que es su contenedor. */
/* El hero se queda clavado arriba y el resto de la página le pasa por encima:
   ese es el efecto de entrada. Todo lo que va detrás lleva fondo opaco y
   z-index 1, porque si no se transparentaría y se vería el hero debajo.
   Mide 140vh, no 100: como está clavado, ese 40% de más no se ve nunca, lo
   que hace es retrasar la llegada del bloque siguiente. Los mismos 40vh van
   al relleno inferior para que el contenido no baje de donde está y se siga
   viendo entero sin hacer scroll. */
.hero{position:sticky;top:0;z-index:0;text-align:center;
  min-height:140vh;min-height:140svh;
  display:flex;flex-direction:column;justify-content:center;align-items:center;
  padding-top:clamp(6rem,12vh,8rem);
  padding-bottom:calc(clamp(3rem,8vh,5rem) + 40vh)}
/* Fondo WebGL (js/hero-bg.js): negro con un giro naranja muy apagado y
   grano, sin distorsión de warp. Si WebGL2 no está disponible o el JS
   no llega a cargar, se queda el negro plano de var(--bg) — el fondo
   nunca es imprescindible para leer el hero. */
.hero__bg{position:absolute;inset:0;z-index:0;pointer-events:none;overflow:hidden}
.hero__bg canvas{display:block;width:100%;height:100%}
.hero__inner{position:relative;z-index:1}
.hero__h1{font-weight:300;letter-spacing:-.035em;line-height:1.03;
  font-size:clamp(2.8rem,min(9.2vw,12.5vh),var(--fs-hero));color:var(--text)}
.hero__h1>span{display:block}
.hero__h1 .dot{color:var(--accent)}
.hero .lead{max-width:30rem;margin-inline:auto;margin-top:clamp(1.5rem,3.4vh,2.25rem);text-wrap:balance}
.hero__act{display:flex;align-items:center;justify-content:center;
  gap:clamp(1.25rem,3vw,2rem);flex-wrap:wrap;margin-top:clamp(1.75rem,3.8vh,2.5rem)}
/* Botón "Escúchanos" con el desplegable de plataformas. Se abre con :hover
   y con :focus-within, así que funciona con ratón, con teclado (al tabular
   al botón se abre y ya se puede seguir tabulando a los enlaces) y al
   tocarlo en móvil, sin una línea de JS.
   El padding-top del menú es el puente entre botón y caja: sin él, al bajar
   el ratón se cruza un hueco sin hover y el desplegable se cerraría. */
.listen{position:relative;display:inline-block}
.listen__btn{cursor:pointer}
.listen__btn .pill__ico svg{width:17px;height:17px;stroke-width:1.7;stroke-linecap:round}
/* width:max-content es imprescindible: al ser absoluto, el ancho "auto" lo
   limita el contenedor (.listen, del tamaño del botón) y la fila se partía. */
.listen__menu{position:absolute;top:100%;left:50%;z-index:5;padding-top:.7rem;
  width:max-content;max-width:min(90vw,34rem);
  transform:translateX(-50%) translateY(-.4rem);
  opacity:0;visibility:hidden;pointer-events:none;
  transition:opacity .25s var(--ease),transform .25s var(--ease),visibility .25s var(--ease)}
.listen:hover .listen__menu,.listen:focus-within .listen__menu{
  opacity:1;visibility:visible;pointer-events:auto;transform:translateX(-50%) translateY(0)}
/* Una sola fila. El max-width es la red de seguridad para móvil: ahí las
   cuatro plataformas no caben de largo y pasan a dos líneas en vez de
   salirse de la pantalla. */
.listen__list{background:var(--surface);border:1px solid var(--border);border-radius:var(--r);
  padding:.4rem;display:flex;flex-direction:row;flex-wrap:wrap;justify-content:center;gap:.15rem}
.listen__item{display:flex;align-items:center;gap:.7rem;padding:.55rem .75rem;border-radius:9px;
  color:var(--text-2);font-weight:300;font-size:.94rem;white-space:nowrap;
  transition:background .25s var(--ease),color .25s var(--ease)}
.listen__item svg{width:17px;height:17px;flex:none;fill:var(--text-mut);
  transition:fill .25s var(--ease)}
.listen__item:hover,.listen__item:focus-visible{background:var(--bg);color:var(--text)}
.listen__item:hover svg,.listen__item:focus-visible svg{fill:var(--accent)}

/* ---------- 10. MÉTRICAS ------------------------------------ */
/* Texto a la izquierda y retrato a la derecha. La columna de texto manda en
   el ancho: el tamaño de la cifra está calculado para que "200.000
   suscriptores." quepa en una línea ahí dentro, que es de donde parte el
   relevo. */
/* 115vh y no 100, igual que el hero: como está clavada, ese 15% de más no se
   ve nunca — lo que hace es dar margen de scroll antes de que la capa
   siguiente empiece a entrar. Los mismos 15vh van al relleno inferior para
   que el contenido siga centrado en la primera pantalla. */
/* Exactamente una pantalla y relleno simétrico, para que texto y retrato
   queden centrados de verdad. Antes la sección medía 115vh con un relleno
   inferior mayor para dejar margen antes del relevo, y eso descentraba: en
   ventanas bajas el contenido se centraba dentro de la sección, que era más
   alta que la pantalla, y en pantalla se veía subido y cortado por abajo.
   Ese margen se hace ahora empujando la capa siguiente, que no toca esta caja. */
.metricas{min-height:100vh;min-height:100svh;
  padding-block:clamp(6rem,16vh,10rem);
  display:grid;grid-template-columns:minmax(0,1.35fr) minmax(0,1fr);
  gap:clamp(2rem,4vw,4rem);align-items:center}
/* Aquí ya no hay relevo de capas: si suscriptores se quedara clavada, la capa
   siguiente taparía la frase "una única cosa" mucho antes de que el titular de
   invitados llegara, y el trazo que los une nacería de un punto ya cubierto.
   Scrolleando las dos juntas, la distancia entre frase y titular es fija y el
   recorrido del trazo se ve entero. La transición entre ambas la hace el
   propio trazo. */

/* .bigline de subframe-composiciones.html: número y palabra juntos, en
   blanco, misma línea — no es un dato que se destaque con color, es un
   titular más. Naranja fuera de esta línea.
   Debajo va la lectura buena de la cifra, al mismo tamaño: es la frase que
   corrige a la de arriba, no una nota al pie. */
.cifra{display:block}
/* Cada línea va entera, sin partir: medido de 800 a 1920px, "200.000
   suscriptores." y "decisores de negocio" caben siempre en su columna con
   margen (a 1440: 451 y 459px de 501). Solo por debajo de 360px se deja partir,
   que es donde ya no caben. */
.cifra__linea,.cifra__alt{display:block;white-space:nowrap}
@media (max-width:359px){.cifra__linea,.cifra__alt{white-space:normal}}
/* .cifra__linea también lleva el tamaño y el interlineado aunque no pinte
   texto propio: si no, su línea se mide con la letra por defecto del h2 y
   queda más alta que las otras dos. */
.cifra__linea,.cifra__n,.cifra__u,.cifra__alt{color:var(--text);font-weight:300;letter-spacing:-.025em;
  line-height:1.06;font-size:clamp(2.1rem,3.9vw,var(--fs-cifra))}
/* La frase de comunidad es una frase, no una segunda cifra: más pequeña que
   el número, puede partir en líneas y lleva su aire por arriba. */
.cifra__alt{white-space:normal;font-size:clamp(1.35rem,2.3vw,2rem);line-height:1.18;
  letter-spacing:-.02em;max-width:21ch;margin-top:clamp(.6rem,1.2vw,1rem);text-wrap:balance}
.cifra__n{font-variant-numeric:tabular-nums;font-feature-settings:"tnum";
  margin-right:clamp(.4rem,1.2vw,.85rem)}
/* El tachado es una línea fina que se dibuja de izquierda a derecha, a la
   altura del centro de las minúsculas. La palabra se apaga un poco al quedar
   tachada, para que la vista salte a la frase de abajo.
   Sin animaciones de scroll (o con movimiento reducido) se ve directamente el
   estado final: tachado puesto y frase de abajo visible, que es el mensaje. */
/* vertical-align:top para que la caja inline-block no alargue la primera
   línea: con la alineación a la base por defecto la línea de la cifra salía
   más alta que las otras dos y la separación no era la misma. */
/* "suscriptores." ya no se tacha ni se apaga (cambio de copy del 06/10): va
   en blanco como la cifra. La línea del tachado queda desactivada. */
.cifra__u{position:relative;display:inline-block;vertical-align:top;color:var(--text)}
.cifra__u::after{display:none;content:"";position:absolute;left:-.04em;right:-.04em;top:54%;
  height:max(1px,.028em);background:var(--text);
  transform-origin:left center}

/* El tachado va por TIEMPO, no ligado al scroll: colgado del scroll, al
   bajar rápido la línea cruzaba la palabra de golpe por mucho que se alargara
   el tramo. Ahora base.js pone .is-tachada cuando la cifra llega a media
   pantalla y la línea tarda 1,8s en cruzar, bajes como bajes; al subir por
   encima se quita y se puede volver a ver.
   Sin JS (sin .js-tacha en <html>) o con movimiento reducido se ve
   directamente el estado final: tachado puesto y frase de abajo visible. */
@media (prefers-reduced-motion:no-preference){
  .js-tacha .cifra__u{color:var(--text);transition:color 1.8s var(--ease)}
  .js-tacha .cifra__u::after{transform:scaleX(0);
    transition:transform 1.8s cubic-bezier(.65,0,.35,1)}
  .js-tacha .cifra__alt{opacity:0;transform:translateY(.35em);filter:blur(8px);
    transition:opacity .9s var(--ease),transform .9s var(--ease-out),filter .9s var(--ease)}
  .js-tacha .cifra.is-tachada .cifra__u{color:var(--text)}
  .js-tacha .cifra.is-tachada .cifra__u::after{transform:scaleX(1)}
  /* La frase nueva espera a que la línea esté casi acabada. */
  .js-tacha .cifra.is-tachada .cifra__alt{opacity:1;transform:none;filter:none;transition-delay:.35s}
}

.metricas__pie{margin-top:clamp(1.2rem,2.4vw,1.85rem);
  color:var(--text-2);font-weight:300;line-height:1.55;
  font-size:clamp(1rem,1.4vw,1.1rem);max-width:46ch}
.metricas__pie p+p{margin-top:1.15rem}

/* Retrato dentro de caja con esquinas redondeadas, como el resto de imágenes
   del sitio. En blanco y negro, coge color al pasar el cursor — las tres a la
   vez, porque son un solo conjunto.
   El margen inferior es lo que sube el retrato: la rejilla centra
   verticalmente, así que sobrar por abajo equivale a subir. */
/* La caja recorta (overflow) y la foto sube 25px: se pierden 25px por arriba
   y el resto del encuadre queda igual. En móvil el recorte es de 20px. */
.luis{position:relative;margin-bottom:clamp(1.5rem,4vh,3.5rem);overflow:hidden;border-radius:var(--r)}
.luis img{filter:grayscale(1) brightness(1.15) contrast(1.06);transition:filter .55s var(--ease)}
.luis:hover img{filter:grayscale(0) brightness(1.1) contrast(1)}
/* El recorte va hecho en el propio archivo (800x960, misma proporción que la
   caja), centrado sobre el conjunto placa + Luis. Así el navegador no recorta
   nada por su cuenta y el encuadre es el que se decidió, no el que salga. */
.luis__main{display:block;width:100%;height:auto;aspect-ratio:1/1.2;object-fit:cover;
  border-radius:var(--r);margin-top:-25px}
/* Viñeteado suave: el centro queda limpio y solo se oscurecen los bordes y
   las esquinas. Va encima de la foto como capa aparte, con el mismo radio, y
   deja pasar el cursor para que el color al pasar por encima siga
   funcionando. Centrado un poco por encima de la mitad, que es donde está la
   cara. */
.luis::after{content:"";position:absolute;inset:0;border-radius:var(--r);pointer-events:none;
  background:radial-gradient(ellipse 66% 62% at 50% 42%,transparent 30%,rgba(0,0,0,.88) 100%)}

/* "una única cosa" va en negrita y sin subrayado: de ella nace el trazo que
   baja hasta el titular siguiente, porque esa única cosa es justo ese titular. */
/* Sin negrita (cambio de copy del 06/10): ya solo marca de dónde nace el hilo. */
.unica{white-space:nowrap}
/* El hilo va fijo y por encima de las capas (pero por debajo de la barra):
   une dos puntos que están en capas distintas y que se mueven una respecto de
   la otra, así que no puede vivir dentro de ninguna de las dos. */
.hilo{position:fixed;inset:0;width:100%;height:100%;z-index:40;
  pointer-events:none;overflow:visible}
.hilo path{fill:none;stroke:var(--text-2);stroke-width:1;stroke-linecap:round;
  opacity:.6}

/* ---------- 10. MURO DE MINIATURAS -------------------------- */
/* Muro a sangre: se sale de los márgenes de .wrap con un margen negativo
   (el truco 50% - 50vw) y lo corta el overflow-x del body, así que ocupa el
   ancho de pantalla sin provocar scroll horizontal.
   Siete columnas en perspectiva que suben solas. Cada columna lleva sus 5
   miniaturas dos veces y se desplaza justo un juego, así que el bucle no
   tiene salto: por los huecos, el recorrido es -50% menos medio hueco.
   Las columnas van a distinta velocidad y con distinto desfase de salida,
   que es lo que impide que el muro se lea como una rejilla. */
/* Sin separación con el párrafo: el muro arranca pegado a él. El aire que se
   ve no es margen, es el fundido de la máscara del propio muro. */
.bleed{margin-top:0;margin-inline:calc(50% - 50vw)}
/* El muro se corta por los cuatro lados a propósito: en perspectiva, cortarlo
   es lo que da sensación de que sigue. La máscara lo funde por arriba y por
   abajo para que no aparezca de golpe. */
/* --tile y --wgap mandan sobre la geometría: el recorrido de la animación se
   calcula a partir de ellos, así que basta cambiarlos en el responsive.
   Alto pensado para que se vean 3 filas, con las de arriba y abajo asomando
   a medias para que el muro no parezca que empieza y acaba. */
.wall{--wgap:1.1rem;
  height:clamp(19rem,34vw,29rem);overflow:hidden;
  perspective:1400px;perspective-origin:50% 50%;
  -webkit-mask-image:linear-gradient(to bottom,transparent,#000 13%,#000 87%,transparent);
  mask-image:linear-gradient(to bottom,transparent,#000 13%,#000 87%,transparent)}
/* align-items:flex-start es obligatorio: con el stretch por defecto la columna
   mide lo que el escenario (no lo que su contenido) y el recorrido en % del
   keyframe salía corto, que es lo que hacía saltar el bucle. */
/* El translateX no es decorativo: el rotateY acerca el lado derecho y aleja el
   izquierdo, así que la proyección empuja todo a la derecha. Sin compensar,
   el muro nacía pegado al margen izquierdo y se salía 500px por el derecho.
   Con -10% sobresale por los dos lados y el recorte se lee parejo. Los valores
   están medidos sobre las baldosas que caen DENTRO de la franja visible: las
   de filas muy bajas llegan más a la izquierda por la perspectiva y engañan. */
.wall__stage{display:flex;gap:var(--wgap);height:100%;transform-style:preserve-3d;
  justify-content:center;align-items:flex-start;transform-origin:center center;
  transform:rotateX(16deg) rotateY(-14deg) translateZ(-120px) scale(1.14) translateX(-10%)}
/* Cada columna lleva 3 juegos de miniaturas y arranca subida justo un juego
   (--set), de modo que siempre hay contenido por encima y por debajo del
   recorte: sin eso, al reiniciar el ciclo se abría un hueco por arriba y el
   bucle se notaba. --off es solo el desfase estético entre columnas. */
.wall__col{--set:calc(5 * (var(--tile) * 0.5625 + var(--wgap)));--off:0rem;
  display:flex;flex-direction:column;gap:var(--wgap);flex:none;
  margin-top:calc(var(--off) - var(--set));
  animation:wall-drift 26s linear infinite;will-change:transform}
.wall__col:nth-child(2){animation-duration:34s;--off:-4rem}
.wall__col:nth-child(3){animation-duration:29s;--off:-2rem}
.wall__col:nth-child(4){animation-duration:37s;--off:-6rem}
.wall__col:nth-child(5){animation-duration:27s;--off:-1rem}
.wall__col:nth-child(6){animation-duration:32s;--off:-5rem}
.wall__col:nth-child(7){animation-duration:24s;--off:-3rem}
/* Al pasar el cursor se para la columna entera: si no, la miniatura que has
   elegido se te escapa por arriba justo cuando se enciende.
   Quien pone is-lit/is-paused es base.js, que busca la miniatura más cercana
   al cursor y perdona los huecos entre filas; el :hover queda de respaldo
   para cuando el script no llega a correr (sin js-wall en el <html>). */
.wall__col.is-paused,
html:not(.js-wall) .wall__col:hover{animation-play-state:paused}
/* Blanco y negro y apagadas; solo se enciende, a color y con un borde naranja
   muy tenue, la que tiene el cursor encima. */
.wall__col img{display:block;width:var(--tile);height:auto;aspect-ratio:16/9;object-fit:cover;
  border-radius:10px;border:1px solid var(--border);
  filter:grayscale(1) brightness(.62);opacity:.78;
  transition:filter .2s var(--ease),opacity .2s var(--ease),
             border-color .2s var(--ease),box-shadow .2s var(--ease)}
.wall__col img.is-lit,
html:not(.js-wall) .wall__col img:hover{filter:grayscale(0) brightness(1);opacity:1;
  border-color:rgba(255,102,51,.65);
  box-shadow:0 0 0 1px rgba(255,102,51,.3),0 0 20px rgba(255,102,51,.28)}
/* El recorrido es exactamente un juego de miniaturas (--set), así que al
   terminar la columna queda calcada de como empezó. En medidas absolutas y
   no en %, porque el % se mide sobre la caja de la columna, que con el
   estirado del flex no coincide con la altura de su contenido. */
@keyframes wall-drift{to{transform:translateY(calc(-1 * var(--set)))}}

/* ---------- 11. INVITADOS ----------------------------------- */
/* Mucho aire por arriba a propósito: es el trecho en negro por el que baja el
   hilo que viene de la sección anterior. Sin él, el recorrido dura un suspiro. */
/* El trecho en negro sobre el titular lo marca el trazo, no el gusto: con más
   de 8vh, frase y titular se separan tanto que cuando el trazo los une la
   frase ya se ha ido por arriba, y el momento que tiene sentido ver —los dos
   extremos unidos— no llega a verse nunca. */
/* El +26vh es la separación con suscriptores, y es lo que marca lo largo que
   es el recorrido del trazo. Medido: con esto el salto queda en ~0,83
   pantallas, que es lo máximo que admite sin que la frase de origen se vaya
   por arriba antes de que el trazo llegue al titular. */
#invitados{padding-top:calc(clamp(3rem,min(11vw,16vh),9rem) + 26vh)}
/* Estructura y escala de .statement en prueba/subframe-composiciones.html
   (titular enorme partido en líneas cortas a mano, párrafo centrado debajo),
   pero con el contraste al revés que en el archivo: allí el titular va
   apagado al 15% y aquí va en blanco y de trazo fino, y es el párrafo el que
   se retira — más fino, algo menor y en gris. */
.statement{text-align:center}
/* El titular ya no lleva saltos puestos a mano: se reparte solo en líneas
   parejas dentro de un ancho que lo deja en tres. */
.statement h2{font-weight:300;letter-spacing:-.03em;line-height:1.03;
  font-size:clamp(2.4rem,7vw,var(--fs-statement));color:var(--text);
  max-width:15ch;margin-inline:auto;text-wrap:balance}
.statement p{color:var(--text-mut);font-weight:300;font-size:clamp(1rem,1.5vw,1.15rem);
  line-height:1.45;max-width:32rem;margin:1.75rem auto 0}

/* ---------- 12. EPISODIOS ----------------------------------- */
/* Miniatura a la izquierda con el play encima y, a la derecha, título,
   entradilla recortada a dos líneas y la fila de accesos. */
/* Buen trecho entre el último episodio y propuestas, para que la lista
   termine del todo antes de que asome el bloque siguiente. */
.eps{margin-top:clamp(2.5rem,5vw,4rem);display:flex;flex-direction:column;
  gap:clamp(2.25rem,4vw,3.5rem)}
.ep{display:grid;grid-template-columns:minmax(0,var(--col-ep)) minmax(0,1fr);
  gap:clamp(1.25rem,3vw,2.5rem);align-items:start}
.ep__thumb{position:relative;display:block;aspect-ratio:16/9;overflow:hidden;
  border-radius:var(--r);background:var(--surface);border:1px solid var(--border)}
.ep__thumb img{display:block;width:100%;height:100%;object-fit:cover;
  transition:transform .5s var(--ease)}
.ep__thumb:hover img{transform:scale(1.04)}
.ep__play{position:absolute;inset:0;margin:auto;width:54px;height:54px;
  border-radius:50%;background:var(--accent);display:grid;place-items:center;
  transition:transform .3s var(--ease)}
.ep__play svg{width:22px;height:22px;fill:#0A0A0A}
.ep__thumb:hover .ep__play{transform:scale(1.08)}
.ep__t{font-weight:400;letter-spacing:-.02em;line-height:1.22;
  font-size:clamp(1.1rem,1.85vw,1.45rem)}
.ep__t a{color:var(--text);transition:color .3s var(--ease)}
.ep__t a:hover{color:var(--accent)}
/* Entradilla recortada a dos líneas: con textos de distinta largura, las
   filas se descuadrarían unas respecto de otras. */
.ep__d{color:var(--text-mut);font-weight:300;font-size:.95rem;line-height:1.55;
  margin-top:.7rem;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
  overflow:hidden}
.ep__foot{display:flex;align-items:center;justify-content:space-between;
  gap:1rem 1.5rem;flex-wrap:wrap;margin-top:1.15rem}
.ep__cta{display:inline-flex;align-items:center;gap:.5rem;
  color:var(--accent);font-weight:500;font-size:.95rem;letter-spacing:-.01em}
.ep__cta svg{width:19px;height:19px;fill:none;stroke:currentColor;stroke-width:1.7;
  stroke-linecap:round;stroke-linejoin:round;transition:transform .3s var(--ease)}
.ep__cta:hover svg{transform:translateX(4px)}
.ep__plats{display:flex;gap:.55rem}
.ep__plat{width:32px;height:32px;border-radius:50%;flex:none;
  background:var(--surface);border:1px solid var(--border);color:var(--text-mut);
  display:grid;place-items:center;
  transition:color .3s var(--ease),border-color .3s var(--ease)}
.ep__plat svg{width:15px;height:15px;fill:currentColor}
.ep__plat:hover{color:var(--text);border-color:var(--accent)}

/* ---------- 12. PROPUESTAS ---------------------------------- */
/* Las dos tarjetas van iguales: son pares en significado, jerarquizar
   por ancho o por botón comunicaría algo falso.
   Sin borde y con radio grande, al estilo de las cajas de precios de la
   referencia: la caja se separa del fondo por su propia superficie, que a
   negro puro se ve de sobra. El aire hace el trabajo que hacía el borde. */
/* Como métricas: clavada, 115vh para tener margen de scroll antes de que el
   cierre empiece a entrar, y ese 15% de más devuelto al relleno inferior para
   que el contenido siga centrado en la primera pantalla. */
/* Exactamente una pantalla y relleno simétrico: así el contenido queda
   centrado de verdad al clavarse. El truco anterior —alargar la sección y
   compensar con un relleno inferior enorme— encogía la caja de contenido y en
   ventanas bajas el titular se desbordaba por arriba y se cortaba.
   "safe" en el centrado es el seguro para ese caso: si el contenido no cabe,
   se pega arriba en vez de salirse por encima del borde. */
/* Ya no ocupa una pantalla entera: al centrarse en 100vh dejaba un hueco
   distinto arriba y abajo según el alto de la ventana y rompía la separación
   uniforme entre secciones. */
/* Propuestas scrollea normal y se marcha sin efecto: el cierre entra por su
   cuenta con la entrada de .news, que ya es suficiente movimiento. */
.packs{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:clamp(1rem,1.8vw,1.5rem);margin-top:clamp(2.5rem,5vw,3.5rem)}
/* El borde va transparente en reposo y no visible: así al encenderse en
   naranja bajo el cursor no se mueve nada de sitio. */
.pack{background:var(--surface);border-radius:22px;
  border:1px solid transparent;
  padding:clamp(1.8rem,3vw,2.6rem) clamp(1.6rem,2.6vw,2.2rem);display:flex;flex-direction:column;
  transition:background-color .3s var(--ease),border-color .3s var(--ease)}
.pack:hover{background:#181818;border-color:var(--accent)}
/* El nombre es el ancla de la tarjeta, como el precio en la referencia:
   grande y de trazo fino, no un titulillo en negrita. */
.pack__name{color:var(--text);font-weight:300;letter-spacing:-.03em;line-height:1.05;
  font-size:clamp(1.6rem,2.6vw,2.15rem)}
.pack__desc{color:var(--text-2);font-weight:300;font-size:1rem;line-height:1.5;
  margin-top:1rem}
/* La nota va un escalón por debajo de la descripción: más pequeña y más
   apagada, para que no compita con ella ni con el botón. */
/* .8rem es el techo para que "Pero antes, te recomendamos..." siga en una
   sola línea. Para llegar a él el relleno lateral de la tarjeta baja a 2.2rem
   (arriba y abajo sigue igual). Medido a 1280, 1440, 1600 y 1920: a .82rem
   ya parte en dos a 1440 y 1600, aunque se recorte más el relleno. */
.pack__nota{color:var(--text-mut);font-weight:300;font-size:.8rem;line-height:1.5;
  margin-top:clamp(1.4rem,2.4vw,1.9rem);margin-bottom:clamp(1.75rem,3vw,2.5rem)}
/* El enlace va en el mismo gris que la nota: lo que lo señala como enlace es
   el subrayado, no el contraste. Al pasar el cursor sube a naranja. */
.pack__link{display:block;margin-top:.35rem;width:max-content;
  color:var(--text-mut);border-bottom:1px solid var(--border);padding-bottom:1px;
  transition:color .3s var(--ease),border-color .3s var(--ease)}
.pack__link:hover{color:var(--accent);border-bottom-color:var(--accent)}
/* Botón a todo el ancho y al fondo. El margin-top:auto lo pega abajo del todo
   y el margen inferior del párrafo pone el mínimo, así que las dos tarjetas
   alinean el botón aunque una tenga una línea más de texto. */
.pack__btn{display:block;text-align:center;margin-top:auto;padding:1rem 1.25rem;
  background:#1F1F1F;color:var(--text);border-radius:10px;
  font-weight:500;font-size:.98rem;letter-spacing:-.01em;
  transition:background-color .3s var(--ease)}
.pack__btn:hover{background:#292929}

/* ---------- 13. NEWSLETTER ---------------------------------- */
/* Menos aire por arriba que el resto de secciones: viene de propuestas, que
   ya ocupa pantalla entera, y con el relleno normal el cierre quedaba
   demasiado bajo. */
/* Sin caja: el cierre va directo sobre el negro, y quien hace de ancla
   visual es el disco, no un recuadro. */
/* --news-aire: el mismo hueco entre el disco y el titular que entre el
   titular y el formulario. */
.news{text-align:center;--news-aire:clamp(1.25rem,2.4vw,1.75rem)}
/* El disco gira siempre: es la marca "esto está sonando", no un indicador de
   scroll. El JPG ya viene recortado al disco (centrado y tangente), así que no
   lleva sombra ni fondo y gira sin bailar. */
@keyframes spin{to{transform:rotate(360deg)}}
.news__vinilo{display:block;width:clamp(6.5rem,11vw,9.5rem);height:auto;
  border-radius:50%;margin:0 auto var(--news-aire);
  animation:spin 14s linear infinite}
@media (prefers-reduced-motion:reduce){.news__vinilo{animation:none}}
/* El tamaño de entrada va en las propiedades scale/translate, no en
   transform: transform ya lo usa el giro. will-change solo mientras base.js
   lo está moviendo. */
.js-vinilo .news__vinilo{will-change:scale,translate}
/* Parada de la newsletter: el bloque se queda fijo (centrado, --news-top lo
   calcula base.js) mientras pasa el relleno de --news-pin que se añade al
   final de la sección. Ese relleno es solo recorrido de scroll: al soltarse,
   el bloque queda pegado al final y la separación con la sección siguiente
   sigue siendo la de siempre. */
.news-pin .news{position:sticky;top:var(--news-top)}
.news-pin #newsletter::after{content:"";display:block;height:var(--news-pin)}
/* Misma escala que .listen h2 de subframe-composiciones.html: es el cierre
   de la página, tiene que pesar tanto como el titular que la abre. */
.news__t{font-weight:300;letter-spacing:-.03em;line-height:1.05;
  font-size:clamp(2.6rem,6vw,4rem);color:var(--text);max-width:14ch;margin-inline:auto;
  text-wrap:balance}
.news__form{display:flex;align-items:stretch;justify-content:center;flex-wrap:wrap;
  gap:.75rem;max-width:27rem;margin:var(--news-aire) auto 0}
.news__input{flex:1;min-width:12rem;height:51px;background:var(--bg);
  border:1px solid var(--border);border-radius:999px;padding-inline:1.25rem;
  color:var(--text);font-family:var(--sans);font-size:1rem;text-align:left;
  transition:border-color .3s var(--ease)}
.news__input::placeholder{color:var(--text-mut)}
.news__input:hover,.news__input:focus{border-color:var(--accent)}
.news__input:focus{outline:none}
.news__note{color:var(--text-mut);font-weight:300;font-size:.88rem;margin-top:1.1rem}
/* Casilla de consentimiento: fila propia debajo del campo y el botón. */
.news__ok{flex:0 0 100%;display:flex;align-items:center;justify-content:center;gap:.6rem;
  min-height:44px;color:var(--text-2);font-weight:300;font-size:.9rem;text-align:left;cursor:pointer}
.news__ok input{flex:none;width:18px;height:18px;margin:0;accent-color:var(--accent);cursor:pointer}
.news__ok a,.news__legal a{color:inherit;text-decoration:underline;text-underline-offset:.2em;
  transition:color .3s var(--ease)}
.news__ok a:hover,.news__legal a:hover{color:var(--accent)}
/* Primera capa informativa: letra pequeña y apagada, pero legible. */
.news__legal{color:var(--text-mut);font-weight:300;font-size:.75rem;line-height:1.5;
  max-width:34rem;margin:1.25rem auto 0;text-wrap:pretty}

/* ---------- 13b. QUIÉN HAY DETRÁS --------------------------- */
/* .agent de subframe-composiciones.html con la marca: caja #141414, pill
   blanca con icono naranja y el texto fuera de la caja. Alineado a la
   izquierda a propósito: la newsletter de arriba va centrada y así el paso
   de una a otra se nota. El hover solo cambia el borde a naranja. */
.grupo__t{max-width:none}
.grupo .lead{margin-top:1.4rem}
.grupo__grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));
  gap:clamp(1rem,2vw,1.5rem);margin-top:clamp(2.5rem,5vw,4rem)}
.grupo__card{display:block;min-width:0}
/* Marco alto con el nombre dentro, grande y abajo a la izquierda. Sin
   icono: el único detalle de color es el borde naranja al pasar el cursor. */
.grupo__stage{position:relative;background:var(--surface);border:1px solid var(--border);border-radius:var(--r);
  aspect-ratio:4/5;display:flex;flex-direction:column;justify-content:flex-end;
  padding:clamp(1.1rem,1.8vw,1.5rem);transition:border-color .3s var(--ease)}
.grupo__card:hover .grupo__stage{border-color:var(--accent)}
/* Caja con foto de fondo (Seobox): en blanco y negro, recortada a la caja,
   con un velo oscuro que se cierra hacia abajo para que el nombre y la
   descripción se sigan leyendo. Es un scrim de legibilidad, no un adorno. */
.grupo__stage--foto{overflow:hidden}
.grupo__foto{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:42% 50%;
  filter:grayscale(1) contrast(1.05) brightness(.68)}
/* Investments: encuadre sobre la mesa y la pantalla, dejando fuera el cristal
   de la derecha, que lleva rotulada la marca de otra empresa. */
.grupo__foto--investors{object-position:38% 50%}
/* Agency: centrado en el videowall con el logo de la agencia y ampliado
   un 30% hacia él (la caja recorta lo que sobra). */
.grupo__foto--agency{object-position:51% 50%;transform:scale(1.3);transform-origin:50% 38%}
/* Academy: el aula, encuadrada sobre los alumnos con el mural de SEO detrás. */
.grupo__foto--academy{object-position:48% 50%}
/* Dos capas: el viñeteado (bordes y esquinas a negro, centro limpio, como
   en la foto de Luis) y, debajo, el velo que se cierra hacia abajo. */
.grupo__stage--foto::before{content:"";position:absolute;inset:0;z-index:1;
  background:
    radial-gradient(ellipse 75% 70% at 50% 42%,transparent 35%,rgba(0,0,0,.7) 100%),
    linear-gradient(to bottom,rgba(10,10,10,.3) 0%,rgba(10,10,10,.4) 40%,rgba(10,10,10,.9) 100%)}
.grupo__stage--foto .grupo__txt{position:relative;z-index:2}
.grupo__name{font-weight:300;letter-spacing:-.03em;line-height:1.02;color:var(--text);
  font-size:clamp(1.25rem,2.4vw,2.2rem)}
/* La descripción vive dentro de la caja, debajo del nombre. Donde hay
   cursor está plegada (fila de rejilla a 0fr) y se despliega al pasar por
   encima o al enfocar la caja con el teclado: el nombre sube y el texto
   aparece en su sitio. En móvil se ve siempre. El corte es por ancho y no
   por (hover:hover): esa consulta da false en portátiles táctiles y en los
   modos de emulación, y ahí la caja se quedaría sin plegar. */
.grupo__desc{display:grid;grid-template-rows:1fr;margin-top:.7rem;
  font-size:.95rem;font-weight:300;line-height:1.45;color:var(--text-2)}
.grupo__desc span{overflow:hidden;min-height:0}
@media (min-width:761px){
  .grupo__desc{grid-template-rows:0fr;margin-top:0;opacity:0;
    transition:grid-template-rows .45s var(--ease-out),margin-top .45s var(--ease-out),opacity .35s var(--ease)}
  .grupo__card:hover .grupo__desc,.grupo__card:focus-visible .grupo__desc{
    grid-template-rows:1fr;margin-top:.7rem;opacity:1}
}
/* Entrada fijada (la activa base.js poniendo .grupo-on en <html> a partir
   de 760px): la sección se queda pegada arriba durante el
   recorrido de .grupo-pin y el JS mueve la frase y destapa el resto. */
.grupo-on .grupo-pin{height:260vh}
.grupo-on .grupo{position:sticky;top:0;min-height:100vh;display:flex;flex-direction:column;
  justify-content:center;padding-block:90px 2rem;border-top:0}
/* El pie queda algo más cerca que una sección de otra: al 60% de --gap, que
   es un cierre y no un bloque más. Fijada, la sección solo deja 2rem por
   abajo (para caber en pantalla); lo que falta lo pone el pie. */
.grupo-on .foot{margin-top:calc(var(--gap) * .6 - 2rem)}
.grupo-on .grupo__t{transform-origin:0 0;will-change:transform,opacity}
/* Si con 4:5 el bloque no cabe en la ventana, base.js fija --marco-h para
   que quepa de un vistazo (cuadrado como mínimo). */
.grupo-on .grupo[style*="--marco-h"] .grupo__stage{aspect-ratio:auto;height:var(--marco-h)}
.grupo-on .grupo__resto,.grupo-on .grupo__card{will-change:transform,opacity}

/* ---------- 13c. VENTANAS --------------------------------- */
/* "Ver perfiles" y "Ver si mi marca encaja". Misma superficie que el resto
   (#141414, borde 1px, radio 14), sin sombras ni desenfoque: el fondo se
   oscurece con un velo liso. Los números de la lista son el único naranja.
   El contenido desplaza por dentro si no cabe; la página de detrás no. */
.ventana{margin:auto;padding:0;border:1px solid var(--border);border-radius:var(--r);
  background:var(--surface);color:var(--text);
  width:min(40rem,calc(100vw - 2 * var(--gutter)));max-height:calc(100dvh - 3rem);
  overflow-y:auto;overscroll-behavior:contain;
  scrollbar-width:thin;scrollbar-color:var(--border) transparent}
.ventana:focus{outline:none}
.ventana::backdrop{background:rgba(0,0,0,.78)}
.ventana[open]{animation:ventana-entra .35s var(--ease-out)}
.ventana[open]::backdrop{animation:ventana-velo .35s var(--ease)}
@keyframes ventana-entra{from{opacity:0;transform:translateY(1rem)}to{opacity:1;transform:none}}
@keyframes ventana-velo{from{opacity:0}to{opacity:1}}
html:has(.ventana[open]){overflow:hidden}
.ventana__in{position:relative;padding:clamp(1.6rem,4vw,2.6rem)}
.ventana__x{position:absolute;top:.9rem;right:.9rem;width:44px;height:44px;border-radius:50%;
  display:grid;place-items:center;color:var(--text-mut);transition:color .3s var(--ease)}
.ventana__x:hover{color:var(--text)}
.ventana__x svg{width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:1.5;stroke-linecap:round}
.ventana__k{display:block;color:var(--text-mut);font-weight:300;font-size:.95rem;margin-bottom:.6rem}
.ventana__t{font-weight:300;letter-spacing:-.03em;line-height:1.08;
  font-size:clamp(1.7rem,4vw,2.3rem);max-width:20ch;padding-right:2.5rem;text-wrap:balance}
.ventana__lead{color:var(--text-2);font-weight:300;font-size:1rem;line-height:1.5;margin-top:1.1rem}
.ventana__lista{list-style:none;counter-reset:n;margin-top:clamp(1.4rem,3vw,2rem);border-top:1px solid var(--border)}
.ventana__lista li{counter-increment:n;display:grid;grid-template-columns:2.2rem minmax(0,1fr);
  column-gap:.5rem;padding-block:.85rem;border-bottom:1px solid var(--border)}
.ventana__lista li::before{content:counter(n);grid-row:1 / span 2;color:var(--accent);
  font-weight:300;font-size:1.15rem;line-height:1.35;font-variant-numeric:tabular-nums}
.ventana__lista h3{font-weight:500;font-size:1.08rem;letter-spacing:-.01em;line-height:1.35}
.ventana__lista p{grid-column:2;color:var(--text-2);font-weight:300;font-size:.95rem;line-height:1.5;margin-top:.2rem}
.ventana__no{margin-block:1.2rem 1.5rem}
.ventana__no h3{color:var(--text-mut);font-weight:300;font-size:.95rem;margin-bottom:.5rem}
.ventana__no li{position:relative;padding-left:1.1rem;color:var(--text-2);font-weight:300;
  font-size:.95rem;line-height:1.5}
.ventana__no li+li{margin-top:.35rem}
.ventana__no li::before{content:"";position:absolute;left:0;top:.72em;width:.5rem;height:1px;background:var(--text-mut)}
@media (max-width:760px){
  .ventana{width:calc(100vw - 1.5rem);max-height:calc(100dvh - 1.5rem)}
  .ventana .pill{width:100%;justify-content:space-between}
}

/* ---------- 14. FOOTER -------------------------------------- */
.foot{padding-block:clamp(2.5rem,5vw,3.5rem) 2.5rem;border-top:1px solid var(--border);margin-top:calc(var(--gap) * .1)}
.foot__min{display:flex;align-items:center;justify-content:space-between;gap:1.25rem 2rem;flex-wrap:wrap}
.foot__copy{color:var(--text-mut);font-weight:300;font-size:.9rem}
.foot__plats{display:flex;flex-wrap:wrap;gap:clamp(1.25rem,3vw,2rem)}
.foot__plats a{color:var(--text-mut);font-weight:300;font-size:.9rem;transition:color .3s var(--ease)}
.foot__plats a:hover{color:var(--text)}

/* ---------- 14b. ENTRADAS POR BLOQUE ------------------------ */
/* Cada bloque entra de una manera distinta para que la página no se lea
   siempre igual al bajar. Todas van ligadas al scroll (no al tiempo), así que
   siguen al dedo y se pueden deshacer subiendo. Donde no haya animaciones de
   scroll, el contenido sale ya colocado.
   Los elementos que se animan aquí no llevan .reveal: una sola mecánica por
   elemento, o se pelean por el mismo transform. */
@supports (animation-timeline:view()){
  @media (prefers-reduced-motion:no-preference){
    /* La curva va DENTRO del atajo animation: declarada aparte antes, el
       propio atajo la reseteaba a "ease". Frena al final, que es lo que hace
       que la entrada se sienta suave en vez de mecánica. */
    /* Invitados: el titular se abre desde un poco más junto y sube. */
    .statement h2{animation:ent-titular var(--ease-out) both;
      animation-timeline:view();animation-range:entry 5% entry 95%}
    /* Episodios: cada fila entra por su lado, y como cada una tiene su propia
       línea de tiempo, se encadenan solas sin programar ningún retardo. */
    .ep{animation:ent-fila var(--ease-out) both;
      animation-timeline:view();animation-range:entry 0% entry 85%}
    /* Propuestas: las tarjetas crecen hasta su tamaño. */
    .pack{animation:ent-tarjeta var(--ease-out) both;
      animation-timeline:view();animation-range:entry 0% entry 95%}
    /* Newsletter: sube y aparece, sin escala ni desplazamiento lateral. */
    /* Newsletter: la entrada la lleva base.js (apartado 8), porque el
       vinilo crece y encoge y eso no se puede colgar de la misma animación
       que su giro. */
  }
}
@keyframes ent-titular{from{opacity:0;transform:translateY(1.6rem);letter-spacing:-.05em}
  to{opacity:1;transform:none;letter-spacing:-.03em}}
@keyframes ent-fila{from{opacity:0;transform:translateX(-2.5rem)}to{opacity:1;transform:none}}
@keyframes ent-tarjeta{from{opacity:0;transform:scale(.94)}to{opacity:1;transform:none}}
@keyframes ent-cierre{from{opacity:0;transform:translateY(2.5rem)}to{opacity:1;transform:none}}

/* ---------- 15. RESPONSIVE ---------------------------------- */
/* --- Monitores: la página crece con la pantalla en vez de quedarse en una
   tira centrada. Solo suben la columna de contenido y los topes de tamaño;
   proporciones, huecos y composición no cambian. --- */
@media (min-width:1600px){
  :root{--maxw:1320px;
    --fs-hero:8rem;--fs-statement:6rem;--fs-cifra:3.9rem;--fs-h2:4.3rem;
    --tile:14.5rem;--col-ep:21rem}
}
@media (min-width:1920px){
  :root{--maxw:1440px;
    --fs-hero:8.8rem;--fs-statement:6.6rem;--fs-cifra:4.3rem;--fs-h2:4.8rem;
    --tile:16.5rem;--col-ep:23rem}
}
/* Panorámicas (2560 y más): la columna se ensancha un poco más, pero el texto
   deja de crecer — una línea más ancha de ~90 caracteres ya cuesta de leer. */
@media (min-width:2400px){
  /* Baldosa mayor no por gusto: a este ancho el escenario se quedaba corto y,
     aun desplazado, dejaba hueco negro por la izquierda. */
  :root{--maxw:1560px;--tile:24rem;--col-ep:25rem}
}


/* Las tarjetas pasan a una columna ya en 1000px, no en 760: por debajo de ahí
   miden unos 310px y la nota de "Pero antes, te recomendamos..." deja de
   caber en una línea, que es como tiene que ir. A una columna sobra sitio. */
@media (max-width:1000px){
  .packs{grid-template-columns:minmax(0,1fr)}
}
@media (max-width:760px){
  body{font-size:16px}
  /* El retrato pasa debajo del texto y se queda a media anchura, centrado:
     a ancho completo se comía la pantalla. */
  .metricas{grid-template-columns:minmax(0,1fr)}
  /* La foto va entre la cifra y "5 Temporadas", no al final: el bloque de
     texto se deshace (display:contents) para que sus piezas y la foto sean
     hermanas en la misma rejilla y se puedan ordenar. Alineada a la
     izquierda, al mismo margen que el texto. */
  .metricas__texto{display:contents}
  .metricas{row-gap:0}
  .metricas .kicker{order:1}
  .cifra{order:2}
  .luis{order:3;width:78%;margin:clamp(1.75rem,6vw,2.5rem) 0 0;
    overflow:hidden;border-radius:var(--r)}
  /* 20px menos por arriba: la foto sube y la caja, que recorta, se queda
     con lo de abajo. */
  .luis__main{margin-top:-20px}
  .metricas__pie{order:4}
  /* El muro conserva la perspectiva pero con baldosas más pequeñas: a este
     ancho siguen entrando varias columnas, aunque se corten. */
  /* Una fila más que antes (cada fila son ~89px: miniatura de 76px + hueco). */
  .wall{--tile:8.5rem;--wgap:.8rem;
    height:clamp(21.5rem,92vw,28rem);perspective:900px}
  .wall__stage{transform:rotateX(14deg) rotateY(-10deg) translateZ(-90px) scale(1.06) translateX(-6%)}
  .foot__min{flex-direction:column;align-items:flex-start;gap:1.5rem}
  /* Sin burger: por debajo de este ancho los enlaces no caben junto a la
     marca, así que se ocultan en vez de amontonarse. */
  .nav__links{display:none}
}
@media (max-width:520px){
  .nav__in{gap:1rem}
}


/* ---------- 16. MÓVIL --------------------------------------- */
/* Adaptación de conjunto para teléfono (por debajo de 760px). Criterios:
   · Zonas táctiles de 44px como mínimo en todo lo que se pulsa.
   · Nada de texto por debajo de 14px.
   · Menos scroll muerto: las listas largas se compactan (episodios) o pasan
     a carrusel (grupo) en vez de apilarse a pantalla completa.
   · Sin hover: lo que en escritorio se descubre al pasar el cursor tiene que
     funcionar al tocar o no depender de ello. */
@media (max-width:760px){
  :root{--gutter:1.6rem;--gap:10.6rem}
  a,button{-webkit-tap-highlight-color:transparent}

  /* Barra: más baja, con el botón de menú a la derecha. */
  .nav__in{height:60px}
  .nav__menu{display:grid;place-content:center;gap:6px;width:44px;height:44px;margin-right:-10px}
  .nav__menu-l{display:block;width:22px;height:1.5px;background:var(--text);border-radius:2px;
    transition:transform .3s var(--ease)}
  .menu-open .nav__menu-l:first-child{transform:translateY(3.75px) rotate(45deg)}
  .menu-open .nav__menu-l:last-child{transform:translateY(-3.75px) rotate(-45deg)}
  /* Con el menú abierto la barra va opaca aunque esté sobre el hero. */
  .menu-open .nav{animation:none;background:var(--bg);border-bottom-color:var(--border)}
  .menu-open,.menu-open body{overflow:hidden}
  /* Capa sólida (nada de desenfoque), enlaces grandes y finos como los
     titulares, separados por la línea de 1px de siempre. */
  .menu:not([hidden]){display:flex;flex-direction:column;justify-content:space-between;
    position:fixed;inset:60px 0 0;z-index:99;background:var(--bg);
    padding-block:1rem 2rem;overflow-y:auto;animation:menu-entra .3s var(--ease-out)}
  .menu__in{display:flex;flex-direction:column}
  .menu__in a{display:block;padding:1rem 0;border-bottom:1px solid var(--border);
    color:var(--text);font-weight:300;font-size:1.9rem;letter-spacing:-.03em;line-height:1.1}
  .menu__in a:active{color:var(--accent)}
  .menu__pie a{display:inline-block;padding-block:.75rem;color:var(--text-mut);font-weight:300;font-size:.95rem}

  /* Tipografía de sección un escalón más contenida: en 375px el kicker a
     1.35rem competía con el titular. */
  .kicker{font-size:1.1rem;margin-bottom:1rem}

  /* Hero: el titular llena el ancho, que es lo que le da presencia en un
     teléfono. Las plataformas del desplegable, con altura táctil. */
  .hero__h1{font-size:clamp(2.8rem,14.2vw,4.2rem)}
  .listen__item{min-height:44px;padding-inline:.9rem}

  /* Episodios: fila compacta. Miniatura pequeña a la izquierda y, al lado,
     título y plataformas. Sin entradilla ni "Ver episodio": la miniatura y
     el título ya llevan al episodio, y así la lista pasa de casi 1.900px a
     algo que se recorre de un vistazo. */
  .eps{gap:1.5rem;margin-top:2rem}
  /* El texto no puede ser más alto que la miniatura (salía hasta 114px
     frente a 77px): miniatura algo mayor, título a dos líneas como máximo y
     fila de iconos de 32px. Título + iconos = ~78px, dentro de los 86px de
     la imagen. */
  .ep{grid-template-columns:9.5rem minmax(0,1fr);gap:.9rem;align-items:center}
  .ep__thumb{border-radius:10px}
  .ep__play{width:32px;height:32px}
  .ep__play svg{width:13px;height:13px}
  .ep__t{font-size:.95rem;line-height:1.28;display:-webkit-box;-webkit-line-clamp:2;
    -webkit-box-orient:vertical;overflow:hidden}
  .ep__d,.ep__cta{display:none}
  .ep__foot{margin-top:.35rem}
  .ep__plats{gap:.35rem;margin-left:-8px}
  /* Se ven de 32px, pero la zona que se puede tocar sigue siendo de 44px:
     la amplía un pseudoelemento transparente sin ocupar sitio en la fila. */
  .ep__plat{position:relative;width:32px;height:32px;background:none;border:0}
  .ep__plat::after{content:"";position:absolute;inset:-6px}
  .ep__plat svg{width:17px;height:17px}

  /* Propuestas: los saltos puestos a mano son para el ancho de escritorio;
     aquí partían las frases en trozos desiguales. */
  .pack{border-radius:18px}
  .pack__desc br{display:none}
  .pack__nota{font-size:.875rem}
  .pack__link{padding-block:.5rem .1rem}

  /* Newsletter: campo y botón a todo el ancho, uno encima del otro. El campo
     se quedaba en 21px de alto: con flex:1 en columna la base es 0. */
  .news__form{flex-direction:column;align-items:stretch;max-width:none}
  .news__input{flex:none;width:100%;height:52px;min-width:0}
  .news .pill{justify-content:space-between}
  .news__ok{justify-content:flex-start}
  .news__legal{font-size:.8rem;text-align:left}

  /* Grupo: las cuatro una debajo de otra, sin carrusel, y apaisadas en vez
     de 2:3 para que la lista no se haga eterna. */
  .grupo__grid{grid-template-columns:minmax(0,1fr);gap:1rem;margin-top:2rem}
  /* Altura mínima y no proporción fija: la descripción va dentro y siempre
     visible, así que la caja tiene que poder crecer si el texto lo pide. */
  .grupo__stage{aspect-ratio:auto;min-height:11.5rem}
  /* Nombre más contenido y en una sola línea: a 2rem y en dos líneas se
     comía media caja. */
  .grupo__name{font-size:1.4rem}
  .grupo__name br{display:none}

  /* Pie: los enlaces eran de 23px de alto. En dos columnas y con relleno
     llegan a la altura táctil; el © pasa al final, como cierre. */
  .foot__min{gap:1.25rem}
  .foot__plats{display:grid;grid-template-columns:1fr 1fr;gap:0 1.5rem;width:100%}
  .foot__plats a{padding-block:.7rem;font-size:.95rem}
  .foot__plats a[href^="mailto"]{grid-column:1/-1}
  .foot__copy{order:2;font-size:.875rem}
}
@keyframes menu-entra{from{opacity:0;transform:translateY(-.5rem)}to{opacity:1;transform:none}}
