/* =========================================================
   SA Sonidos & Multimedia — landing
   Clima: una sala a oscuras. Haz frío (cian de marca) contra tungsteno
   cálido, que son las dos temperaturas que hay de verdad en un escenario.
   Todo recto —rack, flight case, panel LED— y una sola familia tipográfica,
   Archivo variable, empujada a fondo en su eje de ancho: display condensado
   a escala de afiche contra etiquetas técnicas anchas.
   ========================================================= */

/* ── tipografías propias ─────────────────────────────────
   Servidas desde assets/fonts/, igual que las librerías: sin hoja de
   estilo de Google bloqueando el primer pintado y sin que la IP del
   visitante llegue a un tercero. Archivo es variable en peso Y en ancho
   —el sistema tipográfico entero es el contraste entre anchos—, así que
   va un solo archivo con los dos ejes. Ambas: SIL Open Font License 1.1.
--------------------------------------------------------- */
@font-face{
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-display: swap;
  src: url(assets/fonts/archivo-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face{
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-display: swap;
  src: url(assets/fonts/archivo-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
                 U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF,
                 U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face{
  font-family: 'Kaushan Script';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(assets/fonts/kaushan-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ── el clima: una sala a oscuras ────────────────────────
   Dos temperaturas de color, que son las dos que existen de verdad en un
   escenario: el haz frío del cabezal y la luz cálida de tungsteno de la sala.
   El acento es uno solo —el cian— y el ámbar es material, no un segundo
   acento de interfaz: aparece en la firma, los números y los reflejos.
   El violeta y el magenta quedan reservados para un único lugar de toda la
   página, el titular del hero, donde el degradado RGB dice "pantalla LED"
   en vez de decir "degradado". */
:root{
  --ink:    #05060A;   /* negro de sala       */
  --ink-2:  #090B10;   /* secciones alternas  */
  --ink-3:  #0E1117;   /* superficies / cards */
  --line:   #1B212B;   /* hairline estructural */
  --line-2: #2C3542;   /* hairline de foco     */

  --brand:      #00769C;
  --brand-lit:  #35C2EE;   /* el haz frío: el acento, uno solo */
  --violet:     #7B5BD6;
  --magenta:    #E0518F;
  --tungsten:   #F2A83B;   /* la luz cálida de sala */
  --gold:       var(--tungsten);

  /* barrido RGB. Se usa exactamente dos veces: "Pantallas LED" y la barra
     de progreso. Repetido en cada título dejaba de ser un gesto. */
  --beam: linear-gradient(96deg, var(--brand-lit) 0%, var(--violet) 52%, var(--magenta) 100%);

  --txt:   #E9EDF2;
  --txt-2: #AEB8C6;   /* gris de apoyo */

  /* relleno de hover de los botones: mismo acento que --brand-lit pero
     oscurecido lo justo para sostener texto claro encima (ver .btn::before) */
  --ink-cta: #05748C;

  --display: 'Archivo', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --body:    'Archivo', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --script:  'Kaushan Script', 'Segoe Script', cursive;

  /* Archivo es variable en ANCHO (62%–125%) y ese eje estaba desperdiciado
     con todo entre 96% y 118%. El sistema entero se apoya ahora en él:
     el display va condensado y pesado —escala de afiche de teatro— contra
     etiquetas técnicas más anchas y un cuerpo neutro al 100%. El contraste
     es de ancho y de peso dentro de una sola familia, no de dos familias. */
  --display-w: 68%;   /* titulares condensados */
  --label-w:   80%;   /* etiquetas técnicas    */

  --wrap: 1240px;
  --pad:  clamp(20px, 5vw, 48px);
  --gap:  clamp(80px, 10vw, 144px);
  --gap-sm: clamp(56px, 7vw, 100px);

  /* Un solo canal entre piezas de una misma grilla. Antes convivían 12, 14
     y 18 px haciendo el mismo trabajo en tres secciones distintas, y a 14 px
     las tarjetas se leían como una tabla y no como una composición. */
  --gutter: 22px;

  /* Las etiquetas en versalitas —tags, epígrafes, dt, el riel de pasos— son
     un solo rol tipográfico. Tenían nueve interletrados distintos (.1 a .28em)
     y seis cuerpos: acá quedan en dos variables y se aplican en todos lados. */
  --track:      .2em;
  --label-size: .72rem;

  /* Bloqueo de forma: TODO es recto. Un rack, un flight case, un panel LED y
     una consola son rectángulos; la esquina redondeada de 16px era lo único
     que hacía que esto pareciera cualquier landing. Única excepción, y es
     una regla, no un descuido: lo que es circular por función —el FAB, los
     puntos indicadores— sigue siendo circular. */
  --r:  0px;
  --ease:  cubic-bezier(.22,.8,.3,1);
  --ease2: cubic-bezier(.16,1,.3,1);
}

*, *::before, *::after{ box-sizing: border-box; }

html{
  scroll-behavior: auto;          /* lo maneja script.js */
  scroll-padding-top: 84px;
  -webkit-text-size-adjust: 100%;
}

body{
  margin: 0;
  background: var(--ink);
  color: var(--txt);
  font-family: var(--body);
  font-size: 16.5px;
  line-height: 1.62;
  -webkit-font-smoothing: antialiased;
  /* clip y no hidden: hidden crea un contenedor de scroll y eso rompe el
     anclaje de ScrollTrigger. clip recorta igual sin generar scrollport. */
  overflow-x: clip;
}

/* height:auto es necesario: con los atributos width/height en el HTML,
   sin esto el alto del atributo gana sobre el ancho del CSS */
img{ max-width: 100%; height: auto; display: block; }
a{ color: inherit; }
svg{ display: block; }

/* ── tipografía ──────────────────────────────────────── */
h1, h2{
  font-family: var(--display);
  font-stretch: var(--display-w);
  font-weight: 900;
  /* .9 y no menos, y es una restricción de contenido, no de gusto: por debajo
     de ~.9 las mayúsculas acentuadas pierden la tilde al pintarse (medido en
     Chromium con este mismo Archivo) y el titular queda "DE LO TECNICO".
     Media página está en castellano con TÉCNICO, ILUMINACIÓN y CÓMO: la
     tilde no es opcional. Si alguien vuelve a apretar el interlineado, esto
     es lo que se rompe y no avisa. */
  line-height: .9;
  letter-spacing: .002em;   /* la versalita condensada necesita aire, no menos */
  text-transform: uppercase;
  /* reserva para que el clip del reveal no recorte la tilde por arriba */
  padding-top: .2em;
  margin: -.2em 0 0;
  text-wrap: balance;
}
h2{ font-size: clamp(2.9rem, 8.4vw, 6.2rem); }

h3{
  font-family: var(--display);
  font-stretch: 88%;
  font-weight: 800;
  font-size: 1.42rem;
  line-height: 1.06;
  letter-spacing: -.01em;
  margin: 0;
}

p{ margin: 0; }

/* La cláusula que remata cada título. Antes iba con el degradado del haz, y
   el mismo efecto repetido en los seis h2 dejaba de ser un gesto para pasar a
   ser una plantilla; además el texto en degradado pierde el color del sistema
   y se lee peor. Queda un color sólido de marca, que es contraste real. El
   barrido completo se reserva para un único lugar: el titular del hero.

   El contraste de la segunda línea es tipográfico antes que cromático: el
   mismo Archivo, pero fino y menos condensado contra el 900 de la primera.
   Peso e italiana de la MISMA familia; meter otra familia para destacar una
   línea es el recurso de siempre y se nota. */
.grad{
  color: var(--brand-lit);
  font-weight: 300;
  font-stretch: 78%;
}

.hero__title .grad{
  color: transparent;
  background: var(--beam);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}

.motto{
  font-family: var(--script);
  font-size: clamp(1.4rem, 3.2vw, 2.1rem);
  line-height: 1.3;
  color: var(--gold);
  margin: 0;
}

.wrap{
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--pad);
}

.section{ padding-block: var(--gap); position: relative; }
/* las secciones tintadas van más apretadas: si todas respiran igual, el
   scroll no tiene ritmo, tiene métrica */
.section--alt{ background: var(--ink-2); padding-block: var(--gap-sm); }

/* sin tope de ancho: el corte de los títulos lo decide el <br> del HTML.
   Un max-width en ch acá se mide con el cuerpo (17px), no con el título,
   y terminaba partiendo en cuatro líneas lo que iban a ser dos. */
/* Marca de sección: una regla estructural con un tramo encendido, como la
   marca de un guion de cabina. Es estructura, no una etiqueta más: la página
   ya tenía seis titulares idénticos y sumarle seis versalitas encima habría
   sido la plantilla completa. */
.shead{
  margin-bottom: clamp(40px, 6vw, 72px);
  padding-top: 28px;
  border-top: 1px solid var(--line);
  position: relative;
}
.shead::before{
  content: '';
  position: absolute; left: 0; top: -1px;
  width: 72px; height: 2px;
  background: var(--brand-lit);
}
.shead__lead{
  color: var(--txt-2);
  font-size: 1.06rem;
  margin-top: 24px;
  max-width: 52ch;
}

/* Los titulares no entran con un fade: se descubren de abajo hacia arriba,
   como una luz que sube. En versalitas no hay descendentes, así que el
   recorte por clip no corta nada. */
.js .reveal h2{
  clip-path: inset(0 0 100% 0);
  transition: clip-path .95s var(--ease2) .04s;
}
.js .reveal.is-in h2{ clip-path: inset(0 0 0 0); }

.skip{
  position: absolute; left: -9999px;
  background: var(--brand); color: #fff;
  padding: 12px 18px; z-index: 300; border-radius: 0;
}
.skip:focus{ left: 0; top: 0; }

:where(a, button, [tabindex]):focus-visible{
  outline: 2px solid var(--brand-lit);
  outline-offset: 3px;
  border-radius: var(--r);
}

/* Lo que dibuja el navegador y no dibujamos nosotros —la selección, la barra
   de scroll, el subrayado de los enlaces— venía con los valores por defecto,
   que sobre un fondo negro son de otra página. Va con la paleta del sitio. */
::selection{ background: var(--brand); color: #fff; }
html{ scrollbar-color: #2E3440 var(--ink); }
a{ text-underline-offset: .18em; text-decoration-thickness: from-font; }

/* ── Lenis ────────────────────────────────────────────
   Copiado de lenis@1.3.26/dist/lenis.css (MIT). Va inline y no como
   archivo aparte porque son 500 bytes y no justifica otro pedido.
   Sin esto Lenis toma el control del scroll pero el documento nunca
   se ajusta, y la página queda como trabada: no scrollea, y nada de
   lo que depende del scroll llega a dispararse.
------------------------------------------------------- */
html.lenis,
html.lenis body{ height: auto; }

.lenis:not(.lenis-autoToggle).lenis-stopped{ overflow: clip; }

.lenis [data-lenis-prevent],
.lenis [data-lenis-prevent-wheel],
.lenis [data-lenis-prevent-touch],
.lenis [data-lenis-prevent-vertical],
.lenis [data-lenis-prevent-horizontal]{ overscroll-behavior: contain; }

.lenis.lenis-smooth iframe{ pointer-events: none; }

.lenis.lenis-autoToggle{
  transition-property: overflow;
  transition-duration: 1ms;
  transition-behavior: allow-discrete;
}

/* ── pantalla de carga ───────────────────────────────── */
.pre{
  position: fixed; inset: 0; z-index: 500;
  display: grid; place-items: center;
  background: var(--ink);
}
.pre[hidden]{ display: none; }
.pre__inner{ display: grid; justify-items: center; gap: 20px; width: min(300px, 70vw); }
.pre__logo{ width: 78px; opacity: .9; }
.pre__num{
  font-family: var(--display); font-stretch: var(--display-w);
  font-size: clamp(3rem, 9vw, 5.4rem); font-weight: 800;
  line-height: 1; letter-spacing: -.04em;
  font-variant-numeric: tabular-nums;
}
.pre__bar{
  width: 100%; height: 2px;
  background: var(--line); overflow: hidden;
}
.pre__bar i{
  display: block; height: 100%; width: 100%;
  background: var(--brand-lit);
  transform: scaleX(0); transform-origin: 0 50%;
}
.pre__skip{
  position: absolute; right: var(--pad); bottom: 32px;
  background: none; border: 0; cursor: pointer;
  font-family: var(--display); font-stretch: var(--label-w);
  font-size: var(--label-size); font-weight: 700;
  letter-spacing: var(--track); text-transform: uppercase;
  color: var(--txt-2);
  padding: 10px;
  transition: color .25s var(--ease);
}
.pre__skip:hover{ color: var(--txt); }

/* mientras carga no se scrollea */
.is-loading{ overflow: hidden; }

/* ── interruptor de animaciones ───────────────────────
   Sólo se muestra a quien tenga movimiento reducido activado en el
   sistema. El resto nunca lo ve: ya recibe la versión completa.
------------------------------------------------------- */
.mtoggle{
  position: fixed; left: 20px; bottom: 20px; z-index: 130;
  display: inline-flex; align-items: center; gap: 9px;
  padding: 11px 18px;
  border: 1px solid var(--line);
  border-radius: var(--r);
  background: rgba(9,11,16,.92);
  backdrop-filter: blur(12px);
  color: var(--txt-2);
  font-family: var(--display); font-stretch: var(--label-w);
  font-size: var(--label-size); font-weight: 700;
  letter-spacing: var(--track); text-transform: uppercase;
  cursor: pointer;
  transition: color .25s var(--ease), border-color .25s var(--ease);
}
.mtoggle[hidden]{ display: none; }
.mtoggle::before{
  content: '';
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--brand-lit);
  box-shadow: 0 1px 3px rgba(0,0,0,.6);
}
/* Cuando ofrece la versión completa no es un interruptor apagado: es una
   invitación, así que va con el color de marca y el punto latiendo. */
.mtoggle.is-off{ color: var(--brand-lit); border-color: rgba(41,180,224,.32); }
.mtoggle.is-off::before{ animation: mtblink 2.4s var(--ease) infinite; }
@keyframes mtblink{ 0%,100%{ opacity: 1 } 50%{ opacity: .35 } }
.mtoggle:hover{ color: var(--txt); border-color: rgba(41,180,224,.5); }

@media (max-width: 640px){
  .mtoggle{ left: 12px; bottom: 12px; font-size: .68rem; padding: 9px 14px; }
}

/* ── grano ────────────────────────────────────────────
   Una teselita de ruido generada una sola vez en canvas, que
   salta entre posiciones. Es lo que le saca el aspecto plano
   a los degradados grandes sobre negro.
------------------------------------------------------- */
.grain{
  position: fixed; inset: -120px; z-index: 110;
  pointer-events: none;
  opacity: .05;
  background-repeat: repeat;
  animation: grainShift 6s steps(1) infinite;
}
@keyframes grainShift{
  0%   { transform: translate(0,0) }
  10%  { transform: translate(-6%,-4%) }
  20%  { transform: translate(-9%, 3%) }
  30%  { transform: translate( 4%,-6%) }
  40%  { transform: translate(-4%, 8%) }
  50%  { transform: translate(-8%, 4%) }
  60%  { transform: translate( 6%, 2%) }
  70%  { transform: translate( 2%,-7%) }
  80%  { transform: translate(-3%, 5%) }
  90%  { transform: translate( 7%,-2%) }
  100% { transform: translate(0,0) }
}

/* ── haz por shader ──────────────────────────────────── */
.beam{
  position: absolute; inset: auto 0 0 0; z-index: 2;
  width: 100%; height: 100%;
  display: none;                 /* script.js lo prende si hay WebGL */
  pointer-events: none;
}
.beam.is-on{ display: block; }
.beam.is-on ~ .waves--hero{ display: none; }

/* ── sección anclada (los pasos) ─────────────────────── */
.pinsec{ position: relative; display: none; }
.fx .pinsec{ display: block; }
.fx .stepsflat{ display: none; }
.pin{
  height: 100svh;
  display: flex; align-items: center;
  overflow: hidden;
}
.pin__inner{ width: 100%; }
.pin__head{ margin-bottom: clamp(28px, 4vw, 48px); }

.stage{
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: clamp(24px, 5vw, 72px);
  min-height: 46svh;
}
.stage__list{
  list-style: none; margin: 0; padding: 0;
  position: relative;
  min-height: 40svh;
}
/* los cuatro pasos ocupan el mismo lugar y se turnan */
.stg{
  position: absolute; inset: 0;
  display: grid;
  grid-template-columns: 1fr 1.05fr;
  align-items: center;
  gap: clamp(24px, 4vw, 56px);
  opacity: 0; visibility: hidden;
  transform: translateY(20px);
  transition: opacity .45s var(--ease), transform .6s var(--ease2), visibility .45s;
}
.stg__txt{
  display: flex; flex-direction: column; justify-content: center;
  gap: 14px; max-width: 22ch;
}
.stg__img{
  margin: 0; overflow: hidden;
  border-radius: var(--r);
  aspect-ratio: 3 / 2;
  border: 1px solid var(--line);
}
.stg__img img{ width: 100%; height: 100%; object-fit: cover; }
.stg.is-on{ opacity: 1; visibility: visible; transform: none; }
.stg__n{
  font-family: var(--display); font-stretch: var(--display-w);
  font-size: clamp(5rem, 15vw, 12rem); font-weight: 900;
  line-height: .8; letter-spacing: 0;
  color: var(--tungsten);
}
.stg h3{ font-size: clamp(1.5rem, 3vw, 2.2rem); }
.stg p{ color: var(--txt-2); font-size: 1.05rem; line-height: 1.6; }

/* riel de la derecha: dónde estamos de los cuatro */
.rail{
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: 18px;
}
.rail li{
  display: flex; align-items: center; gap: 12px;
  font-family: var(--display); font-stretch: var(--label-w);
  font-size: var(--label-size); font-weight: 700;
  letter-spacing: var(--track); text-transform: uppercase;
  color: #7E8896;
  transition: color .45s var(--ease);
}
/* el trazo crece con scaleX y no con width: animar width recalcula el
   layout de la lista en cada cuadro, y esto corre con el scroll enganchado */
.rail li i{
  display: block; width: 56px; height: 2px;
  background: var(--line);
  transform: scaleX(.607); transform-origin: 0 50%;
  transition: background .45s var(--ease), transform .45s var(--ease2);
}
.rail li.is-on{ color: var(--txt); }
.rail li.is-on i{ transform: none; background: var(--brand-lit); }

/* ── barra de progreso de lectura ────────────────────── */
.progress{
  position: fixed; inset: 0 auto auto 0;
  height: 2px; width: 100%;
  transform: scaleX(0); transform-origin: 0 50%;
  background: var(--beam);
  z-index: 120;
}

/* ── botones ─────────────────────────────────────────── */
.btn{
  --bg: var(--brand);
  position: relative;
  display: inline-flex; align-items: center; gap: 10px;
  padding: 15px 26px;
  border-radius: var(--r);
  background: var(--bg);
  color: #fff;
  font-family: var(--display);
  font-stretch: var(--label-w);
  font-weight: 800;
  font-size: .82rem;
  letter-spacing: .13em;
  text-transform: uppercase;
  text-decoration: none;
  overflow: hidden;
  isolation: isolate;
  transition: transform .28s var(--ease), box-shadow .3s var(--ease);
}
/* el haz entra desde la izquierda: un color, el del acento, no el arcoíris.
   Antes llenaba con --brand-lit e invertía el texto a negro: blanco sobre
   cian claro no se lee (1.9:1) y, apenas se entraba al hover, el texto ya
   era negro sobre el --brand de fondo (3.9:1) mientras el relleno todavía
   viajaba — ningún color de texto pasa contra los dos fondos a la vez.
   Se resuelve bajando el relleno a un tono que sigue leyéndose como acento
   pero nunca deja de sostener el texto claro (5.1:1 contra --ink-cta). */
.btn::before{
  content: '';
  position: absolute; inset: 0; z-index: -1;
  background: var(--ink-cta);
  transform: translateX(-101%);
  transition: transform .45s var(--ease2);
}
.btn:hover{
  transform: translateY(-2px);
  box-shadow: 0 10px 26px -14px rgba(0,0,0,.55);
}
.btn:hover::before{ transform: none; }
/* el botón se hunde: el click tiene que sentirse, no solo verse */
.btn:active{ transform: translateY(0) scale(.975); transition-duration: .08s; }

.btn--lg{ padding: 19px 34px; font-size: .88rem; }
.btn--sm{ padding: 11px 18px; font-size: .74rem; }

.btn--ghost{
  --bg: transparent;
  box-shadow: inset 0 0 0 1px var(--line-2);
  color: #fff;
}
.btn--ghost:hover{ box-shadow: none; }

/* "Calcular estimado": contorno cian, no sólido ni fantasma — un tercer
   peso entre WhatsApp (--brand) y Ver trabajos (fantasma neutro). La
   etiqueta va blanca (no cian) porque cian sobre --ink-cta en hover no
   llega a 4.5:1; el acento cian queda en el borde y en el medidor, que
   no cargan el significado del texto. */
.btn--calc{
  --bg: transparent;
  color: #fff;
  box-shadow: inset 0 0 0 1px rgba(53,194,238,.45);
  transition: color .2s var(--ease), transform .28s var(--ease), box-shadow .3s var(--ease);
}
.btn--calc:hover::before,
.btn--calc:focus-visible::before{ transform: none; }
.btn--calc .calcm{ color: var(--brand-lit); }
.btn--calc:hover .calcm,
.btn--calc:focus-visible .calcm{ color: #fff; }

/* el medidor: cinco barras tipo consola, el mismo lenguaje del haz del
   hero. Sólo transform/opacity — nunca width/height. */
.calcm{ display: inline-flex; align-items: flex-end; gap: 3px; height: 20px; }
.calcm i{
  display: block; width: 4px; height: 20px;
  background: currentColor;
  transform-origin: bottom;
  transform: scaleY(var(--h));
  transition: transform .25s var(--ease);
}
/* el medidor reacciona al paso del mouse/foco, no late solo */
.btn--calc:hover .calcm i,
.btn--calc:focus-visible .calcm i{ transform: scaleY(1); }
.calcm i:nth-child(1){ transition-delay: 0ms; }
.calcm i:nth-child(2){ transition-delay: 30ms; }
.calcm i:nth-child(3){ transition-delay: 60ms; }
.calcm i:nth-child(4){ transition-delay: 90ms; }
.calcm i:nth-child(5){ transition-delay: 120ms; }

/* barrido de la entrada GSAP: .btn ya tiene overflow:hidden, no se escapa */
.btn__sweep{
  position: absolute; inset: 0; pointer-events: none; opacity: 0;
  background: linear-gradient(100deg, transparent 38%, rgba(255,255,255,.30) 50%, transparent 62%);
}

.i-wa{ width: 20px; height: 20px; fill: currentColor; flex: none; }
.btn--lg .i-wa{ width: 22px; height: 22px; }
.i-line{
  width: 20px; height: 20px; flex: none;
  fill: none; stroke: currentColor; stroke-width: 1.7;
}

/* ── nav ─────────────────────────────────────────────── */
.nav{
  position: fixed; inset: 0 0 auto 0; z-index: 100;
  display: grid; align-items: center;
  grid-template-rows: 84px;
  transition: grid-template-rows .4s var(--ease), background .4s var(--ease),
              backdrop-filter .4s var(--ease), border-color .4s var(--ease);
  border-bottom: 1px solid transparent;
}
.nav.is-stuck{
  grid-template-rows: 72px;
  background: rgba(7,8,10,.78);
  backdrop-filter: blur(16px) saturate(140%);
  border-bottom-color: var(--line);
}
.nav__inner{
  display: flex; align-items: center; gap: 22px;
  height: 72px;
}
.nav__brand{
  display: flex; align-items: center; gap: 11px;
  text-decoration: none; margin-right: auto;
}
.nav__brand img{ width: 42px; height: auto; }
.nav__brand span{
  font-family: var(--display);
  font-stretch: var(--label-w);
  font-size: .74rem; font-weight: 700;
  line-height: 1.15; letter-spacing: var(--track);
  text-transform: uppercase; color: var(--txt-2);
}

.nav__links{ display: flex; gap: 30px; }
.nav__links a{
  position: relative;
  font-family: var(--display);
  font-stretch: var(--label-w);
  font-size: .78rem; font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--txt-2);
  text-decoration: none;
  padding-block: 6px;
  transition: color .25s var(--ease);
}
/* subrayado que crece desde la izquierda */
.nav__links a::after{
  content: '';
  position: absolute; left: 0; bottom: 0;
  width: 100%; height: 2px;
  background: var(--brand-lit);
  transform: scaleX(0); transform-origin: 0 50%;
  transition: transform .35s var(--ease2);
}
.nav__links a:hover,
.nav__links a.is-active{ color: var(--txt); }
.nav__links a:hover::after,
.nav__links a.is-active::after{ transform: none; }

.nav__burger{
  display: none;
  width: 44px; height: 44px;
  background: none; border: 0; cursor: pointer;
  flex-direction: column; justify-content: center; gap: 6px;
  padding: 0;
}
.nav__burger span{
  display: block; height: 2px; width: 22px;
  margin-inline: auto;
  background: var(--txt);
  transition: transform .35s var(--ease), opacity .2s;
}
.nav__burger[aria-expanded="true"] span:first-child{ transform: translateY(4px) rotate(45deg); }
.nav__burger[aria-expanded="true"] span:last-child{ transform: translateY(-4px) rotate(-45deg); }

.menu{
  position: fixed; inset: 72px 0 auto 0; z-index: 99;
  background: rgba(7,8,10,.97);
  backdrop-filter: blur(16px);
  border-bottom: 1px solid var(--line);
  padding: 18px var(--pad) 30px;
  display: flex; flex-direction: column; gap: 4px;
  animation: menuIn .3s var(--ease2) both;
}
.menu[hidden]{ display: none; }
@keyframes menuIn{ from{ opacity:0; transform: translateY(-10px) } }
.menu a{
  font-family: var(--display); font-stretch: 105%;
  font-size: 1.5rem; font-weight: 700; letter-spacing: -.01em;
  text-decoration: none; padding: 12px 0;
  border-bottom: 1px solid var(--line);
}
.menu__wa{ color: var(--brand-lit); border-bottom: 0 !important; }

/* ── hero ────────────────────────────────────────────── */
.hero{
  position: relative;
  min-height: 100svh;
  /* anclado abajo: el afiche ocupa el alto y el riel apoya contra el borde,
     en vez de flotar un bloque centrado con media pantalla vacía al lado */
  display: flex; align-items: flex-end;
  padding-block: 132px 76px;
  overflow: hidden;
}
/* fondo de video: tríptico de tres columnas a sangre (desktop) o una sola
   toma (mobile). Las juntas de 2 px se leen como módulos LED. */
.hero__media{
  position: absolute; inset: 0; z-index: 0;
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 2px;
  background: var(--ink);
}
.hero__col{ height: 100%; }
/* velo que apaga cada columna; script.js lo baja a 0 en la que está "activa" */
.hero__veilc{ position: absolute; inset: 0; z-index: 2; background: rgba(5,6,10,.45); pointer-events: none; }
/* velos de contraste, encima del video y debajo del texto */
.hero::after{
  content: '';
  position: absolute; inset: 0;
  z-index: 1;
  background:
    linear-gradient(180deg, rgba(5,6,10,.55) 0%, rgba(5,6,10,0) 22%, rgba(5,6,10,0) 40%, rgba(5,6,10,.82) 72%, #05060A 100%),
    linear-gradient(100deg, rgba(5,6,10,.7) 0%, rgba(5,6,10,0) 55%);
  pointer-events: none;
}

/* halo que sigue al puntero: la luz que se mueve por la sala */
.hero__glow{
  position: absolute; inset: -20%; z-index: 2;
  background: radial-gradient(420px circle at var(--mx,50%) var(--my,42%),
              rgba(41,180,224,.22), rgba(123,91,214,.10) 45%, transparent 70%);
  pointer-events: none;
  transition: opacity .6s var(--ease);
}
.hero__inner{ position: relative; z-index: 3; }

.hero__title{
  /* tope real, no aspiracional: "Pantallas LED." tiene que entrar en UNA
     línea a 1440, si no el hero pasa a cuatro líneas y la CTA se va abajo
     del pliegue. Medido, no estimado. */
  font-size: clamp(3.2rem, 11vw, 8.6rem);
  letter-spacing: 0;
  line-height: .88;   /* mismo piso que h1/h2: por debajo se pierden las tildes */
  margin: 0 0 clamp(34px, 5vw, 58px);
}
.hero__title .mask{ display: block; overflow: hidden; padding-bottom: .04em; }
.hero__title b{ display: block; font-weight: inherit; }
/* arranca pausado: lo suelta la clase .go cuando termina la pantalla de carga */
.js .hero__title b{ animation: rise 1s var(--ease2) var(--d, 0s) both; animation-play-state: paused; }
.js.go .hero__title b{ animation-play-state: running; }
@keyframes rise{ from{ transform: translateY(108%) } }

/* el riel de cabina bajo el afiche */
.hero__rail{
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: end;
  gap: 40px clamp(32px, 6vw, 80px);
  border-top: 1px solid var(--line);
  padding-top: clamp(24px, 3vw, 36px);
}
.hero__side{
  display: grid; gap: 18px;
  justify-items: end; text-align: right;
}

.hero__lead{
  max-width: 46ch;
  font-size: clamp(1.02rem, 1.6vw, 1.18rem);
  color: var(--txt-2);
  margin-bottom: 28px;
}

.hero__cta{ display: flex; flex-wrap: wrap; gap: 12px; }

/* refuerza el argumento anti-sorpresa justo bajo la CTA principal, en vez
   de dejarlo vivir solo al final en Contacto */
.hero__note{
  display: flex; align-items: center; gap: 8px;
  margin: 14px 0 0;
  font-size: .92rem; font-weight: 500;
  color: var(--txt-2);
}
.hero__note span{ color: var(--brand-lit); font-size: .5em; }

.hero__facts{
  display: grid; gap: 9px;
  justify-items: end;
  list-style: none; margin: 0; padding: 0;
  font-family: var(--display); font-stretch: var(--label-w);
  font-size: var(--label-size); font-weight: 700;
  letter-spacing: var(--track); text-transform: uppercase;
  color: var(--txt-2);
}
/* alineados a la derecha: el punto va del lado del borde, no del texto */
.hero__facts li{ display: flex; flex-direction: row-reverse; align-items: center; gap: 9px; }
.hero__facts li::before{
  content: ''; width: 6px; height: 6px; border-radius: 50%;
  background: var(--brand-lit);
}

/* La cajita-mouse con la ruedita adentro era el glifo de scroll de siempre, y
   con las esquinas rectas encima parecía un error de render. Es un haz: una
   guía apagada y un tramo de luz que baja por ella. */
.hero__scroll{
  position: absolute; right: var(--pad); bottom: 30px; z-index: 3;
  width: 1px; height: 56px;
  background: var(--line-2);
  overflow: hidden;
}
.hero__scroll span{
  display: block; width: 100%; height: 18px;
  background: var(--brand-lit);
  animation: wheel 2.1s var(--ease) infinite;
}
@keyframes wheel{
  0%{ opacity:0; transform: translateY(-18px) }
  35%{ opacity:1 }
  100%{ opacity:0; transform: translateY(56px) }
}

/* ── ondas (las dibuja script.js) ────────────────────── */
.waves{
  position: absolute; inset: auto 0 0 0;
  width: 100%; height: 100%;
  fill: none;
  stroke: var(--brand);
  stroke-width: 1;
  pointer-events: none;
}
.waves--hero{ height: 78%; opacity: .5; z-index: 2; }
.waves--band{ height: 100%; opacity: .12; stroke: var(--violet); }
.waves--foot{ height: 100%; opacity: .3; }

/* ── franja de confianza ─────────────────────────────── */
.trust{
  border-block: 1px solid var(--line);
  background: var(--ink-2);
  padding-block: 16px;
}
.trust__inner{
  display: flex; align-items: center; justify-content: center;
  gap: 10px; flex-wrap: wrap; text-align: center;
}
.trust__ico{
  width: 18px; height: 18px; flex: none;
  fill: none; stroke: var(--brand-lit); stroke-width: 2.4;
  stroke-linecap: round; stroke-linejoin: round;
}
.trust__inner p{
  margin: 0;
  font-size: .95rem; color: var(--txt-2);
}
.trust__inner strong{ color: var(--txt); font-weight: 700; }

/* ── marquesina de servicios ─────────────────────────── */
.ticker{
  border-block: 1px solid var(--line);
  background: var(--ink-2);
  overflow: hidden;
  padding-block: 20px;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
.ticker__track{
  display: flex; align-items: center;
  width: max-content;
  animation: slide 38s linear infinite;
}
/* la separación va como margen y no como gap: con gap, el 50% del
   recorrido no cae justo sobre la copia y el loop pega un salto */
.ticker__track > *{ margin-inline: 13px; }   /* 13+13 = los mismos 26 por ítem, y centra bien al envolver */
@keyframes slide{ to{ transform: translateX(-50%) } }
.ticker span{
  font-family: var(--display); font-stretch: var(--display-w);
  font-size: clamp(1.4rem, 3.4vw, 2.4rem);
  font-weight: 800; letter-spacing: -.02em;
  white-space: nowrap;
}
/* punto dibujado por CSS: el glifo ◆ salia con forma y peso distintos
   segun la fuente de sistema de cada plataforma */
.ticker i{
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--brand-lit);
  flex: none;
}

/* ── tarjetas de servicio ────────────────────────────── */
/* Panel de conexionado, no seis tarjetas flotando. La grilla dibuja las
   hairlines con un gap de 1px sobre fondo de línea: las celdas quedan
   pegadas y continuas, como un rack, en vez de seis cajas redondeadas
   separadas por aire —que es exactamente el layout de cualquier plantilla. */
.cards{
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: 1px;
  grid-template-columns: repeat(3, 1fr);
  background: var(--line);
  border: 1px solid var(--line);
}
.card{
  position: relative;
  padding: 30px 28px 32px;
  background: var(--ink-3);
  overflow: hidden;
  isolation: isolate;
  transition: box-shadow .35s var(--ease);
}
/* el canal se enciende: una barra que sube por el borde izquierdo, como un
   fader que entra en vivo. Sube, no barre de costado: la dirección importa. */
.card::before{
  content: '';
  position: absolute; inset: 0 auto 0 0; width: 2px; z-index: 3;
  background: var(--brand-lit);
  transform: scaleY(0); transform-origin: 50% 100%;
  transition: transform .5s var(--ease2);
}
.card:hover{ box-shadow: inset 0 0 0 1px var(--line-2); }
.card:hover::before{ transform: none; }

.card__ico{
  display: grid; place-items: center;
  width: 25px; height: 25px; flex: none;
}
.card__ico svg{
  width: 25px; height: 25px;
  fill: none; stroke: var(--brand-lit);
  stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round;
}
/* el ícono va al costado del título, en el flujo del encabezado, no
   apilado en su propia placa arriba: esa caja redondeada es la plantilla
   de tarjeta de-feature de cualquier generador. */
.card__head{
  display: flex; align-items: center; gap: 12px;
  margin-bottom: 10px;
}
.card__head h3{ margin: 0; }
/* las líneas del icono se dibujan cuando la tarjeta entra en pantalla */
.js .card__ico svg *{
  stroke-dasharray: 120; stroke-dashoffset: 120;
}
.js .card.is-in .card__ico svg *{
  animation: draw 1.1s var(--ease2) calc(var(--d, 0s) + .15s) forwards;
}
@keyframes draw{ to{ stroke-dashoffset: 0 } }

.card h3{ margin-bottom: 10px; }
.card p{ color: var(--txt-2); font-size: 1rem; line-height: 1.6; }

/* las tres principales llevan foto; el icono se apoya sobre el borde */
.card--feat{ padding: 0 28px 28px; }
.card__media{
  position: relative;
  margin: 0 -28px 0;
  aspect-ratio: 3 / 2;
  overflow: hidden;
}
.card__media img{
  width: 100%; height: 100%; object-fit: cover;
  transform: scale(1.04);
  transition: transform .8s var(--ease);
}
.card--feat:hover .card__media img{ transform: scale(1.1); }
/* degradado para que el icono y el título no compitan con la foto */
.card__media::after{
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(5,6,10,.15) 0%, rgba(14,17,23,.58) 62%, var(--ink-3) 100%);
}
.card--feat .card__head{ margin-top: 20px; }

/* ── ilustraciones de las tarjetas sin foto ──────────────
   Selfie 360, espejo mágico y drone no tienen foto propia y no
   existe ninguna libre que muestre el equipo de verdad. En vez de
   poner una foto ajena o inventada, van dibujadas: se animan solas
   y explican el servicio sin fingir que son un registro del trabajo.
--------------------------------------------------------- */
.card__media--art{
  background:
    radial-gradient(122% 92% at 50% 6%, rgba(41,180,224,.11) 0%, transparent 62%),
    linear-gradient(180deg, #101823 0%, var(--ink-3) 100%);
}
/* el degradado de las fotos taparía el dibujo: acá cae sólo al pie */
.card__media--art::after{
  background: linear-gradient(180deg, transparent 0%, transparent 54%,
              rgba(18,21,26,.62) 84%, var(--ink-3) 100%);
}
.art{
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  fill: none; stroke-width: 5;
  stroke-linecap: round; stroke-linejoin: round;
}

/* selfie 360 */
.a3-base{ stroke: #3B4759; }
.a3-base--in{ stroke: #2B3543; }
.a3-halo{ stroke: var(--brand-lit); opacity: .2; }
.a3-person{ stroke: var(--txt-2); opacity: .75; }
.a3-arm{ stroke: #6C7B94; stroke-width: 2; }
.a3-cam{ stroke: var(--brand-lit); stroke-width: 2.2; }
.a3-ray{ stroke: var(--gold); opacity: .5; }
.a3-spin{ animation: a3spin 5.5s linear infinite; transform-origin: 0 0; }
@keyframes a3spin{ to{ transform: rotate(360deg) } }
.a3-halo{ animation: a3halo 3.4s var(--ease) infinite; transform-origin: 450px 412px; }
@keyframes a3halo{ 0%,100%{ opacity: .14; transform: scale(.93) } 50%{ opacity: .55; transform: scale(1.07) } }

/* espejo mágico */
.am-frame{ stroke: #47546B; }
.am-glass{ stroke: #2A3343; }
.am-refl{ stroke: var(--txt-2); opacity: .45; }
.am-foot{ stroke: #47546B; }
.am-scan{ stroke: var(--brand-lit); animation: amscan 4s var(--ease) infinite; }
@keyframes amscan{
  0%   { transform: translateY(0);     opacity: 0 }
  14%  { opacity: 1 }
  40%  { opacity: 1 }
  50%  { transform: translateY(296px); opacity: 0 }
  100% { transform: translateY(296px); opacity: 0 }
}
.am-print{ stroke: var(--brand-lit); opacity: .85; animation: amprint 4s var(--ease2) infinite; }
@keyframes amprint{
  0%,20% { opacity: 0; transform: translate(-104px, 22px) }
  44%    { opacity: 1; transform: none }
  90%    { opacity: 1; transform: none }
  100%   { opacity: 0; transform: none }
}
.am-spark{ stroke: var(--gold); opacity: .55; }

/* drone */
.ad-body{ stroke: #7D8899; }
.ad-arm{ stroke: #4A5668; }
.ad-lens{ stroke: var(--gold); }
.ad-cone{ stroke: var(--brand-lit); opacity: .22; stroke-dasharray: 10 17; }
.ad-ground{ stroke: #3B4759; stroke-dasharray: 3 24; }
.ad-fly{ animation: adfly 3.6s var(--ease) infinite; }
@keyframes adfly{ 0%,100%{ transform: translateY(0) } 50%{ transform: translateY(-15px) } }
/* las hélices giran moviendo el guionado: así no hace falta un
   transform-origin distinto para cada una */
.ad-rot{ stroke: var(--brand-lit); stroke-dasharray: 30 60; animation: adrot 1.05s linear infinite; }
.ad-rot--b{ animation-direction: reverse; }
@keyframes adrot{ to{ stroke-dashoffset: -90 } }
.ad-frame{ stroke: var(--brand-lit); opacity: .55; }

/* sonido: line array colgado + subwoofers + ondas que salen del rig */
.as-rig{ stroke: #3B4759; stroke-width: 2; }
.as-cab{ stroke: #47546B; }
.as-sub{ stroke: #2B3543; }
.as-cone{ stroke: var(--txt-2); opacity: .45; }
.as-led{ fill: var(--gold); stroke: none; opacity: .4; animation: asled 2.6s var(--ease) var(--ad, 0s) infinite; }
@keyframes asled{ 0%,100%{ opacity: .3 } 50%{ opacity: 1 } }
.as-wave{ stroke: var(--brand-lit); opacity: .3; transform-origin: 450px 300px; animation: aswave 2.8s var(--ease) var(--ad, 0s) infinite; }
@keyframes aswave{ 0%,100%{ opacity: .18; transform: scale(.97) } 50%{ opacity: .5; transform: scale(1.02) } }

/* iluminación: truss con cabezales, el del centro pasea el haz */
.al-truss{ stroke: #3B4759; stroke-width: 3; }
.al-clamp{ stroke: #4A5668; }
.al-yoke{ stroke: #4A5668; stroke-width: 3; }
.al-body{ stroke: #7D8899; }
.al-beam{ stroke: var(--brand-lit); opacity: .2; stroke-dasharray: 10 17; }
.al-beam--warm{ stroke: var(--gold); }
.al-head--c{ transform-origin: 450px 120px; animation: alsweep 4.4s var(--ease) infinite; }
@keyframes alsweep{ 0%,100%{ transform: rotate(-7deg) } 50%{ transform: rotate(7deg) } }

/* pantallas led: pared de módulos con barrido de señal y píxeles vivos */
.ap-frame{ stroke: #47546B; }
.ap-grid path{ stroke: #2A3343; stroke-width: 2; }
.ap-scan{ stroke: var(--brand-lit); animation: apscan 3.8s var(--ease) infinite; }
@keyframes apscan{
  0%   { transform: translateY(0);     opacity: 0 }
  10%  { opacity: 1 }
  90%  { opacity: 1 }
  100% { transform: translateY(280px); opacity: 0 }
}
.ap-px{ fill: var(--gold); stroke: none; opacity: .2; animation: appx 2.6s var(--ease) var(--ad, 0s) infinite; }
@keyframes appx{ 0%,100%{ opacity: .15 } 50%{ opacity: .9 } }
.ap-stand{ stroke: #3B4759; }


/* ficha técnica: lo que lleva el servicio, sin párrafo */
.tags{
  list-style: none; margin: 16px 0 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: 7px;
}
/* Eran píldoras con borde: cinco por tarjeta, treinta en pantalla, y la
   sección entera se leía como una nube de etiquetas. Ahora son rótulos de
   patchera: fondo plano y una marca de color a la izquierda. */
.tags li{
  font-family: var(--display); font-stretch: var(--label-w);
  font-size: var(--label-size); font-weight: 700;
  letter-spacing: var(--track); text-transform: uppercase;
  color: var(--txt-2);
  position: relative;
  display: flex; align-items: center; gap: 7px;
  padding: 5px 10px;
  background: rgba(255,255,255,.045);
  border-radius: 0;
  white-space: nowrap;
}
/* marca de jack, no barra de borde: un punto de patchera en vez del
   acento de color apilado sobre el canto, que es el tell de siempre */
.tags li::before{
  content: ''; flex: none;
  width: 4px; height: 4px; border-radius: 50%;
  background: var(--line-2);
}

.card--wide{
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 28px;
  padding: 34px 32px;
}
/* esta tarjeta ya pone el ícono al costado del bloque de texto, no
   apilado arriba: conserva su placa propia, sólo las seis de
   #servicios pasan al ícono simple en línea con el título */
.card--wide .card__ico{
  width: 46px; height: 46px;
  border-radius: var(--r);
  background: rgba(53,194,238,.10);
  border: 1px solid rgba(53,194,238,.26);
}
/* .card .card__tag y no .card__tag a secas: es un <p> dentro de .card,
   y .card p (0-1-1) le ganaba en especificidad al color y al tamaño */
.card .card__tag{
  font-family: var(--display); font-stretch: var(--label-w);
  font-size: var(--label-size); font-weight: 700;
  letter-spacing: var(--track); text-transform: uppercase;
  color: var(--gold); margin-bottom: 8px;
}
.card__link{
  font-family: var(--display); font-stretch: 100%;
  font-weight: 700; font-size: .95rem;
  color: var(--brand-lit); text-decoration: none;
  white-space: nowrap;
}
.card__link:hover{ text-decoration: underline; }

/* ── pasos ───────────────────────────────────────────── */
.steps{
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: var(--gutter);
  grid-template-columns: repeat(4, 1fr);
  counter-reset: s;
}
.steps li{
  position: relative;
  padding: 0 0 30px;
  border-top: 2px solid var(--line-2);
  overflow: hidden;
}
.steps__img{
  margin: 20px 0 22px;
  aspect-ratio: 3 / 2;
  overflow: hidden;
}
.steps__img img{ width: 100%; height: 100%; object-fit: cover; }
/* el número en tungsteno y sólido: el degradado en cada cifra era el mismo
   truco del titular repetido, y en sólido el número pesa más */
.steps__n{
  display: block;
  font-family: var(--display); font-stretch: var(--display-w);
  font-size: 3.6rem; font-weight: 900; line-height: .9;
  letter-spacing: 0;
  color: var(--tungsten);
  margin-bottom: 14px;
}
.steps h3{ margin-bottom: 8px; }
.steps p{ color: var(--txt-2); font-size: .98rem; line-height: 1.6; }

/* ── galería horizontal ──────────────────────────────────
   La sección mide varias pantallas de alto; adentro, el panel
   queda anclado y la cinta se recorre de costado. El alto que
   hace falta lo calcula script.js con el ancho real de la cinta.
--------------------------------------------------------- */
.hsec{ position: relative; }

/* por defecto —sin JS, con movimiento reducido o en pantalla angosta—
   la cinta es una grilla común. La clase .fx en <html> la convierte
   en el recorrido horizontal anclado. */
.htrack{
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--gutter);
  padding-inline: var(--pad);
  max-width: 1500px; margin-inline: auto;
}
.fx .hpin{
  height: 100svh;
  display: flex; align-items: center;
  overflow: hidden;
}
.fx .htrack{
  display: flex; align-items: stretch;
  gap: var(--gutter);
  max-width: none;
}

.gal{
  position: relative; margin: 0;
  border-radius: var(--r);
  overflow: hidden;
  background: var(--ink-3);
}
.fx .gal{ flex: none; height: min(62svh, 560px); }
.gal img{
  width: 100%; height: 100%;
  object-fit: cover;
  transform: scale(1.05);
  transition: transform .8s var(--ease);
}
.gal:hover img{ transform: scale(1.11); }
.gal{ aspect-ratio: 3 / 4; }
.gal--wide{ aspect-ratio: 3 / 2; }
.htrack .gal--wide{ grid-column: span 2; }
.fx .htrack .gal--wide{ grid-column: auto; }

/* Versalita con --track: bien para "SONIDO" (7 caracteres), no para una
   frase entera ("Cabina técnica · temporada de teatro"): todo mayúsculas
   y con ese tracking en una oración larga es lo que impeccable marca
   como all-caps-body, y de verdad cuesta más leerse. Caja normal. */
.gal figcaption{
  position: absolute; inset: auto 0 0 0;
  padding: 46px 20px 18px;
  background: linear-gradient(transparent, rgba(4,5,7,.9));
  font-family: var(--display); font-stretch: var(--label-w);
  font-size: .92rem; font-weight: 700;
  letter-spacing: .005em;
}

/* último panel de la cinta: la salida a Instagram */
.gal--cta{
  aspect-ratio: 3 / 4;
  display: flex; flex-direction: column; justify-content: flex-end;
  gap: 10px;
  padding: 30px;
  text-decoration: none;
  border: 1px solid var(--line);
  background:
    radial-gradient(120% 80% at 20% 100%, rgba(41,180,224,.18), transparent 60%),
    var(--ink-3);
  transition: border-color .4s var(--ease), background .4s var(--ease);
}
.gal--cta:hover{ border-color: rgba(41,180,224,.5); }
.gal__ctaTag{
  font-family: var(--display); font-stretch: var(--label-w);
  font-size: var(--label-size); font-weight: 700;
  letter-spacing: var(--track); text-transform: uppercase;
  color: var(--brand-lit);
}
.gal__ctaTitle{
  font-family: var(--display); font-stretch: var(--display-w);
  font-size: clamp(1.8rem, 3vw, 2.6rem); font-weight: 800;
  line-height: .95; letter-spacing: -.03em;
}
.gal__ctaArrow{
  width: 30px; height: 30px;
  fill: none; stroke: var(--brand-lit);
  stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round;
  transition: transform .4s var(--ease2);
}
.gal--cta:hover .gal__ctaArrow{ transform: translateX(8px); }

/* ── nosotros ────────────────────────────────────────── */
/* Era una tarjeta con borde y fondo propio flotando en la sección. Sin caja
   y con una sola regla encendida a la izquierda, el texto es el objeto. */
.about{
  max-width: 62ch;
  padding: 4px 0 4px clamp(24px, 3.5vw, 44px);
  border-left: 2px solid var(--brand-lit);
}
/* "Nosotros" era un <p class="eyebrow">: la sección quedaba sin encabezado
   para un lector de pantalla. Es un h2 real, a escala de tarjeta y no de
   sección, porque acá titula un bloque y no una sección entera. */
.about__h{
  font-size: 1.05rem;
  font-stretch: var(--label-w);
  letter-spacing: var(--track);
  text-transform: uppercase;
  color: var(--txt-2);
  margin-bottom: 20px;
}

.about__lead{
  font-family: var(--display); font-stretch: 100%;
  font-size: clamp(1.3rem, 2.5vw, 1.75rem);
  font-weight: 400; line-height: 1.35; letter-spacing: -.015em;
}
.about__lead strong{ font-weight: 800; }

.ticks{
  list-style: none; margin: 28px 0 0; padding: 0;
  display: grid; gap: 11px;
}
.ticks li{
  position: relative; padding-left: 30px;
  color: var(--txt-2); font-size: 1rem;
}
.ticks li::before{
  content: '';
  position: absolute; left: 4px; top: .55em;
  width: 11px; height: 6px;
  border-left: 2px solid var(--brand-lit);
  border-bottom: 2px solid var(--brand-lit);
  transform: rotate(-45deg);
}

/* ── equipo propio ──────────────────────────────────── */
.equipo{
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: var(--gutter);
  grid-template-columns: repeat(3, 1fr);
}
.equipo dt{
  font-family: var(--display); font-stretch: var(--label-w);
  font-size: var(--label-size); font-weight: 700;
  letter-spacing: var(--track); text-transform: uppercase;
  color: var(--brand-lit); margin-bottom: 10px;
}
.equipo dd{ margin: 0; color: var(--txt-2); font-size: .98rem; line-height: 1.6; }

/* ── contacto ────────────────────────────────────────── */
/* ── banda "presupuesto en línea" ──────────────────────
   Acompaña la conversión principal (WhatsApp), no compite: título por
   debajo del titular de Contacto a propósito. */
.calcband{
  border-block: 1px solid var(--line);
  background: var(--ink-2);
  padding-block: clamp(40px, 6vw, 72px);
}
.calcband__inner{
  display: grid;
  grid-template-columns: 1fr auto;
  gap: clamp(24px, 4vw, 56px);
  align-items: center;
}
.calcband__eyebrow{
  font-family: var(--display); font-stretch: var(--label-w);
  font-size: var(--label-size); font-weight: 700;
  letter-spacing: var(--track); text-transform: uppercase;
  color: var(--brand-lit);
}
.calcband__title{
  font-size: clamp(1.5rem, 3.2vw, 2.2rem);
  margin: 10px 0 12px;
}
.calcband__lead{ color: var(--txt-2); font-size: 1.02rem; max-width: 52ch; margin: 0; }

.contact{ overflow: hidden; background: var(--ink-2); }
/* El cierre estaba centrado como todo cierre de landing. Alineado a la
   izquierda comparte el eje con el resto de la página y el titular grande
   tiene de dónde arrancar. */
.contact__inner{ position: relative; z-index: 2; }
.contact__title{ font-size: clamp(3rem, 9vw, 7rem); }
.contact__lead{
  color: var(--txt-2);
  font-size: 1.12rem;
  margin: 28px 0 40px;
  max-width: 46ch;
}
.contact__actions{
  display: flex; flex-wrap: wrap; gap: 12px;
}
.contact__meta{
  display: grid; gap: 22px;
  grid-template-columns: repeat(3, 1fr);
  margin: 72px 0 0;
  border-top: 1px solid var(--line);
  padding-top: 32px;
}
.contact__meta dt{
  font-family: var(--display); font-stretch: var(--label-w);
  font-size: var(--label-size); font-weight: 700;
  letter-spacing: var(--track); text-transform: uppercase;
  color: var(--brand-lit); margin-bottom: 6px;
}
.contact__meta dd{ margin: 0; color: var(--txt-2); font-size: .98rem; line-height: 1.5; }

/* ── footer ──────────────────────────────────────────── */
.foot{
  border-top: 1px solid var(--line);
  padding-block: 64px 40px;
  text-align: center;
}
.foot__inner{ display: grid; justify-items: center; gap: 20px; }
.foot__logo{ width: 96px; opacity: .9; }
.motto--foot{ font-size: 1.5rem; }
.foot__links{ display: flex; flex-wrap: wrap; gap: 8px 26px; justify-content: center; }
.foot__links a{
  font-family: var(--display); font-stretch: var(--label-w);
  font-size: .74rem; font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--txt-2); text-decoration: none;
  transition: color .25s var(--ease);
}
.foot__links a:hover{ color: var(--txt); }
.foot__copy{ color: #939CAA; font-size: .86rem; }   /* 5.0:1 sobre el fondo */

/* ── botón flotante de WhatsApp ──────────────────────── */
.wafab{
  position: fixed; right: 20px; bottom: 20px; z-index: 90;
  display: grid; place-items: center;
  width: 56px; height: 56px; border-radius: 50%;
  background: #25D366; color: #06281A;
  box-shadow: 0 14px 34px -10px rgba(0,0,0,.6);
  opacity: 0; visibility: hidden;
  transform: scale(.6) translateY(12px);
  transition: opacity .4s var(--ease), transform .4s var(--ease2), visibility .4s;
}
.wafab.is-on{ opacity: 1; visibility: visible; transform: none; }
.wafab .i-wa{ width: 30px; height: 30px; }
.wafab:hover{ transform: scale(1.07); }

/* ── entradas al hacer scroll ────────────────────────── */
.js .reveal{
  opacity: 0;
  transform: translateY(26px);
  filter: blur(6px);
  transition: opacity .8s var(--ease2) var(--d, 0s),
              transform .8s var(--ease2) var(--d, 0s),
              filter .8s var(--ease2) var(--d, 0s);
}
.js .reveal.is-in{ opacity: 1; transform: none; filter: none; }

/* ── dónde estamos ───────────────────────────────
   El mapa es un SVG armado con datos de OpenStreetMap y servido
   desde acá: no hay iframe, ni pedido a Google, ni cookie de
   terceros. Las calles se dibujan solas al entrar en pantalla.
   Datos © colaboradores de OpenStreetMap (ODbL).
--------------------------------------------------------- */
.map{
  position: relative;
  aspect-ratio: 12 / 5;
  border: 1px solid var(--line);
  border-radius: var(--r);
  overflow: hidden;
  background:
    radial-gradient(70% 120% at 50% 50%, rgba(41,180,224,.09) 0%, transparent 60%),
    linear-gradient(180deg, #0B1017 0%, var(--ink-2) 100%);
}
.map__svg{
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  fill: none; stroke-linecap: round; stroke-linejoin: round;
}
.r-fai{ stroke: #1D2029; stroke-width: 2; }
.r-min{ stroke: #2B3442; stroke-width: 3; }
.r-maj{ stroke: #45546B; stroke-width: 5; }
.r-ruta{ stroke: var(--brand-lit); stroke-width: 7; }
.r-hero{ stroke: var(--brand-lit); stroke-width: 5; opacity: .8; }

.js .map__roads path{ stroke-dasharray: 1; stroke-dashoffset: 1; }
.js .map.is-in .map__roads path{ animation: mapdraw 1.6s var(--ease2) var(--t, 0s) forwards; }
@keyframes mapdraw{ to{ stroke-dashoffset: 0 } }

.map__pin{ position: absolute; left: 50%; top: 50%; z-index: 2; }
.map__pulse{
  position: absolute; left: 0; top: 0;
  width: 24px; height: 24px; margin: -12px 0 0 -12px;
  border: 1px solid var(--brand-lit); border-radius: 50%;
  opacity: 0;
  animation: mappulse 2.9s var(--ease2) var(--d, 0s) infinite;
}
@keyframes mappulse{
  0%  { transform: scale(.35); opacity: .85 }
  72% { opacity: 0 }
  100%{ transform: scale(6.4); opacity: 0 }
}
.map__dot{
  position: absolute; left: 0; top: 0;
  width: 40px; height: 40px; margin: -40px 0 0 -20px;
  fill: none; stroke: var(--brand-lit); stroke-width: 1.7;
  filter: drop-shadow(0 3px 10px rgba(0,0,0,.6));
}
.map__dot path{ fill: rgba(8,10,14,.88); }

.map__card{
  position: absolute; left: 22px; bottom: 22px; z-index: 3;
  max-width: min(340px, calc(100% - 44px));
  padding: 20px 22px;
  border: 1px solid var(--line-2); border-radius: var(--r);
  background: rgba(9,11,15,.84);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
}
.map__eyebrow{
  font-family: var(--display); font-stretch: var(--label-w);
  font-size: var(--label-size); font-weight: 700;
  letter-spacing: var(--track); text-transform: uppercase;
  color: var(--brand-lit); margin-bottom: 8px;
}
.map__addr{ color: var(--txt); font-size: 1rem; line-height: 1.5; margin-bottom: 14px; }
.map__go{
  display: inline-block;
  font-family: var(--display); font-stretch: var(--label-w);
  font-size: var(--label-size); font-weight: 700;
  letter-spacing: var(--track); text-transform: uppercase;
  color: var(--brand-lit); text-decoration: none;
  border-bottom: 1px solid rgba(41,180,224,.35);
  padding-bottom: 2px;
  transition: border-color .3s var(--ease);
}
.map__go:hover{ border-color: var(--brand-lit); }
.map__attr{
  position: absolute; right: 12px; bottom: 10px; z-index: 3;
  font-size: .7rem; color: #8C97A6;   /* 5.5:1 — antes #6B7482 daba 4.07:1 */
}
/* el area tactil llega a 24 px sin agrandar la letra (WCAG 2.5.8) */
.map__attr a{
  color: #8C97A6;
  display: inline-block;
  padding: 6px 4px; margin: -6px -4px;
}

/* ── responsive ──────────────────────────────────────── */

/* Entre 901 px (donde todavía no hay burger) y 1200 px, seis enlaces + el lockup
   de marca completo no entran en una línea y la barra se partía en dos. El
   isotipo SA solo alcanza para identificar a esa altura: libera ~120 px y la
   barra vuelve a una sola línea. */
@media (max-width: 1200px){
  .nav__brand span{ display: none; }
  /* nada de la barra se comprime: con flex:none el isotipo y el botón
     conservan su ancho natural y el sobrante lo absorben los enlaces */
  .nav__brand, .nav .btn--sm{ flex: none; }
  .nav__links{ gap: 16px; white-space: nowrap; }
}

@media (max-width: 1000px){
  .cards{ grid-template-columns: repeat(2, 1fr); }
  .steps{ grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 900px){
  .nav__links{ display: none; }
  .nav__burger{ display: flex; }
  .nav .btn--sm span{ display: none; }
  .nav .btn--sm{ padding: 10px 12px; }
  .hero{ padding-block: 116px 64px; }
  /* el riel se apila y la columna técnica vuelve a la izquierda */
  .hero__rail{ grid-template-columns: 1fr; gap: 32px; }
  .hero__side{ justify-items: start; text-align: left; }
  .hero__facts{ justify-items: start; }
  .hero__facts li{ flex-direction: row; }
  .contact__meta{ grid-template-columns: 1fr; gap: 18px; }
  .equipo{ grid-template-columns: 1fr; gap: 24px; }
  .card--wide{ grid-template-columns: 1fr; gap: 18px; }
  .map{ aspect-ratio: 4 / 3; }
  .htrack{ grid-template-columns: repeat(2, 1fr); }
  .calcband__inner{ grid-template-columns: 1fr; }
  .calcband__inner .btn{ justify-self: start; }
  /* .stg vive dentro de .pinsec, que sólo existe con .fx, y .fx sólo
     se activa arriba de 900 px: acá no había nada que ajustar. */
}

@media (max-width: 640px){
  body{ font-size: 16px; }
  .map{ aspect-ratio: 3 / 4; }
  .map__card{ left: 14px; right: 14px; bottom: 14px; max-width: none; padding: 16px 18px; }
  /* abajo a la derecha la tapa el botón de WhatsApp, y la atribución
     de OpenStreetMap es obligatoria: en pantalla chica va arriba */
  .map__attr{ top: 10px; bottom: auto; }
  .cards{ grid-template-columns: 1fr; }
  .steps{ grid-template-columns: 1fr; }
  .htrack{ grid-template-columns: 1fr; }
  .htrack .gal--wide{ grid-column: auto; }
  .hero__scroll{ display: none; }
  .foot__links{ gap: 6px 18px; }
  .pre__skip{ bottom: 20px; }
}

/* ── movimiento reducido ─────────────────────────────────
   No se apaga todo: lo que molesta es el desplazamiento grande
   y lo que se mueve solo en loop. Los fundidos de opacidad se
   quedan, así la página sigue teniendo vida sin marear.
   (Windows: Configuración › Accesibilidad › Efectos visuales
   › Efectos de animación activa o desactiva esta rama.)
--------------------------------------------------------- */
@media (prefers-reduced-motion: reduce){
  /* Reducir, no apagar — segunda pasada.
     La primera versión dejaba la página en cero animaciones; la segunda
     todavía cortaba de más. En Windows los efectos de animación vienen
     apagados en muchísimas máquinas, así que esta rama la ve un montón
     de gente que nunca pidió una página quieta.

     Hoy queda casi todo: los fundidos con su desplazamiento, el zoom de
     las fotos, las ondas, el grano, el haz, los trazos que se dibujan,
     los dibujos de las tarjetas y los títulos que suben línea por línea.

     Se corta lo que le saca el scroll de las manos al visitante —las
     secciones clavadas, la galería horizontal y el scroll suave, todo
     eso vive en script.js— y acá sólo la marquesina.

     La marquesina se frena porque es lo único que se mueve solo y sin
     fin: dejándola quieta en esta rama queda una forma real de pararla
     para quien la necesite. Además envuelve y se centra, así se leen
     los siete servicios enteros en vez de quedar cortados por el
     overflow; script.js tampoco duplica el contenido acá.

     Todo va condicionado a :root:not(.motion-full), así el botón de
     abajo a la izquierda devuelve la versión completa sin que nadie
     tenga que tocar la configuración del sistema. */

  :root:not(.motion-full) .ticker__track{
    animation: none !important;
    flex-wrap: wrap; justify-content: center;
    width: auto; row-gap: 6px;
  }
  :root:not(.motion-full) .ticker{ -webkit-mask-image: none; mask-image: none; }

  /* Tercera pasada. La marquesina no era lo único que se movía solo y sin fin:
     quedaban once bucles infinitos más —el grano, la rueda del hero, el brazo
     y el halo del Selfie 360, el barrido y la copia del espejo, el vuelo y las
     hélices del drone, y los dos anillos del pin del mapa— corriendo siempre,
     también fuera de pantalla. WCAG 2.2.2 pide una forma de pararlos, y esta
     rama es justo la de quien la necesita. Se detienen en un estado legible:
     el dibujo sigue explicando el servicio, sólo que quieto. Todo lo demás
     —los fundidos, el zoom de las fotos, el haz, los trazos que se dibujan,
     los títulos línea por línea— se queda. */
  :root:not(.motion-full) :is(
    .grain,
    .hero__scroll span,
    .a3-spin, .a3-halo,
    .am-scan, .am-print,
    .ad-fly, .ad-rot,
    .as-led, .as-wave,
    .al-head--c,
    .ap-scan, .ap-px
  ){ animation: none !important; }

  /* estos dos sólo existen mientras se expanden: quietos serían dos círculos
     sueltos alrededor del pin, así que se retiran y queda el pin solo */
  :root:not(.motion-full) .map__pulse{ display: none; }
}

/* ══ scroll narrado (SAW-4, spec: scroll-spec.md) ═══════════════════════
   Tres capas, como el resto de la página:
     base      → sin JS o con movimiento reducido: bloques normales, afiches
     .sx       → JS + GSAP sin reducido: manifiesto sticky
     .sx-d/.sx-m → escritorio / mobile: escenas de servicios sticky
   Todo sticky es nativo (sin pin de GSAP): ningún ancestro lleva overflow. */

/* LCP: el párrafo del hero es el elemento más grande que pinta el navegador.
   Con opacity:0 hasta que JS lo suelta (y con JS cargando 3-4 s en un celular
   de gama media) el LCP se iba a ~4,6 s. Ahora está pintado desde el primer
   cuadro, desenfocado, y se enfoca al entrar: sólo cambia transform y blur. */
.js .hero__lead.reveal{ opacity: 1; }

/* marco de video: el afiche es un <img>; el <video> lo agrega script.js
   encima y entra con un fundido recién cuando empieza a reproducir */
.vf{ position: relative; margin: 0; overflow: hidden; background: var(--ink-3); }
.vf img, .vf video{
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; display: block;
}
.vf video{ opacity: 0; transition: opacity .6s var(--ease); }
.vf.is-playing video{ opacity: 1; }
.vf--main::after{
  content: ''; position: absolute; inset: 0; z-index: 3; pointer-events: none;
  background: rgba(5,6,10,var(--dim, 0));
}

/* botón pausar/reproducir (WCAG 2.2.2) */
.vpause{
  position: absolute; z-index: 6; width: 44px; height: 44px; padding: 0;
  display: grid; place-items: center; cursor: pointer;
  background: rgba(5,6,10,.55); border: 1px solid rgba(233,237,242,.35);
  color: var(--txt);
}
.vpause:focus-visible{ outline: 2px solid var(--brand-lit); outline-offset: 2px; }
.vpause svg{ width: 14px; height: 14px; fill: currentColor; }
.vpause .i-play{ display: none; }
.vpause[aria-pressed="true"] .i-play{ display: block; }
.vpause[aria-pressed="true"] .i-pause{ display: none; }
.vpause--hero{ right: 48px; bottom: 96px; }
.vf--main > .vpause{ left: 12px; bottom: 12px; }            /* bloques apilados: la secundaria ocupa la derecha */
.sx-d .vf--main > .vpause{ left: auto; right: 12px; }        /* escenario: esquina inferior derecha, como la spec */

/* manifiesto (reemplaza la franja de confianza) */
.manifest{
  --rx: 50%;
  border-block: 1px solid var(--line);
  padding: clamp(64px, 9vw, 120px) var(--pad);
  background: radial-gradient(900px 600px at var(--rx) 60%, rgba(53,194,238,.10), transparent 70%), var(--ink);
}
.manifest__txt{
  margin: 0 auto; max-width: 1180px;
  font-family: var(--display); font-stretch: var(--display-w);
  font-weight: 800; text-transform: uppercase;
  font-size: clamp(2.6rem, 5.2vw, 4.75rem); line-height: 1.02;
  color: var(--txt);
}
.manifest__txt .grad{ background: var(--beam); -webkit-background-clip: text; background-clip: text; color: transparent; }
.sx .manifest{ height: 220svh; padding: 0; }
.sx .manifest__stick{
  position: sticky; top: 0; height: 100svh;
  display: grid; align-items: center; padding-inline: var(--pad);
}

/* escenas de servicios: base = bloques apilados */
.scenes{ position: relative; margin-top: clamp(32px, 5vw, 64px); }
.scn{
  position: relative; max-width: var(--wrap); margin: 0 auto;
  padding: 56px var(--pad); border-top: 1px solid var(--line);
  display: grid; gap: 28px;
}
.scn__n{
  font-family: var(--display); font-stretch: var(--label-w);
  font-size: var(--label-size); font-weight: 700;
  letter-spacing: var(--track); text-transform: uppercase; color: var(--txt-2);
}
.scn h3{
  font-weight: 900; text-transform: uppercase; font-stretch: var(--display-w);
  font-size: clamp(3.25rem, 6.6vw, 6rem); line-height: 1;
  padding-top: .2em; margin: -.2em 0 22px;
}
.scn__txt .scn__n{ display: block; margin-top: .2em; }
.scn p{ color: var(--txt-2); font-size: 1.19rem; line-height: 1.5; max-width: 46ch; margin-bottom: 20px; }
.scn__media{ position: relative; width: min(100%, 320px); aspect-ratio: 9 / 16; }
.vf--main{ position: absolute; inset: 0; border: 1px solid var(--line-2); }
.vf--sec{
  position: absolute; z-index: 2; right: -8px; bottom: 28px;
  border: 1px solid var(--line-2); box-shadow: 0 30px 60px rgba(0,0,0,.6);
}
.vf--wide{ width: 160px; aspect-ratio: 16 / 9; }
.vf--tall{ width: 112px; aspect-ratio: 9 / 16; }
.scenes__rail{ display: none; }
.otros{
  margin: 56px 0 18px;
  font-family: var(--display); font-stretch: var(--label-w);
  font-size: var(--label-size); font-weight: 700;
  letter-spacing: var(--track); text-transform: uppercase; color: var(--txt-2);
}

@media (min-width: 901px){
  .scn{ grid-template-columns: 1fr 1fr; align-items: center; gap: 56px; }
}

/* escritorio: un escenario sticky, las cuatro escenas superpuestas */
.sx-d .scenes{ height: 450svh; margin-top: 0; }
.sx-d .scenes__stage{ position: sticky; top: 0; height: 100svh; display: grid; background: var(--ink); }
.sx-d .scn{
  grid-area: 1 / 1; max-width: none; margin: 0; border: 0; height: 100svh;
  padding: 0 120px; gap: 22px; grid-template-columns: repeat(12, 1fr);
}
/* las cuatro escenas ocupan la misma celda: el artículo no recibe clics,
   sólo su marco (y script.js pone inert al de las escenas no activas) */
.sx-d .scn{ pointer-events: none; }
.sx-d .scn__media{ pointer-events: auto; }
.sx-d .scn__txt{ grid-column: 1 / 7; }
.sx-d .scn__media{
  grid-column: 8 / 12; justify-self: center;
  width: auto; height: min(78svh, 760px);
}
.sx-d .scn:not(:first-of-type) :is(.scn__n, p, .tags){ opacity: 0; }
.sx-d .scn:not(:first-of-type) .vf--main{ clip-path: inset(100% 0 0 0); }
.sx-d .scn:not(:first-of-type) .vf--sec{ opacity: 0; }
.sx-d .vf--wide{ width: 300px; right: -150px; bottom: 90px; }
.sx-d .vf--tall{ width: 180px; right: -110px; bottom: 150px; }
.sx-d .scn[data-scn="2"] .vf--tall{ bottom: 70px; }
.sx-d .scn__edge{
  position: absolute; left: 0; right: 0; top: 100%; height: 2px; z-index: 4;
  background: var(--brand-lit); box-shadow: 0 0 18px var(--brand-lit); pointer-events: none;
}
.sx-d .scenes__rail{
  display: grid; gap: 10px; margin: 0; padding: 0; list-style: none;
  position: absolute; right: 56px; top: 50%; transform: translateY(-50%); z-index: 5;
}
.sx-d .scenes__rail li{ width: 2px; height: 44px; background: var(--line-2); transition: background .3s var(--ease); }
.sx-d .scenes__rail li.is-on{ background: var(--brand-lit); }

/* mobile: pila de bloques de 100svh, cada uno tapa al anterior */
.sx-m .scenes{ margin-top: 0; }
.sx-m .scn{
  position: sticky; top: 0; height: 100svh; max-width: none; margin: 0; border: 0;
  padding: 0 20px 28px; background: var(--ink); overflow: hidden;
  display: flex; flex-direction: column; justify-content: flex-end; gap: 0;
  transform-origin: 50% 0;
}
.sx-m .scn::after{
  content: ''; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background:
    linear-gradient(rgba(5,6,10,var(--dim, 0)), rgba(5,6,10,var(--dim, 0))),
    linear-gradient(180deg, rgba(5,6,10,.5) 0%, rgba(5,6,10,0) 18%, rgba(5,6,10,0) 28%, rgba(5,6,10,.85) 48%, #05060A 66%);
}
.sx-m .scn__media{ position: absolute; inset: 0; width: auto; aspect-ratio: auto; }
.sx-m .vf--main{ border: 0; }
.sx-m .scn__txt{ position: relative; z-index: 2; }
.sx-m .scn h3{ font-size: 52px; margin-bottom: 12px; }
.sx-m .scn p{ font-size: 15.5px; margin-bottom: 14px; }
.sx-m .scn .tags li:nth-child(n+3){ display: none; }
.sx-m .vf--sec{ top: 88px; right: 16px; bottom: auto; }
.sx-m .vf--wide{ width: 160px; }
.sx-m .vf--tall{ width: 112px; }

@media (max-width: 900px){
  .hero__media{ grid-template-columns: 1fr; }
  .hero__col--l, .hero__col--r, .hero__veilc{ display: none; }
  .hero::after{
    /* en mobile el texto del hero ocupa más de la mitad de la pantalla: el
       velo sube antes que en la spec para que todo texto quede sobre ≥ .82 */
    background: linear-gradient(180deg, rgba(5,6,10,.55) 0%, rgba(5,6,10,.4) 18%, rgba(5,6,10,.78) 40%, rgba(5,6,10,.88) 60%, #05060A 100%);
  }
  .sx-m .vf--main > .vpause{ top: 88px; left: 16px; right: auto; bottom: auto; }
  .vpause--hero{ top: 88px; right: 16px; bottom: auto; }
}
