/* ═══════════════════════════════════════════
   widu. — landing
   Paleta extraída de logo.jpg / isotipo.jpg
   ═══════════════════════════════════════════ */

:root{
  /* marca */
  --orange:      #FD5107;
  --orange-mid:  #FA8E21;
  --orange-soft: #FDBE6B;
  --butter:      #FCE08D;
  --sand:        #E7E2CF;

  /* neutros */
  --ink:      #16130F;
  --ink-2:    #3A342E;
  --muted:    #6B645C;
  --line:     #E9E5DE;
  --bg:       #FFFFFF;
  --bg-soft:  #FBFAF7;
  --bg-sand:  #F4F1E8;

  --wrap: 1200px;
  --wrap-wide: 1560px;   /* sólo el hero: el titular respira más que el resto */
  --r-sm: 10px;
  --r-md: 18px;
  --r-lg: 26px;
  --pill: 999px;

  --shadow-sm: 0 2px 10px rgba(22,19,15,.05);
  --shadow-md: 0 14px 40px -18px rgba(22,19,15,.22);
  --shadow-lg: 0 30px 70px -30px rgba(253,81,7,.35);

  --sans: "Archivo", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --mono: "Martian Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  /* Una sola familia para todo: el contraste sale del eje de ancho de Archivo,
     no de mezclar fuentes. Por eso --display ya no es una fuente aparte. */
  --display: var(--sans);
  --w-ancho: 112;    /* titulares, como letrero */
  --w-normal: 100;   /* texto corrido */
  --w-estrecho: 78;  /* etiquetas y datos cortos */

  /* Texto sobre superficies de color saturado. Sobre --orange el blanco sólo
     da 3.30:1, así que se reserva para texto grande; el cuerpo va en --ink,
     que ahí mismo da 5.60:1. */
  --tinta-invertida: #FFFFFF;

  --ease: cubic-bezier(.22,.61,.36,1);
}

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

html{ scroll-behavior:smooth; -webkit-text-size-adjust:100%; }

body{
  margin:0;
  font-family:var(--sans);
  font-variation-settings:"wdth" var(--w-normal);
  font-size:16px;
  line-height:1.6;
  color:var(--ink-2);
  background:var(--bg);
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}

h1,h2,h3{
  color:var(--ink); font-weight:800; line-height:1.08; letter-spacing:-.024em; margin:0;
  font-variation-settings:"wdth" var(--w-ancho);
}
p{ margin:0; }
img{ max-width:100%; height:auto; display:block; }
a{ color:inherit; text-decoration:none; }
ul,ol{ margin:0; padding:0; list-style:none; }
button{ font:inherit; color:inherit; }

.sprite{ position:absolute; width:0; height:0; overflow:hidden; }

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

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

:where(a,button,input):focus-visible{
  outline:3px solid var(--orange); outline-offset:3px; border-radius:6px;
}

/* ── iconos ───────────────────────────── */
.ico{
  width:22px; height:22px; flex:none;
  fill:currentColor; stroke:none;
}
.ico--lg{ width:30px; height:30px; }

/* ── botones ──────────────────────────── */
/* Ni cápsula ni rectángulo: un bloque con dos esquinas cortadas en diagonal,
   arriba a la izquierda y abajo a la derecha. Es la figura de un boleto
   troquelado —que es justo lo que se compra aquí— y no se parece a ningún
   botón de plantilla. Planos, sin relieve ni sombra: el color hace el
   trabajo y al pasar el cursor sólo cambia el fondo y corre la flecha.
   El corte vive en un ::before y no en el propio botón, porque clip-path
   recortaría también el anillo de foco y ese se tiene que ver entero. */
.btn{
  position:relative; z-index:0;   /* contexto de apilado: el ::before no se va detrás de la sección */
  display:inline-flex; align-items:center; justify-content:center; gap:10px;
  padding:13px 24px;
  border:0; border-radius:0; background:transparent;
  font-weight:700; font-size:.94rem; letter-spacing:-.01em;
  cursor:pointer; white-space:nowrap;
  --btn-corte:11px;
  --btn-bg:var(--orange);
  transition:color .2s;
}
.btn::before{
  content:""; position:absolute; inset:0; z-index:-1;
  background:var(--btn-bg);
  clip-path:polygon(
    var(--btn-corte) 0, 100% 0,
    100% calc(100% - var(--btn-corte)), calc(100% - var(--btn-corte)) 100%,
    0 100%, 0 var(--btn-corte));
  transition:background-color .2s;
}
.btn .ico{ width:18px; height:18px; transition:transform .3s var(--ease); }
.btn:hover .ico{ transform:translateX(4px); }
.btn--lg{ padding:15px 28px; font-size:.95rem; --btn-corte:13px; }

