:root{
  --black:#000000;
  --near-black:#060807;
  --panel:#0b0f0d;
  --mint:#4EE4AB;
  --lightgreen:#D3FDA5;
  --gray:#A4A4A4;
  --white:#F5F7F5;
  --line: rgba(255,255,255,0.12);
  --ff-head:'Satoshi', 'Space Grotesk', sans-serif;
  --ff-body:'Space Grotesk', 'Satoshi', sans-serif;
  --ease: cubic-bezier(.16,.84,.44,1);
  --container: min(1400px, 92vw);
}

/* usado por el anillo de gradiente en movimiento alrededor del logo — permite
   animar el ángulo del conic-gradient con una curva lineal continua */
@property --nxt-angle{
  syntax:'<angle>';
  initial-value:0deg;
  inherits:false;
}

*{margin:0;padding:0;box-sizing:border-box;}
html{background:var(--black);}
html,body{width:100%;overflow-x:hidden;}
body{
  background:var(--black);
  color:var(--white);
  font-family:var(--ff-body);
  font-weight:400;
  line-height:1.5;
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
}
::selection{background:var(--mint);color:var(--black);}

h1,h2,h3,h4{
  font-family:var(--ff-head);
  font-weight:500;
  letter-spacing:-0.02em;
  line-height:1.02;
  text-transform:uppercase;
}

a{color:inherit;text-decoration:none;}
img,svg{display:block;max-width:100%;}
button{font-family:inherit;cursor:pointer;border:none;background:none;color:inherit;}
ul{list-style:none;}

.container{width:var(--container);margin-inline:auto;}

/* ---------- utility ---------- */
.eyebrow{
  font-family:var(--ff-body);
  text-transform:uppercase;
  letter-spacing:0.28em;
  font-size:11px;
  color:var(--mint);
  display:flex;
  align-items:center;
  gap:10px;
}
.eyebrow::before{
  content:'';
  width:6px;height:6px;border-radius:50%;
  background:var(--mint);
  box-shadow:0 0 8px 1px rgba(78,228,171,0.55);
  flex:none;
}
.eyebrow-logo{
  height:10px;width:auto;
  vertical-align:middle;
  margin-top:-2px;
  display:inline-block;
}
.mint{color:var(--mint);}
.gray{color:var(--gray);}

.reveal{
  opacity:0;
  transform:translateY(40px);
}

.btn{
  position:relative;
  display:inline-flex;
  align-items:center;
  gap:10px;
  padding:16px 30px;
  border-radius:3px;
  font-size:13px;
  letter-spacing:0.05em;
  text-transform:uppercase;
  font-weight:600;
  overflow:hidden;
  isolation:isolate;
}
.btn-primary{
  background:var(--mint);
  color:var(--black);
}
.btn-primary .btn-fill{
  position:absolute;inset:0;
  background:var(--lightgreen);
  transform:translateY(101%);
  transition:transform .5s var(--ease);
  z-index:-1;
}
.btn-primary:hover .btn-fill{transform:translateY(0);}
.btn-ghost{
  border:1px solid var(--line);
  color:var(--white);
  transition:border-color .3s, background .3s;
}
.btn-ghost:hover{border-color:var(--mint); background:rgba(78,228,171,0.08);}
.btn-arrow{transition:transform .4s var(--ease);}
.btn:hover .btn-arrow{transform:translateX(4px) translateY(-4px);}

/* subdued secondary action — used where a button would compete with the primary CTA */
.link-quiet{
  display:inline-flex;
  align-items:center;
  gap:8px;
  color:var(--gray);
  font-size:12.5px;
  letter-spacing:0.08em;
  text-transform:uppercase;
  font-weight:600;
  padding-bottom:4px;
  border-bottom:1px solid var(--line);
  transition:color .3s var(--ease), border-color .3s var(--ease);
}
.link-quiet:hover{color:var(--white); border-color:var(--mint);}
.link-quiet svg{transition:transform .4s var(--ease);}
.link-quiet:hover svg{transform:translateX(4px);}

/* ---------- custom cursor ---------- */
.cursor-dot, .cursor-ring{
  position:fixed;top:0;left:0;
  pointer-events:none;
  z-index:9999;
  border-radius:50%;
  transform:translate(-50%,-50%);
  mix-blend-mode:difference;
}
.cursor-dot{width:6px;height:6px;background:var(--mint);}
.cursor-ring{
  width:36px;height:36px;
  border:1px solid var(--mint);
  transition:width .25s var(--ease), height .25s var(--ease), opacity .25s;
}
.cursor-ring.is-active{width:64px;height:64px;background:rgba(78,228,171,0.12);}
.cursor-ring.has-label{opacity:0;}
.cursor-label{
  position:fixed;top:0;left:0;
  pointer-events:none;
  z-index:10001;
  transform:translate(-50%,-50%) scale(0.5);
  background:var(--mint);
  color:var(--black);
  font-family:var(--ff-head);
  font-weight:700;
  font-size:12px;
  letter-spacing:0.06em;
  text-transform:uppercase;
  padding:12px 20px;
  border-radius:100px;
  white-space:nowrap;
  opacity:0;
  transition:opacity .3s var(--ease), transform .3s var(--ease);
}
.cursor-label.is-visible{opacity:1;transform:translate(-50%,-50%) scale(1);}
@media (hover:none), (pointer:coarse){
  .cursor-dot,.cursor-ring,.cursor-label{display:none;}
}

/* ---------- preloader ---------- */
#preloader{
  position:fixed;inset:0;background:var(--black);
  z-index:10000;
  display:flex;align-items:center;justify-content:center;
  flex-direction:column;gap:22px;
}
#preloader .logo-mark{
  position:relative;
  width:clamp(200px,32vw,360px);
}
#preloader .logo-mark img{
  display:block;
  width:100%;
  height:auto;
}
#preloader .logo-mark .base{opacity:0.18;}
#preloader .logo-mark .fill{
  position:absolute;inset:0;
  /* Degradé (no color plano) a propósito: el filtro SVG de abajo desplaza
     los píxeles del fondo para que se vea "líquido" — sobre un color plano
     ese desplazamiento no cambiaría nada visible, sobre un degradé sí se
     nota como una leve ondulación orgánica en vez de una banda perfecta. */
  background:linear-gradient(135deg, var(--mint), var(--lightgreen));
  -webkit-mask-image:url('assets/nxt-logo.png');
  mask-image:url('assets/nxt-logo.png');
  -webkit-mask-repeat:no-repeat; mask-repeat:no-repeat;
  -webkit-mask-size:100% 100%; mask-size:100% 100%;
  clip-path:inset(0 100% 0 0);
  filter:url(#glassMaterialize);
}
#preloader .logo-mark .pulse{
  position:absolute;inset:-30%;
  background:radial-gradient(circle, rgba(78,228,171,0.55), transparent 70%);
  opacity:0;
  pointer-events:none;
  filter:blur(6px);
}
#preloader .logo-mark::before{
  content:'';
  position:absolute;
  inset:-16% -6%;
  border-radius:8px;
  padding:1px;
  background:conic-gradient(from var(--nxt-angle), transparent 0deg, transparent 250deg, var(--lightgreen) 300deg, var(--mint) 330deg, transparent 360deg);
  -webkit-mask:linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite:xor;
  mask-composite:exclude;
  opacity:0.65;
  animation:nxt-ring 2.1s linear infinite;
}
@media (prefers-reduced-motion: reduce){
  #preloader .logo-mark::before{ animation:none !important; opacity:0; }
}
#preloader .bar{
  width:180px;height:1px;background:var(--line);
  position:relative;overflow:hidden;
}
#preloader .bar span{
  position:absolute;left:0;top:0;bottom:0;width:0%;
  background:var(--mint);
}
#preloader .pct{font-size:11px;letter-spacing:.2em;color:var(--gray);}

/* ---------- nav ---------- */
header{
  position:fixed;top:0;left:0;width:100%;
  z-index:500;
  padding:22px 0;
  transition:padding .4s var(--ease), background .4s var(--ease), border-color .4s var(--ease);
  border-bottom:1px solid transparent;
}
header.scrolled{
  padding:14px 0;
  background:rgba(6,8,7,0.72);
  backdrop-filter:blur(16px) saturate(140%);
  -webkit-backdrop-filter:blur(16px) saturate(140%);
  border-bottom:1px solid var(--line);
}
/* Con el menú mobile abierto, sacamos el backdrop-filter: un backdrop-filter
   (o transform/filter/perspective) en un ancestro crea un nuevo "containing
   block" para los descendientes position:fixed. El panel del menú (nav.links,
   más abajo) es fixed+inset:0 pensado para cubrir toda la pantalla, así que
   si el header (su ancestro) tiene backdrop-filter activo, el panel se fija
   relativo al header (una franja angosta) en vez de al viewport completo, y
   el contenido del menú se desborda sin fondo sólido detrás. */
header.menu-open{
  backdrop-filter:none !important;
  -webkit-backdrop-filter:none !important;
}
.nav-inner{
  display:flex;align-items:center;justify-content:space-between;
}
.logo{
  position:relative;
  display:inline-flex;align-items:center;
  padding:9px 16px;
  border-radius:4px;
}
.logo-img{
  display:block;
  width:auto;
  transition:opacity .3s;
}
.logo:hover .logo-img{opacity:0.8;}

/* Anillo de gradiente en movimiento — efecto propio (canvas/CSS vanilla),
   inspirado en la categoría "moving gradient border": no se usó el
   componente de Originkit (React + Framer Motion, de pago) ya que este
   sitio es JS vanilla sin build step. Solo se enciende con hover/foco para
   no quedar siempre animando alrededor de la marca. */
.logo::before{
  content:'';
  position:absolute;inset:0;
  border-radius:inherit;
  padding:1px;
  background:conic-gradient(from var(--nxt-angle), transparent 0deg, transparent 250deg, var(--lightgreen) 300deg, var(--mint) 330deg, transparent 360deg);
  -webkit-mask:linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite:xor;
  mask-composite:exclude;
  opacity:0.85;
  animation:nxt-ring 2.6s linear infinite;
  pointer-events:none;
}
@keyframes nxt-ring{ to{ --nxt-angle:360deg; } }
@media (prefers-reduced-motion: reduce){
  .logo::before{ animation:none !important; opacity:0; }
}
header .logo-img{height:20px;}
.foot-brand .logo-img{height:27px;}
nav.links{display:flex;align-items:center;gap:38px;}
nav.links a{
  font-size:13px;
  text-transform:uppercase;
  letter-spacing:0.06em;
  color:var(--gray);
  position:relative;
  padding-bottom:4px;
  transition:color .3s;
}
nav.links a::after{
  content:'';position:absolute;left:0;bottom:0;
  width:0;height:1px;background:var(--mint);
  transition:width .35s var(--ease);
}
nav.links a:hover{color:var(--white);}
nav.links a:hover::after{width:100%;}
.nav-right{display:flex;align-items:center;gap:28px;}
.burger{display:none;flex-direction:column;gap:5px;width:26px;z-index:600;}
.burger span{height:1px;background:var(--white);width:100%;transition:transform .3s, opacity .3s;}

