/* ══════════════════════════════════════════════════════════════════
   TUBOX · bloque de resultados
   El caso no tiene galería: su contenido fuerte son los números,
   así que la métrica ocupa el lugar que en la plantilla tenía el video.
   ══════════════════════════════════════════════════════════════════ */
/* ── FICHA SOBRE LA PORTADA ───────────────────────────────────────
   Va dentro del hero pero fuera de .scale_w y de .media_c: esos dos
   se escalan y hacen parallax, y la ficha tiene que quedarse quieta. */
.hero{position:relative}
.hero_ficha{
  position:absolute;left:0;bottom:0;z-index:3;width:100%;
  display:grid;grid-template-columns:repeat(3,auto);justify-content:start;
  gap:0 56px;padding:22px 40px;
  color:var(--color-light);mix-blend-mode:difference;
  font-size:var(--fontXS);font-weight:500;letter-spacing:.08em;text-transform:uppercase;
}
.hero_ficha div{display:flex;flex-direction:column;gap:5px}
.hero_ficha dt{opacity:.6}
.hero_ficha dd{margin:0;font-size:var(--fontS);letter-spacing:.04em}

/* ── DATOS · las cifras repartidas a lo largo del scroll ──────────
   Aparecen entre las piezas, chicas, sin fondo propio: aportan
   mientras se leen los textos y se ven las imágenes. ── */
/* ── COMPARATIVO · mismo lenguaje que la ficha del pie ────────────
   Filete de un pelo por fila, divisor entre columnas y rótulo en gris:
   son las mismas reglas de .credits_row, con una columna más. */
/* bloque con max-width y margen automático, no flex + min(): sobre un
   item flex el porcentaje no se resolvía contra el contenedor y el
   ancho colapsaba al max-content del grid (722px en vez de 1000) */
