/* ═══════════════════════════════════════════════════════════════════════════
   UTOPIA × SYMBIOTIKKA · ONE NACHT STAND · 08 September · Playa Soleil Ibiza
   Negro, rojo y oro. Tipografía de cartel. Nada más.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Las fuentes ─────────────────────────────────────────────────────────────
   Tres archivos, 54 KB en total, todos con `font-display:swap` para que el
   texto se lea desde el primer frame con la de sistema.

   · Power Grotesk  (25 KB) — TODO el texto de la web. Sólo hay Regular, así
     que en ningún sitio se le pide un bold: donde antes había `font-weight:700`
     sobre la de sistema, ahora manda el tamaño y el letter-spacing.
   · Dirtyline      (12 KB) — NO es la fuente de los títulos. Es la letra
     decorativa: se usa de una en una, dentro de un título por lo demás en la
     grotesca negra, igual que la O, la C y la S del cartel.
     Ver `.dl` más abajo.
   · Avant Garde    (16 KB) — sólo la firma del pie.
   ---------------------------------------------------------------------------- */
@font-face{
  font-family:"Power Grotesk";
  src:url("fonts/powergrotesk-regular.woff2") format("woff2");
  font-weight:400;font-style:normal;font-display:swap;
}
@font-face{
  font-family:"Dirtyline";
  src:url("fonts/dirtyline.woff2") format("woff2");
  font-weight:400;font-style:normal;font-display:swap;
  /* Dirtyline no trae ¿ ¡ · – — ni comillas tipográficas. Al limitar el rango
     a letras y números, el navegador va solo a la siguiente de la pila para
     todo lo demás en vez de pintar un tofu. */
  unicode-range:U+0030-0039,U+0041-005A,U+0061-007A,U+00C0-00FF;
}
@font-face{
  font-family:"Avant Garde Gothic";
  src:url("fonts/avantgarde-bold.woff2") format("woff2");
  font-weight:700;font-style:normal;font-display:swap;
}

:root{
  --red:#e30613;
  --gold:#c99e67;
  --ink:#000000;
  --ink2:#070707;
  --ink3:#0e0e0e;
  --line:rgba(255,255,255,.13);
  --line2:rgba(255,255,255,.07);
  --bone:#efece7;
  --dim:#8d8a86;

  /* Los títulos siguen en la grotesca negra condensada: es la que aguanta el
     peso de cartel y la que hace que la letra decorativa destaque. */
  --display:"HelveticaNeue-CondensedBlack","Helvetica Neue","Arial Black",
            Haettenschweiler,Impact,"Arial Narrow",Arial,sans-serif;
  /* El texto corrido y las etiquetas pequeñas, en Power Grotesk. */
  --text:"Power Grotesk",-apple-system,BlinkMacSystemFont,"Helvetica Neue",
         Helvetica,Arial,sans-serif;
  /* `--mono` ya no es monoespaciada: es la misma Power Grotesk. Se conserva el
     nombre porque lo usan ~40 reglas y son las etiquetas en versal espaciada.
     Las cifras van tabulares para que la cuenta atrás y el reloj no bailen. */
  --mono:"Power Grotesk",-apple-system,BlinkMacSystemFont,"Helvetica Neue",
         Helvetica,Arial,sans-serif;
  --fancy:"Dirtyline",var(--display);
  --brand:"Avant Garde Gothic","Century Gothic",Futura,"Avenir Next",Avenir,
          var(--text);

  /* ── La escalera tipográfica ───────────────────────────────────────────
     Seis pasos y no dieciocho. Antes había 18 cuerpos fijos distintos, que no
     es una escala: es el rastro de haber ido ajustando cosas de una en una.
     El salto entre pasos es de ~1,12, suficiente para que dos niveles seguidos
     se distingan sin que el de abajo se vuelva ilegible.

     Los cuerpos grandes NO están aquí: los titulares van en `clamp()` porque
     tienen que responder al ancho, y cada uno tiene su propio término en vw. */
  --t-micro:10.5px;   /* etiquetas mínimas: numeración, pies de foto */
  --t-xs:12px;        /* etiquetas en versal espaciada */
  --t-s:13px;         /* etiquetas largas, menú, precios */
  --t-m:14px;         /* texto secundario */
  --t-base:15.5px;    /* texto corrido que no es `.lead` */
  --t-l:17.5px;       /* texto de lectura larga */

  /* ── La escalera de tracking ──────────────────────────────────────────
     Tres negativos para los titulares (a cuerpo grande la letra pide cerrarse)
     y siete positivos para la versal espaciada. Eran 26 valores sueltos. */
  --ls-t3:-.03em;     /* titulares de cartel */
  --ls-t2:-.02em;
  --ls-t1:-.01em;
  --ls-1:.02em;       /* versal apenas separada */
  --ls-2:.06em;
  --ls-3:.1em;
  --ls-4:.14em;
  --ls-5:.18em;
  --ls-6:.24em;
  --ls-7:.32em;       /* la más abierta: kickers del pie */

  --pad:clamp(18px,5vw,64px);
  --maxw:1240px;
}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}

body{
  font-synthesis-weight:none;
  font-synthesis-style:none;
  margin:0;
  background:var(--ink);
  color:var(--bone);
  font-family:var(--text);
  font-size:var(--t-l);
  line-height:1.62;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}

/* ── La letra decorativa ─────────────────────────────────────────────────────
   El recurso del cartel: un título en la grotesca negra con UNA letra en
   Dirtyline. No se pone a mano — lo hace `dirty()` en app.js, que envuelve en
   `<i class="dl">` la primera aparición de la letra que se le diga.

   Dirtyline tiene una caja mucho más alta y estrecha que la grotesca, así que
   necesita compensación óptica: se agranda, se sube y se le da aire a los
   lados. Sin esto se lee como una errata, no como un guiño.
   ---------------------------------------------------------------------------- */
.dl{
  font-family:var(--fancy);
  font-style:normal;
  font-weight:400;
  font-stretch:normal;          /* Dirtyline no tiene condensada: que no la finja */
  font-size:1.22em;
  line-height:0;                /* no estira la línea del título */
  letter-spacing:0;
  /* Dirtyline lleva remates que se salen de la caja por los dos lados: sin
     este margen la letra se toca con la siguiente y parece una errata.
     A tamaño de cartel sobra la mitad —ver `.ht-in .dl` y `.h2-big .dl`,
     que lo bajan a .02em—: ahí la decorativa va a 1.02em y su remate se sale
     mucho menos que cuando va suelta a 1.22em. */
  margin:0 .1em 0 .03em;
  display:inline-block;
  transform:translateY(.055em);
  color:var(--red);
}
/* Al principio de línea el margen izquierdo sangraría esa línea contra las que
   abren en la grotesca. La clase la pone `dirty()`, no se escribe a mano. */
.dl-lead{margin-left:0}

/* El color de la decorativa tiene una sola regla: sobre fondo rojo o dentro de
   un texto ya rojo, se distingue por FORMA y hereda el color; en cualquier otro
   sitio va en rojo (arriba). Estos dos casos estaban en dos reglas separadas y
   dos más aparecían junto al título y a `.h2-big`, cada una repitiendo lo
   mismo; ahora son una. El título de la portada NO entra aquí: tiene sus
   propias reglas de color, en el bloque rojo del final. Ver `.ht-in .dl`. */
.btn-red .dl, .kicker.red .dl, .h3.red .dl, .on .dl,
.h2.red .dl, .claim .dl, .h2-big .dl{color:currentColor}

/* A tamaño de cartel la decorativa NO se agranda. El 1.22em de arriba compensa
   que Dirtyline tiene la caja más alta y estrecha que la grotesca, y vale para
   una letra suelta en una línea; en un bloque de tres líneas pegadas mete los
   rasgos en la línea vecina. Por lo mismo el margen baja de .1em a .02em. */
.h2-big .dl{font-size:1.02em;margin:0 .02em}
/* …y ese margen abreviado gana por especificidad a `.dl-lead`, así que la que
   abre línea necesita repetirlo aquí o volvería a sangrar su línea. */
.h2-big .dl-lead{margin-left:0}

@media (prefers-reduced-motion:no-preference){
  .dl{transition:color .25s ease}
}

/* Cifras tabulares donde bailan: cuenta atrás, reloj y precios. */
.count b,.moments b,.tlist .pr,.ebclock b{
  font-variant-numeric:tabular-nums;
  font-feature-settings:"tnum" 1;
}