/* Efectos de sonido: botón de silencio inyectado por JS en .nav-right (ver
   initSfxToggle() en app.js) — sin borde propio, se apoya en el mismo
   tratamiento sutil que los nav-link. */
.sfx-toggle{
  display:flex;align-items:center;justify-content:center;
  width:32px;height:32px;border:none;background:none;padding:0;
  color:var(--white);opacity:.75;cursor:pointer;
  transition:opacity .25s var(--ease), color .25s var(--ease);
}
.sfx-toggle:hover{opacity:1;color:var(--mint);}
.sfx-toggle.is-muted{opacity:.45;}
.sfx-toggle:focus-visible{outline:2px solid var(--mint);outline-offset:3px;}

/* ---------- hero ---------- */
.hero{
  position:relative;
  min-height:100svh;
  display:flex;
  flex-direction:column;
  justify-content:center;
  overflow:hidden;
  background:var(--black);
  padding-top:100px;
  /* un poco más que el padding-bottom genérico de .section (150px) — deja
     lugar de sobra para que la franja de logos del hero nunca choque con
     el indicador "SCROLL" de abajo */
  padding-bottom:172px;
}
/* Video de fondo sutil: toma aérea real (drone DJI), oscurecida con -32%
   de brillo (pedido: al menos -30%) más el degradé de siempre, para que
   quede como textura ambiental de fondo y no compita con el texto — el
   glow mint y su parallax siguen intactos por encima. */
.hero-bg{
  position:absolute;
  inset:-4%;
  width:108%;height:108%;
  z-index:0;
  overflow:hidden;
  pointer-events:none;
}
.hero-bg-video{
  width:100%;height:100%;
  object-fit:cover;
  object-position:center 45%;
  filter:grayscale(0.2) brightness(0.68) contrast(0.98) saturate(0.85);
  opacity:0.9;
}
.hero-bg::after{
  content:'';
  position:absolute;inset:0;
  background:
    linear-gradient(180deg, var(--black) 0%, rgba(0,0,0,0.8) 8%, rgba(0,0,0,0.35) 24%, rgba(0,0,0,0.3) 50%, rgba(0,0,0,0.5) 84%, var(--black) 100%),
    radial-gradient(ellipse 65% 55% at 32% 42%, rgba(0,0,0,0.3) 0%, transparent 62%);
}
.hero-glow{
  position:absolute;
  width:60vw;height:60vw;
  max-width:900px;max-height:900px;
  right:-10vw;top:50%;
  transform:translateY(-50%);
  background:radial-gradient(circle at 40% 40%, rgba(78,228,171,0.35), rgba(78,228,171,0.06) 45%, transparent 70%);
  filter:blur(10px);
  z-index:0;
  pointer-events:none;
}
.hero-content{position:relative;z-index:2;}
.hero-top{
  display:flex;justify-content:space-between;align-items:flex-end;
  margin-bottom:18px;
}
.hero h1{
  font-size:clamp(46px, 8.4vw, 128px);
  color:var(--white);
}
.hero h1 .line{overflow:hidden;display:block;}
.hero h1 .line span{display:inline-block;will-change:transform;}
.hero h1 em{
  font-style:normal;
  color:transparent;
  -webkit-text-stroke:1px var(--mint);
}
/* texto oculto solo para lectores de pantalla (p.ej. la palabra "que" que
   el isotipo de NXT reemplaza visualmente en el título) */
.sr-only{
  position:absolute;width:1px;height:1px;
  padding:0;margin:-1px;overflow:hidden;
  clip:rect(0,0,0,0);white-space:nowrap;border:0;
}

/* ---------- isotipo NXT "de vidrio" dentro del título del hero ---------- */
/* Reemplaza la palabra "QUE" del título (queda accesible vía .sr-only).
   Es la X del isotipo NXT (el mismo trazo del logo, recortado del propio
   archivo assets/nxt-logo.png) con un tratamiento tipo vidrio: relleno en
   degradé de marca, un brillo diagonal que la recorre en loop y un leve
   balanceo 3D — mismo lenguaje de "cristal" que ya usa el sitio (filtro
   #glassMaterialize, vidrio del CTA), pero resuelto liviano, sin depender
   de ninguna librería externa. */
.hero-x-glass{
  display:inline-block;
  font-style:normal;
  width:0.98em;
  aspect-ratio:358/303;
  margin:0 0.1em;
  vertical-align:-0.08em;
  filter:drop-shadow(0 0 16px rgba(78,228,171,.5)) drop-shadow(0 6px 14px rgba(0,0,0,.35));
  animation:hxgTilt 6.5s ease-in-out infinite;
  transform-style:preserve-3d;
}
.hero-x-glass svg{display:block;width:100%;height:100%;overflow:visible;}
.hxg-sweep{animation:hxgSweep 3.2s ease-in-out infinite;}
@keyframes hxgTilt{
  0%,100%{transform:perspective(700px) rotateY(0deg) rotateX(0deg);}
  25%{transform:perspective(700px) rotateY(22deg) rotateX(-5deg);}
  50%{transform:perspective(700px) rotateY(0deg) rotateX(0deg);}
  75%{transform:perspective(700px) rotateY(-22deg) rotateX(5deg);}
}
@keyframes hxgSweep{
  0%{transform:translateX(0);}
  60%,100%{transform:translateX(770px);}
}
@media (prefers-reduced-motion: reduce){
  .hero-x-glass{animation:none;}
  .hxg-sweep{animation:none;opacity:0;}
}
.hero-sub{
  display:grid;
  grid-template-columns:1.3fr 1fr;
  gap:60px;
  margin-top:38px;
  align-items:end;
}
.hero-sub p{
  font-size:clamp(15px,1.6vw,19px);
  color:var(--white);
  max-width:46ch;
}
.hero-cta{display:flex;gap:28px;flex-wrap:wrap;align-items:center;}
/* Pedido: que el texto de esta primera pantalla resalte más sobre el video
   de fondo — acá el eyebrow pasa de mint a blanco (como en el resto del
   sitio). Escapado solo a .hero para no tocar ese mismo elemento en el
   resto de las secciones, donde sigue como estaba. */
.hero .eyebrow{color:var(--white);}

/* Franja de logos de clientes dentro del hero (primera pantalla): mismo
   ancho centrado que el resto del contenido del hero (título, párrafo,
   CTA), con el mismo margen a izquierda y derecha — sin padding extra
   asimétrico. El marquee en sí (ver .hero-clients-marquee) se encarga de
   que el logo nunca quede cortado de golpe contra el borde del botón de
   WhatsApp: el difuminado de los bordes ya lo cubre. */
.hero-clients{
  margin-top:20px;
  padding-top:16px;
  border-top:1px solid var(--line);
}
.hero-clients-label{
  display:block;
  font-family:var(--ff-head);
  font-size:10px;
  letter-spacing:0.08em;
  text-transform:uppercase;
  color:var(--gray);
  margin-bottom:14px;
}
/* Mismo mecanismo que .clients-marquee (sección "Marcas que ya crecen con
   NXT" más abajo), copiado tal cual: fondo sólido propio + difuminado en
   los bordes + loop con dos sets duplicados + pausa al hover. El fondo
   sólido es la pieza clave — sin él, el difuminado de los bordes queda
   flotando directo sobre el video del hero y, según qué haya detrás en
   ese fotograma, se nota como un parche oscuro mal integrado en vez de
   desvanecerse. Con fondo propio (igual que la franja de abajo) el
   difuminado siempre cierra contra un color sólido conocido. Como esta
   franja no es full-bleed (va centrada, con el mismo margen del resto del
   hero) se le suma un radius chico para que se lea como una píldora
   flotando sobre el video en vez de un rectángulo duro. */
.hero-clients-marquee{
  position:relative;
  overflow:hidden;
  width:100%;
  background:var(--near-black);
  border-top:1px solid var(--line);
  border-bottom:1px solid var(--line);
  border-radius:14px;
  padding:14px 0;
}
.hero-clients-marquee::before,
.hero-clients-marquee::after{
  content:'';
  position:absolute;top:0;bottom:0;width:56px;z-index:2;pointer-events:none;
}
.hero-clients-marquee::before{left:0;background:linear-gradient(90deg, var(--near-black), transparent);}
.hero-clients-marquee::after{right:0;background:linear-gradient(270deg, var(--near-black), transparent);}
.hero-clients-track{
  display:flex;width:max-content;
  animation:heroClientsMarquee 16s linear infinite;
}
.hero-clients-track:hover{animation-play-state:paused;}
.hero-clients-set{
  display:flex;align-items:center;flex:none;
}
@keyframes heroClientsMarquee{
  from{transform:translateX(0);}
  to{transform:translateX(-50%);}
}
.hero-client-logo{
  position:relative;
  display:flex;align-items:center;justify-content:center;
  flex:none;
  padding:0 18px;
}
.hero-client-logo img{
  /* los PNG ya vienen recortados justo al borde del dibujo (sin aire
     interno), así que esta altura es el tamaño visual real del logo —
     ya no hay que compensar por logos con más o menos margen interno */
  height:22px;width:auto;display:block;
}
/* Casa Quinta y Camiones Exclusivos son isologos circulares (no wordmarks
   horizontales como el resto): a la misma altura de línea se ven más
   chicos que los demás, así que se agrandan un poco para emparejar el
   peso visual con el resto de la fila. */
.hero-client-logo img[src*="casa-quinta"],
.hero-client-logo img[src*="camiones-exclusivos"]{
  height:29px;
}
@media (prefers-reduced-motion: reduce){
  .hero-clients-track{animation:none;}
}
@media (max-width:720px){
  .hero-clients{margin-top:16px;padding-top:14px;}
  .hero-client-logo{padding:0 14px;}
  .hero-client-logo img{height:18px;}
  .hero-client-logo img[src*="casa-quinta"],
  .hero-client-logo img[src*="camiones-exclusivos"]{height:24px;}
  .hero-clients-marquee::before,.hero-clients-marquee::after{width:36px;}
}
/* Ventanas/pantallas bajas (laptop sin maximizar, zoom, etc.): a esta
   altura el "SCROLL" de abajo queda muy cerca del CTA — se libera espacio
   agrandando el padding inferior del hero y achicando el indicador de
   scroll, y se achica un poco la franja de logos para que entre cómoda
   antes de esa zona. */