.btn--primary{ color:#fff; --btn-bg:var(--orange); }
.btn--primary:hover{ --btn-bg:#E84604; }

/* el secundario ya no es un contorno: relleno de arena, que sobre el blanco
   del hero se lee como bloque y deja la diagonal limpia, sin filete partido */
.btn--ghost{ color:var(--ink); --btn-bg:var(--bg-sand); }
.btn--ghost:hover{ color:var(--ink); --btn-bg:var(--butter); }
.btn__down{ font-size:1.05em; line-height:1; transition:transform .3s var(--ease); }
.btn--ghost:hover .btn__down{ transform:translateY(3px); }

.btn--white{ color:var(--ink); --btn-bg:#fff; }
.btn--white:hover{ color:var(--orange); }

.link-arrow{
  display:inline-flex; align-items:center; gap:9px;
  color:var(--orange); font-weight:700; font-size:.94rem;
}
.link-arrow .ico{ width:18px; height:18px; transition:transform .3s var(--ease); }
.link-arrow:hover .ico{ transform:translateX(5px); }

/* ── header ───────────────────────────── */
.site-header{
  position:sticky; top:0; z-index:100;
  background:rgba(255,255,255,.86);
  backdrop-filter:saturate(180%) blur(14px);
  border-bottom:1px solid transparent;
  transition:border-color .3s, box-shadow .3s;
}
.site-header.is-stuck{ border-bottom-color:var(--line); box-shadow:var(--shadow-sm); }

.header__inner{
  display:flex; align-items:center; gap:28px;
  min-height:78px;
}
.brand img{ width:100px; }
.brand{ margin-right:auto; transition:transform .25s var(--ease); }
.brand:hover{ transform:scale(1.04); }

.nav{ display:flex; align-items:center; gap:34px; }
.nav a{
  font-size:.94rem; font-weight:600; color:var(--ink-2);
  position:relative; padding-block:4px; transition:color .2s;
}
.nav a:not(.btn)::after{
  content:""; position:absolute; left:0; right:100%; bottom:0; height:2px;
  background:var(--orange); border-radius:2px; transition:right .3s var(--ease);
}
.nav a:not(.btn):hover{ color:var(--ink); }
.nav a:not(.btn):hover::after{ right:0; }
.nav__cta{ display:none; }

.burger{
  display:none; width:44px; height:44px; padding:11px 10px;
  background:none; border:1px solid var(--line); border-radius:12px; cursor:pointer;
}
.burger span{ display:block; height:2px; border-radius:2px; background:var(--ink); transition:transform .3s var(--ease), opacity .2s; }
.burger span+span{ margin-top:5px; }
.burger[aria-expanded="true"] span:nth-child(1){ transform:translateY(7px) rotate(45deg); }
.burger[aria-expanded="true"] span:nth-child(2){ opacity:0; }
.burger[aria-expanded="true"] span:nth-child(3){ transform:translateY(-7px) rotate(-45deg); }

/* ── tipografía de sección ────────────── */
.eyebrow{
  font-family:var(--sans); font-variation-settings:"wdth" var(--w-estrecho);
  font-size:.84rem; font-weight:700;
  letter-spacing:.05em; text-transform:uppercase; color:var(--orange);
  margin-bottom:18px;
}
.eyebrow--muted{ color:var(--muted); }

.lead{ color:var(--muted); font-size:1.05rem; line-height:1.7; }

.section-head h2{ font-size:clamp(1.7rem, 3.4vw, 2.4rem); }
/* encabezados de las secciones a dos columnas: más contenidos */
.services__inner .section-head h2,
.process__inner .section-head h2,
.projects__inner .section-head h2{ font-size:clamp(1.45rem, 2.6vw, 1.95rem); }
.section-head--center{ max-width:760px; margin-inline:auto; text-align:center; }
.section-head--center h2{ font-size:clamp(1.75rem, 3.6vw, 2.5rem); margin-bottom:18px; }

/* ── display de contraste ─────────────── */
/* Ya no hay una fuente aparte para esto: el acento se consigue estirando
   Archivo al 118 y subiéndola a 800, más apretada que el resto del encabezado.
   Se usa en puñados de palabras, nunca en texto corrido. */
.display{
  font-family:var(--display);
  font-weight:800;
  font-variation-settings:"wdth" 118;
  letter-spacing:-.03em;
}

/* ═══ DIVISOR ════════════════════════════ */
/* Banda a sangre completa que cierra el bloque del hero: un campo de
   vóxeles que ondula solo y se levanta bajo el cursor (escenas.js).
   El degradado lleva del blanco del hero al fondo de la sección
   siguiente, así que la banda se sigue leyendo como transición aunque el
   lienzo no pinte — sin JS, o antes de que la escena entre en pantalla. */
.divisor{
  position:relative;
  z-index:0;
  overflow:hidden;
  height:clamp(90px, 10vw, 140px);
  margin-top:clamp(-30px, -2.5vw, -12px);
  margin-bottom:clamp(-40px, -3vw, -20px);
  background:linear-gradient(180deg, var(--bg) 0%, var(--bg-soft) 100%);
}
.divisor__campo{
  position:absolute; inset:0;
  /* Decorativo: el puntero lo escucha la banda, no el lienzo, para no
     tapar nada de lo que haya alrededor. */
  pointer-events:none;
}

/* ═══ HERO ═══════════════════════════════ */
.hero{ position:relative; padding:0 0 clamp(32px, 4.5vw, 56px); overflow:hidden; }
.hero::after{
  content:""; position:absolute; inset:auto 0 0; height:1px; background:var(--line);
}
.hero__inner{
  position:relative; z-index:1;   /* por encima de los cables del fondo */
  display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  column-gap:clamp(32px, 4vw, 60px);
  row-gap:clamp(26px, 3vw, 44px);
  align-items:start;   /* el visual es más alto que el copy: si se centra, deja un hueco muerto */
}
/* El titular cruza las dos columnas: es lo que hace que el hero llene la pantalla.
   Debajo quedan copy (izquierda) y visual (derecha). */
.hero__title{ grid-column:1 / -1; }
/* Titular a gran escala: pesa por tamaño, no por grosor. El 300 sólo se
   sostiene a partir de ~38px; en móvil el clamp no baja de 2.35rem. */
.hero h1{
  /* El tope lo marca "Ingeniería de", la línea más larga: debe caber entera
     dentro de los 3/4 de columna, también a 1081px (el punto más estrecho
     del layout de escritorio). */
  font-size:clamp(2.1rem, 7vw, 7.5rem);
  font-weight:300;
  line-height:1.04;
  letter-spacing:-.035em;
  margin-bottom:0;          /* el aire lo pone el row-gap del grid */
}
.hero h1 .hl{ color:var(--orange); }

/* Subrayado de marcador: franja butter en la mitad inferior de la palabra.
   Va en el fondo, así que el texto conserva su color y su contraste.
   Porcentajes (no em) para que la banda siga al tamaño en cualquier breakpoint. */
.mark{
  background-image:linear-gradient(var(--butter), var(--butter));
  background-repeat:no-repeat;
  background-size:100% 34%;
  background-position:0 76%;
  padding-inline:.06em;
  -webkit-box-decoration-break:clone;
          box-decoration-break:clone;   /* la franja se repite si la palabra parte de línea */
}
.hero__copy .lead{ max-width:46ch; }
.hero__actions{ display:flex; flex-wrap:wrap; gap:14px; margin-top:34px; }

/* ── titular plegado (fold) ───────────── */
/* .fold aporta la perspectiva y .fold__p hace el giro. Tienen que ser dos
   elementos: si la perspectiva viviera en el mismo nodo que rota, se
   aplicaría al conjunto del titular y todas las letras compartirían punto
   de fuga en vez de plegarse cada una sobre su propia bisagra. */
/* El estado plegado es el de partida y NO lleva transición: las .fold__p sólo
   existen si el JS partió el titular, así que nadie se queda con letras
   invisibles. La transición vive únicamente en .is-unfolded — si estuviera en
   la base, plegar y desplegar compartirían retardo y la animación se comería
   a sí misma. */
.fold{ display:inline-block; perspective:700px; }
.fold__p{
  position:relative; display:inline-block;
  transform-origin:50% 0%;              /* bisagra arriba */
  backface-visibility:hidden;
  transform:rotateX(-92deg); opacity:0;
}
/* sombra del pliegue: se apaga conforme la letra se endereza */
.fold__p::after{
  content:""; position:absolute; inset:-.08em -.02em;
  pointer-events:none; border-radius:.08em;
  mix-blend-mode:multiply; opacity:0;
  /* más suave que el original: sobre fondo blanco el multiply de un negro
     fuerte deja losas grises en vez de sombra de pliegue */
  background:linear-gradient(180deg, rgba(22,19,15,.42) 0%, rgba(22,19,15,.14) 45%, rgba(255,255,255,.2) 100%);
  opacity:.34;
}
.is-unfolded .fold__p{
  transform:none; opacity:1;
  transition:transform .65s cubic-bezier(.165,.84,.44,1),
             opacity   .65s cubic-bezier(.165,.84,.44,1);
}
.is-unfolded .fold__p::after{
  opacity:0;
  transition:opacity .65s cubic-bezier(.165,.84,.44,1);
  transition-delay:inherit;             /* hereda el retardo escalonado del inline style */
}

/* La franja del marcador arranca a 0 de ancho y se pinta cuando el pliegue ya
   va por "de todos". Se condiciona a .js para que sin JS salga completa.
   0% y no 0: mezclar longitud con porcentaje impide interpolar background-size. */
.js .hero__title .mark{ background-size:0% 34%; }
.js .hero__title.is-unfolded .mark{
  background-size:100% 34%;
  transition:background-size .55s var(--ease) 1.3s;
}
/* cursor parpadeante del typing effect en #typed */
#typed::after{
  content:"|";
  display:inline-block;
  margin-left:1px;
  font-weight:300;
  color:currentColor;
  animation:typed-cursor 1s steps(1) infinite;
}
@keyframes typed-cursor{
  0%,50%{opacity:1;}
  50.01%,100%{opacity:0;}
}

/* ── cables animados del hero ─────────── */
/* Entran por el borde derecho y terminan en nodos cuadrados cerca del centro.
   Puramente decorativo: aria-hidden en el marcado y sin captura de puntero. */
.cables{
  position:absolute; z-index:0; inset:0;
  pointer-events:none;
}
/* preserveAspectRatio="none" en el SVG: el viewBox (1440×820) se estira al alto
   real del hero, así que cada coordenada cae siempre en la misma proporción del
   bloque y los nodos no se salen de los huecos previstos. El estirón deformaría
   el grosor del trazo — lo evita non-scaling-stroke. */
.cables svg{ display:block; width:100%; height:100%; }
.cable, .pulse{ vector-effect:non-scaling-stroke; }

.cable{ stroke:rgba(253,81,7,.30); stroke-width:2; stroke-linecap:round; stroke-linejoin:round; }
.cable--thin{ stroke:rgba(253,81,7,.20); stroke-width:1.5; }

/* El pulso es un dash corto sobre el mismo trazado. Con pathLength="100" el
   recorrido siempre mide 100, así que un único @keyframes vale para todos
   los cables sin importar su longitud real. */
.pulse{
  stroke:var(--orange); stroke-width:3; stroke-linecap:round; stroke-linejoin:round;
  stroke-dasharray:11 89;
  animation:cable-pulse 4.4s linear infinite;
  animation-delay:var(--d, 0s);
}
.pulse--thin{ stroke-width:2; stroke:var(--orange-mid); }
@keyframes cable-pulse{
  from{ stroke-dashoffset:100; }   /* dash en el borde derecho */
  to  { stroke-dashoffset:0; }     /* dash llegando al nodo */
}

/* el nodo se enciende justo cuando el pulso termina el recorrido */
.node__ring{ fill:none; stroke:var(--orange); stroke-width:2; opacity:.28; animation:node-ring 4.4s ease-in-out infinite; animation-delay:var(--d, 0s); }
.node__core{ fill:var(--orange); opacity:.55; animation:node-core 4.4s ease-in-out infinite; animation-delay:var(--d, 0s); }
@keyframes node-ring{ 0%,82%{ opacity:.28; } 95%{ opacity:.8; } 100%{ opacity:.28; } }
@keyframes node-core{ 0%,82%{ opacity:.55; } 95%{ opacity:1; } 100%{ opacity:.55; } }

/* visual */
.hero__visual{ position:relative; }
.glow{
  position:absolute; inset:-14% -10% 20%;
  background:
    radial-gradient(46% 52% at 62% 34%, rgba(252,224,141,.85), transparent 70%),
    radial-gradient(38% 44% at 30% 60%, rgba(253,190,107,.5), transparent 72%);
  filter:blur(14px); z-index:-1; pointer-events:none;
}

.flow{ position:relative; aspect-ratio:520/260; margin-bottom:26px; }
.flow__lines{ position:absolute; inset:0; width:100%; height:100%; }
.flow__logo{
  position:absolute; left:46%; top:50%; transform:translate(-50%,-50%);
  width:46%; filter:drop-shadow(0 12px 26px rgba(253,81,7,.22));
}

/* ── el logo se "dibuja" ──────────────────
   Una máscara de gradiente más ancha que la imagen (220%) se desplaza de
   derecha a izquierda; el borde suave del gradiente barre el logo y lo va
   descubriendo de izquierda a derecha. Como el "du." vive en el extremo
   derecho del PNG, aparece solo al final sin necesidad de separarlo.
   El estado oculto se condiciona a .js: sin JS nunca llegaría el .is-in
   que lo revela y el logo se quedaría en blanco. */
.js .flow__logo{
  -webkit-mask-image:linear-gradient(90deg, #000 0 45%, rgba(0,0,0,0) 62%);
          mask-image:linear-gradient(90deg, #000 0 45%, rgba(0,0,0,0) 62%);
  -webkit-mask-repeat:no-repeat; mask-repeat:no-repeat;
  -webkit-mask-size:220% 100%;   mask-size:220% 100%;
  -webkit-mask-position:100% 0;  mask-position:100% 0;   /* oculto */
}
/* Con @keyframes y no con transition: en la lista de `transition` basta que un
   nombre no se reconozca (el par -webkit-/sin prefijo) para que el navegador
   tire la declaración entera y el barrido se salte. Dentro de un @keyframes
   cada propiedad inválida se ignora por separado. */
.js .hero__visual.is-in .flow__logo{
  animation:logo-draw 1.5s var(--ease) .15s both;
}
@keyframes logo-draw{
  from{ -webkit-mask-position:100% 0; mask-position:100% 0; }
  to  { -webkit-mask-position:0% 0;   mask-position:0% 0;   }
}

.brain{
  position:absolute; color:var(--orange-mid);
  width:13%; aspect-ratio:13/10;
  animation:float 6s ease-in-out infinite;
}
.brain--a{ left:2%;  top:12%;  color:var(--orange-mid); }
.brain--b{ left:11%; top:40%;  color:var(--orange); width:11%; animation-delay:-2s; }
.brain--c{ left:6%;  top:66%;  color:var(--orange-soft); width:10%; animation-delay:-4s; }
@keyframes float{ 0%,100%{ transform:translateY(0); } 50%{ transform:translateY(-9px); } }

.pix{ position:absolute; width:9px; height:9px; background:var(--butter); border-radius:1px; }
.pix--1{ left:34%; top:80%; background:var(--orange-soft); }
.pix--2{ left:39%; top:88%; }
.pix--3{ left:30%; top:90%; width:6px; height:6px; }

/* pipeline 4 pasos */
.pipeline{
  display:grid; grid-template-columns:repeat(4,1fr); gap:14px;
  position:relative; text-align:center;
}
.pipeline li{ position:relative; }
.pipeline li:not(:last-child)::after{
  content:""; position:absolute; top:27px; left:calc(50% + 34px); right:calc(-50% + 34px);
  border-top:2px dashed rgba(253,81,7,.45);
}
.pipeline__ico{
  display:grid; place-items:center; width:54px; height:54px; margin:0 auto 12px;
  border-radius:50%; background:var(--butter); color:var(--ink);
  box-shadow:0 8px 18px -10px rgba(253,81,7,.5);
}
.pipeline li:nth-child(2) .pipeline__ico{ background:var(--orange-soft); }
.pipeline li:nth-child(3) .pipeline__ico{ background:var(--orange-mid); color:#fff; }
.pipeline__ico--brain{ background:transparent !important; color:var(--orange) !important; box-shadow:none; }
.pipeline__ico--brain .ico{ width:38px; height:30px; }
.pipeline h3{ font-size:.98rem; margin-bottom:6px; }
.pipeline p{ font-size:.8rem; color:var(--muted); line-height:1.5; }


/* ═══════════════════════════════════════════════════════════════════
   DE LA SECCIÓN 2 EN ADELANTE

   Cada sección tiene un lienzo con una escena de vóxeles. Reglas que se
   repiten y conviene tener presentes al editar:

   · el ritmo de fondos alterna claro / blanco / arena / blanco / OSCURO
     / naranja, para que ninguna sección se confunda con la anterior;
   · la sección oscura (Nosotros) es deliberada: rompe la monotonía y
     hace que el naranja de la marca pese de verdad;
   · el canvas siempre es decorativo — el texto vive en el HTML;
   · todo lo que se anima solo tiene un control manual visible.
   ═══════════════════════════════════════════════════════════════════ */

:root{
  --ink-hondo: #100E0B;     /* fondo de la sección oscura */
  --seccion: clamp(52px, 5.6vw, 84px);
}

/* Todos los canvas de escena se comportan igual: llenan su caja y dejan
   el gesto vertical al navegador, para no bloquear nunca el scroll. */
.escena{
  display:block;
  width:100%; height:100%;
  touch-action:pan-y;
}


/* ═══ barra de progreso de lectura ═══════ */
.progreso{
  position:absolute; left:0; right:0; bottom:-1px; height:2px;
  overflow:hidden; pointer-events:none;
}
.progreso__barra{
  display:block; height:100%; width:100%;
  background:linear-gradient(90deg, var(--orange), var(--orange-mid));
  transform:scaleX(0); transform-origin:0 50%;
}


/* ═══ mapa lateral de secciones ══════════
   Puntos fijos a la derecha. Son anclas reales: sin JavaScript siguen
   llevando a su sección; el script sólo marca cuál es la actual. */
.mapa{
  position:fixed; right:18px; top:50%; transform:translateY(-50%);
  z-index:60; display:flex; flex-direction:column; gap:14px;
  padding:14px 10px; border-radius:var(--pill);
  background:rgba(255,255,255,.72);
  backdrop-filter:blur(10px);
  border:1px solid var(--line);
  box-shadow:var(--shadow-sm);
}
.mapa__p{
  position:relative; width:9px; height:9px; border-radius:50%;
  background:var(--line); border:0; padding:0; cursor:pointer;
  transition:background .3s var(--ease), transform .3s var(--ease);
}
.mapa__p:hover{ background:var(--orange-soft); transform:scale(1.25); }
.mapa__p.is-activo{ background:var(--orange); transform:scale(1.35); }

/* etiqueta con el nombre de la sección, a la izquierda del punto */
.mapa__p span{
  position:absolute; right:22px; top:50%; transform:translateY(-50%) translateX(6px);
  white-space:nowrap; font-size:.72rem; font-weight:700; letter-spacing:.01em;
  color:#fff; background:var(--ink); padding:5px 10px; border-radius:var(--r-sm);
  opacity:0; pointer-events:none;
  transition:opacity .25s var(--ease), transform .25s var(--ease);
}
.mapa__p:hover span,
.mapa__p:focus-visible span{ opacity:1; transform:translateY(-50%) translateX(0); }


/* ═══ ENFOQUE ════════════════════════════ */
.enfoque{
  background:var(--bg-soft);
  padding:var(--seccion) 0;
  border-bottom:1px solid var(--line);
}

.enfoque__lienzo{
  position:relative;
  height:clamp(250px, 30vw, 360px);
  margin:clamp(18px, 2.6vw, 30px) auto clamp(16px, 2.2vw, 26px);
  max-width:900px;
}

/* aviso de que la escena se puede girar; desaparece mientras se arrastra */
.tip{
  position:absolute; left:50%; bottom:-2px; transform:translateX(-50%);
  display:inline-flex; align-items:center; gap:7px;
  font-size:.74rem; font-weight:600; color:var(--muted);
  background:rgba(255,255,255,.85); border:1px solid var(--line);
  padding:6px 13px; border-radius:var(--pill);
  transition:opacity .3s var(--ease);
}
.tip .ico{ width:15px; height:15px; color:var(--orange); }
.escena.is-girando + .tip{ opacity:0; }
.escena{ cursor:grab; }
.escena.is-girando{ cursor:grabbing; }
/* los iconos de servicio y los fondos no se arrastran */
.servicio__lienzo .escena,
.proceso__lienzo .escena,
.valores__lienzo .escena,
.divisor__campo,
.cta__campo{ cursor:default; }

.enfoque__pasos{
  display:grid; grid-template-columns:repeat(3, 1fr);
  gap:clamp(12px, 1.6vw, 20px);
}

.enfoque__paso{
  display:block; text-align:left; cursor:pointer;
  background:#fff; border:1px solid var(--line); border-radius:var(--r-lg);
  padding:clamp(18px, 2.2vw, 26px);
  transition:border-color .35s var(--ease), transform .35s var(--ease),
             box-shadow .35s var(--ease), background .35s var(--ease);
}
.enfoque__paso:hover{ transform:translateY(-3px); box-shadow:var(--shadow-md); }
.enfoque__paso.is-activo{
  border-color:var(--orange);
  box-shadow:0 18px 44px -22px rgba(253,81,7,.55);
  transform:translateY(-3px);
}

.enfoque__cabeza{ display:flex; align-items:center; justify-content:space-between; margin-bottom:14px; }
.enfoque__n{
  font-family:var(--mono); font-size:.78rem; font-weight:700;
  color:var(--muted); transition:color .3s var(--ease);
}
.enfoque__paso.is-activo .enfoque__n{ color:var(--orange); }

.enfoque__ico{
  display:grid; place-items:center; width:42px; height:42px;
  border-radius:var(--r-sm); background:var(--bg-sand); color:var(--ink-2);
  transition:background .35s var(--ease), color .35s var(--ease);
}
.enfoque__ico .ico{ width:22px; height:22px; }
/* el cerebro es de proporción 13×10: si se cuadra, se aplasta */
.enfoque__paso:first-child .enfoque__ico .ico{ width:26px; height:20px; }
.enfoque__paso.is-activo .enfoque__ico{ background:var(--orange); color:#fff; }

.enfoque__paso h3{ font-size:1.02rem; margin-bottom:7px; }
.enfoque__paso p{ font-size:.86rem; color:var(--muted); line-height:1.6; }

/* microcopia que dice qué hace el botón; sólo aparece al interactuar */
.enfoque__estado{
  display:inline-block; margin-top:12px;
  font-size:.72rem; font-weight:700; letter-spacing:.02em;
  color:var(--orange); opacity:0;
  transition:opacity .3s var(--ease);
}
.enfoque__paso:hover .enfoque__estado,
.enfoque__paso:focus-visible .enfoque__estado{ opacity:1; }
.enfoque__paso.is-activo .enfoque__estado{ opacity:0; }


/* ═══ SERVICIOS ══════════════════════════ */
.servicios{ padding:var(--seccion) 0; }
.servicios .section-head{ max-width:720px; margin-bottom:clamp(22px, 2.6vw, 34px); }
.servicios .section-head h2{ margin-bottom:14px; }

/* Rejilla editorial: la tarjeta de IA ocupa dos columnas y se lee en
   horizontal; las otras cuatro caen a su alrededor. Rompe el patrón de
   "cinco tarjetas iguales" sin complicar la lectura. */
.servicios__rejilla{
  display:grid; grid-template-columns:repeat(3, 1fr);
  gap:clamp(12px, 1.4vw, 17px);
}
.servicio--ancho{ grid-column:span 2; }

.servicio{
  display:flex; flex-direction:column; gap:13px;
  background:#fff; border:1px solid var(--line); border-radius:var(--r-lg);
  padding:clamp(17px, 1.8vw, 22px);
  transition:border-color .35s var(--ease), transform .35s var(--ease),
             box-shadow .35s var(--ease);
}
.servicio:hover,
.servicio:focus-visible{
  border-color:var(--orange);
  transform:translateY(-4px);
  box-shadow:0 22px 50px -26px rgba(253,81,7,.5);
}

.servicio__lienzo{ width:78px; height:78px; margin:-8px 0 -8px -8px; }
/* centrado vertical: la tarjeta ancha es mas alta que su contenido
   porque la fila la estira la vecina, y con el contenido arriba queda un
   hueco muerto abajo que parece un error de maquetacion */
.servicio--ancho{ flex-direction:row; align-items:center; gap:clamp(18px, 2.4vw, 30px); }
/* se estira al alto de la fila: si se deja cuadrado, la tarjeta ancha queda
   con aire muerto arriba y abajo porque la fila la estira la tarjeta vecina */
.servicio--ancho .servicio__lienzo{ width:150px; height:auto; align-self:stretch; flex:none; margin:-10px 0 -10px -14px; }
.servicio--ancho h3{ font-size:1.22rem; }

.servicio h3{ font-size:1.02rem; margin-bottom:8px; }
.servicio p{ font-size:.87rem; color:var(--muted); line-height:1.62; }


/* Puente hacia #productos: cierra la sección con una prueba concreta en
   vez de dejar la rejilla colgando. */
.servicios__pie{
  display:flex; flex-wrap:wrap; align-items:center; gap:10px 16px;
  margin-top:clamp(16px, 2vw, 24px);
  font-size:.88rem; color:var(--muted);
}

.etiquetas{ display:flex; flex-wrap:wrap; gap:6px; margin-top:14px; }
.etiquetas li{
  font-size:.71rem; font-weight:600; color:var(--ink-2);
  background:var(--bg-sand); border-radius:var(--pill); padding:4px 10px;
}


/* ═══ PRODUCTOS ══════════════════════════
   Software propio, ya en operación. A diferencia de #proyectos —que
   ilustra tipos de trabajo— aquí cada tarjeta enlaza a algo que se puede
   abrir, así que la tarjeta ENTERA es el enlace y se comporta como tal:
   un solo foco de teclado, y el "abre en otra pestaña" avisado en el texto. */
.productos{ background:var(--bg-soft); padding:var(--seccion) 0; border-block:1px solid var(--line); }
.productos .section-head{ max-width:720px; margin-bottom:clamp(22px, 2.6vw, 34px); }
.productos .section-head h2{ margin-bottom:14px; }

.productos__rejilla{
  display:grid; grid-template-columns:repeat(3, 1fr);
  gap:clamp(12px, 1.4vw, 17px);
}

.producto{
  display:flex; flex-direction:column; gap:11px;
  background:#fff; border:1px solid var(--line); border-radius:var(--r-lg);
  padding:clamp(17px, 1.8vw, 22px);
  color:inherit;
  transition:border-color .35s var(--ease), transform .35s var(--ease),
             box-shadow .35s var(--ease);
}
.producto:hover,
.producto:focus-visible{
  border-color:var(--orange);
  transform:translateY(-4px);
  box-shadow:0 22px 50px -26px rgba(253,81,7,.5);
}

/* Cabecera: el icono y el sector en una sola línea, sin robar alto */
.producto__top{ display:flex; align-items:center; gap:10px; }
.producto__ico{
  flex:none; display:grid; place-items:center;
  width:38px; height:38px; border-radius:11px;
  background:var(--bg-sand); color:var(--orange);
}
.producto__ico .ico{ width:19px; height:19px; }
.producto__sector{
  font-family:var(--mono); font-size:.68rem; font-weight:700;
  letter-spacing:.08em; text-transform:uppercase; color:var(--muted);
}

.producto__n{
  font-family:var(--display); font-weight:400;
  font-size:1.45rem; line-height:1.05; letter-spacing:-.01em;
  color:var(--ink);
}
.producto p{ font-size:.87rem; color:var(--muted); line-height:1.62; }
/* la tarjeta ya separa con gap: la lista no necesita su margen propio */
.producto .etiquetas{ margin-top:2px; }

/* El pie se pega abajo: iguala las tarjetas sin dejar hueco muerto */
.producto__ir{
  margin-top:auto; padding-top:4px;
  display:inline-flex; align-items:center; gap:8px;
  font-size:.84rem; font-weight:700; color:var(--orange);
}
.producto__ir .ico{ width:16px; height:16px; transition:transform .3s var(--ease); }
.producto:hover .producto__ir .ico{ transform:translateX(4px); }
.producto__ir span{ font-family:var(--mono); font-weight:400; font-size:.74rem; color:var(--muted); }


/* ═══ PROCESO ════════════════════════════ */
.proceso{ background:var(--bg-sand); padding:var(--seccion) 0; }

.proceso__lienzo{
  height:clamp(210px, 24vw, 310px);
  margin:clamp(16px, 2.2vw, 26px) auto clamp(14px, 1.8vw, 22px);
  max-width:940px;
}

.pasos{ display:grid; grid-template-columns:repeat(5, 1fr); gap:clamp(8px, 1.2vw, 14px); }

.paso__btn{
  width:100%; height:100%; display:flex; gap:12px; align-items:flex-start;
  text-align:left; cursor:pointer;
  background:transparent; border:1px solid transparent; border-radius:var(--r-md);
  padding:14px 14px 16px;
  transition:background .3s var(--ease), border-color .3s var(--ease), transform .3s var(--ease);
}
.paso__btn:hover{ background:rgba(255,255,255,.7); transform:translateY(-2px); }
.paso.is-activo .paso__btn{ background:#fff; border-color:var(--orange-soft); box-shadow:var(--shadow-sm); }

.paso__n{
  flex:none; display:grid; place-items:center;
  width:30px; height:30px; border-radius:50%;
  font-family:var(--mono); font-size:.72rem; font-weight:700;
  background:#fff; color:var(--muted); border:1px solid var(--line);
  transition:background .3s var(--ease), color .3s var(--ease), border-color .3s var(--ease);
}
.paso.is-activo .paso__n{ background:var(--orange); color:#fff; border-color:var(--orange); }

.paso__txt{ display:block; }
.paso__h{ display:block; font-weight:800; color:var(--ink); font-size:.95rem; margin-bottom:5px; letter-spacing:-.01em; }
.paso__p{ display:block; font-size:.79rem; color:var(--muted); line-height:1.55; }


/* ═══ PROYECTOS ══════════════════════════
   Carrusel 3D. El escenario da la perspectiva y la pista conserva el
   espacio 3D para sus hijas; cada tarjeta se coloca desde JS con su
   propio translate/rotate según su distancia a la del frente. */
.proyectos{ padding:var(--seccion) 0; overflow:hidden; }

.carrusel{ margin-top:clamp(20px, 2.4vw, 30px); outline:none; }
.carrusel:focus-visible{ outline:2px solid var(--orange); outline-offset:14px; border-radius:var(--r-lg); }

.escenario{ perspective:1600px; perspective-origin:50% 45%; }
.pista{
  position:relative;
  height:clamp(370px, 38vw, 450px);
  transform-style:preserve-3d;
  touch-action:pan-y;
}

/* El ancho vive en una variable y el margen negativo se calcula a partir
   de ella. Antes eran dos valores sueltos (`min(680px,88%)` y
   `min(-340px,-44%)`) y no eran la misma cantidad: `min()` con negativos
   devuelve el MÁS negativo, no la mitad del ancho, así que la tarjeta se
   descentraba en cuanto cambiaba el tamaño de la ventana. */
.proyecto{
  --ancho:min(680px, 88%);
  position:absolute; top:0; left:50%;
  width:var(--ancho);
  margin-left:calc(var(--ancho) / -2);
  background:#fff; border:1px solid var(--line); border-radius:var(--r-lg);
  overflow:hidden; box-shadow:var(--shadow-md);
  transition:transform .65s var(--ease), opacity .65s var(--ease);
  transform-style:preserve-3d;
  cursor:pointer;
}
.proyecto.is-activo{ cursor:default; box-shadow:0 40px 80px -40px rgba(22,19,15,.4); }

.proyecto__cuerpo{ padding:clamp(18px, 2.4vw, 26px); }
.proyecto__cuerpo h3{ font-size:1.14rem; margin:6px 0 8px; }
.proyecto__cuerpo > p{ font-size:.88rem; color:var(--muted); line-height:1.62; }

.marcas{ display:flex; flex-wrap:wrap; gap:8px 18px; margin-top:14px; }
.marcas li{ display:flex; align-items:center; gap:7px; font-size:.8rem; font-weight:600; color:var(--ink-2); }
.marcas .ico{ width:16px; height:16px; color:var(--orange); flex:none; }

/* ── maqueta dibujada con CSS ──
   Marcador de posición: son formas, no capturas reales. Cuando el
   cliente entregue pantallas de verdad, se sustituyen por <img>. */
.captura{ background:var(--bg-sand); border-bottom:1px solid var(--line); padding:12px; }
.captura__barra{ display:flex; gap:5px; margin-bottom:10px; }
.captura__barra i{ width:8px; height:8px; border-radius:50%; background:var(--line); }
.captura__barra i:first-child{ background:var(--orange-soft); }

.captura__ui{ display:grid; grid-template-columns:52px 1fr; gap:10px; height:190px; }
.captura__lado{ display:flex; flex-direction:column; gap:7px; background:#fff; border-radius:var(--r-sm); padding:10px 8px; }
.captura__lado span{ height:6px; border-radius:3px; background:var(--line); }
.captura__lado span:first-child{ background:var(--orange); width:70%; }
.captura__main{ background:#fff; border-radius:var(--r-sm); padding:12px; display:flex; flex-direction:column; gap:10px; }
.captura__fila{ display:grid; grid-template-columns:repeat(3,1fr); gap:8px; }
.captura__fila b{ height:26px; border-radius:6px; background:var(--bg-sand); }
.captura__fila b:first-child{ background:var(--butter); }

.captura__grafica{ flex:1; display:flex; align-items:flex-end; gap:6px; }
.captura__grafica i{
  flex:1; border-radius:4px 4px 0 0; background:var(--orange-soft);
  height:var(--h);
  transform-origin:50% 100%;
  animation:barraCrece 2.6s var(--ease) infinite alternate;
}
.captura__grafica i:nth-child(even){ background:var(--orange); animation-delay:.35s; }
.captura__grafica i:nth-child(3n){ animation-delay:.7s; }
@keyframes barraCrece{ from{ transform:scaleY(.62); } to{ transform:scaleY(1); } }

.captura__lineas{ display:flex; flex-direction:column; gap:6px; }
.captura__lineas span{ height:6px; border-radius:3px; background:var(--line); }
.captura__lineas span:nth-child(2){ width:78%; }
.captura__lineas span:nth-child(3){ width:56%; }
.captura__lineas--alto span{ height:9px; }

.captura__chat{ height:190px; background:#fff; border-radius:var(--r-sm); padding:14px; display:flex; flex-direction:column; gap:9px; }
.burbuja{ max-width:78%; font-size:.76rem; line-height:1.45; padding:8px 12px; border-radius:14px; }
.burbuja--ent{ align-self:flex-start; background:var(--bg-sand); color:var(--ink-2); border-bottom-left-radius:5px; }
.burbuja--sal{ align-self:flex-end; background:var(--orange); color:#fff; border-bottom-right-radius:5px; }
.burbuja--escribiendo{ display:flex; gap:4px; align-items:center; padding:11px 13px; }
.burbuja--escribiendo i{ width:6px; height:6px; border-radius:50%; background:rgba(255,255,255,.9); animation:escribe 1.3s infinite; }
.burbuja--escribiendo i:nth-child(2){ animation-delay:.18s; }
.burbuja--escribiendo i:nth-child(3){ animation-delay:.36s; }
@keyframes escribe{ 0%,60%,100%{ opacity:.35; transform:translateY(0); } 30%{ opacity:1; transform:translateY(-3px); } }

.captura__app{ display:grid; grid-template-columns:106px 1fr; gap:14px; height:190px; align-items:center; }
.tel{ background:#fff; border:1px solid var(--line); border-radius:16px; padding:10px 9px; display:flex; flex-direction:column; gap:7px; height:100%; }
.tel__hd{ height:8px; width:52%; border-radius:4px; background:var(--orange); }
.tel__card{ flex:1; border-radius:8px; background:var(--bg-sand); }
.tel__cta{ height:20px; border-radius:var(--pill); background:var(--orange); }

/* ── controles ── */
.carrusel__nav{ display:flex; align-items:center; justify-content:center; gap:18px; margin-top:clamp(18px, 2.6vw, 28px); }

.round{
  display:grid; place-items:center; width:44px; height:44px; border-radius:50%;
  background:#fff; border:1px solid var(--line); color:var(--ink); cursor:pointer;
  transition:background .3s var(--ease), border-color .3s var(--ease),
             color .3s var(--ease), transform .3s var(--ease);
}
.round:hover{ background:var(--orange); border-color:var(--orange); color:#fff; transform:scale(1.07); }
.round .ico{ width:18px; height:18px; }
#prev .ico{ transform:rotate(180deg); }

.puntos{ display:flex; gap:9px; }
.puntos__p{
  width:9px; height:9px; border-radius:50%; border:0; padding:0; cursor:pointer;
  background:var(--line);
  transition:background .3s var(--ease), width .3s var(--ease);
}
.puntos__p:hover{ background:var(--orange-soft); }
.puntos__p.is-activo{ background:var(--orange); width:26px; border-radius:var(--pill); }


/* ═══ NOSOTROS ═══════════════════════════
   La única sección oscura de la página. Es a propósito: corta el ritmo
   de fondos claros y hace que el naranja de la estructura pese. */
.valores{
  background:var(--ink-hondo); color:rgba(255,255,255,.72);
  padding:var(--seccion) 0;
  position:relative; overflow:hidden;
}
.valores__inner{
  display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1.05fr);
  gap:clamp(30px, 5vw, 70px); align-items:center;
}
.valores__lienzo{ height:clamp(260px, 28vw, 360px); }

.valores h2{ color:#fff; }
.valores .eyebrow--muted{ color:var(--orange-soft); }
/* Sobre negro, la banda del resaltado corta los descendentes y parece un
   subrayado mal puesto. En oscuro la palabra acentuada se resuelve con
   color, que es más limpio y sigue siendo el naranja de la marca. */
.valores .mark{ background-image:none; color:var(--orange-soft); }

.valores__lista{ display:flex; flex-direction:column; gap:2px; margin-top:26px; }
.valores__lista li{
  display:flex; gap:15px; align-items:flex-start;
  padding:15px 16px; border-radius:var(--r-md);
  transition:background .3s var(--ease);
}
.valores__lista li:hover{ background:rgba(255,255,255,.05); }

.valores__ico{
  flex:none; display:grid; place-items:center; width:38px; height:38px;
  border-radius:var(--r-sm);
  background:rgba(253,81,7,.16); color:var(--orange-soft);
}
.valores__ico .ico{ width:19px; height:19px; }
.valores__lista h3{ color:#fff; font-size:.97rem; margin-bottom:5px; }
.valores__lista p{ font-size:.84rem; color:rgba(255,255,255,.6); line-height:1.6; }


/* ═══ CTA ════════════════════════════════ */
.cta{
  position:relative; overflow:hidden;
  background:linear-gradient(115deg, var(--orange) 0%, #F2660C 55%, var(--orange-mid) 100%);
  padding:clamp(56px, 7vw, 96px) 0;
}
/* El campo de vóxeles es TEXTURA, no contenido: va a lo ancho, pegado
   abajo y por debajo del texto. Cuando ocupaba sólo la mitad derecha se
   leía como una mancha y encima pisaba la nota del botón. */
.cta__campo{
  position:absolute; left:0; right:0; bottom:0;
  width:100%; height:46%;
  opacity:.55; pointer-events:none;
}
.cta__pixels{
  position:absolute; left:-20px; top:-20px; width:280px; height:200px;
  background-image:
    linear-gradient(var(--butter) 0 0), linear-gradient(rgba(255,255,255,.5) 0 0),
    linear-gradient(var(--butter) 0 0), linear-gradient(rgba(255,255,255,.35) 0 0);
  background-repeat:no-repeat;
  background-size:22px 22px, 14px 14px, 12px 12px, 18px 18px;
  background-position:40px 30px, 76px 66px, 26px 84px, 96px 20px;
  opacity:.55; pointer-events:none;
}

.cta__inner{
  position:relative; z-index:1; padding-bottom:clamp(30px, 6vw, 76px);
  display:flex; align-items:center; justify-content:space-between;
  gap:clamp(24px, 4vw, 48px); flex-wrap:wrap;
}
.cta h2{ color:#fff; font-size:clamp(1.6rem, 3.4vw, 2.3rem); margin-bottom:16px; }
.cta h2 span{ color:var(--butter); }
.cta p{ font-size:.98rem; color:rgba(255,255,255,.92); line-height:1.65; }

.cta__acciones{ display:flex; flex-direction:column; align-items:flex-start; gap:12px; flex:none; }
.cta__nota{ font-size:.78rem; color:rgba(255,255,255,.8); font-weight:600; }


/* ═══ FOOTER ═════════════════════════════ */
.site-footer{ background:#fff; padding:clamp(34px, 4vw, 52px) 0 22px; }
.footer__inner{
  display:grid; grid-template-columns:minmax(0,1fr) auto auto;
  gap:clamp(22px, 4vw, 52px); align-items:start;
  padding-bottom:26px; border-bottom:1px solid var(--line);
}
.brand--footer img{ width:104px; }
.footer__tag{ font-size:.82rem; color:var(--muted); margin-top:10px; }

.footer__nav{ display:flex; flex-direction:column; gap:9px; }
.footer__nav a{ font-size:.84rem; color:var(--muted); transition:color .25s var(--ease); }
.footer__nav a:hover{ color:var(--orange); }

.footer__contacto{ display:flex; flex-direction:column; gap:10px; }
.footer__contacto a{ display:flex; align-items:center; gap:9px; font-size:.84rem; font-weight:600; color:var(--ink-2); transition:color .25s var(--ease); }
.footer__contacto a:hover{ color:var(--orange); }
.footer__contacto .ico{ width:17px; height:17px; color:var(--orange); }

.footer__social{ display:flex; gap:9px; margin-top:6px; }
.footer__social a{
  display:grid; place-items:center; width:34px; height:34px; border-radius:50%;
  background:var(--bg-sand); color:var(--ink-2);
  transition:background .25s var(--ease), color .25s var(--ease), transform .25s var(--ease);
}
.footer__social a:hover{ background:var(--orange); color:#fff; transform:translateY(-2px); }
.footer__social .ico{ width:16px; height:16px; color:inherit; }   /* inherit: si no, .footer__contacto .ico lo pinta naranja y en :hover desaparece sobre el círculo naranja */

.footer__legal{
  display:flex; justify-content:space-between; flex-wrap:wrap; gap:10px;
  padding-top:18px;
}
.footer__legal p{ font-size:.76rem; color:var(--muted); }
.footer__hecho{ font-variation-settings:"wdth" var(--w-estrecho); letter-spacing:.02em; }


/* ═══ REVEAL ═════════════════════════════ */
/* Sólo se ocultan si JS está activo: sin JS todo queda visible. */
.js .reveal{ opacity:0; transform:translateY(20px); transition:opacity .7s var(--ease), transform .7s var(--ease); }
.js .reveal.is-in{ opacity:1; transform:none; }


/* ═══ RESPONSIVE ═════════════════════════ */
/* El hero rompe la caja de 1200px sólo en escritorio: el titular necesita el
   ancho real de la pantalla. Abajo de 1081px vuelve al .wrap normal para no
   desalinearse con el resto de las secciones. */
@media (min-width:1081px){
  .hero__inner{
    max-width:min(var(--wrap-wide), 94vw);
    grid-template-columns:minmax(0,3fr) minmax(0,1fr);   /* titular 3/4 · visual 1/4 */
    grid-template-rows:auto 1fr;   /* el sobrante de altura lo absorbe la fila 2 */
  }
  .hero__title{ grid-column:1; }
  .hero__copy{ grid-column:1; }
  /* La rejilla NO se toca (sigue 3fr/1fr): el logo crece desbordando su columna
     hacia los dos lados. A la izquierda, sobre el aire de los renglones cortos
     del titular; a la derecha, sobre el margen que el .wrap deja libre hasta el
     borde de la ventana. Así el reparto 3/4 · 1/4 del texto queda intacto. */
  .hero__visual{
    grid-column:2; grid-row:1 / span 2; align-self:center;
    margin-left:calc(-1 * clamp(90px, 13vw, 360px));
    margin-right:calc(-1 * clamp(0px, 3vw, 70px));
  }
  /* dentro del flow el logo pasa de 46% a 80% y se recentra para no pisar los cerebros */
  .flow__logo{ width:80%; left:60%; }
}

/* El mapa lateral necesita margen a la derecha del contenido. Por debajo
   de este ancho se pisaría con las tarjetas, así que se retira: el menú
   del encabezado ya cubre la navegación. */
@media (max-width:1240px){
  .mapa{ display:none; }
}

@media (max-width:1080px){
  /* en una sola columna los cables cruzarían por detrás del titular: se retiran */
  .cables{ display:none; }
  .hero__inner{ grid-template-columns:1fr; }
  .hero__visual{ max-width:640px; }

  /* la tarjeta ancha de servicios deja de serlo: en 2 columnas no cabe */
  .servicios__rejilla{ grid-template-columns:repeat(2, 1fr); }
  .productos__rejilla{ grid-template-columns:repeat(2, 1fr); }
  .servicio--ancho{ grid-column:span 2; }

  .valores__inner{ grid-template-columns:1fr; gap:clamp(24px, 4vw, 40px); }
  .valores__lienzo{ height:clamp(215px, 36vw, 290px); order:2; }

  .pasos{ grid-template-columns:repeat(3, 1fr); }
}

@media (max-width:980px){
  .header__cta{ display:none; }
  .burger{ display:block; }
  .nav{
    position:absolute; left:0; right:0; top:100%;
    flex-direction:column; align-items:stretch; gap:0;
    background:#fff; border-bottom:1px solid var(--line);
    padding:8px 24px 22px; box-shadow:var(--shadow-md);
    clip-path:inset(0 0 100% 0); opacity:0; pointer-events:none;
    transition:clip-path .35s var(--ease), opacity .25s;
  }
  .nav.is-open{ clip-path:inset(0 0 0 0); opacity:1; pointer-events:auto; }
  .nav a:not(.btn){ padding:14px 0; border-bottom:1px solid var(--line); }
  .nav__cta{ display:inline-flex; margin-top:18px; }

  .enfoque__pasos{ grid-template-columns:1fr; }
  .enfoque__paso{ display:grid; grid-template-columns:auto 1fr; gap:0 16px; align-items:center; }
  .enfoque__cabeza{ grid-row:1 / span 2; flex-direction:column-reverse; gap:8px; margin:0; }
  .enfoque__paso h3{ align-self:end; }
  .enfoque__estado{ display:none; }

  .footer__inner{ grid-template-columns:1fr 1fr; }
}

@media (max-width:760px){
  .servicios__rejilla{ grid-template-columns:1fr; }
  .productos__rejilla{ grid-template-columns:1fr; }
  .servicio--ancho{ grid-column:span 1; flex-direction:column; }
  .servicio--ancho .servicio__lienzo{ width:96px; height:96px; }

  .pasos{ grid-template-columns:repeat(2, 1fr); }
  .proyecto{ --ancho:min(560px, 94%); }
  .pista{ height:clamp(480px, 108vw, 600px); }
}

@media (max-width:620px){
  .wrap{ padding-inline:18px; }
  /* Los <br> se conservan también en móvil: las cuatro frases del titular son
     cortas y caben, así que la estructura de 4 renglones es la misma en todos
     los anchos. */
  .hero__actions .btn{ width:100%; }
  .pipeline{ grid-template-columns:repeat(2,1fr); gap:22px 12px; }
  .pipeline li::after{ display:none; }

  .enfoque__lienzo{ height:clamp(200px, 52vw, 262px); }
  .proceso__lienzo{ height:clamp(178px, 46vw, 232px); }
  .pasos{ grid-template-columns:1fr; gap:4px; }

  .captura__ui,.captura__chat,.captura__app{ height:150px; }
  .captura__app{ grid-template-columns:80px 1fr; }

  .cta__inner{ flex-direction:column; align-items:flex-start; }
  .cta h2 br{ display:none; }
  .cta__campo{ width:100%; opacity:.4; }
  .divisor{ height:clamp(70px, 18vw, 96px); margin-top:-16px; margin-bottom:-20px; }

  .footer__inner{ grid-template-columns:1fr; }
  .footer__legal{ flex-direction:column; gap:4px; }
}

@media (prefers-reduced-motion:reduce){
  html{ scroll-behavior:auto; }
  *,*::before,*::after{ animation-duration:.001ms !important; animation-iteration-count:1 !important; transition-duration:.001ms !important; }
  .reveal,.js .reveal{ opacity:1; transform:none; }
  /* sin movimiento el pulso es sólo un trazo suelto: se oculta y quedan
     los cables y los nodos, que siguen leyéndose como gráfico */
  .pulse{ display:none; }
  /* el titular aparece ya desplegado, sin giro ni sombra de pliegue */
  .fold__p{ transform:none !important; opacity:1 !important; }
  .fold__p::after{ display:none; }
  .js .hero__title .mark{ background-size:100% 34%; }
  /* el logo sale ya dibujado, sin barrido */
  .js .flow__logo{ -webkit-mask-position:0% 0; mask-position:0% 0; }
  .node__ring{ opacity:.28; }
  .node__core{ opacity:.55; }

  /* Las escenas de vóxeles se pintan una sola vez desde voxel.js. Aquí
     sólo se apaga lo que anima por CSS y se retira el aviso de girar,
     porque el arrastre sigue disponible pero ya no hay giro automático. */
  .captura__grafica i{ animation:none; transform:none; }
  .burbuja--escribiendo i{ animation:none; opacity:.7; }
  .tip{ display:none; }
  .proyecto{ transition:none; }
}