[hidden]{display:none!important}
img{max-width:100%;display:block}
a{color:inherit;text-decoration:none}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
::selection{background:var(--red);color:#fff}

.sr{position:absolute!important;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.skip{position:absolute;left:-9999px;top:0;z-index:200;background:var(--red);color:#fff;padding:12px 18px}
.skip:focus{left:0}
:focus-visible{outline:2px solid var(--red);outline-offset:3px}

/* ─── grano de película ─────────────────────────────────────────────────── */
.grain{
  position:fixed;inset:-50%;z-index:900;pointer-events:none;opacity:.05;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)'/%3E%3C/svg%3E");
  animation:grain 1.1s steps(3) infinite;
  will-change:transform;
}
@keyframes grain{
  0%{transform:translate(0,0)}33%{transform:translate(-3%,2%)}66%{transform:translate(2%,-3%)}100%{transform:translate(0,0)}
}
@media (prefers-reduced-motion:reduce){.grain{animation:none}}

/* ─── layout ────────────────────────────────────────────────────────────── */
/* z-index:2 en todo el contenido: los objetos 3D van en la capa 1, así que
   pasan por encima de los fondos de sección y por debajo de los textos.
   Los fondos que son elementos aparte (.wherebg, .playshot, .symbbg)
   llevan z-index:0 y se quedan debajo de todo. */
.wrap{position:relative;z-index:2;width:100%;max-width:var(--maxw);margin:0 auto;padding:0 var(--pad)}
.ticker,.foot{position:relative;z-index:2}
.wrap.narrow{max-width:820px}
.wrap.center{text-align:center}
.sec{padding:clamp(72px,12vw,150px) 0;position:relative}
.sec+.sec{border-top:1px solid var(--line2)}

/* ─── tipografía ────────────────────────────────────────────────────────── */
.kicker{
  font-family:var(--mono);font-size:var(--t-s);letter-spacing:var(--ls-6);text-transform:uppercase;
  color:var(--dim);margin:0 0 22px;
}
.kicker.red{color:var(--red)}
.kicker .kn{font-style:normal}   /* el número lo pone el JS: ver numberSections() */

.h2{
  font-family:var(--display);font-weight:900;font-stretch:condensed;
  text-transform:uppercase;letter-spacing:var(--ls-t2);line-height:.92;
  /* estos sí parten línea solos, así que el ancho no los limita: suben por
     acompañar a los de cartel, no porque cupiera más */
  font-size:clamp(46px,11.5vw,84px);margin:0 0 22px;
}
/* Los dos titulares de cartel —«Obedece el dress code» y «Agita el móvil»— van
   en rojo y en dos líneas, con una letra decorativa por palabra. Los saltos y
   las decorativas los pone el JS desde los textos; aquí sólo el color y el
   cuerpo. */
.h2-big{
  /* medido igual: en 360 px la línea más ancha es «SHAKE YOUR», que aguanta
     63 px; 16vw pide 57,6 */
  font-size:clamp(52px,16vw,124px);letter-spacing:var(--ls-t3);
  line-height:.86;color:var(--red);
}
.h3{
  font-family:var(--display);font-weight:900;font-stretch:condensed;
  text-transform:uppercase;letter-spacing:var(--ls-1);
  font-size:clamp(24px,3.4vw,36px);margin:64px 0 20px;
}
.h3.red{color:var(--red)}

.lead{font-size:clamp(17.5px,2.1vw,22px);line-height:1.6;color:#c9c5c0;max-width:66ch;margin:0 0 18px}
/* Power Grotesk sólo tiene Regular: el énfasis lo da el color y el aire
   entre letras, no una negrita que el navegador tendría que falsificar. */
.lead b{color:var(--bone);font-weight:400;letter-spacing:var(--ls-1)}
.note{font-family:var(--mono);font-size:var(--t-s);letter-spacing:var(--ls-2);color:var(--dim);line-height:1.7;margin-top:22px}

/* ═══ NAV ═══════════════════════════════════════════════════════════════ */
.nav{
  position:fixed;top:0;left:0;right:0;z-index:120;
  display:flex;align-items:center;gap:16px;
  padding:12px var(--pad);
  background:linear-gradient(#000 20%,rgba(0,0,0,0));
  transition:background .35s,backdrop-filter .35s,border-color .35s;
  border-bottom:1px solid transparent;
  padding-top:calc(12px + env(safe-area-inset-top));
}
.nav.stuck{background:rgba(0,0,0,.86);backdrop-filter:blur(14px) saturate(140%);border-bottom-color:var(--line2)}
/* `flex:none` no es cosmético: en la franja apretada (861–1039) la fila va
   justa y el corazón, siendo un elemento flexible más, se encogía hasta
   desaparecer. Es la marca: no se encoge. */
.nav-mark{flex:none}
.nav-mark img{width:26px;height:auto;opacity:.9}
/* Con Power Grotesk (más ancha que la monoespaciada de antes) y un enlace más
   —Symbiotikka—, la fila no cabía y los enlaces se partían en dos líneas.
   `nowrap` lo impide y el hueco se ajusta al ancho disponible. */
.nav-links{display:flex;gap:clamp(15px,1.9vw,26px);margin-left:auto}
.nav-links a{
  font-family:var(--mono);font-size:var(--t-s);letter-spacing:var(--ls-4);text-transform:uppercase;
  color:var(--dim);transition:color .2s;position:relative;padding:4px 0;
  white-space:nowrap;
}
@media (max-width:1150px){
  .nav-links a{font-size:var(--t-xs);letter-spacing:var(--ls-3)}
}
/* En la franja donde el menú va en el flujo (861–1359) hay que apretarlo: ocho
   enlaces, el logo, el idioma y el botón de entradas en una sola fila. Se le
   quita el tracking y se junta el hueco; por debajo de 861 el menú desaparece y
   manda la barra de abajo. */
@media (max-width:1359px){
  .nav-links{gap:14px}
  .nav-links a{letter-spacing:var(--ls-1)}
  .nav-links+.nav-right{margin-left:14px}
  .nav-right{gap:8px}
}
.nav-links a::after{content:"";position:absolute;left:0;right:100%;bottom:0;height:1px;background:var(--red);transition:right .3s}
.nav-links a:hover{color:var(--bone)}
.nav-links a:hover::after{right:0}
.nav-links a.on{color:var(--bone)}
.nav-links a.on::after{right:0}
.nav-right{display:flex;align-items:center;gap:12px;margin-left:auto}
.nav-links+.nav-right{margin-left:26px}

/* el menú, centrado en la barra. Va fuera del flujo para que ni el logo de la
   izquierda ni los botones de la derecha lo descoloquen, y siga centrado
   aunque las palabras cambien de largo al cambiar de idioma. */
/* El corte de verdad está en **1360**, y sale de medir, no de estimar. Centrado
   de verdad, el menú no sabe nada de lo que tiene al lado, así que se metía por
   debajo del EN/ES y del botón de entradas —«ENTRADAS» encima de «ENTRADAS»—.
   Medida la holgura entre el final del menú y el principio de los botones:

     1040 → −59    1200 → −36    1360 → +30
     1100 → −36    1280 →  −5    1440 → +70

   O sea que se pisaba hasta los 1330 y pico. Primero puse 1040 a ojo y seguía
   pisándose; con la medida, 1360. Por debajo, el menú vuelve al flujo normal
   (logo · menú · botones), que se aprieta pero nunca se solapa. */
@media (min-width:1360px){
  .nav-links{
    position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
    margin:0;gap:clamp(16px,2.2vw,30px);
  }
  .nav-links+.nav-right{margin-left:auto}
}
.lang{
  font-family:var(--mono);font-size:var(--t-s);letter-spacing:var(--ls-3);color:var(--dim);
  border:1px solid var(--line);border-radius:99px;padding:5px 11px;line-height:1;
}
.lang b{color:var(--bone);font-weight:400}
.lang span{opacity:.4;margin:0 3px}
.navbuy{
  font-family:var(--mono);font-size:var(--t-s);letter-spacing:var(--ls-4);text-transform:uppercase;
  background:var(--red);color:#fff;padding:8px 14px;border-radius:99px;line-height:1;
  transition:transform .2s,background .2s;
}
.navbuy:hover{background:#fff;color:#000;transform:translateY(-1px)}
/* sin menú, el idioma y las entradas se van a la derecha: el `+ .nav-right`
   de arriba sigue casando aunque .nav-links esté oculto, y los dejaba
   pegados al logo */
@media (max-width:860px){
  .nav-links{display:none}
  .nav-links+.nav-right{margin-left:auto}
}

/* ═══ HERO ══════════════════════════════════════════════════════════════ */
.hero{
  position:relative;min-height:100svh;display:flex;flex-direction:column;
  align-items:center;justify-content:center;text-align:center;
  padding:calc(96px + env(safe-area-inset-top)) var(--pad) 90px;
  overflow:hidden;
  /* Sin `isolation:isolate`, y es a propósito. La tentación con `.hero-photo`
     —que llegó a llevar un modo de fusión— es aislar la portada para darle un
     fondo propio contra
     el que fundirse, pero no hace falta: el rojo es el fondo de este mismo
     elemento y se pinta antes que la foto, así que ya está en el backdrop.

     Y aislar tiene precio. `.hero` es `position:relative` sin z-index, o sea
     que hoy NO abre contexto de apilado y sus hijos —`.hero-in` en 2, los dos
     círculos en 4— se apilan en el del documento, por encima de los paneles
     3D, que van fijos en 1 (ver `.scroll-obj`). Con `isolate`, esos hijos se
     quedan encerrados aquí dentro y la portada entera baja al 0 del documento:
     los paneles pasarían por delante del título y de los botones. */
}

/* ── la foto de la portada ───────────────────────────────────────────────────
   Stella y Bonnie, a color y RECORTADAS: el archivo viene con canal alfa y sin
   el fondo del estudio, así que lo que hay detrás de las dos es el rojo de la
   marca —el fondo de `.hero`— y no un rectángulo de foto.

   Ahí se acaban de un golpe las tres cosas que este bloque llevaba intentando:
   no hace falta modo de fusión para que el rojo siga siendo el fondo, no hace
   falta filtro para que la foto no se coma la portada, y no hace falta máscara
   para disolver los cantos del archivo, porque no hay cantos. La imagen es a
   color, tal cual, y el fondo es rojo, plano y entero. Es el cartel.

   Y vienen separadas, una a cada lado y con el centro vacío, que es lo que
   convierte esto en una composición y no en un fondo: la columna de texto cae
   por el hueco de en medio y se lee sobre el rojo. Por eso el encuadre se
   ancla ARRIBA y no al centro: lo que sobra se recorta por abajo, que es donde
   las dos ya vienen cortadas, en vez de comerse las cabezas.

   Aquí sólo se decide ese encuadre. El resto está en el PNG.
   ---------------------------------------------------------------------------- */
.hero-photo{
  position:absolute;inset:0;z-index:1;pointer-events:none;overflow:hidden;
}
.hero-photo picture{display:contents}
.hero-photo img{
  width:100%;height:100%;display:block;
  object-fit:cover;object-position:50% 0;
}
/* De la maquinaria que hubo aquí no queda nada, y eso sigue en pie: el `.hero-cut`,
   la máscara del canto de abajo, el vaivén de `herodrift`, la cama de degradados
   de `.hero-photo::after` y el reparto en dos bandas del móvil eran cinco bloques
   de reglas, dos de ellos escritos sólo para que el texto se leyera encima de la
   foto. Con el recorte ese trabajo desaparece de la hoja y se va al archivo: la
   foto de ahora son dos reglas —posición y encuadre— y ni una línea de color.

   `.hero-glow` sigue donde estaba, debajo de la foto, y sigue sin ser un velo:
   es el viñeteado granate de los cantos, para que el rojo tenga cuerpo y no se
   lea como un plano de pintura.
   ---------------------------------------------------------------------------- */

/* ── la portada en el móvil: repartida, no amontonada ────────────────────────
   Centrada, la portada del móvil salía apelotonada en el medio con una franja
   de rojo vacío arriba y otra abajo: seis piezas juntas en la mitad de la
   pantalla y ni una en los dos tercios restantes. En una pantalla apaisada eso
   se lee como un bloque centrado; en una vertical de 886 px de alto se lee como
   un descuido.

   El reparto es el del cartel: la marca arriba, el bloque de título, fecha,
   sitio y cuenta atrás en el centro, y el látigo abajo. Lo hacen **dos**
   `margin:auto`, no uno: el navegador reparte el hueco sobrante a partes
   iguales entre todos los `auto` de la columna, así que uno arriba del título y
   otro debajo de la cuenta atrás dan dos huecos del mismo tamaño —encima y
   debajo del bloque de en medio— en lugar de un solo agujero.

   Con un único `auto` esto ya estuvo aquí, y hacía otra cosa: dejaba TODO el
   hueco en una sola franja central, que era donde caía el beso del recorte que
   entonces había de fondo. Sin foto, esa franja era un agujero entre el título
   y su propia fecha.

   Van con `.hero` delante, y no es manía: los márgenes que se tocan están
   escritos más abajo en esta misma hoja y en abreviado, así que sin el escalón
   de especificidad un `margin:0 0 14px` posterior devuelve el `auto` a cero y
   el reparto no ocurre.
   ---------------------------------------------------------------------------- */
@media (max-width:760px){
  .hero{
    justify-content:flex-start;
    padding-top:calc(74px + env(safe-area-inset-top));
  }
  .hero .hero-in{display:flex;flex-direction:column;flex:1 1 auto}
  .hero .herotitle{margin-top:auto}
  .hero .count{margin-bottom:auto}
  /* La marca y el título se aprietan un punto entre ellos: son el bloque de
     arriba y tienen que leerse como uno solo, no como dos cosas separadas por
     un hueco del tamaño del que ahora hay en el centro. */
  .hero .lockup{margin-bottom:clamp(10px,2.4vw,18px)}

  /* En vertical entra el otro archivo (ver el <picture> del index) y sigue con
     `contain`, apoyado en el suelo: es lo único que las mete a las dos enteras
     en una pantalla que pasa del doble de alta que ancha, y aquí no deja ningún
     borde a la vista —que es lo que descartaba `contain` cuando la imagen era
     un rectángulo— porque ya no hay fondo que enseñar: lo que las rodea es el
     rojo.

     El desbordamiento de los lados es para que se vean MÁS GRANDES. Con
     `contain`, el tamaño de la imagen lo manda el ancho de su caja, así que la
     única forma de subirlo sin recortarlas por abajo es darle a la caja más
     ancho del que tiene la pantalla. Un 13% por cada lado sube la altura de las
     dos de 309 a 389 px en un móvil de 430, y lo que se sale por los cantos es
     pelo y brazo, que es exactamente lo que se sacrifica en un cartel a sangre.
     Lo recorta el `overflow:hidden` de `.hero`.

     El `bottom` negativo es la otra mitad de la operación, y sin él lo anterior
     no vale. Al estar la imagen apoyada abajo, crecer la empuja hacia ARRIBA, y
     los 80 px que gana se los come la cuenta atrás: las cabezas suben hasta la
     línea de las cuatro cifras y «DAYS» y «SEC» acaban sobre el pelo. Bajando el
     suelo de la caja un 6%, las dos crecen hacia abajo en vez de hacia arriba:
     la cuenta atrás se queda en el rojo y lo que se sale por el canto de abajo
     son 56 px de cuerpo, que es justo lo que tapa la barra de los cuatro
     accesos. */
  .hero-photo{left:-13%;right:-13%;bottom:-6%}
  .hero-photo img{object-fit:contain;object-position:50% 100%}
}

/* ── el suelo, en pantalla corta ─────────────────────────────────────────────
   En un teléfono de 667 px de alto —un iPhone SE— la portada entera no cabe a
   su tamaño y «STAND» le caía encima a «MARTES 8 DE SEPTIEMBRE». El lockup y el
   título se miden aquí contra el ALTO de la ventana, igual que ya hacían en el
   portátil bajo, y encogen los dos a la vez.
   ---------------------------------------------------------------------------- */
/* ── el desbordamiento, medido contra el ALTO ────────────────────────────────
   El 13% de arriba está calculado para un móvil de hoy (932 px de alto). En uno
   más corto la portada mide lo mismo pero tiene menos sitio, y esos mismos 80 px
   de más suben las cabezas hasta la línea de la cuenta atrás: «DAYS» y «SEC»,
   que son las dos etiquetas de los cantos, acaban sobre el pelo. Aquí las dos
   crecen menos, que es lo que cabe.
   ---------------------------------------------------------------------------- */
@media (max-width:760px) and (max-height:860px){
  .hero-photo{left:-6%;right:-6%;bottom:-9%}
}

@media (max-width:760px) and (max-height:740px){
  .hero .lk-symb{height:min(58px,7.6vh)}
  .hero .lk-ut{height:min(27px,3.6vh)}
  .hero .lockup{margin-bottom:clamp(8px,1.4vh,14px)}
  .hero .ht-in{font-size:min(13.4vw,7.6vh)}
  .hero .herotitle{margin-bottom:clamp(16px,2.8vh,30px)}
  .hero .count b{font-size:min(9vw,6.4vh)}
  .hero .count{margin-bottom:clamp(10px,1.6vh,18px)}
  /* Aquí las dos ya no crecen nada: en 667 px de alto no hay hueco que ganar,
     sólo bajarlas para que la cuenta atrás siga cayendo en el rojo. */
  .hero-photo{left:0;right:0;bottom:-14%}
}

.hero-glow{
  position:absolute;inset:0;z-index:0;pointer-events:none;
  background:
    radial-gradient(120% 68% at 50% 6%, rgba(227,6,19,.20), transparent 62%),
    radial-gradient(90% 55% at 50% 108%, rgba(201,158,103,.13), transparent 60%),
    radial-gradient(60% 40% at 50% 45%, rgba(255,255,255,.045), transparent 70%);
  animation:breathe 9s ease-in-out infinite;
}
@keyframes breathe{0%,100%{opacity:.85}50%{opacity:1}}
@media (prefers-reduced-motion:reduce){.hero-glow{animation:none}}
.hero-in{position:relative;z-index:2;width:100%;max-width:1000px}


/* ── el lockup de las dos marcas ─────────────────────────────────────────────
   Symbiotikka × UTOPIA, al mismo nivel. Los dos logos vienen con proporciones
   muy distintas (317x205 el uno, 1800x318 el otro), así que NO se les da un
   ancho común: se igualan por ALTURA óptica y cada uno saca su ancho de su
   propia proporción. Igualarlos por ancho achataría a uno de los dos.
   ---------------------------------------------------------------------------- */
/* Con el título debajo, el lockup vuelve a ser lo que es en el cartel: la marca
   que abre, no la pieza que manda. Va a menos de la mitad de lo que medía
   cuando era el h1 y estaba solo. La proporción entre los dos no cambia
   (~2,3:1): lo que cambia es la escala de los dos a la vez. */
.lockup{
  display:flex;align-items:center;justify-content:center;
  gap:clamp(14px,2.4vw,30px);
  margin:0 0 clamp(16px,2.6vw,28px);
}
.lockup img{width:auto;filter:drop-shadow(0 0 70px rgba(227,6,19,.34))}
/* Los dos se igualan por ALTURA, no por ancho: uno es un monograma casi
   cuadrado (317x205) y el otro un wordmark apaisado (1800x318), y a igual
   ancho uno de los dos quedaría achatado. Pero a igual altura de caja el
   monograma pesa más de lo que mide —es un bloque compacto, el otro es una
   línea—, así que va un 11% por debajo de lo que pediría la proporción. */
.lk-symb{height:clamp(44px,7.6vw,100px)}
/* el de UTOPIA es un wordmark apaisado: a la misma altura de caja se vería
   el doble de grande, así que va a algo menos de la mitad */
.lk-ut{height:clamp(22px,3.7vw,49px)}
/* La chapa de MEETS entre los dos logotipos: la misma del cartel. Es una
   pastilla completamente redondeada (border-radius grande, no un valor fijo:
   así el radio es siempre la mitad de la altura y no hay que recalcularlo si
   cambia el cuerpo) en blanco hueso con la palabra en negro.

   En el cartel va en negro sobre rojo; aquí el fondo es oscuro, así que se
   invierte —blanco con letra negra—, que es exactamente la versión que usa el
   cartel de fondo negro. Ver el PDF de identidad, página 9. */
.lk-meets{
  flex:none;align-self:center;
  font-family:var(--display);
  font-size:clamp(9px,1vw,13px);line-height:1;
  letter-spacing:.06em;text-transform:uppercase;
  color:#000;background:var(--bone);
  padding:.42em .78em .5em;border-radius:999px;
  box-shadow:0 0 34px rgba(227,6,19,.34);
}
/* ── el lockup en el móvil: en fila, como en el cartel ───────────────────────
   Por debajo de 520 se apilaban —monograma, chapa y wordmark, uno encima de
   otro— y era una fila que se rendía antes de pelear. Apilados dejan de ser un
   lockup: SYMBIOTIKKA meets UTOPIA es UNA pieza y se lee de izquierda a
   derecha; en tres pisos son tres marcas en una lista.

   Y en fila caben, que era la duda. Echando la cuenta a 390 px: el monograma es
   1,55:1 y el wordmark 5,67:1, así que a 56 y 27 px de alto miden 87 y 153 de
   ancho; con la chapa (~48) y los dos huecos son 310 de los 350 que hay entre
   los márgenes. A 360 son 305 de 320, y a 320 —el teléfono más estrecho que
   existe— las medidas en vw los encogen a la vez y siguen entrando.

   Las alturas van en `min(px, vw)` y no en `clamp`: aquí no hace falta un suelo
   —por debajo de 320 no hay pantallas— y sí un techo que baje con el ancho, que
   es lo que mantiene la fila entera en una sola línea. La proporción entre los
   dos (2,07:1) es la misma que arriba: lo que cambia es la escala de los dos a
   la vez, nunca uno respecto al otro.
   ---------------------------------------------------------------------------- */
@media (max-width:520px){
  .lockup{flex-direction:row;flex-wrap:nowrap;gap:clamp(7px,2.2vw,13px)}
  .lk-symb{height:min(56px,14.6vw)}
  .lk-ut{height:min(27px,7.2vw)}
  .lk-meets{font-size:min(10px,2.5vw);padding:.4em .7em .46em}
}

/* ── LA JERARQUÍA DE LA PORTADA ──────────────────────────────────────────────
   Cuatro cuerpos y en este orden, que es el del cartel impreso:

     marca      ~50 px de alto   el lockup, arriba
     TÍTULO     124 px           «ONE NACHT STAND», lo que manda
     fecha       32 px           el día y la hora
     sitio       40 px           «Playa Soleil», que en el cartel pesa más que
                                 la hora, y debajo IBIZA a 14
     cuenta      42 px           los dígitos, por debajo del sitio

   Los saltos entre escalones son grandes a propósito —del título a la fecha hay
   un 3,9×—: una jerarquía en la que cada paso baja un 15% no se lee como
   jerarquía, se lee como descuido. Antes de esto la portada tenía un logotipo de
   214 px y todo lo demás entre 14 y 58: un salto y una meseta.

   «ONE NACHT STAND» vivía en la sección 01 y ha vuelto aquí, que es donde lo
   pone el cartel. Sigue siendo el mismo dato —EVENT.title, con la O, la C y la
   S en Dirtyline, y el corte de línea del cartel— y lo sigue pintando
   `paintFancy()` sobre `#eventtitle`.
   ---------------------------------------------------------------------------- */
/* El hueco entre «STAND» y la fecha, y es más grande de lo que parece que hace
   falta. El título va con `line-height:.86`, o sea con la caja MÁS CORTA que las
   letras: la S de Dirtyline saca su rasgo por debajo del renglón y se come el
   margen desde dentro. Con los 24 px de antes, el resultado en pantalla era un
   pelo de aire y la fecha parecía la cuarta línea del título.

   Sube a 52, que es lo que deja unos 30 reales por debajo del rasgo de la S.
   Y esto no le quita sitio a nada: desde que la portada no tiene foto que
   enseñar, el hueco de abajo sobra. */
.herotitle{margin:0 0 clamp(24px,3.6vw,52px)}
.ht-in{
  display:block;
  font-family:var(--display);font-weight:900;font-stretch:condensed;
  text-transform:uppercase;color:var(--bone);
  /* El término de en medio manda hasta la tablet, y sale de medir, no de
     probar: «ONE NACHT» —la línea larga, con la O y la C decorativas— ocupa
     **4,71 veces** el cuerpo. En una pantalla de 360 px la columna deja 324,
     o sea 68 px de cuerpo como techo; 16,4vw pide 59 y deja un 13% de aire.

     Si algún día cambia el título hay que volver a medir esto: la que manda es
     la línea más larga, no el título entero. */
  font-size:clamp(54px,16.4vw,124px);
  line-height:.86;letter-spacing:var(--ls-t3);
  /* La sombra de reserva, para el caso de que la portada vuelva a tener algo
     detrás. Sobre el rojo liso manda la del bloque rojo del final, que es una
     caída granate mucho más corta. */
  text-shadow:0 0 60px rgba(0,0,0,.55);
}
/* En la sección el título va rojo sobre negro y las decorativas heredan ese
   rojo: distinguirse por la forma basta. En la portada el título es negro sobre
   rojo, así que las tres tampoco pueden ir en rojo: heredan también. Ese
   `currentColor` lo pone el bloque rojo del final; este rojo de aquí es el que
   valía cuando la portada era negra. */
.ht-in .dl{font-size:1.02em;margin:0 .02em;color:var(--red)}
.ht-in .dl-lead{margin-left:0}

/* La fecha y la hora. En la grotesca del cartel y no en la de texto: es un
   escalón del título, no un pie de página. */
.herodate{
  display:flex;flex-wrap:wrap;align-items:center;justify-content:center;
  gap:clamp(10px,1.5vw,18px);
  font-family:var(--display);font-weight:900;font-stretch:condensed;
  text-transform:uppercase;color:var(--bone);
  font-size:clamp(16px,4.2vw,32px);line-height:1;letter-spacing:var(--ls-t1);
  margin:0 0 clamp(8px,1.2vw,14px);
}
.herodate i{width:5px;height:5px;background:var(--red);border-radius:50%;display:block;flex:none}

/* El sitio, un punto por encima de la fecha —como en el cartel, donde «Playa
   Soleil» pesa más que la hora— y en rojo: es el único rojo de los cuatro
   escalones, así que ordena sin tener que crecer. IBIZA cierra abajo, en el
   cuerpo más pequeño y con el tracking más ancho de la portada: los dos
   extremos de la escala, uno encima del otro. */
/* El sitio ya no es texto sino su propio logotipo, así que aquí no se mide un
   cuerpo: se mide un ANCHO. El wordmark trae «Playa Soleil» y debajo «IBIZA»,
   o sea los dos escalones de antes en una sola pieza, y por eso el tope está
   puesto contra el título: 340 px es poco más de un cuarto de los 1.240 que
   puede llegar a medir «ONE NACHT», que es la proporción que tienen los dos en
   el cartel. */
.heroplace{margin:0 0 clamp(26px,4vw,40px)}
.heroplace img{
  width:clamp(180px,26vw,340px);height:auto;margin:0 auto;
}
/* En pantalla estrecha la fecha y la hora no caben en una línea: la hora baja
   sola y el punto que las separaba se quedaría colgando al final de la primera,
   así que fuera. */
@media (max-width:520px){
  .herodate i{display:none}
  .herodate>span{flex-basis:100%}
  .herodate{gap:4px}
}

/* La bajada y la línea de debajo. Sigue pidiendo menos cuerpo que el título de
   arriba —es la bajada, no el titular—, pero el 4vw de antes la dejaba en 24 px
   en un móvil, ilegible al lado de un título de 108. Ahora es la mitad larga de
   él: «BERLIN COMES» aguanta 56 px en 360, y 14vw pide 50. */
.sec .claim{font-size:clamp(38px,14vw,56px);margin-bottom:10px;color:var(--bone)}
.sec .claim-sub{margin-bottom:clamp(26px,3.4vw,40px)}
.claim{
  font-family:var(--display);font-weight:900;font-stretch:condensed;text-transform:uppercase;
  font-size:clamp(28px,6.6vw,64px);line-height:.92;letter-spacing:var(--ls-t2);margin:0 0 12px;
}
.claim-sub{
  font-family:var(--mono);font-size:clamp(12px,1.8vw,15px);letter-spacing:var(--ls-6);
  text-transform:uppercase;color:var(--dim);margin:0 0 clamp(26px,4vw,40px);
}
/* cuenta atrás */
.count{display:flex;justify-content:center;gap:clamp(10px,3vw,26px);margin-bottom:clamp(30px,5vw,44px)}
.count .c{
  min-width:clamp(62px,15vw,104px);padding:clamp(10px,2vw,16px) 6px;
  border:1px solid var(--line);border-radius:3px;background:rgba(255,255,255,.02);
}
.count b{
  display:block;font-family:var(--display);font-weight:900;font-stretch:condensed;
  /* De 58 a 42: por encima del cuerpo del sitio (40) la cuenta atrás dejaba de
     ser el quinto escalón y se ponía a discutirle el cuarto. */
  font-size:clamp(26px,5.6vw,42px);line-height:1;font-variant-numeric:tabular-nums;
}
.count span{
  display:block;margin-top:7px;font-family:var(--mono);font-size:var(--t-xs);
  letter-spacing:var(--ls-6);text-transform:uppercase;color:var(--dim);
}
.count-live{
  font-family:var(--mono);font-size:var(--t-m);letter-spacing:var(--ls-6);text-transform:uppercase;
  color:var(--red);margin:0 0 clamp(30px,5vw,44px);
}

/* Los dos círculos de la portada —«Get your ticket» y «See the dress code»— ya
   no están, ni aquí ni en el HTML. Iban anclados a los cantos en pantalla ancha
   y ahí es donde están ahora Stella y Bonnie: el aro de línea negra del dress
   code caía sobre el encaje de Stella y desaparecía, y el disco de las entradas
   le tapaba medio cuerpo a Bonnie. En el móvil ya estaban escondidos —las
   entradas están en la barra de arriba y en la de abajo—, así que esto no quita
   ninguna puerta, quita un atajo que había dejado de funcionar. */

@media (min-width:900px){
  /* el botón del látigo vive aquí abajo: le dejamos su hueco */
  .hero{padding-top:calc(84px + env(safe-area-inset-top));padding-bottom:100px}
  .count{margin-bottom:0}
  .count-live{margin-bottom:0}
}

/* Portátiles bajos (1280x800 y compañía): con las medidas de siempre el hero
   se pasaba de alto y el botón de bajar caía fuera. Aquí todo se mide contra
   la altura de la ventana, no contra el ancho. */
@media (min-width:760px) and (max-height:900px){
  .wordmark img{width:min(100%,min(860px,74vh))}
  /* La pieza alta de la portada vuelve a ser el título, así que es él el que se
     mide contra vh. El lockup, que ahora es la marca de cabecera, se encoge con
     él para que la proporción entre los dos aguante en una pantalla baja. */
  .lockup{margin-bottom:clamp(10px,2vh,22px)}
  .lk-symb{height:clamp(40px,8.4vh,82px)}
  .lk-ut{height:clamp(20px,4.1vh,40px)}
  .ht-in{font-size:clamp(46px,13.4vh,104px)}
  /* El mismo hueco de más que en la portada alta, medido en vh: la S de
     Dirtyline saca su rasgo por debajo del renglón —`line-height:.86`— y con
     16 px la fecha se leía pegada al título. Sube a 38, y cabe: desde que la
     portada no tiene foto, el hueco que hay entre el látigo y el botón de bajar
     sobra de largo. */
  .herotitle{margin-bottom:clamp(18px,3.4vh,38px)}
  .herodate{font-size:clamp(15px,3.2vh,27px);margin-bottom:clamp(6px,1vh,12px)}
  .heroplace{margin-bottom:clamp(16px,2.6vh,32px)}
  .heroplace img{width:clamp(170px,30vh,300px)}
  .count{gap:clamp(10px,1.6vw,22px)}
  .count .c{padding:clamp(8px,1.5vh,15px) 6px;min-width:clamp(58px,7.6vh,96px)}
  .count b{font-size:clamp(22px,4vh,38px)}
  .btn-circle{width:clamp(150px,23vh,224px);font-size:clamp(17px,3.1vh,30px)}
  .whipbtn-hero{margin-top:clamp(10px,1.8vh,22px);padding:clamp(9px,1.4vh,14px) clamp(22px,3vw,34px)}
}

/* botones */
.btn{
  display:inline-flex;flex-direction:column;align-items:center;gap:2px;
  padding:16px 30px;border-radius:2px;line-height:1.2;
  font-family:var(--display);font-weight:900;font-stretch:condensed;text-transform:uppercase;
  letter-spacing:var(--ls-2);font-size:var(--t-base);
  transition:transform .22s cubic-bezier(.2,.8,.3,1),background .22s,color .22s,box-shadow .22s;
}
.btn small{font-family:var(--mono);font-size:var(--t-xs);font-weight:400;letter-spacing:var(--ls-5);opacity:.7}
.btn-red{background:var(--red);color:#fff;box-shadow:0 0 0 rgba(227,6,19,0)}
.btn-red:hover{background:#fff;color:#000;transform:translateY(-2px);box-shadow:0 14px 40px rgba(227,6,19,.35)}
.btn-ghost{border:1px solid var(--line);color:var(--bone);justify-content:center}
.btn-ghost:hover{border-color:var(--bone);background:rgba(255,255,255,.05);transform:translateY(-2px)}
.btn-wide{display:flex;width:100%;margin-top:34px;padding:22px}

/* las dos llamadas del hero son círculos */
.btn-circle{
  width:clamp(172px,19.5vw,244px);aspect-ratio:1;border-radius:50%;
  padding:clamp(22px,2.6vw,34px);gap:9px;justify-content:center;
  font-size:clamp(19px,2.05vw,32px);line-height:.94;letter-spacing:var(--ls-t1);
  position:relative;isolation:isolate;text-wrap:balance;
}
.btn-circle small{font-size:clamp(8.5px,.78vw,10.5px);letter-spacing:var(--ls-4);line-height:1.4;opacity:.7}
/* un aro que gira despacio al pasar por encima */
.btn-circle::before{
  content:"";position:absolute;inset:-7px;border-radius:50%;z-index:-1;
  border:1px dashed rgba(255,255,255,.22);
  opacity:0;transition:opacity .3s;
}
.btn-circle:hover::before,.btn-circle:focus-visible::before{
  opacity:1;animation:ring 14s linear infinite;
}
@keyframes ring{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion:reduce){.btn-circle:hover::before{animation:none}}
.btn-red.btn-circle:hover{box-shadow:0 0 60px rgba(227,6,19,.5)}
/* sobre la foto del hero, el borde fino solo no se veía */
.btn-ghost.btn-circle{
  border-color:rgba(255,255,255,.34);background:rgba(0,0,0,.42);
  backdrop-filter:blur(7px) saturate(130%);
}
.btn-ghost.btn-circle:hover{border-color:var(--bone);background:rgba(0,0,0,.62)}

/* el hint de bajar es un botón: da el latigazo y baja */
.scrollhint{
  position:absolute;bottom:18px;left:50%;transform:translateX(-50%);z-index:3;
  display:flex;flex-direction:column;align-items:center;gap:9px;padding:10px 18px 0;
}
.scrollhint b{
  font-family:var(--mono);font-size:var(--t-xs);font-weight:400;letter-spacing:var(--ls-6);
  text-transform:uppercase;color:#6b6764;transition:color .25s,text-shadow .25s;
}
/* La barrita de bajar. Era **un pelo de 1 px** que se apagaba hasta el 20% de
   opacidad tres cuartas partes del ciclo, y sobre el rojo de la portada no se
   veía: no es que se leyera poco, es que no estaba. Un pelo de 1 px ya es
   frágil sobre negro; sobre un color plano y saturado, menos aún.

   Sube a 4 px y con las esquinas redondeadas, que a este grosor ya se notan y
   la convierten en un trazo en vez de en un borde. */
.scrollhint span{
  display:block;width:4px;height:46px;border-radius:3px;
  background:linear-gradient(var(--red),transparent);
  animation:drop 2.2s ease-in-out infinite;
}
.scrollhint:hover b,.scrollhint:focus-visible b{color:var(--red);text-shadow:0 0 18px rgba(227,6,19,.7)}
.scrollhint:active{transform:translateX(-50%) scale(.95)}
/* El vaivén, con el suelo más alto: al 20% la barrita desaparecía del todo en
   los extremos del ciclo y lo que se veía era un parpadeo, no un gesto de bajar.
   Al 55% el trazo no se va nunca y lo que se mueve es el largo. */
@keyframes drop{0%,100%{opacity:.55;transform:scaleY(.45);transform-origin:top}50%{opacity:1;transform:scaleY(1)}}
@keyframes snap{0%{box-shadow:0 0 0 0 rgba(227,6,19,.9)}100%{box-shadow:0 0 22px 7px rgba(227,6,19,0)}}
@media (prefers-reduced-motion:reduce){.scrollhint span{animation:none;opacity:.6}}

/* ═══ TICKER ════════════════════════════════════════════════════════════ */
.ticker{
  overflow:hidden;border-top:1px solid var(--line2);border-bottom:1px solid var(--line2);
  background:var(--ink2);padding:14px 0;
}
.ticker-in{display:flex;width:max-content;animation:slide 42s linear infinite}
.ticker-in span{
  font-family:var(--display);font-weight:900;font-stretch:condensed;text-transform:uppercase;
  font-size:clamp(16px,2.6vw,26px);letter-spacing:var(--ls-1);padding:0 22px;white-space:nowrap;color:#fff;
}
.ticker-in span.star{color:var(--red)}
@keyframes slide{from{transform:translateX(0)}to{transform:translateX(-50%)}}
@media (prefers-reduced-motion:reduce){.ticker-in{animation:none}}

/* ═══ THE NIGHT ═════════════════════════════════════════════════════════ */
.imperatives{list-style:none;margin:46px 0 0;padding:0;display:grid;gap:1px;background:var(--line2);border:1px solid var(--line2)}
.imperatives li{
  display:flex;align-items:baseline;gap:18px;background:var(--ink);
  padding:22px clamp(14px,3vw,26px);transition:background .3s;
}
.imperatives li:hover{background:var(--ink3)}
.imperatives span{font-family:var(--mono);font-size:var(--t-s);letter-spacing:var(--ls-5);color:var(--red)}
.imperatives b{
  font-family:var(--display);font-weight:900;font-stretch:condensed;text-transform:uppercase;
  font-size:clamp(23px,4.3vw,42px);letter-spacing:var(--ls-t1);line-height:1;
}
.storyend{
  margin:34px 0 0;font-family:var(--display);font-weight:900;font-stretch:condensed;
  text-transform:uppercase;font-size:clamp(21px,3.7vw,36px);color:var(--red);letter-spacing:var(--ls-t1);
}

/* ═══ LINE-UP ═══════════════════════════════════════════════════════════
   Lo que había aquí era una rejilla de horas de 780 px de alto —`.tt`, con su
   raíl de horas, sus columnas, sus `.slot` colocados por porcentaje, la línea
   roja del minuto en curso y una `.nowbar` de «sonando ahora»—, y con ella se
   fueron sus dos docenas de reglas y su media query de móvil.

   La lista es la misma pieza que `.moments` y que `.imperatives`: filas sobre
   una rejilla de un píxel de hueco, que es la que dibuja las divisiones. Se
   parece a ellas a propósito —son las tres el mismo tipo de contenido, una
   sucesión— y no hace falta ningún componente nuevo para esto.

   El filete rojo de la izquierda es lo único que se hereda de los `.slot`: era
   lo que marcaba un set dentro de la tabla y sigue marcándolo dentro de la
   lista.
   ---------------------------------------------------------------------------- */
.acts{
  list-style:none;margin:34px 0 0;padding:0;
  display:grid;gap:1px;background:var(--line2);border:1px solid var(--line2);
}
.acts li{
  background:var(--ink);border-left:2px solid var(--red);
  padding:clamp(20px,3.4vw,30px) clamp(14px,3vw,26px);
  transition:background .3s;
}
.acts li:hover{background:var(--ink3)}
/* Mismo cuerpo que tenía el nombre dentro del `.slot`. Allí el tope de 58 px lo
   marcaba el alto del set más corto; aquí no hay alto que respetar, así que lo
   marca el ancho del nombre más largo (CHARLOTTE LION), que a 375 px sigue
   entrando en una línea. */
.acts .n{
  display:block;font-family:var(--display);font-weight:900;font-stretch:condensed;
  text-transform:uppercase;font-size:clamp(30px,5.4vw,58px);line-height:1.02;
  letter-spacing:var(--ls-t2);
}
.acts .r{
  display:block;margin-top:7px;font-family:var(--mono);font-size:var(--t-xs);
  letter-spacing:var(--ls-5);text-transform:uppercase;color:var(--red);
}
/* La biografía es lo que ha ganado sitio al irse la tabla: dentro de un `.slot`
   no cabía —era una caja de alto fijo— y por eso no se enseñaba en ninguna
   parte. Aquí sí, y es lo que de verdad vende a cada artista. */
.acts .b{
  margin:13px 0 0;max-width:64ch;
  color:#c9c5c0;font-size:var(--t-l);line-height:1.55;
}

/* tira de fotos de la sala, debajo de los horarios */
.strip{
  margin:44px 0 0;display:grid;gap:10px;
  grid-template-columns:repeat(3,1fr);
}
@media (max-width:640px){.strip{gap:7px}}
.strip button{
  position:relative;display:block;width:100%;padding:0;overflow:hidden;
  aspect-ratio:4/3;border-radius:3px;background:#0b0b0b;border:1px solid var(--line2);
  transition:transform .3s cubic-bezier(.2,.8,.3,1),border-color .3s;
}
.strip img{width:100%;height:100%;object-fit:cover;filter:grayscale(.45) contrast(1.06);transition:transform .6s cubic-bezier(.2,.8,.3,1),filter .4s}
.strip button::after{content:"";position:absolute;inset:0;background:linear-gradient(transparent 45%,rgba(0,0,0,.88))}
.strip button:hover,.strip button:focus-visible{transform:translateY(-3px);border-color:rgba(255,255,255,.28)}
.strip button:hover img,.strip button:focus-visible img{transform:scale(1.05);filter:grayscale(0) contrast(1.06)}
.strip b{
  position:absolute;left:10px;right:10px;bottom:9px;z-index:2;text-align:left;
  font-family:var(--mono);font-size:var(--t-micro);font-weight:400;letter-spacing:var(--ls-4);
  text-transform:uppercase;color:#e6e2dd;line-height:1.4;
}
@media (max-width:480px){.strip b{font-size:var(--t-micro);letter-spacing:var(--ls-3)}}

.moments{list-style:none;margin:0;padding:0;display:grid;gap:1px;background:var(--line2);border:1px solid var(--line2)}
.moments li{display:flex;gap:clamp(14px,3vw,28px);background:var(--ink);padding:18px clamp(12px,2.5vw,22px);align-items:baseline;transition:opacity .4s,background .4s}
/* `min-width` un punto más ancho que antes: la última hora crece a «06:00 →»
   cuando ya la hemos pasado, y sin sitio empujaba el texto de su fila. */
.moments b{font-family:var(--mono);font-weight:400;font-size:var(--t-base);letter-spacing:var(--ls-2);color:var(--red);flex:none;min-width:64px}
.moments span{color:#c9c5c0;font-size:var(--t-l);line-height:1.55}

/* ── la lista, durante la noche ──────────────────────────────────────────────
   Sólo se marca mientras la fiesta está pasando; el resto del año esto no
   existe y la lista se lee tal cual. Ver `paintMoments()` en app.js.

   Lo pasado se apaga en vez de tacharse o desaparecer: sigue siendo el programa
   de la noche y quien llega a las tres quiere poder leer lo que se ha perdido.
   ---------------------------------------------------------------------------- */
.moments li.past{opacity:.38}
.moments li.now{background:rgba(227,6,19,.07)}
.moments li.now span{color:var(--bone)}
/* La chapa. Va dentro del párrafo y no al lado de la hora porque la hora es una
   columna de ancho fijo: metiéndola ahí, cada fila mediría distinto. */
.moments .np{display:none}
.moments li.now .np{
  display:inline-flex;align-items:center;gap:6px;vertical-align:middle;
  margin-left:10px;padding:3px 9px;border-radius:99px;
  background:var(--red);color:#fff;
  font-family:var(--mono);font-style:normal;font-size:var(--t-micro);
  letter-spacing:var(--ls-5);text-transform:uppercase;
}
.moments .np em{
  width:6px;height:6px;border-radius:50%;background:#fff;flex:none;
  animation:mpulse 1.6s ease-in-out infinite;
}
@keyframes mpulse{0%,100%{opacity:1;transform:scale(1)}50%{opacity:.35;transform:scale(.72)}}
@media (prefers-reduced-motion:reduce){.moments .np em{animation:none}}

/* ═══ DRESS CODE ════════════════════════════════════════════════════════ */
.sec-dress{background:linear-gradient(180deg,#000,#0a0506 40%,#000)}
.dressline{
  font-family:var(--mono);font-size:clamp(12px,2vw,15px);letter-spacing:var(--ls-5);
  text-transform:uppercase;color:var(--gold);margin:0 0 26px;line-height:2;
}
.dressline i{font-style:normal;color:var(--dim);text-transform:none;letter-spacing:var(--ls-3)}

/* vídeo o fotos: sólo se enseña uno, así la sección no se hace eterna */
.views{display:inline-flex;gap:0;margin:30px 0 0;border:1px solid var(--line);border-radius:99px;padding:3px}
.view{
  display:inline-flex;align-items:center;gap:8px;border-radius:99px;padding:9px 18px;
  font-family:var(--mono);font-size:var(--t-s);letter-spacing:var(--ls-4);text-transform:uppercase;
  color:var(--dim);transition:background .25s,color .25s;
}
.view svg{width:15px;height:15px;flex:none;fill:none;stroke:currentColor;stroke-width:1.6;
  stroke-linejoin:round;stroke-linecap:round}
.view svg .f{fill:currentColor;stroke:none}
.view:hover{color:var(--bone)}
.view.on{background:var(--red);color:#fff}
.view.on svg{stroke:#fff}

.player[hidden],.dgrid[hidden]{display:none!important}

.player{
  margin:44px 0 0;display:grid;gap:22px 30px;align-items:start;
  grid-template-columns:minmax(0,340px) minmax(0,1fr);
  grid-template-rows:auto auto 1fr;   /* controles · looks · "not getting in" */
}
@media (max-width:820px){
  .player{grid-template-columns:1fr;grid-template-rows:auto auto auto}
  .screen{grid-row:auto!important}
}

.screen{
  position:relative;grid-column:1;grid-row:1 / span 3;border-radius:4px;overflow:hidden;background:#000;
  aspect-ratio:480/848;box-shadow:0 30px 90px rgba(0,0,0,.8),0 0 0 1px var(--line);
}
.screen video{width:100%;height:100%;object-fit:cover;display:block}
.screen-frame{
  position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(120% 90% at 50% 50%,transparent 55%,rgba(0,0,0,.55));
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.08);
}
.bigplay{
  position:absolute;inset:0;display:grid;place-items:center;background:rgba(0,0,0,.35);
  transition:opacity .3s;
}
.bigplay i{
  width:62px;height:62px;border-radius:50%;border:1px solid rgba(255,255,255,.6);
  display:grid;place-items:center;backdrop-filter:blur(4px);background:rgba(0,0,0,.3);
}
.bigplay i::after{content:"";border-left:15px solid #fff;border-top:9px solid transparent;border-bottom:9px solid transparent;margin-left:4px}
.bigplay.hide{opacity:0;pointer-events:none}
.screen-tag{
  position:absolute;left:12px;top:12px;
  font-family:var(--mono);font-size:var(--t-xs);letter-spacing:var(--ls-4);text-transform:uppercase;
  background:rgba(0,0,0,.62);backdrop-filter:blur(6px);
  border:1px solid rgba(255,255,255,.18);border-radius:2px;
  padding:6px 10px;pointer-events:none;color:#fff;
}
.screen-tag:empty{display:none}
.vprog{position:absolute;left:0;right:0;bottom:0;height:2px;background:rgba(255,255,255,.14)}
.vprog i{display:block;height:100%;width:0;background:var(--red);transition:width .12s linear}

.pcontrols{display:flex;flex-wrap:wrap;align-items:center;gap:10px;grid-column:2}
@media (max-width:820px){.pcontrols{grid-column:1}}
.pill{
  font-family:var(--mono);font-size:var(--t-s);letter-spacing:var(--ls-4);text-transform:uppercase;
  border:1px solid var(--line);border-radius:99px;padding:8px 15px;color:var(--dim);
  display:inline-flex;align-items:center;gap:7px;transition:.2s;
}
.pill:hover{color:var(--bone);border-color:var(--bone)}
.pill.on{background:var(--red);border-color:var(--red);color:#fff}
.spk{width:9px;height:9px;border-radius:1px;background:currentColor;position:relative}
.spk::after{content:"";position:absolute;left:7px;top:-3px;border-left:7px solid currentColor;border-top:7px solid transparent;border-bottom:7px solid transparent}
.phint{font-family:var(--mono);font-size:var(--t-xs);letter-spacing:var(--ls-3);text-transform:uppercase;color:#4c4a48}

.chips{grid-column:2;display:flex;flex-wrap:wrap;gap:7px;align-content:start}
@media (max-width:820px){.chips{grid-column:1}}
.chip{
  font-family:var(--mono);font-size:var(--t-s);letter-spacing:var(--ls-4);text-transform:uppercase;
  border:1px solid var(--line);border-radius:2px;padding:9px 13px;color:#a5a09b;
  transition:.18s;position:relative;
}
.chip:hover{color:#fff;border-color:#fff;transform:translateY(-1px)}
.chip.on{background:var(--red);border-color:var(--red);color:#fff}
.chip.on::after{content:"";position:absolute;left:0;right:0;bottom:-1px;height:1px;background:#fff}

.dgrid{
  margin-top:64px;display:grid;gap:12px;
  grid-template-columns:repeat(auto-fill,minmax(150px,1fr));
}
@media (max-width:520px){.dgrid{grid-template-columns:repeat(2,1fr);gap:9px}}
.dcard{
  position:relative;border-radius:3px;overflow:hidden;background:#0b0b0b;text-align:left;
  aspect-ratio:320/432;border:1px solid var(--line2);
  transition:transform .3s cubic-bezier(.2,.8,.3,1),border-color .3s;
}
.dcard img{width:100%;height:100%;object-fit:cover;transition:transform .6s cubic-bezier(.2,.8,.3,1),filter .4s;filter:grayscale(.35) contrast(1.05)}
.dcard:hover,.dcard:focus-visible{transform:translateY(-4px);border-color:rgba(255,255,255,.3)}
.dcard:hover img{transform:scale(1.06);filter:grayscale(0) contrast(1.05)}
.dcard .veil{position:absolute;inset:0;background:linear-gradient(transparent 38%,rgba(0,0,0,.9))}
.dcard .lab{
  position:absolute;left:11px;right:11px;bottom:34px;
  font-family:var(--display);font-weight:900;font-stretch:condensed;text-transform:uppercase;
  font-size:clamp(15px,2.6vw,19px);line-height:1;letter-spacing:var(--ls-t1);
}
.dcard .num{position:absolute;left:11px;bottom:14px;font-family:var(--mono);font-size:var(--t-xs);letter-spacing:var(--ls-5);color:var(--red)}
.dcard .play{position:absolute;right:10px;bottom:12px;font-family:var(--mono);font-size:var(--t-micro);letter-spacing:var(--ls-4);text-transform:uppercase;color:#fff;opacity:0;transition:opacity .3s}
.dcard:hover .play{opacity:.85}
.dcard.on{border-color:var(--red)}
.dcard.on .num{color:#fff}

.nope{margin-top:78px;border-top:1px solid var(--line2);padding-top:22px}
/* dentro del reproductor va en la columna derecha, pegado a la lista de looks */
.player>.nope{grid-column:2;margin-top:10px;align-self:start}
.player>.nope .h3{margin-top:0}
@media (max-width:820px){.player>.nope{grid-column:1;margin-top:26px}}
.nopelist{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;gap:9px}
.nopelist li{
  font-family:var(--mono);font-size:var(--t-s);letter-spacing:var(--ls-3);text-transform:uppercase;
  border:1px solid rgba(227,6,19,.35);color:#c98d90;padding:9px 14px;border-radius:2px;
  position:relative;
}
.nopelist li::before{content:"✕";color:var(--red);margin-right:8px;font-size:var(--t-micro)}

/* ═══ GALERÍA ═══════════════════════════════════════════════════════════ */
.sec-gal{background:linear-gradient(180deg,#000,#070606 45%,#000)}

.gfilters{display:flex;flex-wrap:wrap;gap:7px;margin:30px 0 26px}
.gfilters .chip{cursor:pointer}
.gfilters .chip b{font-weight:400;opacity:.45;margin-left:7px;font-size:var(--t-micro)}

/* mampostería de verdad: columnas, así cada foto conserva su forma */
.ggrid{columns:4;column-gap:12px}
@media (max-width:1040px){.ggrid{columns:3}}
@media (max-width:700px){.ggrid{columns:2;column-gap:8px}}
.ggrid:empty::after{
  content:attr(data-empty);display:block;font-family:var(--mono);font-size:var(--t-s);
  letter-spacing:var(--ls-4);text-transform:uppercase;color:var(--dim);padding:34px 0;
}

.gcell{
  display:block;width:100%;padding:0;margin:0 0 12px;position:relative;
  break-inside:avoid;-webkit-column-break-inside:avoid;
  border-radius:3px;overflow:hidden;background:#0b0b0b;border:1px solid var(--line2);
  transition:transform .3s cubic-bezier(.2,.8,.3,1),border-color .3s;
}
@media (max-width:700px){.gcell{margin-bottom:8px}}
.gcell[hidden]{display:none!important}
.gcell img{
  width:100%;height:auto;display:block;
  filter:grayscale(.4) contrast(1.06);
  transition:transform .6s cubic-bezier(.2,.8,.3,1),filter .4s;
}
.gcell::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(transparent 55%,rgba(0,0,0,.85));
  opacity:0;transition:opacity .35s;
}
.gcell:hover,.gcell:focus-visible{transform:translateY(-3px);border-color:rgba(255,255,255,.28)}
.gcell:hover img,.gcell:focus-visible img{transform:scale(1.05);filter:grayscale(0) contrast(1.06)}
.gcell:hover::after,.gcell:focus-visible::after{opacity:1}
.gcell .gt{
  position:absolute;left:11px;right:11px;bottom:11px;z-index:2;text-align:left;
  font-family:var(--mono);font-size:var(--t-xs);letter-spacing:var(--ls-4);line-height:1.5;color:#fff;
  opacity:0;transform:translateY(6px);transition:opacity .35s,transform .35s;
}
.gcell:hover .gt,.gcell:focus-visible .gt{opacity:1;transform:none}
.gcell .gn{
  position:absolute;left:11px;top:11px;z-index:2;
  font-family:var(--mono);font-size:var(--t-micro);letter-spacing:var(--ls-5);text-transform:uppercase;
  color:#fff;background:rgba(227,6,19,.9);padding:4px 8px;border-radius:2px;
  opacity:0;transition:opacity .35s;
}
.gcell:hover .gn,.gcell:focus-visible .gn{opacity:1}
@media (hover:none){
  .gcell .gt,.gcell .gn{opacity:1;transform:none}
  .gcell::after{opacity:1}
  .gcell img{filter:none}
}

/* ─── lightbox ─── */
.lbox{
  position:fixed;inset:0;z-index:500;
  background:rgba(0,0,0,.97);backdrop-filter:blur(22px) saturate(120%);
  display:flex;align-items:center;justify-content:center;
  padding:clamp(12px,3vw,40px);
  animation:lbin .28s ease-out;touch-action:pan-y;
}
.lbox[hidden]{display:none!important}
@keyframes lbin{from{opacity:0}to{opacity:1}}
.lb-fig{margin:0;display:flex;flex-direction:column;align-items:center;gap:16px;max-width:100%;max-height:100%}
.lb-stage{position:relative;display:flex;align-items:center;justify-content:center;min-height:0;flex:1}
.lb-stage img{
  max-width:min(1200px,92vw);max-height:76svh;width:auto;height:auto;
  border-radius:3px;box-shadow:0 40px 120px rgba(0,0,0,.9);
  opacity:0;transition:opacity .28s;
}
.lb-stage img.ready{opacity:1}
.lbox.lite .lb-stage img{max-width:min(560px,92vw);max-height:min(560px,62svh)}
.lb-load{
  position:absolute;width:26px;height:26px;border-radius:50%;
  border:1px solid rgba(255,255,255,.18);border-top-color:var(--red);
  animation:spin .8s linear infinite;opacity:0;transition:opacity .2s;
}
.lb-stage.busy .lb-load{opacity:1}
@keyframes spin{to{transform:rotate(360deg)}}
.lb-cap{display:flex;flex-wrap:wrap;align-items:baseline;justify-content:center;gap:8px 16px;text-align:center;padding:0 8px}
.lb-n{font-family:var(--mono);font-size:var(--t-xs);letter-spacing:var(--ls-5);color:var(--red);flex:none}
.lb-txt{font-family:var(--mono);font-size:var(--t-m);letter-spacing:var(--ls-2);line-height:1.6;color:#b7b3ae;max-width:60ch}

.lb-x{
  position:absolute;top:calc(14px + env(safe-area-inset-top));right:16px;z-index:3;
  width:44px;height:44px;border-radius:50%;border:1px solid var(--line);
  display:grid;place-items:center;font-size:var(--t-l);color:var(--dim);
  background:rgba(0,0,0,.5);backdrop-filter:blur(6px);transition:.2s;
}
.lb-x:hover{color:#fff;border-color:#fff}
.lb-arrow{
  position:absolute;top:50%;transform:translateY(-50%);z-index:3;
  width:52px;height:52px;border-radius:50%;border:1px solid var(--line);
  display:grid;place-items:center;font-size:30px;line-height:1;color:var(--dim);
  background:rgba(0,0,0,.45);backdrop-filter:blur(6px);transition:.2s;
}
.lb-arrow span{transform:translateY(-2px)}
.lb-arrow:hover{color:#fff;border-color:#fff;background:rgba(227,6,19,.25)}
.lb-prev{left:clamp(8px,2vw,28px)}
.lb-next{right:clamp(8px,2vw,28px)}
@media (max-width:640px){
  .lb-arrow{width:42px;height:42px;font-size:24px;bottom:calc(16px + env(safe-area-inset-bottom));top:auto;transform:none}
  .lb-prev{left:24px}
  .lb-next{right:24px}
  .lb-stage img{max-height:64svh}
  .lb-cap{padding-bottom:70px}
}

/* ═══ PLAYROOM ══════════════════════════════════════════════════════════ */
.sec-play{background:#000}
.playcard{
  border:1px solid rgba(201,158,103,.3);border-radius:4px;
  background:
    radial-gradient(120% 100% at 0% 0%, rgba(201,158,103,.10), transparent 60%),
    linear-gradient(180deg,#0b0908,#000);
  position:relative;overflow:hidden;
}
/* la foto va de fondo de la tarjeta entera, apagada por la izquierda
   para que el texto siga leyéndose encima */
.playshot{position:absolute;inset:0;z-index:0;background:#000}
.playshot img{
  width:100%;height:100%;object-fit:cover;object-position:64% 24%;
  filter:grayscale(.25) contrast(1.05);
}
.playshot::after{
  content:"";position:absolute;inset:0;
  background:
    linear-gradient(100deg,#000 24%,rgba(0,0,0,.86) 48%,rgba(0,0,0,.42) 82%),
    linear-gradient(180deg,rgba(0,0,0,.55),transparent 28%,rgba(0,0,0,.65));
}
.playtext{position:relative;z-index:1;padding:clamp(26px,5vw,52px);max-width:min(100%,600px)}
.playtext .lead{color:#cfcbc6}
@media (max-width:760px){
  .playshot img{object-position:56% 20%}
  .playshot::after{
    background:linear-gradient(180deg,rgba(0,0,0,.35) 0%,rgba(0,0,0,.8) 38%,#000 72%);
  }
  .playtext{padding-top:clamp(150px,42vw,240px)}
}
.playcard::after{
  content:"";position:absolute;right:-60px;top:-60px;width:240px;height:240px;border-radius:50%;
  background:radial-gradient(circle,rgba(201,158,103,.16),transparent 70%);pointer-events:none;
}
.playby{font-family:var(--mono);font-size:var(--t-m);letter-spacing:var(--ls-6);text-transform:uppercase;color:var(--gold);margin:-12px 0 24px}
/* El gancho: «detrás de la fiesta empieza otro mundo». No es un párrafo más
   —de hecho es la frase con la que el cliente abre la sección—, así que va en
   la grotesca del cartel y en hueso, un escalón por debajo del h2 y otro por
   encima de los tres párrafos. Con esto la tarjeta tiene tres cuerpos: título,
   gancho y texto, que es lo que hace falta para que cinco bloques seguidos no
   se lean como un muro. */
.playlead{
  font-family:var(--display);font-weight:900;font-stretch:condensed;text-transform:uppercase;
  font-size:clamp(19px,3vw,30px);line-height:1.12;letter-spacing:var(--ls-t1);
  color:var(--bone);margin:0 0 20px;max-width:20ch;
}
/* Los párrafos, más juntos entre ellos que el resto de la web: son tres
   seguidos dentro de una tarjeta, no tres secciones. */
.playtext .lead+.lead{margin-top:14px}
/* La letra pequeña de la compra. El `.note` general se apoya en el negro de la
   página; aquí cae sobre la foto de la sala, así que sube un punto de claridad
   y se separa del párrafo de encima con una raya, que es lo que la marca como
   condición y no como una cuarta frase de venta. */
.playtext .note{
  margin-top:22px;padding-top:18px;color:#a7a29c;
  border-top:1px solid rgba(201,158,103,.22);
}
.playmeta{
  display:flex;flex-wrap:wrap;align-items:center;gap:12px;margin-top:26px;
  font-family:var(--mono);font-size:var(--t-s);letter-spacing:var(--ls-5);text-transform:uppercase;color:#d6d2cd;
}
.playmeta i{width:4px;height:4px;background:var(--gold);border-radius:50%;display:block}
/* El botón de reservar. Va rojo y no dorado aunque la tarjeta entera sea de
   oro: el rojo es el color de comprar en toda la web —la píldora de la barra,
   el círculo de la portada, el botón de «entradas»— y aquí cambiarlo sería
   pedirle a alguien que aprenda un segundo color para hacer lo mismo. El oro se
   queda donde estaba: en el borde, en «by Casamor» y en los puntos del meta. */
.playbuy{margin-top:26px}

/* ═══ HOUSE CODE ════════════════════════════════════════════════════════ */
.codelist{list-style:none;margin:44px 0 0;padding:0;counter-reset:c}
.codelist li{
  display:grid;grid-template-columns:64px 1fr;gap:clamp(10px,3vw,30px);
  padding:clamp(20px,3.5vw,32px) 0;border-top:1px solid var(--line2);
}
.codelist li:last-child{border-bottom:1px solid var(--line2)}
.codelist .k{font-family:var(--mono);font-size:var(--t-m);letter-spacing:var(--ls-4);color:var(--red);padding-top:8px}
.codelist b{
  display:block;font-family:var(--display);font-weight:900;font-stretch:condensed;
  text-transform:uppercase;font-size:clamp(23px,4vw,38px);line-height:1.05;letter-spacing:var(--ls-t1);
}
.codelist p{margin:9px 0 0;color:#a9a5a0;font-size:var(--t-l);line-height:1.6;max-width:60ch}

/* ═══ TICKETS ═══════════════════════════════════════════════════════════ */
.sec-tick{background:linear-gradient(180deg,#000,#080808)}
.tlist{list-style:none;margin:38px 0 0;padding:0}
.tlist li{
  display:flex;align-items:baseline;gap:14px;padding:17px 0;border-top:1px solid var(--line2);
}
.tlist li:last-child{border-bottom:1px solid var(--line2)}
.tlist .nm{
  font-family:var(--display);font-weight:900;font-stretch:condensed;text-transform:uppercase;
  font-size:clamp(19px,3.2vw,29px);letter-spacing:var(--ls-t1);
}
.tlist .no{font-family:var(--mono);font-size:var(--t-xs);letter-spacing:var(--ls-4);text-transform:uppercase;color:var(--dim)}
.tlist .dots{flex:1;border-bottom:1px dotted rgba(255,255,255,.18);transform:translateY(-4px)}
.tlist .pr{font-family:var(--mono);font-size:clamp(16px,2.6vw,20px);letter-spacing:var(--ls-2);color:var(--bone);white-space:nowrap}
.tlist li.hot .pr{color:var(--gold)}
.tlist li.out{opacity:.35}
.tlist li.out .pr{text-decoration:line-through}
.tlist .so{font-family:var(--mono);font-size:var(--t-micro);letter-spacing:var(--ls-4);text-transform:uppercase;color:var(--red);border:1px solid rgba(227,6,19,.5);padding:3px 7px;border-radius:2px}
.tlist-sm .nm{font-size:clamp(14px,2.2vw,18px)}

/* Una sola columna. En agosto iban a dos, pero ahí cada línea llevaba un
   precio; aquí lleva dos —el Early Bird y el de después— más la nota del
   Playroom, y a media columna el nombre se partía en dos líneas y la guía de
   puntos desaparecía. Con cuatro tipos de entrada, una columna ancha se lee
   mejor y deja sitio a los dos precios. */
@media (min-width:820px){
  .sec-tick .wrap.narrow{max-width:1060px}
  .tlist li{padding:20px 0}
}

.tsafe{
  margin:16px 0 0;font-family:var(--mono);font-size:var(--t-s);letter-spacing:var(--ls-2);
  line-height:1.75;color:var(--dim);
}

/* ─── la tienda de CM.com, en un panel a pantalla completa ─── */
.shop{
  position:fixed;inset:0;z-index:600;background:#000;
  display:flex;flex-direction:column;
  animation:shopin .3s cubic-bezier(.2,.8,.3,1);
}
.shop[hidden]{display:none!important}
@keyframes shopin{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){.shop{animation:none}}

.shop-bar{
  display:flex;align-items:center;gap:clamp(10px,2vw,18px);flex:none;
  padding:12px var(--pad);padding-top:calc(12px + env(safe-area-inset-top));
  border-bottom:1px solid var(--line2);background:var(--ink2);
}
.shop-mark{width:22px;height:auto;flex:none;opacity:.95}
.shop-ttl{min-width:0;margin-right:auto}
.shop-ttl strong{
  display:block;font-family:var(--display);font-weight:900;font-stretch:condensed;
  text-transform:uppercase;font-size:clamp(15px,2.6vw,21px);line-height:1.1;letter-spacing:var(--ls-t1);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.shop-ttl span{
  display:block;margin-top:2px;font-family:var(--mono);font-size:var(--t-xs);
  letter-spacing:var(--ls-5);text-transform:uppercase;color:var(--gold);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.shop-tab{
  flex:none;font-family:var(--mono);font-size:var(--t-xs);letter-spacing:var(--ls-4);text-transform:uppercase;
  color:var(--dim);border:1px solid var(--line);border-radius:99px;padding:8px 14px;
  transition:.2s;
}
.shop-tab:hover{color:#fff;border-color:#fff}
@media (max-width:620px){.shop-tab{display:none}}
.shop-x{
  flex:none;width:40px;height:40px;border-radius:50%;border:1px solid var(--line);
  display:grid;place-items:center;font-size:var(--t-base);color:var(--dim);transition:.2s;
}
.shop-x:hover{color:#fff;border-color:#fff}

.shop-body{position:relative;flex:1;min-height:0;background:#fff}
.shop-frame{width:100%;height:100%;border:0;display:block;background:#fff}
.shop-frame[hidden]{display:none!important}
.shop-load{
  position:absolute;inset:0;margin:0;display:grid;place-content:center;justify-items:center;gap:16px;
  background:var(--ink);font-family:var(--mono);font-size:var(--t-s);letter-spacing:var(--ls-5);
  text-transform:uppercase;color:var(--dim);
}
.shop-load::before{
  content:"";width:26px;height:26px;border-radius:50%;
  border:1px solid rgba(255,255,255,.16);border-top-color:var(--red);
  animation:spin .8s linear infinite;
}
.shop-load[hidden]{display:none!important}

.shop-fail{
  position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;
  justify-content:center;text-align:center;gap:6px;padding:var(--pad);background:var(--ink);
}
.shop-fail[hidden]{display:none!important}
.shop-fail h3{
  font-family:var(--display);font-weight:900;font-stretch:condensed;text-transform:uppercase;
  font-size:clamp(22px,4.5vw,36px);line-height:1;letter-spacing:var(--ls-t2);margin:0 0 12px;
}
.shop-fail p{max-width:46ch;margin:0 0 26px;color:#a9a5a0;font-size:var(--t-base);line-height:1.65}

/* ═══ NEWSLETTER ════════════════════════════════════════════════════════ */
.sec-news{background:#000}
/* La columna del sello va fija y la del texto flexible: con `auto` el texto se
   comía el reparto y la otra colapsaba a 0. */
.newscard{
  position:relative;overflow:hidden;
  border:1px solid var(--line);border-radius:4px;
  padding:clamp(30px,6vw,58px);
  background:radial-gradient(100% 120% at 100% 0%,rgba(227,6,19,.14),transparent 60%),
             linear-gradient(180deg,#0b0708,#000);
  display:grid;
  grid-template-columns:minmax(0,1fr) clamp(132px,14vw,172px);
  gap:clamp(20px,3.5vw,44px);align-items:center;
}
/* el sello: el corazón dentro de un anillo de texto que gira */
.newstext{grid-area:1/1;min-width:0}
/* El titular de esta tarjeta NO puede ir al cuerpo de los demás. Los `.h2` de
   la página van a 84 px porque tienen delante una columna de 692; este tiene
   368 —la tarjeta le quita el relleno y el sello—, y a 84 px «ENTRA EL
   PRIMERO,» se partía en dos y el titular salía en tres líneas en vez de en
   dos.

   El número sale de medir, no de probar: «ENTRA EL PRIMERO,» —la línea larga,
   y en castellano, que es el idioma que manda aquí— ocupa **7,81 veces** el
   cuerpo de letra. En 368 px eso son 47 px de techo; 44 deja un 7% de aire. */
.newstext .h2{font-size:clamp(30px,4.6vw,44px);margin-bottom:16px}
.newsseal{grid-area:1/2;position:relative;width:100%;aspect-ratio:1}
.newsseal svg{
  width:100%;height:100%;display:block;
  animation:seal 26s linear infinite;
}
.newsseal text{
  fill:var(--gold);font-family:var(--mono);font-size:var(--t-s);
  text-transform:uppercase;   /* el espaciado lo reparte textLength */
}
.newsseal img{
  position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  width:44%;height:auto;opacity:.92;
}
.newsseal::after{
  content:"";position:absolute;inset:19%;border-radius:50%;
  border:1px solid rgba(227,6,19,.28);
}
@keyframes seal{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion:reduce){.newsseal svg{animation:none}}
@media (max-width:720px){
  .newscard{grid-template-columns:1fr;justify-items:center;text-align:center}
  .newsseal{grid-area:1/1;width:clamp(132px,42vw,180px)}
  .newstext{grid-area:2/1}
  .newsform{justify-content:center}
  .newscard .lead{margin-inline:auto}
}

.newsform{display:flex;gap:10px;margin-top:26px;flex-wrap:wrap}
.newsform input{
  flex:1;min-width:200px;background:rgba(255,255,255,.04);border:1px solid var(--line);
  border-radius:2px;padding:17px 18px;color:var(--bone);font-family:var(--mono);
  font-size:var(--t-base);letter-spacing:var(--ls-2);
}
.newsform input::placeholder{color:#5a5754}
.newsform input:focus{outline:none;border-color:var(--red);background:rgba(227,6,19,.06)}
.newsform .btn{padding:17px 30px}
.btn-round{border-radius:99px;padding-inline:34px}
.newsmsg{
  min-height:20px;margin:14px 0 0;font-family:var(--mono);font-size:var(--t-s);
  letter-spacing:var(--ls-4);text-transform:uppercase;color:var(--gold);
}
.newsmsg.bad{color:var(--red)}
/* Mientras el alta va de camino: el botón deja de aceptar clics para que nadie
   se apunte tres veces por impaciencia. */
.newsform.sending input,
.newsform.sending .btn{opacity:.5;pointer-events:none}

/* ═══ WHERE ═════════════════════════════════════════════════════════════ */
.sec-where{position:relative;overflow:hidden}
.wherebg{position:absolute;inset:0;z-index:0;pointer-events:none}
.wherebg img{
  width:100%;height:100%;object-fit:cover;object-position:50% 42%;
  filter:grayscale(.2) contrast(1.1) brightness(1.12);
}
.wherebg::after{
  content:"";position:absolute;inset:0;
  background:
    linear-gradient(180deg,#000 0%,rgba(0,0,0,.55) 24%,rgba(0,0,0,.6) 66%,#000 100%),
    linear-gradient(90deg,rgba(0,0,0,.82),rgba(0,0,0,.22) 60%);
}
@media (max-width:760px){
  .wherebg::after{
    background:linear-gradient(180deg,#000 0%,rgba(0,0,0,.7) 22%,rgba(0,0,0,.74) 70%,#000 100%);
  }
}

/* ═══ WHIP ══════════════════════════════════════════════════════════════ */
.sec-whip{background:#000;padding-bottom:clamp(90px,14vw,170px)}
.whipbtn{
  margin-top:28px;position:relative;z-index:0;
  font-family:var(--display);font-weight:900;font-stretch:condensed;text-transform:uppercase;
  font-size:clamp(16px,3vw,22px);letter-spacing:var(--ls-1);
  border:1px solid var(--red);color:var(--bone);padding:18px 40px;border-radius:99px;
  transition:.22s;overflow:hidden;
}
.whipbtn::before{
  content:"";position:absolute;inset:0;background:var(--red);transform:scaleX(0);transform-origin:left;
  transition:transform .35s cubic-bezier(.2,.8,.3,1);z-index:-1;
}
.whipbtn:hover{color:#fff}
.whipbtn:hover::before{transform:scaleX(1)}
.whipbtn:active{transform:scale(.97)}
.whipbtn>span{position:relative;z-index:1}
/* el mismo botón, pero en la portada: más bajo y con brillo para que se lea
   sobre la foto. Sin background propio: el relleno del hover va en ::before. */
.whipbtn-hero{
  position:relative;z-index:3;
  margin-top:clamp(14px,2.6vh,30px);
  padding:clamp(12px,1.8vh,16px) clamp(26px,4vw,40px);
  font-size:clamp(13px,2.2vw,17px);letter-spacing:var(--ls-2);
  box-shadow:0 0 34px rgba(227,6,19,.26),inset 0 0 26px rgba(227,6,19,.10);
}
.whipbtn-hero:hover{box-shadow:0 0 52px rgba(227,6,19,.45)}
.whiphint{margin:16px 0 0;font-family:var(--mono);font-size:var(--t-s);letter-spacing:var(--ls-5);
  text-transform:uppercase;color:#4c4a48}
.whiphint[hidden]{display:none}
.whipcount{margin-top:18px;font-family:var(--mono);font-size:var(--t-s);letter-spacing:var(--ls-5);text-transform:uppercase;color:var(--dim)}
.whipcount b{color:var(--red);font-size:var(--t-base);font-weight:400}

/* el telón: apaga la página entera para que la frase del latigazo se lea */
/* ═══ LA PUERTA ═════════════════════════════════════════════════════════════
   El «¿tienes 18?» convertido en la puerta del club: lo primero que se ve, y
   el botón de «sí» es el látigo.

   **Es negra, y aquí hubo una roja con el recorte del cartel de fondo.** No
   colaba, y no por fea: era la portada otra vez. Quien pulsa se encuentra tres
   segundos después con el mismo rojo, el mismo recorte y el mismo círculo, y
   entonces el latigazo no ha abierto nada —parece que la web se ha recargado—.
   Una puerta tiene que ser **otro sitio** que la sala: si enseña la sala, no
   es una puerta, es una capa encima de la sala.

   Así que negra y sin foto: la marca en blanco, la pregunta y un círculo rojo.
   El rojo se guarda entero para lo que hay detrás, y el salto de negro a rojo
   —con el latigazo en medio— es lo que hace que entrar se note.

   **z-index 790, y el número importa.** Va por encima de todo lo de la página
   (la barra de arriba, la de abajo, la tienda) y por DEBAJO del telón del
   látigo (798), del fogonazo (800) y de la frase (801). Así, al pulsar, el
   latigazo se pinta encima de la puerta y la puerta se retira con la pantalla
   ya en negro: no se ve desaparecer nada, se ve un latigazo. El grano (900)
   también queda por encima, que es lo que hace que la puerta tenga la misma
   textura que el resto.
   ---------------------------------------------------------------------------- */
.gated,.gated body{overflow:hidden}

.gate{
  position:fixed;inset:0;z-index:790;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  text-align:center;
  padding:calc(28px + env(safe-area-inset-top)) var(--pad)
          calc(28px + env(safe-area-inset-bottom));
  background:#000;color:var(--bone);
  overflow:hidden;
  transition:opacity .45s ease;
}
.gate.gone{opacity:0;pointer-events:none}

/* Un rescoldo, no una foto. Sin nada, el negro a pantalla completa se lee como
   una página que no ha cargado; con dos radiales muy flojos —rojo arriba, donde
   está la marca, y un poso por abajo— se lee como una sala a oscuras, que es lo
   que hay al otro lado de una puerta. Es la misma receta que `.hero-glow`, a la
   mitad de fuerza. */
.gate::before{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:
    radial-gradient(90% 60% at 50% 0%,   rgba(227,6,19,.22), transparent 64%),
    radial-gradient(70% 50% at 50% 108%, rgba(227,6,19,.10), transparent 62%);
}
.gate-in{position:relative;z-index:1;width:100%;max-width:640px}

/* El lockup, a media escala: aquí es la firma de quien pregunta, no la marca de
   cabecera. Y hay que deshacerle a mano dos reglas del bloque de la portada
   roja —la chapa de MEETS en negro y la sombra granate de los logotipos—, que
   están escritas sin acotar a `.hero` porque hasta ahora el lockup sólo vivía
   allí. Sobre negro vuelven a ser las de siempre. */
.gate-lockup{margin:0 0 clamp(20px,4vh,38px)}
.gate-lockup .lk-symb{height:clamp(34px,5.4vh,52px)}
.gate-lockup .lk-ut{height:clamp(17px,2.6vh,25px)}
.gate-lockup img{filter:drop-shadow(0 0 60px rgba(227,6,19,.34))}
.gate-lockup .lk-meets{background:var(--bone);color:#000;box-shadow:0 0 34px rgba(227,6,19,.34)}

/* El rótulo pequeño de encima. Sólo lo usa la pantalla del rebote: en la
   pregunta, el `+18` ya hace de rótulo y uno encima de otro serían dos. */
.gate-kicker{
  margin:0 0 clamp(8px,1.4vh,14px);
  font-family:var(--mono);font-size:var(--t-s);letter-spacing:var(--ls-6);
  text-transform:uppercase;color:var(--dim);
}

/* El `+18` es la pieza grande y la pregunta va debajo, no al revés, y ese
   reparto es el del cartel de un club: primero la marca —que se reconoce de un
   vistazo y no hay que leerla— y luego la letra, que es la que dice exactamente
   qué se está preguntando.

   Antes la pieza grande era «¿Tienes 18?», que es una frase de barra: se lee
   rápido y se contesta sin pensar, que es justo lo contrario de lo que tiene
   que hacer una verificación de edad. La pregunta entera está ahora escrita
   como se escribe, y el guiño se ha ido al subtítulo y al botón.

   Todo se mide contra el ALTO además de contra el ancho: la puerta no tiene
   scroll —el `overflow:hidden` del `.gated` lo impide—, así que lo que crezca
   de más se pierde, y en un teléfono corto lo primero que se perdería es el
   botón de entrar. */
.gate-mark{
  margin:0 0 clamp(6px,1.2vh,14px);
  font-family:var(--display);font-weight:900;font-stretch:condensed;
  line-height:.86;letter-spacing:var(--ls-t2);
  font-size:clamp(58px,min(17vw,13vh),136px);
  color:var(--bone);
}
.gate-q{
  margin:0 0 clamp(10px,1.8vh,18px);
  font-family:var(--display);font-weight:900;font-stretch:condensed;
  text-transform:uppercase;line-height:1.02;letter-spacing:var(--ls-t1);
  font-size:clamp(19px,min(5.2vw,3.4vh),34px);
  color:var(--bone);
}
/* El guiño va en la grotesca del cartel y no en la Power Grotesk pequeña: es un
   escalón del titular, no un pie. */
.gate-sub{
  margin:0 0 clamp(20px,3.6vh,36px);
  font-family:var(--display);font-weight:900;font-stretch:condensed;
  text-transform:uppercase;line-height:1.16;letter-spacing:var(--ls-t1);
  font-size:clamp(13px,min(3.6vw,2.3vh),21px);color:#a9a5a0;
}

/* ── el botón de sí ─────────────────────────────────────────────────────────
   Es el círculo de la portada, y sobre negro es el ROJO de siempre: la misma
   pieza con la que se compran las entradas, que es lo que la hace reconocible
   tres segundos después, cuando aparece otra vez en el hero.

   **En el móvil era demasiado pequeño y demasiado quieto.** Medía 219 px con la
   letra a 19, que son las medidas que hereda de `.btn-circle` —pensadas para
   dos círculos que conviven con una portada entera—, y aquí no compite con
   nada: es lo único que se puede pulsar en toda la pantalla. Un botón que es la
   única salida tiene que mandar como tal.

   Ahora se mide contra el ancho **y** contra el alto (`min(72vw, 34vh)`): en un
   teléfono normal sale a 260 px, un 20% más, y en uno corto encoge con la
   pantalla en vez de comerse el pie. Y el cuerpo de letra sube de 19 a 27, que
   es lo que hace que «DA EL LATIGAZO» llene el círculo en lugar de flotar en
   medio. El relleno baja a la vez: si sube la letra y no baja el relleno, lo
   que se gana en cuerpo se pierde en líneas. */
.gate-yes{
  width:clamp(168px,min(72vw,34vh),260px);
  padding:clamp(18px,4.4vw,34px);
  font-size:clamp(20px,min(7vw,3.4vh),34px);
}
.gate-yes small{opacity:.72;font-size:clamp(10px,min(2.8vw,1.4vh),13px)}

/* ── y el latido ─────────────────────────────────────────────────────────────
   Un halo rojo que respira: el círculo se lee **encendido** sobre el negro en
   vez de pegado a él. Es lo que le faltaba: en un móvil no hay puntero, así que
   el aro de puntos de `.btn-circle::before` —que se enciende al pasar por
   encima— no se ve nunca, y sin él el círculo era una mancha quieta en una
   pantalla quieta. Nada decía que se pudiera tocar.

   **Empezó siendo un anillo que salía del borde y se desvanecía**, el gesto de
   notificación de toda la vida, y en pantalla no se veía. El motivo es de
   dibujo y no de código: un anillo así arranca con radio CERO —o sea, debajo
   del botón, tapado— y para cuando ha crecido lo suficiente para asomar ya va
   por la mitad de su opacidad. Lo único que se llegaba a ver era un hilo rojo
   al 20%. Comprobado congelando la animación en dos puntos del ciclo: en los
   dos, nada.

   Un halo que respira no tiene ese problema porque **no depende de crecer**:
   está siempre ahí, y lo que cambia es cuánto. Va en el `::after` y no en el
   botón para no pisarle el `box-shadow` del hover, que es otra cosa y en el
   escritorio sí se ve.

   Se apaga al pulsar —ya no hay nada que anunciar— y con `prefers-reduced-
   motion`, donde algo latiendo cada tres segundos es exactamente lo que ese
   ajuste pide que no pase. */
.gate-yes::after{
  content:"";position:absolute;inset:0;border-radius:50%;z-index:-1;
  animation:gateglow 2.8s ease-in-out infinite;
}
@keyframes gateglow{
  0%,100%{box-shadow:0 0 30px 4px rgba(227,6,19,.30)}
  50%    {box-shadow:0 0 68px 14px rgba(227,6,19,.62)}
}
/* El hundido del dedo. `.btn` ya trae la transición, así que esto es sólo el
   estado; sin él, en un móvil no hay ninguna respuesta entre tocar y que suene
   el látigo, y ahí pueden pasar hasta 450 ms. */
.gate-yes:active{transform:scale(.95)}

/* Al pulsar se hunde y ahí se queda: entre el clic y el chasquido pasan hasta
   450 ms —lo que tarde en restallar la grabación que toque— y sin esta señal
   ese medio segundo se lee como que no ha pasado nada y se vuelve a pulsar. */
.gate.cracked .gate-yes{transform:scale(.96);opacity:.85;pointer-events:none}
.gate.cracked .gate-yes::after{animation:none;box-shadow:none}
@media (prefers-reduced-motion:reduce){
  .gate-yes::after{animation:none;box-shadow:none}
}

/* `width:max-content` y no `display:block` a secas: el subrayado de un bloque
   centrado con `margin:auto` se va de lado a lado de la columna —640 px de raya
   debajo de cuatro palabras—, y lo que tiene que subrayar es el texto. */
.gate-no{
  display:block;width:max-content;max-width:100%;
  margin:clamp(16px,2.6vh,24px) auto 0;padding:9px 4px 6px;
  font-family:var(--mono);font-size:var(--t-s);letter-spacing:var(--ls-4);
  text-transform:uppercase;color:var(--dim);
  border-bottom:1px solid var(--line);transition:.2s;
}
.gate-no:hover,.gate-no:focus-visible{color:var(--bone);border-bottom-color:var(--bone)}

.gate-foot{
  margin:clamp(24px,4.4vh,44px) auto 0;max-width:46ch;
  font-family:var(--mono);font-size:var(--t-xs);line-height:1.5;
  letter-spacing:var(--ls-2);color:#6b6764;
}

/* ── el otro lado ────────────────────────────────────────────────────────────
   Sin marca, sin botón y sin nada de la fiesta: una pantalla que sigue
   enseñándola a quien no puede entrar está diciendo lo contrario de lo que
   acaba de decir. La frase sube a ser la pieza grande porque es lo único que
   hay que leer, y debajo va el enlace al que se va sola en 2,4 s. */
.gate-bounce .gate-q{font-size:clamp(30px,min(9vw,6.4vh),62px);line-height:.98}
.gate-bed{margin:clamp(22px,4vh,38px) 0 0}
.gate-bed a{
  display:inline-block;padding:12px 26px;border-radius:99px;
  border:1px solid var(--red);color:var(--bone);
  font-family:var(--display);font-weight:900;font-stretch:condensed;
  text-transform:uppercase;font-size:clamp(13px,2.2vw,17px);letter-spacing:var(--ls-2);
  transition:.22s;
}
.gate-bed a:hover,.gate-bed a:focus-visible{background:var(--red);color:#fff}

/* El foco se le pone a mano al bloque del rebote para que un lector de pantalla
   lea la respuesta en vez de quedarse en un botón que ya no está en la vista.
   Pero el bloque no es un control y nadie ha tabulado hasta él, así que el aro
   del navegador aquí no informa de nada: dibuja un recuadro alrededor de media
   pantalla. Se quita sólo en este caso —el de un contenedor con `tabindex="-1"`
   enfocado por código—, nunca en los botones. */
.gate:focus,.gate-in:focus{outline:none}

.whipveil{
  position:fixed;inset:0;z-index:798;pointer-events:none;opacity:0;
  background:radial-gradient(120% 95% at 50% 50%,rgba(0,0,0,.9),#000 68%);
}
.whipveil.go{animation:wveil 1.5s cubic-bezier(.2,.8,.3,1)}
@keyframes wveil{
  0%{opacity:0}
  8%{opacity:1}
  66%{opacity:1}
  100%{opacity:0}
}

.slash{
  position:fixed;inset:0;z-index:800;pointer-events:none;opacity:0;
  background:linear-gradient(105deg,transparent 42%,rgba(255,255,255,.95) 49%,rgba(227,6,19,.9) 51%,transparent 58%);
  mix-blend-mode:screen;
}
.slash.go{animation:slash .42s cubic-bezier(.2,.8,.3,1)}
@keyframes slash{
  0%{opacity:0;transform:translateX(-40%) scaleY(1.4)}
  22%{opacity:1}
  100%{opacity:0;transform:translateX(45%) scaleY(1.4)}
}
.whipword{
  position:fixed;left:50%;top:50%;transform:translate(-50%,-50%) scale(.9);z-index:801;
  font-family:var(--display);font-weight:900;font-stretch:condensed;text-transform:uppercase;
  font-size:clamp(26px,7vw,64px);letter-spacing:var(--ls-t2);text-align:center;line-height:1;
  color:#fff;text-shadow:0 0 40px rgba(227,6,19,.8);pointer-events:none;opacity:0;
  padding:0 24px;max-width:90vw;
}
.whipword.go{animation:wword 1.5s cubic-bezier(.2,.8,.3,1)}
@keyframes wword{
  0%{opacity:0;transform:translate(-50%,-50%) scale(1.25)}
  12%{opacity:1;transform:translate(-50%,-50%) scale(1)}
  70%{opacity:1}
  100%{opacity:0;transform:translate(-50%,-50%) scale(1)}
}
/* ── las frases, en el móvil ─────────────────────────────────────────────────
   La frase se pinta sola sobre el telón negro: es lo ÚNICO que hay en pantalla
   durante ese segundo y medio, y aun así iba a 27 px en un teléfono —7vw, que
   es una medida pensada para que no reventara en una tablet—. Un titular a
   cuerpo de pie de foto en medio de una pantalla vacía no es un golpe, es una
   nota.

   A 12vw sale a 47 px y ocupa dos o tres líneas, que es lo que tiene que
   ocupar: el látigo restalla y aparece una frase a tamaño de cartel. El
   interlineado baja a 0,94 porque a ese cuerpo el de 1 abre demasiado, y el
   resplandor rojo sube y se dobla —uno ancho para el ambiente y otro pegado a
   la letra para el contorno—, que es lo que la despega del negro sin
   emborronarla.

   `max-width` sube de 90 a 94vw: con la letra más grande, el 90% dejaba una
   palabra larga partida por la mitad. */
@media (max-width:760px){
  .whipword{
    font-size:clamp(34px,12vw,56px);
    line-height:.94;
    padding:0 16px;max-width:94vw;
    text-shadow:0 0 60px rgba(227,6,19,.85),0 0 16px rgba(227,6,19,.55);
  }
}

@media (prefers-reduced-motion:reduce){
  .slash.go,.whipword.go{animation-duration:.01s}
  .whipveil.go{animation-duration:.9s}
}

/* ═══ FOOTER ════════════════════════════════════════════════════════════ */
.foot{
  border-top:1px solid var(--line2);padding:clamp(56px,9vw,96px) var(--pad) calc(46px + env(safe-area-inset-bottom));
  text-align:center;background:#000;
}

/* la marca paraguas, separada de la de la fiesta */
/* ahora abre el pie: sin la raya de separación, que ya no separa de nada */
.circleblock{margin:0 auto clamp(32px,5vw,46px);max-width:560px}
.circlekick{
  margin:0 0 16px;font-family:var(--mono);font-size:var(--t-xs);letter-spacing:var(--ls-7);
  text-transform:uppercase;color:#4c4a48;
}
.circlemark{width:min(72%,340px);height:auto;margin:0 auto;opacity:.72;transition:opacity .3s}
.circlemark:hover{opacity:1}
.circleline{
  margin:20px auto 0;max-width:48ch;font-size:var(--t-base);line-height:1.7;color:#6b6764;
}
.footnote{max-width:56ch;margin:0 auto 28px;font-size:var(--t-m);line-height:1.7;color:#4c4a48}
.credit{display:inline-flex;align-items:baseline;gap:7px}
.credit span{font-family:var(--mono);font-size:var(--t-xs);letter-spacing:var(--ls-5);text-transform:uppercase;color:#4c4a48}
.credit b{font-family:var(--brand);font-weight:700;text-transform:lowercase;font-size:var(--t-l);letter-spacing:0;color:var(--bone);transition:color .2s}
.credit:hover b{color:var(--red)}

/* ═══ BARRA DE ABAJO (sólo móvil) ═══════════════════════════════════════
   Lo que hace falta durante la noche, a un pulgar de distancia. Aparece
   justo donde el menú de arriba se esconde.
   ═══════════════════════════════════════════════════════════════════════ */
.tabbar{display:none}
@media (max-width:860px){
  .tabbar{
    position:fixed;left:0;right:0;bottom:0;z-index:130;
    display:grid;grid-template-columns:repeat(5,1fr);
    background:rgba(0,0,0,.9);backdrop-filter:blur(18px) saturate(140%);
    border-top:1px solid var(--line2);
    padding-bottom:env(safe-area-inset-bottom);
  }
  .tabbar a{
    display:flex;flex-direction:column;align-items:center;justify-content:center;gap:5px;
    padding:9px 3px;color:#6f6b68;transition:color .2s;min-height:56px;
  }
  .tabbar svg{
    width:21px;height:21px;fill:none;stroke:currentColor;stroke-width:1.5;
    stroke-linejoin:round;stroke-linecap:round;transition:transform .25s;
  }
  .tabbar svg .c,.tabbar svg .d{stroke-width:1.7}
  .tabbar span{
    font-family:var(--mono);font-size:var(--t-micro);letter-spacing:var(--ls-2);text-transform:uppercase;
    /* El overflow:hidden es para el ellipsis de las etiquetas largas, pero con
       line-height:1 recortaba también por arriba: el acento de la Ó de «CÓMO»
       se salía de la caja y desaparecía. Con 1.35 cabe y no mueve nada, porque
       el enlace centra en columna. */
    line-height:1.35;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  }
  .tabbar a.on{color:var(--bone)}
  .tabbar a.on svg{stroke:var(--red);transform:translateY(-1px)}
  .tabbar a:active svg{transform:scale(.9)}
  .tab-buy{color:#c9948f}
  .tab-buy svg{stroke:var(--red)}
  .tab-buy.on{color:#fff}

  /* que la barra no se coma ni el final de la página ni el botón de bajar */
  .foot{padding-bottom:calc(46px + 62px + env(safe-area-inset-bottom))}
  .scrollhint{bottom:calc(20px + 56px + env(safe-area-inset-bottom))}
  /* ...ni el botón del látigo, que va justo encima */
  .hero{padding-bottom:calc(150px + env(safe-area-inset-bottom))}


  /* del hint de bajar solo se queda la línea roja. El texto oculto para
     lectores de pantalla sigue ahí, así que el botón conserva su nombre;
     el min-width es para que siga siendo un objetivo tocable */
  .scrollhint b{display:none}
  .scrollhint{min-width:48px;align-items:center}
  .hero{padding-bottom:calc(90px + 56px + env(safe-area-inset-bottom))}
}

/* ═══ OBJETOS 3D ════════════════════════════════════════════════════════
   Igual que en Infinity: paneles fijos de 44vw por toda la altura de la
   ventana, pegados a un lado y fuera de pantalla. El scroll les da la
   posición y la opacidad (ver assets/obj3d.js). No tapan nada porque no
   reciben el puntero. En móvil salen igual, con el panel más ancho.
   ═══════════════════════════════════════════════════════════════════════ */
.scroll-obj{
  position:fixed;top:0;bottom:0;
  width:44vw;z-index:1;pointer-events:none;   /* siempre entre fondo y texto */
  will-change:transform,opacity;opacity:0;
}
.scroll-obj.s-left  {left:-2vw}
.scroll-obj.s-right {right:-2vw}
.scroll-obj.s-bottom{left:0;right:0;width:auto}
.scroll-obj canvas  {width:100%;height:100%;display:block}

/* en móvil el panel ocupa el ancho entero: 44vw en un teléfono son cuatro
   dedos y el objeto salía recortado. La cámara se encarga del resto (ver
   fitCamera en obj3d.js). */
@media (max-width:768px){
  .scroll-obj{width:100vw}
  .scroll-obj.s-left {left:0}
  .scroll-obj.s-right{right:0}
}
@media (prefers-reduced-motion:reduce){
  .scroll-obj{will-change:opacity}
}

/* ═══ SHEET ═════════════════════════════════════════════════════════════ */
.sheetwrap{
  position:fixed;inset:0;z-index:400;background:rgba(0,0,0,.82);backdrop-filter:blur(10px);
  display:flex;align-items:flex-end;justify-content:center;padding:0;
}
.sheetwrap[hidden]{display:none}
.sheet{
  width:100%;max-width:620px;background:#0a0a0a;border:1px solid var(--line);
  border-radius:6px 6px 0 0;padding:clamp(24px,5vw,40px);
  padding-bottom:calc(clamp(24px,5vw,40px) + env(safe-area-inset-bottom));
  max-height:88svh;overflow:auto;animation:up .34s cubic-bezier(.2,.8,.3,1);
}
@media (min-width:720px){
  .sheetwrap{align-items:center;padding:24px}
  .sheet{border-radius:6px}
}
@keyframes up{from{transform:translateY(26px);opacity:0}to{transform:none;opacity:1}}
.sheet .x{position:absolute;top:14px;right:16px;font-family:var(--mono);font-size:var(--t-s);letter-spacing:var(--ls-4);color:var(--dim)}
.sheet .st{font-family:var(--mono);font-size:var(--t-s);letter-spacing:var(--ls-5);text-transform:uppercase;color:var(--red);margin:0 0 10px}
.sheet h3{
  font-family:var(--display);font-weight:900;font-stretch:condensed;text-transform:uppercase;
  font-size:clamp(28px,6vw,48px);line-height:.95;letter-spacing:var(--ls-t2);margin:0 0 14px;
}
.sheet .sm{display:flex;flex-wrap:wrap;gap:10px;margin-bottom:20px}
.sheet .sm span{font-family:var(--mono);font-size:var(--t-xs);letter-spacing:var(--ls-4);text-transform:uppercase;border:1px solid var(--line);padding:6px 11px;border-radius:2px;color:var(--dim)}
.sheet p{color:#b7b3ae;font-size:var(--t-base);line-height:1.66;margin:0 0 18px}
.sheet .close{
  width:100%;border:1px solid var(--line);border-radius:2px;padding:14px;
  font-family:var(--mono);font-size:var(--t-s);letter-spacing:var(--ls-5);text-transform:uppercase;color:var(--dim);
}
.sheet .close:hover{border-color:var(--bone);color:var(--bone)}
.sheet .gobtn{
  width:100%;background:var(--red);color:#fff;border-radius:2px;padding:15px;margin-bottom:10px;
  font-family:var(--mono);font-size:var(--t-s);letter-spacing:var(--ls-5);text-transform:uppercase;
  transition:background .2s,color .2s;
}
.sheet .gobtn:hover{background:#fff;color:#000}
.sheet img.sf{width:100%;border-radius:3px;margin-bottom:20px;aspect-ratio:320/432;object-fit:cover;object-position:50% 22%}
/* la del artista es de sala, no un look: apaisada y centrada */
.sheet img.sf.wide{aspect-ratio:16/10;object-position:50% 50%}

/* ═══ reveal on scroll ══════════════════════════════════════════════════ */
.rv{opacity:0;transform:translateY(22px);transition:opacity .7s cubic-bezier(.2,.8,.3,1),transform .7s cubic-bezier(.2,.8,.3,1)}
.rv.in{opacity:1;transform:none}
@media (prefers-reduced-motion:reduce){.rv{opacity:1;transform:none;transition:none}}

/* ═══ STELLA BOSSI ══════════════════════════════════════════════════════════
   Su propia sección, la 03. Estuvo un rato en la 01, de relleno del canalón
   que dejaba la columna de texto, y estaba mal: ahí era decoración de la
   sección de otra cosa. Aquí el texto habla de ella, así que la foto no
   acompaña, manda —y por eso va más grande que cuando era un adorno.

   Recortada y a tamaño de cartel, apoyada en el borde de abajo como si
   estuviera de pie en la sección.

   Tres cosas que la hacen funcionar y no estorbar:

   · Va **detrás** del texto y sin capturar el ratón. La columna de texto no se
     mueve ni un píxel por ella; si la ventana se estrecha, la que se aparta es
     ella.
   · Se **funde a negro por abajo** con una máscara. Sin eso se ve el corte
     recto del recorte contra el fondo, que es lo que delata un PNG pegado.
   · Lleva **su rojo detrás**: un resplandor que la despega del negro y la ata
     al rojo de la casa. Sin él, un recorte sobre negro plano parece una
     pegatina.
   ═══════════════════════════════════════════════════════════════════════════ */
.sec-stella{
  position:relative;overflow:hidden;
  /* `isolation:isolate` crea contexto de apilamiento, y **hace falta desde que
     esta sección tiene fondo propio**. La foto va con `z-index:-1` para quedar
     por detrás del texto; sin contexto aquí, ese -1 la manda al contexto raíz y
     se va por detrás del fondo de la propia sección: desaparece del todo.
     Con el contexto, el -1 se queda dentro y significa lo que tiene que
     significar —detrás del texto, delante del fondo—. */
  isolation:isolate;
  /* **El fondo es de la sección, no de ella.** Antes el rojo salía de un
     `::before` colgado de la propia foto, y en el móvil eso se descoloca: allí
     la foto pasa a ser un float, o sea deja de estar posicionada, y su
     `::before` absoluto se calcula entonces contra la sección entera. El
     resplandor acababa donde acababa, de rebote.

     Ahora el resplandor es de la sección y punto. Detrás del recorte se ve
     exactamente el fondo de la sección, que es lo que tiene que verse detrás de
     un PNG. El foco cae a la derecha porque es donde está ella, en las dos
     pantallas. */
  background:
    radial-gradient(88% 66% at 72% 34%, rgba(227,6,19,.17), transparent 70%),
    linear-gradient(180deg, #0a0506 0%, #000 74%);
}
/* `position:static` en la columna, **sólo aquí**, y no es un detalle: `.wrap`
   lleva `position:relative` de serie para toda la página, y con la foto viviendo
   ahora dentro de la columna eso la convertía en su bloque contenedor. El
   `position:absolute` de escritorio se calculaba entonces contra los 692 px de
   la columna en vez de contra la sección entera, y la foto se plantaba en medio
   del texto en lugar de irse al canalón.

   Se pierde el `z-index:2` de la columna, y da igual: que el texto quede por
   encima de la foto lo resuelve el orden del HTML —la foto va antes, se pinta
   antes—, que es como funcionaba de todas formas. */
.sec-stella .wrap{position:static}
/* La columna se descentra a la izquierda **sólo aquí**, y sólo donde la foto
   ocupa el canalón de la derecha. Centrada dejaba el mismo aire a los dos lados
   como si a la derecha no hubiera nada, y sí lo hay: ella.

   El margen **no es un número elegido a ojo**: es exactamente donde empieza la
   columna ancha del resto de la página. `.wrap` normal —la de «quién pincha y
   cuándo»— mide `--maxw` (1240) y va centrada, así que su borde izquierdo cae en
   `(100vw − 1240) / 2`. Pidiéndole eso a la columna estrecha de aquí, las dos
   arrancan en la misma vertical y la página no da un salto al pasar de una
   sección a la otra. El `max(0px, …)` es para cuando la ventana es más estrecha
   que 1240: ahí la columna ancha ya toca el borde y el margen tiene que ser
   cero, no negativo. */
@media (min-width:1181px){
  .sec-stella .wrap{
    margin-left:max(0px,calc((100vw - var(--maxw)) / 2));
    margin-right:auto;
  }
  /* Con el texto corrido a la izquierda sobra sitio a la derecha, así que ella
     se mueve hacia allí. **Se mueve con el margen, no creciendo**: el primer
     intento la ensanchó y su alto se pasó del alto de la sección —1082 px de
     foto contra 968 de sección a 1440—, así que el `overflow:hidden` le cortaba
     la cabeza. El tope de 435 px es el ancho al que su alto (×2,21) cabe justo
     en la sección; de ahí en adelante quien la mueve es el `right`. */
  .sec-stella .stella{right:clamp(0px,7vw,150px);width:clamp(230px,30vw,435px)}
}
/* Su logotipo hace de titular. Va al ancho, no al alto: es un garabato casi
   cuadrado (414x347) y lo que tiene que casar es el ancho de la columna, igual
   que el de Symbiotikka dos secciones más arriba. */
.stellah{margin:6px 0 clamp(18px,2.8vw,28px)}
.stellah img{
  width:clamp(190px,26vw,340px);height:auto;display:block;
  filter:drop-shadow(0 3px 26px rgba(0,0,0,.9));
}
.stella{
  /* No va pegada al borde: a ras el brazo derecho se corta justo por la mano y
     parece un descuido en vez de una sangría. Un dedo de aire y se lee entera. */
  /* `z-index:-1` y no 0: un elemento **posicionado** con z-index 0 se pinta por
     encima del contenido que no está posicionado, así que con 0 se comía los
     párrafos. Con -1 se va detrás del texto pero sigue por delante del fondo de
     la sección, que es donde tiene que estar. */
  position:absolute;right:0;bottom:0;z-index:-1;pointer-events:none;
  /* Manda el **ancho**, no el alto. Es lo que parece al revés y no lo es: el
     hueco que hay que llenar es el canalón que deja la columna de texto, y ese
     canalón mide (ancho de página − 692) / 2, o sea ~26vw en cuanto la columna
     toca su tope. Atarla al alto de la sección la hacía crecer con el texto
     —en una página larga salía de tres metros y se comía la columna—; atada al
     ancho, ocupa siempre el mismo canalón mida lo que mida la sección.
     El alto sale de la proporción (679x1500). */
  /* El ancho **es** el del canalón, calculado, no elegido a ojo: la columna de
     texto mide 692 px como mucho, así que a cada lado sobra `(100vw − 692) / 2`.
     Pidiendo exactamente eso, la foto llena el hueco y no toca una sola línea
     de texto. Con un número fijo había que elegir entre dejar aire en pantallas
     anchas o comerse el texto en las estrechas. */
  width:clamp(200px,calc((100vw - 692px) / 2),460px);
}
.stella img{
  width:100%;height:auto;display:block;
  /* `drop-shadow` sigue la **silueta** del PNG, no su caja, así que le dibuja un
     halo alrededor del cuerpo. En el canalón de escritorio, sobre negro, eso la
     despega del fondo y está bien. Sobre el fondo de la sección era otra cosa:
     un cerco negro pegado a ella, que es justo lo que no se quiere detrás de un
     recorte. Aquí se queda suave; en el móvil se va del todo (más abajo). */
  filter:contrast(1.06) saturate(1.06) drop-shadow(-16px 0 40px rgba(0,0,0,.5));
  -webkit-mask-image:linear-gradient(180deg,#000 62%,rgba(0,0,0,.55) 88%,transparent 100%);
          mask-image:linear-gradient(180deg,#000 62%,rgba(0,0,0,.55) 88%,transparent 100%);
}
/* Por debajo de 1180 la columna de texto ya llega donde está ella, así que
   deja de ser una figura al lado y pasa a ser fondo: se aparta hacia fuera,
   baja de opacidad y suelta la etiqueta, que ahí sí se cruzaría con el texto. */
@media (max-width:1180px){
  .stella{right:-5%;width:clamp(190px,27vw,360px);opacity:.34}
}

/* ── en el móvil, un float ───────────────────────────────────────────────────
   Aquí estaba de fondo, al 30% y detrás del texto, y era exactamente lo que no
   tenía que ser: **el texto la tapaba**. En su propia sección la foto no es
   ambiente, es el asunto.

   Así que en vertical deja de estar posicionada y pasa a ser un `float:right`.
   Un float es lo único que hace que el texto **la rodee** en vez de pasarle por
   encima: es literalmente para lo que existe. Y como el float arranca donde
   está escrito —justo antes del logotipo—, su cabeza queda alineada con él sin
   que haya que ajustar ningún número.

   El margen derecho negativo la saca un poco por el canto de la pantalla: sin
   él se queda un ladrillo de 42vw en medio y la columna de texto se ahoga.
   ---------------------------------------------------------------------------- */
@media (max-width:760px){
  .stella{
    position:static;float:right;
    width:42vw;max-width:210px;opacity:1;
    margin:0 -9% 6px 16px;
    shape-outside:margin-box;
  }
  /* Sin sombra: aquí no está sobre el negro del canalón, está sobre el fondo de
     la sección, y el halo que la despegaba allí aquí sólo tapa ese fondo.

     La máscara sube: en el móvil se ve de cintura para arriba y lo que sobra se
     va fundiendo antes, para que el texto recupere el ancho completo cuanto
     antes. */
  .stella img{
    filter:contrast(1.06) saturate(1.06);
    -webkit-mask-image:linear-gradient(180deg,#000 46%,rgba(0,0,0,.5) 74%,transparent 96%);
            mask-image:linear-gradient(180deg,#000 46%,rgba(0,0,0,.5) 74%,transparent 96%);
  }
}

/* ═══ SYMBIOTIKKA ═══════════════════════════════════════════════════════════
   Misma tarjeta que el Playroom, pero girada: la foto entra por la derecha y
   el degradado apaga ese lado en vez del izquierdo. Así las dos tarjetas de la
   página se leen como una familia sin ser la misma imagen dos veces.
   ═══════════════════════════════════════════════════════════════════════════ */
/* ═══ SYMBIOTIKKA ═══════════════════════════════════════════════════════════
   Antes esto era una tarjeta: un rectángulo con borde, esquinas redondeadas y
   una foto de pista metida dentro. El problema no era el estilo, era el
   formato: una caja dice «ficha», y esta sección no es una ficha, es la única
   prueba que da la web de qué es Symbiotikka.

   Así que fuera la caja. Es una banda a sangre —el mismo patrón que
   `.sec-where`— con el vídeo de fondo a toda pantalla y el texto encima, en la
   misma columna estrecha que el resto de la página. Sin borde, sin panel y sin
   nada que lo separe de la sección de al lado más que el propio fondo.
   ═══════════════════════════════════════════════════════════════════════════ */
.sec-symb{position:relative;overflow:hidden}
.symbbg{position:absolute;inset:0;z-index:0;pointer-events:none;background:#000}

/* La foto, a sangre. Un <img> normal con `object-fit:cover`: llena la sección
   entera, sin franjas ni máscaras. Aquí hubo un vídeo y antes un iframe de
   YouTube, y cada uno traía su propio apaño para encajar —unidades de
   contenedor uno, una franja centrada con máscara el otro—. Una foto no
   necesita ninguno. */
.symbbg img{
  position:absolute;inset:0;
  width:100%;height:100%;object-fit:cover;object-position:50% 38%;
}

/* La foto es de club: negra, movida y con focos de colores. Sin apagarla no
   se lee una línea encima. Se baja el brillo y se funde a negro por los cuatro
   lados, igual que la portada, y se le deja el rojo: es la misma sala. */
.symbbg::after{
  content:"";position:absolute;inset:0;
  background:
    linear-gradient(180deg,#000 0%,rgba(0,0,0,.56) 18%,rgba(0,0,0,.44) 60%,
                     rgba(0,0,0,.66) 86%,#000 100%),
    linear-gradient(90deg,rgba(0,0,0,.88) 0%,rgba(0,0,0,.46) 46%,rgba(0,0,0,.18) 100%),
    radial-gradient(90% 70% at 80% 40%,rgba(227,6,19,.16),transparent 70%);
}
@media (max-width:760px){
  /* En vertical el texto va sobre todo el ancho, no a un lado: el degradado
     lateral sobra y el de arriba abajo tiene que trabajar más. */
  .symbbg::after{
    background:
      linear-gradient(180deg,#000 0%,rgba(0,0,0,.7) 16%,rgba(0,0,0,.62) 60%,
                       rgba(0,0,0,.78) 86%,#000 100%),
      radial-gradient(90% 60% at 50% 30%,rgba(227,6,19,.14),transparent 72%);
  }
}

.sec-symb .wrap{position:relative;z-index:1}
/* Sin panel debajo, la sombra es lo que hace legible el texto sobre una imagen
   en movimiento. Cuesta mucho menos que volver a tapar el vídeo con otra capa
   —que era, otra vez, la caja. */
.sec-symb .wrap > *{text-shadow:0 1px 10px rgba(0,0,0,.92), 0 0 34px rgba(0,0,0,.72)}
.sec-symb .lead{color:#cfcbc6;max-width:62ch}
.symbmark{
  width:clamp(96px,15vw,150px);height:auto;
  margin:6px 0 clamp(16px,2.6vw,24px);
  opacity:.96;filter:drop-shadow(0 2px 18px rgba(0,0,0,.9));
}
.symbfrom{
  font-family:var(--mono);font-size:var(--t-s);letter-spacing:var(--ls-6);text-transform:uppercase;
  color:var(--dim);margin:22px 0 24px;
}
.symbacts{display:flex;flex-wrap:wrap;gap:12px}
/* El crédito del vídeo. Va pequeño y al final, pero va: el material es de DJ
   Mag y de Symbiotikka, no nuestro. */
.symbcredit{
  font-family:var(--mono);font-size:var(--t-micro);letter-spacing:var(--ls-4);
  text-transform:uppercase;color:var(--dim);margin:22px 0 0;max-width:44ch;
  line-height:1.6;
}

/* ═══ MERCADO TEMÁTICO ══════════════════════════════════════════════════════
   Nuevo en esta edición. Va dentro del line-up, así que se separa con un filete
   en vez de con el aire de una sección entera.
   ═══════════════════════════════════════════════════════════════════════════ */
.market{
  margin-top:clamp(44px,6vw,72px);
  padding-top:clamp(28px,4vw,40px);
  border-top:1px solid var(--line2);
}
.market .h3{margin-top:0}
.market .lead{max-width:60ch}

/* ═══ EARLY BIRD ════════════════════════════════════════════════════════════
   La barra de plazo encima de la lista de precios. Sólo existe mientras el
   Early Bird esté vivo: la esconde buildEarly() y se va sola al vencer.
   ═══════════════════════════════════════════════════════════════════════════ */
.early{
  display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;
  gap:12px 20px;
  margin-top:clamp(26px,4vw,38px);
  padding:15px clamp(16px,2.6vw,22px);
  border:1px solid rgba(227,6,19,.42);border-radius:3px;
  background:linear-gradient(90deg,rgba(227,6,19,.14),rgba(227,6,19,.03));
}
.ebkick{
  font-family:var(--mono);font-size:var(--t-s);letter-spacing:var(--ls-6);text-transform:uppercase;
  color:var(--red);margin:0;
}
.ebclock{display:flex;align-items:baseline;gap:3px}
.ebclock b{
  font-family:var(--display);font-weight:900;font-stretch:condensed;
  font-size:clamp(20px,3.4vw,28px);line-height:1;color:var(--bone);
}
.ebclock span{
  font-family:var(--mono);font-size:var(--t-xs);letter-spacing:var(--ls-4);text-transform:uppercase;
  color:var(--dim);margin-right:11px;
}
.ebclock span:last-child{margin-right:0}

/* El precio de después, al lado del de ahora: tachado y en gris, para que se
   vea de un vistazo lo que se ahorra quien compra hoy. */
.tlist .pr-then{
  font-family:var(--mono);font-size:clamp(11px,1.7vw,13px);letter-spacing:var(--ls-2);
  color:var(--dim);white-space:nowrap;
}
.tlist .pr-then s{text-decoration-thickness:1px;text-decoration-color:rgba(255,255,255,.45)}
.tlist .pr-then i{font-style:normal;letter-spacing:var(--ls-4);text-transform:uppercase;font-size:.82em;opacity:.75}

/* ═══ EL BOTÓN DE LA CANCIÓN ════════════════════════════════════════════════
   La pastilla de abajo a la derecha mientras suena «Weekend Baddie». Hace dos
   cosas a la vez y las dos importan: dice **qué** está sonando —es el crédito
   de Stella Bossi, que además es la cabeza de cartel— y deja callarlo de un
   toque, que es lo mínimo que se le debe a quien no esperaba sonido.

   Sólo existe dentro del tramo de la canción: `[hidden]` lo quita del todo y
   `.on` lo hace aparecer. Se esconde por opacidad y no por `display` para que
   entre y salga con la misma calma que el sonido.
   ═══════════════════════════════════════════════════════════════════════════ */
.sndbtn{
  position:fixed;right:var(--pad);z-index:125;
  bottom:calc(18px + env(safe-area-inset-bottom));
  display:flex;align-items:center;gap:10px;
  padding:9px 14px 9px 12px;
  border:1px solid var(--line2);border-radius:100px;
  background:rgba(0,0,0,.72);backdrop-filter:blur(14px) saturate(140%);
  color:var(--dim);cursor:pointer;
  opacity:0;transform:translateY(8px);pointer-events:none;
  transition:opacity .5s,transform .5s,color .25s,border-color .25s;
}
.sndbtn.on{opacity:1;transform:none;pointer-events:auto}
.sndbtn:hover{color:var(--bone);border-color:var(--line)}

.sndname{
  font-family:var(--mono);font-size:var(--t-xs);letter-spacing:var(--ls-3);text-transform:uppercase;
  white-space:nowrap;
}
.sndname b{color:var(--bone);font-weight:400}
/* El punto entre el nombre y el título. En versal y con este tracking las dos
   mitades se leían como una sola cosa —«STELLA BOSSI WEEKEND BADDIE»— y hace
   falta ver dónde acaba quién firma y dónde empieza qué suena. */
.sndname i{font-style:normal;opacity:.5;margin:0 .5em}
.sndbtn.off .sndname b{color:inherit}

/* Las tres barras del ecualizador. No miden nada —no hay analizador detrás—:
   son la señal de «esto está sonando», y por eso se paran en seco al callarlo
   en vez de seguir bailando sobre el silencio. */
.sndbars{display:flex;align-items:flex-end;gap:2px;width:13px;height:13px}
.sndbars i{
  flex:1;background:var(--red);border-radius:1px;
  height:100%;transform-origin:50% 100%;
  animation:sndbar .9s ease-in-out infinite;
}
.sndbars i:nth-child(2){animation-delay:-.35s}
.sndbars i:nth-child(3){animation-delay:-.6s}
@keyframes sndbar{
  0%,100%{transform:scaleY(.28)}
  50%    {transform:scaleY(1)}
}
/* Callada: las barras se quedan quietas y en gris, y se les cruza una raya. Así
   el estado se lee sin tener que oír nada —que es justo el caso, porque no
   suena—, y también en una captura, donde una animación no se ve.

   La raya va al 64% y no a la mitad, y no es un capricho: las barras quietas
   ocupan el 70% de abajo de la caja, así que una raya centrada les pasaría por
   encima sin tocarlas y parecería una flecha de tendencia, no un tachón. La
   sombra de arriba la despega de la barra que cruza. */
.sndbtn.off .sndbars i{animation:none;transform:scaleY(.7);background:currentColor}
.sndbtn.off .sndbars{position:relative}
.sndbtn.off .sndbars::after{
  content:"";position:absolute;left:-2px;right:-2px;top:64%;
  height:1.5px;background:currentColor;transform:rotate(-38deg);
  box-shadow:0 -2px 0 rgba(0,0,0,.9);
}

/* En móvil manda la barra de abajo: la pastilla se sube por encima de ella y
   pierde el nombre —no cabe sin empujar nada— y se queda en el disco con las
   barras, que es lo que hace falta para callarla. */
@media (max-width:860px){
  .sndbtn{
    bottom:calc(56px + 14px + env(safe-area-inset-bottom));
    padding:11px;gap:0;
  }
  .sndname{display:none}
}

/* Quien pide menos movimiento no quiere tres barras botando en un rincón: el
   estado se sigue leyendo por el color y por la raya. */
@media (prefers-reduced-motion:reduce){
  .sndbars i{animation:none;transform:scaleY(.62)}
  .sndbtn{transition:opacity .3s}
}

/* ═══ LA PORTADA EN ROJO ═════════════════════════════════════════════════════
   La portada se da la vuelta y pasa a ser el cartel: fondo del ROJO de la marca
   y todo el texto en NEGRO. Hasta aquí era al revés —negro de fondo, texto en
   hueso— y por eso este bloque va al final y en uno solo: no es un retoque de
   color suelto, es la misma decisión aplicada a las quince piezas de la
   portada a la vez, y separarlas en sus reglas de origen dejaría la inversión
   repartida por medio archivo sin que se lea en ningún sitio entera.

   Todo lo de aquí abajo está acotado a `.hero` (y a la barra de arriba mientras
   está sobre ella). El resto de la página no se toca: sigue siendo negra.

   Y ahora el rojo se ve entero, porque no hay nada encima. Aquí abajo había
   tres bloques más —`.hero-photo`, su cama de degradados y la versión de esa
   cama para el móvil— cuyo único trabajo era devolver el rojo por encima de la
   foto allí donde caía texto: dos óvalos y una cortina, con sus porcentajes
   cuadrados a la línea de la fecha y a la de la cuenta atrás. Al irse la foto
   se van los tres: no hay nada de lo que proteger al negro.
   ---------------------------------------------------------------------------- */
.hero{background:var(--red);color:var(--ink)}

/* El halo. Era rojo sobre negro —ponía el color— y ahora sobra por definición:
   el color ya está. Pasa a ser lo contrario, un viñeteado granate que cierra
   los cuatro cantos para que el rojo no se lea como un plano plano de pintura. */
.hero-glow{
  background:
    radial-gradient(120% 78% at 50% 44%, rgba(227,6,19,0) 42%, rgba(122,0,7,.30) 100%),
    radial-gradient(80% 50% at 50% 0%,   rgba(122,0,7,.26), transparent 66%);
}

/* ── los cuatro escalones, en negro ─────────────────────────────────────────
   Los logotipos vienen ya en negro y con los detalles de dentro calados, así
   que aquí no hay ningún filtro de color: sólo se cambia el halo. Era un
   resplandor rojo —para despegar un logotipo blanco de un fondo negro— e
   invisible sobre rojo; ahora es una sombra de verdad, que es lo que despega
   una tinta negra de un fondo de color.

   El `invert(1)` que hubo aquí un rato no valía: el arte blanco trae los ojos
   en aspa y la mordaza en negro OPACO, y darle la vuelta al color sin dársela
   al alfa los dejaba en blanco, o sea manchas blancas en medio del cartel. Se
   arregla en el archivo, no en el CSS: ver `utopia-black-cut.png`. */
.lockup img{filter:drop-shadow(0 6px 26px rgba(80,0,4,.28))}
/* La chapa vuelve a la versión del cartel: negra sobre el rojo, con la palabra
   calada. Aquí estaba invertida —hueso con letra negra— porque el fondo era
   oscuro; con el fondo rojo, la del cartel es la que toca. Ver el PDF de
   identidad, página 9. */
.lk-meets{background:var(--ink);color:var(--red);box-shadow:none}

/* Ni un halo en toda la portada, y ya no hace falta ninguno. Mientras hubo foto
   debajo, cada cuerpo pequeño —la fecha, el hint de bajar, el círculo del dress
   code— llevaba pegado un resplandor del rojo de la marca: aclaraba dos o tres
   píxeles detrás del trazo para que la letra tuviera contra qué leerse cuando
   le tocaba caer sobre pelo negro o sobre malla. Sobre el rojo liso ese halo es
   rojo sobre el mismo rojo, o sea nada, y donde llegaba a verse ensuciaba el
   canto de la letra como un contorno mal impreso. Fuera los tres.

   Lo único que se queda es la sombra del título, y no es un halo: es una caída
   granate muy abierta que le da peso a la mancha de tinta, como la que llevan
   los dos logotipos justo aquí encima. */
.ht-in{color:var(--ink);text-shadow:0 4px 30px rgba(80,0,4,.20)}
/* El wordmark, en NEGRO, como los otros dos logotipos y como el resto de la
   portada. Estuvo en blanco mientras la fecha y la cuenta atrás iban en hueso;
   al pasar todo a una tinta, este se va con ellas.

   `brightness(0)` y no quitar el filtro: el archivo ya es negro, pero el filtro
   fuerza el arte a negro puro **sea del color que sea**, así que el resultado
   no depende de qué tono venga en el PNG. Y aquí se puede tocar el color a
   ciegas, al revés que con el de UTOPIA: este wordmark es de un solo color
   sobre transparente, sin detalles opacos dentro que se estropeen. */
.heroplace img{filter:brightness(0)}
/* Sobre rojo, la decorativa se distingue por FORMA y hereda el color: es la
   regla de toda la web (ver «El color de la decorativa tiene una sola regla»)
   y también la del cartel, donde la O, la C y la S son tan negras como el
   resto. El rojo que llevaban aquí era para despegarlas del vídeo oscuro. */
.ht-in .dl{color:currentColor}

/* ── los tres escalones de debajo del título, TAMBIÉN EN NEGRO ───────────────
   La fecha, el sitio y la cuenta atrás iban en hueso: eran una segunda tinta
   para separar la información del titular sin repetir cuerpo. Con foto detrás
   tenía además una razón práctica —caían sobre el pelo negro y la malla, donde
   una tinta negra se apagaba—, y sin foto esa razón desaparece.

   Ahora la portada es de una sola tinta, como el cartel impreso: TODO en negro
   sobre el rojo. Negro sobre este rojo da 5,25:1, y el hueso 4,3:1, así que
   además de ser lo que pide el cliente es lo que más se lee, y en el cuerpo más
   pequeño de la portada —las etiquetas de la cuenta atrás, 16 px— es donde más
   se nota la diferencia.

   La jerarquía no la pierde: la llevaban el tamaño y el peso mucho antes que el
   color, y esos no se tocan. El título sigue midiendo cuatro veces la fecha. */
.herodate{color:var(--ink)}
.herodate i{background:var(--ink)}


/* ── la cuenta atrás, sin cajas ──────────────────────────────────────────────
   Las cuatro cajas eran una respuesta al fondo negro: una cifra clara sobre una
   foto oscura necesitaba una caja que la sostuviera. Sobre el rojo no hace
   falta nada de eso —el negro se lee solo— y cuatro rectángulos en medio del
   cartel eran cuatro cosas más que contar. Se quedan la cifra y su etiqueta.

   El `min-width` sí se queda: son cifras que cambian cada segundo y sin un
   ancho fijo el bloque entero se movería a cada tic. Con él y con las tabulares
   que ya llevaban, la cuenta atrás está quieta. */
.hero .count .c{
  border:0;background:none;padding:0;
  min-width:clamp(52px,11vw,84px);
}
.hero .count{gap:clamp(14px,3.4vw,32px)}

/* ── y mucho más gorda ───────────────────────────────────────────────────────
   Sin las cajas, la cuenta atrás se quedó en cuatro cifras sueltas del tamaño
   de un pie de foto: el quinto escalón de la portada, sí, pero tan por debajo
   del cuarto que dejaba de contar. Y es el único dato que se mueve.

   Sube de 42 a 60 px, o sea al mismo cuerpo que la fecha, y las etiquetas dejan
   la mono para ir en la grotesca del cartel, a peso completo.
   La medida es `min(7.4vw, 8.4vh)`: contra el ancho **y** contra el alto, para
   que en un portátil bajo —donde el resto de la portada ya se mide en vh— la
   cuenta atrás encoja con todo lo demás en vez de comerse el hueco del botón
   de bajar.

   El `min-width` sube con la cifra: son cuatro números que cambian cada
   segundo y el ancho fijo es lo que impide que el bloque baile a cada tic. */
.hero .count b{
  color:var(--ink);
  font-size:clamp(34px,min(7.4vw,8.4vh),60px);
  letter-spacing:-.015em;
}
.hero .count span{
  /* Sin opacidad. Las etiquetas iban al 88% para compensar que el hueso sobre
     rojo llega flojo; en negro no hay nada que compensar, y a 16 px cualquier
     velo se paga en legibilidad. Se separan de las cifras por cuerpo —cuatro
     veces más pequeñas— y no por tinta. */
  color:var(--ink);
  font-family:var(--display);font-weight:900;font-stretch:condensed;
  font-size:clamp(11px,min(1.7vw,1.9vh),16px);
  letter-spacing:var(--ls-4);
  margin-top:clamp(3px,.6vh,6px);
}
.hero .count .c{min-width:clamp(62px,min(13vw,14vh),108px)}
.hero .count-live{color:var(--ink)}

/* ── botones y remates ──────────────────────────────────────────────────────
   Aquí vivían los dos círculos de la portada, con las seis reglas que hacían
   falta para pasarlos del negro de antes al rojo de ahora. Se fueron con ellos.

   el látigo: el aro rojo sobre rojo tampoco existía */
.whipbtn-hero{border-color:var(--ink);color:var(--ink);box-shadow:none}
.whipbtn-hero::before{background:var(--ink)}
.whipbtn-hero:hover{color:var(--red);box-shadow:none}

.scrollhint b{color:rgba(0,0,0,.62)}
/* Sobre el rojo, la barrita es negra y **no se va a transparente**: acabar en
   nada sobre un fondo de color deja medio trazo en el aire. Cierra en un negro
   al 20%, que sigue leyéndose contra el rojo. */
.scrollhint span{background:linear-gradient(var(--ink) 0 55%,rgba(0,0,0,.22))}
.scrollhint:hover b,.scrollhint:focus-visible b{color:var(--ink);text-shadow:none}

/* ── la barra de arriba, mientras está sobre el rojo ─────────────────────────
   `.nav:not(.stuck)` **es** «estamos en lo alto de la portada»: la clase la
   pone el scroll a los 40 px y por encima de eso no hay más que hero. Así que
   no hace falta ni una línea de JS nueva para esto.

   Lo primero que se va es el degradado negro de la barra: sobre el rojo era una
   mancha oscura en el borde de arriba del cartel. En cuanto se baja, `.stuck`
   devuelve la barra oscura de siempre, que sobre el rojo se lee bien.
   ---------------------------------------------------------------------------- */
.nav:not(.stuck){background:none}
.nav-mark .nm-k{display:none}
.nav:not(.stuck) .nav-mark .nm-w{display:none}
.nav:not(.stuck) .nav-mark .nm-k{display:block;opacity:1}
.nav:not(.stuck) .nav-links a{color:rgba(0,0,0,.62)}
.nav:not(.stuck) .nav-links a:hover,
.nav:not(.stuck) .nav-links a.on{color:var(--ink)}
.nav:not(.stuck) .nav-links a::after{background:var(--ink)}
.nav:not(.stuck) .lang{color:rgba(0,0,0,.62);border-color:rgba(0,0,0,.28)}
.nav:not(.stuck) .lang b{color:var(--ink)}
.nav:not(.stuck) .navbuy{background:var(--ink);color:var(--bone)}
.nav:not(.stuck) .navbuy:hover{background:var(--bone);color:var(--ink)}