@media (max-height:760px){
  .hero{padding-bottom:200px;}
  .scroll-cue .track{height:28px;}
  .scroll-cue{gap:6px;}
  .hero-clients{margin-top:14px;padding-top:10px;}
  .hero-clients-label{margin-bottom:8px;}
  .hero-client-logo img{height:19px;}
  .hero-client-logo img[src*="casa-quinta"],
  .hero-client-logo img[src*="camiones-exclusivos"]{height:25px;}
}

.scroll-cue{
  position:absolute;
  bottom:38px;left:50%;
  transform:translateX(-50%);
  display:flex;flex-direction:column;align-items:center;gap:10px;
  z-index:2;
}
.scroll-cue .track{
  width:1px;height:52px;
  background:var(--line);
  position:relative;overflow:hidden;
}
.scroll-cue .track i{
  position:absolute;top:-100%;left:0;width:100%;height:100%;
  background:var(--mint);
  animation:scrollcue 1.8s ease-in-out infinite;
}
@keyframes scrollcue{
  0%{top:-100%;} 50%{top:0;} 100%{top:100%;}
}
.scroll-cue span{
  font-size:10px;letter-spacing:.2em;color:var(--gray);text-transform:uppercase;
  writing-mode:vertical-rl;
}

/* ---------- marquee ---------- */
.marquee-strip{
  border-top:1px solid var(--line);
  border-bottom:1px solid var(--line);
  padding:20px 0;
  overflow:hidden;
  background:var(--near-black);
  position:relative;
  z-index:3;
}
.marquee-track{
  display:flex;width:max-content;
  animation:marquee 32s linear infinite;
}
.marquee-track > span{
  font-family:var(--ff-head);
  font-size:20px;
  text-transform:uppercase;
  letter-spacing:0.04em;
  color:var(--gray);
  padding:0 28px;
  display:flex;align-items:center;gap:28px;
  white-space:nowrap;
}
.marquee-track > span > i{
  width:6px;height:6px;border-radius:50%;background:var(--mint);display:inline-block;
}
@keyframes marquee{
  from{transform:translateX(0);}
  to{transform:translateX(-50%);}
}
.mq-word{display:inline-block;}
.mq-ch{display:inline-block;}
.mq-ch.is-glitching{
  color:var(--mint);
  text-shadow:1px 0 rgba(255,45,90,0.55), -1px 0 rgba(60,220,255,0.55);
}
@media (prefers-reduced-motion: reduce){
  .mq-ch.is-glitching{color:inherit;text-shadow:none;}
}

/* ---------- clientes ---------- */
/* Franja de logos de clientes, mismo lenguaje visual que .marquee-strip
   (borde arriba/abajo, fondo near-black) pero con loop más lento y logos
   en vez de texto. Todos los logos se procesan a un único color plano
   (var(--white)) para que se lean como un mismo sistema pese a venir de
   marcas muy distintas entre sí. */
.clients{
  padding:104px 0 0;
}
.clients-marquee{
  margin-top:52px;
  border-top:1px solid var(--line);
  border-bottom:1px solid var(--line);
  padding:38px 0;
  overflow:hidden;
  background:var(--near-black);
  position:relative;
}
/* difumina los bordes del loop para que los logos no aparezcan/desaparezcan
   de golpe en los costados */
.clients-marquee::before,
.clients-marquee::after{
  content:'';
  position:absolute;top:0;bottom:0;width:120px;z-index:2;pointer-events:none;
}
.clients-marquee::before{left:0;background:linear-gradient(90deg, var(--near-black), transparent);}
.clients-marquee::after{right:0;background:linear-gradient(270deg, var(--near-black), transparent);}
.clients-track{
  display:flex;width:max-content;
  animation:clientsMarquee 16s linear infinite;
}
.clients-track:hover{animation-play-state:paused;}
.clients-set{
  display:flex;align-items:center;flex:none;
}
.client-logo{
  display:flex;align-items:center;justify-content:center;
  flex:none;padding:0 52px;
  position:relative;
  animation:clientFloat 5.2s ease-in-out infinite;
}
/* pequeño desfasaje por logo (dentro de cada set de 5, nth-child arranca de
   nuevo en 1) para que no floten todos sincronizados — se sienta más
   orgánico, como si cada marca "respirara" a su propio ritmo */
.client-logo:nth-child(1){animation-delay:0s;}
.client-logo:nth-child(2){animation-delay:-1.1s;}
.client-logo:nth-child(3){animation-delay:-2.2s;}
.client-logo:nth-child(4){animation-delay:-3.3s;}
.client-logo:nth-child(5){animation-delay:-4.1s;}
@keyframes clientFloat{
  0%,100%{transform:translateY(0);}
  50%{transform:translateY(-7px);}
}
.client-logo img{
  height:38px;width:auto;display:block;
  opacity:0.6;
  transition:opacity .45s var(--ease), transform .45s var(--ease), filter .45s var(--ease);
}
.client-logo img:hover{
  opacity:1;
  transform:scale(1.12);
  filter:drop-shadow(0 0 18px rgba(78,228,171,.55));
}
/* brillo que cruza el logo al pasar el mouse, en diagonal — mismo lenguaje
   de "vidrio/destello" que el resto del sitio (glassMaterialize, cta glass) */
.client-logo::after{
  content:'';
  position:absolute;inset:-6px -18px;
  background:linear-gradient(115deg, transparent 40%, rgba(255,255,255,.55) 50%, transparent 60%);
  background-size:220% 220%;
  background-position:130% 0;
  opacity:0;
  mix-blend-mode:overlay;
  pointer-events:none;
  transition:opacity .3s ease;
}
.client-logo:hover::after{
  opacity:1;
  animation:clientShine .85s ease-out;
}
@keyframes clientShine{
  from{background-position:130% 0;}
  to{background-position:-30% 0;}
}
@keyframes clientsMarquee{
  from{transform:translateX(0);}
  to{transform:translateX(-50%);}
}
@media (prefers-reduced-motion: reduce){
  .clients-track{animation:none;}
  .client-logo{animation:none;}
  .client-logo:hover::after{animation:none;opacity:0;}
}
@media (max-width: 720px){
  .client-logo{padding:0 32px;}
  .client-logo img{height:28px;}
  .clients-marquee::before,.clients-marquee::after{width:60px;}
}

/* ---------- section base ---------- */
/* Paginado tipo presentación: cada <section> es una "página" numerada de,
   como mínimo, una pantalla completa (min-height, no height fijo — así el
   contenido que no entra en una pantalla, en vez de recortarse, sigue
   fluyendo y empuja la sección a ser más alta, nunca se pierde nada).
   scroll-snap-type en html hace que el scroll se acomode a estos bordes;
   "proximity" (no "mandatory") para que nunca se sienta trabado si una
   sección es más alta que la pantalla. El indicador "0X / 0Y" que lo
   acompaña se arma solo en initPageIndex() (app.js), no hace falta
   tocar el HTML de cada página. */
html{scroll-snap-type:y proximity;}
section{
  position:relative;padding:150px 0;
  min-height:100vh; min-height:100dvh;
  display:flex; flex-direction:column; justify-content:center;
  scroll-snap-align:start;
}
@media (max-width:760px){
  /* En mobile las secciones apiladas (grids a 1 columna) suelen quedar
     mucho más altas que una pantalla — forzar el snap ahí se siente
     trabado en vez de fluido, así que se desactiva y queda scroll libre;
     el indicador de página sigue mostrando en qué sección estás. */
  html{scroll-snap-type:none;}
}

/* Indicador fijo "0X / 0Y" — inyectado por initPageIndex() en app.js,
   una vez por página, no vive en el HTML. Se actualiza con un
   IntersectionObserver mirando qué <section> ocupa más pantalla. */
.page-index{
  position:fixed;right:28px;bottom:96px;z-index:500;
  display:flex;align-items:center;gap:12px;
  font-size:11px;letter-spacing:.09em;text-transform:uppercase;
  color:var(--gray);
  pointer-events:none;
  opacity:1;
  transition:opacity .3s var(--ease);
}
.page-index.is-hidden{opacity:0;}
.page-index .pi-current{color:var(--white);font-weight:600;}
.page-index .pi-track{
  width:30px;height:2px;border-radius:2px;
  background:var(--line);position:relative;overflow:hidden;
}
.page-index .pi-track i{
  position:absolute;left:0;top:0;bottom:0;width:0%;
  background:var(--mint);border-radius:2px;
  transition:width .35s var(--ease);
}
@media (max-width:760px){
  .page-index{right:18px;bottom:80px;font-size:10px;gap:9px;}
  .page-index .pi-track{width:22px;}
}

/* Botón flotante de WhatsApp — círculo fijo abajo a la derecha, presente en
   todas las páginas (ver antes de los scripts finales en cada .html).
   Reutiliza los mismos colores/hover que .btn-primary (mint -> lightgreen)
   para que se sienta parte de la identidad de NXT en vez del verde típico
   de WhatsApp. El .page-index (indicador "0X/0Y") se corrió un poco más
   arriba (ver arriba) para no superponerse con este botón. */
.wa-float{
  position:fixed;right:24px;bottom:24px;z-index:700;
  width:58px;height:58px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  background:var(--mint);color:var(--black);
  box-shadow:0 6px 22px rgba(0,0,0,0.35), 0 0 0 1px rgba(78,228,171,0.4);
  transition:background .3s var(--ease), transform .3s var(--ease), box-shadow .3s var(--ease);
}
.wa-float:hover{
  background:var(--lightgreen);
  transform:translateY(-3px) scale(1.04);
  box-shadow:0 10px 28px rgba(0,0,0,0.4), 0 0 22px 2px rgba(78,228,171,0.45);
}
.wa-float svg{display:block;}
@media (max-width:760px){
  .wa-float{right:16px;bottom:16px;width:52px;height:52px;}
  .wa-float svg{width:24px;height:24px;}
}
.section-head{
  display:flex;justify-content:space-between;align-items:flex-end;
  gap:40px;margin-bottom:80px;
  flex-wrap:wrap;
}
.section-head h2{
  font-size:clamp(34px,5vw,64px);
  max-width:14ch;
}
.section-head .desc{max-width:34ch;color:var(--gray);font-size:15px;}

/* Gráfico de crecimiento de la sección Proceso (reemplaza el texto que
   estaba acá al lado del título, y antes de eso una esfera 3D y un paisaje
   de línea patagónico — ver comentario en index.html y en
   initProcesoOrganic en app.js). Cada trazo se dibuja solo
   (stroke-dashoffset) al entrar en pantalla, escalonado por el
   transition-delay que cada <path>/<circle> trae inline en el HTML; la
   clase .is-drawn la agrega initProcesoOrganic vía IntersectionObserver.
   Después de dibujarse queda una respiración lenta y sutil (po-breathe),
   para que se sienta "vivo" sin ser una animación llamativa. */
