/* ═══════════════════════════════════════════
   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: "Elms Sans", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --mono: "Space Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  /* display de contraste: sólo para las palabras acentuadas. Un peso (400),
     caja muy alta y ancha — nunca usar en párrafos ni en bloques largos. */
  --display: "Climate Crisis", var(--sans);

  --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-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.12; letter-spacing:-.02em; margin:0; }
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 ──────────────────────────── */
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:10px;
  padding:13px 24px;
  border:1.5px solid transparent; border-radius:var(--pill);
  font-weight:700; font-size:.94rem; letter-spacing:-.01em;
  cursor:pointer; white-space:nowrap;
  transition:transform .25s var(--ease), box-shadow .25s var(--ease),
             background-color .2s, color .2s, border-color .2s;
}
.btn .ico{ width:18px; height:18px; transition:transform .3s var(--ease); }
.btn:hover .ico{ transform:translateX(4px); }
.btn--lg{ padding:15px 26px; font-size:.95rem; }

.btn--primary{ background:var(--orange); color:#fff; box-shadow:0 10px 26px -12px rgba(253,81,7,.75); }
.btn--primary:hover{ background:#E84604; transform:translateY(-2px); box-shadow:0 16px 34px -12px rgba(253,81,7,.8); }

.btn--ghost{ background:#fff; color:var(--ink); border-color:var(--line); }
.btn--ghost:hover{ border-color:var(--orange); color:var(--orange); transform:translateY(-2px); }
.btn__down{ font-size:1.05em; line-height:1; transition:transform .3s var(--ease); }
.btn--ghost:hover .btn__down{ transform:translateY(3px); }

.btn--white{ background:#fff; color:var(--ink); box-shadow:0 14px 34px -14px rgba(0,0,0,.4); }
.btn--white:hover{ transform:translateY(-2px); 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(--mono); font-size:.76rem; font-weight:700;
  letter-spacing:.16em; 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 ─────────────── */
/* Climate Crisis: se usa en puñados de palabras, nunca en texto corrido.
   Sólo existe en un peso, así que fijamos 400 — si hereda el 700/800 del
   encabezado el navegador sintetiza una falsa negrita y ensucia el trazo.
   La caja del tipo es muy alta: bajamos el tamaño relativo y el interlineado
   para que la línea acentuada pese lo mismo que el resto del encabezado. */
.display{
  font-family:var(--display);
  font-weight:400;
  font-size:.86em;
  line-height:1.05;
  letter-spacing:-.01em;
}

/* ═══ TICKER ═════════════════════════════ */
/* Banda a sangre completa que cierra el bloque del hero. */
.ticker{
  position:relative;
  overflow:hidden;
  /* difumina las palabras al entrar y salir por los bordes */
  -webkit-mask-image:linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
          mask-image:linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
}

.ticker__track{
  display:flex; width:max-content;
  animation:ticker-scroll 34s linear infinite;
  will-change:transform;            /* compositado en GPU: evita tirones en móvil */
}
/* Se congela al pasar el cursor para poder leer. Sólo en dispositivos con puntero
   real: en touch el :hover se queda "pegado" tras un tap y detendría la marquesina. */
@media (hover:hover) and (pointer:fine){
  .ticker:hover .ticker__track{ animation-play-state:paused; }
}

.ticker__group{ display:flex; align-items:center; flex:none; }

.ticker__group li{
  display:flex; align-items:center;
  padding-block:clamp(13px, 1.6vw, 18px);
  font-weight:800; font-size:clamp(.9rem, 1.9vw, 1.3rem);
  line-height:1.1; letter-spacing:.14em; text-transform:uppercase;
  color:var(--ink); white-space:nowrap;
}

/* separador: cuadro naranja, mismo motivo de píxel que el hero */
.ticker__group li::after{
  content:""; flex:none;
  width:8px; height:8px; background:var(--orange);
  margin-inline:clamp(18px, 3.2vw, 44px);
}

/* alternancia relleno / contorno para dar ritmo */
@supports (-webkit-text-stroke:1px currentColor){
  .ticker__group li:nth-child(even){
    color:transparent; -webkit-text-stroke:1px var(--ink);
  }
}

@keyframes ticker-scroll{
  from{ transform:translateX(0); }
  to  { transform:translateX(-50%); }
}

/* ═══ HERO ═══════════════════════════════ */
.hero{ position:relative; padding:0 0 clamp(56px, 8vw, 96px); 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.6rem, 9vw, 10rem);
  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;
}

/* ── 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; }

/* ═══ ENFOQUE ════════════════════════════ */
.approach{ background:var(--bg-soft); padding:clamp(56px, 7vw, 92px) 0; position:relative; overflow:hidden; }
.approach::before,.approach::after{
  content:""; position:absolute; width:180px; height:180px; opacity:.5;
  background-image:
    linear-gradient(var(--butter) 0 0), linear-gradient(var(--orange-soft) 0 0),
    linear-gradient(var(--butter) 0 0), linear-gradient(var(--orange-soft) 0 0);
  background-repeat:no-repeat;
  background-size:16px 16px, 26px 26px, 12px 12px, 20px 20px;
  background-position:10px 40px, 46px 8px, 78px 62px, 30px 96px;
}
.approach::before{ left:-10px; top:64px; }
.approach::after{ right:-10px; top:44px; transform:scaleX(-1); }

.cards-3{
  display:grid; grid-template-columns:repeat(3,1fr); gap:22px;
  margin-top:46px;
}
.card{
  display:flex; gap:18px; align-items:flex-start;
  background:#fff; border:1px solid var(--line); border-radius:var(--r-md);
  padding:26px 24px;
  transition:transform .3s var(--ease), box-shadow .3s var(--ease), border-color .3s;
}
.card:hover{ transform:translateY(-4px); box-shadow:var(--shadow-md); border-color:#DDD7CB; }
.card__ico{ display:grid; place-items:center; width:56px; height:56px; border-radius:50%; flex:none; }
.card__ico--soft  { background:var(--butter);      color:var(--ink); }
.card__ico--mid   { background:var(--orange-soft); color:var(--ink); }
.card__ico--strong{ background:var(--orange-mid);  color:#fff; }
.card__ico .ico{ width:28px; height:28px; }
.card h3{ font-size:1.05rem; margin-bottom:8px; }
.card p{ font-size:.9rem; color:var(--muted); line-height:1.6; }

/* ═══ SERVICIOS ══════════════════════════ */
.services{ padding:clamp(56px, 7vw, 92px) 0; border-bottom:1px solid var(--line); }
.services__inner{ display:grid; grid-template-columns:minmax(0,.95fr) minmax(0,2.15fr); gap:clamp(28px,4vw,56px); }
.services .section-head h2{ margin-bottom:20px; }

.services__grid{ display:grid; grid-template-columns:repeat(4,1fr); gap:0; }
.service{ padding:4px 22px; border-left:1px solid var(--line); transition:transform .3s var(--ease); }
.service:first-child{ border-left:0; padding-left:0; }
.service:hover{ transform:translateY(-4px); }
.service .ico--lg{ color:var(--orange); margin-bottom:16px; }
.service h3{ font-size:1rem; margin-bottom:10px; }
.service p{ font-size:.86rem; color:var(--muted); line-height:1.6; }

@media (min-width:981px){
  .services__grid{ grid-template-columns:repeat(3,1fr); row-gap:34px; }
  .service:nth-child(3n+1){ border-left:0; padding-left:0; }
}

/* ═══ PROCESO ════════════════════════════ */
.process{ background:var(--bg-sand); padding:clamp(56px, 7vw, 92px) 0; }
.process__inner{ display:grid; grid-template-columns:minmax(0,.95fr) minmax(0,2.15fr); gap:clamp(28px,4vw,56px); }

.steps{ display:grid; grid-template-columns:repeat(5,1fr); gap:16px; }
.step{ position:relative; }
.step:not(:last-child)::after{
  content:""; position:absolute; top:22px; left:52px; right:-8px;
  border-top:2px dashed rgba(253,81,7,.4);
}
.step__num{
  display:grid; place-items:center; width:44px; height:44px; margin-bottom:16px;
  border-radius:50%; background:var(--orange); color:#fff;
  font-family:var(--mono); font-weight:700; font-size:.9rem;
  box-shadow:0 10px 20px -10px rgba(253,81,7,.7);
}
.step:nth-child(1) .step__num{ background:var(--butter); color:var(--ink); }
.step:nth-child(2) .step__num{ background:var(--orange-soft); color:var(--ink); }
.step:nth-child(3) .step__num{ background:var(--orange-mid); }
.step h3{ font-size:.98rem; color:var(--orange); margin-bottom:8px; }
.step p{ font-size:.84rem; color:var(--muted); line-height:1.55; }

/* ═══ PROYECTOS ══════════════════════════ */
.projects{ padding:clamp(56px, 7vw, 92px) 0; }
.projects__inner{ display:grid; grid-template-columns:minmax(0,.95fr) minmax(0,2.15fr); gap:clamp(28px,4vw,56px); }
.projects .section-head h2{ margin-bottom:20px; }

.slider{ position:relative; overflow:hidden; border-radius:var(--r-lg); }
.slider__track{ display:flex; transition:transform .55s var(--ease); }
.project{
  flex:0 0 100%;
  display:grid; grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr); gap:26px; align-items:center;
  background:var(--bg-soft); border:1px solid var(--line); border-radius:var(--r-lg);
  padding:22px;
}
.project__body h3{ font-size:1.15rem; margin-bottom:10px; }
.project__body p{ font-size:.9rem; color:var(--muted); margin-bottom:16px; }
.ticks li{ display:flex; align-items:center; gap:10px; font-size:.88rem; padding-block:5px; }
.ticks .ico{ width:19px; height:19px; color:var(--orange-mid); }

.slider__nav{ position:absolute; right:18px; bottom:18px; display:flex; gap:8px; }
.round{
  width:38px; height:38px; border-radius:50%; cursor:pointer;
  background:#fff; border:1px solid var(--line); color:var(--ink);
  font-size:1.25rem; line-height:1; display:grid; place-items:center;
  transition:background .2s, color .2s, border-color .2s, transform .2s;
}
.round:hover{ background:var(--orange); border-color:var(--orange); color:#fff; transform:scale(1.06); }

/* maqueta de pantalla */
.shot{
  background:#1C1A17; border-radius:var(--r-md); padding:10px;
  box-shadow:var(--shadow-md); overflow:hidden;
}
.shot__bar{ display:flex; gap:6px; padding:2px 4px 10px; }
.shot__bar i{ width:8px; height:8px; border-radius:50%; background:#4A443C; }
.shot__bar i:first-child{ background:var(--orange); }
.shot__ui{ display:grid; grid-template-columns:64px 1fr; gap:8px; background:#F7F5F1; border-radius:10px; padding:10px; min-height:190px; }
.shot__side{ display:grid; align-content:start; gap:7px; }
.shot__side span{ height:8px; border-radius:3px; background:#E2DED5; }
.shot__side span:first-child{ background:var(--orange); width:70%; }
.shot__main{ display:grid; align-content:start; gap:10px; }
.shot__row{ display:grid; grid-template-columns:repeat(3,1fr); gap:7px; }
.shot__row b{ height:30px; border-radius:6px; background:#EDE9E1; }
.shot__row b:first-child{ background:var(--butter); }
.shot__chart{ display:flex; align-items:flex-end; gap:6px; height:78px; padding:8px; background:#fff; border-radius:8px; }
.shot__chart i{ flex:1; border-radius:3px 3px 0 0; background:var(--orange-soft); }
.shot__chart i:nth-child(4),.shot__chart i:nth-child(6){ background:var(--orange); }
.shot__lines{ display:grid; gap:6px; }
.shot__lines span{ height:7px; border-radius:3px; background:#EDE9E1; }
.shot__lines span:nth-child(2){ width:76%; }
.shot__lines span:nth-child(3){ width:58%; }

.shot__chat{ background:#F7F5F1; border-radius:10px; padding:14px; min-height:190px; display:grid; align-content:start; gap:9px; }
.bub{ font-size:.78rem; line-height:1.45; padding:9px 13px; border-radius:14px; max-width:82%; }
.bub--in{ background:#fff; color:var(--ink-2); border:1px solid var(--line); border-bottom-left-radius:4px; }
.bub--out{ background:var(--orange); color:#fff; justify-self:end; border-bottom-right-radius:4px; }
.bub--typing{ display:flex; gap:5px; padding:12px 14px; }
.bub--typing i{ width:6px; height:6px; border-radius:50%; background:rgba(255,255,255,.9); animation:blink 1.3s infinite; }
.bub--typing i:nth-child(2){ animation-delay:.2s; }
.bub--typing i:nth-child(3){ animation-delay:.4s; }
@keyframes blink{ 0%,60%,100%{ opacity:.35; } 30%{ opacity:1; } }

.shot__app{ display:grid; grid-template-columns:88px 1fr; gap:14px; background:#F7F5F1; border-radius:10px; padding:14px; min-height:190px; }
.phone{ background:#fff; border:1px solid var(--line); border-radius:12px; padding:8px; display:grid; align-content:start; gap:7px; }
.phone__hd{ height:10px; border-radius:3px; background:var(--orange); width:60%; }
.phone__card{ height:34px; border-radius:7px; background:#EFEBE3; }
.phone__cta{ height:14px; border-radius:7px; background:var(--butter); }
.shot__lines--tall{ align-content:center; }

/* ═══ VALORES ════════════════════════════ */
.values{ background:var(--bg-soft); padding:clamp(56px, 7vw, 92px) 0; }
.values__grid{ display:grid; grid-template-columns:repeat(5,1fr); gap:0; margin-top:44px; }
.values__grid li{ padding:0 22px; border-left:1px solid var(--line); }
.values__grid li:first-child{ border-left:0; padding-left:0; }
.values__grid .ico{ width:26px; height:26px; color:var(--orange); margin-bottom:14px; }
.values__grid h3{ font-size:.95rem; margin-bottom:8px; }
.values__grid p{ font-size:.84rem; color:var(--muted); line-height:1.55; }

/* ═══ CTA ════════════════════════════════ */
.cta{
  position:relative; overflow:hidden;
  background:linear-gradient(105deg, #FF6A1E 0%, var(--orange) 48%, #E8420B 100%);
  color:#fff; padding:clamp(46px, 6vw, 72px) 0;
}
.cta__pixels{
  position:absolute; left:0; top:0; bottom:0; width:340px; opacity:.55;
  background-image:
    linear-gradient(rgba(255,255,255,.5) 0 0), linear-gradient(rgba(255,255,255,.3) 0 0),
    linear-gradient(rgba(255,255,255,.45) 0 0), linear-gradient(rgba(255,255,255,.25) 0 0),
    linear-gradient(rgba(255,255,255,.4) 0 0), linear-gradient(rgba(255,255,255,.2) 0 0);
  background-repeat:no-repeat;
  background-size:22px 22px, 34px 34px, 16px 16px, 26px 26px, 14px 14px, 30px 30px;
  background-position:0 18px, 30px 62px, 74px 24px, 8px 118px, 62px 140px, 96px 92px;
}
.cta__wave{
  position:absolute; right:-130px; top:50%; transform:translateY(-50%);
  width:560px; height:330px; opacity:.13;
  background:url("../img/logo-white.png") no-repeat center/contain;
}
.cta__inner{ position:relative; display:flex; align-items:center; justify-content:space-between; gap:34px; 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; }

/* ═══ FOOTER ═════════════════════════════ */
.site-footer{ background:#fff; padding:34px 0 20px; }
.footer__inner{ display:flex; align-items:center; gap:28px; flex-wrap:wrap; }
.brand--footer img{ width:92px; }
.footer__tag{ font-size:.9rem; color:var(--muted); margin-right:auto; }
.footer__contact{ display:flex; gap:26px; flex-wrap:wrap; }
.footer__contact a{ display:inline-flex; align-items:center; gap:9px; font-size:.9rem; color:var(--ink-2); transition:color .2s; }
.footer__contact a:hover{ color:var(--orange); }
.footer__contact .ico{ width:19px; height:19px; color:var(--orange); }
.footer__social{ display:flex; gap:12px; }
.footer__social a{
  display:grid; place-items:center; width:38px; height:38px; border-radius:50%;
  border:1px solid var(--line); color:var(--ink-2);
  transition:background .2s, color .2s, border-color .2s, transform .2s;
}
.footer__social a:hover{ background:var(--orange); border-color:var(--orange); color:#fff; transform:translateY(-2px); }
.footer__legal{ margin-top:24px; padding-top:18px; border-top:1px solid var(--line); }
.footer__legal p{ font-size:.8rem; color:var(--muted); }

/* ═══ 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, no el hueco bajo el titular */
  }
  .hero__title{ grid-column:1; }
  .hero__copy{ grid-column:1; }
  /* el visual ocupa la columna estrecha completa, a la altura del titular y del copy */
  /* el visual queda solo en la columna estrecha: centrado contra el titular */
  .hero__visual{ grid-column:2; grid-row:1 / span 2; align-self:center; }
  /* La columna es 1/4 del ancho, demasiado poco para que el logo pese. Se
     desborda hacia la izquierda, sobre el aire que dejan los renglones cortos
     del titular; el tope del clamp lo mantiene lejos de "Ingeniería de". */
  /* 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{
    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%; }
}

@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; }
  .services__inner,.process__inner,.projects__inner{ grid-template-columns: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; }

  .cards-3{ grid-template-columns:1fr; }
  .services__grid{ grid-template-columns:repeat(2,1fr) !important; row-gap:30px; }
  .service{ padding-inline:20px; }
  .service:nth-child(odd){ border-left:0; padding-left:0; }
  .service:nth-child(even){ border-left:1px solid var(--line); padding-left:20px; }

  .steps{ grid-template-columns:repeat(2,1fr); gap:26px; }
  .step::after{ display:none; }

  .project{ grid-template-columns:1fr; }
  .slider__nav{ position:static; justify-content:flex-end; margin-top:14px; }

  .values__grid{ grid-template-columns:repeat(2,1fr); gap:28px 0; }
  .values__grid li{ padding-inline:20px; }
  .values__grid li:nth-child(odd){ border-left:0; padding-left:0; }
}

@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. (Con el copy largo anterior había que anularlos.) */
  .hero__actions .btn{ width:100%; }
  .pipeline{ grid-template-columns:repeat(2,1fr); gap:22px 12px; }
  .pipeline li::after{ display:none; }
  .services__grid{ grid-template-columns:1fr !important; }
  .service{ border-left:0 !important; padding-left:0 !important; }
  .steps{ grid-template-columns:1fr; gap:22px; }
  .values__grid{ grid-template-columns:1fr; }
  .values__grid li{ border-left:0 !important; padding-left:0 !important; }
  .cta__inner{ flex-direction:column; align-items:flex-start; }
  .cta h2 br{ display:none; }
  .cta__wave{ display:none; }
  .footer__tag{ margin-right:0; width:100%; }
  .shot__app{ grid-template-columns:80px 1fr; }
}

@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; }
  /* el ticker se queda quieto en su posición inicial, no saltado al final */
  .ticker__track{ animation:none !important; transform:none !important; }
  /* 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; }
}