.comparativo{width:100%;padding:9vh 40px 12vh}
/* 580px, el mismo ancho que la ficha del pie */
.comp_c{width:100%;max-width:580px;margin-inline:auto}
.comp_fila{
  display:grid;grid-template-columns:min(180px,33%) 1fr 1fr;gap:0;
  font-family:var(--sans);font-size:var(--fontS);font-weight:500;line-height:150%;
  /* toda la tabla en caja alta. El cuarto de espacio es la corrección
     de siempre para versalita: sin él las palabras largas se apelmazan */
  text-transform:uppercase;letter-spacing:.04em;
  border-top:1px solid #06040320;
}
.comp_fila>*{padding:11px 14px}
.comp_fila>:first-child{padding-left:0}
.comp_fila h4{color:#6d6f68;border-right:1px solid #06040320}
.comp_fila>:nth-child(2){border-right:1px solid #06040320;color:#8b8d85}

/* encabezado: sin filete arriba y con los rótulos en versalita. No cambia
   de cuerpo — lo único que lo separa de las filas es la caja alta. */
.comp_head{
  border-top:0;
  letter-spacing:.10em;text-transform:uppercase;
}
.comp_head h4{color:var(--color-dark)}
.comp_head>:nth-child(3){color:var(--color-dark)}

/* Toda la tabla en una sola cara y un solo cuerpo. La jerarquía la
   llevan el gris del rótulo, el gris de la columna "antes" y el filete
   de la fila de cierre — no el tamaño ni un color de realce. */
.comp_fila>:nth-child(2),
.comp_fila>:nth-child(3){
  font-variant-numeric:tabular-nums;
}
.comp_head>:nth-child(2),
.comp_head>:nth-child(3){
  letter-spacing:.10em;
}
/* la fila de cierre carga el peso: es la comparación que da sentido al resto */
.comp_cierre{
  border-top:1px solid #06040347;border-bottom:1px solid #06040347;
  background-color:#0604030a;
}
.comp_cierre h4{color:var(--color-dark)}
/* Todo el peso de la fila de cierre está en su filete y su fondo. El
   selector va cargado porque .comp_fila>:nth-child(3) tiene más
   especificidad que .comp_acento a secas. */
.comp_fila.comp_cierre>.comp_acento{
  color:var(--color-dark);font-weight:500;
}

/* OJO — las celdas .comp_ref siguen llevando datos de REFERENCIA, no
   reales. La marca visual está apagada a pedido, para previsualizar sin
   ruido. Para volver a verlas, descomentar el bloque de abajo.
   Se encuentran con:  grep -n "comp_ref\|data-pendiente" tubox.html
.comp_ref{
  color:#8b8d85;
  text-decoration:underline dotted #C9142B;
  text-underline-offset:5px;
  cursor:help;
}
*/

@media (max-width:768px){
  .comparativo{padding:7vh 20px 9vh}
  /* tres columnas no entran en 375px: cada fila pasa a ser un bloque con
     el rótulo arriba y las dos columnas debajo, una al lado de la otra */
  .comp_fila{grid-template-columns:1fr 1fr}
  .comp_fila h4{
    grid-column:1 / -1;border-right:0;padding:12px 0 4px;
    letter-spacing:.08em;text-transform:uppercase;
  }
  .comp_fila>:nth-child(2){padding-left:0}
  .comp_fila>*{padding:0 12px 13px}
  .comp_head{display:none}
}




/* ── marquesina infinita ─────────────────────────────────────────── */
.marquesina{overflow:hidden;width:100%;padding:22px 0;
  border-block:1px solid #06040320}
.marquesina_pista{display:flex;gap:40px;width:max-content;will-change:transform}
.marquesina span{
  font-size:var(--fontS);font-weight:500;letter-spacing:.14em;
  text-transform:uppercase;white-space:nowrap;color:#6d6f68;
}
.marquesina.oscura{background-color:var(--color-dark);border-block-color:#ffffff1f}
.marquesina.oscura span{color:#8b8d85}

@media(max-width:900px){
  .hero_ficha{grid-template-columns:1fr;gap:8px;padding:16px 20px}
  .hero_ficha div{flex-direction:row;align-items:baseline;gap:10px}
  .hero_ficha dt{min-width:64px}
  .marquesina{padding:16px 0}
}

/* ── bloques de texto numerados ─────────────────────────────────── */
/* mucho aire arriba y abajo: el texto necesita recorrido para
   atravesar la zona de foco y que el efecto se lea */
/* Sin el efecto de lectura estas secciones están quietas, así que se
   dimensionan por su contenido: un 100svh con 26vh de padding era aire
   muerto que sólo se sostenía mientras el texto entraba fundiéndose. */
/* ── ETAPAS · panel de pestañas ────────────────────────────────────
   Ya no se avanza con el scroll: el panel ocupa una pantalla, queda
   centrado con aire arriba y abajo, y las pestañas pasan solas. El
   marco con filete lo vuelve un instrumento y no un tramo de página.

   El scroll se sacó a propósito: atarlo obligaba a scrollear para leer
   y la lectura quedaba a merced de la rueda. Con temporizador, el
   contenido se lee quieto. ── */
.etapas{
  display:grid;place-items:center;
  width:100%;height:100svh;padding:0 40px;
}
.etapas_marco{
  display:grid;grid-template-columns:300px 1fr;
  width:min(100%,1000px);height:calc(100svh - 176px);
  border:1px solid #06040326;
}
.etapas_menu{
  display:flex;flex-direction:column;
  padding:26px 0 26px 26px;
  border-right:1px solid #06040326;
}
.etapas_lista{display:flex;flex-direction:column;list-style:none;padding-right:26px}
/* El gris de las inactivas era #b9bbb4 sobre #e9eae4: una relación de
   contraste de 1,6:1. No es un gris tenue, es un texto que no se ve —
   sólo se leían la activa y el epígrafe de la ficha, y la navegación
   parecía tener dos entradas en vez de seis. #5a5c55 da 5,6:1, que se
   lee sin dejar de estar en segundo plano respecto de la activa. */
.etapas_lista button{
  position:relative;
  display:grid;grid-template-columns:auto 1fr;align-items:baseline;gap:12px;
  width:100%;padding:13px 0;cursor:pointer;text-align:left;
  border-top:1px solid transparent;
  color:#5a5c55;
  transition:color .25s var(--ease);
}
.etapas_lista li + li button{border-top-color:#0604031a}
.etapas_lista button:hover,
.etapas_lista button:focus-visible{color:var(--color-dark)}
/* el número de la activa pasa a la cara del display: junto con la barra
   de abajo son las dos señales de "estás acá" */
.etapas_lista button[aria-current]{color:var(--color-dark)}
.etapas_lista button[aria-current] .etapa_n{font-weight:500}

/* La ficha de números no es el paso siguiente del relato: es el saldo.
   Por eso baja al pie de la columna, detrás de un filete y sin número
   — numerarla la haría parecer la continuación de la secuencia, que es
   justo lo que no es. La sangría hacia la izquierda remata la idea. */
.etapas_aparte{margin-top:auto;padding-top:20px;border-top:1px solid #06040326}
.etapas_corte{
  margin:0 0 3px;
  font-family:var(--sans);font-size:var(--fontXXS);font-weight:400;
  letter-spacing:.14em;text-transform:uppercase;color:#8b8d85;
}
.etapas_lista_datos{padding-right:26px}
.etapas_lista_datos button{grid-template-columns:1fr;border-top:0}

/* La barra que se llena es el indicador: dice cuál está activa y, sobre
   todo, que el turno se está agotando. Sin eso el cambio sorprende. */
/* La pista gris aparece sólo bajo la activa: sin ella la barra crecía
   desde la nada y no se leía como un tiempo que se agota, sino como un
   subrayado creciendo por gusto. */
.etapas_lista button::before{
  content:'';position:absolute;left:0;bottom:-1px;height:2px;width:100%;
  background-color:#06040317;
  opacity:0;transition:opacity .25s var(--ease);
}
.etapas_lista button[aria-current]::before{opacity:1}
.etapas_lista button::after{
  content:'';position:absolute;left:0;bottom:-1px;height:2px;width:100%;
  background-color:var(--color-dark);
  transform:scaleX(0);transform-origin:left;
}
.etapas_lista button[aria-current]::after{
  transform:scaleX(var(--avance,0));
}

/* declaración propia: le gana al color y al text-shadow que la animación
   del neón computa en el botón y que si no heredaría */
.etapa_n{
  font-family:var(--display);font-size:13px;line-height:1;
  font-variant-numeric:tabular-nums;letter-spacing:.02em;
  color:var(--color-dark);text-shadow:none;
}
.etapa_rot{
  font-size:var(--fontS);font-weight:500;letter-spacing:.11em;line-height:130%;
  text-transform:uppercase;
}

/* grid en vez de position:absolute: apila las etapas en la misma celda
   y aun así la caja toma el alto de la más alta */
/* position:relative es lo que ancla el seguidor del puntero: sin esto
   se posicionaba contra un ancestro lejano y el GIF terminaba flotando
   sobre la portada. El overflow además lo recorta a la caja, que es lo
   que hace que la reacción viva sólo donde están los párrafos. */
.etapas_caja{position:relative;display:grid;overflow:hidden}
.etapas_caja > .etapa{grid-area:1/1;align-self:center}

.etapa{
  display:flex;flex-direction:column;
  padding:34px;overflow-y:auto;max-height:100%;
  opacity:0;transform:translateY(38px);
  pointer-events:none;
  transition:opacity .5s var(--ease),transform .62s var(--ease);
}
.etapa.activa{opacity:1;transform:none;pointer-events:auto}

.etapa.saliendo{opacity:0;transform:translateY(-40px)}
/* el gif encabeza la etapa: el aire va abajo, no arriba */
.etapa .reaccion{margin-top:0;margin-bottom:34px}
/* ── EL ÁNIMO DE LA ETAPA ──────────────────────────────────────────
   Cada etapa nombra el estado de ánimo del momento —la bronca, la
   desconfianza, la rosca— antes de contarlo. Sirve para dos cosas: le
   da al relato un arco en vez de una lista de tareas, y deja explícito
   qué tiene que transmitir el GIF de esa etapa. Va en mono, chico y en
   el gris de las etiquetas: es un rótulo, no un título. */
/* El selector va cargado a propósito: .etapa p:not(.entrada) tiene
   (0,2,1) y le ganaba a .etapa_animo a secas, así que el rótulo salía
   en 17px gris como si fuera un párrafo más. */
article.etapa p.etapa_animo{
  margin:0 0 12px;
  font-family:var(--sans);font-size:10px;font-weight:400;
  letter-spacing:.2em;text-transform:uppercase;color:#8b8d85;
  text-align:left;
}
/* respiro entre el título y el cuerpo */
.etapa .entrada{margin-bottom:16px}
.etapa p{
  font-family:var(--texto);font-size:19px;font-weight:500;line-height:166%;
  /* tope de ancho atado al tamaño: sobre los 700px de la columna, sin
     esto quedaban ~80 caracteres por renglón, largo para leer de corrido */
  max-width:600px;
  text-align:justify;hyphens:auto;
}
/* sin bold: la jerarquía la lleva sólo el tamaño */
.etapa .entrada{font-size:24px;font-weight:500;line-height:144%;text-align:left}
/* El cuerpo va dos puntos por debajo, en redonda y en gris: la entrada
   es la que tiene que frenar el ojo, y el resto acompaña. Sin esto los
   dos pesaban igual y la pestaña se leía como un bloque parejo.
   Alcanza también al tercer párrafo donde lo hay — la entrada abre y
   todo lo que sigue es el mismo cuerpo de texto. */
.etapa p:not(.entrada){font-size:17px;font-weight:400;color:#4a4c46}
.etapa strong{font-weight:600}

@media(max-width:900px){
  /* En táctil el marco deja de ser una sola pantalla: las pestañas se
     apilan arriba en una tira y el panel toma el alto que necesite. Un
     alto fijo con texto de tres párrafos obliga a scrollear adentro de
     una caja adentro de la página, que se siente atrapado. */
  .etapas{height:auto;padding:9vh 20px}
  .etapas_marco{grid-template-columns:1fr;height:auto;min-height:74svh}
  .etapas_menu{
    padding:16px 16px 0;
    border-right:0;border-bottom:1px solid #06040326;
  }
  .etapas_lista{
    flex-direction:row;overflow-x:auto;gap:0 20px;padding:0 0 2px;
    scrollbar-width:none;
  }
  .etapas_lista::-webkit-scrollbar{display:none}
  .etapas_lista button{
    width:auto;flex:0 0 auto;padding:10px 0 12px;border-top:0;
  }
  .etapas_lista li + li button{border-top-color:transparent}
  /* con la lista en horizontal la separación no puede ser un filete
     arriba: pasa a ser un tabique a la izquierda, al final de la tira.
     Queda fija mientras 01, 02… se deslizan, así que la ficha está
     siempre a mano y siempre visiblemente aparte. */
  /* min-width:0 en los dos: un item de grid arranca en min-width:auto y
     se pasa de su pista, así que sin esto la tira no se desplaza — se
     desborda, y con seis pestañas se iba a 629px sobre 375 de pantalla */
  .etapas_menu{flex-direction:row;align-items:stretch;gap:0;min-width:0}
  .etapas_lista{min-width:0;flex:1 1 auto}
  .etapas_lista .etapa_rot,.etapas_lista .etapa_n{white-space:nowrap}
  .etapas_aparte{
    display:flex;align-items:center;flex:0 0 auto;
    margin-top:0;padding:0 0 0 16px;
    border-top:0;border-left:1px solid #06040326;
  }
  .etapas_corte{display:none}
  .etapas_lista_datos{padding-right:0}
  .etapa{padding:22px 16px 26px;max-height:none;overflow:visible}
}

@media(max-width:900px){
  .metricas{padding:72px 20px;gap:30px}
  .metricas_grid{grid-template-columns:1fr}
  .metrica{padding:20px 0 0}
  .metrica_principal .cifra{font-size:clamp(56px,17vw,110px)}
  .etapa p{font-size:17px;max-width:none}
  .etapa .entrada{font-size:21px}
  .ficha_corta{grid-template-columns:1fr 1fr;gap:16px;padding:20px}
}
.banda .lazy_wrapper{width:min(100%,1180px);margin-inline:auto;aspect-ratio:3000/992}
@media(max-width:768px){.banda{padding:12px 0}}

/* ── GALERÍA · una pieza por vez ──────────────────────────────────
   Arriba el archivo y las acciones; abajo la navegación, más grande
   porque es lo que se usa. El escenario va oscuro para que la pieza
   se despegue del fondo claro de la página. ── */
.galeria{padding:0}
.gal{width:100%}

/* La barra se pega al tope mientras la galería ocupa la pantalla. No
   puede ganarle al header por z-index: vive dentro de .inner, que tiene
   z-index:1 y crea contexto de apilamiento, así que el 14 del header
   siempre pintaría encima. En vez de pelear, el header se corre — el JS
   lo retrae mientras la barra manda y lo devuelve al pasar la galería. */
.gal_barra{
  position:sticky;top:0;z-index:12;
  display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:stretch;
  background-color:var(--color-light);
  border-top:1px solid #06040326;border-bottom:1px solid #06040326;
}
.gal_celda{
  display:flex;align-items:center;gap:10px;padding:12px 20px;
  font-size:12px;font-weight:500;letter-spacing:.10em;
  text-transform:uppercase;white-space:nowrap;
}
.gal_alt{overflow:hidden;text-overflow:ellipsis;color:#6d6f68;min-width:0}

/* Acciones: son interfaz, así que llevan etiqueta además del ícono.
   Sin aspect-ratio — con texto adentro el botón se ensancha y esa regla
   le forzaba la misma altura, dejándolo enorme (97x97).
   Sin stretch heredaría el align-items:center de .gal_celda. */
.gal_acciones{padding:0;gap:0;justify-content:flex-end;align-items:stretch}
.gal_acciones button{
  display:flex;align-items:center;gap:9px;
  padding:0 20px;cursor:pointer;
  font-size:12px;font-weight:500;letter-spacing:.08em;text-transform:uppercase;
  border-left:1px solid #06040326;
  transition:background-color .18s ease-out,color .18s ease-out;
}
.gal_acciones button svg{flex:0 0 auto}
.gal_acciones button:hover{background-color:#060403;color:#eeeeee}
.gal_aviso{
  display:flex;align-items:center;padding-right:16px;
  font-size:var(--fontXXS);letter-spacing:.08em;text-transform:uppercase;
  color:#6d6f68;opacity:0;transition:opacity .25s var(--ease);
}
.gal_aviso.visible{opacity:1}

.gal_escena{
  position:relative;height:min(68svh,720px);overflow:hidden;
  background-color:#dedede;
}
.gal_pieza{
  position:absolute;inset:0;opacity:0;pointer-events:none;
  transition:opacity .45s var(--ease);
}
.gal_pieza.activa{opacity:1;pointer-events:auto}
.gal_pieza .lazy_wrapper{
  width:100%;height:100%;aspect-ratio:auto;padding:34px;
  display:flex;align-items:center;justify-content:center;cursor:zoom-in;
}
.gal_pieza img{width:auto;height:auto;max-width:100%;max-height:100%;object-fit:contain}
.gal_pieza .placeholder{background-color:transparent}

.gal_progreso{height:1px;background-color:#06040320;overflow:hidden}
.gal_progreso i{
  display:block;height:100%;width:100%;background-color:var(--color-dark);
  transform:scaleX(0);transform-origin:left center;
}

/* pie: la navegación centrada, no estirada a los bordes */
.gal_pie{
  display:flex;flex-direction:column;align-items:center;gap:16px;
  padding:26px 20px 34px;
}
.gal_nav{
  display:flex;align-items:stretch;
  border:1px solid #06040326;
}
.gal_nav button{
  padding:15px 26px;cursor:pointer;
  font-size:13px;font-weight:500;letter-spacing:.08em;text-transform:uppercase;
  transition:background-color .18s ease-out,color .18s ease-out;
}
.gal_nav button:hover{background-color:#060403;color:#eeeeee}
.gal_idx{
  display:flex;align-items:center;gap:7px;padding:15px 26px;
  font-size:20px;font-weight:500;font-variant-numeric:tabular-nums;
  border-inline:1px solid #06040326;
}
.gal_idx em{font-style:normal;color:#8b8d85;font-size:15px}

/* indicador de posición: un segmento por pieza */
.gal_puntos{display:flex;gap:6px}
.gal_puntos button{
  width:26px;height:3px;cursor:pointer;
  background-color:#06040326;transition:background-color .25s var(--ease);
}
.gal_puntos button:hover{background-color:#06040359}
.gal_puntos button[aria-current]{background-color:var(--color-dark)}

/* ── PORTADAS DE REELS · carrusel horizontal ──────────────────────
   La sección se fija mientras el riel se desplaza en X; cuando la
   última portada termina de pasar, el scroll vertical sigue solo.
   En táctil no se fija nada: es un scroll horizontal nativo, que es
   el gesto que la gente ya espera en un teléfono.
   ── */
/* El alto de la sección lo pone el JS: ventana + recorrido horizontal.
   Se usa position:sticky y NO el pin de ScrollTrigger, porque el pin del
   footer deja un transform en #work_wrapper y eso vuelve al contenedor
   bloque de referencia de cualquier descendiente fixed: el pin anidado
   terminaba dibujándose fuera de pantalla. */
/* Gris claro y no negro: sobre negro cada pieza quedaba recortada
   flotando, y las capturas de app —que son casi todas blancas— se
   veían como agujeros. El gris sale de mezclar el claro del sitio con
   el oscuro, así que pertenece a la paleta y no es un gris cualquiera. */
.reels{
  position:relative;width:100%;
  background-color:#dcddd6;color:var(--color-dark);
}
.reels_sticky{
  position:sticky;top:0;height:100svh;overflow:hidden;
  display:flex;align-items:center;
}
.reels_inner{display:flex;flex-direction:column;gap:28px;width:100%}
.reels_title{
  padding:0 40px;
  font-size:var(--fontXS);font-weight:500;letter-spacing:.14em;text-transform:uppercase;
  /* el gris de antes era para fondo negro: sobre el claro daba 2,46:1 */
  color:#5a5c55;
}
.reels_pista{
  display:flex;align-items:center;gap:20px;
  padding:0 40px;width:max-content;will-change:transform;
}
/* las portadas son 9:16: se dimensionan por altura, no por ancho.
   Así llenan la sección y el riel gana recorrido para desplazarse. */
.reel{flex:0 0 auto}
.reel .lazy_wrapper{height:min(70svh,660px);width:auto;aspect-ratio:var(--ar,9/16)}
.reel img,.reel video{width:100%;height:100%;object-fit:cover;display:block}
/* mismo radio en las tres galerías del sitio: las portadas de reel, las
   capturas de la app y las piezas de video. El recorte lo hace el
   .lazy_wrapper, que es el que tiene overflow:hidden */
.reel .lazy_wrapper{border-radius:15px}

@media(max-width:900px){
  .reels{height:auto!important;padding:64px 0}
  .reels_sticky{position:static;height:auto;overflow:visible}
  .reels_pista{
    width:auto;overflow-x:auto;padding:0 20px 8px;
    scroll-snap-type:x mandatory;-webkit-overflow-scrolling:touch;
  }
  .reels_pista::-webkit-scrollbar{height:0}
  .reel{scroll-snap-align:center}
  .reel .lazy_wrapper{height:auto;width:62vw}
  .reels_title{padding:0 20px}
}

/* ── puntos del riel de reels (los inyecta el JS en táctil) ─────── */
.reels_puntos{
  display:flex;justify-content:center;gap:7px;
  padding:20px 20px 0;
}
.reels_puntos button{
  width:24px;height:3px;cursor:pointer;
  /* claro translúcido servía sobre negro; sobre el gris desaparecía */
  background-color:#0604032e;
  transition:background-color .3s var(--ease);
}
.reels_puntos button[aria-current]{background-color:var(--color-dark)}

/* ── EL SITIO · portada primero, sitio real recién al pedirlo ─────
   Cargar un sitio entero en un iframe cuesta una página de red completa;
   hasta que no hacen clic se muestra sólo la portada. El iframe se sirve
   a 1512px —el mismo ancho con el que está diseñada la portada— y se
   escala, así las proporciones coinciden y no salta al cargar. ── */
.sitio{
  display:flex;flex-direction:column;
  width:100%;padding:120px 0;
}
.sitio_barra{
  display:grid;grid-template-columns:1fr auto;align-items:stretch;
  width:min(100%,1180px);margin-inline:auto;
  border:1px solid #06040326;border-bottom:0;
}
.sitio_url{
  display:flex;align-items:center;padding:12px 20px;
  font-size:12px;font-weight:500;letter-spacing:.09em;
  text-transform:uppercase;color:#6d6f68;
}
/* mismo botón cuadrado que las redes del header y las acciones de galería */
.sitio_abrir{
  display:grid;place-items:center;
  height:100%;aspect-ratio:1;width:auto;
  border-left:1px solid #06040326;
  transition:background-color .18s ease-out,color .18s ease-out;
}
.sitio_abrir:hover{background-color:#060403;color:#eeeeee}

.sitio_visor{
  position:relative;overflow:hidden;
  width:min(100%,1180px);margin-inline:auto;
  aspect-ratio:1512/982;
  border:1px solid #06040326;background-color:#111;
}
.sitio_visor iframe{
  position:absolute;top:0;left:0;width:1512px;height:945px;border:0;
  transform:scale(var(--k,.5));transform-origin:0 0;
  pointer-events:none;                 /* inerte hasta que se active */
}
.sitio_visor.activo iframe{pointer-events:auto}

/* portada y botón comparten celda: así el botón queda centrado encima
   de la imagen sin depender de una posición estática */
.sitio_previa{
  position:absolute;inset:0;z-index:2;display:grid;
  background-color:#1a1b19;
}
.sitio_previa > *{grid-area:1/1}
.sitio_previa img{width:100%;height:100%;object-fit:cover;display:block}
.sitio_entrar{
  place-self:center;
  display:flex;align-items:center;gap:12px;
  padding:17px 30px;cursor:pointer;
  border-radius:999px;
  background-color:var(--color-light);color:var(--color-dark);
  box-shadow:0 16px 44px #06040340;
  font-size:var(--fontS);font-weight:600;letter-spacing:.09em;text-transform:uppercase;
  transition:transform .28s var(--ease),background-color .2s ease-out;
}
.sitio_entrar::after{content:'↗';font-size:15px;line-height:1}
.sitio_entrar:hover{transform:scale(1.045);background-color:#fff}
.sitio_visor.cargado .sitio_previa{opacity:0;pointer-events:none;transition:opacity .5s var(--ease)}

/* una vez cargado, la capa devuelve el scroll a la página */
.sitio_capa{
  position:absolute;inset:0;z-index:3;display:none;
  align-items:center;justify-content:center;
  background-color:#06040338;cursor:pointer;
}
.sitio_visor.cargado:not(.activo) .sitio_capa{display:flex}
.sitio_capa span{
  padding:12px 20px;background-color:var(--color-light);color:var(--color-dark);
  font-size:var(--fontXS);font-weight:500;letter-spacing:.10em;text-transform:uppercase;
}
.sitio_aviso{
  position:absolute;left:0;bottom:0;z-index:4;padding:8px 12px;
  background-color:var(--color-dark);color:var(--color-light);
  font-size:var(--fontXXS);font-weight:500;letter-spacing:.08em;text-transform:uppercase;
  opacity:0;transition:opacity .3s;pointer-events:none;
}
.sitio_visor.activo .sitio_aviso{opacity:1}

@media(max-width:768px){
  /* sin gap: la barra tiene que quedar pegada al visualizador */
  .sitio{padding:70px 0;gap:0}
  .sitio_barra,.sitio_visor{width:auto;margin-inline:20px}
  /* en táctil el iframe compite con el gesto de scroll: sólo el enlace */
  .sitio_entrar{padding:14px 22px;font-size:var(--fontXS)}
}

/* ── REACCIONES · sólo el GIF, en una píldora angosta ─────────────
   Sin texto: la reacción la da la imagen, no una leyenda. ── */
/* Sin contenedor: el GIF es la reacción. Cada uno con su proporción y
   ancho propios — uno es apaisado y el otro casi 4:3, forzarlos al mismo
   recuadro los deformaría. */
/* Cuadrado, derecho y con las esquinas redondeadas. Sin hover: la
   reacción es un guiño, no un control — invitar a pasarle el mouse
   prometía algo que después no pasaba. */
.reaccion{
  position:relative;z-index:2;
  display:block;width:var(--w,96px);aspect-ratio:1;
  margin-top:20px;overflow:hidden;
  border-radius:12px;
  background-color:transparent;
}

/* ── LA REACCIÓN COMO CURSOR ───────────────────────────────────────
   En escritorio el GIF deja de ocupar un lugar fijo y pasa a seguir al
   puntero, pero SÓLO dentro de la caja de los párrafos: ahí la reacción
   acompaña lo que se está leyendo en ese momento, y afuera no molesta.
   El recorte lo hace el overflow:hidden que .etapas_caja ya tenía.

   Lo único que se anima es transform, escrito una vez por cuadro desde
   un rAF que corre nada más mientras el puntero está adentro. Los
   pointermove no escriben estilos: sólo guardan la última posición. */
.reaccion_cursor{
  position:absolute;top:0;left:0;z-index:6;
  width:var(--rc,168px);aspect-ratio:1;
  overflow:hidden;border-radius:14px;
  pointer-events:none;
  opacity:0;
  transform:translate3d(-999px,-999px,0);
  transition:opacity .28s var(--ease);
  will-change:transform;
}
.reaccion_cursor.visible{opacity:1}
.reaccion_cursor.sin_gif{opacity:0 !important}
.reaccion_cursor img{
  width:100%;height:100%;object-fit:cover;display:block;
}
/* En táctil el JS inserta la reacción dentro de la etapa y le da una
   sola vuelta; después la reemplaza por un canvas con el cuadro en el
   que quedó, que hereda la misma caja. */
.etapa .reaccion_quieta{
  display:block;width:var(--w,96px);aspect-ratio:1;
  margin:0 0 34px;object-fit:cover;
  border-radius:12px;
}
.etapa .reaccion{margin:0 0 34px}
.etapa .reaccion img{
  position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;display:block;
}
/* Un iframe no acepta object-fit, así que el recorte cuadrado va a mano:
   se lo lleva al alto de la caja, se le da el ancho que pide su propia
   proporción (--arn) y se lo centra. Lo que sobra lo corta el overflow. */
.reaccion iframe,.reaccion img{
  position:absolute;top:0;left:50%;
  height:100%;width:calc(100% * var(--arn,1));
  transform:translateX(-50%);
  display:block;border:0;pointer-events:none;
}
.reaccion img{object-fit:cover}

.reaccion.vacia .reaccion_media{
  display:flex;align-items:center;justify-content:center;
  background-color:transparent;border:1px dashed #06040340;
}
.reaccion.vacia .reaccion_media::after{
  content:'GIF';font-family:var(--sans);font-size:var(--fontXXS);
  letter-spacing:.14em;color:#8b8d85;
}
.reaccion.vacia .reaccion_media img{display:none}

@media(max-width:768px){
  .reaccion{width:min(var(--w,96px),30vw)}
}


/* ── VISOR AMPLIADO · la pieza de galería a pantalla completa ─────
   Este bloque faltaba entero, así que [data-gal-ampliar] agregaba la
   clase a un div sin estilos y no pasaba nada visible. ── */
.visor{
  position:fixed;inset:0;z-index:50;
  display:flex;align-items:center;justify-content:center;
  padding:60px 40px 76px;
  background-color:#060403f5;
  opacity:0;visibility:hidden;pointer-events:none;
  transition:opacity .34s var(--ease),visibility .34s var(--ease);
}
.visor.abierto{opacity:1;visibility:visible;pointer-events:auto}
/* el reset pone img{width:100%}: sin width:auto la imagen se deforma */
.visor img{
  width:auto;height:auto;max-width:100%;max-height:100%;
  object-fit:contain;display:block;
  transform:scale(.97);transition:transform .42s var(--ease);
}
.visor.abierto img{transform:none}
.visor_pie{
  position:absolute;left:0;bottom:0;width:100%;
  display:grid;grid-template-columns:auto 1fr auto;align-items:center;gap:24px;
  padding:15px 24px;
  border-top:1px solid #ffffff1f;
  color:#b9bbb4;font-size:var(--fontXS);font-weight:500;
  letter-spacing:.09em;text-transform:uppercase;
}
.visor_pie [data-visor-n]{color:var(--color-light);font-variant-numeric:tabular-nums}
.visor_pie [data-visor-t]{color:#8b8d85;text-transform:none;letter-spacing:.02em}
.visor_pie span:last-child{color:#6d6f68}
@media (max-width:768px){
  /* En táctil la galería va a sangre: los instrumentos se tocan entre sí
     y llegan a los dos bordes, sin aire alrededor. */
  .gal_escena{height:auto;aspect-ratio:4/5}
  .gal_pieza .lazy_wrapper{padding:0}

  .gal_barra{grid-template-columns:minmax(0,1fr) auto}
  .gal_celda{padding:11px 14px;gap:8px}
  .gal_alt{font-size:var(--fontXXS)}
  .gal_acciones button span{display:none}
  .gal_acciones button{padding:0 15px}

  /* el pie pierde su marco y la navegación se estira de borde a borde */
  .gal_pie{padding:0;gap:0}
  .gal_nav{width:100%;border-inline:0;border-bottom:0}
  .gal_nav button{flex:1;padding:15px 0}
  .gal_idx{flex:0 0 auto;padding:15px 18px}
  .gal_puntos{padding:15px 0 20px}

  .visor{padding:40px 16px 64px}
  .visor_pie{grid-template-columns:1fr;gap:4px;padding:12px 16px}
  .visor_pie [data-visor-t]{display:none}
}


/* ── VIBE · reproductor de la portada ─────────────────────────────
   Mismo cuadrado instrumental del header. La pista es opcional: si el
   archivo no está, el botón queda inerte y lo dice, en vez de fallar
   en silencio al hacer clic. ── */
.hero_vibe{
  position:absolute;right:20px;bottom:22px;z-index:4;
  display:flex;align-items:stretch;
  border:1px solid #e9eae43d;
  /* sin backdrop-filter: acá está sobre la portada, que hace parallax,
     así que el fondo cambia y se volvía a desenfocar en cada cuadro del
     scroll. Un negro plano más opaco se lee igual sobre una foto. */
  background-color:#060403ad;
  color:var(--color-light);
}
.vibe_btn{
  display:grid;place-items:center;
  aspect-ratio:1;width:auto;padding:0 13px;cursor:pointer;
  border-right:1px solid #e9eae43d;
  transition:background-color .18s ease-out,color .18s ease-out;
}
.vibe_btn:hover{background-color:#eeeeee;color:#060403}
.vibe_pause{display:none}
.hero_vibe.sonando .vibe_play{display:none}
.hero_vibe.sonando .vibe_pause{display:block}
.hero_vibe.sin_pista .vibe_btn{cursor:not-allowed;opacity:.45}
.vibe_txt{
  display:flex;flex-direction:column;justify-content:center;gap:2px;
  padding:9px 14px;
}
.vibe_rotulo{
  font-size:var(--fontXXS);font-weight:600;letter-spacing:.13em;text-transform:uppercase;
}
.vibe_estado{
  font-size:var(--fontXXS);font-weight:500;letter-spacing:.08em;
  text-transform:uppercase;color:#e9eae499;
}
/* las ondas sólo se mueven mientras suena */
.vibe_ondas{
  display:flex;align-items:center;gap:3px;padding:0 14px 0 0;
}
.vibe_ondas i{
  width:2px;height:7px;background-color:#e9eae466;
  transition:background-color .3s;
}
.hero_vibe.sonando .vibe_ondas i{
  background-color:var(--color-light);
  animation:vibe_onda .9s ease-in-out infinite;
}
.hero_vibe.sonando .vibe_ondas i:nth-child(2){animation-delay:.15s}
.hero_vibe.sonando .vibe_ondas i:nth-child(3){animation-delay:.3s}
.hero_vibe.sonando .vibe_ondas i:nth-child(4){animation-delay:.45s}
@keyframes vibe_onda{0%,100%{height:5px}50%{height:15px}}
@media (max-width:900px){.hero_vibe{display:none}}
@media (prefers-reduced-motion:reduce){
  .hero_vibe.sonando .vibe_ondas i{animation:none;height:11px}
}