.proceso-organic{
  width:100%;max-width:300px;height:auto;
  flex:0 0 auto;
  transform-origin:50% 60%;
}
@media (max-width:760px){
  .proceso-organic{max-width:230px;}
}
.proceso-organic .po-line{
  stroke:var(--mint);
  stroke-width:1.8;
  stroke-linecap:round;
  stroke-linejoin:round;
  stroke-dasharray:520;
  stroke-dashoffset:520;
  transition:stroke-dashoffset 1.4s var(--ease);
  opacity:0.85;
}
.proceso-organic .po-base{ stroke:var(--gray); stroke-width:1.4; opacity:0.5; }
.proceso-organic .po-growth{ stroke:var(--mint); }
.proceso-organic .po-arrow{ stroke:var(--mint); stroke-width:1.6; opacity:0.9; }
.proceso-organic .po-grid{
  stroke:var(--gray);
  stroke-width:1;
  opacity:0;
  transition:opacity .8s var(--ease);
}
.proceso-organic .po-area{
  opacity:0;
  transition:opacity 1.2s var(--ease) 1.1s;
}
.proceso-organic .po-bud{
  fill:var(--mint);
  opacity:0;
  transform:scale(0);
  transform-box:fill-box;
  transform-origin:center;
  transition:opacity .5s var(--ease), transform .5s var(--ease);
}
.proceso-organic .po-spore{
  fill:var(--lightgreen);
  opacity:0;
  transition:opacity 1s var(--ease);
}
.proceso-organic.is-drawn .po-line{stroke-dashoffset:0;}
.proceso-organic.is-drawn .po-grid{opacity:0.18;}
.proceso-organic.is-drawn .po-area{opacity:1;}
.proceso-organic.is-drawn .po-bud{opacity:1; transform:scale(1);}
.proceso-organic.is-drawn .po-spore{opacity:0.5;}
@keyframes po-breathe{ 0%,100%{transform:scale(1);} 50%{transform:scale(1.025);} }
.proceso-organic.is-drawn{ animation:po-breathe 8s ease-in-out 3s infinite; }
@media (prefers-reduced-motion: reduce){
  .proceso-organic .po-line{transition:none; stroke-dashoffset:0;}
  .proceso-organic .po-grid{transition:none; opacity:0.18;}
  .proceso-organic .po-area{transition:none; opacity:1;}
  .proceso-organic .po-bud{transition:none; opacity:1; transform:scale(1);}
  .proceso-organic .po-spore{transition:none; opacity:0.5;}
  .proceso-organic.is-drawn{animation:none;}
}

/* Íconos junto al número de cada paso de Proceso (lupa, lápiz, capas,
   barras — antes eran paisajes de la Patagonia) — se encienden en mint
   junto con el paso (misma clase .on que ya prendía el punto de la línea
   de progreso, ver initProcess en app.js), reforzando en cada etapa la idea
   de negocio/resultado en vez de un progreso abstracto. */
.p-step .p-eco{
  display:inline-flex;
  vertical-align:middle;
  margin-left:8px;
  color:var(--gray);
  opacity:0.6;
  transition:color .4s, opacity .4s;
}
.p-step .p-eco svg{width:18px;height:18px;display:block;}
.p-step.on .p-eco{color:var(--mint); opacity:1;}

/* ---------- kinetic title (per-word reveal) ---------- */
.kinetic-word{display:inline-block;overflow:hidden;vertical-align:top;}
.kinetic-word-inner{display:inline-block;will-change:transform;}

/* ---------- tilt cards ---------- */
.tilt-card{will-change:transform;}
.tilt-glow{
  position:absolute;inset:0;
  z-index:3;
  pointer-events:none;
  opacity:0;
  transition:opacity .4s;
  background:radial-gradient(circle at var(--mx,50%) var(--my,50%), rgba(78,228,171,0.30), transparent 55%);
}
.tilt-card:hover .tilt-glow{opacity:1;}
.idx{font-family:var(--ff-head);font-size:13px;color:var(--gray);letter-spacing:.1em;}

/* ---------- manifesto ---------- */
.manifesto{
  background:var(--panel);
  border-top:1px solid var(--line);
  border-bottom:1px solid var(--line);
}
.manifesto-inner{max-width:1000px;margin-inline:auto;text-align:center;}
.manifesto p{
  font-family:var(--ff-head);
  font-size:clamp(24px,4.2vw,52px);
  text-transform:none;
  letter-spacing:-0.01em;
  line-height:1.25;
  color:var(--gray);
}
.manifesto p .w{color:var(--gray); transition:color .1s;}
.manifesto p .w.on{color:var(--white);}
.manifesto p .w.mint-on{color:var(--mint);}
.manifesto .quote-mark{
  font-family:var(--ff-head);
  font-size:80px;color:var(--mint);opacity:.5;line-height:.5;margin-bottom:10px;display:block;
}

/* ---------- glass card (sistema reutilizable) ---------- */
/* Interpretación propia de las referencias visuales que subiste: panel de
   vidrio esmerilado, borde con gradiente en movimiento, glow verde, grilla
   técnica en la esquina e isotipo NXT como marca de agua. Mismo lenguaje que
   el resto del sitio (mint/lightgreen, --nxt-angle) — se usa como contenedor
   reutilizable con el contenido real de cada sección en vez del texto de
   muestra de las imágenes ("+200% Inovación", "Conetcta", etc.). */
.glass-card{
  position:relative;
  isolation:isolate;
  border-radius:20px;
  background:linear-gradient(155deg, rgba(20,42,34,0.55), rgba(6,9,8,0.86));
  backdrop-filter:blur(13px) saturate(118%);
  -webkit-backdrop-filter:blur(13px) saturate(118%);
}
.glass-card::before{
  content:'';
  position:absolute;inset:0;
  border-radius:inherit;
  padding:1px;
  background:conic-gradient(from var(--nxt-angle), transparent 0deg, transparent 250deg, var(--lightgreen) 300deg, var(--mint) 330deg, transparent 360deg);
  -webkit-mask:linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite:xor;
  mask-composite:exclude;
  opacity:0.5;
  animation:nxt-ring 8.5s linear infinite;
  pointer-events:none;
  z-index:2;
}
.glass-card::after{
  content:'';
  position:absolute;
  top:-25%;right:-20%;
  width:75%;height:140%;
  background:radial-gradient(circle, rgba(78,228,171,0.2), transparent 70%);
  filter:blur(26px);
  z-index:-1;
  pointer-events:none;
}
/* Antes era una grilla técnica (líneas rectas) — se cambió por una
   dispersión de puntos, más orgánica (semillas/musgo que motas de
   circuito), pidiendo bajarle el tono "tech" a la tarjeta. */
.glass-card .gc-grid{
  position:absolute;right:0;bottom:0;
  width:96px;height:64px;
  background-image:radial-gradient(rgba(255,255,255,0.22) 1.4px, transparent 1.6px);
  background-size:13px 13px;
  -webkit-mask-image:linear-gradient(135deg, transparent 15%, #000 65%);
  mask-image:linear-gradient(135deg, transparent 15%, #000 65%);
  pointer-events:none;
}
.glass-card .gc-logo{
  position:absolute;right:20px;bottom:18px;
  height:13px;width:auto;opacity:0.85;
  z-index:1;
}
@media (prefers-reduced-motion: reduce){
  .glass-card::before{animation:none !important;}
}

/* ---------- stats / servicio destacado ---------- */
/* Antes eran 4 glass-cards con números (años de trayectoria, clientes,
   etc.) — se reemplazaron por una sola glass-card (mismo sistema visual:
   borde con gradiente en movimiento, glow, grilla técnica, isotipo de
   marca de agua) para anunciar el nuevo servicio de grabaciones aéreas
   con drone, en vocabulario simple. El isotipo del drone flota
   suavemente (loop CSS) como único "animación" propia de esta card, ya
   que no hay un número para contar.
   Nota: hubo una versión intermedia con un video real al lado del texto
   (panel .stat-solo-media, ver historial en README) — se sacó a pedido
   ("no me gustó, elimínenlo") en espera de un video de reemplazo. Si en
   algún momento se vuelve a sumar un video, reutilizar ese mismo patrón:
   .stat-solo.has-media + .stat-solo-media + .stat-solo-video, documentado
   en el punto 25 del README. */
.stats{padding-top:110px;padding-bottom:110px;}
.stat-solo{
  padding:48px 44px;
  display:flex;
  align-items:center;
  gap:40px;
}
.stat-solo-icon{
  flex:0 0 auto;
  width:88px;height:88px;
  border-radius:50%;
  border:1px solid var(--line);
  display:flex;align-items:center;justify-content:center;
  color:var(--mint);
  animation:nxt-drone-hover 3.2s ease-in-out infinite;
}
.stat-solo-icon svg{width:44px;height:44px;}
/* Drone 3D (Meshy AI, sin animación propia): el modelo llena el mismo
   círculo que antes ocupaba el ícono plano — el "vuelo" lo dan la rotación
   lenta continua (auto-rotate, agregada por JS solo si no hay
   prefers-reduced-motion) más el mismo bamboleo vertical nxt-drone-hover
   que ya tenía el círculo. En la vista previa de un solo archivo el CDN de
   model-viewer no llega a cargar: queda la imagen de respaldo del slot
   "poster", así que siempre se ve algo, animado o no. */
.stat-solo-icon.is-3d{
  width:132px;height:132px;
  overflow:hidden;
  background:radial-gradient(circle at 50% 55%, rgba(78,228,171,0.16), transparent 72%);
}
.stat-solo-icon.is-3d .drone-viewer{
  width:100%;height:100%;
  --poster-color:transparent;
  pointer-events:none;
}
@media (max-width:760px){
  .stat-solo-icon.is-3d{width:112px;height:112px;}
}
.stat-solo-text .eyebrow{margin-bottom:10px;}
.stat-solo-text h3{
  font-family:var(--ff-head);
  font-size:clamp(24px,3vw,34px);
  font-weight:500;
  text-transform:none;
  color:var(--white);
  margin-bottom:10px;
}
.stat-solo-text p{color:var(--gray);font-size:15px;line-height:1.5;max-width:56ch;}
@keyframes nxt-drone-hover{
  0%,100%{transform:translateY(0);}
  50%{transform:translateY(-8px);}
}
@media (prefers-reduced-motion: reduce){
  .stat-solo-icon{animation:none;}
}
@media (max-width:760px){
  .stat-solo{flex-direction:column;text-align:center;padding:40px 28px;gap:22px;}
  .stat-solo-text p{max-width:none;}
}

/* Galería de tomas aéreas: 4 videos reales, en fila, debajo de la card de
   "Grabaciones aéreas" — mismo marco visual que se probó antes en la
   card sola (bordes redondeados, borde sutil, formato vertical 9:16) pero
   ahora como grilla de 4. Cada uno arranca solo (autoplay+muted+loop+
   playsinline) sin pedir permiso al navegador; el poster (JPG liviano) es
   lo único que se ve si el navegador bloquea el autoplay. */
.aerial-gallery-head{margin-top:44px;margin-bottom:18px;}
.aerial-gallery-head p{
  color:var(--gray);
  font-size:13px;
  text-transform:uppercase;
  letter-spacing:.06em;
}
.aerial-gallery{
  display:grid;
  grid-template-columns:repeat(4, 1fr);
  gap:16px;
}
.aerial-card{
  border-radius:14px;
  overflow:hidden;
  border:1px solid var(--line);
  aspect-ratio:9/16;
  box-shadow:0 16px 40px -18px rgba(0,0,0,0.6);
  transition:transform .45s var(--ease), border-color .3s;
}
.aerial-card:hover{transform:translateY(-6px);border-color:rgba(78,228,171,0.4);}
.aerial-video{
  width:100%;height:100%;
  object-fit:cover;
  display:block;
  background:var(--panel);
}
@media (max-width:760px){
  .aerial-gallery{grid-template-columns:repeat(2, 1fr);gap:12px;}
  .aerial-gallery-head{margin-top:32px;text-align:center;}
}
@media (prefers-reduced-motion: reduce){
  .aerial-card{transition:none;}
}

/* Galería "Reel" de contenido audiovisual (página Contenido Audiovisual):
   6 piezas reales de drone 4K, editadas con su propio audio. A diferencia
   de la galería aérea de arriba (que es autoplay+muted, solo fondo), acá
   el sonido es parte del trabajo — así que van con controles nativos,
   preload="metadata" (no descargan hasta que se tocan) y arrancan
   pausadas con un botón de play propio encima del poster. Mismo marco
   visual 9:16 que la galería aérea para que el sitio se sienta de una
   sola pieza. */
.reel-gallery-head{margin-bottom:22px;}
.reel-gallery{
  display:grid;
  grid-template-columns:repeat(3, 1fr);
  gap:18px;
}
.reel-card{
  position:relative;
  border-radius:14px;
  overflow:hidden;
  border:1px solid var(--line);
  aspect-ratio:9/16;
  box-shadow:0 16px 40px -18px rgba(0,0,0,0.6);
  transition:transform .45s var(--ease), border-color .3s;
  background:var(--panel);
}
.reel-card:hover{transform:translateY(-6px);border-color:rgba(78,228,171,0.4);}
.reel-video{
  width:100%;height:100%;
  object-fit:cover;
  display:block;
  background:var(--panel);
}
.reel-play{
  position:absolute;inset:0;
  display:flex;align-items:center;justify-content:center;
  background:linear-gradient(180deg, rgba(0,0,0,0.05) 0%, rgba(0,0,0,0.35) 100%);
  cursor:pointer;
  border:none;padding:0;
  transition:opacity .3s;
}
.reel-play-icon{
  width:56px;height:56px;border-radius:50%;
  background:var(--mint);
  display:flex;align-items:center;justify-content:center;
  box-shadow:0 8px 24px -6px rgba(78,228,171,0.6);
  transition:transform .25s;
}
.reel-card:hover .reel-play-icon{transform:scale(1.08);}
.reel-play-icon svg{margin-left:3px;}
.reel-card.is-playing .reel-play{opacity:0;pointer-events:none;}
@media (max-width:760px){
  .reel-gallery{grid-template-columns:repeat(2, 1fr);gap:12px;}
  .reel-gallery-head{text-align:center;}
}
@media (prefers-reduced-motion: reduce){
  .reel-card{transition:none;}
}

/* ---------- services ---------- */
.services-list{border-top:1px solid var(--line);}
.service-row{
  border-bottom:1px solid var(--line);
  padding:40px 0;
  display:grid;
  grid-template-columns:70px 1.4fr 1.6fr 90px;
  align-items:center;
  gap:30px;
  position:relative;
  overflow:hidden;
  transition:padding-left .45s var(--ease);
}
.service-row::before{
  content:'';
  position:absolute;inset:0;
  background:linear-gradient(90deg, rgba(78,228,171,0.14), transparent 70%);
  transform:translateX(-101%);
  transition:transform .5s var(--ease);
  z-index:0;
}
.service-row:hover::before{transform:translateX(0);}
.service-row:hover{padding-left:26px;}
.service-row > *{position:relative;z-index:1;}
.service-row .s-idx{font-family:var(--ff-head);color:var(--gray);font-size:14px;}
.service-row h3{
  font-size:clamp(22px,2.6vw,34px);
  text-transform:none;
  font-weight:500;
  display:flex;align-items:center;gap:14px;
}
.service-row p{color:var(--gray);font-size:14.5px;max-width:48ch;}
.service-row .s-tags{display:flex;flex-wrap:wrap;gap:8px;margin-top:10px;}
.service-row .s-tags span{
  font-size:11px;text-transform:uppercase;letter-spacing:.05em;
  border:1px solid var(--line);border-radius:100px;padding:5px 12px;color:var(--gray);
}
.service-row .s-arrow{
  justify-self:end;
  width:46px;height:46px;border-radius:50%;
  border:1px solid var(--line);
  display:flex;align-items:center;justify-content:center;
  transition:transform .45s var(--ease), background .3s, border-color .3s;
}
.service-row:hover .s-arrow{
  transform:rotate(45deg);
  background:var(--mint);border-color:var(--mint);
}
.service-row:hover .s-arrow svg{stroke:var(--black);}
.service-row .s-arrow svg{stroke:var(--white);transition:stroke .3s;}

/* Servicios sin página propia todavía (04-06): mismo layout que un
   service-row normal, pero sin el hover "clickeable" (glow + flecha que
   gira a mint) que antes prometía una acción que no pasaba nada — en su
   lugar, una etiqueta honesta "Pronto". Ver los 3 <div class="service-row
   is-soon"> en index.html. */
.service-row.is-soon{cursor:default;}
.service-row.is-soon::before{display:none;}
.service-row.is-soon:hover{padding-left:0;}
.service-row.is-soon h3{color:var(--gray);}
.service-row .s-soon{
  justify-self:end;
  font-family:var(--ff-head);color:var(--gray);font-size:11px;
  text-transform:uppercase;letter-spacing:.06em;
  border:1px solid var(--line);border-radius:100px;
  padding:8px 14px;white-space:nowrap;
}

/* ---------- process ---------- */
.process{background:var(--panel); border-top:1px solid var(--line); border-bottom:1px solid var(--line);}
.process-pin{min-height:100vh; display:flex; flex-direction:column; justify-content:center;}
.process-line{
  position:relative;
  height:2px;background:var(--line);
  margin:70px 0 0;
}
.process-line .fill{
  position:absolute;left:0;top:0;height:100%;width:0%;
  background:linear-gradient(90deg,var(--mint),var(--lightgreen));
  box-shadow:0 0 10px 1px rgba(78,228,171,0.5);
}
.process-steps{
  display:grid;grid-template-columns:repeat(4,1fr);
  margin-top:-1px;
}
.p-step{padding-top:30px;position:relative;}
.p-step .dot{
  position:absolute;top:-6px;left:0;
  width:12px;height:12px;border-radius:50%;
  background:var(--near-black);border:2px solid var(--line);
  transition:background .3s, border-color .3s, box-shadow .3s;
}
.p-step.on .dot{background:var(--mint);border-color:var(--mint); box-shadow:0 0 9px 1px rgba(78,228,171,0.5);}
.p-step .p-num{font-family:var(--ff-head);color:var(--gray);font-size:13px;}
.p-step h4{
  margin-top:14px;font-size:clamp(20px,2.4vw,30px);text-transform:none;font-weight:500;
}
.p-step p{margin-top:12px;color:var(--gray);font-size:14px;max-width:30ch;}


/* ---------- values ---------- */
/* Video de fondo de esta sección, mismo tratamiento que el Hero y el
   page-hero de las páginas internas: silenciado y en loop, oscurecido con
   filtro + degradé para que el texto se siga leyendo, con una foto de
   respaldo mientras carga (poster del <video>, en el HTML). Clases
   propias (.nosotros-bg / .nosotros-bg-video) para no compartir selector
   ni parallax con las otras dos. Las glass-card de abajo ya son vidrio
   esmerilado (backdrop-filter) — con el video atrás se ven con un blur
   real detrás en vez de puro negro, gratis, sin tocar esa clase. */
#nosotros{overflow:hidden;}
#nosotros .container{position:relative; z-index:2;}
.nosotros-bg{
  position:absolute;
  inset:-9%;
  width:118%;height:118%;
  z-index:0;
  overflow:hidden;
  pointer-events:none;
}
.nosotros-bg-video{
  width:100%;height:100%;
  object-fit:cover;
  object-position:center 50%;
  filter:grayscale(0.2) brightness(0.5) contrast(0.98) saturate(0.85);
  opacity:0.9;
}
.nosotros-bg::after{
  content:'';
  position:absolute;inset:0;
  background:linear-gradient(180deg, var(--black) 0%, rgba(0,0,0,0.5) 14%, rgba(0,0,0,0.4) 55%, rgba(0,0,0,0.65) 88%, var(--black) 100%);
}
.values-grid{
  display:grid;grid-template-columns:repeat(3,1fr);gap:20px;
}
.value-card{padding:44px 38px 62px;min-height:320px;display:flex;flex-direction:column;justify-content:space-between;}
.value-card .v-num{
  align-self:flex-start;
  font-family:var(--ff-head);color:var(--mint);font-size:11px;
  letter-spacing:.08em;text-transform:uppercase;
  border:1px solid rgba(78,228,171,0.35);border-radius:100px;
  padding:6px 14px;
}
.value-card h3{font-size:clamp(24px,2.6vw,32px);text-transform:none;font-weight:500;margin-top:36px;}
.value-card p{color:var(--gray);font-size:14.5px;margin-top:16px;max-width:34ch;}

/* ---------- cta ---------- */
.cta{
  background:var(--panel);
  text-align:center;
  border-top:1px solid var(--line);
  overflow:hidden;
}
.cta .container{position:relative;z-index:2;}
/* Isotipo en vidrio líquido detrás del título de cierre — ver initCtaGlass()
   en app.js (empuja rotación/escala/opacidad y el "scale" del filtro SVG
   #ctaGlassDistort con el scroll) y la nota en index.html junto al filtro. */
.cta-glass-bg{
  position:absolute;inset:0;
  display:flex;align-items:center;justify-content:center;
  overflow:hidden;
  pointer-events:none;
  z-index:0;
}
.cta-glass-mark{
  position:relative;
  width:min(85vw, 1180px);
  aspect-ratio:5458 / 1376;
  -webkit-mask-image:url('assets/nxt-logo.png');
  mask-image:url('assets/nxt-logo.png');
  -webkit-mask-size:contain;mask-size:contain;
  -webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;
  -webkit-mask-position:center;mask-position:center;
  background:linear-gradient(155deg, rgba(255,255,255,0.22), rgba(78,228,171,0.12));
  backdrop-filter:blur(14px) saturate(122%) brightness(1.02);
  -webkit-backdrop-filter:blur(14px) saturate(122%) brightness(1.02);
  filter:url(#ctaGlassDistort) drop-shadow(0 30px 60px rgba(0,0,0,0.4));
  opacity:.5;
  will-change:transform, opacity;
}
@media (max-width:760px){
  .cta-glass-mark{width:96vw;}
}
@media (prefers-reduced-motion: reduce){
  .cta-glass-mark{opacity:.4;}
}
.cta .eyebrow{justify-content:center;margin-bottom:26px;}
.cta h2{
  font-size:clamp(38px,7vw,96px);
  max-width:16ch;margin-inline:auto;
}
.cta h2 a{
  display:inline-block;position:relative;
}
.cta h2 a .u{
  position:absolute;left:0;bottom:0.06em;width:100%;height:2px;background:var(--mint);
  transform:scaleX(0);transform-origin:left;transition:transform .5s var(--ease);
}
.cta h2 a:hover .u{transform:scaleX(1);}
.cta-sub{margin-top:30px;color:var(--gray);font-size:16px;}
.cta-btns{display:flex;justify-content:center;gap:28px;margin-top:44px;flex-wrap:wrap;align-items:center;}

/* Formulario de contacto real, envío fluido sin salir de la página (Netlify
   Forms) — ver el comentario junto al <form> en index.html y
   initContactForm() en app.js. El form y el bloque de éxito (.cta-form-success)
   comparten el mismo max-width/margin para que el cambio de uno a otro no
   salte de ancho; el form se desvanece (.is-hidden) y, recién cuando terminó
   la transición, app.js lo oculta y muestra el bloque de éxito con su propio
   fade-in (.is-visible). */
.cta-form{
  text-align:left;
  max-width:640px;
  margin:44px auto 0;
  display:flex;flex-direction:column;gap:22px;
  transition:opacity .3s var(--ease), transform .3s var(--ease);
}
.cta-form.is-hidden{
  opacity:0;
  transform:translateY(-8px);
  pointer-events:none;
}
.cta-form-row{display:grid;grid-template-columns:1fr 1fr;gap:22px;}
.cta-field{display:flex;flex-direction:column;gap:8px;}
.cta-field label{
  font-family:var(--ff-head);color:var(--gray);font-size:11px;
  text-transform:uppercase;letter-spacing:.08em;
}
.cta-field input, .cta-field select, .cta-field textarea{
  background:rgba(255,255,255,0.03);
  border:1px solid var(--line);border-radius:3px;
  padding:14px 16px;
  color:var(--white);font-family:var(--ff-body);font-size:14.5px;
  transition:border-color .3s var(--ease), background .3s var(--ease);
}
.cta-field input:focus, .cta-field select:focus, .cta-field textarea:focus{
  outline:none;border-color:var(--mint);background:rgba(78,228,171,0.05);
}
.cta-field textarea{resize:vertical;min-height:110px;}
.cta-field select{cursor:pointer;}
.cta-field-opt{text-transform:none;letter-spacing:0;opacity:.7;}
.cta-form-foot{display:flex;align-items:center;gap:22px;flex-wrap:wrap;margin-top:4px;}
.cta-form-note{color:var(--gray);font-size:12.5px;line-height:1.5;max-width:34ch;}
.cta-form-note a{color:var(--mint);text-decoration:underline;text-underline-offset:2px;}
.cta-back{margin-top:32px;}
@media (max-width:640px){
  .cta-form-row{grid-template-columns:1fr;}
}

/* Campo trampa anti-spam de Netlify Forms (netlify-honeypot="bot-field"):
   tiene que seguir siendo parte real del DOM (no display:none — algunos
   bots lo ignoran si está completamente oculto por ahí), pero invisible y
   fuera del tab order para una persona real. */
.cta-form-honeypot{
  position:absolute;
  width:1px;height:1px;
  overflow:hidden;
  clip:rect(0,0,0,0);
  white-space:nowrap;
}

/* Estado de éxito: mismo ancho/alineación que el form para que no haya
   salto de layout al reemplazar uno por otro (ver initContactForm en
   app.js). Empieza invisible y corrido 8px hacia abajo; app.js le agrega
   .is-visible en el frame siguiente a sacarle [hidden], así el navegador
   sí anima la transición en vez de aplicarla de una. */
.cta-form-success{
  max-width:640px;
  margin:44px auto 0;
  text-align:left;
  padding:34px 38px;
  border:1px solid var(--line);
  border-radius:6px;
  background:rgba(78,228,171,0.05);
  opacity:0;
  transform:translateY(8px);
  transition:opacity .4s var(--ease), transform .4s var(--ease);
}
.cta-form-success.is-visible{opacity:1;transform:translateY(0);}
.cta-form-success svg{color:var(--mint);}
.cta-form-success h3{
  font-family:var(--ff-head);
  font-size:22px;
  font-weight:500;
  color:var(--white);
  margin-top:16px;
}
.cta-form-success p{
  margin-top:10px;
  color:var(--gray);
  font-size:14.5px;
  max-width:42ch;
}
@media (max-width:640px){
  .cta-form-success{padding:28px 26px;}
}

/* ---------- footer ---------- */
footer{padding:70px 0 34px;border-top:1px solid var(--line);}
.foot-top{
  display:grid;grid-template-columns:1.4fr repeat(3,1fr);gap:40px;
  padding-bottom:60px;border-bottom:1px solid var(--line);
}
.foot-brand .logo{font-size:28px;}
.foot-brand p{color:var(--gray);font-size:14px;margin-top:18px;max-width:32ch;}
.foot-col h5{
  font-size:11px;text-transform:uppercase;letter-spacing:.14em;color:var(--gray);margin-bottom:20px;
}
.foot-col ul li{margin-bottom:12px;}
.foot-col ul a{font-size:14.5px;color:var(--white);transition:color .3s;}
.foot-col ul a:hover{color:var(--mint);}
.foot-bottom{
  display:flex;justify-content:space-between;align-items:center;padding-top:26px;
  color:var(--gray);font-size:12.5px;flex-wrap:wrap;gap:14px;
}
.back-top{
  display:flex;align-items:center;gap:8px;color:var(--gray);transition:color .3s;
}
.back-top:hover{color:var(--mint);}

/* ---------- responsive ---------- */
@media (max-width:1080px){
  .hero-sub{grid-template-columns:1fr;gap:24px;}
  .process-steps{grid-template-columns:repeat(2,1fr);row-gap:40px;}
  .values-grid{grid-template-columns:1fr;}
  .foot-top{grid-template-columns:1fr 1fr;}
}
@media (max-width:820px){
  nav.links{
    position:fixed;inset:0;top:0;
    background:var(--black);
    flex-direction:column;justify-content:center;align-items:flex-start;
    padding:0 8vw;
    transform:translateX(100%);
    transition:transform .5s var(--ease);
    gap:22px;
  }
  nav.links.open{transform:translateX(0);}
  nav.links a{font-size:26px;}
  .burger{display:flex;}
  .nav-right .btn-ghost{display:none;}
  /* .service-row en el HTML tiene 4 hijos directos: .s-idx (número),
     h3 (título), un <div> sin clase que envuelve el párrafo + .s-tags, y
     .s-arrow. Con 2 columnas de grid, ".service-row p, .service-row
     .s-tags{grid-column:2/3}" no hacía nada — el párrafo y las tags NO son
     hijos directos del grid (son nietos, dentro de ese <div>), así que ese
     selector nunca los alcanzaba. El <div> que sí es el hijo directo caía
     por auto-placement en la columna angosta de 40px, apretando el texto a
     una palabra por línea. El fix apunta al <div> real (único hijo directo
     sin clase) para que ocupe la columna ancha. */
  .service-row{grid-template-columns:40px 1fr;}
  .service-row > div{grid-column:2/3;}
  .service-row .s-arrow{position:absolute;right:0;top:40px;}
  .service-row .s-soon{position:absolute;right:0;top:40px;}
  .section-head{margin-bottom:50px;}
  section{padding:100px 0;}
  .foot-top{grid-template-columns:1fr;gap:34px;}
}

/* ---------- página Identidad & Branding ---------- */
.page-hero{padding:190px 0 40px; position:relative; overflow:hidden;}
.page-hero .container{position:relative; z-index:2;}
/* Video de fondo de esta página, mismo tratamiento que el de la Home
   (.hero-bg): silenciado y en loop, oscurecido con un filtro CSS + un
   degradé encima para que el texto se siga leyendo bien, con una foto de
   respaldo mientras carga (poster del <video>, en el HTML). Clases
   propias (.page-hero-bg / .page-hero-bg-video) en vez de reutilizar
   .hero-bg para no pisar el selector ni el parallax que ya usa esa clase
   en la Home. */
.page-hero-bg{
  position:absolute;
  inset:-4%;
  width:108%;height:108%;
  z-index:0;
  overflow:hidden;
  pointer-events:none;
}
.page-hero-bg-video{
  width:100%;height:100%;
  object-fit:cover;
  object-position:center 50%;
  filter:grayscale(0.2) brightness(0.55) contrast(0.98) saturate(0.85);
  opacity:0.9;
}
.page-hero-bg::after{
  content:'';
  position:absolute;inset:0;
  background:linear-gradient(180deg, var(--black) 0%, rgba(0,0,0,0.55) 16%, rgba(0,0,0,0.45) 55%, rgba(0,0,0,0.7) 90%, var(--black) 100%);
}
.page-hero .desc{color:var(--gray);max-width:58ch;margin-top:20px;font-size:16.5px;}
.page-back{
  display:inline-flex;align-items:center;gap:8px;
  color:var(--gray);font-size:12.5px;letter-spacing:.06em;text-transform:uppercase;font-weight:600;
  margin-bottom:26px;
  transition:color .3s var(--ease);
}
.page-back:hover{color:var(--mint);}
.page-back svg{transform:scaleX(-1);}

/* Round carousel — interpretación propia (canvas-free, CSS + JS vanilla) de
   la idea "anillo 3D cilíndrico con tarjetas de dos caras (frente real,
   reverso espejado/oscurecido), cámara con leve inclinación, que gira solo
   y responde a drag/rueda del mouse, con motion blur al girar rápido y
   click en la pieza frontal para verla completa". No usa el componente de
   Originkit "Round Carousel" (React/Framer, de pago) — construido desde
   cero para este stack con transforms CSS 3D nativos. Ver
   initRotatingCarousel() en app.js. */
.rc-section{padding:10px 0 90px;}
.rc-stage{
  position:relative;
  height:460px;
  perspective:1800px;
  display:flex;align-items:center;justify-content:center;
  overflow:hidden;
  cursor:grab;
  touch-action:pan-y;
  outline:none;
}
.rc-stage:focus-visible{box-shadow:inset 0 0 0 2px var(--mint);}
.rc-stage.is-dragging{cursor:grabbing;}
.rc-ring{
  position:relative;width:0;height:0;
  transform-style:preserve-3d;
  will-change:transform,filter;
}
.rc-card{
  position:absolute;top:50%;left:50%;
  border:none;background:none;padding:0;
  cursor:pointer;
  transform-style:preserve-3d;
  will-change:transform;
}
.rc-face{
  position:absolute;inset:0;
  border-radius:18px;
  background-color:var(--panel);
  background-size:cover;background-position:center;
  backface-visibility:hidden;-webkit-backface-visibility:hidden;
  box-shadow:0 16px 38px rgba(0,0,0,0.4);
  transition:transform .5s var(--ease);
}
.rc-card.is-focus .rc-face{box-shadow:0 26px 60px rgba(0,0,0,0.55), 0 0 0 2px rgba(78,228,171,0.55);}
.rc-card.is-focus:hover .rc-face{transform:scale(1.06);}
.rc-card:focus-visible .rc-face{outline:2px solid var(--mint);outline-offset:4px;}
.rc-edge{position:absolute;top:0;bottom:0;width:16%;pointer-events:none;z-index:5;}
.rc-edge-l{left:0;background:linear-gradient(to right, var(--black) 0%, transparent 100%);}
.rc-edge-r{right:0;background:linear-gradient(to left, var(--black) 0%, transparent 100%);}
.rc-stage.rc-static{
  overflow-x:auto;overflow-y:visible;justify-content:flex-start;
  gap:10px;padding:0 4px;perspective:none;scrollbar-width:none;
}
.rc-stage.rc-static::-webkit-scrollbar{display:none;}
.rc-stage.rc-static .rc-ring{
  display:flex;gap:10px;width:max-content;height:auto;
  transform:none !important;filter:none !important;
}
.rc-stage.rc-static .rc-card{
  position:relative;top:auto;left:auto;flex:none;
  width:190px;height:244px;
  transform:none !important;
}
.rc-stage.rc-static .rc-face{border-radius:8px;}
@media (max-width:760px){
  .rc-stage.rc-static .rc-card{width:150px;height:192px;}
}
.rc-lightbox{
  position:fixed;inset:0;background:rgba(2,5,4,0.92);
  display:flex;align-items:center;justify-content:center;padding:40px;
  opacity:0;pointer-events:none;
  transition:opacity .35s var(--ease);
  z-index:600;
}
.rc-lightbox.is-open{opacity:1;pointer-events:auto;}
.rc-lightbox img{
  max-width:min(900px,90vw);max-height:86vh;
  border-radius:10px;
  box-shadow:0 40px 100px rgba(0,0,0,0.6);
}
.rc-lightbox-close{
  position:absolute;top:24px;right:24px;
  width:44px;height:44px;border-radius:50%;
  border:1px solid var(--line);background:var(--panel);color:var(--white,#fff);
  font-size:24px;line-height:1;cursor:pointer;
}
.rc-lightbox-close:hover{border-color:var(--mint);color:var(--mint);}

@media (max-width:760px){
  .rc-stage{height:360px;}
}

/* ---------------- Coverflow 3D — piezas de marca (Home / Servicios) ----------------
   Interpretación propia (canvas-free, CSS + JS vanilla) de la idea "coverflow
   3D: la tarjeta activa queda de frente en el centro y las vecinas se
   inclinan hacia atrás en perspectiva; click en cualquiera la trae al
   centro". No usa el componente de Originkit "Coverflow Gallery"
   (React/Framer, de pago) — se construyó desde cero para este stack, sin
   build step, con el mismo patrón que el Round Carousel de Identidad &
   Branding (ver .rc-* arriba). Ver initCoverflow() en app.js. */
.coverflow{margin:70px 0 6px;}
.coverflow-stage{
  position:relative;
  width:100%;
  height:clamp(300px, 40vw, 460px);
  display:flex;align-items:center;justify-content:center;
  perspective:1600px;
  outline:none;
}
.coverflow-stage:focus-visible{box-shadow:inset 0 0 0 2px var(--mint);}
.coverflow-track{position:relative;width:1px;height:1px;transform-style:preserve-3d;}
.cf-card{
  position:absolute;left:50%;top:50%;
  width:clamp(190px, 20vw, 280px);
  height:clamp(250px, 26vw, 360px);
  border-radius:18px;
  overflow:hidden;
  border:1px solid var(--line);
  background:var(--panel);
  padding:0;
  transform-style:preserve-3d;
  transform-origin:center center;
  box-shadow:0 16px 38px rgba(0,0,0,0.4);
  transition:transform .65s var(--ease), opacity .65s var(--ease), box-shadow .35s;
  will-change:transform;
}
.cf-card img{
  position:absolute;inset:0;
  width:100%;height:100%;
  object-fit:cover;
  display:block;
  pointer-events:none;
  user-select:none;
}
.cf-dim{
  position:absolute;inset:0;
  background:#000;
  opacity:0;
  transition:opacity .65s var(--ease);
  pointer-events:none;
}
.cf-card.is-active{box-shadow:0 26px 60px rgba(0,0,0,0.55), 0 0 0 2px rgba(78,228,171,0.55);}
.cf-card:focus-visible{outline:2px solid var(--mint);outline-offset:4px;}
.coverflow-stage.coverflow-static{
  overflow-x:auto;overflow-y:visible;justify-content:flex-start;
  gap:12px;padding:0 4px;perspective:none;scrollbar-width:none;
}
.coverflow-stage.coverflow-static::-webkit-scrollbar{display:none;}
.coverflow-stage.coverflow-static .coverflow-track{
  display:flex;gap:12px;width:max-content;height:auto;
}
.coverflow-stage.coverflow-static .cf-card{
  position:relative;top:auto;left:auto;flex:none;
  width:200px;height:256px;
  transform:none !important;opacity:1 !important;
}
@media (max-width:760px){
  .coverflow-stage{height:clamp(230px,64vw,320px);}
  .cf-card{width:clamp(150px,50vw,210px);height:clamp(198px,66vw,276px);}
  .coverflow-stage.coverflow-static .cf-card{width:160px;height:206px;}
}
@media (prefers-reduced-motion: reduce){
  .cf-card{transition:opacity .3s;}
}

/* ---------------- Vidrio líquido — marca flotante (Identidad & Branding) ----------------
   Isotipo NXT recortado en "vidrio esmerilado" (glassmorphism), flotando
   sobre una foto de la sección, con un balanceo idle lento y una leve
   inclinación 3D hacia el mouse (ver initGlassShowcase() en app.js).
   Inspirado en la categoría "figura de vidrio líquido flotante sobre un
   fondo" del componente "Glass Icon" de Originkit que se pidió agregar — es
   un componente React + Framer Motion de pago que renderiza la figura con
   WebGL (raymarching de un cuerpo 3D real, con mapa de entorno de estudio y
   dispersión cromática por canal) — no se copió ese código/shader, que es
   literalmente el producto que vende Originkit; en su lugar se construyó un
   equivalente propio mucho más liviano, sin WebGL: el isotipo recorta
   (mask-image sobre el PNG del logo, por su canal alfa) un panel con
   backdrop-filter (blur + saturación — mismo lenguaje visual que .glass-card
   más arriba) y un filtro SVG (feTurbulence + feDisplacementMap, ver el
   <svg> oculto al inicio del <body>) que ondula esa zona para sugerir una
   refracción sutil. Funciona en cualquier navegador moderno sin exigir GPU;
   si backdrop-filter no está soportado, el navegador simplemente lo ignora y
   el isotipo se ve como un panel translúcido liso, sin romper el layout. */
.glass-section{padding:20px 0 110px;}
.glass-stage{
  position:relative;
  height:560px;
  border-radius:20px;
  overflow:hidden;
  display:flex;align-items:center;justify-content:center;
}
.glass-bg{
  position:absolute;inset:0;
  background-size:cover;background-position:center;
  transform:scale(1.06);
}
.glass-overlay{
  position:absolute;inset:0;
  background:linear-gradient(180deg, rgba(2,5,4,0.1) 0%, rgba(2,5,4,0.74) 100%);
}
.glass-float{
  position:relative;
  perspective:1000px;
  animation:glass-float-bob 7s ease-in-out infinite;
  will-change:transform;
}
.glass-mark{
  position:relative;
  width:min(58vw, 460px);
  aspect-ratio:5458 / 1376;
  -webkit-mask-image:url('assets/nxt-logo.png');
  mask-image:url('assets/nxt-logo.png');
  -webkit-mask-size:contain;mask-size:contain;
  -webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;
  -webkit-mask-position:center;mask-position:center;
  background:linear-gradient(155deg, rgba(255,255,255,0.55), rgba(78,228,171,0.2));
  backdrop-filter:blur(16px) saturate(160%) brightness(1.25);
  -webkit-backdrop-filter:blur(16px) saturate(160%) brightness(1.25);
  filter:url(#glassDistort) drop-shadow(0 24px 46px rgba(0,0,0,0.5));
}
.glass-caption{
  position:absolute;left:0;right:0;bottom:34px;
  text-align:center;
  padding:0 24px;
  z-index:3;
}
.glass-caption .eyebrow{justify-content:center;}
.glass-caption p{color:var(--gray);max-width:440px;margin:10px auto 0;}
@keyframes glass-float-bob{
  0%,100%{transform:translateY(0);}
  50%{transform:translateY(-14px);}
}
@media (prefers-reduced-motion: reduce){
  .glass-float{animation:none;}
}
@media (max-width:760px){
  .glass-stage{height:420px;}
  .glass-mark{width:74vw;}
}

/* Diseño Digital & UX/UI — mapa conceptual */
.dd-section{padding:20px 0 150px;}
.dd-stage{
  position:relative;
  width:min(76vw,76vh,620px);
  height:min(76vw,76vh,620px);
  max-width:100%;
  margin:40px auto 56px;
}
.dd-stage canvas{
  position:absolute;inset:0;
  width:100%;height:100%;
  display:block;
}
.dd-center{
  position:absolute;inset:0;
  display:flex;align-items:center;justify-content:center;
  pointer-events:none;
}
.dd-logo{
  width:36%;height:36%;
  object-fit:contain;
  filter:drop-shadow(0 0 46px rgba(78,228,171,0.28));
}
.dd-node{
  position:absolute;
  transform:translate(-50%,-50%);
  display:flex;flex-direction:column;align-items:center;gap:9px;
  text-align:center;
  opacity:0;
  transition:opacity .7s var(--ease), transform .7s var(--ease);
}
.dd-node[data-dd-node]{transform:translate(-50%,-50%) translateY(6px);}
.dd-node.is-in{opacity:1;transform:translate(-50%,-50%) translateY(0);}
.dd-dot{
  width:8px;height:8px;border-radius:50%;
  background:var(--mint);
  box-shadow:0 0 14px rgba(78,228,171,0.75);
}
.dd-label{
  font-size:12.5px;letter-spacing:.07em;text-transform:uppercase;
  color:#fff;white-space:nowrap;
  background:rgba(2,5,4,0.6);
  backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);
  border:1px solid rgba(255,255,255,0.12);
  border-radius:100px;
  padding:7px 15px;
}
.dd-caption{
  max-width:46ch;
  margin:0 auto;
  text-align:center;
  color:var(--gray);
  font-size:14px;
  line-height:1.6;
}
@media (max-width:760px){
  .dd-stage{width:88vw;height:88vw;margin:24px auto 40px;}
  .dd-label{font-size:10.5px;padding:5px 11px;}
  .dd-logo{width:34%;height:34%;}
}
@media (prefers-reduced-motion: reduce){
  .dd-node{transition:none;}
}

/* Fondo de partículas (foto de campaña) — solo en páginas con
   body.has-bg-particles, para no afectar el stacking del resto del sitio. */
.dd-bg-canvas{
  position:fixed;inset:0;
  width:100%;height:100%;
  z-index:1;
  pointer-events:none;
}
.has-bg-particles main{position:relative;z-index:2;}
.has-bg-particles footer{position:relative;z-index:2;background:var(--black);}
@media (prefers-reduced-motion: reduce){
  .dd-bg-canvas{display:none;}
}

/* Imagen de partículas interactiva — Desarrollo Web & Tech: panel acotado
   con la foto del edificio en modo "contain" (se ve entera, sin recortar),
   que se arma al pasar el cursor por encima — ver initWebTechParticles()
   en app.js. */
.dw-section{padding:10px 0 90px;}
.dw-stage{
  position:relative;
  height:460px;
  border-radius:20px;
  overflow:hidden;
  background:var(--panel);
  cursor:pointer;
}
.dw-stage canvas{
  position:absolute;inset:0;
  width:100%;height:100%;
  display:block;
}
.dw-hint{
  position:absolute;
  left:50%;bottom:28px;
  transform:translateX(-50%);
  font-size:12.5px;letter-spacing:.07em;text-transform:uppercase;
  color:#fff;
  background:rgba(2,5,4,0.6);
  backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);
  border:1px solid rgba(255,255,255,0.12);
  border-radius:100px;
  padding:9px 18px;
  pointer-events:none;
  transition:opacity .4s var(--ease);
  opacity:0.9;
}
@media (max-width:760px){
  .dw-stage{height:360px;}
}
@media (prefers-reduced-motion: reduce){
  .dw-hint{display:none;}
}

/* ---------- equipo ---------- */
/* Caras reales detrás de NXT. Mismo sistema visual que .value-card
   (glass-card con borde en gradiente animado) para que se sienta parte
   del mismo lenguaje que el resto del sitio, no un agregado aparte.
   El avatar acepta foto real (team-avatar img) o, mientras no haya foto,
   cae en iniciales sobre el degradé de marca (team-avatar sin img). */
.team-grid{
  display:grid;grid-template-columns:repeat(3,1fr);gap:20px;
}
.team-card{
  padding:40px 34px;
  display:flex;flex-direction:column;gap:18px;
}
.team-avatar{
  width:76px;height:76px;border-radius:50%;
  overflow:hidden;
  display:flex;align-items:center;justify-content:center;
  background:linear-gradient(135deg, var(--mint), var(--lightgreen));
  color:var(--black);
  font-family:var(--ff-head);font-weight:700;font-size:22px;letter-spacing:.02em;
  flex:none;
}
.team-avatar img{width:100%;height:100%;object-fit:cover;display:block;}
.team-card h3{font-size:20px;text-transform:none;font-weight:500;}
.team-card .t-role{
  color:var(--mint);font-size:12px;text-transform:uppercase;letter-spacing:.08em;
  margin-top:-10px;
}
.team-card p{color:var(--gray);font-size:14px;line-height:1.55;}
@media (max-width:1080px){
  .team-grid{grid-template-columns:1fr;}
}

/* ---------- testimonios ---------- */
/* Prueba social con voz real de cliente — complementa el marquee de logos
   (quién trabaja con NXT) con lo que esos clientes dicen. Mismo sistema
   glass-card. IMPORTANTE: el contenido de cada tarjeta debe ser una cita
   real del cliente (ver cuestionario de testimonios) — nunca una frase
   inventada atribuida a una marca real. */
.testi-grid{
  display:grid;grid-template-columns:repeat(3,1fr);gap:20px;
}
.testi-card{
  padding:40px 34px;
  display:flex;flex-direction:column;gap:20px;
  justify-content:space-between;
  min-height:220px;
}
.testi-card .t-mark{
  font-family:var(--ff-head);font-size:46px;color:var(--mint);opacity:.6;line-height:.5;
}
.testi-card .t-quote{
  color:var(--white);font-size:15.5px;line-height:1.55;
}
.testi-author{display:flex;align-items:center;gap:12px;}
.testi-author .team-avatar{width:44px;height:44px;font-size:14px;}
.testi-author .t-name{font-size:13.5px;font-weight:600;color:var(--white);}
.testi-author .t-company{font-size:12px;color:var(--gray);}
@media (max-width:1080px){
  .testi-grid{grid-template-columns:1fr;}
}

/* ---------- casos de éxito ---------- */
/* Resultados reales medidos por NXT (reportes propios / métricas nativas
   de Instagram), no citas del cliente — por eso puede llevar datos ya,
   a diferencia de Testimonios que espera respuestas reales del cuestionario.
   Mismo sistema glass-card. Logo del cliente arriba, stats abajo en grilla
   2x2. Si se suma un tercer caso, pasa a 3 columnas (ver media query). */
.case-grid{
  display:grid;grid-template-columns:repeat(2,1fr);gap:20px;
}
.case-card{
  padding:40px 34px;
  display:flex;flex-direction:column;gap:22px;
}
.case-logo{
  height:34px;display:flex;align-items:center;
}
.case-logo img{height:100%;width:auto;display:block;}
.case-card h3{font-size:20px;text-transform:none;font-weight:500;margin-top:-4px;}
.case-card .c-tag{
  color:var(--mint);font-size:12px;text-transform:uppercase;letter-spacing:.08em;
  margin-top:-16px;
}
.case-card .c-note{color:var(--gray);font-size:14px;line-height:1.55;}
.case-stats{
  display:grid;grid-template-columns:1fr 1fr;gap:18px 14px;
  padding-top:4px;border-top:1px solid rgba(255,255,255,0.08);
}
.case-stat .c-num{
  display:block;font-family:var(--ff-head);font-weight:600;font-size:26px;
  color:var(--white);line-height:1.15;
}
.case-stat .c-label{display:block;color:var(--gray);font-size:12px;line-height:1.4;margin-top:4px;}
.case-videos{
  display:grid;grid-template-columns:1fr 1fr;gap:12px;
}
/* Miniatura clickeable (ya no el video completo incrustado): la imagen poster
   más un ícono de play centrado. Clickearla abre #caseLightbox (ver app.js,
   initCaseVideoLightbox) en vez de reproducir in-place. */
.case-video-thumb{
  position:relative;
  width:100%;aspect-ratio:9/16;
  border-radius:12px;overflow:hidden;
  background:#000;border:none;padding:0;cursor:pointer;
  display:block;
}
.case-video-thumb img{
  width:100%;height:100%;object-fit:cover;display:block;
  transition:transform .5s var(--ease), filter .5s var(--ease);
}
.case-video-thumb:hover img{transform:scale(1.06);filter:brightness(.75);}
.case-play-icon{
  position:absolute;inset:0;margin:auto;
  width:46px;height:46px;border-radius:50%;
  background:rgba(8,14,12,0.55);
  border:1px solid rgba(255,255,255,0.35);
  backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);
  display:flex;align-items:center;justify-content:center;
  transition:background .3s var(--ease), border-color .3s var(--ease), transform .3s var(--ease);
}
.case-play-icon::before{
  content:'';
  border-style:solid;
  border-width:8px 0 8px 13px;
  border-color:transparent transparent transparent var(--white,#fff);
  margin-left:3px;
}
.case-video-thumb:hover .case-play-icon{
  background:var(--mint);border-color:var(--mint);transform:scale(1.08);
}
.case-video-thumb:hover .case-play-icon::before{border-left-color:var(--black);}

/* Lightbox de video — mismo lenguaje visual que .rc-lightbox (overlay oscuro
   a pantalla completa, botón de cerrar circular) pero con un único
   reproductor <video> cuyo src se reasigna al vuelo en vez de un <img>. */
.case-lightbox{
  position:fixed;inset:0;background:rgba(2,5,4,0.92);
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:14px;
  padding:40px;
  opacity:0;pointer-events:none;
  transition:opacity .35s var(--ease);
  z-index:600;
}
.case-lightbox.is-open{opacity:1;pointer-events:auto;}
.case-lightbox video{
  max-width:min(420px,88vw);max-height:80vh;width:auto;height:auto;
  aspect-ratio:9/16;border-radius:14px;background:#000;
  box-shadow:0 40px 100px rgba(0,0,0,0.6);
}
.case-lightbox-label{color:var(--gray);font-size:13px;letter-spacing:.02em;}
.case-lightbox-close{
  position:absolute;top:24px;right:24px;
  width:44px;height:44px;border-radius:50%;
  border:1px solid var(--line);background:var(--panel);color:var(--white,#fff);
  font-size:24px;line-height:1;cursor:pointer;
}
.case-lightbox-close:hover{border-color:var(--mint);color:var(--mint);}

@media (max-width:1080px){
  .case-grid{grid-template-columns:1fr;}
}

@media (prefers-reduced-motion: reduce){
  *{animation-duration:0.001ms !important; animation-iteration-count:1 !important; transition-duration:0.001ms !important;}
}
